Gestión de sesiones y compactación (análisis detallado)
Este documento explica cómo OpenClaw gestiona las sesiones de extremo a extremo:- Enrutamiento de sesiones (cómo los mensajes entrantes se asignan a una
sessionKey) - Almacén de sesiones (
sessions.json) y qué rastrea - Persistencia de transcripciones (
*.jsonl) y su estructura - Higiene de transcripciones (ajustes específicos del proveedor antes de las ejecuciones)
- Límites de contexto (ventana de contexto frente a tokens rastreados)
- Compactación (compactación manual + automática) y dónde enganchar trabajo previo a la compactación
- Mantenimiento silencioso (por ejemplo, escrituras de memoria que no deberían producir salida visible para el usuario)
- /concepts/session
- /concepts/compaction
- /concepts/memory
- /concepts/memory-search
- /concepts/session-pruning
- /reference/transcript-hygiene
Fuente de verdad: el Gateway
OpenClaw está diseñado en torno a un único proceso Gateway que posee el estado de la sesión.- Las interfaces de usuario (app de macOS, UI de control web, TUI) deben consultar al Gateway para obtener listas de sesiones y recuentos de tokens.
- En modo remoto, los archivos de sesión están en el host remoto; “comprobar tus archivos locales del Mac” no reflejará lo que está usando el Gateway.
Dos capas de persistencia
OpenClaw persiste las sesiones en dos capas:-
Almacén de sesiones (
sessions.json)- Mapa clave/valor:
sessionKey -> SessionEntry - Pequeño, mutable, seguro de editar (o de borrar entradas)
- Rastrea metadatos de la sesión (id de sesión actual, última actividad, alternadores, contadores de tokens, etc.)
- Mapa clave/valor:
-
Transcripción (
<sessionId>.jsonl)- Transcripción append-only con estructura de árbol (las entradas tienen
id+parentId) - Almacena la conversación real + llamadas a herramientas + resúmenes de compactación
- Se usa para reconstruir el contexto del modelo para turnos futuros
- Transcripción append-only con estructura de árbol (las entradas tienen
Ubicaciones en disco
Por agente, en el host del Gateway:- Almacén:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transcripciones:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Sesiones de temas de Telegram:
.../<sessionId>-topic-<threadId>.jsonl
- Sesiones de temas de Telegram:
src/config/sessions.ts.
Mantenimiento del almacén y controles de disco
La persistencia de sesiones tiene controles automáticos de mantenimiento (session.maintenance) para sessions.json y los artefactos de transcripción:
mode:warn(predeterminado) oenforcepruneAfter: umbral de antigüedad para entradas obsoletas (predeterminado30d)maxEntries: límite de entradas ensessions.json(predeterminado500)rotateBytes: rotasessions.jsoncuando es demasiado grande (predeterminado10mb)resetArchiveRetention: retención para archivos de archivado de transcripciones*.reset.<timestamp>(predeterminado: igual quepruneAfter;falsedesactiva la limpieza)maxDiskBytes: presupuesto opcional para el directorio de sesioneshighWaterBytes: objetivo opcional después de la limpieza (predeterminado80%demaxDiskBytes)
mode: "enforce"):
- Elimina primero los artefactos de transcripción archivados u huérfanos más antiguos.
- Si todavía está por encima del objetivo, expulsa las entradas de sesión más antiguas y sus archivos de transcripción.
- Sigue hasta que el uso esté en o por debajo de
highWaterBytes.
mode: "warn", OpenClaw informa sobre posibles expulsiones pero no modifica el almacén ni los archivos.
Ejecuta el mantenimiento bajo demanda:
Sesiones cron y registros de ejecución
Las ejecuciones cron aisladas también crean entradas/transcripciones de sesión, y tienen controles de retención dedicados:cron.sessionRetention(predeterminado24h) depura las sesiones antiguas de ejecuciones cron aisladas del almacén de sesiones (falsedesactiva esta opción).cron.runLog.maxBytes+cron.runLog.keepLinesdepuran archivos~/.openclaw/cron/runs/<jobId>.jsonl(valores predeterminados:2_000_000bytes y2000líneas).
Claves de sesión (sessionKey)
Una sessionKey identifica en qué contenedor de conversación estás (enrutamiento + aislamiento).
Patrones comunes:
- Chat principal/directo (por agente):
agent:<agentId>:<mainKey>(predeterminadomain) - 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)
Ids de sesión (sessionId)
Cada sessionKey apunta a un sessionId actual (el archivo de transcripción que continúa la conversación).
Reglas generales:
- Restablecer (
/new,/reset) crea un nuevosessionIdpara esasessionKey. - Restablecimiento diario (predeterminado a las 4:00 AM hora local en el host del gateway) crea un nuevo
sessionIden el siguiente mensaje después del límite de restablecimiento. - Caducidad por inactividad (
session.reset.idleMinuteso el heredadosession.idleMinutes) crea un nuevosessionIdcuando llega un mensaje después de la ventana de inactividad. Cuando diario + inactividad están ambos configurados, gana el que caduque primero. - Protección de bifurcación del padre del hilo (
session.parentForkMaxTokens, predeterminado100000) omite la bifurcación de la transcripción padre cuando la sesión padre ya es demasiado grande; el nuevo hilo empieza desde cero. Establece0para desactivarlo.
initSessionState() en src/auto-reply/reply/session.ts.
Esquema del almacén de sesiones (sessions.json)
El tipo de valor del almacén es SessionEntry en src/config/sessions.ts.
Campos clave (no exhaustivo):
sessionId: id de la transcripción actual (el nombre del archivo se deriva de esto a menos que se establezcasessionFile)updatedAt: marca de tiempo de la última actividadsessionFile: sobrescritura opcional explícita de la ruta de la transcripciónchatType:direct | group | room(ayuda a las interfaces y a la política de envío)provider,subject,room,space,displayName: metadatos para etiquetado de grupos/canales- Alternadores:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(sobrescritura por sesión)
- Selección de modelo:
providerOverride,modelOverride,authProfileOverride
- Contadores de tokens (best-effort / dependientes del proveedor):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: con qué frecuencia se completó la compactación automática para esta clave de sesiónmemoryFlushAt: marca de tiempo del último vaciado de memoria previo a la compactaciónmemoryFlushCompactionCount: recuento de compactaciones cuando se ejecutó el último vaciado
Estructura de la transcripción (*.jsonl)
Las transcripciones las gestiona el SessionManager de @mariozechner/pi-coding-agent.
El archivo es JSONL:
- Primera línea: cabecera de sesión (
type: "session", incluyeid,cwd,timestamp,parentSessionopcional) - Luego: entradas de sesión con
id+parentId(árbol)
message: mensajes de usuario/asistente/toolResultcustom_message: mensajes inyectados por extensiones que sí entran en el contexto del modelo (pueden ocultarse de la UI)custom: estado de la extensión que no entra en el contexto del modelocompaction: resumen de compactación persistido confirstKeptEntryIdytokensBeforebranch_summary: resumen persistido al navegar por una rama del árbol
SessionManager para leerlas/escribirlas.
Ventanas de contexto frente a tokens rastreados
Importan dos conceptos distintos:- Ventana de contexto del modelo: límite estricto por modelo (tokens visibles para el modelo)
- Contadores del almacén de sesiones: estadísticas acumuladas escritas en
sessions.json(usadas para/statusy paneles)
- La ventana de contexto proviene del catálogo de modelos (y puede sobrescribirse mediante configuración).
contextTokensen el almacén es un valor estimado/de informes en tiempo de ejecución; no lo trates como una garantía estricta.
Compactación: qué es
La compactación resume la conversación antigua en una entrada persistidacompaction en la transcripción y mantiene intactos los mensajes recientes.
Después de la compactación, los turnos futuros ven:
- El resumen de compactación
- Los mensajes posteriores a
firstKeptEntryId
Límites de fragmentos de compactación y emparejamiento de herramientas
Cuando OpenClaw divide una transcripción larga en fragmentos de compactación, mantiene las llamadas a herramientas del asistente emparejadas con sus entradastoolResult
correspondientes.
- Si la división por proporción de tokens cae entre una llamada a herramienta y su resultado, OpenClaw desplaza el límite al mensaje de llamada a herramienta del asistente en lugar de separar el par.
- Si un bloque final de resultado de herramienta, de otro modo, hiciera que el fragmento superara el objetivo, OpenClaw preserva ese bloque de herramienta pendiente y mantiene intacta la cola no resumida.
- Los bloques de llamada a herramienta abortados/con error no mantienen abierta una división pendiente.
Cuándo ocurre la compactación automática (runtime de Pi)
En el agente Pi integrado, la compactación automática se activa en dos casos:- Recuperación por desbordamiento: el modelo devuelve un error de desbordamiento de contexto
(
request_too_large,context length exceeded,input exceeds the maximum number of tokens,input token count exceeds the maximum number of input tokens,input is too long for the model,ollama error: context length exceeded, y variantes similares con forma de proveedor) → compactar → reintentar. - Mantenimiento por umbral: después de un turno correcto, cuando:
contextTokens > contextWindow - reserveTokens
Donde:
contextWindowes la ventana de contexto del modeloreserveTokenses el margen reservado para prompts + la siguiente salida del modelo
Ajustes de compactación (reserveTokens, keepRecentTokens)
Los ajustes de compactación de Pi viven en la configuración de Pi:
- Si
compaction.reserveTokens < reserveTokensFloor, OpenClaw lo aumenta. - El suelo predeterminado es
20000tokens. - Establece
agents.defaults.compaction.reserveTokensFloor: 0para desactivar el suelo. - Si ya es mayor, OpenClaw lo deja como está.
ensurePiCompactionReserveTokens() en src/agents/pi-settings.ts
(llamado desde src/agents/pi-embedded-runner.ts).
Superficies visibles para el usuario
Puedes observar la compactación y el estado de la sesión mediante:/status(en cualquier sesión de chat)openclaw status(CLI)openclaw sessions/sessions --json- Modo detallado:
🧹 Compactación automática completada+ recuento de compactaciones
Mantenimiento silencioso (NO_REPLY)
OpenClaw admite turnos “silenciosos” para tareas en segundo plano donde el usuario no debería ver salida intermedia.
Convención:
- El asistente empieza su salida con el token silencioso exacto
NO_REPLY/no_replypara indicar “no entregar una respuesta al usuario”. - OpenClaw elimina/suprime esto en la capa de entrega.
- La supresión exacta del token silencioso no distingue mayúsculas de minúsculas, así que
NO_REPLYyno_replycuentan cuando toda la carga útil es solo el token silencioso. - Esto es solo para turnos verdaderamente en segundo plano/sin entrega; no es un atajo para solicitudes ordinarias procesables del usuario.
2026.1.10, OpenClaw también suprime el streaming de borrador/escritura cuando un
fragmento parcial empieza con NO_REPLY, para que las operaciones silenciosas no filtren salida
parcial a mitad del turno.
”Vaciado de memoria” previo a la compactación (implementado)
Objetivo: antes de que ocurra la compactación automática, ejecutar un turno agéntico silencioso que escriba estado duradero en disco (por ejemplo,memory/YYYY-MM-DD.md en el espacio de trabajo del agente) para que la compactación no pueda
borrar contexto crítico.
OpenClaw usa el enfoque de vaciado previo al umbral:
- Supervisar el uso de contexto de la sesión.
- Cuando cruza un “umbral suave” (por debajo del umbral de compactación de Pi), ejecutar una directiva silenciosa de “escribe memoria ahora” al agente.
- Usar el token silencioso exacto
NO_REPLY/no_replypara que el usuario no vea nada.
agents.defaults.compaction.memoryFlush):
enabled(predeterminado:true)softThresholdTokens(predeterminado:4000)prompt(mensaje de usuario para el turno de vaciado)systemPrompt(prompt del sistema adicional añadido para el turno de vaciado)
- El prompt/prompt del sistema predeterminados incluyen una pista
NO_REPLYpara suprimir la entrega. - El vaciado se ejecuta una vez por ciclo de compactación (rastreado en
sessions.json). - El vaciado se ejecuta solo para sesiones Pi integradas (los backends de CLI lo omiten).
- El vaciado se omite cuando el espacio de trabajo de la sesión es de solo lectura (
workspaceAccess: "ro"o"none"). - Consulta Memory para el diseño de archivos del espacio de trabajo y los patrones de escritura.
session_before_compact en la API de extensiones, pero la lógica de vaciado
de OpenClaw vive actualmente del lado del Gateway.
Lista de verificación para solución de problemas
- ¿La clave de sesión es incorrecta? Empieza con /concepts/session y confirma la
sessionKeyen/status. - ¿No coinciden el almacén y la transcripción? Confirma el host del Gateway y la ruta del almacén desde
openclaw status. - ¿Compactación excesiva? Comprueba:
- ventana de contexto del modelo (demasiado pequeña)
- ajustes de compactación (
reserveTokensdemasiado alto para la ventana del modelo puede causar una compactación más temprana) - exceso de resultados de herramientas: habilita/ajusta la depuración de sesión
- ¿Se filtran turnos silenciosos? Confirma que la respuesta empieza con
NO_REPLY(token exacto sin distinguir mayúsculas de minúsculas) y que estás en una compilación que incluye la corrección de supresión de streaming.