|
|
|
|
|
""" |
|
|
测试多个工具调用的处理逻辑 |
|
|
""" |
|
|
|
|
|
import sys |
|
|
import os |
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|
|
|
|
|
from app.utils.sse_tool_handler import SSEToolHandler |
|
|
|
|
|
def test_multiple_tool_calls(): |
|
|
"""测试多个工具调用的处理""" |
|
|
|
|
|
handler = SSEToolHandler("test-model", stream=False) |
|
|
|
|
|
print("🧪 测试多个工具调用处理\n") |
|
|
|
|
|
|
|
|
test_chunks = [ |
|
|
|
|
|
{ |
|
|
"phase": "tool_call", |
|
|
"edit_content": '<glm_block view="">{"type": "mcp", "data": {"metadata": {"id": "call_5y5gir0mygx", "name": "mcp__playwright__browser_navigate", "arguments": "{\\"url\\":\\"https://www.bil", "result": "", "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 24 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "tool_call", |
|
|
"edit_content": 'ibili.com\\"}', |
|
|
"edit_index": 194 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "other", |
|
|
"edit_content": 'null, "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 219 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "tool_call", |
|
|
"edit_content": '<glm_block view="">{"type": "mcp", "data": {"metadata": {"id": "call_j8r24x6xtg", "name": "mcp__playwright__browser_snapshot", "arguments": "{}", "result": "", "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 406 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "other", |
|
|
"edit_content": 'null, "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 566 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "tool_call", |
|
|
"edit_content": '<glm_block view="">{"type": "mcp", "data": {"metadata": {"id": "call_scvwo0xaoil", "name": "mcp__playwright__browser_navigate", "arguments": "{\\"url\\":\\"https://www.bil", "result": "", "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 753 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "tool_call", |
|
|
"edit_content": 'ibili.com\\"}', |
|
|
"edit_index": 925 |
|
|
}, |
|
|
|
|
|
{ |
|
|
"phase": "other", |
|
|
"edit_content": 'null, "display_result": "", "duration": "...", "status": "completed", "is_error": false, "mcp_server": {"name": "mcp-server"}}, "thought": null, "ppt": null, "browser": null}}</glm_block>', |
|
|
"edit_index": 950 |
|
|
} |
|
|
] |
|
|
|
|
|
tool_calls_completed = [] |
|
|
|
|
|
for i, chunk in enumerate(test_chunks, 1): |
|
|
print(f"处理块 {i}: edit_index={chunk['edit_index']}, phase={chunk['phase']}") |
|
|
|
|
|
|
|
|
old_tool_id = handler.tool_id |
|
|
old_tool_name = handler.tool_name |
|
|
old_has_tool_call = handler.has_tool_call |
|
|
|
|
|
|
|
|
results = list(handler.process_sse_chunk(chunk)) |
|
|
|
|
|
|
|
|
if handler.tool_id != old_tool_id and handler.tool_id: |
|
|
print(f" 🎯 新工具调用开始: {handler.tool_name} (id: {handler.tool_id})") |
|
|
|
|
|
|
|
|
if old_has_tool_call and not handler.has_tool_call: |
|
|
tool_calls_completed.append({ |
|
|
"name": old_tool_name or "unknown", |
|
|
"id": old_tool_id |
|
|
}) |
|
|
print(f" ✅ 工具调用完成: {old_tool_name or 'unknown'}") |
|
|
|
|
|
print(f" 当前状态: has_tool_call={handler.has_tool_call}, tool_id={handler.tool_id}") |
|
|
print() |
|
|
|
|
|
print(f"📊 测试结果:") |
|
|
print(f" 完成的工具调用数量: {len(tool_calls_completed)}") |
|
|
for i, tool in enumerate(tool_calls_completed, 1): |
|
|
print(f" {i}. {tool['name']} (id: {tool['id']})") |
|
|
|
|
|
|
|
|
expected_tools = [ |
|
|
"mcp__playwright__browser_navigate", |
|
|
"mcp__playwright__browser_snapshot", |
|
|
"mcp__playwright__browser_navigate" |
|
|
] |
|
|
|
|
|
completed_tool_names = [tool['name'] for tool in tool_calls_completed] |
|
|
|
|
|
if completed_tool_names == expected_tools: |
|
|
print("\n✅ 测试通过!正确处理了所有工具调用") |
|
|
print("📝 结论:重复的工具调用是上游发送的,我们的处理逻辑是正确的") |
|
|
return True |
|
|
else: |
|
|
print(f"\n❌ 测试失败!") |
|
|
print(f" 期望: {expected_tools}") |
|
|
print(f" 实际: {completed_tool_names}") |
|
|
return False |
|
|
|
|
|
if __name__ == "__main__": |
|
|
success = test_multiple_tool_calls() |
|
|
|
|
|
if success: |
|
|
print("\n🎯 总结:") |
|
|
print("1. 我们的 API 代理正确处理了每个不同的工具调用") |
|
|
print("2. 重复的工具调用是上游 Z.AI 模型发送的,不是我们的问题") |
|
|
print("3. 每个工具调用都有不同的 ID,说明这是模型的有意行为") |
|
|
print("4. 可能的原因:模型重试、验证操作、或处理复杂任务的策略") |
|
|
else: |
|
|
print("\n❌ 需要进一步调试处理逻辑") |
|
|
|