fix(app): open sole provider model picker directly
Running chats expose one provider, so an intermediate provider screen and back action are redundant. Restore the direct model-list entry behavior while preserving the multi-provider picker.
This commit is contained in:
@@ -1,17 +1,14 @@
|
|||||||
import { test } from "../support/fixtures";
|
import { expect, test } from "../support/fixtures";
|
||||||
import {
|
import {
|
||||||
applyProfileFromPicker,
|
applyProfileFromPicker,
|
||||||
closeModelPicker,
|
closeModelPicker,
|
||||||
drillIntoProvider,
|
|
||||||
expectComposerDoesNotName,
|
expectComposerDoesNotName,
|
||||||
expectAgentProfilesEmptyPrompt,
|
expectAgentProfilesEmptyPrompt,
|
||||||
expectProfileEditTooltip,
|
expectProfileEditTooltip,
|
||||||
expectComposerMode,
|
expectComposerMode,
|
||||||
expectComposerModel,
|
expectComposerModel,
|
||||||
expectModelRowSelected,
|
expectModelRowSelected,
|
||||||
expectNothingSelectedInPickerRoot,
|
|
||||||
expectProfileEditIsPencilOnly,
|
expectProfileEditIsPencilOnly,
|
||||||
expectProfilePinnedAboveProviders,
|
|
||||||
expectProfileVisibleForProvider,
|
expectProfileVisibleForProvider,
|
||||||
openModelPicker,
|
openModelPicker,
|
||||||
openAgentProfilesFromEmptyPrompt,
|
openAgentProfilesFromEmptyPrompt,
|
||||||
@@ -74,9 +71,12 @@ test.describe("Agent profiles in the model picker", () => {
|
|||||||
await expectComposerMode(page, "Load test");
|
await expectComposerMode(page, "Load test");
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("the profile is pinned above the provider list", async () => {
|
await test.step("the sole provider opens directly", async () => {
|
||||||
await openModelPicker(page);
|
await openModelPicker(page);
|
||||||
await expectProfilePinnedAboveProviders(page, {
|
await expect(page.getByTestId("model-search-input").first()).toBeVisible();
|
||||||
|
await expect(page.getByTestId("sheet-header-back")).toHaveCount(0);
|
||||||
|
await expect(page.locator('[data-testid^="model-provider-"]')).toHaveCount(0);
|
||||||
|
await expectProfileVisibleForProvider(page, {
|
||||||
name: PROFILE.name,
|
name: PROFILE.name,
|
||||||
summary: PROFILE_SUMMARY,
|
summary: PROFILE_SUMMARY,
|
||||||
});
|
});
|
||||||
@@ -100,17 +100,9 @@ test.describe("Agent profiles in the model picker", () => {
|
|||||||
await expectComposerDoesNotName(page, PROFILE.name);
|
await expectComposerDoesNotName(page, PROFILE.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("reopening the picker shows no profile marked as selected", async () => {
|
await test.step("reopening returns directly to the provider models", async () => {
|
||||||
await openModelPicker(page);
|
await openModelPicker(page);
|
||||||
await expectProfilePinnedAboveProviders(page, {
|
await expect(page.getByTestId("model-search-input").first()).toBeVisible();
|
||||||
name: PROFILE.name,
|
|
||||||
summary: PROFILE_SUMMARY,
|
|
||||||
});
|
|
||||||
await expectNothingSelectedInPickerRoot(page);
|
|
||||||
});
|
|
||||||
|
|
||||||
await test.step("the model it materialized is the one marked selected", async () => {
|
|
||||||
await drillIntoProvider(page, "mock");
|
|
||||||
await expectProfileVisibleForProvider(page, {
|
await expectProfileVisibleForProvider(page, {
|
||||||
name: PROFILE.name,
|
name: PROFILE.name,
|
||||||
summary: PROFILE_SUMMARY,
|
summary: PROFILE_SUMMARY,
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ describe("model browser initial view", () => {
|
|||||||
).toEqual({ kind: "all" });
|
).toEqual({ kind: "all" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps the root even when a single provider would otherwise be skipped", () => {
|
it("opens a sole provider directly regardless of root content", () => {
|
||||||
expect(
|
expect(
|
||||||
resolveInitialModelBrowserView({
|
resolveInitialModelBrowserView({
|
||||||
providers: [pi],
|
providers: [pi],
|
||||||
@@ -78,7 +78,7 @@ describe("model browser initial view", () => {
|
|||||||
selectedModel: "pi-pro",
|
selectedModel: "pi-pro",
|
||||||
hasProfiles: true,
|
hasProfiles: true,
|
||||||
}),
|
}),
|
||||||
).toEqual({ kind: "all" });
|
).toEqual({ kind: "provider", providerId: "pi", providerLabel: "Pi" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("falls back to the root when the selected provider is gone", () => {
|
it("falls back to the root when the selected provider is gone", () => {
|
||||||
|
|||||||
@@ -32,11 +32,7 @@ export function resolveModelBrowserAllView({
|
|||||||
return { kind: "searchResults", rows };
|
return { kind: "searchResults", rows };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Where the picker lands when it opens. A sole provider skips the redundant root view. */
|
||||||
* Where the picker lands when it opens. Agent profiles live on the root view, so
|
|
||||||
* a host that has any profile always opens there — including the single-provider
|
|
||||||
* case, which would otherwise skip the root entirely and hide them.
|
|
||||||
*/
|
|
||||||
export function resolveInitialModelBrowserView({
|
export function resolveInitialModelBrowserView({
|
||||||
providers,
|
providers,
|
||||||
selectedProvider,
|
selectedProvider,
|
||||||
@@ -48,10 +44,6 @@ export function resolveInitialModelBrowserView({
|
|||||||
selectedModel: string;
|
selectedModel: string;
|
||||||
hasProfiles: boolean;
|
hasProfiles: boolean;
|
||||||
}): ModelBrowserView {
|
}): ModelBrowserView {
|
||||||
if (hasProfiles) {
|
|
||||||
return { kind: "all" };
|
|
||||||
}
|
|
||||||
|
|
||||||
const singleProvider = providers.length === 1 ? providers[0] : undefined;
|
const singleProvider = providers.length === 1 ? providers[0] : undefined;
|
||||||
if (singleProvider) {
|
if (singleProvider) {
|
||||||
return {
|
return {
|
||||||
@@ -61,6 +53,10 @@ export function resolveInitialModelBrowserView({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasProfiles) {
|
||||||
|
return { kind: "all" };
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedProvider.length > 0 && selectedModel.length > 0) {
|
if (selectedProvider.length > 0 && selectedModel.length > 0) {
|
||||||
const provider = providers.find((entry) => entry.id === selectedProvider);
|
const provider = providers.find((entry) => entry.id === selectedProvider);
|
||||||
if (provider) {
|
if (provider) {
|
||||||
|
|||||||
@@ -292,9 +292,7 @@ export function useModelBrowser({
|
|||||||
setSearchQuery(value);
|
setSearchQuery(value);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// A pinned profiles section makes the root worth returning to, so the back
|
const singleProviderView = providers.length === 1;
|
||||||
// affordance stays even when the drill-down was the only provider.
|
|
||||||
const singleProviderView = providers.length === 1 && !hasProfiles;
|
|
||||||
const header = useMemo<SheetHeader>(() => {
|
const header = useMemo<SheetHeader>(() => {
|
||||||
if (view.kind === "all") {
|
if (view.kind === "all") {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user