Compaction injects a stale summary when the model does not call `compact_chat`
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 58/100
Línea de trabajo
Start by tracing compaction through src/eca/features/tools/chat.clj (compact-chat), src/eca/features/chat.clj (trigger-compact!), src/eca/features/chat/lifecycle.clj (complete-compact!), and src/eca/shared.clj (compact-side-effect!). Check how the current compaction's tool call is tracked and how a text-only response reaches the finish side effect. Add a test with a fake LLM returning text only; done means the old summary is not silently injected and failure or recovery is handled visibly.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
When the LLM answers the compact prompt with plain text instead of calling the compact_chat tool, ECA still completes the compaction and injects the chat's previous :last-summary as "The conversation was compacted/summarized, consider this summary:". The new summary, written as text, is discarded. The chat then continues from a summary of an older state, with no warning to the user or the model.
In a chat that was never compacted before, the injected summary is empty instead.
Environment
- ECA 0.161.2 (also present on master at
edca8608a) - Model: a local Qwen3.8-Flash-Next over an OpenAI-compatible endpoint (
openai-chatAPI); probably reproducible with any model that sometimes ignores the tool instruction - Custom compact prompt (
prompts.compact), which says "Calleca__compact_chatwith the summary as its argument"; the defaultcompact.mdsays the same - Auto-compaction during a running turn (
autoCompactPercentage: 85)
What happened
One long chat, compacted three times by auto-compaction, same model and same compact prompt each time:
- Compactions 1 and 2: the model called
compact_chat; the injected summary matched the tool argument. OK. - Compaction 3 (mid-turn, right after a long subagent result): the model's reasoning ended with "Now, writing the summary." and it answered with the full summary (~12.8k chars) as a normal assistant message. No tool call, no malformed tool-call markup.
- ECA appended
compact_markerand then injected the summary stored by compaction 2. That summary described a task from hours earlier, with obsolete state and instructions. The text answer from step 2 was not used. - ECA resumed the turn ("Continue with the task. The previous user request was: …"), so the agent continued with the stale summary as its only memory of the session.
The persisted chat shows: assistant message with the new summary → compact_marker → user message whose text equals the chat's last-summary field (the old one).
Cause in the code
compact_chatis the only place that stores a summary: it sets:last-summaryand:compact-done? true(src/eca/features/tools/chat.clj,compact-chat).- A mid-turn compaction finishes through
compact-finished-side-effect!→lifecycle/complete-compact!→shared/compact-side-effect!(src/eca/features/chat.clj,trigger-compact!;src/eca/features/chat/lifecycle.clj,complete-compact!;src/eca/shared.clj,compact-side-effect!). compact-side-effect!always reads(get-in db [:chats chat-id :last-summary])and injects it. Nothing checks thatcompact_chatwas called during this compaction;:compact-done?is only used to skip postRequest hooks (chat.clj,on-tools-called).- The finish side effect runs however the compact prompt ends, also when it ends with a text-only answer.
Steps to reproduce
- Use a model (or a fake OpenAI-compatible server) that answers the compact prompt with plain text and no tool call.
- In a chat that was compacted once before (so
:last-summaryholds summary A), trigger a second compaction (/compactor auto-compaction). - The model answers with summary B as text.
Expected: the chat continues with summary B, or the compaction fails visibly.
Actual: the chat continues with summary A (or an empty summary, if there was no earlier compaction). Nothing tells the user.
Suggested fixes
Any of these would prevent the silent stale summary:
- Detect it: clear
:last-summary(or record the compaction's start) before sending the compact prompt, and incompact-side-effect!treat "nocompact_chatcall in this compaction" as a failure. - Recover: when the compact turn ends without the tool call, re-prompt once ("call
eca__compact_chatwith the summary you just wrote"), or use the final assistant text as the summary. - Fail loudly: if neither works, do not append the marker; keep the history, and show a system message such as "Compaction failed: the model did not call compact_chat".
A test with a fake LLM that answers the compact prompt with text only would cover this.
Workaround
None on the user side, except watching for the problem: after a compaction, check that the injected summary describes the current work. Hooks cannot fix it: postCompact runs after the summary was chosen. A postCompact hook can only add context, for example re-inject the current task state from a file.
- Lenguaje dominante
- Clojure
- Estrellas
- 1k
- Forks
- 82
- Merge medio
- 3 d 39 min
- PR fusionados (30 d)
- 15
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de editor-code-assistant/eca
-
bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
editor-code-assistant/eca#655 ·
Los mantenedores suelen responder en 2 días
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
editor-code-assistant/eca#652 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 12/100
editor-code-assistant/eca#648 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
editor-code-assistant/eca#644 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Add the ability to see what changed in the system promptPosiblemente ocupada @zikajk la tomó hace 9 días. Abiertoenhancement
editor-code-assistant/eca#642 · 1 asignado ·
Los mantenedores suelen responder en 2 días
Todos los issues de editor-code-assistant/eca
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
IOP MCP
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
calcit-lang/calcit#2133 ·
Los mantenedores suelen responder en 1 día
-
worker/start rejects middleware supplied as a VarPosiblemente ocupada @rajp152k la tomó hace 3 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Profiler (Remotery) leaks a socket for every connection that fails the WebSocket handshakePosiblemente ocupada @rthery la tomó hace 3 días. Abiertotriage
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día