feat(billing): alibaba cache write/read tracking - #2323
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds explicit-cache detection and billing for Alibaba: pricing types and model data for cache read/write rates, updates cost calculation to accept an explicitCacheUsed flag, normalizes/prepares Alibaba cache_control in requests, extracts/mapping cache creation tokens from responses, and threads the flag through chat billing paths. ChangesAlibaba Explicit Cache Billing Support
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/actions/src/prepare-request-body.ts`:
- Around line 1018-1035: When stripping ttl from the cache_control object in the
asRecord branch, ensure we don't forward an empty cache_control or a record
missing type: after computing const { ttl: _ttl, ...ccRest } = cc, check if
Object.keys(ccRest).length === 0 || !("type" in asRecord); if so, return a copy
of asRecord with cache_control omitted (not set to {}), otherwise return the
spread with cache_control: ccRest; keep mutated = true and preserve the same
return casting/type as used around part and asRecord.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: f4087d09-43db-415b-9174-697176e5315b
📒 Files selected for processing (14)
apps/gateway/src/chat/chat.tsapps/gateway/src/chat/tools/extract-token-usage.spec.tsapps/gateway/src/chat/tools/extract-token-usage.tsapps/gateway/src/chat/tools/parse-provider-response.spec.tsapps/gateway/src/chat/tools/parse-provider-response.tsapps/gateway/src/chat/tools/transform-openai-streaming.spec.tsapps/gateway/src/chat/tools/transform-openai-streaming.tsapps/gateway/src/lib/alibaba-pricing.spec.tsapps/gateway/src/lib/costs.spec.tsapps/gateway/src/lib/costs.tspackages/actions/src/prepare-request-body.spec.tspackages/actions/src/prepare-request-body.tspackages/models/src/models.tspackages/models/src/models/alibaba.ts
…-tokens-tracking # Conflicts: # packages/actions/src/prepare-request-body.spec.ts # packages/actions/src/prepare-request-body.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/actions/src/prepare-request-body.spec.ts (1)
1445-1445: ⚡ Quick winReplace
as anywith a minimal typed response shape in the new Alibaba tests.Line 1445 and Line 1490 use
as any, which weakens assertions and hides shape regressions in this new path.Proposed typed test cast
- )) as any; + )) as { + messages: Array<{ + content: Array<{ + cache_control?: { type: "ephemeral"; ttl?: string }; + }>; + }>; + }; ... - )) as any; + )) as { + messages: Array<{ + content: Array<{ + cache_control?: { type: "ephemeral"; ttl?: string }; + }>; + }>; + };As per coding guidelines, "Never use
anytype or force cast withas anyunless absolutely necessary."Also applies to: 1490-1490
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/actions/src/prepare-request-body.spec.ts` at line 1445, Replace the two occurrences of "as any" in the new Alibaba tests with a minimal, explicit test interface that matches only the properties the assertions access; locate the casts in the Alibaba-specific tests in prepare-request-body.spec.ts (the two casts around the new Alibaba test path) and define a small type (e.g., MinimalAlibabaResponse) capturing just the fields used by the assertions, then cast the mocked response to that type instead of any so shape regressions are caught by the compiler and tests remain strict.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/actions/src/prepare-request-body.spec.ts`:
- Line 1445: Replace the two occurrences of "as any" in the new Alibaba tests
with a minimal, explicit test interface that matches only the properties the
assertions access; locate the casts in the Alibaba-specific tests in
prepare-request-body.spec.ts (the two casts around the new Alibaba test path)
and define a small type (e.g., MinimalAlibabaResponse) capturing just the fields
used by the assertions, then cast the mocked response to that type instead of
any so shape regressions are caught by the compiler and tests remain strict.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: cd39dfa9-42ea-4f5b-93f9-811cc5aee8c1
📒 Files selected for processing (5)
apps/gateway/src/chat/chat.tsapps/gateway/src/chat/tools/parse-provider-response.tspackages/actions/src/prepare-request-body.spec.tspackages/actions/src/prepare-request-body.tspackages/models/src/models.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/models/src/models.ts
- packages/actions/src/prepare-request-body.ts
- apps/gateway/src/chat/chat.ts
Summary
cache_creation_input_tokensfrom the nestedprompt_tokens_detailsshape, forwards thecache_control: {type: "ephemeral"}marker to the upstream (stripping unsupportedttl: "1h"), and bills writes at the 1.25× rate.cacheReadInputPriceschema field plus a request-sideexplicitCacheUsedflag so cache-read hits bill at Alibaba's 10% explicit rate whencache_controlwas sent vs. the 20% implicit rate otherwise — a fork Anthropic doesn't need since it only has explicit caching.cacheWriteInputPrice(125%) andcacheReadInputPrice(10%);qwen3-coder-pluscachedInputPricecorrected from a mislabelled 10% to the documented 20%.Test plan
ttl: "1h"strip🤖 Generated with Claude Code
Summary by CodeRabbit