Skip to content

第三方 Anthropic 代理 (gaccode 等) 测试连接使用模型别名导致失败,更新时 base_url 空字符串校验问题 #552

@TeamZaobi

Description

@TeamZaobi

问题描述

在服务商配置界面,对使用 Anthropic 协议的第三方代理(如 gaccode.com)进行测试连接更新配置时都会失败,但实际对话却能正常走通。

复现步骤

  1. 添加 Anthropic Third-party API 服务商,填入 base_url(如 https://gaccode.com/claudecode)和 API key
  2. 点击测试连接 → 失败
  3. 尝试编辑并保存已配置好的服务商 → 失败
  4. 但其他以前配好了服务的旧版CodePilot直接升级后,只要不碰这个服务商的配置,直接发起对话,模型工作正常 ✅

根因分析

问题 1:测试连接使用了模型别名

testProviderConnection 函数的模型名解析链:

modelName → preset.defaultRoleModels.default → preset.defaultModels[0].upstreamModelId → preset.defaultModels[0].modelId → "sonnet"

anthropic-thirdparty 预设的 defaultModels(变量 t,与 openrouter / litellm 共用)没有设置 upstreamModelId:

// 变量 t
[
  { modelId: "sonnet", displayName: "Sonnet 4.6", role: "sonnet", ... },
  { modelId: "opus", displayName: "Opus", role: "opus", ... },
  { modelId: "haiku", displayName: "Haiku 4.5", role: "haiku", ... },
]
// 注意:全都没有 upstreamModelId!

因此测试连接最终发送 {"model": "sonnet"} 到第三方代理。

但第三方代理(gaccode 等)不支持 Anthropic 的模型别名(sonnet/opus/haiku),只认完整模型 ID(如 claude-sonnet-4-20250514)。

实测验证:

model 值 HTTP 状态 响应
"sonnet" (别名) 500 No claude account available
"opus" (别名) 500 No claude account available
"haiku" (别名) 500 No claude account available
"claude-sonnet-4-20250514" (完整ID) 200 ✅ pong
"claude-opus-4-20250514" (完整ID) 200 ✅ pong
"claude-haiku-4-5-20251001" (完整ID) 200 ✅ pong

问题 2:更新时 base_url 空字符串校验

PUT handler 的验证逻辑:

const baseUrl = body.base_url !== undefined ? body.base_url : existing.base_url;
if (protocol === "anthropic" && !baseUrl?.trim()) {
  return { code: "ANTHROPIC_BASE_URL_REQUIRED" };
}

当前端表单提交 base_url: ""(空字符串而非 undefined)时,body.base_url !== undefined 为 true,触发此错误,即使该服务商原本已有有效的 base_url。

为什么实际对话能通?

detectTransport 对非 api.anthropic.com 的 base_url 返回 claude-code-compat 传输层,实际对话走 SDK 子进程,直接使用用户在 UI 中选择的完整模型 ID,不经过别名转换。

建议修复

修复 1(测试连接)

方案 A(快速):为第三方预设的 defaultModels 补充 upstreamModelId。但这不完美——第三方代理不一定托管所有官方模型,别名映射到错误模型也可能失败。

方案 B(根本):在测试连接界面提供模型输入框,让用户可以指定用哪个模型进行连通性测试,而不是硬编码推断。

修复 2(更新校验)

将空字符串 "" 等同于 undefined 处理:

const baseUrl = body.base_url || existing.base_url;

影响范围

  • 所有使用 anthropic-thirdparty 预设的第三方 Anthropic 代理(gaccode、LiteLLM、Ollama 等)
  • openrouter / litellm 预设也可能受影响(共用同一组 t 默认模型)

本 issue 基于客户端源码分析 + curl 实测验证。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions