v1.3.8

Architecture

Last updated


A high-level view of how Agenvoy fits together. For per-module diagrams, sequence flows, and the tool-dispatch state machine, jump into the topic-specific pages.

Overview


graph TB
    subgraph Entry["Entry · cmd/app"]
        App["agen · TUI (socket client) + daemon<br/>agen stop · update · --daemon<br/>non-TTY stdin · MCP server"]
        Web["Web dashboard · page/<br/>embedded in the binary<br/>served at 127.0.0.1 / [::1]:17989"]
        IPC["Daemon IPC · internal/runtime/ipc<br/>~/.config/agenvoy/daemon.sock · 0600<br/>run · pending · cancel · steer · reply · mcp"]
    end

    subgraph Engine["Engine · internal/agents/exec"]
        Run["exec.Prepare · exec.Run<br/>skill match → named skill → exec/model.Route<br/>session model · dispatcher · tiers · priority"]
        Execute["exec.Execute · ≤256 iterations<br/>3-pass parallel tool calls<br/>7 fixed tools loaded, rest by name via run_tool"]
        Sub["exec/subagent.Exec<br/>in-process · max(NumCPU/2, 3) concurrent<br/>background legs (TUI)"]
        Compact["compact · threshold → old history → tool history<br/>overflow → learned limit → decision prune → trim"]
        Decision["decision · internal/agents/decision<br/>TypeSafe / OpenRouter · 3 s typed calls<br/>dispatch · watch · web filter · turn context · summary · trim"]
    end

    subgraph Pending["Pending · internal/runtime"]
        Reg["Prefix-routed listener registry<br/>per-entry buffered=1 reply ch<br/>TUI cli- (per window) · web chat- · Telegram tg- · Discord dc-"]
        BG["Background jobs · internal/tools/interactive<br/>cmd_ · sub_ legs grouped per turn<br/>report to open task · run next when ended · cancel"]
    end

    subgraph Providers["go-llm-router v0.10.1 · 14 provider entries + compat<br/>incl. claude-code · + TypeSafe for decisions"]
        P["OpenAI · Codex · Claude · Gemini<br/>Grok · Grok (xAI) · Copilot · DeepSeek<br/>Mistral · NVIDIA · Ollama Cloud · OpenRouter<br/>Cloudflare · + any OpenAI-compatible endpoint<br/>Claude Code · local claude CLI, opt-in"]
    end

    subgraph Tools["Tool Subsystem · internal/tools"]
        T["find_files · read_files · edit_file · file_history<br/>search_web · fetch_page · http_request<br/>subagents · schedules · run_skill · ask_user<br/>chat_history · error_history · find_tools · run_tool<br/>run_command · background_command · background_subagents<br/>public_api_list · reasoning_guide · write_result · html_template"]
        MCP["MCP · internal/runtime/mcp<br/>client + server · go-sdk"]
        Adapter["toolAdapter · internal/runtime<br/>script_* · ext_*"]
    end

    subgraph Security["Security · go-pkg/sandbox"]
        S["bwrap (Linux) / sandbox-exec (macOS)<br/>filesystem.Policy · DeniedMap"]
    end

    subgraph Session["Session · internal/session"]
        SL["history.json · summary.json<br/>action.log · pending/<br/>fsnotify watch"]
    end

    subgraph Memory["Memory · SQLite + ToriiDB"]
        M["history.db · session · message_meta<br/>messages + FTS5 · action_history<br/>file_history · usage + tool call ids<br/>db_0..db_3 · error_memory 90d TTL"]
    end

    subgraph Kura["KuraDB · user-registered MCP server"]
        K["kura mcp<br/>one entry in mcp.json<br/>mcp__kura__list_rag · mcp__kura__search_rag"]
    end

    App -->|Unix socket| IPC
    IPC --> Run
    Web --> Run
    Run --> Execute
    Execute -->|subagents| Sub
    Sub -->|exec.Run isSub| Run
    Execute --> Compact
    Execute -->|tool gap · skill filter| Decision
    Compact --> Decision
    Execute -->|Send| Providers
    Execute -->|tool calls| Tools
    Tools --> MCP
    Tools --> Adapter
    Tools --> Security
    Tools -.->|mcp__kura__*<br/>absent when the server is not registered| Kura
    Execute <-->|confirm/ask| Pending
    IPC <-->|ask · reply| Pending
    Sub <-->|subagent ask_user| Pending
    Tools -->|background| BG
    BG -->|resume| Run
    Execute <--> Memory
    Execute <--> Session
  1. graph TB
  2. subgraph Entry["Entry · cmd/app"]
  3. App["agen · TUI (socket client) + daemon<br/>agen stop · update · --daemon<br/>non-TTY stdin · MCP server"]
  4. Web["Web dashboard · page/<br/>embedded in the binary<br/>served at 127.0.0.1 / [::1]:17989"]
  5. IPC["Daemon IPC · internal/runtime/ipc<br/>~/.config/agenvoy/daemon.sock · 0600<br/>run · pending · cancel · steer · reply · mcp"]
  6. end
  7. subgraph Engine["Engine · internal/agents/exec"]
  8. Run["exec.Prepare · exec.Run<br/>skill match → named skill → exec/model.Route<br/>session model · dispatcher · tiers · priority"]
  9. Execute["exec.Execute · ≤256 iterations<br/>3-pass parallel tool calls<br/>7 fixed tools loaded, rest by name via run_tool"]
  10. Sub["exec/subagent.Exec<br/>in-process · max(NumCPU/2, 3) concurrent<br/>background legs (TUI)"]
  11. Compact["compact · threshold → old history → tool history<br/>overflow → learned limit → decision prune → trim"]
  12. Decision["decision · internal/agents/decision<br/>TypeSafe / OpenRouter · 3 s typed calls<br/>dispatch · watch · web filter · turn context · summary · trim"]
  13. end
  14. subgraph Pending["Pending · internal/runtime"]
  15. Reg["Prefix-routed listener registry<br/>per-entry buffered=1 reply ch<br/>TUI cli- (per window) · web chat- · Telegram tg- · Discord dc-"]
  16. BG["Background jobs · internal/tools/interactive<br/>cmd_ · sub_ legs grouped per turn<br/>report to open task · run next when ended · cancel"]
  17. end
  18. subgraph Providers["go-llm-router v0.10.1 · 14 provider entries + compat<br/>incl. claude-code · + TypeSafe for decisions"]
  19. P["OpenAI · Codex · Claude · Gemini<br/>Grok · Grok (xAI) · Copilot · DeepSeek<br/>Mistral · NVIDIA · Ollama Cloud · OpenRouter<br/>Cloudflare · + any OpenAI-compatible endpoint<br/>Claude Code · local claude CLI, opt-in"]
  20. end
  21. subgraph Tools["Tool Subsystem · internal/tools"]
  22. T["find_files · read_files · edit_file · file_history<br/>search_web · fetch_page · http_request<br/>subagents · schedules · run_skill · ask_user<br/>chat_history · error_history · find_tools · run_tool<br/>run_command · background_command · background_subagents<br/>public_api_list · reasoning_guide · write_result · html_template"]
  23. MCP["MCP · internal/runtime/mcp<br/>client + server · go-sdk"]
  24. Adapter["toolAdapter · internal/runtime<br/>script_* · ext_*"]
  25. end
  26. subgraph Security["Security · go-pkg/sandbox"]
  27. S["bwrap (Linux) / sandbox-exec (macOS)<br/>filesystem.Policy · DeniedMap"]
  28. end
  29. subgraph Session["Session · internal/session"]
  30. SL["history.json · summary.json<br/>action.log · pending/<br/>fsnotify watch"]
  31. end
  32. subgraph Memory["Memory · SQLite + ToriiDB"]
  33. M["history.db · session · message_meta<br/>messages + FTS5 · action_history<br/>file_history · usage + tool call ids<br/>db_0..db_3 · error_memory 90d TTL"]
  34. end
  35. subgraph Kura["KuraDB · user-registered MCP server"]
  36. K["kura mcp<br/>one entry in mcp.json<br/>mcp__kura__list_rag · mcp__kura__search_rag"]
  37. end
  38. App -->|Unix socket| IPC
  39. IPC --> Run
  40. Web --> Run
  41. Run --> Execute
  42. Execute -->|subagents| Sub
  43. Sub -->|exec.Run isSub| Run
  44. Execute --> Compact
  45. Execute -->|tool gap · skill filter| Decision
  46. Compact --> Decision
  47. Execute -->|Send| Providers
  48. Execute -->|tool calls| Tools
  49. Tools --> MCP
  50. Tools --> Adapter
  51. Tools --> Security
  52. Tools -.->|mcp__kura__*<br/>absent when the server is not registered| Kura
  53. Execute <-->|confirm/ask| Pending
  54. IPC <-->|ask · reply| Pending
  55. Sub <-->|subagent ask_user| Pending
  56. Tools -->|background| BG
  57. BG -->|resume| Run
  58. Execute <--> Memory
  59. Execute <--> Session

run_command_background was renamed background_command, and run_websocket, pkg_manage and user-defined api_* tools were dropped (Removed in v1.3.2); use background_command, run_command with sudo or sandbox: false, and the built-in public_api_list instead.

Cross-cutting principles


  • OS-native sandbox over Go-side filters — security policy is enforced at the OS boundary; new restrictions go into go-pkg/sandbox, not into agenvoy callers
  • Prompt as policy — system-prompt protection (the guardrail rules from configs/jsons/guardrail_rules.json) and the cross-tool output rules live in the system prompt under configs/prompts/, while which tool fits which request lives in that tool's own description; adding a category means editing the prompt or the description, not the engine. The permission mode is no longer stated in the system prompt (Removed in v1.3.7); the confirm gate enforces it
  • In-process over HTTP for subagents — subagents(mode=invoke) goes through exec/subagent.Exec, which calls exec.Run(..., isSub=true) directly, sharing the same provider clients, sandbox, pending registry, and memory layer; AllowAll and WorkDir flow through ctx
  • Read tools fan out, write tools serialize — concurrency is opt-in and requires both "no side effects" and "upstream allows parallelism"
  • One config layer per concern — provider credentials in OS keychain, registered models, priority, tiers, and limits in config.json, MCP in mcp.json, session config and persona in the SQLite session table; each tool author / user touches at most one place
  • One daemon runs every agent — the browser dashboard, the chat channels, and external callers reach the daemon over HTTP on 127.0.0.1:17989 (also [::1]:17989); since v1.2.0 the TUI no longer runs agents or opens MCP connections itself and sends runs, pending resumes, cancels, steers, replies and /mcp actions over the Unix socket ~/.config/agenvoy/daemon.sock (mode 0600, newline-delimited JSON). The dashboard is embedded rather than hosted, so there is no second origin to keep in sync
  • Vendor code lives upstream — provider adapters moved to go-llm-router and the MCP protocol to the official go-sdk; a fix belongs in the upstream module rather than a local shim
中文