System overview
31 tools, three agent tiers, and an in-process coordination bus.Three-tier agent architecture
| Tier | Agent | Step limit | Token limit | Purpose |
|---|---|---|---|---|
| 1 | Forge | 500 | Full context | Main orchestrator —plans, dispatches, responds |
| 2 | Code | 25 | 150K | File edits, refactoring, implementation |
| 2 | Explore | 15 | 80K | Read-only research, code analysis |
| 2 | WebSearch | — | — | Multi-step web research with scraping |
AgentBus
In-process coordination layer for parallel subagents. File Cache —First reader caches the content; concurrent readers get the same Promise. Generation counter prevents stale overwrites after concurrent edits. Tool Result Cache —LRU, max 200 entries. Keyed bytoolName:canonicalized-args. Covers: read_code, grep, glob, navigate, analyze, web_search. Persists across dispatches via exportCaches().
Edit Mutex —Promise-chaining serializes edits to the same file. First editor becomes owner; second gets a warning.
Findings —Agents call report_finding(label, content) to post to the bus. Each step, prepareStep() drains unseen findings and injects them as peer discovery messages.
Step lifecycle
Each agent step passes throughprepareStep():
Result pipeline
Agent quality pipeline
Schema Enforcement —The dispatch schema requires atargetFiles array on every task. Pre-dispatch validation rejects tasks without real file paths before any subagent runs.
Complexity-Tier Routing —detectTaskTier() classifies tasks as trivial or standard. Trivial tasks route to the trivialModel when configured.
De-Sloppify Pass —After code agents finish, a cleanup agent runs in fresh context to remove sloppy patterns: tests of language features, redundant type checks, console.log, commented-out code, over-defensive error handling.
Done Tool Contracts —Explore and code done tools demand pasteable code, not prose. If the parent has to re-read files, the done call failed.
Intelligence router
Routes code intelligence operations to the best available backend.| Backend | Tier | Capabilities |
|---|---|---|
| LSP | 1 | definitions, references, rename, diagnostics, code actions, call hierarchy, type info, formatting |
| ts-morph | 2 | TypeScript/JavaScript —AST definitions, references, rename, extract, unused detection |
| tree-sitter | 2 | 33 languages —symbol extraction, imports/exports, scopes, outlines |
| regex | 3 | Universal fallback —symbol search, simple definitions, import patterns |
LSP integration
Dual-backend architecture —the agent always has LSP access regardless of editor state:- Neovim bridge: When the editor is open, routes LSP requests through Neovim’s running servers via Lua RPC. Zero startup cost.
- Standalone client: When the editor is closed, spawns LSP servers directly as child processes with JSON-RPC over stdin/stdout.
- Multi-language warmup: On boot,
detectAllLanguages()scans project config files and spawns standalone LSP servers for all detected languages in parallel. - Server discovery: PATH,
~/.soulforge/lsp-servers/,~/.local/share/soulforge/mason/bin/
Web search system
| Search Backend | Trigger | Notes |
|---|---|---|
| Brave Search API | BRAVE_API_KEY set | Structured results with snippets |
| DuckDuckGo HTML | Brave unavailable | Scrapes html.duckduckgo.com, no API key |
| Page Fetch Backend | Trigger | Notes |
|---|---|---|
| Jina Reader | Always tried first | Returns clean markdown |
| Readability | Jina fails | @mozilla/readability + linkedom |
| Fallback strip | Readability fails | Regex HTML to text |
Context manager
Assembles the system prompt from multiple sources:- Mode instructions —persona-specific behavior
- Project info —detected toolchain, package.json metadata
- Git context —branch, recent commits, dirty files
- Repo map —PageRank-ranked file/symbol view
- Memory —persistent project/global memory from SQLite
- Forbidden files —security patterns that block AI access
- Outside-CWD gating —write tools require confirmation for paths outside the project
- Skills —loaded skill instructions
UI layer
Framework: OpenTUI (React reconciler for terminal UIs).| Store | Purpose |
|---|---|
stores/ui.ts | Modal state, active panels, layout flags |
stores/errors.ts | Background error log |
stores/repomap.ts | Scan progress, stats, semantic summary status |
stores/statusbar.ts | Memory usage, polling |
| Component | Purpose |
|---|---|
App.tsx | Root —wires all state, keybindings, modals |
InputBox.tsx | Multiline input with paste collapse, fuzzy history, command autocomplete |
MessageList.tsx | Chat messages with markdown, syntax highlighting, tool call progress |
ContextBar.tsx | Live context usage with green/gray dot indicator |
EditorPanel.tsx | Embedded Neovim with screen rendering |
CommandPicker.tsx | Slash command palette |
ToolCallDisplay.tsx | Real-time tool execution visualization |