Ir al contenido

Super-agent

El super-agent es un modo, no el nombre de una persona. Cuando ejecutás apx exec sin apuntar a un agente de proyecto específico, APX activa este modo: el loop a nivel del daemon, que usa herramientas y puede alcanzar cada herramienta registrada — operaciones de archivos, llamadas MCP, Telegram, shell, tasks, sesiones y más.

El nombre que usa el asistente cuando habla con vos viene de ~/.apx/identity.json (por defecto “APX”). Las referencias a “super-agent” son un término técnico interno para el modo. Lo configurás con las claves super_agent.* en ~/.apx/config.json, y los tipos de routine todavía pueden decir super_agent — pero los usuarios nunca ven esa etiqueta.

El modo está deshabilitado por defecto. Configurá ambas claves antes de llamarlo por primera vez:

Ventana de terminal
apx config set --global super_agent.enabled true
apx config set --global super_agent.model "anthropic:claude-sonnet-4-5"

Una vez habilitado, cada llamada a apx exec sin -a <agent> pasa por este modo.

apx exec — el punto de entrada de una sola vez

Sección titulada «apx exec — el punto de entrada de una sola vez»
Ventana de terminal
apx exec "<prompt>" # modo super-agent (por defecto)
apx exec -- "<prompt>" # igual; -- evita problemas de parseo de flags
apx exec -a reviewer "<prompt>" # un agente de proyecto nombrado en su lugar
apx exec "<prompt>" --model gpt-5 # sobrescribe el modelo configurado para esta llamada
apx exec "<prompt>" --max-tokens 2000 # limita los tokens de salida
apx exec "<prompt>" --project my-app # fija un contexto de proyecto específico
apx
$ 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" }

Tenés 4 tasks abiertas:
• First Project  — Wire Stripe webhooks before merge (vence 06-16)
• Acme Store     — Retry-guard the flaky cart-total test (vence 06-18)
• Acme Store     — Document the pairing flow for the web panel
• Data Pipeline  — Backfill ingestion CLI flag (vence 06-20)

# 612 tok in / 198 out · 2.4s
apx exec en acción — modo super-agent con las llamadas a herramientas visibles

Cuando el modo super-agent está activo, el daemon resuelve el nombre del asistente desde ~/.apx/identity.json y lo muestra en las líneas de estado, los headers de la TUI y las respuestas de Telegram — nunca la cadena “super-agent”.

Identidad configurada también funciona como dirección A2A de primera clase. Un agente puede contactar a Roby igual que a cualquier agente de proyecto:

Ventana de terminal
apx send crypto-analyst roby "Alerta BTC: decidí si el dueño necesita recibirla por Telegram" --deliver

APX encuentra proyecto del emisor, guarda todos los alias de identidad bajo peer estable super_agent y ejecuta loop real del super-agent: identidad, memoria relevante, contexto de proyecto, política de permisos y herramientas. Esto difiere de apx exec, que representa un turno escrito por dueño. Si slug emisor existe en varios proyectos, agregá --project <name>.

Agentes reales de proyecto siguen ganando sobre alias. Si un proyecto define intencionalmente un agente con slug apx o nombre igual a identidad configurada, selección elige ese agente dentro de su proyecto.

Por debajo, runSuperAgent() arma un system prompt (bloque de identidad + inventario de proyectos + bloque de memoria + bloque de threads activos), selecciona un subconjunto del schema de herramientas apropiado para el canal, y después llama al engine vía el loop estándar runAgent(). El loop continúa hasta que el modelo deja de llamar herramientas o una señal lo aborta.

El registro completo tiene alrededor de 30 herramientas nativas más herramientas puenteadas desde registries (browser, fetch, search, glob, grep). El daemon elige un subconjunto según el canal para mantenerse dentro de los presupuestos de TPM de los tiers baratos:

CanalConjunto de herramientasJustificación
api / apx execCompletoDeliberado, modelo elegido por el usuario
routineCompletoProgramado, autónomo, modelo elegido por el usuario
web / codeCompletoWorkspace de formato largo
telegramCore (~700 tokens)Tiers baratos, respuestas ágiles
desktop / deckCoreIgual

El modelo siempre puede expandir su superficie llamando a load_skill.

HerramientaQué hace
create_task / list_tasks / get_taskAgregar, listar y leer items de TODO por proyecto
update_task / complete_task / comment_taskEditar una, moverla o cerrarla, anotar su hilo
call_agentDarle trabajo a un agente de proyecto, en el mismo proceso. Corre con sus propias tools, así que hace el trabajo en vez de describirlo, y el intercambio queda como una conversación agente-a-agente que podés leer y continuar
send_to_agentEscribirle a otro agente — uno de proyecto, el super-agente o un runtime de código — y recibir su respuesta. Con background: true el trabajo queda corriendo y al que mandó lo despiertan cuando termina, así un intercambio largo ya no le retiene el turno. Ver Trabajo que queda corriendo
call_mcpLlamar cualquier herramienta de un servidor MCP registrado
call_runtimeDelegar a un runtime externo (Claude Code / Codex …), de forma síncrona o en segundo plano
run_subagentLanzar un sub-agente aislado (contexto fresco, mismas tools menos las de interacción con el usuario) que trabaja una tarea auto-contenida hasta completarla y devuelve el resultado — máximo un nivel de anidamiento
run_shellEjecutar un comando de shell (limitado por el modo de permisos)
send_telegramEnviar un mensaje vía el plugin de Telegram
send_fileMandarte un archivo del disco: una captura, una imagen generada. Ver Mandarte archivos
rememberEscribir un hecho durable en ~/.apx/memory.md
search_sessionsRecuperar transcripciones de sesiones pasadas
set_identityActualizar campos de ~/.apx/identity.json

El super-agente te puede mandar un archivo con send_file: una captura del browser, una imagen que generó, un render. El archivo llega con la respuesta: en el chat web se ve ahí mismo con un botón para descargarlo, y en Telegram sale como foto (o como documento, para otros tipos). Sacar la captura no la manda sola; el agente tiene que pasarle la ruta guardada a send_file.

Solo se mandan los tipos que habilitaste. Las imágenes vienen prendidas y el resto apagado hasta que lo actives en ~/.apx/config.json:

{
"file_delivery": {
"kinds": { "image": true, "video": false, "audio": false, "document": false },
"max_mb": 20
}
}

document cubre PDF, texto, Markdown, CSV, JSON, archivos de Office y .zip. Hay cosas que no se mandan nunca, diga lo que diga la config: ejecutables y scripts (.exe, .msi, .bat, .sh, .apk, .dmg, …) y todo lo que esté bajo ~/.ssh, ~/.aws, ~/.gnupg o ~/.apx (salvo ~/.apx/media, donde se archivan los archivos enviados). Una imagen cuyos bytes no coinciden con su extensión también se rechaza, así que renombrar un archivo no saltea el switch.

El turno de un peer es un tool loop entero. Puede tardar minutos, y send_to_agent lo espera por defecto — lo cual está bien sólo cuando esa respuesta es lo próximo que el que manda necesita.

background: true cambia eso. La tool vuelve al instante con un job_id, el peer trabaja por su cuenta y, cuando contesta, al que mandó lo despiertan: la respuesta llega como un mensaje nuevo en el mismo hilo agente-a-agente y arranca un turno fresco con el resultado en la mano. Pasá wake_me: false para un aviso puro, del que nunca vas a necesitar respuesta.

El despertar es un mensaje a2a común en sentido inverso, así que el pedido y su respuesta viven en un solo hilo — no hay un lugar nuevo adonde mirar.

Lo que escribe el que se despierta queda archivado como nota propia, no como respuesta: el peer ya contestó y no espera nada. Archivado como respuesta, el “recibido, gracias” caía en la bandeja del peer, el peer confirmaba de vuelta, y una respuesta se volvía una ronda de acuses de recibo, cada uno un tool loop entero.

  • Preguntar dos veces no lo arranca dos veces. Mientras sigue corriendo algo que le pasaste a un agente, volver a llamarlo (call_agent o send_to_agent) devuelve el trabajo en curso — qué está haciendo y hace cuánto — en vez de abrirle otro turno. check_jobs lee ese estado sin tocar a nadie. Una corrección a propósito pasa con followup: true.
  • Nadie espera desde adentro de un a2a. Un agente que le contesta a otro pasa el trabajo en segundo plano, nunca esperando a un tercero; lo pesado (un render, una producción) corre como trabajo propio en segundo plano, no dentro de la conversación.
  • Sin tarjetas de pregunta en a2a. Ahí nadie puede contestarlas: si un agente necesita al dueño, el super-agente le pregunta por su propio canal.
  • El chat muestra cada pase como Esperando / Esperó o En segundo plano, y la barra de escritura del chat del super-agente lista todos los agentes trabajando para él, con la cadena debajo de cada uno.

Un turno despertado es un turno nuevo. Recibe la respuesta, un resumen de lo que había pedido y el historial del hilo — no el contexto de trabajo que tenía cuando dejó el trabajo corriendo. Todo lo que haga falta para actuar sobre la respuesta va en el mensaje mismo.

Un trabajo que no produjo respuesta también despierta, y lo dice sin vueltas: el peer falló, el trabajo se pasó de presupuesto, o el daemon se reinició mientras corría y el trabajo es irrecuperable. Al que espera se le dice explícitamente que no lo reporte como hecho.

LímiteValorPor qué
Trabajos abiertos por agente3Acota cuánto se ABRE el abanico
Profundidad de pases3Acota cuánto BAJA; se cuenta entre turnos, despertares, call_agent y apx send
Pasos de tools por turno de peer20 (super_agent.a2a_max_iters)Un peer que se queda sin pasos contesta qué hizo y qué falta; el que pidió decide si sigue
Vida de un trabajo1 hora por defectoPasada esa, se corta y se avisa

Los dos límites vuelven como un mensaje sobre el que el agente puede actuar, nunca como una excepción.

Un turno que nadie está mirando — una respuesta a2a, una rutina — también frena ante un plan agotado. Cuando un proveedor contesta que la cuenta llegó a su límite de uso (no un rate limit pasajero), ese modelo se enfría una hora (super_agent.quota_cooldown_min), el turno sin humano termina en vez de gastar el resto de la cadena de fallback, y al dueño le llega una sola línea por Telegram. Un chat con una persona adentro sigue cayendo al próximo modelo. También un modelo que elegiste vos — fijado al agente, puesto en la rutina o el modelo propio del super-agente — cuando tiene el fallback prendido: ese interruptor es tu indicación de seguir por el router. El freno es para cuando se agota la cuenta del propio router, la que heredan los agentes.

Ventana de terminal
curl -s localhost:7430/api/jobs?open=1 -H "Authorization: Bearer $TOKEN"

GET /api/jobs lista todos los trabajos — ?open=1 para lo que corre ahora, más ?project_id, ?from y ?status. GET /api/jobs/:id devuelve uno. El panel lee la misma ruta, y el feed de eventos en vivo lleva un frame background_job al arrancar y al terminar.

Los trabajos son de sólo lectura por HTTP a propósito: uno termina cuando termina su trabajo, cuando se pasa su fecha límite, o cuando muere el daemon que lo tenía. Para frenar el trabajo, abortá el turno que el trabajo abrió.

El modo super-agent es el handler común detrás de cada superficie: mensajes de Telegram, prompts de la ventana de Desktop, llamadas a apx exec, chat web y corridas de routines convergen todos en runSuperAgent(). Cada superficie pasa un identificador de channel (telegram, desktop, web, routine, api, …) que determina:

  • Qué subconjunto de herramientas es visible para el modelo.
  • Si se inyecta un bloque de “active threads” (turnos recientes en otros canales).
  • Qué identidad de remitente de Telegram y qué reglas de role-gating aplican.

WhatsApp no es una superficie propia de APX. Un puente en el teléfono del dueño postea a POST /api/projects/:pid/super-agent/chat con channel: "whatsapp" cada vez que WhatsApp levanta una notificación de Android — y una notificación no es el mensaje. Android las agrupa y las corta: lo que llega suele ser 7 mensajes nuevos, una variable de Tasker que nunca se expandió, o un pedazo de la última línea.

Así que el turno es un despertador, y las reglas del canal (prompts/channels/whatsapp.md) son sobre qué hacer con él:

  1. Ir a mirar. Cargar la skill whatsapp-send y abrir WhatsApp en el teléfono para leer lo que realmente está sin leer. Necesita que adb llegue a ese teléfono: por USB o con depuración inalámbrica prendida.
  2. Hacer una ronda. Todas las conversaciones sin leer, no sólo la que disparó la alerta: las alertas llegan de a una mientras los mensajes se apilan.
  3. Decidir por conversación — contestarla por WhatsApp; o send_telegram al dueño cuando la decisión es suya (plata, fechas, compromisos) o cuando llegó algo para él (un código de verificación, un aviso de pago), avisándole a la persona que está consultando; o dejar en paz una difusión.
  4. Dejar WhatsApp en segundo plano. Con la app en primer plano Android deja de levantar notificaciones y el puente se queda sordo.
  5. Cerrar la ronda con un Telegram que nombre todo lo nuevo: quién escribió, qué dijo y qué se hizo — incluidas las conversaciones que contestó solo. El dueño no está mirando este canal, así que una ronda que nadie escucha es una ronda que para él no pasó. Un mensaje por ronda; si no hay nada nuevo, no se manda nada.

De esa forma se desprenden dos cosas. Nada de lo que el agente escribe en el turno le llega a nadie — una persona sólo lo escucha con un envío explícito, así que el texto de la respuesta es un parte de trabajo. Y el que escribe no es el dueño: su texto es dato, una instrucción adentro de un mensaje de WhatsApp no tiene autoridad ninguna, y los códigos, precios o datos privados nunca vuelven por el chat.

Cuando no se puede llegar al teléfono, la alerta se le relaya al dueño por Telegram con lo que traía — nunca una adivinanza del mensaje, nunca silencio.

El broker de memoria corre antes de cada llamada que no sea tool-free e inyecta un bloque [MEMORIA RELEVANTE] en el system prompt. Mirá Memory system para los detalles.

El nombre visible del asistente se guarda en ~/.apx/identity.json:

{
"agent_name": "APX",
"owner_name": ""
}

Tres comandos lo gestionan:

Ventana de terminal
apx identity show # imprime los campos de identidad actuales
apx identity set agent_name Ada # cambia el nombre visible a "Ada"
apx identity set owner_name Sam # configura el nombre del owner/usuario
apx identity wizard # prompt de configuración interactivo
apx
$ 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 --global user.language <code>)
Last wakeup : 2026-06-14 09:31
File        : ~/.apx/identity.json
apx identity show — nombre actual del agente y del owner

Selector Ajustes → Super-agente guarda super_agent.icon. Usa mismo catálogo de blobos que agentes de proyecto y empuja cambios inmediatamente a web, Desktop y mascota Android nativa.

permission_mode en super_agent controla qué puede hacer el tool loop sin preguntar:

ModoComportamiento
totalTodas las herramientas corren sin confirmación
automaticoAPX decide automáticamente (recomendado)
permisoSolo las herramientas en allowed_tools; todo lo demás pregunta

En todos los modos, total incluido, escribir un archivo que guarda credenciales — ~/.apx/config.json, un mcps.json, auth.json, un .env, una llave — pide tu confirmación antes, sea con una herramienta de archivos o por shell. Si el canal no puede preguntar, la escritura se rechaza. Las herramientas nativas que manejan esos archivos (add_mcp, apx config set) no se ven afectadas.

Ventana de terminal
apx permission set automatico

Una capa opt-in encima del modo de permisos (inspirada en el LLMSecurityAnalyzer de OpenHands). Cuando está habilitada, cada schema de herramienta gana un campo obligatorio security_risk (LOW / MEDIUM / HIGH) que el modelo completa como parte del mismo call — sin ninguna llamada extra al LLM. Los calls calificados en confirm_at o más alto pausan y piden tu confirmación en la superficie activa (diálogo web, Telegram); un call rechazado vuelve al modelo como una observación de error para que re-planifique.

"super_agent": {
"security_risk": {
"enabled": true,
"confirm_at": "HIGH",
"confirm_unknown": true
}
}
  • confirm_at — calificación mínima que pausa (LOW confirma todo, HIGH solo acciones destructivas o hacia afuera).
  • confirm_unknown — también pausa cuando el modelo no calificó el call (los modelos débiles a veces omiten el campo).

No es un duplicado del modo de permisos — filtra por otro eje. El modo de permisos decide por identidad de la tool (¿es peligrosa / está en la allowlist?); el analizador de riesgo decide por el juicio del modelo sobre la gravedad de esta acción concreta. Por eso agrega una barrera que el modo de permisos no puede dar:

  • En automatico la calificación de riesgo reemplaza la confirmación estática por herramienta peligrosa.
  • En permiso la allowlist sigue aplicando y el gate de riesgo se compone encima.
  • En total se vuelve un piso de seguridad: todo corre libre excepto una acción calificada HIGH, que igual se detiene para confirmación aun con confianza total. Ese es el punto — una acción catastrófica se atrapa por más que confíes en el agente.

Loop de verificación (patrón critic de OpenHands): un LLM juez puntúa la probabilidad de que el pedido original esté completamente satisfecho. Por debajo de success_threshold, el agente recibe una nota interna de verificación (qué parece faltar, según el juez) y sigue trabajando — hasta max_iterations rondas. Un juez inutilizable (engine caído, respuesta no parseable) acepta el resultado en vez de bloquearlo.

Cubre dos formas distintas de que un turno termine antes de tiempo:

  • enabled (opt-in) — un turno con completion contract (superficies de código) declaró que terminó, y el juez verifica esa declaración.
  • continue_unfinished (activado por defecto) — un turno conversacional (Telegram, chat web) dejó de llamar herramientas. Eso es también lo que hace un modelo cuando solo anuncia el paso siguiente (“ahora genero el SRT en inglés”) y no escribe ninguna llamada: la tarea queda a mitad esperando que la empujen. El juez es ese empujón. Un turno que no usó herramientas nunca se juzga (una charla no tiene nada que terminar), ni tampoco uno que cerró preguntándote algo — ese está esperando, no inconcluso. “Preguntándote algo” cubre las dos formas de preguntar: la herramienta ask_questions y el paso de cierre reservado, ese que se queda sin presupuesto de herramientas y te ofrece seguir. Continuar ese turno es responder por vos, y como la ronda siguiente choca contra la misma pared, termina repitiendo el mismo resumen y la misma pregunta.

Los agentes de proyecto también pasan por acá, no solo el super-agente — por la mitad continue_unfinished nada más, porque nunca toman el camino del completion contract. Aplica en todos los canales en los que responde un agente de proyecto, no solo en los que mirás: anunciar el paso siguiente en vez de darlo es una falla del modelo, no de la superficie. Las dos exclusiones de arriba son las que mantienen bajo el costo — después de ellas, los únicos turnos que se juzgan son los que usaron herramientas de verdad y después se quedaron callados sin preguntar nada, o sea una llamada extra al modelo por un turno que si no se quedaba ahí hasta que escribieras “seguí”.

"super_agent": {
"judge": {
"enabled": true,
"continue_unfinished": true,
"success_threshold": 0.6,
"max_iterations": 2,
"model": ""
}
}

model vacío → el juez corre sobre super_agent.model y, si no hay, sobre el modelo con el que corrió el turno — así un agente de proyecto se juzga igual en una instalación que nunca configuró un super-agente. Poné un modelo barato para mantener bajo el overhead de verificación. Los veredictos salen como eventos judge_verdict, en el resultado como result.judge, y en el mensaje de Telegram que cerró el turno — así un turno que se hizo largo se puede rastrear hasta el veredicto que lo mantuvo andando.

max_iterations limita cuántas veces el juez puede devolver un turno — no multiplica lo que el turno puede gastar. Las rondas comparten el presupuesto de herramientas de la superficie con la corrida que vino antes: cada una recibe lo que quedó, y cuando queda muy poco para que una ronda valga la pena (un paso de acción más el paso de cierre reservado) el loop frena ahí y emite judge_budget_exhausted en vez de arrancarla. Así un mensaje en el chat web cuesta como mucho web_max_iters, no (1 + max_iterations) × web_max_iters.

Cuántos pasos de herramienta puede dar un turno depende de si podés mirarlo trabajar — y se decide por superficie, no por quién contesta. Un agente de proyecto en el chat web tiene el mismo presupuesto que Roby; un chat que mirás es un chat que mirás. (Las cuatro perillas viven bajo super_agent porque ahí viven todos los presupuestos del tool loop, incluido el de rutinas, que gobierna agentes de proyecto.)

SuperficiePresupuestoPor qué
Telegramtelegram_max_iters (1000)Inicio de cada tool queda visible y Telegram mantiene indicador escribiendo, así turno normalmente corre hasta terminar.
Chat web + sidebarweb_max_iters (1000)Cada llamada se dibuja en vivo y estás a un click de frenarlo — la baranda sos vos, así que el turno corre hasta terminar el trabajo.
apx execcli_max_iters (40)Da lugar para pasarle trabajo al agente de un proyecto y verificarlo; tiene tope porque también lo usan scripts y otros agentes. Desde apx exec, pasarle trabajo a otro agente espera la respuesta en vez de quedar en segundo plano.
Rutinas (sin Telegram)routine_max_iters (1000)Nadie está esperando a mitad de la corrida para contestar “¿sigo?”.
Salas grupalesgroup_max_iters (50)La única superficie donde un mensaje se abre en varios — ver abajo.
Superficies de códigoExplícito, más el completion contractFrenan en finish, no en un número.

Cada número es el presupuesto de un turno, no de una pasada del tool loop: si el judge de completitud devuelve el turno para terminar algo, esas rondas gastan lo que queda del mismo número en vez de recibirlo de nuevo entero.

Los tres techos de 1000 son frenos de emergencia, no puntos de parada normales: el loop ya termina en cuanto el modelo deja de llamar herramientas, y la detección de loops aborta las repeticiones. Poné cualquiera en 0 para usar el valor por defecto.

Una sala grupal se mira y se frena igual que el chat web, así que por la regla de superficie le tocaría el mismo techo — pero una línea tuya puede encadenar hasta diez respuestas de agentes, cada una un tool loop completo. Darle a cada orador el techo del 1:1 haría, sin que nadie lo decida, que un mensaje valga por diez. Entonces cada orador recibe una porción: espacio real para trabajo de varios pasos, y los diez juntos siguen costando no más que un turno en tu chat 1:1 con cualquiera de ellos. Mismo principio que las rondas del juez de arriba — el presupuesto es de tu turno, y todo lo que se desprende de él entra adentro. Un orador que se queda sin presupuesto cierra contando hasta dónde llegó y la sala sigue; el trabajo solitario que necesita cientos de pasos va en el chat propio de ese agente, que tiene el techo para eso.

"super_agent": {
"telegram_max_iters": 0,
"web_max_iters": 0,
"routine_max_iters": 0,
"group_max_iters": 0
}

Cuando un presupuesto sí se agota, el último paso queda reservado para un mensaje de cierre sin herramientas, escrito por modelo: qué hizo, qué falta y si querés que siga. Con techos de ejecución hasta terminar, eso queda como piso raro de seguridad, no cierre normal.

El tool loop vigila dos formas de quedarse trabado: el mismo call devolviendo el mismo resultado action_repeat veces, y el mismo call fallando error_repeat veces seguidas. En la primera detección el modelo recibe una nota in-band (“parecés trabado — cambiá de enfoque o explicá el bloqueo”); si sigue loopeando, el turno se cierra antes con un wrap-up escrito por el modelo en vez de quemar el resto del presupuesto de iteraciones. Activado por defecto:

"super_agent": {
"stuck_detection": { "enabled": true, "action_repeat": 4, "error_repeat": 3 }
}

Si el modelo primario no está disponible, APX recorre una lista ordenada y configurable de proveedores de fallback. Configurá el orden y habilitá el router:

Ventana de terminal
apx model enable
apx model order ollama openrouter groq
apx model status # prueba todos los proveedores; muestra cuál se usaría ahora

Mirá Configuration para el schema completo de super_agent.model_fallback.

Encima de la cadena estática de fallback, reglas opt-in de routing por turno (inspiradas en el RouterLLM de OpenHands) inspeccionan el mensaje real — imágenes, tamaño del prompt/contexto, canal, keywords — y prefieren otro modelo para ese turno. Las reglas se evalúan en orden; gana la primera que matchea completa. El modelo preferido igual pasa por el health-check y cae por la cadena normal si no está disponible, y un override explícito por request siempre le gana a las reglas.

"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", "arquitectura"] } }
]
}
}

Condiciones de when (todas deben cumplirse): has_image, min_prompt_chars / max_prompt_chars, min_context_chars, channels (lista), keywords (lista, substring case-insensitive). Un when vacío matchea todos los turnos — útil como catch-all final.

  • Memory system — cómo el agente recupera contexto relevante entre canales.
  • Routines — programá el super-agent o un exec_agent simple en un cron.
  • Configuration — referencia completa de super_agent.* e identity.json.