apollo
apollo is a local-first Rust AI agent runtime for people who want the bot on their own machine, not hidden behind a hosted control plane.
Single ~16MB binary, ~41ms warm start, async-first (tokio), trait-driven. Ships with 10+ messaging channels, 20+ LLM providers, pluggable memory (SurrealDB + RocksDB), tool guardrails, context compaction, XML tool-call recovery, autonomous coding mode, and a plugin system with lifecycle hooks.
Features
Core
- Async-first — tokio throughout, no blocking on the runtime thread
- Trait-driven architecture — swap providers, channels, tools, memory backends
- Tool guardrails — loop detection, idempotent vs mutating classification, failure counting, configurable warn/block thresholds
- Pluggable context compaction — summarizer trait + default LLM-based compactor with configurable thresholds
- Self-healing retry — auto re-prompts LLM with error context on tool failures
- rx4 rotary harness — the agent loop is owned by the rx4 (rotary) engine; apollo owns everything around it (context, tools, memory, persistence)
- XML tool-call recovery — state-machine parser extracts
<tool_call>blocks from the response text, so providers without native tool calling still work. The parser also supports incremental feeding for streaming callers - Lifecycle hooks — plugins can intercept pre/post tool calls, session start/end
- Skill template preprocessing —
${HERMES_SKILL_DIR},${HERMES_SESSION_ID}variables +!\command`` inline shell execution in SKILL.md
Messaging Channels
Telegram, CLI, Discord, Slack, WhatsApp, Matrix, Signal, IRC, Google Chat, MS Teams
Telegram and CLI are the default features and the two exercised against the
real services. The rest are opt-in Cargo features, covered end-to-end against
a mock server by tests/channel_conformance.rs. Verify one against its real
service with apollo channel-check --channel <name>.
LLM Providers
Anthropic (default), OpenAI-compat, Ollama, Copilot, OpenRouter, Groq, Together, Mistral, DeepSeek, Fireworks, Perplexity, xAI, Moonshot, Venice, HuggingFace, SiliconFlow, Cerebras, MiniMax, Vercel, Cloudflare
Tools
shell, file_ops (read/write/list), edit, web_search, web_fetch, vibemania (subspace coding agent), dynamic tools, MCP bridge, session management, cron scheduling, browser automation, message send, config management, mode switching, brief summary, and feature-gated signed desktop actions through Praefectus
Web search
web_search picks a backend from the environment, in order:
SEARXNG_URL— a self-hosted SearXNG instance. Ranked results, no third-party key, and only the query leaves the machine.- DuckDuckGo — keyless and always available. Reads the lite result page, and falls back to the Instant Answer API when that page is refused.
PERPLEXITY_API_KEY— paid, kept for existing setups.
Anthropic can also run the search itself, which replaces the tool rather than configuring it:
The model searches during its own turn, so results never round-trip through
apollo and nothing needs a search key — but the searches are billed by Anthropic,
and apollo's web_search tool is left unregistered to keep the name unambiguous.
Other providers ignore the setting.
Memory
- SurrealDB + RocksDB backend with conversation history, BM25 full-text search, vector embeddings
- Each embedding records its dimension and model. Vector search filters by dimension and scores with an in-process cosine scan, so switching embedding models never mixes incomparable vectors. There is no ANN index — recall is exact and linear in the namespace
- RocksDB opens lazily on first use, not on the boot path
- Sticker cache, file indexing, code chunk storage
- Plugable via
MemoryProvidertrait
Advanced
- Autonomous coding mode — 24/7 loop: reads TODO.md, runs agent, validates with tests, commits/pushes only on success. Failure pause state persists across restarts
- Skill curator — background task reviews skills, suggests improvements for stale/empty/low-quality skills
- Trajectory export — ReAct step serialization (thought→action→observation) for RL training data
- Agent swarm — parallel sub-agent spawning for distributed task execution
- Cron scheduler — SurrealDB-backed recurring and one-shot tasks with execution leases, retries, and in-memory fallback
- Plugin system — JSON-RPC 2.0 + lifecycle hooks (pre/post tool, session events)
- Hot-reloadable tools, skills, and system prompt
- Self-update — git poll + rebuild + optional restart
Quick Start
# From crates.io (binaries: apollo, apollo-install)
# From source
Other subcommands: status, mcp, message (msg), cron, autonomous,
swarm, self-update.
Install from a release binary (after build):
Agent HTTP API
apollo chat and apollo serve expose the agent on 127.0.0.1:31338
(APOLLO_HTTP_PORT overrides the port, APOLLO_HTTP=0 disables the server):
POST /v1/chat—{"message": "...", "chat_id": "..."}GET /v1/chat/stream— WebSocket, same request body, streamed eventsGET /health— unauthenticated liveness check
Breaking change: the API now requires a bearer token. Both /v1/chat and
the WebSocket need Authorization: Bearer <token> and return 401 without it.
The server generates a token on first run and writes it to
~/.apollo/http-token (mode 0600); set APOLLO_HTTP_TOKEN to supply your own
to the server and its clients instead. Existing scripts must be updated:
Requests carrying an Origin header are refused with 403 on both endpoints.
Browsers always send Origin, so no web page can drive the agent; native
clients (the TUI, apollo-ui, curl) never send it.
Current Status
- ✅
cargo clippy --all-targets --all-features— 0 warnings - ✅
cargo test --all-features— passing - ✅
cargo build --release— passes, ~16MBapollobinary - ✅ v0.3.1 — install from source, release binary, or
cargo install apollo-agent(crates.io package; binariesapollo,apollo-install)
Configuration
Initialize with apollo init, edit apollo.json. Key sections:
agent— max rounds, history limit, model selection, compaction thresholdsprovider— LLM backend choice + credentialschannel— messaging platform configpolicy— shell/dynamic tool/plugin permission gatesruntime.self_update— auto-update git pollingtoolsets.enabled/disabled— per-platform tool allow/deny lists
Validation
--all-features is not optional — several providers are behind non-default
features.
Storage
- SurrealDB + RocksDB is the only backend for memory, session state, and swarm/coordinator data.
storage.backendis fixed tosurreal.- Startup fails fast if config requests any other storage mode.