From 2052b5b140fe140e66d83be5a96079bc4877dd2c Mon Sep 17 00:00:00 2001 From: chenchen Date: Tue, 12 May 2026 15:49:42 +0800 Subject: [PATCH] feat(web,docs): adaptive task polling + contract patch list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - task-card-view: refetchInterval now adapts to state — 3s for running/awaiting_approval, stop on completed/failed, 15s otherwise. Approval requests now surface within 3s instead of up to 15. - docs: collect every Manager-side compat patch (deeplink mapping, redact fallback, polling-vs-SSE) so mcp-server team can fold them back into the contract. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../manager-side-contract-patches.md | 61 +++++++++++++++++++ .../src/features/tasks/task-card-view.tsx | 7 ++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 docs/integration/manager-side-contract-patches.md diff --git a/docs/integration/manager-side-contract-patches.md b/docs/integration/manager-side-contract-patches.md new file mode 100644 index 0000000..58eff51 --- /dev/null +++ b/docs/integration/manager-side-contract-patches.md @@ -0,0 +1,61 @@ +# Manager → mcp-server 契约补丁清单 + +> 来源:Heicode Manager 前端集成 §1–§6 时打的本地 patch。建议 mcp-server 侧把这些归一掉,前端就能删掉对应的兼容层。 + +## 1. `manager_actions[].deeplink` 命名空间 + +**当前现象**:mcp-server 返回的 deeplink 形如 `/manager/resources`、`/manager/wallet`、`/manager/audit`。 + +**Manager 实际路由**:`/sk-sources`、`/wallet`、`/audit`。 + +**前端兜底**:`src/features/tasks/task-card-view.tsx::normalizeDeeplink()` 做了映射表。 + +**建议**:mcp-server 直接返回 Manager 真实路径,或返回 `{kind: 'resources' | 'wallet' | 'audit', ...}` 让前端自己拼。前者更简单。 + +| mcp-server 现返回 | Manager 应跳 | +|---|---| +| `/manager/resources` | `/sk-sources` | +| `/manager/wallet` | `/wallet` | +| `/manager/audit` | `/audit` | +| `/manager/tasks/{id}` | `/tasks/{id}` | + +## 2. §5 审计日志的敏感字段 redact + +**当前现象**:mcp-server `/api/agnet/audit` 返回的条目里 `payload` 字段可能包含 token / secret 原文(按 §5 设计应在服务端 mask)。 + +**前端兜底**:`src/features/agnet-console/pages.tsx::maskIfSecret()` 做了第二层 mask(按 key 名匹配 `secret|token|password|api_key`)。 + +**建议**:mcp-server 在写审计或读出时统一 mask,前端可以删掉那一层。 + +## 3. §6 任务卡 `manager_actions` 形状一致性 + +**当前确认**:HeicodeTaskCard 真实形状是 `{goal, scope, generated_artifacts, manager_actions: [{label, deeplink}]}`,前端已对齐。 + +**建议**:在 mcp-server contract 文档 §6 里把这个形状固定下来,避免后续漂移。 + +## 4. §4 usage 字段名 + +**当前消费**:`{date, total_quota, total_tokens, prompt_tokens, completion_tokens, count}`。 + +**Manager 用**:sparkline 取 `total_quota`、tooltip 拼 `date` + `formatQuota(total_quota)`。 + +**建议**:维持当前字段名即可。如果未来引入按模型聚合,建议另起 endpoint,不要在 `items` 里混。 + +## 5. §5 `/api/agnet/*` stub 数据 + +**当前**:mcp-server 内存 dict(按 §5.0 设计),无 agent-manager 真实转发。 + +**阻塞解除条件**: +- agent-manager 侧给 mcp-server 派发 service token +- mcp-server 把 stub 换成对 `20.212.121.126:80` 的真实转发(HTTP/80,Host 头 `agent-manager.taijiagnet.com`) + +Manager 前端已按 §5 契约消费,stub → 真实数据无需前端改动。 + +## 6. SSE `/api/user/tasks/{id}/events` 状态 + +**当前**:Manager 用 `refetchInterval` 自适应轮询替代(active 状态 3 秒,terminal 状态停止,其它 15 秒)。 + +**建议**:mcp-server 把 SSE 帧格式(event name、data shape)写进契约文档,前端再切到 EventSource / fetch stream。事件至少要覆盖: +- `status_changed`(包含新 status) +- `followup_added`(包含 followup payload) +- `card_updated`(包含完整 HeicodeTaskCard) diff --git a/heicode/web/default/src/features/tasks/task-card-view.tsx b/heicode/web/default/src/features/tasks/task-card-view.tsx index b44fe25..3c614f9 100644 --- a/heicode/web/default/src/features/tasks/task-card-view.tsx +++ b/heicode/web/default/src/features/tasks/task-card-view.tsx @@ -158,7 +158,12 @@ export function TaskCardView() { const { data: task, isLoading } = useQuery({ queryKey: ['heicode', 'task', id], queryFn: () => getHeicodeTask(id), - refetchInterval: 15_000, + refetchInterval: (q) => { + const status = (q.state.data as HeicodeTask | undefined)?.status + if (status === 'completed' || status === 'failed') return false + if (status === 'running' || status === 'awaiting_approval') return 3_000 + return 15_000 + }, }) const answerMutation = useMutation({