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:
parent
738574b9f0
commit
8251321dac
7 changed files with 1268 additions and 59 deletions
139
docs/README.md
139
docs/README.md
|
|
@ -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
|
||||
|
|
|
|||
246
docs/architecture/overview.md
Normal file
246
docs/architecture/overview.md
Normal 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
229
docs/config/ref-settings.md
Normal 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 |
|
||||
188
docs/getting-started/quickstart.md
Normal file
188
docs/getting-started/quickstart.md
Normal 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
110
docs/pro/README.md
Normal 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.
|
||||
177
docs/pro/features/analytics.md
Normal file
177
docs/pro/features/analytics.md
Normal 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.
|
||||
238
docs/pro/features/cost-intelligence.md
Normal file
238
docs/pro/features/cost-intelligence.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue