Skip to content

feat(runtime): 金额预算、价格快照与 Provider 资格诊断 - #64

Merged
Qiyuanqiii merged 2 commits into
mainfrom
codex/issue-49-monetary-budget-pricing
Aug 15, 2026
Merged

Qiyuanqiii merged 2 commits into
mainfrom
codex/issue-49-monetary-budget-pricing

Conversation

@Qiyuanqiii

Copy link
Copy Markdown
Member

背景

issue #49(父任务 #35):domain.Budget.MaxCostUSD 一直只是被校验和持久化的字段,从未被执行;模型调用成本没有任何记账。直接用浮点美元记账会引入舍入误差,价格若由 Provider 响应或仓库文件携带则模型输出/提示注入就能抬价或绕过预算。同时 diagnostic 与 Harness qualification 的结果缺少一个稳定、可持久化的"端点资格"分类。

本次改动

  • 新增 internal/pricing:price_snapshot.v1 算子价格表 wire 格式(64 KiB / 512 条目上限、provider/model 唯一、内容哈希指纹强制重算、未知字段拒绝、RFC3339 有效期必须覆盖导入时刻且最长一年),整数 micro-USD 成本估算(天花板除法,任何非零用量都不会舍入成免费)。
  • schema v100:provider_price_snapshots(唯一 active 快照)、run_monetary_usage(run 级聚合)与 run_monetary_reservations(按 attempt 预留)三张表;账本遵循 reserve→call→settle-or-release,CAS 推进,open = reserved − settled − released,remaining = cap − open。
  • 自愈与终态:每次预留/读取用量前用终态 model.completed / model.failed 事件对账 open 预留;run 进入终态时强制释放全部 open 预留;同内容导入幂等回放,新导入原子轮换。
  • 失败关闭闸门:MaxCostUSD > 0 才启用;活动价格表必须携带该 provider/model 的精确条目否则预留失败;结算时条目缺失按整笔预留保守计费;未启用闸门的 run 完全跳过(untracked)。
  • 资格诊断:8 值 taxonomy(not_configured / available / protocol_mismatch / auth_failed / network_failed / rate_limit / capacity / model_unsupported),持久化于 qualification_status.<provider>.<model>,诊断/qualification/模型可用性视图统一返回;未诊断过的模型在 Web 显示中性状态。
  • 接入面:HTTP GET/POST /api/v1/models/prices(POST 走 control token)、CLI provider price-import --file / provider price-list、run usage 的 monetary_* 字段、Web 模型面板的资格状态展示;root / specialist / readonly fanout 共享 run 聚合(fanout 用 fnv 派生稳定 attempt id,重试回放同一预留)。

测试覆盖

  • internal/pricing:估算/取整、snapshot 校验、wire 解析(未知字段、指纹、有效期)与指纹幂等。
  • internal/store:预留/结算/释放/超卖/回放、untracked 跳过、价格导入幂等与轮换、终态释放、model.* 事件对账(100@1USD/M + 50@2USD/M = 200 micros)。
  • internal/application:Supervisor 预留→结算全链路(2 input @ 1.00 USD/M + 3 output @ 2.00 USD/M = 8 micros)与缺价格条目 fail-closed。
  • internal/httpapi:价格导入/列表/重放/拒绝用例;OpenAPI 路径、操作、枚举(含资格状态 8 值与空值)断言;全部实时路由验证。
  • Web:客户端解析器新字段/枚举校验、59 个测试文件 235 个用例、typecheck 与 build。
  • 迁移链:v100 逆迁移 helper 补齐,既有 v8→latest 等升级测试恢复通过;README schema 时间线审计(100 行)通过。

验证结果

  • go build ./...、go vet ./... 通过。
  • go test -timeout 30m ./...:除 internal/analyzer 两个既有的环境性 0xc0000142 失败(与本次改动无关)外全部通过。
  • go test -race(pricing / modelregistry / store 焦点用例)通过。
  • Web:typecheck、vitest(235 passed)、build、check:api 通过;docs/openapi.json 与 web/src/api/schema.d.ts 重新生成且与源码一致。

安全边界与非目标

  • 价格是算子数据,不是模型输出:Provider 响应、README、Skill、仓库文件永远无法触达导入面(仅 Go 控制面 HTTP/CLI),模型输出不能抬价或放款。
  • 未引入 Mission 级金额字段:当前"Mission 总金额上限"由 run 聚合覆盖,Mission 级上限与 vendor 价格订阅、多币种留待后续(ADR 0101 已记录)。
  • 金额闸门只在 MaxCostUSD > 0 时生效,既有 run 行为不变;未启用时账本完全不记账。
  • 本改动不改变现有 turn/token/时间/工具预算的语义,也不引入任何新的网络执行或宿主权限。

Closes #49

- 新增 internal/pricing:price_snapshot.v1 算子价格表(整数 micro-USD、指纹重算、未知字段拒绝、有效期约束)与天花板除法成本估算
- schema v100:provider_price_snapshots / run_monetary_usage / run_monetary_reservations 账本(reserve→call→settle-or-release,CAS 推进,终态 model.* 事件对账自愈,run 终态强制释放)
- MaxCostUSD>0 才启用闸门;缺活动价格条目 fail-closed,结算缺条目按整笔预留保守计费;root/specialist/readonly fanout 共享 run 聚合
- 资格状态 8 值 taxonomy(qualification_status.<provider>.<model> 持久化),诊断/qualification/可用性视图统一返回
- HTTP GET/POST /api/v1/models/prices + CLI provider price-import/price-list + run usage 金额字段
- Web 客户端校验与模型面板资格状态展示
@Qiyuanqiii
Qiyuanqiii merged commit 4cc2032 into main Aug 15, 2026
5 checks passed
@NanaseInori
NanaseInori deleted the codex/issue-49-monetary-budget-pricing branch September 16, 2026 09:09
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.

feat(runtime): 金额预算、价格快照与 Provider 资格诊断

1 participant