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 — Bounded async channels (Tokio) for in-process clients (TUI, headless), JSONL over stdin/stdout for external clients (ante serve --stdio), 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 streaming responses.

ProviderWire FormatModels
AnthropicMessages APIClaude family (haiku-4-5, sonnet-4-5, sonnet-4-6, opus-4-6)
Anthropic SubscriptionMessages APIClaude family (OAuth)
OpenAIResponses APIGPT-5 family
OpenAI CompatibleChat CompletionsCustom models
OpenAI SubscriptionResponses APIGPT-5 family (OAuth via Codex)
GeminiGemini APIGemini 3 family
Vertex AI GeminiGemini APIGemini 3 family
Grok (xAI)Responses APIGrok 4
ZaiOpenAI-compatibleGLM-4.7
Open RouterOpenAI-compatibleMultiple providers
AntixOpenAI-compatibleClaude, GPT via Antigma (OAuth)
LocalOpenAI-compatibleGGUF models

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, Z_AI_API_KEY, VERTEX_GEMINI_API_KEY)
  • OAuth — Interactive OAuth flow supported for Anthropic, OpenAI, and Antix, handled through the TUI

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 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
BashOutputShellNoRead output from background shells
KillShellShellYesTerminate background shells
AgentBuiltinNoSpawn sub-agent for complex tasks
TodoWriteBuiltinNoManage task lists
WebFetchBuiltinYesFetch and process web content
WebSearchBuiltinYesSearch the web
ImageReadBuiltinNoRead and analyze images (opt-in)

Tool filtering

Tools can be filtered at session level:

  • Allowed list (--allowed-tools) — Only these tools are available
  • Disallowed list (--disallowed-tools) — These tools are removed
  • Supports ToolMatcher syntax: Bash(ls -la), Agent(explore)
  • Names are matched case-insensitively

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. When the context budget nears the limit, auto-compaction summarizes the history

Storage

Ante stores configuration and state across several locations:

LocationPurpose
~/.ante/settings.jsonUser preferences (model, provider, theme)
~/.ante/catalog.jsonCustom provider/model catalog
~/.ante/skills/User-level skills
~/.ante/agents/User-level sub-agents
.ante/Project-local configuration
.ante/projects/Project memory directory
/tmp/ante/Temporary files scoped per project

The ANTE_HOME environment variable can override the home config directory.