Skip to content

建立可信真实 E2E:修复 TUI harness,并覆盖 ZimoOS MCP 工具名兼容 #27

Description

@zhuqingyv

Problem

当前测试结论容易混淆两类问题:

  1. 真实功能集成问题:MA 接入 mteam/ZimoOS 时,MCP 原始工具名是 zimoos.current / zimoos.act / zimoos.search,但 OpenAI-compatible provider 要求 function name 只能匹配 ^[A-Za-z0-9_-]+$。如果直接暴露 mteam-primary__zimoos.current,DeepSeek 会在请求前拒绝。
  2. E2E harness 失效问题:现有 test/e2e.shtest/e2e-real.ts 不能可靠代表真实可用性。一个卡在 TUI prompt 匹配,另一个写死旧路径直接启动失败。

目标不是简单修一个脚本,而是建立可信的真实 e2e 分层:普通 MA run、真实 CLI agent benchmark、TUI smoke、真实 mteam/ZimoOS MCP 集成各自证明不同事情,报告时不能互相替代。

Evidence

本地实测证据(2026-07-02):

  • PATH=/Users/zhuqingyu/dev/my-agent/bin:$PATH TIMEOUT_DEFAULT=90 E2E_DEBUG=1 bash test/e2e.sh

    • 结果:0 pass, 4 fail
    • 失败点:全部是 <<TIMEOUT waiting for prompt>>,未进入发送用户输入阶段。
    • 结论:这是 TUI prompt harness 不兼容当前界面,不是模型任务失败证据。
  • npm run e2e:real

    • 结果:0 pass, 3 fail
    • 错误:node-pty posix_spawnp failed
    • 代码证据:test/e2e-real.ts 写死 /Users/zhuqingyu/project/my-agent/Users/zhuqingyu/project/supercell,当前仓库在 /Users/zhuqingyu/dev/my-agent
  • 真实 non-interactive MA run 通过:

    • node dist/src/cli/index.js run --config ~/.my-agent/benchmark-ma-config.json --prompt "你好,用一句中文回答你是谁"
    • node dist/src/cli/index.js run --config ~/.my-agent/benchmark-ma-config.json --prompt "请查看当前目录..."
    • 第二条实际调用了 fs__list_directory
  • 真实 L3 benchmark 通过:

    • npm run benchmark -- --level L3 --task L3-009 --adapter test/benchmark/adapters/ma.yaml --runs 1
    • 最新结果:score 0.985,passRate 1.0
    • report:test/benchmark/reports/2026-07-02T12-59-09-942Z-d404d2/
  • 真实 mteam/ZimoOS e2e 初次失败:

    • DeepSeek 返回:400 Invalid 'tools[9].function.name': string does not match pattern. Expected a string that matches the pattern '^[a-zA-Z0-9_-]+$'.
    • 根因:MCP tool name 含 .,例如 zimoos.current
  • 修复后真实 mteam/ZimoOS e2e 通过:

    • 本地 mteam backend:127.0.0.1:58590
    • MA 通过 mteam-primary stdio MCP 调用 zimoos.current
    • provider 可见工具名:mteam-primary__zimoos_x2e_current
    • MCP 原始执行工具名仍是:zimoos.current
    • 返回:title = zimoos HomevisibleContent = 16,真实 frameCursor = zos-solo-ma-zimoos-e2e-ma-zimoos-e2e:home:cursor:0001
    • debug log 出现:runtime slot updated: zimoos.currentFrame
    • 下一轮 request 出现:[ZimoOS Current Frame]

相关文件:

  • src/agent/tool-router.ts
  • src/agent.ts / mcpToolsToOpenAI
  • src/agent/runtime-context-slots.ts
  • src/agent/tool-executor.ts
  • src/agent/message-store.ts
  • test/e2e.sh
  • test/e2e-real.ts
  • test/benchmark/adapters/ma.yaml
  • test/benchmark/README.md
  • AGENT.md

Architecture Direction

把 e2e 分成四层,不再用一个脚本承载所有“真实可用”含义:

  1. MA run smoke

    • 入口:node dist/src/cli/index.js run --config ... --prompt ...
    • 证明:provider 可用、主循环可完成、基础工具可调用、final answer 格式可解析。
    • 不证明:TUI 渲染、PTY 输入、ZimoOS MCP。
  2. L3 real benchmark

    • 入口:npm run benchmark -- --level L3 --adapter test/benchmark/adapters/ma.yaml ...
    • 证明:真实 CLI agent 在临时工程里改代码、跑 objective checks、接受真实 judge。
    • 不证明:交互式 TUI。
  3. TUI PTY smoke

    • 入口:node-pty 驱动当前仓库 bin/madist/src/cli/index.js
    • 证明:TUI 可启动、用户能输入、能看到进度/完成/失败摘要、ESC/quit 生效。
    • 只做少量 smoke,不作为复杂任务质量评分来源。
  4. ZimoOS MCP integration e2e

    • 入口:MA 临时 config + mteam-primary stdio MCP + 本地 mteam backend。
    • source of truth:mteam 返回的真实 protocol: "zimoos/os-frame" OSFrame。
    • 证明:MCP 原始工具名兼容 provider schema,MA 能调用 zimoos.current,live slot 更新,下一轮 request 注入最新 frame,历史 tool result 只保留 audit。

Reuse / Mature Solution Plan

优先复用现有项目结构,不新增一套孤立 runner:

  • 复用 test/benchmark/README.mdAGENT.md 的证据规则:dry-run/unit/mock 不等于真实可用。
  • 复用 ma run --prompt --config 作为非交互真实 smoke,避免 TUI 控制问题污染 provider/tool 判断。
  • 复用 test/benchmark/adapters/ma.yaml 和 L3 runner 做真实任务质量验证。
  • 复用 node-pty 做 TUI smoke,替换过时的 expect prompt 匹配。
  • 复用 mteam-primary stdio MCP,保持 mteam 对外工具面仍是 zimoos.current / zimoos.act / zimoos.search
  • 工具名兼容层放在 MA 的 MCP router/adapter 边界,不改 mteam 工具名,不要求 provider 接受非标准 function name。

Implementation Checklist

  • 工具名兼容正式落地

    • src/agent/tool-router.ts 提供统一 mcpToolFunctionName(serverName, toolName)
    • mcpToolsToOpenAI() 只暴露 provider-safe function name。
    • routeToolCall() / findToolSchema() 能从 provider-safe name 路由回原始 MCP tool name。
    • 覆盖 zimoos.current -> zimoos_x2e_current,并保证普通 fs__read_file 不变。
  • 修复 TUI e2e harness

    • 废弃或重写 test/e2e.sh,不要依赖过时 ❯|> prompt。
    • 使用 node-pty 统一驱动当前仓库 CLI。
    • 用稳定状态信号判断 ready/done,例如 session banner、输入框可见、task:done 显示、完成、failure summary,而不是单一 prompt 字符。
    • 输出失败时保留 tail、exit code、是否已发送用户输入。
  • 修复 test/e2e-real.ts

    • 删除 /Users/zhuqingyu/project/... 硬编码。
    • process.cwd() / repo root 推导 TSX、CLI、fixture 工作区。
    • 如果 node-pty 当前环境不可用,要明确 skip 并说明原因,不得伪装为 agent 功能失败。
  • 增加真实 ZimoOS MCP e2e

    • 测试前探测 http://127.0.0.1:58590/api/panel/zimoos/current
    • 若 mteam backend 不在,明确 skip:requires: mteam_backend
    • 临时生成 MA config,接入 mteam-primary stdio MCP。
    • prompt 要求调用 zimoos.current,断言输出包含真实 frameCursor/title/visibleContent count。
    • 断言 debug/trace 中有 runtime slot updated: zimoos.currentFrame
    • 断言下一轮 request 有 [ZimoOS Current Frame],tool history 是 audit-only,不包含完整 OSFrame JSON。
  • 报告分层

    • summary 中分别列出 unitma run smokeL3 benchmarkTUI smokeZimoOS MCP e2e
    • 任一层失败时必须标明失败层和失败原因,不允许写“e2e 全失败/功能全失败”这种混合结论。

Validation

必须跑:

npm run build
npm test
npx tsx --test test/benchmark/runner/__tests__/*.test.ts
npx tsx test/benchmark/runner/index.ts --dry-run
node dist/src/cli/index.js run --config ~/.my-agent/benchmark-ma-config.json --prompt "你好,用一句中文回答你是谁"
node dist/src/cli/index.js run --config ~/.my-agent/benchmark-ma-config.json --prompt "请查看当前目录,列出最多5个顶层文件或目录,并说明你是通过工具看到的"
npm run benchmark -- --level L3 --task L3-009 --adapter test/benchmark/adapters/ma.yaml --runs 1

如果本机 mteam backend 正在运行,还必须跑:

curl -sS -X POST http://127.0.0.1:58590/api/panel/zimoos/current \
  -H 'content-type: application/json' \
  -d '{"teamId":"local","agentId":"ma-e2e","instanceId":"ma-e2e"}'

并跑 MA + mteam-primary stdio MCP 的真实 ZimoOS e2e。若 backend 不在,只能 skip 这一层,不能用 mock OSFrame 替代真实结论。

Acceptance Criteria

  • DeepSeek/OpenAI-compatible 不再因 mteam/ZimoOS tool name 含 . 报 provider schema 错。
  • zimoos.current 无参工具能首轮执行,不被 empty-args retry 延迟。
  • 真实 ZimoOS e2e 能证明:调用 mteam-primary MCP、拿到真实 OSFrame、更新 live slot、下一轮 request 注入 [ZimoOS Current Frame]
  • test/e2e.sh 不再作为过时 prompt matcher 保留;要么迁移到 node-pty,要么明确退役。
  • test/e2e-real.ts 不再有用户机器绝对路径硬编码。
  • e2e 报告能区分 harness failure、provider failure、tool routing failure、task quality failure。
  • 文档明确:dry-run/unit/mock 不能代表真实 e2e。

Non-goals

  • 不在本 issue 完整重构 append-only 主上下文;那仍属于 重构 MA 上下文为线性追加,并适配 ZimoOS 实时虚拟界面 #26 后续阶段。
  • 不修改 mteam 的公开工具名,不能把 zimoos.current 改成 MA 专属命名。
  • 不把 renderer DOM、截图原文、TeamCanvas omniscient 状态塞进 MA。
  • 不把复杂 L3 质量 gate 和 TUI smoke 混成一个分数。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions