Herramientas de sesión

Objetivo: conjunto de herramientas pequeño y difícil de usar mal para que los agentes puedan listar sesiones, obtener historial y enviar mensajes a otra sesión.

Nombres de herramientas

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

Modelo de claves

  • El bucket principal de chat directo siempre es la clave literal "main" (resuelta a la clave principal del agente actual).
  • Los chats grupales usan agent:<agentId>:<channel>:group:<id> o agent:<agentId>:<channel>:channel:<id> (pasa la clave completa).
  • Los trabajos cron usan cron:<job.id>.
  • Los hooks usan hook:<uuid> a menos que se configure explícitamente.
  • Las sesiones de nodo usan node-<nodeId> a menos que se configure explícitamente.

global y unknown son valores reservados y nunca se listan. Si session.scope = "global", se sustituye por main para todas las herramientas para que los llamadores nunca vean global.

sessions_list

Lista las sesiones como un array de filas.

Parámetros:

  • kinds?: string[] filtro: cualquiera de "main" | "group" | "cron" | "hook" | "node" | "other"
  • limit?: number máximo de filas (por defecto: valor del servidor, tope p. ej. 200)
  • activeMinutes?: number solo sesiones actualizadas en los últimos N minutos
  • messageLimit?: number 0 = sin mensajes (por defecto 0); >0 = incluir últimos N mensajes

Comportamiento:

  • messageLimit > 0 obtiene chat.history por sesión e incluye los últimos N mensajes.
  • Los resultados de herramientas se filtran en la salida de la lista; usa sessions_history para mensajes de herramientas.
  • Al ejecutarse en una sesión de agente sandboxed, las herramientas de sesión tienen por defecto visibilidad solo de sesiones generadas (ver más abajo).

Forma de la fila (JSON):

  • key: clave de sesión (string)
  • kind: main | group | cron | hook | node | other
  • channel: whatsapp | telegram | discord | signal | imessage | webchat | internal | unknown
  • displayName (etiqueta de visualización del grupo si está disponible)
  • updatedAt (ms)
  • sessionId
  • model, contextTokens, totalTokens
  • thinkingLevel, verboseLevel, systemSent, abortedLastRun
  • sendPolicy (sobreescritura de sesión si está configurada)
  • lastChannel, lastTo
  • deliveryContext ({ channel, to, accountId } normalizado cuando está disponible)
  • transcriptPath (ruta derivada de mejor esfuerzo del directorio del store + sessionId)
  • messages? (solo cuando messageLimit > 0)

sessions_history

Obtiene la transcripción de una sesión.

Parámetros:

  • sessionKey (requerido; acepta clave de sesión o sessionId de sessions_list)
  • limit?: number máximo de mensajes (el servidor aplica un tope)
  • includeTools?: boolean (por defecto false)

Comportamiento:

  • includeTools=false filtra mensajes con role: "toolResult".
  • Devuelve el array de mensajes en el formato de transcripción crudo.
  • Cuando se proporciona un sessionId, OpenClaw lo resuelve a la clave de sesión correspondiente (los ids faltantes generan error).

sessions_send

Envía un mensaje a otra sesión.

Parámetros:

  • sessionKey (requerido; acepta clave de sesión o sessionId de sessions_list)
  • message (requerido)
  • timeoutSeconds?: number (por defecto >0; 0 = disparar y olvidar)

Comportamiento:

  • timeoutSeconds = 0: encolar y devolver { runId, status: "accepted" }.
  • timeoutSeconds > 0: esperar hasta N segundos a que se complete, luego devolver { runId, status: "ok", reply }.
  • Si la espera expira: { runId, status: "timeout", error }. La ejecución continúa; llama a sessions_history después.
  • Si la ejecución falla: { runId, status: "error", error }.
  • Las ejecuciones de entrega con anuncio se ejecutan después de que la ejecución principal se complete y son de mejor esfuerzo; status: "ok" no garantiza que el anuncio se haya entregado.
  • Espera mediante agent.wait del gateway (lado servidor) para que las reconexiones no pierdan la espera.
  • El contexto del mensaje entre agentes se inyecta para la ejecución principal.
  • Los mensajes entre sesiones se persisten con message.provenance.kind = "inter_session" para que los lectores de transcripciones puedan distinguir instrucciones enrutadas del agente de entradas de usuarios externos.
  • Después de que la ejecución principal se completa, OpenClaw ejecuta un bucle de respuesta:
    • Las rondas 2+ alternan entre los agentes solicitante y destino.
    • Responde exactamente REPLY_SKIP para detener el ping-pong.
    • El máximo de turnos es session.agentToAgent.maxPingPongTurns (0–5, por defecto 5).
  • Una vez que el bucle termina, OpenClaw ejecuta el paso de anuncio entre agentes (solo agente destino):
    • Responde exactamente ANNOUNCE_SKIP para mantenerse en silencio.
    • Cualquier otra respuesta se envía al canal destino.
    • El paso de anuncio incluye la solicitud original + respuesta de la ronda 1 + última respuesta del ping-pong.

Campo channel

  • Para grupos, channel es el canal registrado en la entrada de sesión.
  • Para chats directos, channel se mapea desde lastChannel.
  • Para cron/hook/node, channel es internal.
  • Si falta, channel es unknown.

Seguridad / Política de envío

Bloqueo basado en políticas por canal/tipo de chat (no por id de sesión).

{
  "session": {
    "sendPolicy": {
      "rules": [
        {
          "match": { "channel": "discord", "chatType": "group" },
          "action": "deny"
        }
      ],
      "default": "allow"
    }
  }
}

Sobreescritura en runtime (por entrada de sesión):

  • sendPolicy: "allow" | "deny" (sin configurar = heredar config)
  • Configurable mediante sessions.patch o /send on|off|inherit solo para el propietario (mensaje independiente).

Puntos de aplicación:

  • chat.send / agent (gateway)
  • lógica de entrega de auto-respuesta

sessions_spawn

Genera una ejecución de sub-agente en una sesión aislada y anuncia el resultado de vuelta al canal de chat del solicitante.

Parámetros:

  • task (requerido)
  • label? (opcional; se usa para logs/UI)
  • agentId? (opcional; generar bajo otro id de agente si está permitido)
  • model? (opcional; sobreescribe el modelo del sub-agente; valores inválidos generan error)
  • thinking? (opcional; sobreescribe el nivel de razonamiento para la ejecución del sub-agente)
  • runTimeoutSeconds? (por defecto es agents.defaults.subagents.runTimeoutSeconds cuando está configurado, de lo contrario 0; cuando está configurado, aborta la ejecución del sub-agente después de N segundos)
  • thread? (por defecto false; solicita enrutamiento vinculado a hilo para este spawn cuando lo soporta el canal/plugin)
  • mode? (run|session; por defecto run, pero cambia a session cuando thread=true; mode="session" requiere thread=true)
  • cleanup? (delete|keep, por defecto keep)
  • sandbox? (inherit|require, por defecto inherit; require rechaza el spawn a menos que el runtime hijo destino esté sandboxed)
  • attachments? (array opcional de archivos inline; solo runtime de subagente, ACP rechaza). Cada entrada: { name, content, encoding?: "utf8" | "base64", mimeType? }. Los archivos se materializan en el workspace hijo en .openclaw/attachments/<uuid>/. Devuelve un recibo con sha256 por archivo.
  • attachAs? (opcional; hint { mountPath? } reservado para futuras implementaciones de montaje)

Lista de permitidos:

  • agents.list[].subagents.allowAgents: lista de ids de agente permitidos mediante agentId (["*"] para permitir cualquiera). Por defecto: solo el agente solicitante.
  • Guarda de herencia de sandbox: si la sesión solicitante está sandboxed, sessions_spawn rechaza destinos que se ejecutarían sin sandbox.

Descubrimiento:

  • Usa agents_list para descubrir qué ids de agente están permitidos para sessions_spawn.

Comportamiento:

  • Inicia una nueva sesión agent:<agentId>:subagent:<uuid> con deliver: false.
  • Los sub-agentes tienen por defecto el conjunto completo de herramientas menos las herramientas de sesión (configurable mediante tools.subagents.tools).
  • Los sub-agentes no pueden llamar a sessions_spawn (no se permite sub-agente → sub-agente).
  • Siempre no bloqueante: devuelve { status: "accepted", runId, childSessionKey } inmediatamente.
  • Con thread=true, los plugins de canal pueden vincular la entrega/enrutamiento a un destino de hilo (el soporte de Discord se controla con session.threadBindings.* y channels.discord.threadBindings.*).
  • Tras completarse, OpenClaw ejecuta un paso de anuncio del sub-agente y publica el resultado en el canal de chat del solicitante.
    • Si la respuesta final del asistente está vacía, el último toolResult del historial del sub-agente se incluye como Result.
  • Responde exactamente ANNOUNCE_SKIP durante el paso de anuncio para mantenerse en silencio.
  • Las respuestas de anuncio se normalizan a Status/Result/Notes; Status proviene del resultado del runtime (no del texto del modelo).
  • Las sesiones de sub-agente se archivan automáticamente después de agents.defaults.subagents.archiveAfterMinutes (por defecto: 60).
  • Las respuestas de anuncio incluyen una línea de estadísticas (runtime, tokens, sessionKey/sessionId, ruta de transcripción y costo opcional).

Visibilidad de sesión en sandbox

Las herramientas de sesión se pueden acotar para reducir el acceso entre sesiones.

Comportamiento por defecto:

  • tools.sessions.visibility tiene por defecto tree (sesión actual + sesiones de subagentes generadas).
  • Para sesiones sandboxed, agents.defaults.sandbox.sessionToolsVisibility puede limitar forzosamente la visibilidad.

Configuración:

{
  tools: {
    sessions: {
      // "self" | "tree" | "agent" | "all"
      // por defecto: "tree"
      visibility: "tree",
    },
  },
  agents: {
    defaults: {
      sandbox: {
        // por defecto: "spawned"
        sessionToolsVisibility: "spawned", // o "all"
      },
    },
  },
}

Notas:

  • self: solo la clave de sesión actual.
  • tree: sesión actual + sesiones generadas por la sesión actual.
  • agent: cualquier sesión que pertenezca al id de agente actual.
  • all: cualquier sesión (el acceso entre agentes aún requiere tools.agentToAgent).
  • Cuando una sesión está sandboxed y sessionToolsVisibility="spawned", OpenClaw limita la visibilidad a tree incluso si configuras tools.sessions.visibility="all".