fix(tui): persist model switches by default
This commit is contained in:
@@ -25,6 +25,36 @@ describe('createSlashHandler', () => {
|
||||
expect(ctx.gateway.gw.request).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('persists typed /model switches by default', async () => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
|
||||
const ctx = buildCtx({
|
||||
gateway: {
|
||||
...buildGateway(),
|
||||
rpc: vi.fn(() => Promise.resolve({ value: 'x-model' }))
|
||||
}
|
||||
})
|
||||
|
||||
expect(createSlashHandler(ctx)('/model x-model')).toBe(true)
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||
key: 'model',
|
||||
session_id: 'sid-abc',
|
||||
value: 'x-model --global'
|
||||
})
|
||||
})
|
||||
|
||||
it('does not duplicate --global for explicit persistent model switches', () => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
const ctx = buildCtx()
|
||||
|
||||
createSlashHandler(ctx)('/model x-model --global')
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||
key: 'model',
|
||||
session_id: 'sid-abc',
|
||||
value: 'x-model --global'
|
||||
})
|
||||
})
|
||||
|
||||
it('opens the skills hub locally for bare /skills', () => {
|
||||
const ctx = buildCtx()
|
||||
|
||||
|
||||
@@ -16,6 +16,14 @@ import { patchOverlayState } from '../../overlayStore.js'
|
||||
import { patchUiState } from '../../uiStore.js'
|
||||
import type { SlashCommand } from '../types.js'
|
||||
|
||||
const GLOBAL_MODEL_FLAG_RE = /(?:^|\s)--global(?:\s|$)/
|
||||
|
||||
const persistedModelArg = (arg: string) => {
|
||||
const trimmed = arg.trim()
|
||||
|
||||
return GLOBAL_MODEL_FLAG_RE.test(trimmed) ? trimmed : `${trimmed} --global`
|
||||
}
|
||||
|
||||
export const sessionCommands: SlashCommand[] = [
|
||||
{
|
||||
aliases: ['bg'],
|
||||
@@ -69,21 +77,23 @@ export const sessionCommands: SlashCommand[] = [
|
||||
return patchOverlayState({ modelPicker: true })
|
||||
}
|
||||
|
||||
ctx.gateway.rpc<ConfigSetResponse>('config.set', { key: 'model', session_id: ctx.sid, value: arg.trim() }).then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return ctx.transcript.sys('error: invalid response: model switch')
|
||||
}
|
||||
ctx.gateway
|
||||
.rpc<ConfigSetResponse>('config.set', { key: 'model', session_id: ctx.sid, value: persistedModelArg(arg) })
|
||||
.then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return ctx.transcript.sys('error: invalid response: model switch')
|
||||
}
|
||||
|
||||
ctx.transcript.sys(`model → ${r.value}`)
|
||||
ctx.local.maybeWarn(r)
|
||||
ctx.transcript.sys(`model → ${r.value}`)
|
||||
ctx.local.maybeWarn(r)
|
||||
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
info: state.info ? { ...state.info, model: r.value! } : { model: r.value!, skills: {}, tools: {} }
|
||||
}))
|
||||
})
|
||||
)
|
||||
patchUiState(state => ({
|
||||
...state,
|
||||
info: state.info ? { ...state.info, model: r.value! } : { model: r.value!, skills: {}, tools: {} }
|
||||
}))
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -627,7 +627,7 @@ export function useMainApp(gw: GatewayClient) {
|
||||
|
||||
const onModelSelect = useCallback((value: string) => {
|
||||
patchOverlayState({ modelPicker: false })
|
||||
slashRef.current(`/model ${value}`)
|
||||
slashRef.current(`/model ${value} --global`)
|
||||
}, [])
|
||||
|
||||
const hasReasoning = Boolean(turn.reasoning.trim())
|
||||
|
||||
Reference in New Issue
Block a user