Bug: chat continuation history is rebuilt twice when server injects CONTINUATION header
Summary
chat continuations can accidentally duplicate conversation history and grow context much faster than expected.
The server-level continuation reconstruction emits a header like:
=== CONVERSATION HISTORY (CONTINUATION) ===
...
=== END CONVERSATION HISTORY ===But SimpleTool currently checks for the exact substring:
"=== CONVERSATION HISTORY ==="That check does not match the actual (CONTINUATION) header. As a result, when a request reaches SimpleTool with already-embedded history, the tool treats it as missing history and reconstructs the thread again.
Impact
This causes duplicated history in the prompt and can also store an already-expanded prompt back into the conversation thread as a new user turn. Multi-turn chat continuations then inflate quickly and may hit downstream context limits earlier than expected.
Symptoms may include:
- repeated or unexpectedly large
=== CONVERSATION HISTORYblocks - continuation turn counts increasing faster than expected
- downstream provider errors such as context length exceeded / request too large
- poor behavior for long-running
chatcontinuation workflows
Suspected Root Cause
server.py reconstructs continuation history before tool execution.
tools/simple/base.py then tries to detect whether history is already embedded:
if "=== CONVERSATION HISTORY ===" in field_value:
prompt = field_value
else:
# reconstruct againThe actual header contains a suffix:
=== CONVERSATION HISTORY (CONTINUATION) ===So the detection misses.
Suggested Fix
Use a broader sentinel check, for example:
def _has_embedded_conversation_history(prompt: str) -> bool:
return (
"=== CONVERSATION HISTORY" in prompt
and "=== END CONVERSATION HISTORY ===" in prompt
)Then use that helper in SimpleTool instead of checking for the exact old header.
Suggested Test
Add a test covering the server-emitted header:
prompt = """=== CONVERSATION HISTORY (CONTINUATION) ===
Thread: 12345678-1234-1234-1234-123456789012
Previous conversation turns:
--- Turn 1 (Agent) ---
hello
=== END CONVERSATION HISTORY ===
=== NEW USER INPUT ===
continue
"""
assert ChatTool._has_embedded_conversation_history(prompt) is TrueNotes
This appears independent of any particular downstream provider. Providers with stricter context limits simply expose the issue sooner.
Source: BeehiveInnovations/pal-mcp-server