initial: blog-app snapshot
This commit is contained in:
24
.probe/exa_mcp_probe.sh
Normal file
24
.probe/exa_mcp_probe.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# Probe the Exa hosted MCP (same endpoint omo websearch uses) from plain HTTP.
|
||||
set -u
|
||||
URL="https://mcp.exa.ai/mcp?tools=web_search_exa"
|
||||
H1='Content-Type: application/json'
|
||||
H2='Accept: application/json, text/event-stream'
|
||||
|
||||
echo "=== initialize ==="
|
||||
INIT_RESP=$(curl -sS -i -m 30 "$URL" -X POST -H "$H1" -H "$H2" \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"watchdog-probe","version":"0.1"}}}')
|
||||
echo "$INIT_RESP" | head -30
|
||||
SID=$(echo "$INIT_RESP" | grep -i '^mcp-session-id:' | tr -d '\r' | awk '{print $2}')
|
||||
echo "session-id: ${SID:-<none>}"
|
||||
|
||||
echo "=== notifications/initialized ==="
|
||||
curl -sS -m 15 -o /dev/null -w '%{http_code}\n' "$URL" -X POST -H "$H1" -H "$H2" \
|
||||
${SID:+-H "Mcp-Session-Id: $SID"} \
|
||||
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
|
||||
|
||||
echo "=== tools/call web_search_exa ==="
|
||||
curl -sS -m 60 "$URL" -X POST -H "$H1" -H "$H2" \
|
||||
${SID:+-H "Mcp-Session-Id: $SID"} \
|
||||
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"web_search_exa","arguments":{"query":"sst opencode latest release 2026","numResults":3}}}' | head -c 2500
|
||||
echo
|
||||
77
.probe/manager-brief.md
Normal file
77
.probe/manager-brief.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 总任务: 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 直接用, 不要重新探索)
|
||||
|
||||
1. **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
|
||||
2. **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 源 (单源失败不得中断整体).
|
||||
3. **RSS/Atom**: `https://github.com/{owner}/{repo}/releases.atom` (sst/opencode 的 atom 也 301, requests 跟随即可). 用标准库 xml.etree.ElementTree 解析, **禁止装 feedparser**.
|
||||
4. **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. POST `notifications/initialized` (带 Mcp-Session-Id 头)
|
||||
c. POST `tools/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 版
|
||||
5. **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. 中文输出.
|
||||
6. **系统时区 Asia/Shanghai (UTC+8)** — cron `0 9 * * *` 即每天早 9 点.
|
||||
7. **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 + 重启 + 健康检查), 不要重写它, 但需要时可以读它参考.
|
||||
8. **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)
|
||||
1. cron 安装脚本存在且幂等, 安装后 `crontab -l` 能看到 9:00 条目 (review 时实际执行安装脚本验证)
|
||||
2. 数据源 ≥5: GitHub Releases API / GitHub commits API / npm registry / Exa web search / GitHub releases.atom — 报告头部的数据源清单要真列出
|
||||
3. 监控 6 项目, 报告每项含 version/date/中文摘要/breaking 标记/★
|
||||
4. `scripts/daily_watchdog.py` 真实跑一遍 (review agent 执行), 生成真报告 (禁止 mock), review 报告里必须附至少 1 段真实 curl/脚本输出证据
|
||||
5. Flask /watchdog 渲染最近 7 天 + POST /watchdog/run 手动触发可用 (review agent 用 deploy.sh 重启后 curl 验证 127.0.0.1:8090 和 192.168.2.25:8090)
|
||||
6. 无新 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 根.
|
||||
14
.probe/run-sisyphus-b2b3.sh
Normal file
14
.probe/run-sisyphus-b2b3.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# t_f1f53c88: fork omo Sisyphus (default agent, NO --agent) with .sisyphus-brief-b2b3.md
|
||||
set -u
|
||||
export HOME=/home/yi
|
||||
cd /home/yi/opencode-blog-showcase/blog-app
|
||||
TS=$(date +%H%M%S)
|
||||
LOG=/home/yi/opencode-blog-showcase/logs/sisyphus-b2b3-${TS}.ndjson
|
||||
echo "log: $LOG"
|
||||
opencode run --attach http://127.0.0.1:4096 \
|
||||
--model litellm-local/coding \
|
||||
--dir /home/yi/opencode-blog-showcase/blog-app \
|
||||
--format json \
|
||||
"$(cat .sisyphus-brief-b2b3.md)" > "$LOG" 2>&1
|
||||
echo "exit=$? log=$LOG"
|
||||
Reference in New Issue
Block a user