Skip to content

feat(codex): surface turn-level cache and spend telemetry - #646

Open
yzxcj797 wants to merge 3 commits into
yc-software:mainfrom
yzxcj797:feat/codex-turn-usage-586d
Open

feat(codex): surface turn-level cache and spend telemetry#646
yzxcj797 wants to merge 3 commits into
yc-software:mainfrom
yzxcj797:feat/codex-turn-usage-586d

Conversation

@yzxcj797

@yzxcj797 yzxcj797 commented Aug 21, 2026

Copy link
Copy Markdown

Summary

Follow-up to #645: codex accumulated full per-thread usage live (usageByThread, the same totals its recordLlmRequest flush reports) but its turn result carried none of it, so codex turns landed in turn_metrics without the cache or spend telemetry pi and claude already report.

Implementation

The turn result maps the summed thread totals through one pure usageToTurnTelemetry helper: cacheUsage (cacheRead/cacheWrite/uncachedInput) and costUsage (outputTokens, costUsd). The codex SDK reports no cost, so costUsd stays 0 — the same value already persisted to session_llm_requests for these calls, and consistent with #645's claude fallback convention.

Stacked on #645 (the costUsage turn-result field and turn_metrics columns land there) — rebase or merge order: #645 first.

opencode still reports no turn telemetry: its usage is only fetched in the post-return flush, so wiring it needs a small restructure — noted for follow-up rather than smuggled into this change.

Testing

  • New pure unit test for the mapping (usageToTurnTelemetry): totals → cache + spend shape, null for a no-usage turn. Green.
  • The JSON-RPC integration test's fake binary now emits outputTokens/cachedInputTokens in its final token-usage notification and asserts both telemetry fields on the turn result (passes where the fake-binary harness tests run; the 9 fake-binary tests fail identically with and without this change on this Windows host — spawn of a shebang script — so the stash differential for them is inconclusive locally).
  • tsc --noEmit clean against the stacked base.

Follow-up to #586


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…/metrics

The budget now debits the LlmCallUsage the harnesses meter, but an
operator planning which models to run qm on still had to join spend out
of session_llm_requests by hand: turn_metrics carried the cache columns
and no cost, no output tokens.

Harness turn results gain costUsage {outputTokens, costUsd} alongside
cacheUsage -- pi sums its per-call stats, claude reports the SDK's
running cost total with the fallback branch flagging unknown cost, and
the mock harness reports its deterministic usage. The orchestrator
lands both on TurnMetricSample, turn_metrics grows output_tokens and
cost_usd (ALTER TABLE ADD COLUMN IF NOT EXISTS, so existing deployments
migrate in place), and /v1/admin/metrics returns a spend block:
samples, turnsWithKnownCost, costUsdTotal, outputTokensTotal.

Follow-up to yc-software#586
codex accumulated full per-thread usage live but its turn result
carried none of it, so codex turns landed in turn_metrics without the
cache or spend telemetry pi and claude already report.

The turn result now maps the same thread totals the recordLlmRequest
flush uses, through one pure usageToTurnTelemetry helper: cacheUsage
(cacheRead/cacheWrite/uncachedInput) and costUsage (outputTokens,
costUsd). The codex SDK reports no cost, so costUsd stays 0 -- the same
value already persisted to session_llm_requests for these calls.

opencode still reports no turn telemetry: its usage is only fetched in
the post-return flush, so wiring it needs a restructure noted for
follow-up.

Follow-up to yc-software#586
The mapping is harness-agnostic; the next harness to report turn
telemetry imports it from the module that owns the result shape.
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.

1 participant