From 81d9fa17be1285e163d15ecd531dec66a20a8aaa Mon Sep 17 00:00:00 2001 From: u1544096979 <14545695+u1544096979@user.noreply.gitee.com> Date: Fri, 4 Sep 2026 22:35:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(proxy):=20=E5=BF=BD=E7=95=A5=E7=A9=BA?= =?UTF-8?q?=E7=9A=84=E6=97=A7=E5=BC=8F=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/proxy/providers/streaming.rs | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/proxy/providers/streaming.rs b/src-tauri/src/proxy/providers/streaming.rs index fda7b435f..122c82118 100644 --- a/src-tauri/src/proxy/providers/streaming.rs +++ b/src-tauri/src/proxy/providers/streaming.rs @@ -481,7 +481,16 @@ pub fn create_anthropic_sse_stream( legacy_function_name = Some(name.clone()); } - if function_call.name.is_some() || function_call.arguments.is_some() { + let has_legacy_function_payload = function_call + .name + .as_deref() + .is_some_and(|name| !name.is_empty()) + || function_call + .arguments + .as_deref() + .is_some_and(|arguments| !arguments.is_empty()); + + if has_legacy_function_payload { if let Some(index) = current_non_tool_block_index.take() { let event = json!({ "type": "content_block_stop", @@ -1193,6 +1202,26 @@ mod tests { ); } + #[tokio::test] + async fn empty_legacy_function_call_does_not_emit_tool_use() { + let input = concat!( + "data: {\"id\":\"chatcmpl_1\",\"model\":\"glm-5.3-flash\",\"choices\":[{\"delta\":{\"content\":\"ok\",\"function_call\":null}}]}\n\n", + "data: {\"id\":\"chatcmpl_1\",\"model\":\"glm-5.3-flash\",\"choices\":[{\"delta\":{\"function_call\":{\"name\":\"\",\"arguments\":\"\"}},\"finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":1,\"completion_tokens\":1}}\n\n", + "data: [DONE]\n\n" + ); + + let events = collect_events(input).await; + assert!(!events.iter().any(|event| { + event["type"] == "content_block_start" + && event["content_block"]["type"] == "tool_use" + })); + assert!(events.iter().any(|event| { + event["type"] == "message_delta" + && event["delta"]["stop_reason"] == "end_turn" + })); + assert!(events.iter().any(|event| event["type"] == "message_stop")); + } + #[tokio::test] async fn legacy_function_call_stream_emits_tool_use_block_and_argument_delta() { let input = concat!(