History compaction spills oversized tool results instead of truncating to 80 chars
For a worker with historyCompression: true on its WorkerProfile (see src/core/workerProfiles.ts),
once accumulated message history exceeds historyCompressionBudget (default 8000 tokens,
CYBERINE_HISTORY_COMPRESSION_BUDGET), TruncationHistoryCompressor (src/core/historyCompression.ts)
now tries a cheaper fix FIRST, before dropping any turn of the conversation: any tool-result
message estimated at 200+ tokens is spilled to disk (the same store TOOL-RESULT-SPILL /
spill_retrieve uses) and replaced in place with a short locator note. The whole history is
re-measured afterward — a worker whose bulk is tool-output bytes often fits again without losing
a single round, just the raw bytes of what a tool printed; you will see
[history compaction: N tool result(s) spilled to disk, no messages dropped] in the worker's
output stream when this alone was enough.
Only when spilling still is not enough does the existing drop-and-digest path run: the oldest
rounds are dropped and replaced by one === COMPRESSED HISTORY === system message
([history compressed: N messages summarized, M tool result(s) spilled to disk]). Two
correctness fixes ship alongside the spill behavior: a dropped tool result now shows its
spill:// locator in the digest instead of a blind 80-char slice (which used to risk cutting a
retrieval path off mid-string), and an assistant's tool-call turn is never dropped separately
from its own tool-result turn(s) — they are always kept or dropped together, since a request
with one but not the other is invalid for most providers.
Known Limitations and Deferred Work (src/core/historyCompression.ts). This is purely
mechanical — no LLM summarization call is made (a separate, costed decision, deliberately out of
scope here). The digest text itself is still a plain heuristic summary, not derived from what was
actually spilled; a spilled tool result that later gets dropped shows only its locator, not any
content preview. There is no cross-round de-duplication — the same underlying file read twice by
a worker produces two independent spill files if both are ever compacted. src/tui/contextView.ts
mirrors this file's approxTokens/messageTokens heuristic for its own /context report; those
two functions are untouched by this change specifically so that mirror stays accurate.
Oversized tool results — spill-to-disk + retrieval (spill_retrieve)
Every tool call an agent adapter makes (LoopAgentAdapter, AnthropicAgentAdapter, BedrockAdapter, VertexAdapter — including MCP tools consumed via McpToolAdapter, which previously had no cap at...
Malformed tool calls — validate-then-repair on the loop tool-input path (kmk7x)
Open models on OpenAI-compatible endpoints (DeepSeek, MiniMax, GLM, Qwen) emit a small set of recurring tool-call shape errors. Before this change a loop worker parsed the arguments with...