Architecture
Architectureπ
LocalGPT is one Cargo workspace: the assistant, the world apps (the desktop app, Gen, MD, Verse, previs) and the world-format crates they all share. MD and Verse used to be repositories of their own and were folded in so the format could not drift between apps; the format itself then moved out to the Open World Format, whose Rust reference this workspace consumes as the openworldformat crate.
Workspace Structureπ
crates/
βββ core/ # localgpt-core β the shared library: agent, memory, config, security, MCP, cron, hooks
βββ cli/ # localgpt β the main binary: clap CLI, TUI, desktop GUI, daemon, `localgpt world`
βββ cli-tools/ # localgpt-cli-tools β the dangerous tools: bash, read/write/edit_file, browser
βββ server/ # localgpt-server β HTTP/WS API, OpenAI-compatible API, TLS, BridgeManager
βββ sandbox/ # localgpt-sandbox β Landlock/Seatbelt kernel-enforced shell isolation
βββ mobile-ffi/ # localgpt-mobile-ffi β UniFFI bindings for iOS/Android
βββ gen/ # localgpt-gen β the world builder (Bevy): interactive, MCP server, headless, sessions, live canvas
βββ app/ # localgpt-app β the one desktop app: Gen's shell with documents, songs and packages as modes
βββ md/ # localgpt-md β a Markdown file as a walkable world (pure lib + Bevy bin)
βββ verse/ # localgpt-verse β a 3D world for every song (lib + Bevy bin)
βββ previs/ # localgpt-previs β screenplay β per-scene .world with set/cast/coverage, a board, a shot list
βββ previs-web/ # localgpt-previs-web β previs's draft as WASM, for the localgpt.md page
βββ world-types/ # localgpt-world-types β the world data model (serde only; the format's types re-exported)
βββ world-bevy/ # localgpt-world-bevy β the one Bevy mapping of the format (Gen, MD, Verse, the app)
βββ world-audio/ # localgpt-world-audio β the one mapping of the format's audio (kira + FunDSP)
βββ world-export/ # localgpt-world-export β the three.js viewer and HTML export, no Bevy
βββ world-sync/ # localgpt-world-sync β collaborative rooms: shared document, ops, wire protocol, authority
βββ world-editor/ # localgpt-world-editor β the non-linear editing model: tips, forks, folds, deltas
βββ world-agent/ # localgpt-world-agent β the live authority, packages, headless commands, the tool-call protocol
βββ relay/ # localgpt-relay β internet reach for collaborative rooms
βββ bridge/ # localgpt-bridge β secure IPC protocol for bridge daemons
βββ spacetime/ # localgpt-spacetime β SpacetimeDB multiplayer module (standalone; wasm toolchain)
bridges/
βββ cli/ # localgpt-bridge-cli β a terminal that connects to a running daemon over the IPC socket
apps/
βββ apple/ # iOS/macOS (Swift, UniFFI)
βββ android/ # Android (Kotlin, UniFFI)
βββ app-desktop/ # the LocalGPT.app bundler (Developer ID + notarization when given)
βββ web/ # web client
website*/ # one Cloudflare Worker each: localgpt.app (this site), gen., verse., localgpt.md, localgpt.world
scripts/ # fetch-model.sh and fetch-assets.sh β the two downloads every app sharesDependency Graphπ
βββββββββββββββββββ
β localgpt-core β (no internal deps; compiles for iOS and Android)
ββββββββββ¬βββββββββ
βββββββββββββββββ¬ββββββββΌβββββββββ¬βββββββββββββββ
βΌ βΌ βΌ βΌ βΌ
ββββββββββββββββ ββββββββββββββ ββββββββ ββββββββββ ββββββββββββββββ
β localgpt- β β localgpt- β β gen β β mobile β β world-types β
β bridge β β sandbox β β β β -ffi β β (serde only) β
β (no internal)β βββββββ¬βββββββ ββββββββ ββββββββββ ββββββββ¬ββββββββ
ββββββββ¬ββββββββ β β
β βΌ βββββββββββββββββββΌβββββββββββββββ¬ββββββββββββ
β ββββββββββββββββββββ βΌ βΌ βΌ βΌ
β β localgpt-cli- β world-bevy world-export world-sync world-agent
β β tools (core+ β world-audio (three.js) world-editor (the authority)
β β sandbox) β (Bevy, kira) previs
β ββββββββββ¬ββββββββββ β β β β
βΌ β ββββββββββ¬βββββββββ΄βββββββββββββββ΄ββββββββββββ
βββββββββββββββββββ β βΌ
β localgpt-server β β gen ββΊ app (md + verse as libs)
β (core + bridge) β β md, verse, previs-web
ββββββββββ¬βββββββββ β
βΌ βΌ
ββββββββββββββββββββββββββββ
β localgpt (CLI) β
β core + server + sandbox β
β + cli-tools + world-agentβ
ββββββββββββββββββββββββββββ
Bridge daemons depend on core + bridge. Mobile depends on core with default-features = false plus local embeddings and sqlite-vec.
Crate Summaryπ
| Crate | Type | Purpose |
|---|---|---|
localgpt-core | lib | Agent, providers, memory, config, security, MCP client and server, cron, hooks. Zero platform-specific dependencies |
localgpt | bin | The assistantβs CLI, TUI, desktop GUI and daemon, and localgpt world |
localgpt-cli-tools | lib | The dangerous tools (shell, files, browser) the CLI and daemon inject; never in core |
localgpt-server | lib | HTTP/WebSocket API, OpenAI-compatible surface, embedded web UI, TLS, BridgeManager |
localgpt-sandbox | lib | Landlock/seccomp, Seatbelt and container sandboxing for shell commands |
localgpt-bridge | lib | IPC protocol for bridge daemons |
localgpt-bridge-cli | bin | Terminal chat over the daemonβs bridge socket |
localgpt-mobile-ffi | lib+bin | UniFFI bindings; LocalGPTClient owns a tokio runtime and an AgentHandle |
localgpt-gen | lib+bin | The world builder: Bevy viewport, the agent loop, 77 tools, MCP server and relay, headless, sessions, the live canvas |
localgpt-app | bin | The one desktop app, assembled from the gen library with MD and Verse as libraries (not published) |
localgpt-md | lib+bin | Markdown β sections β a world; the pure library is what the app compiles documents with |
localgpt-verse | lib+bin | Song analysis β mood β a furnished, performing world; song_world is what the app calls |
localgpt-previs | lib+bin | Screenplay β per-scene .world, board and shot list; deterministic, no model, no network |
localgpt-previs-web | lib | The same draft as WASM for localgpt.md (not published) |
localgpt-world-types | lib | The data model: the formatβs types re-exported, plus NPCs, behavior libraries, regions, sync drift. schema writes world.schema.json |
localgpt-world-bevy | lib | The only place a shape, material, light or environment becomes Bevy components |
localgpt-world-audio | lib | One kira AudioManager; FunDSP graphs as sources; ambience, spatial emitters, soundtracks |
localgpt-world-export | lib | The three.js viewer (vendored from the formatβs npm package) and generate_html; no Bevy |
localgpt-world-sync | lib | Shared world document, validated EditOps, the wire protocol, the room authority; no Bevy, no I/O |
localgpt-world-editor | lib | History as a tree: a branch index, a fold cache fast enough to scrub, deltas between tips |
localgpt-world-agent | lib | LiveWorld (the live authority), packages, the headless commands behind localgpt world, the tool-call protocol, the shared download paths |
localgpt-relay | bin | Forwards WebSocket frames between a host and its guests by room code; never holds world state (not published) |
localgpt-spacetime | module | SpacetimeDB rooms: the same ops and validation as a LAN host, in the cloud (standalone workspace) |
The world format is sharedπ
Every app reads and writes one format. localgpt-world-types is the source: the Open World Formatβs document, session and state types come from the openworldformat crate and are re-exported unchanged, and the crate adds LocalGPTβs own surface on top. localgpt-world-bevy is the only place those types become Bevy components, so Gen, MD, Verse and the app render identically; localgpt-world-audio is the one mapping of the formatβs audio; localgpt-world-export holds the only web renderer, the same three.js viewer localgpt.world serves and every exported HTML page embeds.
Reference scenes live in crates/world-types/conformance/ and are rendered by both renderers; the web viewerβs headless render check runs in CI. The rule inside the workspace: add fields to world-types, never a parallel format β proposals that change what the format means belong in the formatβs own repository.
A .world package is a folder: manifest.json (the head), ops.jsonl (the log), assets/ (content-addressed), AGENTS.md. LiveWorld in world-agent is the one authority that commits to it β from the window (live canvas) or from localgpt world β and world-editor is the view that follows: tips, forks, folds and deltas, which the history rail and panel draw.
Core Librariesπ
localgpt-coreπ
Foundation library with zero platform-specific dependencies, compiled for aarch64-apple-ios and aarch64-linux-android as well as the desktop:
- Agent: the
LLMProvidertrait and its implementations (Anthropic, OpenAI and OpenAI-compatible, xAI, Gemini, Vertex AI, GLM, Ollama, Claude/Gemini/Codex CLIs), model aliases, failover, compaction, checkpoints, tool filters, approval - Memory: SQLite FTS5 + sqlite-vec with local embeddings, Markdown and no-op backends, active recall, dreaming (background consolidation), the wiki
- Config: TOML with XDG path resolution, migration and hot reload
- Security:
POLICY.mdinjection and sanitization, protected files, SSRF guards, the hardcoded security suffix - Heartbeat and cron: autonomous runs, each job in a fresh session, with a durable outbox
- MCP: a client for external servers (stdio, HTTP/SSE) and a server exposing memory tools
- Session: conversation management with automatic compaction and branching
Safe tools only (create_safe_tools): memory, web, documents, audio transcription, wiki, spawn_agent. The CLI and daemon inject the dangerous tools from localgpt-cli-tools; server agents and bridges never get them.
localgpt-bridgeπ
IPC protocol for daemon-to-bridge communication: tarpc-based async RPC, peer identity verification (Unix UID/GID), credential exchange, Unix sockets and Windows named pipes.
Desktop Componentsπ
localgpt-serverπ
- Axum HTTP: REST API, the OpenAI-compatible
/v1/chat/completionsand/v1/models, the embedded web UI (RustEmbed), the tool-approval endpoint - WebSocket: real-time chat streaming
- BridgeManager: the socket server for bridge daemons
- TLS and per-IP rate limiting
localgpt-sandboxπ
| Platform | Technology |
|---|---|
| Linux | Landlock + seccomp |
| macOS | Seatbelt (sandbox-init) |
| Any | Docker / Podman as a backend |
| Windows | Restricted tokens |
Falls back gracefully on unsupported systems.
Binariesπ
localgpt (CLI)π
| Command | Purpose |
|---|---|
chat, tui, ask | conversation |
daemon | HTTP server + web UI + heartbeat + cron |
world | a .world packageβs command line: init, submit, undo, log, tips, verify, history, and mcp β the open canvasβs tools over stdio |
mcp-server | memory and web tools over stdio for other agents |
memory, config, policy, session, cron, hooks, tool | the workspace and the daemonβs services |
sandbox, cert, doctor, paths, init, completion | setup and diagnostics |
gen | launches localgpt-gen |
localgpt-genπ
The world builder: a Bevy window with the agent loop and 77 gen_* tools in three profiles; mcp-server (stdio, --mcp-http, --connect to a running windowβs relay); headless generation; --host/--join/--web/--relay collaborative sessions over world-sync; --live for the live canvas; --replay. See LocalGPT Gen.
localgpt-appπ
The desktop app: Genβs shell plus --md, --song and --world. Thin by design β everything heavy comes from the gen library, MDβs pure library compiles documents, Verseβs library builds song worlds, and the prompt panel runs Genβs own agent loop.
localgpt-previsπ
Script to board, deterministic: Fountain, Final Draft .fdx, PDF or Markdown pages in; per scene a .world with set, cast and coverage, plus board.html and shotlist.csv. The same draft function runs as WASM on localgpt.md. See Previs.
localgpt-relayπ
Internet reach for collaborative rooms: forwards frames between a NATβd host and its guests by room code.
System Promptπ
Every agent in the family shares the base system prompt built by build_system_prompt() in localgpt-core: identity, safety guidelines, the registered toolsβ documentation, the workspace and the current time, memory conventions, runtime info. On a new session the agent loads its workspace context (SOUL.md, MEMORY.md, daily logs, HEARTBEAT.md) and appends it.
| CLI | Gen and the app | Server / Mobile | |
|---|---|---|---|
| Agent creation | Agent::new() β async, connects MCP servers | Agent::new_with_tools() β the gen toolbelt at the chosen profile | Agent::new() β safe tools only |
| Tools | Safe tools + CLI tools (shell, files) + spawn_agent | Safe tools + gen_* tools; interactive Gen adds the CLI tools at the full profile | Safe tools only |
| Workspace | the assistantβs (main agent) | Genβs own (gen agent, gen-settings.json); no config.toml | the assistantβs |
| Extra prompts | None | creative-memory guidance and the headless experiment prompt, injected as user messages | None |
The world modes keep their own settings and workspace so nothing from the assistantβs memory reaches a world or a shared session unless the user puts it there.
Mobileπ
localgpt-mobile-ffi exposes LocalGPTClient (an Arc<Mutex<Agent>> with its own tokio runtime) through UniFFI proc-macros. Build outputs: liblocalgpt_mobile.a + Swift bindings β an XCFramework for iOS/macOS; liblocalgpt_mobile.so + Kotlin bindings β an AAR for Android. Core is built with embeddings-local + sqlite-vec and none of the subprocess providers or HTTP.
Bridge Daemonπ
A standalone binary that connects to the running daemon over the IPC protocol in localgpt-bridge; localgpt-bridge-cli is the terminal one (rustyline).
Design Principlesπ
- Core stays portable β
localgpt-corecompiles for iOS and Android with no desktop dependencies; clap, eframe, axum, landlock and the like live incli,server,sandbox,cli-toolsorgen. - Dangerous tools live in
cli-toolsβ never in coreβs safe set; server agents and bridges never see them. - One format, one mapping each β fields go into
world-types;world-bevy,world-audioandworld-exportare the only places the format becomes pixels or sound. - One authority per world β
LiveWorldcommits; the canvas, the editor model andlocalgpt worldfollow. A direct write tomanifest.jsonis put back. - Feature flags for the heavy tiers β the in-process LLM, the ML mood model, physics and multiplayer are opt-in, and each has a CI job so gated code cannot rot.
- Graceful degradation β the sandbox falls back on unsupported systems; a missing model leaves the rule-derived draft on screen.