Repository navigation
Conversation
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…replacement NTFS can reuse the same creation-time tick when a file is deleted and immediately recreated at the same path, so relying on creation_time alone could misidentify a replaced Hermes database as the same file and skip starting a new baseline. Use volume serial + file index as the primary identity signal with creation_time as a second factor, and space out the replacement test to avoid the metadata reuse window.
|
Reviewed the full diff (25 files, +4811/−123) against the issue's proposed solution — this is a solid, first-class implementation. I went through the Rust sync path ( What's done well
Two non-blocking observations before merge
Net: implementation quality is merge-ready from my read — I'd love to see this land and iterate on cadence/UX in follow-ups rather than block on polish. @farion1231 if the size is the concern, the diff is cleanly separated (Rust service + migration + frontend) and could even be merged in two steps if that helps. (For context: I use both cc-switch and Hermes Agent daily — this is exactly the missing integration; happy to help with follow-ups, e.g. sync-cadence docs or a usage-sync trigger test.) |
# Conflicts: # src/components/usage/UsageTrendChart.tsx
|
Thanks @xrbs00 - saw the Checks had not started reporting yet when I looked (~10 min after your push), so just worth a glance once they land. Observation 2 (one-line note in the description about when Hermes aggregate deltas are expected to appear between |
Resolve the v18 schema lineage split by converging both byte-cursor and Hermes aggregate structures in v19. Preserve both dashboard features and isolate Hermes provider tests from the live HERMES_HOME.
…r-6120 # Conflicts: # src/components/usage/UsageTrendChart.tsx
|
@farion1231 快合并这个功能 |
|
Sharing two findings from implementing the same goal user-side, in case they're useful for this PR. I built a user-side sync for Hermes → CC Switch usage dashboard and ran it against a real Hermes install. Two things came out of it that seem relevant to the discussion here. 1. The "per-call billing is not possible" concern may be outdated — but not in The maintainer previously removed Hermes usage tracking, citing that all API calls in a process collapse into a single Reading But There is, however, a table I have not seen discussed: 2. The reason a This one is structural, and I think it is the strongest argument for the dedicated-table design in this PR.
Producing a truthful call count therefore seems to require either writing N rows per window (i.e. synthesising N requests that never existed, with the token split between them) or storing a counter in a table that has a counter column — which is what this PR does. I went with the second option being unavailable to me and documented the resulting limitation rather than fabricating rows. Offer If useful, I can test this PR against a real Hermes install and report the results — happy to test on Windows, and I can also check Linux if that is useful. I have no stake in the implementation choice; I mention this only because the |
|
Update on this PR (head 25b8751):
The current upstream CI run is action_required with no test jobs, so it has NOT validated this head yet. If a maintainer is comfortable approving the fork workflow, the remote checks can run; code-owner review remains outstanding. No Hermes runtime was enabled or restarted as part of this PR update. |
|
@xrbs00 我把你这个插件在真机上跑了一天(Hermes v0.21.2 / Windows / CC Switch 3.20.4), 先说好消息:你的聚合逻辑是干净的拿一个真实长会话(会话 id
三项全等(插件 169 条事件 = 主循环 149 + background_review 19 + 1 条零散)。 另外纠正我自己的一个判断错误: 三条可以直接改的1)
for name in ("post_api_request", "api_request_error", "post_auxiliary_call"):
ctx.register_hook(name, callback)前两个在 $ git grep -c post_auxiliary_call HEAD
(0 个文件)所以 同一会话按
漏了 141/310 = 45.5%。 approval 占大头,而且这是长任务里最高频的操作—— 好消息是 approval 不需要上游改,
把 2) 现在 manifest 只有三行( name: ccswitch-usage
version: "1.0"
description: ...
provides_hooks:
- post_api_request
- api_request_error
- pre_approval_request
- post_approval_response3)重试的 一个 404 重试 3 次的调用,三条事件 一个技术提问我核对 PRIMARY KEY (session_id, model, billing_provider, billing_base_url, billing_mode, task)上面那个会话里出现了两条 想确认你导入器那边分组用的是几列?如果也是 4 列,可能得跟着补。 自查
|
|
@Chunai-Bboy 感谢实测反馈,已逐条核查,并在
本地针对性验证:Python 8/8、前端 15/15、Rust 聚合/采集 20/20,类型与格式检查通过。 请在 Hermes 0.21.5(v2026.9.24)或更新、具备全部三个钩子的安装上重新安装更新后的插件并重启 Hermes,复测 approval/title_generation 与重试耗时显示。 |
|
@xrbs00 逐条复核完了。先说结论:你的回复全对,我评论里两条核心论断是错的,给你道歉。谢谢你点名要 SHA——正是它帮我把错误定位到了根上。 错误 1:
|
| 项 | 结果 |
|---|---|
hermes plugins validate |
通过(旧版是 fail) |
plugins doctor |
3 hook(s) 注册(旧版报 unknown hook) |
| 插件自带测试 | 8/8 |
| 版本门 | REQUIRED_HOOKS 缺任何一项就明确拒绝采集并提示升级,不静默丢 |
post_auxiliary_call 实抓 |
真实长写作会话 aux 从 0 → 17 条(approval 15 + compression 2) |
同一会话、升级后同一窗口的对账
| 维度 | 插件逐条 | state.db 聚合 | 结果 |
|---|---|---|---|
| approval | 15 条 / 10,490 in | 15 / 10,490 | 逐 token 一致 |
| main + background_review | 251 / 429,487 | 223+28 / 332,237+97,250 | 恒等(bg 走 post_api_request 记成 main,聚合拆行) |
| compression | 2 / 131,602 | 1 / 67,721 | 聚合漏了第一次 |
最后一条是给你的弹药,不是抱怨:第一次压缩(15:32:17,109s,in 63,881 / out 12,096)真实成功了——其后 main 的 prompt 从 3–10K 骤降到 1–2K,上下文确实被压了——但 session_model_usage 里 compression 行的 first_seen 恰好等于第二次压缩结束的时刻(15:59:18),第一次压缩的用量没进任何聚合行。
也就是说在 0.21.5 上,你的账本反而比 Hermes 官方聚合更完整。这值得写进 PR 描述当卖点,也值得给 Hermes 报一个 aux 丢账的 issue——需要的话我把时间线和数值整理成最小复现贴上来。
最后
谢谢你连我没说对的两条也认真核查,能改的当天就推了 2bc6b19,该坚持的(审批 UI 钩子那条,你说得完全对)也顶住了。这份 PR 的工程质量配得上早点 merge。CI 如果跑过这个 head,我可以把 validate / doctor / 8 个测试的输出连同上面这张对账表整理贴给维护者看。
我这边的同步(聚合走 session_model_usage、你的账本当可选增强)会继续跟你的结论对齐:明细与聚合分表、永不相加。
|
@xrbs00 这个 PR 的文档与诚实度在同类 PR 里非常突出(分阶段记录、明确标注哪些是估算、CI 状态如实说明"action_required 不能称为通过")。 但 +7421/−133、45 个文件是超大包,且混合了至少三个主题(用量同步、Hook 采集插件新子系统、Profile 会话导入)——按 grab-bag 处理,将以此为依据建议关闭本 PR,欢迎拆分后单独重提,然后我们再逐一查看哪些可以被合并。 PR 混合的主题(建议拆分)
需要维护者确认的方向问题1. [P1] Hook 采集插件是新子系统。 在 Hermes 侧安装 CC Switch Hook 插件、维护每 Profile 独立账本、注册时检查 值得肯定的设计
|
2026-10-03 更新:采集兼容性与耗时语义(HEAD
2bc6b199)post_api_request、api_request_error、post_auxiliary_call。已补全provides_hooks与requires_hermes;注册前检查实际VALID_HOOKS,缺少钩子时明确拒绝采集,不创建账本、不静默漏掉辅助调用。git diff --check通过。兼容版本隔离 fixture 的真实 Doctor/严格 admission 检查通过(仅控制宿主版本为 0.21.5,非已启用的真实安装验证);低于最低版本的环境被拒绝。不把此前全套验证当作此提交的全套结果。25b8751d的 7 项 GitHub 检查已通过,替代此前“action_required”的旧状态;本次新 HEAD 的 CI 工作流 为action_required,测试 jobs 为 0,需要维护者批准运行;目前只有标签检查通过,不能称为新 HEAD CI 已通过。代码所有者审查仍需完成。没有启用或重启任何 Hermes 运行时。2026-09-30 阶段记录:可选请求采集与历史估算(非当前 HEAD)
当时 HEAD 25b8751 已解决与上游主线的合并冲突。本地验证:Python 插件 5/5、Rust 采集 4/4、v20→v21 迁移及配置锚点回归各 1/1、前端相关 13/13、TypeScript 类型检查、Rust fmt 和 Clippy 通过。前端全套单进程 151/151 个文件、1706/1706 项通过;默认并行模式曾有两项 App 集成用例失败,故不声称默认并行模式稳定全绿。Rust 全套排除当前 Windows 账户无权限运行的两个符号链接用例后,2954 项通过、10 项忽略、0 项失败;未排除时不声称全套通过。当时 GitHub CI 为 action_required、尚未启动测试 job;此后该 HEAD 的 7 项检查已通过。上述全套结果属于旧 HEAD,最新状态见顶部更新;代码所有者审查仍需完成。
以下保留原有聚合导入的设计说明;其旧版验证记录不代表当前 HEAD。
概要
本 PR 将 Hermes Agent 的
session_model_usage累计统计作为独立数据源接入 Usage Dashboard。proxy_request_logs,也不会用于推断状态码、成功率、延迟或逐请求费用。因此,升级后不会立即出现既有 Hermes 历史用量;只有建立基线后的新增用量和有界成本校正会进入统计。
背景
此前的 Hermes 集成以会话为粒度。同一进程内的多次 API 调用可能聚合到一条会话记录,模型字段也可能停留在初始模型,无法可靠表示实际的模型和提供商归因。维护者在 #5201 中说明了这一限制,并暂时移除了旧实现。
较新的 Hermes 版本提供
session_model_usage,按会话、模型、提供商路径、计费模式和任务累计记录调用数、令牌与成本。该表改善了模型和提供商归因,但其语义仍是累计统计,不是请求日志。本 PR 因此采用“累计快照与同步窗口增量”的独立导入模型,而不是将数据写入现有的
proxy_request_logs。Addresses #5088
Addresses the Hermes-specific portion of #4784
Context: #5201
实现内容
state.db和profiles/*/state.db。query_only模式读取,兼容 WAL。调用数和时间语义
Hermes 的
api_call_count是源表报告的累计 API 调用计数,不等同于 CC Switch 代理实际观察到的物理 HTTP 请求数。对于每个首次发现的统计序列:
如果计数回退、数据库身份变化或统计序列重置,则建立新的基线,不拼接新旧序列。
所有增量归属于相邻两次同步之间的窗口。因此,日、周和趋势视图反映的是同步窗口,不能用于恢复精确请求时间、逐请求顺序或重试与回退链。
成本语义
成本直接使用 Hermes 源表报告值:
cost_status为actual、final、settled或complete,且存在actual_cost_usd时,采用实际成本。estimated_cost_usd。$0,则保留该源值和来源语义,不转换为 API 市场等价成本。每个统计序列持久化首次成本基线和此前已导入的成本余额:
当较高的估算成本被较低的实际成本替换时,可以产生只包含成本的有符号校正:
即使源成本先跌破基线,之后再回升到基线,也不会重新导入历史金额;只有超过基线的部分才会形成新增成本。
因此,Dashboard 中的 Hermes Cost 表示首次建立基线后,Hermes 报告成本的净变化。它不是 Hermes 当前绝对累计成本、逐请求账单、提供商最终实付金额,也不是 CC Switch 重新估算的市场价格。
仅筛选包含成本校正的同步窗口时,窗口成本可能为负。界面显示
$0.0000也不代表服务免费;它可能表示该同步窗口没有新增成本、Hermes 未报告成本,或源数据将费用标记为订阅已包含。兼容性和错误隔离
原有只读聚合导入已针对 Hermes Agent v0.19.1 的
session_model_usage表结构完成验证,不通过 Hermes 版本号硬编码最低兼容版本;新增可选请求采集插件则要求 Hermes ≥0.21.5(v2026.9.24)及完整的三个钩子,见顶部更新。同步时直接探测源表和所需列:
CC Switch 自有表结构覆盖以下情况:
旧快照缺少
emitted_cost_balance_usd,且历史增量没有记账分段时,系统不会尝试跨计数重置重建历史余额,而是建立安全的新基线:如果已有可证明的已导入余额,仅缺少成本基线,则按以下规则恢复连续状态:
数据边界
原有累计聚合导入不推断逐请求事实。新增可选 Hermes Hook 插件从启用并重启后开始记录受支持路径的请求时间、状态与延迟等元数据;未覆盖路径、Hook 写入失败和未上报的用量保持未知,不声称完整物理 HTTP 请求日志或逐请求费用。
本 PR 也不读取提示词、消息正文、请求头、Cookie、密钥或原始错误,不持久化
billing_base_url原值,只保存稳定归因所需的派生标识。旧版验证记录(非当前 HEAD)
本次与最新主线
3217f725合并后,以下验证通过:tsc --noEmit。cargo fmt --check。cargo clippy -- -D warnings。git diff --check,且无未解决合并路径。完整前端 Vitest 在候选分支仍有 1 个主线既有的全套时序超时:
3217f725独立基线:133 个测试文件中 132 个通过;1012 项测试中 1010 项通过,包含同一超时及其后续 DOM 清理级联。tests/integration/App.test.tsx独立新进程复跑:7/7 通过。因此不把完整前端套件标记为全绿;现有证据表明剩余超时可在最新主线复现,并非本 PR 新增的稳定回归。
完整 Rust 未在当前账户下原样全绿:3 个测试需要 Windows 创建 symlink 特权(错误码 1314)。排除这 3 个环境受限用例后,其余 Rust 测试和 Clippy 均通过。
建议审查入口
src-tauri/src/services/session_usage_hermes.rs数据库发现、只读同步、快照与增量、计数重置、数据库身份和有界成本校正。
src-tauri/src/database/schema.rsCC Switch 自有快照、增量及迁移与修复表结构。
src-tauri/src/services/usage_stats.rs与现有聚合、筛选和查询接口的合并。
src/components/usage/UsageDashboard.tsx及相关概览、表格和趋势组件数据精度提示、混合来源汇总和不支持指标的隐藏逻辑。