zizi 367d01db21 W06 模型宿主、角色、预算与流式合同:模型宿主合同、角色策略冻结、预算预留结算与流式回合证据。
按 R2 串行阶段整理提交;包内文件为该阶段交付(含后续小增量),状态以工作包清单为准。
2026-09-10 19:25:41 +08:00

66 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Responses 的完成对象是最终依据;delta 仅用于过程显示。"""
import json
from collections.abc import Iterable
from muse.任务运行.接口 import 工具请求, 模型协议错误, 模型用量, 模型结果
def 解析响应(事件: Iterable[dict]) -> 模型结果:
响应 = None
片段 = []
for 项 in 事件:
类型 = 项.get("type")
if 类型 == "response.output_text.delta":
片段.append(项.get("delta", ""))
elif 类型 in {"response.completed", "response.failed", "response.incomplete"}:
响应 = 项.get("response")
if not isinstance(响应, dict):
raise 模型协议错误("Responses 终态缺少响应对象")
if 响应.get("status") != 类型.split(".")[1]:
raise 模型协议错误("Responses 事件与响应状态不一致")
elif 类型 == "error":
return 模型结果("failed", "".join(片段), None, None, 失败码=项.get("code"))
if 响应 is None:
return 模型结果("incomplete", "".join(片段), None, None, 失败码="TERMINAL_MISSING")
状态 = 响应["status"]
文本, 工具 = [], []
for 输出 in 响应.get("output", []):
if 输出.get("type") == "message":
for 内容 in 输出.get("content", []):
if 内容.get("type") == "output_text":
文本.append(内容["text"])
elif 内容.get("type") == "refusal":
状态 = "failed"
elif 输出.get("type") == "function_call":
try:
参数 = json.loads(输出["arguments"])
if not isinstance(参数, dict):
raise ValueError()
工具.append(工具请求(输出["call_id"], 输出["name"], 参数))
except (ValueError, KeyError):
raise 模型协议错误("模型工具调用参数不符合对象合同") from None
用量 = 响应.get("usage")
统计 = None
if 用量 is not None:
try:
统计 = 模型用量(
用量["input_tokens"],
用量["output_tokens"],
(用量.get("input_tokens_details") or {}).get("cached_tokens", 0),
)
except (KeyError, TypeError):
raise 模型协议错误("Responses 用量字段不完整") from None
if 工具 and 状态 == "completed":
状态 = "tool_calls"
return 模型结果(
状态,
"".join(文本),
响应.get("model"),
统计,
响应.get("id"),
tuple(工具),
回放协议="responses",
回放内容=tuple(响应.get("output", [])),
)