Spaces:
Paused
Paused
File size: 8,298 Bytes
fd21f34 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
#!/usr/bin/env python3
"""
测试 done 阶段处理
"""
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
import json
def test_done_phase_handling():
"""测试 done 阶段的处理"""
handler = SSEToolHandler("test-model", stream=True)
print("🧪 测试 done 阶段处理\n")
# 模拟完整的对话流程
test_chunks = [
# 回答阶段
{
"phase": "answer",
"delta_content": "这是回答内容",
"edit_content": ""
},
# 完成阶段
{
"phase": "done",
"done": True,
"delta_content": "",
"usage": {
"prompt_tokens": 100,
"completion_tokens": 50,
"total_tokens": 150
}
}
]
output_chunks = []
for i, chunk in enumerate(test_chunks, 1):
print(f"处理块 {i}: phase={chunk['phase']}")
results = list(handler.process_sse_chunk(chunk))
output_chunks.extend(results)
print(f" 输出数量: {len(results)}")
for j, result in enumerate(results):
if result.strip() == "data: [DONE]":
print(f" 输出 {j+1}: [DONE] 标记")
else:
print(f" 输出 {j+1}: {result[:80]}{'...' if len(result) > 80 else ''}")
print()
print(f"📊 测试结果:")
print(f" 总输出块数量: {len(output_chunks)}")
# 验证输出内容
has_content = False
has_final_chunk = False
has_done_marker = False
has_usage = False
for output in output_chunks:
if output.startswith("data: "):
json_str = output[6:].strip()
if json_str == "[DONE]":
has_done_marker = True
print(" ✅ 找到 [DONE] 标记")
elif json_str:
try:
data = json.loads(json_str)
if "choices" in data and data["choices"]:
delta = data["choices"][0].get("delta", {})
content = delta.get("content", "")
finish_reason = data["choices"][0].get("finish_reason")
if content:
has_content = True
print(f" ✅ 找到内容: '{content}'")
if finish_reason == "stop":
has_final_chunk = True
print(" ✅ 找到最终完成块")
if "usage" in data:
has_usage = True
print(f" ✅ 找到 usage 信息: {data['usage']}")
except json.JSONDecodeError as e:
print(f" ❌ JSON 解析错误: {e}")
# 验证结果
success = has_content and has_final_chunk and has_done_marker
print(f"\n📋 验证结果:")
print(f" 包含回答内容: {'✅' if has_content else '❌'}")
print(f" 包含最终完成块: {'✅' if has_final_chunk else '❌'}")
print(f" 包含 [DONE] 标记: {'✅' if has_done_marker else '❌'}")
print(f" 包含 usage 信息: {'✅' if has_usage else '❌'}")
if success:
print("\n✅ done 阶段处理测试通过!")
return True
else:
print("\n❌ done 阶段处理测试失败!")
return False
def test_done_phase_with_tool_call():
"""测试带工具调用的 done 阶段处理"""
handler = SSEToolHandler("test-model", stream=True)
print("🧪 测试带工具调用的 done 阶段处理\n")
# 模拟工具调用 + 回答 + 完成的流程
test_chunks = [
# 工具调用开始
{
"phase": "tool_call",
"edit_content": '<glm_block view="">{"type": "mcp", "data": {"metadata": {"id": "call_test", "name": "test_tool", "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": 100
},
# 工具调用结束
{
"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": 200
},
# 回答阶段
{
"phase": "answer",
"delta_content": "工具调用完成,这是回答。",
"edit_content": ""
},
# 完成阶段
{
"phase": "done",
"done": True,
"delta_content": ""
}
]
output_chunks = []
for i, chunk in enumerate(test_chunks, 1):
print(f"处理块 {i}: phase={chunk['phase']}")
results = list(handler.process_sse_chunk(chunk))
output_chunks.extend(results)
print(f" 输出数量: {len(results)}")
print()
# 检查是否有工具调用、回答内容和完成标记
has_tool_call = any("tool_calls" in output for output in output_chunks)
has_answer_content = any("工具调用完成" in output for output in output_chunks)
has_done_marker = any(output.strip() == "data: [DONE]" for output in output_chunks)
print(f"📊 混合流程测试结果:")
print(f" 包含工具调用: {'✅' if has_tool_call else '❌'}")
print(f" 包含回答内容: {'✅' if has_answer_content else '❌'}")
print(f" 包含 [DONE] 标记: {'✅' if has_done_marker else '❌'}")
success = has_tool_call and has_answer_content and has_done_marker
if success:
print("\n✅ 混合流程 done 阶段测试通过!")
return True
else:
print("\n❌ 混合流程 done 阶段测试失败!")
return False
def test_done_phase_warning_fix():
"""测试 done 阶段不再产生警告"""
handler = SSEToolHandler("test-model", stream=True)
print("🧪 测试 done 阶段警告修复\n")
# 模拟 done 阶段
chunk = {
"phase": "done",
"done": True,
"delta_content": ""
}
print("处理 done 阶段块...")
# 捕获日志输出(这里我们主要检查是否有异常)
try:
results = list(handler.process_sse_chunk(chunk))
print(f" 成功处理,输出 {len(results)} 个块")
# 检查是否有 [DONE] 标记
has_done = any(output.strip() == "data: [DONE]" for output in results)
print(f" 包含 [DONE] 标记: {'✅' if has_done else '❌'}")
print("\n✅ done 阶段不再产生警告!")
return True
except Exception as e:
print(f"\n❌ 处理 done 阶段时出错: {e}")
return False
if __name__ == "__main__":
print("🔧 测试 done 阶段处理\n")
test1_success = test_done_phase_handling()
print("\n" + "="*50 + "\n")
test2_success = test_done_phase_with_tool_call()
print("\n" + "="*50 + "\n")
test3_success = test_done_phase_warning_fix()
print("\n" + "="*50)
print("🎯 总结:")
print(f" done 阶段基本处理: {'✅ 通过' if test1_success else '❌ 失败'}")
print(f" done 阶段混合流程: {'✅ 通过' if test2_success else '❌ 失败'}")
print(f" done 阶段警告修复: {'✅ 通过' if test3_success else '❌ 失败'}")
if test1_success and test2_success and test3_success:
print("\n🎉 所有测试通过!done 阶段处理完善!")
print("\n💡 修复效果:")
print(" - 不再显示 '未知的 SSE 阶段: done' 警告")
print(" - 正确处理对话完成流程")
print(" - 自动刷新缓冲区和完成工具调用")
print(" - 发送标准的 OpenAI 完成标记")
else:
print("\n❌ 部分测试失败,需要进一步调试")
|