fix(mcp): accept legacy tool result data alias
All checks were successful
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / tests (push) Successful in 1m6s
CD Pipeline / build-and-deploy (push) Successful in 3m24s
CD Pipeline / post-deploy-checks (push) Successful in 1m17s

This commit is contained in:
Your Name
2026-05-06 16:02:27 +08:00
parent e5094c5c53
commit 927c2a758d
3 changed files with 51 additions and 1 deletions

View File

@@ -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,

View 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"

View File

@@ -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。