Skip to content

server: disable tool calls during compaction requests#591

Open
ober wants to merge 1 commit into
antirez:mainfrom
ober:fix/disable-tools-during-compaction
Open

server: disable tool calls during compaction requests#591
ober wants to merge 1 commit into
antirez:mainfrom
ober:fix/disable-tools-during-compaction

Conversation

@ober

@ober ober commented Jul 21, 2026

Copy link
Copy Markdown

server: disable tool calls during compaction requests

Problem

When opencode (or other Responses API clients) sends a compaction request to summarize a session, the ds4 server was allowing the model to emit DSML tool calls as part of its summary output. These tool calls were returned as raw text in the response content instead of being converted to structured tool_calls, causing breakage in clients that expect either proper JSON tool calls or plain text.

Observed Behavior

During session compaction, the model would output raw DSML like:

<|DSML|tool_calls>
<|DSML|invoke name="bash">
<|DSML|parameter name="command" string="true">cd /Users/user/sfb && python3 ...
</|DSML|parameter>
</|DSML|invoke>
</|DSML|tool_calls>

This raw DSML text was included in the assistant response content, which:

  1. Confused clients expecting structured tool calls or plain text summaries
  2. Polluted the session history with non-executable tool call syntax
  3. Made compaction summaries unreadable and unusable

Root Cause

The Responses API parser (parse_responses_input) correctly identifies "compaction" and "context_compaction" items as bookkeeping entries in the input history. However, this information was not propagated to the request handler, so has_tools remained true even when the request was clearly a compaction/summary operation.

With has_tools = true, the model DSML tool call output was processed by the tool parser. When the parser failed (or the DSML was incomplete), the raw DSML was returned as assistant text content.

Solution

Track whether the last item in the Responses API input history is a compaction type ("compaction" or "context_compaction"), and disable tool calls (has_tools = false) for such requests.

Changes

  1. parse_responses_input: Added a bool *last_was_compaction out-parameter that is set to true when a compaction bookkeeping item is encountered in the input history.

  2. parse_responses_request: Passes the last_was_compaction flag and uses it to disable tools:

    r->has_tools = active_tool_schemas && active_tool_schemas[0] && !last_was_compaction;
    
  3. Test updates: Updated existing test calls to parse_responses_input to pass NULL for the new parameter.

Impact

  • Compaction requests now generate plain text summaries without tool calls
  • Normal chat requests are unaffected - tool calls work as before
  • No protocol changes - the fix is internal to the server request parsing

Testing

  • Verified the server builds cleanly with make
  • Server restarts and operates normally for regular chat requests with tools
  • Compaction requests (input ending with "type": "compaction") now have has_tools = false

Files Changed

  • ds4_server.c: 10 insertions, 6 deletions

When the Responses API input history ends with a "compaction" or
"context_compaction" bookkeeping item, the model was still emitting
DSML tool calls as part of its summary output. These tool calls were
returned as raw text in the response content, causing breakage in
clients like opencode that expect structured tool_calls or plain text.

Track whether the last input item was a compaction type and disable
has_tools in that case, so the model generates a plain text summary
without attempting tool invocations.

Fixes bogus DSML appearing in compaction/summary responses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant