feat: improve OpenAI messages compatibility for Claude Code

This commit is contained in:
lyen1688
2026-05-05 19:32:41 +08:00
parent 94e494319a
commit 0584305e5a
21 changed files with 2525 additions and 136 deletions
@@ -632,21 +632,7 @@ func (h *OpenAIGatewayHandler) Messages(c *gin.Context) {
sessionHash := h.gatewayService.GenerateSessionHash(c, body)
promptCacheKey := h.gatewayService.ExtractSessionID(c, body)
// Anthropic 格式的请求在 metadata.user_id 中携带 session 标识,
// 而非 OpenAI 的 session_id/conversation_id headers。
// 从中派生 sessionHashsticky session)和 promptCacheKeyupstream cache)。
if sessionHash == "" || promptCacheKey == "" {
if userID := strings.TrimSpace(gjson.GetBytes(body, "metadata.user_id").String()); userID != "" {
seed := reqModel + "-" + userID
if promptCacheKey == "" {
promptCacheKey = service.GenerateSessionUUID(seed)
}
if sessionHash == "" {
sessionHash = service.DeriveSessionHashFromSeed(seed)
}
}
}
sessionHash, promptCacheKey = resolveOpenAIMessagesMetadataSession(sessionHash, promptCacheKey, reqModel, body)
maxAccountSwitches := h.maxAccountSwitches
switchCount := 0
@@ -830,6 +816,20 @@ func (h *OpenAIGatewayHandler) Messages(c *gin.Context) {
}
}
func resolveOpenAIMessagesMetadataSession(sessionHash, promptCacheKey, reqModel string, body []byte) (string, string) {
// Anthropic metadata.user_id 只作为账号粘性信号。上游 GPT/Codex 缓存键
// 交给 ForwardAsAnthropic 从 cache_control 或完整消息 digest 派生,避免
// 固定 metadata key 压住后续 turn 的缓存滚动。
if sessionHash != "" {
return sessionHash, promptCacheKey
}
if userID := strings.TrimSpace(gjson.GetBytes(body, "metadata.user_id").String()); userID != "" {
seed := reqModel + "-" + userID
sessionHash = service.DeriveSessionHashFromSeed(seed)
}
return sessionHash, promptCacheKey
}
// anthropicErrorResponse writes an error in Anthropic Messages API format.
func (h *OpenAIGatewayHandler) anthropicErrorResponse(c *gin.Context, status int, errType, message string) {
c.JSON(status, gin.H{