@xopcai/xopc 0.0.34 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/{agents-BENeGWaV.js → agents-3MgROWaB.js} +2 -2
  3. package/dist/gateway/static/root/assets/{agents-BENeGWaV.js.map → agents-3MgROWaB.js.map} +1 -1
  4. package/dist/gateway/static/root/assets/{apps-page-C8S_3XR3.js → apps-page-Dh89sZVt.js} +2 -2
  5. package/dist/gateway/static/root/assets/{apps-page-C8S_3XR3.js.map → apps-page-Dh89sZVt.js.map} +1 -1
  6. package/dist/gateway/static/root/assets/{channels-settings-Z0gz9LEn.js → channels-settings-BNR4uMFv.js} +2 -2
  7. package/dist/gateway/static/root/assets/{channels-settings-Z0gz9LEn.js.map → channels-settings-BNR4uMFv.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{cron-api-DHcunvTO.js → cron-api-HehSuhku.js} +2 -2
  9. package/dist/gateway/static/root/assets/{cron-api-DHcunvTO.js.map → cron-api-HehSuhku.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{cron-page-CdZjOHQ5.js → cron-page-cNl5O7jj.js} +2 -2
  11. package/dist/gateway/static/root/assets/{cron-page-CdZjOHQ5.js.map → cron-page-cNl5O7jj.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{dist-DPEltH1B.js → dist-RpqJxYGW.js} +2 -2
  13. package/dist/gateway/static/root/assets/{dist-DPEltH1B.js.map → dist-RpqJxYGW.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{extension-debug-page-DyEkbdRu.js → extension-debug-page-C38A0UVx.js} +2 -2
  15. package/dist/gateway/static/root/assets/{extension-debug-page-DyEkbdRu.js.map → extension-debug-page-C38A0UVx.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-page-Vr_24oNG.js → extension-page-BHVeBMn8.js} +2 -2
  17. package/dist/gateway/static/root/assets/{extension-page-Vr_24oNG.js.map → extension-page-BHVeBMn8.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/{extension-settings-page-D3wIHYGH.js → extension-settings-page-D1iDIHYn.js} +2 -2
  19. package/dist/gateway/static/root/assets/{extension-settings-page-D3wIHYGH.js.map → extension-settings-page-D1iDIHYn.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/{index-DfzxemgG.js → index-C9ACajYe.js} +5 -5
  21. package/dist/gateway/static/root/assets/{index-DfzxemgG.js.map → index-C9ACajYe.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{logs-page-D-swbxzE.js → logs-page-DxbZy88k.js} +2 -2
  23. package/dist/gateway/static/root/assets/{logs-page-D-swbxzE.js.map → logs-page-DxbZy88k.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{sessions-page-CkevfEBJ.js → sessions-page-Cl-1QJM9.js} +2 -2
  25. package/dist/gateway/static/root/assets/{sessions-page-CkevfEBJ.js.map → sessions-page-Cl-1QJM9.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{settings-page-CGDCcKXO.js → settings-page-DUYYElOB.js} +2 -2
  27. package/dist/gateway/static/root/assets/{settings-page-CGDCcKXO.js.map → settings-page-DUYYElOB.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/skills-page-MiXi4U0-.js +3 -0
  29. package/dist/gateway/static/root/assets/skills-page-MiXi4U0-.js.map +1 -0
  30. package/dist/gateway/static/root/index.html +1 -1
  31. package/dist/package.js +1 -1
  32. package/package.json +1 -1
  33. package/dist/gateway/static/root/assets/skills-page-ZTABuog7.js +0 -3
  34. package/dist/gateway/static/root/assets/skills-page-ZTABuog7.js.map +0 -1
  35. /package/skills/{meta → tools}/skill-creator/LICENSE.txt +0 -0
  36. /package/skills/{meta → tools}/skill-creator/SKILL-zh.md +0 -0
  37. /package/skills/{meta → tools}/skill-creator/SKILL.md +0 -0
  38. /package/skills/{meta → tools}/skill-creator/agents/analyzer.md +0 -0
  39. /package/skills/{meta → tools}/skill-creator/agents/comparator.md +0 -0
  40. /package/skills/{meta → tools}/skill-creator/agents/grader.md +0 -0
  41. /package/skills/{meta → tools}/skill-creator/assets/eval_review.html +0 -0
  42. /package/skills/{meta → tools}/skill-creator/eval-viewer/generate_review.py +0 -0
  43. /package/skills/{meta → tools}/skill-creator/eval-viewer/viewer.html +0 -0
  44. /package/skills/{meta → tools}/skill-creator/references/schemas.md +0 -0
  45. /package/skills/{meta → tools}/skill-creator/scripts/__init__.py +0 -0
  46. /package/skills/{meta → tools}/skill-creator/scripts/aggregate_benchmark.py +0 -0
  47. /package/skills/{meta → tools}/skill-creator/scripts/generate_report.py +0 -0
  48. /package/skills/{meta → tools}/skill-creator/scripts/improve_description.py +0 -0
  49. /package/skills/{meta → tools}/skill-creator/scripts/package_skill.py +0 -0
  50. /package/skills/{meta → tools}/skill-creator/scripts/quick_validate.py +0 -0
  51. /package/skills/{meta → tools}/skill-creator/scripts/run_eval.py +0 -0
  52. /package/skills/{meta → tools}/skill-creator/scripts/run_loop.py +0 -0
  53. /package/skills/{meta → tools}/skill-creator/scripts/utils.py +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"settings-page-CGDCcKXO.js","names":[],"sources":["../../../../../web/src/features/settings/appearance-settings.tsx","../../../../../web/src/features/settings/dreaming-config-api.ts","../../../../../web/src/features/settings/dreaming-settings.tsx","../../../../../web/src/features/settings/gateway-config-api.ts","../../../../../web/src/features/settings/gateway-settings.tsx","../../../../../web/src/features/settings/channels-status-swr.ts","../../../../../web/src/features/settings/heartbeat-md-swr.ts","../../../../../web/src/features/settings/heartbeat-config-api.ts","../../../../../web/src/features/settings/heartbeat-interval-presets.ts","../../../../../web/src/features/settings/heartbeat-settings.tsx","../../../../../web/src/features/settings/agents/image-generation-model-input.tsx","../../../../../web/src/features/settings/agents/agent-defaults-panels/image-model-chains-section.tsx","../../../../../web/src/features/settings/image-models-settings.tsx","../../../../../web/src/features/settings/models-json-api.ts","../../../../../web/src/features/settings/agents/agent-defaults-panels/chat-model-fallbacks-section.tsx","../../../../../web/src/features/settings/models/models-settings-lib.ts","../../../../../web/src/features/settings/models/models-model-edit-dialog.tsx","../../../../../web/src/features/settings/models/models-provider-add-dialog.tsx","../../../../../web/src/features/settings/models/models-providers-list.tsx","../../../../../web/src/features/settings/models/models-settings-panel.tsx","../../../../../web/src/features/settings/oauth-api.ts","../../../../../web/src/features/settings/provider-info-popover.tsx","../../../../../web/src/features/settings/providers/providers-settings-lib.ts","../../../../../web/src/features/settings/providers/provider-credential-row.tsx","../../../../../web/src/features/settings/providers/providers-settings-panel.tsx","../../../../../web/src/features/settings/system-settings-panel.tsx","../../../../../web/src/features/settings/voice-config-api.ts","../../../../../web/src/features/settings/voice-settings.tsx","../../../../../web/src/features/settings/web-search-config-api.ts","../../../../../web/src/features/settings/web-search-settings.tsx","../../../../../web/src/pages/settings-page.tsx"],"sourcesContent":["import { PreferenceSelectFields } from '@/components/shell/preference-select-fields';\nimport { messages } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { type ColorScheme, useThemeStore } from '@/stores/theme-store';\n\nfunction preferenceCardClassName() {\n return cn('rounded-xl border border-edge-subtle bg-surface-base px-4 py-1 sm:px-5');\n}\n\n/**\n * Mini chrome preview per globals.css tokens — left: light, right: dark for the same palette.\n */\nconst SCHEME_PREVIEW: Record<\n ColorScheme,\n { light: { canvas: string; panel: string; accent: string; fg: string; muted: string }; dark: { canvas: string; panel: string; accent: string; fg: string; muted: string } }\n> = {\n default: {\n light: {\n canvas: '#f5f5f7',\n panel: '#ffffff',\n accent: '#2563eb',\n fg: '#1d1d1f',\n muted: '#d2d2d7',\n },\n dark: {\n canvas: '#1c1c1e',\n panel: '#2c2c2e',\n accent: '#3b82f6',\n fg: '#f5f5f7',\n muted: '#48484a',\n },\n },\n emerald: {\n light: {\n canvas: '#f0fdf4',\n panel: '#ffffff',\n accent: '#059669',\n fg: '#052e16',\n muted: '#86efac',\n },\n dark: {\n canvas: '#000000',\n panel: '#0a0a0a',\n accent: '#10b981',\n fg: '#d1fae5',\n muted: '#134e2a',\n },\n },\n mono: {\n light: {\n canvas: '#ffffff',\n panel: '#f5f5f5',\n accent: '#111111',\n fg: '#111111',\n muted: '#e5e7eb',\n },\n dark: {\n canvas: '#101010',\n panel: '#1a1a1a',\n accent: '#737373',\n fg: '#fafafa',\n muted: '#333333',\n },\n },\n};\n\nfunction SchemePreviewHalf({\n canvas,\n panel,\n accent,\n fg,\n muted,\n}: {\n canvas: string;\n panel: string;\n accent: string;\n fg: string;\n muted: string;\n}) {\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col justify-center gap-1 p-1.5\" style={{ backgroundColor: canvas }}>\n <div\n className=\"flex flex-col gap-0.5 rounded-sm border p-1\"\n style={{ backgroundColor: panel, borderColor: muted }}\n >\n <div className=\"flex items-center gap-1\">\n <div className=\"h-1 w-1 shrink-0 rounded-full\" style={{ backgroundColor: accent }} />\n <div className=\"h-1 min-w-0 flex-1 rounded-full\" style={{ backgroundColor: fg, opacity: 0.85 }} />\n </div>\n <div className=\"h-1 w-2/3 max-w-[70%] rounded-full\" style={{ backgroundColor: muted }} />\n <div className=\"h-1 w-1/2 max-w-[55%] rounded-full\" style={{ backgroundColor: muted }} />\n </div>\n </div>\n );\n}\n\n/** Side-by-side light (left) and dark (right) samples for one color scheme. */\nfunction SchemePreviewSwatch({ scheme }: { scheme: ColorScheme }) {\n const { light, dark } = SCHEME_PREVIEW[scheme];\n return (\n <div className=\"flex h-11 w-full overflow-hidden rounded-md border border-edge-subtle\">\n <SchemePreviewHalf {...light} />\n <div className=\"w-px shrink-0 bg-black/12 dark:bg-white/12\" aria-hidden />\n <SchemePreviewHalf {...dark} />\n </div>\n );\n}\n\nconst COLOR_SCHEME_OPTIONS: {\n value: ColorScheme;\n labelKey: 'colorSchemeDefault' | 'colorSchemeLightGreen' | 'colorSchemeModernMono';\n}[] = [\n { value: 'default', labelKey: 'colorSchemeDefault' },\n { value: 'emerald', labelKey: 'colorSchemeLightGreen' },\n { value: 'mono', labelKey: 'colorSchemeModernMono' },\n];\n\nfunction ColorSchemeSelector() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.appearanceSettings;\n const colorScheme = useThemeStore((s) => s.colorScheme);\n const setColorScheme = useThemeStore((s) => s.setColorScheme);\n\n return (\n <div className=\"flex flex-col gap-2 border-b border-edge-subtle py-3.5 last:border-b-0 sm:py-4\">\n <div className=\"min-w-0\">\n <div className=\"text-sm font-semibold text-fg\">{a.colorSchemeTitle}</div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{a.colorSchemeDescription}</p>\n </div>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {COLOR_SCHEME_OPTIONS.map(({ value, labelKey }) => {\n const isSelected = colorScheme === value;\n return (\n <button\n key={value}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => setColorScheme(value)}\n className={cn(\n 'flex flex-col gap-2 rounded-xl border-2 p-2.5 text-left transition-[border-color,box-shadow] duration-150',\n isSelected\n ? 'border-accent shadow-[0_0_0_1px_var(--color-accent)]'\n : 'border-edge-subtle hover:border-edge',\n )}\n >\n <SchemePreviewSwatch scheme={value} />\n <span\n className={cn(\n 'text-xs font-medium leading-none',\n isSelected ? 'text-accent-fg' : 'text-fg-muted',\n )}\n >\n {a[labelKey]}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function AppearanceSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.appearanceSettings;\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-1\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{a.pageTitle}</h1>\n <p className=\"text-sm text-fg-muted\">{a.subtitle}</p>\n </header>\n\n <section className={preferenceCardClassName()} aria-labelledby=\"pref-language-heading\">\n <h2 id=\"pref-language-heading\" className=\"sr-only\">\n {a.languageTitle}\n </h2>\n <PreferenceSelectFields variant=\"page\" sections={['language']} />\n </section>\n\n <section className={preferenceCardClassName()} aria-labelledby=\"pref-appearance-heading\">\n <h2 id=\"pref-appearance-heading\" className=\"sr-only\">\n {a.themeTitle}\n </h2>\n <PreferenceSelectFields variant=\"page\" sections={['theme', 'font']} />\n <ColorSchemeSelector />\n </section>\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport type DreamingLightConfigState = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n dedupeSimilarity: number;\n};\n\nexport type DreamingDeepConfigState = {\n enabled: boolean;\n cron: string;\n minScore: number;\n minRecallCount: number;\n limit: number;\n recencyHalfLifeDays: number;\n maxAgeDays: number;\n};\n\nexport type DreamingRemConfigState = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n minPatternStrength: number;\n};\n\nexport type DreamingConfigState = {\n enabled: boolean;\n frequency: string;\n timezone: string;\n /** @deprecated Use phases.deep.enabled */\n deepEnabled: boolean;\n /** @deprecated Use phases.deep.minScore */\n minScore: number;\n /** @deprecated Use phases.deep.minRecallCount */\n minRecallCount: number;\n /** @deprecated Use phases.deep.limit */\n limit: number;\n light: DreamingLightConfigState;\n deep: DreamingDeepConfigState;\n rem: DreamingRemConfigState;\n};\n\nconst LIGHT_DEFAULTS: DreamingLightConfigState = {\n enabled: true,\n cron: '0 */6 * * *',\n lookbackDays: 1,\n limit: 50,\n dedupeSimilarity: 0.85,\n};\n\nconst DEEP_DEFAULTS: DreamingDeepConfigState = {\n enabled: true,\n cron: '0 3 * * *',\n minScore: 0.8,\n minRecallCount: 3,\n limit: 10,\n recencyHalfLifeDays: 14,\n maxAgeDays: 30,\n};\n\nconst REM_DEFAULTS: DreamingRemConfigState = {\n enabled: true,\n cron: '0 5 * * 0',\n lookbackDays: 7,\n limit: 20,\n minPatternStrength: 0.6,\n};\n\nconst DEFAULTS: DreamingConfigState = {\n enabled: false,\n frequency: '0 3 * * *',\n timezone: '',\n deepEnabled: true,\n minScore: 0.8,\n minRecallCount: 3,\n limit: 10,\n light: LIGHT_DEFAULTS,\n deep: DEEP_DEFAULTS,\n rem: REM_DEFAULTS,\n};\n\nfunction clamp01(n: number, fallback: number): number {\n if (!Number.isFinite(n)) return fallback;\n return Math.max(0, Math.min(1, n));\n}\n\nfunction toInt(n: unknown, fallback: number): number {\n const x = typeof n === 'string' ? Number(n) : (n as number);\n if (!Number.isFinite(x)) return fallback;\n return Math.max(0, Math.floor(x));\n}\n\nfunction toNum(value: unknown, fallback: number): number {\n const num = typeof value === 'string' ? Number(value) : (value as number);\n return Number.isFinite(num) ? num : fallback;\n}\n\nexport function normalizeDreamingFromConfig(config: unknown): DreamingConfigState {\n const c = isRecord(config) ? config : {};\n const agents = isRecord(c.agents) ? c.agents : {};\n const defaults = isRecord(agents.defaults) ? agents.defaults : {};\n const memory = isRecord(defaults.memory) ? defaults.memory : {};\n const dreaming = isRecord(memory.dreaming) ? memory.dreaming : {};\n const phases = isRecord(dreaming.phases) ? dreaming.phases : {};\n const lightRaw = isRecord(phases.light) ? phases.light : {};\n const deepRaw = isRecord(phases.deep) ? phases.deep : {};\n const remRaw = isRecord(phases.rem) ? phases.rem : {};\n\n return {\n enabled: dreaming.enabled === true,\n frequency: typeof dreaming.frequency === 'string' && dreaming.frequency.trim() ? dreaming.frequency.trim() : DEFAULTS.frequency,\n timezone: typeof dreaming.timezone === 'string' ? dreaming.timezone : '',\n deepEnabled: deepRaw.enabled !== false,\n minScore: clamp01(typeof deepRaw.minScore === 'number' ? deepRaw.minScore : Number(deepRaw.minScore), DEFAULTS.minScore),\n minRecallCount: Math.max(1, toInt(deepRaw.minRecallCount, DEFAULTS.minRecallCount)),\n limit: toInt(deepRaw.limit, DEFAULTS.limit),\n light: {\n enabled: lightRaw.enabled !== false,\n cron: typeof lightRaw.cron === 'string' && lightRaw.cron.trim() ? lightRaw.cron.trim() : LIGHT_DEFAULTS.cron,\n lookbackDays: Math.max(1, toInt(lightRaw.lookbackDays, LIGHT_DEFAULTS.lookbackDays)),\n limit: toInt(lightRaw.limit, LIGHT_DEFAULTS.limit),\n dedupeSimilarity: clamp01(toNum(lightRaw.dedupeSimilarity, LIGHT_DEFAULTS.dedupeSimilarity), LIGHT_DEFAULTS.dedupeSimilarity),\n },\n deep: {\n enabled: deepRaw.enabled !== false,\n cron: typeof deepRaw.cron === 'string' && deepRaw.cron.trim() ? deepRaw.cron.trim() : DEEP_DEFAULTS.cron,\n minScore: clamp01(toNum(deepRaw.minScore, DEEP_DEFAULTS.minScore), DEEP_DEFAULTS.minScore),\n minRecallCount: Math.max(1, toInt(deepRaw.minRecallCount, DEEP_DEFAULTS.minRecallCount)),\n limit: toInt(deepRaw.limit, DEEP_DEFAULTS.limit),\n recencyHalfLifeDays: Math.max(1, toNum(deepRaw.recencyHalfLifeDays, DEEP_DEFAULTS.recencyHalfLifeDays)),\n maxAgeDays: Math.max(1, toNum(deepRaw.maxAgeDays, DEEP_DEFAULTS.maxAgeDays)),\n },\n rem: {\n enabled: remRaw.enabled !== false,\n cron: typeof remRaw.cron === 'string' && remRaw.cron.trim() ? remRaw.cron.trim() : REM_DEFAULTS.cron,\n lookbackDays: Math.max(1, toInt(remRaw.lookbackDays, REM_DEFAULTS.lookbackDays)),\n limit: toInt(remRaw.limit, REM_DEFAULTS.limit),\n minPatternStrength: clamp01(toNum(remRaw.minPatternStrength, REM_DEFAULTS.minPatternStrength), REM_DEFAULTS.minPatternStrength),\n },\n };\n}\n\nexport async function patchDreamingConfig(state: DreamingConfigState): Promise<void> {\n const freq = state.frequency.trim();\n const tz = state.timezone.trim();\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n agents: {\n defaults: {\n memory: {\n dreaming: {\n enabled: Boolean(state.enabled),\n frequency: freq || null,\n timezone: tz || null,\n phases: {\n light: {\n enabled: Boolean(state.light.enabled),\n cron: state.light.cron.trim() || null,\n lookbackDays: Math.max(1, Math.floor(state.light.lookbackDays)),\n limit: Math.max(0, Math.floor(state.light.limit)),\n dedupeSimilarity: clamp01(state.light.dedupeSimilarity, LIGHT_DEFAULTS.dedupeSimilarity),\n },\n deep: {\n enabled: Boolean(state.deep.enabled),\n cron: state.deep.cron.trim() || null,\n minScore: clamp01(state.deep.minScore, DEEP_DEFAULTS.minScore),\n minRecallCount: Math.max(1, Math.floor(state.deep.minRecallCount)),\n limit: Math.max(0, Math.floor(state.deep.limit)),\n recencyHalfLifeDays: Math.max(1, state.deep.recencyHalfLifeDays),\n maxAgeDays: Math.max(1, state.deep.maxAgeDays),\n },\n rem: {\n enabled: Boolean(state.rem.enabled),\n cron: state.rem.cron.trim() || null,\n lookbackDays: Math.max(1, Math.floor(state.rem.lookbackDays)),\n limit: Math.max(0, Math.floor(state.rem.limit)),\n minPatternStrength: clamp01(state.rem.minPatternStrength, REM_DEFAULTS.minPatternStrength),\n },\n },\n },\n },\n },\n },\n }),\n });\n\n void revalidateGatewayConfig();\n}\n\n","import { Activity, Loader2, Moon, Play, RefreshCw, ScanLine, Settings2, Sparkles, Sun, Trash2, Unlock, Wrench } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { messages, type MessageBundle } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { cn } from '@/lib/cn';\nimport {\n SettingsFormSection,\n settingsFormSectionClassName,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport {\n dreamingSwrKey,\n fetchDreamingEvents,\n fetchDreamingStatus,\n fetchDreamingPreview,\n postDreamingAction,\n postDreamingRunNow,\n type DreamingEvent,\n type DreamingGatewayStatus,\n type DreamingLastRunRecord,\n type DreamingPhaseId,\n type DreamingPreviewItem,\n type PhaseLastRun,\n} from '@/features/settings/dreaming-api';\nimport {\n normalizeDreamingFromConfig,\n patchDreamingConfig,\n type DreamingConfigState,\n} from '@/features/settings/dreaming-config-api';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\n\nfunction rowLabelClass(): string {\n return 'text-xs font-medium text-fg-muted';\n}\n\nfunction rowValueClass(): string {\n return 'text-sm font-medium text-fg';\n}\n\nfunction isoShort(v: string | null | undefined): string {\n if (!v) return '—';\n return v.replace('T', ' ').replace('Z', '');\n}\n\nfunction formatDurationMs(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)} ms`;\n return `${(ms / 1000).toFixed(2)} s`;\n}\n\ntype DreamingSettingsI18n = MessageBundle['dreamingSettings'];\n\nfunction Subsection({ label, children, className }: { label: string; children: ReactNode; className?: string }) {\n return (\n <div className={cn('space-y-2', className)}>\n <h3 className=\"text-[0.7rem] font-semibold uppercase tracking-wider text-fg-muted\">{label}</h3>\n {children}\n </div>\n );\n}\n\nfunction PhaseStatusCard({\n icon,\n label,\n enabled,\n cron,\n details,\n t,\n}: {\n icon: ReactNode;\n label: string;\n enabled: boolean;\n cron: string;\n details: string;\n t: DreamingSettingsI18n;\n}) {\n return (\n <div className={cn(settingsFormSectionClassName(), 'space-y-1.5')}>\n <div className=\"flex items-center gap-2\">\n {icon}\n <span className=\"text-sm font-medium text-fg\">{label}</span>\n <span className={cn('ml-auto text-xs font-medium', enabled ? 'text-emerald-600 dark:text-emerald-400' : 'text-fg-muted')}>\n {enabled ? t.on : t.off}\n </span>\n </div>\n <div className=\"font-mono text-xs text-fg-muted\">{cron}</div>\n <div className=\"text-xs text-fg-muted\">{details}</div>\n </div>\n );\n}\n\nfunction PhaseLastRunBlock({\n label,\n lastRun,\n t,\n}: {\n label: string;\n lastRun: PhaseLastRun | undefined;\n t: DreamingSettingsI18n;\n}) {\n return (\n <Subsection label={label}>\n {lastRun?.exists ? (\n <details className=\"group rounded-lg border border-edge-subtle\">\n <summary className=\"cursor-pointer list-none px-3 py-2 text-xs font-medium text-fg-muted marker:hidden [&::-webkit-details-marker]:hidden\">\n <span className=\"underline decoration-edge underline-offset-2 group-open:text-fg\">{t.lastRunRaw}</span>\n </summary>\n <pre className=\"max-h-[12rem] overflow-auto border-t border-edge-subtle p-3 text-xs text-fg-muted\">\n {JSON.stringify(lastRun.raw, null, 2)}\n </pre>\n </details>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.phaseLastRunEmpty}</p>\n )}\n </Subsection>\n );\n}\n\nfunction LastRunStructuredView({ t, r }: { t: DreamingSettingsI18n; r: DreamingLastRunRecord }) {\n const s = r.deep?.skipped;\n return (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunStatus}</div>\n <div className={cn(rowValueClass(), r.ok ? 'text-emerald-600 dark:text-emerald-400' : 'text-amber-600 dark:text-amber-400')}>\n {r.ok ? t.lastRunSuccess : t.lastRunFailure}\n </div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunDuration}</div>\n <div className={rowValueClass()}>{formatDurationMs(r.durationMs)}</div>\n </div>\n <div className={cn(settingsFormSectionClassName(), 'sm:col-span-2')}>\n <div className={rowLabelClass()}>{t.lastRunReason}</div>\n <div className={rowValueClass()}>{r.reason}</div>\n {r.errorMessage ? (\n <div className=\"mt-1 text-xs text-amber-600 dark:text-amber-400\">{`${t.lastRunError}: ${r.errorMessage}`}</div>\n ) : null}\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunRanked}</div>\n <div className={rowValueClass()}>{String(r.deep?.candidatesRanked ?? '—')}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunApplied}</div>\n <div className={rowValueClass()}>{String(r.deep?.applied ?? '—')}</div>\n </div>\n {s ? (\n <div className=\"sm:col-span-2\">\n <div className=\"mb-2 text-xs font-medium text-fg\">{t.lastRunSkipped}</div>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipKey}</div>\n <div className={rowValueClass()}>{String(s.alreadyPromotedKey)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipRehydrate}</div>\n <div className={rowValueClass()}>{String(s.rehydrateFailed)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipContaminated}</div>\n <div className={rowValueClass()}>{String(s.contaminated)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipHash}</div>\n <div className={rowValueClass()}>{String(s.hashDuplicate)}</div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction lockStatusLabel(\n s: DreamingGatewayStatus['lock'],\n labels: Pick<DreamingSettingsI18n, 'lockValueLocked' | 'lockValueUnlocked'>,\n): { text: string; className: string } {\n if (s.locked) {\n return { text: labels.lockValueLocked, className: 'text-amber-600 dark:text-amber-400' };\n }\n return { text: labels.lockValueUnlocked, className: 'text-emerald-600 dark:text-emerald-400' };\n}\n\nexport function DreamingSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.dreamingSettings;\n\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const { data: cfgData } = useGatewayConfigSwr(hasToken);\n\n const [actionBusy, setActionBusy] = useState<null | 'reset_store' | 'clear_lock'>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionOk, setActionOk] = useState(false);\n const [runBusy, setRunBusy] = useState(false);\n const [runOk, setRunOk] = useState(false);\n const [runError, setRunError] = useState<string | null>(null);\n const [runPhase, setRunPhase] = useState<DreamingPhaseId>('deep');\n const [cfgForm, setCfgForm] = useState<DreamingConfigState | null>(null);\n const [cfgBaseline, setCfgBaseline] = useState<DreamingConfigState | null>(null);\n const [cfgSaving, setCfgSaving] = useState(false);\n const [cfgOk, setCfgOk] = useState(false);\n const [cfgError, setCfgError] = useState<string | null>(null);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [previewItems, setPreviewItems] = useState<DreamingPreviewItem[] | null>(null);\n const [eventsLoading, setEventsLoading] = useState(false);\n const [eventsError, setEventsError] = useState<string | null>(null);\n const [events, setEvents] = useState<DreamingEvent[] | null>(null);\n\n const { data, error, isLoading, mutate } = useSWR(hasToken ? dreamingSwrKey() : null, fetchDreamingStatus, {\n revalidateOnFocus: false,\n });\n\n const lockLabel = useMemo(\n () => (data ? lockStatusLabel(data.lock, t) : null),\n [data, t],\n );\n\n const errorMessages = useMemo(() => {\n const list: string[] = [];\n if (error) list.push(error instanceof Error ? error.message : String(error));\n if (actionError) list.push(actionError);\n if (runError) list.push(runError);\n if (previewError) list.push(previewError);\n if (eventsError) list.push(eventsError);\n if (cfgError) list.push(cfgError);\n return list;\n }, [error, actionError, runError, previewError, eventsError, cfgError]);\n\n const successMessages = useMemo(() => {\n const list: string[] = [];\n if (cfgOk) list.push(t.configSaved);\n if (runOk) list.push(t.runQueued);\n if (actionOk) list.push(t.actionOk);\n return list;\n }, [cfgOk, runOk, actionOk, t]);\n\n const doRefresh = useCallback(async () => {\n setActionOk(false);\n setActionError(null);\n setRunOk(false);\n setRunError(null);\n setCfgOk(false);\n setCfgError(null);\n setPreviewError(null);\n await mutate();\n }, [mutate]);\n\n const loadPreview = useCallback(async () => {\n setPreviewLoading(true);\n setPreviewError(null);\n try {\n const res = await fetchDreamingPreview(20);\n setPreviewItems(res.items ?? []);\n } catch (e) {\n setPreviewError(e instanceof Error ? e.message : String(e));\n } finally {\n setPreviewLoading(false);\n }\n }, []);\n\n const loadEvents = useCallback(async () => {\n setEventsLoading(true);\n setEventsError(null);\n try {\n const result = await fetchDreamingEvents(50);\n setEvents(result);\n } catch (e) {\n setEventsError(e instanceof Error ? e.message : String(e));\n } finally {\n setEventsLoading(false);\n }\n }, []);\n\n const doRunNow = useCallback(async (phase: DreamingPhaseId = 'deep') => {\n setRunBusy(true);\n setRunOk(false);\n setRunError(null);\n try {\n await postDreamingRunNow(phase);\n setRunOk(true);\n await mutate();\n } catch (e) {\n setRunError(e instanceof Error ? e.message : String(e));\n } finally {\n setRunBusy(false);\n }\n }, [mutate]);\n\n const doAction = useCallback(\n async (action: 'reset_store' | 'clear_lock') => {\n setActionBusy(action);\n setActionError(null);\n setActionOk(false);\n try {\n await postDreamingAction(action);\n setActionOk(true);\n await mutate();\n } catch (e) {\n setActionError(e instanceof Error ? e.message : String(e));\n } finally {\n setActionBusy(null);\n }\n },\n [mutate],\n );\n\n const disabled = !hasToken || isLoading || Boolean(actionBusy);\n\n const cfgFromGateway = useMemo(() => {\n const rawCfg = cfgData?.payload?.config;\n return normalizeDreamingFromConfig(rawCfg ?? {});\n }, [cfgData]);\n\n // Hydrate config form when config is loaded/changes.\n useEffect(() => {\n if (!hasToken) return;\n if (!cfgBaseline) {\n setCfgBaseline(cfgFromGateway);\n setCfgForm(cfgFromGateway);\n return;\n }\n // If baseline differs from latest gateway config (e.g. reload), reset.\n const nextJson = JSON.stringify(cfgFromGateway);\n const baseJson = JSON.stringify(cfgBaseline);\n if (nextJson !== baseJson) {\n setCfgBaseline(cfgFromGateway);\n setCfgForm(cfgFromGateway);\n }\n }, [cfgBaseline, cfgFromGateway, hasToken]);\n\n const cfgDirty = useMemo(() => {\n if (!cfgForm || !cfgBaseline) return false;\n return JSON.stringify(cfgForm) !== JSON.stringify(cfgBaseline);\n }, [cfgForm, cfgBaseline]);\n\n const saveConfig = useCallback(async () => {\n if (!cfgForm) return;\n setCfgSaving(true);\n setCfgOk(false);\n setCfgError(null);\n try {\n await patchDreamingConfig(cfgForm);\n setCfgBaseline(cfgForm);\n setCfgOk(true);\n await mutate();\n } catch (e) {\n setCfgError(e instanceof Error ? e.message : String(e));\n } finally {\n setCfgSaving(false);\n }\n }, [cfgForm, mutate]);\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <header className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.subtitle}</p>\n </div>\n <div className=\"flex shrink-0 items-center justify-end gap-2\">\n <select\n className=\"rounded-lg border border-edge bg-surface-panel px-2 py-1.5 text-xs text-fg\"\n value={runPhase}\n onChange={(e) => setRunPhase(e.target.value as DreamingPhaseId)}\n disabled={!hasToken || runBusy}\n >\n <option value=\"light\">Light</option>\n <option value=\"deep\">Deep</option>\n <option value=\"rem\">REM</option>\n </select>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || runBusy}\n onClick={() => void doRunNow(runPhase)}\n title={t.runNowHint}\n >\n {runBusy ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Play className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.runNow}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken}\n onClick={() => void doRefresh()}\n >\n <RefreshCw className=\"mr-2 size-4\" aria-hidden />\n {t.refresh}\n </Button>\n </div>\n </header>\n\n {errorMessages.length > 0 ? (\n <div\n className=\"space-y-1.5 rounded-2xl border border-amber-500/20 bg-amber-500/5 px-4 py-3\"\n role=\"alert\"\n >\n {errorMessages.map((line, i) => (\n <p key={i} className=\"text-sm text-amber-800 dark:text-amber-200/90\">\n {line}\n </p>\n ))}\n </div>\n ) : null}\n {successMessages.length > 0 ? (\n <div\n className=\"space-y-1.5 rounded-2xl border border-emerald-500/20 bg-emerald-500/5 px-4 py-3\"\n role=\"status\"\n >\n {successMessages.map((line, i) => (\n <p key={i} className=\"text-sm text-emerald-800 dark:text-emerald-200/90\">\n {line}\n </p>\n ))}\n </div>\n ) : null}\n\n <div className=\"flex flex-col gap-6\">\n <SettingsFormSection className=\"min-w-0\">\n <SettingsFormSectionHeader\n icon={Settings2}\n title={t.configTitle}\n subtitle={t.configHint}\n trailing={\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || !cfgForm || cfgSaving || !cfgDirty}\n onClick={() => void saveConfig()}\n >\n {cfgSaving ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.saveConfig}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || !cfgForm || cfgSaving || !cfgDirty}\n onClick={() => {\n setCfgOk(false);\n setCfgError(null);\n setCfgForm(cfgBaseline);\n }}\n >\n {t.resetConfig}\n </Button>\n </div>\n }\n />\n\n {cfgForm ? (\n <div className=\"space-y-5\">\n {/* Global settings */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={cfgForm.enabled}\n onChange={(e) => setCfgForm({ ...cfgForm, enabled: e.target.checked })}\n />\n <span>{cfgForm.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configFrequency}</div>\n <input\n className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg placeholder:text-fg-subtle dark:border-edge\"\n value={cfgForm.frequency}\n onChange={(e) => setCfgForm({ ...cfgForm, frequency: e.target.value })}\n placeholder=\"0 3 * * *\"\n />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configTimezone}</div>\n <input\n className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg placeholder:text-fg-subtle dark:border-edge\"\n value={cfgForm.timezone}\n onChange={(e) => setCfgForm({ ...cfgForm, timezone: e.target.value })}\n placeholder=\"Asia/Shanghai\"\n />\n </div>\n </div>\n\n {/* Light Sleep */}\n <Subsection label={t.configPhaseLight}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseLightHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.light.enabled} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, enabled: e.target.checked } })} />\n <span>{cfgForm.light.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.cron} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, cron: e.target.value } })} placeholder=\"0 */6 * * *\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightLookbackDays}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.lookbackDays} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, lookbackDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.limit} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightDedupe}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.dedupeSimilarity} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, dedupeSimilarity: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n\n {/* Deep Sleep */}\n <Subsection label={t.configPhaseDeep}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseDeepHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.deep.enabled} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, enabled: e.target.checked } })} />\n <span>{cfgForm.deep.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.cron} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, cron: e.target.value } })} placeholder=\"0 3 * * *\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMinScore}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.minScore} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, minScore: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMinRecallCount}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.minRecallCount} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, minRecallCount: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.limit} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepHalfLife}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.recencyHalfLifeDays} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, recencyHalfLifeDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMaxAge}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.maxAgeDays} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, maxAgeDays: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n\n {/* REM Sleep */}\n <Subsection label={t.configPhaseRem}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseRemHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.rem.enabled} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, enabled: e.target.checked } })} />\n <span>{cfgForm.rem.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.cron} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, cron: e.target.value } })} placeholder=\"0 5 * * 0\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemLookbackDays}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.lookbackDays} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, lookbackDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.limit} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemMinStrength}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.minPatternStrength} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, minPatternStrength: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.configLoading}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection className=\"min-w-0\">\n <SettingsFormSectionHeader\n icon={Activity}\n title={t.runtimeTitle}\n subtitle={t.runtimeHint}\n trailing={isLoading ? <Loader2 className=\"size-4 shrink-0 animate-spin text-fg-muted\" aria-hidden /> : null}\n />\n\n <div className=\"space-y-6\">\n <Subsection label={t.subsectionSchedule}>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.enabled}</div>\n <div className={rowValueClass()}>{data ? (data.config.enabled ? t.on : t.off) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lock}</div>\n <div className={cn(rowValueClass(), lockLabel?.className)}>{lockLabel ? lockLabel.text : '—'}</div>\n </div>\n <div className={cn(settingsFormSectionClassName(), 'sm:col-span-2')}>\n <div className={rowLabelClass()}>{t.schedule}</div>\n <div className=\"mt-1 break-all font-mono text-sm text-fg\">{data ? data.config.frequency : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.timezone}</div>\n <div className={rowValueClass()}>{data ? data.config.timezone : '—'}</div>\n </div>\n </div>\n </Subsection>\n\n <Subsection label={t.subsectionStore}>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeEntries}</div>\n <div className={rowValueClass()}>{data ? String(data.store.entryCount) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storePromoted}</div>\n <div className={rowValueClass()}>{data ? String(data.store.promotedCount) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeUpdatedAt}</div>\n <div className={rowValueClass()}>{data ? isoShort(data.store.updatedAt) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeLastPromotedAt}</div>\n <div className={rowValueClass()}>{data ? isoShort(data.store.lastPromotedAt) : '—'}</div>\n </div>\n </div>\n </Subsection>\n\n {data?.config?.phases ? (\n <Subsection label={t.subsectionPhases}>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <PhaseStatusCard\n icon={<Sun className=\"size-4 text-amber-500\" />}\n label=\"Light\"\n enabled={data.config.phases.light.enabled}\n cron={data.config.phases.light.cron}\n details={`lookback=${data.config.phases.light.lookbackDays}d, limit=${data.config.phases.light.limit}, dedupe=${data.config.phases.light.dedupeSimilarity}`}\n t={t}\n />\n <PhaseStatusCard\n icon={<Moon className=\"size-4 text-indigo-500\" />}\n label=\"Deep\"\n enabled={data.config.phases.deep.enabled}\n cron={data.config.phases.deep.cron}\n details={`minScore=${data.config.phases.deep.minScore}, recalls≥${data.config.phases.deep.minRecallCount}, limit=${data.config.phases.deep.limit}, halfLife=${data.config.phases.deep.recencyHalfLifeDays}d`}\n t={t}\n />\n <PhaseStatusCard\n icon={<Sparkles className=\"size-4 text-purple-500\" />}\n label=\"REM\"\n enabled={data.config.phases.rem.enabled}\n cron={data.config.phases.rem.cron}\n details={`lookback=${data.config.phases.rem.lookbackDays}d, limit=${data.config.phases.rem.limit}, strength≥${data.config.phases.rem.minPatternStrength}`}\n t={t}\n />\n </div>\n </Subsection>\n ) : null}\n\n <Subsection label={t.subsectionLastRun}>\n <p className=\"mb-2 text-xs text-fg-muted\">{t.lastRunBlockHint}</p>\n {data?.lastRun?.exists ? (\n <div className=\"space-y-3\">\n {data.lastRun.parseError ? (\n <p className=\"text-sm text-amber-600 dark:text-amber-400\" role=\"alert\">\n {t.lastRunParseError}\n {': '}\n {data.lastRun.parseError}\n </p>\n ) : null}\n {data.lastRun.record ? (\n <div className=\"rounded-xl border border-edge-subtle bg-surface-panel/40 p-2 sm:p-3\">\n <LastRunStructuredView t={t} r={data.lastRun.record} />\n </div>\n ) : null}\n {data.lastRun.raw !== undefined && data.lastRun.raw !== null ? (\n <details className=\"group rounded-lg border border-edge-subtle\">\n <summary className=\"cursor-pointer list-none px-3 py-2 text-xs font-medium text-fg-muted marker:hidden [&::-webkit-details-marker]:hidden\">\n <span className=\"underline decoration-edge underline-offset-2 group-open:text-fg\">{t.lastRunRaw}</span>\n </summary>\n <pre className=\"max-h-[12rem] overflow-auto border-t border-edge-subtle p-3 text-xs text-fg-muted\">\n {JSON.stringify(data.lastRun.raw, null, 2)}\n </pre>\n </details>\n ) : null}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.lastRunEmpty}</p>\n )}\n </Subsection>\n\n <PhaseLastRunBlock label={t.subsectionLightLastRun} lastRun={data?.lightLastRun} t={t} />\n <PhaseLastRunBlock label={t.subsectionRemLastRun} lastRun={data?.remLastRun} t={t} />\n </div>\n </SettingsFormSection>\n </div>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={ScanLine}\n title={t.previewTitle}\n subtitle={t.previewHint}\n trailing={\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || previewLoading}\n onClick={() => void loadPreview()}\n >\n {previewLoading ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.previewLoad}\n </Button>\n }\n />\n {previewItems ? (\n previewItems.length > 0 ? (\n <div className=\"space-y-2\">\n {previewItems.map((it) => {\n const src = `${it.path}:${it.startLine}-${it.endLine}`;\n const skipped = it.skippedReason;\n return (\n <div\n key={`${it.key}:${it.hash}:${src}`}\n className=\"rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-3\"\n >\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-fg-muted\">\n <span className=\"font-medium text-fg\">{src}</span>\n <span>score={it.score.toFixed(3)}</span>\n <span>recalls={it.recallCount}</span>\n <span>avg={it.avgScore.toFixed(3)}</span>\n <span>decay={it.recencyDecay?.toFixed(3) ?? '—'}</span>\n {skipped ? (\n <span className=\"text-amber-600 dark:text-amber-400\">{skipped}</span>\n ) : (\n <span className=\"text-emerald-600 dark:text-emerald-400\">{t.previewEligible}</span>\n )}\n </div>\n {it.snippet ? <div className=\"mt-2 text-sm text-fg\">{it.snippet}</div> : null}\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.previewEmpty}</p>\n )\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.previewNotLoaded}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Activity}\n title={t.eventsTitle}\n subtitle={t.eventsHint}\n trailing={\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || eventsLoading}\n onClick={() => void loadEvents()}\n >\n {eventsLoading ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.eventsLoad}\n </Button>\n }\n />\n {events ? (\n events.length > 0 ? (\n <div className=\"space-y-1.5\">\n {events.map((ev, idx) => {\n const phaseIcon = ev.phase === 'light' ? '☀️' : ev.phase === 'rem' ? '✨' : '🌙';\n const metrics = ev.phase === 'light'\n ? `scanned=${ev.scannedEntries ?? 0} new=${ev.newSignals ?? 0} deduped=${ev.deduped ?? 0}`\n : ev.phase === 'rem'\n ? `patterns=${ev.patternsDiscovered ?? 0} analyzed=${ev.entriesAnalyzed ?? 0}`\n : `candidates=${ev.candidates ?? 0} applied=${ev.applied ?? 0}`;\n return (\n <div\n key={`${ev.timestamp}:${ev.phase}:${idx}`}\n className=\"flex flex-wrap items-center gap-x-3 gap-y-1 rounded-lg border border-edge-subtle bg-surface-panel/60 px-3 py-2 text-xs\"\n >\n <span>{phaseIcon}</span>\n <span className=\"font-medium text-fg\">{ev.phase}</span>\n <span className={cn('font-medium', ev.ok ? 'text-emerald-600 dark:text-emerald-400' : 'text-amber-600 dark:text-amber-400')}>\n {ev.ok ? 'OK' : 'FAIL'}\n </span>\n <span className=\"text-fg-muted\">{metrics}</span>\n <span className=\"text-fg-muted\">{formatDurationMs(ev.durationMs)}</span>\n <span className=\"ml-auto text-fg-subtle\">{isoShort(ev.timestamp)}</span>\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.eventsEmpty}</p>\n )\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.eventsNotLoaded}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection className=\"max-w-2xl\">\n <SettingsFormSectionHeader icon={Wrench} title={t.maintenanceTitle} subtitle={t.maintenanceHint} />\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <Button\n variant=\"secondary\"\n disabled={disabled}\n onClick={() => {\n if (!confirm(t.confirmResetStore)) return;\n void doAction('reset_store');\n }}\n >\n {actionBusy === 'reset_store' ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Trash2 className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.resetStore}\n </Button>\n <Button\n variant=\"secondary\"\n disabled={disabled}\n onClick={() => {\n if (!confirm(t.confirmClearLock)) return;\n void doAction('clear_lock');\n }}\n >\n {actionBusy === 'clear_lock' ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Unlock className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.clearLock}\n </Button>\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type { GatewaySettingsState, UpdatePackageChannel } from './gateway-settings.types';\n\nexport type { GatewaySettingsState, UpdatePackageChannel } from './gateway-settings.types';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport function normalizeGatewayFromConfig(config: unknown): GatewaySettingsState {\n const c = isRecord(config) ? config : {};\n const gw = isRecord(c.gateway) ? c.gateway : {};\n const auth = isRecord(gw.auth) ? gw.auth : {};\n const mode = auth.mode === 'none' || auth.mode === 'token' ? auth.mode : 'token';\n const upd = isRecord(c.update) ? c.update : {};\n const ch = upd.channel;\n const updateChannel: UpdatePackageChannel =\n ch === 'beta' || ch === 'dev' || ch === 'stable' ? ch : 'stable';\n return {\n host: typeof gw.host === 'string' ? gw.host : '',\n port: typeof gw.port === 'number' ? gw.port : undefined,\n auth: {\n mode,\n token: typeof auth.token === 'string' ? auth.token : '',\n },\n updateChannel,\n };\n}\n\nexport async function fetchGatewaySettings(): Promise<GatewaySettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeGatewayFromConfig(res.payload?.config ?? {});\n}\n\nexport async function patchGatewaySettings(state: GatewaySettingsState): Promise<void> {\n const token = state.auth.token.trim();\n const auth =\n token.length > 0\n ? { mode: state.auth.mode, token: state.auth.token }\n : { mode: state.auth.mode };\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n gateway: {\n auth,\n },\n update: {\n channel: state.updateChannel,\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { AlertCircle, Check, Copy, ExternalLink, Eye, EyeOff, Loader2, Server, Smartphone } from 'lucide-react';\nimport QRCode from 'qrcode';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n normalizeGatewayFromConfig,\n patchGatewaySettings,\n type GatewaySettingsState,\n} from '@/features/settings/gateway-config-api';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport {\n buildMobileGatewayPairDeepLink,\n getBaseUrl,\n isLoopbackHttpOrigin,\n} from '@/lib/url';\nimport { messages, type GatewaySettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nexport function GatewaySettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const g = m.gatewaySettings;\n const token = useGatewayStore((st) => st.token);\n const tokenExpired = useGatewayStore((st) => st.tokenExpired);\n const openTokenDialog = useGatewayStore((st) => st.openTokenDialog);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<GatewaySettingsState | null>(null);\n const [baseline, setBaseline] = useState<GatewaySettingsState | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const [showAccessToken, setShowAccessToken] = useState(false);\n const [copied, setCopied] = useState(false);\n const dirtyRef = useRef(false);\n\n const { data, error: swrError, isLoading, mutate } = useGatewayConfigSwr(hasToken);\n\n const parsed = useMemo(\n () =>\n data?.payload?.config !== undefined\n ? structuredClone(normalizeGatewayFromConfig(data.payload.config))\n : null,\n [data],\n );\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n dirtyRef.current = false;\n return;\n }\n if (parsed === null) return;\n if (!dirtyRef.current) {\n setForm(parsed);\n setBaseline(structuredClone(parsed));\n setSaveOk(false);\n }\n }, [hasToken, parsed]);\n\n const loading = Boolean(hasToken && isLoading && data === undefined && !swrError);\n const fetchError =\n swrError instanceof Error ? swrError.message : swrError ? String(swrError) : null;\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const updateAuth = useCallback((patch: Partial<GatewaySettingsState['auth']>) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, auth: { ...f.auth, ...patch } } : null));\n }, []);\n\n const updateChannel = useCallback((channel: GatewaySettingsState['updateChannel']) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, updateChannel: channel } : null));\n }, []);\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchGatewaySettings(form);\n dirtyRef.current = false;\n const next = structuredClone(form);\n setBaseline(next);\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : g.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, g.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n dirtyRef.current = false;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n const copyAccessToken = useCallback(async () => {\n const t = form?.auth.token;\n if (!t) return;\n await navigator.clipboard.writeText(t).catch(() => {});\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n }, [form?.auth.token]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.gateway}</h1>\n <p className=\"text-sm text-fg-muted\">{g.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {g.loading}\n </div>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? g.loadError}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\n {g.retry}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.gateway}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{g.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'gateway')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {g.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{g.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {g.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? g.saving : g.save}\n </Button>\n </div>\n </header>\n\n {tokenExpired ? (\n <div\n className=\"flex flex-col gap-3 rounded-lg border border-red-200 bg-red-50 px-4 py-3 dark:border-red-900/50 dark:bg-red-950/40\"\n role=\"alert\"\n >\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0 text-red-600 dark:text-red-400\" />\n <p className=\"text-sm text-red-900 dark:text-red-100\">{g.tokenExpired}</p>\n </div>\n <div>\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={() => openTokenDialog()}>\n {g.updateToken}\n </Button>\n </div>\n </div>\n ) : null}\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{g.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n {form.auth.mode === 'none' ? (\n <p className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\">\n {g.authModeNone}\n </p>\n ) : null}\n\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-5 flex items-center gap-2 text-sm font-semibold text-fg\">\n <Server className=\"size-4 text-accent\" strokeWidth={1.75} />\n {m.settingsSections.gateway}\n </div>\n <div className=\"space-y-4\">\n {(form.host || form.port != null) && (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{g.listenHost}</div>\n <div className=\"rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50\">\n {form.host || '—'}\n </div>\n </div>\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{g.listenPort}</div>\n <div className=\"rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50\">\n {form.port != null ? String(form.port) : '—'}\n </div>\n </div>\n <p className=\"sm:col-span-2 text-xs text-fg-subtle\">{g.listenHint}</p>\n </div>\n )}\n\n <AccessTokenField\n g={g}\n value={form.auth.token}\n show={showAccessToken}\n copied={copied}\n onToggleShow={() => setShowAccessToken((s) => !s)}\n onCopy={() => void copyAccessToken()}\n onChange={(token) => updateAuth({ token })}\n />\n\n <Button type=\"button\" variant=\"secondary\" className=\"w-full sm:w-auto\" onClick={() => openTokenDialog()}>\n {g.changeToken}\n </Button>\n\n {token ? <MobileGatewayPairCard g={g} gatewayToken={token} /> : null}\n\n <div className=\"space-y-2 border-t border-edge pt-4\">\n <label className=\"text-sm font-medium text-fg\" htmlFor=\"gateway-update-channel\">\n {g.updateChannel}\n </label>\n <select\n id=\"gateway-update-channel\"\n value={form.updateChannel}\n onChange={(e) => updateChannel(e.target.value as GatewaySettingsState['updateChannel'])}\n className={inputClassName()}\n >\n <option value=\"stable\">{g.channelStable}</option>\n <option value=\"beta\">{g.channelBeta}</option>\n <option value=\"dev\">{g.channelDev}</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{g.updateChannelHint}</p>\n </div>\n </div>\n </section>\n </div>\n );\n}\n\nfunction MobileGatewayPairCard({\n g,\n gatewayToken,\n}: {\n g: GatewaySettingsMessages;\n gatewayToken: string;\n}) {\n const [pairBaseUrl, setPairBaseUrl] = useState(getBaseUrl);\n const [qrDataUrl, setQrDataUrl] = useState<string | null>(null);\n const [qrGenFailed, setQrGenFailed] = useState(false);\n const [linkCopied, setLinkCopied] = useState(false);\n\n const trimmedBase = pairBaseUrl.trim();\n const baseOk = useMemo(() => {\n try {\n const u = new URL(trimmedBase);\n return u.protocol === 'http:' || u.protocol === 'https:';\n } catch {\n return false;\n }\n }, [trimmedBase]);\n\n const deepLink = useMemo(() => {\n if (!gatewayToken || !baseOk) return '';\n return buildMobileGatewayPairDeepLink({ baseUrl: trimmedBase, gatewayToken });\n }, [baseOk, gatewayToken, trimmedBase]);\n\n useEffect(() => {\n if (!deepLink) {\n setQrDataUrl(null);\n setQrGenFailed(false);\n return;\n }\n let cancelled = false;\n setQrGenFailed(false);\n void QRCode.toDataURL(deepLink, {\n width: 216,\n margin: 2,\n errorCorrectionLevel: 'M',\n color: { dark: '#000000ff', light: '#ffffffff' },\n })\n .then((url) => {\n if (!cancelled) setQrDataUrl(url);\n })\n .catch(() => {\n if (!cancelled) {\n setQrGenFailed(true);\n setQrDataUrl(null);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [deepLink]);\n\n const localhostWarn = baseOk && isLoopbackHttpOrigin(trimmedBase);\n\n const copyDeepLink = useCallback(async () => {\n if (!deepLink) return;\n await navigator.clipboard.writeText(deepLink).catch(() => {});\n setLinkCopied(true);\n window.setTimeout(() => setLinkCopied(false), 2000);\n }, [deepLink]);\n\n return (\n <div className=\"space-y-3 border-t border-edge pt-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Smartphone className=\"size-4 text-accent\" strokeWidth={1.75} />\n {g.mobilePairTitle}\n </div>\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairSubtitle}</p>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-fg\" htmlFor=\"gateway-mobile-pair-base\">\n {g.mobilePairBaseUrlLabel}\n </label>\n <input\n id=\"gateway-mobile-pair-base\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={pairBaseUrl}\n onChange={(e) => setPairBaseUrl(e.target.value)}\n />\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairBaseUrlHint}</p>\n {!baseOk ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{g.mobilePairInvalidBaseUrl}</p> : null}\n {localhostWarn ? (\n <p className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\">\n {g.mobilePairLocalhostWarning}\n </p>\n ) : null}\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairSecurityNote}</p>\n </div>\n\n {deepLink ? (\n <div className=\"flex flex-col items-center gap-3 sm:items-start\">\n {qrDataUrl && !qrGenFailed ? (\n <img\n src={qrDataUrl}\n alt=\"\"\n className=\"h-56 w-56 rounded-lg border border-edge-subtle bg-white object-contain p-3 dark:border-edge\"\n />\n ) : null}\n {!qrDataUrl && !qrGenFailed ? <p className=\"text-sm text-fg-muted\">{g.mobilePairEncoding}</p> : null}\n {qrGenFailed ? <p className=\"text-center text-sm text-fg-muted sm:text-left\">{g.mobilePairImageError}</p> : null}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-full sm:w-auto\"\n disabled={!deepLink}\n onClick={() => void copyDeepLink()}\n >\n {linkCopied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n {linkCopied ? g.mobilePairCopied : g.mobilePairCopyLink}\n </Button>\n </div>\n ) : null}\n\n <p className=\"break-all font-mono text-[10px] leading-relaxed text-fg-subtle\">{g.mobilePairSchemeHint}</p>\n </div>\n );\n}\n\nfunction AccessTokenField({\n g,\n value,\n show,\n copied,\n onToggleShow,\n onCopy,\n onChange,\n}: {\n g: GatewaySettingsMessages;\n value: string;\n show: boolean;\n copied: boolean;\n onToggleShow: () => void;\n onCopy: () => void;\n onChange: (v: string) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"text-sm font-medium text-fg\">{g.accessToken}</div>\n <div className=\"flex flex-wrap gap-2\">\n <input\n className={cn(inputClassName(), 'min-w-0 flex-1 font-mono text-xs')}\n type={show ? 'text' : 'password'}\n autoComplete=\"off\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={g.tokenPlaceholder}\n />\n {value ? (\n <Button type=\"button\" variant=\"secondary\" className=\"px-2 py-1 text-xs\" onClick={onCopy}>\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n {copied ? g.copied : g.copy}\n </Button>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" className=\"px-2 py-1 text-xs\" onClick={onToggleShow}>\n {show ? <EyeOff className=\"size-3.5\" /> : <Eye className=\"size-3.5\" />}\n {show ? g.hide : g.show}\n </Button>\n </div>\n <p className=\"text-xs text-fg-subtle\">{g.tokenHelp}</p>\n </div>\n );\n}\n","import { getChannels } from '@/features/cron/cron-api';\nimport { apiUrl } from '@/lib/url';\n\nexport function channelsStatusSwrKey(): string {\n return apiUrl('/api/channels/status');\n}\n\n/** Same network call as `getChannels`; use with `channelsStatusSwrKey()` for SWR. */\nexport const fetchChannelsStatusSwr = getChannels;\n","import { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport function heartbeatMdSwrKey(): string {\n return apiUrl('/api/workspace/heartbeat-md');\n}\n\nexport async function fetchHeartbeatMdSwr(): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(heartbeatMdSwrKey());\n return typeof res.payload?.content === 'string' ? res.payload.content : '';\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { heartbeatMdSwrKey } from '@/features/settings/heartbeat-md-swr';\nimport { mutate } from 'swr';\n\nimport type { HeartbeatSettingsState } from './heartbeat-settings.types';\n\nexport type { HeartbeatSettingsState } from './heartbeat-settings.types';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport function normalizeHeartbeatFromConfig(config: unknown): HeartbeatSettingsState {\n const c = isRecord(config) ? config : {};\n const gw = isRecord(c.gateway) ? c.gateway : {};\n const hb = isRecord(gw.heartbeat) ? gw.heartbeat : {};\n const ahRaw = hb.activeHours;\n const ah = isRecord(ahRaw) ? ahRaw : null;\n const activeHours =\n ah && typeof ah.start === 'string' && typeof ah.end === 'string' && ah.start && ah.end\n ? {\n start: ah.start,\n end: ah.end,\n timezone: typeof ah.timezone === 'string' ? ah.timezone : '',\n }\n : null;\n return {\n enabled: Boolean(hb.enabled ?? true),\n intervalMs: typeof hb.intervalMs === 'number' && Number.isFinite(hb.intervalMs) ? hb.intervalMs : 1_800_000,\n target: typeof hb.target === 'string' ? hb.target : '',\n targetChatId: typeof hb.targetChatId === 'string' ? hb.targetChatId : '',\n prompt: typeof hb.prompt === 'string' ? hb.prompt : '',\n ackMaxChars:\n typeof hb.ackMaxChars === 'number' && Number.isFinite(hb.ackMaxChars) ? hb.ackMaxChars : '',\n isolatedSession: Boolean(hb.isolatedSession),\n activeHours,\n };\n}\n\nfunction buildHeartbeatPayload(state: HeartbeatSettingsState): Record<string, unknown> {\n const p: Record<string, unknown> = {\n enabled: state.enabled,\n intervalMs: state.intervalMs,\n };\n if (state.target.trim()) p.target = state.target.trim();\n else p.target = null;\n if (state.targetChatId.trim()) p.targetChatId = state.targetChatId.trim();\n else p.targetChatId = null;\n if (state.prompt.trim()) p.prompt = state.prompt.trim();\n else p.prompt = null;\n if (state.ackMaxChars === '' || state.ackMaxChars === undefined) {\n p.ackMaxChars = null;\n } else {\n p.ackMaxChars = state.ackMaxChars;\n }\n if (state.isolatedSession) p.isolatedSession = true;\n else p.isolatedSession = null;\n if (state.activeHours?.start?.trim() && state.activeHours?.end?.trim()) {\n p.activeHours = {\n start: state.activeHours.start.trim(),\n end: state.activeHours.end.trim(),\n ...(state.activeHours.timezone.trim()\n ? { timezone: state.activeHours.timezone.trim() }\n : {}),\n };\n } else {\n p.activeHours = null;\n }\n return p;\n}\n\nexport async function patchHeartbeatSettings(state: HeartbeatSettingsState): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n gateway: {\n heartbeat: buildHeartbeatPayload(state),\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchHeartbeatMd(): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(\n apiUrl('/api/workspace/heartbeat-md'),\n );\n return typeof res.payload?.content === 'string' ? res.payload.content : '';\n}\n\nexport async function putHeartbeatMd(content: string): Promise<void> {\n await fetchJson(apiUrl('/api/workspace/heartbeat-md'), {\n method: 'PUT',\n body: JSON.stringify({ content }),\n });\n void mutate(heartbeatMdSwrKey());\n}\n\n/** Queue one heartbeat run (same path as the interval timer). */\nexport async function triggerHeartbeat(reason?: string): Promise<void> {\n await fetchJson(apiUrl('/api/heartbeat/trigger'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(reason ? { reason } : {}),\n });\n}\n","/** Preset heartbeat intervals (ms). Must match gateway `intervalMs`. */\nexport const HEARTBEAT_INTERVAL_PRESET_MS_ORDER = [\n 30_000,\n 60_000,\n 300_000,\n 600_000,\n 900_000,\n 1_800_000,\n 3_600_000,\n 7_200_000,\n] as const;\n\nexport const HEARTBEAT_INTERVAL_PRESET_MS = new Set<number>(HEARTBEAT_INTERVAL_PRESET_MS_ORDER);\n","import { ExternalLink, Heart, Loader2, Play, RefreshCw } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { getSessionChatIds, type ChannelStatus, type SessionChatId } from '@/features/cron/cron-api';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport { channelsStatusSwrKey, fetchChannelsStatusSwr } from '@/features/settings/channels-status-swr';\nimport {\n normalizeHeartbeatFromConfig,\n patchHeartbeatSettings,\n putHeartbeatMd,\n triggerHeartbeat,\n} from '@/features/settings/heartbeat-config-api';\nimport { fetchHeartbeatMdSwr, heartbeatMdSwrKey } from '@/features/settings/heartbeat-md-swr';\nimport type { HeartbeatSettingsState } from '@/features/settings/heartbeat-settings.types';\nimport { SettingsFormSection } from '@/features/settings/settings-form-section';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type HeartbeatSettingsMessages } from '@/i18n/messages';\nimport {\n HEARTBEAT_INTERVAL_PRESET_MS,\n HEARTBEAT_INTERVAL_PRESET_MS_ORDER,\n} from '@/features/settings/heartbeat-interval-presets';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\ntype CronMessages = ReturnType<typeof messages>['cron'];\n\nfunction workspacePathFromConfig(cfg: unknown): string {\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) return '';\n const agents = (cfg as { agents?: unknown }).agents;\n if (!agents || typeof agents !== 'object' || Array.isArray(agents)) return '';\n const defaults = (agents as { defaults?: unknown }).defaults;\n if (!defaults || typeof defaults !== 'object' || Array.isArray(defaults)) return '';\n const w = (defaults as { workspace?: unknown }).workspace;\n return typeof w === 'string' ? w : '';\n}\n\nfunction intervalPresetLabel(\n ms: number,\n p: HeartbeatSettingsMessages['intervalPresets'],\n): string {\n switch (ms) {\n case 30_000:\n return p.every30s;\n case 60_000:\n return p.every1min;\n case 300_000:\n return p.every5min;\n case 600_000:\n return p.every10min;\n case 900_000:\n return p.every15min;\n case 1_800_000:\n return p.every30min;\n case 3_600_000:\n return p.every1h;\n case 7_200_000:\n return p.every2h;\n default:\n return String(ms);\n }\n}\n\nexport function HeartbeatSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const h = m.heartbeatSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<HeartbeatSettingsState | null>(null);\n const [baseline, setBaseline] = useState<HeartbeatSettingsState | null>(null);\n const [doc, setDoc] = useState<string>('');\n const [docBaseline, setDocBaseline] = useState<string>('');\n const [savingConfig, setSavingConfig] = useState(false);\n const [savingDoc, setSavingDoc] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveConfigOk, setSaveConfigOk] = useState(false);\n const [saveDocOk, setSaveDocOk] = useState(false);\n const [triggerLoading, setTriggerLoading] = useState(false);\n const [triggerOk, setTriggerOk] = useState(false);\n const [triggerError, setTriggerError] = useState<string | null>(null);\n const [sessionChatIds, setSessionChatIds] = useState<SessionChatId[]>([]);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: mdContent,\n error: mdErr,\n isLoading: mdLoading,\n mutate: mutMd,\n } = useSWR(hasToken ? heartbeatMdSwrKey() : null, fetchHeartbeatMdSwr, { revalidateOnFocus: false });\n const { data: channels = [] } = useSWR(hasToken ? channelsStatusSwrKey() : null, fetchChannelsStatusSwr, {\n revalidateOnFocus: false,\n });\n\n const workspacePath = useMemo(\n () => workspacePathFromConfig(cfgData?.payload?.config),\n [cfgData],\n );\n\n const heartbeatParsed = useMemo(\n () => normalizeHeartbeatFromConfig(cfgData?.payload?.config ?? {}),\n [cfgData],\n );\n\n const dirtyConfig = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const dirtyDoc = useMemo(() => doc !== docBaseline, [doc, docBaseline]);\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n return;\n }\n if (cfgData === undefined) return;\n if (!dirtyConfig) {\n const next = structuredClone(heartbeatParsed);\n setForm(next);\n setBaseline(next);\n setSaveConfigOk(false);\n }\n }, [hasToken, cfgData, heartbeatParsed, dirtyConfig]);\n\n useEffect(() => {\n if (!hasToken || mdContent === undefined) return;\n if (!dirtyDoc) {\n setDoc(mdContent);\n setDocBaseline(mdContent);\n setSaveDocOk(false);\n }\n }, [hasToken, mdContent, dirtyDoc]);\n\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : mdErr instanceof Error\n ? mdErr.message\n : mdErr\n ? String(mdErr)\n : null;\n\n const loading = Boolean(\n hasToken &&\n (cfgData === undefined || mdContent === undefined) &&\n !fetchError &&\n (cfgLoading || mdLoading),\n );\n\n useEffect(() => {\n if (!hasToken || !form) {\n setSessionChatIds([]);\n return;\n }\n const t = form.target.trim();\n if (!t) {\n setSessionChatIds([]);\n return;\n }\n let cancelled = false;\n void getSessionChatIds(t).then((ids) => {\n if (!cancelled) setSessionChatIds(ids);\n });\n return () => {\n cancelled = true;\n };\n }, [hasToken, form?.target]);\n\n const refreshSessionChatIds = useCallback(() => {\n const t = form?.target?.trim();\n if (!t) return;\n void getSessionChatIds(t).then(setSessionChatIds);\n }, [form?.target]);\n\n const runHeartbeatNow = useCallback(async () => {\n setTriggerLoading(true);\n setTriggerOk(false);\n setTriggerError(null);\n try {\n await triggerHeartbeat();\n setTriggerOk(true);\n window.setTimeout(() => setTriggerOk(false), 3000);\n } catch (e) {\n setTriggerError(e instanceof Error ? e.message : h.triggerError);\n } finally {\n setTriggerLoading(false);\n }\n }, [h.triggerError]);\n\n const update = useCallback((patch: Partial<HeartbeatSettingsState>) => {\n setForm((f) => (f ? { ...f, ...patch } : null));\n }, []);\n\n const discardConfiguration = useCallback(() => {\n if (!baseline) return;\n setForm(structuredClone(baseline));\n setSaveConfigOk(false);\n setError(null);\n }, [baseline]);\n\n const discardDocument = useCallback(() => {\n setDoc(docBaseline);\n setSaveDocOk(false);\n setError(null);\n }, [docBaseline]);\n\n const saveConfiguration = useCallback(async () => {\n if (!form || savingConfig) return;\n setSavingConfig(true);\n setError(null);\n setSaveConfigOk(false);\n try {\n await patchHeartbeatSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setSaveConfigOk(true);\n window.setTimeout(() => setSaveConfigOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : h.saveConfigError);\n } finally {\n setSavingConfig(false);\n }\n }, [form, savingConfig, h.saveConfigError]);\n\n const saveDocument = useCallback(async () => {\n if (savingDoc) return;\n setSavingDoc(true);\n setError(null);\n setSaveDocOk(false);\n try {\n await putHeartbeatMd(doc);\n setDocBaseline(doc);\n setSaveDocOk(true);\n window.setTimeout(() => setSaveDocOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : h.saveDocError);\n } finally {\n setSavingDoc(false);\n }\n }, [doc, savingDoc, h.saveDocError]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.heartbeat}</h1>\n <p className=\"text-sm text-fg-muted\">{h.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {h.loading}\n </div>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? h.loadError}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutMd();\n }}\n >\n {h.retry}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.heartbeat}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{h.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'heartbeat')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {h.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n </header>\n\n {workspacePath ? (\n <p className=\"text-xs text-fg-subtle\">\n {h.workspaceLabel}: <span className=\"font-mono text-fg-muted\">{workspacePath}</span>\n </p>\n ) : null}\n\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <SettingsFormSection>\n <div className=\"mb-2 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Heart className=\"size-4 text-accent\" strokeWidth={1.75} />\n {h.configSection}\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex items-center gap-2\"\n disabled={triggerLoading}\n onClick={() => void runHeartbeatNow()}\n >\n {triggerLoading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Play className=\"size-4\" strokeWidth={1.75} aria-hidden />\n )}\n {triggerLoading ? h.triggering : h.triggerNow}\n </Button>\n {triggerOk ? <span className=\"text-sm text-fg-muted\">{h.triggered}</span> : null}\n </div>\n </div>\n <p className=\"mb-4 text-xs text-fg-subtle\">{h.triggerHint}</p>\n {triggerError ? <p className=\"mb-3 text-sm text-red-600 dark:text-red-400\">{triggerError}</p> : null}\n <HeartbeatConfigFields\n h={h}\n cron={m.cron}\n form={form}\n channels={channels}\n sessionChatIds={sessionChatIds}\n onRefreshChatIds={refreshSessionChatIds}\n update={update}\n inputClassName={inputClassName}\n selectClassName={selectClassName}\n />\n <div className=\"mt-4 flex flex-wrap items-center gap-2\">\n {saveConfigOk ? <span className=\"text-sm text-fg-muted\">{h.savedConfig}</span> : null}\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={!dirtyConfig || savingConfig}\n onClick={discardConfiguration}\n >\n {h.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={!dirtyConfig || savingConfig}\n onClick={() => void saveConfiguration()}\n >\n {savingConfig ? h.savingConfig : h.saveConfig}\n </Button>\n {dirtyConfig ? <span className=\"text-xs text-amber-800 dark:text-amber-200\">{h.unsavedConfig}</span> : null}\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <div className=\"mb-2 text-sm font-semibold text-fg\">{h.docSection}</div>\n <p className=\"mb-3 text-xs text-fg-subtle\">{h.docHint}</p>\n <textarea\n className={cn(inputClassName(), 'min-h-[12rem] resize-y font-mono text-xs leading-relaxed')}\n value={doc}\n onChange={(e) => setDoc(e.target.value)}\n spellCheck={false}\n aria-label={h.docSection}\n />\n <div className=\"mt-4 flex flex-wrap items-center gap-2\">\n {saveDocOk ? <span className=\"text-sm text-fg-muted\">{h.savedDoc}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirtyDoc || savingDoc} onClick={discardDocument}>\n {h.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={!dirtyDoc || savingDoc}\n onClick={() => void saveDocument()}\n >\n {savingDoc ? h.savingDoc : h.saveDoc}\n </Button>\n {dirtyDoc ? <span className=\"text-xs text-amber-800 dark:text-amber-200\">{h.unsavedDoc}</span> : null}\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n\nfunction HeartbeatConfigFields({\n h,\n cron: c,\n form,\n channels,\n sessionChatIds,\n onRefreshChatIds,\n update,\n inputClassName: inputCn,\n selectClassName: selectCn,\n}: {\n h: HeartbeatSettingsMessages;\n cron: CronMessages;\n form: HeartbeatSettingsState;\n channels: ChannelStatus[];\n sessionChatIds: SessionChatId[];\n onRefreshChatIds: () => void;\n update: (patch: Partial<HeartbeatSettingsState>) => void;\n inputClassName: typeof inputClassName;\n selectClassName: typeof selectClassName;\n}) {\n const channelNames = useMemo(() => new Set(channels.map((x) => x.name)), [channels]);\n const targetTrim = form.target.trim();\n const showCustomChannel = Boolean(targetTrim && !channelNames.has(targetTrim));\n\n const intervalPresetSelectValue = useMemo(\n () => (HEARTBEAT_INTERVAL_PRESET_MS.has(form.intervalMs) ? String(form.intervalMs) : ''),\n [form.intervalMs],\n );\n\n const [intervalSecondsDraft, setIntervalSecondsDraft] = useState<string | null>(null);\n const intervalSecondsCommitted = Math.max(1, Math.round(form.intervalMs / 1000));\n const intervalSecondsInputValue =\n intervalSecondsDraft !== null ? intervalSecondsDraft : String(intervalSecondsCommitted);\n\n useEffect(() => {\n setIntervalSecondsDraft(null);\n }, [form.intervalMs]);\n\n return (\n <div className=\"space-y-4\">\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={form.enabled}\n onChange={(e) => update({ enabled: e.target.checked })}\n />\n {h.enable}\n </label>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"text-sm font-medium text-fg\">{h.interval}</div>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{h.intervalSecondsLabel}</span>\n <div className=\"flex gap-2\">\n <input\n type=\"number\"\n min={1}\n step={1}\n className={cn(inputCn(), 'min-w-0 flex-1')}\n value={intervalSecondsInputValue}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalSecondsDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1) {\n update({ intervalMs: raw * 1000 });\n }\n }}\n onBlur={() => {\n if (intervalSecondsDraft === null) return;\n const raw = parseInt(intervalSecondsDraft, 10);\n if (!Number.isFinite(raw) || raw < 1) {\n update({ intervalMs: 1000 });\n } else {\n update({ intervalMs: raw * 1000 });\n }\n setIntervalSecondsDraft(null);\n }}\n />\n <select\n className={cn(selectCn(), 'max-w-[11rem] shrink-0 text-xs')}\n value={intervalPresetSelectValue}\n onChange={(e) => {\n const v = e.target.value;\n if (v) {\n update({ intervalMs: parseInt(v, 10) });\n setIntervalSecondsDraft(null);\n }\n }}\n >\n <option value=\"\">{h.intervalPresets.custom}</option>\n {HEARTBEAT_INTERVAL_PRESET_MS_ORDER.map((ms) => (\n <option key={ms} value={String(ms)}>\n {intervalPresetLabel(ms, h.intervalPresets)}\n </option>\n ))}\n </select>\n </div>\n </div>\n <p className=\"text-xs text-fg-muted\">{h.intervalHintPreset}</p>\n <p className=\"text-xs text-fg-subtle\">{h.intervalHint}</p>\n </div>\n\n <div className=\"border-t border-edge-subtle pt-4\">\n <div className=\"mb-2 text-sm font-medium text-fg\">{h.deliveryTitle}</div>\n\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.channel}</span>\n <select\n className={selectCn()}\n value={targetTrim}\n onChange={(e) => {\n const v = e.target.value.trim();\n update({ target: v, targetChatId: '' });\n }}\n >\n <option value=\"\">{h.channelNone}</option>\n {showCustomChannel ? (\n <option value={targetTrim}>\n {targetTrim} ({h.customChannelSuffix})\n </option>\n ) : null}\n {channels.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? '(disabled)' : ''}\n </option>\n ))}\n </select>\n </label>\n\n {targetTrim ? (\n <div className=\"mt-3 flex flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.recipient}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n title={c.refreshRecipientHint}\n onClick={onRefreshChatIds}\n >\n <RefreshCw className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {c.refreshList}\n </Button>\n </div>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n className={cn(inputCn(), 'min-w-0 flex-1')}\n value={form.targetChatId}\n onChange={(e) => update({ targetChatId: e.target.value })}\n placeholder={c.recipientPlaceholder}\n autoComplete=\"off\"\n />\n <select\n className={cn(selectCn(), 'max-w-[10rem] shrink-0 text-xs')}\n value={form.targetChatId}\n onChange={(e) => {\n const v = e.target.value;\n if (v) update({ targetChatId: v });\n }}\n >\n <option value=\"\">{c.selectRecipient}</option>\n {sessionChatIds.length > 0 ? (\n sessionChatIds.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, c.lastActiveLabels)}\n </option>\n ))\n ) : (\n <option value=\"\" disabled>\n {c.noRecentChatsOption}\n </option>\n )}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">\n {sessionChatIds.length > 0 ? c.enterManuallyOrSelect : c.noRecentChats}\n </p>\n </div>\n ) : null}\n\n <p className=\"mt-2 text-xs text-fg-subtle\">{h.deliveryHint}</p>\n </div>\n\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{h.prompt}</div>\n <textarea\n className={cn(inputCn(), 'min-h-[4.5rem] resize-y font-mono text-xs')}\n value={form.prompt}\n onChange={(e) => update({ prompt: e.target.value })}\n placeholder={h.promptPlaceholder}\n />\n <p className=\"mt-1 text-xs text-fg-subtle\">{h.promptHint}</p>\n </div>\n\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{h.ackMaxChars}</div>\n <input\n type=\"number\"\n min={1}\n className={inputCn()}\n value={form.ackMaxChars === '' ? '' : form.ackMaxChars}\n onChange={(e) => {\n const v = e.target.value;\n if (v === '') update({ ackMaxChars: '' });\n else {\n const n = parseInt(v, 10);\n update({ ackMaxChars: Number.isFinite(n) ? n : '' });\n }\n }}\n placeholder={h.ackDefaultPlaceholder}\n />\n <p className=\"mt-1 text-xs text-fg-subtle\">{h.ackMaxCharsHint}</p>\n </div>\n\n <label className=\"flex cursor-pointer items-start gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox mt-0.5\"\n checked={form.isolatedSession}\n onChange={(e) => update({ isolatedSession: e.target.checked })}\n />\n <span>\n {h.isolatedSession}\n <span className=\"mt-1 block text-xs text-fg-subtle\">{h.isolatedSessionHint}</span>\n </span>\n </label>\n\n <div className=\"border-t border-edge-subtle pt-4\">\n <div className=\"mb-2 text-sm font-medium text-fg\">{h.activeHoursTitle}</div>\n {form.activeHours ? (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeStart}</div>\n <input\n className={inputCn()}\n value={form.activeHours.start}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, start: e.target.value },\n })\n }\n placeholder=\"09:00\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeEnd}</div>\n <input\n className={inputCn()}\n value={form.activeHours.end}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, end: e.target.value },\n })\n }\n placeholder=\"22:00\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeTimezone}</div>\n <input\n className={inputCn()}\n value={form.activeHours.timezone}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, timezone: e.target.value },\n })\n }\n placeholder=\"Asia/Shanghai\"\n />\n </div>\n </div>\n ) : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-sm\"\n onClick={() =>\n update({\n activeHours: { start: '09:00', end: '22:00', timezone: '' },\n })\n }\n >\n {h.addActiveHours}\n </Button>\n )}\n {form.activeHours ? (\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-xs\"\n onClick={() => update({ activeHours: null })}\n >\n {h.clearActiveHours}\n </Button>\n </div>\n ) : null}\n <p className=\"mt-2 text-xs text-fg-subtle\">{h.activeHoursHint}</p>\n </div>\n </div>\n );\n}\n","import * as Popover from '@radix-ui/react-popover';\nimport { Check, ChevronsUpDown } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport {\n comboboxTriggerLayoutClass,\n formControlBorderFocusClass,\n selectComboboxTriggerFocusClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { apiFetch } from '@/lib/fetch';\nimport { interaction } from '@/lib/interaction';\nimport { apiUrl } from '@/lib/url';\n\nexport type ImageProviderSummary = {\n id: string;\n defaultModel?: string;\n models: string[];\n /** From gateway: provider has resolvable API credentials. */\n configured?: boolean;\n};\n\nasync function fetchImageGenerationProviders(): Promise<ImageProviderSummary[]> {\n const res = await apiFetch(apiUrl('/api/image/providers'));\n if (!res.ok) throw new Error(`Image providers: HTTP ${res.status}`);\n const data = (await res.json()) as { payload?: { providers?: ImageProviderSummary[] } };\n return data.payload?.providers ?? [];\n}\n\nfunction modelIdsForProviders(providerList: ImageProviderSummary[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const p of providerList) {\n const models = p.models.length > 0 ? p.models : p.defaultModel ? [p.defaultModel] : [];\n for (const m of models) {\n const id = `${p.id}/${m}`;\n if (!seen.has(id)) {\n seen.add(id);\n out.push(id);\n }\n }\n }\n return out;\n}\n\n/** Only image-generation providers the gateway marks as configured (credentials available). */\nfunction buildConfiguredModelIds(providers: ImageProviderSummary[], currentValueTrimmed: string): string[] {\n const configuredOnly = providers.filter((p) => p.configured === true);\n const fromRegistry = modelIdsForProviders(configuredOnly);\n if (!currentValueTrimmed || fromRegistry.includes(currentValueTrimmed)) {\n return fromRegistry;\n }\n return [currentValueTrimmed, ...fromRegistry];\n}\n\nfunction idsMatchingQuery(ids: string[], query: string): string[] {\n const raw = query.trim().toLowerCase();\n if (!raw) return ids;\n const tokens = raw.split(/[/\\s]+/).filter(Boolean);\n return ids.filter((h) => {\n const lower = h.toLowerCase();\n return tokens.every((t) => lower.includes(t));\n });\n}\n\nconst SWR_KEY = 'image-generation-providers';\n\n/**\n * Dropdown only: choose a registered `provider/model` from the gateway. Search runs inside\n * the popover; the trigger is not a text field (no free-text model strings).\n */\nexport function ImageGenerationModelInput({\n value,\n disabled,\n placeholder,\n searchPlaceholder,\n noMatches,\n registryEmptyHint,\n outOfFilterNote,\n className,\n onChange,\n}: {\n value: string;\n disabled?: boolean;\n placeholder: string;\n searchPlaceholder: string;\n noMatches: string;\n /** When every provider is unconfigured and there is no current value. */\n registryEmptyHint?: string;\n /** Current value uses a provider that is not configured (still listed so you can change it). */\n outOfFilterNote?: string;\n className?: string;\n onChange: (modelId: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const { data: providers, isLoading, error } = useSWR(SWR_KEY, fetchImageGenerationProviders, {\n revalidateOnFocus: false,\n });\n\n const valueTrimmed = value.trim();\n const configuredOnlyIds = useMemo(\n () => modelIdsForProviders((providers ?? []).filter((p) => p.configured === true)),\n [providers],\n );\n const allIds = useMemo(\n () => buildConfiguredModelIds(providers ?? [], valueTrimmed),\n [providers, valueTrimmed],\n );\n const filtered = useMemo(() => idsMatchingQuery(allIds, query), [allIds, query]);\n const showOutOfFilterNote =\n Boolean(outOfFilterNote) &&\n Boolean(valueTrimmed) &&\n !configuredOnlyIds.includes(valueTrimmed);\n\n const label = value.trim() ? value : placeholder;\n const titleText = value.trim() || placeholder;\n\n const handleOpenChange = useCallback(\n (next: boolean) => {\n setOpen(next);\n if (!next) {\n setQuery('');\n }\n },\n [],\n );\n\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <Popover.Root open={open} onOpenChange={handleOpenChange} modal={false}>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n disabled={disabled || isLoading}\n title={isLoading ? '…' : titleText}\n className={cn(\n comboboxTriggerLayoutClass,\n 'items-center gap-2 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-2 text-left text-sm font-normal text-fg',\n interaction.transition,\n 'hover:border-edge hover:bg-surface-hover/45',\n selectComboboxTriggerFocusClass,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'dark:border-edge-subtle dark:hover:bg-surface-hover/55',\n className,\n )}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"min-w-0 truncate\">{isLoading ? '…' : label}</span>\n <ChevronsUpDown className=\"h-4 w-4 shrink-0 text-fg-subtle opacity-70\" aria-hidden />\n </button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n className=\"z-50 w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-edge-subtle bg-surface-panel p-1 shadow-elevated dark:border-edge-subtle\"\n side=\"bottom\"\n sideOffset={4}\n align=\"end\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <input\n type=\"search\"\n className={cn(\n 'mb-1 w-full rounded-lg border border-edge-subtle bg-surface-base px-2.5 py-1.5 text-sm text-fg placeholder:text-fg-disabled dark:bg-surface-hover/40',\n formControlBorderFocusClass,\n )}\n placeholder={searchPlaceholder}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => e.stopPropagation()}\n />\n <div className=\"max-h-60 overflow-auto\" role=\"listbox\" aria-label={searchPlaceholder}>\n {error ? (\n <div className=\"px-2 py-2 text-xs text-red-600 dark:text-red-400\">\n {error instanceof Error ? error.message : 'Failed to load image providers'}\n </div>\n ) : null}\n {!error && allIds.length === 0 && !isLoading ? (\n <div className=\"px-2 py-3 text-center text-xs text-fg-muted\">\n {registryEmptyHint ?? noMatches}\n </div>\n ) : null}\n {!error && allIds.length > 0 && filtered.length === 0 ? (\n <div className=\"px-2 py-3 text-center text-xs text-fg-muted\">{noMatches}</div>\n ) : null}\n {filtered.map((id) => (\n <button\n key={id}\n type=\"button\"\n role=\"option\"\n aria-selected={id === value}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-fg hover:bg-surface-hover',\n id === value && 'bg-surface-hover/90 font-medium dark:bg-surface-hover/70',\n )}\n onClick={() => {\n onChange(id);\n setOpen(false);\n setQuery('');\n }}\n >\n <Check className={cn('h-4 w-4 shrink-0', id !== value && 'invisible')} aria-hidden />\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">{id}</span>\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n {showOutOfFilterNote ? (\n <p className=\"text-xs text-amber-700 dark:text-amber-400/90\">{outOfFilterNote}</p>\n ) : null}\n </div>\n );\n}\n","import { Image as ImageIcon, Plus, Trash2 } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\n\nimport { AgentDefaultsField } from '../agent-defaults-field';\nimport type { AgentDefaultsPanelProps } from '../agent-defaults-panel-props';\nimport { ImageGenerationModelInput } from '../image-generation-model-input';\n\n/** Vision + image-generation defaults (`agents.defaults.*`) — lives on the Image generation settings page. */\nexport function AgentDefaultsImageModelChainsSection(props: AgentDefaultsPanelProps) {\n const { a, chat, form, update } = props;\n\n return (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={ImageIcon} title={a.cardModelsTitle} subtitle={a.cardModelsSubtitle} />\n <div className=\"mt-4 flex flex-col gap-5\">\n <AgentDefaultsField label={a.label.imageModel} description={a.desc.imageModel}>\n <ModelSelector\n value={form.imageModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n capabilitiesFilter=\"vision\"\n registryEmptyHint={a.visionRegistryEmpty}\n outOfFilterNote={a.visionOutOfFilterNote}\n onChange={(modelId) => update({ imageModel: modelId })}\n />\n </AgentDefaultsField>\n <AgentDefaultsField label={a.label.imageModelFallbacks} description={a.desc.imageModelFallbacks}>\n <div className=\"flex flex-col gap-2\">\n {form.imageModelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ModelSelector\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n capabilitiesFilter=\"vision\"\n registryEmptyHint={a.visionRegistryEmpty}\n outOfFilterNote={a.visionOutOfFilterNote}\n onChange={(modelId) => {\n const next = [...form.imageModelFallbacks];\n next[idx] = modelId;\n update({ imageModelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n imageModelFallbacks: form.imageModelFallbacks.filter((_, j) => j !== idx),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() => update({ imageModelFallbacks: [...form.imageModelFallbacks, ''] })}\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </AgentDefaultsField>\n <AgentDefaultsField label={a.label.imageGenerationModel} description={a.desc.imageGenerationModel}>\n <ImageGenerationModelInput\n value={form.imageGenerationModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n registryEmptyHint={a.imageGenRegistryEmpty}\n outOfFilterNote={a.imageGenOutOfFilterNote}\n onChange={(modelId) => update({ imageGenerationModel: modelId })}\n />\n </AgentDefaultsField>\n <AgentDefaultsField\n label={a.label.imageGenerationModelFallbacks}\n description={a.desc.imageGenerationModelFallbacks}\n >\n <div className=\"flex flex-col gap-2\">\n {form.imageGenerationModelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ImageGenerationModelInput\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n registryEmptyHint={a.imageGenRegistryEmpty}\n outOfFilterNote={a.imageGenOutOfFilterNote}\n onChange={(modelId) => {\n const next = [...form.imageGenerationModelFallbacks];\n next[idx] = modelId;\n update({ imageGenerationModelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n imageGenerationModelFallbacks: form.imageGenerationModelFallbacks.filter(\n (_, j) => j !== idx,\n ),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() =>\n update({ imageGenerationModelFallbacks: [...form.imageGenerationModelFallbacks, ''] })\n }\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </AgentDefaultsField>\n </div>\n </SettingsFormSection>\n );\n}\n","import { Image as ImageIcon, Loader2, RefreshCw, Save, Server } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport { AgentDefaultsImageModelChainsSection } from '@/features/settings/agents/agent-defaults-panels/image-model-chains-section';\nimport {\n fetchAgentDefaults,\n parseParamsJsonForSave,\n patchAgentDefaults,\n type AgentDefaultsState,\n} from '@/features/settings/config-api';\nimport {\n SettingsFormSection,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\ninterface ImageGenProviderSummary {\n id: string;\n label?: string;\n defaultModel?: string;\n models: string[];\n aliases?: string[];\n configured?: boolean;\n capabilities?: unknown;\n}\n\nfunction inputClass(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n );\n}\n\nconst PROVIDERS_SWR_KEY = '/api/image/providers';\n\nfunction pickImageDefaultsSlice(s: AgentDefaultsState) {\n return {\n imageModel: s.imageModel,\n imageModelFallbacks: s.imageModelFallbacks,\n imageGenerationModel: s.imageGenerationModel,\n imageGenerationModelFallbacks: s.imageGenerationModelFallbacks,\n imageGenerationModelTimeoutMs: s.imageGenerationModelTimeoutMs,\n imageGenerationModelAutoProviderFallback: s.imageGenerationModelAutoProviderFallback,\n };\n}\n\nasync function fetchImageProviders(): Promise<ImageGenProviderSummary[]> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { providers?: ImageGenProviderSummary[] };\n }>(apiUrl(PROVIDERS_SWR_KEY));\n return res?.payload?.providers ?? [];\n}\n\nexport function ImageModelsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.imageModelsSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n // Load + persist agent defaults (image-generation knobs).\n const [state, setState] = useState<AgentDefaultsState | null>(null);\n const [baseline, setBaseline] = useState<AgentDefaultsState | null>(null);\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [savedFlash, setSavedFlash] = useState(false);\n const [error, setError] = useState<string | undefined>(undefined);\n\n const reload = useCallback(async () => {\n if (!hasToken) return;\n setLoading(true);\n setError(undefined);\n try {\n const fresh = await fetchAgentDefaults();\n const snapshot = structuredClone(fresh);\n setState(snapshot);\n setBaseline(structuredClone(snapshot));\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n }, [hasToken]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n const patchAgentDefaultsLocal = useCallback((patch: Partial<AgentDefaultsState>) => {\n setState((s) => (s ? { ...s, ...patch } : null));\n }, []);\n\n // Provider catalogue (from /api/image/providers).\n const { data: providers = [], mutate: refreshProviders } = useSWR<ImageGenProviderSummary[]>(\n hasToken ? PROVIDERS_SWR_KEY : null,\n fetchImageProviders,\n { revalidateOnFocus: false },\n );\n\n // Tie config-payload SWR cache so other panels see our edits after save.\n const gwSwr = useGatewayConfigSwr(hasToken);\n\n const dirty = useMemo(() => {\n if (!state || !baseline) return false;\n return (\n JSON.stringify(pickImageDefaultsSlice(state)) !== JSON.stringify(pickImageDefaultsSlice(baseline))\n );\n }, [state, baseline]);\n\n const onSave = useCallback(async () => {\n if (!state) return;\n setSaving(true);\n setError(undefined);\n try {\n try {\n void parseParamsJsonForSave(state.paramsJson);\n } catch (e) {\n setError(\n e instanceof SyntaxError\n ? m.agentSettings.advanced.paramsInvalidJson\n : e instanceof Error\n ? e.message\n : m.agentSettings.advanced.paramsInvalidJson,\n );\n return;\n }\n await patchAgentDefaults(state);\n setBaseline(structuredClone(state));\n setSavedFlash(true);\n window.setTimeout(() => setSavedFlash(false), 1500);\n // Refresh shared SWR cache so models / agent defaults panels stay in sync.\n void gwSwr.mutate?.();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setSaving(false);\n }\n }, [state, gwSwr, m.agentSettings]);\n\n const onDiscard = useCallback(() => {\n if (!baseline) return;\n setState(structuredClone(baseline));\n setError(undefined);\n setSavedFlash(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-8 text-sm text-fg-muted\">\n {language === 'zh' ? '请先登录网关。' : 'Connect to a gateway to continue.'}\n </div>\n );\n }\n\n if (loading || !state) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main items-center gap-2 px-4 py-8 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" /> Loading…\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{t.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.subtitle}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n void reload();\n void refreshProviders();\n }}\n >\n <RefreshCw className=\"size-3.5\" />\n <span className=\"ml-1.5\">{t.refresh}</span>\n </Button>\n {savedFlash ? <span className=\"text-sm text-fg-muted\">{t.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" onClick={onDiscard} disabled={!dirty || saving}>\n {t.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={() => void onSave()} disabled={!dirty || saving}>\n {saving ? <Loader2 className=\"size-3.5 animate-spin\" /> : <Save className=\"size-3.5\" />}\n <span className=\"ml-1.5\">{saving ? t.saving : t.save}</span>\n </Button>\n </div>\n </header>\n\n {error ? (\n <div className=\"rounded-lg border border-red-500/30 bg-red-500/10 px-3 py-2 text-sm text-red-700 dark:text-red-300\">\n {error}\n </div>\n ) : null}\n\n <AgentDefaultsImageModelChainsSection\n form={state}\n update={patchAgentDefaultsLocal}\n a={m.agentSettings}\n chat={m.chat}\n />\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={ImageIcon} title={t.title} subtitle={t.subtitle} />\n <div className=\"flex flex-col gap-4\">\n <div className=\"rounded-lg border border-edge-subtle bg-surface-base px-3 py-2.5 text-xs leading-relaxed text-fg-muted\">\n {t.crossLinkHint}\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <label className=\"text-sm font-medium text-fg\">{t.timeoutLabel}</label>\n <input\n type=\"number\"\n min={0}\n step={1000}\n className={cn(inputClass(), 'max-w-[12rem]')}\n value={state.imageGenerationModelTimeoutMs ?? ''}\n placeholder=\"120000\"\n onChange={(e) => {\n const raw = e.target.value.trim();\n const next = raw === '' ? null : Math.max(0, Math.floor(Number(raw)));\n setState((prev) =>\n prev\n ? {\n ...prev,\n imageGenerationModelTimeoutMs: next && next > 0 ? next : null,\n }\n : null,\n );\n }}\n />\n <p className=\"text-xs text-fg-subtle\">{t.timeoutHint}</p>\n </div>\n <label className=\"flex items-start gap-3 text-sm\">\n <input\n type=\"checkbox\"\n className=\"mt-0.5\"\n checked={state.imageGenerationModelAutoProviderFallback}\n onChange={(e) =>\n setState((prev) =>\n prev\n ? { ...prev, imageGenerationModelAutoProviderFallback: e.target.checked }\n : null,\n )\n }\n />\n <span className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium text-fg\">{t.autoFallbackLabel}</span>\n <span className=\"text-xs text-fg-subtle\">{t.autoFallbackHint}</span>\n </span>\n </label>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Server} title={t.providersTitle} subtitle=\"\" />\n {providers.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{t.providersEmpty}</p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {providers.map((p) => (\n <div\n key={p.id}\n className=\"rounded-lg border border-edge bg-surface-panel px-4 py-3\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{p.label ?? p.id}</span>\n <span className=\"text-xs text-fg-subtle\">({p.id})</span>\n </div>\n {p.configured ? (\n <span className=\"rounded-full bg-accent-soft px-2 py-0.5 text-xs font-medium text-accent-fg\">\n {t.configured}\n </span>\n ) : (\n <span className=\"rounded-full border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-xs font-medium text-amber-700 dark:text-amber-300\">\n {t.missingKey}\n </span>\n )}\n </div>\n {p.defaultModel ? (\n <p className=\"mt-1 text-xs text-fg-subtle\">\n <span className=\"text-fg-muted\">{t.defaultModel}:</span> {p.id}/{p.defaultModel}\n </p>\n ) : null}\n {p.models.length > 0 ? (\n <p className=\"mt-0.5 text-xs text-fg-subtle\">\n <span className=\"text-fg-muted\">{t.modelsLabel}:</span>{' '}\n {p.models.map((mm) => `${p.id}/${mm}`).join(', ')}\n </p>\n ) : null}\n </div>\n ))}\n </div>\n )}\n </SettingsFormSection>\n </div>\n );\n}\n","import { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type {\n ApiType,\n CustomModel,\n ModelsJsonConfig,\n ProviderConfig,\n ValidationResult,\n} from './models-json.types';\n\nexport type {\n ApiType,\n CustomModel,\n ModelsJsonConfig,\n ProviderConfig,\n ValidationResult,\n} from './models-json.types';\n\nexport interface ModelsJsonStatus {\n config: ModelsJsonConfig;\n path: string;\n exists: boolean;\n loadError?: string;\n}\n\nexport interface ApiKeyTestResult {\n type: 'literal' | 'env' | 'command';\n resolved?: string;\n error?: string;\n}\n\nexport const API_TYPE_OPTIONS: { value: ApiType; label: string }[] = [\n { value: 'openai-completions', label: 'OpenAI Completions' },\n { value: 'openai-responses', label: 'OpenAI Responses' },\n { value: 'anthropic-messages', label: 'Anthropic Messages' },\n { value: 'google-generative-ai', label: 'Google Generative AI' },\n { value: 'azure-openai-responses', label: 'Azure OpenAI' },\n { value: 'bedrock-converse-stream', label: 'AWS Bedrock' },\n { value: 'openai-codex-responses', label: 'OpenAI Codex' },\n { value: 'google-gemini-cli', label: 'Google Gemini CLI' },\n { value: 'google-vertex', label: 'Google Vertex AI' },\n];\n\nfunction gatewayErrorMessage(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') return undefined;\n const o = body as { error?: unknown };\n if (typeof o.error === 'string') return o.error;\n if (o.error && typeof o.error === 'object' && 'message' in o.error) {\n const m = (o.error as { message?: unknown }).message;\n return typeof m === 'string' ? m : undefined;\n }\n return undefined;\n}\n\n/** Ensures `providers` exists when the gateway returns a partial object. */\nexport function normalizeModelsJsonConfig(input: unknown): ModelsJsonConfig {\n if (!input || typeof input !== 'object') {\n return { providers: {} };\n }\n const o = input as Record<string, unknown>;\n const raw = o.providers;\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n return input as ModelsJsonConfig;\n }\n return { ...o, providers: {} };\n}\n\nexport async function fetchModelsJson(): Promise<ModelsJsonStatus> {\n const res = await apiFetch(apiUrl('/api/models-json'));\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ModelsJsonStatus;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return {\n ...data.payload,\n config: normalizeModelsJsonConfig(data.payload.config),\n };\n}\n\nexport async function validateModelsJson(config: ModelsJsonConfig): Promise<ValidationResult> {\n const res = await apiFetch(apiUrl('/api/models-json/validate'), {\n method: 'POST',\n body: JSON.stringify({ config }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ValidationResult;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function saveModelsJson(\n config: ModelsJsonConfig,\n): Promise<{ saved: boolean; modelCount: number }> {\n const res = await apiFetch(apiUrl('/api/models-json'), {\n method: 'PATCH',\n body: JSON.stringify({ config }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: { saved: boolean; modelCount: number };\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function reloadModelsJson(): Promise<{ modelCount: number; error?: string }> {\n const res = await apiFetch(apiUrl('/api/models-json/reload'), { method: 'POST' });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: { modelCount: number; error?: string };\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function testApiKey(value: string): Promise<ApiKeyTestResult> {\n const res = await apiFetch(apiUrl('/api/models-json/test-api-key'), {\n method: 'POST',\n body: JSON.stringify({ value }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ApiKeyTestResult;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport function createCustomProvider(\n baseUrl: string,\n apiKey: string,\n api: ApiType = 'openai-completions',\n): ProviderConfig {\n return {\n baseUrl,\n apiKey,\n api,\n models: [],\n };\n}\n\nexport function createCustomModel(id: string, name?: string, overrides?: Partial<CustomModel>): CustomModel {\n return {\n id,\n name: name || id,\n input: ['text'],\n contextWindow: 128000,\n maxTokens: 16384,\n cost: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n ...overrides,\n };\n}\n\nexport function isShellCommand(value: string): boolean {\n return value.startsWith('!');\n}\n\nexport function isEnvVar(value: string): boolean {\n return /^[A-Z][A-Z0-9_]*$/.test(value);\n}\n\nexport function getApiKeyType(value: string): 'shell' | 'env' | 'literal' {\n if (isShellCommand(value)) return 'shell';\n if (isEnvVar(value)) return 'env';\n return 'literal';\n}\n\nexport function maskApiKey(value: string): string {\n if (!value) return '';\n if (value.length <= 8) return '••••';\n return `${value.slice(0, 4)}••••${value.slice(-4)}`;\n}\n","import { Cpu, Plus, Trash2 } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\n\nimport type { AgentDefaultsPanelProps } from '../agent-defaults-panel-props';\n\n/** Chat-only fallback chain (`agents.defaults.modelFallbacks`) — lives on the Models settings page. */\nexport function AgentDefaultsChatModelFallbacksSection(props: AgentDefaultsPanelProps) {\n const { a, chat, form, update } = props;\n\n return (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cpu} title={a.label.modelFallbacks} subtitle={a.desc.modelFallbacks} />\n <div className=\"mt-4 flex flex-col gap-2\">\n {form.modelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ModelSelector\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => {\n const next = [...form.modelFallbacks];\n next[idx] = modelId;\n update({ modelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n modelFallbacks: form.modelFallbacks.filter((_, j) => j !== idx),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() => update({ modelFallbacks: [...form.modelFallbacks, ''] })}\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </SettingsFormSection>\n );\n}\n","import { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\n\nimport type { CustomModel, ModelsJsonConfig, ProviderConfig } from '../models-json-api';\n\nexport const PROVIDER_PRESETS: Record<string, Partial<ProviderConfig>> = {\n ollama: {\n baseUrl: 'http://localhost:11434/v1',\n api: 'openai-completions',\n apiKey: 'ollama',\n },\n lmstudio: {\n baseUrl: 'http://localhost:1234/v1',\n api: 'openai-completions',\n apiKey: 'lmstudio',\n },\n openrouter: {\n baseUrl: 'https://openrouter.ai/api/v1',\n api: 'openai-completions',\n apiKey: '',\n },\n zhipuCn: {\n baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4',\n api: 'openai-completions',\n apiKey: 'ZHIPU_API_KEY',\n },\n zaiGeneral: {\n baseUrl: 'https://api.z.ai/api/paas/v4',\n api: 'openai-completions',\n apiKey: 'ZAI_API_KEY',\n },\n};\n\nexport function providerIdForPreset(presetKey: string): string {\n if (presetKey === 'openrouter') return 'openrouter';\n if (presetKey === 'zhipuCn') return 'zhipu-cn';\n if (presetKey === 'zaiGeneral') return 'zai';\n return presetKey;\n}\n\nexport const INPUT_OPTIONS = [\n { value: 'text', labelKey: 'inputTextOnly' as const },\n { value: 'text,image', labelKey: 'inputTextVision' as const },\n];\n\nexport function inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nexport function selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nexport function parseInputSelect(model: CustomModel): string {\n const i = model.input || ['text'];\n if (i.includes('image')) return 'text,image';\n return 'text';\n}\n\nexport function inputFromSelect(sel: string): ('text' | 'image')[] {\n if (sel === 'text,image') return ['text', 'image'];\n return ['text'];\n}\n\nexport function updateProvider(\n config: ModelsJsonConfig,\n providerId: string,\n updates: Partial<ProviderConfig>,\n): ModelsJsonConfig {\n return {\n ...config,\n providers: {\n ...config.providers,\n [providerId]: {\n ...config.providers[providerId],\n ...updates,\n },\n },\n };\n}\n\nexport function removeProvider(config: ModelsJsonConfig, providerId: string): ModelsJsonConfig {\n const providers = { ...config.providers };\n delete providers[providerId];\n return { ...config, providers };\n}\n\nexport function addProviderEntry(\n config: ModelsJsonConfig,\n providerId: string,\n prov: ProviderConfig,\n): ModelsJsonConfig {\n return {\n ...config,\n providers: {\n ...config.providers,\n [providerId]: prov,\n },\n };\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport { createCustomModel, type CustomModel } from '../models-json-api';\n\nimport {\n inputClassName,\n INPUT_OPTIONS,\n inputFromSelect,\n parseInputSelect,\n selectClassName,\n} from './models-settings-lib';\n\ntype ModelDialogProps = {\n open: boolean;\n onOpenChange: (o: boolean) => void;\n providerId: string | null;\n model: CustomModel | null;\n isNew: boolean;\n onSave: (model: CustomModel) => void;\n m: ModelsSettingsMessages;\n};\n\nexport function ModelEditDialogContent({\n open,\n onOpenChange,\n providerId,\n model,\n isNew,\n onSave,\n m,\n}: ModelDialogProps) {\n const [form, setForm] = useState<Partial<CustomModel>>(() => createCustomModel(''));\n const [errors, setErrors] = useState<Map<string, string>>(() => new Map());\n\n useEffect(() => {\n if (!open) return;\n setErrors(new Map());\n setForm(model ? { ...model } : createCustomModel(''));\n }, [open, model]);\n\n const update = <K extends keyof CustomModel>(field: K, value: CustomModel[K]) => {\n setForm((f) => ({ ...f, [field]: value }));\n setErrors((prev) => {\n const next = new Map(prev);\n next.delete(field);\n return next;\n });\n };\n\n const validate = (): boolean => {\n const next = new Map<string, string>();\n const id = (form.id || '').trim();\n if (!id) next.set('id', m.modelIdRequired);\n if (form.contextWindow !== undefined && form.contextWindow <= 0) {\n next.set('contextWindow', m.mustBePositive);\n }\n if (form.maxTokens !== undefined && form.maxTokens <= 0) {\n next.set('maxTokens', m.mustBePositive);\n }\n setErrors(next);\n return next.size === 0;\n };\n\n const handleSave = () => {\n if (!validate()) return;\n const id = (form.id || '').trim();\n const result: CustomModel = {\n ...form,\n id,\n name: form.name?.trim() || id,\n reasoning: form.reasoning || false,\n input: form.input || ['text'],\n contextWindow: form.contextWindow ?? 128000,\n maxTokens: form.maxTokens ?? 16384,\n cost: {\n input: form.cost?.input ?? 0,\n output: form.cost?.output ?? 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n },\n };\n onSave(result);\n onOpenChange(false);\n };\n\n const inputSel = parseInputSelect(form as CustomModel);\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,720px)] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2',\n 'overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"mb-3 flex items-start justify-between gap-2\">\n <div>\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {isNew ? m.addModelTitle : m.editModelTitle}\n </Dialog.Title>\n {providerId ? (\n <p className=\"mt-0.5 text-xs text-fg-muted\">\n {m.modelProviderLabel}: {providerId}\n </p>\n ) : null}\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n aria-label={m.close}\n >\n <X className=\"size-4\" />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg\">\n {m.modelId}\n <span className=\"text-red-600 dark:text-red-400\"> *</span>\n </label>\n <input\n className={cn(inputClassName(), errors.has('id') && 'border-red-500')}\n value={form.id || ''}\n onChange={(e) => update('id', e.target.value)}\n placeholder=\"e.g. llama3.1:8b\"\n disabled={!isNew}\n />\n {errors.has('id') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('id')}</p>\n ) : null}\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.displayName}</label>\n <input\n className={inputClassName()}\n value={form.name || ''}\n onChange={(e) => update('name', e.target.value)}\n />\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.inputTypes}</label>\n <select\n className={selectClassName()}\n value={inputSel}\n onChange={(e) => update('input', inputFromSelect(e.target.value))}\n >\n {INPUT_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {m[opt.labelKey]}\n </option>\n ))}\n </select>\n </div>\n <label className=\"mt-6 flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={form.reasoning || false}\n onChange={(e) => update('reasoning', e.target.checked)}\n />\n {m.reasoning}\n </label>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.contextWindow}</label>\n <input\n type=\"number\"\n min={1}\n className={cn(inputClassName(), errors.has('contextWindow') && 'border-red-500')}\n value={form.contextWindow ?? 128000}\n onChange={(e) => update('contextWindow', parseInt(e.target.value, 10) || 0)}\n />\n {errors.has('contextWindow') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('contextWindow')}</p>\n ) : null}\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.maxOutputTokens}</label>\n <input\n type=\"number\"\n min={1}\n className={cn(inputClassName(), errors.has('maxTokens') && 'border-red-500')}\n value={form.maxTokens ?? 16384}\n onChange={(e) => update('maxTokens', parseInt(e.target.value, 10) || 0)}\n />\n {errors.has('maxTokens') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('maxTokens')}</p>\n ) : null}\n </div>\n </div>\n <div className=\"border-t border-edge-subtle pt-2 dark:border-edge\">\n <p className=\"mb-2 text-xs font-semibold text-fg\">{m.costSection}</p>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1 block text-xs text-fg-muted\">{m.costInput}</label>\n <input\n type=\"number\"\n step=\"any\"\n min={0}\n className={inputClassName()}\n value={form.cost?.input ?? 0}\n onChange={(e) =>\n update('cost', {\n ...form.cost,\n input: parseFloat(e.target.value) || 0,\n output: form.cost?.output ?? 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n })\n }\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs text-fg-muted\">{m.costOutput}</label>\n <input\n type=\"number\"\n step=\"any\"\n min={0}\n className={inputClassName()}\n value={form.cost?.output ?? 0}\n onChange={(e) =>\n update('cost', {\n ...form.cost,\n input: form.cost?.input ?? 0,\n output: parseFloat(e.target.value) || 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n })\n }\n />\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge\">\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"secondary\">\n {m.cancel}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={handleSave}>\n {isNew ? m.addModelConfirm : m.saveModelConfirm}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { AlertCircle, X } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport {\n API_TYPE_OPTIONS,\n type ApiType,\n type ProviderConfig,\n} from '../models-json-api';\n\nimport {\n inputClassName,\n PROVIDER_PRESETS,\n providerIdForPreset,\n selectClassName,\n} from './models-settings-lib';\n\ntype ProviderDialogProps = {\n open: boolean;\n onOpenChange: (o: boolean) => void;\n presetKey?: string | null;\n onConfirm: (providerId: string, prov: ProviderConfig) => void;\n m: ModelsSettingsMessages;\n};\n\nexport function ProviderAddDialog({ open, onOpenChange, presetKey, onConfirm, m }: ProviderDialogProps) {\n const [providerId, setProviderId] = useState('');\n const [preset, setPreset] = useState('custom');\n const [baseUrl, setBaseUrl] = useState('');\n const [api, setApi] = useState<ApiType>('openai-completions');\n const [apiKey, setApiKey] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!open) return;\n setError(null);\n const pk = presetKey || null;\n if (pk && PROVIDER_PRESETS[pk]) {\n const p = PROVIDER_PRESETS[pk];\n setPreset(pk);\n setBaseUrl(p.baseUrl || '');\n setApi((p.api as ApiType) || 'openai-completions');\n setApiKey(p.apiKey ?? '');\n setProviderId(providerIdForPreset(pk));\n } else {\n setPreset('custom');\n setProviderId('');\n setBaseUrl('');\n setApi('openai-completions');\n setApiKey('');\n }\n }, [open, presetKey]);\n\n const applyPreset = (key: string) => {\n setPreset(key);\n if (key === 'custom') return;\n const p = PROVIDER_PRESETS[key];\n if (!p) return;\n setBaseUrl(p.baseUrl || '');\n setApi((p.api as ApiType) || 'openai-completions');\n setApiKey(p.apiKey ?? '');\n setProviderId(providerIdForPreset(key));\n };\n\n const handleSubmit = () => {\n const id = providerId.trim();\n if (!id) {\n setError(m.providerIdRequired);\n return;\n }\n setError(null);\n onConfirm(id, {\n baseUrl: baseUrl.trim() || undefined,\n api,\n apiKey: apiKey.trim() || undefined,\n models: [],\n });\n onOpenChange(false);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,640px)] w-[min(100%-2rem,32rem)] -translate-x-1/2 -translate-y-1/2',\n 'overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"mb-3 flex items-start justify-between gap-2\">\n <div>\n <Dialog.Title className=\"text-base font-semibold text-fg\">{m.addProviderTitle}</Dialog.Title>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{m.addProviderSubtitle}</p>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n aria-label={m.close}\n >\n <X className=\"size-4\" />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.presetLabel}</label>\n <select\n className={selectClassName()}\n value={preset}\n onChange={(e) => applyPreset(e.target.value)}\n >\n <option value=\"custom\">{m.presetCustom}</option>\n <option value=\"ollama\">{m.presetOllama}</option>\n <option value=\"lmstudio\">{m.presetLmStudio}</option>\n <option value=\"openrouter\">{m.presetOpenRouter}</option>\n <option value=\"zhipuCn\">{m.presetZhipuCn}</option>\n <option value=\"zaiGeneral\">{m.presetZaiGeneral}</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg\">\n {m.providerIdLabel}\n <span className=\"text-red-600 dark:text-red-400\"> *</span>\n </label>\n <input\n className={inputClassName()}\n value={providerId}\n onChange={(e) => setProviderId(e.target.value)}\n placeholder={m.providerIdPlaceholder}\n />\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.baseUrl}</label>\n <input\n className={inputClassName()}\n value={baseUrl}\n onChange={(e) => setBaseUrl(e.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.apiType}</label>\n <select\n className={selectClassName()}\n value={api}\n onChange={(e) => setApi(e.target.value as ApiType)}\n >\n {API_TYPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.apiKey}</label>\n <input\n className={inputClassName()}\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n placeholder={m.apiKeyPlaceholder}\n />\n </div>\n {error ? (\n <p className=\"flex items-center gap-1 text-xs text-red-600 dark:text-red-400\">\n <AlertCircle className=\"size-3.5 shrink-0\" />\n {error}\n </p>\n ) : null}\n </div>\n\n <div className=\"mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge\">\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"secondary\">\n {m.cancel}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={handleSubmit}>\n {m.addProviderConfirm}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import {\n Box,\n ChevronDown,\n ChevronRight,\n Cpu,\n Eye,\n EyeOff,\n Pencil,\n Plus,\n Trash2,\n Zap,\n} from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport {\n API_TYPE_OPTIONS,\n getApiKeyType,\n maskApiKey,\n type ApiType,\n type CustomModel,\n type ModelsJsonConfig,\n} from '../models-json-api';\n\nimport { inputClassName, selectClassName, updateProvider } from './models-settings-lib';\n\nexport type ModelsTestResult = { type: string; resolved?: string; error?: string };\n\ntype ModelsProvidersListProps = {\n config: ModelsJsonConfig;\n setConfig: Dispatch<SetStateAction<ModelsJsonConfig>>;\n expanded: Set<string>;\n toggleExpand: (id: string) => void;\n showPw: Set<string>;\n toggleShowPw: (id: string) => void;\n testResults: Map<string, ModelsTestResult>;\n runTestKey: (providerId: string, value: string) => void;\n ms: ModelsSettingsMessages;\n removeProv: (providerId: string) => void;\n openModelDialog: (providerId: string, model: CustomModel | null, isNew: boolean) => void;\n setTestResults: Dispatch<SetStateAction<Map<string, ModelsTestResult>>>;\n};\n\nexport function ModelsProvidersList({\n config,\n setConfig,\n expanded,\n toggleExpand,\n showPw,\n toggleShowPw,\n testResults,\n runTestKey,\n ms,\n removeProv,\n openModelDialog,\n setTestResults,\n}: ModelsProvidersListProps) {\n return (\n <div className=\"flex flex-col gap-3\">\n {Object.entries(config.providers)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([id, prov]) => {\n const isEx = expanded.has(id);\n const nModels = prov.models?.length ?? 0;\n const keyType = prov.apiKey ? getApiKeyType(prov.apiKey) : null;\n const testResult = testResults.get(id);\n const pwVisible = showPw.has(id);\n\n return (\n <section\n key={id}\n className=\"overflow-hidden rounded-2xl bg-surface-base\"\n >\n <div className=\"flex items-center justify-between gap-2 border-b border-edge-subtle bg-surface-hover/35 px-3 py-2 dark:border-edge-subtle\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 text-left text-sm font-semibold text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n onClick={() => toggleExpand(id)}\n >\n {isEx ? (\n <ChevronDown className=\"size-4 shrink-0 text-fg-muted\" />\n ) : (\n <ChevronRight className=\"size-4 shrink-0 text-fg-muted\" />\n )}\n <span className=\"truncate\">{id}</span>\n {nModels > 0 ? (\n <span className=\"shrink-0 rounded-full bg-accent px-2 py-0.5 text-[10px] font-medium text-white\">\n {nModels}\n </span>\n ) : null}\n {keyType ? (\n <span\n className={cn(\n 'shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium',\n keyType === 'shell' && 'bg-blue-100 text-blue-800 dark:bg-blue-950 dark:text-blue-200',\n keyType === 'env' && 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200',\n keyType === 'literal' && 'bg-surface-hover text-fg-muted dark:bg-surface-active',\n )}\n >\n {keyType === 'shell' ? ms.badgeShell : keyType === 'env' ? ms.badgeEnv : ms.badgeLiteral}\n </span>\n ) : null}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-red-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 dark:hover:text-red-400\"\n onClick={() => removeProv(id)}\n aria-label={ms.removeProvider}\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n\n {isEx ? (\n <div className=\"space-y-4 px-3 py-3\">\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.baseUrl}</label>\n <input\n className={inputClassName()}\n value={prov.baseUrl || ''}\n onChange={(e) =>\n setConfig((c) => updateProvider(c, id, { baseUrl: e.target.value }))\n }\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.apiType}</label>\n <select\n className={selectClassName()}\n value={prov.api || 'openai-completions'}\n onChange={(e) =>\n setConfig((c) =>\n updateProvider(c, id, { api: e.target.value as ApiType }),\n )\n }\n >\n {API_TYPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.apiKey}</label>\n <div className=\"flex flex-wrap gap-2\">\n <input\n className={cn(inputClassName(), 'min-w-0 flex-1')}\n type={pwVisible ? 'text' : 'password'}\n autoComplete=\"off\"\n value={prov.apiKey || ''}\n onChange={(e) => {\n const v = e.target.value;\n setConfig((c) => updateProvider(c, id, { apiKey: v }));\n setTestResults((prev) => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }}\n placeholder={ms.apiKeyPlaceholder}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => toggleShowPw(id)}\n >\n {pwVisible ? (\n <>\n <EyeOff className=\"mr-1 size-3.5\" />\n {ms.hide}\n </>\n ) : (\n <>\n <Eye className=\"mr-1 size-3.5\" />\n {ms.show}\n </>\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => runTestKey(id, prov.apiKey || '')}\n >\n {ms.testKey}\n </Button>\n </div>\n {testResult ? (\n <p\n className={cn(\n 'mt-1 text-xs',\n testResult.error ? 'text-red-600 dark:text-red-400' : 'text-emerald-700 dark:text-emerald-400',\n )}\n >\n {testResult.error\n ? `${ms.testError}: ${testResult.error}`\n : `${ms.testOk} (${testResult.type}): ${maskApiKey(testResult.resolved || '')}`}\n </p>\n ) : null}\n <p className=\"mt-1 text-xs text-fg-subtle\">{ms.apiKeyHint}</p>\n </div>\n\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={prov.authHeader || false}\n onChange={(e) =>\n setConfig((c) => updateProvider(c, id, { authHeader: e.target.checked }))\n }\n />\n {ms.authHeader}\n </label>\n\n <div className=\"border-t border-edge-subtle pt-3 dark:border-edge\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{ms.modelsSection}</span>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => openModelDialog(id, null, true)}\n >\n <Plus className=\"mr-1 size-3.5\" />\n {ms.addModel}\n </Button>\n </div>\n {(prov.models || []).length === 0 ? (\n <p className=\"text-xs text-fg-muted\">{ms.modelsEmpty}</p>\n ) : (\n <ul className=\"space-y-2\">\n {(prov.models || []).map((mod) => (\n <li\n key={mod.id}\n className=\"flex items-center justify-between gap-2 rounded-lg border border-edge-subtle bg-surface-base px-3 py-2 dark:border-edge\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-fg\">{mod.id}</div>\n {mod.name && mod.name !== mod.id ? (\n <div className=\"truncate text-xs text-fg-muted\">{mod.name}</div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 gap-1\">\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-fg\"\n onClick={() => openModelDialog(id, mod, false)}\n aria-label={ms.editModel}\n >\n <Pencil className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-red-600 dark:hover:text-red-400\"\n onClick={() => {\n if (!window.confirm(ms.removeModelConfirm.replace('{{id}}', mod.id))) return;\n setConfig((c) => {\n const p = c.providers[id];\n if (!p) return c;\n return updateProvider(c, id, {\n models: (p.models || []).filter((mm) => mm.id !== mod.id),\n });\n });\n }}\n aria-label={ms.removeModel}\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n ) : null}\n </section>\n );\n })}\n </div>\n );\n}\n\ntype ModelsSettingsEmptyStateProps = {\n ms: ModelsSettingsMessages;\n openAddProvider: (preset: string | null) => void;\n};\n\nexport function ModelsSettingsEmptyState({ ms, openAddProvider }: ModelsSettingsEmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center rounded-xl border-2 border-dashed border-edge-subtle bg-surface-panel px-6 py-12 text-center dark:border-edge\">\n <div className=\"mb-4 flex size-14 items-center justify-center rounded-full border border-edge bg-surface-base dark:border-edge\">\n <Cpu className=\"size-7 text-accent\" strokeWidth={1.5} />\n </div>\n <h2 className=\"mb-1 text-base font-semibold text-fg\">{ms.emptyTitle}</h2>\n <p className=\"mb-6 max-w-md text-sm text-fg-muted\">{ms.emptyDesc}</p>\n <Button\n type=\"button\"\n className=\"mb-6 bg-accent text-white hover:bg-accent/90\"\n onClick={() => openAddProvider(null)}\n >\n <Plus className=\"mr-1 size-4\" />\n {ms.emptyCta}\n </Button>\n <div className=\"flex flex-wrap justify-center gap-2\">\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('ollama')}\n >\n <Zap className=\"size-3.5\" aria-hidden />\n {ms.presetOllama}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('openrouter')}\n >\n <Box className=\"size-3.5\" aria-hidden />\n {ms.presetOpenRouter}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('lmstudio')}\n >\n <Cpu className=\"size-3.5\" aria-hidden />\n {ms.presetLmStudio}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('zhipuCn')}\n >\n <Zap className=\"size-3.5\" aria-hidden />\n {ms.presetZhipuCn}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('zaiGeneral')}\n >\n <Box className=\"size-3.5\" aria-hidden />\n {ms.presetZaiGeneral}\n </button>\n </div>\n </div>\n );\n}\n","import {\n AlertCircle,\n ExternalLink,\n Loader2,\n Plus,\n RefreshCw,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport {\n fetchModelsJson,\n normalizeModelsJsonConfig,\n reloadModelsJson,\n saveModelsJson,\n testApiKey,\n validateModelsJson,\n type CustomModel,\n type ModelsJsonConfig,\n type ProviderConfig,\n type ValidationResult,\n} from '../models-json-api';\nimport { AgentDefaultsChatModelFallbacksSection } from '../agents/agent-defaults-panels/chat-model-fallbacks-section';\nimport { useAgentDefaultsForm } from '../agents/use-agent-defaults-form';\n\nimport { ModelEditDialogContent } from './models-model-edit-dialog';\nimport { ProviderAddDialog } from './models-provider-add-dialog';\nimport {\n ModelsProvidersList,\n ModelsSettingsEmptyState,\n type ModelsTestResult,\n} from './models-providers-list';\nimport { addProviderEntry, inputClassName, removeProvider, updateProvider } from './models-settings-lib';\n\nexport function ModelsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const ms = m.modelsSettings;\n const agentVm = useAgentDefaultsForm(m.agentSettings);\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [config, setConfig] = useState<ModelsJsonConfig>({ providers: {} });\n const [baseline, setBaseline] = useState<ModelsJsonConfig>({ providers: {} });\n const [path, setPath] = useState('');\n const [loadMetaError, setLoadMetaError] = useState<string | undefined>();\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [validating, setValidating] = useState(false);\n const [reloading, setReloading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const [validation, setValidation] = useState<ValidationResult | null>(null);\n const [expanded, setExpanded] = useState<Set<string>>(() => new Set());\n const [showRawJson, setShowRawJson] = useState(false);\n const [rawText, setRawText] = useState('');\n const [rawError, setRawError] = useState<string | null>(null);\n const [showPw, setShowPw] = useState<Set<string>>(() => new Set());\n const [testResults, setTestResults] = useState<Map<string, ModelsTestResult>>(() => new Map());\n\n const [providerDialogOpen, setProviderDialogOpen] = useState(false);\n const [providerPreset, setProviderPreset] = useState<string | null>(null);\n\n const [modelDialogOpen, setModelDialogOpen] = useState(false);\n const [modelDialogCtx, setModelDialogCtx] = useState<{\n providerId: string;\n model: CustomModel | null;\n isNew: boolean;\n } | null>(null);\n\n const load = useCallback(async (opts?: { skipFullPageLoading?: boolean }) => {\n const showFullPageLoading = !opts?.skipFullPageLoading;\n if (showFullPageLoading) {\n setLoading(true);\n }\n setError(null);\n try {\n const st = await fetchModelsJson();\n const norm = normalizeModelsJsonConfig(st.config);\n setConfig(norm);\n setBaseline(structuredClone(norm));\n setPath(st.path);\n setLoadMetaError(st.loadError);\n setValidation(null);\n setSaveOk(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.loadError);\n setConfig({ providers: {} });\n setBaseline({ providers: {} });\n } finally {\n if (showFullPageLoading) {\n setLoading(false);\n }\n }\n }, [ms.loadError]);\n\n useEffect(() => {\n if (!hasToken) {\n setLoading(false);\n return;\n }\n void load();\n }, [hasToken, load]);\n\n const dirty = useMemo(\n () => JSON.stringify(config) !== JSON.stringify(baseline),\n [config, baseline],\n );\n\n const agentPanelProps = useMemo(() => {\n if (!agentVm.form) return null;\n return {\n form: agentVm.form,\n update: agentVm.update,\n a: m.agentSettings,\n chat: m.chat,\n };\n }, [agentVm.form, agentVm.update, m.agentSettings, m.chat]);\n\n const combinedDirty = dirty || agentVm.dirty;\n\n const stats = useMemo(() => {\n const ids = Object.keys(config.providers);\n let models = 0;\n for (const p of Object.values(config.providers)) {\n models += p.models?.length ?? 0;\n }\n return { providers: ids.length, models };\n }, [config.providers]);\n\n const toggleExpand = (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const toggleShowPw = (id: string) => {\n setShowPw((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const syncRawFromConfig = useCallback(() => {\n setRawText(JSON.stringify(config, null, 2));\n setRawError(null);\n }, [config]);\n\n useEffect(() => {\n if (showRawJson) syncRawFromConfig();\n }, [showRawJson, syncRawFromConfig]);\n\n const applyRawJson = () => {\n try {\n const parsed = JSON.parse(rawText) as unknown;\n const norm = normalizeModelsJsonConfig(parsed);\n setConfig(norm);\n setRawError(null);\n } catch {\n setRawError(ms.jsonParseError);\n }\n };\n\n const runValidate = async () => {\n setValidating(true);\n setError(null);\n try {\n const r = await validateModelsJson(config);\n setValidation(r);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.validateError);\n } finally {\n setValidating(false);\n }\n };\n\n const runSave = async () => {\n if (saving || agentVm.saving) return;\n const hadJsonDirty = dirty;\n const hadAgentDirty = agentVm.dirty;\n if (!hadJsonDirty && !hadAgentDirty) return;\n\n setError(null);\n setSaveOk(false);\n try {\n if (hadJsonDirty) {\n setSaving(true);\n try {\n await saveModelsJson(config);\n setBaseline(structuredClone(config));\n setValidation(null);\n } finally {\n setSaving(false);\n }\n }\n if (hadAgentDirty && agentVm.form) {\n const agentOk = await agentVm.save();\n if (!agentOk) {\n throw new Error(m.agentSettings.saveError);\n }\n }\n setSaveOk(true);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.saveError);\n }\n };\n\n const runDiscard = useCallback(() => {\n setConfig(structuredClone(baseline));\n setValidation(null);\n setSaveOk(false);\n setError(null);\n if (showRawJson) {\n setRawText(JSON.stringify(baseline, null, 2));\n setRawError(null);\n }\n agentVm.discard();\n }, [baseline, showRawJson, agentVm.discard]);\n\n const runReload = async () => {\n setReloading(true);\n setError(null);\n try {\n await reloadModelsJson();\n await load({ skipFullPageLoading: true });\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.reloadError);\n } finally {\n setReloading(false);\n }\n };\n\n const runTestKey = async (providerId: string, value: string) => {\n try {\n const r = await testApiKey(value);\n setTestResults((prev) => {\n const next = new Map(prev);\n next.set(providerId, r);\n return next;\n });\n } catch (e) {\n setTestResults((prev) => {\n const next = new Map(prev);\n next.set(providerId, {\n type: 'error',\n error: e instanceof Error ? e.message : 'Error',\n });\n return next;\n });\n }\n };\n\n const openAddProvider = (preset: string | null = null) => {\n setProviderPreset(preset);\n setProviderDialogOpen(true);\n };\n\n const onProviderAdded = (providerId: string, prov: ProviderConfig) => {\n setConfig((c) => addProviderEntry(c, providerId, prov));\n setExpanded((prev) => new Set(prev).add(providerId));\n };\n\n const removeProv = (providerId: string) => {\n if (!window.confirm(ms.removeProviderConfirm.replace('{{id}}', providerId))) return;\n setConfig((c) => removeProvider(c, providerId));\n setTestResults((prev) => {\n const next = new Map(prev);\n next.delete(providerId);\n return next;\n });\n };\n\n const openModelDialog = (providerId: string, model: CustomModel | null, isNew: boolean) => {\n setModelDialogCtx({ providerId, model, isNew });\n setModelDialogOpen(true);\n };\n\n const onModelSaved = (updated: CustomModel) => {\n if (!modelDialogCtx) return;\n const { providerId, isNew } = modelDialogCtx;\n setConfig((c) => {\n const p = c.providers[providerId];\n if (!p) return c;\n const models = p.models || [];\n if (isNew) {\n return updateProvider(c, providerId, { models: [...models, updated] });\n }\n return updateProvider(c, providerId, {\n models: models.map((mm) => (mm.id === updated.id ? updated : mm)),\n });\n });\n };\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.models}</h1>\n <p className=\"text-sm text-fg-muted\">{ms.needToken}</p>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-8\">\n <div className=\"flex flex-col gap-1\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.models}</h1>\n <p className=\"text-sm text-fg-muted\">{ms.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'models')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {ms.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n\n {loadMetaError ? (\n <div\n className=\"flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\"\n role=\"status\"\n >\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{ms.loadFileWarning}: {loadMetaError}</span>\n </div>\n ) : null}\n\n {path ? (\n <p className=\"text-xs text-fg-subtle\">\n {ms.filePath}: <code className=\"rounded bg-surface-base px-1 py-0.5 font-mono text-fg-muted\">{path}</code>\n </p>\n ) : null}\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n className=\"bg-accent text-white hover:bg-accent/90\"\n onClick={() => openAddProvider(null)}\n disabled={loading}\n >\n <Plus className=\"mr-1 size-4\" />\n {ms.addProvider}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={runValidate}\n disabled={loading || validating}\n >\n {validating ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.validating}\n </>\n ) : (\n ms.validate\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={runDiscard}\n disabled={loading || saving || agentVm.saving || !combinedDirty}\n >\n {ms.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={() => void runSave()}\n disabled={loading || saving || agentVm.saving || !combinedDirty}\n >\n {saving || agentVm.saving ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.saving}\n </>\n ) : (\n ms.save\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[8.5rem] justify-center\"\n onClick={runReload}\n disabled={loading || reloading}\n >\n {reloading ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.reloading}\n </>\n ) : (\n <>\n <RefreshCw className=\"mr-1 size-4\" />\n {ms.reload}\n </>\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"text-fg-muted\"\n onClick={() => {\n setShowRawJson((v) => !v);\n setRawError(null);\n }}\n >\n {showRawJson ? ms.hideJson : ms.showJson}\n </Button>\n <div className=\"ml-auto flex items-center gap-2 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-1.5 text-sm dark:border-edge\">\n <span className=\"text-fg-muted\">\n {ms.statsProviders.replace('{{count}}', String(stats.providers))}\n </span>\n <span className=\"text-fg-subtle\">|</span>\n <span className=\"text-fg-muted\">\n {ms.statsModels.replace('{{count}}', String(stats.models))}\n </span>\n </div>\n </div>\n\n {combinedDirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{ms.unsavedHint}</p> : null}\n {saveOk || agentVm.saveOk ? (\n <p className=\"text-xs text-emerald-700 dark:text-emerald-400\" role=\"status\">\n {ms.saved}\n </p>\n ) : null}\n {error ? (\n <p className=\"flex items-center gap-1 text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n <AlertCircle className=\"size-4 shrink-0\" />\n {error}\n </p>\n ) : null}\n {agentVm.error ? (\n <p className=\"flex items-center gap-1 text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n <AlertCircle className=\"size-4 shrink-0\" />\n {agentVm.error}\n </p>\n ) : null}\n\n {validation && validation.errors.length > 0 ? (\n <div\n className=\"rounded-lg border border-amber-200 bg-amber-50/80 px-3 py-2 dark:border-amber-800 dark:bg-amber-950/30\"\n role=\"status\"\n >\n <p className=\"mb-1 text-sm font-medium text-amber-950 dark:text-amber-100\">\n {validation.valid ? ms.validationWarnings : ms.validationErrors}\n </p>\n <ul className=\"list-inside list-disc space-y-0.5 text-xs text-amber-900 dark:text-amber-200\">\n {validation.errors.map((err, i) => (\n <li key={`${err.path}-${i}`}>\n {err.path}: {err.message} ({err.severity})\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {loading ? (\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {ms.loading}\n </div>\n ) : showRawJson ? (\n <div className=\"flex flex-col gap-2\">\n <textarea\n className={cn(\n inputClassName(),\n 'min-h-[320px] resize-y font-mono text-xs leading-relaxed',\n )}\n value={rawText}\n onChange={(e) => setRawText(e.target.value)}\n spellCheck={false}\n />\n {rawError ? <p className=\"text-xs text-red-600 dark:text-red-400\">{rawError}</p> : null}\n <div className=\"flex gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={syncRawFromConfig}>\n {ms.jsonReset}\n </Button>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={applyRawJson}>\n {ms.jsonApply}\n </Button>\n </div>\n </div>\n ) : Object.keys(config.providers).length === 0 ? (\n <ModelsSettingsEmptyState ms={ms} openAddProvider={openAddProvider} />\n ) : (\n <ModelsProvidersList\n config={config}\n setConfig={setConfig}\n expanded={expanded}\n toggleExpand={toggleExpand}\n showPw={showPw}\n toggleShowPw={toggleShowPw}\n testResults={testResults}\n runTestKey={runTestKey}\n ms={ms}\n removeProv={removeProv}\n openModelDialog={openModelDialog}\n setTestResults={setTestResults}\n />\n )}\n\n {agentPanelProps ? (\n <div className=\"mt-10 border-t border-edge-subtle pt-8 dark:border-edge\">\n <AgentDefaultsChatModelFallbacksSection {...agentPanelProps} />\n </div>\n ) : null}\n\n <ProviderAddDialog\n open={providerDialogOpen}\n onOpenChange={setProviderDialogOpen}\n presetKey={providerPreset}\n onConfirm={onProviderAdded}\n m={ms}\n />\n\n <ModelEditDialogContent\n open={modelDialogOpen}\n onOpenChange={(o) => {\n setModelDialogOpen(o);\n if (!o) setModelDialogCtx(null);\n }}\n providerId={modelDialogCtx?.providerId ?? null}\n model={modelDialogCtx?.model ?? null}\n isNew={modelDialogCtx?.isNew ?? false}\n onSave={onModelSaved}\n m={ms}\n />\n </div>\n );\n}\n","import { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport interface OAuthStartResult {\n sessionId: string;\n provider: string;\n status: string;\n}\n\nexport interface OAuthSessionStatus {\n sessionId: string;\n provider: string;\n status: 'pending' | 'waiting_auth' | 'waiting_code' | 'completed' | 'failed' | 'cancelled';\n authUrl?: string;\n instructions?: string;\n message?: string;\n error?: string;\n expiresAt: number;\n}\n\nexport async function startAsyncOAuthLogin(provider: string): Promise<OAuthStartResult> {\n const res = await apiFetch(apiUrl('/api/auth/oauth-async/start'), {\n method: 'POST',\n body: JSON.stringify({ provider }),\n });\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { error?: string };\n throw new Error(err.error || `OAuth start failed: ${res.status}`);\n }\n const data = (await res.json()) as { payload: OAuthStartResult };\n return data.payload;\n}\n\nexport async function fetchOAuthSessionStatus(sessionId: string): Promise<OAuthSessionStatus> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/status`));\n if (!res.ok) {\n throw new Error(`OAuth status: ${res.status}`);\n }\n const data = (await res.json()) as { payload: OAuthSessionStatus };\n return data.payload;\n}\n\nexport async function submitOAuthCode(sessionId: string, code: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/code`), {\n method: 'POST',\n body: JSON.stringify({ code }),\n });\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { error?: string };\n throw new Error(err.error || `Submit code failed: ${res.status}`);\n }\n}\n\nexport async function cancelOAuth(sessionId: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/cancel`), {\n method: 'POST',\n });\n if (!res.ok) {\n throw new Error(`Cancel OAuth failed: ${res.status}`);\n }\n}\n\nexport async function cleanupOAuthSession(sessionId: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}`), {\n method: 'DELETE',\n });\n if (!res.ok) {\n throw new Error(`Cleanup session failed: ${res.status}`);\n }\n}\n\nexport async function revokeOAuth(provider: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth/${encodeURIComponent(provider)}`), {\n method: 'DELETE',\n });\n if (!res.ok) {\n throw new Error(`Revoke OAuth failed: ${res.status}`);\n }\n}\n","import * as Popover from '@radix-ui/react-popover';\nimport { ExternalLink, Info, X } from 'lucide-react';\n\nimport { cn } from '@/lib/cn';\nimport type { StoredLanguage } from '@/lib/storage';\n\nimport { PROVIDER_ENRICHMENT } from './provider-enrichment';\n\ninterface ProviderInfoPopoverProps {\n providerId: string;\n language: StoredLanguage;\n}\n\nexport function ProviderInfoPopover({ providerId, language }: ProviderInfoPopoverProps) {\n const enrichment = PROVIDER_ENRICHMENT[providerId];\n if (!enrichment) return null;\n\n const isZh = language === 'zh';\n const description = isZh && enrichment.descriptionZh ? enrichment.descriptionZh : enrichment.description;\n if (!description) return null;\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n aria-label={isZh ? `${providerId} 详情` : `${providerId} info`}\n >\n <Info className=\"size-3.5\" aria-hidden />\n </button>\n </Popover.Trigger>\n\n <Popover.Portal>\n <Popover.Content\n side=\"right\"\n align=\"start\"\n sideOffset={6}\n className={cn(\n 'z-50 w-64 rounded-xl border border-edge bg-surface-panel p-3 shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"text-xs font-semibold text-fg\">{providerId}</p>\n <Popover.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg\"\n aria-label={isZh ? '关闭' : 'Close'}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n </Popover.Close>\n </div>\n\n <p className=\"mt-1.5 text-xs leading-relaxed text-fg-muted\">{description}</p>\n\n {enrichment.bestFor && enrichment.bestFor.length > 0 ? (\n <div className=\"mt-2\">\n <p className=\"text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {isZh ? '适合场景' : 'Best for'}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {enrichment.bestFor.map((tag) => (\n <span\n key={tag}\n className=\"rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium text-fg-muted\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n ) : null}\n\n {enrichment.freeTier !== undefined ? (\n <div className=\"mt-2\">\n <p className=\"text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {isZh ? '免费额度' : 'Free tier'}\n </p>\n <p className=\"mt-0.5 text-xs text-fg-muted\">\n {enrichment.freeTier\n ? enrichment.freeTierNote ?? (isZh ? '有免费额度' : 'Available')\n : isZh\n ? '无免费额度(按量付费)'\n : 'None (pay-as-you-go)'}\n </p>\n </div>\n ) : null}\n\n {enrichment.pricingUrl || enrichment.docsUrl ? (\n <div className=\"mt-2.5 flex gap-3\">\n {enrichment.pricingUrl ? (\n <a\n href={enrichment.pricingUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline\"\n >\n {isZh ? '定价' : 'Pricing'}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ) : null}\n {enrichment.docsUrl ? (\n <a\n href={enrichment.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline\"\n >\n {isZh ? '文档' : 'Docs'}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ) : null}\n </div>\n ) : null}\n\n <Popover.Arrow className=\"fill-edge\" />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","import type { ProviderActiveKeySource, ProviderCategory, ProviderRowModel } from '@/features/settings/providers-api';\nimport type { ProvidersSettingsMessages } from '@/i18n/messages';\n\nexport const CATEGORY_ORDER: ProviderCategory[] = [\n 'common',\n 'specialty',\n 'enterprise',\n 'oauth',\n 'extension',\n];\n\nexport function groupByCategory(rows: ProviderRowModel[]): Map<ProviderCategory, ProviderRowModel[]> {\n const map = new Map<ProviderCategory, ProviderRowModel[]>();\n for (const c of CATEGORY_ORDER) map.set(c, []);\n for (const r of rows) {\n const cat = r.category || 'specialty';\n const list = map.get(cat) ?? [];\n list.push(r);\n map.set(cat, list);\n }\n return map;\n}\n\nexport function interpolate(template: string, params: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => String(params[key] ?? ''));\n}\n\nexport function activeSourceLabel(\n labels: ProvidersSettingsMessages,\n src: ProviderActiveKeySource | undefined,\n): string {\n switch (src) {\n case 'agent':\n return labels.sourceAgent;\n case 'gateway':\n return labels.sourceGateway;\n case 'oauth':\n return labels.sourceOauth;\n case 'env':\n return labels.sourceEnv;\n case 'models_json':\n return labels.sourceModelsJson;\n case 'extension':\n return labels.sourceExtension;\n default:\n return labels.sourceNone;\n }\n}\n","import {\n AlertCircle,\n CheckCircle2,\n ChevronDown,\n Copy,\n ExternalLink,\n Eye,\n EyeOff,\n Info,\n KeyRound,\n Loader2,\n LogIn,\n LogOut,\n Trash2,\n X,\n} from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ConfirmDialog } from '@/components/ui/confirm-dialog';\nimport type { ConfiguredModel } from '@/features/chat/registry-api';\nimport {\n cancelOAuth,\n cleanupOAuthSession,\n fetchOAuthSessionStatus,\n revokeOAuth,\n startAsyncOAuthLogin,\n submitOAuthCode,\n} from '@/features/settings/oauth-api';\nimport {\n deleteProviderApiKey,\n isMaskedKey,\n testProviderKeyResolution,\n type ProviderRowModel,\n} from '@/features/settings/providers-api';\nimport {\n getOrderedApiKeyLinks,\n PROVIDER_ENRICHMENT,\n providerApiKeyLinkLabel,\n} from '@/features/settings/provider-enrichment';\nimport { ProviderInfoPopover } from '@/features/settings/provider-info-popover';\nimport { activeSourceLabel, interpolate } from './providers-settings-lib';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport type { StoredLanguage } from '@/lib/storage';\nimport type { ProvidersSettingsMessages } from '@/i18n/messages';\n\nfunction EnvVarCopyRow({\n envVar,\n labels,\n}: {\n envVar: string;\n labels: ProvidersSettingsMessages;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(envVar);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n } catch {\n /* ignore clipboard errors */\n }\n };\n\n return (\n <div className=\"flex items-center gap-2\">\n <code className=\"rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[11px] text-fg-muted\">{envVar}</code>\n <button\n type=\"button\"\n onClick={() => void handleCopy()}\n className=\"rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg\"\n title={copied ? labels.copied : labels.copy}\n aria-label={copied ? labels.copied : labels.copy}\n >\n {copied ? (\n <CheckCircle2 className=\"size-3.5 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n ) : (\n <Copy className=\"size-3.5\" aria-hidden />\n )}\n </button>\n </div>\n );\n}\n\nexport function ProviderCredentialRow({\n row,\n value,\n rowDirty,\n labels,\n language,\n onChange,\n onReload,\n justSaved,\n availableModels,\n}: {\n row: ProviderRowModel;\n value: string;\n rowDirty: boolean;\n labels: ProvidersSettingsMessages;\n language: StoredLanguage;\n onChange: (id: string, v: string) => void;\n onReload: () => void;\n justSaved: boolean;\n availableModels: ConfiguredModel[];\n}) {\n const [expanded, setExpanded] = useState(false);\n const [showKey, setShowKey] = useState(false);\n const [copied, setCopied] = useState(false);\n const [revokeError, setRevokeError] = useState<string | null>(null);\n const [removeLoading, setRemoveLoading] = useState(false);\n const [removeMessage, setRemoveMessage] = useState<string | null>(null);\n const [removeConfirmOpen, setRemoveConfirmOpen] = useState(false);\n const masked = isMaskedKey(value);\n const inputValue = masked && !showKey ? '' : value;\n const isOAuthConfigured = row.configured && !masked && Boolean(value);\n\n const [oauthLoading, setOauthLoading] = useState(false);\n const [sessionId, setSessionId] = useState<string | undefined>();\n const [oauthStatus, setOauthStatus] = useState<\n 'idle' | 'waiting' | 'waiting_code' | 'success' | 'error' | undefined\n >();\n const [oauthMessage, setOauthMessage] = useState<string | undefined>();\n const [authUrl, setAuthUrl] = useState<string | undefined>();\n const [instructions, setInstructions] = useState<string | undefined>();\n const [codeInput, setCodeInput] = useState('');\n\n const [testLoading, setTestLoading] = useState(false);\n const [testMessage, setTestMessage] = useState<string | null>(null);\n const [testOk, setTestOk] = useState<boolean | null>(null);\n\n const activeSrc = row.activeKeySource ?? 'none';\n\n const apiKeyLinks = useMemo(() => getOrderedApiKeyLinks(row.id, language), [row.id, language]);\n\n useEffect(() => {\n return () => {\n if (sessionId) {\n void cleanupOAuthSession(sessionId).catch(() => {});\n }\n };\n }, [sessionId]);\n\n useEffect(() => {\n if (!sessionId || !oauthLoading) return;\n const id = window.setInterval(() => {\n void (async () => {\n try {\n const st = await fetchOAuthSessionStatus(sessionId);\n setOauthMessage(st.message);\n setAuthUrl(st.authUrl);\n setInstructions(st.instructions);\n if (st.status === 'waiting_auth' || st.status === 'waiting_code') {\n setOauthStatus(st.status === 'waiting_code' ? 'waiting_code' : 'waiting');\n } else if (st.status === 'completed') {\n window.clearInterval(id);\n setOauthLoading(false);\n setOauthStatus('success');\n setOauthMessage(st.message);\n window.setTimeout(() => onReload(), 800);\n } else if (st.status === 'failed' || st.status === 'cancelled') {\n window.clearInterval(id);\n setOauthLoading(false);\n setOauthStatus('error');\n setOauthMessage(st.error || st.message || 'OAuth failed');\n }\n } catch {\n /* ignore poll errors */\n }\n })();\n }, 1000);\n return () => window.clearInterval(id);\n }, [sessionId, oauthLoading, onReload]);\n\n const startOAuth = async () => {\n setOauthLoading(true);\n setOauthStatus('waiting');\n setOauthMessage(labels.oauthStarting);\n setSessionId(undefined);\n setAuthUrl(undefined);\n setInstructions(undefined);\n try {\n const res = await startAsyncOAuthLogin(row.id);\n setSessionId(res.sessionId);\n } catch (e) {\n setOauthStatus('error');\n setOauthMessage(e instanceof Error ? e.message : 'OAuth failed');\n setOauthLoading(false);\n }\n };\n\n const cancelFlow = async () => {\n if (!sessionId) return;\n try {\n await cancelOAuth(sessionId);\n } catch {\n /* ignore */\n }\n setSessionId(undefined);\n setOauthLoading(false);\n setOauthStatus('idle');\n setOauthMessage(undefined);\n };\n\n const submitCode = async () => {\n if (!sessionId || !codeInput.trim()) return;\n try {\n await submitOAuthCode(sessionId, codeInput.trim());\n setCodeInput('');\n setOauthMessage(labels.oauthProcessingCode);\n } catch (e) {\n setOauthStatus('error');\n setOauthMessage(e instanceof Error ? e.message : 'Failed');\n }\n };\n\n const doRevoke = () => {\n if (!window.confirm(interpolate(labels.revokeConfirm, { name: row.name }))) return;\n setRevokeError(null);\n void revokeOAuth(row.id)\n .then(() => onReload())\n .catch((e) => setRevokeError(e instanceof Error ? e.message : labels.revokeFailed));\n };\n\n const doRemoveKey = async () => {\n setRemoveConfirmOpen(false);\n setRemoveLoading(true);\n setRemoveMessage(null);\n try {\n await deleteProviderApiKey(row.id);\n setRemoveMessage(labels.removeKeySuccess);\n onChange(row.id, '');\n window.setTimeout(() => onReload(), 600);\n } catch (error) {\n setRemoveMessage(error instanceof Error ? error.message : labels.removeKeyFailed);\n } finally {\n setRemoveLoading(false);\n }\n };\n\n const canRemoveKey =\n row.configured && masked && activeSrc !== 'env' && activeSrc !== 'extension' && activeSrc !== 'models_json';\n\n const copyKey = async () => {\n if (!value || masked) return;\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n } catch {\n /* ignore */\n }\n };\n\n const runTest = async () => {\n const v = value.trim();\n if (!v || isMaskedKey(v)) return;\n setTestLoading(true);\n setTestMessage(null);\n setTestOk(null);\n try {\n const res = await testProviderKeyResolution(v);\n if (res.error) {\n setTestOk(false);\n setTestMessage(`${labels.testFailed} ${res.error}`);\n return;\n }\n setTestOk(true);\n if (res.type === 'env') setTestMessage(labels.testOkEnv);\n else if (res.type === 'command') setTestMessage(labels.testOkCommand);\n else setTestMessage(labels.testOkLiteral);\n } catch (e) {\n setTestOk(false);\n setTestMessage(e instanceof Error ? e.message : labels.testFailed);\n } finally {\n setTestLoading(false);\n }\n };\n\n const secondaryLine = rowDirty\n ? labels.metaWillSave\n : row.configured\n ? masked\n ? `${labels.metaMasked} · ${labels.runtimeLabelPrefix} ${activeSourceLabel(labels, activeSrc)}`\n : `${labels.runtimeLabelPrefix} ${activeSourceLabel(labels, activeSrc)}`\n : labels.metaNotConfigured;\n\n const detailsId = `provider-details-${row.id}`;\n\n return (\n <div className=\"bg-surface-panel\">\n <div className=\"flex items-center gap-3 px-3 py-3 sm:px-4\">\n <div\n className=\"flex size-8 shrink-0 items-center justify-center rounded-md bg-surface-hover/80 dark:bg-surface-hover/50\"\n aria-hidden\n >\n {row.configured ? (\n <CheckCircle2 className=\"size-4 text-emerald-600 dark:text-emerald-400\" />\n ) : (\n <KeyRound className=\"size-4 text-fg-subtle\" strokeWidth={1.75} />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{row.name}</span>\n <ProviderInfoPopover providerId={row.id} language={language} />\n <span className=\"rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {row.id}\n </span>\n <span className=\"rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {row.category}\n </span>\n </div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{secondaryLine}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n aria-expanded={expanded}\n aria-controls={detailsId}\n aria-label={labels.expandRowDetails}\n onClick={() => setExpanded((e) => !e)}\n >\n <ChevronDown className={cn('size-4 transition-transform', expanded && 'rotate-180')} aria-hidden />\n </Button>\n </div>\n\n {expanded ? (\n <div\n id={detailsId}\n role=\"region\"\n className=\"space-y-3 border-t border-edge-subtle bg-surface-base/40 px-3 py-3 dark:bg-surface-base/20 sm:px-4\"\n >\n {row.supportsApiKey !== false ? (\n <div className=\"flex flex-col gap-2\">\n <div className=\"relative flex flex-col gap-2 sm:flex-row sm:gap-2\">\n <div className=\"relative min-w-0 flex-1\">\n <input\n type={showKey || !masked ? 'text' : 'password'}\n className={cn(\n 'w-full rounded-lg border border-edge bg-surface-panel py-2 pl-3 pr-20 font-mono text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n value={inputValue}\n placeholder={\n masked ? labels.placeholderOverride : row.configured ? labels.placeholderKeep : labels.placeholderKey\n }\n disabled={oauthLoading}\n onChange={(e) => onChange(row.id, e.target.value)}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <div className=\"absolute right-1 top-1/2 flex -translate-y-1/2 gap-0.5\">\n {value && !masked ? (\n <button\n type=\"button\"\n className={cn(\n 'rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg',\n interaction.transition,\n interaction.press,\n interaction.focusRingPanel,\n )}\n title={copied ? labels.copied : labels.copy}\n aria-label={copied ? labels.copied : labels.copy}\n onClick={() => void copyKey()}\n >\n {copied ? <CheckCircle2 className=\"size-4\" /> : <Copy className=\"size-4\" />}\n </button>\n ) : null}\n <button\n type=\"button\"\n className={cn(\n 'rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg disabled:opacity-40',\n interaction.transition,\n interaction.press,\n interaction.focusRingPanel,\n )}\n title={showKey ? labels.hide : labels.show}\n aria-label={showKey ? labels.hide : labels.show}\n disabled={masked}\n onClick={() => setShowKey((s) => !s)}\n >\n {showKey ? <EyeOff className=\"size-4\" /> : <Eye className=\"size-4\" />}\n </button>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2 sm:shrink-0\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1\"\n disabled={oauthLoading || testLoading || !value.trim() || isMaskedKey(value)}\n onClick={() => void runTest()}\n >\n {testLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : null}\n {testLoading ? labels.testingKey : labels.testKey}\n </Button>\n {row.supportsOAuth ? (\n isOAuthConfigured ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1 text-red-600 dark:text-red-400\"\n onClick={doRevoke}\n >\n <LogOut className=\"size-4\" aria-hidden />\n {labels.revoke}\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1\"\n disabled={oauthLoading}\n onClick={() => void startOAuth()}\n >\n {oauthLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : <LogIn className=\"size-4\" aria-hidden />}\n {labels.oauth}\n </Button>\n )\n ) : null}\n {canRemoveKey ? (\n <>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1 text-red-600 dark:text-red-400\"\n disabled={removeLoading}\n onClick={() => setRemoveConfirmOpen(true)}\n >\n {removeLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : <Trash2 className=\"size-4\" aria-hidden />}\n {labels.removeKey}\n </Button>\n <ConfirmDialog\n open={removeConfirmOpen}\n title={labels.removeKey}\n description={interpolate(labels.removeKeyConfirm, { name: row.name })}\n confirmLabel={labels.removeKey}\n cancelLabel={labels.cancelOAuth}\n destructive\n onConfirm={() => void doRemoveKey()}\n onCancel={() => setRemoveConfirmOpen(false)}\n />\n </>\n ) : null}\n </div>\n </div>\n {testMessage ? (\n <p\n className={cn(\n 'text-xs',\n testOk === false ? 'text-red-600 dark:text-red-400' : 'text-fg-muted',\n )}\n role=\"status\"\n >\n {testMessage}\n </p>\n ) : null}\n {apiKeyLinks.length > 0 ? (\n <div className=\"flex flex-col gap-1\">\n {apiKeyLinks.map((link) => (\n <a\n key={`${link.kind}-${link.href}`}\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex w-fit items-center gap-1 text-xs font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {providerApiKeyLinkLabel(link.kind, labels)}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {oauthMessage ? (\n <div\n className={cn(\n 'flex gap-2 rounded-md px-3 py-2 text-xs',\n oauthStatus === 'error'\n ? 'border border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400'\n : 'bg-surface-base text-fg-muted',\n )}\n >\n {oauthStatus === 'error' ? (\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n ) : oauthStatus === 'success' ? (\n <CheckCircle2 className=\"mt-0.5 size-4 shrink-0 text-emerald-600\" aria-hidden />\n ) : (\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n )}\n <span>{oauthMessage}</span>\n </div>\n ) : null}\n\n {revokeError ? (\n <div\n className=\"flex gap-2 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400\"\n role=\"alert\"\n >\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{revokeError}</span>\n </div>\n ) : null}\n\n {removeMessage ? (\n <div\n className={cn(\n 'flex gap-2 rounded-md px-3 py-2 text-xs',\n removeMessage === labels.removeKeySuccess\n ? 'bg-surface-hover/60 text-fg-muted dark:bg-surface-hover/40'\n : 'border border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400',\n )}\n role=\"status\"\n >\n {removeMessage === labels.removeKeySuccess ? (\n <CheckCircle2 className=\"mt-0.5 size-4 shrink-0 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n ) : (\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n )}\n <span>{removeMessage}</span>\n </div>\n ) : null}\n\n {(oauthStatus === 'waiting' || oauthStatus === 'waiting_code') && (\n <div className=\"flex flex-wrap gap-2\">\n {authUrl ? (\n <a\n href={authUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-medium text-white hover:bg-accent-hover\"\n >\n <ExternalLink className=\"size-4\" aria-hidden />\n {labels.openAuthPage}\n </a>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" className=\"gap-1\" onClick={() => void cancelFlow()}>\n <X className=\"size-4\" aria-hidden />\n {labels.cancelOAuth}\n </Button>\n </div>\n )}\n\n {instructions ? (\n <div className=\"flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{instructions}</span>\n </div>\n ) : null}\n\n {oauthStatus === 'waiting_code' ? (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n className={cn(\n 'min-w-0 flex-1 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n value={codeInput}\n placeholder={labels.pasteRedirectUrl}\n onChange={(e) => setCodeInput(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && void submitCode()}\n />\n <Button type=\"button\" variant=\"primary\" className=\"shrink-0\" onClick={() => void submitCode()}>\n {labels.submitCode}\n </Button>\n </div>\n ) : null}\n\n {masked ? (\n <div className=\"flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{activeSrc === 'env' ? labels.envHint : labels.maskedStoredHint}</span>\n </div>\n ) : null}\n\n {row.supportsOAuth && !masked && !isOAuthConfigured ? (\n <p className=\"text-xs text-fg-subtle\">{labels.oauthHint}</p>\n ) : null}\n\n {justSaved ? (\n <div className=\"flex items-start gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <CheckCircle2 className=\"mt-0.5 size-3.5 shrink-0 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n <span>\n {(() => {\n const providerModels = availableModels.filter((m) => m.provider === row.id);\n if (providerModels.length === 0) return labels.savedNoModels;\n const preview = providerModels\n .slice(0, 3)\n .map((m) => m.name || m.id)\n .join(', ');\n const suffix = providerModels.length > 3 ? `… (+${providerModels.length - 3})` : '';\n return `${providerModels.length} ${labels.savedModelsAvailable}: ${preview}${suffix}`;\n })()}\n </span>\n </div>\n ) : null}\n\n {(PROVIDER_ENRICHMENT[row.id]?.envVars ?? []).length > 0 ? (\n <details>\n <summary className=\"cursor-pointer select-none list-none text-xs text-fg-subtle hover:text-fg-muted\">\n {labels.envVarAlt}\n </summary>\n <div className=\"mt-1.5 flex flex-col gap-1\">\n {(PROVIDER_ENRICHMENT[row.id]?.envVars ?? []).map((envVar) => (\n <EnvVarCopyRow key={envVar} envVar={envVar} labels={labels} />\n ))}\n </div>\n </details>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import {\n CheckCircle2,\n ChevronDown,\n KeyRound,\n Search,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { CONFIGURED_MODELS_SWR_KEY, fetchConfiguredModelsCached } from '@/features/chat/registry-api';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n isMaskedKey,\n mergeProviderRows,\n patchProviderApiKeys,\n providersKeysFromConfigRoot,\n type ProviderMeta,\n type ProviderRowModel,\n} from '@/features/settings/providers-api';\nimport { PROVIDER_ENRICHMENT } from '@/features/settings/provider-enrichment';\nimport { ProviderCredentialRow } from './provider-credential-row';\nimport { CATEGORY_ORDER, groupByCategory, interpolate } from './providers-settings-lib';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nexport function ProvidersSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const p = m.providersSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [draft, setDraft] = useState<Record<string, string>>({});\n const [baseline, setBaseline] = useState<Record<string, string>>({});\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveNotice, setSaveNotice] = useState<null | 'saved' | 'noChanges'>(null);\n const [expandedCats, setExpandedCats] = useState<Set<string>>(() => new Set(['common']));\n const [searchQuery, setSearchQuery] = useState('');\n const [unconfiguredOnly, setUnconfiguredOnly] = useState(false);\n const [savedProviderIds, setSavedProviderIds] = useState<Set<string>>(() => new Set());\n const prevSearchRef = useRef('');\n\n const metaUrl = apiUrl('/api/providers/meta');\n const fetchMetaList = useCallback(async (url: string) => {\n const data = await fetchJson<{ ok?: boolean; payload?: { providers?: ProviderMeta[] } }>(url);\n return data.payload?.providers ?? [];\n }, []);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: metaList,\n error: metaErr,\n isLoading: metaLoading,\n mutate: mutMeta,\n } = useSWR(hasToken ? metaUrl : null, fetchMetaList, { revalidateOnFocus: false });\n const { data: models, mutate: mutModels } = useSWR(\n hasToken ? CONFIGURED_MODELS_SWR_KEY : null,\n () => fetchConfiguredModelsCached(),\n { revalidateOnFocus: false },\n );\n\n const mergedRows = useMemo((): ProviderRowModel[] | null => {\n if (!metaList || cfgData === undefined) return null;\n const keys = providersKeysFromConfigRoot(cfgData.payload?.config);\n return mergeProviderRows(metaList, keys, models ?? []);\n }, [metaList, cfgData, models]);\n\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : metaErr instanceof Error\n ? metaErr.message\n : metaErr\n ? String(metaErr)\n : null;\n\n const loading = Boolean(\n hasToken && mergedRows === null && (cfgLoading || metaLoading) && !fetchError,\n );\n\n const dirty = useMemo(\n () => JSON.stringify(draft) !== JSON.stringify(baseline),\n [draft, baseline],\n );\n\n useEffect(() => {\n if (!dirty) return;\n const onBeforeUnload = (e: BeforeUnloadEvent) => {\n e.preventDefault();\n e.returnValue = '';\n };\n window.addEventListener('beforeunload', onBeforeUnload);\n return () => window.removeEventListener('beforeunload', onBeforeUnload);\n }, [dirty]);\n\n useEffect(() => {\n if (!hasToken || mergedRows === null) return;\n if (!dirty) {\n const d: Record<string, string> = {};\n for (const r of mergedRows) d[r.id] = r.apiKey;\n setDraft(d);\n setBaseline({ ...d });\n }\n }, [hasToken, mergedRows, dirty]);\n\n const metaRows = mergedRows ?? [];\n\n const filteredRows = useMemo(() => {\n let rows = metaRows;\n const q = searchQuery.trim().toLowerCase();\n if (q) {\n rows = rows.filter((r) => {\n const enrichment = PROVIDER_ENRICHMENT[r.id];\n const aliases = enrichment?.aliases ?? [];\n return (\n r.id.toLowerCase().includes(q) ||\n r.name.toLowerCase().includes(q) ||\n aliases.some((alias) => alias.toLowerCase().includes(q))\n );\n });\n }\n if (unconfiguredOnly) {\n rows = rows.filter((r) => !r.configured);\n }\n return rows;\n }, [metaRows, searchQuery, unconfiguredOnly]);\n\n const groups = useMemo(() => groupByCategory(filteredRows), [filteredRows]);\n\n useEffect(() => {\n const prev = prevSearchRef.current;\n prevSearchRef.current = searchQuery;\n if (searchQuery.trim()) {\n const next = new Set<string>();\n for (const c of CATEGORY_ORDER) {\n if ((groups.get(c) ?? []).length > 0) next.add(c);\n }\n setExpandedCats(next);\n return;\n }\n if (prev.trim()) {\n setExpandedCats(new Set(['common']));\n }\n }, [searchQuery, groups]);\n\n const save = useCallback(async () => {\n if (saving) return;\n const toPatch: Record<string, string> = {};\n for (const id of Object.keys(draft)) {\n const v = draft[id]?.trim() ?? '';\n if (!v || isMaskedKey(v)) continue;\n toPatch[id] = v;\n }\n if (Object.keys(toPatch).length === 0) {\n setBaseline({ ...draft });\n setSaveNotice('noChanges');\n window.setTimeout(() => setSaveNotice(null), 2500);\n return;\n }\n setSaving(true);\n setError(null);\n setSaveNotice(null);\n try {\n await patchProviderApiKeys(toPatch);\n setSavedProviderIds(new Set(Object.keys(toPatch)));\n const freshModels = (await mutModels(fetchConfiguredModelsCached(true))) ?? models ?? [];\n const [nextCfg, nextMeta] = await Promise.all([mutCfg(), mutMeta()]);\n const list = Array.isArray(nextMeta) ? nextMeta : metaList ?? [];\n const cfg = nextCfg ?? cfgData;\n if (cfg?.payload) {\n const keys = providersKeysFromConfigRoot(cfg.payload.config);\n const rows = mergeProviderRows(list, keys, freshModels);\n const d: Record<string, string> = {};\n for (const r of rows) d[r.id] = r.apiKey;\n setDraft(d);\n setBaseline({ ...d });\n }\n setSaveNotice('saved');\n window.setTimeout(() => setSaveNotice(null), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : p.saveError);\n } finally {\n setSaving(false);\n }\n }, [cfgData, draft, metaList, models, mutCfg, mutMeta, mutModels, p.saveError, saving]);\n\n const discard = useCallback(() => {\n setDraft({ ...baseline });\n setError(null);\n setSaveNotice(null);\n setSavedProviderIds(new Set());\n }, [baseline]);\n\n const toggleCat = (cat: string) => {\n setExpandedCats((prev) => {\n const next = new Set(prev);\n if (next.has(cat)) next.delete(cat);\n else next.add(cat);\n return next;\n });\n };\n\n const refreshProviders = useCallback(() => {\n void mutCfg();\n void mutMeta();\n }, [mutCfg, mutMeta]);\n\n const filtersActive = Boolean(searchQuery.trim() || unconfiguredOnly);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <div className=\"flex items-start gap-3 rounded-2xl bg-surface-base p-6\">\n <KeyRound className=\"mt-0.5 size-5 shrink-0 text-fg-subtle\" strokeWidth={1.75} />\n <div>\n <h1 className=\"text-base font-semibold text-fg\">{m.settingsSections.providers}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{p.needToken}</p>\n </div>\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-8\">\n <div className=\"h-8 w-48 animate-pulse rounded bg-surface-hover\" />\n <div className=\"mt-6 h-32 animate-pulse rounded-xl bg-surface-hover\" />\n <p className=\"mt-4 text-sm text-fg-muted\">{m.logs.loading}</p>\n </div>\n );\n }\n\n if (metaRows.length === 0) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <div className=\"rounded-xl border border-edge-subtle bg-surface-base px-4 py-3\">\n <p className=\"text-sm font-medium text-fg\">{p.loadError}</p>\n <p className=\"mt-1 text-sm text-fg-muted\">{error ?? fetchError ?? p.empty}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutMeta();\n }}\n >\n {m.logs.refresh}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.providers}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{p.subtitle}</p>\n <p className=\"mt-2 text-xs text-fg-subtle\">{p.rotateHint}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {saveNotice === 'saved' ? <span className=\"text-sm text-fg-muted\">{p.saved}</span> : null}\n {saveNotice === 'noChanges' ? <span className=\"text-sm text-fg-muted\">{p.noChangesSaved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {p.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? p.saving : p.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{p.unsavedHint}</p> : null}\n\n <p className=\"text-sm leading-relaxed text-fg-muted\">\n {p.intro}{' '}\n <a\n href={docsGuidePageUrl(language, 'models')}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {p.docsLink}\n </a>\n {' · '}\n <Link\n to=\"/settings/models\"\n className=\"font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {p.modelsLink}\n </Link>\n </p>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center\">\n <div className=\"relative min-w-0 flex-1 sm:max-w-md\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-subtle\"\n strokeWidth={1.75}\n aria-hidden\n />\n <input\n type=\"search\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={p.searchPlaceholder}\n autoComplete=\"off\"\n className={cn(\n 'w-full rounded-lg border border-edge bg-surface-panel py-2 pl-10 pr-3 text-sm text-fg placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n aria-label={p.searchPlaceholder}\n />\n </div>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg-muted\">\n <input\n type=\"checkbox\"\n checked={unconfiguredOnly}\n onChange={(e) => setUnconfiguredOnly(e.target.checked)}\n className=\"size-4 rounded border-edge text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n />\n {p.unconfiguredOnly}\n </label>\n {filtersActive ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-fit self-start text-fg-muted\"\n onClick={() => {\n setSearchQuery('');\n setUnconfiguredOnly(false);\n }}\n >\n {p.clearFilters}\n </Button>\n ) : null}\n </div>\n\n {error ? (\n <div\n className=\"rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : null}\n\n {filteredRows.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-edge-subtle bg-surface-base px-4 py-8 text-center text-sm text-fg-muted\">\n <p>{p.noMatches}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"mt-4\"\n onClick={() => {\n setSearchQuery('');\n setUnconfiguredOnly(false);\n }}\n >\n {p.clearFilters}\n </Button>\n </div>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {CATEGORY_ORDER.map((cat) => {\n const list = groups.get(cat) ?? [];\n if (list.length === 0) return null;\n const expanded = expandedCats.has(cat);\n const configuredCount = list.filter((r) => r.configured).length;\n const panelId = `providers-cat-${cat}`;\n return (\n <section key={cat} className=\"overflow-hidden rounded-2xl bg-surface-base\">\n <button\n type=\"button\"\n id={`${panelId}-trigger`}\n aria-expanded={expanded}\n aria-controls={panelId}\n className=\"flex w-full items-center justify-between gap-2 border-b border-edge-subtle px-4 py-3 text-left transition-colors hover:bg-surface-hover/60 dark:border-edge-subtle\"\n onClick={() => toggleCat(cat)}\n >\n <span className=\"flex min-w-0 items-center gap-2 text-sm font-semibold text-fg\">\n <span className=\"truncate\">{p.categories[cat]}</span>\n <span className=\"shrink-0 rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {list.length}\n </span>\n </span>\n <span className=\"flex shrink-0 items-center gap-2\">\n {configuredCount > 0 ? (\n <span className=\"flex items-center gap-1 text-xs text-fg-subtle\">\n <CheckCircle2 className=\"size-3.5 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n {interpolate(p.configuredCount, { count: String(configuredCount) })}\n </span>\n ) : null}\n <ChevronDown\n className={cn('size-4 text-fg-subtle transition-transform', expanded && 'rotate-180')}\n aria-hidden\n />\n </span>\n </button>\n {expanded ? (\n <div id={panelId} role=\"region\" aria-labelledby={`${panelId}-trigger`} className=\"divide-y divide-edge-subtle\">\n {list.map((row) => (\n <div id={`provider-row-${row.id}`} key={row.id}>\n <ProviderCredentialRow\n row={row}\n value={draft[row.id] ?? ''}\n rowDirty={(draft[row.id] ?? '') !== (baseline[row.id] ?? '')}\n labels={p}\n language={language}\n onChange={(id, v) => setDraft((d) => ({ ...d, [id]: v }))}\n onReload={refreshProviders}\n justSaved={savedProviderIds.has(row.id)}\n availableModels={models ?? []}\n />\n </div>\n ))}\n </div>\n ) : null}\n </section>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { ExternalLink, Shield } from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { SettingsFormSection, settingsFormSectionClassName } from '@/features/settings/settings-form-section';\nimport { isElectron } from '@/lib/electron-env';\nimport type { StoredLanguage } from '@/lib/storage';\nimport { messages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport type { PrivacyPaneKind, ShellPermissionSnapshot, SystemSettingsBehavior, TccTriState } from '@/types/electron';\n\nconst PERM_ROWS: { key: keyof ShellPermissionSnapshot; pane: PrivacyPaneKind }[] = [\n { key: 'fullDisk', pane: 'fullDisk' },\n { key: 'screen', pane: 'screen' },\n { key: 'microphone', pane: 'microphone' },\n { key: 'accessibility', pane: 'accessibility' },\n { key: 'automation', pane: 'automation' },\n { key: 'notifications', pane: 'notifications' },\n { key: 'location', pane: 'location' },\n];\n\nfunction triStateFromMessages(\n lang: StoredLanguage,\n s: TccTriState,\n): { label: string; className: string } {\n const m = messages(lang).systemSettings.status;\n if (s === 'granted') {\n return { label: m.granted, className: 'text-emerald-600 dark:text-emerald-400' };\n }\n if (s === 'denied') {\n return { label: m.denied, className: 'text-amber-600 dark:text-amber-400' };\n }\n return { label: m.unknown, className: 'text-fg-muted' };\n}\n\nexport function SystemSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.systemSettings;\n\n const [behavior, setBehavior] = useState<SystemSettingsBehavior | null>(null);\n const [perms, setPerms] = useState<ShellPermissionSnapshot | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n\n const api = typeof window !== 'undefined' ? window.electronAPI?.system : undefined;\n\n const load = useCallback(async () => {\n if (!api) {\n return;\n }\n setLoadError(null);\n try {\n const b = await api.getBehavior();\n setBehavior(b);\n setPerms(await api.getPermissions());\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n }, [api]);\n\n useEffect(() => {\n if (isElectron() && api) {\n void load();\n }\n }, [api, load]);\n\n if (!isElectron() || !api) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n <div className={settingsFormSectionClassName()}>\n <p className=\"text-sm font-medium text-fg\">{t.desktopOnlyTitle}</p>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.desktopOnlyBody}</p>\n </div>\n </div>\n );\n }\n\n const patchBehavior = async (patch: {\n openAtLogin?: boolean;\n keepAwakePreferred?: boolean;\n notifyEnabled?: boolean;\n notifySoundEnabled?: boolean;\n }) => {\n try {\n const { behavior: next } = await api.setBehavior(patch);\n setBehavior(next);\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n };\n\n const openPrivacy = async (kind: PrivacyPaneKind) => {\n try {\n const r = await api.openPrivacy(kind);\n if (!r.ok) {\n setLoadError('open_privacy failed');\n }\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n };\n\n const permissionsHint = (() => {\n if (!behavior) {\n return t.permissionsHint;\n }\n if (behavior.platform === 'win32') {\n return t.permissionsHintWin;\n }\n if (behavior.platform === 'linux') {\n return t.permissionsHintLinux;\n }\n if (behavior.platform === 'darwin') {\n return t.permissionsHintDarwin;\n }\n return t.permissionsHint;\n })();\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <div>\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n </div>\n\n {loadError ? (\n <p className=\"text-sm text-amber-600 dark:text-amber-400\" role=\"alert\">\n {loadError}\n </p>\n ) : null}\n\n <SettingsFormSection>\n <div className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-fg\">\n <Shield className=\"size-4 text-accent\" strokeWidth={1.75} />\n {t.behaviorGroup}\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.openAtLogin}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.openAtLoginDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.openAtLogin)}\n onChange={(e) => {\n void patchBehavior({ openAtLogin: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.keepAwake}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.keepAwakeDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.keepAwakePreferred)}\n onChange={(e) => {\n void patchBehavior({ keepAwakePreferred: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.notifyDesktop}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.notifyDesktopDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.notifyEnabled)}\n onChange={(e) => {\n void patchBehavior({ notifyEnabled: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.notifySound}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.notifySoundDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.notifySoundEnabled)}\n onChange={(e) => {\n void patchBehavior({ notifySoundEnabled: e.target.checked });\n }}\n />\n </div>\n </div>\n </SettingsFormSection>\n\n {behavior && perms ? (\n <section className={settingsFormSectionClassName()}>\n <div className=\"mb-4 flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-sm font-semibold text-fg\">{t.permissionsTitle}</h2>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{permissionsHint}</p>\n </div>\n <button\n type=\"button\"\n className=\"mt-2 inline-flex max-w-full items-center justify-center rounded-lg border border-edge bg-surface-panel px-3 py-1.5 text-sm font-medium text-fg transition-colors hover:bg-surface-hover sm:mt-0\"\n onClick={() => void load()}\n >\n {t.refresh}\n </button>\n </div>\n <ul className=\"space-y-3\">\n {PERM_ROWS.map(({ key, pane }) => {\n const st = triStateFromMessages(language, perms[key]);\n const permLabel = t.perm[key];\n if (!permLabel) {\n return null;\n }\n return (\n <li\n key={key}\n className=\"flex flex-col gap-2 rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-3 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm font-medium text-fg\">{permLabel.title}</div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{permLabel.desc}</p>\n <p className={`mt-1 text-xs font-medium ${st.className}`}>{st.label}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {key === 'microphone' && behavior?.platform === 'darwin' ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover\"\n onClick={() => {\n void (async () => {\n try {\n await api.requestMicrophone();\n setPerms(await api.getPermissions());\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n })();\n }}\n >\n {language === 'zh' ? '请求访问' : 'Request'}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover\"\n onClick={() => void openPrivacy(pane)}\n >\n {t.openSettings}\n <ExternalLink className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n </section>\n ) : null}\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type { SttSettings, TtsSettings, VoiceModelsPayload, VoiceSettingsState } from './voice-settings.types';\n\nexport type { SttSettings, TtsSettings, VoiceModelsPayload, VoiceSettingsState } from './voice-settings.types';\n\nfunction defaultStt(): SttSettings {\n return {\n enabled: false,\n provider: 'alibaba',\n alibaba: { model: 'paraformer-v2' },\n openai: { model: 'whisper-1' },\n fallback: { enabled: true, order: ['alibaba', 'openai'] },\n };\n}\n\n// Defaults intentionally mirror src/config/schema.ts (TTSConfigSchema /\n// TTSEdgeConfigSchema) and extensions/tts-local-cli/xopc.extension.json so a\n// PATCH /api/config round-trip never silently overrides backend defaults.\nfunction defaultTts(): TtsSettings {\n return {\n enabled: false,\n provider: 'openai',\n trigger: 'always',\n maxTextLength: 512,\n timeoutMs: 60000,\n alibaba: { model: 'qwen-tts', voice: 'Cherry' },\n openai: { model: 'tts-1', voice: 'alloy' },\n edge: { voice: 'en-US-MichelleNeural' },\n minimax: { model: 'speech-2.8-hd', voice: 'male-qn-qingse' },\n 'tts-local-cli': {\n command: '',\n outputFormat: 'wav',\n },\n };\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction mergeStt(raw: unknown): SttSettings {\n const d = defaultStt();\n if (!isRecord(raw)) return d;\n const provider = raw.provider === 'openai' ? 'openai' : 'alibaba';\n const alibaba = isRecord(raw.alibaba) ? { ...d.alibaba, ...raw.alibaba } : d.alibaba;\n const openai = isRecord(raw.openai) ? { ...d.openai, ...raw.openai } : d.openai;\n const baseFallback = d.fallback ?? { enabled: true, order: ['alibaba', 'openai'] as const };\n let fallback = baseFallback;\n if (isRecord(raw.fallback)) {\n const order = Array.isArray(raw.fallback.order)\n ? (raw.fallback.order.filter((x) => x === 'alibaba' || x === 'openai') as ('alibaba' | 'openai')[])\n : fallback.order;\n fallback = {\n enabled: typeof raw.fallback.enabled === 'boolean' ? raw.fallback.enabled : fallback.enabled,\n order: order.length ? order : fallback.order,\n };\n }\n return {\n enabled: Boolean(raw.enabled),\n provider,\n alibaba,\n openai,\n fallback,\n };\n}\n\n/** Provider id is open string — extension SpeechProviderPlugins (e.g. tts-local-cli) are allowed. */\nfunction normalizeTtsProvider(v: unknown): string {\n return typeof v === 'string' && v.trim().length > 0 ? v.trim() : 'openai';\n}\n\nfunction mergeTts(raw: unknown): TtsSettings {\n const d = defaultTts();\n if (!isRecord(raw)) return d;\n const provider = normalizeTtsProvider(raw.provider);\n const trigger =\n raw.trigger === 'off' ||\n raw.trigger === 'always' ||\n raw.trigger === 'inbound' ||\n raw.trigger === 'tagged'\n ? raw.trigger\n : 'always';\n // Per-provider buckets: keep built-in defaults, plus passthrough for any\n // extension-provider key (e.g. `tts-local-cli`) so unknown plugins survive\n // a round-trip through the UI without losing their config.\n const localCliRaw = raw['tts-local-cli'];\n return {\n enabled: Boolean(raw.enabled),\n provider,\n trigger,\n maxTextLength:\n typeof raw.maxTextLength === 'number' && Number.isFinite(raw.maxTextLength)\n ? raw.maxTextLength\n : d.maxTextLength,\n timeoutMs:\n typeof raw.timeoutMs === 'number' && Number.isFinite(raw.timeoutMs) ? raw.timeoutMs : d.timeoutMs,\n alibaba: isRecord(raw.alibaba) ? { ...d.alibaba, ...raw.alibaba } : d.alibaba,\n openai: isRecord(raw.openai) ? { ...d.openai, ...raw.openai } : d.openai,\n edge: isRecord(raw.edge) ? { ...d.edge, ...raw.edge } : d.edge,\n minimax: isRecord(raw.minimax) ? { ...d.minimax, ...raw.minimax } : d.minimax,\n 'tts-local-cli': isRecord(localCliRaw)\n ? { ...d['tts-local-cli'], ...localCliRaw }\n : d['tts-local-cli'],\n };\n}\n\nexport function normalizeVoiceSettings(config: unknown): VoiceSettingsState {\n const c = isRecord(config) ? config : {};\n return {\n stt: mergeStt(c.stt),\n tts: mergeTts(c.tts),\n };\n}\n\nexport async function fetchVoiceSettings(): Promise<VoiceSettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeVoiceSettings(res.payload?.config ?? {});\n}\n\nexport async function patchVoiceSettings(state: VoiceSettingsState): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({ stt: state.stt, tts: state.tts }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchVoiceModels(): Promise<VoiceModelsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: { models?: VoiceModelsPayload } }>(\n apiUrl('/api/voice/models'),\n );\n if (!res.payload?.models) {\n throw new Error('Missing voice models payload');\n }\n return res.payload.models;\n}\n","import { ExternalLink, Loader2, Mic, Volume2 } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n fetchVoiceModels,\n normalizeVoiceSettings,\n patchVoiceSettings,\n type VoiceModelsPayload,\n type VoiceSettingsState,\n} from '@/features/settings/voice-config-api';\nimport { apiUrl } from '@/lib/url';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type VoiceSettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst STT_ALIBABA_FALLBACK = [\n { id: 'paraformer-v2', name: 'Paraformer v2' },\n { id: 'paraformer-v1', name: 'Paraformer v1' },\n];\nconst STT_OPENAI_FALLBACK = [{ id: 'whisper-1', name: 'Whisper-1' }];\nconst TTS_OPENAI_MODELS_FALLBACK = [\n { id: 'tts-1', name: 'TTS-1' },\n { id: 'tts-1-hd', name: 'TTS-1 HD' },\n];\nconst TTS_OPENAI_VOICES_FALLBACK = [\n { id: 'alloy', name: 'Alloy' },\n { id: 'echo', name: 'Echo' },\n];\nconst TTS_ALIBABA_MODELS_FALLBACK = [\n { id: 'qwen-tts', name: 'Qwen TTS' },\n { id: 'qwen3-tts-flash', name: 'Qwen3 TTS Flash' },\n];\nconst TTS_ALIBABA_VOICES_FALLBACK = [\n { id: 'Cherry', name: 'Cherry' },\n { id: 'longxiaochun', name: 'Long Xiao Chun' },\n];\nconst TTS_EDGE_VOICES_FALLBACK = [\n { id: 'en-US-MichelleNeural', name: 'Michelle (US English)' },\n { id: 'zh-CN-XiaoxiaoNeural', name: 'Xiaoxiao (Chinese)' },\n];\nconst TTS_MINIMAX_MODELS_FALLBACK = [\n { id: 'speech-2.8-hd', name: 'Speech 2.8 HD (Recommended)' },\n { id: 'speech-2.8-turbo', name: 'Speech 2.8 Turbo (Fast)' },\n];\nconst TTS_MINIMAX_VOICES_FALLBACK = [\n { id: 'male-qn-qingse', name: 'Male Qingse (青涩男声)' },\n { id: 'female-shaonv', name: 'Female Shaonv (少女音)' },\n];\n\nexport function VoiceSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const v = m.voiceSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<VoiceSettingsState | null>(null);\n const [baseline, setBaseline] = useState<VoiceSettingsState | null>(null);\n const [models, setModels] = useState<VoiceModelsPayload | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: voiceModels,\n error: vmErr,\n isLoading: vmLoading,\n mutate: mutVm,\n } = useSWR(hasToken ? apiUrl('/api/voice/models') : null, fetchVoiceModels, { revalidateOnFocus: false });\n\n const voiceParsed = useMemo(\n () =>\n cfgData?.payload?.config !== undefined\n ? normalizeVoiceSettings(cfgData.payload.config)\n : null,\n [cfgData],\n );\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n setModels(null);\n return;\n }\n if (voiceParsed === null || voiceModels === undefined) return;\n if (!dirty) {\n setForm(structuredClone(voiceParsed));\n setBaseline(structuredClone(voiceParsed));\n setModels(voiceModels);\n setSaveOk(false);\n }\n }, [hasToken, voiceParsed, voiceModels, dirty]);\n\n const loading = Boolean(\n hasToken &&\n (voiceParsed === null || voiceModels === undefined) &&\n (cfgLoading || vmLoading),\n );\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : vmErr instanceof Error\n ? vmErr.message\n : vmErr\n ? String(vmErr)\n : null;\n\n const updateStt = useCallback((patch: Partial<VoiceSettingsState['stt']>) => {\n setForm((f) => (f ? { ...f, stt: { ...f.stt, ...patch } } : null));\n }, []);\n\n const updateSttAlibaba = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['alibaba']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n stt: { ...f.stt, alibaba: { ...f.stt.alibaba, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateSttOpenai = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['openai']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n stt: { ...f.stt, openai: { ...f.stt.openai, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateSttFallback = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['fallback']>>) => {\n setForm((f) => {\n if (!f) return null;\n const cur = f.stt.fallback ?? { enabled: true, order: ['alibaba', 'openai'] };\n return {\n ...f,\n stt: {\n ...f.stt,\n fallback: { ...cur, ...patch },\n },\n };\n });\n }, []);\n\n const updateTts = useCallback((patch: Partial<VoiceSettingsState['tts']>) => {\n setForm((f) => (f ? { ...f, tts: { ...f.tts, ...patch } } : null));\n }, []);\n\n const updateTtsAlibaba = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['alibaba']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, alibaba: { ...f.tts.alibaba, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsOpenai = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['openai']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, openai: { ...f.tts.openai, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsEdge = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['edge']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, edge: { ...f.tts.edge, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsMinimax = useCallback(\n (patch: Partial<NonNullable<VoiceSettingsState['tts']['minimax']>>) => {\n setForm((f) =>\n f ? { ...f, tts: { ...f.tts, minimax: { ...f.tts.minimax, ...patch } } } : null,\n );\n },\n [],\n );\n\n const updateTtsLocalCli = useCallback(\n (patch: Partial<NonNullable<VoiceSettingsState['tts']['tts-local-cli']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: {\n ...f.tts,\n 'tts-local-cli': { ...f.tts['tts-local-cli'], ...patch },\n },\n }\n : null,\n );\n },\n [],\n );\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchVoiceSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setForm(next);\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : v.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, v.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.voice}</h1>\n <p className=\"text-sm text-fg-muted\">{v.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {v.loading}\n </div>\n </div>\n );\n }\n\n if (!form || models === null) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? v.loadError}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutVm();\n }}\n >\n {v.retry}\n </Button>\n </div>\n );\n }\n\n const stt = form.stt;\n const tts = form.tts;\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.voice}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{v.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'voice')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {v.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{v.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {v.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? v.saving : v.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{v.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <div className=\"flex flex-col gap-4\">\n <SttSection\n v={v}\n stt={stt}\n models={models}\n updateStt={updateStt}\n updateSttAlibaba={updateSttAlibaba}\n updateSttOpenai={updateSttOpenai}\n updateSttFallback={updateSttFallback}\n />\n\n <TtsSection\n v={v}\n tts={tts}\n models={models}\n updateTts={updateTts}\n updateTtsAlibaba={updateTtsAlibaba}\n updateTtsOpenai={updateTtsOpenai}\n updateTtsEdge={updateTtsEdge}\n updateTtsMinimax={updateTtsMinimax}\n updateTtsLocalCli={updateTtsLocalCli}\n />\n </div>\n\n <div className=\"rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10\">\n <p className=\"text-sm text-fg\">\n <strong className=\"text-accent\">{v.notes.title}</strong> {v.notes.duration}\n </p>\n <p className=\"mt-2 text-xs text-fg-muted\">{v.notes.envVars}</p>\n </div>\n </div>\n );\n}\n\nfunction SttSection({\n v,\n stt,\n models,\n updateStt,\n updateSttAlibaba,\n updateSttOpenai,\n updateSttFallback,\n}: {\n v: VoiceSettingsMessages;\n stt: VoiceSettingsState['stt'];\n models: VoiceModelsPayload | null;\n updateStt: (p: Partial<VoiceSettingsState['stt']>) => void;\n updateSttAlibaba: (p: Partial<NonNullable<VoiceSettingsState['stt']['alibaba']>>) => void;\n updateSttOpenai: (p: Partial<NonNullable<VoiceSettingsState['stt']['openai']>>) => void;\n updateSttFallback: (p: Partial<NonNullable<VoiceSettingsState['stt']['fallback']>>) => void;\n}) {\n const alibabaModels = models?.stt?.alibaba?.length ? models.stt.alibaba : STT_ALIBABA_FALLBACK;\n const openaiModels = models?.stt?.openai?.length ? models.stt.openai : STT_OPENAI_FALLBACK;\n\n return (\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Mic className=\"size-4 text-accent\" strokeWidth={1.75} />\n {v.stt.title}\n </div>\n <p className=\"mt-1 text-xs text-fg-muted\">{v.stt.description}</p>\n </div>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.stt.enable}</div>\n <p className=\"text-xs text-fg-muted\">{v.stt.enableDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={stt.enabled}\n onChange={(e) => updateStt({ enabled: e.target.checked })}\n />\n </div>\n\n {stt.enabled ? (\n <>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.provider}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.provider}\n onChange={(e) => updateStt({ provider: e.target.value as 'alibaba' | 'openai' })}\n >\n <option value=\"alibaba\">{v.stt.alibaba}</option>\n <option value=\"openai\">{v.stt.openai}</option>\n </select>\n </div>\n </div>\n\n {stt.provider === 'alibaba' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={stt.alibaba?.apiKey ?? ''}\n onChange={(e) => updateSttAlibaba({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (DASHSCOPE_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.alibaba?.model ?? ''}\n onChange={(e) => updateSttAlibaba({ model: e.target.value })}\n >\n {alibabaModels.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={stt.openai?.apiKey ?? ''}\n onChange={(e) => updateSttOpenai({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (OPENAI_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.openai?.model ?? ''}\n onChange={(e) => updateSttOpenai({ model: e.target.value })}\n >\n {openaiModels.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.stt.fallback}</div>\n <p className=\"text-xs text-fg-muted\">{v.stt.fallbackDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={stt.fallback?.enabled ?? true}\n onChange={(e) => updateSttFallback({ enabled: e.target.checked })}\n />\n </div>\n </>\n ) : null}\n </div>\n </section>\n );\n}\n\nfunction TtsSection({\n v,\n tts,\n models,\n updateTts,\n updateTtsAlibaba,\n updateTtsOpenai,\n updateTtsEdge,\n updateTtsMinimax,\n updateTtsLocalCli,\n}: {\n v: VoiceSettingsMessages;\n tts: VoiceSettingsState['tts'];\n models: VoiceModelsPayload | null;\n updateTts: (p: Partial<VoiceSettingsState['tts']>) => void;\n updateTtsAlibaba: (p: Partial<NonNullable<VoiceSettingsState['tts']['alibaba']>>) => void;\n updateTtsOpenai: (p: Partial<NonNullable<VoiceSettingsState['tts']['openai']>>) => void;\n updateTtsEdge: (p: Partial<NonNullable<VoiceSettingsState['tts']['edge']>>) => void;\n updateTtsMinimax: (p: Partial<NonNullable<VoiceSettingsState['tts']['minimax']>>) => void;\n updateTtsLocalCli: (p: Partial<NonNullable<VoiceSettingsState['tts']['tts-local-cli']>>) => void;\n}) {\n const triggerDesc = (t: string) => {\n if (t === 'off') return v.tts.triggerDescOff;\n if (t === 'always') return v.tts.triggerDescAlways;\n if (t === 'inbound') return v.tts.triggerDescInbound;\n if (t === 'tagged') return v.tts.triggerDescTagged;\n return '';\n };\n\n const ttsOpenai = models?.tts?.openai?.length ? models.tts.openai : TTS_OPENAI_MODELS_FALLBACK;\n const ttsVoicesOpenai = models?.ttsVoices?.openai?.length ? models.ttsVoices.openai : TTS_OPENAI_VOICES_FALLBACK;\n const ttsAlibaba = models?.tts?.alibaba?.length ? models.tts.alibaba : TTS_ALIBABA_MODELS_FALLBACK;\n const ttsVoicesAlibaba = models?.ttsVoices?.alibaba?.length ? models.ttsVoices.alibaba : TTS_ALIBABA_VOICES_FALLBACK;\n const ttsVoicesEdge = models?.ttsVoices?.edge?.length ? models.ttsVoices.edge : TTS_EDGE_VOICES_FALLBACK;\n const ttsMinimax = models?.tts?.minimax?.length ? models.tts.minimax : TTS_MINIMAX_MODELS_FALLBACK;\n const ttsVoicesMinimax = models?.ttsVoices?.minimax?.length\n ? models.ttsVoices.minimax\n : TTS_MINIMAX_VOICES_FALLBACK;\n\n return (\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Volume2 className=\"size-4 text-accent\" strokeWidth={1.75} />\n {v.tts.title}\n </div>\n <p className=\"mt-1 text-xs text-fg-muted\">{v.tts.description}</p>\n </div>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.tts.enable}</div>\n <p className=\"text-xs text-fg-muted\">{v.tts.enableDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={tts.enabled}\n onChange={(e) => updateTts({ enabled: e.target.checked })}\n />\n </div>\n\n {tts.enabled ? (\n <>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.trigger}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.trigger}\n onChange={(e) =>\n updateTts({ trigger: e.target.value as VoiceSettingsState['tts']['trigger'] })\n }\n >\n <option value=\"off\">{v.tts.triggerOff}</option>\n <option value=\"always\">{v.tts.triggerAlways}</option>\n <option value=\"inbound\">{v.tts.triggerInbound}</option>\n <option value=\"tagged\">{v.tts.triggerTagged}</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{triggerDesc(tts.trigger)}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.provider}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.provider}\n onChange={(e) => updateTts({ provider: e.target.value })}\n >\n <option value=\"openai\">{v.tts.providerOpenai}</option>\n <option value=\"alibaba\">{v.stt.alibaba}</option>\n <option value=\"minimax\">MiniMax</option>\n <option value=\"edge\">{v.tts.providerEdge}</option>\n <option value=\"tts-local-cli\">{v.tts.providerLocalCli}</option>\n </select>\n </div>\n </div>\n\n {tts.provider === 'openai' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.openai?.apiKey ?? ''}\n onChange={(e) => updateTtsOpenai({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (OPENAI_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.openai?.model ?? ''}\n onChange={(e) => updateTtsOpenai({ model: e.target.value })}\n >\n {ttsOpenai.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.openai?.voice ?? ''}\n onChange={(e) => updateTtsOpenai({ voice: e.target.value })}\n >\n {ttsVoicesOpenai.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'alibaba' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.alibaba?.apiKey ?? ''}\n onChange={(e) => updateTtsAlibaba({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (DASHSCOPE_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.alibaba?.model ?? ''}\n onChange={(e) => updateTtsAlibaba({ model: e.target.value })}\n >\n {ttsAlibaba.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.alibaba?.voice ?? ''}\n onChange={(e) => updateTtsAlibaba({ voice: e.target.value })}\n >\n {ttsVoicesAlibaba.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'minimax' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.minimax?.apiKey ?? ''}\n onChange={(e) => updateTtsMinimax({ apiKey: e.target.value })}\n placeholder=\"eyJ...\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.stt.apiKeyDesc} (MINIMAX_API_KEY)</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.minimax?.model ?? ''}\n onChange={(e) => updateTtsMinimax({ model: e.target.value })}\n >\n {ttsMinimax.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.minimax?.voice ?? ''}\n onChange={(e) => updateTtsMinimax({ voice: e.target.value })}\n >\n {ttsVoicesMinimax.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'edge' ? (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.edge?.voice ?? ''}\n onChange={(e) => updateTtsEdge({ voice: e.target.value })}\n >\n {ttsVoicesEdge.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-fg-subtle\">{v.tts.edgeHint}</p>\n </div>\n ) : null}\n\n {tts.provider === 'tts-local-cli' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.tts.localCli.command}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={tts['tts-local-cli']?.command ?? ''}\n onChange={(e) => updateTtsLocalCli({ command: e.target.value })}\n placeholder={v.tts.localCli.commandPlaceholder}\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.commandDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.localCli.cwd}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={tts['tts-local-cli']?.cwd ?? ''}\n onChange={(e) => updateTtsLocalCli({ cwd: e.target.value })}\n placeholder=\"/path/to/cwd\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.cwdDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.localCli.outputFormat}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts['tts-local-cli']?.outputFormat ?? 'wav'}\n onChange={(e) =>\n updateTtsLocalCli({\n outputFormat: e.target.value as 'mp3' | 'opus' | 'wav',\n })\n }\n >\n <option value=\"wav\">wav</option>\n <option value=\"mp3\">mp3</option>\n <option value=\"opus\">opus</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.outputFormatDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.tts.localCli.timeoutMs}</FieldLabel>\n <input\n className={inputClassName()}\n type=\"number\"\n min={0}\n step={1000}\n value={\n typeof tts['tts-local-cli']?.timeoutMs === 'number'\n ? String(tts['tts-local-cli'].timeoutMs)\n : ''\n }\n onChange={(e) => {\n const raw = e.target.value.trim();\n if (raw === '') {\n updateTtsLocalCli({ timeoutMs: undefined });\n return;\n }\n const num = Number(raw);\n if (Number.isFinite(num) && num >= 0) {\n updateTtsLocalCli({ timeoutMs: num });\n }\n }}\n placeholder=\"30000\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.timeoutMsDesc}</p>\n </div>\n <p className=\"text-xs text-fg-subtle sm:col-span-2\">{v.tts.localCli.hint}</p>\n </div>\n ) : null}\n </>\n ) : null}\n </div>\n </section>\n );\n}\n\nfunction FieldLabel({ children }: { children: ReactNode }) {\n return <div className=\"text-sm font-medium text-fg\">{children}</div>;\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport type SearchProviderRow = {\n type: 'brave' | 'tavily' | 'bing' | 'searxng';\n apiKey: string;\n url: string;\n disabled: boolean;\n};\n\nexport type WebSearchSettingsState = {\n regionMode: 'auto' | 'cn' | 'global';\n maxResults: number;\n providers: SearchProviderRow[];\n};\n\nexport function normalizeWebSearchSettingsFromConfig(cfg: unknown): WebSearchSettingsState {\n const tools = cfg && typeof cfg === 'object' && 'tools' in cfg ? (cfg as { tools?: unknown }).tools : undefined;\n const web = tools && typeof tools === 'object' && 'web' in tools ? (tools as { web?: unknown }).web : undefined;\n const region =\n web && typeof web === 'object' && 'region' in web\n ? (web as { region?: unknown }).region\n : undefined;\n const regionMode =\n region === 'cn' || region === 'global' ? region : 'auto';\n\n const search =\n web && typeof web === 'object' && 'search' in web ? (web as { search?: unknown }).search : undefined;\n const s = search && typeof search === 'object' ? (search as Record<string, unknown>) : {};\n\n const maxResults =\n typeof s.maxResults === 'number' && Number.isFinite(s.maxResults) ? Math.floor(s.maxResults) : 5;\n\n const rawProviders = s.providers;\n const rows: SearchProviderRow[] = Array.isArray(rawProviders)\n ? rawProviders.map((p) => {\n const o = p && typeof p === 'object' ? (p as Record<string, unknown>) : {};\n const type = o.type;\n const t =\n type === 'brave' || type === 'tavily' || type === 'bing' || type === 'searxng' ? type : 'brave';\n return {\n type: t,\n apiKey: typeof o.apiKey === 'string' ? o.apiKey : '',\n url: typeof o.url === 'string' ? o.url : '',\n disabled: o.disabled === true,\n };\n })\n : [];\n\n return {\n regionMode,\n maxResults,\n providers: rows,\n };\n}\n\nexport async function fetchWebSearchSettings(): Promise<WebSearchSettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeWebSearchSettingsFromConfig(res.payload?.config);\n}\n\nexport async function patchWebSearchSettings(state: WebSearchSettingsState): Promise<void> {\n const region =\n state.regionMode === 'auto' ? 'auto' : state.regionMode === 'cn' ? 'cn' : 'global';\n\n const search: Record<string, unknown> = {\n maxResults: state.maxResults,\n providers: state.providers.map((p) => {\n const row: Record<string, unknown> = {\n type: p.type,\n apiKey: p.apiKey,\n };\n if (p.type === 'searxng' && p.url.trim()) {\n row.url = p.url.trim().replace(/\\/+$/, '');\n }\n if (p.disabled) row.disabled = true;\n return row;\n }),\n };\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n tools: {\n web: {\n region,\n search,\n },\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { ExternalLink, Loader2, Plus, Search, Trash2 } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n normalizeWebSearchSettingsFromConfig,\n patchWebSearchSettings,\n type SearchProviderRow,\n type WebSearchSettingsState,\n} from '@/features/settings/web-search-config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { isMaskedKey } from '@/features/settings/providers-api';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type WebSearchSettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction Field({\n label,\n description,\n children,\n}: {\n label: string;\n description: string;\n children: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"text-sm font-medium text-fg\">{label}</div>\n {children}\n <p className=\"text-xs leading-relaxed text-fg-subtle\">{description}</p>\n </div>\n );\n}\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst PROVIDER_TYPES: SearchProviderRow['type'][] = ['brave', 'tavily', 'bing', 'searxng'];\n\nfunction emptyProviderRow(): SearchProviderRow {\n return { type: 'brave', apiKey: '', url: '', disabled: false };\n}\n\nexport function WebSearchSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const w = m.webSearchSettings;\n const logs = m.logs;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<WebSearchSettingsState | null>(null);\n const [baseline, setBaseline] = useState<WebSearchSettingsState | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const dirtyRef = useRef(false);\n\n const { data, error: swrError, isLoading, mutate } = useGatewayConfigSwr(hasToken);\n\n const parsed = useMemo(\n () =>\n data?.payload?.config !== undefined\n ? normalizeWebSearchSettingsFromConfig(data.payload.config)\n : null,\n [data],\n );\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n dirtyRef.current = false;\n return;\n }\n if (parsed === null) return;\n if (!dirtyRef.current) {\n setForm(parsed);\n setBaseline(parsed);\n }\n }, [hasToken, parsed]);\n\n const loading = Boolean(hasToken && isLoading && data === undefined && !swrError);\n const fetchError =\n swrError instanceof Error ? swrError.message : swrError ? String(swrError) : null;\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const update = useCallback((patch: Partial<WebSearchSettingsState>) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, ...patch } : null));\n }, []);\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchWebSearchSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setForm(next);\n dirtyRef.current = false;\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : w.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, w.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n dirtyRef.current = false;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-6\">\n <h1 className=\"text-lg font-semibold text-fg\">{w.title}</h1>\n <p className=\"text-sm text-fg-muted\">{w.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col items-center gap-3 px-4 py-8\">\n <Loader2 className=\"size-8 animate-spin text-fg-muted\" aria-hidden />\n <p className=\"text-sm text-fg-muted\">{w.loading}</p>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? w.loadError}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\n {logs.refresh}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{w.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{w.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'gateway')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {w.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{w.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {w.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? w.saving : w.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{w.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={w.sectionRegion} subtitle={w.sectionRegionHint} />\n <div className=\"flex max-w-md flex-col gap-4\">\n <Field label={w.regionLabel} description={w.regionDesc}>\n <select\n className={selectClassName()}\n value={form.regionMode}\n onChange={(e) =>\n update({\n regionMode: e.target.value as WebSearchSettingsState['regionMode'],\n })\n }\n >\n <option value=\"auto\">{w.regionAuto}</option>\n <option value=\"cn\">{w.regionCn}</option>\n <option value=\"global\">{w.regionGlobal}</option>\n </select>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={w.sectionSearch} subtitle={w.sectionSearchHint} />\n <div className=\"flex max-w-xl flex-col gap-6\">\n <Field label={w.maxResultsLabel} description={w.maxResultsDesc}>\n <input\n type=\"number\"\n min={1}\n max={50}\n className={inputClassName()}\n value={form.maxResults}\n onChange={(e) => update({ maxResults: Math.max(1, Math.min(50, Number(e.target.value) || 5)) })}\n />\n </Field>\n\n <div className=\"flex flex-col gap-3\">\n <div className=\"text-sm font-medium text-fg\">{w.providersTitle}</div>\n {form.providers.map((row, index) => (\n <ProviderRowEditor\n key={index}\n row={row}\n labels={w}\n onChange={(next) => {\n const nextRows = [...form.providers];\n nextRows[index] = next;\n update({ providers: nextRows });\n }}\n onRemove={() => {\n update({ providers: form.providers.filter((_, i) => i !== index) });\n }}\n />\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5 text-sm\"\n onClick={() => update({ providers: [...form.providers, emptyProviderRow()] })}\n >\n <Plus className=\"size-4\" />\n {w.addProvider}\n </Button>\n </div>\n </div>\n </SettingsFormSection>\n\n <p className=\"text-xs leading-relaxed text-fg-subtle\">{w.footerHint}</p>\n </div>\n );\n}\n\nfunction ProviderRowEditor({\n row,\n labels,\n onChange,\n onRemove,\n}: {\n row: SearchProviderRow;\n labels: WebSearchSettingsMessages;\n onChange: (r: SearchProviderRow) => void;\n onRemove: () => void;\n}) {\n return (\n <div className=\"flex flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-panel/60 p-4 dark:border-edge-subtle\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <select\n className={cn(selectClassName(), 'min-w-[8rem]')}\n value={row.type}\n onChange={(e) =>\n onChange({\n ...row,\n type: e.target.value as SearchProviderRow['type'],\n url: e.target.value === 'searxng' ? row.url : '',\n })\n }\n >\n {PROVIDER_TYPES.map((t) => (\n <option key={t} value={t}>\n {labels.providerTypes[t]}\n </option>\n ))}\n </select>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex cursor-pointer items-center gap-1.5 text-xs text-fg-muted\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 rounded border-edge\"\n checked={row.disabled}\n onChange={(e) => onChange({ ...row, disabled: e.target.checked })}\n />\n {labels.disabled}\n </label>\n <Button type=\"button\" variant=\"ghost\" className=\"h-8 px-2 text-fg-muted\" onClick={onRemove}>\n <Trash2 className=\"size-4\" />\n </Button>\n </div>\n </div>\n {row.type === 'searxng' ? (\n <Field label={labels.urlLabel} description={labels.urlDesc}>\n <input\n type=\"url\"\n className={inputClassName()}\n value={row.url}\n placeholder=\"http://localhost:8080\"\n onChange={(e) => onChange({ ...row, url: e.target.value })}\n />\n </Field>\n ) : null}\n <Field label={labels.apiKeyLabel} description={labels.apiKeyDesc}>\n <input\n type=\"password\"\n autoComplete=\"off\"\n className={inputClassName()}\n value={isMaskedKey(row.apiKey) ? '' : row.apiKey}\n placeholder={isMaskedKey(row.apiKey) ? labels.keyPlaceholderMasked : labels.keyPlaceholder}\n onChange={(e) => onChange({ ...row, apiKey: e.target.value })}\n />\n </Field>\n </div>\n );\n}\n","import { Navigate, useParams } from 'react-router-dom';\n\nimport {\n AgentBrowserDefaultsPage,\n AgentChatDefaultsPage,\n AgentRuntimeDefaultsPage,\n AgentSystemPromptDefaultsPage,\n AgentToolsDefaultsPage,\n AgentWorkspaceDefaultsPage,\n} from '@/features/settings/agents';\nimport { AppearanceSettingsPanel } from '@/features/settings/appearance-settings';\nimport { DreamingSettingsPanel } from '@/features/settings/dreaming-settings';\nimport { GatewaySettingsPanel } from '@/features/settings/gateway-settings';\nimport { HeartbeatSettingsPanel } from '@/features/settings/heartbeat-settings';\nimport { ImageModelsSettingsPanel } from '@/features/settings/image-models-settings';\nimport { ModelsSettingsPanel } from '@/features/settings/models-settings';\nimport { ProvidersSettingsPanel } from '@/features/settings/providers-settings';\nimport { SystemSettingsPanel } from '@/features/settings/system-settings-panel';\nimport { VoiceSettingsPanel } from '@/features/settings/voice-settings';\nimport { WebSearchSettingsPanel } from '@/features/settings/web-search-settings';\nimport { messages } from '@/i18n/messages';\nimport type { SettingsSectionId } from '@/navigation';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nconst SECTIONS: SettingsSectionId[] = [\n 'appearance',\n 'system',\n 'agent-chat',\n 'agent-workspace',\n 'agent-browser',\n 'agent-runtime',\n 'agent-tools',\n 'agent-system-prompt',\n 'providers',\n 'models',\n 'image-models',\n 'voice',\n 'gateway',\n 'heartbeat',\n 'search',\n 'dreams',\n];\n\nexport function SettingsPage() {\n const { section } = useParams();\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n\n if (section === 'agent' || section === 'agents') {\n return <Navigate to=\"/agents\" replace />;\n }\n\n if (!section || !SECTIONS.includes(section as SettingsSectionId)) {\n return <Navigate to=\"/settings/appearance\" replace />;\n }\n\n const id = section as SettingsSectionId;\n const title = m.settingsSections[id];\n\n if (id === 'appearance') {\n return <AppearanceSettingsPanel />;\n }\n\n if (id === 'system') {\n return <SystemSettingsPanel />;\n }\n\n if (id === 'agent-chat') {\n return <AgentChatDefaultsPage />;\n }\n\n if (id === 'agent-workspace') {\n return <AgentWorkspaceDefaultsPage />;\n }\n\n if (id === 'agent-browser') {\n return <AgentBrowserDefaultsPage />;\n }\n\n if (id === 'agent-runtime') {\n return <AgentRuntimeDefaultsPage />;\n }\n\n if (id === 'agent-tools') {\n return <AgentToolsDefaultsPage />;\n }\n\n if (id === 'agent-system-prompt') {\n return <AgentSystemPromptDefaultsPage />;\n }\n\n if (id === 'providers') {\n return <ProvidersSettingsPanel />;\n }\n\n if (id === 'models') {\n return <ModelsSettingsPanel />;\n }\n\n if (id === 'image-models') {\n return <ImageModelsSettingsPanel />;\n }\n\n if (id === 'voice') {\n return <VoiceSettingsPanel />;\n }\n\n if (id === 'gateway') {\n return <GatewaySettingsPanel />;\n }\n\n if (id === 'heartbeat') {\n return <HeartbeatSettingsPanel />;\n }\n\n if (id === 'search') {\n return <WebSearchSettingsPanel />;\n }\n\n if (id === 'dreams') {\n return <DreamingSettingsPanel />;\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{title}</h1>\n <p className=\"text-sm text-fg-muted\">\n {language === 'zh' ? `设置 · ${title}(即将推出)。` : `Settings · ${title} (coming soon).`}\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"settings-page-DUYYElOB.js","names":[],"sources":["../../../../../web/src/features/settings/appearance-settings.tsx","../../../../../web/src/features/settings/dreaming-config-api.ts","../../../../../web/src/features/settings/dreaming-settings.tsx","../../../../../web/src/features/settings/gateway-config-api.ts","../../../../../web/src/features/settings/gateway-settings.tsx","../../../../../web/src/features/settings/channels-status-swr.ts","../../../../../web/src/features/settings/heartbeat-md-swr.ts","../../../../../web/src/features/settings/heartbeat-config-api.ts","../../../../../web/src/features/settings/heartbeat-interval-presets.ts","../../../../../web/src/features/settings/heartbeat-settings.tsx","../../../../../web/src/features/settings/agents/image-generation-model-input.tsx","../../../../../web/src/features/settings/agents/agent-defaults-panels/image-model-chains-section.tsx","../../../../../web/src/features/settings/image-models-settings.tsx","../../../../../web/src/features/settings/models-json-api.ts","../../../../../web/src/features/settings/agents/agent-defaults-panels/chat-model-fallbacks-section.tsx","../../../../../web/src/features/settings/models/models-settings-lib.ts","../../../../../web/src/features/settings/models/models-model-edit-dialog.tsx","../../../../../web/src/features/settings/models/models-provider-add-dialog.tsx","../../../../../web/src/features/settings/models/models-providers-list.tsx","../../../../../web/src/features/settings/models/models-settings-panel.tsx","../../../../../web/src/features/settings/oauth-api.ts","../../../../../web/src/features/settings/provider-info-popover.tsx","../../../../../web/src/features/settings/providers/providers-settings-lib.ts","../../../../../web/src/features/settings/providers/provider-credential-row.tsx","../../../../../web/src/features/settings/providers/providers-settings-panel.tsx","../../../../../web/src/features/settings/system-settings-panel.tsx","../../../../../web/src/features/settings/voice-config-api.ts","../../../../../web/src/features/settings/voice-settings.tsx","../../../../../web/src/features/settings/web-search-config-api.ts","../../../../../web/src/features/settings/web-search-settings.tsx","../../../../../web/src/pages/settings-page.tsx"],"sourcesContent":["import { PreferenceSelectFields } from '@/components/shell/preference-select-fields';\nimport { messages } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { type ColorScheme, useThemeStore } from '@/stores/theme-store';\n\nfunction preferenceCardClassName() {\n return cn('rounded-xl border border-edge-subtle bg-surface-base px-4 py-1 sm:px-5');\n}\n\n/**\n * Mini chrome preview per globals.css tokens — left: light, right: dark for the same palette.\n */\nconst SCHEME_PREVIEW: Record<\n ColorScheme,\n { light: { canvas: string; panel: string; accent: string; fg: string; muted: string }; dark: { canvas: string; panel: string; accent: string; fg: string; muted: string } }\n> = {\n default: {\n light: {\n canvas: '#f5f5f7',\n panel: '#ffffff',\n accent: '#2563eb',\n fg: '#1d1d1f',\n muted: '#d2d2d7',\n },\n dark: {\n canvas: '#1c1c1e',\n panel: '#2c2c2e',\n accent: '#3b82f6',\n fg: '#f5f5f7',\n muted: '#48484a',\n },\n },\n emerald: {\n light: {\n canvas: '#f0fdf4',\n panel: '#ffffff',\n accent: '#059669',\n fg: '#052e16',\n muted: '#86efac',\n },\n dark: {\n canvas: '#000000',\n panel: '#0a0a0a',\n accent: '#10b981',\n fg: '#d1fae5',\n muted: '#134e2a',\n },\n },\n mono: {\n light: {\n canvas: '#ffffff',\n panel: '#f5f5f5',\n accent: '#111111',\n fg: '#111111',\n muted: '#e5e7eb',\n },\n dark: {\n canvas: '#101010',\n panel: '#1a1a1a',\n accent: '#737373',\n fg: '#fafafa',\n muted: '#333333',\n },\n },\n};\n\nfunction SchemePreviewHalf({\n canvas,\n panel,\n accent,\n fg,\n muted,\n}: {\n canvas: string;\n panel: string;\n accent: string;\n fg: string;\n muted: string;\n}) {\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col justify-center gap-1 p-1.5\" style={{ backgroundColor: canvas }}>\n <div\n className=\"flex flex-col gap-0.5 rounded-sm border p-1\"\n style={{ backgroundColor: panel, borderColor: muted }}\n >\n <div className=\"flex items-center gap-1\">\n <div className=\"h-1 w-1 shrink-0 rounded-full\" style={{ backgroundColor: accent }} />\n <div className=\"h-1 min-w-0 flex-1 rounded-full\" style={{ backgroundColor: fg, opacity: 0.85 }} />\n </div>\n <div className=\"h-1 w-2/3 max-w-[70%] rounded-full\" style={{ backgroundColor: muted }} />\n <div className=\"h-1 w-1/2 max-w-[55%] rounded-full\" style={{ backgroundColor: muted }} />\n </div>\n </div>\n );\n}\n\n/** Side-by-side light (left) and dark (right) samples for one color scheme. */\nfunction SchemePreviewSwatch({ scheme }: { scheme: ColorScheme }) {\n const { light, dark } = SCHEME_PREVIEW[scheme];\n return (\n <div className=\"flex h-11 w-full overflow-hidden rounded-md border border-edge-subtle\">\n <SchemePreviewHalf {...light} />\n <div className=\"w-px shrink-0 bg-black/12 dark:bg-white/12\" aria-hidden />\n <SchemePreviewHalf {...dark} />\n </div>\n );\n}\n\nconst COLOR_SCHEME_OPTIONS: {\n value: ColorScheme;\n labelKey: 'colorSchemeDefault' | 'colorSchemeLightGreen' | 'colorSchemeModernMono';\n}[] = [\n { value: 'default', labelKey: 'colorSchemeDefault' },\n { value: 'emerald', labelKey: 'colorSchemeLightGreen' },\n { value: 'mono', labelKey: 'colorSchemeModernMono' },\n];\n\nfunction ColorSchemeSelector() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.appearanceSettings;\n const colorScheme = useThemeStore((s) => s.colorScheme);\n const setColorScheme = useThemeStore((s) => s.setColorScheme);\n\n return (\n <div className=\"flex flex-col gap-2 border-b border-edge-subtle py-3.5 last:border-b-0 sm:py-4\">\n <div className=\"min-w-0\">\n <div className=\"text-sm font-semibold text-fg\">{a.colorSchemeTitle}</div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{a.colorSchemeDescription}</p>\n </div>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {COLOR_SCHEME_OPTIONS.map(({ value, labelKey }) => {\n const isSelected = colorScheme === value;\n return (\n <button\n key={value}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => setColorScheme(value)}\n className={cn(\n 'flex flex-col gap-2 rounded-xl border-2 p-2.5 text-left transition-[border-color,box-shadow] duration-150',\n isSelected\n ? 'border-accent shadow-[0_0_0_1px_var(--color-accent)]'\n : 'border-edge-subtle hover:border-edge',\n )}\n >\n <SchemePreviewSwatch scheme={value} />\n <span\n className={cn(\n 'text-xs font-medium leading-none',\n isSelected ? 'text-accent-fg' : 'text-fg-muted',\n )}\n >\n {a[labelKey]}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function AppearanceSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.appearanceSettings;\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-1\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{a.pageTitle}</h1>\n <p className=\"text-sm text-fg-muted\">{a.subtitle}</p>\n </header>\n\n <section className={preferenceCardClassName()} aria-labelledby=\"pref-language-heading\">\n <h2 id=\"pref-language-heading\" className=\"sr-only\">\n {a.languageTitle}\n </h2>\n <PreferenceSelectFields variant=\"page\" sections={['language']} />\n </section>\n\n <section className={preferenceCardClassName()} aria-labelledby=\"pref-appearance-heading\">\n <h2 id=\"pref-appearance-heading\" className=\"sr-only\">\n {a.themeTitle}\n </h2>\n <PreferenceSelectFields variant=\"page\" sections={['theme', 'font']} />\n <ColorSchemeSelector />\n </section>\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport type DreamingLightConfigState = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n dedupeSimilarity: number;\n};\n\nexport type DreamingDeepConfigState = {\n enabled: boolean;\n cron: string;\n minScore: number;\n minRecallCount: number;\n limit: number;\n recencyHalfLifeDays: number;\n maxAgeDays: number;\n};\n\nexport type DreamingRemConfigState = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n minPatternStrength: number;\n};\n\nexport type DreamingConfigState = {\n enabled: boolean;\n frequency: string;\n timezone: string;\n /** @deprecated Use phases.deep.enabled */\n deepEnabled: boolean;\n /** @deprecated Use phases.deep.minScore */\n minScore: number;\n /** @deprecated Use phases.deep.minRecallCount */\n minRecallCount: number;\n /** @deprecated Use phases.deep.limit */\n limit: number;\n light: DreamingLightConfigState;\n deep: DreamingDeepConfigState;\n rem: DreamingRemConfigState;\n};\n\nconst LIGHT_DEFAULTS: DreamingLightConfigState = {\n enabled: true,\n cron: '0 */6 * * *',\n lookbackDays: 1,\n limit: 50,\n dedupeSimilarity: 0.85,\n};\n\nconst DEEP_DEFAULTS: DreamingDeepConfigState = {\n enabled: true,\n cron: '0 3 * * *',\n minScore: 0.8,\n minRecallCount: 3,\n limit: 10,\n recencyHalfLifeDays: 14,\n maxAgeDays: 30,\n};\n\nconst REM_DEFAULTS: DreamingRemConfigState = {\n enabled: true,\n cron: '0 5 * * 0',\n lookbackDays: 7,\n limit: 20,\n minPatternStrength: 0.6,\n};\n\nconst DEFAULTS: DreamingConfigState = {\n enabled: false,\n frequency: '0 3 * * *',\n timezone: '',\n deepEnabled: true,\n minScore: 0.8,\n minRecallCount: 3,\n limit: 10,\n light: LIGHT_DEFAULTS,\n deep: DEEP_DEFAULTS,\n rem: REM_DEFAULTS,\n};\n\nfunction clamp01(n: number, fallback: number): number {\n if (!Number.isFinite(n)) return fallback;\n return Math.max(0, Math.min(1, n));\n}\n\nfunction toInt(n: unknown, fallback: number): number {\n const x = typeof n === 'string' ? Number(n) : (n as number);\n if (!Number.isFinite(x)) return fallback;\n return Math.max(0, Math.floor(x));\n}\n\nfunction toNum(value: unknown, fallback: number): number {\n const num = typeof value === 'string' ? Number(value) : (value as number);\n return Number.isFinite(num) ? num : fallback;\n}\n\nexport function normalizeDreamingFromConfig(config: unknown): DreamingConfigState {\n const c = isRecord(config) ? config : {};\n const agents = isRecord(c.agents) ? c.agents : {};\n const defaults = isRecord(agents.defaults) ? agents.defaults : {};\n const memory = isRecord(defaults.memory) ? defaults.memory : {};\n const dreaming = isRecord(memory.dreaming) ? memory.dreaming : {};\n const phases = isRecord(dreaming.phases) ? dreaming.phases : {};\n const lightRaw = isRecord(phases.light) ? phases.light : {};\n const deepRaw = isRecord(phases.deep) ? phases.deep : {};\n const remRaw = isRecord(phases.rem) ? phases.rem : {};\n\n return {\n enabled: dreaming.enabled === true,\n frequency: typeof dreaming.frequency === 'string' && dreaming.frequency.trim() ? dreaming.frequency.trim() : DEFAULTS.frequency,\n timezone: typeof dreaming.timezone === 'string' ? dreaming.timezone : '',\n deepEnabled: deepRaw.enabled !== false,\n minScore: clamp01(typeof deepRaw.minScore === 'number' ? deepRaw.minScore : Number(deepRaw.minScore), DEFAULTS.minScore),\n minRecallCount: Math.max(1, toInt(deepRaw.minRecallCount, DEFAULTS.minRecallCount)),\n limit: toInt(deepRaw.limit, DEFAULTS.limit),\n light: {\n enabled: lightRaw.enabled !== false,\n cron: typeof lightRaw.cron === 'string' && lightRaw.cron.trim() ? lightRaw.cron.trim() : LIGHT_DEFAULTS.cron,\n lookbackDays: Math.max(1, toInt(lightRaw.lookbackDays, LIGHT_DEFAULTS.lookbackDays)),\n limit: toInt(lightRaw.limit, LIGHT_DEFAULTS.limit),\n dedupeSimilarity: clamp01(toNum(lightRaw.dedupeSimilarity, LIGHT_DEFAULTS.dedupeSimilarity), LIGHT_DEFAULTS.dedupeSimilarity),\n },\n deep: {\n enabled: deepRaw.enabled !== false,\n cron: typeof deepRaw.cron === 'string' && deepRaw.cron.trim() ? deepRaw.cron.trim() : DEEP_DEFAULTS.cron,\n minScore: clamp01(toNum(deepRaw.minScore, DEEP_DEFAULTS.minScore), DEEP_DEFAULTS.minScore),\n minRecallCount: Math.max(1, toInt(deepRaw.minRecallCount, DEEP_DEFAULTS.minRecallCount)),\n limit: toInt(deepRaw.limit, DEEP_DEFAULTS.limit),\n recencyHalfLifeDays: Math.max(1, toNum(deepRaw.recencyHalfLifeDays, DEEP_DEFAULTS.recencyHalfLifeDays)),\n maxAgeDays: Math.max(1, toNum(deepRaw.maxAgeDays, DEEP_DEFAULTS.maxAgeDays)),\n },\n rem: {\n enabled: remRaw.enabled !== false,\n cron: typeof remRaw.cron === 'string' && remRaw.cron.trim() ? remRaw.cron.trim() : REM_DEFAULTS.cron,\n lookbackDays: Math.max(1, toInt(remRaw.lookbackDays, REM_DEFAULTS.lookbackDays)),\n limit: toInt(remRaw.limit, REM_DEFAULTS.limit),\n minPatternStrength: clamp01(toNum(remRaw.minPatternStrength, REM_DEFAULTS.minPatternStrength), REM_DEFAULTS.minPatternStrength),\n },\n };\n}\n\nexport async function patchDreamingConfig(state: DreamingConfigState): Promise<void> {\n const freq = state.frequency.trim();\n const tz = state.timezone.trim();\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n agents: {\n defaults: {\n memory: {\n dreaming: {\n enabled: Boolean(state.enabled),\n frequency: freq || null,\n timezone: tz || null,\n phases: {\n light: {\n enabled: Boolean(state.light.enabled),\n cron: state.light.cron.trim() || null,\n lookbackDays: Math.max(1, Math.floor(state.light.lookbackDays)),\n limit: Math.max(0, Math.floor(state.light.limit)),\n dedupeSimilarity: clamp01(state.light.dedupeSimilarity, LIGHT_DEFAULTS.dedupeSimilarity),\n },\n deep: {\n enabled: Boolean(state.deep.enabled),\n cron: state.deep.cron.trim() || null,\n minScore: clamp01(state.deep.minScore, DEEP_DEFAULTS.minScore),\n minRecallCount: Math.max(1, Math.floor(state.deep.minRecallCount)),\n limit: Math.max(0, Math.floor(state.deep.limit)),\n recencyHalfLifeDays: Math.max(1, state.deep.recencyHalfLifeDays),\n maxAgeDays: Math.max(1, state.deep.maxAgeDays),\n },\n rem: {\n enabled: Boolean(state.rem.enabled),\n cron: state.rem.cron.trim() || null,\n lookbackDays: Math.max(1, Math.floor(state.rem.lookbackDays)),\n limit: Math.max(0, Math.floor(state.rem.limit)),\n minPatternStrength: clamp01(state.rem.minPatternStrength, REM_DEFAULTS.minPatternStrength),\n },\n },\n },\n },\n },\n },\n }),\n });\n\n void revalidateGatewayConfig();\n}\n\n","import { Activity, Loader2, Moon, Play, RefreshCw, ScanLine, Settings2, Sparkles, Sun, Trash2, Unlock, Wrench } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { messages, type MessageBundle } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { cn } from '@/lib/cn';\nimport {\n SettingsFormSection,\n settingsFormSectionClassName,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport {\n dreamingSwrKey,\n fetchDreamingEvents,\n fetchDreamingStatus,\n fetchDreamingPreview,\n postDreamingAction,\n postDreamingRunNow,\n type DreamingEvent,\n type DreamingGatewayStatus,\n type DreamingLastRunRecord,\n type DreamingPhaseId,\n type DreamingPreviewItem,\n type PhaseLastRun,\n} from '@/features/settings/dreaming-api';\nimport {\n normalizeDreamingFromConfig,\n patchDreamingConfig,\n type DreamingConfigState,\n} from '@/features/settings/dreaming-config-api';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\n\nfunction rowLabelClass(): string {\n return 'text-xs font-medium text-fg-muted';\n}\n\nfunction rowValueClass(): string {\n return 'text-sm font-medium text-fg';\n}\n\nfunction isoShort(v: string | null | undefined): string {\n if (!v) return '—';\n return v.replace('T', ' ').replace('Z', '');\n}\n\nfunction formatDurationMs(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)} ms`;\n return `${(ms / 1000).toFixed(2)} s`;\n}\n\ntype DreamingSettingsI18n = MessageBundle['dreamingSettings'];\n\nfunction Subsection({ label, children, className }: { label: string; children: ReactNode; className?: string }) {\n return (\n <div className={cn('space-y-2', className)}>\n <h3 className=\"text-[0.7rem] font-semibold uppercase tracking-wider text-fg-muted\">{label}</h3>\n {children}\n </div>\n );\n}\n\nfunction PhaseStatusCard({\n icon,\n label,\n enabled,\n cron,\n details,\n t,\n}: {\n icon: ReactNode;\n label: string;\n enabled: boolean;\n cron: string;\n details: string;\n t: DreamingSettingsI18n;\n}) {\n return (\n <div className={cn(settingsFormSectionClassName(), 'space-y-1.5')}>\n <div className=\"flex items-center gap-2\">\n {icon}\n <span className=\"text-sm font-medium text-fg\">{label}</span>\n <span className={cn('ml-auto text-xs font-medium', enabled ? 'text-emerald-600 dark:text-emerald-400' : 'text-fg-muted')}>\n {enabled ? t.on : t.off}\n </span>\n </div>\n <div className=\"font-mono text-xs text-fg-muted\">{cron}</div>\n <div className=\"text-xs text-fg-muted\">{details}</div>\n </div>\n );\n}\n\nfunction PhaseLastRunBlock({\n label,\n lastRun,\n t,\n}: {\n label: string;\n lastRun: PhaseLastRun | undefined;\n t: DreamingSettingsI18n;\n}) {\n return (\n <Subsection label={label}>\n {lastRun?.exists ? (\n <details className=\"group rounded-lg border border-edge-subtle\">\n <summary className=\"cursor-pointer list-none px-3 py-2 text-xs font-medium text-fg-muted marker:hidden [&::-webkit-details-marker]:hidden\">\n <span className=\"underline decoration-edge underline-offset-2 group-open:text-fg\">{t.lastRunRaw}</span>\n </summary>\n <pre className=\"max-h-[12rem] overflow-auto border-t border-edge-subtle p-3 text-xs text-fg-muted\">\n {JSON.stringify(lastRun.raw, null, 2)}\n </pre>\n </details>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.phaseLastRunEmpty}</p>\n )}\n </Subsection>\n );\n}\n\nfunction LastRunStructuredView({ t, r }: { t: DreamingSettingsI18n; r: DreamingLastRunRecord }) {\n const s = r.deep?.skipped;\n return (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunStatus}</div>\n <div className={cn(rowValueClass(), r.ok ? 'text-emerald-600 dark:text-emerald-400' : 'text-amber-600 dark:text-amber-400')}>\n {r.ok ? t.lastRunSuccess : t.lastRunFailure}\n </div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunDuration}</div>\n <div className={rowValueClass()}>{formatDurationMs(r.durationMs)}</div>\n </div>\n <div className={cn(settingsFormSectionClassName(), 'sm:col-span-2')}>\n <div className={rowLabelClass()}>{t.lastRunReason}</div>\n <div className={rowValueClass()}>{r.reason}</div>\n {r.errorMessage ? (\n <div className=\"mt-1 text-xs text-amber-600 dark:text-amber-400\">{`${t.lastRunError}: ${r.errorMessage}`}</div>\n ) : null}\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunRanked}</div>\n <div className={rowValueClass()}>{String(r.deep?.candidatesRanked ?? '—')}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunApplied}</div>\n <div className={rowValueClass()}>{String(r.deep?.applied ?? '—')}</div>\n </div>\n {s ? (\n <div className=\"sm:col-span-2\">\n <div className=\"mb-2 text-xs font-medium text-fg\">{t.lastRunSkipped}</div>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipKey}</div>\n <div className={rowValueClass()}>{String(s.alreadyPromotedKey)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipRehydrate}</div>\n <div className={rowValueClass()}>{String(s.rehydrateFailed)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipContaminated}</div>\n <div className={rowValueClass()}>{String(s.contaminated)}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lastRunSkipHash}</div>\n <div className={rowValueClass()}>{String(s.hashDuplicate)}</div>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction lockStatusLabel(\n s: DreamingGatewayStatus['lock'],\n labels: Pick<DreamingSettingsI18n, 'lockValueLocked' | 'lockValueUnlocked'>,\n): { text: string; className: string } {\n if (s.locked) {\n return { text: labels.lockValueLocked, className: 'text-amber-600 dark:text-amber-400' };\n }\n return { text: labels.lockValueUnlocked, className: 'text-emerald-600 dark:text-emerald-400' };\n}\n\nexport function DreamingSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.dreamingSettings;\n\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const { data: cfgData } = useGatewayConfigSwr(hasToken);\n\n const [actionBusy, setActionBusy] = useState<null | 'reset_store' | 'clear_lock'>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionOk, setActionOk] = useState(false);\n const [runBusy, setRunBusy] = useState(false);\n const [runOk, setRunOk] = useState(false);\n const [runError, setRunError] = useState<string | null>(null);\n const [runPhase, setRunPhase] = useState<DreamingPhaseId>('deep');\n const [cfgForm, setCfgForm] = useState<DreamingConfigState | null>(null);\n const [cfgBaseline, setCfgBaseline] = useState<DreamingConfigState | null>(null);\n const [cfgSaving, setCfgSaving] = useState(false);\n const [cfgOk, setCfgOk] = useState(false);\n const [cfgError, setCfgError] = useState<string | null>(null);\n const [previewLoading, setPreviewLoading] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [previewItems, setPreviewItems] = useState<DreamingPreviewItem[] | null>(null);\n const [eventsLoading, setEventsLoading] = useState(false);\n const [eventsError, setEventsError] = useState<string | null>(null);\n const [events, setEvents] = useState<DreamingEvent[] | null>(null);\n\n const { data, error, isLoading, mutate } = useSWR(hasToken ? dreamingSwrKey() : null, fetchDreamingStatus, {\n revalidateOnFocus: false,\n });\n\n const lockLabel = useMemo(\n () => (data ? lockStatusLabel(data.lock, t) : null),\n [data, t],\n );\n\n const errorMessages = useMemo(() => {\n const list: string[] = [];\n if (error) list.push(error instanceof Error ? error.message : String(error));\n if (actionError) list.push(actionError);\n if (runError) list.push(runError);\n if (previewError) list.push(previewError);\n if (eventsError) list.push(eventsError);\n if (cfgError) list.push(cfgError);\n return list;\n }, [error, actionError, runError, previewError, eventsError, cfgError]);\n\n const successMessages = useMemo(() => {\n const list: string[] = [];\n if (cfgOk) list.push(t.configSaved);\n if (runOk) list.push(t.runQueued);\n if (actionOk) list.push(t.actionOk);\n return list;\n }, [cfgOk, runOk, actionOk, t]);\n\n const doRefresh = useCallback(async () => {\n setActionOk(false);\n setActionError(null);\n setRunOk(false);\n setRunError(null);\n setCfgOk(false);\n setCfgError(null);\n setPreviewError(null);\n await mutate();\n }, [mutate]);\n\n const loadPreview = useCallback(async () => {\n setPreviewLoading(true);\n setPreviewError(null);\n try {\n const res = await fetchDreamingPreview(20);\n setPreviewItems(res.items ?? []);\n } catch (e) {\n setPreviewError(e instanceof Error ? e.message : String(e));\n } finally {\n setPreviewLoading(false);\n }\n }, []);\n\n const loadEvents = useCallback(async () => {\n setEventsLoading(true);\n setEventsError(null);\n try {\n const result = await fetchDreamingEvents(50);\n setEvents(result);\n } catch (e) {\n setEventsError(e instanceof Error ? e.message : String(e));\n } finally {\n setEventsLoading(false);\n }\n }, []);\n\n const doRunNow = useCallback(async (phase: DreamingPhaseId = 'deep') => {\n setRunBusy(true);\n setRunOk(false);\n setRunError(null);\n try {\n await postDreamingRunNow(phase);\n setRunOk(true);\n await mutate();\n } catch (e) {\n setRunError(e instanceof Error ? e.message : String(e));\n } finally {\n setRunBusy(false);\n }\n }, [mutate]);\n\n const doAction = useCallback(\n async (action: 'reset_store' | 'clear_lock') => {\n setActionBusy(action);\n setActionError(null);\n setActionOk(false);\n try {\n await postDreamingAction(action);\n setActionOk(true);\n await mutate();\n } catch (e) {\n setActionError(e instanceof Error ? e.message : String(e));\n } finally {\n setActionBusy(null);\n }\n },\n [mutate],\n );\n\n const disabled = !hasToken || isLoading || Boolean(actionBusy);\n\n const cfgFromGateway = useMemo(() => {\n const rawCfg = cfgData?.payload?.config;\n return normalizeDreamingFromConfig(rawCfg ?? {});\n }, [cfgData]);\n\n // Hydrate config form when config is loaded/changes.\n useEffect(() => {\n if (!hasToken) return;\n if (!cfgBaseline) {\n setCfgBaseline(cfgFromGateway);\n setCfgForm(cfgFromGateway);\n return;\n }\n // If baseline differs from latest gateway config (e.g. reload), reset.\n const nextJson = JSON.stringify(cfgFromGateway);\n const baseJson = JSON.stringify(cfgBaseline);\n if (nextJson !== baseJson) {\n setCfgBaseline(cfgFromGateway);\n setCfgForm(cfgFromGateway);\n }\n }, [cfgBaseline, cfgFromGateway, hasToken]);\n\n const cfgDirty = useMemo(() => {\n if (!cfgForm || !cfgBaseline) return false;\n return JSON.stringify(cfgForm) !== JSON.stringify(cfgBaseline);\n }, [cfgForm, cfgBaseline]);\n\n const saveConfig = useCallback(async () => {\n if (!cfgForm) return;\n setCfgSaving(true);\n setCfgOk(false);\n setCfgError(null);\n try {\n await patchDreamingConfig(cfgForm);\n setCfgBaseline(cfgForm);\n setCfgOk(true);\n await mutate();\n } catch (e) {\n setCfgError(e instanceof Error ? e.message : String(e));\n } finally {\n setCfgSaving(false);\n }\n }, [cfgForm, mutate]);\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <header className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.subtitle}</p>\n </div>\n <div className=\"flex shrink-0 items-center justify-end gap-2\">\n <select\n className=\"rounded-lg border border-edge bg-surface-panel px-2 py-1.5 text-xs text-fg\"\n value={runPhase}\n onChange={(e) => setRunPhase(e.target.value as DreamingPhaseId)}\n disabled={!hasToken || runBusy}\n >\n <option value=\"light\">Light</option>\n <option value=\"deep\">Deep</option>\n <option value=\"rem\">REM</option>\n </select>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || runBusy}\n onClick={() => void doRunNow(runPhase)}\n title={t.runNowHint}\n >\n {runBusy ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Play className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.runNow}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken}\n onClick={() => void doRefresh()}\n >\n <RefreshCw className=\"mr-2 size-4\" aria-hidden />\n {t.refresh}\n </Button>\n </div>\n </header>\n\n {errorMessages.length > 0 ? (\n <div\n className=\"space-y-1.5 rounded-2xl border border-amber-500/20 bg-amber-500/5 px-4 py-3\"\n role=\"alert\"\n >\n {errorMessages.map((line, i) => (\n <p key={i} className=\"text-sm text-amber-800 dark:text-amber-200/90\">\n {line}\n </p>\n ))}\n </div>\n ) : null}\n {successMessages.length > 0 ? (\n <div\n className=\"space-y-1.5 rounded-2xl border border-emerald-500/20 bg-emerald-500/5 px-4 py-3\"\n role=\"status\"\n >\n {successMessages.map((line, i) => (\n <p key={i} className=\"text-sm text-emerald-800 dark:text-emerald-200/90\">\n {line}\n </p>\n ))}\n </div>\n ) : null}\n\n <div className=\"flex flex-col gap-6\">\n <SettingsFormSection className=\"min-w-0\">\n <SettingsFormSectionHeader\n icon={Settings2}\n title={t.configTitle}\n subtitle={t.configHint}\n trailing={\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || !cfgForm || cfgSaving || !cfgDirty}\n onClick={() => void saveConfig()}\n >\n {cfgSaving ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.saveConfig}\n </Button>\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || !cfgForm || cfgSaving || !cfgDirty}\n onClick={() => {\n setCfgOk(false);\n setCfgError(null);\n setCfgForm(cfgBaseline);\n }}\n >\n {t.resetConfig}\n </Button>\n </div>\n }\n />\n\n {cfgForm ? (\n <div className=\"space-y-5\">\n {/* Global settings */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={cfgForm.enabled}\n onChange={(e) => setCfgForm({ ...cfgForm, enabled: e.target.checked })}\n />\n <span>{cfgForm.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configFrequency}</div>\n <input\n className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg placeholder:text-fg-subtle dark:border-edge\"\n value={cfgForm.frequency}\n onChange={(e) => setCfgForm({ ...cfgForm, frequency: e.target.value })}\n placeholder=\"0 3 * * *\"\n />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configTimezone}</div>\n <input\n className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg placeholder:text-fg-subtle dark:border-edge\"\n value={cfgForm.timezone}\n onChange={(e) => setCfgForm({ ...cfgForm, timezone: e.target.value })}\n placeholder=\"Asia/Shanghai\"\n />\n </div>\n </div>\n\n {/* Light Sleep */}\n <Subsection label={t.configPhaseLight}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseLightHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.light.enabled} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, enabled: e.target.checked } })} />\n <span>{cfgForm.light.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.cron} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, cron: e.target.value } })} placeholder=\"0 */6 * * *\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightLookbackDays}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.lookbackDays} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, lookbackDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.limit} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configLightDedupe}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.light.dedupeSimilarity} onChange={(e) => setCfgForm({ ...cfgForm, light: { ...cfgForm.light, dedupeSimilarity: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n\n {/* Deep Sleep */}\n <Subsection label={t.configPhaseDeep}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseDeepHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.deep.enabled} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, enabled: e.target.checked } })} />\n <span>{cfgForm.deep.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.cron} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, cron: e.target.value } })} placeholder=\"0 3 * * *\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMinScore}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.minScore} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, minScore: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMinRecallCount}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.minRecallCount} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, minRecallCount: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.limit} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepHalfLife}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.recencyHalfLifeDays} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, recencyHalfLifeDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configDeepMaxAge}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.deep.maxAgeDays} onChange={(e) => setCfgForm({ ...cfgForm, deep: { ...cfgForm.deep, maxAgeDays: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n\n {/* REM Sleep */}\n <Subsection label={t.configPhaseRem}>\n <p className=\"text-xs text-fg-muted\">{t.configPhaseRemHint}</p>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseEnabled}</div>\n <label className=\"mt-2 inline-flex items-center gap-2 text-sm text-fg\">\n <input type=\"checkbox\" className=\"ui-checkbox\" checked={cfgForm.rem.enabled} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, enabled: e.target.checked } })} />\n <span>{cfgForm.rem.enabled ? t.on : t.off}</span>\n </label>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configPhaseCron}</div>\n <input className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.cron} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, cron: e.target.value } })} placeholder=\"0 5 * * 0\" />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemLookbackDays}</div>\n <input type=\"number\" step=\"1\" min={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.lookbackDays} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, lookbackDays: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemLimit}</div>\n <input type=\"number\" step=\"1\" min={0} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.limit} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, limit: Number(e.target.value) } })} />\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.configRemMinStrength}</div>\n <input type=\"number\" step=\"0.01\" min={0} max={1} className=\"mt-2 w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg dark:border-edge\" value={cfgForm.rem.minPatternStrength} onChange={(e) => setCfgForm({ ...cfgForm, rem: { ...cfgForm.rem, minPatternStrength: Number(e.target.value) } })} />\n </div>\n </div>\n </Subsection>\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.configLoading}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection className=\"min-w-0\">\n <SettingsFormSectionHeader\n icon={Activity}\n title={t.runtimeTitle}\n subtitle={t.runtimeHint}\n trailing={isLoading ? <Loader2 className=\"size-4 shrink-0 animate-spin text-fg-muted\" aria-hidden /> : null}\n />\n\n <div className=\"space-y-6\">\n <Subsection label={t.subsectionSchedule}>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.enabled}</div>\n <div className={rowValueClass()}>{data ? (data.config.enabled ? t.on : t.off) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.lock}</div>\n <div className={cn(rowValueClass(), lockLabel?.className)}>{lockLabel ? lockLabel.text : '—'}</div>\n </div>\n <div className={cn(settingsFormSectionClassName(), 'sm:col-span-2')}>\n <div className={rowLabelClass()}>{t.schedule}</div>\n <div className=\"mt-1 break-all font-mono text-sm text-fg\">{data ? data.config.frequency : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.timezone}</div>\n <div className={rowValueClass()}>{data ? data.config.timezone : '—'}</div>\n </div>\n </div>\n </Subsection>\n\n <Subsection label={t.subsectionStore}>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeEntries}</div>\n <div className={rowValueClass()}>{data ? String(data.store.entryCount) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storePromoted}</div>\n <div className={rowValueClass()}>{data ? String(data.store.promotedCount) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeUpdatedAt}</div>\n <div className={rowValueClass()}>{data ? isoShort(data.store.updatedAt) : '—'}</div>\n </div>\n <div className={settingsFormSectionClassName()}>\n <div className={rowLabelClass()}>{t.storeLastPromotedAt}</div>\n <div className={rowValueClass()}>{data ? isoShort(data.store.lastPromotedAt) : '—'}</div>\n </div>\n </div>\n </Subsection>\n\n {data?.config?.phases ? (\n <Subsection label={t.subsectionPhases}>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <PhaseStatusCard\n icon={<Sun className=\"size-4 text-amber-500\" />}\n label=\"Light\"\n enabled={data.config.phases.light.enabled}\n cron={data.config.phases.light.cron}\n details={`lookback=${data.config.phases.light.lookbackDays}d, limit=${data.config.phases.light.limit}, dedupe=${data.config.phases.light.dedupeSimilarity}`}\n t={t}\n />\n <PhaseStatusCard\n icon={<Moon className=\"size-4 text-indigo-500\" />}\n label=\"Deep\"\n enabled={data.config.phases.deep.enabled}\n cron={data.config.phases.deep.cron}\n details={`minScore=${data.config.phases.deep.minScore}, recalls≥${data.config.phases.deep.minRecallCount}, limit=${data.config.phases.deep.limit}, halfLife=${data.config.phases.deep.recencyHalfLifeDays}d`}\n t={t}\n />\n <PhaseStatusCard\n icon={<Sparkles className=\"size-4 text-purple-500\" />}\n label=\"REM\"\n enabled={data.config.phases.rem.enabled}\n cron={data.config.phases.rem.cron}\n details={`lookback=${data.config.phases.rem.lookbackDays}d, limit=${data.config.phases.rem.limit}, strength≥${data.config.phases.rem.minPatternStrength}`}\n t={t}\n />\n </div>\n </Subsection>\n ) : null}\n\n <Subsection label={t.subsectionLastRun}>\n <p className=\"mb-2 text-xs text-fg-muted\">{t.lastRunBlockHint}</p>\n {data?.lastRun?.exists ? (\n <div className=\"space-y-3\">\n {data.lastRun.parseError ? (\n <p className=\"text-sm text-amber-600 dark:text-amber-400\" role=\"alert\">\n {t.lastRunParseError}\n {': '}\n {data.lastRun.parseError}\n </p>\n ) : null}\n {data.lastRun.record ? (\n <div className=\"rounded-xl border border-edge-subtle bg-surface-panel/40 p-2 sm:p-3\">\n <LastRunStructuredView t={t} r={data.lastRun.record} />\n </div>\n ) : null}\n {data.lastRun.raw !== undefined && data.lastRun.raw !== null ? (\n <details className=\"group rounded-lg border border-edge-subtle\">\n <summary className=\"cursor-pointer list-none px-3 py-2 text-xs font-medium text-fg-muted marker:hidden [&::-webkit-details-marker]:hidden\">\n <span className=\"underline decoration-edge underline-offset-2 group-open:text-fg\">{t.lastRunRaw}</span>\n </summary>\n <pre className=\"max-h-[12rem] overflow-auto border-t border-edge-subtle p-3 text-xs text-fg-muted\">\n {JSON.stringify(data.lastRun.raw, null, 2)}\n </pre>\n </details>\n ) : null}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.lastRunEmpty}</p>\n )}\n </Subsection>\n\n <PhaseLastRunBlock label={t.subsectionLightLastRun} lastRun={data?.lightLastRun} t={t} />\n <PhaseLastRunBlock label={t.subsectionRemLastRun} lastRun={data?.remLastRun} t={t} />\n </div>\n </SettingsFormSection>\n </div>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={ScanLine}\n title={t.previewTitle}\n subtitle={t.previewHint}\n trailing={\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || previewLoading}\n onClick={() => void loadPreview()}\n >\n {previewLoading ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.previewLoad}\n </Button>\n }\n />\n {previewItems ? (\n previewItems.length > 0 ? (\n <div className=\"space-y-2\">\n {previewItems.map((it) => {\n const src = `${it.path}:${it.startLine}-${it.endLine}`;\n const skipped = it.skippedReason;\n return (\n <div\n key={`${it.key}:${it.hash}:${src}`}\n className=\"rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-3\"\n >\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-fg-muted\">\n <span className=\"font-medium text-fg\">{src}</span>\n <span>score={it.score.toFixed(3)}</span>\n <span>recalls={it.recallCount}</span>\n <span>avg={it.avgScore.toFixed(3)}</span>\n <span>decay={it.recencyDecay?.toFixed(3) ?? '—'}</span>\n {skipped ? (\n <span className=\"text-amber-600 dark:text-amber-400\">{skipped}</span>\n ) : (\n <span className=\"text-emerald-600 dark:text-emerald-400\">{t.previewEligible}</span>\n )}\n </div>\n {it.snippet ? <div className=\"mt-2 text-sm text-fg\">{it.snippet}</div> : null}\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.previewEmpty}</p>\n )\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.previewNotLoaded}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Activity}\n title={t.eventsTitle}\n subtitle={t.eventsHint}\n trailing={\n <Button\n variant=\"secondary\"\n className=\"px-2.5 py-1.5 text-xs\"\n disabled={!hasToken || eventsLoading}\n onClick={() => void loadEvents()}\n >\n {eventsLoading ? <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden /> : null}\n {t.eventsLoad}\n </Button>\n }\n />\n {events ? (\n events.length > 0 ? (\n <div className=\"space-y-1.5\">\n {events.map((ev, idx) => {\n const phaseIcon = ev.phase === 'light' ? '☀️' : ev.phase === 'rem' ? '✨' : '🌙';\n const metrics = ev.phase === 'light'\n ? `scanned=${ev.scannedEntries ?? 0} new=${ev.newSignals ?? 0} deduped=${ev.deduped ?? 0}`\n : ev.phase === 'rem'\n ? `patterns=${ev.patternsDiscovered ?? 0} analyzed=${ev.entriesAnalyzed ?? 0}`\n : `candidates=${ev.candidates ?? 0} applied=${ev.applied ?? 0}`;\n return (\n <div\n key={`${ev.timestamp}:${ev.phase}:${idx}`}\n className=\"flex flex-wrap items-center gap-x-3 gap-y-1 rounded-lg border border-edge-subtle bg-surface-panel/60 px-3 py-2 text-xs\"\n >\n <span>{phaseIcon}</span>\n <span className=\"font-medium text-fg\">{ev.phase}</span>\n <span className={cn('font-medium', ev.ok ? 'text-emerald-600 dark:text-emerald-400' : 'text-amber-600 dark:text-amber-400')}>\n {ev.ok ? 'OK' : 'FAIL'}\n </span>\n <span className=\"text-fg-muted\">{metrics}</span>\n <span className=\"text-fg-muted\">{formatDurationMs(ev.durationMs)}</span>\n <span className=\"ml-auto text-fg-subtle\">{isoShort(ev.timestamp)}</span>\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.eventsEmpty}</p>\n )\n ) : (\n <p className=\"text-sm text-fg-muted\">{t.eventsNotLoaded}</p>\n )}\n </SettingsFormSection>\n\n <SettingsFormSection className=\"max-w-2xl\">\n <SettingsFormSectionHeader icon={Wrench} title={t.maintenanceTitle} subtitle={t.maintenanceHint} />\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <Button\n variant=\"secondary\"\n disabled={disabled}\n onClick={() => {\n if (!confirm(t.confirmResetStore)) return;\n void doAction('reset_store');\n }}\n >\n {actionBusy === 'reset_store' ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Trash2 className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.resetStore}\n </Button>\n <Button\n variant=\"secondary\"\n disabled={disabled}\n onClick={() => {\n if (!confirm(t.confirmClearLock)) return;\n void doAction('clear_lock');\n }}\n >\n {actionBusy === 'clear_lock' ? (\n <Loader2 className=\"mr-2 size-4 animate-spin\" aria-hidden />\n ) : (\n <Unlock className=\"mr-2 size-4\" aria-hidden />\n )}\n {t.clearLock}\n </Button>\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type { GatewaySettingsState, UpdatePackageChannel } from './gateway-settings.types';\n\nexport type { GatewaySettingsState, UpdatePackageChannel } from './gateway-settings.types';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport function normalizeGatewayFromConfig(config: unknown): GatewaySettingsState {\n const c = isRecord(config) ? config : {};\n const gw = isRecord(c.gateway) ? c.gateway : {};\n const auth = isRecord(gw.auth) ? gw.auth : {};\n const mode = auth.mode === 'none' || auth.mode === 'token' ? auth.mode : 'token';\n const upd = isRecord(c.update) ? c.update : {};\n const ch = upd.channel;\n const updateChannel: UpdatePackageChannel =\n ch === 'beta' || ch === 'dev' || ch === 'stable' ? ch : 'stable';\n return {\n host: typeof gw.host === 'string' ? gw.host : '',\n port: typeof gw.port === 'number' ? gw.port : undefined,\n auth: {\n mode,\n token: typeof auth.token === 'string' ? auth.token : '',\n },\n updateChannel,\n };\n}\n\nexport async function fetchGatewaySettings(): Promise<GatewaySettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeGatewayFromConfig(res.payload?.config ?? {});\n}\n\nexport async function patchGatewaySettings(state: GatewaySettingsState): Promise<void> {\n const token = state.auth.token.trim();\n const auth =\n token.length > 0\n ? { mode: state.auth.mode, token: state.auth.token }\n : { mode: state.auth.mode };\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n gateway: {\n auth,\n },\n update: {\n channel: state.updateChannel,\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { AlertCircle, Check, Copy, ExternalLink, Eye, EyeOff, Loader2, Server, Smartphone } from 'lucide-react';\nimport QRCode from 'qrcode';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n normalizeGatewayFromConfig,\n patchGatewaySettings,\n type GatewaySettingsState,\n} from '@/features/settings/gateway-config-api';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport {\n buildMobileGatewayPairDeepLink,\n getBaseUrl,\n isLoopbackHttpOrigin,\n} from '@/lib/url';\nimport { messages, type GatewaySettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nexport function GatewaySettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const g = m.gatewaySettings;\n const token = useGatewayStore((st) => st.token);\n const tokenExpired = useGatewayStore((st) => st.tokenExpired);\n const openTokenDialog = useGatewayStore((st) => st.openTokenDialog);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<GatewaySettingsState | null>(null);\n const [baseline, setBaseline] = useState<GatewaySettingsState | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const [showAccessToken, setShowAccessToken] = useState(false);\n const [copied, setCopied] = useState(false);\n const dirtyRef = useRef(false);\n\n const { data, error: swrError, isLoading, mutate } = useGatewayConfigSwr(hasToken);\n\n const parsed = useMemo(\n () =>\n data?.payload?.config !== undefined\n ? structuredClone(normalizeGatewayFromConfig(data.payload.config))\n : null,\n [data],\n );\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n dirtyRef.current = false;\n return;\n }\n if (parsed === null) return;\n if (!dirtyRef.current) {\n setForm(parsed);\n setBaseline(structuredClone(parsed));\n setSaveOk(false);\n }\n }, [hasToken, parsed]);\n\n const loading = Boolean(hasToken && isLoading && data === undefined && !swrError);\n const fetchError =\n swrError instanceof Error ? swrError.message : swrError ? String(swrError) : null;\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const updateAuth = useCallback((patch: Partial<GatewaySettingsState['auth']>) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, auth: { ...f.auth, ...patch } } : null));\n }, []);\n\n const updateChannel = useCallback((channel: GatewaySettingsState['updateChannel']) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, updateChannel: channel } : null));\n }, []);\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchGatewaySettings(form);\n dirtyRef.current = false;\n const next = structuredClone(form);\n setBaseline(next);\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : g.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, g.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n dirtyRef.current = false;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n const copyAccessToken = useCallback(async () => {\n const t = form?.auth.token;\n if (!t) return;\n await navigator.clipboard.writeText(t).catch(() => {});\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n }, [form?.auth.token]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.gateway}</h1>\n <p className=\"text-sm text-fg-muted\">{g.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {g.loading}\n </div>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? g.loadError}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\n {g.retry}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.gateway}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{g.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'gateway')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {g.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{g.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {g.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? g.saving : g.save}\n </Button>\n </div>\n </header>\n\n {tokenExpired ? (\n <div\n className=\"flex flex-col gap-3 rounded-lg border border-red-200 bg-red-50 px-4 py-3 dark:border-red-900/50 dark:bg-red-950/40\"\n role=\"alert\"\n >\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"mt-0.5 size-4 shrink-0 text-red-600 dark:text-red-400\" />\n <p className=\"text-sm text-red-900 dark:text-red-100\">{g.tokenExpired}</p>\n </div>\n <div>\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={() => openTokenDialog()}>\n {g.updateToken}\n </Button>\n </div>\n </div>\n ) : null}\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{g.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n {form.auth.mode === 'none' ? (\n <p className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\">\n {g.authModeNone}\n </p>\n ) : null}\n\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-5 flex items-center gap-2 text-sm font-semibold text-fg\">\n <Server className=\"size-4 text-accent\" strokeWidth={1.75} />\n {m.settingsSections.gateway}\n </div>\n <div className=\"space-y-4\">\n {(form.host || form.port != null) && (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{g.listenHost}</div>\n <div className=\"rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50\">\n {form.host || '—'}\n </div>\n </div>\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{g.listenPort}</div>\n <div className=\"rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50\">\n {form.port != null ? String(form.port) : '—'}\n </div>\n </div>\n <p className=\"sm:col-span-2 text-xs text-fg-subtle\">{g.listenHint}</p>\n </div>\n )}\n\n <AccessTokenField\n g={g}\n value={form.auth.token}\n show={showAccessToken}\n copied={copied}\n onToggleShow={() => setShowAccessToken((s) => !s)}\n onCopy={() => void copyAccessToken()}\n onChange={(token) => updateAuth({ token })}\n />\n\n <Button type=\"button\" variant=\"secondary\" className=\"w-full sm:w-auto\" onClick={() => openTokenDialog()}>\n {g.changeToken}\n </Button>\n\n {token ? <MobileGatewayPairCard g={g} gatewayToken={token} /> : null}\n\n <div className=\"space-y-2 border-t border-edge pt-4\">\n <label className=\"text-sm font-medium text-fg\" htmlFor=\"gateway-update-channel\">\n {g.updateChannel}\n </label>\n <select\n id=\"gateway-update-channel\"\n value={form.updateChannel}\n onChange={(e) => updateChannel(e.target.value as GatewaySettingsState['updateChannel'])}\n className={inputClassName()}\n >\n <option value=\"stable\">{g.channelStable}</option>\n <option value=\"beta\">{g.channelBeta}</option>\n <option value=\"dev\">{g.channelDev}</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{g.updateChannelHint}</p>\n </div>\n </div>\n </section>\n </div>\n );\n}\n\nfunction MobileGatewayPairCard({\n g,\n gatewayToken,\n}: {\n g: GatewaySettingsMessages;\n gatewayToken: string;\n}) {\n const [pairBaseUrl, setPairBaseUrl] = useState(getBaseUrl);\n const [qrDataUrl, setQrDataUrl] = useState<string | null>(null);\n const [qrGenFailed, setQrGenFailed] = useState(false);\n const [linkCopied, setLinkCopied] = useState(false);\n\n const trimmedBase = pairBaseUrl.trim();\n const baseOk = useMemo(() => {\n try {\n const u = new URL(trimmedBase);\n return u.protocol === 'http:' || u.protocol === 'https:';\n } catch {\n return false;\n }\n }, [trimmedBase]);\n\n const deepLink = useMemo(() => {\n if (!gatewayToken || !baseOk) return '';\n return buildMobileGatewayPairDeepLink({ baseUrl: trimmedBase, gatewayToken });\n }, [baseOk, gatewayToken, trimmedBase]);\n\n useEffect(() => {\n if (!deepLink) {\n setQrDataUrl(null);\n setQrGenFailed(false);\n return;\n }\n let cancelled = false;\n setQrGenFailed(false);\n void QRCode.toDataURL(deepLink, {\n width: 216,\n margin: 2,\n errorCorrectionLevel: 'M',\n color: { dark: '#000000ff', light: '#ffffffff' },\n })\n .then((url) => {\n if (!cancelled) setQrDataUrl(url);\n })\n .catch(() => {\n if (!cancelled) {\n setQrGenFailed(true);\n setQrDataUrl(null);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [deepLink]);\n\n const localhostWarn = baseOk && isLoopbackHttpOrigin(trimmedBase);\n\n const copyDeepLink = useCallback(async () => {\n if (!deepLink) return;\n await navigator.clipboard.writeText(deepLink).catch(() => {});\n setLinkCopied(true);\n window.setTimeout(() => setLinkCopied(false), 2000);\n }, [deepLink]);\n\n return (\n <div className=\"space-y-3 border-t border-edge pt-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Smartphone className=\"size-4 text-accent\" strokeWidth={1.75} />\n {g.mobilePairTitle}\n </div>\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairSubtitle}</p>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-fg\" htmlFor=\"gateway-mobile-pair-base\">\n {g.mobilePairBaseUrlLabel}\n </label>\n <input\n id=\"gateway-mobile-pair-base\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={pairBaseUrl}\n onChange={(e) => setPairBaseUrl(e.target.value)}\n />\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairBaseUrlHint}</p>\n {!baseOk ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{g.mobilePairInvalidBaseUrl}</p> : null}\n {localhostWarn ? (\n <p className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\">\n {g.mobilePairLocalhostWarning}\n </p>\n ) : null}\n <p className=\"text-xs text-fg-subtle\">{g.mobilePairSecurityNote}</p>\n </div>\n\n {deepLink ? (\n <div className=\"flex flex-col items-center gap-3 sm:items-start\">\n {qrDataUrl && !qrGenFailed ? (\n <img\n src={qrDataUrl}\n alt=\"\"\n className=\"h-56 w-56 rounded-lg border border-edge-subtle bg-white object-contain p-3 dark:border-edge\"\n />\n ) : null}\n {!qrDataUrl && !qrGenFailed ? <p className=\"text-sm text-fg-muted\">{g.mobilePairEncoding}</p> : null}\n {qrGenFailed ? <p className=\"text-center text-sm text-fg-muted sm:text-left\">{g.mobilePairImageError}</p> : null}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-full sm:w-auto\"\n disabled={!deepLink}\n onClick={() => void copyDeepLink()}\n >\n {linkCopied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n {linkCopied ? g.mobilePairCopied : g.mobilePairCopyLink}\n </Button>\n </div>\n ) : null}\n\n <p className=\"break-all font-mono text-[10px] leading-relaxed text-fg-subtle\">{g.mobilePairSchemeHint}</p>\n </div>\n );\n}\n\nfunction AccessTokenField({\n g,\n value,\n show,\n copied,\n onToggleShow,\n onCopy,\n onChange,\n}: {\n g: GatewaySettingsMessages;\n value: string;\n show: boolean;\n copied: boolean;\n onToggleShow: () => void;\n onCopy: () => void;\n onChange: (v: string) => void;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"text-sm font-medium text-fg\">{g.accessToken}</div>\n <div className=\"flex flex-wrap gap-2\">\n <input\n className={cn(inputClassName(), 'min-w-0 flex-1 font-mono text-xs')}\n type={show ? 'text' : 'password'}\n autoComplete=\"off\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={g.tokenPlaceholder}\n />\n {value ? (\n <Button type=\"button\" variant=\"secondary\" className=\"px-2 py-1 text-xs\" onClick={onCopy}>\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n {copied ? g.copied : g.copy}\n </Button>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" className=\"px-2 py-1 text-xs\" onClick={onToggleShow}>\n {show ? <EyeOff className=\"size-3.5\" /> : <Eye className=\"size-3.5\" />}\n {show ? g.hide : g.show}\n </Button>\n </div>\n <p className=\"text-xs text-fg-subtle\">{g.tokenHelp}</p>\n </div>\n );\n}\n","import { getChannels } from '@/features/cron/cron-api';\nimport { apiUrl } from '@/lib/url';\n\nexport function channelsStatusSwrKey(): string {\n return apiUrl('/api/channels/status');\n}\n\n/** Same network call as `getChannels`; use with `channelsStatusSwrKey()` for SWR. */\nexport const fetchChannelsStatusSwr = getChannels;\n","import { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport function heartbeatMdSwrKey(): string {\n return apiUrl('/api/workspace/heartbeat-md');\n}\n\nexport async function fetchHeartbeatMdSwr(): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(heartbeatMdSwrKey());\n return typeof res.payload?.content === 'string' ? res.payload.content : '';\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { heartbeatMdSwrKey } from '@/features/settings/heartbeat-md-swr';\nimport { mutate } from 'swr';\n\nimport type { HeartbeatSettingsState } from './heartbeat-settings.types';\n\nexport type { HeartbeatSettingsState } from './heartbeat-settings.types';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nexport function normalizeHeartbeatFromConfig(config: unknown): HeartbeatSettingsState {\n const c = isRecord(config) ? config : {};\n const gw = isRecord(c.gateway) ? c.gateway : {};\n const hb = isRecord(gw.heartbeat) ? gw.heartbeat : {};\n const ahRaw = hb.activeHours;\n const ah = isRecord(ahRaw) ? ahRaw : null;\n const activeHours =\n ah && typeof ah.start === 'string' && typeof ah.end === 'string' && ah.start && ah.end\n ? {\n start: ah.start,\n end: ah.end,\n timezone: typeof ah.timezone === 'string' ? ah.timezone : '',\n }\n : null;\n return {\n enabled: Boolean(hb.enabled ?? true),\n intervalMs: typeof hb.intervalMs === 'number' && Number.isFinite(hb.intervalMs) ? hb.intervalMs : 1_800_000,\n target: typeof hb.target === 'string' ? hb.target : '',\n targetChatId: typeof hb.targetChatId === 'string' ? hb.targetChatId : '',\n prompt: typeof hb.prompt === 'string' ? hb.prompt : '',\n ackMaxChars:\n typeof hb.ackMaxChars === 'number' && Number.isFinite(hb.ackMaxChars) ? hb.ackMaxChars : '',\n isolatedSession: Boolean(hb.isolatedSession),\n activeHours,\n };\n}\n\nfunction buildHeartbeatPayload(state: HeartbeatSettingsState): Record<string, unknown> {\n const p: Record<string, unknown> = {\n enabled: state.enabled,\n intervalMs: state.intervalMs,\n };\n if (state.target.trim()) p.target = state.target.trim();\n else p.target = null;\n if (state.targetChatId.trim()) p.targetChatId = state.targetChatId.trim();\n else p.targetChatId = null;\n if (state.prompt.trim()) p.prompt = state.prompt.trim();\n else p.prompt = null;\n if (state.ackMaxChars === '' || state.ackMaxChars === undefined) {\n p.ackMaxChars = null;\n } else {\n p.ackMaxChars = state.ackMaxChars;\n }\n if (state.isolatedSession) p.isolatedSession = true;\n else p.isolatedSession = null;\n if (state.activeHours?.start?.trim() && state.activeHours?.end?.trim()) {\n p.activeHours = {\n start: state.activeHours.start.trim(),\n end: state.activeHours.end.trim(),\n ...(state.activeHours.timezone.trim()\n ? { timezone: state.activeHours.timezone.trim() }\n : {}),\n };\n } else {\n p.activeHours = null;\n }\n return p;\n}\n\nexport async function patchHeartbeatSettings(state: HeartbeatSettingsState): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n gateway: {\n heartbeat: buildHeartbeatPayload(state),\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchHeartbeatMd(): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(\n apiUrl('/api/workspace/heartbeat-md'),\n );\n return typeof res.payload?.content === 'string' ? res.payload.content : '';\n}\n\nexport async function putHeartbeatMd(content: string): Promise<void> {\n await fetchJson(apiUrl('/api/workspace/heartbeat-md'), {\n method: 'PUT',\n body: JSON.stringify({ content }),\n });\n void mutate(heartbeatMdSwrKey());\n}\n\n/** Queue one heartbeat run (same path as the interval timer). */\nexport async function triggerHeartbeat(reason?: string): Promise<void> {\n await fetchJson(apiUrl('/api/heartbeat/trigger'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(reason ? { reason } : {}),\n });\n}\n","/** Preset heartbeat intervals (ms). Must match gateway `intervalMs`. */\nexport const HEARTBEAT_INTERVAL_PRESET_MS_ORDER = [\n 30_000,\n 60_000,\n 300_000,\n 600_000,\n 900_000,\n 1_800_000,\n 3_600_000,\n 7_200_000,\n] as const;\n\nexport const HEARTBEAT_INTERVAL_PRESET_MS = new Set<number>(HEARTBEAT_INTERVAL_PRESET_MS_ORDER);\n","import { ExternalLink, Heart, Loader2, Play, RefreshCw } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { getSessionChatIds, type ChannelStatus, type SessionChatId } from '@/features/cron/cron-api';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport { channelsStatusSwrKey, fetchChannelsStatusSwr } from '@/features/settings/channels-status-swr';\nimport {\n normalizeHeartbeatFromConfig,\n patchHeartbeatSettings,\n putHeartbeatMd,\n triggerHeartbeat,\n} from '@/features/settings/heartbeat-config-api';\nimport { fetchHeartbeatMdSwr, heartbeatMdSwrKey } from '@/features/settings/heartbeat-md-swr';\nimport type { HeartbeatSettingsState } from '@/features/settings/heartbeat-settings.types';\nimport { SettingsFormSection } from '@/features/settings/settings-form-section';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type HeartbeatSettingsMessages } from '@/i18n/messages';\nimport {\n HEARTBEAT_INTERVAL_PRESET_MS,\n HEARTBEAT_INTERVAL_PRESET_MS_ORDER,\n} from '@/features/settings/heartbeat-interval-presets';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\ntype CronMessages = ReturnType<typeof messages>['cron'];\n\nfunction workspacePathFromConfig(cfg: unknown): string {\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) return '';\n const agents = (cfg as { agents?: unknown }).agents;\n if (!agents || typeof agents !== 'object' || Array.isArray(agents)) return '';\n const defaults = (agents as { defaults?: unknown }).defaults;\n if (!defaults || typeof defaults !== 'object' || Array.isArray(defaults)) return '';\n const w = (defaults as { workspace?: unknown }).workspace;\n return typeof w === 'string' ? w : '';\n}\n\nfunction intervalPresetLabel(\n ms: number,\n p: HeartbeatSettingsMessages['intervalPresets'],\n): string {\n switch (ms) {\n case 30_000:\n return p.every30s;\n case 60_000:\n return p.every1min;\n case 300_000:\n return p.every5min;\n case 600_000:\n return p.every10min;\n case 900_000:\n return p.every15min;\n case 1_800_000:\n return p.every30min;\n case 3_600_000:\n return p.every1h;\n case 7_200_000:\n return p.every2h;\n default:\n return String(ms);\n }\n}\n\nexport function HeartbeatSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const h = m.heartbeatSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<HeartbeatSettingsState | null>(null);\n const [baseline, setBaseline] = useState<HeartbeatSettingsState | null>(null);\n const [doc, setDoc] = useState<string>('');\n const [docBaseline, setDocBaseline] = useState<string>('');\n const [savingConfig, setSavingConfig] = useState(false);\n const [savingDoc, setSavingDoc] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveConfigOk, setSaveConfigOk] = useState(false);\n const [saveDocOk, setSaveDocOk] = useState(false);\n const [triggerLoading, setTriggerLoading] = useState(false);\n const [triggerOk, setTriggerOk] = useState(false);\n const [triggerError, setTriggerError] = useState<string | null>(null);\n const [sessionChatIds, setSessionChatIds] = useState<SessionChatId[]>([]);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: mdContent,\n error: mdErr,\n isLoading: mdLoading,\n mutate: mutMd,\n } = useSWR(hasToken ? heartbeatMdSwrKey() : null, fetchHeartbeatMdSwr, { revalidateOnFocus: false });\n const { data: channels = [] } = useSWR(hasToken ? channelsStatusSwrKey() : null, fetchChannelsStatusSwr, {\n revalidateOnFocus: false,\n });\n\n const workspacePath = useMemo(\n () => workspacePathFromConfig(cfgData?.payload?.config),\n [cfgData],\n );\n\n const heartbeatParsed = useMemo(\n () => normalizeHeartbeatFromConfig(cfgData?.payload?.config ?? {}),\n [cfgData],\n );\n\n const dirtyConfig = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const dirtyDoc = useMemo(() => doc !== docBaseline, [doc, docBaseline]);\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n return;\n }\n if (cfgData === undefined) return;\n if (!dirtyConfig) {\n const next = structuredClone(heartbeatParsed);\n setForm(next);\n setBaseline(next);\n setSaveConfigOk(false);\n }\n }, [hasToken, cfgData, heartbeatParsed, dirtyConfig]);\n\n useEffect(() => {\n if (!hasToken || mdContent === undefined) return;\n if (!dirtyDoc) {\n setDoc(mdContent);\n setDocBaseline(mdContent);\n setSaveDocOk(false);\n }\n }, [hasToken, mdContent, dirtyDoc]);\n\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : mdErr instanceof Error\n ? mdErr.message\n : mdErr\n ? String(mdErr)\n : null;\n\n const loading = Boolean(\n hasToken &&\n (cfgData === undefined || mdContent === undefined) &&\n !fetchError &&\n (cfgLoading || mdLoading),\n );\n\n useEffect(() => {\n if (!hasToken || !form) {\n setSessionChatIds([]);\n return;\n }\n const t = form.target.trim();\n if (!t) {\n setSessionChatIds([]);\n return;\n }\n let cancelled = false;\n void getSessionChatIds(t).then((ids) => {\n if (!cancelled) setSessionChatIds(ids);\n });\n return () => {\n cancelled = true;\n };\n }, [hasToken, form?.target]);\n\n const refreshSessionChatIds = useCallback(() => {\n const t = form?.target?.trim();\n if (!t) return;\n void getSessionChatIds(t).then(setSessionChatIds);\n }, [form?.target]);\n\n const runHeartbeatNow = useCallback(async () => {\n setTriggerLoading(true);\n setTriggerOk(false);\n setTriggerError(null);\n try {\n await triggerHeartbeat();\n setTriggerOk(true);\n window.setTimeout(() => setTriggerOk(false), 3000);\n } catch (e) {\n setTriggerError(e instanceof Error ? e.message : h.triggerError);\n } finally {\n setTriggerLoading(false);\n }\n }, [h.triggerError]);\n\n const update = useCallback((patch: Partial<HeartbeatSettingsState>) => {\n setForm((f) => (f ? { ...f, ...patch } : null));\n }, []);\n\n const discardConfiguration = useCallback(() => {\n if (!baseline) return;\n setForm(structuredClone(baseline));\n setSaveConfigOk(false);\n setError(null);\n }, [baseline]);\n\n const discardDocument = useCallback(() => {\n setDoc(docBaseline);\n setSaveDocOk(false);\n setError(null);\n }, [docBaseline]);\n\n const saveConfiguration = useCallback(async () => {\n if (!form || savingConfig) return;\n setSavingConfig(true);\n setError(null);\n setSaveConfigOk(false);\n try {\n await patchHeartbeatSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setSaveConfigOk(true);\n window.setTimeout(() => setSaveConfigOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : h.saveConfigError);\n } finally {\n setSavingConfig(false);\n }\n }, [form, savingConfig, h.saveConfigError]);\n\n const saveDocument = useCallback(async () => {\n if (savingDoc) return;\n setSavingDoc(true);\n setError(null);\n setSaveDocOk(false);\n try {\n await putHeartbeatMd(doc);\n setDocBaseline(doc);\n setSaveDocOk(true);\n window.setTimeout(() => setSaveDocOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : h.saveDocError);\n } finally {\n setSavingDoc(false);\n }\n }, [doc, savingDoc, h.saveDocError]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.heartbeat}</h1>\n <p className=\"text-sm text-fg-muted\">{h.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {h.loading}\n </div>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? h.loadError}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutMd();\n }}\n >\n {h.retry}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.heartbeat}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{h.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'heartbeat')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {h.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n </header>\n\n {workspacePath ? (\n <p className=\"text-xs text-fg-subtle\">\n {h.workspaceLabel}: <span className=\"font-mono text-fg-muted\">{workspacePath}</span>\n </p>\n ) : null}\n\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <SettingsFormSection>\n <div className=\"mb-2 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Heart className=\"size-4 text-accent\" strokeWidth={1.75} />\n {h.configSection}\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex items-center gap-2\"\n disabled={triggerLoading}\n onClick={() => void runHeartbeatNow()}\n >\n {triggerLoading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Play className=\"size-4\" strokeWidth={1.75} aria-hidden />\n )}\n {triggerLoading ? h.triggering : h.triggerNow}\n </Button>\n {triggerOk ? <span className=\"text-sm text-fg-muted\">{h.triggered}</span> : null}\n </div>\n </div>\n <p className=\"mb-4 text-xs text-fg-subtle\">{h.triggerHint}</p>\n {triggerError ? <p className=\"mb-3 text-sm text-red-600 dark:text-red-400\">{triggerError}</p> : null}\n <HeartbeatConfigFields\n h={h}\n cron={m.cron}\n form={form}\n channels={channels}\n sessionChatIds={sessionChatIds}\n onRefreshChatIds={refreshSessionChatIds}\n update={update}\n inputClassName={inputClassName}\n selectClassName={selectClassName}\n />\n <div className=\"mt-4 flex flex-wrap items-center gap-2\">\n {saveConfigOk ? <span className=\"text-sm text-fg-muted\">{h.savedConfig}</span> : null}\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={!dirtyConfig || savingConfig}\n onClick={discardConfiguration}\n >\n {h.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={!dirtyConfig || savingConfig}\n onClick={() => void saveConfiguration()}\n >\n {savingConfig ? h.savingConfig : h.saveConfig}\n </Button>\n {dirtyConfig ? <span className=\"text-xs text-amber-800 dark:text-amber-200\">{h.unsavedConfig}</span> : null}\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <div className=\"mb-2 text-sm font-semibold text-fg\">{h.docSection}</div>\n <p className=\"mb-3 text-xs text-fg-subtle\">{h.docHint}</p>\n <textarea\n className={cn(inputClassName(), 'min-h-[12rem] resize-y font-mono text-xs leading-relaxed')}\n value={doc}\n onChange={(e) => setDoc(e.target.value)}\n spellCheck={false}\n aria-label={h.docSection}\n />\n <div className=\"mt-4 flex flex-wrap items-center gap-2\">\n {saveDocOk ? <span className=\"text-sm text-fg-muted\">{h.savedDoc}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirtyDoc || savingDoc} onClick={discardDocument}>\n {h.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n disabled={!dirtyDoc || savingDoc}\n onClick={() => void saveDocument()}\n >\n {savingDoc ? h.savingDoc : h.saveDoc}\n </Button>\n {dirtyDoc ? <span className=\"text-xs text-amber-800 dark:text-amber-200\">{h.unsavedDoc}</span> : null}\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n\nfunction HeartbeatConfigFields({\n h,\n cron: c,\n form,\n channels,\n sessionChatIds,\n onRefreshChatIds,\n update,\n inputClassName: inputCn,\n selectClassName: selectCn,\n}: {\n h: HeartbeatSettingsMessages;\n cron: CronMessages;\n form: HeartbeatSettingsState;\n channels: ChannelStatus[];\n sessionChatIds: SessionChatId[];\n onRefreshChatIds: () => void;\n update: (patch: Partial<HeartbeatSettingsState>) => void;\n inputClassName: typeof inputClassName;\n selectClassName: typeof selectClassName;\n}) {\n const channelNames = useMemo(() => new Set(channels.map((x) => x.name)), [channels]);\n const targetTrim = form.target.trim();\n const showCustomChannel = Boolean(targetTrim && !channelNames.has(targetTrim));\n\n const intervalPresetSelectValue = useMemo(\n () => (HEARTBEAT_INTERVAL_PRESET_MS.has(form.intervalMs) ? String(form.intervalMs) : ''),\n [form.intervalMs],\n );\n\n const [intervalSecondsDraft, setIntervalSecondsDraft] = useState<string | null>(null);\n const intervalSecondsCommitted = Math.max(1, Math.round(form.intervalMs / 1000));\n const intervalSecondsInputValue =\n intervalSecondsDraft !== null ? intervalSecondsDraft : String(intervalSecondsCommitted);\n\n useEffect(() => {\n setIntervalSecondsDraft(null);\n }, [form.intervalMs]);\n\n return (\n <div className=\"space-y-4\">\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={form.enabled}\n onChange={(e) => update({ enabled: e.target.checked })}\n />\n {h.enable}\n </label>\n\n <div className=\"flex flex-col gap-2\">\n <div className=\"text-sm font-medium text-fg\">{h.interval}</div>\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{h.intervalSecondsLabel}</span>\n <div className=\"flex gap-2\">\n <input\n type=\"number\"\n min={1}\n step={1}\n className={cn(inputCn(), 'min-w-0 flex-1')}\n value={intervalSecondsInputValue}\n onChange={(e) => {\n const next = e.target.value;\n setIntervalSecondsDraft(next);\n const raw = parseInt(next, 10);\n if (Number.isFinite(raw) && raw >= 1) {\n update({ intervalMs: raw * 1000 });\n }\n }}\n onBlur={() => {\n if (intervalSecondsDraft === null) return;\n const raw = parseInt(intervalSecondsDraft, 10);\n if (!Number.isFinite(raw) || raw < 1) {\n update({ intervalMs: 1000 });\n } else {\n update({ intervalMs: raw * 1000 });\n }\n setIntervalSecondsDraft(null);\n }}\n />\n <select\n className={cn(selectCn(), 'max-w-[11rem] shrink-0 text-xs')}\n value={intervalPresetSelectValue}\n onChange={(e) => {\n const v = e.target.value;\n if (v) {\n update({ intervalMs: parseInt(v, 10) });\n setIntervalSecondsDraft(null);\n }\n }}\n >\n <option value=\"\">{h.intervalPresets.custom}</option>\n {HEARTBEAT_INTERVAL_PRESET_MS_ORDER.map((ms) => (\n <option key={ms} value={String(ms)}>\n {intervalPresetLabel(ms, h.intervalPresets)}\n </option>\n ))}\n </select>\n </div>\n </div>\n <p className=\"text-xs text-fg-muted\">{h.intervalHintPreset}</p>\n <p className=\"text-xs text-fg-subtle\">{h.intervalHint}</p>\n </div>\n\n <div className=\"border-t border-edge-subtle pt-4\">\n <div className=\"mb-2 text-sm font-medium text-fg\">{h.deliveryTitle}</div>\n\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.channel}</span>\n <select\n className={selectCn()}\n value={targetTrim}\n onChange={(e) => {\n const v = e.target.value.trim();\n update({ target: v, targetChatId: '' });\n }}\n >\n <option value=\"\">{h.channelNone}</option>\n {showCustomChannel ? (\n <option value={targetTrim}>\n {targetTrim} ({h.customChannelSuffix})\n </option>\n ) : null}\n {channels.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? '(disabled)' : ''}\n </option>\n ))}\n </select>\n </label>\n\n {targetTrim ? (\n <div className=\"mt-3 flex flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-fg-muted\">{c.recipient}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n title={c.refreshRecipientHint}\n onClick={onRefreshChatIds}\n >\n <RefreshCw className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {c.refreshList}\n </Button>\n </div>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n className={cn(inputCn(), 'min-w-0 flex-1')}\n value={form.targetChatId}\n onChange={(e) => update({ targetChatId: e.target.value })}\n placeholder={c.recipientPlaceholder}\n autoComplete=\"off\"\n />\n <select\n className={cn(selectCn(), 'max-w-[10rem] shrink-0 text-xs')}\n value={form.targetChatId}\n onChange={(e) => {\n const v = e.target.value;\n if (v) update({ targetChatId: v });\n }}\n >\n <option value=\"\">{c.selectRecipient}</option>\n {sessionChatIds.length > 0 ? (\n sessionChatIds.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, c.lastActiveLabels)}\n </option>\n ))\n ) : (\n <option value=\"\" disabled>\n {c.noRecentChatsOption}\n </option>\n )}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">\n {sessionChatIds.length > 0 ? c.enterManuallyOrSelect : c.noRecentChats}\n </p>\n </div>\n ) : null}\n\n <p className=\"mt-2 text-xs text-fg-subtle\">{h.deliveryHint}</p>\n </div>\n\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{h.prompt}</div>\n <textarea\n className={cn(inputCn(), 'min-h-[4.5rem] resize-y font-mono text-xs')}\n value={form.prompt}\n onChange={(e) => update({ prompt: e.target.value })}\n placeholder={h.promptPlaceholder}\n />\n <p className=\"mt-1 text-xs text-fg-subtle\">{h.promptHint}</p>\n </div>\n\n <div>\n <div className=\"mb-1 text-sm font-medium text-fg\">{h.ackMaxChars}</div>\n <input\n type=\"number\"\n min={1}\n className={inputCn()}\n value={form.ackMaxChars === '' ? '' : form.ackMaxChars}\n onChange={(e) => {\n const v = e.target.value;\n if (v === '') update({ ackMaxChars: '' });\n else {\n const n = parseInt(v, 10);\n update({ ackMaxChars: Number.isFinite(n) ? n : '' });\n }\n }}\n placeholder={h.ackDefaultPlaceholder}\n />\n <p className=\"mt-1 text-xs text-fg-subtle\">{h.ackMaxCharsHint}</p>\n </div>\n\n <label className=\"flex cursor-pointer items-start gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox mt-0.5\"\n checked={form.isolatedSession}\n onChange={(e) => update({ isolatedSession: e.target.checked })}\n />\n <span>\n {h.isolatedSession}\n <span className=\"mt-1 block text-xs text-fg-subtle\">{h.isolatedSessionHint}</span>\n </span>\n </label>\n\n <div className=\"border-t border-edge-subtle pt-4\">\n <div className=\"mb-2 text-sm font-medium text-fg\">{h.activeHoursTitle}</div>\n {form.activeHours ? (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeStart}</div>\n <input\n className={inputCn()}\n value={form.activeHours.start}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, start: e.target.value },\n })\n }\n placeholder=\"09:00\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeEnd}</div>\n <input\n className={inputCn()}\n value={form.activeHours.end}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, end: e.target.value },\n })\n }\n placeholder=\"22:00\"\n />\n </div>\n <div>\n <div className=\"mb-1 text-xs text-fg\">{h.activeTimezone}</div>\n <input\n className={inputCn()}\n value={form.activeHours.timezone}\n onChange={(e) =>\n update({\n activeHours: { ...form.activeHours!, timezone: e.target.value },\n })\n }\n placeholder=\"Asia/Shanghai\"\n />\n </div>\n </div>\n ) : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-sm\"\n onClick={() =>\n update({\n activeHours: { start: '09:00', end: '22:00', timezone: '' },\n })\n }\n >\n {h.addActiveHours}\n </Button>\n )}\n {form.activeHours ? (\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-xs\"\n onClick={() => update({ activeHours: null })}\n >\n {h.clearActiveHours}\n </Button>\n </div>\n ) : null}\n <p className=\"mt-2 text-xs text-fg-subtle\">{h.activeHoursHint}</p>\n </div>\n </div>\n );\n}\n","import * as Popover from '@radix-ui/react-popover';\nimport { Check, ChevronsUpDown } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport {\n comboboxTriggerLayoutClass,\n formControlBorderFocusClass,\n selectComboboxTriggerFocusClass,\n} from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { apiFetch } from '@/lib/fetch';\nimport { interaction } from '@/lib/interaction';\nimport { apiUrl } from '@/lib/url';\n\nexport type ImageProviderSummary = {\n id: string;\n defaultModel?: string;\n models: string[];\n /** From gateway: provider has resolvable API credentials. */\n configured?: boolean;\n};\n\nasync function fetchImageGenerationProviders(): Promise<ImageProviderSummary[]> {\n const res = await apiFetch(apiUrl('/api/image/providers'));\n if (!res.ok) throw new Error(`Image providers: HTTP ${res.status}`);\n const data = (await res.json()) as { payload?: { providers?: ImageProviderSummary[] } };\n return data.payload?.providers ?? [];\n}\n\nfunction modelIdsForProviders(providerList: ImageProviderSummary[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const p of providerList) {\n const models = p.models.length > 0 ? p.models : p.defaultModel ? [p.defaultModel] : [];\n for (const m of models) {\n const id = `${p.id}/${m}`;\n if (!seen.has(id)) {\n seen.add(id);\n out.push(id);\n }\n }\n }\n return out;\n}\n\n/** Only image-generation providers the gateway marks as configured (credentials available). */\nfunction buildConfiguredModelIds(providers: ImageProviderSummary[], currentValueTrimmed: string): string[] {\n const configuredOnly = providers.filter((p) => p.configured === true);\n const fromRegistry = modelIdsForProviders(configuredOnly);\n if (!currentValueTrimmed || fromRegistry.includes(currentValueTrimmed)) {\n return fromRegistry;\n }\n return [currentValueTrimmed, ...fromRegistry];\n}\n\nfunction idsMatchingQuery(ids: string[], query: string): string[] {\n const raw = query.trim().toLowerCase();\n if (!raw) return ids;\n const tokens = raw.split(/[/\\s]+/).filter(Boolean);\n return ids.filter((h) => {\n const lower = h.toLowerCase();\n return tokens.every((t) => lower.includes(t));\n });\n}\n\nconst SWR_KEY = 'image-generation-providers';\n\n/**\n * Dropdown only: choose a registered `provider/model` from the gateway. Search runs inside\n * the popover; the trigger is not a text field (no free-text model strings).\n */\nexport function ImageGenerationModelInput({\n value,\n disabled,\n placeholder,\n searchPlaceholder,\n noMatches,\n registryEmptyHint,\n outOfFilterNote,\n className,\n onChange,\n}: {\n value: string;\n disabled?: boolean;\n placeholder: string;\n searchPlaceholder: string;\n noMatches: string;\n /** When every provider is unconfigured and there is no current value. */\n registryEmptyHint?: string;\n /** Current value uses a provider that is not configured (still listed so you can change it). */\n outOfFilterNote?: string;\n className?: string;\n onChange: (modelId: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const { data: providers, isLoading, error } = useSWR(SWR_KEY, fetchImageGenerationProviders, {\n revalidateOnFocus: false,\n });\n\n const valueTrimmed = value.trim();\n const configuredOnlyIds = useMemo(\n () => modelIdsForProviders((providers ?? []).filter((p) => p.configured === true)),\n [providers],\n );\n const allIds = useMemo(\n () => buildConfiguredModelIds(providers ?? [], valueTrimmed),\n [providers, valueTrimmed],\n );\n const filtered = useMemo(() => idsMatchingQuery(allIds, query), [allIds, query]);\n const showOutOfFilterNote =\n Boolean(outOfFilterNote) &&\n Boolean(valueTrimmed) &&\n !configuredOnlyIds.includes(valueTrimmed);\n\n const label = value.trim() ? value : placeholder;\n const titleText = value.trim() || placeholder;\n\n const handleOpenChange = useCallback(\n (next: boolean) => {\n setOpen(next);\n if (!next) {\n setQuery('');\n }\n },\n [],\n );\n\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <Popover.Root open={open} onOpenChange={handleOpenChange} modal={false}>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n disabled={disabled || isLoading}\n title={isLoading ? '…' : titleText}\n className={cn(\n comboboxTriggerLayoutClass,\n 'items-center gap-2 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-2 text-left text-sm font-normal text-fg',\n interaction.transition,\n 'hover:border-edge hover:bg-surface-hover/45',\n selectComboboxTriggerFocusClass,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'dark:border-edge-subtle dark:hover:bg-surface-hover/55',\n className,\n )}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"min-w-0 truncate\">{isLoading ? '…' : label}</span>\n <ChevronsUpDown className=\"h-4 w-4 shrink-0 text-fg-subtle opacity-70\" aria-hidden />\n </button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n className=\"z-50 w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-edge-subtle bg-surface-panel p-1 shadow-elevated dark:border-edge-subtle\"\n side=\"bottom\"\n sideOffset={4}\n align=\"end\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <input\n type=\"search\"\n className={cn(\n 'mb-1 w-full rounded-lg border border-edge-subtle bg-surface-base px-2.5 py-1.5 text-sm text-fg placeholder:text-fg-disabled dark:bg-surface-hover/40',\n formControlBorderFocusClass,\n )}\n placeholder={searchPlaceholder}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => e.stopPropagation()}\n />\n <div className=\"max-h-60 overflow-auto\" role=\"listbox\" aria-label={searchPlaceholder}>\n {error ? (\n <div className=\"px-2 py-2 text-xs text-red-600 dark:text-red-400\">\n {error instanceof Error ? error.message : 'Failed to load image providers'}\n </div>\n ) : null}\n {!error && allIds.length === 0 && !isLoading ? (\n <div className=\"px-2 py-3 text-center text-xs text-fg-muted\">\n {registryEmptyHint ?? noMatches}\n </div>\n ) : null}\n {!error && allIds.length > 0 && filtered.length === 0 ? (\n <div className=\"px-2 py-3 text-center text-xs text-fg-muted\">{noMatches}</div>\n ) : null}\n {filtered.map((id) => (\n <button\n key={id}\n type=\"button\"\n role=\"option\"\n aria-selected={id === value}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-fg hover:bg-surface-hover',\n id === value && 'bg-surface-hover/90 font-medium dark:bg-surface-hover/70',\n )}\n onClick={() => {\n onChange(id);\n setOpen(false);\n setQuery('');\n }}\n >\n <Check className={cn('h-4 w-4 shrink-0', id !== value && 'invisible')} aria-hidden />\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">{id}</span>\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n {showOutOfFilterNote ? (\n <p className=\"text-xs text-amber-700 dark:text-amber-400/90\">{outOfFilterNote}</p>\n ) : null}\n </div>\n );\n}\n","import { Image as ImageIcon, Plus, Trash2 } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\n\nimport { AgentDefaultsField } from '../agent-defaults-field';\nimport type { AgentDefaultsPanelProps } from '../agent-defaults-panel-props';\nimport { ImageGenerationModelInput } from '../image-generation-model-input';\n\n/** Vision + image-generation defaults (`agents.defaults.*`) — lives on the Image generation settings page. */\nexport function AgentDefaultsImageModelChainsSection(props: AgentDefaultsPanelProps) {\n const { a, chat, form, update } = props;\n\n return (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={ImageIcon} title={a.cardModelsTitle} subtitle={a.cardModelsSubtitle} />\n <div className=\"mt-4 flex flex-col gap-5\">\n <AgentDefaultsField label={a.label.imageModel} description={a.desc.imageModel}>\n <ModelSelector\n value={form.imageModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n capabilitiesFilter=\"vision\"\n registryEmptyHint={a.visionRegistryEmpty}\n outOfFilterNote={a.visionOutOfFilterNote}\n onChange={(modelId) => update({ imageModel: modelId })}\n />\n </AgentDefaultsField>\n <AgentDefaultsField label={a.label.imageModelFallbacks} description={a.desc.imageModelFallbacks}>\n <div className=\"flex flex-col gap-2\">\n {form.imageModelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ModelSelector\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n capabilitiesFilter=\"vision\"\n registryEmptyHint={a.visionRegistryEmpty}\n outOfFilterNote={a.visionOutOfFilterNote}\n onChange={(modelId) => {\n const next = [...form.imageModelFallbacks];\n next[idx] = modelId;\n update({ imageModelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n imageModelFallbacks: form.imageModelFallbacks.filter((_, j) => j !== idx),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() => update({ imageModelFallbacks: [...form.imageModelFallbacks, ''] })}\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </AgentDefaultsField>\n <AgentDefaultsField label={a.label.imageGenerationModel} description={a.desc.imageGenerationModel}>\n <ImageGenerationModelInput\n value={form.imageGenerationModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n registryEmptyHint={a.imageGenRegistryEmpty}\n outOfFilterNote={a.imageGenOutOfFilterNote}\n onChange={(modelId) => update({ imageGenerationModel: modelId })}\n />\n </AgentDefaultsField>\n <AgentDefaultsField\n label={a.label.imageGenerationModelFallbacks}\n description={a.desc.imageGenerationModelFallbacks}\n >\n <div className=\"flex flex-col gap-2\">\n {form.imageGenerationModelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ImageGenerationModelInput\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n registryEmptyHint={a.imageGenRegistryEmpty}\n outOfFilterNote={a.imageGenOutOfFilterNote}\n onChange={(modelId) => {\n const next = [...form.imageGenerationModelFallbacks];\n next[idx] = modelId;\n update({ imageGenerationModelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n imageGenerationModelFallbacks: form.imageGenerationModelFallbacks.filter(\n (_, j) => j !== idx,\n ),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() =>\n update({ imageGenerationModelFallbacks: [...form.imageGenerationModelFallbacks, ''] })\n }\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </AgentDefaultsField>\n </div>\n </SettingsFormSection>\n );\n}\n","import { Image as ImageIcon, Loader2, RefreshCw, Save, Server } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport { AgentDefaultsImageModelChainsSection } from '@/features/settings/agents/agent-defaults-panels/image-model-chains-section';\nimport {\n fetchAgentDefaults,\n parseParamsJsonForSave,\n patchAgentDefaults,\n type AgentDefaultsState,\n} from '@/features/settings/config-api';\nimport {\n SettingsFormSection,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\ninterface ImageGenProviderSummary {\n id: string;\n label?: string;\n defaultModel?: string;\n models: string[];\n aliases?: string[];\n configured?: boolean;\n capabilities?: unknown;\n}\n\nfunction inputClass(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n );\n}\n\nconst PROVIDERS_SWR_KEY = '/api/image/providers';\n\nfunction pickImageDefaultsSlice(s: AgentDefaultsState) {\n return {\n imageModel: s.imageModel,\n imageModelFallbacks: s.imageModelFallbacks,\n imageGenerationModel: s.imageGenerationModel,\n imageGenerationModelFallbacks: s.imageGenerationModelFallbacks,\n imageGenerationModelTimeoutMs: s.imageGenerationModelTimeoutMs,\n imageGenerationModelAutoProviderFallback: s.imageGenerationModelAutoProviderFallback,\n };\n}\n\nasync function fetchImageProviders(): Promise<ImageGenProviderSummary[]> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { providers?: ImageGenProviderSummary[] };\n }>(apiUrl(PROVIDERS_SWR_KEY));\n return res?.payload?.providers ?? [];\n}\n\nexport function ImageModelsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.imageModelsSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n // Load + persist agent defaults (image-generation knobs).\n const [state, setState] = useState<AgentDefaultsState | null>(null);\n const [baseline, setBaseline] = useState<AgentDefaultsState | null>(null);\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [savedFlash, setSavedFlash] = useState(false);\n const [error, setError] = useState<string | undefined>(undefined);\n\n const reload = useCallback(async () => {\n if (!hasToken) return;\n setLoading(true);\n setError(undefined);\n try {\n const fresh = await fetchAgentDefaults();\n const snapshot = structuredClone(fresh);\n setState(snapshot);\n setBaseline(structuredClone(snapshot));\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n }, [hasToken]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n const patchAgentDefaultsLocal = useCallback((patch: Partial<AgentDefaultsState>) => {\n setState((s) => (s ? { ...s, ...patch } : null));\n }, []);\n\n // Provider catalogue (from /api/image/providers).\n const { data: providers = [], mutate: refreshProviders } = useSWR<ImageGenProviderSummary[]>(\n hasToken ? PROVIDERS_SWR_KEY : null,\n fetchImageProviders,\n { revalidateOnFocus: false },\n );\n\n // Tie config-payload SWR cache so other panels see our edits after save.\n const gwSwr = useGatewayConfigSwr(hasToken);\n\n const dirty = useMemo(() => {\n if (!state || !baseline) return false;\n return (\n JSON.stringify(pickImageDefaultsSlice(state)) !== JSON.stringify(pickImageDefaultsSlice(baseline))\n );\n }, [state, baseline]);\n\n const onSave = useCallback(async () => {\n if (!state) return;\n setSaving(true);\n setError(undefined);\n try {\n try {\n void parseParamsJsonForSave(state.paramsJson);\n } catch (e) {\n setError(\n e instanceof SyntaxError\n ? m.agentSettings.advanced.paramsInvalidJson\n : e instanceof Error\n ? e.message\n : m.agentSettings.advanced.paramsInvalidJson,\n );\n return;\n }\n await patchAgentDefaults(state);\n setBaseline(structuredClone(state));\n setSavedFlash(true);\n window.setTimeout(() => setSavedFlash(false), 1500);\n // Refresh shared SWR cache so models / agent defaults panels stay in sync.\n void gwSwr.mutate?.();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setSaving(false);\n }\n }, [state, gwSwr, m.agentSettings]);\n\n const onDiscard = useCallback(() => {\n if (!baseline) return;\n setState(structuredClone(baseline));\n setError(undefined);\n setSavedFlash(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-8 text-sm text-fg-muted\">\n {language === 'zh' ? '请先登录网关。' : 'Connect to a gateway to continue.'}\n </div>\n );\n }\n\n if (loading || !state) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main items-center gap-2 px-4 py-8 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" /> Loading…\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{t.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.subtitle}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n void reload();\n void refreshProviders();\n }}\n >\n <RefreshCw className=\"size-3.5\" />\n <span className=\"ml-1.5\">{t.refresh}</span>\n </Button>\n {savedFlash ? <span className=\"text-sm text-fg-muted\">{t.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" onClick={onDiscard} disabled={!dirty || saving}>\n {t.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={() => void onSave()} disabled={!dirty || saving}>\n {saving ? <Loader2 className=\"size-3.5 animate-spin\" /> : <Save className=\"size-3.5\" />}\n <span className=\"ml-1.5\">{saving ? t.saving : t.save}</span>\n </Button>\n </div>\n </header>\n\n {error ? (\n <div className=\"rounded-lg border border-red-500/30 bg-red-500/10 px-3 py-2 text-sm text-red-700 dark:text-red-300\">\n {error}\n </div>\n ) : null}\n\n <AgentDefaultsImageModelChainsSection\n form={state}\n update={patchAgentDefaultsLocal}\n a={m.agentSettings}\n chat={m.chat}\n />\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={ImageIcon} title={t.title} subtitle={t.subtitle} />\n <div className=\"flex flex-col gap-4\">\n <div className=\"rounded-lg border border-edge-subtle bg-surface-base px-3 py-2.5 text-xs leading-relaxed text-fg-muted\">\n {t.crossLinkHint}\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <label className=\"text-sm font-medium text-fg\">{t.timeoutLabel}</label>\n <input\n type=\"number\"\n min={0}\n step={1000}\n className={cn(inputClass(), 'max-w-[12rem]')}\n value={state.imageGenerationModelTimeoutMs ?? ''}\n placeholder=\"120000\"\n onChange={(e) => {\n const raw = e.target.value.trim();\n const next = raw === '' ? null : Math.max(0, Math.floor(Number(raw)));\n setState((prev) =>\n prev\n ? {\n ...prev,\n imageGenerationModelTimeoutMs: next && next > 0 ? next : null,\n }\n : null,\n );\n }}\n />\n <p className=\"text-xs text-fg-subtle\">{t.timeoutHint}</p>\n </div>\n <label className=\"flex items-start gap-3 text-sm\">\n <input\n type=\"checkbox\"\n className=\"mt-0.5\"\n checked={state.imageGenerationModelAutoProviderFallback}\n onChange={(e) =>\n setState((prev) =>\n prev\n ? { ...prev, imageGenerationModelAutoProviderFallback: e.target.checked }\n : null,\n )\n }\n />\n <span className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium text-fg\">{t.autoFallbackLabel}</span>\n <span className=\"text-xs text-fg-subtle\">{t.autoFallbackHint}</span>\n </span>\n </label>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Server} title={t.providersTitle} subtitle=\"\" />\n {providers.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{t.providersEmpty}</p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {providers.map((p) => (\n <div\n key={p.id}\n className=\"rounded-lg border border-edge bg-surface-panel px-4 py-3\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{p.label ?? p.id}</span>\n <span className=\"text-xs text-fg-subtle\">({p.id})</span>\n </div>\n {p.configured ? (\n <span className=\"rounded-full bg-accent-soft px-2 py-0.5 text-xs font-medium text-accent-fg\">\n {t.configured}\n </span>\n ) : (\n <span className=\"rounded-full border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-xs font-medium text-amber-700 dark:text-amber-300\">\n {t.missingKey}\n </span>\n )}\n </div>\n {p.defaultModel ? (\n <p className=\"mt-1 text-xs text-fg-subtle\">\n <span className=\"text-fg-muted\">{t.defaultModel}:</span> {p.id}/{p.defaultModel}\n </p>\n ) : null}\n {p.models.length > 0 ? (\n <p className=\"mt-0.5 text-xs text-fg-subtle\">\n <span className=\"text-fg-muted\">{t.modelsLabel}:</span>{' '}\n {p.models.map((mm) => `${p.id}/${mm}`).join(', ')}\n </p>\n ) : null}\n </div>\n ))}\n </div>\n )}\n </SettingsFormSection>\n </div>\n );\n}\n","import { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type {\n ApiType,\n CustomModel,\n ModelsJsonConfig,\n ProviderConfig,\n ValidationResult,\n} from './models-json.types';\n\nexport type {\n ApiType,\n CustomModel,\n ModelsJsonConfig,\n ProviderConfig,\n ValidationResult,\n} from './models-json.types';\n\nexport interface ModelsJsonStatus {\n config: ModelsJsonConfig;\n path: string;\n exists: boolean;\n loadError?: string;\n}\n\nexport interface ApiKeyTestResult {\n type: 'literal' | 'env' | 'command';\n resolved?: string;\n error?: string;\n}\n\nexport const API_TYPE_OPTIONS: { value: ApiType; label: string }[] = [\n { value: 'openai-completions', label: 'OpenAI Completions' },\n { value: 'openai-responses', label: 'OpenAI Responses' },\n { value: 'anthropic-messages', label: 'Anthropic Messages' },\n { value: 'google-generative-ai', label: 'Google Generative AI' },\n { value: 'azure-openai-responses', label: 'Azure OpenAI' },\n { value: 'bedrock-converse-stream', label: 'AWS Bedrock' },\n { value: 'openai-codex-responses', label: 'OpenAI Codex' },\n { value: 'google-gemini-cli', label: 'Google Gemini CLI' },\n { value: 'google-vertex', label: 'Google Vertex AI' },\n];\n\nfunction gatewayErrorMessage(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') return undefined;\n const o = body as { error?: unknown };\n if (typeof o.error === 'string') return o.error;\n if (o.error && typeof o.error === 'object' && 'message' in o.error) {\n const m = (o.error as { message?: unknown }).message;\n return typeof m === 'string' ? m : undefined;\n }\n return undefined;\n}\n\n/** Ensures `providers` exists when the gateway returns a partial object. */\nexport function normalizeModelsJsonConfig(input: unknown): ModelsJsonConfig {\n if (!input || typeof input !== 'object') {\n return { providers: {} };\n }\n const o = input as Record<string, unknown>;\n const raw = o.providers;\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n return input as ModelsJsonConfig;\n }\n return { ...o, providers: {} };\n}\n\nexport async function fetchModelsJson(): Promise<ModelsJsonStatus> {\n const res = await apiFetch(apiUrl('/api/models-json'));\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ModelsJsonStatus;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return {\n ...data.payload,\n config: normalizeModelsJsonConfig(data.payload.config),\n };\n}\n\nexport async function validateModelsJson(config: ModelsJsonConfig): Promise<ValidationResult> {\n const res = await apiFetch(apiUrl('/api/models-json/validate'), {\n method: 'POST',\n body: JSON.stringify({ config }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ValidationResult;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function saveModelsJson(\n config: ModelsJsonConfig,\n): Promise<{ saved: boolean; modelCount: number }> {\n const res = await apiFetch(apiUrl('/api/models-json'), {\n method: 'PATCH',\n body: JSON.stringify({ config }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: { saved: boolean; modelCount: number };\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function reloadModelsJson(): Promise<{ modelCount: number; error?: string }> {\n const res = await apiFetch(apiUrl('/api/models-json/reload'), { method: 'POST' });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: { modelCount: number; error?: string };\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport async function testApiKey(value: string): Promise<ApiKeyTestResult> {\n const res = await apiFetch(apiUrl('/api/models-json/test-api-key'), {\n method: 'POST',\n body: JSON.stringify({ value }),\n });\n const data = await res.json().catch(() => ({})) as {\n ok?: boolean;\n payload?: ApiKeyTestResult;\n error?: unknown;\n };\n if (!res.ok || !data.ok || !data.payload) {\n throw new Error(gatewayErrorMessage(data) || `HTTP ${res.status}`);\n }\n return data.payload;\n}\n\nexport function createCustomProvider(\n baseUrl: string,\n apiKey: string,\n api: ApiType = 'openai-completions',\n): ProviderConfig {\n return {\n baseUrl,\n apiKey,\n api,\n models: [],\n };\n}\n\nexport function createCustomModel(id: string, name?: string, overrides?: Partial<CustomModel>): CustomModel {\n return {\n id,\n name: name || id,\n input: ['text'],\n contextWindow: 128000,\n maxTokens: 16384,\n cost: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n ...overrides,\n };\n}\n\nexport function isShellCommand(value: string): boolean {\n return value.startsWith('!');\n}\n\nexport function isEnvVar(value: string): boolean {\n return /^[A-Z][A-Z0-9_]*$/.test(value);\n}\n\nexport function getApiKeyType(value: string): 'shell' | 'env' | 'literal' {\n if (isShellCommand(value)) return 'shell';\n if (isEnvVar(value)) return 'env';\n return 'literal';\n}\n\nexport function maskApiKey(value: string): string {\n if (!value) return '';\n if (value.length <= 8) return '••••';\n return `${value.slice(0, 4)}••••${value.slice(-4)}`;\n}\n","import { Cpu, Plus, Trash2 } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\n\nimport type { AgentDefaultsPanelProps } from '../agent-defaults-panel-props';\n\n/** Chat-only fallback chain (`agents.defaults.modelFallbacks`) — lives on the Models settings page. */\nexport function AgentDefaultsChatModelFallbacksSection(props: AgentDefaultsPanelProps) {\n const { a, chat, form, update } = props;\n\n return (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cpu} title={a.label.modelFallbacks} subtitle={a.desc.modelFallbacks} />\n <div className=\"mt-4 flex flex-col gap-2\">\n {form.modelFallbacks.map((fb, idx) => (\n <div key={idx} className=\"flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <ModelSelector\n value={fb}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => {\n const next = [...form.modelFallbacks];\n next[idx] = modelId;\n update({ modelFallbacks: next });\n }}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={a.removeModelFallback}\n onClick={() =>\n update({\n modelFallbacks: form.modelFallbacks.filter((_, j) => j !== idx),\n })\n }\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5\"\n onClick={() => update({ modelFallbacks: [...form.modelFallbacks, ''] })}\n >\n <Plus className=\"size-4 shrink-0\" strokeWidth={1.75} />\n {a.addModelFallback}\n </Button>\n </div>\n </SettingsFormSection>\n );\n}\n","import { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\n\nimport type { CustomModel, ModelsJsonConfig, ProviderConfig } from '../models-json-api';\n\nexport const PROVIDER_PRESETS: Record<string, Partial<ProviderConfig>> = {\n ollama: {\n baseUrl: 'http://localhost:11434/v1',\n api: 'openai-completions',\n apiKey: 'ollama',\n },\n lmstudio: {\n baseUrl: 'http://localhost:1234/v1',\n api: 'openai-completions',\n apiKey: 'lmstudio',\n },\n openrouter: {\n baseUrl: 'https://openrouter.ai/api/v1',\n api: 'openai-completions',\n apiKey: '',\n },\n zhipuCn: {\n baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4',\n api: 'openai-completions',\n apiKey: 'ZHIPU_API_KEY',\n },\n zaiGeneral: {\n baseUrl: 'https://api.z.ai/api/paas/v4',\n api: 'openai-completions',\n apiKey: 'ZAI_API_KEY',\n },\n};\n\nexport function providerIdForPreset(presetKey: string): string {\n if (presetKey === 'openrouter') return 'openrouter';\n if (presetKey === 'zhipuCn') return 'zhipu-cn';\n if (presetKey === 'zaiGeneral') return 'zai';\n return presetKey;\n}\n\nexport const INPUT_OPTIONS = [\n { value: 'text', labelKey: 'inputTextOnly' as const },\n { value: 'text,image', labelKey: 'inputTextVision' as const },\n];\n\nexport function inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nexport function selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nexport function parseInputSelect(model: CustomModel): string {\n const i = model.input || ['text'];\n if (i.includes('image')) return 'text,image';\n return 'text';\n}\n\nexport function inputFromSelect(sel: string): ('text' | 'image')[] {\n if (sel === 'text,image') return ['text', 'image'];\n return ['text'];\n}\n\nexport function updateProvider(\n config: ModelsJsonConfig,\n providerId: string,\n updates: Partial<ProviderConfig>,\n): ModelsJsonConfig {\n return {\n ...config,\n providers: {\n ...config.providers,\n [providerId]: {\n ...config.providers[providerId],\n ...updates,\n },\n },\n };\n}\n\nexport function removeProvider(config: ModelsJsonConfig, providerId: string): ModelsJsonConfig {\n const providers = { ...config.providers };\n delete providers[providerId];\n return { ...config, providers };\n}\n\nexport function addProviderEntry(\n config: ModelsJsonConfig,\n providerId: string,\n prov: ProviderConfig,\n): ModelsJsonConfig {\n return {\n ...config,\n providers: {\n ...config.providers,\n [providerId]: prov,\n },\n };\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport { createCustomModel, type CustomModel } from '../models-json-api';\n\nimport {\n inputClassName,\n INPUT_OPTIONS,\n inputFromSelect,\n parseInputSelect,\n selectClassName,\n} from './models-settings-lib';\n\ntype ModelDialogProps = {\n open: boolean;\n onOpenChange: (o: boolean) => void;\n providerId: string | null;\n model: CustomModel | null;\n isNew: boolean;\n onSave: (model: CustomModel) => void;\n m: ModelsSettingsMessages;\n};\n\nexport function ModelEditDialogContent({\n open,\n onOpenChange,\n providerId,\n model,\n isNew,\n onSave,\n m,\n}: ModelDialogProps) {\n const [form, setForm] = useState<Partial<CustomModel>>(() => createCustomModel(''));\n const [errors, setErrors] = useState<Map<string, string>>(() => new Map());\n\n useEffect(() => {\n if (!open) return;\n setErrors(new Map());\n setForm(model ? { ...model } : createCustomModel(''));\n }, [open, model]);\n\n const update = <K extends keyof CustomModel>(field: K, value: CustomModel[K]) => {\n setForm((f) => ({ ...f, [field]: value }));\n setErrors((prev) => {\n const next = new Map(prev);\n next.delete(field);\n return next;\n });\n };\n\n const validate = (): boolean => {\n const next = new Map<string, string>();\n const id = (form.id || '').trim();\n if (!id) next.set('id', m.modelIdRequired);\n if (form.contextWindow !== undefined && form.contextWindow <= 0) {\n next.set('contextWindow', m.mustBePositive);\n }\n if (form.maxTokens !== undefined && form.maxTokens <= 0) {\n next.set('maxTokens', m.mustBePositive);\n }\n setErrors(next);\n return next.size === 0;\n };\n\n const handleSave = () => {\n if (!validate()) return;\n const id = (form.id || '').trim();\n const result: CustomModel = {\n ...form,\n id,\n name: form.name?.trim() || id,\n reasoning: form.reasoning || false,\n input: form.input || ['text'],\n contextWindow: form.contextWindow ?? 128000,\n maxTokens: form.maxTokens ?? 16384,\n cost: {\n input: form.cost?.input ?? 0,\n output: form.cost?.output ?? 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n },\n };\n onSave(result);\n onOpenChange(false);\n };\n\n const inputSel = parseInputSelect(form as CustomModel);\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,720px)] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2',\n 'overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"mb-3 flex items-start justify-between gap-2\">\n <div>\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {isNew ? m.addModelTitle : m.editModelTitle}\n </Dialog.Title>\n {providerId ? (\n <p className=\"mt-0.5 text-xs text-fg-muted\">\n {m.modelProviderLabel}: {providerId}\n </p>\n ) : null}\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n aria-label={m.close}\n >\n <X className=\"size-4\" />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg\">\n {m.modelId}\n <span className=\"text-red-600 dark:text-red-400\"> *</span>\n </label>\n <input\n className={cn(inputClassName(), errors.has('id') && 'border-red-500')}\n value={form.id || ''}\n onChange={(e) => update('id', e.target.value)}\n placeholder=\"e.g. llama3.1:8b\"\n disabled={!isNew}\n />\n {errors.has('id') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('id')}</p>\n ) : null}\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.displayName}</label>\n <input\n className={inputClassName()}\n value={form.name || ''}\n onChange={(e) => update('name', e.target.value)}\n />\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.inputTypes}</label>\n <select\n className={selectClassName()}\n value={inputSel}\n onChange={(e) => update('input', inputFromSelect(e.target.value))}\n >\n {INPUT_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {m[opt.labelKey]}\n </option>\n ))}\n </select>\n </div>\n <label className=\"mt-6 flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={form.reasoning || false}\n onChange={(e) => update('reasoning', e.target.checked)}\n />\n {m.reasoning}\n </label>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.contextWindow}</label>\n <input\n type=\"number\"\n min={1}\n className={cn(inputClassName(), errors.has('contextWindow') && 'border-red-500')}\n value={form.contextWindow ?? 128000}\n onChange={(e) => update('contextWindow', parseInt(e.target.value, 10) || 0)}\n />\n {errors.has('contextWindow') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('contextWindow')}</p>\n ) : null}\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.maxOutputTokens}</label>\n <input\n type=\"number\"\n min={1}\n className={cn(inputClassName(), errors.has('maxTokens') && 'border-red-500')}\n value={form.maxTokens ?? 16384}\n onChange={(e) => update('maxTokens', parseInt(e.target.value, 10) || 0)}\n />\n {errors.has('maxTokens') ? (\n <p className=\"mt-1 text-xs text-red-600 dark:text-red-400\">{errors.get('maxTokens')}</p>\n ) : null}\n </div>\n </div>\n <div className=\"border-t border-edge-subtle pt-2 dark:border-edge\">\n <p className=\"mb-2 text-xs font-semibold text-fg\">{m.costSection}</p>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1 block text-xs text-fg-muted\">{m.costInput}</label>\n <input\n type=\"number\"\n step=\"any\"\n min={0}\n className={inputClassName()}\n value={form.cost?.input ?? 0}\n onChange={(e) =>\n update('cost', {\n ...form.cost,\n input: parseFloat(e.target.value) || 0,\n output: form.cost?.output ?? 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n })\n }\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs text-fg-muted\">{m.costOutput}</label>\n <input\n type=\"number\"\n step=\"any\"\n min={0}\n className={inputClassName()}\n value={form.cost?.output ?? 0}\n onChange={(e) =>\n update('cost', {\n ...form.cost,\n input: form.cost?.input ?? 0,\n output: parseFloat(e.target.value) || 0,\n cacheRead: form.cost?.cacheRead ?? 0,\n cacheWrite: form.cost?.cacheWrite ?? 0,\n })\n }\n />\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge\">\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"secondary\">\n {m.cancel}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={handleSave}>\n {isNew ? m.addModelConfirm : m.saveModelConfirm}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { AlertCircle, X } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport {\n API_TYPE_OPTIONS,\n type ApiType,\n type ProviderConfig,\n} from '../models-json-api';\n\nimport {\n inputClassName,\n PROVIDER_PRESETS,\n providerIdForPreset,\n selectClassName,\n} from './models-settings-lib';\n\ntype ProviderDialogProps = {\n open: boolean;\n onOpenChange: (o: boolean) => void;\n presetKey?: string | null;\n onConfirm: (providerId: string, prov: ProviderConfig) => void;\n m: ModelsSettingsMessages;\n};\n\nexport function ProviderAddDialog({ open, onOpenChange, presetKey, onConfirm, m }: ProviderDialogProps) {\n const [providerId, setProviderId] = useState('');\n const [preset, setPreset] = useState('custom');\n const [baseUrl, setBaseUrl] = useState('');\n const [api, setApi] = useState<ApiType>('openai-completions');\n const [apiKey, setApiKey] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (!open) return;\n setError(null);\n const pk = presetKey || null;\n if (pk && PROVIDER_PRESETS[pk]) {\n const p = PROVIDER_PRESETS[pk];\n setPreset(pk);\n setBaseUrl(p.baseUrl || '');\n setApi((p.api as ApiType) || 'openai-completions');\n setApiKey(p.apiKey ?? '');\n setProviderId(providerIdForPreset(pk));\n } else {\n setPreset('custom');\n setProviderId('');\n setBaseUrl('');\n setApi('openai-completions');\n setApiKey('');\n }\n }, [open, presetKey]);\n\n const applyPreset = (key: string) => {\n setPreset(key);\n if (key === 'custom') return;\n const p = PROVIDER_PRESETS[key];\n if (!p) return;\n setBaseUrl(p.baseUrl || '');\n setApi((p.api as ApiType) || 'openai-completions');\n setApiKey(p.apiKey ?? '');\n setProviderId(providerIdForPreset(key));\n };\n\n const handleSubmit = () => {\n const id = providerId.trim();\n if (!id) {\n setError(m.providerIdRequired);\n return;\n }\n setError(null);\n onConfirm(id, {\n baseUrl: baseUrl.trim() || undefined,\n api,\n apiKey: apiKey.trim() || undefined,\n models: [],\n });\n onOpenChange(false);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,640px)] w-[min(100%-2rem,32rem)] -translate-x-1/2 -translate-y-1/2',\n 'overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"mb-3 flex items-start justify-between gap-2\">\n <div>\n <Dialog.Title className=\"text-base font-semibold text-fg\">{m.addProviderTitle}</Dialog.Title>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{m.addProviderSubtitle}</p>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n aria-label={m.close}\n >\n <X className=\"size-4\" />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.presetLabel}</label>\n <select\n className={selectClassName()}\n value={preset}\n onChange={(e) => applyPreset(e.target.value)}\n >\n <option value=\"custom\">{m.presetCustom}</option>\n <option value=\"ollama\">{m.presetOllama}</option>\n <option value=\"lmstudio\">{m.presetLmStudio}</option>\n <option value=\"openrouter\">{m.presetOpenRouter}</option>\n <option value=\"zhipuCn\">{m.presetZhipuCn}</option>\n <option value=\"zaiGeneral\">{m.presetZaiGeneral}</option>\n </select>\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg\">\n {m.providerIdLabel}\n <span className=\"text-red-600 dark:text-red-400\"> *</span>\n </label>\n <input\n className={inputClassName()}\n value={providerId}\n onChange={(e) => setProviderId(e.target.value)}\n placeholder={m.providerIdPlaceholder}\n />\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.baseUrl}</label>\n <input\n className={inputClassName()}\n value={baseUrl}\n onChange={(e) => setBaseUrl(e.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.apiType}</label>\n <select\n className={selectClassName()}\n value={api}\n onChange={(e) => setApi(e.target.value as ApiType)}\n >\n {API_TYPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{m.apiKey}</label>\n <input\n className={inputClassName()}\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n placeholder={m.apiKeyPlaceholder}\n />\n </div>\n {error ? (\n <p className=\"flex items-center gap-1 text-xs text-red-600 dark:text-red-400\">\n <AlertCircle className=\"size-3.5 shrink-0\" />\n {error}\n </p>\n ) : null}\n </div>\n\n <div className=\"mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge\">\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"secondary\">\n {m.cancel}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={handleSubmit}>\n {m.addProviderConfirm}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import {\n Box,\n ChevronDown,\n ChevronRight,\n Cpu,\n Eye,\n EyeOff,\n Pencil,\n Plus,\n Trash2,\n Zap,\n} from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport { type ModelsSettingsMessages } from '@/i18n/messages';\n\nimport {\n API_TYPE_OPTIONS,\n getApiKeyType,\n maskApiKey,\n type ApiType,\n type CustomModel,\n type ModelsJsonConfig,\n} from '../models-json-api';\n\nimport { inputClassName, selectClassName, updateProvider } from './models-settings-lib';\n\nexport type ModelsTestResult = { type: string; resolved?: string; error?: string };\n\ntype ModelsProvidersListProps = {\n config: ModelsJsonConfig;\n setConfig: Dispatch<SetStateAction<ModelsJsonConfig>>;\n expanded: Set<string>;\n toggleExpand: (id: string) => void;\n showPw: Set<string>;\n toggleShowPw: (id: string) => void;\n testResults: Map<string, ModelsTestResult>;\n runTestKey: (providerId: string, value: string) => void;\n ms: ModelsSettingsMessages;\n removeProv: (providerId: string) => void;\n openModelDialog: (providerId: string, model: CustomModel | null, isNew: boolean) => void;\n setTestResults: Dispatch<SetStateAction<Map<string, ModelsTestResult>>>;\n};\n\nexport function ModelsProvidersList({\n config,\n setConfig,\n expanded,\n toggleExpand,\n showPw,\n toggleShowPw,\n testResults,\n runTestKey,\n ms,\n removeProv,\n openModelDialog,\n setTestResults,\n}: ModelsProvidersListProps) {\n return (\n <div className=\"flex flex-col gap-3\">\n {Object.entries(config.providers)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([id, prov]) => {\n const isEx = expanded.has(id);\n const nModels = prov.models?.length ?? 0;\n const keyType = prov.apiKey ? getApiKeyType(prov.apiKey) : null;\n const testResult = testResults.get(id);\n const pwVisible = showPw.has(id);\n\n return (\n <section\n key={id}\n className=\"overflow-hidden rounded-2xl bg-surface-base\"\n >\n <div className=\"flex items-center justify-between gap-2 border-b border-edge-subtle bg-surface-hover/35 px-3 py-2 dark:border-edge-subtle\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 text-left text-sm font-semibold text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n onClick={() => toggleExpand(id)}\n >\n {isEx ? (\n <ChevronDown className=\"size-4 shrink-0 text-fg-muted\" />\n ) : (\n <ChevronRight className=\"size-4 shrink-0 text-fg-muted\" />\n )}\n <span className=\"truncate\">{id}</span>\n {nModels > 0 ? (\n <span className=\"shrink-0 rounded-full bg-accent px-2 py-0.5 text-[10px] font-medium text-white\">\n {nModels}\n </span>\n ) : null}\n {keyType ? (\n <span\n className={cn(\n 'shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium',\n keyType === 'shell' && 'bg-blue-100 text-blue-800 dark:bg-blue-950 dark:text-blue-200',\n keyType === 'env' && 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200',\n keyType === 'literal' && 'bg-surface-hover text-fg-muted dark:bg-surface-active',\n )}\n >\n {keyType === 'shell' ? ms.badgeShell : keyType === 'env' ? ms.badgeEnv : ms.badgeLiteral}\n </span>\n ) : null}\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-red-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 dark:hover:text-red-400\"\n onClick={() => removeProv(id)}\n aria-label={ms.removeProvider}\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n\n {isEx ? (\n <div className=\"space-y-4 px-3 py-3\">\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.baseUrl}</label>\n <input\n className={inputClassName()}\n value={prov.baseUrl || ''}\n onChange={(e) =>\n setConfig((c) => updateProvider(c, id, { baseUrl: e.target.value }))\n }\n />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.apiType}</label>\n <select\n className={selectClassName()}\n value={prov.api || 'openai-completions'}\n onChange={(e) =>\n setConfig((c) =>\n updateProvider(c, id, { api: e.target.value as ApiType }),\n )\n }\n >\n {API_TYPE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div>\n <label className=\"mb-1 block text-xs font-medium text-fg-muted\">{ms.apiKey}</label>\n <div className=\"flex flex-wrap gap-2\">\n <input\n className={cn(inputClassName(), 'min-w-0 flex-1')}\n type={pwVisible ? 'text' : 'password'}\n autoComplete=\"off\"\n value={prov.apiKey || ''}\n onChange={(e) => {\n const v = e.target.value;\n setConfig((c) => updateProvider(c, id, { apiKey: v }));\n setTestResults((prev) => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }}\n placeholder={ms.apiKeyPlaceholder}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => toggleShowPw(id)}\n >\n {pwVisible ? (\n <>\n <EyeOff className=\"mr-1 size-3.5\" />\n {ms.hide}\n </>\n ) : (\n <>\n <Eye className=\"mr-1 size-3.5\" />\n {ms.show}\n </>\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => runTestKey(id, prov.apiKey || '')}\n >\n {ms.testKey}\n </Button>\n </div>\n {testResult ? (\n <p\n className={cn(\n 'mt-1 text-xs',\n testResult.error ? 'text-red-600 dark:text-red-400' : 'text-emerald-700 dark:text-emerald-400',\n )}\n >\n {testResult.error\n ? `${ms.testError}: ${testResult.error}`\n : `${ms.testOk} (${testResult.type}): ${maskApiKey(testResult.resolved || '')}`}\n </p>\n ) : null}\n <p className=\"mt-1 text-xs text-fg-subtle\">{ms.apiKeyHint}</p>\n </div>\n\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={prov.authHeader || false}\n onChange={(e) =>\n setConfig((c) => updateProvider(c, id, { authHeader: e.target.checked }))\n }\n />\n {ms.authHeader}\n </label>\n\n <div className=\"border-t border-edge-subtle pt-3 dark:border-edge\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{ms.modelsSection}</span>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"px-2 py-1 text-xs\"\n onClick={() => openModelDialog(id, null, true)}\n >\n <Plus className=\"mr-1 size-3.5\" />\n {ms.addModel}\n </Button>\n </div>\n {(prov.models || []).length === 0 ? (\n <p className=\"text-xs text-fg-muted\">{ms.modelsEmpty}</p>\n ) : (\n <ul className=\"space-y-2\">\n {(prov.models || []).map((mod) => (\n <li\n key={mod.id}\n className=\"flex items-center justify-between gap-2 rounded-lg border border-edge-subtle bg-surface-base px-3 py-2 dark:border-edge\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-fg\">{mod.id}</div>\n {mod.name && mod.name !== mod.id ? (\n <div className=\"truncate text-xs text-fg-muted\">{mod.name}</div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 gap-1\">\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-fg\"\n onClick={() => openModelDialog(id, mod, false)}\n aria-label={ms.editModel}\n >\n <Pencil className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n className=\"rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-red-600 dark:hover:text-red-400\"\n onClick={() => {\n if (!window.confirm(ms.removeModelConfirm.replace('{{id}}', mod.id))) return;\n setConfig((c) => {\n const p = c.providers[id];\n if (!p) return c;\n return updateProvider(c, id, {\n models: (p.models || []).filter((mm) => mm.id !== mod.id),\n });\n });\n }}\n aria-label={ms.removeModel}\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n ) : null}\n </section>\n );\n })}\n </div>\n );\n}\n\ntype ModelsSettingsEmptyStateProps = {\n ms: ModelsSettingsMessages;\n openAddProvider: (preset: string | null) => void;\n};\n\nexport function ModelsSettingsEmptyState({ ms, openAddProvider }: ModelsSettingsEmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center rounded-xl border-2 border-dashed border-edge-subtle bg-surface-panel px-6 py-12 text-center dark:border-edge\">\n <div className=\"mb-4 flex size-14 items-center justify-center rounded-full border border-edge bg-surface-base dark:border-edge\">\n <Cpu className=\"size-7 text-accent\" strokeWidth={1.5} />\n </div>\n <h2 className=\"mb-1 text-base font-semibold text-fg\">{ms.emptyTitle}</h2>\n <p className=\"mb-6 max-w-md text-sm text-fg-muted\">{ms.emptyDesc}</p>\n <Button\n type=\"button\"\n className=\"mb-6 bg-accent text-white hover:bg-accent/90\"\n onClick={() => openAddProvider(null)}\n >\n <Plus className=\"mr-1 size-4\" />\n {ms.emptyCta}\n </Button>\n <div className=\"flex flex-wrap justify-center gap-2\">\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('ollama')}\n >\n <Zap className=\"size-3.5\" aria-hidden />\n {ms.presetOllama}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('openrouter')}\n >\n <Box className=\"size-3.5\" aria-hidden />\n {ms.presetOpenRouter}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('lmstudio')}\n >\n <Cpu className=\"size-3.5\" aria-hidden />\n {ms.presetLmStudio}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('zhipuCn')}\n >\n <Zap className=\"size-3.5\" aria-hidden />\n {ms.presetZhipuCn}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge',\n interaction.transition,\n interaction.focusRingBase,\n )}\n onClick={() => openAddProvider('zaiGeneral')}\n >\n <Box className=\"size-3.5\" aria-hidden />\n {ms.presetZaiGeneral}\n </button>\n </div>\n </div>\n );\n}\n","import {\n AlertCircle,\n ExternalLink,\n Loader2,\n Plus,\n RefreshCw,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport {\n fetchModelsJson,\n normalizeModelsJsonConfig,\n reloadModelsJson,\n saveModelsJson,\n testApiKey,\n validateModelsJson,\n type CustomModel,\n type ModelsJsonConfig,\n type ProviderConfig,\n type ValidationResult,\n} from '../models-json-api';\nimport { AgentDefaultsChatModelFallbacksSection } from '../agents/agent-defaults-panels/chat-model-fallbacks-section';\nimport { useAgentDefaultsForm } from '../agents/use-agent-defaults-form';\n\nimport { ModelEditDialogContent } from './models-model-edit-dialog';\nimport { ProviderAddDialog } from './models-provider-add-dialog';\nimport {\n ModelsProvidersList,\n ModelsSettingsEmptyState,\n type ModelsTestResult,\n} from './models-providers-list';\nimport { addProviderEntry, inputClassName, removeProvider, updateProvider } from './models-settings-lib';\n\nexport function ModelsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const ms = m.modelsSettings;\n const agentVm = useAgentDefaultsForm(m.agentSettings);\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [config, setConfig] = useState<ModelsJsonConfig>({ providers: {} });\n const [baseline, setBaseline] = useState<ModelsJsonConfig>({ providers: {} });\n const [path, setPath] = useState('');\n const [loadMetaError, setLoadMetaError] = useState<string | undefined>();\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [validating, setValidating] = useState(false);\n const [reloading, setReloading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const [validation, setValidation] = useState<ValidationResult | null>(null);\n const [expanded, setExpanded] = useState<Set<string>>(() => new Set());\n const [showRawJson, setShowRawJson] = useState(false);\n const [rawText, setRawText] = useState('');\n const [rawError, setRawError] = useState<string | null>(null);\n const [showPw, setShowPw] = useState<Set<string>>(() => new Set());\n const [testResults, setTestResults] = useState<Map<string, ModelsTestResult>>(() => new Map());\n\n const [providerDialogOpen, setProviderDialogOpen] = useState(false);\n const [providerPreset, setProviderPreset] = useState<string | null>(null);\n\n const [modelDialogOpen, setModelDialogOpen] = useState(false);\n const [modelDialogCtx, setModelDialogCtx] = useState<{\n providerId: string;\n model: CustomModel | null;\n isNew: boolean;\n } | null>(null);\n\n const load = useCallback(async (opts?: { skipFullPageLoading?: boolean }) => {\n const showFullPageLoading = !opts?.skipFullPageLoading;\n if (showFullPageLoading) {\n setLoading(true);\n }\n setError(null);\n try {\n const st = await fetchModelsJson();\n const norm = normalizeModelsJsonConfig(st.config);\n setConfig(norm);\n setBaseline(structuredClone(norm));\n setPath(st.path);\n setLoadMetaError(st.loadError);\n setValidation(null);\n setSaveOk(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.loadError);\n setConfig({ providers: {} });\n setBaseline({ providers: {} });\n } finally {\n if (showFullPageLoading) {\n setLoading(false);\n }\n }\n }, [ms.loadError]);\n\n useEffect(() => {\n if (!hasToken) {\n setLoading(false);\n return;\n }\n void load();\n }, [hasToken, load]);\n\n const dirty = useMemo(\n () => JSON.stringify(config) !== JSON.stringify(baseline),\n [config, baseline],\n );\n\n const agentPanelProps = useMemo(() => {\n if (!agentVm.form) return null;\n return {\n form: agentVm.form,\n update: agentVm.update,\n a: m.agentSettings,\n chat: m.chat,\n };\n }, [agentVm.form, agentVm.update, m.agentSettings, m.chat]);\n\n const combinedDirty = dirty || agentVm.dirty;\n\n const stats = useMemo(() => {\n const ids = Object.keys(config.providers);\n let models = 0;\n for (const p of Object.values(config.providers)) {\n models += p.models?.length ?? 0;\n }\n return { providers: ids.length, models };\n }, [config.providers]);\n\n const toggleExpand = (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const toggleShowPw = (id: string) => {\n setShowPw((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const syncRawFromConfig = useCallback(() => {\n setRawText(JSON.stringify(config, null, 2));\n setRawError(null);\n }, [config]);\n\n useEffect(() => {\n if (showRawJson) syncRawFromConfig();\n }, [showRawJson, syncRawFromConfig]);\n\n const applyRawJson = () => {\n try {\n const parsed = JSON.parse(rawText) as unknown;\n const norm = normalizeModelsJsonConfig(parsed);\n setConfig(norm);\n setRawError(null);\n } catch {\n setRawError(ms.jsonParseError);\n }\n };\n\n const runValidate = async () => {\n setValidating(true);\n setError(null);\n try {\n const r = await validateModelsJson(config);\n setValidation(r);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.validateError);\n } finally {\n setValidating(false);\n }\n };\n\n const runSave = async () => {\n if (saving || agentVm.saving) return;\n const hadJsonDirty = dirty;\n const hadAgentDirty = agentVm.dirty;\n if (!hadJsonDirty && !hadAgentDirty) return;\n\n setError(null);\n setSaveOk(false);\n try {\n if (hadJsonDirty) {\n setSaving(true);\n try {\n await saveModelsJson(config);\n setBaseline(structuredClone(config));\n setValidation(null);\n } finally {\n setSaving(false);\n }\n }\n if (hadAgentDirty && agentVm.form) {\n const agentOk = await agentVm.save();\n if (!agentOk) {\n throw new Error(m.agentSettings.saveError);\n }\n }\n setSaveOk(true);\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.saveError);\n }\n };\n\n const runDiscard = useCallback(() => {\n setConfig(structuredClone(baseline));\n setValidation(null);\n setSaveOk(false);\n setError(null);\n if (showRawJson) {\n setRawText(JSON.stringify(baseline, null, 2));\n setRawError(null);\n }\n agentVm.discard();\n }, [baseline, showRawJson, agentVm.discard]);\n\n const runReload = async () => {\n setReloading(true);\n setError(null);\n try {\n await reloadModelsJson();\n await load({ skipFullPageLoading: true });\n } catch (e) {\n setError(e instanceof Error ? e.message : ms.reloadError);\n } finally {\n setReloading(false);\n }\n };\n\n const runTestKey = async (providerId: string, value: string) => {\n try {\n const r = await testApiKey(value);\n setTestResults((prev) => {\n const next = new Map(prev);\n next.set(providerId, r);\n return next;\n });\n } catch (e) {\n setTestResults((prev) => {\n const next = new Map(prev);\n next.set(providerId, {\n type: 'error',\n error: e instanceof Error ? e.message : 'Error',\n });\n return next;\n });\n }\n };\n\n const openAddProvider = (preset: string | null = null) => {\n setProviderPreset(preset);\n setProviderDialogOpen(true);\n };\n\n const onProviderAdded = (providerId: string, prov: ProviderConfig) => {\n setConfig((c) => addProviderEntry(c, providerId, prov));\n setExpanded((prev) => new Set(prev).add(providerId));\n };\n\n const removeProv = (providerId: string) => {\n if (!window.confirm(ms.removeProviderConfirm.replace('{{id}}', providerId))) return;\n setConfig((c) => removeProvider(c, providerId));\n setTestResults((prev) => {\n const next = new Map(prev);\n next.delete(providerId);\n return next;\n });\n };\n\n const openModelDialog = (providerId: string, model: CustomModel | null, isNew: boolean) => {\n setModelDialogCtx({ providerId, model, isNew });\n setModelDialogOpen(true);\n };\n\n const onModelSaved = (updated: CustomModel) => {\n if (!modelDialogCtx) return;\n const { providerId, isNew } = modelDialogCtx;\n setConfig((c) => {\n const p = c.providers[providerId];\n if (!p) return c;\n const models = p.models || [];\n if (isNew) {\n return updateProvider(c, providerId, { models: [...models, updated] });\n }\n return updateProvider(c, providerId, {\n models: models.map((mm) => (mm.id === updated.id ? updated : mm)),\n });\n });\n };\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.models}</h1>\n <p className=\"text-sm text-fg-muted\">{ms.needToken}</p>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-8\">\n <div className=\"flex flex-col gap-1\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.models}</h1>\n <p className=\"text-sm text-fg-muted\">{ms.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'models')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {ms.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n\n {loadMetaError ? (\n <div\n className=\"flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100\"\n role=\"status\"\n >\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{ms.loadFileWarning}: {loadMetaError}</span>\n </div>\n ) : null}\n\n {path ? (\n <p className=\"text-xs text-fg-subtle\">\n {ms.filePath}: <code className=\"rounded bg-surface-base px-1 py-0.5 font-mono text-fg-muted\">{path}</code>\n </p>\n ) : null}\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n className=\"bg-accent text-white hover:bg-accent/90\"\n onClick={() => openAddProvider(null)}\n disabled={loading}\n >\n <Plus className=\"mr-1 size-4\" />\n {ms.addProvider}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={runValidate}\n disabled={loading || validating}\n >\n {validating ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.validating}\n </>\n ) : (\n ms.validate\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={runDiscard}\n disabled={loading || saving || agentVm.saving || !combinedDirty}\n >\n {ms.discard}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[7.5rem] justify-center\"\n onClick={() => void runSave()}\n disabled={loading || saving || agentVm.saving || !combinedDirty}\n >\n {saving || agentVm.saving ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.saving}\n </>\n ) : (\n ms.save\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"inline-flex min-h-9 min-w-[8.5rem] justify-center\"\n onClick={runReload}\n disabled={loading || reloading}\n >\n {reloading ? (\n <>\n <Loader2 className=\"mr-1 size-4 animate-spin\" />\n {ms.reloading}\n </>\n ) : (\n <>\n <RefreshCw className=\"mr-1 size-4\" />\n {ms.reload}\n </>\n )}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"text-fg-muted\"\n onClick={() => {\n setShowRawJson((v) => !v);\n setRawError(null);\n }}\n >\n {showRawJson ? ms.hideJson : ms.showJson}\n </Button>\n <div className=\"ml-auto flex items-center gap-2 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-1.5 text-sm dark:border-edge\">\n <span className=\"text-fg-muted\">\n {ms.statsProviders.replace('{{count}}', String(stats.providers))}\n </span>\n <span className=\"text-fg-subtle\">|</span>\n <span className=\"text-fg-muted\">\n {ms.statsModels.replace('{{count}}', String(stats.models))}\n </span>\n </div>\n </div>\n\n {combinedDirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{ms.unsavedHint}</p> : null}\n {saveOk || agentVm.saveOk ? (\n <p className=\"text-xs text-emerald-700 dark:text-emerald-400\" role=\"status\">\n {ms.saved}\n </p>\n ) : null}\n {error ? (\n <p className=\"flex items-center gap-1 text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n <AlertCircle className=\"size-4 shrink-0\" />\n {error}\n </p>\n ) : null}\n {agentVm.error ? (\n <p className=\"flex items-center gap-1 text-sm text-red-600 dark:text-red-400\" role=\"alert\">\n <AlertCircle className=\"size-4 shrink-0\" />\n {agentVm.error}\n </p>\n ) : null}\n\n {validation && validation.errors.length > 0 ? (\n <div\n className=\"rounded-lg border border-amber-200 bg-amber-50/80 px-3 py-2 dark:border-amber-800 dark:bg-amber-950/30\"\n role=\"status\"\n >\n <p className=\"mb-1 text-sm font-medium text-amber-950 dark:text-amber-100\">\n {validation.valid ? ms.validationWarnings : ms.validationErrors}\n </p>\n <ul className=\"list-inside list-disc space-y-0.5 text-xs text-amber-900 dark:text-amber-200\">\n {validation.errors.map((err, i) => (\n <li key={`${err.path}-${i}`}>\n {err.path}: {err.message} ({err.severity})\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {loading ? (\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {ms.loading}\n </div>\n ) : showRawJson ? (\n <div className=\"flex flex-col gap-2\">\n <textarea\n className={cn(\n inputClassName(),\n 'min-h-[320px] resize-y font-mono text-xs leading-relaxed',\n )}\n value={rawText}\n onChange={(e) => setRawText(e.target.value)}\n spellCheck={false}\n />\n {rawError ? <p className=\"text-xs text-red-600 dark:text-red-400\">{rawError}</p> : null}\n <div className=\"flex gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={syncRawFromConfig}>\n {ms.jsonReset}\n </Button>\n <Button type=\"button\" className=\"bg-accent text-white hover:bg-accent/90\" onClick={applyRawJson}>\n {ms.jsonApply}\n </Button>\n </div>\n </div>\n ) : Object.keys(config.providers).length === 0 ? (\n <ModelsSettingsEmptyState ms={ms} openAddProvider={openAddProvider} />\n ) : (\n <ModelsProvidersList\n config={config}\n setConfig={setConfig}\n expanded={expanded}\n toggleExpand={toggleExpand}\n showPw={showPw}\n toggleShowPw={toggleShowPw}\n testResults={testResults}\n runTestKey={runTestKey}\n ms={ms}\n removeProv={removeProv}\n openModelDialog={openModelDialog}\n setTestResults={setTestResults}\n />\n )}\n\n {agentPanelProps ? (\n <div className=\"mt-10 border-t border-edge-subtle pt-8 dark:border-edge\">\n <AgentDefaultsChatModelFallbacksSection {...agentPanelProps} />\n </div>\n ) : null}\n\n <ProviderAddDialog\n open={providerDialogOpen}\n onOpenChange={setProviderDialogOpen}\n presetKey={providerPreset}\n onConfirm={onProviderAdded}\n m={ms}\n />\n\n <ModelEditDialogContent\n open={modelDialogOpen}\n onOpenChange={(o) => {\n setModelDialogOpen(o);\n if (!o) setModelDialogCtx(null);\n }}\n providerId={modelDialogCtx?.providerId ?? null}\n model={modelDialogCtx?.model ?? null}\n isNew={modelDialogCtx?.isNew ?? false}\n onSave={onModelSaved}\n m={ms}\n />\n </div>\n );\n}\n","import { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport interface OAuthStartResult {\n sessionId: string;\n provider: string;\n status: string;\n}\n\nexport interface OAuthSessionStatus {\n sessionId: string;\n provider: string;\n status: 'pending' | 'waiting_auth' | 'waiting_code' | 'completed' | 'failed' | 'cancelled';\n authUrl?: string;\n instructions?: string;\n message?: string;\n error?: string;\n expiresAt: number;\n}\n\nexport async function startAsyncOAuthLogin(provider: string): Promise<OAuthStartResult> {\n const res = await apiFetch(apiUrl('/api/auth/oauth-async/start'), {\n method: 'POST',\n body: JSON.stringify({ provider }),\n });\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { error?: string };\n throw new Error(err.error || `OAuth start failed: ${res.status}`);\n }\n const data = (await res.json()) as { payload: OAuthStartResult };\n return data.payload;\n}\n\nexport async function fetchOAuthSessionStatus(sessionId: string): Promise<OAuthSessionStatus> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/status`));\n if (!res.ok) {\n throw new Error(`OAuth status: ${res.status}`);\n }\n const data = (await res.json()) as { payload: OAuthSessionStatus };\n return data.payload;\n}\n\nexport async function submitOAuthCode(sessionId: string, code: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/code`), {\n method: 'POST',\n body: JSON.stringify({ code }),\n });\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { error?: string };\n throw new Error(err.error || `Submit code failed: ${res.status}`);\n }\n}\n\nexport async function cancelOAuth(sessionId: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}/cancel`), {\n method: 'POST',\n });\n if (!res.ok) {\n throw new Error(`Cancel OAuth failed: ${res.status}`);\n }\n}\n\nexport async function cleanupOAuthSession(sessionId: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth-async/${encodeURIComponent(sessionId)}`), {\n method: 'DELETE',\n });\n if (!res.ok) {\n throw new Error(`Cleanup session failed: ${res.status}`);\n }\n}\n\nexport async function revokeOAuth(provider: string): Promise<void> {\n const res = await apiFetch(apiUrl(`/api/auth/oauth/${encodeURIComponent(provider)}`), {\n method: 'DELETE',\n });\n if (!res.ok) {\n throw new Error(`Revoke OAuth failed: ${res.status}`);\n }\n}\n","import * as Popover from '@radix-ui/react-popover';\nimport { ExternalLink, Info, X } from 'lucide-react';\n\nimport { cn } from '@/lib/cn';\nimport type { StoredLanguage } from '@/lib/storage';\n\nimport { PROVIDER_ENRICHMENT } from './provider-enrichment';\n\ninterface ProviderInfoPopoverProps {\n providerId: string;\n language: StoredLanguage;\n}\n\nexport function ProviderInfoPopover({ providerId, language }: ProviderInfoPopoverProps) {\n const enrichment = PROVIDER_ENRICHMENT[providerId];\n if (!enrichment) return null;\n\n const isZh = language === 'zh';\n const description = isZh && enrichment.descriptionZh ? enrichment.descriptionZh : enrichment.description;\n if (!description) return null;\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n aria-label={isZh ? `${providerId} 详情` : `${providerId} info`}\n >\n <Info className=\"size-3.5\" aria-hidden />\n </button>\n </Popover.Trigger>\n\n <Popover.Portal>\n <Popover.Content\n side=\"right\"\n align=\"start\"\n sideOffset={6}\n className={cn(\n 'z-50 w-64 rounded-xl border border-edge bg-surface-panel p-3 shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"text-xs font-semibold text-fg\">{providerId}</p>\n <Popover.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg\"\n aria-label={isZh ? '关闭' : 'Close'}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n </Popover.Close>\n </div>\n\n <p className=\"mt-1.5 text-xs leading-relaxed text-fg-muted\">{description}</p>\n\n {enrichment.bestFor && enrichment.bestFor.length > 0 ? (\n <div className=\"mt-2\">\n <p className=\"text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {isZh ? '适合场景' : 'Best for'}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {enrichment.bestFor.map((tag) => (\n <span\n key={tag}\n className=\"rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium text-fg-muted\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n ) : null}\n\n {enrichment.freeTier !== undefined ? (\n <div className=\"mt-2\">\n <p className=\"text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {isZh ? '免费额度' : 'Free tier'}\n </p>\n <p className=\"mt-0.5 text-xs text-fg-muted\">\n {enrichment.freeTier\n ? enrichment.freeTierNote ?? (isZh ? '有免费额度' : 'Available')\n : isZh\n ? '无免费额度(按量付费)'\n : 'None (pay-as-you-go)'}\n </p>\n </div>\n ) : null}\n\n {enrichment.pricingUrl || enrichment.docsUrl ? (\n <div className=\"mt-2.5 flex gap-3\">\n {enrichment.pricingUrl ? (\n <a\n href={enrichment.pricingUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline\"\n >\n {isZh ? '定价' : 'Pricing'}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ) : null}\n {enrichment.docsUrl ? (\n <a\n href={enrichment.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline\"\n >\n {isZh ? '文档' : 'Docs'}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ) : null}\n </div>\n ) : null}\n\n <Popover.Arrow className=\"fill-edge\" />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n","import type { ProviderActiveKeySource, ProviderCategory, ProviderRowModel } from '@/features/settings/providers-api';\nimport type { ProvidersSettingsMessages } from '@/i18n/messages';\n\nexport const CATEGORY_ORDER: ProviderCategory[] = [\n 'common',\n 'specialty',\n 'enterprise',\n 'oauth',\n 'extension',\n];\n\nexport function groupByCategory(rows: ProviderRowModel[]): Map<ProviderCategory, ProviderRowModel[]> {\n const map = new Map<ProviderCategory, ProviderRowModel[]>();\n for (const c of CATEGORY_ORDER) map.set(c, []);\n for (const r of rows) {\n const cat = r.category || 'specialty';\n const list = map.get(cat) ?? [];\n list.push(r);\n map.set(cat, list);\n }\n return map;\n}\n\nexport function interpolate(template: string, params: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => String(params[key] ?? ''));\n}\n\nexport function activeSourceLabel(\n labels: ProvidersSettingsMessages,\n src: ProviderActiveKeySource | undefined,\n): string {\n switch (src) {\n case 'agent':\n return labels.sourceAgent;\n case 'gateway':\n return labels.sourceGateway;\n case 'oauth':\n return labels.sourceOauth;\n case 'env':\n return labels.sourceEnv;\n case 'models_json':\n return labels.sourceModelsJson;\n case 'extension':\n return labels.sourceExtension;\n default:\n return labels.sourceNone;\n }\n}\n","import {\n AlertCircle,\n CheckCircle2,\n ChevronDown,\n Copy,\n ExternalLink,\n Eye,\n EyeOff,\n Info,\n KeyRound,\n Loader2,\n LogIn,\n LogOut,\n Trash2,\n X,\n} from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ConfirmDialog } from '@/components/ui/confirm-dialog';\nimport type { ConfiguredModel } from '@/features/chat/registry-api';\nimport {\n cancelOAuth,\n cleanupOAuthSession,\n fetchOAuthSessionStatus,\n revokeOAuth,\n startAsyncOAuthLogin,\n submitOAuthCode,\n} from '@/features/settings/oauth-api';\nimport {\n deleteProviderApiKey,\n isMaskedKey,\n testProviderKeyResolution,\n type ProviderRowModel,\n} from '@/features/settings/providers-api';\nimport {\n getOrderedApiKeyLinks,\n PROVIDER_ENRICHMENT,\n providerApiKeyLinkLabel,\n} from '@/features/settings/provider-enrichment';\nimport { ProviderInfoPopover } from '@/features/settings/provider-info-popover';\nimport { activeSourceLabel, interpolate } from './providers-settings-lib';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport type { StoredLanguage } from '@/lib/storage';\nimport type { ProvidersSettingsMessages } from '@/i18n/messages';\n\nfunction EnvVarCopyRow({\n envVar,\n labels,\n}: {\n envVar: string;\n labels: ProvidersSettingsMessages;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(envVar);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n } catch {\n /* ignore clipboard errors */\n }\n };\n\n return (\n <div className=\"flex items-center gap-2\">\n <code className=\"rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[11px] text-fg-muted\">{envVar}</code>\n <button\n type=\"button\"\n onClick={() => void handleCopy()}\n className=\"rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg\"\n title={copied ? labels.copied : labels.copy}\n aria-label={copied ? labels.copied : labels.copy}\n >\n {copied ? (\n <CheckCircle2 className=\"size-3.5 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n ) : (\n <Copy className=\"size-3.5\" aria-hidden />\n )}\n </button>\n </div>\n );\n}\n\nexport function ProviderCredentialRow({\n row,\n value,\n rowDirty,\n labels,\n language,\n onChange,\n onReload,\n justSaved,\n availableModels,\n}: {\n row: ProviderRowModel;\n value: string;\n rowDirty: boolean;\n labels: ProvidersSettingsMessages;\n language: StoredLanguage;\n onChange: (id: string, v: string) => void;\n onReload: () => void;\n justSaved: boolean;\n availableModels: ConfiguredModel[];\n}) {\n const [expanded, setExpanded] = useState(false);\n const [showKey, setShowKey] = useState(false);\n const [copied, setCopied] = useState(false);\n const [revokeError, setRevokeError] = useState<string | null>(null);\n const [removeLoading, setRemoveLoading] = useState(false);\n const [removeMessage, setRemoveMessage] = useState<string | null>(null);\n const [removeConfirmOpen, setRemoveConfirmOpen] = useState(false);\n const masked = isMaskedKey(value);\n const inputValue = masked && !showKey ? '' : value;\n const isOAuthConfigured = row.configured && !masked && Boolean(value);\n\n const [oauthLoading, setOauthLoading] = useState(false);\n const [sessionId, setSessionId] = useState<string | undefined>();\n const [oauthStatus, setOauthStatus] = useState<\n 'idle' | 'waiting' | 'waiting_code' | 'success' | 'error' | undefined\n >();\n const [oauthMessage, setOauthMessage] = useState<string | undefined>();\n const [authUrl, setAuthUrl] = useState<string | undefined>();\n const [instructions, setInstructions] = useState<string | undefined>();\n const [codeInput, setCodeInput] = useState('');\n\n const [testLoading, setTestLoading] = useState(false);\n const [testMessage, setTestMessage] = useState<string | null>(null);\n const [testOk, setTestOk] = useState<boolean | null>(null);\n\n const activeSrc = row.activeKeySource ?? 'none';\n\n const apiKeyLinks = useMemo(() => getOrderedApiKeyLinks(row.id, language), [row.id, language]);\n\n useEffect(() => {\n return () => {\n if (sessionId) {\n void cleanupOAuthSession(sessionId).catch(() => {});\n }\n };\n }, [sessionId]);\n\n useEffect(() => {\n if (!sessionId || !oauthLoading) return;\n const id = window.setInterval(() => {\n void (async () => {\n try {\n const st = await fetchOAuthSessionStatus(sessionId);\n setOauthMessage(st.message);\n setAuthUrl(st.authUrl);\n setInstructions(st.instructions);\n if (st.status === 'waiting_auth' || st.status === 'waiting_code') {\n setOauthStatus(st.status === 'waiting_code' ? 'waiting_code' : 'waiting');\n } else if (st.status === 'completed') {\n window.clearInterval(id);\n setOauthLoading(false);\n setOauthStatus('success');\n setOauthMessage(st.message);\n window.setTimeout(() => onReload(), 800);\n } else if (st.status === 'failed' || st.status === 'cancelled') {\n window.clearInterval(id);\n setOauthLoading(false);\n setOauthStatus('error');\n setOauthMessage(st.error || st.message || 'OAuth failed');\n }\n } catch {\n /* ignore poll errors */\n }\n })();\n }, 1000);\n return () => window.clearInterval(id);\n }, [sessionId, oauthLoading, onReload]);\n\n const startOAuth = async () => {\n setOauthLoading(true);\n setOauthStatus('waiting');\n setOauthMessage(labels.oauthStarting);\n setSessionId(undefined);\n setAuthUrl(undefined);\n setInstructions(undefined);\n try {\n const res = await startAsyncOAuthLogin(row.id);\n setSessionId(res.sessionId);\n } catch (e) {\n setOauthStatus('error');\n setOauthMessage(e instanceof Error ? e.message : 'OAuth failed');\n setOauthLoading(false);\n }\n };\n\n const cancelFlow = async () => {\n if (!sessionId) return;\n try {\n await cancelOAuth(sessionId);\n } catch {\n /* ignore */\n }\n setSessionId(undefined);\n setOauthLoading(false);\n setOauthStatus('idle');\n setOauthMessage(undefined);\n };\n\n const submitCode = async () => {\n if (!sessionId || !codeInput.trim()) return;\n try {\n await submitOAuthCode(sessionId, codeInput.trim());\n setCodeInput('');\n setOauthMessage(labels.oauthProcessingCode);\n } catch (e) {\n setOauthStatus('error');\n setOauthMessage(e instanceof Error ? e.message : 'Failed');\n }\n };\n\n const doRevoke = () => {\n if (!window.confirm(interpolate(labels.revokeConfirm, { name: row.name }))) return;\n setRevokeError(null);\n void revokeOAuth(row.id)\n .then(() => onReload())\n .catch((e) => setRevokeError(e instanceof Error ? e.message : labels.revokeFailed));\n };\n\n const doRemoveKey = async () => {\n setRemoveConfirmOpen(false);\n setRemoveLoading(true);\n setRemoveMessage(null);\n try {\n await deleteProviderApiKey(row.id);\n setRemoveMessage(labels.removeKeySuccess);\n onChange(row.id, '');\n window.setTimeout(() => onReload(), 600);\n } catch (error) {\n setRemoveMessage(error instanceof Error ? error.message : labels.removeKeyFailed);\n } finally {\n setRemoveLoading(false);\n }\n };\n\n const canRemoveKey =\n row.configured && masked && activeSrc !== 'env' && activeSrc !== 'extension' && activeSrc !== 'models_json';\n\n const copyKey = async () => {\n if (!value || masked) return;\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n } catch {\n /* ignore */\n }\n };\n\n const runTest = async () => {\n const v = value.trim();\n if (!v || isMaskedKey(v)) return;\n setTestLoading(true);\n setTestMessage(null);\n setTestOk(null);\n try {\n const res = await testProviderKeyResolution(v);\n if (res.error) {\n setTestOk(false);\n setTestMessage(`${labels.testFailed} ${res.error}`);\n return;\n }\n setTestOk(true);\n if (res.type === 'env') setTestMessage(labels.testOkEnv);\n else if (res.type === 'command') setTestMessage(labels.testOkCommand);\n else setTestMessage(labels.testOkLiteral);\n } catch (e) {\n setTestOk(false);\n setTestMessage(e instanceof Error ? e.message : labels.testFailed);\n } finally {\n setTestLoading(false);\n }\n };\n\n const secondaryLine = rowDirty\n ? labels.metaWillSave\n : row.configured\n ? masked\n ? `${labels.metaMasked} · ${labels.runtimeLabelPrefix} ${activeSourceLabel(labels, activeSrc)}`\n : `${labels.runtimeLabelPrefix} ${activeSourceLabel(labels, activeSrc)}`\n : labels.metaNotConfigured;\n\n const detailsId = `provider-details-${row.id}`;\n\n return (\n <div className=\"bg-surface-panel\">\n <div className=\"flex items-center gap-3 px-3 py-3 sm:px-4\">\n <div\n className=\"flex size-8 shrink-0 items-center justify-center rounded-md bg-surface-hover/80 dark:bg-surface-hover/50\"\n aria-hidden\n >\n {row.configured ? (\n <CheckCircle2 className=\"size-4 text-emerald-600 dark:text-emerald-400\" />\n ) : (\n <KeyRound className=\"size-4 text-fg-subtle\" strokeWidth={1.75} />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-semibold text-fg\">{row.name}</span>\n <ProviderInfoPopover providerId={row.id} language={language} />\n <span className=\"rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {row.id}\n </span>\n <span className=\"rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {row.category}\n </span>\n </div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{secondaryLine}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-9 shrink-0 p-0\"\n aria-expanded={expanded}\n aria-controls={detailsId}\n aria-label={labels.expandRowDetails}\n onClick={() => setExpanded((e) => !e)}\n >\n <ChevronDown className={cn('size-4 transition-transform', expanded && 'rotate-180')} aria-hidden />\n </Button>\n </div>\n\n {expanded ? (\n <div\n id={detailsId}\n role=\"region\"\n className=\"space-y-3 border-t border-edge-subtle bg-surface-base/40 px-3 py-3 dark:bg-surface-base/20 sm:px-4\"\n >\n {row.supportsApiKey !== false ? (\n <div className=\"flex flex-col gap-2\">\n <div className=\"relative flex flex-col gap-2 sm:flex-row sm:gap-2\">\n <div className=\"relative min-w-0 flex-1\">\n <input\n type={showKey || !masked ? 'text' : 'password'}\n className={cn(\n 'w-full rounded-lg border border-edge bg-surface-panel py-2 pl-3 pr-20 font-mono text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n value={inputValue}\n placeholder={\n masked ? labels.placeholderOverride : row.configured ? labels.placeholderKeep : labels.placeholderKey\n }\n disabled={oauthLoading}\n onChange={(e) => onChange(row.id, e.target.value)}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <div className=\"absolute right-1 top-1/2 flex -translate-y-1/2 gap-0.5\">\n {value && !masked ? (\n <button\n type=\"button\"\n className={cn(\n 'rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg',\n interaction.transition,\n interaction.press,\n interaction.focusRingPanel,\n )}\n title={copied ? labels.copied : labels.copy}\n aria-label={copied ? labels.copied : labels.copy}\n onClick={() => void copyKey()}\n >\n {copied ? <CheckCircle2 className=\"size-4\" /> : <Copy className=\"size-4\" />}\n </button>\n ) : null}\n <button\n type=\"button\"\n className={cn(\n 'rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg disabled:opacity-40',\n interaction.transition,\n interaction.press,\n interaction.focusRingPanel,\n )}\n title={showKey ? labels.hide : labels.show}\n aria-label={showKey ? labels.hide : labels.show}\n disabled={masked}\n onClick={() => setShowKey((s) => !s)}\n >\n {showKey ? <EyeOff className=\"size-4\" /> : <Eye className=\"size-4\" />}\n </button>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2 sm:shrink-0\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1\"\n disabled={oauthLoading || testLoading || !value.trim() || isMaskedKey(value)}\n onClick={() => void runTest()}\n >\n {testLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : null}\n {testLoading ? labels.testingKey : labels.testKey}\n </Button>\n {row.supportsOAuth ? (\n isOAuthConfigured ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1 text-red-600 dark:text-red-400\"\n onClick={doRevoke}\n >\n <LogOut className=\"size-4\" aria-hidden />\n {labels.revoke}\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1\"\n disabled={oauthLoading}\n onClick={() => void startOAuth()}\n >\n {oauthLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : <LogIn className=\"size-4\" aria-hidden />}\n {labels.oauth}\n </Button>\n )\n ) : null}\n {canRemoveKey ? (\n <>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"gap-1 text-red-600 dark:text-red-400\"\n disabled={removeLoading}\n onClick={() => setRemoveConfirmOpen(true)}\n >\n {removeLoading ? <Loader2 className=\"size-4 animate-spin\" aria-hidden /> : <Trash2 className=\"size-4\" aria-hidden />}\n {labels.removeKey}\n </Button>\n <ConfirmDialog\n open={removeConfirmOpen}\n title={labels.removeKey}\n description={interpolate(labels.removeKeyConfirm, { name: row.name })}\n confirmLabel={labels.removeKey}\n cancelLabel={labels.cancelOAuth}\n destructive\n onConfirm={() => void doRemoveKey()}\n onCancel={() => setRemoveConfirmOpen(false)}\n />\n </>\n ) : null}\n </div>\n </div>\n {testMessage ? (\n <p\n className={cn(\n 'text-xs',\n testOk === false ? 'text-red-600 dark:text-red-400' : 'text-fg-muted',\n )}\n role=\"status\"\n >\n {testMessage}\n </p>\n ) : null}\n {apiKeyLinks.length > 0 ? (\n <div className=\"flex flex-col gap-1\">\n {apiKeyLinks.map((link) => (\n <a\n key={`${link.kind}-${link.href}`}\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex w-fit items-center gap-1 text-xs font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {providerApiKeyLinkLabel(link.kind, labels)}\n <ExternalLink className=\"size-3\" aria-hidden />\n </a>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {oauthMessage ? (\n <div\n className={cn(\n 'flex gap-2 rounded-md px-3 py-2 text-xs',\n oauthStatus === 'error'\n ? 'border border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400'\n : 'bg-surface-base text-fg-muted',\n )}\n >\n {oauthStatus === 'error' ? (\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n ) : oauthStatus === 'success' ? (\n <CheckCircle2 className=\"mt-0.5 size-4 shrink-0 text-emerald-600\" aria-hidden />\n ) : (\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n )}\n <span>{oauthMessage}</span>\n </div>\n ) : null}\n\n {revokeError ? (\n <div\n className=\"flex gap-2 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400\"\n role=\"alert\"\n >\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{revokeError}</span>\n </div>\n ) : null}\n\n {removeMessage ? (\n <div\n className={cn(\n 'flex gap-2 rounded-md px-3 py-2 text-xs',\n removeMessage === labels.removeKeySuccess\n ? 'bg-surface-hover/60 text-fg-muted dark:bg-surface-hover/40'\n : 'border border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400',\n )}\n role=\"status\"\n >\n {removeMessage === labels.removeKeySuccess ? (\n <CheckCircle2 className=\"mt-0.5 size-4 shrink-0 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n ) : (\n <AlertCircle className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n )}\n <span>{removeMessage}</span>\n </div>\n ) : null}\n\n {(oauthStatus === 'waiting' || oauthStatus === 'waiting_code') && (\n <div className=\"flex flex-wrap gap-2\">\n {authUrl ? (\n <a\n href={authUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-medium text-white hover:bg-accent-hover\"\n >\n <ExternalLink className=\"size-4\" aria-hidden />\n {labels.openAuthPage}\n </a>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" className=\"gap-1\" onClick={() => void cancelFlow()}>\n <X className=\"size-4\" aria-hidden />\n {labels.cancelOAuth}\n </Button>\n </div>\n )}\n\n {instructions ? (\n <div className=\"flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{instructions}</span>\n </div>\n ) : null}\n\n {oauthStatus === 'waiting_code' ? (\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n className={cn(\n 'min-w-0 flex-1 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n value={codeInput}\n placeholder={labels.pasteRedirectUrl}\n onChange={(e) => setCodeInput(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && void submitCode()}\n />\n <Button type=\"button\" variant=\"primary\" className=\"shrink-0\" onClick={() => void submitCode()}>\n {labels.submitCode}\n </Button>\n </div>\n ) : null}\n\n {masked ? (\n <div className=\"flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <Info className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n <span>{activeSrc === 'env' ? labels.envHint : labels.maskedStoredHint}</span>\n </div>\n ) : null}\n\n {row.supportsOAuth && !masked && !isOAuthConfigured ? (\n <p className=\"text-xs text-fg-subtle\">{labels.oauthHint}</p>\n ) : null}\n\n {justSaved ? (\n <div className=\"flex items-start gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40\">\n <CheckCircle2 className=\"mt-0.5 size-3.5 shrink-0 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n <span>\n {(() => {\n const providerModels = availableModels.filter((m) => m.provider === row.id);\n if (providerModels.length === 0) return labels.savedNoModels;\n const preview = providerModels\n .slice(0, 3)\n .map((m) => m.name || m.id)\n .join(', ');\n const suffix = providerModels.length > 3 ? `… (+${providerModels.length - 3})` : '';\n return `${providerModels.length} ${labels.savedModelsAvailable}: ${preview}${suffix}`;\n })()}\n </span>\n </div>\n ) : null}\n\n {(PROVIDER_ENRICHMENT[row.id]?.envVars ?? []).length > 0 ? (\n <details>\n <summary className=\"cursor-pointer select-none list-none text-xs text-fg-subtle hover:text-fg-muted\">\n {labels.envVarAlt}\n </summary>\n <div className=\"mt-1.5 flex flex-col gap-1\">\n {(PROVIDER_ENRICHMENT[row.id]?.envVars ?? []).map((envVar) => (\n <EnvVarCopyRow key={envVar} envVar={envVar} labels={labels} />\n ))}\n </div>\n </details>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import {\n CheckCircle2,\n ChevronDown,\n KeyRound,\n Search,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { CONFIGURED_MODELS_SWR_KEY, fetchConfiguredModelsCached } from '@/features/chat/registry-api';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n isMaskedKey,\n mergeProviderRows,\n patchProviderApiKeys,\n providersKeysFromConfigRoot,\n type ProviderMeta,\n type ProviderRowModel,\n} from '@/features/settings/providers-api';\nimport { PROVIDER_ENRICHMENT } from '@/features/settings/provider-enrichment';\nimport { ProviderCredentialRow } from './provider-credential-row';\nimport { CATEGORY_ORDER, groupByCategory, interpolate } from './providers-settings-lib';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nexport function ProvidersSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const p = m.providersSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [draft, setDraft] = useState<Record<string, string>>({});\n const [baseline, setBaseline] = useState<Record<string, string>>({});\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveNotice, setSaveNotice] = useState<null | 'saved' | 'noChanges'>(null);\n const [expandedCats, setExpandedCats] = useState<Set<string>>(() => new Set(['common']));\n const [searchQuery, setSearchQuery] = useState('');\n const [unconfiguredOnly, setUnconfiguredOnly] = useState(false);\n const [savedProviderIds, setSavedProviderIds] = useState<Set<string>>(() => new Set());\n const prevSearchRef = useRef('');\n\n const metaUrl = apiUrl('/api/providers/meta');\n const fetchMetaList = useCallback(async (url: string) => {\n const data = await fetchJson<{ ok?: boolean; payload?: { providers?: ProviderMeta[] } }>(url);\n return data.payload?.providers ?? [];\n }, []);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: metaList,\n error: metaErr,\n isLoading: metaLoading,\n mutate: mutMeta,\n } = useSWR(hasToken ? metaUrl : null, fetchMetaList, { revalidateOnFocus: false });\n const { data: models, mutate: mutModels } = useSWR(\n hasToken ? CONFIGURED_MODELS_SWR_KEY : null,\n () => fetchConfiguredModelsCached(),\n { revalidateOnFocus: false },\n );\n\n const mergedRows = useMemo((): ProviderRowModel[] | null => {\n if (!metaList || cfgData === undefined) return null;\n const keys = providersKeysFromConfigRoot(cfgData.payload?.config);\n return mergeProviderRows(metaList, keys, models ?? []);\n }, [metaList, cfgData, models]);\n\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : metaErr instanceof Error\n ? metaErr.message\n : metaErr\n ? String(metaErr)\n : null;\n\n const loading = Boolean(\n hasToken && mergedRows === null && (cfgLoading || metaLoading) && !fetchError,\n );\n\n const dirty = useMemo(\n () => JSON.stringify(draft) !== JSON.stringify(baseline),\n [draft, baseline],\n );\n\n useEffect(() => {\n if (!dirty) return;\n const onBeforeUnload = (e: BeforeUnloadEvent) => {\n e.preventDefault();\n e.returnValue = '';\n };\n window.addEventListener('beforeunload', onBeforeUnload);\n return () => window.removeEventListener('beforeunload', onBeforeUnload);\n }, [dirty]);\n\n useEffect(() => {\n if (!hasToken || mergedRows === null) return;\n if (!dirty) {\n const d: Record<string, string> = {};\n for (const r of mergedRows) d[r.id] = r.apiKey;\n setDraft(d);\n setBaseline({ ...d });\n }\n }, [hasToken, mergedRows, dirty]);\n\n const metaRows = mergedRows ?? [];\n\n const filteredRows = useMemo(() => {\n let rows = metaRows;\n const q = searchQuery.trim().toLowerCase();\n if (q) {\n rows = rows.filter((r) => {\n const enrichment = PROVIDER_ENRICHMENT[r.id];\n const aliases = enrichment?.aliases ?? [];\n return (\n r.id.toLowerCase().includes(q) ||\n r.name.toLowerCase().includes(q) ||\n aliases.some((alias) => alias.toLowerCase().includes(q))\n );\n });\n }\n if (unconfiguredOnly) {\n rows = rows.filter((r) => !r.configured);\n }\n return rows;\n }, [metaRows, searchQuery, unconfiguredOnly]);\n\n const groups = useMemo(() => groupByCategory(filteredRows), [filteredRows]);\n\n useEffect(() => {\n const prev = prevSearchRef.current;\n prevSearchRef.current = searchQuery;\n if (searchQuery.trim()) {\n const next = new Set<string>();\n for (const c of CATEGORY_ORDER) {\n if ((groups.get(c) ?? []).length > 0) next.add(c);\n }\n setExpandedCats(next);\n return;\n }\n if (prev.trim()) {\n setExpandedCats(new Set(['common']));\n }\n }, [searchQuery, groups]);\n\n const save = useCallback(async () => {\n if (saving) return;\n const toPatch: Record<string, string> = {};\n for (const id of Object.keys(draft)) {\n const v = draft[id]?.trim() ?? '';\n if (!v || isMaskedKey(v)) continue;\n toPatch[id] = v;\n }\n if (Object.keys(toPatch).length === 0) {\n setBaseline({ ...draft });\n setSaveNotice('noChanges');\n window.setTimeout(() => setSaveNotice(null), 2500);\n return;\n }\n setSaving(true);\n setError(null);\n setSaveNotice(null);\n try {\n await patchProviderApiKeys(toPatch);\n setSavedProviderIds(new Set(Object.keys(toPatch)));\n const freshModels = (await mutModels(fetchConfiguredModelsCached(true))) ?? models ?? [];\n const [nextCfg, nextMeta] = await Promise.all([mutCfg(), mutMeta()]);\n const list = Array.isArray(nextMeta) ? nextMeta : metaList ?? [];\n const cfg = nextCfg ?? cfgData;\n if (cfg?.payload) {\n const keys = providersKeysFromConfigRoot(cfg.payload.config);\n const rows = mergeProviderRows(list, keys, freshModels);\n const d: Record<string, string> = {};\n for (const r of rows) d[r.id] = r.apiKey;\n setDraft(d);\n setBaseline({ ...d });\n }\n setSaveNotice('saved');\n window.setTimeout(() => setSaveNotice(null), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : p.saveError);\n } finally {\n setSaving(false);\n }\n }, [cfgData, draft, metaList, models, mutCfg, mutMeta, mutModels, p.saveError, saving]);\n\n const discard = useCallback(() => {\n setDraft({ ...baseline });\n setError(null);\n setSaveNotice(null);\n setSavedProviderIds(new Set());\n }, [baseline]);\n\n const toggleCat = (cat: string) => {\n setExpandedCats((prev) => {\n const next = new Set(prev);\n if (next.has(cat)) next.delete(cat);\n else next.add(cat);\n return next;\n });\n };\n\n const refreshProviders = useCallback(() => {\n void mutCfg();\n void mutMeta();\n }, [mutCfg, mutMeta]);\n\n const filtersActive = Boolean(searchQuery.trim() || unconfiguredOnly);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <div className=\"flex items-start gap-3 rounded-2xl bg-surface-base p-6\">\n <KeyRound className=\"mt-0.5 size-5 shrink-0 text-fg-subtle\" strokeWidth={1.75} />\n <div>\n <h1 className=\"text-base font-semibold text-fg\">{m.settingsSections.providers}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{p.needToken}</p>\n </div>\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto w-full max-w-app-main px-4 py-8\">\n <div className=\"h-8 w-48 animate-pulse rounded bg-surface-hover\" />\n <div className=\"mt-6 h-32 animate-pulse rounded-xl bg-surface-hover\" />\n <p className=\"mt-4 text-sm text-fg-muted\">{m.logs.loading}</p>\n </div>\n );\n }\n\n if (metaRows.length === 0) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <div className=\"rounded-xl border border-edge-subtle bg-surface-base px-4 py-3\">\n <p className=\"text-sm font-medium text-fg\">{p.loadError}</p>\n <p className=\"mt-1 text-sm text-fg-muted\">{error ?? fetchError ?? p.empty}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutMeta();\n }}\n >\n {m.logs.refresh}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.providers}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{p.subtitle}</p>\n <p className=\"mt-2 text-xs text-fg-subtle\">{p.rotateHint}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {saveNotice === 'saved' ? <span className=\"text-sm text-fg-muted\">{p.saved}</span> : null}\n {saveNotice === 'noChanges' ? <span className=\"text-sm text-fg-muted\">{p.noChangesSaved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {p.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? p.saving : p.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{p.unsavedHint}</p> : null}\n\n <p className=\"text-sm leading-relaxed text-fg-muted\">\n {p.intro}{' '}\n <a\n href={docsGuidePageUrl(language, 'models')}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {p.docsLink}\n </a>\n {' · '}\n <Link\n to=\"/settings/models\"\n className=\"font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n >\n {p.modelsLink}\n </Link>\n </p>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center\">\n <div className=\"relative min-w-0 flex-1 sm:max-w-md\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-subtle\"\n strokeWidth={1.75}\n aria-hidden\n />\n <input\n type=\"search\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={p.searchPlaceholder}\n autoComplete=\"off\"\n className={cn(\n 'w-full rounded-lg border border-edge bg-surface-panel py-2 pl-10 pr-3 text-sm text-fg placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n )}\n aria-label={p.searchPlaceholder}\n />\n </div>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg-muted\">\n <input\n type=\"checkbox\"\n checked={unconfiguredOnly}\n onChange={(e) => setUnconfiguredOnly(e.target.checked)}\n className=\"size-4 rounded border-edge text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent\"\n />\n {p.unconfiguredOnly}\n </label>\n {filtersActive ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-9 w-fit self-start text-fg-muted\"\n onClick={() => {\n setSearchQuery('');\n setUnconfiguredOnly(false);\n }}\n >\n {p.clearFilters}\n </Button>\n ) : null}\n </div>\n\n {error ? (\n <div\n className=\"rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : null}\n\n {filteredRows.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-edge-subtle bg-surface-base px-4 py-8 text-center text-sm text-fg-muted\">\n <p>{p.noMatches}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"mt-4\"\n onClick={() => {\n setSearchQuery('');\n setUnconfiguredOnly(false);\n }}\n >\n {p.clearFilters}\n </Button>\n </div>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {CATEGORY_ORDER.map((cat) => {\n const list = groups.get(cat) ?? [];\n if (list.length === 0) return null;\n const expanded = expandedCats.has(cat);\n const configuredCount = list.filter((r) => r.configured).length;\n const panelId = `providers-cat-${cat}`;\n return (\n <section key={cat} className=\"overflow-hidden rounded-2xl bg-surface-base\">\n <button\n type=\"button\"\n id={`${panelId}-trigger`}\n aria-expanded={expanded}\n aria-controls={panelId}\n className=\"flex w-full items-center justify-between gap-2 border-b border-edge-subtle px-4 py-3 text-left transition-colors hover:bg-surface-hover/60 dark:border-edge-subtle\"\n onClick={() => toggleCat(cat)}\n >\n <span className=\"flex min-w-0 items-center gap-2 text-sm font-semibold text-fg\">\n <span className=\"truncate\">{p.categories[cat]}</span>\n <span className=\"shrink-0 rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle\">\n {list.length}\n </span>\n </span>\n <span className=\"flex shrink-0 items-center gap-2\">\n {configuredCount > 0 ? (\n <span className=\"flex items-center gap-1 text-xs text-fg-subtle\">\n <CheckCircle2 className=\"size-3.5 text-emerald-600 dark:text-emerald-400\" aria-hidden />\n {interpolate(p.configuredCount, { count: String(configuredCount) })}\n </span>\n ) : null}\n <ChevronDown\n className={cn('size-4 text-fg-subtle transition-transform', expanded && 'rotate-180')}\n aria-hidden\n />\n </span>\n </button>\n {expanded ? (\n <div id={panelId} role=\"region\" aria-labelledby={`${panelId}-trigger`} className=\"divide-y divide-edge-subtle\">\n {list.map((row) => (\n <div id={`provider-row-${row.id}`} key={row.id}>\n <ProviderCredentialRow\n row={row}\n value={draft[row.id] ?? ''}\n rowDirty={(draft[row.id] ?? '') !== (baseline[row.id] ?? '')}\n labels={p}\n language={language}\n onChange={(id, v) => setDraft((d) => ({ ...d, [id]: v }))}\n onReload={refreshProviders}\n justSaved={savedProviderIds.has(row.id)}\n availableModels={models ?? []}\n />\n </div>\n ))}\n </div>\n ) : null}\n </section>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import { ExternalLink, Shield } from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { SettingsFormSection, settingsFormSectionClassName } from '@/features/settings/settings-form-section';\nimport { isElectron } from '@/lib/electron-env';\nimport type { StoredLanguage } from '@/lib/storage';\nimport { messages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport type { PrivacyPaneKind, ShellPermissionSnapshot, SystemSettingsBehavior, TccTriState } from '@/types/electron';\n\nconst PERM_ROWS: { key: keyof ShellPermissionSnapshot; pane: PrivacyPaneKind }[] = [\n { key: 'fullDisk', pane: 'fullDisk' },\n { key: 'screen', pane: 'screen' },\n { key: 'microphone', pane: 'microphone' },\n { key: 'accessibility', pane: 'accessibility' },\n { key: 'automation', pane: 'automation' },\n { key: 'notifications', pane: 'notifications' },\n { key: 'location', pane: 'location' },\n];\n\nfunction triStateFromMessages(\n lang: StoredLanguage,\n s: TccTriState,\n): { label: string; className: string } {\n const m = messages(lang).systemSettings.status;\n if (s === 'granted') {\n return { label: m.granted, className: 'text-emerald-600 dark:text-emerald-400' };\n }\n if (s === 'denied') {\n return { label: m.denied, className: 'text-amber-600 dark:text-amber-400' };\n }\n return { label: m.unknown, className: 'text-fg-muted' };\n}\n\nexport function SystemSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const t = m.systemSettings;\n\n const [behavior, setBehavior] = useState<SystemSettingsBehavior | null>(null);\n const [perms, setPerms] = useState<ShellPermissionSnapshot | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n\n const api = typeof window !== 'undefined' ? window.electronAPI?.system : undefined;\n\n const load = useCallback(async () => {\n if (!api) {\n return;\n }\n setLoadError(null);\n try {\n const b = await api.getBehavior();\n setBehavior(b);\n setPerms(await api.getPermissions());\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n }, [api]);\n\n useEffect(() => {\n if (isElectron() && api) {\n void load();\n }\n }, [api, load]);\n\n if (!isElectron() || !api) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n <div className={settingsFormSectionClassName()}>\n <p className=\"text-sm font-medium text-fg\">{t.desktopOnlyTitle}</p>\n <p className=\"mt-1 text-sm text-fg-muted\">{t.desktopOnlyBody}</p>\n </div>\n </div>\n );\n }\n\n const patchBehavior = async (patch: {\n openAtLogin?: boolean;\n keepAwakePreferred?: boolean;\n notifyEnabled?: boolean;\n notifySoundEnabled?: boolean;\n }) => {\n try {\n const { behavior: next } = await api.setBehavior(patch);\n setBehavior(next);\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n };\n\n const openPrivacy = async (kind: PrivacyPaneKind) => {\n try {\n const r = await api.openPrivacy(kind);\n if (!r.ok) {\n setLoadError('open_privacy failed');\n }\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n };\n\n const permissionsHint = (() => {\n if (!behavior) {\n return t.permissionsHint;\n }\n if (behavior.platform === 'win32') {\n return t.permissionsHintWin;\n }\n if (behavior.platform === 'linux') {\n return t.permissionsHintLinux;\n }\n if (behavior.platform === 'darwin') {\n return t.permissionsHintDarwin;\n }\n return t.permissionsHint;\n })();\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8\">\n <div>\n <h1 className=\"text-lg font-semibold text-fg\">{t.title}</h1>\n </div>\n\n {loadError ? (\n <p className=\"text-sm text-amber-600 dark:text-amber-400\" role=\"alert\">\n {loadError}\n </p>\n ) : null}\n\n <SettingsFormSection>\n <div className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-fg\">\n <Shield className=\"size-4 text-accent\" strokeWidth={1.75} />\n {t.behaviorGroup}\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.openAtLogin}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.openAtLoginDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.openAtLogin)}\n onChange={(e) => {\n void patchBehavior({ openAtLogin: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.keepAwake}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.keepAwakeDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.keepAwakePreferred)}\n onChange={(e) => {\n void patchBehavior({ keepAwakePreferred: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.notifyDesktop}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.notifyDesktopDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.notifyEnabled)}\n onChange={(e) => {\n void patchBehavior({ notifyEnabled: e.target.checked });\n }}\n />\n </div>\n <div className=\"flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{t.toggles.notifySound}</div>\n <p className=\"text-xs text-fg-muted\">{t.toggles.notifySoundDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n disabled={!behavior}\n checked={Boolean(behavior?.notifySoundEnabled)}\n onChange={(e) => {\n void patchBehavior({ notifySoundEnabled: e.target.checked });\n }}\n />\n </div>\n </div>\n </SettingsFormSection>\n\n {behavior && perms ? (\n <section className={settingsFormSectionClassName()}>\n <div className=\"mb-4 flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-sm font-semibold text-fg\">{t.permissionsTitle}</h2>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{permissionsHint}</p>\n </div>\n <button\n type=\"button\"\n className=\"mt-2 inline-flex max-w-full items-center justify-center rounded-lg border border-edge bg-surface-panel px-3 py-1.5 text-sm font-medium text-fg transition-colors hover:bg-surface-hover sm:mt-0\"\n onClick={() => void load()}\n >\n {t.refresh}\n </button>\n </div>\n <ul className=\"space-y-3\">\n {PERM_ROWS.map(({ key, pane }) => {\n const st = triStateFromMessages(language, perms[key]);\n const permLabel = t.perm[key];\n if (!permLabel) {\n return null;\n }\n return (\n <li\n key={key}\n className=\"flex flex-col gap-2 rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-3 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm font-medium text-fg\">{permLabel.title}</div>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{permLabel.desc}</p>\n <p className={`mt-1 text-xs font-medium ${st.className}`}>{st.label}</p>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n {key === 'microphone' && behavior?.platform === 'darwin' ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover\"\n onClick={() => {\n void (async () => {\n try {\n await api.requestMicrophone();\n setPerms(await api.getPermissions());\n } catch (e) {\n setLoadError(e instanceof Error ? e.message : String(e));\n }\n })();\n }}\n >\n {language === 'zh' ? '请求访问' : 'Request'}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover\"\n onClick={() => void openPrivacy(pane)}\n >\n {t.openSettings}\n <ExternalLink className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n </section>\n ) : null}\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type { SttSettings, TtsSettings, VoiceModelsPayload, VoiceSettingsState } from './voice-settings.types';\n\nexport type { SttSettings, TtsSettings, VoiceModelsPayload, VoiceSettingsState } from './voice-settings.types';\n\nfunction defaultStt(): SttSettings {\n return {\n enabled: false,\n provider: 'alibaba',\n alibaba: { model: 'paraformer-v2' },\n openai: { model: 'whisper-1' },\n fallback: { enabled: true, order: ['alibaba', 'openai'] },\n };\n}\n\n// Defaults intentionally mirror src/config/schema.ts (TTSConfigSchema /\n// TTSEdgeConfigSchema) and extensions/tts-local-cli/xopc.extension.json so a\n// PATCH /api/config round-trip never silently overrides backend defaults.\nfunction defaultTts(): TtsSettings {\n return {\n enabled: false,\n provider: 'openai',\n trigger: 'always',\n maxTextLength: 512,\n timeoutMs: 60000,\n alibaba: { model: 'qwen-tts', voice: 'Cherry' },\n openai: { model: 'tts-1', voice: 'alloy' },\n edge: { voice: 'en-US-MichelleNeural' },\n minimax: { model: 'speech-2.8-hd', voice: 'male-qn-qingse' },\n 'tts-local-cli': {\n command: '',\n outputFormat: 'wav',\n },\n };\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction mergeStt(raw: unknown): SttSettings {\n const d = defaultStt();\n if (!isRecord(raw)) return d;\n const provider = raw.provider === 'openai' ? 'openai' : 'alibaba';\n const alibaba = isRecord(raw.alibaba) ? { ...d.alibaba, ...raw.alibaba } : d.alibaba;\n const openai = isRecord(raw.openai) ? { ...d.openai, ...raw.openai } : d.openai;\n const baseFallback = d.fallback ?? { enabled: true, order: ['alibaba', 'openai'] as const };\n let fallback = baseFallback;\n if (isRecord(raw.fallback)) {\n const order = Array.isArray(raw.fallback.order)\n ? (raw.fallback.order.filter((x) => x === 'alibaba' || x === 'openai') as ('alibaba' | 'openai')[])\n : fallback.order;\n fallback = {\n enabled: typeof raw.fallback.enabled === 'boolean' ? raw.fallback.enabled : fallback.enabled,\n order: order.length ? order : fallback.order,\n };\n }\n return {\n enabled: Boolean(raw.enabled),\n provider,\n alibaba,\n openai,\n fallback,\n };\n}\n\n/** Provider id is open string — extension SpeechProviderPlugins (e.g. tts-local-cli) are allowed. */\nfunction normalizeTtsProvider(v: unknown): string {\n return typeof v === 'string' && v.trim().length > 0 ? v.trim() : 'openai';\n}\n\nfunction mergeTts(raw: unknown): TtsSettings {\n const d = defaultTts();\n if (!isRecord(raw)) return d;\n const provider = normalizeTtsProvider(raw.provider);\n const trigger =\n raw.trigger === 'off' ||\n raw.trigger === 'always' ||\n raw.trigger === 'inbound' ||\n raw.trigger === 'tagged'\n ? raw.trigger\n : 'always';\n // Per-provider buckets: keep built-in defaults, plus passthrough for any\n // extension-provider key (e.g. `tts-local-cli`) so unknown plugins survive\n // a round-trip through the UI without losing their config.\n const localCliRaw = raw['tts-local-cli'];\n return {\n enabled: Boolean(raw.enabled),\n provider,\n trigger,\n maxTextLength:\n typeof raw.maxTextLength === 'number' && Number.isFinite(raw.maxTextLength)\n ? raw.maxTextLength\n : d.maxTextLength,\n timeoutMs:\n typeof raw.timeoutMs === 'number' && Number.isFinite(raw.timeoutMs) ? raw.timeoutMs : d.timeoutMs,\n alibaba: isRecord(raw.alibaba) ? { ...d.alibaba, ...raw.alibaba } : d.alibaba,\n openai: isRecord(raw.openai) ? { ...d.openai, ...raw.openai } : d.openai,\n edge: isRecord(raw.edge) ? { ...d.edge, ...raw.edge } : d.edge,\n minimax: isRecord(raw.minimax) ? { ...d.minimax, ...raw.minimax } : d.minimax,\n 'tts-local-cli': isRecord(localCliRaw)\n ? { ...d['tts-local-cli'], ...localCliRaw }\n : d['tts-local-cli'],\n };\n}\n\nexport function normalizeVoiceSettings(config: unknown): VoiceSettingsState {\n const c = isRecord(config) ? config : {};\n return {\n stt: mergeStt(c.stt),\n tts: mergeTts(c.tts),\n };\n}\n\nexport async function fetchVoiceSettings(): Promise<VoiceSettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeVoiceSettings(res.payload?.config ?? {});\n}\n\nexport async function patchVoiceSettings(state: VoiceSettingsState): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({ stt: state.stt, tts: state.tts }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchVoiceModels(): Promise<VoiceModelsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: { models?: VoiceModelsPayload } }>(\n apiUrl('/api/voice/models'),\n );\n if (!res.payload?.models) {\n throw new Error('Missing voice models payload');\n }\n return res.payload.models;\n}\n","import { ExternalLink, Loader2, Mic, Volume2 } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';\nimport useSWR from 'swr';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n fetchVoiceModels,\n normalizeVoiceSettings,\n patchVoiceSettings,\n type VoiceModelsPayload,\n type VoiceSettingsState,\n} from '@/features/settings/voice-config-api';\nimport { apiUrl } from '@/lib/url';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type VoiceSettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst STT_ALIBABA_FALLBACK = [\n { id: 'paraformer-v2', name: 'Paraformer v2' },\n { id: 'paraformer-v1', name: 'Paraformer v1' },\n];\nconst STT_OPENAI_FALLBACK = [{ id: 'whisper-1', name: 'Whisper-1' }];\nconst TTS_OPENAI_MODELS_FALLBACK = [\n { id: 'tts-1', name: 'TTS-1' },\n { id: 'tts-1-hd', name: 'TTS-1 HD' },\n];\nconst TTS_OPENAI_VOICES_FALLBACK = [\n { id: 'alloy', name: 'Alloy' },\n { id: 'echo', name: 'Echo' },\n];\nconst TTS_ALIBABA_MODELS_FALLBACK = [\n { id: 'qwen-tts', name: 'Qwen TTS' },\n { id: 'qwen3-tts-flash', name: 'Qwen3 TTS Flash' },\n];\nconst TTS_ALIBABA_VOICES_FALLBACK = [\n { id: 'Cherry', name: 'Cherry' },\n { id: 'longxiaochun', name: 'Long Xiao Chun' },\n];\nconst TTS_EDGE_VOICES_FALLBACK = [\n { id: 'en-US-MichelleNeural', name: 'Michelle (US English)' },\n { id: 'zh-CN-XiaoxiaoNeural', name: 'Xiaoxiao (Chinese)' },\n];\nconst TTS_MINIMAX_MODELS_FALLBACK = [\n { id: 'speech-2.8-hd', name: 'Speech 2.8 HD (Recommended)' },\n { id: 'speech-2.8-turbo', name: 'Speech 2.8 Turbo (Fast)' },\n];\nconst TTS_MINIMAX_VOICES_FALLBACK = [\n { id: 'male-qn-qingse', name: 'Male Qingse (青涩男声)' },\n { id: 'female-shaonv', name: 'Female Shaonv (少女音)' },\n];\n\nexport function VoiceSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const v = m.voiceSettings;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<VoiceSettingsState | null>(null);\n const [baseline, setBaseline] = useState<VoiceSettingsState | null>(null);\n const [models, setModels] = useState<VoiceModelsPayload | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n\n const {\n data: cfgData,\n error: cfgErr,\n isLoading: cfgLoading,\n mutate: mutCfg,\n } = useGatewayConfigSwr(hasToken);\n const {\n data: voiceModels,\n error: vmErr,\n isLoading: vmLoading,\n mutate: mutVm,\n } = useSWR(hasToken ? apiUrl('/api/voice/models') : null, fetchVoiceModels, { revalidateOnFocus: false });\n\n const voiceParsed = useMemo(\n () =>\n cfgData?.payload?.config !== undefined\n ? normalizeVoiceSettings(cfgData.payload.config)\n : null,\n [cfgData],\n );\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n setModels(null);\n return;\n }\n if (voiceParsed === null || voiceModels === undefined) return;\n if (!dirty) {\n setForm(structuredClone(voiceParsed));\n setBaseline(structuredClone(voiceParsed));\n setModels(voiceModels);\n setSaveOk(false);\n }\n }, [hasToken, voiceParsed, voiceModels, dirty]);\n\n const loading = Boolean(\n hasToken &&\n (voiceParsed === null || voiceModels === undefined) &&\n (cfgLoading || vmLoading),\n );\n const fetchError =\n cfgErr instanceof Error\n ? cfgErr.message\n : cfgErr\n ? String(cfgErr)\n : vmErr instanceof Error\n ? vmErr.message\n : vmErr\n ? String(vmErr)\n : null;\n\n const updateStt = useCallback((patch: Partial<VoiceSettingsState['stt']>) => {\n setForm((f) => (f ? { ...f, stt: { ...f.stt, ...patch } } : null));\n }, []);\n\n const updateSttAlibaba = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['alibaba']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n stt: { ...f.stt, alibaba: { ...f.stt.alibaba, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateSttOpenai = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['openai']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n stt: { ...f.stt, openai: { ...f.stt.openai, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateSttFallback = useCallback((patch: Partial<NonNullable<VoiceSettingsState['stt']['fallback']>>) => {\n setForm((f) => {\n if (!f) return null;\n const cur = f.stt.fallback ?? { enabled: true, order: ['alibaba', 'openai'] };\n return {\n ...f,\n stt: {\n ...f.stt,\n fallback: { ...cur, ...patch },\n },\n };\n });\n }, []);\n\n const updateTts = useCallback((patch: Partial<VoiceSettingsState['tts']>) => {\n setForm((f) => (f ? { ...f, tts: { ...f.tts, ...patch } } : null));\n }, []);\n\n const updateTtsAlibaba = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['alibaba']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, alibaba: { ...f.tts.alibaba, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsOpenai = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['openai']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, openai: { ...f.tts.openai, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsEdge = useCallback((patch: Partial<NonNullable<VoiceSettingsState['tts']['edge']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: { ...f.tts, edge: { ...f.tts.edge, ...patch } },\n }\n : null,\n );\n }, []);\n\n const updateTtsMinimax = useCallback(\n (patch: Partial<NonNullable<VoiceSettingsState['tts']['minimax']>>) => {\n setForm((f) =>\n f ? { ...f, tts: { ...f.tts, minimax: { ...f.tts.minimax, ...patch } } } : null,\n );\n },\n [],\n );\n\n const updateTtsLocalCli = useCallback(\n (patch: Partial<NonNullable<VoiceSettingsState['tts']['tts-local-cli']>>) => {\n setForm((f) =>\n f\n ? {\n ...f,\n tts: {\n ...f.tts,\n 'tts-local-cli': { ...f.tts['tts-local-cli'], ...patch },\n },\n }\n : null,\n );\n },\n [],\n );\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchVoiceSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setForm(next);\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : v.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, v.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{m.settingsSections.voice}</h1>\n <p className=\"text-sm text-fg-muted\">{v.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <div className=\"flex items-center gap-2 text-sm text-fg-muted\">\n <Loader2 className=\"size-4 animate-spin\" />\n {v.loading}\n </div>\n </div>\n );\n }\n\n if (!form || models === null) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? v.loadError}</p>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n void mutCfg();\n void mutVm();\n }}\n >\n {v.retry}\n </Button>\n </div>\n );\n }\n\n const stt = form.stt;\n const tts = form.tts;\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{m.settingsSections.voice}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{v.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'voice')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {v.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{v.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {v.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? v.saving : v.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{v.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <div className=\"flex flex-col gap-4\">\n <SttSection\n v={v}\n stt={stt}\n models={models}\n updateStt={updateStt}\n updateSttAlibaba={updateSttAlibaba}\n updateSttOpenai={updateSttOpenai}\n updateSttFallback={updateSttFallback}\n />\n\n <TtsSection\n v={v}\n tts={tts}\n models={models}\n updateTts={updateTts}\n updateTtsAlibaba={updateTtsAlibaba}\n updateTtsOpenai={updateTtsOpenai}\n updateTtsEdge={updateTtsEdge}\n updateTtsMinimax={updateTtsMinimax}\n updateTtsLocalCli={updateTtsLocalCli}\n />\n </div>\n\n <div className=\"rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10\">\n <p className=\"text-sm text-fg\">\n <strong className=\"text-accent\">{v.notes.title}</strong> {v.notes.duration}\n </p>\n <p className=\"mt-2 text-xs text-fg-muted\">{v.notes.envVars}</p>\n </div>\n </div>\n );\n}\n\nfunction SttSection({\n v,\n stt,\n models,\n updateStt,\n updateSttAlibaba,\n updateSttOpenai,\n updateSttFallback,\n}: {\n v: VoiceSettingsMessages;\n stt: VoiceSettingsState['stt'];\n models: VoiceModelsPayload | null;\n updateStt: (p: Partial<VoiceSettingsState['stt']>) => void;\n updateSttAlibaba: (p: Partial<NonNullable<VoiceSettingsState['stt']['alibaba']>>) => void;\n updateSttOpenai: (p: Partial<NonNullable<VoiceSettingsState['stt']['openai']>>) => void;\n updateSttFallback: (p: Partial<NonNullable<VoiceSettingsState['stt']['fallback']>>) => void;\n}) {\n const alibabaModels = models?.stt?.alibaba?.length ? models.stt.alibaba : STT_ALIBABA_FALLBACK;\n const openaiModels = models?.stt?.openai?.length ? models.stt.openai : STT_OPENAI_FALLBACK;\n\n return (\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Mic className=\"size-4 text-accent\" strokeWidth={1.75} />\n {v.stt.title}\n </div>\n <p className=\"mt-1 text-xs text-fg-muted\">{v.stt.description}</p>\n </div>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.stt.enable}</div>\n <p className=\"text-xs text-fg-muted\">{v.stt.enableDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={stt.enabled}\n onChange={(e) => updateStt({ enabled: e.target.checked })}\n />\n </div>\n\n {stt.enabled ? (\n <>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.provider}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.provider}\n onChange={(e) => updateStt({ provider: e.target.value as 'alibaba' | 'openai' })}\n >\n <option value=\"alibaba\">{v.stt.alibaba}</option>\n <option value=\"openai\">{v.stt.openai}</option>\n </select>\n </div>\n </div>\n\n {stt.provider === 'alibaba' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={stt.alibaba?.apiKey ?? ''}\n onChange={(e) => updateSttAlibaba({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (DASHSCOPE_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.alibaba?.model ?? ''}\n onChange={(e) => updateSttAlibaba({ model: e.target.value })}\n >\n {alibabaModels.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={stt.openai?.apiKey ?? ''}\n onChange={(e) => updateSttOpenai({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (OPENAI_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={stt.openai?.model ?? ''}\n onChange={(e) => updateSttOpenai({ model: e.target.value })}\n >\n {openaiModels.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.stt.fallback}</div>\n <p className=\"text-xs text-fg-muted\">{v.stt.fallbackDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={stt.fallback?.enabled ?? true}\n onChange={(e) => updateSttFallback({ enabled: e.target.checked })}\n />\n </div>\n </>\n ) : null}\n </div>\n </section>\n );\n}\n\nfunction TtsSection({\n v,\n tts,\n models,\n updateTts,\n updateTtsAlibaba,\n updateTtsOpenai,\n updateTtsEdge,\n updateTtsMinimax,\n updateTtsLocalCli,\n}: {\n v: VoiceSettingsMessages;\n tts: VoiceSettingsState['tts'];\n models: VoiceModelsPayload | null;\n updateTts: (p: Partial<VoiceSettingsState['tts']>) => void;\n updateTtsAlibaba: (p: Partial<NonNullable<VoiceSettingsState['tts']['alibaba']>>) => void;\n updateTtsOpenai: (p: Partial<NonNullable<VoiceSettingsState['tts']['openai']>>) => void;\n updateTtsEdge: (p: Partial<NonNullable<VoiceSettingsState['tts']['edge']>>) => void;\n updateTtsMinimax: (p: Partial<NonNullable<VoiceSettingsState['tts']['minimax']>>) => void;\n updateTtsLocalCli: (p: Partial<NonNullable<VoiceSettingsState['tts']['tts-local-cli']>>) => void;\n}) {\n const triggerDesc = (t: string) => {\n if (t === 'off') return v.tts.triggerDescOff;\n if (t === 'always') return v.tts.triggerDescAlways;\n if (t === 'inbound') return v.tts.triggerDescInbound;\n if (t === 'tagged') return v.tts.triggerDescTagged;\n return '';\n };\n\n const ttsOpenai = models?.tts?.openai?.length ? models.tts.openai : TTS_OPENAI_MODELS_FALLBACK;\n const ttsVoicesOpenai = models?.ttsVoices?.openai?.length ? models.ttsVoices.openai : TTS_OPENAI_VOICES_FALLBACK;\n const ttsAlibaba = models?.tts?.alibaba?.length ? models.tts.alibaba : TTS_ALIBABA_MODELS_FALLBACK;\n const ttsVoicesAlibaba = models?.ttsVoices?.alibaba?.length ? models.ttsVoices.alibaba : TTS_ALIBABA_VOICES_FALLBACK;\n const ttsVoicesEdge = models?.ttsVoices?.edge?.length ? models.ttsVoices.edge : TTS_EDGE_VOICES_FALLBACK;\n const ttsMinimax = models?.tts?.minimax?.length ? models.tts.minimax : TTS_MINIMAX_MODELS_FALLBACK;\n const ttsVoicesMinimax = models?.ttsVoices?.minimax?.length\n ? models.ttsVoices.minimax\n : TTS_MINIMAX_VOICES_FALLBACK;\n\n return (\n <section className=\"rounded-2xl bg-surface-base px-4 py-5 sm:px-5\">\n <div className=\"mb-4\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-fg\">\n <Volume2 className=\"size-4 text-accent\" strokeWidth={1.75} />\n {v.tts.title}\n </div>\n <p className=\"mt-1 text-xs text-fg-muted\">{v.tts.description}</p>\n </div>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35\">\n <div>\n <div className=\"text-sm font-medium text-fg\">{v.tts.enable}</div>\n <p className=\"text-xs text-fg-muted\">{v.tts.enableDesc}</p>\n </div>\n <input\n type=\"checkbox\"\n className=\"ui-checkbox\"\n checked={tts.enabled}\n onChange={(e) => updateTts({ enabled: e.target.checked })}\n />\n </div>\n\n {tts.enabled ? (\n <>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.trigger}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.trigger}\n onChange={(e) =>\n updateTts({ trigger: e.target.value as VoiceSettingsState['tts']['trigger'] })\n }\n >\n <option value=\"off\">{v.tts.triggerOff}</option>\n <option value=\"always\">{v.tts.triggerAlways}</option>\n <option value=\"inbound\">{v.tts.triggerInbound}</option>\n <option value=\"tagged\">{v.tts.triggerTagged}</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{triggerDesc(tts.trigger)}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.provider}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.provider}\n onChange={(e) => updateTts({ provider: e.target.value })}\n >\n <option value=\"openai\">{v.tts.providerOpenai}</option>\n <option value=\"alibaba\">{v.stt.alibaba}</option>\n <option value=\"minimax\">MiniMax</option>\n <option value=\"edge\">{v.tts.providerEdge}</option>\n <option value=\"tts-local-cli\">{v.tts.providerLocalCli}</option>\n </select>\n </div>\n </div>\n\n {tts.provider === 'openai' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.openai?.apiKey ?? ''}\n onChange={(e) => updateTtsOpenai({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (OPENAI_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.openai?.model ?? ''}\n onChange={(e) => updateTtsOpenai({ model: e.target.value })}\n >\n {ttsOpenai.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.openai?.voice ?? ''}\n onChange={(e) => updateTtsOpenai({ voice: e.target.value })}\n >\n {ttsVoicesOpenai.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'alibaba' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.alibaba?.apiKey ?? ''}\n onChange={(e) => updateTtsAlibaba({ apiKey: e.target.value })}\n placeholder=\"sk-...\"\n />\n <p className=\"text-xs text-fg-subtle\">\n {v.stt.apiKeyDesc} (DASHSCOPE_API_KEY)\n </p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.alibaba?.model ?? ''}\n onChange={(e) => updateTtsAlibaba({ model: e.target.value })}\n >\n {ttsAlibaba.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.alibaba?.voice ?? ''}\n onChange={(e) => updateTtsAlibaba({ voice: e.target.value })}\n >\n {ttsVoicesAlibaba.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'minimax' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.stt.apiKey}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"password\"\n autoComplete=\"off\"\n value={tts.minimax?.apiKey ?? ''}\n onChange={(e) => updateTtsMinimax({ apiKey: e.target.value })}\n placeholder=\"eyJ...\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.stt.apiKeyDesc} (MINIMAX_API_KEY)</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.stt.model}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.minimax?.model ?? ''}\n onChange={(e) => updateTtsMinimax({ model: e.target.value })}\n >\n {ttsMinimax.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.minimax?.voice ?? ''}\n onChange={(e) => updateTtsMinimax({ voice: e.target.value })}\n >\n {ttsVoicesMinimax.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n ) : null}\n\n {tts.provider === 'edge' ? (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.voice}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts.edge?.voice ?? ''}\n onChange={(e) => updateTtsEdge({ voice: e.target.value })}\n >\n {ttsVoicesEdge.map((m) => (\n <option key={m.id} value={m.id}>\n {m.name}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-fg-subtle\">{v.tts.edgeHint}</p>\n </div>\n ) : null}\n\n {tts.provider === 'tts-local-cli' ? (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.tts.localCli.command}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={tts['tts-local-cli']?.command ?? ''}\n onChange={(e) => updateTtsLocalCli({ command: e.target.value })}\n placeholder={v.tts.localCli.commandPlaceholder}\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.commandDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.localCli.cwd}</FieldLabel>\n <input\n className={cn(inputClassName(), 'font-mono text-xs')}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n value={tts['tts-local-cli']?.cwd ?? ''}\n onChange={(e) => updateTtsLocalCli({ cwd: e.target.value })}\n placeholder=\"/path/to/cwd\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.cwdDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel>{v.tts.localCli.outputFormat}</FieldLabel>\n <select\n className={selectClassName()}\n value={tts['tts-local-cli']?.outputFormat ?? 'wav'}\n onChange={(e) =>\n updateTtsLocalCli({\n outputFormat: e.target.value as 'mp3' | 'opus' | 'wav',\n })\n }\n >\n <option value=\"wav\">wav</option>\n <option value=\"mp3\">mp3</option>\n <option value=\"opus\">opus</option>\n </select>\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.outputFormatDesc}</p>\n </div>\n <div className=\"flex flex-col gap-1.5 sm:col-span-2\">\n <FieldLabel>{v.tts.localCli.timeoutMs}</FieldLabel>\n <input\n className={inputClassName()}\n type=\"number\"\n min={0}\n step={1000}\n value={\n typeof tts['tts-local-cli']?.timeoutMs === 'number'\n ? String(tts['tts-local-cli'].timeoutMs)\n : ''\n }\n onChange={(e) => {\n const raw = e.target.value.trim();\n if (raw === '') {\n updateTtsLocalCli({ timeoutMs: undefined });\n return;\n }\n const num = Number(raw);\n if (Number.isFinite(num) && num >= 0) {\n updateTtsLocalCli({ timeoutMs: num });\n }\n }}\n placeholder=\"30000\"\n />\n <p className=\"text-xs text-fg-subtle\">{v.tts.localCli.timeoutMsDesc}</p>\n </div>\n <p className=\"text-xs text-fg-subtle sm:col-span-2\">{v.tts.localCli.hint}</p>\n </div>\n ) : null}\n </>\n ) : null}\n </div>\n </section>\n );\n}\n\nfunction FieldLabel({ children }: { children: ReactNode }) {\n return <div className=\"text-sm font-medium text-fg\">{children}</div>;\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport type SearchProviderRow = {\n type: 'brave' | 'tavily' | 'bing' | 'searxng';\n apiKey: string;\n url: string;\n disabled: boolean;\n};\n\nexport type WebSearchSettingsState = {\n regionMode: 'auto' | 'cn' | 'global';\n maxResults: number;\n providers: SearchProviderRow[];\n};\n\nexport function normalizeWebSearchSettingsFromConfig(cfg: unknown): WebSearchSettingsState {\n const tools = cfg && typeof cfg === 'object' && 'tools' in cfg ? (cfg as { tools?: unknown }).tools : undefined;\n const web = tools && typeof tools === 'object' && 'web' in tools ? (tools as { web?: unknown }).web : undefined;\n const region =\n web && typeof web === 'object' && 'region' in web\n ? (web as { region?: unknown }).region\n : undefined;\n const regionMode =\n region === 'cn' || region === 'global' ? region : 'auto';\n\n const search =\n web && typeof web === 'object' && 'search' in web ? (web as { search?: unknown }).search : undefined;\n const s = search && typeof search === 'object' ? (search as Record<string, unknown>) : {};\n\n const maxResults =\n typeof s.maxResults === 'number' && Number.isFinite(s.maxResults) ? Math.floor(s.maxResults) : 5;\n\n const rawProviders = s.providers;\n const rows: SearchProviderRow[] = Array.isArray(rawProviders)\n ? rawProviders.map((p) => {\n const o = p && typeof p === 'object' ? (p as Record<string, unknown>) : {};\n const type = o.type;\n const t =\n type === 'brave' || type === 'tavily' || type === 'bing' || type === 'searxng' ? type : 'brave';\n return {\n type: t,\n apiKey: typeof o.apiKey === 'string' ? o.apiKey : '',\n url: typeof o.url === 'string' ? o.url : '',\n disabled: o.disabled === true,\n };\n })\n : [];\n\n return {\n regionMode,\n maxResults,\n providers: rows,\n };\n}\n\nexport async function fetchWebSearchSettings(): Promise<WebSearchSettingsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n return normalizeWebSearchSettingsFromConfig(res.payload?.config);\n}\n\nexport async function patchWebSearchSettings(state: WebSearchSettingsState): Promise<void> {\n const region =\n state.regionMode === 'auto' ? 'auto' : state.regionMode === 'cn' ? 'cn' : 'global';\n\n const search: Record<string, unknown> = {\n maxResults: state.maxResults,\n providers: state.providers.map((p) => {\n const row: Record<string, unknown> = {\n type: p.type,\n apiKey: p.apiKey,\n };\n if (p.type === 'searxng' && p.url.trim()) {\n row.url = p.url.trim().replace(/\\/+$/, '');\n }\n if (p.disabled) row.disabled = true;\n return row;\n }),\n };\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n tools: {\n web: {\n region,\n search,\n },\n },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { ExternalLink, Loader2, Plus, Search, Trash2 } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n normalizeWebSearchSettingsFromConfig,\n patchWebSearchSettings,\n type SearchProviderRow,\n type WebSearchSettingsState,\n} from '@/features/settings/web-search-config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { isMaskedKey } from '@/features/settings/providers-api';\nimport { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\nimport { messages, type WebSearchSettingsMessages } from '@/i18n/messages';\nimport { docsGuidePageUrl } from '@/navigation';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nfunction Field({\n label,\n description,\n children,\n}: {\n label: string;\n description: string;\n children: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"text-sm font-medium text-fg\">{label}</div>\n {children}\n <p className=\"text-xs leading-relaxed text-fg-subtle\">{description}</p>\n </div>\n );\n}\n\nfunction inputClassName(): string {\n return cn(\n 'w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg',\n 'placeholder:text-fg-subtle',\n settingsInputFocusClass,\n 'dark:border-edge',\n );\n}\n\nfunction selectClassName(): string {\n return cn(selectControlBaseClass, nativeSelectMaxWidthClass);\n}\n\nconst PROVIDER_TYPES: SearchProviderRow['type'][] = ['brave', 'tavily', 'bing', 'searxng'];\n\nfunction emptyProviderRow(): SearchProviderRow {\n return { type: 'brave', apiKey: '', url: '', disabled: false };\n}\n\nexport function WebSearchSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const w = m.webSearchSettings;\n const logs = m.logs;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<WebSearchSettingsState | null>(null);\n const [baseline, setBaseline] = useState<WebSearchSettingsState | null>(null);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [saveOk, setSaveOk] = useState(false);\n const dirtyRef = useRef(false);\n\n const { data, error: swrError, isLoading, mutate } = useGatewayConfigSwr(hasToken);\n\n const parsed = useMemo(\n () =>\n data?.payload?.config !== undefined\n ? normalizeWebSearchSettingsFromConfig(data.payload.config)\n : null,\n [data],\n );\n\n useEffect(() => {\n if (!hasToken) {\n setForm(null);\n setBaseline(null);\n dirtyRef.current = false;\n return;\n }\n if (parsed === null) return;\n if (!dirtyRef.current) {\n setForm(parsed);\n setBaseline(parsed);\n }\n }, [hasToken, parsed]);\n\n const loading = Boolean(hasToken && isLoading && data === undefined && !swrError);\n const fetchError =\n swrError instanceof Error ? swrError.message : swrError ? String(swrError) : null;\n\n const dirty = useMemo(() => {\n if (!form || !baseline) return false;\n return JSON.stringify(form) !== JSON.stringify(baseline);\n }, [form, baseline]);\n\n const update = useCallback((patch: Partial<WebSearchSettingsState>) => {\n dirtyRef.current = true;\n setForm((f) => (f ? { ...f, ...patch } : null));\n }, []);\n\n const save = useCallback(async () => {\n if (!form || saving) return;\n setSaving(true);\n setError(null);\n setSaveOk(false);\n try {\n await patchWebSearchSettings(form);\n const next = structuredClone(form);\n setBaseline(next);\n setForm(next);\n dirtyRef.current = false;\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : w.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, w.saveError]);\n\n const discard = useCallback(() => {\n if (!baseline) return;\n dirtyRef.current = false;\n setForm(structuredClone(baseline));\n setError(null);\n setSaveOk(false);\n }, [baseline]);\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-6\">\n <h1 className=\"text-lg font-semibold text-fg\">{w.title}</h1>\n <p className=\"text-sm text-fg-muted\">{w.needToken}</p>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col items-center gap-3 px-4 py-8\">\n <Loader2 className=\"size-8 animate-spin text-fg-muted\" aria-hidden />\n <p className=\"text-sm text-fg-muted\">{w.loading}</p>\n </div>\n );\n }\n\n if (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{error ?? fetchError ?? w.loadError}</p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\n {logs.refresh}\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6\">\n <header className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-lg font-semibold tracking-tight text-fg\">{w.title}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{w.subtitle}</p>\n <a\n href={docsGuidePageUrl(language, 'gateway')}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40\"\n >\n {w.docsLink}\n <ExternalLink className=\"size-3.5\" />\n </a>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{w.saved}</span> : null}\n <Button type=\"button\" variant=\"secondary\" disabled={!dirty || saving} onClick={discard}>\n {w.discard}\n </Button>\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? w.saving : w.save}\n </Button>\n </div>\n </header>\n\n {dirty ? <p className=\"text-xs text-amber-800 dark:text-amber-200\">{w.unsavedHint}</p> : null}\n {error ? <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p> : null}\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={w.sectionRegion} subtitle={w.sectionRegionHint} />\n <div className=\"flex max-w-md flex-col gap-4\">\n <Field label={w.regionLabel} description={w.regionDesc}>\n <select\n className={selectClassName()}\n value={form.regionMode}\n onChange={(e) =>\n update({\n regionMode: e.target.value as WebSearchSettingsState['regionMode'],\n })\n }\n >\n <option value=\"auto\">{w.regionAuto}</option>\n <option value=\"cn\">{w.regionCn}</option>\n <option value=\"global\">{w.regionGlobal}</option>\n </select>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={w.sectionSearch} subtitle={w.sectionSearchHint} />\n <div className=\"flex max-w-xl flex-col gap-6\">\n <Field label={w.maxResultsLabel} description={w.maxResultsDesc}>\n <input\n type=\"number\"\n min={1}\n max={50}\n className={inputClassName()}\n value={form.maxResults}\n onChange={(e) => update({ maxResults: Math.max(1, Math.min(50, Number(e.target.value) || 5)) })}\n />\n </Field>\n\n <div className=\"flex flex-col gap-3\">\n <div className=\"text-sm font-medium text-fg\">{w.providersTitle}</div>\n {form.providers.map((row, index) => (\n <ProviderRowEditor\n key={index}\n row={row}\n labels={w}\n onChange={(next) => {\n const nextRows = [...form.providers];\n nextRows[index] = next;\n update({ providers: nextRows });\n }}\n onRemove={() => {\n update({ providers: form.providers.filter((_, i) => i !== index) });\n }}\n />\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit gap-1.5 text-sm\"\n onClick={() => update({ providers: [...form.providers, emptyProviderRow()] })}\n >\n <Plus className=\"size-4\" />\n {w.addProvider}\n </Button>\n </div>\n </div>\n </SettingsFormSection>\n\n <p className=\"text-xs leading-relaxed text-fg-subtle\">{w.footerHint}</p>\n </div>\n );\n}\n\nfunction ProviderRowEditor({\n row,\n labels,\n onChange,\n onRemove,\n}: {\n row: SearchProviderRow;\n labels: WebSearchSettingsMessages;\n onChange: (r: SearchProviderRow) => void;\n onRemove: () => void;\n}) {\n return (\n <div className=\"flex flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-panel/60 p-4 dark:border-edge-subtle\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <select\n className={cn(selectClassName(), 'min-w-[8rem]')}\n value={row.type}\n onChange={(e) =>\n onChange({\n ...row,\n type: e.target.value as SearchProviderRow['type'],\n url: e.target.value === 'searxng' ? row.url : '',\n })\n }\n >\n {PROVIDER_TYPES.map((t) => (\n <option key={t} value={t}>\n {labels.providerTypes[t]}\n </option>\n ))}\n </select>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex cursor-pointer items-center gap-1.5 text-xs text-fg-muted\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 rounded border-edge\"\n checked={row.disabled}\n onChange={(e) => onChange({ ...row, disabled: e.target.checked })}\n />\n {labels.disabled}\n </label>\n <Button type=\"button\" variant=\"ghost\" className=\"h-8 px-2 text-fg-muted\" onClick={onRemove}>\n <Trash2 className=\"size-4\" />\n </Button>\n </div>\n </div>\n {row.type === 'searxng' ? (\n <Field label={labels.urlLabel} description={labels.urlDesc}>\n <input\n type=\"url\"\n className={inputClassName()}\n value={row.url}\n placeholder=\"http://localhost:8080\"\n onChange={(e) => onChange({ ...row, url: e.target.value })}\n />\n </Field>\n ) : null}\n <Field label={labels.apiKeyLabel} description={labels.apiKeyDesc}>\n <input\n type=\"password\"\n autoComplete=\"off\"\n className={inputClassName()}\n value={isMaskedKey(row.apiKey) ? '' : row.apiKey}\n placeholder={isMaskedKey(row.apiKey) ? labels.keyPlaceholderMasked : labels.keyPlaceholder}\n onChange={(e) => onChange({ ...row, apiKey: e.target.value })}\n />\n </Field>\n </div>\n );\n}\n","import { Navigate, useParams } from 'react-router-dom';\n\nimport {\n AgentBrowserDefaultsPage,\n AgentChatDefaultsPage,\n AgentRuntimeDefaultsPage,\n AgentSystemPromptDefaultsPage,\n AgentToolsDefaultsPage,\n AgentWorkspaceDefaultsPage,\n} from '@/features/settings/agents';\nimport { AppearanceSettingsPanel } from '@/features/settings/appearance-settings';\nimport { DreamingSettingsPanel } from '@/features/settings/dreaming-settings';\nimport { GatewaySettingsPanel } from '@/features/settings/gateway-settings';\nimport { HeartbeatSettingsPanel } from '@/features/settings/heartbeat-settings';\nimport { ImageModelsSettingsPanel } from '@/features/settings/image-models-settings';\nimport { ModelsSettingsPanel } from '@/features/settings/models-settings';\nimport { ProvidersSettingsPanel } from '@/features/settings/providers-settings';\nimport { SystemSettingsPanel } from '@/features/settings/system-settings-panel';\nimport { VoiceSettingsPanel } from '@/features/settings/voice-settings';\nimport { WebSearchSettingsPanel } from '@/features/settings/web-search-settings';\nimport { messages } from '@/i18n/messages';\nimport type { SettingsSectionId } from '@/navigation';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nconst SECTIONS: SettingsSectionId[] = [\n 'appearance',\n 'system',\n 'agent-chat',\n 'agent-workspace',\n 'agent-browser',\n 'agent-runtime',\n 'agent-tools',\n 'agent-system-prompt',\n 'providers',\n 'models',\n 'image-models',\n 'voice',\n 'gateway',\n 'heartbeat',\n 'search',\n 'dreams',\n];\n\nexport function SettingsPage() {\n const { section } = useParams();\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n\n if (section === 'agent' || section === 'agents') {\n return <Navigate to=\"/agents\" replace />;\n }\n\n if (!section || !SECTIONS.includes(section as SettingsSectionId)) {\n return <Navigate to=\"/settings/appearance\" replace />;\n }\n\n const id = section as SettingsSectionId;\n const title = m.settingsSections[id];\n\n if (id === 'appearance') {\n return <AppearanceSettingsPanel />;\n }\n\n if (id === 'system') {\n return <SystemSettingsPanel />;\n }\n\n if (id === 'agent-chat') {\n return <AgentChatDefaultsPage />;\n }\n\n if (id === 'agent-workspace') {\n return <AgentWorkspaceDefaultsPage />;\n }\n\n if (id === 'agent-browser') {\n return <AgentBrowserDefaultsPage />;\n }\n\n if (id === 'agent-runtime') {\n return <AgentRuntimeDefaultsPage />;\n }\n\n if (id === 'agent-tools') {\n return <AgentToolsDefaultsPage />;\n }\n\n if (id === 'agent-system-prompt') {\n return <AgentSystemPromptDefaultsPage />;\n }\n\n if (id === 'providers') {\n return <ProvidersSettingsPanel />;\n }\n\n if (id === 'models') {\n return <ModelsSettingsPanel />;\n }\n\n if (id === 'image-models') {\n return <ImageModelsSettingsPanel />;\n }\n\n if (id === 'voice') {\n return <VoiceSettingsPanel />;\n }\n\n if (id === 'gateway') {\n return <GatewaySettingsPanel />;\n }\n\n if (id === 'heartbeat') {\n return <HeartbeatSettingsPanel />;\n }\n\n if (id === 'search') {\n return <WebSearchSettingsPanel />;\n }\n\n if (id === 'dreams') {\n return <DreamingSettingsPanel />;\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{title}</h1>\n <p className=\"text-sm text-fg-muted\">\n {language === 'zh' ? `设置 · ${title}(即将推出)。` : `Settings · ${title} (coming soon).`}\n </p>\n </div>\n );\n}\n"],"mappings":"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"}