Ir al contenido

Gestiona sesiones y compactación en OpenClaw: Guía técnica

OpenClaw está diseñado en torno a un único proceso Gateway que gestiona el estado de la sesión. Por esta razón, las UIs (app de macOS, web Control UI, TUI) deben consultar al Gateway para obtener las listas de sesiones y los conteos de tokens.

Si usas el modo remoto, los archivos de sesión se encuentran en el host remoto. Revisar tus archivos locales en Mac no reflejará lo que el Gateway está utilizando en ese momento.

OpenClaw persiste las sesiones en dos capas distintas:

  1. Almacén de sesiones (sessions.json)

    • Es un mapa clave/valor: sessionKey -> SessionEntry.
    • Es pequeño, mutable y seguro para editar manualmente (o para borrar entradas).
    • Rastrea los metadatos de la sesión (ID de sesión actual, última actividad, interruptores, contadores de tokens, etc.).
  2. Transcripción (<sessionId>.jsonl)

    • Es un registro de solo anexar con estructura de árbol (las entradas tienen id + parentId).
    • Guarda la conversación real, las llamadas a herramientas y los resúmenes de compactación.
    • Se utiliza para reconstruir el contexto del modelo en futuros turnos.

Por cada agente, dentro del host del Gateway, encontrarás lo siguiente:

  • Almacén: ~/.openclaw/agents/<agentId>/sessions/sessions.json
  • Transcripciones: ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl
  • Sesiones de hilos de Telegram: .../<sessionId>-topic-<threadId>.jsonl
  • Resolución de rutas: OpenClaw gestiona estas ubicaciones mediante src/config/sessions.ts.

Mantenimiento del almacén y controles de disco

Sección titulada «Mantenimiento del almacén y controles de disco»

La persistencia de sesiones incluye controles de mantenimiento automático (session.maintenance) tanto para sessions.json como para los artefactos de transcripción:

  • mode: warn (por defecto) o enforce.
  • pruneAfter: límite de antigüedad para entradas obsoletas (por defecto 30d).
  • maxEntries: límite de entradas en sessions.json (por defecto 500).
  • rotateBytes: rota sessions.json cuando supera el tamaño (por defecto 10mb).
  • resetArchiveRetention: retención para archivos *.reset.<timestamp> (por defecto igual que pruneAfter; false desactiva la limpieza).
  • maxDiskBytes: presupuesto opcional para el directorio de sesiones.
  • highWaterBytes: objetivo opcional tras la limpieza (por defecto 80% de maxDiskBytes).

Orden de ejecución para la limpieza del presupuesto de disco (mode: "enforce"):

  1. Primero se eliminan los artefactos de transcripción archivados u huérfanos más antiguos.
  2. Si el tamaño sigue por encima del objetivo, se expulsan las entradas de sesión más antiguas y sus archivos de transcripción hasta que el uso esté en o por debajo de highWaterBytes.

En el modo mode: "warn", OpenClaw te informará sobre las posibles expulsiones, pero no modificará el almacén ni los archivos.

Puedes ejecutar el mantenimiento bajo demanda con estos comandos:

Ventana de terminal
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce

Las ejecuciones aisladas de cron también crean entradas de sesión y transcripciones, y tienen controles de retención específicos:

  • cron.sessionRetention (por defecto 24h) elimina las sesiones antiguas de ejecuciones de cron aisladas del store de sesiones (false lo desactiva).
  • cron.runLog.maxBytes + cron.runLog.keepLines limpian los archivos ~/.openclaw/cron/runs/<jobId>.jsonl (valores por defecto: 2_000_000 bytes y 2000 líneas).

Una sessionKey identifica en qué “cubo de conversación” te encuentras (enrutamiento + aislamiento).

Patrones comunes:

  • Chat principal/directo (por agente): agent:<agentId>:<mainKey> (por defecto main)
  • Grupo: agent:<agentId>:<channel>:group:<id>
  • Sala/canal (Discord/Slack): agent:<agentId>:<channel>:channel:<id> o ...:room:<id>
  • Cron: cron:<job.id>
  • Webhook: hook:<uuid> (a menos que se sobrescriba)

Las reglas canónicas están documentadas en /concepts/session.


Cada sessionKey apunta a un sessionId actual (el archivo de transcripción que continúa la conversación).

Reglas generales:

  • Reset (/new, /reset) crea un nuevo sessionId para esa sessionKey.
  • Daily reset (por defecto a las 4:00 AM hora local en el host del Gateway) crea un nuevo sessionId en el siguiente mensaje tras el límite del reset.
  • Idle expiry (session.reset.idleMinutes o el antiguo session.idleMinutes) crea un nuevo sessionId cuando llega un mensaje después de la ventana de inactividad. Cuando ambos están configurados, el que expire primero gana.
  • Thread parent fork guard (session.parentForkMaxTokens, por defecto 100000) omite el fork de la transcripción del padre cuando la sesión padre ya es demasiado grande; el nuevo hilo empieza de cero. Usa 0 para desactivarlo.

Detalle de implementación: la decisión ocurre en initSessionState() en src/auto-reply/reply/session.ts.


El tipo de valor del store es SessionEntry en src/config/sessions.ts.

Campos clave (no es una lista exhaustiva):

  • sessionId: id de la transcripción actual (el nombre del archivo se deriva de aquí a menos que se use sessionFile)
  • updatedAt: timestamp de la última actividad
  • sessionFile: sobrescritura opcional de la ruta de la transcripción
  • chatType: direct | group | room (ayuda a las interfaces y a la política de envío)
  • provider, subject, room, space, displayName: metadatos para etiquetas de grupo o canal
  • Toggles:
    • thinkingLevel, verboseLevel, reasoningLevel, elevatedLevel
    • sendPolicy (sobrescritura por sesión)
  • Selección de modelo:
    • providerOverride, modelOverride, authProfileOverride
  • Contadores de tokens (basados en el mejor esfuerzo / dependen del proveedor):
    • inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: cuántas veces se completó la auto-compactación para esta clave de sesión
  • memoryFlushAt: timestamp del último volcado de memoria pre-compactación
  • memoryFlushCompactionCount: conteo de compactación cuando se ejecutó el último volcado

Puedes editar el store sin miedo, pero el Gateway manda: puede sobrescribir o rehidratar entradas mientras las sesiones se ejecutan.

Los transcripts los gestiona el SessionManager de @mariozechner/pi-coding-agent.

El archivo utiliza el formato JSONL:

  • Primera línea: cabecera de la sesión (type: "session", incluye id, cwd, timestamp y, opcionalmente, parentSession)
  • Después: entradas de la sesión con id + parentId (en estructura de árbol)

Tipos de entrada destacados:

  • message: mensajes de usuario, asistente o toolResult
  • custom_message: mensajes inyectados por extensiones que sí entran en el contexto del modelo (pueden ocultarse en la interfaz de usuario)
  • custom: estado de la extensión que no entra en el contexto del modelo
  • compaction: resumen de compactación persistido con firstKeptEntryId y tokensBefore
  • branch_summary: resumen persistido al navegar por una rama del árbol

OpenClaw no intenta “arreglar” los transcripts a propósito; el Gateway utiliza el SessionManager para leerlos y escribirlos.


Hay dos conceptos distintos que debes tener en cuenta:

  1. Model context window: límite estricto por modelo (tokens que el modelo puede ver)
  2. Session store counters: estadísticas acumulativas escritas en sessions.json (utilizadas para /status y dashboards)

Si estás ajustando los límites:

  • La context window proviene del catálogo de modelos (y puedes sobrescribirla mediante la configuración).
  • contextTokens en el store es una estimación o valor de reporte en tiempo de ejecución; no lo consideres como una garantía absoluta.

Para saber más, consulta /token-use.

La compactación resume las conversaciones antiguas en una entrada de compaction persistente dentro del transcript y mantiene intactos los mensajes recientes.

Después de la compactación, los siguientes turnos ven:

  • El resumen de la compactación
  • Los mensajes posteriores a firstKeptEntryId

La compactación es persistente (a diferencia del session pruning). Consulta /concepts/session-pruning.


Cuándo ocurre la auto-compactación (Pi runtime)

Sección titulada «Cuándo ocurre la auto-compactación (Pi runtime)»

En el agente Pi embebido, la auto-compactación se activa en dos casos:

  1. Recuperación de desbordamiento (overflow): el modelo devuelve un error de desbordamiento de contexto → compactar → reintentar.
  2. Mantenimiento de umbral: después de un turno exitoso, cuando:

contextTokens > contextWindow - reserveTokens

Donde:

  • contextWindow es el context window del modelo
  • reserveTokens es el margen reservado para los prompts + la siguiente salida del modelo

Estas son semánticas del Pi runtime (OpenClaw consume los eventos, pero Pi decide cuándo compactar).

Ajustes de compactación (reserveTokens, keepRecentTokens)

Sección titulada «Ajustes de compactación (reserveTokens, keepRecentTokens)»

Los ajustes de compactación de Pi viven en la configuración de Pi:

{
compaction: {
enabled: true,
reserveTokens: 16384,
keepRecentTokens: 20000,
},
}

OpenClaw también impone un límite mínimo de seguridad para las ejecuciones embebidas:

  • Si compaction.reserveTokens < reserveTokensFloor, OpenClaw lo aumenta.
  • El límite por defecto es de 20000 tokens.
  • Configura agents.defaults.compaction.reserveTokensFloor: 0 para desactivar este límite.
  • Si el valor ya es más alto, OpenClaw no lo toca.

El motivo: dejar suficiente margen para las tareas de mantenimiento de varios turnos (como las escrituras en memoria) antes de que la compactación sea inevitable.

Implementación: ensurePiCompactionReserveTokens() en src/agents/pi-settings.ts (llamado desde src/agents/pi-embedded-runner.ts).

Puedes observar la compactación y el estado de la sesión a través de:

  • /status (en cualquier sesión de chat)
  • openclaw status (CLI)
  • openclaw sessions / sessions --json
  • Modo verbose: 🧹 Auto-compaction complete + el contador de compactación

OpenClaw admite turnos “silenciosos” para tareas en segundo plano donde no quieres que el usuario vea resultados intermedios.

Convención:

  • El asistente comienza su respuesta con NO_REPLY para indicar “no entregues esta respuesta al usuario”.
  • OpenClaw elimina o suprime esto en la capa de entrega.

Desde la versión 2026.1.10, OpenClaw también suprime el streaming de borradores/escritura cuando un fragmento parcial comienza con NO_REPLY. De esta forma, las operaciones silenciosas no filtran contenido parcial a mitad del turno.


”Memory flush” previo a la compactación (implementado)

Sección titulada «”Memory flush” previo a la compactación (implementado)»

Objetivo: antes de que ocurra la auto-compactación, se ejecuta un turno de agente silencioso que escribe el estado duradero en el disco (por ejemplo, memory/YYYY-MM-DD.md en el workspace del agente). Esto evita que la compactación borre contexto crítico.

OpenClaw utiliza el enfoque de vaciado previo al umbral (pre-threshold flush):

  1. Monitoriza el uso del contexto de la sesión.
  2. Cuando cruza un “umbral suave” (por debajo del umbral de compactación de Pi), envía una directiva silenciosa de “escribir memoria ahora” al agente.
  3. Usa NO_REPLY para que el usuario no vea nada.

Configuración (agents.defaults.compaction.memoryFlush):

  • enabled (por defecto: true)
  • softThresholdTokens (por defecto: 4000)
  • prompt (mensaje del usuario para el turno de vaciado)
  • systemPrompt (prompt de sistema extra añadido para el turno de vaciado)

Notas:

  • El prompt y el systemPrompt por defecto incluyen una indicación de NO_REPLY para suprimir la entrega.
  • El vaciado se ejecuta una vez por ciclo de compactación (rastreado en sessions.json).
  • El vaciado solo funciona para sesiones de Pi embebidas (los backends de CLI lo omiten).
  • El vaciado se salta cuando el workspace de la sesión es de solo lectura (workspaceAccess: "ro" o "none").
  • Consulta Memory para ver el diseño de archivos del workspace y los patrones de escritura.

Pi también expone un hook session_before_compact en la API de la extensión, pero la lógica de vaciado de OpenClaw reside actualmente en el lado del Gateway.


Lista de verificación para resolución de problemas

Sección titulada «Lista de verificación para resolución de problemas»
  • ¿Key de sesión incorrecta? Empieza con /concepts/session y confirma la sessionKey en /status.
  • ¿Desajuste entre Store y transcripción? Confirma el host del Gateway y la ruta del store desde openclaw status.
  • ¿Exceso de compactación (spam)? Revisa:
    • Ventana de contexto del modelo (demasiado pequeña).
    • Configuración de compactación (reserveTokens demasiado alto para la ventana del modelo puede causar compactaciones prematuras).
    • Exceso de resultados de herramientas: activa o ajusta el recorte de sesiones (session pruning).
  • ¿Se filtran los turnos silenciosos? Confirma que la respuesta empieza con NO_REPLY (el token exacto) y que usas una versión que incluya la corrección de supresión de streaming.
OpenClaw

OpenClaw Expert

Sigues atascado?

Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.