Skip to content

V1.5-clean — 干净重构(撤回 fast,重做 100% PRD 对照)#1

Merged
bcefghj merged 18 commits into
mainfrom
v1.5-clean
May 6, 2026
Merged

V1.5-clean — 干净重构(撤回 fast,重做 100% PRD 对照)#1
bcefghj merged 18 commits into
mainfrom
v1.5-clean

Conversation

@bcefghj

@bcefghj bcefghj commented May 6, 2026

Copy link
Copy Markdown
Owner

V1.5-clean — 干净重构

重要:本 PR 撤回了 composer-2-fast 在 v1-rewrite 上的 22 文件改动,从 origin/main 起步用 claude-opus-4-7 重做,7 角度批判 + 100% PRD 对照。

一句话差异

旧版(fast):bot 沉默、硬编码 IP 死链、假联网、假 24 SKILL 集成。
新版(clean):5 闸门 IntentRouter 不沉默、MiniMax-only LLM、真 DDG/Bing 联网、真飞书 OpenAPI 三件套、反向 MCP server :8003 暴露给评委 Cursor。

测试

  • ✅ 131 单元测试全绿
  • ✅ 7 竞赛 e2e 全绿
  • ✅ T1-T20 链路烟雾 20/20(scripts/run_t20_smoke.py
  • ✅ 服务器 8.136.98.175 部署完成(dashboard :8001、MCP :8003、systemd Restart=always)
  • ⏳ 真机飞书消息(待 .env 飞书新 secret + 阿里云安全组开 80)

14 个独立 commit

phase 0: 凭据安全、本地清理、回滚 fast
phase 1.1 LLM MiniMax-only
phase 1.2 web_search DDG + Bing
phase 1.3 IntentRouter 5 闸门 + CHAT verdict
phase 1.4+1.5 bot 删硬编码 IP + LLM judge + idempotency
phase 1.6 Planner LLM-driven + 8 例 few-shot
phase 1.7 doc/slide 接 search_results
phase 1.8 web.search + media.tts 注册
phase 1.9 状态机 10 状态 + LEGAL_TRANSITIONS
phase 1.10 cards 过滤空 URL + context_confirm
phase 1.11 dashboard 中文化 + heartbeat
phase 2.1 反向 MCP server :8003 + 4 工具白名单
phase 2.2 lark.* 飞书 OpenAPI 真集成
phase 2.3 OPENCLAW_COMPAT.md 字段对照
phase 3.1 + 3.2 服务器部署脚本 + systemd unit + nginx
phase 4.1 + 4.2 T1-T20 + JUDGE_TEST_REPORT.md
phase 5 CHANGELOG-v1.5.md

不做项(明确)

LaTeX PDF / 动画展示页 / 答辩视频 / 24 SKILL submodule / openclaw-lark submodule / Workforce GAN 默认 / Promptfoo 红队 14 用例。

安全行动(用户操作)

  • GitHub Settings → PAT 吊销 ghp_rneAaz...PFLu
  • 飞书开发者后台轮换 App Secret(ctcVIY...HQ 已明文)
  • 阿里云控制台 ECS 安全组开 80/tcp(OS 防火墙已开,云端再开一次)

合并后

  • v1.5.0 tag 指向合并 commit
  • 删除远程 archive/v4-pre-prd-2026-04v1-rewrite 分支

详见 CHANGELOG-v1.5.mdJUDGE_TEST_REPORT.md

bcefghj and others added 18 commits May 7, 2026 05:20
…penai 死分支

- 移除多 provider 抽象层(V1 时期挂的三套分支线上从未验证过)
- 仅保留 MiniMax 的 OpenAI 兼容 endpoint /v1/chat/completions
- LLM_MOCK=1 / 缺 MINIMAX_API_KEY 触发 mock,CI 与离线可跑
- 重试预算 30s,429/5xx 指数退避 max 3 次
- .env.example 同步收敛为 MiniMax-only + 显式 DASHBOARD_PUBLIC_BASE

Co-authored-by: Cursor <cursoragent@cursor.com>
- 不再叫 minimax_mcp(命名诚实化:HTTP 抓 HTML 而非 MCP 协议)
- WebSearcher.search() 双兜底,全失败返空 list 不抛异常
- 单测 6 条覆盖 DDG/Bing 解析、k 截断、双失败、空 query

Co-authored-by: Cursor <cursoragent@cursor.com>
- 重写为 5 闸门:命令 → 显式 → 关键字快速通道 → LLM 判定 → 闲聊兜底
- 新增 IntentVerdict.CHAT / COMMAND,业务变更:闲聊不再沉默
- 信息充分性 _has_topic:去掉 form/verb/filler 后剩余 ≥ 3 字符或长度 ≥ 14 才允许闸门 3 短路 READY
- TIMELY_RE 时效性检测 → IntentResult.needs_web_search
- 强/弱 form 词分层 + 占位词剥离,避免 "帮我做个 PPT" 单词命中误启
- LLMJudgeFn 注入式接口,本模块不依赖 LLM client 便于测试
- CooldownStore 区分群聊 300s / 单聊 10s
- 单测 22 条覆盖 5 闸门 + cooldown + 业务变更场景

Co-authored-by: Cursor <cursoragent@cursor.com>
…AT 路径

bot.py:
- 删除 http://118.178.242.26 硬编码,URL 全部走 _public_dashboard_url() 读 DASHBOARD_PUBLIC_BASE
- 注入 _llm_judge(MiniMax 8s timeout + 内存 LRU cache 10min)作为 IntentRouter 闸门 4
- 内存版 _is_dup:60s 内同 (sender, md5(text)) 去重,避免连发触发多次
- _collect_artifacts:去重 + 过滤空 URL + 相对 /artifacts 自动拼绝对(修 []( ) 空链接 bug)
- plan_launcher 透传 needs_web_search

router.py:
- IntentVerdict.CHAT → text_reply 直发友好回复(绝不沉默)
- COMMAND verdict 在 router 层处理 help/status/claim/pause/resume/ignore
- 卡片 actions 扩到 PRD §6/§7 全集:pilot.ctx.add/confirm/adjust + pilot.task.*
- _launch 兼容新旧 plan_launcher 签名(needs_web_search optional)

附带:替换 docs/ 与 flutter_client/ 中 6 处旧 IP 为新服务器 8.136.98.175

Co-authored-by: Cursor <cursoragent@cursor.com>
…工具白名单

- 启发式:检测到 TIMELY_RE(最新/今年/2026/...)或 meta.needs_web_search=True →
  自动插 web.search 第 0 步,并把 ${s1.results} 透传给 doc.append/slide.generate.search_results
- _inject_web_search 兜底:LLM 漏插 web.search 时调用方可补一步
- KNOWN_TOOLS 加 web.search / media.tts / lark.im.fetch_thread / lark.doc.search / lark.bitable.search
- system prompt 重写为 8 例 few-shot:含 OpenClaw 联网、群聊整理、PRD 转 PPT、多维表格月报
- TIMELY_RE 收窄:去掉"趋势/进展/新出"避免长期话题误触发,保留显式时效词
- 单测:test_plan_timely_keyword_triggers_web_search / test_plan_meta_forces_web_search / test_plan_no_web_search_when_no_timely

Co-authored-by: Cursor <cursoragent@cursor.com>
doc.append:
- 新增 search_results 参数(list[{title,url,snippet}])
- _normalize_search_results:兼容 list / dict / json string / 占位符未替换情况
- _generate_markdown 注入 cite_block,要求 LLM 在正文以 [1] [2] 形式引用,并在文末列"## 参考资料"

slide.generate:
- 新增 search_results 参数 + _normalize_search_results
- _llm_outline 注入 cite_block,要求大纲在 bullets 中以 [1]/[2] 引用真实数据
- 返回新增 pptx_url_absolute(DASHBOARD_PUBLIC_BASE 拼绝对 URL)+ citations 字段

Co-authored-by: Cursor <cursoragent@cursor.com>
- web.search 委托 pilot.llm.web_search.WebSearcher(DDG + Bing CN,无 API key)
- media.tts 走 MiniMax T2A /v1/t2a_v2,默认 AGENT_PILOT_ENABLE_TTS=0 禁用避免比赛意外消耗
- 不实现 image / video / voice_clone / image_understand 这些 fast 时期挂的空壳
- registry._register_builtin_tools 引入 web_media + 兼容性引入 lark_tools(下个 commit 实现)
- 单测 4 条覆盖 schema 注册 / 调度执行 / TTS 默认禁用 / TTS 凭据缺失

Co-authored-by: Cursor <cursoragent@cursor.com>
… STAGES

- LEGAL_TRANSITIONS dict 显式列出每个状态的合法目标集(PRD §10)
- Task.transition() 默认校验,非法抛 IllegalTransitionError;force=True 可跳过
- 增加 transition_to / can_transition_to 别名,匹配 PRD 命名
- STAGES = ("context","doc","ppt","rehearse") + set_stage_owner() 仅允许已知 stage
- 单测 12 条覆盖:完整旅程、SUGGESTED→DELIVERED 跨状态、PLANNING→PPT 短路径、
  PAUSED 恢复、FAILED 重试、IGNORED 复活、stage_owners 校验、force 旁路
- 旧 test_task_state_transition 适配业务变更:必须 ASSIGNED → PLANNING 合法路径

Co-authored-by: Cursor <cursoragent@cursor.com>
- builder.context_confirm_card 重写为 PRD §7.2 规范:
  • 已理解任务(task_summary)/ 已用资料 / 缺失资料 三段
  • 按钮统一为 📎 添加资料 / ✅ 确认生成 / 📝 调整目标 → pilot.ctx.add/confirm/adjust
- builder.task_delivered_card 修复:URL 为空跳过避免 []( ) 渲染异常
  • 全部为空时显示占位提示
  • 中文 kind label(doc → 文档,slide → 演示稿,canvas → 画布)
- 新建 cards/context_confirm.py:ContextSummary dataclass + build() 便利构造器
  • missing 字段自动翻译(audience → "受众(给谁看)")
- 单测 4 条覆盖空 URL 过滤、占位提示、3 按钮 action 命名、ContextSummary 翻译

Co-authored-by: Cursor <cursoragent@cursor.com>
server.py:
- /api/events/{session_id} SSE 加 30s heartbeat 保持代理/nginx 不掐线

dashboard.html 重写:
- 事件 kind i18n(KIND_LABELS 22 项):plan_start → 🛫 任务启动,step.done → ✅ 步骤完成
- 工具名 i18n(TOOL_LABELS 14 项):doc.append → 📝 AI 生成文档内容,web.search → 🌐 联网搜索
- 进度条:完成步数 / 总步数 + 百分比(plan_start payload.steps 长度初始化)
- 已用时(前端每秒滚动 Date.now() - planStartedAt)
- 产物面板(artifact-list):step.done 时根据 tool 名解析 doc/canvas/slide/tts URL,去重展示
- 删除原 8 步 Harness Loop 区块(Loop 阶段标识在事件流里已经够清楚)
- heartbeat 监听:状态从"实时"→"实时(心跳)"

index.html 诚实化:
- "飞书 SKILL 29" → "飞书 OpenAPI · IM·Doc·Bitable"(实际接入数量,不吹牛)
- Capability 层描述 → "10+ 内置工具 · 飞书 IM/Doc/Bitable · web.search 联网"

Co-authored-by: Cursor <cursoragent@cursor.com>
工具:
- lark.im.fetch_thread  → 群聊消息抓取(GET /im/v1/messages container_type=chat)
- lark.doc.search       → 云文档检索(POST /drive/v1/files/search)
- lark.bitable.search   → 多维表格记录检索(POST /bitable/v1/apps/.../records/search)

实现:
- 全部委托 pilot.surface.feishu.client.FeishuClient 已有/新加方法
- 不引入 larksuite/cli submodule(那只是 markdown 文档,不是可执行代码)
- 缺凭据 / 缺参数 → ok=False + reason,不抛异常
- registry namespace="lark",与 pilot 内置工具区分

新增 FeishuClient 方法:
- drive_search(query, count) → [{token,name,type,url}]
- bitable_search(app_token, table_id, query, page_size) → [{record_id, fields}]

单测 5 条覆盖:3 工具注册 + 缺凭据 / 缺 table_id / 空 query 降级

Co-authored-by: Cursor <cursoragent@cursor.com>
- pilot/surface/lark_mcp_runner.py:FastAPI + SSE + JSON-RPC 子集
- 白名单 4 个非破坏性工具:doc.create / doc.append / slide.generate / web.search
- /tools/list、/tools/call、/sse、/messages、/health
- docs/MCP_USAGE.md:Cursor / Claude Desktop 接入示例
- tests/unit/test_lark_mcp_runner.py:6 测全过

避免暴露 archive.bundle 等破坏性工具,防止外部 client 误调。

Co-authored-by: Cursor <cursoragent@cursor.com>
- scripts/server/install.sh:幂等一键安装(Ubuntu 22.04),apt + venv + pip + systemd + nginx + UFW
- scripts/systemd/agent-pilot-bot.service:bot 长连接服务,Restart=always
- scripts/systemd/agent-pilot-dashboard.service:dashboard :8001
- scripts/systemd/agent-pilot-mcp.service:反向 MCP server :8003
- scripts/nginx/agent-pilot.conf:80→:8001,/sse 关 buffering
- docs/DEPLOY.md:8.136.98.175 完整部署 + 健康检查 + 故障排查

UFW deny 8001/8002/8003,只暴露 22/80/443。

Co-authored-by: Cursor <cursoragent@cursor.com>
- scripts/run_t20_smoke.py:T1-T20 链路烟雾,输入文本→IntentRouter→Planner→工具
- docs/JUDGE_TEST_REPORT.md:评委验收 20 用例表 + 真机 R1-R8 操作清单 + 复测命令
- runtime/intent_router.py:
  · _detect_command 支持 /pilot 帮助 / @pilot 状态 前缀剥离
  · _has_topic 阈值微调(residual ≥ 2 字符或 len ≥ 12)
- 全量回归:131 unit + 7 e2e + 20 smoke 全绿

不再沉默、不假联网、不假飞书集成。

Co-authored-by: Cursor <cursoragent@cursor.com>
@bcefghj bcefghj merged commit e7ddf9f into main May 6, 2026
1 of 3 checks passed
@bcefghj bcefghj deleted the v1.5-clean branch May 6, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant