Skip to content

Commit b2da129

Browse files
fix(tui): show resolved model ref in confirmation
Uses the canonical model ref returned by `sessions.patch` for the TUI `/model` confirmation so alias inputs report the model that was actually applied. The fallback still shows the raw input when a backend does not return `resolved`, and the display path uses `modelKey` so nested model ids keep the provider prefix without double-prefixing self-prefixed ids. Proof: local focused TUI Vitest/format/lint; autoreview clean; Crabbox AWS focused TUI test run `run_7d7cc5b040e8`; exact-head GitHub CI green on `6db4acfb08f9d477ee1bdab429bd7189b78ffc92`.
1 parent 5b21a03 commit b2da129

2 files changed

Lines changed: 70 additions & 1 deletion

File tree

src/tui/tui-command-handlers.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,68 @@ describe("tui command handlers", () => {
11491149
expect(closeOverlay).toHaveBeenCalledTimes(1);
11501150
});
11511151

1152+
it("shows resolved canonical model ref after /model alias, not raw alias string", async () => {
1153+
// When the user types `/model gpt4` (a bare alias), the gateway resolves it
1154+
// server-side and returns the canonical ref in result.resolved. The TUI must
1155+
// display the canonical ref, not the raw alias, so the user knows which model
1156+
// was actually applied.
1157+
const patchSession = vi.fn().mockResolvedValue({
1158+
ok: true,
1159+
path: "/sessions/patch",
1160+
key: "agent:main:main",
1161+
entry: {},
1162+
resolved: { modelProvider: "openai", model: "gpt-5.5" },
1163+
});
1164+
const refreshSessionInfo = vi.fn().mockResolvedValue(undefined);
1165+
const applySessionInfoFromPatch = vi.fn();
1166+
const { handleCommand, addSystem } = createHarness({
1167+
patchSession,
1168+
refreshSessionInfo,
1169+
applySessionInfoFromPatch,
1170+
});
1171+
1172+
await handleCommand("/model gpt4");
1173+
1174+
expect(patchSession).toHaveBeenCalledWith(expect.objectContaining({ model: "gpt4" }));
1175+
// Should show the canonical resolved ref, not the raw alias "gpt4"
1176+
expect(addSystem).toHaveBeenCalledWith("model set to openai/gpt-5.5");
1177+
});
1178+
1179+
it("falls back to raw input in /model confirmation when resolved ref unavailable", async () => {
1180+
// Older gateway versions may not return resolved; fall back to raw arg.
1181+
const patchSession = vi.fn().mockResolvedValue({
1182+
ok: true,
1183+
path: "/sessions/patch",
1184+
key: "agent:main:main",
1185+
entry: {},
1186+
// No `resolved` field
1187+
});
1188+
const { handleCommand, addSystem } = createHarness({ patchSession });
1189+
1190+
await handleCommand("/model openai/gpt-5.5");
1191+
1192+
expect(addSystem).toHaveBeenCalledWith("model set to openai/gpt-5.5");
1193+
});
1194+
it("preserves provider prefix for nested model ids in /model confirmation", async () => {
1195+
// Some providers route to nested model ids that themselves contain a slash
1196+
// (e.g. resolved.model: "moonshotai/kimi-k2.5" with modelProvider: "nvidia").
1197+
// The confirmation must still show the full nvidia/moonshotai/kimi-k2.5 ref
1198+
// to match the footer/status bar, not strip the provider just because the
1199+
// model id already contains a slash.
1200+
const patchSession = vi.fn().mockResolvedValue({
1201+
ok: true,
1202+
path: "/sessions/patch",
1203+
key: "agent:main:main",
1204+
entry: {},
1205+
resolved: { modelProvider: "nvidia", model: "moonshotai/kimi-k2.5" },
1206+
});
1207+
const { handleCommand, addSystem } = createHarness({ patchSession });
1208+
1209+
await handleCommand("/model nvidia/moonshotai/kimi-k2.5");
1210+
1211+
expect(addSystem).toHaveBeenCalledWith("model set to nvidia/moonshotai/kimi-k2.5");
1212+
});
1213+
11521214
it("renders model listing feedback before the backend list resolves", async () => {
11531215
let resolveModels: (
11541216
value: Array<{ provider: string; id: string; name?: string }>,

src/tui/tui-command-handlers.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,14 @@ export function createCommandHandlers(context: CommandHandlerContext) {
469469
...currentSessionPatchTarget(),
470470
model: args,
471471
});
472-
chatLog.addSystem(`model set to ${args}`);
472+
const resolvedModel = result.resolved?.model;
473+
const resolvedProvider = result.resolved?.modelProvider;
474+
const resolvedModelRef = resolvedModel
475+
? resolvedProvider
476+
? modelKey(resolvedProvider, resolvedModel)
477+
: resolvedModel
478+
: args;
479+
chatLog.addSystem(`model set to ${resolvedModelRef}`);
473480
applySessionInfoFromPatch(result);
474481
await refreshSessionInfo();
475482
} catch (err) {

0 commit comments

Comments
 (0)