debug: 修复流式传输语句重复的问题
This commit is contained in:
parent
485b07c12f
commit
a8f631a034
|
|
@ -140,6 +140,8 @@ async def chat_endpoint(request: Request):
|
|||
temperature=temperature
|
||||
)
|
||||
|
||||
full_content = "" # 用于累计完整内容
|
||||
|
||||
for idx, response in enumerate(responses):
|
||||
if response.status_code == 200:
|
||||
# 检查响应是否包含预期的内容
|
||||
|
|
@ -156,6 +158,29 @@ async def chat_endpoint(request: Request):
|
|||
'content' in response.output.choices[0]['message']):
|
||||
|
||||
content = response.output.choices[0]['message']['content']
|
||||
|
||||
# 只有当内容发生变化时才发送增量
|
||||
if len(content) > len(full_content):
|
||||
delta_content = content[len(full_content):]
|
||||
full_content = content
|
||||
|
||||
if delta_content.strip(): # 只有当有非空白新内容时才发送
|
||||
# 构建 SSE 数据块
|
||||
data = {
|
||||
"id": f"chatcmpl-{uuid.uuid4()}",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": int(datetime.utcnow().timestamp()),
|
||||
"model": model,
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"delta": {"content": delta_content},
|
||||
"finish_reason": None
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
yield f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
|
||||
# 否则尝试从 output.text 获取内容(DashScope特定格式)
|
||||
elif (hasattr(response, 'output') and
|
||||
response.output and
|
||||
|
|
@ -163,26 +188,28 @@ async def chat_endpoint(request: Request):
|
|||
|
||||
content = response.output.get('text')
|
||||
|
||||
if content:
|
||||
# 构建 SSE 数据块
|
||||
data = {
|
||||
"id": f"chatcmpl-{uuid.uuid4()}",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": int(datetime.utcnow().timestamp()),
|
||||
"model": model,
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"delta": {"content": content} if content else {},
|
||||
"finish_reason": None
|
||||
}
|
||||
]
|
||||
}
|
||||
# 只有当内容发生变化时才发送增量
|
||||
if len(content) > len(full_content):
|
||||
delta_content = content[len(full_content):]
|
||||
full_content = content
|
||||
|
||||
yield f"data: {json.dumps(data)}\n\n"
|
||||
else:
|
||||
# 如果响应中没有内容,跳过
|
||||
continue
|
||||
if delta_content.strip(): # 只有当有非空白新内容时才发送
|
||||
# 构建 SSE 数据块
|
||||
data = {
|
||||
"id": f"chatcmpl-{uuid.uuid4()}",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": int(datetime.utcnow().timestamp()),
|
||||
"model": model,
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"delta": {"content": delta_content},
|
||||
"finish_reason": None
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
yield f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
|
||||
else:
|
||||
# 错误处理
|
||||
error_data = {
|
||||
|
|
@ -193,7 +220,7 @@ async def chat_endpoint(request: Request):
|
|||
"code": response.code
|
||||
}
|
||||
}
|
||||
yield f"data: {json.dumps(error_data)}\n\n"
|
||||
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
|
||||
break
|
||||
|
||||
# 发送结束信号
|
||||
|
|
@ -210,9 +237,8 @@ async def chat_endpoint(request: Request):
|
|||
}
|
||||
]
|
||||
}
|
||||
yield f"data: {json.dumps(finish_data)}\n\n"
|
||||
yield f"data: {json.dumps(finish_data, ensure_ascii=False)}\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
|
||||
except Exception as e:
|
||||
error_data = {
|
||||
"error": {
|
||||
|
|
@ -220,7 +246,7 @@ async def chat_endpoint(request: Request):
|
|||
"type": "server_error"
|
||||
}
|
||||
}
|
||||
yield f"data: {json.dumps(error_data)}\n\n"
|
||||
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
|
||||
|
||||
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
||||
else:
|
||||
|
|
@ -272,7 +298,7 @@ async def chat_endpoint(request: Request):
|
|||
"totalTokens": response.usage.total_tokens
|
||||
}
|
||||
|
||||
return JSONResponse(content=chat_response)
|
||||
return JSONResponse(content=chat_response, ensure_ascii=False)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
|
|
|
|||
|
|
@ -164,6 +164,12 @@ class ChatApi {
|
|||
if (match) {
|
||||
try {
|
||||
const data = JSON.parse(match[1]);
|
||||
// 检查是否有完成原因,如果是完成则跳出
|
||||
const finishReason = data.choices?.[0]?.finish_reason;
|
||||
if (finishReason && finishReason !== "null") {
|
||||
break;
|
||||
}
|
||||
|
||||
const content = data.choices?.[0]?.delta?.content;
|
||||
if (content) {
|
||||
yield content;
|
||||
|
|
|
|||
Loading…
Reference in New Issue