Files
deepseek-harness/packages/client/ui-agent-preset/tests/settings-store.spec.ts
Yichen Jiang 6758da87ae feat(web): choose the default agent preset from General settings
One settings row picking which preset new sessions are composed from.

It is deliberately a new-session preference, not a live switch: a session's
preset is fixed at creation and the host refuses to adopt an existing session
under a different one, so the row says "applies to sessions you start from now
on" rather than implying it can retune a running agent.

Options and the current value come from one `agentPreset.list` call — the
roster already reports which id an unspecified session gets, so the row needs
no settings-schema introspection, unlike the permission row it is modelled on.
The write targets only the namespace's `default` field.

The menu marks `user` rows: a locally authored preset is exactly as privileged
as the plugins it names, and presenting it identically to a shipped one would
hide that.

An empty roster reads as `unavailable` and renders nothing, because composing
no presets is a valid deployment rather than a failure — distinct from a
roster call that failed, which surfaces its message.
2026-08-07 00:38:11 +08:00

123 lines
4.7 KiB
TypeScript

/**
* The agent-preset settings controller: it derives both the options and the
* current default from one roster call, writes only the `default` field, and
* treats an empty roster as "this deployment composes no presets" rather than
* as a failure.
*/
import { describe, expect, it } from 'vitest'
import type { IApiClient } from '@deepseek-ai/dsh-client-connection/client'
import {
AGENT_PRESET_SETTINGS_NS, AgentPresetSettingsController,
} from '../src/client/settings-store.ts'
interface Recorded { ns: string; patch: unknown }
/** A client whose roster and write outcome the test controls. */
function fakeApi(
presets: { id: string; trust: 'system' | 'user'; isDefault: boolean }[],
options: { writes?: Recorded[]; failWrite?: string; failList?: string } = {},
): IApiClient {
return {
agentPresets: {
list: () => Promise.resolve(options.failList === undefined
? { rpcId: 'r', result: { ok: true as const, value: { presets } } }
: { rpcId: 'r', result: { ok: false as const, error: { code: 'internal', message: options.failList, details: {} } } }),
},
settings: {
update: (payload: { ns: string; patch: unknown }) => {
options.writes?.push({ ns: payload.ns, patch: payload.patch })
if (options.failWrite !== undefined) {
return Promise.resolve({ rpcId: 'r', result: { ok: false as const, error: { code: 'internal', message: options.failWrite, details: {} } } })
}
// A committed write moves the roster's default, exactly as the host does.
for (const preset of presets) {
preset.isDefault = preset.id === (payload.patch as { default?: string }).default
}
return Promise.resolve({ rpcId: 'r', result: { ok: true as const, value: {} } })
},
},
} as unknown as IApiClient
}
describe('the agent-preset settings controller', () => {
it('derives options and the current default from one roster call', async () => {
const controller = new AgentPresetSettingsController(fakeApi([
{ id: 'standard', trust: 'system', isDefault: true },
{ id: 'mine', trust: 'user', isDefault: false },
]))
await controller.load()
const state = controller.store.getSnapshot()
expect(state.status).toBe('ready')
expect(state.currentValue).toBe('standard')
expect(state.options).toEqual([
{ id: 'standard', trust: 'system' },
{ id: 'mine', trust: 'user' },
])
})
it('reports an empty roster as unavailable, not as an error', async () => {
const controller = new AgentPresetSettingsController(fakeApi([]))
await controller.load()
// A deployment composing no presets is valid: every session shares the
// host composition and the row renders nothing.
expect(controller.store.getSnapshot().status).toBe('unavailable')
expect(controller.store.getSnapshot().error).toBeNull()
})
it('writes only the default field, into the agent-presets namespace', async () => {
const writes: Recorded[] = []
const controller = new AgentPresetSettingsController(fakeApi([
{ id: 'standard', trust: 'system', isDefault: true },
{ id: 'core-web', trust: 'system', isDefault: false },
], { writes }))
await controller.load()
await controller.select('core-web')
expect(writes).toEqual([{ ns: AGENT_PRESET_SETTINGS_NS, patch: { default: 'core-web' } }])
expect(controller.store.getSnapshot().currentValue).toBe('core-web')
})
it('restores the previous value and surfaces the message when the write fails', async () => {
const controller = new AgentPresetSettingsController(fakeApi([
{ id: 'standard', trust: 'system', isDefault: true },
{ id: 'core-web', trust: 'system', isDefault: false },
], { failWrite: 'read-only settings' }))
await controller.load()
await controller.select('core-web')
const state = controller.store.getSnapshot()
expect(state.currentValue).toBe('standard')
expect(state.error).toBe('read-only settings')
expect(state.status).toBe('ready')
})
it('ignores a pick that is already the default', async () => {
const writes: Recorded[] = []
const controller = new AgentPresetSettingsController(fakeApi([
{ id: 'standard', trust: 'system', isDefault: true },
], { writes }))
await controller.load()
await controller.select('standard')
expect(writes).toEqual([])
})
it('surfaces a roster failure without claiming the deployment has no presets', async () => {
const controller = new AgentPresetSettingsController(fakeApi([], { failList: 'host down' }))
await controller.load()
const state = controller.store.getSnapshot()
expect(state.status).toBe('error')
expect(state.error).toBe('host down')
})
})