From 8bc284c60e9beba4bb7d421f1bc6847b5a54cfb2 Mon Sep 17 00:00:00 2001 From: Patrick Buckley Date: Tue, 10 Mar 2026 13:42:57 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20agent=20context=20overflow=20=E2=80=94?= =?UTF-8?q?=20truncate=20tool=20output,=20catch=20context=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent tool outputs are now truncated to 16k chars to prevent search results (14M+ chars observed) from blowing past the model's context limit. On context-exceeded API errors, the agent returns its last content instead of crashing. --- turnstone/core/session.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/turnstone/core/session.py b/turnstone/core/session.py index df13ef10..cb32e649 100644 --- a/turnstone/core/session.py +++ b/turnstone/core/session.py @@ -2548,7 +2548,20 @@ class ChatSession: turn = 0 while max_tool_turns < 0 or turn < max_tool_turns: - result = _api_call(agent_messages) + try: + result = _api_call(agent_messages) + except Exception as e: + # Context-exceeded or other non-retryable API error. + # Return what we have so far rather than crashing. + err_str = str(e).lower() + if "context" in err_str or "token" in err_str: + self.ui.on_info(f"[{label}] context limit reached, stopping early") + # Find the last assistant content we have + for msg in reversed(agent_messages): + if msg.get("role") == "assistant" and msg.get("content"): + return msg["content"] + return f"({label} stopped: context limit exceeded)" + raise # Handle truncation or content filter — stop agent early if result.finish_reason == "length": @@ -2612,6 +2625,12 @@ class ChatSession: else: output = f"Unknown tool: {tool_name}" + # Truncate large tool outputs to avoid blowing context limits. + # Agents operate autonomously; they can refine their queries + # if truncation loses important detail. + if isinstance(output, str) and len(output) > 16000: + output = output[:16000] + f"\n\n... (truncated from {len(output)} chars)" + agent_messages.append( { "role": "tool",