cyberine
UsageRun recipes

Usage records for external meters — billed dollars, per-model tokens, aux spend (k0nnx, kq39p, kcajh)

Every dollar figure Cyberine keeps now travels with the model and the token counts behind it, so a meter outside Cyberine (tokenburn, a spreadsheet) can price it again or check it without guessing. There is nothing to switch on and no new environment variable.

Provider-billed cost on a loop worker (k0nnx): when an OpenAI-wire provider puts its own cost on the final usage chunk (OpenRouter's usage.cost), the loop worker stores it as usage.billedUsd on the workerRuns entry and usage.costUsd becomes that figure plus any delegate-subtask cost, so run cost, the fleet Cost column, the daily cap and cyberine cost all read the billed amount instead of the rate-table estimate. A run where any round of the worker lacked a cost keeps the table estimate and has no billedUsd. The chat planner already did the same through providerReportedCostUsd in src/chat/providerCost.ts.

Per-model usage in the global run index (kq39p): each ~/.cyberine/runs/<runId>.json entry carries a usage array with one object per source, provider, model and billing class: calls, inputTokens, cacheHitTokens, outputTokens, billedUsd (provider-reported) and estimatedUsd (rate-table or CLI-reported). source is worker or aux in a run record (a chat session adds chat entries under sessionTokens); costModel is subscription, metered, free-local or free, and subscription marks notional cost. The entry is rewritten with the rest of the record on every run write, so it still prices after the run directory, worktree or temp dir is gone.

Aux and chat records (kcajh): each paid judge, router, re-ranker or planner call appends model, token counts and a billed flag to ~/.cyberine/credits/aux-spend.jsonl next to its usd; inside a run the same detail folds into run.json as auxUsage (the dollar total stays in auxCostUsd). Worker spend rows in ~/.cyberine/credits/events.jsonl and credit-units.jsonl also name the model and tokens. A chat session keeps sessionTokens.auxUsage (compaction, handoff and run-report turns) next to auxUsd.

jq '.usage' ~/.cyberine/runs/<runId>.json
tail -n 3 ~/.cyberine/credits/aux-spend.jsonl
jq '.sessionTokens.auxUsage' ~/.cyberine/chat-sessions/<sessionId>.json
npm run selftest:run-usage

Known limitations and deferred work:

  • Only providers that report a cost on the usage chunk get billedUsd; DeepSeek, Moonshot and the rest stay on the rate table, and billedUsd is never invented from tokens.
  • ~/.cyberine/credits/spendcap-events.jsonl and dailycap-reservations.jsonl stay dollar-only: they are cap bookkeeping, not usage records.
  • Runs and ledger rows written before these changes are not backfilled; an old run with aux dollars but no detail shows one unknown provider aux entry in its new index record, and a pre-kq39p index record has no usage key until its run is written again.
  • The non-streaming judge path reads usage.cost from the response body; the aux ledger prunes to the current UTC day past 64 KB, so an external meter must read it at least daily.
  • Not verified against a live OpenRouter response from this change: the fixtures are a local fake server, and no provider was called.