fix(quick-pane): restore model catalog controls
This commit is contained in:
+80
-2
@@ -7,16 +7,19 @@ import {
|
||||
reconcileWorkspace,
|
||||
workspaceReducer,
|
||||
} from "./workspace/reducer";
|
||||
import { modelIdentityFromValue, modelIdentityValue } from "./model-catalog";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
invoke: vi.fn(),
|
||||
loadSnapshot: vi.fn(),
|
||||
refresh: vi.fn(),
|
||||
dispatch: vi.fn(),
|
||||
emitTo: vi.fn(),
|
||||
useWorkspace: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@tauri-apps/api/core", () => ({ invoke: mocks.invoke }));
|
||||
vi.mock("@tauri-apps/api/event", () => ({ emitTo: mocks.emitTo }));
|
||||
vi.mock("@tauri-apps/api/window", () => ({
|
||||
getCurrentWindow: () => ({ startDragging: vi.fn() }),
|
||||
}));
|
||||
@@ -87,10 +90,21 @@ function deferred<T>() {
|
||||
return { promise, resolve, reject };
|
||||
}
|
||||
|
||||
describe("model catalog identity", () => {
|
||||
it("preserves model IDs containing slashes", () => {
|
||||
const identity = {
|
||||
provider: "openrouter",
|
||||
modelId: "anthropic/claude/sonnet",
|
||||
};
|
||||
expect(modelIdentityFromValue(modelIdentityValue(identity))).toEqual(identity);
|
||||
});
|
||||
});
|
||||
|
||||
describe("App command progress and errors", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mocks.invoke.mockResolvedValue(uiState);
|
||||
mocks.emitTo.mockResolvedValue(undefined);
|
||||
mocks.refresh.mockResolvedValue(undefined);
|
||||
mocks.loadSnapshot.mockResolvedValue(true);
|
||||
mocks.useWorkspace.mockReturnValue({
|
||||
@@ -108,6 +122,69 @@ describe("App command progress and errors", () => {
|
||||
expect(status).toHaveTextContent("Ready for your next prompt");
|
||||
});
|
||||
|
||||
it("loads shared catalog selectors and derives providers from model choices", async () => {
|
||||
const user = userEvent.setup();
|
||||
const loaded: UiState = {
|
||||
...uiState,
|
||||
quickPane: {
|
||||
workspace: "/repo",
|
||||
provider: "openai",
|
||||
model: "gpt-5",
|
||||
followUpProvider: "openai",
|
||||
followUpModel: "gpt-5",
|
||||
instructions: "Stay concise.",
|
||||
maximumSeconds: 60,
|
||||
maximumToolCalls: 6,
|
||||
},
|
||||
};
|
||||
mocks.invoke.mockImplementation((command: string) => {
|
||||
if (command === "get_model_catalog")
|
||||
return Promise.resolve({
|
||||
models: [
|
||||
{ provider: "openai", id: "gpt-5" },
|
||||
{ provider: "openrouter", id: "anthropic/claude/sonnet" },
|
||||
],
|
||||
});
|
||||
if (command === "load_ui_state") return Promise.resolve(loaded);
|
||||
return Promise.resolve(undefined);
|
||||
});
|
||||
render(<App />);
|
||||
await waitFor(() =>
|
||||
expect(mocks.invoke).toHaveBeenCalledWith("get_model_catalog"),
|
||||
);
|
||||
await user.click(screen.getByRole("button", { name: "Controls" }));
|
||||
const quickModel = screen.getByRole("combobox", { name: /Quick model/ });
|
||||
expect(quickModel).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("combobox", { name: /Follow-up model/ }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.queryByLabelText(/Quick provider/)).toBeNull();
|
||||
expect(screen.queryByLabelText(/Follow-up provider/)).toBeNull();
|
||||
|
||||
await user.selectOptions(
|
||||
quickModel,
|
||||
modelIdentityValue({
|
||||
provider: "openrouter",
|
||||
modelId: "anthropic/claude/sonnet",
|
||||
}),
|
||||
);
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Save Quick Pane settings" }),
|
||||
);
|
||||
await waitFor(() =>
|
||||
expect(mocks.invoke).toHaveBeenCalledWith("save_ui_state", {
|
||||
state: {
|
||||
...loaded,
|
||||
quickPane: {
|
||||
...loaded.quickPane,
|
||||
provider: "openrouter",
|
||||
model: "anthropic/claude/sonnet",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("shows restart progress until the replacement snapshot is restored", async () => {
|
||||
const user = userEvent.setup();
|
||||
const restart = deferred<unknown>();
|
||||
@@ -127,9 +204,10 @@ describe("App command progress and errors", () => {
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole("main")).toHaveAttribute("aria-busy", "true");
|
||||
await user.click(restarting);
|
||||
expect(mocks.invoke).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.invoke).toHaveBeenCalledTimes(3);
|
||||
expect(mocks.invoke).toHaveBeenNthCalledWith(1, "load_ui_state");
|
||||
expect(mocks.invoke).toHaveBeenNthCalledWith(2, "restart", {
|
||||
expect(mocks.invoke).toHaveBeenNthCalledWith(2, "get_model_catalog");
|
||||
expect(mocks.invoke).toHaveBeenNthCalledWith(3, "restart", {
|
||||
agentId: "agent-a",
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user