refactor: 重构 Tool Result 契约,移除 ui_hints 统一使用 result 字段

- ToolAgentOutput 移除 result_summary 和 ui_hints,统一使用 result 字段
- 日历/用户查找工具移除 ui_hints 输出,改为机器可读的结构化结果
- Agent History 移除 tool 消息的 ui_hints 处理逻辑
- App 版本检查改为 manifest.json 方式,支持多渠道发布
- 更新 settings 配置和测试用例适配新结构
This commit is contained in:
qzl
2026-03-17 12:18:09 +08:00
parent c26cdbbc27
commit aa30fe0ce6
44 changed files with 984 additions and 655 deletions
@@ -54,10 +54,7 @@ def _is_agui_event(event: dict[str, Any]) -> bool:
def _sanitize_agui_event(event: dict[str, Any]) -> dict[str, Any]:
payload = dict(event)
event_type = str(payload.get("type", "")).strip().upper()
if event_type in {
EventType.TEXT_MESSAGE_END.value,
EventType.TOOL_CALL_RESULT.value,
}:
if event_type == EventType.TEXT_MESSAGE_END.value:
ui_hints = payload.get("ui_hints")
if ui_hints is not None:
try:
@@ -67,7 +64,6 @@ def _sanitize_agui_event(event: dict[str, Any]) -> dict[str, Any]:
except Exception:
pass
payload.pop("ui_hints", None)
if event_type == EventType.TEXT_MESSAGE_END.value:
for key in (
"inputTokens",
"outputTokens",
@@ -76,6 +72,9 @@ def _sanitize_agui_event(event: dict[str, Any]) -> dict[str, Any]:
"model",
):
payload.pop(key, None)
if event_type == EventType.TOOL_CALL_RESULT.value:
payload.pop("ui_hints", None)
payload.pop("ui_schema", None)
return payload
@@ -130,10 +129,13 @@ def _build_text_end(event: dict[str, Any]) -> TextMessageEndEvent:
def _build_tool_result(event: dict[str, Any]) -> ToolCallResultEvent:
data = event.get("data", {})
content = data.get("result")
if not isinstance(content, str):
content = data.get("toolAgentOutput", "")
return ToolCallResultEvent(
message_id=data.get("messageId", ""),
tool_call_id=data.get("toolCallId", ""),
content=data.get("toolAgentOutput", ""),
content=content,
role="tool",
)
@@ -191,7 +193,7 @@ def to_agui_wire_event(event: dict[str, Any] | BaseEvent) -> dict[str, Any]:
tool_result_payload["threadId"] = thread_id
if isinstance(run_id, str) and run_id:
tool_result_payload["runId"] = run_id
reserved = {"type", "threadId", "runId"}
reserved = {"type", "threadId", "runId", "ui_hints", "ui_schema"}
tool_result_payload.update({k: v for k, v in data.items() if k not in reserved})
return tool_result_payload
+2 -3
View File
@@ -213,9 +213,8 @@ class SqlAlchemyEventStore:
"tool_call_id": self._event_value(event, "tool_call_id"),
"tool_call_args": self._event_value(event, "tool_call_args"),
"status": self._event_value(event, "status"),
"result_summary": self._event_value(event, "result_summary"),
"result": self._event_value(event, "result"),
"error": self._event_value(event, "error"),
"ui_hints": self._event_value(event, "ui_hints"),
}
try:
@@ -231,7 +230,7 @@ class SqlAlchemyEventStore:
)
return
content = tool_output.result_summary
content = tool_output.result
locked_session = await session_repo.lock_session_for_update(
session_id=session_id