Fix GLM-4.6 tool calls don't support streaming output for arguments i…#13989
Conversation
Summary of ChangesHello @cynial, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a limitation in GLM-4.6 tool calls where streaming output for arguments was not supported at a character level, leading to a suboptimal user experience. The changes introduce a robust streaming mechanism that incrementally processes XML tool call fragments and converts them into JSON, enabling real-time output and improving the responsiveness of tool argument parsing. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a significant and well-executed refactoring to enable character-level streaming for GLM-4.6 tool call arguments. The implementation of a state machine for converting the XML-like format to JSON is a robust solution for incremental parsing. The code quality is high, with improved modularity through new helper functions, better error handling with specific exceptions, and comprehensive docstrings. The associated test cases have also been effectively updated to validate the new streaming behavior. I have one suggestion for a minor performance optimization.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
/tag-and-rerun-ci |
|
@JustinTong0323 Hi, could you please review this PR when you have a chance? Thanks |
|
@CatherineSue @JustinTong0323 Let me know if there's anything else I should do, or if you'd like me to make any other changes. I've been running this patch in production for a week now, and everything seems to be working well. If anything comes up, I'll post updates here. |
…n_eagle3_npu * 'main' of https://github.com/sgl-project/sglang: (25 commits) [NPU] perf update with kvcache nz & w4a8 quant (sgl-project#14423) [PP Prefill][NIXL] Fix PP mode transfer completion tracking to wait for all ranks (sgl-project#15027) Fix GLM-4.6 tool calls don't support streaming output for arguments i… (sgl-project#13989) feature: adding nightly wheel workflow and indexer (sgl-project#14924) [diffusion] feat: Improve LoRA compatibility by adding unified format detection and diffusers-based normalization (sgl-project#14659) [Fix] Disable trtllm moe backend for draft model for a qucik fix (sgl-project#15002) [diffusion] fix: use NDRotaryEmbedding in flux_2 (sgl-project#15034) Mistral Large 3 NVFP4 support (sgl-project#14485) call check_quantized_moe_compatibility after initialize (sgl-project#13876) Add sgl_router_attempt_http_responses_total for single attempt information (sgl-project#15037) Add error code in prometheus metrics and add X-SMG-Error-Code header (sgl-project#15036) Provide more fine grained error reason for reqwest error (sgl-project#15032) Tiny change http router response format to unify (sgl-project#15031) Tiny unify grpc existing error responses into new format (sgl-project#15030) Add `code` field and unify error responses for router (sgl-project#15028) Super tiny remove unused log_request (sgl-project#15035) Fix decode OOM caused by retraction (sgl-project#14939) [CI]Add gb200 runner back (sgl-project#15024) Add a special label for b200 CI runner that can run kernel tests (sgl-project#15033) Fix regression caused by fa3 block_table (sgl-project#15009) ... # Conflicts: # python/sglang/srt/hardware_backend/npu/attention/ascend_backend.py
|
@cynial Can the content of <arg_value> be modified to return a stream? Because in scenarios like file editing tools or file creation tools, the content that <arg_value> needs to return is often very large, leading to long wait times and a poor user experience. If streaming returns could be supported, we could show the user the process of file creation, for example: |
|
@gaoganlsz You can try this patch; it should work as you expect (perhaps my test case wasn't clear enough). |
sgl-project#13989) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
sgl-project#13989) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Motivation
The original
glm_moe_detector_old_normal.pyimplementation, unable to achieve character-level streaming output, resulting in suboptimal user experience:Modifications
1. Refactored
parse_streaming_increment()Method2. Introduced Streaming State Machine
Added a complete state machine to handle real-time XML to JSON conversion:
State Transition Flow:
INIT→IN_KEY→WAITING_VALUE→IN_VALUE→BETWEEN→ ...Flow Comparison Diagrams:
graph TD A[Receive new text] --> B[Append to buffer] B --> C{Found </tool_call>?} C -->|Yes| D[Call detect_and_parse<br/>Re-parse entire tool call] C -->|No| E[Return empty result] D --> F[Parse complete XML] F --> G[Extract function name and parameters] G --> H[Return complete result] H --> I[Update tool_id] style D fill:#ffcccc style F fill:#ffccccgraph TD A[Receive new text] --> B[Append to buffer] B --> C{Found <tool_call>?} C -->|No| D[Check if potential start] C -->|Yes| E{Tool name sent?} E -->|No| F[Send tool name] E -->|Yes| G[Get new XML fragment] G --> H[State machine processing] H --> I{Current state?} I -->|INIT/BETWEEN| J[Detect arg_key tag] I -->|IN_KEY| K[Collect key name] I -->|WAITING_VALUE| L[Detect arg_value tag] I -->|IN_VALUE| M[Process value content] M --> N{Value type?} N -->|string| O[Output quoted JSON string] N -->|number| P[Output number] N -->|object| Q[Output object/array] O --> R[Real-time JSON increment output] P --> R Q --> R R --> S{Encountered </tool_call>?} S -->|No| T[Continue waiting] S -->|Yes| U[Complete JSON structure] U --> V[Update tool_id and reset state] style H fill:#ccffcc style R fill:#ccffcc style N fill:#ffffccVerification
Checklist