Skip to main content

Architecture

This page is the top-level map of Minerva Agent internals. Use it to orient yourself in the codebase, then dive into subsystem-specific docs for implementation details.

System Overview​

┌─────────────────────────────────────────────────────────────────────┐
│ Entry Points │
│ │
│ CLI (cli.py) Gateway (gateway/run.py) ACP (acp_adapter/) │
│ TUI / Desktop API Server Python Library │
└──────────┬──────────────┬───────────────────────┬───────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ AIAgent (run_agent.py) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Prompt │ │ Provider │ │ Tool │ │
│ │ Builder │ │ Resolution │ │ Dispatch │ │
│ │ (prompt_ │ │ (runtime_ │ │ (model_ │ │
│ │ builder.py) │ │ provider.py)│ │ tools.py) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐ │
│ │ Compression │ │ 3 API Modes │ │ Tool Registry│ │
│ │ & Caching │ │ chat_compl. │ │ (registry.py)│ │
│ │ │ │ codex_resp. │ │ 70+ tools │ │
│ │ │ │ anthropic │ │ ~40 toolsets │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────┴─────────────────┴─────────────────┴───────────────────────┘
│ │
▼ ▼
┌───────────────────┐ ┌──────────────────────┐
│ Session Storage │ │ Tool Backends │
│ (SQLite + FTS5) │ │ Terminal (7 backends) │
│ minerva_state.py │ │ Browser (5 backends) │
│ gateway/session.py│ │ Web (10 backends) │
└───────────────────┘ │ MCP (dynamic) │
│ File, Vision, etc. │
└──────────────────────┘

Directory Structure​

minerva-agent/
├── run_agent.py # AIAgent facade — loop lives in agent/conversation_loop.py + agent/turn_*.py
├── cli.py # MinervaCLI facade — mixins in minerva_cli/cli_*_mixin.py
├── model_tools.py # Tool discovery, schema collection, dispatch
├── toolsets.py # Tool groupings and platform presets
├── minerva_state.py # SQLite session/state database facade (+ minerva_state_*.py siblings)
├── minerva_constants.py # MINERVA_HOME, profile-aware paths
│
├── agent/ # Agent internals
│ ├── prompt_builder.py # System prompt assembly
│ ├── context_engine.py # ContextEngine ABC (pluggable)
│ ├── context_compressor.py # Default engine — lossy summarization
│ ├── prompt_caching.py # Anthropic prompt caching
│ ├── auxiliary_client.py # Auxiliary LLM for side tasks (vision, summarization)
│ ├── model_metadata.py # Model context lengths, token estimation
│ ├── models_dev.py # models.dev registry integration
│ ├── anthropic_adapter.py # Anthropic Messages API format conversion
│ ├── display.py # KawaiiSpinner, tool preview formatting
│ ├── skill_commands.py # Skill slash commands
│ ├── memory_manager.py # Memory manager orchestration
│ ├── memory_provider.py # Memory provider ABC
│ └── trajectory.py # Trajectory saving helpers
│
├── minerva_cli/ # CLI subcommands and setup
│ ├── main.py # Entry point — `minerva` subcommands (parsers in subcommands/, main_*.py)
│ ├── config.py # DEFAULT_CONFIG, OPTIONAL_ENV_VARS, migration
│ ├── commands.py # COMMAND_REGISTRY — central slash command definitions
│ ├── auth.py # PROVIDER_REGISTRY, credential resolution (+ auth_*.py siblings)
│ ├── runtime_provider.py # Provider → api_mode + credentials
│ ├── models.py # Model catalog, provider model lists
│ ├── model_switch.py # /model command logic (CLI + gateway shared)
│ ├── setup.py # Interactive setup wizard (+ setup_*.py siblings)
│ ├── skin_engine.py # CLI theming engine
│ ├── skills_config.py # minerva skills — enable/disable per platform
│ ├── skills_hub.py # /skills slash command
│ ├── tools_config.py # minerva tools — enable/disable per platform
│ ├── plugins.py # PluginManager — discovery, loading, hooks
│ ├── callbacks.py # Terminal callbacks (clarify, sudo, approval)
│ └── gateway.py # minerva gateway start/stop
│
├── tools/ # Tool implementations (one file per tool)
│ ├── registry.py # Central tool registry
│ ├── approval.py # Dangerous command detection
│ ├── terminal_tool.py # Terminal orchestration
│ ├── process_registry.py # Background process management
│ ├── file_tools.py # read_file, write_file, patch, search_files
│ ├── web_tools.py # web_search, web_extract
│ ├── browser_tool.py # Browser automation tools facade (+ browser_tool_*.py siblings)
│ ├── code_execution_tool.py # execute_code sandbox
│ ├── delegate_tool.py # Subagent delegation
│ ├── mcp_tool.py # MCP client facade (+ mcp_tool_*.py siblings)
│ ├── credential_files.py # File-based credential passthrough
│ ├── env_passthrough.py # Env var passthrough for sandboxes
│ ├── ansi_strip.py # ANSI escape stripping
│ └── environments/ # Terminal backends (local, docker, ssh, modal, daytona, singularity, vercel_sandbox)
│
├── gateway/ # Messaging platform gateway
│ ├── run.py # GatewayRunner facade — message dispatch (+ run_*.py siblings)
│ ├── session.py # SessionStore — conversation persistence
│ ├── delivery.py # Outbound message delivery
│ ├── pairing.py # DM pairing authorization
│ ├── hooks.py # Hook discovery and lifecycle events
│ ├── mirror.py # Cross-session message mirroring
│ ├── status.py # Token locks, profile-scoped process tracking
│ └── platforms/ # Built-in adapters: webhook, api_server
│
├── plugins/platforms/ # Bundled platform plugins: telegram, discord, slack
│
├── acp_adapter/ # ACP server (VS Code / Zed / JetBrains)
├── cron/ # Scheduler (jobs.py, scheduler.py)
├── plugins/memory/ # Memory provider plugins
├── plugins/context_engine/ # Context engine plugins
├── skills/ # Bundled skills, by category (all active)
├── website/ # Docusaurus documentation site
└── tests/ # Pytest suite (~40,000 tests across ~3,500 files)

Data Flow​

CLI Session​

User input → MinervaCLI.chat()
→ AIAgent.run_conversation()
→ system_prompt.build_system_prompt()
→ runtime_provider.resolve_runtime_provider()
→ API call (chat_completions / codex_responses / anthropic_messages)
→ tool_calls? → model_tools.handle_function_call() → loop
→ final response → display → save to SessionDB

Gateway Message​

Platform event → Adapter.on_message() → MessageEvent
→ GatewayRunner._handle_message()
→ authorize user
→ resolve session key
→ create AIAgent with session history
→ AIAgent.run_conversation()
→ deliver response back through adapter

Cron Job​

Scheduler tick → load due jobs from jobs.json
→ create fresh AIAgent (no history)
→ inject attached skills as context
→ run job prompt
→ deliver response to target platform
→ update job state and next_run

If you are new to the codebase:

  1. This page — orient yourself
  2. Agent Loop Internals — how AIAgent works
  3. Prompt Assembly — system prompt construction
  4. Provider Runtime Resolution — how providers are selected
  5. Adding Providers — practical guide to adding a new provider
  6. Tools Runtime — tool registry, dispatch, environments
  7. Session Storage — SQLite schema, FTS5, session lineage
  8. Gateway Internals — messaging platform gateway
  9. Context Compression & Prompt Caching — compression and caching
  10. ACP Internals — IDE integration

Major Subsystems​

Agent Loop​

The synchronous orchestration engine (AIAgent, exposed by the run_agent.py facade; the loop lives in agent/conversation_loop.py and agent/turn_*.py). Handles provider selection, prompt construction, tool execution, retries, fallback, callbacks, compression, and persistence. Supports three API modes for different provider backends.

→ Agent Loop Internals

Prompt System​

Prompt construction and maintenance across the conversation lifecycle:

  • system_prompt.py + prompt_builder.py — assembles the ordered system-prompt tiers (stable → context → volatile): identity/tool guidance/skills, context files, then memory/profile/timestamp blocks
  • prompt_caching.py — Applies Anthropic cache breakpoints for prefix caching
  • context_compressor.py — Summarizes middle conversation turns when context exceeds thresholds

→ Prompt Assembly, Context Compression & Prompt Caching

Provider Resolution​

A shared runtime resolver used by CLI, gateway, cron, ACP, and auxiliary calls. Maps (provider, model) tuples to (api_mode, api_key, base_url). Handles 18+ providers, OAuth flows, credential pools, and alias resolution.

→ Provider Runtime Resolution

Tool System​

Central tool registry (tools/registry.py) with 70+ registered tools across ~40 toolsets. Each tool file self-registers at import time. The registry handles schema collection, dispatch, availability checking, and error wrapping. Terminal tools support 7 backends (local, Docker, SSH, Daytona, Modal, Singularity, Vercel Sandbox).

→ Tools Runtime

Session Persistence​

SQLite-based session storage with FTS5 full-text search. Sessions have lineage tracking (parent/child across compressions), per-platform isolation, and atomic writes with contention handling.

→ Session Storage

Messaging Gateway​

Long-running process with platform adapters (Telegram, Discord, Slack, webhooks, API server), unified session routing, user authorization (allowlists + DM pairing), slash command dispatch, hook system, cron ticking, and background maintenance.

→ Gateway Internals

Plugin System​

Three discovery sources: ~/.minerva/plugins/ (user), .minerva/plugins/ (project), and pip entry points. Plugins register tools, hooks, and CLI commands through a context API. Two specialized plugin types exist: memory providers (plugins/memory/) and context engines (plugins/context_engine/). Both are single-select — only one of each can be active at a time, configured via minerva plugins or config.yaml.

→ Plugin Guide, Memory Provider Plugin

Cron​

First-class agent tasks (not shell tasks). Jobs store in JSON, support multiple schedule formats, can attach skills and scripts, and deliver to any platform.

→ Cron Internals

ACP Integration​

Exposes Minerva as an editor-native agent over stdio/JSON-RPC for VS Code, Zed, and JetBrains.

→ ACP Internals

Trajectories​

Saves agent sessions as ShareGPT-format trajectories (save_trajectories) for training data or debugging.

→ Trajectories & Training Format

Design Principles​

PrincipleWhat it means in practice
Prompt stabilitySystem prompt doesn't change mid-conversation. No cache-breaking mutations except explicit user actions (/model).
Observable executionEvery tool call is visible to the user via callbacks. Progress updates in CLI (spinner) and gateway (chat messages).
InterruptibleAPI calls and tool execution can be cancelled mid-flight by user input or signals.
Platform-agnostic coreOne AIAgent class serves CLI, TUI/desktop, gateway, ACP, and API server. Platform differences live in the entry point, not the agent.
Loose couplingOptional subsystems (MCP, plugins, memory providers) use registry patterns and check_fn gating, not hard dependencies.
Profile isolationEach profile (minerva -p <name>) gets its own MINERVA_HOME, config, memory, sessions, and gateway PID. Multiple profiles run concurrently.

File Dependency Chain​

tools/registry.py (no deps — imported by all tool files)
↑
tools/*.py (each calls registry.register() at import time)
↑
model_tools.py (imports tools/registry + triggers tool discovery)
↑
run_agent.py, cli.py

This chain means tool registration happens at import time, before any agent instance is created. Any tools/*.py file with a top-level registry.register() call is auto-discovered — no manual import list needed.