Skip to content

fix(deepseekv3): Fix DeepSeekV3Detector tool_index assignment and multi-tool call streaming support#6655

Merged
zhyncs merged 4 commits intomainfrom
chang/tool-dsv3
May 28, 2025
Merged

fix(deepseekv3): Fix DeepSeekV3Detector tool_index assignment and multi-tool call streaming support#6655
zhyncs merged 4 commits intomainfrom
chang/tool-dsv3

Conversation

@CatherineSue
Copy link
Copy Markdown
Collaborator

@CatherineSue CatherineSue commented May 27, 2025

Motivation

This PR focuses to fix the current two issues in DeepSeekV3Detector.

  1. tool_index: Current the tool_index of each ToolCallItem is assigned based on the index of the function name in the tools list passed by the request. See: feat(Tool Calling): Support required and specific function mode #6550 (comment)
    The correct behavior should be the index of the current tool call in the response tool_calls list.
  2. DeepSeekV3Detector is not parsing multi-tools correctly. See: [Feature] Tool Call Roadmap #6589 (comment)

Modifications

  • Fix tool_index to use call sequence position instead of tool array position
  • Add support for detecting subsequent tool calls without bot_token prefix
  • Implement smart buffer management to preserve multiple tool calls
  • Maintain adapter.py integration state arrays for streaming compatibility

This resolves issues where:

  1. Tool calls were assigned incorrect indices based on tool definition order
  2. Second and subsequent tool calls were treated as normal text
  3. Buffer was cleared completely, losing subsequent tool call data

Checklist

…ti-tool call streaming support

- Fix tool_index to use call sequence position instead of tool array position
- Add support for detecting subsequent tool calls without bot_token prefix
- Implement smart buffer management to preserve multiple tool calls
- Maintain adapter.py integration state arrays for streaming compatibility

This resolves issues where:
1. Tool calls were assigned incorrect indices based on tool definition order
2. Second and subsequent tool calls were treated as normal text
3. Buffer was cleared completely, losing subsequent tool call data
@CatherineSue
Copy link
Copy Markdown
Collaborator Author

Test before:
447361068-f8be5a56-ee02-4cdc-89f0-e02f55d6f1e5

After:
Screenshot 2025-05-26 at 10 28 29 PM

@zhyncs
Copy link
Copy Markdown
Collaborator

zhyncs commented May 27, 2025

/gemini summary

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello! Gemini here, providing a summary of this pull request. This PR focuses on addressing two key issues within the DeepSeekV3Detector component. Firstly, it corrects the assignment of the tool_index for ToolCallItems during streaming, ensuring it reflects the sequential position of the tool call in the response rather than its index in the initial tool list provided in the request. Secondly, it enhances the detector's ability to correctly parse and handle multiple consecutive tool calls within a single streaming response, which was previously causing subsequent calls to be misinterpreted as normal text. The changes involve updating the streaming parsing logic to maintain state across tool calls, manage the internal buffer more intelligently, and correctly identify and index each tool call as it streams.

Highlights

  • Fix incorrect tool_index: The tool_index assigned to streamed ToolCallItems now correctly represents the order of the tool call in the model's response, rather than the index of the tool definition in the initial request.
  • Support multi-tool call streaming: The detector can now correctly parse and yield multiple tool calls that appear consecutively in the streaming output, even if subsequent calls lack the initial bot_token prefix.
  • Improved buffer management: The internal buffer logic has been updated to preserve content that might contain subsequent tool calls after one is completed, preventing data loss and enabling multi-tool call detection.
  • Maintain adapter state: Logic was added to maintain state arrays (prev_tool_call_arr, streamed_args_for_tool) compatible with the adapter.py requirements for handling streaming tool calls.

Changelog

  • python/sglang/srt/function_call/deepseekv3_detector.py
    • Added self.current_tool_id to track the index of the current tool call being processed during streaming.
    • Modified the buffer clearing condition in parse_streaming_increment to keep the buffer if a tool call start token (<|tool call begin|>) is present, allowing detection of subsequent tool calls without the bot_token.
    • Initialized state tracking arrays (prev_tool_call_arr, streamed_args_for_tool) and current_tool_id upon detecting the first tool call.
    • Ensured state tracking arrays are dynamically sized to accommodate multiple tool calls.
    • Changed tool_index assignment in ToolCallItem creation to use self.current_tool_id.
    • Stored initial tool call name and updated arguments in self.prev_tool_call_arr for adapter compatibility.
    • Appended streamed argument increments to self.streamed_args_for_tool.
    • Updated buffer management upon completion of a tool call to remove only the completed call's content, preserving any subsequent text (potential next tool call).
    • Incremented self.current_tool_id after a tool call is fully parsed.

Activity

  • CatherineSue posted screenshots demonstrating the behavior before and after the changes.
  • zhyncs requested this summary using the /gemini summary command.

@zhyncs
Copy link
Copy Markdown
Collaborator

zhyncs commented May 27, 2025

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses two key issues in DeepSeekV3Detector: the incorrect tool_index assignment and the lack of support for parsing multiple tool calls in a streaming fashion. The introduction of current_tool_id for sequential indexing and the refined buffer management to preserve subsequent tool calls are significant improvements. The changes to handle subsequent tool calls without the bot_token prefix also look good. Overall, these modifications enhance the robustness and correctness of tool call parsing for DeepSeekV3.

I have one point for clarification regarding buffer clearing in a specific edge case, detailed below.

Summary of Findings

  • Tool Index Correction: The PR successfully corrects the tool_index assignment by using a sequential current_tool_id incremented for each tool call, rather than relying on the tool definition order. This aligns with the expected behavior.
  • Multi-Tool Call Streaming Support: The changes significantly improve support for streaming multiple tool calls. Detecting subsequent tool calls via <|tool call begin|> and the smart buffer management (self._buffer = current_text[match.end() :]) are key to this.
  • Buffer Clearing Edge Case: There's a potential edge case in buffer management: if a tool call's JSON arguments are complete but its final end-tag (<|tool call end|>) is missing from the buffer, the entire buffer is cleared. This might lead to loss of subsequent tool call data if the stream is malformed or tokens arrive in a specific order. This was noted as a review comment.
  • State Management for Adapter: The state arrays prev_tool_call_arr and streamed_args_for_tool are now correctly managed for multiple tool calls, ensuring compatibility with adapter.py.

Merge Readiness

The pull request makes substantial improvements to DeepSeekV3 tool call detection. However, there's one medium-severity concern regarding buffer clearing in an edge case (detailed in the review comment) that could potentially lead to data loss for subsequent tool calls under specific circumstances. It would be beneficial to clarify or address this point before merging. I am unable to approve pull requests, so please ensure further review and approval from authorized maintainers after addressing any feedback.

Comment thread python/sglang/srt/function_call/deepseekv3_detector.py
@zhyncs zhyncs merged commit 461a730 into main May 28, 2025
29 of 41 checks passed
@zhyncs zhyncs deleted the chang/tool-dsv3 branch May 28, 2025 07:22
@CatherineSue CatherineSue mentioned this pull request May 28, 2025
7 tasks
Layssy pushed a commit to Layssy/sglang-iaas that referenced this pull request Jun 9, 2025
xwu-intel pushed a commit to xwu-intel/sglang that referenced this pull request Jun 17, 2025
AdamSSSun pushed a commit to AdamSSSun/sglang that referenced this pull request Jul 11, 2025
…e function call @20250708-1524 \n associate with this pr. sgl-project#6655
AdamSSSun pushed a commit to AdamSSSun/sglang that referenced this pull request Jul 11, 2025
…e function call @20250708-1524 \n associate with this pr. sgl-project#6655  in this version: 0.4.6.post1
AdamSSSun pushed a commit to AdamSSSun/sglang that referenced this pull request Jul 11, 2025
…le function call @20250708-1524 \n associate with this pr. sgl-project#6655 in this version: 0.4.6.post1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants