feat(providers): an OpenAI-compatible preset for any vLLM, LM Studio or gateway URL

Step 8 of the provider refactor plan, a new provider made of one record.
'custom' runs on @ai-sdk/openai-compatible with <think> extraction, merges
system messages (open-source chat templates reject several), has no default
URL (so a key alone does not count as connected, and the chat endpoint is
shown under the URL field) and lists models from its /models. Server side:
CUSTOM_API_KEY and CUSTOM_BASE_URL, ADMIN_CUSTOM_* in the admin panel.
env.example and the three provider docs gained a section; the picker count
in the e2e test is 25 and a new e2e test walks through the preset. The
behavior snapshot gained the new provider's 146 rows; its two 'No AI provider
configured' rows list CUSTOM_API_KEY now.
This commit is contained in:
dayuan.jiang
2026-10-12 21:17:51 +09:00
parent 717f7e9445
commit b2cadfa5bf
9 changed files with 246 additions and 9 deletions
+4 -4
View File
@@ -24,16 +24,16 @@ const sorted = (list: Iterable<string>) => [...list].sort()
describe("the provider record", () => {
it("is what the rest of the app imports as PROVIDER_INFO", () => {
expect(PROVIDER_INFO).toBe(PROVIDERS)
expect(PROVIDER_NAMES).toHaveLength(24)
expect(PROVIDER_NAMES).toHaveLength(25)
})
it("has 21 providers taking part in server key auto-detection", () => {
it("has 22 providers taking part in server key auto-detection", () => {
// credential apiKey or vertexKey: the providers whose <P>_API_KEY the
// server must have; aws, optionalKey and none need no key
const detected = PROVIDER_NAMES.filter((p) =>
["apiKey", "vertexKey"].includes(PROVIDERS[p].credential),
)
expect(detected).toHaveLength(21)
expect(detected).toHaveLength(22)
// Ollama has a key variable too, an optional one
const withKeyVar = PROVIDER_NAMES.filter((p) => !!envVarsOf(p).apiKey)
expect(sorted(detected)).toEqual(
@@ -142,7 +142,7 @@ describe("the picker's order", () => {
id: "cloud",
providers: ["bedrock", "vertexai", "azure", "edgeone"],
},
{ id: "selfHosted", providers: ["ollama", "sglang"] },
{ id: "selfHosted", providers: ["ollama", "sglang", "custom"] },
])
})