From a97272236729779826a2cece1166a2200dc28112 Mon Sep 17 00:00:00 2001 From: Seefs Date: Sat, 7 Feb 2026 14:21:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8openai=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=B8=A0=E9=81=93=E5=9C=A8=E6=9C=80=E7=BB=88=E7=AB=AF=E7=82=B9?= =?UTF-8?q?=E4=B8=BAclaude=E5=8E=9F=E7=94=9F=E7=AB=AF=E7=82=B9=E4=B8=8B?= =?UTF-8?q?=E8=BF=98=E6=98=AF=E8=B5=B0=E4=BA=86openai=E6=89=A3=E5=87=8Finp?= =?UTF-8?q?ut=5Ftoken=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- relay/channel/ali/adaptor.go | 7 ++----- relay/channel/claude/adaptor.go | 1 + relay/channel/codex/adaptor.go | 8 ++++---- relay/channel/deepseek/adaptor.go | 7 ++----- relay/channel/moonshot/adaptor.go | 7 ++----- relay/channel/vertex/adaptor.go | 5 +++-- relay/channel/volcengine/adaptor.go | 6 ++---- relay/channel/zhipu_4v/adaptor.go | 7 ++----- relay/common/relay_info.go | 2 ++ relay/compatible_handler.go | 2 +- 10 files changed, 21 insertions(+), 31 deletions(-) diff --git a/relay/channel/ali/adaptor.go b/relay/channel/ali/adaptor.go index f3cc4b6c..faf70981 100644 --- a/relay/channel/ali/adaptor.go +++ b/relay/channel/ali/adaptor.go @@ -223,11 +223,8 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom switch info.RelayFormat { case types.RelayFormatClaude: if supportsAliAnthropicMessages(info.UpstreamModelName) { - if info.IsStream { - return claude.ClaudeStreamHandler(c, resp, info) - } - - return claude.ClaudeHandler(c, resp, info) + adaptor := claude.Adaptor{} + return adaptor.DoResponse(c, resp, info) } adaptor := openai.Adaptor{} diff --git a/relay/channel/claude/adaptor.go b/relay/channel/claude/adaptor.go index 29595391..a713c17d 100644 --- a/relay/channel/claude/adaptor.go +++ b/relay/channel/claude/adaptor.go @@ -95,6 +95,7 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request } func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { + info.FinalRequestRelayFormat = types.RelayFormatClaude if info.IsStream { return ClaudeStreamHandler(c, resp, info) } else { diff --git a/relay/channel/codex/adaptor.go b/relay/channel/codex/adaptor.go index d8a4e866..42f3b8e4 100644 --- a/relay/channel/codex/adaptor.go +++ b/relay/channel/codex/adaptor.go @@ -26,7 +26,7 @@ func (a *Adaptor) ConvertGeminiRequest(c *gin.Context, info *relaycommon.RelayIn } func (a *Adaptor) ConvertClaudeRequest(*gin.Context, *relaycommon.RelayInfo, *dto.ClaudeRequest) (any, error) { - return nil, errors.New("codex channel: endpoint not supported") + return nil, errors.New("codex channel: /v1/messages endpoint not supported") } func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.AudioRequest) (io.Reader, error) { @@ -41,15 +41,15 @@ func (a *Adaptor) Init(info *relaycommon.RelayInfo) { } func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayInfo, request *dto.GeneralOpenAIRequest) (any, error) { - return nil, errors.New("codex channel: endpoint not supported") + return nil, errors.New("codex channel: /v1/chat/completions endpoint not supported") } func (a *Adaptor) ConvertRerankRequest(c *gin.Context, relayMode int, request dto.RerankRequest) (any, error) { - return nil, errors.New("codex channel: endpoint not supported") + return nil, errors.New("codex channel: /v1/rerank endpoint not supported") } func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.EmbeddingRequest) (any, error) { - return nil, errors.New("codex channel: endpoint not supported") + return nil, errors.New("codex channel: /v1/embeddings endpoint not supported") } func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) { diff --git a/relay/channel/deepseek/adaptor.go b/relay/channel/deepseek/adaptor.go index 6de2653b..57fcf3d0 100644 --- a/relay/channel/deepseek/adaptor.go +++ b/relay/channel/deepseek/adaptor.go @@ -95,11 +95,8 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { switch info.RelayFormat { case types.RelayFormatClaude: - if info.IsStream { - return claude.ClaudeStreamHandler(c, resp, info) - } else { - return claude.ClaudeHandler(c, resp, info) - } + adaptor := claude.Adaptor{} + return adaptor.DoResponse(c, resp, info) default: adaptor := openai.Adaptor{} return adaptor.DoResponse(c, resp, info) diff --git a/relay/channel/moonshot/adaptor.go b/relay/channel/moonshot/adaptor.go index 25a6e2a3..c2f6ee4a 100644 --- a/relay/channel/moonshot/adaptor.go +++ b/relay/channel/moonshot/adaptor.go @@ -102,11 +102,8 @@ func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *relaycommon.Rela func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { switch info.RelayFormat { case types.RelayFormatClaude: - if info.IsStream { - return claude.ClaudeStreamHandler(c, resp, info) - } else { - return claude.ClaudeHandler(c, resp, info) - } + adaptor := claude.Adaptor{} + return adaptor.DoResponse(c, resp, info) default: adaptor := openai.Adaptor{} return adaptor.DoResponse(c, resp, info) diff --git a/relay/channel/vertex/adaptor.go b/relay/channel/vertex/adaptor.go index 7c48907e..c8d27276 100644 --- a/relay/channel/vertex/adaptor.go +++ b/relay/channel/vertex/adaptor.go @@ -365,10 +365,11 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request } func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { + claudeAdaptor := claude.Adaptor{} if info.IsStream { switch a.RequestMode { case RequestModeClaude: - return claude.ClaudeStreamHandler(c, resp, info) + return claudeAdaptor.DoResponse(c, resp, info) case RequestModeGemini: if info.RelayMode == constant.RelayModeGemini { return gemini.GeminiTextGenerationStreamHandler(c, info, resp) @@ -381,7 +382,7 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom } else { switch a.RequestMode { case RequestModeClaude: - return claude.ClaudeHandler(c, resp, info) + return claudeAdaptor.DoResponse(c, resp, info) case RequestModeGemini: if info.RelayMode == constant.RelayModeGemini { return gemini.GeminiTextGenerationHandler(c, info, resp) diff --git a/relay/channel/volcengine/adaptor.go b/relay/channel/volcengine/adaptor.go index 22caa6b9..9f2b8e80 100644 --- a/relay/channel/volcengine/adaptor.go +++ b/relay/channel/volcengine/adaptor.go @@ -347,10 +347,8 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { if info.RelayFormat == types.RelayFormatClaude { if _, ok := channelconstant.ChannelSpecialBases[info.ChannelBaseUrl]; ok { - if info.IsStream { - return claude.ClaudeStreamHandler(c, resp, info) - } - return claude.ClaudeHandler(c, resp, info) + adaptor := claude.Adaptor{} + return adaptor.DoResponse(c, resp, info) } } diff --git a/relay/channel/zhipu_4v/adaptor.go b/relay/channel/zhipu_4v/adaptor.go index 7e25c7ca..597c4859 100644 --- a/relay/channel/zhipu_4v/adaptor.go +++ b/relay/channel/zhipu_4v/adaptor.go @@ -109,11 +109,8 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { switch info.RelayFormat { case types.RelayFormatClaude: - if info.IsStream { - return claude.ClaudeStreamHandler(c, resp, info) - } else { - return claude.ClaudeHandler(c, resp, info) - } + adaptor := claude.Adaptor{} + return adaptor.DoResponse(c, resp, info) default: if info.RelayMode == relayconstant.RelayModeImagesGenerations { return zhipu4vImageHandler(c, resp, info) diff --git a/relay/common/relay_info.go b/relay/common/relay_info.go index 96f68d47..e71ebdfa 100644 --- a/relay/common/relay_info.go +++ b/relay/common/relay_info.go @@ -145,6 +145,8 @@ type RelayInfo struct { // RequestConversionChain records request format conversions in order, e.g. // ["openai", "openai_responses"] or ["openai", "claude"]. RequestConversionChain []types.RelayFormat + // 最终请求到上游的格式 TODO: 当前仅设置了Claude + FinalRequestRelayFormat types.RelayFormat ThinkingContentInfo TokenCountMeta diff --git a/relay/compatible_handler.go b/relay/compatible_handler.go index 21180d8d..eeb7b7aa 100644 --- a/relay/compatible_handler.go +++ b/relay/compatible_handler.go @@ -334,7 +334,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, usage var audioInputQuota decimal.Decimal var audioInputPrice float64 - isClaudeUsageSemantic := relayInfo.ChannelType == constant.ChannelTypeAnthropic + isClaudeUsageSemantic := relayInfo.FinalRequestRelayFormat == types.RelayFormatClaude if !relayInfo.PriceData.UsePrice { baseTokens := dPromptTokens // 减去 cached tokens