Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions apps/web/src/components/chat/modelPickerEmptyState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,11 @@ export function resolveModelPickerEmptyState(input: {
};
}

if (input.activeTabKind === "favorites") {
return { lines: ["No favorite models"], showSettingsAction: false };
}

// Nothing to pick and every provider the user enabled is unusable: name
// each one instead of leaving them to guess which is broken.
// each one instead of leaving them to guess which is broken. This wins
// over the Favorites empty text because a cold install has no usable
// provider tabs at all, so Favorites is the only tab the picker can open
// on and its bare "No favorite models" would hide the one actionable fact.
const enabledProviders = input.providers.filter((provider) => provider.enabled);
const unavailableProviders = enabledProviders.filter(
(provider) => getModelPickerProviderAvailability(provider.snapshot) !== "available",
Expand All @@ -124,5 +123,9 @@ export function resolveModelPickerEmptyState(input: {
};
}

if (input.activeTabKind === "favorites") {
return { lines: ["No favorite models"], showSettingsAction: false };
}

return { lines: ["No models available"], showSettingsAction: false };
}
25 changes: 23 additions & 2 deletions apps/web/src/components/chat/modelPickerSearch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,34 @@ describe("resolveModelPickerEmptyState", () => {
).toEqual({ lines: ["No models available"], showSettingsAction: false });
});

it("keeps the favorites tab message provider-agnostic", () => {
it("keeps the favorites tab message while a provider is still usable", () => {
expect(
resolveModelPickerEmptyState({
searchQuery: "",
activeTabKind: "favorites",
providers: [CLAUDE_MISSING],
providers: [CODEX_READY, CLAUDE_MISSING],
}),
).toEqual({ lines: ["No favorite models"], showSettingsAction: false });
});

it("explains providers from the favorites tab on a cold install", () => {
// A cold install has no usable provider tabs, so Favorites is the only
// tab the picker can open on; the provider guidance must win there too.
expect(
resolveModelPickerEmptyState({
searchQuery: "",
activeTabKind: "favorites",
providers: [
makeProvider("codex", "Codex", {
status: "warning",
auth: { status: "unauthenticated" },
}),
CLAUDE_MISSING,
],
}),
).toEqual({
lines: ["Codex · Not authenticated", "Claude · Not found"],
showSettingsAction: true,
});
});
});
Loading