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.
A sixteenth override shape, a key with a private base URL, so the snapshot
holds usesServerEndpoint's answer for the server's own network before the
function changes. 252 rows added, none changed.
Step 0 of docs/plans/2026-10-provider-refactor.md. provider-matrix.test.ts
snapshots what getAIModel hands to each SDK factory, and what
usesServerCredentials, usesServerEndpoint, globalBaseUrl and chatRequestUrl
answer, for 24 providers, 15 client override shapes and 9 server
environments, plus auto-detection rows and model id probes (3879 rows).
provider-legacy.test.ts keeps a copy of the two quota functions and compares
them with the live ones over every input class (30720 and 288 combinations).
No production code changes.