mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 17:52:31 +03:00
fix(providers): mint a Zed LLM token for zed-hosted model discovery (#9628)
Merge-train validated (tip 6ce4effef8). Vitest failures confirmed as base-red (#9679).
This commit is contained in:
@@ -30,6 +30,7 @@ import {
|
||||
import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error";
|
||||
import { getStaticQoderModels } from "@omniroute/open-sse/services/qoderCli.ts";
|
||||
import { deriveConfigFromRegistryModelsUrl } from "./discoveryConfig";
|
||||
import { resolveZedModels } from "@omniroute/open-sse/shared/zedAuth.ts";
|
||||
import {
|
||||
fetchGitHubCopilotModels,
|
||||
fetchGheCopilotModels,
|
||||
@@ -2005,6 +2006,62 @@ export async function GET(
|
||||
return buildApiDiscoveryResponse(models);
|
||||
}
|
||||
|
||||
// Zed Hosted needs a two-step auth the generic discovery path cannot express:
|
||||
// `cloud.zed.dev/models` rejects the account access token and requires an LLM
|
||||
// token minted by POST /client/llm_tokens (authorized with Zed's own
|
||||
// `<userId> <accessToken>` scheme). The registry `modelsUrl` otherwise falls
|
||||
// through to deriveConfigFromRegistryModelsUrl(), which hardcodes
|
||||
// `Bearer <token>` and always 401s with "Invalid Authorization header".
|
||||
// ProviderModelsConfigEntry.buildHeaders is synchronous, so the token
|
||||
// exchange cannot be expressed there — hence a dedicated branch that reuses
|
||||
// the executor's own resolveZedModels().
|
||||
if (provider === "zed-hosted") {
|
||||
const zedToken = accessToken || apiKey;
|
||||
if (!zedToken) {
|
||||
const fallback = buildDiscoveryFallbackResponse();
|
||||
if (fallback) return fallback;
|
||||
return NextResponse.json({ error: "Zed connection has no access token" }, { status: 400 });
|
||||
}
|
||||
let providerSpecificData: Record<string, unknown> = {};
|
||||
const rawPsd = (connection as { providerSpecificData?: unknown }).providerSpecificData;
|
||||
if (typeof rawPsd === "string") {
|
||||
try {
|
||||
providerSpecificData = JSON.parse(rawPsd) as Record<string, unknown>;
|
||||
} catch {
|
||||
providerSpecificData = {};
|
||||
}
|
||||
} else if (rawPsd && typeof rawPsd === "object") {
|
||||
providerSpecificData = rawPsd as Record<string, unknown>;
|
||||
}
|
||||
|
||||
try {
|
||||
const catalog = await resolveZedModels({
|
||||
accessToken: zedToken,
|
||||
providerSpecificData,
|
||||
} as Parameters<typeof resolveZedModels>[0]);
|
||||
const zedModels = (catalog?.models ?? []).map((model) => ({
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
context_length: model.contextLength,
|
||||
max_output_tokens: model.maxOutputTokens,
|
||||
supports_tools: model.supportsTools,
|
||||
supports_images: model.supportsImages,
|
||||
}));
|
||||
return buildApiDiscoveryResponse(zedModels);
|
||||
} catch (error) {
|
||||
console.log("Error fetching models from provider", {
|
||||
provider,
|
||||
errorText: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
const fallback = buildDiscoveryFallbackResponse();
|
||||
if (fallback) return fallback;
|
||||
return NextResponse.json(
|
||||
{ error: `Failed to fetch models: ${sanitizeErrorMessage(error)}` },
|
||||
{ status: 502 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const config =
|
||||
provider in PROVIDER_MODELS_CONFIG
|
||||
? PROVIDER_MODELS_CONFIG[provider as keyof typeof PROVIDER_MODELS_CONFIG]
|
||||
|
||||
Reference in New Issue
Block a user