fix: normalize OpenAI/Azure cached input tokens for correct cost persistence#23210
fix: normalize OpenAI/Azure cached input tokens for correct cost persistence#23210ibetitsmike wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f98e9acaa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000444_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
7f98e9a to
3d0aee4
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d0aee421b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000444_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
coderd/database/migrations/000444_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 04738d1ed6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000444_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c2d5e4f7a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000445_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 949eeb5759
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000445_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
949eeb5 to
a5a7514
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5a75147f6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000445_fix_openai_cache_token_double_count.up.sql
Outdated
Show resolved
Hide resolved
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e374c7b3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000446_fix_openai_cache_token_double_count.up.sql
Show resolved
Hide resolved
coderd/database/migrations/000446_fix_openai_cache_token_double_count.up.sql
Show resolved
Hide resolved
2e374c7 to
74543a1
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74543a19bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
coderd/database/migrations/000446_fix_openai_cache_token_double_count.up.sql
Show resolved
Hide resolved
…istence OpenAI reports prompt_tokens including cached tokens, and separately reports cached_tokens. The persistence path stored both values as-is, causing double-counted costs and inflated input token counts. Changes: - Add normalizePersistedUsage() helper that subtracts CacheReadTokens from InputTokens for openai/azure providers before persistence - Apply normalized usage for both cost calculation and DB insert - Add migration 000445 to correct historical rows (delta-only cost adjustment to preserve other pricing components) - Extend test fixtures, add unit/integration/regression tests - Clarify ChatMessageUsage field semantics in SDK docs
74543a1 to
3e05ad2
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. Swish! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Fortunately will be fixed upstream. |
Problem
OpenAI reports
prompt_tokens(mapped toInputTokens) including cached tokens, and separately reportscached_tokens(mapped toCacheReadTokens). The persistence path stored both values as-is, causing:CalculateTotalCostMicrospricedInputTokensat input rate +CacheReadTokensat cache rate, billing the cached portion twice.Anthropic reports these fields separately (InputTokens = non-cached only), so only OpenAI/Azure are affected.
Fix
coderd/chatd/usage.go):normalizePersistedUsage(provider, raw)subtractsCacheReadTokensfromInputTokensforopenaiandazureproviders. Returns a copy — rawstep.Usagestays untouched for compaction/context accounting.coderd/chatd/chatd.go): Uses normalized usage for bothusageForCostandInsertChatMessageparams.input_tokensand recomputestotal_cost_microsfor affected OpenAI/Azure rows. Preserves NULL (unpriced) costs.codersdk/chats.go): ClarifiesInputTokensis the non-cached billable bucket;TotalTokensis raw provider-reported.Tests
TestNormalizePersistedUsage— 6 table cases (subtract, clamp, explicit zero, both-zero, Anthropic unchanged, no-cache)TestPersistStepNormalizesCachedInput— end-to-end integration with mock OpenAI serverTestContextTokensFromUsage— compaction still uses raw (non-normalized) usageTestCalculateTotalCostMicros— Anthropic separate-bucket regressionTestChatCostSummary— cache tokens in summary aggregationTestMigrate(including UpDownUp) passes