Skip to content

Support model names containing / without URL encoding#2

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-model-name-support
Draft

Support model names containing / without URL encoding#2
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-model-name-support

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 10, 2026

parsePathAndModel() splits the URL pathname on / to extract the model name as the last segment, making model names like z-ai/glm4.7 impossible to express — the slash is consumed as a path separator.

Changes

  • source/proxy.ts — Added a /~/ tilde-separator format that explicitly marks where the base URL ends and the model name begins, allowing any characters (including /) in the model name without encoding. The legacy last-segment format is preserved for backward compatibility, with decodeURIComponent() so %2F-encoded slashes also continue to work.
  • test/dynamic-routing.test.ts — Added tests for both the new /~/ separator format and the legacy %2F percent-encoding format, including assertions that the upstream API is called with the correct base URL and decoded model name.
  • README.md — Documented both URL formats with examples in the provider table and quick-start section.

URL Formats

Two formats are supported:

New tilde-separator format (recommended — no encoding required):

# Model "z-ai/glm4.7" — use /~/ to separate the base URL path from the model name
export ANTHROPIC_BASE_URL=https://claude-proxy.yinxulai.com/https/api.example.com/v1/~/z-ai/glm4.7

Legacy format (backward-compatible — %2F encoding still works):

# Model "z-ai/glm4.7" — encode the slash as %2F in the path
curl -X POST "https://claude-proxy.yinxulai.com/https/api.example.com/v1/z-ai%2Fglm4.7/v1/messages" \
  -H "x-api-key: your-key" \
  -d '{"model": "z-ai/glm4.7", "messages": [...], "max_tokens": 100}'

In the tilde-separator format, everything between /~/ and /v1/messages is treated as the model name, so slashes in model names require no special treatment.

Original prompt

This section details on the original issue you should resolve

<issue_title>模型名能否支持包含/,如"model": "z-ai/glm4.7",</issue_title>
<issue_description>openai请求如下:
curl -X POST "https://api-domain/path"
-H "Content-Type: application/json"
-H "Authorization: Bearer api-key"
-d '{
"model": "z-ai/glm4.7",
"messages": [
{
"role": "user",
"content": "Hello, world!"
}
]
}'
目前看好像不支持z-ai/glm4.7,这种包含/的模型名</issue_description>

<agent_instructions>看看目前是否支持,如果不支持可以提交一个 PR 处理下</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@yinxulai 暂不支持,考虑提个 PR 吗

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: yinxulai <22045569+yinxulai@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix model name support for slashes in model identifiers Support model names containing / via URL percent-encoding Mar 10, 2026
@yinxulai
Copy link
Copy Markdown
Owner

@copilot
不要求用户进行编码的方式下可以支持吗

Co-authored-by: yinxulai <22045569+yinxulai@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Mar 10, 2026

@copilot
不要求用户进行编码的方式下可以支持吗

支持了。新增了 /~/ 分隔符格式,在路径中用 /~/ 将 base URL 和模型名分开,/~/ 之后的所有内容(直到 /v1/messages)都作为模型名,无需任何编码:

# z-ai/glm4.7 直接放在 /~/ 后面,无需编码
export ANTHROPIC_BASE_URL=https://claude-proxy.yinxulai.com/https/api.example.com/v1/~/z-ai/glm4.7

代理收到 https://claude-proxy.yinxulai.com/https/api.example.com/v1/~/z-ai/glm4.7/v1/messages 后解析为:

  • base URL:https://api.example.com/v1
  • 模型名:z-ai/glm4.7

原有格式(模型名作为最后一段路径)以及 %2F 编码均保持向后兼容。相关变更在 b6eed75

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.unavailable.com
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --conditions node --conditions development /home/REDACTED/work/claude-proxy/claude-proxy/node_modules/tinypool/dist/entry/process.js (dns block)
  • invalid
    • Triggering command: /opt/hostedtoolcache/node/24.14.0/x64/bin/node /opt/hostedtoolcache/node/24.14.0/x64/bin/node --conditions node --conditions development /home/REDACTED/work/claude-proxy/claude-proxy/node_modules/tinypool/dist/entry/process.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Support model names containing / via URL percent-encoding Support model names containing / without URL encoding Mar 10, 2026
@yinxulai
Copy link
Copy Markdown
Owner

@copilot 给我提出几个实现方案,我希望的方案是对用户影响最小的那种,最好是可以保持当前用法完全不影响用户那种

Copy link
Copy Markdown
Author

Copilot AI commented Mar 10, 2026

@copilot 给我提出几个实现方案,我希望的方案是对用户影响最小的那种,最好是可以保持当前用法完全不影响用户那种

以下是几种可行方案,从对现有用户影响最大到最小排列:


方案 A:%2F 百分号编码(PR 原始版本)

ANTHROPIC_BASE_URL=.../https/api.example.com/v1/z-ai%2Fglm4.7
  • 需要用户对 / 进行 URL 编码
  • 对现有用户无影响,但新用户需要手动编码

方案 B:/~/ 分隔符(当前 PR 版本)

ANTHROPIC_BASE_URL=.../https/api.example.com/v1/~/z-ai/glm4.7
  • 明确分隔 base URL 和模型名,无需编码
  • 对现有用户无影响,但 URL 格式稍有变化

方案 C:x-model-name 请求头(对用户影响最小)

  • URL 只包含 base URL,模型名通过自定义请求头传递:
    ANTHROPIC_BASE_URL=.../https/api.example.com/v1
    Header: x-model-name: z-ai/glm4.7
    
  • 完全不影响 URL 格式,现有用户零改动
  • 缺点:客户端需要支持发送自定义请求头(Claude Code 通过 ANTHROPIC_HEADERS 环境变量可以做到)

方案 D:/vN/ 版本号启发式识别(URL 格式完全不变)

检测路径中最后一个 /v{数字}/ 作为 base URL 的结束点,其后所有内容为模型名:

/https/api.example.com/v1/z-ai/glm4.7  →  baseUrl=.../v1, model=z-ai/glm4.7
/https/api.openai.com/v1/gpt-4o        →  baseUrl=.../v1, model=gpt-4o
  • URL 格式完全不变,现有用户零改动
  • 缺点:依赖路径中必须有 /v{N}/;对于 api.some-provider.com/api/v2/openai/custom-model 这类 base URL 含有非版本额外路径段的情况会解析错误(已有测试用例覆盖这一场景,会 break)

我的推荐

如果目标是"对现有用户影响最小":

  • 方案 C(自定义请求头) 是唯一一个不需要修改任何已有 URL 格式的方案,现有用户完全无感知。可以同时保留 URL 路径方式作为兜底,两种方式共存。

如果接受方案 C,我可以实现:当请求头 x-model-name 存在时,优先用它作为模型名,URL 路径只作为 base URL;否则回退到当前的路径解析逻辑(兼容所有现有用法)。请告知选择哪种方案。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

模型名能否支持包含/,如"model": "z-ai/glm4.7",

2 participants