Repository navigation
fix(providers): mint a Zed LLM token for zed-hosted model discovery - #9628
Merged
diegosouzapw merged 3 commits intoAug 7, 2026
Merged
diegosouzapw merged 3 commits into
diegosouzapw merged 3 commits into
Conversation
Model discovery for `zed-hosted` always failed with `Failed to fetch models: 401` / "Invalid Authorization header". The registry entry (open-sse/config/providers/registry/zed-hosted) sets `modelsUrl`, so discovery falls through to deriveConfigFromRegistryModelsUrl(), which hardcodes `Bearer <token>` and sends the Zed *account* access token at cloud.zed.dev/models. Zed requires two-step auth there: the account token only authorizes `/client/*` under Zed's own `<userId> <accessToken>` scheme, and /models needs an LLM token minted by POST /client/llm_tokens. Verified against a live account — Bearer with a non-LLM token returns "Invalid Authorization header", while the two-step flow returns the full 16-model catalog. ProviderModelsConfigEntry.buildHeaders is synchronous, so the token exchange cannot be expressed in the generic config. Add a dedicated branch that reuses the executor's own resolveZedModels(), which already implements the exchange via zedLlmFetch. Note: `zed-hosted` was merged in cheaper-inference#6118 titled "NEEDS LIVE OAUTH VALIDATION"; this is the discovery half of that validation. Inference still returns 500 and is not addressed here. Claude-Session: https://claude.ai/code/session_01WDAGfwSnbiWJmjsbz6zUC5
Regression guard for the zed-hosted branch in the provider models route (Hard Rule #8/#18). Three cases, all red before the fix and green after: - mints an LLM token via POST /client/llm_tokens (Zed's `<userId> <accessToken>` scheme) and asserts GET /models carries the minted `Bearer <llmToken>`, never the account access token. Without the fix the route falls through to the registry `modelsUrl` path, which sends `Bearer <accessToken>` at cloud.zed.dev/models and 401s. - resolves the organization via /client/users/me when the connection has none — the OAuth import stores `organizationId: tokens.organization_id || undefined`, so a connection can legitimately land without one. - degrades to the local catalog (no 500, no stack trace in the body) when Zed rejects the token. Caches in open-sse/shared/zedAuth.ts are module-level and keyed by `<userId>:<organizationId>:<token suffix>`, so each case uses a distinct access token and clearZedCaches() runs between tests.
diegosouzapw
merged commit Aug 7, 2026
e224165
into
cheaper-inference:release/v3.8.50
3 checks passed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…heaper-inference#9628) Merge-train validated (tip 6ce4effef8). Vitest failures confirmed as base-red (cheaper-inference#9679).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Model discovery for the
zed-hostedprovider always failed in the dashboard — refreshing themodel list returned
401 Invalid Authorization headerand the connection was left with nocatalog.
Root cause
zed-hostedshipsmodels: []+modelsUrl: "https://cloud.zed.dev/models"in the registry(
open-sse/config/providers/registry/zed-hosted/index.ts), so the route fell through toderiveConfigFromRegistryModelsUrl(). That generic path hardcodesAuthorization: Bearer <accessToken>.Zed's catalog endpoint does not accept the account access token. It requires an LLM token
minted by
POST /client/llm_tokens, which is itself authorized with Zed's own<userId> <accessToken>scheme — a two-step exchange the generic path cannot express, becauseProviderModelsConfigEntry.buildHeadersis synchronous and the mint is async.Fix
A dedicated
provider === "zed-hosted"branch insrc/app/api/providers/[id]/models/route.tsthat reuses the executor's own
resolveZedModels()fromopen-sse/shared/zedAuth.ts— the samecode path the completion executor already uses, so discovery and execution can no longer
disagree about how to authenticate. It handles the
providerSpecificDatastring/object shape,maps the Zed catalog onto the route's model shape, and on failure degrades to the cached/local
catalog instead of surfacing a raw error.
Validation (Hard Rule #18)
tests/unit/zed-hosted-models-discovery-route.test.ts— 3 cases, verified red before the fixand green after (fix reverted in place with
git checkout HEAD~1 -- <route>, same worktree):401 !== 200/client/users/mewhen connection has none500The first case asserts the catalog request carries the minted
Bearer <llmToken>and neverthe account access token — that assertion is what reproduces the reported bug.
Regression suites (
zed-*,mitm-handler-zed,provider-models-route,provider-models-route-codex,provider-models-discovery-split,provider-models-config):161 / 162 pass. The single failure is
provider models route retries Antigravity discovery endpoints before returning remote models, which fails identically with this fix reverted — seeinherited base-red below.
typecheck:core: 8 errors, all in untouchedopen-sse/files, none in the changed route.ESLint on the changed route: 1 error, the pre-existing
@/lib/localDbbarrel import at line 14(frozen in
config/quality/eslint-suppressions.json). Prettier clean.release/v3.8.50is not green. Two inherited failures show up on this branch and are notintroduced by it:
134_ccr_blocks.sqlvs134_proxy_logs_egress_ip.sql(added by fix(sse): back the CCR block store with a durable tier (#9061) #9198 and fix(db): persist account egress IP into proxy_logs #9291).
getMigrationFiles()throws on the collision, so everyDB-touching unit test aborts before its first assertion. Reproducing the test results above
required renaming one file locally; that rename is deliberately not part of this PR — per
the base-green policy a base-red fix belongs in its own freeze-gated
fix/release-v3.8.50-baseredsPR.Notes
135_/136_collision fixed byf2e36ad;
release/v3.8.50has been merged in, so this branch now only carries the134_collision above.