fix(mcp): accept legacy tool result data alias
This commit is contained in:
@@ -14,6 +14,7 @@ from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
@@ -41,12 +42,21 @@ class MCPToolResult:
|
||||
"""
|
||||
|
||||
success: bool
|
||||
execution_id: str
|
||||
execution_id: str = ""
|
||||
output: Any | None = None
|
||||
# 2026-05-06 Codex: 舊 provider 曾使用 data=... 作為成功輸出欄位。
|
||||
# 保留 alias,避免 provider 成功路徑因 dataclass 參數不相容而 crash。
|
||||
data: Any | None = None
|
||||
error: str | None = None
|
||||
duration: float = 0.0
|
||||
timestamp: datetime = field(default_factory=now_taipei)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not self.execution_id:
|
||||
self.execution_id = f"mcp-{uuid4()}"
|
||||
if self.output is None and self.data is not None:
|
||||
self.output = self.data
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"success": self.success,
|
||||
|
||||
28
apps/api/tests/test_mcp_tool_result_compat.py
Normal file
28
apps/api/tests/test_mcp_tool_result_compat.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from src.plugins.mcp.interfaces import MCPToolResult
|
||||
|
||||
|
||||
def test_mcp_tool_result_accepts_legacy_data_alias() -> None:
|
||||
result = MCPToolResult(success=True, data={"ok": True})
|
||||
|
||||
assert result.execution_id.startswith("mcp-")
|
||||
assert result.output == {"ok": True}
|
||||
assert result.to_dict()["output"] == {"ok": True}
|
||||
|
||||
|
||||
def test_mcp_tool_result_keeps_explicit_output_over_data_alias() -> None:
|
||||
result = MCPToolResult(
|
||||
success=True,
|
||||
execution_id="exec-1",
|
||||
output={"new": True},
|
||||
data={"legacy": True},
|
||||
)
|
||||
|
||||
assert result.execution_id == "exec-1"
|
||||
assert result.output == {"new": True}
|
||||
|
||||
|
||||
def test_mcp_tool_result_allows_failure_without_execution_id() -> None:
|
||||
result = MCPToolResult(success=False, error="blocked")
|
||||
|
||||
assert result.execution_id.startswith("mcp-")
|
||||
assert result.error == "blocked"
|
||||
@@ -1,3 +1,15 @@
|
||||
## 2026-05-06 | MCPToolResult 相容舊 provider 的 data alias
|
||||
|
||||
**背景**:AwoooP 整合風險 P0-D 指出部分 MCP provider 成功路徑仍使用 `MCPToolResult(data=...)`,但標準 dataclass 欄位是 `output` 且 `execution_id` 必填;Sentry / ArgoCD 等成功路徑可能因此在有效 API 回應後反而 crash。
|
||||
|
||||
**本次修補**:
|
||||
- `MCPToolResult` 對舊 provider 介面做向後相容:`data` 自動映射到 `output`。
|
||||
- 缺少 `execution_id` 時自動產生 `mcp-<uuid>`,避免失敗/blocked 回傳因建構 DTO 就爆掉。
|
||||
- 補回歸測試,鎖住 `data` alias、明確 `output` 優先,以及 failure without execution_id。
|
||||
|
||||
**後續**:
|
||||
- 這是相容層止血;後續仍應逐步把 provider call-sites 改成明確 `output=` 與穩定 `execution_id`。
|
||||
|
||||
## 2026-05-06 | CD 188 ops sync 防止 SSH 子程序停住
|
||||
|
||||
**背景**:`22453161` 的完整 CD 已完成 tests、API/Web image build、K8s GitOps deploy,但 `Sync Ops Scripts to 188` 卡住。現場 process 顯示 `timeout 30s ssh ... 192.168.0.188` 與子 `ssh` 進入 stopped 狀態,導致 job 無法前進到 post-deploy checks。
|
||||
|
||||
Reference in New Issue
Block a user