@circuitwall/jarela 0.8.0 → 0.8.1

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 (98) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page.js +1 -537
  15. package/.next/standalone/.next/server/app/_not-found/page.js.map +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +23 -2
  19. package/.next/standalone/.next/server/app/_not-found.rsc +47 -18
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +47 -18
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +36 -7
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  26. package/.next/standalone/.next/server/app/index.html +23 -2
  27. package/.next/standalone/.next/server/app/index.rsc +46 -17
  28. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +46 -17
  30. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +36 -7
  32. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  33. package/.next/standalone/.next/server/app/page.js +79690 -79580
  34. package/.next/standalone/.next/server/app/page.js.map +1 -1
  35. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/setup/page.js +1 -1
  38. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/setup.html +1 -1
  41. package/.next/standalone/.next/server/app/setup.rsc +48 -19
  42. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +48 -19
  43. package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +36 -7
  45. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  46. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
  47. package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
  48. package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
  49. package/.next/standalone/.next/server/chunks/4045.js +611 -0
  50. package/.next/standalone/.next/server/chunks/4045.js.map +1 -0
  51. package/.next/standalone/.next/server/chunks/5432.js +5 -2
  52. package/.next/standalone/.next/server/chunks/5432.js.map +1 -1
  53. package/.next/standalone/.next/server/chunks/{5745.js → 6765.js} +9 -551
  54. package/.next/standalone/.next/server/chunks/6765.js.map +1 -0
  55. package/.next/standalone/.next/server/chunks/7885.js +5 -2
  56. package/.next/standalone/.next/server/chunks/7885.js.map +1 -1
  57. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  58. package/.next/standalone/.next/server/pages/404.html +23 -2
  59. package/.next/standalone/.next/server/pages/500.html +1 -1
  60. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  61. package/.next/standalone/.next/static/chunks/{3741-81560b0aef166f49.js → 3741-b70e2d1a48a087d6.js} +16 -9
  62. package/.next/standalone/.next/static/chunks/3741-b70e2d1a48a087d6.js.map +1 -0
  63. package/.next/standalone/.next/static/chunks/app/{layout-31009df0f341ccf5.js → layout-84c6f211a7a1ca36.js} +38 -5
  64. package/.next/standalone/.next/static/chunks/app/layout-84c6f211a7a1ca36.js.map +1 -0
  65. package/.next/standalone/.next/static/chunks/app/{page-108f526cb6e48b7b.js → page-31e4d0ad258be21a.js} +258 -122
  66. package/.next/standalone/.next/static/chunks/app/page-31e4d0ad258be21a.js.map +1 -0
  67. package/.next/standalone/.next/static/css/af02b3acc7d8f08d.css +5 -0
  68. package/.next/standalone/.next/static/css/af02b3acc7d8f08d.css.map +1 -0
  69. package/.next/standalone/package.json +1 -1
  70. package/.next/standalone/public/manifest.json +2 -2
  71. package/CHANGELOG.md +24 -0
  72. package/api/types.ts +3 -1
  73. package/app/layout.tsx +30 -1
  74. package/components/agents/AgentEditor.tsx +5 -5
  75. package/components/layout/AppShell.tsx +36 -18
  76. package/components/layout/MenuPanel.tsx +7 -7
  77. package/components/models/ModelEditor.tsx +3 -3
  78. package/components/profile/ProfileEditor.tsx +9 -9
  79. package/components/profile/ProfilePanel.tsx +3 -3
  80. package/components/setup/OnboardingWizard.tsx +4 -4
  81. package/components/ui/HeaderActivity.tsx +24 -0
  82. package/contexts/AppContext.tsx +12 -4
  83. package/contexts/ThemeContext.tsx +30 -1
  84. package/hooks/useSSE.ts +42 -5
  85. package/lib/agents/base.ts +3 -1
  86. package/lib/agents/run-thread.ts +6 -3
  87. package/lib/ui/loading.ts +59 -0
  88. package/package.json +1 -1
  89. package/public/manifest.json +2 -2
  90. package/.next/standalone/.next/server/chunks/5745.js.map +0 -1
  91. package/.next/standalone/.next/static/chunks/3741-81560b0aef166f49.js.map +0 -1
  92. package/.next/standalone/.next/static/chunks/app/layout-31009df0f341ccf5.js.map +0 -1
  93. package/.next/standalone/.next/static/chunks/app/page-108f526cb6e48b7b.js.map +0 -1
  94. package/.next/standalone/.next/static/css/a23baa1c79db0435.css +0 -5
  95. package/.next/standalone/.next/static/css/a23baa1c79db0435.css.map +0 -1
  96. package/components/ui/TopProgressBar.tsx +0 -32
  97. /package/.next/standalone/.next/static/{0ImXz-nn9QbojXpTvB3i0 → yk5tOLkAUA4hfQKDjGbzK}/_buildManifest.js +0 -0
  98. /package/.next/standalone/.next/static/{0ImXz-nn9QbojXpTvB3i0 → yk5tOLkAUA4hfQKDjGbzK}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"7885.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/triggers/registry.ts","webpack://@circuitwall/jarela/./lib/triggers/runner.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/scheduled-task.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/watcher.ts","webpack://@circuitwall/jarela/./lib/documents/reindex-local-file.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/fs-watch.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/document-fast-sweep.ts","webpack://@circuitwall/jarela/./lib/triggers/reactions/notify.ts","webpack://@circuitwall/jarela/./lib/triggers/index.ts","webpack://@circuitwall/jarela/./lib/voice/constants.ts","webpack://@circuitwall/jarela/./lib/voice/gemini.ts","webpack://@circuitwall/jarela/./lib/documents/search.ts","webpack://@circuitwall/jarela/./lib/scheduler/index.ts","webpack://@circuitwall/jarela/./lib/agents/conversation-summary.ts","webpack://@circuitwall/jarela/./lib/tools/external.ts","webpack://@circuitwall/jarela/./lib/agents/stream-collector.ts","webpack://@circuitwall/jarela/./lib/tools/memory.ts","webpack://@circuitwall/jarela/./lib/tools/documents.ts","webpack://@circuitwall/jarela/./lib/tools/exec.ts","webpack://@circuitwall/jarela/./lib/tools/files.ts","webpack://@circuitwall/jarela/./lib/tools/search.ts","webpack://@circuitwall/jarela/./lib/utils/private-ip.ts","webpack://@circuitwall/jarela/./lib/tools/fetch.ts","webpack://@circuitwall/jarela/./lib/tools/location.ts","webpack://@circuitwall/jarela/./lib/tools/generate_image.ts","webpack://@circuitwall/jarela/./lib/tools/generate_voice.ts","webpack://@circuitwall/jarela/./lib/tools/schedule.ts","webpack://@circuitwall/jarela/./lib/tools/watcher.ts","webpack://@circuitwall/jarela/./lib/tools/propose.ts","webpack://@circuitwall/jarela/./lib/tools/integrations.ts","webpack://@circuitwall/jarela/./lib/tools/calendar.ts","webpack://@circuitwall/jarela/./lib/tools/outlook-calendar.ts","webpack://@circuitwall/jarela/./lib/tools/builtins.ts","webpack://@circuitwall/jarela/./lib/tools/index.ts","webpack://@circuitwall/jarela/./lib/stores/tool-stats.ts","webpack://@circuitwall/jarela/./lib/files.ts","webpack://@circuitwall/jarela/./lib/stores/builtin-tools.ts","webpack://@circuitwall/jarela/./lib/utils/google-api.ts","webpack://@circuitwall/jarela/./lib/stores/user-profile.ts","webpack://@circuitwall/jarela/./lib/env/config.ts","webpack://@circuitwall/jarela/./lib/stores/scheduled-tasks.ts","webpack://@circuitwall/jarela/./lib/providers/jarela-chat-model.ts","webpack://@circuitwall/jarela/./lib/stores/langgraph-store.ts","webpack://@circuitwall/jarela/./lib/agents/sqlite-checkpoint-saver.ts","webpack://@circuitwall/jarela/./lib/agents/checkpointer.ts","webpack://@circuitwall/jarela/./lib/agents/llm.ts","webpack://@circuitwall/jarela/./lib/agents/adaptive-persona.ts","webpack://@circuitwall/jarela/./lib/agents/harness/resolve.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/claim-detector.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/citation-parser.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/validator.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/index.ts","webpack://@circuitwall/jarela/./lib/agents/context-budget.ts","webpack://@circuitwall/jarela/./lib/agents/run-thread.ts","webpack://@circuitwall/jarela/./lib/triggers/scripts.ts","webpack://@circuitwall/jarela/./lib/stores/tool-secrets.ts","webpack://@circuitwall/jarela/./lib/stores/threads.ts","webpack://@circuitwall/jarela/./lib/stores/reaction-shared.ts","webpack://@circuitwall/jarela/./lib/stores/watchers.ts"],"sourcesContent":["import type { TriggerHandler } from \"./types\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\n// Module-level registry. getOrCreateGlobal so HMR / repeated imports in\n// dev don't lose registrations across module re-evaluations.\ninterface RegistryState {\n handlers: Map<string, TriggerHandler>;\n}\nconst state = getOrCreateGlobal<RegistryState>(\"__jarela_trigger_registry\", () => ({\n handlers: new Map(),\n}));\n\nexport function registerTriggerHandler(handler: TriggerHandler): void {\n state.handlers.set(handler.kind, handler);\n}\n\nexport function getTriggerHandler(kind: string): TriggerHandler | undefined {\n return state.handlers.get(kind);\n}\n\nexport function listTriggerHandlers(): TriggerHandler[] {\n return Array.from(state.handlers.values());\n}\n\n// Test helper. Not exposed in the public surface — only the test file\n// reaches in to reset.\nexport function __resetTriggerRegistry(): void {\n state.handlers.clear();\n}\n","import { getOrCreateAgentThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { prepareThreadRun, persistAssistantMessage } from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { getScript } from \"./scripts\";\nimport type {\n PromptFiring,\n ScriptFiring,\n TriggerFiring,\n TriggerOutcome,\n} from \"./types\";\n\n/**\n * Invoke an agent for one prompt firing. Extracted from the original\n * scheduler `runTask` so any handler that wants chat semantics goes\n * through the exact same run/persist/silent code path.\n *\n * The runner does NOT publish notifications — different trigger kinds\n * want different notification payloads, so that responsibility stays\n * with each handler's markFired().\n */\nexport async function runTriggerAgent(firing: PromptFiring): Promise<TriggerOutcome> {\n const agent = getAgentConfig(firing.agentId);\n if (!agent) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Agent \"${firing.agentId}\" not found`,\n };\n }\n const thread = getOrCreateAgentThread(firing.agentId);\n const category = firing.category ?? firing.kind;\n\n // Silent mode: wrap the prompt with a \"reply only if material\" directive\n // AND a NO_REPLY sentinel so the post-run code can drop the assistant\n // turn entirely when nothing is worth surfacing. Visibility itself is\n // handled at the chat-panel layer via the category-filter toolbar.\n const effectivePrompt = firing.silent\n ? `${firing.prompt}\\n\\n[SILENT_TRIGGER] This prompt was triggered automatically. Reply with information only if there is something material the user needs to see right now. If nothing material to report, reply with exactly the single token NO_REPLY and nothing else.`\n : firing.prompt;\n\n try {\n const prepared = await prepareThreadRun(\n thread.thread_id,\n effectivePrompt,\n undefined,\n undefined,\n undefined,\n undefined,\n category,\n );\n const collected = await collectStream(prepared.stream);\n const replyText = collected.assistantContent.trim();\n const isNoReply = firing.silent === true && /^\\s*NO[_ ]?REPLY\\b/i.test(replyText);\n const skipAssistant = firing.silent === true && (isNoReply || replyText.length === 0);\n if (!skipAssistant) {\n persistAssistantMessage(\n thread.thread_id,\n collected.assistantContent,\n collected.usedTools,\n collected.toolEvents,\n category,\n );\n }\n return {\n status: skipAssistant ? \"skipped\" : \"done\",\n preview: skipAssistant\n ? \"\"\n : collected.assistantContent.replace(/\\s+/g, \" \").trim().slice(0, 120),\n threadId: thread.thread_id,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: thread.thread_id,\n error: msg,\n };\n }\n}\n\n/**\n * Run an in-process script for one script firing. No thread, no LLM,\n * no message persistence — the script does its own side effects. The\n * preview goes into TriggerOutcome for telemetry / notifications.\n */\nexport async function runTriggerScript(firing: ScriptFiring): Promise<TriggerOutcome> {\n const fn = getScript(firing.script);\n if (!fn) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Script \"${firing.script}\" not registered`,\n };\n }\n try {\n const result = await fn(firing.args ?? {});\n return {\n status: \"done\",\n preview: result.preview,\n threadId: \"\",\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n };\n }\n}\n\n/**\n * Dispatch one firing by mode. The fan-out loop in runTriggerTick\n * goes through here so handlers don't have to know which runner to\n * call.\n */\nexport async function runTriggerFiring(firing: TriggerFiring): Promise<TriggerOutcome> {\n if (firing.mode === \"script\") return runTriggerScript(firing);\n return runTriggerAgent(firing);\n}\n","import {\n getDueTasks,\n markTaskRan,\n getScheduledTask,\n type ScheduledTaskRow,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport type {\n TriggerFiring,\n TriggerHandler,\n TriggerOutcome,\n} from \"../types\";\n\nexport const SCHEDULED_TASK_KIND = \"scheduled_task\";\n\n/**\n * ADR-0032 — produce the right firing for a scheduled task. Routes on\n * `reaction_kind`: 'agent_prompt' → PromptFiring (the original ADR-0021\n * path); 'script' → ScriptFiring dispatched through the trigger runner\n * with no LLM round-trip. Unlike watchers, scheduled-task script firings\n * do NOT carry diff context (`previous`/`current`) — there's no diff to\n * report. Scripts that don't read those fields work in both contexts\n * unchanged.\n */\nfunction buildFiring(task: ScheduledTaskRow): TriggerFiring {\n if (task.reaction_kind === \"script\" && task.reaction_script) {\n let userArgs: Record<string, unknown> = {};\n if (task.reaction_script_args) {\n try {\n const parsed = JSON.parse(task.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty.\n }\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"script\",\n script: task.reaction_script,\n args: {\n ...userArgs,\n task: {\n id: task.id,\n agent_id: task.agent_id,\n description: task.description,\n schedule: task.schedule,\n schedule_kind: task.kind,\n },\n },\n meta: {\n agent_id: task.agent_id,\n schedule: task.schedule,\n scheduleKind: task.kind,\n reaction_kind: \"script\",\n reaction_script: task.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this task.\n silent: task.silent === 1,\n },\n };\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"prompt\",\n agentId: task.agent_id,\n prompt: task.prompt,\n silent: task.silent === 1,\n // Preserves the existing message-channel filter behaviour (ADR-0022).\n category: \"scheduled_task\",\n meta: { schedule: task.schedule, scheduleKind: task.kind, reaction_kind: \"agent_prompt\", silent: task.silent === 1 },\n };\n}\n\nexport const scheduledTaskHandler: TriggerHandler = {\n kind: SCHEDULED_TASK_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n return getDueTasks(asOf).map(buildFiring);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n const scheduleKind = (firing.meta?.scheduleKind as ScheduledTaskRow[\"kind\"] | undefined) ?? \"cron\";\n const schedule = (firing.meta?.schedule as string | undefined) ?? \"\";\n // Always advance the schedule (or delete the row for one-shots),\n // regardless of which firing mode we ran.\n markTaskRan(firing.id, scheduleKind, schedule, outcome.error);\n\n // ADR-0032 — silent=true on the task suppresses both NO_REPLY-style\n // agent behaviour AND the task_completed notification. Errors still\n // surface so the user sees failures even on muted tasks.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n // ADR-0032 — script firings publish a synthesised notification so the\n // UI event stream still lights up. No thread, so threadId is empty.\n const meta = (firing.meta ?? {}) as { agent_id?: string; reaction_script?: string };\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Scheduled task fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/** Public helper for the \"Run now\" API route — fires a single task by id. */\nexport function firingForTaskId(taskId: string): TriggerFiring | null {\n const task = getScheduledTask(taskId);\n return task ? buildFiring(task) : null;\n}\n","// Watcher trigger handler (ADR-0027). Sibling of scheduled-task.ts.\n//\n// Per scheduler tick, for every due watcher row:\n// 1. Resolve the named tool from the built-in registry.\n// 2. Invoke it with the saved JSON args (no agent context — watcher\n// tools must be context-free).\n// 3. Hash the stringified result and compare to last_fingerprint.\n// 4. If the hash differs from the previous run, return a TriggerFiring\n// whose prompt embeds a compact previous->current diff for the agent.\n// If it matches (or this is the first run with no previous), record\n// the fingerprint and skip — no LLM call, no firing.\n// 5. Either way the watcher's next_run_at is advanced by\n// interval_seconds. Errors during polling are recorded on the row\n// and surfaced in the UI.\n//\n// All scheduling work happens inside `getDueFirings` because the\n// abstraction's markFired is only called for actually-fired runs.\nimport { createHash } from \"node:crypto\";\nimport {\n getDueWatchers,\n getWatcher,\n recordWatcherPoll,\n recordWatcherPollError,\n type WatcherRow,\n} from \"@/lib/stores/watchers\";\nimport { registeredTools } from \"@/lib/tools/registry\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport type { TriggerFiring, TriggerHandler, TriggerOutcome } from \"../types\";\n\nexport const WATCHER_KIND = \"watcher\";\n\nfunction fingerprint(s: string): string {\n return createHash(\"sha256\").update(s).digest(\"hex\");\n}\n\nfunction stringifyResult(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nconst DEFAULT_REACTION_DIRECTIVE =\n `Summarise what changed and decide whether the user needs to know. ` +\n `If nothing material changed, you may stay silent.`;\n\n// Watcher tool outputs can be very large (full JSON payloads, long lists).\n// Keep the diff context bounded so one firing cannot consume most of an\n// agent's prompt budget.\nconst MAX_DIFF_CONTEXT_BYTES = 3500;\n\nfunction normalizeForDiff(raw: string): string {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2);\n } catch {\n return raw;\n }\n}\n\nfunction buildDiffForPrompt(previous: string | null, current: string): string {\n if (previous === null) return \"+ (first observation baseline established; no diff available)\";\n\n const prev = normalizeForDiff(previous).split(/\\r?\\n/);\n const curr = normalizeForDiff(current).split(/\\r?\\n/);\n\n let start = 0;\n while (start < prev.length && start < curr.length && prev[start] === curr[start]) {\n start += 1;\n }\n\n let prevEnd = prev.length - 1;\n let currEnd = curr.length - 1;\n while (prevEnd >= start && currEnd >= start && prev[prevEnd] === curr[currEnd]) {\n prevEnd -= 1;\n currEnd -= 1;\n }\n\n const removed = prev.slice(start, prevEnd + 1);\n const added = curr.slice(start, currEnd + 1);\n if (removed.length === 0 && added.length === 0) {\n return \"(no textual diff after normalization)\";\n }\n\n const hunkHeader = `@@ old:${start + 1}-${Math.max(start, prevEnd + 1)} new:${start + 1}-${Math.max(start, currEnd + 1)} @@`;\n const raw = [\n hunkHeader,\n ...removed.map((l) => `- ${l}`),\n ...added.map((l) => `+ ${l}`),\n ].join(\"\\n\");\n\n const bytes = Buffer.byteLength(raw, \"utf8\");\n const clipped = truncateBytes(raw, MAX_DIFF_CONTEXT_BYTES);\n if (!clipped.truncated) return raw;\n return `${clipped.text}\\n… [diff truncated: showing ${MAX_DIFF_CONTEXT_BYTES} of ${bytes} bytes; full values retained in watcher state]`;\n}\n\nfunction buildFiringPrompt(watcher: WatcherRow, previous: string | null, current: string): string {\n const argsPretty = (() => {\n try { return JSON.stringify(JSON.parse(watcher.tool_args), null, 2); }\n catch { return watcher.tool_args; }\n })();\n // ADR-0030: a non-null reaction_prompt swaps in for the default directive.\n // The diff envelope (label/tool/args/diff) is unchanged so the agent\n // always has the change context regardless of the user's instruction.\n const directive = watcher.reaction_prompt?.trim() || DEFAULT_REACTION_DIRECTIVE;\n return [\n `Watcher \"${watcher.label}\" detected a change.`,\n ``,\n `Tool: ${watcher.tool_name}`,\n `Args: ${argsPretty}`,\n ``,\n `--- Diff (previous -> current) ---`,\n buildDiffForPrompt(previous, current),\n ``,\n directive,\n ].join(\"\\n\");\n}\n\n/**\n * ADR-0031 — build the args bundle handed to a `reaction.*` script when\n * a watcher with reaction_kind='script' fires. The bundle merges the\n * user-supplied script args with diff context (previous + current\n * stringified results, plus a slim `watcher` descriptor) so any reaction\n * script can access both the static config and the change context.\n */\nfunction buildScriptArgs(watcher: WatcherRow, previous: string | null, current: string): Record<string, unknown> {\n let userArgs: Record<string, unknown> = {};\n if (watcher.reaction_script_args) {\n try {\n const parsed = JSON.parse(watcher.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty so the script still\n // runs with diff context.\n }\n }\n return {\n ...userArgs,\n watcher: {\n id: watcher.id,\n label: watcher.label,\n tool_name: watcher.tool_name,\n tool_args: safeJson(watcher.tool_args),\n agent_id: watcher.agent_id,\n },\n previous,\n current,\n };\n}\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\n/**\n * ADR-0031 — produce the right firing for a watcher that just observed\n * a change. Routes on `reaction_kind`: 'agent_prompt' → PromptFiring (the\n * original ADR-0027 path); 'script' → ScriptFiring dispatched through\n * the trigger runner with no LLM round-trip.\n */\nfunction buildFiring(watcher: WatcherRow, previous: string | null, current: string): TriggerFiring {\n if (watcher.reaction_kind === \"script\" && watcher.reaction_script) {\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"script\",\n script: watcher.reaction_script,\n args: buildScriptArgs(watcher, previous, current),\n meta: {\n label: watcher.label,\n tool_name: watcher.tool_name,\n agent_id: watcher.agent_id,\n reaction_kind: \"script\",\n reaction_script: watcher.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this watcher.\n silent: watcher.silent === 1,\n },\n };\n }\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"prompt\",\n agentId: watcher.agent_id,\n prompt: buildFiringPrompt(watcher, previous, current),\n silent: watcher.silent === 1,\n category: \"watcher\",\n meta: { label: watcher.label, tool_name: watcher.tool_name, reaction_kind: \"agent_prompt\", silent: watcher.silent === 1 },\n };\n}\n\nasync function invokeWatcherTool(watcher: WatcherRow): Promise<string> {\n const entry = registeredTools().find((t) => t.name === watcher.tool_name);\n if (!entry) throw new Error(`tool \"${watcher.tool_name}\" is not registered`);\n let args: unknown;\n try { args = JSON.parse(watcher.tool_args); }\n catch (e) { throw new Error(`tool_args is not valid JSON: ${e instanceof Error ? e.message : String(e)}`); }\n // LangChain tools accept the args object directly via .invoke().\n // Watcher tools must be context-free (no thread_id / agent_id).\n const result = await entry.invoke(args as Record<string, unknown>);\n return stringifyResult(result);\n}\n\n/**\n * Poll every due watcher and produce firings only for those whose\n * tool result changed since the last poll. Updates polling state\n * synchronously so subsequent ticks see the advanced next_run_at.\n */\nasync function pollDueWatchers(asOf: Date): Promise<TriggerFiring[]> {\n const due = getDueWatchers(asOf);\n const firings: TriggerFiring[] = [];\n for (const watcher of due) {\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({\n id: watcher.id,\n fingerprint: fp,\n result,\n fired: changed,\n });\n if (changed) {\n firings.push(buildFiring(watcher, watcher.last_result, result));\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n // A polling error doesn't fire the agent; it's surfaced via\n // last_error on the row + UI. Logging only.\n console.error(`[watcher] poll ${watcher.id} (${watcher.tool_name}) failed:`, msg);\n }\n }\n return firings;\n}\n\nexport const watcherHandler: TriggerHandler = {\n kind: WATCHER_KIND,\n\n async getDueFirings(asOf: Date): Promise<TriggerFiring[]> {\n return pollDueWatchers(asOf);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n // Polling state (last_run_at, last_fingerprint, last_result,\n // next_run_at) was already advanced inside getDueFirings — we only\n // publish a notification here so the UI's event stream lights up.\n // ADR-0031 — script firings publish too; reuse `task_completed` with\n // a synthesised prompt and the watcher's agent_id from meta (script\n // firings have no thread, so threadId is empty).\n // silent=true on the watcher suppresses the notification (in addition\n // to the prompt-mode NO_REPLY semantic). Errors still surface.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n const meta = (firing.meta ?? {}) as { label?: string; agent_id?: string; reaction_script?: string };\n const label = meta.label ?? \"(watcher)\";\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/**\n * \"Run now\" — force a single poll of one watcher and, if the result\n * differs from `last_fingerprint`, return a ready-to-run firing. Used by\n * the manual /run HTTP endpoint. Returns null when the poll didn't\n * trigger a firing (no change, or the watcher is gone).\n */\nexport async function firingForWatcherIdNow(id: string): Promise<TriggerFiring | null> {\n const watcher = getWatcher(id);\n if (!watcher) return null;\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({ id: watcher.id, fingerprint: fp, result, fired: changed });\n if (!changed) return null;\n return buildFiring(watcher, watcher.last_result, result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n throw err;\n }\n}\n","// Single-file re-index path used by the fs-watch trigger.\n//\n// The full sweep in indexer.ts handles \"scan everything\" semantics —\n// allowlists, size caps, deletion sweeps. For watcher firings we\n// already know the absolute path, so we duplicate just the per-file\n// part: stat → read → hash → upsert (or delete).\n\nimport { promises as fs } from \"node:fs\";\nimport { relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { getDocumentSource } from \"@/lib/stores/document-sources\";\nimport { registerScript } from \"@/lib/triggers/scripts\";\nimport {\n ALLOWED_EXT,\n MAX_FILE_BYTES,\n hashContent,\n lowerExt,\n readTextFile,\n upsertLocalDocument,\n type FileEntry,\n} from \"./indexer\";\n\nexport interface ReindexResult {\n preview: string;\n}\n\n/**\n * Re-index a single file inside a local_folder source. Idempotent;\n * returns \"deleted\" / \"skipped\" / \"added\" / \"updated\" / \"unchanged\".\n */\nexport async function reindexLocalFile(args: {\n source_id: string;\n abs: string;\n}): Promise<ReindexResult> {\n const source = getDocumentSource(args.source_id);\n if (!source) return { preview: `skipped: source ${args.source_id} missing` };\n if (source.kind !== \"local_folder\") {\n return { preview: `skipped: source ${args.source_id} is not local_folder` };\n }\n\n const db = getDb();\n\n let stat;\n try {\n stat = await fs.stat(args.abs);\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n // File gone — drop the row (chunks cascade via FK).\n const info = db\n .prepare(\"DELETE FROM documents WHERE source_id=? AND path=?\")\n .run(args.source_id, args.abs);\n return {\n preview: info.changes > 0 ? `deleted ${args.abs}` : `skipped: not indexed (${args.abs})`,\n };\n }\n throw err;\n }\n\n if (!stat.isFile()) return { preview: `skipped: not a regular file (${args.abs})` };\n if (stat.size > MAX_FILE_BYTES) return { preview: `skipped: file > MAX_FILE_BYTES (${args.abs})` };\n\n // Watchers don't pre-filter by extension as aggressively as the\n // sweep does, so re-check here. Keeps the allowlist as the single\n // source of truth even if a future caller forgets.\n if (!ALLOWED_EXT.has(lowerExt(args.abs))) {\n return { preview: `skipped: ext not allowed (${args.abs})` };\n }\n\n const text = await readTextFile(args.abs);\n if (text === null) return { preview: `skipped: binary or unreadable (${args.abs})` };\n\n const hash = hashContent(text);\n const existing = db\n .prepare(\n \"SELECT id, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=? AND path=?\",\n )\n .get(args.source_id, args.abs) as\n | { id: string; mtime_ms: number; size_bytes: number; content_hash: string }\n | undefined;\n\n if (existing && existing.content_hash === hash) {\n // Mtime/size may have shifted (touch / OneDrive sync) but content\n // is unchanged — touch the row instead of re-embedding.\n db.prepare(\n \"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\",\n ).run(Math.floor(stat.mtimeMs), stat.size, new Date().toISOString(), existing.id);\n return { preview: `unchanged ${args.abs}` };\n }\n\n const f: FileEntry = {\n abs: args.abs,\n rel: relative(source.path, args.abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(stat.mtimeMs),\n size: stat.size,\n };\n await upsertLocalDocument(args.source_id, f, text, hash, existing?.id);\n return { preview: existing ? `updated ${args.abs}` : `added ${args.abs}` };\n}\n\n// Registry side-effect: register the script the fs-watch handler\n// emits. Importing this module wires it. Call sites are\n// instrumentation.ts (boot) and the fs-watch handler module\n// (defensive in case boot order changes).\nlet registered = false;\nexport function registerDocumentScripts(): void {\n if (registered) return;\n registerScript(\"documents.reindex_local_file\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n const abs = String(args.abs ?? \"\");\n if (!sourceId || !abs) {\n return { preview: \"skipped: missing source_id or abs\" };\n }\n return reindexLocalFile({ source_id: sourceId, abs });\n });\n registered = true;\n}\n\nregisterDocumentScripts();\n","// fs.watch-driven re-indexing for local document sources.\n//\n// Boots one watcher per enabled `local_folder` source. Filesystem events\n// are filtered (skip dot-dirs / build output / disallowed extensions)\n// and debounced per-(source_id, abs) for 500 ms. Each surviving event\n// becomes a ScriptFiring that the runner dispatches to\n// `documents.reindex_local_file`.\n//\n// On Linux, fs.watch with `recursive: true` is unsupported — we log\n// once per source and rely on the 10-min full sweep there. On macOS\n// and Windows this gives sub-second propagation from save-to-search.\n\nimport { promises as fs, type FSWatcher, watch as fsWatch } from \"node:fs\";\nimport { join, sep } from \"node:path\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { listEnabledDocumentSources } from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, SKIP_DIRS, lowerExt } from \"@/lib/documents/indexer\";\n// Side-effect import: ensures `documents.reindex_local_file` is in the\n// script registry before the first firing dispatches.\nimport \"@/lib/documents/reindex-local-file\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const FS_WATCH_KIND = \"fs_watch\";\n\nconst DEBOUNCE_MS = 500;\n\ninterface WatcherState {\n sourceId: string;\n rootPath: string;\n watcher: FSWatcher | null;\n /** Map<abs, debounce-timer-id> while a debounce is in flight. */\n debounceTimers: Map<string, NodeJS.Timeout>;\n}\n\ninterface FsWatchState {\n watchers: Map<string, WatcherState>; // sourceId → state\n /** Coalesced pending firings, keyed by `${source_id}:${abs}`. */\n pending: Map<string, { source_id: string; abs: string }>;\n unsupportedLogged: Set<string>;\n}\n\n// Stored on globalThis: Next's standalone build bundles this module into\n// multiple chunks (one per route that transitively imports it), and each\n// chunk would otherwise have its own copy of `state`. Without the global\n// pin, the chunk that runs `attachWatcher` enqueues into a different Map\n// than the chunk the scheduler tick reads via `drainPending`.\nconst state = getOrCreateGlobal<FsWatchState>(\"__jarela_fs_watch_state\", () => ({\n watchers: new Map(),\n pending: new Map(),\n unsupportedLogged: new Set(),\n}));\n\nfunction pendingKey(sourceId: string, abs: string): string {\n return `${sourceId}:${abs}`;\n}\n\nfunction enqueuePending(sourceId: string, abs: string): void {\n state.pending.set(pendingKey(sourceId, abs), { source_id: sourceId, abs });\n}\n\nfunction scheduleDebounce(w: WatcherState, abs: string): void {\n const existing = w.debounceTimers.get(abs);\n if (existing) clearTimeout(existing);\n const t = setTimeout(() => {\n w.debounceTimers.delete(abs);\n enqueuePending(w.sourceId, abs);\n }, DEBOUNCE_MS);\n // Don't keep the event loop alive just for the debounce.\n if (typeof t.unref === \"function\") t.unref();\n w.debounceTimers.set(abs, t);\n}\n\nfunction handleEvent(w: WatcherState, filename: string | null): void {\n if (!filename) return;\n // Filter dot-dirs and SKIP_DIRS inline. We can't trust the\n // recursive watcher to honour them.\n const segments = filename.split(/[\\\\/]+/).filter((s) => s.length > 0);\n if (segments.length === 0) return;\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (SKIP_DIRS.has(seg)) return;\n if (seg.startsWith(\".\")) return;\n }\n const file = segments[segments.length - 1];\n if (!ALLOWED_EXT.has(lowerExt(file))) return;\n const abs = join(w.rootPath, ...segments);\n scheduleDebounce(w, abs);\n}\n\nasync function attachWatcher(sourceId: string, rootPath: string): Promise<void> {\n if (state.watchers.has(sourceId)) return;\n // Confirm the directory still exists; fs.watch on a nonexistent path\n // throws synchronously and tears down the boot loop.\n try {\n const st = await fs.stat(rootPath);\n if (!st.isDirectory()) return;\n } catch {\n return;\n }\n\n const w: WatcherState = {\n sourceId,\n rootPath,\n watcher: null,\n debounceTimers: new Map(),\n };\n try {\n w.watcher = fsWatch(\n rootPath,\n { recursive: true, persistent: false },\n (_event, filename) => {\n const name: string | null =\n typeof filename === \"string\"\n ? filename\n : filename\n ? (filename as Buffer).toString()\n : null;\n handleEvent(w, name);\n },\n );\n w.watcher.on(\"error\", (err) => {\n console.warn(`[triggers/fs_watch] watcher error for ${rootPath}:`, err.message);\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ERR_FEATURE_UNAVAILABLE_ON_PLATFORM\") {\n // Linux: recursive fs.watch isn't supported. Falling back to the\n // 10-min full sweep is fine — log once per source.\n if (!state.unsupportedLogged.has(sourceId)) {\n console.warn(\n `[triggers/fs_watch] recursive fs.watch unsupported on this platform; ` +\n `relying on the full sweep for source \"${rootPath}\"`,\n );\n state.unsupportedLogged.add(sourceId);\n }\n return;\n }\n console.warn(`[triggers/fs_watch] failed to attach watcher to ${rootPath}:`, e.message);\n return;\n }\n state.watchers.set(sourceId, w);\n}\n\nfunction detachWatcher(sourceId: string): void {\n const w = state.watchers.get(sourceId);\n if (!w) return;\n for (const t of w.debounceTimers.values()) clearTimeout(t);\n w.debounceTimers.clear();\n if (w.watcher) {\n try { w.watcher.close(); } catch { /* noop */ }\n }\n state.watchers.delete(sourceId);\n}\n\nasync function syncWatchers(): Promise<void> {\n const sources = listEnabledDocumentSources().filter((s) => s.kind === \"local_folder\");\n const wantSourceIds = new Set(sources.map((s) => s.id));\n\n // Drop watchers whose source disappeared / disabled.\n for (const sourceId of Array.from(state.watchers.keys())) {\n if (!wantSourceIds.has(sourceId)) {\n detachWatcher(sourceId);\n }\n }\n\n // Attach new watchers.\n for (const s of sources) {\n if (state.watchers.has(s.id)) continue;\n await attachWatcher(s.id, s.path);\n }\n}\n\nfunction drainPending(): ScriptFiring[] {\n if (state.pending.size === 0) return [];\n const now = Date.now();\n const firings: ScriptFiring[] = [];\n for (const { source_id, abs } of state.pending.values()) {\n firings.push({\n id: `${source_id}:${abs}:${now}`,\n kind: FS_WATCH_KIND,\n mode: \"script\",\n script: \"documents.reindex_local_file\",\n args: { source_id, abs },\n });\n }\n state.pending.clear();\n return firings;\n}\n\nexport const fsWatchHandler: TriggerHandler = {\n kind: FS_WATCH_KIND,\n\n async start(): Promise<void> {\n await syncWatchers();\n },\n\n async sync(): Promise<void> {\n await syncWatchers();\n },\n\n async stop(): Promise<void> {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n },\n\n getDueFirings(_asOf: Date): TriggerFiring[] {\n return drainPending();\n },\n\n markFired(): void {\n // The script writes its own state into `documents`. Nothing extra\n // to bookkeep here — keeping this empty also means re-firing after\n // an error is the next watcher event, which is the right thing.\n },\n};\n\n/** Test-only helper. */\nexport function __resetFsWatchState(): void {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n state.unsupportedLogged.clear();\n}\n\n/** Test-only helper. Pumps a synthetic event without touching the real fs. */\nexport function __pushEventForTest(sourceId: string, rootPath: string, filename: string): void {\n let w = state.watchers.get(sourceId);\n if (!w) {\n w = { sourceId, rootPath, watcher: null, debounceTimers: new Map() };\n state.watchers.set(sourceId, w);\n }\n handleEvent(w, filename);\n}\n","// Fast (60 s) re-sweep loop for remote document sources.\n//\n// Local folders use fs.watch for low-latency reindexing; remote\n// sources (Confluence / Jira) have no inotify equivalent, so we poll\n// — but at a much higher cadence than the 10-min full sweep. Each\n// source's existing cursor (last_cursor on document_sources) means\n// the upstream API call only fetches what changed since last poll,\n// keeping rate-limit pressure low.\n\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n} from \"@/lib/stores/document-sources\";\nimport { isRemoteKind, runRemoteSource } from \"@/lib/documents/remote\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { registerScript } from \"../scripts\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const DOCUMENT_FAST_SWEEP_KIND = \"doc_fast_sweep\";\n\nconst DEFAULT_INTERVAL_MS = 60_000;\n\nfunction intervalMs(): number {\n const raw = process.env.JARELA_FAST_REMOTE_SWEEP_MS;\n if (!raw) return DEFAULT_INTERVAL_MS;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 1000 ? n : DEFAULT_INTERVAL_MS;\n}\n\ninterface SweepState {\n /** sourceId → last fired (ms epoch). */\n lastRunAt: Map<string, number>;\n}\n\n// Pinned to globalThis: Next's standalone build bundles handler files\n// into multiple chunks, and module-local state would otherwise be split\n// across them. See lib/triggers/handlers/fs-watch.ts for the same fix.\nconst state = getOrCreateGlobal<SweepState>(\n \"__jarela_doc_fast_sweep_state\",\n () => ({ lastRunAt: new Map() }),\n);\n\nlet scriptRegistered = false;\nfunction registerSweepScript(): void {\n if (scriptRegistered) return;\n registerScript(\"documents.run_remote_source\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n if (!sourceId) return { preview: \"skipped: missing source_id\" };\n // Resolve the source row at fire time so we always pick up the\n // latest config / cursor without caching it.\n const sources = listEnabledDocumentSources();\n const source = sources.find((s) => s.id === sourceId);\n if (!source) return { preview: `skipped: source ${sourceId} not enabled` };\n if (!isRemoteKind(source.kind)) {\n return { preview: `skipped: source ${sourceId} is not a remote kind` };\n }\n try {\n const stats = await runRemoteSource(source);\n return {\n preview:\n `${source.kind} ${source.path}: ` +\n `+${stats.added} ~${stats.updated} =${stats.unchanged} !${stats.errors}`,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // The runRemoteSource path normally swallows its own errors; if\n // something escaped, mark the source so the panel surfaces it.\n try { markSourceScanned(source.id, msg); } catch { /* noop */ }\n throw err;\n }\n });\n scriptRegistered = true;\n}\n\nregisterSweepScript();\n\nexport const documentFastSweepHandler: TriggerHandler = {\n kind: DOCUMENT_FAST_SWEEP_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n const now = asOf.getTime();\n const interval = intervalMs();\n const sources = listEnabledDocumentSources().filter((s) => isRemoteKind(s.kind));\n const firings: ScriptFiring[] = [];\n for (const s of sources) {\n const last = state.lastRunAt.get(s.id) ?? 0;\n if (now - last < interval) continue;\n firings.push({\n id: `${s.id}:${now}`,\n kind: DOCUMENT_FAST_SWEEP_KIND,\n mode: \"script\",\n script: \"documents.run_remote_source\",\n args: { source_id: s.id },\n });\n }\n return firings;\n },\n\n markFired(firing: TriggerFiring): void {\n if (firing.mode !== \"script\") return;\n const sourceId = firing.args ? String(firing.args.source_id ?? \"\") : \"\";\n if (!sourceId) return;\n // Throttle on every firing regardless of outcome — Atlassian\n // rate-limits don't differentiate between success and error.\n state.lastRunAt.set(sourceId, Date.now());\n },\n};\n\n/** Test-only helper. */\nexport function __resetFastSweepState(): void {\n state.lastRunAt.clear();\n}\n","// ADR-0031 — `reaction.notify`: a watcher reaction script that publishes\n// a `task_completed` notification with the watcher's diff preview.\n//\n// Args provided by the watcher handler at fire time (see\n// pollDueWatchers in handlers/watcher.ts):\n// { watcher: { id, label, tool_name, tool_args, agent_id },\n// previous: string | null,\n// current: string,\n// ...userArgs }\n//\n// User-supplied args (subset that this script reads):\n// { title?: string, level?: \"info\" | \"warning\" }\nimport { registerScript, type ScriptResult } from \"@/lib/triggers/scripts\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\ninterface NotifyContext {\n watcher?: {\n id?: string;\n label?: string;\n tool_name?: string;\n agent_id?: string;\n };\n previous?: string | null;\n current?: string;\n title?: string;\n level?: \"info\" | \"warning\";\n}\n\nfunction shortPreview(previous: string | null | undefined, current: string | undefined): string {\n const cur = (current ?? \"\").replace(/\\s+/g, \" \").trim();\n const prev = (previous ?? \"\").replace(/\\s+/g, \" \").trim();\n if (!prev) return cur.slice(0, 120);\n // Trivial diff: just show \"<prev> → <current>\" trimmed at both ends.\n const left = prev.slice(0, 50);\n const right = cur.slice(0, 50);\n return `${left} → ${right}`;\n}\n\nregisterScript(\"reaction.notify\", async (args: Record<string, unknown>): Promise<ScriptResult> => {\n const ctx = args as NotifyContext;\n const watcher = ctx.watcher ?? {};\n const label = watcher.label ?? \"(unknown watcher)\";\n const title = (typeof ctx.title === \"string\" && ctx.title.trim()) || label;\n const preview = shortPreview(ctx.previous, ctx.current);\n // Reuse `task_completed` as the notification surface — the UI already\n // subscribes to it for scheduled-task / agent-prompt firings, and it\n // tolerates an empty thread_id (script firings have no thread).\n publishNotification({\n type: \"task_completed\",\n task_id: watcher.id ?? \"\",\n agent_id: watcher.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" detected a change.`,\n thread_id: \"\",\n status: \"done\",\n preview,\n ts: Date.now(),\n });\n return { preview: `notify: ${title} — ${preview}`.slice(0, 160) };\n});\n","import { listTriggerHandlers, registerTriggerHandler } from \"./registry\";\nimport { runTriggerAgent, runTriggerFiring, runTriggerScript } from \"./runner\";\nimport {\n scheduledTaskHandler,\n firingForTaskId,\n SCHEDULED_TASK_KIND,\n} from \"./handlers/scheduled-task\";\nimport {\n watcherHandler,\n firingForWatcherIdNow,\n WATCHER_KIND,\n} from \"./handlers/watcher\";\nimport { fsWatchHandler } from \"./handlers/fs-watch\";\nimport { documentFastSweepHandler } from \"./handlers/document-fast-sweep\";\n// Side-effect imports: ensure built-in reaction scripts (ADR-0031) are\n// in the registry before the first watcher firing dispatches.\nimport \"./reactions/notify\";\nimport type { TriggerFiring } from \"./types\";\n\n// Single registration site for built-in handlers. Importing this file\n// from the scheduler ensures every handler is wired before the first\n// tick. Future PRs add their handlers here.\nlet registered = false;\nexport function registerHandlers(): void {\n if (registered) return;\n registerTriggerHandler(scheduledTaskHandler);\n registerTriggerHandler(watcherHandler);\n registerTriggerHandler(fsWatchHandler);\n registerTriggerHandler(documentFastSweepHandler);\n registered = true;\n}\n\n// Eager registration on module load — preserves the legacy behaviour\n// where importing this module wires the scheduled-task handler.\nregisterHandlers();\n\n/** Boot every registered handler that has a start() lifecycle hook. */\nexport async function startAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.start) continue;\n try {\n await handler.start();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" start failed:`, msg);\n }\n }\n}\n\n/** Drain every registered handler that has a stop() lifecycle hook. */\nexport async function stopAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.stop) continue;\n try {\n await handler.stop();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" stop failed:`, msg);\n }\n }\n}\n\n/**\n * Notify handlers that something they care about changed. Today this\n * is fired by the document-source mutation routes so fs-watch and the\n * fast remote sweep can re-evaluate which sources they're watching.\n */\nexport async function notifyTriggerHandlers(_reason: string): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.sync) continue;\n try {\n await handler.sync();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" sync failed:`, msg);\n }\n }\n}\n\n/** Run one tick of the trigger fan-out. Used by the scheduler loop. */\nexport async function runTriggerTick(asOf: Date = new Date()): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n let firings: TriggerFiring[];\n try {\n firings = await handler.getDueFirings(asOf);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" getDueFirings failed:`, msg);\n continue;\n }\n for (const firing of firings) {\n try {\n const outcome = await runTriggerFiring(firing);\n await handler.markFired(firing, outcome);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] firing ${handler.kind}/${firing.id} failed:`, msg);\n try {\n await handler.markFired(firing, {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n });\n } catch (innerErr) {\n console.error(\n `[triggers] handler \"${handler.kind}\" markFired threw after error:`,\n innerErr,\n );\n }\n }\n }\n }\n}\n\n/**\n * Fire a single scheduled-task by id, on demand. Preserves the original\n * runScheduledTaskNow surface: returns when the run completes, throws\n * the underlying error if the run itself threw.\n */\nexport async function runScheduledTaskFiringNow(taskId: string): Promise<void> {\n const firing = firingForTaskId(taskId);\n if (!firing) throw new Error(`scheduled task ${taskId} not found`);\n // Route through runTriggerFiring so script-kind firings dispatch\n // through the script registry instead of the agent (ADR-0032).\n const outcome = await runTriggerFiring(firing);\n await scheduledTaskHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\n/**\n * Force a single watcher to poll right now. If the polled value differs\n * from the previously stored fingerprint, fire the agent and return.\n * Returns silently when there's no diff (so the manual \"Run now\" button\n * doesn't fabricate a turn out of an unchanged poll).\n */\nexport async function runWatcherFiringNow(watcherId: string): Promise<void> {\n const firing = await firingForWatcherIdNow(watcherId);\n if (!firing) return;\n if (firing.mode !== \"prompt\") return;\n const outcome = await runTriggerAgent(firing);\n await watcherHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\nexport { SCHEDULED_TASK_KIND, WATCHER_KIND };\nexport * from \"./types\";\nexport { registerTriggerHandler, listTriggerHandlers } from \"./registry\";\nexport { runTriggerAgent, runTriggerScript, runTriggerFiring };\nexport {\n registerScript,\n getScript,\n listScripts,\n listReactionScripts,\n isReactionScript,\n REACTION_SCRIPT_PREFIX,\n} from \"./scripts\";\n","// Client-safe constants for the voice picker UI. Kept in a standalone\n// module so client components can import them without dragging server-only\n// modules (lib/db, undici, node:child_process) through the import graph.\n\nexport const GEMINI_VOICES: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"Zephyr\", label: \"Zephyr · bright\" },\n { id: \"Puck\", label: \"Puck · upbeat\" },\n { id: \"Charon\", label: \"Charon · informative\" },\n { id: \"Kore\", label: \"Kore · firm\" },\n { id: \"Fenrir\", label: \"Fenrir · excitable\" },\n { id: \"Leda\", label: \"Leda · youthful\" },\n { id: \"Orus\", label: \"Orus · firm\" },\n { id: \"Aoede\", label: \"Aoede · breezy\" },\n { id: \"Callirrhoe\", label: \"Callirrhoe · easy-going\" },\n { id: \"Autonoe\", label: \"Autonoe · bright\" },\n { id: \"Enceladus\", label: \"Enceladus · breathy\" },\n { id: \"Iapetus\", label: \"Iapetus · clear\" },\n { id: \"Umbriel\", label: \"Umbriel · easy-going\" },\n { id: \"Algieba\", label: \"Algieba · smooth\" },\n { id: \"Despina\", label: \"Despina · smooth\" },\n { id: \"Erinome\", label: \"Erinome · clear\" },\n { id: \"Algenib\", label: \"Algenib · gravelly\" },\n { id: \"Rasalgethi\", label: \"Rasalgethi · informative\" },\n { id: \"Laomedeia\", label: \"Laomedeia · upbeat\" },\n { id: \"Achernar\", label: \"Achernar · soft\" },\n { id: \"Alnilam\", label: \"Alnilam · firm\" },\n { id: \"Schedar\", label: \"Schedar · even\" },\n { id: \"Gacrux\", label: \"Gacrux · mature\" },\n { id: \"Pulcherrima\", label: \"Pulcherrima · forward\" },\n { id: \"Achird\", label: \"Achird · friendly\" },\n { id: \"Zubenelgenubi\", label: \"Zubenelgenubi · casual\" },\n { id: \"Vindemiatrix\", label: \"Vindemiatrix · gentle\" },\n { id: \"Sadachbia\", label: \"Sadachbia · lively\" },\n { id: \"Sadaltager\", label: \"Sadaltager · knowledgeable\" },\n { id: \"Sulafat\", label: \"Sulafat · warm\" },\n];\n\nexport const GEMINI_TTS_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash-preview-tts\", label: \"Flash TTS (fast, cheap)\" },\n { id: \"gemini-2.5-pro-preview-tts\", label: \"Pro TTS (higher quality)\" },\n];\n\nexport const GEMINI_STT_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash\", label: \"Flash (fast, multilingual)\" },\n { id: \"gemini-2.5-pro\", label: \"Pro (slower, more accurate)\" },\n];\n","// Gemini voice helpers — TTS via the *-preview-tts models and STT by\n// feeding inline audio bytes to a multimodal Gemini model. Both call the\n// native REST API (the OpenAI-compat proxy doesn't expose AUDIO modality\n// or inline_data parts). API key is resolved from the \"google\" integration,\n// same source as lib/tools/generate_image.ts.\n\nimport { getConfig } from \"@/lib/env/config\";\nimport {\n resolveGoogleApiKey as resolveGoogleApiKeyShared,\n timeoutSignal,\n} from \"@/lib/utils/google-api\";\n\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\nexport function resolveGoogleApiKey(): string | null {\n return resolveGoogleApiKeyShared();\n}\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\n/**\n * Synthesize speech with Gemini TTS. Gemini returns PCM L16 (raw 16-bit\n * little-endian, 24 kHz mono); we wrap it with a WAV header so any\n * <audio> element can play it.\n *\n * Style/tone is steered by prepending a natural-language instruction to\n * the spoken text (Gemini's recommended pattern), e.g. style=\"Say warmly\n * and slowly\" produces \"Say warmly and slowly: <text>\". For multi-speaker\n * scenes, pass `speakers` with up to 2 entries and write the text as\n * `Name: line ...` per turn — Gemini will switch voices accordingly.\n */\nexport async function geminiTts(opts: {\n apiKey: string;\n model: string;\n voiceName: string;\n text: string;\n style?: string;\n speakers?: Array<{ name: string; voiceName: string }>;\n}): Promise<{ wav: Buffer; mime: \"audio/wav\" }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const style = opts.style?.trim();\n const spoken = style ? `${style.replace(/:\\s*$/, \"\")}: ${opts.text}` : opts.text;\n const speakers = (opts.speakers ?? []).filter((s) => s.name && s.voiceName).slice(0, 2);\n const speechConfig: Record<string, unknown> =\n speakers.length >= 2\n ? {\n multiSpeakerVoiceConfig: {\n speakerVoiceConfigs: speakers.map((s) => ({\n speaker: s.name,\n voiceConfig: { prebuiltVoiceConfig: { voiceName: s.voiceName } },\n })),\n },\n }\n : {\n voiceConfig: {\n prebuiltVoiceConfig: { voiceName: opts.voiceName },\n },\n };\n const body = {\n contents: [{ role: \"user\", parts: [{ text: spoken }] }],\n generationConfig: {\n responseModalities: [\"AUDIO\"],\n speechConfig,\n },\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini TTS ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"\";\n if (data) {\n const pcm = Buffer.from(data, \"base64\");\n const rate = parseSampleRate(mime) ?? 24000;\n return { wav: pcmToWav(pcm, rate, 1, 16), mime: \"audio/wav\" };\n }\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini TTS returned no audio: ${text}` : \"Gemini TTS returned no audio\");\n}\n\n/**\n * Transcribe audio via a Gemini multimodal model. Returns the verbatim\n * transcript, preserving the speaker's original language (including code-\n * switched English/Chinese).\n */\nexport async function geminiStt(opts: {\n apiKey: string;\n model: string;\n audio: Buffer;\n mimeType: string;\n}): Promise<{ text: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const body = {\n contents: [{\n role: \"user\",\n parts: [\n {\n text:\n \"Transcribe the following audio verbatim. Preserve the speaker's \" +\n \"original language, including mixed English and Chinese. Output ONLY \" +\n \"the transcript text — no quotes, no commentary, no language tags.\",\n },\n { inline_data: { mime_type: opts.mimeType, data: opts.audio.toString(\"base64\") } },\n ],\n }],\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini STT ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n const text = parts.map((p) => p.text).filter(Boolean).join(\"\").trim();\n if (!text) throw new Error(\"Gemini STT returned no transcript\");\n return { text };\n}\n\n// `audio/L16;codec=pcm;rate=24000` → 24000\nfunction parseSampleRate(mime: string): number | null {\n const m = /rate=(\\d+)/i.exec(mime);\n if (!m) return null;\n const n = parseInt(m[1], 10);\n return Number.isFinite(n) && n > 0 ? n : null;\n}\n\n// Build a RIFF/WAVE header for raw PCM. Standard 16-bit, mono unless told\n// otherwise. No fancy chunks — just enough to satisfy browser audio.\nfunction pcmToWav(pcm: Buffer, sampleRate: number, channels: number, bitsPerSample: number): Buffer {\n const byteRate = (sampleRate * channels * bitsPerSample) / 8;\n const blockAlign = (channels * bitsPerSample) / 8;\n const dataSize = pcm.length;\n const header = Buffer.alloc(44);\n header.write(\"RIFF\", 0);\n header.writeUInt32LE(36 + dataSize, 4);\n header.write(\"WAVE\", 8);\n header.write(\"fmt \", 12);\n header.writeUInt32LE(16, 16); // fmt chunk size\n header.writeUInt16LE(1, 20); // PCM\n header.writeUInt16LE(channels, 22);\n header.writeUInt32LE(sampleRate, 24);\n header.writeUInt32LE(byteRate, 28);\n header.writeUInt16LE(blockAlign, 32);\n header.writeUInt16LE(bitsPerSample, 34);\n header.write(\"data\", 36);\n header.writeUInt32LE(dataSize, 40);\n return Buffer.concat([header, pcm]);\n}\n\n// Re-export the client-safe constants for callers that already import from\n// this module on the server side.\nexport { GEMINI_VOICES, GEMINI_TTS_MODELS, GEMINI_STT_MODELS } from \"./constants\";\n","// Semantic search over document_chunks (ADR-0024). Cosine over embedded\n// chunks; substring fallback for chunks without embeddings (covers the\n// \"no embedding provider configured\" case and the brief window before\n// async embed completes after indexing).\n\nimport { getDb } from \"@/lib/db\";\nimport { embedOne, cosine } from \"@/lib/embeddings\";\n\nexport interface DocumentHit {\n document_id: string;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n chunk_index: number;\n text: string;\n score: number;\n match: \"semantic\" | \"substring\";\n}\n\ninterface Row {\n chunk_id: string;\n document_id: string;\n chunk_index: number;\n text: string;\n embedding: string | null;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n}\n\nexport async function searchDocuments(\n query: string,\n opts?: { limit?: number; sourceId?: string },\n): Promise<DocumentHit[]> {\n const limit = Math.min(Math.max(opts?.limit ?? 8, 1), 25);\n const db = getDb();\n const trimmed = query.trim();\n if (trimmed.length === 0) return [];\n\n // Hard cap on rows scanned per query — at thousands of chunks the JS\n // cosine pass is still milliseconds, but we still want a ceiling.\n const limitRows = 20_000;\n const rows = (\n opts?.sourceId\n ? db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE d.source_id = ? AND ds.enabled = 1\n LIMIT ?`,\n ).all(opts.sourceId, limitRows)\n : db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE ds.enabled = 1\n LIMIT ?`,\n ).all(limitRows)\n ) as unknown as Row[];\n\n if (rows.length === 0) return [];\n\n const qVec = await embedOne(trimmed);\n const scored: DocumentHit[] = [];\n const lowered = trimmed.toLowerCase();\n\n for (const r of rows) {\n let score = 0;\n let match: \"semantic\" | \"substring\" = \"semantic\";\n if (qVec && r.embedding) {\n let vec: number[] | null = null;\n try { vec = JSON.parse(r.embedding) as number[]; } catch { vec = null; }\n if (vec) score = cosine(qVec, vec);\n else { score = substringScore(r.text, lowered); match = \"substring\"; }\n } else {\n score = substringScore(r.text, lowered);\n match = \"substring\";\n }\n if (score <= 0) continue;\n scored.push({\n document_id: r.document_id,\n source_id: r.source_id,\n source_label: r.source_label,\n rel_path: r.rel_path,\n abs_path: r.abs_path,\n chunk_index: r.chunk_index,\n text: r.text,\n score,\n match,\n });\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n}\n\nfunction substringScore(haystack: string, needleLower: string): number {\n const hay = haystack.toLowerCase();\n if (!hay.includes(needleLower)) {\n // Try token-level OR match — at least one query token has to appear.\n const tokens = needleLower.split(/\\s+/).filter((t) => t.length > 2);\n let hits = 0;\n for (const t of tokens) if (hay.includes(t)) hits++;\n if (hits === 0) return 0;\n return Math.min(0.4, hits / Math.max(tokens.length, 1) * 0.4);\n }\n // Phrase match — high but below typical semantic top scores.\n return 0.6;\n}\n","// Scheduler loop. Owns the timer + the \"is a tick in flight?\" guard. The\n// actual firing logic lives in lib/triggers — this file only schedules\n// runTriggerTick() and exports a \"Run now\" helper that the existing\n// scheduled-tasks HTTP route uses.\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { indexAllSources } from \"@/lib/documents/indexer\";\nimport { runTriggerTick, runScheduledTaskFiringNow } from \"@/lib/triggers\";\nimport type { ScheduledTaskRow } from \"@/lib/stores/scheduled-tasks\";\n\n// Env-tunable so e2e tests can ride a tighter loop without waiting 30 s\n// per fs-watch firing. Production / dev use the 30 s default; tests\n// should set JARELA_SCHEDULER_TICK_MS=200 (or similar).\nconst POLL_INTERVAL_MS = (() => {\n const raw = process.env.JARELA_SCHEDULER_TICK_MS;\n if (!raw) return 30_000;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 50 ? n : 30_000;\n})();\n// Sweep document sources every Nth tick. 20 ticks × 30s = 10 min, which\n// matches typical \"I edited a file, ask Jarela about it\" patience. PR-D\n// upgrades this to event-driven fs watching.\nconst DOC_SWEEP_EVERY_TICKS = 20;\n\ninterface SchedulerState {\n started: boolean;\n timer: NodeJS.Timeout | null;\n running: boolean;\n tickCount: number;\n}\nconst state = getOrCreateGlobal<SchedulerState>(\"__jarela_scheduler\", () => ({\n started: false,\n timer: null,\n running: false,\n tickCount: 0,\n}));\n\n// Idempotent — call repeatedly; only the first call starts the loop.\nexport function startScheduler(): void {\n if (state.started) return;\n state.started = true;\n setImmediate(() => { void tick(); });\n state.timer = setInterval(() => { void tick(); }, POLL_INTERVAL_MS);\n if (typeof state.timer.unref === \"function\") state.timer.unref();\n}\n\nexport function stopScheduler(): void {\n if (state.timer) {\n clearInterval(state.timer);\n state.timer = null;\n }\n state.started = false;\n}\n\nasync function tick(): Promise<void> {\n if (state.running) return;\n state.running = true;\n try {\n await runTriggerTick();\n\n // Document-RAG reindex sweep (ADR-0024). Polled here until PR-D wires\n // an fs watcher. Failures are logged but never block the tick.\n state.tickCount = (state.tickCount + 1) % DOC_SWEEP_EVERY_TICKS;\n if (state.tickCount === 0) {\n try {\n await indexAllSources();\n } catch (err) {\n console.error(\n \"[scheduler] document index sweep failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n } finally {\n state.running = false;\n }\n}\n\n/**\n * Public wrapper retained for the \"Run now\" UI button + HTTP route.\n * Internally delegates to the trigger runner so the manual path and the\n * tick path share the exact same code.\n */\nexport async function runScheduledTaskNow(task: ScheduledTaskRow): Promise<void> {\n await runScheduledTaskFiringNow(task.id);\n}\n","import type { ContentPart } from \"@/lib/tools/types\";\nimport type { ModelProvider, ProviderMessage, ProviderParams } from \"@/lib/providers/types\";\n\nexport function transcriptText(raw: string): string {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return raw;\n return (parsed as ContentPart[])\n .map((p) => {\n if (p.type === \"text\") return p.text;\n if (p.type === \"image\") return `[image attachment: ${p.media_type}]`;\n if (p.type === \"file\") return `[file attachment: ${p.name} (${p.media_type})]`;\n return \"\";\n })\n .filter(Boolean)\n .join(\" \")\n .trim();\n } catch {\n return raw;\n }\n}\n\nfunction summaryMessages(transcript: string): ProviderMessage[] {\n return [\n {\n role: \"system\",\n content:\n \"You are a concise summarizer. Summarize the conversation below in 3-7 bullet points, capturing key facts, decisions, and context that would be useful to remember later.\",\n },\n {\n role: \"user\",\n content: `Conversation to summarize:\\n\\n${transcript}`,\n },\n ];\n}\n\nexport async function summarizeTranscript(\n provider: Pick<ModelProvider, \"chat\">,\n modelId: string,\n providerParams: ProviderParams,\n transcript: string,\n): Promise<string> {\n const trimmed = transcript.trim();\n if (!trimmed) return \"\";\n\n const { stream } = await provider.chat(modelId, summaryMessages(trimmed), providerParams);\n let summary = \"\";\n for await (const chunk of stream) summary += chunk;\n return summary.trim();\n}","import { join } from \"node:path\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { tool } from \"@langchain/core/tools\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { getToolSecret, type ToolSecretSlot } from \"@/lib/stores/tool-secrets\";\nimport type { ToolCategory } from \"./registry\";\n\n/**\n * Absolute path to the external tools directory. Resolved lazily from\n * `getConfig().toolsDir` so JARELA_TOOLS_DIR (and JARELA_DB_DIR fallback)\n * are honoured.\n */\nexport function getToolsDir(): string {\n return getConfig().toolsDir;\n}\n\nexport interface ExternalToolDef {\n name: string;\n description: string;\n schema: object;\n category?: ToolCategory;\n // Optional per-tool secret slots. Surfaced in the Extensions panel as\n // editable form fields; persisted (encrypted at rest) in the\n // `tool-secrets` memory namespace. Read at run time via `ctx.getSecret`.\n // See ADR-0023.\n secrets?: ToolSecretSlot[];\n run: (\n args: Record<string, unknown>,\n ctx: {\n thread_id?: string;\n // Returns the persisted secret for this tool's slot, or `null` if\n // it has not been configured. Always scoped to the current tool —\n // a tool cannot read another tool's secrets via this helper.\n getSecret: (key: string) => string | null;\n },\n ) => unknown | Promise<unknown>;\n}\n\nexport interface ExtensionLoadError {\n file: string;\n error: string;\n}\n\nexport interface ExternalToolsResult {\n tools: StructuredToolInterface[];\n categories: Map<string, ToolCategory>;\n files: Map<string, string>;\n // Declared secret slots per tool name (empty array if the tool did not\n // declare any). Used by the Extensions panel to render input fields.\n secrets: Map<string, ToolSecretSlot[]>;\n errors: ExtensionLoadError[];\n}\n\nfunction isValidSlot(v: unknown): v is ToolSecretSlot {\n if (!v || typeof v !== \"object\") return false;\n const o = v as Record<string, unknown>;\n if (typeof o.key !== \"string\" || !/^[a-z0-9_-]+$/i.test(o.key)) return false;\n if (o.label !== undefined && typeof o.label !== \"string\") return false;\n if (o.required !== undefined && typeof o.required !== \"boolean\") return false;\n if (o.description !== undefined && typeof o.description !== \"string\") return false;\n return true;\n}\n\nfunction isValid(p: unknown): p is ExternalToolDef {\n if (!p || typeof p !== \"object\") return false;\n const o = p as Record<string, unknown>;\n if (\n typeof o.name !== \"string\" ||\n o.name.trim() === \"\" ||\n typeof o.description !== \"string\" ||\n typeof o.schema !== \"object\" ||\n o.schema === null ||\n typeof o.run !== \"function\"\n ) return false;\n if (o.secrets !== undefined) {\n if (!Array.isArray(o.secrets)) return false;\n if (!o.secrets.every(isValidSlot)) return false;\n }\n return true;\n}\n\nexport function loadExternalTools(\n builtinNames: ReadonlySet<string>,\n): ExternalToolsResult {\n const tools: StructuredToolInterface[] = [];\n const categories = new Map<string, ToolCategory>();\n const files = new Map<string, string>();\n const secrets = new Map<string, ToolSecretSlot[]>();\n const errors: ExtensionLoadError[] = [];\n\n const toolsDir = getToolsDir();\n if (!existsSync(toolsDir)) {\n return { tools, categories, files, secrets, errors };\n }\n\n // Same trick as lib/providers/external.ts: bypass webpack's static analysis\n // so the dynamic require survives the Next build.\n const { createRequire } = (\n process as unknown as { getBuiltinModule: (id: string) => typeof import(\"node:module\") }\n ).getBuiltinModule(\"node:module\");\n const req = createRequire(join(toolsDir, \"_anchor\"));\n\n let entries: string[];\n try {\n entries = readdirSync(toolsDir);\n } catch {\n return { tools, categories, files, secrets, errors };\n }\n\n const seen = new Set<string>();\n\n for (const entry of entries) {\n if (!/\\.(c?js|ts)$/i.test(entry)) continue;\n const path = join(toolsDir, entry);\n try {\n if (!statSync(path).isFile()) continue;\n } catch {\n continue;\n }\n\n let mod: unknown;\n try {\n delete req.cache[req.resolve(path)];\n mod = req(path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ file: entry, error: message });\n console.error(`[tools] failed to load ${entry}:`, err);\n continue;\n }\n\n const candidate =\n (mod as { default?: unknown })?.default ?? (mod as unknown);\n if (!isValid(candidate)) {\n const msg =\n \"does not export a valid ExternalToolDef (need { name, description, schema, run })\";\n errors.push({ file: entry, error: msg });\n console.error(`[tools] ${entry} ${msg}`);\n continue;\n }\n\n const def = candidate;\n if (builtinNames.has(def.name)) {\n const msg = `name \"${def.name}\" collides with a built-in tool — built-in takes precedence`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] external ${entry}: ${msg}`);\n continue;\n }\n if (seen.has(def.name)) {\n const msg = `duplicate external tool \"${def.name}\"`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] ${entry}: ${msg}`);\n continue;\n }\n seen.add(def.name);\n\n const wrapped = tool(\n async (args: unknown, _runManager?: unknown, config?: RunnableConfig) => {\n const ctx = {\n thread_id: config?.configurable?.thread_id as string | undefined,\n getSecret: (key: string) => getToolSecret(def.name, key),\n };\n const result = await def.run(args as Record<string, unknown>, ctx);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n },\n {\n name: def.name,\n description: def.description,\n schema: def.schema as never,\n },\n ) as unknown as StructuredToolInterface;\n\n tools.push(wrapped);\n files.set(def.name, entry);\n if (def.category) categories.set(def.name, def.category);\n secrets.set(def.name, def.secrets ?? []);\n }\n\n return { tools, categories, files, secrets, errors };\n}\n","// Shared collector for agent stream consumers.\n//\n// Previously three near-identical drain loops lived in:\n// - app/api/v1/threads/[thread_id]/run/route.ts (HTTP run)\n// - lib/scheduler/index.ts (cron tasks)\n// - lib/bridges/dispatcher.ts (WhatsApp / bridges)\n//\n// They all read `prepared.stream`, accumulate `text_delta` into a single\n// assistant string, record `tool_call`/`tool_result` events, stop on\n// `done`/`error`, and surface the terminal state. This helper unifies that.\n\nimport type { StreamChunk } from \"@/lib/agents/base\";\nimport type { PersistedToolEvent } from \"@/lib/stores/threads\";\n\nexport interface CollectedRun {\n assistantContent: string;\n usedTools: string[];\n toolEvents: PersistedToolEvent[];\n terminal: \"done\" | \"error\";\n errorMessage?: string;\n}\n\nexport interface CollectStreamOptions {\n // Called for every chunk before it is interpreted. Use for live broadcast\n // (HTTP SSE, websocket, etc.). Throwing here aborts the run with terminal\n // = \"error\".\n onChunk?: (chunk: StreamChunk) => void;\n}\n\n/** Drain an async stream of `StreamChunk` into a single `CollectedRun`. */\nexport async function collectStream(\n stream: AsyncIterable<StreamChunk>,\n opts: CollectStreamOptions = {},\n): Promise<CollectedRun> {\n const result: CollectedRun = {\n assistantContent: \"\",\n usedTools: [],\n toolEvents: [],\n terminal: \"done\",\n };\n\n try {\n for await (const chunk of stream) {\n opts.onChunk?.(chunk);\n switch (chunk.type) {\n case \"text_delta\": {\n result.assistantContent += (chunk.data.delta as string) ?? \"\";\n break;\n }\n case \"tool_call\": {\n const d = chunk.data as { id?: string; name?: string; arguments?: unknown };\n if (d.name) result.usedTools.push(d.name);\n result.toolEvents.push({\n id: d.id ?? `call-${result.toolEvents.length}`,\n phase: \"call\",\n name: d.name ?? \"\",\n payload: d.arguments,\n });\n break;\n }\n case \"tool_result\": {\n const d = chunk.data as { id?: string; name?: string; result?: unknown };\n result.toolEvents.push({\n id: d.id ?? `result-${result.toolEvents.length}`,\n phase: \"result\",\n name: d.name ?? \"\",\n payload: d.result,\n });\n break;\n }\n case \"error\": {\n result.terminal = \"error\";\n const msg = (chunk.data as { message?: unknown })?.message;\n if (typeof msg === \"string\") result.errorMessage = msg;\n return result;\n }\n case \"done\": {\n return result;\n }\n // thinking_delta and unknown types are pass-through (already\n // forwarded to onChunk above).\n }\n }\n } catch (err) {\n result.terminal = \"error\";\n result.errorMessage = err instanceof Error ? err.message : String(err);\n }\n\n return result;\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getMemory, putMemory, listMemory } from \"@/lib/stores/memory\";\nimport { registerTools } from \"./registry\";\n\nexport const memoryReadTool = tool(\n async ({ namespace, key }) => {\n const row = getMemory(namespace, key);\n if (!row) return JSON.stringify(null);\n return row.value; // already stored as a JSON string\n },\n {\n name: \"memory_read\",\n description: \"Read a value from long-term memory by namespace and key. Returns null if not found.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n }),\n },\n);\n\nexport const memoryWriteTool = tool(\n async ({ namespace, key, value }) => {\n putMemory(namespace, key, value);\n return JSON.stringify({ ok: true, namespace, key });\n },\n {\n name: \"memory_write\",\n description:\n \"Write or update a value in long-term memory. Use this to remember facts, user preferences, or any information that should persist across conversations.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n value: z.string().describe(\"Value to store (serialize objects to JSON before passing)\"),\n }),\n },\n);\n\nexport const memoryListTool = tool(\n async ({ namespace, search, limit }) => {\n const rows = listMemory(namespace, search, limit ?? 20);\n const result = rows.map((r) => ({\n namespace: r.namespace,\n key: r.key,\n value: (() => {\n try {\n return JSON.parse(r.value);\n } catch {\n return r.value;\n }\n })(),\n updated_at: r.updated_at,\n }));\n return JSON.stringify(result);\n },\n {\n name: \"memory_list\",\n description: \"List memory entries, optionally filtered by namespace or search term.\",\n schema: z.object({\n namespace: z.string().optional().describe(\"Filter by namespace (optional)\"),\n search: z.string().optional().describe(\"Search term to filter keys/values (optional)\"),\n limit: z.number().optional().describe(\"Max results (default 20)\"),\n }),\n },\n);\n\nregisterTools(\"Memory\", [memoryReadTool, memoryWriteTool, memoryListTool]);\n","// documents_search — semantic recall over folders the user indexed under\n// Documents (ADR-0024). Cosine over embedded chunks; substring fallback\n// when no embedding provider is configured or chunks haven't been\n// embedded yet.\n\nimport { tool } from \"@langchain/core/tools\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { searchDocuments } from \"@/lib/documents/search\";\nimport {\n createDocumentSource,\n deleteDocumentSource,\n getDocumentSource,\n getDocumentSourceByPath,\n listDocumentSources,\n type DocumentSourceKind,\n} from \"@/lib/stores/document-sources\";\nimport { indexOnDemand, runRemoteSource } from \"@/lib/documents/remote\";\nimport { notifyTriggerHandlers } from \"@/lib/triggers\";\n\nexport const documentsSearch = tool(\n async ({ query, limit, source_id }) => {\n const hits = await searchDocuments(query, { limit, sourceId: source_id });\n return JSON.stringify({\n query,\n hits: hits.map((h) => ({\n source: h.source_label ?? h.source_id,\n path: h.rel_path,\n chunk_index: h.chunk_index,\n score: Number(h.score.toFixed(4)),\n match: h.match,\n text: h.text,\n })),\n });\n },\n {\n name: \"documents_search\",\n description:\n \"Search indexed local documents (notes, READMEs, code, configs) by semantic similarity. \" +\n \"Use when the user references files in folders they've added under Documents, or when \" +\n \"you need facts from project-specific text the model wouldn't otherwise know. Returns \" +\n \"the top matching text chunks with their source path.\",\n schema: z.object({\n query: z.string().describe(\"Natural-language question or keywords to look up.\"),\n limit: z.number().int().min(1).max(25).optional()\n .describe(\"Max results to return (default 8).\"),\n source_id: z.string().optional()\n .describe(\"Restrict the search to a single document_source id. Omit to search all.\"),\n }),\n },\n);\n\nexport const documentsListSources = tool(\n async () => {\n const rows = listDocumentSources();\n return JSON.stringify({\n sources: rows.map((r) => ({\n id: r.id,\n path: r.path,\n label: r.label,\n enabled: r.enabled === 1,\n last_scan_at: r.last_scan_at,\n })),\n });\n },\n {\n name: \"documents_list_sources\",\n description:\n \"List the folders Jarela is indexing for document search. Useful before calling \" +\n \"documents_search with a source_id filter.\",\n schema: z.object({}),\n },\n);\n\nexport const documentsAddLocalSource = tool(\n async ({ path: inputPath, label }) => {\n const abs = path.resolve(inputPath);\n try {\n const st = await fs.stat(abs);\n if (!st.isDirectory()) {\n return JSON.stringify({ error: \"path is not a directory\" });\n }\n } catch {\n return JSON.stringify({ error: \"path does not exist or is unreadable\" });\n }\n if (getDocumentSourceByPath(abs)) {\n return JSON.stringify({ error: \"source already exists for this path\" });\n }\n try {\n const row = createDocumentSource({ path: abs, label: label ?? null, kind: \"local_folder\" });\n await notifyTriggerHandlers(\"source_changed\");\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n path: row.path,\n label: row.label,\n note: \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_local_source\",\n description:\n \"Add a local folder as a Documents source so its files become searchable via documents_search. \" +\n \"Pass any relative or absolute path; the tool resolves it to an absolute directory and validates it.\",\n schema: z.object({\n path: z.string().min(1).describe(\"Local folder path to index (relative or absolute).\"),\n label: z.string().optional().describe(\"Optional source label shown in the Documents panel.\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [documentsSearch, documentsListSources, documentsAddLocalSource]);\n\n// ── Remote document sources (ADR-0026) ──────────────────────────────────────\n//\n// These tools let agents add Jira projects, JQL queries, Confluence spaces,\n// and CQL queries as document sources, so a single retrieval surface\n// (`documents_search`) covers both local files and Atlassian content.\n\nconst REMOTE_KINDS = [\n \"confluence_space\",\n \"confluence_cql\",\n \"jira_project\",\n \"jira_jql\",\n \"github_pulls\",\n \"github_repo\",\n] as const;\n\nfunction syntheticPath(kind: DocumentSourceKind, config: Record<string, unknown>): string {\n switch (kind) {\n case \"confluence_space\": return `confluence-space://${String(config.space_key ?? \"\").trim()}`;\n case \"confluence_cql\": return `confluence-cql://${Buffer.from(String(config.cql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"jira_project\": return `jira-project://${String(config.project_key ?? \"\").trim()}`;\n case \"jira_jql\": return `jira-jql://${Buffer.from(String(config.jql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"github_pulls\": return `github-pulls://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n case \"github_repo\": return `github-repo://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n default: return `remote://${kind}/${Date.now()}`;\n }\n}\n\nfunction validateRemoteConfig(kind: typeof REMOTE_KINDS[number], cfg: Record<string, unknown>): string | null {\n if (kind === \"confluence_space\" && !cfg.space_key) return \"config.space_key is required for confluence_space\";\n if (kind === \"confluence_cql\" && !cfg.cql) return \"config.cql is required for confluence_cql\";\n if (kind === \"jira_project\" && !cfg.project_key) return \"config.project_key is required for jira_project\";\n if (kind === \"jira_jql\" && !cfg.jql) return \"config.jql is required for jira_jql\";\n if (kind === \"github_pulls\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_pulls\";\n if (kind === \"github_repo\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_repo\";\n return null;\n}\n\nexport const documentsAddRemoteSource = tool(\n async ({ kind, label, config }) => {\n const err = validateRemoteConfig(kind, config);\n if (err) return JSON.stringify({ error: err });\n const path = syntheticPath(kind, config);\n try {\n const row = createDocumentSource({ path, label, kind, config });\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n label: row.label,\n note: \"Remote sources index on the scheduler sweep (~10 min). Call documents_reindex_source with this id to force an immediate sync. Local folders auto-reindex on file changes.\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_remote_source\",\n description:\n \"Add a Jira project / JQL query / Confluence space / CQL query / GitHub repo as a document source. \" +\n \"Indexed content becomes searchable via documents_search alongside local folders. \" +\n \"Examples: kind='confluence_space' config={space_key:'ENG'}; kind='jira_project' \" +\n \"config={project_key:'ABC', recency_days:90}; kind='jira_jql' config={jql:'project = ABC AND status != Done'}; \" +\n \"kind='github_pulls' config={owner:'octocat', repo:'hello-world', state:'all', recency_days:60}; \" +\n \"kind='github_repo' config={owner:'octocat', repo:'hello-world', ref:'main', path_prefix:'docs'}.\",\n schema: z.object({\n kind: z.enum(REMOTE_KINDS),\n label: z.string().describe(\"Human-readable label shown in the Documents panel.\"),\n config: z.record(z.string(), z.unknown())\n .describe(\"Per-kind config. confluence_space: {space_key}. confluence_cql: {cql}. \" +\n \"jira_project: {project_key}. jira_jql: {jql}. \" +\n \"github_pulls: {owner, repo, state?, recency_days?}. \" +\n \"github_repo: {owner, repo, ref?, path_prefix?}. Optional everywhere: recency_days (int).\"),\n }),\n },\n);\n\nexport const documentsRemoveSource = tool(\n async ({ source_id, confirm }) => {\n if (confirm !== source_id) {\n return JSON.stringify({ error: \"pass confirm equal to source_id to actually delete\" });\n }\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n const ok = deleteDocumentSource(source_id);\n return JSON.stringify({ ok, id: source_id, label: row.label });\n },\n {\n name: \"documents_remove_source\",\n description:\n \"Delete a document source and all its indexed chunks. Destructive — requires `confirm` to equal `source_id`.\",\n schema: z.object({\n source_id: z.string(),\n confirm: z.string().describe(\"Must equal source_id to proceed.\"),\n }),\n },\n);\n\nexport const documentsReindexSource = tool(\n async ({ source_id }) => {\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n if (row.kind === \"local_folder\") {\n return JSON.stringify({\n error: \"documents_reindex_source is only for remote sources (Jira/Confluence). \" +\n \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n }\n try {\n const stats = await runRemoteSource(row);\n return JSON.stringify({ ok: true, id: source_id, stats });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_reindex_source\",\n description:\n \"Force an immediate incremental sync of a remote document source. Returns counts of added / updated / unchanged docs.\",\n schema: z.object({ source_id: z.string() }),\n },\n);\n\nexport const documentsIndexUrl = tool(\n async ({ input }) => {\n try {\n const res = await indexOnDemand(input);\n return JSON.stringify({ ok: true, ...res });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_index_url\",\n description:\n \"Fetch and index a single Jira issue, Confluence page, or GitHub PR/issue/file on demand, \" +\n \"stored under a shared 'On-demand URLs' source. Accepts a bare Jira key (ABC-123), a \" +\n \"/browse/<KEY> URL, a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, \" +\n \"/issues/<n>, or /blob/<ref>/<path> URL.\",\n schema: z.object({\n input: z.string().describe(\"Jira key, Jira URL, Confluence page URL, or GitHub PR/issue/blob URL\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [\n documentsAddRemoteSource,\n documentsRemoveSource,\n documentsReindexSource,\n documentsIndexUrl,\n]);\n","import { execSync } from \"node:child_process\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { getInjectedSubprocessEnv } from \"@/lib/env/allowlist\";\n\nconst MAX_OUTPUT_BYTES = 8_000;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_TIMEOUT_MS = 60_000;\n\nconst BLOCKED_PATTERNS = [\n /\\brm\\s+-rf\\s+\\/\\b/i,\n /\\bshutdown\\b/i,\n /\\breboot\\b/i,\n /\\bmkfs\\b/i,\n /:\\s*\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:\\s*&\\s*\\}\\s*;/,\n];\n\nfunction isBlockedCommand(command: string): boolean {\n return BLOCKED_PATTERNS.some((pattern) => pattern.test(command));\n}\n\nfunction clipOutput(text: string, max = MAX_OUTPUT_BYTES): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: `${text.slice(0, max)}\\n[output truncated]`, truncated: true };\n}\n\nfunction runLocalCommand(\n command: string,\n options: {\n cwd?: string;\n env?: Record<string, string>;\n timeout_ms?: number;\n allow_unsafe?: boolean;\n },\n): string {\n if (!command.trim()) {\n return JSON.stringify({ exit_code: 1, stderr: \"command is required\" });\n }\n\n const timeout = Math.min(options.timeout_ms ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n if (!options.allow_unsafe && isBlockedCommand(command)) {\n return JSON.stringify({\n exit_code: 126,\n stderr: \"Command blocked by safety policy. Pass allow_unsafe=true only when you fully trust the command.\",\n });\n }\n\n const cwd = options.cwd?.trim() ? options.cwd : process.cwd();\n // Layered env. Later spreads win:\n // 1. process.env — PATH, HOME, locale, the shell's exports\n // 2. integration-store credentials — so a service install (launchd,\n // systemd) where ANTHROPIC_API_KEY etc. were never exported in the\n // service's environment still hands those values to subprocesses.\n // The encrypted store, populated by env-sync from the user's rc\n // or via the Integrations panel, is the canonical source.\n // 3. options.env — explicit per-call override always wins.\n const env = { ...process.env, ...getInjectedSubprocessEnv(), ...options.env };\n\n try {\n const output = execSync(command, {\n cwd,\n env,\n timeout,\n encoding: \"utf8\",\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const clipped = clipOutput(output);\n return JSON.stringify({ exit_code: 0, stdout: clipped.value, truncated: clipped.truncated, cwd });\n } catch (err: unknown) {\n const e = err as { stdout?: string; stderr?: string; status?: number; message?: string };\n const out = clipOutput(String(e.stdout ?? \"\"));\n const errText = clipOutput(String(e.stderr ?? e.message ?? \"\"), 2_000);\n return JSON.stringify({\n exit_code: e.status ?? 1,\n stdout: out.value,\n stderr: errText.value,\n truncated: out.truncated || errText.truncated,\n cwd,\n });\n }\n}\n\nconst execSchema = z.object({\n command: z.string().describe(\"Shell command to execute\"),\n cwd: z.string().optional().describe(\"Working directory for command execution (defaults to process cwd)\"),\n env: z.record(z.string(), z.string()).optional().describe(\"Environment variables to inject for this command\"),\n timeout_ms: z.number().optional().describe(\"Timeout in milliseconds (default 10000, max 60000)\"),\n allow_unsafe: z.boolean().optional().describe(\"Set true to bypass safety blocking for risky commands\"),\n});\n\nexport const localExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"local_exec\",\n description: \"Run local shell commands with optional cwd/env overrides. Output is truncated to 8 KB.\",\n schema: execSchema,\n },\n);\n\nexport const shellExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"shell_exec\",\n description: \"Backward-compatible alias for local_exec.\",\n schema: execSchema,\n },\n);\n\nregisterTools(\"Shell\", [localExecTool, shellExecTool]);\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\n// Dedicated file tools. Agents previously had to drive every edit through\n// `local_exec` / `shell_exec`, which works for \"create a new file with this\n// content\" (echo / Set-Content) but is hostile to in-place edits: quoting\n// rules differ per shell, multi-line strings break under cmd.exe, and a\n// read-modify-write cycle needs two shell calls plus careful diff-by-hand.\n// These tools give agents a first-class file write + targeted edit surface.\n\nconst MAX_READ_BYTES = 64_000;\nconst MAX_WRITE_BYTES = 2_000_000;\n// Hard cap on the JSON payload returned by file_list. Stops a misconfigured\n// recursive listing of a giant tree from blowing the LLM's prompt budget\n// (one user hit 361K tokens / 64K limit from a single call).\nconst MAX_LIST_JSON_BYTES = 24_000;\n\nfunction clip(text: string, max: number): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: text.slice(0, max), truncated: true };\n}\n\n// Resolve agent-supplied paths against the USER'S HOME directory, not\n// process.cwd(). In production cwd is the Jarela install dir\n// (%LOCALAPPDATA%\\Programs\\Jarela) — if the agent writes \"notes.txt\"\n// expecting it to land somewhere visible, it lands buried in the install\n// tree and the user concludes the tool didn't run. Home is the natural\n// default for an \"assistant on my computer\". Absolute paths and ~/ paths\n// are honored verbatim.\nfunction resolvePath(p: string): string {\n if (!p.trim()) throw new Error(\"path is required\");\n let s = p.trim();\n if (s === \"~\") return os.homedir();\n if (s.startsWith(\"~/\") || s.startsWith(\"~\\\\\")) {\n s = path.join(os.homedir(), s.slice(2));\n return path.resolve(s);\n }\n if (path.isAbsolute(s)) return path.resolve(s);\n return path.resolve(os.homedir(), s);\n}\n\n// Filesystem denylist for agent-driven file tools. The LLM has free\n// rein over the user's HOME by design — but a handful of subtrees hold\n// credentials whose disclosure or mutation is far more dangerous than\n// any chat use case justifies: SSH private keys, GPG secret rings,\n// cached cloud-provider tokens, the gh CLI auth blob, kubeconfig, the\n// docker daemon config. We also forbid writes to ~/.jarela so a\n// prompt-injected page can't rewrite the app's own SQLite state.\n//\n// Operators with an explicit need (e.g. asking the agent to fix an\n// authorized_keys file) can opt back in with\n// JARELA_ALLOW_SENSITIVE_FILES=1.\nfunction isInside(abs: string, parent: string): boolean {\n const a = path.resolve(abs);\n const p = path.resolve(parent);\n if (a === p) return true;\n const rel = path.relative(p, a);\n return !!rel && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n}\n\nfunction sensitiveBase(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".ssh\"),\n path.join(home, \".gnupg\"),\n path.join(home, \".aws\"),\n path.join(home, \".config\", \"gh\"),\n path.join(home, \".kube\"),\n path.join(home, \".docker\"),\n ];\n}\n\nfunction sensitiveFiles(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".netrc\"),\n path.join(home, \"_netrc\"), // Windows convention\n path.join(home, \".pgpass\"),\n ];\n}\n\nfunction jarelaDataDir(): string {\n return process.env.JARELA_DB_DIR\n ? path.resolve(process.env.JARELA_DB_DIR)\n : path.join(os.homedir(), \".jarela\");\n}\n\nfunction assertSafePath(abs: string, op: \"read\" | \"write\"): void {\n if (process.env.JARELA_ALLOW_SENSITIVE_FILES === \"1\") return;\n for (const base of sensitiveBase()) {\n if (isInside(abs, base)) {\n throw new Error(\n `refused: '${abs}' is inside a credential directory (${path.basename(base)}). ` +\n `Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n for (const f of sensitiveFiles()) {\n if (path.resolve(abs) === path.resolve(f)) {\n throw new Error(\n `refused: '${abs}' is a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n // Filename-based defense: catch private-key files anywhere on disk.\n const base = path.basename(abs).toLowerCase();\n if (\n base === \"id_rsa\" ||\n base === \"id_ed25519\" ||\n base === \"id_ecdsa\" ||\n base === \"id_dsa\" ||\n base.endsWith(\".pem\") ||\n base.endsWith(\".key\") ||\n base === \"credentials\"\n ) {\n throw new Error(\n `refused: '${abs}' looks like a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n if (op === \"write\" && isInside(abs, jarelaDataDir())) {\n throw new Error(\n `refused: '${abs}' is inside Jarela's data dir; the agent must not mutate app state directly.`,\n );\n }\n}\n\n// --- read ---------------------------------------------------------------\n\nconst readSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n start_line: z.number().int().min(1).optional().describe(\"1-based first line to include\"),\n end_line: z.number().int().min(1).optional().describe(\"1-based last line to include (inclusive)\"),\n});\n\nexport const fileReadTool = tool(\n async ({ path: filePath, start_line, end_line }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"read\");\n const raw = await fs.readFile(abs, \"utf8\");\n let content = raw;\n let lineRange: { start: number; end: number } | null = null;\n if (start_line || end_line) {\n const lines = raw.split(/\\r?\\n/);\n const s = Math.max(1, start_line ?? 1);\n const e = Math.min(lines.length, end_line ?? lines.length);\n content = lines.slice(s - 1, e).join(\"\\n\");\n lineRange = { start: s, end: e };\n }\n const clipped = clip(content, MAX_READ_BYTES);\n return JSON.stringify({\n ok: true,\n path: abs,\n content: clipped.value,\n truncated: clipped.truncated,\n line_range: lineRange,\n total_lines: raw.split(/\\r?\\n/).length,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_read\",\n description:\n \"Read a UTF-8 text file. Optional 1-based start_line/end_line slice. Output clipped at 64 KB — for large files always pass a line range and walk in chunks.\",\n schema: readSchema,\n },\n);\n\n// --- write --------------------------------------------------------------\n\nconst writeSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n content: z.string().describe(\"Full file content. Overwrites the file if it exists.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories (default true)\"),\n});\n\nexport const fileWriteTool = tool(\n async ({ path: filePath, content, create_dirs }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n if (content.length > MAX_WRITE_BYTES) {\n return JSON.stringify({ ok: false, path: abs, error: `content exceeds ${MAX_WRITE_BYTES} bytes` });\n }\n assertSafePath(abs, \"write\");\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(abs), { recursive: true });\n }\n let existed = true;\n try {\n await fs.access(abs);\n } catch {\n existed = false;\n }\n await fs.writeFile(abs, content, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_written: Buffer.byteLength(content, \"utf8\"),\n created: !existed,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_write\",\n description:\n \"Create or fully overwrite a UTF-8 text file. Parent directories are created by default. Use file_edit for targeted in-place changes.\",\n schema: writeSchema,\n },\n);\n\n// --- edit ---------------------------------------------------------------\n\nconst editSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n old_string: z\n .string()\n .min(1)\n .describe(\n \"Exact literal substring to replace. Must appear EXACTLY ONCE in the file (include surrounding context to disambiguate).\",\n ),\n new_string: z.string().describe(\"Replacement text. May be empty to delete.\"),\n});\n\nexport const fileEditTool = tool(\n async ({ path: filePath, old_string, new_string }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"write\");\n const raw = await fs.readFile(abs, \"utf8\");\n const first = raw.indexOf(old_string);\n if (first === -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string not found. Re-read the file and try with the exact current content.\",\n });\n }\n const second = raw.indexOf(old_string, first + old_string.length);\n if (second !== -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string matches multiple times. Add surrounding context to make it unique.\",\n match_count: raw.split(old_string).length - 1,\n });\n }\n const next = raw.slice(0, first) + new_string + raw.slice(first + old_string.length);\n await fs.writeFile(abs, next, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_before: Buffer.byteLength(raw, \"utf8\"),\n bytes_after: Buffer.byteLength(next, \"utf8\"),\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_edit\",\n description:\n \"Replace a single exact-match substring inside a file. The old_string must appear exactly once — include enough surrounding context to disambiguate. Use this for in-place edits instead of shell heredocs.\",\n schema: editSchema,\n },\n);\n\n// --- move / rename ------------------------------------------------------\n\nconst moveSchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is moved into it preserving its basename.\"),\n overwrite: z\n .boolean()\n .optional()\n .describe(\"Allow replacing an existing destination file (default false). Existing directories are never overwritten.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories of the destination (default true).\"),\n});\n\nexport const fileMoveTool = tool(\n async ({ source, destination, overwrite, create_dirs }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"write\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n // If destination is an existing directory, move source INTO it\n // preserving its basename — matches `mv src dir/` semantics.\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // dst missing — fine\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat) {\n if (dstStat.isDirectory()) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination is an existing directory; refusing to overwrite\",\n });\n }\n if (!overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n }\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n }\n await fs.rename(srcAbs, dstAbs);\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n // Cross-device rename fails with EXDEV on Linux/macOS. Fall back to\n // copy+unlink so the agent doesn't need to know about device boundaries.\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"EXDEV\") {\n try {\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n await fs.rm(srcAbs, { recursive: true, force: true });\n return JSON.stringify({ ok: true, source: srcAbs, destination: dstAbs, cross_device: true });\n } catch (err2) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err2 as Error).message });\n }\n }\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_move\",\n description:\n \"Move or rename a file or directory. If destination is an existing directory, source is moved into it. Handles cross-device moves via copy+remove fallback.\",\n schema: moveSchema,\n },\n);\n\n// --- list ---------------------------------------------------------------\n\nconst listSchema = z.object({\n path: z.string().describe(\"Directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n max_entries: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .describe(\"Cap on returned entries (default 200, max 500). Listings are non-recursive — to explore subtrees, call file_list once per directory.\"),\n include_hidden: z\n .boolean()\n .optional()\n .describe(\"Include dot-prefixed entries (default false)\"),\n pattern: z\n .string()\n .optional()\n .describe(\"Optional case-insensitive substring filter applied to the basename\"),\n});\n\nexport const fileListTool = tool(\n async ({ path: dirPath, max_entries, include_hidden, pattern }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n const cap = max_entries ?? 200;\n const filter = pattern?.toLowerCase() ?? null;\n const entries: Array<{ path: string; kind: \"file\" | \"directory\" | \"other\"; size?: number }> = [];\n let truncated = false;\n try {\n let items: import(\"node:fs\").Dirent[];\n try {\n items = await fs.readdir(abs, { withFileTypes: true });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n items.sort((a, b) => a.name.localeCompare(b.name));\n for (const it of items) {\n if (entries.length >= cap) {\n truncated = true;\n break;\n }\n if (!include_hidden && it.name.startsWith(\".\")) continue;\n if (filter && !it.name.toLowerCase().includes(filter)) continue;\n const full = path.join(abs, it.name);\n const kind: \"file\" | \"directory\" | \"other\" = it.isDirectory()\n ? \"directory\"\n : it.isFile()\n ? \"file\"\n : \"other\";\n let size: number | undefined;\n if (kind === \"file\") {\n try {\n const st = await fs.stat(full);\n size = st.size;\n } catch {\n // ignore\n }\n }\n entries.push({ path: full, kind, size });\n }\n // Build the payload, then enforce a hard JSON byte cap. If the entry\n // list itself is too large (e.g. extremely long filenames), drop\n // entries from the tail until we fit so the LLM never gets a result\n // that blows past its prompt budget.\n const build = (es: typeof entries, droppedForSize: number) => JSON.stringify({\n ok: true,\n path: abs,\n entries: es,\n count: es.length,\n total_in_dir_after_filters: entries.length,\n truncated: truncated || droppedForSize > 0,\n truncated_hint: (truncated || droppedForSize > 0)\n ? \"Result truncated. Lower max_entries, add a `pattern` filter, or descend into a more specific subdirectory.\"\n : undefined,\n dropped_for_size: droppedForSize > 0 ? droppedForSize : undefined,\n filters: {\n include_hidden: !!include_hidden,\n pattern: pattern ?? null,\n max_entries: cap,\n },\n });\n let payload = build(entries, 0);\n if (payload.length > MAX_LIST_JSON_BYTES) {\n // Binary-trim entries from the tail until we fit.\n let lo = 0, hi = entries.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi + 1) / 2);\n if (build(entries.slice(0, mid), entries.length - mid).length <= MAX_LIST_JSON_BYTES) lo = mid;\n else hi = mid - 1;\n }\n payload = build(entries.slice(0, lo), entries.length - lo);\n }\n return payload;\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_list\",\n description:\n \"List one directory's entries (NON-RECURSIVE). To explore a subtree, call file_list once per directory and decide what to descend into based on the result — do NOT try to list everything at once. Hidden (dot) entries are skipped unless include_hidden=true. Optional `pattern` substring filter on basenames. Default cap 200 entries (max 500); the JSON result is hard-capped at ~24 KB and excess entries are dropped with a hint.\",\n schema: listSchema,\n },\n);\n\n// --- mkdir --------------------------------------------------------------\n\nconst mkdirSchema = z.object({\n path: z.string().describe(\"Directory path to create. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z.boolean().optional().describe(\"Create parent directories as needed (default true)\"),\n});\n\nexport const fileMkdirTool = tool(\n async ({ path: dirPath, recursive }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"write\");\n await fs.mkdir(abs, { recursive: recursive !== false });\n return JSON.stringify({ ok: true, path: abs });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_mkdir\",\n description: \"Create a directory. Creates parents by default.\",\n schema: mkdirSchema,\n },\n);\n\n// --- delete -------------------------------------------------------------\n\nconst deleteSchema = z.object({\n path: z.string().describe(\"File or directory path to remove. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z\n .boolean()\n .optional()\n .describe(\"Required to delete a non-empty directory (default false)\"),\n});\n\nexport const fileDeleteTool = tool(\n async ({ path: targetPath, recursive }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n assertSafePath(abs, \"write\");\n const st = await fs.stat(abs);\n if (st.isDirectory()) {\n if (!recursive) {\n // Try non-recursive rmdir first — succeeds only if empty.\n try {\n await fs.rmdir(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"empty\" });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOTEMPTY\") {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"directory is not empty. Pass recursive=true to delete its contents.\",\n });\n }\n throw err;\n }\n }\n await fs.rm(abs, { recursive: true, force: false });\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"recursive\" });\n }\n await fs.unlink(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"file\" });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_delete\",\n description:\n \"Delete a file or directory. Non-empty directories require recursive=true. Symlinks are not followed.\",\n schema: deleteSchema,\n },\n);\n\n// --- copy ---------------------------------------------------------------\n\nconst copySchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is copied into it preserving its basename.\"),\n overwrite: z.boolean().optional().describe(\"Allow replacing an existing destination (default false)\"),\n recursive: z.boolean().optional().describe(\"Recurse when copying a directory (default true)\"),\n});\n\nexport const fileCopyTool = tool(\n async ({ source, destination, overwrite, recursive }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"read\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // missing\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat && !overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n if (srcStat.isDirectory()) {\n if (recursive === false) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n error: \"source is a directory but recursive=false\",\n });\n }\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n } else {\n await fs.copyFile(srcAbs, dstAbs);\n }\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_copy\",\n description:\n \"Copy a file or directory. If destination is an existing directory, source is copied into it. Directories require recursive=true (default).\",\n schema: copySchema,\n },\n);\n\n// --- stat ---------------------------------------------------------------\n\nconst statSchema = z.object({\n path: z.string().describe(\"File or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n});\n\nexport const fileStatTool = tool(\n async ({ path: targetPath }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n const st = await fs.stat(abs);\n return JSON.stringify({\n ok: true,\n path: abs,\n exists: true,\n kind: st.isDirectory() ? \"directory\" : st.isFile() ? \"file\" : \"other\",\n size: st.size,\n modified_ms: st.mtimeMs,\n created_ms: st.birthtimeMs,\n mode: st.mode,\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n return JSON.stringify({ ok: true, path: abs, exists: false });\n }\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_stat\",\n description: \"Check whether a path exists and return its kind, size, and timestamps.\",\n schema: statSchema,\n },\n);\n\nregisterTools(\"Files\", [\n fileReadTool, fileWriteTool, fileEditTool, fileMoveTool, fileCopyTool,\n fileDeleteTool, fileListTool, fileMkdirTool, fileStatTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\n// Tavily is the preferred backend for agent-grade search (clean JSON, citations,\n// good ranking) but requires an API key. Without one we fall back to scraping\n// DuckDuckGo's HTML endpoint — which works without auth and goes through\n// EnvHttpProxyAgent on corporate networks.\nasync function tavilySearch(query: string, limit: number, apiKey: string): Promise<SearchResult[]> {\n const res = await fetch(\"https://api.tavily.com/search\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: limit,\n search_depth: \"basic\",\n }),\n });\n if (!res.ok) throw new Error(`Tavily ${res.status}: ${await res.text()}`);\n const data = (await res.json()) as { results?: Array<{ title: string; url: string; content?: string }> };\n return (data.results ?? []).slice(0, limit).map((r) => ({\n title: r.title,\n url: r.url,\n snippet: r.content ?? \"\",\n }));\n}\n\n// Rotate UA across retries — DDG flags repeated identical fingerprints.\nconst UA_POOL = [\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36\",\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0 Safari/537.36\",\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15\",\n \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0\",\n];\n\nasync function ddgSearch(query: string, limit: number): Promise<SearchResult[]> {\n // DDG returns a 202 \"anomaly detection\" placeholder when it suspects\n // automation. Retry with rotated UAs and exponential backoff. Empty results\n // on a 200 are treated as legitimate \"no hits\" and not retried.\n let lastStatus = 0;\n for (let attempt = 0; attempt < 5; attempt++) {\n const ua = UA_POOL[attempt % UA_POOL.length];\n const res = await fetch(\"https://html.duckduckgo.com/html/\", {\n method: \"POST\",\n headers: {\n \"User-Agent\": ua,\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Referer\": \"https://duckduckgo.com/\",\n },\n body: `q=${encodeURIComponent(query)}&kl=us-en`,\n });\n lastStatus = res.status;\n if (!res.ok) throw new Error(`DuckDuckGo ${res.status}`);\n const html = await res.text();\n const parsed = parseDDGHtml(html, limit);\n if (parsed.length > 0) return parsed;\n if (res.status !== 202) return parsed; // genuine empty result on 200\n // Backoff: 400, 900, 1600, 2500 ms — total max ≈ 5.4s\n await new Promise((r) => setTimeout(r, 400 + attempt * 500));\n }\n // All retries returned 202 placeholder — surface as empty so caller can handle.\n console.warn(`[web_search] DDG returned ${lastStatus} placeholder on all attempts for \"${query}\"`);\n return [];\n}\n\nfunction parseDDGHtml(html: string, limit: number): SearchResult[] {\n const results: SearchResult[] = [];\n // Each result block contains a result__a (title link) and a result__snippet (snippet link).\n const blockRe = /<div\\s+class=\"result\\s+results_links[^\"]*\"[\\s\\S]*?<\\/div>\\s*<\\/div>/g;\n let match: RegExpExecArray | null;\n while ((match = blockRe.exec(html)) !== null) {\n if (results.length >= limit) break;\n const block = match[0];\n const titleMatch = /<a[^>]+class=\"result__a\"[^>]+href=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n const snippetMatch = /<a[^>]+class=\"result__snippet\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n if (!titleMatch) continue;\n const url = unwrapDDGRedirect(decodeHTML(titleMatch[1]));\n if (!url) continue;\n const title = stripTags(titleMatch[2]).trim();\n const snippet = snippetMatch ? stripTags(snippetMatch[1]).trim() : \"\";\n if (title) results.push({ title, url, snippet });\n }\n return results;\n}\n\nfunction unwrapDDGRedirect(href: string): string | null {\n // DDG wraps outbound links as //duckduckgo.com/l/?uddg=<encoded>&...\n if (href.startsWith(\"//\")) href = `https:${href}`;\n try {\n const u = new URL(href);\n if (u.hostname.endsWith(\"duckduckgo.com\") && u.pathname === \"/l/\") {\n const real = u.searchParams.get(\"uddg\");\n return real ? decodeURIComponent(real) : null;\n }\n return u.toString();\n } catch {\n return null;\n }\n}\n\nfunction stripTags(s: string): string {\n return s.replace(/<[^>]+>/g, \"\");\n}\n\nfunction decodeHTML(s: string): string {\n return s\n .replace(/&amp;/g, \"&\")\n .replace(/&quot;/g, '\"')\n .replace(/&#x27;/g, \"'\")\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\");\n}\n\nexport const webSearchTool = tool(\n async ({ query, max_results }) => {\n const limit = Math.min(max_results ?? 5, 10);\n const tavilyKey = process.env.TAVILY_API_KEY;\n\n try {\n const results = tavilyKey\n ? await tavilySearch(query, limit, tavilyKey)\n : await ddgSearch(query, limit);\n return JSON.stringify({\n query,\n provider: tavilyKey ? \"tavily\" : \"duckduckgo\",\n results,\n total: results.length,\n });\n } catch (err) {\n return JSON.stringify({\n query,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n },\n {\n name: \"web_search\",\n description:\n \"Search the web and return relevant results (title, url, snippet). \" +\n \"Best for factual lookups, current events, documentation, and research. \" +\n \"Returns up to 10 results per call; default 5.\",\n schema: z.object({\n query: z.string().describe(\"Search query\"),\n max_results: z.number().optional().describe(\"Max results to return (default 5, max 10)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webSearchTool]);\n","// SSRF guard: classify an address (or hostname) as \"private\" — i.e. one\n// that an LLM-driven agent should never be allowed to reach with a\n// server-side fetch driven by attacker-controlled input. The bar is set\n// by what the access middleware (lib/auth/access.ts) treats as\n// privileged: anything that resolves to loopback hits the API without\n// authentication, and link-local / cloud-metadata / RFC1918 ranges\n// reach the host's LAN or cloud provider's introspection surface.\n//\n// Used by `web_fetch` and other agent-controlled URL fetchers to block\n// the canonical SSRF / metadata-service paths:\n// - http://127.0.0.1:4312/api/v1/... → self-call into our own admin API\n// - http://169.254.169.254/... → AWS/GCE/Azure metadata\n// - http://10.x / 192.168.x / etc. → LAN router / printer admin\n//\n// Operators with a legitimate need (e.g. fetching from an internal docs\n// server) can opt back in with `JARELA_ALLOW_PRIVATE_FETCH=1`.\n\nimport { promises as dns } from \"node:dns\";\nimport net from \"node:net\";\n\nexport type PrivateClassification =\n | \"public\"\n | \"loopback\"\n | \"private\"\n | \"link-local\"\n | \"unspecified\"\n | \"broadcast\"\n | \"reserved\";\n\nfunction ipv4InCidr(addr: number, prefix: number, bits: number): boolean {\n const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0;\n return (addr & mask) === (prefix & mask);\n}\n\nfunction ipv4ToNumber(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let n = 0;\n for (const part of parts) {\n const v = Number(part);\n if (!Number.isInteger(v) || v < 0 || v > 255) return null;\n n = (n << 8) | v;\n }\n return n >>> 0;\n}\n\nfunction classifyIPv4(ip: string): PrivateClassification {\n const n = ipv4ToNumber(ip);\n if (n === null) return \"reserved\";\n // 0.0.0.0/8 — \"this network\"\n if (ipv4InCidr(n, ipv4ToNumber(\"0.0.0.0\")!, 8)) return \"unspecified\";\n // 127.0.0.0/8 — loopback\n if (ipv4InCidr(n, ipv4ToNumber(\"127.0.0.0\")!, 8)) return \"loopback\";\n // 10.0.0.0/8\n if (ipv4InCidr(n, ipv4ToNumber(\"10.0.0.0\")!, 8)) return \"private\";\n // 172.16.0.0/12\n if (ipv4InCidr(n, ipv4ToNumber(\"172.16.0.0\")!, 12)) return \"private\";\n // 192.168.0.0/16\n if (ipv4InCidr(n, ipv4ToNumber(\"192.168.0.0\")!, 16)) return \"private\";\n // 169.254.0.0/16 — link-local (incl. cloud metadata at 169.254.169.254)\n if (ipv4InCidr(n, ipv4ToNumber(\"169.254.0.0\")!, 16)) return \"link-local\";\n // 100.64.0.0/10 — CGNAT / Tailscale carrier-grade NAT range. Treat as\n // private: anything reachable here is a tailnet peer, not a public URL.\n if (ipv4InCidr(n, ipv4ToNumber(\"100.64.0.0\")!, 10)) return \"private\";\n // 224.0.0.0/4 — multicast; 240.0.0.0/4 — reserved; 255.255.255.255 — broadcast\n if (ipv4InCidr(n, ipv4ToNumber(\"224.0.0.0\")!, 4)) return \"reserved\";\n if (ipv4InCidr(n, ipv4ToNumber(\"240.0.0.0\")!, 4)) return \"reserved\";\n return \"public\";\n}\n\nfunction classifyIPv6(ip: string): PrivateClassification {\n // Normalise: lower-case, drop zone id (fe80::1%eth0).\n const bare = ip.toLowerCase().split(\"%\")[0];\n if (bare === \"::\" || bare === \"::0\") return \"unspecified\";\n if (bare === \"::1\") return \"loopback\";\n // IPv4-mapped (::ffff:a.b.c.d) — classify the embedded v4.\n if (bare.startsWith(\"::ffff:\")) {\n const v4 = bare.slice(7);\n if (net.isIPv4(v4)) return classifyIPv4(v4);\n }\n // fe80::/10 — link-local\n if (/^fe[89ab][0-9a-f]?:/.test(bare)) return \"link-local\";\n // fc00::/7 — unique local addresses\n if (/^f[cd][0-9a-f]{0,2}:/.test(bare)) return \"private\";\n // ff00::/8 — multicast\n if (bare.startsWith(\"ff\")) return \"reserved\";\n return \"public\";\n}\n\nexport function classifyAddress(ip: string): PrivateClassification {\n if (net.isIPv4(ip)) return classifyIPv4(ip);\n if (net.isIPv6(ip)) return classifyIPv6(ip);\n return \"reserved\";\n}\n\nexport function isPrivateAddress(ip: string): boolean {\n const cls = classifyAddress(ip);\n return cls !== \"public\";\n}\n\nexport interface UrlCheckResult {\n allowed: boolean;\n reason?: PrivateClassification | \"invalid-url\" | \"unsupported-scheme\" | \"resolve-failed\";\n resolved?: string[];\n}\n\n/**\n * Pre-flight check for a server-side fetch driven by agent input.\n *\n * Returns `{ allowed: true }` when every IP the URL's hostname resolves\n * to is publicly routable. If `JARELA_ALLOW_PRIVATE_FETCH=1` the result\n * is always `{ allowed: true }` (operator opt-out).\n *\n * Hostnames that fail to resolve are treated as **rejected** — better to\n * refuse than to hand the question off to undici and re-resolve at\n * connect time, when we have no way to inspect the answer.\n */\nexport async function checkPublicUrl(rawUrl: string): Promise<UrlCheckResult> {\n if (process.env.JARELA_ALLOW_PRIVATE_FETCH === \"1\") {\n return { allowed: true };\n }\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return { allowed: false, reason: \"invalid-url\" };\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return { allowed: false, reason: \"unsupported-scheme\" };\n }\n // Strip [] from IPv6 literals so net.isIP / dns.lookup work.\n const host = url.hostname.replace(/^\\[|\\]$/g, \"\");\n if (net.isIP(host)) {\n const cls = classifyAddress(host);\n return cls === \"public\" ? { allowed: true, resolved: [host] } : { allowed: false, reason: cls, resolved: [host] };\n }\n let addrs: Array<{ address: string; family: number }>;\n try {\n addrs = await dns.lookup(host, { all: true });\n } catch {\n return { allowed: false, reason: \"resolve-failed\" };\n }\n const resolved = addrs.map((a) => a.address);\n for (const addr of resolved) {\n const cls = classifyAddress(addr);\n if (cls !== \"public\") return { allowed: false, reason: cls, resolved };\n }\n return { allowed: true, resolved };\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { checkPublicUrl } from \"@/lib/utils/private-ip\";\nimport { registerTools } from \"./registry\";\n\nconst MAX_BYTES = 200_000;\nconst TIMEOUT_MS = 15_000;\n// Defense against SSRF redirect chains: every Location-hop is re-checked\n// against the SSRF policy. Cap the chain so a malicious server can't\n// pin us in a redirect loop.\nconst MAX_REDIRECTS = 5;\n\nfunction extractTitle(html: string): string | null {\n const m = /<title[^>]*>([^<]+)<\\/title>/i.exec(html);\n return m ? m[1].trim() : null;\n}\n\n// Pull image URLs out of a fetched page so the agent can embed them in its\n// reply via standard markdown `![alt](url)`. We expose three categories:\n// - og: the page's primary OG image (most useful — chosen by the publisher)\n// - twitter: the Twitter card image (close second)\n// - samples: the first few <img src=…> tags (fallback when meta is missing)\n//\n// All URLs are resolved to absolute against the final fetched URL so the\n// agent can use them as-is. Data URIs and tracking pixels are filtered out.\nfunction extractImages(html: string, baseUrl: string): {\n og: string | null;\n twitter: string | null;\n samples: string[];\n} {\n const og =\n /<meta[^>]+property=[\"']og:image(?::secure_url|:url)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+property=[\"']og:image[\"']/i.exec(html)?.[1] ?? null;\n\n const twitter =\n /<meta[^>]+name=[\"']twitter:image(?::src)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+name=[\"']twitter:image[\"']/i.exec(html)?.[1] ?? null;\n\n const seen = new Set<string>();\n const samples: string[] = [];\n for (const m of html.matchAll(/<img[^>]+src=[\"']([^\"']+)[\"']/gi)) {\n const src = m[1];\n if (!src || src.startsWith(\"data:\")) continue;\n // Skip obvious tracking pixels and tiny svgs.\n if (/(?:1x1|pixel|spacer)\\.(?:gif|png)/i.test(src)) continue;\n const abs = resolveUrl(src, baseUrl);\n if (!abs || seen.has(abs)) continue;\n seen.add(abs);\n samples.push(abs);\n if (samples.length >= 6) break;\n }\n\n return {\n og: resolveUrl(og, baseUrl),\n twitter: resolveUrl(twitter, baseUrl),\n samples,\n };\n}\n\nfunction resolveUrl(u: string | null | undefined, base: string): string | null {\n if (!u) return null;\n try { return new URL(u, base).toString(); } catch { return null; }\n}\n\nexport const webFetchTool = tool(\n async ({ url, mode, max_chars }) => {\n if (!/^https?:\\/\\//.test(url)) {\n return JSON.stringify({ error: \"url must start with http:// or https://\" });\n }\n const ctrl = new AbortController();\n const timeout = setTimeout(() => ctrl.abort(), TIMEOUT_MS);\n try {\n // SSRF guard. The LLM controls `url`, and our HTTP middleware\n // treats loopback callers as the host machine's admin user — a\n // prompt-injected page could otherwise ask the agent to fetch\n // http://127.0.0.1:4312/api/v1/... and elevate. Same story for\n // 169.254.169.254 (cloud metadata) and the RFC1918 ranges.\n // Operators with a legitimate intranet need can opt back in via\n // JARELA_ALLOW_PRIVATE_FETCH=1.\n const initialCheck = await checkPublicUrl(url);\n if (!initialCheck.allowed) {\n return JSON.stringify({\n url,\n error: `Refused to fetch private/loopback address (${initialCheck.reason}). Set JARELA_ALLOW_PRIVATE_FETCH=1 to override.`,\n });\n }\n\n // Manual redirect chasing so each hop is re-checked against the\n // SSRF policy. A 30x to an attacker-controlled host could otherwise\n // bounce us into 169.254.x even though the initial URL looked\n // public.\n let currentUrl = url;\n let res: Response;\n for (let hop = 0; ; hop++) {\n res = await fetch(currentUrl, {\n signal: ctrl.signal,\n redirect: \"manual\",\n headers: {\n \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Accept\": \"text/html,application/xhtml+xml,*/*;q=0.8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n },\n });\n if (res.status < 300 || res.status >= 400) break;\n const loc = res.headers.get(\"location\");\n if (!loc) break;\n if (hop >= MAX_REDIRECTS) {\n return JSON.stringify({ url: currentUrl, error: `too many redirects (>${MAX_REDIRECTS})` });\n }\n let next: string;\n try {\n next = new URL(loc, currentUrl).toString();\n } catch {\n return JSON.stringify({ url: currentUrl, error: `invalid redirect target: ${loc}` });\n }\n const hopCheck = await checkPublicUrl(next);\n if (!hopCheck.allowed) {\n return JSON.stringify({\n url: next,\n error: `Refused redirect to private/loopback address (${hopCheck.reason}).`,\n });\n }\n currentUrl = next;\n }\n\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n const finalUrl = res.url || currentUrl;\n // Read up to MAX_BYTES so a 5MB page doesn't blow the agent's context.\n const reader = res.body?.getReader();\n const decoder = new TextDecoder();\n let bytesRead = 0;\n let raw = \"\";\n if (reader) {\n while (bytesRead < MAX_BYTES) {\n const { value, done } = await reader.read();\n if (done) break;\n bytesRead += value.byteLength;\n raw += decoder.decode(value, { stream: true });\n if (bytesRead >= MAX_BYTES) {\n await reader.cancel();\n break;\n }\n }\n }\n const truncated = bytesRead >= MAX_BYTES;\n const cap = max_chars ?? 8000;\n const wantHtml = mode === \"html\";\n const title = extractTitle(raw);\n const body = wantHtml ? raw : stripHtml(raw);\n const clipped = body.length > cap ? body.slice(0, cap) + \"…\" : body;\n const images = extractImages(raw, finalUrl);\n\n return JSON.stringify({\n url: finalUrl,\n status: res.status,\n content_type: contentType,\n title,\n mode: wantHtml ? \"html\" : \"text\",\n bytes_read: bytesRead,\n truncated,\n content: clipped,\n images,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return JSON.stringify({ url, error: msg });\n } finally {\n clearTimeout(timeout);\n }\n },\n {\n name: \"web_fetch\",\n description:\n \"Fetch the content of a URL. Default mode='text' returns extracted plain text (good for summarizing articles). \" +\n \"mode='html' returns raw HTML if you specifically need markup. Truncates after 200KB. \" +\n \"Use this when web_search returns a URL but you need the actual page content, or to fetch a specific known page. \" +\n \"The response also includes an `images` object with absolute URLs extracted from the page: \" +\n \"`og` (og:image — usually the best hero image), `twitter` (twitter:image), and `samples` (first few <img> tags). \" +\n \"Embed these in your reply with markdown `![alt](url)` to produce rich, image-rich answers.\",\n schema: z.object({\n url: z.string().describe(\"Absolute URL starting with http:// or https://\"),\n mode: z.enum([\"text\", \"html\"]).optional().describe(\"'text' (default) extracts readable text; 'html' returns raw markup\"),\n max_chars: z.number().optional().describe(\"Max characters to return after extraction (default 8000)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webFetchTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { registerTools } from \"./registry\";\n\n// Returns the user's last reported browser geolocation, if they've opted in\n// from the UI. The agent should call this whenever a request is location-\n// dependent (\"what's the weather\", \"find a coffee shop near me\", \"how long\n// to drive home\"). It returns a structured JSON payload — never coordinates\n// inline in prose. If sharing is disabled the result explains how to enable\n// it, so the agent can relay that to the user.\nexport const getUserLocationTool = tool(\n async () => {\n const profile = getUserProfile();\n if (!profile || profile.location_consent !== 1) {\n return JSON.stringify({\n available: false,\n reason: \"user has not enabled location sharing\",\n how_to_enable: \"Open the Profile panel and toggle 'Share my location'.\",\n });\n }\n if (\n typeof profile.location_lat !== \"number\" ||\n typeof profile.location_lng !== \"number\"\n ) {\n return JSON.stringify({\n available: false,\n reason: \"consent granted but no coordinates reported yet\",\n how_to_enable: \"Reload the app so the browser can request a fix.\",\n });\n }\n const updatedAt = profile.location_updated_at;\n const ageMs = updatedAt ? Date.now() - Date.parse(updatedAt) : null;\n return JSON.stringify({\n available: true,\n lat: profile.location_lat,\n lng: profile.location_lng,\n accuracy_m: profile.location_accuracy_m ?? null,\n label: profile.location_label ?? null,\n updated_at: updatedAt,\n age_seconds: ageMs !== null ? Math.round(ageMs / 1000) : null,\n });\n },\n {\n name: \"get_user_location\",\n description:\n \"Get the user's current geographic location (latitude/longitude) from their browser. Use this whenever the answer depends on where the user is — weather, nearby places, directions home, local time of points-of-interest. Returns { available, lat, lng, accuracy_m, label, age_seconds } or { available: false, reason } if the user hasn't opted in.\",\n schema: z.object({}).describe(\"No arguments — the user's location is stored server-side and updated by the client.\"),\n },\n);\n\nregisterTools(\"Web\", [getUserLocationTool]);\n","// generate_image: produce an image from a text prompt using Google's Gemini\n// image-generation models (a.k.a. \"nano banana\") via the Generative Language\n// REST API. Falls back to Imagen if the user picks one of those model ids.\n//\n// API key resolution: integrations store (\"google\" → api_key) →\n// GEMINI_API_KEY env → GOOGLE_API_KEY env. The Integrations panel is the\n// recommended way to set this.\n//\n// Output: PNG bytes written to ~/.jarela/files/<uuid>.png. The tool returns\n// a relative URL the chat renderer can embed via markdown `![alt](url)`.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { resolveGoogleApiKey, timeoutSignal } from \"@/lib/utils/google-api\";\nimport { registerTools } from \"./registry\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-image\";\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\ninterface ImagenPrediction {\n bytesBase64Encoded?: string;\n mimeType?: string;\n}\ninterface ImagenResponse {\n predictions?: ImagenPrediction[];\n error?: { message?: string };\n}\n\nasync function callGemini(model: string, prompt: string, apiKey: string): Promise<{ data: Buffer; mime: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`;\n const body = {\n contents: [{ role: \"user\", parts: [{ text: prompt }] }],\n generationConfig: { responseModalities: [\"IMAGE\", \"TEXT\"] },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Gemini request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"image/png\";\n if (data) return { data: Buffer.from(data, \"base64\"), mime };\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini returned no image: ${text}` : \"Gemini returned no image\");\n}\n\nasync function callImagen(model: string, prompt: string, apiKey: string, n: number, aspect: string): Promise<Array<{ data: Buffer; mime: string }>> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:predict?key=${encodeURIComponent(apiKey)}`;\n const body = {\n instances: [{ prompt }],\n parameters: { sampleCount: Math.max(1, Math.min(4, n)), aspectRatio: aspect },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Imagen request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as ImagenResponse;\n if (!res.ok) {\n throw new Error(`Imagen ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const preds = json.predictions ?? [];\n const out: Array<{ data: Buffer; mime: string }> = [];\n for (const p of preds) {\n if (p.bytesBase64Encoded) {\n out.push({ data: Buffer.from(p.bytesBase64Encoded, \"base64\"), mime: p.mimeType ?? \"image/png\" });\n }\n }\n if (out.length === 0) throw new Error(\"Imagen returned no image\");\n return out;\n}\n\nfunction describeError(err: unknown): string {\n if (!(err instanceof Error)) return String(err);\n const cause = (err as { cause?: unknown }).cause;\n if (cause instanceof Error) {\n const code = (cause as { code?: string }).code;\n return code ? `${err.message}: ${cause.message} (${code})` : `${err.message}: ${cause.message}`;\n }\n return err.message;\n}\n\nfunction extForMime(mime: string): string {\n if (mime === \"image/jpeg\") return \"jpg\";\n if (mime === \"image/webp\") return \"webp\";\n if (mime === \"image/gif\") return \"gif\";\n return \"png\";\n}\n\nexport const generateImageTool = tool(\n async ({ prompt, model, count, aspect_ratio }) => {\n const trimmed = prompt.trim();\n if (!trimmed) throw new Error(\"prompt is required and must be non-empty\");\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open the Integrations panel and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const m = (model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;\n const aspect = aspect_ratio ?? \"1:1\";\n const n = count ?? 1;\n\n const images = m.startsWith(\"imagen\")\n ? await callImagen(m, trimmed, apiKey, n, aspect)\n : [await callGemini(m, trimmed, apiKey)];\n\n const saved = images.map((img) => {\n const name = `img-${randomUUID()}.${extForMime(img.mime)}`;\n writeBinaryFile(name, img.data);\n const url = `/api/v1/files/${name}`;\n return { url, mime: img.mime, bytes: img.data.length };\n });\n\n return JSON.stringify({\n model: m,\n prompt: trimmed,\n images: saved,\n markdown: saved.map((s, i) => `![${trimmed.slice(0, 80)}${images.length > 1 ? ` (${i + 1})` : \"\"}](${s.url})`).join(\"\\n\\n\"),\n hint: \"Embed images in your reply using the `markdown` field verbatim, or build your own `![alt](url)` from `images[].url`.\",\n });\n },\n {\n name: \"generate_image\",\n description:\n \"Generate one or more images from a text prompt using Google's Gemini image models (default: gemini-2.5-flash-image) or Imagen. Returns local URLs the assistant should embed in its reply via markdown `![alt](url)`. Requires the Google integration (api_key) to be configured.\",\n schema: z.object({\n prompt: z.string().describe(\"Detailed description of the image to generate.\"),\n model: z\n .string()\n .optional()\n .describe(\n \"Optional Google model id. Defaults to `gemini-2.5-flash-image`. Use an `imagen-*` model (e.g. `imagen-3.0-generate-002`) for higher-fidelity stills.\",\n ),\n count: z\n .number()\n .int()\n .min(1)\n .max(4)\n .optional()\n .describe(\"Number of images to generate. Only honored by Imagen models; Gemini models always return 1.\"),\n aspect_ratio: z\n .enum([\"1:1\", \"3:4\", \"4:3\", \"9:16\", \"16:9\"])\n .optional()\n .describe(\"Aspect ratio. Only honored by Imagen models; ignored by Gemini image models.\"),\n }),\n },\n);\n\nregisterTools(\"Images\", [generateImageTool]);\n","// generate_voice: synthesize spoken audio from text using Gemini TTS and\n// return a /api/v1/files/ URL the assistant should embed in its reply.\n//\n// Voice/model are NOT exposed to the agent — they're locked to the\n// active agent's per-agent voice config (set by the user in AgentEditor).\n// The agent only controls *what* to say, *how* to say it (style), and\n// whether to autoplay. Multi-speaker scenes still allow per-speaker\n// voice selection because that's compositional, not preference.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { geminiTts, resolveGoogleApiKey } from \"@/lib/voice/gemini\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-preview-tts\";\nconst DEFAULT_VOICE = \"Kore\";\nconst MAX_TEXT_CHARS = 5000;\n\nconst SpeakerSchema = z.object({\n name: z.string().min(1).describe(\"Speaker label that appears in the text, e.g. 'Alice'.\"),\n voice_name: z.string().min(1).describe(\"Gemini prebuilt voice for this speaker (e.g. 'Kore', 'Puck').\"),\n});\n\nfunction resolveAgentVoice(config?: RunnableConfig): { model: string; voice: string } {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const thread = getThread(threadId);\n if (!thread?.agent_id) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const agent = getAgentConfig(thread.agent_id);\n return {\n model: agent?.voice_model?.trim() || DEFAULT_MODEL,\n voice: agent?.voice_name?.trim() || DEFAULT_VOICE,\n };\n}\n\nexport const generateVoiceTool = tool(\n async ({ text, style, speakers, autoplay }, config) => {\n const trimmed = (text ?? \"\").trim();\n if (!trimmed) throw new Error(\"text is required and must be non-empty\");\n if (trimmed.length > MAX_TEXT_CHARS) {\n throw new Error(`text exceeds ${MAX_TEXT_CHARS} character cap`);\n }\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open Integrations and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const { model, voice } = resolveAgentVoice(config);\n const speakerList = (speakers ?? [])\n .map((s) => ({ name: s.name.trim(), voiceName: s.voice_name.trim() }))\n .filter((s) => s.name && s.voiceName);\n\n const { wav } = await geminiTts({\n apiKey,\n model,\n voiceName: voice,\n text: trimmed,\n style: style?.trim() || undefined,\n speakers: speakerList.length >= 2 ? speakerList : undefined,\n });\n\n const name = `voice-${randomUUID()}.wav`;\n writeBinaryFile(name, wav);\n const baseUrl = `/api/v1/files/${name}`;\n const url = autoplay ? `${baseUrl}?autoplay=1` : baseUrl;\n\n return JSON.stringify({\n style: style ?? null,\n speakers: speakerList.length >= 2 ? speakerList : null,\n autoplay: !!autoplay,\n bytes: wav.length,\n url,\n markdown: `[\\u{1F50A} Voice clip${autoplay ? \" (auto)\" : \"\"}](${url})`,\n hint: \"Embed the `markdown` field verbatim in your reply on its own line; the chat renderer will turn that link into an inline audio player. Set autoplay=true only when the user asked you to speak (e.g. they sent voice input or explicitly asked you to talk). Do NOT wrap it in a code fence and do NOT transcribe the audio in the reply \\u2014 the player is the answer.\",\n });\n },\n {\n name: \"generate_voice\",\n description:\n \"Synthesize speech with Google's Gemini TTS using the agent's configured voice, and return a local audio URL the assistant must embed via the returned `markdown`. Use the `style` arg to steer tone/emotion (e.g. 'Say cheerfully', 'Whisper conspiratorially'). For dialogues, pass up to 2 `speakers` (with explicit voice names per speaker) and prefix each line in `text` with `Name: `. Requires the Google integration (api_key). The voice and model are picked by the user in the agent's settings and cannot be overridden here.\",\n schema: z.object({\n text: z\n .string()\n .min(1)\n .describe(\n \"The text to speak. For dialogues, write one turn per line as `Name: line` matching the `speakers` labels. Max 5000 chars.\",\n ),\n style: z\n .string()\n .optional()\n .describe(\n \"Natural-language style instruction prepended to the text, e.g. 'Say warmly and slowly', 'Whisper conspiratorially', 'In a tired, defeated voice', 'Read like a 1940s radio host'.\",\n ),\n speakers: z\n .array(SpeakerSchema)\n .min(2)\n .max(2)\n .optional()\n .describe(\n \"Optional 2-speaker setup for dialogues. When set, the agent's default voice is ignored and each line in `text` should start with one of the speaker `name`s followed by ': '. Use this only when composing a scripted dialogue with two distinct characters.\",\n ),\n autoplay: z\n .boolean()\n .optional()\n .describe(\n \"If true, the audio plays automatically when the message renders. Use this ONLY when the user clearly wants you to speak back (they sent voice input, said 'say it out loud', etc.). Default false \\u2014 user clicks play.\",\n ),\n }),\n },\n);\n\nregisterTools(\"Voice\", [generateVoiceTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport {\n createScheduledTask,\n listScheduledTasks,\n deleteScheduledTask,\n computeNextRun,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleTaskTool = tool(\n async (\n { prompt, when_iso, cron, description, silent, reaction_kind, reaction_script, reaction_script_args },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n if (!when_iso && !cron) return JSON.stringify({ error: \"Provide either when_iso (one-shot) or cron (recurring)\" });\n if (when_iso && cron) return JSON.stringify({ error: \"Provide only one of when_iso or cron, not both\" });\n // ADR-0032 — for kind='script' the agent must supply reaction_script.\n // For kind='agent_prompt' (default) prompt is required.\n if (reaction_kind === \"script\") {\n if (!reaction_script) {\n return JSON.stringify({ error: \"reaction_kind='script' requires reaction_script\" });\n }\n } else if (!prompt) {\n return JSON.stringify({ error: \"prompt is required when reaction_kind='agent_prompt'\" });\n }\n\n try {\n const kind = cron ? \"cron\" : \"once\";\n const schedule = cron ?? when_iso!;\n // Validate by computing the first run.\n const firstRun = computeNextRun(kind, schedule);\n if (kind === \"once\" && firstRun.getTime() < Date.now() - 60_000) {\n return JSON.stringify({ error: `when_iso \"${schedule}\" is in the past` });\n }\n const row = createScheduledTask({\n agent_id: agentId,\n prompt,\n description,\n kind,\n schedule,\n silent,\n reaction_kind,\n reaction_script,\n reaction_script_args,\n });\n // Make sure the poller is awake so newly created tasks fire on time.\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n kind,\n schedule,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_task\",\n description:\n \"Schedule a future firing for this agent. \" +\n \"For one-shot reminders pass when_iso (ISO 8601 timestamp, e.g. '2026-05-15T15:00:00Z'). \" +\n \"For recurring tasks pass a 5-field cron expression (e.g. '0 9 * * 1-5' = weekdays 9am). \" +\n \"Use the current time from your context to convert phrases like 'in 30 minutes' or 'tomorrow at 9am' into when_iso. \" +\n \"Default reaction_kind is 'agent_prompt' — the firing sends `prompt` to the agent. \" +\n \"Set reaction_kind='script' to fire a registered reaction.* script with no LLM round-trip; \" +\n \"use list_reaction_scripts to discover names. \" +\n \"Set silent=true for background polling tasks: suppresses the task_completed notification AND instructs the \" +\n \"agent to answer NO_REPLY on firings where there is nothing material to surface (those turns are dropped). \" +\n \"Errors still notify so failures aren't hidden. Visible firings remain tagged 'scheduled' so the user can hide \" +\n \"the group with the chat filter toolbar.\",\n schema: z.object({\n prompt: z.string().optional().describe(\n \"The prompt the agent will receive when the task fires. Required when reaction_kind='agent_prompt' (the default).\",\n ),\n when_iso: z.string().optional().describe(\"ISO 8601 UTC timestamp for one-shot scheduling\"),\n cron: z.string().optional().describe(\"5-field cron expression for recurring scheduling\"),\n description: z.string().optional().describe(\"Short human-readable label for the task\"),\n silent: z.boolean().optional().describe(\n \"When true the task is muted: the task_completed notification is suppressed and the agent is instructed to \" +\n \"reply only when something material surfaces (NO_REPLY answers are dropped). Errors still notify. \" +\n \"Useful for background polling jobs (e.g. 'check inbox every 10 min').\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"ADR-0032 reaction discriminator. 'agent_prompt' (default) runs the agent with `prompt`. \" +\n \"'script' runs a registered reaction.* script with no LLM round-trip.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Must be a name returned by list_reaction_scripts (begins with 'reaction.').\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object of args forwarded to the reaction script. The script also receives a `task` descriptor.\",\n ),\n }),\n },\n);\n\nexport const listScheduledTasksTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const tasks = listScheduledTasks(agentId).map((t) => ({\n id: t.id,\n prompt: t.prompt,\n description: t.description,\n kind: t.kind,\n schedule: t.schedule,\n next_run_at: t.next_run_at,\n last_run_at: t.last_run_at,\n last_error: t.last_error,\n enabled: t.enabled === 1,\n silent: t.silent === 1,\n reaction_kind: t.reaction_kind,\n reaction_script: t.reaction_script,\n reaction_script_args: t.reaction_script_args ? safeJson(t.reaction_script_args) : null,\n }));\n return JSON.stringify({ tasks, count: tasks.length });\n },\n {\n name: \"list_scheduled_tasks\",\n description: \"List all scheduled tasks for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelScheduledTaskTool = tool(\n async ({ id }) => {\n const ok = deleteScheduledTask(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Task ${id} not found` });\n },\n {\n name: \"cancel_scheduled_task\",\n description: \"Cancel a previously scheduled task by id.\",\n schema: z.object({\n id: z.string().describe(\"Task id returned by schedule_task or list_scheduled_tasks\"),\n }),\n },\n);\n\nregisterTools(\"Schedule\", [scheduleTaskTool, listScheduledTasksTool, cancelScheduledTaskTool]);\n","// Watcher tools (ADR-0027). Agent-facing CRUD for event-driven tasks.\n// Mirrors lib/tools/schedule.ts in shape so agents have a familiar\n// surface area: schedule_task ↔ schedule_watcher, list_scheduled_tasks\n// ↔ list_watchers, cancel_scheduled_task ↔ cancel_watcher.\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools, registeredTools } from \"./registry\";\nimport {\n createWatcher,\n listWatchers,\n deleteWatcher,\n} from \"@/lib/stores/watchers\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { listReactionScripts } from \"@/lib/triggers/scripts\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleWatcherTool = tool(\n async (\n {\n label,\n tool: toolName,\n args,\n every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n // Sanity-check that the tool exists locally. We can only register\n // watchers over built-in tools — MCP / external tool surfaces aren't\n // poll-safe in the scheduler (no per-request side context).\n const target = registeredTools().find((t) => t.name === toolName);\n if (!target) {\n return JSON.stringify({\n error: `Tool \"${toolName}\" is not a built-in tool. Watchers can only poll built-in tools.`,\n });\n }\n try {\n const row = createWatcher({\n agent_id: agentId,\n label,\n tool_name: toolName,\n tool_args: args ?? {},\n interval_seconds: every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n });\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n interval_seconds: row.interval_seconds,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_prompt: row.reaction_prompt,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_watcher\",\n description:\n \"Register an event-driven watcher: poll one built-in tool every N seconds \" +\n \"and re-engage this agent only when the tool's output changes since the \" +\n \"previous poll. Unlike schedule_task, this consumes zero LLM tokens between \" +\n \"changes — the scheduler runs the tool, hashes the result (SHA-256 of the \" +\n \"stringified return value), and only fires the agent on a diff. The agent \" +\n \"receives the previous + current results as context.\\n\\n\" +\n \"WHEN TO USE (use this instead of schedule_task whenever the user wants \" +\n \"to be notified about CHANGES rather than at fixed times):\\n\" +\n \" • 'tell me when Jira issue ABC-123 changes status' → jira_get_issue\\n\" +\n \" • 'ping me when a new ticket lands in SLPV assigned to me' → jira_search with a narrow JQL\\n\" +\n \" • 'notify me when files appear in ~/Downloads' → file_list on that path\\n\" +\n \" • 'watch this Confluence page for edits' → confluence_get_page\\n\" +\n \" • 'tell me when a webpage changes' → web_fetch\\n\\n\" +\n \"This is the SUBSTITUTE for webhooks and OS-level filesystem events, which \" +\n \"Jarela does not have. Don't tell the user 'no webhook support' — propose a \" +\n \"watcher instead.\\n\\n\" +\n \"LIMITS (be honest with the user about these):\\n\" +\n \" • Built-in tools only (no MCP / external tools — scheduler runs without per-request context).\\n\" +\n \" • Minimum interval 60 seconds.\\n\" +\n \" • Diff is byte-exact SHA-256 of the tool's stringified result. If the tool \" +\n \"returns volatile fields (e.g. `updated` timestamps, view counts) the watcher \" +\n \"will fire on every poll. Mitigate by passing args that narrow the tool's \" +\n \"output (e.g. `fields` on jira_search, specific paths on file_list).\\n\" +\n \" • First poll seeds the baseline silently — the agent is NOT fired on creation.\\n\\n\" +\n \"Set silent=true to mute the watcher: suppresses the task_completed notification on firing \" +\n \"AND lets the agent reply with NO_REPLY on changes it judges immaterial. Errors still notify.\\n\\n\" +\n \"REACTION KIND (ADR-0031): two reaction modes are supported.\\n\" +\n \" • 'agent_prompt' (default): on diff, this agent runs with reaction_prompt as the \" +\n \"directive (or the default 'summarise' directive if not supplied). Costs LLM tokens.\\n\" +\n \" • 'script': on diff, a built-in reaction script (`reaction.*`) runs INSTEAD of the \" +\n \"agent. Zero LLM tokens. Use list_reaction_scripts to discover available scripts \" +\n \"(e.g. `reaction.notify` posts a UI notification with the diff). Provide \" +\n \"reaction_script and optional reaction_script_args. Cannot be combined with reaction_prompt.\",\n schema: z.object({\n label: z.string().min(1).describe(\"Short human-readable name (e.g. 'ABC-123 status')\"),\n tool: z.string().min(1).describe(\"Name of a built-in tool to poll (e.g. 'jira_get_issue')\"),\n args: z.record(z.string(), z.unknown()).optional().describe(\n \"Arguments to pass to the tool on every poll, as a JSON object\",\n ),\n every_seconds: z.number().int().min(60).describe(\n \"Polling interval in seconds. Minimum 60.\",\n ),\n silent: z.boolean().optional().describe(\n \"When true the watcher is muted: the task_completed notification is suppressed and the agent is \" +\n \"instructed to reply only when the change is material (NO_REPLY firings are dropped). Errors still notify. \" +\n \"Visible firings remain tagged 'watcher'.\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"Reaction mode (ADR-0031). 'agent_prompt' (default) runs this agent on each diff; \" +\n \"'script' runs a built-in reaction.* script with no LLM round-trip.\",\n ),\n reaction_prompt: z.string().max(4000).optional().describe(\n \"Only valid when reaction_kind='agent_prompt' (or unset). Optional instruction for \" +\n \"what the agent should do on each detected change. Replaces the default 'summarise \" +\n \"the diff' directive. The previous + current tool results are still appended as \" +\n \"context, so the prompt should describe the REACTION (e.g. 'open a Jira ticket \" +\n \"against the broken dashboard', 'message me in plain English only if the price \" +\n \"dropped >5%'). Max 4000 characters.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Name of a registered reaction script \" +\n \"(must start with 'reaction.'). Use list_reaction_scripts to discover.\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object forwarded to the reaction script alongside the diff context \" +\n \"({watcher, previous, current}). Schema is script-specific.\",\n ),\n }),\n },\n);\n\nexport const listReactionScriptsTool = tool(\n async () => {\n const scripts = listReactionScripts();\n return JSON.stringify({ scripts, count: scripts.length });\n },\n {\n name: \"list_reaction_scripts\",\n description:\n \"List the names of built-in reaction scripts available to schedule_watcher AND \" +\n \"schedule_task when reaction_kind='script'. Reaction scripts run with NO LLM round-trip \" +\n \"on a firing. Watchers auto-merge {watcher, previous, current} into the script args; \" +\n \"scheduled tasks auto-merge a `task` descriptor (no diff context). Names are always \" +\n \"prefixed with `reaction.` (e.g. `reaction.notify`). Internal built-in scripts outside \" +\n \"the `reaction.` namespace (for example documents.reindex_local_file) are intentionally \" +\n \"excluded from this list.\",\n schema: z.object({}),\n },\n);\n\nexport const listWatchersTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const watchers = listWatchers(agentId).map((w) => ({\n id: w.id,\n label: w.label,\n tool: w.tool_name,\n args: safeParse(w.tool_args),\n interval_seconds: w.interval_seconds,\n next_run_at: w.next_run_at,\n last_run_at: w.last_run_at,\n last_fired_at: w.last_fired_at,\n last_error: w.last_error,\n enabled: w.enabled === 1,\n silent: w.silent === 1,\n reaction_kind: w.reaction_kind,\n reaction_prompt: w.reaction_prompt,\n reaction_script: w.reaction_script,\n reaction_script_args: w.reaction_script_args ? safeParse(w.reaction_script_args) : null,\n }));\n return JSON.stringify({ watchers, count: watchers.length });\n },\n {\n name: \"list_watchers\",\n description: \"List all event-driven watchers registered for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelWatcherTool = tool(\n async ({ id }) => {\n const ok = deleteWatcher(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Watcher ${id} not found` });\n },\n {\n name: \"cancel_watcher\",\n description: \"Cancel a previously registered watcher by id.\",\n schema: z.object({\n id: z.string().describe(\"Watcher id returned by schedule_watcher or list_watchers\"),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Schedule\", [\n scheduleWatcherTool,\n listWatchersTool,\n cancelWatcherTool,\n listReactionScriptsTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { createPendingAction, getPendingAction } from \"@/lib/stores/pending-actions\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n return getThread(threadId)?.agent_id ?? null;\n}\n\nexport const proposeConfigChangeTool = tool(\n async ({ kind, payload, reason }, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"no agent context\" });\n const row = createPendingAction({ agent_id: agentId, kind, payload, reason });\n // Surface as a browser notification so the user notices even if not on this agent.\n publishNotification({\n type: \"run_completed\", // reuse channel; UI can branch on preview text\n thread_id: \"\",\n agent_id: agentId,\n status: \"done\",\n preview: `🛠️ Proposed config change (${kind}) — awaiting your approval`,\n ts: Date.now(),\n });\n return JSON.stringify({\n proposal_id: row.id,\n status: \"pending\",\n message:\n \"Proposal queued for the user's approval. Tell the user briefly what you proposed and that \" +\n \"they need to approve it in the chat. Do not retry; check status later with check_proposal.\",\n });\n },\n {\n name: \"propose_config_change\",\n description:\n \"Propose a configuration change that requires user approval. Use this when you'd benefit from \" +\n \"installing/toggling an MCP server, or modifying agent settings (tool allowlist, identity, instructions, history window). \" +\n \"The proposal is queued and shown to the user; they explicitly approve or deny. \" +\n \"Don't propose changes the user didn't ask for — only when the current task clearly needs it.\",\n schema: z.object({\n kind: z\n .enum([\n \"install_mcp\",\n \"toggle_mcp\",\n \"update_agent_tools\",\n \"update_agent\",\n \"start_oauth\",\n \"set_provider_key\",\n \"enable_integration\",\n \"upsert_harness\",\n ])\n .describe(\"Type of change being proposed\"),\n payload: z.record(z.string(), z.unknown())\n .describe(\n \"Parameters for the change. NEVER put secrets, API keys, OAuth tokens, \" +\n \"or passwords in this object — those are collected by the approval UI \" +\n \"directly. Examples by kind:\\n\" +\n \"- install_mcp: { registry_id: 'github', variables: { GITHUB_TOKEN: 'asks-user-for-it' } } \" +\n \" OR { name, transport, spec }\\n\" +\n \"- toggle_mcp: { name: 'github', enabled: true }\\n\" +\n \"- update_agent_tools: { agent_id: '<this-agent>', tools: ['web_search', 'memory_*'] }\\n\" +\n \"- update_agent: { agent_id, identity?, instructions?, history_limit?, history_window_hours?, harness_id? } \" +\n \" — harness_id accepts an existing harness id ('builtin:default' or 'custom:<uuid>'), or null to inherit the global default\\n\" +\n \"- start_oauth: { integration_id: 'gmail' } — only after enable_integration saved client_id/secret\\n\" +\n \"- set_provider_key: { name: 'anthropic-default', provider: 'anthropic', model_id: 'claude-opus-4-7', is_default?: true } \" +\n \" — the user pastes the API key into the approval modal; do NOT include it here\\n\" +\n \"- enable_integration: { id: 'gmail' } — the user fills credentials in the approval modal\\n\" +\n \"- upsert_harness: { id?: 'custom:<uuid>', name, description?, sections: { capabilities?: {enabled,body}, plan_first?: {enabled,body}, presentation?: {enabled,body}, citation?: {enabled,body}, self_config?: {enabled,body} } } \" +\n \" — omit `id` to create; pass an existing custom:* id to edit. Built-in harnesses ('builtin:*') are read-only and rejected.\"\n ),\n reason: z.string().describe(\"Short human-readable reason shown to the user (≤100 chars)\"),\n }),\n },\n);\n\nexport const checkProposalTool = tool(\n async ({ proposal_id }) => {\n const row = getPendingAction(proposal_id);\n if (!row) return JSON.stringify({ error: `proposal ${proposal_id} not found` });\n return JSON.stringify({\n id: row.id,\n kind: row.kind,\n status: row.status,\n result: row.result ? safeParse(row.result) : null,\n created_at: row.created_at,\n decided_at: row.decided_at,\n });\n },\n {\n name: \"check_proposal\",\n description: \"Check the status of a previously-submitted config-change proposal by its id.\",\n schema: z.object({\n proposal_id: z.string(),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Config\", [proposeConfigChangeTool, checkProposalTool]);\n","// Read-only tools that expose integration manifests to the agent. See\n// ADR-0010 — these power the \"user asks how to connect X → agent narrates\n// the steps and proposes actions\" loop without giving the agent any new\n// privileges.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getManifest, listManifests } from \"@/lib/integrations/registry\";\nimport { registerTools } from \"./registry\";\nimport { getIntegrationStatus, isKnownIntegration } from \"@/lib/stores/integrations\";\n\nfunction manifestStatus(id: string): \"configured\" | \"not_configured\" | \"no_credentials_schema\" {\n if (!isKnownIntegration(id)) return \"no_credentials_schema\";\n return getIntegrationStatus(id)?.configured ? \"configured\" : \"not_configured\";\n}\n\nexport const listIntegrationsTool = tool(\n async () => {\n const summary = listManifests().map((m) => ({\n id: m.id,\n name: m.name,\n category: m.category,\n summary: m.summary,\n status: manifestStatus(m.id),\n }));\n return JSON.stringify({ integrations: summary });\n },\n {\n name: \"list_integrations\",\n description:\n \"List every integration Jarela knows how to set up, with a one-line summary and \" +\n \"current configuration status. Read-only. Use this when the user asks 'what can I connect?' \" +\n \"or before proposing enable_integration, so you know what's available and whether it's \" +\n \"already configured.\",\n schema: z.object({}),\n },\n);\n\nexport const getIntegrationSetupTool = tool(\n async ({ id }) => {\n const manifest = getManifest(id);\n if (!manifest) {\n return JSON.stringify({\n error: `unknown integration \"${id}\". Call list_integrations to see available ids.`,\n });\n }\n return JSON.stringify({\n id: manifest.id,\n name: manifest.name,\n summary: manifest.summary,\n category: manifest.category,\n status: manifestStatus(manifest.id),\n prerequisites: manifest.prerequisites,\n steps: manifest.steps,\n troubleshooting: manifest.troubleshooting,\n notes: [\n \"Walk the user through `prerequisites` first; some require browser actions outside Jarela.\",\n \"For each step that has a `proposes` field, call propose_config_change with that kind when ready.\",\n \"When a step has a `verify.tool`, call that tool after applying the step to confirm success.\",\n ],\n });\n },\n {\n name: \"get_integration_setup\",\n description:\n \"Return the full setup manifest for one integration — prerequisites, ordered steps, and \" +\n \"troubleshooting hints. Read-only. Use this before walking the user through a setup, or \" +\n \"when a tool fails and you need the integration-specific recovery hint.\",\n schema: z.object({\n id: z.string().describe(\"Integration id from list_integrations (e.g. 'gmail', 'atlassian')\"),\n }),\n },\n);\n\nregisterTools(\"Config\", [listIntegrationsTool, getIntegrationSetupTool]);\n","/**\n * Native Google Calendar tools — direct REST calls to\n * calendar.googleapis.com, sharing the Gmail OAuth client (one Google\n * account, one refresh token, one access-token cache; see\n * lib/integrations/gmail-oauth.ts).\n *\n * Scope-wise this surface is **events on existing calendars**:\n * - list / get / create / update / delete events\n * - list the user's calendars (read-only)\n * There is deliberately no calendar-list create/delete and no ACL\n * editing. To enable a wider surface, add the broader scope to\n * GMAIL_SCOPES and (force users to) reconnect.\n *\n * v1 design notes:\n * - calendarId defaults to \"primary\" everywhere so the agent can\n * create a quick event without first calling list_calendars.\n * - All datetimes are RFC3339 strings (e.g. \"2026-05-19T16:00:00-07:00\").\n * When the caller omits a timezone offset, Google falls back to the\n * calendar's default TZ. The tools surface a `time_zone` field that\n * forwards an IANA name in case the caller wants to be explicit.\n * - `calendar_create_event` can provision a Google Meet link via the\n * conferenceData createRequest dance — gated behind `add_meet_link`\n * so unused calls don't trip Google's quota.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n googleFetch,\n resolveGoogleAuth,\n type GoogleAuth,\n} from \"@/lib/integrations/gmail-oauth\";\n\nconst CALENDAR_BASE = \"https://www.googleapis.com/calendar/v3\";\nconst calendarFetch = (auth: GoogleAuth, path: string, init?: RequestInit) =>\n googleFetch(auth, \"Calendar\", CALENDAR_BASE, path, init);\n\n// ── Type shapes (minimal — only what we read back) ──────────────────────────\n\ninterface CalendarListEntry {\n id?: string;\n summary?: string;\n primary?: boolean;\n timeZone?: string;\n accessRole?: string;\n}\n\ninterface EventDateTime {\n dateTime?: string;\n date?: string;\n timeZone?: string;\n}\n\ninterface EventAttendee {\n email?: string;\n displayName?: string;\n responseStatus?: string;\n}\n\ninterface CalendarEvent {\n id?: string;\n status?: string;\n htmlLink?: string;\n hangoutLink?: string;\n summary?: string;\n description?: string;\n location?: string;\n start?: EventDateTime;\n end?: EventDateTime;\n attendees?: EventAttendee[];\n}\n\n// Slim down a full event to the fields the agent actually needs in a\n// thread response. Keeps tool outputs small enough not to blow context.\nfunction slimEvent(e: CalendarEvent): Record<string, unknown> {\n return {\n id: e.id,\n status: e.status,\n summary: e.summary ?? null,\n description: e.description ?? null,\n location: e.location ?? null,\n start: e.start?.dateTime ?? e.start?.date ?? null,\n end: e.end?.dateTime ?? e.end?.date ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.email,\n name: a.displayName ?? null,\n response: a.responseStatus ?? null,\n })),\n meet_link: e.hangoutLink ?? null,\n html_link: e.htmlLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const calendarListCalendarsTool = tool(\n async () => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await calendarFetch(auth, \"/users/me/calendarList\") as {\n items?: CalendarListEntry[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.items ?? []).map((c) => ({\n id: c.id,\n summary: c.summary ?? null,\n primary: c.primary === true,\n time_zone: c.timeZone ?? null,\n access_role: c.accessRole ?? null,\n })),\n });\n },\n {\n name: \"calendar_list_calendars\",\n description:\n \"List the user's Google calendars (primary + any they've subscribed to). \" +\n \"Returns id, summary, primary flag, time zone, access role per entry. The \" +\n \"`id` is what other calendar_* tools expect as `calendar_id`. Use this when \" +\n \"the user mentions a non-primary calendar by name (e.g. 'put it on my Work \" +\n \"calendar') — match against `summary` to find the right id.\",\n schema: z.object({}),\n },\n);\n\nexport const calendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, query, max_results }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const params = new URLSearchParams({\n singleEvents: \"true\",\n orderBy: \"startTime\",\n maxResults: String(Math.min(Math.max(max_results ?? 25, 1), 100)),\n });\n // Default window: now → +7 days. Keeps \"what's on my schedule\" cheap.\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n params.set(\"timeMin\", time_min ?? now.toISOString());\n params.set(\"timeMax\", time_max ?? inAWeek.toISOString());\n if (query) params.set(\"q\", query);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events?${params.toString()}`,\n ) as { items?: CalendarEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.items ?? []).map(slimEvent),\n });\n },\n {\n name: \"calendar_list_events\",\n description:\n \"List events on a calendar within a time window. Defaults: primary calendar, \" +\n \"now → +7 days, ordered by start, recurring events expanded into single \" +\n \"instances. **Use this before creating an event** to avoid double-booking, \" +\n \"and to look up existing event ids before updating/deleting. \" +\n \"Datetimes are RFC3339 (e.g. '2026-05-19T16:00:00-07:00').\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n query: z.string().optional().describe(\"Free-text search across event fields\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const calendarGetEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(auth, `/calendars/${cal}/events/${eid}`) as\n CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_get_event\",\n description:\n \"Fetch one Google Calendar event by id. Returns the same slim shape as \" +\n \"calendar_list_events but for a single event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id (from calendar_list_events results)\"),\n }),\n },\n);\n\nexport const calendarCreateEventTool = tool(\n async ({\n calendar_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone, add_meet_link,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n\n interface EventBody {\n summary: string;\n description?: string;\n location?: string;\n start: EventDateTime;\n end: EventDateTime;\n attendees?: { email: string }[];\n conferenceData?: {\n createRequest: { requestId: string; conferenceSolutionKey: { type: string } };\n };\n }\n const body: EventBody = {\n summary,\n start: { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n end: { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n };\n if (description) body.description = description;\n if (location) body.location = location;\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((email) => ({ email }));\n }\n if (add_meet_link) {\n body.conferenceData = {\n createRequest: {\n // requestId must be unique per createRequest; Google echoes it back.\n requestId: `jarela-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n }\n\n // conferenceDataVersion=1 is required for Google to honor the\n // createRequest and provision a Meet URL. Harmless to set without it.\n const params = add_meet_link ? \"?conferenceDataVersion=1\" : \"\";\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events${params}`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_create_event\",\n description:\n \"Create a Google Calendar event on a calendar (default: 'primary'). \" +\n \"Datetimes are RFC3339 strings — include a timezone offset (e.g. \" +\n \"'2026-05-19T16:00:00-07:00') or set `time_zone` to an IANA name (e.g. \" +\n \"'America/Los_Angeles') so the user's calendar interprets the time \" +\n \"correctly. Attendees are emailed an invite automatically. Set \" +\n \"`add_meet_link: true` to provision a Google Meet URL on the event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n summary: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (markdown not rendered)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA timezone, e.g. 'America/Los_Angeles'\"),\n add_meet_link: z.boolean().optional().describe(\"Provision a Google Meet URL on this event\"),\n }),\n },\n);\n\nexport const calendarUpdateEventTool = tool(\n async ({\n calendar_id, event_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n\n const patch: Record<string, unknown> = {};\n if (summary !== undefined) patch.summary = summary;\n if (description !== undefined) patch.description = description;\n if (location !== undefined) patch.location = location;\n if (start_iso !== undefined) {\n patch.start = { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (end_iso !== undefined) {\n patch.end = { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (attendees !== undefined) {\n patch.attendees = attendees.map((email) => ({ email }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"PATCH\", body: JSON.stringify(patch) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_update_event\",\n description:\n \"Patch a Google Calendar event. Only the fields you supply are changed; \" +\n \"omit fields to leave them alone. Use this to reschedule (`start_iso`/`end_iso`), \" +\n \"rename (`summary`), or adjust the invitee list (`attendees` — note this \" +\n \"**replaces** the full list, so include everyone who should remain).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id\"),\n summary: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA timezone applied to start/end\"),\n }),\n },\n);\n\nexport const calendarDeleteEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"calendar_delete_event\",\n description:\n \"Delete a Google Calendar event by id. Attendees are notified by default. \" +\n \"Returns `{ ok: true, id }` on success. Use `calendar_list_events` to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n calendarListCalendarsTool, calendarListEventsTool, calendarGetEventTool,\n calendarCreateEventTool, calendarUpdateEventTool, calendarDeleteEventTool,\n]);\n","/**\n * Outlook Calendar tools via Microsoft Graph. Mirrors lib/tools/calendar.ts\n * (the Google Calendar set) one-for-one so the agent's mental model\n * carries over between providers.\n *\n * Graph differences vs Google Calendar worth knowing:\n * - Each event's start/end is { dateTime, timeZone } where timeZone is\n * a Windows-time-zone string by default (\"Pacific Standard Time\"),\n * not IANA. We pass an explicit `Prefer: outlook.timezone=\"UTC\"`\n * header so reads come back in UTC and the agent doesn't have to\n * navigate two TZ namespaces.\n * - Listing events in a window uses /calendarView (auto-expands\n * recurring series), parallel to Google's `singleEvents=true`.\n * - Online meetings use `isOnlineMeeting:true` +\n * `onlineMeetingProvider:\"teamsForBusiness\"`. Provisioning a Teams\n * link is gated behind `add_teams_link` to keep create_event cheap\n * when the agent just wants a plain event.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n graphFetch,\n resolveMicrosoftAuth,\n} from \"@/lib/integrations/microsoft-oauth\";\n\n// ── Graph type shapes (minimal subset) ──────────────────────────────────────\n\ninterface GraphCalendar {\n id?: string;\n name?: string;\n isDefaultCalendar?: boolean;\n canEdit?: boolean;\n owner?: { name?: string; address?: string };\n}\n\ninterface GraphDateTimeTimeZone {\n dateTime?: string;\n timeZone?: string;\n}\n\ninterface GraphAttendee {\n emailAddress?: { name?: string; address?: string };\n status?: { response?: string; time?: string };\n type?: string;\n}\n\ninterface GraphEvent {\n id?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n start?: GraphDateTimeTimeZone;\n end?: GraphDateTimeTimeZone;\n location?: { displayName?: string };\n attendees?: GraphAttendee[];\n isAllDay?: boolean;\n isCancelled?: boolean;\n showAs?: string;\n webLink?: string;\n onlineMeeting?: { joinUrl?: string };\n onlineMeetingProvider?: string;\n}\n\nfunction slimEvent(e: GraphEvent): Record<string, unknown> {\n return {\n id: e.id,\n subject: e.subject ?? null,\n description: e.bodyPreview ?? null,\n location: e.location?.displayName ?? null,\n start: e.start?.dateTime ?? null,\n end: e.end?.dateTime ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.emailAddress?.address ?? null,\n name: a.emailAddress?.name ?? null,\n response: a.status?.response ?? null,\n })),\n is_all_day: e.isAllDay === true,\n is_cancelled: e.isCancelled === true,\n show_as: e.showAs ?? null,\n teams_link: e.onlineMeeting?.joinUrl ?? null,\n web_link: e.webLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const outlookCalendarListCalendarsTool = tool(\n async () => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await graphFetch(auth, \"/me/calendars\") as {\n value?: GraphCalendar[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.value ?? []).map((c) => ({\n id: c.id,\n name: c.name ?? null,\n is_default: c.isDefaultCalendar === true,\n can_edit: c.canEdit === true,\n owner: c.owner?.address ?? null,\n })),\n });\n },\n {\n name: \"outlook_calendar_list_calendars\",\n description:\n \"List the user's Outlook calendars (primary + shared). Returns id, name, \" +\n \"is_default flag, edit permission, owner. The `id` is what other \" +\n \"outlook_calendar_* tools expect as `calendar_id`. Omit `calendar_id` \" +\n \"in those tools to use the user's default calendar.\",\n schema: z.object({}),\n },\n);\n\nexport const outlookCalendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, max_results }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n const startISO = time_min ?? now.toISOString();\n const endISO = time_max ?? inAWeek.toISOString();\n const top = Math.min(Math.max(max_results ?? 25, 1), 100);\n // /calendarView expands recurring series into individual instances —\n // the closest parallel to Google's singleEvents=true.\n const base = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/calendarView`\n : \"/me/calendarView\";\n const params = new URLSearchParams({\n startDateTime: startISO,\n endDateTime: endISO,\n $top: String(top),\n $orderby: \"start/dateTime\",\n });\n const data = await graphFetch(auth, `${base}?${params.toString()}`, {\n // Force UTC in responses so the agent doesn't juggle Windows-TZ names.\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as { value?: GraphEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.value ?? []).map(slimEvent),\n });\n },\n {\n name: \"outlook_calendar_list_events\",\n description:\n \"List Outlook calendar events within a time window. Defaults: default \" +\n \"calendar, now → +7 days, ordered by start, recurring series expanded. \" +\n \"**Use this before creating an event** to avoid double-booking, and to \" +\n \"look up event ids before updating/deleting. All datetimes returned in \" +\n \"UTC (RFC3339 'Z'-suffixed).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const outlookCalendarGetEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const e = await graphFetch(auth, `/me/events/${encodeURIComponent(event_id)}`, {\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (e.error) return JSON.stringify({ error: e.error });\n return JSON.stringify(slimEvent(e));\n },\n {\n name: \"outlook_calendar_get_event\",\n description:\n \"Fetch one Outlook calendar event by id. Returns the same slim shape as \" +\n \"outlook_calendar_list_events but for a single event.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id (from outlook_calendar_list_events)\"),\n }),\n },\n);\n\nexport const outlookCalendarCreateEventTool = tool(\n async ({\n calendar_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone, add_teams_link,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n interface EventBody {\n subject: string;\n body?: { contentType: \"text\"; content: string };\n start: GraphDateTimeTimeZone;\n end: GraphDateTimeTimeZone;\n location?: { displayName: string };\n attendees?: Array<{ emailAddress: { address: string }; type: \"required\" }>;\n isOnlineMeeting?: boolean;\n onlineMeetingProvider?: string;\n }\n // Graph uses Windows TZ names by default but also accepts IANA names\n // when the body specifies them per-field. Default to UTC if the\n // caller omits time_zone (matches the list endpoint's behavior).\n const tz = time_zone ?? \"UTC\";\n const body: EventBody = {\n subject,\n start: { dateTime: start_iso, timeZone: tz },\n end: { dateTime: end_iso, timeZone: tz },\n };\n if (description) body.body = { contentType: \"text\", content: description };\n if (location) body.location = { displayName: location };\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (add_teams_link) {\n body.isOnlineMeeting = true;\n body.onlineMeetingProvider = \"teamsForBusiness\";\n }\n\n const path = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/events`\n : \"/me/events\";\n const r = await graphFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_create_event\",\n description:\n \"Create an Outlook calendar event. Datetimes are RFC3339 strings; pair \" +\n \"with `time_zone` (IANA like 'America/Los_Angeles' or Windows TZ like \" +\n \"'Pacific Standard Time') so Outlook interprets them correctly. Defaults \" +\n \"to UTC if omitted. Attendees are automatically sent invites. Set \" +\n \"`add_teams_link: true` to provision a Teams meeting URL (requires a \" +\n \"work/school M365 account; personal Microsoft accounts cannot create \" +\n \"Teams meetings via Graph).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n subject: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (plain text)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA or Windows timezone (default 'UTC')\"),\n add_teams_link: z.boolean().optional().describe(\"Provision a Teams meeting URL on this event\"),\n }),\n },\n);\n\nexport const outlookCalendarUpdateEventTool = tool(\n async ({\n event_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const tz = time_zone ?? \"UTC\";\n const patch: Record<string, unknown> = {};\n if (subject !== undefined) patch.subject = subject;\n if (description !== undefined) patch.body = { contentType: \"text\", content: description };\n if (location !== undefined) patch.location = { displayName: location };\n if (start_iso !== undefined) patch.start = { dateTime: start_iso, timeZone: tz };\n if (end_iso !== undefined) patch.end = { dateTime: end_iso, timeZone: tz };\n if (attendees !== undefined) {\n patch.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(patch),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n },\n ) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_update_event\",\n description:\n \"Patch an Outlook calendar event. Only supplied fields are changed; omit \" +\n \"fields to leave them alone. Note `attendees` REPLACES the full invitee \" +\n \"list, so include everyone who should remain.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id\"),\n subject: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body (plain text)\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA or Windows TZ applied to start/end (default 'UTC')\"),\n }),\n },\n);\n\nexport const outlookCalendarDeleteEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"outlook_calendar_delete_event\",\n description:\n \"Delete an Outlook calendar event by id. Attendees are notified. Returns \" +\n \"`{ ok: true, id }` on success. Use outlook_calendar_list_events to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n outlookCalendarListCalendarsTool, outlookCalendarListEventsTool,\n outlookCalendarGetEventTool, outlookCalendarCreateEventTool,\n outlookCalendarUpdateEventTool, outlookCalendarDeleteEventTool,\n]);\n","// Barrel of built-in tool modules. Each side-effect import triggers the\n// module's `registerTools(...)` call (see ./registry.ts). Adding a new\n// built-in tool: add the file under lib/tools/ and append a line here.\n//\n// Order matters only for deterministic logging / UI ordering — registry\n// preserves insertion order.\n\nimport \"./memory\";\nimport \"./documents\";\nimport \"./exec\";\nimport \"./files\";\nimport \"./search\";\nimport \"./fetch\";\nimport \"./location\";\nimport \"./generate_image\";\nimport \"./generate_voice\";\nimport \"./schedule\";\nimport \"./watcher\";\nimport \"./propose\";\nimport \"./integrations\";\nimport \"./atlassian\";\nimport \"./jira-align\";\nimport \"./github\";\nimport \"./gmail\";\nimport \"./calendar\";\nimport \"./outlook\";\nimport \"./outlook-calendar\";\n","// Public tool surface for the agent runtime.\n//\n// Built-in tools register themselves at module load (see ./registry.ts and\n// ./builtins.ts). External tools live under JARELA_TOOLS_DIR and are\n// loaded per-call (hot-reload). MCP tools come from lib/mcp/client.ts.\n//\n// To add a new built-in tool:\n// 1. Copy lib/tools/template.ts to lib/tools/<name>.ts and implement it.\n// 2. Call `registerTools(\"<Category>\", [yourTool, ...])` at the bottom.\n// 3. Add `import \"./<name>\";` to lib/tools/builtins.ts.\n//\n// That's it — no central array to update, no parallel category map.\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\n\n// Side-effect import: triggers registerTools() in every built-in module.\nimport \"./builtins\";\n\nimport {\n registeredTools,\n registeredNames,\n registeredCategory,\n registeredGroup,\n type ToolCategory,\n type ToolGroup,\n} from \"./registry\";\nimport { getMcpTools } from \"@/lib/mcp/client\";\nimport {\n loadExternalTools,\n getToolsDir,\n type ExtensionLoadError,\n} from \"./external\";\nimport type { OpenAITool, ToolContext, ToolParamSchema } from \"./types\";\nimport type { ToolPolicy } from \"@/lib/agents/base\";\nimport { disabledCategories } from \"@/lib/stores/builtin-tools\";\n\nexport * from \"./types\";\nexport { getToolsDir, type ExtensionLoadError } from \"./external\";\nexport { registerTools, type ToolCategory, type ToolGroup } from \"./registry\";\n\nconst ALL_BUILTINS: StructuredToolInterface[] = registeredTools();\nexport const BUILTIN_TOOL_NAMES: ReadonlySet<string> = registeredNames();\n\n// Per-call recompute so files dropped in $JARELA_TOOLS_DIR are picked up\n// without restart. loadExternalTools cache-busts require() per file.\nfunction loadExternal() {\n return loadExternalTools(BUILTIN_TOOL_NAMES);\n}\n\nexport function getToolCategory(name: string, source: \"builtin\" | \"mcp\"): ToolCategory {\n const builtin = registeredCategory(name);\n if (builtin) return builtin;\n const ext = loadExternal().categories.get(name);\n if (ext) return ext;\n return source === \"mcp\" ? \"MCP\" : \"Config\";\n}\n\nexport function getToolGroup(name: string, source: \"builtin\" | \"mcp\"): ToolGroup {\n const cat = getToolCategory(name, source);\n if (cat === \"MCP\") return null;\n return registeredGroup(name) ?? null;\n}\n\nfunction applyPolicy(\n tools: StructuredToolInterface[],\n policy?: ToolPolicy,\n): StructuredToolInterface[] {\n const allowSet = policy?.allow?.length ? new Set(policy.allow) : null;\n const denySet = policy?.deny?.length ? new Set(policy.deny) : null;\n return tools.filter((t) => {\n if (allowSet && !allowSet.has(t.name)) return false;\n if (denySet && denySet.has(t.name)) return false;\n return true;\n });\n}\n\n// Filter built-in tools whose category is disabled in the toggle store.\n// External + MCP tools are untouched (they have their own enable surfaces).\nfunction applyCategoryToggles(tools: StructuredToolInterface[]): StructuredToolInterface[] {\n const disabled = disabledCategories();\n if (disabled.size === 0) return tools;\n return tools.filter((t) => {\n const cat = registeredCategory(t.name);\n if (!cat) return true; // not a built-in (or unregistered) → leave it\n return !disabled.has(cat);\n });\n}\n\n// Synchronous: built-in + external tools (no MCP). Used by GET /api/v1/tools\n// and any code path that can't await.\nexport function getAllTools(policy?: ToolPolicy): StructuredToolInterface[] {\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools],\n policy,\n );\n}\n\n// Async: built-in + external + MCP tools.\n// Use this anywhere the agent might invoke tools (createReactAgent input).\n// External tools are loaded per-call (hot-reload). MCP tools are cached by\n// lib/mcp/client.ts and only re-resolved when the mcp_servers table changes.\nexport async function getAllToolsAsync(policy?: ToolPolicy): Promise<StructuredToolInterface[]> {\n let mcpTools: StructuredToolInterface[] = [];\n try {\n mcpTools = await getMcpTools();\n } catch (err) {\n console.error(\"[tools] MCP load failed, continuing with built-ins only:\", err);\n }\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools, ...mcpTools],\n policy,\n );\n}\n\nexport function toOpenAITools(tools: StructuredToolInterface[]): OpenAITool[] {\n return tools.map((t) => {\n const oai = convertToOpenAITool(t);\n return {\n type: \"function\",\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n };\n });\n}\n\nexport async function executeTool(\n name: string,\n args: Record<string, unknown>,\n context: ToolContext = {},\n): Promise<unknown> {\n let t = ALL_BUILTINS.find((x) => x.name === name);\n if (t) {\n const cat = registeredCategory(name);\n if (cat && disabledCategories().has(cat)) {\n throw new Error(`Tool \"${name}\" is disabled (category ${cat} is turned off)`);\n }\n }\n if (!t) {\n t = loadExternal().tools.find((x) => x.name === name);\n }\n if (!t) throw new Error(`Unknown tool: ${name}`);\n\n const config: RunnableConfig = context.thread_id\n ? { configurable: { thread_id: context.thread_id } }\n : {};\n\n const result = await t.invoke(args, config);\n\n // Tools return JSON strings per LangChain convention; parse back for downstream use.\n if (typeof result === \"string\") {\n try {\n return JSON.parse(result);\n } catch {\n return result;\n }\n }\n return result;\n}\n\n// One-shot startup loader. Call from instrumentation.ts so external tools\n// load + log their status at boot rather than lazily on first agent turn.\nlet _initialized = false;\nexport interface InitToolsSummary {\n builtinCount: number;\n externalCount: number;\n errors: ExtensionLoadError[];\n toolsDir: string;\n}\n\nexport function initTools(): InitToolsSummary {\n const toolsDir = getToolsDir();\n const result = loadExternal();\n const summary: InitToolsSummary = {\n builtinCount: ALL_BUILTINS.length,\n externalCount: result.tools.length,\n errors: result.errors,\n toolsDir,\n };\n\n if (!_initialized) {\n console.info(\n `[tools] ${summary.builtinCount} built-in tool(s) registered; ` +\n `${summary.externalCount} external tool(s) loaded from ${toolsDir}`,\n );\n for (const err of summary.errors) {\n console.error(`[tools] external ${err.file}: ${err.error}`);\n }\n _initialized = true;\n }\n return summary;\n}\n","import type { PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\nexport interface ToolStatsRow {\n tool_name: string;\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n last_called_at: string | null;\n updated_at: string;\n}\n\nexport interface ToolUsefulnessStats {\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n success_rate: number;\n usefulness_rate: number;\n score: number;\n never_used: boolean;\n last_called_at: string | null;\n}\n\ninterface ToolUsageDelta {\n name: string;\n calls: number;\n successes: number;\n errors: number;\n used: number;\n}\n\nconst UPSERT_SQL = `\n INSERT INTO tool_stats\n (tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at)\n VALUES\n (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(tool_name) DO UPDATE SET\n call_count = tool_stats.call_count + excluded.call_count,\n success_count = tool_stats.success_count + excluded.success_count,\n error_count = tool_stats.error_count + excluded.error_count,\n used_count = tool_stats.used_count + excluded.used_count,\n last_called_at = COALESCE(excluded.last_called_at, tool_stats.last_called_at),\n updated_at = excluded.updated_at\n`;\n\nexport function recordToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): void {\n const deltas = summarizeToolUsage(toolEvents, assistantContent);\n if (deltas.length === 0) return;\n\n const db = getDb();\n const stamp = now();\n const stmt = db.prepare(UPSERT_SQL);\n db.exec(\"BEGIN\");\n try {\n for (const row of deltas) {\n stmt.run(\n row.name,\n row.calls,\n row.successes,\n row.errors,\n row.used,\n row.calls > 0 ? stamp : null,\n stamp,\n );\n }\n db.exec(\"COMMIT\");\n } catch (err) {\n try { db.exec(\"ROLLBACK\"); } catch { /* ignore rollback failure */ }\n throw err;\n }\n}\n\nexport function listToolStats(): ToolStatsRow[] {\n return getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats`,\n )\n .all() as unknown as ToolStatsRow[];\n}\n\nexport function getToolStatsMap(names?: readonly string[]): Map<string, ToolUsefulnessStats> {\n const rows = names && names.length > 0\n ? getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats\n WHERE tool_name IN (${names.map(() => \"?\").join(\",\")})`,\n )\n .all(...names) as unknown as ToolStatsRow[]\n : listToolStats();\n\n const out = new Map<string, ToolUsefulnessStats>();\n for (const row of rows) out.set(row.tool_name, toStats(row));\n return out;\n}\n\nexport function defaultToolStats(): ToolUsefulnessStats {\n return {\n call_count: 0,\n success_count: 0,\n error_count: 0,\n used_count: 0,\n success_rate: 1,\n usefulness_rate: 1,\n score: 1,\n never_used: true,\n last_called_at: null,\n };\n}\n\nexport function toStats(row: ToolStatsRow): ToolUsefulnessStats {\n const calls = Math.max(0, row.call_count);\n if (calls === 0) return defaultToolStats();\n\n const successRate = clamp01(row.success_count / calls);\n const usefulnessRate = clamp01(row.used_count / calls);\n const score = clamp01((successRate * 0.65) + (usefulnessRate * 0.35));\n\n return {\n call_count: calls,\n success_count: row.success_count,\n error_count: row.error_count,\n used_count: row.used_count,\n success_rate: successRate,\n usefulness_rate: usefulnessRate,\n score,\n never_used: false,\n last_called_at: row.last_called_at,\n };\n}\n\nexport function summarizeToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): ToolUsageDelta[] {\n const byId = new Map<string, { name: string; successful: boolean; used: boolean }>();\n const assistantTerms = normalizeText(assistantContent);\n\n for (const ev of toolEvents) {\n if (!ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const existing = byId.get(key) ?? { name: ev.name, successful: false, used: false };\n\n if (ev.phase === \"call\") {\n existing.name = ev.name;\n } else if (ev.phase === \"result\") {\n const successful = !isErrorPayload(ev.payload);\n existing.successful = successful;\n existing.used = successful && payloadLooksUsed(ev.payload, assistantTerms);\n }\n\n byId.set(key, existing);\n }\n\n const totals = new Map<string, ToolUsageDelta>();\n for (const ev of toolEvents) {\n if (ev.phase !== \"call\" || !ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const outcome = byId.get(key);\n const next = totals.get(ev.name) ?? {\n name: ev.name,\n calls: 0,\n successes: 0,\n errors: 0,\n used: 0,\n };\n next.calls += 1;\n if (outcome?.successful) next.successes += 1;\n else next.errors += 1;\n if (outcome?.used) next.used += 1;\n totals.set(ev.name, next);\n }\n\n return [...totals.values()];\n}\n\nfunction payloadLooksUsed(payload: unknown, assistantTerms: Set<string>): boolean {\n if (assistantTerms.size === 0) return false;\n const candidates = extractPayloadTerms(payload);\n if (candidates.length === 0) return false;\n\n let matched = 0;\n for (const term of candidates) {\n if (assistantTerms.has(term)) matched += 1;\n if (matched >= 2) return true;\n }\n return false;\n}\n\nfunction extractPayloadTerms(payload: unknown): string[] {\n const raw = stringifyPayload(payload);\n if (!raw) return [];\n const unique = new Set<string>();\n for (const token of raw.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n if (/^\\d+$/.test(token) && token.length < 6) continue;\n unique.add(token);\n if (unique.size >= 24) break;\n }\n return [...unique];\n}\n\nfunction stringifyPayload(payload: unknown): string {\n if (typeof payload === \"string\") return payload;\n try {\n return JSON.stringify(payload);\n } catch {\n return \"\";\n }\n}\n\nfunction normalizeText(text: string): Set<string> {\n const out = new Set<string>();\n for (const token of text.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n out.add(token);\n }\n return out;\n}\n\nfunction isErrorPayload(payload: unknown): boolean {\n if (typeof payload === \"string\") return /\\berror\\b|\\bfailed\\b|\\bexception\\b/i.test(payload);\n if (!payload || typeof payload !== \"object\") return false;\n if (\"error\" in payload || \"errors\" in payload) return true;\n const status = \"status\" in payload ? (payload as { status?: unknown }).status : undefined;\n if (typeof status === \"string\" && /error|failed/i.test(status)) return true;\n return false;\n}\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}","// Local file store for binary artifacts produced by tools (generated images,\n// downloads, etc.). Files live under ~/.jarela/files/ and are served by\n// GET /api/v1/files/[name]. The tool returns a relative URL the chat\n// renderer can embed as <img src=\"/api/v1/files/...\">.\n\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\n\nexport const FILES_DIR = join(getDataDir(), \"files\");\n\nmkdirSync(FILES_DIR, { recursive: true });\n\n// Name must be a single path segment with no separators or \"..\". Callers\n// generate names from randomUUID() so this is mostly defense-in-depth.\nconst SAFE_NAME = /^[A-Za-z0-9._-]+$/;\n\nexport function isSafeFileName(name: string): boolean {\n return SAFE_NAME.test(name) && !name.includes(\"..\");\n}\n\nexport function fileAbsPath(name: string): string | null {\n if (!isSafeFileName(name)) return null;\n return join(FILES_DIR, name);\n}\n\nexport function writeBinaryFile(name: string, data: Buffer): string {\n if (!isSafeFileName(name)) throw new Error(`unsafe file name: ${name}`);\n const p = join(FILES_DIR, name);\n writeFileSync(p, data);\n return p;\n}\n","// Built-in tool category toggles.\n//\n// A category is \"enabled\" unless an explicit row in `builtin_tool_categories`\n// says otherwise. Default-enabled semantics mean upgrading installs keep\n// every category working with zero migration work.\n//\n// Disabled categories are filtered at three layers:\n// - GET /api/v1/tools (so the agent editor never offers them as permissions)\n// - getAllTools / getAllToolsAsync (so the agent runtime can't see them)\n// - executeTool (defense in depth, blocks stale agent configs)\n\nimport { getDb } from \"@/lib/db\";\nimport type { BuiltinCategory } from \"@/lib/tools/registry\";\n\ninterface Row {\n category: string;\n enabled: number;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function isCategoryEnabled(category: BuiltinCategory): boolean {\n const row = getDb()\n .prepare(\"SELECT enabled FROM builtin_tool_categories WHERE category=?\")\n .get(category) as { enabled: number } | undefined;\n return row ? row.enabled === 1 : true;\n}\n\nexport function disabledCategories(): Set<BuiltinCategory> {\n const rows = getDb()\n .prepare(\"SELECT category FROM builtin_tool_categories WHERE enabled=0\")\n .all() as unknown as Array<{ category: string }>;\n return new Set(rows.map((r) => r.category as BuiltinCategory));\n}\n\nexport function listCategoryStates(): Array<{ category: string; enabled: boolean; updated_at: string | null }> {\n const rows = getDb()\n .prepare(\"SELECT category, enabled, updated_at FROM builtin_tool_categories\")\n .all() as unknown as Row[];\n return rows.map((r) => ({\n category: r.category,\n enabled: r.enabled === 1,\n updated_at: r.updated_at,\n }));\n}\n\nexport function setCategoryEnabled(category: BuiltinCategory, enabled: boolean): void {\n getDb()\n .prepare(\n `INSERT INTO builtin_tool_categories (category, enabled, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(category) DO UPDATE SET enabled=excluded.enabled, updated_at=excluded.updated_at`,\n )\n .run(category, enabled ? 1 : 0, now());\n}\n","import { getIntegrationRaw } from \"@/lib/stores/integrations\";\n\nexport function timeoutSignal(ms: number): AbortSignal {\n const c = new AbortController();\n setTimeout(() => c.abort(new Error(`timeout after ${ms}ms`)), ms).unref?.();\n return c.signal;\n}\n\nexport function resolveGoogleApiKey(): string | null {\n const raw = getIntegrationRaw(\"google\");\n const fromStore = raw?.api_key?.trim();\n if (fromStore) return fromStore;\n return (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || \"\").trim() || null;\n}\n","import { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\n// Persona presets (see ADR — to be written). Drives the Credentials\n// panel's category filter so the agent surface stays calm.\n//\n// home → llm + mail + calendar + chat\n// work → everything except chat-only (everyone uses work mail/cal/jira)\n// dev → everything (including infrastructure)\n// custom → no filter, show everything\n//\n// NULL in the DB also means \"no filter\".\nexport type UserPreset = \"home\" | \"work\" | \"dev\" | \"custom\";\n\nexport function isUserPreset(v: unknown): v is UserPreset {\n return v === \"home\" || v === \"work\" || v === \"dev\" || v === \"custom\";\n}\n\nexport interface UserProfileRow {\n id: string;\n name: string;\n icon: string | null;\n about: string;\n created_at: string;\n updated_at: string;\n // ── Geolocation (opt-in) ─────────────────────────────────────────────\n // Populated by the client (navigator.geolocation) only when\n // location_consent === 1. All five fields are null when sharing is off.\n location_lat: number | null;\n location_lng: number | null;\n location_accuracy_m: number | null;\n location_label: string | null;\n location_updated_at: string | null;\n location_consent: number; // 0 | 1\n // ── Persona ──────────────────────────────────────────────────────────\n preset: UserPreset | null;\n}\n\nexport function getUserProfile(): UserProfileRow | null {\n return (\n (getDb()\n .prepare(\"SELECT * FROM user_profile WHERE id='me'\")\n .get() as unknown as UserProfileRow) ?? null\n );\n}\n\nexport function upsertUserProfile(\n name: string,\n icon: string | null,\n about: string,\n): UserProfileRow {\n const t = now();\n const db = getDb();\n const existing = getUserProfile();\n const created_at = existing?.created_at ?? t;\n // Preserve location columns on profile edit — we only update them via the\n // dedicated location endpoints.\n db.prepare(\n `INSERT INTO user_profile (id, name, icon, about, created_at, updated_at)\n VALUES ('me', ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n name=excluded.name, icon=excluded.icon, about=excluded.about,\n updated_at=excluded.updated_at`,\n ).run(name, icon ?? null, about, created_at, t);\n return getUserProfile()!;\n}\n\nexport function setLocationConsent(consent: boolean): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists.\n const existing = getUserProfile();\n if (!existing) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET location_consent=?, updated_at=?\n ${consent ? \"\" : \", location_lat=NULL, location_lng=NULL, location_accuracy_m=NULL, location_label=NULL, location_updated_at=NULL\"}\n WHERE id='me'`,\n ).run(consent ? 1 : 0, t);\n return getUserProfile()!;\n}\n\nexport function updateUserLocation(input: {\n lat: number;\n lng: number;\n accuracy_m?: number | null;\n label?: string | null;\n}): UserProfileRow {\n const existing = getUserProfile();\n if (!existing || existing.location_consent !== 1) {\n throw new Error(\"location sharing is not enabled\");\n }\n const t = now();\n getDb()\n .prepare(\n `UPDATE user_profile SET\n location_lat=?, location_lng=?, location_accuracy_m=?, location_label=?,\n location_updated_at=?, updated_at=?\n WHERE id='me'`,\n )\n .run(\n input.lat,\n input.lng,\n input.accuracy_m ?? null,\n input.label ?? null,\n t,\n t,\n );\n return getUserProfile()!;\n}\n\nexport function setUserPreset(preset: UserPreset | null): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists so the UPDATE has something to touch.\n if (!getUserProfile()) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET preset=?, updated_at=? WHERE id='me'`,\n ).run(preset, t);\n return getUserProfile()!;\n}\n","// Central runtime configuration, resolved from environment variables.\n//\n// All operational knobs (port, host, data dir, timeouts, agent limits) flow\n// through this module so there is exactly one place documenting which env\n// vars Jarela respects and what the defaults are. Code MUST NOT read these\n// `process.env` keys directly — import `config` instead.\n//\n// Resolution order for every entry: explicit JARELA_* var → legacy/standard\n// var (where one exists, e.g. PORT/HOSTNAME for Next.js compatibility) →\n// hard-coded default.\n//\n// Values are resolved lazily on first read and cached. Tests that mutate\n// `process.env` must call `resetConfigCache()` between cases.\n\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { getAppName, getAppDescription, getAppIssueUrl } from \"./app-config\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface JarelaConfig {\n /** TCP port the Next.js server binds to. */\n readonly port: number;\n /** Hostname/interface the server binds to (loopback by default). */\n readonly hostname: string;\n /** Absolute path to the SQLite + files data directory. */\n readonly dataDir: string;\n /** Absolute path to the external-tools directory (CJS/TS plugins). */\n readonly toolsDir: string;\n /** Max LangGraph node visits per agent run before erroring out. */\n readonly recursionLimit: number;\n /** Per-request timeout for Gemini voice (TTS/STT) calls, ms. */\n readonly voiceTimeoutMs: number;\n /** Per-request timeout for Gemini image-generation calls, ms. */\n readonly imageTimeoutMs: number;\n /** User-visible app name. Forks override via NEXT_PUBLIC_APP_NAME. */\n readonly appName: string;\n /** Meta description for the HTML <head>. NEXT_PUBLIC_APP_DESCRIPTION. */\n readonly appDescription: string;\n /** \"Report a bug\" target — GitHub issues URL. NEXT_PUBLIC_APP_ISSUE_URL. */\n readonly issueUrl: string;\n}\n\nconst DEFAULTS = {\n port: 4312,\n hostname: \"127.0.0.1\",\n recursionLimit: 200,\n voiceTimeoutMs: 60_000,\n imageTimeoutMs: 60_000,\n} as const;\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\nfunction parsePort(value: string | undefined, fallback: number): number {\n const n = parsePositiveInt(value, fallback);\n return n >= 1 && n <= 65_535 ? n : fallback;\n}\n\nlet cached: JarelaConfig | null = null;\n\nfunction expandHome(p: string): string {\n return p.startsWith(\"~\") ? p.replace(/^~/, homedir()) : p;\n}\n\nexport function getConfig(): JarelaConfig {\n if (cached) return cached;\n const env = process.env;\n const dataDir = getDataDir();\n cached = {\n port: parsePort(env.JARELA_PORT ?? env.PORT, DEFAULTS.port),\n hostname: (env.JARELA_HOSTNAME ?? env.HOSTNAME ?? DEFAULTS.hostname).trim() || DEFAULTS.hostname,\n dataDir,\n toolsDir: env.JARELA_TOOLS_DIR ? expandHome(env.JARELA_TOOLS_DIR) : join(dataDir, \"tools\"),\n recursionLimit: parsePositiveInt(env.JARELA_RECURSION_LIMIT, DEFAULTS.recursionLimit),\n voiceTimeoutMs: parsePositiveInt(env.JARELA_VOICE_TIMEOUT_MS, DEFAULTS.voiceTimeoutMs),\n imageTimeoutMs: parsePositiveInt(env.JARELA_IMAGE_TIMEOUT_MS, DEFAULTS.imageTimeoutMs),\n appName: getAppName(),\n appDescription: getAppDescription(),\n issueUrl: getAppIssueUrl(),\n };\n return cached;\n}\n\n/** Test-only: drop the memoised config so the next read picks up env edits. */\nexport function resetConfigCache(): void {\n cached = null;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { getDb } from \"@/lib/db\";\nimport {\n resolveReaction,\n validateReactionScript,\n normaliseReactionScriptArgs,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\nexport type ScheduleKind = \"once\" | \"cron\";\n\nexport interface ScheduledTaskRow {\n id: string;\n agent_id: string;\n prompt: string;\n description: string | null;\n kind: ScheduleKind;\n schedule: string; // ISO timestamp for \"once\", cron expression for \"cron\"\n next_run_at: string; // ISO\n last_run_at: string | null;\n last_error: string | null;\n enabled: number; // 0 | 1\n // When 1 the scheduler wraps the prompt with a \"reply only if material\"\n // directive and a NO_REPLY sentinel; NO_REPLY/empty assistant turns are\n // dropped. Visibility is handled at the UI layer via the chat-panel\n // category-filter toolbar (firings are tagged `scheduled_task`).\n silent: number; // 0 | 1\n // ADR-0032 — discriminated reaction. 'agent_prompt' (default) runs the\n // agent with `prompt`; 'script' runs a registered reaction.* script\n // with no LLM round-trip. The other branch's columns are forced NULL\n // by the store layer (see resolveReaction in reaction-shared.ts).\n reaction_kind: ReactionKind;\n reaction_script: string | null;\n reaction_script_args: string | null; // JSON-encoded record\n created_at: string;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function computeNextRun(kind: ScheduleKind, schedule: string, after: Date = new Date()): Date {\n if (kind === \"once\") {\n const ts = new Date(schedule);\n if (Number.isNaN(ts.getTime())) throw new Error(`Invalid ISO timestamp: ${schedule}`);\n return ts;\n }\n const it = CronExpressionParser.parse(schedule, { currentDate: after });\n return it.next().toDate();\n}\n\nexport interface CreateScheduledTaskInput {\n agent_id: string;\n // Required for kind='agent_prompt'; ignored (stored as \"\") for kind='script'.\n prompt?: string;\n description?: string;\n kind: ScheduleKind;\n schedule: string;\n silent?: boolean;\n // ADR-0032 — discriminated reaction. Same shape as the watcher store.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createScheduledTask(input: CreateScheduledTaskInput): ScheduledTaskRow {\n const id = randomUUID();\n const t = now();\n const next = computeNextRun(input.kind, input.schedule).toISOString();\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction({\n reaction_kind: input.reaction_kind,\n // Scheduled tasks don't carry a reaction_prompt override — the firing\n // prompt is `input.prompt` itself when kind='agent_prompt'. Pass null\n // so resolveReaction normalises it consistently.\n reaction_prompt: null,\n reaction_script: input.reaction_script,\n reaction_script_args: input.reaction_script_args,\n });\n if (reaction.kind === \"agent_prompt\" && !input.prompt) {\n throw new Error(\"prompt is required when reaction_kind='agent_prompt'\");\n }\n // For kind='script' we still need a non-NULL value in the prompt column\n // (NOT NULL constraint stays). Empty string is the agreed sentinel; the\n // discriminator decides whether prompt is read.\n const prompt = reaction.kind === \"script\" ? (input.prompt ?? \"\") : input.prompt!;\n getDb()\n .prepare(\n `INSERT INTO scheduled_tasks\n (id, agent_id, prompt, description, kind, schedule, next_run_at, last_run_at, last_error, enabled, silent,\n reaction_kind, reaction_script, reaction_script_args, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, 1, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, prompt, input.description ?? null, input.kind, input.schedule, next, silent,\n reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n prompt,\n description: input.description ?? null,\n kind: input.kind,\n schedule: input.schedule,\n next_run_at: next,\n last_run_at: null,\n last_error: null,\n enabled: 1,\n silent,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listScheduledTasks(agentId?: string): ScheduledTaskRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM scheduled_tasks WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM scheduled_tasks ORDER BY next_run_at ASC\").all();\n return rows as unknown as ScheduledTaskRow[];\n}\n\nexport function getScheduledTask(id: string): ScheduledTaskRow | null {\n const row = getDb().prepare(\"SELECT * FROM scheduled_tasks WHERE id=?\").get(id);\n return (row as ScheduledTaskRow | undefined) ?? null;\n}\n\nexport function getDueTasks(asOf: Date = new Date()): ScheduledTaskRow[] {\n return getDb()\n .prepare(\"SELECT * FROM scheduled_tasks WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as ScheduledTaskRow[];\n}\n\nexport function deleteScheduledTask(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateScheduledTaskInput {\n prompt?: string;\n description?: string | null;\n kind?: ScheduleKind;\n schedule?: string;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0032 — same discriminated-union semantics as updateWatcher:\n // explicit reaction_kind does a full replace; absent kind allows\n // kind-preserving patch of the matching branch's fields.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\n// Patch an existing task. Only the supplied fields are touched; the rest\n// stay as-is. Changing `kind` or `schedule` recomputes `next_run_at`\n// against the new value so the scheduler picks the right next firing.\nexport function updateScheduledTask(id: string, patch: UpdateScheduledTaskInput): ScheduledTaskRow | null {\n const existing = getScheduledTask(id);\n if (!existing) return null;\n const nextKind = patch.kind ?? existing.kind;\n const nextSchedule = patch.schedule ?? existing.schedule;\n const t = now();\n // If the schedule (kind or expression) changed, validate + recompute. If\n // it didn't change we keep the existing next_run_at so a simple prompt\n // edit doesn't accidentally re-arm an already-overdue task.\n let nextRunAt = existing.next_run_at;\n if (patch.kind !== undefined || patch.schedule !== undefined) {\n nextRunAt = computeNextRun(nextKind, nextSchedule, new Date(t)).toISOString();\n }\n\n // Compute the reaction columns. Two cases mirroring updateWatcher:\n // 1. patch.reaction_kind is set → fully resolve as a new reaction.\n // 2. patch.reaction_kind is absent → keep existing kind, allow the\n // matching branch's field to be patched.\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: null,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n reaction = { kind: \"agent_prompt\", prompt: null, script: null, scriptArgs: null };\n }\n\n // Prompt column constraint: must be non-NULL. For kind='script' we keep\n // whatever was there (or \"\" if switching from script with empty existing).\n const nextPrompt = patch.prompt !== undefined\n ? patch.prompt\n : (reaction.kind === \"agent_prompt\" && existing.reaction_kind === \"script\"\n ? (existing.prompt || \"\")\n : existing.prompt);\n\n getDb()\n .prepare(\n `UPDATE scheduled_tasks SET\n prompt=?, description=?, kind=?, schedule=?, next_run_at=?, enabled=?, silent=?, last_error=?,\n reaction_kind=?, reaction_script=?, reaction_script_args=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n nextPrompt,\n patch.description === undefined ? existing.description : patch.description,\n nextKind,\n nextSchedule,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n // Clear the last error whenever the user touches the task — they've\n // presumably fixed whatever caused it.\n null,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getScheduledTask(id);\n}\n\nexport function markTaskRan(id: string, kind: ScheduleKind, schedule: string, error?: string): void {\n const t = now();\n if (kind === \"once\") {\n // One-shot tasks delete themselves after firing.\n getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return;\n }\n let nextRun: string;\n try {\n nextRun = computeNextRun(kind, schedule, new Date(t)).toISOString();\n } catch (e) {\n // Invalid cron — disable the task to avoid a tight error loop.\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET enabled=0, last_run_at=?, last_error=?, updated_at=? WHERE id=?\")\n .run(t, `Cron parse failed: ${e instanceof Error ? e.message : String(e)}`, t, id);\n return;\n }\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?\")\n .run(t, error ?? null, nextRun, t, id);\n}\n","import { BaseChatModel, type BaseChatModelCallOptions } from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n type BaseMessage,\n isAIMessage,\n isHumanMessage,\n isSystemMessage,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatGeneration, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport type { ModelProvider, ProviderParams } from \"@/lib/providers/types\";\nimport type { ContentPart, InvokeMessage, OpenAITool, ToolParamSchema } from \"@/lib/tools/types\";\n\ninterface Fields {\n provider: ModelProvider;\n modelId: string;\n params: ProviderParams;\n boundTools?: StructuredToolInterface[];\n}\n\nexport class JarelaChatModel extends BaseChatModel {\n lc_namespace = [\"jarela\", \"chat_models\"];\n lc_serializable = false;\n\n private _provider: ModelProvider;\n private _modelId: string;\n private _params: ProviderParams;\n private _boundTools: StructuredToolInterface[];\n\n constructor(fields: Fields) {\n super({});\n this._provider = fields.provider;\n this._modelId = fields.modelId;\n this._params = fields.params;\n this._boundTools = fields.boundTools ?? [];\n }\n\n _llmType(): string {\n return `jarela_${this._provider?.name ?? \"chat\"}`;\n }\n\n // createReactAgent calls bindTools() to attach the tool list before streaming.\n bindTools(tools: StructuredToolInterface[], _kwargs?: Partial<BaseChatModelCallOptions>): Runnable {\n return new JarelaChatModel({\n provider: this._provider,\n modelId: this._modelId,\n params: this._params,\n boundTools: tools,\n });\n }\n\n private _convertedTools(): OpenAITool[] {\n return this._boundTools.flatMap((t) => {\n try {\n const oai = convertToOpenAITool(t) as { function?: { name?: string; description?: string; parameters: unknown } };\n if (!oai?.function?.name) return [];\n return [{\n type: \"function\" as const,\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n }];\n } catch {\n return [];\n }\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatResult> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n // Streaming path — assemble chunks into a final message.\n if (this._provider.streamInvoke && openaiTools.length > 0) {\n const finalChunk = await this._streamToFinalChunk(invokeMessages, openaiTools, runManager);\n const gen: ChatGeneration = {\n message: aiMessageFromChunk(finalChunk.message as AIMessageChunk),\n text: typeof finalChunk.message.content === \"string\" ? finalChunk.message.content : \"\",\n };\n return { generations: [gen] };\n }\n\n if (this._provider.invoke && openaiTools.length > 0) {\n const result = await this._provider.invoke(this._modelId, invokeMessages, this._params, openaiTools);\n const aiMsg = new AIMessage({\n content: result.text ?? \"\",\n tool_calls: result.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.arguments,\n type: \"tool_call\" as const,\n })),\n });\n const gen: ChatGeneration = { message: aiMsg, text: result.text ?? \"\" };\n return { generations: [gen] };\n }\n\n const providerMessages = invokeMessages\n .filter((m) => m.role !== \"tool\")\n .map((m) => ({ role: m.role as \"user\" | \"assistant\" | \"system\", content: m.content }));\n const { stream } = await this._provider.chat(this._modelId, providerMessages, this._params);\n let text = \"\";\n for await (const chunk of stream) { text += chunk; }\n const gen: ChatGeneration = { message: new AIMessage(text), text };\n return { generations: [gen] };\n }\n\n private async _streamToFinalChunk(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatGenerationChunk> {\n let acc: ChatGenerationChunk | null = null;\n for await (const chunk of this._streamFromProvider(invokeMessages, openaiTools, runManager)) {\n acc = acc ? acc.concat(chunk) : chunk;\n }\n return acc ?? new ChatGenerationChunk({ message: new AIMessageChunk({ content: \"\" }), text: \"\" });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n if (!this._provider.streamInvoke) {\n const result = await this._generate(messages, _options, runManager);\n const msg = result.generations[0].message as AIMessage;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: msg.content,\n tool_call_chunks: msg.tool_calls?.map((tc, i) => ({\n index: i,\n id: tc.id,\n name: tc.name,\n args: JSON.stringify(tc.args),\n type: \"tool_call_chunk\" as const,\n })) ?? [],\n }),\n text: typeof msg.content === \"string\" ? msg.content : \"\",\n });\n return;\n }\n\n yield* this._streamFromProvider(invokeMessages, openaiTools, runManager);\n }\n\n private async *_streamFromProvider(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n if (!this._provider.streamInvoke) return;\n let emittedAny = false;\n let stopReason: \"stop\" | \"tool_use\" | \"length\" | undefined;\n for await (const event of this._provider.streamInvoke(this._modelId, invokeMessages, this._params, openaiTools)) {\n if (event.type === \"text\") {\n emittedAny = true;\n await runManager?.handleLLMNewToken(event.delta);\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({ content: event.delta }),\n text: event.delta,\n });\n } else if (event.type === \"thinking\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { reasoning_content: event.delta },\n }),\n text: \"\",\n });\n } else if (event.type === \"tool_call_chunk\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n tool_call_chunks: [{\n index: event.index,\n id: event.id,\n name: event.name,\n args: event.args_delta,\n type: \"tool_call_chunk\" as const,\n }],\n }),\n text: \"\",\n });\n } else if (event.type === \"stop\") {\n stopReason = event.reason;\n }\n }\n // Provider ended the stream without emitting any text, thinking, or tool\n // call chunks. Without this guard, LangChain's BaseChatModel consumer sees\n // zero ChatGenerationChunks and throws \"Received empty response from chat\n // model call.\" — opaque to users. Translate the underlying stop reason\n // into something actionable.\n if (!emittedAny) {\n if (stopReason === \"length\") {\n throw new Error(\n \"Model returned no content before hitting max_tokens. \" +\n \"Reasoning likely consumed the entire token budget — raise max_tokens \" +\n \"(or the thinking budget) in the model config and retry.\",\n );\n }\n // stopReason \"stop\" with no content can mean a content-filter refusal\n // (OpenAI/Azure map content_filter -> \"stop\" in our type), or a model\n // that legitimately decided to emit nothing on this turn. Yield one\n // empty chunk so LangChain has something to aggregate; the agent loop\n // will record an empty AIMessage and the UI will fall through to `done`.\n console.warn(\n `[jarela-chat-model] Provider ${this._provider.name} ended stream with no content (stopReason=${stopReason ?? \"<none>\"}).`,\n );\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: stopReason ? { empty_stream_reason: stopReason } : {},\n }),\n text: \"\",\n });\n return;\n }\n // Mid-stream truncation: provider produced content then stopped because of\n // max_tokens (or a length-equivalent). The aggregated message is partial\n // (e.g. a table cut off mid-row). Tag the final chunk with stop_reason so\n // the agent layer can surface a \"your output was truncated\" warning to\n // the user — otherwise they see a cut-off response with no explanation.\n if (stopReason === \"length\") {\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { stop_reason: \"length\" },\n }),\n text: \"\",\n });\n }\n }\n}\n\nfunction aiMessageFromChunk(chunk: AIMessageChunk): AIMessage {\n return new AIMessage({\n content: chunk.content,\n tool_calls: chunk.tool_calls,\n invalid_tool_calls: chunk.invalid_tool_calls,\n additional_kwargs: chunk.additional_kwargs,\n });\n}\n\n// LangChain's BaseMessage.content can be a string or a content-block array\n// (text, image_url, etc. — used for multi-modal input). Preserve it through\n// to InvokeMessage so the provider routes can translate properly. Stringifying\n// destroys image attachments — `String([{...}, {...}])` becomes \"[object Object],...\"\nfunction lcContentToInvoke(content: BaseMessage[\"content\"]): string | ContentPart[] {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: ContentPart[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push({ type: \"text\", text: block });\n continue;\n }\n if (!block || typeof block !== \"object\") continue;\n const b = block as Record<string, unknown>;\n if (b.type === \"text\" && typeof b.text === \"string\") {\n parts.push({ type: \"text\", text: b.text });\n } else if (b.type === \"image_url\") {\n // OpenAI-style: { type: \"image_url\", image_url: { url: \"data:image/png;base64,...\" } }\n const url = (b.image_url as { url?: string } | string | undefined);\n const dataUrl = typeof url === \"string\" ? url : url?.url;\n if (dataUrl?.startsWith(\"data:\")) {\n const m = /^data:([^;]+);base64,(.+)$/.exec(dataUrl);\n if (m) parts.push({ type: \"image\", media_type: m[1], data: m[2] });\n }\n } else if (b.type === \"image\") {\n // Anthropic-style: { type: \"image\", source: { type: \"base64\", media_type, data } }\n const src = b.source as { media_type?: string; data?: string } | undefined;\n if (src?.media_type && src.data) {\n parts.push({ type: \"image\", media_type: src.media_type, data: src.data });\n }\n }\n }\n // If we ended up with only text blocks, collapse to a string so providers\n // that don't need multi-modal handling don't have to special-case.\n if (parts.every((p) => p.type === \"text\")) {\n return parts.map((p) => (p as { text: string }).text).join(\"\\n\");\n }\n return parts;\n}\n\nfunction toInvokeMessages(messages: BaseMessage[]): InvokeMessage[] {\n return messages.map((m): InvokeMessage => {\n if (isHumanMessage(m)) {\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n }\n if (isSystemMessage(m)) {\n return { role: \"system\", content: lcContentToInvoke(m.content) };\n }\n if (isAIMessage(m)) {\n const ai = m as AIMessage;\n const invokeMsg: InvokeMessage = {\n role: \"assistant\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n };\n if (ai.tool_calls?.length) {\n invokeMsg.tool_calls = ai.tool_calls.map((tc) => ({\n id: tc.id ?? \"\",\n type: \"function\" as const,\n function: { name: tc.name, arguments: JSON.stringify(tc.args) },\n }));\n }\n // DeepSeek thinking-mode: propagate the reasoning trace back so the\n // provider can echo it on follow-up turns (required by their API).\n const reasoning = ai.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n invokeMsg.reasoning_content = reasoning;\n }\n return invokeMsg;\n }\n if (isToolMessage(m)) {\n return {\n role: \"tool\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n tool_call_id: m.tool_call_id,\n };\n }\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n });\n}\n","import { BaseStore } from \"@langchain/langgraph-checkpoint\";\nimport type { Operation, OperationResults, Item } from \"@langchain/langgraph-checkpoint\";\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nexport class SqliteMemoryStore extends BaseStore {\n async batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>> {\n const results = await Promise.all(\n operations.map(async (op): Promise<Item | null | Item[] | void> => {\n // GetOperation: { namespace, key } — no \"value\" or \"namespacePrefix\"\n if (\"key\" in op && \"namespace\" in op && !(\"value\" in op) && !(\"namespacePrefix\" in op)) {\n const ns = op.namespace.join(\"/\");\n const row = getMemory(ns, op.key);\n if (!row) return null;\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(row.value) as Record<string, unknown>;\n } catch {\n value = { _raw: row.value };\n }\n return {\n namespace: op.namespace,\n key: op.key,\n value,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n };\n }\n\n // PutOperation: { namespace, key, value }\n if (\"value\" in op && \"namespace\" in op && \"key\" in op) {\n const ns = op.namespace.join(\"/\");\n if (op.value === null) {\n deleteMemory(ns, op.key);\n } else {\n putMemory(ns, op.key, op.value);\n }\n return undefined;\n }\n\n // SearchOperation: { namespacePrefix, ... }\n if (\"namespacePrefix\" in op) {\n const prefix = (op.namespacePrefix as string[]).join(\"/\");\n const limit = \"limit\" in op && typeof op.limit === \"number\" ? op.limit : 10;\n const rows = listMemory(prefix || undefined, undefined, limit);\n return rows.map((r) => {\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(r.value) as Record<string, unknown>;\n } catch {\n value = { _raw: r.value };\n }\n return {\n namespace: r.namespace.split(\"/\"),\n key: r.key,\n value,\n createdAt: new Date(r.created_at),\n updatedAt: new Date(r.updated_at),\n };\n });\n }\n\n return undefined;\n }),\n );\n return results as unknown as OperationResults<Op>;\n }\n}\n","import { DatabaseSync, type StatementSync } from \"node:sqlite\";\nimport { type RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseCheckpointSaver,\n TASKS,\n copyCheckpoint,\n maxChannelVersion,\n type Checkpoint,\n type CheckpointListOptions,\n type CheckpointMetadata,\n type CheckpointTuple,\n type PendingWrite,\n type SerializerProtocol,\n} from \"@langchain/langgraph-checkpoint\";\n\n// In-tree LangGraph checkpoint saver backed by node:sqlite.\n//\n// Schema-compatible drop-in replacement for SqliteSaver from\n// @langchain/langgraph-checkpoint-sqlite. The DDL is byte-identical so an\n// existing checkpoints.db keeps working without migration.\n\nconst VALID_FILTER_KEYS: readonly string[] = [\"source\", \"step\", \"parents\"];\n\ntype Row = Record<string, unknown>;\n\nfunction buildLatestSelect(includeCheckpointId: boolean): string {\n return `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\n WHERE thread_id = ? AND checkpoint_ns = ? ${\n includeCheckpointId\n ? \"AND checkpoint_id = ?\"\n : \"ORDER BY checkpoint_id DESC LIMIT 1\"\n }`;\n}\n\n// node:sqlite rejects `undefined` parameter binds; coerce to null.\nfunction nv<T>(v: T | undefined | null): T | null {\n return v === undefined ? null : (v as T | null);\n}\n\nexport class NodeSqliteSaver extends BaseCheckpointSaver {\n db: DatabaseSync;\n\n protected isSetup = false;\n protected withoutCheckpoint!: StatementSync;\n protected withCheckpoint!: StatementSync;\n\n constructor(db: DatabaseSync, serde?: SerializerProtocol) {\n super(serde);\n this.db = db;\n }\n\n static fromConnString(connStringOrLocalPath: string): NodeSqliteSaver {\n return new NodeSqliteSaver(new DatabaseSync(connStringOrLocalPath));\n }\n\n protected setup(): void {\n if (this.isSetup) return;\n this.db.exec(\"PRAGMA journal_mode=WAL\");\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS checkpoints (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n parent_checkpoint_id TEXT,\n type TEXT,\n checkpoint BLOB,\n metadata BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)\n);`);\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS writes (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n idx INTEGER NOT NULL,\n channel TEXT NOT NULL,\n type TEXT,\n value BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)\n);`);\n this.withoutCheckpoint = this.db.prepare(buildLatestSelect(false));\n this.withCheckpoint = this.db.prepare(buildLatestSelect(true));\n this.isSetup = true;\n }\n\n protected txn<T>(fn: () => T): T {\n this.db.exec(\"BEGIN\");\n try {\n const result = fn();\n this.db.exec(\"COMMIT\");\n return result;\n } catch (err) {\n try {\n this.db.exec(\"ROLLBACK\");\n } catch {\n // ignore rollback failure; surface the original error\n }\n throw err;\n }\n }\n\n private async decodeRowState(row: Row): Promise<{\n pendingWrites: [string, string, unknown][];\n checkpoint: Checkpoint;\n metadata: CheckpointMetadata;\n }> {\n const pendingWrites = await Promise.all(\n JSON.parse(String(row.pending_writes ?? \"[]\")).map(\n async (write: { task_id: string; channel: string; type?: string; value?: string }) => {\n return [\n write.task_id,\n write.channel,\n await this.serde.loadsTyped(write.type ?? \"json\", write.value ?? \"\"),\n ] as [string, string, unknown];\n },\n ),\n );\n\n const checkpoint = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.checkpoint as Uint8Array | string,\n )) as Checkpoint;\n\n if (checkpoint.v < 4 && row.parent_checkpoint_id != null) {\n await this.migratePendingSends(\n checkpoint,\n row.thread_id as string,\n row.parent_checkpoint_id as string,\n );\n }\n\n const metadata = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.metadata as Uint8Array | string,\n )) as CheckpointMetadata;\n\n return { pendingWrites, checkpoint, metadata };\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n this.setup();\n const { thread_id, checkpoint_ns = \"\", checkpoint_id } =\n config.configurable ?? {};\n const args: unknown[] = [nv(thread_id), checkpoint_ns];\n if (checkpoint_id) args.push(checkpoint_id);\n const stmt = checkpoint_id ? this.withCheckpoint : this.withoutCheckpoint;\n const row = stmt.get(...(args as never[])) as Row | undefined;\n if (row === undefined) return undefined;\n\n let finalConfig = config;\n if (!checkpoint_id) {\n finalConfig = {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n };\n }\n if (\n finalConfig.configurable?.thread_id === undefined ||\n finalConfig.configurable?.checkpoint_id === undefined\n ) {\n throw new Error(\"Missing thread_id or checkpoint_id\");\n }\n\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n\n return {\n checkpoint,\n config: finalConfig,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n\n async *list(\n config: RunnableConfig,\n options?: CheckpointListOptions,\n ): AsyncGenerator<CheckpointTuple> {\n const { limit, before, filter } = options ?? {};\n this.setup();\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns;\n\n let sql = `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\\n`;\n\n const whereClause: string[] = [];\n if (thread_id) whereClause.push(\"thread_id = ?\");\n if (checkpoint_ns !== undefined && checkpoint_ns !== null) {\n whereClause.push(\"checkpoint_ns = ?\");\n }\n if (before?.configurable?.checkpoint_id !== undefined) {\n whereClause.push(\"checkpoint_id < ?\");\n }\n\n const sanitizedFilter = Object.fromEntries(\n Object.entries(filter ?? {}).filter(\n ([key, value]) => value !== undefined && VALID_FILTER_KEYS.includes(key),\n ),\n );\n whereClause.push(\n ...Object.entries(sanitizedFilter).map(\n ([key]) => `jsonb(CAST(metadata AS TEXT))->'$.${key}' = ?`,\n ),\n );\n if (whereClause.length > 0) sql += `WHERE\\n ${whereClause.join(\" AND\\n \")}\\n`;\n sql += \"\\nORDER BY checkpoint_id DESC\";\n if (limit) sql += ` LIMIT ${parseInt(String(limit), 10)}`;\n\n const args: unknown[] = [\n thread_id,\n checkpoint_ns,\n before?.configurable?.checkpoint_id,\n ...Object.values(sanitizedFilter).map((value) => JSON.stringify(value)),\n ].filter((value) => value !== undefined && value !== null);\n\n const rows = this.db.prepare(sql).all(...(args as never[])) as Row[];\n for (const row of rows) {\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n yield {\n config: {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n },\n checkpoint,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n ): Promise<RunnableConfig> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n const thread_id = config.configurable?.thread_id as string | undefined;\n const checkpoint_ns = (config.configurable?.checkpoint_ns ?? \"\") as string;\n const parent_checkpoint_id = config.configurable?.checkpoint_id as\n | string\n | undefined;\n if (!thread_id) {\n throw new Error(`Missing \"thread_id\" field in passed \"config.configurable\".`);\n }\n const preparedCheckpoint = copyCheckpoint(checkpoint);\n const [\n [type1, serializedCheckpoint],\n [type2, serializedMetadata],\n ] = await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n if (type1 !== type2) {\n throw new Error(\n \"Failed to serialized checkpoint and metadata to the same type.\",\n );\n }\n this.db\n .prepare(\n `INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n thread_id,\n checkpoint_ns,\n checkpoint.id,\n nv(parent_checkpoint_id),\n type1,\n serializedCheckpoint as never,\n serializedMetadata as never,\n );\n return {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string,\n ): Promise<void> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n if (!config.configurable?.thread_id) {\n throw new Error(\"Missing thread_id field in config.configurable.\");\n }\n if (!config.configurable?.checkpoint_id) {\n throw new Error(\"Missing checkpoint_id field in config.configurable.\");\n }\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO writes\n (thread_id, checkpoint_ns, checkpoint_id, task_id, idx, channel, type, value)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `);\n const rows = await Promise.all(\n writes.map(async (write, idx) => {\n const [type, serializedWrite] = await this.serde.dumpsTyped(write[1]);\n return [\n config.configurable?.thread_id as string,\n (config.configurable?.checkpoint_ns ?? \"\") as string,\n config.configurable?.checkpoint_id as string,\n taskId,\n idx,\n write[0],\n type,\n serializedWrite,\n ] as const;\n }),\n );\n this.txn(() => {\n for (const row of rows) stmt.run(...(row as unknown as never[]));\n });\n }\n\n async deleteThread(threadId: string): Promise<void> {\n this.setup();\n this.txn(() => {\n this.db\n .prepare(`DELETE FROM checkpoints WHERE thread_id = ?`)\n .run(threadId);\n this.db.prepare(`DELETE FROM writes WHERE thread_id = ?`).run(threadId);\n });\n }\n\n protected async migratePendingSends(\n checkpoint: Checkpoint,\n threadId: string,\n parentCheckpointId: string,\n ): Promise<void> {\n const row = this.db\n .prepare(\n `\n SELECT\n checkpoint_id,\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n ) as pending_sends\n FROM writes as ps\n WHERE ps.thread_id = ?\n AND ps.checkpoint_id = ?\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n `,\n )\n .get(threadId, parentCheckpointId) as Row | undefined;\n const pendingSendsJson = String(row?.pending_sends ?? \"[]\");\n const mutable = checkpoint as Checkpoint & {\n channel_values?: Record<string, unknown>;\n channel_versions: Record<string, unknown>;\n };\n mutable.channel_values ??= {};\n mutable.channel_values[TASKS] = await Promise.all(\n JSON.parse(pendingSendsJson).map(\n ({ type, value }: { type?: string; value?: string }) =>\n this.serde.loadsTyped(type ?? \"json\", value ?? \"\"),\n ),\n );\n mutable.channel_versions[TASKS] =\n Object.keys(checkpoint.channel_versions).length > 0\n ? maxChannelVersion(...Object.values(checkpoint.channel_versions))\n : this.getNextVersion(undefined);\n }\n}\n","import { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { NodeSqliteSaver } from \"./sqlite-checkpoint-saver\";\n\n// Persistent graph state per thread_id. Multi-step plans, scratchpad messages,\n// and any pending tool-call sequence survive process restarts and resume on\n// the next agent.stream() with the same thread_id.\n//\n// Stored in a separate DB file (~/.jarela/checkpoints.db) so LangGraph\n// manages its own schema independently of our own migrations under\n// lib/db/. Both files use WAL mode via the same node:sqlite driver.\n\nconst CHECKPOINT_PATH = join(getDataDir(), \"checkpoints.db\");\n\nlet _saver: NodeSqliteSaver | null = null;\n\nexport function getCheckpointer(): NodeSqliteSaver {\n if (!_saver) {\n _saver = NodeSqliteSaver.fromConnString(CHECKPOINT_PATH);\n }\n return _saver;\n}\n","import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\nimport {\n AIMessage,\n AIMessageChunk,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getDefaultModelConfig } from \"@/lib/stores/model-config\";\nimport { getAllToolsAsync } from \"@/lib/tools\";\nimport { JarelaChatModel } from \"@/lib/providers/jarela-chat-model\";\nimport { SqliteMemoryStore } from \"@/lib/stores/langgraph-store\";\nimport { getCheckpointer } from \"@/lib/agents/checkpointer\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport type { StreamChunk, StreamOptions } from \"./base\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\nimport { getConfig } from \"@/lib/env/config\";\n\nfunction toBaseMessages(\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n systemPrompt?: string,\n): BaseMessage[] {\n const base: BaseMessage[] = systemPrompt ? [new SystemMessage(systemPrompt)] : [];\n return [\n ...base,\n ...messages.map((m) => {\n // Plain text path — fast & most common.\n if (typeof m.content === \"string\") {\n return m.role === \"user\" ? new HumanMessage(m.content) : new AIMessage(m.content);\n }\n // Multi-modal path — translate our ContentPart[] into LangChain's\n // standard content-block array. Images become OpenAI-style\n // `image_url` blocks (the LangChain idiom that all major providers\n // accept on input). File attachments fall back to text so they\n // still reach text-only models. Assistant messages currently never\n // contain attachments in our flow, so we just flatten to text.\n if (m.role === \"assistant\") {\n const text = m.content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text).join(\"\\n\");\n return new AIMessage(text);\n }\n const blocks: Array<Record<string, unknown>> = [];\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) blocks.push({ type: \"text\", text: part.text });\n } else if (part.type === \"image\") {\n blocks.push({\n type: \"image_url\",\n image_url: { url: `data:${part.media_type};base64,${part.data}` },\n });\n } else if (part.type === \"file\") {\n if (part.media_type.startsWith(\"text/\") || part.media_type === \"application/json\") {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name}]\\n${part.data}` });\n } else {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name} (${part.media_type})]` });\n }\n }\n }\n // Cast through unknown — LangChain's strict block-union type rejects our\n // dynamic shape, but at runtime BaseMessage stores content as-is and\n // ChatModels consume whatever the provider's API expects (image_url for\n // OpenAI, image for Anthropic, etc.).\n return new HumanMessage({ content: blocks as unknown as string });\n }),\n ];\n}\n\nexport async function* streamWithConfig(\n threadId: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n options?: StreamOptions,\n signal?: AbortSignal,\n): AsyncIterable<StreamChunk> {\n const runCfg = options?.agent_run_config;\n\n const cfgName = runCfg?.model_config_name ?? null;\n const cfg = cfgName ? getModelConfig(cfgName) : getDefaultModelConfig();\n\n if (!cfg) {\n yield { type: \"error\", data: { message: \"No model configured. Add a model in the Models panel.\", code: \"no_model\" } };\n return;\n }\n\n let params: ProviderParams;\n try {\n params = JSON.parse(cfg.params) as ProviderParams;\n } catch {\n yield { type: \"error\", data: { message: `Model config \"${cfg.name}\" has invalid JSON params.`, code: \"config_parse_error\" } };\n return;\n }\n\n const provider = getProvider(cfg.provider);\n\n const toolPolicy = runCfg?.allowed_tools?.length\n ? { allow: runCfg.allowed_tools }\n : options?.tool_policy;\n const tools = await getAllToolsAsync(toolPolicy);\n\n const model = new JarelaChatModel({ provider, modelId: cfg.model_id, params });\n const store = new SqliteMemoryStore();\n const checkpointer = getCheckpointer();\n\n // Wipe prior checkpoint state for this thread BEFORE invoking the agent.\n // Every turn we rebuild the message history from jarela.db.messages (the\n // source of truth), so the checkpointer's only job is to buffer in-flight\n // tool-call state within the current turn. Without this delete, LangGraph's\n // default messages-state reducer keeps appending — every prior turn's tool\n // results (plus any inline image data URIs) stay in state forever and get\n // replayed to the LLM, eventually blowing past the model's context window.\n // See: thread fb35423b grew to 893 MB / 238 checkpoints because a single\n // image-attached HumanMessage (~1.2 MB base64) was replayed on every retry.\n try {\n await checkpointer.deleteThread(threadId);\n } catch (err) {\n // SqliteSaver creates the `checkpoints` table lazily on first write.\n // If we get here before any checkpoint has ever been persisted (fresh\n // DB, first turn of the process), deleteThread raises\n // `SQLITE_ERROR: no such table: checkpoints` — which is a no-op for us,\n // not an error. Swallow it; surface anything else.\n const msg = err instanceof Error ? err.message : String(err);\n if (!/no such table:\\s*checkpoints/i.test(msg)) {\n console.error(\"[llm] checkpoint reset failed for thread\", threadId, err);\n }\n }\n\n const agent = createReactAgent({ llm: model, tools, store, checkpointer });\n\n // Track which AIMessageChunk-tool-call-chunks we've already announced (by id).\n // We emit a tool_call event once per id when both id+name are known and\n // the assistant turn ends, so callers see structured tool calls (not partial ones).\n const announcedToolIds = new Set<string>();\n let pendingAIChunk: AIMessageChunk | null = null;\n let totalOutputTokens = 0;\n // Tracks whether the model hit max_tokens mid-stream. JarelaChatModel tags\n // the final chunk with additional_kwargs.stop_reason=\"length\" when this\n // happens; we surface a non-fatal warning before `done` so the user knows\n // their (visibly truncated) response was cut off — and can ask to continue.\n let truncatedByLength = false;\n // Tracks whether the previous emitted chunk was a tool result. When the next\n // AI message starts producing text, we prepend a paragraph break so the\n // pre-tool plan acknowledgment and the post-tool reply don't visually merge.\n let needsParagraphBreak = false;\n let textEmittedSinceLastBreak = false;\n\n const flushPendingToolCalls = function* (): Iterable<StreamChunk> {\n if (!pendingAIChunk) return;\n const calls = pendingAIChunk.tool_calls ?? [];\n for (const tc of calls) {\n if (!tc.id || announcedToolIds.has(tc.id)) continue;\n announcedToolIds.add(tc.id);\n yield { type: \"tool_call\", data: { id: tc.id, name: tc.name ?? \"\", arguments: tc.args ?? {} } };\n }\n pendingAIChunk = null;\n };\n\n try {\n const agentStream = await agent.stream(\n { messages: toBaseMessages(messages, runCfg?.system_prompt) },\n {\n streamMode: [\"messages\", \"updates\"],\n configurable: { thread_id: threadId },\n // LangGraph counts EACH node visit (model call + each tool call) as a\n // step. File-organization, multi-search-and-fetch, and any task that\n // pairs every action with a verify call (file_move + file_stat, etc.)\n // burns through 50 fast — 25 file moves and you're done. 200 leaves\n // generous headroom for legitimate multi-step work while still\n // bounding obvious runaway loops. Configurable via env per deployment.\n recursionLimit: getConfig().recursionLimit,\n // Cancellation: when the user hits Stop (or the last client\n // disconnects), the route aborts this signal and the LangGraph\n // pregel loop unwinds, throwing a friendly aborted error below.\n signal,\n },\n );\n\n for await (const [mode, payload] of agentStream as AsyncIterable<[string, unknown]>) {\n if (mode === \"messages\") {\n const [chunk] = payload as [BaseMessage, unknown];\n if (chunk instanceof AIMessageChunk) {\n if (typeof chunk.content === \"string\" && chunk.content) {\n // After a tool result, the next AI text starts a new conceptual\n // turn. Insert a paragraph break so the pre-tool plan and the\n // post-tool reply don't visually merge into one run-on sentence.\n let delta = chunk.content;\n if (needsParagraphBreak && textEmittedSinceLastBreak) {\n delta = \"\\n\\n\" + delta;\n }\n needsParagraphBreak = false;\n textEmittedSinceLastBreak = true;\n totalOutputTokens += 1;\n yield { type: \"text_delta\", data: { delta } };\n }\n const reasoning = chunk.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n yield { type: \"thinking_delta\", data: { delta: reasoning } };\n }\n if (chunk.additional_kwargs?.stop_reason === \"length\") {\n truncatedByLength = true;\n }\n pendingAIChunk = pendingAIChunk ? pendingAIChunk.concat(chunk) : chunk;\n } else if (chunk instanceof ToolMessage) {\n yield* flushPendingToolCalls();\n let result: unknown = chunk.content;\n if (typeof result === \"string\") {\n try { result = JSON.parse(result); } catch { /* keep string */ }\n }\n yield {\n type: \"tool_result\",\n data: { id: chunk.tool_call_id, name: chunk.name ?? \"\", result },\n };\n // Next AI text should be visually separated from the pre-tool prose.\n needsParagraphBreak = true;\n }\n } else if (mode === \"updates\") {\n // End of an agent step — flush any unflushed tool calls (e.g. final assistant message\n // with no follow-up tool execution).\n yield* flushPendingToolCalls();\n }\n }\n\n // Final flush in case stream ended without an \"updates\" tick.\n yield* flushPendingToolCalls();\n } catch (err) {\n const name = err instanceof Error ? err.name : \"\";\n const baseMsg = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error && err.stack ? err.stack : \"\";\n // undici surfaces network failures as a bare \"fetch failed\" with the\n // real reason (ECONNREFUSED, EAI_AGAIN, UND_ERR_SOCKET, cert issues,\n // proxy CONNECT rejects, …) hidden under err.cause. Walk the chain so\n // operators get a useful log line and the UI shows something actionable.\n const causeChain: string[] = [];\n let cur: unknown = err;\n let depth = 0;\n while (cur && typeof cur === \"object\" && \"cause\" in cur && depth < 4) {\n const c = (cur as { cause?: unknown }).cause;\n if (!c) break;\n const cMsg = c instanceof Error ? `${c.name}: ${c.message}` : String(c);\n const cCode = c && typeof c === \"object\" && \"code\" in c ? ` [${(c as { code?: string }).code}]` : \"\";\n causeChain.push(`${cMsg}${cCode}`);\n cur = c;\n depth += 1;\n }\n const rawMsg = causeChain.length > 0\n ? `${baseMsg} (cause: ${causeChain.join(\" → \")})`\n : baseMsg;\n\n // User-initiated abort (Stop button / client disconnect): emit a\n // short error chunk and let the route fall through to `done` so the\n // queued-message drain in the UI fires normally.\n if (signal?.aborted || name === \"AbortError\" || /aborted/i.test(rawMsg)) {\n yield { type: \"error\", data: { message: \"Run interrupted by user.\", code: \"aborted\" } };\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n aborted: true,\n },\n };\n return;\n }\n\n console.error(\"[agent_error]\", stack || rawMsg);\n\n // Translate LangGraph's recursion limit into a friendly explanation —\n // the raw stack mentions internal Pregel paths users can't act on. They\n // CAN act on knowing the agent loop didn't converge (likely chasing tool\n // results in a loop or a genuinely deep multi-step task).\n let friendly = rawMsg;\n let code = \"agent_error\";\n if (name === \"GraphRecursionError\" || /recursion limit/i.test(rawMsg)) {\n const limit = getConfig().recursionLimit;\n friendly =\n `The agent took too many tool-calling steps without finishing (hit the ${limit}-step limit). ` +\n `If the task is legitimately deep, raise JARELA_RECURSION_LIMIT in the env. ` +\n `If the agent looked stuck in a loop (calling the same tool repeatedly), simplify the prompt or ` +\n `try /new to start fresh — long histories of tool results sometimes make the model re-attempt the same step.`;\n code = \"recursion_limit\";\n } else if (/Received empty response from chat model call/i.test(rawMsg)) {\n // Defense in depth: JarelaChatModel._streamFromProvider already guards\n // against this by emitting a sentinel empty chunk, but if a future\n // provider bypasses that path we still want a useful message instead of\n // the raw LangChain stack.\n friendly =\n \"The model returned an empty response. This usually means a content filter triggered, \" +\n \"max_tokens was too low for a reasoning model, or the connection dropped mid-stream. \" +\n \"Check the model config and retry.\";\n code = \"empty_response\";\n } else if (/max_tokens/i.test(rawMsg) && /no content|before hitting/i.test(rawMsg)) {\n code = \"max_tokens_exhausted\";\n }\n // Pull out the FIRST in-app frame from the stack so the user sees what\n // module triggered it, without dumping the full Pregel/webpack trace.\n const firstAppFrame = stack.split(\"\\n\").find((l) => /\\(rsc\\)\\.\\/lib\\//.test(l));\n const trimmed = firstAppFrame ? `\\n${firstAppFrame.trim()}` : \"\";\n yield { type: \"error\", data: { message: `${friendly}${trimmed}`, code } };\n return;\n }\n\n if (truncatedByLength) {\n yield {\n type: \"error\",\n data: {\n message:\n \"Response truncated — the model hit its max_tokens limit before finishing. \" +\n \"Raise max_tokens in the model config (Anthropic defaults to 4096) and ask me to continue.\",\n code: \"max_tokens_truncated\",\n },\n };\n }\n\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n },\n };\n}\n","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { MBTI_PRESETS, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\n\ninterface SignalSnapshot {\n mood: \"frustrated\" | \"rushed\" | \"positive\" | \"neutral\";\n urgency: number;\n frustration: number;\n positivity: number;\n}\n\n/**\n * Build a compact runtime persona section from per-agent adaptive settings and\n * the current user message. This keeps adaptation deterministic and auditable.\n */\nexport function buildAdaptivePersonaContext(agent: AgentConfigRow, userMessage: string): string {\n if (!agent.adaptive_persona_enabled) return \"\";\n\n const mbti = toMbti(agent.adaptive_mbti) ?? \"INTJ\";\n const mbtiLabel = MBTI_PRESETS[mbti].label;\n\n const strength = clampPercent(agent.adaptive_persona_strength);\n const empathy = clampPercent(agent.adaptive_empathy);\n const expressiveness = clampPercent(agent.adaptive_expressiveness);\n const verbosity = clampPercent(agent.adaptive_verbosity);\n\n const signal = detectSignals(userMessage);\n const intensity = strength / 100;\n\n const targetEmpathy = clampPercent(\n empathy + Math.round((signal.frustration * 30 + signal.urgency * 10 - signal.positivity * 6) * intensity),\n );\n const targetExpressive = clampPercent(\n expressiveness + Math.round((signal.positivity * 24 - signal.frustration * 12) * intensity),\n );\n const targetVerbosity = clampPercent(\n verbosity + Math.round((signal.urgency * -30 + signal.frustration * -12) * intensity),\n );\n\n const empathyBand = bandLabel(targetEmpathy, [30, 70], [\"low\", \"balanced\", \"high\"]);\n const expressiveBand = bandLabel(targetExpressive, [30, 70], [\"reserved\", \"balanced\", \"energetic\"]);\n const verbosityBand = bandLabel(targetVerbosity, [30, 70], [\"concise\", \"balanced\", \"detailed\"]);\n\n const directives = [\n empathyBand === \"high\"\n ? \"Acknowledge user friction clearly before giving steps.\"\n : empathyBand === \"low\"\n ? \"Keep emotional language minimal; stay pragmatic and neutral.\"\n : \"Use light empathy, then move quickly to actionable guidance.\",\n verbosityBand === \"concise\"\n ? \"Prefer short, direct answers and prioritize the next concrete action.\"\n : verbosityBand === \"detailed\"\n ? \"Provide fuller rationale and tradeoffs when relevant.\"\n : \"Keep explanations compact with enough rationale to be useful.\",\n expressiveBand === \"energetic\"\n ? \"Use lively but professional tone; avoid slang and exaggeration.\"\n : expressiveBand === \"reserved\"\n ? \"Use calm, matter-of-fact wording.\"\n : \"Use steady, approachable wording.\",\n signal.mood === \"rushed\"\n ? \"User appears time-constrained; front-load the answer and avoid preamble.\"\n : signal.mood === \"frustrated\"\n ? \"User appears frustrated; validate briefly and offer a clear recovery path.\"\n : \"Do not force mood mirroring; keep behavior stable and task-focused.\",\n ];\n\n return [\n \"--- Adaptive persona ---\",\n \"These style constraints are dynamic and apply to this turn only.\",\n `Preset: ${mbti} (${mbtiLabel})`,\n `Detected user signal: ${signal.mood}`,\n `Adapt strength: ${strength}/100`,\n `Target empathy: ${targetEmpathy}/100 (${empathyBand})`,\n `Target expressiveness: ${targetExpressive}/100 (${expressiveBand})`,\n `Target verbosity: ${targetVerbosity}/100 (${verbosityBand})`,\n \"Style directives:\",\n ...directives.map((d) => `- ${d}`),\n \"Never sacrifice factual accuracy, safety policy, or execution completeness for style.\",\n ].join(\"\\n\");\n}\n\nfunction detectSignals(text: string): SignalSnapshot {\n const lower = text.toLowerCase();\n\n const frustrationHits = countMatches(lower, [\n \"stuck\", \"frustrat\", \"annoy\", \"angry\", \"wtf\", \"doesn't work\", \"not working\", \"broken\", \"hate this\",\n ]);\n const urgencyHits = countMatches(lower, [\n \"asap\", \"urgent\", \"quick\", \"quickly\", \"fast\", \"hurry\", \"right now\", \"immediately\",\n ]);\n const positivityHits = countMatches(lower, [\n \"thanks\", \"thank you\", \"awesome\", \"great\", \"love\", \"perfect\", \"nice\",\n ]);\n\n const frustration = Math.min(1, frustrationHits / 2);\n const urgency = Math.min(1, urgencyHits / 2);\n const positivity = Math.min(1, positivityHits / 2);\n\n let mood: SignalSnapshot[\"mood\"] = \"neutral\";\n if (frustration >= 0.5) mood = \"frustrated\";\n else if (urgency >= 0.5) mood = \"rushed\";\n else if (positivity >= 0.5) mood = \"positive\";\n\n return { mood, urgency, frustration, positivity };\n}\n\nfunction countMatches(text: string, terms: string[]): number {\n let n = 0;\n for (const term of terms) {\n if (text.includes(term)) n += 1;\n }\n return n;\n}\n\nfunction clampPercent(v: number): number {\n if (!Number.isFinite(v)) return 50;\n return Math.max(0, Math.min(100, Math.round(v)));\n}\n\nfunction bandLabel<T extends string>(value: number, cutoffs: [number, number], labels: [T, T, T]): T {\n if (value < cutoffs[0]) return labels[0];\n if (value > cutoffs[1]) return labels[2];\n return labels[1];\n}\n\nfunction toMbti(v: string | null | undefined): MbtiType | null {\n if (!v) return null;\n return (v in MBTI_PRESETS ? v : null) as MbtiType | null;\n}\n","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { getDefaultHarnessId, getHarness } from \"@/lib/stores/harnesses\";\nimport { getBuiltinHarness } from \"./presets\";\nimport { DEFAULT_HARNESS_ID, HARNESS_SECTION_KEYS, type HarnessSectionKey } from \"./types\";\n\nexport type ResolvedHarnessSections = Record<HarnessSectionKey, string>;\n\n/**\n * Resolve which harness applies to a given agent and return its section\n * bodies as a record. Disabled sections become empty strings (so the\n * caller's `.filter(Boolean)` in systemParts assembly drops them).\n *\n * Resolution order:\n * 1. agentCfg.harness_id (per-agent override)\n * 2. app-settings default_harness_id (global default)\n * 3. builtin:default\n *\n * Stale ids (custom harness deleted out from under an agent) fall back to\n * builtin:default rather than erroring — matches how missing model configs\n * behave in this codebase.\n */\nexport function resolveHarness(\n agentCfg: Pick<AgentConfigRow, \"harness_id\">,\n): ResolvedHarnessSections {\n const id = agentCfg.harness_id || getDefaultHarnessId() || DEFAULT_HARNESS_ID;\n const harness =\n getHarness(id) ?? getBuiltinHarness(DEFAULT_HARNESS_ID) ?? null;\n const out = {} as ResolvedHarnessSections;\n for (const key of HARNESS_SECTION_KEYS) {\n const section = harness?.sections[key];\n out[key] = section?.enabled ? section.body : \"\";\n }\n return out;\n}\n","import type { Claim } from \"./types\";\n\n// First-person past-tense or perfect-tense action verbs that imply work was\n// performed in the current turn. We don't try to enumerate every English verb;\n// the set covers the dominant fabrication shapes in observed transcripts.\nconst ACTION_VERBS = [\n \"patched\", \"edited\", \"wrote\", \"ran\", \"verified\", \"created\", \"deleted\",\n \"updated\", \"committed\", \"saved\", \"added\", \"removed\", \"fixed\", \"applied\",\n \"installed\", \"configured\", \"renamed\", \"moved\", \"copied\", \"pushed\", \"merged\",\n \"checked\", \"confirmed\", \"tested\",\n];\n\nconst VERB_GROUP = ACTION_VERBS.join(\"|\");\n\nconst PATTERNS: RegExp[] = [\n // \"I patched the file\" — bare past tense\n new RegExp(`\\\\bI\\\\s+(?:just\\\\s+)?(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"I've patched\", \"I have patched\"\n new RegExp(`\\\\bI(?:'ve|\\\\s+have)\\\\s+(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"Verified the bytes\" — leading capital, no subject (common in concise replies)\n new RegExp(`(?:^|\\\\.\\\\s+|\\\\n)(${VERB_GROUP})\\\\b`, \"gi\"),\n];\n\nconst FUTURE_PATTERNS: RegExp[] = [\n // \"I'll patch\", \"I will patch\", \"I would patch\", \"I could patch\"\n /\\bI(?:'ll|\\s+will|\\s+would|\\s+could|\\s+should|\\s+can|\\s+might)\\s+\\w+/i,\n];\n\nexport function findActionClaims(text: string): Claim[] {\n const out: Claim[] = [];\n const seen = new Set<string>();\n for (const re of PATTERNS) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const verb = m[1].toLowerCase();\n // Skip if this match is inside a future-tense clause. Scan a small\n // backward window for \"I'll / I will\" before the verb.\n const start = Math.max(0, m.index - 24);\n const window = text.slice(start, m.index + m[0].length);\n if (FUTURE_PATTERNS.some((f) => f.test(window))) continue;\n const key = `${verb}@${m.index}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ verb, raw: m[0].trim() });\n }\n }\n return out;\n}\n","import type { Citation } from \"./types\";\n\n// Matches `(via NAME)` and `(via NAME ARG1 ARG2)` and `(via NAME, file: ...)`.\n// Captures the tool name (first whitespace-delimited identifier-ish token).\n// Ignores file-path citations like `(lib/foo.ts:42)` and memory citations\n// like `(memory: ns/key)` — those are not tool-call claims.\nconst VIA_RE = /\\(\\s*via\\s+([A-Za-z_][\\w-]*)[^)]*\\)/g;\n\nexport function findCitations(text: string): Citation[] {\n const out: Citation[] = [];\n VIA_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VIA_RE.exec(text)) !== null) {\n out.push({ tool: m[1], raw: m[0] });\n }\n return out;\n}\n","import { findActionClaims } from \"./claim-detector\";\nimport { findCitations } from \"./citation-parser\";\nimport type { ValidationResult } from \"./types\";\n\nconst SUMMARY_PATTERNS: RegExp[] = [\n /^#{1,6}\\s*Summary(?:\\s+of\\s+changes)?\\b/im,\n /\\bI(?:'ve|\\s+have)\\s+completed\\b/i,\n /\\bWhat\\s+I\\s+did\\b/i,\n];\n\n/**\n * Cross-check the assistant's text output against the tool calls actually\n * issued in this turn. Returns ok=true when nothing fishy is detected,\n * or ok=false with a kind + reason when a fabrication shape is matched.\n *\n * Priority (first match wins): citation_unregistered_tool >\n * citation_uncalled_tool > claim_without_tool > summary_without_action.\n *\n * Lenient principle: when ANY tool was called this turn, action-claim text\n * is allowed (the model legitimately did work, even if its phrasing isn't\n * tagged with `(via ...)`). Citations are checked regardless of tool count.\n */\nexport function validateAssistantOutput(\n text: string,\n toolCalls: readonly string[],\n allowedTools: readonly string[],\n): ValidationResult {\n const calledSet = new Set(toolCalls);\n const allowedSet = new Set(allowedTools);\n\n // Citation checks run regardless of whether other tools were called —\n // a `(via foo)` tag MUST refer to a registered tool that was actually\n // invoked this turn.\n const citations = findCitations(text);\n for (const c of citations) {\n if (!allowedSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_unregistered_tool\",\n reason: `You wrote \"${c.raw}\" but \"${c.tool}\" is not a registered tool. Either drop the citation or call the correct tool.`,\n evidence: c.raw,\n };\n }\n if (!calledSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_uncalled_tool\",\n reason: `You wrote \"${c.raw}\" but did not actually call \"${c.tool}\" this turn. Call the tool or drop the citation.`,\n evidence: c.raw,\n };\n }\n }\n\n // Claim and summary checks only fire when zero tools were called. If any\n // tool ran, the text is treated as legitimately describing work done.\n if (toolCalls.length > 0) return { ok: true };\n\n const claims = findActionClaims(text);\n if (claims.length > 0) {\n const c = claims[0];\n return {\n ok: false,\n kind: \"claim_without_tool\",\n reason: `You wrote \"${c.raw}\" but did not call any tool this turn. Either call the tool that performs the action or rephrase as a proposal.`,\n evidence: c.raw,\n };\n }\n\n for (const re of SUMMARY_PATTERNS) {\n const m = text.match(re);\n if (m) {\n return {\n ok: false,\n kind: \"summary_without_action\",\n reason: `You wrote a summary section (\"${m[0].trim()}\") but did not call any tool this turn. Drop the recap or do the work first.`,\n evidence: m[0].trim(),\n };\n }\n }\n\n return { ok: true };\n}\n","export { validateAssistantOutput } from \"./validator\";\nexport { findActionClaims } from \"./claim-detector\";\nexport { findCitations } from \"./citation-parser\";\nexport type {\n ValidationKind,\n ValidationOk,\n ValidationFail,\n ValidationResult,\n Citation,\n Claim,\n} from \"./types\";\n","import type { MessageRow } from \"@/lib/stores/threads\";\nimport { transcriptText } from \"@/lib/agents/conversation-summary\";\n\nexport type ContextTier = \"hot\" | \"warm\" | \"facts\";\n\nexport type ContextTierPriority = [ContextTier, ContextTier, ContextTier];\n\nexport interface ContextTierProportions {\n hot?: number;\n warm?: number;\n facts?: number;\n}\n\nexport interface ContextBudgetConfig {\n context_window_tokens?: number;\n max_tokens?: number;\n context_tier_proportions?: ContextTierProportions;\n context_tier_priority?: ContextTierPriority | readonly ContextTier[] | unknown;\n}\n\nexport interface ContextBudget {\n contextWindowTokens: number;\n outputReserveTokens: number;\n inputBudgetTokens: number;\n overheadTokens: number;\n tierBudgets: Record<ContextTier, number>;\n tierPriority: ContextTierPriority;\n}\n\nconst DEFAULT_CONTEXT_WINDOW_TOKENS = 8_192;\nconst DEFAULT_OVERHEAD_TOKENS = 1_200;\nconst DEFAULT_OUTPUT_RESERVE_RATIO = 0.2;\nconst DEFAULT_TIER_PRIORITY: ContextTierPriority = [\"hot\", \"warm\", \"facts\"];\nconst DEFAULT_TIER_PROPORTIONS: Required<ContextTierProportions> = {\n hot: 0.6,\n warm: 0.25,\n facts: 0.15,\n};\n\nexport function estimateTokens(text: string): number {\n const trimmed = text.trim();\n if (!trimmed) return 0;\n return Math.max(1, Math.ceil(trimmed.length / 4));\n}\n\nexport function normalizeTierPriority(value: ContextBudgetConfig[\"context_tier_priority\"]): ContextTierPriority {\n if (!Array.isArray(value)) return DEFAULT_TIER_PRIORITY;\n const tiers = value.filter((v): v is ContextTier => v === \"hot\" || v === \"warm\" || v === \"facts\");\n if (tiers.length !== 3) return DEFAULT_TIER_PRIORITY;\n if (new Set(tiers).size !== 3) return DEFAULT_TIER_PRIORITY;\n return [tiers[0], tiers[1], tiers[2]];\n}\n\nexport function normalizeTierProportions(value: ContextTierProportions | undefined): Required<ContextTierProportions> {\n const hot = toPositiveNumber(value?.hot, DEFAULT_TIER_PROPORTIONS.hot);\n const warm = toPositiveNumber(value?.warm, DEFAULT_TIER_PROPORTIONS.warm);\n const facts = toPositiveNumber(value?.facts, DEFAULT_TIER_PROPORTIONS.facts);\n const sum = hot + warm + facts;\n if (sum <= 0) return DEFAULT_TIER_PROPORTIONS;\n return {\n hot: hot / sum,\n warm: warm / sum,\n facts: facts / sum,\n };\n}\n\nexport function computeContextBudget(config: ContextBudgetConfig): ContextBudget {\n const contextWindowTokens = Math.max(\n 1,\n Math.floor(config.context_window_tokens ?? DEFAULT_CONTEXT_WINDOW_TOKENS),\n );\n const outputReserveTokens = Math.max(\n 256,\n Math.min(\n contextWindowTokens - 1,\n Math.floor(config.max_tokens ?? contextWindowTokens * DEFAULT_OUTPUT_RESERVE_RATIO),\n ),\n );\n const overheadTokens = Math.max(0, Math.min(DEFAULT_OVERHEAD_TOKENS, contextWindowTokens - outputReserveTokens));\n const inputBudgetTokens = Math.max(0, contextWindowTokens - outputReserveTokens - overheadTokens);\n const proportions = normalizeTierProportions(config.context_tier_proportions);\n const tierPriority = normalizeTierPriority(config.context_tier_priority);\n const tierBudgets = {\n hot: Math.floor(inputBudgetTokens * proportions.hot),\n warm: Math.floor(inputBudgetTokens * proportions.warm),\n facts: Math.max(0, inputBudgetTokens - Math.floor(inputBudgetTokens * proportions.hot) - Math.floor(inputBudgetTokens * proportions.warm)),\n } satisfies Record<ContextTier, number>;\n\n return {\n contextWindowTokens,\n outputReserveTokens,\n inputBudgetTokens,\n overheadTokens,\n tierBudgets,\n tierPriority,\n };\n}\n\nexport function takeRecentMessagesWithinBudget(messages: readonly MessageRow[], tokenBudget: number): MessageRow[] {\n if (tokenBudget <= 0 || messages.length === 0) return [];\n const chosen: MessageRow[] = [];\n let used = 0;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n const tokens = estimateTokens(transcriptText(msg.content));\n if (chosen.length > 0 && used + tokens > tokenBudget) break;\n chosen.push(msg);\n used += tokens;\n if (used >= tokenBudget) break;\n }\n return chosen.reverse();\n}\n\nexport function truncateLargestMessagesWithinBudget(messages: readonly MessageRow[], tokenBudget: number): MessageRow[] {\n if (messages.length === 0) return [];\n if (tokenBudget <= 0) return messages.slice(-1);\n\n const out = messages.map((m) => ({ ...m }));\n let tokens = out.map((m) => estimateTokens(transcriptText(m.content)));\n let total = tokens.reduce((a, b) => a + b, 0);\n if (total <= tokenBudget) return out;\n\n // Keep shrinking the largest message until the aggregate fits the budget.\n // This is a last-resort guardrail for pathological long turns.\n while (total > tokenBudget) {\n let idx = 0;\n for (let i = 1; i < tokens.length; i += 1) {\n if (tokens[i] > tokens[idx]) idx = i;\n }\n const cur = tokens[idx];\n if (cur <= 1) break;\n\n const needed = total - tokenBudget;\n const nextTokens = Math.max(1, cur - needed);\n const nextChars = Math.max(8, nextTokens * 4 - 32);\n const raw = transcriptText(out[idx].content).replace(/\\s+/g, \" \").trim();\n const suffix = \" [truncated for context budget]\";\n const clipped = raw.length > nextChars\n ? `${raw.slice(0, Math.max(1, nextChars)).trimEnd()}${suffix}`\n : raw;\n\n out[idx] = { ...out[idx], content: clipped };\n tokens[idx] = estimateTokens(clipped);\n total = tokens.reduce((a, b) => a + b, 0);\n }\n\n return out;\n}\n\nexport function formatContextBudgetSummary(budget: ContextBudget): string {\n const parts = [\n `window ${budget.contextWindowTokens} tokens`,\n `output reserve ${budget.outputReserveTokens}`,\n `input budget ${budget.inputBudgetTokens}`,\n `hot ${budget.tierBudgets.hot}`,\n `warm ${budget.tierBudgets.warm}`,\n `facts ${budget.tierBudgets.facts}`,\n ];\n return parts.join(\" · \");\n}\n\nfunction toPositiveNumber(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}","import { streamWithConfig } from \"@/lib/agents/llm\";\nimport type { StreamChunk, StreamOptions } from \"@/lib/agents/base\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport { addMessage, getRecentMessagesWindow, getThread, touchThread, type PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { recordToolUsage } from \"@/lib/stores/tool-stats\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { recall, type RecalledMemory } from \"@/lib/embeddings\";\nimport { listIntegrations } from \"@/lib/stores/integrations\";\nimport { buildAdaptivePersonaContext } from \"@/lib/agents/adaptive-persona\";\nimport { resolveHarness } from \"@/lib/agents/harness/resolve\";\nimport { validateAssistantOutput } from \"@/lib/agents/output-validator\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport os from \"node:os\";\nimport {\n computeContextBudget,\n formatContextBudgetSummary,\n takeRecentMessagesWithinBudget,\n truncateLargestMessagesWithinBudget,\n} from \"@/lib/agents/context-budget\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { summarizeTranscript, transcriptText } from \"@/lib/agents/conversation-summary\";\nimport { getDefaultModelConfig, getModelConfig } from \"@/lib/stores/model-config\";\nimport { getProvider } from \"@/lib/providers\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\n\n// Resolve the app name once at module load. Forks set NEXT_PUBLIC_APP_NAME to\n// rebrand the user-visible name the LLM echoes in chat replies; default\n// \"Jarela\" for upstream. Per-turn pieces of the system prompt (user profile,\n// integrations, time, env) still interpolate this constant directly.\nconst APP_NAME = getAppName();\n\nexport class RunThreadError extends Error {\n status: number;\n code: string;\n\n constructor(status: number, message: string, code: string) {\n super(message);\n this.status = status;\n this.code = code;\n }\n}\n\n// Hard cap on how long we wait for the embedding-based recall pass before\n// starting the LLM stream without it. Recall is best-effort context — making\n// users wait on a cold OpenAI embeddings round-trip every turn is a worse UX\n// than occasionally missing a memory hit.\nconst RECALL_BUDGET_MS = 400;\n\nfunction raceWithBudget<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {\n return new Promise<T>((resolve) => {\n let settled = false;\n const t = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(fallback);\n }\n }, ms);\n promise.then(\n (v) => { if (!settled) { settled = true; clearTimeout(t); resolve(v); } },\n () => { if (!settled) { settled = true; clearTimeout(t); resolve(fallback); } },\n );\n });\n}\n\n// The harness sections (capabilities, plan-first, presentation, citation,\n// self-config) used to live here as hard-coded constants. They moved to\n// `lib/agents/harness/presets.ts` as the body of `builtin:default`, and\n// `resolveHarness(agentCfg)` returns them per-turn (allowing per-agent\n// override + global default selection). See ADR-0033.\n\nexport interface PreparedThreadRun {\n stream: AsyncIterable<StreamChunk>;\n thread_id: string;\n}\n\n// Max times we'll auto-retry a single user turn when the model emits a\n// \"one moment\" stall without firing any tool. One retry is plenty — if the\n// model is *still* stalling after a forceful nudge, looping further just\n// burns tokens and the warning footer on the persisted message gives the\n// user a clear manual recovery path (\"continue\").\nconst MAX_STALL_AUTO_RETRIES = 1;\n\nfunction parseContent(raw: string): string | ContentPart[] {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length > 0 &&\n typeof parsed[0] === \"object\" &&\n parsed[0] !== null &&\n \"type\" in (parsed[0] as object)\n ) {\n return parsed as ContentPart[];\n }\n } catch {\n // not valid JSON — treat as plain text\n }\n return raw;\n}\n\nfunction contentText(content: string | ContentPart[]): string {\n if (typeof content === \"string\") return content;\n return content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text)\n .join(\" \");\n}\n\nexport async function prepareThreadRun(\n thread_id: string,\n message: string,\n options?: StreamOptions,\n attachments?: ContentPart[],\n signal?: AbortSignal,\n // Internal: tracks how many stall-retries are still allowed in this turn.\n // Public callers leave this undefined and get the default budget. The\n // wrapper decrements it when it recursively re-invokes prepareThreadRun.\n _stallRetriesLeft: number = MAX_STALL_AUTO_RETRIES,\n // Optional classification tag persisted on the injected user message.\n // Surfaces in the chat panel's category-filter toolbar (e.g.\n // 'scheduled_task', 'bridge', 'synthetic'). undefined = ordinary chat.\n userCategory: string | null = null,\n): Promise<PreparedThreadRun> {\n // Lazy-start the scheduler when any agent activity occurs so previously\n // saved scheduled tasks resume firing across server restarts.\n startScheduler();\n\n const thread = getThread(thread_id);\n if (!thread) throw new RunThreadError(404, \"Thread not found\", \"thread_not_found\");\n\n const trimmed = message.trim();\n if (!trimmed && !attachments?.length) {\n throw new RunThreadError(400, \"message required\", \"message_required\");\n }\n\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) {\n throw new RunThreadError(404, `Agent \"${thread.agent_id}\" not found`, \"agent_not_found\");\n }\n\n const content: string | ContentPart[] =\n attachments?.length ? [{ type: \"text\", text: trimmed }, ...attachments] : trimmed;\n\n const stored = typeof content === \"string\" ? content : JSON.stringify(content);\n addMessage(thread_id, \"user\", stored, undefined, userCategory);\n touchThread(thread_id, trimmed.slice(0, 80) || undefined);\n\n // Build the LLM history window: latest N messages that are also within the\n // last X hours. Both bounds come from the agent's config (defaults 50 / 8h).\n // The full history remains queryable via getMessages for the UI.\n const limit = agentCfg.history_limit ?? 50;\n const windowHours = agentCfg.history_window_hours ?? 8;\n const sinceISO = windowHours > 0\n ? new Date(Date.now() - windowHours * 3600_000).toISOString()\n : undefined;\n const allWindowMessages = getRecentMessagesWindow(thread_id, limit, sinceISO);\n\n const modelCfg = agentCfg.model_config_name\n ? getModelConfig(agentCfg.model_config_name)\n : getDefaultModelConfig();\n let providerParams: ProviderParams = {};\n if (modelCfg) {\n try {\n providerParams = JSON.parse(modelCfg.params) as ProviderParams;\n } catch {\n providerParams = {};\n }\n }\n\n const budget = computeContextBudget({\n context_window_tokens:\n typeof providerParams.context_window_tokens === \"number\"\n ? providerParams.context_window_tokens\n : undefined,\n max_tokens: typeof providerParams.max_tokens === \"number\" ? providerParams.max_tokens : undefined,\n context_tier_proportions:\n typeof providerParams.context_tier_proportions === \"object\" && providerParams.context_tier_proportions\n ? (providerParams.context_tier_proportions as { hot?: number; warm?: number; facts?: number })\n : undefined,\n context_tier_priority: providerParams.context_tier_priority,\n });\n\n const hotMessages = takeRecentMessagesWithinBudget(allWindowMessages, budget.tierBudgets.hot);\n\n // Build agent run config from DB record\n const userProfile = getUserProfile();\n const userCtxParts: string[] = [];\n if (userProfile?.name) userCtxParts.push(`Name: ${userProfile.name}`);\n if (userProfile?.about) userCtxParts.push(`About: ${userProfile.about}`);\n if (\n userProfile?.location_consent === 1 &&\n typeof userProfile.location_lat === \"number\" &&\n typeof userProfile.location_lng === \"number\"\n ) {\n const ageSec = userProfile.location_updated_at\n ? Math.round((Date.now() - Date.parse(userProfile.location_updated_at)) / 1000)\n : null;\n const ageStr = ageSec === null ? \"unknown age\"\n : ageSec < 120 ? `${ageSec}s ago`\n : ageSec < 7200 ? `${Math.round(ageSec / 60)}m ago`\n : `${Math.round(ageSec / 3600)}h ago`;\n const acc = userProfile.location_accuracy_m != null\n ? ` (±${Math.round(userProfile.location_accuracy_m)}m)` : \"\";\n const label = userProfile.location_label ? ` — ${userProfile.location_label}` : \"\";\n userCtxParts.push(\n `Location: ${userProfile.location_lat.toFixed(5)}, ${userProfile.location_lng.toFixed(5)}${acc}${label} [updated ${ageStr}]`,\n \" (User has opted in to share location. Use it for any location-dependent answer — weather, nearby places, directions, local time. Call get_user_location for the freshest values.)\",\n );\n }\n const userCtx = userCtxParts.length > 0\n ? `--- User context ---\\n${userCtxParts.join(\"\\n\")}`\n : null;\n\n const timeCtx = `Current time: ${new Date().toISOString()} (UTC). Use this when computing scheduled task timestamps.`;\n const experienceMode = options?.ui_experience_mode === \"normal\" ? \"normal\" : \"advanced\";\n const experienceCtx = [\n \"--- UX mode ---\",\n `User interface mode: ${experienceMode}.`,\n experienceMode === \"normal\"\n ? \"Prefer concise, plain-language explanations and avoid exposing low-level configuration details unless asked.\"\n : \"User opted into advanced controls; detailed technical explanations are welcome.\",\n ].join(\"\\n\");\n\n // Host environment hint so the agent doesn't have to guess platform-specific\n // paths (e.g. iCloud Drive lives at a different default location on Windows\n // vs. macOS). Keeps the agent grounded in the actual filesystem it's\n // operating against.\n const envCtx = [\n \"--- Host environment ---\",\n `Platform: ${process.platform} (${process.arch})`,\n `CWD: ${process.cwd()}`,\n `Home: ${os.homedir()}`,\n process.platform === \"win32\"\n ? \"iCloud Drive on Windows (if installed): %USERPROFILE%\\\\iCloudDrive (a.k.a. ~\\\\iCloudDrive)\"\n : process.platform === \"darwin\"\n ? \"iCloud Drive on macOS: ~/Library/Mobile Documents/com~apple~CloudDocs\"\n : \"\",\n `File-tool path resolution: absolute paths and \\`~/...\\` are honored verbatim; BARE RELATIVE paths (e.g. \\`notes.txt\\`) resolve against HOME, not cwd. cwd is the ${APP_NAME} install directory and should never be used as a default location for user files.`,\n \"Verify file paths with file_stat or file_list before assuming they exist. Always echo the resolved absolute path back to the user when you create/move/delete a file so they know where it landed.\",\n ].filter(Boolean).join(\"\\n\");\n\n // Surface configured integrations so the LLM knows native tools are wired\n // and ready. Without this, the model defaults to shell-exec'ing CLIs (`jira`,\n // `gh`, etc.) because that's what its training data covers — even though\n // the typed REST tools are right there in the function list.\n const configuredIntegrations = listIntegrations().filter((i) => i.configured);\n const integrationsCtx = configuredIntegrations.length > 0 ? [\n \"--- Configured integrations (use the typed tools, not shell CLIs) ---\",\n ...configuredIntegrations.flatMap((i) => {\n if (i.name === \"atlassian\") {\n const url = i.values.url;\n return [\n `Atlassian: ${url} as ${i.values.email}.`,\n \" Use jira_search / jira_get_issue / jira_create_issue / jira_add_comment / jira_transition_issue / confluence_search / confluence_get_page.\",\n \" DO NOT shell out to a `jira` or `acli` CLI — these REST tools are already authenticated and use the corporate proxy correctly.\",\n ];\n }\n if (i.name === \"jira_align\") {\n return [\n \"Jira Align: configured.\",\n \" Use jira_align_search_items / jira_align_get_item / jira_align_create_item / jira_align_update_item / jira_align_transition_item / jira_align_add_comment.\",\n ];\n }\n if (i.name === \"github\") {\n return [\n \"GitHub: configured.\",\n \" Use github_* tools for issues/PRs/code/reviews (search, create, update, comment, merge, file fetch) instead of shelling out to `gh`.\",\n ];\n }\n if (i.name === \"gmail\") {\n return [\n \"Gmail + Calendar: configured.\",\n \" Use gmail_* for inbox/search/draft/labels and calendar_* for event operations. Prefer these typed tools over raw IMAP/SMTP instructions.\",\n ];\n }\n if (i.name === \"outlook\") {\n return [\n \"Outlook + Calendar: configured.\",\n \" Use outlook_* for mail operations and outlook_calendar_* for event operations.\",\n ];\n }\n if (i.name === \"google\") {\n return [\n \"Google AI: configured.\",\n \" Use generate_image when the user asks to create images; don't claim image generation is unavailable.\",\n ];\n }\n return [`${i.name}: configured.`];\n }),\n \"\",\n ].join(\"\\n\") : \"\";\n\n const memoryCtx = [\n \"--- Memory & recall ---\",\n \"You have long-term memory across sessions and a fresh recall pass on every turn.\",\n `- Hot conversation history is budgeted by model context size: ${formatContextBudgetSummary(budget)}.`,\n \"- A semantic search over all stored memory entries + past chat messages was run against the user's turn; matching items appear under \\\"Relevant context\\\" below.\",\n \"- Use memory_write proactively when the user shares a fact, preference, or decision worth remembering. Use memory_read / memory_list to recall stored facts on demand.\",\n \"- If you want detail from outside the recent window, the user can scroll up — but for facts you've stored explicitly, prefer recall over guessing.\",\n ].join(\"\\n\");\n\n const warmSummaryCtx = await buildWarmSummaryContext(\n allWindowMessages,\n hotMessages.length,\n modelCfg?.provider,\n modelCfg?.model_id,\n providerParams,\n budget.tierBudgets.warm,\n );\n\n const warmWasExpected = budget.tierBudgets.warm > 32 && (allWindowMessages.length - hotMessages.length) >= 2;\n const hotMessagesForPrompt = !warmSummaryCtx && warmWasExpected\n ? truncateLargestMessagesWithinBudget(hotMessages, budget.tierBudgets.hot)\n : hotMessages;\n\n const history = hotMessagesForPrompt.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: parseContent(m.content),\n }));\n\n const factsCtx = buildFactsContext(trimmed, budget.tierBudgets.facts);\n\n const tierCtxByName = {\n hot: \"\",\n warm: warmSummaryCtx,\n facts: factsCtx,\n } as const;\n const tierOrderCtx = budget.tierPriority\n .map((tier) => tierCtxByName[tier])\n .filter(Boolean);\n\n // Semantic recall: pull in long-term memory + past messages relevant to this turn.\n // Skip messages from the current thread that are already in the windowed history.\n // Capped at RECALL_BUDGET_MS — if the embedding round-trip is slower than\n // that the LLM stream starts without recall hits rather than letting the\n // user stare at an idle screen waiting on a network call.\n const oldestInWindow = history.length > 0 ? contentText(history[0].content) : null;\n const recallCtx = await raceWithBudget(\n buildRecallContext(thread_id, trimmed, oldestInWindow),\n RECALL_BUDGET_MS,\n \"\",\n );\n const adaptivePersonaCtx = buildAdaptivePersonaContext(agentCfg, trimmed);\n const harnessParts = resolveHarness(agentCfg);\n\n const systemParts = [\n agentCfg.identity,\n agentCfg.instructions,\n adaptivePersonaCtx,\n userCtx,\n integrationsCtx,\n harnessParts.capabilities,\n harnessParts.plan_first,\n harnessParts.presentation,\n harnessParts.citation,\n timeCtx,\n envCtx,\n harnessParts.self_config,\n experienceCtx,\n memoryCtx,\n ...tierOrderCtx,\n recallCtx,\n ].filter(Boolean);\n let allowedTools: string[] = [];\n try {\n allowedTools = JSON.parse(agentCfg.tools) as string[];\n } catch { /* keep empty */ }\n\n const streamOpts: StreamOptions = {\n ...options,\n agent_run_config: {\n system_prompt: systemParts.join(\"\\n\\n\"),\n allowed_tools: allowedTools,\n model_config_name: agentCfg.model_config_name ?? null,\n },\n };\n\n const rawStream = streamWithConfig(thread_id, history, streamOpts, signal);\n return {\n stream: stallRetryStream(rawStream, thread_id, options, signal, _stallRetriesLeft, allowedTools),\n thread_id,\n };\n}\n\nasync function buildWarmSummaryContext(\n allWindowMessages: readonly { role: string; content: string }[],\n hotCount: number,\n providerName: string | undefined,\n modelId: string | undefined,\n providerParams: ProviderParams,\n warmBudgetTokens: number,\n): Promise<string> {\n if (warmBudgetTokens <= 32) return \"\";\n if (!providerName || !modelId) return \"\";\n const warmMessages = allWindowMessages.slice(0, Math.max(0, allWindowMessages.length - hotCount));\n if (warmMessages.length < 2) return \"\";\n\n // Keep summary input bounded by the warm budget to avoid recursive prompt bloat.\n const summaryInputChars = Math.max(0, warmBudgetTokens * 4);\n const transcript = warmMessages\n .map((m) => `${m.role === \"user\" ? \"User\" : \"Assistant\"}: ${transcriptText(m.content)}`)\n .join(\"\\n\\n\")\n .slice(-summaryInputChars);\n if (!transcript.trim()) return \"\";\n\n try {\n const provider = getProvider(providerName);\n const summary = await summarizeTranscript(provider, modelId, providerParams, transcript);\n if (!summary) return \"\";\n return [\n \"--- Warm context summary ---\",\n \"Compressed recap of earlier messages outside the hot window:\",\n summary,\n ].join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\nfunction buildFactsContext(query: string, factsBudgetTokens: number): string {\n if (factsBudgetTokens <= 16) return \"\";\n const charBudget = factsBudgetTokens * 4;\n const rows = listMemory(\"facts\", query.slice(0, 120), 12);\n if (rows.length === 0) return \"\";\n\n const lines = [\n \"--- Facts memory ---\",\n \"Durable fact entries from memory_store namespace=facts:\",\n ];\n let used = 0;\n for (const row of rows) {\n const line = `- ${row.key}: ${String(row.value).slice(0, 220)}`;\n if (used > 0 && used + line.length > charBudget) break;\n lines.push(line);\n used += line.length;\n }\n return lines.length > 2 ? lines.join(\"\\n\") : \"\";\n}\n\n// Wraps the raw agent stream with stall-retry logic. Chunks pass through\n// LIVE to the consumer (so the chat UI sees deltas as they arrive); we only\n// hold the terminal `done` chunk so we can decide whether to retry. If the\n// completed turn produced no tool calls AND the assistant text matches a\n// \"one moment\"-style stall pattern, we inject a forceful nudge as a\n// synthetic user message and forward the retry stream's chunks too. The\n// stalled prose stays visible (already streamed) and a \"↻\" separator marks\n// the boundary; the consumer's text/tool accumulator naturally captures\n// both halves into a single combined assistant message.\nasync function* stallRetryStream(\n inner: AsyncIterable<StreamChunk>,\n thread_id: string,\n options: StreamOptions | undefined,\n signal: AbortSignal | undefined,\n retriesLeft: number,\n allowedTools: readonly string[],\n): AsyncGenerator<StreamChunk> {\n // If no retry budget, just forward everything unchanged. The downstream\n // persistAssistantMessage will still tag a stall or fabrication with a\n // warning footer.\n if (retriesLeft <= 0) {\n for await (const chunk of inner) yield chunk;\n return;\n }\n\n let textBuf = \"\";\n const toolNames: string[] = [];\n let doneChunk: StreamChunk | null = null;\n let sawError = false;\n\n for await (const chunk of inner) {\n if (chunk.type === \"text_delta\") {\n const d = (chunk.data as { delta?: unknown } | undefined)?.delta;\n if (typeof d === \"string\") textBuf += d;\n yield chunk;\n } else if (chunk.type === \"tool_call\") {\n const name = (chunk.data as { name?: unknown } | undefined)?.name;\n if (typeof name === \"string\" && name) toolNames.push(name);\n yield chunk;\n } else if (chunk.type === \"done\") {\n // Hold the terminal marker — if we retry, the retry's `done` closes\n // the turn instead.\n doneChunk = chunk;\n break;\n } else if (chunk.type === \"error\") {\n sawError = true;\n yield chunk;\n return;\n } else {\n yield chunk;\n }\n }\n\n const stalled =\n !sawError &&\n toolNames.length === 0 &&\n textBuf.trim().length > 0 &&\n looksLikeStall(textBuf.trim());\n\n // Fabrication check (ADR-0037): only run when the stall path didn't claim\n // this turn — stall-retry already handles zero-tool stall-prose turns.\n const fabrication = !sawError && !stalled\n ? validateAssistantOutput(textBuf, toolNames, allowedTools)\n : ({ ok: true } as const);\n\n if (!stalled && fabrication.ok) {\n if (doneChunk) yield doneChunk;\n return;\n }\n\n // Visible separator between the stalled prose and the retry continuation,\n // so the user can see something is being re-attempted.\n yield { type: \"text_delta\", data: { delta: \"\\n\\n↻ \" } };\n\n // Inject a forceful nudge as a synthetic user message so the model sees\n // its own flagged reply + an instruction to continue. Stall and fabrication\n // get distinct, reason-aware nudges.\n const nudge = stalled\n ? \"\\u21bb Auto-retry: your previous reply ended with a 'one moment' style promise but you didn't call any tool, which ends the turn with nothing happening. Continue the original task NOW by invoking the appropriate tool. Do not acknowledge, do not apologize \\u2014 just call the tool.\"\n : `\\u21bb Auto-retry: output validator flagged your reply. ${\"reason\" in fabrication ? fabrication.reason : \"\"} Redo this turn without the false claim \\u2014 either call the actual tool, or rephrase as a proposal/question.`;\n\n const retry = await prepareThreadRun(\n thread_id,\n nudge,\n options,\n undefined,\n signal,\n retriesLeft - 1,\n );\n for await (const chunk of retry.stream) yield chunk;\n}\n\nexport function persistAssistantMessage(\n thread_id: string,\n content: string,\n usedTools?: readonly string[],\n toolEvents?: readonly PersistedToolEvent[],\n category: string | null = null,\n): void {\n const trimmed = content.trim();\n // Append a small, persistent footer listing which tools actually ran this\n // turn. Without this, tool_call events are live-only UI — after the stream\n // ends (or on page reload, or if a mobile client missed the brief render)\n // the assistant text remains saying \"I scheduled X\" with no proof a tool\n // ran, which reads as a hallucination even when the tool did execute.\n let final = trimmed;\n const toolList = usedTools ? Array.from(new Set(usedTools.filter(Boolean))) : [];\n // Stall detector: model ended its turn with a \"one moment\" / \"let me check\"\n // promise but invoked no tool. The system prompt forbids this, but models\n // occasionally do it anyway. Marking the message inline gives the user a\n // concrete next-step (\"type continue\") instead of staring at silence.\n if (toolList.length === 0 && trimmed && looksLikeStall(trimmed)) {\n final = `${trimmed}\\n\\n*⚠️ Agent stalled — promised a next step but did not invoke any tool. Reply \"continue\" to retry.*`;\n } else if (toolList.length > 0) {\n final = `${trimmed}\\n\\n*— used: ${toolList.join(\", \")}*`;\n }\n // Fabrication footer (ADR-0037): runs after the retry budget is exhausted\n // and a flagged reply still made it through. Look up allowed tools from\n // the agent config so callers don't have to thread it through.\n if (trimmed && !final.includes(\"*⚠️ Agent stalled\")) {\n const allowedTools = lookupAllowedToolsForThread(thread_id);\n const v = validateAssistantOutput(trimmed, toolList, allowedTools);\n if (!v.ok) {\n final = `${final}\\n\\n*⚠️ Output validator flagged: ${v.reason}*`;\n }\n }\n // Cap individual tool payloads so a single 64KB file_read result doesn't\n // make every reload of this thread re-download a giant blob. Keep the\n // first ~8KB — enough to be useful, small enough to be cheap.\n const sanitizedEvents = toolEvents && toolEvents.length > 0\n ? toolEvents.map(capToolEventPayload)\n : null;\n // Strip the `?autoplay=1` hint that generate_voice embeds in /api/v1/files\n // URLs before persistence. Autoplay is a transient signal for the live\n // streaming client only — reloading the thread, scrolling back, or opening\n // the conversation from another browser must not replay TTS clips the user\n // has already heard.\n const persisted = stripAutoplayHints(final);\n if (persisted || (sanitizedEvents && sanitizedEvents.length > 0)) {\n addMessage(thread_id, \"assistant\", persisted, sanitizedEvents, category);\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n recordToolUsage(sanitizedEvents, persisted);\n }\n }\n}\n\n// Removes `autoplay=1` from /api/v1/files/*.{wav,mp3,...} URLs that appear in\n// the assistant text. Handles it as the sole query param (`?autoplay=1`) or\n// combined with others (`?foo=bar&autoplay=1`, `?autoplay=1&foo=bar`).\nfunction stripAutoplayHints(text: string): string {\n if (!text || !text.includes(\"autoplay=1\")) return text;\n return text.replace(\n /(\\/api\\/v1\\/files\\/[^\\s)\"']+?\\.(?:wav|mp3|ogg|webm|m4a))(\\?[^\\s)\"']*)/gi,\n (_full, base: string, query: string) => {\n const cleaned = query\n .replace(/[?&]autoplay=1\\b/g, \"\")\n .replace(/^&/, \"?\");\n return cleaned === \"?\" || cleaned === \"\" ? base : `${base}${cleaned}`;\n },\n );\n}\n\nconst MAX_PERSISTED_PAYLOAD_BYTES = 8_000;\n\nfunction capToolEventPayload(ev: PersistedToolEvent): PersistedToolEvent {\n try {\n const serialized = JSON.stringify(ev.payload);\n if (serialized.length <= MAX_PERSISTED_PAYLOAD_BYTES) return ev;\n return {\n ...ev,\n payload: {\n __truncated: true,\n preview: serialized.slice(0, MAX_PERSISTED_PAYLOAD_BYTES),\n original_bytes: serialized.length,\n },\n };\n } catch {\n return { ...ev, payload: { __truncated: true, error: \"unserializable\" } };\n }\n}\n\nconst STALL_PATTERNS: RegExp[] = [\n /\\bone (moment|sec(?:ond)?)\\b/i,\n /\\bgive me (a|just a) (moment|sec(?:ond)?|minute)\\b/i,\n /\\bhold on\\b/i,\n /\\bjust a (moment|sec(?:ond)?|minute)\\b/i,\n /\\bbear with me\\b/i,\n /\\blet me (check|verify|continue|proceed|look|try|do (?:that|this|it))\\b/i,\n /\\bi['’]?ll (check|verify|continue|proceed|look|try|do (?:that|this|it)|keep going|get (?:on|right) (?:on|to))/i,\n /\\b(continuing|proceeding|working on it|moving on)\\b.*[!.]?\\s*$/i,\n];\n\n// Resolve the agent's allowed_tools list from a thread id. Best-effort: empty\n// list if the thread or agent config has gone away (the validator then\n// flags any `(via foo)` citation as unregistered, which is the safe default).\nfunction lookupAllowedToolsForThread(thread_id: string): string[] {\n try {\n const thread = getThread(thread_id);\n if (!thread) return [];\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) return [];\n const parsed = JSON.parse(agentCfg.tools) as unknown;\n return Array.isArray(parsed) ? parsed.filter((t): t is string => typeof t === \"string\") : [];\n } catch {\n return [];\n }\n}\n\nexport function looksLikeStall(text: string): boolean {\n // Inspect the last paragraph / sentence \\u2014 earlier acknowledgment\n // language is fine when followed by real work. The stall signal is when\n // the message ends on a promise.\n const tail = text.split(/\\n{2,}|(?<=[.!?])\\s+/).filter(Boolean).slice(-2).join(\" \");\n return STALL_PATTERNS.some((re) => re.test(tail));\n}\n\n// Run semantic recall on the user's turn, format the top hits as a system-prompt\n// block. Empty string when no embeddings configured or no good matches.\nasync function buildRecallContext(\n current_thread_id: string,\n query: string,\n windowOldestContent: string | null,\n): Promise<string> {\n if (!query.trim()) return \"\";\n let hits: RecalledMemory[];\n try {\n hits = await recall(query, 6);\n } catch {\n return \"\";\n }\n if (hits.length === 0) return \"\";\n\n // Drop matches that already live in the in-prompt history window.\n const filtered = hits.filter((h) => {\n if (h.source === \"message\" && h.thread_id === current_thread_id) {\n // crude but cheap: skip if it's the same content as anything in the window\n return windowOldestContent !== h.content;\n }\n return true;\n });\n if (filtered.length === 0) return \"\";\n\n const lines = [\n \"--- Your retrieved memory for this turn ---\",\n \"These entries were pulled from YOUR own memory store (not user-supplied just now).\",\n \"Treat them as facts you previously committed to remember. Cite them confidently when relevant.\",\n \"\",\n ];\n for (const h of filtered) {\n const stamp = h.created_at.slice(0, 10);\n if (h.source === \"memory\") {\n lines.push(`• [memory ${h.namespace}/${h.key}, ${stamp}] ${truncate(h.content, 280)}`);\n } else {\n const tag = h.thread_id === current_thread_id ? \"earlier this thread\" : \"past chat\";\n lines.push(`• [${tag} · ${h.role}, ${stamp}] ${truncate(h.content, 280)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction truncate(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length > max ? flat.slice(0, max) + \"…\" : flat;\n}\n\nexport function shouldEmitChunk(\n chunkType: StreamChunk[\"type\"],\n options?: StreamOptions,\n): boolean {\n const includeTools = options?.filters?.include_tools ?? true;\n const includeThinking = options?.filters?.include_thinking ?? true;\n if (!includeTools && (chunkType === \"tool_call\" || chunkType === \"tool_result\")) return false;\n if (!includeThinking && chunkType === \"thinking_delta\") return false;\n return true;\n}\n\nexport { contentText };\n","// ADR-0028. In-process script registry for ScriptFiring.\n//\n// Trust model: only built-ins are registered, in code, at module load\n// time. There is NO mechanism to register a script from DB, user input,\n// or shell-out — `script` on a ScriptFiring is just a key into this\n// map. This keeps scripted triggers safe even though they bypass the\n// LLM/thread machinery that gates prompt firings.\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface ScriptResult {\n /** Short, single-line summary suitable for telemetry / logs. */\n preview: string;\n}\n\nexport type ScriptFn = (args: Record<string, unknown>) => Promise<ScriptResult>;\n\ninterface ScriptRegistryState {\n scripts: Map<string, ScriptFn>;\n}\n\nconst state = getOrCreateGlobal<ScriptRegistryState>(\n \"__jarela_trigger_scripts\",\n () => ({ scripts: new Map() }),\n);\n\nexport function registerScript(name: string, fn: ScriptFn): void {\n // Idempotent re-registration is fine — HMR and repeated module imports\n // in dev re-execute the registration calls. We just overwrite with the\n // latest function, matching the trigger handler registry's behaviour.\n state.scripts.set(name, fn);\n}\n\nexport function getScript(name: string): ScriptFn | undefined {\n return state.scripts.get(name);\n}\n\nexport function listScripts(): string[] {\n return Array.from(state.scripts.keys()).sort();\n}\n\n// ADR-0031 — names beginning with this prefix are user-attachable\n// reaction scripts. Internal plumbing scripts (e.g.\n// `documents.reindex_local_file`) live under other namespaces and are\n// excluded so the watcher schedule surface can't accidentally invoke\n// them.\nexport const REACTION_SCRIPT_PREFIX = \"reaction.\";\n\nexport function listReactionScripts(): string[] {\n return listScripts().filter((n) => n.startsWith(REACTION_SCRIPT_PREFIX));\n}\n\nexport function isReactionScript(name: string): boolean {\n return name.startsWith(REACTION_SCRIPT_PREFIX) && state.scripts.has(name);\n}\n\n/** Test-only helper. */\nexport function __resetScriptRegistry(): void {\n state.scripts.clear();\n}\n","// Encrypted-at-rest secrets for external tools (ADR-0023).\n//\n// External tools declare secret \"slots\" in their module.exports:\n// secrets: [{ key: \"api_key\", label: \"OpenWeather API key\", required: true }]\n//\n// Values are persisted in the `tool-secrets` namespace of the memory store\n// (which is flagged sensitive in lib/crypto/sensitive.ts, so envelope\n// encryption applies — same primitive as the integrations store).\n//\n// Keys are stored as `<toolName>:<slotKey>`. Tool names and slot keys are\n// validated to a conservative character set so they can't collide with the\n// namespace delimiter or smuggle SQL/JSON metacharacters.\n//\n// Note on isolation: external tools run in-process with full Node privileges\n// (ADR-0013), so a malicious tool could read another tool's secrets by going\n// around this API (e.g. directly opening the SQLite file). The per-tool\n// scoping here is a *convention* surfaced through `ctx.getSecret`, not a\n// sandbox boundary.\n\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nconst NAMESPACE = \"tool-secrets\";\nconst NAME_RE = /^[a-z0-9_-]+$/i;\n\nexport interface ToolSecretSlot {\n key: string;\n label?: string;\n required?: boolean;\n description?: string;\n}\n\nfunction validName(s: string): boolean {\n return typeof s === \"string\" && s.length > 0 && s.length <= 64 && NAME_RE.test(s);\n}\n\nfunction compoundKey(toolName: string, key: string): string {\n return `${toolName}:${key}`;\n}\n\nfunction parseStored(raw: string): string | null {\n try {\n const v = JSON.parse(raw);\n return typeof v === \"string\" ? v : null;\n } catch {\n return null;\n }\n}\n\nexport function getToolSecret(toolName: string, key: string): string | null {\n if (!validName(toolName) || !validName(key)) return null;\n const row = getMemory(NAMESPACE, compoundKey(toolName, key));\n if (!row) return null;\n return parseStored(row.value);\n}\n\nexport function setToolSecret(toolName: string, key: string, value: string): void {\n if (!validName(toolName)) throw new Error(`invalid tool name: ${toolName}`);\n if (!validName(key)) throw new Error(`invalid secret key: ${key}`);\n if (typeof value !== \"string\") throw new Error(\"secret value must be a string\");\n putMemory(NAMESPACE, compoundKey(toolName, key), value);\n}\n\nexport function deleteToolSecret(toolName: string, key: string): boolean {\n if (!validName(toolName) || !validName(key)) return false;\n return deleteMemory(NAMESPACE, compoundKey(toolName, key));\n}\n\n// Returns which declared slots have a value persisted. Never returns the\n// plaintext — that only escapes via `ctx.getSecret` inside the tool's own\n// run loop.\nexport function describeToolSecrets(\n toolName: string,\n slots: ToolSecretSlot[],\n): Array<ToolSecretSlot & { is_set: boolean }> {\n if (!validName(toolName)) return slots.map((s) => ({ ...s, is_set: false }));\n return slots.map((s) => ({\n ...s,\n is_set: getToolSecret(toolName, s.key) !== null,\n }));\n}\n\n// Delete every persisted secret for a tool — used when an external tool\n// file is removed and the operator wants to clear stale credentials.\nexport function purgeToolSecrets(toolName: string): number {\n if (!validName(toolName)) return 0;\n const prefix = `${toolName}:`;\n const rows = listMemory(NAMESPACE, undefined, 1000).filter((r) =>\n r.key.startsWith(prefix),\n );\n let n = 0;\n for (const r of rows) {\n if (deleteMemory(NAMESPACE, r.key)) n++;\n }\n return n;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { embedOne } from \"@/lib/embeddings\";\n\nconst now = () => new Date().toISOString();\n\n// Explicit column list for message reads — omits `embedding` (~20KB of\n// JSON-encoded float[] per row) which only the embeddings module reads.\n// Avoids dragging it through the chat-history result set on every call.\nconst MSG_COLS_SQL = \"SELECT msg_id, thread_id, role, content, created_at, tool_events, category FROM messages\";\n\nexport interface ThreadRow {\n thread_id: string; agent_id: string; title: string | null;\n created_at: string; updated_at: string; message_count: number;\n}\nexport interface MessageRow {\n msg_id: string; thread_id: string; role: string; content: string; created_at: string;\n // JSON-encoded array of PersistedToolEvent. null when no tool work happened\n // on this turn or for user messages. Read back by the chat UI so historical\n // bubbles show the same expandable CALL/RESULT entries as live streaming.\n tool_events?: string | null;\n // Non-null tags classify the message into a filterable group in the chat\n // panel (e.g. 'scheduled_task', 'bridge', 'synthetic'). NULL = ordinary\n // user/assistant chat content.\n category?: string | null;\n}\n\nexport interface PersistedToolEvent {\n id: string;\n phase: \"call\" | \"result\";\n name: string;\n payload: unknown;\n}\n\nexport function listThreads(limit = 50, offset = 0): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads ORDER BY updated_at DESC LIMIT ? OFFSET ?\")\n .all(limit, offset) as unknown as ThreadRow[];\n}\n\nexport function listThreadsByAgent(agent_id: string, limit = 50): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? ORDER BY updated_at DESC LIMIT ?\")\n .all(agent_id, limit) as unknown as ThreadRow[];\n}\n\nexport function getThread(thread_id: string): ThreadRow | null {\n return (getDb().prepare(\"SELECT * FROM threads WHERE thread_id=?\").get(thread_id) as unknown as ThreadRow) ?? null;\n}\n\nexport function createThread(agent_id: string, title?: string): ThreadRow {\n const t = now();\n const thread_id = randomUUID();\n getDb()\n .prepare(\"INSERT INTO threads (thread_id,agent_id,title,created_at,updated_at,message_count) VALUES (?,?,?,?,?,0)\")\n .run(thread_id, agent_id, title ?? null, t, t);\n return { thread_id, agent_id, title: title ?? null, created_at: t, updated_at: t, message_count: 0 };\n}\n\nexport function deleteThread(thread_id: string): boolean {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(thread_id);\n const r = db.prepare(\"DELETE FROM threads WHERE thread_id=?\").run(thread_id);\n return r.changes > 0;\n}\n\nexport function getMessages(thread_id: string): MessageRow[] {\n return getDb()\n .prepare(MSG_COLS_SQL + \" WHERE thread_id=? ORDER BY created_at ASC\")\n .all(thread_id) as unknown as MessageRow[];\n}\n\n// Pull the latest N messages within a time window. Used to build the LLM\n// context — keeps prompt size bounded as threads grow indefinitely.\n// limit: 0 or negative = unlimited\n// sinceISO: undefined = no time bound\n// Returns chronological order (oldest first) so it can be appended to the prompt directly.\nexport function getRecentMessagesWindow(\n thread_id: string,\n limit: number,\n sinceISO?: string,\n): MessageRow[] {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (sinceISO) {\n sql += \" AND created_at >= ?\";\n params.push(sinceISO);\n }\n sql += \" ORDER BY created_at DESC\";\n if (limit > 0) {\n sql += \" LIMIT ?\";\n params.push(limit);\n }\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n return rows.reverse();\n}\n\n// Forward-fetch — return messages strictly newer than `afterISO`, oldest\n// first, capped at `limit`. Used by the chat view to pull only the\n// freshly-persisted user+assistant pair after a run completes, instead of\n// re-fetching the whole most-recent page.\nexport function getMessagesAfter(\n thread_id: string,\n afterISO: string,\n limit = 50,\n): MessageRow[] {\n return getDb()\n .prepare(\n MSG_COLS_SQL +\n \" WHERE thread_id=? AND created_at > ? ORDER BY created_at ASC LIMIT ?\",\n )\n .all(thread_id, afterISO, limit) as unknown as MessageRow[];\n}\n\n// Pagination for the chat UI. Returns the latest N messages strictly older\n// than `beforeISO` (cursor). Caller passes the oldest already-loaded message's\n// created_at as the cursor; first page omits beforeISO.\nexport function getMessagesPage(\n thread_id: string,\n limit: number,\n beforeISO?: string,\n): { messages: MessageRow[]; has_more: boolean } {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (beforeISO) {\n sql += \" AND created_at < ?\";\n params.push(beforeISO);\n }\n sql += \" ORDER BY created_at DESC LIMIT ?\";\n params.push(limit + 1); // fetch one extra to detect if there's more\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n const has_more = rows.length > limit;\n return { messages: rows.slice(0, limit).reverse(), has_more };\n}\n\nexport function addMessage(\n thread_id: string,\n role: \"user\" | \"assistant\",\n content: string,\n toolEvents?: PersistedToolEvent[] | null,\n category: string | null = null,\n): MessageRow {\n const msg_id = randomUUID();\n const t = now();\n const db = getDb();\n const toolEventsJson = toolEvents && toolEvents.length > 0 ? JSON.stringify(toolEvents) : null;\n db.prepare(\"INSERT INTO messages (msg_id,thread_id,role,content,created_at,tool_events,category) VALUES (?,?,?,?,?,?,?)\")\n .run(msg_id, thread_id, role, content, t, toolEventsJson, category);\n db.prepare(\"UPDATE threads SET message_count=message_count+1 WHERE thread_id=?\").run(thread_id);\n // Best-effort: embed the message so semantic recall can pull it back later.\n // Skip empty / very short content (greetings have no useful signal).\n if (content.trim().length >= 12) {\n embedOne(content).then((vec) => {\n if (vec) {\n getDb().prepare(\"UPDATE messages SET embedding=? WHERE msg_id=?\").run(JSON.stringify(vec), msg_id);\n }\n }).catch(() => { /* logged in embeddings module */ });\n }\n return { msg_id, thread_id, role, content, created_at: t, tool_events: toolEventsJson, category };\n}\n\nexport function getOrCreateAgentThread(agentId: string): ThreadRow {\n const existing = getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? LIMIT 1\")\n .get(agentId) as ThreadRow | undefined;\n if (existing) return existing;\n return createThread(agentId);\n}\n\nexport function clearThreadMessages(threadId: string): void {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(threadId);\n db.prepare(\"UPDATE threads SET message_count=0, updated_at=? WHERE thread_id=?\")\n .run(new Date().toISOString(), threadId);\n}\n\nexport function touchThread(thread_id: string, firstMsg?: string): void {\n const t = now();\n getDb()\n .prepare(\"UPDATE threads SET updated_at=?, title=COALESCE(title,?) WHERE thread_id=?\")\n .run(t, firstMsg ? firstMsg.slice(0, 80) : null, thread_id);\n}\n","// Shared reaction-discriminator helpers for the watcher (ADR-0031) and\n// scheduled-task (ADR-0032) stores. Both schemas use the same\n// `reaction_kind` / `reaction_script` / `reaction_script_args` triple, so\n// validation lives here and is imported by both.\n\nimport { isReactionScript, REACTION_SCRIPT_PREFIX } from \"@/lib/triggers/scripts\";\n\nexport type ReactionKind = \"agent_prompt\" | \"script\";\n\nconst MAX_REACTION_PROMPT_CHARS = 4000;\nconst MAX_REACTION_SCRIPT_ARGS_CHARS = 4000;\n\n/**\n * Normalise a reaction-prompt input into the value we store. Treats\n * undefined / null / whitespace-only as \"no override\" → NULL. Throws when\n * the prompt exceeds 4000 characters (the firing-prompt budget).\n */\nexport function normaliseReactionPrompt(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"string\") {\n throw new Error(\"reaction_prompt must be a string\");\n }\n const trimmed = input.trim();\n if (!trimmed) return null;\n if (trimmed.length > MAX_REACTION_PROMPT_CHARS) {\n throw new Error(\n `reaction_prompt must be <= ${MAX_REACTION_PROMPT_CHARS} characters (got ${trimmed.length})`,\n );\n }\n return trimmed;\n}\n\n/**\n * Validate a reaction-script name: must start with the `reaction.` prefix\n * AND be registered in the in-process script registry. Validated at write\n * time so a bad name is rejected by the agent tool / HTTP route, not by\n * the scheduler tick.\n */\nexport function validateReactionScript(name: unknown): string {\n if (typeof name !== \"string\" || !name.trim()) {\n throw new Error(\"reaction_script must be a non-empty string\");\n }\n const trimmed = name.trim();\n if (!trimmed.startsWith(REACTION_SCRIPT_PREFIX)) {\n throw new Error(\n `reaction_script must begin with \"${REACTION_SCRIPT_PREFIX}\" — got \"${trimmed}\"`,\n );\n }\n if (!isReactionScript(trimmed)) {\n throw new Error(`reaction_script \"${trimmed}\" is not registered`);\n }\n return trimmed;\n}\n\n/**\n * Normalise reaction-script args into a JSON-encoded string suitable for\n * the DB column. undefined / null → NULL. Anything else must be a plain\n * object that JSON-encodes to <= 4000 chars.\n */\nexport function normaliseReactionScriptArgs(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"reaction_script_args must be a JSON object\");\n }\n const json = JSON.stringify(input);\n if (json.length > MAX_REACTION_SCRIPT_ARGS_CHARS) {\n throw new Error(\n `reaction_script_args JSON must be <= ${MAX_REACTION_SCRIPT_ARGS_CHARS} chars (got ${json.length})`,\n );\n }\n return json;\n}\n\nexport interface ResolvedReaction {\n kind: ReactionKind;\n prompt: string | null;\n script: string | null;\n scriptArgs: string | null;\n}\n\n/**\n * Apply the discriminated-union rules for the reaction columns:\n * kind='script' → prompt forced NULL; script + scriptArgs validated.\n * kind='agent_prompt' → script + scriptArgs forced NULL; prompt normalised.\n * Centralised so create/update paths in both stores share one source of\n * truth for the union semantics.\n */\nexport function resolveReaction(input: {\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}): ResolvedReaction {\n const kind: ReactionKind = input.reaction_kind ?? \"agent_prompt\";\n if (kind === \"script\") {\n if (!input.reaction_script) {\n throw new Error(\"reaction_kind='script' requires reaction_script\");\n }\n return {\n kind,\n prompt: null,\n script: validateReactionScript(input.reaction_script),\n scriptArgs: normaliseReactionScriptArgs(input.reaction_script_args ?? null),\n };\n }\n return {\n kind,\n prompt: normaliseReactionPrompt(input.reaction_prompt),\n script: null,\n scriptArgs: null,\n };\n}\n","// Watcher store (ADR-0027). Sibling to lib/stores/scheduled-tasks.ts;\n// shape mirrors it so the UI + trigger plumbing can treat them as\n// near-equivalents apart from the diff-aware fields.\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n resolveReaction,\n validateReactionScript,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\n// Re-export so existing imports of these helpers from `@/lib/stores/watchers`\n// keep working (back-compat for tests + any historical call site).\nexport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n validateReactionScript,\n type ReactionKind,\n};\n\nexport interface WatcherRow {\n id: string;\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args: string; // JSON-encoded record passed to the tool\n interval_seconds: number;\n last_fingerprint: string | null;\n last_result: string | null; // stringified previous tool output, for the diff prompt\n last_run_at: string | null; // ISO — most recent poll, regardless of whether it fired\n last_fired_at: string | null; // ISO — most recent firing (i.e. fingerprint changed)\n last_error: string | null;\n next_run_at: string; // ISO\n enabled: number; // 0 | 1\n silent: number; // 0 | 1\n reaction_prompt: string | null; // ADR-0030: user-supplied directive; NULL = default\n reaction_kind: ReactionKind; // ADR-0031\n reaction_script: string | null; // ADR-0031: registry key when reaction_kind='script'\n reaction_script_args: string | null; // ADR-0031: JSON-encoded args bag\n created_at: string;\n updated_at: string;\n}\n\nconst MIN_INTERVAL_SECONDS = 60;\nconst now = () => new Date().toISOString();\n\nexport function clampInterval(seconds: number): number {\n if (!Number.isFinite(seconds)) throw new Error(\"interval_seconds must be a finite number\");\n const n = Math.floor(seconds);\n if (n < MIN_INTERVAL_SECONDS) {\n throw new Error(`interval_seconds must be >= ${MIN_INTERVAL_SECONDS}`);\n }\n return n;\n}\n\nexport interface CreateWatcherInput {\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args?: Record<string, unknown>;\n interval_seconds: number;\n silent?: boolean;\n // ADR-0030 / ADR-0031: only one reaction is active per watcher.\n // - kind 'agent_prompt' (default): reaction_prompt is the optional directive.\n // - kind 'script': reaction_script + reaction_script_args drive a script firing.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createWatcher(input: CreateWatcherInput): WatcherRow {\n const id = randomUUID();\n const t = now();\n const interval = clampInterval(input.interval_seconds);\n // Schedule the very first poll for `interval` seconds from now. The\n // agent-facing tool description tells the agent to call list_watchers\n // or wait one cycle; we don't fire immediately to avoid stampedes\n // when an agent registers a watcher.\n const next = new Date(Date.now() + interval * 1000).toISOString();\n const argsJson = JSON.stringify(input.tool_args ?? {});\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction(input);\n getDb()\n .prepare(\n `INSERT INTO watchers\n (id, agent_id, label, tool_name, tool_args, interval_seconds,\n last_fingerprint, last_result, last_run_at, last_fired_at, last_error,\n next_run_at, enabled, silent, reaction_prompt,\n reaction_kind, reaction_script, reaction_script_args,\n created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, NULL, NULL, NULL, NULL, NULL, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, input.label, input.tool_name, argsJson, interval, next, silent,\n reaction.prompt, reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n label: input.label,\n tool_name: input.tool_name,\n tool_args: argsJson,\n interval_seconds: interval,\n last_fingerprint: null,\n last_result: null,\n last_run_at: null,\n last_fired_at: null,\n last_error: null,\n next_run_at: next,\n enabled: 1,\n silent,\n reaction_prompt: reaction.prompt,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listWatchers(agentId?: string): WatcherRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM watchers WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM watchers ORDER BY next_run_at ASC\").all();\n return rows as unknown as WatcherRow[];\n}\n\nexport function getWatcher(id: string): WatcherRow | null {\n const row = getDb().prepare(\"SELECT * FROM watchers WHERE id=?\").get(id);\n return (row as WatcherRow | undefined) ?? null;\n}\n\nexport function getDueWatchers(asOf: Date = new Date()): WatcherRow[] {\n return getDb()\n .prepare(\"SELECT * FROM watchers WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as WatcherRow[];\n}\n\nexport function deleteWatcher(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM watchers WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateWatcherInput {\n label?: string;\n interval_seconds?: number;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0030 / ADR-0031: a PATCH may swap the reaction kind. The semantics\n // mirror the create input — if reaction_kind is provided, the reaction is\n // fully replaced (the other branch's fields are forced NULL). If\n // reaction_kind is absent, only the matching field for the EXISTING kind\n // can be updated. undefined leaves a field alone; null clears it.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function updateWatcher(id: string, patch: UpdateWatcherInput): WatcherRow | null {\n const existing = getWatcher(id);\n if (!existing) return null;\n const t = now();\n const interval = patch.interval_seconds !== undefined\n ? clampInterval(patch.interval_seconds)\n : existing.interval_seconds;\n // Only recompute next_run_at when the interval changed; otherwise keep\n // the existing schedule so a label edit doesn't reset the cycle.\n const nextRunAt = patch.interval_seconds !== undefined\n ? new Date(Date.now() + interval * 1000).toISOString()\n : existing.next_run_at;\n\n // Compute the reaction columns. Two cases:\n // 1. patch.reaction_kind is set → fully resolve the patch as a new reaction.\n // 2. patch.reaction_kind is absent → keep the existing kind, but allow the\n // matching branch's field to be patched (e.g. update reaction_prompt\n // while staying in 'agent_prompt' kind).\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: patch.reaction_prompt,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n const prompt = patch.reaction_prompt === undefined\n ? existing.reaction_prompt\n : normaliseReactionPrompt(patch.reaction_prompt);\n reaction = { kind: \"agent_prompt\", prompt, script: null, scriptArgs: null };\n }\n\n getDb()\n .prepare(\n `UPDATE watchers\n SET label=?, interval_seconds=?, next_run_at=?, enabled=?, silent=?,\n reaction_prompt=?, reaction_kind=?, reaction_script=?, reaction_script_args=?,\n updated_at=?\n WHERE id=?`,\n )\n .run(\n patch.label ?? existing.label,\n interval,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n reaction.prompt,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getWatcher(id);\n}\n\n// Bookkeeping after a poll. Always advances next_run_at. `fired`\n// indicates the fingerprint changed; when false we still update\n// last_run_at + last_fingerprint (first run, or unchanged).\nexport function recordWatcherPoll(input: {\n id: string;\n fingerprint: string;\n result: string;\n fired: boolean;\n error?: string;\n}): void {\n const existing = getWatcher(input.id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers\n SET last_fingerprint=?, last_result=?, last_run_at=?,\n last_fired_at=COALESCE(?, last_fired_at),\n last_error=?, next_run_at=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n input.fingerprint,\n input.result,\n t,\n input.fired ? t : null,\n input.error ?? null,\n nextRunAt,\n t,\n input.id,\n );\n}\n\nexport function recordWatcherPollError(id: string, error: string): void {\n const existing = getWatcher(id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?`,\n )\n .run(t, error, nextRunAt, t, id);\n}\n"],"names":["getOrCreateGlobal","state","handlers","Map","registerTriggerHandler","handler","set","kind","getTriggerHandler","get","listTriggerHandlers","Array","from","values","__resetTriggerRegistry","clear","getOrCreateAgentThread","getAgentConfig","prepareThreadRun","persistAssistantMessage","collectStream","getScript","runTriggerAgent","firing","agent","agentId","status","preview","threadId","error","thread","category","effectivePrompt","silent","prompt","prepared","thread_id","undefined","collected","stream","replyText","assistantContent","trim","isNoReply","test","skipAssistant","length","usedTools","toolEvents","replace","slice","err","msg","Error","message","String","runTriggerScript","fn","script","result","args","runTriggerFiring","mode","getDueTasks","markTaskRan","getScheduledTask","publish","publishNotification","SCHEDULED_TASK_KIND","buildFiring","task","reaction_kind","reaction_script","userArgs","reaction_script_args","parsed","JSON","parse","isArray","id","agent_id","description","schedule","schedule_kind","meta","scheduleKind","scheduledTaskHandler","getDueFirings","asOf","map","markFired","outcome","type","task_id","ts","Date","now","scriptName","firingForTaskId","taskId","createHash","getDueWatchers","getWatcher","recordWatcherPoll","recordWatcherPollError","registeredTools","truncateBytes","WATCHER_KIND","fingerprint","s","update","digest","stringifyResult","value","stringify","DEFAULT_REACTION_DIRECTIVE","MAX_DIFF_CONTEXT_BYTES","normalizeForDiff","raw","buildDiffForPrompt","previous","current","prev","split","curr","start","prevEnd","currEnd","removed","added","hunkHeader","Math","max","l","join","bytes","Buffer","byteLength","clipped","truncated","text","buildFiringPrompt","watcher","argsPretty","tool_args","directive","reaction_prompt","label","tool_name","buildScriptArgs","safeJson","invokeWatcherTool","entry","find","t","name","e","invoke","pollDueWatchers","due","firings","fp","firstRun","last_fingerprint","changed","fired","push","last_result","console","watcherHandler","firingForWatcherIdNow","promises","fs","relative","sep","getDb","getDocumentSource","registerScript","ALLOWED_EXT","MAX_FILE_BYTES","hashContent","lowerExt","readTextFile","upsertLocalDocument","reindexLocalFile","source","source_id","db","stat","abs","code","info","prepare","run","changes","isFile","size","has","hash","existing","content_hash","floor","mtimeMs","toISOString","f","rel","path","mtime_ms","registered","registerDocumentScripts","sourceId","watch","fsWatch","listEnabledDocumentSources","SKIP_DIRS","FS_WATCH_KIND","DEBOUNCE_MS","watchers","pending","unsupportedLogged","Set","pendingKey","enqueuePending","scheduleDebounce","w","debounceTimers","clearTimeout","setTimeout","delete","unref","handleEvent","filename","segments","filter","i","seg","startsWith","file","rootPath","attachWatcher","st","isDirectory","recursive","persistent","_event","toString","on","warn","add","detachWatcher","close","syncWatchers","sources","wantSourceIds","keys","drainPending","fsWatchHandler","sync","stop","_asOf","__resetFsWatchState","__pushEventForTest","markSourceScanned","isRemoteKind","runRemoteSource","DOCUMENT_FAST_SWEEP_KIND","DEFAULT_INTERVAL_MS","intervalMs","process","env","JARELA_FAST_REMOTE_SWEEP_MS","n","Number","parseInt","isFinite","lastRunAt","scriptRegistered","registerSweepScript","stats","updated","unchanged","errors","documentFastSweepHandler","getTime","interval","last","__resetFastSweepState","shortPreview","cur","left","right","ctx","title","registerHandlers","startAllTriggerHandlers","stopAllTriggerHandlers","notifyTriggerHandlers","_reason","runTriggerTick","innerErr","runScheduledTaskFiringNow","runWatcherFiringNow","watcherId","listScripts","listReactionScripts","isReactionScript","REACTION_SCRIPT_PREFIX","GEMINI_VOICES","GEMINI_TTS_MODELS","GEMINI_STT_MODELS","getConfig","resolveGoogleApiKey","resolveGoogleApiKeyShared","timeoutSignal","ENDPOINT","geminiTts","opts","url","encodeURIComponent","model","apiKey","style","spoken","speakers","voiceName","speechConfig","multiSpeakerVoiceConfig","speakerVoiceConfigs","speaker","voiceConfig","prebuiltVoiceConfig","body","contents","role","parts","generationConfig","responseModalities","res","fetch","method","headers","signal","voiceTimeoutMs","json","ok","candidates","content","p","inline","inlineData","inline_data","data","mime","mimeType","mime_type","pcm","rate","parseSampleRate","wav","pcmToWav","Boolean","geminiStt","audio","m","exec","sampleRate","channels","bitsPerSample","byteRate","blockAlign","dataSize","header","alloc","write","writeUInt32LE","writeUInt16LE","concat","embedOne","cosine","searchDocuments","query","limit","min","trimmed","limitRows","rows","all","qVec","scored","lowered","toLowerCase","r","score","match","embedding","vec","substringScore","document_id","source_label","rel_path","abs_path","chunk_index","sort","a","b","haystack","needleLower","hay","includes","tokens","hits","indexAllSources","POLL_INTERVAL_MS","JARELA_SCHEDULER_TICK_MS","DOC_SWEEP_EVERY_TICKS","started","timer","running","tickCount","startScheduler","setImmediate","tick","setInterval","stopScheduler","clearInterval","runScheduledTaskNow","transcriptText","media_type","summaryMessages","transcript","summarizeTranscript","provider","modelId","providerParams","chat","summary","chunk","existsSync","readdirSync","statSync","tool","getToolSecret","getToolsDir","toolsDir","isValidSlot","v","o","key","required","isValid","schema","secrets","every","loadExternalTools","builtinNames","tools","categories","files","createRequire","getBuiltinModule","req","entries","seen","mod","cache","resolve","candidate","default","def","wrapped","_runManager","config","configurable","getSecret","terminal","onChunk","delta","d","phase","payload","arguments","errorMessage","z","getMemory","putMemory","listMemory","registerTools","memoryReadTool","namespace","row","object","string","describe","memoryWriteTool","memoryListTool","search","updated_at","optional","number","createDocumentSource","deleteDocumentSource","getDocumentSourceByPath","listDocumentSources","indexOnDemand","documentsSearch","h","toFixed","int","documentsListSources","enabled","last_scan_at","documentsAddLocalSource","inputPath","note","REMOTE_KINDS","syntheticPath","space_key","cql","project_key","jql","owner","repo","validateRemoteConfig","cfg","documentsAddRemoteSource","enum","record","unknown","documentsRemoveSource","confirm","documentsReindexSource","documentsIndexUrl","input","execSync","getInjectedSubprocessEnv","MAX_OUTPUT_BYTES","DEFAULT_TIMEOUT_MS","MAX_TIMEOUT_MS","BLOCKED_PATTERNS","isBlockedCommand","command","some","pattern","clipOutput","runLocalCommand","options","exit_code","stderr","timeout","timeout_ms","allow_unsafe","cwd","output","encoding","maxBuffer","stdio","stdout","out","errText","execSchema","boolean","localExecTool","shellExecTool","os","MAX_READ_BYTES","MAX_WRITE_BYTES","MAX_LIST_JSON_BYTES","clip","resolvePath","homedir","isAbsolute","isInside","parent","sensitiveBase","home","sensitiveFiles","jarelaDataDir","JARELA_DB_DIR","assertSafePath","op","JARELA_ALLOW_SENSITIVE_FILES","base","basename","endsWith","readSchema","start_line","end_line","fileReadTool","filePath","readFile","lineRange","lines","end","line_range","total_lines","writeSchema","create_dirs","fileWriteTool","mkdir","dirname","existed","access","writeFile","bytes_written","created","editSchema","old_string","new_string","fileEditTool","first","indexOf","second","match_count","next","bytes_before","bytes_after","moveSchema","destination","overwrite","fileMoveTool","srcAbs","dstAbs","srcStat","dstStat","rename","cp","force","errorOnExist","rm","cross_device","err2","listSchema","max_entries","include_hidden","fileListTool","dirPath","cap","items","readdir","withFileTypes","localeCompare","it","full","build","es","droppedForSize","count","total_in_dir_after_filters","truncated_hint","dropped_for_size","filters","lo","hi","mid","mkdirSchema","fileMkdirTool","deleteSchema","fileDeleteTool","targetPath","rmdir","unlink","copySchema","fileCopyTool","copyFile","statSchema","fileStatTool","exists","modified_ms","created_ms","birthtimeMs","tavilySearch","api_key","max_results","search_depth","results","snippet","UA_POOL","ddgSearch","lastStatus","attempt","ua","html","parseDDGHtml","Promise","blockRe","block","titleMatch","snippetMatch","unwrapDDGRedirect","decodeHTML","stripTags","href","u","URL","hostname","pathname","real","searchParams","decodeURIComponent","webSearchTool","tavilyKey","TAVILY_API_KEY","total","dns","net","ipv4InCidr","addr","prefix","bits","mask","ipv4ToNumber","ip","part","isInteger","classifyIPv4","classifyIPv6","bare","v4","isIPv4","classifyAddress","isIPv6","isPrivateAddress","cls","checkPublicUrl","rawUrl","JARELA_ALLOW_PRIVATE_FETCH","allowed","reason","protocol","host","isIP","resolved","addrs","lookup","address","stripHtml","MAX_BYTES","TIMEOUT_MS","MAX_REDIRECTS","extractTitle","extractImages","baseUrl","og","twitter","samples","matchAll","src","resolveUrl","webFetchTool","max_chars","ctrl","AbortController","abort","initialCheck","currentUrl","hop","redirect","loc","hopCheck","contentType","finalUrl","reader","getReader","decoder","TextDecoder","bytesRead","done","read","decode","cancel","wantHtml","images","content_type","bytes_read","getUserProfile","getUserLocationTool","profile","location_consent","available","how_to_enable","location_lat","location_lng","updatedAt","location_updated_at","ageMs","lat","lng","accuracy_m","location_accuracy_m","location_label","age_seconds","round","randomUUID","writeBinaryFile","DEFAULT_MODEL","callGemini","imageTimeoutMs","describeError","callImagen","aspect","instances","parameters","sampleCount","aspectRatio","preds","predictions","bytesBase64Encoded","cause","extForMime","generateImageTool","aspect_ratio","saved","img","markdown","hint","getThread","DEFAULT_VOICE","MAX_TEXT_CHARS","SpeakerSchema","voice_name","resolveAgentVoice","voice","voice_model","generateVoiceTool","autoplay","speakerList","array","createScheduledTask","listScheduledTasks","deleteScheduledTask","computeNextRun","agentIdFromConfig","scheduleTaskTool","when_iso","cron","next_run_at","listScheduledTasksTool","_args","tasks","last_run_at","last_error","cancelScheduledTaskTool","createWatcher","listWatchers","deleteWatcher","scheduleWatcherTool","toolName","every_seconds","target","interval_seconds","listReactionScriptsTool","scripts","listWatchersTool","safeParse","last_fired_at","cancelWatcherTool","createPendingAction","getPendingAction","proposeConfigChangeTool","proposal_id","checkProposalTool","created_at","decided_at","getManifest","listManifests","getIntegrationStatus","isKnownIntegration","manifestStatus","configured","listIntegrationsTool","integrations","getIntegrationSetupTool","manifest","prerequisites","steps","troubleshooting","notes","googleFetch","resolveGoogleAuth","CALENDAR_BASE","calendarFetch","auth","init","slimEvent","location","dateTime","date","time_zone","timeZone","attendees","email","displayName","response","responseStatus","meet_link","hangoutLink","html_link","htmlLink","calendarListCalendarsTool","calendars","c","primary","access_role","accessRole","calendarListEventsTool","calendar_id","time_min","time_max","cal","params","URLSearchParams","singleEvents","orderBy","maxResults","inAWeek","events","calendarGetEventTool","event_id","eid","calendarCreateEventTool","start_iso","end_iso","add_meet_link","conferenceData","createRequest","requestId","random","conferenceSolutionKey","calendarUpdateEventTool","patch","Object","calendarDeleteEventTool","graphFetch","resolveMicrosoftAuth","subject","bodyPreview","emailAddress","is_all_day","isAllDay","is_cancelled","isCancelled","show_as","showAs","teams_link","onlineMeeting","joinUrl","web_link","webLink","outlookCalendarListCalendarsTool","is_default","isDefaultCalendar","can_edit","canEdit","outlookCalendarListEventsTool","startISO","endISO","top","startDateTime","endDateTime","$top","$orderby","Prefer","outlookCalendarGetEventTool","outlookCalendarCreateEventTool","add_teams_link","tz","isOnlineMeeting","onlineMeetingProvider","outlookCalendarUpdateEventTool","outlookCalendarDeleteEventTool","convertToOpenAITool","registeredNames","registeredCategory","registeredGroup","getMcpTools","disabledCategories","ALL_BUILTINS","BUILTIN_TOOL_NAMES","loadExternal","getToolCategory","builtin","ext","getToolGroup","cat","applyPolicy","policy","allowSet","allow","denySet","deny","applyCategoryToggles","disabled","getAllTools","getAllToolsAsync","mcpTools","toOpenAITools","oai","function","executeTool","context","x","_initialized","initTools","builtinCount","externalCount","UPSERT_SQL","recordToolUsage","deltas","summarizeToolUsage","stamp","stmt","calls","successes","used","listToolStats","getToolStatsMap","names","toStats","defaultToolStats","call_count","success_count","error_count","used_count","success_rate","usefulness_rate","never_used","last_called_at","successRate","clamp01","usefulnessRate","byId","assistantTerms","normalizeText","ev","successful","isErrorPayload","payloadLooksUsed","totals","extractPayloadTerms","matched","term","stringifyPayload","unique","token","mkdirSync","writeFileSync","getDataDir","FILES_DIR","SAFE_NAME","isSafeFileName","fileAbsPath","isCategoryEnabled","listCategoryStates","setCategoryEnabled","getIntegrationRaw","ms","fromStore","GEMINI_API_KEY","GOOGLE_API_KEY","isUserPreset","upsertUserProfile","icon","about","setLocationConsent","consent","updateUserLocation","setUserPreset","preset","getAppName","getAppDescription","getAppIssueUrl","DEFAULTS","port","recursionLimit","parsePositiveInt","fallback","parsePort","cached","expandHome","dataDir","JARELA_PORT","PORT","JARELA_HOSTNAME","HOSTNAME","JARELA_TOOLS_DIR","JARELA_RECURSION_LIMIT","JARELA_VOICE_TIMEOUT_MS","JARELA_IMAGE_TIMEOUT_MS","appName","appDescription","issueUrl","resetConfigCache","CronExpressionParser","resolveReaction","validateReactionScript","normaliseReactionScriptArgs","after","isNaN","currentDate","toDate","reaction","scriptArgs","updateScheduledTask","nextKind","nextSchedule","nextRunAt","nextPrompt","nextRun","BaseChatModel","AIMessage","AIMessageChunk","isAIMessage","isHumanMessage","isSystemMessage","isToolMessage","ChatGenerationChunk","JarelaChatModel","fields","lc_namespace","lc_serializable","_provider","_modelId","_params","_boundTools","boundTools","_llmType","bindTools","_kwargs","_convertedTools","flatMap","_generate","messages","_options","runManager","invokeMessages","toInvokeMessages","openaiTools","streamInvoke","finalChunk","_streamToFinalChunk","gen","aiMessageFromChunk","generations","aiMsg","tool_calls","tc","providerMessages","acc","_streamFromProvider","_streamResponseChunks","tool_call_chunks","index","emittedAny","stopReason","event","handleLLMNewToken","additional_kwargs","reasoning_content","args_delta","empty_stream_reason","stop_reason","invalid_tool_calls","lcContentToInvoke","image_url","dataUrl","ai","invokeMsg","reasoning","tool_call_id","BaseStore","deleteMemory","SqliteMemoryStore","batch","operations","ns","_raw","createdAt","namespacePrefix","DatabaseSync","BaseCheckpointSaver","TASKS","copyCheckpoint","maxChannelVersion","VALID_FILTER_KEYS","buildLatestSelect","includeCheckpointId","nv","NodeSqliteSaver","serde","isSetup","fromConnString","connStringOrLocalPath","setup","withoutCheckpoint","withCheckpoint","txn","decodeRowState","pendingWrites","pending_writes","channel","loadsTyped","checkpoint","parent_checkpoint_id","migratePendingSends","metadata","getTuple","checkpoint_ns","checkpoint_id","finalConfig","parentConfig","list","before","sql","whereClause","sanitizedFilter","fromEntries","put","preparedCheckpoint","type1","serializedCheckpoint","type2","serializedMetadata","dumpsTyped","putWrites","writes","idx","serializedWrite","deleteThread","parentCheckpointId","pendingSendsJson","pending_sends","mutable","channel_values","channel_versions","getNextVersion","CHECKPOINT_PATH","_saver","getCheckpointer","createReactAgent","HumanMessage","SystemMessage","ToolMessage","getProvider","getModelConfig","getDefaultModelConfig","toBaseMessages","systemPrompt","blocks","streamWithConfig","runCfg","agent_run_config","cfgName","model_config_name","toolPolicy","allowed_tools","tool_policy","model_id","store","checkpointer","llm","announcedToolIds","pendingAIChunk","totalOutputTokens","truncatedByLength","needsParagraphBreak","textEmittedSinceLastBreak","flushPendingToolCalls","agentStream","system_prompt","streamMode","baseMsg","stack","causeChain","depth","cMsg","cCode","rawMsg","aborted","message_id","usage","input_tokens","output_tokens","friendly","firstAppFrame","MBTI_PRESETS","buildAdaptivePersonaContext","userMessage","adaptive_persona_enabled","mbti","toMbti","adaptive_mbti","mbtiLabel","strength","clampPercent","adaptive_persona_strength","empathy","adaptive_empathy","expressiveness","adaptive_expressiveness","verbosity","adaptive_verbosity","detectSignals","intensity","targetEmpathy","frustration","urgency","positivity","targetExpressive","targetVerbosity","empathyBand","bandLabel","expressiveBand","verbosityBand","directives","mood","lower","frustrationHits","countMatches","urgencyHits","positivityHits","terms","cutoffs","labels","getDefaultHarnessId","getHarness","getBuiltinHarness","DEFAULT_HARNESS_ID","HARNESS_SECTION_KEYS","resolveHarness","agentCfg","harness_id","harness","section","sections","ACTION_VERBS","VERB_GROUP","PATTERNS","RegExp","FUTURE_PATTERNS","findActionClaims","re","lastIndex","verb","window","VIA_RE","findCitations","SUMMARY_PATTERNS","validateAssistantOutput","toolCalls","allowedTools","calledSet","allowedSet","citations","evidence","claims","DEFAULT_CONTEXT_WINDOW_TOKENS","DEFAULT_OVERHEAD_TOKENS","DEFAULT_OUTPUT_RESERVE_RATIO","DEFAULT_TIER_PRIORITY","DEFAULT_TIER_PROPORTIONS","hot","warm","facts","estimateTokens","ceil","normalizeTierPriority","tiers","normalizeTierProportions","toPositiveNumber","sum","computeContextBudget","contextWindowTokens","context_window_tokens","outputReserveTokens","max_tokens","overheadTokens","inputBudgetTokens","proportions","context_tier_proportions","tierPriority","context_tier_priority","tierBudgets","takeRecentMessagesWithinBudget","tokenBudget","chosen","reverse","truncateLargestMessagesWithinBudget","reduce","needed","nextTokens","nextChars","suffix","trimEnd","formatContextBudgetSummary","budget","addMessage","getRecentMessagesWindow","touchThread","recall","listIntegrations","APP_NAME","RunThreadError","RECALL_BUDGET_MS","raceWithBudget","promise","settled","then","MAX_STALL_AUTO_RETRIES","parseContent","contentText","attachments","_stallRetriesLeft","userCategory","stored","history_limit","windowHours","history_window_hours","sinceISO","allWindowMessages","modelCfg","hotMessages","userProfile","userCtxParts","ageSec","ageStr","userCtx","timeCtx","experienceMode","ui_experience_mode","experienceCtx","envCtx","platform","arch","configuredIntegrations","integrationsCtx","memoryCtx","warmSummaryCtx","buildWarmSummaryContext","warmWasExpected","hotMessagesForPrompt","history","factsCtx","buildFactsContext","tierCtxByName","tierOrderCtx","tier","oldestInWindow","recallCtx","buildRecallContext","adaptivePersonaCtx","harnessParts","systemParts","identity","instructions","capabilities","plan_first","presentation","citation","self_config","streamOpts","rawStream","stallRetryStream","hotCount","providerName","warmBudgetTokens","warmMessages","summaryInputChars","factsBudgetTokens","charBudget","line","inner","retriesLeft","textBuf","toolNames","doneChunk","sawError","stalled","looksLikeStall","fabrication","nudge","retry","final","toolList","lookupAllowedToolsForThread","sanitizedEvents","capToolEventPayload","persisted","stripAutoplayHints","_full","cleaned","MAX_PERSISTED_PAYLOAD_BYTES","serialized","__truncated","original_bytes","STALL_PATTERNS","tail","current_thread_id","windowOldestContent","filtered","truncate","tag","flat","shouldEmitChunk","chunkType","includeTools","include_tools","includeThinking","include_thinking","__resetScriptRegistry","NAMESPACE","NAME_RE","validName","compoundKey","parseStored","setToolSecret","deleteToolSecret","describeToolSecrets","slots","is_set","purgeToolSecrets","MSG_COLS_SQL","listThreads","offset","listThreadsByAgent","createThread","message_count","getMessages","getMessagesAfter","afterISO","getMessagesPage","beforeISO","has_more","msg_id","toolEventsJson","catch","tool_events","clearThreadMessages","firstMsg","MAX_REACTION_PROMPT_CHARS","MAX_REACTION_SCRIPT_ARGS_CHARS","normaliseReactionPrompt","MIN_INTERVAL_SECONDS","clampInterval","seconds","argsJson","updateWatcher"],"sourceRoot":"","ignoreList":[]}
1
+ {"version":3,"file":"7885.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/triggers/registry.ts","webpack://@circuitwall/jarela/./lib/triggers/runner.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/scheduled-task.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/watcher.ts","webpack://@circuitwall/jarela/./lib/documents/reindex-local-file.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/fs-watch.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/document-fast-sweep.ts","webpack://@circuitwall/jarela/./lib/triggers/reactions/notify.ts","webpack://@circuitwall/jarela/./lib/triggers/index.ts","webpack://@circuitwall/jarela/./lib/voice/constants.ts","webpack://@circuitwall/jarela/./lib/voice/gemini.ts","webpack://@circuitwall/jarela/./lib/documents/search.ts","webpack://@circuitwall/jarela/./lib/scheduler/index.ts","webpack://@circuitwall/jarela/./lib/agents/conversation-summary.ts","webpack://@circuitwall/jarela/./lib/tools/external.ts","webpack://@circuitwall/jarela/./lib/agents/stream-collector.ts","webpack://@circuitwall/jarela/./lib/tools/memory.ts","webpack://@circuitwall/jarela/./lib/tools/documents.ts","webpack://@circuitwall/jarela/./lib/tools/exec.ts","webpack://@circuitwall/jarela/./lib/tools/files.ts","webpack://@circuitwall/jarela/./lib/tools/search.ts","webpack://@circuitwall/jarela/./lib/utils/private-ip.ts","webpack://@circuitwall/jarela/./lib/tools/fetch.ts","webpack://@circuitwall/jarela/./lib/tools/location.ts","webpack://@circuitwall/jarela/./lib/tools/generate_image.ts","webpack://@circuitwall/jarela/./lib/tools/generate_voice.ts","webpack://@circuitwall/jarela/./lib/tools/schedule.ts","webpack://@circuitwall/jarela/./lib/tools/watcher.ts","webpack://@circuitwall/jarela/./lib/tools/propose.ts","webpack://@circuitwall/jarela/./lib/tools/integrations.ts","webpack://@circuitwall/jarela/./lib/tools/calendar.ts","webpack://@circuitwall/jarela/./lib/tools/outlook-calendar.ts","webpack://@circuitwall/jarela/./lib/tools/builtins.ts","webpack://@circuitwall/jarela/./lib/tools/index.ts","webpack://@circuitwall/jarela/./lib/stores/tool-stats.ts","webpack://@circuitwall/jarela/./lib/files.ts","webpack://@circuitwall/jarela/./lib/stores/builtin-tools.ts","webpack://@circuitwall/jarela/./lib/utils/google-api.ts","webpack://@circuitwall/jarela/./lib/stores/user-profile.ts","webpack://@circuitwall/jarela/./lib/env/config.ts","webpack://@circuitwall/jarela/./lib/stores/scheduled-tasks.ts","webpack://@circuitwall/jarela/./lib/providers/jarela-chat-model.ts","webpack://@circuitwall/jarela/./lib/stores/langgraph-store.ts","webpack://@circuitwall/jarela/./lib/agents/sqlite-checkpoint-saver.ts","webpack://@circuitwall/jarela/./lib/agents/checkpointer.ts","webpack://@circuitwall/jarela/./lib/agents/llm.ts","webpack://@circuitwall/jarela/./lib/agents/adaptive-persona.ts","webpack://@circuitwall/jarela/./lib/agents/harness/resolve.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/claim-detector.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/citation-parser.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/validator.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/index.ts","webpack://@circuitwall/jarela/./lib/agents/context-budget.ts","webpack://@circuitwall/jarela/./lib/agents/run-thread.ts","webpack://@circuitwall/jarela/./lib/triggers/scripts.ts","webpack://@circuitwall/jarela/./lib/stores/tool-secrets.ts","webpack://@circuitwall/jarela/./lib/stores/threads.ts","webpack://@circuitwall/jarela/./lib/stores/reaction-shared.ts","webpack://@circuitwall/jarela/./lib/stores/watchers.ts"],"sourcesContent":["import type { TriggerHandler } from \"./types\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\n// Module-level registry. getOrCreateGlobal so HMR / repeated imports in\n// dev don't lose registrations across module re-evaluations.\ninterface RegistryState {\n handlers: Map<string, TriggerHandler>;\n}\nconst state = getOrCreateGlobal<RegistryState>(\"__jarela_trigger_registry\", () => ({\n handlers: new Map(),\n}));\n\nexport function registerTriggerHandler(handler: TriggerHandler): void {\n state.handlers.set(handler.kind, handler);\n}\n\nexport function getTriggerHandler(kind: string): TriggerHandler | undefined {\n return state.handlers.get(kind);\n}\n\nexport function listTriggerHandlers(): TriggerHandler[] {\n return Array.from(state.handlers.values());\n}\n\n// Test helper. Not exposed in the public surface — only the test file\n// reaches in to reset.\nexport function __resetTriggerRegistry(): void {\n state.handlers.clear();\n}\n","import { getOrCreateAgentThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { prepareThreadRun, persistAssistantMessage } from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { getScript } from \"./scripts\";\nimport type {\n PromptFiring,\n ScriptFiring,\n TriggerFiring,\n TriggerOutcome,\n} from \"./types\";\n\n/**\n * Invoke an agent for one prompt firing. Extracted from the original\n * scheduler `runTask` so any handler that wants chat semantics goes\n * through the exact same run/persist/silent code path.\n *\n * The runner does NOT publish notifications — different trigger kinds\n * want different notification payloads, so that responsibility stays\n * with each handler's markFired().\n */\nexport async function runTriggerAgent(firing: PromptFiring): Promise<TriggerOutcome> {\n const agent = getAgentConfig(firing.agentId);\n if (!agent) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Agent \"${firing.agentId}\" not found`,\n };\n }\n const thread = getOrCreateAgentThread(firing.agentId);\n const category = firing.category ?? firing.kind;\n\n // Silent mode: wrap the prompt with a \"reply only if material\" directive\n // AND a NO_REPLY sentinel so the post-run code can drop the assistant\n // turn entirely when nothing is worth surfacing. Visibility itself is\n // handled at the chat-panel layer via the category-filter toolbar.\n const effectivePrompt = firing.silent\n ? `${firing.prompt}\\n\\n[SILENT_TRIGGER] This prompt was triggered automatically. Reply with information only if there is something material the user needs to see right now. If nothing material to report, reply with exactly the single token NO_REPLY and nothing else.`\n : firing.prompt;\n\n try {\n const prepared = await prepareThreadRun(\n thread.thread_id,\n effectivePrompt,\n undefined,\n undefined,\n undefined,\n undefined,\n category,\n );\n const collected = await collectStream(prepared.stream);\n const replyText = collected.assistantContent.trim();\n const isNoReply = firing.silent === true && /^\\s*NO[_ ]?REPLY\\b/i.test(replyText);\n const skipAssistant = firing.silent === true && (isNoReply || replyText.length === 0);\n if (!skipAssistant) {\n persistAssistantMessage(\n thread.thread_id,\n collected.assistantContent,\n collected.usedTools,\n collected.toolEvents,\n category,\n );\n }\n return {\n status: skipAssistant ? \"skipped\" : \"done\",\n preview: skipAssistant\n ? \"\"\n : collected.assistantContent.replace(/\\s+/g, \" \").trim().slice(0, 120),\n threadId: thread.thread_id,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: thread.thread_id,\n error: msg,\n };\n }\n}\n\n/**\n * Run an in-process script for one script firing. No thread, no LLM,\n * no message persistence — the script does its own side effects. The\n * preview goes into TriggerOutcome for telemetry / notifications.\n */\nexport async function runTriggerScript(firing: ScriptFiring): Promise<TriggerOutcome> {\n const fn = getScript(firing.script);\n if (!fn) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Script \"${firing.script}\" not registered`,\n };\n }\n try {\n const result = await fn(firing.args ?? {});\n return {\n status: \"done\",\n preview: result.preview,\n threadId: \"\",\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n };\n }\n}\n\n/**\n * Dispatch one firing by mode. The fan-out loop in runTriggerTick\n * goes through here so handlers don't have to know which runner to\n * call.\n */\nexport async function runTriggerFiring(firing: TriggerFiring): Promise<TriggerOutcome> {\n if (firing.mode === \"script\") return runTriggerScript(firing);\n return runTriggerAgent(firing);\n}\n","import {\n getDueTasks,\n markTaskRan,\n getScheduledTask,\n type ScheduledTaskRow,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport type {\n TriggerFiring,\n TriggerHandler,\n TriggerOutcome,\n} from \"../types\";\n\nexport const SCHEDULED_TASK_KIND = \"scheduled_task\";\n\n/**\n * ADR-0032 — produce the right firing for a scheduled task. Routes on\n * `reaction_kind`: 'agent_prompt' → PromptFiring (the original ADR-0021\n * path); 'script' → ScriptFiring dispatched through the trigger runner\n * with no LLM round-trip. Unlike watchers, scheduled-task script firings\n * do NOT carry diff context (`previous`/`current`) — there's no diff to\n * report. Scripts that don't read those fields work in both contexts\n * unchanged.\n */\nfunction buildFiring(task: ScheduledTaskRow): TriggerFiring {\n if (task.reaction_kind === \"script\" && task.reaction_script) {\n let userArgs: Record<string, unknown> = {};\n if (task.reaction_script_args) {\n try {\n const parsed = JSON.parse(task.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty.\n }\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"script\",\n script: task.reaction_script,\n args: {\n ...userArgs,\n task: {\n id: task.id,\n agent_id: task.agent_id,\n description: task.description,\n schedule: task.schedule,\n schedule_kind: task.kind,\n },\n },\n meta: {\n agent_id: task.agent_id,\n schedule: task.schedule,\n scheduleKind: task.kind,\n reaction_kind: \"script\",\n reaction_script: task.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this task.\n silent: task.silent === 1,\n },\n };\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"prompt\",\n agentId: task.agent_id,\n prompt: task.prompt,\n silent: task.silent === 1,\n // Preserves the existing message-channel filter behaviour (ADR-0022).\n category: \"scheduled_task\",\n meta: { schedule: task.schedule, scheduleKind: task.kind, reaction_kind: \"agent_prompt\", silent: task.silent === 1 },\n };\n}\n\nexport const scheduledTaskHandler: TriggerHandler = {\n kind: SCHEDULED_TASK_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n return getDueTasks(asOf).map(buildFiring);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n const scheduleKind = (firing.meta?.scheduleKind as ScheduledTaskRow[\"kind\"] | undefined) ?? \"cron\";\n const schedule = (firing.meta?.schedule as string | undefined) ?? \"\";\n // Always advance the schedule (or delete the row for one-shots),\n // regardless of which firing mode we ran.\n markTaskRan(firing.id, scheduleKind, schedule, outcome.error);\n\n // ADR-0032 — silent=true on the task suppresses both NO_REPLY-style\n // agent behaviour AND the task_completed notification. Errors still\n // surface so the user sees failures even on muted tasks.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n // ADR-0032 — script firings publish a synthesised notification so the\n // UI event stream still lights up. No thread, so threadId is empty.\n const meta = (firing.meta ?? {}) as { agent_id?: string; reaction_script?: string };\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Scheduled task fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/** Public helper for the \"Run now\" API route — fires a single task by id. */\nexport function firingForTaskId(taskId: string): TriggerFiring | null {\n const task = getScheduledTask(taskId);\n return task ? buildFiring(task) : null;\n}\n","// Watcher trigger handler (ADR-0027). Sibling of scheduled-task.ts.\n//\n// Per scheduler tick, for every due watcher row:\n// 1. Resolve the named tool from the built-in registry.\n// 2. Invoke it with the saved JSON args (no agent context — watcher\n// tools must be context-free).\n// 3. Hash the stringified result and compare to last_fingerprint.\n// 4. If the hash differs from the previous run, return a TriggerFiring\n// whose prompt embeds a compact previous->current diff for the agent.\n// If it matches (or this is the first run with no previous), record\n// the fingerprint and skip — no LLM call, no firing.\n// 5. Either way the watcher's next_run_at is advanced by\n// interval_seconds. Errors during polling are recorded on the row\n// and surfaced in the UI.\n//\n// All scheduling work happens inside `getDueFirings` because the\n// abstraction's markFired is only called for actually-fired runs.\nimport { createHash } from \"node:crypto\";\nimport {\n getDueWatchers,\n getWatcher,\n recordWatcherPoll,\n recordWatcherPollError,\n type WatcherRow,\n} from \"@/lib/stores/watchers\";\nimport { registeredTools } from \"@/lib/tools/registry\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport type { TriggerFiring, TriggerHandler, TriggerOutcome } from \"../types\";\n\nexport const WATCHER_KIND = \"watcher\";\n\nfunction fingerprint(s: string): string {\n return createHash(\"sha256\").update(s).digest(\"hex\");\n}\n\nfunction stringifyResult(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nconst DEFAULT_REACTION_DIRECTIVE =\n `Summarise what changed and decide whether the user needs to know. ` +\n `If nothing material changed, you may stay silent.`;\n\n// Watcher tool outputs can be very large (full JSON payloads, long lists).\n// Keep the diff context bounded so one firing cannot consume most of an\n// agent's prompt budget.\nconst MAX_DIFF_CONTEXT_BYTES = 3500;\n\nfunction normalizeForDiff(raw: string): string {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2);\n } catch {\n return raw;\n }\n}\n\nfunction buildDiffForPrompt(previous: string | null, current: string): string {\n if (previous === null) return \"+ (first observation baseline established; no diff available)\";\n\n const prev = normalizeForDiff(previous).split(/\\r?\\n/);\n const curr = normalizeForDiff(current).split(/\\r?\\n/);\n\n let start = 0;\n while (start < prev.length && start < curr.length && prev[start] === curr[start]) {\n start += 1;\n }\n\n let prevEnd = prev.length - 1;\n let currEnd = curr.length - 1;\n while (prevEnd >= start && currEnd >= start && prev[prevEnd] === curr[currEnd]) {\n prevEnd -= 1;\n currEnd -= 1;\n }\n\n const removed = prev.slice(start, prevEnd + 1);\n const added = curr.slice(start, currEnd + 1);\n if (removed.length === 0 && added.length === 0) {\n return \"(no textual diff after normalization)\";\n }\n\n const hunkHeader = `@@ old:${start + 1}-${Math.max(start, prevEnd + 1)} new:${start + 1}-${Math.max(start, currEnd + 1)} @@`;\n const raw = [\n hunkHeader,\n ...removed.map((l) => `- ${l}`),\n ...added.map((l) => `+ ${l}`),\n ].join(\"\\n\");\n\n const bytes = Buffer.byteLength(raw, \"utf8\");\n const clipped = truncateBytes(raw, MAX_DIFF_CONTEXT_BYTES);\n if (!clipped.truncated) return raw;\n return `${clipped.text}\\n… [diff truncated: showing ${MAX_DIFF_CONTEXT_BYTES} of ${bytes} bytes; full values retained in watcher state]`;\n}\n\nfunction buildFiringPrompt(watcher: WatcherRow, previous: string | null, current: string): string {\n const argsPretty = (() => {\n try { return JSON.stringify(JSON.parse(watcher.tool_args), null, 2); }\n catch { return watcher.tool_args; }\n })();\n // ADR-0030: a non-null reaction_prompt swaps in for the default directive.\n // The diff envelope (label/tool/args/diff) is unchanged so the agent\n // always has the change context regardless of the user's instruction.\n const directive = watcher.reaction_prompt?.trim() || DEFAULT_REACTION_DIRECTIVE;\n return [\n `Watcher \"${watcher.label}\" detected a change.`,\n ``,\n `Tool: ${watcher.tool_name}`,\n `Args: ${argsPretty}`,\n ``,\n `--- Diff (previous -> current) ---`,\n buildDiffForPrompt(previous, current),\n ``,\n directive,\n ].join(\"\\n\");\n}\n\n/**\n * ADR-0031 — build the args bundle handed to a `reaction.*` script when\n * a watcher with reaction_kind='script' fires. The bundle merges the\n * user-supplied script args with diff context (previous + current\n * stringified results, plus a slim `watcher` descriptor) so any reaction\n * script can access both the static config and the change context.\n */\nfunction buildScriptArgs(watcher: WatcherRow, previous: string | null, current: string): Record<string, unknown> {\n let userArgs: Record<string, unknown> = {};\n if (watcher.reaction_script_args) {\n try {\n const parsed = JSON.parse(watcher.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty so the script still\n // runs with diff context.\n }\n }\n return {\n ...userArgs,\n watcher: {\n id: watcher.id,\n label: watcher.label,\n tool_name: watcher.tool_name,\n tool_args: safeJson(watcher.tool_args),\n agent_id: watcher.agent_id,\n },\n previous,\n current,\n };\n}\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\n/**\n * ADR-0031 — produce the right firing for a watcher that just observed\n * a change. Routes on `reaction_kind`: 'agent_prompt' → PromptFiring (the\n * original ADR-0027 path); 'script' → ScriptFiring dispatched through\n * the trigger runner with no LLM round-trip.\n */\nfunction buildFiring(watcher: WatcherRow, previous: string | null, current: string): TriggerFiring {\n if (watcher.reaction_kind === \"script\" && watcher.reaction_script) {\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"script\",\n script: watcher.reaction_script,\n args: buildScriptArgs(watcher, previous, current),\n meta: {\n label: watcher.label,\n tool_name: watcher.tool_name,\n agent_id: watcher.agent_id,\n reaction_kind: \"script\",\n reaction_script: watcher.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this watcher.\n silent: watcher.silent === 1,\n },\n };\n }\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"prompt\",\n agentId: watcher.agent_id,\n prompt: buildFiringPrompt(watcher, previous, current),\n silent: watcher.silent === 1,\n category: \"watcher\",\n meta: { label: watcher.label, tool_name: watcher.tool_name, reaction_kind: \"agent_prompt\", silent: watcher.silent === 1 },\n };\n}\n\nasync function invokeWatcherTool(watcher: WatcherRow): Promise<string> {\n const entry = registeredTools().find((t) => t.name === watcher.tool_name);\n if (!entry) throw new Error(`tool \"${watcher.tool_name}\" is not registered`);\n let args: unknown;\n try { args = JSON.parse(watcher.tool_args); }\n catch (e) { throw new Error(`tool_args is not valid JSON: ${e instanceof Error ? e.message : String(e)}`); }\n // LangChain tools accept the args object directly via .invoke().\n // Watcher tools must be context-free (no thread_id / agent_id).\n const result = await entry.invoke(args as Record<string, unknown>);\n return stringifyResult(result);\n}\n\n/**\n * Poll every due watcher and produce firings only for those whose\n * tool result changed since the last poll. Updates polling state\n * synchronously so subsequent ticks see the advanced next_run_at.\n */\nasync function pollDueWatchers(asOf: Date): Promise<TriggerFiring[]> {\n const due = getDueWatchers(asOf);\n const firings: TriggerFiring[] = [];\n for (const watcher of due) {\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({\n id: watcher.id,\n fingerprint: fp,\n result,\n fired: changed,\n });\n if (changed) {\n firings.push(buildFiring(watcher, watcher.last_result, result));\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n // A polling error doesn't fire the agent; it's surfaced via\n // last_error on the row + UI. Logging only.\n console.error(`[watcher] poll ${watcher.id} (${watcher.tool_name}) failed:`, msg);\n }\n }\n return firings;\n}\n\nexport const watcherHandler: TriggerHandler = {\n kind: WATCHER_KIND,\n\n async getDueFirings(asOf: Date): Promise<TriggerFiring[]> {\n return pollDueWatchers(asOf);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n // Polling state (last_run_at, last_fingerprint, last_result,\n // next_run_at) was already advanced inside getDueFirings — we only\n // publish a notification here so the UI's event stream lights up.\n // ADR-0031 — script firings publish too; reuse `task_completed` with\n // a synthesised prompt and the watcher's agent_id from meta (script\n // firings have no thread, so threadId is empty).\n // silent=true on the watcher suppresses the notification (in addition\n // to the prompt-mode NO_REPLY semantic). Errors still surface.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n const meta = (firing.meta ?? {}) as { label?: string; agent_id?: string; reaction_script?: string };\n const label = meta.label ?? \"(watcher)\";\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/**\n * \"Run now\" — force a single poll of one watcher and, if the result\n * differs from `last_fingerprint`, return a ready-to-run firing. Used by\n * the manual /run HTTP endpoint. Returns null when the poll didn't\n * trigger a firing (no change, or the watcher is gone).\n */\nexport async function firingForWatcherIdNow(id: string): Promise<TriggerFiring | null> {\n const watcher = getWatcher(id);\n if (!watcher) return null;\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({ id: watcher.id, fingerprint: fp, result, fired: changed });\n if (!changed) return null;\n return buildFiring(watcher, watcher.last_result, result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n throw err;\n }\n}\n","// Single-file re-index path used by the fs-watch trigger.\n//\n// The full sweep in indexer.ts handles \"scan everything\" semantics —\n// allowlists, size caps, deletion sweeps. For watcher firings we\n// already know the absolute path, so we duplicate just the per-file\n// part: stat → read → hash → upsert (or delete).\n\nimport { promises as fs } from \"node:fs\";\nimport { relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { getDocumentSource } from \"@/lib/stores/document-sources\";\nimport { registerScript } from \"@/lib/triggers/scripts\";\nimport {\n ALLOWED_EXT,\n MAX_FILE_BYTES,\n hashContent,\n lowerExt,\n readTextFile,\n upsertLocalDocument,\n type FileEntry,\n} from \"./indexer\";\n\nexport interface ReindexResult {\n preview: string;\n}\n\n/**\n * Re-index a single file inside a local_folder source. Idempotent;\n * returns \"deleted\" / \"skipped\" / \"added\" / \"updated\" / \"unchanged\".\n */\nexport async function reindexLocalFile(args: {\n source_id: string;\n abs: string;\n}): Promise<ReindexResult> {\n const source = getDocumentSource(args.source_id);\n if (!source) return { preview: `skipped: source ${args.source_id} missing` };\n if (source.kind !== \"local_folder\") {\n return { preview: `skipped: source ${args.source_id} is not local_folder` };\n }\n\n const db = getDb();\n\n let stat;\n try {\n stat = await fs.stat(args.abs);\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n // File gone — drop the row (chunks cascade via FK).\n const info = db\n .prepare(\"DELETE FROM documents WHERE source_id=? AND path=?\")\n .run(args.source_id, args.abs);\n return {\n preview: info.changes > 0 ? `deleted ${args.abs}` : `skipped: not indexed (${args.abs})`,\n };\n }\n throw err;\n }\n\n if (!stat.isFile()) return { preview: `skipped: not a regular file (${args.abs})` };\n if (stat.size > MAX_FILE_BYTES) return { preview: `skipped: file > MAX_FILE_BYTES (${args.abs})` };\n\n // Watchers don't pre-filter by extension as aggressively as the\n // sweep does, so re-check here. Keeps the allowlist as the single\n // source of truth even if a future caller forgets.\n if (!ALLOWED_EXT.has(lowerExt(args.abs))) {\n return { preview: `skipped: ext not allowed (${args.abs})` };\n }\n\n const text = await readTextFile(args.abs);\n if (text === null) return { preview: `skipped: binary or unreadable (${args.abs})` };\n\n const hash = hashContent(text);\n const existing = db\n .prepare(\n \"SELECT id, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=? AND path=?\",\n )\n .get(args.source_id, args.abs) as\n | { id: string; mtime_ms: number; size_bytes: number; content_hash: string }\n | undefined;\n\n if (existing && existing.content_hash === hash) {\n // Mtime/size may have shifted (touch / OneDrive sync) but content\n // is unchanged — touch the row instead of re-embedding.\n db.prepare(\n \"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\",\n ).run(Math.floor(stat.mtimeMs), stat.size, new Date().toISOString(), existing.id);\n return { preview: `unchanged ${args.abs}` };\n }\n\n const f: FileEntry = {\n abs: args.abs,\n rel: relative(source.path, args.abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(stat.mtimeMs),\n size: stat.size,\n };\n await upsertLocalDocument(args.source_id, f, text, hash, existing?.id);\n return { preview: existing ? `updated ${args.abs}` : `added ${args.abs}` };\n}\n\n// Registry side-effect: register the script the fs-watch handler\n// emits. Importing this module wires it. Call sites are\n// instrumentation.ts (boot) and the fs-watch handler module\n// (defensive in case boot order changes).\nlet registered = false;\nexport function registerDocumentScripts(): void {\n if (registered) return;\n registerScript(\"documents.reindex_local_file\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n const abs = String(args.abs ?? \"\");\n if (!sourceId || !abs) {\n return { preview: \"skipped: missing source_id or abs\" };\n }\n return reindexLocalFile({ source_id: sourceId, abs });\n });\n registered = true;\n}\n\nregisterDocumentScripts();\n","// fs.watch-driven re-indexing for local document sources.\n//\n// Boots one watcher per enabled `local_folder` source. Filesystem events\n// are filtered (skip dot-dirs / build output / disallowed extensions)\n// and debounced per-(source_id, abs) for 500 ms. Each surviving event\n// becomes a ScriptFiring that the runner dispatches to\n// `documents.reindex_local_file`.\n//\n// On Linux, fs.watch with `recursive: true` is unsupported — we log\n// once per source and rely on the 10-min full sweep there. On macOS\n// and Windows this gives sub-second propagation from save-to-search.\n\nimport { promises as fs, type FSWatcher, watch as fsWatch } from \"node:fs\";\nimport { join, sep } from \"node:path\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { listEnabledDocumentSources } from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, SKIP_DIRS, lowerExt } from \"@/lib/documents/indexer\";\n// Side-effect import: ensures `documents.reindex_local_file` is in the\n// script registry before the first firing dispatches.\nimport \"@/lib/documents/reindex-local-file\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const FS_WATCH_KIND = \"fs_watch\";\n\nconst DEBOUNCE_MS = 500;\n\ninterface WatcherState {\n sourceId: string;\n rootPath: string;\n watcher: FSWatcher | null;\n /** Map<abs, debounce-timer-id> while a debounce is in flight. */\n debounceTimers: Map<string, NodeJS.Timeout>;\n}\n\ninterface FsWatchState {\n watchers: Map<string, WatcherState>; // sourceId → state\n /** Coalesced pending firings, keyed by `${source_id}:${abs}`. */\n pending: Map<string, { source_id: string; abs: string }>;\n unsupportedLogged: Set<string>;\n}\n\n// Stored on globalThis: Next's standalone build bundles this module into\n// multiple chunks (one per route that transitively imports it), and each\n// chunk would otherwise have its own copy of `state`. Without the global\n// pin, the chunk that runs `attachWatcher` enqueues into a different Map\n// than the chunk the scheduler tick reads via `drainPending`.\nconst state = getOrCreateGlobal<FsWatchState>(\"__jarela_fs_watch_state\", () => ({\n watchers: new Map(),\n pending: new Map(),\n unsupportedLogged: new Set(),\n}));\n\nfunction pendingKey(sourceId: string, abs: string): string {\n return `${sourceId}:${abs}`;\n}\n\nfunction enqueuePending(sourceId: string, abs: string): void {\n state.pending.set(pendingKey(sourceId, abs), { source_id: sourceId, abs });\n}\n\nfunction scheduleDebounce(w: WatcherState, abs: string): void {\n const existing = w.debounceTimers.get(abs);\n if (existing) clearTimeout(existing);\n const t = setTimeout(() => {\n w.debounceTimers.delete(abs);\n enqueuePending(w.sourceId, abs);\n }, DEBOUNCE_MS);\n // Don't keep the event loop alive just for the debounce.\n if (typeof t.unref === \"function\") t.unref();\n w.debounceTimers.set(abs, t);\n}\n\nfunction handleEvent(w: WatcherState, filename: string | null): void {\n if (!filename) return;\n // Filter dot-dirs and SKIP_DIRS inline. We can't trust the\n // recursive watcher to honour them.\n const segments = filename.split(/[\\\\/]+/).filter((s) => s.length > 0);\n if (segments.length === 0) return;\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (SKIP_DIRS.has(seg)) return;\n if (seg.startsWith(\".\")) return;\n }\n const file = segments[segments.length - 1];\n if (!ALLOWED_EXT.has(lowerExt(file))) return;\n const abs = join(w.rootPath, ...segments);\n scheduleDebounce(w, abs);\n}\n\nasync function attachWatcher(sourceId: string, rootPath: string): Promise<void> {\n if (state.watchers.has(sourceId)) return;\n // Confirm the directory still exists; fs.watch on a nonexistent path\n // throws synchronously and tears down the boot loop.\n try {\n const st = await fs.stat(rootPath);\n if (!st.isDirectory()) return;\n } catch {\n return;\n }\n\n const w: WatcherState = {\n sourceId,\n rootPath,\n watcher: null,\n debounceTimers: new Map(),\n };\n try {\n w.watcher = fsWatch(\n rootPath,\n { recursive: true, persistent: false },\n (_event, filename) => {\n const name: string | null =\n typeof filename === \"string\"\n ? filename\n : filename\n ? (filename as Buffer).toString()\n : null;\n handleEvent(w, name);\n },\n );\n w.watcher.on(\"error\", (err) => {\n console.warn(`[triggers/fs_watch] watcher error for ${rootPath}:`, err.message);\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ERR_FEATURE_UNAVAILABLE_ON_PLATFORM\") {\n // Linux: recursive fs.watch isn't supported. Falling back to the\n // 10-min full sweep is fine — log once per source.\n if (!state.unsupportedLogged.has(sourceId)) {\n console.warn(\n `[triggers/fs_watch] recursive fs.watch unsupported on this platform; ` +\n `relying on the full sweep for source \"${rootPath}\"`,\n );\n state.unsupportedLogged.add(sourceId);\n }\n return;\n }\n console.warn(`[triggers/fs_watch] failed to attach watcher to ${rootPath}:`, e.message);\n return;\n }\n state.watchers.set(sourceId, w);\n}\n\nfunction detachWatcher(sourceId: string): void {\n const w = state.watchers.get(sourceId);\n if (!w) return;\n for (const t of w.debounceTimers.values()) clearTimeout(t);\n w.debounceTimers.clear();\n if (w.watcher) {\n try { w.watcher.close(); } catch { /* noop */ }\n }\n state.watchers.delete(sourceId);\n}\n\nasync function syncWatchers(): Promise<void> {\n const sources = listEnabledDocumentSources().filter((s) => s.kind === \"local_folder\");\n const wantSourceIds = new Set(sources.map((s) => s.id));\n\n // Drop watchers whose source disappeared / disabled.\n for (const sourceId of Array.from(state.watchers.keys())) {\n if (!wantSourceIds.has(sourceId)) {\n detachWatcher(sourceId);\n }\n }\n\n // Attach new watchers.\n for (const s of sources) {\n if (state.watchers.has(s.id)) continue;\n await attachWatcher(s.id, s.path);\n }\n}\n\nfunction drainPending(): ScriptFiring[] {\n if (state.pending.size === 0) return [];\n const now = Date.now();\n const firings: ScriptFiring[] = [];\n for (const { source_id, abs } of state.pending.values()) {\n firings.push({\n id: `${source_id}:${abs}:${now}`,\n kind: FS_WATCH_KIND,\n mode: \"script\",\n script: \"documents.reindex_local_file\",\n args: { source_id, abs },\n });\n }\n state.pending.clear();\n return firings;\n}\n\nexport const fsWatchHandler: TriggerHandler = {\n kind: FS_WATCH_KIND,\n\n async start(): Promise<void> {\n await syncWatchers();\n },\n\n async sync(): Promise<void> {\n await syncWatchers();\n },\n\n async stop(): Promise<void> {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n },\n\n getDueFirings(_asOf: Date): TriggerFiring[] {\n return drainPending();\n },\n\n markFired(): void {\n // The script writes its own state into `documents`. Nothing extra\n // to bookkeep here — keeping this empty also means re-firing after\n // an error is the next watcher event, which is the right thing.\n },\n};\n\n/** Test-only helper. */\nexport function __resetFsWatchState(): void {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n state.unsupportedLogged.clear();\n}\n\n/** Test-only helper. Pumps a synthetic event without touching the real fs. */\nexport function __pushEventForTest(sourceId: string, rootPath: string, filename: string): void {\n let w = state.watchers.get(sourceId);\n if (!w) {\n w = { sourceId, rootPath, watcher: null, debounceTimers: new Map() };\n state.watchers.set(sourceId, w);\n }\n handleEvent(w, filename);\n}\n","// Fast (60 s) re-sweep loop for remote document sources.\n//\n// Local folders use fs.watch for low-latency reindexing; remote\n// sources (Confluence / Jira) have no inotify equivalent, so we poll\n// — but at a much higher cadence than the 10-min full sweep. Each\n// source's existing cursor (last_cursor on document_sources) means\n// the upstream API call only fetches what changed since last poll,\n// keeping rate-limit pressure low.\n\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n} from \"@/lib/stores/document-sources\";\nimport { isRemoteKind, runRemoteSource } from \"@/lib/documents/remote\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { registerScript } from \"../scripts\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const DOCUMENT_FAST_SWEEP_KIND = \"doc_fast_sweep\";\n\nconst DEFAULT_INTERVAL_MS = 60_000;\n\nfunction intervalMs(): number {\n const raw = process.env.JARELA_FAST_REMOTE_SWEEP_MS;\n if (!raw) return DEFAULT_INTERVAL_MS;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 1000 ? n : DEFAULT_INTERVAL_MS;\n}\n\ninterface SweepState {\n /** sourceId → last fired (ms epoch). */\n lastRunAt: Map<string, number>;\n}\n\n// Pinned to globalThis: Next's standalone build bundles handler files\n// into multiple chunks, and module-local state would otherwise be split\n// across them. See lib/triggers/handlers/fs-watch.ts for the same fix.\nconst state = getOrCreateGlobal<SweepState>(\n \"__jarela_doc_fast_sweep_state\",\n () => ({ lastRunAt: new Map() }),\n);\n\nlet scriptRegistered = false;\nfunction registerSweepScript(): void {\n if (scriptRegistered) return;\n registerScript(\"documents.run_remote_source\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n if (!sourceId) return { preview: \"skipped: missing source_id\" };\n // Resolve the source row at fire time so we always pick up the\n // latest config / cursor without caching it.\n const sources = listEnabledDocumentSources();\n const source = sources.find((s) => s.id === sourceId);\n if (!source) return { preview: `skipped: source ${sourceId} not enabled` };\n if (!isRemoteKind(source.kind)) {\n return { preview: `skipped: source ${sourceId} is not a remote kind` };\n }\n try {\n const stats = await runRemoteSource(source);\n return {\n preview:\n `${source.kind} ${source.path}: ` +\n `+${stats.added} ~${stats.updated} =${stats.unchanged} !${stats.errors}`,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // The runRemoteSource path normally swallows its own errors; if\n // something escaped, mark the source so the panel surfaces it.\n try { markSourceScanned(source.id, msg); } catch { /* noop */ }\n throw err;\n }\n });\n scriptRegistered = true;\n}\n\nregisterSweepScript();\n\nexport const documentFastSweepHandler: TriggerHandler = {\n kind: DOCUMENT_FAST_SWEEP_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n const now = asOf.getTime();\n const interval = intervalMs();\n const sources = listEnabledDocumentSources().filter((s) => isRemoteKind(s.kind));\n const firings: ScriptFiring[] = [];\n for (const s of sources) {\n const last = state.lastRunAt.get(s.id) ?? 0;\n if (now - last < interval) continue;\n firings.push({\n id: `${s.id}:${now}`,\n kind: DOCUMENT_FAST_SWEEP_KIND,\n mode: \"script\",\n script: \"documents.run_remote_source\",\n args: { source_id: s.id },\n });\n }\n return firings;\n },\n\n markFired(firing: TriggerFiring): void {\n if (firing.mode !== \"script\") return;\n const sourceId = firing.args ? String(firing.args.source_id ?? \"\") : \"\";\n if (!sourceId) return;\n // Throttle on every firing regardless of outcome — Atlassian\n // rate-limits don't differentiate between success and error.\n state.lastRunAt.set(sourceId, Date.now());\n },\n};\n\n/** Test-only helper. */\nexport function __resetFastSweepState(): void {\n state.lastRunAt.clear();\n}\n","// ADR-0031 — `reaction.notify`: a watcher reaction script that publishes\n// a `task_completed` notification with the watcher's diff preview.\n//\n// Args provided by the watcher handler at fire time (see\n// pollDueWatchers in handlers/watcher.ts):\n// { watcher: { id, label, tool_name, tool_args, agent_id },\n// previous: string | null,\n// current: string,\n// ...userArgs }\n//\n// User-supplied args (subset that this script reads):\n// { title?: string, level?: \"info\" | \"warning\" }\nimport { registerScript, type ScriptResult } from \"@/lib/triggers/scripts\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\ninterface NotifyContext {\n watcher?: {\n id?: string;\n label?: string;\n tool_name?: string;\n agent_id?: string;\n };\n previous?: string | null;\n current?: string;\n title?: string;\n level?: \"info\" | \"warning\";\n}\n\nfunction shortPreview(previous: string | null | undefined, current: string | undefined): string {\n const cur = (current ?? \"\").replace(/\\s+/g, \" \").trim();\n const prev = (previous ?? \"\").replace(/\\s+/g, \" \").trim();\n if (!prev) return cur.slice(0, 120);\n // Trivial diff: just show \"<prev> → <current>\" trimmed at both ends.\n const left = prev.slice(0, 50);\n const right = cur.slice(0, 50);\n return `${left} → ${right}`;\n}\n\nregisterScript(\"reaction.notify\", async (args: Record<string, unknown>): Promise<ScriptResult> => {\n const ctx = args as NotifyContext;\n const watcher = ctx.watcher ?? {};\n const label = watcher.label ?? \"(unknown watcher)\";\n const title = (typeof ctx.title === \"string\" && ctx.title.trim()) || label;\n const preview = shortPreview(ctx.previous, ctx.current);\n // Reuse `task_completed` as the notification surface — the UI already\n // subscribes to it for scheduled-task / agent-prompt firings, and it\n // tolerates an empty thread_id (script firings have no thread).\n publishNotification({\n type: \"task_completed\",\n task_id: watcher.id ?? \"\",\n agent_id: watcher.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" detected a change.`,\n thread_id: \"\",\n status: \"done\",\n preview,\n ts: Date.now(),\n });\n return { preview: `notify: ${title} — ${preview}`.slice(0, 160) };\n});\n","import { listTriggerHandlers, registerTriggerHandler } from \"./registry\";\nimport { runTriggerAgent, runTriggerFiring, runTriggerScript } from \"./runner\";\nimport {\n scheduledTaskHandler,\n firingForTaskId,\n SCHEDULED_TASK_KIND,\n} from \"./handlers/scheduled-task\";\nimport {\n watcherHandler,\n firingForWatcherIdNow,\n WATCHER_KIND,\n} from \"./handlers/watcher\";\nimport { fsWatchHandler } from \"./handlers/fs-watch\";\nimport { documentFastSweepHandler } from \"./handlers/document-fast-sweep\";\n// Side-effect imports: ensure built-in reaction scripts (ADR-0031) are\n// in the registry before the first watcher firing dispatches.\nimport \"./reactions/notify\";\nimport type { TriggerFiring } from \"./types\";\n\n// Single registration site for built-in handlers. Importing this file\n// from the scheduler ensures every handler is wired before the first\n// tick. Future PRs add their handlers here.\nlet registered = false;\nexport function registerHandlers(): void {\n if (registered) return;\n registerTriggerHandler(scheduledTaskHandler);\n registerTriggerHandler(watcherHandler);\n registerTriggerHandler(fsWatchHandler);\n registerTriggerHandler(documentFastSweepHandler);\n registered = true;\n}\n\n// Eager registration on module load — preserves the legacy behaviour\n// where importing this module wires the scheduled-task handler.\nregisterHandlers();\n\n/** Boot every registered handler that has a start() lifecycle hook. */\nexport async function startAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.start) continue;\n try {\n await handler.start();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" start failed:`, msg);\n }\n }\n}\n\n/** Drain every registered handler that has a stop() lifecycle hook. */\nexport async function stopAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.stop) continue;\n try {\n await handler.stop();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" stop failed:`, msg);\n }\n }\n}\n\n/**\n * Notify handlers that something they care about changed. Today this\n * is fired by the document-source mutation routes so fs-watch and the\n * fast remote sweep can re-evaluate which sources they're watching.\n */\nexport async function notifyTriggerHandlers(_reason: string): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.sync) continue;\n try {\n await handler.sync();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" sync failed:`, msg);\n }\n }\n}\n\n/** Run one tick of the trigger fan-out. Used by the scheduler loop. */\nexport async function runTriggerTick(asOf: Date = new Date()): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n let firings: TriggerFiring[];\n try {\n firings = await handler.getDueFirings(asOf);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" getDueFirings failed:`, msg);\n continue;\n }\n for (const firing of firings) {\n try {\n const outcome = await runTriggerFiring(firing);\n await handler.markFired(firing, outcome);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] firing ${handler.kind}/${firing.id} failed:`, msg);\n try {\n await handler.markFired(firing, {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n });\n } catch (innerErr) {\n console.error(\n `[triggers] handler \"${handler.kind}\" markFired threw after error:`,\n innerErr,\n );\n }\n }\n }\n }\n}\n\n/**\n * Fire a single scheduled-task by id, on demand. Preserves the original\n * runScheduledTaskNow surface: returns when the run completes, throws\n * the underlying error if the run itself threw.\n */\nexport async function runScheduledTaskFiringNow(taskId: string): Promise<void> {\n const firing = firingForTaskId(taskId);\n if (!firing) throw new Error(`scheduled task ${taskId} not found`);\n // Route through runTriggerFiring so script-kind firings dispatch\n // through the script registry instead of the agent (ADR-0032).\n const outcome = await runTriggerFiring(firing);\n await scheduledTaskHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\n/**\n * Force a single watcher to poll right now. If the polled value differs\n * from the previously stored fingerprint, fire the agent and return.\n * Returns silently when there's no diff (so the manual \"Run now\" button\n * doesn't fabricate a turn out of an unchanged poll).\n */\nexport async function runWatcherFiringNow(watcherId: string): Promise<void> {\n const firing = await firingForWatcherIdNow(watcherId);\n if (!firing) return;\n if (firing.mode !== \"prompt\") return;\n const outcome = await runTriggerAgent(firing);\n await watcherHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\nexport { SCHEDULED_TASK_KIND, WATCHER_KIND };\nexport * from \"./types\";\nexport { registerTriggerHandler, listTriggerHandlers } from \"./registry\";\nexport { runTriggerAgent, runTriggerScript, runTriggerFiring };\nexport {\n registerScript,\n getScript,\n listScripts,\n listReactionScripts,\n isReactionScript,\n REACTION_SCRIPT_PREFIX,\n} from \"./scripts\";\n","// Client-safe constants for the voice picker UI. Kept in a standalone\n// module so client components can import them without dragging server-only\n// modules (lib/db, undici, node:child_process) through the import graph.\n\nexport const GEMINI_VOICES: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"Zephyr\", label: \"Zephyr · bright\" },\n { id: \"Puck\", label: \"Puck · upbeat\" },\n { id: \"Charon\", label: \"Charon · informative\" },\n { id: \"Kore\", label: \"Kore · firm\" },\n { id: \"Fenrir\", label: \"Fenrir · excitable\" },\n { id: \"Leda\", label: \"Leda · youthful\" },\n { id: \"Orus\", label: \"Orus · firm\" },\n { id: \"Aoede\", label: \"Aoede · breezy\" },\n { id: \"Callirrhoe\", label: \"Callirrhoe · easy-going\" },\n { id: \"Autonoe\", label: \"Autonoe · bright\" },\n { id: \"Enceladus\", label: \"Enceladus · breathy\" },\n { id: \"Iapetus\", label: \"Iapetus · clear\" },\n { id: \"Umbriel\", label: \"Umbriel · easy-going\" },\n { id: \"Algieba\", label: \"Algieba · smooth\" },\n { id: \"Despina\", label: \"Despina · smooth\" },\n { id: \"Erinome\", label: \"Erinome · clear\" },\n { id: \"Algenib\", label: \"Algenib · gravelly\" },\n { id: \"Rasalgethi\", label: \"Rasalgethi · informative\" },\n { id: \"Laomedeia\", label: \"Laomedeia · upbeat\" },\n { id: \"Achernar\", label: \"Achernar · soft\" },\n { id: \"Alnilam\", label: \"Alnilam · firm\" },\n { id: \"Schedar\", label: \"Schedar · even\" },\n { id: \"Gacrux\", label: \"Gacrux · mature\" },\n { id: \"Pulcherrima\", label: \"Pulcherrima · forward\" },\n { id: \"Achird\", label: \"Achird · friendly\" },\n { id: \"Zubenelgenubi\", label: \"Zubenelgenubi · casual\" },\n { id: \"Vindemiatrix\", label: \"Vindemiatrix · gentle\" },\n { id: \"Sadachbia\", label: \"Sadachbia · lively\" },\n { id: \"Sadaltager\", label: \"Sadaltager · knowledgeable\" },\n { id: \"Sulafat\", label: \"Sulafat · warm\" },\n];\n\nexport const GEMINI_TTS_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash-preview-tts\", label: \"Flash TTS (fast, cheap)\" },\n { id: \"gemini-2.5-pro-preview-tts\", label: \"Pro TTS (higher quality)\" },\n];\n\nexport const GEMINI_STT_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash\", label: \"Flash (fast, multilingual)\" },\n { id: \"gemini-2.5-pro\", label: \"Pro (slower, more accurate)\" },\n];\n","// Gemini voice helpers — TTS via the *-preview-tts models and STT by\n// feeding inline audio bytes to a multimodal Gemini model. Both call the\n// native REST API (the OpenAI-compat proxy doesn't expose AUDIO modality\n// or inline_data parts). API key is resolved from the \"google\" integration,\n// same source as lib/tools/generate_image.ts.\n\nimport { getConfig } from \"@/lib/env/config\";\nimport {\n resolveGoogleApiKey as resolveGoogleApiKeyShared,\n timeoutSignal,\n} from \"@/lib/utils/google-api\";\n\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\nexport function resolveGoogleApiKey(): string | null {\n return resolveGoogleApiKeyShared();\n}\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\n/**\n * Synthesize speech with Gemini TTS. Gemini returns PCM L16 (raw 16-bit\n * little-endian, 24 kHz mono); we wrap it with a WAV header so any\n * <audio> element can play it.\n *\n * Style/tone is steered by prepending a natural-language instruction to\n * the spoken text (Gemini's recommended pattern), e.g. style=\"Say warmly\n * and slowly\" produces \"Say warmly and slowly: <text>\". For multi-speaker\n * scenes, pass `speakers` with up to 2 entries and write the text as\n * `Name: line ...` per turn — Gemini will switch voices accordingly.\n */\nexport async function geminiTts(opts: {\n apiKey: string;\n model: string;\n voiceName: string;\n text: string;\n style?: string;\n speakers?: Array<{ name: string; voiceName: string }>;\n}): Promise<{ wav: Buffer; mime: \"audio/wav\" }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const style = opts.style?.trim();\n const spoken = style ? `${style.replace(/:\\s*$/, \"\")}: ${opts.text}` : opts.text;\n const speakers = (opts.speakers ?? []).filter((s) => s.name && s.voiceName).slice(0, 2);\n const speechConfig: Record<string, unknown> =\n speakers.length >= 2\n ? {\n multiSpeakerVoiceConfig: {\n speakerVoiceConfigs: speakers.map((s) => ({\n speaker: s.name,\n voiceConfig: { prebuiltVoiceConfig: { voiceName: s.voiceName } },\n })),\n },\n }\n : {\n voiceConfig: {\n prebuiltVoiceConfig: { voiceName: opts.voiceName },\n },\n };\n const body = {\n contents: [{ role: \"user\", parts: [{ text: spoken }] }],\n generationConfig: {\n responseModalities: [\"AUDIO\"],\n speechConfig,\n },\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini TTS ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"\";\n if (data) {\n const pcm = Buffer.from(data, \"base64\");\n const rate = parseSampleRate(mime) ?? 24000;\n return { wav: pcmToWav(pcm, rate, 1, 16), mime: \"audio/wav\" };\n }\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini TTS returned no audio: ${text}` : \"Gemini TTS returned no audio\");\n}\n\n/**\n * Transcribe audio via a Gemini multimodal model. Returns the verbatim\n * transcript, preserving the speaker's original language (including code-\n * switched English/Chinese).\n */\nexport async function geminiStt(opts: {\n apiKey: string;\n model: string;\n audio: Buffer;\n mimeType: string;\n}): Promise<{ text: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const body = {\n contents: [{\n role: \"user\",\n parts: [\n {\n text:\n \"Transcribe the following audio verbatim. Preserve the speaker's \" +\n \"original language, including mixed English and Chinese. Output ONLY \" +\n \"the transcript text — no quotes, no commentary, no language tags.\",\n },\n { inline_data: { mime_type: opts.mimeType, data: opts.audio.toString(\"base64\") } },\n ],\n }],\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini STT ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n const text = parts.map((p) => p.text).filter(Boolean).join(\"\").trim();\n if (!text) throw new Error(\"Gemini STT returned no transcript\");\n return { text };\n}\n\n// `audio/L16;codec=pcm;rate=24000` → 24000\nfunction parseSampleRate(mime: string): number | null {\n const m = /rate=(\\d+)/i.exec(mime);\n if (!m) return null;\n const n = parseInt(m[1], 10);\n return Number.isFinite(n) && n > 0 ? n : null;\n}\n\n// Build a RIFF/WAVE header for raw PCM. Standard 16-bit, mono unless told\n// otherwise. No fancy chunks — just enough to satisfy browser audio.\nfunction pcmToWav(pcm: Buffer, sampleRate: number, channels: number, bitsPerSample: number): Buffer {\n const byteRate = (sampleRate * channels * bitsPerSample) / 8;\n const blockAlign = (channels * bitsPerSample) / 8;\n const dataSize = pcm.length;\n const header = Buffer.alloc(44);\n header.write(\"RIFF\", 0);\n header.writeUInt32LE(36 + dataSize, 4);\n header.write(\"WAVE\", 8);\n header.write(\"fmt \", 12);\n header.writeUInt32LE(16, 16); // fmt chunk size\n header.writeUInt16LE(1, 20); // PCM\n header.writeUInt16LE(channels, 22);\n header.writeUInt32LE(sampleRate, 24);\n header.writeUInt32LE(byteRate, 28);\n header.writeUInt16LE(blockAlign, 32);\n header.writeUInt16LE(bitsPerSample, 34);\n header.write(\"data\", 36);\n header.writeUInt32LE(dataSize, 40);\n return Buffer.concat([header, pcm]);\n}\n\n// Re-export the client-safe constants for callers that already import from\n// this module on the server side.\nexport { GEMINI_VOICES, GEMINI_TTS_MODELS, GEMINI_STT_MODELS } from \"./constants\";\n","// Semantic search over document_chunks (ADR-0024). Cosine over embedded\n// chunks; substring fallback for chunks without embeddings (covers the\n// \"no embedding provider configured\" case and the brief window before\n// async embed completes after indexing).\n\nimport { getDb } from \"@/lib/db\";\nimport { embedOne, cosine } from \"@/lib/embeddings\";\n\nexport interface DocumentHit {\n document_id: string;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n chunk_index: number;\n text: string;\n score: number;\n match: \"semantic\" | \"substring\";\n}\n\ninterface Row {\n chunk_id: string;\n document_id: string;\n chunk_index: number;\n text: string;\n embedding: string | null;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n}\n\nexport async function searchDocuments(\n query: string,\n opts?: { limit?: number; sourceId?: string },\n): Promise<DocumentHit[]> {\n const limit = Math.min(Math.max(opts?.limit ?? 8, 1), 25);\n const db = getDb();\n const trimmed = query.trim();\n if (trimmed.length === 0) return [];\n\n // Hard cap on rows scanned per query — at thousands of chunks the JS\n // cosine pass is still milliseconds, but we still want a ceiling.\n const limitRows = 20_000;\n const rows = (\n opts?.sourceId\n ? db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE d.source_id = ? AND ds.enabled = 1\n LIMIT ?`,\n ).all(opts.sourceId, limitRows)\n : db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE ds.enabled = 1\n LIMIT ?`,\n ).all(limitRows)\n ) as unknown as Row[];\n\n if (rows.length === 0) return [];\n\n const qVec = await embedOne(trimmed);\n const scored: DocumentHit[] = [];\n const lowered = trimmed.toLowerCase();\n\n for (const r of rows) {\n let score = 0;\n let match: \"semantic\" | \"substring\" = \"semantic\";\n if (qVec && r.embedding) {\n let vec: number[] | null = null;\n try { vec = JSON.parse(r.embedding) as number[]; } catch { vec = null; }\n if (vec) score = cosine(qVec, vec);\n else { score = substringScore(r.text, lowered); match = \"substring\"; }\n } else {\n score = substringScore(r.text, lowered);\n match = \"substring\";\n }\n if (score <= 0) continue;\n scored.push({\n document_id: r.document_id,\n source_id: r.source_id,\n source_label: r.source_label,\n rel_path: r.rel_path,\n abs_path: r.abs_path,\n chunk_index: r.chunk_index,\n text: r.text,\n score,\n match,\n });\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n}\n\nfunction substringScore(haystack: string, needleLower: string): number {\n const hay = haystack.toLowerCase();\n if (!hay.includes(needleLower)) {\n // Try token-level OR match — at least one query token has to appear.\n const tokens = needleLower.split(/\\s+/).filter((t) => t.length > 2);\n let hits = 0;\n for (const t of tokens) if (hay.includes(t)) hits++;\n if (hits === 0) return 0;\n return Math.min(0.4, hits / Math.max(tokens.length, 1) * 0.4);\n }\n // Phrase match — high but below typical semantic top scores.\n return 0.6;\n}\n","// Scheduler loop. Owns the timer + the \"is a tick in flight?\" guard. The\n// actual firing logic lives in lib/triggers — this file only schedules\n// runTriggerTick() and exports a \"Run now\" helper that the existing\n// scheduled-tasks HTTP route uses.\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { indexAllSources } from \"@/lib/documents/indexer\";\nimport { runTriggerTick, runScheduledTaskFiringNow } from \"@/lib/triggers\";\nimport type { ScheduledTaskRow } from \"@/lib/stores/scheduled-tasks\";\n\n// Env-tunable so e2e tests can ride a tighter loop without waiting 30 s\n// per fs-watch firing. Production / dev use the 30 s default; tests\n// should set JARELA_SCHEDULER_TICK_MS=200 (or similar).\nconst POLL_INTERVAL_MS = (() => {\n const raw = process.env.JARELA_SCHEDULER_TICK_MS;\n if (!raw) return 30_000;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 50 ? n : 30_000;\n})();\n// Sweep document sources every Nth tick. 20 ticks × 30s = 10 min, which\n// matches typical \"I edited a file, ask Jarela about it\" patience. PR-D\n// upgrades this to event-driven fs watching.\nconst DOC_SWEEP_EVERY_TICKS = 20;\n\ninterface SchedulerState {\n started: boolean;\n timer: NodeJS.Timeout | null;\n running: boolean;\n tickCount: number;\n}\nconst state = getOrCreateGlobal<SchedulerState>(\"__jarela_scheduler\", () => ({\n started: false,\n timer: null,\n running: false,\n tickCount: 0,\n}));\n\n// Idempotent — call repeatedly; only the first call starts the loop.\nexport function startScheduler(): void {\n if (state.started) return;\n state.started = true;\n setImmediate(() => { void tick(); });\n state.timer = setInterval(() => { void tick(); }, POLL_INTERVAL_MS);\n if (typeof state.timer.unref === \"function\") state.timer.unref();\n}\n\nexport function stopScheduler(): void {\n if (state.timer) {\n clearInterval(state.timer);\n state.timer = null;\n }\n state.started = false;\n}\n\nasync function tick(): Promise<void> {\n if (state.running) return;\n state.running = true;\n try {\n await runTriggerTick();\n\n // Document-RAG reindex sweep (ADR-0024). Polled here until PR-D wires\n // an fs watcher. Failures are logged but never block the tick.\n state.tickCount = (state.tickCount + 1) % DOC_SWEEP_EVERY_TICKS;\n if (state.tickCount === 0) {\n try {\n await indexAllSources();\n } catch (err) {\n console.error(\n \"[scheduler] document index sweep failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n } finally {\n state.running = false;\n }\n}\n\n/**\n * Public wrapper retained for the \"Run now\" UI button + HTTP route.\n * Internally delegates to the trigger runner so the manual path and the\n * tick path share the exact same code.\n */\nexport async function runScheduledTaskNow(task: ScheduledTaskRow): Promise<void> {\n await runScheduledTaskFiringNow(task.id);\n}\n","import type { ContentPart } from \"@/lib/tools/types\";\nimport type { ModelProvider, ProviderMessage, ProviderParams } from \"@/lib/providers/types\";\n\nexport function transcriptText(raw: string): string {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return raw;\n return (parsed as ContentPart[])\n .map((p) => {\n if (p.type === \"text\") return p.text;\n if (p.type === \"image\") return `[image attachment: ${p.media_type}]`;\n if (p.type === \"file\") return `[file attachment: ${p.name} (${p.media_type})]`;\n return \"\";\n })\n .filter(Boolean)\n .join(\" \")\n .trim();\n } catch {\n return raw;\n }\n}\n\nfunction summaryMessages(transcript: string): ProviderMessage[] {\n return [\n {\n role: \"system\",\n content:\n \"You are a concise summarizer. Summarize the conversation below in 3-7 bullet points, capturing key facts, decisions, and context that would be useful to remember later.\",\n },\n {\n role: \"user\",\n content: `Conversation to summarize:\\n\\n${transcript}`,\n },\n ];\n}\n\nexport async function summarizeTranscript(\n provider: Pick<ModelProvider, \"chat\">,\n modelId: string,\n providerParams: ProviderParams,\n transcript: string,\n): Promise<string> {\n const trimmed = transcript.trim();\n if (!trimmed) return \"\";\n\n const { stream } = await provider.chat(modelId, summaryMessages(trimmed), providerParams);\n let summary = \"\";\n for await (const chunk of stream) summary += chunk;\n return summary.trim();\n}","import { join } from \"node:path\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { tool } from \"@langchain/core/tools\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { getToolSecret, type ToolSecretSlot } from \"@/lib/stores/tool-secrets\";\nimport type { ToolCategory } from \"./registry\";\n\n/**\n * Absolute path to the external tools directory. Resolved lazily from\n * `getConfig().toolsDir` so JARELA_TOOLS_DIR (and JARELA_DB_DIR fallback)\n * are honoured.\n */\nexport function getToolsDir(): string {\n return getConfig().toolsDir;\n}\n\nexport interface ExternalToolDef {\n name: string;\n description: string;\n schema: object;\n category?: ToolCategory;\n // Optional per-tool secret slots. Surfaced in the Extensions panel as\n // editable form fields; persisted (encrypted at rest) in the\n // `tool-secrets` memory namespace. Read at run time via `ctx.getSecret`.\n // See ADR-0023.\n secrets?: ToolSecretSlot[];\n run: (\n args: Record<string, unknown>,\n ctx: {\n thread_id?: string;\n // Returns the persisted secret for this tool's slot, or `null` if\n // it has not been configured. Always scoped to the current tool —\n // a tool cannot read another tool's secrets via this helper.\n getSecret: (key: string) => string | null;\n },\n ) => unknown | Promise<unknown>;\n}\n\nexport interface ExtensionLoadError {\n file: string;\n error: string;\n}\n\nexport interface ExternalToolsResult {\n tools: StructuredToolInterface[];\n categories: Map<string, ToolCategory>;\n files: Map<string, string>;\n // Declared secret slots per tool name (empty array if the tool did not\n // declare any). Used by the Extensions panel to render input fields.\n secrets: Map<string, ToolSecretSlot[]>;\n errors: ExtensionLoadError[];\n}\n\nfunction isValidSlot(v: unknown): v is ToolSecretSlot {\n if (!v || typeof v !== \"object\") return false;\n const o = v as Record<string, unknown>;\n if (typeof o.key !== \"string\" || !/^[a-z0-9_-]+$/i.test(o.key)) return false;\n if (o.label !== undefined && typeof o.label !== \"string\") return false;\n if (o.required !== undefined && typeof o.required !== \"boolean\") return false;\n if (o.description !== undefined && typeof o.description !== \"string\") return false;\n return true;\n}\n\nfunction isValid(p: unknown): p is ExternalToolDef {\n if (!p || typeof p !== \"object\") return false;\n const o = p as Record<string, unknown>;\n if (\n typeof o.name !== \"string\" ||\n o.name.trim() === \"\" ||\n typeof o.description !== \"string\" ||\n typeof o.schema !== \"object\" ||\n o.schema === null ||\n typeof o.run !== \"function\"\n ) return false;\n if (o.secrets !== undefined) {\n if (!Array.isArray(o.secrets)) return false;\n if (!o.secrets.every(isValidSlot)) return false;\n }\n return true;\n}\n\nexport function loadExternalTools(\n builtinNames: ReadonlySet<string>,\n): ExternalToolsResult {\n const tools: StructuredToolInterface[] = [];\n const categories = new Map<string, ToolCategory>();\n const files = new Map<string, string>();\n const secrets = new Map<string, ToolSecretSlot[]>();\n const errors: ExtensionLoadError[] = [];\n\n const toolsDir = getToolsDir();\n if (!existsSync(toolsDir)) {\n return { tools, categories, files, secrets, errors };\n }\n\n // Same trick as lib/providers/external.ts: bypass webpack's static analysis\n // so the dynamic require survives the Next build.\n const { createRequire } = (\n process as unknown as { getBuiltinModule: (id: string) => typeof import(\"node:module\") }\n ).getBuiltinModule(\"node:module\");\n const req = createRequire(join(toolsDir, \"_anchor\"));\n\n let entries: string[];\n try {\n entries = readdirSync(toolsDir);\n } catch {\n return { tools, categories, files, secrets, errors };\n }\n\n const seen = new Set<string>();\n\n for (const entry of entries) {\n if (!/\\.(c?js|ts)$/i.test(entry)) continue;\n const path = join(toolsDir, entry);\n try {\n if (!statSync(path).isFile()) continue;\n } catch {\n continue;\n }\n\n let mod: unknown;\n try {\n delete req.cache[req.resolve(path)];\n mod = req(path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ file: entry, error: message });\n console.error(`[tools] failed to load ${entry}:`, err);\n continue;\n }\n\n const candidate =\n (mod as { default?: unknown })?.default ?? (mod as unknown);\n if (!isValid(candidate)) {\n const msg =\n \"does not export a valid ExternalToolDef (need { name, description, schema, run })\";\n errors.push({ file: entry, error: msg });\n console.error(`[tools] ${entry} ${msg}`);\n continue;\n }\n\n const def = candidate;\n if (builtinNames.has(def.name)) {\n const msg = `name \"${def.name}\" collides with a built-in tool — built-in takes precedence`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] external ${entry}: ${msg}`);\n continue;\n }\n if (seen.has(def.name)) {\n const msg = `duplicate external tool \"${def.name}\"`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] ${entry}: ${msg}`);\n continue;\n }\n seen.add(def.name);\n\n const wrapped = tool(\n async (args: unknown, _runManager?: unknown, config?: RunnableConfig) => {\n const ctx = {\n thread_id: config?.configurable?.thread_id as string | undefined,\n getSecret: (key: string) => getToolSecret(def.name, key),\n };\n const result = await def.run(args as Record<string, unknown>, ctx);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n },\n {\n name: def.name,\n description: def.description,\n schema: def.schema as never,\n },\n ) as unknown as StructuredToolInterface;\n\n tools.push(wrapped);\n files.set(def.name, entry);\n if (def.category) categories.set(def.name, def.category);\n secrets.set(def.name, def.secrets ?? []);\n }\n\n return { tools, categories, files, secrets, errors };\n}\n","// Shared collector for agent stream consumers.\n//\n// Previously three near-identical drain loops lived in:\n// - app/api/v1/threads/[thread_id]/run/route.ts (HTTP run)\n// - lib/scheduler/index.ts (cron tasks)\n// - lib/bridges/dispatcher.ts (WhatsApp / bridges)\n//\n// They all read `prepared.stream`, accumulate `text_delta` into a single\n// assistant string, record `tool_call`/`tool_result` events, stop on\n// `done`/`error`, and surface the terminal state. This helper unifies that.\n\nimport type { StreamChunk } from \"@/lib/agents/base\";\nimport type { PersistedToolEvent } from \"@/lib/stores/threads\";\n\nexport interface CollectedRun {\n assistantContent: string;\n usedTools: string[];\n toolEvents: PersistedToolEvent[];\n terminal: \"done\" | \"error\";\n errorMessage?: string;\n}\n\nexport interface CollectStreamOptions {\n // Called for every chunk before it is interpreted. Use for live broadcast\n // (HTTP SSE, websocket, etc.). Throwing here aborts the run with terminal\n // = \"error\".\n onChunk?: (chunk: StreamChunk) => void;\n}\n\n/** Drain an async stream of `StreamChunk` into a single `CollectedRun`. */\nexport async function collectStream(\n stream: AsyncIterable<StreamChunk>,\n opts: CollectStreamOptions = {},\n): Promise<CollectedRun> {\n const result: CollectedRun = {\n assistantContent: \"\",\n usedTools: [],\n toolEvents: [],\n terminal: \"done\",\n };\n\n try {\n for await (const chunk of stream) {\n opts.onChunk?.(chunk);\n switch (chunk.type) {\n case \"text_delta\": {\n result.assistantContent += (chunk.data.delta as string) ?? \"\";\n break;\n }\n case \"tool_call\": {\n const d = chunk.data as { id?: string; name?: string; arguments?: unknown };\n if (d.name) result.usedTools.push(d.name);\n result.toolEvents.push({\n id: d.id ?? `call-${result.toolEvents.length}`,\n phase: \"call\",\n name: d.name ?? \"\",\n payload: d.arguments,\n });\n break;\n }\n case \"tool_result\": {\n const d = chunk.data as { id?: string; name?: string; result?: unknown };\n result.toolEvents.push({\n id: d.id ?? `result-${result.toolEvents.length}`,\n phase: \"result\",\n name: d.name ?? \"\",\n payload: d.result,\n });\n break;\n }\n case \"error\": {\n result.terminal = \"error\";\n const msg = (chunk.data as { message?: unknown })?.message;\n if (typeof msg === \"string\") result.errorMessage = msg;\n return result;\n }\n case \"done\": {\n return result;\n }\n // thinking_delta and unknown types are pass-through (already\n // forwarded to onChunk above).\n }\n }\n } catch (err) {\n result.terminal = \"error\";\n result.errorMessage = err instanceof Error ? err.message : String(err);\n }\n\n return result;\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getMemory, putMemory, listMemory } from \"@/lib/stores/memory\";\nimport { registerTools } from \"./registry\";\n\nexport const memoryReadTool = tool(\n async ({ namespace, key }) => {\n const row = getMemory(namespace, key);\n if (!row) return JSON.stringify(null);\n return row.value; // already stored as a JSON string\n },\n {\n name: \"memory_read\",\n description: \"Read a value from long-term memory by namespace and key. Returns null if not found.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n }),\n },\n);\n\nexport const memoryWriteTool = tool(\n async ({ namespace, key, value }) => {\n putMemory(namespace, key, value);\n return JSON.stringify({ ok: true, namespace, key });\n },\n {\n name: \"memory_write\",\n description:\n \"Write or update a value in long-term memory. Use this to remember facts, user preferences, or any information that should persist across conversations.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n value: z.string().describe(\"Value to store (serialize objects to JSON before passing)\"),\n }),\n },\n);\n\nexport const memoryListTool = tool(\n async ({ namespace, search, limit }) => {\n const rows = listMemory(namespace, search, limit ?? 20);\n const result = rows.map((r) => ({\n namespace: r.namespace,\n key: r.key,\n value: (() => {\n try {\n return JSON.parse(r.value);\n } catch {\n return r.value;\n }\n })(),\n updated_at: r.updated_at,\n }));\n return JSON.stringify(result);\n },\n {\n name: \"memory_list\",\n description: \"List memory entries, optionally filtered by namespace or search term.\",\n schema: z.object({\n namespace: z.string().optional().describe(\"Filter by namespace (optional)\"),\n search: z.string().optional().describe(\"Search term to filter keys/values (optional)\"),\n limit: z.number().optional().describe(\"Max results (default 20)\"),\n }),\n },\n);\n\nregisterTools(\"Memory\", [memoryReadTool, memoryWriteTool, memoryListTool]);\n","// documents_search — semantic recall over folders the user indexed under\n// Documents (ADR-0024). Cosine over embedded chunks; substring fallback\n// when no embedding provider is configured or chunks haven't been\n// embedded yet.\n\nimport { tool } from \"@langchain/core/tools\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { searchDocuments } from \"@/lib/documents/search\";\nimport {\n createDocumentSource,\n deleteDocumentSource,\n getDocumentSource,\n getDocumentSourceByPath,\n listDocumentSources,\n type DocumentSourceKind,\n} from \"@/lib/stores/document-sources\";\nimport { indexOnDemand, runRemoteSource } from \"@/lib/documents/remote\";\nimport { notifyTriggerHandlers } from \"@/lib/triggers\";\n\nexport const documentsSearch = tool(\n async ({ query, limit, source_id }) => {\n const hits = await searchDocuments(query, { limit, sourceId: source_id });\n return JSON.stringify({\n query,\n hits: hits.map((h) => ({\n source: h.source_label ?? h.source_id,\n path: h.rel_path,\n chunk_index: h.chunk_index,\n score: Number(h.score.toFixed(4)),\n match: h.match,\n text: h.text,\n })),\n });\n },\n {\n name: \"documents_search\",\n description:\n \"Search indexed local documents (notes, READMEs, code, configs) by semantic similarity. \" +\n \"Use when the user references files in folders they've added under Documents, or when \" +\n \"you need facts from project-specific text the model wouldn't otherwise know. Returns \" +\n \"the top matching text chunks with their source path.\",\n schema: z.object({\n query: z.string().describe(\"Natural-language question or keywords to look up.\"),\n limit: z.number().int().min(1).max(25).optional()\n .describe(\"Max results to return (default 8).\"),\n source_id: z.string().optional()\n .describe(\"Restrict the search to a single document_source id. Omit to search all.\"),\n }),\n },\n);\n\nexport const documentsListSources = tool(\n async () => {\n const rows = listDocumentSources();\n return JSON.stringify({\n sources: rows.map((r) => ({\n id: r.id,\n path: r.path,\n label: r.label,\n enabled: r.enabled === 1,\n last_scan_at: r.last_scan_at,\n })),\n });\n },\n {\n name: \"documents_list_sources\",\n description:\n \"List the folders Jarela is indexing for document search. Useful before calling \" +\n \"documents_search with a source_id filter.\",\n schema: z.object({}),\n },\n);\n\nexport const documentsAddLocalSource = tool(\n async ({ path: inputPath, label }) => {\n const abs = path.resolve(inputPath);\n try {\n const st = await fs.stat(abs);\n if (!st.isDirectory()) {\n return JSON.stringify({ error: \"path is not a directory\" });\n }\n } catch {\n return JSON.stringify({ error: \"path does not exist or is unreadable\" });\n }\n if (getDocumentSourceByPath(abs)) {\n return JSON.stringify({ error: \"source already exists for this path\" });\n }\n try {\n const row = createDocumentSource({ path: abs, label: label ?? null, kind: \"local_folder\" });\n await notifyTriggerHandlers(\"source_changed\");\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n path: row.path,\n label: row.label,\n note: \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_local_source\",\n description:\n \"Add a local folder as a Documents source so its files become searchable via documents_search. \" +\n \"Pass any relative or absolute path; the tool resolves it to an absolute directory and validates it.\",\n schema: z.object({\n path: z.string().min(1).describe(\"Local folder path to index (relative or absolute).\"),\n label: z.string().optional().describe(\"Optional source label shown in the Documents panel.\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [documentsSearch, documentsListSources, documentsAddLocalSource]);\n\n// ── Remote document sources (ADR-0026) ──────────────────────────────────────\n//\n// These tools let agents add Jira projects, JQL queries, Confluence spaces,\n// and CQL queries as document sources, so a single retrieval surface\n// (`documents_search`) covers both local files and Atlassian content.\n\nconst REMOTE_KINDS = [\n \"confluence_space\",\n \"confluence_cql\",\n \"jira_project\",\n \"jira_jql\",\n \"github_pulls\",\n \"github_repo\",\n] as const;\n\nfunction syntheticPath(kind: DocumentSourceKind, config: Record<string, unknown>): string {\n switch (kind) {\n case \"confluence_space\": return `confluence-space://${String(config.space_key ?? \"\").trim()}`;\n case \"confluence_cql\": return `confluence-cql://${Buffer.from(String(config.cql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"jira_project\": return `jira-project://${String(config.project_key ?? \"\").trim()}`;\n case \"jira_jql\": return `jira-jql://${Buffer.from(String(config.jql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"github_pulls\": return `github-pulls://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n case \"github_repo\": return `github-repo://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n default: return `remote://${kind}/${Date.now()}`;\n }\n}\n\nfunction validateRemoteConfig(kind: typeof REMOTE_KINDS[number], cfg: Record<string, unknown>): string | null {\n if (kind === \"confluence_space\" && !cfg.space_key) return \"config.space_key is required for confluence_space\";\n if (kind === \"confluence_cql\" && !cfg.cql) return \"config.cql is required for confluence_cql\";\n if (kind === \"jira_project\" && !cfg.project_key) return \"config.project_key is required for jira_project\";\n if (kind === \"jira_jql\" && !cfg.jql) return \"config.jql is required for jira_jql\";\n if (kind === \"github_pulls\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_pulls\";\n if (kind === \"github_repo\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_repo\";\n return null;\n}\n\nexport const documentsAddRemoteSource = tool(\n async ({ kind, label, config }) => {\n const err = validateRemoteConfig(kind, config);\n if (err) return JSON.stringify({ error: err });\n const path = syntheticPath(kind, config);\n try {\n const row = createDocumentSource({ path, label, kind, config });\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n label: row.label,\n note: \"Remote sources index on the scheduler sweep (~10 min). Call documents_reindex_source with this id to force an immediate sync. Local folders auto-reindex on file changes.\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_remote_source\",\n description:\n \"Add a Jira project / JQL query / Confluence space / CQL query / GitHub repo as a document source. \" +\n \"Indexed content becomes searchable via documents_search alongside local folders. \" +\n \"Examples: kind='confluence_space' config={space_key:'ENG'}; kind='jira_project' \" +\n \"config={project_key:'ABC', recency_days:90}; kind='jira_jql' config={jql:'project = ABC AND status != Done'}; \" +\n \"kind='github_pulls' config={owner:'octocat', repo:'hello-world', state:'all', recency_days:60}; \" +\n \"kind='github_repo' config={owner:'octocat', repo:'hello-world', ref:'main', path_prefix:'docs'}.\",\n schema: z.object({\n kind: z.enum(REMOTE_KINDS),\n label: z.string().describe(\"Human-readable label shown in the Documents panel.\"),\n config: z.record(z.string(), z.unknown())\n .describe(\"Per-kind config. confluence_space: {space_key}. confluence_cql: {cql}. \" +\n \"jira_project: {project_key}. jira_jql: {jql}. \" +\n \"github_pulls: {owner, repo, state?, recency_days?}. \" +\n \"github_repo: {owner, repo, ref?, path_prefix?}. Optional everywhere: recency_days (int).\"),\n }),\n },\n);\n\nexport const documentsRemoveSource = tool(\n async ({ source_id, confirm }) => {\n if (confirm !== source_id) {\n return JSON.stringify({ error: \"pass confirm equal to source_id to actually delete\" });\n }\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n const ok = deleteDocumentSource(source_id);\n return JSON.stringify({ ok, id: source_id, label: row.label });\n },\n {\n name: \"documents_remove_source\",\n description:\n \"Delete a document source and all its indexed chunks. Destructive — requires `confirm` to equal `source_id`.\",\n schema: z.object({\n source_id: z.string(),\n confirm: z.string().describe(\"Must equal source_id to proceed.\"),\n }),\n },\n);\n\nexport const documentsReindexSource = tool(\n async ({ source_id }) => {\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n if (row.kind === \"local_folder\") {\n return JSON.stringify({\n error: \"documents_reindex_source is only for remote sources (Jira/Confluence). \" +\n \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n }\n try {\n const stats = await runRemoteSource(row);\n return JSON.stringify({ ok: true, id: source_id, stats });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_reindex_source\",\n description:\n \"Force an immediate incremental sync of a remote document source. Returns counts of added / updated / unchanged docs.\",\n schema: z.object({ source_id: z.string() }),\n },\n);\n\nexport const documentsIndexUrl = tool(\n async ({ input }) => {\n try {\n const res = await indexOnDemand(input);\n return JSON.stringify({ ok: true, ...res });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_index_url\",\n description:\n \"Fetch and index a single Jira issue, Confluence page, or GitHub PR/issue/file on demand, \" +\n \"stored under a shared 'On-demand URLs' source. Accepts a bare Jira key (ABC-123), a \" +\n \"/browse/<KEY> URL, a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, \" +\n \"/issues/<n>, or /blob/<ref>/<path> URL.\",\n schema: z.object({\n input: z.string().describe(\"Jira key, Jira URL, Confluence page URL, or GitHub PR/issue/blob URL\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [\n documentsAddRemoteSource,\n documentsRemoveSource,\n documentsReindexSource,\n documentsIndexUrl,\n]);\n","import { execSync } from \"node:child_process\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { getInjectedSubprocessEnv } from \"@/lib/env/allowlist\";\n\nconst MAX_OUTPUT_BYTES = 8_000;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_TIMEOUT_MS = 60_000;\n\nconst BLOCKED_PATTERNS = [\n /\\brm\\s+-rf\\s+\\/\\b/i,\n /\\bshutdown\\b/i,\n /\\breboot\\b/i,\n /\\bmkfs\\b/i,\n /:\\s*\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:\\s*&\\s*\\}\\s*;/,\n];\n\nfunction isBlockedCommand(command: string): boolean {\n return BLOCKED_PATTERNS.some((pattern) => pattern.test(command));\n}\n\nfunction clipOutput(text: string, max = MAX_OUTPUT_BYTES): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: `${text.slice(0, max)}\\n[output truncated]`, truncated: true };\n}\n\nfunction runLocalCommand(\n command: string,\n options: {\n cwd?: string;\n env?: Record<string, string>;\n timeout_ms?: number;\n allow_unsafe?: boolean;\n },\n): string {\n if (!command.trim()) {\n return JSON.stringify({ exit_code: 1, stderr: \"command is required\" });\n }\n\n const timeout = Math.min(options.timeout_ms ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n if (!options.allow_unsafe && isBlockedCommand(command)) {\n return JSON.stringify({\n exit_code: 126,\n stderr: \"Command blocked by safety policy. Pass allow_unsafe=true only when you fully trust the command.\",\n });\n }\n\n const cwd = options.cwd?.trim() ? options.cwd : process.cwd();\n // Layered env. Later spreads win:\n // 1. process.env — PATH, HOME, locale, the shell's exports\n // 2. integration-store credentials — so a service install (launchd,\n // systemd) where ANTHROPIC_API_KEY etc. were never exported in the\n // service's environment still hands those values to subprocesses.\n // The encrypted store, populated by env-sync from the user's rc\n // or via the Integrations panel, is the canonical source.\n // 3. options.env — explicit per-call override always wins.\n const env = { ...process.env, ...getInjectedSubprocessEnv(), ...options.env };\n\n try {\n const output = execSync(command, {\n cwd,\n env,\n timeout,\n encoding: \"utf8\",\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const clipped = clipOutput(output);\n return JSON.stringify({ exit_code: 0, stdout: clipped.value, truncated: clipped.truncated, cwd });\n } catch (err: unknown) {\n const e = err as { stdout?: string; stderr?: string; status?: number; message?: string };\n const out = clipOutput(String(e.stdout ?? \"\"));\n const errText = clipOutput(String(e.stderr ?? e.message ?? \"\"), 2_000);\n return JSON.stringify({\n exit_code: e.status ?? 1,\n stdout: out.value,\n stderr: errText.value,\n truncated: out.truncated || errText.truncated,\n cwd,\n });\n }\n}\n\nconst execSchema = z.object({\n command: z.string().describe(\"Shell command to execute\"),\n cwd: z.string().optional().describe(\"Working directory for command execution (defaults to process cwd)\"),\n env: z.record(z.string(), z.string()).optional().describe(\"Environment variables to inject for this command\"),\n timeout_ms: z.number().optional().describe(\"Timeout in milliseconds (default 10000, max 60000)\"),\n allow_unsafe: z.boolean().optional().describe(\"Set true to bypass safety blocking for risky commands\"),\n});\n\nexport const localExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"local_exec\",\n description: \"Run local shell commands with optional cwd/env overrides. Output is truncated to 8 KB.\",\n schema: execSchema,\n },\n);\n\nexport const shellExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"shell_exec\",\n description: \"Backward-compatible alias for local_exec.\",\n schema: execSchema,\n },\n);\n\nregisterTools(\"Shell\", [localExecTool, shellExecTool]);\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\n// Dedicated file tools. Agents previously had to drive every edit through\n// `local_exec` / `shell_exec`, which works for \"create a new file with this\n// content\" (echo / Set-Content) but is hostile to in-place edits: quoting\n// rules differ per shell, multi-line strings break under cmd.exe, and a\n// read-modify-write cycle needs two shell calls plus careful diff-by-hand.\n// These tools give agents a first-class file write + targeted edit surface.\n\nconst MAX_READ_BYTES = 64_000;\nconst MAX_WRITE_BYTES = 2_000_000;\n// Hard cap on the JSON payload returned by file_list. Stops a misconfigured\n// recursive listing of a giant tree from blowing the LLM's prompt budget\n// (one user hit 361K tokens / 64K limit from a single call).\nconst MAX_LIST_JSON_BYTES = 24_000;\n\nfunction clip(text: string, max: number): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: text.slice(0, max), truncated: true };\n}\n\n// Resolve agent-supplied paths against the USER'S HOME directory, not\n// process.cwd(). In production cwd is the Jarela install dir\n// (%LOCALAPPDATA%\\Programs\\Jarela) — if the agent writes \"notes.txt\"\n// expecting it to land somewhere visible, it lands buried in the install\n// tree and the user concludes the tool didn't run. Home is the natural\n// default for an \"assistant on my computer\". Absolute paths and ~/ paths\n// are honored verbatim.\nfunction resolvePath(p: string): string {\n if (!p.trim()) throw new Error(\"path is required\");\n let s = p.trim();\n if (s === \"~\") return os.homedir();\n if (s.startsWith(\"~/\") || s.startsWith(\"~\\\\\")) {\n s = path.join(os.homedir(), s.slice(2));\n return path.resolve(s);\n }\n if (path.isAbsolute(s)) return path.resolve(s);\n return path.resolve(os.homedir(), s);\n}\n\n// Filesystem denylist for agent-driven file tools. The LLM has free\n// rein over the user's HOME by design — but a handful of subtrees hold\n// credentials whose disclosure or mutation is far more dangerous than\n// any chat use case justifies: SSH private keys, GPG secret rings,\n// cached cloud-provider tokens, the gh CLI auth blob, kubeconfig, the\n// docker daemon config. We also forbid writes to ~/.jarela so a\n// prompt-injected page can't rewrite the app's own SQLite state.\n//\n// Operators with an explicit need (e.g. asking the agent to fix an\n// authorized_keys file) can opt back in with\n// JARELA_ALLOW_SENSITIVE_FILES=1.\nfunction isInside(abs: string, parent: string): boolean {\n const a = path.resolve(abs);\n const p = path.resolve(parent);\n if (a === p) return true;\n const rel = path.relative(p, a);\n return !!rel && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n}\n\nfunction sensitiveBase(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".ssh\"),\n path.join(home, \".gnupg\"),\n path.join(home, \".aws\"),\n path.join(home, \".config\", \"gh\"),\n path.join(home, \".kube\"),\n path.join(home, \".docker\"),\n ];\n}\n\nfunction sensitiveFiles(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".netrc\"),\n path.join(home, \"_netrc\"), // Windows convention\n path.join(home, \".pgpass\"),\n ];\n}\n\nfunction jarelaDataDir(): string {\n return process.env.JARELA_DB_DIR\n ? path.resolve(process.env.JARELA_DB_DIR)\n : path.join(os.homedir(), \".jarela\");\n}\n\nfunction assertSafePath(abs: string, op: \"read\" | \"write\"): void {\n if (process.env.JARELA_ALLOW_SENSITIVE_FILES === \"1\") return;\n for (const base of sensitiveBase()) {\n if (isInside(abs, base)) {\n throw new Error(\n `refused: '${abs}' is inside a credential directory (${path.basename(base)}). ` +\n `Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n for (const f of sensitiveFiles()) {\n if (path.resolve(abs) === path.resolve(f)) {\n throw new Error(\n `refused: '${abs}' is a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n // Filename-based defense: catch private-key files anywhere on disk.\n const base = path.basename(abs).toLowerCase();\n if (\n base === \"id_rsa\" ||\n base === \"id_ed25519\" ||\n base === \"id_ecdsa\" ||\n base === \"id_dsa\" ||\n base.endsWith(\".pem\") ||\n base.endsWith(\".key\") ||\n base === \"credentials\"\n ) {\n throw new Error(\n `refused: '${abs}' looks like a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n if (op === \"write\" && isInside(abs, jarelaDataDir())) {\n throw new Error(\n `refused: '${abs}' is inside Jarela's data dir; the agent must not mutate app state directly.`,\n );\n }\n}\n\n// --- read ---------------------------------------------------------------\n\nconst readSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n start_line: z.number().int().min(1).optional().describe(\"1-based first line to include\"),\n end_line: z.number().int().min(1).optional().describe(\"1-based last line to include (inclusive)\"),\n});\n\nexport const fileReadTool = tool(\n async ({ path: filePath, start_line, end_line }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"read\");\n const raw = await fs.readFile(abs, \"utf8\");\n let content = raw;\n let lineRange: { start: number; end: number } | null = null;\n if (start_line || end_line) {\n const lines = raw.split(/\\r?\\n/);\n const s = Math.max(1, start_line ?? 1);\n const e = Math.min(lines.length, end_line ?? lines.length);\n content = lines.slice(s - 1, e).join(\"\\n\");\n lineRange = { start: s, end: e };\n }\n const clipped = clip(content, MAX_READ_BYTES);\n return JSON.stringify({\n ok: true,\n path: abs,\n content: clipped.value,\n truncated: clipped.truncated,\n line_range: lineRange,\n total_lines: raw.split(/\\r?\\n/).length,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_read\",\n description:\n \"Read a UTF-8 text file. Optional 1-based start_line/end_line slice. Output clipped at 64 KB — for large files always pass a line range and walk in chunks.\",\n schema: readSchema,\n },\n);\n\n// --- write --------------------------------------------------------------\n\nconst writeSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n content: z.string().describe(\"Full file content. Overwrites the file if it exists.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories (default true)\"),\n});\n\nexport const fileWriteTool = tool(\n async ({ path: filePath, content, create_dirs }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n if (content.length > MAX_WRITE_BYTES) {\n return JSON.stringify({ ok: false, path: abs, error: `content exceeds ${MAX_WRITE_BYTES} bytes` });\n }\n assertSafePath(abs, \"write\");\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(abs), { recursive: true });\n }\n let existed = true;\n try {\n await fs.access(abs);\n } catch {\n existed = false;\n }\n await fs.writeFile(abs, content, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_written: Buffer.byteLength(content, \"utf8\"),\n created: !existed,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_write\",\n description:\n \"Create or fully overwrite a UTF-8 text file. Parent directories are created by default. Use file_edit for targeted in-place changes.\",\n schema: writeSchema,\n },\n);\n\n// --- edit ---------------------------------------------------------------\n\nconst editSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n old_string: z\n .string()\n .min(1)\n .describe(\n \"Exact literal substring to replace. Must appear EXACTLY ONCE in the file (include surrounding context to disambiguate).\",\n ),\n new_string: z.string().describe(\"Replacement text. May be empty to delete.\"),\n});\n\nexport const fileEditTool = tool(\n async ({ path: filePath, old_string, new_string }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"write\");\n const raw = await fs.readFile(abs, \"utf8\");\n const first = raw.indexOf(old_string);\n if (first === -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string not found. Re-read the file and try with the exact current content.\",\n });\n }\n const second = raw.indexOf(old_string, first + old_string.length);\n if (second !== -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string matches multiple times. Add surrounding context to make it unique.\",\n match_count: raw.split(old_string).length - 1,\n });\n }\n const next = raw.slice(0, first) + new_string + raw.slice(first + old_string.length);\n await fs.writeFile(abs, next, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_before: Buffer.byteLength(raw, \"utf8\"),\n bytes_after: Buffer.byteLength(next, \"utf8\"),\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_edit\",\n description:\n \"Replace a single exact-match substring inside a file. The old_string must appear exactly once — include enough surrounding context to disambiguate. Use this for in-place edits instead of shell heredocs.\",\n schema: editSchema,\n },\n);\n\n// --- move / rename ------------------------------------------------------\n\nconst moveSchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is moved into it preserving its basename.\"),\n overwrite: z\n .boolean()\n .optional()\n .describe(\"Allow replacing an existing destination file (default false). Existing directories are never overwritten.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories of the destination (default true).\"),\n});\n\nexport const fileMoveTool = tool(\n async ({ source, destination, overwrite, create_dirs }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"write\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n // If destination is an existing directory, move source INTO it\n // preserving its basename — matches `mv src dir/` semantics.\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // dst missing — fine\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat) {\n if (dstStat.isDirectory()) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination is an existing directory; refusing to overwrite\",\n });\n }\n if (!overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n }\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n }\n await fs.rename(srcAbs, dstAbs);\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n // Cross-device rename fails with EXDEV on Linux/macOS. Fall back to\n // copy+unlink so the agent doesn't need to know about device boundaries.\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"EXDEV\") {\n try {\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n await fs.rm(srcAbs, { recursive: true, force: true });\n return JSON.stringify({ ok: true, source: srcAbs, destination: dstAbs, cross_device: true });\n } catch (err2) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err2 as Error).message });\n }\n }\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_move\",\n description:\n \"Move or rename a file or directory. If destination is an existing directory, source is moved into it. Handles cross-device moves via copy+remove fallback.\",\n schema: moveSchema,\n },\n);\n\n// --- list ---------------------------------------------------------------\n\nconst listSchema = z.object({\n path: z.string().describe(\"Directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n max_entries: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .describe(\"Cap on returned entries (default 200, max 500). Listings are non-recursive — to explore subtrees, call file_list once per directory.\"),\n include_hidden: z\n .boolean()\n .optional()\n .describe(\"Include dot-prefixed entries (default false)\"),\n pattern: z\n .string()\n .optional()\n .describe(\"Optional case-insensitive substring filter applied to the basename\"),\n});\n\nexport const fileListTool = tool(\n async ({ path: dirPath, max_entries, include_hidden, pattern }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n const cap = max_entries ?? 200;\n const filter = pattern?.toLowerCase() ?? null;\n const entries: Array<{ path: string; kind: \"file\" | \"directory\" | \"other\"; size?: number }> = [];\n let truncated = false;\n try {\n let items: import(\"node:fs\").Dirent[];\n try {\n items = await fs.readdir(abs, { withFileTypes: true });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n items.sort((a, b) => a.name.localeCompare(b.name));\n for (const it of items) {\n if (entries.length >= cap) {\n truncated = true;\n break;\n }\n if (!include_hidden && it.name.startsWith(\".\")) continue;\n if (filter && !it.name.toLowerCase().includes(filter)) continue;\n const full = path.join(abs, it.name);\n const kind: \"file\" | \"directory\" | \"other\" = it.isDirectory()\n ? \"directory\"\n : it.isFile()\n ? \"file\"\n : \"other\";\n let size: number | undefined;\n if (kind === \"file\") {\n try {\n const st = await fs.stat(full);\n size = st.size;\n } catch {\n // ignore\n }\n }\n entries.push({ path: full, kind, size });\n }\n // Build the payload, then enforce a hard JSON byte cap. If the entry\n // list itself is too large (e.g. extremely long filenames), drop\n // entries from the tail until we fit so the LLM never gets a result\n // that blows past its prompt budget.\n const build = (es: typeof entries, droppedForSize: number) => JSON.stringify({\n ok: true,\n path: abs,\n entries: es,\n count: es.length,\n total_in_dir_after_filters: entries.length,\n truncated: truncated || droppedForSize > 0,\n truncated_hint: (truncated || droppedForSize > 0)\n ? \"Result truncated. Lower max_entries, add a `pattern` filter, or descend into a more specific subdirectory.\"\n : undefined,\n dropped_for_size: droppedForSize > 0 ? droppedForSize : undefined,\n filters: {\n include_hidden: !!include_hidden,\n pattern: pattern ?? null,\n max_entries: cap,\n },\n });\n let payload = build(entries, 0);\n if (payload.length > MAX_LIST_JSON_BYTES) {\n // Binary-trim entries from the tail until we fit.\n let lo = 0, hi = entries.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi + 1) / 2);\n if (build(entries.slice(0, mid), entries.length - mid).length <= MAX_LIST_JSON_BYTES) lo = mid;\n else hi = mid - 1;\n }\n payload = build(entries.slice(0, lo), entries.length - lo);\n }\n return payload;\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_list\",\n description:\n \"List one directory's entries (NON-RECURSIVE). To explore a subtree, call file_list once per directory and decide what to descend into based on the result — do NOT try to list everything at once. Hidden (dot) entries are skipped unless include_hidden=true. Optional `pattern` substring filter on basenames. Default cap 200 entries (max 500); the JSON result is hard-capped at ~24 KB and excess entries are dropped with a hint.\",\n schema: listSchema,\n },\n);\n\n// --- mkdir --------------------------------------------------------------\n\nconst mkdirSchema = z.object({\n path: z.string().describe(\"Directory path to create. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z.boolean().optional().describe(\"Create parent directories as needed (default true)\"),\n});\n\nexport const fileMkdirTool = tool(\n async ({ path: dirPath, recursive }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"write\");\n await fs.mkdir(abs, { recursive: recursive !== false });\n return JSON.stringify({ ok: true, path: abs });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_mkdir\",\n description: \"Create a directory. Creates parents by default.\",\n schema: mkdirSchema,\n },\n);\n\n// --- delete -------------------------------------------------------------\n\nconst deleteSchema = z.object({\n path: z.string().describe(\"File or directory path to remove. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z\n .boolean()\n .optional()\n .describe(\"Required to delete a non-empty directory (default false)\"),\n});\n\nexport const fileDeleteTool = tool(\n async ({ path: targetPath, recursive }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n assertSafePath(abs, \"write\");\n const st = await fs.stat(abs);\n if (st.isDirectory()) {\n if (!recursive) {\n // Try non-recursive rmdir first — succeeds only if empty.\n try {\n await fs.rmdir(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"empty\" });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOTEMPTY\") {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"directory is not empty. Pass recursive=true to delete its contents.\",\n });\n }\n throw err;\n }\n }\n await fs.rm(abs, { recursive: true, force: false });\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"recursive\" });\n }\n await fs.unlink(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"file\" });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_delete\",\n description:\n \"Delete a file or directory. Non-empty directories require recursive=true. Symlinks are not followed.\",\n schema: deleteSchema,\n },\n);\n\n// --- copy ---------------------------------------------------------------\n\nconst copySchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is copied into it preserving its basename.\"),\n overwrite: z.boolean().optional().describe(\"Allow replacing an existing destination (default false)\"),\n recursive: z.boolean().optional().describe(\"Recurse when copying a directory (default true)\"),\n});\n\nexport const fileCopyTool = tool(\n async ({ source, destination, overwrite, recursive }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"read\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // missing\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat && !overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n if (srcStat.isDirectory()) {\n if (recursive === false) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n error: \"source is a directory but recursive=false\",\n });\n }\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n } else {\n await fs.copyFile(srcAbs, dstAbs);\n }\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_copy\",\n description:\n \"Copy a file or directory. If destination is an existing directory, source is copied into it. Directories require recursive=true (default).\",\n schema: copySchema,\n },\n);\n\n// --- stat ---------------------------------------------------------------\n\nconst statSchema = z.object({\n path: z.string().describe(\"File or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n});\n\nexport const fileStatTool = tool(\n async ({ path: targetPath }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n const st = await fs.stat(abs);\n return JSON.stringify({\n ok: true,\n path: abs,\n exists: true,\n kind: st.isDirectory() ? \"directory\" : st.isFile() ? \"file\" : \"other\",\n size: st.size,\n modified_ms: st.mtimeMs,\n created_ms: st.birthtimeMs,\n mode: st.mode,\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n return JSON.stringify({ ok: true, path: abs, exists: false });\n }\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_stat\",\n description: \"Check whether a path exists and return its kind, size, and timestamps.\",\n schema: statSchema,\n },\n);\n\nregisterTools(\"Files\", [\n fileReadTool, fileWriteTool, fileEditTool, fileMoveTool, fileCopyTool,\n fileDeleteTool, fileListTool, fileMkdirTool, fileStatTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\n// Tavily is the preferred backend for agent-grade search (clean JSON, citations,\n// good ranking) but requires an API key. Without one we fall back to scraping\n// DuckDuckGo's HTML endpoint — which works without auth and goes through\n// EnvHttpProxyAgent on corporate networks.\nasync function tavilySearch(query: string, limit: number, apiKey: string): Promise<SearchResult[]> {\n const res = await fetch(\"https://api.tavily.com/search\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: limit,\n search_depth: \"basic\",\n }),\n });\n if (!res.ok) throw new Error(`Tavily ${res.status}: ${await res.text()}`);\n const data = (await res.json()) as { results?: Array<{ title: string; url: string; content?: string }> };\n return (data.results ?? []).slice(0, limit).map((r) => ({\n title: r.title,\n url: r.url,\n snippet: r.content ?? \"\",\n }));\n}\n\n// Rotate UA across retries — DDG flags repeated identical fingerprints.\nconst UA_POOL = [\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36\",\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0 Safari/537.36\",\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15\",\n \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0\",\n];\n\nasync function ddgSearch(query: string, limit: number): Promise<SearchResult[]> {\n // DDG returns a 202 \"anomaly detection\" placeholder when it suspects\n // automation. Retry with rotated UAs and exponential backoff. Empty results\n // on a 200 are treated as legitimate \"no hits\" and not retried.\n let lastStatus = 0;\n for (let attempt = 0; attempt < 5; attempt++) {\n const ua = UA_POOL[attempt % UA_POOL.length];\n const res = await fetch(\"https://html.duckduckgo.com/html/\", {\n method: \"POST\",\n headers: {\n \"User-Agent\": ua,\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Referer\": \"https://duckduckgo.com/\",\n },\n body: `q=${encodeURIComponent(query)}&kl=us-en`,\n });\n lastStatus = res.status;\n if (!res.ok) throw new Error(`DuckDuckGo ${res.status}`);\n const html = await res.text();\n const parsed = parseDDGHtml(html, limit);\n if (parsed.length > 0) return parsed;\n if (res.status !== 202) return parsed; // genuine empty result on 200\n // Backoff: 400, 900, 1600, 2500 ms — total max ≈ 5.4s\n await new Promise((r) => setTimeout(r, 400 + attempt * 500));\n }\n // All retries returned 202 placeholder — surface as empty so caller can handle.\n console.warn(`[web_search] DDG returned ${lastStatus} placeholder on all attempts for \"${query}\"`);\n return [];\n}\n\nfunction parseDDGHtml(html: string, limit: number): SearchResult[] {\n const results: SearchResult[] = [];\n // Each result block contains a result__a (title link) and a result__snippet (snippet link).\n const blockRe = /<div\\s+class=\"result\\s+results_links[^\"]*\"[\\s\\S]*?<\\/div>\\s*<\\/div>/g;\n let match: RegExpExecArray | null;\n while ((match = blockRe.exec(html)) !== null) {\n if (results.length >= limit) break;\n const block = match[0];\n const titleMatch = /<a[^>]+class=\"result__a\"[^>]+href=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n const snippetMatch = /<a[^>]+class=\"result__snippet\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n if (!titleMatch) continue;\n const url = unwrapDDGRedirect(decodeHTML(titleMatch[1]));\n if (!url) continue;\n const title = stripTags(titleMatch[2]).trim();\n const snippet = snippetMatch ? stripTags(snippetMatch[1]).trim() : \"\";\n if (title) results.push({ title, url, snippet });\n }\n return results;\n}\n\nfunction unwrapDDGRedirect(href: string): string | null {\n // DDG wraps outbound links as //duckduckgo.com/l/?uddg=<encoded>&...\n if (href.startsWith(\"//\")) href = `https:${href}`;\n try {\n const u = new URL(href);\n if (u.hostname.endsWith(\"duckduckgo.com\") && u.pathname === \"/l/\") {\n const real = u.searchParams.get(\"uddg\");\n return real ? decodeURIComponent(real) : null;\n }\n return u.toString();\n } catch {\n return null;\n }\n}\n\nfunction stripTags(s: string): string {\n return s.replace(/<[^>]+>/g, \"\");\n}\n\nfunction decodeHTML(s: string): string {\n return s\n .replace(/&amp;/g, \"&\")\n .replace(/&quot;/g, '\"')\n .replace(/&#x27;/g, \"'\")\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\");\n}\n\nexport const webSearchTool = tool(\n async ({ query, max_results }) => {\n const limit = Math.min(max_results ?? 5, 10);\n const tavilyKey = process.env.TAVILY_API_KEY;\n\n try {\n const results = tavilyKey\n ? await tavilySearch(query, limit, tavilyKey)\n : await ddgSearch(query, limit);\n return JSON.stringify({\n query,\n provider: tavilyKey ? \"tavily\" : \"duckduckgo\",\n results,\n total: results.length,\n });\n } catch (err) {\n return JSON.stringify({\n query,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n },\n {\n name: \"web_search\",\n description:\n \"Search the web and return relevant results (title, url, snippet). \" +\n \"Best for factual lookups, current events, documentation, and research. \" +\n \"Returns up to 10 results per call; default 5.\",\n schema: z.object({\n query: z.string().describe(\"Search query\"),\n max_results: z.number().optional().describe(\"Max results to return (default 5, max 10)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webSearchTool]);\n","// SSRF guard: classify an address (or hostname) as \"private\" — i.e. one\n// that an LLM-driven agent should never be allowed to reach with a\n// server-side fetch driven by attacker-controlled input. The bar is set\n// by what the access middleware (lib/auth/access.ts) treats as\n// privileged: anything that resolves to loopback hits the API without\n// authentication, and link-local / cloud-metadata / RFC1918 ranges\n// reach the host's LAN or cloud provider's introspection surface.\n//\n// Used by `web_fetch` and other agent-controlled URL fetchers to block\n// the canonical SSRF / metadata-service paths:\n// - http://127.0.0.1:4312/api/v1/... → self-call into our own admin API\n// - http://169.254.169.254/... → AWS/GCE/Azure metadata\n// - http://10.x / 192.168.x / etc. → LAN router / printer admin\n//\n// Operators with a legitimate need (e.g. fetching from an internal docs\n// server) can opt back in with `JARELA_ALLOW_PRIVATE_FETCH=1`.\n\nimport { promises as dns } from \"node:dns\";\nimport net from \"node:net\";\n\nexport type PrivateClassification =\n | \"public\"\n | \"loopback\"\n | \"private\"\n | \"link-local\"\n | \"unspecified\"\n | \"broadcast\"\n | \"reserved\";\n\nfunction ipv4InCidr(addr: number, prefix: number, bits: number): boolean {\n const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0;\n return (addr & mask) === (prefix & mask);\n}\n\nfunction ipv4ToNumber(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let n = 0;\n for (const part of parts) {\n const v = Number(part);\n if (!Number.isInteger(v) || v < 0 || v > 255) return null;\n n = (n << 8) | v;\n }\n return n >>> 0;\n}\n\nfunction classifyIPv4(ip: string): PrivateClassification {\n const n = ipv4ToNumber(ip);\n if (n === null) return \"reserved\";\n // 0.0.0.0/8 — \"this network\"\n if (ipv4InCidr(n, ipv4ToNumber(\"0.0.0.0\")!, 8)) return \"unspecified\";\n // 127.0.0.0/8 — loopback\n if (ipv4InCidr(n, ipv4ToNumber(\"127.0.0.0\")!, 8)) return \"loopback\";\n // 10.0.0.0/8\n if (ipv4InCidr(n, ipv4ToNumber(\"10.0.0.0\")!, 8)) return \"private\";\n // 172.16.0.0/12\n if (ipv4InCidr(n, ipv4ToNumber(\"172.16.0.0\")!, 12)) return \"private\";\n // 192.168.0.0/16\n if (ipv4InCidr(n, ipv4ToNumber(\"192.168.0.0\")!, 16)) return \"private\";\n // 169.254.0.0/16 — link-local (incl. cloud metadata at 169.254.169.254)\n if (ipv4InCidr(n, ipv4ToNumber(\"169.254.0.0\")!, 16)) return \"link-local\";\n // 100.64.0.0/10 — CGNAT / Tailscale carrier-grade NAT range. Treat as\n // private: anything reachable here is a tailnet peer, not a public URL.\n if (ipv4InCidr(n, ipv4ToNumber(\"100.64.0.0\")!, 10)) return \"private\";\n // 224.0.0.0/4 — multicast; 240.0.0.0/4 — reserved; 255.255.255.255 — broadcast\n if (ipv4InCidr(n, ipv4ToNumber(\"224.0.0.0\")!, 4)) return \"reserved\";\n if (ipv4InCidr(n, ipv4ToNumber(\"240.0.0.0\")!, 4)) return \"reserved\";\n return \"public\";\n}\n\nfunction classifyIPv6(ip: string): PrivateClassification {\n // Normalise: lower-case, drop zone id (fe80::1%eth0).\n const bare = ip.toLowerCase().split(\"%\")[0];\n if (bare === \"::\" || bare === \"::0\") return \"unspecified\";\n if (bare === \"::1\") return \"loopback\";\n // IPv4-mapped (::ffff:a.b.c.d) — classify the embedded v4.\n if (bare.startsWith(\"::ffff:\")) {\n const v4 = bare.slice(7);\n if (net.isIPv4(v4)) return classifyIPv4(v4);\n }\n // fe80::/10 — link-local\n if (/^fe[89ab][0-9a-f]?:/.test(bare)) return \"link-local\";\n // fc00::/7 — unique local addresses\n if (/^f[cd][0-9a-f]{0,2}:/.test(bare)) return \"private\";\n // ff00::/8 — multicast\n if (bare.startsWith(\"ff\")) return \"reserved\";\n return \"public\";\n}\n\nexport function classifyAddress(ip: string): PrivateClassification {\n if (net.isIPv4(ip)) return classifyIPv4(ip);\n if (net.isIPv6(ip)) return classifyIPv6(ip);\n return \"reserved\";\n}\n\nexport function isPrivateAddress(ip: string): boolean {\n const cls = classifyAddress(ip);\n return cls !== \"public\";\n}\n\nexport interface UrlCheckResult {\n allowed: boolean;\n reason?: PrivateClassification | \"invalid-url\" | \"unsupported-scheme\" | \"resolve-failed\";\n resolved?: string[];\n}\n\n/**\n * Pre-flight check for a server-side fetch driven by agent input.\n *\n * Returns `{ allowed: true }` when every IP the URL's hostname resolves\n * to is publicly routable. If `JARELA_ALLOW_PRIVATE_FETCH=1` the result\n * is always `{ allowed: true }` (operator opt-out).\n *\n * Hostnames that fail to resolve are treated as **rejected** — better to\n * refuse than to hand the question off to undici and re-resolve at\n * connect time, when we have no way to inspect the answer.\n */\nexport async function checkPublicUrl(rawUrl: string): Promise<UrlCheckResult> {\n if (process.env.JARELA_ALLOW_PRIVATE_FETCH === \"1\") {\n return { allowed: true };\n }\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return { allowed: false, reason: \"invalid-url\" };\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return { allowed: false, reason: \"unsupported-scheme\" };\n }\n // Strip [] from IPv6 literals so net.isIP / dns.lookup work.\n const host = url.hostname.replace(/^\\[|\\]$/g, \"\");\n if (net.isIP(host)) {\n const cls = classifyAddress(host);\n return cls === \"public\" ? { allowed: true, resolved: [host] } : { allowed: false, reason: cls, resolved: [host] };\n }\n let addrs: Array<{ address: string; family: number }>;\n try {\n addrs = await dns.lookup(host, { all: true });\n } catch {\n return { allowed: false, reason: \"resolve-failed\" };\n }\n const resolved = addrs.map((a) => a.address);\n for (const addr of resolved) {\n const cls = classifyAddress(addr);\n if (cls !== \"public\") return { allowed: false, reason: cls, resolved };\n }\n return { allowed: true, resolved };\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { checkPublicUrl } from \"@/lib/utils/private-ip\";\nimport { registerTools } from \"./registry\";\n\nconst MAX_BYTES = 200_000;\nconst TIMEOUT_MS = 15_000;\n// Defense against SSRF redirect chains: every Location-hop is re-checked\n// against the SSRF policy. Cap the chain so a malicious server can't\n// pin us in a redirect loop.\nconst MAX_REDIRECTS = 5;\n\nfunction extractTitle(html: string): string | null {\n const m = /<title[^>]*>([^<]+)<\\/title>/i.exec(html);\n return m ? m[1].trim() : null;\n}\n\n// Pull image URLs out of a fetched page so the agent can embed them in its\n// reply via standard markdown `![alt](url)`. We expose three categories:\n// - og: the page's primary OG image (most useful — chosen by the publisher)\n// - twitter: the Twitter card image (close second)\n// - samples: the first few <img src=…> tags (fallback when meta is missing)\n//\n// All URLs are resolved to absolute against the final fetched URL so the\n// agent can use them as-is. Data URIs and tracking pixels are filtered out.\nfunction extractImages(html: string, baseUrl: string): {\n og: string | null;\n twitter: string | null;\n samples: string[];\n} {\n const og =\n /<meta[^>]+property=[\"']og:image(?::secure_url|:url)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+property=[\"']og:image[\"']/i.exec(html)?.[1] ?? null;\n\n const twitter =\n /<meta[^>]+name=[\"']twitter:image(?::src)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+name=[\"']twitter:image[\"']/i.exec(html)?.[1] ?? null;\n\n const seen = new Set<string>();\n const samples: string[] = [];\n for (const m of html.matchAll(/<img[^>]+src=[\"']([^\"']+)[\"']/gi)) {\n const src = m[1];\n if (!src || src.startsWith(\"data:\")) continue;\n // Skip obvious tracking pixels and tiny svgs.\n if (/(?:1x1|pixel|spacer)\\.(?:gif|png)/i.test(src)) continue;\n const abs = resolveUrl(src, baseUrl);\n if (!abs || seen.has(abs)) continue;\n seen.add(abs);\n samples.push(abs);\n if (samples.length >= 6) break;\n }\n\n return {\n og: resolveUrl(og, baseUrl),\n twitter: resolveUrl(twitter, baseUrl),\n samples,\n };\n}\n\nfunction resolveUrl(u: string | null | undefined, base: string): string | null {\n if (!u) return null;\n try { return new URL(u, base).toString(); } catch { return null; }\n}\n\nexport const webFetchTool = tool(\n async ({ url, mode, max_chars }) => {\n if (!/^https?:\\/\\//.test(url)) {\n return JSON.stringify({ error: \"url must start with http:// or https://\" });\n }\n const ctrl = new AbortController();\n const timeout = setTimeout(() => ctrl.abort(), TIMEOUT_MS);\n try {\n // SSRF guard. The LLM controls `url`, and our HTTP middleware\n // treats loopback callers as the host machine's admin user — a\n // prompt-injected page could otherwise ask the agent to fetch\n // http://127.0.0.1:4312/api/v1/... and elevate. Same story for\n // 169.254.169.254 (cloud metadata) and the RFC1918 ranges.\n // Operators with a legitimate intranet need can opt back in via\n // JARELA_ALLOW_PRIVATE_FETCH=1.\n const initialCheck = await checkPublicUrl(url);\n if (!initialCheck.allowed) {\n return JSON.stringify({\n url,\n error: `Refused to fetch private/loopback address (${initialCheck.reason}). Set JARELA_ALLOW_PRIVATE_FETCH=1 to override.`,\n });\n }\n\n // Manual redirect chasing so each hop is re-checked against the\n // SSRF policy. A 30x to an attacker-controlled host could otherwise\n // bounce us into 169.254.x even though the initial URL looked\n // public.\n let currentUrl = url;\n let res: Response;\n for (let hop = 0; ; hop++) {\n res = await fetch(currentUrl, {\n signal: ctrl.signal,\n redirect: \"manual\",\n headers: {\n \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Accept\": \"text/html,application/xhtml+xml,*/*;q=0.8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n },\n });\n if (res.status < 300 || res.status >= 400) break;\n const loc = res.headers.get(\"location\");\n if (!loc) break;\n if (hop >= MAX_REDIRECTS) {\n return JSON.stringify({ url: currentUrl, error: `too many redirects (>${MAX_REDIRECTS})` });\n }\n let next: string;\n try {\n next = new URL(loc, currentUrl).toString();\n } catch {\n return JSON.stringify({ url: currentUrl, error: `invalid redirect target: ${loc}` });\n }\n const hopCheck = await checkPublicUrl(next);\n if (!hopCheck.allowed) {\n return JSON.stringify({\n url: next,\n error: `Refused redirect to private/loopback address (${hopCheck.reason}).`,\n });\n }\n currentUrl = next;\n }\n\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n const finalUrl = res.url || currentUrl;\n // Read up to MAX_BYTES so a 5MB page doesn't blow the agent's context.\n const reader = res.body?.getReader();\n const decoder = new TextDecoder();\n let bytesRead = 0;\n let raw = \"\";\n if (reader) {\n while (bytesRead < MAX_BYTES) {\n const { value, done } = await reader.read();\n if (done) break;\n bytesRead += value.byteLength;\n raw += decoder.decode(value, { stream: true });\n if (bytesRead >= MAX_BYTES) {\n await reader.cancel();\n break;\n }\n }\n }\n const truncated = bytesRead >= MAX_BYTES;\n const cap = max_chars ?? 8000;\n const wantHtml = mode === \"html\";\n const title = extractTitle(raw);\n const body = wantHtml ? raw : stripHtml(raw);\n const clipped = body.length > cap ? body.slice(0, cap) + \"…\" : body;\n const images = extractImages(raw, finalUrl);\n\n return JSON.stringify({\n url: finalUrl,\n status: res.status,\n content_type: contentType,\n title,\n mode: wantHtml ? \"html\" : \"text\",\n bytes_read: bytesRead,\n truncated,\n content: clipped,\n images,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return JSON.stringify({ url, error: msg });\n } finally {\n clearTimeout(timeout);\n }\n },\n {\n name: \"web_fetch\",\n description:\n \"Fetch the content of a URL. Default mode='text' returns extracted plain text (good for summarizing articles). \" +\n \"mode='html' returns raw HTML if you specifically need markup. Truncates after 200KB. \" +\n \"Use this when web_search returns a URL but you need the actual page content, or to fetch a specific known page. \" +\n \"The response also includes an `images` object with absolute URLs extracted from the page: \" +\n \"`og` (og:image — usually the best hero image), `twitter` (twitter:image), and `samples` (first few <img> tags). \" +\n \"Embed these in your reply with markdown `![alt](url)` to produce rich, image-rich answers.\",\n schema: z.object({\n url: z.string().describe(\"Absolute URL starting with http:// or https://\"),\n mode: z.enum([\"text\", \"html\"]).optional().describe(\"'text' (default) extracts readable text; 'html' returns raw markup\"),\n max_chars: z.number().optional().describe(\"Max characters to return after extraction (default 8000)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webFetchTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { registerTools } from \"./registry\";\n\n// Returns the user's last reported browser geolocation, if they've opted in\n// from the UI. The agent should call this whenever a request is location-\n// dependent (\"what's the weather\", \"find a coffee shop near me\", \"how long\n// to drive home\"). It returns a structured JSON payload — never coordinates\n// inline in prose. If sharing is disabled the result explains how to enable\n// it, so the agent can relay that to the user.\nexport const getUserLocationTool = tool(\n async () => {\n const profile = getUserProfile();\n if (!profile || profile.location_consent !== 1) {\n return JSON.stringify({\n available: false,\n reason: \"user has not enabled location sharing\",\n how_to_enable: \"Open the Profile panel and toggle 'Share my location'.\",\n });\n }\n if (\n typeof profile.location_lat !== \"number\" ||\n typeof profile.location_lng !== \"number\"\n ) {\n return JSON.stringify({\n available: false,\n reason: \"consent granted but no coordinates reported yet\",\n how_to_enable: \"Reload the app so the browser can request a fix.\",\n });\n }\n const updatedAt = profile.location_updated_at;\n const ageMs = updatedAt ? Date.now() - Date.parse(updatedAt) : null;\n return JSON.stringify({\n available: true,\n lat: profile.location_lat,\n lng: profile.location_lng,\n accuracy_m: profile.location_accuracy_m ?? null,\n label: profile.location_label ?? null,\n updated_at: updatedAt,\n age_seconds: ageMs !== null ? Math.round(ageMs / 1000) : null,\n });\n },\n {\n name: \"get_user_location\",\n description:\n \"Get the user's current geographic location (latitude/longitude) from their browser. Use this whenever the answer depends on where the user is — weather, nearby places, directions home, local time of points-of-interest. Returns { available, lat, lng, accuracy_m, label, age_seconds } or { available: false, reason } if the user hasn't opted in.\",\n schema: z.object({}).describe(\"No arguments — the user's location is stored server-side and updated by the client.\"),\n },\n);\n\nregisterTools(\"Web\", [getUserLocationTool]);\n","// generate_image: produce an image from a text prompt using Google's Gemini\n// image-generation models (a.k.a. \"nano banana\") via the Generative Language\n// REST API. Falls back to Imagen if the user picks one of those model ids.\n//\n// API key resolution: integrations store (\"google\" → api_key) →\n// GEMINI_API_KEY env → GOOGLE_API_KEY env. The Integrations panel is the\n// recommended way to set this.\n//\n// Output: PNG bytes written to ~/.jarela/files/<uuid>.png. The tool returns\n// a relative URL the chat renderer can embed via markdown `![alt](url)`.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { resolveGoogleApiKey, timeoutSignal } from \"@/lib/utils/google-api\";\nimport { registerTools } from \"./registry\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-image\";\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\ninterface ImagenPrediction {\n bytesBase64Encoded?: string;\n mimeType?: string;\n}\ninterface ImagenResponse {\n predictions?: ImagenPrediction[];\n error?: { message?: string };\n}\n\nasync function callGemini(model: string, prompt: string, apiKey: string): Promise<{ data: Buffer; mime: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`;\n const body = {\n contents: [{ role: \"user\", parts: [{ text: prompt }] }],\n generationConfig: { responseModalities: [\"IMAGE\", \"TEXT\"] },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Gemini request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"image/png\";\n if (data) return { data: Buffer.from(data, \"base64\"), mime };\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini returned no image: ${text}` : \"Gemini returned no image\");\n}\n\nasync function callImagen(model: string, prompt: string, apiKey: string, n: number, aspect: string): Promise<Array<{ data: Buffer; mime: string }>> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:predict?key=${encodeURIComponent(apiKey)}`;\n const body = {\n instances: [{ prompt }],\n parameters: { sampleCount: Math.max(1, Math.min(4, n)), aspectRatio: aspect },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Imagen request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as ImagenResponse;\n if (!res.ok) {\n throw new Error(`Imagen ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const preds = json.predictions ?? [];\n const out: Array<{ data: Buffer; mime: string }> = [];\n for (const p of preds) {\n if (p.bytesBase64Encoded) {\n out.push({ data: Buffer.from(p.bytesBase64Encoded, \"base64\"), mime: p.mimeType ?? \"image/png\" });\n }\n }\n if (out.length === 0) throw new Error(\"Imagen returned no image\");\n return out;\n}\n\nfunction describeError(err: unknown): string {\n if (!(err instanceof Error)) return String(err);\n const cause = (err as { cause?: unknown }).cause;\n if (cause instanceof Error) {\n const code = (cause as { code?: string }).code;\n return code ? `${err.message}: ${cause.message} (${code})` : `${err.message}: ${cause.message}`;\n }\n return err.message;\n}\n\nfunction extForMime(mime: string): string {\n if (mime === \"image/jpeg\") return \"jpg\";\n if (mime === \"image/webp\") return \"webp\";\n if (mime === \"image/gif\") return \"gif\";\n return \"png\";\n}\n\nexport const generateImageTool = tool(\n async ({ prompt, model, count, aspect_ratio }) => {\n const trimmed = prompt.trim();\n if (!trimmed) throw new Error(\"prompt is required and must be non-empty\");\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open the Integrations panel and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const m = (model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;\n const aspect = aspect_ratio ?? \"1:1\";\n const n = count ?? 1;\n\n const images = m.startsWith(\"imagen\")\n ? await callImagen(m, trimmed, apiKey, n, aspect)\n : [await callGemini(m, trimmed, apiKey)];\n\n const saved = images.map((img) => {\n const name = `img-${randomUUID()}.${extForMime(img.mime)}`;\n writeBinaryFile(name, img.data);\n const url = `/api/v1/files/${name}`;\n return { url, mime: img.mime, bytes: img.data.length };\n });\n\n return JSON.stringify({\n model: m,\n prompt: trimmed,\n images: saved,\n markdown: saved.map((s, i) => `![${trimmed.slice(0, 80)}${images.length > 1 ? ` (${i + 1})` : \"\"}](${s.url})`).join(\"\\n\\n\"),\n hint: \"Embed images in your reply using the `markdown` field verbatim, or build your own `![alt](url)` from `images[].url`.\",\n });\n },\n {\n name: \"generate_image\",\n description:\n \"Generate one or more images from a text prompt using Google's Gemini image models (default: gemini-2.5-flash-image) or Imagen. Returns local URLs the assistant should embed in its reply via markdown `![alt](url)`. Requires the Google integration (api_key) to be configured.\",\n schema: z.object({\n prompt: z.string().describe(\"Detailed description of the image to generate.\"),\n model: z\n .string()\n .optional()\n .describe(\n \"Optional Google model id. Defaults to `gemini-2.5-flash-image`. Use an `imagen-*` model (e.g. `imagen-3.0-generate-002`) for higher-fidelity stills.\",\n ),\n count: z\n .number()\n .int()\n .min(1)\n .max(4)\n .optional()\n .describe(\"Number of images to generate. Only honored by Imagen models; Gemini models always return 1.\"),\n aspect_ratio: z\n .enum([\"1:1\", \"3:4\", \"4:3\", \"9:16\", \"16:9\"])\n .optional()\n .describe(\"Aspect ratio. Only honored by Imagen models; ignored by Gemini image models.\"),\n }),\n },\n);\n\nregisterTools(\"Images\", [generateImageTool]);\n","// generate_voice: synthesize spoken audio from text using Gemini TTS and\n// return a /api/v1/files/ URL the assistant should embed in its reply.\n//\n// Voice/model are NOT exposed to the agent — they're locked to the\n// active agent's per-agent voice config (set by the user in AgentEditor).\n// The agent only controls *what* to say, *how* to say it (style), and\n// whether to autoplay. Multi-speaker scenes still allow per-speaker\n// voice selection because that's compositional, not preference.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { geminiTts, resolveGoogleApiKey } from \"@/lib/voice/gemini\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-preview-tts\";\nconst DEFAULT_VOICE = \"Kore\";\nconst MAX_TEXT_CHARS = 5000;\n\nconst SpeakerSchema = z.object({\n name: z.string().min(1).describe(\"Speaker label that appears in the text, e.g. 'Alice'.\"),\n voice_name: z.string().min(1).describe(\"Gemini prebuilt voice for this speaker (e.g. 'Kore', 'Puck').\"),\n});\n\nfunction resolveAgentVoice(config?: RunnableConfig): { model: string; voice: string } {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const thread = getThread(threadId);\n if (!thread?.agent_id) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const agent = getAgentConfig(thread.agent_id);\n return {\n model: agent?.voice_model?.trim() || DEFAULT_MODEL,\n voice: agent?.voice_name?.trim() || DEFAULT_VOICE,\n };\n}\n\nexport const generateVoiceTool = tool(\n async ({ text, style, speakers, autoplay }, config) => {\n const trimmed = (text ?? \"\").trim();\n if (!trimmed) throw new Error(\"text is required and must be non-empty\");\n if (trimmed.length > MAX_TEXT_CHARS) {\n throw new Error(`text exceeds ${MAX_TEXT_CHARS} character cap`);\n }\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open Integrations and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const { model, voice } = resolveAgentVoice(config);\n const speakerList = (speakers ?? [])\n .map((s) => ({ name: s.name.trim(), voiceName: s.voice_name.trim() }))\n .filter((s) => s.name && s.voiceName);\n\n const { wav } = await geminiTts({\n apiKey,\n model,\n voiceName: voice,\n text: trimmed,\n style: style?.trim() || undefined,\n speakers: speakerList.length >= 2 ? speakerList : undefined,\n });\n\n const name = `voice-${randomUUID()}.wav`;\n writeBinaryFile(name, wav);\n const baseUrl = `/api/v1/files/${name}`;\n const url = autoplay ? `${baseUrl}?autoplay=1` : baseUrl;\n\n return JSON.stringify({\n style: style ?? null,\n speakers: speakerList.length >= 2 ? speakerList : null,\n autoplay: !!autoplay,\n bytes: wav.length,\n url,\n markdown: `[\\u{1F50A} Voice clip${autoplay ? \" (auto)\" : \"\"}](${url})`,\n hint: \"Embed the `markdown` field verbatim in your reply on its own line; the chat renderer will turn that link into an inline audio player. Set autoplay=true only when the user asked you to speak (e.g. they sent voice input or explicitly asked you to talk). Do NOT wrap it in a code fence and do NOT transcribe the audio in the reply \\u2014 the player is the answer.\",\n });\n },\n {\n name: \"generate_voice\",\n description:\n \"Synthesize speech with Google's Gemini TTS using the agent's configured voice, and return a local audio URL the assistant must embed via the returned `markdown`. Use the `style` arg to steer tone/emotion (e.g. 'Say cheerfully', 'Whisper conspiratorially'). For dialogues, pass up to 2 `speakers` (with explicit voice names per speaker) and prefix each line in `text` with `Name: `. Requires the Google integration (api_key). The voice and model are picked by the user in the agent's settings and cannot be overridden here.\",\n schema: z.object({\n text: z\n .string()\n .min(1)\n .describe(\n \"The text to speak. For dialogues, write one turn per line as `Name: line` matching the `speakers` labels. Max 5000 chars.\",\n ),\n style: z\n .string()\n .optional()\n .describe(\n \"Natural-language style instruction prepended to the text, e.g. 'Say warmly and slowly', 'Whisper conspiratorially', 'In a tired, defeated voice', 'Read like a 1940s radio host'.\",\n ),\n speakers: z\n .array(SpeakerSchema)\n .min(2)\n .max(2)\n .optional()\n .describe(\n \"Optional 2-speaker setup for dialogues. When set, the agent's default voice is ignored and each line in `text` should start with one of the speaker `name`s followed by ': '. Use this only when composing a scripted dialogue with two distinct characters.\",\n ),\n autoplay: z\n .boolean()\n .optional()\n .describe(\n \"If true, the audio plays automatically when the message renders. Use this ONLY when the user clearly wants you to speak back (they sent voice input, said 'say it out loud', etc.). Default false \\u2014 user clicks play.\",\n ),\n }),\n },\n);\n\nregisterTools(\"Voice\", [generateVoiceTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport {\n createScheduledTask,\n listScheduledTasks,\n deleteScheduledTask,\n computeNextRun,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleTaskTool = tool(\n async (\n { prompt, when_iso, cron, description, silent, reaction_kind, reaction_script, reaction_script_args },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n if (!when_iso && !cron) return JSON.stringify({ error: \"Provide either when_iso (one-shot) or cron (recurring)\" });\n if (when_iso && cron) return JSON.stringify({ error: \"Provide only one of when_iso or cron, not both\" });\n // ADR-0032 — for kind='script' the agent must supply reaction_script.\n // For kind='agent_prompt' (default) prompt is required.\n if (reaction_kind === \"script\") {\n if (!reaction_script) {\n return JSON.stringify({ error: \"reaction_kind='script' requires reaction_script\" });\n }\n } else if (!prompt) {\n return JSON.stringify({ error: \"prompt is required when reaction_kind='agent_prompt'\" });\n }\n\n try {\n const kind = cron ? \"cron\" : \"once\";\n const schedule = cron ?? when_iso!;\n // Validate by computing the first run.\n const firstRun = computeNextRun(kind, schedule);\n if (kind === \"once\" && firstRun.getTime() < Date.now() - 60_000) {\n return JSON.stringify({ error: `when_iso \"${schedule}\" is in the past` });\n }\n const row = createScheduledTask({\n agent_id: agentId,\n prompt,\n description,\n kind,\n schedule,\n silent,\n reaction_kind,\n reaction_script,\n reaction_script_args,\n });\n // Make sure the poller is awake so newly created tasks fire on time.\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n kind,\n schedule,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_task\",\n description:\n \"Schedule a future firing for this agent. \" +\n \"For one-shot reminders pass when_iso (ISO 8601 timestamp, e.g. '2026-05-15T15:00:00Z'). \" +\n \"For recurring tasks pass a 5-field cron expression (e.g. '0 9 * * 1-5' = weekdays 9am). \" +\n \"Use the current time from your context to convert phrases like 'in 30 minutes' or 'tomorrow at 9am' into when_iso. \" +\n \"Default reaction_kind is 'agent_prompt' — the firing sends `prompt` to the agent. \" +\n \"Set reaction_kind='script' to fire a registered reaction.* script with no LLM round-trip; \" +\n \"use list_reaction_scripts to discover names. \" +\n \"Set silent=true for background polling tasks: suppresses the task_completed notification AND instructs the \" +\n \"agent to answer NO_REPLY on firings where there is nothing material to surface (those turns are dropped). \" +\n \"Errors still notify so failures aren't hidden. Visible firings remain tagged 'scheduled' so the user can hide \" +\n \"the group with the chat filter toolbar.\",\n schema: z.object({\n prompt: z.string().optional().describe(\n \"The prompt the agent will receive when the task fires. Required when reaction_kind='agent_prompt' (the default).\",\n ),\n when_iso: z.string().optional().describe(\"ISO 8601 UTC timestamp for one-shot scheduling\"),\n cron: z.string().optional().describe(\"5-field cron expression for recurring scheduling\"),\n description: z.string().optional().describe(\"Short human-readable label for the task\"),\n silent: z.boolean().optional().describe(\n \"When true the task is muted: the task_completed notification is suppressed and the agent is instructed to \" +\n \"reply only when something material surfaces (NO_REPLY answers are dropped). Errors still notify. \" +\n \"Useful for background polling jobs (e.g. 'check inbox every 10 min').\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"ADR-0032 reaction discriminator. 'agent_prompt' (default) runs the agent with `prompt`. \" +\n \"'script' runs a registered reaction.* script with no LLM round-trip.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Must be a name returned by list_reaction_scripts (begins with 'reaction.').\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object of args forwarded to the reaction script. The script also receives a `task` descriptor.\",\n ),\n }),\n },\n);\n\nexport const listScheduledTasksTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const tasks = listScheduledTasks(agentId).map((t) => ({\n id: t.id,\n prompt: t.prompt,\n description: t.description,\n kind: t.kind,\n schedule: t.schedule,\n next_run_at: t.next_run_at,\n last_run_at: t.last_run_at,\n last_error: t.last_error,\n enabled: t.enabled === 1,\n silent: t.silent === 1,\n reaction_kind: t.reaction_kind,\n reaction_script: t.reaction_script,\n reaction_script_args: t.reaction_script_args ? safeJson(t.reaction_script_args) : null,\n }));\n return JSON.stringify({ tasks, count: tasks.length });\n },\n {\n name: \"list_scheduled_tasks\",\n description: \"List all scheduled tasks for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelScheduledTaskTool = tool(\n async ({ id }) => {\n const ok = deleteScheduledTask(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Task ${id} not found` });\n },\n {\n name: \"cancel_scheduled_task\",\n description: \"Cancel a previously scheduled task by id.\",\n schema: z.object({\n id: z.string().describe(\"Task id returned by schedule_task or list_scheduled_tasks\"),\n }),\n },\n);\n\nregisterTools(\"Schedule\", [scheduleTaskTool, listScheduledTasksTool, cancelScheduledTaskTool]);\n","// Watcher tools (ADR-0027). Agent-facing CRUD for event-driven tasks.\n// Mirrors lib/tools/schedule.ts in shape so agents have a familiar\n// surface area: schedule_task ↔ schedule_watcher, list_scheduled_tasks\n// ↔ list_watchers, cancel_scheduled_task ↔ cancel_watcher.\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools, registeredTools } from \"./registry\";\nimport {\n createWatcher,\n listWatchers,\n deleteWatcher,\n} from \"@/lib/stores/watchers\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { listReactionScripts } from \"@/lib/triggers/scripts\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleWatcherTool = tool(\n async (\n {\n label,\n tool: toolName,\n args,\n every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n // Sanity-check that the tool exists locally. We can only register\n // watchers over built-in tools — MCP / external tool surfaces aren't\n // poll-safe in the scheduler (no per-request side context).\n const target = registeredTools().find((t) => t.name === toolName);\n if (!target) {\n return JSON.stringify({\n error: `Tool \"${toolName}\" is not a built-in tool. Watchers can only poll built-in tools.`,\n });\n }\n try {\n const row = createWatcher({\n agent_id: agentId,\n label,\n tool_name: toolName,\n tool_args: args ?? {},\n interval_seconds: every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n });\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n interval_seconds: row.interval_seconds,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_prompt: row.reaction_prompt,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_watcher\",\n description:\n \"Register an event-driven watcher: poll one built-in tool every N seconds \" +\n \"and re-engage this agent only when the tool's output changes since the \" +\n \"previous poll. Unlike schedule_task, this consumes zero LLM tokens between \" +\n \"changes — the scheduler runs the tool, hashes the result (SHA-256 of the \" +\n \"stringified return value), and only fires the agent on a diff. The agent \" +\n \"receives the previous + current results as context.\\n\\n\" +\n \"WHEN TO USE (use this instead of schedule_task whenever the user wants \" +\n \"to be notified about CHANGES rather than at fixed times):\\n\" +\n \" • 'tell me when Jira issue ABC-123 changes status' → jira_get_issue\\n\" +\n \" • 'ping me when a new ticket lands in SLPV assigned to me' → jira_search with a narrow JQL\\n\" +\n \" • 'notify me when files appear in ~/Downloads' → file_list on that path\\n\" +\n \" • 'watch this Confluence page for edits' → confluence_get_page\\n\" +\n \" • 'tell me when a webpage changes' → web_fetch\\n\\n\" +\n \"This is the SUBSTITUTE for webhooks and OS-level filesystem events, which \" +\n \"Jarela does not have. Don't tell the user 'no webhook support' — propose a \" +\n \"watcher instead.\\n\\n\" +\n \"LIMITS (be honest with the user about these):\\n\" +\n \" • Built-in tools only (no MCP / external tools — scheduler runs without per-request context).\\n\" +\n \" • Minimum interval 60 seconds.\\n\" +\n \" • Diff is byte-exact SHA-256 of the tool's stringified result. If the tool \" +\n \"returns volatile fields (e.g. `updated` timestamps, view counts) the watcher \" +\n \"will fire on every poll. Mitigate by passing args that narrow the tool's \" +\n \"output (e.g. `fields` on jira_search, specific paths on file_list).\\n\" +\n \" • First poll seeds the baseline silently — the agent is NOT fired on creation.\\n\\n\" +\n \"Set silent=true to mute the watcher: suppresses the task_completed notification on firing \" +\n \"AND lets the agent reply with NO_REPLY on changes it judges immaterial. Errors still notify.\\n\\n\" +\n \"REACTION KIND (ADR-0031): two reaction modes are supported.\\n\" +\n \" • 'agent_prompt' (default): on diff, this agent runs with reaction_prompt as the \" +\n \"directive (or the default 'summarise' directive if not supplied). Costs LLM tokens.\\n\" +\n \" • 'script': on diff, a built-in reaction script (`reaction.*`) runs INSTEAD of the \" +\n \"agent. Zero LLM tokens. Use list_reaction_scripts to discover available scripts \" +\n \"(e.g. `reaction.notify` posts a UI notification with the diff). Provide \" +\n \"reaction_script and optional reaction_script_args. Cannot be combined with reaction_prompt.\",\n schema: z.object({\n label: z.string().min(1).describe(\"Short human-readable name (e.g. 'ABC-123 status')\"),\n tool: z.string().min(1).describe(\"Name of a built-in tool to poll (e.g. 'jira_get_issue')\"),\n args: z.record(z.string(), z.unknown()).optional().describe(\n \"Arguments to pass to the tool on every poll, as a JSON object\",\n ),\n every_seconds: z.number().int().min(60).describe(\n \"Polling interval in seconds. Minimum 60.\",\n ),\n silent: z.boolean().optional().describe(\n \"When true the watcher is muted: the task_completed notification is suppressed and the agent is \" +\n \"instructed to reply only when the change is material (NO_REPLY firings are dropped). Errors still notify. \" +\n \"Visible firings remain tagged 'watcher'.\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"Reaction mode (ADR-0031). 'agent_prompt' (default) runs this agent on each diff; \" +\n \"'script' runs a built-in reaction.* script with no LLM round-trip.\",\n ),\n reaction_prompt: z.string().max(4000).optional().describe(\n \"Only valid when reaction_kind='agent_prompt' (or unset). Optional instruction for \" +\n \"what the agent should do on each detected change. Replaces the default 'summarise \" +\n \"the diff' directive. The previous + current tool results are still appended as \" +\n \"context, so the prompt should describe the REACTION (e.g. 'open a Jira ticket \" +\n \"against the broken dashboard', 'message me in plain English only if the price \" +\n \"dropped >5%'). Max 4000 characters.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Name of a registered reaction script \" +\n \"(must start with 'reaction.'). Use list_reaction_scripts to discover.\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object forwarded to the reaction script alongside the diff context \" +\n \"({watcher, previous, current}). Schema is script-specific.\",\n ),\n }),\n },\n);\n\nexport const listReactionScriptsTool = tool(\n async () => {\n const scripts = listReactionScripts();\n return JSON.stringify({ scripts, count: scripts.length });\n },\n {\n name: \"list_reaction_scripts\",\n description:\n \"List the names of built-in reaction scripts available to schedule_watcher AND \" +\n \"schedule_task when reaction_kind='script'. Reaction scripts run with NO LLM round-trip \" +\n \"on a firing. Watchers auto-merge {watcher, previous, current} into the script args; \" +\n \"scheduled tasks auto-merge a `task` descriptor (no diff context). Names are always \" +\n \"prefixed with `reaction.` (e.g. `reaction.notify`). Internal built-in scripts outside \" +\n \"the `reaction.` namespace (for example documents.reindex_local_file) are intentionally \" +\n \"excluded from this list.\",\n schema: z.object({}),\n },\n);\n\nexport const listWatchersTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const watchers = listWatchers(agentId).map((w) => ({\n id: w.id,\n label: w.label,\n tool: w.tool_name,\n args: safeParse(w.tool_args),\n interval_seconds: w.interval_seconds,\n next_run_at: w.next_run_at,\n last_run_at: w.last_run_at,\n last_fired_at: w.last_fired_at,\n last_error: w.last_error,\n enabled: w.enabled === 1,\n silent: w.silent === 1,\n reaction_kind: w.reaction_kind,\n reaction_prompt: w.reaction_prompt,\n reaction_script: w.reaction_script,\n reaction_script_args: w.reaction_script_args ? safeParse(w.reaction_script_args) : null,\n }));\n return JSON.stringify({ watchers, count: watchers.length });\n },\n {\n name: \"list_watchers\",\n description: \"List all event-driven watchers registered for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelWatcherTool = tool(\n async ({ id }) => {\n const ok = deleteWatcher(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Watcher ${id} not found` });\n },\n {\n name: \"cancel_watcher\",\n description: \"Cancel a previously registered watcher by id.\",\n schema: z.object({\n id: z.string().describe(\"Watcher id returned by schedule_watcher or list_watchers\"),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Schedule\", [\n scheduleWatcherTool,\n listWatchersTool,\n cancelWatcherTool,\n listReactionScriptsTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { createPendingAction, getPendingAction } from \"@/lib/stores/pending-actions\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n return getThread(threadId)?.agent_id ?? null;\n}\n\nexport const proposeConfigChangeTool = tool(\n async ({ kind, payload, reason }, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"no agent context\" });\n const row = createPendingAction({ agent_id: agentId, kind, payload, reason });\n // Surface as a browser notification so the user notices even if not on this agent.\n publishNotification({\n type: \"run_completed\", // reuse channel; UI can branch on preview text\n thread_id: \"\",\n agent_id: agentId,\n status: \"done\",\n preview: `🛠️ Proposed config change (${kind}) — awaiting your approval`,\n ts: Date.now(),\n });\n return JSON.stringify({\n proposal_id: row.id,\n status: \"pending\",\n message:\n \"Proposal queued for the user's approval. Tell the user briefly what you proposed and that \" +\n \"they need to approve it in the chat. Do not retry; check status later with check_proposal.\",\n });\n },\n {\n name: \"propose_config_change\",\n description:\n \"Propose a configuration change that requires user approval. Use this when you'd benefit from \" +\n \"installing/toggling an MCP server, or modifying agent settings (tool allowlist, identity, instructions, history window). \" +\n \"The proposal is queued and shown to the user; they explicitly approve or deny. \" +\n \"Don't propose changes the user didn't ask for — only when the current task clearly needs it.\",\n schema: z.object({\n kind: z\n .enum([\n \"install_mcp\",\n \"toggle_mcp\",\n \"update_agent_tools\",\n \"update_agent\",\n \"start_oauth\",\n \"set_provider_key\",\n \"enable_integration\",\n \"upsert_harness\",\n ])\n .describe(\"Type of change being proposed\"),\n payload: z.record(z.string(), z.unknown())\n .describe(\n \"Parameters for the change. NEVER put secrets, API keys, OAuth tokens, \" +\n \"or passwords in this object — those are collected by the approval UI \" +\n \"directly. Examples by kind:\\n\" +\n \"- install_mcp: { registry_id: 'github', variables: { GITHUB_TOKEN: 'asks-user-for-it' } } \" +\n \" OR { name, transport, spec }\\n\" +\n \"- toggle_mcp: { name: 'github', enabled: true }\\n\" +\n \"- update_agent_tools: { agent_id: '<this-agent>', tools: ['web_search', 'memory_*'] }\\n\" +\n \"- update_agent: { agent_id, identity?, instructions?, history_limit?, history_window_hours?, harness_id? } \" +\n \" — harness_id accepts an existing harness id ('builtin:default' or 'custom:<uuid>'), or null to inherit the global default\\n\" +\n \"- start_oauth: { integration_id: 'gmail' } — only after enable_integration saved client_id/secret\\n\" +\n \"- set_provider_key: { name: 'anthropic-default', provider: 'anthropic', model_id: 'claude-opus-4-7', is_default?: true } \" +\n \" — the user pastes the API key into the approval modal; do NOT include it here\\n\" +\n \"- enable_integration: { id: 'gmail' } — the user fills credentials in the approval modal\\n\" +\n \"- upsert_harness: { id?: 'custom:<uuid>', name, description?, sections: { capabilities?: {enabled,body}, plan_first?: {enabled,body}, presentation?: {enabled,body}, citation?: {enabled,body}, self_config?: {enabled,body} } } \" +\n \" — omit `id` to create; pass an existing custom:* id to edit. Built-in harnesses ('builtin:*') are read-only and rejected.\"\n ),\n reason: z.string().describe(\"Short human-readable reason shown to the user (≤100 chars)\"),\n }),\n },\n);\n\nexport const checkProposalTool = tool(\n async ({ proposal_id }) => {\n const row = getPendingAction(proposal_id);\n if (!row) return JSON.stringify({ error: `proposal ${proposal_id} not found` });\n return JSON.stringify({\n id: row.id,\n kind: row.kind,\n status: row.status,\n result: row.result ? safeParse(row.result) : null,\n created_at: row.created_at,\n decided_at: row.decided_at,\n });\n },\n {\n name: \"check_proposal\",\n description: \"Check the status of a previously-submitted config-change proposal by its id.\",\n schema: z.object({\n proposal_id: z.string(),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Config\", [proposeConfigChangeTool, checkProposalTool]);\n","// Read-only tools that expose integration manifests to the agent. See\n// ADR-0010 — these power the \"user asks how to connect X → agent narrates\n// the steps and proposes actions\" loop without giving the agent any new\n// privileges.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getManifest, listManifests } from \"@/lib/integrations/registry\";\nimport { registerTools } from \"./registry\";\nimport { getIntegrationStatus, isKnownIntegration } from \"@/lib/stores/integrations\";\n\nfunction manifestStatus(id: string): \"configured\" | \"not_configured\" | \"no_credentials_schema\" {\n if (!isKnownIntegration(id)) return \"no_credentials_schema\";\n return getIntegrationStatus(id)?.configured ? \"configured\" : \"not_configured\";\n}\n\nexport const listIntegrationsTool = tool(\n async () => {\n const summary = listManifests().map((m) => ({\n id: m.id,\n name: m.name,\n category: m.category,\n summary: m.summary,\n status: manifestStatus(m.id),\n }));\n return JSON.stringify({ integrations: summary });\n },\n {\n name: \"list_integrations\",\n description:\n \"List every integration Jarela knows how to set up, with a one-line summary and \" +\n \"current configuration status. Read-only. Use this when the user asks 'what can I connect?' \" +\n \"or before proposing enable_integration, so you know what's available and whether it's \" +\n \"already configured.\",\n schema: z.object({}),\n },\n);\n\nexport const getIntegrationSetupTool = tool(\n async ({ id }) => {\n const manifest = getManifest(id);\n if (!manifest) {\n return JSON.stringify({\n error: `unknown integration \"${id}\". Call list_integrations to see available ids.`,\n });\n }\n return JSON.stringify({\n id: manifest.id,\n name: manifest.name,\n summary: manifest.summary,\n category: manifest.category,\n status: manifestStatus(manifest.id),\n prerequisites: manifest.prerequisites,\n steps: manifest.steps,\n troubleshooting: manifest.troubleshooting,\n notes: [\n \"Walk the user through `prerequisites` first; some require browser actions outside Jarela.\",\n \"For each step that has a `proposes` field, call propose_config_change with that kind when ready.\",\n \"When a step has a `verify.tool`, call that tool after applying the step to confirm success.\",\n ],\n });\n },\n {\n name: \"get_integration_setup\",\n description:\n \"Return the full setup manifest for one integration — prerequisites, ordered steps, and \" +\n \"troubleshooting hints. Read-only. Use this before walking the user through a setup, or \" +\n \"when a tool fails and you need the integration-specific recovery hint.\",\n schema: z.object({\n id: z.string().describe(\"Integration id from list_integrations (e.g. 'gmail', 'atlassian')\"),\n }),\n },\n);\n\nregisterTools(\"Config\", [listIntegrationsTool, getIntegrationSetupTool]);\n","/**\n * Native Google Calendar tools — direct REST calls to\n * calendar.googleapis.com, sharing the Gmail OAuth client (one Google\n * account, one refresh token, one access-token cache; see\n * lib/integrations/gmail-oauth.ts).\n *\n * Scope-wise this surface is **events on existing calendars**:\n * - list / get / create / update / delete events\n * - list the user's calendars (read-only)\n * There is deliberately no calendar-list create/delete and no ACL\n * editing. To enable a wider surface, add the broader scope to\n * GMAIL_SCOPES and (force users to) reconnect.\n *\n * v1 design notes:\n * - calendarId defaults to \"primary\" everywhere so the agent can\n * create a quick event without first calling list_calendars.\n * - All datetimes are RFC3339 strings (e.g. \"2026-05-19T16:00:00-07:00\").\n * When the caller omits a timezone offset, Google falls back to the\n * calendar's default TZ. The tools surface a `time_zone` field that\n * forwards an IANA name in case the caller wants to be explicit.\n * - `calendar_create_event` can provision a Google Meet link via the\n * conferenceData createRequest dance — gated behind `add_meet_link`\n * so unused calls don't trip Google's quota.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n googleFetch,\n resolveGoogleAuth,\n type GoogleAuth,\n} from \"@/lib/integrations/gmail-oauth\";\n\nconst CALENDAR_BASE = \"https://www.googleapis.com/calendar/v3\";\nconst calendarFetch = (auth: GoogleAuth, path: string, init?: RequestInit) =>\n googleFetch(auth, \"Calendar\", CALENDAR_BASE, path, init);\n\n// ── Type shapes (minimal — only what we read back) ──────────────────────────\n\ninterface CalendarListEntry {\n id?: string;\n summary?: string;\n primary?: boolean;\n timeZone?: string;\n accessRole?: string;\n}\n\ninterface EventDateTime {\n dateTime?: string;\n date?: string;\n timeZone?: string;\n}\n\ninterface EventAttendee {\n email?: string;\n displayName?: string;\n responseStatus?: string;\n}\n\ninterface CalendarEvent {\n id?: string;\n status?: string;\n htmlLink?: string;\n hangoutLink?: string;\n summary?: string;\n description?: string;\n location?: string;\n start?: EventDateTime;\n end?: EventDateTime;\n attendees?: EventAttendee[];\n}\n\n// Slim down a full event to the fields the agent actually needs in a\n// thread response. Keeps tool outputs small enough not to blow context.\nfunction slimEvent(e: CalendarEvent): Record<string, unknown> {\n return {\n id: e.id,\n status: e.status,\n summary: e.summary ?? null,\n description: e.description ?? null,\n location: e.location ?? null,\n start: e.start?.dateTime ?? e.start?.date ?? null,\n end: e.end?.dateTime ?? e.end?.date ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.email,\n name: a.displayName ?? null,\n response: a.responseStatus ?? null,\n })),\n meet_link: e.hangoutLink ?? null,\n html_link: e.htmlLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const calendarListCalendarsTool = tool(\n async () => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await calendarFetch(auth, \"/users/me/calendarList\") as {\n items?: CalendarListEntry[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.items ?? []).map((c) => ({\n id: c.id,\n summary: c.summary ?? null,\n primary: c.primary === true,\n time_zone: c.timeZone ?? null,\n access_role: c.accessRole ?? null,\n })),\n });\n },\n {\n name: \"calendar_list_calendars\",\n description:\n \"List the user's Google calendars (primary + any they've subscribed to). \" +\n \"Returns id, summary, primary flag, time zone, access role per entry. The \" +\n \"`id` is what other calendar_* tools expect as `calendar_id`. Use this when \" +\n \"the user mentions a non-primary calendar by name (e.g. 'put it on my Work \" +\n \"calendar') — match against `summary` to find the right id.\",\n schema: z.object({}),\n },\n);\n\nexport const calendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, query, max_results }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const params = new URLSearchParams({\n singleEvents: \"true\",\n orderBy: \"startTime\",\n maxResults: String(Math.min(Math.max(max_results ?? 25, 1), 100)),\n });\n // Default window: now → +7 days. Keeps \"what's on my schedule\" cheap.\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n params.set(\"timeMin\", time_min ?? now.toISOString());\n params.set(\"timeMax\", time_max ?? inAWeek.toISOString());\n if (query) params.set(\"q\", query);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events?${params.toString()}`,\n ) as { items?: CalendarEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.items ?? []).map(slimEvent),\n });\n },\n {\n name: \"calendar_list_events\",\n description:\n \"List events on a calendar within a time window. Defaults: primary calendar, \" +\n \"now → +7 days, ordered by start, recurring events expanded into single \" +\n \"instances. **Use this before creating an event** to avoid double-booking, \" +\n \"and to look up existing event ids before updating/deleting. \" +\n \"Datetimes are RFC3339 (e.g. '2026-05-19T16:00:00-07:00').\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n query: z.string().optional().describe(\"Free-text search across event fields\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const calendarGetEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(auth, `/calendars/${cal}/events/${eid}`) as\n CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_get_event\",\n description:\n \"Fetch one Google Calendar event by id. Returns the same slim shape as \" +\n \"calendar_list_events but for a single event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id (from calendar_list_events results)\"),\n }),\n },\n);\n\nexport const calendarCreateEventTool = tool(\n async ({\n calendar_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone, add_meet_link,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n\n interface EventBody {\n summary: string;\n description?: string;\n location?: string;\n start: EventDateTime;\n end: EventDateTime;\n attendees?: { email: string }[];\n conferenceData?: {\n createRequest: { requestId: string; conferenceSolutionKey: { type: string } };\n };\n }\n const body: EventBody = {\n summary,\n start: { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n end: { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n };\n if (description) body.description = description;\n if (location) body.location = location;\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((email) => ({ email }));\n }\n if (add_meet_link) {\n body.conferenceData = {\n createRequest: {\n // requestId must be unique per createRequest; Google echoes it back.\n requestId: `jarela-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n }\n\n // conferenceDataVersion=1 is required for Google to honor the\n // createRequest and provision a Meet URL. Harmless to set without it.\n const params = add_meet_link ? \"?conferenceDataVersion=1\" : \"\";\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events${params}`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_create_event\",\n description:\n \"Create a Google Calendar event on a calendar (default: 'primary'). \" +\n \"Datetimes are RFC3339 strings — include a timezone offset (e.g. \" +\n \"'2026-05-19T16:00:00-07:00') or set `time_zone` to an IANA name (e.g. \" +\n \"'America/Los_Angeles') so the user's calendar interprets the time \" +\n \"correctly. Attendees are emailed an invite automatically. Set \" +\n \"`add_meet_link: true` to provision a Google Meet URL on the event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n summary: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (markdown not rendered)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA timezone, e.g. 'America/Los_Angeles'\"),\n add_meet_link: z.boolean().optional().describe(\"Provision a Google Meet URL on this event\"),\n }),\n },\n);\n\nexport const calendarUpdateEventTool = tool(\n async ({\n calendar_id, event_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n\n const patch: Record<string, unknown> = {};\n if (summary !== undefined) patch.summary = summary;\n if (description !== undefined) patch.description = description;\n if (location !== undefined) patch.location = location;\n if (start_iso !== undefined) {\n patch.start = { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (end_iso !== undefined) {\n patch.end = { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (attendees !== undefined) {\n patch.attendees = attendees.map((email) => ({ email }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"PATCH\", body: JSON.stringify(patch) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_update_event\",\n description:\n \"Patch a Google Calendar event. Only the fields you supply are changed; \" +\n \"omit fields to leave them alone. Use this to reschedule (`start_iso`/`end_iso`), \" +\n \"rename (`summary`), or adjust the invitee list (`attendees` — note this \" +\n \"**replaces** the full list, so include everyone who should remain).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id\"),\n summary: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA timezone applied to start/end\"),\n }),\n },\n);\n\nexport const calendarDeleteEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"calendar_delete_event\",\n description:\n \"Delete a Google Calendar event by id. Attendees are notified by default. \" +\n \"Returns `{ ok: true, id }` on success. Use `calendar_list_events` to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n calendarListCalendarsTool, calendarListEventsTool, calendarGetEventTool,\n calendarCreateEventTool, calendarUpdateEventTool, calendarDeleteEventTool,\n]);\n","/**\n * Outlook Calendar tools via Microsoft Graph. Mirrors lib/tools/calendar.ts\n * (the Google Calendar set) one-for-one so the agent's mental model\n * carries over between providers.\n *\n * Graph differences vs Google Calendar worth knowing:\n * - Each event's start/end is { dateTime, timeZone } where timeZone is\n * a Windows-time-zone string by default (\"Pacific Standard Time\"),\n * not IANA. We pass an explicit `Prefer: outlook.timezone=\"UTC\"`\n * header so reads come back in UTC and the agent doesn't have to\n * navigate two TZ namespaces.\n * - Listing events in a window uses /calendarView (auto-expands\n * recurring series), parallel to Google's `singleEvents=true`.\n * - Online meetings use `isOnlineMeeting:true` +\n * `onlineMeetingProvider:\"teamsForBusiness\"`. Provisioning a Teams\n * link is gated behind `add_teams_link` to keep create_event cheap\n * when the agent just wants a plain event.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n graphFetch,\n resolveMicrosoftAuth,\n} from \"@/lib/integrations/microsoft-oauth\";\n\n// ── Graph type shapes (minimal subset) ──────────────────────────────────────\n\ninterface GraphCalendar {\n id?: string;\n name?: string;\n isDefaultCalendar?: boolean;\n canEdit?: boolean;\n owner?: { name?: string; address?: string };\n}\n\ninterface GraphDateTimeTimeZone {\n dateTime?: string;\n timeZone?: string;\n}\n\ninterface GraphAttendee {\n emailAddress?: { name?: string; address?: string };\n status?: { response?: string; time?: string };\n type?: string;\n}\n\ninterface GraphEvent {\n id?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n start?: GraphDateTimeTimeZone;\n end?: GraphDateTimeTimeZone;\n location?: { displayName?: string };\n attendees?: GraphAttendee[];\n isAllDay?: boolean;\n isCancelled?: boolean;\n showAs?: string;\n webLink?: string;\n onlineMeeting?: { joinUrl?: string };\n onlineMeetingProvider?: string;\n}\n\nfunction slimEvent(e: GraphEvent): Record<string, unknown> {\n return {\n id: e.id,\n subject: e.subject ?? null,\n description: e.bodyPreview ?? null,\n location: e.location?.displayName ?? null,\n start: e.start?.dateTime ?? null,\n end: e.end?.dateTime ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.emailAddress?.address ?? null,\n name: a.emailAddress?.name ?? null,\n response: a.status?.response ?? null,\n })),\n is_all_day: e.isAllDay === true,\n is_cancelled: e.isCancelled === true,\n show_as: e.showAs ?? null,\n teams_link: e.onlineMeeting?.joinUrl ?? null,\n web_link: e.webLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const outlookCalendarListCalendarsTool = tool(\n async () => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await graphFetch(auth, \"/me/calendars\") as {\n value?: GraphCalendar[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.value ?? []).map((c) => ({\n id: c.id,\n name: c.name ?? null,\n is_default: c.isDefaultCalendar === true,\n can_edit: c.canEdit === true,\n owner: c.owner?.address ?? null,\n })),\n });\n },\n {\n name: \"outlook_calendar_list_calendars\",\n description:\n \"List the user's Outlook calendars (primary + shared). Returns id, name, \" +\n \"is_default flag, edit permission, owner. The `id` is what other \" +\n \"outlook_calendar_* tools expect as `calendar_id`. Omit `calendar_id` \" +\n \"in those tools to use the user's default calendar.\",\n schema: z.object({}),\n },\n);\n\nexport const outlookCalendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, max_results }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n const startISO = time_min ?? now.toISOString();\n const endISO = time_max ?? inAWeek.toISOString();\n const top = Math.min(Math.max(max_results ?? 25, 1), 100);\n // /calendarView expands recurring series into individual instances —\n // the closest parallel to Google's singleEvents=true.\n const base = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/calendarView`\n : \"/me/calendarView\";\n const params = new URLSearchParams({\n startDateTime: startISO,\n endDateTime: endISO,\n $top: String(top),\n $orderby: \"start/dateTime\",\n });\n const data = await graphFetch(auth, `${base}?${params.toString()}`, {\n // Force UTC in responses so the agent doesn't juggle Windows-TZ names.\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as { value?: GraphEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.value ?? []).map(slimEvent),\n });\n },\n {\n name: \"outlook_calendar_list_events\",\n description:\n \"List Outlook calendar events within a time window. Defaults: default \" +\n \"calendar, now → +7 days, ordered by start, recurring series expanded. \" +\n \"**Use this before creating an event** to avoid double-booking, and to \" +\n \"look up event ids before updating/deleting. All datetimes returned in \" +\n \"UTC (RFC3339 'Z'-suffixed).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const outlookCalendarGetEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const e = await graphFetch(auth, `/me/events/${encodeURIComponent(event_id)}`, {\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (e.error) return JSON.stringify({ error: e.error });\n return JSON.stringify(slimEvent(e));\n },\n {\n name: \"outlook_calendar_get_event\",\n description:\n \"Fetch one Outlook calendar event by id. Returns the same slim shape as \" +\n \"outlook_calendar_list_events but for a single event.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id (from outlook_calendar_list_events)\"),\n }),\n },\n);\n\nexport const outlookCalendarCreateEventTool = tool(\n async ({\n calendar_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone, add_teams_link,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n interface EventBody {\n subject: string;\n body?: { contentType: \"text\"; content: string };\n start: GraphDateTimeTimeZone;\n end: GraphDateTimeTimeZone;\n location?: { displayName: string };\n attendees?: Array<{ emailAddress: { address: string }; type: \"required\" }>;\n isOnlineMeeting?: boolean;\n onlineMeetingProvider?: string;\n }\n // Graph uses Windows TZ names by default but also accepts IANA names\n // when the body specifies them per-field. Default to UTC if the\n // caller omits time_zone (matches the list endpoint's behavior).\n const tz = time_zone ?? \"UTC\";\n const body: EventBody = {\n subject,\n start: { dateTime: start_iso, timeZone: tz },\n end: { dateTime: end_iso, timeZone: tz },\n };\n if (description) body.body = { contentType: \"text\", content: description };\n if (location) body.location = { displayName: location };\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (add_teams_link) {\n body.isOnlineMeeting = true;\n body.onlineMeetingProvider = \"teamsForBusiness\";\n }\n\n const path = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/events`\n : \"/me/events\";\n const r = await graphFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_create_event\",\n description:\n \"Create an Outlook calendar event. Datetimes are RFC3339 strings; pair \" +\n \"with `time_zone` (IANA like 'America/Los_Angeles' or Windows TZ like \" +\n \"'Pacific Standard Time') so Outlook interprets them correctly. Defaults \" +\n \"to UTC if omitted. Attendees are automatically sent invites. Set \" +\n \"`add_teams_link: true` to provision a Teams meeting URL (requires a \" +\n \"work/school M365 account; personal Microsoft accounts cannot create \" +\n \"Teams meetings via Graph).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n subject: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (plain text)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA or Windows timezone (default 'UTC')\"),\n add_teams_link: z.boolean().optional().describe(\"Provision a Teams meeting URL on this event\"),\n }),\n },\n);\n\nexport const outlookCalendarUpdateEventTool = tool(\n async ({\n event_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const tz = time_zone ?? \"UTC\";\n const patch: Record<string, unknown> = {};\n if (subject !== undefined) patch.subject = subject;\n if (description !== undefined) patch.body = { contentType: \"text\", content: description };\n if (location !== undefined) patch.location = { displayName: location };\n if (start_iso !== undefined) patch.start = { dateTime: start_iso, timeZone: tz };\n if (end_iso !== undefined) patch.end = { dateTime: end_iso, timeZone: tz };\n if (attendees !== undefined) {\n patch.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(patch),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n },\n ) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_update_event\",\n description:\n \"Patch an Outlook calendar event. Only supplied fields are changed; omit \" +\n \"fields to leave them alone. Note `attendees` REPLACES the full invitee \" +\n \"list, so include everyone who should remain.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id\"),\n subject: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body (plain text)\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA or Windows TZ applied to start/end (default 'UTC')\"),\n }),\n },\n);\n\nexport const outlookCalendarDeleteEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"outlook_calendar_delete_event\",\n description:\n \"Delete an Outlook calendar event by id. Attendees are notified. Returns \" +\n \"`{ ok: true, id }` on success. Use outlook_calendar_list_events to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n outlookCalendarListCalendarsTool, outlookCalendarListEventsTool,\n outlookCalendarGetEventTool, outlookCalendarCreateEventTool,\n outlookCalendarUpdateEventTool, outlookCalendarDeleteEventTool,\n]);\n","// Barrel of built-in tool modules. Each side-effect import triggers the\n// module's `registerTools(...)` call (see ./registry.ts). Adding a new\n// built-in tool: add the file under lib/tools/ and append a line here.\n//\n// Order matters only for deterministic logging / UI ordering — registry\n// preserves insertion order.\n\nimport \"./memory\";\nimport \"./documents\";\nimport \"./exec\";\nimport \"./files\";\nimport \"./search\";\nimport \"./fetch\";\nimport \"./location\";\nimport \"./generate_image\";\nimport \"./generate_voice\";\nimport \"./schedule\";\nimport \"./watcher\";\nimport \"./propose\";\nimport \"./integrations\";\nimport \"./atlassian\";\nimport \"./jira-align\";\nimport \"./github\";\nimport \"./gmail\";\nimport \"./calendar\";\nimport \"./outlook\";\nimport \"./outlook-calendar\";\n","// Public tool surface for the agent runtime.\n//\n// Built-in tools register themselves at module load (see ./registry.ts and\n// ./builtins.ts). External tools live under JARELA_TOOLS_DIR and are\n// loaded per-call (hot-reload). MCP tools come from lib/mcp/client.ts.\n//\n// To add a new built-in tool:\n// 1. Copy lib/tools/template.ts to lib/tools/<name>.ts and implement it.\n// 2. Call `registerTools(\"<Category>\", [yourTool, ...])` at the bottom.\n// 3. Add `import \"./<name>\";` to lib/tools/builtins.ts.\n//\n// That's it — no central array to update, no parallel category map.\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\n\n// Side-effect import: triggers registerTools() in every built-in module.\nimport \"./builtins\";\n\nimport {\n registeredTools,\n registeredNames,\n registeredCategory,\n registeredGroup,\n type ToolCategory,\n type ToolGroup,\n} from \"./registry\";\nimport { getMcpTools } from \"@/lib/mcp/client\";\nimport {\n loadExternalTools,\n getToolsDir,\n type ExtensionLoadError,\n} from \"./external\";\nimport type { OpenAITool, ToolContext, ToolParamSchema } from \"./types\";\nimport type { ToolPolicy } from \"@/lib/agents/base\";\nimport { disabledCategories } from \"@/lib/stores/builtin-tools\";\n\nexport * from \"./types\";\nexport { getToolsDir, type ExtensionLoadError } from \"./external\";\nexport { registerTools, type ToolCategory, type ToolGroup } from \"./registry\";\n\nconst ALL_BUILTINS: StructuredToolInterface[] = registeredTools();\nexport const BUILTIN_TOOL_NAMES: ReadonlySet<string> = registeredNames();\n\n// Per-call recompute so files dropped in $JARELA_TOOLS_DIR are picked up\n// without restart. loadExternalTools cache-busts require() per file.\nfunction loadExternal() {\n return loadExternalTools(BUILTIN_TOOL_NAMES);\n}\n\nexport function getToolCategory(name: string, source: \"builtin\" | \"mcp\"): ToolCategory {\n const builtin = registeredCategory(name);\n if (builtin) return builtin;\n const ext = loadExternal().categories.get(name);\n if (ext) return ext;\n return source === \"mcp\" ? \"MCP\" : \"Config\";\n}\n\nexport function getToolGroup(name: string, source: \"builtin\" | \"mcp\"): ToolGroup {\n const cat = getToolCategory(name, source);\n if (cat === \"MCP\") return null;\n return registeredGroup(name) ?? null;\n}\n\nfunction applyPolicy(\n tools: StructuredToolInterface[],\n policy?: ToolPolicy,\n): StructuredToolInterface[] {\n const allowSet = policy?.allow?.length ? new Set(policy.allow) : null;\n const denySet = policy?.deny?.length ? new Set(policy.deny) : null;\n return tools.filter((t) => {\n if (allowSet && !allowSet.has(t.name)) return false;\n if (denySet && denySet.has(t.name)) return false;\n return true;\n });\n}\n\n// Filter built-in tools whose category is disabled in the toggle store.\n// External + MCP tools are untouched (they have their own enable surfaces).\nfunction applyCategoryToggles(tools: StructuredToolInterface[]): StructuredToolInterface[] {\n const disabled = disabledCategories();\n if (disabled.size === 0) return tools;\n return tools.filter((t) => {\n const cat = registeredCategory(t.name);\n if (!cat) return true; // not a built-in (or unregistered) → leave it\n return !disabled.has(cat);\n });\n}\n\n// Synchronous: built-in + external tools (no MCP). Used by GET /api/v1/tools\n// and any code path that can't await.\nexport function getAllTools(policy?: ToolPolicy): StructuredToolInterface[] {\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools],\n policy,\n );\n}\n\n// Async: built-in + external + MCP tools.\n// Use this anywhere the agent might invoke tools (createReactAgent input).\n// External tools are loaded per-call (hot-reload). MCP tools are cached by\n// lib/mcp/client.ts and only re-resolved when the mcp_servers table changes.\nexport async function getAllToolsAsync(policy?: ToolPolicy): Promise<StructuredToolInterface[]> {\n let mcpTools: StructuredToolInterface[] = [];\n try {\n mcpTools = await getMcpTools();\n } catch (err) {\n console.error(\"[tools] MCP load failed, continuing with built-ins only:\", err);\n }\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools, ...mcpTools],\n policy,\n );\n}\n\nexport function toOpenAITools(tools: StructuredToolInterface[]): OpenAITool[] {\n return tools.map((t) => {\n const oai = convertToOpenAITool(t);\n return {\n type: \"function\",\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n };\n });\n}\n\nexport async function executeTool(\n name: string,\n args: Record<string, unknown>,\n context: ToolContext = {},\n): Promise<unknown> {\n let t = ALL_BUILTINS.find((x) => x.name === name);\n if (t) {\n const cat = registeredCategory(name);\n if (cat && disabledCategories().has(cat)) {\n throw new Error(`Tool \"${name}\" is disabled (category ${cat} is turned off)`);\n }\n }\n if (!t) {\n t = loadExternal().tools.find((x) => x.name === name);\n }\n if (!t) throw new Error(`Unknown tool: ${name}`);\n\n const config: RunnableConfig = context.thread_id\n ? { configurable: { thread_id: context.thread_id } }\n : {};\n\n const result = await t.invoke(args, config);\n\n // Tools return JSON strings per LangChain convention; parse back for downstream use.\n if (typeof result === \"string\") {\n try {\n return JSON.parse(result);\n } catch {\n return result;\n }\n }\n return result;\n}\n\n// One-shot startup loader. Call from instrumentation.ts so external tools\n// load + log their status at boot rather than lazily on first agent turn.\nlet _initialized = false;\nexport interface InitToolsSummary {\n builtinCount: number;\n externalCount: number;\n errors: ExtensionLoadError[];\n toolsDir: string;\n}\n\nexport function initTools(): InitToolsSummary {\n const toolsDir = getToolsDir();\n const result = loadExternal();\n const summary: InitToolsSummary = {\n builtinCount: ALL_BUILTINS.length,\n externalCount: result.tools.length,\n errors: result.errors,\n toolsDir,\n };\n\n if (!_initialized) {\n console.info(\n `[tools] ${summary.builtinCount} built-in tool(s) registered; ` +\n `${summary.externalCount} external tool(s) loaded from ${toolsDir}`,\n );\n for (const err of summary.errors) {\n console.error(`[tools] external ${err.file}: ${err.error}`);\n }\n _initialized = true;\n }\n return summary;\n}\n","import type { PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\nexport interface ToolStatsRow {\n tool_name: string;\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n last_called_at: string | null;\n updated_at: string;\n}\n\nexport interface ToolUsefulnessStats {\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n success_rate: number;\n usefulness_rate: number;\n score: number;\n never_used: boolean;\n last_called_at: string | null;\n}\n\ninterface ToolUsageDelta {\n name: string;\n calls: number;\n successes: number;\n errors: number;\n used: number;\n}\n\nconst UPSERT_SQL = `\n INSERT INTO tool_stats\n (tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at)\n VALUES\n (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(tool_name) DO UPDATE SET\n call_count = tool_stats.call_count + excluded.call_count,\n success_count = tool_stats.success_count + excluded.success_count,\n error_count = tool_stats.error_count + excluded.error_count,\n used_count = tool_stats.used_count + excluded.used_count,\n last_called_at = COALESCE(excluded.last_called_at, tool_stats.last_called_at),\n updated_at = excluded.updated_at\n`;\n\nexport function recordToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): void {\n const deltas = summarizeToolUsage(toolEvents, assistantContent);\n if (deltas.length === 0) return;\n\n const db = getDb();\n const stamp = now();\n const stmt = db.prepare(UPSERT_SQL);\n db.exec(\"BEGIN\");\n try {\n for (const row of deltas) {\n stmt.run(\n row.name,\n row.calls,\n row.successes,\n row.errors,\n row.used,\n row.calls > 0 ? stamp : null,\n stamp,\n );\n }\n db.exec(\"COMMIT\");\n } catch (err) {\n try { db.exec(\"ROLLBACK\"); } catch { /* ignore rollback failure */ }\n throw err;\n }\n}\n\nexport function listToolStats(): ToolStatsRow[] {\n return getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats`,\n )\n .all() as unknown as ToolStatsRow[];\n}\n\nexport function getToolStatsMap(names?: readonly string[]): Map<string, ToolUsefulnessStats> {\n const rows = names && names.length > 0\n ? getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats\n WHERE tool_name IN (${names.map(() => \"?\").join(\",\")})`,\n )\n .all(...names) as unknown as ToolStatsRow[]\n : listToolStats();\n\n const out = new Map<string, ToolUsefulnessStats>();\n for (const row of rows) out.set(row.tool_name, toStats(row));\n return out;\n}\n\nexport function defaultToolStats(): ToolUsefulnessStats {\n return {\n call_count: 0,\n success_count: 0,\n error_count: 0,\n used_count: 0,\n success_rate: 1,\n usefulness_rate: 1,\n score: 1,\n never_used: true,\n last_called_at: null,\n };\n}\n\nexport function toStats(row: ToolStatsRow): ToolUsefulnessStats {\n const calls = Math.max(0, row.call_count);\n if (calls === 0) return defaultToolStats();\n\n const successRate = clamp01(row.success_count / calls);\n const usefulnessRate = clamp01(row.used_count / calls);\n const score = clamp01((successRate * 0.65) + (usefulnessRate * 0.35));\n\n return {\n call_count: calls,\n success_count: row.success_count,\n error_count: row.error_count,\n used_count: row.used_count,\n success_rate: successRate,\n usefulness_rate: usefulnessRate,\n score,\n never_used: false,\n last_called_at: row.last_called_at,\n };\n}\n\nexport function summarizeToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): ToolUsageDelta[] {\n const byId = new Map<string, { name: string; successful: boolean; used: boolean }>();\n const assistantTerms = normalizeText(assistantContent);\n\n for (const ev of toolEvents) {\n if (!ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const existing = byId.get(key) ?? { name: ev.name, successful: false, used: false };\n\n if (ev.phase === \"call\") {\n existing.name = ev.name;\n } else if (ev.phase === \"result\") {\n const successful = !isErrorPayload(ev.payload);\n existing.successful = successful;\n existing.used = successful && payloadLooksUsed(ev.payload, assistantTerms);\n }\n\n byId.set(key, existing);\n }\n\n const totals = new Map<string, ToolUsageDelta>();\n for (const ev of toolEvents) {\n if (ev.phase !== \"call\" || !ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const outcome = byId.get(key);\n const next = totals.get(ev.name) ?? {\n name: ev.name,\n calls: 0,\n successes: 0,\n errors: 0,\n used: 0,\n };\n next.calls += 1;\n if (outcome?.successful) next.successes += 1;\n else next.errors += 1;\n if (outcome?.used) next.used += 1;\n totals.set(ev.name, next);\n }\n\n return [...totals.values()];\n}\n\nfunction payloadLooksUsed(payload: unknown, assistantTerms: Set<string>): boolean {\n if (assistantTerms.size === 0) return false;\n const candidates = extractPayloadTerms(payload);\n if (candidates.length === 0) return false;\n\n let matched = 0;\n for (const term of candidates) {\n if (assistantTerms.has(term)) matched += 1;\n if (matched >= 2) return true;\n }\n return false;\n}\n\nfunction extractPayloadTerms(payload: unknown): string[] {\n const raw = stringifyPayload(payload);\n if (!raw) return [];\n const unique = new Set<string>();\n for (const token of raw.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n if (/^\\d+$/.test(token) && token.length < 6) continue;\n unique.add(token);\n if (unique.size >= 24) break;\n }\n return [...unique];\n}\n\nfunction stringifyPayload(payload: unknown): string {\n if (typeof payload === \"string\") return payload;\n try {\n return JSON.stringify(payload);\n } catch {\n return \"\";\n }\n}\n\nfunction normalizeText(text: string): Set<string> {\n const out = new Set<string>();\n for (const token of text.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n out.add(token);\n }\n return out;\n}\n\nfunction isErrorPayload(payload: unknown): boolean {\n if (typeof payload === \"string\") return /\\berror\\b|\\bfailed\\b|\\bexception\\b/i.test(payload);\n if (!payload || typeof payload !== \"object\") return false;\n if (\"error\" in payload || \"errors\" in payload) return true;\n const status = \"status\" in payload ? (payload as { status?: unknown }).status : undefined;\n if (typeof status === \"string\" && /error|failed/i.test(status)) return true;\n return false;\n}\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}","// Local file store for binary artifacts produced by tools (generated images,\n// downloads, etc.). Files live under ~/.jarela/files/ and are served by\n// GET /api/v1/files/[name]. The tool returns a relative URL the chat\n// renderer can embed as <img src=\"/api/v1/files/...\">.\n\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\n\nexport const FILES_DIR = join(getDataDir(), \"files\");\n\nmkdirSync(FILES_DIR, { recursive: true });\n\n// Name must be a single path segment with no separators or \"..\". Callers\n// generate names from randomUUID() so this is mostly defense-in-depth.\nconst SAFE_NAME = /^[A-Za-z0-9._-]+$/;\n\nexport function isSafeFileName(name: string): boolean {\n return SAFE_NAME.test(name) && !name.includes(\"..\");\n}\n\nexport function fileAbsPath(name: string): string | null {\n if (!isSafeFileName(name)) return null;\n return join(FILES_DIR, name);\n}\n\nexport function writeBinaryFile(name: string, data: Buffer): string {\n if (!isSafeFileName(name)) throw new Error(`unsafe file name: ${name}`);\n const p = join(FILES_DIR, name);\n writeFileSync(p, data);\n return p;\n}\n","// Built-in tool category toggles.\n//\n// A category is \"enabled\" unless an explicit row in `builtin_tool_categories`\n// says otherwise. Default-enabled semantics mean upgrading installs keep\n// every category working with zero migration work.\n//\n// Disabled categories are filtered at three layers:\n// - GET /api/v1/tools (so the agent editor never offers them as permissions)\n// - getAllTools / getAllToolsAsync (so the agent runtime can't see them)\n// - executeTool (defense in depth, blocks stale agent configs)\n\nimport { getDb } from \"@/lib/db\";\nimport type { BuiltinCategory } from \"@/lib/tools/registry\";\n\ninterface Row {\n category: string;\n enabled: number;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function isCategoryEnabled(category: BuiltinCategory): boolean {\n const row = getDb()\n .prepare(\"SELECT enabled FROM builtin_tool_categories WHERE category=?\")\n .get(category) as { enabled: number } | undefined;\n return row ? row.enabled === 1 : true;\n}\n\nexport function disabledCategories(): Set<BuiltinCategory> {\n const rows = getDb()\n .prepare(\"SELECT category FROM builtin_tool_categories WHERE enabled=0\")\n .all() as unknown as Array<{ category: string }>;\n return new Set(rows.map((r) => r.category as BuiltinCategory));\n}\n\nexport function listCategoryStates(): Array<{ category: string; enabled: boolean; updated_at: string | null }> {\n const rows = getDb()\n .prepare(\"SELECT category, enabled, updated_at FROM builtin_tool_categories\")\n .all() as unknown as Row[];\n return rows.map((r) => ({\n category: r.category,\n enabled: r.enabled === 1,\n updated_at: r.updated_at,\n }));\n}\n\nexport function setCategoryEnabled(category: BuiltinCategory, enabled: boolean): void {\n getDb()\n .prepare(\n `INSERT INTO builtin_tool_categories (category, enabled, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(category) DO UPDATE SET enabled=excluded.enabled, updated_at=excluded.updated_at`,\n )\n .run(category, enabled ? 1 : 0, now());\n}\n","import { getIntegrationRaw } from \"@/lib/stores/integrations\";\n\nexport function timeoutSignal(ms: number): AbortSignal {\n const c = new AbortController();\n setTimeout(() => c.abort(new Error(`timeout after ${ms}ms`)), ms).unref?.();\n return c.signal;\n}\n\nexport function resolveGoogleApiKey(): string | null {\n const raw = getIntegrationRaw(\"google\");\n const fromStore = raw?.api_key?.trim();\n if (fromStore) return fromStore;\n return (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || \"\").trim() || null;\n}\n","import { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\n// Persona presets (see ADR — to be written). Drives the Credentials\n// panel's category filter so the agent surface stays calm.\n//\n// home → llm + mail + calendar + chat\n// work → everything except chat-only (everyone uses work mail/cal/jira)\n// dev → everything (including infrastructure)\n// custom → no filter, show everything\n//\n// NULL in the DB also means \"no filter\".\nexport type UserPreset = \"home\" | \"work\" | \"dev\" | \"custom\";\n\nexport function isUserPreset(v: unknown): v is UserPreset {\n return v === \"home\" || v === \"work\" || v === \"dev\" || v === \"custom\";\n}\n\nexport interface UserProfileRow {\n id: string;\n name: string;\n icon: string | null;\n about: string;\n created_at: string;\n updated_at: string;\n // ── Geolocation (opt-in) ─────────────────────────────────────────────\n // Populated by the client (navigator.geolocation) only when\n // location_consent === 1. All five fields are null when sharing is off.\n location_lat: number | null;\n location_lng: number | null;\n location_accuracy_m: number | null;\n location_label: string | null;\n location_updated_at: string | null;\n location_consent: number; // 0 | 1\n // ── Persona ──────────────────────────────────────────────────────────\n preset: UserPreset | null;\n}\n\nexport function getUserProfile(): UserProfileRow | null {\n return (\n (getDb()\n .prepare(\"SELECT * FROM user_profile WHERE id='me'\")\n .get() as unknown as UserProfileRow) ?? null\n );\n}\n\nexport function upsertUserProfile(\n name: string,\n icon: string | null,\n about: string,\n): UserProfileRow {\n const t = now();\n const db = getDb();\n const existing = getUserProfile();\n const created_at = existing?.created_at ?? t;\n // Preserve location columns on profile edit — we only update them via the\n // dedicated location endpoints.\n db.prepare(\n `INSERT INTO user_profile (id, name, icon, about, created_at, updated_at)\n VALUES ('me', ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n name=excluded.name, icon=excluded.icon, about=excluded.about,\n updated_at=excluded.updated_at`,\n ).run(name, icon ?? null, about, created_at, t);\n return getUserProfile()!;\n}\n\nexport function setLocationConsent(consent: boolean): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists.\n const existing = getUserProfile();\n if (!existing) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET location_consent=?, updated_at=?\n ${consent ? \"\" : \", location_lat=NULL, location_lng=NULL, location_accuracy_m=NULL, location_label=NULL, location_updated_at=NULL\"}\n WHERE id='me'`,\n ).run(consent ? 1 : 0, t);\n return getUserProfile()!;\n}\n\nexport function updateUserLocation(input: {\n lat: number;\n lng: number;\n accuracy_m?: number | null;\n label?: string | null;\n}): UserProfileRow {\n const existing = getUserProfile();\n if (!existing || existing.location_consent !== 1) {\n throw new Error(\"location sharing is not enabled\");\n }\n const t = now();\n getDb()\n .prepare(\n `UPDATE user_profile SET\n location_lat=?, location_lng=?, location_accuracy_m=?, location_label=?,\n location_updated_at=?, updated_at=?\n WHERE id='me'`,\n )\n .run(\n input.lat,\n input.lng,\n input.accuracy_m ?? null,\n input.label ?? null,\n t,\n t,\n );\n return getUserProfile()!;\n}\n\nexport function setUserPreset(preset: UserPreset | null): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists so the UPDATE has something to touch.\n if (!getUserProfile()) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET preset=?, updated_at=? WHERE id='me'`,\n ).run(preset, t);\n return getUserProfile()!;\n}\n","// Central runtime configuration, resolved from environment variables.\n//\n// All operational knobs (port, host, data dir, timeouts, agent limits) flow\n// through this module so there is exactly one place documenting which env\n// vars Jarela respects and what the defaults are. Code MUST NOT read these\n// `process.env` keys directly — import `config` instead.\n//\n// Resolution order for every entry: explicit JARELA_* var → legacy/standard\n// var (where one exists, e.g. PORT/HOSTNAME for Next.js compatibility) →\n// hard-coded default.\n//\n// Values are resolved lazily on first read and cached. Tests that mutate\n// `process.env` must call `resetConfigCache()` between cases.\n\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { getAppName, getAppDescription, getAppIssueUrl } from \"./app-config\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface JarelaConfig {\n /** TCP port the Next.js server binds to. */\n readonly port: number;\n /** Hostname/interface the server binds to (loopback by default). */\n readonly hostname: string;\n /** Absolute path to the SQLite + files data directory. */\n readonly dataDir: string;\n /** Absolute path to the external-tools directory (CJS/TS plugins). */\n readonly toolsDir: string;\n /** Max LangGraph node visits per agent run before erroring out. */\n readonly recursionLimit: number;\n /** Per-request timeout for Gemini voice (TTS/STT) calls, ms. */\n readonly voiceTimeoutMs: number;\n /** Per-request timeout for Gemini image-generation calls, ms. */\n readonly imageTimeoutMs: number;\n /** User-visible app name. Forks override via NEXT_PUBLIC_APP_NAME. */\n readonly appName: string;\n /** Meta description for the HTML <head>. NEXT_PUBLIC_APP_DESCRIPTION. */\n readonly appDescription: string;\n /** \"Report a bug\" target — GitHub issues URL. NEXT_PUBLIC_APP_ISSUE_URL. */\n readonly issueUrl: string;\n}\n\nconst DEFAULTS = {\n port: 4312,\n hostname: \"127.0.0.1\",\n recursionLimit: 200,\n voiceTimeoutMs: 60_000,\n imageTimeoutMs: 60_000,\n} as const;\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\nfunction parsePort(value: string | undefined, fallback: number): number {\n const n = parsePositiveInt(value, fallback);\n return n >= 1 && n <= 65_535 ? n : fallback;\n}\n\nlet cached: JarelaConfig | null = null;\n\nfunction expandHome(p: string): string {\n return p.startsWith(\"~\") ? p.replace(/^~/, homedir()) : p;\n}\n\nexport function getConfig(): JarelaConfig {\n if (cached) return cached;\n const env = process.env;\n const dataDir = getDataDir();\n cached = {\n port: parsePort(env.JARELA_PORT ?? env.PORT, DEFAULTS.port),\n hostname: (env.JARELA_HOSTNAME ?? env.HOSTNAME ?? DEFAULTS.hostname).trim() || DEFAULTS.hostname,\n dataDir,\n toolsDir: env.JARELA_TOOLS_DIR ? expandHome(env.JARELA_TOOLS_DIR) : join(dataDir, \"tools\"),\n recursionLimit: parsePositiveInt(env.JARELA_RECURSION_LIMIT, DEFAULTS.recursionLimit),\n voiceTimeoutMs: parsePositiveInt(env.JARELA_VOICE_TIMEOUT_MS, DEFAULTS.voiceTimeoutMs),\n imageTimeoutMs: parsePositiveInt(env.JARELA_IMAGE_TIMEOUT_MS, DEFAULTS.imageTimeoutMs),\n appName: getAppName(),\n appDescription: getAppDescription(),\n issueUrl: getAppIssueUrl(),\n };\n return cached;\n}\n\n/** Test-only: drop the memoised config so the next read picks up env edits. */\nexport function resetConfigCache(): void {\n cached = null;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { getDb } from \"@/lib/db\";\nimport {\n resolveReaction,\n validateReactionScript,\n normaliseReactionScriptArgs,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\nexport type ScheduleKind = \"once\" | \"cron\";\n\nexport interface ScheduledTaskRow {\n id: string;\n agent_id: string;\n prompt: string;\n description: string | null;\n kind: ScheduleKind;\n schedule: string; // ISO timestamp for \"once\", cron expression for \"cron\"\n next_run_at: string; // ISO\n last_run_at: string | null;\n last_error: string | null;\n enabled: number; // 0 | 1\n // When 1 the scheduler wraps the prompt with a \"reply only if material\"\n // directive and a NO_REPLY sentinel; NO_REPLY/empty assistant turns are\n // dropped. Visibility is handled at the UI layer via the chat-panel\n // category-filter toolbar (firings are tagged `scheduled_task`).\n silent: number; // 0 | 1\n // ADR-0032 — discriminated reaction. 'agent_prompt' (default) runs the\n // agent with `prompt`; 'script' runs a registered reaction.* script\n // with no LLM round-trip. The other branch's columns are forced NULL\n // by the store layer (see resolveReaction in reaction-shared.ts).\n reaction_kind: ReactionKind;\n reaction_script: string | null;\n reaction_script_args: string | null; // JSON-encoded record\n created_at: string;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function computeNextRun(kind: ScheduleKind, schedule: string, after: Date = new Date()): Date {\n if (kind === \"once\") {\n const ts = new Date(schedule);\n if (Number.isNaN(ts.getTime())) throw new Error(`Invalid ISO timestamp: ${schedule}`);\n return ts;\n }\n const it = CronExpressionParser.parse(schedule, { currentDate: after });\n return it.next().toDate();\n}\n\nexport interface CreateScheduledTaskInput {\n agent_id: string;\n // Required for kind='agent_prompt'; ignored (stored as \"\") for kind='script'.\n prompt?: string;\n description?: string;\n kind: ScheduleKind;\n schedule: string;\n silent?: boolean;\n // ADR-0032 — discriminated reaction. Same shape as the watcher store.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createScheduledTask(input: CreateScheduledTaskInput): ScheduledTaskRow {\n const id = randomUUID();\n const t = now();\n const next = computeNextRun(input.kind, input.schedule).toISOString();\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction({\n reaction_kind: input.reaction_kind,\n // Scheduled tasks don't carry a reaction_prompt override — the firing\n // prompt is `input.prompt` itself when kind='agent_prompt'. Pass null\n // so resolveReaction normalises it consistently.\n reaction_prompt: null,\n reaction_script: input.reaction_script,\n reaction_script_args: input.reaction_script_args,\n });\n if (reaction.kind === \"agent_prompt\" && !input.prompt) {\n throw new Error(\"prompt is required when reaction_kind='agent_prompt'\");\n }\n // For kind='script' we still need a non-NULL value in the prompt column\n // (NOT NULL constraint stays). Empty string is the agreed sentinel; the\n // discriminator decides whether prompt is read.\n const prompt = reaction.kind === \"script\" ? (input.prompt ?? \"\") : input.prompt!;\n getDb()\n .prepare(\n `INSERT INTO scheduled_tasks\n (id, agent_id, prompt, description, kind, schedule, next_run_at, last_run_at, last_error, enabled, silent,\n reaction_kind, reaction_script, reaction_script_args, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, 1, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, prompt, input.description ?? null, input.kind, input.schedule, next, silent,\n reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n prompt,\n description: input.description ?? null,\n kind: input.kind,\n schedule: input.schedule,\n next_run_at: next,\n last_run_at: null,\n last_error: null,\n enabled: 1,\n silent,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listScheduledTasks(agentId?: string): ScheduledTaskRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM scheduled_tasks WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM scheduled_tasks ORDER BY next_run_at ASC\").all();\n return rows as unknown as ScheduledTaskRow[];\n}\n\nexport function getScheduledTask(id: string): ScheduledTaskRow | null {\n const row = getDb().prepare(\"SELECT * FROM scheduled_tasks WHERE id=?\").get(id);\n return (row as ScheduledTaskRow | undefined) ?? null;\n}\n\nexport function getDueTasks(asOf: Date = new Date()): ScheduledTaskRow[] {\n return getDb()\n .prepare(\"SELECT * FROM scheduled_tasks WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as ScheduledTaskRow[];\n}\n\nexport function deleteScheduledTask(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateScheduledTaskInput {\n prompt?: string;\n description?: string | null;\n kind?: ScheduleKind;\n schedule?: string;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0032 — same discriminated-union semantics as updateWatcher:\n // explicit reaction_kind does a full replace; absent kind allows\n // kind-preserving patch of the matching branch's fields.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\n// Patch an existing task. Only the supplied fields are touched; the rest\n// stay as-is. Changing `kind` or `schedule` recomputes `next_run_at`\n// against the new value so the scheduler picks the right next firing.\nexport function updateScheduledTask(id: string, patch: UpdateScheduledTaskInput): ScheduledTaskRow | null {\n const existing = getScheduledTask(id);\n if (!existing) return null;\n const nextKind = patch.kind ?? existing.kind;\n const nextSchedule = patch.schedule ?? existing.schedule;\n const t = now();\n // If the schedule (kind or expression) changed, validate + recompute. If\n // it didn't change we keep the existing next_run_at so a simple prompt\n // edit doesn't accidentally re-arm an already-overdue task.\n let nextRunAt = existing.next_run_at;\n if (patch.kind !== undefined || patch.schedule !== undefined) {\n nextRunAt = computeNextRun(nextKind, nextSchedule, new Date(t)).toISOString();\n }\n\n // Compute the reaction columns. Two cases mirroring updateWatcher:\n // 1. patch.reaction_kind is set → fully resolve as a new reaction.\n // 2. patch.reaction_kind is absent → keep existing kind, allow the\n // matching branch's field to be patched.\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: null,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n reaction = { kind: \"agent_prompt\", prompt: null, script: null, scriptArgs: null };\n }\n\n // Prompt column constraint: must be non-NULL. For kind='script' we keep\n // whatever was there (or \"\" if switching from script with empty existing).\n const nextPrompt = patch.prompt !== undefined\n ? patch.prompt\n : (reaction.kind === \"agent_prompt\" && existing.reaction_kind === \"script\"\n ? (existing.prompt || \"\")\n : existing.prompt);\n\n getDb()\n .prepare(\n `UPDATE scheduled_tasks SET\n prompt=?, description=?, kind=?, schedule=?, next_run_at=?, enabled=?, silent=?, last_error=?,\n reaction_kind=?, reaction_script=?, reaction_script_args=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n nextPrompt,\n patch.description === undefined ? existing.description : patch.description,\n nextKind,\n nextSchedule,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n // Clear the last error whenever the user touches the task — they've\n // presumably fixed whatever caused it.\n null,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getScheduledTask(id);\n}\n\nexport function markTaskRan(id: string, kind: ScheduleKind, schedule: string, error?: string): void {\n const t = now();\n if (kind === \"once\") {\n // One-shot tasks delete themselves after firing.\n getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return;\n }\n let nextRun: string;\n try {\n nextRun = computeNextRun(kind, schedule, new Date(t)).toISOString();\n } catch (e) {\n // Invalid cron — disable the task to avoid a tight error loop.\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET enabled=0, last_run_at=?, last_error=?, updated_at=? WHERE id=?\")\n .run(t, `Cron parse failed: ${e instanceof Error ? e.message : String(e)}`, t, id);\n return;\n }\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?\")\n .run(t, error ?? null, nextRun, t, id);\n}\n","import { BaseChatModel, type BaseChatModelCallOptions } from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n type BaseMessage,\n isAIMessage,\n isHumanMessage,\n isSystemMessage,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatGeneration, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport type { ModelProvider, ProviderParams } from \"@/lib/providers/types\";\nimport type { ContentPart, InvokeMessage, OpenAITool, ToolParamSchema } from \"@/lib/tools/types\";\n\ninterface Fields {\n provider: ModelProvider;\n modelId: string;\n params: ProviderParams;\n boundTools?: StructuredToolInterface[];\n}\n\nexport class JarelaChatModel extends BaseChatModel {\n lc_namespace = [\"jarela\", \"chat_models\"];\n lc_serializable = false;\n\n private _provider: ModelProvider;\n private _modelId: string;\n private _params: ProviderParams;\n private _boundTools: StructuredToolInterface[];\n\n constructor(fields: Fields) {\n super({});\n this._provider = fields.provider;\n this._modelId = fields.modelId;\n this._params = fields.params;\n this._boundTools = fields.boundTools ?? [];\n }\n\n _llmType(): string {\n return `jarela_${this._provider?.name ?? \"chat\"}`;\n }\n\n // createReactAgent calls bindTools() to attach the tool list before streaming.\n bindTools(tools: StructuredToolInterface[], _kwargs?: Partial<BaseChatModelCallOptions>): Runnable {\n return new JarelaChatModel({\n provider: this._provider,\n modelId: this._modelId,\n params: this._params,\n boundTools: tools,\n });\n }\n\n private _convertedTools(): OpenAITool[] {\n return this._boundTools.flatMap((t) => {\n try {\n const oai = convertToOpenAITool(t) as { function?: { name?: string; description?: string; parameters: unknown } };\n if (!oai?.function?.name) return [];\n return [{\n type: \"function\" as const,\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n }];\n } catch {\n return [];\n }\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatResult> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n // Streaming path — assemble chunks into a final message.\n if (this._provider.streamInvoke && openaiTools.length > 0) {\n const finalChunk = await this._streamToFinalChunk(invokeMessages, openaiTools, runManager);\n const gen: ChatGeneration = {\n message: aiMessageFromChunk(finalChunk.message as AIMessageChunk),\n text: typeof finalChunk.message.content === \"string\" ? finalChunk.message.content : \"\",\n };\n return { generations: [gen] };\n }\n\n if (this._provider.invoke && openaiTools.length > 0) {\n const result = await this._provider.invoke(this._modelId, invokeMessages, this._params, openaiTools);\n const aiMsg = new AIMessage({\n content: result.text ?? \"\",\n tool_calls: result.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.arguments,\n type: \"tool_call\" as const,\n })),\n });\n const gen: ChatGeneration = { message: aiMsg, text: result.text ?? \"\" };\n return { generations: [gen] };\n }\n\n const providerMessages = invokeMessages\n .filter((m) => m.role !== \"tool\")\n .map((m) => ({ role: m.role as \"user\" | \"assistant\" | \"system\", content: m.content }));\n const { stream } = await this._provider.chat(this._modelId, providerMessages, this._params);\n let text = \"\";\n for await (const chunk of stream) { text += chunk; }\n const gen: ChatGeneration = { message: new AIMessage(text), text };\n return { generations: [gen] };\n }\n\n private async _streamToFinalChunk(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatGenerationChunk> {\n let acc: ChatGenerationChunk | null = null;\n for await (const chunk of this._streamFromProvider(invokeMessages, openaiTools, runManager)) {\n acc = acc ? acc.concat(chunk) : chunk;\n }\n return acc ?? new ChatGenerationChunk({ message: new AIMessageChunk({ content: \"\" }), text: \"\" });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n if (!this._provider.streamInvoke) {\n const result = await this._generate(messages, _options, runManager);\n const msg = result.generations[0].message as AIMessage;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: msg.content,\n tool_call_chunks: msg.tool_calls?.map((tc, i) => ({\n index: i,\n id: tc.id,\n name: tc.name,\n args: JSON.stringify(tc.args),\n type: \"tool_call_chunk\" as const,\n })) ?? [],\n }),\n text: typeof msg.content === \"string\" ? msg.content : \"\",\n });\n return;\n }\n\n yield* this._streamFromProvider(invokeMessages, openaiTools, runManager);\n }\n\n private async *_streamFromProvider(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n if (!this._provider.streamInvoke) return;\n let emittedAny = false;\n let stopReason: \"stop\" | \"tool_use\" | \"length\" | undefined;\n for await (const event of this._provider.streamInvoke(this._modelId, invokeMessages, this._params, openaiTools)) {\n if (event.type === \"text\") {\n emittedAny = true;\n await runManager?.handleLLMNewToken(event.delta);\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({ content: event.delta }),\n text: event.delta,\n });\n } else if (event.type === \"thinking\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { reasoning_content: event.delta },\n }),\n text: \"\",\n });\n } else if (event.type === \"tool_call_chunk\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n tool_call_chunks: [{\n index: event.index,\n id: event.id,\n name: event.name,\n args: event.args_delta,\n type: \"tool_call_chunk\" as const,\n }],\n }),\n text: \"\",\n });\n } else if (event.type === \"stop\") {\n stopReason = event.reason;\n }\n }\n // Provider ended the stream without emitting any text, thinking, or tool\n // call chunks. Without this guard, LangChain's BaseChatModel consumer sees\n // zero ChatGenerationChunks and throws \"Received empty response from chat\n // model call.\" — opaque to users. Translate the underlying stop reason\n // into something actionable.\n if (!emittedAny) {\n if (stopReason === \"length\") {\n throw new Error(\n \"Model returned no content before hitting max_tokens. \" +\n \"Reasoning likely consumed the entire token budget — raise max_tokens \" +\n \"(or the thinking budget) in the model config and retry.\",\n );\n }\n // stopReason \"stop\" with no content can mean a content-filter refusal\n // (OpenAI/Azure map content_filter -> \"stop\" in our type), or a model\n // that legitimately decided to emit nothing on this turn. Yield one\n // empty chunk so LangChain has something to aggregate; the agent loop\n // will record an empty AIMessage and the UI will fall through to `done`.\n console.warn(\n `[jarela-chat-model] Provider ${this._provider.name} ended stream with no content (stopReason=${stopReason ?? \"<none>\"}).`,\n );\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: stopReason ? { empty_stream_reason: stopReason } : {},\n }),\n text: \"\",\n });\n return;\n }\n // Mid-stream truncation: provider produced content then stopped because of\n // max_tokens (or a length-equivalent). The aggregated message is partial\n // (e.g. a table cut off mid-row). Tag the final chunk with stop_reason so\n // the agent layer can surface a \"your output was truncated\" warning to\n // the user — otherwise they see a cut-off response with no explanation.\n if (stopReason === \"length\") {\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { stop_reason: \"length\" },\n }),\n text: \"\",\n });\n }\n }\n}\n\nfunction aiMessageFromChunk(chunk: AIMessageChunk): AIMessage {\n return new AIMessage({\n content: chunk.content,\n tool_calls: chunk.tool_calls,\n invalid_tool_calls: chunk.invalid_tool_calls,\n additional_kwargs: chunk.additional_kwargs,\n });\n}\n\n// LangChain's BaseMessage.content can be a string or a content-block array\n// (text, image_url, etc. — used for multi-modal input). Preserve it through\n// to InvokeMessage so the provider routes can translate properly. Stringifying\n// destroys image attachments — `String([{...}, {...}])` becomes \"[object Object],...\"\nfunction lcContentToInvoke(content: BaseMessage[\"content\"]): string | ContentPart[] {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: ContentPart[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push({ type: \"text\", text: block });\n continue;\n }\n if (!block || typeof block !== \"object\") continue;\n const b = block as Record<string, unknown>;\n if (b.type === \"text\" && typeof b.text === \"string\") {\n parts.push({ type: \"text\", text: b.text });\n } else if (b.type === \"image_url\") {\n // OpenAI-style: { type: \"image_url\", image_url: { url: \"data:image/png;base64,...\" } }\n const url = (b.image_url as { url?: string } | string | undefined);\n const dataUrl = typeof url === \"string\" ? url : url?.url;\n if (dataUrl?.startsWith(\"data:\")) {\n const m = /^data:([^;]+);base64,(.+)$/.exec(dataUrl);\n if (m) parts.push({ type: \"image\", media_type: m[1], data: m[2] });\n }\n } else if (b.type === \"image\") {\n // Anthropic-style: { type: \"image\", source: { type: \"base64\", media_type, data } }\n const src = b.source as { media_type?: string; data?: string } | undefined;\n if (src?.media_type && src.data) {\n parts.push({ type: \"image\", media_type: src.media_type, data: src.data });\n }\n }\n }\n // If we ended up with only text blocks, collapse to a string so providers\n // that don't need multi-modal handling don't have to special-case.\n if (parts.every((p) => p.type === \"text\")) {\n return parts.map((p) => (p as { text: string }).text).join(\"\\n\");\n }\n return parts;\n}\n\nfunction toInvokeMessages(messages: BaseMessage[]): InvokeMessage[] {\n return messages.map((m): InvokeMessage => {\n if (isHumanMessage(m)) {\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n }\n if (isSystemMessage(m)) {\n return { role: \"system\", content: lcContentToInvoke(m.content) };\n }\n if (isAIMessage(m)) {\n const ai = m as AIMessage;\n const invokeMsg: InvokeMessage = {\n role: \"assistant\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n };\n if (ai.tool_calls?.length) {\n invokeMsg.tool_calls = ai.tool_calls.map((tc) => ({\n id: tc.id ?? \"\",\n type: \"function\" as const,\n function: { name: tc.name, arguments: JSON.stringify(tc.args) },\n }));\n }\n // DeepSeek thinking-mode: propagate the reasoning trace back so the\n // provider can echo it on follow-up turns (required by their API).\n const reasoning = ai.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n invokeMsg.reasoning_content = reasoning;\n }\n return invokeMsg;\n }\n if (isToolMessage(m)) {\n return {\n role: \"tool\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n tool_call_id: m.tool_call_id,\n };\n }\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n });\n}\n","import { BaseStore } from \"@langchain/langgraph-checkpoint\";\nimport type { Operation, OperationResults, Item } from \"@langchain/langgraph-checkpoint\";\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nexport class SqliteMemoryStore extends BaseStore {\n async batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>> {\n const results = await Promise.all(\n operations.map(async (op): Promise<Item | null | Item[] | void> => {\n // GetOperation: { namespace, key } — no \"value\" or \"namespacePrefix\"\n if (\"key\" in op && \"namespace\" in op && !(\"value\" in op) && !(\"namespacePrefix\" in op)) {\n const ns = op.namespace.join(\"/\");\n const row = getMemory(ns, op.key);\n if (!row) return null;\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(row.value) as Record<string, unknown>;\n } catch {\n value = { _raw: row.value };\n }\n return {\n namespace: op.namespace,\n key: op.key,\n value,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n };\n }\n\n // PutOperation: { namespace, key, value }\n if (\"value\" in op && \"namespace\" in op && \"key\" in op) {\n const ns = op.namespace.join(\"/\");\n if (op.value === null) {\n deleteMemory(ns, op.key);\n } else {\n putMemory(ns, op.key, op.value);\n }\n return undefined;\n }\n\n // SearchOperation: { namespacePrefix, ... }\n if (\"namespacePrefix\" in op) {\n const prefix = (op.namespacePrefix as string[]).join(\"/\");\n const limit = \"limit\" in op && typeof op.limit === \"number\" ? op.limit : 10;\n const rows = listMemory(prefix || undefined, undefined, limit);\n return rows.map((r) => {\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(r.value) as Record<string, unknown>;\n } catch {\n value = { _raw: r.value };\n }\n return {\n namespace: r.namespace.split(\"/\"),\n key: r.key,\n value,\n createdAt: new Date(r.created_at),\n updatedAt: new Date(r.updated_at),\n };\n });\n }\n\n return undefined;\n }),\n );\n return results as unknown as OperationResults<Op>;\n }\n}\n","import { DatabaseSync, type StatementSync } from \"node:sqlite\";\nimport { type RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseCheckpointSaver,\n TASKS,\n copyCheckpoint,\n maxChannelVersion,\n type Checkpoint,\n type CheckpointListOptions,\n type CheckpointMetadata,\n type CheckpointTuple,\n type PendingWrite,\n type SerializerProtocol,\n} from \"@langchain/langgraph-checkpoint\";\n\n// In-tree LangGraph checkpoint saver backed by node:sqlite.\n//\n// Schema-compatible drop-in replacement for SqliteSaver from\n// @langchain/langgraph-checkpoint-sqlite. The DDL is byte-identical so an\n// existing checkpoints.db keeps working without migration.\n\nconst VALID_FILTER_KEYS: readonly string[] = [\"source\", \"step\", \"parents\"];\n\ntype Row = Record<string, unknown>;\n\nfunction buildLatestSelect(includeCheckpointId: boolean): string {\n return `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\n WHERE thread_id = ? AND checkpoint_ns = ? ${\n includeCheckpointId\n ? \"AND checkpoint_id = ?\"\n : \"ORDER BY checkpoint_id DESC LIMIT 1\"\n }`;\n}\n\n// node:sqlite rejects `undefined` parameter binds; coerce to null.\nfunction nv<T>(v: T | undefined | null): T | null {\n return v === undefined ? null : (v as T | null);\n}\n\nexport class NodeSqliteSaver extends BaseCheckpointSaver {\n db: DatabaseSync;\n\n protected isSetup = false;\n protected withoutCheckpoint!: StatementSync;\n protected withCheckpoint!: StatementSync;\n\n constructor(db: DatabaseSync, serde?: SerializerProtocol) {\n super(serde);\n this.db = db;\n }\n\n static fromConnString(connStringOrLocalPath: string): NodeSqliteSaver {\n return new NodeSqliteSaver(new DatabaseSync(connStringOrLocalPath));\n }\n\n protected setup(): void {\n if (this.isSetup) return;\n this.db.exec(\"PRAGMA journal_mode=WAL\");\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS checkpoints (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n parent_checkpoint_id TEXT,\n type TEXT,\n checkpoint BLOB,\n metadata BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)\n);`);\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS writes (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n idx INTEGER NOT NULL,\n channel TEXT NOT NULL,\n type TEXT,\n value BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)\n);`);\n this.withoutCheckpoint = this.db.prepare(buildLatestSelect(false));\n this.withCheckpoint = this.db.prepare(buildLatestSelect(true));\n this.isSetup = true;\n }\n\n protected txn<T>(fn: () => T): T {\n this.db.exec(\"BEGIN\");\n try {\n const result = fn();\n this.db.exec(\"COMMIT\");\n return result;\n } catch (err) {\n try {\n this.db.exec(\"ROLLBACK\");\n } catch {\n // ignore rollback failure; surface the original error\n }\n throw err;\n }\n }\n\n private async decodeRowState(row: Row): Promise<{\n pendingWrites: [string, string, unknown][];\n checkpoint: Checkpoint;\n metadata: CheckpointMetadata;\n }> {\n const pendingWrites = await Promise.all(\n JSON.parse(String(row.pending_writes ?? \"[]\")).map(\n async (write: { task_id: string; channel: string; type?: string; value?: string }) => {\n return [\n write.task_id,\n write.channel,\n await this.serde.loadsTyped(write.type ?? \"json\", write.value ?? \"\"),\n ] as [string, string, unknown];\n },\n ),\n );\n\n const checkpoint = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.checkpoint as Uint8Array | string,\n )) as Checkpoint;\n\n if (checkpoint.v < 4 && row.parent_checkpoint_id != null) {\n await this.migratePendingSends(\n checkpoint,\n row.thread_id as string,\n row.parent_checkpoint_id as string,\n );\n }\n\n const metadata = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.metadata as Uint8Array | string,\n )) as CheckpointMetadata;\n\n return { pendingWrites, checkpoint, metadata };\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n this.setup();\n const { thread_id, checkpoint_ns = \"\", checkpoint_id } =\n config.configurable ?? {};\n const args: unknown[] = [nv(thread_id), checkpoint_ns];\n if (checkpoint_id) args.push(checkpoint_id);\n const stmt = checkpoint_id ? this.withCheckpoint : this.withoutCheckpoint;\n const row = stmt.get(...(args as never[])) as Row | undefined;\n if (row === undefined) return undefined;\n\n let finalConfig = config;\n if (!checkpoint_id) {\n finalConfig = {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n };\n }\n if (\n finalConfig.configurable?.thread_id === undefined ||\n finalConfig.configurable?.checkpoint_id === undefined\n ) {\n throw new Error(\"Missing thread_id or checkpoint_id\");\n }\n\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n\n return {\n checkpoint,\n config: finalConfig,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n\n async *list(\n config: RunnableConfig,\n options?: CheckpointListOptions,\n ): AsyncGenerator<CheckpointTuple> {\n const { limit, before, filter } = options ?? {};\n this.setup();\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns;\n\n let sql = `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\\n`;\n\n const whereClause: string[] = [];\n if (thread_id) whereClause.push(\"thread_id = ?\");\n if (checkpoint_ns !== undefined && checkpoint_ns !== null) {\n whereClause.push(\"checkpoint_ns = ?\");\n }\n if (before?.configurable?.checkpoint_id !== undefined) {\n whereClause.push(\"checkpoint_id < ?\");\n }\n\n const sanitizedFilter = Object.fromEntries(\n Object.entries(filter ?? {}).filter(\n ([key, value]) => value !== undefined && VALID_FILTER_KEYS.includes(key),\n ),\n );\n whereClause.push(\n ...Object.entries(sanitizedFilter).map(\n ([key]) => `jsonb(CAST(metadata AS TEXT))->'$.${key}' = ?`,\n ),\n );\n if (whereClause.length > 0) sql += `WHERE\\n ${whereClause.join(\" AND\\n \")}\\n`;\n sql += \"\\nORDER BY checkpoint_id DESC\";\n if (limit) sql += ` LIMIT ${parseInt(String(limit), 10)}`;\n\n const args: unknown[] = [\n thread_id,\n checkpoint_ns,\n before?.configurable?.checkpoint_id,\n ...Object.values(sanitizedFilter).map((value) => JSON.stringify(value)),\n ].filter((value) => value !== undefined && value !== null);\n\n const rows = this.db.prepare(sql).all(...(args as never[])) as Row[];\n for (const row of rows) {\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n yield {\n config: {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n },\n checkpoint,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n ): Promise<RunnableConfig> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n const thread_id = config.configurable?.thread_id as string | undefined;\n const checkpoint_ns = (config.configurable?.checkpoint_ns ?? \"\") as string;\n const parent_checkpoint_id = config.configurable?.checkpoint_id as\n | string\n | undefined;\n if (!thread_id) {\n throw new Error(`Missing \"thread_id\" field in passed \"config.configurable\".`);\n }\n const preparedCheckpoint = copyCheckpoint(checkpoint);\n const [\n [type1, serializedCheckpoint],\n [type2, serializedMetadata],\n ] = await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n if (type1 !== type2) {\n throw new Error(\n \"Failed to serialized checkpoint and metadata to the same type.\",\n );\n }\n this.db\n .prepare(\n `INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n thread_id,\n checkpoint_ns,\n checkpoint.id,\n nv(parent_checkpoint_id),\n type1,\n serializedCheckpoint as never,\n serializedMetadata as never,\n );\n return {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string,\n ): Promise<void> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n if (!config.configurable?.thread_id) {\n throw new Error(\"Missing thread_id field in config.configurable.\");\n }\n if (!config.configurable?.checkpoint_id) {\n throw new Error(\"Missing checkpoint_id field in config.configurable.\");\n }\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO writes\n (thread_id, checkpoint_ns, checkpoint_id, task_id, idx, channel, type, value)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `);\n const rows = await Promise.all(\n writes.map(async (write, idx) => {\n const [type, serializedWrite] = await this.serde.dumpsTyped(write[1]);\n return [\n config.configurable?.thread_id as string,\n (config.configurable?.checkpoint_ns ?? \"\") as string,\n config.configurable?.checkpoint_id as string,\n taskId,\n idx,\n write[0],\n type,\n serializedWrite,\n ] as const;\n }),\n );\n this.txn(() => {\n for (const row of rows) stmt.run(...(row as unknown as never[]));\n });\n }\n\n async deleteThread(threadId: string): Promise<void> {\n this.setup();\n this.txn(() => {\n this.db\n .prepare(`DELETE FROM checkpoints WHERE thread_id = ?`)\n .run(threadId);\n this.db.prepare(`DELETE FROM writes WHERE thread_id = ?`).run(threadId);\n });\n }\n\n protected async migratePendingSends(\n checkpoint: Checkpoint,\n threadId: string,\n parentCheckpointId: string,\n ): Promise<void> {\n const row = this.db\n .prepare(\n `\n SELECT\n checkpoint_id,\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n ) as pending_sends\n FROM writes as ps\n WHERE ps.thread_id = ?\n AND ps.checkpoint_id = ?\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n `,\n )\n .get(threadId, parentCheckpointId) as Row | undefined;\n const pendingSendsJson = String(row?.pending_sends ?? \"[]\");\n const mutable = checkpoint as Checkpoint & {\n channel_values?: Record<string, unknown>;\n channel_versions: Record<string, unknown>;\n };\n mutable.channel_values ??= {};\n mutable.channel_values[TASKS] = await Promise.all(\n JSON.parse(pendingSendsJson).map(\n ({ type, value }: { type?: string; value?: string }) =>\n this.serde.loadsTyped(type ?? \"json\", value ?? \"\"),\n ),\n );\n mutable.channel_versions[TASKS] =\n Object.keys(checkpoint.channel_versions).length > 0\n ? maxChannelVersion(...Object.values(checkpoint.channel_versions))\n : this.getNextVersion(undefined);\n }\n}\n","import { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { NodeSqliteSaver } from \"./sqlite-checkpoint-saver\";\n\n// Persistent graph state per thread_id. Multi-step plans, scratchpad messages,\n// and any pending tool-call sequence survive process restarts and resume on\n// the next agent.stream() with the same thread_id.\n//\n// Stored in a separate DB file (~/.jarela/checkpoints.db) so LangGraph\n// manages its own schema independently of our own migrations under\n// lib/db/. Both files use WAL mode via the same node:sqlite driver.\n\nconst CHECKPOINT_PATH = join(getDataDir(), \"checkpoints.db\");\n\nlet _saver: NodeSqliteSaver | null = null;\n\nexport function getCheckpointer(): NodeSqliteSaver {\n if (!_saver) {\n _saver = NodeSqliteSaver.fromConnString(CHECKPOINT_PATH);\n }\n return _saver;\n}\n","import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\nimport {\n AIMessage,\n AIMessageChunk,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getDefaultModelConfig } from \"@/lib/stores/model-config\";\nimport { getAllToolsAsync } from \"@/lib/tools\";\nimport { JarelaChatModel } from \"@/lib/providers/jarela-chat-model\";\nimport { SqliteMemoryStore } from \"@/lib/stores/langgraph-store\";\nimport { getCheckpointer } from \"@/lib/agents/checkpointer\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport type { StreamChunk, StreamOptions } from \"./base\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\nimport { getConfig } from \"@/lib/env/config\";\n\nfunction toBaseMessages(\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n systemPrompt?: string,\n): BaseMessage[] {\n const base: BaseMessage[] = systemPrompt ? [new SystemMessage(systemPrompt)] : [];\n return [\n ...base,\n ...messages.map((m) => {\n // Plain text path — fast & most common.\n if (typeof m.content === \"string\") {\n return m.role === \"user\" ? new HumanMessage(m.content) : new AIMessage(m.content);\n }\n // Multi-modal path — translate our ContentPart[] into LangChain's\n // standard content-block array. Images become OpenAI-style\n // `image_url` blocks (the LangChain idiom that all major providers\n // accept on input). File attachments fall back to text so they\n // still reach text-only models. Assistant messages currently never\n // contain attachments in our flow, so we just flatten to text.\n if (m.role === \"assistant\") {\n const text = m.content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text).join(\"\\n\");\n return new AIMessage(text);\n }\n const blocks: Array<Record<string, unknown>> = [];\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) blocks.push({ type: \"text\", text: part.text });\n } else if (part.type === \"image\") {\n blocks.push({\n type: \"image_url\",\n image_url: { url: `data:${part.media_type};base64,${part.data}` },\n });\n } else if (part.type === \"file\") {\n if (part.media_type.startsWith(\"text/\") || part.media_type === \"application/json\") {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name}]\\n${part.data}` });\n } else {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name} (${part.media_type})]` });\n }\n }\n }\n // Cast through unknown — LangChain's strict block-union type rejects our\n // dynamic shape, but at runtime BaseMessage stores content as-is and\n // ChatModels consume whatever the provider's API expects (image_url for\n // OpenAI, image for Anthropic, etc.).\n return new HumanMessage({ content: blocks as unknown as string });\n }),\n ];\n}\n\nexport async function* streamWithConfig(\n threadId: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n options?: StreamOptions,\n signal?: AbortSignal,\n): AsyncIterable<StreamChunk> {\n const runCfg = options?.agent_run_config;\n\n const cfgName = runCfg?.model_config_name ?? null;\n const cfg = cfgName ? getModelConfig(cfgName) : getDefaultModelConfig();\n\n if (!cfg) {\n yield { type: \"error\", data: { message: \"No model configured. Add a model in the Models panel.\", code: \"no_model\" } };\n return;\n }\n\n let params: ProviderParams;\n try {\n params = JSON.parse(cfg.params) as ProviderParams;\n } catch {\n yield { type: \"error\", data: { message: `Model config \"${cfg.name}\" has invalid JSON params.`, code: \"config_parse_error\" } };\n return;\n }\n\n const provider = getProvider(cfg.provider);\n\n const toolPolicy = runCfg?.allowed_tools?.length\n ? { allow: runCfg.allowed_tools }\n : options?.tool_policy;\n const tools = await getAllToolsAsync(toolPolicy);\n\n const model = new JarelaChatModel({ provider, modelId: cfg.model_id, params });\n const store = new SqliteMemoryStore();\n const checkpointer = getCheckpointer();\n\n // Wipe prior checkpoint state for this thread BEFORE invoking the agent.\n // Every turn we rebuild the message history from jarela.db.messages (the\n // source of truth), so the checkpointer's only job is to buffer in-flight\n // tool-call state within the current turn. Without this delete, LangGraph's\n // default messages-state reducer keeps appending — every prior turn's tool\n // results (plus any inline image data URIs) stay in state forever and get\n // replayed to the LLM, eventually blowing past the model's context window.\n // See: thread fb35423b grew to 893 MB / 238 checkpoints because a single\n // image-attached HumanMessage (~1.2 MB base64) was replayed on every retry.\n try {\n await checkpointer.deleteThread(threadId);\n } catch (err) {\n // SqliteSaver creates the `checkpoints` table lazily on first write.\n // If we get here before any checkpoint has ever been persisted (fresh\n // DB, first turn of the process), deleteThread raises\n // `SQLITE_ERROR: no such table: checkpoints` — which is a no-op for us,\n // not an error. Swallow it; surface anything else.\n const msg = err instanceof Error ? err.message : String(err);\n if (!/no such table:\\s*checkpoints/i.test(msg)) {\n console.error(\"[llm] checkpoint reset failed for thread\", threadId, err);\n }\n }\n\n const agent = createReactAgent({ llm: model, tools, store, checkpointer });\n\n // Track which AIMessageChunk-tool-call-chunks we've already announced (by id).\n // We emit a tool_call event once per id when both id+name are known and\n // the assistant turn ends, so callers see structured tool calls (not partial ones).\n const announcedToolIds = new Set<string>();\n let pendingAIChunk: AIMessageChunk | null = null;\n let totalOutputTokens = 0;\n // Tracks whether the model hit max_tokens mid-stream. JarelaChatModel tags\n // the final chunk with additional_kwargs.stop_reason=\"length\" when this\n // happens; we surface a non-fatal warning before `done` so the user knows\n // their (visibly truncated) response was cut off — and can ask to continue.\n let truncatedByLength = false;\n // Tracks whether the previous emitted chunk was a tool result. When the next\n // AI message starts producing text, we prepend a paragraph break so the\n // pre-tool plan acknowledgment and the post-tool reply don't visually merge.\n let needsParagraphBreak = false;\n let textEmittedSinceLastBreak = false;\n\n const flushPendingToolCalls = function* (): Iterable<StreamChunk> {\n if (!pendingAIChunk) return;\n const calls = pendingAIChunk.tool_calls ?? [];\n for (const tc of calls) {\n if (!tc.id || announcedToolIds.has(tc.id)) continue;\n announcedToolIds.add(tc.id);\n yield { type: \"tool_call\", data: { id: tc.id, name: tc.name ?? \"\", arguments: tc.args ?? {} } };\n }\n pendingAIChunk = null;\n };\n\n try {\n const agentStream = await agent.stream(\n { messages: toBaseMessages(messages, runCfg?.system_prompt) },\n {\n streamMode: [\"messages\", \"updates\"],\n configurable: { thread_id: threadId },\n // LangGraph counts EACH node visit (model call + each tool call) as a\n // step. File-organization, multi-search-and-fetch, and any task that\n // pairs every action with a verify call (file_move + file_stat, etc.)\n // burns through 50 fast — 25 file moves and you're done. 200 leaves\n // generous headroom for legitimate multi-step work while still\n // bounding obvious runaway loops. Configurable via env per deployment.\n recursionLimit: getConfig().recursionLimit,\n // Cancellation: when the user hits Stop (or the last client\n // disconnects), the route aborts this signal and the LangGraph\n // pregel loop unwinds, throwing a friendly aborted error below.\n signal,\n },\n );\n\n for await (const [mode, payload] of agentStream as AsyncIterable<[string, unknown]>) {\n if (mode === \"messages\") {\n const [chunk] = payload as [BaseMessage, unknown];\n if (chunk instanceof AIMessageChunk) {\n if (typeof chunk.content === \"string\" && chunk.content) {\n // After a tool result, the next AI text starts a new conceptual\n // turn. Insert a paragraph break so the pre-tool plan and the\n // post-tool reply don't visually merge into one run-on sentence.\n let delta = chunk.content;\n if (needsParagraphBreak && textEmittedSinceLastBreak) {\n delta = \"\\n\\n\" + delta;\n }\n needsParagraphBreak = false;\n textEmittedSinceLastBreak = true;\n totalOutputTokens += 1;\n yield { type: \"text_delta\", data: { delta } };\n }\n const reasoning = chunk.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n yield { type: \"thinking_delta\", data: { delta: reasoning } };\n }\n if (chunk.additional_kwargs?.stop_reason === \"length\") {\n truncatedByLength = true;\n }\n pendingAIChunk = pendingAIChunk ? pendingAIChunk.concat(chunk) : chunk;\n } else if (chunk instanceof ToolMessage) {\n yield* flushPendingToolCalls();\n let result: unknown = chunk.content;\n if (typeof result === \"string\") {\n try { result = JSON.parse(result); } catch { /* keep string */ }\n }\n yield {\n type: \"tool_result\",\n data: { id: chunk.tool_call_id, name: chunk.name ?? \"\", result },\n };\n // Next AI text should be visually separated from the pre-tool prose.\n needsParagraphBreak = true;\n }\n } else if (mode === \"updates\") {\n // End of an agent step — flush any unflushed tool calls (e.g. final assistant message\n // with no follow-up tool execution).\n yield* flushPendingToolCalls();\n }\n }\n\n // Final flush in case stream ended without an \"updates\" tick.\n yield* flushPendingToolCalls();\n } catch (err) {\n const name = err instanceof Error ? err.name : \"\";\n const baseMsg = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error && err.stack ? err.stack : \"\";\n // undici surfaces network failures as a bare \"fetch failed\" with the\n // real reason (ECONNREFUSED, EAI_AGAIN, UND_ERR_SOCKET, cert issues,\n // proxy CONNECT rejects, …) hidden under err.cause. Walk the chain so\n // operators get a useful log line and the UI shows something actionable.\n const causeChain: string[] = [];\n let cur: unknown = err;\n let depth = 0;\n while (cur && typeof cur === \"object\" && \"cause\" in cur && depth < 4) {\n const c = (cur as { cause?: unknown }).cause;\n if (!c) break;\n const cMsg = c instanceof Error ? `${c.name}: ${c.message}` : String(c);\n const cCode = c && typeof c === \"object\" && \"code\" in c ? ` [${(c as { code?: string }).code}]` : \"\";\n causeChain.push(`${cMsg}${cCode}`);\n cur = c;\n depth += 1;\n }\n const rawMsg = causeChain.length > 0\n ? `${baseMsg} (cause: ${causeChain.join(\" → \")})`\n : baseMsg;\n\n // User-initiated abort (Stop button / client disconnect): emit a\n // short error chunk and let the route fall through to `done` so the\n // queued-message drain in the UI fires normally.\n if (signal?.aborted || name === \"AbortError\" || /aborted/i.test(rawMsg)) {\n yield { type: \"error\", data: { message: \"Run interrupted by user.\", code: \"aborted\" } };\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n aborted: true,\n },\n };\n return;\n }\n\n console.error(\"[agent_error]\", stack || rawMsg);\n\n // Translate LangGraph's recursion limit into a friendly explanation —\n // the raw stack mentions internal Pregel paths users can't act on. They\n // CAN act on knowing the agent loop didn't converge (likely chasing tool\n // results in a loop or a genuinely deep multi-step task).\n let friendly = rawMsg;\n let code = \"agent_error\";\n if (name === \"GraphRecursionError\" || /recursion limit/i.test(rawMsg)) {\n const limit = getConfig().recursionLimit;\n friendly =\n `The agent took too many tool-calling steps without finishing (hit the ${limit}-step limit). ` +\n `If the task is legitimately deep, raise JARELA_RECURSION_LIMIT in the env. ` +\n `If the agent looked stuck in a loop (calling the same tool repeatedly), simplify the prompt or ` +\n `try /new to start fresh — long histories of tool results sometimes make the model re-attempt the same step.`;\n code = \"recursion_limit\";\n } else if (/Received empty response from chat model call/i.test(rawMsg)) {\n // Defense in depth: JarelaChatModel._streamFromProvider already guards\n // against this by emitting a sentinel empty chunk, but if a future\n // provider bypasses that path we still want a useful message instead of\n // the raw LangChain stack.\n friendly =\n \"The model returned an empty response. This usually means a content filter triggered, \" +\n \"max_tokens was too low for a reasoning model, or the connection dropped mid-stream. \" +\n \"Check the model config and retry.\";\n code = \"empty_response\";\n } else if (/max_tokens/i.test(rawMsg) && /no content|before hitting/i.test(rawMsg)) {\n code = \"max_tokens_exhausted\";\n }\n // Pull out the FIRST in-app frame from the stack so the user sees what\n // module triggered it, without dumping the full Pregel/webpack trace.\n const firstAppFrame = stack.split(\"\\n\").find((l) => /\\(rsc\\)\\.\\/lib\\//.test(l));\n const trimmed = firstAppFrame ? `\\n${firstAppFrame.trim()}` : \"\";\n yield { type: \"error\", data: { message: `${friendly}${trimmed}`, code } };\n return;\n }\n\n if (truncatedByLength) {\n yield {\n type: \"error\",\n data: {\n message:\n \"Response truncated — the model hit its max_tokens limit before finishing. \" +\n \"Raise max_tokens in the model config (Anthropic defaults to 4096) and ask me to continue.\",\n code: \"max_tokens_truncated\",\n },\n };\n }\n\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n },\n };\n}\n","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { MBTI_PRESETS, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\n\ninterface SignalSnapshot {\n mood: \"frustrated\" | \"rushed\" | \"positive\" | \"neutral\";\n urgency: number;\n frustration: number;\n positivity: number;\n}\n\n/**\n * Build a compact runtime persona section from per-agent adaptive settings and\n * the current user message. This keeps adaptation deterministic and auditable.\n */\nexport function buildAdaptivePersonaContext(agent: AgentConfigRow, userMessage: string): string {\n if (!agent.adaptive_persona_enabled) return \"\";\n\n const mbti = toMbti(agent.adaptive_mbti) ?? \"INTJ\";\n const mbtiLabel = MBTI_PRESETS[mbti].label;\n\n const strength = clampPercent(agent.adaptive_persona_strength);\n const empathy = clampPercent(agent.adaptive_empathy);\n const expressiveness = clampPercent(agent.adaptive_expressiveness);\n const verbosity = clampPercent(agent.adaptive_verbosity);\n\n const signal = detectSignals(userMessage);\n const intensity = strength / 100;\n\n const targetEmpathy = clampPercent(\n empathy + Math.round((signal.frustration * 30 + signal.urgency * 10 - signal.positivity * 6) * intensity),\n );\n const targetExpressive = clampPercent(\n expressiveness + Math.round((signal.positivity * 24 - signal.frustration * 12) * intensity),\n );\n const targetVerbosity = clampPercent(\n verbosity + Math.round((signal.urgency * -30 + signal.frustration * -12) * intensity),\n );\n\n const empathyBand = bandLabel(targetEmpathy, [30, 70], [\"low\", \"balanced\", \"high\"]);\n const expressiveBand = bandLabel(targetExpressive, [30, 70], [\"reserved\", \"balanced\", \"energetic\"]);\n const verbosityBand = bandLabel(targetVerbosity, [30, 70], [\"concise\", \"balanced\", \"detailed\"]);\n\n const directives = [\n empathyBand === \"high\"\n ? \"Acknowledge user friction clearly before giving steps.\"\n : empathyBand === \"low\"\n ? \"Keep emotional language minimal; stay pragmatic and neutral.\"\n : \"Use light empathy, then move quickly to actionable guidance.\",\n verbosityBand === \"concise\"\n ? \"Prefer short, direct answers and prioritize the next concrete action.\"\n : verbosityBand === \"detailed\"\n ? \"Provide fuller rationale and tradeoffs when relevant.\"\n : \"Keep explanations compact with enough rationale to be useful.\",\n expressiveBand === \"energetic\"\n ? \"Use lively but professional tone; avoid slang and exaggeration.\"\n : expressiveBand === \"reserved\"\n ? \"Use calm, matter-of-fact wording.\"\n : \"Use steady, approachable wording.\",\n signal.mood === \"rushed\"\n ? \"User appears time-constrained; front-load the answer and avoid preamble.\"\n : signal.mood === \"frustrated\"\n ? \"User appears frustrated; validate briefly and offer a clear recovery path.\"\n : \"Do not force mood mirroring; keep behavior stable and task-focused.\",\n ];\n\n return [\n \"--- Adaptive persona ---\",\n \"These style constraints are dynamic and apply to this turn only.\",\n `Preset: ${mbti} (${mbtiLabel})`,\n `Detected user signal: ${signal.mood}`,\n `Adapt strength: ${strength}/100`,\n `Target empathy: ${targetEmpathy}/100 (${empathyBand})`,\n `Target expressiveness: ${targetExpressive}/100 (${expressiveBand})`,\n `Target verbosity: ${targetVerbosity}/100 (${verbosityBand})`,\n \"Style directives:\",\n ...directives.map((d) => `- ${d}`),\n \"Never sacrifice factual accuracy, safety policy, or execution completeness for style.\",\n ].join(\"\\n\");\n}\n\nfunction detectSignals(text: string): SignalSnapshot {\n const lower = text.toLowerCase();\n\n const frustrationHits = countMatches(lower, [\n \"stuck\", \"frustrat\", \"annoy\", \"angry\", \"wtf\", \"doesn't work\", \"not working\", \"broken\", \"hate this\",\n ]);\n const urgencyHits = countMatches(lower, [\n \"asap\", \"urgent\", \"quick\", \"quickly\", \"fast\", \"hurry\", \"right now\", \"immediately\",\n ]);\n const positivityHits = countMatches(lower, [\n \"thanks\", \"thank you\", \"awesome\", \"great\", \"love\", \"perfect\", \"nice\",\n ]);\n\n const frustration = Math.min(1, frustrationHits / 2);\n const urgency = Math.min(1, urgencyHits / 2);\n const positivity = Math.min(1, positivityHits / 2);\n\n let mood: SignalSnapshot[\"mood\"] = \"neutral\";\n if (frustration >= 0.5) mood = \"frustrated\";\n else if (urgency >= 0.5) mood = \"rushed\";\n else if (positivity >= 0.5) mood = \"positive\";\n\n return { mood, urgency, frustration, positivity };\n}\n\nfunction countMatches(text: string, terms: string[]): number {\n let n = 0;\n for (const term of terms) {\n if (text.includes(term)) n += 1;\n }\n return n;\n}\n\nfunction clampPercent(v: number): number {\n if (!Number.isFinite(v)) return 50;\n return Math.max(0, Math.min(100, Math.round(v)));\n}\n\nfunction bandLabel<T extends string>(value: number, cutoffs: [number, number], labels: [T, T, T]): T {\n if (value < cutoffs[0]) return labels[0];\n if (value > cutoffs[1]) return labels[2];\n return labels[1];\n}\n\nfunction toMbti(v: string | null | undefined): MbtiType | null {\n if (!v) return null;\n return (v in MBTI_PRESETS ? v : null) as MbtiType | null;\n}\n","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { getDefaultHarnessId, getHarness } from \"@/lib/stores/harnesses\";\nimport { getBuiltinHarness } from \"./presets\";\nimport { DEFAULT_HARNESS_ID, HARNESS_SECTION_KEYS, type HarnessSectionKey } from \"./types\";\n\nexport type ResolvedHarnessSections = Record<HarnessSectionKey, string>;\n\n/**\n * Resolve which harness applies to a given agent and return its section\n * bodies as a record. Disabled sections become empty strings (so the\n * caller's `.filter(Boolean)` in systemParts assembly drops them).\n *\n * Resolution order:\n * 1. agentCfg.harness_id (per-agent override)\n * 2. app-settings default_harness_id (global default)\n * 3. builtin:default\n *\n * Stale ids (custom harness deleted out from under an agent) fall back to\n * builtin:default rather than erroring — matches how missing model configs\n * behave in this codebase.\n */\nexport function resolveHarness(\n agentCfg: Pick<AgentConfigRow, \"harness_id\">,\n): ResolvedHarnessSections {\n const id = agentCfg.harness_id || getDefaultHarnessId() || DEFAULT_HARNESS_ID;\n const harness =\n getHarness(id) ?? getBuiltinHarness(DEFAULT_HARNESS_ID) ?? null;\n const out = {} as ResolvedHarnessSections;\n for (const key of HARNESS_SECTION_KEYS) {\n const section = harness?.sections[key];\n out[key] = section?.enabled ? section.body : \"\";\n }\n return out;\n}\n","import type { Claim } from \"./types\";\n\n// First-person past-tense or perfect-tense action verbs that imply work was\n// performed in the current turn. We don't try to enumerate every English verb;\n// the set covers the dominant fabrication shapes in observed transcripts.\nconst ACTION_VERBS = [\n \"patched\", \"edited\", \"wrote\", \"ran\", \"verified\", \"created\", \"deleted\",\n \"updated\", \"committed\", \"saved\", \"added\", \"removed\", \"fixed\", \"applied\",\n \"installed\", \"configured\", \"renamed\", \"moved\", \"copied\", \"pushed\", \"merged\",\n \"checked\", \"confirmed\", \"tested\",\n];\n\nconst VERB_GROUP = ACTION_VERBS.join(\"|\");\n\nconst PATTERNS: RegExp[] = [\n // \"I patched the file\" — bare past tense\n new RegExp(`\\\\bI\\\\s+(?:just\\\\s+)?(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"I've patched\", \"I have patched\"\n new RegExp(`\\\\bI(?:'ve|\\\\s+have)\\\\s+(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"Verified the bytes\" — leading capital, no subject (common in concise replies)\n new RegExp(`(?:^|\\\\.\\\\s+|\\\\n)(${VERB_GROUP})\\\\b`, \"gi\"),\n];\n\nconst FUTURE_PATTERNS: RegExp[] = [\n // \"I'll patch\", \"I will patch\", \"I would patch\", \"I could patch\"\n /\\bI(?:'ll|\\s+will|\\s+would|\\s+could|\\s+should|\\s+can|\\s+might)\\s+\\w+/i,\n];\n\nexport function findActionClaims(text: string): Claim[] {\n const out: Claim[] = [];\n const seen = new Set<string>();\n for (const re of PATTERNS) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const verb = m[1].toLowerCase();\n // Skip if this match is inside a future-tense clause. Scan a small\n // backward window for \"I'll / I will\" before the verb.\n const start = Math.max(0, m.index - 24);\n const window = text.slice(start, m.index + m[0].length);\n if (FUTURE_PATTERNS.some((f) => f.test(window))) continue;\n const key = `${verb}@${m.index}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ verb, raw: m[0].trim() });\n }\n }\n return out;\n}\n","import type { Citation } from \"./types\";\n\n// Matches `(via NAME)` and `(via NAME ARG1 ARG2)` and `(via NAME, file: ...)`.\n// Captures the tool name (first whitespace-delimited identifier-ish token).\n// Ignores file-path citations like `(lib/foo.ts:42)` and memory citations\n// like `(memory: ns/key)` — those are not tool-call claims.\nconst VIA_RE = /\\(\\s*via\\s+([A-Za-z_][\\w-]*)[^)]*\\)/g;\n\nexport function findCitations(text: string): Citation[] {\n const out: Citation[] = [];\n VIA_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VIA_RE.exec(text)) !== null) {\n out.push({ tool: m[1], raw: m[0] });\n }\n return out;\n}\n","import { findActionClaims } from \"./claim-detector\";\nimport { findCitations } from \"./citation-parser\";\nimport type { ValidationResult } from \"./types\";\n\nconst SUMMARY_PATTERNS: RegExp[] = [\n /^#{1,6}\\s*Summary(?:\\s+of\\s+changes)?\\b/im,\n /\\bI(?:'ve|\\s+have)\\s+completed\\b/i,\n /\\bWhat\\s+I\\s+did\\b/i,\n];\n\n/**\n * Cross-check the assistant's text output against the tool calls actually\n * issued in this turn. Returns ok=true when nothing fishy is detected,\n * or ok=false with a kind + reason when a fabrication shape is matched.\n *\n * Priority (first match wins): citation_unregistered_tool >\n * citation_uncalled_tool > claim_without_tool > summary_without_action.\n *\n * Lenient principle: when ANY tool was called this turn, action-claim text\n * is allowed (the model legitimately did work, even if its phrasing isn't\n * tagged with `(via ...)`). Citations are checked regardless of tool count.\n */\nexport function validateAssistantOutput(\n text: string,\n toolCalls: readonly string[],\n allowedTools: readonly string[],\n): ValidationResult {\n const calledSet = new Set(toolCalls);\n const allowedSet = new Set(allowedTools);\n\n // Citation checks run regardless of whether other tools were called —\n // a `(via foo)` tag MUST refer to a registered tool that was actually\n // invoked this turn.\n const citations = findCitations(text);\n for (const c of citations) {\n if (!allowedSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_unregistered_tool\",\n reason: `You wrote \"${c.raw}\" but \"${c.tool}\" is not a registered tool. Either drop the citation or call the correct tool.`,\n evidence: c.raw,\n };\n }\n if (!calledSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_uncalled_tool\",\n reason: `You wrote \"${c.raw}\" but did not actually call \"${c.tool}\" this turn. Call the tool or drop the citation.`,\n evidence: c.raw,\n };\n }\n }\n\n // Claim and summary checks only fire when zero tools were called. If any\n // tool ran, the text is treated as legitimately describing work done.\n if (toolCalls.length > 0) return { ok: true };\n\n const claims = findActionClaims(text);\n if (claims.length > 0) {\n const c = claims[0];\n return {\n ok: false,\n kind: \"claim_without_tool\",\n reason: `You wrote \"${c.raw}\" but did not call any tool this turn. Either call the tool that performs the action or rephrase as a proposal.`,\n evidence: c.raw,\n };\n }\n\n for (const re of SUMMARY_PATTERNS) {\n const m = text.match(re);\n if (m) {\n return {\n ok: false,\n kind: \"summary_without_action\",\n reason: `You wrote a summary section (\"${m[0].trim()}\") but did not call any tool this turn. Drop the recap or do the work first.`,\n evidence: m[0].trim(),\n };\n }\n }\n\n return { ok: true };\n}\n","export { validateAssistantOutput } from \"./validator\";\nexport { findActionClaims } from \"./claim-detector\";\nexport { findCitations } from \"./citation-parser\";\nexport type {\n ValidationKind,\n ValidationOk,\n ValidationFail,\n ValidationResult,\n Citation,\n Claim,\n} from \"./types\";\n","import type { MessageRow } from \"@/lib/stores/threads\";\nimport { transcriptText } from \"@/lib/agents/conversation-summary\";\n\nexport type ContextTier = \"hot\" | \"warm\" | \"facts\";\n\nexport type ContextTierPriority = [ContextTier, ContextTier, ContextTier];\n\nexport interface ContextTierProportions {\n hot?: number;\n warm?: number;\n facts?: number;\n}\n\nexport interface ContextBudgetConfig {\n context_window_tokens?: number;\n max_tokens?: number;\n context_tier_proportions?: ContextTierProportions;\n context_tier_priority?: ContextTierPriority | readonly ContextTier[] | unknown;\n}\n\nexport interface ContextBudget {\n contextWindowTokens: number;\n outputReserveTokens: number;\n inputBudgetTokens: number;\n overheadTokens: number;\n tierBudgets: Record<ContextTier, number>;\n tierPriority: ContextTierPriority;\n}\n\nconst DEFAULT_CONTEXT_WINDOW_TOKENS = 8_192;\nconst DEFAULT_OVERHEAD_TOKENS = 1_200;\nconst DEFAULT_OUTPUT_RESERVE_RATIO = 0.2;\nconst DEFAULT_TIER_PRIORITY: ContextTierPriority = [\"hot\", \"warm\", \"facts\"];\nconst DEFAULT_TIER_PROPORTIONS: Required<ContextTierProportions> = {\n hot: 0.6,\n warm: 0.25,\n facts: 0.15,\n};\n\nexport function estimateTokens(text: string): number {\n const trimmed = text.trim();\n if (!trimmed) return 0;\n return Math.max(1, Math.ceil(trimmed.length / 4));\n}\n\nexport function normalizeTierPriority(value: ContextBudgetConfig[\"context_tier_priority\"]): ContextTierPriority {\n if (!Array.isArray(value)) return DEFAULT_TIER_PRIORITY;\n const tiers = value.filter((v): v is ContextTier => v === \"hot\" || v === \"warm\" || v === \"facts\");\n if (tiers.length !== 3) return DEFAULT_TIER_PRIORITY;\n if (new Set(tiers).size !== 3) return DEFAULT_TIER_PRIORITY;\n return [tiers[0], tiers[1], tiers[2]];\n}\n\nexport function normalizeTierProportions(value: ContextTierProportions | undefined): Required<ContextTierProportions> {\n const hot = toPositiveNumber(value?.hot, DEFAULT_TIER_PROPORTIONS.hot);\n const warm = toPositiveNumber(value?.warm, DEFAULT_TIER_PROPORTIONS.warm);\n const facts = toPositiveNumber(value?.facts, DEFAULT_TIER_PROPORTIONS.facts);\n const sum = hot + warm + facts;\n if (sum <= 0) return DEFAULT_TIER_PROPORTIONS;\n return {\n hot: hot / sum,\n warm: warm / sum,\n facts: facts / sum,\n };\n}\n\nexport function computeContextBudget(config: ContextBudgetConfig): ContextBudget {\n const contextWindowTokens = Math.max(\n 1,\n Math.floor(config.context_window_tokens ?? DEFAULT_CONTEXT_WINDOW_TOKENS),\n );\n const outputReserveTokens = Math.max(\n 256,\n Math.min(\n contextWindowTokens - 1,\n Math.floor(config.max_tokens ?? contextWindowTokens * DEFAULT_OUTPUT_RESERVE_RATIO),\n ),\n );\n const overheadTokens = Math.max(0, Math.min(DEFAULT_OVERHEAD_TOKENS, contextWindowTokens - outputReserveTokens));\n const inputBudgetTokens = Math.max(0, contextWindowTokens - outputReserveTokens - overheadTokens);\n const proportions = normalizeTierProportions(config.context_tier_proportions);\n const tierPriority = normalizeTierPriority(config.context_tier_priority);\n const tierBudgets = {\n hot: Math.floor(inputBudgetTokens * proportions.hot),\n warm: Math.floor(inputBudgetTokens * proportions.warm),\n facts: Math.max(0, inputBudgetTokens - Math.floor(inputBudgetTokens * proportions.hot) - Math.floor(inputBudgetTokens * proportions.warm)),\n } satisfies Record<ContextTier, number>;\n\n return {\n contextWindowTokens,\n outputReserveTokens,\n inputBudgetTokens,\n overheadTokens,\n tierBudgets,\n tierPriority,\n };\n}\n\nexport function takeRecentMessagesWithinBudget(messages: readonly MessageRow[], tokenBudget: number): MessageRow[] {\n if (tokenBudget <= 0 || messages.length === 0) return [];\n const chosen: MessageRow[] = [];\n let used = 0;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n const tokens = estimateTokens(transcriptText(msg.content));\n if (chosen.length > 0 && used + tokens > tokenBudget) break;\n chosen.push(msg);\n used += tokens;\n if (used >= tokenBudget) break;\n }\n return chosen.reverse();\n}\n\nexport function truncateLargestMessagesWithinBudget(messages: readonly MessageRow[], tokenBudget: number): MessageRow[] {\n if (messages.length === 0) return [];\n if (tokenBudget <= 0) return messages.slice(-1);\n\n const out = messages.map((m) => ({ ...m }));\n let tokens = out.map((m) => estimateTokens(transcriptText(m.content)));\n let total = tokens.reduce((a, b) => a + b, 0);\n if (total <= tokenBudget) return out;\n\n // Keep shrinking the largest message until the aggregate fits the budget.\n // This is a last-resort guardrail for pathological long turns.\n while (total > tokenBudget) {\n let idx = 0;\n for (let i = 1; i < tokens.length; i += 1) {\n if (tokens[i] > tokens[idx]) idx = i;\n }\n const cur = tokens[idx];\n if (cur <= 1) break;\n\n const needed = total - tokenBudget;\n const nextTokens = Math.max(1, cur - needed);\n const nextChars = Math.max(8, nextTokens * 4 - 32);\n const raw = transcriptText(out[idx].content).replace(/\\s+/g, \" \").trim();\n const suffix = \" [truncated for context budget]\";\n const clipped = raw.length > nextChars\n ? `${raw.slice(0, Math.max(1, nextChars)).trimEnd()}${suffix}`\n : raw;\n\n out[idx] = { ...out[idx], content: clipped };\n tokens[idx] = estimateTokens(clipped);\n total = tokens.reduce((a, b) => a + b, 0);\n }\n\n return out;\n}\n\nexport function formatContextBudgetSummary(budget: ContextBudget): string {\n const parts = [\n `window ${budget.contextWindowTokens} tokens`,\n `output reserve ${budget.outputReserveTokens}`,\n `input budget ${budget.inputBudgetTokens}`,\n `hot ${budget.tierBudgets.hot}`,\n `warm ${budget.tierBudgets.warm}`,\n `facts ${budget.tierBudgets.facts}`,\n ];\n return parts.join(\" · \");\n}\n\nfunction toPositiveNumber(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}","import { streamWithConfig } from \"@/lib/agents/llm\";\nimport type { StreamChunk, StreamOptions } from \"@/lib/agents/base\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport { addMessage, getRecentMessagesWindow, getThread, touchThread, type PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { recordToolUsage } from \"@/lib/stores/tool-stats\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { recall, type RecalledMemory } from \"@/lib/embeddings\";\nimport { listIntegrations } from \"@/lib/stores/integrations\";\nimport { buildAdaptivePersonaContext } from \"@/lib/agents/adaptive-persona\";\nimport { resolveHarness } from \"@/lib/agents/harness/resolve\";\nimport { validateAssistantOutput } from \"@/lib/agents/output-validator\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport os from \"node:os\";\nimport {\n computeContextBudget,\n formatContextBudgetSummary,\n takeRecentMessagesWithinBudget,\n truncateLargestMessagesWithinBudget,\n} from \"@/lib/agents/context-budget\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { summarizeTranscript, transcriptText } from \"@/lib/agents/conversation-summary\";\nimport { getDefaultModelConfig, getModelConfig } from \"@/lib/stores/model-config\";\nimport { getProvider } from \"@/lib/providers\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\n\n// Resolve the app name once at module load. Forks set NEXT_PUBLIC_APP_NAME to\n// rebrand the user-visible name the LLM echoes in chat replies; default\n// \"Jarela\" for upstream. Per-turn pieces of the system prompt (user profile,\n// integrations, time, env) still interpolate this constant directly.\nconst APP_NAME = getAppName();\n\nexport class RunThreadError extends Error {\n status: number;\n code: string;\n\n constructor(status: number, message: string, code: string) {\n super(message);\n this.status = status;\n this.code = code;\n }\n}\n\n// Hard cap on how long we wait for the embedding-based recall pass before\n// starting the LLM stream without it. Recall is best-effort context — making\n// users wait on a cold OpenAI embeddings round-trip every turn is a worse UX\n// than occasionally missing a memory hit.\nconst RECALL_BUDGET_MS = 400;\n\nfunction raceWithBudget<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {\n return new Promise<T>((resolve) => {\n let settled = false;\n const t = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(fallback);\n }\n }, ms);\n promise.then(\n (v) => { if (!settled) { settled = true; clearTimeout(t); resolve(v); } },\n () => { if (!settled) { settled = true; clearTimeout(t); resolve(fallback); } },\n );\n });\n}\n\n// The harness sections (capabilities, plan-first, presentation, citation,\n// self-config) used to live here as hard-coded constants. They moved to\n// `lib/agents/harness/presets.ts` as the body of `builtin:default`, and\n// `resolveHarness(agentCfg)` returns them per-turn (allowing per-agent\n// override + global default selection). See ADR-0033.\n\nexport interface PreparedThreadRun {\n stream: AsyncIterable<StreamChunk>;\n thread_id: string;\n}\n\n// Max times we'll auto-retry a single user turn when the model emits a\n// \"one moment\" stall without firing any tool. One retry is plenty — if the\n// model is *still* stalling after a forceful nudge, looping further just\n// burns tokens and the warning footer on the persisted message gives the\n// user a clear manual recovery path (\"continue\").\nconst MAX_STALL_AUTO_RETRIES = 1;\n\nfunction parseContent(raw: string): string | ContentPart[] {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length > 0 &&\n typeof parsed[0] === \"object\" &&\n parsed[0] !== null &&\n \"type\" in (parsed[0] as object)\n ) {\n return parsed as ContentPart[];\n }\n } catch {\n // not valid JSON — treat as plain text\n }\n return raw;\n}\n\nfunction contentText(content: string | ContentPart[]): string {\n if (typeof content === \"string\") return content;\n return content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text)\n .join(\" \");\n}\n\nexport async function prepareThreadRun(\n thread_id: string,\n message: string,\n options?: StreamOptions,\n attachments?: ContentPart[],\n signal?: AbortSignal,\n // Internal: tracks how many stall-retries are still allowed in this turn.\n // Public callers leave this undefined and get the default budget. The\n // wrapper decrements it when it recursively re-invokes prepareThreadRun.\n _stallRetriesLeft: number = MAX_STALL_AUTO_RETRIES,\n // Optional classification tag persisted on the injected user message.\n // Surfaces in the chat panel's category-filter toolbar (e.g.\n // 'scheduled_task', 'bridge', 'synthetic'). undefined = ordinary chat.\n userCategory: string | null = null,\n): Promise<PreparedThreadRun> {\n // Lazy-start the scheduler when any agent activity occurs so previously\n // saved scheduled tasks resume firing across server restarts.\n startScheduler();\n\n const thread = getThread(thread_id);\n if (!thread) throw new RunThreadError(404, \"Thread not found\", \"thread_not_found\");\n\n const trimmed = message.trim();\n if (!trimmed && !attachments?.length) {\n throw new RunThreadError(400, \"message required\", \"message_required\");\n }\n\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) {\n throw new RunThreadError(404, `Agent \"${thread.agent_id}\" not found`, \"agent_not_found\");\n }\n\n const content: string | ContentPart[] =\n attachments?.length ? [{ type: \"text\", text: trimmed }, ...attachments] : trimmed;\n\n const stored = typeof content === \"string\" ? content : JSON.stringify(content);\n addMessage(thread_id, \"user\", stored, undefined, userCategory);\n touchThread(thread_id, trimmed.slice(0, 80) || undefined);\n\n // Build the LLM history window: latest N messages that are also within the\n // last X hours. Both bounds come from the agent's config (defaults 50 / 8h).\n // The full history remains queryable via getMessages for the UI.\n const limit = agentCfg.history_limit ?? 50;\n const windowHours = agentCfg.history_window_hours ?? 8;\n const sinceISO = windowHours > 0\n ? new Date(Date.now() - windowHours * 3600_000).toISOString()\n : undefined;\n const allWindowMessages = getRecentMessagesWindow(thread_id, limit, sinceISO);\n\n const modelCfg = agentCfg.model_config_name\n ? getModelConfig(agentCfg.model_config_name)\n : getDefaultModelConfig();\n let providerParams: ProviderParams = {};\n if (modelCfg) {\n try {\n providerParams = JSON.parse(modelCfg.params) as ProviderParams;\n } catch {\n providerParams = {};\n }\n }\n\n const budget = computeContextBudget({\n context_window_tokens:\n typeof providerParams.context_window_tokens === \"number\"\n ? providerParams.context_window_tokens\n : undefined,\n max_tokens: typeof providerParams.max_tokens === \"number\" ? providerParams.max_tokens : undefined,\n context_tier_proportions:\n typeof providerParams.context_tier_proportions === \"object\" && providerParams.context_tier_proportions\n ? (providerParams.context_tier_proportions as { hot?: number; warm?: number; facts?: number })\n : undefined,\n context_tier_priority: providerParams.context_tier_priority,\n });\n\n const hotMessages = takeRecentMessagesWithinBudget(allWindowMessages, budget.tierBudgets.hot);\n\n // Build agent run config from DB record\n const userProfile = getUserProfile();\n const userCtxParts: string[] = [];\n if (userProfile?.name) userCtxParts.push(`Name: ${userProfile.name}`);\n if (userProfile?.about) userCtxParts.push(`About: ${userProfile.about}`);\n if (\n userProfile?.location_consent === 1 &&\n typeof userProfile.location_lat === \"number\" &&\n typeof userProfile.location_lng === \"number\"\n ) {\n const ageSec = userProfile.location_updated_at\n ? Math.round((Date.now() - Date.parse(userProfile.location_updated_at)) / 1000)\n : null;\n const ageStr = ageSec === null ? \"unknown age\"\n : ageSec < 120 ? `${ageSec}s ago`\n : ageSec < 7200 ? `${Math.round(ageSec / 60)}m ago`\n : `${Math.round(ageSec / 3600)}h ago`;\n const acc = userProfile.location_accuracy_m != null\n ? ` (±${Math.round(userProfile.location_accuracy_m)}m)` : \"\";\n const label = userProfile.location_label ? ` — ${userProfile.location_label}` : \"\";\n userCtxParts.push(\n `Location: ${userProfile.location_lat.toFixed(5)}, ${userProfile.location_lng.toFixed(5)}${acc}${label} [updated ${ageStr}]`,\n \" (User has opted in to share location. Use it for any location-dependent answer — weather, nearby places, directions, local time. Call get_user_location for the freshest values.)\",\n );\n }\n const userCtx = userCtxParts.length > 0\n ? `--- User context ---\\n${userCtxParts.join(\"\\n\")}`\n : null;\n\n const timeCtx = `Current time: ${new Date().toISOString()} (UTC). Use this when computing scheduled task timestamps.`;\n // Accept both the new (\"essential\"/\"full\") and legacy (\"normal\"/\"advanced\")\n // labels so an older client speaking to a newer server still works.\n const rawMode = options?.ui_experience_mode;\n const experienceMode = rawMode === \"essential\" || rawMode === \"normal\" ? \"essential\" : \"full\";\n const experienceCtx = [\n \"--- UX mode ---\",\n `User interface mode: ${experienceMode}.`,\n experienceMode === \"essential\"\n ? \"Prefer concise, plain-language explanations and avoid exposing low-level configuration details unless asked.\"\n : \"User opted into the full / advanced UI; detailed technical explanations are welcome.\",\n ].join(\"\\n\");\n\n // Host environment hint so the agent doesn't have to guess platform-specific\n // paths (e.g. iCloud Drive lives at a different default location on Windows\n // vs. macOS). Keeps the agent grounded in the actual filesystem it's\n // operating against.\n const envCtx = [\n \"--- Host environment ---\",\n `Platform: ${process.platform} (${process.arch})`,\n `CWD: ${process.cwd()}`,\n `Home: ${os.homedir()}`,\n process.platform === \"win32\"\n ? \"iCloud Drive on Windows (if installed): %USERPROFILE%\\\\iCloudDrive (a.k.a. ~\\\\iCloudDrive)\"\n : process.platform === \"darwin\"\n ? \"iCloud Drive on macOS: ~/Library/Mobile Documents/com~apple~CloudDocs\"\n : \"\",\n `File-tool path resolution: absolute paths and \\`~/...\\` are honored verbatim; BARE RELATIVE paths (e.g. \\`notes.txt\\`) resolve against HOME, not cwd. cwd is the ${APP_NAME} install directory and should never be used as a default location for user files.`,\n \"Verify file paths with file_stat or file_list before assuming they exist. Always echo the resolved absolute path back to the user when you create/move/delete a file so they know where it landed.\",\n ].filter(Boolean).join(\"\\n\");\n\n // Surface configured integrations so the LLM knows native tools are wired\n // and ready. Without this, the model defaults to shell-exec'ing CLIs (`jira`,\n // `gh`, etc.) because that's what its training data covers — even though\n // the typed REST tools are right there in the function list.\n const configuredIntegrations = listIntegrations().filter((i) => i.configured);\n const integrationsCtx = configuredIntegrations.length > 0 ? [\n \"--- Configured integrations (use the typed tools, not shell CLIs) ---\",\n ...configuredIntegrations.flatMap((i) => {\n if (i.name === \"atlassian\") {\n const url = i.values.url;\n return [\n `Atlassian: ${url} as ${i.values.email}.`,\n \" Use jira_search / jira_get_issue / jira_create_issue / jira_add_comment / jira_transition_issue / confluence_search / confluence_get_page.\",\n \" DO NOT shell out to a `jira` or `acli` CLI — these REST tools are already authenticated and use the corporate proxy correctly.\",\n ];\n }\n if (i.name === \"jira_align\") {\n return [\n \"Jira Align: configured.\",\n \" Use jira_align_search_items / jira_align_get_item / jira_align_create_item / jira_align_update_item / jira_align_transition_item / jira_align_add_comment.\",\n ];\n }\n if (i.name === \"github\") {\n return [\n \"GitHub: configured.\",\n \" Use github_* tools for issues/PRs/code/reviews (search, create, update, comment, merge, file fetch) instead of shelling out to `gh`.\",\n ];\n }\n if (i.name === \"gmail\") {\n return [\n \"Gmail + Calendar: configured.\",\n \" Use gmail_* for inbox/search/draft/labels and calendar_* for event operations. Prefer these typed tools over raw IMAP/SMTP instructions.\",\n ];\n }\n if (i.name === \"outlook\") {\n return [\n \"Outlook + Calendar: configured.\",\n \" Use outlook_* for mail operations and outlook_calendar_* for event operations.\",\n ];\n }\n if (i.name === \"google\") {\n return [\n \"Google AI: configured.\",\n \" Use generate_image when the user asks to create images; don't claim image generation is unavailable.\",\n ];\n }\n return [`${i.name}: configured.`];\n }),\n \"\",\n ].join(\"\\n\") : \"\";\n\n const memoryCtx = [\n \"--- Memory & recall ---\",\n \"You have long-term memory across sessions and a fresh recall pass on every turn.\",\n `- Hot conversation history is budgeted by model context size: ${formatContextBudgetSummary(budget)}.`,\n \"- A semantic search over all stored memory entries + past chat messages was run against the user's turn; matching items appear under \\\"Relevant context\\\" below.\",\n \"- Use memory_write proactively when the user shares a fact, preference, or decision worth remembering. Use memory_read / memory_list to recall stored facts on demand.\",\n \"- If you want detail from outside the recent window, the user can scroll up — but for facts you've stored explicitly, prefer recall over guessing.\",\n ].join(\"\\n\");\n\n const warmSummaryCtx = await buildWarmSummaryContext(\n allWindowMessages,\n hotMessages.length,\n modelCfg?.provider,\n modelCfg?.model_id,\n providerParams,\n budget.tierBudgets.warm,\n );\n\n const warmWasExpected = budget.tierBudgets.warm > 32 && (allWindowMessages.length - hotMessages.length) >= 2;\n const hotMessagesForPrompt = !warmSummaryCtx && warmWasExpected\n ? truncateLargestMessagesWithinBudget(hotMessages, budget.tierBudgets.hot)\n : hotMessages;\n\n const history = hotMessagesForPrompt.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: parseContent(m.content),\n }));\n\n const factsCtx = buildFactsContext(trimmed, budget.tierBudgets.facts);\n\n const tierCtxByName = {\n hot: \"\",\n warm: warmSummaryCtx,\n facts: factsCtx,\n } as const;\n const tierOrderCtx = budget.tierPriority\n .map((tier) => tierCtxByName[tier])\n .filter(Boolean);\n\n // Semantic recall: pull in long-term memory + past messages relevant to this turn.\n // Skip messages from the current thread that are already in the windowed history.\n // Capped at RECALL_BUDGET_MS — if the embedding round-trip is slower than\n // that the LLM stream starts without recall hits rather than letting the\n // user stare at an idle screen waiting on a network call.\n const oldestInWindow = history.length > 0 ? contentText(history[0].content) : null;\n const recallCtx = await raceWithBudget(\n buildRecallContext(thread_id, trimmed, oldestInWindow),\n RECALL_BUDGET_MS,\n \"\",\n );\n const adaptivePersonaCtx = buildAdaptivePersonaContext(agentCfg, trimmed);\n const harnessParts = resolveHarness(agentCfg);\n\n const systemParts = [\n agentCfg.identity,\n agentCfg.instructions,\n adaptivePersonaCtx,\n userCtx,\n integrationsCtx,\n harnessParts.capabilities,\n harnessParts.plan_first,\n harnessParts.presentation,\n harnessParts.citation,\n timeCtx,\n envCtx,\n harnessParts.self_config,\n experienceCtx,\n memoryCtx,\n ...tierOrderCtx,\n recallCtx,\n ].filter(Boolean);\n let allowedTools: string[] = [];\n try {\n allowedTools = JSON.parse(agentCfg.tools) as string[];\n } catch { /* keep empty */ }\n\n const streamOpts: StreamOptions = {\n ...options,\n agent_run_config: {\n system_prompt: systemParts.join(\"\\n\\n\"),\n allowed_tools: allowedTools,\n model_config_name: agentCfg.model_config_name ?? null,\n },\n };\n\n const rawStream = streamWithConfig(thread_id, history, streamOpts, signal);\n return {\n stream: stallRetryStream(rawStream, thread_id, options, signal, _stallRetriesLeft, allowedTools),\n thread_id,\n };\n}\n\nasync function buildWarmSummaryContext(\n allWindowMessages: readonly { role: string; content: string }[],\n hotCount: number,\n providerName: string | undefined,\n modelId: string | undefined,\n providerParams: ProviderParams,\n warmBudgetTokens: number,\n): Promise<string> {\n if (warmBudgetTokens <= 32) return \"\";\n if (!providerName || !modelId) return \"\";\n const warmMessages = allWindowMessages.slice(0, Math.max(0, allWindowMessages.length - hotCount));\n if (warmMessages.length < 2) return \"\";\n\n // Keep summary input bounded by the warm budget to avoid recursive prompt bloat.\n const summaryInputChars = Math.max(0, warmBudgetTokens * 4);\n const transcript = warmMessages\n .map((m) => `${m.role === \"user\" ? \"User\" : \"Assistant\"}: ${transcriptText(m.content)}`)\n .join(\"\\n\\n\")\n .slice(-summaryInputChars);\n if (!transcript.trim()) return \"\";\n\n try {\n const provider = getProvider(providerName);\n const summary = await summarizeTranscript(provider, modelId, providerParams, transcript);\n if (!summary) return \"\";\n return [\n \"--- Warm context summary ---\",\n \"Compressed recap of earlier messages outside the hot window:\",\n summary,\n ].join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\nfunction buildFactsContext(query: string, factsBudgetTokens: number): string {\n if (factsBudgetTokens <= 16) return \"\";\n const charBudget = factsBudgetTokens * 4;\n const rows = listMemory(\"facts\", query.slice(0, 120), 12);\n if (rows.length === 0) return \"\";\n\n const lines = [\n \"--- Facts memory ---\",\n \"Durable fact entries from memory_store namespace=facts:\",\n ];\n let used = 0;\n for (const row of rows) {\n const line = `- ${row.key}: ${String(row.value).slice(0, 220)}`;\n if (used > 0 && used + line.length > charBudget) break;\n lines.push(line);\n used += line.length;\n }\n return lines.length > 2 ? lines.join(\"\\n\") : \"\";\n}\n\n// Wraps the raw agent stream with stall-retry logic. Chunks pass through\n// LIVE to the consumer (so the chat UI sees deltas as they arrive); we only\n// hold the terminal `done` chunk so we can decide whether to retry. If the\n// completed turn produced no tool calls AND the assistant text matches a\n// \"one moment\"-style stall pattern, we inject a forceful nudge as a\n// synthetic user message and forward the retry stream's chunks too. The\n// stalled prose stays visible (already streamed) and a \"↻\" separator marks\n// the boundary; the consumer's text/tool accumulator naturally captures\n// both halves into a single combined assistant message.\nasync function* stallRetryStream(\n inner: AsyncIterable<StreamChunk>,\n thread_id: string,\n options: StreamOptions | undefined,\n signal: AbortSignal | undefined,\n retriesLeft: number,\n allowedTools: readonly string[],\n): AsyncGenerator<StreamChunk> {\n // If no retry budget, just forward everything unchanged. The downstream\n // persistAssistantMessage will still tag a stall or fabrication with a\n // warning footer.\n if (retriesLeft <= 0) {\n for await (const chunk of inner) yield chunk;\n return;\n }\n\n let textBuf = \"\";\n const toolNames: string[] = [];\n let doneChunk: StreamChunk | null = null;\n let sawError = false;\n\n for await (const chunk of inner) {\n if (chunk.type === \"text_delta\") {\n const d = (chunk.data as { delta?: unknown } | undefined)?.delta;\n if (typeof d === \"string\") textBuf += d;\n yield chunk;\n } else if (chunk.type === \"tool_call\") {\n const name = (chunk.data as { name?: unknown } | undefined)?.name;\n if (typeof name === \"string\" && name) toolNames.push(name);\n yield chunk;\n } else if (chunk.type === \"done\") {\n // Hold the terminal marker — if we retry, the retry's `done` closes\n // the turn instead.\n doneChunk = chunk;\n break;\n } else if (chunk.type === \"error\") {\n sawError = true;\n yield chunk;\n return;\n } else {\n yield chunk;\n }\n }\n\n const stalled =\n !sawError &&\n toolNames.length === 0 &&\n textBuf.trim().length > 0 &&\n looksLikeStall(textBuf.trim());\n\n // Fabrication check (ADR-0037): only run when the stall path didn't claim\n // this turn — stall-retry already handles zero-tool stall-prose turns.\n const fabrication = !sawError && !stalled\n ? validateAssistantOutput(textBuf, toolNames, allowedTools)\n : ({ ok: true } as const);\n\n if (!stalled && fabrication.ok) {\n if (doneChunk) yield doneChunk;\n return;\n }\n\n // Visible separator between the stalled prose and the retry continuation,\n // so the user can see something is being re-attempted.\n yield { type: \"text_delta\", data: { delta: \"\\n\\n↻ \" } };\n\n // Inject a forceful nudge as a synthetic user message so the model sees\n // its own flagged reply + an instruction to continue. Stall and fabrication\n // get distinct, reason-aware nudges.\n const nudge = stalled\n ? \"\\u21bb Auto-retry: your previous reply ended with a 'one moment' style promise but you didn't call any tool, which ends the turn with nothing happening. Continue the original task NOW by invoking the appropriate tool. Do not acknowledge, do not apologize \\u2014 just call the tool.\"\n : `\\u21bb Auto-retry: output validator flagged your reply. ${\"reason\" in fabrication ? fabrication.reason : \"\"} Redo this turn without the false claim \\u2014 either call the actual tool, or rephrase as a proposal/question.`;\n\n const retry = await prepareThreadRun(\n thread_id,\n nudge,\n options,\n undefined,\n signal,\n retriesLeft - 1,\n );\n for await (const chunk of retry.stream) yield chunk;\n}\n\nexport function persistAssistantMessage(\n thread_id: string,\n content: string,\n usedTools?: readonly string[],\n toolEvents?: readonly PersistedToolEvent[],\n category: string | null = null,\n): void {\n const trimmed = content.trim();\n // Append a small, persistent footer listing which tools actually ran this\n // turn. Without this, tool_call events are live-only UI — after the stream\n // ends (or on page reload, or if a mobile client missed the brief render)\n // the assistant text remains saying \"I scheduled X\" with no proof a tool\n // ran, which reads as a hallucination even when the tool did execute.\n let final = trimmed;\n const toolList = usedTools ? Array.from(new Set(usedTools.filter(Boolean))) : [];\n // Stall detector: model ended its turn with a \"one moment\" / \"let me check\"\n // promise but invoked no tool. The system prompt forbids this, but models\n // occasionally do it anyway. Marking the message inline gives the user a\n // concrete next-step (\"type continue\") instead of staring at silence.\n if (toolList.length === 0 && trimmed && looksLikeStall(trimmed)) {\n final = `${trimmed}\\n\\n*⚠️ Agent stalled — promised a next step but did not invoke any tool. Reply \"continue\" to retry.*`;\n } else if (toolList.length > 0) {\n final = `${trimmed}\\n\\n*— used: ${toolList.join(\", \")}*`;\n }\n // Fabrication footer (ADR-0037): runs after the retry budget is exhausted\n // and a flagged reply still made it through. Look up allowed tools from\n // the agent config so callers don't have to thread it through.\n if (trimmed && !final.includes(\"*⚠️ Agent stalled\")) {\n const allowedTools = lookupAllowedToolsForThread(thread_id);\n const v = validateAssistantOutput(trimmed, toolList, allowedTools);\n if (!v.ok) {\n final = `${final}\\n\\n*⚠️ Output validator flagged: ${v.reason}*`;\n }\n }\n // Cap individual tool payloads so a single 64KB file_read result doesn't\n // make every reload of this thread re-download a giant blob. Keep the\n // first ~8KB — enough to be useful, small enough to be cheap.\n const sanitizedEvents = toolEvents && toolEvents.length > 0\n ? toolEvents.map(capToolEventPayload)\n : null;\n // Strip the `?autoplay=1` hint that generate_voice embeds in /api/v1/files\n // URLs before persistence. Autoplay is a transient signal for the live\n // streaming client only — reloading the thread, scrolling back, or opening\n // the conversation from another browser must not replay TTS clips the user\n // has already heard.\n const persisted = stripAutoplayHints(final);\n if (persisted || (sanitizedEvents && sanitizedEvents.length > 0)) {\n addMessage(thread_id, \"assistant\", persisted, sanitizedEvents, category);\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n recordToolUsage(sanitizedEvents, persisted);\n }\n }\n}\n\n// Removes `autoplay=1` from /api/v1/files/*.{wav,mp3,...} URLs that appear in\n// the assistant text. Handles it as the sole query param (`?autoplay=1`) or\n// combined with others (`?foo=bar&autoplay=1`, `?autoplay=1&foo=bar`).\nfunction stripAutoplayHints(text: string): string {\n if (!text || !text.includes(\"autoplay=1\")) return text;\n return text.replace(\n /(\\/api\\/v1\\/files\\/[^\\s)\"']+?\\.(?:wav|mp3|ogg|webm|m4a))(\\?[^\\s)\"']*)/gi,\n (_full, base: string, query: string) => {\n const cleaned = query\n .replace(/[?&]autoplay=1\\b/g, \"\")\n .replace(/^&/, \"?\");\n return cleaned === \"?\" || cleaned === \"\" ? base : `${base}${cleaned}`;\n },\n );\n}\n\nconst MAX_PERSISTED_PAYLOAD_BYTES = 8_000;\n\nfunction capToolEventPayload(ev: PersistedToolEvent): PersistedToolEvent {\n try {\n const serialized = JSON.stringify(ev.payload);\n if (serialized.length <= MAX_PERSISTED_PAYLOAD_BYTES) return ev;\n return {\n ...ev,\n payload: {\n __truncated: true,\n preview: serialized.slice(0, MAX_PERSISTED_PAYLOAD_BYTES),\n original_bytes: serialized.length,\n },\n };\n } catch {\n return { ...ev, payload: { __truncated: true, error: \"unserializable\" } };\n }\n}\n\nconst STALL_PATTERNS: RegExp[] = [\n /\\bone (moment|sec(?:ond)?)\\b/i,\n /\\bgive me (a|just a) (moment|sec(?:ond)?|minute)\\b/i,\n /\\bhold on\\b/i,\n /\\bjust a (moment|sec(?:ond)?|minute)\\b/i,\n /\\bbear with me\\b/i,\n /\\blet me (check|verify|continue|proceed|look|try|do (?:that|this|it))\\b/i,\n /\\bi['’]?ll (check|verify|continue|proceed|look|try|do (?:that|this|it)|keep going|get (?:on|right) (?:on|to))/i,\n /\\b(continuing|proceeding|working on it|moving on)\\b.*[!.]?\\s*$/i,\n];\n\n// Resolve the agent's allowed_tools list from a thread id. Best-effort: empty\n// list if the thread or agent config has gone away (the validator then\n// flags any `(via foo)` citation as unregistered, which is the safe default).\nfunction lookupAllowedToolsForThread(thread_id: string): string[] {\n try {\n const thread = getThread(thread_id);\n if (!thread) return [];\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) return [];\n const parsed = JSON.parse(agentCfg.tools) as unknown;\n return Array.isArray(parsed) ? parsed.filter((t): t is string => typeof t === \"string\") : [];\n } catch {\n return [];\n }\n}\n\nexport function looksLikeStall(text: string): boolean {\n // Inspect the last paragraph / sentence \\u2014 earlier acknowledgment\n // language is fine when followed by real work. The stall signal is when\n // the message ends on a promise.\n const tail = text.split(/\\n{2,}|(?<=[.!?])\\s+/).filter(Boolean).slice(-2).join(\" \");\n return STALL_PATTERNS.some((re) => re.test(tail));\n}\n\n// Run semantic recall on the user's turn, format the top hits as a system-prompt\n// block. Empty string when no embeddings configured or no good matches.\nasync function buildRecallContext(\n current_thread_id: string,\n query: string,\n windowOldestContent: string | null,\n): Promise<string> {\n if (!query.trim()) return \"\";\n let hits: RecalledMemory[];\n try {\n hits = await recall(query, 6);\n } catch {\n return \"\";\n }\n if (hits.length === 0) return \"\";\n\n // Drop matches that already live in the in-prompt history window.\n const filtered = hits.filter((h) => {\n if (h.source === \"message\" && h.thread_id === current_thread_id) {\n // crude but cheap: skip if it's the same content as anything in the window\n return windowOldestContent !== h.content;\n }\n return true;\n });\n if (filtered.length === 0) return \"\";\n\n const lines = [\n \"--- Your retrieved memory for this turn ---\",\n \"These entries were pulled from YOUR own memory store (not user-supplied just now).\",\n \"Treat them as facts you previously committed to remember. Cite them confidently when relevant.\",\n \"\",\n ];\n for (const h of filtered) {\n const stamp = h.created_at.slice(0, 10);\n if (h.source === \"memory\") {\n lines.push(`• [memory ${h.namespace}/${h.key}, ${stamp}] ${truncate(h.content, 280)}`);\n } else {\n const tag = h.thread_id === current_thread_id ? \"earlier this thread\" : \"past chat\";\n lines.push(`• [${tag} · ${h.role}, ${stamp}] ${truncate(h.content, 280)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction truncate(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length > max ? flat.slice(0, max) + \"…\" : flat;\n}\n\nexport function shouldEmitChunk(\n chunkType: StreamChunk[\"type\"],\n options?: StreamOptions,\n): boolean {\n const includeTools = options?.filters?.include_tools ?? true;\n const includeThinking = options?.filters?.include_thinking ?? true;\n if (!includeTools && (chunkType === \"tool_call\" || chunkType === \"tool_result\")) return false;\n if (!includeThinking && chunkType === \"thinking_delta\") return false;\n return true;\n}\n\nexport { contentText };\n","// ADR-0028. In-process script registry for ScriptFiring.\n//\n// Trust model: only built-ins are registered, in code, at module load\n// time. There is NO mechanism to register a script from DB, user input,\n// or shell-out — `script` on a ScriptFiring is just a key into this\n// map. This keeps scripted triggers safe even though they bypass the\n// LLM/thread machinery that gates prompt firings.\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface ScriptResult {\n /** Short, single-line summary suitable for telemetry / logs. */\n preview: string;\n}\n\nexport type ScriptFn = (args: Record<string, unknown>) => Promise<ScriptResult>;\n\ninterface ScriptRegistryState {\n scripts: Map<string, ScriptFn>;\n}\n\nconst state = getOrCreateGlobal<ScriptRegistryState>(\n \"__jarela_trigger_scripts\",\n () => ({ scripts: new Map() }),\n);\n\nexport function registerScript(name: string, fn: ScriptFn): void {\n // Idempotent re-registration is fine — HMR and repeated module imports\n // in dev re-execute the registration calls. We just overwrite with the\n // latest function, matching the trigger handler registry's behaviour.\n state.scripts.set(name, fn);\n}\n\nexport function getScript(name: string): ScriptFn | undefined {\n return state.scripts.get(name);\n}\n\nexport function listScripts(): string[] {\n return Array.from(state.scripts.keys()).sort();\n}\n\n// ADR-0031 — names beginning with this prefix are user-attachable\n// reaction scripts. Internal plumbing scripts (e.g.\n// `documents.reindex_local_file`) live under other namespaces and are\n// excluded so the watcher schedule surface can't accidentally invoke\n// them.\nexport const REACTION_SCRIPT_PREFIX = \"reaction.\";\n\nexport function listReactionScripts(): string[] {\n return listScripts().filter((n) => n.startsWith(REACTION_SCRIPT_PREFIX));\n}\n\nexport function isReactionScript(name: string): boolean {\n return name.startsWith(REACTION_SCRIPT_PREFIX) && state.scripts.has(name);\n}\n\n/** Test-only helper. */\nexport function __resetScriptRegistry(): void {\n state.scripts.clear();\n}\n","// Encrypted-at-rest secrets for external tools (ADR-0023).\n//\n// External tools declare secret \"slots\" in their module.exports:\n// secrets: [{ key: \"api_key\", label: \"OpenWeather API key\", required: true }]\n//\n// Values are persisted in the `tool-secrets` namespace of the memory store\n// (which is flagged sensitive in lib/crypto/sensitive.ts, so envelope\n// encryption applies — same primitive as the integrations store).\n//\n// Keys are stored as `<toolName>:<slotKey>`. Tool names and slot keys are\n// validated to a conservative character set so they can't collide with the\n// namespace delimiter or smuggle SQL/JSON metacharacters.\n//\n// Note on isolation: external tools run in-process with full Node privileges\n// (ADR-0013), so a malicious tool could read another tool's secrets by going\n// around this API (e.g. directly opening the SQLite file). The per-tool\n// scoping here is a *convention* surfaced through `ctx.getSecret`, not a\n// sandbox boundary.\n\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nconst NAMESPACE = \"tool-secrets\";\nconst NAME_RE = /^[a-z0-9_-]+$/i;\n\nexport interface ToolSecretSlot {\n key: string;\n label?: string;\n required?: boolean;\n description?: string;\n}\n\nfunction validName(s: string): boolean {\n return typeof s === \"string\" && s.length > 0 && s.length <= 64 && NAME_RE.test(s);\n}\n\nfunction compoundKey(toolName: string, key: string): string {\n return `${toolName}:${key}`;\n}\n\nfunction parseStored(raw: string): string | null {\n try {\n const v = JSON.parse(raw);\n return typeof v === \"string\" ? v : null;\n } catch {\n return null;\n }\n}\n\nexport function getToolSecret(toolName: string, key: string): string | null {\n if (!validName(toolName) || !validName(key)) return null;\n const row = getMemory(NAMESPACE, compoundKey(toolName, key));\n if (!row) return null;\n return parseStored(row.value);\n}\n\nexport function setToolSecret(toolName: string, key: string, value: string): void {\n if (!validName(toolName)) throw new Error(`invalid tool name: ${toolName}`);\n if (!validName(key)) throw new Error(`invalid secret key: ${key}`);\n if (typeof value !== \"string\") throw new Error(\"secret value must be a string\");\n putMemory(NAMESPACE, compoundKey(toolName, key), value);\n}\n\nexport function deleteToolSecret(toolName: string, key: string): boolean {\n if (!validName(toolName) || !validName(key)) return false;\n return deleteMemory(NAMESPACE, compoundKey(toolName, key));\n}\n\n// Returns which declared slots have a value persisted. Never returns the\n// plaintext — that only escapes via `ctx.getSecret` inside the tool's own\n// run loop.\nexport function describeToolSecrets(\n toolName: string,\n slots: ToolSecretSlot[],\n): Array<ToolSecretSlot & { is_set: boolean }> {\n if (!validName(toolName)) return slots.map((s) => ({ ...s, is_set: false }));\n return slots.map((s) => ({\n ...s,\n is_set: getToolSecret(toolName, s.key) !== null,\n }));\n}\n\n// Delete every persisted secret for a tool — used when an external tool\n// file is removed and the operator wants to clear stale credentials.\nexport function purgeToolSecrets(toolName: string): number {\n if (!validName(toolName)) return 0;\n const prefix = `${toolName}:`;\n const rows = listMemory(NAMESPACE, undefined, 1000).filter((r) =>\n r.key.startsWith(prefix),\n );\n let n = 0;\n for (const r of rows) {\n if (deleteMemory(NAMESPACE, r.key)) n++;\n }\n return n;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { embedOne } from \"@/lib/embeddings\";\n\nconst now = () => new Date().toISOString();\n\n// Explicit column list for message reads — omits `embedding` (~20KB of\n// JSON-encoded float[] per row) which only the embeddings module reads.\n// Avoids dragging it through the chat-history result set on every call.\nconst MSG_COLS_SQL = \"SELECT msg_id, thread_id, role, content, created_at, tool_events, category FROM messages\";\n\nexport interface ThreadRow {\n thread_id: string; agent_id: string; title: string | null;\n created_at: string; updated_at: string; message_count: number;\n}\nexport interface MessageRow {\n msg_id: string; thread_id: string; role: string; content: string; created_at: string;\n // JSON-encoded array of PersistedToolEvent. null when no tool work happened\n // on this turn or for user messages. Read back by the chat UI so historical\n // bubbles show the same expandable CALL/RESULT entries as live streaming.\n tool_events?: string | null;\n // Non-null tags classify the message into a filterable group in the chat\n // panel (e.g. 'scheduled_task', 'bridge', 'synthetic'). NULL = ordinary\n // user/assistant chat content.\n category?: string | null;\n}\n\nexport interface PersistedToolEvent {\n id: string;\n phase: \"call\" | \"result\";\n name: string;\n payload: unknown;\n}\n\nexport function listThreads(limit = 50, offset = 0): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads ORDER BY updated_at DESC LIMIT ? OFFSET ?\")\n .all(limit, offset) as unknown as ThreadRow[];\n}\n\nexport function listThreadsByAgent(agent_id: string, limit = 50): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? ORDER BY updated_at DESC LIMIT ?\")\n .all(agent_id, limit) as unknown as ThreadRow[];\n}\n\nexport function getThread(thread_id: string): ThreadRow | null {\n return (getDb().prepare(\"SELECT * FROM threads WHERE thread_id=?\").get(thread_id) as unknown as ThreadRow) ?? null;\n}\n\nexport function createThread(agent_id: string, title?: string): ThreadRow {\n const t = now();\n const thread_id = randomUUID();\n getDb()\n .prepare(\"INSERT INTO threads (thread_id,agent_id,title,created_at,updated_at,message_count) VALUES (?,?,?,?,?,0)\")\n .run(thread_id, agent_id, title ?? null, t, t);\n return { thread_id, agent_id, title: title ?? null, created_at: t, updated_at: t, message_count: 0 };\n}\n\nexport function deleteThread(thread_id: string): boolean {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(thread_id);\n const r = db.prepare(\"DELETE FROM threads WHERE thread_id=?\").run(thread_id);\n return r.changes > 0;\n}\n\nexport function getMessages(thread_id: string): MessageRow[] {\n return getDb()\n .prepare(MSG_COLS_SQL + \" WHERE thread_id=? ORDER BY created_at ASC\")\n .all(thread_id) as unknown as MessageRow[];\n}\n\n// Pull the latest N messages within a time window. Used to build the LLM\n// context — keeps prompt size bounded as threads grow indefinitely.\n// limit: 0 or negative = unlimited\n// sinceISO: undefined = no time bound\n// Returns chronological order (oldest first) so it can be appended to the prompt directly.\nexport function getRecentMessagesWindow(\n thread_id: string,\n limit: number,\n sinceISO?: string,\n): MessageRow[] {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (sinceISO) {\n sql += \" AND created_at >= ?\";\n params.push(sinceISO);\n }\n sql += \" ORDER BY created_at DESC\";\n if (limit > 0) {\n sql += \" LIMIT ?\";\n params.push(limit);\n }\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n return rows.reverse();\n}\n\n// Forward-fetch — return messages strictly newer than `afterISO`, oldest\n// first, capped at `limit`. Used by the chat view to pull only the\n// freshly-persisted user+assistant pair after a run completes, instead of\n// re-fetching the whole most-recent page.\nexport function getMessagesAfter(\n thread_id: string,\n afterISO: string,\n limit = 50,\n): MessageRow[] {\n return getDb()\n .prepare(\n MSG_COLS_SQL +\n \" WHERE thread_id=? AND created_at > ? ORDER BY created_at ASC LIMIT ?\",\n )\n .all(thread_id, afterISO, limit) as unknown as MessageRow[];\n}\n\n// Pagination for the chat UI. Returns the latest N messages strictly older\n// than `beforeISO` (cursor). Caller passes the oldest already-loaded message's\n// created_at as the cursor; first page omits beforeISO.\nexport function getMessagesPage(\n thread_id: string,\n limit: number,\n beforeISO?: string,\n): { messages: MessageRow[]; has_more: boolean } {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (beforeISO) {\n sql += \" AND created_at < ?\";\n params.push(beforeISO);\n }\n sql += \" ORDER BY created_at DESC LIMIT ?\";\n params.push(limit + 1); // fetch one extra to detect if there's more\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n const has_more = rows.length > limit;\n return { messages: rows.slice(0, limit).reverse(), has_more };\n}\n\nexport function addMessage(\n thread_id: string,\n role: \"user\" | \"assistant\",\n content: string,\n toolEvents?: PersistedToolEvent[] | null,\n category: string | null = null,\n): MessageRow {\n const msg_id = randomUUID();\n const t = now();\n const db = getDb();\n const toolEventsJson = toolEvents && toolEvents.length > 0 ? JSON.stringify(toolEvents) : null;\n db.prepare(\"INSERT INTO messages (msg_id,thread_id,role,content,created_at,tool_events,category) VALUES (?,?,?,?,?,?,?)\")\n .run(msg_id, thread_id, role, content, t, toolEventsJson, category);\n db.prepare(\"UPDATE threads SET message_count=message_count+1 WHERE thread_id=?\").run(thread_id);\n // Best-effort: embed the message so semantic recall can pull it back later.\n // Skip empty / very short content (greetings have no useful signal).\n if (content.trim().length >= 12) {\n embedOne(content).then((vec) => {\n if (vec) {\n getDb().prepare(\"UPDATE messages SET embedding=? WHERE msg_id=?\").run(JSON.stringify(vec), msg_id);\n }\n }).catch(() => { /* logged in embeddings module */ });\n }\n return { msg_id, thread_id, role, content, created_at: t, tool_events: toolEventsJson, category };\n}\n\nexport function getOrCreateAgentThread(agentId: string): ThreadRow {\n const existing = getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? LIMIT 1\")\n .get(agentId) as ThreadRow | undefined;\n if (existing) return existing;\n return createThread(agentId);\n}\n\nexport function clearThreadMessages(threadId: string): void {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(threadId);\n db.prepare(\"UPDATE threads SET message_count=0, updated_at=? WHERE thread_id=?\")\n .run(new Date().toISOString(), threadId);\n}\n\nexport function touchThread(thread_id: string, firstMsg?: string): void {\n const t = now();\n getDb()\n .prepare(\"UPDATE threads SET updated_at=?, title=COALESCE(title,?) WHERE thread_id=?\")\n .run(t, firstMsg ? firstMsg.slice(0, 80) : null, thread_id);\n}\n","// Shared reaction-discriminator helpers for the watcher (ADR-0031) and\n// scheduled-task (ADR-0032) stores. Both schemas use the same\n// `reaction_kind` / `reaction_script` / `reaction_script_args` triple, so\n// validation lives here and is imported by both.\n\nimport { isReactionScript, REACTION_SCRIPT_PREFIX } from \"@/lib/triggers/scripts\";\n\nexport type ReactionKind = \"agent_prompt\" | \"script\";\n\nconst MAX_REACTION_PROMPT_CHARS = 4000;\nconst MAX_REACTION_SCRIPT_ARGS_CHARS = 4000;\n\n/**\n * Normalise a reaction-prompt input into the value we store. Treats\n * undefined / null / whitespace-only as \"no override\" → NULL. Throws when\n * the prompt exceeds 4000 characters (the firing-prompt budget).\n */\nexport function normaliseReactionPrompt(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"string\") {\n throw new Error(\"reaction_prompt must be a string\");\n }\n const trimmed = input.trim();\n if (!trimmed) return null;\n if (trimmed.length > MAX_REACTION_PROMPT_CHARS) {\n throw new Error(\n `reaction_prompt must be <= ${MAX_REACTION_PROMPT_CHARS} characters (got ${trimmed.length})`,\n );\n }\n return trimmed;\n}\n\n/**\n * Validate a reaction-script name: must start with the `reaction.` prefix\n * AND be registered in the in-process script registry. Validated at write\n * time so a bad name is rejected by the agent tool / HTTP route, not by\n * the scheduler tick.\n */\nexport function validateReactionScript(name: unknown): string {\n if (typeof name !== \"string\" || !name.trim()) {\n throw new Error(\"reaction_script must be a non-empty string\");\n }\n const trimmed = name.trim();\n if (!trimmed.startsWith(REACTION_SCRIPT_PREFIX)) {\n throw new Error(\n `reaction_script must begin with \"${REACTION_SCRIPT_PREFIX}\" — got \"${trimmed}\"`,\n );\n }\n if (!isReactionScript(trimmed)) {\n throw new Error(`reaction_script \"${trimmed}\" is not registered`);\n }\n return trimmed;\n}\n\n/**\n * Normalise reaction-script args into a JSON-encoded string suitable for\n * the DB column. undefined / null → NULL. Anything else must be a plain\n * object that JSON-encodes to <= 4000 chars.\n */\nexport function normaliseReactionScriptArgs(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"reaction_script_args must be a JSON object\");\n }\n const json = JSON.stringify(input);\n if (json.length > MAX_REACTION_SCRIPT_ARGS_CHARS) {\n throw new Error(\n `reaction_script_args JSON must be <= ${MAX_REACTION_SCRIPT_ARGS_CHARS} chars (got ${json.length})`,\n );\n }\n return json;\n}\n\nexport interface ResolvedReaction {\n kind: ReactionKind;\n prompt: string | null;\n script: string | null;\n scriptArgs: string | null;\n}\n\n/**\n * Apply the discriminated-union rules for the reaction columns:\n * kind='script' → prompt forced NULL; script + scriptArgs validated.\n * kind='agent_prompt' → script + scriptArgs forced NULL; prompt normalised.\n * Centralised so create/update paths in both stores share one source of\n * truth for the union semantics.\n */\nexport function resolveReaction(input: {\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}): ResolvedReaction {\n const kind: ReactionKind = input.reaction_kind ?? \"agent_prompt\";\n if (kind === \"script\") {\n if (!input.reaction_script) {\n throw new Error(\"reaction_kind='script' requires reaction_script\");\n }\n return {\n kind,\n prompt: null,\n script: validateReactionScript(input.reaction_script),\n scriptArgs: normaliseReactionScriptArgs(input.reaction_script_args ?? null),\n };\n }\n return {\n kind,\n prompt: normaliseReactionPrompt(input.reaction_prompt),\n script: null,\n scriptArgs: null,\n };\n}\n","// Watcher store (ADR-0027). Sibling to lib/stores/scheduled-tasks.ts;\n// shape mirrors it so the UI + trigger plumbing can treat them as\n// near-equivalents apart from the diff-aware fields.\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n resolveReaction,\n validateReactionScript,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\n// Re-export so existing imports of these helpers from `@/lib/stores/watchers`\n// keep working (back-compat for tests + any historical call site).\nexport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n validateReactionScript,\n type ReactionKind,\n};\n\nexport interface WatcherRow {\n id: string;\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args: string; // JSON-encoded record passed to the tool\n interval_seconds: number;\n last_fingerprint: string | null;\n last_result: string | null; // stringified previous tool output, for the diff prompt\n last_run_at: string | null; // ISO — most recent poll, regardless of whether it fired\n last_fired_at: string | null; // ISO — most recent firing (i.e. fingerprint changed)\n last_error: string | null;\n next_run_at: string; // ISO\n enabled: number; // 0 | 1\n silent: number; // 0 | 1\n reaction_prompt: string | null; // ADR-0030: user-supplied directive; NULL = default\n reaction_kind: ReactionKind; // ADR-0031\n reaction_script: string | null; // ADR-0031: registry key when reaction_kind='script'\n reaction_script_args: string | null; // ADR-0031: JSON-encoded args bag\n created_at: string;\n updated_at: string;\n}\n\nconst MIN_INTERVAL_SECONDS = 60;\nconst now = () => new Date().toISOString();\n\nexport function clampInterval(seconds: number): number {\n if (!Number.isFinite(seconds)) throw new Error(\"interval_seconds must be a finite number\");\n const n = Math.floor(seconds);\n if (n < MIN_INTERVAL_SECONDS) {\n throw new Error(`interval_seconds must be >= ${MIN_INTERVAL_SECONDS}`);\n }\n return n;\n}\n\nexport interface CreateWatcherInput {\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args?: Record<string, unknown>;\n interval_seconds: number;\n silent?: boolean;\n // ADR-0030 / ADR-0031: only one reaction is active per watcher.\n // - kind 'agent_prompt' (default): reaction_prompt is the optional directive.\n // - kind 'script': reaction_script + reaction_script_args drive a script firing.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createWatcher(input: CreateWatcherInput): WatcherRow {\n const id = randomUUID();\n const t = now();\n const interval = clampInterval(input.interval_seconds);\n // Schedule the very first poll for `interval` seconds from now. The\n // agent-facing tool description tells the agent to call list_watchers\n // or wait one cycle; we don't fire immediately to avoid stampedes\n // when an agent registers a watcher.\n const next = new Date(Date.now() + interval * 1000).toISOString();\n const argsJson = JSON.stringify(input.tool_args ?? {});\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction(input);\n getDb()\n .prepare(\n `INSERT INTO watchers\n (id, agent_id, label, tool_name, tool_args, interval_seconds,\n last_fingerprint, last_result, last_run_at, last_fired_at, last_error,\n next_run_at, enabled, silent, reaction_prompt,\n reaction_kind, reaction_script, reaction_script_args,\n created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, NULL, NULL, NULL, NULL, NULL, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, input.label, input.tool_name, argsJson, interval, next, silent,\n reaction.prompt, reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n label: input.label,\n tool_name: input.tool_name,\n tool_args: argsJson,\n interval_seconds: interval,\n last_fingerprint: null,\n last_result: null,\n last_run_at: null,\n last_fired_at: null,\n last_error: null,\n next_run_at: next,\n enabled: 1,\n silent,\n reaction_prompt: reaction.prompt,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listWatchers(agentId?: string): WatcherRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM watchers WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM watchers ORDER BY next_run_at ASC\").all();\n return rows as unknown as WatcherRow[];\n}\n\nexport function getWatcher(id: string): WatcherRow | null {\n const row = getDb().prepare(\"SELECT * FROM watchers WHERE id=?\").get(id);\n return (row as WatcherRow | undefined) ?? null;\n}\n\nexport function getDueWatchers(asOf: Date = new Date()): WatcherRow[] {\n return getDb()\n .prepare(\"SELECT * FROM watchers WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as WatcherRow[];\n}\n\nexport function deleteWatcher(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM watchers WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateWatcherInput {\n label?: string;\n interval_seconds?: number;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0030 / ADR-0031: a PATCH may swap the reaction kind. The semantics\n // mirror the create input — if reaction_kind is provided, the reaction is\n // fully replaced (the other branch's fields are forced NULL). If\n // reaction_kind is absent, only the matching field for the EXISTING kind\n // can be updated. undefined leaves a field alone; null clears it.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function updateWatcher(id: string, patch: UpdateWatcherInput): WatcherRow | null {\n const existing = getWatcher(id);\n if (!existing) return null;\n const t = now();\n const interval = patch.interval_seconds !== undefined\n ? clampInterval(patch.interval_seconds)\n : existing.interval_seconds;\n // Only recompute next_run_at when the interval changed; otherwise keep\n // the existing schedule so a label edit doesn't reset the cycle.\n const nextRunAt = patch.interval_seconds !== undefined\n ? new Date(Date.now() + interval * 1000).toISOString()\n : existing.next_run_at;\n\n // Compute the reaction columns. Two cases:\n // 1. patch.reaction_kind is set → fully resolve the patch as a new reaction.\n // 2. patch.reaction_kind is absent → keep the existing kind, but allow the\n // matching branch's field to be patched (e.g. update reaction_prompt\n // while staying in 'agent_prompt' kind).\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: patch.reaction_prompt,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n const prompt = patch.reaction_prompt === undefined\n ? existing.reaction_prompt\n : normaliseReactionPrompt(patch.reaction_prompt);\n reaction = { kind: \"agent_prompt\", prompt, script: null, scriptArgs: null };\n }\n\n getDb()\n .prepare(\n `UPDATE watchers\n SET label=?, interval_seconds=?, next_run_at=?, enabled=?, silent=?,\n reaction_prompt=?, reaction_kind=?, reaction_script=?, reaction_script_args=?,\n updated_at=?\n WHERE id=?`,\n )\n .run(\n patch.label ?? existing.label,\n interval,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n reaction.prompt,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getWatcher(id);\n}\n\n// Bookkeeping after a poll. Always advances next_run_at. `fired`\n// indicates the fingerprint changed; when false we still update\n// last_run_at + last_fingerprint (first run, or unchanged).\nexport function recordWatcherPoll(input: {\n id: string;\n fingerprint: string;\n result: string;\n fired: boolean;\n error?: string;\n}): void {\n const existing = getWatcher(input.id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers\n SET last_fingerprint=?, last_result=?, last_run_at=?,\n last_fired_at=COALESCE(?, last_fired_at),\n last_error=?, next_run_at=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n input.fingerprint,\n input.result,\n t,\n input.fired ? t : null,\n input.error ?? null,\n nextRunAt,\n t,\n input.id,\n );\n}\n\nexport function recordWatcherPollError(id: string, error: string): void {\n const existing = getWatcher(id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?`,\n )\n .run(t, error, nextRunAt, t, id);\n}\n"],"names":["getOrCreateGlobal","state","handlers","Map","registerTriggerHandler","handler","set","kind","getTriggerHandler","get","listTriggerHandlers","Array","from","values","__resetTriggerRegistry","clear","getOrCreateAgentThread","getAgentConfig","prepareThreadRun","persistAssistantMessage","collectStream","getScript","runTriggerAgent","firing","agent","agentId","status","preview","threadId","error","thread","category","effectivePrompt","silent","prompt","prepared","thread_id","undefined","collected","stream","replyText","assistantContent","trim","isNoReply","test","skipAssistant","length","usedTools","toolEvents","replace","slice","err","msg","Error","message","String","runTriggerScript","fn","script","result","args","runTriggerFiring","mode","getDueTasks","markTaskRan","getScheduledTask","publish","publishNotification","SCHEDULED_TASK_KIND","buildFiring","task","reaction_kind","reaction_script","userArgs","reaction_script_args","parsed","JSON","parse","isArray","id","agent_id","description","schedule","schedule_kind","meta","scheduleKind","scheduledTaskHandler","getDueFirings","asOf","map","markFired","outcome","type","task_id","ts","Date","now","scriptName","firingForTaskId","taskId","createHash","getDueWatchers","getWatcher","recordWatcherPoll","recordWatcherPollError","registeredTools","truncateBytes","WATCHER_KIND","fingerprint","s","update","digest","stringifyResult","value","stringify","DEFAULT_REACTION_DIRECTIVE","MAX_DIFF_CONTEXT_BYTES","normalizeForDiff","raw","buildDiffForPrompt","previous","current","prev","split","curr","start","prevEnd","currEnd","removed","added","hunkHeader","Math","max","l","join","bytes","Buffer","byteLength","clipped","truncated","text","buildFiringPrompt","watcher","argsPretty","tool_args","directive","reaction_prompt","label","tool_name","buildScriptArgs","safeJson","invokeWatcherTool","entry","find","t","name","e","invoke","pollDueWatchers","due","firings","fp","firstRun","last_fingerprint","changed","fired","push","last_result","console","watcherHandler","firingForWatcherIdNow","promises","fs","relative","sep","getDb","getDocumentSource","registerScript","ALLOWED_EXT","MAX_FILE_BYTES","hashContent","lowerExt","readTextFile","upsertLocalDocument","reindexLocalFile","source","source_id","db","stat","abs","code","info","prepare","run","changes","isFile","size","has","hash","existing","content_hash","floor","mtimeMs","toISOString","f","rel","path","mtime_ms","registered","registerDocumentScripts","sourceId","watch","fsWatch","listEnabledDocumentSources","SKIP_DIRS","FS_WATCH_KIND","DEBOUNCE_MS","watchers","pending","unsupportedLogged","Set","pendingKey","enqueuePending","scheduleDebounce","w","debounceTimers","clearTimeout","setTimeout","delete","unref","handleEvent","filename","segments","filter","i","seg","startsWith","file","rootPath","attachWatcher","st","isDirectory","recursive","persistent","_event","toString","on","warn","add","detachWatcher","close","syncWatchers","sources","wantSourceIds","keys","drainPending","fsWatchHandler","sync","stop","_asOf","__resetFsWatchState","__pushEventForTest","markSourceScanned","isRemoteKind","runRemoteSource","DOCUMENT_FAST_SWEEP_KIND","DEFAULT_INTERVAL_MS","intervalMs","process","env","JARELA_FAST_REMOTE_SWEEP_MS","n","Number","parseInt","isFinite","lastRunAt","scriptRegistered","registerSweepScript","stats","updated","unchanged","errors","documentFastSweepHandler","getTime","interval","last","__resetFastSweepState","shortPreview","cur","left","right","ctx","title","registerHandlers","startAllTriggerHandlers","stopAllTriggerHandlers","notifyTriggerHandlers","_reason","runTriggerTick","innerErr","runScheduledTaskFiringNow","runWatcherFiringNow","watcherId","listScripts","listReactionScripts","isReactionScript","REACTION_SCRIPT_PREFIX","GEMINI_VOICES","GEMINI_TTS_MODELS","GEMINI_STT_MODELS","getConfig","resolveGoogleApiKey","resolveGoogleApiKeyShared","timeoutSignal","ENDPOINT","geminiTts","opts","url","encodeURIComponent","model","apiKey","style","spoken","speakers","voiceName","speechConfig","multiSpeakerVoiceConfig","speakerVoiceConfigs","speaker","voiceConfig","prebuiltVoiceConfig","body","contents","role","parts","generationConfig","responseModalities","res","fetch","method","headers","signal","voiceTimeoutMs","json","ok","candidates","content","p","inline","inlineData","inline_data","data","mime","mimeType","mime_type","pcm","rate","parseSampleRate","wav","pcmToWav","Boolean","geminiStt","audio","m","exec","sampleRate","channels","bitsPerSample","byteRate","blockAlign","dataSize","header","alloc","write","writeUInt32LE","writeUInt16LE","concat","embedOne","cosine","searchDocuments","query","limit","min","trimmed","limitRows","rows","all","qVec","scored","lowered","toLowerCase","r","score","match","embedding","vec","substringScore","document_id","source_label","rel_path","abs_path","chunk_index","sort","a","b","haystack","needleLower","hay","includes","tokens","hits","indexAllSources","POLL_INTERVAL_MS","JARELA_SCHEDULER_TICK_MS","DOC_SWEEP_EVERY_TICKS","started","timer","running","tickCount","startScheduler","setImmediate","tick","setInterval","stopScheduler","clearInterval","runScheduledTaskNow","transcriptText","media_type","summaryMessages","transcript","summarizeTranscript","provider","modelId","providerParams","chat","summary","chunk","existsSync","readdirSync","statSync","tool","getToolSecret","getToolsDir","toolsDir","isValidSlot","v","o","key","required","isValid","schema","secrets","every","loadExternalTools","builtinNames","tools","categories","files","createRequire","getBuiltinModule","req","entries","seen","mod","cache","resolve","candidate","default","def","wrapped","_runManager","config","configurable","getSecret","terminal","onChunk","delta","d","phase","payload","arguments","errorMessage","z","getMemory","putMemory","listMemory","registerTools","memoryReadTool","namespace","row","object","string","describe","memoryWriteTool","memoryListTool","search","updated_at","optional","number","createDocumentSource","deleteDocumentSource","getDocumentSourceByPath","listDocumentSources","indexOnDemand","documentsSearch","h","toFixed","int","documentsListSources","enabled","last_scan_at","documentsAddLocalSource","inputPath","note","REMOTE_KINDS","syntheticPath","space_key","cql","project_key","jql","owner","repo","validateRemoteConfig","cfg","documentsAddRemoteSource","enum","record","unknown","documentsRemoveSource","confirm","documentsReindexSource","documentsIndexUrl","input","execSync","getInjectedSubprocessEnv","MAX_OUTPUT_BYTES","DEFAULT_TIMEOUT_MS","MAX_TIMEOUT_MS","BLOCKED_PATTERNS","isBlockedCommand","command","some","pattern","clipOutput","runLocalCommand","options","exit_code","stderr","timeout","timeout_ms","allow_unsafe","cwd","output","encoding","maxBuffer","stdio","stdout","out","errText","execSchema","boolean","localExecTool","shellExecTool","os","MAX_READ_BYTES","MAX_WRITE_BYTES","MAX_LIST_JSON_BYTES","clip","resolvePath","homedir","isAbsolute","isInside","parent","sensitiveBase","home","sensitiveFiles","jarelaDataDir","JARELA_DB_DIR","assertSafePath","op","JARELA_ALLOW_SENSITIVE_FILES","base","basename","endsWith","readSchema","start_line","end_line","fileReadTool","filePath","readFile","lineRange","lines","end","line_range","total_lines","writeSchema","create_dirs","fileWriteTool","mkdir","dirname","existed","access","writeFile","bytes_written","created","editSchema","old_string","new_string","fileEditTool","first","indexOf","second","match_count","next","bytes_before","bytes_after","moveSchema","destination","overwrite","fileMoveTool","srcAbs","dstAbs","srcStat","dstStat","rename","cp","force","errorOnExist","rm","cross_device","err2","listSchema","max_entries","include_hidden","fileListTool","dirPath","cap","items","readdir","withFileTypes","localeCompare","it","full","build","es","droppedForSize","count","total_in_dir_after_filters","truncated_hint","dropped_for_size","filters","lo","hi","mid","mkdirSchema","fileMkdirTool","deleteSchema","fileDeleteTool","targetPath","rmdir","unlink","copySchema","fileCopyTool","copyFile","statSchema","fileStatTool","exists","modified_ms","created_ms","birthtimeMs","tavilySearch","api_key","max_results","search_depth","results","snippet","UA_POOL","ddgSearch","lastStatus","attempt","ua","html","parseDDGHtml","Promise","blockRe","block","titleMatch","snippetMatch","unwrapDDGRedirect","decodeHTML","stripTags","href","u","URL","hostname","pathname","real","searchParams","decodeURIComponent","webSearchTool","tavilyKey","TAVILY_API_KEY","total","dns","net","ipv4InCidr","addr","prefix","bits","mask","ipv4ToNumber","ip","part","isInteger","classifyIPv4","classifyIPv6","bare","v4","isIPv4","classifyAddress","isIPv6","isPrivateAddress","cls","checkPublicUrl","rawUrl","JARELA_ALLOW_PRIVATE_FETCH","allowed","reason","protocol","host","isIP","resolved","addrs","lookup","address","stripHtml","MAX_BYTES","TIMEOUT_MS","MAX_REDIRECTS","extractTitle","extractImages","baseUrl","og","twitter","samples","matchAll","src","resolveUrl","webFetchTool","max_chars","ctrl","AbortController","abort","initialCheck","currentUrl","hop","redirect","loc","hopCheck","contentType","finalUrl","reader","getReader","decoder","TextDecoder","bytesRead","done","read","decode","cancel","wantHtml","images","content_type","bytes_read","getUserProfile","getUserLocationTool","profile","location_consent","available","how_to_enable","location_lat","location_lng","updatedAt","location_updated_at","ageMs","lat","lng","accuracy_m","location_accuracy_m","location_label","age_seconds","round","randomUUID","writeBinaryFile","DEFAULT_MODEL","callGemini","imageTimeoutMs","describeError","callImagen","aspect","instances","parameters","sampleCount","aspectRatio","preds","predictions","bytesBase64Encoded","cause","extForMime","generateImageTool","aspect_ratio","saved","img","markdown","hint","getThread","DEFAULT_VOICE","MAX_TEXT_CHARS","SpeakerSchema","voice_name","resolveAgentVoice","voice","voice_model","generateVoiceTool","autoplay","speakerList","array","createScheduledTask","listScheduledTasks","deleteScheduledTask","computeNextRun","agentIdFromConfig","scheduleTaskTool","when_iso","cron","next_run_at","listScheduledTasksTool","_args","tasks","last_run_at","last_error","cancelScheduledTaskTool","createWatcher","listWatchers","deleteWatcher","scheduleWatcherTool","toolName","every_seconds","target","interval_seconds","listReactionScriptsTool","scripts","listWatchersTool","safeParse","last_fired_at","cancelWatcherTool","createPendingAction","getPendingAction","proposeConfigChangeTool","proposal_id","checkProposalTool","created_at","decided_at","getManifest","listManifests","getIntegrationStatus","isKnownIntegration","manifestStatus","configured","listIntegrationsTool","integrations","getIntegrationSetupTool","manifest","prerequisites","steps","troubleshooting","notes","googleFetch","resolveGoogleAuth","CALENDAR_BASE","calendarFetch","auth","init","slimEvent","location","dateTime","date","time_zone","timeZone","attendees","email","displayName","response","responseStatus","meet_link","hangoutLink","html_link","htmlLink","calendarListCalendarsTool","calendars","c","primary","access_role","accessRole","calendarListEventsTool","calendar_id","time_min","time_max","cal","params","URLSearchParams","singleEvents","orderBy","maxResults","inAWeek","events","calendarGetEventTool","event_id","eid","calendarCreateEventTool","start_iso","end_iso","add_meet_link","conferenceData","createRequest","requestId","random","conferenceSolutionKey","calendarUpdateEventTool","patch","Object","calendarDeleteEventTool","graphFetch","resolveMicrosoftAuth","subject","bodyPreview","emailAddress","is_all_day","isAllDay","is_cancelled","isCancelled","show_as","showAs","teams_link","onlineMeeting","joinUrl","web_link","webLink","outlookCalendarListCalendarsTool","is_default","isDefaultCalendar","can_edit","canEdit","outlookCalendarListEventsTool","startISO","endISO","top","startDateTime","endDateTime","$top","$orderby","Prefer","outlookCalendarGetEventTool","outlookCalendarCreateEventTool","add_teams_link","tz","isOnlineMeeting","onlineMeetingProvider","outlookCalendarUpdateEventTool","outlookCalendarDeleteEventTool","convertToOpenAITool","registeredNames","registeredCategory","registeredGroup","getMcpTools","disabledCategories","ALL_BUILTINS","BUILTIN_TOOL_NAMES","loadExternal","getToolCategory","builtin","ext","getToolGroup","cat","applyPolicy","policy","allowSet","allow","denySet","deny","applyCategoryToggles","disabled","getAllTools","getAllToolsAsync","mcpTools","toOpenAITools","oai","function","executeTool","context","x","_initialized","initTools","builtinCount","externalCount","UPSERT_SQL","recordToolUsage","deltas","summarizeToolUsage","stamp","stmt","calls","successes","used","listToolStats","getToolStatsMap","names","toStats","defaultToolStats","call_count","success_count","error_count","used_count","success_rate","usefulness_rate","never_used","last_called_at","successRate","clamp01","usefulnessRate","byId","assistantTerms","normalizeText","ev","successful","isErrorPayload","payloadLooksUsed","totals","extractPayloadTerms","matched","term","stringifyPayload","unique","token","mkdirSync","writeFileSync","getDataDir","FILES_DIR","SAFE_NAME","isSafeFileName","fileAbsPath","isCategoryEnabled","listCategoryStates","setCategoryEnabled","getIntegrationRaw","ms","fromStore","GEMINI_API_KEY","GOOGLE_API_KEY","isUserPreset","upsertUserProfile","icon","about","setLocationConsent","consent","updateUserLocation","setUserPreset","preset","getAppName","getAppDescription","getAppIssueUrl","DEFAULTS","port","recursionLimit","parsePositiveInt","fallback","parsePort","cached","expandHome","dataDir","JARELA_PORT","PORT","JARELA_HOSTNAME","HOSTNAME","JARELA_TOOLS_DIR","JARELA_RECURSION_LIMIT","JARELA_VOICE_TIMEOUT_MS","JARELA_IMAGE_TIMEOUT_MS","appName","appDescription","issueUrl","resetConfigCache","CronExpressionParser","resolveReaction","validateReactionScript","normaliseReactionScriptArgs","after","isNaN","currentDate","toDate","reaction","scriptArgs","updateScheduledTask","nextKind","nextSchedule","nextRunAt","nextPrompt","nextRun","BaseChatModel","AIMessage","AIMessageChunk","isAIMessage","isHumanMessage","isSystemMessage","isToolMessage","ChatGenerationChunk","JarelaChatModel","fields","lc_namespace","lc_serializable","_provider","_modelId","_params","_boundTools","boundTools","_llmType","bindTools","_kwargs","_convertedTools","flatMap","_generate","messages","_options","runManager","invokeMessages","toInvokeMessages","openaiTools","streamInvoke","finalChunk","_streamToFinalChunk","gen","aiMessageFromChunk","generations","aiMsg","tool_calls","tc","providerMessages","acc","_streamFromProvider","_streamResponseChunks","tool_call_chunks","index","emittedAny","stopReason","event","handleLLMNewToken","additional_kwargs","reasoning_content","args_delta","empty_stream_reason","stop_reason","invalid_tool_calls","lcContentToInvoke","image_url","dataUrl","ai","invokeMsg","reasoning","tool_call_id","BaseStore","deleteMemory","SqliteMemoryStore","batch","operations","ns","_raw","createdAt","namespacePrefix","DatabaseSync","BaseCheckpointSaver","TASKS","copyCheckpoint","maxChannelVersion","VALID_FILTER_KEYS","buildLatestSelect","includeCheckpointId","nv","NodeSqliteSaver","serde","isSetup","fromConnString","connStringOrLocalPath","setup","withoutCheckpoint","withCheckpoint","txn","decodeRowState","pendingWrites","pending_writes","channel","loadsTyped","checkpoint","parent_checkpoint_id","migratePendingSends","metadata","getTuple","checkpoint_ns","checkpoint_id","finalConfig","parentConfig","list","before","sql","whereClause","sanitizedFilter","fromEntries","put","preparedCheckpoint","type1","serializedCheckpoint","type2","serializedMetadata","dumpsTyped","putWrites","writes","idx","serializedWrite","deleteThread","parentCheckpointId","pendingSendsJson","pending_sends","mutable","channel_values","channel_versions","getNextVersion","CHECKPOINT_PATH","_saver","getCheckpointer","createReactAgent","HumanMessage","SystemMessage","ToolMessage","getProvider","getModelConfig","getDefaultModelConfig","toBaseMessages","systemPrompt","blocks","streamWithConfig","runCfg","agent_run_config","cfgName","model_config_name","toolPolicy","allowed_tools","tool_policy","model_id","store","checkpointer","llm","announcedToolIds","pendingAIChunk","totalOutputTokens","truncatedByLength","needsParagraphBreak","textEmittedSinceLastBreak","flushPendingToolCalls","agentStream","system_prompt","streamMode","baseMsg","stack","causeChain","depth","cMsg","cCode","rawMsg","aborted","message_id","usage","input_tokens","output_tokens","friendly","firstAppFrame","MBTI_PRESETS","buildAdaptivePersonaContext","userMessage","adaptive_persona_enabled","mbti","toMbti","adaptive_mbti","mbtiLabel","strength","clampPercent","adaptive_persona_strength","empathy","adaptive_empathy","expressiveness","adaptive_expressiveness","verbosity","adaptive_verbosity","detectSignals","intensity","targetEmpathy","frustration","urgency","positivity","targetExpressive","targetVerbosity","empathyBand","bandLabel","expressiveBand","verbosityBand","directives","mood","lower","frustrationHits","countMatches","urgencyHits","positivityHits","terms","cutoffs","labels","getDefaultHarnessId","getHarness","getBuiltinHarness","DEFAULT_HARNESS_ID","HARNESS_SECTION_KEYS","resolveHarness","agentCfg","harness_id","harness","section","sections","ACTION_VERBS","VERB_GROUP","PATTERNS","RegExp","FUTURE_PATTERNS","findActionClaims","re","lastIndex","verb","window","VIA_RE","findCitations","SUMMARY_PATTERNS","validateAssistantOutput","toolCalls","allowedTools","calledSet","allowedSet","citations","evidence","claims","DEFAULT_CONTEXT_WINDOW_TOKENS","DEFAULT_OVERHEAD_TOKENS","DEFAULT_OUTPUT_RESERVE_RATIO","DEFAULT_TIER_PRIORITY","DEFAULT_TIER_PROPORTIONS","hot","warm","facts","estimateTokens","ceil","normalizeTierPriority","tiers","normalizeTierProportions","toPositiveNumber","sum","computeContextBudget","contextWindowTokens","context_window_tokens","outputReserveTokens","max_tokens","overheadTokens","inputBudgetTokens","proportions","context_tier_proportions","tierPriority","context_tier_priority","tierBudgets","takeRecentMessagesWithinBudget","tokenBudget","chosen","reverse","truncateLargestMessagesWithinBudget","reduce","needed","nextTokens","nextChars","suffix","trimEnd","formatContextBudgetSummary","budget","addMessage","getRecentMessagesWindow","touchThread","recall","listIntegrations","APP_NAME","RunThreadError","RECALL_BUDGET_MS","raceWithBudget","promise","settled","then","MAX_STALL_AUTO_RETRIES","parseContent","contentText","attachments","_stallRetriesLeft","userCategory","stored","history_limit","windowHours","history_window_hours","sinceISO","allWindowMessages","modelCfg","hotMessages","userProfile","userCtxParts","ageSec","ageStr","userCtx","timeCtx","rawMode","ui_experience_mode","experienceMode","experienceCtx","envCtx","platform","arch","configuredIntegrations","integrationsCtx","memoryCtx","warmSummaryCtx","buildWarmSummaryContext","warmWasExpected","hotMessagesForPrompt","history","factsCtx","buildFactsContext","tierCtxByName","tierOrderCtx","tier","oldestInWindow","recallCtx","buildRecallContext","adaptivePersonaCtx","harnessParts","systemParts","identity","instructions","capabilities","plan_first","presentation","citation","self_config","streamOpts","rawStream","stallRetryStream","hotCount","providerName","warmBudgetTokens","warmMessages","summaryInputChars","factsBudgetTokens","charBudget","line","inner","retriesLeft","textBuf","toolNames","doneChunk","sawError","stalled","looksLikeStall","fabrication","nudge","retry","final","toolList","lookupAllowedToolsForThread","sanitizedEvents","capToolEventPayload","persisted","stripAutoplayHints","_full","cleaned","MAX_PERSISTED_PAYLOAD_BYTES","serialized","__truncated","original_bytes","STALL_PATTERNS","tail","current_thread_id","windowOldestContent","filtered","truncate","tag","flat","shouldEmitChunk","chunkType","includeTools","include_tools","includeThinking","include_thinking","__resetScriptRegistry","NAMESPACE","NAME_RE","validName","compoundKey","parseStored","setToolSecret","deleteToolSecret","describeToolSecrets","slots","is_set","purgeToolSecrets","MSG_COLS_SQL","listThreads","offset","listThreadsByAgent","createThread","message_count","getMessages","getMessagesAfter","afterISO","getMessagesPage","beforeISO","has_more","msg_id","toolEventsJson","catch","tool_events","clearThreadMessages","firstMsg","MAX_REACTION_PROMPT_CHARS","MAX_REACTION_SCRIPT_ARGS_CHARS","normaliseReactionPrompt","MIN_INTERVAL_SECONDS","clampInterval","seconds","argsJson","updateWatcher"],"sourceRoot":"","ignoreList":[]}