Skip to main content

Architecture

Overview​

Ante follows a clean separation of concerns with a client-daemon architecture. The UI and core logic are decoupled through message passing, making it possible to swap frontends (TUI, headless) without changing the underlying engine.

Architecture diagram

Client-Daemon split​

┌────────────────┐ ┌─────────────────────────────┐
│ Client │ Op │ Daemon │
│ │ ───────▶ │ │
│ TUI / Headless │ │ Session ─▶ Turn ─▶ Step │
│ or Serve │ ◀─────── │ │
│ │ Evt │ Tools Providers Store │
└────────────────┘ └─────────────────────────────┘
  • Client — The user-facing layer. The ratatui-based TUI, headless CLI runner, or an external process connected via ante serve. Sends Op operations and renders Evt events.
  • Daemon — The core engine. Receives operations, manages sessions, dispatches to LLM providers, schedules tool execution, and emits events.
  • Transport — A bounded operation channel and unbounded event channel (Tokio) for in-process clients (TUI, headless), JSONL over stdin/stdout for external clients (ante serve --stdio), a Unix domain socket for local clients that dial a shared host (ante serve --sock), or WebSocket for networked clients (ante serve --ws). Message IDs enable tracing across the boundary.

Architecture direction: Session-centric to Agent-centric​

Ante started with a session-centric runtime where Session is the primary execution owner. We are moving toward an agent-centric runtime, where long-lived Agent instances own execution and communicate through messages.

This is similar to an actor-based model:

  • Agent as actor — Each agent has isolated state, a mailbox, and a single logical execution loop.
  • Message-driven coordination — Agents coordinate via typed messages/events instead of shared mutable state.
  • Hierarchical supervision — Parent agents can spawn child agents (sub-agents), monitor outcomes, and decide retry/escalation policy.

Why this shift:

  • Better isolation between concurrent tasks and sub-agents
  • Clear ownership of memory, permissions, and tool budgets per agent
  • More predictable scaling as workflows become multi-agent

In this direction, Session remains important, but as a container for user interaction history, persistence, and protocol-level coordination rather than the only unit of execution.

LLM providers​

Ante is provider-agnostic. Each provider implements a common interface for sending prompts and receiving responses. Transient mid-stream failures reconnect within the turn. Streaming calls fail after five minutes of transport silence; any transport read, including keepalives and partial tool arguments, resets that timer. Buffered calls must finish within the timeout. That window is per provider — override it with stream_idle_timeout_secs.

ProviderWire FormatModels
AnthropicMessages APIClaude 4.5 and 5 families
Anthropic SubscriptionMessages APIClaude family (OAuth)
OpenAIResponses APIGPT-6 Astra and GPT-5 models
OpenAI CompatibleChat CompletionsCustom models
OpenAI SubscriptionResponses APIGPT-6 Astra and GPT-5.6 (OAuth via Codex)
GeminiGemini APIGemini 3.x family
Vertex AI GeminiGemini APIGemini 3.x family
Grok (xAI)Responses APIGrok 4.6
ZaiOpenAI-compatibleGLM-5.3
Open RouterOpenAI-compatibleMulti-vendor chat models
Open Router ResponsesResponses APIGPT models over OpenRouter
Open Router AnthropicMessages APIClaude models over OpenRouter
DeepSeekOpenAI-compatibleDeepSeek V4 family
AntixAnthropic MessagesClaude, GPT, Gemini, Qwen, DeepSeek via Antigma
Antix (API key)Anthropic MessagesSame Antix catalog with API-key auth
LocalOpenAI-compatibleGGUF models via llama.cpp

Providers are resolved from a catalog at session init time. The user can override via CLI flags (--provider, --model) or persistent settings.

Authentication​

  • API keys — Set via environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, OPENROUTER_API_KEY, OPENAI_COMPATIBLE_API_KEY, ZAI_API_KEY, DEEPSEEK_API_KEY, VERTEX_GEMINI_API_KEY, ANTIX_API_KEY)
  • OAuth — Browser sign-in for Anthropic, OpenAI, Antix, and any oauth_profiles entry, through /providers in the TUI or ante auth login
  • Stored keys and helpers — ante auth add stores a key; a helpers command can supply one. See Credentials

Tool system​

Tools are the agent's hands. Each tool implements the Tool trait:

#[async_trait]
pub trait Tool: Send + Sync {
fn metadata(&self) -> &ToolMetadata;
async fn call(&self, input: ToolCallInput) -> Result<ToolCallOutput>;
}

Built-in tools​

ToolCategoryApprovalDescription
ReadFile I/ONoRead text, image, or PDF file contents
WriteFile I/OYesCreate or overwrite files
EditFile I/OYesExact string replacement in files
GlobFile I/ONoFind files by pattern
GrepFile I/ONoSearch file contents with regex
BashShellYesExecute shell commands; returns a durable handle when a command outlives its max_wait_ms window
AgentBuiltinNoSpawn sub-agent for complex tasks
AskUserBuiltinNoAsk structured questions; pauses attended sessions for an answer
TodoWriteBuiltinNoManage task lists (opt-in)
WebFetchBuiltinYesFetch and process web content
WebSearchBuiltinYesSearch the web (auto-enabled on web-search-capable providers)
ViewImageBuiltinNoRead and analyze images (opt-in)

Tool filtering​

Tools can be filtered at session level:

  • Base list (--tools) — Replace the default set with exactly these tools
  • Include list (--include-tools) — Add tools on top of the default or --tools base set
  • Exclude list (--exclude-tools) — Remove tools after the base and include lists are applied
  • Supports ToolMatcher syntax: Bash(ls -la), Agent(explore)
  • Names are matched case-insensitively
  • The same selection gates dynamically registered tools (MCP servers), so they cannot bypass the filter

Session lifecycle​

  1. Client sends Op::StartSession with model, provider, and policy
  2. Daemon resolves the provider, authenticates, discovers skills and sub-agents
  3. Daemon creates a Session and emits Evt::SessionStart
  4. User sends Op::UserInput to start a task
  5. Session spawns a Turn which communicates with the LLM
  6. Turn executes tools, requests approvals, and eventually completes
  7. As the conversation approaches the context limit, Ante summarizes older context while retaining recent conversation and user messages