Summary
The automatic context-compaction path (summarize_transcript) sends the entire session history + system prompt to the summarization model without any token-budget protection. The manual path (archive_session) correctly uses get_history(max_tokens=budget) chunking, but the automatic path does not.
Consequence
Once a session's history exceeds the model's input budget, a deadlock occurs:
- Governor blocks the request because input > budget ("Unable to compact context")
- Compaction itself requires an LLM call whose input (full history + prompt) also exceeds the budget
- That call is also blocked / falls back to raw archiving, so history never shrinks
- The session is permanently stuck — the only recovery is
/newor manually clearing history
In our case the trigger was a misconfigured contextWindowTokens (64000 vs the model's real 1M window), which made fixed overhead (~92k tokens of system prompt + tool definitions) exceed the local input budget (~54784). But even with a correctly sized window, any session whose history grows past the window hits the same permanent deadlock — a bigger window only delays it.
Observed behavior
Compressing context… → Unable to compact context (input 91985 tokens > budget 54784)Repeated on every turn; context never reduced.
Suggested fix
Apply the same budget guard used by archive_session to summarize_transcript: when the history passed to the summarizer exceeds the model's input budget, truncate/chunk it via get_history(max_tokens=budget - reserved_for_prompt) (or fall back to keeping the most recent N messages) so compaction can always make progress.
Environment
- nanobot v0.3.5 (upgrade that made the failure visible: precise tiktoken estimation + strict governor)
- macOS, GLM-5.3-Flash endpoint
I tested this against current
origin/main(12a9a8a692c7e8fc6d3d293afdddcdaa390436df) using the real Zhipu GLM-5.3-Flash API and a temporary copy of a local session. I could reproduce the oversized archive-input condition, but I could not reproduce the permanent compaction deadlock described in this issue.Test details:
last_archived=7126. Running it as-is did not trigger compaction. The turn completed successfully with 10,781 provider input tokens.context_window_tokens=200000, the archive input budget was 191,808 tokens. Current main detected that the archive request did not fit and used the raw-checkpoint fallback. The subsequent GLM request used 14,740 input tokens and completed successfully.context_window_tokens=64000. The regular input budget was 54,784 tokens (64000 - 8192 max output - 1024 safety buffer), while the archive guard used 55,808 tokens (64000 - 8192). Current main again used the raw-checkpoint fallback, then sent a 14,740-token request to GLM, which completed successfully.The original config and session were not modified. One limitation is that the configured XMind MCP server was not connected during the probe, so its tool schemas were not included in the prompt measurements.
My conclusion from these runs is:
Compressing context -> Unable to compact contexton every turn) is not reproduced on current main. Current main preserves liveness by falling back to a raw checkpoint.54,784value in the 64k setup is a local input budget, not the GLM model's context limit or the system-prompt size.Reproducing the original hard deadlock may require the exact v0.3.5 revision and the reporter's session/tool state.