Architecture guide for contributors
This document explains how Akmon is organized internally and how the core agent loop works.
Crate structure
akmon/
├── crates/
│ ├── akmon-cli/ # binary entry point, args, command routing
│ ├── akmon-core/ # policies, sandbox, shared types, security primitives
│ ├── akmon-config/ # config loading and provider resolution inputs
│ ├── akmon-models/ # provider adapters and stream normalization
│ ├── akmon-tools/ # tool implementations
│ ├── akmon-query/ # agent loop, context assembly, session lifecycle
│ ├── akmon-tui/ # ratatui UI and runtime bridge
│ └── akmon-index/ # optional semantic index
The agent loop (akmon-query/src/session.rs)
At a high level:
- build prompt/context bundle,
- call provider stream,
- process deltas and stop reason,
- execute tool calls when requested,
- append tool results to context,
- continue loop until model ends with no pending tools.
Stop-reason behavior:
ToolUse: execute tools, continue loop,EndTurn+ tool calls: execute then continue,EndTurnwith no tool calls: complete run,MaxTokens: perform continuation strategy where applicable.
This loop is why Akmon behaves like an autonomous worker, not a one-response chatbot.
Context assembly order
Effective ordering in practice:
- project/system steering (
AKMON.mdand base system instructions), - optional specs/handoff context,
- language/profile hints,
- conversation history,
- dynamic extras (todos/memory blocks).
The order prioritizes stable steering first, then volatile task state later.
Provider abstraction
akmon-models normalizes provider-specific behavior into common stream events and model errors so akmon-query can remain provider-agnostic.
Responsibilities include:
- mapping provider payloads to
StreamEvent, - retry handling where provider-specific (for example rate limits),
- first-token/stream timeout behavior,
- provider display and model-specific heuristics.
Permission system path
Before tool execution:
- derive concrete permission requirement from tool + args,
- evaluate policy mode (deny/auto/interative),
- request user confirmation if needed,
- execute tool only after allow.
This is enforced centrally in session execution flow, not left to individual tools.
Adding a tool
- implement
Tooltrait inakmon-tools, - define permission requirements and argument schema,
- register in tool registry,
- add unit tests and integration path checks,
- document in
docs/src/reference/tools.md.
Common mistakes and troubleshooting
- Mistake: adding side effects in a read-oriented tool.
- Mistake: bypassing policy path for convenience.
- Mistake: returning unstructured errors that break UX/reporting.
- Fix: keep tool outputs structured and route all side effects through permission-checked paths.