Files
Coder 99b63abde6 feat: show per-step OpenRouter cost on the Trajectory tab
Extend the openRouterCost projection with a per-step priced-cost map
keyed by turn:step so surfaces can render spend without re-pricing, and
have the Trajectory view read it through the framework useProjection seat:
each priced assistant step shows its USD cost on the request boundary chip
and in the inspector summary, while unpriced steps stay blank. Also fix a
pre-existing exactOptionalPropertyTypes error in extractCacheRates that the
host typecheck surfaced.
2026-08-20 22:14:09 +07:00

4.4 KiB
Raw Permalink Blame History

@deepseek-ai/dsh-openrouter-usage

English | 中文

OpenRouter 花费追踪:一个提供账户余额的 Typert Remote 网关,加上 openRouterCost 会话投影——后者用 OpenRouter 的模型定价表为日志中的 token 用量计价。

在无法解析到 OPENROUTER_API_KEY(即 OpenRouter LLM 路由所用的同一个凭证)时,本包处于惰性状态:无 key 意味着不发起请求、定价表为空(因此每个 step 都保持未计价)、余额为空。

配置

- id: openrouter-usage
  name: '@deepseek-ai/dsh-openrouter-usage'
  config:
    apiKeyEnv: OPENROUTER_API_KEY
    baseURL: https://openrouter.ai/api/v1
    syncEnabled: true
    pricingRefreshMs: 21600000
    balanceRefreshMs: 60000
Key 默认值 含义
apiKeyEnv OPENROUTER_API_KEY 每次刷新解析的凭证引用。
baseURL https://openrouter.ai/api/v1 OpenRouter API 根;会拼接 /credits/models/auth/key
syncEnabled true 是否运行周期性的定价/余额刷新。
pricingRefreshMs 216000006 小时) 定价表刷新间隔(毫秒)。
balanceRefreshMs 6000060 秒) 余额刷新间隔(毫秒)。

key 经凭证边界(ctx.credentials)解析,并以后端环境作为回退,方式与 dsh-web-search-deepseek 一致。

服务契约

ctx.openRouterUsage 是一个 Typert Remote 网关。snapshot() 方法返回最近一次成功的余额快照的副本:balanceUsd 是来自 GET /credits 的可用余额(total_credits 减去已花费的 total_usage,即 OpenRouter 仪表盘展示的数字),外加来自 GET /auth/keylabel 与月度 usageTokens/limitTokens 预算、isFreeTierupdatedAt 时间戳。在任何成功获取之前,它返回一个全 null 的记录;一次失败的刷新会保留上一次已知快照并记录日志。同一个 key 还会从 GET /models 刷新模型定价表USD 每 token 的 pricing.prompt/completion,以及 flat 的 request 费用,若 API 披露时还有可选的 input_cache_read/input_cache_write)。

openRouterCost 投影会按定价表折叠每个会话日志中的 token 用量(assistant/chunk 的 usage 与 assistant/message 的 usage按 step 去重)。归属优先采用已组装消息自身的 provider/model;仅有 chunk 的失败step 则按最新的 request/context 路由计价。非 openrouter provider 上的 step 不属于本域,不会改变任何值;模型没有对应定价条目的 OpenRouter step 会计作未知未计价step。投影的 steps 视图字段以 ${turn}:${step} 为键记录每个已计价 step 的美元成本,便于按 step 展示花费而无需重复计价;未计价的 step 不在该映射中。

扩展点

Web 界面读取 openRouterCost 投影并通过客户端组装调用余额 Remotectx.remote.openRouterUsage.snapshot());组件栈由 dsh-client-ui-openrouter-usage 提供。网关不需要任何 session 或 agent 接线——一切都依托持久全量日志投影与一次缓存的请求。

模型体验

OpenRouter 花费与余额读数

模型看到什么

什么也看不到。花费与余额只是面向客户端的只读模型:两者都不会进入模型请求、工具 schema 或任何提示词。agent 循环保持不变。

Token 影响

不会产生模型 token。计价的数字来自 assistant/messageassistant/chunk 事件中早已记录的用量。

KV Cache 影响

因为花费只是对既有用量事件的投影而非新的模型可见输入KV cache 不受影响。

已知限制与暂缓事项

  • 估算,而非逐条计费——花费是 tokens × 模型定价,不是 OpenRouter 逐条 generation 的计费。generation id 并未持久记录,且 pi-ai 适配器丢弃了 usage.cost,因此投影是根据 token 数重建花费的。free tier 与促销定价可能与模型表有出入。
  • 计价以折叠时刻为准——投影在单元格折叠时使用当时的模型表计价。刷新定价只会影响其后折叠的单元格;已折叠的历史保持此前的数值。
  • 逐 token 近似——当 API 未披露单独的 cache 费率时cache 读/写回退到 prompt 费率flat 的 request 费用每个 step 记一次。账单可能相差不到一分钱。
  • 无设置卡片——本插件只通过 cordis.yml 暴露配置;设置项界面推迟实现。