mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 20:03:13 +08:00
fix(desktop): keep the session model out of a new provider's settings JSON
The add-model editor was spreading the whole managed settings file, so the model picker's selected default (model / modelContext) showed up as if it belonged to the provider being added and was written back on save.
This commit is contained in:
@@ -2733,6 +2733,69 @@ describe('Settings > Providers tab', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('omits the session default model from a new provider settings JSON', async () => {
|
||||
MOCK_GET_SETTINGS.mockResolvedValue({
|
||||
model: 'grok-4.7',
|
||||
modelContext: '1m',
|
||||
futureSetting: true,
|
||||
env: { EXISTING_ENV: '1' },
|
||||
})
|
||||
providerStoreState.createProvider = vi.fn().mockResolvedValue({
|
||||
id: 'provider-new',
|
||||
presetId: 'custom',
|
||||
name: 'Custom',
|
||||
apiKey: 'sk-test',
|
||||
baseUrl: 'https://api.example.com/anthropic',
|
||||
apiFormat: 'anthropic',
|
||||
models: {
|
||||
main: 'custom-main',
|
||||
haiku: 'custom-main',
|
||||
sonnet: 'custom-main',
|
||||
opus: 'custom-main',
|
||||
},
|
||||
})
|
||||
providerStoreState.presets = [
|
||||
{
|
||||
id: 'custom',
|
||||
name: 'Custom',
|
||||
baseUrl: 'https://api.example.com/anthropic',
|
||||
apiFormat: 'anthropic',
|
||||
defaultModels: {
|
||||
main: 'custom-main',
|
||||
haiku: '',
|
||||
sonnet: '',
|
||||
opus: '',
|
||||
},
|
||||
needsApiKey: true,
|
||||
websiteUrl: '',
|
||||
},
|
||||
]
|
||||
|
||||
render(<Settings />)
|
||||
fireEvent.click(screen.getByRole('button', { name: /Add Model/i }))
|
||||
const dialog = screen.getByRole('dialog')
|
||||
const settingsTextarea = await waitFor(() => {
|
||||
const textarea = dialog.querySelector('textarea')
|
||||
expect(textarea?.value).toContain('"EXISTING_ENV"')
|
||||
return textarea as HTMLTextAreaElement
|
||||
})
|
||||
const displayed = JSON.parse(settingsTextarea.value) as Record<string, unknown>
|
||||
expect(displayed).not.toHaveProperty('model')
|
||||
expect(displayed).not.toHaveProperty('modelContext')
|
||||
expect(displayed).toMatchObject({ futureSetting: true })
|
||||
|
||||
fireEvent.change(within(dialog).getByPlaceholderText('sk-...'), { target: { value: 'sk-test' } })
|
||||
fireEvent.click(within(dialog).getByRole('button', { name: /Save|Add/i }))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(MOCK_UPDATE_SETTINGS).toHaveBeenCalled()
|
||||
})
|
||||
const saved = MOCK_UPDATE_SETTINGS.mock.calls.at(-1)?.[0] as Record<string, unknown>
|
||||
expect(saved).not.toHaveProperty('model')
|
||||
expect(saved).not.toHaveProperty('modelContext')
|
||||
expect(saved).toMatchObject({ futureSetting: true, env: expect.objectContaining({ EXISTING_ENV: '1' }) })
|
||||
})
|
||||
|
||||
it('defaults Tool Search off and requires confirmation before persisting an explicit enable', async () => {
|
||||
MOCK_GET_SETTINGS.mockResolvedValue({ env: { EXISTING_ENV: '1' } })
|
||||
providerStoreState.createProvider = vi.fn().mockResolvedValue({
|
||||
|
||||
@@ -1156,6 +1156,12 @@ function ProviderFormModal({ open, onClose, mode, provider, presets, browserMode
|
||||
skipWebFetchPreflight: settings.skipWebFetchPreflight ?? true,
|
||||
env: mergedEnv,
|
||||
}
|
||||
// `model` / `modelContext` are the session's selected default, written by
|
||||
// the model picker. They are not part of the provider being added, so
|
||||
// showing them here makes a new provider look like it inherits Grok 4.7
|
||||
// (or whatever was last selected) and saving would write that back.
|
||||
delete merged.model
|
||||
delete merged.modelContext
|
||||
setSettingsJson(JSON.stringify(writeCompatibilityJson(merged, apiFormat === 'anthropic' ? undefined : parseCompatibilityForm(compatibility)), null, 2))
|
||||
}).catch(() => {
|
||||
if (!cancelled && !settingsJsonUserEditedRef.current) {
|
||||
@@ -1569,6 +1575,11 @@ function ProviderFormModal({ open, onClose, mode, provider, presets, browserMode
|
||||
const { providersApi } = await import('../../api/providers')
|
||||
const settings = writeCompatibilityJson(parsed, storedCompatibility)
|
||||
delete settings.requestCompatibility
|
||||
// The editor never owns the session default model. updateSettings merges
|
||||
// by replacing the whole object, so omitting these keys keeps the
|
||||
// model picker's selection instead of clearing it.
|
||||
delete settings.model
|
||||
delete settings.modelContext
|
||||
await providersApi.updateSettings(settings)
|
||||
} catch {
|
||||
// JSON validation already prevents this
|
||||
|
||||
Reference in New Issue
Block a user