Let custom OpenAI/Anthropic-compatible providers take a hand-entered model id

This commit is contained in:
ZacharyZhang-NY committed 2026-05-30 02:06:04 -04:00
1 parent 1b0d766c0c
commit 35e1097041
4 files changed
+10 -14

No files matched your search

@@ -357,10 +357,7 @@ export const providerAdapters: ProviderAdapterRegistry = {
refresh: refreshUnsupported("Custom OpenAI-compatible endpoint"),
revoke: revokeLocalProfile((profile) => { requireOpenAiCompatProfile(profile); }),
parseAuthProfile: parseOpenAiCompatProfile,
listModels: (ctx) => {
const profile = requireOpenAiCompatProfile(ctx.authProfile);
return fetchOpenAiModels(`${profile.baseUrl}/models`, { authorization: `Bearer ${profile.apiKey}` });
},
listModels: () => listStaticModels("custom-openai"),
getRateLimitState: providerRateLimitUnknown,
streamResponse: streamUnsupported("Custom OpenAI-compatible endpoint"),
cancelResponse: cancelUnsupported("Custom OpenAI-compatible endpoint"),
@@ -378,13 +375,7 @@ export const providerAdapters: ProviderAdapterRegistry = {
refresh: refreshUnsupported("Custom Anthropic-compatible endpoint"),
revoke: revokeLocalProfile((profile) => { requireAnthropicCompatProfile(profile); }),
parseAuthProfile: parseAnthropicCompatProfile,
listModels: (ctx) => {
const profile = requireAnthropicCompatProfile(ctx.authProfile);
return fetchAnthropicModels(`${profile.baseUrl}/v1/models`, {
"x-api-key": profile.apiKey,
"anthropic-version": ANTHROPIC_VERSION,
});
},
listModels: () => listStaticModels("custom-anthropic"),
getRateLimitState: providerRateLimitUnknown,
streamResponse: streamUnsupported("Custom Anthropic-compatible endpoint"),
cancelResponse: cancelUnsupported("Custom Anthropic-compatible endpoint"),
@@ -417,7 +417,7 @@ function ProviderCredentialFields({
}
function modelPlaceholder(live: boolean, isOAuthLike: boolean, loading: boolean): string {
if (!live) return "Type the model id (e.g. gpt-5.5)";
if (!live) return "Enter the model id";
if (loading || isOAuthLike) return "Loading…";
return "Click “Get models”, or type a model id";
}
@@ -150,8 +150,10 @@ const RAW_CATALOG: Omit<ProviderCatalogEntry, "models" | "supportsLiveModels">[]
},
];
// Providers with no enumerable models endpoint: the Codex subscription and the
// browser-token / cloud connectors. Their model id is entered as free text.
// Providers with no enumerable models endpoint: the Codex subscription, the
// browser-token / cloud connectors, and user-configured custom endpoints whose
// model id is entered by hand. The UI offers a fixed dropdown (when a curated
// list exists) or a free-text model id instead of a live fetch.
const CURATED_MODEL_PROVIDERS = new Set([
"github-copilot",
"google-antigravity",
@@ -159,6 +161,8 @@ const CURATED_MODEL_PROVIDERS = new Set([
"azure-openai",
"aws-bedrock",
"vertex-ai",
"custom-openai",
"custom-anthropic",
]);
export const PROVIDER_CATALOG: ProviderCatalogEntry[] = RAW_CATALOG.map((entry) => ({
@@ -91,6 +91,7 @@ describe("provider contracts", () => {
// catalog; the rest fetch live (covered offline by provider-models-fetch.test).
const CURATED_MODEL_PROVIDERS = new Set([
"github-copilot", "google-antigravity", "gpt-account", "azure-openai", "aws-bedrock", "vertex-ai",
"custom-openai", "custom-anthropic",
]);
test("exposes model listing and rate limit adapter contracts", async () => {