diff --git a/backend/internal/service/openai_gateway_chat_completions_raw.go b/backend/internal/service/openai_gateway_chat_completions_raw.go index 7427c6fc9c..9d7234dd96 100644 --- a/backend/internal/service/openai_gateway_chat_completions_raw.go +++ b/backend/internal/service/openai_gateway_chat_completions_raw.go @@ -156,6 +156,10 @@ func (s *OpenAIGatewayService) forwardAsRawChatCompletions( if err != nil { return nil, fmt.Errorf("normalize Grok chat reasoning effort: %w", err) } + upstreamBody, err = sanitizeGrokUnsupportedFields(upstreamBody) + if err != nil { + return nil, fmt.Errorf("sanitize Grok unsupported fields: %w", err) + } } upstreamBody = applyOllamaCloudRawChatCompletionsRequest(account, upstreamBody) diff --git a/backend/internal/service/openai_gateway_grok.go b/backend/internal/service/openai_gateway_grok.go index 21c7342356..34fdc82e67 100644 --- a/backend/internal/service/openai_gateway_grok.go +++ b/backend/internal/service/openai_gateway_grok.go @@ -752,11 +752,14 @@ func grokSupportsReasoningEffort(model string) bool { } } -var grokResponsesUnsupportedRecursiveFields = map[string]struct{}{ +// grokUnsupportedRecursiveFields 定义 Grok 平台(Responses 和 Chat Completions)不支持的字段 +var grokUnsupportedRecursiveFields = map[string]struct{}{ "external_web_access": {}, } -func sanitizeGrokResponsesUnsupportedFields(body []byte) ([]byte, error) { +// sanitizeGrokUnsupportedFields 递归移除 Grok 平台不支持的字段 +// 适用于 Responses API 和 Chat Completions API +func sanitizeGrokUnsupportedFields(body []byte) ([]byte, error) { if !bytes.Contains(body, []byte(`"external_web_access"`)) { return body, nil } @@ -765,12 +768,15 @@ func sanitizeGrokResponsesUnsupportedFields(body []byte) ([]byte, error) { if err := decodeOpenAIJSONUseNumber(body, &payload); err != nil { return nil, err } - if !deleteJSONFields(payload, grokResponsesUnsupportedRecursiveFields) { + if !deleteJSONFields(payload, grokUnsupportedRecursiveFields) { return body, nil } return marshalOpenAIUpstreamJSON(payload) } +// sanitizeGrokResponsesUnsupportedFields 保留旧函数名作为别名,向后兼容 +var sanitizeGrokResponsesUnsupportedFields = sanitizeGrokUnsupportedFields + func deleteJSONFields(value any, fields map[string]struct{}) bool { switch typed := value.(type) { case map[string]any: