diff --git a/packages/client/ui-settings-models/tests/model-list-catalog.client.spec.tsx b/packages/client/ui-settings-models/tests/model-list-catalog.client.spec.tsx
index 66fc62bbc4..4a142ec8d5 100644
--- a/packages/client/ui-settings-models/tests/model-list-catalog.client.spec.tsx
+++ b/packages/client/ui-settings-models/tests/model-list-catalog.client.spec.tsx
@@ -54,3 +54,30 @@ it('uses provider input defaults for a model absent from the installed catalog',
fireEvent.click(text)
expect(onChange).toHaveBeenCalledWith([{ id: 'custom', input: ['text', 'image'] }])
})
+
+it('inherits catalog inputs once an incomplete draft has a model id', async () => {
+ const onChange = vi.fn()
+ const props = {
+ onChange, catalogProvider: 'openai',
+ probe: { settingsNs: 'llm-pi-ai', provider: 'openai' },
+ disabled: false, t: (key: keyof typeof en) => en[key],
+ operations: operations(() => Promise.resolve({
+ kind: 'found', models: [{ id: 'vision', inputModalities: ['text', 'image'] }],
+ })),
+ }
+ const { rerender } = render()
+ fireEvent.click(screen.getByRole('button', { name: `${en.modelAdvanced} 1` }))
+ const image = screen.getByRole('checkbox', { name: en.modelInputImage })
+ await waitFor(() => { expect(image.disabled).toBe(false) })
+ expect(screen.getByRole('checkbox', { name: en.modelInputText }).checked).toBe(true)
+ expect(image.checked).toBe(false)
+ expect(onChange).not.toHaveBeenCalled()
+
+ const id = screen.getByLabelText(`${en.modelId} 1`)
+ expect(id.value).toBe('')
+ fireEvent.change(id, { target: { value: 'vision' } })
+ expect(onChange).toHaveBeenCalledExactlyOnceWith([{ id: 'vision' }])
+ rerender()
+ expect(image.checked).toBe(true)
+ expect(onChange).toHaveBeenCalledTimes(1)
+})
diff --git a/packages/client/ui-settings-models/tests/provider-form.client.spec.tsx b/packages/client/ui-settings-models/tests/provider-form.client.spec.tsx
index cbf207605a..0659607e8d 100644
--- a/packages/client/ui-settings-models/tests/provider-form.client.spec.tsx
+++ b/packages/client/ui-settings-models/tests/provider-form.client.spec.tsx
@@ -522,6 +522,35 @@ describe('endpoint interrogation', () => {
expect(mutate).not.toHaveBeenCalled()
})
+ it('inherits a custom provider default input and persists an explicit model override', async () => {
+ const { discover, mutate } = await mountSection({
+ providers: {
+ 'acme-gateway': {
+ api: 'openai-completions', baseURL: 'https://gateway.acme.example/v1',
+ defaultInput: ['text', 'image'], models: [{ id: 'custom' }],
+ },
+ },
+ declaredRoutes: ['acme-gateway'],
+ })
+ openEditor('acme-gateway')
+ expandModel(1)
+ const types = within(screen.getByRole('group', { name: `${en.modelInputTypes} 1` }))
+ expect(types.getByRole('checkbox', { name: en.modelInputText }).checked).toBe(true)
+ const image = types.getByRole('checkbox', { name: en.modelInputImage })
+ expect(image.checked).toBe(true)
+ expect(image.disabled).toBe(false)
+ expect(discover).not.toHaveBeenCalled()
+ expect(mutate).not.toHaveBeenCalled()
+
+ fireEvent.click(image)
+ fireEvent.click(screen.getByText(en.apply))
+ await waitFor(() => { expect(mutate).toHaveBeenCalledTimes(1) })
+ expect(firstMutate(mutate).ops).toEqual([{
+ op: 'set', path: ['providers', 'acme-gateway', 'models'],
+ value: [{ id: 'custom', input: ['text'] }],
+ }])
+ })
+
it('asks the endpoint the form shows, with a key that is not yet stored', async () => {
const discover = vi.fn(() => Promise.resolve(ok([{ id: 'acme-large', contextWindow: 65_536 }])))
await mountSection({ discover })