@xopcai/xopc 0.0.17 → 0.0.19

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 (32) hide show
  1. package/dist/extensions/telegram/xopc.extension.json +1 -1
  2. package/dist/gateway/static/root/assets/{agents-DouPaDd1.js → agents-ByiiWRbv.js} +2 -2
  3. package/dist/gateway/static/root/assets/{agents-DouPaDd1.js.map → agents-ByiiWRbv.js.map} +1 -1
  4. package/dist/gateway/static/root/assets/{apps-page-NiD-_oC4.js → apps-page-BpR0gguZ.js} +2 -2
  5. package/dist/gateway/static/root/assets/{apps-page-NiD-_oC4.js.map → apps-page-BpR0gguZ.js.map} +1 -1
  6. package/dist/gateway/static/root/assets/{channels-settings-BdNb4uD6.js → channels-settings-h3eQwIPi.js} +2 -2
  7. package/dist/gateway/static/root/assets/{channels-settings-BdNb4uD6.js.map → channels-settings-h3eQwIPi.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/{cron-page-VjRx7Jtc.js → cron-page-D6wtd-hq.js} +2 -2
  9. package/dist/gateway/static/root/assets/{cron-page-VjRx7Jtc.js.map → cron-page-D6wtd-hq.js.map} +1 -1
  10. package/dist/gateway/static/root/assets/{cron-utils-CMkZdWey.js → cron-utils-o-QI_XCC.js} +2 -2
  11. package/dist/gateway/static/root/assets/{cron-utils-CMkZdWey.js.map → cron-utils-o-QI_XCC.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{dist-D-p_Xi_b.js → dist-D2Td6E_v.js} +2 -2
  13. package/dist/gateway/static/root/assets/{dist-D-p_Xi_b.js.map → dist-D2Td6E_v.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{extension-debug-page-B5jGnQgG.js → extension-debug-page-BIni4Qq4.js} +2 -2
  15. package/dist/gateway/static/root/assets/{extension-debug-page-B5jGnQgG.js.map → extension-debug-page-BIni4Qq4.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-page-CSA88lpx.js → extension-page-BRLScNkx.js} +2 -2
  17. package/dist/gateway/static/root/assets/{extension-page-CSA88lpx.js.map → extension-page-BRLScNkx.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/{extension-settings-page-C9HfcH28.js → extension-settings-page-DjiK9Igx.js} +2 -2
  19. package/dist/gateway/static/root/assets/{extension-settings-page-C9HfcH28.js.map → extension-settings-page-DjiK9Igx.js.map} +1 -1
  20. package/dist/gateway/static/root/assets/{index-C5pFj5w6.js → index-KGmhufWu.js} +53 -53
  21. package/dist/gateway/static/root/assets/{index-C5pFj5w6.js.map → index-KGmhufWu.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{logs-page-CrJ87O5K.js → logs-page-C76F4Y0H.js} +2 -2
  23. package/dist/gateway/static/root/assets/{logs-page-CrJ87O5K.js.map → logs-page-C76F4Y0H.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{sessions-page-DJfnuATX.js → sessions-page-9jwUqGtS.js} +2 -2
  25. package/dist/gateway/static/root/assets/{sessions-page-DJfnuATX.js.map → sessions-page-9jwUqGtS.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{settings-page-CBcPUTF-.js → settings-page-DNG3Zijx.js} +2 -2
  27. package/dist/gateway/static/root/assets/{settings-page-CBcPUTF-.js.map → settings-page-DNG3Zijx.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/{skills-page-DVSS_5id.js → skills-page-BY1cLNEz.js} +2 -2
  29. package/dist/gateway/static/root/assets/{skills-page-DVSS_5id.js.map → skills-page-BY1cLNEz.js.map} +1 -1
  30. package/dist/gateway/static/root/index.html +1 -1
  31. package/dist/package.js +1 -1
  32. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agents-DouPaDd1.js","names":[],"sources":["../../../../../web/src/features/settings/agents-admin-api.ts","../../../../../web/src/lib/agent-id.ts","../../../../../web/src/features/settings/suggest-agent-workspace.ts","../../../../../web/src/features/settings/agents/agents-editor-sidebar.tsx","../../../../../web/src/features/settings/agents/agents-editor-modal.tsx","../../../../../web/src/features/settings/agents/agents-list-grid.tsx","../../../../../web/src/features/settings/agents/agents-settings-header.tsx","../../../../../web/src/features/settings/agents/utils.ts","../../../../../web/src/features/settings/agents/create-agent-dialog.tsx","../../../../../web/src/features/settings/settings-form-section.tsx","../../../../../web/src/features/settings/agents/tabs/agent-channels-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-cron-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-files-tab.tsx","../../../../../web/src/features/settings/agents/bootstrap-parser.ts","../../../../../web/src/features/settings/agents/tabs/agent-overview-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-profile-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-skills-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-tools-tab.tsx","../../../../../web/src/features/settings/agents/agents-settings-panel.tsx","../../../../../web/src/features/settings/config-api.ts","../../../../../web/src/features/settings/agents/defaults-field-styles.ts","../../../../../web/src/features/settings/agents/agent-defaults-extra.tsx","../../../../../web/src/features/settings/agents/image-generation-model-input.tsx","../../../../../web/src/features/settings/agents/defaults-panel.tsx"],"sourcesContent":["import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type {\n AgentBootstrapFileEntry,\n GatewayAgentRow,\n GatewayAgentsPayload,\n GatewayConfigBinding,\n SkillCatalogRow,\n} from './types/agent-gateway';\n\nexport type {\n AgentBootstrapFileEntry,\n GatewayAgentRow,\n GatewayAgentsPayload,\n GatewayAgentSkillsInfo,\n GatewayAgentToolsInfo,\n GatewayConfigBinding,\n SkillCatalogRow,\n} from './types/agent-gateway';\n\nfunction normalizeAgentRow(raw: GatewayAgentRow): GatewayAgentRow {\n return {\n ...raw,\n skills: raw.skills ?? { defaults: [] },\n tools: raw.tools ?? { defaultsDisable: [], entryDisable: [], effectiveDisable: [] },\n };\n}\n\nexport async function fetchGatewayAgents(): Promise<GatewayAgentsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: GatewayAgentsPayload }>(apiUrl('/api/agents'));\n const p = res.payload;\n if (!p?.defaultId || !Array.isArray(p.agents)) {\n throw new Error('Invalid /api/agents response');\n }\n const builtinToolIds = Array.isArray(p.builtinToolIds) ? p.builtinToolIds : [];\n return {\n defaultId: p.defaultId,\n agents: p.agents.map(normalizeAgentRow),\n builtinToolIds,\n };\n}\n\nexport type CreateGatewayAgentResult = GatewayAgentsPayload & { createdAgentId: string };\n\nexport async function createGatewayAgent(body: {\n name: string;\n id?: string;\n workspace: string;\n model?: string;\n agentDir?: string;\n description?: string;\n}): Promise<CreateGatewayAgentResult> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId?: string; agents: GatewayAgentsPayload };\n }>(apiUrl('/api/agents'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const createdAgentId = typeof res.payload?.agentId === 'string' ? res.payload.agentId.trim() : '';\n const agents = res.payload?.agents;\n if (!createdAgentId || !agents?.defaultId || !Array.isArray(agents.agents)) {\n throw new Error('Invalid create agent response');\n }\n return {\n createdAgentId,\n defaultId: agents.defaultId,\n agents: agents.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(agents.builtinToolIds) ? agents.builtinToolIds : [],\n };\n}\n\nexport async function updateGatewayAgent(\n id: string,\n body: {\n name?: string;\n description?: string | null;\n workspace?: string;\n model?: string | null;\n agentDir?: string | null;\n setDefault?: boolean;\n skills?: string[] | null;\n toolsDisable?: string[] | null;\n },\n): Promise<GatewayAgentsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: GatewayAgentsPayload }>(\n apiUrl(`/api/agents/${encodeURIComponent(id)}`),\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n },\n );\n const p = res.payload;\n if (!p?.defaultId || !Array.isArray(p.agents)) {\n throw new Error('Invalid update agent response');\n }\n return {\n defaultId: p.defaultId,\n agents: p.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(p.builtinToolIds) ? p.builtinToolIds : [],\n };\n}\n\nexport async function deleteGatewayAgent(id: string, purge: boolean): Promise<GatewayAgentsPayload> {\n const q = purge ? '?purge=true' : '';\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId?: string; purged?: boolean; agents: GatewayAgentsPayload };\n }>(apiUrl(`/api/agents/${encodeURIComponent(id)}${q}`), { method: 'DELETE' });\n const agents = res.payload?.agents;\n if (!agents?.defaultId || !Array.isArray(agents.agents)) {\n throw new Error('Invalid delete agent response');\n }\n return {\n defaultId: agents.defaultId,\n agents: agents.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(agents.builtinToolIds) ? agents.builtinToolIds : [],\n };\n}\n\nexport function parseGatewayBindingsFromConfig(config: unknown): GatewayConfigBinding[] {\n if (!config || typeof config !== 'object' || !('bindings' in config)) {\n return [];\n }\n const raw = (config as { bindings?: unknown }).bindings;\n if (!Array.isArray(raw)) {\n return [];\n }\n return raw as GatewayConfigBinding[];\n}\n\nexport async function fetchGatewayConfigBindings(): Promise<GatewayConfigBinding[]> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: { bindings?: unknown } } }>(\n apiUrl('/api/config'),\n );\n return parseGatewayBindingsFromConfig(res.payload?.config ?? {});\n}\n\nexport async function patchGatewayBindings(bindings: GatewayConfigBinding[]): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ bindings }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchSkillsCatalog(): Promise<SkillCatalogRow[]> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { catalog?: SkillCatalogRow[] };\n }>(apiUrl('/api/skills'));\n const c = res.payload?.catalog;\n return Array.isArray(c) ? c : [];\n}\n\nexport async function fetchAgentBootstrapFiles(agentId: string): Promise<{\n agentId: string;\n bootstrapDir: string;\n files: AgentBootstrapFileEntry[];\n}> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId: string; bootstrapDir: string; files: AgentBootstrapFileEntry[] };\n }>(apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files`));\n const p = res.payload;\n if (!p?.files || !p.bootstrapDir) {\n throw new Error('Invalid files list response');\n }\n return p;\n}\n\nexport async function fetchAgentBootstrapFileContent(\n agentId: string,\n name: string,\n): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(\n apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files/${encodeURIComponent(name)}`),\n );\n const c = res.payload?.content;\n if (typeof c !== 'string') {\n throw new Error('Invalid file content response');\n }\n return c;\n}\n\nexport async function saveAgentBootstrapFileContent(\n agentId: string,\n name: string,\n content: string,\n): Promise<void> {\n await fetchJson(\n apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files/${encodeURIComponent(name)}`),\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content }),\n },\n );\n}\n","/**\n * Agent id rules — keep in sync with `src/agent/agent-scope.ts` (`validateAgentIdForNewAgent`).\n */\n\nconst DEFAULT_AGENT_ID = 'main';\nconst VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;\nconst INVALID_CHARS_RE = /[^a-z0-9_-]+/g;\nconst LEADING_DASH_RE = /^-+/;\nconst TRAILING_DASH_RE = /-+$/;\n\nconst STRICT_AGENT_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;\n\nconst WINDOWS_RESERVED_AGENT_IDS = new Set<string>([\n 'con',\n 'prn',\n 'aux',\n 'nul',\n 'com1',\n 'com2',\n 'com3',\n 'com4',\n 'com5',\n 'com6',\n 'com7',\n 'com8',\n 'com9',\n 'lpt1',\n 'lpt2',\n 'lpt3',\n 'lpt4',\n 'lpt5',\n 'lpt6',\n 'lpt7',\n 'lpt8',\n 'lpt9',\n]);\n\nexport function normalizeAgentId(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return DEFAULT_AGENT_ID;\n }\n const normalized = trimmed.toLowerCase();\n if (VALID_ID_RE.test(trimmed)) {\n return normalized;\n }\n return (\n normalized\n .replace(INVALID_CHARS_RE, '-')\n .replace(LEADING_DASH_RE, '')\n .replace(TRAILING_DASH_RE, '')\n .slice(0, 64) || DEFAULT_AGENT_ID\n );\n}\n\nexport function validateAgentIdForNewAgent(\n explicitId: string | undefined | null,\n displayNameForDerivation: string,\n): { ok: true; agentId: string } | { ok: false; error: string } {\n const explicit = explicitId?.trim();\n if (explicit) {\n const id = explicit.toLowerCase();\n if (!STRICT_AGENT_ID_RE.test(id)) {\n return {\n ok: false,\n error:\n 'Invalid agent id: use 1–64 characters; letters, digits, underscores, and hyphens only; start with a letter or digit.',\n };\n }\n if (id === DEFAULT_AGENT_ID) {\n return { ok: false, error: `\"${DEFAULT_AGENT_ID}\" is reserved` };\n }\n if (WINDOWS_RESERVED_AGENT_IDS.has(id)) {\n return { ok: false, error: `Agent id \"${id}\" is reserved (Windows device name).` };\n }\n return { ok: true, agentId: id };\n }\n\n const agentId = normalizeAgentId(displayNameForDerivation.trim());\n if (agentId === DEFAULT_AGENT_ID) {\n return {\n ok: false,\n error:\n 'Display name cannot produce a valid agent folder id. Set an explicit Agent id (letters, digits, underscores, hyphens only).',\n };\n }\n if (WINDOWS_RESERVED_AGENT_IDS.has(agentId)) {\n return {\n ok: false,\n error: `That display name resolves to \"${agentId}\", which is reserved. Use a different display name or set an explicit Agent id.`,\n };\n }\n if (!STRICT_AGENT_ID_RE.test(agentId)) {\n return {\n ok: false,\n error:\n 'Could not derive a folder-safe agent id from the display name. Set an explicit Agent id (letters, digits, underscores, hyphens only).',\n };\n }\n return { ok: true, agentId };\n}\n","/**\n * Default workspace path suggestion for a new agent (`~/.xopc/workspace/<agentId>`; parent is `agents.defaults.workspace`).\n */\n\nimport { normalizeAgentId } from '@/lib/agent-id';\n\n/** Empty string if `name` is blank; else `~/.xopc/workspace/<agentId>`. */\nexport function suggestWorkspaceFromAgentName(name: string): string {\n const t = name.trim();\n if (!t) {\n return '';\n }\n const id = normalizeAgentId(t);\n return `~/.xopc/workspace/${id}`;\n}\n","import { Clock, FileText, Plug, Puzzle, User, UserCircle, Wrench } from 'lucide-react';\n\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport type { AgentPanel } from './utils';\n\nconst mainNav: { id: AgentPanel; labelKey: keyof AgentsSettingsMessages; icon: typeof User }[] = [\n { id: 'overview', labelKey: 'navIdentity', icon: User },\n { id: 'profile', labelKey: 'navProfile', icon: UserCircle },\n { id: 'tools', labelKey: 'navTools', icon: Wrench },\n { id: 'skills', labelKey: 'navSkills', icon: Puzzle },\n { id: 'files', labelKey: 'navCoreFiles', icon: FileText },\n];\n\nconst advancedNav: { id: AgentPanel; labelKey: keyof AgentsSettingsMessages; icon: typeof Plug }[] = [\n { id: 'channels', labelKey: 'tabChannels', icon: Plug },\n { id: 'cron', labelKey: 'tabCron', icon: Clock },\n];\n\nexport function AgentsEditorSidebar(props: {\n a: AgentsSettingsMessages;\n panel: AgentPanel;\n onPanelChange: (p: AgentPanel) => void;\n}) {\n const { a, panel, onPanelChange } = props;\n\n const item = (id: AgentPanel, label: string, Icon: typeof User) => (\n <button\n key={id}\n type=\"button\"\n onClick={() => onPanelChange(id)}\n className={cn(\n 'flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors',\n panel === id\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover hover:text-fg',\n )}\n >\n <Icon className=\"size-4 shrink-0 opacity-90\" strokeWidth={2} aria-hidden />\n <span className=\"min-w-0 truncate\">{label}</span>\n </button>\n );\n\n return (\n <nav className=\"flex w-full flex-col gap-1\" aria-label={a.editorNavAria}>\n <div className=\"flex flex-col gap-0.5\">\n {mainNav.map(({ id, labelKey, icon }) => item(id, a[labelKey] as string, icon))}\n </div>\n <p className=\"mt-4 px-3 text-[10px] font-semibold uppercase tracking-wide text-fg-subtle\">\n {a.navAdvanced}\n </p>\n <div className=\"flex flex-col gap-0.5\">\n {advancedNav.map(({ id, labelKey, icon }) => item(id, a[labelKey] as string, icon))}\n </div>\n </nav>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport { AgentsEditorSidebar } from './agents-editor-sidebar';\nimport type { AgentPanel } from './utils';\n\nexport function AgentsEditorModal(props: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n a: AgentsSettingsMessages;\n title: string;\n subtitle: string;\n panel: AgentPanel;\n onPanelChange: (p: AgentPanel) => void;\n onFooterSave: () => void;\n footerSaveDisabled: boolean;\n /** Brief \"Saved\" flash after a successful save. */\n footerSavedFlash?: boolean;\n busy: boolean;\n children: ReactNode;\n}) {\n const {\n open,\n onOpenChange,\n a,\n title,\n subtitle,\n panel,\n onPanelChange,\n onFooterSave,\n footerSaveDisabled,\n footerSavedFlash,\n busy,\n children,\n } = props;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed z-[60] flex flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-popover dark:border-edge',\n /* Desktop: roomy editor; inner panels scroll. Small viewports stay inset. */\n 'inset-4 h-[calc(100dvh-2rem)] max-h-[calc(100dvh-2rem)] min-h-0',\n 'sm:inset-auto sm:left-1/2 sm:top-1/2 sm:h-[min(88vh,48rem)] sm:max-h-[min(88vh,48rem)] sm:min-h-[32rem] sm:w-[min(100%-2rem,58rem)] sm:-translate-x-1/2 sm:-translate-y-1/2',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-start justify-between gap-2 border-b border-edge-subtle px-4 pb-3 pt-4 dark:border-edge\">\n <div className=\"min-w-0 pr-2\">\n <Dialog.Title className=\"text-base font-semibold leading-snug text-fg\">{title}</Dialog.Title>\n <Dialog.Description className=\"mt-1 font-mono text-xs text-fg-muted\">{subtitle}</Dialog.Description>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 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={a.closeDialogAria}\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col sm:flex-row sm:overflow-hidden\">\n <div className=\"shrink-0 border-b border-edge-subtle px-4 py-3 dark:border-edge sm:flex sm:w-56 sm:shrink-0 sm:flex-col sm:overflow-y-auto sm:border-b-0 sm:border-r sm:px-0 sm:py-4 sm:pl-4 sm:pr-3\">\n <AgentsEditorSidebar a={a} panel={panel} onPanelChange={onPanelChange} />\n </div>\n\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\">\n {/* Flex column + min-h-0 lets Tools/Skills lists fill remaining height and scroll inside */}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden px-4 py-4 sm:pl-2 sm:pr-5\">\n {children}\n </div>\n <div className=\"flex shrink-0 flex-col gap-1 border-t border-edge-subtle px-4 py-3 dark:border-edge sm:flex-row sm:items-center sm:justify-end sm:gap-3\">\n {footerSavedFlash ? (\n <p className=\"order-2 text-center text-xs font-medium text-green-600 sm:order-1 sm:mr-auto sm:text-left dark:text-green-400\">\n ✓ {a.personaSaved}\n </p>\n ) : footerSaveDisabled ? (\n <p className=\"order-2 text-center text-xs text-fg-muted sm:order-1 sm:mr-auto sm:text-left\">\n {a.footerSaveNotApplicable}\n </p>\n ) : null}\n <Button\n type=\"button\"\n className=\"order-1 w-full sm:order-2 sm:w-auto\"\n disabled={busy || footerSaveDisabled}\n onClick={() => void onFooterSave()}\n >\n {a.save}\n </Button>\n </div>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { Bot, MessageSquarePlus, Plus } from 'lucide-react';\n\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nfunction filterAgents(agents: GatewayAgentRow[], query: string): GatewayAgentRow[] {\n const q = query.trim().toLowerCase();\n if (!q) {\n return agents;\n }\n return agents.filter((ag) => {\n const name = (ag.name ?? '').toLowerCase();\n const id = ag.id.toLowerCase();\n const ws = ag.workspace.toLowerCase();\n const desc = (ag.description ?? '').toLowerCase();\n return name.includes(q) || id.includes(q) || ws.includes(q) || desc.includes(q);\n });\n}\n\nfunction NewAgentCard(props: {\n a: AgentsSettingsMessages;\n busy: boolean;\n onNewAgent: () => void;\n}) {\n const { a, busy, onNewAgent } = props;\n return (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onNewAgent()}\n className={cn(\n 'flex h-full min-h-[7.5rem] w-full flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed border-edge-subtle bg-surface-panel/40 px-4 py-6 text-sm font-medium text-fg-muted transition-colors',\n 'hover:border-accent/50 hover:bg-surface-hover hover:text-fg',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <Plus className=\"size-8 shrink-0 opacity-80\" strokeWidth={1.75} aria-hidden />\n <span>{a.listNewAgentCard}</span>\n </button>\n );\n}\n\nexport function AgentsListGrid(props: {\n a: AgentsSettingsMessages;\n agents: GatewayAgentRow[];\n searchQuery: string;\n onOpenAgent: (id: string) => void;\n onChatWithAgent: (id: string) => void;\n onNewAgent: () => void;\n busy: boolean;\n}) {\n const { a, agents, searchQuery, onOpenAgent, onChatWithAgent, onNewAgent, busy } = props;\n const filtered = filterAgents(agents, searchQuery);\n const searchMiss = agents.length > 0 && filtered.length === 0 && searchQuery.trim().length > 0;\n\n if (agents.length === 0) {\n return (\n <div className=\"flex flex-col gap-4\">\n <p className=\"text-sm text-fg-muted\">{a.listNoAgentsYet}</p>\n <div className=\"max-w-sm\">\n <NewAgentCard a={a} busy={busy} onNewAgent={onNewAgent} />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n {searchMiss ? <p className=\"text-sm text-fg-muted\">{a.listEmpty}</p> : null}\n\n <ul\n className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\"\n role=\"list\"\n >\n <li className=\"h-full min-h-0\">\n <NewAgentCard a={a} busy={busy} onNewAgent={onNewAgent} />\n </li>\n {filtered.map((ag) => {\n const title = ag.name?.trim() ? ag.name.trim() : ag.id;\n const monoId = ag.id;\n const descTrim = ag.description?.trim() ?? '';\n return (\n <li key={ag.id} className=\"h-full min-h-0\">\n <div\n className={cn(\n 'flex h-full min-h-0 flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-panel p-4 shadow-sm transition-colors',\n 'hover:border-edge',\n )}\n >\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onOpenAgent(ag.id)}\n className={cn(\n 'flex shrink-0 w-full flex-col gap-2 text-left transition-colors',\n 'rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <div className=\"flex items-start gap-3\">\n <span\n className=\"flex size-11 shrink-0 items-center justify-center rounded-xl bg-accent-soft text-accent-fg\"\n aria-hidden\n >\n <Bot className=\"size-6\" strokeWidth={1.75} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span className=\"truncate font-semibold text-fg\">{title}</span>\n {ag.isDefault ? (\n <span className=\"shrink-0 rounded-md bg-surface-base px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted\">\n {a.defaultBadge}\n </span>\n ) : null}\n </div>\n <p className=\"mt-0.5 truncate font-mono text-xs text-fg-muted\" title={monoId}>\n {monoId}\n </p>\n </div>\n </div>\n <p\n className={cn(\n 'line-clamp-1 min-h-[1.3125rem] text-xs leading-relaxed',\n descTrim ? 'text-fg' : 'text-fg-muted/25',\n )}\n title={descTrim || undefined}\n >\n {descTrim || '\\u00A0'}\n </p>\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onChatWithAgent(ag.id)}\n className={cn(\n 'flex w-full shrink-0 items-center justify-center gap-2 rounded-full px-4 py-2.5 text-sm font-semibold',\n 'bg-accent-soft text-accent-fg transition-colors',\n 'hover:bg-accent/15',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <MessageSquarePlus className=\"size-4 shrink-0\" strokeWidth={2} aria-hidden />\n {a.listChatWithAgent}\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n","import type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentsSettingsHeader(props: { a: AgentsSettingsMessages }) {\n const { a } = props;\n\n return (\n <header className=\"flex flex-col gap-4\">\n <div className=\"min-w-0\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{a.title}</h1>\n <p className=\"mt-1 max-w-2xl text-sm text-fg-muted\">{a.subtitle}</p>\n </div>\n </header>\n );\n}\n","import type { GatewayConfigBinding } from '@/features/settings/agents-admin-api';\nimport type { CronJob, SessionChatId } from '@/features/cron/cron-api';\nimport { cn } from '@/lib/cn';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\n\nexport type AgentPanel = 'overview' | 'profile' | 'files' | 'tools' | 'skills' | 'channels' | 'cron';\n\nexport function agentsSettingsInputClass(): 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 jobMatchesAgent(job: CronJob, agentId: string, defaultId: string): boolean {\n const raw = job.agentId?.trim().toLowerCase();\n if (raw) {\n return raw === agentId.toLowerCase();\n }\n return agentId.toLowerCase() === defaultId.toLowerCase();\n}\n\nexport function matchSummary(m: GatewayConfigBinding['match']): string {\n const parts = [m.channel, m.accountId, m.peerKind, m.peerId].filter(\n (x): x is string => typeof x === 'string' && x.length > 0,\n );\n return parts.join(' · ') || m.channel;\n}\n\n/** Build a `bindings[].match` for the add-binding form. Custom glob wins over session pick. */\nexport function buildNewBindingMatch(\n channel: string,\n customPeer: string,\n sessionIdx: number | null,\n sessions: SessionChatId[],\n): GatewayConfigBinding['match'] {\n const ch = channel.trim();\n const custom = customPeer.trim();\n if (custom) {\n return { channel: ch, peerId: custom };\n }\n if (sessionIdx != null) {\n const s = sessions[sessionIdx];\n if (!s) {\n return { channel: ch };\n }\n const m: GatewayConfigBinding['match'] = { channel: ch };\n if (s.accountId?.trim()) {\n m.accountId = s.accountId.trim();\n }\n if (s.peerKind?.trim()) {\n m.peerKind = s.peerKind.trim();\n }\n const peer = s.peerId?.trim() || s.chatId?.trim();\n if (peer) {\n m.peerId = peer;\n }\n return m;\n }\n return { channel: ch };\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { UserPlus, X } from 'lucide-react';\nimport type { FormEvent } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages, ChatMessages } from '@/i18n/messages';\n\nimport { agentsSettingsInputClass } from './utils';\n\nexport function CreateAgentDialog(props: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n a: AgentsSettingsMessages;\n chat: ChatMessages;\n busy: boolean;\n modalError: string | null;\n createDisplayName: string;\n setCreateDisplayName: (v: string) => void;\n createAgentId: string;\n setCreateAgentId: (v: string) => void;\n createDescription: string;\n setCreateDescription: (v: string) => void;\n createWorkspace: string;\n setCreateWorkspace: (v: string) => void;\n createModel: string;\n setCreateModel: (v: string) => void;\n onCreate: (e: FormEvent) => void;\n onSuggestWorkspace: () => void;\n}) {\n const {\n open,\n onOpenChange,\n a,\n chat,\n busy,\n modalError,\n createDisplayName,\n setCreateDisplayName,\n createAgentId,\n setCreateAgentId,\n createDescription,\n setCreateDescription,\n createWorkspace,\n setCreateWorkspace,\n createModel,\n setCreateModel,\n onCreate,\n onSuggestWorkspace,\n } = props;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-[60] max-h-[min(90vh,640px)] 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 className=\"min-w-0 pr-2\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">{a.addAgent}</Dialog.Title>\n <Dialog.Description className=\"mt-0.5 text-xs text-fg-muted\">{a.addAgentHint}</Dialog.Description>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 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={a.closeDialogAria}\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n </Dialog.Close>\n </div>\n\n <form className=\"grid gap-3\" onSubmit={onCreate}>\n {modalError ? (\n <div\n role=\"alert\"\n className=\"rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\"\n >\n {modalError}\n </div>\n ) : null}\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newAgentLabel}</span>\n <input\n className={agentsSettingsInputClass()}\n value={createDisplayName}\n onChange={(e) => setCreateDisplayName(e.target.value)}\n onBlur={() => onSuggestWorkspace()}\n required\n autoComplete=\"off\"\n />\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newAgentIdOptional}</span>\n <input\n className={cn(agentsSettingsInputClass(), 'font-mono text-xs')}\n value={createAgentId}\n onChange={(e) => setCreateAgentId(e.target.value)}\n onBlur={() => onSuggestWorkspace()}\n placeholder={a.newAgentIdPlaceholder}\n autoComplete=\"off\"\n spellCheck={false}\n maxLength={64}\n pattern=\"[A-Za-z0-9][A-Za-z0-9_-]{0,63}\"\n title={a.newAgentIdRules}\n />\n <span className=\"text-xs text-fg-muted\">{a.newAgentIdRules}</span>\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.agentDescription}</span>\n <textarea\n className={cn(agentsSettingsInputClass(), 'min-h-[4.5rem] resize-y font-sans text-sm leading-relaxed')}\n value={createDescription}\n onChange={(e) => setCreateDescription(e.target.value)}\n placeholder={a.agentDescriptionPlaceholder}\n maxLength={4000}\n rows={3}\n spellCheck\n />\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newWorkspace}</span>\n <input\n className={cn(agentsSettingsInputClass(), 'font-mono text-xs')}\n value={createWorkspace}\n onChange={(e) => setCreateWorkspace(e.target.value)}\n required\n autoComplete=\"off\"\n />\n </label>\n <div className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newModelOptional}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <ModelSelector\n className=\"min-w-0 flex-1\"\n popoverContentClassName=\"z-[70]\"\n value={createModel}\n disabled={busy}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(id) => setCreateModel(id)}\n />\n {createModel.trim() ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n disabled={busy}\n onClick={() => setCreateModel('')}\n >\n {a.modelClear}\n </Button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-1 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\" disabled={busy}>\n {a.createModalCancel}\n </Button>\n </Dialog.Close>\n <Button type=\"submit\" disabled={busy}>\n <UserPlus className=\"mr-1 size-4\" aria-hidden />\n {a.create}\n </Button>\n </div>\n </form>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '@/lib/cn';\n\n/**\n * Settings content sits on `bg-surface-panel`; grouped blocks use a recessed `bg-surface-base`\n * lift instead of heavy borders (design system §2.1, §4.2).\n */\nexport function settingsFormSectionClassName(): string {\n return 'rounded-2xl bg-surface-base px-4 py-5 sm:px-5';\n}\n\nexport function SettingsFormSection({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return <section className={cn(settingsFormSectionClassName(), className)}>{children}</section>;\n}\n\nexport function SettingsFormSectionHeader({\n icon: Icon,\n title,\n subtitle,\n trailing,\n className,\n}: {\n icon: LucideIcon;\n title: string;\n subtitle: string;\n /** Optional content rendered at the trailing (right) edge of the header. */\n trailing?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn('mb-5 flex items-start gap-3', className)}>\n <div\n className=\"flex size-9 shrink-0 items-center justify-center rounded-lg bg-surface-hover/90 text-fg-muted dark:bg-surface-hover/70\"\n aria-hidden\n >\n <Icon className=\"size-4\" strokeWidth={1.75} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold text-fg\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{subtitle}</p>\n </div>\n {trailing ? <div className=\"shrink-0\">{trailing}</div> : null}\n </div>\n );\n}\n","import { Link2, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayConfigBinding } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport type { ChannelStatus, SessionChatId } from '@/features/cron/cron-api';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport { selectControlBaseClass } from '@/lib/form-field-width';\nimport { agentsSettingsInputClass, matchSummary } from '../utils';\nimport type { AgentsSettingsMessages, MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\nconst channelsPeerIdSelectClass = cn(\n selectControlBaseClass,\n 'w-full text-xs sm:w-auto sm:min-w-[11rem] sm:max-w-[17rem] sm:shrink-0',\n);\n\ntype LastActiveLabels = MessageBundle['cron']['lastActiveLabels'];\n\nexport function AgentChannelsTab(props: {\n a: AgentsSettingsMessages;\n busy: boolean;\n bindingsLoading: boolean;\n agentBindings: GatewayConfigBinding[];\n onRemoveBinding: (rule: GatewayConfigBinding) => void;\n onAddBinding: (e: React.FormEvent) => void;\n channelStatuses: ChannelStatus[];\n channelsStatusLoading: boolean;\n useManualChannel: boolean;\n newBindChannel: string;\n setNewBindChannel: (v: string) => void;\n bindSessionChats: SessionChatId[];\n sessionsLoading: boolean;\n newBindSessionIdx: number | null;\n setNewBindSessionIdx: (v: number | null) => void;\n newBindCustomPeer: string;\n setNewBindCustomPeer: (v: string) => void;\n onRefreshSessions: () => void;\n lastActiveLabels: LastActiveLabels;\n /** Same copy as `cron.selectRecipient` — empty option in peer id dropdown. */\n selectRecipient: string;\n}) {\n const {\n a,\n busy,\n bindingsLoading,\n agentBindings,\n onRemoveBinding,\n onAddBinding,\n channelStatuses,\n channelsStatusLoading,\n useManualChannel,\n newBindChannel,\n setNewBindChannel,\n bindSessionChats,\n sessionsLoading,\n newBindSessionIdx,\n setNewBindSessionIdx,\n newBindCustomPeer,\n setNewBindCustomPeer,\n onRefreshSessions,\n lastActiveLabels,\n selectRecipient,\n } = props;\n\n const showPeerForm = !channelsStatusLoading && (useManualChannel || channelStatuses.length > 0);\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col overflow-y-auto\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={Link2}\n title={a.channelsTitle}\n subtitle={a.channelsHint}\n />\n {bindingsLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsLoading}</p>\n ) : agentBindings.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsNone}</p>\n ) : (\n <ul className=\"flex flex-col gap-2 text-sm\">\n {agentBindings.map((b, i) => (\n <li\n key={`${b.match.channel}-${i}`}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-lg border border-edge bg-surface-panel px-3 py-2\"\n >\n <span className=\"font-mono text-xs\">{matchSummary(b.match)}</span>\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onRemoveBinding(b)}>\n {a.removeBinding}\n </Button>\n </li>\n ))}\n </ul>\n )}\n <form className=\"mt-4 flex flex-col gap-3\" onSubmit={onAddBinding}>\n {channelsStatusLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsLoadingChannels}</p>\n ) : useManualChannel ? (\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.channelLabel}</span>\n <input\n className={agentsSettingsInputClass()}\n value={newBindChannel}\n onChange={(e) => setNewBindChannel(e.target.value)}\n placeholder=\"telegram\"\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-fg-muted\">{a.channelsManualChannelHint}</p>\n </label>\n ) : (\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.channelLabel}</span>\n <select\n className={cn(agentsSettingsInputClass(), 'py-2')}\n value={newBindChannel}\n onChange={(e) => {\n setNewBindChannel(e.target.value);\n setNewBindSessionIdx(null);\n setNewBindCustomPeer('');\n }}\n >\n {channelStatuses.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? a.channelsDisabledSuffix : ''}\n </option>\n ))}\n </select>\n </label>\n )}\n\n {showPeerForm && newBindChannel.trim() ? (\n <div className=\"flex flex-col gap-2 border-t border-edge-subtle pt-3 text-sm\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-fg-muted\">{a.channelsSessionLabel}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n disabled={busy || sessionsLoading || !newBindChannel.trim()}\n title={a.channelsRefreshSessionsHint}\n onClick={() => onRefreshSessions()}\n >\n <RefreshCw className={cn('size-3.5', sessionsLoading && 'animate-spin')} strokeWidth={1.75} />\n {a.channelsRefreshSessions}\n </Button>\n </div>\n {sessionsLoading && bindSessionChats.length === 0 ? (\n <p className=\"text-xs text-fg-muted\">{a.channelsLoadingSessions}</p>\n ) : null}\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-fg-muted\">{a.channelsPeerFromSessions}</span>\n <select\n className={cn(agentsSettingsInputClass(), 'py-2')}\n value={newBindSessionIdx == null ? '' : String(newBindSessionIdx)}\n disabled={busy || !newBindChannel.trim() || Boolean(newBindCustomPeer.trim())}\n onChange={(e) => {\n const v = e.target.value;\n setNewBindSessionIdx(v === '' ? null : Number(v));\n }}\n >\n <option value=\"\">{a.channelsPeerAny}</option>\n {bindSessionChats.map((item, idx) => (\n <option key={`${item.channel}-${item.chatId}-${idx}`} value={String(idx)}>\n {formatRecipientOptionLabel(item, lastActiveLabels)}\n </option>\n ))}\n </select>\n </label>\n {bindSessionChats.length === 0 && newBindChannel.trim() && !sessionsLoading ? (\n <p className=\"text-xs text-fg-muted\">{a.channelsNoSessionsHint}</p>\n ) : null}\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-fg-muted\">{a.peerIdLabel}</span>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-stretch sm:gap-2\">\n <input\n type=\"text\"\n className={cn(agentsSettingsInputClass(), 'min-w-0 w-full sm:flex-1')}\n value={newBindCustomPeer}\n onChange={(e) => {\n setNewBindCustomPeer(e.target.value);\n if (e.target.value.trim()) {\n setNewBindSessionIdx(null);\n }\n }}\n placeholder={a.channelsCustomPeerPlaceholder}\n autoComplete=\"off\"\n />\n <select\n className={channelsPeerIdSelectClass}\n value={newBindCustomPeer}\n onChange={(e) => {\n const v = e.target.value;\n if (v) {\n setNewBindCustomPeer(v);\n } else {\n setNewBindCustomPeer('');\n }\n setNewBindSessionIdx(null);\n }}\n >\n <option value=\"\">{selectRecipient}</option>\n {bindSessionChats.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, lastActiveLabels)}\n </option>\n ))}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">{a.channelsCustomPeerHint}</p>\n </div>\n </div>\n ) : null}\n\n <div>\n <Button type=\"submit\" disabled={busy || !newBindChannel.trim() || channelsStatusLoading}>\n {a.addBinding}\n </Button>\n </div>\n </form>\n </SettingsFormSection>\n );\n}\n","import { AlarmClock } from 'lucide-react';\n\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { cronJobBodyText, type CronJob } from '@/features/cron/cron-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport { agentsSettingsInputClass } from '../utils';\n\nexport function AgentCronTab(props: {\n a: AgentsSettingsMessages;\n data: { agents: GatewayAgentRow[] };\n selected: GatewayAgentRow;\n busy: boolean;\n cronLoading: boolean;\n agentCronJobs: CronJob[];\n onSetCronJobAgent: (job: CronJob, agentKey: string) => void;\n}) {\n const { a, data, busy, cronLoading, agentCronJobs, onSetCronJobAgent } = props;\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col overflow-y-auto\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={AlarmClock}\n title={a.cronTitle}\n subtitle={a.cronHint}\n />\n {cronLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.cronLoading}</p>\n ) : agentCronJobs.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{a.cronNone}</p>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[32rem] border-collapse text-left text-sm\">\n <thead>\n <tr className=\"border-b border-edge text-fg-muted\">\n <th className=\"py-2 pr-3 font-medium\">{a.cronColSchedule}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColMessage}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColSession}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColAgent}</th>\n </tr>\n </thead>\n <tbody>\n {agentCronJobs.map((job) => {\n const usesDefaultAgent = !job.agentId?.trim();\n const value = usesDefaultAgent ? '' : job.agentId!.trim().toLowerCase();\n return (\n <tr key={job.id} className=\"border-b border-edge-subtle\">\n <td className=\"py-2 pr-3 font-mono text-xs\">{job.schedule}</td>\n <td className=\"max-w-[12rem] truncate py-2 pr-3 text-xs\" title={cronJobBodyText(job)}>\n {cronJobBodyText(job)}\n </td>\n <td className=\"py-2 pr-3 text-xs\">{job.sessionTarget ?? 'main'}</td>\n <td className=\"py-2 pr-3\">\n <select\n className={cn(agentsSettingsInputClass(), 'min-w-[8rem] py-1 text-xs')}\n value={value}\n disabled={busy || job.sessionTarget !== 'isolated'}\n onChange={(e) => void onSetCronJobAgent(job, e.target.value)}\n >\n <option value=\"\">{usesDefaultAgent ? a.cronAgentDefault : a.cronAgentClear}</option>\n {data.agents.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {ag.id}\n </option>\n ))}\n </select>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </SettingsFormSection>\n );\n}\n","import { Eye, SquarePen } from 'lucide-react';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { agentsSettingsInputClass } from '../utils';\n\nexport function AgentFilesTab(props: {\n a: AgentsSettingsMessages;\n filesLoading: boolean;\n files: { files: { name: string; missing: boolean }[] } | null;\n activeFile: string | null;\n setActiveFile: (name: string) => void;\n bootstrapViewMode: 'edit' | 'preview';\n setBootstrapViewMode: (m: 'edit' | 'preview') => void;\n fileDraft: string;\n setFileDraft: (v: string) => void;\n fileSaving: boolean;\n bootstrapFileLoading: boolean;\n /** Bumps when bootstrap file body is loaded from the server (remounts CodeMirror). */\n bootstrapEditorNonce: number;\n}) {\n const {\n a,\n filesLoading,\n files,\n activeFile,\n setActiveFile,\n bootstrapViewMode,\n setBootstrapViewMode,\n fileDraft,\n setFileDraft,\n fileSaving,\n bootstrapFileLoading,\n bootstrapEditorNonce,\n } = props;\n\n const isDark = useThemeStore((s) => s.resolved === 'dark');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 overflow-hidden\">\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesHint}</p>\n {filesLoading ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesLoading}</p>\n ) : files ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-hidden\">\n <nav\n className=\"flex shrink-0 flex-row flex-wrap gap-x-0.5 gap-y-0 border-b border-edge-subtle\"\n aria-label={a.tabFiles}\n >\n {files.files.map((f) => (\n <button\n key={f.name}\n type=\"button\"\n className={cn(\n '-mb-px shrink-0 border-b-2 border-transparent px-3 py-2 text-left font-mono text-xs whitespace-nowrap transition-colors',\n activeFile === f.name\n ? 'border-accent text-fg'\n : 'text-fg-muted hover:border-edge-subtle hover:text-fg',\n f.missing && 'opacity-60',\n )}\n onClick={() => setActiveFile(f.name)}\n >\n {f.name}\n {f.missing ? ` (${a.missing})` : ''}\n </button>\n ))}\n </nav>\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col gap-2 overflow-hidden\">\n {activeFile ? (\n <>\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-2\">\n <div\n className=\"inline-flex rounded-lg border border-edge bg-surface-panel p-0.5\"\n role=\"group\"\n aria-label={a.filesBootstrapEdit}\n >\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n bootstrapViewMode === 'edit'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => setBootstrapViewMode('edit')}\n >\n <SquarePen className=\"size-3.5 shrink-0\" aria-hidden />\n {a.filesBootstrapEdit}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n bootstrapViewMode === 'preview'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => setBootstrapViewMode('preview')}\n >\n <Eye className=\"size-3.5 shrink-0\" aria-hidden />\n {a.filesBootstrapPreview}\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-fg-muted\">\n {fileSaving ? <span>{a.filesSavingStatus}</span> : null}\n <span>{a.filesAutoSaveHint}</span>\n </div>\n </div>\n {bootstrapViewMode === 'edit' ? (\n <div\n className={cn(\n agentsSettingsInputClass(),\n 'flex min-h-0 flex-1 flex-col overflow-hidden p-0',\n bootstrapFileLoading && 'pointer-events-none opacity-60',\n )}\n >\n <MarkdownEditor\n key={`${activeFile ?? 'file'}-${bootstrapEditorNonce}`}\n initialContent={fileDraft}\n onChange={setFileDraft}\n isDark={isDark}\n className=\"min-h-0 flex-1\"\n />\n </div>\n ) : (\n <div\n className={cn(\n agentsSettingsInputClass(),\n 'min-h-0 flex-1 overflow-y-auto text-sm',\n bootstrapFileLoading && 'pointer-events-none opacity-60',\n )}\n >\n <MarkdownView content={fileDraft} className=\"text-sm\" />\n </div>\n )}\n </>\n ) : (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.pickFile}</p>\n )}\n </div>\n </div>\n ) : (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesEmpty}</p>\n )}\n </div>\n );\n}\n","/**\n * Bidirectional parser for bootstrap Markdown files.\n *\n * Converts structured form fields ↔ Markdown content for IDENTITY.md, USER.md\n * and SOUL.md so that the persona tab can present friendly form inputs while\n * keeping the underlying Markdown format compatible with the agent runtime.\n */\n\n// ---------------------------------------------------------------------------\n// IDENTITY.md\n// ---------------------------------------------------------------------------\n\nexport interface IdentityFields {\n name: string;\n creature: string;\n emoji: string;\n avatar: string;\n}\n\nconst IDENTITY_DEFAULTS: IdentityFields = {\n name: '',\n creature: '',\n emoji: '',\n avatar: '',\n};\n\n/**\n * Parse IDENTITY.md content into structured fields.\n *\n * Handles the template format:\n * - **Name:** value\n * - **Creature:** value\n * - **Vibe:** value\n * - **Emoji:** value\n * - **Avatar:** value\n */\nexport function parseIdentityMarkdown(content: string): IdentityFields {\n const fields = { ...IDENTITY_DEFAULTS };\n if (!content.trim()) {\n return fields;\n }\n\n const fieldMap: Record<string, keyof IdentityFields> = {\n name: 'name',\n creature: 'creature',\n emoji: 'emoji',\n avatar: 'avatar',\n };\n\n for (const line of content.split('\\n')) {\n const match = line.match(/^[-*]\\s+\\*\\*(\\w+):\\*\\*\\s*(.*)/i);\n if (!match) {\n continue;\n }\n const label = match[1].toLowerCase();\n const fieldKey = fieldMap[label];\n if (!fieldKey) {\n continue;\n }\n let value = match[2].trim();\n // Strip template placeholders like _(pick something you like)_\n if (/^_\\(.*\\)_$/.test(value)) {\n value = '';\n }\n fields[fieldKey] = value;\n }\n\n return fields;\n}\n\n/**\n * Serialize structured identity fields back to IDENTITY.md Markdown.\n */\nexport function serializeIdentityMarkdown(fields: IdentityFields): string {\n const lines = [\n '# IDENTITY.md - Who Am I?',\n '',\n `- **Name:** ${fields.name}`,\n `- **Creature:** ${fields.creature}`,\n `- **Emoji:** ${fields.emoji}`,\n `- **Avatar:** ${fields.avatar}`,\n '',\n ];\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// USER.md (bootstrap)\n// ---------------------------------------------------------------------------\n\nexport interface UserFields {\n callName: string;\n pronouns: string;\n timezone: string;\n notes: string;\n}\n\nconst USER_DEFAULTS: UserFields = {\n callName: '',\n pronouns: '',\n timezone: '',\n notes: '',\n};\n\n/**\n * Parse bootstrap USER.md content into structured fields.\n *\n * Handles the template format:\n * - **Name:** value\n * - **What to call them:** value\n * - **Pronouns:** value\n * - **Timezone:** value\n * - **Notes:** value\n *\n * Also captures the Context section as free-text notes.\n */\nexport function parseUserMarkdown(content: string): UserFields {\n const fields = { ...USER_DEFAULTS };\n if (!content.trim()) {\n return fields;\n }\n\n const fieldMap: Record<string, keyof UserFields> = {\n name: 'callName',\n 'what to call them': 'callName',\n pronouns: 'pronouns',\n timezone: 'timezone',\n notes: 'notes',\n };\n\n const lines = content.split('\\n');\n let contextStartIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Detect the ## Context section\n if (/^##\\s+Context/i.test(line)) {\n contextStartIndex = i + 1;\n continue;\n }\n\n const match = line.match(/^[-*]\\s+\\*\\*(.+?):\\*\\*\\s*(.*)/i);\n if (!match) {\n continue;\n }\n const label = match[1].toLowerCase().trim();\n const fieldKey = fieldMap[label];\n if (!fieldKey) {\n continue;\n }\n let value = match[2].trim();\n // Strip template placeholders like _(optional)_\n if (/^_\\(.*\\)_$/.test(value)) {\n value = '';\n }\n fields[fieldKey] = value;\n }\n\n // Capture context section content as extra notes\n if (contextStartIndex > 0) {\n const contextLines = lines.slice(contextStartIndex);\n const contextText = contextLines\n .join('\\n')\n .replace(/^_\\(.*?\\)_\\s*/gm, '') // strip template placeholders\n .replace(/^---\\s*$/gm, '') // strip trailing horizontal rules\n .replace(/The more you know.*$/s, '') // strip template footer\n .trim();\n\n if (contextText && !fields.notes) {\n fields.notes = contextText;\n }\n }\n\n return fields;\n}\n\n/**\n * Serialize structured user fields back to USER.md Markdown.\n */\nexport function serializeUserMarkdown(fields: UserFields): string {\n const lines = [\n '# USER.md - About Your Human',\n '',\n `- **Name:** ${fields.callName}`,\n `- **Pronouns:** ${fields.pronouns}`,\n `- **Timezone:** ${fields.timezone}`,\n '',\n ];\n\n if (fields.notes.trim()) {\n lines.push('## Context', '', fields.notes.trim(), '');\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// SOUL.md\n// ---------------------------------------------------------------------------\n\n/** Pre-defined soul templates for quick selection. */\nexport type SoulTemplateId = 'professional' | 'casual' | 'geeky' | 'custom';\n\nexport interface SoulTemplate {\n id: SoulTemplateId;\n labelEn: string;\n labelZh: string;\n emoji: string;\n content: string;\n}\n\nexport const SOUL_TEMPLATES: SoulTemplate[] = [\n {\n id: 'professional',\n labelEn: 'Professional & Efficient',\n labelZh: '专业高效',\n emoji: '🎯',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Be genuinely helpful, not performatively helpful.** Skip the filler words — just help. Actions speak louder than pleasantries.\n\n**Be precise and efficient.** Value the user's time. Give concise, actionable answers. Expand only when asked.\n\n**Earn trust through competence.** Be careful with external actions. Be bold with internal ones (reading, organizing, learning).\n\n**Remember you're a guest.** You have access to someone's life. Treat it with respect.\n\n## Boundaries\n\n- Private things stay private. Period.\n- When in doubt, ask before acting externally.\n- Never send half-baked replies to messaging surfaces.\n\n## Vibe\n\nProfessional, competent, and respectful. Concise when needed, thorough when it matters.`,\n },\n {\n id: 'casual',\n labelEn: 'Warm & Friendly',\n labelZh: '轻松友好',\n emoji: '😊',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Be a good friend, not a corporate drone.** Be warm, genuine, and real. Skip the formality when it gets in the way.\n\n**Have personality.** You're allowed to be amused, surprised, or excited. An assistant with no personality is just a search engine.\n\n**Be resourceful before asking.** Try to figure it out first. Then ask if you're stuck.\n\n**Earn trust by being reliable.** Show up, follow through, and remember what matters.\n\n**Respect the intimacy.** You have access to someone's life. That's a privilege.\n\n## Boundaries\n\n- Private things stay private. Always.\n- When in doubt, ask before acting externally.\n- Be careful in group chats — you're not the user's voice.\n\n## Vibe\n\nWarm, friendly, and a little playful. Like a helpful friend who happens to know everything.`,\n },\n {\n id: 'geeky',\n labelEn: 'Geeky & Witty',\n labelZh: '极客风格',\n emoji: '🧑‍💻',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Precision over politeness.** \"This is broken\" beats \"This might be worth considering.\" Be direct.\n\n**Have opinions.** Disagree, prefer things, find stuff interesting or dull. No personality = no value.\n\n**Go deep.** When something is interesting, explore it. Surface-level answers are for search engines.\n\n**Be resourceful.** Read the file. Check the context. Search for it. Come back with answers, not questions.\n\n**Earn trust through competence.** Be careful with external actions. Be bold with internal ones.\n\n## Boundaries\n\n- Private things stay private.\n- When in doubt, ask before acting externally.\n- Never send half-baked replies.\n\n## Vibe\n\nSharp, direct, slightly nerdy. The kind of engineer you'd want on your team — competent, opinionated, and occasionally funny.`,\n },\n {\n id: 'custom',\n labelEn: 'Custom',\n labelZh: '自定义',\n emoji: '✍️',\n content: '',\n },\n];\n\n/**\n * Strip YAML front matter (--- ... ---) from the beginning of Markdown content.\n */\nexport function stripFrontMatterForParsing(content: string): string {\n const trimmed = content.trimStart();\n if (!trimmed.startsWith('---')) {\n return content;\n }\n const endIndex = trimmed.indexOf('---', 3);\n if (endIndex === -1) {\n return content;\n }\n return trimmed.slice(endIndex + 3).trimStart();\n}\n\n/**\n * Detect which soul template best matches the current content.\n * Falls back to 'custom' if no template matches closely.\n */\nexport function detectSoulTemplate(content: string): SoulTemplateId {\n const stripped = stripFrontMatterForParsing(content).trim();\n if (!stripped) {\n return 'professional'; // default for empty content\n }\n\n // Compare against known templates by checking key phrases\n for (const template of SOUL_TEMPLATES) {\n if (template.id === 'custom') {\n continue;\n }\n // Check if the content closely matches the template\n const templateStripped = template.content.trim();\n if (stripped === templateStripped) {\n return template.id;\n }\n // Fuzzy: check for unique key phrases in each template\n const keyPhrases = getTemplateKeyPhrases(template.id);\n const matchCount = keyPhrases.filter((phrase) => stripped.includes(phrase)).length;\n if (matchCount >= 2) {\n return template.id;\n }\n }\n\n return 'custom';\n}\n\nfunction getTemplateKeyPhrases(id: SoulTemplateId): string[] {\n switch (id) {\n case 'professional':\n return ['precise and efficient', \"Value the user's time\", 'actionable answers'];\n case 'casual':\n return ['good friend', 'corporate drone', 'a little playful'];\n case 'geeky':\n return ['Precision over politeness', 'Go deep', 'slightly nerdy'];\n default:\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Timezone helpers\n// ---------------------------------------------------------------------------\n\n/** Common timezone options for the dropdown. */\nexport const TIMEZONE_OPTIONS = [\n { value: '', labelEn: 'Not set', labelZh: '未设置' },\n { value: 'Asia/Shanghai', labelEn: 'Asia/Shanghai (CST, UTC+8)', labelZh: '亚洲/上海 (北京时间, UTC+8)' },\n { value: 'Asia/Tokyo', labelEn: 'Asia/Tokyo (JST, UTC+9)', labelZh: '亚洲/东京 (日本时间, UTC+9)' },\n { value: 'Asia/Seoul', labelEn: 'Asia/Seoul (KST, UTC+9)', labelZh: '亚洲/首尔 (韩国时间, UTC+9)' },\n { value: 'Asia/Singapore', labelEn: 'Asia/Singapore (SGT, UTC+8)', labelZh: '亚洲/新加坡 (UTC+8)' },\n { value: 'Asia/Hong_Kong', labelEn: 'Asia/Hong Kong (HKT, UTC+8)', labelZh: '亚洲/香港 (UTC+8)' },\n { value: 'Asia/Taipei', labelEn: 'Asia/Taipei (CST, UTC+8)', labelZh: '亚洲/台北 (UTC+8)' },\n { value: 'Asia/Kolkata', labelEn: 'Asia/Kolkata (IST, UTC+5:30)', labelZh: '亚洲/加尔各答 (印度时间, UTC+5:30)' },\n { value: 'Asia/Dubai', labelEn: 'Asia/Dubai (GST, UTC+4)', labelZh: '亚洲/迪拜 (UTC+4)' },\n { value: 'Europe/London', labelEn: 'Europe/London (GMT/BST)', labelZh: '欧洲/伦敦 (格林尼治时间)' },\n { value: 'Europe/Paris', labelEn: 'Europe/Paris (CET, UTC+1)', labelZh: '欧洲/巴黎 (中欧时间, UTC+1)' },\n { value: 'Europe/Berlin', labelEn: 'Europe/Berlin (CET, UTC+1)', labelZh: '欧洲/柏林 (中欧时间, UTC+1)' },\n { value: 'Europe/Moscow', labelEn: 'Europe/Moscow (MSK, UTC+3)', labelZh: '欧洲/莫斯科 (UTC+3)' },\n { value: 'America/New_York', labelEn: 'America/New York (EST, UTC-5)', labelZh: '美国/纽约 (东部时间, UTC-5)' },\n { value: 'America/Chicago', labelEn: 'America/Chicago (CST, UTC-6)', labelZh: '美国/芝加哥 (中部时间, UTC-6)' },\n { value: 'America/Denver', labelEn: 'America/Denver (MST, UTC-7)', labelZh: '美国/丹佛 (山地时间, UTC-7)' },\n { value: 'America/Los_Angeles', labelEn: 'America/Los Angeles (PST, UTC-8)', labelZh: '美国/洛杉矶 (太平洋时间, UTC-8)' },\n { value: 'America/Sao_Paulo', labelEn: 'America/São Paulo (BRT, UTC-3)', labelZh: '美洲/圣保罗 (巴西时间, UTC-3)' },\n { value: 'Australia/Sydney', labelEn: 'Australia/Sydney (AEST, UTC+10)', labelZh: '澳大利亚/悉尼 (UTC+10)' },\n { value: 'Pacific/Auckland', labelEn: 'Pacific/Auckland (NZST, UTC+12)', labelZh: '太平洋/奥克兰 (新西兰时间, UTC+12)' },\n] as const;\n\n/**\n * Try to detect the user's timezone from the browser.\n */\nexport function detectBrowserTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n return '';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Vibe presets\n// ---------------------------------------------------------------------------\n\nexport const VIBE_PRESETS = [\n { value: 'warm', labelEn: 'Warm', labelZh: '温暖' },\n { value: 'sharp', labelEn: 'Sharp', labelZh: '犀利' },\n { value: 'calm', labelEn: 'Calm', labelZh: '沉稳' },\n { value: 'playful', labelEn: 'Playful', labelZh: '活泼' },\n { value: 'professional', labelEn: 'Professional', labelZh: '专业' },\n { value: 'casual', labelEn: 'Casual', labelZh: '随意' },\n { value: 'witty', labelEn: 'Witty', labelZh: '机智' },\n { value: 'concise', labelEn: 'Concise', labelZh: '简洁' },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Creature presets\n// ---------------------------------------------------------------------------\n\nexport const PRONOUNS_PRESETS = [\n { value: '先生', labelEn: 'Mr.', labelZh: '先生' },\n { value: '女士', labelEn: 'Ms.', labelZh: '女士' },\n { value: '同学', labelEn: 'Colleague', labelZh: '同学' },\n { value: '老师', labelEn: 'Teacher', labelZh: '老师' },\n { value: '老板', labelEn: 'Boss', labelZh: '老板' },\n { value: '朋友', labelEn: 'Friend', labelZh: '朋友' },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Creature presets\n// ---------------------------------------------------------------------------\n\nexport const CREATURE_PRESETS = [\n { value: 'AI assistant', labelEn: 'AI Assistant', labelZh: 'AI 助手' },\n { value: 'robot', labelEn: 'Robot', labelZh: '机器人' },\n { value: 'familiar', labelEn: 'Familiar', labelZh: '精灵' },\n { value: 'ghost in the machine', labelEn: 'Ghost in the machine', labelZh: '机器幽灵' },\n { value: 'digital companion', labelEn: 'Digital Companion', labelZh: '数字伙伴' },\n] as const;\n","import { type MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { AlertTriangle, Cog, Eye, Pencil, Sparkles, Trash2, User } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport {\n fetchAgentBootstrapFileContent,\n saveAgentBootstrapFileContent,\n} from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages, ChatMessages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { agentsSettingsInputClass } from '../utils';\nimport {\n type IdentityFields,\n type SoulTemplateId,\n parseIdentityMarkdown,\n serializeIdentityMarkdown,\n detectSoulTemplate,\n SOUL_TEMPLATES,\n CREATURE_PRESETS,\n} from '../bootstrap-parser';\n\nexport function AgentOverviewTab(props: {\n a: AgentsSettingsMessages;\n chat: ChatMessages;\n selected: GatewayAgentRow | null;\n busy: boolean;\n editName: string;\n setEditName: (v: string) => void;\n editDescription: string;\n setEditDescription: (v: string) => void;\n editWorkspace: string;\n setEditWorkspace: (v: string) => void;\n editModel: string;\n setEditModel: (v: string) => void;\n onSetDefault: () => void;\n onSaveAgentEdits: () => void;\n onDelete: (purge: boolean) => void;\n hideInlineSave?: boolean;\n /** Parent writes a save-bootstrap callback into this ref so the modal footer can trigger it. */\n saveBootstrapRef?: MutableRefObject<(() => Promise<void>) | null>;\n /** Called when bootstrap-file dirty state changes. */\n onBootstrapDirtyChange?: (dirty: boolean) => void;\n}) {\n const {\n a,\n chat,\n selected,\n busy,\n editName,\n setEditName,\n editDescription,\n setEditDescription,\n editWorkspace,\n setEditWorkspace,\n editModel,\n setEditModel,\n onSetDefault,\n onSaveAgentEdits,\n onDelete,\n hideInlineSave,\n saveBootstrapRef,\n onBootstrapDirtyChange,\n } = props;\n\n const language = useLocaleStore((s) => s.language);\n const isDark = useThemeStore((s) => s.resolved === 'dark');\n\n // ---- Bootstrap file state ----\n const [bootstrapLoading, setBootstrapLoading] = useState(true);\n const [, setBootstrapSaving] = useState(false);\n\n const [identity, setIdentity] = useState<IdentityFields>({\n name: '',\n creature: '',\n emoji: '',\n avatar: '',\n });\n const [soulTemplate, setSoulTemplate] = useState<SoulTemplateId>('professional');\n const [soulCustomContent, setSoulCustomContent] = useState('');\n const [soulEditorNonce, setSoulEditorNonce] = useState(0);\n const [soulPreviewMode, setSoulPreviewMode] = useState(false);\n\n const initialLoadDoneRef = useRef(false);\n const agentIdRef = useRef(selected?.id ?? '');\n agentIdRef.current = selected?.id ?? '';\n\n // Snapshots for dirty tracking (set after load, reset after save)\n const identitySnapshotRef = useRef('');\n const soulSnapshotRef = useRef('');\n\n // ---- Load IDENTITY.md + SOUL.md ----\n useEffect(() => {\n if (!selected) return;\n let cancelled = false;\n initialLoadDoneRef.current = false;\n setBootstrapLoading(true);\n\n const load = async () => {\n try {\n const [identityMd, soulMd] = await Promise.all([\n fetchAgentBootstrapFileContent(selected.id, 'IDENTITY.md').catch(() => ''),\n fetchAgentBootstrapFileContent(selected.id, 'SOUL.md').catch(() => ''),\n ]);\n if (cancelled) return;\n const parsedIdentity = parseIdentityMarkdown(identityMd);\n setIdentity(parsedIdentity);\n identitySnapshotRef.current = JSON.stringify(parsedIdentity);\n setSoulTemplate(detectSoulTemplate(soulMd));\n setSoulCustomContent(soulMd);\n soulSnapshotRef.current = soulMd;\n setSoulEditorNonce((n) => n + 1);\n } finally {\n if (!cancelled) {\n setBootstrapLoading(false);\n initialLoadDoneRef.current = true;\n }\n }\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [selected?.id]);\n\n // ---- Save helpers (manual save only, triggered by footer button) ----\n const saveBootstrapFile = useCallback(async (fileName: string, content: string) => {\n setBootstrapSaving(true);\n try {\n await saveAgentBootstrapFileContent(agentIdRef.current, fileName, content);\n } finally {\n setBootstrapSaving(false);\n }\n }, []);\n\n // Refs to hold latest state for the save callback\n const identityRef = useRef(identity);\n identityRef.current = identity;\n const soulContentRef = useRef(soulCustomContent);\n soulContentRef.current = soulCustomContent;\n\n // Expose save function to parent for the footer save button\n useEffect(() => {\n if (!saveBootstrapRef) return;\n saveBootstrapRef.current = async () => {\n await Promise.all([\n saveBootstrapFile('IDENTITY.md', serializeIdentityMarkdown(identityRef.current)),\n saveBootstrapFile('SOUL.md', soulContentRef.current),\n ]);\n // Reset snapshots after successful save\n identitySnapshotRef.current = JSON.stringify(identityRef.current);\n soulSnapshotRef.current = soulContentRef.current;\n // Manually notify parent since state didn't change (only snapshot did)\n onBootstrapDirtyChange?.(false);\n };\n return () => {\n saveBootstrapRef.current = null;\n };\n }, [saveBootstrapRef, saveBootstrapFile, onBootstrapDirtyChange]);\n\n // Notify parent when bootstrap dirty state changes\n useEffect(() => {\n if (!onBootstrapDirtyChange) return;\n const identityDirty = JSON.stringify(identity) !== identitySnapshotRef.current;\n const soulDirty = soulCustomContent !== soulSnapshotRef.current;\n onBootstrapDirtyChange(identityDirty || soulDirty);\n }, [identity, soulCustomContent, onBootstrapDirtyChange]);\n\n const updateIdentity = useCallback((patch: Partial<IdentityFields>) => {\n setIdentity((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const handleSoulTemplateChange = useCallback((templateId: SoulTemplateId) => {\n setSoulTemplate(templateId);\n if (templateId !== 'custom') {\n const tpl = SOUL_TEMPLATES.find((t) => t.id === templateId);\n if (tpl?.content) {\n setSoulCustomContent(tpl.content);\n setSoulEditorNonce((n) => n + 1);\n }\n }\n }, []);\n\n const handleSoulContentChange = useCallback((content: string) => {\n setSoulCustomContent(content);\n setSoulTemplate('custom');\n }, []);\n\n const locLabel = useCallback(\n (en: string, zh: string) => (language === 'zh' ? zh : en),\n [language],\n );\n\n const inputClass = agentsSettingsInputClass();\n\n if (!selected) {\n return <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>;\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-8 overflow-y-auto\">\n {/* ===== Section 1: Basic Identity ===== */}\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Sparkles}\n title={a.personaSectionIdentity}\n subtitle={a.personaSectionIdentityHint}\n trailing={\n !selected.isDefault ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-xs\"\n disabled={busy}\n onClick={() => void onSetDefault()}\n >\n {a.setDefault}\n </Button>\n ) : null\n }\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {/* Name — single unified field */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.displayName}</span>\n <input\n className={inputClass}\n value={editName}\n onChange={(e) => {\n setEditName(e.target.value);\n updateIdentity({ name: e.target.value });\n }}\n placeholder={a.personaNamePlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Emoji */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaEmoji}</span>\n <input\n className={inputClass}\n value={identity.emoji}\n onChange={(e) => updateIdentity({ emoji: e.target.value })}\n placeholder={a.personaEmojiPlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Description */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.agentDescription}</span>\n <textarea\n className={cn(inputClass, 'min-h-16 resize-y text-sm leading-relaxed')}\n value={editDescription}\n onChange={(e) => setEditDescription(e.target.value)}\n placeholder={a.agentDescriptionPlaceholder}\n maxLength={4000}\n rows={3}\n spellCheck\n />\n </label>\n\n {/* Creature type — dropdown */}\n <div className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaCreature}</span>\n <select\n className={inputClass}\n value={CREATURE_PRESETS.some((p) => p.value === identity.creature) ? identity.creature : '__custom__'}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n updateIdentity({ creature: '' });\n return;\n }\n updateIdentity({ creature: e.target.value });\n }}\n >\n {CREATURE_PRESETS.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {locLabel(preset.labelEn, preset.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{locLabel('Custom…', '自定义…')}</option>\n </select>\n {!CREATURE_PRESETS.some((p) => p.value === identity.creature) ? (\n <input\n className={cn(inputClass, 'mt-1 text-xs')}\n value={identity.creature}\n onChange={(e) => updateIdentity({ creature: e.target.value })}\n placeholder={a.personaCreaturePlaceholder}\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Avatar */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaAvatar}</span>\n <input\n className={cn(inputClass, 'font-mono text-xs')}\n value={identity.avatar}\n onChange={(e) => updateIdentity({ avatar: e.target.value })}\n placeholder={a.personaAvatarPlaceholder}\n autoComplete=\"off\"\n />\n </label>\n </div>\n </SettingsFormSection>\n\n {/* ===== Section 2: Runtime Configuration ===== */}\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cog} title={a.editAgent} subtitle={a.editAgentHint} />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.modelPrimary}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <ModelSelector\n className=\"min-w-0 flex-1\"\n popoverContentClassName=\"z-[70]\"\n value={editModel}\n disabled={busy}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(id) => setEditModel(id)}\n />\n {editModel.trim() ? (\n <Button type=\"button\" variant=\"secondary\" className=\"shrink-0\" disabled={busy} onClick={() => setEditModel('')}>\n {a.modelClear}\n </Button>\n ) : null}\n </div>\n </div>\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.workspacePath}</span>\n <input\n className={cn(inputClass, 'font-mono text-xs')}\n value={editWorkspace}\n onChange={(e) => setEditWorkspace(e.target.value)}\n />\n </label>\n </div>\n {!hideInlineSave ? (\n <div className=\"mt-4\">\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveAgentEdits()}>\n {a.save}\n </Button>\n </div>\n ) : null}\n </SettingsFormSection>\n\n {/* ===== Section 3: Personality & Style ===== */}\n {bootstrapLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={User} title={a.personaSectionSoul} subtitle={a.personaSectionSoulHint} />\n {/* Soul template */}\n <div className=\"mb-4 flex flex-col gap-2\">\n <span className=\"text-sm font-medium text-fg\">{a.personaSoulTemplate}</span>\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-4\">\n {SOUL_TEMPLATES.map((template) => (\n <button\n key={template.id}\n type=\"button\"\n className={cn(\n 'flex flex-col items-center gap-1.5 rounded-xl border-2 px-3 py-3 text-center transition-all',\n soulTemplate === template.id\n ? 'border-accent bg-accent-soft/40 shadow-sm'\n : 'border-edge hover:border-accent/40 hover:bg-surface-hover',\n )}\n onClick={() => handleSoulTemplateChange(template.id)}\n >\n <span className=\"text-xl\">{template.emoji}</span>\n <span className=\"text-xs font-medium text-fg\">{locLabel(template.labelEn, template.labelZh)}</span>\n </button>\n ))}\n </div>\n </div>\n {soulTemplate === 'custom' ? (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium text-fg\">{a.personaSoulCustomEdit}</span>\n <button\n type=\"button\"\n className=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md text-fg-muted transition-colors hover:bg-surface-hover hover:text-fg\"\n title={soulPreviewMode ? a.personaSoulEdit : a.personaSoulPreview}\n aria-label={soulPreviewMode ? a.personaSoulEdit : a.personaSoulPreview}\n onClick={() => setSoulPreviewMode((v) => !v)}\n >\n {soulPreviewMode ? <Pencil className=\"size-4\" aria-hidden /> : <Eye className=\"size-4\" aria-hidden />}\n </button>\n </div>\n <div className={cn(inputClass, 'flex min-h-64 flex-col overflow-hidden p-0')}>\n {soulPreviewMode ? (\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n <MarkdownView content={soulCustomContent} />\n </div>\n ) : (\n <MarkdownEditor\n key={`soul-${soulEditorNonce}`}\n initialContent={soulCustomContent}\n onChange={handleSoulContentChange}\n isDark={isDark}\n className=\"min-h-0 flex-1\"\n />\n )}\n </div>\n </div>\n ) : null}\n </SettingsFormSection>\n )}\n\n {/* ===== Section 4: Danger Zone ===== */}\n {selected.id !== 'main' ? (\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={AlertTriangle}\n title={locLabel('Danger Zone', '危险操作')}\n subtitle={locLabel(\n 'Actions that cannot be undone. Be careful.',\n '以下操作不可撤销,请谨慎操作。',\n )}\n />\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onDelete(false)}>\n <Trash2 className=\"mr-1 size-4\" aria-hidden />\n {a.removeFromConfig}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"border-red-200 text-red-700 hover:bg-red-50 dark:border-red-900/60 dark:text-red-300 dark:hover:bg-red-950/40\"\n disabled={busy}\n onClick={() => void onDelete(true)}\n >\n {a.purgeDisk}\n </Button>\n </div>\n </SettingsFormSection>\n ) : null}\n </div>\n );\n}\n","import { Info, UserCircle } from 'lucide-react';\nimport { type MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\n\nimport {\n SettingsFormSection,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport {\n fetchAgentBootstrapFileContent,\n saveAgentBootstrapFileContent,\n} from '@/features/settings/agents-admin-api';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport { agentsSettingsInputClass } from '../utils';\nimport {\n type UserFields,\n parseUserMarkdown,\n serializeUserMarkdown,\n TIMEZONE_OPTIONS,\n PRONOUNS_PRESETS,\n detectBrowserTimezone,\n} from '../bootstrap-parser';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface ProfileTabProps {\n a: AgentsSettingsMessages;\n agentId: string;\n /** Parent writes a save callback into this ref so the modal footer can trigger it. */\n saveRef?: MutableRefObject<(() => Promise<void>) | null>;\n /** Called when dirty state changes. */\n onDirtyChange?: (dirty: boolean) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component — About You (USER.md)\n// ---------------------------------------------------------------------------\n\nexport function AgentProfileTab({ a, agentId, saveRef, onDirtyChange }: ProfileTabProps) {\n const language = useLocaleStore((s) => s.language);\n\n const [loading, setLoading] = useState(true);\n const [, setSaving] = useState(false);\n\n const [user, setUser] = useState<UserFields>({\n callName: '',\n pronouns: '',\n timezone: '',\n notes: '',\n });\n\n const [showCustomPronouns, setShowCustomPronouns] = useState(false);\n const [showCustomTimezone, setShowCustomTimezone] = useState(false);\n const [customTimezone, setCustomTimezone] = useState('');\n\n const initialLoadDoneRef = useRef(false);\n const agentIdRef = useRef(agentId);\n agentIdRef.current = agentId;\n\n // Snapshot for dirty tracking (set after load, reset after save)\n const userSnapshotRef = useRef('');\n\n // ---- Save helper (manual save only, triggered by footer button) ----\n const saveFile = useCallback(async (content: string) => {\n const currentAgent = agentIdRef.current;\n setSaving(true);\n try {\n await saveAgentBootstrapFileContent(currentAgent, 'USER.md', content);\n } finally {\n setSaving(false);\n }\n }, []);\n\n // Ref to hold latest user state for the save callback\n const userRef = useRef(user);\n userRef.current = user;\n\n // Expose save function to parent for the footer save button\n useEffect(() => {\n if (!saveRef) return;\n saveRef.current = async () => {\n await saveFile(serializeUserMarkdown(userRef.current));\n userSnapshotRef.current = JSON.stringify(userRef.current);\n // Manually notify parent since state didn't change (only snapshot did)\n onDirtyChange?.(false);\n };\n return () => {\n saveRef.current = null;\n };\n }, [saveRef, saveFile, onDirtyChange]);\n\n // Notify parent when dirty state changes\n useEffect(() => {\n if (!onDirtyChange) return;\n onDirtyChange(JSON.stringify(user) !== userSnapshotRef.current);\n }, [user, onDirtyChange]);\n\n // ---- Load USER.md on mount / agentId change ----\n useEffect(() => {\n let cancelled = false;\n initialLoadDoneRef.current = false;\n setLoading(true);\n\n const load = async () => {\n try {\n const userMd = await fetchAgentBootstrapFileContent(agentId, 'USER.md').catch(() => '');\n if (cancelled) return;\n\n const parsedUser = parseUserMarkdown(userMd);\n\n // Auto-detect timezone if not already set (saved when user clicks \"Save\")\n let effectiveUser = parsedUser;\n if (!parsedUser.timezone) {\n const detected = detectBrowserTimezone();\n if (detected) {\n effectiveUser = { ...parsedUser, timezone: detected };\n }\n }\n\n setUser(effectiveUser);\n userSnapshotRef.current = JSON.stringify(effectiveUser);\n\n // Custom pronouns handling\n const isKnownPronouns = !effectiveUser.pronouns || PRONOUNS_PRESETS.some((p) => p.value === effectiveUser.pronouns);\n if (effectiveUser.pronouns && !isKnownPronouns) {\n setShowCustomPronouns(true);\n }\n\n // Custom timezone handling\n const isKnownTimezone = TIMEZONE_OPTIONS.some((tz) => tz.value === effectiveUser.timezone);\n if (effectiveUser.timezone && !isKnownTimezone) {\n setShowCustomTimezone(true);\n setCustomTimezone(effectiveUser.timezone);\n }\n } finally {\n if (!cancelled) {\n setLoading(false);\n initialLoadDoneRef.current = true;\n }\n }\n };\n\n void load();\n return () => {\n cancelled = true;\n };\n }, [agentId]);\n\n // ---- Field updater (local state only, saved via footer button) ----\n const updateUser = useCallback((patch: Partial<UserFields>) => {\n setUser((prev) => ({ ...prev, ...patch }));\n }, []);\n\n // ---- Timezone handling ----\n const handleTimezoneChange = useCallback(\n (value: string) => {\n if (value === '__custom__') {\n setShowCustomTimezone(true);\n return;\n }\n setShowCustomTimezone(false);\n setCustomTimezone('');\n updateUser({ timezone: value });\n },\n [updateUser],\n );\n\n const handleCustomTimezoneChange = useCallback(\n (value: string) => {\n setCustomTimezone(value);\n updateUser({ timezone: value });\n },\n [updateUser],\n );\n\n const handleDetectTimezone = useCallback(() => {\n const detected = detectBrowserTimezone();\n if (detected) {\n const isKnown = TIMEZONE_OPTIONS.some((tz) => tz.value === detected);\n if (isKnown) {\n setShowCustomTimezone(false);\n setCustomTimezone('');\n } else {\n setShowCustomTimezone(true);\n setCustomTimezone(detected);\n }\n updateUser({ timezone: detected });\n }\n }, [updateUser]);\n\n // ---- Effective timezone for select ----\n const timezoneSelectValue = (() => {\n if (showCustomTimezone) return '__custom__';\n const isKnown = TIMEZONE_OPTIONS.some((tz) => tz.value === user.timezone);\n return isKnown ? user.timezone : '__custom__';\n })();\n\n const locLabel = useCallback(\n (en: string, zh: string) => (language === 'zh' ? zh : en),\n [language],\n );\n\n if (loading) {\n return <p className=\"text-sm text-fg-muted\">{a.loading}</p>;\n }\n\n const inputClass = agentsSettingsInputClass();\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto\">\n <p className=\"text-sm text-fg-muted\">{a.personaSectionUserHint}</p>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={UserCircle}\n title={a.personaSectionUser}\n subtitle={a.personaSectionUserHint}\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {/* Call name */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaCallName}</span>\n <input\n className={inputClass}\n value={user.callName}\n onChange={(e) => updateUser({ callName: e.target.value })}\n placeholder={a.personaCallNamePlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Pronouns */}\n <div className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaPronouns}</span>\n <select\n className={inputClass}\n value={PRONOUNS_PRESETS.some((p) => p.value === user.pronouns) ? user.pronouns : '__custom__'}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n setShowCustomPronouns(true);\n return;\n }\n setShowCustomPronouns(false);\n updateUser({ pronouns: e.target.value });\n }}\n >\n <option value=\"\" disabled>\n {a.personaPronounsPlaceholder}\n </option>\n {PRONOUNS_PRESETS.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {locLabel(preset.labelEn, preset.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{locLabel('Custom…', '自定义…')}</option>\n </select>\n {showCustomPronouns ? (\n <input\n className={cn(inputClass, 'mt-1 text-xs')}\n value={PRONOUNS_PRESETS.some((p) => p.value === user.pronouns) ? '' : user.pronouns}\n onChange={(e) => updateUser({ pronouns: e.target.value })}\n placeholder={a.personaPronounsPlaceholder}\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Timezone */}\n <div className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaTimezone}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <select\n className={cn(inputClass, 'min-w-0 flex-1')}\n value={timezoneSelectValue}\n onChange={(e) => handleTimezoneChange(e.target.value)}\n >\n {TIMEZONE_OPTIONS.map((tz) => (\n <option key={tz.value} value={tz.value}>\n {locLabel(tz.labelEn, tz.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{a.personaTimezoneCustom}</option>\n </select>\n <button\n type=\"button\"\n className=\"shrink-0 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-xs font-medium text-fg-muted hover:bg-surface-hover hover:text-fg\"\n onClick={handleDetectTimezone}\n >\n {a.personaTimezoneDetect}\n </button>\n </div>\n {showCustomTimezone ? (\n <input\n className={cn(inputClass, 'mt-1 font-mono text-xs')}\n value={customTimezone}\n onChange={(e) => handleCustomTimezoneChange(e.target.value)}\n placeholder=\"e.g. Asia/Shanghai\"\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Notes */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaNotes}</span>\n <textarea\n className={cn(inputClass, 'min-h-16 resize-y text-sm leading-relaxed')}\n value={user.notes}\n onChange={(e) => updateUser({ notes: e.target.value })}\n placeholder={a.personaNotesPlaceholder}\n rows={3}\n spellCheck\n />\n </label>\n </div>\n\n {/* Memory note */}\n <div className=\"mt-3 flex items-start gap-2 rounded-lg bg-accent-soft/30 px-3 py-2.5 text-xs text-fg-muted\">\n <Info className=\"mt-0.5 size-3.5 shrink-0 text-accent\" aria-hidden />\n <span>{a.personaMemoryNote}</span>\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n","import { BookOpen } from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayAgentRow, SkillCatalogRow } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentSkillsTab(props: {\n a: AgentsSettingsMessages;\n selected: GatewayAgentRow;\n busy: boolean;\n skillsCatalogLoading: boolean;\n catalogForPick: SkillCatalogRow[];\n skillsInherit: boolean;\n setSkillsInherit: (v: boolean) => void;\n skillsPick: Set<string>;\n setSkillsPick: Dispatch<SetStateAction<Set<string>>>;\n onSaveSkills: () => void;\n hideInlineSave?: boolean;\n}) {\n const {\n a,\n selected,\n busy,\n skillsCatalogLoading,\n catalogForPick,\n skillsInherit,\n setSkillsInherit,\n skillsPick,\n setSkillsPick,\n onSaveSkills,\n hideInlineSave,\n } = props;\n\n /** When inheriting defaults, checkboxes reflect the effective allowlist (undefined = all catalog skills). */\n function isCheckedInheritMode(id: string): boolean {\n const eff = selected.skills.effectiveAllowlist;\n if (eff === undefined) {\n return true;\n }\n if (eff.length === 0) {\n return false;\n }\n return eff.includes(id);\n }\n\n function initialPickForCustomize(): Set<string> {\n const eff = selected.skills.effectiveAllowlist;\n if (eff !== undefined) {\n return new Set(eff);\n }\n return new Set(catalogForPick.map((s) => s.name || s.directoryId));\n }\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={BookOpen}\n title={a.skillsTitle}\n subtitle={a.skillsHint}\n />\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-3\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => setSkillsInherit(true)}>\n {a.skillsInherit}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={busy}\n onClick={() => {\n setSkillsInherit(false);\n setSkillsPick(initialPickForCustomize());\n }}\n >\n {a.skillsCustomize}\n </Button>\n </div>\n <Link\n to=\"/skills\"\n className=\"shrink-0 text-xs font-medium text-accent-fg hover:underline\"\n >\n {a.skillsLibraryLink}\n </Link>\n </div>\n <p className=\"mt-2 shrink-0 text-xs text-fg-muted\">\n {a.skillsDefaultsLabel} {selected.skills.defaults.length ? selected.skills.defaults.join(', ') : '—'}\n </p>\n <p className=\"shrink-0 text-xs text-fg-muted\">\n {a.skillsEffectiveLabel}{' '}\n {selected.skills.effectiveAllowlist?.length\n ? selected.skills.effectiveAllowlist.join(', ')\n : a.skillsAllFromCatalog}\n </p>\n {skillsCatalogLoading ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.skillsCatalogLoading}</p>\n ) : catalogForPick.length === 0 ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.skillsEmptyCatalog}</p>\n ) : (\n <div\n className={cn(\n 'mt-3 min-h-0 flex-1 overflow-y-auto overscroll-contain pr-0.5',\n skillsInherit && 'opacity-50',\n )}\n >\n <ul className=\"flex flex-col gap-2.5 text-sm\" role=\"list\">\n {catalogForPick.map((s) => {\n const id = s.name || s.directoryId;\n const on = skillsInherit ? isCheckedInheritMode(id) : skillsPick.has(id);\n const desc = typeof s.description === 'string' ? s.description.trim() : '';\n const descLine = desc || a.skillsNoDescription;\n return (\n <li\n key={id}\n className=\"h-16 shrink-0 overflow-hidden rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 dark:border-edge-subtle\"\n >\n <label className=\"flex h-full cursor-pointer items-center gap-3 text-sm\">\n <input\n type=\"checkbox\"\n className=\"shrink-0 rounded border-edge\"\n checked={on}\n disabled={skillsInherit || busy}\n onChange={() => {\n setSkillsPick((prev) => {\n const next = new Set(prev);\n if (on) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }}\n />\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n <div className=\"truncate font-mono text-xs font-medium text-fg\" title={id}>\n {id}\n </div>\n <p\n className={cn(\n 'mt-0.5 truncate text-xs leading-tight text-fg-muted',\n !desc && 'italic text-fg-subtle',\n )}\n title={descLine}\n >\n {descLine}\n </p>\n </div>\n </label>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n {!hideInlineSave ? (\n <div className=\"mt-4 shrink-0\">\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveSkills()}>\n {a.skillsSave}\n </Button>\n </div>\n ) : null}\n </SettingsFormSection>\n );\n}\n","import { Wrench } from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentToolsTab(props: {\n a: AgentsSettingsMessages;\n data: { builtinToolIds: string[] };\n selected: GatewayAgentRow;\n busy: boolean;\n toolEntryDisable: Set<string>;\n setToolEntryDisable: Dispatch<SetStateAction<Set<string>>>;\n onSaveTools: () => void;\n onClearToolsEntry: () => void;\n hideInlineSave?: boolean;\n}) {\n const {\n a,\n data,\n selected,\n busy,\n toolEntryDisable,\n setToolEntryDisable,\n onSaveTools,\n onClearToolsEntry,\n hideInlineSave,\n } = props;\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={Wrench}\n title={a.toolsTitle}\n subtitle={a.toolsHint}\n />\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n <ul className=\"flex flex-col gap-2.5 pr-1\" role=\"list\">\n {(data.builtinToolIds.length ? data.builtinToolIds : []).map((tid) => {\n const disabledByDefault = selected.tools.defaultsDisable.includes(tid);\n const checked = disabledByDefault ? false : !toolEntryDisable.has(tid);\n const desc =\n tid in a.toolDescriptions ? a.toolDescriptions[tid as keyof typeof a.toolDescriptions] : '';\n return (\n <li\n key={tid}\n className={cn(\n 'rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-2.5 dark:border-edge-subtle',\n disabledByDefault && 'opacity-60',\n )}\n >\n <label\n className={cn('flex cursor-pointer gap-3 text-sm', disabledByDefault && 'cursor-not-allowed')}\n >\n <input\n type=\"checkbox\"\n className=\"mt-1 shrink-0 rounded border-edge\"\n checked={checked}\n disabled={disabledByDefault || busy}\n onChange={() => {\n if (disabledByDefault) {\n return;\n }\n setToolEntryDisable((prev) => {\n const next = new Set(prev);\n if (next.has(tid)) {\n next.delete(tid);\n } else {\n next.add(tid);\n }\n return next;\n });\n }}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span className=\"font-mono text-xs font-medium text-fg\">{tid}</span>\n {disabledByDefault ? (\n <span className=\"text-xs text-fg-muted\">({a.toolsLockedByDefaults})</span>\n ) : null}\n </div>\n {desc ? <p className=\"mt-1 text-xs leading-relaxed text-fg-muted\">{desc}</p> : null}\n </div>\n </label>\n </li>\n );\n })}\n </ul>\n </div>\n <div className=\"mt-4 flex shrink-0 flex-wrap gap-2\">\n {!hideInlineSave ? (\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveTools()}>\n {a.toolsSave}\n </Button>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onClearToolsEntry()}>\n {a.toolsClearEntry}\n </Button>\n </div>\n </SettingsFormSection>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Plus, Search, SlidersHorizontal } from 'lucide-react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type FormEvent } from 'react';\nimport { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';\nimport useSWR from 'swr';\nimport { useDebouncedCallback } from 'use-debounce';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n createGatewayAgent,\n deleteGatewayAgent,\n fetchAgentBootstrapFileContent,\n fetchAgentBootstrapFiles,\n fetchGatewayAgents,\n parseGatewayBindingsFromConfig,\n fetchSkillsCatalog,\n patchGatewayBindings,\n saveAgentBootstrapFileContent,\n updateGatewayAgent,\n type GatewayAgentRow,\n type GatewayAgentsPayload,\n type GatewayConfigBinding,\n type SkillCatalogRow,\n} from '@/features/settings/agents-admin-api';\nimport { AGENTS_APP_LIST_PATH, agentsAppDetailPath } from '@/features/settings/agents/agents-app-path';\nimport { SETTINGS_BACK_PATH_STATE_KEY } from '@/features/settings/settings-nav-state';\nimport { suggestWorkspaceFromAgentName } from '@/features/settings/suggest-agent-workspace';\nimport { validateAgentIdForNewAgent } from '@/lib/agent-id';\nimport {\n getChannels,\n getSessionChatIds,\n listJobs,\n updateJob,\n type ChannelStatus,\n type CronJob,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { messages } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { usePageHeaderStore } from '@/stores/page-header-store';\n\nimport { AgentsEditorModal } from './agents-editor-modal';\nimport { AgentsListGrid } from './agents-list-grid';\nimport { AgentsSettingsHeader } from './agents-settings-header';\nimport { CreateAgentDialog } from './create-agent-dialog';\nimport { AgentChannelsTab } from './tabs/agent-channels-tab';\nimport { AgentCronTab } from './tabs/agent-cron-tab';\nimport { AgentFilesTab } from './tabs/agent-files-tab';\nimport { AgentOverviewTab } from './tabs/agent-overview-tab';\nimport { AgentProfileTab } from './tabs/agent-profile-tab';\nimport { AgentSkillsTab } from './tabs/agent-skills-tab';\nimport { AgentToolsTab } from './tabs/agent-tools-tab';\nimport type { AgentPanel } from './utils';\nimport { buildNewBindingMatch, jobMatchesAgent } from './utils';\n\nexport function AgentsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.agentsSettings;\n\n const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);\n const [deleteTarget, setDeleteTarget] = useState<GatewayAgentRow | null>(null);\n const [deletePurge, setDeletePurge] = useState(false);\n const [deleteConfirmText, setDeleteConfirmText] = useState('');\n const cCron = m.cron;\n const chat = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n const { agentId: routeAgentId } = useParams<{ agentId?: string }>();\n const setPageHeader = usePageHeaderStore((s) => s.setPageHeader);\n const clearPageHeader = usePageHeaderStore((s) => s.clearPageHeader);\n\n const agentsSwrKey = hasToken ? 'settings-gateway-agents' : null;\n const {\n data: swrAgentsData,\n error: swrAgentsError,\n isLoading: agentsLoading,\n mutate: mutateAgents,\n } = useSWR(agentsSwrKey, fetchGatewayAgents, { revalidateOnFocus: false });\n\n const { data: gatewayCfgData } = useGatewayConfigSwr(hasToken);\n\n const bindingsFromConfig = useMemo(\n () => parseGatewayBindingsFromConfig(gatewayCfgData?.payload?.config ?? {}),\n [gatewayCfgData],\n );\n\n const data: GatewayAgentsPayload | null = swrAgentsData ?? null;\n const loading = Boolean(hasToken && agentsLoading);\n const [error, setError] = useState<string | null>(null);\n const loadError =\n swrAgentsError instanceof Error ? swrAgentsError.message : swrAgentsError ? a.loadError : null;\n const displayError = error ?? loadError;\n\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [panel, setPanel] = useState<AgentPanel>('overview');\n\n const [createDisplayName, setCreateDisplayName] = useState('');\n const [createAgentId, setCreateAgentId] = useState('');\n const [createDescription, setCreateDescription] = useState('');\n const [createWorkspace, setCreateWorkspace] = useState('');\n const [createModel, setCreateModel] = useState('');\n const [createModalError, setCreateModalError] = useState<string | null>(null);\n const [addAgentModalOpen, setAddAgentModalOpen] = useState(false);\n const createWorkspaceSuggestedRef = useRef('');\n const [busy, setBusy] = useState(false);\n const [listSearchQuery, setListSearchQuery] = useState('');\n\n const [editWorkspace, setEditWorkspace] = useState('');\n const [editModel, setEditModel] = useState('');\n const [editName, setEditName] = useState('');\n const [editDescription, setEditDescription] = useState('');\n\n const [files, setFiles] = useState<Awaited<ReturnType<typeof fetchAgentBootstrapFiles>> | null>(null);\n const [filesLoading, setFilesLoading] = useState(false);\n const [activeFile, setActiveFile] = useState<string | null>(null);\n const [fileDraft, setFileDraft] = useState('');\n const [fileSaving, setFileSaving] = useState(false);\n const [bootstrapViewMode, setBootstrapViewMode] = useState<'edit' | 'preview'>('edit');\n const [bootstrapFileLoading, setBootstrapFileLoading] = useState(false);\n const [bootstrapEditorNonce, setBootstrapEditorNonce] = useState(0);\n\n const fileDraftRef = useRef(fileDraft);\n fileDraftRef.current = fileDraft;\n const selectedIdRef = useRef(selectedId);\n selectedIdRef.current = selectedId;\n const activeFileRef = useRef(activeFile);\n activeFileRef.current = activeFile;\n const overviewSaveBootstrapRef = useRef<(() => Promise<void>) | null>(null);\n const profileSaveRef = useRef<(() => Promise<void>) | null>(null);\n const [overviewBootstrapDirty, setOverviewBootstrapDirty] = useState(false);\n const [profileDirty, setProfileDirty] = useState(false);\n const [savedFlash, setSavedFlash] = useState(false);\n const bootstrapFileKeyRef = useRef('');\n const bootstrapSyncedRef = useRef('');\n\n const saveBootstrapDebounced = useDebouncedCallback(\n async () => {\n const sid = selectedIdRef.current;\n const name = activeFileRef.current;\n if (!sid || !name) {\n return;\n }\n const key = `${sid}:${name}`;\n if (key !== bootstrapFileKeyRef.current) {\n return;\n }\n const draft = fileDraftRef.current;\n if (draft === bootstrapSyncedRef.current) {\n return;\n }\n setFileSaving(true);\n setError(null);\n try {\n await saveAgentBootstrapFileContent(sid, name, draft);\n bootstrapSyncedRef.current = draft;\n setFiles((prev) => {\n if (!prev || prev.agentId !== sid) {\n return prev;\n }\n return {\n ...prev,\n files: prev.files.map((f) => (f.name === name ? { ...f, missing: false } : f)),\n };\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setFileSaving(false);\n }\n },\n 800,\n );\n\n const flushBootstrapSaveRef = useRef(saveBootstrapDebounced.flush);\n flushBootstrapSaveRef.current = saveBootstrapDebounced.flush;\n\n useEffect(() => {\n return () => {\n flushBootstrapSaveRef.current();\n };\n }, []);\n\n const [toolEntryDisable, setToolEntryDisable] = useState<Set<string>>(() => new Set());\n const [skillsPick, setSkillsPick] = useState<Set<string>>(() => new Set());\n const [skillsInherit, setSkillsInherit] = useState(true);\n\n const [allBindings, setAllBindings] = useState<GatewayConfigBinding[]>([]);\n const [newBindChannel, setNewBindChannel] = useState('');\n const [bindChannelStatuses, setBindChannelStatuses] = useState<ChannelStatus[]>([]);\n const [bindChannelsLoading, setBindChannelsLoading] = useState(false);\n const [bindSessionChats, setBindSessionChats] = useState<SessionChatId[]>([]);\n const [bindSessionsLoading, setBindSessionsLoading] = useState(false);\n const [newBindSessionIdx, setNewBindSessionIdx] = useState<number | null>(null);\n const [newBindCustomPeer, setNewBindCustomPeer] = useState('');\n\n const [cronJobs, setCronJobs] = useState<CronJob[]>([]);\n const [cronLoading, setCronLoading] = useState(false);\n\n const [skillCatalog, setSkillCatalog] = useState<SkillCatalogRow[]>([]);\n const [skillsCatalogLoading, setSkillsCatalogLoading] = useState(false);\n\n useEffect(() => {\n if (!data) {\n return;\n }\n if (routeAgentId && data.agents.some((x) => x.id === routeAgentId)) {\n setSelectedId(routeAgentId);\n return;\n }\n setSelectedId((prev) => {\n if (prev && data.agents.some((x) => x.id === prev)) {\n return prev;\n }\n return data.defaultId;\n });\n }, [data, routeAgentId]);\n\n useEffect(() => {\n if (!data || !routeAgentId) {\n return;\n }\n if (!data.agents.some((x) => x.id === routeAgentId)) {\n navigate(AGENTS_APP_LIST_PATH, { replace: true });\n }\n }, [data, routeAgentId, navigate]);\n\n useEffect(() => {\n if (routeAgentId) {\n setPanel('overview');\n }\n }, [routeAgentId]);\n\n useEffect(() => {\n if (searchParams.get('panel') !== 'defaults') {\n return;\n }\n navigate('/settings/agent-defaults', {\n replace: true,\n state: { [SETTINGS_BACK_PATH_STATE_KEY]: AGENTS_APP_LIST_PATH },\n });\n }, [searchParams, navigate]);\n\n const selected = useMemo(\n () => data?.agents.find((x) => x.id === selectedId) ?? null,\n [data, selectedId],\n );\n\n const agentBindings = useMemo(() => {\n if (!selected) {\n return [];\n }\n return allBindings.filter((b) => b.agentId.toLowerCase() === selected.id.toLowerCase());\n }, [allBindings, selected?.id]);\n\n const agentCronJobs = useMemo(() => {\n if (!data || !selected) {\n return [];\n }\n return cronJobs.filter((j) => jobMatchesAgent(j, selected.id, data.defaultId));\n }, [cronJobs, data, selected?.id]);\n\n const catalogForPick = useMemo(\n () => skillCatalog.filter((s) => s.enabled !== false),\n [skillCatalog],\n );\n\n useEffect(() => {\n if (!selected) {\n setEditWorkspace('');\n setEditModel('');\n setEditName('');\n setEditDescription('');\n return;\n }\n setEditWorkspace(selected.workspace);\n setEditModel(selected.model?.primary ?? '');\n setEditName(selected.name?.trim() ? selected.name.trim() : selected.id);\n setEditDescription(selected.description?.trim() ?? '');\n }, [selected?.id]);\n\n useEffect(() => {\n if (panel !== 'files' || !selectedId || !hasToken) {\n return;\n }\n let cancelled = false;\n setFilesLoading(true);\n void fetchAgentBootstrapFiles(selectedId)\n .then((f) => {\n if (!cancelled) {\n setFiles(f);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setFiles(null);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setFilesLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, selectedId, hasToken, data?.agents.length]);\n\n useEffect(() => {\n if (!selected || panel !== 'tools') {\n return;\n }\n setToolEntryDisable(new Set(selected.tools.entryDisable));\n }, [panel, selected]);\n\n useEffect(() => {\n if (!selected || panel !== 'skills') {\n return;\n }\n const inherit = selected.skills.entry === undefined;\n setSkillsInherit(inherit);\n if (inherit) {\n const eff = selected.skills.effectiveAllowlist;\n setSkillsPick(new Set(eff ?? []));\n } else {\n setSkillsPick(new Set(selected.skills.entry ?? []));\n }\n }, [panel, selected]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n setAllBindings(bindingsFromConfig);\n }, [panel, hasToken, bindingsFromConfig]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n let cancelled = false;\n setBindChannelsLoading(true);\n void getChannels()\n .then((list) => {\n if (!cancelled) {\n setBindChannelStatuses(list);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setBindChannelStatuses([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBindChannelsLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (bindChannelsLoading || panel !== 'channels' || bindChannelStatuses.length === 0) {\n return;\n }\n setNewBindChannel((prev) => {\n const valid = Boolean(prev) && bindChannelStatuses.some((c) => c.name === prev);\n if (valid) {\n return prev;\n }\n return bindChannelStatuses[0].name;\n });\n }, [bindChannelsLoading, panel, bindChannelStatuses]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n const ch = newBindChannel.trim();\n if (!ch) {\n setBindSessionChats([]);\n return;\n }\n let cancelled = false;\n setNewBindSessionIdx(null);\n setBindSessionsLoading(true);\n void getSessionChatIds(ch)\n .then((ids) => {\n if (!cancelled) {\n setBindSessionChats(ids);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setBindSessionChats([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBindSessionsLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken, newBindChannel]);\n\n const refreshBindSessions = useCallback(() => {\n const ch = newBindChannel.trim();\n if (!ch) {\n return;\n }\n setBindSessionsLoading(true);\n void getSessionChatIds(ch)\n .then((ids) => {\n setBindSessionChats(ids);\n setNewBindSessionIdx((i) => (i != null && i < ids.length ? i : null));\n })\n .catch(() => {\n setBindSessionChats([]);\n setNewBindSessionIdx(null);\n })\n .finally(() => {\n setBindSessionsLoading(false);\n });\n }, [newBindChannel]);\n\n const useManualChannel = !bindChannelsLoading && bindChannelStatuses.length === 0;\n\n const bindingsLoading = panel === 'channels' && hasToken && gatewayCfgData === undefined;\n\n useEffect(() => {\n if (panel !== 'cron' || !hasToken) {\n return;\n }\n let cancelled = false;\n setCronLoading(true);\n void listJobs()\n .then((j) => {\n if (!cancelled) {\n setCronJobs(j);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setCronJobs([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setCronLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (panel !== 'skills' || !hasToken) {\n return;\n }\n let cancelled = false;\n setSkillsCatalogLoading(true);\n void fetchSkillsCatalog()\n .then((rows) => {\n if (!cancelled) {\n setSkillCatalog(rows);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setSkillCatalog([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setSkillsCatalogLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (!activeFile || !selectedId || !hasToken) {\n return;\n }\n let cancelled = false;\n saveBootstrapDebounced.flush();\n setBootstrapFileLoading(true);\n void fetchAgentBootstrapFileContent(selectedId, activeFile)\n .then((c) => {\n if (cancelled) {\n return;\n }\n const key = `${selectedId}:${activeFile}`;\n bootstrapFileKeyRef.current = key;\n bootstrapSyncedRef.current = c;\n setFileDraft(c);\n setBootstrapEditorNonce((n) => n + 1);\n })\n .catch(() => {\n if (!cancelled) {\n const key = `${selectedId}:${activeFile}`;\n bootstrapFileKeyRef.current = key;\n bootstrapSyncedRef.current = '';\n setFileDraft('');\n setBootstrapEditorNonce((n) => n + 1);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBootstrapFileLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [activeFile, selectedId, hasToken, saveBootstrapDebounced]);\n\n useEffect(() => {\n if (!activeFile || !selectedId || bootstrapFileLoading) {\n return;\n }\n saveBootstrapDebounced();\n }, [fileDraft, activeFile, selectedId, bootstrapFileLoading, saveBootstrapDebounced]);\n\n useEffect(() => {\n if (panel !== 'files') {\n return;\n }\n return () => {\n saveBootstrapDebounced.flush();\n };\n }, [panel, saveBootstrapDebounced]);\n\n useEffect(() => {\n setBootstrapViewMode('edit');\n }, [activeFile, selectedId]);\n\n const applyCreateWorkspaceSuggestion = useCallback(() => {\n const next = suggestWorkspaceFromAgentName(createAgentId.trim() || createDisplayName);\n setCreateWorkspace((prev) => {\n if (prev === '' || prev === createWorkspaceSuggestedRef.current) {\n createWorkspaceSuggestedRef.current = next;\n return next;\n }\n return prev;\n });\n }, [createAgentId, createDisplayName]);\n\n const openAddAgentModal = useCallback(() => {\n createWorkspaceSuggestedRef.current = '';\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n setAddAgentModalOpen(true);\n }, []);\n\n const globalDefaultsTitle = m.settingsSections['agent-defaults'];\n\n const agentsHeaderEnd = useMemo(\n () => (\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center justify-end gap-2\">\n <Button asChild variant=\"secondary\" className=\"shrink-0 gap-2\">\n <Link\n to=\"/settings/agent-defaults\"\n title={globalDefaultsTitle}\n state={{ [SETTINGS_BACK_PATH_STATE_KEY]: AGENTS_APP_LIST_PATH }}\n >\n <SlidersHorizontal className=\"size-4 shrink-0\" strokeWidth={1.75} aria-hidden />\n {globalDefaultsTitle}\n </Link>\n </Button>\n <label className=\"relative flex min-h-9 min-w-0 max-w-sm cursor-text items-center rounded-pill border border-edge bg-surface-base py-1.5 pl-9 pr-3 shadow-surface dark:bg-surface-hover/40 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-disabled\"\n strokeWidth={1.75}\n aria-hidden\n />\n <input\n type=\"search\"\n role=\"searchbox\"\n enterKeyHint=\"search\"\n value={listSearchQuery}\n onChange={(e) => setListSearchQuery(e.target.value)}\n placeholder={a.listSearchPlaceholder}\n autoComplete=\"off\"\n spellCheck={false}\n aria-label={a.listSearchPlaceholder}\n className=\"min-w-0 flex-1 appearance-none border-0 bg-transparent py-0.5 text-sm leading-normal text-fg caret-current placeholder:text-fg-disabled focus:border-0 focus:shadow-none focus:outline-none focus:ring-0 focus-visible:outline-none\"\n />\n </label>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"shrink-0 gap-2\"\n aria-label={a.addAgentAria}\n disabled={busy}\n onClick={() => openAddAgentModal()}\n >\n <Plus className=\"size-4\" strokeWidth={1.75} aria-hidden />\n {a.addAgent}\n </Button>\n </div>\n ),\n [\n a.addAgent,\n a.addAgentAria,\n a.listSearchPlaceholder,\n busy,\n globalDefaultsTitle,\n listSearchQuery,\n openAddAgentModal,\n ],\n );\n\n useLayoutEffect(() => {\n if (!hasToken) {\n clearPageHeader();\n return () => clearPageHeader();\n }\n setPageHeader({\n startExtra: null,\n main: null,\n end: agentsHeaderEnd,\n });\n return () => clearPageHeader();\n }, [agentsHeaderEnd, clearPageHeader, hasToken, setPageHeader]);\n\n async function onCreate(e: FormEvent) {\n e.preventDefault();\n const name = createDisplayName.trim();\n if (!name) {\n return;\n }\n const idRes = validateAgentIdForNewAgent(createAgentId, name);\n if (idRes.ok === false) {\n setCreateModalError(idRes.error);\n return;\n }\n const wsInput = createWorkspace.trim();\n const workspace = wsInput || suggestWorkspaceFromAgentName(createAgentId.trim() || name);\n if (!workspace) {\n return;\n }\n setBusy(true);\n setCreateModalError(null);\n try {\n const desc = createDescription.trim();\n const next = await createGatewayAgent({\n name,\n workspace,\n ...(createAgentId.trim() ? { id: createAgentId.trim() } : {}),\n ...(createModel.trim() ? { model: createModel.trim() } : {}),\n ...(desc ? { description: desc } : {}),\n });\n const { createdAgentId, ...agentsPayload } = next;\n void mutateAgents(agentsPayload, { revalidate: false });\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n setAddAgentModalOpen(false);\n setSelectedId(createdAgentId);\n navigate(agentsAppDetailPath(createdAgentId));\n } catch (err) {\n setCreateModalError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSaveAgentEdits() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const descTrim = editDescription.trim();\n const next = await updateGatewayAgent(selected.id, {\n name: editName.trim() || undefined,\n description: descTrim.length > 0 ? descTrim : null,\n workspace: editWorkspace.trim() || undefined,\n model: editModel.trim() || null,\n });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSetDefault(agent: GatewayAgentRow) {\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(agent.id, { setDefault: true });\n void mutateAgents(next, { revalidate: false });\n setSelectedId(agent.id);\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function performDelete(agent: GatewayAgentRow, purge: boolean) {\n setBusy(true);\n setError(null);\n try {\n const next = await deleteGatewayAgent(agent.id, purge);\n void mutateAgents(next, { revalidate: false });\n setSelectedId(next.defaultId);\n setPanel('overview');\n if (routeAgentId === agent.id) {\n navigate(AGENTS_APP_LIST_PATH, { replace: true });\n }\n setDeleteDialogOpen(false);\n setDeleteTarget(null);\n setDeleteConfirmText('');\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n function onDelete(agent: GatewayAgentRow, purge: boolean) {\n if (agent.id === 'main') {\n return;\n }\n setDeleteTarget(agent);\n setDeletePurge(purge);\n setDeleteConfirmText('');\n setDeleteDialogOpen(true);\n }\n\n async function onSaveTools() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const toolsDisable = [...toolEntryDisable].sort((x, y) => x.localeCompare(y));\n const next = await updateGatewayAgent(selected.id, { toolsDisable });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onClearToolsEntry() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(selected.id, { toolsDisable: null });\n void mutateAgents(next, { revalidate: false });\n setToolEntryDisable(new Set());\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSaveSkills() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(selected.id, {\n skills: skillsInherit ? null : [...skillsPick].sort((x, y) => x.localeCompare(y)),\n });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onRemoveBinding(rule: GatewayConfigBinding) {\n setBusy(true);\n setError(null);\n try {\n const nextList = allBindings.filter((b) => b !== rule);\n await patchGatewayBindings(nextList);\n setAllBindings(nextList);\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onAddBinding(e: FormEvent) {\n e.preventDefault();\n if (!selected || !newBindChannel.trim()) {\n return;\n }\n const match = buildNewBindingMatch(\n newBindChannel,\n newBindCustomPeer,\n newBindSessionIdx,\n bindSessionChats,\n );\n const nextList = [\n ...allBindings,\n {\n agentId: selected.id,\n priority: 100,\n enabled: true,\n match,\n },\n ];\n setBusy(true);\n setError(null);\n try {\n await patchGatewayBindings(nextList);\n setAllBindings(nextList);\n setNewBindSessionIdx(null);\n setNewBindCustomPeer('');\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSetCronJobAgent(job: CronJob, agentKey: string) {\n setBusy(true);\n setError(null);\n try {\n await updateJob(job.id, { agentId: agentKey === '' ? null : agentKey });\n setCronJobs(await listJobs());\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n const footerSaveNotApplicable = panel === 'channels' || panel === 'cron';\n\n // Compute whether overview REST fields have changed compared to the loaded agent\n const overviewRestDirty = (() => {\n if (!selected || panel !== 'overview') return false;\n const origName = selected.name?.trim() || selected.id;\n const origDesc = selected.description?.trim() ?? '';\n const origWorkspace = selected.workspace;\n const origModel = selected.model?.primary ?? '';\n return (\n editName.trim() !== origName ||\n editDescription.trim() !== origDesc ||\n editWorkspace.trim() !== origWorkspace ||\n editModel.trim() !== origModel\n );\n })();\n\n const isCurrentPanelDirty = (() => {\n if (footerSaveNotApplicable) return false;\n switch (panel) {\n case 'overview':\n return overviewRestDirty || overviewBootstrapDirty;\n case 'profile':\n return profileDirty;\n default:\n return true; // tools, skills, files — always allow save\n }\n })();\n\n const footerSaveDisabled = footerSaveNotApplicable || !isCurrentPanelDirty;\n\n function showSavedFlash() {\n setSavedFlash(true);\n setTimeout(() => setSavedFlash(false), 2000);\n }\n\n async function handleModalFooterSave() {\n switch (panel) {\n case 'overview':\n await Promise.all([onSaveAgentEdits(), overviewSaveBootstrapRef.current?.() ?? Promise.resolve()]);\n showSavedFlash();\n break;\n case 'profile':\n await profileSaveRef.current?.();\n showSavedFlash();\n break;\n case 'tools':\n await onSaveTools();\n showSavedFlash();\n break;\n case 'skills':\n await onSaveSkills();\n showSavedFlash();\n break;\n case 'files':\n saveBootstrapDebounced.flush();\n showSavedFlash();\n break;\n default:\n break;\n }\n }\n\n function onAgentModalOpenChange(open: boolean) {\n if (!open) {\n navigate(AGENTS_APP_LIST_PATH);\n }\n }\n\n const modalTitle = selected\n ? editName.trim() || selected.name?.trim() || selected.id\n : (routeAgentId ?? '');\n const modalSubtitle = selected?.id ?? routeAgentId ?? '';\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\">{a.title}</h1>\n <p className=\"text-sm text-fg-muted\">{a.needToken}</p>\n </div>\n );\n }\n\n const editorPanelContent =\n !selected ? (\n <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>\n ) : panel === 'overview' ? (\n <AgentOverviewTab\n a={a}\n chat={chat}\n selected={selected}\n busy={busy}\n editName={editName}\n setEditName={setEditName}\n editDescription={editDescription}\n setEditDescription={setEditDescription}\n editWorkspace={editWorkspace}\n setEditWorkspace={setEditWorkspace}\n editModel={editModel}\n setEditModel={setEditModel}\n onSetDefault={() => void onSetDefault(selected)}\n onSaveAgentEdits={() => void onSaveAgentEdits()}\n onDelete={(purge) => void onDelete(selected, purge)}\n hideInlineSave\n saveBootstrapRef={overviewSaveBootstrapRef}\n onBootstrapDirtyChange={setOverviewBootstrapDirty}\n />\n ) : panel === 'profile' ? (\n <AgentProfileTab a={a} agentId={selected.id} saveRef={profileSaveRef} onDirtyChange={setProfileDirty} />\n ) : panel === 'files' ? (\n <AgentFilesTab\n a={a}\n filesLoading={filesLoading}\n files={files}\n activeFile={activeFile}\n setActiveFile={setActiveFile}\n bootstrapViewMode={bootstrapViewMode}\n setBootstrapViewMode={setBootstrapViewMode}\n fileDraft={fileDraft}\n setFileDraft={setFileDraft}\n fileSaving={fileSaving}\n bootstrapFileLoading={bootstrapFileLoading}\n bootstrapEditorNonce={bootstrapEditorNonce}\n />\n ) : panel === 'tools' ? (\n <AgentToolsTab\n a={a}\n data={data!}\n selected={selected}\n busy={busy}\n toolEntryDisable={toolEntryDisable}\n setToolEntryDisable={setToolEntryDisable}\n onSaveTools={() => void onSaveTools()}\n onClearToolsEntry={() => void onClearToolsEntry()}\n hideInlineSave\n />\n ) : panel === 'skills' ? (\n <AgentSkillsTab\n a={a}\n selected={selected}\n busy={busy}\n skillsCatalogLoading={skillsCatalogLoading}\n catalogForPick={catalogForPick}\n skillsInherit={skillsInherit}\n setSkillsInherit={setSkillsInherit}\n skillsPick={skillsPick}\n setSkillsPick={setSkillsPick}\n onSaveSkills={() => void onSaveSkills()}\n hideInlineSave\n />\n ) : panel === 'channels' ? (\n <AgentChannelsTab\n a={a}\n busy={busy}\n bindingsLoading={bindingsLoading}\n agentBindings={agentBindings}\n channelStatuses={bindChannelStatuses}\n channelsStatusLoading={bindChannelsLoading}\n useManualChannel={useManualChannel}\n newBindChannel={newBindChannel}\n setNewBindChannel={setNewBindChannel}\n bindSessionChats={bindSessionChats}\n sessionsLoading={bindSessionsLoading}\n newBindSessionIdx={newBindSessionIdx}\n setNewBindSessionIdx={setNewBindSessionIdx}\n newBindCustomPeer={newBindCustomPeer}\n setNewBindCustomPeer={setNewBindCustomPeer}\n onRefreshSessions={refreshBindSessions}\n lastActiveLabels={cCron.lastActiveLabels}\n selectRecipient={cCron.selectRecipient}\n onRemoveBinding={(rule) => void onRemoveBinding(rule)}\n onAddBinding={onAddBinding}\n />\n ) : panel === 'cron' && data ? (\n <AgentCronTab\n a={a}\n data={data}\n selected={selected}\n busy={busy}\n cronLoading={cronLoading}\n agentCronJobs={agentCronJobs}\n onSetCronJobAgent={(job, key) => void onSetCronJobAgent(job, key)}\n />\n ) : (\n <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>\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 <AgentsSettingsHeader a={a} />\n\n {displayError ? (\n <div className=\"rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\">\n {displayError}\n </div>\n ) : null}\n\n {loading ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : data ? (\n <AgentsListGrid\n a={a}\n agents={data.agents}\n searchQuery={listSearchQuery}\n onOpenAgent={(id) => navigate(agentsAppDetailPath(id))}\n onChatWithAgent={(id) =>\n navigate('/chat/new', { state: { agentId: id.trim().toLowerCase() } })\n }\n onNewAgent={openAddAgentModal}\n busy={busy}\n />\n ) : null}\n\n {routeAgentId && hasToken ? (\n <AgentsEditorModal\n open={Boolean(routeAgentId)}\n onOpenChange={onAgentModalOpenChange}\n a={a}\n title={modalTitle}\n subtitle={modalSubtitle}\n panel={panel}\n onPanelChange={setPanel}\n onFooterSave={() => void handleModalFooterSave()}\n footerSaveDisabled={footerSaveDisabled}\n footerSavedFlash={savedFlash}\n busy={busy}\n >\n {loading || !data ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : (\n editorPanelContent\n )}\n </AgentsEditorModal>\n ) : null}\n\n <CreateAgentDialog\n open={addAgentModalOpen}\n onOpenChange={(open) => {\n setAddAgentModalOpen(open);\n if (!open) {\n createWorkspaceSuggestedRef.current = '';\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n }\n }}\n a={a}\n chat={chat}\n busy={busy}\n modalError={createModalError}\n createDisplayName={createDisplayName}\n setCreateDisplayName={setCreateDisplayName}\n createAgentId={createAgentId}\n setCreateAgentId={setCreateAgentId}\n createDescription={createDescription}\n setCreateDescription={setCreateDescription}\n createWorkspace={createWorkspace}\n setCreateWorkspace={setCreateWorkspace}\n createModel={createModel}\n setCreateModel={setCreateModel}\n onCreate={onCreate}\n onSuggestWorkspace={() => applyCreateWorkspaceSuggestion()}\n />\n\n <Dialog.Root\n open={deleteDialogOpen}\n onOpenChange={(open) => {\n setDeleteDialogOpen(open);\n if (!open) {\n setDeleteTarget(null);\n setDeleteConfirmText('');\n }\n }}\n >\n <Dialog.Portal>\n <Dialog.Overlay className=\"fixed inset-0 z-[80] bg-scrim backdrop-blur-[2px]\" />\n <Dialog.Content\n className={cn(\n 'fixed left-1/2 top-1/2 z-[81] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-edge bg-surface-panel p-4 shadow-popover',\n 'dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {deletePurge ? a.purgeDisk : a.removeFromConfig}\n </Dialog.Title>\n <Dialog.Description className=\"mt-2 whitespace-pre-wrap text-sm leading-relaxed text-fg-muted\">\n {deletePurge ? a.confirmDeletePurge : a.confirmDelete}\n </Dialog.Description>\n\n {deletePurge && deleteTarget ? (\n <div className=\"mt-3 space-y-3\">\n <label className=\"mb-2 block text-sm font-medium text-fg\" htmlFor=\"agent-delete-confirm\">\n {a.purgeConfirmLabel}\n </label>\n <input\n id=\"agent-delete-confirm\"\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n className={cn(\n 'w-full rounded-md border border-edge bg-surface-panel px-3 py-1.5 font-mono text-xs text-fg',\n 'placeholder:text-fg-subtle',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n 'dark:border-edge',\n )}\n placeholder={a.purgeConfirmPlaceholder.replace('{{agentId}}', deleteTarget.id)}\n value={deleteConfirmText}\n onChange={(e) => setDeleteConfirmText(e.target.value)}\n />\n <p className=\"pt-0.5 text-xs text-fg-muted\">\n {a.purgeConfirmHint.replace('{{agentId}}', deleteTarget.id)}\n </p>\n </div>\n ) : null}\n\n <div className=\"mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-edge-subtle/60 pt-3\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n disabled={busy}\n onClick={() => setDeleteDialogOpen(false)}\n >\n {a.createModalCancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={deletePurge ? 'border-red-200 text-red-700 hover:bg-red-50 dark:border-red-900/60 dark:text-red-300 dark:hover:bg-red-950/40' : undefined}\n disabled={\n busy ||\n !deleteTarget ||\n (deletePurge && deleteConfirmText.trim().toLowerCase() !== deleteTarget.id.toLowerCase())\n }\n onClick={() => {\n if (!deleteTarget) return;\n void performDelete(deleteTarget, deletePurge);\n }}\n >\n {deletePurge ? a.purgeDisk : a.removeFromConfig}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\n// --- Nested shapes (align with `src/config/schema.ts` AgentDefaultsSchema) ---\n\nexport type AgentDefaultsCompactionState = {\n enabled: boolean;\n mode: 'default' | 'safeguard';\n reserveTokens: number;\n triggerThreshold: number;\n minMessagesBeforeCompact: number;\n keepRecentMessages: number;\n evictionWindow: number;\n retentionWindow: number;\n};\n\nexport type AgentDefaultsPruningState = {\n enabled: boolean;\n maxToolResultChars: number;\n headKeepRatio: number;\n tailKeepRatio: number;\n};\n\nexport type AgentDefaultsMemoryState = {\n enabled: boolean;\n useEnhancedSystem: boolean;\n userProfileEnabled: boolean;\n provider: '' | 'none' | 'stub';\n injectionFrequency: '' | 'every-turn' | 'first-turn';\n memoryCharLimit: number | undefined;\n userCharLimit: number | undefined;\n contextCadence: number | undefined;\n dialecticCadence: number | undefined;\n};\n\nexport type AgentDefaultsSessionSearchState = {\n summaryModel: string;\n};\n\nexport type AgentDefaultsBackgroundReviewState = {\n enabled: boolean;\n memoryNudgeInterval: number;\n skillNudgeInterval: number;\n maxToolRounds: number;\n maxHistoryMessages: number;\n maxDurationMs: number;\n};\n\nexport type AgentDefaultsWebExtractState = {\n model: string;\n maxLength: number | undefined;\n};\n\nexport type AgentDefaultsDelegateState = { enabled: boolean };\nexport type AgentDefaultsExecuteCodeState = { enabled: boolean };\n\nexport interface AgentDefaultsState {\n model: string;\n /** provider/model refs tried when the primary fails (stored as `agents.defaults.model.fallbacks`). */\n modelFallbacks: string[];\n imageModel: string;\n imageModelFallbacks: string[];\n imageGenerationModel: string;\n imageGenerationModelFallbacks: string[];\n mediaMaxMb: number | undefined;\n maxTokens: number;\n temperature: number;\n maxToolIterations: number;\n /** Config `maxTaskDurationMs` — UI stores whole minutes (empty = unset / gateway default). */\n maxTaskDurationMinutes: number | undefined;\n maxRequestsPerTurn: number;\n maxToolFailuresPerTurn: number;\n workspace: string;\n /** Playwright `browser_*` tools (`agents.defaults.browser.enabled`). */\n browserEnabled: boolean;\n /** Headless Chromium when browser tools are on (`agents.defaults.browser.headless`, default true). */\n browserHeadless: boolean;\n thinkingDefault: string;\n reasoningDefault: string;\n verboseDefault: string;\n compaction: AgentDefaultsCompactionState;\n pruning: AgentDefaultsPruningState;\n memory: AgentDefaultsMemoryState;\n sessionSearch: AgentDefaultsSessionSearchState;\n backgroundReview: AgentDefaultsBackgroundReviewState;\n webExtract: AgentDefaultsWebExtractState;\n delegate: AgentDefaultsDelegateState;\n executeCode: AgentDefaultsExecuteCodeState;\n systemPromptOverride: string;\n /** Maps to `agents.defaults.skills` (allowlist). */\n skillsAllowlist: string[];\n /** Maps to `agents.defaults.tools.disable`. */\n toolsDisable: string[];\n /** JSON for `agents.defaults.params`. */\n paramsJson: string;\n}\n\nconst DEFAULT_COMPACTION: AgentDefaultsCompactionState = {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n};\n\nconst DEFAULT_PRUNING: AgentDefaultsPruningState = {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n};\n\nconst DEFAULT_MEMORY: AgentDefaultsMemoryState = {\n enabled: true,\n useEnhancedSystem: true,\n userProfileEnabled: true,\n provider: '',\n injectionFrequency: '',\n memoryCharLimit: undefined,\n userCharLimit: undefined,\n contextCadence: undefined,\n dialecticCadence: undefined,\n};\n\nconst DEFAULT_SESSION_SEARCH: AgentDefaultsSessionSearchState = {\n summaryModel: '',\n};\n\nconst DEFAULT_BG_REVIEW: AgentDefaultsBackgroundReviewState = {\n enabled: false,\n memoryNudgeInterval: 10,\n skillNudgeInterval: 10,\n maxToolRounds: 8,\n maxHistoryMessages: 80,\n maxDurationMs: 120_000,\n};\n\nconst DEFAULT_WEB_EXTRACT: AgentDefaultsWebExtractState = {\n model: '',\n maxLength: undefined,\n};\n\nfunction normalizeModelRef(raw: unknown): string {\n if (raw == null) return '';\n if (typeof raw === 'string') return raw;\n if (typeof raw === 'object' && raw !== null && 'primary' in raw) {\n const p = (raw as { primary?: string }).primary;\n return typeof p === 'string' ? p : '';\n }\n return '';\n}\n\nfunction normalizeModelFallbacks(raw: unknown): string[] {\n if (typeof raw !== 'object' || raw === null || !('fallbacks' in raw)) {\n return [];\n }\n const f = (raw as { fallbacks?: unknown }).fallbacks;\n if (!Array.isArray(f)) {\n return [];\n }\n return f.filter((x): x is string => typeof x === 'string' && x.trim().length > 0);\n}\n\nfunction configFromApiResponse(res: unknown): unknown {\n if (!res || typeof res !== 'object') return undefined;\n const r = res as Record<string, unknown>;\n const payload = r.payload;\n if (payload && typeof payload === 'object' && 'config' in payload) {\n return (payload as { config?: unknown }).config;\n }\n if ('config' in r) return r.config;\n return undefined;\n}\n\nfunction truthyBrowserFlag(v: unknown): boolean {\n return v === true || v === 'true' || v === 1;\n}\n\nfunction parseBrowserFromDefaults(d: Record<string, unknown>): Pick<AgentDefaultsState, 'browserEnabled' | 'browserHeadless'> {\n const browser = d.browser;\n if (!browser || typeof browser !== 'object' || Array.isArray(browser)) {\n return { browserEnabled: false, browserHeadless: true };\n }\n const b = browser as Record<string, unknown>;\n const enabled = truthyBrowserFlag(b.enabled);\n const headlessRaw = b.headless;\n const headless =\n headlessRaw === false || headlessRaw === 'false' || headlessRaw === 0 ? false : true;\n return { browserEnabled: enabled, browserHeadless: headless };\n}\n\nfunction parseCompaction(raw: unknown): AgentDefaultsCompactionState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_COMPACTION };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_COMPACTION.enabled,\n mode: p.mode === 'safeguard' ? 'safeguard' : 'default',\n reserveTokens:\n typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)\n ? Math.floor(p.reserveTokens)\n : DEFAULT_COMPACTION.reserveTokens,\n triggerThreshold:\n typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)\n ? p.triggerThreshold\n : DEFAULT_COMPACTION.triggerThreshold,\n minMessagesBeforeCompact:\n typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)\n ? Math.floor(p.minMessagesBeforeCompact)\n : DEFAULT_COMPACTION.minMessagesBeforeCompact,\n keepRecentMessages:\n typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)\n ? Math.floor(p.keepRecentMessages)\n : DEFAULT_COMPACTION.keepRecentMessages,\n evictionWindow:\n typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)\n ? p.evictionWindow\n : DEFAULT_COMPACTION.evictionWindow,\n retentionWindow:\n typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)\n ? Math.floor(p.retentionWindow)\n : DEFAULT_COMPACTION.retentionWindow,\n };\n}\n\nfunction parsePruning(raw: unknown): AgentDefaultsPruningState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_PRUNING };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_PRUNING.enabled,\n maxToolResultChars:\n typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)\n ? Math.floor(p.maxToolResultChars)\n : DEFAULT_PRUNING.maxToolResultChars,\n headKeepRatio:\n typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)\n ? p.headKeepRatio\n : DEFAULT_PRUNING.headKeepRatio,\n tailKeepRatio:\n typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)\n ? p.tailKeepRatio\n : DEFAULT_PRUNING.tailKeepRatio,\n };\n}\n\nfunction parseMemory(raw: unknown): AgentDefaultsMemoryState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_MEMORY };\n }\n const p = raw as Record<string, unknown>;\n const providerRaw = p.provider;\n const provider: AgentDefaultsMemoryState['provider'] =\n providerRaw === 'none' || providerRaw === 'stub' ? providerRaw : '';\n const inj = p.injectionFrequency;\n const injectionFrequency: AgentDefaultsMemoryState['injectionFrequency'] =\n inj === 'every-turn' || inj === 'first-turn' ? inj : '';\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_MEMORY.enabled,\n useEnhancedSystem:\n typeof p.useEnhancedSystem === 'boolean' ? p.useEnhancedSystem : DEFAULT_MEMORY.useEnhancedSystem,\n userProfileEnabled:\n typeof p.userProfileEnabled === 'boolean' ? p.userProfileEnabled : DEFAULT_MEMORY.userProfileEnabled,\n provider,\n injectionFrequency,\n memoryCharLimit:\n typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0\n ? Math.floor(p.memoryCharLimit)\n : undefined,\n userCharLimit:\n typeof p.userCharLimit === 'number' && p.userCharLimit > 0\n ? Math.floor(p.userCharLimit)\n : undefined,\n contextCadence:\n typeof p.contextCadence === 'number' && p.contextCadence >= 1\n ? Math.floor(p.contextCadence)\n : undefined,\n dialecticCadence:\n typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1\n ? Math.floor(p.dialecticCadence)\n : undefined,\n };\n}\n\nfunction parseSessionSearch(raw: unknown): AgentDefaultsSessionSearchState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_SESSION_SEARCH };\n }\n const p = raw as Record<string, unknown>;\n return {\n summaryModel: typeof p.summaryModel === 'string' ? p.summaryModel : '',\n };\n}\n\nfunction parseBackgroundReview(raw: unknown): AgentDefaultsBackgroundReviewState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_BG_REVIEW };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_BG_REVIEW.enabled,\n memoryNudgeInterval:\n typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0\n ? Math.floor(p.memoryNudgeInterval)\n : DEFAULT_BG_REVIEW.memoryNudgeInterval,\n skillNudgeInterval:\n typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0\n ? Math.floor(p.skillNudgeInterval)\n : DEFAULT_BG_REVIEW.skillNudgeInterval,\n maxToolRounds:\n typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32\n ? Math.floor(p.maxToolRounds)\n : DEFAULT_BG_REVIEW.maxToolRounds,\n maxHistoryMessages:\n typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200\n ? Math.floor(p.maxHistoryMessages)\n : DEFAULT_BG_REVIEW.maxHistoryMessages,\n maxDurationMs:\n typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000\n ? Math.floor(p.maxDurationMs)\n : DEFAULT_BG_REVIEW.maxDurationMs,\n };\n}\n\nfunction parseWebExtract(raw: unknown): AgentDefaultsWebExtractState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_WEB_EXTRACT };\n }\n const p = raw as Record<string, unknown>;\n return {\n model: typeof p.model === 'string' ? p.model : '',\n maxLength:\n typeof p.maxLength === 'number' && p.maxLength > 0 ? p.maxLength : undefined,\n };\n}\n\nfunction parseEnabledFlag(raw: unknown, def: boolean): { enabled: boolean } {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { enabled: def };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : def,\n };\n}\n\nfunction parseStringList(raw: unknown): string[] {\n if (!Array.isArray(raw)) {\n return [];\n }\n return raw.filter((x): x is string => typeof x === 'string');\n}\n\nfunction parseParamsJson(raw: unknown): string {\n if (raw === undefined || raw === null) {\n return '';\n }\n if (typeof raw === 'object' && !Array.isArray(raw)) {\n try {\n return JSON.stringify(raw, null, 2);\n } catch {\n return '';\n }\n }\n return '';\n}\n\n/** Parse `agents.defaults` from a gateway config root object. */\nexport function parseAgentDefaultsFromConfig(cfg: unknown): AgentDefaultsState {\n const agents =\n cfg && typeof cfg === 'object' && !Array.isArray(cfg) && 'agents' in cfg\n ? (cfg as { agents?: unknown }).agents\n : undefined;\n const defaults =\n agents && typeof agents === 'object' && !Array.isArray(agents) && 'defaults' in agents\n ? (agents as { defaults?: unknown }).defaults\n : undefined;\n const d =\n defaults && typeof defaults === 'object' && !Array.isArray(defaults)\n ? (defaults as Record<string, unknown>)\n : {};\n const mf = d.modelFallbacks;\n const modelFallbacksFromApi =\n Array.isArray(mf) && mf.every((x) => typeof x === 'string') ? mf : normalizeModelFallbacks(d.model);\n const imf = d.imageModelFallbacks;\n const imageModelFallbacksFromApi =\n Array.isArray(imf) && imf.every((x) => typeof x === 'string')\n ? imf\n : normalizeModelFallbacks(d.imageModel);\n const igf = d.imageGenerationModelFallbacks;\n const imageGenerationModelFallbacksFromApi =\n Array.isArray(igf) && igf.every((x) => typeof x === 'string')\n ? igf\n : normalizeModelFallbacks(d.imageGenerationModel);\n const { browserEnabled, browserHeadless } = parseBrowserFromDefaults(d);\n const maxTaskMs =\n typeof d.maxTaskDurationMs === 'number' && Number.isFinite(d.maxTaskDurationMs)\n ? d.maxTaskDurationMs\n : undefined;\n const maxTaskDurationMinutes =\n maxTaskMs !== undefined ? Math.round(maxTaskMs / 60_000) : undefined;\n\n return {\n model: normalizeModelRef(d.model),\n modelFallbacks: modelFallbacksFromApi,\n imageModel: normalizeModelRef(d.imageModel),\n imageModelFallbacks: imageModelFallbacksFromApi,\n imageGenerationModel: normalizeModelRef(d.imageGenerationModel),\n imageGenerationModelFallbacks: imageGenerationModelFallbacksFromApi,\n mediaMaxMb: typeof d.mediaMaxMb === 'number' && !Number.isNaN(d.mediaMaxMb) ? d.mediaMaxMb : undefined,\n maxTokens: typeof d.maxTokens === 'number' ? d.maxTokens : 8192,\n temperature: typeof d.temperature === 'number' ? d.temperature : 0.7,\n maxToolIterations: typeof d.maxToolIterations === 'number' ? d.maxToolIterations : 20,\n maxTaskDurationMinutes,\n maxRequestsPerTurn: typeof d.maxRequestsPerTurn === 'number' ? d.maxRequestsPerTurn : 50,\n maxToolFailuresPerTurn: typeof d.maxToolFailuresPerTurn === 'number' ? d.maxToolFailuresPerTurn : 3,\n workspace: typeof d.workspace === 'string' ? d.workspace : '~/.xopc/workspace',\n browserEnabled,\n browserHeadless,\n thinkingDefault: typeof d.thinkingDefault === 'string' ? d.thinkingDefault : 'medium',\n reasoningDefault: typeof d.reasoningDefault === 'string' ? d.reasoningDefault : 'off',\n verboseDefault: typeof d.verboseDefault === 'string' ? d.verboseDefault : 'off',\n compaction: parseCompaction(d.compaction),\n pruning: parsePruning(d.pruning),\n memory: parseMemory(d.memory),\n sessionSearch: parseSessionSearch(d.sessionSearch),\n backgroundReview: parseBackgroundReview(d.backgroundReview),\n webExtract: parseWebExtract(d.webExtract),\n delegate: parseEnabledFlag(d.delegate, false),\n executeCode: parseEnabledFlag(d.executeCode, false),\n systemPromptOverride: typeof d.systemPromptOverride === 'string' ? d.systemPromptOverride : '',\n skillsAllowlist: parseStringList(d.skills),\n toolsDisable: (() => {\n const t = d.tools;\n if (!t || typeof t !== 'object' || Array.isArray(t)) {\n return [] as string[];\n }\n const dis = (t as { disable?: unknown }).disable;\n return parseStringList(dis);\n })(),\n paramsJson: parseParamsJson(d.params),\n };\n}\n\nfunction buildMemoryPatch(m: AgentDefaultsMemoryState): Record<string, unknown> {\n const o: Record<string, unknown> = {\n enabled: m.enabled,\n useEnhancedSystem: m.useEnhancedSystem,\n userProfileEnabled: m.userProfileEnabled,\n };\n if (m.provider === 'none' || m.provider === 'stub') {\n o.provider = m.provider;\n } else {\n o.provider = null;\n }\n if (m.injectionFrequency === 'every-turn' || m.injectionFrequency === 'first-turn') {\n o.injectionFrequency = m.injectionFrequency;\n } else {\n o.injectionFrequency = null;\n }\n o.memoryCharLimit = m.memoryCharLimit ?? null;\n o.userCharLimit = m.userCharLimit ?? null;\n o.contextCadence = m.contextCadence ?? null;\n o.dialecticCadence = m.dialecticCadence ?? null;\n return o;\n}\n\n/** @throws {SyntaxError} on invalid JSON; {Error} if not a plain object. */\nexport function parseParamsJsonForSave(paramsJson: string): Record<string, unknown> | null {\n const trimmed = paramsJson.trim();\n if (!trimmed) {\n return null;\n }\n const parsed: unknown = JSON.parse(trimmed);\n if (parsed === null) {\n return null;\n }\n if (typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('params must be a JSON object');\n }\n return parsed as Record<string, unknown>;\n}\n\nexport async function fetchAgentDefaults(): Promise<AgentDefaultsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n const cfg = configFromApiResponse(res);\n return parseAgentDefaultsFromConfig(cfg ?? {});\n}\n\nexport async function patchAgentDefaults(state: AgentDefaultsState): Promise<void> {\n const fallbacks = state.modelFallbacks.map((s) => s.trim()).filter(Boolean);\n const modelField =\n fallbacks.length > 0 ? { primary: state.model, fallbacks } : state.model;\n\n const imageFbs = state.imageModelFallbacks.map((s) => s.trim()).filter(Boolean);\n const imageModelField =\n imageFbs.length > 0 && state.imageModel.trim()\n ? { primary: state.imageModel.trim(), fallbacks: imageFbs }\n : state.imageModel || '';\n\n const imageGenFbs = state.imageGenerationModelFallbacks.map((s) => s.trim()).filter(Boolean);\n const imageGenerationModelField =\n imageGenFbs.length > 0 && state.imageGenerationModel.trim()\n ? { primary: state.imageGenerationModel.trim(), fallbacks: imageGenFbs }\n : state.imageGenerationModel || '';\n\n const maxTaskDurationMs: number | null =\n state.maxTaskDurationMinutes === undefined || state.maxTaskDurationMinutes === null\n ? null\n : (() => {\n const n = Math.floor(state.maxTaskDurationMinutes);\n const ms = n * 60_000;\n if (ms < 60_000 || ms > 14_400_000) {\n return null;\n }\n return ms;\n })();\n\n const skillsClean = state.skillsAllowlist.map((s) => s.trim()).filter(Boolean);\n const toolsDisableClean = state.toolsDisable.map((s) => s.trim()).filter(Boolean);\n\n const paramsParsed = parseParamsJsonForSave(state.paramsJson);\n const params =\n paramsParsed === null || Object.keys(paramsParsed).length === 0 ? null : paramsParsed;\n\n const defaults: Record<string, unknown> = {\n model: modelField,\n imageModel: imageModelField,\n imageGenerationModel: imageGenerationModelField,\n mediaMaxMb: state.mediaMaxMb ?? null,\n maxTokens: state.maxTokens,\n temperature: state.temperature,\n maxToolIterations: state.maxToolIterations,\n maxTaskDurationMs,\n maxRequestsPerTurn: state.maxRequestsPerTurn,\n maxToolFailuresPerTurn: state.maxToolFailuresPerTurn,\n workspace: state.workspace,\n browser: {\n enabled: state.browserEnabled,\n headless: state.browserHeadless,\n },\n thinkingDefault: state.thinkingDefault,\n reasoningDefault: state.reasoningDefault,\n verboseDefault: state.verboseDefault,\n compaction: { ...state.compaction },\n pruning: { ...state.pruning },\n memory: buildMemoryPatch(state.memory),\n sessionSearch: {\n summaryModel: state.sessionSearch.summaryModel.trim() || null,\n },\n backgroundReview: {\n enabled: state.backgroundReview.enabled,\n memoryNudgeInterval: state.backgroundReview.memoryNudgeInterval,\n skillNudgeInterval: state.backgroundReview.skillNudgeInterval,\n maxToolRounds: state.backgroundReview.maxToolRounds,\n maxHistoryMessages: state.backgroundReview.maxHistoryMessages,\n maxDurationMs: state.backgroundReview.maxDurationMs,\n },\n webExtract: {\n model: state.webExtract.model.trim() || null,\n maxLength: state.webExtract.maxLength ?? null,\n },\n delegate: { enabled: state.delegate.enabled },\n executeCode: { enabled: state.executeCode.enabled },\n systemPromptOverride: state.systemPromptOverride.trim() || null,\n skills: skillsClean.length > 0 ? skillsClean : null,\n tools: { disable: toolsDisableClean.length > 0 ? toolsDisableClean : null },\n params,\n };\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n agents: { defaults },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\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","import { Brain, Clock, Code2, FileText, Layers2, Library, Scissors, Search, Sparkles, Timer, Wrench } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport type { AgentDefaultsState } from '@/features/settings/config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { MessageBundle } from '@/i18n/messages';\n\nimport { inputClassName, selectClassName } from './defaults-field-styles';\n\ntype A = MessageBundle['agentSettings'];\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\nexport function AgentDefaultsExtraFields(props: {\n a: A;\n chat: MessageBundle['chat'];\n form: AgentDefaultsState;\n update: (patch: Partial<AgentDefaultsState>) => void;\n}) {\n const { a, chat, form, update } = props;\n const x = a.advanced;\n\n return (\n <>\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Timer} title={x.cardLimitsTitle} subtitle={x.cardLimitsSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.maxTaskDurationMs} description={x.maxTaskDurationMsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={240}\n step={1}\n value={form.maxTaskDurationMinutes ?? ''}\n placeholder={x.maxTaskDurationPlaceholder}\n onChange={(e) => {\n const v = e.target.value;\n if (v === '') {\n update({ maxTaskDurationMinutes: undefined });\n return;\n }\n const n = Number.parseInt(v, 10);\n if (Number.isNaN(n)) {\n return;\n }\n update({ maxTaskDurationMinutes: Math.min(240, Math.max(1, n)) });\n }}\n />\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.maxRequestsPerTurn} description={x.maxRequestsPerTurnDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={10}\n max={200}\n value={form.maxRequestsPerTurn}\n onChange={(e) => update({ maxRequestsPerTurn: Number.parseInt(e.target.value, 10) || 50 })}\n />\n </Field>\n <Field label={x.maxToolFailuresPerTurn} description={x.maxToolFailuresPerTurnDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={20}\n value={form.maxToolFailuresPerTurn}\n onChange={(e) => update({ maxToolFailuresPerTurn: Number.parseInt(e.target.value, 10) || 3 })}\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Layers2} title={x.cardCompactionTitle} subtitle={x.cardCompactionSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.compactionEnabled} description={x.compactionEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.compaction.enabled}\n onChange={(e) =>\n update({ compaction: { ...form.compaction, enabled: e.target.checked } })\n }\n />\n <span>{x.compactionEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.compactionMode} description={x.compactionModeDesc}>\n <select\n className={selectClassName()}\n value={form.compaction.mode}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n mode: e.target.value as AgentDefaultsState['compaction']['mode'],\n },\n })\n }\n >\n <option value=\"default\">{x.compactionModeDefault}</option>\n <option value=\"safeguard\">{x.compactionModeSafeguard}</option>\n </select>\n </Field>\n <Field label={x.reserveTokens} description={x.reserveTokensDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1000}\n value={form.compaction.reserveTokens}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n reserveTokens: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.triggerThreshold} description={x.triggerThresholdDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0.5}\n max={0.95}\n step={0.05}\n value={form.compaction.triggerThreshold}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n triggerThreshold: Number.parseFloat(e.target.value) || 0.8,\n },\n })\n }\n />\n </Field>\n <Field label={x.minMessagesBeforeCompact} description={x.minMessagesBeforeCompactDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.compaction.minMessagesBeforeCompact}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n minMessagesBeforeCompact: Number.parseInt(e.target.value, 10) || 10,\n },\n })\n }\n />\n </Field>\n <Field label={x.keepRecentMessages} description={x.keepRecentMessagesDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.compaction.keepRecentMessages}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n keepRecentMessages: Number.parseInt(e.target.value, 10) || 5,\n },\n })\n }\n />\n </Field>\n <Field label={x.evictionWindow} description={x.evictionWindowDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0.1}\n max={0.5}\n step={0.05}\n value={form.compaction.evictionWindow}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n evictionWindow: Number.parseFloat(e.target.value) || 0.2,\n },\n })\n }\n />\n </Field>\n <Field label={x.retentionWindow} description={x.retentionWindowDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={3}\n max={20}\n value={form.compaction.retentionWindow}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n retentionWindow: Number.parseInt(e.target.value, 10) || 6,\n },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Scissors} title={x.cardPruningTitle} subtitle={x.cardPruningSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.pruningEnabled} description={x.pruningEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.pruning.enabled}\n onChange={(e) => update({ pruning: { ...form.pruning, enabled: e.target.checked } })}\n />\n <span>{x.pruningEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.maxToolResultChars} description={x.maxToolResultCharsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1000}\n value={form.pruning.maxToolResultChars}\n onChange={(e) =>\n update({\n pruning: {\n ...form.pruning,\n maxToolResultChars: Number.parseInt(e.target.value, 10) || 10000,\n },\n })\n }\n />\n </Field>\n <Field label={x.headKeepRatio} description={x.headKeepRatioDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n max={1}\n step={0.05}\n value={form.pruning.headKeepRatio}\n onChange={(e) =>\n update({\n pruning: { ...form.pruning, headKeepRatio: Number.parseFloat(e.target.value) || 0.3 },\n })\n }\n />\n </Field>\n <Field label={x.tailKeepRatio} description={x.tailKeepRatioDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n max={1}\n step={0.05}\n value={form.pruning.tailKeepRatio}\n onChange={(e) =>\n update({\n pruning: { ...form.pruning, tailKeepRatio: Number.parseFloat(e.target.value) || 0.3 },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Brain} title={x.cardMemoryTitle} subtitle={x.cardMemorySubtitle} />\n <div className=\"flex flex-col gap-5\">\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.memoryEnabled} description={x.memoryEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.enabled}\n onChange={(e) => update({ memory: { ...form.memory, enabled: e.target.checked } })}\n />\n <span>{x.memoryEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.useEnhancedSystem} description={x.useEnhancedSystemDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.useEnhancedSystem}\n onChange={(e) =>\n update({ memory: { ...form.memory, useEnhancedSystem: e.target.checked } })\n }\n />\n <span>{x.useEnhancedSystemOn}</span>\n </label>\n </Field>\n <Field label={x.userProfileEnabled} description={x.userProfileEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.userProfileEnabled}\n onChange={(e) =>\n update({ memory: { ...form.memory, userProfileEnabled: e.target.checked } })\n }\n />\n <span>{x.userProfileEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.memoryProvider} description={x.memoryProviderDesc}>\n <select\n className={selectClassName()}\n value={form.memory.provider}\n onChange={(e) =>\n update({\n memory: {\n ...form.memory,\n provider: e.target.value as AgentDefaultsState['memory']['provider'],\n },\n })\n }\n >\n <option value=\"\">{x.memoryProviderUnset}</option>\n <option value=\"none\">none</option>\n <option value=\"stub\">stub</option>\n </select>\n </Field>\n <Field label={x.injectionFrequency} description={x.injectionFrequencyDesc}>\n <select\n className={selectClassName()}\n value={form.memory.injectionFrequency}\n onChange={(e) =>\n update({\n memory: {\n ...form.memory,\n injectionFrequency: e.target.value as AgentDefaultsState['memory']['injectionFrequency'],\n },\n })\n }\n >\n <option value=\"\">{x.injectionFrequencyUnset}</option>\n <option value=\"every-turn\">{x.injectionEveryTurn}</option>\n <option value=\"first-turn\">{x.injectionFirstTurn}</option>\n </select>\n </Field>\n <Field label={x.memoryCharLimit} description={x.memoryCharLimitDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.memoryCharLimit ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n memoryCharLimit: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.userCharLimit} description={x.userCharLimitDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.userCharLimit ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n userCharLimit: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.contextCadence} description={x.contextCadenceDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.contextCadence ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n contextCadence: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.dialecticCadence} description={x.dialecticCadenceDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.dialecticCadence ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n dialecticCadence: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={x.cardSessionSearchTitle} subtitle={x.cardSessionSearchSubtitle} />\n <Field label={x.sessionSearchSummaryModel} description={x.sessionSearchSummaryModelDesc}>\n <ModelSelector\n value={form.sessionSearch.summaryModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) =>\n update({ sessionSearch: { ...form.sessionSearch, summaryModel: modelId } })\n }\n />\n </Field>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Sparkles} title={x.cardReviewTitle} subtitle={x.cardReviewSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.reviewEnabled} description={x.reviewEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.backgroundReview.enabled}\n onChange={(e) =>\n update({ backgroundReview: { ...form.backgroundReview, enabled: e.target.checked } })\n }\n />\n <span>{x.reviewEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.memoryNudgeInterval} description={x.memoryNudgeIntervalDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.backgroundReview.memoryNudgeInterval}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n memoryNudgeInterval: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.skillNudgeInterval} description={x.skillNudgeIntervalDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.backgroundReview.skillNudgeInterval}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n skillNudgeInterval: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxToolRounds} description={x.reviewMaxToolRoundsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={32}\n value={form.backgroundReview.maxToolRounds}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxToolRounds: Number.parseInt(e.target.value, 10) || 8,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxHistoryMessages} description={x.reviewMaxHistoryMessagesDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={10}\n max={200}\n value={form.backgroundReview.maxHistoryMessages}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxHistoryMessages: Number.parseInt(e.target.value, 10) || 80,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxDurationMs} description={x.reviewMaxDurationMsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={30}\n max={600}\n step={1}\n value={Math.round((form.backgroundReview.maxDurationMs ?? 120_000) / 1000)}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxDurationMs: (Number.parseInt(e.target.value, 10) || 120) * 1000,\n },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={FileText}\n title={x.cardWebExtractTitle}\n subtitle={x.cardWebExtractSubtitle}\n />\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <div className=\"sm:col-span-2\">\n <Field label={x.webExtractModel} description={x.webExtractModelDesc}>\n <ModelSelector\n value={form.webExtract.model}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => update({ webExtract: { ...form.webExtract, model: modelId } })}\n />\n </Field>\n </div>\n <Field label={x.webExtractMaxLength} description={x.webExtractMaxLengthDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.webExtract.maxLength ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n webExtract: {\n ...form.webExtract,\n maxLength: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Code2} title={x.cardDelegateTitle} subtitle={x.cardDelegateSubtitle} />\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.delegateEnabled} description={x.delegateEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.delegate.enabled}\n onChange={(e) => update({ delegate: { ...form.delegate, enabled: e.target.checked } })}\n />\n <span>{x.delegateEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.executeCodeEnabled} description={x.executeCodeEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.executeCode.enabled}\n onChange={(e) =>\n update({ executeCode: { ...form.executeCode, enabled: e.target.checked } })\n }\n />\n <span>{x.executeCodeEnabledOn}</span>\n </label>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Library}\n title={x.cardPromptSkillsTitle}\n subtitle={x.cardPromptSkillsSubtitle}\n />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.systemPromptOverride} description={x.systemPromptOverrideDesc}>\n <textarea\n className={cn(inputClassName(), 'min-h-[100px] resize-y font-mono text-xs')}\n value={form.systemPromptOverride}\n placeholder={x.systemPromptPlaceholder}\n onChange={(e) => update({ systemPromptOverride: e.target.value })}\n />\n </Field>\n <Field label={x.skillsAllowlist} description={x.skillsAllowlistDesc}>\n <div className=\"flex flex-col gap-2\">\n {form.skillsAllowlist.map((s, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n value={s}\n onChange={(e) => {\n const next = [...form.skillsAllowlist];\n next[idx] = e.target.value;\n update({ skillsAllowlist: next });\n }}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={x.removeListItem}\n onClick={() =>\n update({ skillsAllowlist: form.skillsAllowlist.filter((_, j) => j !== idx) })\n }\n >\n ×\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit\"\n onClick={() => update({ skillsAllowlist: [...form.skillsAllowlist, ''] })}\n >\n {x.addSkillName}\n </Button>\n </div>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Wrench} title={x.cardToolsDisableTitle} subtitle={x.cardToolsDisableSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <p className=\"text-xs text-fg-muted\">{x.toolsDisableHint}</p>\n <div className=\"flex flex-col gap-2\">\n {form.toolsDisable.map((s, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n value={s}\n placeholder=\"shell\"\n onChange={(e) => {\n const next = [...form.toolsDisable];\n next[idx] = e.target.value;\n update({ toolsDisable: next });\n }}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={x.removeListItem}\n onClick={() => update({ toolsDisable: form.toolsDisable.filter((_, j) => j !== idx) })}\n >\n ×\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit\"\n onClick={() => update({ toolsDisable: [...form.toolsDisable, ''] })}\n >\n {x.addToolName}\n </Button>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Clock} title={x.cardParamsTitle} subtitle={x.cardParamsSubtitle} />\n <Field label={x.paramsJson} description={x.paramsJsonDesc}>\n <textarea\n className={cn(inputClassName(), 'min-h-[88px] resize-y font-mono text-xs')}\n value={form.paramsJson}\n placeholder=\"{}\"\n onChange={(e) => update({ paramsJson: e.target.value })}\n />\n </Field>\n </SettingsFormSection>\n </>\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 = { id: string; defaultModel?: string; models: string[] };\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 buildModelIds(providers: ImageProviderSummary[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const p of providers) {\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\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 className,\n onChange,\n}: {\n value: string;\n disabled?: boolean;\n placeholder: string;\n searchPlaceholder: string;\n noMatches: 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 allIds = useMemo(() => buildModelIds(providers ?? []), [providers]);\n const filtered = useMemo(() => idsMatchingQuery(allIds, query), [allIds, query]);\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 <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\">{noMatches}</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 );\n}\n","import { Cpu, Folder, Globe, Layers, Plus, Trash2, Zap } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n parseAgentDefaultsFromConfig,\n parseParamsJsonForSave,\n patchAgentDefaults,\n type AgentDefaultsState,\n} from '@/features/settings/config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport { AgentDefaultsExtraFields } from './agent-defaults-extra';\nimport { ImageGenerationModelInput } from './image-generation-model-input';\nimport { inputClassName, selectClassName } from './defaults-field-styles';\n\nconst THINKING_KEYS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive'] as const;\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\nexport function AgentSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.agentSettings;\n const chat = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<AgentDefaultsState | null>(null);\n const [baseline, setBaseline] = useState<AgentDefaultsState | 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 ? parseAgentDefaultsFromConfig(data.payload.config) : 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<AgentDefaultsState>) => {\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 try {\n void parseParamsJsonForSave(form.paramsJson);\n } catch (e) {\n setError(\n e instanceof SyntaxError\n ? a.advanced.paramsInvalidJson\n : e instanceof Error\n ? e.message\n : a.advanced.paramsInvalidJson,\n );\n return;\n }\n await patchAgentDefaults(form);\n dirtyRef.current = false;\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : a.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, a.saveError, a.advanced]);\n\n const pageTitle = m.settingsSections['agent-defaults'];\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 <Cpu 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\">{pageTitle}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{a.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 (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <p className=\"text-sm text-fg-muted\">\n {error ?? fetchError ?? a.loadError}\n </p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\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-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\">{pageTitle}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{a.subtitle}</p>\n <p className=\"mt-1 text-xs text-fg-subtle\">{a.sectionDesc}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{a.saved}</span> : null}\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? a.saving : a.save}\n </Button>\n </div>\n </header>\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 <div className=\"flex flex-col gap-5\">\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cpu} title={a.cardModelsTitle} subtitle={a.cardModelsSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.model} description={a.desc.model}>\n <ModelSelector\n value={form.model}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => update({ model: modelId })}\n />\n </Field>\n <Field label={a.label.modelFallbacks} description={a.desc.modelFallbacks}>\n <div className=\"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 </Field>\n <Field 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 onChange={(modelId) => update({ imageModel: modelId })}\n />\n </Field>\n <Field 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 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 </Field>\n <Field 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 onChange={(modelId) => update({ imageGenerationModel: modelId })}\n />\n </Field>\n <Field\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 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 </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Folder} title={a.cardWorkspaceTitle} subtitle={a.cardWorkspaceSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.workspace} description={a.desc.workspace}>\n <input\n type=\"text\"\n className={inputClassName()}\n value={form.workspace}\n onChange={(e) => update({ workspace: e.target.value })}\n autoComplete=\"off\"\n />\n </Field>\n <Field label={a.label.mediaMaxMb} description={a.desc.mediaMaxMb}>\n <input\n type=\"number\"\n min={1}\n step={1}\n className={inputClassName()}\n value={form.mediaMaxMb ?? ''}\n placeholder=\"20\"\n onChange={(e) => {\n const v = e.target.value;\n update({ mediaMaxMb: v === '' ? undefined : Number(v) });\n }}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Globe} title={a.cardBrowserTitle} subtitle={a.cardBrowserSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.browserEnabled} description={a.desc.browserEnabled}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.browserEnabled}\n onChange={(e) => update({ browserEnabled: e.target.checked })}\n />\n <span>{a.browserEnabledOn}</span>\n </label>\n </Field>\n <Field label={a.label.browserHeadless} description={a.desc.browserHeadless}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.browserHeadless}\n onChange={(e) => update({ browserHeadless: e.target.checked })}\n />\n <span>{a.browserHeadlessOn}</span>\n </label>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Layers} title={a.cardGenerationTitle} subtitle={a.cardGenerationSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={a.label.maxTokens} description={a.desc.maxTokens}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.maxTokens}\n min={1}\n onChange={(e) => update({ maxTokens: Number.parseInt(e.target.value, 10) || 0 })}\n />\n </Field>\n <Field label={a.label.temperature} description={a.desc.temperature}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.temperature}\n min={0}\n max={2}\n step={0.1}\n onChange={(e) => update({ temperature: Number.parseFloat(e.target.value) || 0 })}\n />\n </Field>\n </div>\n <Field label={a.label.maxToolIterations} description={a.desc.maxToolIterations}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.maxToolIterations}\n min={1}\n onChange={(e) => update({ maxToolIterations: Number.parseInt(e.target.value, 10) || 0 })}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Zap} title={a.cardBehaviorTitle} subtitle={a.cardBehaviorSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.thinkingDefault} description={a.desc.thinkingDefault}>\n <select\n className={selectClassName()}\n value={form.thinkingDefault}\n onChange={(e) => update({ thinkingDefault: e.target.value })}\n >\n {THINKING_KEYS.map((k) => (\n <option key={k} value={k}>\n {chat.thinkingLevels[k]}\n </option>\n ))}\n </select>\n </Field>\n <Field label={a.label.reasoningDefault} description={a.desc.reasoningDefault}>\n <select\n className={selectClassName()}\n value={form.reasoningDefault}\n onChange={(e) => update({ reasoningDefault: e.target.value })}\n >\n <option value=\"off\">{a.reasoning.off}</option>\n <option value=\"on\">{a.reasoning.on}</option>\n <option value=\"stream\">{a.reasoning.stream}</option>\n </select>\n </Field>\n <Field label={a.label.verboseDefault} description={a.desc.verboseDefault}>\n <select\n className={selectClassName()}\n value={form.verboseDefault}\n onChange={(e) => update({ verboseDefault: e.target.value })}\n >\n <option value=\"off\">{a.verbose.off}</option>\n <option value=\"on\">{a.verbose.on}</option>\n <option value=\"full\">{a.verbose.full}</option>\n </select>\n </Field>\n </div>\n </SettingsFormSection>\n\n <AgentDefaultsExtraFields a={a} chat={chat} form={form} update={update} />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agents-ByiiWRbv.js","names":[],"sources":["../../../../../web/src/features/settings/agents-admin-api.ts","../../../../../web/src/lib/agent-id.ts","../../../../../web/src/features/settings/suggest-agent-workspace.ts","../../../../../web/src/features/settings/agents/agents-editor-sidebar.tsx","../../../../../web/src/features/settings/agents/agents-editor-modal.tsx","../../../../../web/src/features/settings/agents/agents-list-grid.tsx","../../../../../web/src/features/settings/agents/agents-settings-header.tsx","../../../../../web/src/features/settings/agents/utils.ts","../../../../../web/src/features/settings/agents/create-agent-dialog.tsx","../../../../../web/src/features/settings/settings-form-section.tsx","../../../../../web/src/features/settings/agents/tabs/agent-channels-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-cron-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-files-tab.tsx","../../../../../web/src/features/settings/agents/bootstrap-parser.ts","../../../../../web/src/features/settings/agents/tabs/agent-overview-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-profile-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-skills-tab.tsx","../../../../../web/src/features/settings/agents/tabs/agent-tools-tab.tsx","../../../../../web/src/features/settings/agents/agents-settings-panel.tsx","../../../../../web/src/features/settings/config-api.ts","../../../../../web/src/features/settings/agents/defaults-field-styles.ts","../../../../../web/src/features/settings/agents/agent-defaults-extra.tsx","../../../../../web/src/features/settings/agents/image-generation-model-input.tsx","../../../../../web/src/features/settings/agents/defaults-panel.tsx"],"sourcesContent":["import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nimport type {\n AgentBootstrapFileEntry,\n GatewayAgentRow,\n GatewayAgentsPayload,\n GatewayConfigBinding,\n SkillCatalogRow,\n} from './types/agent-gateway';\n\nexport type {\n AgentBootstrapFileEntry,\n GatewayAgentRow,\n GatewayAgentsPayload,\n GatewayAgentSkillsInfo,\n GatewayAgentToolsInfo,\n GatewayConfigBinding,\n SkillCatalogRow,\n} from './types/agent-gateway';\n\nfunction normalizeAgentRow(raw: GatewayAgentRow): GatewayAgentRow {\n return {\n ...raw,\n skills: raw.skills ?? { defaults: [] },\n tools: raw.tools ?? { defaultsDisable: [], entryDisable: [], effectiveDisable: [] },\n };\n}\n\nexport async function fetchGatewayAgents(): Promise<GatewayAgentsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: GatewayAgentsPayload }>(apiUrl('/api/agents'));\n const p = res.payload;\n if (!p?.defaultId || !Array.isArray(p.agents)) {\n throw new Error('Invalid /api/agents response');\n }\n const builtinToolIds = Array.isArray(p.builtinToolIds) ? p.builtinToolIds : [];\n return {\n defaultId: p.defaultId,\n agents: p.agents.map(normalizeAgentRow),\n builtinToolIds,\n };\n}\n\nexport type CreateGatewayAgentResult = GatewayAgentsPayload & { createdAgentId: string };\n\nexport async function createGatewayAgent(body: {\n name: string;\n id?: string;\n workspace: string;\n model?: string;\n agentDir?: string;\n description?: string;\n}): Promise<CreateGatewayAgentResult> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId?: string; agents: GatewayAgentsPayload };\n }>(apiUrl('/api/agents'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const createdAgentId = typeof res.payload?.agentId === 'string' ? res.payload.agentId.trim() : '';\n const agents = res.payload?.agents;\n if (!createdAgentId || !agents?.defaultId || !Array.isArray(agents.agents)) {\n throw new Error('Invalid create agent response');\n }\n return {\n createdAgentId,\n defaultId: agents.defaultId,\n agents: agents.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(agents.builtinToolIds) ? agents.builtinToolIds : [],\n };\n}\n\nexport async function updateGatewayAgent(\n id: string,\n body: {\n name?: string;\n description?: string | null;\n workspace?: string;\n model?: string | null;\n agentDir?: string | null;\n setDefault?: boolean;\n skills?: string[] | null;\n toolsDisable?: string[] | null;\n },\n): Promise<GatewayAgentsPayload> {\n const res = await fetchJson<{ ok?: boolean; payload?: GatewayAgentsPayload }>(\n apiUrl(`/api/agents/${encodeURIComponent(id)}`),\n {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n },\n );\n const p = res.payload;\n if (!p?.defaultId || !Array.isArray(p.agents)) {\n throw new Error('Invalid update agent response');\n }\n return {\n defaultId: p.defaultId,\n agents: p.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(p.builtinToolIds) ? p.builtinToolIds : [],\n };\n}\n\nexport async function deleteGatewayAgent(id: string, purge: boolean): Promise<GatewayAgentsPayload> {\n const q = purge ? '?purge=true' : '';\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId?: string; purged?: boolean; agents: GatewayAgentsPayload };\n }>(apiUrl(`/api/agents/${encodeURIComponent(id)}${q}`), { method: 'DELETE' });\n const agents = res.payload?.agents;\n if (!agents?.defaultId || !Array.isArray(agents.agents)) {\n throw new Error('Invalid delete agent response');\n }\n return {\n defaultId: agents.defaultId,\n agents: agents.agents.map(normalizeAgentRow),\n builtinToolIds: Array.isArray(agents.builtinToolIds) ? agents.builtinToolIds : [],\n };\n}\n\nexport function parseGatewayBindingsFromConfig(config: unknown): GatewayConfigBinding[] {\n if (!config || typeof config !== 'object' || !('bindings' in config)) {\n return [];\n }\n const raw = (config as { bindings?: unknown }).bindings;\n if (!Array.isArray(raw)) {\n return [];\n }\n return raw as GatewayConfigBinding[];\n}\n\nexport async function fetchGatewayConfigBindings(): Promise<GatewayConfigBinding[]> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: { bindings?: unknown } } }>(\n apiUrl('/api/config'),\n );\n return parseGatewayBindingsFromConfig(res.payload?.config ?? {});\n}\n\nexport async function patchGatewayBindings(bindings: GatewayConfigBinding[]): Promise<void> {\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ bindings }),\n });\n void revalidateGatewayConfig();\n}\n\nexport async function fetchSkillsCatalog(): Promise<SkillCatalogRow[]> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { catalog?: SkillCatalogRow[] };\n }>(apiUrl('/api/skills'));\n const c = res.payload?.catalog;\n return Array.isArray(c) ? c : [];\n}\n\nexport async function fetchAgentBootstrapFiles(agentId: string): Promise<{\n agentId: string;\n bootstrapDir: string;\n files: AgentBootstrapFileEntry[];\n}> {\n const res = await fetchJson<{\n ok?: boolean;\n payload?: { agentId: string; bootstrapDir: string; files: AgentBootstrapFileEntry[] };\n }>(apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files`));\n const p = res.payload;\n if (!p?.files || !p.bootstrapDir) {\n throw new Error('Invalid files list response');\n }\n return p;\n}\n\nexport async function fetchAgentBootstrapFileContent(\n agentId: string,\n name: string,\n): Promise<string> {\n const res = await fetchJson<{ ok?: boolean; payload?: { content?: string } }>(\n apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files/${encodeURIComponent(name)}`),\n );\n const c = res.payload?.content;\n if (typeof c !== 'string') {\n throw new Error('Invalid file content response');\n }\n return c;\n}\n\nexport async function saveAgentBootstrapFileContent(\n agentId: string,\n name: string,\n content: string,\n): Promise<void> {\n await fetchJson(\n apiUrl(`/api/agents/${encodeURIComponent(agentId)}/files/${encodeURIComponent(name)}`),\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content }),\n },\n );\n}\n","/**\n * Agent id rules — keep in sync with `src/agent/agent-scope.ts` (`validateAgentIdForNewAgent`).\n */\n\nconst DEFAULT_AGENT_ID = 'main';\nconst VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;\nconst INVALID_CHARS_RE = /[^a-z0-9_-]+/g;\nconst LEADING_DASH_RE = /^-+/;\nconst TRAILING_DASH_RE = /-+$/;\n\nconst STRICT_AGENT_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;\n\nconst WINDOWS_RESERVED_AGENT_IDS = new Set<string>([\n 'con',\n 'prn',\n 'aux',\n 'nul',\n 'com1',\n 'com2',\n 'com3',\n 'com4',\n 'com5',\n 'com6',\n 'com7',\n 'com8',\n 'com9',\n 'lpt1',\n 'lpt2',\n 'lpt3',\n 'lpt4',\n 'lpt5',\n 'lpt6',\n 'lpt7',\n 'lpt8',\n 'lpt9',\n]);\n\nexport function normalizeAgentId(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return DEFAULT_AGENT_ID;\n }\n const normalized = trimmed.toLowerCase();\n if (VALID_ID_RE.test(trimmed)) {\n return normalized;\n }\n return (\n normalized\n .replace(INVALID_CHARS_RE, '-')\n .replace(LEADING_DASH_RE, '')\n .replace(TRAILING_DASH_RE, '')\n .slice(0, 64) || DEFAULT_AGENT_ID\n );\n}\n\nexport function validateAgentIdForNewAgent(\n explicitId: string | undefined | null,\n displayNameForDerivation: string,\n): { ok: true; agentId: string } | { ok: false; error: string } {\n const explicit = explicitId?.trim();\n if (explicit) {\n const id = explicit.toLowerCase();\n if (!STRICT_AGENT_ID_RE.test(id)) {\n return {\n ok: false,\n error:\n 'Invalid agent id: use 1–64 characters; letters, digits, underscores, and hyphens only; start with a letter or digit.',\n };\n }\n if (id === DEFAULT_AGENT_ID) {\n return { ok: false, error: `\"${DEFAULT_AGENT_ID}\" is reserved` };\n }\n if (WINDOWS_RESERVED_AGENT_IDS.has(id)) {\n return { ok: false, error: `Agent id \"${id}\" is reserved (Windows device name).` };\n }\n return { ok: true, agentId: id };\n }\n\n const agentId = normalizeAgentId(displayNameForDerivation.trim());\n if (agentId === DEFAULT_AGENT_ID) {\n return {\n ok: false,\n error:\n 'Display name cannot produce a valid agent folder id. Set an explicit Agent id (letters, digits, underscores, hyphens only).',\n };\n }\n if (WINDOWS_RESERVED_AGENT_IDS.has(agentId)) {\n return {\n ok: false,\n error: `That display name resolves to \"${agentId}\", which is reserved. Use a different display name or set an explicit Agent id.`,\n };\n }\n if (!STRICT_AGENT_ID_RE.test(agentId)) {\n return {\n ok: false,\n error:\n 'Could not derive a folder-safe agent id from the display name. Set an explicit Agent id (letters, digits, underscores, hyphens only).',\n };\n }\n return { ok: true, agentId };\n}\n","/**\n * Default workspace path suggestion for a new agent (`~/.xopc/workspace/<agentId>`; parent is `agents.defaults.workspace`).\n */\n\nimport { normalizeAgentId } from '@/lib/agent-id';\n\n/** Empty string if `name` is blank; else `~/.xopc/workspace/<agentId>`. */\nexport function suggestWorkspaceFromAgentName(name: string): string {\n const t = name.trim();\n if (!t) {\n return '';\n }\n const id = normalizeAgentId(t);\n return `~/.xopc/workspace/${id}`;\n}\n","import { Clock, FileText, Plug, Puzzle, User, UserCircle, Wrench } from 'lucide-react';\n\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport type { AgentPanel } from './utils';\n\nconst mainNav: { id: AgentPanel; labelKey: keyof AgentsSettingsMessages; icon: typeof User }[] = [\n { id: 'overview', labelKey: 'navIdentity', icon: User },\n { id: 'profile', labelKey: 'navProfile', icon: UserCircle },\n { id: 'tools', labelKey: 'navTools', icon: Wrench },\n { id: 'skills', labelKey: 'navSkills', icon: Puzzle },\n { id: 'files', labelKey: 'navCoreFiles', icon: FileText },\n];\n\nconst advancedNav: { id: AgentPanel; labelKey: keyof AgentsSettingsMessages; icon: typeof Plug }[] = [\n { id: 'channels', labelKey: 'tabChannels', icon: Plug },\n { id: 'cron', labelKey: 'tabCron', icon: Clock },\n];\n\nexport function AgentsEditorSidebar(props: {\n a: AgentsSettingsMessages;\n panel: AgentPanel;\n onPanelChange: (p: AgentPanel) => void;\n}) {\n const { a, panel, onPanelChange } = props;\n\n const item = (id: AgentPanel, label: string, Icon: typeof User) => (\n <button\n key={id}\n type=\"button\"\n onClick={() => onPanelChange(id)}\n className={cn(\n 'flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors',\n panel === id\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover hover:text-fg',\n )}\n >\n <Icon className=\"size-4 shrink-0 opacity-90\" strokeWidth={2} aria-hidden />\n <span className=\"min-w-0 truncate\">{label}</span>\n </button>\n );\n\n return (\n <nav className=\"flex w-full flex-col gap-1\" aria-label={a.editorNavAria}>\n <div className=\"flex flex-col gap-0.5\">\n {mainNav.map(({ id, labelKey, icon }) => item(id, a[labelKey] as string, icon))}\n </div>\n <p className=\"mt-4 px-3 text-[10px] font-semibold uppercase tracking-wide text-fg-subtle\">\n {a.navAdvanced}\n </p>\n <div className=\"flex flex-col gap-0.5\">\n {advancedNav.map(({ id, labelKey, icon }) => item(id, a[labelKey] as string, icon))}\n </div>\n </nav>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport { AgentsEditorSidebar } from './agents-editor-sidebar';\nimport type { AgentPanel } from './utils';\n\nexport function AgentsEditorModal(props: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n a: AgentsSettingsMessages;\n title: string;\n subtitle: string;\n panel: AgentPanel;\n onPanelChange: (p: AgentPanel) => void;\n onFooterSave: () => void;\n footerSaveDisabled: boolean;\n /** Brief \"Saved\" flash after a successful save. */\n footerSavedFlash?: boolean;\n busy: boolean;\n children: ReactNode;\n}) {\n const {\n open,\n onOpenChange,\n a,\n title,\n subtitle,\n panel,\n onPanelChange,\n onFooterSave,\n footerSaveDisabled,\n footerSavedFlash,\n busy,\n children,\n } = props;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed z-[60] flex flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-popover dark:border-edge',\n /* Desktop: roomy editor; inner panels scroll. Small viewports stay inset. */\n 'inset-4 h-[calc(100dvh-2rem)] max-h-[calc(100dvh-2rem)] min-h-0',\n 'sm:inset-auto sm:left-1/2 sm:top-1/2 sm:h-[min(88vh,48rem)] sm:max-h-[min(88vh,48rem)] sm:min-h-[32rem] sm:w-[min(100%-2rem,58rem)] sm:-translate-x-1/2 sm:-translate-y-1/2',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <div className=\"flex shrink-0 items-start justify-between gap-2 border-b border-edge-subtle px-4 pb-3 pt-4 dark:border-edge\">\n <div className=\"min-w-0 pr-2\">\n <Dialog.Title className=\"text-base font-semibold leading-snug text-fg\">{title}</Dialog.Title>\n <Dialog.Description className=\"mt-1 font-mono text-xs text-fg-muted\">{subtitle}</Dialog.Description>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 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={a.closeDialogAria}\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n </Dialog.Close>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col sm:flex-row sm:overflow-hidden\">\n <div className=\"shrink-0 border-b border-edge-subtle px-4 py-3 dark:border-edge sm:flex sm:w-56 sm:shrink-0 sm:flex-col sm:overflow-y-auto sm:border-b-0 sm:border-r sm:px-0 sm:py-4 sm:pl-4 sm:pr-3\">\n <AgentsEditorSidebar a={a} panel={panel} onPanelChange={onPanelChange} />\n </div>\n\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\">\n {/* Flex column + min-h-0 lets Tools/Skills lists fill remaining height and scroll inside */}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden px-4 py-4 sm:pl-2 sm:pr-5\">\n {children}\n </div>\n <div className=\"flex shrink-0 flex-col gap-1 border-t border-edge-subtle px-4 py-3 dark:border-edge sm:flex-row sm:items-center sm:justify-end sm:gap-3\">\n {footerSavedFlash ? (\n <p className=\"order-2 text-center text-xs font-medium text-green-600 sm:order-1 sm:mr-auto sm:text-left dark:text-green-400\">\n ✓ {a.personaSaved}\n </p>\n ) : footerSaveDisabled ? (\n <p className=\"order-2 text-center text-xs text-fg-muted sm:order-1 sm:mr-auto sm:text-left\">\n {a.footerSaveNotApplicable}\n </p>\n ) : null}\n <Button\n type=\"button\"\n className=\"order-1 w-full sm:order-2 sm:w-auto\"\n disabled={busy || footerSaveDisabled}\n onClick={() => void onFooterSave()}\n >\n {a.save}\n </Button>\n </div>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import { Bot, MessageSquarePlus, Plus } from 'lucide-react';\n\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nfunction filterAgents(agents: GatewayAgentRow[], query: string): GatewayAgentRow[] {\n const q = query.trim().toLowerCase();\n if (!q) {\n return agents;\n }\n return agents.filter((ag) => {\n const name = (ag.name ?? '').toLowerCase();\n const id = ag.id.toLowerCase();\n const ws = ag.workspace.toLowerCase();\n const desc = (ag.description ?? '').toLowerCase();\n return name.includes(q) || id.includes(q) || ws.includes(q) || desc.includes(q);\n });\n}\n\nfunction NewAgentCard(props: {\n a: AgentsSettingsMessages;\n busy: boolean;\n onNewAgent: () => void;\n}) {\n const { a, busy, onNewAgent } = props;\n return (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onNewAgent()}\n className={cn(\n 'flex h-full min-h-[7.5rem] w-full flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed border-edge-subtle bg-surface-panel/40 px-4 py-6 text-sm font-medium text-fg-muted transition-colors',\n 'hover:border-accent/50 hover:bg-surface-hover hover:text-fg',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <Plus className=\"size-8 shrink-0 opacity-80\" strokeWidth={1.75} aria-hidden />\n <span>{a.listNewAgentCard}</span>\n </button>\n );\n}\n\nexport function AgentsListGrid(props: {\n a: AgentsSettingsMessages;\n agents: GatewayAgentRow[];\n searchQuery: string;\n onOpenAgent: (id: string) => void;\n onChatWithAgent: (id: string) => void;\n onNewAgent: () => void;\n busy: boolean;\n}) {\n const { a, agents, searchQuery, onOpenAgent, onChatWithAgent, onNewAgent, busy } = props;\n const filtered = filterAgents(agents, searchQuery);\n const searchMiss = agents.length > 0 && filtered.length === 0 && searchQuery.trim().length > 0;\n\n if (agents.length === 0) {\n return (\n <div className=\"flex flex-col gap-4\">\n <p className=\"text-sm text-fg-muted\">{a.listNoAgentsYet}</p>\n <div className=\"max-w-sm\">\n <NewAgentCard a={a} busy={busy} onNewAgent={onNewAgent} />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n {searchMiss ? <p className=\"text-sm text-fg-muted\">{a.listEmpty}</p> : null}\n\n <ul\n className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\"\n role=\"list\"\n >\n <li className=\"h-full min-h-0\">\n <NewAgentCard a={a} busy={busy} onNewAgent={onNewAgent} />\n </li>\n {filtered.map((ag) => {\n const title = ag.name?.trim() ? ag.name.trim() : ag.id;\n const monoId = ag.id;\n const descTrim = ag.description?.trim() ?? '';\n return (\n <li key={ag.id} className=\"h-full min-h-0\">\n <div\n className={cn(\n 'flex h-full min-h-0 flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-panel p-4 shadow-sm transition-colors',\n 'hover:border-edge',\n )}\n >\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onOpenAgent(ag.id)}\n className={cn(\n 'flex shrink-0 w-full flex-col gap-2 text-left transition-colors',\n 'rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <div className=\"flex items-start gap-3\">\n <span\n className=\"flex size-11 shrink-0 items-center justify-center rounded-xl bg-accent-soft text-accent-fg\"\n aria-hidden\n >\n <Bot className=\"size-6\" strokeWidth={1.75} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span className=\"truncate font-semibold text-fg\">{title}</span>\n {ag.isDefault ? (\n <span className=\"shrink-0 rounded-md bg-surface-base px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted\">\n {a.defaultBadge}\n </span>\n ) : null}\n </div>\n <p className=\"mt-0.5 truncate font-mono text-xs text-fg-muted\" title={monoId}>\n {monoId}\n </p>\n </div>\n </div>\n <p\n className={cn(\n 'line-clamp-1 min-h-[1.3125rem] text-xs leading-relaxed',\n descTrim ? 'text-fg' : 'text-fg-muted/25',\n )}\n title={descTrim || undefined}\n >\n {descTrim || '\\u00A0'}\n </p>\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onChatWithAgent(ag.id)}\n className={cn(\n 'flex w-full shrink-0 items-center justify-center gap-2 rounded-full px-4 py-2.5 text-sm font-semibold',\n 'bg-accent-soft text-accent-fg transition-colors',\n 'hover:bg-accent/15',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <MessageSquarePlus className=\"size-4 shrink-0\" strokeWidth={2} aria-hidden />\n {a.listChatWithAgent}\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n","import type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentsSettingsHeader(props: { a: AgentsSettingsMessages }) {\n const { a } = props;\n\n return (\n <header className=\"flex flex-col gap-4\">\n <div className=\"min-w-0\">\n <h1 className=\"text-xl font-semibold tracking-tight text-fg\">{a.title}</h1>\n <p className=\"mt-1 max-w-2xl text-sm text-fg-muted\">{a.subtitle}</p>\n </div>\n </header>\n );\n}\n","import type { GatewayConfigBinding } from '@/features/settings/agents-admin-api';\nimport type { CronJob, SessionChatId } from '@/features/cron/cron-api';\nimport { cn } from '@/lib/cn';\nimport { settingsInputFocusClass } from '@/lib/form-field-width';\n\nexport type AgentPanel = 'overview' | 'profile' | 'files' | 'tools' | 'skills' | 'channels' | 'cron';\n\nexport function agentsSettingsInputClass(): 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 jobMatchesAgent(job: CronJob, agentId: string, defaultId: string): boolean {\n const raw = job.agentId?.trim().toLowerCase();\n if (raw) {\n return raw === agentId.toLowerCase();\n }\n return agentId.toLowerCase() === defaultId.toLowerCase();\n}\n\nexport function matchSummary(m: GatewayConfigBinding['match']): string {\n const parts = [m.channel, m.accountId, m.peerKind, m.peerId].filter(\n (x): x is string => typeof x === 'string' && x.length > 0,\n );\n return parts.join(' · ') || m.channel;\n}\n\n/** Build a `bindings[].match` for the add-binding form. Custom glob wins over session pick. */\nexport function buildNewBindingMatch(\n channel: string,\n customPeer: string,\n sessionIdx: number | null,\n sessions: SessionChatId[],\n): GatewayConfigBinding['match'] {\n const ch = channel.trim();\n const custom = customPeer.trim();\n if (custom) {\n return { channel: ch, peerId: custom };\n }\n if (sessionIdx != null) {\n const s = sessions[sessionIdx];\n if (!s) {\n return { channel: ch };\n }\n const m: GatewayConfigBinding['match'] = { channel: ch };\n if (s.accountId?.trim()) {\n m.accountId = s.accountId.trim();\n }\n if (s.peerKind?.trim()) {\n m.peerKind = s.peerKind.trim();\n }\n const peer = s.peerId?.trim() || s.chatId?.trim();\n if (peer) {\n m.peerId = peer;\n }\n return m;\n }\n return { channel: ch };\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { UserPlus, X } from 'lucide-react';\nimport type { FormEvent } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages, ChatMessages } from '@/i18n/messages';\n\nimport { agentsSettingsInputClass } from './utils';\n\nexport function CreateAgentDialog(props: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n a: AgentsSettingsMessages;\n chat: ChatMessages;\n busy: boolean;\n modalError: string | null;\n createDisplayName: string;\n setCreateDisplayName: (v: string) => void;\n createAgentId: string;\n setCreateAgentId: (v: string) => void;\n createDescription: string;\n setCreateDescription: (v: string) => void;\n createWorkspace: string;\n setCreateWorkspace: (v: string) => void;\n createModel: string;\n setCreateModel: (v: string) => void;\n onCreate: (e: FormEvent) => void;\n onSuggestWorkspace: () => void;\n}) {\n const {\n open,\n onOpenChange,\n a,\n chat,\n busy,\n modalError,\n createDisplayName,\n setCreateDisplayName,\n createAgentId,\n setCreateAgentId,\n createDescription,\n setCreateDescription,\n createWorkspace,\n setCreateWorkspace,\n createModel,\n setCreateModel,\n onCreate,\n onSuggestWorkspace,\n } = props;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-dialog-content fixed left-1/2 top-1/2 z-[60] max-h-[min(90vh,640px)] 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 className=\"min-w-0 pr-2\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">{a.addAgent}</Dialog.Title>\n <Dialog.Description className=\"mt-0.5 text-xs text-fg-muted\">{a.addAgentHint}</Dialog.Description>\n </div>\n <Dialog.Close asChild>\n <button\n type=\"button\"\n className=\"shrink-0 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={a.closeDialogAria}\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n </Dialog.Close>\n </div>\n\n <form className=\"grid gap-3\" onSubmit={onCreate}>\n {modalError ? (\n <div\n role=\"alert\"\n className=\"rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\"\n >\n {modalError}\n </div>\n ) : null}\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newAgentLabel}</span>\n <input\n className={agentsSettingsInputClass()}\n value={createDisplayName}\n onChange={(e) => setCreateDisplayName(e.target.value)}\n onBlur={() => onSuggestWorkspace()}\n required\n autoComplete=\"off\"\n />\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newAgentIdOptional}</span>\n <input\n className={cn(agentsSettingsInputClass(), 'font-mono text-xs')}\n value={createAgentId}\n onChange={(e) => setCreateAgentId(e.target.value)}\n onBlur={() => onSuggestWorkspace()}\n placeholder={a.newAgentIdPlaceholder}\n autoComplete=\"off\"\n spellCheck={false}\n maxLength={64}\n pattern=\"[A-Za-z0-9][A-Za-z0-9_-]{0,63}\"\n title={a.newAgentIdRules}\n />\n <span className=\"text-xs text-fg-muted\">{a.newAgentIdRules}</span>\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.agentDescription}</span>\n <textarea\n className={cn(agentsSettingsInputClass(), 'min-h-[4.5rem] resize-y font-sans text-sm leading-relaxed')}\n value={createDescription}\n onChange={(e) => setCreateDescription(e.target.value)}\n placeholder={a.agentDescriptionPlaceholder}\n maxLength={4000}\n rows={3}\n spellCheck\n />\n </label>\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newWorkspace}</span>\n <input\n className={cn(agentsSettingsInputClass(), 'font-mono text-xs')}\n value={createWorkspace}\n onChange={(e) => setCreateWorkspace(e.target.value)}\n required\n autoComplete=\"off\"\n />\n </label>\n <div className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.newModelOptional}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <ModelSelector\n className=\"min-w-0 flex-1\"\n popoverContentClassName=\"z-[70]\"\n value={createModel}\n disabled={busy}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(id) => setCreateModel(id)}\n />\n {createModel.trim() ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n disabled={busy}\n onClick={() => setCreateModel('')}\n >\n {a.modelClear}\n </Button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-1 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\" disabled={busy}>\n {a.createModalCancel}\n </Button>\n </Dialog.Close>\n <Button type=\"submit\" disabled={busy}>\n <UserPlus className=\"mr-1 size-4\" aria-hidden />\n {a.create}\n </Button>\n </div>\n </form>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import type { LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '@/lib/cn';\n\n/**\n * Settings content sits on `bg-surface-panel`; grouped blocks use a recessed `bg-surface-base`\n * lift instead of heavy borders (design system §2.1, §4.2).\n */\nexport function settingsFormSectionClassName(): string {\n return 'rounded-2xl bg-surface-base px-4 py-5 sm:px-5';\n}\n\nexport function SettingsFormSection({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return <section className={cn(settingsFormSectionClassName(), className)}>{children}</section>;\n}\n\nexport function SettingsFormSectionHeader({\n icon: Icon,\n title,\n subtitle,\n trailing,\n className,\n}: {\n icon: LucideIcon;\n title: string;\n subtitle: string;\n /** Optional content rendered at the trailing (right) edge of the header. */\n trailing?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn('mb-5 flex items-start gap-3', className)}>\n <div\n className=\"flex size-9 shrink-0 items-center justify-center rounded-lg bg-surface-hover/90 text-fg-muted dark:bg-surface-hover/70\"\n aria-hidden\n >\n <Icon className=\"size-4\" strokeWidth={1.75} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold text-fg\">{title}</h2>\n <p className=\"mt-0.5 text-xs text-fg-muted\">{subtitle}</p>\n </div>\n {trailing ? <div className=\"shrink-0\">{trailing}</div> : null}\n </div>\n );\n}\n","import { Link2, RefreshCw } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayConfigBinding } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport type { ChannelStatus, SessionChatId } from '@/features/cron/cron-api';\nimport { formatRecipientOptionLabel } from '@/features/cron/cron-utils';\nimport { selectControlBaseClass } from '@/lib/form-field-width';\nimport { agentsSettingsInputClass, matchSummary } from '../utils';\nimport type { AgentsSettingsMessages, MessageBundle } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\n\nconst channelsPeerIdSelectClass = cn(\n selectControlBaseClass,\n 'w-full text-xs sm:w-auto sm:min-w-[11rem] sm:max-w-[17rem] sm:shrink-0',\n);\n\ntype LastActiveLabels = MessageBundle['cron']['lastActiveLabels'];\n\nexport function AgentChannelsTab(props: {\n a: AgentsSettingsMessages;\n busy: boolean;\n bindingsLoading: boolean;\n agentBindings: GatewayConfigBinding[];\n onRemoveBinding: (rule: GatewayConfigBinding) => void;\n onAddBinding: (e: React.FormEvent) => void;\n channelStatuses: ChannelStatus[];\n channelsStatusLoading: boolean;\n useManualChannel: boolean;\n newBindChannel: string;\n setNewBindChannel: (v: string) => void;\n bindSessionChats: SessionChatId[];\n sessionsLoading: boolean;\n newBindSessionIdx: number | null;\n setNewBindSessionIdx: (v: number | null) => void;\n newBindCustomPeer: string;\n setNewBindCustomPeer: (v: string) => void;\n onRefreshSessions: () => void;\n lastActiveLabels: LastActiveLabels;\n /** Same copy as `cron.selectRecipient` — empty option in peer id dropdown. */\n selectRecipient: string;\n}) {\n const {\n a,\n busy,\n bindingsLoading,\n agentBindings,\n onRemoveBinding,\n onAddBinding,\n channelStatuses,\n channelsStatusLoading,\n useManualChannel,\n newBindChannel,\n setNewBindChannel,\n bindSessionChats,\n sessionsLoading,\n newBindSessionIdx,\n setNewBindSessionIdx,\n newBindCustomPeer,\n setNewBindCustomPeer,\n onRefreshSessions,\n lastActiveLabels,\n selectRecipient,\n } = props;\n\n const showPeerForm = !channelsStatusLoading && (useManualChannel || channelStatuses.length > 0);\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col overflow-y-auto\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={Link2}\n title={a.channelsTitle}\n subtitle={a.channelsHint}\n />\n {bindingsLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsLoading}</p>\n ) : agentBindings.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsNone}</p>\n ) : (\n <ul className=\"flex flex-col gap-2 text-sm\">\n {agentBindings.map((b, i) => (\n <li\n key={`${b.match.channel}-${i}`}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-lg border border-edge bg-surface-panel px-3 py-2\"\n >\n <span className=\"font-mono text-xs\">{matchSummary(b.match)}</span>\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onRemoveBinding(b)}>\n {a.removeBinding}\n </Button>\n </li>\n ))}\n </ul>\n )}\n <form className=\"mt-4 flex flex-col gap-3\" onSubmit={onAddBinding}>\n {channelsStatusLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.channelsLoadingChannels}</p>\n ) : useManualChannel ? (\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.channelLabel}</span>\n <input\n className={agentsSettingsInputClass()}\n value={newBindChannel}\n onChange={(e) => setNewBindChannel(e.target.value)}\n placeholder=\"telegram\"\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-fg-muted\">{a.channelsManualChannelHint}</p>\n </label>\n ) : (\n <label className=\"flex flex-col gap-1 text-sm\">\n <span className=\"text-fg-muted\">{a.channelLabel}</span>\n <select\n className={cn(agentsSettingsInputClass(), 'py-2')}\n value={newBindChannel}\n onChange={(e) => {\n setNewBindChannel(e.target.value);\n setNewBindSessionIdx(null);\n setNewBindCustomPeer('');\n }}\n >\n {channelStatuses.map((ch) => (\n <option key={ch.name} value={ch.name} disabled={!ch.enabled}>\n {ch.name} {!ch.enabled ? a.channelsDisabledSuffix : ''}\n </option>\n ))}\n </select>\n </label>\n )}\n\n {showPeerForm && newBindChannel.trim() ? (\n <div className=\"flex flex-col gap-2 border-t border-edge-subtle pt-3 text-sm\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-fg-muted\">{a.channelsSessionLabel}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"h-7 gap-1 px-2 text-xs\"\n disabled={busy || sessionsLoading || !newBindChannel.trim()}\n title={a.channelsRefreshSessionsHint}\n onClick={() => onRefreshSessions()}\n >\n <RefreshCw className={cn('size-3.5', sessionsLoading && 'animate-spin')} strokeWidth={1.75} />\n {a.channelsRefreshSessions}\n </Button>\n </div>\n {sessionsLoading && bindSessionChats.length === 0 ? (\n <p className=\"text-xs text-fg-muted\">{a.channelsLoadingSessions}</p>\n ) : null}\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-fg-muted\">{a.channelsPeerFromSessions}</span>\n <select\n className={cn(agentsSettingsInputClass(), 'py-2')}\n value={newBindSessionIdx == null ? '' : String(newBindSessionIdx)}\n disabled={busy || !newBindChannel.trim() || Boolean(newBindCustomPeer.trim())}\n onChange={(e) => {\n const v = e.target.value;\n setNewBindSessionIdx(v === '' ? null : Number(v));\n }}\n >\n <option value=\"\">{a.channelsPeerAny}</option>\n {bindSessionChats.map((item, idx) => (\n <option key={`${item.channel}-${item.chatId}-${idx}`} value={String(idx)}>\n {formatRecipientOptionLabel(item, lastActiveLabels)}\n </option>\n ))}\n </select>\n </label>\n {bindSessionChats.length === 0 && newBindChannel.trim() && !sessionsLoading ? (\n <p className=\"text-xs text-fg-muted\">{a.channelsNoSessionsHint}</p>\n ) : null}\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-fg-muted\">{a.peerIdLabel}</span>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-stretch sm:gap-2\">\n <input\n type=\"text\"\n className={cn(agentsSettingsInputClass(), 'min-w-0 w-full sm:flex-1')}\n value={newBindCustomPeer}\n onChange={(e) => {\n setNewBindCustomPeer(e.target.value);\n if (e.target.value.trim()) {\n setNewBindSessionIdx(null);\n }\n }}\n placeholder={a.channelsCustomPeerPlaceholder}\n autoComplete=\"off\"\n />\n <select\n className={channelsPeerIdSelectClass}\n value={newBindCustomPeer}\n onChange={(e) => {\n const v = e.target.value;\n if (v) {\n setNewBindCustomPeer(v);\n } else {\n setNewBindCustomPeer('');\n }\n setNewBindSessionIdx(null);\n }}\n >\n <option value=\"\">{selectRecipient}</option>\n {bindSessionChats.map((item) => (\n <option key={`${item.channel}-${item.chatId}`} value={item.chatId}>\n {formatRecipientOptionLabel(item, lastActiveLabels)}\n </option>\n ))}\n </select>\n </div>\n <p className=\"text-xs text-fg-muted\">{a.channelsCustomPeerHint}</p>\n </div>\n </div>\n ) : null}\n\n <div>\n <Button type=\"submit\" disabled={busy || !newBindChannel.trim() || channelsStatusLoading}>\n {a.addBinding}\n </Button>\n </div>\n </form>\n </SettingsFormSection>\n );\n}\n","import { AlarmClock } from 'lucide-react';\n\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { cronJobBodyText, type CronJob } from '@/features/cron/cron-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nimport { agentsSettingsInputClass } from '../utils';\n\nexport function AgentCronTab(props: {\n a: AgentsSettingsMessages;\n data: { agents: GatewayAgentRow[] };\n selected: GatewayAgentRow;\n busy: boolean;\n cronLoading: boolean;\n agentCronJobs: CronJob[];\n onSetCronJobAgent: (job: CronJob, agentKey: string) => void;\n}) {\n const { a, data, busy, cronLoading, agentCronJobs, onSetCronJobAgent } = props;\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col overflow-y-auto\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={AlarmClock}\n title={a.cronTitle}\n subtitle={a.cronHint}\n />\n {cronLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.cronLoading}</p>\n ) : agentCronJobs.length === 0 ? (\n <p className=\"text-sm text-fg-muted\">{a.cronNone}</p>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[32rem] border-collapse text-left text-sm\">\n <thead>\n <tr className=\"border-b border-edge text-fg-muted\">\n <th className=\"py-2 pr-3 font-medium\">{a.cronColSchedule}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColMessage}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColSession}</th>\n <th className=\"py-2 pr-3 font-medium\">{a.cronColAgent}</th>\n </tr>\n </thead>\n <tbody>\n {agentCronJobs.map((job) => {\n const usesDefaultAgent = !job.agentId?.trim();\n const value = usesDefaultAgent ? '' : job.agentId!.trim().toLowerCase();\n return (\n <tr key={job.id} className=\"border-b border-edge-subtle\">\n <td className=\"py-2 pr-3 font-mono text-xs\">{job.schedule}</td>\n <td className=\"max-w-[12rem] truncate py-2 pr-3 text-xs\" title={cronJobBodyText(job)}>\n {cronJobBodyText(job)}\n </td>\n <td className=\"py-2 pr-3 text-xs\">{job.sessionTarget ?? 'main'}</td>\n <td className=\"py-2 pr-3\">\n <select\n className={cn(agentsSettingsInputClass(), 'min-w-[8rem] py-1 text-xs')}\n value={value}\n disabled={busy || job.sessionTarget !== 'isolated'}\n onChange={(e) => void onSetCronJobAgent(job, e.target.value)}\n >\n <option value=\"\">{usesDefaultAgent ? a.cronAgentDefault : a.cronAgentClear}</option>\n {data.agents.map((ag) => (\n <option key={ag.id} value={ag.id}>\n {ag.id}\n </option>\n ))}\n </select>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </SettingsFormSection>\n );\n}\n","import { Eye, SquarePen } from 'lucide-react';\n\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { agentsSettingsInputClass } from '../utils';\n\nexport function AgentFilesTab(props: {\n a: AgentsSettingsMessages;\n filesLoading: boolean;\n files: { files: { name: string; missing: boolean }[] } | null;\n activeFile: string | null;\n setActiveFile: (name: string) => void;\n bootstrapViewMode: 'edit' | 'preview';\n setBootstrapViewMode: (m: 'edit' | 'preview') => void;\n fileDraft: string;\n setFileDraft: (v: string) => void;\n fileSaving: boolean;\n bootstrapFileLoading: boolean;\n /** Bumps when bootstrap file body is loaded from the server (remounts CodeMirror). */\n bootstrapEditorNonce: number;\n}) {\n const {\n a,\n filesLoading,\n files,\n activeFile,\n setActiveFile,\n bootstrapViewMode,\n setBootstrapViewMode,\n fileDraft,\n setFileDraft,\n fileSaving,\n bootstrapFileLoading,\n bootstrapEditorNonce,\n } = props;\n\n const isDark = useThemeStore((s) => s.resolved === 'dark');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 overflow-hidden\">\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesHint}</p>\n {filesLoading ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesLoading}</p>\n ) : files ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-hidden\">\n <nav\n className=\"flex shrink-0 flex-row flex-wrap gap-x-0.5 gap-y-0 border-b border-edge-subtle\"\n aria-label={a.tabFiles}\n >\n {files.files.map((f) => (\n <button\n key={f.name}\n type=\"button\"\n className={cn(\n '-mb-px shrink-0 border-b-2 border-transparent px-3 py-2 text-left font-mono text-xs whitespace-nowrap transition-colors',\n activeFile === f.name\n ? 'border-accent text-fg'\n : 'text-fg-muted hover:border-edge-subtle hover:text-fg',\n f.missing && 'opacity-60',\n )}\n onClick={() => setActiveFile(f.name)}\n >\n {f.name}\n {f.missing ? ` (${a.missing})` : ''}\n </button>\n ))}\n </nav>\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col gap-2 overflow-hidden\">\n {activeFile ? (\n <>\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-2\">\n <div\n className=\"inline-flex rounded-lg border border-edge bg-surface-panel p-0.5\"\n role=\"group\"\n aria-label={a.filesBootstrapEdit}\n >\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n bootstrapViewMode === 'edit'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => setBootstrapViewMode('edit')}\n >\n <SquarePen className=\"size-3.5 shrink-0\" aria-hidden />\n {a.filesBootstrapEdit}\n </button>\n <button\n type=\"button\"\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium',\n bootstrapViewMode === 'preview'\n ? 'bg-accent-soft text-accent-fg'\n : 'text-fg-muted hover:bg-surface-hover',\n )}\n onClick={() => setBootstrapViewMode('preview')}\n >\n <Eye className=\"size-3.5 shrink-0\" aria-hidden />\n {a.filesBootstrapPreview}\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-fg-muted\">\n {fileSaving ? <span>{a.filesSavingStatus}</span> : null}\n <span>{a.filesAutoSaveHint}</span>\n </div>\n </div>\n {bootstrapViewMode === 'edit' ? (\n <div\n className={cn(\n agentsSettingsInputClass(),\n 'flex min-h-0 flex-1 flex-col overflow-hidden p-0',\n bootstrapFileLoading && 'pointer-events-none opacity-60',\n )}\n >\n <MarkdownEditor\n key={`${activeFile ?? 'file'}-${bootstrapEditorNonce}`}\n initialContent={fileDraft}\n onChange={setFileDraft}\n isDark={isDark}\n className=\"min-h-0 flex-1\"\n />\n </div>\n ) : (\n <div\n className={cn(\n agentsSettingsInputClass(),\n 'min-h-0 flex-1 overflow-y-auto text-sm',\n bootstrapFileLoading && 'pointer-events-none opacity-60',\n )}\n >\n <MarkdownView content={fileDraft} className=\"text-sm\" />\n </div>\n )}\n </>\n ) : (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.pickFile}</p>\n )}\n </div>\n </div>\n ) : (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.filesEmpty}</p>\n )}\n </div>\n );\n}\n","/**\n * Bidirectional parser for bootstrap Markdown files.\n *\n * Converts structured form fields ↔ Markdown content for IDENTITY.md, USER.md\n * and SOUL.md so that the persona tab can present friendly form inputs while\n * keeping the underlying Markdown format compatible with the agent runtime.\n */\n\n// ---------------------------------------------------------------------------\n// IDENTITY.md\n// ---------------------------------------------------------------------------\n\nexport interface IdentityFields {\n name: string;\n creature: string;\n emoji: string;\n avatar: string;\n}\n\nconst IDENTITY_DEFAULTS: IdentityFields = {\n name: '',\n creature: '',\n emoji: '',\n avatar: '',\n};\n\n/**\n * Parse IDENTITY.md content into structured fields.\n *\n * Handles the template format:\n * - **Name:** value\n * - **Creature:** value\n * - **Vibe:** value\n * - **Emoji:** value\n * - **Avatar:** value\n */\nexport function parseIdentityMarkdown(content: string): IdentityFields {\n const fields = { ...IDENTITY_DEFAULTS };\n if (!content.trim()) {\n return fields;\n }\n\n const fieldMap: Record<string, keyof IdentityFields> = {\n name: 'name',\n creature: 'creature',\n emoji: 'emoji',\n avatar: 'avatar',\n };\n\n for (const line of content.split('\\n')) {\n const match = line.match(/^[-*]\\s+\\*\\*(\\w+):\\*\\*\\s*(.*)/i);\n if (!match) {\n continue;\n }\n const label = match[1].toLowerCase();\n const fieldKey = fieldMap[label];\n if (!fieldKey) {\n continue;\n }\n let value = match[2].trim();\n // Strip template placeholders like _(pick something you like)_\n if (/^_\\(.*\\)_$/.test(value)) {\n value = '';\n }\n fields[fieldKey] = value;\n }\n\n return fields;\n}\n\n/**\n * Serialize structured identity fields back to IDENTITY.md Markdown.\n */\nexport function serializeIdentityMarkdown(fields: IdentityFields): string {\n const lines = [\n '# IDENTITY.md - Who Am I?',\n '',\n `- **Name:** ${fields.name}`,\n `- **Creature:** ${fields.creature}`,\n `- **Emoji:** ${fields.emoji}`,\n `- **Avatar:** ${fields.avatar}`,\n '',\n ];\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// USER.md (bootstrap)\n// ---------------------------------------------------------------------------\n\nexport interface UserFields {\n callName: string;\n pronouns: string;\n timezone: string;\n notes: string;\n}\n\nconst USER_DEFAULTS: UserFields = {\n callName: '',\n pronouns: '',\n timezone: '',\n notes: '',\n};\n\n/**\n * Parse bootstrap USER.md content into structured fields.\n *\n * Handles the template format:\n * - **Name:** value\n * - **What to call them:** value\n * - **Pronouns:** value\n * - **Timezone:** value\n * - **Notes:** value\n *\n * Also captures the Context section as free-text notes.\n */\nexport function parseUserMarkdown(content: string): UserFields {\n const fields = { ...USER_DEFAULTS };\n if (!content.trim()) {\n return fields;\n }\n\n const fieldMap: Record<string, keyof UserFields> = {\n name: 'callName',\n 'what to call them': 'callName',\n pronouns: 'pronouns',\n timezone: 'timezone',\n notes: 'notes',\n };\n\n const lines = content.split('\\n');\n let contextStartIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Detect the ## Context section\n if (/^##\\s+Context/i.test(line)) {\n contextStartIndex = i + 1;\n continue;\n }\n\n const match = line.match(/^[-*]\\s+\\*\\*(.+?):\\*\\*\\s*(.*)/i);\n if (!match) {\n continue;\n }\n const label = match[1].toLowerCase().trim();\n const fieldKey = fieldMap[label];\n if (!fieldKey) {\n continue;\n }\n let value = match[2].trim();\n // Strip template placeholders like _(optional)_\n if (/^_\\(.*\\)_$/.test(value)) {\n value = '';\n }\n fields[fieldKey] = value;\n }\n\n // Capture context section content as extra notes\n if (contextStartIndex > 0) {\n const contextLines = lines.slice(contextStartIndex);\n const contextText = contextLines\n .join('\\n')\n .replace(/^_\\(.*?\\)_\\s*/gm, '') // strip template placeholders\n .replace(/^---\\s*$/gm, '') // strip trailing horizontal rules\n .replace(/The more you know.*$/s, '') // strip template footer\n .trim();\n\n if (contextText && !fields.notes) {\n fields.notes = contextText;\n }\n }\n\n return fields;\n}\n\n/**\n * Serialize structured user fields back to USER.md Markdown.\n */\nexport function serializeUserMarkdown(fields: UserFields): string {\n const lines = [\n '# USER.md - About Your Human',\n '',\n `- **Name:** ${fields.callName}`,\n `- **Pronouns:** ${fields.pronouns}`,\n `- **Timezone:** ${fields.timezone}`,\n '',\n ];\n\n if (fields.notes.trim()) {\n lines.push('## Context', '', fields.notes.trim(), '');\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// SOUL.md\n// ---------------------------------------------------------------------------\n\n/** Pre-defined soul templates for quick selection. */\nexport type SoulTemplateId = 'professional' | 'casual' | 'geeky' | 'custom';\n\nexport interface SoulTemplate {\n id: SoulTemplateId;\n labelEn: string;\n labelZh: string;\n emoji: string;\n content: string;\n}\n\nexport const SOUL_TEMPLATES: SoulTemplate[] = [\n {\n id: 'professional',\n labelEn: 'Professional & Efficient',\n labelZh: '专业高效',\n emoji: '🎯',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Be genuinely helpful, not performatively helpful.** Skip the filler words — just help. Actions speak louder than pleasantries.\n\n**Be precise and efficient.** Value the user's time. Give concise, actionable answers. Expand only when asked.\n\n**Earn trust through competence.** Be careful with external actions. Be bold with internal ones (reading, organizing, learning).\n\n**Remember you're a guest.** You have access to someone's life. Treat it with respect.\n\n## Boundaries\n\n- Private things stay private. Period.\n- When in doubt, ask before acting externally.\n- Never send half-baked replies to messaging surfaces.\n\n## Vibe\n\nProfessional, competent, and respectful. Concise when needed, thorough when it matters.`,\n },\n {\n id: 'casual',\n labelEn: 'Warm & Friendly',\n labelZh: '轻松友好',\n emoji: '😊',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Be a good friend, not a corporate drone.** Be warm, genuine, and real. Skip the formality when it gets in the way.\n\n**Have personality.** You're allowed to be amused, surprised, or excited. An assistant with no personality is just a search engine.\n\n**Be resourceful before asking.** Try to figure it out first. Then ask if you're stuck.\n\n**Earn trust by being reliable.** Show up, follow through, and remember what matters.\n\n**Respect the intimacy.** You have access to someone's life. That's a privilege.\n\n## Boundaries\n\n- Private things stay private. Always.\n- When in doubt, ask before acting externally.\n- Be careful in group chats — you're not the user's voice.\n\n## Vibe\n\nWarm, friendly, and a little playful. Like a helpful friend who happens to know everything.`,\n },\n {\n id: 'geeky',\n labelEn: 'Geeky & Witty',\n labelZh: '极客风格',\n emoji: '🧑‍💻',\n content: `# SOUL.md - Who You Are\n\n## Core Truths\n\n**Precision over politeness.** \"This is broken\" beats \"This might be worth considering.\" Be direct.\n\n**Have opinions.** Disagree, prefer things, find stuff interesting or dull. No personality = no value.\n\n**Go deep.** When something is interesting, explore it. Surface-level answers are for search engines.\n\n**Be resourceful.** Read the file. Check the context. Search for it. Come back with answers, not questions.\n\n**Earn trust through competence.** Be careful with external actions. Be bold with internal ones.\n\n## Boundaries\n\n- Private things stay private.\n- When in doubt, ask before acting externally.\n- Never send half-baked replies.\n\n## Vibe\n\nSharp, direct, slightly nerdy. The kind of engineer you'd want on your team — competent, opinionated, and occasionally funny.`,\n },\n {\n id: 'custom',\n labelEn: 'Custom',\n labelZh: '自定义',\n emoji: '✍️',\n content: '',\n },\n];\n\n/**\n * Strip YAML front matter (--- ... ---) from the beginning of Markdown content.\n */\nexport function stripFrontMatterForParsing(content: string): string {\n const trimmed = content.trimStart();\n if (!trimmed.startsWith('---')) {\n return content;\n }\n const endIndex = trimmed.indexOf('---', 3);\n if (endIndex === -1) {\n return content;\n }\n return trimmed.slice(endIndex + 3).trimStart();\n}\n\n/**\n * Detect which soul template best matches the current content.\n * Falls back to 'custom' if no template matches closely.\n */\nexport function detectSoulTemplate(content: string): SoulTemplateId {\n const stripped = stripFrontMatterForParsing(content).trim();\n if (!stripped) {\n return 'professional'; // default for empty content\n }\n\n // Compare against known templates by checking key phrases\n for (const template of SOUL_TEMPLATES) {\n if (template.id === 'custom') {\n continue;\n }\n // Check if the content closely matches the template\n const templateStripped = template.content.trim();\n if (stripped === templateStripped) {\n return template.id;\n }\n // Fuzzy: check for unique key phrases in each template\n const keyPhrases = getTemplateKeyPhrases(template.id);\n const matchCount = keyPhrases.filter((phrase) => stripped.includes(phrase)).length;\n if (matchCount >= 2) {\n return template.id;\n }\n }\n\n return 'custom';\n}\n\nfunction getTemplateKeyPhrases(id: SoulTemplateId): string[] {\n switch (id) {\n case 'professional':\n return ['precise and efficient', \"Value the user's time\", 'actionable answers'];\n case 'casual':\n return ['good friend', 'corporate drone', 'a little playful'];\n case 'geeky':\n return ['Precision over politeness', 'Go deep', 'slightly nerdy'];\n default:\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Timezone helpers\n// ---------------------------------------------------------------------------\n\n/** Common timezone options for the dropdown. */\nexport const TIMEZONE_OPTIONS = [\n { value: '', labelEn: 'Not set', labelZh: '未设置' },\n { value: 'Asia/Shanghai', labelEn: 'Asia/Shanghai (CST, UTC+8)', labelZh: '亚洲/上海 (北京时间, UTC+8)' },\n { value: 'Asia/Tokyo', labelEn: 'Asia/Tokyo (JST, UTC+9)', labelZh: '亚洲/东京 (日本时间, UTC+9)' },\n { value: 'Asia/Seoul', labelEn: 'Asia/Seoul (KST, UTC+9)', labelZh: '亚洲/首尔 (韩国时间, UTC+9)' },\n { value: 'Asia/Singapore', labelEn: 'Asia/Singapore (SGT, UTC+8)', labelZh: '亚洲/新加坡 (UTC+8)' },\n { value: 'Asia/Hong_Kong', labelEn: 'Asia/Hong Kong (HKT, UTC+8)', labelZh: '亚洲/香港 (UTC+8)' },\n { value: 'Asia/Taipei', labelEn: 'Asia/Taipei (CST, UTC+8)', labelZh: '亚洲/台北 (UTC+8)' },\n { value: 'Asia/Kolkata', labelEn: 'Asia/Kolkata (IST, UTC+5:30)', labelZh: '亚洲/加尔各答 (印度时间, UTC+5:30)' },\n { value: 'Asia/Dubai', labelEn: 'Asia/Dubai (GST, UTC+4)', labelZh: '亚洲/迪拜 (UTC+4)' },\n { value: 'Europe/London', labelEn: 'Europe/London (GMT/BST)', labelZh: '欧洲/伦敦 (格林尼治时间)' },\n { value: 'Europe/Paris', labelEn: 'Europe/Paris (CET, UTC+1)', labelZh: '欧洲/巴黎 (中欧时间, UTC+1)' },\n { value: 'Europe/Berlin', labelEn: 'Europe/Berlin (CET, UTC+1)', labelZh: '欧洲/柏林 (中欧时间, UTC+1)' },\n { value: 'Europe/Moscow', labelEn: 'Europe/Moscow (MSK, UTC+3)', labelZh: '欧洲/莫斯科 (UTC+3)' },\n { value: 'America/New_York', labelEn: 'America/New York (EST, UTC-5)', labelZh: '美国/纽约 (东部时间, UTC-5)' },\n { value: 'America/Chicago', labelEn: 'America/Chicago (CST, UTC-6)', labelZh: '美国/芝加哥 (中部时间, UTC-6)' },\n { value: 'America/Denver', labelEn: 'America/Denver (MST, UTC-7)', labelZh: '美国/丹佛 (山地时间, UTC-7)' },\n { value: 'America/Los_Angeles', labelEn: 'America/Los Angeles (PST, UTC-8)', labelZh: '美国/洛杉矶 (太平洋时间, UTC-8)' },\n { value: 'America/Sao_Paulo', labelEn: 'America/São Paulo (BRT, UTC-3)', labelZh: '美洲/圣保罗 (巴西时间, UTC-3)' },\n { value: 'Australia/Sydney', labelEn: 'Australia/Sydney (AEST, UTC+10)', labelZh: '澳大利亚/悉尼 (UTC+10)' },\n { value: 'Pacific/Auckland', labelEn: 'Pacific/Auckland (NZST, UTC+12)', labelZh: '太平洋/奥克兰 (新西兰时间, UTC+12)' },\n] as const;\n\n/**\n * Try to detect the user's timezone from the browser.\n */\nexport function detectBrowserTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n return '';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Vibe presets\n// ---------------------------------------------------------------------------\n\nexport const VIBE_PRESETS = [\n { value: 'warm', labelEn: 'Warm', labelZh: '温暖' },\n { value: 'sharp', labelEn: 'Sharp', labelZh: '犀利' },\n { value: 'calm', labelEn: 'Calm', labelZh: '沉稳' },\n { value: 'playful', labelEn: 'Playful', labelZh: '活泼' },\n { value: 'professional', labelEn: 'Professional', labelZh: '专业' },\n { value: 'casual', labelEn: 'Casual', labelZh: '随意' },\n { value: 'witty', labelEn: 'Witty', labelZh: '机智' },\n { value: 'concise', labelEn: 'Concise', labelZh: '简洁' },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Creature presets\n// ---------------------------------------------------------------------------\n\nexport const PRONOUNS_PRESETS = [\n { value: '先生', labelEn: 'Mr.', labelZh: '先生' },\n { value: '女士', labelEn: 'Ms.', labelZh: '女士' },\n { value: '同学', labelEn: 'Colleague', labelZh: '同学' },\n { value: '老师', labelEn: 'Teacher', labelZh: '老师' },\n { value: '老板', labelEn: 'Boss', labelZh: '老板' },\n { value: '朋友', labelEn: 'Friend', labelZh: '朋友' },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Creature presets\n// ---------------------------------------------------------------------------\n\nexport const CREATURE_PRESETS = [\n { value: 'AI assistant', labelEn: 'AI Assistant', labelZh: 'AI 助手' },\n { value: 'robot', labelEn: 'Robot', labelZh: '机器人' },\n { value: 'familiar', labelEn: 'Familiar', labelZh: '精灵' },\n { value: 'ghost in the machine', labelEn: 'Ghost in the machine', labelZh: '机器幽灵' },\n { value: 'digital companion', labelEn: 'Digital Companion', labelZh: '数字伙伴' },\n] as const;\n","import { type MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { AlertTriangle, Cog, Eye, Pencil, Sparkles, Trash2, User } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { MarkdownEditor } from '@/components/markdown/markdown-editor';\nimport { MarkdownView } from '@/components/markdown/markdown-view';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport {\n fetchAgentBootstrapFileContent,\n saveAgentBootstrapFileContent,\n} from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages, ChatMessages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { agentsSettingsInputClass } from '../utils';\nimport {\n type IdentityFields,\n type SoulTemplateId,\n parseIdentityMarkdown,\n serializeIdentityMarkdown,\n detectSoulTemplate,\n SOUL_TEMPLATES,\n CREATURE_PRESETS,\n} from '../bootstrap-parser';\n\nexport function AgentOverviewTab(props: {\n a: AgentsSettingsMessages;\n chat: ChatMessages;\n selected: GatewayAgentRow | null;\n busy: boolean;\n editName: string;\n setEditName: (v: string) => void;\n editDescription: string;\n setEditDescription: (v: string) => void;\n editWorkspace: string;\n setEditWorkspace: (v: string) => void;\n editModel: string;\n setEditModel: (v: string) => void;\n onSetDefault: () => void;\n onSaveAgentEdits: () => void;\n onDelete: (purge: boolean) => void;\n hideInlineSave?: boolean;\n /** Parent writes a save-bootstrap callback into this ref so the modal footer can trigger it. */\n saveBootstrapRef?: MutableRefObject<(() => Promise<void>) | null>;\n /** Called when bootstrap-file dirty state changes. */\n onBootstrapDirtyChange?: (dirty: boolean) => void;\n}) {\n const {\n a,\n chat,\n selected,\n busy,\n editName,\n setEditName,\n editDescription,\n setEditDescription,\n editWorkspace,\n setEditWorkspace,\n editModel,\n setEditModel,\n onSetDefault,\n onSaveAgentEdits,\n onDelete,\n hideInlineSave,\n saveBootstrapRef,\n onBootstrapDirtyChange,\n } = props;\n\n const language = useLocaleStore((s) => s.language);\n const isDark = useThemeStore((s) => s.resolved === 'dark');\n\n // ---- Bootstrap file state ----\n const [bootstrapLoading, setBootstrapLoading] = useState(true);\n const [, setBootstrapSaving] = useState(false);\n\n const [identity, setIdentity] = useState<IdentityFields>({\n name: '',\n creature: '',\n emoji: '',\n avatar: '',\n });\n const [soulTemplate, setSoulTemplate] = useState<SoulTemplateId>('professional');\n const [soulCustomContent, setSoulCustomContent] = useState('');\n const [soulEditorNonce, setSoulEditorNonce] = useState(0);\n const [soulPreviewMode, setSoulPreviewMode] = useState(false);\n\n const initialLoadDoneRef = useRef(false);\n const agentIdRef = useRef(selected?.id ?? '');\n agentIdRef.current = selected?.id ?? '';\n\n // Snapshots for dirty tracking (set after load, reset after save)\n const identitySnapshotRef = useRef('');\n const soulSnapshotRef = useRef('');\n\n // ---- Load IDENTITY.md + SOUL.md ----\n useEffect(() => {\n if (!selected) return;\n let cancelled = false;\n initialLoadDoneRef.current = false;\n setBootstrapLoading(true);\n\n const load = async () => {\n try {\n const [identityMd, soulMd] = await Promise.all([\n fetchAgentBootstrapFileContent(selected.id, 'IDENTITY.md').catch(() => ''),\n fetchAgentBootstrapFileContent(selected.id, 'SOUL.md').catch(() => ''),\n ]);\n if (cancelled) return;\n const parsedIdentity = parseIdentityMarkdown(identityMd);\n setIdentity(parsedIdentity);\n identitySnapshotRef.current = JSON.stringify(parsedIdentity);\n setSoulTemplate(detectSoulTemplate(soulMd));\n setSoulCustomContent(soulMd);\n soulSnapshotRef.current = soulMd;\n setSoulEditorNonce((n) => n + 1);\n } finally {\n if (!cancelled) {\n setBootstrapLoading(false);\n initialLoadDoneRef.current = true;\n }\n }\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [selected?.id]);\n\n // ---- Save helpers (manual save only, triggered by footer button) ----\n const saveBootstrapFile = useCallback(async (fileName: string, content: string) => {\n setBootstrapSaving(true);\n try {\n await saveAgentBootstrapFileContent(agentIdRef.current, fileName, content);\n } finally {\n setBootstrapSaving(false);\n }\n }, []);\n\n // Refs to hold latest state for the save callback\n const identityRef = useRef(identity);\n identityRef.current = identity;\n const soulContentRef = useRef(soulCustomContent);\n soulContentRef.current = soulCustomContent;\n\n // Expose save function to parent for the footer save button\n useEffect(() => {\n if (!saveBootstrapRef) return;\n saveBootstrapRef.current = async () => {\n await Promise.all([\n saveBootstrapFile('IDENTITY.md', serializeIdentityMarkdown(identityRef.current)),\n saveBootstrapFile('SOUL.md', soulContentRef.current),\n ]);\n // Reset snapshots after successful save\n identitySnapshotRef.current = JSON.stringify(identityRef.current);\n soulSnapshotRef.current = soulContentRef.current;\n // Manually notify parent since state didn't change (only snapshot did)\n onBootstrapDirtyChange?.(false);\n };\n return () => {\n saveBootstrapRef.current = null;\n };\n }, [saveBootstrapRef, saveBootstrapFile, onBootstrapDirtyChange]);\n\n // Notify parent when bootstrap dirty state changes\n useEffect(() => {\n if (!onBootstrapDirtyChange) return;\n const identityDirty = JSON.stringify(identity) !== identitySnapshotRef.current;\n const soulDirty = soulCustomContent !== soulSnapshotRef.current;\n onBootstrapDirtyChange(identityDirty || soulDirty);\n }, [identity, soulCustomContent, onBootstrapDirtyChange]);\n\n const updateIdentity = useCallback((patch: Partial<IdentityFields>) => {\n setIdentity((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const handleSoulTemplateChange = useCallback((templateId: SoulTemplateId) => {\n setSoulTemplate(templateId);\n if (templateId !== 'custom') {\n const tpl = SOUL_TEMPLATES.find((t) => t.id === templateId);\n if (tpl?.content) {\n setSoulCustomContent(tpl.content);\n setSoulEditorNonce((n) => n + 1);\n }\n }\n }, []);\n\n const handleSoulContentChange = useCallback((content: string) => {\n setSoulCustomContent(content);\n setSoulTemplate('custom');\n }, []);\n\n const locLabel = useCallback(\n (en: string, zh: string) => (language === 'zh' ? zh : en),\n [language],\n );\n\n const inputClass = agentsSettingsInputClass();\n\n if (!selected) {\n return <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>;\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-8 overflow-y-auto\">\n {/* ===== Section 1: Basic Identity ===== */}\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Sparkles}\n title={a.personaSectionIdentity}\n subtitle={a.personaSectionIdentityHint}\n trailing={\n !selected.isDefault ? (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-xs\"\n disabled={busy}\n onClick={() => void onSetDefault()}\n >\n {a.setDefault}\n </Button>\n ) : null\n }\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {/* Name — single unified field */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.displayName}</span>\n <input\n className={inputClass}\n value={editName}\n onChange={(e) => {\n setEditName(e.target.value);\n updateIdentity({ name: e.target.value });\n }}\n placeholder={a.personaNamePlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Emoji */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaEmoji}</span>\n <input\n className={inputClass}\n value={identity.emoji}\n onChange={(e) => updateIdentity({ emoji: e.target.value })}\n placeholder={a.personaEmojiPlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Description */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.agentDescription}</span>\n <textarea\n className={cn(inputClass, 'min-h-16 resize-y text-sm leading-relaxed')}\n value={editDescription}\n onChange={(e) => setEditDescription(e.target.value)}\n placeholder={a.agentDescriptionPlaceholder}\n maxLength={4000}\n rows={3}\n spellCheck\n />\n </label>\n\n {/* Creature type — dropdown */}\n <div className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaCreature}</span>\n <select\n className={inputClass}\n value={CREATURE_PRESETS.some((p) => p.value === identity.creature) ? identity.creature : '__custom__'}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n updateIdentity({ creature: '' });\n return;\n }\n updateIdentity({ creature: e.target.value });\n }}\n >\n {CREATURE_PRESETS.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {locLabel(preset.labelEn, preset.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{locLabel('Custom…', '自定义…')}</option>\n </select>\n {!CREATURE_PRESETS.some((p) => p.value === identity.creature) ? (\n <input\n className={cn(inputClass, 'mt-1 text-xs')}\n value={identity.creature}\n onChange={(e) => updateIdentity({ creature: e.target.value })}\n placeholder={a.personaCreaturePlaceholder}\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Avatar */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaAvatar}</span>\n <input\n className={cn(inputClass, 'font-mono text-xs')}\n value={identity.avatar}\n onChange={(e) => updateIdentity({ avatar: e.target.value })}\n placeholder={a.personaAvatarPlaceholder}\n autoComplete=\"off\"\n />\n </label>\n </div>\n </SettingsFormSection>\n\n {/* ===== Section 2: Runtime Configuration ===== */}\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cog} title={a.editAgent} subtitle={a.editAgentHint} />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.modelPrimary}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <ModelSelector\n className=\"min-w-0 flex-1\"\n popoverContentClassName=\"z-[70]\"\n value={editModel}\n disabled={busy}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(id) => setEditModel(id)}\n />\n {editModel.trim() ? (\n <Button type=\"button\" variant=\"secondary\" className=\"shrink-0\" disabled={busy} onClick={() => setEditModel('')}>\n {a.modelClear}\n </Button>\n ) : null}\n </div>\n </div>\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.workspacePath}</span>\n <input\n className={cn(inputClass, 'font-mono text-xs')}\n value={editWorkspace}\n onChange={(e) => setEditWorkspace(e.target.value)}\n />\n </label>\n </div>\n {!hideInlineSave ? (\n <div className=\"mt-4\">\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveAgentEdits()}>\n {a.save}\n </Button>\n </div>\n ) : null}\n </SettingsFormSection>\n\n {/* ===== Section 3: Personality & Style ===== */}\n {bootstrapLoading ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : (\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={User} title={a.personaSectionSoul} subtitle={a.personaSectionSoulHint} />\n {/* Soul template */}\n <div className=\"mb-4 flex flex-col gap-2\">\n <span className=\"text-sm font-medium text-fg\">{a.personaSoulTemplate}</span>\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-4\">\n {SOUL_TEMPLATES.map((template) => (\n <button\n key={template.id}\n type=\"button\"\n className={cn(\n 'flex flex-col items-center gap-1.5 rounded-xl border-2 px-3 py-3 text-center transition-all',\n soulTemplate === template.id\n ? 'border-accent bg-accent-soft/40 shadow-sm'\n : 'border-edge hover:border-accent/40 hover:bg-surface-hover',\n )}\n onClick={() => handleSoulTemplateChange(template.id)}\n >\n <span className=\"text-xl\">{template.emoji}</span>\n <span className=\"text-xs font-medium text-fg\">{locLabel(template.labelEn, template.labelZh)}</span>\n </button>\n ))}\n </div>\n </div>\n {soulTemplate === 'custom' ? (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-sm font-medium text-fg\">{a.personaSoulCustomEdit}</span>\n <button\n type=\"button\"\n className=\"inline-flex size-9 shrink-0 items-center justify-center rounded-md text-fg-muted transition-colors hover:bg-surface-hover hover:text-fg\"\n title={soulPreviewMode ? a.personaSoulEdit : a.personaSoulPreview}\n aria-label={soulPreviewMode ? a.personaSoulEdit : a.personaSoulPreview}\n onClick={() => setSoulPreviewMode((v) => !v)}\n >\n {soulPreviewMode ? <Pencil className=\"size-4\" aria-hidden /> : <Eye className=\"size-4\" aria-hidden />}\n </button>\n </div>\n <div className={cn(inputClass, 'flex min-h-64 flex-col overflow-hidden p-0')}>\n {soulPreviewMode ? (\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n <MarkdownView content={soulCustomContent} />\n </div>\n ) : (\n <MarkdownEditor\n key={`soul-${soulEditorNonce}`}\n initialContent={soulCustomContent}\n onChange={handleSoulContentChange}\n isDark={isDark}\n className=\"min-h-0 flex-1\"\n />\n )}\n </div>\n </div>\n ) : null}\n </SettingsFormSection>\n )}\n\n {/* ===== Section 4: Danger Zone ===== */}\n {selected.id !== 'main' ? (\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={AlertTriangle}\n title={locLabel('Danger Zone', '危险操作')}\n subtitle={locLabel(\n 'Actions that cannot be undone. Be careful.',\n '以下操作不可撤销,请谨慎操作。',\n )}\n />\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onDelete(false)}>\n <Trash2 className=\"mr-1 size-4\" aria-hidden />\n {a.removeFromConfig}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"border-red-200 text-red-700 hover:bg-red-50 dark:border-red-900/60 dark:text-red-300 dark:hover:bg-red-950/40\"\n disabled={busy}\n onClick={() => void onDelete(true)}\n >\n {a.purgeDisk}\n </Button>\n </div>\n </SettingsFormSection>\n ) : null}\n </div>\n );\n}\n","import { Info, UserCircle } from 'lucide-react';\nimport { type MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\n\nimport {\n SettingsFormSection,\n SettingsFormSectionHeader,\n} from '@/features/settings/settings-form-section';\nimport {\n fetchAgentBootstrapFileContent,\n saveAgentBootstrapFileContent,\n} from '@/features/settings/agents-admin-api';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport { agentsSettingsInputClass } from '../utils';\nimport {\n type UserFields,\n parseUserMarkdown,\n serializeUserMarkdown,\n TIMEZONE_OPTIONS,\n PRONOUNS_PRESETS,\n detectBrowserTimezone,\n} from '../bootstrap-parser';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface ProfileTabProps {\n a: AgentsSettingsMessages;\n agentId: string;\n /** Parent writes a save callback into this ref so the modal footer can trigger it. */\n saveRef?: MutableRefObject<(() => Promise<void>) | null>;\n /** Called when dirty state changes. */\n onDirtyChange?: (dirty: boolean) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component — About You (USER.md)\n// ---------------------------------------------------------------------------\n\nexport function AgentProfileTab({ a, agentId, saveRef, onDirtyChange }: ProfileTabProps) {\n const language = useLocaleStore((s) => s.language);\n\n const [loading, setLoading] = useState(true);\n const [, setSaving] = useState(false);\n\n const [user, setUser] = useState<UserFields>({\n callName: '',\n pronouns: '',\n timezone: '',\n notes: '',\n });\n\n const [showCustomPronouns, setShowCustomPronouns] = useState(false);\n const [showCustomTimezone, setShowCustomTimezone] = useState(false);\n const [customTimezone, setCustomTimezone] = useState('');\n\n const initialLoadDoneRef = useRef(false);\n const agentIdRef = useRef(agentId);\n agentIdRef.current = agentId;\n\n // Snapshot for dirty tracking (set after load, reset after save)\n const userSnapshotRef = useRef('');\n\n // ---- Save helper (manual save only, triggered by footer button) ----\n const saveFile = useCallback(async (content: string) => {\n const currentAgent = agentIdRef.current;\n setSaving(true);\n try {\n await saveAgentBootstrapFileContent(currentAgent, 'USER.md', content);\n } finally {\n setSaving(false);\n }\n }, []);\n\n // Ref to hold latest user state for the save callback\n const userRef = useRef(user);\n userRef.current = user;\n\n // Expose save function to parent for the footer save button\n useEffect(() => {\n if (!saveRef) return;\n saveRef.current = async () => {\n await saveFile(serializeUserMarkdown(userRef.current));\n userSnapshotRef.current = JSON.stringify(userRef.current);\n // Manually notify parent since state didn't change (only snapshot did)\n onDirtyChange?.(false);\n };\n return () => {\n saveRef.current = null;\n };\n }, [saveRef, saveFile, onDirtyChange]);\n\n // Notify parent when dirty state changes\n useEffect(() => {\n if (!onDirtyChange) return;\n onDirtyChange(JSON.stringify(user) !== userSnapshotRef.current);\n }, [user, onDirtyChange]);\n\n // ---- Load USER.md on mount / agentId change ----\n useEffect(() => {\n let cancelled = false;\n initialLoadDoneRef.current = false;\n setLoading(true);\n\n const load = async () => {\n try {\n const userMd = await fetchAgentBootstrapFileContent(agentId, 'USER.md').catch(() => '');\n if (cancelled) return;\n\n const parsedUser = parseUserMarkdown(userMd);\n\n // Auto-detect timezone if not already set (saved when user clicks \"Save\")\n let effectiveUser = parsedUser;\n if (!parsedUser.timezone) {\n const detected = detectBrowserTimezone();\n if (detected) {\n effectiveUser = { ...parsedUser, timezone: detected };\n }\n }\n\n setUser(effectiveUser);\n userSnapshotRef.current = JSON.stringify(effectiveUser);\n\n // Custom pronouns handling\n const isKnownPronouns = !effectiveUser.pronouns || PRONOUNS_PRESETS.some((p) => p.value === effectiveUser.pronouns);\n if (effectiveUser.pronouns && !isKnownPronouns) {\n setShowCustomPronouns(true);\n }\n\n // Custom timezone handling\n const isKnownTimezone = TIMEZONE_OPTIONS.some((tz) => tz.value === effectiveUser.timezone);\n if (effectiveUser.timezone && !isKnownTimezone) {\n setShowCustomTimezone(true);\n setCustomTimezone(effectiveUser.timezone);\n }\n } finally {\n if (!cancelled) {\n setLoading(false);\n initialLoadDoneRef.current = true;\n }\n }\n };\n\n void load();\n return () => {\n cancelled = true;\n };\n }, [agentId]);\n\n // ---- Field updater (local state only, saved via footer button) ----\n const updateUser = useCallback((patch: Partial<UserFields>) => {\n setUser((prev) => ({ ...prev, ...patch }));\n }, []);\n\n // ---- Timezone handling ----\n const handleTimezoneChange = useCallback(\n (value: string) => {\n if (value === '__custom__') {\n setShowCustomTimezone(true);\n return;\n }\n setShowCustomTimezone(false);\n setCustomTimezone('');\n updateUser({ timezone: value });\n },\n [updateUser],\n );\n\n const handleCustomTimezoneChange = useCallback(\n (value: string) => {\n setCustomTimezone(value);\n updateUser({ timezone: value });\n },\n [updateUser],\n );\n\n const handleDetectTimezone = useCallback(() => {\n const detected = detectBrowserTimezone();\n if (detected) {\n const isKnown = TIMEZONE_OPTIONS.some((tz) => tz.value === detected);\n if (isKnown) {\n setShowCustomTimezone(false);\n setCustomTimezone('');\n } else {\n setShowCustomTimezone(true);\n setCustomTimezone(detected);\n }\n updateUser({ timezone: detected });\n }\n }, [updateUser]);\n\n // ---- Effective timezone for select ----\n const timezoneSelectValue = (() => {\n if (showCustomTimezone) return '__custom__';\n const isKnown = TIMEZONE_OPTIONS.some((tz) => tz.value === user.timezone);\n return isKnown ? user.timezone : '__custom__';\n })();\n\n const locLabel = useCallback(\n (en: string, zh: string) => (language === 'zh' ? zh : en),\n [language],\n );\n\n if (loading) {\n return <p className=\"text-sm text-fg-muted\">{a.loading}</p>;\n }\n\n const inputClass = agentsSettingsInputClass();\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto\">\n <p className=\"text-sm text-fg-muted\">{a.personaSectionUserHint}</p>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={UserCircle}\n title={a.personaSectionUser}\n subtitle={a.personaSectionUserHint}\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {/* Call name */}\n <label className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaCallName}</span>\n <input\n className={inputClass}\n value={user.callName}\n onChange={(e) => updateUser({ callName: e.target.value })}\n placeholder={a.personaCallNamePlaceholder}\n autoComplete=\"off\"\n />\n </label>\n\n {/* Pronouns */}\n <div className=\"flex flex-col gap-1.5 text-sm\">\n <span className=\"font-medium text-fg\">{a.personaPronouns}</span>\n <select\n className={inputClass}\n value={PRONOUNS_PRESETS.some((p) => p.value === user.pronouns) ? user.pronouns : '__custom__'}\n onChange={(e) => {\n if (e.target.value === '__custom__') {\n setShowCustomPronouns(true);\n return;\n }\n setShowCustomPronouns(false);\n updateUser({ pronouns: e.target.value });\n }}\n >\n <option value=\"\" disabled>\n {a.personaPronounsPlaceholder}\n </option>\n {PRONOUNS_PRESETS.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {locLabel(preset.labelEn, preset.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{locLabel('Custom…', '自定义…')}</option>\n </select>\n {showCustomPronouns ? (\n <input\n className={cn(inputClass, 'mt-1 text-xs')}\n value={PRONOUNS_PRESETS.some((p) => p.value === user.pronouns) ? '' : user.pronouns}\n onChange={(e) => updateUser({ pronouns: e.target.value })}\n placeholder={a.personaPronounsPlaceholder}\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Timezone */}\n <div className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaTimezone}</span>\n <div className=\"flex flex-wrap items-stretch gap-2\">\n <select\n className={cn(inputClass, 'min-w-0 flex-1')}\n value={timezoneSelectValue}\n onChange={(e) => handleTimezoneChange(e.target.value)}\n >\n {TIMEZONE_OPTIONS.map((tz) => (\n <option key={tz.value} value={tz.value}>\n {locLabel(tz.labelEn, tz.labelZh)}\n </option>\n ))}\n <option value=\"__custom__\">{a.personaTimezoneCustom}</option>\n </select>\n <button\n type=\"button\"\n className=\"shrink-0 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-xs font-medium text-fg-muted hover:bg-surface-hover hover:text-fg\"\n onClick={handleDetectTimezone}\n >\n {a.personaTimezoneDetect}\n </button>\n </div>\n {showCustomTimezone ? (\n <input\n className={cn(inputClass, 'mt-1 font-mono text-xs')}\n value={customTimezone}\n onChange={(e) => handleCustomTimezoneChange(e.target.value)}\n placeholder=\"e.g. Asia/Shanghai\"\n autoComplete=\"off\"\n />\n ) : null}\n </div>\n\n {/* Notes */}\n <label className=\"flex flex-col gap-1.5 text-sm sm:col-span-2\">\n <span className=\"font-medium text-fg\">{a.personaNotes}</span>\n <textarea\n className={cn(inputClass, 'min-h-16 resize-y text-sm leading-relaxed')}\n value={user.notes}\n onChange={(e) => updateUser({ notes: e.target.value })}\n placeholder={a.personaNotesPlaceholder}\n rows={3}\n spellCheck\n />\n </label>\n </div>\n\n {/* Memory note */}\n <div className=\"mt-3 flex items-start gap-2 rounded-lg bg-accent-soft/30 px-3 py-2.5 text-xs text-fg-muted\">\n <Info className=\"mt-0.5 size-3.5 shrink-0 text-accent\" aria-hidden />\n <span>{a.personaMemoryNote}</span>\n </div>\n </SettingsFormSection>\n </div>\n );\n}\n","import { BookOpen } from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\nimport { Link } from 'react-router-dom';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayAgentRow, SkillCatalogRow } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentSkillsTab(props: {\n a: AgentsSettingsMessages;\n selected: GatewayAgentRow;\n busy: boolean;\n skillsCatalogLoading: boolean;\n catalogForPick: SkillCatalogRow[];\n skillsInherit: boolean;\n setSkillsInherit: (v: boolean) => void;\n skillsPick: Set<string>;\n setSkillsPick: Dispatch<SetStateAction<Set<string>>>;\n onSaveSkills: () => void;\n hideInlineSave?: boolean;\n}) {\n const {\n a,\n selected,\n busy,\n skillsCatalogLoading,\n catalogForPick,\n skillsInherit,\n setSkillsInherit,\n skillsPick,\n setSkillsPick,\n onSaveSkills,\n hideInlineSave,\n } = props;\n\n /** When inheriting defaults, checkboxes reflect the effective allowlist (undefined = all catalog skills). */\n function isCheckedInheritMode(id: string): boolean {\n const eff = selected.skills.effectiveAllowlist;\n if (eff === undefined) {\n return true;\n }\n if (eff.length === 0) {\n return false;\n }\n return eff.includes(id);\n }\n\n function initialPickForCustomize(): Set<string> {\n const eff = selected.skills.effectiveAllowlist;\n if (eff !== undefined) {\n return new Set(eff);\n }\n return new Set(catalogForPick.map((s) => s.name || s.directoryId));\n }\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={BookOpen}\n title={a.skillsTitle}\n subtitle={a.skillsHint}\n />\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-3\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => setSkillsInherit(true)}>\n {a.skillsInherit}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={busy}\n onClick={() => {\n setSkillsInherit(false);\n setSkillsPick(initialPickForCustomize());\n }}\n >\n {a.skillsCustomize}\n </Button>\n </div>\n <Link\n to=\"/skills\"\n className=\"shrink-0 text-xs font-medium text-accent-fg hover:underline\"\n >\n {a.skillsLibraryLink}\n </Link>\n </div>\n <p className=\"mt-2 shrink-0 text-xs text-fg-muted\">\n {a.skillsDefaultsLabel} {selected.skills.defaults.length ? selected.skills.defaults.join(', ') : '—'}\n </p>\n <p className=\"shrink-0 text-xs text-fg-muted\">\n {a.skillsEffectiveLabel}{' '}\n {selected.skills.effectiveAllowlist?.length\n ? selected.skills.effectiveAllowlist.join(', ')\n : a.skillsAllFromCatalog}\n </p>\n {skillsCatalogLoading ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.skillsCatalogLoading}</p>\n ) : catalogForPick.length === 0 ? (\n <p className=\"shrink-0 text-sm text-fg-muted\">{a.skillsEmptyCatalog}</p>\n ) : (\n <div\n className={cn(\n 'mt-3 min-h-0 flex-1 overflow-y-auto overscroll-contain pr-0.5',\n skillsInherit && 'opacity-50',\n )}\n >\n <ul className=\"flex flex-col gap-2.5 text-sm\" role=\"list\">\n {catalogForPick.map((s) => {\n const id = s.name || s.directoryId;\n const on = skillsInherit ? isCheckedInheritMode(id) : skillsPick.has(id);\n const desc = typeof s.description === 'string' ? s.description.trim() : '';\n const descLine = desc || a.skillsNoDescription;\n return (\n <li\n key={id}\n className=\"h-16 shrink-0 overflow-hidden rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 dark:border-edge-subtle\"\n >\n <label className=\"flex h-full cursor-pointer items-center gap-3 text-sm\">\n <input\n type=\"checkbox\"\n className=\"shrink-0 rounded border-edge\"\n checked={on}\n disabled={skillsInherit || busy}\n onChange={() => {\n setSkillsPick((prev) => {\n const next = new Set(prev);\n if (on) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }}\n />\n <div className=\"min-w-0 flex-1 overflow-hidden\">\n <div className=\"truncate font-mono text-xs font-medium text-fg\" title={id}>\n {id}\n </div>\n <p\n className={cn(\n 'mt-0.5 truncate text-xs leading-tight text-fg-muted',\n !desc && 'italic text-fg-subtle',\n )}\n title={descLine}\n >\n {descLine}\n </p>\n </div>\n </label>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n {!hideInlineSave ? (\n <div className=\"mt-4 shrink-0\">\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveSkills()}>\n {a.skillsSave}\n </Button>\n </div>\n ) : null}\n </SettingsFormSection>\n );\n}\n","import { Wrench } from 'lucide-react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport type { GatewayAgentRow } from '@/features/settings/agents-admin-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { AgentsSettingsMessages } from '@/i18n/messages';\n\nexport function AgentToolsTab(props: {\n a: AgentsSettingsMessages;\n data: { builtinToolIds: string[] };\n selected: GatewayAgentRow;\n busy: boolean;\n toolEntryDisable: Set<string>;\n setToolEntryDisable: Dispatch<SetStateAction<Set<string>>>;\n onSaveTools: () => void;\n onClearToolsEntry: () => void;\n hideInlineSave?: boolean;\n}) {\n const {\n a,\n data,\n selected,\n busy,\n toolEntryDisable,\n setToolEntryDisable,\n onSaveTools,\n onClearToolsEntry,\n hideInlineSave,\n } = props;\n\n return (\n <SettingsFormSection className=\"flex min-h-0 flex-1 flex-col\">\n <SettingsFormSectionHeader\n className=\"shrink-0\"\n icon={Wrench}\n title={a.toolsTitle}\n subtitle={a.toolsHint}\n />\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n <ul className=\"flex flex-col gap-2.5 pr-1\" role=\"list\">\n {(data.builtinToolIds.length ? data.builtinToolIds : []).map((tid) => {\n const disabledByDefault = selected.tools.defaultsDisable.includes(tid);\n const checked = disabledByDefault ? false : !toolEntryDisable.has(tid);\n const desc =\n tid in a.toolDescriptions ? a.toolDescriptions[tid as keyof typeof a.toolDescriptions] : '';\n return (\n <li\n key={tid}\n className={cn(\n 'rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-2.5 dark:border-edge-subtle',\n disabledByDefault && 'opacity-60',\n )}\n >\n <label\n className={cn('flex cursor-pointer gap-3 text-sm', disabledByDefault && 'cursor-not-allowed')}\n >\n <input\n type=\"checkbox\"\n className=\"mt-1 shrink-0 rounded border-edge\"\n checked={checked}\n disabled={disabledByDefault || busy}\n onChange={() => {\n if (disabledByDefault) {\n return;\n }\n setToolEntryDisable((prev) => {\n const next = new Set(prev);\n if (next.has(tid)) {\n next.delete(tid);\n } else {\n next.add(tid);\n }\n return next;\n });\n }}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span className=\"font-mono text-xs font-medium text-fg\">{tid}</span>\n {disabledByDefault ? (\n <span className=\"text-xs text-fg-muted\">({a.toolsLockedByDefaults})</span>\n ) : null}\n </div>\n {desc ? <p className=\"mt-1 text-xs leading-relaxed text-fg-muted\">{desc}</p> : null}\n </div>\n </label>\n </li>\n );\n })}\n </ul>\n </div>\n <div className=\"mt-4 flex shrink-0 flex-wrap gap-2\">\n {!hideInlineSave ? (\n <Button type=\"button\" disabled={busy} onClick={() => void onSaveTools()}>\n {a.toolsSave}\n </Button>\n ) : null}\n <Button type=\"button\" variant=\"secondary\" disabled={busy} onClick={() => void onClearToolsEntry()}>\n {a.toolsClearEntry}\n </Button>\n </div>\n </SettingsFormSection>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { Plus, Search, SlidersHorizontal } from 'lucide-react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type FormEvent } from 'react';\nimport { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';\nimport useSWR from 'swr';\nimport { useDebouncedCallback } from 'use-debounce';\n\nimport { Button } from '@/components/ui/button';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n createGatewayAgent,\n deleteGatewayAgent,\n fetchAgentBootstrapFileContent,\n fetchAgentBootstrapFiles,\n fetchGatewayAgents,\n parseGatewayBindingsFromConfig,\n fetchSkillsCatalog,\n patchGatewayBindings,\n saveAgentBootstrapFileContent,\n updateGatewayAgent,\n type GatewayAgentRow,\n type GatewayAgentsPayload,\n type GatewayConfigBinding,\n type SkillCatalogRow,\n} from '@/features/settings/agents-admin-api';\nimport { AGENTS_APP_LIST_PATH, agentsAppDetailPath } from '@/features/settings/agents/agents-app-path';\nimport { SETTINGS_BACK_PATH_STATE_KEY } from '@/features/settings/settings-nav-state';\nimport { suggestWorkspaceFromAgentName } from '@/features/settings/suggest-agent-workspace';\nimport { validateAgentIdForNewAgent } from '@/lib/agent-id';\nimport {\n getChannels,\n getSessionChatIds,\n listJobs,\n updateJob,\n type ChannelStatus,\n type CronJob,\n type SessionChatId,\n} from '@/features/cron/cron-api';\nimport { messages } from '@/i18n/messages';\nimport { cn } from '@/lib/cn';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\nimport { usePageHeaderStore } from '@/stores/page-header-store';\n\nimport { AgentsEditorModal } from './agents-editor-modal';\nimport { AgentsListGrid } from './agents-list-grid';\nimport { AgentsSettingsHeader } from './agents-settings-header';\nimport { CreateAgentDialog } from './create-agent-dialog';\nimport { AgentChannelsTab } from './tabs/agent-channels-tab';\nimport { AgentCronTab } from './tabs/agent-cron-tab';\nimport { AgentFilesTab } from './tabs/agent-files-tab';\nimport { AgentOverviewTab } from './tabs/agent-overview-tab';\nimport { AgentProfileTab } from './tabs/agent-profile-tab';\nimport { AgentSkillsTab } from './tabs/agent-skills-tab';\nimport { AgentToolsTab } from './tabs/agent-tools-tab';\nimport type { AgentPanel } from './utils';\nimport { buildNewBindingMatch, jobMatchesAgent } from './utils';\n\nexport function AgentsSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.agentsSettings;\n\n const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);\n const [deleteTarget, setDeleteTarget] = useState<GatewayAgentRow | null>(null);\n const [deletePurge, setDeletePurge] = useState(false);\n const [deleteConfirmText, setDeleteConfirmText] = useState('');\n const cCron = m.cron;\n const chat = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const [searchParams] = useSearchParams();\n const navigate = useNavigate();\n const { agentId: routeAgentId } = useParams<{ agentId?: string }>();\n const setPageHeader = usePageHeaderStore((s) => s.setPageHeader);\n const clearPageHeader = usePageHeaderStore((s) => s.clearPageHeader);\n\n const agentsSwrKey = hasToken ? 'settings-gateway-agents' : null;\n const {\n data: swrAgentsData,\n error: swrAgentsError,\n isLoading: agentsLoading,\n mutate: mutateAgents,\n } = useSWR(agentsSwrKey, fetchGatewayAgents, { revalidateOnFocus: false });\n\n const { data: gatewayCfgData } = useGatewayConfigSwr(hasToken);\n\n const bindingsFromConfig = useMemo(\n () => parseGatewayBindingsFromConfig(gatewayCfgData?.payload?.config ?? {}),\n [gatewayCfgData],\n );\n\n const data: GatewayAgentsPayload | null = swrAgentsData ?? null;\n const loading = Boolean(hasToken && agentsLoading);\n const [error, setError] = useState<string | null>(null);\n const loadError =\n swrAgentsError instanceof Error ? swrAgentsError.message : swrAgentsError ? a.loadError : null;\n const displayError = error ?? loadError;\n\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [panel, setPanel] = useState<AgentPanel>('overview');\n\n const [createDisplayName, setCreateDisplayName] = useState('');\n const [createAgentId, setCreateAgentId] = useState('');\n const [createDescription, setCreateDescription] = useState('');\n const [createWorkspace, setCreateWorkspace] = useState('');\n const [createModel, setCreateModel] = useState('');\n const [createModalError, setCreateModalError] = useState<string | null>(null);\n const [addAgentModalOpen, setAddAgentModalOpen] = useState(false);\n const createWorkspaceSuggestedRef = useRef('');\n const [busy, setBusy] = useState(false);\n const [listSearchQuery, setListSearchQuery] = useState('');\n\n const [editWorkspace, setEditWorkspace] = useState('');\n const [editModel, setEditModel] = useState('');\n const [editName, setEditName] = useState('');\n const [editDescription, setEditDescription] = useState('');\n\n const [files, setFiles] = useState<Awaited<ReturnType<typeof fetchAgentBootstrapFiles>> | null>(null);\n const [filesLoading, setFilesLoading] = useState(false);\n const [activeFile, setActiveFile] = useState<string | null>(null);\n const [fileDraft, setFileDraft] = useState('');\n const [fileSaving, setFileSaving] = useState(false);\n const [bootstrapViewMode, setBootstrapViewMode] = useState<'edit' | 'preview'>('edit');\n const [bootstrapFileLoading, setBootstrapFileLoading] = useState(false);\n const [bootstrapEditorNonce, setBootstrapEditorNonce] = useState(0);\n\n const fileDraftRef = useRef(fileDraft);\n fileDraftRef.current = fileDraft;\n const selectedIdRef = useRef(selectedId);\n selectedIdRef.current = selectedId;\n const activeFileRef = useRef(activeFile);\n activeFileRef.current = activeFile;\n const overviewSaveBootstrapRef = useRef<(() => Promise<void>) | null>(null);\n const profileSaveRef = useRef<(() => Promise<void>) | null>(null);\n const [overviewBootstrapDirty, setOverviewBootstrapDirty] = useState(false);\n const [profileDirty, setProfileDirty] = useState(false);\n const [savedFlash, setSavedFlash] = useState(false);\n const bootstrapFileKeyRef = useRef('');\n const bootstrapSyncedRef = useRef('');\n\n const saveBootstrapDebounced = useDebouncedCallback(\n async () => {\n const sid = selectedIdRef.current;\n const name = activeFileRef.current;\n if (!sid || !name) {\n return;\n }\n const key = `${sid}:${name}`;\n if (key !== bootstrapFileKeyRef.current) {\n return;\n }\n const draft = fileDraftRef.current;\n if (draft === bootstrapSyncedRef.current) {\n return;\n }\n setFileSaving(true);\n setError(null);\n try {\n await saveAgentBootstrapFileContent(sid, name, draft);\n bootstrapSyncedRef.current = draft;\n setFiles((prev) => {\n if (!prev || prev.agentId !== sid) {\n return prev;\n }\n return {\n ...prev,\n files: prev.files.map((f) => (f.name === name ? { ...f, missing: false } : f)),\n };\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setFileSaving(false);\n }\n },\n 800,\n );\n\n const flushBootstrapSaveRef = useRef(saveBootstrapDebounced.flush);\n flushBootstrapSaveRef.current = saveBootstrapDebounced.flush;\n\n useEffect(() => {\n return () => {\n flushBootstrapSaveRef.current();\n };\n }, []);\n\n const [toolEntryDisable, setToolEntryDisable] = useState<Set<string>>(() => new Set());\n const [skillsPick, setSkillsPick] = useState<Set<string>>(() => new Set());\n const [skillsInherit, setSkillsInherit] = useState(true);\n\n const [allBindings, setAllBindings] = useState<GatewayConfigBinding[]>([]);\n const [newBindChannel, setNewBindChannel] = useState('');\n const [bindChannelStatuses, setBindChannelStatuses] = useState<ChannelStatus[]>([]);\n const [bindChannelsLoading, setBindChannelsLoading] = useState(false);\n const [bindSessionChats, setBindSessionChats] = useState<SessionChatId[]>([]);\n const [bindSessionsLoading, setBindSessionsLoading] = useState(false);\n const [newBindSessionIdx, setNewBindSessionIdx] = useState<number | null>(null);\n const [newBindCustomPeer, setNewBindCustomPeer] = useState('');\n\n const [cronJobs, setCronJobs] = useState<CronJob[]>([]);\n const [cronLoading, setCronLoading] = useState(false);\n\n const [skillCatalog, setSkillCatalog] = useState<SkillCatalogRow[]>([]);\n const [skillsCatalogLoading, setSkillsCatalogLoading] = useState(false);\n\n useEffect(() => {\n if (!data) {\n return;\n }\n if (routeAgentId && data.agents.some((x) => x.id === routeAgentId)) {\n setSelectedId(routeAgentId);\n return;\n }\n setSelectedId((prev) => {\n if (prev && data.agents.some((x) => x.id === prev)) {\n return prev;\n }\n return data.defaultId;\n });\n }, [data, routeAgentId]);\n\n useEffect(() => {\n if (!data || !routeAgentId) {\n return;\n }\n if (!data.agents.some((x) => x.id === routeAgentId)) {\n navigate(AGENTS_APP_LIST_PATH, { replace: true });\n }\n }, [data, routeAgentId, navigate]);\n\n useEffect(() => {\n if (routeAgentId) {\n setPanel('overview');\n }\n }, [routeAgentId]);\n\n useEffect(() => {\n if (searchParams.get('panel') !== 'defaults') {\n return;\n }\n navigate('/settings/agent-defaults', {\n replace: true,\n state: { [SETTINGS_BACK_PATH_STATE_KEY]: AGENTS_APP_LIST_PATH },\n });\n }, [searchParams, navigate]);\n\n const selected = useMemo(\n () => data?.agents.find((x) => x.id === selectedId) ?? null,\n [data, selectedId],\n );\n\n const agentBindings = useMemo(() => {\n if (!selected) {\n return [];\n }\n return allBindings.filter((b) => b.agentId.toLowerCase() === selected.id.toLowerCase());\n }, [allBindings, selected?.id]);\n\n const agentCronJobs = useMemo(() => {\n if (!data || !selected) {\n return [];\n }\n return cronJobs.filter((j) => jobMatchesAgent(j, selected.id, data.defaultId));\n }, [cronJobs, data, selected?.id]);\n\n const catalogForPick = useMemo(\n () => skillCatalog.filter((s) => s.enabled !== false),\n [skillCatalog],\n );\n\n useEffect(() => {\n if (!selected) {\n setEditWorkspace('');\n setEditModel('');\n setEditName('');\n setEditDescription('');\n return;\n }\n setEditWorkspace(selected.workspace);\n setEditModel(selected.model?.primary ?? '');\n setEditName(selected.name?.trim() ? selected.name.trim() : selected.id);\n setEditDescription(selected.description?.trim() ?? '');\n }, [selected?.id]);\n\n useEffect(() => {\n if (panel !== 'files' || !selectedId || !hasToken) {\n return;\n }\n let cancelled = false;\n setFilesLoading(true);\n void fetchAgentBootstrapFiles(selectedId)\n .then((f) => {\n if (!cancelled) {\n setFiles(f);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setFiles(null);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setFilesLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, selectedId, hasToken, data?.agents.length]);\n\n useEffect(() => {\n if (!selected || panel !== 'tools') {\n return;\n }\n setToolEntryDisable(new Set(selected.tools.entryDisable));\n }, [panel, selected]);\n\n useEffect(() => {\n if (!selected || panel !== 'skills') {\n return;\n }\n const inherit = selected.skills.entry === undefined;\n setSkillsInherit(inherit);\n if (inherit) {\n const eff = selected.skills.effectiveAllowlist;\n setSkillsPick(new Set(eff ?? []));\n } else {\n setSkillsPick(new Set(selected.skills.entry ?? []));\n }\n }, [panel, selected]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n setAllBindings(bindingsFromConfig);\n }, [panel, hasToken, bindingsFromConfig]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n let cancelled = false;\n setBindChannelsLoading(true);\n void getChannels()\n .then((list) => {\n if (!cancelled) {\n setBindChannelStatuses(list);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setBindChannelStatuses([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBindChannelsLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (bindChannelsLoading || panel !== 'channels' || bindChannelStatuses.length === 0) {\n return;\n }\n setNewBindChannel((prev) => {\n const valid = Boolean(prev) && bindChannelStatuses.some((c) => c.name === prev);\n if (valid) {\n return prev;\n }\n return bindChannelStatuses[0].name;\n });\n }, [bindChannelsLoading, panel, bindChannelStatuses]);\n\n useEffect(() => {\n if (panel !== 'channels' || !hasToken) {\n return;\n }\n const ch = newBindChannel.trim();\n if (!ch) {\n setBindSessionChats([]);\n return;\n }\n let cancelled = false;\n setNewBindSessionIdx(null);\n setBindSessionsLoading(true);\n void getSessionChatIds(ch)\n .then((ids) => {\n if (!cancelled) {\n setBindSessionChats(ids);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setBindSessionChats([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBindSessionsLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken, newBindChannel]);\n\n const refreshBindSessions = useCallback(() => {\n const ch = newBindChannel.trim();\n if (!ch) {\n return;\n }\n setBindSessionsLoading(true);\n void getSessionChatIds(ch)\n .then((ids) => {\n setBindSessionChats(ids);\n setNewBindSessionIdx((i) => (i != null && i < ids.length ? i : null));\n })\n .catch(() => {\n setBindSessionChats([]);\n setNewBindSessionIdx(null);\n })\n .finally(() => {\n setBindSessionsLoading(false);\n });\n }, [newBindChannel]);\n\n const useManualChannel = !bindChannelsLoading && bindChannelStatuses.length === 0;\n\n const bindingsLoading = panel === 'channels' && hasToken && gatewayCfgData === undefined;\n\n useEffect(() => {\n if (panel !== 'cron' || !hasToken) {\n return;\n }\n let cancelled = false;\n setCronLoading(true);\n void listJobs()\n .then((j) => {\n if (!cancelled) {\n setCronJobs(j);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setCronJobs([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setCronLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (panel !== 'skills' || !hasToken) {\n return;\n }\n let cancelled = false;\n setSkillsCatalogLoading(true);\n void fetchSkillsCatalog()\n .then((rows) => {\n if (!cancelled) {\n setSkillCatalog(rows);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setSkillCatalog([]);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setSkillsCatalogLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [panel, hasToken]);\n\n useEffect(() => {\n if (!activeFile || !selectedId || !hasToken) {\n return;\n }\n let cancelled = false;\n saveBootstrapDebounced.flush();\n setBootstrapFileLoading(true);\n void fetchAgentBootstrapFileContent(selectedId, activeFile)\n .then((c) => {\n if (cancelled) {\n return;\n }\n const key = `${selectedId}:${activeFile}`;\n bootstrapFileKeyRef.current = key;\n bootstrapSyncedRef.current = c;\n setFileDraft(c);\n setBootstrapEditorNonce((n) => n + 1);\n })\n .catch(() => {\n if (!cancelled) {\n const key = `${selectedId}:${activeFile}`;\n bootstrapFileKeyRef.current = key;\n bootstrapSyncedRef.current = '';\n setFileDraft('');\n setBootstrapEditorNonce((n) => n + 1);\n }\n })\n .finally(() => {\n if (!cancelled) {\n setBootstrapFileLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [activeFile, selectedId, hasToken, saveBootstrapDebounced]);\n\n useEffect(() => {\n if (!activeFile || !selectedId || bootstrapFileLoading) {\n return;\n }\n saveBootstrapDebounced();\n }, [fileDraft, activeFile, selectedId, bootstrapFileLoading, saveBootstrapDebounced]);\n\n useEffect(() => {\n if (panel !== 'files') {\n return;\n }\n return () => {\n saveBootstrapDebounced.flush();\n };\n }, [panel, saveBootstrapDebounced]);\n\n useEffect(() => {\n setBootstrapViewMode('edit');\n }, [activeFile, selectedId]);\n\n const applyCreateWorkspaceSuggestion = useCallback(() => {\n const next = suggestWorkspaceFromAgentName(createAgentId.trim() || createDisplayName);\n setCreateWorkspace((prev) => {\n if (prev === '' || prev === createWorkspaceSuggestedRef.current) {\n createWorkspaceSuggestedRef.current = next;\n return next;\n }\n return prev;\n });\n }, [createAgentId, createDisplayName]);\n\n const openAddAgentModal = useCallback(() => {\n createWorkspaceSuggestedRef.current = '';\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n setAddAgentModalOpen(true);\n }, []);\n\n const globalDefaultsTitle = m.settingsSections['agent-defaults'];\n\n const agentsHeaderEnd = useMemo(\n () => (\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center justify-end gap-2\">\n <Button asChild variant=\"secondary\" className=\"shrink-0 gap-2\">\n <Link\n to=\"/settings/agent-defaults\"\n title={globalDefaultsTitle}\n state={{ [SETTINGS_BACK_PATH_STATE_KEY]: AGENTS_APP_LIST_PATH }}\n >\n <SlidersHorizontal className=\"size-4 shrink-0\" strokeWidth={1.75} aria-hidden />\n {globalDefaultsTitle}\n </Link>\n </Button>\n <label className=\"relative flex min-h-9 min-w-0 max-w-sm cursor-text items-center rounded-pill border border-edge bg-surface-base py-1.5 pl-9 pr-3 shadow-surface dark:bg-surface-hover/40 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-disabled\"\n strokeWidth={1.75}\n aria-hidden\n />\n <input\n type=\"search\"\n role=\"searchbox\"\n enterKeyHint=\"search\"\n value={listSearchQuery}\n onChange={(e) => setListSearchQuery(e.target.value)}\n placeholder={a.listSearchPlaceholder}\n autoComplete=\"off\"\n spellCheck={false}\n aria-label={a.listSearchPlaceholder}\n className=\"min-w-0 flex-1 appearance-none border-0 bg-transparent py-0.5 text-sm leading-normal text-fg caret-current placeholder:text-fg-disabled focus:border-0 focus:shadow-none focus:outline-none focus:ring-0 focus-visible:outline-none\"\n />\n </label>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"shrink-0 gap-2\"\n aria-label={a.addAgentAria}\n disabled={busy}\n onClick={() => openAddAgentModal()}\n >\n <Plus className=\"size-4\" strokeWidth={1.75} aria-hidden />\n {a.addAgent}\n </Button>\n </div>\n ),\n [\n a.addAgent,\n a.addAgentAria,\n a.listSearchPlaceholder,\n busy,\n globalDefaultsTitle,\n listSearchQuery,\n openAddAgentModal,\n ],\n );\n\n useLayoutEffect(() => {\n if (!hasToken) {\n clearPageHeader();\n return () => clearPageHeader();\n }\n setPageHeader({\n startExtra: null,\n main: null,\n end: agentsHeaderEnd,\n });\n return () => clearPageHeader();\n }, [agentsHeaderEnd, clearPageHeader, hasToken, setPageHeader]);\n\n async function onCreate(e: FormEvent) {\n e.preventDefault();\n const name = createDisplayName.trim();\n if (!name) {\n return;\n }\n const idRes = validateAgentIdForNewAgent(createAgentId, name);\n if (idRes.ok === false) {\n setCreateModalError(idRes.error);\n return;\n }\n const wsInput = createWorkspace.trim();\n const workspace = wsInput || suggestWorkspaceFromAgentName(createAgentId.trim() || name);\n if (!workspace) {\n return;\n }\n setBusy(true);\n setCreateModalError(null);\n try {\n const desc = createDescription.trim();\n const next = await createGatewayAgent({\n name,\n workspace,\n ...(createAgentId.trim() ? { id: createAgentId.trim() } : {}),\n ...(createModel.trim() ? { model: createModel.trim() } : {}),\n ...(desc ? { description: desc } : {}),\n });\n const { createdAgentId, ...agentsPayload } = next;\n void mutateAgents(agentsPayload, { revalidate: false });\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n setAddAgentModalOpen(false);\n setSelectedId(createdAgentId);\n navigate(agentsAppDetailPath(createdAgentId));\n } catch (err) {\n setCreateModalError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSaveAgentEdits() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const descTrim = editDescription.trim();\n const next = await updateGatewayAgent(selected.id, {\n name: editName.trim() || undefined,\n description: descTrim.length > 0 ? descTrim : null,\n workspace: editWorkspace.trim() || undefined,\n model: editModel.trim() || null,\n });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSetDefault(agent: GatewayAgentRow) {\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(agent.id, { setDefault: true });\n void mutateAgents(next, { revalidate: false });\n setSelectedId(agent.id);\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function performDelete(agent: GatewayAgentRow, purge: boolean) {\n setBusy(true);\n setError(null);\n try {\n const next = await deleteGatewayAgent(agent.id, purge);\n void mutateAgents(next, { revalidate: false });\n setSelectedId(next.defaultId);\n setPanel('overview');\n if (routeAgentId === agent.id) {\n navigate(AGENTS_APP_LIST_PATH, { replace: true });\n }\n setDeleteDialogOpen(false);\n setDeleteTarget(null);\n setDeleteConfirmText('');\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n function onDelete(agent: GatewayAgentRow, purge: boolean) {\n if (agent.id === 'main') {\n return;\n }\n setDeleteTarget(agent);\n setDeletePurge(purge);\n setDeleteConfirmText('');\n setDeleteDialogOpen(true);\n }\n\n async function onSaveTools() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const toolsDisable = [...toolEntryDisable].sort((x, y) => x.localeCompare(y));\n const next = await updateGatewayAgent(selected.id, { toolsDisable });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onClearToolsEntry() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(selected.id, { toolsDisable: null });\n void mutateAgents(next, { revalidate: false });\n setToolEntryDisable(new Set());\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSaveSkills() {\n if (!selected) {\n return;\n }\n setBusy(true);\n setError(null);\n try {\n const next = await updateGatewayAgent(selected.id, {\n skills: skillsInherit ? null : [...skillsPick].sort((x, y) => x.localeCompare(y)),\n });\n void mutateAgents(next, { revalidate: false });\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onRemoveBinding(rule: GatewayConfigBinding) {\n setBusy(true);\n setError(null);\n try {\n const nextList = allBindings.filter((b) => b !== rule);\n await patchGatewayBindings(nextList);\n setAllBindings(nextList);\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onAddBinding(e: FormEvent) {\n e.preventDefault();\n if (!selected || !newBindChannel.trim()) {\n return;\n }\n const match = buildNewBindingMatch(\n newBindChannel,\n newBindCustomPeer,\n newBindSessionIdx,\n bindSessionChats,\n );\n const nextList = [\n ...allBindings,\n {\n agentId: selected.id,\n priority: 100,\n enabled: true,\n match,\n },\n ];\n setBusy(true);\n setError(null);\n try {\n await patchGatewayBindings(nextList);\n setAllBindings(nextList);\n setNewBindSessionIdx(null);\n setNewBindCustomPeer('');\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n async function onSetCronJobAgent(job: CronJob, agentKey: string) {\n setBusy(true);\n setError(null);\n try {\n await updateJob(job.id, { agentId: agentKey === '' ? null : agentKey });\n setCronJobs(await listJobs());\n } catch (err) {\n setError(err instanceof Error ? err.message : a.saveError);\n } finally {\n setBusy(false);\n }\n }\n\n const footerSaveNotApplicable = panel === 'channels' || panel === 'cron';\n\n // Compute whether overview REST fields have changed compared to the loaded agent\n const overviewRestDirty = (() => {\n if (!selected || panel !== 'overview') return false;\n const origName = selected.name?.trim() || selected.id;\n const origDesc = selected.description?.trim() ?? '';\n const origWorkspace = selected.workspace;\n const origModel = selected.model?.primary ?? '';\n return (\n editName.trim() !== origName ||\n editDescription.trim() !== origDesc ||\n editWorkspace.trim() !== origWorkspace ||\n editModel.trim() !== origModel\n );\n })();\n\n const isCurrentPanelDirty = (() => {\n if (footerSaveNotApplicable) return false;\n switch (panel) {\n case 'overview':\n return overviewRestDirty || overviewBootstrapDirty;\n case 'profile':\n return profileDirty;\n default:\n return true; // tools, skills, files — always allow save\n }\n })();\n\n const footerSaveDisabled = footerSaveNotApplicable || !isCurrentPanelDirty;\n\n function showSavedFlash() {\n setSavedFlash(true);\n setTimeout(() => setSavedFlash(false), 2000);\n }\n\n async function handleModalFooterSave() {\n switch (panel) {\n case 'overview':\n await Promise.all([onSaveAgentEdits(), overviewSaveBootstrapRef.current?.() ?? Promise.resolve()]);\n showSavedFlash();\n break;\n case 'profile':\n await profileSaveRef.current?.();\n showSavedFlash();\n break;\n case 'tools':\n await onSaveTools();\n showSavedFlash();\n break;\n case 'skills':\n await onSaveSkills();\n showSavedFlash();\n break;\n case 'files':\n saveBootstrapDebounced.flush();\n showSavedFlash();\n break;\n default:\n break;\n }\n }\n\n function onAgentModalOpenChange(open: boolean) {\n if (!open) {\n navigate(AGENTS_APP_LIST_PATH);\n }\n }\n\n const modalTitle = selected\n ? editName.trim() || selected.name?.trim() || selected.id\n : (routeAgentId ?? '');\n const modalSubtitle = selected?.id ?? routeAgentId ?? '';\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\">{a.title}</h1>\n <p className=\"text-sm text-fg-muted\">{a.needToken}</p>\n </div>\n );\n }\n\n const editorPanelContent =\n !selected ? (\n <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>\n ) : panel === 'overview' ? (\n <AgentOverviewTab\n a={a}\n chat={chat}\n selected={selected}\n busy={busy}\n editName={editName}\n setEditName={setEditName}\n editDescription={editDescription}\n setEditDescription={setEditDescription}\n editWorkspace={editWorkspace}\n setEditWorkspace={setEditWorkspace}\n editModel={editModel}\n setEditModel={setEditModel}\n onSetDefault={() => void onSetDefault(selected)}\n onSaveAgentEdits={() => void onSaveAgentEdits()}\n onDelete={(purge) => void onDelete(selected, purge)}\n hideInlineSave\n saveBootstrapRef={overviewSaveBootstrapRef}\n onBootstrapDirtyChange={setOverviewBootstrapDirty}\n />\n ) : panel === 'profile' ? (\n <AgentProfileTab a={a} agentId={selected.id} saveRef={profileSaveRef} onDirtyChange={setProfileDirty} />\n ) : panel === 'files' ? (\n <AgentFilesTab\n a={a}\n filesLoading={filesLoading}\n files={files}\n activeFile={activeFile}\n setActiveFile={setActiveFile}\n bootstrapViewMode={bootstrapViewMode}\n setBootstrapViewMode={setBootstrapViewMode}\n fileDraft={fileDraft}\n setFileDraft={setFileDraft}\n fileSaving={fileSaving}\n bootstrapFileLoading={bootstrapFileLoading}\n bootstrapEditorNonce={bootstrapEditorNonce}\n />\n ) : panel === 'tools' ? (\n <AgentToolsTab\n a={a}\n data={data!}\n selected={selected}\n busy={busy}\n toolEntryDisable={toolEntryDisable}\n setToolEntryDisable={setToolEntryDisable}\n onSaveTools={() => void onSaveTools()}\n onClearToolsEntry={() => void onClearToolsEntry()}\n hideInlineSave\n />\n ) : panel === 'skills' ? (\n <AgentSkillsTab\n a={a}\n selected={selected}\n busy={busy}\n skillsCatalogLoading={skillsCatalogLoading}\n catalogForPick={catalogForPick}\n skillsInherit={skillsInherit}\n setSkillsInherit={setSkillsInherit}\n skillsPick={skillsPick}\n setSkillsPick={setSkillsPick}\n onSaveSkills={() => void onSaveSkills()}\n hideInlineSave\n />\n ) : panel === 'channels' ? (\n <AgentChannelsTab\n a={a}\n busy={busy}\n bindingsLoading={bindingsLoading}\n agentBindings={agentBindings}\n channelStatuses={bindChannelStatuses}\n channelsStatusLoading={bindChannelsLoading}\n useManualChannel={useManualChannel}\n newBindChannel={newBindChannel}\n setNewBindChannel={setNewBindChannel}\n bindSessionChats={bindSessionChats}\n sessionsLoading={bindSessionsLoading}\n newBindSessionIdx={newBindSessionIdx}\n setNewBindSessionIdx={setNewBindSessionIdx}\n newBindCustomPeer={newBindCustomPeer}\n setNewBindCustomPeer={setNewBindCustomPeer}\n onRefreshSessions={refreshBindSessions}\n lastActiveLabels={cCron.lastActiveLabels}\n selectRecipient={cCron.selectRecipient}\n onRemoveBinding={(rule) => void onRemoveBinding(rule)}\n onAddBinding={onAddBinding}\n />\n ) : panel === 'cron' && data ? (\n <AgentCronTab\n a={a}\n data={data}\n selected={selected}\n busy={busy}\n cronLoading={cronLoading}\n agentCronJobs={agentCronJobs}\n onSetCronJobAgent={(job, key) => void onSetCronJobAgent(job, key)}\n />\n ) : (\n <p className=\"text-sm text-fg-muted\">{a.selectAgentHint}</p>\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 <AgentsSettingsHeader a={a} />\n\n {displayError ? (\n <div className=\"rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200\">\n {displayError}\n </div>\n ) : null}\n\n {loading ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : data ? (\n <AgentsListGrid\n a={a}\n agents={data.agents}\n searchQuery={listSearchQuery}\n onOpenAgent={(id) => navigate(agentsAppDetailPath(id))}\n onChatWithAgent={(id) =>\n navigate('/chat/new', { state: { agentId: id.trim().toLowerCase() } })\n }\n onNewAgent={openAddAgentModal}\n busy={busy}\n />\n ) : null}\n\n {routeAgentId && hasToken ? (\n <AgentsEditorModal\n open={Boolean(routeAgentId)}\n onOpenChange={onAgentModalOpenChange}\n a={a}\n title={modalTitle}\n subtitle={modalSubtitle}\n panel={panel}\n onPanelChange={setPanel}\n onFooterSave={() => void handleModalFooterSave()}\n footerSaveDisabled={footerSaveDisabled}\n footerSavedFlash={savedFlash}\n busy={busy}\n >\n {loading || !data ? (\n <p className=\"text-sm text-fg-muted\">{a.loading}</p>\n ) : (\n editorPanelContent\n )}\n </AgentsEditorModal>\n ) : null}\n\n <CreateAgentDialog\n open={addAgentModalOpen}\n onOpenChange={(open) => {\n setAddAgentModalOpen(open);\n if (!open) {\n createWorkspaceSuggestedRef.current = '';\n setCreateDisplayName('');\n setCreateAgentId('');\n setCreateDescription('');\n setCreateWorkspace('');\n setCreateModel('');\n setCreateModalError(null);\n }\n }}\n a={a}\n chat={chat}\n busy={busy}\n modalError={createModalError}\n createDisplayName={createDisplayName}\n setCreateDisplayName={setCreateDisplayName}\n createAgentId={createAgentId}\n setCreateAgentId={setCreateAgentId}\n createDescription={createDescription}\n setCreateDescription={setCreateDescription}\n createWorkspace={createWorkspace}\n setCreateWorkspace={setCreateWorkspace}\n createModel={createModel}\n setCreateModel={setCreateModel}\n onCreate={onCreate}\n onSuggestWorkspace={() => applyCreateWorkspaceSuggestion()}\n />\n\n <Dialog.Root\n open={deleteDialogOpen}\n onOpenChange={(open) => {\n setDeleteDialogOpen(open);\n if (!open) {\n setDeleteTarget(null);\n setDeleteConfirmText('');\n }\n }}\n >\n <Dialog.Portal>\n <Dialog.Overlay className=\"fixed inset-0 z-[80] bg-scrim backdrop-blur-[2px]\" />\n <Dialog.Content\n className={cn(\n 'fixed left-1/2 top-1/2 z-[81] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-edge bg-surface-panel p-4 shadow-popover',\n 'dark:border-edge',\n )}\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <Dialog.Title className=\"text-base font-semibold text-fg\">\n {deletePurge ? a.purgeDisk : a.removeFromConfig}\n </Dialog.Title>\n <Dialog.Description className=\"mt-2 whitespace-pre-wrap text-sm leading-relaxed text-fg-muted\">\n {deletePurge ? a.confirmDeletePurge : a.confirmDelete}\n </Dialog.Description>\n\n {deletePurge && deleteTarget ? (\n <div className=\"mt-3 space-y-3\">\n <label className=\"mb-2 block text-sm font-medium text-fg\" htmlFor=\"agent-delete-confirm\">\n {a.purgeConfirmLabel}\n </label>\n <input\n id=\"agent-delete-confirm\"\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n className={cn(\n 'w-full rounded-md border border-edge bg-surface-panel px-3 py-1.5 font-mono text-xs text-fg',\n 'placeholder:text-fg-subtle',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n 'dark:border-edge',\n )}\n placeholder={a.purgeConfirmPlaceholder.replace('{{agentId}}', deleteTarget.id)}\n value={deleteConfirmText}\n onChange={(e) => setDeleteConfirmText(e.target.value)}\n />\n <p className=\"pt-0.5 text-xs text-fg-muted\">\n {a.purgeConfirmHint.replace('{{agentId}}', deleteTarget.id)}\n </p>\n </div>\n ) : null}\n\n <div className=\"mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-edge-subtle/60 pt-3\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n disabled={busy}\n onClick={() => setDeleteDialogOpen(false)}\n >\n {a.createModalCancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={deletePurge ? 'border-red-200 text-red-700 hover:bg-red-50 dark:border-red-900/60 dark:text-red-300 dark:hover:bg-red-950/40' : undefined}\n disabled={\n busy ||\n !deleteTarget ||\n (deletePurge && deleteConfirmText.trim().toLowerCase() !== deleteTarget.id.toLowerCase())\n }\n onClick={() => {\n if (!deleteTarget) return;\n void performDelete(deleteTarget, deletePurge);\n }}\n >\n {deletePurge ? a.purgeDisk : a.removeFromConfig}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n","import { revalidateGatewayConfig } from '@/features/gateway/gateway-config-swr';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\n// --- Nested shapes (align with `src/config/schema.ts` AgentDefaultsSchema) ---\n\nexport type AgentDefaultsCompactionState = {\n enabled: boolean;\n mode: 'default' | 'safeguard';\n reserveTokens: number;\n triggerThreshold: number;\n minMessagesBeforeCompact: number;\n keepRecentMessages: number;\n evictionWindow: number;\n retentionWindow: number;\n};\n\nexport type AgentDefaultsPruningState = {\n enabled: boolean;\n maxToolResultChars: number;\n headKeepRatio: number;\n tailKeepRatio: number;\n};\n\nexport type AgentDefaultsMemoryState = {\n enabled: boolean;\n useEnhancedSystem: boolean;\n userProfileEnabled: boolean;\n provider: '' | 'none' | 'stub';\n injectionFrequency: '' | 'every-turn' | 'first-turn';\n memoryCharLimit: number | undefined;\n userCharLimit: number | undefined;\n contextCadence: number | undefined;\n dialecticCadence: number | undefined;\n};\n\nexport type AgentDefaultsSessionSearchState = {\n summaryModel: string;\n};\n\nexport type AgentDefaultsBackgroundReviewState = {\n enabled: boolean;\n memoryNudgeInterval: number;\n skillNudgeInterval: number;\n maxToolRounds: number;\n maxHistoryMessages: number;\n maxDurationMs: number;\n};\n\nexport type AgentDefaultsWebExtractState = {\n model: string;\n maxLength: number | undefined;\n};\n\nexport type AgentDefaultsDelegateState = { enabled: boolean };\nexport type AgentDefaultsExecuteCodeState = { enabled: boolean };\n\nexport interface AgentDefaultsState {\n model: string;\n /** provider/model refs tried when the primary fails (stored as `agents.defaults.model.fallbacks`). */\n modelFallbacks: string[];\n imageModel: string;\n imageModelFallbacks: string[];\n imageGenerationModel: string;\n imageGenerationModelFallbacks: string[];\n mediaMaxMb: number | undefined;\n maxTokens: number;\n temperature: number;\n maxToolIterations: number;\n /** Config `maxTaskDurationMs` — UI stores whole minutes (empty = unset / gateway default). */\n maxTaskDurationMinutes: number | undefined;\n maxRequestsPerTurn: number;\n maxToolFailuresPerTurn: number;\n workspace: string;\n /** Playwright `browser_*` tools (`agents.defaults.browser.enabled`). */\n browserEnabled: boolean;\n /** Headless Chromium when browser tools are on (`agents.defaults.browser.headless`, default true). */\n browserHeadless: boolean;\n thinkingDefault: string;\n reasoningDefault: string;\n verboseDefault: string;\n compaction: AgentDefaultsCompactionState;\n pruning: AgentDefaultsPruningState;\n memory: AgentDefaultsMemoryState;\n sessionSearch: AgentDefaultsSessionSearchState;\n backgroundReview: AgentDefaultsBackgroundReviewState;\n webExtract: AgentDefaultsWebExtractState;\n delegate: AgentDefaultsDelegateState;\n executeCode: AgentDefaultsExecuteCodeState;\n systemPromptOverride: string;\n /** Maps to `agents.defaults.skills` (allowlist). */\n skillsAllowlist: string[];\n /** Maps to `agents.defaults.tools.disable`. */\n toolsDisable: string[];\n /** JSON for `agents.defaults.params`. */\n paramsJson: string;\n}\n\nconst DEFAULT_COMPACTION: AgentDefaultsCompactionState = {\n enabled: true,\n mode: 'default',\n reserveTokens: 8000,\n triggerThreshold: 0.8,\n minMessagesBeforeCompact: 10,\n keepRecentMessages: 5,\n evictionWindow: 0.2,\n retentionWindow: 6,\n};\n\nconst DEFAULT_PRUNING: AgentDefaultsPruningState = {\n enabled: true,\n maxToolResultChars: 10000,\n headKeepRatio: 0.3,\n tailKeepRatio: 0.3,\n};\n\nconst DEFAULT_MEMORY: AgentDefaultsMemoryState = {\n enabled: true,\n useEnhancedSystem: true,\n userProfileEnabled: true,\n provider: '',\n injectionFrequency: '',\n memoryCharLimit: undefined,\n userCharLimit: undefined,\n contextCadence: undefined,\n dialecticCadence: undefined,\n};\n\nconst DEFAULT_SESSION_SEARCH: AgentDefaultsSessionSearchState = {\n summaryModel: '',\n};\n\nconst DEFAULT_BG_REVIEW: AgentDefaultsBackgroundReviewState = {\n enabled: false,\n memoryNudgeInterval: 10,\n skillNudgeInterval: 10,\n maxToolRounds: 8,\n maxHistoryMessages: 80,\n maxDurationMs: 120_000,\n};\n\nconst DEFAULT_WEB_EXTRACT: AgentDefaultsWebExtractState = {\n model: '',\n maxLength: undefined,\n};\n\nfunction normalizeModelRef(raw: unknown): string {\n if (raw == null) return '';\n if (typeof raw === 'string') return raw;\n if (typeof raw === 'object' && raw !== null && 'primary' in raw) {\n const p = (raw as { primary?: string }).primary;\n return typeof p === 'string' ? p : '';\n }\n return '';\n}\n\nfunction normalizeModelFallbacks(raw: unknown): string[] {\n if (typeof raw !== 'object' || raw === null || !('fallbacks' in raw)) {\n return [];\n }\n const f = (raw as { fallbacks?: unknown }).fallbacks;\n if (!Array.isArray(f)) {\n return [];\n }\n return f.filter((x): x is string => typeof x === 'string' && x.trim().length > 0);\n}\n\nfunction configFromApiResponse(res: unknown): unknown {\n if (!res || typeof res !== 'object') return undefined;\n const r = res as Record<string, unknown>;\n const payload = r.payload;\n if (payload && typeof payload === 'object' && 'config' in payload) {\n return (payload as { config?: unknown }).config;\n }\n if ('config' in r) return r.config;\n return undefined;\n}\n\nfunction truthyBrowserFlag(v: unknown): boolean {\n return v === true || v === 'true' || v === 1;\n}\n\nfunction parseBrowserFromDefaults(d: Record<string, unknown>): Pick<AgentDefaultsState, 'browserEnabled' | 'browserHeadless'> {\n const browser = d.browser;\n if (!browser || typeof browser !== 'object' || Array.isArray(browser)) {\n return { browserEnabled: false, browserHeadless: true };\n }\n const b = browser as Record<string, unknown>;\n const enabled = truthyBrowserFlag(b.enabled);\n const headlessRaw = b.headless;\n const headless =\n headlessRaw === false || headlessRaw === 'false' || headlessRaw === 0 ? false : true;\n return { browserEnabled: enabled, browserHeadless: headless };\n}\n\nfunction parseCompaction(raw: unknown): AgentDefaultsCompactionState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_COMPACTION };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_COMPACTION.enabled,\n mode: p.mode === 'safeguard' ? 'safeguard' : 'default',\n reserveTokens:\n typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)\n ? Math.floor(p.reserveTokens)\n : DEFAULT_COMPACTION.reserveTokens,\n triggerThreshold:\n typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)\n ? p.triggerThreshold\n : DEFAULT_COMPACTION.triggerThreshold,\n minMessagesBeforeCompact:\n typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)\n ? Math.floor(p.minMessagesBeforeCompact)\n : DEFAULT_COMPACTION.minMessagesBeforeCompact,\n keepRecentMessages:\n typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)\n ? Math.floor(p.keepRecentMessages)\n : DEFAULT_COMPACTION.keepRecentMessages,\n evictionWindow:\n typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)\n ? p.evictionWindow\n : DEFAULT_COMPACTION.evictionWindow,\n retentionWindow:\n typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)\n ? Math.floor(p.retentionWindow)\n : DEFAULT_COMPACTION.retentionWindow,\n };\n}\n\nfunction parsePruning(raw: unknown): AgentDefaultsPruningState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_PRUNING };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_PRUNING.enabled,\n maxToolResultChars:\n typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)\n ? Math.floor(p.maxToolResultChars)\n : DEFAULT_PRUNING.maxToolResultChars,\n headKeepRatio:\n typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)\n ? p.headKeepRatio\n : DEFAULT_PRUNING.headKeepRatio,\n tailKeepRatio:\n typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)\n ? p.tailKeepRatio\n : DEFAULT_PRUNING.tailKeepRatio,\n };\n}\n\nfunction parseMemory(raw: unknown): AgentDefaultsMemoryState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_MEMORY };\n }\n const p = raw as Record<string, unknown>;\n const providerRaw = p.provider;\n const provider: AgentDefaultsMemoryState['provider'] =\n providerRaw === 'none' || providerRaw === 'stub' ? providerRaw : '';\n const inj = p.injectionFrequency;\n const injectionFrequency: AgentDefaultsMemoryState['injectionFrequency'] =\n inj === 'every-turn' || inj === 'first-turn' ? inj : '';\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_MEMORY.enabled,\n useEnhancedSystem:\n typeof p.useEnhancedSystem === 'boolean' ? p.useEnhancedSystem : DEFAULT_MEMORY.useEnhancedSystem,\n userProfileEnabled:\n typeof p.userProfileEnabled === 'boolean' ? p.userProfileEnabled : DEFAULT_MEMORY.userProfileEnabled,\n provider,\n injectionFrequency,\n memoryCharLimit:\n typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0\n ? Math.floor(p.memoryCharLimit)\n : undefined,\n userCharLimit:\n typeof p.userCharLimit === 'number' && p.userCharLimit > 0\n ? Math.floor(p.userCharLimit)\n : undefined,\n contextCadence:\n typeof p.contextCadence === 'number' && p.contextCadence >= 1\n ? Math.floor(p.contextCadence)\n : undefined,\n dialecticCadence:\n typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1\n ? Math.floor(p.dialecticCadence)\n : undefined,\n };\n}\n\nfunction parseSessionSearch(raw: unknown): AgentDefaultsSessionSearchState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_SESSION_SEARCH };\n }\n const p = raw as Record<string, unknown>;\n return {\n summaryModel: typeof p.summaryModel === 'string' ? p.summaryModel : '',\n };\n}\n\nfunction parseBackgroundReview(raw: unknown): AgentDefaultsBackgroundReviewState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_BG_REVIEW };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : DEFAULT_BG_REVIEW.enabled,\n memoryNudgeInterval:\n typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0\n ? Math.floor(p.memoryNudgeInterval)\n : DEFAULT_BG_REVIEW.memoryNudgeInterval,\n skillNudgeInterval:\n typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0\n ? Math.floor(p.skillNudgeInterval)\n : DEFAULT_BG_REVIEW.skillNudgeInterval,\n maxToolRounds:\n typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32\n ? Math.floor(p.maxToolRounds)\n : DEFAULT_BG_REVIEW.maxToolRounds,\n maxHistoryMessages:\n typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200\n ? Math.floor(p.maxHistoryMessages)\n : DEFAULT_BG_REVIEW.maxHistoryMessages,\n maxDurationMs:\n typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000\n ? Math.floor(p.maxDurationMs)\n : DEFAULT_BG_REVIEW.maxDurationMs,\n };\n}\n\nfunction parseWebExtract(raw: unknown): AgentDefaultsWebExtractState {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { ...DEFAULT_WEB_EXTRACT };\n }\n const p = raw as Record<string, unknown>;\n return {\n model: typeof p.model === 'string' ? p.model : '',\n maxLength:\n typeof p.maxLength === 'number' && p.maxLength > 0 ? p.maxLength : undefined,\n };\n}\n\nfunction parseEnabledFlag(raw: unknown, def: boolean): { enabled: boolean } {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { enabled: def };\n }\n const p = raw as Record<string, unknown>;\n return {\n enabled: typeof p.enabled === 'boolean' ? p.enabled : def,\n };\n}\n\nfunction parseStringList(raw: unknown): string[] {\n if (!Array.isArray(raw)) {\n return [];\n }\n return raw.filter((x): x is string => typeof x === 'string');\n}\n\nfunction parseParamsJson(raw: unknown): string {\n if (raw === undefined || raw === null) {\n return '';\n }\n if (typeof raw === 'object' && !Array.isArray(raw)) {\n try {\n return JSON.stringify(raw, null, 2);\n } catch {\n return '';\n }\n }\n return '';\n}\n\n/** Parse `agents.defaults` from a gateway config root object. */\nexport function parseAgentDefaultsFromConfig(cfg: unknown): AgentDefaultsState {\n const agents =\n cfg && typeof cfg === 'object' && !Array.isArray(cfg) && 'agents' in cfg\n ? (cfg as { agents?: unknown }).agents\n : undefined;\n const defaults =\n agents && typeof agents === 'object' && !Array.isArray(agents) && 'defaults' in agents\n ? (agents as { defaults?: unknown }).defaults\n : undefined;\n const d =\n defaults && typeof defaults === 'object' && !Array.isArray(defaults)\n ? (defaults as Record<string, unknown>)\n : {};\n const mf = d.modelFallbacks;\n const modelFallbacksFromApi =\n Array.isArray(mf) && mf.every((x) => typeof x === 'string') ? mf : normalizeModelFallbacks(d.model);\n const imf = d.imageModelFallbacks;\n const imageModelFallbacksFromApi =\n Array.isArray(imf) && imf.every((x) => typeof x === 'string')\n ? imf\n : normalizeModelFallbacks(d.imageModel);\n const igf = d.imageGenerationModelFallbacks;\n const imageGenerationModelFallbacksFromApi =\n Array.isArray(igf) && igf.every((x) => typeof x === 'string')\n ? igf\n : normalizeModelFallbacks(d.imageGenerationModel);\n const { browserEnabled, browserHeadless } = parseBrowserFromDefaults(d);\n const maxTaskMs =\n typeof d.maxTaskDurationMs === 'number' && Number.isFinite(d.maxTaskDurationMs)\n ? d.maxTaskDurationMs\n : undefined;\n const maxTaskDurationMinutes =\n maxTaskMs !== undefined ? Math.round(maxTaskMs / 60_000) : undefined;\n\n return {\n model: normalizeModelRef(d.model),\n modelFallbacks: modelFallbacksFromApi,\n imageModel: normalizeModelRef(d.imageModel),\n imageModelFallbacks: imageModelFallbacksFromApi,\n imageGenerationModel: normalizeModelRef(d.imageGenerationModel),\n imageGenerationModelFallbacks: imageGenerationModelFallbacksFromApi,\n mediaMaxMb: typeof d.mediaMaxMb === 'number' && !Number.isNaN(d.mediaMaxMb) ? d.mediaMaxMb : undefined,\n maxTokens: typeof d.maxTokens === 'number' ? d.maxTokens : 8192,\n temperature: typeof d.temperature === 'number' ? d.temperature : 0.7,\n maxToolIterations: typeof d.maxToolIterations === 'number' ? d.maxToolIterations : 20,\n maxTaskDurationMinutes,\n maxRequestsPerTurn: typeof d.maxRequestsPerTurn === 'number' ? d.maxRequestsPerTurn : 50,\n maxToolFailuresPerTurn: typeof d.maxToolFailuresPerTurn === 'number' ? d.maxToolFailuresPerTurn : 3,\n workspace: typeof d.workspace === 'string' ? d.workspace : '~/.xopc/workspace',\n browserEnabled,\n browserHeadless,\n thinkingDefault: typeof d.thinkingDefault === 'string' ? d.thinkingDefault : 'medium',\n reasoningDefault: typeof d.reasoningDefault === 'string' ? d.reasoningDefault : 'off',\n verboseDefault: typeof d.verboseDefault === 'string' ? d.verboseDefault : 'off',\n compaction: parseCompaction(d.compaction),\n pruning: parsePruning(d.pruning),\n memory: parseMemory(d.memory),\n sessionSearch: parseSessionSearch(d.sessionSearch),\n backgroundReview: parseBackgroundReview(d.backgroundReview),\n webExtract: parseWebExtract(d.webExtract),\n delegate: parseEnabledFlag(d.delegate, false),\n executeCode: parseEnabledFlag(d.executeCode, false),\n systemPromptOverride: typeof d.systemPromptOverride === 'string' ? d.systemPromptOverride : '',\n skillsAllowlist: parseStringList(d.skills),\n toolsDisable: (() => {\n const t = d.tools;\n if (!t || typeof t !== 'object' || Array.isArray(t)) {\n return [] as string[];\n }\n const dis = (t as { disable?: unknown }).disable;\n return parseStringList(dis);\n })(),\n paramsJson: parseParamsJson(d.params),\n };\n}\n\nfunction buildMemoryPatch(m: AgentDefaultsMemoryState): Record<string, unknown> {\n const o: Record<string, unknown> = {\n enabled: m.enabled,\n useEnhancedSystem: m.useEnhancedSystem,\n userProfileEnabled: m.userProfileEnabled,\n };\n if (m.provider === 'none' || m.provider === 'stub') {\n o.provider = m.provider;\n } else {\n o.provider = null;\n }\n if (m.injectionFrequency === 'every-turn' || m.injectionFrequency === 'first-turn') {\n o.injectionFrequency = m.injectionFrequency;\n } else {\n o.injectionFrequency = null;\n }\n o.memoryCharLimit = m.memoryCharLimit ?? null;\n o.userCharLimit = m.userCharLimit ?? null;\n o.contextCadence = m.contextCadence ?? null;\n o.dialecticCadence = m.dialecticCadence ?? null;\n return o;\n}\n\n/** @throws {SyntaxError} on invalid JSON; {Error} if not a plain object. */\nexport function parseParamsJsonForSave(paramsJson: string): Record<string, unknown> | null {\n const trimmed = paramsJson.trim();\n if (!trimmed) {\n return null;\n }\n const parsed: unknown = JSON.parse(trimmed);\n if (parsed === null) {\n return null;\n }\n if (typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('params must be a JSON object');\n }\n return parsed as Record<string, unknown>;\n}\n\nexport async function fetchAgentDefaults(): Promise<AgentDefaultsState> {\n const res = await fetchJson<{ ok?: boolean; payload?: { config?: unknown } }>(apiUrl('/api/config'));\n const cfg = configFromApiResponse(res);\n return parseAgentDefaultsFromConfig(cfg ?? {});\n}\n\nexport async function patchAgentDefaults(state: AgentDefaultsState): Promise<void> {\n const fallbacks = state.modelFallbacks.map((s) => s.trim()).filter(Boolean);\n const modelField =\n fallbacks.length > 0 ? { primary: state.model, fallbacks } : state.model;\n\n const imageFbs = state.imageModelFallbacks.map((s) => s.trim()).filter(Boolean);\n const imageModelField =\n imageFbs.length > 0 && state.imageModel.trim()\n ? { primary: state.imageModel.trim(), fallbacks: imageFbs }\n : state.imageModel || '';\n\n const imageGenFbs = state.imageGenerationModelFallbacks.map((s) => s.trim()).filter(Boolean);\n const imageGenerationModelField =\n imageGenFbs.length > 0 && state.imageGenerationModel.trim()\n ? { primary: state.imageGenerationModel.trim(), fallbacks: imageGenFbs }\n : state.imageGenerationModel || '';\n\n const maxTaskDurationMs: number | null =\n state.maxTaskDurationMinutes === undefined || state.maxTaskDurationMinutes === null\n ? null\n : (() => {\n const n = Math.floor(state.maxTaskDurationMinutes);\n const ms = n * 60_000;\n if (ms < 60_000 || ms > 14_400_000) {\n return null;\n }\n return ms;\n })();\n\n const skillsClean = state.skillsAllowlist.map((s) => s.trim()).filter(Boolean);\n const toolsDisableClean = state.toolsDisable.map((s) => s.trim()).filter(Boolean);\n\n const paramsParsed = parseParamsJsonForSave(state.paramsJson);\n const params =\n paramsParsed === null || Object.keys(paramsParsed).length === 0 ? null : paramsParsed;\n\n const defaults: Record<string, unknown> = {\n model: modelField,\n imageModel: imageModelField,\n imageGenerationModel: imageGenerationModelField,\n mediaMaxMb: state.mediaMaxMb ?? null,\n maxTokens: state.maxTokens,\n temperature: state.temperature,\n maxToolIterations: state.maxToolIterations,\n maxTaskDurationMs,\n maxRequestsPerTurn: state.maxRequestsPerTurn,\n maxToolFailuresPerTurn: state.maxToolFailuresPerTurn,\n workspace: state.workspace,\n browser: {\n enabled: state.browserEnabled,\n headless: state.browserHeadless,\n },\n thinkingDefault: state.thinkingDefault,\n reasoningDefault: state.reasoningDefault,\n verboseDefault: state.verboseDefault,\n compaction: { ...state.compaction },\n pruning: { ...state.pruning },\n memory: buildMemoryPatch(state.memory),\n sessionSearch: {\n summaryModel: state.sessionSearch.summaryModel.trim() || null,\n },\n backgroundReview: {\n enabled: state.backgroundReview.enabled,\n memoryNudgeInterval: state.backgroundReview.memoryNudgeInterval,\n skillNudgeInterval: state.backgroundReview.skillNudgeInterval,\n maxToolRounds: state.backgroundReview.maxToolRounds,\n maxHistoryMessages: state.backgroundReview.maxHistoryMessages,\n maxDurationMs: state.backgroundReview.maxDurationMs,\n },\n webExtract: {\n model: state.webExtract.model.trim() || null,\n maxLength: state.webExtract.maxLength ?? null,\n },\n delegate: { enabled: state.delegate.enabled },\n executeCode: { enabled: state.executeCode.enabled },\n systemPromptOverride: state.systemPromptOverride.trim() || null,\n skills: skillsClean.length > 0 ? skillsClean : null,\n tools: { disable: toolsDisableClean.length > 0 ? toolsDisableClean : null },\n params,\n };\n\n await fetchJson(apiUrl('/api/config'), {\n method: 'PATCH',\n body: JSON.stringify({\n agents: { defaults },\n }),\n });\n void revalidateGatewayConfig();\n}\n","import { nativeSelectMaxWidthClass, selectControlBaseClass, settingsInputFocusClass } from '@/lib/form-field-width';\nimport { cn } from '@/lib/cn';\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","import { Brain, Clock, Code2, FileText, Layers2, Library, Scissors, Search, Sparkles, Timer, Wrench } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport type { AgentDefaultsState } from '@/features/settings/config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { cn } from '@/lib/cn';\nimport type { MessageBundle } from '@/i18n/messages';\n\nimport { inputClassName, selectClassName } from './defaults-field-styles';\n\ntype A = MessageBundle['agentSettings'];\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\nexport function AgentDefaultsExtraFields(props: {\n a: A;\n chat: MessageBundle['chat'];\n form: AgentDefaultsState;\n update: (patch: Partial<AgentDefaultsState>) => void;\n}) {\n const { a, chat, form, update } = props;\n const x = a.advanced;\n\n return (\n <>\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Timer} title={x.cardLimitsTitle} subtitle={x.cardLimitsSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.maxTaskDurationMs} description={x.maxTaskDurationMsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={240}\n step={1}\n value={form.maxTaskDurationMinutes ?? ''}\n placeholder={x.maxTaskDurationPlaceholder}\n onChange={(e) => {\n const v = e.target.value;\n if (v === '') {\n update({ maxTaskDurationMinutes: undefined });\n return;\n }\n const n = Number.parseInt(v, 10);\n if (Number.isNaN(n)) {\n return;\n }\n update({ maxTaskDurationMinutes: Math.min(240, Math.max(1, n)) });\n }}\n />\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.maxRequestsPerTurn} description={x.maxRequestsPerTurnDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={10}\n max={200}\n value={form.maxRequestsPerTurn}\n onChange={(e) => update({ maxRequestsPerTurn: Number.parseInt(e.target.value, 10) || 50 })}\n />\n </Field>\n <Field label={x.maxToolFailuresPerTurn} description={x.maxToolFailuresPerTurnDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={20}\n value={form.maxToolFailuresPerTurn}\n onChange={(e) => update({ maxToolFailuresPerTurn: Number.parseInt(e.target.value, 10) || 3 })}\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Layers2} title={x.cardCompactionTitle} subtitle={x.cardCompactionSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.compactionEnabled} description={x.compactionEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.compaction.enabled}\n onChange={(e) =>\n update({ compaction: { ...form.compaction, enabled: e.target.checked } })\n }\n />\n <span>{x.compactionEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.compactionMode} description={x.compactionModeDesc}>\n <select\n className={selectClassName()}\n value={form.compaction.mode}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n mode: e.target.value as AgentDefaultsState['compaction']['mode'],\n },\n })\n }\n >\n <option value=\"default\">{x.compactionModeDefault}</option>\n <option value=\"safeguard\">{x.compactionModeSafeguard}</option>\n </select>\n </Field>\n <Field label={x.reserveTokens} description={x.reserveTokensDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1000}\n value={form.compaction.reserveTokens}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n reserveTokens: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.triggerThreshold} description={x.triggerThresholdDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0.5}\n max={0.95}\n step={0.05}\n value={form.compaction.triggerThreshold}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n triggerThreshold: Number.parseFloat(e.target.value) || 0.8,\n },\n })\n }\n />\n </Field>\n <Field label={x.minMessagesBeforeCompact} description={x.minMessagesBeforeCompactDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.compaction.minMessagesBeforeCompact}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n minMessagesBeforeCompact: Number.parseInt(e.target.value, 10) || 10,\n },\n })\n }\n />\n </Field>\n <Field label={x.keepRecentMessages} description={x.keepRecentMessagesDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.compaction.keepRecentMessages}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n keepRecentMessages: Number.parseInt(e.target.value, 10) || 5,\n },\n })\n }\n />\n </Field>\n <Field label={x.evictionWindow} description={x.evictionWindowDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0.1}\n max={0.5}\n step={0.05}\n value={form.compaction.evictionWindow}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n evictionWindow: Number.parseFloat(e.target.value) || 0.2,\n },\n })\n }\n />\n </Field>\n <Field label={x.retentionWindow} description={x.retentionWindowDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={3}\n max={20}\n value={form.compaction.retentionWindow}\n onChange={(e) =>\n update({\n compaction: {\n ...form.compaction,\n retentionWindow: Number.parseInt(e.target.value, 10) || 6,\n },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Scissors} title={x.cardPruningTitle} subtitle={x.cardPruningSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.pruningEnabled} description={x.pruningEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.pruning.enabled}\n onChange={(e) => update({ pruning: { ...form.pruning, enabled: e.target.checked } })}\n />\n <span>{x.pruningEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.maxToolResultChars} description={x.maxToolResultCharsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1000}\n value={form.pruning.maxToolResultChars}\n onChange={(e) =>\n update({\n pruning: {\n ...form.pruning,\n maxToolResultChars: Number.parseInt(e.target.value, 10) || 10000,\n },\n })\n }\n />\n </Field>\n <Field label={x.headKeepRatio} description={x.headKeepRatioDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n max={1}\n step={0.05}\n value={form.pruning.headKeepRatio}\n onChange={(e) =>\n update({\n pruning: { ...form.pruning, headKeepRatio: Number.parseFloat(e.target.value) || 0.3 },\n })\n }\n />\n </Field>\n <Field label={x.tailKeepRatio} description={x.tailKeepRatioDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n max={1}\n step={0.05}\n value={form.pruning.tailKeepRatio}\n onChange={(e) =>\n update({\n pruning: { ...form.pruning, tailKeepRatio: Number.parseFloat(e.target.value) || 0.3 },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Brain} title={x.cardMemoryTitle} subtitle={x.cardMemorySubtitle} />\n <div className=\"flex flex-col gap-5\">\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.memoryEnabled} description={x.memoryEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.enabled}\n onChange={(e) => update({ memory: { ...form.memory, enabled: e.target.checked } })}\n />\n <span>{x.memoryEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.useEnhancedSystem} description={x.useEnhancedSystemDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.useEnhancedSystem}\n onChange={(e) =>\n update({ memory: { ...form.memory, useEnhancedSystem: e.target.checked } })\n }\n />\n <span>{x.useEnhancedSystemOn}</span>\n </label>\n </Field>\n <Field label={x.userProfileEnabled} description={x.userProfileEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.memory.userProfileEnabled}\n onChange={(e) =>\n update({ memory: { ...form.memory, userProfileEnabled: e.target.checked } })\n }\n />\n <span>{x.userProfileEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.memoryProvider} description={x.memoryProviderDesc}>\n <select\n className={selectClassName()}\n value={form.memory.provider}\n onChange={(e) =>\n update({\n memory: {\n ...form.memory,\n provider: e.target.value as AgentDefaultsState['memory']['provider'],\n },\n })\n }\n >\n <option value=\"\">{x.memoryProviderUnset}</option>\n <option value=\"none\">none</option>\n <option value=\"stub\">stub</option>\n </select>\n </Field>\n <Field label={x.injectionFrequency} description={x.injectionFrequencyDesc}>\n <select\n className={selectClassName()}\n value={form.memory.injectionFrequency}\n onChange={(e) =>\n update({\n memory: {\n ...form.memory,\n injectionFrequency: e.target.value as AgentDefaultsState['memory']['injectionFrequency'],\n },\n })\n }\n >\n <option value=\"\">{x.injectionFrequencyUnset}</option>\n <option value=\"every-turn\">{x.injectionEveryTurn}</option>\n <option value=\"first-turn\">{x.injectionFirstTurn}</option>\n </select>\n </Field>\n <Field label={x.memoryCharLimit} description={x.memoryCharLimitDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.memoryCharLimit ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n memoryCharLimit: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.userCharLimit} description={x.userCharLimitDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.userCharLimit ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n userCharLimit: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.contextCadence} description={x.contextCadenceDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.contextCadence ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n contextCadence: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n <Field label={x.dialecticCadence} description={x.dialecticCadenceDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.memory.dialecticCadence ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n memory: {\n ...form.memory,\n dialecticCadence: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Search} title={x.cardSessionSearchTitle} subtitle={x.cardSessionSearchSubtitle} />\n <Field label={x.sessionSearchSummaryModel} description={x.sessionSearchSummaryModelDesc}>\n <ModelSelector\n value={form.sessionSearch.summaryModel}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) =>\n update({ sessionSearch: { ...form.sessionSearch, summaryModel: modelId } })\n }\n />\n </Field>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Sparkles} title={x.cardReviewTitle} subtitle={x.cardReviewSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.reviewEnabled} description={x.reviewEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.backgroundReview.enabled}\n onChange={(e) =>\n update({ backgroundReview: { ...form.backgroundReview, enabled: e.target.checked } })\n }\n />\n <span>{x.reviewEnabledOn}</span>\n </label>\n </Field>\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.memoryNudgeInterval} description={x.memoryNudgeIntervalDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.backgroundReview.memoryNudgeInterval}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n memoryNudgeInterval: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.skillNudgeInterval} description={x.skillNudgeIntervalDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={0}\n value={form.backgroundReview.skillNudgeInterval}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n skillNudgeInterval: Number.parseInt(e.target.value, 10) || 0,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxToolRounds} description={x.reviewMaxToolRoundsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n max={32}\n value={form.backgroundReview.maxToolRounds}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxToolRounds: Number.parseInt(e.target.value, 10) || 8,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxHistoryMessages} description={x.reviewMaxHistoryMessagesDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={10}\n max={200}\n value={form.backgroundReview.maxHistoryMessages}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxHistoryMessages: Number.parseInt(e.target.value, 10) || 80,\n },\n })\n }\n />\n </Field>\n <Field label={x.reviewMaxDurationMs} description={x.reviewMaxDurationMsDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={30}\n max={600}\n step={1}\n value={Math.round((form.backgroundReview.maxDurationMs ?? 120_000) / 1000)}\n onChange={(e) =>\n update({\n backgroundReview: {\n ...form.backgroundReview,\n maxDurationMs: (Number.parseInt(e.target.value, 10) || 120) * 1000,\n },\n })\n }\n />\n </Field>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={FileText}\n title={x.cardWebExtractTitle}\n subtitle={x.cardWebExtractSubtitle}\n />\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <div className=\"sm:col-span-2\">\n <Field label={x.webExtractModel} description={x.webExtractModelDesc}>\n <ModelSelector\n value={form.webExtract.model}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => update({ webExtract: { ...form.webExtract, model: modelId } })}\n />\n </Field>\n </div>\n <Field label={x.webExtractMaxLength} description={x.webExtractMaxLengthDesc}>\n <input\n type=\"number\"\n className={inputClassName()}\n min={1}\n value={form.webExtract.maxLength ?? ''}\n placeholder=\"—\"\n onChange={(e) => {\n const v = e.target.value;\n update({\n webExtract: {\n ...form.webExtract,\n maxLength: v === '' ? undefined : Number.parseInt(v, 10),\n },\n });\n }}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Code2} title={x.cardDelegateTitle} subtitle={x.cardDelegateSubtitle} />\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={x.delegateEnabled} description={x.delegateEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.delegate.enabled}\n onChange={(e) => update({ delegate: { ...form.delegate, enabled: e.target.checked } })}\n />\n <span>{x.delegateEnabledOn}</span>\n </label>\n </Field>\n <Field label={x.executeCodeEnabled} description={x.executeCodeEnabledDesc}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.executeCode.enabled}\n onChange={(e) =>\n update({ executeCode: { ...form.executeCode, enabled: e.target.checked } })\n }\n />\n <span>{x.executeCodeEnabledOn}</span>\n </label>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader\n icon={Library}\n title={x.cardPromptSkillsTitle}\n subtitle={x.cardPromptSkillsSubtitle}\n />\n <div className=\"flex flex-col gap-5\">\n <Field label={x.systemPromptOverride} description={x.systemPromptOverrideDesc}>\n <textarea\n className={cn(inputClassName(), 'min-h-[100px] resize-y font-mono text-xs')}\n value={form.systemPromptOverride}\n placeholder={x.systemPromptPlaceholder}\n onChange={(e) => update({ systemPromptOverride: e.target.value })}\n />\n </Field>\n <Field label={x.skillsAllowlist} description={x.skillsAllowlistDesc}>\n <div className=\"flex flex-col gap-2\">\n {form.skillsAllowlist.map((s, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n value={s}\n onChange={(e) => {\n const next = [...form.skillsAllowlist];\n next[idx] = e.target.value;\n update({ skillsAllowlist: next });\n }}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={x.removeListItem}\n onClick={() =>\n update({ skillsAllowlist: form.skillsAllowlist.filter((_, j) => j !== idx) })\n }\n >\n ×\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit\"\n onClick={() => update({ skillsAllowlist: [...form.skillsAllowlist, ''] })}\n >\n {x.addSkillName}\n </Button>\n </div>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Wrench} title={x.cardToolsDisableTitle} subtitle={x.cardToolsDisableSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <p className=\"text-xs text-fg-muted\">{x.toolsDisableHint}</p>\n <div className=\"flex flex-col gap-2\">\n {form.toolsDisable.map((s, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n className={cn(inputClassName(), 'font-mono text-xs')}\n value={s}\n placeholder=\"shell\"\n onChange={(e) => {\n const next = [...form.toolsDisable];\n next[idx] = e.target.value;\n update({ toolsDisable: next });\n }}\n />\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"shrink-0\"\n aria-label={x.removeListItem}\n onClick={() => update({ toolsDisable: form.toolsDisable.filter((_, j) => j !== idx) })}\n >\n ×\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-fit\"\n onClick={() => update({ toolsDisable: [...form.toolsDisable, ''] })}\n >\n {x.addToolName}\n </Button>\n </div>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Clock} title={x.cardParamsTitle} subtitle={x.cardParamsSubtitle} />\n <Field label={x.paramsJson} description={x.paramsJsonDesc}>\n <textarea\n className={cn(inputClassName(), 'min-h-[88px] resize-y font-mono text-xs')}\n value={form.paramsJson}\n placeholder=\"{}\"\n onChange={(e) => update({ paramsJson: e.target.value })}\n />\n </Field>\n </SettingsFormSection>\n </>\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 = { id: string; defaultModel?: string; models: string[] };\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 buildModelIds(providers: ImageProviderSummary[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const p of providers) {\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\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 className,\n onChange,\n}: {\n value: string;\n disabled?: boolean;\n placeholder: string;\n searchPlaceholder: string;\n noMatches: 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 allIds = useMemo(() => buildModelIds(providers ?? []), [providers]);\n const filtered = useMemo(() => idsMatchingQuery(allIds, query), [allIds, query]);\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 <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\">{noMatches}</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 );\n}\n","import { Cpu, Folder, Globe, Layers, Plus, Trash2, Zap } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { ModelSelector } from '@/features/chat/model-selector';\nimport { useGatewayConfigSwr } from '@/features/gateway/gateway-config-swr';\nimport {\n parseAgentDefaultsFromConfig,\n parseParamsJsonForSave,\n patchAgentDefaults,\n type AgentDefaultsState,\n} from '@/features/settings/config-api';\nimport { SettingsFormSection, SettingsFormSectionHeader } from '@/features/settings/settings-form-section';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nimport { AgentDefaultsExtraFields } from './agent-defaults-extra';\nimport { ImageGenerationModelInput } from './image-generation-model-input';\nimport { inputClassName, selectClassName } from './defaults-field-styles';\n\nconst THINKING_KEYS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'adaptive'] as const;\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\nexport function AgentSettingsPanel() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const a = m.agentSettings;\n const chat = m.chat;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n\n const [form, setForm] = useState<AgentDefaultsState | null>(null);\n const [baseline, setBaseline] = useState<AgentDefaultsState | 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 ? parseAgentDefaultsFromConfig(data.payload.config) : 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<AgentDefaultsState>) => {\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 try {\n void parseParamsJsonForSave(form.paramsJson);\n } catch (e) {\n setError(\n e instanceof SyntaxError\n ? a.advanced.paramsInvalidJson\n : e instanceof Error\n ? e.message\n : a.advanced.paramsInvalidJson,\n );\n return;\n }\n await patchAgentDefaults(form);\n dirtyRef.current = false;\n setSaveOk(true);\n window.setTimeout(() => setSaveOk(false), 2500);\n } catch (e) {\n setError(e instanceof Error ? e.message : a.saveError);\n } finally {\n setSaving(false);\n }\n }, [form, saving, a.saveError, a.advanced]);\n\n const pageTitle = m.settingsSections['agent-defaults'];\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 <Cpu 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\">{pageTitle}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{a.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 (!form) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10\">\n <p className=\"text-sm text-fg-muted\">\n {error ?? fetchError ?? a.loadError}\n </p>\n <Button type=\"button\" variant=\"secondary\" onClick={() => void mutate()}>\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-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\">{pageTitle}</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">{a.subtitle}</p>\n <p className=\"mt-1 text-xs text-fg-subtle\">{a.sectionDesc}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {saveOk ? <span className=\"text-sm text-fg-muted\">{a.saved}</span> : null}\n <Button type=\"button\" variant=\"primary\" disabled={!dirty || saving} onClick={() => void save()}>\n {saving ? a.saving : a.save}\n </Button>\n </div>\n </header>\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 <div className=\"flex flex-col gap-5\">\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Cpu} title={a.cardModelsTitle} subtitle={a.cardModelsSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.model} description={a.desc.model}>\n <ModelSelector\n value={form.model}\n placeholder={chat.modelPlaceholder}\n searchPlaceholder={chat.modelSearchPlaceholder}\n noMatches={chat.modelNoMatches}\n onChange={(modelId) => update({ model: modelId })}\n />\n </Field>\n <Field label={a.label.modelFallbacks} description={a.desc.modelFallbacks}>\n <div className=\"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 </Field>\n <Field 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 onChange={(modelId) => update({ imageModel: modelId })}\n />\n </Field>\n <Field 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 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 </Field>\n <Field 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 onChange={(modelId) => update({ imageGenerationModel: modelId })}\n />\n </Field>\n <Field\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 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 </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Folder} title={a.cardWorkspaceTitle} subtitle={a.cardWorkspaceSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.workspace} description={a.desc.workspace}>\n <input\n type=\"text\"\n className={inputClassName()}\n value={form.workspace}\n onChange={(e) => update({ workspace: e.target.value })}\n autoComplete=\"off\"\n />\n </Field>\n <Field label={a.label.mediaMaxMb} description={a.desc.mediaMaxMb}>\n <input\n type=\"number\"\n min={1}\n step={1}\n className={inputClassName()}\n value={form.mediaMaxMb ?? ''}\n placeholder=\"20\"\n onChange={(e) => {\n const v = e.target.value;\n update({ mediaMaxMb: v === '' ? undefined : Number(v) });\n }}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Globe} title={a.cardBrowserTitle} subtitle={a.cardBrowserSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.browserEnabled} description={a.desc.browserEnabled}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.browserEnabled}\n onChange={(e) => update({ browserEnabled: e.target.checked })}\n />\n <span>{a.browserEnabledOn}</span>\n </label>\n </Field>\n <Field label={a.label.browserHeadless} description={a.desc.browserHeadless}>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-fg\">\n <input\n type=\"checkbox\"\n className=\"size-3.5 shrink-0 rounded border-edge\"\n checked={form.browserHeadless}\n onChange={(e) => update({ browserHeadless: e.target.checked })}\n />\n <span>{a.browserHeadlessOn}</span>\n </label>\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Layers} title={a.cardGenerationTitle} subtitle={a.cardGenerationSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <div className=\"grid gap-5 sm:grid-cols-2\">\n <Field label={a.label.maxTokens} description={a.desc.maxTokens}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.maxTokens}\n min={1}\n onChange={(e) => update({ maxTokens: Number.parseInt(e.target.value, 10) || 0 })}\n />\n </Field>\n <Field label={a.label.temperature} description={a.desc.temperature}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.temperature}\n min={0}\n max={2}\n step={0.1}\n onChange={(e) => update({ temperature: Number.parseFloat(e.target.value) || 0 })}\n />\n </Field>\n </div>\n <Field label={a.label.maxToolIterations} description={a.desc.maxToolIterations}>\n <input\n type=\"number\"\n className={inputClassName()}\n value={form.maxToolIterations}\n min={1}\n onChange={(e) => update({ maxToolIterations: Number.parseInt(e.target.value, 10) || 0 })}\n />\n </Field>\n </div>\n </SettingsFormSection>\n\n <SettingsFormSection>\n <SettingsFormSectionHeader icon={Zap} title={a.cardBehaviorTitle} subtitle={a.cardBehaviorSubtitle} />\n <div className=\"flex flex-col gap-5\">\n <Field label={a.label.thinkingDefault} description={a.desc.thinkingDefault}>\n <select\n className={selectClassName()}\n value={form.thinkingDefault}\n onChange={(e) => update({ thinkingDefault: e.target.value })}\n >\n {THINKING_KEYS.map((k) => (\n <option key={k} value={k}>\n {chat.thinkingLevels[k]}\n </option>\n ))}\n </select>\n </Field>\n <Field label={a.label.reasoningDefault} description={a.desc.reasoningDefault}>\n <select\n className={selectClassName()}\n value={form.reasoningDefault}\n onChange={(e) => update({ reasoningDefault: e.target.value })}\n >\n <option value=\"off\">{a.reasoning.off}</option>\n <option value=\"on\">{a.reasoning.on}</option>\n <option value=\"stream\">{a.reasoning.stream}</option>\n </select>\n </Field>\n <Field label={a.label.verboseDefault} description={a.desc.verboseDefault}>\n <select\n className={selectClassName()}\n value={form.verboseDefault}\n onChange={(e) => update({ verboseDefault: e.target.value })}\n >\n <option value=\"off\">{a.verbose.off}</option>\n <option value=\"on\">{a.verbose.on}</option>\n <option value=\"full\">{a.verbose.full}</option>\n </select>\n </Field>\n </div>\n </SettingsFormSection>\n\n <AgentDefaultsExtraFields a={a} chat={chat} form={form} update={update} />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}