Skip to content

feat(config): tolerate /v1 base-url convention in endpoint connectivity probe - #23

Merged
RowitZou merged 1 commit into
mainfrom
feature/baseurl-tolerant
Jun 26, 2026
Merged

feat(config): tolerate /v1 base-url convention in endpoint connectivity probe#23
RowitZou merged 1 commit into
mainfrom
feature/baseurl-tolerant

Conversation

@RowitZou

Copy link
Copy Markdown
Owner

背景

OpenAI / Anthropic 两个 SDK 的 baseURL 约定不同:OpenAI 的带 /v1https://api.openai.com/v1),Anthropic 的不带(SDK 自己补 /v1/...)。用户配 endpoint 时经常填错形式——最常见是给 openai 网关填了不带 /v1host:port——导致探针/wire 打到 404 或网关的 HTML 网页。

改动

endpoint 连通性探针现在容忍 /v1 约定:先试用户填的原值(非标网关路径仍能命中),再试约定修正后的候选(openai 缺 /v1 就补、anthropic 多 /v1 就去),哪个真能列出 model 就用哪个。探针实际打通的那个 base-url 被持久化并显示在结果卡上——不是盲改,没有额外提示文案,存的就是验证过的 wire 路径。

  • list-models.tsapiKeyBaseUrlCandidates + listApiKeyModelsResolvingBaseUrl(优先选能列 model 的候选,否则首个可达,否则首个错误)。
  • config.ts / admin.ts:探针返回 resolvedBaseUrl;endpoint add/set(/config/admin 两面)持久化它而非用户原值。

测试

候选生成 + 容忍 lister 单测(openai 缺 /v1 → 解析成 +/v1、anthropic 错带 /v1 → 去掉、全不可达 → 返回首个错误);config 持久化测试断言 resolved base-url 落进 config.json(旧码上 fail)。全量 2616/2616、typecheck 干净。

🤖 Generated with Claude Code

…tivity probe

OpenAI and Anthropic SDKs take `baseURL` differently — OpenAI's includes the
`/v1` segment, Anthropic's does not (the SDK appends `/v1/...` itself). Users
routinely paste the wrong shape (most often a bare `host:port` for an openai
gateway that needs `/v1`), and the probe / wire then 404s or hits the gateway's
HTML web UI.

The endpoint connectivity probe now resolves the base-url tolerantly: it tries
the value AS-GIVEN first (so a non-standard gateway path still works), then the
convention-corrected alternative (openai: +`/v1` when missing; anthropic: strip
a trailing `/v1`), and keeps whichever actually lists models. The base-url that
responded is persisted and shown on the result card, so the stored endpoint
matches the verified wire path — no blind rewrite, no extra hint text.

- list-models.ts: `apiKeyBaseUrlCandidates` + `listApiKeyModelsResolvingBaseUrl`
  (prefers a candidate that lists models, else first reachable, else first error).
- config.ts / admin.ts: probe returns `resolvedBaseUrl`; endpoint add/set
  (both /config and /admin) persist it instead of the raw typed value.

Tests: candidate-generation + tolerant-lister unit tests (openai-missing-/v1
resolves to +/v1, anthropic-wrong-/v1 strips, all-unreachable returns first
error); config persist test asserts the resolved base-url lands in config.json
(fails on old code). Full suite 2616/2616, typecheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 26, 2026 09:14
@RowitZou
RowitZou merged commit e0c059a into main Jun 26, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the endpoint connectivity probe to tolerate differing /v1 base-url conventions between OpenAI-style and Anthropic-style apiKey endpoints by probing multiple base-url candidates and persisting the base-url that actually responded.

Changes:

  • Add base-url candidate generation and a tolerant model-lister that resolves a working base-url (/v1 add/remove) while probing.
  • Thread resolvedBaseUrl through the /config and /admin endpoint probe paths and persist the resolved base-url on add/set.
  • Add unit tests covering candidate generation, tolerant probing behavior, and config persistence of the resolved base-url.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/provider/list-models.ts Adds base-url candidate generation and a tolerant model listing function that returns resolvedBaseUrl.
src/provider/list-models.test.ts Adds unit tests for candidate generation and base-url-resolving probe behavior.
src/commands/config.ts Uses the resolving lister in endpoint probing and persists resolvedBaseUrl for /config endpoint add/set.
src/commands/config.test.ts Adds a regression test asserting resolved base-url persistence in user config.
src/commands/admin.ts Persists resolvedBaseUrl for /admin endpoint add/set as well.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +124 to +126
if (baseUrl === undefined) return [undefined]
const trimmed = baseUrl.trim().replace(/\/+$/, '')
if (!trimmed) return [undefined]
Comment thread src/commands/config.ts
Comment on lines +540 to +544
// the add confirmation. `resolvedBaseUrl` is the base-url that actually
// responded — set when the probe normalized the `/v1` convention (apiKey
// endpoints only); the caller persists / displays it so the stored endpoint
// matches the verified wire path. Undefined when no base-url was probed
// (codex / default base) or the as-given value worked unchanged.
@RowitZou
RowitZou deleted the feature/baseurl-tolerant branch June 26, 2026 09:17
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.

2 participants