diff --git a/src/renderer/src/components/native-chat/native-chat-pty-session-options.ts b/src/renderer/src/components/native-chat/native-chat-pty-session-options.ts index aa7562b5944..34f9477cf91 100644 --- a/src/renderer/src/components/native-chat/native-chat-pty-session-options.ts +++ b/src/renderer/src/components/native-chat/native-chat-pty-session-options.ts @@ -63,8 +63,9 @@ export function createNativeChatPtySessionOptions( return null } let models = [...(args.initialModels ?? catalog.models)] - // The enrichment cache only ever holds probe output, so being handed a list at all - // means `isDefault` below names the account's real default rather than the seed guess. + // The enrichment cache holds probe output plus consent-gated seed rows, which are stripped + // of `isDefault`, so being handed a list at all still means `isDefault` below names the + // account's real default rather than the seed guess. let modelsAreDiscovered = args.initialModels !== undefined let record = readNativeChatSessionOptionCache(args.scopeKey, args.fallbackScopeKey) ?? diff --git a/src/shared/agent-session-option-catalog.test.ts b/src/shared/agent-session-option-catalog.test.ts index 8b89275fa6e..2a94cb05ad8 100644 --- a/src/shared/agent-session-option-catalog.test.ts +++ b/src/shared/agent-session-option-catalog.test.ts @@ -139,6 +139,19 @@ describe('agent session option catalog', () => { expect(merged.find(({ id }) => id === 'fable')?.options.map(({ id }) => id)).toEqual(['effort']) }) + it('strips `isDefault` from a re-added gated row so it cannot pose as the probed default', () => { + const claude = getAgentSessionOptionCatalog('claude')! + const catalog = { + ...claude, + models: [{ id: 'fable', label: 'Fable', isDefault: true, options: [] }] + } + const merged = withConsentGatedSeedModels(catalog, [ + { id: 'sonnet', label: 'Sonnet', options: [] } + ]) + expect(merged.map(({ id }) => id)).toEqual(['fable', 'sonnet']) + expect(merged[0].isDefault).toBeUndefined() + }) + it('leaves a probe that already lists Fable untouched', () => { const catalog = getAgentSessionOptionCatalog('claude')! const discovered = [ diff --git a/src/shared/agent-session-option-catalog.ts b/src/shared/agent-session-option-catalog.ts index 21ffe898b28..79681b221c1 100644 --- a/src/shared/agent-session-option-catalog.ts +++ b/src/shared/agent-session-option-catalog.ts @@ -85,7 +85,9 @@ export function withConsentGatedSeedModels( const missing = catalog.models.filter( (model) => gated.includes(model.id) && !discovered.some((live) => live.id === model.id) ) - return [...missing, ...discovered] + // Why: consumers read `isDefault` on an enriched list as the probe's answer, and a row the + // probe never listed cannot name the account's default. + return [...missing.map(({ isDefault: _seeded, ...model }) => model), ...discovered] } /** Discovery decides membership; the seed keeps its option menus, which discovery never carries.