fix(stream): 跳过空 choices 的 SSE 帧并记录 usage,避免流式解析越界
This commit is contained in:
@@ -270,7 +270,15 @@ async def _default_stream_response_handler(
|
|||||||
# 如果中断量被设置,则抛出ReqAbortException
|
# 如果中断量被设置,则抛出ReqAbortException
|
||||||
_insure_buffer_closed()
|
_insure_buffer_closed()
|
||||||
raise ReqAbortException("请求被外部信号中断")
|
raise ReqAbortException("请求被外部信号中断")
|
||||||
|
# 空 choices / usage-only 帧的防御
|
||||||
|
if not getattr(event, "choices", None) or len(event.choices) == 0:
|
||||||
|
if getattr(event, "usage", None):
|
||||||
|
_usage_record = (
|
||||||
|
event.usage.prompt_tokens or 0,
|
||||||
|
event.usage.completion_tokens or 0,
|
||||||
|
event.usage.total_tokens or 0,
|
||||||
|
)
|
||||||
|
continue # 跳过本帧,避免访问 choices[0]
|
||||||
delta = event.choices[0].delta # 获取当前块的delta内容
|
delta = event.choices[0].delta # 获取当前块的delta内容
|
||||||
|
|
||||||
if hasattr(delta, "reasoning_content") and delta.reasoning_content: # type: ignore
|
if hasattr(delta, "reasoning_content") and delta.reasoning_content: # type: ignore
|
||||||
|
|||||||
Reference in New Issue
Block a user