Skip to content

UsageUpdate.cost is still not populated for codex-acp #209

@simonrosenberg

Description

@simonrosenberg

Summary

codex-acp sends UsageUpdate notifications and can populate PromptResponse.usage, but UsageUpdate.cost is always null.

ACP clients cannot report cumulative session cost for Codex ACP sessions, and many render this as $0.00 — which is misleading because the data is unavailable rather than zero.

Current state

Root cause

The OpenAI Responses API does not return any cost or pricing information — only token counts (input_tokens, output_tokens, cached_tokens, reasoning_tokens, total_tokens). The upstream Codex event stream (TokenCountEvent) faithfully forwards these counts but carries no cost signal.

For comparison, the Claude Agent SDK exposes total_cost_usd on result messages, which is why claude-agent-acp can populate UsageUpdate.cost today.

Why this matters

ACP defines cumulative cost on UsageUpdate.cost, and clients (OpenHands, Zed, benchmark harnesses) already consume it when present. Without it:

  • Benchmark runs cannot compare spend across ACP and non-ACP agents
  • Client telemetry remains incomplete
  • UIs show a misleading $0.00 instead of "unknown"

Upstream request

Filed openai/codex#16258 requesting that Codex expose an authoritative cumulative session cost in its event stream. Codex is the only component that knows the model, service tier, and billing method — making it the right place to compute cost. This is the ideal long-term fix.

Interim solution: derive cost from token counts

Until the upstream is addressed, codex-acp could compute an estimated cost locally using the token breakdown already available in TokenCountEvent and a model pricing table.

Available signals at the point where UsageUpdate is sent:

Signal Available Source
Model name Yes self.get_current_model()
Input tokens Yes TokenCountEvent.info.last_token_usage
Cached input tokens Yes TokenCountEvent.info.last_token_usage
Output tokens Yes TokenCountEvent.info.last_token_usage
Reasoning tokens Yes TokenCountEvent.info.last_token_usage
Auth method Yes CodexAuthMethod (ChatGpt / CodexApiKey / OpenAiApiKey)
Service tier No Not exposed (see openai/codex#13794)

Proposed approach:

  • Maintain a pricing table mapping model slug → per-million-token rates (input / cached input / output / reasoning)
  • On each TokenCountEvent, compute incremental cost from last_token_usage and accumulate across the session
  • For CodexAuthMethod::ChatGpt (subscription users): set cost: None — no meaningful per-token cost
  • For API-key auth: set cost: Some(Cost::new(amount, "USD"))

Caveats:

  • Service tier: Codex can reroute to different tiers with different pricing. Without a tier signal, this computes against base model rates — may undercount for /fast mode. (Also tracked in openai/codex#13794.)
  • Pricing drift: model pricing changes occasionally, requiring table updates
  • Cached input discount: OpenAI charges ~50% less for cached tokens on most models — known and can be applied

Even with these limitations, an estimate is significantly better than null / $0.00 for API-key users, and the field can be upgraded to the authoritative upstream signal once openai/codex#16258 is addressed.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions