Super-agent
The super-agent is a mode, not a persona name. When you run apx exec without targeting a
specific project agent, APX activates this mode: the daemon-level, tool-using loop that can reach
every registered tool — file operations, MCP calls, Telegram, shell, tasks, sessions, and more.
The name the assistant uses when talking to you comes from ~/.apx/identity.json (default
“APX”). References to “super-agent” are an internal technical term for the mode. You configure
it with super_agent.* keys in ~/.apx/config.json, and routine kinds may still say
super_agent — but users never see that label.
Enabling it
Section titled “Enabling it”The mode is disabled by default. Set both keys before you first call it:
apx config set super_agent.enabled trueapx config set super_agent.model "anthropic:claude-sonnet-4-5"Once enabled, every apx exec call without -a <agent> goes through this mode.
apx exec — the one-shot entry point
Section titled “apx exec — the one-shot entry point”apx exec "<prompt>" # super-agent mode (default)apx exec -- "<prompt>" # same; -- avoids flag parsing issuesapx exec -a reviewer "<prompt>" # named project agent insteadapx exec "<prompt>" --model gpt-5 # override the configured model for this callapx exec "<prompt>" --max-tokens 2000 # cap output tokensapx exec "<prompt>" --project my-app # pin to a specific project context$ apx exec 'list my open tasks across all projects' Roby (super-agent) · anthropic:claude-sonnet-4-5 → tool tasks.list { project: "First Project", state: "open" } → tool tasks.list { project: "Acme Store", state: "open" } → tool tasks.list { project: "Data Pipeline", state: "open" } You have 4 open tasks: • First Project — Wire Stripe webhooks before merge (due 06-16) • Acme Store — Retry-guard the flaky cart-total test (due 06-18) • Acme Store — Document the pairing flow for the web panel • Data Pipeline — Backfill ingestion CLI flag (due 06-20) # 612 tok in / 198 out · 2.4s
When the super-agent mode is active the daemon resolves the assistant’s name from
~/.apx/identity.json and displays it in status lines, TUI headers, and Telegram replies —
never the string “super-agent”.
The tool loop
Section titled “The tool loop”Under the hood runSuperAgent() builds a system prompt (identity block + project inventory +
memory block + active-threads block), selects a tool schema subset appropriate for the channel,
then calls the engine via the standard runAgent() loop. The loop continues until the model stops
calling tools or a signal aborts it.
Tool registry
Section titled “Tool registry”The full registry has around 30 native tools plus registry-bridged tools (browser, fetch, search, glob, grep). The daemon picks a subset based on the channel to stay within cheap-tier TPM budgets:
| Channel | Tool set | Rationale |
|---|---|---|
api / apx exec | Full | Deliberate, user-picked model |
routine | Full | Scheduled, autonomous, user-picked model |
web / code | Full | Long-form workspace |
telegram | Core (~700 tokens) | Cheap tiers, snappy replies |
desktop / deck | Core | Same |
The model can always expand its surface by calling load_skill.
Selected native tools
Section titled “Selected native tools”| Tool | What it does |
|---|---|
create_task / list_tasks | Add and read per-project TODO items |
call_agent | Delegate to a named project agent without spawning a new process |
call_mcp | Call any registered MCP server tool |
call_runtime | Delegate to an external runtime (Claude Code / Codex …), synchronously or in the background |
run_subagent | Spawn an isolated sub-agent (fresh context, same tools minus user-interaction ones) that works a self-contained task to completion and returns its result — one nesting level max |
run_shell | Execute a shell command (gated by permission mode) |
send_telegram | Send a message via the Telegram plugin |
remember | Write a durable fact to ~/.apx/memory.md |
search_sessions | Retrieve past session transcripts |
set_identity | Update ~/.apx/identity.json fields |
Cross-channel brokering
Section titled “Cross-channel brokering”The super-agent mode is the common handler behind every surface: Telegram messages, Desktop window
prompts, apx exec calls, web chat, and routine runs all converge on runSuperAgent(). Each
surface passes a channel identifier (telegram, desktop, web, routine, api, …) which
drives:
- Which tool subset is visible to the model.
- Whether an “active threads” block (recent turns on other channels) is injected.
- Which Telegram sender identity and role-gating rules apply.
The memory broker runs before every non-tool-free call and injects a [MEMORIA RELEVANTE] block
into the system prompt. See Memory system for details.
Identity — apx identity
Section titled “Identity — apx identity”The assistant’s user-facing name is stored in ~/.apx/identity.json:
{ "agent_name": "APX", "owner_name": ""}Three commands manage it:
apx identity show # print current identity fieldsapx identity set agent_name Ada # change the display name to "Ada"apx identity set owner_name Sam # set the owner/user nameapx identity wizard # interactive setup prompt$ apx identity show Agent name : Roby Personality : pragmatic, concise, a little playful Owner : Alex Context : prefers es-AR, ships fast, hates ceremony Language : en (apx config set user.language <code>) Last wakeup : 2026-06-14 09:31 File : ~/.apx/identity.json
Permission mode
Section titled “Permission mode”permission_mode in super_agent controls what the tool loop can do without asking:
| Mode | Behavior |
|---|---|
total | All tools run without confirmation |
automatico | APX decides automatically (recommended) |
permiso | Only tools in allowed_tools; everything else asks |
apx permission set automaticoInline security-risk analysis
Section titled “Inline security-risk analysis”An opt-in layer on top of the permission mode (inspired by OpenHands’ LLMSecurityAnalyzer).
When enabled, every tool schema gains a required security_risk field (LOW / MEDIUM / HIGH)
that the model must fill as part of the call itself — no extra LLM pass. Calls graded at or above
confirm_at pause for your confirmation on the active surface (web dialog, Telegram); a declined
call comes back to the model as an error observation so it can re-plan.
"super_agent": { "security_risk": { "enabled": true, "confirm_at": "HIGH", "confirm_unknown": true }}confirm_at— minimum grade that pauses (LOWconfirms everything,HIGHonly destructive/outward actions).confirm_unknown— also pause when the model didn’t grade the call (weak models sometimes omit the field).
It’s not a duplicate of the permission mode — it gates by a different axis. Permission mode decides by tool identity (is this tool dangerous / on the allowlist); the risk analyzer decides by the model’s judgment of this specific action’s severity. So it adds a guard the permission mode can’t:
- In
automaticothe risk grade replaces the static dangerous-tool confirmation. - In
permisothe allowlist still applies and the risk gate composes on top. - In
totalit becomes a safety floor: everything runs free except aHIGH-graded action, which still stops for confirmation even under full trust. That’s the point — a catastrophic action gets caught no matter how much you trust the agent.
Goal-completion judge
Section titled “Goal-completion judge”Opt-in verification loop (OpenHands critic pattern) for completion-contract turns (coding
surfaces): after the agent declares done, an LLM judge scores the probability that the original
request is fully satisfied. Below success_threshold the agent receives an internal verification
note (what looks unmet, per the judge) and continues — up to max_iterations rounds. An
unusable judge (engine down, unparseable reply) accepts the result rather than blocking it.
"super_agent": { "judge": { "enabled": true, "success_threshold": 0.6, "max_iterations": 2, "model": "" }}model empty → the judge runs on super_agent.model; set a cheap model to keep verification
overhead low. Verdicts surface as judge_verdict events and on the result as result.judge.
Stuck detection
Section titled “Stuck detection”The tool loop watches for two loop shapes: the same call returning the same result
action_repeat times, and the same call erroring error_repeat times in a row. On the first
detection the model gets an in-band nudge (“you appear stuck — change approach or explain the
blocker”); if it keeps looping, the turn is closed early with a model-authored wrap-up instead of
burning the rest of the iteration budget. On by default:
"super_agent": { "stuck_detection": { "enabled": true, "action_repeat": 4, "error_repeat": 3 }}Model fallback
Section titled “Model fallback”If the primary model is unavailable, APX walks a configurable ordered list of fallback providers. Set the order and enable the router:
apx model enableapx model order ollama openrouter groqapx model status # probe all providers; show which would be used nowSee Configuration for the full super_agent.model_fallback schema.
Content-based routing
Section titled “Content-based routing”On top of the static fallback chain, opt-in per-turn routing rules (inspired by OpenHands’
RouterLLM) inspect the actual message — images, prompt/context size, channel, keywords — and
prefer a different model for that turn. Rules are evaluated in order; the first full match wins.
The preferred model is still health-checked and falls back down the regular chain if unavailable,
and an explicit per-request model override always beats the rules.
"super_agent": { "routing": { "enabled": true, "rules": [ { "model": "anthropic:claude-sonnet-5", "when": { "has_image": true } }, { "model": "groq:llama-3.3-70b-versatile", "when": { "max_prompt_chars": 200, "channels": ["telegram"] } }, { "model": "anthropic:claude-opus-4-8", "when": { "keywords": ["refactor", "architecture"] } } ] }}when conditions (all must hold): has_image, min_prompt_chars / max_prompt_chars,
min_context_chars, channels (list), keywords (case-insensitive substring list). An empty
when matches every turn — useful as a final catch-all.
- Memory system — how the agent retrieves relevant context across channels.
- Routines — schedule the super-agent or a plain
exec_agenton a cron. - Configuration — full
super_agent.*andidentity.jsonreference.