


























@@ -8,6 +8,7 @@ import {
88type LoadHistoryMock = ReturnType<typeof vi.fn> & (() => Promise<void>);
99type RunAuthFlow = NonNullable<Parameters<typeof createCommandHandlers>[0]["runAuthFlow"]>;
1010type SelectableOverlay = {
11+items?: Array<{ value: string; label?: string; description?: string }>;
1112onSelect?: (item: { value: string; label?: string; description?: string }) => void;
1213};
1314type SetActivityStatusMock = ReturnType<typeof vi.fn> & ((text: string) => void);
@@ -21,6 +22,7 @@ function createHarness(params?: {
2122sendChat?: ReturnType<typeof vi.fn>;
2223getGatewayStatus?: ReturnType<typeof vi.fn>;
2324listSessions?: ReturnType<typeof vi.fn>;
25+listModels?: ReturnType<typeof vi.fn>;
2426patchSession?: ReturnType<typeof vi.fn>;
2527resetSession?: ReturnType<typeof vi.fn>;
2628runAuthFlow?: RunAuthFlow;
@@ -38,6 +40,7 @@ function createHarness(params?: {
3840const sendChat = params?.sendChat ?? vi.fn().mockResolvedValue({ runId: "r1" });
3941const getGatewayStatus = params?.getGatewayStatus ?? vi.fn().mockResolvedValue({});
4042const listSessions = params?.listSessions ?? vi.fn().mockResolvedValue({ sessions: [] });
43+const listModels = params?.listModels ?? vi.fn().mockResolvedValue([]);
4144const patchSession = params?.patchSession ?? vi.fn().mockResolvedValue({});
4245const resetSession = params?.resetSession ?? vi.fn().mockResolvedValue({ ok: true });
4346const setSession = params?.setSession ?? (vi.fn().mockResolvedValue(undefined) as SetSessionMock);
@@ -71,7 +74,14 @@ function createHarness(params?: {
7174};
72757376const { handleCommand, openSessionSelector } = createCommandHandlers({
74-client: { sendChat, getGatewayStatus, listSessions, patchSession, resetSession } as never,
77+client: {
78+ sendChat,
79+ getGatewayStatus,
80+ listSessions,
81+ listModels,
82+ patchSession,
83+ resetSession,
84+} as never,
7585chatLog: { addUser, addSystem } as never,
7686tui: { requestRender } as never,
7787opts: params?.opts ?? {},
@@ -99,6 +109,7 @@ function createHarness(params?: {
99109 handleCommand,
100110 getGatewayStatus,
101111 listSessions,
112+ listModels,
102113 sendChat,
103114 openSessionSelector,
104115 openOverlay,
@@ -526,4 +537,42 @@ describe("tui command handlers", () => {
526537expect(applySessionInfoFromPatch).toHaveBeenCalledWith({ groupActivation: "always" });
527538expect(refreshSessionInfo).toHaveBeenCalledTimes(1);
528539});
540+541+it("uses canonical model refs in the model selector", async () => {
542+const listModels = vi.fn().mockResolvedValue([
543+{
544+provider: "openrouter",
545+id: "openrouter/auto",
546+name: "OpenRouter Auto",
547+},
548+]);
549+const patchSession = vi.fn().mockResolvedValue({ model: "openrouter/auto" });
550+const refreshSessionInfo = vi.fn().mockResolvedValue(undefined);
551+const applySessionInfoFromPatch = vi.fn();
552+const { handleCommand, openOverlay, closeOverlay } = createHarness({
553+ listModels,
554+ patchSession,
555+ refreshSessionInfo,
556+ applySessionInfoFromPatch,
557+});
558+559+await handleCommand("/model");
560+561+const selector = openOverlay.mock.calls[0]?.[0] as SelectableOverlay | undefined;
562+expect(selector?.items?.[0]).toMatchObject({
563+value: "openrouter/auto",
564+label: "openrouter/auto",
565+});
566+567+selector?.onSelect?.({ value: "openrouter/auto", label: "openrouter/auto" });
568+await flushAsyncSelect();
569+570+expect(patchSession).toHaveBeenCalledWith({
571+key: "agent:main:main",
572+model: "openrouter/auto",
573+});
574+expect(applySessionInfoFromPatch).toHaveBeenCalledWith({ model: "openrouter/auto" });
575+expect(refreshSessionInfo).toHaveBeenCalledTimes(1);
576+expect(closeOverlay).toHaveBeenCalledTimes(1);
577+});
529578});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。