# Architecture Layers

Each layer of Agenvoy, the package that implements it and what it is responsible for.

| Layer | Package | Responsibility |
|---|---|---|
| Entry | `cmd/app` | argv dispatch (`stop` / `update` / `--daemon` / `-p` one-shot client of `POST /v1/send`, v1.3.9; `--enable-claude-code` was Removed in v1.2.3); MCP server on non-TTY stdin; init sandbox, filesystem policy, MCP manager |
| App services | `internal/app` | agent registry build and the `config.json` watcher, used by both daemon and TUI; Telegram / Discord reload, session watcher, MCP setup, chat push hooks and skill runs, used by the daemon only (since v1.2.0 the TUI opens no MCP connections); daemon spawn, used by the TUI |
| Startup | `internal/startup` | start-on-login via a launchd plist (macOS) or systemd service (Linux), toggled from `/config`; moved from `internal/runtime/startup`, which no longer exists |
| Notes | — | operator notes (`internal/note`, the `find_note` tool, `/v1/note*` and the startup notes migration) were removed in v1.0.23; a `note` table left in an older `history.db` is no longer read |
| Runtime singleton | `internal/runtime` | `~/.config/agenvoy/runtime.uid` lock (UID, PID, start time); a second daemon aborts while the recorded one is alive; since v1.3.7 `agen stop` stops every running daemon — each `agen --daemon` process found with `ps` (`ListDaemons`) plus the recorded PID — sending SIGTERM, then SIGKILL after a 3 s grace window |
| Engine | `internal/agents/exec` | `Prepare` / `Run` (skill match, named skill, model resolution; `Start` was renamed `Run` in v1.2.1); iteration loop; tool dispatch; dispatcher routing with tiers and priority in `exec/model` since v1.2.1 (`Route` with the dispatcher in `select_with_llm.go` and the decision-model dispatcher raced against it in `select_with_decision.go` since v1.3.1 (the TypeSafe beta dispatcher in `select_with_jev.go` was Removed in v1.3.1), `Next` for fallback with a health check; since v1.1.0 a session whose reasoning is `auto` gets its level from the dispatcher's work-kind pick, replacing the global `auto_reasoning` switch, and `pass`-tier models are never picked by the dispatcher or used as fallbacks); cooldown and retry (`retryHandler`); subagent host (`exec/subagent.Exec`, at most `max(NumCPU / 2, 3)` concurrent since v1.3.0, 3 before) |
| Decision | `internal/agents/decision` | added in v1.3.1. The configured decision model (`typesafe` or `openrouter`, built with `router.NewDecision`): `Available` lists the choices (cached 15 minutes, minus excluded models), `Ready` / `Request` / `Decide` / `Batch` / `Confident` are shared by dispatch, watch checks, `search_web` / `fetch_page` filtering, the turn-context tool-gap hint and skill filter, summary filtering (the cron pass, and since v1.3.7 the per-turn relevance check on summary entries) and context-overflow tool-step pruning |
| Compaction | `internal/agents/exec/compact` | per-model threshold, tool-history and old-history folding, trim and raw-tool fallbacks; since v1.3.0 the input limit learned from overflow errors (`NoteOverflow`) and the 80% overflow trim (`TrimRatio`), preceded since v1.3.1 by decision-model tool-step pruning |
| Providers | `go-llm-router` v0.10.2 (external module) | unified `Agent.Send()` across 14 provider entries plus any OpenAI-compatible endpoint; the `claude-code` provider (in this repo from v1.1.0, moved into `go-llm-router` in v1.1.4) drives the local `claude` CLI as a model and is enabled whenever the `claude` binary is found (the `agen --enable-claude-code` opt-in was Removed in v1.2.3); reasoning and fast-mode normalization. Speech-to-text and text-to-speech route separately, backed by OpenAI, Gemini and (since v1.0.17) OpenRouter |
| Tools | `internal/tools` + `internal/runtime/toolAdapter` | built-in / API / script / extension tool definitions |
| MCP | `internal/runtime/mcp` | client and server on the official `modelcontextprotocol/go-sdk`, one package |
| Sandbox | `go-pkg/sandbox` | OS-native isolation; `Wrap()` builds the command and, since v1.3.0, `Run()` executes it |
| Filesystem | `go-pkg/filesystem` (+ `reader/`) + `internal/filesystem` | policy-aware writes; ToriiDB pathing |

Session storage, the dashboard, pending routing, memory, the scheduler, IPC and the TUI are covered in [Runtime Layers](/architecture-layers-runtime).
