Files
AgentsMeeting/gateway/scripts/specs/usage_collector.json
T

97 lines
7.7 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"module": "usage_collector",
"version": "3.0",
"purpose": "OpenCode Go 订阅用量采集脚本 — Hybrid v3.0。混合采集:主模式 HTTP + stored cookies4 个账号同时采集),辅助模式 CDP(仅 Chrome 当前登录账号补充/验证)。从 opencode.ai SSR HTML 解析 rolling/weekly/monthly 用量百分比和倒计时,写入 temp/usage_stats.json。支持 --daemon 持续采集(每 5 分钟)。",
"ui_location": "Infrastructure tab → OpenCode Go Usage section(通过 dashboard.py 的 /api/usage 和 /api/usage/refresh",
"human_help": {
"title": "OpenCode Go Usage Collector — 用量采集脚本",
"description": [
"usage_collector.py 是一个 Python 脚本,从 opencode.ai 的 SSR HTML 中解析 4 个订阅账号的用量数据(5h rolling / weekly / monthly),写入 JSON 缓存供 dashboard 展示。",
"混合采集模式:① 主模式 — HTTP + stored cookies,可同时采集所有账号(无需 Chrome 登录态切换),快但需要预先提取 cookies ② 辅助模式 — CDP 通过 Chrome tab 获取,只能采集当前登录账号,慢但不需要预先提取 cookieshttpOnly cookies 由浏览器自动携带)。",
"Cookie 提取:一次性操作 — python extract_cookies.py key1 --workspace-id wrk_XXX → cookies/key1.json。每个账号登录后执行一次。",
"SSR 解析:主模式用 per-metric regex 解析 HTML 中的 usagePercent + resetInSec(处理嵌套 $R[N]={} 格式);CDP 辅助模式通过 CDP /eval 执行 JS fetch 获取完整 HTML 并解析。"
],
"usage": [
"1. 首次配置: 逐个登录 4 个 opencode 账号 → python extract_cookies.py key{N} --workspace-id wrk_XXX",
"2. 采集: python usage_collector.py(一次性采集全部账号)",
"3. 守护: python usage_collector.py --daemon(每 5 分钟自动采集)",
"4. 仅 CDP: python usage_collector.py --cdp-only(仅采集 Chrome 当前登录账号)",
"5. 打印结果: python usage_collector.py --print",
"6. Dashboard: GET /api/usage(读缓存)/ POST /api/usage/refresh(触发采集)"
],
"troubleshooting": [
"如果某账号采集失败: 检查 cookies/{key_id}.json 是否存在且有效 — Session 可能已过期",
"如果 CDP 模式不可用: 确认 Chrome 以 --remote-debugging-port=9222 启动 + cdp-proxy.mjs (3456) 在运行",
"如果 SSR 解析失败: opencode.ai 的 SSR hydration 格式可能已变更 — 需要更新 regex",
"如果 usage_stats.json 为空: 检查脚本是否有文件写入权限 + TEMP_DIR 是否存在",
"如果采集结果过旧: 检查 --daemon 是否在运行,或手动触发 Refresh"
]
},
"ai_spec": {
"apis": [
{"method": "N/A (CLI)", "path": "python usage_collector.py [--daemon|--cdp-only|--print]", "returns": "写 temp/usage_stats.json + stdout 日志", "note": "CLI 脚本,非 HTTP API"},
{"method": "CDP call", "path": "localhost:3456/targets + /eval", "returns": "SSR HTML (CDP mode)", "note": "通过 cdp-proxy.mjs 与 Chrome 通信"},
{"method": "HTTP GET", "path": "https://opencode.ai/workspace/{ws_id}/go", "returns": "SSR HTML (HTTP mode)", "note": "带 Cookie header (从 cookies/{key_id}.json 读取)"}
],
"dependencies": [
"usage_monitor/accounts.json — 账号 workspace ID × key_id × label 配置 (.gitignore)",
"usage_monitor/cookies/{key_id}.json — 存储的 cookies (httpOnly auth cookie, .gitignore)",
"cdp-proxy.mjs (localhost:3456) — Chrome 远程调试代理 (CDP 辅助模式)",
"Chrome (Windows) with --remote-debugging-port=9222 — 浏览器 + 登录态",
"Python 3.10+ (stdlib only: urllib, json, re, logging, http.cookiejar)",
"temp/usage_stats.json — 输出缓存 (dashboard.py 直接读取)",
"opencode.ai API — 无公开 API,唯一数据来源是 SSR hydration script"
],
"architecture": {
"flow": "主模式: 遍历 accounts.json → 读取 cookies/{key_id}.json → HTTP GET opencode.ai workspace page → 正则解析 SSR HTML → CDP 辅助: Chrome tab → fetch(location.href) → 解析 → 合并结果 → 写 usage_stats.json",
"dual_collection": "主模式(HTTP cookies)可同时采所有账号 / CDP 辅助(Chrome browser)仅当前登录账号 / 两种结果合并: CDP 优先,HTTP 补充",
"regex_parsing": "per-metric regex 匹配 rollingUsage:$R[N]={status,usagePercent,resetInSec} — 处理嵌套 $R[N]={} 而非简单 blob regex",
"daemon_mode": "每 5 分钟自动采集 — time.sleep(300) 循环",
"cookie_rotation": "不同账号有独立 cookie 文件 — cookies/key1.json, cookies/key2.json, ... — cookie 文件通过 extract_cookies.py 生成"
},
"constraints": [
"accounts.json 不可提交 git — 已加入 .gitignore",
"cookies/*.json 不可提交 git — 含 httpOnly auth cookie",
"采集频率 ≥ 5min — 过密会触发 opencode.ai 风控",
"不要用 blob regex 解析 SSR — 嵌套 $R[N]={} 会导致 [^}]* 在内层 } 处断",
"CDP 辅助模式仅在主模式失败或需验证时使用 — 依赖 Chrome 登录态",
"Cookie 过期后需重新提取 — extract_cookies.py 每个账号执行一次"
],
"must_not": [
"不要把 accounts.json 或 cookies/*.json 提交到 git",
"不要在采集脚本中硬编码 workspace ID — 必须从 accounts.json 读取",
"不要尝试用 Python requests + 提取的 cookies 单独采集 — httpOnly cookies 无法通过 document.cookie 提取",
"不要用 blob regex 解析 SSR — 用 per-metric regex"
],
"related_modules": [
{"module": "usage_monitor", "relation": "usage_collector 是 usage_monitor 模块的数据采集层 — 采集结果供 dashboard 的 usage_monitor 展示"},
{"module": "dashboard", "relation": "dashboard 通过 /api/usage/refresh 触发采集 + /api/usage 读取缓存 + auto-timer 自动触发"},
{"module": "xmpp_bot", "relation": "xmpp_bot 的 /usage 端点也可触发采集(旧版用法,新版 dashboard 直接 subprocess 调用)"}
],
"tests": [
{"id": "UC01", "name": "accounts.json 解析正确", "endpoint": "读取 accounts.json → 过滤出有 workspace_id 的记录"},
{"id": "UC02", "name": "HTTP 主模式采集返回有效数据", "endpoint": "带 cookie 的 HTTP GET → 解析 usagePercent > 0"},
{"id": "UC03", "name": "CDP 辅助模式在 Chrome 启动时可用", "endpoint": "CDP /targets → 找到 opencode.ai tab"},
{"id": "UC04", "name": "输出 usage_stats.json 格式正确", "endpoint": "采集后检查 JSON schema: accounts 数组 + last_refresh_iso"},
{"id": "UC05", "name": "--daemon 模式每 5 分钟采集", "endpoint": "--daemon 启动后连续 2 次采集间隔 ≈ 300s"}
],
"known_issues": [
"opencode.ai Go 用量目前无公开 API — PR #16513 未上线,数据唯一来源是 SSR hydration script",
"Cookie 有效期: opencode.ai session cookies 可能随时过期 → session_expired 标记提醒用户重新登录",
"CDP proxy 依赖: 若 Chrome 关闭或 cdp-proxy.mjs 未运行,CDP 辅助模式将失败",
"HTML 返回大小: CDP /eval 返回完整 SSR HTML (~16KB),可用带宽消耗"
],
"related_files": [
"gateway/scripts/usage_collector.py — 本文件 (742行, v3.0)",
"gateway/scripts/usage_monitor/accounts.json — 账号配置 (.gitignore)",
"gateway/scripts/usage_monitor/cookies/{key_id}.json — Cookie 文件 (.gitignore)",
"gateway/scripts/usage_monitor/extract_cookies.py — Cookie 提取工具",
"gateway/temp/usage_stats.json — 采集结果缓存",
"gateway/scripts/specs/usage_collector.json — 本 spec",
".opencode/skills/web-access/scripts/cdp-proxy.mjs — CDP proxy (3456)"
]
}
}