fix(openai): tool_call delta 重复携带 function.name,增强严格客户端兼容性

在 ToolCallStart 时记录 block_index 到 tool_name 的映射,
ToolCallDelta 时同步输出 function.name,避免严格客户端丢弃无 name 的 delta。
提取 _ss_dict 辅助方法统一 stream state 中 dict 字段的初始化逻辑。
This commit is contained in:
fawney19
2026-03-15 22:04:21 +08:00
parent d58c27d22d
commit 60842fbbb5
3 changed files with 30 additions and 15 deletions

View File

@@ -858,6 +858,7 @@ def test_tool_call_stream_index_stable_across_deltas() -> None:
# 收集所有 tool_calls chunk
tc_indices: list[int] = []
tc_ids: list[str] = []
tc_names: list[str] = []
for event in all_events:
for choice in event.get("choices", []):
tcs = choice.get("delta", {}).get("tool_calls")
@@ -865,6 +866,7 @@ def test_tool_call_stream_index_stable_across_deltas() -> None:
for tc in tcs:
tc_indices.append(tc["index"])
tc_ids.append(str(tc.get("id") or ""))
tc_names.append(str((tc.get("function") or {}).get("name") or ""))
assert len(tc_indices) >= 2, f"expected at least 2 tool_call chunks, got {len(tc_indices)}"
# 同一个 tool call 的所有 chunk 必须使用相同的 index
@@ -875,3 +877,7 @@ def test_tool_call_stream_index_stable_across_deltas() -> None:
"tool_call id should be repeated on every delta for strict OpenAI-compatible clients, "
f"got: {tc_ids}"
)
assert all(tc_name == "get_weather" for tc_name in tc_names), (
"tool_call function.name should be repeated on every delta for strict "
f"OpenAI-compatible clients, got: {tc_names}"
)

View File

@@ -332,6 +332,7 @@ def test_openai_stream_chunk_and_event_roundtrip_basic() -> None:
)
assert tool_delta["choices"][0]["delta"]["tool_calls"][0]["id"] == "call_1"
assert tool_delta["choices"][0]["delta"]["tool_calls"][0]["index"] == 0
assert tool_delta["choices"][0]["delta"]["tool_calls"][0]["function"]["name"] == "get_weather"
# 最终 stop chunk finish_reason=tool_calls
assert out_chunks[-1]["choices"][0]["finish_reason"] == "tool_calls"