Steps 4a and 4b of the provider refactor plan. resolveEndpoint(provider,
overrides) answers, by the record's credential kind, whose key a call uses
(keySource), which key, which URL, whether the URL was configured and whether
the client-chosen URL needs the redirect guard. It never throws, fetches or
logs. The five branches of getAIModel's second switch (bedrock, vertexai,
ollama, edgeone, default) are gone: Bedrock's credential selection moved
unchanged into bedrockModel(), called when the record's sdk is bedrock; every
other provider goes through resolveEndpoint and createModel, whose switch now
runs on the record's sdk field (Vertex and Ollama became cases). The three
errors for a missing Vertex key or a missing base URL stay in getAIModel with
their texts. The SSRF guard at the top reads the credential kind instead of
provider names. resolveApiKey returns whose key it found; the array apiKeyEnv
log moved to getAIModel so a later usesServerCredentials call draws no second
log line.
The behavior snapshot is unchanged, and resolveEndpoint's keySource agrees
with the pre-refactor usesServerCredentials on all 30720 input classes.
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.