refactor(ui-agent-preset): one home for turning a roster into options
The chip and the settings row both spread the same three fields, and `exactOptionalPropertyTypes` makes the absent-vs-undefined dance verbose enough that the duplication gate flagged it.
This commit is contained in:
@@ -14,7 +14,7 @@ import type { IApiClient } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import {
|
||||
createSnapshotStore, type SessionId, type SnapshotStore,
|
||||
} from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import { messageOf } from './settings-store.ts'
|
||||
import { messageOf, presetOptions } from './settings-store.ts'
|
||||
import type { AgentPresetOption } from './settings-store.ts'
|
||||
|
||||
/** Hero-chip snapshot. */
|
||||
@@ -80,12 +80,7 @@ export class AgentPresetSeatController {
|
||||
const { presets } = response.result.value
|
||||
this.fallback = presets.find(preset => preset.isDefault)?.id ?? presets[0]?.id ?? ''
|
||||
this.set({
|
||||
options: presets.map(preset => ({
|
||||
id: preset.id,
|
||||
trust: preset.trust,
|
||||
...preset.name === undefined ? {} : { name: preset.name },
|
||||
...preset.description === undefined ? {} : { description: preset.description },
|
||||
})),
|
||||
options: presetOptions(presets),
|
||||
current: this.staged ?? this.fallback,
|
||||
error: null,
|
||||
})
|
||||
|
||||
@@ -61,6 +61,27 @@ export interface AgentPresetOption {
|
||||
description?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* The roster entries as every surface renders them.
|
||||
*
|
||||
* The chip, the row, and the management section all show the same three
|
||||
* facts, and `exactOptionalPropertyTypes` makes "absent" and "present as
|
||||
* undefined" different shapes — so the spread dance belongs in one place
|
||||
* rather than once per store.
|
||||
* @param presets - the roster the host answered with.
|
||||
* @returns one option per preset, in roster order.
|
||||
*/
|
||||
export function presetOptions(
|
||||
presets: readonly { id: string, trust: 'system' | 'user', name?: string, description?: string }[],
|
||||
): AgentPresetOption[] {
|
||||
return presets.map(preset => ({
|
||||
id: preset.id,
|
||||
trust: preset.trust,
|
||||
...preset.name === undefined ? {} : { name: preset.name },
|
||||
...preset.description === undefined ? {} : { description: preset.description },
|
||||
}))
|
||||
}
|
||||
|
||||
/** Agent-preset settings-row snapshot. */
|
||||
export interface AgentPresetSettingsState {
|
||||
status: 'idle' | 'loading' | 'ready' | 'saving' | 'unavailable' | 'error'
|
||||
@@ -127,12 +148,7 @@ export class AgentPresetSettingsController {
|
||||
status: 'ready',
|
||||
error: null,
|
||||
writable: described.result.ok && described.result.value.writable,
|
||||
options: presets.map(preset => ({
|
||||
id: preset.id,
|
||||
trust: preset.trust,
|
||||
...preset.name === undefined ? {} : { name: preset.name },
|
||||
...preset.description === undefined ? {} : { description: preset.description },
|
||||
})),
|
||||
options: presetOptions(presets),
|
||||
// A roster can mark nothing default: settings can name a preset that
|
||||
// was since deleted, and the picker still has to show something.
|
||||
currentValue: presets.find(preset => preset.isDefault)?.id ?? first.id,
|
||||
|
||||
Reference in New Issue
Block a user