Architecture Deep Dive
Understanding jaato's architecture will help you navigate the codebase and identify where to make changes. This guide covers the core components, plugin system, and execution flows.
High-Level Architecture
At its core, jaato is a client framework that orchestrates communication between your application, AI models, and tool execution. Here's the layered architecture:
(Your code that uses jaato)"] end subgraph JaatoLayer["Jaato Framework Layer"] subgraph JaatoClient["JaatoClient (Main Orchestrator)"] API["Public API:
• connect()
• configure_tools()
• send_message()
• get_history()"] end subgraph CoreComponents["Core Components"] TE["ToolExecutor
(Runs tool functions)"] PR["PluginRegistry
(Manages plugins)"] TL["TokenLedger
(Token accounting)"] end subgraph PluginLayer["Plugin Layer"] PERM["PermissionPlugin
(Access control)"] TOOLS["Tool Plugins
(CLI, MCP, Todo, etc.)"] end end subgraph ProviderLayer["Provider Abstraction Layer"] Provider["ModelProviderPlugin
(Provider-agnostic interface)"] end subgraph ExternalServices["External AI Services"] Google["Google GenAI
(Gemini models)"] Anthropic["Anthropic
(Claude models)"] Others["Others..."] end App --> API API --> TE API --> PR API --> TL TE --> PERM PR --> TOOLS TE --> TOOLS API --> Provider Provider --> Google Provider --> Anthropic Provider --> Others classDef clientStyle fill:#e1f5ff,stroke:#0288d1,stroke-width:2px classDef frameworkStyle fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px classDef providerStyle fill:#fff3e0,stroke:#f57c00,stroke-width:2px classDef externalStyle fill:#e8f5e9,stroke:#388e3c,stroke-width:2px class App clientStyle class API,TE,PR,TL,PERM,TOOLS frameworkStyle class Provider providerStyle class Google,Anthropic,Others externalStyle
Key layers:
- Application Layer (Blue) - Your code using jaato
- Framework Layer (Purple) - jaato's core orchestration and plugin system
- Provider Layer (Orange) - Abstract AI provider interface
- External Services (Green) - AI model providers (Google, Anthropic, etc.)
Component Diagram
This diagram shows how the major components relate to each other and which external services they interact with.
jaato_client.py] subgraph Core["Core Components"] TE[ToolExecutor
ai_tool_runner.py] TL[TokenLedger
token_accounting.py] end subgraph Plugins["Plugin System"] PR[PluginRegistry
plugins/registry.py] subgraph Available["Available Plugins"] BG[BackgroundPlugin] CLI[CLIToolPlugin] MCP[MCPToolPlugin] PERM[PermissionPlugin] TODO[TodoPlugin] REFS[ReferencesPlugin] FEDIT[FileEditPlugin] SESS[SessionPlugin] end end MCM[MCPClientManager
mcp_context_manager.py] end subgraph External["External Services"] VAI[AI Provider
Models] MCPS[MCP Servers] Shell[Local Shell] end App --> JC JC --> TE JC --> TL JC --> PR PR --> BG PR --> CLI PR --> MCP PR --> PERM PR --> TODO PR --> REFS PR --> FEDIT TE --> PERM TE --> BG BG --> CLI BG --> MCP MCP --> MCM MCM --> MCPS CLI --> Shell JC --> VAI
Message Flow Sequence
When a user sends a message, jaato orchestrates communication between the model and tools. Here's the typical flow:
The sequence above can repeat multiple times if the model makes additional function calls based on previous results. JaatoClient handles this loop automatically until the model returns a final text response.
Plugin System Architecture
jaato has three distinct plugin systems, each serving a different purpose:
1. Tool Plugins
Managed by PluginRegistry, these provide tools for the model
to call via function calling. Examples: CLI, MCP, file editing, web search.
- Location:
shared/plugins/*/ - Entry Point:
jaato.plugins - Protocol:
ToolPlugin - Key Methods:
get_tool_schemas(),get_executors()
2. GC (Garbage Collection) Plugins
Manage context window overflow by removing or summarizing old conversation turns. Strategies: truncate, summarize, hybrid.
- Location:
shared/plugins/gc_*/ - Entry Point:
jaato.gc_plugins - Protocol:
GCPlugin - Key Methods:
should_collect(),collect()
3. Model Provider Plugins
Abstract AI provider SDKs to provide a uniform interface. Supports Anthropic, Google GenAI, GitHub Models, Claude CLI, Antigravity, and Ollama.
- Location:
shared/plugins/model_provider/*/ - Entry Point:
jaato.model_providers - Protocol:
ModelProviderPlugin - Key Methods:
connect(),send_message(),get_history()
File Structure
Understanding where code lives will help you navigate the codebase:
jaato/
├── shared/ # Core framework (internal)
│ ├── __init__.py # Package exports
│ ├── jaato_client.py # JaatoClient - main orchestrator
│ ├── ai_tool_runner.py # ToolExecutor - function loop
│ ├── token_accounting.py # TokenLedger - usage tracking
│ ├── mcp_context_manager.py # MCP server connections
│ │
│ └── plugins/ # Plugin system
│ ├── base.py # ToolPlugin protocol
│ ├── registry.py # PluginRegistry
│ │
│ ├── model_provider/ # Provider abstraction
│ │ ├── base.py # ModelProviderPlugin protocol
│ │ ├── types.py # Provider-agnostic types
│ │ ├── anthropic/ # Anthropic Claude
│ │ ├── google_genai/ # Google GenAI / Vertex AI
│ │ ├── github_models/ # GitHub Models API
│ │ ├── claude_cli/ # Claude CLI wrapper
│ │ ├── antigravity/ # Google IDE backend
│ │ └── ollama/ # Ollama local models
│ │
│ ├── cli/ # CLI tool plugin
│ ├── mcp/ # MCP integration
│ ├── permission/ # Permission control
│ ├── todo/ # Task planning
│ ├── file_edit/ # File operations
│ ├── web_search/ # DuckDuckGo search
│ ├── session/ # Session persistence
│ │
│ ├── gc_truncate/ # GC: truncation strategy
│ ├── gc_summarize/ # GC: summarization strategy
│ └── gc_hybrid/ # GC: hybrid strategy
│
├── jaato/ # Public API (for external use)
│ └── __init__.py # Re-exports from shared/
│
├── simple-client/ # Reference implementation
│ └── interactive_client.py # Interactive CLI client
│
└── docs/ # Documentation
├── api/ # HTML API docs (this site)
└── architecture.md # Architecture markdown
UI Hooks System
The framework provides a UI hooks system (AgentUIHooks protocol) that enables
rich terminal UIs to integrate with agent execution. This provides visibility into agent
lifecycle, tool execution, and accounting.
Key Hooks
| Hook | When Called | Purpose |
|---|---|---|
on_agent_status_changed |
Status change | Start/stop spinner ("active", "done", "error") |
on_tool_call_start |
Tool begins | Show active tool below spinner |
on_tool_call_end |
Tool completes | Remove tool from display |
on_agent_output |
Any output | Route to agent's output buffer |
on_agent_turn_completed |
Turn ends | Update per-turn accounting |
Tool Call Visualization
The on_tool_call_start and on_tool_call_end hooks enable real-time
visualization of active tool calls. When a tool is executing, the UI can show it below the spinner:
Model> ⠋ thinking...
├─ cli_execute({'cmd': 'ls -la'})
└─ web_search({'query': 'python docs'})
These hooks are emitted automatically for all plugins from
JaatoSession._run_chat_loop(). No plugin-specific changes are required.
Hook and Callback Propagation
Hooks and callbacks are set at multiple levels to ensure all agents behave consistently:
JaatoClient.set_ui_hooks(hooks)- Main agent, passes to sessionJaatoSession.set_ui_hooks(hooks, agent_id)- Tool lifecycle emissionJaatoSession.set_retry_callback(callback)- Routes retry notifications through custom handlerSubagentPlugin.set_ui_hooks(hooks)- Passes to spawned sessionsSubagentPlugin.set_retry_callback(callback)- Passes to spawned sessionsSubagentPlugin.set_plan_reporter(reporter)- Injects plan reporter into subagent TodoPlugins
The retry callback ensures rate limit retry messages from subagents are routed through the same channel as the parent (e.g., to the rich client's output panel) instead of printing to console.
The plan reporter ensures subagent plans are displayed in the UI (e.g., status bar popup) instead
of the console. The reporter is injected via _injected_reporter in the TodoPlugin config.
See Subagent UI Hooks API for complete documentation.
Key Abstractions
Provider-Agnostic Types
To support multiple AI providers, jaato defines its own types in
shared/plugins/model_provider/types.py:
ToolSchema- Function declaration (replaces SDK-specific types)Message- Conversation message with role and partsPart- Message content (text, function_call, function_response)ProviderResponse- Unified response from any provider
Plugin Discovery
Plugins register via Python entry points in pyproject.toml:
[project.entry-points."jaato.plugins"]
cli = "shared.plugins.cli:create_plugin"
mcp = "shared.plugins.mcp:create_plugin"
todo = "shared.plugins.todo:create_plugin"
[project.entry-points."jaato.gc_plugins"]
gc_truncate = "shared.plugins.gc_truncate:create_plugin"
gc_summarize = "shared.plugins.gc_summarize:create_plugin"
User Commands vs Model Tools
Plugins can provide two types of capabilities:
| Type | Invoked By | History | Example |
|---|---|---|---|
| Model Tools | AI via function calling | Always in history | cli_execute, web_search |
| User Commands | User types directly | Configurable | plan, sessions |
Related Pages
🏁 Getting Started
Set up your development environment and run tests.
🔌 Plugin Concepts
Learn how the plugin system works from a user perspective.
🛠️ Building Plugins
Step-by-step guide to creating your own tool plugin.
📄 Full Architecture Doc
Complete architecture markdown with all diagrams and details.