fix(openai): inject stable compat prompt_cache_key for codex oauth chat-completions path
This commit is contained in:
81
backend/internal/service/openai_compat_prompt_cache_key.go
Normal file
81
backend/internal/service/openai_compat_prompt_cache_key.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/pkg/apicompat"
|
||||
)
|
||||
|
||||
const compatPromptCacheKeyPrefix = "compat_cc_"
|
||||
|
||||
func shouldAutoInjectPromptCacheKeyForCompat(model string) bool {
|
||||
switch normalizeCodexModel(strings.TrimSpace(model)) {
|
||||
case "gpt-5.4", "gpt-5.3-codex":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func deriveCompatPromptCacheKey(req *apicompat.ChatCompletionsRequest, mappedModel string) string {
|
||||
if req == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
normalizedModel := normalizeCodexModel(strings.TrimSpace(mappedModel))
|
||||
if normalizedModel == "" {
|
||||
normalizedModel = normalizeCodexModel(strings.TrimSpace(req.Model))
|
||||
}
|
||||
if normalizedModel == "" {
|
||||
normalizedModel = strings.TrimSpace(req.Model)
|
||||
}
|
||||
|
||||
seedParts := []string{"model=" + normalizedModel}
|
||||
if req.ReasoningEffort != "" {
|
||||
seedParts = append(seedParts, "reasoning_effort="+strings.TrimSpace(req.ReasoningEffort))
|
||||
}
|
||||
if len(req.ToolChoice) > 0 {
|
||||
seedParts = append(seedParts, "tool_choice="+normalizeCompatSeedJSON(req.ToolChoice))
|
||||
}
|
||||
if len(req.Tools) > 0 {
|
||||
if raw, err := json.Marshal(req.Tools); err == nil {
|
||||
seedParts = append(seedParts, "tools="+normalizeCompatSeedJSON(raw))
|
||||
}
|
||||
}
|
||||
if len(req.Functions) > 0 {
|
||||
if raw, err := json.Marshal(req.Functions); err == nil {
|
||||
seedParts = append(seedParts, "functions="+normalizeCompatSeedJSON(raw))
|
||||
}
|
||||
}
|
||||
|
||||
firstUserCaptured := false
|
||||
for _, msg := range req.Messages {
|
||||
switch strings.TrimSpace(msg.Role) {
|
||||
case "system":
|
||||
seedParts = append(seedParts, "system="+normalizeCompatSeedJSON(msg.Content))
|
||||
case "user":
|
||||
if !firstUserCaptured {
|
||||
seedParts = append(seedParts, "first_user="+normalizeCompatSeedJSON(msg.Content))
|
||||
firstUserCaptured = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return compatPromptCacheKeyPrefix + hashSensitiveValueForLog(strings.Join(seedParts, "|"))
|
||||
}
|
||||
|
||||
func normalizeCompatSeedJSON(v json.RawMessage) string {
|
||||
if len(v) == 0 {
|
||||
return ""
|
||||
}
|
||||
var tmp any
|
||||
if err := json.Unmarshal(v, &tmp); err != nil {
|
||||
return string(v)
|
||||
}
|
||||
out, err := json.Marshal(tmp)
|
||||
if err != nil {
|
||||
return string(v)
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
Reference in New Issue
Block a user