Skip to content

Commit a461538

Browse files
committed
fix: 修复gpt->claude转换无法命中codex缓存问题
1 parent ebe6f41 commit a461538

5 files changed

Lines changed: 40 additions & 1 deletion

File tree

backend/internal/handler/openai_gateway_handler.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,21 @@ func (h *OpenAIGatewayHandler) Messages(c *gin.Context) {
560560
sessionHash := h.gatewayService.GenerateSessionHash(c, body)
561561
promptCacheKey := h.gatewayService.ExtractSessionID(c, body)
562562

563+
// Anthropic 格式的请求在 metadata.user_id 中携带 session 标识,
564+
// 而非 OpenAI 的 session_id/conversation_id headers。
565+
// 从中派生 sessionHash(sticky session)和 promptCacheKey(upstream cache)。
566+
if sessionHash == "" || promptCacheKey == "" {
567+
if userID := strings.TrimSpace(gjson.GetBytes(body, "metadata.user_id").String()); userID != "" {
568+
seed := reqModel + "-" + userID
569+
if promptCacheKey == "" {
570+
promptCacheKey = service.GenerateSessionUUID(seed)
571+
}
572+
if sessionHash == "" {
573+
sessionHash = service.DeriveSessionHashFromSeed(seed)
574+
}
575+
}
576+
}
577+
563578
maxAccountSwitches := h.maxAccountSwitches
564579
switchCount := 0
565580
failedAccountIDs := make(map[int64]struct{})

backend/internal/service/gateway_service.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,11 @@ func (s *GatewayService) buildOAuthMetadataUserID(parsed *ParsedRequest, account
997997
return fmt.Sprintf("user_%s_account__session_%s", userID, sessionID)
998998
}
999999

1000+
// GenerateSessionUUID creates a deterministic UUID4 from a seed string.
1001+
func GenerateSessionUUID(seed string) string {
1002+
return generateSessionUUID(seed)
1003+
}
1004+
10001005
func generateSessionUUID(seed string) string {
10011006
if seed == "" {
10021007
return uuid.NewString()

backend/internal/service/openai_gateway_messages.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,12 @@ func (s *OpenAIGatewayService) ForwardAsAnthropic(
7878
if err := json.Unmarshal(responsesBody, &reqBody); err != nil {
7979
return nil, fmt.Errorf("unmarshal for codex transform: %w", err)
8080
}
81-
applyCodexOAuthTransform(reqBody, false, false)
81+
codexResult := applyCodexOAuthTransform(reqBody, false, false)
82+
if codexResult.PromptCacheKey != "" {
83+
promptCacheKey = codexResult.PromptCacheKey
84+
} else if promptCacheKey != "" {
85+
reqBody["prompt_cache_key"] = promptCacheKey
86+
}
8287
// OAuth codex transform forces stream=true upstream, so always use
8388
// the streaming response handler regardless of what the client asked.
8489
isStream = true

backend/internal/service/openai_gateway_service.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,6 +3646,13 @@ type OpenAIRecordUsageInput struct {
36463646
// RecordUsage records usage and deducts balance
36473647
func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRecordUsageInput) error {
36483648
result := input.Result
3649+
3650+
// 跳过所有 token 均为零的用量记录——上游未返回 usage 时不应写入数据库
3651+
if result.Usage.InputTokens == 0 && result.Usage.OutputTokens == 0 &&
3652+
result.Usage.CacheCreationInputTokens == 0 && result.Usage.CacheReadInputTokens == 0 {
3653+
return nil
3654+
}
3655+
36493656
apiKey := input.APIKey
36503657
user := input.User
36513658
account := input.Account

backend/internal/service/openai_sticky_compat.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ func openAIStickyCompatStats() (legacyReadFallbackTotal, legacyReadFallbackHit,
2929
openAIStickyLegacyDualWriteTotal.Load()
3030
}
3131

32+
// DeriveSessionHashFromSeed computes the current-format sticky-session hash
33+
// from an arbitrary seed string.
34+
func DeriveSessionHashFromSeed(seed string) string {
35+
currentHash, _ := deriveOpenAISessionHashes(seed)
36+
return currentHash
37+
}
38+
3239
func deriveOpenAISessionHashes(sessionID string) (currentHash string, legacyHash string) {
3340
normalized := strings.TrimSpace(sessionID)
3441
if normalized == "" {

0 commit comments

Comments
 (0)