# 架構分層

Agenvoy 的每一層、實作它的 package 與其職責。

| 層 | 套件 | 職責 |
|---|---|---|
| Entry | `cmd/app` | argv dispatch（`stop` / `update` / `--daemon` / `--enable-claude-code`）；stdin 非 TTY 時作為 MCP server；初始化 sandbox、filesystem policy、MCP manager |
| App services | `internal/app` | 建立 agent registry 與監看 `config.json`，daemon 與 TUI 皆使用；重新載入 Telegram / Discord、session watcher、MCP 設定、聊天推送 hook 與 skill 執行僅 daemon 使用（v1.2.0 起 TUI 不再開啟任何 MCP 連線）；daemon 啟動由 TUI 使用 |
| Startup | `internal/startup` | 以 launchd plist（macOS）或 systemd service（Linux）登入時啟動，由 `/config` 切換；由 `internal/runtime/startup` 移入，原路徑已不存在 |
| Notes | — | 操作者筆記（`internal/note`、`find_note` 工具、`/v1/note*` 與啟動時的筆記 migration）已於 v1.0.23 移除；舊版 `history.db` 留下的 `note` 表不再被讀取 |
| Runtime singleton | `internal/runtime` | `~/.config/agenvoy/runtime.uid` 鎖（PID、啟動時間、claude-code 旗標）；紀錄中的 daemon 仍存活時，第二個 daemon 直接中止；`agen stop` 送出 SIGTERM，3 秒寬限後改送 SIGKILL |
| Engine | `internal/agents/exec` | `Prepare` / `Run`（skill 比對、指名 skill、模型解析；`Start` 於 v1.2.1 更名為 `Run`）；iteration loop；tool dispatch；結合 tier 與優先序的 dispatcher 路由自 v1.2.1 起位於 `exec/model`（`Route`，dispatcher 在 `select_with_llm.go`、TypeSafe beta dispatcher 在 `select_with_jev.go`，`Next` 負責 fallback 與健康檢查；v1.1.0 起 reasoning 設為 `auto` 的 session 依 dispatcher 判定的工作類型取得等級，取代全域 `auto_reasoning` 開關，且 `pass` tier 模型不會被 dispatcher 選中、也不作為 fallback）；cooldown 與重試（`retryHandler`）；subagent host（`exec/subagent.Exec`，最多 3 個並行） |
| Compaction | `internal/agents/exec/compact` | 各模型門檻、tool 歷史與舊歷史折疊、trim 與 raw-tool fallback |
| Providers | `go-llm-router` v0.9.4（外部模組） | 跨 14 個 provider 條目及任何 OpenAI 相容端點的統一 `Agent.Send()`；`claude-code` provider（v1.1.0 起位於本 repo，v1.1.4 移入 `go-llm-router`）以本機 `claude` CLI 作為模型，預設關閉，須以 `agen --enable-claude-code` 啟動（daemon 須先停止）；reasoning 與 fast 模式正規化。speech-to-text 與 text-to-speech 各自獨立路由，由 OpenAI、Gemini 與（v1.0.17 起）OpenRouter 支援 |
| Tools | `internal/tools` + `internal/runtime/toolAdapter` | built-in / API / script / extension tool 定義 |
| MCP | `internal/runtime/mcp` | 建構於官方 `modelcontextprotocol/go-sdk` 的 client 與 server，單一套件 |
| Sandbox | `go-pkg/sandbox` | OS-native 隔離，單一入口 `Wrap()` |
| Filesystem | `go-pkg/filesystem`（+ `reader/`）+ `internal/filesystem` | policy-aware 寫入；ToriiDB pathing |

Session 儲存、儀表板、pending 路由、記憶、排程、IPC 與 TUI 見 [執行期分層](/zh/docs/architecture-layers-runtime)。
