fix(ui): surface model load failures and align request key with models
Some checks failed
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled

Throw when both model endpoints fail so ChatUI can show an error instead of
an empty list. Use the same resolved key for model listing and chat requests,
and drop the fetch_models JSDoc
This commit is contained in:
mubashir1osmani 2026-08-06 15:35:24 -07:00
parent f40ef53894
commit b6475bd343
3 changed files with 21 additions and 9 deletions

View file

@ -455,7 +455,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
if (!simplified) {
void loadModels();
}
void loadMCPServers(userApiKey);
void loadMCPServers();
return () => {
cancelled = true;
@ -794,7 +794,8 @@ const ChatUI: React.FC<ChatUIProps> = ({
return;
}
const effectiveApiKey = simplified ? accessToken : apiKeySource === "session" ? accessToken : apiKey;
const effectiveApiKey =
simplified || apiKeySource === "session" ? accessToken : debouncedCustomApiKey || apiKey.trim();
if (!effectiveApiKey) {
NotificationsManager.fromBackend("Please provide a Virtual Key or select Current UI Session");

View file

@ -74,4 +74,12 @@ describe("fetchAvailableModels", () => {
const models = await fetchAvailableModels("sk-virtual-key");
expect(models).toEqual([{ model_group: "only-from-key", mode: undefined }]);
});
it("throws when both model endpoints fail", async () => {
mockGet.mockImplementation(async () => {
throw new Error("network down");
});
await expect(fetchAvailableModels("sk-virtual-key")).rejects.toThrow("network down");
});
});

View file

@ -25,15 +25,10 @@ const dedupeAndSort = (models: ModelGroup[]): ModelGroup[] => {
return unique;
};
/**
* Loads models available to the given key.
*
* Prefers OpenAI-compatible `/v1/models` (scoped to the key's access) and enriches
* entries with `mode` from `/model_group/info` when that endpoint is available.
* Falls back to `/model_group/info` alone if `/v1/models` is empty or fails.
*/
export const fetchAvailableModels = async (accessToken: string): Promise<ModelGroup[]> => {
const modeByName = new Map<string, string | undefined>();
let groupInfoError: unknown;
let listModelsError: unknown;
try {
const groupInfo = await apiClient.get<{ data?: ModelGroupInfoItem[] }>("/model_group/info", {
@ -46,6 +41,7 @@ export const fetchAvailableModels = async (accessToken: string): Promise<ModelGr
}
}
} catch (error) {
groupInfoError = error;
console.error("Error fetching model group info:", error);
}
@ -70,6 +66,7 @@ export const fetchAvailableModels = async (accessToken: string): Promise<ModelGr
return dedupeAndSort(fromList);
}
} catch (error) {
listModelsError = error;
console.error("Error fetching /v1/models:", error);
}
@ -82,5 +79,11 @@ export const fetchAvailableModels = async (accessToken: string): Promise<ModelGr
);
}
if (groupInfoError && listModelsError) {
throw listModelsError instanceof Error
? listModelsError
: new Error("Failed to load models from /v1/models and /model_group/info");
}
return [];
};