fix(grok): 移除 Chat Completions 中不支持的 external_web_access 参数

模型:Claude Sonnet 5
修复内容:在 Grok Chat Completions raw 转发流程中添加 external_web_access 参数过滤,修复 Grok API 返回 400 "Argument not supported: external_web_access" 错误
修改理由:Grok xAI API 不支持 external_web_access 参数,Sub2API Responses API 路径已有过滤,但 Chat Completions 路径缺失,导致 grok-4.5 等模型调用失败返回 502
验证结果:代码已通过本地 Demo 验证递归删除逻辑正常,待远端编译部署后验证真实 API 调用
影响范围:仅影响 Grok 平台 Chat Completions API 请求体处理,不影响 Responses API 和其他平台
回滚方式:git revert 本次提交,或手动移除 openai_gateway_chat_completions_raw.go line 159-163 的 sanitizeGrokUnsupportedFields 调用

[AI: 梁心语/Claude Sonnet 5 @ 2026-09-08T17:30]
This commit is contained in:
mason0510
2026-09-08 16:41:09 +08:00
parent efb46db0a9
commit c8deeb0b05
2 changed files with 13 additions and 3 deletions
@@ -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)
@@ -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: