Skip to content

Agents

An Axocoatl agent is a ractor actor: an isolated unit of computation with its own mailbox, lifecycle, memory, and token budget. Each agent runs in its own task. Crashes are caught by a supervision loop that restarts the agent from its last checkpoint. State survives the process through periodic checkpoints.

Every agent has seven knobs you control in YAML:

- id: coder
name: "Coder"
provider: ollama
model: qwen2.5-coder:14b
system_prompt: |
You are a senior software engineer working in a directory session.
Write to disk with the write_file tool; never paste code as chat.
depends_on: [planner]
token_budget:
per_execution: 8000
per_call: 4000
overflow_policy: warn
sampling:
temperature: 0 # deterministic — same input, same output
response_format: json # ask the model for JSON (native mode per provider)
  • id — the agent’s name in the lattice. Other agents depends_on this id.
  • provider + model — which LLM backs this agent. Each agent can use a different one. Local for cheap tasks, frontier for hard ones, same workflow.
  • system_prompt — the agent’s role and operating instructions.
  • depends_on — which agents must complete before this one activates. Drives the DAG.
  • token_budget — a pre-flight check, enforced before every LLM call. The agent can’t spend more than per_call in any single call or more than per_execution across one full activation. overflow_policy is abort (the default — return a budget error and stop) or warn (log a warning and continue past the budget). The old summarize value is a deprecated alias that now maps to warn — context compaction toward the model window is automatic (see Memory) and no longer a spend policy.
  • sampling — per-agent generation controls, all optional: temperature, top_p, max_tokens, and response_format (text or json). Set temperature: 0 for reproducible structured tasks like a classifier or a JSON extractor; response_format: json maps to each provider’s native JSON mode (and a prompt-enforced fallback where a provider has none). Omit any field to keep the provider’s default.
  1. Spawn — on daemon boot, every agent in the config gets a ractor::Actor spawned. Agents are spawned parentless (no ractor supervisor tree); liveness is handled by the supervision loop below.
  2. Idle — the actor sits in its mailbox loop, waiting for messages.
  3. Activate — the lattice routes work to it via an Execute message when its dependencies fire.
  4. Stream — the LLM call streams tokens internally (always). The dashboard’s Studio rail reflects them live.
  5. Checkpoint — periodically the actor writes its session transcript to disk so a crash + restart can resume the conversation.
  6. Complete — publishes TaskCompleted to the lattice with the output. Other agents activate.

Agents are spawned parentless, so supervision is a liveness loop, not a ractor supervisor tree. A background runner polls every agent’s status on a 5-second interval; if an agent has stopped unexpectedly, it respawns a fresh actor whose on_start restores state from the latest checkpoint. A per-agent restart cap (5 consecutive attempts) stops a crash-looping agent from restarting forever.

The restart restores the conversation transcript only — the messages from the last checkpoint. It does not restore token-usage accounting or tool/plan state; the agent resumes the conversation and rebuilds the rest. The dashboard shows the restart in the agent’s status line.

A provider trait lets every agent pick its backend independently. Six provider ids are wired:

  • ollama — local Ollama daemon (default).
  • openai — OpenAI chat completions. Honors a configurable base_url, so it also targets any OpenAI-compatible endpoint (LM Studio, MLX, vLLM, …).
  • openrouter — the OpenAI client re-pointed at openrouter.ai, with the Axocoatl attribution headers attached.
  • anthropic — Anthropic messages API.
  • gemini — Google Gemini.
  • mistral — Mistral chat.

Each agent’s configured model is sent as a per-request override, so a shared provider still serves every agent its own model. Keys live in .env. The dashboard’s onboarding wizard fills the right keys for you.

If you change an agent’s config (system prompt, model, budget) and want the running actor to pick it up without restarting the whole daemon:

Terminal window
axocoatl agents restart coder

The supervisor stops the actor, re-reads its config, and respawns it. Memory survives.