/ src / server / chat / slash-command-parser / settings-builders.ts
settings-builders.ts
  1  import {
  2    parseProviderEndpointMode,
  3  } from '@/server/chat/slash-command-parser-provider-target'
  4  import type { GlobalDefaults } from '@/lib/shared/chat'
  5  import type {
  6    SettingsDefaultsFieldCommandInput,
  7    SettingsDefaultsFieldKind,
  8    SettingsDefaultsClearTarget,
  9    SlashCommand,
 10  } from './ast'
 11  import {
 12    SETTINGS_DEFAULTS_CLEAR_ALL_PATCH,
 13    SETTINGS_PROVIDER_CLEAR_PATCH,
 14    parseProviderDefaultPreset,
 15  } from './ast'
 16  import { parseReasoningLevel } from './reasoning'
 17  import { parseThinkingLevel } from './thinking'
 18  
 19  const SETTINGS_DEFAULTS_FIELD_COMMAND_BUILDERS: Record<
 20    SettingsDefaultsFieldKind,
 21    (input: SettingsDefaultsFieldCommandInput) => SlashCommand
 22  > = {
 23    model: buildSettingsDefaultsModelFieldCommand,
 24    thinking: buildSettingsDefaultsThinkingFieldCommand,
 25    reasoning: buildSettingsDefaultsReasoningFieldCommand,
 26    providerId: buildSettingsDefaultsProviderIdFieldCommand,
 27    endpointMode: buildSettingsDefaultsEndpointModeFieldCommand,
 28  }
 29  
 30  export function buildSettingsDefaultsClearCommand(
 31    clearTarget: SettingsDefaultsClearTarget,
 32  ): SlashCommand {
 33    if (clearTarget === 'all') {
 34      return buildSettingsDefaultsUpdateCommand(
 35        'all defaults reset',
 36        SETTINGS_DEFAULTS_CLEAR_ALL_PATCH,
 37      )
 38    }
 39  
 40    if (clearTarget === 'model') {
 41      return buildSettingsDefaultsUpdateCommand('default model cleared', {
 42        chatModel: null,
 43      })
 44    }
 45  
 46    if (clearTarget === 'thinking') {
 47      return buildSettingsDefaultsUpdateCommand('default thinking cleared', {
 48        thinkingLevel: null,
 49      })
 50    }
 51  
 52    if (clearTarget === 'reasoning') {
 53      return buildSettingsDefaultsUpdateCommand('default reasoning cleared', {
 54        reasoningLevel: null,
 55      })
 56    }
 57  
 58    if (clearTarget === 'provider') {
 59      return buildSettingsDefaultsUpdateCommand(
 60        'default provider settings cleared',
 61        SETTINGS_PROVIDER_CLEAR_PATCH,
 62      )
 63    }
 64  
 65    return buildSettingsDefaultsUpdateCommand(
 66      'default provider endpoint mode cleared',
 67      { providerEndpointMode: null },
 68    )
 69  }
 70  
 71  export function buildSettingsDefaultsFieldCommand(
 72    fieldKind: SettingsDefaultsFieldKind,
 73    input: SettingsDefaultsFieldCommandInput,
 74  ): SlashCommand {
 75    const buildFieldCommand = SETTINGS_DEFAULTS_FIELD_COMMAND_BUILDERS[fieldKind]
 76    return buildFieldCommand(input)
 77  }
 78  
 79  export function buildSettingsDefaultsModelFieldCommand(
 80    input: SettingsDefaultsFieldCommandInput,
 81  ): SlashCommand {
 82    return buildSettingsDefaultsUpdateCommand(
 83      input.clearValue
 84        ? 'default model cleared'
 85        : `default model → ${input.rawValue}`,
 86      { chatModel: input.clearValue ? null : input.rawValue },
 87    )
 88  }
 89  
 90  export function buildSettingsDefaultsThinkingFieldCommand(
 91    input: SettingsDefaultsFieldCommandInput,
 92  ): SlashCommand {
 93    if (input.clearValue) {
 94      return buildSettingsDefaultsUpdateCommand('default thinking cleared', {
 95        thinkingLevel: null,
 96      })
 97    }
 98    const thinkingLevel = parseThinkingLevel(input.rawValue)
 99    if (!thinkingLevel) return { kind: 'settings-defaults-show' }
100    return buildSettingsDefaultsUpdateCommand(`default thinking → ${thinkingLevel}`, {
101      thinkingLevel,
102    })
103  }
104  
105  export function buildSettingsDefaultsReasoningFieldCommand(
106    input: SettingsDefaultsFieldCommandInput,
107  ): SlashCommand {
108    if (input.clearValue) {
109      return buildSettingsDefaultsUpdateCommand('default reasoning cleared', {
110        reasoningLevel: null,
111      })
112    }
113    const reasoningLevel = parseReasoningLevel(input.rawValue)
114    if (!reasoningLevel) return { kind: 'settings-defaults-show' }
115    return buildSettingsDefaultsUpdateCommand(`default reasoning → ${reasoningLevel}`, {
116      reasoningLevel,
117    })
118  }
119  
120  export function buildSettingsDefaultsProviderIdFieldCommand(
121    input: SettingsDefaultsFieldCommandInput,
122  ): SlashCommand {
123    if (input.clearValue) {
124      return buildSettingsDefaultsUpdateCommand('default provider cleared', {
125        defaultProviderId: null,
126      })
127    }
128    const preset = parseProviderDefaultPreset(input.rawValue)
129    if (!preset) return { kind: 'settings-defaults-show' }
130    return buildSettingsDefaultsUpdateCommand(
131      `default provider → ${preset}`,
132      { defaultProviderId: preset },
133    )
134  }
135  
136  export function buildSettingsDefaultsEndpointModeFieldCommand(
137    input: SettingsDefaultsFieldCommandInput,
138  ): SlashCommand {
139    if (input.clearValue) {
140      return buildSettingsDefaultsUpdateCommand(
141        'default provider endpoint mode cleared',
142        { providerEndpointMode: null },
143      )
144    }
145  
146    const endpointMode = parseProviderEndpointMode(input.rawValue)
147    if (!endpointMode) return { kind: 'settings-defaults-show' }
148    return buildSettingsDefaultsUpdateCommand(
149      `default provider endpoint mode → ${endpointMode}`,
150      { providerEndpointMode: endpointMode },
151    )
152  }
153  
154  export function buildSettingsDefaultsUpdateCommand(
155    scopeLabel: string,
156    patch: Partial<GlobalDefaults>,
157  ): SlashCommand {
158    return {
159      kind: 'settings-defaults-update',
160      scopeLabel,
161      patch,
162    }
163  }