fix(openai): account cached tokens for zhipu_v4 usage - #1982
Conversation
zhipu_v4 usage
WalkthroughAdds a usage post-processing hook to normalize cached token counts after initial usage computation, with body-based extraction for specific channels (DeepSeek, Zhipu_v4). Integrates this into OpenAI/OpenRouter flows and updates streaming support to include Zhipu_v4. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Relay as Relay Handler
participant Channel as Channel Impl
participant Upstream as Upstream API
Client->>Relay: Request (chat/completions)
Relay->>Upstream: Forward request
Upstream-->>Relay: Response (body, usage)
Relay->>Channel: Compute initial usage
note over Relay,Channel: New step: applyUsagePostProcessing
Channel->>Channel: If DeepSeek/Zhipu_v4: adjust CachedTokens
alt CachedTokens missing
Channel->>Channel: Extract from body (usage.prompt_tokens_details.cached_tokens<br/>or usage.cached_tokens or prompt_cache_hit_tokens)
end
Channel-->>Relay: Normalized usage
Relay-->>Client: Response (usage with CachedTokens)
%% Styling notes
rect rgba(230, 245, 255, 0.4)
note right of Channel: New/changed logic: post-processing & body extraction
end
sequenceDiagram
autonumber
actor Client
participant Relay as Relay (Streaming)
participant Zhipu as Zhipu_v4 API
Client->>Relay: Streaming request
Relay->>Zhipu: Initiate stream
Zhipu-->>Relay: Streamed chunks
Relay->>Relay: Post-process usage on finalization (Zhipu_v4 supported)
Relay-->>Client: Stream + final usage (with CachedTokens if extractable)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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: 0
🧹 Nitpick comments (2)
relay/channel/openai/relay-openai.go (2)
637-658: Consider documenting the precedence order for cached token extraction.The logic correctly handles multiple sources for cached tokens, but the precedence order for Zhipu_v4 (InputTokensDetails → body extraction → PromptCacheHitTokens) isn't immediately obvious.
Add a brief comment above the Zhipu_v4 case:
case constant.ChannelTypeZhipu_v4: + // Precedence: InputTokensDetails.CachedTokens > body extraction > PromptCacheHitTokens if usage.PromptTokensDetails.CachedTokens == 0 {
660-689: Consider adding debug logging for unmarshal failures.The function silently returns
(0, false)when JSON unmarshaling fails. While this is acceptable for best-effort extraction, adding debug logging could help diagnose issues when cached tokens aren't extracted as expected.Add debug logging for unmarshal errors:
if err := json.Unmarshal(body, &payload); err != nil { + if common.DebugEnabled { + common.LogDebug(fmt.Sprintf("Failed to extract cached tokens from response body: %v", err)) + } return 0, false }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
relay/channel/openai/relay-openai.go(3 hunks)relay/common/relay_info.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
relay/channel/openai/relay-openai.go (3)
dto/openai_response.go (1)
Usage(221-234)relay/common/relay_info.go (1)
RelayInfo(74-121)constant/channel.go (2)
ChannelTypeDeepSeek(43-43)ChannelTypeZhipu_v4(30-30)
relay/common/relay_info.go (1)
constant/channel.go (1)
ChannelTypeZhipu_v4(30-30)
🔇 Additional comments (4)
relay/common/relay_info.go (1)
264-264: LGTM! Correctly enables stream options support for Zhipu_v4.Adding
ChannelTypeZhipu_v4to thestreamSupportedChannelsmap enables theSupportStreamOptionsflag for this channel, which is essential for proper cached token billing in streaming responses.relay/channel/openai/relay-openai.go (3)
233-233: LGTM! Correctly applies post-processing with response body.The non-streaming handler correctly passes the
responseBodyto enable cached token extraction from the JSON payload when other fields are unavailable.
633-633: LGTM! Consistent post-processing in usage handler.Correctly applies the same post-processing pattern as the main handler.
168-169: Cached token extraction for Zhipu_v4 streaming is already handled. The streaming handler inrelay_responses.gopopulatesusage.PromptTokensDetails.CachedTokensfromInputTokensDetails, so callingapplyUsagePostProcessing(nil)safely captures cached tokens.
fix(openai): account cached tokens for zhipu_v4 usage
PR 类型
PR 是否包含破坏性更新?
PR 描述
为 Zhipu V4 渠道在通用 OpenAI适配器中新增缓存 token 处理逻辑,确保从usage 结构中正确提取 cached_tokens 并回写到
prompt_tokens_details。兼容流式与非流式响应,并在渠道元信息中启用 StreamOptions支持,使缓存命中能正确计费。
Summary by CodeRabbit
New Features
Bug Fixes