Spacebot is a multi-platform conversational AI agent system implemented in Rust. It provides a complete framework for building AI agents that can interact with users across messaging platforms (Discord, Slack, Telegram, Twitch, Email), execute tasks with shell/file/browser access, maintain long-term memory, and supervise their own operation.
The system is designed around a process model where each major activity (conversation management, reasoning, task execution, system observation) runs in a dedicated process with role-specific tool access. This architecture enables fine-grained supervision, resource isolation, and parallel execution of complex workflows.
Scope: This page provides a high-level introduction to Spacebot's architecture, process types, and major subsystems. For detailed information about specific components:
The following diagram maps Spacebot's major subsystems to their implementation in the codebase:
Sources: src/main.rs331-421 src/lib.rs380-404 src/api/server.rs31-329 src/api/state.rs48-141 src/agent/channel.rs478-595 src/llm/manager.rs33-60 src/messaging/manager.rs1-50
| Subsystem | Purpose | Primary Implementation |
|---|---|---|
| Entry Point | CLI parsing, daemon lifecycle, onboarding | src/main.rs |
| HTTP API | REST endpoints, SSE event stream, web dashboard backend | src/api/server.rs src/api/state.rs |
| Agent Runtime | Hot-reloadable configuration, event bus, dependency injection | src/config/runtime.rs src/lib.rs380-404 |
| Process Types | Channel, Branch, Worker, Cortex (see below) | src/agent/ |
| Intelligence Layer | LLM provider routing, memory search, prompt assembly | src/llm/ src/memory/ src/prompts/ |
| Tool System | Process-specific tool servers, 40+ built-in tools | src/tools/ |
| Messaging Adapters | Platform normalization (Discord, Slack, Telegram, etc.) | src/messaging/ |
| Persistence | SQLite (structured), LanceDB (vectors), REDB (secrets) | Database initialization in src/db.rs |
Sources: src/main.rs1-1400 src/lib.rs1-404 src/api/server.rs1-472 src/config/runtime.rs1-350
Spacebot implements a hierarchical process model with four distinct process types. Each type runs in its own tokio task with isolated tool access and specific responsibilities.
Sources: src/lib.rs80-101 src/lib.rs63-78 src/agent/channel.rs394-456 src/agent/branch.rs1-50 src/agent/worker.rs1-100 src/agent/cortex.rs1-100
Channel (ProcessType::Channel)
reply, branch, spawn_worker, route, cancel, skip, react)Branch (ProcessType::Branch)
memory_save, memory_recall, memory_delete, task_create, task_list, task_updateWorker (ProcessType::Worker)
shell, file_read, file_write, file_edit, browser, set_status, task_update (scoped)Cortex (ProcessType::Cortex)
memory_save (consolidation only)Sources: src/lib.rs80-101 src/agent/channel.rs1-2100 src/agent/branch.rs1-800 src/agent/worker.rs1-1500 src/agent/cortex.rs1-1000
The following diagram shows how messages flow through Spacebot from external platforms to the agent runtime and back:
Sources: src/messaging/discord.rs1-100 src/messaging/slack.rs1-150 src/main.rs310-329 src/agent/channel.rs940-1500 src/llm/model.rs245-490 src/tools/reply.rs1-240
All messaging adapters implement the Messaging trait (src/messaging/traits.rs1-50) which requires:
start(): Launch platform connection, return InboundStreamrespond(): Send OutboundResponse to platformsend_status(): Update typing indicator or similarEach adapter normalizes platform events into InboundMessage:
Sources: src/lib.rs426-470 src/messaging/traits.rs1-100 src/messaging/discord.rs100-200 src/messaging/slack.rs150-250
Outbound responses are paired with the originating InboundMessage via RoutedResponse (src/lib.rs472-478):
The target.metadata map contains platform-specific fields (e.g., discord_channel_id, slack_thread_ts) that adapters use to route replies to the correct thread/channel.
Sources: src/lib.rs472-478 src/main.rs310-329 src/messaging/discord.rs140-300 src/messaging/slack.rs500-700
Spacebot supports multiple LLM providers through a unified routing layer:
rig::completion::CompletionModel with retry + fallback logicThe system supports 20+ providers including Anthropic, OpenAI, OpenRouter, Google Gemini, DeepSeek, and local Ollama instances. Provider credentials are hot-reloadable via ArcSwap.
Sources: src/llm/manager.rs1-250 src/llm/model.rs1-550 src/llm/routing.rs1-150 src/config/providers.rs1-300
A hybrid graph + vector memory system:
memories table): Typed memories (identity, fact, decision, event, etc.)associations table): Directed graph edges (RelatedTo, Updates, Contradicts, etc.)Cortex maintains memory health through periodic decay, pruning, and merging operations.
Sources: src/memory/search.rs1-400 src/memory/store.rs1-500 src/agent/cortex.rs200-600
Tools are registered per-process-type with isolated ToolServer instances:
reply, branch, spawn_worker, route, cancel, skip, react, send_message, send_filememory_save, memory_recall, task_create, task_list, task_update, spacebot_docsshell, file_read, file_write, file_edit, file_list, browser, set_status, secret_setTools implement rig::tool::Tool and use JSON Schema for argument validation.
Sources: src/tools/reply.rs1-240 src/tools/spawn_worker.rs1-400 src/tools/memory_tools.rs1-300 src/tools/shell.rs1-200 src/agent/channel.rs538-540
Three database backends:
| Database | Purpose | Schema | Access Pattern |
|---|---|---|---|
| SQLite | Conversations, process runs, tasks, cron jobs, memories | src/db.rs1-500 | sqlx::SqlitePool via AgentDeps |
| LanceDB | Embedding vectors for memory search | src/memory/embedding.rs | Per-agent lancedb::Connection |
| REDB | Encrypted secret storage (AES-GCM + Argon2) | src/secrets/store.rs | Singleton SecretsStore |
Sources: src/db.rs1-500 src/memory/embedding.rs1-300 src/secrets/store.rs1-800 src/conversation/logger.rs1-200
Spacebot configuration is managed through a layered system:
env:VARIABLE_NAME syntax (src/config/load.rs1-400)secret:SECRET_NAME syntax (src/config/load.rs14-20)ArcSwap (src/config/runtime.rs1-350)Configuration changes are detected by a file watcher (src/config/watcher.rs1-150) and propagate to running processes without restart.
Sources: src/config.rs1-900 src/config/load.rs1-600 src/config/runtime.rs1-350 src/config/watcher.rs1-150
Spacebot supports three deployment modes:
| Mode | Entry Point | Configuration | Use Case |
|---|---|---|---|
| Native | cargo run or Homebrew binary | ~/.spacebot/config.toml | Development, local use |
| Docker | Dockerfile multi-stage build | /data/config.toml (volume mount) | Containerized deployment |
| Hosted | Fly.io or similar | Platform secrets + volume | Cloud hosting |
The Docker image includes self-update capability (src/update/docker.rs1-300) where the container can pull a new image, create a replacement container, and atomically swap before terminating.
Sources: src/main.rs331-421 src/daemon.rs1-400 src/update/docker.rs1-300 Dockerfile1-100
All process lifecycle and tool execution events flow through a per-agent broadcast channel:
Events are:
tokio::sync::broadcast::Sender<ProcessEvent> (src/lib.rs319-344)Sources: src/lib.rs148-311 src/lib.rs319-344 src/agent/channel.rs946-1100 src/agent/cortex.rs100-400 src/api/system.rs1-200