Rutinas
Una rutina es una tarea APX programada. El daemon corre un tick del scheduler cada 5 segundos y dispara
cualquier rutina que esté vencida. Cada rutina tiene un kind, un schedule, un blob JSON spec opcional,
y arrays de hooks de shell opcionales (pre_commands / post_commands).
| Tipo | ¿LLM? | ¿Herramientas? | Descripción |
|---|---|---|---|
heartbeat | No | — | Registra un marcador. Útil como ping de “sigo vivo”. |
shell | No | — | Corre un comando de shell. Captura el stdout. |
exec_agent | Sí | Allowlist del agente | Carga un agente del proyecto, corre spec.prompt con las tools de su campo tools: (no el registro del superagente) y persiste una conversación. allowed_tools: [] deja el path de texto de una sola llamada. |
super_agent | Sí | Todas | Corre el agente APX por defecto con el registro completo de herramientas. Bucle multi-iteración. |
telegram | No | — | Envía un spec.text fijo vía el plugin de Telegram. |
Regla general para elegir:
- ¿El agente del proyecto tiene que hacer el trabajo (archivos, Asana, tools)? →
exec_agent. - ¿El agente APX por defecto, con el registro completo? →
super_agent. - ¿Texto de un modelo, sin llamadas a tools? →
exec_agentconallowed_tools: []. - ¿Shell puro sin LLM? →
shell. - ¿Mensaje fijo de Telegram en un horario? →
telegram.
Gramática de programación
Sección titulada «Gramática de programación»| Formato | Ejemplos | Notas |
|---|---|---|
every:<N><unit> | every:30s, every:5m, every:24h, every:7d | El más común. |
once:<iso-8601> | once:2026-12-01T08:00:00Z | Dispara una vez, después se deshabilita solo. |
| Expresión cron | */5 * * * *, 0 8 * * * | Cron estándar de 5 campos. |
apx routine add
Sección titulada «apx routine add»apx routine add <name> \ --kind <kind> \ --schedule <schedule> \ [--spec '<json>'] \ [--pre-commands 'cmd1,cmd2'] \ [--post-commands 'cmd'] \ [--skip-prompt-on signal|pre_failure|pre_success|always|never] \ [--permission-mode total|automatico|permiso] \ [--allowed-tools tool1,tool2] \ [--project <name|id|path>]Configuración JSON específica del tipo:
| Tipo | Claves de spec requeridas | Opcionales |
|---|---|---|
exec_agent | prompt | agent (slug, por defecto default) |
super_agent | prompt | — |
shell | cmd | — |
telegram | text | — |
heartbeat | (ninguna) | — |
--pre-commands y --post-commands
Sección titulada «--pre-commands y --post-commands»Comandos de shell separados por comas. Forman un pipeline alrededor de la llamada al LLM:
-
pre_commandscorren secuencialmente. Su stdout combinado queda disponible como:{{pre_output}}— sustituido enspec.prompt(y enspec.text) antes de la llamada al LLM. Siempre se sustituye: sinpre_commands, o sin salida, el hueco queda vacío en vez de llegarle al modelo como llaves literales.$APX_PRE_OUTPUT— variable de entorno parapost_commands.$APX_PRE_OUTPUT_FILE— ruta a un archivo temporal con la salida completa (para payloads grandes).
-
Corre el handler del tipo. Su resultado de texto se expone como
$APX_LLM_OUTPUT. -
post_commandscorren secuencialmente con$APX_LLM_OUTPUT,$APX_PRE_OUTPUT, y$APX_STATUSen el entorno.
--skip-prompt-on
Sección titulada «--skip-prompt-on»Controla cuándo se saltea la llamada al LLM (fase 2), según lo que hicieron los pre_commands:
| Valor | Comportamiento |
|---|---|
signal (por defecto) | Saltea el LLM cuando el stdout de los comandos pre contiene APX_SKIP. Los códigos de salida se ignoran. Es una señal de contenido, no una señal del sistema operativo — decide el comando pre. |
pre_failure | Saltea el LLM cuando el último comando pre sale distinto de cero. |
pre_success | Saltea el LLM cuando el último comando pre sale cero. Es el opuesto exacto de pre_failure — sirve cuando que el comando pre salga bien significa que no queda nada para pensar. |
always | Siempre saltea el LLM — útil para pipelines pre→post puros. |
never | Siempre corre el LLM, hagan lo que hagan los comandos pre. |
Los post_commands corren siempre, se haya salteado el LLM o no; $APX_SKIPPED vale 1 cuando se salteó.
Emitir la señal de skip desde un comando pre se ve así:
apx routine add digest \ --pre 'test -s ~/report.txt || echo APX_SKIP' \ --skip-prompt-on signal--permission-mode
Sección titulada «--permission-mode»Sobreescribe el super_agent.permission_mode global para esta rutina:
total | automatico | permiso.
Con qué modelo corre
Sección titulada «Con qué modelo corre»Una rutina corre con el modelo propio de su agente (exec_agent) o el del super-agente, y cae al
router. Para darle a un trabajo otro modelo, usá --model proveedor:modelo (spec.model, panel:
Modelo de la rutina). Si ese modelo falla, la corrida sigue con el modelo del agente y después
con el router — el modelo de la rutina es una elección para ese trabajo, nunca reemplaza al del agente.
Otros subcomandos
Sección titulada «Otros subcomandos»apx routine list [--project <name|id|path>]apx routine get <name> [--project <name|id|path>]apx routine history <name> [--project <name|id|path>]apx routine run <name> [--project <name|id|path>] # forzar disparo ahoraapx routine enable <name> [--project <name|id|path>]apx routine disable <name> [--project <name|id|path>]apx routine remove <name> [--project <name|id|path>]$ apx routine list --project myapp project #2 routines: NAME EN KIND SCHEDULE NEXT_RUN LAST morning-standup ✓ exec_agent every:1h 2026-06-14 10:00:00 ✓ 2026-06-14 09:00:02 daily-weather ✓ telegram once:08:00 2026-06-15 08:00:00 ✓ 2026-06-14 08:00:01 healthcheck ✓ heartbeat every:5m 2026-06-14 09:35:00 ✓ 2026-06-14 09:30:00 nightly-backup ✗ shell once:02:00 — ✗ 2026-06-13 02:00:04
Ejemplos
Sección titulada «Ejemplos»Texto plano + entrega por Telegram
Sección titulada «Texto plano + entrega por Telegram»apx routine add daily-weather \ --project myapp \ --kind exec_agent \ --schedule "every:24h" \ --spec '{"agent":"default","prompt":"El clima es {{pre_output}}. Una frase amigable, sin saludos."}' \ --pre-commands "curl -s 'https://wttr.in/London?format=%t+%C+viento+%w'" \ --post-commands 'apx telegram send "$APX_LLM_OUTPUT"'Super-agente con herramientas, horario de mañana
Sección titulada «Super-agente con herramientas, horario de mañana»apx routine add morning-standup \ --project myapp \ --kind super_agent \ --schedule "0 9 * * *" \ --spec '{"prompt":"List open tasks across projects and send me a short summary via Telegram."}' \ --permission-mode automaticoShell puro, sin LLM
Sección titulada «Shell puro, sin LLM»apx routine add db-backup \ --project myapp \ --kind shell \ --schedule "every:24h" \ --spec '{"cmd":"pg_dump mydb > /backups/mydb-$(date +%F).sql"}'Ejecución única a futuro
Sección titulada «Ejecución única a futuro»apx routine add deploy-prod \ --project myapp \ --kind super_agent \ --schedule "once:2026-07-01T10:00:00Z" \ --spec '{"prompt":"Run the production deploy checklist and report status."}'El gotcha de la doble respuesta
Sección titulada «El gotcha de la doble respuesta»# ✗ Frágil — depende de la heurística de supresión--kind super_agent \--spec '{"prompt":"El clima es {{pre_output}}. Mandalo por Telegram."}' \--post-commands 'apx telegram send "$APX_LLM_OUTPUT"'
# ✓ Limpio — el modelo escribe el texto, la shell lo entrega--kind exec_agent \--spec '{"prompt":"El clima es {{pre_output}}. Una frase amigable, sin saludos."}' \--post-commands 'apx telegram send "$APX_LLM_OUTPUT"'Debugging
Sección titulada «Debugging»apx routine history <name> --project myapp # últimas N ejecuciones con estado y salidaapx log -f # seguir el log unificado del daemonapx messages tail --channel routine -n 20 # últimos 20 mensajes del canal routineUna rutina que “no envía nada” lo más frecuente es que signifique: enabled: false, next_run_at está en el
futuro, o el LLM devolvió texto vacío. Revisá apx routine history primero — el campo result.text
muestra exactamente lo que produjo el modelo.
Mirar una corrida
Sección titulada «Mirar una corrida»La pantalla Rutinas del panel muestra la corrida que está pasando ahora, no sólo las que terminaron. Una rutina corriendo queda marcada desde el momento en que arranca, la lista de ejecuciones dibuja sus pasos a medida que el agente los da, y cada ejecución terminada linkea al chat donde quedó archivada. Ese estado vive en el daemon: sobrevive un refresh, se ve igual en todos los paneles abiertos, y muestra también las corridas que disparó el scheduler sin que nadie estuviera mirando. Un reinicio del daemon lo borra — la corrida se murió con el proceso.
Siguiente
Sección titulada «Siguiente»- Tareas — lista de TODO por proyecto que las rutinas pueden leer y escribir.
- Super-agente — el modo bajo el cual corren las rutinas
super_agent. - Configuración — fallback de modelo global y configuración de permisos.