From 4aedbfc4a80526a90c696c9249d3bd9d1b3fe205 Mon Sep 17 00:00:00 2001 From: jjaw Date: Wed, 15 Jul 2026 06:54:59 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=20OpenAI=20=E8=BD=AC?= =?UTF-8?q?=E5=8F=91=E5=A4=8D=E7=94=A8=E8=BE=B9=E7=95=8C=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/handler/openai_gateway_handler.go | 1 + backend/internal/service/openai_gateway_forward.go | 1 + backend/internal/service/openai_gateway_passthrough.go | 7 ++++--- backend/internal/service/openai_image_intent_hint.go | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index 52d039c4f..5455a3e9f 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -58,6 +58,7 @@ func openAIModelMappedBody(body []byte, mapped bool, mappedModel string, replace func seedOpenAIForwardImageIntentHint(c *gin.Context, channelMapped bool, imageIntent bool) { if channelMapped { + // 渠道映射改变了规范请求,保持 unknown,由 Forward 按映射后的 model/body 初始化。 return } service.SetOpenAIImageIntentHint(c, imageIntent) diff --git a/backend/internal/service/openai_gateway_forward.go b/backend/internal/service/openai_gateway_forward.go index 76a573150..e4915f3ef 100644 --- a/backend/internal/service/openai_gateway_forward.go +++ b/backend/internal/service/openai_gateway_forward.go @@ -20,6 +20,7 @@ import ( // Forward forwards request to OpenAI API func (s *OpenAIGatewayService) Forward(ctx context.Context, c *gin.Context, account *Account, body []byte) (*OpenAIForwardResult, error) { startTime := time.Now() + // 固定渠道映射后的请求级 canonical body;账号 normalize/strip 不得改写跨 failover hint。 canonicalImageIntentBody := body restrictionResult := s.detectCodexClientRestriction(c, account, body) diff --git a/backend/internal/service/openai_gateway_passthrough.go b/backend/internal/service/openai_gateway_passthrough.go index a439061c8..d27fa0798 100644 --- a/backend/internal/service/openai_gateway_passthrough.go +++ b/backend/internal/service/openai_gateway_passthrough.go @@ -1,8 +1,6 @@ package service -// 本文件由 openai_gateway_service.go 纯移动拆分而来:/v1/responses 直通 -// (passthrough)转发路径及其流式/非流式响应处理与错误处理。仅做代码搬迁, -// 无任何行为变更。 +// 本文件承载 /v1/responses 透传转发及其流式、非流式响应与错误处理。 import ( "bufio" @@ -103,6 +101,7 @@ func (s *OpenAIGatewayService) forwardOpenAIPassthrough( body = updatedBody apiKey := getAPIKeyFromContext(c) + // 同一 attempt 的最终 model/body 只判定一次,权限检查与后续图片状态设置共用该结果。 imageIntent := resolveOpenAIPassthroughImageIntent( c, reqModel, @@ -874,7 +873,9 @@ func (s *OpenAIGatewayService) handleStreamingResponsePassthrough( failedMessage := "" clientOutputStarted := false upstreamRequestID := strings.TrimSpace(resp.Header.Get("x-request-id")) + // pendingLines 在首个可见输出前保留前导事件,确保无输出失败仍可安全 failover。 pendingLines := make([]string, 0, 8) + // flushPending 表示已写入但未到 SSE 空行边界的脏状态;defer 兜底函数退出前的残留,断连后不再 Flush。 flushPending := false flushPendingOutput := func() { if clientDisconnected || !flushPending { diff --git a/backend/internal/service/openai_image_intent_hint.go b/backend/internal/service/openai_image_intent_hint.go index e5a1e8f0b..f8f966e5f 100644 --- a/backend/internal/service/openai_image_intent_hint.go +++ b/backend/internal/service/openai_image_intent_hint.go @@ -2,11 +2,12 @@ package service import "github.com/gin-gonic/gin" +// 请求级 hint 仅限 HTTP:缺失表示 unknown,false/true 都表示已完成 canonical 判定。 const openAIImageIntentHintContextKey = "openai_image_intent_hint" type openAIImageIntentClassifier func(endpoint string, requestedModel string, body []byte) bool -// SetOpenAIImageIntentHint records the canonical request body's image intent. +// SetOpenAIImageIntentHint 只写入请求级 canonical 判定,不记录 attempt-local 结果。 func SetOpenAIImageIntentHint(c *gin.Context, imageIntent bool) { if c == nil || GetOpenAIClientTransport(c) != OpenAIClientTransportHTTP { return @@ -51,6 +52,7 @@ func resolveOpenAIPassthroughImageIntent( ) bool { imageIntent := resolveOpenAIImageIntentHint(c, canonicalRequestedModel, canonicalBody, classify) if attemptInvalidated { + // strip/compact 改写只重算当前 attempt,不得把变换后的结果写回请求级 canonical hint。 imageIntent = classify(openAIResponsesEndpoint, attemptRequestedModel, attemptBody) } return imageIntent