Understand how afk works
Follow a request through the shared session harness, provider routing, tool dispatch, and durable state.
AFK is a standalone agent runtime: it connects a model to tools, applies policy around their execution, and records the work. The terminal, Telegram, daemon, and web interface are different surfaces over the same session harness. Understanding that separation helps you choose a surface without confusing the conversation, the model provider, and the processes doing the work.
Follow a request through the runtime
Start an interactive session in a project:
afk iFor a single request without the REPL:
afk chat "Explain the structure of this project without changing files."Load the session configuration
The surface creates an AgentSession, loads the composed system prompt, discovers extensions, and connects configured MCP servers. An ongoing REPL or chat conversation can reuse its session across many turns; it does not bootstrap from nothing for every message.
Send context to the selected provider
The harness sends your message, instructions, available tool definitions, and conversation context to the provider selected for the model. Providers translate their own API events into a common stream that AFK's surfaces can render.
Execute requested tools through the dispatcher
The model requests a tool; the runtime checks the available tool surface and applicable permissions and hooks. PreToolUse hooks can block before execution. Successful or failed tool execution produces results and the corresponding post-execution events.
Continue until the turn finishes
Tool results become input to the next model round. The loop continues until the model finishes, a limit or error ends the turn, or you interrupt. The session records evidence and may remain open for your next message.
The core implementation lives under src/agent/; terminal surfaces under src/cli/, Telegram under src/telegram/, and browser automation under src/browser/. The provider boundary keeps those surfaces independent of any one model SDK.
Provider routing
Model slots and aliases resolve before model-name inference. An explicit provider override takes precedence, followed by a slot's provider binding and model-based routing.
| Provider family | Typical models | Connection |
|---|---|---|
| Anthropic direct | Claude models and aliases bound to them | Anthropic Messages API, with thinking and prompt-cache support where available |
| OpenAI-compatible | GPT, o-series, Codex, and supported org/model or local-server IDs | Chat Completions-compatible endpoints; the ChatGPT subscription path uses the Responses wire |
| xAI | Grok models | Dedicated xAI provider with API-key or supported OAuth authentication |
Use models and providers for credentials and compatibility, and local models for custom endpoints. Provider support is not a promise that every model has identical tool, image, thinking, or context capabilities.
For an explicit override with a matching model alias:
afk chat "Explain this project." --model sonnet --provider anthropic-direct/model can change the model in an ongoing session. If the provider or endpoint changes, the router rebuilds the provider runtime while preserving session accounting. With a journal, it transfers structured conversation history subject to the target provider's supported content; without one it uses a text-history fallback. See sessions and context.
Tool dispatch and delegation
Tools act on the world; model text alone does not change files or send a message. The available tools depend on operator configuration, model-slot restrictions, surface capabilities, and subagent scope, rather than one fixed universal list.
| Tool group | Purpose |
|---|---|
| Files and shell | read_file, write_file, edit_file, patch_apply, glob, grep, list_directory, and bash inspect or change local state |
| Web and browser | web_scrape fetches Markdown, raw text, or search results; browser tools navigate and interact through Playwright |
| Delegation | agent creates a child session; skill runs a reusable procedure; compose schedules dependent tasks and parallel independent tasks |
| Memory | memory_search, memory_update, and procedure_write, when available, work with durable cross-session memory |
| Operator communication | send_telegram notifies the configured operator; it reports an error if Telegram is not configured |
| Configuration | config_get and config_set inspect or edit supported configuration, with secrets masked and sensitive keys restricted |
| Integrations | MCP tools appear under names such as mcp__server__tool |
Child sessions have their own execution context and constrained tool surface. Parent cancellation propagates through the child tree. compose expresses task dependencies explicitly; its default failure policy cancels ongoing siblings and skips downstream tasks, while best-effort workflows can disable fail-fast behavior. See subagents.
MCP configuration layers from plugin contributions to user configuration, project .mcp.json, and an explicit --mcp-config file. Servers connect in parallel, and tool-list change notifications refresh the top-level tool surface. Forked children do not automatically inherit the parent's MCP manager.
The tool reference describes individual contracts. Use tool access to control which tools are exposed, and extensions to add procedures or integrations.
Outcomes are distinct from runtime completion
The framework asks the agent to finish with a useful terminal state, rather than merely stop producing text:
| State | Meaning |
|---|---|
| Done | The objective is satisfied, with evidence you can inspect |
| Blocked | An external dependency prevents progress, with an exact unblock condition |
| Asking | A specific question must be answered before proceeding |
| Interrupted | You halted the work, with state preserved where possible |
Interactive surfaces render outcome information. These task outcomes are different from lower-level runtime events such as a completed turn, an error, or cancellation. A successful API response or process exit does not by itself prove that the task was completed correctly; use verification.
System prompt layering
AFK always starts with its framework base prompt, then appends an operator overlay when one is configured. The overlay source follows this precedence:
| Priority | Source |
|---|---|
| Highest | AFK_SYSTEM_PROMPT |
| Next | systemPrompt in afk.config.json |
| File fallback | User ~/.afk/AFK.md plus project AFK.md |
In the file tier, both nonempty files are combined, user first and project second. An absent overlay leaves the framework base alone; an overlay does not replace the base. --dump-prompt lets you inspect the composed prompt and its provenance. See AFK.md and editing configuration.
Where state lives
AFK's default runtime home is ~/.afk/, independent of Claude Code's runtime directory. AFK_HOME can relocate that home; AFK_STATE_DIR can relocate the state tier separately. Project-local extensions and artifacts can also live under the project's .afk/ directory.
~/.afk/
config/ configuration, MCP servers, schedules
state/
sessions/ session sidecars, event ledgers, journals, blobs
todos/ todo panel data
transcripts/ saved conversation transcripts
daemon/ daemon state
memory/ cross-session memory
witness/ traces and captured evidence
bg/ background agent job records and logs
proc-jobs/ supervised shell process logs
queue/ queued tasks
plugins/ installed plugins
skills/ user skills
farms/ branch farm workspaces
logs/
cache/
agent-framework/ telemetry and derived session recordsThe message journal preserves conversation content and tool results; the witness trace records what ran and how it ended. Retention settings bound parts of this storage, so treat it as runtime state, not a permanent backup. See sessions and context and observability.
Permissions and isolation
AFK does not require approval for every ordinary tool call, but specific boundaries can prompt or block. New CLI installations default to bypass permissions unless configured otherwise. Contained modes support path approval; autonomous mode adds a high-risk action gate, including an operator approval path when available.
A worktree keeps repository changes separate from your main checkout:
afk i --worktreeIt does not isolate network access or the rest of the machine. Read safety and permissions before delegating sensitive or unattended work.