7.5 KiB
7.5 KiB
总任务: blog-app 加 "AI Agent 升级迭代日报" (daily agent watchdog)
你是 manager, 严格按你的工作流: plan 拆任务 -> build 串行执行 -> review 给正式 verdict. 自己不写代码.
Goal
给 Flask 博客应用 (workspace = /home/yi/opencode-blog-showcase/blog-app) 加一个后台日报功能: 每天自动抓 6 个 AI agent 项目的最新版本/发布/commit, 用 Exa web search 补充资料, 用本地 litellm 智能总结, 写 markdown 报告 + SQLite 存档, Flask /watchdog 页面展示最近 7 天报告并支持手动触发.
已验证的环境事实 (build agent 直接用, 不要重新探索)
- GitHub API (无需 token, 剩余额度充足):
- latest release:
GET https://api.github.com/repos/{owner}/{repo}/releases/latest(6 个 repo 全部 200) - commits:
GET https://api.github.com/repos/{owner}/{repo}/commits?per_page=5 - 注意:
sst/opencode返回 301 (已改名 anomalyco/opencode), requests 默认跟随重定向即可, 但报告里 repo 名仍写 sst/opencode
- latest release:
- npm registry:
GET https://registry.npmjs.org/{pkg}/latest已验证 200 的包:opencode-ai,@anthropic-ai/claude-code,@openai/codex,hermes-agent,oh-my-openagent.hindsight包存在但可能不是 vectorize-io/hindsight 那个项目 — 取回后检查 description 相关性, 不相关就跳过该项目的 npm 源 (单源失败不得中断整体). - RSS/Atom:
https://github.com/{owner}/{repo}/releases.atom(sst/opencode 的 atom 也 301, requests 跟随即可). 用标准库 xml.etree.ElementTree 解析, 禁止装 feedparser. - Web search = Exa 托管 MCP (omo websearch 同款, 免 API key, 已实测可用):
- 端点:
POST https://mcp.exa.ai/mcp?tools=web_search_exa - 协议: MCP streamable HTTP / JSON-RPC. 流程:
a. POST
initialize(params: protocolVersion "2025-03-26", capabilities {}, clientInfo) — 响应头Mcp-Session-Id必须保存 b. POSTnotifications/initialized(带 Mcp-Session-Id 头) c. POSTtools/call, name=web_search_exa, arguments={"query": "...", "numResults": 3}(带 Mcp-Session-Id 头) - 请求头:
Content-Type: application/json,Accept: application/json, text/event-stream - 响应是 SSE 格式 (
event: message\ndata: {json}), 解析 data 行的 JSON 取result.content[0].text - 参考实现: workspace 里
.probe/exa_mcp_probe.sh有我实测通过的 curl 版
- 端点:
- LLM 总结 = litellm 本地代理:
POST http://127.0.0.1:4000/v1/chat/completions, json={"model": "analysis", "messages": [...], "max_tokens": 1024}, 无需 Authorization 头, timeout=300. model 名就是字符串 "analysis" (Qwen3.7 Plus). 发给 LLM 的单项目数据截断 (release body ≤500 字符, commit message ≤200 字符), 总 prompt <12KB. 中文输出. - 系统时区 Asia/Shanghai (UTC+8) — cron
0 9 * * *即每天早 9 点. - Flask app 现状: app.py (561 行) 已有 get_db() (projects.db 只读), /analyze SSE 流式等. 运行方式:
/usr/bin/python3 app.py, host 0.0.0.0 port 8090. 现有模板在 templates/, 静态在 static/. 部署脚本 scripts/deploy.sh 已存在 (kill + 重启 + 健康检查), 不要重写它, 但需要时可以读它参考. - opencode 写文件权限: agent 的 write/edit 工具只能写 workspace (/home/yi/opencode-blog-showcase/blog-app) 内部. 所有代码文件都必须落在 workspace 里. 运行时目录 (data/, logs/) 由 python 脚本运行时 os.makedirs 创建, 不是 agent 用 write 工具创建. 任何临时/测试文件落到 workspace 内
./.review-tmp/.
架构决策 (已定, 不许改)
- 新文件
scripts/daily_watchdog.py: 独立可执行脚本 (/usr/bin/python3 scripts/daily_watchdog.py), 做全部 抓取->web search 补充->LLM 总结->写报告->存 SQLite. 退出码: 全失败=1, 部分失败=0 但报告里标注. - SQLite:
~/opencode-blog-showcase/data/watchdog.db(脚本运行时创建目录). 表自己设计 (建议 reports 表: date, markdown, meta_json, created_at + 唯一索引). 绝对不许碰 projects.db. - 报告文件:
~/opencode-blog-showcase/logs/daily-agent-watchdog-YYYY-MM-DD.md, 同时内容存 watchdog.db. - Flask 路由 (加在 app.py, 风格与现有路由一致):
GET /watchdog— 从 watchdog.db 读最近 7 天报告渲染 templates/watchdog.html (base.html extend, 导航与现有页面一致); 没有报告时显示空态 + 立即跑按钮POST /watchdog/run— subprocess 后台起 daily_watchdog.py (不等结果), redirect 回 /watchdog 并 flash "已触发, 约 1-2 分钟后刷新". 简单防重: 60 秒内重复 POST 返回 429.- base.html 导航加 "日报" 链接
- cron:
scripts/install_watchdog_cron.sh— 幂等地往当前用户 crontab 加0 9 * * * cd /home/yi/opencode-blog-showcase/blog-app && /usr/bin/python3 scripts/daily_watchdog.py >> /home/yi/opencode-blog-showcase/logs/daily-agent-watchdog.log 2>&1(先 crontab -l 检查已存在则跳过). 脚本由 build agent 写好, 由 review agent 或上层 worker 执行, build 阶段不执行. - 失败告警: 单项目/单源失败 -> 报告里该项标 "⚠️ 抓取失败: 原因", 继续其他项目. 整体失败 (如 LLM 挂) -> 仍写一份含错误说明的报告 + log 里 ERROR 行. 任何情况下脚本不得因单个源失败而崩溃退出非零 (除非连一个项目都没抓到).
监控项目 (6 个, ★ = 当前 setup 装了)
| repo | npm 包 | ★ | 备注 |
|---|---|---|---|
| sst/opencode | opencode-ai | ★ | 已装 1.18.14 (301->anomalyco/opencode) |
| anthropics/claude-code | @anthropic-ai/claude-code | ★ | |
| openai/codex | @openai/codex | ||
| NousResearch/hermes-agent | hermes-agent | ★ | |
| code-yeongyu/oh-my-openagent | oh-my-openagent | ★ | |
| vectorize-io/hindsight | hindsight (需验证相关性, 不相关则跳过 npm) | ★ |
报告格式 (每项目必须有)
- latest version, last release date, 1 句中文 changelog 摘要 (LLM 生成), breaking change 标记 (LLM 判断 true/false + 依据), ★ 相关性说明
- 报告头部: 日期, 数据源清单 (实际成功用了哪几个), 各项目一节
- ≥30% 的报告内容必须来自 web search 补充 (每项目至少 1 条 Exa 搜索结果摘要进报告, 标注来源 URL)
Acceptance (review 必须逐项验证, 全过才 PASS)
- cron 安装脚本存在且幂等, 安装后
crontab -l能看到 9:00 条目 (review 时实际执行安装脚本验证) - 数据源 ≥5: GitHub Releases API / GitHub commits API / npm registry / Exa web search / GitHub releases.atom — 报告头部的数据源清单要真列出
- 监控 6 项目, 报告每项含 version/date/中文摘要/breaking 标记/★
scripts/daily_watchdog.py真实跑一遍 (review agent 执行), 生成真报告 (禁止 mock), review 报告里必须附至少 1 段真实 curl/脚本输出证据- Flask /watchdog 渲染最近 7 天 + POST /watchdog/run 手动触发可用 (review agent 用 deploy.sh 重启后 curl 验证 127.0.0.1:8090 和 192.168.2.25:8090)
- 无新 pip 依赖 (只用 flask/requests/sqlite3/标准库)
禁止 (越界=FAIL)
- 禁止改 litellm 配置 / restart litellm-proxy / llama-server
- 禁止改 projects.db schema, 禁止改 scripts/fetch_data.py
- 禁止碰 /home/yi/wxhook, /home/yi/.litellm, /home/yi/opencode, omo 安装目录和配置
- 禁止 mock 数据 / 预生成报告 / 用云端 LLM 替代 litellm analysis
- 禁止 pip install 任何新包
- 禁止删改 .probe/ 目录外的现有文件 (app.py 只做新增式修改: 加路由加导航, 不动现有路由逻辑)
输出
按你的 STEP/FINAL 格式汇报. FINAL 里 deliverable_path 指向 workspace 根.