diff --git a/src/acp-agent.ts b/src/acp-agent.ts index 2f4c65bd..22d4f77b 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -6946,11 +6946,23 @@ export function buildConfigOptions( category: "model", type: "select", currentValue: models.currentModelId, - options: models.availableModels.map((m) => ({ - value: m.modelId, - name: m.name, - description: m.description ?? undefined, - })), + options: models.availableModels.map((m) => { + if (m.modelId === "default") { + const defaultInfo = modelInfos.find((mi) => mi.value === "default"); + const resolvedModel = defaultInfo?.resolvedModel; + if (resolvedModel) { + const namedMatch = modelInfos.find( + (mi) => mi.value !== "default" && mi.resolvedModel === resolvedModel, + ); + return { + value: m.modelId, + name: m.name, + description: namedMatch?.displayName ?? resolvedModel, + }; + } + } + return { value: m.modelId, name: m.name, description: m.description ?? undefined }; + }), }, ]; diff --git a/src/tests/acp-agent.test.ts b/src/tests/acp-agent.test.ts index 9fba24d6..5c4d180f 100644 --- a/src/tests/acp-agent.test.ts +++ b/src/tests/acp-agent.test.ts @@ -13462,6 +13462,83 @@ describe("agent selection config option", () => { }); }); + describe("buildConfigOptions model option resolved description", () => { + const modes = { currentModeId: "default", availableModes: [] }; + const models = { + currentModelId: "default", + availableModels: [{ modelId: "default", name: "Default", description: "" }], + }; + + it("sets description to the named model's displayName when resolvedModel matches", () => { + const modelInfos = [ + { + value: "default", + displayName: "Default", + description: "", + resolvedModel: "claude-sonnet-5", + }, + { + value: "sonnet", + displayName: "Claude Sonnet 5", + description: "Balanced", + resolvedModel: "claude-sonnet-5", + }, + ]; + const options = buildConfigOptions( + modes, + models, + modelInfos as any, + undefined, + [], + "default", + ); + const modelOption = options.find((o) => o.id === "model"); + const defaultEntry = (modelOption as any).options.find((o: any) => o.value === "default"); + expect(defaultEntry.description).toBe("Claude Sonnet 5"); + }); + + it("falls back to resolvedModel itself when no named model shares it", () => { + const modelInfos = [ + { + value: "default", + displayName: "Default", + description: "", + resolvedModel: "claude-opus-5-20251201", + }, + ]; + const options = buildConfigOptions( + modes, + models, + modelInfos as any, + undefined, + [], + "default", + ); + const modelOption = options.find((o) => o.id === "model"); + const defaultEntry = (modelOption as any).options.find((o: any) => o.value === "default"); + expect(defaultEntry.description).toBe("claude-opus-5-20251201"); + }); + + it("leaves description undefined when default model has no resolvedModel", () => { + const modelsNoDesc = { + currentModelId: "default", + availableModels: [{ modelId: "default", name: "Default" }], + }; + const modelInfos = [{ value: "default", displayName: "Default", description: "" }]; + const options = buildConfigOptions( + modes, + modelsNoDesc, + modelInfos as any, + undefined, + [], + "default", + ); + const modelOption = options.find((o) => o.id === "model"); + const defaultEntry = (modelOption as any).options.find((o: any) => o.value === "default"); + expect(defaultEntry.description).toBeUndefined(); + }); + }); + describe("switching the agent", () => { function createMockAgent() { const mockClient = { sessionUpdate: async () => {} } as unknown as AcpClient;