/ src / server / chat / slash-command-parser / settings.ts
settings.ts
 1  import type { SlashCommand } from './ast'
 2  import {
 3    SETTINGS_DEFAULTS_CLEAR_TARGET_ALIASES,
 4    SETTINGS_DEFAULTS_FIELD_ALIAS_TO_KIND,
 5  } from './ast'
 6  import {
 7    buildSettingsDefaultsClearCommand,
 8    buildSettingsDefaultsFieldCommand,
 9  } from './settings-builders'
10  import type { ParsedSlashInput } from './lexer'
11  
12  export function parseSettingsSlashCommand(input: ParsedSlashInput): SlashCommand | null {
13    if (input.name !== 'settings') return null
14  
15    const normalized = input.rest.toLowerCase()
16    if (!input.rest || normalized === 'show' || normalized === 'current') {
17      return { kind: 'settings-show' }
18    }
19    if (
20      normalized === 'defaults' ||
21      normalized === 'defaults show' ||
22      normalized === 'defaults current'
23    ) {
24      return { kind: 'settings-defaults-show' }
25    }
26    if (normalized.startsWith('defaults ')) {
27      return parseSettingsDefaultsSlashCommand(
28        input.rest.slice('defaults'.length).trim(),
29      )
30    }
31    return { kind: 'settings-show' }
32  }
33  
34  export function parseSettingsDefaultsSlashCommand(rest: string): SlashCommand {
35    const trimmed = rest.trim()
36    if (!trimmed) return { kind: 'settings-defaults-show' }
37  
38    const clearCommand = parseSettingsDefaultsClearCommand(trimmed)
39    if (clearCommand) return clearCommand
40  
41    const fieldCommand = parseSettingsDefaultsFieldCommand(trimmed)
42    if (fieldCommand) return fieldCommand
43  
44    return { kind: 'settings-defaults-show' }
45  }
46  
47  export function parseSettingsDefaultsClearCommand(trimmed: string): SlashCommand | null {
48    const clearMatch = trimmed.match(
49      /^clear(?:\s+(all|model|think|thinking|reasoning|provider|url|endpoint))?$/i,
50    )
51    if (!clearMatch) return null
52  
53    const rawTarget = clearMatch[1] ? clearMatch[1].toLowerCase() : 'all'
54    const clearTarget =
55      SETTINGS_DEFAULTS_CLEAR_TARGET_ALIASES[rawTarget] ?? 'endpoint'
56  
57    return buildSettingsDefaultsClearCommand(clearTarget)
58  }
59  
60  export function parseSettingsDefaultsFieldCommand(trimmed: string): SlashCommand | null {
61    const fieldMatch = trimmed.match(/^([a-z_][a-z0-9_-]*)\s*:\s*(.+)$/i)
62    if (!fieldMatch) return null
63  
64    const field = fieldMatch[1].toLowerCase()
65    const rawValue = fieldMatch[2].trim()
66    const clearValue =
67      rawValue === '' || /^(none|null|clear|reset|default)$/i.test(rawValue)
68  
69    const fieldKind = SETTINGS_DEFAULTS_FIELD_ALIAS_TO_KIND[field]
70    if (!fieldKind) return { kind: 'settings-defaults-show' }
71  
72    return buildSettingsDefaultsFieldCommand(fieldKind, {
73      rawValue,
74      clearValue,
75    })
76  }