Skip to content

fix: OpenAI 路径添加防御性 usage 合并逻辑#1232

Closed
Evsdrg wants to merge 1 commit into
claude-code-best:mainfrom
Evsdrg:fix/openai-cache-guards
Closed

fix: OpenAI 路径添加防御性 usage 合并逻辑#1232
Evsdrg wants to merge 1 commit into
claude-code-best:mainfrom
Evsdrg:fix/openai-cache-guards

Conversation

@Evsdrg
Copy link
Copy Markdown
Contributor

@Evsdrg Evsdrg commented May 16, 2026

Summary

将 OpenAI 路径中 message_delta 处理器的 { ...usage, ...deltaUsage }
spread 替换为 updateOpenAIUsage() 函数,与 claude.tsupdateUsage()
模式保持一致。

当前 OpenAI 适配器发送的 message_delta 包含完整字段,spread 不会丢失
数据。但若未来适配器在某事件中省略了 cache 字段(传 explicit 0),spread
会无声覆盖有效值。新函数仅在 delta 字段有意义值时更新,否则保留当前值。

Context

跨 provider 缓存兼容性分析(见 PR #1225 的后续讨论)发现:

  • Anthropic 路径使用 updateUsage() 做字段级保护合���
  • OpenAI 路径使用裸 { ...usage, ...deltaUsage } spread,缺少防御
  • Codex/ChatGPT Responses API 路径同理(走同一个 message_delta 处理器)

Test plan

  • tsc --noEmit 零错误
  • biome format 零差异
  • biome lint 零违规

🤖 Generated with Claude Code Best

Summary by CodeRabbit

  • Bug Fixes
    • Improved token usage tracking for OpenAI API calls to accurately preserve cache-related metrics and prevent unintended resets of cached token counts.

Review Change Stack

将 message_delta 处理器中的 `{ ...usage, ...deltaUsage }` spread
替换为 updateOpenAIUsage() 函数,与 claude.ts 的 updateUsage() 模式
保持一致。

当前适配器发送的 message_delta 包含完整字段,spread 不会丢失数据。
但若未来适配器在某事件中省略了 cache 字段(传 explicit 0),spread
会无声覆盖有效值。新函数仅在 delta 字段有意义值时更新,否则保留
当前值。

Co-Authored-By: deepseek-v4-pro[1m] <deepseek-ai@claude-code-best.win>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6d1e45f7-3285-4691-bdfd-0229040f06f9

📥 Commits

Reviewing files that changed from the base of the PR and between 5b941d4 and 59ab664.

📒 Files selected for processing (1)
  • src/services/api/openai/index.ts

📝 Walkthrough

Walkthrough

The OpenAI streaming adapter adds defensive merging logic for incremental token-usage updates. A new updateOpenAIUsage() helper preserves cache-related token fields (cache-creation and cache-read tokens) when streaming deltas provide zeros, preventing accidental zeroing of prior valid metrics. The helper is applied at the message_delta usage accumulation point, replacing a shallow object spread.

Changes

OpenAI Token Usage Defense

Layer / File(s) Summary
Defensive usage merge helper and application
src/services/api/openai/index.ts
Add updateOpenAIUsage() to selectively merge token deltas, updating input/output tokens directly while preserving cache token fields against zero overwrites. Apply the helper at message_delta accumulation to replace shallow spread.

Possibly related PRs

  • claude-code-best/claude-code#226: Both PRs address OpenAI stream usage merging/mapping in the OpenAI adapter flow—specifically preserving/propagating message_delta token usage (including cache-related fields) and ensuring correct stop_reason/assembled AssistantMessage output.

Poem

A spreadsheet once flat could not hold its ground,
When zeros came crashing with nary a sound,
But updateOpenAIUsage() builds walls strong and true—
Cache tokens now safe from the overwrite crew! 🐰✨


🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title is in Chinese and describes the main change: adding defensive usage merge logic to the OpenAI path, which matches the file changes summary about implementing updateOpenAIUsage() helper for safer token-usage merging.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Evsdrg
Copy link
Copy Markdown
Contributor Author

Evsdrg commented May 16, 2026

Superseded by PR #1234 which extracts the same fix into a shared module (openaiShared.ts) used by both OpenAI and Grok paths.

@Evsdrg Evsdrg closed this May 16, 2026
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