Engines
An engine is a direct LLM adapter inside APX. When you call apx exec or apx chat, APX
resolves the target model, selects the matching adapter, and calls the provider API — no external
process is spawned.
This is distinct from apx run, which delegates to an external coding CLI. See
Runtimes for that path.
Supported engines
Section titled “Supported engines”| Provider | Adapter ID | Notes |
|---|---|---|
| Anthropic | anthropic | Claude models; key from ANTHROPIC_API_KEY or config |
| OpenAI | openai | GPT and o-series models; key from OPENAI_API_KEY or config |
| Gemini | gemini | Google Gemini models; key from GEMINI_API_KEY or config |
| Ollama | ollama | Local models; no API key needed, just base_url |
| Groq | groq | OpenAI-compatible; default model llama-3.3-70b-versatile |
| OpenRouter | openrouter | OpenAI-compatible; routes to many providers; default model meta-llama/llama-3.3-70b-instruct |
| Mock | mock | Returns a canned response; useful for testing and CI |
Engine configuration
Section titled “Engine configuration”Engines are configured in ~/.apx/config.json under the engines key:
{ "engines": { "anthropic": { "api_key": "sk-ant-..." }, "openai": { "api_key": "sk-...", "base_url": "https://api.openai.com/v1" }, "gemini": { "api_key": "..." }, "groq": { "api_key": "...", "base_url": "https://api.groq.com/openai/v1" }, "openrouter":{ "api_key": "...", "base_url": "https://openrouter.ai/api/v1" }, "ollama": { "base_url": "http://localhost:11434" } }}API keys can also be set via environment variables — ANTHROPIC_API_KEY, OPENAI_API_KEY,
GEMINI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY — without editing the config file.
Model ID grammar
Section titled “Model ID grammar”When specifying a model to --model or in an agent definition, APX accepts two forms:
- Explicit:
<provider>:<model>— e.g.ollama:llama3.2,anthropic:claude-sonnet-4-5,openrouter:meta-llama/llama-3.3-70b-instruct - Inferred: bare model name — APX resolves the provider automatically:
claude-*→anthropicgpt-*,o1-*,o3-*,o4-*→openaigemini-*→geminimock→mock
If APX cannot infer the provider, use the explicit provider:model form.
Running a one-shot exec
Section titled “Running a one-shot exec”apx exec "<prompt>" [--model <id>] [--max-tokens N] [--temperature T] [--project <name|id|path>]apx exec -a <agent> "<prompt>" [--model <id>]Without -a, the call goes to the APX super-agent (the daemon’s default). With -a, it uses the
specified APC agent’s system prompt and memory.
Examples:
# Super-agent, default modelapx exec "Summarize the open tasks in this project"
# Specific agent with model overrideapx exec -a reviewer "What are the riskiest changes in this PR?" --model anthropic:claude-opus-4-5
# Local Ollama modelapx exec "Explain this stack trace" --model ollama:llama3.2
# Force a specific output sizeapx exec "Write a haiku about daemons" --max-tokens 100Interactive chat
Section titled “Interactive chat”apx chat <agent> [--model <id>] [--conversation <id>] [--project <name|id|path>]apx chat opens an interactive REPL that keeps a conversation thread alive across turns. Each
session is stored under ~/.apx/projects/<apx-id>/agents/<slug>/conversations/. Pass
--conversation <id> to resume a previous thread.
apx chat reviewerapx chat reviewer --conversation abc123The model fallback router
Section titled “The model fallback router”For the APX super-agent (the daemon’s own assistant), APX maintains a model fallback router. Instead of failing when a provider is unavailable, it tries providers in a configurable order.
The router is configured under super_agent.model_fallback in ~/.apx/config.json:
{ "super_agent": { "model": "ollama:llama3.2:3b", "model_fallback": { "enabled": true, "models": [ "openrouter:meta-llama/llama-3.3-70b-instruct", "groq:llama-3.3-70b-versatile" ], "health_timeout_ms": 800 } }}The router tries super_agent.model first. If it fails the health check (Ollama strictly verifies
the model is pulled; cloud providers check reachability within health_timeout_ms), it walks
model_fallback.models in order and uses the first healthy one.
super_agent.model is also what every project agent with Model: inherit (or no model) runs on.
To give the super-agent a different model without moving the whole fleet, set
super_agent.self_model (Settings → Super-agent → Own model). It is a preference, not a pin: it is
health-checked and falls down the same chain, router #1 first. Switch that off with
super_agent.self_model_fallback: false (the checkbox under it) to fail instead; a project agent
pinned to its own Model: has the same switch (model_fallback: false, apx agent set --no-model-fallback).
An account whose usage limit is spent is skipped for an hour instead of being retried on every
turn, and turns nobody is watching (a2a, routines) stop rather than fall through, unless they
started on a model you chose with its fallback on — see
the super-agent page. For the ChatGPT plan, reasoning effort
is a setting of the model, not another model: the panel shows an Effort control beside every
model picker and displays the pair as gpt-5.6-luna · high. It is stored as a suffix on the model
id — chatgpt-codex:gpt-5.6-luna@medium (minimal|low|medium|high|xhigh), which is also how the
CLI takes it — or as a default in engines.chatgpt-codex.reasoning_effort.
What the calls cost
Section titled “What the calls cost”Every engine call is recorded in ~/.apx/usage/<day>.jsonl (UTC days) with its model, surface,
agent, duration and tokens. apx usage summarizes a day by model, channel and agent:
apx usage # todayapx usage --date 2026-09-23 --since 11apx usage breaker # the spend breaker: last hour of background calls, any pauseapx usage resume # lift a pause nowThe spend breaker
Section titled “The spend breaker”Background work — routines, agents talking to each other, and task threads agents hand to each
other — has an hourly ceiling on model calls, counted over the last hour, globally and per project.
Past it, that work pauses (30 minutes by default) and you get one Telegram line saying so. Your own
chats are never paused, and neither is an agent you are waiting on from one of them. The limits live in
super_agent.spend_breaker:
{ "super_agent": { "spend_breaker": { "enabled": true, "calls_per_hour": 400, "project_calls_per_hour": 250, "pause_min": 30} } }Managing the router with apx model
Section titled “Managing the router with apx model”The apx model subcommands let you inspect and configure the fallback router without editing
JSON by hand:
apx model status # print provider health, fallback order, and active modelapx model order ollama openrouter groq # set the attempt orderapx model key groq sk-xxxx # save a provider API keyapx model key openrouter sk-or-xxxxapx model set openrouter openrouter/anthropic/claude-3.7-sonnet # pin a specific model for a providerapx model test # resolve which model the router would pick right nowapx model enable # enable the fallback routerapx model disable # disable (primary model only)$ apx model status Model router primary: anthropic:claude-sonnet-4-5 fallback: on order: ollama → openrouter → groq active: anthropic:claude-sonnet-4-5 ✓ ollama llama3.2:3b up key:config ✓ openrouter meta-llama/llama-3.3-70b up key:config ✗ groq llama-3.3-70b-versatile down (no key) ✓ anthropic claude-sonnet-4-5 up key:config Keys → ~/.apx/config.json engines.{groq,openrouter}.api_key Or env: GROQ_API_KEY, OPENROUTER_API_KEY
Provider key shortcuts
Section titled “Provider key shortcuts”apx model key writes the key into engines.<provider>.api_key in ~/.apx/config.json.
Two providers that are commonly used as fallbacks have shortcut names:
apx model key groq <key> # → engines.groq.api_keyapx model key openrouter <key> # → engines.openrouter.api_keyFor Anthropic, OpenAI, and Gemini, set keys the same way:
apx model key anthropic <key>apx model key openai <key>apx model key gemini <key>Terminology note
Section titled “Terminology note”The config file uses the key engines for what this documentation calls engines (direct LLM
adapters). An earlier design used the key model_providers internally. If you see references to
model_providers in older skill files or notes, they refer to the same concept; the canonical key
in ~/.apx/config.json is engines.
run vs. exec
Section titled “run vs. exec”apx exec / apx chat | apx run | |
|---|---|---|
| Execution model | Direct LLM call inside APX | External CLI subprocess |
| File edits / shell | No | Yes (the external CLI can write files and run commands) |
| Model choice | --model flag or agent config, resolved by APX | Controlled by the external CLI’s own config |
| Speed | Fast — one API call | Slower — spawns a process, may take minutes |
| Use when | Quick Q&A, generation, reasoning | Full coding-agent work (edits, terminal) |
Related
Section titled “Related”- Runtimes — external coding CLIs via
apx run - Configuration — full
~/.apx/config.jsonreference