docs: restructure documentation into multilevel directory layout

New structure: docs/ split into 11 subdirectories (getting-started/,
agents/, providers/, sidecar/, multi-machine/, plugins/, config/,
production/, architecture/, contributing/, pro/).

New files:
- docs/README.md: navigation index with audience table
- docs/getting-started/quickstart.md: install, build, first session
- docs/config/ref-settings.md: all env vars, config files, databases
- docs/architecture/overview.md: split from architecture.md (>300 lines)
- docs/pro/README.md: Pro edition overview
- docs/pro/features/analytics.md: analytics dashboard docs
- docs/pro/features/cost-intelligence.md: budget + router docs

Remaining docs being written by background agents — will be committed
in follow-up when complete.
This commit is contained in:
Hibryda 2026-03-17 04:15:15 +01:00
parent 738574b9f0
commit 8251321dac
7 changed files with 1268 additions and 59 deletions

View file

@ -1,79 +1,87 @@
---
title: "Documentation"
role: part
parent: null
order: 1
description: "Project documentation index"
---
# Agents Orchestrator — Documentation
# Agent Orchestrator Documentation
Multi-project AI agent dashboard with terminal, SSH, and multi-provider session management.
Built with Tauri 2.x (Rust) + Svelte 5 + Claude Agent SDK.
Agent Orchestrator (formerly Agents Orchestrator) is a multi-project AI agent orchestration dashboard built with Tauri 2.x, Svelte 5, and the Claude Agent SDK. It transforms a traditional terminal emulator into a mission control for running, monitoring, and coordinating multiple AI agent sessions across multiple codebases simultaneously.
> **Source of truth.** Before making changes, consult these docs. After making changes, update them.
The application has three major version milestones:
## Quick Navigation
- **v1** — A single-file Python GTK3+VTE terminal emulator with Claude Code session management. Production-stable, still shipped as `agor`.
- **v2** — A ground-up rewrite using Tauri 2.x (Rust backend) + Svelte 5 (frontend). Multi-pane terminal with structured agent sessions, subagent tree visualization, session persistence, multi-machine relay support, 17 themes, and comprehensive packaging.
- **v3 (Mission Control)** — A further redesign on top of v2's codebase. Replaces the free-form pane grid with a project-group dashboard. Adds multi-agent orchestration (4 management roles), inter-agent messaging (btmsg), task boards (bttask), session anchors, health monitoring, FTS5 search, plugin system, Landlock sandboxing, secrets management, and 704 automated tests.
> **Important:** The `docs/` directory is the single source of truth for this project. Before making changes, consult the docs. After making changes, update the docs.
---
| Audience | Start Here |
|----------|-----------|
| New users | [Getting Started](getting-started/quickstart.md) |
| Contributors | [Dual-Repo Workflow](contributing/dual-repo-workflow.md), [Testing](contributing/testing.md) |
| Pro customers | [Pro Edition](pro/README.md), [Marketplace](pro/marketplace/README.md) |
| Plugin developers | [Plugin Development Guide](plugins/guide-developing.md) |
## Documentation Map
### Architecture & Design
### Getting Started
| Document | What It Covers |
|----------|---------------|
| [architecture.md](architecture.md) | End-to-end system architecture: Rust backend, Svelte frontend, sidecar layer, data model, layout system, data flow, IPC patterns |
| [decisions.md](decisions.md) | Architecture decisions log: rationale and dates for all major design choices |
| [multi-machine.md](multi-machine.md) | Multi-machine relay architecture: agor-core extraction, agor-relay binary, RemoteManager, WebSocket protocol, reconnection |
- [Quickstart](getting-started/quickstart.md) — install, build, first agent session
### Subsystem Guides
### Architecture
| Document | What It Covers |
|----------|---------------|
| [sidecar.md](sidecar.md) | Sidecar process lifecycle, multi-provider runners (Claude/Codex/Ollama), env var stripping, CLI detection, NDJSON protocol |
| [orchestration.md](orchestration.md) | Multi-agent orchestration: btmsg messaging, bttask kanban, Tier 1/2 agent roles, wake scheduler, system prompts |
| [production.md](production.md) | Production hardening: sidecar supervisor, Landlock sandbox, FTS5 search, plugin system, secrets management, notifications, health monitoring, audit logging |
| [provider-adapter/](provider-adapter/) | Multi-provider adapter pattern: architecture decisions, coupling analysis, implementation progress |
- [System Overview](architecture/overview.md) — components, data flow, IPC patterns
- [Data Model](architecture/data-model.md) — SQLite schemas, layout, keyboard shortcuts
- [Decisions](architecture/decisions.md) — architecture decision log with rationale
- [Phases](architecture/phases.md) — v2 implementation phases (P1-7 + multi-machine A-D)
- [Research Findings](architecture/findings.md) — SDK, performance, coupling analysis
### Implementation & Progress
### Agents & Orchestration
| Document | What It Covers |
|----------|---------------|
| [phases.md](phases.md) | v2 implementation phases (1-7 + multi-machine A-D + profiles/skills) with checklists |
| [progress/v3.md](progress/v3.md) | v3 session-by-session progress log (Phases 1-10 + production hardening) |
| [progress/v2.md](progress/v2.md) | v2 session-by-session progress log (recent sessions) |
| [progress/v2-archive.md](progress/v2-archive.md) | Archived v2 progress (2026-03-05 to 2026-03-06 early) |
- [Orchestration](agents/orchestration.md) — btmsg, bttask, 4 management roles, wake scheduler, session anchors
- [btmsg Reference](agents/ref-btmsg.md) — inter-agent messaging CLI and database schema
- [bttask Reference](agents/ref-bttask.md) — kanban task board CLI and operations
### Research & Analysis
### Providers
| Document | What It Covers |
|----------|---------------|
| [findings.md](findings.md) | All research: Claude Agent SDK, Tauri+xterm.js, terminal performance, adversarial review, provider coupling, codebase reuse, session anchors, multi-agent design, theme evolution, performance measurements |
- [Provider Reference](providers/ref-providers.md) — Claude, Codex, Ollama, Aider: models, capabilities, routing
### Release & Testing
### Sidecar
| Document | What It Covers |
|----------|---------------|
| [release-notes.md](release-notes.md) | v3.0 release notes: feature summary, breaking changes, test coverage, known limitations |
| [e2e-testing.md](e2e-testing.md) | E2E testing facility: WebDriverIO fixtures, test mode, LLM judge, CI integration, troubleshooting |
- [Sidecar Architecture](sidecar/architecture.md) — runners, NDJSON protocol, crash recovery, env stripping
---
### Multi-Machine
## Quick Orientation
- [Relay Architecture](multi-machine/relay.md) — WebSocket server, TLS, SPKI pinning, reconnection
If you are new to this codebase, read the documents in this order:
### Production Hardening
1. **[architecture.md](architecture.md)** — Understand how the pieces fit together
2. **[decisions.md](decisions.md)** — Understand why things are built the way they are
3. **[sidecar.md](sidecar.md)** — Understand how agent sessions actually run
4. **[orchestration.md](orchestration.md)** — Understand multi-agent coordination
5. **[e2e-testing.md](e2e-testing.md)** — Understand how to test changes
- [Hardening](production/hardening.md) — sidecar supervisor, Landlock sandbox, WAL checkpoint, TLS relay
- [Features](production/features.md) — FTS5 search, plugin sandbox, secrets, notifications, audit, error classification
For research context, read [findings.md](findings.md). For implementation history, see [phases.md](phases.md) and [progress/](progress/).
### Configuration
- [Settings Reference](config/ref-settings.md) — env vars, config files, databases, themes, per-project settings
### Plugins
- [Plugin Development Guide](plugins/guide-developing.md) — Web Worker sandbox API, manifest, publishing, examples
### Contributing
- [Dual-Repo Workflow](contributing/dual-repo-workflow.md) — community vs commercial repos, sync, leak prevention
- [Testing](contributing/testing.md) — E2E fixtures, test mode, LLM judge, CI integration
### Pro Edition (Commercial)
- [Pro Overview](pro/README.md) — feature list, plugin architecture, IPC pattern
- [Analytics Dashboard](pro/features/analytics.md) — cost/token/model tracking over time
- [Cost Intelligence](pro/features/cost-intelligence.md) — budget governor, smart model router
- [Knowledge Base](pro/features/knowledge-base.md) — persistent memory, codebase symbol graph
- [Git Integration](pro/features/git-integration.md) — context injection, branch policy
- [Marketplace](pro/marketplace/README.md) — 13 plugins (8 free + 5 paid), catalog, install/update
### Release History
- [Release Notes](release-notes.md) — v3.0 features, breaking changes, requirements
### Progress Logs
- [v3 Progress](progress/v3.md) — session-by-session development log
- [v2 Progress](progress/v2.md)
- [v2 Archive](progress/v2-archive.md)
---
@ -82,10 +90,23 @@ For research context, read [findings.md](findings.md). For implementation histor
| Path | Purpose |
|------|---------|
| `src-tauri/src/` | Rust backend: commands, SQLite, btmsg, bttask, search, secrets, plugins |
| `agor-core/` | Shared Rust crate: PtyManager, SidecarManager, EventSink trait, Landlock sandbox |
| `agor-core/` | Shared Rust crate: PtyManager, SidecarManager, EventSink, Landlock sandbox |
| `agor-relay/` | Standalone relay binary for remote machine support |
| `agor-pro/` | Commercial plugin crate (Pro edition features) |
| `src/lib/` | Svelte 5 frontend: components, stores, adapters, utils, providers |
| `sidecar/` | Agent sidecar runners (Claude, Codex, Ollama) — compiled to ESM bundles |
| `src/lib/commercial/` | Pro edition Svelte components and IPC bridge |
| `sidecar/` | Agent sidecar runners (Claude, Codex, Ollama, Aider) — ESM bundles |
| `tests/e2e/` | WebDriverIO E2E tests, fixtures, LLM judge |
| `ctx/` | Context manager CLI tool (SQLite-based, standalone) |
| `consult/` | Multi-model tribunal CLI (OpenRouter, standalone Python) |
| `tests/commercial/` | Pro edition tests (excluded from community builds) |
| `scripts/` | Build scripts, plugin scaffolding, test runner |
| `.githooks/` | Pre-push leak prevention hook |
## Reading Order for New Contributors
1. [Getting Started](getting-started/quickstart.md) — build and run
2. [System Overview](architecture/overview.md) — how the pieces fit
3. [Decisions](architecture/decisions.md) — why things are built this way
4. [Sidecar Architecture](sidecar/architecture.md) — how agent sessions run
5. [Orchestration](agents/orchestration.md) — multi-agent coordination
6. [Testing](contributing/testing.md) — how to test changes
7. [Dual-Repo Workflow](contributing/dual-repo-workflow.md) — how to contribute

View file

@ -0,0 +1,246 @@
# System Architecture — Overview
This document describes the end-to-end architecture of Agent Orchestrator (agor) — how the Rust backend, Svelte 5 frontend, and Node.js/Deno sidecar processes work together to provide a multi-project AI agent orchestration dashboard.
---
## High-Level Overview
Agent Orchestrator is a Tauri 2.x desktop application. Tauri provides a Rust backend process and a WebKit2GTK-based webview for the frontend. The application manages AI agent sessions by spawning sidecar child processes that communicate with AI provider APIs (Claude, Codex, Ollama).
```
+----------------------------------------------------------------+
| Agent Orchestrator (Tauri 2.x) |
| |
| +------------------+ Tauri IPC +--------------------+ |
| | WebView | <-------------> | Rust Backend | |
| | (Svelte 5) | invoke/listen | | |
| | | | +-- PtyManager | |
| | +-- ProjectGrid | | +-- SidecarManager | |
| | +-- AgentPane | | +-- SessionDb | |
| | +-- TerminalPane | | +-- BtmsgDb | |
| | +-- StatusBar | | +-- SearchDb | |
| | +-- Stores | | +-- SecretsManager | |
| +------------------+ | +-- RemoteManager | |
| | +-- FileWatchers | |
| +--------------------+ |
| | |
+-------------------------------------------+--------------------+
| stdio NDJSON
v
+-------------------+
| Sidecar Processes |
| (Deno or Node.js) |
| |
| claude-runner.mjs |
| codex-runner.mjs |
| ollama-runner.mjs |
+-------------------+
```
### Why Three Layers?
1. **Rust backend** — Manages OS-level resources (PTY processes, file watchers, SQLite databases) with memory safety and low overhead. Exposes everything to the frontend via Tauri IPC commands and events.
2. **Svelte 5 frontend** — Renders the UI with fine-grained reactivity (no VDOM). Svelte 5 runes (`$state`, `$derived`, `$effect`) provide signal-based reactivity comparable to Solid.js but with a larger ecosystem.
3. **Sidecar processes** — The Claude Agent SDK, OpenAI Codex SDK, and Ollama API are all JavaScript/TypeScript libraries. They cannot run in Rust or in the WebKit2GTK webview (no Node.js APIs). The sidecar layer bridges this gap: Rust spawns a JS process, communicates via stdio NDJSON, and forwards structured messages to the frontend.
---
## Rust Backend (`src-tauri/`)
The Rust backend is the central coordinator. It owns all OS resources and database connections.
### Cargo Workspace
```
agor/
+-- Cargo.toml # Workspace root
+-- agor-core/ # Shared crate
| +-- src/
| +-- lib.rs
| +-- pty.rs # PtyManager (portable-pty)
| +-- sidecar.rs # SidecarManager (multi-provider)
| +-- supervisor.rs # SidecarSupervisor (crash recovery)
| +-- sandbox.rs # Landlock sandbox
| +-- event.rs # EventSink trait
+-- agor-relay/ # Remote machine relay
| +-- src/main.rs # WebSocket server + token auth
+-- src-tauri/ # Tauri application
+-- src/
+-- lib.rs # AppState + setup + handler registration
+-- commands/ # 16 domain command modules
+-- btmsg.rs # Inter-agent messaging (SQLite)
+-- bttask.rs # Task board (SQLite, shared btmsg.db)
+-- search.rs # FTS5 full-text search
+-- secrets.rs # System keyring (libsecret)
+-- plugins.rs # Plugin discovery
+-- notifications.rs # Desktop notifications
+-- session/ # SessionDb (sessions, layout, settings, agents, metrics, anchors)
+-- remote.rs # RemoteManager (WebSocket client)
+-- ctx.rs # Read-only ctx database access
+-- memora.rs # Read-only Memora database access
+-- telemetry.rs # OpenTelemetry tracing
+-- groups.rs # Project groups config
+-- watcher.rs # File watcher (notify crate)
+-- fs_watcher.rs # Per-project filesystem watcher (inotify)
+-- event_sink.rs # TauriEventSink implementation
+-- pty.rs # Thin re-export from agor-core
+-- sidecar.rs # Thin re-export from agor-core
```
The `agor-core` crate exists so that both the Tauri application and the standalone `agor-relay` binary can share PtyManager and SidecarManager code. The `EventSink` trait abstracts event emission — TauriEventSink wraps Tauri's AppHandle, while the relay uses a WebSocket-based EventSink.
### AppState
All backend state lives in `AppState`, initialized during Tauri setup:
```rust
pub struct AppState {
pub pty_manager: Mutex<PtyManager>,
pub sidecar_manager: Mutex<SidecarManager>,
pub session_db: Mutex<SessionDb>,
pub remote_manager: Mutex<RemoteManager>,
pub telemetry: Option<TelemetryGuard>,
}
```
### Command Modules
Tauri commands are organized into 16 domain modules under `commands/`:
| Module | Commands | Purpose |
|--------|----------|---------|
| `pty` | spawn, write, resize, kill | Terminal management |
| `agent` | query, stop, ready, restart | Agent session lifecycle |
| `session` | session CRUD, layout, settings | Session persistence |
| `persistence` | agent state, messages | Agent session continuity |
| `knowledge` | ctx, memora queries | External knowledge bases |
| `claude` | profiles, skills | Claude-specific features |
| `groups` | load, save | Project group config |
| `files` | list_directory, read/write file | File browser |
| `watcher` | start, stop | File change monitoring |
| `remote` | 12 commands | Remote machine management |
| `bttask` | list, create, update, delete, comments | Task board |
| `search` | init, search, rebuild, index | FTS5 search |
| `secrets` | store, get, delete, list, has_keyring | Secrets management |
| `plugins` | discover, read_file | Plugin discovery |
| `notifications` | send_desktop | OS notifications |
| `misc` | test_mode, frontend_log | Utilities |
---
## Svelte 5 Frontend (`src/`)
The frontend uses Svelte 5 with runes for reactive state management. The UI follows a VSCode-inspired layout with a left icon rail, expandable drawer, project grid, and status bar.
### Component Hierarchy
```
App.svelte [Root -- VSCode-style layout]
+-- CommandPalette.svelte [Ctrl+K overlay, 18+ commands]
+-- SearchOverlay.svelte [Ctrl+Shift+F, FTS5 Spotlight-style]
+-- NotificationCenter.svelte [Bell icon + dropdown]
+-- GlobalTabBar.svelte [Left icon rail, 2.75rem wide]
+-- [Sidebar Panel] [Expandable drawer, max 50%]
| +-- SettingsTab.svelte [Global settings + group/project CRUD]
+-- ProjectGrid.svelte [Flex + scroll-snap, adaptive count]
| +-- ProjectBox.svelte [Per-project container, 11 tab types]
| +-- ProjectHeader.svelte [Icon + name + status + badges]
| +-- AgentSession.svelte [Main Claude session wrapper]
| | +-- AgentPane.svelte [Structured message rendering]
| | +-- TeamAgentsPanel.svelte [Tier 1 subagent cards]
| +-- TerminalTabs.svelte [Shell/SSH/agent-preview tabs]
| | +-- TerminalPane.svelte [xterm.js + Canvas addon]
| | +-- AgentPreviewPane.svelte [Read-only agent activity]
| +-- DocsTab / ContextTab / FilesTab / SshTab / MemoriesTab
| +-- MetricsPanel / TaskBoardTab / ArchitectureTab / TestingTab
+-- StatusBar.svelte [Agent counts, burn rate, attention queue]
```
### Stores (Svelte 5 Runes)
All store files use the `.svelte.ts` extension — required for Svelte 5 runes (`$state`, `$derived`, `$effect`). Files with plain `.ts` extension compile but fail at runtime with "rune_outside_svelte".
| Store | Purpose |
|-------|---------|
| `workspace.svelte.ts` | Project groups, active group, tabs, focus |
| `agents.svelte.ts` | Agent sessions, messages, cost, parent/child hierarchy |
| `health.svelte.ts` | Per-project health tracking, attention scoring, burn rate |
| `conflicts.svelte.ts` | File overlap + external write detection |
| `anchors.svelte.ts` | Session anchor management (auto/pinned/promoted) |
| `notifications.svelte.ts` | Toast + history (6 types, unread badge) |
| `plugins.svelte.ts` | Plugin command registry, event bus |
| `theme.svelte.ts` | 17 themes, font restoration |
| `machines.svelte.ts` | Remote machine state |
| `wake-scheduler.svelte.ts` | Manager auto-wake (3 strategies, per-manager timers) |
### Agent Dispatcher
The agent dispatcher (`agent-dispatcher.ts`, ~260 lines) is the central router between sidecar events and the agent store. When the Rust backend emits a `sidecar-message` Tauri event, the dispatcher:
1. Looks up the provider for the session (via `sessionProviderMap`)
2. Routes the raw message through the appropriate adapter (claude-messages.ts, codex-messages.ts, or ollama-messages.ts) via `message-adapters.ts`
3. Feeds the resulting `AgentMessage[]` into the agent store
4. Handles side effects: subagent pane spawning, session persistence, auto-anchoring, worktree detection, health tracking, conflict recording
The dispatcher delegates to four extracted utility modules:
- `utils/session-persistence.ts` — session-project maps, persistSessionForProject
- `utils/subagent-router.ts` — spawn + route subagent panes
- `utils/auto-anchoring.ts` — triggerAutoAnchor on first compaction event
- `utils/worktree-detection.ts` — detectWorktreeFromCwd pure function
---
## Data Flow: Agent Query Lifecycle
```
1. User types prompt in AgentPane
2. AgentPane calls agentBridge.queryAgent(options)
3. agent-bridge.ts invokes Tauri command 'agent_query'
4. Rust agent_query handler calls SidecarManager.query()
5. SidecarManager resolves provider runner (e.g., claude-runner.mjs)
6. SidecarManager writes QueryMessage as NDJSON to sidecar stdin
7. Sidecar runner calls provider SDK (e.g., Claude Agent SDK query())
8. Provider SDK streams responses
9. Runner forwards each response as NDJSON to stdout
10. SidecarManager reads stdout line-by-line
11. SidecarManager emits Tauri event 'sidecar-message' with sessionId + data
12. Frontend agent-dispatcher.ts receives event
13. Dispatcher routes through message-adapters.ts -> provider-specific parser
14. Parser converts to AgentMessage[]
15. Dispatcher feeds messages into agents.svelte.ts store
16. AgentPane reactively re-renders via $derived bindings
```
---
## Configuration
### Project Groups (`~/.config/agor/groups.json`)
Human-editable JSON file defining project groups and their projects. Loaded at startup by `groups.rs`. Not hot-reloaded — changes require app restart or group switch.
### SQLite Settings (`sessions.db` -> `settings` table)
Key-value store for user preferences: theme, fonts, shell, CWD, provider settings. Accessed via `settings-bridge.ts` -> `settings_get`/`settings_set` Tauri commands.
### Environment Variables
| Variable | Purpose |
|----------|---------|
| `AGOR_TEST` | Enables test mode (disables watchers, wake scheduler) |
| `AGOR_TEST_DATA_DIR` | Redirects SQLite database storage |
| `AGOR_TEST_CONFIG_DIR` | Redirects groups.json config |
| `AGOR_OTLP_ENDPOINT` | Enables OpenTelemetry OTLP export |
---
## Key Constraints
1. **WebKit2GTK has no WebGL** — xterm.js must use the Canvas addon explicitly. Maximum 4 active xterm.js instances to avoid OOM.
2. **Svelte 5 runes require `.svelte.ts`** — Store files using `$state`/`$derived` must have the `.svelte.ts` extension. The compiler silently accepts `.ts` but runes fail at runtime.
3. **Single shared sidecar** — All agent sessions share one SidecarManager. Per-project isolation is via `cwd`, `claude_config_dir`, and `session_id` routing. Per-project sidecar pools deferred to v3.1.
4. **SQLite WAL mode** — Both databases use WAL with 5s busy_timeout for concurrent access from Rust backend + Python CLIs (btmsg/bttask).
5. **camelCase wire format** — Rust uses `#[serde(rename_all = "camelCase")]`. TypeScript interfaces must match. This was a source of bugs during development (see [findings.md](findings.md) for context).

229
docs/config/ref-settings.md Normal file
View file

@ -0,0 +1,229 @@
# Configuration Reference
All configuration paths, environment variables, database files, and per-project
settings for Agents Orchestrator.
## Environment variables
### Core
| Variable | Default | Description |
|----------|---------|-------------|
| `AGOR_TEST` | unset | Set to `1` to enable test mode. Disables file watchers, wake scheduler, and telemetry. |
| `AGOR_OTLP_ENDPOINT` | unset | OpenTelemetry OTLP/HTTP endpoint (e.g. `http://localhost:4318`). When unset, telemetry is console-only. |
| `AGOR_TEST_DATA_DIR` | unset | Override data directory in test mode. Isolates SQLite databases. |
| `AGOR_TEST_CONFIG_DIR` | unset | Override config directory in test mode. Isolates groups.json and plugins. |
| `AGOR_TEST_CTX_DIR` | unset | Override ctx database directory in test mode. |
| `AGOR_EDITION` | `community` | Set to `pro` to enable commercial features (used by vitest and CI). |
### Provider-specific
Provider environment variables (`CLAUDE_*`, `CODEX_*`, `OLLAMA_*`) are stripped
from the sidecar process environment to prevent cross-contamination. The
whitelist `CLAUDE_CODE_EXPERIMENTAL_*` is preserved.
Variables the sidecar runner may read:
| Variable | Provider | Description |
|----------|----------|-------------|
| `ANTHROPIC_API_KEY` | Claude | API key (used by Claude CLI internally) |
| `OPENAI_API_KEY` | Codex | API key for Codex SDK |
| `OPENROUTER_API_KEY` | Aider | API key for OpenRouter-routed models |
| `CLAUDE_CONFIG_DIR` | Claude | Override Claude config directory (multi-account) |
| `BTMSG_AGENT_ID` | All (Tier 1) | Injected for management agents to enable btmsg/bttask CLI |
## Config files
Base directory: `~/.config/agor/`
### groups.json
Primary configuration file. Defines project groups, projects, and management
agents.
```
~/.config/agor/groups.json
```
Schema: `GroupsFile` (see `src/lib/types/groups.ts`).
Structure:
```json
{
"version": 1,
"groups": [
{
"id": "group-id",
"name": "Group Name",
"projects": [ ... ],
"agents": [ ... ]
}
],
"activeGroupId": "group-id"
}
```
Managed via the Settings tab in the UI or by editing the file directly. Changes
are picked up on next group load.
### accounts.json (Pro edition)
Commercial multi-account configuration.
```
~/.config/agor/accounts.json
```
Only present when `AGOR_EDITION=pro`. Not included in the community build.
### plugins/
Plugin discovery directory. Each plugin is a subdirectory containing a
`plugin.json` manifest.
```
~/.config/agor/plugins/
my-plugin/
plugin.json
index.js
```
Plugins run in Web Worker sandboxes with permission-gated APIs. See
`src/lib/plugins/plugin-host.ts`.
## Database files
Base directory: `~/.local/share/agor/`
All databases use SQLite WAL mode with 5-second busy timeout for concurrent
access.
### sessions.db
Session persistence, layout state, settings, session metrics, and anchors.
```
~/.local/share/agor/sessions.db
```
Tables:
| Table | Description |
|-------|-------------|
| `sessions` | Session state (project_id, group_name, layout data) |
| `agent_messages` | Per-project message persistence |
| `project_agent_state` | SDK session ID, cost, status per project |
| `session_metrics` | Historical session data (tokens, turns, cost, model) |
| `session_anchors` | Preserved turns through compaction chains |
| `settings` | Key-value application settings |
### btmsg.db
Shared database for inter-agent messaging (btmsg) and task board (bttask).
```
~/.local/share/agor/btmsg.db
```
Created by the `btmsg` CLI on first `btmsg register`. Used concurrently by
Python CLIs and the Rust backend.
Tables:
| Table | Description |
|-------|-------------|
| `agents` | Registered agents (id, name, role, group_id, tier, model, status) |
| `messages` | Direct messages between agents |
| `channels` | Named broadcast channels |
| `channel_messages` | Messages posted to channels |
| `contacts` | ACL for agent-to-agent visibility |
| `heartbeats` | Agent liveness tracking |
| `dead_letter_queue` | Undeliverable messages |
| `audit_log` | Agent action audit trail |
| `seen_messages` | Per-message read tracking (session_id, message_id) |
| `tasks` | Kanban task board entries |
| `task_comments` | Comments on tasks |
### search.db
FTS5 full-text search index.
```
~/.local/share/agor/search.db
```
Virtual tables:
| Table | Description |
|-------|-------------|
| `search_messages` | Indexed agent messages |
| `search_tasks` | Indexed task board entries |
| `search_btmsg` | Indexed btmsg messages |
Rebuilt on demand via the search overlay (`Ctrl+Shift+F`).
## Tauri configuration
### src-tauri/tauri.conf.json
Community edition Tauri config. Defines window properties, permissions, updater
endpoint, and bundle metadata.
### src-tauri/tauri.conf.commercial.json
Commercial edition overlay. Merged with the base config when building with
`--config src-tauri/tauri.conf.commercial.json`. Changes bundle identifier,
product name, and updater URL.
## Theme settings
17 themes in 3 groups, all mapping to the same 26 `--ctp-*` CSS custom
properties.
| Group | Themes |
|-------|--------|
| Catppuccin | Mocha (default), Macchiato, Frappe, Latte |
| Editor | VSCode Dark+, Atom One Dark, Monokai, Dracula, Nord, Solarized Dark, GitHub Dark |
| Deep Dark | Tokyo Night, Gruvbox Dark, Ayu Dark, Poimandres, Vesper, Midnight |
Settings keys (persisted in `sessions.db` settings table):
| Key | Default | Description |
|-----|---------|-------------|
| `theme` | `mocha` | Active theme ID |
| `ui_font_family` | system sans-serif | UI element font |
| `ui_font_size` | `14` (px) | UI font size (feeds CSS `--ui-font-size`) |
| `term_font_family` | system monospace | Terminal font |
| `term_font_size` | `14` (px) | Terminal font size (feeds CSS `--term-font-size`) |
| `default_shell` | system default | Default shell for terminal panes |
| `default_cwd` | `~` | Default working directory |
All font settings are restored from SQLite on startup via `initTheme()`.
## Per-project settings
These fields are set in `groups.json` per project entry (`ProjectConfig`):
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `provider` | `ProviderId` | `claude` | Agent provider |
| `model` | string | provider default | Model identifier override |
| `profile` | string | `default` | Claude profile name |
| `useWorktrees` | boolean | `false` | Git worktree isolation per session |
| `sandboxEnabled` | boolean | `false` | Landlock filesystem sandbox |
| `autonomousMode` | string | `restricted` | `restricted` or `autonomous` |
| `anchorBudgetScale` | string | `medium` | Anchor budget: `small` (2K), `medium` (6K), `large` (12K), `full` (20K) |
| `stallThresholdMin` | number | `15` | Minutes before idle agent is marked stalled (range 5--60) |
### Agent-specific fields
Set on `GroupAgentConfig` entries in the `agents` array:
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `role` | string | required | `manager`, `architect`, `tester`, or `reviewer` |
| `wakeIntervalMin` | number | `3` | Auto-wake check interval (Manager only) |
| `wakeStrategy` | string | `smart` | `persistent`, `on-demand`, or `smart` |
| `wakeThreshold` | number | `0.5` | Threshold for smart wake strategy (0.0--1.0) |
| `systemPrompt` | string | none | Custom system prompt appended to generated prompt |

View file

@ -0,0 +1,188 @@
# Quickstart
Get Agents Orchestrator (agor) running locally in under 10 minutes.
## Prerequisites
| Dependency | Version | Notes |
|------------|---------|-------|
| Node.js | 20+ | npm included |
| Rust | 1.77+ | Install via [rustup](https://rustup.rs/) |
| WebKit2GTK | 4.1 | Tauri 2.x rendering engine |
| System libs | -- | See below |
### System libraries (Debian/Ubuntu)
```bash
sudo apt install \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libappindicator3-dev \
librsvg2-dev \
libssl-dev \
libsoup-3.0-dev \
javascriptcoregtk-4.1 \
patchelf
```
### Optional dependencies
- **Claude Code CLI** -- Required for the Claude provider. Auto-detected at
`~/.local/bin/claude`, `~/.claude/local/claude`, `/usr/local/bin/claude`, or
`/usr/bin/claude`.
- **Deno** -- Preferred sidecar runtime (faster startup). Falls back to Node.js.
- **Ollama** -- Required for the Ollama provider. Must be running on
`localhost:11434`.
## Clone and build
```bash
git clone git@github.com:DexterFromLab/agent-orchestrator.git
cd agent-orchestrator
npm install
npm run tauri dev
```
The dev server runs on port **9700**. Tauri opens a native window automatically.
### Production build
```bash
npm run tauri build
```
Output: `.deb` and AppImage in `src-tauri/target/release/bundle/`.
## Project configuration
Agor organizes work into **groups**, each containing one or more **projects**
(codebases) and optional **agents** (Tier 1 management roles).
Configuration lives in `~/.config/agor/groups.json`. On first launch, agor
creates a default file. You can also create it manually:
```json
{
"version": 1,
"groups": [
{
"id": "my-team",
"name": "My Team",
"projects": [
{
"id": "backend",
"name": "Backend API",
"identifier": "backend-api",
"description": "REST API service",
"icon": "B",
"cwd": "/home/user/code/backend",
"profile": "default",
"enabled": true,
"provider": "claude"
},
{
"id": "frontend",
"name": "Frontend App",
"identifier": "frontend-app",
"description": "Svelte web client",
"icon": "F",
"cwd": "/home/user/code/frontend",
"profile": "default",
"enabled": true,
"provider": "claude",
"model": "claude-sonnet-4-6"
}
],
"agents": [
{
"id": "mgr-1",
"name": "Manager",
"role": "manager",
"enabled": true,
"wakeIntervalMin": 3,
"wakeStrategy": "smart",
"wakeThreshold": 0.5
}
]
}
],
"activeGroupId": "my-team"
}
```
### Key fields
| Field | Required | Description |
|-------|----------|-------------|
| `id` | Yes | Unique identifier within the group |
| `cwd` | Yes | Absolute path to the project directory |
| `provider` | No | `claude` (default), `codex`, `ollama`, or `aider` |
| `model` | No | Model override; falls back to provider default |
| `profile` | No | Claude profile name from `~/.config/switcher/profiles/` |
| `useWorktrees` | No | Enable git worktree isolation per session |
| `sandboxEnabled` | No | Enable Landlock filesystem sandbox (Linux 5.13+) |
| `autonomousMode` | No | `restricted` (default) or `autonomous` |
| `anchorBudgetScale` | No | Anchor token budget: `small`, `medium`, `large`, `full` |
| `stallThresholdMin` | No | Minutes before idle agent is marked stalled (default 15) |
## Creating your first agent session
1. Launch agor (`npm run tauri dev` or the built binary).
2. The workspace shows your configured projects as cards in a grid.
3. Click a project card to focus it. The **Model** tab opens by default.
4. Type a prompt in the input area at the bottom and press Enter.
5. Agor spawns a sidecar process, connects to the provider, and streams
responses in real time.
The agent session persists across tab switches. Closing the project card stops
the agent.
## Keyboard shortcuts
| Shortcut | Action |
|----------|--------|
| `Ctrl+B` | Toggle sidebar |
| `Ctrl+,` | Open settings |
| `Ctrl+Shift+F` | Full-text search overlay |
| `Ctrl+K` | Command palette |
| `Alt+1` -- `Alt+5` | Focus project 1--5 |
| `Escape` | Close sidebar / overlay / palette |
## Running tests
```bash
# All tests (vitest frontend + cargo backend)
npm run test:all
# Frontend only
npm run test
# Backend only
npm run test:cargo
# E2E tests (requires built binary)
npm run test:all:e2e
```
## Directory layout
```
agent-orchestrator/
agor-core/ # Shared Rust crate (PTY, sidecar, supervisor, sandbox)
agor-relay/ # Standalone relay binary (WebSocket server)
src-tauri/ # Tauri app (Rust backend)
src/ # Svelte 5 frontend
sidecar/ # Provider runner scripts (compiled to .mjs)
docs/ # Project documentation
tests/e2e/ # WebDriverIO E2E tests
```
## Next steps
- [Configuration reference](../config/ref-settings.md) -- all env vars, config
files, and per-project settings.
- [Provider reference](../providers/ref-providers.md) -- Claude, Codex, Ollama,
Aider setup.
- [btmsg reference](../agents/ref-btmsg.md) -- inter-agent messaging.
- [bttask reference](../agents/ref-bttask.md) -- kanban task board.

110
docs/pro/README.md Normal file
View file

@ -0,0 +1,110 @@
# Agents Orchestrator Pro Edition
> This documentation covers Pro edition features available in the agents-orchestrator/agents-orchestrator private repository.
## Overview
Agents Orchestrator Pro extends the open-source community edition with commercial features for teams and organizations that need deeper analytics, cost controls, persistent agent knowledge, and a plugin marketplace. Pro features are architecturally isolated from the community codebase, implemented as a Tauri plugin crate and a separate Svelte module tree.
## Feature Summary
| Feature | Description | Documentation |
|---------|-------------|---------------|
| Analytics Dashboard | Session cost trends, model usage breakdown, daily statistics | [analytics.md](features/analytics.md) |
| Budget Governor | Per-project monthly token budgets with soft/hard limits | [cost-intelligence.md](features/cost-intelligence.md) |
| Smart Model Router | Cost-aware model selection with routing profiles | [cost-intelligence.md](features/cost-intelligence.md) |
| Persistent Agent Memory | Per-project knowledge fragments with FTS5 search and TTL | [knowledge-base.md](features/knowledge-base.md) |
| Codebase Symbol Graph | Regex-based symbol extraction and caller lookup | [knowledge-base.md](features/knowledge-base.md) |
| Git Context Injection | Branch, commit, and diff context for agent prompts | [git-integration.md](features/git-integration.md) |
| Branch Policy | Session-level protection for sensitive branches | [git-integration.md](features/git-integration.md) |
| Plugin Marketplace | Curated plugin catalog with install/update lifecycle | [marketplace/README.md](marketplace/README.md) |
## Architecture
Pro features are separated from the community codebase at two layers:
### Rust Backend: `agor-pro` Tauri Plugin Crate
The `agor-pro` crate is a standalone Tauri plugin located at `crates/agor-pro/` in the private repository. It contains all Pro-specific Rust logic: SQLite tables, commands, and business rules.
The crate exposes a single entry point:
```rust
pub fn init() -> TauriPlugin<tauri::Wry> { ... }
```
### Svelte Frontend: `src/lib/commercial/`
Pro UI components live under `src/lib/commercial/` with their own adapters and stores. Community components never import from this path. The commercial module tree mirrors the community structure:
```
src/lib/commercial/
adapters/ -- IPC bridges for pro commands
components/ -- Pro-specific UI (analytics, budgets, marketplace)
stores/ -- Pro-specific state
```
## Feature Flag
Pro features are gated at both compile time and runtime.
### Cargo Feature Flag
The `pro` feature flag controls Rust compilation:
```bash
# Community build (default)
cargo build -p bterminal
# Pro build
cargo build -p bterminal --features pro
```
When `--features pro` is active, `lib.rs` registers the plugin:
```rust
#[cfg(feature = "pro")]
app.handle().plugin(agor_pro::init());
```
### Frontend Edition Flag
The `AGOR_EDITION` environment variable controls frontend feature visibility:
```bash
# Community build (default)
AGOR_EDITION=community npm run tauri build
# Pro build
AGOR_EDITION=pro npm run tauri build
```
Svelte components check this at module level:
```typescript
const isPro = import.meta.env.VITE_AGOR_EDITION === 'pro';
```
## IPC Pattern
All Pro commands follow the Tauri plugin IPC convention. Commands are namespaced under `plugin:agor-pro`:
```typescript
import { invoke } from '@tauri-apps/api/core';
const summary = await invoke('plugin:agor-pro|pro_analytics_summary', {
period: 30,
});
```
Command names use the `pro_` prefix consistently. Arguments are passed as a single object. Return types are JSON-serialized Rust structs with `#[serde(rename_all = "camelCase")]`.
## Error Handling
Pro commands return `Result<T, String>` on the Rust side. The frontend adapters in `src/lib/commercial/adapters/` wrap `invoke()` calls and surface errors through the standard notification system. When the Pro plugin is not loaded (community build), invoke calls fail with a predictable `plugin not found` error that the adapters catch and handle silently.
## Database
Pro features use a dedicated SQLite database at `~/.local/share/bterminal/agor_pro.db` (WAL mode, 5s busy timeout). This keeps Pro data isolated from community tables. The `pro_budgets` and `pro_budget_log` tables are created on plugin init via migrations.
Read-only access to community tables (e.g., `session_metrics` in `sessions.db`) is done through a separate read-only connection.

View file

@ -0,0 +1,177 @@
# Analytics Dashboard
> This documentation covers Pro edition features available in the agents-orchestrator/agents-orchestrator private repository.
## Overview
The Analytics Dashboard provides historical cost and usage visibility across all projects. It reads from the community `session_metrics` table (no additional data collection required) and presents aggregated views through three commands and corresponding UI components.
## Data Source
All analytics are derived from the existing `session_metrics` table in `sessions.db`:
```sql
-- Community table (read-only access from Pro plugin)
CREATE TABLE session_metrics (
id INTEGER PRIMARY KEY,
project_id TEXT NOT NULL,
session_id TEXT NOT NULL,
started_at TEXT,
ended_at TEXT,
peak_tokens INTEGER,
turn_count INTEGER,
tool_call_count INTEGER,
cost_usd REAL,
model TEXT,
status TEXT,
error_message TEXT
);
```
The Pro plugin opens a read-only connection to `sessions.db` and queries this table. It never writes to community databases.
## Commands
### pro_analytics_summary
Returns an aggregated summary for the specified period.
**Arguments:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `period` | `u32` | Yes | Number of days to look back (7, 14, 30, or 90) |
| `projectId` | `String` | No | Filter to a single project. Omit for all projects. |
**Response: `AnalyticsSummary`**
```typescript
interface AnalyticsSummary {
totalCostUsd: number;
totalSessions: number;
totalTurns: number;
totalToolCalls: number;
avgCostPerSession: number;
avgTurnsPerSession: number;
peakTokensMax: number;
periodDays: number;
projectCount: number;
}
```
### pro_analytics_daily
Returns per-day statistics for charting.
**Arguments:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `period` | `u32` | Yes | Number of days (7, 14, 30, or 90) |
| `projectId` | `String` | No | Filter to a single project |
**Response: `Vec<DailyStats>`**
```typescript
interface DailyStats {
date: string; // ISO 8601 date (YYYY-MM-DD)
costUsd: number;
sessionCount: number;
turnCount: number;
toolCallCount: number;
}
```
Days with no sessions are included with zero values to ensure continuous chart data.
### pro_analytics_model_breakdown
Returns usage grouped by model.
**Arguments:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `period` | `u32` | Yes | Number of days (7, 14, 30, or 90) |
| `projectId` | `String` | No | Filter to a single project |
**Response: `Vec<ModelBreakdown>`**
```typescript
interface ModelBreakdown {
model: string;
sessionCount: number;
totalCostUsd: number;
avgCostPerSession: number;
totalTurns: number;
totalToolCalls: number;
pctOfTotalCost: number; // 0.0 to 100.0
}
```
Results are sorted by `totalCostUsd` descending.
## Period Selection
The UI presents four period options:
| Period | Label | Use Case |
|--------|-------|----------|
| 7 | Last 7 days | Recent activity check |
| 14 | Last 14 days | Sprint review |
| 30 | Last 30 days | Monthly cost review |
| 90 | Last 90 days | Quarterly trend analysis |
The selected period is stored in the component state and defaults to 30 days. Changing the period triggers a fresh query (no client-side caching).
## UI Components
### AnalyticsDashboard.svelte
Top-level Pro tab component. Contains:
1. **Period selector** -- segmented button group (7/14/30/90).
2. **Summary cards** -- four stat cards showing total cost, sessions, avg cost/session, peak tokens.
3. **Daily cost chart** -- SVG bar chart rendered from `DailyStats[]`.
4. **Model breakdown table** -- sortable table from `ModelBreakdown[]`.
### Daily Cost Chart
The chart is a pure SVG element (no charting library). Implementation details:
- Bars are sized relative to the maximum daily cost in the period.
- X-axis labels show abbreviated dates (e.g., "Mar 5").
- Y-axis shows cost in USD with appropriate precision ($0.01 for small values, $1.00 for large).
- Hover tooltip shows exact cost, session count, and turn count for the day.
- Colors use `var(--ctp-blue)` for bars, `var(--ctp-surface1)` for gridlines.
- Responsive: adapts bar width to container via `container-type: inline-size`.
### Model Breakdown Table
Standard sortable table with columns: Model, Sessions, Cost, Avg Cost, Turns, Tools, % of Total. Default sort by cost descending. The `% of Total` column includes a proportional bar using `var(--ctp-sapphire)`.
## IPC Examples
```typescript
// Get 30-day summary across all projects
const summary = await invoke('plugin:agor-pro|pro_analytics_summary', {
period: 30,
});
// Get daily stats for a specific project
const daily = await invoke('plugin:agor-pro|pro_analytics_daily', {
period: 14,
projectId: 'my-project',
});
// Get model breakdown
const models = await invoke('plugin:agor-pro|pro_analytics_model_breakdown', {
period: 90,
});
```
## Limitations
- Analytics are computed on-demand from raw session_metrics rows. For large datasets (10,000+ sessions), queries may take 100-200ms. No materialized views or pre-aggregation.
- Historical data depends on community session_metrics persistence. If sessions.db is deleted or migrated, analytics history resets.
- Cost values are only available for providers that report cost (Claude, Codex). Ollama sessions show $0.00.

View file

@ -0,0 +1,238 @@
# Cost Intelligence
> This documentation covers Pro edition features available in the agents-orchestrator/agents-orchestrator private repository.
Cost Intelligence comprises two systems: the Budget Governor (hard cost controls) and the Smart Model Router (cost-aware model selection). Both operate at the per-project level and integrate with the agent launch pipeline.
---
## Budget Governor
### Purpose
The Budget Governor enforces per-project monthly token budgets. It prevents runaway costs by warning at a soft limit and blocking agent launches at a hard limit.
### Budget Configuration
Each project can have a monthly budget with two thresholds:
| Threshold | Default | Behavior |
|-----------|---------|----------|
| Soft limit | 80% of budget | Emits a warning notification. Agent proceeds. |
| Hard limit | 100% of budget | Blocks agent launch. Returns error to UI. |
Budgets are denominated in USD. The governor tracks cumulative cost for the current calendar month by summing `cost_usd` from `session_metrics` and `pro_budget_log`.
### Emergency Override
When the hard limit is reached, the UI displays a confirmation dialog with the current spend and budget. The user can authorize an emergency override that allows the next session to proceed. Overrides are logged in `pro_budget_log` with `override = true`. Each override is single-use; subsequent launches require a new override.
### SQLite Tables
Both tables reside in `agor_pro.db`.
```sql
CREATE TABLE pro_budgets (
project_id TEXT PRIMARY KEY,
monthly_budget_usd REAL NOT NULL,
soft_limit_pct REAL NOT NULL DEFAULT 0.80,
hard_limit_pct REAL NOT NULL DEFAULT 1.00,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE pro_budget_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id TEXT NOT NULL,
session_id TEXT NOT NULL,
cost_usd REAL NOT NULL,
cumulative_usd REAL NOT NULL,
month TEXT NOT NULL, -- YYYY-MM format
override INTEGER NOT NULL DEFAULT 0,
logged_at TEXT NOT NULL DEFAULT (datetime('now'))
);
```
### Commands
#### pro_budget_set
Creates or updates a budget for a project.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
| `monthlyBudgetUsd` | `f64` | Yes | Monthly budget in USD |
| `softLimitPct` | `f64` | No | Soft limit percentage (default 0.80) |
| `hardLimitPct` | `f64` | No | Hard limit percentage (default 1.00) |
#### pro_budget_get
Returns the budget configuration for a project. Returns `null` if no budget is set.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
#### pro_budget_check
Pre-dispatch hook. Checks whether the project can launch a new agent session.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
**Response: `BudgetCheckResult`**
```typescript
interface BudgetCheckResult {
allowed: boolean;
currentSpendUsd: number;
budgetUsd: number;
pctUsed: number; // 0.0 to 1.0
softLimitReached: boolean;
hardLimitReached: boolean;
month: string; // YYYY-MM
}
```
#### pro_budget_log_usage
Records cost for a completed session. Called by the agent dispatcher on session end.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
| `sessionId` | `String` | Yes | Session identifier |
| `costUsd` | `f64` | Yes | Session cost |
| `override` | `bool` | No | Whether this was an emergency override |
#### pro_budget_reset
Resets the cumulative spend for a project's current month. Deletes all `pro_budget_log` entries for the current month.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
#### pro_budget_list
Returns budgets and current spend for all projects.
**Response: `Vec<ProjectBudgetStatus>`**
```typescript
interface ProjectBudgetStatus {
projectId: string;
monthlyBudgetUsd: number;
currentSpendUsd: number;
pctUsed: number;
softLimitReached: boolean;
hardLimitReached: boolean;
}
```
### Pre-Dispatch Integration
The budget check is wired into the agent launch path:
1. User triggers agent start in AgentPane.
2. `AgentSession.startQuery()` calls `pro_budget_check` before invoking the sidecar.
3. If `softLimitReached`: toast warning, agent proceeds.
4. If `hardLimitReached`: blocks launch, shows override dialog.
5. On override confirmation: calls `pro_budget_log_usage` with `override: true`, then proceeds.
6. On session completion: `agent-dispatcher` calls `pro_budget_log_usage` with actual cost.
---
## Smart Model Router
### Purpose
The Smart Model Router recommends which model to use for a given agent session based on the project's routing profile and the agent's role. It does not force model selection -- it provides a recommendation that the user can accept or override.
### Routing Profiles
Three built-in profiles define model preferences:
#### CostSaver
Minimizes cost by preferring smaller models for routine tasks.
| Role | Recommended Model |
|------|-------------------|
| Manager | claude-sonnet-4-5-20250514 |
| Architect | claude-sonnet-4-5-20250514 |
| Tester | claude-haiku-4-5-20250514 |
| Reviewer | claude-haiku-4-5-20250514 |
| Default (no role) | claude-sonnet-4-5-20250514 |
#### QualityFirst
Maximizes output quality by preferring the most capable model.
| Role | Recommended Model |
|------|-------------------|
| Manager | claude-opus-4-5-20250514 |
| Architect | claude-opus-4-5-20250514 |
| Tester | claude-sonnet-4-5-20250514 |
| Reviewer | claude-sonnet-4-5-20250514 |
| Default (no role) | claude-opus-4-5-20250514 |
#### Balanced
Default profile. Balances cost and quality per role.
| Role | Recommended Model |
|------|-------------------|
| Manager | claude-sonnet-4-5-20250514 |
| Architect | claude-opus-4-5-20250514 |
| Tester | claude-haiku-4-5-20250514 |
| Reviewer | claude-sonnet-4-5-20250514 |
| Default (no role) | claude-sonnet-4-5-20250514 |
### Commands
#### pro_router_recommend
Returns the recommended model for a given project and role.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
| `role` | `String` | No | Agent role (manager/architect/tester/reviewer) |
**Response:**
```typescript
interface RouterRecommendation {
model: string;
profile: string; // CostSaver | QualityFirst | Balanced
reason: string; // Human-readable explanation
}
```
#### pro_router_set_profile
Sets the routing profile for a project.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
| `profile` | `String` | Yes | Profile name: CostSaver, QualityFirst, or Balanced |
#### pro_router_get_profile
Returns the current routing profile for a project. Defaults to Balanced.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | `String` | Yes | Project identifier |
#### pro_router_list_profiles
Returns all available routing profiles with their role-to-model mappings. Takes no arguments.
### Integration with Agent Launch
The router recommendation is surfaced in the AgentPane model selector. When a project has a routing profile set, the recommended model appears as a highlighted option in the dropdown. The user retains full control to select any available model.