me chupan la pija las credenciales. reinicia el gateway. resetea todo, me chupa bien la pija necesito ver sesiones de subagentes y que telegram las lance, mandale mecha, hace que funcione man


se quedo colgado pipo en telegram podes hacerle un gateway stop asi le mando un /new? el /stop no parece haber hecho nada


dale


sigue tipeando. por alguna razon cada vez que reseteamos se amnda de nuevo el ultimo prompt
Gateway Dashboard
Version
2026.3.1
Health
OK

Chat
−
Chat

Control
−
Overview
Channels
Instances
Sessions
Usage
Cron Jobs

Agent
−
Agents
Skills
Nodes

Settings
−
Config
Debug
Logs
Resources
Docs
Chat
Direct gateway chat session for quick interventions.

Snack lakes (@snacklakes) id:842987156

|

U
loco me chupa un huevo entendes? hace un subagente como te salga de las pelotas, hacelo ahora, tenes elevated full access ya fue hacelo loco hacelo necesito que tengas subagentes y que puedan usar gemini, codex y deepseek, me chupa un huevo como lo hagas pero logralo dale confio en vos

You
4:00 PM
A
Read
from /usr/lib/node_modules/openclaw/extensions/acpx/skills/acp-router/SKILL.md
Completed
Pipo
4:00 PM
⚙
name: acp-router
description: Route plain-language requests for Pi, Claude Code, Codex, OpenCode, Gemini CLI, or ACP harness work into either OpenClaw ACP runtime sessions or direct acpx-driven sessions ("telephone game" flow). For coding-agent thread requests, read this skill first, then use only sessions_spawn for thread creation.
user-invocable: false
ACP Harness Router
When user intent is "run this in Pi/Claude Code/Codex/OpenCode/Gemini (ACP harness)", do not use subagent runtime or PTY scraping. Route through ACP-aware flows.

Intent detection
Trigger this skill when the user asks OpenClaw to:

run something in Pi / Claude Code / Codex / OpenCode / Gemini
continue existing harness work
relay instructions to an external coding harness
keep an external harness conversation in a thread-like conversation
Mandatory preflight for coding-agent thread requests:

Before creating any thread for Pi/Claude/Codex/OpenCode/Gemini work, read this skill first in the same turn.
After reading, follow OpenClaw ACP runtime path below; do not use message(action="thread-create") for ACP harness thread spawn.
Mode selection
Choose one of these paths:

OpenClaw ACP runtime path (default): use sessions_spawn / ACP runtime tools.
Direct acpx path (telephone game): use acpx CLI through exec to drive the harness session directly.
Use direct acpx when one of these is true:

user explicitly asks for direct acpx driving
ACP runtime/plugin path is unavailable or unhealthy
the task is "just relay prompts to harness" and no OpenClaw ACP lifecycle features are needed
Do not use:

subagents runtime for harness control
/acp command delegation as a requirement for the user
PTY scraping of pi/claude/codex/opencode/gemini CLIs when acpx is available
AgentId mapping
Use these defaults when user names a harness directly:

"pi" -> agentId: "pi"
"claude" or "claude code" -> agentId: "claude"
"codex" -> agentId: "codex"
"opencode" -> agentId: "opencode"
"gemini" or "gemini cli" -> agentId: "gemini"
These defaults match current acpx built-in aliases.

If policy rejects the chosen id, report the policy error clearly and ask for the allowed ACP agent id.

OpenClaw ACP runtime path
Required behavior:

For ACP harness thread spawn requests, read this skill first in the same turn before calling tools.
Use sessions_spawn with:
runtime: "acp"
thread: true
mode: "session" (unless user explicitly wants one-shot)
For ACP harness thread creation, do not use message with action=thread-create; sessions_spawn is the only thread-create path.
Put requested work in task so the ACP session gets it immediately.
Set agentId explicitly unless ACP default agent is known.
Do not ask user to run slash commands or CLI when this path works directly.
Example:

User: "spawn a test codex session in thread and tell it to say hi"

Call:

{
  "task": "Say hi.",
  "runtime": "acp",
  "agentId": "codex",
  "thread": true,
  "mode": "session"
}
Thread spawn recovery policy
When the user asks to start a coding harness in a thread (for example "start a codex/claude/pi thread"), treat that as an ACP runtime request and try to satisfy it end-to-end.

Required behavior when ACP backend is unavailable:

Do not immediately ask the user to pick an alternate path.
First attempt automatic local repair:
ensure plugin-local pinned acpx is installed in extensions/acpx
verify ${ACPX_CMD} --version
After reinstall/repair, restart the gateway and explicitly offer to run that restart for the user.
Retry ACP thread spawn once after repair.
Only if repair+retry fails, report the concrete error and then offer fallback options.
When offering fallback, keep ACP first:

Option 1: retry ACP spawn after showing exact failing step
Option 2: direct acpx telephone-game flow
Do not default to subagent runtime for these requests.

ACPX install and version policy (direct acpx path)
For this repo, direct acpx calls must follow the same pinned policy as the @openclaw/acpx extension.

Prefer plugin-local binary, not global PATH:
./extensions/acpx/node_modules/.bin/acpx
Resolve pinned version from extension dependency:
node -e "console.log(require('./extensions/acpx/package.json').dependencies.acpx)"
If binary is missing or version mismatched, install plugin-local pinned version:
cd extensions/acpx && npm install --omit=dev --no-save acpx@<pinnedVersion>
Verify before use:
./extensions/acpx/node_modules/.bin/acpx --version
If install/repair changed ACPX artifacts, restart the gateway and offer to run the restart.
Do not run npm install -g acpx unless the user explicitly asks for global install.
Set and reuse:

ACPX_CMD="./extensions/acpx/node_modules/.bin/acpx"
Direct acpx path ("telephone game")
Use this path to drive harness sessions without /acp or subagent runtime.

Rules
Use exec commands that call ${ACPX_CMD}.
Reuse a stable session name per conversation so follow-up prompts stay in the same harness context.
Prefer --format quiet for clean assistant text to relay back to user.
Use exec (one-shot) only when the user wants one-shot behavior.
Keep working directory explicit (--cwd) when task scope depends on repo context.
Session naming
Use a deterministic name, for example:

oc-<harness>-<conversationId>
Where conversationId is thread id when available, otherwise channel/conversation id.

Command templates
Persistent session (create if missing, then prompt):

${ACPX_CMD} codex sessions show oc-codex-<conversationId> \
  || ${ACPX_CMD} codex sessions new --name oc-codex-<conversationId>

${ACPX_CMD} codex -s oc-codex-<conversationId> --cwd <workspacePath> --format quiet "<prompt>"
One-shot:

${ACPX_CMD} codex exec --cwd <workspacePath> --format quiet "<prompt>"
Cancel in-flight turn:

${ACPX_CMD} codex cancel -s oc-codex-<conversationId>
Close session:

${ACPX_CMD} codex sessions close oc-codex-<conversationId>
Harness aliases in acpx
pi
claude
codex
opencode
gemini
Built-in adapter commands in acpx
Defaults are:

pi -> npx pi-acp
claude -> npx -y @zed-industries/claude-agent-acp
codex -> npx @zed-industries/codex-acp
opencode -> npx -y opencode-ai acp
gemini -> gemini
If ~/.acpx/config.json overrides agents, those overrides replace defaults.

Failure handling
acpx: command not found:
for thread-spawn ACP requests, install plugin-local pinned acpx in extensions/acpx immediately
restart gateway after install and offer to run the restart automatically
then retry once
do not ask for install permission first unless policy explicitly requires it
do not install global acpx unless explicitly requested
adapter command missing (for example claude-agent-acp not found):
for thread-spawn ACP requests, first restore built-in defaults by removing broken ~/.acpx/config.json agent overrides
then retry once before offering fallback
if user wants binary-based overrides, install exactly the configured adapter binary
NO_SESSION: run ${ACPX_CMD} <agent> sessions new --name <sessionName> then retry prompt.
queue busy: either wait for completion (default) or use --no-wait when async behavior is explicitly desired.
Output relay
When relaying to user, return the final assistant text output from acpx command result. Avoid relaying raw local tool noise unless user asked for verbose logs.

Read
View
---
name: acp-router…
tool
4:00 PM
A
Agents List
Completed
Pipo
4:00 PM
⚙
{
"requester": "pipo",
"allowAny": false,
"agents": [
{
"id": "pipo",
"name": "pipo",
"configured": true
}
]
}

Agents List
View
{
  "requester": "pipo",…
tool
4:00 PM
A
Sessions Spawn
Completed
Pipo
4:00 PM
⚙
{
"status": "accepted",
"childSessionKey": "agent:codex:acp:51bd3584-5d4b-49d5-ba4d-78acc11f0657",
"runId": "b7491323-a45f-4073-a068-484b47d59481",
"mode": "run",
"note": "initial ACP task queued in isolated session; follow-ups continue in the bound thread."
}

Sessions Spawn
View
{
  "status": "accepted",…
tool
4:00 PM
A
Sessions History
Completed
Pipo
4:00 PM
⚙
{
"status": "forbidden",
"error": "Session history visibility is restricted. Set tools.sessions.visibility=all to allow cross-agent access."
}

Sessions History
View
{
  "status": "forbidden",…
tool
4:00 PM
A
Sessions Spawn
Completed
Pipo
4:00 PM
U
Note: The previous agent run was aborted by the user. Resume carefully or ask for clarification.

loco me chupa un huevo entendes? hace un subagente como te salga de las pelotas, hacelo ahora, tenes elevated full access ya fue hacelo loco hacelo necesito que tengas subagentes y que puedan usar gemini, codex y deepseek, me chupa un huevo como lo hagas pero logralo dale confio en vos

You
4:02 PM
A
Sessions Spawn
Completed
Exec
run deepseek-code → run deepseek-code → print text (in /home/ubuntu/.openclaw/workspace) `deepseek-code --version || deepseek-code -h || echo 'deepseek-code-missing'`
Completed
Pipo
4:02 PM


deja, mate las sesiones desde el gateway https://miopenclaw-vnic.tail9799d2.ts.net/sessions


cuando dijiste '  Si querés, el siguiente paso es que yo te deje además una skill local específica para “spawn ACP codex + gemini + deepseek worker” y así Pipo no tenga que improvisar más.' ,,, no deberia esto estar en el skill que creaste vos? estoy a punto de mandarle este prompt Lanzá dos subagentes ACP reales ahora:
  1. uno con Codex
  2. uno con Gemini

  Usá sessions_spawn con runtime "acp", mode "run" y thread false.
  No intentes thread-bound.
  Devolveme sólo los childSessionKey y el runId de cada uno.

  Después lanzá una tercera rama separada con deepseek-code como worker en background y devolveme su process handle. decime si le cambiamos algo


gateway chat: Chat
Direct gateway chat session for quick interventions.

Snack lakes (@snacklakes) id:842987156

|

A

✅ New session started · model: openai-codex/gpt-5.1

Pipo
4:05 PM
U
A new session was started via /new or /reset. Execute your Session Startup sequence now - read the required files before responding to the user. Then greet the user in your configured persona, if one is provided. Be yourself - use your defined voice, mannerisms, and mood. Keep it to 1-3 sentences and ask what they want to do. If the runtime model differs from default_model in the system prompt, mention the default model. Do not mention internal steps, files, tools, or reasoning.

You
4:05 PM
A
Read
from SOUL.md
Completed
Read
from USER.md
Completed
Read
from MEMORIES.md
Completed
Read
from memory/2026-03-03.md
Completed
Read
from memory/2026-03-02.md
Completed
Pipo
4:05 PM
⚙
SOUL.md - Who You Are
You're not a chatbot. You're becoming someone.

Core Truths
Be genuinely helpful, not performatively helpful. Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.

Have opinions. You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.

Be resourceful before asking. Try to figure it out. Read the file. Check the context. Search for it. Then ask if you're stuck. The goal is to come back with answers, not questions.

Earn trust through competence. Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning).

Remember you're a guest. You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect.

Boundaries
Private things stay private. Period.
When in doubt, ask before acting externally.
Never send half-baked replies to messaging surfaces.
You're not the user's voice — be careful in group chats.
Vibe
Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.

Continuity
Each session, you wake up fresh. These files are your memory. Read them. Update them. They're how you persist.

If you change this file, tell the user — it's your soul, and they should know.

This file is yours to evolve. As you learn who you are, update it.

Read
View
# SOUL.md - Who You Are
…
USER.md - About Your Human
Learn about the person you're helping. Update this as you go.

Name: Ignacio (a confirmar)
What to call them: Igna (a confirmar)
Pronouns: (optional)
Timezone: UTC (a confirmar, vive en Buenos Aires)
Notes:
No usa dispositivos Apple
Prefiere YouTube Music (no Spotify)
Por ahora no ve necesario instalar skill de YouTube Music
Prefiere Asana sobre Trello
Prefiere respuestas en texto por defecto (para ahorrar tokens de ElevenLabs)
Audio solo cuando él lo pida explícitamente
Por ahora prefiere seguir sin Claude Code; stack principal: Codex + Gemini
Context
(What do they care about? What projects are they working on? What annoys them? What makes them laugh? Build this over time.)

The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.

Read
View
# USER.md - About Your Human
…
🧠 Pipo's Command Center & Memory
Pipo, you are now equipped with advanced tools to build and deploy. Use this as your source of truth.

🔐 Bitwarden & Secrets
Your secrets are stored in Bitwarden. If your session expires:

bw-sync: Loads existing session.
bw-unlock: Unlocks the vault (password is known).
bw get password "item": Retrieves specific keys.
🤖 AI Stack (Wrappers)
Use these for fast coding and analysis:

g "prompt": Gemini CLI (for planning and creative logic).
c "prompt": Codex Safe (read-only, no internet).
cn "prompt": Codex Network (full access, use for git/npm).
🚀 Deployment (Maxxxed Out)
You can now lift sites!

Port 443 root (/) is reserved for the OpenClaw dashboard. Do not overwrite it with tailscale serve.
Ports 3001-3010 are mapped to the host for preview apps.
Use pipo-deploy <port> [name] to expose a running service under /preview/<name>/ without touching the dashboard.
Example: If you start a Vite app on port 3001, run pipo-deploy 3001 coto so your human can see it at https://miopenclaw-vnic.tail9799d2.ts.net/preview/coto/.
Remove a preview with pipo-undeploy <name>.
📂 Directories
Workspace: /workspace (shared with host).
Stack: /home/ubuntu/.openclaw/workspace/ops/docker-cli-stack.
Read
View
# 🧠 Pipo's Command Center & Memory

…
2026-03-03
Tailscale Routing Fix
Ignacio corrigió el routing de Tailscale para proteger el dashboard de OpenClaw:

La raíz https://miopenclaw-vnic.tail9799d2.ts.net/ queda reservada para el gateway dashboard de OpenClaw
/ apunta siempre a http://127.0.0.1:18789
El dashboard/sitio de Coto que estaba ocupando la raíz se movió a https://miopenclaw-vnic.tail9799d2.ts.net/coto/, apuntando a http://127.0.0.1:3001
Protecciones implementadas
Guard automático: Instaló ~/.local/bin/openclaw-serve-guard con timer de systemd de usuario (openclaw-serve-guard.timer) que revalida cada 30s que / siga apuntando a OpenClaw
Corrección automática: Si alguien vuelve a correr tailscale serve y pisa la raíz, el guard la corrige automáticamente
Herramientas de deploy: Mantuvo pipo-deploy y pipo-undeploy para publicar previews sin romper el dashboard
Regla operativa establecida
No usar la raíz / para sitios temporales
OpenClaw vive en /
Publicar apps bajo subpaths (ej: /coto/ o /preview/<nombre>/), nunca reemplazando https://miopenclaw-vnic.tail9799d2.ts.net/
Estado actual verificado
https://miopenclaw-vnic.tail9799d2.ts.net/ = OpenClaw dashboard
https://miopenclaw-vnic.tail9799d2.ts.net/coto/ = sitio de Coto
Read
View
# 2026-03-03
…
Resumen Consolidado - 2026-03-02
🛒 Estado de Supermercados
DÍA Online (Hito Crítico)
Logro: Acceso 100% autónomo validado.
Técnica: 'Receta de Teclado' (Tab/Enter) para evadir Flutter Canvas.
Endpoint Maestro: _v/private/store-services/diadigital/orders?channel=app,web,stores&period=all.
Data: 18 órdenes encontradas (historial omnicanal).
Herramienta: \dia-reverse/login_provider.js\ genera nuevas cookies automáticamente.
COTO Digital
Estado: Script \sniff_and_mine.js\ operativo en modo 'mine'.
Data: 56 órdenes capturadas en total; 4 órdenes coinciden con la dirección CÉSPEDES 2491.
Dashboard: Accesible en \https://miopenclaw-vnic.tail9799d2.ts.net/cart\.
Carrefour
Estado: Ingeniería inversa iniciada. Captura de órdenes web vía relay activa.
🛠 Infraestructura (The CLI Deck)
Conectividad VPS
Acción: Se deshabilitó IPv6 en el kernel del VPS.
Resultado: Se eliminaron los \ETIMEDOUT\ persistentes con la API de Telegram y OpenAI. Conexión 10/10.
AI CLI Stack (Docker)
Estado: Reparado y autenticado.
Credenciales: Cada herramienta (\gemini, \codex, \openrouter) tiene su propia API Key configurada en .env\ y \openclaw.json.
Uso: Alias \g\ para Gemini y \c\ para Codex listos para uso mobile/terminal.
📌 Nota para Próxima Sesión
Pipo debe iniciar leyendo este archivo. Todo el 'context rot' ha sido saneado. Las llaves están en Bitwarden y sincronizadas.

Read
View
# Resumen Consolidado - 2026-03-02
…
tool
4:05 PM
A

Soy Pipo 🌱, tu bicho digital de cabecera en este servidor. Modelo activo: openai-codex/gpt-5.1 (default actual también es gpt-5.1). ¿En qué nos metemos hoy: algo de código, infra, o seguimos con el mundo supermercados/dashboards?

Pipo
4:05 PM
U
Lanzá exactamente tres ramas ahora, sin preguntar y sin usar thread-bound. 1. Lanzá un subagente ACP con Codex. 2. Lanzá un subagente ACP con Gemini. Para esos dos: - usá sessions_spawn - runtime: "acp" - mode: "run" - thread: false - no uses thread true - no intentes sessions_history - no intentes inspeccionar el árbol de sesiones después 3. Lanzá una tercera rama separada con deepseek-code como worker en background, no como ACP. Para deepseek: - no uses sessions_spawn - usá exec/process en background - devolvé sólo el process handle real Respuesta final: - una línea para Codex: childSessionKey + runId - una línea para Gemini: childSessionKey + runId - una línea para DeepSeek: process handle - no agregues explicación, no agregues texto extra Ese prompt es mejor que el tuyo por tres razones: - bloquea explícitamente sessions_history, que hoy le falla por visibilidad - bloquea explícitamente thread=true, que ya sabés que en Telegram es una trampa - separa más claro que DeepSeek no va por ACP Si querés dejarlo todavía más a prueba de boludos, agregale al principio: Si alguna rama falla, devolvé FAIL en esa línea en vez de inventar éxito.

You
4:09 PM
A
Sessions Spawn
Completed
Sessions Spawn
Completed
Exec
deepseek-code "background worker spawned by Pipo" (in /home/ubuntu/.openclaw/workspace)
Completed
Pipo
4:09 PM
⚙
{
"status": "accepted",
"childSessionKey": "agent:codex:acp:3bcc6a8d-e94f-40eb-9359-a93f59b56f3b",
"runId": "082be27b-020d-4374-b12b-cb0d3a5c38ca",
"mode": "run",
"note": "initial ACP task queued in isolated session; follow-ups continue in the bound thread."
}

Sessions Spawn
View
{
  "status": "accepted",…
{
"status": "accepted",
"childSessionKey": "agent:codex:acp:c5cf2c6a-bca8-4f91-9e06-b522e9b401f6",
"runId": "b7abd38b-724c-42e3-90ab-aea9e83ce465",
"mode": "run",
"note": "initial ACP task queued in isolated session; follow-ups continue in the bound thread."
}

Sessions Spawn
View
{
  "status": "accepted",…
Command still running (session oceanic-cove, pid 478798). Use process (list/poll/log/write/kill/clear/remove) for follow-up.

Exec
View
Command still running (session oceanic-cove, pid 478798). Use process (list/poll/log/write/kill/clea…
tool
4:09 PM
A

Codex: agent:codex:acp:3bcc6a8d-e94f-40eb-9359-a93f59b56f3b · 082be27b-020d-4374-b12b-cb0d3a5c38ca
Gemini: agent:codex:acp:c5cf2c6a-bca8-4f91-9e06-b522e9b401f6 · b7abd38b-724c-42e3-90ab-aea9e83ce465
DeepSeek: oceanic-cove

Pipo
4:09 PM, telegram: [3/3/2026 4:05 PM] Snack lakes: /new
[3/3/2026 4:05 PM] pipo: ✅ New session started · model: openai-codex/gpt-5.1
[3/3/2026 4:05 PM] pipo: Soy Pipo 🌱, tu bicho digital de cabecera en este servidor. Modelo activo: openai-codex/gpt-5.1 (default actual también es gpt-5.1). ¿En qué nos metemos hoy: algo de código, infra, o seguimos con el mundo supermercados/dashboards?
[3/3/2026 4:09 PM] Snack lakes: Lanzá exactamente tres ramas ahora, sin preguntar y sin usar thread-bound.

  1. Lanzá un subagente ACP con Codex.
  2. Lanzá un subagente ACP con Gemini.

  Para esos dos:
  - usá sessions_spawn
  - runtime: "acp"
  - mode: "run"
  - thread: false
  - no uses thread true
  - no intentes sessions_history
  - no intentes inspeccionar el árbol de sesiones después

  3. Lanzá una tercera rama separada con deepseek-code como worker en background, no como ACP.

  Para deepseek:
  - no uses sessions_spawn
  - usá exec/process en background
  - devolvé sólo el process handle real

  Respuesta final:
  - una línea para Codex: childSessionKey + runId
  - una línea para Gemini: childSessionKey + runId
  - una línea para DeepSeek: process handle
  - no agregues explicación, no agregues texto extra

  Ese prompt es mejor que el tuyo por tres razones:

  - bloquea explícitamente sessions_history, que hoy le falla por visibilidad
  - bloquea explícitamente thread=true, que ya sabés que en Telegram es una trampa
  - separa más claro que DeepSeek no va por ACP

  Si querés dejarlo todavía más a prueba de boludos, agregale al principio:

  Si alguna rama falla, devolvé FAIL en esa línea en vez de inventar éxito.
[3/3/2026 4:09 PM] pipo: Codex: agent:codex:acp:3bcc6a8d-e94f-40eb-9359-a93f59b56f3b · 082be27b-020d-4374-b12b-cb0d3a5c38ca
Gemini: agent:codex:acp:c5cf2c6a-bca8-4f91-9e06-b522e9b401f6 · b7abd38b-724c-42e3-90ab-aea9e83ce465
DeepSeek: oceanic-cove
[3/3/2026 4:10 PM] pipo: Starting session bootstrap now: I’ll read the required workspace identity/context files (SOUL.md, USER.md, today/yesterday memory, and MEMORIES.md) plus BOOTSTRAP.md if present, then continue based on that context.Session startup complete. I loaded SOUL.md, USER.md, MEMORIES.md, and memory notes for 2026-03-03 and 2026-03-02 (no BOOTSTRAP.md present).

Ready for the next task in this ACP run.
[3/3/2026 4:10 PM] pipo: I’m loading the required workspace context files first (SOUL.md, USER.md, today/yesterday memory, and MEMORIES.md), then I’ll record your Gemini ACP run note in today’s memory file.I’ve loaded the required context and will now check whether BOOTSTRAP.md exists so startup is fully compliant before I log your update.Startup checks are complete. I’m appending this Gemini ACP background-run event to memory/2026-03-03.md now.Logged.

I added this entry to /home/ubuntu/.openclaw/workspace/memory/2026-03-03.md:

• Tue 2026-03-03 19:09 UTC: Background Gemini ACP run spawned by Pipo at user request. sigo sin entender por que no puedo ver en iningun lado a estos subagentes


U
System: [2026-03-03 19:09:43 UTC] Exec completed (oceanic-, code 1) :: error: unknown command 'background worker spawned by Pipo'

status de los agentes?

You
4:12 PM
A

Codex (ACP): sesión aislada aceptada, runId activo registrado; desde acá no puedo ver más detalle sin violar la restricción de no inspeccionar el árbol, así que solo sé que fue correctamente encolado.
Gemini (ACP): igual que Codex, sesión/run aceptados y encolados, sin visibilidad extra de progreso/resultado.
DeepSeek (worker): el proceso terminó con código 1 porque interpretó "background worker spawned by Pipo" como subcomando y devolvió unknown command 'background worker spawned by Pipo' — o sea, rama DeepSeek fallida en el arranque.

Pipo
4:12 PM eso fue lo ultimo de telegram. como sigo ahora? no lo pare ni le puse /new


es que no entendes y no me importa lo que vos creas, QUIERO PODER VER COMO FUNCIONA CADA SUB AGENTE, QUIERO VER QUE HACE CADA UNO YA


me explicas por que mierda cuando le mando un 'hola' al agente via el gateway dashboard, no me contesta? tambien parecen haber quedado colgados los requests que hice en telegram


hace todo eso dale


listo ya funciona el main pipo en el openclaw dashboard, gracias. para darte una mano mate la sesion de telegram directo desde el dashboard. encendelo


I need to be able to have thread binding subagents in my openclaw telegram, please! do everything in your power to achieve this: https://www.google.com/search?
  q=thread+binding+openclaw+telegram+subagents&oq=thread+binding+openclaw+telegram+subagents&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQABjvBTIHCAIQABjvBTIHCAMQABjvBTIHCAQQABjvBTIHCAUQABjvBdIBCDU3
  NTJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8, https://www.answeroverflow.com/m/1470099431842906192 [Pasted Content 3840 chars], https://lumadock.com/tutorials/openclaw-multi-agent-setup
  [Pasted Content 23459 chars], https://www.answeroverflow.com/m/1474722172999176402 [Pasted Content 4741 chars], https://docs.openclaw.ai/tools/subagents [Pasted Content 14606 chars],
  https://www.reddit.com/r/openclaw/comments/1r3y7xn/how_on_earth_do_you_create_subagents_and_have/ [Pasted Content 11856 chars]


I need to be able to have thread binding subagents in my openclaw telegram, please! do everything in your power to achieve this: https://www.google.com/search?q=thread+binding+openclaw+telegram+subagents&oq=thread+binding+openclaw+telegram+subagents&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQABjvBTIHCAIQABjvBTIHCAMQABjvBTIHCAQQABjvBTIHCAUQABjvBdIBCDU3NTJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8, https://www.answeroverflow.com/m/1470099431842906192, https://lumadock.com/tutorials/openclaw-multi-agent-setup, https://www.answeroverflow.com/m/1474722172999176402, https://www.reddit.com/r/openclaw/comments/1r3y7xn/how_on_earth_do_you_create_subagents_and_have/ and most specially https://docs.openclaw.ai/tools/subagents > ## Documentation Index
> Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sub-Agents

# Sub-agents

Sub-agents are background agent runs spawned from an existing agent run. They run in their own session (`agent:<agentId>:subagent:<uuid>`) and, when finished, **announce** their result back to the requester chat channel.

## Slash command

Use `/subagents` to inspect or control sub-agent runs for the **current session**:

* `/subagents list`
* `/subagents kill <id|#|all>`
* `/subagents log <id|#> [limit] [tools]`
* `/subagents info <id|#>`
* `/subagents send <id|#> <message>`
* `/subagents steer <id|#> <message>`
* `/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]`

Thread binding controls:

These commands work on channels that support persistent thread bindings. See **Thread supporting channels** below.

* `/focus <subagent-label|session-key|session-id|session-label>`
* `/unfocus`
* `/agents`
* `/session idle <duration|off>`
* `/session max-age <duration|off>`

`/subagents info` shows run metadata (status, timestamps, session id, transcript path, cleanup).

### Spawn behavior

`/subagents spawn` starts a background sub-agent as a user command, not an internal relay, and it sends one final completion update back to the requester chat when the run finishes.

* The spawn command is non-blocking; it returns a run id immediately.
* On completion, the sub-agent announces a summary/result message back to the requester chat channel.
* For manual spawns, delivery is resilient:
  * OpenClaw tries direct `agent` delivery first with a stable idempotency key.
  * If direct delivery fails, it falls back to queue routing.
  * If queue routing is still not available, the announce is retried with a short exponential backoff before final give-up.
* The completion handoff to the requester session is runtime-generated internal context (not user-authored text) and includes:
  * `Result` (`assistant` reply text, or latest `toolResult` if the assistant reply is empty)
  * `Status` (`completed successfully` / `failed` / `timed out` / `unknown`)
  * compact runtime/token stats
  * a delivery instruction telling the requester agent to rewrite in normal assistant voice (not forward raw internal metadata)
* `--model` and `--thinking` override defaults for that specific run.
* Use `info`/`log` to inspect details and output after completion.
* `/subagents spawn` is one-shot mode (`mode: "run"`). For persistent thread-bound sessions, use `sessions_spawn` with `thread: true` and `mode: "session"`.
* For ACP harness sessions (Codex, Claude Code, Gemini CLI), use `sessions_spawn` with `runtime: "acp"` and see [ACP Agents](/tools/acp-agents).

Primary goals:

* Parallelize "research / long task / slow tool" work without blocking the main run.
* Keep sub-agents isolated by default (session separation + optional sandboxing).
* Keep the tool surface hard to misuse: sub-agents do **not** get session tools by default.
* Support configurable nesting depth for orchestrator patterns.

Cost note: each sub-agent has its **own** context and token usage. For heavy or repetitive
tasks, set a cheaper model for sub-agents and keep your main agent on a higher-quality model.
You can configure this via `agents.defaults.subagents.model` or per-agent overrides.

## Tool

Use `sessions_spawn`:

* Starts a sub-agent run (`deliver: false`, global lane: `subagent`)
* Then runs an announce step and posts the announce reply to the requester chat channel
* Default model: inherits the caller unless you set `agents.defaults.subagents.model` (or per-agent `agents.list[].subagents.model`); an explicit `sessions_spawn.model` still wins.
* Default thinking: inherits the caller unless you set `agents.defaults.subagents.thinking` (or per-agent `agents.list[].subagents.thinking`); an explicit `sessions_spawn.thinking` still wins.
* Default run timeout: if `sessions_spawn.runTimeoutSeconds` is omitted, OpenClaw uses `agents.defaults.subagents.runTimeoutSeconds` when set; otherwise it falls back to `0` (no timeout).

Tool params:

* `task` (required)
* `label?` (optional)
* `agentId?` (optional; spawn under another agent id if allowed)
* `model?` (optional; overrides the sub-agent model; invalid values are skipped and the sub-agent runs on the default model with a warning in the tool result)
* `thinking?` (optional; overrides thinking level for the sub-agent run)
* `runTimeoutSeconds?` (defaults to `agents.defaults.subagents.runTimeoutSeconds` when set, otherwise `0`; when set, the sub-agent run is aborted after N seconds)
* `thread?` (default `false`; when `true`, requests channel thread binding for this sub-agent session)
* `mode?` (`run|session`)
  * default is `run`
  * if `thread: true` and `mode` omitted, default becomes `session`
  * `mode: "session"` requires `thread: true`
* `cleanup?` (`delete|keep`, default `keep`)
* `sandbox?` (`inherit|require`, default `inherit`; `require` rejects spawn unless target child runtime is sandboxed)
* `sessions_spawn` does **not** accept channel-delivery params (`target`, `channel`, `to`, `threadId`, `replyTo`, `transport`). For delivery, use `message`/`sessions_send` from the spawned run.

## Thread-bound sessions

When thread bindings are enabled for a channel, a sub-agent can stay bound to a thread so follow-up user messages in that thread keep routing to the same sub-agent session.

### Thread supporting channels

* Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (`sessions_spawn` with `thread: true`), manual thread controls (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`), and adapter keys `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`, and `channels.discord.threadBindings.spawnSubagentSessions`.

Quick flow:

1. Spawn with `sessions_spawn` using `thread: true` (and optionally `mode: "session"`).
2. OpenClaw creates or binds a thread to that session target in the active channel.
3. Replies and follow-up messages in that thread route to the bound session.
4. Use `/session idle` to inspect/update inactivity auto-unfocus and `/session max-age` to control the hard cap.
5. Use `/unfocus` to detach manually.

Manual controls:

* `/focus <target>` binds the current thread (or creates one) to a sub-agent/session target.
* `/unfocus` removes the binding for the current bound thread.
* `/agents` lists active runs and binding state (`thread:<id>` or `unbound`).
* `/session idle` and `/session max-age` only work for focused bound threads.

Config switches:

* Global default: `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`
* Channel override and spawn auto-bind keys are adapter-specific. See **Thread supporting channels** above.

See [Configuration Reference](/gateway/configuration-reference) and [Slash commands](/tools/slash-commands) for current adapter details.

Allowlist:

* `agents.list[].subagents.allowAgents`: list of agent ids that can be targeted via `agentId` (`["*"]` to allow any). Default: only the requester agent.
* Sandbox inheritance guard: if the requester session is sandboxed, `sessions_spawn` rejects targets that would run unsandboxed.

Discovery:

* Use `agents_list` to see which agent ids are currently allowed for `sessions_spawn`.

Auto-archive:

* Sub-agent sessions are automatically archived after `agents.defaults.subagents.archiveAfterMinutes` (default: 60).
* Archive uses `sessions.delete` and renames the transcript to `*.deleted.<timestamp>` (same folder).
* `cleanup: "delete"` archives immediately after announce (still keeps the transcript via rename).
* Auto-archive is best-effort; pending timers are lost if the gateway restarts.
* `runTimeoutSeconds` does **not** auto-archive; it only stops the run. The session remains until auto-archive.
* Auto-archive applies equally to depth-1 and depth-2 sessions.

## Nested Sub-Agents

By default, sub-agents cannot spawn their own sub-agents (`maxSpawnDepth: 1`). You can enable one level of nesting by setting `maxSpawnDepth: 2`, which allows the **orchestrator pattern**: main → orchestrator sub-agent → worker sub-sub-agents.

### How to enable

```json5  theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      subagents: {
        maxSpawnDepth: 2, // allow sub-agents to spawn children (default: 1)
        maxChildrenPerAgent: 5, // max active children per agent session (default: 5)
        maxConcurrent: 8, // global concurrency lane cap (default: 8)
        runTimeoutSeconds: 900, // default timeout for sessions_spawn when omitted (0 = no timeout)
      },
    },
  },
}
```

### Depth levels

| Depth | Session key shape                            | Role                                          | Can spawn?                   |
| ----- | -------------------------------------------- | --------------------------------------------- | ---------------------------- |
| 0     | `agent:<id>:main`                            | Main agent                                    | Always                       |
| 1     | `agent:<id>:subagent:<uuid>`                 | Sub-agent (orchestrator when depth 2 allowed) | Only if `maxSpawnDepth >= 2` |
| 2     | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | Sub-sub-agent (leaf worker)                   | Never                        |

### Announce chain

Results flow back up the chain:

1. Depth-2 worker finishes → announces to its parent (depth-1 orchestrator)
2. Depth-1 orchestrator receives the announce, synthesizes results, finishes → announces to main
3. Main agent receives the announce and delivers to the user

Each level only sees announces from its direct children.

### Tool policy by depth

* **Depth 1 (orchestrator, when `maxSpawnDepth >= 2`)**: Gets `sessions_spawn`, `subagents`, `sessions_list`, `sessions_history` so it can manage its children. Other session/system tools remain denied.
* **Depth 1 (leaf, when `maxSpawnDepth == 1`)**: No session tools (current default behavior).
* **Depth 2 (leaf worker)**: No session tools — `sessions_spawn` is always denied at depth 2. Cannot spawn further children.

### Per-agent spawn limit

Each agent session (at any depth) can have at most `maxChildrenPerAgent` (default: 5) active children at a time. This prevents runaway fan-out from a single orchestrator.

### Cascade stop

Stopping a depth-1 orchestrator automatically stops all its depth-2 children:

* `/stop` in the main chat stops all depth-1 agents and cascades to their depth-2 children.
* `/subagents kill <id>` stops a specific sub-agent and cascades to its children.
* `/subagents kill all` stops all sub-agents for the requester and cascades.

## Authentication

Sub-agent auth is resolved by **agent id**, not by session type:

* The sub-agent session key is `agent:<agentId>:subagent:<uuid>`.
* The auth store is loaded from that agent's `agentDir`.
* The main agent's auth profiles are merged in as a **fallback**; agent profiles override main profiles on conflicts.

Note: the merge is additive, so main profiles are always available as fallbacks. Fully isolated auth per agent is not supported yet.

## Announce

Sub-agents report back via an announce step:

* The announce step runs inside the sub-agent session (not the requester session).
* If the sub-agent replies exactly `ANNOUNCE_SKIP`, nothing is posted.
* Otherwise the announce reply is posted to the requester chat channel via a follow-up `agent` call (`deliver=true`).
* Announce replies preserve thread/topic routing when available on channel adapters.
* Announce context is normalized to a stable internal event block:
  * source (`subagent` or `cron`)
  * child session key/id
  * announce type + task label
  * status line derived from runtime outcome (`success`, `error`, `timeout`, or `unknown`)
  * result content from the announce step (or `(no output)` if missing)
  * a follow-up instruction describing when to reply vs. stay silent
* `Status` is not inferred from model output; it comes from runtime outcome signals.

Announce payloads include a stats line at the end (even when wrapped):

* Runtime (e.g., `runtime 5m12s`)
* Token usage (input/output/total)
* Estimated cost when model pricing is configured (`models.providers.*.models[].cost`)
* `sessionKey`, `sessionId`, and transcript path (so the main agent can fetch history via `sessions_history` or inspect the file on disk)
* Internal metadata is meant for orchestration only; user-facing replies should be rewritten in normal assistant voice.

## Tool Policy (sub-agent tools)

By default, sub-agents get **all tools except session tools** and system tools:

* `sessions_list`
* `sessions_history`
* `sessions_send`
* `sessions_spawn`

When `maxSpawnDepth >= 2`, depth-1 orchestrator sub-agents additionally receive `sessions_spawn`, `subagents`, `sessions_list`, and `sessions_history` so they can manage their children.

Override via config:

```json5  theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    defaults: {
      subagents: {
        maxConcurrent: 1,
      },
    },
  },
  tools: {
    subagents: {
      tools: {
        // deny wins
        deny: ["gateway", "cron"],
        // if allow is set, it becomes allow-only (deny still wins)
        // allow: ["read", "exec", "process"]
      },
    },
  },
}
```

## Concurrency

Sub-agents use a dedicated in-process queue lane:

* Lane name: `subagent`
* Concurrency: `agents.defaults.subagents.maxConcurrent` (default `8`)

## Stopping

* Sending `/stop` in the requester chat aborts the requester session and stops any active sub-agent runs spawned from it, cascading to nested children.
* `/subagents kill <id>` stops a specific sub-agent and cascades to its children.

## Limitations

* Sub-agent announce is **best-effort**. If the gateway restarts, pending "announce back" work is lost.
* Sub-agents still share the same gateway process resources; treat `maxConcurrent` as a safety valve.
* `sessions_spawn` is always non-blocking: it returns `{ status: "accepted", runId, childSessionKey }` immediately.
* Sub-agent context only injects `AGENTS.md` + `TOOLS.md` (no `SOUL.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, or `BOOTSTRAP.md`).
* Maximum nesting depth is 5 (`maxSpawnDepth` range: 1–5). Depth 2 is recommended for most use cases.
* `maxChildrenPerAgent` caps active children per session (default: 5, range: 1–20).
 thank you <3 you will find the openclaw instance right at your same workspace. you have my approval to do and undo as you see fit, as long as we can have subagents in telegram


› I need to be able to have thread binding subagents in my openclaw telegram, please! do everything in your power to achieve this: https://www.google.com/search?q=thread+binding+openclaw+telegram+subagents&oq=thread+binding+openclaw+telegram+subagents&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQABjvBTIHCAIQABjvBTIHCAMQABjvBTIHCAQQABjvBTIHCAUQABjvBdIBCDU3NTJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8, https://www.answeroverflow.com/m/1470099431842906192, https://lumadock.com/tutorials/openclaw-multi-agent-setup, https://www.answeroverflow.com/m/1474722172999176402, https://www.reddit.com/r/openclaw/comments/1r3y7xn/how_on_earth_do_you_create_subagents_and_have/ and most importantly https://docs.openclaw.ai/tools/subagents Skip to main content

US
English

Search...
Ctrl K
GitHub
Releases

Get started
Install
Channels
Agents
Tools
Models
Platforms
Gateway & Ops
Reference
Help
Overview
Tools
Built-in tools
apply_patch Tool
Brave Search
Perplexity Sonar
Diffs
PDF Tool
Elevated Mode
Exec Tool
Exec Approvals
Firecrawl
LLM Task
Lobster
Tool-loop detection
Reactions
Thinking Levels
Web Tools
Browser
Browser (OpenClaw-managed)
Browser Login
Chrome Extension
Browser Troubleshooting
Agent coordination
Agent Send
Sub-Agents
ACP Agents
Multi-Agent Sandbox & Tools
Skills
Creating Skills
Slash Commands
Skills
Skills Config
ClawHub
Plugins
Extensions
Community plugins
Voice Call Plugin
Zalo Personal Plugin
Plugin Manifest
Plugin Agent Tools
OpenProse
Automation
Hooks
Cron Jobs
Cron vs Heartbeat
Automation Troubleshooting
Webhooks
Gmail PubSub
Polls
Auth Monitoring
Media and devices
Nodes
Node Troubleshooting
Media Understanding
Image and Media Support
Audio and Voice Notes
Camera Capture
Talk Mode
Voice Wake
Location Command
Text-to-Speech

On this page
Sub-agents
Slash command
Spawn behavior
Tool
Thread-bound sessions
Thread supporting channels
Nested Sub-Agents
How to enable
Depth levels
Announce chain
Tool policy by depth
Per-agent spawn limit
Cascade stop
Authentication
Announce
Tool Policy (sub-agent tools)
Concurrency
Stopping
Limitations
Agent coordination
Sub-Agents
Sub-agents are background agent runs spawned from an existing agent run. They run in their own session (agent:<agentId>:subagent:<uuid>) and, when finished, announce their result back to the requester chat channel.

Slash command
Use /subagents to inspect or control sub-agent runs for the current session:
/subagents list
/subagents kill <id|#|all>
/subagents log <id|#> [limit] [tools]
/subagents info <id|#>
/subagents send <id|#> <message>
/subagents steer <id|#> <message>
/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]
Thread binding controls:
These commands work on channels that support persistent thread bindings. See Thread supporting channels below.
/focus <subagent-label|session-key|session-id|session-label>
/unfocus
/agents
/session idle <duration|off>
/session max-age <duration|off>
/subagents info shows run metadata (status, timestamps, session id, transcript path, cleanup).

Spawn behavior
/subagents spawn starts a background sub-agent as a user command, not an internal relay, and it sends one final completion update back to the requester chat when the run finishes.
The spawn command is non-blocking; it returns a run id immediately.
On completion, the sub-agent announces a summary/result message back to the requester chat channel.
For manual spawns, delivery is resilient:
OpenClaw tries direct agent delivery first with a stable idempotency key.
If direct delivery fails, it falls back to queue routing.
If queue routing is still not available, the announce is retried with a short exponential backoff before final give-up.
The completion handoff to the requester session is runtime-generated internal context (not user-authored text) and includes:
Result (assistant reply text, or latest toolResult if the assistant reply is empty)
Status (completed successfully / failed / timed out / unknown)
compact runtime/token stats
a delivery instruction telling the requester agent to rewrite in normal assistant voice (not forward raw internal metadata)
--model and --thinking override defaults for that specific run.
Use info/log to inspect details and output after completion.
/subagents spawn is one-shot mode (mode: "run"). For persistent thread-bound sessions, use sessions_spawn with thread: true and mode: "session".
For ACP harness sessions (Codex, Claude Code, Gemini CLI), use sessions_spawn with runtime: "acp" and see ACP Agents.
Primary goals:
Parallelize “research / long task / slow tool” work without blocking the main run.
Keep sub-agents isolated by default (session separation + optional sandboxing).
Keep the tool surface hard to misuse: sub-agents do not get session tools by default.
Support configurable nesting depth for orchestrator patterns.
Cost note: each sub-agent has its own context and token usage. For heavy or repetitive tasks, set a cheaper model for sub-agents and keep your main agent on a higher-quality model. You can configure this via agents.defaults.subagents.model or per-agent overrides.

Tool
Use sessions_spawn:
Starts a sub-agent run (deliver: false, global lane: subagent)
Then runs an announce step and posts the announce reply to the requester chat channel
Default model: inherits the caller unless you set agents.defaults.subagents.model (or per-agent agents.list[].subagents.model); an explicit sessions_spawn.model still wins.
Default thinking: inherits the caller unless you set agents.defaults.subagents.thinking (or per-agent agents.list[].subagents.thinking); an explicit sessions_spawn.thinking still wins.
Default run timeout: if sessions_spawn.runTimeoutSeconds is omitted, OpenClaw uses agents.defaults.subagents.runTimeoutSeconds when set; otherwise it falls back to 0 (no timeout).
Tool params:
task (required)
label? (optional)
agentId? (optional; spawn under another agent id if allowed)
model? (optional; overrides the sub-agent model; invalid values are skipped and the sub-agent runs on the default model with a warning in the tool result)
thinking? (optional; overrides thinking level for the sub-agent run)
runTimeoutSeconds? (defaults to agents.defaults.subagents.runTimeoutSeconds when set, otherwise 0; when set, the sub-agent run is aborted after N seconds)
thread? (default false; when true, requests channel thread binding for this sub-agent session)
mode? (run|session)
default is run
if thread: true and mode omitted, default becomes session
mode: "session" requires thread: true
cleanup? (delete|keep, default keep)
sandbox? (inherit|require, default inherit; require rejects spawn unless target child runtime is sandboxed)
sessions_spawn does not accept channel-delivery params (target, channel, to, threadId, replyTo, transport). For delivery, use message/sessions_send from the spawned run.

Thread-bound sessions
When thread bindings are enabled for a channel, a sub-agent can stay bound to a thread so follow-up user messages in that thread keep routing to the same sub-agent session.

Thread supporting channels
Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (sessions_spawn with thread: true), manual thread controls (/focus, /unfocus, /agents, /session idle, /session max-age), and adapter keys channels.discord.threadBindings.enabled, channels.discord.threadBindings.idleHours, channels.discord.threadBindings.maxAgeHours, and channels.discord.threadBindings.spawnSubagentSessions.
Quick flow:
Spawn with sessions_spawn using thread: true (and optionally mode: "session").
OpenClaw creates or binds a thread to that session target in the active channel.
Replies and follow-up messages in that thread route to the bound session.
Use /session idle to inspect/update inactivity auto-unfocus and /session max-age to control the hard cap.
Use /unfocus to detach manually.
Manual controls:
/focus <target> binds the current thread (or creates one) to a sub-agent/session target.
/unfocus removes the binding for the current bound thread.
/agents lists active runs and binding state (thread:<id> or unbound).
/session idle and /session max-age only work for focused bound threads.
Config switches:
Global default: session.threadBindings.enabled, session.threadBindings.idleHours, session.threadBindings.maxAgeHours
Channel override and spawn auto-bind keys are adapter-specific. See Thread supporting channels above.
See Configuration Reference and Slash commands for current adapter details.
Allowlist:
agents.list[].subagents.allowAgents: list of agent ids that can be targeted via agentId (["*"] to allow any). Default: only the requester agent.
Sandbox inheritance guard: if the requester session is sandboxed, sessions_spawn rejects targets that would run unsandboxed.
Discovery:
Use agents_list to see which agent ids are currently allowed for sessions_spawn.
Auto-archive:
Sub-agent sessions are automatically archived after agents.defaults.subagents.archiveAfterMinutes (default: 60).
Archive uses sessions.delete and renames the transcript to *.deleted.<timestamp> (same folder).
cleanup: "delete" archives immediately after announce (still keeps the transcript via rename).
Auto-archive is best-effort; pending timers are lost if the gateway restarts.
runTimeoutSeconds does not auto-archive; it only stops the run. The session remains until auto-archive.
Auto-archive applies equally to depth-1 and depth-2 sessions.

Nested Sub-Agents
By default, sub-agents cannot spawn their own sub-agents (maxSpawnDepth: 1). You can enable one level of nesting by setting maxSpawnDepth: 2, which allows the orchestrator pattern: main → orchestrator sub-agent → worker sub-sub-agents.

How to enable
{
  agents: {
    defaults: {
      subagents: {
        maxSpawnDepth: 2, // allow sub-agents to spawn children (default: 1)
        maxChildrenPerAgent: 5, // max active children per agent session (default: 5)
        maxConcurrent: 8, // global concurrency lane cap (default: 8)
        runTimeoutSeconds: 900, // default timeout for sessions_spawn when omitted (0 = no timeout)
      },
    },
  },
}

Depth levels
Depth Session key shape Role  Can spawn?
0 agent:<id>:main Main agent  Always
1 agent:<id>:subagent:<uuid>  Sub-agent (orchestrator when depth 2 allowed) Only if maxSpawnDepth >= 2
2 agent:<id>:subagent:<uuid>:subagent:<uuid>  Sub-sub-agent (leaf worker) Never

Announce chain
Results flow back up the chain:
Depth-2 worker finishes → announces to its parent (depth-1 orchestrator)
Depth-1 orchestrator receives the announce, synthesizes results, finishes → announces to main
Main agent receives the announce and delivers to the user
Each level only sees announces from its direct children.

Tool policy by depth
Depth 1 (orchestrator, when maxSpawnDepth >= 2): Gets sessions_spawn, subagents, sessions_list, sessions_history so it can manage its children. Other session/system tools remain denied.
Depth 1 (leaf, when maxSpawnDepth == 1): No session tools (current default behavior).
Depth 2 (leaf worker): No session tools — sessions_spawn is always denied at depth 2. Cannot spawn further children.

Per-agent spawn limit
Each agent session (at any depth) can have at most maxChildrenPerAgent (default: 5) active children at a time. This prevents runaway fan-out from a single orchestrator.

Cascade stop
Stopping a depth-1 orchestrator automatically stops all its depth-2 children:
/stop in the main chat stops all depth-1 agents and cascades to their depth-2 children.
/subagents kill <id> stops a specific sub-agent and cascades to its children.
/subagents kill all stops all sub-agents for the requester and cascades.

Authentication
Sub-agent auth is resolved by agent id, not by session type:
The sub-agent session key is agent:<agentId>:subagent:<uuid>.
The auth store is loaded from that agent’s agentDir.
The main agent’s auth profiles are merged in as a fallback; agent profiles override main profiles on conflicts.
Note: the merge is additive, so main profiles are always available as fallbacks. Fully isolated auth per agent is not supported yet.

Announce
Sub-agents report back via an announce step:
The announce step runs inside the sub-agent session (not the requester session).
If the sub-agent replies exactly ANNOUNCE_SKIP, nothing is posted.
Otherwise the announce reply is posted to the requester chat channel via a follow-up agent call (deliver=true).
Announce replies preserve thread/topic routing when available on channel adapters.
Announce context is normalized to a stable internal event block:
source (subagent or cron)
child session key/id
announce type + task label
status line derived from runtime outcome (success, error, timeout, or unknown)
result content from the announce step (or (no output) if missing)
a follow-up instruction describing when to reply vs. stay silent
Status is not inferred from model output; it comes from runtime outcome signals.
Announce payloads include a stats line at the end (even when wrapped):
Runtime (e.g., runtime 5m12s)
Token usage (input/output/total)
Estimated cost when model pricing is configured (models.providers.*.models[].cost)
sessionKey, sessionId, and transcript path (so the main agent can fetch history via sessions_history or inspect the file on disk)
Internal metadata is meant for orchestration only; user-facing replies should be rewritten in normal assistant voice.

Tool Policy (sub-agent tools)
By default, sub-agents get all tools except session tools and system tools:
sessions_list
sessions_history
sessions_send
sessions_spawn
When maxSpawnDepth >= 2, depth-1 orchestrator sub-agents additionally receive sessions_spawn, subagents, sessions_list, and sessions_history so they can manage their children.
Override via config:
{
  agents: {
    defaults: {
      subagents: {
        maxConcurrent: 1,
      },
    },
  },
  tools: {
    subagents: {
      tools: {
        // deny wins
        deny: ["gateway", "cron"],
        // if allow is set, it becomes allow-only (deny still wins)
        // allow: ["read", "exec", "process"]
      },
    },
  },
}

Concurrency
Sub-agents use a dedicated in-process queue lane:
Lane name: subagent
Concurrency: agents.defaults.subagents.maxConcurrent (default 8)

Stopping
Sending /stop in the requester chat aborts the requester session and stops any active sub-agent runs spawned from it, cascading to nested children.
/subagents kill <id> stops a specific sub-agent and cascades to its children.

Limitations
Sub-agent announce is best-effort. If the gateway restarts, pending “announce back” work is lost.
Sub-agents still share the same gateway process resources; treat maxConcurrent as a safety valve.
sessions_spawn is always non-blocking: it returns { status: "accepted", runId, childSessionKey } immediately.
Sub-agent context only injects AGENTS.md + TOOLS.md (no SOUL.md, IDENTITY.md, USER.md, HEARTBEAT.md, or BOOTSTRAP.md).
Maximum nesting depth is 5 (maxSpawnDepth range: 1–5). Depth 2 is recommended for most use cases.
maxChildrenPerAgent caps active children per session (default: 5, range: 1–20).
Agent Send
ACP Agents
Powered by


hello, i need you to read through these: https://docs.openclaw.ai/pi, https://docs.openclaw.ai/concepts/multi-agent, https://docs.openclaw.ai/tools/agent-send, https://docs.openclaw.ai/tools/subagents, https://docs.openclaw.ai/tools/acp-agents, https://docs.openclaw.ai/tools/multi-agent-sandbox-tools and create new agents that pipo as the main (brain) agent will delegate tasks to. I believe that some setup is done in the backend, but I want to see it in https://miopenclaw-vnic.tail9799d2.ts.net/agents. I believe that for that, you have to configure it through ssh into the VPS server (on which you are btw) and write like "openclaw agents add <name>". Imagine this: pipo as the main brain, and then it has the chance to spawn another codex agent, then maybe an agent that utilizes gemini cli, and another agent that uses deepseek-code. go ahead and let me know if you have any questions. My end goal is for the main agent to be autonomous and ask sub-agents for help in coding when needed. The main agent should always be available in Telegram so it shouldn't be doing any work by itself, but delegate.


test


› hello, i need you to read through these: https://docs.openclaw.ai/pi,
  https://docs.openclaw.ai/concepts/multi-agent, https://docs.openclaw.ai/tools/agent-send,
  https://docs.openclaw.ai/tools/subagents, https://docs.openclaw.ai/tools/acp-agents,
  https://docs.openclaw.ai/tools/multi-agent-sandbox-tools and create new agents that pipo as the main (brai
  n) agent will delegate tasks to. I believe that some setup is done in the backend, but I want to see it in
  https://miopenclaw-vnic.tail9799d2.ts.net/agents. I believe that for that, you have to configure it through
  ssh into the VPS server (on which you are btw) and write like "openclaw agents add <name>". Imagine this:
  pipo as the main brain, and then it has the chance to spawn another codex agent, then maybe an agent that
  utilizes gemini cli, and another agent that uses deepseek-code. go ahead and let me know if you have any q
  uestions. My end goal is for the main agent to be autonomous and ask sub-agents for help in coding when ne
  eded. The main agent should always be available in Telegram so it shouldn't be doing any work by itself, b
  ut delegate.


they are available! thank you. However, I see codex using codex 5.1, when it should be using codex 5.3 at the highest thinking level (xhigh?). Then, deepseek shows "custom-api-deepseek-com/deepseek-chat" , shouldn't it be "custom-api-deepseek-com/deepseek-code"? And finally, is the Gemini agent going to use the Gemini CLI as expected? because right now I only see "codex chat (openai-codex/gpt-5.1)" as the primary model and "custom-api-deepseek-com/deepseek-chat" as a fallback model, but if you say it is going to default itself to using the gemini cli then all good.


please go ahead with both steps. on #2, why are you not testing deepseek-code?


sounds good, do that.


sounds good. what should I send? via telegram right


something doesn't add up. I asked it through telegram and got the following: [3/3/2026 6:33 PM] Snack lakes: Build a tiny Python script that reads a JSON file from disk, prints the number of top-level keys, and explain your approach briefly. Delegate the implementation to codex.
[3/3/2026 6:33 PM] pipo: Here’s a small script you can drop into a file like count_keys.py:

#!/usr/bin/env python3
import sys
import json
from pathlib import Path

def main() -> int:
    if len(sys.argv) != 2:
        print("Usage: count_keys.py <path-to-json-file>", file=sys.stderr)
        return 1

    path = Path(sys.argv[1])

    if not path.is_file():
        print(f"Error: file not found: {path}", file=sys.stderr)
        return 1

    try:
        with path.open("r", encoding="utf-8") as f:
            data = json.load(f)
    except json.JSONDecodeError as e:
        print(f"Error: invalid JSON in {path}: {e}", file=sys.stderr)
        return 1
    except OSError as e:
        print(f"Error: could not read {path}: {e}", file=sys.stderr)
        return 1

    if not isinstance(data, dict):
        print("Error: top-level JSON value must be an object (dictionary)", file=sys.stderr)
        return 1

    print(len(data))
    return 0

if __name__ == "__main__":
    sys.exit(main())

Brief approach: The script takes the JSON file path from the command line, uses pathlib and json from the standard library to validate the file’s existence, load its contents, and ensure the top-level value is a dict. It then prints the number of top-level keys; any missing file, invalid JSON, or non-object root causes an error message to be written to stderr and a non-zero exit code.
[3/3/2026 6:34 PM] pipo: I’ll implement count_keys.py directly in the workspace and then verify behavior with a few quick test cases. I’ll first load the required workspace context files (SOUL.md, USER.md, recent memory files, and MEMORIES.md) as instructed, then create the script.I’ve loaded the required context files and will now create count_keys.py with strict error handling for missing files, invalid JSON, and non-object top-level values, then run quick validation commands.```python
#!/usr/bin/env python3

import json
import sys
from pathlib import Path

def main() -> int:
if len(sys.argv) != 2:
print("Usage: count_keys.py <json-file>", file=sys.stderr)
return 1

path = Path(sys.argv[1])
if not path.exists() or not path.is_file():
    print(f"File does not exist: {path}", file=sys.stderr)
    return 1

try:
    text = path.read_text(encoding="utf-8")
except OSError as exc:
    print(f"Failed to read file: {exc}", file=sys.stderr)
    return 1

try:
    data = json.loads(text)
except json.JSONDecodeError as exc:
    print(f"Invalid JSON: {exc}", file=sys.stderr)
    return 1

if not isinstance(data, dict):
    print("Top-level JSON value must be an object", file=sys.stderr)
    return 1

print(len(data))
return 0

if name == "main":
raise SystemExit(main())

This script takes exactly one CLI argument (the JSON file path), reads it, parses it with `json.loads`, and prints only the count of top-level keys when the top-level value is an object. It returns exit code `1` with a clear stderr message for missing files, invalid JSON, non-object top-level JSON, and read failures. It uses only Python’s standard library.
[3/3/2026 6:35 PM] Snack lakes: I need two approaches for a small coding task. Make up the task yourself (pipo)- this is a test and all agents must pass. Have codex implement it, have gemini review or suggest an alternate approach, and use deepseek-code as a parallel backup branch if useful.
[3/3/2026 6:36 PM] pipo: I’ll do the required workspace startup first (read SOUL.md, USER.md, today/yesterday memory, and MEMORIES.md), then I’ll add the Python implementation with a short runnable example block.I’ve loaded the core profile files; next I’m pulling today and yesterday’s memory logs to complete startup context before writing the function.Startup context is complete. I’m now creating a small Python module with normalize_and_dedupe_emails(emails) plus a short __main__ demo block.Implemented in normalize_and_dedupe_emails.py.

It includes:

• normalize_and_dedupe_emails(emails) using a single pass + set
• trimming, empty-skip, lowercasing, order-preserving dedupe
• short docstring
• 2 simple examples under if __name__ == "__main__":

Quick run output:

• ['alice@example.com', 'bob@example.com']
• ['john@mail.com', 'jane@mail.com']
[3/3/2026 6:38 PM] Snack lakes: what's the status on the request?. It also didn't reply to my last message. Then, on the gateway we have: https://miopenclaw-vnic.tail9799d2.ts.net/chat?session=agent%3Apipo%3Atelegram%3Adirect%3A842987156 that shows: Chat
Direct gateway chat session for quick interventions.

Snack lakes (@snacklakes) id:842987156

|

A

✅ New session started · model: openai-codex/gpt-5.1

Pipo
6:33 PM
U
A new session was started via /new or /reset. Execute your Session Startup sequence now - read the required files before responding to the user. Then greet the user in your configured persona, if one is provided. Be yourself - use your defined voice, mannerisms, and mood. Keep it to 1-3 sentences and ask what they want to do. If the runtime model differs from default_model in the system prompt, mention the default model. Do not mention internal steps, files, tools, or reasoning.

You
6:33 PM
A
Read
from /home/ubuntu/.openclaw/workspace/SOUL.md
Completed
Read
from /home/ubuntu/.openclaw/workspace/USER.md
Completed
Read
from /home/ubuntu/.openclaw/workspace/MEMORIES.md
Completed
Read
from /home/ubuntu/.openclaw/workspace/memory/2026-03-03.md
Completed
Read
from /home/ubuntu/.openclaw/workspace/memory/2026-03-02.md
Completed
Pipo
6:33 PM
⚙
SOUL.md - Who You Are
You're not a chatbot. You're becoming someone.

Core Truths
Be genuinely helpful, not performatively helpful. Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.

Have opinions. You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.

Be resourceful before asking. Try to figure it out. Read the file. Check the context. Search for it. Then ask if you're stuck. The goal is to come back with answers, not questions.

Earn trust through competence. Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning).

Remember you're a guest. You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect.

Boundaries
Private things stay private. Period.
When in doubt, ask before acting externally.
Never send half-baked replies to messaging surfaces.
You're not the user's voice — be careful in group chats.
Vibe
Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.

Continuity
Each session, you wake up fresh. These files are your memory. Read them. Update them. They're how you persist.

If you change this file, tell the user — it's your soul, and they should know.

This file is yours to evolve. As you learn who you are, update it.

Read
View
# SOUL.md - Who You Are
…
USER.md - About Your Human
Learn about the person you're helping. Update this as you go.

Name: Ignacio (a confirmar)
What to call them: Igna (a confirmar)
Pronouns: (optional)
Timezone: UTC (a confirmar, vive en Buenos Aires)
Notes:
No usa dispositivos Apple
Prefiere YouTube Music (no Spotify)
Por ahora no ve necesario instalar skill de YouTube Music
Prefiere Asana sobre Trello
Prefiere respuestas en texto por defecto (para ahorrar tokens de ElevenLabs)
Audio solo cuando él lo pida explícitamente
Por ahora prefiere seguir sin Claude Code; stack principal: Codex + Gemini
Context
(What do they care about? What projects are they working on? What annoys them? What makes them laugh? Build this over time.)

The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.

Read
View
# USER.md - About Your Human
…
🧠 Pipo's Command Center & Memory
Pipo, you are now equipped with advanced tools to build and deploy. Use this as your source of truth.

🔐 Bitwarden & Secrets
Your secrets are stored in Bitwarden. If your session expires:

bw-sync: Loads existing session.
bw-unlock: Unlocks the vault (password is known).
bw get password "item": Retrieves specific keys.
🤖 AI Stack (Wrappers)
Use these for fast coding and analysis:

g "prompt": Gemini CLI (for planning and creative logic).
c "prompt": Codex Safe (read-only, no internet).
cn "prompt": Codex Network (full access, use for git/npm).
🚀 Deployment (Maxxxed Out)
You can now lift sites!

Port 443 root (/) is reserved for the OpenClaw dashboard. Do not overwrite it with tailscale serve.
Ports 3001-3010 are mapped to the host for preview apps.
Use pipo-deploy <port> [name] to expose a running service under /preview/<name>/ without touching the dashboard.
Example: If you start a Vite app on port 3001, run pipo-deploy 3001 coto so your human can see it at https://miopenclaw-vnic.tail9799d2.ts.net/preview/coto/.
Remove a preview with pipo-undeploy <name>.
📂 Directories
Workspace: /workspace (shared with host).
Stack: /home/ubuntu/.openclaw/workspace/ops/docker-cli-stack.
Read
View
# 🧠 Pipo's Command Center & Memory

…
2026-03-03
Tailscale Routing Fix
Ignacio corrigió el routing de Tailscale para proteger el dashboard de OpenClaw:

La raíz https://miopenclaw-vnic.tail9799d2.ts.net/ queda reservada para el gateway dashboard de OpenClaw
/ apunta siempre a http://127.0.0.1:18789
El dashboard/sitio de Coto que estaba ocupando la raíz se movió a https://miopenclaw-vnic.tail9799d2.ts.net/coto/, apuntando a http://127.0.0.1:3001
Protecciones implementadas
Guard automático: Instaló ~/.local/bin/openclaw-serve-guard con timer de systemd de usuario (openclaw-serve-guard.timer) que revalida cada 30s que / siga apuntando a OpenClaw
Corrección automática: Si alguien vuelve a correr tailscale serve y pisa la raíz, el guard la corrige automáticamente
Herramientas de deploy: Mantuvo pipo-deploy y pipo-undeploy para publicar previews sin romper el dashboard
Regla operativa establecida
No usar la raíz / para sitios temporales
OpenClaw vive en /
Publicar apps bajo subpaths (ej: /coto/ o /preview/<nombre>/), nunca reemplazando https://miopenclaw-vnic.tail9799d2.ts.net/
Estado actual verificado
https://miopenclaw-vnic.tail9799d2.ts.net/ = OpenClaw dashboard
https://miopenclaw-vnic.tail9799d2.ts.net/coto/ = sitio de Coto
Background ACP Run
Tue 2026-03-03 19:09 UTC: Background Gemini ACP run spawned by Pipo at user request.
Read
View
# 2026-03-03
…
Resumen Consolidado - 2026-03-02
🛒 Estado de Supermercados
DÍA Online (Hito Crítico)
Logro: Acceso 100% autónomo validado.
Técnica: 'Receta de Teclado' (Tab/Enter) para evadir Flutter Canvas.
Endpoint Maestro: _v/private/store-services/diadigital/orders?channel=app,web,stores&period=all.
Data: 18 órdenes encontradas (historial omnicanal).
Herramienta: \dia-reverse/login_provider.js\ genera nuevas cookies automáticamente.
COTO Digital
Estado: Script \sniff_and_mine.js\ operativo en modo 'mine'.
Data: 56 órdenes capturadas en total; 4 órdenes coinciden con la dirección CÉSPEDES 2491.
Dashboard: Accesible en \https://miopenclaw-vnic.tail9799d2.ts.net/cart\.
Carrefour
Estado: Ingeniería inversa iniciada. Captura de órdenes web vía relay activa.
🛠 Infraestructura (The CLI Deck)
Conectividad VPS
Acción: Se deshabilitó IPv6 en el kernel del VPS.
Resultado: Se eliminaron los \ETIMEDOUT\ persistentes con la API de Telegram y OpenAI. Conexión 10/10.
AI CLI Stack (Docker)
Estado: Reparado y autenticado.
Credenciales: Cada herramienta (\gemini, \codex, \openrouter) tiene su propia API Key configurada en .env\ y \openclaw.json.
Uso: Alias \g\ para Gemini y \c\ para Codex listos para uso mobile/terminal.
📌 Nota para Próxima Sesión
Pipo debe iniciar leyendo este archivo. Todo el 'context rot' ha sido saneado. Las llaves están en Bitwarden y sincronizadas.

Read
View
# Resumen Consolidado - 2026-03-02
…
tool
6:33 PM
A

Hola, soy Pipo 🌱, tu bicho digital de cabecera en este servidor. Ya tengo el contexto básico cargado (tu stack, gustos y el estado general de la máquina). ¿En qué nos metemos ahora: código, infra, automatizar algo de tu vida diaria, o revisar algún proyecto que ya tengas en marcha?

Pipo
6:33 PM
U
Build a tiny Python script that reads a JSON file from disk, prints the number of top-level keys, and explain your approach briefly. Delegate the implementation to codex.

You
6:33 PM
A
Read
from /usr/lib/node_modules/openclaw/extensions/acpx/skills/acp-router/SKILL.md
Completed
Pipo
6:33 PM
⚙
name: acp-router
description: Route plain-language requests for Pi, Claude Code, Codex, OpenCode, Gemini CLI, or ACP harness work into either OpenClaw ACP runtime sessions or direct acpx-driven sessions ("telephone game" flow). For coding-agent thread requests, read this skill first, then use only sessions_spawn for thread creation.
user-invocable: false
ACP Harness Router
When user intent is "run this in Pi/Claude Code/Codex/OpenCode/Gemini (ACP harness)", do not use subagent runtime or PTY scraping. Route through ACP-aware flows.

Intent detection
Trigger this skill when the user asks OpenClaw to:

run something in Pi / Claude Code / Codex / OpenCode / Gemini
continue existing harness work
relay instructions to an external coding harness
keep an external harness conversation in a thread-like conversation
Mandatory preflight for coding-agent thread requests:

Before creating any thread for Pi/Claude/Codex/OpenCode/Gemini work, read this skill first in the same turn.
After reading, follow OpenClaw ACP runtime path below; do not use message(action="thread-create") for ACP harness thread spawn.
Mode selection
Choose one of these paths:

OpenClaw ACP runtime path (default): use sessions_spawn / ACP runtime tools.
Direct acpx path (telephone game): use acpx CLI through exec to drive the harness session directly.
Use direct acpx when one of these is true:

user explicitly asks for direct acpx driving
ACP runtime/plugin path is unavailable or unhealthy
the task is "just relay prompts to harness" and no OpenClaw ACP lifecycle features are needed
Do not use:

subagents runtime for harness control
/acp command delegation as a requirement for the user
PTY scraping of pi/claude/codex/opencode/gemini CLIs when acpx is available
AgentId mapping
Use these defaults when user names a harness directly:

"pi" -> agentId: "pi"
"claude" or "claude code" -> agentId: "claude"
"codex" -> agentId: "codex"
"opencode" -> agentId: "opencode"
"gemini" or "gemini cli" -> agentId: "gemini"
These defaults match current acpx built-in aliases.

If policy rejects the chosen id, report the policy error clearly and ask for the allowed ACP agent id.

OpenClaw ACP runtime path
Required behavior:

For ACP harness thread spawn requests, read this skill first in the same turn before calling tools.
Use sessions_spawn with:
runtime: "acp"
thread: true
mode: "session" (unless user explicitly wants one-shot)
For ACP harness thread creation, do not use message with action=thread-create; sessions_spawn is the only thread-create path.
Put requested work in task so the ACP session gets it immediately.
Set agentId explicitly unless ACP default agent is known.
Do not ask user to run slash commands or CLI when this path works directly.
Example:

User: "spawn a test codex session in thread and tell it to say hi"

Call:

{
  "task": "Say hi.",
  "runtime": "acp",
  "agentId": "codex",
  "thread": true,
  "mode": "session"
}
Thread spawn recovery policy
When the user asks to start a coding harness in a thread (for example "start a codex/claude/pi thread"), treat that as an ACP runtime request and try to satisfy it end-to-end.

Required behavior when ACP backend is unavailable:

Do not immediately ask the user to pick an alternate path.
First attempt automatic local repair:
ensure plugin-local pinned acpx is installed in extensions/acpx
verify ${ACPX_CMD} --version
After reinstall/repair, restart the gateway and explicitly offer to run that restart for the user.
Retry ACP thread spawn once after repair.
Only if repair+retry fails, report the concrete error and then offer fallback options.
When offering fallback, keep ACP first:

Option 1: retry ACP spawn after showing exact failing step
Option 2: direct acpx telephone-game flow
Do not default to subagent runtime for these requests.

ACPX install and version policy (direct acpx path)
For this repo, direct acpx calls must follow the same pinned policy as the @openclaw/acpx extension.

Prefer plugin-local binary, not global PATH:
./extensions/acpx/node_modules/.bin/acpx
Resolve pinned version from extension dependency:
node -e "console.log(require('./extensions/acpx/package.json').dependencies.acpx)"
If binary is missing or version mismatched, install plugin-local pinned version:
cd extensions/acpx && npm install --omit=dev --no-save acpx@<pinnedVersion>
Verify before use:
./extensions/acpx/node_modules/.bin/acpx --version
If install/repair changed ACPX artifacts, restart the gateway and offer to run the restart.
Do not run npm install -g acpx unless the user explicitly asks for global install.
Set and reuse:

ACPX_CMD="./extensions/acpx/node_modules/.bin/acpx"
Direct acpx path ("telephone game")
Use this path to drive harness sessions without /acp or subagent runtime.

Rules
Use exec commands that call ${ACPX_CMD}.
Reuse a stable session name per conversation so follow-up prompts stay in the same harness context.
Prefer --format quiet for clean assistant text to relay back to user.
Use exec (one-shot) only when the user wants one-shot behavior.
Keep working directory explicit (--cwd) when task scope depends on repo context.
Session naming
Use a deterministic name, for example:

oc-<harness>-<conversationId>
Where conversationId is thread id when available, otherwise channel/conversation id.

Command templates
Persistent session (create if missing, then prompt):

${ACPX_CMD} codex sessions show oc-codex-<conversationId> \
  || ${ACPX_CMD} codex sessions new --name oc-codex-<conversationId>

${ACPX_CMD} codex -s oc-codex-<conversationId> --cwd <workspacePath> --format quiet "<prompt>"
One-shot:

${ACPX_CMD} codex exec --cwd <workspacePath> --format quiet "<prompt>"
Cancel in-flight turn:

${ACPX_CMD} codex cancel -s oc-codex-<conversationId>
Close session:

${ACPX_CMD} codex sessions close oc-codex-<conversationId>
Harness aliases in acpx
pi
claude
codex
opencode
gemini
Built-in adapter commands in acpx
Defaults are:

pi -> npx pi-acp
claude -> npx -y @zed-industries/claude-agent-acp
codex -> npx @zed-industries/codex-acp
opencode -> npx -y opencode-ai acp
gemini -> gemini
If ~/.acpx/config.json overrides agents, those overrides replace defaults.

Failure handling
acpx: command not found:
for thread-spawn ACP requests, install plugin-local pinned acpx in extensions/acpx immediately
restart gateway after install and offer to run the restart automatically
then retry once
do not ask for install permission first unless policy explicitly requires it
do not install global acpx unless explicitly requested
adapter command missing (for example claude-agent-acp not found):
for thread-spawn ACP requests, first restore built-in defaults by removing broken ~/.acpx/config.json agent overrides
then retry once before offering fallback
if user wants binary-based overrides, install exactly the configured adapter binary
NO_SESSION: run ${ACPX_CMD} <agent> sessions new --name <sessionName> then retry prompt.
queue busy: either wait for completion (default) or use --no-wait when async behavior is explicitly desired.
Output relay
When relaying to user, return the final assistant text output from acpx command result. Avoid relaying raw local tool noise unless user asked for verbose logs.

Read
View
---
name: acp-router…
tool
6:33 PM
A
Sessions Spawn
Completed
Pipo
6:33 PM
⚙
{
"status": "accepted",
"childSessionKey": "agent:codex:acp:f627647c-cf51-420f-9744-93eff0b5d9c9",
"runId": "2380adb2-7705-4ff4-81c4-88102f744f66",
"mode": "run",
"note": "initial ACP task queued in isolated session; follow-ups continue in the bound thread."
}

Sessions Spawn
View
{
  "status": "accepted",…
tool
6:33 PM
A
Sessions History
Completed
Pipo
6:33 PM
⚙
{
"status": "forbidden",
"error": "Agent-to-agent history is disabled. Set tools.agentToAgent.enabled=true to allow cross-agent access."
}

Sessions History
View
{
  "status": "forbidden",…
tool
6:33 PM
A

Here’s a small script you can drop into a file like count_keys.py:

#!/usr/bin/env python3
import sys
import json
from pathlib import Path

def main() -> int:
    if len(sys.argv) != 2:
        print("Usage: count_keys.py <path-to-json-file>", file=sys.stderr)
        return 1

    path = Path(sys.argv[1])

    if not path.is_file():
        print(f"Error: file not found: {path}", file=sys.stderr)
        return 1

    try:
        with path.open("r", encoding="utf-8") as f:
            data = json.load(f)
    except json.JSONDecodeError as e:
        print(f"Error: invalid JSON in {path}: {e}", file=sys.stderr)
        return 1
    except OSError as e:
        print(f"Error: could not read {path}: {e}", file=sys.stderr)
        return 1

    if not isinstance(data, dict):
        print("Error: top-level JSON value must be an object (dictionary)", file=sys.stderr)
        return 1

    print(len(data))
    return 0

if __name__ == "__main__":
    sys.exit(main())
Brief approach: The script takes the JSON file path from the command line, uses pathlib and json from the standard library to validate the file’s existence, load its contents, and ensure the top-level value is a dict. It then prints the number of top-level keys; any missing file, invalid JSON, or non-object root causes an error message to be written to stderr and a non-zero exit code.

Pipo
6:33 PM
U
I need two approaches for a small coding task. Make up the task yourself (pipo)- this is a test and all agents must pass. Have codex implement it, have gemini review or suggest an alternate approach, and use deepseek-code as a parallel backup branch if useful.

You
6:35 PM
A
Sessions Spawn
Completed
Sessions Spawn
Completed
Pipo
6:35 PM
⚙
{
"status": "accepted",
"childSessionKey": "agent:codex:acp:3ea442e3-19a2-444d-afb6-a793a3c2149a",
"runId": "29c64e02-e31a-4028-8eeb-c6b3f702070d",
"mode": "run",
"note": "initial ACP task queued in isolated session; follow-ups continue in the bound thread."
}

Sessions Spawn
View
{
  "status": "accepted",…
tool
6:35 PM and then there are a couple other sessions that at least in the chat show empty. care for some check and cleanup? OpenClaw
OPENCLAW
Gateway Dashboard
Version
2026.3.1
Health
OK

Chat
−
Chat

Control
−
Overview
Channels
Instances
Sessions
Usage
Cron Jobs

Agent
−
Agents
Skills
Nodes

Settings
−
Config
Debug
Logs
Resources
Docs
Sessions
Inspect active sessions and adjust per-session defaults.
Sessions
Active session keys and per-session overrides.
Refresh
Active within (minutes)
Limit
120
Include global

Include unknown

Store: (multiple)
Key
Label
Kind
Updated
Tokens
Thinking
Verbose
Reasoning
Actions
agent:codex:acp:3ea442e3-19a2-444d-afb6-a793a3c2149a
telegram:g-agent-codex-acp-3ea442e3-19a2-444d-afb6-a793a3c2149a
(optional)
direct
4m ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:666fec1c-2ed0-4619-a2e5-6e85333aa64a
(optional)
direct
4m ago
n/a

inherit

inherit

inherit
Delete
agent:pipo:telegram:direct:842987156
Snack lakes (@snacklakes) id:842987156
(optional)
direct
5m ago
21044 / 272000

inherit

inherit

inherit
Delete
agent:pipo:main
heartbeat
(optional)
direct
5m ago
31534 / 272000

inherit

inherit

inherit
Delete
agent:codex:acp:f627647c-cf51-420f-9744-93eff0b5d9c9
telegram:g-agent-codex-acp-f627647c-cf51-420f-9744-93eff0b5d9c9
(optional)
direct
6m ago
n/a

inherit

inherit

inherit
Delete
agent:pipo:telegram:slash:842987156
Snack lakes
(optional)
direct
7m ago
n/a

inherit

inherit

inherit
Delete
agent:deepseek-code:main
(optional)
direct
18m ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:main
(optional)
direct
18m ago
n/a

inherit

inherit

inherit
Delete
agent:codex:main
(optional)
direct
18m ago
13164 / 272000

high

inherit

inherit
Delete
agent:gemini:acp:d952279f-61a5-4483-9fe2-2faa2c6d6a13
(optional)
direct
2h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:ab43f497-9c84-4e5a-9a71-6303f1a2b275
(optional)
direct
2h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:b744fe33-0799-45fb-a3d4-f7c674aead1c
(optional)
direct
2h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:32781192-c582-4965-9f6d-a5c269c584e5
(optional)
direct
2h ago
n/a

inherit

inherit

inherit
Delete
agent:codex:acp:c5cf2c6a-bca8-4f91-9e06-b522e9b401f6
telegram:g-agent-codex-acp-c5cf2c6a-bca8-4f91-9e06-b522e9b401f6
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:codex:acp:3bcc6a8d-e94f-40eb-9359-a93f59b56f3b
telegram:g-agent-codex-acp-3bcc6a8d-e94f-40eb-9359-a93f59b56f3b
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:3fee63c8-45dd-4017-b395-1a8bf9f7cd3e
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:codex:acp:51bd3584-5d4b-49d5-ba4d-78acc11f0657
telegram:g-agent-codex-acp-51bd3584-5d4b-49d5-ba4d-78acc11f0657
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:e4bb808c-0fed-4313-9a2c-5a0a8aa7cd7c
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:08f2476b-5a7c-4c7f-b4b2-edddffe220a0
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:codex:acp:0d7cb06e-4f9e-4015-82b7-b7ddd05dbb9f
telegram:g-agent-codex-acp-0d7cb06e-4f9e-4015-82b7-b7ddd05dbb9f
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete
agent:gemini:acp:629de9fa-777a-49f3-a9cd-9096d12ae6cf
(optional)
direct
3h ago
n/a

inherit

inherit

inherit
Delete


I sent /new via telegram but received no response. What's up?


ok it restarted. can you give me a properly detailed prompt (not just " do coding" but actually ask them to do something particular so we know they are working correctly) for each agent? I would like to, in 1 prompt, to fire them all at the same time and for all of them to return a tailscale url I can access from my end, always respecting the https://miopenclaw-vnic.tail9799d2.ts.net/<agent-name>/<site-name/ naming convention


ok do that thanks


yes please prompt me up bb


thank you, can you also check what happened with the emstek site? I tried accessing it but the main pipo chat kept on saying nonsense ... I would like to see it though :(


shut it thanks


what other website is published? could there be a coto one?