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
Summary
codex-acpsendsUsageUpdatenotifications and can populatePromptResponse.usage, butUsageUpdate.costis alwaysnull.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
PromptResponse.usage: fixable incodex-acp(covered by Populate PromptResponse.usage from Codex token usage #210)UsageUpdate.used/UsageUpdate.size: available todayUsageUpdate.cost: alwaysnullRoot 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_usdon result messages, which is whyclaude-agent-acpcan populateUsageUpdate.costtoday.Why this matters
ACP defines cumulative cost on
UsageUpdate.cost, and clients (OpenHands, Zed, benchmark harnesses) already consume it when present. Without it:$0.00instead 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-acpcould compute an estimated cost locally using the token breakdown already available inTokenCountEventand a model pricing table.Available signals at the point where
UsageUpdateis sent:self.get_current_model()TokenCountEvent.info.last_token_usageTokenCountEvent.info.last_token_usageTokenCountEvent.info.last_token_usageTokenCountEvent.info.last_token_usageCodexAuthMethod(ChatGpt / CodexApiKey / OpenAiApiKey)Proposed approach:
TokenCountEvent, compute incremental cost fromlast_token_usageand accumulate across the sessionCodexAuthMethod::ChatGpt(subscription users): setcost: None— no meaningful per-token costcost: Some(Cost::new(amount, "USD"))Caveats:
/fastmode. (Also tracked in openai/codex#13794.)Even with these limitations, an estimate is significantly better than
null/$0.00for API-key users, and the field can be upgraded to the authoritative upstream signal once openai/codex#16258 is addressed.Related
used/size), cost still missingPromptResponse.usage