@circuitwall/jarela 1.2.0 → 1.3.0
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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +218 -7
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/events/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js +8 -1
- package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js +8 -1
- package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js +8 -1
- package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js +8 -1
- package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/tools/route.js +2 -2
- package/.next/standalone/.next/server/app/page.js +0 -16
- package/.next/standalone/.next/server/app/page.js.map +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/210.js +1 -1
- package/.next/standalone/.next/server/chunks/239.js +5335 -5230
- package/.next/standalone/.next/server/chunks/239.js.map +1 -1
- package/.next/standalone/.next/server/chunks/{1683.js → 241.js} +210 -36
- package/.next/standalone/.next/server/chunks/241.js.map +1 -0
- package/.next/standalone/.next/server/chunks/{8135.js → 2539.js} +218 -36
- package/.next/standalone/.next/server/chunks/2539.js.map +1 -0
- package/.next/standalone/.next/server/chunks/4631.js +218 -7
- package/.next/standalone/.next/server/chunks/4631.js.map +1 -1
- package/.next/standalone/.next/server/chunks/8866.js +13389 -13073
- package/.next/standalone/.next/server/chunks/8866.js.map +1 -1
- package/.next/standalone/.next/server/chunks/9032.js +1 -1
- package/.next/standalone/.next/server/chunks/9032.js.map +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/app/{page-62e0d5f2404b403b.js → page-2ab710949b62a638.js} +1 -17
- package/.next/standalone/.next/static/chunks/app/page-2ab710949b62a638.js.map +1 -0
- package/.next/standalone/package.json +1 -1
- package/CHANGELOG.md +74 -0
- package/components/ui/BootScreen.tsx +0 -10
- package/lib/agents/agent-turn.ts +9 -0
- package/lib/agents/prepare/request.ts +9 -0
- package/lib/agents/run-thread.ts +9 -1
- package/lib/api/extension-turn.ts +7 -0
- package/lib/bridges/attachment-store.test.ts +440 -0
- package/lib/bridges/attachment-store.ts +184 -0
- package/lib/bridges/whatsapp.ts +50 -32
- package/lib/tools/async-results-tool.ts +114 -0
- package/lib/tools/async-results.test.ts +481 -0
- package/lib/tools/async-results.ts +165 -0
- package/lib/tools/builtins.ts +1 -0
- package/lib/tools/wallclock.ts +114 -8
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/1683.js.map +0 -1
- package/.next/standalone/.next/server/chunks/8135.js.map +0 -1
- package/.next/standalone/.next/static/chunks/app/page-62e0d5f2404b403b.js.map +0 -1
- /package/.next/standalone/.next/static/{2xWP8843jbntFGKLnHK6R → ZKy7LJ3KXj2TIyKOg_fBH}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{2xWP8843jbntFGKLnHK6R → ZKy7LJ3KXj2TIyKOg_fBH}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"239.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/agents/run-queue.ts","webpack://@circuitwall/jarela/./lib/voice/constants.ts","webpack://@circuitwall/jarela/./lib/voice/gemini.ts","webpack://@circuitwall/jarela/./lib/providers/jarela-chat-model.ts","webpack://@circuitwall/jarela/./lib/stores/langgraph-store.ts","webpack://@circuitwall/jarela/./lib/agents/llm.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/adaptive-persona.ts","webpack://@circuitwall/jarela/./lib/agents/harness/resolve.ts","webpack://@circuitwall/jarela/./lib/agents/context-budget.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/system-prompt.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/history-window.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/index.ts","webpack://@circuitwall/jarela/./lib/stores/known-rates.ts","webpack://@circuitwall/jarela/./lib/stores/pricing.ts","webpack://@circuitwall/jarela/./lib/agents/hallucination-classifier.ts","webpack://@circuitwall/jarela/./lib/agents/citation-checker.ts","webpack://@circuitwall/jarela/./lib/agents/run-thread.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/safety.ts","webpack://@circuitwall/jarela/./lib/tools/workspace-context.ts","webpack://@circuitwall/jarela/./lib/tools/exec.ts","webpack://@circuitwall/jarela/./lib/tools/files.ts","webpack://@circuitwall/jarela/./lib/tools/files-search.ts","webpack://@circuitwall/jarela/./lib/tools/workspace.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/delegate.ts","webpack://@circuitwall/jarela/./lib/tools/system_config.ts","webpack://@circuitwall/jarela/./lib/tools/list-tools.ts","webpack://@circuitwall/jarela/./lib/tools/providers-info.ts","webpack://@circuitwall/jarela/./lib/tools/mcp-servers-info.ts","webpack://@circuitwall/jarela/./lib/tools/extension-surfaces.ts","webpack://@circuitwall/jarela/./lib/tools/builtins.ts","webpack://@circuitwall/jarela/./lib/tools/index.ts","webpack://@circuitwall/jarela/./lib/providers/known-context-windows.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/agents/agent-turn.ts","webpack://@circuitwall/jarela/./lib/utils/google-api.ts","webpack://@circuitwall/jarela/./lib/stores/user-profile.ts","webpack://@circuitwall/jarela/./lib/agents/run-registry.ts","webpack://@circuitwall/jarela/./lib/agents/turn-profile.ts","webpack://@circuitwall/jarela/./lib/stores/scheduled-tasks.ts","webpack://@circuitwall/jarela/./lib/triggers/scripts.ts","webpack://@circuitwall/jarela/./lib/stores/tool-secrets.ts","webpack://@circuitwall/jarela/./lib/health/runner.ts","webpack://@circuitwall/jarela/./lib/env/overrides.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 { runAgentTurn } from \"@/lib/agents/agent-turn\";\nimport { QueueFullError } from \"@/lib/agents/run-queue\";\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 result = await runAgentTurn({\n thread_id: thread.thread_id,\n queue_source: \"trigger\",\n message: effectivePrompt,\n user_category: category,\n assistant_category: category,\n silent: firing.silent === true,\n });\n return {\n status: result.skippedAssistant ? \"skipped\" : \"done\",\n preview: result.preview,\n threadId: thread.thread_id,\n };\n } catch (err) {\n const msg = err instanceof Error\n ? (err instanceof QueueFullError ? `queue full: ${err.message}` : err.message)\n : 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","// Per-thread FIFO queue for agent runs.\n//\n// Every entry point that drives an agent on a thread (HTTP POST, scheduler,\n// watcher, trigger, bridge) wraps its work with `enqueueThreadRun`. The\n// queue serialises execution per `thread_id`: a second job for the same\n// thread waits for the first to settle before starting. Different threads\n// stay parallel.\n//\n// Why: a single thread_id is shared across the chat UI, every bridge chat\n// routed to the same agent, every watcher fire, and every scheduled task\n// for that agent (one-thread-per-agent invariant). LangGraph's SQLite\n// checkpoint store is DB-level locked, not per-thread, so two concurrent\n// `agent.stream()` calls on the same thread_id will both read the same\n// checkpoint, both write, and the later write clobbers the earlier — one\n// turn's state can land in another turn's history. Serialising at this\n// layer is the cheapest fix.\n//\n// In-memory + single-process. Multi-instance deployment would need a\n// shared lock (Redis, Postgres advisory locks) — explicitly out of scope.\n// A process crash drops the in-flight head and discards every queued job\n// without ever invoking the runner: same blast radius as today's stranded\n// `running` registry entries.\n\ntype Source = \"user\" | \"scheduler\" | \"watcher\" | \"trigger\" | \"bridge\" | \"extension\" | \"delegate\";\n\n// Per-thread chain tail. Each enqueue chains onto the previous tail; the\n// new promise becomes the tail. When the tail settles AND no one chained\n// onto it in the meantime, the entry is removed to keep the map bounded.\nconst tails = new Map<string, Promise<unknown>>();\n\n// Per-thread depth counter. Bumped on enqueue, decremented when the job\n// settles. Used for queue_position reporting and the overflow guard.\nconst depths = new Map<string, number>();\n\nconst DEFAULT_MAX_DEPTH = 16;\n\nexport interface EnqueueOptions {\n /** Soft cap on per-thread queue depth. Returning above this throws a\n * `QueueFullError` so the caller can drop the fire instead of pinning\n * it in memory. Default 16. */\n maxDepth?: number;\n}\n\nexport interface EnqueueResult<T> {\n /** Promise that resolves when this job's runner completes. Awaiting\n * this is what blocks bridge/trigger callers until they have the\n * assistant content to reply / persist. The HTTP route can fire-and-\n * forget. */\n result: Promise<T>;\n /** 0-indexed slot at enqueue time. 0 means \"running now\" (no jobs\n * ahead), N means \"waiting behind N jobs\". Snapshot only — drains\n * monotonically as preceding jobs finish but we don't surface\n * progress updates. */\n position: number;\n}\n\nexport class QueueFullError extends Error {\n constructor(thread_id: string, depth: number) {\n super(`Per-thread run queue full for thread ${thread_id} (depth=${depth})`);\n this.name = \"QueueFullError\";\n }\n}\n\nexport function enqueueThreadRun<T>(\n thread_id: string,\n _source: Source,\n runner: () => Promise<T>,\n options: EnqueueOptions = {},\n): EnqueueResult<T> {\n const max = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n const currentDepth = depths.get(thread_id) ?? 0;\n if (currentDepth >= max) {\n throw new QueueFullError(thread_id, currentDepth);\n }\n const position = currentDepth;\n depths.set(thread_id, currentDepth + 1);\n\n // Chain onto the existing tail. Both fulfilled and rejected branches\n // run the new runner — one job's failure must not skip the next.\n const prev = tails.get(thread_id) ?? Promise.resolve();\n const next: Promise<T> = prev.then(() => runner(), () => runner());\n\n tails.set(thread_id, next);\n // Side-channel cleanup. `.finally` propagates the rejection, so absorb\n // it with a no-op `.catch` — the real rejection is still surfaced to\n // the caller via the returned `result` promise.\n next.finally(() => {\n const d = depths.get(thread_id) ?? 0;\n if (d <= 1) depths.delete(thread_id);\n else depths.set(thread_id, d - 1);\n if (tails.get(thread_id) === next) tails.delete(thread_id);\n }).catch(() => { /* handled by caller via result */ });\n\n return { result: next, position };\n}\n\n/** Current queue depth for a thread, including the running head. 0 means\n * no in-flight or pending work. Useful for diagnostics and tests. */\nexport function getQueueDepth(thread_id: string): number {\n return depths.get(thread_id) ?? 0;\n}\n\n/** Reset all queue state. Test-only — never call from production code. */\nexport function __resetForTests(): void {\n tails.clear();\n depths.clear();\n}\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","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 } else if (event.type === \"usage\") {\n // ADR-0041: surface real provider token counts on the final\n // AIMessageChunk via LangChain's standard `usage_metadata` field so\n // the agent loop can snapshot them into message_usage. PR #181 added\n // Anthropic prompt caching; carry the cache breakdown through\n // `input_token_details` (LangChain's standard channel) so cost\n // attribution downstream can apply the 1.25× / 0.1× rates.\n emittedAny = true;\n const cacheCreation = event.cache_creation_input_tokens ?? 0;\n const cacheRead = event.cache_read_input_tokens ?? 0;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n usage_metadata: {\n input_tokens: event.input_tokens ?? 0,\n output_tokens: event.output_tokens ?? 0,\n total_tokens: event.total_tokens\n ?? (event.input_tokens ?? 0) + (event.output_tokens ?? 0),\n ...(cacheCreation > 0 || cacheRead > 0\n ? { input_token_details: { cache_creation: cacheCreation, cache_read: cacheRead } }\n : {}),\n },\n }),\n text: \"\",\n });\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 { 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, getModelParams, upsertModelConfig } 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 const params: ProviderParams = getModelParams(cfg);\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 // ADR-0041: accumulate real per-call provider usage across the react loop\n // so the `done` chunk can carry authoritative token counts for snapshot.\n // Each LLM call inside the multi-step loop yields its own usage chunk via\n // JarelaChatModel; we sum them so the final figure covers the whole turn.\n let usageInputTokens = 0;\n let usageOutputTokens = 0;\n // PR #181 + cache-fidelity follow-up: Anthropic prompt-cache reads/writes\n // arrive as a separate breakdown via `input_token_details`. Sum them\n // independently so the dashboard can report cost correctly (cache reads\n // are 10× cheaper, cache writes 1.25× more expensive than fresh input).\n let usageCacheCreationTokens = 0;\n let usageCacheReadTokens = 0;\n let sawUsage = false;\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: {\n thread_id: threadId,\n delegation_depth: runCfg?.delegation?.depth ?? 0,\n delegation_ancestors: runCfg?.delegation?.ancestors ?? [],\n },\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 // ADR-0041: capture provider-reported token usage when present.\n const usage = chunk.usage_metadata;\n if (usage && (usage.input_tokens > 0 || usage.output_tokens > 0)) {\n usageInputTokens += usage.input_tokens ?? 0;\n usageOutputTokens += usage.output_tokens ?? 0;\n const details = usage.input_token_details;\n if (details) {\n usageCacheCreationTokens += details.cache_creation ?? 0;\n usageCacheReadTokens += details.cache_read ?? 0;\n }\n sawUsage = true;\n }\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: sawUsage\n ? {\n input_tokens: usageInputTokens,\n output_tokens: usageOutputTokens,\n cache_creation_input_tokens: usageCacheCreationTokens,\n cache_read_input_tokens: usageCacheReadTokens,\n source: \"provider\",\n }\n : { input_tokens: 0, output_tokens: totalOutputTokens, source: \"estimate\" },\n provider: cfg.provider,\n model_id: cfg.model_id,\n model_config_name: cfg.name,\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 (isContextOverflowError(rawMsg)) {\n // Hit the model's input window. Either the assumed/known context size\n // is bigger than what the provider actually serves on this tier, the\n // user's plan is throttled, or the conversation legitimately overflowed.\n // Either way the budget calculator's assumption was optimistic — tell\n // the user how to recover instead of dumping the provider stack.\n const observed = parseContextLimitFromError(rawMsg);\n if (observed && observed.limit > 0) {\n // Self-correct: persist the provider-reported limit back to the\n // model config so the next turn's budget calculator uses it. We\n // shrink by 10% as a safety margin (tokenisers disagree and tool\n // results we don't yet count add overhead). Only writes when the\n // new value is smaller than what's stored — never grows blindly.\n try {\n const current = typeof params.context_window_tokens === \"number\"\n ? params.context_window_tokens\n : Number.POSITIVE_INFINITY;\n const corrected = Math.max(2048, Math.floor(observed.limit * 0.9));\n if (corrected < current) {\n const nextParams = { ...params, context_window_tokens: corrected };\n upsertModelConfig(cfg.name, cfg.provider, cfg.model_id, nextParams, cfg.is_default === 1);\n console.warn(\n `[llm] context-window self-correct for ${cfg.name} (${cfg.provider}/${cfg.model_id}): ` +\n `provider reported ${observed.limit} tokens; persisted context_window_tokens=${corrected}`,\n );\n }\n } catch (persistErr) {\n console.error(\"[llm] failed to self-correct context_window_tokens\", persistErr);\n }\n friendly =\n `The request exceeded the model's context window (provider reported ~${observed.limit.toLocaleString()} tokens` +\n (observed.requested ? `, request had ~${observed.requested.toLocaleString()}` : \"\") +\n `). Persisted the corrected window on this model config; retry the turn or trim history.`;\n } else {\n friendly =\n \"The request exceeded the model's context window. \" +\n \"Trim history (lower `history_limit` / `history_window_hours` on the agent), \" +\n \"pin a smaller `context_window_tokens` in the model config so the budget calculator \" +\n \"leaves more headroom, or start a new thread.\";\n }\n code = \"context_length_exceeded\";\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: sawUsage\n ? {\n input_tokens: usageInputTokens,\n output_tokens: usageOutputTokens,\n cache_creation_input_tokens: usageCacheCreationTokens,\n cache_read_input_tokens: usageCacheReadTokens,\n source: \"provider\",\n }\n : { input_tokens: 0, output_tokens: totalOutputTokens, source: \"estimate\" },\n provider: cfg.provider,\n model_id: cfg.model_id,\n model_config_name: cfg.name,\n },\n };\n}\n\n// Detect provider error messages that indicate the request exceeded the\n// model's input/context window. Patterns sourced from OpenAI, Anthropic,\n// Gemini, DeepSeek, and the Copilot proxy.\nexport function isContextOverflowError(msg: string): boolean {\n if (!msg) return false;\n return (\n /context[_ ]length[_ ]exceeded/i.test(msg) ||\n /maximum context length/i.test(msg) ||\n /context window/i.test(msg) ||\n /prompt is too long/i.test(msg) ||\n /input(?:'s)? token count.*exceeds/i.test(msg) ||\n /exceeds the maximum number of tokens/i.test(msg) ||\n /request too large.*tokens/i.test(msg) ||\n /too many input tokens/i.test(msg) ||\n /string too long/i.test(msg)\n );\n}\n\n// Extract the model's actual context-window size (and, when present, the\n// request size) from a provider error message. Provider phrasings observed:\n// OpenAI: \"maximum context length is 128000 tokens. However, your\n// messages resulted in 213998 tokens\"\n// OpenAI: \"This model's maximum context length is 8192 tokens, however\n// you requested 9000 tokens\"\n// Anthropic: \"prompt is too long: 235812 tokens > 200000 maximum\"\n// Gemini: \"The input token count (1234567) exceeds the maximum number\n// of tokens allowed (1048576)\"\n// DeepSeek: \"Range of input length should be [1, 65536]\"\n// Returns null when no number pair can be confidently extracted.\nexport function parseContextLimitFromError(\n msg: string,\n): { limit: number; requested?: number } | null {\n if (!msg) return null;\n const num = (s: string) => parseInt(s.replace(/[,_\\s]/g, \"\"), 10);\n\n // OpenAI \"maximum context length is X tokens\" (+ optional \"resulted in Y\" / \"requested Y\")\n const openai = msg.match(\n /maximum context length is\\s+([\\d,_\\s]+)\\s*tokens?[\\s\\S]*?(?:resulted in|requested)\\s+([\\d,_\\s]+)/i,\n );\n if (openai) {\n const limit = num(openai[1]);\n const requested = num(openai[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n const openaiNoReq = msg.match(/maximum context length is\\s+([\\d,_\\s]+)/i);\n if (openaiNoReq) {\n const limit = num(openaiNoReq[1]);\n if (limit > 0) return { limit };\n }\n\n // Anthropic \"prompt is too long: N tokens > M maximum\"\n const anthropic = msg.match(/prompt is too long:\\s*([\\d,_\\s]+)\\s*tokens?\\s*>\\s*([\\d,_\\s]+)/i);\n if (anthropic) {\n const requested = num(anthropic[1]);\n const limit = num(anthropic[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n\n // Gemini \"input token count (N) exceeds the maximum number of tokens allowed (M)\"\n const gemini = msg.match(/input token count\\s*\\(([\\d,_\\s]+)\\)[\\s\\S]*?\\(([\\d,_\\s]+)\\)/i);\n if (gemini) {\n const requested = num(gemini[1]);\n const limit = num(gemini[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n\n // DeepSeek \"Range of input length should be [1, N]\"\n const deepseek = msg.match(/range of input length should be\\s*\\[\\s*\\d+\\s*,\\s*([\\d,_\\s]+)\\s*\\]/i);\n if (deepseek) {\n const limit = num(deepseek[1]);\n if (limit > 0) return { limit };\n }\n\n return null;\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 { 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 { 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\n/**\n * Roll unused tier headroom into the spill pool that the next tier in\n * priority order will draw from. Each tier receives `softCap + incomingSpill`\n * to spend; whatever it doesn't use becomes the next tier's `incomingSpill`.\n *\n * Pure: no allocation order is assumed — callers walk `tierPriority` and\n * decide the data-flow ordering separately.\n */\nexport function applyTierSpill(\n softCap: number,\n incomingSpill: number,\n used: number,\n): { cap: number; spill: number } {\n const cap = softCap + incomingSpill;\n return { cap, spill: Math.max(0, cap - used) };\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}","// System-prompt assembly. Pure function: given the resolved context\n// (agent config, history budget, recall hits, etc.), returns the joined\n// system-prompt string passed to the provider. Each context block is a\n// file-private helper; the top-level `buildSystemPrompt` joins them in\n// the order the harness has documented since ADR-0033.\n//\n// See ADR-0039 for the decomposition rationale.\n\nimport os from \"node:os\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { parseCitationStrictness } from \"@/lib/stores/agent-configs\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { listIntegrations } from \"@/lib/stores/integrations\";\nimport { listEnabledDocumentSources, getDocumentSourceStats } from \"@/lib/stores/document-sources\";\nimport { buildAdaptivePersonaContext } from \"@/lib/agents/adaptive-persona\";\nimport { resolveHarness } from \"@/lib/agents/harness/resolve\";\nimport {\n type ContextBudget,\n formatContextBudgetSummary,\n} from \"@/lib/agents/context-budget\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport type { StreamOptions } from \"@/lib/agents/base\";\nimport type { SourceManifestEntry } from \"@/lib/agents/citation-checker\";\n\nconst APP_NAME = getAppName();\n\nexport interface SystemPromptContext {\n agentCfg: AgentConfigRow;\n trimmedMessage: string;\n budget: ContextBudget;\n recallCtx: string;\n warmSummaryCtx: string;\n factsCtx: string;\n experienceMode: \"essential\" | \"full\";\n delegateRosterLines: string[];\n /** Numbered source manifest the agent may cite via `[N]` markers. Built\n * by run-thread from the thread's visited-source set + prior-dialog\n * turns when the agent's `citation_strictness` is not `'off'`. Empty\n * array or undefined disables citation. */\n sourceManifest?: ReadonlyArray<SourceManifestEntry>;\n}\n\nexport function buildSystemPrompt(ctx: SystemPromptContext): string {\n const { agentCfg, trimmedMessage, budget, recallCtx, warmSummaryCtx, factsCtx, experienceMode, delegateRosterLines, sourceManifest } = ctx;\n\n const adaptivePersonaCtx = buildAdaptivePersonaContext(agentCfg, trimmedMessage);\n const harnessParts = resolveHarness(agentCfg);\n\n // Tier ordering follows the agent's configured priority (hot is the\n // in-prompt history itself, so it doesn't have a context block here).\n const tierCtxByName = { hot: \"\", warm: warmSummaryCtx, facts: factsCtx } as const;\n const tierOrderCtx = budget.tierPriority.map((t) => tierCtxByName[t]).filter(Boolean);\n\n const parts: (string | null | undefined)[] = [\n agentCfg.identity,\n agentCfg.instructions,\n adaptivePersonaCtx,\n buildUserContext(),\n buildIntegrationsContext(),\n buildDocumentsContext(),\n harnessParts.capabilities,\n harnessParts.plan_first,\n harnessParts.presentation,\n harnessParts.citation,\n buildSourceLinkContext(agentCfg, sourceManifest ?? []),\n buildTimeContext(),\n buildEnvContext(),\n harnessParts.self_config,\n buildExperienceContext(experienceMode),\n buildOutputBudgetContext(budget),\n buildMemoryContext(budget),\n ...tierOrderCtx,\n recallCtx,\n buildDelegatesContext(delegateRosterLines),\n ];\n\n return parts.filter(Boolean).join(\"\\n\\n\");\n}\n\nexport function resolveExperienceMode(options?: StreamOptions): \"essential\" | \"full\" {\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 raw = options?.ui_experience_mode;\n return raw === \"essential\" || raw === \"normal\" ? \"essential\" : \"full\";\n}\n\n// ── Context block builders (file-private) ────────────────────────────────\n\nfunction buildUserContext(): string {\n const userProfile = getUserProfile();\n const parts: string[] = [];\n if (userProfile?.name) parts.push(`Name: ${userProfile.name}`);\n if (userProfile?.about) parts.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 parts.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 return parts.length > 0 ? `--- User context ---\\n${parts.join(\"\\n\")}` : \"\";\n}\n\nfunction buildTimeContext(): string {\n return `Current time: ${new Date().toISOString()} (UTC). Use this when computing scheduled task timestamps.`;\n}\n\n// Citation enforcement directive. Empty unless the agent's\n// `citation_strictness` is not `'off'`. Shows the numbered source\n// manifest (tool-visited sources + memory items + prior assistant turns)\n// the agent may cite via inline `[N]` markers — the chat UI renders each\n// `[N]` as a clickable link or anchor. Invented numbers stay as plain\n// text and are flagged by the post-turn checker.\n//\n// Strictness levels:\n// informational — agent NOT asked to cite (checker still surfaces\n// references in the UI)\n// standard — agent nudged to cite KEY (load-bearing) claims\n// strict — agent asked to cite EVERY factual claim\n//\n// Numbered markers were chosen over free-form `[label](href)` because\n// long-form LLM output reliably regresses to its training distribution\n// when asked to type exact paths mid-sentence — Perplexity, Wikipedia,\n// and Anthropic's first-party Citations all sidestep that by letting the\n// model emit a short stable token (`[3]`) and resolving the link\n// out-of-band. Same idea here.\nfunction buildSourceLinkContext(\n agent: AgentConfigRow,\n manifest: ReadonlyArray<SourceManifestEntry>,\n): string {\n const strictness = parseCitationStrictness(agent.citation_strictness) ?? \"off\";\n if (strictness === \"off\" || strictness === \"informational\") return \"\";\n\n const intro =\n strictness === \"strict\"\n ? \"Your reply will be audited by a second-pass model that ranks every factual claim by impact. Cite EVERY factual claim — quoted numbers, file contents, API behavior, named facts, paraphrases of earlier turns. The audit downgrades unsupported claims as low-confidence; citing up front saves you from re-grounding rounds for things you already know.\"\n : \"Your reply will be audited by a second-pass model that ranks every factual claim by impact. Cite KEY load-bearing claims (quoted numbers, file contents, API behavior, named facts). Don't mark incidentals, summaries, plans, or your own derivations — over-citing is as bad as not citing. The audit re-grounds unsupported KEY claims; citing up front saves the extra round.\";\n\n // The pre-turn manifest is always empty under the current design — we\n // surface citable references in the post-turn manifest after tool\n // events have actually been recorded. So the only valid citation form\n // during drafting is the inline markdown link.\n void manifest;\n return [\n \"--- Citation format ---\",\n intro,\n \"PRIMARY (inline links): cite by writing a standard markdown link inline: `[short label](https://example.com/path)` or `[file name](/abs/path.ts)` or `[earlier reply](#msg-<id>)`. Wrap the cited PHRASE itself as the link text when natural — `Jade has [ice skating at 16:00](?thread=…&agent=…)` reads better than a trailing `[1]`.\",\n \"When a tool result contains a `cite_as` field (delegate_to_agent does, and so do some integrations), paste that exact value somewhere in your reply — it's a pre-built markdown link to the source. Anything you summarize from a delegate or from a web/file tool result MUST carry at least one inline link back to where it came from; a summary with zero links reads as if you made the facts up.\",\n \"For web_search / fetch_webpage results, the URL is right there in the tool output — use it: `[headline or short label](https://...)`. For file_read results, link the absolute path: `[filename.ext](/abs/path/filename.ext)`.\",\n \"FALLBACK (declared refs block): if a source is awkward to cite inline (e.g. you summarized 4 articles in one paragraph), you MAY end your reply with a fenced block exactly like this:\",\n \"```jarela-references\",\n \"[\",\n \" { \\\"label\\\": \\\"CNN — Mars mission\\\", \\\"href\\\": \\\"https://cnn.com/...\\\" },\",\n \" { \\\"label\\\": \\\"Postman's reply\\\", \\\"href\\\": \\\"?thread=...&agent=...\\\" }\",\n \"]\",\n \"```\",\n \"Rules for the declared-refs block: it MUST be the very last thing in your reply, MUST be valid JSON (an array of `{label, href}` objects, both strings), and MUST be inside a fenced code block tagged exactly `jarela-references`. The block is stripped from your reply before it's shown to the user — the entries appear as numbered chips in a References footer the UI builds automatically. Use this sparingly — inline links are always preferred because they show the user which words came from where.\",\n \"DO NOT write `[CNN, June 4]`, `[Reuters]`, `[AP News]`, or any other bare-text bracket without a URL — those are NOT citations, they render as plain text and the audit counts them as uncited.\",\n \"If a claim is central to your answer and you have no link to attach, ground it first via a tool (web_search, fetch_webpage, file_read, …) before stating it.\",\n ].join(\"\\n\");\n}\n\nfunction buildExperienceContext(mode: \"essential\" | \"full\"): string {\n return [\n \"--- UX mode ---\",\n `User interface mode: ${mode}.`,\n mode === \"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\nfunction buildEnvContext(): string {\n return [\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\nfunction buildIntegrationsContext(): string {\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 configured = listIntegrations().filter((i) => i.configured);\n if (configured.length === 0) return \"\";\n\n const lines: string[] = [\"--- Configured integrations (use the typed tools, not shell CLIs) ---\"];\n for (const i of configured) {\n if (i.name === \"atlassian\") {\n const url = i.values.url;\n lines.push(\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 } else if (i.name === \"jira_align\") {\n lines.push(\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 } else if (i.name === \"github\") {\n lines.push(\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 } else if (i.name === \"gmail\") {\n lines.push(\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 } else if (i.name === \"outlook\") {\n lines.push(\n \"Outlook + Calendar: configured.\",\n \" Use outlook_* for mail operations and outlook_calendar_* for event operations.\",\n );\n } else if (i.name === \"google\") {\n lines.push(\n \"Google AI: configured.\",\n \" Use generate_image when the user asks to create images; don't claim image generation is unavailable.\",\n );\n } else {\n lines.push(`${i.name}: configured.`);\n }\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction buildOutputBudgetContext(budget: ContextBudget): string {\n const tokens = budget.outputReserveTokens;\n const words = Math.round(tokens * 0.75);\n return [\n \"--- Output budget ---\",\n `Your reply is capped at ~${tokens} output tokens per turn (≈${words} words). The provider truncates mid-sentence if you exceed it — you will not get a chance to finish.`,\n \"- Lead with the answer. Skip preambles, restating the question, and recapping context the user already sees.\",\n \"- If the user asks for a long artifact (essay, plan, large code dump, exhaustive list), estimate the size first. If it won't fit, ask whether to split across turns, summarise, or stream only the requested section.\",\n \"- Prefer dense prose and tight bullets over verbose explanation. Don't repeat yourself across paragraphs.\",\n ].join(\"\\n\");\n}\n\nfunction buildMemoryContext(budget: ContextBudget): string {\n return [\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\nfunction buildDelegatesContext(lines: string[]): string {\n if (lines.length === 0) return \"\";\n return [\n \"--- Available delegates ---\",\n \"You can hand subtasks to these other agents via the `delegate_to_agent` tool. Only delegate when the target agent has specialized knowledge or tools you lack — don't delegate trivial subtasks.\",\n \"BEFORE you call delegate_to_agent, briefly tell the user in one sentence which agent you're handing to and why. The user will see the tool card with the delegate's name, task, and final result.\",\n ...lines,\n ].join(\"\\n\");\n}\n\n// Surface indexed Documents so the model knows the RAG corpus exists.\n// Without this nudge agents almost never call `documents_search` — they have\n// no signal that any local content is searchable. Gated on actually-indexed\n// chunks (not just configured sources) so an empty/erroring source doesn't\n// produce false advertising.\nfunction buildDocumentsContext(): string {\n const sources = listEnabledDocumentSources();\n if (sources.length === 0) return \"\";\n\n let totalChunks = 0;\n const lines: string[] = [];\n for (const s of sources) {\n const stats = getDocumentSourceStats(s.id);\n if (stats.chunk_count === 0) continue;\n totalChunks += stats.chunk_count;\n const label = s.label ?? s.path;\n lines.push(`- ${label} (${s.kind}, ${stats.chunk_count} chunks)`);\n }\n if (totalChunks === 0) return \"\";\n\n return [\n \"--- Indexed documents ---\",\n `The user has ${totalChunks} indexed chunks across ${lines.length} document source(s) available to you:`,\n ...lines,\n \"Call `documents_search` whenever the user asks about local files, notes, project docs, or any content that sounds like it lives in one of these sources. Prefer it over guessing from training data. Use `documents_list_sources` to enumerate, and pass `source_id` to scope a search.\",\n ].join(\"\\n\");\n}\n","// History-window assembly. Pulls the latest N messages within the agent's\n// time bound, computes the context budget, summarises overflow into a warm\n// recap, and pulls fact-memory hits relevant to the current turn.\n//\n// All work is synchronous SQLite + one optional LLM call (for the warm\n// summary). The LLM call is best-effort: if the provider errors, we return\n// an empty warm context rather than blocking the turn.\n//\n// See ADR-0039 for the decomposition rationale.\n\nimport { getRecentMessagesWindow, getThread, setThreadWarmSummary } from \"@/lib/stores/threads\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\nimport {\n applyTierSpill,\n computeContextBudget,\n estimateTokens,\n takeRecentMessagesWithinBudget,\n truncateLargestMessagesWithinBudget,\n type ContextBudget,\n} from \"@/lib/agents/context-budget\";\nimport { summarizeTranscript, transcriptText } from \"@/lib/agents/conversation-summary\";\nimport type { MessageRow } from \"@/lib/stores/threads\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getKnownContextLength } from \"@/lib/providers/known-context-windows\";\nimport type { ContentPart } from \"@/lib/tools/types\";\n\nexport interface ResolvedHistoryWindow {\n history: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>;\n budget: ContextBudget;\n warmSummaryCtx: string;\n factsCtx: string;\n // Per-tier *actual* input-token consumption derived from the assembled\n // window. Lets the chat UI render a diagnostic context-usage bar that\n // shows which tier is starving so the user can rebalance the agent's\n // hot/warm/facts split. Overhead is the system-prompt-side allowance\n // (caller may overwrite with a more precise measurement before persist).\n tierUsage: {\n hot_tokens: number;\n warm_tokens: number;\n facts_tokens: number;\n overhead_tokens: number;\n };\n}\n\n/**\n * Build the per-turn history window the LLM sees. Returns the in-prompt\n * message list (already JSON-content-parsed), the context budget, and\n * the warm-summary + facts context strings ready to slot into the system\n * prompt.\n *\n * `hotSince` (ADR-0042) is the user's explicit context boundary. When set,\n * it overrides the agent's `history_window_hours`-derived bound so the\n * boundary line in the chat is the source of truth for what enters hot.\n * When fresh, the cached `warm_summary` on the thread is reused; when the\n * boundary has moved since the last summary was computed (or no summary\n * exists), the warm tier re-summarises and the new text is persisted.\n */\nexport async function buildHistoryWindow(\n thread_id: string,\n agentCfg: AgentConfigRow,\n providerParams: ProviderParams,\n trimmedMessage: string,\n modelInfo: { providerName?: string; modelId?: string },\n hotSince?: string | null,\n): Promise<ResolvedHistoryWindow> {\n const limit = agentCfg.history_limit ?? 50;\n const windowHours = agentCfg.history_window_hours ?? 8;\n // Explicit pin wins over the agent default. NULL/undefined falls back to\n // the time-window heuristic; existing threads with no pin behave exactly\n // as they did before this ADR landed.\n const sinceISO = hotSince\n ? hotSince\n : windowHours > 0\n ? new Date(Date.now() - windowHours * 3600_000).toISOString()\n : undefined;\n const allWindowMessages = getRecentMessagesWindow(thread_id, limit, sinceISO);\n\n // Reuse the persisted warm summary when the boundary it covers still\n // matches the current pin — saves an LLM call on every turn that doesn't\n // change the boundary.\n const cached = hotSince ? getThread(thread_id) : null;\n const cachedSummaryFresh =\n !!cached?.warm_summary && cached.warm_summary_before === hotSince;\n\n const budget = computeContextBudget({\n context_window_tokens:\n typeof providerParams.context_window_tokens === \"number\"\n ? providerParams.context_window_tokens\n : resolveFallbackContextWindow(modelInfo),\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 // Walk tiers in the configured priority order, threading the unused-token\n // spill from each tier into the next so leftover headroom isn't wasted.\n // Default priority [hot, warm, facts] makes this identical to the natural\n // data-flow order; non-default priorities still respect the data-flow\n // dependency (warm needs hot's slice) by falling back to hot's soft cap\n // when warm is asked to evaluate before hot has run.\n let spill = 0;\n let hotMessages: MessageRow[] | undefined;\n let hotCap = 0;\n let warmSummaryCtx = \"\";\n let factsCtx = \"\";\n\n for (const tier of budget.tierPriority) {\n if (tier === \"hot\") {\n ({ cap: hotCap } = applyTierSpill(budget.tierBudgets.hot, spill, 0));\n hotMessages = takeRecentMessagesWithinBudget(allWindowMessages, hotCap);\n const used = sumMessageTokens(hotMessages);\n ({ spill } = applyTierSpill(budget.tierBudgets.hot, spill, used));\n } else if (tier === \"warm\") {\n const warmCap = budget.tierBudgets.warm + spill;\n if (cachedSummaryFresh && cached?.warm_summary) {\n // Pin-stable turn: don't pay the summariser tax again.\n warmSummaryCtx = cached.warm_summary;\n } else {\n // If priority evaluates warm before hot, do a provisional hot slice at\n // hot's soft cap so we know which messages to summarise. Hot's later\n // pass may then absorb more (its cap will include any warm spill back),\n // and the warm summary will harmlessly cover a few messages hot also\n // includes — better than not summarising at all.\n const hotForSlice = hotMessages ?? takeRecentMessagesWithinBudget(allWindowMessages, budget.tierBudgets.hot);\n warmSummaryCtx = await buildWarmSummary(\n allWindowMessages,\n hotForSlice.length,\n modelInfo.providerName,\n modelInfo.modelId,\n providerParams,\n warmCap,\n );\n // Persist the freshly-computed summary keyed on the boundary it\n // covers, so the chat UI can render it on the next page load and\n // subsequent same-pin turns can short-circuit the LLM call. Skipped\n // when there's no explicit pin because the time-windowed boundary\n // shifts every turn — caching it would never hit.\n if (warmSummaryCtx && hotSince) {\n setThreadWarmSummary(thread_id, warmSummaryCtx, hotSince);\n }\n }\n const used = estimateTokens(warmSummaryCtx);\n ({ spill } = applyTierSpill(budget.tierBudgets.warm, spill, used));\n } else {\n const factsCap = budget.tierBudgets.facts + spill;\n factsCtx = buildFactsContext(trimmedMessage, factsCap);\n const used = estimateTokens(factsCtx);\n ({ spill } = applyTierSpill(budget.tierBudgets.facts, spill, used));\n }\n }\n\n // Hot is always evaluated above (priority always contains all three tiers),\n // but TypeScript can't see that. Default to an empty list defensively.\n const hotMessagesResolved = hotMessages ?? [];\n\n // If the warm tier was expected but failed to summarise, fall back to\n // truncating the largest hot messages so the older context isn't silently\n // dropped — better to clip overlong messages than lose them entirely.\n const warmWasExpected = budget.tierBudgets.warm > 32 && (allWindowMessages.length - hotMessagesResolved.length) >= 2;\n const hotMessagesForPrompt = !warmSummaryCtx && warmWasExpected\n ? truncateLargestMessagesWithinBudget(hotMessagesResolved, hotCap || budget.tierBudgets.hot)\n : hotMessagesResolved;\n\n const history = hotMessagesForPrompt.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: parseContent(m.content),\n }));\n\n // Re-measure hot AFTER any truncation so the recorded usage matches what\n // actually went into the prompt. Warm/facts are already finalised above.\n const hotTokensFinal = hotMessagesForPrompt.reduce(\n (acc, m) => acc + estimateTokens(transcriptText(m.content)),\n 0,\n );\n\n return {\n history,\n budget,\n warmSummaryCtx,\n factsCtx,\n tierUsage: {\n hot_tokens: hotTokensFinal,\n warm_tokens: estimateTokens(warmSummaryCtx),\n facts_tokens: estimateTokens(factsCtx),\n overhead_tokens: budget.overheadTokens,\n },\n };\n}\n\nfunction sumMessageTokens(messages: readonly MessageRow[]): number {\n return messages.reduce((acc, m) => acc + estimateTokens(transcriptText(m.content)), 0);\n}\n\n// When the agent's model config doesn't pin `context_window_tokens`, fall\n// back to the web-sourced known-models table keyed by (provider, model_id).\n// Returns undefined when the model is unrecognised — the budget calculator\n// then uses its hard-coded 8k default.\nfunction resolveFallbackContextWindow(\n modelInfo: { providerName?: string; modelId?: string },\n): number | undefined {\n if (!modelInfo.providerName || !modelInfo.modelId) return undefined;\n return getKnownContextLength(modelInfo.providerName, modelInfo.modelId) ?? undefined;\n}\n\n// Recover ContentPart[] from messages that were stored as JSON-encoded\n// arrays (text + attachments). Plain string messages pass through.\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\nasync function buildWarmSummary(\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","export type { ThreadRunRequest } from \"./request\";\nexport {\n buildSystemPrompt,\n resolveExperienceMode,\n type SystemPromptContext,\n} from \"./system-prompt\";\nexport {\n buildHistoryWindow,\n type ResolvedHistoryWindow,\n} from \"./history-window\";\n","// Authoritative published per-1M-token rates for canonical model ids.\n//\n// Used by `modelRatesFor` as the FINAL fallback after the live snapshot\n// lookup chain. The snapshot extractor can break when a provider redesigns\n// its pricing page (regex window misses the model name, LLM extraction\n// returns uniform garbage); without a baseline, the dashboard cost columns\n// silently go to null on the most-used models. This table guarantees a\n// non-null rate for the canonical ids regardless of snapshot health.\n//\n// **These rates ARE stale by construction.** Bump manually when a provider\n// updates published pricing. The live snapshot — when healthy — wins; this\n// is only consulted when nothing else matched. Confidence is reported as\n// \"medium\" so the dashboard's data-quality chip flags it as not-the-source-\n// of-truth.\n//\n// Keep the list short. Only include canonical ids the snapshot extractor\n// reliably struggles with. Aliases handled by `modelAliasCandidates` (e.g.\n// the post-`/` suffix of `openai/gpt-4o`) so we don't need separate entries\n// for aggregator-namespaced ids.\n//\n// Sources, last verified 2026-06:\n// - https://www.anthropic.com/pricing\n// - https://openai.com/api/pricing/\n// - https://ai.google.dev/gemini-api/docs/pricing\n// - https://platform.deepseek.com/pricing\n\nimport type { ProviderRates } from \"./pricing\";\n\ninterface KnownRate {\n inputPer1M: number;\n outputPer1M: number;\n}\n\nconst KNOWN_MODEL_RATES: Record<string, KnownRate> = {\n // Anthropic\n \"claude-opus-4-7\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4-6\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4-5\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-sonnet-4-6\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-sonnet-4-5\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-sonnet-4\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-haiku-4-5\": { inputPer1M: 1, outputPer1M: 5 },\n \"claude-3-5-sonnet\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-3-5-haiku\": { inputPer1M: 0.8, outputPer1M: 4 },\n \"claude-3-opus\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-3-sonnet\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-3-haiku\": { inputPer1M: 0.25, outputPer1M: 1.25 },\n\n // OpenAI\n \"gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n \"gpt-4-turbo\": { inputPer1M: 10, outputPer1M: 30 },\n \"gpt-4\": { inputPer1M: 30, outputPer1M: 60 },\n \"gpt-3.5-turbo\": { inputPer1M: 0.5, outputPer1M: 1.5 },\n \"o1\": { inputPer1M: 15, outputPer1M: 60 },\n \"o1-mini\": { inputPer1M: 3, outputPer1M: 12 },\n \"o1-preview\": { inputPer1M: 15, outputPer1M: 60 },\n \"o3-mini\": { inputPer1M: 1.1, outputPer1M: 4.4 },\n\n // Google Gemini\n \"gemini-2.5-pro\": { inputPer1M: 1.25, outputPer1M: 5 },\n \"gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5 },\n \"gemini-2.5-flash-lite\": { inputPer1M: 0.1, outputPer1M: 0.4 },\n \"gemini-2.0-flash\": { inputPer1M: 0.1, outputPer1M: 0.4 },\n \"gemini-2.0-flash-lite\": { inputPer1M: 0.075, outputPer1M: 0.3 },\n \"gemini-1.5-pro\": { inputPer1M: 1.25, outputPer1M: 5 },\n \"gemini-1.5-flash\": { inputPer1M: 0.075, outputPer1M: 0.3 },\n\n // DeepSeek\n \"deepseek-chat\": { inputPer1M: 0.27, outputPer1M: 1.10 },\n \"deepseek-reasoner\": { inputPer1M: 0.55, outputPer1M: 2.19 },\n \"deepseek-coder\": { inputPer1M: 0.27, outputPer1M: 1.10 },\n\n // Cohere\n \"command-r-plus\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"command-r\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\nexport function knownRateFor(modelId: string): ProviderRates | null {\n const key = modelId.trim().toLowerCase();\n if (!key) return null;\n const hit = KNOWN_MODEL_RATES[key];\n if (!hit) return null;\n return {\n inputPer1M: hit.inputPer1M,\n outputPer1M: hit.outputPer1M,\n source: \"jarela:known-rates\",\n inferred: false,\n confidence: \"medium\",\n ok: true,\n status: null,\n error: null,\n };\n}\n\nexport function knownRateModelIds(): string[] {\n return Object.keys(KNOWN_MODEL_RATES);\n}\n","// Sync pricing lookups for both write-time cost snapshots (ADR-0041\n// `message_usage`) and read-time dashboard aggregation.\n//\n// The previous live in `lib/stores/dashboard-metrics.ts` was async because\n// the dashboard was the only consumer and it loaded the JSON via fs/promises.\n// The write path (persistAssistantMessage) needs sync access, so we read\n// the snapshot synchronously and cache it in process memory keyed by\n// mtime. Refreshing the pricing snapshot on disk invalidates the cache on\n// next read.\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { knownRateFor } from \"./known-rates\";\n\nexport type ProviderRates = {\n inputPer1M: number | null;\n outputPer1M: number | null;\n source: string;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n ok: boolean;\n status: number | null;\n error: string | null;\n};\n\ntype PricingSnapshotSource = {\n id: string;\n pricing_url: string;\n resolved_url?: string | null;\n ok?: boolean;\n status?: number | null;\n error?: string | null;\n price_signals?: string[];\n model_rates?: Array<{\n model_id: string;\n input_per_1m_usd: number | null;\n output_per_1m_usd: number | null;\n inferred?: boolean;\n confidence?: \"high\" | \"medium\" | \"low\";\n }>;\n};\n\ntype PricingSnapshot = {\n generated_at?: string;\n sources?: PricingSnapshotSource[];\n};\n\nexport interface PricingTables {\n byProvider: Map<string, ProviderRates>;\n byProviderModel: Map<string, ProviderRates>;\n // Aggregator-agnostic: lookup by model_id alone. Some providers proxy\n // upstream models (github-copilot, openrouter-style aggregators) and\n // don't expose per-model pricing themselves, so we also index every\n // model_rate by its model id. First-write wins; subsequent same-id\n // entries only overwrite when they improve confidence or fill a null.\n byModel: Map<string, ProviderRates>;\n generatedAt: string | null;\n}\n\nconst EXPECTED_PROVIDERS = [\"openai\", \"anthropic\", \"google\", \"deepseek\", \"cohere\", \"github-copilot\"];\n\nlet cached: { mtimeMs: number; tables: PricingTables } | null = null;\n\nfunction snapshotPath(): string {\n return join(process.cwd(), \"docs\", \"journal\", \"pricing-snapshot.json\");\n}\n\nfunction readSnapshotSync(): { snapshot: PricingSnapshot | null; mtimeMs: number } {\n try {\n const p = snapshotPath();\n const stat = statSync(p);\n const raw = readFileSync(p, \"utf8\");\n return { snapshot: JSON.parse(raw) as PricingSnapshot, mtimeMs: stat.mtimeMs };\n } catch {\n return { snapshot: null, mtimeMs: 0 };\n }\n}\n\nexport function getPricingTables(): PricingTables {\n const { snapshot, mtimeMs } = readSnapshotSync();\n if (cached && cached.mtimeMs === mtimeMs) return cached.tables;\n\n const byProvider = new Map<string, ProviderRates>();\n const byProviderModel = new Map<string, ProviderRates>();\n const byModel = new Map<string, ProviderRates>();\n\n for (const provider of EXPECTED_PROVIDERS) {\n byProvider.set(provider, {\n inputPer1M: null,\n outputPer1M: null,\n source: \"snapshot-missing\",\n inferred: true,\n confidence: \"low\",\n ok: false,\n status: null,\n error: \"provider missing in pricing snapshot\",\n });\n }\n\n if (snapshot?.sources) {\n for (const source of snapshot.sources) {\n const key = normalizeProvider(source.id);\n if (!key) continue;\n const parsed = inferRatesFromSignals(source.price_signals ?? []);\n const modelInputRates = (source.model_rates ?? [])\n .map((m) => m.input_per_1m_usd)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n const modelOutputRates = (source.model_rates ?? [])\n .map((m) => m.output_per_1m_usd)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n\n const providerInput = parsed.inputPer1M ?? (modelInputRates[0] ?? null);\n const providerOutput = parsed.outputPer1M ?? (modelOutputRates[0] ?? null);\n const providerDerivedFromModels = parsed.inputPer1M == null && parsed.outputPer1M == null\n && (providerInput != null || providerOutput != null);\n\n byProvider.set(key, {\n inputPer1M: providerInput,\n outputPer1M: providerOutput,\n source: source.resolved_url ?? source.pricing_url,\n inferred: providerDerivedFromModels ? true : parsed.inferred,\n confidence: providerDerivedFromModels ? \"medium\" : parsed.confidence,\n ok: source.ok !== false || providerDerivedFromModels,\n status: source.status ?? null,\n error: source.error ?? null,\n });\n\n for (const modelRate of source.model_rates ?? []) {\n const normalizedModel = modelRate.model_id?.trim().toLowerCase();\n if (!normalizedModel) continue;\n const entry: ProviderRates = {\n inputPer1M: modelRate.input_per_1m_usd,\n outputPer1M: modelRate.output_per_1m_usd,\n source: source.resolved_url ?? source.pricing_url,\n inferred: modelRate.inferred !== false,\n confidence: modelRate.confidence ?? \"low\",\n ok: source.ok !== false,\n status: source.status ?? null,\n error: source.error ?? null,\n };\n byProviderModel.set(`${key}::${normalizedModel}`, entry);\n // Aggregator-agnostic index. Prefer entries with actual numbers and\n // higher confidence so that, e.g., anthropic's authoritative rate\n // for `claude-opus-4-7` beats a copilot proxy guess for the same id.\n const existing = byModel.get(normalizedModel);\n if (!existing || isBetterRate(entry, existing)) {\n byModel.set(normalizedModel, entry);\n }\n }\n }\n }\n\n const tables: PricingTables = {\n byProvider,\n byProviderModel,\n byModel,\n generatedAt: snapshot?.generated_at ?? null,\n };\n cached = { mtimeMs, tables };\n return tables;\n}\n\nexport function providerRatesFor(tables: PricingTables, provider: string | null): ProviderRates {\n if (!provider) {\n return {\n inputPer1M: null, outputPer1M: null, source: \"unknown\",\n inferred: true, confidence: \"low\", ok: false, status: null,\n error: \"no provider assigned\",\n };\n }\n return tables.byProvider.get(provider.toLowerCase()) ?? {\n inputPer1M: null, outputPer1M: null, source: \"unknown\",\n inferred: true, confidence: \"low\", ok: false, status: null,\n error: \"provider missing in pricing snapshot\",\n };\n}\n\nexport function modelRatesFor(\n tables: PricingTables,\n provider: string | null,\n modelId: string | null,\n): ProviderRates {\n if (!modelId) return providerRatesFor(tables, provider);\n const modelKey = modelId.trim().toLowerCase();\n if (!modelKey) return providerRatesFor(tables, provider);\n\n // 1. Prefer (provider, model_id) when both are known — authoritative.\n if (provider) {\n const providerKey = normalizeProvider(provider);\n if (providerKey) {\n const candidates = modelAliasCandidates(providerKey, modelKey);\n for (const candidate of candidates) {\n const exact = tables.byProviderModel.get(`${providerKey}::${candidate}`);\n if (exact) return exact;\n }\n\n // github-copilot (and similar aggregators) re-expose upstream models\n // without their own pricing entry. Resolve via the inferred upstream\n // vendor before falling back to plain model lookup.\n if (providerKey === \"github-copilot\") {\n const upstream = inferProviderFromModelId(modelKey);\n if (upstream) {\n const upstreamCandidates = modelAliasCandidates(upstream, modelKey);\n for (const candidate of upstreamCandidates) {\n const viaUpstreamModel = tables.byProviderModel.get(`${upstream}::${candidate}`);\n if (viaUpstreamModel) return viaUpstreamModel;\n }\n // Upstream had no per-model rate either — try its provider-level\n // rate before falling through to the model-only index.\n const upstreamProviderRate = tables.byProvider.get(upstream);\n if (upstreamProviderRate && upstreamProviderRate.ok) return upstreamProviderRate;\n }\n }\n }\n }\n\n // 2. Aggregator fallback: lookup by model_id alone. Covers the case where\n // the user-configured provider doesn't publish per-model pricing but the\n // same id is rated by its upstream vendor in the snapshot.\n for (const candidate of modelAliasCandidates(provider ? (normalizeProvider(provider) ?? \"\") : \"\", modelKey)) {\n const viaModel = tables.byModel.get(candidate);\n if (viaModel) return viaModel;\n }\n const directModel = tables.byModel.get(modelKey);\n if (directModel) return directModel;\n\n // 3. Hardcoded known-rates fallback. The live snapshot extractor can\n // silently lose data (anthropic page redesign zeroed model_rates,\n // LLM-extract returning uniform garbage); this table guarantees a\n // sane non-null rate for canonical ids. Rates are stale by design,\n // so confidence=\"medium\". Snapshot wins when present.\n for (const candidate of modelAliasCandidates(provider ? (normalizeProvider(provider) ?? \"\") : \"\", modelKey)) {\n const known = knownRateFor(candidate);\n if (known) return known;\n }\n\n // 4. Provider-level rate (or \"no provider assigned\" error).\n return providerRatesFor(tables, provider);\n}\n\n// Tie-breaker for the byModel index when multiple sources rate the same id.\n// Prefer entries that actually have numbers and the higher confidence band.\nfunction isBetterRate(next: ProviderRates, prev: ProviderRates): boolean {\n const nextHas = next.inputPer1M != null || next.outputPer1M != null;\n const prevHas = prev.inputPer1M != null || prev.outputPer1M != null;\n if (nextHas && !prevHas) return true;\n if (!nextHas && prevHas) return false;\n const rank = { high: 2, medium: 1, low: 0 } as const;\n return rank[next.confidence] > rank[prev.confidence];\n}\n\nexport function normalizeProvider(id: string): string | null {\n const lower = id.toLowerCase();\n if (lower.includes(\"github\") || lower.includes(\"copilot\")) return \"github-copilot\";\n if (lower.includes(\"google\") || lower.includes(\"gemini\")) return \"google\";\n if (lower.includes(\"openai\")) return \"openai\";\n if (lower.includes(\"anthropic\")) return \"anthropic\";\n if (lower.includes(\"cohere\")) return \"cohere\";\n if (lower.includes(\"deepseek\")) return \"deepseek\";\n return lower || null;\n}\n\nfunction modelAliasCandidates(provider: string, modelId: string): string[] {\n const out = new Set<string>();\n const id = modelId.trim().toLowerCase();\n if (!id) return [];\n out.add(id);\n // Aggregators (OpenRouter, LiteLLM, etc.) namespace upstream models as\n // `vendor/model` or `aggregator/vendor/model`. The snapshot only stores\n // the bare model id, so add the post-`/` suffix as a fallback candidate.\n const slash = id.lastIndexOf(\"/\");\n if (slash >= 0 && slash < id.length - 1) out.add(id.slice(slash + 1));\n if (provider === \"deepseek\") {\n if (/reasoner/.test(id) || /r1/.test(id)) out.add(\"deepseek-reasoner\");\n if (/chat/.test(id) || /v[0-9]/.test(id) || /coder/.test(id)) out.add(\"deepseek-chat\");\n }\n return [...out];\n}\n\nfunction inferProviderFromModelId(modelId: string): string | null {\n const raw = modelId.trim().toLowerCase();\n if (!raw) return null;\n const slash = raw.lastIndexOf(\"/\");\n const id = slash >= 0 && slash < raw.length - 1 ? raw.slice(slash + 1) : raw;\n if (id.startsWith(\"gpt-\") || /^o[1-4](?:-|$)/.test(id)) return \"openai\";\n if (id.startsWith(\"claude-\")) return \"anthropic\";\n if (id.startsWith(\"gemini-\")) return \"google\";\n if (id.startsWith(\"deepseek-\")) return \"deepseek\";\n if (id.startsWith(\"command-\") || id.startsWith(\"embed-\")) return \"cohere\";\n return null;\n}\n\nfunction inferRatesFromSignals(signals: string[]): {\n inputPer1M: number | null;\n outputPer1M: number | null;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n} {\n const tokenRates = signals\n .map((s) => {\n const m = /\\$\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\/?\\s*(?:1M\\s*tokens|M\\s*Tok|MTok)/i.exec(s);\n if (!m) return null;\n return Number(m[1]);\n })\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n if (tokenRates.length === 0) {\n return { inputPer1M: null, outputPer1M: null, inferred: true, confidence: \"low\" };\n }\n return {\n inputPer1M: tokenRates[0],\n outputPer1M: tokenRates[tokenRates.length - 1],\n inferred: true,\n confidence: tokenRates.length >= 2 ? \"medium\" : \"low\",\n };\n}\n\n// Anthropic prompt-cache multipliers, applied against the standard input\n// rate. Cache writes are billed at 1.25× input (\"cache create\"); cache\n// reads are billed at 0.1× input (\"cache hit\"). Source:\n// https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#pricing\n// We apply the same multipliers to other providers that publish a\n// cache-token breakdown — OpenAI's prompt caching, for example, also\n// quotes a 0.5× read multiplier, but its API surfaces only `cached_tokens`\n// (no separate write count) and a future PR can split that out. For now\n// any provider that emits both fields will be priced as above.\nexport const CACHE_CREATION_INPUT_RATE_MULTIPLIER = 1.25;\nexport const CACHE_READ_INPUT_RATE_MULTIPLIER = 0.1;\n\nexport interface CacheTokenBreakdown {\n cache_creation_input_tokens?: number | null;\n cache_read_input_tokens?: number | null;\n}\n\nexport function estimateCostUsd(\n inputTokens: number,\n outputTokens: number,\n rates: Pick<ProviderRates, \"inputPer1M\" | \"outputPer1M\">,\n cache?: CacheTokenBreakdown | null,\n): number {\n const inputRate = rates.inputPer1M;\n const outputRate = rates.outputPer1M;\n if (inputRate == null && outputRate == null) return 0;\n const inCost = inputRate == null ? 0 : (inputTokens / 1_000_000) * inputRate;\n const outCost = outputRate == null ? 0 : (outputTokens / 1_000_000) * outputRate;\n let cacheCost = 0;\n if (cache && inputRate != null) {\n const create = cache.cache_creation_input_tokens ?? 0;\n const read = cache.cache_read_input_tokens ?? 0;\n if (create > 0) cacheCost += (create / 1_000_000) * inputRate * CACHE_CREATION_INPUT_RATE_MULTIPLIER;\n if (read > 0) cacheCost += (read / 1_000_000) * inputRate * CACHE_READ_INPUT_RATE_MULTIPLIER;\n }\n return inCost + outCost + cacheCost;\n}\n","// Anti-hallucination detector — judges whether an agent turn STALLED,\n// meaning the assistant narrated future work but didn't invoke a\n// write-class tool to actually do the thing.\n//\n// Two detection methods, picked by mode (one or the other, never both):\n// \"off\" — no detection.\n// \"regex\" — fast pattern match in lib/agents/run-thread.ts (default).\n// \"model\" — LLM classifier via this module. Requires a saved model\n// config name; falls back to \"regex\" if missing.\n//\n// Per-agent (lib/stores/agent-configs.ts):\n// anti_hallucination_mode + anti_hallucination_model_config\n// NULL on either column → inherit the env defaults below.\n//\n// Global (lib/env/schema.ts):\n// JARELA_HALLUCINATION_DETECTOR_MODE = off | regex | model (default: regex)\n// JARELA_HALLUCINATION_DETECTOR_MODEL = saved model config name\n//\n// Any invocation error / parse failure / abort returns null so the call\n// site can fall back; the classifier never blocks the turn.\n\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport { isWriteLikeToolName } from \"@/lib/agents/run-thread\";\nimport { getConfig } from \"@/lib/env/config\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\n\nexport type DetectorMode = \"off\" | \"regex\" | \"model\";\n\nexport interface ResolvedDetector {\n /** Effective mode after merging the agent override over the env default. */\n mode: DetectorMode;\n /** Effective model config name (only meaningful when mode === \"model\"). */\n modelConfigName: string;\n}\n\n/**\n * Merge the per-agent override (`anti_hallucination_mode` + `_model_config`)\n * over the env default (JARELA_HALLUCINATION_DETECTOR_MODE +\n * JARELA_HALLUCINATION_DETECTOR_MODEL).\n *\n * If the resolved mode is \"model\" but no model config name is available,\n * silently downgrade to \"regex\" — this is the cheaper safe fallback. We\n * also downgrade when the named config doesn't exist (typo, deleted\n * config); the call site can log if it cares.\n */\nexport function resolveDetector(agent: Pick<AgentConfigRow, \"anti_hallucination_mode\" | \"anti_hallucination_model_config\"> | null | undefined): ResolvedDetector {\n const env = getConfig();\n const rawMode = (agent?.anti_hallucination_mode as DetectorMode | null | undefined)\n ?? env.hallucinationDetectorMode;\n const modelName = (agent?.anti_hallucination_model_config?.trim() || env.hallucinationDetectorModel.trim());\n if (rawMode === \"model\" && (!modelName || !getModelConfig(modelName))) {\n // Asked for model classifier but it's not actually configured — fall\n // back to regex so the agent still has SOME guard.\n return { mode: \"regex\", modelConfigName: \"\" };\n }\n if (rawMode === \"off\" || rawMode === \"regex\" || rawMode === \"model\") {\n return { mode: rawMode, modelConfigName: modelName };\n }\n return { mode: \"regex\", modelConfigName: \"\" };\n}\n\nexport interface StallVerdict {\n stalled: boolean;\n reason: string;\n}\n\n// Keep the prompt tight so a fast model returns in ~1s. We feed only\n// the trailing prose (last 1500 chars) — the stall signal is at the end\n// of the turn, not in the middle, and longer payloads inflate cost\n// without helping accuracy.\nconst PROMPT_TAIL_BUDGET = 1500;\n\nconst SYSTEM_PROMPT = `You judge whether an agent turn STALLED.\n\nA stalled turn is one where the assistant narrated future work — promised to write/edit/save/update something, said \"I'll do X now\" or \"I'm doing X now\" — but did not actually invoke a write-class tool to make the change. Read-only tools (file_read, web_search, list_dir) DO NOT count as fulfilling a write promise.\n\nYou will receive: the list of tools the agent called this turn, whether any were write-class, and the trailing prose of the assistant text.\n\nReply with EXACTLY one JSON object on one line, no surrounding prose, no markdown fence:\n\n{\"stalled\": true|false, \"reason\": \"<one short sentence, max 120 chars>\"}\n\nIf the agent called a write-class tool and the prose is consistent with that, stalled=false.\nIf the prose promises a write but no write-class tool was called, stalled=true.\nIf the agent's text is a normal completion message (\"Here are the results\", \"Done\"), stalled=false even if no write tool was called.`;\n\nexport async function classifyStall(\n assistantText: string,\n toolNames: readonly string[],\n modelConfigName: string,\n signal?: AbortSignal,\n): Promise<StallVerdict | null> {\n const cfgName = modelConfigName.trim();\n if (!cfgName) return null;\n\n const cfg = getModelConfig(cfgName);\n if (!cfg) return null;\n const params = getModelParams(cfg);\n\n let provider;\n try {\n provider = getProvider(cfg.provider);\n } catch {\n return null;\n }\n if (!provider.invoke) return null;\n\n const usedWriteTool = toolNames.some(isWriteLikeToolName);\n const tail = assistantText.slice(-PROMPT_TAIL_BUDGET);\n const userMsg = `Tools called this turn: ${JSON.stringify(toolNames)}\nAny write-class tools called? ${usedWriteTool ? \"yes\" : \"no\"}\n\nAssistant text (trailing ${tail.length} chars):\n${tail}`;\n\n if (signal?.aborted) return null;\n\n let result;\n try {\n result = await provider.invoke(\n cfg.model_id,\n [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMsg },\n ],\n params,\n [],\n );\n } catch {\n return null;\n }\n\n const text = result?.text ?? \"\";\n return parseVerdict(text);\n}\n\n// Strict JSON parse — extract the first {...} that looks like a verdict\n// and validate fields. Returns null on any parse failure so the caller\n// can treat \"no opinion\" as \"fall back to regex\".\nexport function parseVerdict(text: string): StallVerdict | null {\n if (!text) return null;\n // Strip code fences a chatty model might wrap the JSON in.\n const stripped = text.replace(/```(?:json)?\\s*/gi, \"\").replace(/```/g, \"\").trim();\n // Find the first balanced-looking object literal.\n const m = /\\{[^{}]*\"stalled\"[^{}]*\\}/.exec(stripped);\n if (!m) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(m[0]);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n const obj = parsed as Record<string, unknown>;\n if (typeof obj.stalled !== \"boolean\") return null;\n const reason = typeof obj.reason === \"string\" ? obj.reason.slice(0, 200) : \"\";\n return { stalled: obj.stalled, reason };\n}\n","// Citation checker — second-pass LLM that decides whether the assistant\n// turn's factual claims are backed by sources the agent actually visited\n// in this thread.\n//\n// Pipeline:\n// 1. extractVisitedSources(threadId) walks every persisted tool event +\n// the just-produced events to build the {url|path} provenance set.\n// 2. buildSourceManifest / buildCombinedManifest number the most-recent N\n// sources (tool-visited files/URLs, memory items, prior assistant\n// turns) so the model can cite by writing an inline `[N]` marker\n// instead of typing the full path/URL in every claim.\n// 3. extractCitedMarkers(text) pulls every `[N]` marker out of\n// the assistant text so the checker can skip turns that carry no\n// citations at all.\n// 4. classifyCitations(text, manifest, modelConfigName) asks the checker\n// LLM to emit a strict-JSON verdict listing each factual claim, the\n// marker the agent attached (if any), and whether that marker is in\n// the manifest.\n//\n// Failure modes (timeout, parse error, missing model config, provider\n// throw) all return null. The caller writes metadata only on a non-null\n// verdict and the chat UI degrades to \"no badge\" when metadata is absent.\n//\n// Design choices:\n// - Provenance scope is the whole thread, not a rolling window. Matches\n// how focused chat threads work in practice and avoids false flags\n// when the agent legitimately re-cites a file it read five turns ago.\n// - The manifest is built BEFORE the LLM turn (in run-thread) and shown\n// to the model in the system prompt. The model only has to write a\n// small marker `[3]` instead of a full URL — long-form LLM output is\n// much more reliable at emitting short stable tokens than at typing\n// exact paths in the middle of prose.\n// - Reuses anti_hallucination_model_config as the checker model so the\n// user only configures one cheap classifier model per agent.\n\nimport type { PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { getMessages } from \"@/lib/stores/threads\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { isSensitiveMemoryNamespace } from \"@/lib/crypto/sensitive\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport { getConfig } from \"@/lib/env/config\";\nimport os from \"node:os\";\n\nexport interface CitationClaim {\n text: string;\n marker: number | null;\n link: string | null;\n verified: boolean;\n reason: string;\n /** Load-bearing-ness as judged by the checker. The UI surfaces top-N\n * claims at `informational` strictness and uses this to colour the\n * reference panel. */\n impact: \"high\" | \"med\" | \"low\";\n}\n\nexport interface SourceManifestEntry {\n n: number;\n label: string;\n href: string;\n}\n\nexport interface CitationVerdict {\n checker_model: string;\n claims: CitationClaim[];\n unverified_links: string[];\n}\n\n// Tools whose calls/results contribute URLs or file paths to the visited\n// set. Anything not on this list is ignored — e.g. memory_read returns\n// stored notes, not external sources, so citing a memory hit as a \"source\"\n// shouldn't count as provenance.\n//\n// Split by phase: for listing/search tools (file_list, file_grep,\n// file_glob, file_stat) only the CALL args count — the agent visited\n// the directory, not every child path the listing returned. Without\n// this split, a single `file_list ~/Downloads` floods the manifest with\n// 50+ \"sources\" the agent never opened.\nconst SOURCE_PRODUCING_TOOLS_CALL = new Set([\n \"file_read\", \"file_edit\", \"file_multi_edit\", \"file_write\",\n \"file_list\", \"file_grep\", \"file_glob\", \"file_stat\",\n \"web_search\", \"fetch_webpage\", \"web_fetch\",\n]);\nconst SOURCE_PRODUCING_TOOLS_RESULT = new Set([\n \"file_read\", \"file_edit\", \"file_multi_edit\", \"file_write\",\n \"web_search\", \"fetch_webpage\", \"web_fetch\",\n]);\n\n// Strip query/fragment for URLs and normalize backslashes for paths so a\n// citation that drops `?utm=...` or uses forward slashes on Windows still\n// matches the visited entry. Also fold `~/...` to the resolved home dir\n// so `~/Downloads/x` and `C:\\Users\\andre\\Downloads\\x` de-dupe.\nexport function normalizeSource(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) return \"\";\n if (/^https?:\\/\\//i.test(trimmed)) {\n try {\n const u = new URL(trimmed);\n return `${u.protocol}//${u.host}${u.pathname}`.replace(/\\/+$/, \"\").toLowerCase();\n } catch {\n return trimmed.toLowerCase();\n }\n }\n let normalized = trimmed.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\"~/\") || normalized === \"~\") {\n try {\n const home = os.homedir().replace(/\\\\/g, \"/\");\n normalized = normalized === \"~\" ? home : home + normalized.slice(1);\n } catch { /* fall through */ }\n }\n return normalized.replace(/\\/+$/, \"\").toLowerCase();\n}\n\n/**\n * Extract every URL or path referenced by the given tool events. Walks\n * both call payloads (arguments the agent passed, e.g. file_read.path)\n * and result payloads (URLs the search engine returned). Returns a Set\n * of normalized source strings.\n */\nexport function extractSourcesFromEvents(events: readonly PersistedToolEvent[]): Set<string> {\n const out = new Set<string>();\n for (const ev of events) {\n const allow = ev.phase === \"call\"\n ? SOURCE_PRODUCING_TOOLS_CALL\n : SOURCE_PRODUCING_TOOLS_RESULT;\n if (!allow.has(ev.name)) continue;\n collectStringsFromPayload(ev.payload, out);\n }\n return out;\n}\n\n/**\n * Build the per-thread visited-source set: every file path / URL the\n * agent has touched via tool calls across the full thread history,\n * unioned with the just-produced events.\n */\nexport function extractVisitedSources(\n thread_id: string,\n freshEvents: readonly PersistedToolEvent[],\n): Set<string> {\n const out = extractSourcesFromEvents(freshEvents);\n for (const m of getMessages(thread_id)) {\n if (!m.tool_events) continue;\n let parsed: unknown;\n try { parsed = JSON.parse(m.tool_events); } catch { continue; }\n if (!Array.isArray(parsed)) continue;\n const events = parsed.filter((e): e is PersistedToolEvent =>\n !!e && typeof e === \"object\" && typeof (e as { name?: unknown }).name === \"string\",\n );\n for (const s of extractSourcesFromEvents(events)) out.add(s);\n }\n return out;\n}\n\n/**\n * Pull every markdown link target out of the assistant text. Kept for\n * back-compat and as a useful primitive; the new marker-based flow uses\n * extractCitedMarkers instead.\n */\nexport function extractCitedLinks(text: string): string[] {\n if (!text) return [];\n const out = new Set<string>();\n const re = /\\[[^\\]]*\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const href = m[1].trim();\n if (href) out.add(href);\n }\n return Array.from(out);\n}\n\n/**\n * Pull every numeric marker (`[1]`, `[12]`) out of the assistant text.\n * Skips reference-link tails like `[label][1]` via the lookbehind so the\n * checker doesn't misread accidental markdown reference-link syntax as a\n * citation marker. Returns unique numbers in first-seen order.\n */\nexport function extractCitedMarkers(text: string): number[] {\n if (!text) return [];\n const out = new Set<number>();\n const re = /(?<!\\])\\[(\\d+)\\]/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const n = parseInt(m[1], 10);\n if (Number.isFinite(n) && n > 0) out.add(n);\n }\n return Array.from(out);\n}\n\n/**\n * Build the numbered source manifest the agent will see in its system\n * prompt. Takes the visited-sources set (insertion-ordered ≈ chronological\n * because both Set and the events that filled it preserve order) and\n * returns the most-recent `max` entries numbered 1..N.\n *\n * Most-recent rather than first-N because old sources are less likely to\n * still be relevant on long threads; a tight cap keeps the prompt cheap.\n */\nexport function buildSourceManifest(\n visited: ReadonlySet<string>,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0 || visited.size === 0) return [];\n const all = Array.from(visited);\n const tail = all.slice(-max);\n return tail.map((href, i) => ({\n n: i + 1,\n label: labelForSource(href),\n href,\n }));\n}\n\nfunction labelForSource(href: string): string {\n if (href.startsWith(\"http://\") || href.startsWith(\"https://\")) {\n try {\n const u = new URL(href);\n const path = u.pathname.replace(/\\/$/, \"\");\n return `${u.hostname}${path}`;\n } catch { return href; }\n }\n return href;\n}\n\n/** Public re-export so callers building a manifest outside this module\n * (e.g. run-thread's post-turn refresh) use the same labeling rules. */\nexport const labelForCitedSource = labelForSource;\n\n/**\n * Pull prior assistant turns in this thread into citable manifest entries.\n * Used at all strictness levels (when citations are enabled). Each entry's\n * `href` is a `#msg-<id>` anchor the UI can scroll to; the label is a short\n * timestamp (\"12m ago\") so the agent has something readable to reference.\n *\n * Returns the most-recent `max` assistant turns, oldest-first so a later\n * `buildSourceManifest` call's \"tail = recent\" semantics keeps stable\n * numbering even as new turns land.\n */\nexport function extractPriorDialogSources(\n thread_id: string,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0) return [];\n const all = getMessages(thread_id);\n const assistant = all.filter((m) => m.role === \"assistant\" && (m.content ?? \"\").trim().length > 0);\n const tail = assistant.slice(-max);\n const nowMs = Date.now();\n return tail.map((m, i) => {\n const ts = Date.parse(m.created_at);\n const ageMs = Number.isFinite(ts) ? Math.max(0, nowMs - ts) : 0;\n return {\n n: i + 1,\n label: `Earlier in thread (${formatAge(ageMs)})`,\n href: `#msg-${m.msg_id}`,\n };\n });\n}\n\nfunction formatAge(ms: number): string {\n if (ms < 60_000) return \"just now\";\n const min = Math.round(ms / 60_000);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n return `${day}d ago`;\n}\n\n/**\n * Pull memory items into citable manifest entries. Memory is durable user\n * context (preferences, learned facts, scheduled-task state), so making\n * them citable lets the agent ground answers like \"as you mentioned last\n * week, …\" with a verifiable reference.\n *\n * Scope: most-recently-updated `max` items across all non-sensitive\n * namespaces. Sensitive namespaces are skipped — `listMemory(undefined)`\n * already decrypts them but exposing them in the system prompt and the\n * UI references panel would defeat the at-rest encryption (ADR-0005).\n */\nexport function extractMemorySources(max: number): SourceManifestEntry[] {\n if (max <= 0) return [];\n const items = listMemory(undefined, undefined, max);\n return items\n .filter((m) => !isSensitiveMemoryNamespace(m.namespace))\n .map((m, i) => ({\n n: i + 1,\n label: `Memory: ${m.namespace}/${m.key}`,\n href: `memory://${m.namespace}/${m.key}`,\n }));\n}\n\n/**\n * Pull every `delegate_to_agent` tool result in the thread into citable\n * manifest entries. The parent agent's reply often paraphrases the\n * delegate's answer (\"Postman says today's agenda is …\") — without this\n * bucket those claims have no matching source and the agent has nothing\n * legal to cite, so it just omits the marker entirely.\n *\n * Each entry's label is `{delegate_name} replied ({age})`; the href\n * points to the persisted-event anchor inside the parent message so the\n * UI can scroll to the delegate tool card and the user can expand it.\n */\nexport function extractDelegateSources(\n thread_id: string,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0) return [];\n type DelegateHit = { agent: string; createdAt: string; msgId: string; eventId: string };\n const hits: DelegateHit[] = [];\n for (const m of getMessages(thread_id)) {\n if (!m.tool_events) continue;\n let parsed: unknown;\n try { parsed = JSON.parse(m.tool_events); } catch { continue; }\n if (!Array.isArray(parsed)) continue;\n for (const ev of parsed) {\n if (!ev || typeof ev !== \"object\") continue;\n const e = ev as { id?: unknown; name?: unknown; phase?: unknown; payload?: unknown };\n if (e.name !== \"delegate_to_agent\" || e.phase !== \"result\") continue;\n let payload: unknown = e.payload;\n if (typeof payload === \"string\") {\n try { payload = JSON.parse(payload); } catch { /* keep raw */ }\n }\n const p = (payload && typeof payload === \"object\") ? payload as Record<string, unknown> : null;\n if (!p || p.ok === false) continue;\n const agent = typeof p.agent_name === \"string\" ? p.agent_name : \"delegate\";\n hits.push({\n agent,\n createdAt: m.created_at,\n msgId: m.msg_id,\n eventId: typeof e.id === \"string\" ? e.id : \"\",\n });\n }\n }\n const tail = hits.slice(-max);\n const nowMs = Date.now();\n return tail.map((h, i) => {\n const ts = Date.parse(h.createdAt);\n const ageMs = Number.isFinite(ts) ? Math.max(0, nowMs - ts) : 0;\n return {\n n: i + 1,\n label: `${h.agent} replied (${formatAge(ageMs)})`,\n href: `#msg-${h.msgId}`,\n };\n });\n}\n\n/**\n * Combine THIS TURN's tool-visited sources + delegate replies + (optional)\n * memory items into one numbered manifest. Caller controls which buckets\n * to include via the per-bucket caps. Numbering is stable within the\n * turn (tools, delegates, memory in that order).\n *\n * Scope is intentionally THIS-TURN-ONLY for tool sources. A reply about\n * iCloud cleanup shouldn't surface the agent's 8-hour-old web_search\n * results for \"today's news\" — those are visible in their own reply's\n * panel and dragging them across turns drowns the panel in noise the\n * user has to mentally filter every time.\n *\n * Cross-turn signal (prior dialog, memory items) is OPT-IN via the\n * caller's cap setting. Default 0 = don't surface; the agent can still\n * cite earlier turns by writing a markdown link with the `#msg-…` anchor\n * if it genuinely needs to.\n */\nexport function buildCombinedManifest(\n freshEvents: readonly PersistedToolEvent[],\n thread_id: string,\n caps: { tools: number; memory?: number; delegates?: number },\n): SourceManifestEntry[] {\n const toolsSet = extractSourcesFromEvents(freshEvents);\n const tools = buildSourceManifest(toolsSet, caps.tools);\n // Delegate replies from THIS turn only: walk freshEvents for delegate\n // tool-results and emit one entry per successful delegation. Older\n // delegations belong to their own turn's manifest.\n const delegates: SourceManifestEntry[] = [];\n if ((caps.delegates ?? 0) > 0) {\n for (const ev of freshEvents) {\n if (ev.name !== \"delegate_to_agent\" || ev.phase !== \"result\") continue;\n let payload: unknown = ev.payload;\n if (typeof payload === \"string\") {\n try { payload = JSON.parse(payload); } catch { /* keep raw */ }\n }\n const p = (payload && typeof payload === \"object\") ? payload as Record<string, unknown> : null;\n if (!p || p.ok === false) continue;\n const agent = typeof p.agent_name === \"string\" ? p.agent_name : \"delegate\";\n const childThread = typeof p.thread_id === \"string\" ? p.thread_id : \"\";\n delegates.push({\n n: 0,\n label: `${agent} replied`,\n href: childThread ? `?tab=threads&thread=${childThread}` : \"#\",\n });\n if (delegates.length >= (caps.delegates ?? 0)) break;\n }\n }\n const memory = (caps.memory ?? 0) > 0 ? extractMemorySources(caps.memory!) : [];\n void thread_id; // currently unused; reserved for future per-thread filters\n const merged = [...tools, ...delegates, ...memory];\n return merged.map((e, i) => ({ ...e, n: i + 1 }));\n}\n\n/**\n * Agent-declared references: an optional trailing fenced block\n * ```jarela-references` containing a JSON array of `{label, href}`\n * objects. The block is stripped from the persisted body, and each entry\n * is folded into the source manifest (deduped against tool-derived\n * entries by normalized href).\n *\n * Why: most modern LLMs handle structured side-channels (tool calls,\n * fenced JSON) more reliably than they handle \"remember to write [3]\n * after each claim\". Letting the agent declare its sources as a small\n * machine-readable list at the end of its reply gives us a high-signal\n * fallback when the agent didn't manage to put every link inline.\n *\n * Forgiving on malformed JSON / missing fields — the agent is allowed\n * to skip the block entirely, and a bad block is silently dropped (the\n * body still renders, just without the declared refs).\n */\nconst DECLARED_REFS_FENCE_RE = /\\n*```jarela-references\\s*\\n([\\s\\S]*?)\\n```[\\s\\n]*$/;\n\nexport interface DeclaredReference {\n label: string;\n href: string;\n}\n\nexport function extractDeclaredReferences(\n text: string,\n): { body: string; refs: DeclaredReference[] } {\n const m = DECLARED_REFS_FENCE_RE.exec(text);\n if (!m) return { body: text, refs: [] };\n let parsed: unknown;\n try {\n parsed = JSON.parse(m[1]);\n } catch {\n // Malformed JSON: leave the body untouched so the user at least sees\n // what the agent wrote, rather than silently dropping content.\n return { body: text, refs: [] };\n }\n if (!Array.isArray(parsed)) return { body: text, refs: [] };\n const refs: DeclaredReference[] = [];\n for (const item of parsed) {\n if (!item || typeof item !== \"object\") continue;\n const obj = item as Record<string, unknown>;\n const label = typeof obj.label === \"string\" ? obj.label.trim() : \"\";\n const href = typeof obj.href === \"string\" ? obj.href.trim() : \"\";\n if (label && href) refs.push({ label, href });\n }\n const body = text.slice(0, m.index).trimEnd();\n return { body, refs };\n}\n\n/**\n * Strip an in-progress `jarela-references` fence during streaming so the\n * user never sees raw JSON flash on screen between the opening fence and\n * the closing one. If the closing fence has arrived, defer to the full\n * parser via {@link extractDeclaredReferences}; otherwise cut everything\n * from the opening fence onward.\n */\nexport function stripStreamingDeclaredReferences(text: string): string {\n if (/```jarela-references[\\s\\S]*?\\n```/.test(text)) {\n return extractDeclaredReferences(text).body;\n }\n const idx = text.indexOf(\"```jarela-references\");\n if (idx < 0) return text;\n return text.slice(0, idx).trimEnd();\n}\n\n/**\n * Merge agent-declared refs into an existing manifest. Dedup is by\n * normalized href (same comparison the tool extractor uses), so an agent\n * that declares a URL the manifest already has gets de-duped silently\n * instead of double-listed. New refs are appended after existing ones\n * and renumbered.\n */\nexport function mergeDeclaredReferences(\n manifest: readonly SourceManifestEntry[],\n declared: readonly DeclaredReference[],\n): SourceManifestEntry[] {\n if (declared.length === 0) return [...manifest];\n const seen = new Set(manifest.map((e) => normalizeSource(e.href)));\n const merged = [...manifest];\n for (const d of declared) {\n const key = normalizeSource(d.href);\n if (key && seen.has(key)) continue;\n seen.add(key);\n merged.push({ n: 0, label: d.label, href: d.href });\n }\n return merged.map((e, i) => ({ ...e, n: i + 1 }));\n}\n\nconst SYSTEM_PROMPT = `You audit an assistant turn and list its FACTUAL CLAIMS, sorted by impact (most load-bearing first).\n\nYou will receive:\n- A numbered list of SOURCES the agent had available in this thread. Sources may be any of: a tool-visited file/URL, a memory item, or an earlier assistant turn in this thread.\n- The assistant text (or its trailing portion).\n\nThe agent cites a source by writing an inline marker like [3] right after the claim, where the number matches a row in the SOURCES list. A marker MAY appear mid-sentence or at the end of a sentence.\n\nFor each FACTUAL claim — a quoted number, file contents, API behavior, named fact (date, version, person), paraphrased finding, or a recap of a prior turn — emit one entry. IGNORE pure opinion, plans (\"I'll do X\"), conversational filler, and trivial syntactic glue.\n\nRank impact:\n- \"high\": load-bearing. The rest of the answer depends on this being right.\n- \"med\": meaningful but not load-bearing. Wrong would be misleading but not fatal.\n- \"low\": incidental. Wrong would be a minor blemish.\n\nSort by impact (high → med → low) within the array. Cap at 15 claims total; if more would qualify, keep the highest-impact 15 and drop the rest.\n\nFor each claim, report:\n- \"text\": short paraphrase of the claim (max 120 chars).\n- \"marker\": the integer the agent attached (e.g. 3 for [3]), or null if no marker.\n- \"impact\": one of \"high\" | \"med\" | \"low\".\n- \"verified\": true if marker is non-null AND that number is in the SOURCES list, else false.\n- \"reason\": one short sentence (max 120 chars) explaining the verdict.\n\nReply with EXACTLY one JSON object on one line, no surrounding prose, no markdown fence:\n\n{\"claims\":[{\"text\":\"...\",\"marker\":<integer-or-null>,\"impact\":\"high|med|low\",\"verified\":true|false,\"reason\":\"...\"}]}\n\nIf the turn has no factual claims (pure chitchat or plans), return {\"claims\":[]}.`;\n\nexport async function classifyCitations(\n assistantText: string,\n manifest: ReadonlyArray<SourceManifestEntry>,\n modelConfigName: string,\n signal?: AbortSignal,\n): Promise<CitationVerdict | null> {\n const cfgName = modelConfigName.trim();\n if (!cfgName) return null;\n const cfg = getModelConfig(cfgName);\n if (!cfg) return null;\n const params = getModelParams(cfg);\n\n let provider;\n try { provider = getProvider(cfg.provider); } catch { return null; }\n if (!provider.invoke) return null;\n\n // Tail the text so a 60KB turn doesn't blow the checker budget. Citations\n // are usually inline so any sub-window catches representative claims.\n // JARELA_CITATION_CHECKER_TAIL_CHARS=0 disables truncation entirely (use\n // when claims often appear early in long answers — costs more tokens).\n const tailBudget = getConfig().citationCheckerTailChars;\n const sent = tailBudget > 0 ? assistantText.slice(-tailBudget) : assistantText;\n const portionLabel = tailBudget > 0 && assistantText.length > tailBudget\n ? `trailing ${sent.length} chars of ${assistantText.length}`\n : `full ${sent.length} chars`;\n const sourcesList = manifest.map((e) => {\n const trailer = e.label === e.href ? \"\" : ` — ${e.href}`;\n return `[${e.n}] ${e.label}${trailer}`;\n }).join(\"\\n\");\n const userMsg = `Sources (${manifest.length}):\n${sourcesList || \"(none)\"}\n\nAssistant text (${portionLabel}):\n${sent}`;\n\n if (signal?.aborted) return null;\n let result;\n try {\n result = await provider.invoke(\n cfg.model_id,\n [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMsg },\n ],\n params,\n [],\n );\n } catch { return null; }\n\n const parsed = parseCitationVerdict(result?.text ?? \"\");\n if (!parsed) return null;\n // Resolve marker → manifest entry ourselves rather than trusting the LLM\n // for the membership decision — the LLM is good at extracting claims but\n // not at exact-integer set membership.\n const byN = new Map(manifest.map((e) => [e.n, e]));\n const claims = parsed.map((c) => {\n const marker = c.marker ?? null;\n const entry = marker !== null ? byN.get(marker) : undefined;\n const link = entry?.href ?? null;\n const verified = entry !== undefined;\n return { ...c, marker, link, verified };\n });\n // Stable sort by impact (high → med → low) so callers can slice the\n // top-N for the informational-strictness UI without re-sorting.\n const impactRank: Record<CitationClaim[\"impact\"], number> = { high: 0, med: 1, low: 2 };\n claims.sort((a, b) => impactRank[a.impact] - impactRank[b.impact]);\n return { checker_model: cfgName, claims, unverified_links: [] };\n}\n\n/**\n * Tolerant strict-JSON parser for the checker output. Returns null on any\n * shape mismatch so the caller can degrade to \"no metadata\". Parses both\n * `marker` (new manifest-based flow) and `link` (legacy free-form flow).\n */\nexport function parseCitationVerdict(text: string): CitationClaim[] | null {\n if (!text) return null;\n const stripped = text.replace(/```(?:json)?\\s*/gi, \"\").replace(/```/g, \"\").trim();\n const m = /\\{[^]*\"claims\"[^]*\\}/.exec(stripped);\n if (!m) return null;\n let parsed: unknown;\n try { parsed = JSON.parse(m[0]); } catch { return null; }\n if (!parsed || typeof parsed !== \"object\") return null;\n const claimsRaw = (parsed as { claims?: unknown }).claims;\n if (!Array.isArray(claimsRaw)) return null;\n const claims: CitationClaim[] = [];\n for (const item of claimsRaw) {\n if (!item || typeof item !== \"object\") continue;\n const r = item as Record<string, unknown>;\n const text = typeof r.text === \"string\" ? r.text.slice(0, 200) : \"\";\n if (!text) continue;\n const markerRaw = r.marker;\n const marker = typeof markerRaw === \"number\" && Number.isFinite(markerRaw) && markerRaw > 0\n ? Math.floor(markerRaw)\n : null;\n const link = typeof r.link === \"string\" && r.link.trim() ? r.link.trim() : null;\n const verified = r.verified === true;\n const reason = typeof r.reason === \"string\" ? r.reason.slice(0, 200) : \"\";\n const impactRaw = typeof r.impact === \"string\" ? r.impact.toLowerCase() : \"\";\n const impact: CitationClaim[\"impact\"] =\n impactRaw === \"high\" ? \"high\" : impactRaw === \"low\" ? \"low\" : \"med\";\n claims.push({ text, marker, link, verified, reason, impact });\n }\n return claims;\n}\n\nfunction collectStringsFromPayload(payload: unknown, out: Set<string>): void {\n if (!payload) return;\n if (typeof payload === \"string\") {\n const n = normalizeSource(payload);\n if (looksLikeSource(n)) out.add(n);\n return;\n }\n if (Array.isArray(payload)) {\n for (const item of payload) collectStringsFromPayload(item, out);\n return;\n }\n if (typeof payload === \"object\") {\n for (const v of Object.values(payload as Record<string, unknown>)) {\n collectStringsFromPayload(v, out);\n }\n }\n}\n\nfunction looksLikeSource(s: string): boolean {\n if (!s) return false;\n // URLs are bounded, single-line, no whitespace, no JSON syntax. Anything\n // longer than 2048 chars (browser-typical URL cap) is almost certainly a\n // tool-result payload dump and never a real source. Same for strings\n // that contain whitespace, control chars, or look like a JSON literal.\n if (s.length > 2048) return false;\n if (/[\\s\"'`<>{}]/.test(s)) return false;\n if (s.startsWith(\"{\") || s.startsWith(\"[\")) return false;\n // Asset / binary URLs: images, fonts, stylesheets, scripts, video,\n // audio, archives, favicons. fetch_webpage normalisation surfaces every\n // <img src> on the page; without this filter the references panel\n // drowns under CDN logos and profile thumbnails. Real content sources\n // are HTML or text, not assets.\n const assetExt = /\\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|tiff?|woff2?|ttf|otf|eot|css|js|mjs|map|mp4|webm|mov|m4v|avi|mkv|mp3|wav|ogg|m4a|flac|zip|tar|gz|rar|7z|pdf|epub)(?:\\?|#|$)/i;\n if (assetExt.test(s)) return false;\n // Image-CDN URLs without file extensions: services like dims.apnews.com,\n // images.unsplash.com, cloudinary, imgix, etc. encode transforms into\n // the URL path (`/resize/`, `/crop/`, `/strip/`, `/quality/`, `/fit/`,\n // `/format/`) and serve the rendered bytes off the trailing parameter.\n // No file extension to match — pattern-detect the path segments instead.\n if (/\\/(?:resize|crop|strip|quality|fit|format|trim|rotate|scale|smart|w_\\d+|h_\\d+|c_fill|q_\\d+)\\//i.test(s)) return false;\n if (s.startsWith(\"http://\") || s.startsWith(\"https://\")) return true;\n // Workspace-relative paths or URI-style refs picked up from file_*\n // tool args/results. Require a real path separator AND that the basename\n // has a recognisable extension. Drop bare directories — `~/Downloads`\n // isn't a citable source, only the files inside it are. This also\n // rejects sentence fragments like \"Earlier in thread (7h ago)\".\n if (s.startsWith(\"memory://\")) return true;\n const hasFileExt = /\\.[a-z0-9]{1,8}$/i.test(s);\n if (s.startsWith(\"file://\")) return hasFileExt;\n if (/^[a-z]:[\\\\/]/i.test(s)) return hasFileExt; // C:/ or C:\\\n if (s.startsWith(\"/\") || s.startsWith(\"./\") || s.startsWith(\"../\") || s.startsWith(\"~/\")) {\n return hasFileExt;\n }\n // Plain relative path: must contain `/` AND have a file extension.\n return /\\//.test(s) && hasFileExt;\n}\n","import { streamWithConfig } from \"@/lib/agents/llm\";\nimport { getConfig } from \"@/lib/env/config\";\nimport type { StreamChunk, StreamOptions } from \"@/lib/agents/base\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport { addMessage, getThread, setMessageMetadata, setThreadContextPin, touchThread, type PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { recordToolUsage } from \"@/lib/stores/tool-stats\";\nimport { getAgentConfig, getAgentTierProportions, getAgentTools, parseCitationStrictness, parseDelegateTargets } from \"@/lib/stores/agent-configs\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { recall, type RecalledMemory } from \"@/lib/embeddings\";\nimport { validateAssistantOutput } from \"@/lib/agents/output-validator\";\nimport { getDefaultModelConfig, getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport {\n buildHistoryWindow,\n buildSystemPrompt,\n resolveExperienceMode,\n type ThreadRunRequest,\n} from \"@/lib/agents/prepare\";\nimport { recordMessageUsage } from \"@/lib/stores/message-usage\";\nimport { getPricingTables, modelRatesFor, estimateCostUsd } from \"@/lib/stores/pricing\";\nimport { estimateTokens } from \"@/lib/agents/context-budget\";\nimport { classifyStall, resolveDetector } from \"@/lib/agents/hallucination-classifier\";\nimport {\n buildCombinedManifest,\n classifyCitations,\n extractCitedMarkers,\n extractDeclaredReferences,\n mergeDeclaredReferences,\n type SourceManifestEntry,\n} from \"@/lib/agents/citation-checker\";\n\nexport type { ThreadRunRequest } from \"@/lib/agents/prepare\";\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\nexport interface PreparedThreadRun {\n stream: AsyncIterable<StreamChunk>;\n thread_id: string;\n // Snapshot of how the per-turn context window was allocated and consumed.\n // Forwarded to `persistAssistantMessage` so message_usage carries the\n // per-tier breakdown the chat UI uses for its diagnostic context bar.\n context_snapshot?: ContextUsageSnapshot;\n // Numbered source manifest shown to the agent for this turn (when\n // `citation_strictness` is not `off`). Forwarded to `persistAssistantMessage`\n // so the EXACT list the agent saw is persisted with the message — the\n // chat UI uses it to resolve inline `[N]` markers to clickable links,\n // and the citation checker uses it to score marker validity. Empty when\n // the flag is off.\n source_manifest?: SourceManifestEntry[];\n}\n\nexport interface ContextUsageSnapshot {\n context_window_tokens: number;\n hot_tokens: number;\n warm_tokens: number;\n facts_tokens: number;\n overhead_tokens: number;\n hot_budget_tokens: number;\n warm_budget_tokens: number;\n facts_budget_tokens: number;\n}\n\n// JARELA_MAX_STALL_RETRIES / JARELA_MAX_TRANSIENT_RETRIES override these.\n// Read fresh per turn so non-restart-required reloads take effect.\nfunction maxStallRetries(): number { return getConfig().maxStallRetries; }\nfunction maxTransientRetries(): number { return getConfig().maxTransientRetries; }\n\n// Hard cap on how deep an A → B → C delegation chain can go via the\n// `delegate_to_agent` built-in tool. Public callers start at depth 0; the\n// delegate tool increments before recursively invoking prepareThreadRun. At\n// depth >= MAX_DELEGATION_DEPTH the tool refuses with `depth_exceeded` so a\n// mis-configured agent network can't runaway.\nexport const MAX_DELEGATION_DEPTH = 2;\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 function snapshotThreadModelConfigName(thread_id: string): string | null {\n const thread = getThread(thread_id);\n if (!thread) return null;\n\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) return null;\n\n return agentCfg.model_config_name ?? getDefaultModelConfig()?.name ?? null;\n}\n\n/**\n * Per-turn entry point. Validates the request, persists the user message,\n * builds the history window + system prompt, kicks off the LLM stream, and\n * wraps the result in `stallRetryStream` so flagged turns can auto-retry.\n *\n * The 7-positional-arg version was refactored into the `ThreadRunRequest`\n * shape in ADR-0039. Internal control fields are `_`-prefixed; public\n * callers leave them undefined.\n */\nexport async function prepareThreadRun(req: ThreadRunRequest): 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(req.thread_id);\n if (!thread) throw new RunThreadError(404, \"Thread not found\", \"thread_not_found\");\n\n const trimmed = req.message.trim();\n if (!trimmed && !req.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 // Persist the user turn (including any attachments) before the LLM stream\n // so reload-mid-stream still shows the prompt. The stall-retry path sets\n // `_skip_persist_message` to keep its synthetic `↻ Auto-retry: …` nudges\n // out of the durable history — otherwise every nudge becomes a permanent\n // user-role row that the LLM mistakes for real user input on every future\n // turn.\n const content: string | ContentPart[] =\n req.attachments?.length ? [{ type: \"text\", text: trimmed }, ...req.attachments] : trimmed;\n const stored = typeof content === \"string\" ? content : JSON.stringify(content);\n if (!req._skip_persist_message) {\n addMessage(req.thread_id, \"user\", stored, undefined, req.user_category ?? null);\n touchThread(req.thread_id, trimmed.slice(0, 80) || undefined);\n }\n\n // Resolve model config + provider params (for both the live stream and\n // the warm-summary recursion inside buildHistoryWindow).\n const modelConfigName = req._pinned_model_config_name\n ?? agentCfg.model_config_name\n ?? getDefaultModelConfig()?.name\n ?? null;\n const modelCfg = modelConfigName ? getModelConfig(modelConfigName) : null;\n const baseProviderParams = getModelParams(modelCfg);\n\n // ADR-0043 — per-agent override of context_tier_proportions. The agent's\n // value, when set, replaces the model's default for THIS run only; the\n // stream LLM call below still uses the unmodified params. Splitting them\n // keeps the override scoped to the budget computation.\n const agentTierProportions = getAgentTierProportions(agentCfg);\n const providerParams = agentTierProportions\n ? { ...baseProviderParams, context_tier_proportions: agentTierProportions }\n : baseProviderParams;\n\n // ADR-0042. Persist the user-chosen boundary before we build the window so\n // the history fetch and the cached-summary lookup both see the same pin.\n // `null` clears the pin; `undefined` leaves whatever's already on the row.\n if (req.hot_since !== undefined) {\n setThreadContextPin(req.thread_id, req.hot_since);\n }\n const effectiveHotSince = req.hot_since !== undefined ? req.hot_since : (thread.hot_since ?? null);\n\n const historyWindow = await buildHistoryWindow(\n req.thread_id,\n agentCfg,\n providerParams,\n trimmed,\n { providerName: modelCfg?.provider, modelId: modelCfg?.model_id },\n effectiveHotSince,\n );\n\n const allowedTools = getAgentTools(agentCfg);\n const delegateRosterLines = buildDelegateRoster(agentCfg, allowedTools);\n\n // Recall is best-effort: cap on RECALL_BUDGET_MS so a cold embeddings\n // round-trip doesn't block the LLM stream from starting.\n const oldestInWindow = historyWindow.history.length > 0\n ? contentText(historyWindow.history[0].content)\n : null;\n const rawRecallCtx = req.context_profile && req.context_profile.include_recall === false\n ? \"\"\n : await raceWithBudget(\n buildRecallContext(req.thread_id, trimmed, oldestInWindow),\n RECALL_BUDGET_MS,\n \"\",\n );\n\n // Apply the per-category context profile (see lib/agents/turn-profile.ts).\n // The toggles fire AFTER buildHistoryWindow so the budget snapshot still\n // shows what we *would have* spent on hot/warm — useful when debugging\n // why an extension turn answered with the field's own context only.\n const profile = req.context_profile;\n // include_hot=false strips PRIOR thread history but must keep the current\n // turn's user message, otherwise the LLM is called with only a system\n // prompt (e.g. Gemini rejects with \"contents is not specified\").\n const effectiveHistory = profile && profile.include_hot === false\n ? [{ role: \"user\" as const, content }]\n : historyWindow.history;\n const effectiveWarmSummary = profile && profile.include_warm === false\n ? \"\"\n : historyWindow.warmSummaryCtx;\n const effectiveFacts = profile && profile.include_facts === false\n ? \"\"\n : historyWindow.factsCtx;\n const recallCtx = rawRecallCtx;\n\n // Numbered source manifest, shown to the agent for `[N]` markers and\n // persisted on the assistant row so the chat UI can resolve markers →\n // clickable links/anchors. Built from every source the agent has touched\n // in this thread (tool calls), plus the user's memory items, plus prior\n // assistant turns — see ADR-0044. Empty (and the prompt block becomes a\n // \"no sources yet\" note) when strictness is `off` or the thread is fresh.\n // Pre-turn manifest: empty in practice. The agent hasn't called any\n // tools yet on this turn, so there are no `[N]` numbers it could\n // attach. Citations for THIS turn happen in two ways:\n // 1. Mid-prose markdown links `[label](https://…)` for sources the\n // agent fetches while drafting (web_search/web_fetch/file_read\n // results it just got back).\n // 2. Numeric `[N]` markers resolved AFTER the turn finishes — the\n // post-turn manifest refresh in `persistAssistantMessage` appends\n // this-turn tool + delegate sources and numbers them.\n // Old design dragged in every source from every prior turn in the\n // thread plus 10 memory items plus 10 dialog anchors — produced a\n // 38-entry panel of mostly-irrelevant noise on every reply. Dropped.\n const strictness = parseCitationStrictness(agentCfg.citation_strictness) ?? \"off\";\n const sourceManifest: SourceManifestEntry[] = [];\n void strictness; // strictness is read again at persist-time\n\n const systemPrompt = buildSystemPrompt({\n agentCfg,\n trimmedMessage: trimmed,\n budget: historyWindow.budget,\n recallCtx,\n warmSummaryCtx: effectiveWarmSummary,\n factsCtx: effectiveFacts,\n experienceMode: resolveExperienceMode(req.options),\n delegateRosterLines,\n sourceManifest,\n });\n\n const delegationDepth = req._delegation_depth ?? 0;\n const delegationAncestors = req._delegation_ancestors ?? [];\n const streamOpts: StreamOptions = {\n ...req.options,\n agent_run_config: {\n system_prompt: systemPrompt,\n allowed_tools: allowedTools,\n model_config_name: modelConfigName,\n delegation: delegationDepth > 0 || delegationAncestors.length > 0\n ? { depth: delegationDepth, ancestors: delegationAncestors }\n : undefined,\n },\n };\n\n // Stall-retry path: the nudge needs to reach the LLM but isn't (and\n // shouldn't be) in the DB. Append it to the in-memory history just for\n // this LLM call. Use the structured `content` form (not the JSON-\n // stringified fallback) so attachments survive into the LLM call.\n const finalHistory = req._inject_message_into_history\n ? [...effectiveHistory, { role: \"user\" as const, content }]\n : effectiveHistory;\n\n const rawStream = streamWithConfig(req.thread_id, finalHistory, streamOpts, req.signal);\n const retriesLeft = req._stall_retries_left ?? maxStallRetries();\n // Overhead = the assembled system prompt + per-message scaffolding, which\n // is more accurate than the budget's static overhead allowance.\n const overheadTokens = estimateTokens(systemPrompt);\n return {\n stream: stallRetryStream(rawStream, req, allowedTools, retriesLeft),\n thread_id: req.thread_id,\n context_snapshot: {\n context_window_tokens: historyWindow.budget.contextWindowTokens,\n hot_tokens: profile && profile.include_hot === false ? 0 : historyWindow.tierUsage.hot_tokens,\n warm_tokens: profile && profile.include_warm === false ? 0 : historyWindow.tierUsage.warm_tokens,\n facts_tokens: profile && profile.include_facts === false ? 0 : historyWindow.tierUsage.facts_tokens,\n overhead_tokens: overheadTokens,\n hot_budget_tokens: historyWindow.budget.tierBudgets.hot,\n warm_budget_tokens: historyWindow.budget.tierBudgets.warm,\n facts_budget_tokens: historyWindow.budget.tierBudgets.facts,\n },\n source_manifest: sourceManifest.length > 0 ? sourceManifest : undefined,\n };\n}\n\n/**\n * Build the `--- Available delegates ---` block lines for the system prompt\n * when the agent has the `delegate_to_agent` tool allowed and at least one\n * resolvable delegate target. Empty array short-circuits the block.\n */\nfunction buildDelegateRoster(\n agentCfg: { delegate_targets?: string | null },\n allowedTools: readonly string[],\n): string[] {\n const delegateIds = parseDelegateTargets(agentCfg.delegate_targets);\n if (delegateIds.length === 0) return [];\n if (!allowedTools.includes(\"delegate_to_agent\")) return [];\n\n return delegateIds\n .map((id) => {\n const child = getAgentConfig(id);\n if (!child) return null;\n const firstLine = (child.identity || child.instructions || \"\").split(\"\\n\")[0].slice(0, 120);\n return ` - ${child.id} — ${child.name}${firstLine ? `: ${firstLine}` : \"\"}`;\n })\n .filter((s): s is string => Boolean(s));\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 originalReq: ThreadRunRequest,\n allowedTools: readonly string[],\n retriesLeft: number,\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 // Track (name, args) signatures within the turn so we can detect a\n // ReAct loop where the model spins on the same tool call. Counts\n // increment only on tool_call chunks; tool_result echoes are ignored.\n const signatureCounts = new Map<string, number>();\n let loopedToolName: string | null = null;\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 data = chunk.data as { name?: unknown; arguments?: unknown } | undefined;\n const name = typeof data?.name === \"string\" ? data.name : \"\";\n const args = data?.arguments && typeof data.arguments === \"object\"\n ? (data.arguments as Record<string, unknown>)\n : {};\n if (name) {\n toolNames.push(name);\n const sig = toolCallSignature(name, args);\n const count = (signatureCounts.get(sig) ?? 0) + 1;\n signatureCounts.set(sig, count);\n if (count >= TOOL_LOOP_THRESHOLD && loopedToolName === null) {\n loopedToolName = name;\n // Leave a fingerprint so future loop incidents can be traced\n // to a specific provider/model — most often a sign the\n // aggregator's tool-use fidelity is poor (model narrates\n // \"writing now\" without emitting the corresponding tool_use\n // block).\n console.warn(\n `[stall-retry] tool-loop detected: tool=${name} repeats=${count} thread=${originalReq.thread_id}`,\n );\n yield chunk;\n break;\n }\n }\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 trimmedText = textBuf.trim();\n const isStallProse = trimmedText.length > 0 && looksLikeStall(trimmedText);\n // The original stall path: model produced narration but called nothing.\n const zeroToolStall = !sawError && toolNames.length === 0 && isStallProse;\n // The \"promised next-step\" path: model DID call read-only tools, ended\n // the turn with stall prose (\"Writing it now\", \"Saving the file now\"),\n // and never invoked a write-like tool. Real failure from the wild — the\n // read+narrate+stop loop slipped past the zero-tool gate.\n const promisedWriteStall =\n !sawError &&\n !zeroToolStall &&\n isStallProse &&\n toolNames.length > 0 &&\n !toolNames.some(isWriteLikeToolName);\n const regexStalled = zeroToolStall || promisedWriteStall;\n const looped = !sawError && loopedToolName !== null;\n\n // Anti-hallucination detector — picks ONE method per turn (regex or\n // model), based on the resolved per-agent (or global env) settings.\n // The classifier and the regex never run together; the model is more\n // accurate but adds latency + cost, the regex is fast but brittle.\n const agentCfg = getAgentConfig(originalReq.thread_id ? (getThread(originalReq.thread_id)?.agent_id ?? \"\") : \"\");\n const detector = resolveDetector(agentCfg);\n // Strict citation mode forces the stall classifier to model-based:\n // strict turns are higher-stakes, so the more accurate (but more\n // expensive) LLM judge is worth the extra round-trip. Falls back to\n // regex automatically if the agent has no checker model configured.\n const strictness = agentCfg ? parseCitationStrictness(agentCfg.citation_strictness) : null;\n if (strictness === \"strict\" && detector.modelConfigName) {\n detector.mode = \"model\";\n }\n let classifierStalled = false;\n let classifierReason = \"\";\n if (!sawError && !looped && detector.mode === \"model\") {\n const verdict = await classifyStall(textBuf, toolNames, detector.modelConfigName, originalReq.signal)\n .catch(() => null);\n if (verdict) {\n classifierStalled = verdict.stalled;\n classifierReason = verdict.reason;\n } else {\n // Classifier unavailable / errored / aborted — fall back to regex\n // for THIS turn so the agent isn't left ungovernable.\n console.warn(\n `[anti-hallucination] classifier unavailable, falling back to regex for thread ${originalReq.thread_id} (model=${detector.modelConfigName || \"<unset>\"})`,\n );\n }\n }\n\n // Effective stall verdict per the resolved mode:\n // off → no stall detection (whatever the regex thought, ignore)\n // regex → regex verdict\n // model → classifier verdict if we got one, else regex fallback\n const stalled =\n detector.mode === \"off\"\n ? false\n : detector.mode === \"regex\"\n ? regexStalled\n : (classifierStalled || (classifierReason === \"\" && regexStalled)); // \"model\" mode\n\n // Fabrication check (ADR-0037): only run when no other path claimed\n // this turn.\n const fabrication = !sawError && !stalled && !looped\n ? validateAssistantOutput(textBuf, toolNames, allowedTools)\n : ({ ok: true } as const);\n\n // Strict-mode citation audit. Runs ONLY at `citation_strictness === 'strict'`\n // when no earlier gate already claimed the turn — that's when we want to\n // catch hallucinated/uncited high-impact claims and force a correction\n // round. Standard / informational defer to the post-persist fire-and-\n // forget checker (no nudge, just surfacing). The audit is synchronous so\n // it adds one checker round-trip to strict turns; the cost is the price\n // of the stronger guarantee.\n let uncitedHighClaims: ReadonlyArray<{ text: string; reason: string; marker: number | null }> = [];\n if (\n !sawError && !stalled && !looped && fabrication.ok\n && agentCfg\n && parseCitationStrictness(agentCfg.citation_strictness) === \"strict\"\n && retriesLeft > 0\n && textBuf.trim().length > 0\n ) {\n const checkerModel = (agentCfg.anti_hallucination_model_config ?? \"\").trim();\n if (checkerModel) {\n // The audit grades against THIS turn's sources. We don't accumulate\n // tool-result payloads in this scope (only names + signatures for\n // loop detection), so the audit can only see what landed in the\n // text — pass an empty events array and let `classifyCitations`\n // judge purely on the markers/links in the prose. The post-persist\n // checker (which runs against the persisted manifest) catches\n // anything this scope misses.\n const auditManifest = buildCombinedManifest([], originalReq.thread_id, {\n tools: Math.max(0, getConfig().citationManifestMax - 10),\n delegates: 10,\n });\n try {\n const verdict = await classifyCitations(textBuf, auditManifest, checkerModel, originalReq.signal);\n if (verdict) {\n uncitedHighClaims = verdict.claims\n .filter((c) => c.impact === \"high\" && !c.verified)\n .map((c) => ({ text: c.text, reason: c.reason, marker: c.marker }));\n }\n } catch { /* audit failed — fall through, no retry */ }\n }\n }\n const citationFail = uncitedHighClaims.length > 0;\n\n if (!stalled && !looped && fabrication.ok && !citationFail) {\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. Each failure mode\n // gets its own reason-aware nudge.\n const nudge = looped\n ? `↻ Auto-retry: you called \\`${loopedToolName}\\` ${TOOL_LOOP_THRESHOLD}+ times in this turn with the same arguments without making progress. Either invoke a DIFFERENT tool to advance the task (for example, if you intend to write a file, call \\`file_write\\` now), or stop and explain what's blocking. Do NOT call \\`${loopedToolName}\\` again with the same arguments.`\n : promisedWriteStall\n ? `↻ Auto-retry: your reply ended with a 'writing/saving/creating ... now' style statement but you only called read-only tools (${[...new Set(toolNames)].slice(0, 6).join(\", \")}) — no write-like tool was invoked. Don't narrate the next step; CALL the actual write tool now (e.g. file_write, file_edit, memory_write). If you cannot, stop and explain why.`\n : zeroToolStall\n ? \"↻ 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 — just call the tool.\"\n : classifierStalled\n ? `↻ Auto-retry: the anti-hallucination classifier flagged your reply as a stall (${classifierReason || \"promise without a write tool\"}). Don't narrate the next step; either CALL the actual tool that fulfils what you promised, or stop and explain why you can't.`\n : citationFail\n ? `↻ Auto-retry: the citation audit flagged ${uncitedHighClaims.length} high-impact claim${uncitedHighClaims.length === 1 ? \"\" : \"s\"} without a verified source:\\n${uncitedHighClaims.slice(0, 5).map((c, i) => ` ${i + 1}. ${c.text}${c.reason ? ` — ${c.reason}` : \"\"}`).join(\"\\n\")}\\n\\nFix each one in exactly ONE of these three ways:\\n (a) cite an existing source from the manifest by appending the marker \\`[N]\\` to the claim,\\n (b) call a tool now (file_read, web_search, fetch_webpage, memory_read, …) to actually ground the claim before stating it,\\n (c) rephrase plainly — drop the specific number/fact, or say \"I don't have a source for this\" — so the claim is no longer load-bearing.\\n\\nDo NOT just restate the same claim. Do NOT invent a marker number that isn't in the manifest.`\n : `↻ Auto-retry: output validator flagged your reply. ${\"reason\" in fabrication ? fabrication.reason : \"\"} Redo this turn without the false claim — either call the actual tool, or rephrase as a proposal/question.`;\n\n const retry = await prepareThreadRun({\n ...originalReq,\n message: nudge,\n attachments: undefined,\n _stall_retries_left: retriesLeft - 1,\n // The nudge is in-memory only — never write it to `messages`. The\n // assistant's combined (original + ↻ + retry) text gets persisted\n // ONCE at end-of-turn via `persistAssistantMessage`, which is the\n // sole durable record of what happened. Without these flags the\n // nudge becomes a permanent user-role row the LLM mistakes for\n // user input on every future turn.\n _skip_persist_message: true,\n _inject_message_into_history: true,\n });\n for await (const chunk of retry.stream) yield chunk;\n}\n\nexport interface AssistantUsageSnapshot {\n input_tokens: number;\n output_tokens: number;\n // Anthropic prompt-cache breakdown (PR #181). Disjoint from input_tokens:\n // total billable input = input_tokens + cache_creation + cache_read,\n // priced at 1×, 1.25×, and 0.1× the input rate respectively.\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n provider: string;\n model_id: string;\n model_config_name: string | null;\n}\n\n// Footer appended to an assistant message that was cut off by the user\n// (Stop button or steer-while-streaming). Both human readers and the LLM\n// see this on the next turn — the agent treats it as \"the previous reply\n// was abandoned; the user's next message is the new direction\".\nexport const INTERRUPT_MARKER = \"*⏸ Interrupted by user.*\";\n\n/** Append the interrupt footer to a (possibly empty) partial reply. */\nexport function withInterruptMarker(partial: string): string {\n const trimmed = partial.trim();\n if (!trimmed) return INTERRUPT_MARKER;\n if (trimmed.endsWith(INTERRUPT_MARKER)) return trimmed;\n return `${trimmed}\\n\\n${INTERRUPT_MARKER}`;\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 usage?: AssistantUsageSnapshot | null,\n contextSnapshot?: ContextUsageSnapshot | null,\n sourceManifest?: readonly SourceManifestEntry[] | null,\n): void {\n const trimmed = content.trim();\n let final = trimmed;\n const toolList = usedTools ? Array.from(new Set(usedTools.filter(Boolean))) : [];\n // Skip stall + fabrication footers when the user explicitly interrupted\n // the run — the message wasn't a model stall, it was a deliberate stop,\n // and the interrupt marker already explains the cut to both reader and\n // the next agent turn.\n const wasInterrupted = trimmed.endsWith(INTERRUPT_MARKER);\n // Stall detector: model ended its turn with a promise-shaped tail but\n // either invoked no tool, OR called only read-only tools while\n // narrating a write. Both shapes look identical to the user — a chat\n // bubble that ends mid-task — so the warning footer covers both.\n // The retry budget (MAX_STALL_AUTO_RETRIES) is exhausted by the time\n // we hit this code path, so the footer is the user's manual recovery\n // affordance: \"Reply continue\".\n const isStallProse = !!trimmed && !wasInterrupted && looksLikeStall(trimmed);\n const noTool = toolList.length === 0;\n const noWriteTool = toolList.length > 0 && !toolList.some(isWriteLikeToolName);\n if (isStallProse && (noTool || noWriteTool)) {\n final = `${trimmed}\\n\\n*⚠️ Agent stalled — promised a next step but did not invoke a write tool. Reply \"continue\" to retry.*`;\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 && !wasInterrupted && !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 withoutAutoplay = stripAutoplayHints(final);\n // Split the optional trailing ```jarela-references` JSON block off the\n // body before persistence. The block is a machine-readable list of\n // {label, href} pairs the agent declared as its sources for this turn;\n // we merge it into the manifest below. The body stored in\n // messages.content is the clean prose without the fence.\n const { body: persisted, refs: declaredRefs } = extractDeclaredReferences(withoutAutoplay);\n if (persisted || (sanitizedEvents && sanitizedEvents.length > 0)) {\n const row = addMessage(thread_id, \"assistant\", persisted, sanitizedEvents, category);\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n recordToolUsage(sanitizedEvents, persisted);\n }\n // Persist the source manifest for THIS reply into the message's\n // metadata. The chat UI uses it to resolve inline `[N]` markers →\n // clickable links and to populate the References panel.\n //\n // Scope: ONLY this turn's tool events + this turn's delegate replies.\n // We deliberately don't include prior-turn sources, memory items, or\n // earlier-dialog anchors — each reply's panel must reflect what backs\n // THAT reply, otherwise the panel turns into a 40-entry haystack of\n // stale links from unrelated topics across the thread (real user\n // complaint, 2026-06-07: \"there are so many irrelevant citation\").\n //\n // The agent's mid-prose markdown links `[label](url)` need no\n // manifest entry — they linkify themselves.\n let manifest: SourceManifestEntry[] = [];\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n const strictness = agent ? parseCitationStrictness(agent.citation_strictness) ?? \"off\" : \"off\";\n if (strictness !== \"off\") {\n manifest = buildCombinedManifest(sanitizedEvents, thread_id, {\n tools: getConfig().citationManifestMax,\n delegates: 10,\n });\n }\n }\n // Fold the agent's declared refs into the manifest (dedup by\n // normalized href). These are appended after tool-derived entries\n // and renumbered. Skipped when strictness is `off` so off-mode\n // agents that ignore the fence don't suddenly get a References\n // panel (the strictness gate is the user's switch for this whole\n // feature).\n if (declaredRefs.length > 0) {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n const strictness = agent ? parseCitationStrictness(agent.citation_strictness) ?? \"off\" : \"off\";\n if (strictness !== \"off\") {\n manifest = mergeDeclaredReferences(manifest, declaredRefs);\n }\n }\n if (manifest.length > 0) {\n setMessageMetadata(row.msg_id, {\n citations: {\n checker_model: \"\",\n claims: [],\n unverified_links: [],\n sources: manifest.map((e) => ({ n: e.n, label: e.label, href: e.href })),\n },\n });\n }\n // Citation checker (fire-and-forget). Runs only when the agent's\n // `citation_strictness` is not `off`, the persisted text is non-empty,\n // the manifest is non-empty, and (at standard/informational levels)\n // the text actually carries at least one `[N]` marker to verify.\n // Strict mode skips the marker pre-check so the audit can flag\n // missing citations. Writes its verdict back into `messages.metadata`\n // alongside the manifest; the UI picks it up on the next refresh.\n // Any failure (timeout, parse error, missing checker model) leaves\n // the manifest in place and the message renders normally.\n if (persisted && manifest.length > 0) {\n void runCitationCheckerForRow(thread_id, row.msg_id, persisted, manifest);\n }\n // ADR-0041 wrote provider-reported token usage when available. The\n // per-tier context snapshot (hot/warm/facts/overhead) is computed\n // locally and is meaningful even when the provider didn't emit a\n // usage event (custom proxies, mid-stream errors, providers that\n // omit usage on tool turns), so persist the row whenever EITHER side\n // has data. The cost/rate columns simply stay null when there are\n // no provider tokens to price.\n const hasProviderUsage = !!(usage && (usage.input_tokens > 0 || usage.output_tokens > 0));\n if (hasProviderUsage || contextSnapshot) {\n try {\n const thread = getThread(thread_id);\n const agentId = thread?.agent_id ?? \"\";\n const agent = agentId ? getAgentConfig(agentId) : null;\n const agentName = agent?.name ?? agentId;\n const tables = getPricingTables();\n const rates = hasProviderUsage\n ? modelRatesFor(tables, usage!.provider, usage!.model_id)\n : { inputPer1M: null, outputPer1M: null };\n const cacheCreation = hasProviderUsage ? (usage!.cache_creation_input_tokens ?? 0) : 0;\n const cacheRead = hasProviderUsage ? (usage!.cache_read_input_tokens ?? 0) : 0;\n const cost = hasProviderUsage\n ? estimateCostUsd(usage!.input_tokens, usage!.output_tokens, rates, {\n cache_creation_input_tokens: cacheCreation,\n cache_read_input_tokens: cacheRead,\n })\n : 0;\n recordMessageUsage({\n message_id: row.msg_id,\n thread_id,\n agent_id: agentId,\n agent_name: agentName,\n provider: hasProviderUsage ? usage!.provider : \"\",\n model_id: hasProviderUsage ? usage!.model_id : \"\",\n model_config_name: hasProviderUsage ? usage!.model_config_name : null,\n input_tokens: hasProviderUsage ? usage!.input_tokens : 0,\n output_tokens: hasProviderUsage ? usage!.output_tokens : 0,\n input_rate_usd_per_mtok: rates.inputPer1M,\n output_rate_usd_per_mtok: rates.outputPer1M,\n cost_usd: cost,\n cache_creation_input_tokens: cacheCreation > 0 ? cacheCreation : null,\n cache_read_input_tokens: cacheRead > 0 ? cacheRead : null,\n tier_usage: contextSnapshot\n ? {\n hot_tokens: contextSnapshot.hot_tokens,\n warm_tokens: contextSnapshot.warm_tokens,\n facts_tokens: contextSnapshot.facts_tokens,\n overhead_tokens: contextSnapshot.overhead_tokens,\n hot_budget_tokens: contextSnapshot.hot_budget_tokens,\n warm_budget_tokens: contextSnapshot.warm_budget_tokens,\n facts_budget_tokens: contextSnapshot.facts_budget_tokens,\n context_window_tokens: contextSnapshot.context_window_tokens,\n }\n : null,\n });\n } catch (err) {\n console.error(\"[message_usage] snapshot failed\", err);\n }\n }\n }\n}\n\n/**\n * Fire-and-forget citation checker. Gated by the agent's\n * `citation_strictness` and the existence of a checker model. The checker\n * is intentionally permissive about failure — anything that goes wrong\n * (no model, provider throw, parse failure, timeout) leaves the manifest-\n * only metadata in place so the chat UI still renders `[N]` markers as\n * links.\n */\nasync function runCitationCheckerForRow(\n thread_id: string,\n msg_id: string,\n persistedText: string,\n sourceManifest: readonly SourceManifestEntry[],\n): Promise<void> {\n try {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n if (!agent) return;\n const strictness = parseCitationStrictness(agent.citation_strictness) ?? \"off\";\n if (strictness === \"off\") return;\n const checkerModel = (agent.anti_hallucination_model_config ?? \"\").trim();\n if (!checkerModel) return;\n // Strict mode runs the checker even when the agent emitted no markers\n // (it should have cited every claim — the audit will flag the\n // missing ones). Standard / informational skip the LLM round-trip\n // when there's literally nothing to verify, as a cost guard.\n if (strictness !== \"strict\" && extractCitedMarkers(persistedText).length === 0) return;\n const verdict = await classifyCitations(persistedText, sourceManifest, checkerModel);\n if (!verdict) return;\n setMessageMetadata(msg_id, {\n citations: {\n ...verdict,\n sources: sourceManifest.map((e) => ({ n: e.n, label: e.label, href: e.href })),\n },\n });\n } catch (err) {\n console.error(\"[citation-checker] failed\", err);\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 TOOL_LOOP_THRESHOLD = 3;\n\n// A \"write-like\" tool, by name, is one whose path segments contain a CRUD\n// verb. Per-segment match so e.g. `dataset_search` doesn't qualify on\n// `set`. Used to flag the \"called read-only tools then promised a write\"\n// stall pattern.\nconst WRITE_VERB_SEGMENTS = new Set([\n \"write\", \"edit\", \"create\", \"update\", \"delete\", \"move\", \"copy\", \"mkdir\",\n \"add\", \"insert\", \"patch\", \"post\", \"put\", \"send\", \"publish\", \"save\",\n \"upload\", \"transition\", \"rank\", \"merge\", \"set\", \"schedule\", \"cancel\",\n]);\n\nexport function isWriteLikeToolName(name: string): boolean {\n if (!name) return false;\n const segments = name.toLowerCase().split(/[._\\-/]+/).filter(Boolean);\n return segments.some((s) => WRITE_VERB_SEGMENTS.has(s));\n}\n\n// Stable signature of a tool call so repeated identical calls collapse to\n// the same key. JSON.stringify with sorted keys is good enough — the\n// argument shapes that matter here are small JSON objects, not graphs.\nexport function toolCallSignature(name: string, args: Record<string, unknown>): string {\n try {\n const sortedKeys = Object.keys(args).sort();\n const stable: Record<string, unknown> = {};\n for (const k of sortedKeys) stable[k] = args[k];\n return `${name}::${JSON.stringify(stable)}`;\n } catch {\n return `${name}::<unserializable>`;\n }\n}\n\n// Returns the FIRST tool name whose `(name, args)` signature appears\n// `threshold` or more times in `events`. Empty names and threshold <= 0\n// disable the check.\nexport function detectToolLoop(\n events: ReadonlyArray<{ name: string; args: Record<string, unknown> }>,\n threshold: number,\n): string | null {\n if (threshold <= 0) return null;\n const counts = new Map<string, number>();\n for (const ev of events) {\n if (!ev.name) continue;\n const sig = toolCallSignature(ev.name, ev.args);\n const c = (counts.get(sig) ?? 0) + 1;\n counts.set(sig, c);\n if (c >= threshold) return ev.name;\n }\n return null;\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 // Aspirational future-action family: \"Writing X now\", \"Saving the file\n // now\", \"Creating the report now\". Catches the read-only-tools +\n // narrate-the-write + end-of-turn loop where the model promises a\n // write but never invokes the corresponding tool.\n /\\b(writing|saving|creating|updating|deleting|adding|appending|generating|drafting|pushing|sending|posting|moving|copying|renaming|editing|regenerating)\\b[^.!?]*\\bnow\\b[!.]?\\s*$/i,\n // Broader promise-shape: any \"I'll <verb>\" or \"I will <verb>\" followed\n // by \"now\" anywhere in the trailing clause. Catches \"I will read it\n // now to understand the plan\" / \"I'll add the note now\" — variants the\n // narrow aspirational-verb list above misses because the verb is in\n // bare infinitive form and `now` is mid-sentence rather than at the\n // end.\n /\\b(?:i['’]?ll|i\\s+will)\\s+\\w+\\b[^.!?]*\\bnow\\b/i,\n // Present-continuous version: \"I'm reading … now to figure out …\" /\n // \"I am updating the dashboard now to reflect …\". Same idea, but the\n // model is narrating in progress rather than promising in future.\n // Same failure mode in practice — followed by no actual write call.\n /\\b(?:i['’]?m|i\\s+am)\\s+\\w+ing\\b[^.!?]*\\bnow\\b/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 const thread = getThread(thread_id);\n if (!thread) return [];\n const agentCfg = getAgentConfig(thread.agent_id);\n return getAgentTools(agentCfg);\n}\n\nexport function looksLikeStall(text: string): boolean {\n // Inspect the last paragraph / sentence — 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","// 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 { runAllHealthProbes } from \"@/lib/health/runner\";\nimport { isMasterKeyLocked } from \"@/lib/crypto/master-key\";\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// Probe integrations + LLM keys every Nth tick. 20 ticks × 30s = 10 min\n// — frequent enough that a freshly-expired token surfaces in roughly the\n// same window as a doc-source sweep, cheap enough that we don't hammer\n// the vendor /me endpoints. The health runner itself dedups alerts so\n// repeated failures only re-fire on its own (longer) backoff.\nconst HEALTH_SWEEP_EVERY_TICKS = 20;\n\ninterface SchedulerState {\n started: boolean;\n timer: NodeJS.Timeout | null;\n running: boolean;\n tickCount: number;\n healthTickCount: number;\n}\nconst state = getOrCreateGlobal<SchedulerState>(\"__jarela_scheduler\", () => ({\n started: false,\n timer: null,\n running: false,\n tickCount: 0,\n healthTickCount: 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 // Fire the first health probe immediately (instead of waiting 10min)\n // so a freshly-started server surfaces a broken token / unreachable\n // vendor on the first SSE subscription. Fire-and-forget; cheap.\n if (!isMasterKeyLocked()) {\n runAllHealthProbes().catch((err) => {\n console.error(\n \"[scheduler] initial health probe failed:\",\n err instanceof Error ? err.message : String(err),\n );\n });\n }\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 // Skip the entire tick while the at-rest key is locked (ADR-0063):\n // every encrypted store read would throw MasterKeyLockedError and\n // pollute the console. The tick resumes naturally once the user\n // unlocks via the splash.\n if (isMasterKeyLocked()) 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\n // Health probe sweep. Tracks integrations + LLM keys, publishes\n // health_alert notifications on state transitions. Runs out-of-band\n // from triggers so a slow vendor doesn't delay scheduled-task firing.\n state.healthTickCount = (state.healthTickCount + 1) % HEALTH_SWEEP_EVERY_TICKS;\n if (state.healthTickCount === 0) {\n runAllHealthProbes().catch((err) => {\n console.error(\n \"[scheduler] health probe 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\";\nimport type { AssistantUsageSnapshot } from \"@/lib/agents/run-thread\";\n\nexport interface CollectedRun {\n assistantContent: string;\n usedTools: string[];\n toolEvents: PersistedToolEvent[];\n terminal: \"done\" | \"error\";\n errorMessage?: string;\n // True when the run ended because the user hit Stop or steered. Distinct\n // from a generic stream error so persistence can mark the partial turn\n // with an interrupt footer instead of an error one — the next agent turn\n // reads the marker and knows the previous reply was cut, not stalled.\n aborted?: boolean;\n // ADR-0041: provider-reported token usage + model/provider snapshot from\n // the terminal `done` chunk. Undefined when the stream errored out before\n // a usage event arrived (or the provider didn't report one).\n usage?: AssistantUsageSnapshot;\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 data = chunk.data as { message?: unknown; code?: unknown };\n const msg = data?.message;\n if (typeof msg === \"string\") result.errorMessage = msg;\n if (data?.code === \"aborted\") result.aborted = true;\n return result;\n }\n case \"done\": {\n const d = chunk.data as {\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n source?: string;\n };\n provider?: string;\n model_id?: string;\n model_config_name?: string | null;\n };\n if (d?.usage && d.provider && d.model_id && d.usage.source === \"provider\") {\n result.usage = {\n input_tokens: d.usage.input_tokens ?? 0,\n output_tokens: d.usage.output_tokens ?? 0,\n cache_creation_input_tokens: d.usage.cache_creation_input_tokens ?? 0,\n cache_read_input_tokens: d.usage.cache_read_input_tokens ?? 0,\n provider: d.provider,\n model_id: d.model_id,\n model_config_name: d.model_config_name ?? null,\n };\n }\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 const name = err instanceof Error ? err.name : \"\";\n const msg = err instanceof Error ? err.message : String(err);\n result.errorMessage = msg;\n if (name === \"AbortError\" || /aborted/i.test(msg)) result.aborted = true;\n }\n\n return result;\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getMemory, putMemory, listMemory, deleteMemory } 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\nexport const memoryDeleteTool = tool(\n async ({ namespace, key }) => {\n const removed = deleteMemory(namespace, key);\n return JSON.stringify({ ok: true, namespace, key, removed });\n },\n {\n name: \"memory_delete\",\n description:\n \"Delete a single memory entry by namespace and key. Returns { removed: true } if a row was removed, { removed: false } if no matching row existed. Bulk deletion by namespace is not supported by this tool — list-then-delete-loop if needed.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace\"),\n key: z.string().describe(\"Key within the namespace\"),\n }),\n },\n);\n\nregisterTools(\"Memory\", \"read\", [memoryReadTool, memoryListTool]);\nregisterTools(\"Memory\", \"write\", [memoryWriteTool, memoryDeleteTool]);\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\", \"read\", [documentsSearch, documentsListSources]);\nregisterTools(\"Documents\", \"write\", [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\", \"write\", [\n documentsAddRemoteSource,\n documentsRemoveSource,\n documentsReindexSource,\n documentsIndexUrl,\n]);\n","// Safety mode for destructive built-in tools (exec + filesystem writes).\n//\n// Resolved once per call from `JARELA_TOOL_SAFETY`. Three tiers:\n//\n// \"safe\" — read-only. Exec accepts only an allowlisted set of\n// inspection commands (ls, git status, …); filesystem\n// tools refuse every write, edit, move, copy, delete,\n// or mkdir. Per-call `allow_unsafe` is IGNORED.\n// \"mostly_safe\" — default. Exec blocks the obviously-dangerous pattern\n// list (rm -rf /, shutdown, fork bomb, …); filesystem\n// tools refuse credential paths and the Jarela data dir.\n// Per-call `allow_unsafe=true` lifts the exec block for\n// that single call.\n// \"bypass\" — every guard off. For local development on a machine\n// you control and trust completely. NOT for use behind\n// a tunnel or with untrusted prompt sources.\n//\n// The mode is process-wide so prompt injection cannot escalate by\n// passing arguments — the LLM can only ever *downgrade* (via\n// `allow_unsafe=false` semantics, which is just \"don't try to bypass\").\n\nexport type SafetyMode = \"safe\" | \"mostly_safe\" | \"bypass\";\n\nexport function resolveSafetyMode(): SafetyMode {\n const raw = (process.env.JARELA_TOOL_SAFETY ?? \"\").trim().toLowerCase();\n if (raw === \"safe\") return \"safe\";\n if (raw === \"bypass\" || raw === \"unsafe\") return \"bypass\";\n return \"mostly_safe\";\n}\n\n// Inspection-only commands allowed in `safe` mode. Matched as the FIRST\n// token (after stripping leading whitespace) — pipelines, redirections,\n// command substitution, &&, ;, etc. are all rejected because we cannot\n// reason about what the right-hand side will do.\nconst SAFE_EXEC_ALLOWLIST = new Set([\n \"ls\", \"dir\", \"pwd\", \"cd\", \"echo\", \"cat\", \"type\", \"head\", \"tail\",\n \"wc\", \"stat\", \"file\", \"which\", \"where\", \"whoami\", \"hostname\",\n \"date\", \"uname\", \"df\", \"du\", \"ps\", \"env\", \"printenv\",\n \"git\", \"node\", \"npm\", \"npx\", \"deno\", \"python\", \"python3\", \"pip\", \"pip3\",\n]);\n\n// Subcommands considered read-only for tools that take a verb. We only\n// need to enumerate the dangerous tools here — anything not listed falls\n// back to \"the whole tool is read-only\" (e.g. `cat`, `ls`).\nconst SAFE_SUBCOMMANDS: Record<string, Set<string>> = {\n git: new Set([\n \"status\", \"log\", \"diff\", \"show\", \"blame\", \"branch\", \"tag\",\n \"remote\", \"ls-files\", \"ls-tree\", \"config\", \"rev-parse\",\n \"describe\", \"shortlog\", \"reflog\",\n ]),\n npm: new Set([\"ls\", \"list\", \"view\", \"info\", \"outdated\", \"config\", \"whoami\", \"ping\", \"doctor\"]),\n npx: new Set([]), // npx runs arbitrary code; never allow under \"safe\"\n node: new Set([]), // bare `node` opens a REPL; `node script.js` runs anything\n python: new Set([]),\n python3: new Set([]),\n deno: new Set([\"info\", \"doc\"]),\n pip: new Set([\"list\", \"show\", \"freeze\", \"config\"]),\n pip3: new Set([\"list\", \"show\", \"freeze\", \"config\"]),\n};\n\n// Shell metacharacters that compose commands or redirect IO. Their\n// presence in `safe` mode is grounds for rejection because the\n// allowlist check only inspects the first token.\nconst COMPOSER_RE = /[|&;`$<>]|\\$\\(|\\|\\||&&/;\n\nexport interface ExecAllowResult {\n allowed: boolean;\n reason?: string;\n}\n\nexport function checkExecAllowed(\n command: string,\n opts: { mode: SafetyMode; allowUnsafe?: boolean; blockedByPattern: boolean },\n): ExecAllowResult {\n if (opts.mode === \"bypass\") return { allowed: true };\n if (opts.mode === \"mostly_safe\") {\n if (opts.blockedByPattern && !opts.allowUnsafe) {\n return {\n allowed: false,\n reason:\n \"Command blocked by safety policy (mode=mostly_safe). Pass allow_unsafe=true only when you fully trust the command.\",\n };\n }\n return { allowed: true };\n }\n // safe mode\n const trimmed = command.trim();\n if (!trimmed) return { allowed: false, reason: \"command is required\" };\n if (COMPOSER_RE.test(trimmed)) {\n return {\n allowed: false,\n reason:\n \"safe mode rejects pipelines, redirection, command substitution, &&, and ;. \" +\n \"Set JARELA_TOOL_SAFETY=mostly_safe (or bypass) to allow composite commands.\",\n };\n }\n const tokens = trimmed.split(/\\s+/);\n const head = tokens[0]?.toLowerCase();\n if (!head || !SAFE_EXEC_ALLOWLIST.has(head)) {\n return {\n allowed: false,\n reason:\n `safe mode allows only inspection commands (${[...SAFE_EXEC_ALLOWLIST].sort().join(\", \")}). ` +\n \"Set JARELA_TOOL_SAFETY=mostly_safe to enable the broader policy.\",\n };\n }\n const subAllowlist = SAFE_SUBCOMMANDS[head];\n if (subAllowlist) {\n const sub = tokens[1]?.toLowerCase().replace(/^--?/, \"\");\n // Allow bare invocations that are themselves read-only (e.g. `git`\n // alone prints help). Reject if the subcommand is missing for tools\n // that need one to be safe (node/python/npx → arbitrary code).\n if (subAllowlist.size === 0) {\n return {\n allowed: false,\n reason: `safe mode refuses '${head}' because it can execute arbitrary code. Use mostly_safe or bypass.`,\n };\n }\n if (sub && !subAllowlist.has(sub)) {\n return {\n allowed: false,\n reason:\n `safe mode allows '${head}' only for: ${[...subAllowlist].sort().join(\", \")}. ` +\n \"Use mostly_safe or bypass for other subcommands.\",\n };\n }\n }\n return { allowed: true };\n}\n\n// File-system op classification.\nexport type FsOp = \"read\" | \"write\";\n\nexport function checkFsAllowed(\n op: FsOp,\n opts: { mode: SafetyMode },\n): ExecAllowResult {\n if (opts.mode === \"bypass\" || opts.mode === \"mostly_safe\") return { allowed: true };\n // safe mode: reads are fine, writes are not.\n if (op === \"read\") return { allowed: true };\n return {\n allowed: false,\n reason:\n \"safe mode refuses filesystem mutations (write/edit/move/copy/delete/mkdir). \" +\n \"Set JARELA_TOOL_SAFETY=mostly_safe to enable writes outside credential dirs.\",\n };\n}\n","// Per-thread workspace context for software-development agents.\n//\n// `workspace_init` registers a project root for the active thread; from\n// then on, every `file_*` and `local_exec` call with a relative path\n// resolves against that root instead of the user's HOME directory.\n//\n// State lives on globalThis under a Symbol so multiple module instances\n// (Next.js route bundles, dev HMR) share the same map. Same idempotency\n// pattern as lib/logging/sink.ts.\n//\n// Tools read the active workspace by passing the langchain tool config\n// through to `currentWorkspace(config)`. The config carries\n// `configurable.thread_id` set by the agent runner; tools invoked\n// outside a thread (live tests, ad-hoc CLI use) fall through to the\n// \"_default\" slot.\n\nexport interface WorkspaceContext {\n root: string;\n scoped: boolean;\n /** Set when initialised; useful for status output. */\n opened_at: number;\n}\n\nconst STATE_KEY: unique symbol = Symbol.for(\"@jarela/workspace-context\");\ntype GlobalWithWorkspace = typeof globalThis & {\n [STATE_KEY]?: Map<string, WorkspaceContext>;\n};\n\nfunction store(): Map<string, WorkspaceContext> {\n const g = globalThis as GlobalWithWorkspace;\n if (!g[STATE_KEY]) g[STATE_KEY] = new Map();\n return g[STATE_KEY]!;\n}\n\nconst DEFAULT_KEY = \"_default\";\n\n/** Langchain tool config shape (only the parts we care about). */\nexport interface ToolConfig {\n configurable?: {\n thread_id?: string;\n [k: string]: unknown;\n };\n}\n\nfunction keyFor(config?: ToolConfig): string {\n const tid = config?.configurable?.thread_id;\n return typeof tid === \"string\" && tid ? tid : DEFAULT_KEY;\n}\n\nexport function currentWorkspace(config?: ToolConfig): WorkspaceContext | undefined {\n return store().get(keyFor(config));\n}\n\nexport function setWorkspace(ws: WorkspaceContext, config?: ToolConfig): void {\n store().set(keyFor(config), ws);\n}\n\nexport function clearWorkspace(config?: ToolConfig): boolean {\n return store().delete(keyFor(config));\n}\n\n/** Test-only: wipe every registered workspace. */\nexport function _resetWorkspaceContext(): void {\n store().clear();\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\";\nimport { checkExecAllowed, resolveSafetyMode } from \"./safety\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\n\n// JARELA_EXEC_MAX_OUTPUT_BYTES overrides the output cap.\nfunction maxOutputBytes(): number { return getConfig().execMaxOutputBytes; }\n// Internal subprocess timeout. The agent's wall-clock budget on the tool\n// call (see lib/tools/wallclock.ts) is the primary deadline; this kills\n// the child process so a runaway shell can't keep burning CPU after the\n// wallclock abandons the promise.\nconst EXEC_DEFAULT_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 = maxOutputBytes()): { 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 workspaceRoot?: string;\n },\n): string {\n if (!command.trim()) {\n return JSON.stringify({ exit_code: 1, stderr: \"command is required\" });\n }\n\n const timeout = options.timeout_ms ?? EXEC_DEFAULT_TIMEOUT_MS;\n\n const mode = resolveSafetyMode();\n const gate = checkExecAllowed(command, {\n mode,\n allowUnsafe: options.allow_unsafe,\n blockedByPattern: isBlockedCommand(command),\n });\n if (!gate.allowed) {\n return JSON.stringify({ exit_code: 126, stderr: gate.reason, safety_mode: mode });\n }\n\n // Precedence: explicit options.cwd > active workspace root > process.cwd().\n // The workspace root takes priority over process.cwd() so the agent\n // doesn't have to thread `cwd` into every shell call once it's called\n // workspace_init.\n const cwd = options.cwd?.trim()\n ? options.cwd\n : options.workspaceRoot ?? 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: maxOutputBytes() * 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; signal?: string; code?: string; killed?: boolean };\n const out = clipOutput(String(e.stdout ?? \"\"));\n // Node's execSync surfaces a `timeout` kill as `signal: \"SIGTERM\"`\n // and/or `killed: true` with no exit status. Bare exit_code=1 +\n // empty stderr would lead the agent to retry the same command;\n // call out the timeout explicitly so it narrows scope or raises\n // timeout_ms instead.\n const timedOut = e.code === \"ETIMEDOUT\"\n || e.signal === \"SIGTERM\"\n || (e.killed === true && (e.status == null || e.status === 0));\n if (timedOut) {\n const errText = clipOutput(String(e.stderr ?? \"\"), 2_000);\n return JSON.stringify({\n exit_code: 124,\n stdout: out.value,\n stderr: errText.value,\n truncated: out.truncated || errText.truncated,\n cwd,\n timed_out: true,\n timeout_ms: timeout,\n error: `command timed out after ${Math.round(timeout / 1000)}s. Try a narrower scope, a smaller working set, or pass a larger timeout_ms.`,\n });\n }\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(\"Subprocess kill timeout in milliseconds (default 60000). Independent of the agent's wall-clock budget on this call.\"),\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 }, config?: ToolConfig) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe, workspaceRoot: currentWorkspace(config)?.root }),\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 }, config?: ToolConfig) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe, workspaceRoot: currentWorkspace(config)?.root }),\n {\n name: \"shell_exec\",\n description: \"Backward-compatible alias for local_exec.\",\n schema: execSchema,\n },\n);\n\nregisterTools(\"Shell\", \"execute\", [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\";\nimport { checkFsAllowed, resolveSafetyMode } from \"./safety\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\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\n// JARELA_FILES_MAX_READ_BYTES / JARELA_FILES_MAX_WRITE_BYTES override these.\n// MAX_LIST_JSON_BYTES isn't user-tunable: the cap exists to keep file_list\n// JSON inside one LLM context budget; raising it just shifts the failure.\nfunction maxReadBytes(): number { return getConfig().filesMaxReadBytes; }\nfunction maxWriteBytes(): number { return getConfig().filesMaxWriteBytes; }\nconst MAX_LIST_JSON_BYTES = 24_000;\n\n// Wall-clock deadline for a single fs.* call. Cloud-sync filesystem\n// providers (OneDrive, iCloud, Dropbox), network mounts, and aggressive\n// AV scanners can wedge fs.writeFile/readFile/mkdir indefinitely. Without\n// a deadline the agent loop just spins until the run-registry idle\n// watchdog (90s default) force-finishes the run with a generic \"run\n// timed out\" — the user never learns it was a stuck fs op. With this,\n// the deadline fires first and a structured error envelope tells the\n// agent (and the user) which path stalled.\n//\n// This is a hardcoded leak-prevention backstop. The agent-controlled\n// wall-clock budget on every tool call (see lib/tools/wallclock.ts) is\n// the primary deadline; this only fires when the wallclock is even\n// longer than the backstop (e.g. a 10-minute build that includes a\n// stuck file op).\nconst FS_DEADLINE_BACKSTOP_MS = 360_000;\nexport async function withFsDeadline<T>(\n label: string,\n abs: string,\n work: () => Promise<T>,\n deadlineMs: number = FS_DEADLINE_BACKSTOP_MS,\n): Promise<T> {\n const ms = deadlineMs;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\n `${label} on '${abs}' timed out after ${Math.round(ms / 1000)}s — the path may be on a stalled filesystem (cloud-sync provider, network mount, AV scanner). Try a different location.`,\n )), ms);\n });\n try {\n return await Promise.race([work(), timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\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.\n//\n// - `~` and `~/foo` always resolve against $HOME.\n// - Absolute paths are honoured verbatim.\n// - Bare relative paths resolve against `workspaceRoot` if one is set\n// (the agent called `workspace_init`), otherwise against $HOME.\n//\n// 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\"; the workspace root takes\n// priority once the agent has declared one.\nfunction resolvePath(p: string, workspaceRoot?: 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(workspaceRoot ?? os.homedir(), s);\n}\n\n/**\n * Resolver factory bound to the current tool call's workspace context.\n * Returns a `resolve()` that handles ~/abs/relative paths and enforces\n * `scoped: true` (absolute paths outside the workspace root are refused).\n */\nexport function pathResolverFor(config?: ToolConfig): {\n resolve: (p: string) => string;\n workspace?: ReturnType<typeof currentWorkspace>;\n} {\n const workspace = currentWorkspace(config);\n return {\n workspace,\n resolve: (p: string): string => {\n const abs = resolvePath(p, workspace?.root);\n if (workspace?.scoped && !isInside(abs, workspace.root)) {\n throw new Error(\n `refused: '${abs}' is outside the scoped workspace '${workspace.root}'. ` +\n `Call workspace_init with scoped=false to allow paths outside the project, or use a relative path.`,\n );\n }\n return abs;\n },\n };\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\nexport function assertSafePath(abs: string, op: \"read\" | \"write\"): void {\n const mode = resolveSafetyMode();\n const gate = checkFsAllowed(op, { mode });\n if (!gate.allowed) throw new Error(gate.reason);\n // bypass mode disables every guard, including the credential denylist.\n if (mode === \"bypass\") return;\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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"read\");\n const raw = await withFsDeadline(\"file_read\", abs, () => 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, maxReadBytes());\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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n const cap = maxWriteBytes();\n if (content.length > cap) {\n return JSON.stringify({ ok: false, path: abs, error: `content exceeds ${cap} bytes` });\n }\n assertSafePath(abs, \"write\");\n if (create_dirs !== false) {\n await withFsDeadline(\"file_write.mkdir\", path.dirname(abs), () => fs.mkdir(path.dirname(abs), { recursive: true }));\n }\n let existed = true;\n try {\n await withFsDeadline(\"file_write.access\", abs, () => fs.access(abs));\n } catch {\n existed = false;\n }\n await withFsDeadline(\"file_write\", abs, () => 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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"write\");\n const raw = await withFsDeadline(\"file_edit.read\", abs, () => 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 withFsDeadline(\"file_edit\", abs, () => 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 }, config?: ToolConfig) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n const { resolve } = pathResolverFor(config);\n srcAbs = resolve(source);\n dstAbs = resolve(destination);\n assertSafePath(srcAbs, \"write\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await withFsDeadline(\"file_move.stat\", srcAbs, () => 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 withFsDeadline(\"file_move.stat\", dstAbs, () => 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 withFsDeadline(\"file_move.stat\", dstAbs, () => 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 withFsDeadline(\"file_move.mkdir\", path.dirname(dstAbs), () => fs.mkdir(path.dirname(dstAbs), { recursive: true }));\n }\n await withFsDeadline(\"file_move\", srcAbs, () => 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 withFsDeadline(\"file_move.cp\", dstAbs, () => fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite }));\n await withFsDeadline(\"file_move.rm\", srcAbs, () => 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 }, config?: ToolConfig) => {\n let abs = dirPath;\n try {\n abs = pathResolverFor(config).resolve(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 withFsDeadline(\"file_list\", abs, () => 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 withFsDeadline(\"file_list.stat\", full, () => 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 }, config?: ToolConfig) => {\n let abs = dirPath;\n try {\n abs = pathResolverFor(config).resolve(dirPath);\n assertSafePath(abs, \"write\");\n await withFsDeadline(\"file_mkdir\", abs, () => 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 }, config?: ToolConfig) => {\n let abs = targetPath;\n try {\n abs = pathResolverFor(config).resolve(targetPath);\n assertSafePath(abs, \"write\");\n const st = await withFsDeadline(\"file_delete.stat\", abs, () => fs.stat(abs));\n if (st.isDirectory()) {\n if (!recursive) {\n // Try non-recursive rmdir first — succeeds only if empty.\n try {\n await withFsDeadline(\"file_delete.rmdir\", abs, () => 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 withFsDeadline(\"file_delete.rm\", abs, () => fs.rm(abs, { recursive: true, force: false }));\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"recursive\" });\n }\n await withFsDeadline(\"file_delete\", abs, () => 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 }, config?: ToolConfig) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n const { resolve } = pathResolverFor(config);\n srcAbs = resolve(source);\n dstAbs = resolve(destination);\n assertSafePath(srcAbs, \"read\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await withFsDeadline(\"file_copy.stat\", srcAbs, () => fs.stat(srcAbs));\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await withFsDeadline(\"file_copy.stat\", dstAbs, () => 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 withFsDeadline(\"file_copy.stat\", dstAbs, () => 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 withFsDeadline(\"file_copy.mkdir\", path.dirname(dstAbs), () => 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 withFsDeadline(\"file_copy.cp\", dstAbs, () => fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite }));\n } else {\n await withFsDeadline(\"file_copy\", dstAbs, () => 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 }, config?: ToolConfig) => {\n let abs = targetPath;\n try {\n abs = pathResolverFor(config).resolve(targetPath);\n const st = await withFsDeadline(\"file_stat\", abs, () => 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\", \"read\", [fileReadTool, fileListTool, fileStatTool]);\nregisterTools(\"Files\", \"write\", [\n fileWriteTool, fileEditTool, fileMoveTool, fileCopyTool, fileDeleteTool, fileMkdirTool,\n]);\n","// Search + bulk-edit tools for SWE agents.\n//\n// - `file_glob` — find files by glob pattern under a root (workspace-aware).\n// - `file_grep` — search file contents with a regex or literal, optionally\n// scoped to a glob. Replaces ad-hoc `rg`/`grep`/`Get-ChildItem`\n// calls through local_exec that break across shells.\n// - `file_multi_edit` — apply N anchored str_replace edits to one file in a\n// single transaction. All edits must apply cleanly or none do.\n//\n// All three honour the active workspace from workspace-context: bare\n// relative paths and glob roots resolve against the workspace root if\n// one is open. The credential-file denylist applies to every match.\n\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\nimport { pathResolverFor, assertSafePath, withFsDeadline } from \"./files\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// ---------------------------------------------------------------------------\n// Limits.\n//\n// Capped to keep one tool call inside an LLM context budget. file_grep\n// returns at most MAX_MATCHES across at most MAX_FILES_SCANNED — if the\n// agent's pattern is too broad, it gets a `truncated: true` hint and an\n// instruction to narrow.\n// ---------------------------------------------------------------------------\nconst MAX_FILES_SCANNED = 5_000; // hard cap on files visited\nconst MAX_MATCHES = 200; // hard cap on grep hits returned\nconst MAX_LINE_BYTES = 2_000; // truncate any matched line longer than this\nconst MAX_GLOB_RESULTS = 1_000; // hard cap on file_glob returns\nconst MAX_MULTI_EDITS = 50; // hard cap on edits per multi_edit call\nconst MAX_GREP_FILE_BYTES = 1_000_000; // skip files larger than ~1 MB (likely binary or vendored)\n\n// Directories we never recurse into — same list as workspace_init's tree\n// walker. Keeps grep snappy on real projects.\nconst DEFAULT_IGNORE = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"out\",\n \"coverage\", \"__pycache__\", \"target\", \"vendor\", \".venv\", \"venv\",\n \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\n// ---------------------------------------------------------------------------\n// Tiny glob compiler.\n//\n// Supports the subset the agent actually needs: `*` (any chars except /),\n// `**` (any chars including /), `?` (single non-/ char), and `{a,b,c}`\n// alternation. No bracket character classes — they're rarely useful at\n// this level and add escaping complexity. The pattern is matched against\n// the POSIX-style relative path (forward slashes) from the search root.\n// ---------------------------------------------------------------------------\nfunction compileGlob(pattern: string): RegExp {\n // Tokenise so `{a,b}` doesn't get its commas/braces escaped.\n let i = 0;\n let out = \"^\";\n while (i < pattern.length) {\n const c = pattern[i];\n if (c === \"*\") {\n if (pattern[i + 1] === \"*\") {\n // `**/` or `**` — match across directory separators.\n out += \".*\";\n i += 2;\n if (pattern[i] === \"/\") i++;\n } else {\n out += \"[^/]*\";\n i++;\n }\n } else if (c === \"?\") {\n out += \"[^/]\";\n i++;\n } else if (c === \"{\") {\n const end = pattern.indexOf(\"}\", i);\n if (end === -1) {\n out += \"\\\\{\";\n i++;\n continue;\n }\n const alts = pattern.slice(i + 1, end).split(\",\").map(escapeRegExp);\n out += `(?:${alts.join(\"|\")})`;\n i = end + 1;\n } else {\n out += escapeRegExp(c);\n i++;\n }\n }\n out += \"$\";\n return new RegExp(out);\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\ninterface WalkResult {\n files: string[]; // POSIX-relative paths from root\n scanned: number;\n truncated: boolean;\n}\n\nasync function walk(\n root: string,\n options: { includeHidden?: boolean; maxFiles: number; ignore?: Set<string> },\n): Promise<WalkResult> {\n const ignore = options.ignore ?? DEFAULT_IGNORE;\n const files: string[] = [];\n let scanned = 0;\n let truncated = false;\n\n async function visit(absDir: string, relDir: string): Promise<void> {\n if (truncated) return;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(absDir, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const e of entries) {\n if (truncated) return;\n if (!options.includeHidden && e.name.startsWith(\".\") && e.name !== \".\") continue;\n if (ignore.has(e.name)) continue;\n const childRel = relDir ? `${relDir}/${e.name}` : e.name;\n const childAbs = path.join(absDir, e.name);\n if (e.isDirectory()) {\n await visit(childAbs, childRel);\n } else if (e.isFile()) {\n scanned++;\n files.push(childRel);\n if (files.length >= options.maxFiles) {\n truncated = true;\n return;\n }\n }\n }\n }\n\n await visit(root, \"\");\n return { files, scanned, truncated };\n}\n\n// ---------------------------------------------------------------------------\n// file_glob\n// ---------------------------------------------------------------------------\n\nconst globSchema = z.object({\n pattern: z.string().min(1).describe(\"Glob pattern matched against POSIX-relative paths from `root`. Supports *, **, ?, and {a,b} alternation. Example: 'src/**/*.{ts,tsx}'.\"),\n root: z.string().optional().describe(\"Directory to search under. Defaults to the active workspace root, or $HOME if no workspace is open. Absolute / ~/ / relative paths accepted.\"),\n include_hidden: z.boolean().optional().describe(\"Include dot-prefixed directories and files. Default false.\"),\n max_results: z.number().int().min(1).max(MAX_GLOB_RESULTS).optional().describe(`Cap on returned matches (default 200, max ${MAX_GLOB_RESULTS}).`),\n});\n\nexport const fileGlobTool = tool(\n async (input, config?: ToolConfig) => {\n const { pattern, root: rawRoot, include_hidden, max_results } = input;\n const { resolve, workspace } = pathResolverFor(config);\n\n let rootAbs: string;\n try {\n rootAbs = rawRoot ? resolve(rawRoot) : (workspace?.root ?? resolve(\".\"));\n assertSafePath(rootAbs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message });\n }\n\n let rootStat: import(\"node:fs\").Stats;\n try {\n rootStat = await withFsDeadline(\"file_glob.stat\", rootAbs, () => fs.stat(rootAbs));\n } catch (err) {\n return JSON.stringify({ ok: false, root: rootAbs, error: (err as Error).message });\n }\n if (!rootStat.isDirectory()) {\n return JSON.stringify({ ok: false, root: rootAbs, error: \"root is not a directory\" });\n }\n\n const re = compileGlob(pattern);\n const cap = max_results ?? 200;\n\n const walked = await withFsDeadline(\"file_glob\", rootAbs, () =>\n walk(rootAbs, { includeHidden: include_hidden, maxFiles: MAX_FILES_SCANNED }),\n );\n\n const matches: string[] = [];\n for (const rel of walked.files) {\n if (re.test(rel)) {\n matches.push(rel);\n if (matches.length >= cap) break;\n }\n }\n\n return JSON.stringify({\n ok: true,\n root: rootAbs,\n pattern,\n matches,\n count: matches.length,\n files_scanned: walked.scanned,\n truncated: walked.truncated || matches.length >= cap,\n truncated_hint: (walked.truncated || matches.length >= cap)\n ? \"Narrow the pattern, raise max_results, or set a more specific root.\"\n : undefined,\n });\n },\n {\n name: \"file_glob\",\n description:\n \"Find files by glob pattern under a directory. Supports *, **, ?, and {a,b} alternation. Skips node_modules/.git/dist/build/.next/coverage/etc by default. Returns POSIX-relative paths from the search root.\",\n schema: globSchema,\n },\n);\n\n// ---------------------------------------------------------------------------\n// file_grep\n// ---------------------------------------------------------------------------\n\nconst grepSchema = z.object({\n pattern: z.string().min(1).describe(\"Search pattern. Regex by default; pass literal=true to treat as a plain substring.\"),\n literal: z.boolean().optional().describe(\"Treat `pattern` as a literal substring instead of a regex. Default false.\"),\n case_insensitive: z.boolean().optional().describe(\"Case-insensitive match. Default false.\"),\n root: z.string().optional().describe(\"Directory to search under. Defaults to the active workspace root, or $HOME.\"),\n glob: z.string().optional().describe(\"Optional file-name glob (e.g. '**/*.ts') to restrict which files are scanned.\"),\n include_hidden: z.boolean().optional().describe(\"Search inside dot-prefixed directories. Default false.\"),\n max_matches: z.number().int().min(1).max(MAX_MATCHES).optional().describe(`Cap on returned matches (default 100, max ${MAX_MATCHES}).`),\n context: z.number().int().min(0).max(5).optional().describe(\"Lines of context to return around each match (default 0).\"),\n});\n\ninterface GrepMatch {\n path: string; // POSIX-relative to root\n line: number; // 1-based\n text: string;\n before?: string[];\n after?: string[];\n}\n\nexport const fileGrepTool = tool(\n async (input, config?: ToolConfig) => {\n const {\n pattern, literal, case_insensitive,\n root: rawRoot, glob, include_hidden,\n max_matches, context,\n } = input;\n const { resolve, workspace } = pathResolverFor(config);\n\n let rootAbs: string;\n try {\n rootAbs = rawRoot ? resolve(rawRoot) : (workspace?.root ?? resolve(\".\"));\n assertSafePath(rootAbs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message });\n }\n\n let re: RegExp;\n try {\n const src = literal ? escapeRegExp(pattern) : pattern;\n re = new RegExp(src, case_insensitive ? \"i\" : \"\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: `invalid pattern: ${(err as Error).message}` });\n }\n\n const fileRe = glob ? compileGlob(glob) : null;\n const cap = max_matches ?? 100;\n const ctx = context ?? 0;\n\n const walked = await withFsDeadline(\"file_grep.walk\", rootAbs, () =>\n walk(rootAbs, { includeHidden: include_hidden, maxFiles: MAX_FILES_SCANNED }),\n );\n\n const matches: GrepMatch[] = [];\n let filesWithMatches = 0;\n let filesScanned = 0;\n let truncated = walked.truncated;\n\n outer: for (const rel of walked.files) {\n if (fileRe && !fileRe.test(rel)) continue;\n const abs = path.join(rootAbs, rel);\n let stat: import(\"node:fs\").Stats;\n try {\n stat = await fs.stat(abs);\n } catch {\n continue;\n }\n if (stat.size > MAX_GREP_FILE_BYTES) continue;\n filesScanned++;\n\n let raw: string;\n try {\n raw = await fs.readFile(abs, \"utf8\");\n } catch {\n continue; // unreadable / binary\n }\n // Quick binary heuristic — if a NUL byte is in the first 8 KB, skip.\n if (raw.length > 0 && raw.indexOf(\"\\u0000\") !== -1) continue;\n\n const lines = raw.split(/\\r?\\n/);\n let fileHadMatch = false;\n for (let i = 0; i < lines.length; i++) {\n // Use exec so we don't share a global regex's lastIndex across calls.\n if (re.test(lines[i])) {\n // Reset lastIndex defensively in case the user passed /g.\n re.lastIndex = 0;\n fileHadMatch = true;\n const text = clipLine(lines[i]);\n const m: GrepMatch = { path: rel, line: i + 1, text };\n if (ctx > 0) {\n m.before = lines.slice(Math.max(0, i - ctx), i).map(clipLine);\n m.after = lines.slice(i + 1, Math.min(lines.length, i + 1 + ctx)).map(clipLine);\n }\n matches.push(m);\n if (matches.length >= cap) {\n truncated = true;\n break outer;\n }\n }\n }\n if (fileHadMatch) filesWithMatches++;\n }\n\n return JSON.stringify({\n ok: true,\n root: rootAbs,\n pattern,\n literal: !!literal,\n case_insensitive: !!case_insensitive,\n glob: glob ?? null,\n matches,\n count: matches.length,\n files_with_matches: filesWithMatches,\n files_scanned: filesScanned,\n truncated,\n truncated_hint: truncated\n ? \"Narrow the pattern, add a glob filter, raise max_matches, or set a more specific root.\"\n : undefined,\n });\n },\n {\n name: \"file_grep\",\n description:\n \"Search file contents under a directory by regex (or literal substring with literal=true). Optional glob filter (e.g. '**/*.ts'). Returns POSIX-relative paths and 1-based line numbers, with optional N-line context. Skips node_modules/.git/etc, binary files (NUL-byte heuristic), and files >1 MB.\",\n schema: grepSchema,\n },\n);\n\nfunction clipLine(s: string): string {\n return s.length > MAX_LINE_BYTES ? `${s.slice(0, MAX_LINE_BYTES)}…[truncated]` : s;\n}\n\n// ---------------------------------------------------------------------------\n// file_multi_edit\n//\n// Applies N anchored str_replace edits to one file atomically: we read\n// once, apply all edits in order to the in-memory buffer, and only write\n// if every edit found exactly one match. If any edit fails (no match or\n// multiple matches), the file is left untouched and we return per-edit\n// status so the agent knows which one to fix.\n// ---------------------------------------------------------------------------\n\nconst multiEditSchema = z.object({\n path: z.string().describe(\"File path. Absolute / ~/ / relative to workspace root.\"),\n edits: z\n .array(z.object({\n old_string: z.string().min(1).describe(\"Exact literal substring to replace. Must match EXACTLY ONCE in the (current, partially-edited) buffer at the time it's applied.\"),\n new_string: z.string().describe(\"Replacement text. May be empty to delete.\"),\n }))\n .min(1)\n .max(MAX_MULTI_EDITS)\n .describe(`Up to ${MAX_MULTI_EDITS} edits, applied in order. All-or-nothing: if any edit fails to find exactly one match, the file is not modified.`),\n});\n\nexport const fileMultiEditTool = tool(\n async ({ path: filePath, edits }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"write\");\n\n const raw = await withFsDeadline(\"file_multi_edit.read\", abs, () => fs.readFile(abs, \"utf8\"));\n let buf = raw;\n const results: Array<{ index: number; ok: boolean; match_count?: number; error?: string }> = [];\n let failed = false;\n\n for (let i = 0; i < edits.length; i++) {\n const { old_string, new_string } = edits[i];\n const first = buf.indexOf(old_string);\n if (first === -1) {\n results.push({\n index: i, ok: false,\n error: \"old_string not found in the current buffer (note: earlier edits may have already changed it).\",\n });\n failed = true;\n continue;\n }\n const second = buf.indexOf(old_string, first + old_string.length);\n if (second !== -1) {\n const count = buf.split(old_string).length - 1;\n results.push({\n index: i, ok: false, match_count: count,\n error: \"old_string matches multiple times. Add surrounding context to make it unique.\",\n });\n failed = true;\n continue;\n }\n buf = buf.slice(0, first) + new_string + buf.slice(first + old_string.length);\n results.push({ index: i, ok: true });\n }\n\n if (failed) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"one or more edits failed; file was not modified\",\n edits: results,\n });\n }\n\n await withFsDeadline(\"file_multi_edit.write\", abs, () => fs.writeFile(abs, buf, \"utf8\"));\n return JSON.stringify({\n ok: true,\n path: abs,\n edits_applied: edits.length,\n bytes_before: Buffer.byteLength(raw, \"utf8\"),\n bytes_after: Buffer.byteLength(buf, \"utf8\"),\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_multi_edit\",\n description:\n \"Apply multiple anchored str_replace edits to one file atomically. Each edit's old_string must match EXACTLY ONCE in the (partially-edited) buffer at the time it's applied. All-or-nothing: if any edit fails, the file is not modified and per-edit status is returned. Prefer this over multiple file_edit round-trips when refactoring within a single file.\",\n schema: multiEditSchema,\n },\n);\n\n// Reference getConfig so dead-code elimination doesn't drop the import —\n// used indirectly via withFsDeadline / assertSafePath, but keeping a\n// direct reference helps the typecheck if those signatures ever change.\nvoid getConfig;\n\nregisterTools(\"Files\", \"read\", [fileGlobTool, fileGrepTool]);\nregisterTools(\"Files\", \"write\", [fileMultiEditTool]);\n","// `workspace_init` / `workspace_status` / `workspace_close`.\n//\n// Single agent-driven entry point for \"I am working in this directory\".\n// Returns a context bundle so the agent doesn't have to make a dozen\n// exploratory shell calls before it can start working: git state,\n// detected language / package manager / scripts, README head,\n// convention files (CLAUDE.md, CONTRIBUTING.md, ADR dir).\n//\n// Once set, every `file_*` and `local_exec` call with a relative path\n// resolves against the workspace root instead of the user's HOME.\n// Absolute paths are honoured as-is. Set `scoped: true` to refuse\n// absolute paths outside the root (off by default so the agent can\n// still read e.g. ~/Downloads to copy a file into the project).\n\nimport { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n currentWorkspace,\n setWorkspace,\n clearWorkspace,\n type ToolConfig,\n} from \"./workspace-context\";\n\nconst execFileP = promisify(execFile);\n\n// Probe budget. Keep generous enough for slow filesystems but short\n// enough that the agent isn't blocked for tens of seconds on a stalled\n// cloud-sync provider.\nconst PROBE_TIMEOUT_MS = 8_000;\n\nconst MAX_TREE_DEFAULT = 200;\nconst MAX_TREE_HARD_CAP = 1_000;\nconst README_MAX_BYTES = 2_048;\n\n// Reuse the credential denylist shape from files.ts — keep this list in\n// sync if files.ts grows new sensitive bases. We intentionally don't\n// import from files.ts to avoid a tight coupling; workspace_init is the\n// only place where the *whole root* is gated (file tools gate per call).\nfunction sensitiveRoots(): 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 process.env.JARELA_DB_DIR\n ? path.resolve(process.env.JARELA_DB_DIR)\n : path.join(home, \".jarela\"),\n ];\n}\n\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 resolveAgentPath(p: string): string {\n let s = p.trim();\n if (!s) throw new Error(\"path is required\");\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\nasync function withTimeout<T>(label: string, p: Promise<T>): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${PROBE_TIMEOUT_MS}ms`)),\n PROBE_TIMEOUT_MS,\n );\n });\n try {\n return await Promise.race([p, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\ninterface GitProbe {\n is_repo: boolean;\n branch?: string;\n remote?: string;\n head?: string;\n dirty?: boolean;\n untracked_count?: number;\n}\n\nasync function probeGit(root: string): Promise<GitProbe> {\n // `git rev-parse --is-inside-work-tree` is the canonical \"is this a repo?\" check.\n try {\n await execFileP(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], { cwd: root, timeout: PROBE_TIMEOUT_MS });\n } catch {\n return { is_repo: false };\n }\n const out: GitProbe = { is_repo: true };\n const safe = async (args: string[]): Promise<string> => {\n try {\n const { stdout } = await execFileP(\"git\", args, { cwd: root, timeout: PROBE_TIMEOUT_MS });\n return stdout.trim();\n } catch {\n return \"\";\n }\n };\n const [branch, head, remote, status] = await Promise.all([\n safe([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"]),\n safe([\"rev-parse\", \"--short\", \"HEAD\"]),\n safe([\"config\", \"--get\", \"remote.origin.url\"]),\n safe([\"status\", \"--porcelain\"]),\n ]);\n if (branch) out.branch = branch;\n if (head) out.head = head;\n if (remote) out.remote = remote;\n if (status !== undefined) {\n const lines = status ? status.split(/\\r?\\n/) : [];\n out.dirty = lines.length > 0;\n out.untracked_count = lines.filter((l) => l.startsWith(\"??\")).length;\n }\n return out;\n}\n\ninterface PackageManifest {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n packageManager?: string;\n}\n\nasync function readJsonIfExists(p: string): Promise<PackageManifest | null> {\n try {\n const raw = await fs.readFile(p, \"utf8\");\n return JSON.parse(raw) as PackageManifest;\n } catch {\n return null;\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function detectPackageManager(root: string, pkg: PackageManifest | null): Promise<string> {\n if (pkg?.packageManager) {\n const pm = pkg.packageManager.split(\"@\")[0];\n if (pm) return pm;\n }\n if (await fileExists(path.join(root, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (await fileExists(path.join(root, \"yarn.lock\"))) return \"yarn\";\n if (await fileExists(path.join(root, \"bun.lockb\"))) return \"bun\";\n if (await fileExists(path.join(root, \"package-lock.json\"))) return \"npm\";\n if (await fileExists(path.join(root, \"Pipfile\"))) return \"pipenv\";\n if (await fileExists(path.join(root, \"poetry.lock\"))) return \"poetry\";\n if (await fileExists(path.join(root, \"requirements.txt\"))) return \"pip\";\n if (await fileExists(path.join(root, \"Cargo.toml\"))) return \"cargo\";\n if (await fileExists(path.join(root, \"go.mod\"))) return \"go\";\n return \"none\";\n}\n\nfunction detectTestRunner(pkg: PackageManifest | null): string | undefined {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n if (deps.vitest) return \"vitest\";\n if (deps.jest) return \"jest\";\n if (deps.mocha) return \"mocha\";\n if (deps.ava) return \"ava\";\n if (pkg?.scripts?.test) return \"npm:test\";\n return undefined;\n}\n\nfunction detectFrameworks(pkg: PackageManifest | null): string[] {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n const out: string[] = [];\n if (deps.next) out.push(\"next\");\n if (deps.react) out.push(\"react\");\n if (deps.vue) out.push(\"vue\");\n if (deps.svelte) out.push(\"svelte\");\n if (deps[\"@angular/core\"]) out.push(\"angular\");\n if (deps.express) out.push(\"express\");\n if (deps.fastify) out.push(\"fastify\");\n if (deps.tailwindcss) out.push(\"tailwind\");\n if (deps[\"@langchain/core\"]) out.push(\"langchain\");\n return out;\n}\n\nasync function parseMakefileTargets(root: string): Promise<string[]> {\n const p = path.join(root, \"Makefile\");\n try {\n const raw = await fs.readFile(p, \"utf8\");\n const targets: string[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n // Match `target:` or `target: dep1 dep2` but skip variable assignments\n // and indented recipe lines.\n const m = /^([A-Za-z0-9_.-]+)\\s*:(?!=)/.exec(line);\n if (m && !line.startsWith(\"\\t\")) targets.push(m[1]);\n }\n // Dedupe preserving order; cap at 50.\n return Array.from(new Set(targets)).slice(0, 50);\n } catch {\n return [];\n }\n}\n\nasync function detectLanguages(root: string): Promise<string[]> {\n const found = new Set<string>();\n // Quick scan: top-level + one level of children. Avoids full recursive walk.\n try {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n if (e.isFile()) markLanguage(e.name, found);\n }\n if (await fileExists(path.join(root, \"tsconfig.json\"))) found.add(\"typescript\");\n if (await fileExists(path.join(root, \"go.mod\"))) found.add(\"go\");\n if (await fileExists(path.join(root, \"Cargo.toml\"))) found.add(\"rust\");\n if (await fileExists(path.join(root, \"pyproject.toml\"))) found.add(\"python\");\n if (await fileExists(path.join(root, \"pom.xml\"))) found.add(\"java\");\n if (await fileExists(path.join(root, \"build.gradle\")) || await fileExists(path.join(root, \"build.gradle.kts\"))) found.add(\"java\");\n } catch {\n /* ignore */\n }\n return Array.from(found);\n}\n\nfunction markLanguage(filename: string, into: Set<string>): void {\n const ext = path.extname(filename).toLowerCase();\n const map: Record<string, string> = {\n \".ts\": \"typescript\", \".tsx\": \"typescript\",\n \".js\": \"javascript\", \".jsx\": \"javascript\", \".mjs\": \"javascript\", \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\", \".kt\": \"kotlin\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n \".cs\": \"csharp\",\n \".swift\": \"swift\",\n };\n const l = map[ext];\n if (l) into.add(l);\n}\n\n// Lightweight directory tree honouring a small ignore list. We don't\n// fully parse .gitignore — that's a heavy dep for this probe; the\n// default ignores cover the 95% case (node_modules, .git, dist, build,\n// .next, coverage, __pycache__, target, vendor). Returns at most\n// `maxEntries` rows; sets `truncated=true` if more existed.\ninterface TreeEntry {\n path: string;\n kind: \"file\" | \"dir\";\n size?: number;\n}\n\nconst DEFAULT_IGNORE = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"out\",\n \"coverage\", \"__pycache__\", \"target\", \"vendor\", \".venv\", \"venv\",\n \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\nasync function buildTree(\n root: string,\n maxEntries: number,\n): Promise<{ entries: TreeEntry[]; truncated: boolean }> {\n const entries: TreeEntry[] = [];\n let truncated = false;\n\n async function walk(dirAbs: string, dirRel: string, depth: number): Promise<void> {\n if (entries.length >= maxEntries) {\n truncated = true;\n return;\n }\n if (depth > 4) return; // hard depth cap to keep probe bounded\n let kids: import(\"node:fs\").Dirent[];\n try {\n kids = await fs.readdir(dirAbs, { withFileTypes: true });\n } catch {\n return;\n }\n kids.sort((a, b) => {\n // dirs first, then files; alpha within group\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n for (const k of kids) {\n if (entries.length >= maxEntries) {\n truncated = true;\n return;\n }\n if (DEFAULT_IGNORE.has(k.name)) continue;\n const childAbs = path.join(dirAbs, k.name);\n const childRel = dirRel ? `${dirRel}/${k.name}` : k.name;\n if (k.isDirectory()) {\n entries.push({ path: `${childRel}/`, kind: \"dir\" });\n await walk(childAbs, childRel, depth + 1);\n } else if (k.isFile()) {\n let size: number | undefined;\n try {\n const st = await fs.stat(childAbs);\n size = st.size;\n } catch {\n /* ignore */\n }\n entries.push({ path: childRel, kind: \"file\", size });\n }\n }\n }\n\n await walk(root, \"\", 0);\n return { entries, truncated };\n}\n\nasync function readReadme(root: string): Promise<{ path: string; head: string; truncated: boolean } | null> {\n try {\n const entries = await fs.readdir(root);\n const candidate = entries.find((e) => /^readme(\\.[a-z0-9]+)?$/i.test(e));\n if (!candidate) return null;\n const abs = path.join(root, candidate);\n const raw = await fs.readFile(abs, \"utf8\");\n const head = raw.slice(0, README_MAX_BYTES);\n return { path: candidate, head, truncated: raw.length > README_MAX_BYTES };\n } catch {\n return null;\n }\n}\n\nasync function detectConventionFiles(root: string): Promise<{\n claude_md: string | null;\n agents_md: string | null;\n contributing_md: string | null;\n adr_dir: string | null;\n}> {\n const claude = (await fileExists(path.join(root, \"CLAUDE.md\"))) ? \"CLAUDE.md\" : null;\n const agents = (await fileExists(path.join(root, \"AGENTS.md\"))) ? \"AGENTS.md\" : null;\n const contributing = (await fileExists(path.join(root, \"CONTRIBUTING.md\"))) ? \"CONTRIBUTING.md\" : null;\n // ADR dir conventions: docs/adr, docs/decisions, adr\n let adrDir: string | null = null;\n for (const candidate of [\"docs/adr\", \"docs/decisions\", \"adr\"]) {\n if (await fileExists(path.join(root, candidate))) {\n adrDir = candidate;\n break;\n }\n }\n return { claude_md: claude, agents_md: agents, contributing_md: contributing, adr_dir: adrDir };\n}\n\n// Build the prioritised required-reading list the agent MUST read before\n// taking any other action. Order matters — earlier entries are higher\n// priority. We resolve each candidate to (relative path, byte size) so\n// the agent knows what it's about to spend tokens on.\n//\n// We deliberately do NOT inline contents here: the agent already has\n// file_read for that, the user sees the read calls in the tool stream,\n// and large convention files don't get force-loaded on every init.\nasync function buildRequiredReading(\n root: string,\n conventions: Awaited<ReturnType<typeof detectConventionFiles>>,\n readme: { path: string } | null,\n extra: string[],\n): Promise<Array<{ path: string; bytes: number; reason: string }>> {\n const seen = new Set<string>();\n const out: Array<{ path: string; bytes: number; reason: string }> = [];\n\n const push = async (rel: string | null, reason: string): Promise<void> => {\n if (!rel || seen.has(rel)) return;\n try {\n const st = await fs.stat(path.join(root, rel));\n if (!st.isFile()) return;\n seen.add(rel);\n out.push({ path: rel, bytes: st.size, reason });\n } catch {\n /* file vanished between detect and stat — skip */\n }\n };\n\n // Priority order:\n // 1. CLAUDE.md / AGENTS.md — agent-specific operating instructions.\n // 2. CONTRIBUTING.md — contribution + commit + release rules.\n // 3. README.md — project overview & invariants.\n // 4. Top-level ADR index — architectural decisions if a docs/adr exists.\n // 5. Caller-supplied extras — project-specific must-reads.\n await push(conventions.claude_md, \"agent operating instructions\");\n await push(conventions.agents_md, \"agent operating instructions\");\n await push(conventions.contributing_md, \"contribution + commit + release rules\");\n await push(readme?.path ?? null, \"project overview\");\n\n if (conventions.adr_dir) {\n for (const idx of [\"README.md\", \"index.md\", \"0000-index.md\"]) {\n const rel = `${conventions.adr_dir}/${idx}`;\n await push(rel, \"architectural decision records (index)\");\n }\n }\n\n for (const extraPath of extra) {\n const cleaned = extraPath.trim();\n if (!cleaned) continue;\n // Refuse absolute paths or parent-escape — required_reading is always\n // workspace-relative so the agent can't be coaxed into reading\n // /etc/passwd via a prompt-injected init call.\n if (path.isAbsolute(cleaned) || cleaned.startsWith(\"..\") || cleaned.split(/[\\\\/]/).includes(\"..\")) {\n continue;\n }\n await push(cleaned.replace(/\\\\/g, \"/\"), \"caller-supplied\");\n }\n\n return out;\n}\n\n// --- init ---------------------------------------------------------------\n\nconst initSchema = z.object({\n path: z.string().describe(\"Project root directory. Absolute or ~/foo; bare relative paths resolve against the user's HOME.\"),\n scoped: z.boolean().optional().describe(\"When true, later file_*/local_exec calls refuse absolute paths outside the root. Default false.\"),\n include_tree: z.boolean().optional().describe(\"Include a bounded directory tree in the response. Default true.\"),\n max_tree_entries: z.number().int().min(0).max(MAX_TREE_HARD_CAP).optional().describe(`Cap on tree rows. Default ${MAX_TREE_DEFAULT}, max ${MAX_TREE_HARD_CAP}.`),\n include_git: z.boolean().optional().describe(\"Probe git state. Default true.\"),\n include_scripts: z.boolean().optional().describe(\"Parse package.json scripts and Makefile targets. Default true.\"),\n include_readme: z.boolean().optional().describe(\"Return the head of the project README. Default true.\"),\n extra_required_reading: z\n .array(z.string())\n .optional()\n .describe(\"Additional workspace-relative paths to append to required_reading. Absolute paths and '..' segments are rejected.\"),\n});\n\nexport const workspaceInitTool = tool(\n async (input, config?: ToolConfig) => {\n const {\n path: rawPath,\n scoped = false,\n include_tree = true,\n max_tree_entries,\n include_git = true,\n include_scripts = true,\n include_readme = true,\n extra_required_reading = [],\n } = input;\n\n let abs: string;\n try {\n abs = resolveAgentPath(rawPath);\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message, code: \"WORKSPACE_BAD_PATH\" });\n }\n\n // Validate the path exists and is a directory.\n let stat: import(\"node:fs\").Stats;\n try {\n stat = await withTimeout(\"workspace_init.stat\", fs.stat(abs));\n } catch (err) {\n const msg = (err as Error).message;\n const code = msg.includes(\"ENOENT\") ? \"WORKSPACE_NOT_FOUND\" : msg.includes(\"timed out\") ? \"WORKSPACE_TIMEOUT\" : \"WORKSPACE_ERROR\";\n return JSON.stringify({ ok: false, path: abs, error: msg, code });\n }\n if (!stat.isDirectory()) {\n return JSON.stringify({ ok: false, path: abs, error: \"path is not a directory\", code: \"WORKSPACE_NOT_DIR\" });\n }\n\n // Sensitive-root guard. Override by setting JARELA_ALLOW_SENSITIVE_FILES=1\n // (same opt-out as the per-file denylist in files.ts).\n if (process.env.JARELA_ALLOW_SENSITIVE_FILES !== \"1\") {\n for (const base of sensitiveRoots()) {\n if (isInside(abs, base)) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: `refused: '${abs}' is inside a sensitive directory (${path.basename(base)}). Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n code: \"WORKSPACE_SENSITIVE\",\n });\n }\n }\n }\n\n // Install the workspace before probing — so probe-time errors don't\n // leave the agent without an active workspace.\n setWorkspace({ root: abs, scoped, opened_at: Date.now() }, config);\n\n // Probe everything in parallel and tolerate individual failures.\n const pkg = include_scripts ? await readJsonIfExists(path.join(abs, \"package.json\")) : null;\n\n const [git, languages, packageManager, makefileTargets, tree, readme, conventions, hasDockerfile, hasDevcontainer] = await Promise.all([\n include_git ? withTimeout(\"workspace_init.git\", probeGit(abs)).catch(() => ({ is_repo: false } as GitProbe)) : Promise.resolve({ is_repo: false } as GitProbe),\n detectLanguages(abs),\n include_scripts ? detectPackageManager(abs, pkg) : Promise.resolve(\"none\"),\n include_scripts ? parseMakefileTargets(abs) : Promise.resolve([] as string[]),\n include_tree\n ? buildTree(abs, Math.min(max_tree_entries ?? MAX_TREE_DEFAULT, MAX_TREE_HARD_CAP))\n : Promise.resolve({ entries: [] as TreeEntry[], truncated: false }),\n include_readme ? readReadme(abs) : Promise.resolve(null),\n detectConventionFiles(abs),\n fileExists(path.join(abs, \"Dockerfile\")),\n fileExists(path.join(abs, \".devcontainer\", \"devcontainer.json\")),\n ]);\n\n return JSON.stringify({\n ok: true,\n root: abs,\n scoped,\n git,\n project: {\n languages,\n package_manager: packageManager,\n framework_hints: detectFrameworks(pkg),\n test_runner: detectTestRunner(pkg),\n scripts: pkg?.scripts ?? {},\n makefile_targets: makefileTargets,\n has_dockerfile: hasDockerfile,\n has_devcontainer: hasDevcontainer,\n },\n tree: include_tree ? tree : undefined,\n readme,\n conventions,\n required_reading: await buildRequiredReading(abs, conventions, readme, extra_required_reading),\n });\n },\n {\n name: \"workspace_init\",\n description:\n \"Register a project directory as the active workspace for this thread and return its context bundle (git state, languages, scripts, tree, README head, convention files, required_reading). After this call, file_*/local_exec calls with relative paths resolve against the workspace root instead of $HOME. Call this once at the start of any coding task. CRITICAL: the response includes a `required_reading` array of workspace-relative documentation files (CLAUDE.md, AGENTS.md, CONTRIBUTING.md, README, ADR index, plus any caller-supplied extras). You MUST `file_read` every entry in `required_reading` before taking any other action (no edits, no shell commands, no further tool calls beyond file_read for those paths). These files define the project's contribution rules, commit format, release process, and architectural invariants — skipping them produces output that fails review.\",\n schema: initSchema,\n },\n);\n\n// --- status -------------------------------------------------------------\n\nexport const workspaceStatusTool = tool(\n async (_input, config?: ToolConfig) => {\n const ws = currentWorkspace(config);\n if (!ws) {\n return JSON.stringify({ ok: true, active: false });\n }\n // Re-probe git state cheaply — that's the only field that drifts.\n const git = await probeGit(ws.root).catch(() => ({ is_repo: false } as GitProbe));\n return JSON.stringify({\n ok: true,\n active: true,\n root: ws.root,\n scoped: ws.scoped,\n opened_at: ws.opened_at,\n git,\n });\n },\n {\n name: \"workspace_status\",\n description:\n \"Return the currently active workspace (if any) plus fresh git status. Cheap — no tree walk. Use to check 'am I where I think I am?' before destructive operations.\",\n schema: z.object({}).describe(\"No arguments.\"),\n },\n);\n\n// --- close --------------------------------------------------------------\n\nexport const workspaceCloseTool = tool(\n async (_input, config?: ToolConfig) => {\n const cleared = clearWorkspace(config);\n return JSON.stringify({ ok: true, was_active: cleared });\n },\n {\n name: \"workspace_close\",\n description:\n \"Clear the active workspace for this thread. Subsequent file_*/local_exec calls with relative paths return to resolving against $HOME / process cwd.\",\n schema: z.object({}).describe(\"No arguments.\"),\n },\n);\n\nregisterTools(\"Files\", \"read\", [workspaceInitTool, workspaceStatusTool, workspaceCloseTool]);\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(/&/g, \"&\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/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\", \"read\", [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\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// JARELA_FETCH_TOOL_MAX_BYTES overrides the byte cap.\nfunction maxBytes(): number { return getConfig().fetchToolMaxBytes; }\n// Internal cap on a single fetch. The agent's wall-clock budget on the\n// tool call (see lib/tools/wallclock.ts) is the primary deadline; this is\n// a leak backstop that actually closes the socket via AbortController so a\n// stuck server can't tie up an fd indefinitely.\nconst FETCH_INTERNAL_TIMEOUT_MS = 120_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 ``. 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_MS = FETCH_INTERNAL_TIMEOUT_MS;\n const MAX_BYTES = maxBytes();\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 const aborted = ctrl.signal.aborted\n || (err instanceof Error && (err.name === \"AbortError\" || /abort/i.test(msg)));\n if (aborted) {\n return JSON.stringify({\n url,\n error: `timed out after ${Math.round(TIMEOUT_MS / 1000)}s. The page is slow or unresponsive — try a different URL or pass a larger deadline_ms.`,\n timed_out: true,\n timeout_ms: TIMEOUT_MS,\n });\n }\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 `` 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\", \"read\", [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\", \"read\", [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 ``.\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) => ``).join(\"\\n\\n\"),\n hint: \"Embed images in your reply using the `markdown` field verbatim, or build your own `` 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 ``. 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\", \"execute\", [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\", \"execute\", [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\", \"read\", [listScheduledTasksTool]);\nregisterTools(\"Schedule\", \"write\", [scheduleTaskTool, 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\", \"read\", [listWatchersTool, listReactionScriptsTool]);\nregisterTools(\"Schedule\", \"write\", [scheduleWatcherTool, cancelWatcherTool]);\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\", \"read\", [checkProposalTool]);\nregisterTools(\"Config\", \"write\", [proposeConfigChangeTool]);\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\", \"read\", [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, subject, 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 // `subject` is accepted as an alias for `summary` so agents trained on\n // Outlook vocabulary don't fail the schema on first try.\n const eventSummary = summary ?? subject;\n if (!eventSummary) {\n return JSON.stringify({ error: \"summary (or subject) is required\" });\n }\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: eventSummary,\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).optional().describe(\"Event title shown on the calendar (alias: subject)\"),\n subject: z.string().min(1).optional().describe(\"Alias for summary (Outlook vocabulary)\"),\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, subject, 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 const eventSummary = summary ?? subject;\n if (eventSummary !== undefined) patch.summary = eventSummary;\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 (alias: subject)\"),\n subject: z.string().optional().describe(\"Alias for summary (Outlook vocabulary)\"),\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\", \"read\", [\n calendarListCalendarsTool, calendarListEventsTool, calendarGetEventTool,\n]);\nregisterTools(\"Calendar\", \"write\", [\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, summary, 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 // `summary` is accepted as an alias for `subject` so agents trained on\n // Google Calendar's vocabulary don't fail the schema on first try.\n const eventSubject = subject ?? summary;\n if (!eventSubject) {\n return JSON.stringify({ error: \"subject (or summary) is required\" });\n }\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: eventSubject,\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).optional().describe(\"Event title shown on the calendar (alias: summary)\"),\n summary: z.string().min(1).optional().describe(\"Alias for subject (Google Calendar vocabulary)\"),\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, summary, 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 const eventSubject = subject ?? summary;\n if (eventSubject !== undefined) patch.subject = eventSubject;\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 (alias: summary)\"),\n summary: z.string().optional().describe(\"Alias for subject (Google Calendar vocabulary)\"),\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\", \"read\", [\n outlookCalendarListCalendarsTool, outlookCalendarListEventsTool, outlookCalendarGetEventTool,\n]);\nregisterTools(\"Calendar\", \"write\", [\n outlookCalendarCreateEventTool, outlookCalendarUpdateEventTool, outlookCalendarDeleteEventTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport {\n getAgentConfig,\n parseDelegateTargets,\n} from \"@/lib/stores/agent-configs\";\nimport { getThread, getOrCreateAgentThread } from \"@/lib/stores/threads\";\nimport {\n MAX_DELEGATION_DEPTH,\n prepareThreadRun,\n persistAssistantMessage,\n} from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { enqueueThreadRun } from \"@/lib/agents/run-queue\";\nimport { resolveTurnProfile } from \"@/lib/agents/turn-profile\";\n\ninterface DelegateContext {\n parentAgentId: string;\n depth: number;\n ancestors: readonly string[];\n}\n\nfunction readDelegateContext(config?: RunnableConfig): DelegateContext | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n if (!thread) return null;\n const depth = (config?.configurable?.delegation_depth as number | undefined) ?? 0;\n const ancestorsRaw = config?.configurable?.delegation_ancestors as\n | readonly string[]\n | undefined;\n const ancestors = Array.isArray(ancestorsRaw) ? ancestorsRaw : [];\n return { parentAgentId: thread.agent_id, depth, ancestors };\n}\n\nfunction fail(code: string, message: string, extra: Record<string, unknown> = {}): string {\n return JSON.stringify({ ok: false, error_code: code, message, ...extra });\n}\n\nexport const delegateToAgentTool = tool(\n async ({ agent_id, task }, config) => {\n const ctx = readDelegateContext(config);\n if (!ctx) return fail(\"no_context\", \"No agent context (missing thread_id)\");\n\n const parent = getAgentConfig(ctx.parentAgentId);\n if (!parent) return fail(\"agent_not_found\", `Parent agent \"${ctx.parentAgentId}\" not found`);\n\n if (agent_id === ctx.parentAgentId) {\n return fail(\"cycle_detected\", \"Cannot delegate to self\");\n }\n if (ctx.ancestors.includes(agent_id)) {\n return fail(\"cycle_detected\", `Delegation cycle: ${agent_id} is already in the chain [${ctx.ancestors.join(\" -> \")}]`);\n }\n if (ctx.depth >= MAX_DELEGATION_DEPTH) {\n return fail(\n \"depth_exceeded\",\n `Maximum delegation depth (${MAX_DELEGATION_DEPTH}) reached. Chain: [${[...ctx.ancestors, ctx.parentAgentId].join(\" -> \")}]`,\n );\n }\n\n const roster = parseDelegateTargets(parent.delegate_targets);\n if (!roster.includes(agent_id)) {\n return fail(\n \"not_in_roster\",\n `Agent \"${agent_id}\" is not in the delegate roster for \"${parent.id}\". Available: [${roster.join(\", \") || \"none\"}]`,\n );\n }\n\n const child = getAgentConfig(agent_id);\n if (!child) return fail(\"agent_not_found\", `Delegate agent \"${agent_id}\" not found`);\n\n const childThread = getOrCreateAgentThread(agent_id);\n const startedAt = Date.now();\n\n try {\n // Serialise on the child thread_id with every other entry point\n // (HTTP POST, scheduler, watcher, bridge, sibling delegations) —\n // see lib/agents/run-queue.ts. A delegate fired while the child is\n // already running waits in the child's queue instead of racing the\n // checkpoint store.\n const queued = await enqueueThreadRun(childThread.thread_id, \"delegate\", async () => {\n const prepared = await prepareThreadRun({\n thread_id: childThread.thread_id,\n message: task,\n user_category: \"delegation\",\n context_profile: resolveTurnProfile(\"delegate\"),\n _delegation_depth: ctx.depth + 1,\n _delegation_ancestors: [...ctx.ancestors, ctx.parentAgentId],\n });\n const collected = await collectStream(prepared.stream);\n if (collected.terminal !== \"error\") {\n persistAssistantMessage(\n childThread.thread_id,\n collected.assistantContent,\n collected.usedTools,\n collected.toolEvents,\n \"delegation\",\n collected.usage ?? null,\n prepared.context_snapshot ?? null,\n prepared.source_manifest ?? null,\n );\n }\n return collected;\n }).result;\n const elapsed_ms = Date.now() - startedAt;\n\n if (queued.terminal === \"error\") {\n return fail(\"child_error\", queued.errorMessage ?? \"Child agent run failed\", {\n agent_id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n });\n }\n\n return JSON.stringify({\n ok: true,\n agent_id: child.id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n depth: ctx.depth + 1,\n result: queued.assistantContent.trim(),\n used_tools: Array.from(new Set(queued.usedTools)),\n elapsed_ms,\n // Ready-to-paste markdown link the parent agent can drop into its\n // reply so the user can trace the summary back to the delegate's\n // full thread. The chat UI resolves `?thread=<tid>&agent=<aid>`\n // via parseHref → SELECT_THREAD, which atomically sets both\n // activeThreadId and activeAgentId (chat tab won't render the\n // thread without the agent id).\n cite_as: `[${child.name}'s reply](?thread=${childThread.thread_id}&agent=${child.id})`,\n });\n } catch (err) {\n return fail(\"child_error\", err instanceof Error ? err.message : String(err), {\n agent_id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n });\n }\n },\n {\n name: \"delegate_to_agent\",\n description:\n \"Hand a subtask to another agent that has specialized knowledge or tools you lack. \" +\n \"The delegate runs in its own thread; the user sees a tool card with the delegate's name, \" +\n \"the task you sent, and the delegate's final answer (plus a link to open the delegate's thread). \" +\n \"Only delegate when the target agent is genuinely better-suited — do NOT delegate trivial subtasks \" +\n \"you can handle yourself. Before calling this tool, tell the user in one sentence which agent you \" +\n \"are handing to and why. Available delegate ids are listed in the 'Available delegates' system \" +\n \"section; calling with an id outside that list will be refused.\",\n schema: z.object({\n agent_id: z.string().describe(\n \"The id of the delegate agent. Must appear in the 'Available delegates' list in your system prompt.\",\n ),\n task: z.string().min(1).describe(\n \"A self-contained task description for the delegate. Include all context the delegate needs — \" +\n \"the delegate does NOT see your conversation history with the user, only this task string.\",\n ),\n }),\n },\n);\n\nregisterTools(\"Agent\", \"execute\", [delegateToAgentTool]);\n","// Agent-callable knobs for the JARELA_* override store.\n//\n// Both tools are gated by the per-var schema flag `agentWritable` —\n// agents cannot write to anything not flagged true (defaults to false).\n// `restart_server` is only wired here; agents still need the tool to be\n// in their selected toolset to call it (default agents do not include\n// these).\n//\n// Use cases the user explicitly asked to support:\n// - \"agent, lower the run idle timeout to 30s and restart\"\n// - \"agent, switch the log level to debug for the next hour\"\n//\n// We surface the schema's tier/restart flags in the response so the\n// agent's reply can tell the user what changed and whether a restart\n// fired (or is needed but skipped).\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { envSchemaByName } from \"@/lib/env/schema\";\nimport { patchOverride, validateForSchema } from \"@/lib/env/overrides\";\nimport { resetConfigCache } from \"@/lib/env/config\";\n\nconst setEnvSchema = z.object({\n name: z.string().describe(\"Env var name. Must be a JARELA_* knob the schema flags as agent-writable; otherwise the call returns code=forbidden.\"),\n value: z\n .string()\n .nullable()\n .describe(\"New value as a string (numbers/bools come as their string form: '5000' / 'true'). Pass null to clear the override and revert to the default.\"),\n reason: z\n .string()\n .optional()\n .describe(\"Short note explaining the change — logged for postmortems.\"),\n});\n\nconst setEnvVar = tool(\n async ({ name, value, reason }) => {\n const def = envSchemaByName().get(name);\n if (!def) {\n return JSON.stringify({\n ok: false,\n code: \"unknown_var\",\n error: `unknown env var: ${name}`,\n hint: \"List the schema with /api/v1/env (GET) before guessing names. Only JARELA_* keys defined in lib/env/schema.ts are accepted.\",\n });\n }\n if (!def.agentWritable) {\n return JSON.stringify({\n ok: false,\n code: \"forbidden\",\n error: `${name} is not flagged agentWritable in the schema`,\n hint: \"Agents cannot edit infra knobs (port, hostname, dataDir, …). Tell the user to change this from the Environment panel themselves.\",\n });\n }\n if (value !== null) {\n const verr = validateForSchema(def, value);\n if (verr) {\n return JSON.stringify({\n ok: false,\n code: \"invalid_value\",\n error: `${name}: ${verr}`,\n hint: \"Re-issue the call with a value that matches the schema's type/min/max/enum.\",\n });\n }\n }\n await patchOverride(name, value);\n if (value === null) delete process.env[name];\n else process.env[name] = value;\n resetConfigCache();\n return JSON.stringify({\n ok: true,\n name,\n value,\n requiresRestart: def.requiresRestart,\n reason: reason ?? null,\n hint: def.requiresRestart\n ? \"Override persisted. The change requires a server restart — call restart_server to apply, OR tell the user to click Restart in the Environment panel.\"\n : \"Override persisted and is in effect immediately. No restart needed.\",\n });\n },\n {\n name: \"set_env_var\",\n description:\n \"Set or unset a JARELA_* runtime override. Only schema-flagged agent-writable knobs are accepted; everything else returns code=forbidden. Use this when the user explicitly asks to change a runtime setting (e.g. log level, retry budget). Pair with restart_server when the result reports requiresRestart=true.\",\n schema: setEnvSchema,\n },\n);\n\nconst restartSchema = z.object({\n reason: z.string().min(1).describe(\"Why the restart is needed (logged + included in /api/v1/system/restart payload). Required.\"),\n});\n\nconst restartServer = tool(\n async ({ reason }) => {\n // Use the same endpoint the UI hits. Doing it via fetch instead of\n // calling process.exit() directly here means the request response\n // flushes back to the agent (and through it, the user) before the\n // process tears down.\n try {\n const port = Number(process.env.JARELA_PORT ?? process.env.PORT ?? 4312);\n const host = process.env.JARELA_HOSTNAME ?? process.env.HOSTNAME ?? \"127.0.0.1\";\n const r = await fetch(`http://${host}:${port}/api/v1/system/restart`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ reason: `[agent] ${reason}` }),\n });\n const body = (await r.json().catch(() => ({}))) as { hint?: string };\n return JSON.stringify({\n ok: r.ok,\n status: r.status,\n reason,\n hint: body.hint ?? \"Restart request sent. The supervisor will relaunch the process; the user's UI will reconnect automatically.\",\n });\n } catch (e) {\n return JSON.stringify({\n ok: false,\n code: \"restart_failed\",\n error: (e as Error).message,\n hint: \"Could not reach /api/v1/system/restart from inside the same process. Tell the user they need to restart manually.\",\n });\n }\n },\n {\n name: \"restart_server\",\n description:\n \"Restart the Jarela server. Only call this when the user explicitly asks for a restart, OR when set_env_var returned requiresRestart=true and the user agreed. The UI reconnects automatically once the supervisor (launchd/systemd/Task Scheduler) relaunches.\",\n schema: restartSchema,\n },\n);\n\nregisterTools(\"Config\", \"execute\", [setEnvVar, restartServer]);\n","// Read-only introspection tool — lets the agent enumerate every tool it has\n// access to right now (built-in + external + MCP), so it can answer\n// \"what's in my toolbox / is X available\" without the user having to\n// describe the project's tool surface in the prompt.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport {\n getAllToolsAsync,\n getToolCategory,\n getToolCapability,\n getToolGroup,\n getToolSource,\n type ToolSource,\n} from \"./index\";\nimport type { Capability, ToolCategory } from \"./registry\";\nimport { registerTools } from \"./registry\";\n\ninterface ToolSummary {\n name: string;\n description: string;\n category: ToolCategory;\n capability: Capability;\n source: ToolSource;\n group: string | null;\n}\n\nexport const listToolsTool = tool(\n async ({ category, capability, source }) => {\n const all = await getAllToolsAsync();\n const summaries: ToolSummary[] = all.map((t) => ({\n name: t.name,\n description: typeof t.description === \"string\" ? t.description : \"\",\n category: getToolCategory(t.name),\n capability: getToolCapability(t.name),\n source: getToolSource(t.name),\n group: getToolGroup(t.name),\n }));\n\n const filtered = summaries.filter((s) =>\n (!category || s.category === category) &&\n (!capability || s.capability === capability) &&\n (!source || s.source === source),\n );\n\n const counts = {\n total: filtered.length,\n by_source: { builtin: 0, external: 0, mcp: 0 } as Record<ToolSource, number>,\n by_capability: { read: 0, write: 0, execute: 0 } as Record<Capability, number>,\n };\n for (const s of filtered) {\n counts.by_source[s.source]++;\n counts.by_capability[s.capability]++;\n }\n\n return JSON.stringify({ tools: filtered, counts });\n },\n {\n name: \"list_tools\",\n description:\n \"List every tool currently available to this agent — built-in tools, \" +\n \"external (~/.jarela/providers JS plugins), and MCP server tools — with \" +\n \"category, capability (read/write/execute), and source. Read-only. \" +\n \"Use this when the user asks 'what can you do?', when picking between \" +\n \"tools for a task, or when troubleshooting whether a specific tool is \" +\n \"registered. Optional filters narrow by category, capability, or source.\",\n schema: z.object({\n category: z\n .string()\n .optional()\n .describe(\"Optional category filter (e.g. 'Files', 'Mail', 'GitHub', 'MCP')\"),\n capability: z\n .enum([\"read\", \"write\", \"execute\"])\n .optional()\n .describe(\"Optional capability filter — the safety class of the tool\"),\n source: z\n .enum([\"builtin\", \"external\", \"mcp\"])\n .optional()\n .describe(\"Optional source filter — where the tool came from\"),\n }),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listToolsTool]);\n","// Read-only introspection for LLM provider adapters. Two paired tools:\n// - list_providers: enumerate every adapter (built-in + external).\n// - describe_provider: capability map + known model context windows for one.\n// Together they let the agent answer \"what can we route to\" or pick a model\n// by capability without hand-coded knowledge of the provider catalog.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport {\n listProviderNames,\n getProvider,\n BUILTIN_PROVIDER_NAMES,\n} from \"@/lib/providers\";\nimport { listKnownModels } from \"@/lib/providers/known-context-windows\";\nimport { registerTools } from \"./registry\";\n\ntype ProviderSource = \"builtin\" | \"external\";\n\nfunction sourceOf(name: string): ProviderSource {\n return BUILTIN_PROVIDER_NAMES.has(name) ? \"builtin\" : \"external\";\n}\n\nexport const listProvidersTool = tool(\n async () => {\n const names = listProviderNames();\n const providers = names.map((name) => ({\n name,\n source: sourceOf(name),\n }));\n return JSON.stringify({\n providers,\n count: providers.length,\n builtin_count: providers.filter((p) => p.source === \"builtin\").length,\n external_count: providers.filter((p) => p.source === \"external\").length,\n });\n },\n {\n name: \"list_providers\",\n description:\n \"List every LLM provider adapter registered in this app (built-in like \" +\n \"anthropic / openai / gemini / deepseek / github-copilot / langchain, plus \" +\n \"any external `.cjs` plugins under ~/.jarela/providers/). Read-only. \" +\n \"Use this before suggesting a model swap, or when answering 'what can \" +\n \"we route to.' Call describe_provider afterwards for capability details.\",\n schema: z.object({}),\n },\n);\n\nexport const describeProviderTool = tool(\n async ({ name }) => {\n let provider;\n try {\n provider = getProvider(name);\n } catch (err) {\n return JSON.stringify({\n error: err instanceof Error ? err.message : String(err),\n hint: \"Call list_providers to see registered names.\",\n });\n }\n\n // Capability inferred from which methods the adapter implements. We\n // intentionally don't call listModels() here — that would hit the\n // network and require valid credentials, which makes this a \"read\"-class\n // tool that sometimes fails for credential reasons. Static introspection\n // only.\n const capabilities = {\n chat: typeof provider.chat === \"function\",\n invoke: typeof provider.invoke === \"function\",\n stream_invoke: typeof provider.streamInvoke === \"function\",\n embed: typeof provider.embed === \"function\",\n list_models: typeof provider.listModels === \"function\",\n };\n\n const models = listKnownModels(name);\n\n return JSON.stringify({\n name,\n source: sourceOf(name),\n capabilities,\n known_models: models,\n notes: [\n models.length === 0\n ? \"No static model catalog for this provider — call /api/v1/models?provider=\" +\n name + \" for live discovery if the adapter implements list_models.\"\n : \"Static catalog only. Live `list_models` (when supported) may include \" +\n \"newer models not listed here.\",\n ],\n });\n },\n {\n name: \"describe_provider\",\n description:\n \"Return capability flags (chat / invoke / stream / embed / list_models) \" +\n \"and the static known-models catalog (with context windows) for one \" +\n \"registered provider. Read-only. Use this to choose a model by capability, \" +\n \"or to explain provider differences to the user. Call list_providers first \" +\n \"if you don't know the provider name.\",\n schema: z.object({\n name: z\n .string()\n .describe(\"Provider name from list_providers, e.g. 'anthropic', 'openai', 'gemini'\"),\n }),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listProvidersTool, describeProviderTool]);\n","// Read-only introspection of configured MCP servers — names, transports,\n// enabled/disabled state, last connection error, and the count of tools each\n// server contributes to the live tool pool. Lets the agent answer \"why is\n// my Jira tool unavailable?\" without bouncing the user through the UI.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { listMcpServers } from \"@/lib/stores/mcp-servers\";\nimport { getAllToolsAsync } from \"./index\";\nimport { getToolSource } from \"./index\";\nimport { registerTools } from \"./registry\";\n\ninterface McpServerSummary {\n name: string;\n transport: \"stdio\" | \"http\";\n enabled: boolean;\n last_error: string | null;\n tool_count: number;\n created_at: string;\n updated_at: string;\n}\n\nexport const listMcpServersTool = tool(\n async () => {\n const rows = listMcpServers();\n const allTools = await getAllToolsAsync();\n // MCP tools don't carry their server name as a structured field — for\n // the per-server count we count every tool whose source is \"mcp\", and\n // we surface the total separately. Per-server attribution would require\n // a deeper hook into MultiServerMCPClient's tool-namespace metadata,\n // which is a bigger change than this introspection step warrants today.\n const totalMcp = allTools.filter((t) => getToolSource(t.name) === \"mcp\").length;\n\n const servers: McpServerSummary[] = rows.map((r) => ({\n name: r.name,\n transport: r.transport,\n enabled: r.enabled === 1,\n last_error: r.last_error,\n // Per-server tool count not yet attributable; surface total on every\n // row for now and document the limitation in `notes` below.\n tool_count: r.enabled === 1 ? totalMcp : 0,\n created_at: r.created_at,\n updated_at: r.updated_at,\n }));\n\n return JSON.stringify({\n servers,\n count: servers.length,\n enabled_count: servers.filter((s) => s.enabled).length,\n total_mcp_tool_count: totalMcp,\n notes: [\n \"tool_count is an aggregate across all enabled MCP servers — per-server \" +\n \"attribution requires deeper namespace tracking that's not implemented yet.\",\n \"last_error shows the most recent connection error if any; null means \" +\n \"the server has never failed since last config change.\",\n ],\n });\n },\n {\n name: \"list_mcp_servers\",\n description:\n \"List every configured MCP server (stdio or http transport) with its \" +\n \"enabled state, last connection error, and the aggregate count of MCP \" +\n \"tools currently in the agent's pool. Read-only. Use this when \" +\n \"diagnosing 'my <X> tool isn't working' — check enabled and last_error \" +\n \"before assuming the tool itself is broken.\",\n schema: z.object({}),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listMcpServersTool]);\n","// Meta-introspection: a hand-curated catalog of every place a third party\n// (or the agent itself, on behalf of the user) can extend or customize the\n// app. Read-only. The tool returns a structured map that points to the\n// registration entrypoint, the integration guide section, and an example\n// file for each surface — so the agent can answer \"how do I add an X?\"\n// or \"what can be customized\" without needing the docs in its context.\n//\n// SOURCE OF TRUTH: this file. When a new extension surface lands, add an\n// entry below — it's a single source for both the agent runtime and the\n// `docs/EXTENDING.md` table-of-contents anchor.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\ninterface ExtensionSurface {\n id: string;\n name: string;\n summary: string;\n registration_entrypoint: string;\n doc_section: string;\n example_path?: string;\n introspection_tool?: string;\n related_adrs: string[];\n}\n\nconst SURFACES: readonly ExtensionSurface[] = [\n {\n id: \"llm_provider_builtin\",\n name: \"Built-in LLM provider\",\n summary:\n \"Add a new in-tree adapter (Anthropic, OpenAI, Gemini, … pattern). \" +\n \"Implements the ModelProvider interface and is registered via the static \" +\n \"BUILTINS map in lib/providers/index.ts.\",\n registration_entrypoint: \"lib/providers/index.ts (BUILTINS map)\",\n doc_section: \"docs/EXTENDING.md#adding-an-llm-provider-built-in\",\n example_path: \"lib/providers/anthropic.ts\",\n introspection_tool: \"list_providers\",\n related_adrs: [\"ADR-0013\"],\n },\n {\n id: \"llm_provider_external\",\n name: \"External LLM provider plugin\",\n summary:\n \"Drop a `.cjs` plugin into ~/.jarela/providers/ that exports an object \" +\n \"matching ModelProvider. Hot-loaded per call (no rebuild).\",\n registration_entrypoint: \"~/.jarela/providers/<name>.cjs\",\n doc_section: \"docs/EXTENDING.md#adding-an-llm-provider-external\",\n example_path: \"lib/providers/template-external.cjs.example\",\n introspection_tool: \"list_providers\",\n related_adrs: [\"ADR-0013\"],\n },\n {\n id: \"builtin_tool\",\n name: \"Built-in tool\",\n summary:\n \"Add a tool callable by the agent. Implement with @langchain/core/tools, \" +\n \"register with `registerTools(category, capability, [tool])`, and add a \" +\n \"side-effect import in lib/tools/builtins.ts. Capability gating is \" +\n \"read | write | execute.\",\n registration_entrypoint: \"lib/tools/<name>.ts (registerTools call) + lib/tools/builtins.ts\",\n doc_section: \"docs/EXTENDING.md#adding-a-built-in-tool\",\n example_path: \"lib/tools/template.ts\",\n introspection_tool: \"list_tools\",\n related_adrs: [\"ADR-0038\"],\n },\n {\n id: \"mcp_server\",\n name: \"MCP server\",\n summary:\n \"Connect a Model Context Protocol server (stdio or http transport). \" +\n \"Configured via the UI (mcp_servers DB table) or programmatically through \" +\n \"lib/stores/mcp-servers.ts. Tools auto-merge into the same pool as \" +\n \"built-ins. Online discovery via the MCP registry is also supported.\",\n registration_entrypoint: \"lib/stores/mcp-servers.ts (upsertMcpServer)\",\n doc_section: \"docs/EXTENDING.md#adding-an-mcp-server\",\n introspection_tool: \"list_mcp_servers\",\n related_adrs: [\"ADR-0014\"],\n },\n {\n id: \"agent_harness\",\n name: \"Agent harness\",\n summary:\n \"Compose system-prompt sections that shape an agent's behaviour \" +\n \"(plan-first, self-config, capability-listing, etc.). Built-in presets \" +\n \"live in lib/agents/harness/presets.ts; custom harnesses are stored in \" +\n \"the memory_store under the `app-settings` namespace.\",\n registration_entrypoint: \"lib/agents/harness/presets.ts (built-in) or memory_store (custom)\",\n doc_section: \"docs/EXTENDING.md#adding-a-custom-harness\",\n related_adrs: [\"ADR-0036\"],\n },\n {\n id: \"integration_manifest\",\n name: \"Integration manifest\",\n summary:\n \"Add a new agent-led setup recipe — prerequisites, ordered steps, \" +\n \"troubleshooting hints. The agent narrates the recipe and proposes \" +\n \"the corresponding config changes through propose_config_change.\",\n registration_entrypoint: \"lib/integrations/registry.ts\",\n doc_section: \"docs/EXTENDING.md#adding-an-integration-manifest\",\n introspection_tool: \"list_integrations\",\n related_adrs: [\"ADR-0010\"],\n },\n {\n id: \"brand_overlay\",\n name: \"Brand / app identity\",\n summary:\n \"Customize the app's name, description, and issue URL via environment \" +\n \"variables. No code change required. Used by downstream packages that \" +\n \"consume @circuitwall/jarela as an npm dep (e.g. brand overlays).\",\n registration_entrypoint: \"NEXT_PUBLIC_APP_NAME, NEXT_PUBLIC_APP_DESCRIPTION, NEXT_PUBLIC_APP_ISSUE_URL\",\n doc_section: \"docs/EXTENDING.md#branding-the-app\",\n related_adrs: [\"ADR-0005\"],\n },\n];\n\nexport const describeExtensionSurfacesTool = tool(\n async () => {\n return JSON.stringify({\n surfaces: SURFACES,\n count: SURFACES.length,\n guide_path: \"docs/EXTENDING.md\",\n contract_paths: [\n \"lib/providers/types.ts (ModelProvider interface)\",\n \"lib/tools/types.ts (OpenAITool, ToolContext, InvokeMessage)\",\n \"lib/tools/registry.ts (registerTools, ToolCategory, Capability)\",\n \"lib/mcp/registry.ts (RegistryEntry, applyVariables)\",\n ],\n notes: [\n \"Each surface's introspection_tool, when set, lets you enumerate what's \" +\n \"currently registered. Call those when the user asks 'what's available' \" +\n \"rather than describing the type from memory.\",\n \"A surface can have either a static example_path (for external plugins) or \" +\n \"no example (for surfaces wired entirely through the UI / DB). When in \" +\n \"doubt, the doc_section under EXTENDING.md is the canonical walk-through.\",\n ],\n });\n },\n {\n name: \"describe_extension_surfaces\",\n description:\n \"Return the curated catalog of every extension surface in this app — \" +\n \"providers, tools, MCP servers, harnesses, integration manifests, brand \" +\n \"overlay. Each entry has a registration entrypoint, an EXTENDING.md \" +\n \"section anchor, and (when applicable) the introspection tool that lists \" +\n \"what's currently registered. Read-only. Call this when the user asks \" +\n \"'how do I add an X?' or 'what can be customized?' so you can guide \" +\n \"them with the right files and docs.\",\n schema: z.object({}),\n },\n);\n\nregisterTools(\"Config\", \"read\", [describeExtensionSurfacesTool]);\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 \"./files-search\";\nimport \"./workspace\";\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\";\nimport \"./delegate\";\nimport \"./system_config\";\nimport \"./list-tools\";\nimport \"./providers-info\";\nimport \"./mcp-servers-info\";\nimport \"./extension-surfaces\";\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>\", \"<read|write|execute>\", [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 registeredCapability,\n registeredGroup,\n type Capability,\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 {\n registerTools,\n type Capability,\n type ToolCategory,\n type ToolGroup,\n} from \"./registry\";\n\n// Live accessors — DO NOT snapshot at module-load time. Some tool modules\n// import back from this file (for `getAllToolsAsync` etc.) and would create\n// a circular import cycle: their `registerTools(...)` call runs AFTER this\n// module finishes evaluating, so any captured snapshot here would miss them\n// and they'd silently disappear from the agent's tool pool. Live calls dodge\n// the problem — by the time anyone INVOKES `getAllTools()` / etc., every\n// builtin has registered.\nfunction allBuiltins(): StructuredToolInterface[] {\n return registeredTools();\n}\nfunction builtinNames(): ReadonlySet<string> {\n return registeredNames();\n}\n\n// Backwards-compatible export. Callers that import this Set get its current\n// contents at the moment they read it (a fresh Set each access). Internal\n// code prefers `builtinNames()` directly; this stays for external consumers\n// like the extensions API route.\nexport function getBuiltinToolNames(): ReadonlySet<string> {\n return builtinNames();\n}\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(builtinNames());\n}\n\nexport type ToolSource = \"builtin\" | \"external\" | \"mcp\";\n\n// Resolve a tool's origin from its name. Used to label rows in the tools\n// API and to route metadata lookups. Returns \"mcp\" for any name that is\n// neither a registered built-in nor an external (JARELA_TOOLS_DIR) tool —\n// matches today's behavior where MCP tools are everything else.\nexport function getToolSource(name: string): ToolSource {\n if (builtinNames().has(name)) return \"builtin\";\n if (loadExternal().tools.some((t) => t.name === name)) return \"external\";\n return \"mcp\";\n}\n\n// Look up a tool's safety class. Built-in tools have a declared capability;\n// external (JARELA_TOOLS_DIR) and MCP tools default to \"execute\" — the\n// conservative choice until manifest-level overrides land (ADR-0038).\n// Source is derived internally so callers can't mis-tag external tools as\n// MCP (or vice versa).\nexport function getToolCapability(name: string): Capability {\n return registeredCapability(name) ?? \"execute\";\n}\n\nexport function getToolCategory(name: string): 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 getToolSource(name) === \"mcp\" ? \"MCP\" : \"Config\";\n}\n\nexport function getToolGroup(name: string): ToolGroup {\n const cat = getToolCategory(name);\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(allBuiltins()), ...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(allBuiltins()), ...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 = allBuiltins().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: allBuiltins().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","// Web-sourced fallback context-window sizes per (provider, model_id).\n// Used when the live `/models` endpoint doesn't report `context_length`\n// (OpenAI's catalog and GitHub Copilot's catalog both omit it) AND the\n// user hasn't pinned `context_window_tokens` on the model config.\n//\n// Resolution order at runtime is:\n// 1. user-set `params.context_window_tokens` (explicit override)\n// 2. live API value via `listModels()` / catalog cache (when populated)\n// 3. this static fallback (this file)\n// 4. `DEFAULT_CONTEXT_WINDOW_TOKENS` in lib/agents/context-budget.ts\n//\n// Verified from each vendor's public docs as of 2026-06. Bump when vendors\n// publish new families.\n\nexport interface KnownModelLimits {\n context_length: number;\n max_output_tokens?: number;\n}\n\nconst ANTHROPIC: Record<string, KnownModelLimits> = {\n \"claude-opus-4-7\": { context_length: 1_000_000, max_output_tokens: 8192 },\n \"claude-opus-4\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-sonnet-4-6\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-sonnet-4\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3.7-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-7-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-5-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-5-haiku\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-haiku-4-5\": { context_length: 200_000, max_output_tokens: 4096 },\n \"claude-haiku-4\": { context_length: 200_000, max_output_tokens: 4096 },\n \"claude-3-opus\": { context_length: 200_000, max_output_tokens: 4096 },\n};\n\nconst GEMINI: Record<string, KnownModelLimits> = {\n \"gemini-2.5-pro\": { context_length: 1_048_576, max_output_tokens: 65_536 },\n \"gemini-2.5-flash\": { context_length: 1_048_576, max_output_tokens: 65_536 },\n \"gemini-2.0-flash-lite\": { context_length: 1_048_576, max_output_tokens: 8192 },\n \"gemini-2.0-flash\": { context_length: 1_048_576, max_output_tokens: 8192 },\n \"gemini-1.5-pro\": { context_length: 2_097_152, max_output_tokens: 8192 },\n \"gemini-1.5-flash\": { context_length: 1_048_576, max_output_tokens: 8192 },\n};\n\nconst OPENAI: Record<string, KnownModelLimits> = {\n \"gpt-5-mini\": { context_length: 400_000, max_output_tokens: 128_000 },\n \"gpt-5\": { context_length: 400_000, max_output_tokens: 128_000 },\n \"gpt-4.1-mini\": { context_length: 1_047_576, max_output_tokens: 32_768 },\n \"gpt-4.1\": { context_length: 1_047_576, max_output_tokens: 32_768 },\n \"gpt-4o-mini\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"gpt-4o\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"gpt-4-turbo\": { context_length: 128_000, max_output_tokens: 4096 },\n \"gpt-4\": { context_length: 8192, max_output_tokens: 4096 },\n \"gpt-3.5-turbo\": { context_length: 16_385, max_output_tokens: 4096 },\n \"chatgpt-4o\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"o4-mini\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o3-mini\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o3\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o1-mini\": { context_length: 128_000, max_output_tokens: 65_536 },\n \"o1\": { context_length: 200_000, max_output_tokens: 100_000 },\n};\n\nconst DEEPSEEK: Record<string, KnownModelLimits> = {\n \"deepseek-v4-flash\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-v4-pro\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-chat\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-reasoner\": { context_length: 65_536, max_output_tokens: 8192 },\n};\n\n// GitHub Copilot proxies vendor models — sometimes under a transformed id\n// (e.g. `Github-Opus4.6`, `copilot-claude-3.5-sonnet`). Strip the proxy\n// prefix and dispatch to the underlying vendor table.\nfunction resolveCopilot(model_id: string): KnownModelLimits | null {\n const normalized = model_id\n .replace(/^(?:Github-|copilot-)/i, \"\")\n .toLowerCase();\n // Canonicalise a few proxy-specific spellings.\n const canon = normalized\n .replace(/^opus4\\.6/, \"claude-opus-4-7\")\n .replace(/^opus4/, \"claude-opus-4\")\n .replace(/^sonnet4\\.6/, \"claude-sonnet-4-6\")\n .replace(/^sonnet4/, \"claude-sonnet-4\")\n .replace(/^haiku4\\.5/, \"claude-haiku-4-5\");\n if (canon.startsWith(\"claude\")) return matchPrefix(ANTHROPIC, canon);\n if (canon.startsWith(\"gemini\")) return matchPrefix(GEMINI, canon);\n if (canon.startsWith(\"gpt\") || /^o[134](?:-|$)/.test(canon)) return matchPrefix(OPENAI, canon);\n return null;\n}\n\nfunction matchPrefix(table: Record<string, KnownModelLimits>, id: string): KnownModelLimits | null {\n const lower = id.toLowerCase();\n const exact = table[lower];\n if (exact) return exact;\n // Longest-prefix match so `gpt-4o-2024-08-06` resolves to `gpt-4o` and\n // not `gpt-4` (which would also prefix-match).\n let best: { key: string; v: KnownModelLimits } | null = null;\n for (const [k, v] of Object.entries(table)) {\n if (lower.startsWith(k) && (!best || k.length > best.key.length)) {\n best = { key: k, v };\n }\n }\n return best?.v ?? null;\n}\n\nexport function getKnownModelLimits(provider: string, model_id: string): KnownModelLimits | null {\n if (!provider || !model_id) return null;\n switch (provider) {\n case \"anthropic\": return matchPrefix(ANTHROPIC, model_id);\n case \"gemini\": return matchPrefix(GEMINI, model_id);\n case \"openai\": return matchPrefix(OPENAI, model_id);\n case \"deepseek\": return matchPrefix(DEEPSEEK, model_id);\n case \"github-copilot\": return resolveCopilot(model_id);\n default: return null;\n }\n}\n\nexport function getKnownContextLength(provider: string, model_id: string): number | null {\n return getKnownModelLimits(provider, model_id)?.context_length ?? null;\n}\n\nexport function getKnownMaxOutputTokens(provider: string, model_id: string): number | null {\n return getKnownModelLimits(provider, model_id)?.max_output_tokens ?? null;\n}\n\n// Flat catalog snapshot for one provider — used by introspection tools so\n// the agent can enumerate what's known statically. Returns [] for providers\n// without a static table (e.g. `langchain`, `mock`, externals).\nexport function listKnownModels(\n provider: string,\n): Array<{ model_id: string; context_length: number; max_output_tokens: number | null }> {\n let table: Record<string, KnownModelLimits> | null = null;\n switch (provider) {\n case \"anthropic\": table = ANTHROPIC; break;\n case \"gemini\": table = GEMINI; break;\n case \"openai\": table = OPENAI; break;\n case \"deepseek\": table = DEEPSEEK; break;\n default: return [];\n }\n return Object.entries(table).map(([model_id, l]) => ({\n model_id,\n context_length: l.context_length,\n max_output_tokens: l.max_output_tokens ?? null,\n }));\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 type { ContentPart } from \"@/lib/tools/types\";\nimport { prepareThreadRun, persistAssistantMessage, snapshotThreadModelConfigName, withInterruptMarker } from \"@/lib/agents/run-thread\";\nimport type { AssistantUsageSnapshot } from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { enqueueThreadRun } from \"@/lib/agents/run-queue\";\nimport { startRun, finishRun, broadcast } from \"@/lib/agents/run-registry\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { resolveTurnProfile, type TurnContextProfile } from \"@/lib/agents/turn-profile\";\n\nconst NO_REPLY_RE = /^\\s*NO[_ ]?REPLY\\b/i;\n\nexport type AgentTurnQueueSource =\n | \"user\"\n | \"scheduler\"\n | \"watcher\"\n | \"trigger\"\n | \"bridge\"\n | \"extension\"\n | \"delegate\";\n\nexport interface RunAgentTurnRequest {\n thread_id: string;\n queue_source: AgentTurnQueueSource;\n message: string;\n attachments?: ContentPart[];\n user_category?: string | null;\n assistant_category?: string | null;\n silent?: boolean;\n /**\n * When true, `prepareThreadRun` will NOT add the message to the DB.\n * Use this when the caller has already persisted the user message and\n * only wants to run the agent against it (e.g. page-capture observer).\n */\n skip_persist_user_message?: boolean;\n\n /**\n * Per-call override of the context profile (see\n * `@/lib/agents/turn-profile`). When omitted, the profile is resolved\n * from `queue_source` via `TURN_PROFILES`. Provide partial overrides\n * to flip an individual toggle for a specific call without changing\n * the category default.\n */\n context_profile_override?: Partial<TurnContextProfile> | null;\n}\n\nexport interface RunAgentTurnResult {\n assistantContent: string;\n preview: string;\n skippedAssistant: boolean;\n usage: AssistantUsageSnapshot | null;\n}\n\n/**\n * Canonical external-turn runner: queue -> prepare -> collect -> persist.\n *\n * Use this for non-UI callers (bridges, triggers, watchers, schedulers) so\n * they all share the same silent-mode and persistence rules.\n */\nexport async function runAgentTurn(req: RunAgentTurnRequest): Promise<RunAgentTurnResult> {\n const pinnedModelConfigName = snapshotThreadModelConfigName(req.thread_id);\n const contextProfile = resolveTurnProfile(req.queue_source, req.context_profile_override);\n const thread = getThread(req.thread_id);\n const enqueued = enqueueThreadRun(req.thread_id, req.queue_source, async () => {\n // Register in the run-registry like the HTTP route does so the idle\n // and wall-clock watchdogs bound this execution. Without this, a\n // hung provider stream (bad creds, dead upstream, runaway tool loop)\n // from any non-HTTP entry point would pin the per-thread queue head\n // indefinitely. Lives inside the queued callback so registry slots\n // serialise with the queue.\n const active = startRun(req.thread_id, thread?.agent_id ?? null);\n let terminal: \"done\" | \"error\" = \"error\";\n try {\n const prepared = await prepareThreadRun({\n thread_id: req.thread_id,\n message: req.message,\n attachments: req.attachments,\n user_category: req.user_category ?? null,\n context_profile: contextProfile,\n signal: active.abort.signal,\n _pinned_model_config_name: pinnedModelConfigName,\n _skip_persist_message: req.skip_persist_user_message,\n });\n\n const collected = await collectStream(prepared.stream, {\n onChunk: (chunk) => broadcast(active, chunk),\n });\n const trimmed = collected.assistantContent.trim();\n // Silent-mode runners (bridges, watchers, schedulers) skip persistence\n // when the model emitted nothing meaningful — but if the run was\n // user-aborted, we still want a record so the next turn isn't blind to\n // the interruption.\n const skipSilent = req.silent === true\n && !collected.aborted\n && (trimmed.length === 0 || NO_REPLY_RE.test(trimmed));\n\n if (!skipSilent) {\n const contentToPersist = collected.aborted\n ? withInterruptMarker(collected.assistantContent)\n : collected.assistantContent;\n persistAssistantMessage(\n req.thread_id,\n contentToPersist,\n collected.usedTools,\n collected.toolEvents,\n req.assistant_category ?? req.user_category ?? null,\n collected.usage ?? null,\n prepared.context_snapshot ?? null,\n prepared.source_manifest ?? null,\n );\n }\n\n terminal = collected.terminal === \"error\" ? \"error\" : \"done\";\n return {\n assistantContent: collected.assistantContent,\n skippedAssistant: skipSilent,\n usage: collected.usage ?? null,\n };\n } finally {\n finishRun(active, terminal);\n }\n });\n\n const done = await enqueued.result;\n return {\n assistantContent: done.assistantContent,\n skippedAssistant: done.skippedAssistant,\n usage: done.usage,\n preview: done.skippedAssistant\n ? \"\"\n : done.assistantContent.replace(/\\s+/g, \" \").trim().slice(0, 120),\n };\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","import type { StreamChunk } from \"./base\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// In-memory registry of in-flight agent runs, keyed by thread_id. When the user\n// switches agents mid-stream, the run keeps going server-side; if they return\n// (or open a second tab), they re-attach via subscribe() and see live deltas.\n//\n// Trade-offs:\n// - Single Node process only. Multi-instance deploys would need a shared\n// pubsub (Redis, NATS) — not in scope for a local app.\n// - Buffered events are capped to MAX_BUFFERED so a 100k-token response\n// doesn't pin GBs of memory if every chunk lingers. Late attachers see the\n// most recent slice plus all subsequent events.\n\ntype Subscriber = (chunk: StreamChunk) => void;\n\n// Read once at module init. JARELA_RUN_BUFFER_SIZE / JARELA_RUN_REGISTRY_TTL_MS\n// override the defaults.\nconst MAX_BUFFERED = getConfig().runBufferSize;\nconst RECENT_TTL_MS = getConfig().runRegistryTtlMs;\n// Idle (no-progress) ceiling and wall-clock ceiling: read fresh per-run\n// from getConfig() so non-restart-required env reloads take effect.\nfunction runIdleMs(): number { return getConfig().runIdleMs; }\nfunction runMaxMs(): number { return getConfig().runMaxMs; }\n\nexport interface ActiveRun {\n thread_id: string;\n agent_id: string | null;\n started_at: number;\n finished_at: number | null;\n status: \"running\" | \"done\" | \"error\";\n events: StreamChunk[];\n subscribers: Set<Subscriber>;\n // Final assistant text — useful for notification body without replaying every event.\n final_text: string;\n // Server-side abort: when the user clicks Stop (or the last client\n // disconnects), we signal this controller so the LangGraph stream cancels\n // itself instead of running to completion in the background.\n abort: AbortController;\n // Last activity timestamp — bumped on every broadcast() so the idle\n // watchdog can tell live progress from a wedged stream.\n last_chunk_at: number;\n // Tool-call ids that have been announced (tool_call) but not yet\n // resolved (tool_result). The idle watchdog pauses while this is\n // non-empty: silence between a tool_call and its tool_result is the\n // tool executing, not a wedged provider stream, and tools have their\n // own per-tool timeouts.\n inflight_tools: Set<string>;\n // Per-tool start timestamps for the entries in `inflight_tools`. The\n // wall-clock watchdog uses these (plus `tool_time_ms_done`) to\n // discount tool execution from the agent's wall-clock budget — see\n // `effectiveElapsedMs()`. The agent's wall-clock bounds *agent +\n // provider* time; long-running tools (a big shell exec, a slow MCP\n // call) shouldn't burn it. Each tool already enforces its own\n // per-call timeout (lib/tools/exec.ts, lib/tools/fetch.ts, MCP SDKs)\n // so a hung tool still terminates — it just doesn't pull the agent\n // loop down with it.\n tool_started_at: Map<string, number>;\n // Cumulative wall-clock time spent inside completed tool calls. Adds\n // on each tool_result; never decreases.\n tool_time_ms_done: number;\n}\n\nconst runs = new Map<string, ActiveRun>();\n\nexport function startRun(thread_id: string, agent_id: string | null): ActiveRun {\n // If a stale completed run exists, drop it before starting a new one.\n const existing = runs.get(thread_id);\n if (existing && existing.status === \"running\") {\n throw new Error(`A run is already active for thread ${thread_id}`);\n }\n const now = Date.now();\n const run: ActiveRun = {\n thread_id,\n agent_id,\n started_at: now,\n finished_at: null,\n status: \"running\",\n events: [],\n subscribers: new Set(),\n final_text: \"\",\n abort: new AbortController(),\n last_chunk_at: now,\n inflight_tools: new Set<string>(),\n tool_started_at: new Map<string, number>(),\n tool_time_ms_done: 0,\n };\n runs.set(thread_id, run);\n scheduleIdleWatchdog(run);\n scheduleMaxWatchdog(run);\n return run;\n}\n\n// Synthesise a typed error chunk for the watchdog termination paths and\n// fan it out to subscribers BEFORE flipping `status` to \"error\". The order\n// matters: `broadcast()`'s status guard drops any chunk delivered after\n// `finishRun()` has run, so calling finishRun first would silently swallow\n// the error and the client's EventSource would just see the connection\n// close with no terminal event — bubble keeps spinning, no toast. Doing\n// it the other way around lets the client receive a real error event,\n// render a \"Run timed out\" toast, and (if the consumer wires it up)\n// trigger an auto-retry path. Followed by `done` so the consumer's\n// for-await loop can break cleanly without waiting for an EOF.\nfunction emitWatchdogTermination(\n run: ActiveRun,\n code: \"run_idle_timeout\" | \"run_max_timeout\",\n message: string,\n): void {\n if (run.status !== \"running\") return;\n // Direct registry mutation so the broadcast goes through the regular\n // path (subscribers + buffer + seq stamp) without re-entering any of\n // the watchdog scheduling. Mirrors broadcast() but bypasses the\n // status check we'd otherwise be racing against.\n run.last_chunk_at = Date.now();\n const errChunk: StreamChunk = { type: \"error\", data: { message, code } };\n if (run.events.length < MAX_BUFFERED) run.events.push(errChunk);\n for (const fn of run.subscribers) {\n try { fn(errChunk); } catch { /* subscriber errored, ignore */ }\n }\n // Pair with a synthetic `done` so the client's consume() loop breaks\n // on a terminal event rather than waiting for the EventSource to close.\n const doneChunk: StreamChunk = { type: \"done\", data: {} };\n if (run.events.length < MAX_BUFFERED) run.events.push(doneChunk);\n for (const fn of run.subscribers) {\n try { fn(doneChunk); } catch { /* */ }\n }\n}\n\n// Self-rearming idle watchdog. Fires when no chunk has arrived for\n// `idleMs`; otherwise reschedules itself for `(last_chunk_at + idleMs) -\n// now`. We never carry a handle on the run — the closure just bails if\n// the run is no longer the registry's entry or no longer running.\nfunction scheduleIdleWatchdog(run: ActiveRun): void {\n const idleMs = runIdleMs();\n const fireIn = Math.max(0, (run.last_chunk_at + idleMs) - Date.now());\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur !== run) return;\n if (run.status !== \"running\") return;\n const idle = Date.now() - run.last_chunk_at;\n if (idle < idleMs) {\n scheduleIdleWatchdog(run);\n return;\n }\n if (run.inflight_tools.size > 0) {\n // Tool execution in progress — silence here is the tool working,\n // not a wedged provider stream. Skip the kill, re-check in idleMs.\n // The tool_result will bump last_chunk_at when it lands.\n setTimeout(() => scheduleIdleWatchdog(run), idleMs).unref?.();\n return;\n }\n console.warn(`[run-registry] idle watchdog: force-finishing stalled run for thread ${run.thread_id} after ${idle}ms of no progress`);\n emitWatchdogTermination(\n run,\n \"run_idle_timeout\",\n `Run timed out — no progress for ${Math.round(idle / 1000)}s. The provider stream went silent before the agent finished. Try again, or split the request into smaller steps.`,\n );\n try { run.abort.abort(\"run_idle_timeout\"); } catch { /* */ }\n finishRun(run, \"error\");\n }, fireIn).unref?.();\n}\n\n// Wall-clock elapsed minus time spent inside tool calls (both completed and\n// currently in flight). The wall-clock watchdog uses this so a 5-minute\n// shell exec or a slow MCP roundtrip doesn't burn the agent's budget;\n// tools enforce their own timeouts. See ActiveRun.tool_started_at for the\n// rationale.\nfunction effectiveElapsedMs(run: ActiveRun, now: number): number {\n let inflightToolMs = 0;\n for (const startedAt of run.tool_started_at.values()) {\n inflightToolMs += Math.max(0, now - startedAt);\n }\n return Math.max(0, (now - run.started_at) - run.tool_time_ms_done - inflightToolMs);\n}\n\nfunction scheduleMaxWatchdog(run: ActiveRun): void {\n const max = runMaxMs();\n const now = Date.now();\n const fireIn = Math.max(0, max - effectiveElapsedMs(run, now));\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur !== run) return;\n if (run.status !== \"running\") return;\n const elapsed = effectiveElapsedMs(run, Date.now());\n if (elapsed < max) {\n // Tool time pushed the effective elapsed back below the ceiling —\n // re-arm for the remaining budget. Without this, a tool that runs\n // for longer than `max` between firing and resolving would let\n // the next setTimeout overshoot.\n scheduleMaxWatchdog(run);\n return;\n }\n console.warn(`[run-registry] wall-clock watchdog: force-finishing run for thread ${run.thread_id} after ${elapsed}ms of agent time (excluding tool execution)`);\n emitWatchdogTermination(\n run,\n \"run_max_timeout\",\n `Run exceeded the wall-clock limit (${Math.round(max / 1000)}s of agent time, excluding tool execution). The agent was force-stopped. Try a smaller scope or raise JARELA_RUN_MAX_MS if this is expected.`,\n );\n try { run.abort.abort(\"run_watchdog_timeout\"); } catch { /* */ }\n finishRun(run, \"error\");\n }, fireIn).unref?.();\n}\n\nexport function broadcast(run: ActiveRun, chunk: StreamChunk): void {\n // Identity-check: a superseded run must not smear trailing chunks onto\n // the replacement entry in the registry.\n if (runs.get(run.thread_id) !== run) return;\n run.last_chunk_at = Date.now();\n if (chunk.type === \"text_delta\") {\n run.final_text += (chunk.data.delta as string) ?? \"\";\n } else if (chunk.type === \"tool_call\") {\n const id = (chunk.data as { id?: string }).id;\n if (id) {\n run.inflight_tools.add(id);\n run.tool_started_at.set(id, Date.now());\n }\n } else if (chunk.type === \"tool_result\") {\n const id = (chunk.data as { id?: string }).id;\n if (id) {\n run.inflight_tools.delete(id);\n const startedAt = run.tool_started_at.get(id);\n if (startedAt !== undefined) {\n run.tool_time_ms_done += Math.max(0, Date.now() - startedAt);\n run.tool_started_at.delete(id);\n // The tool just gave the agent its budget back; re-arm the\n // wall-clock watchdog against the new effective elapsed.\n scheduleMaxWatchdog(run);\n }\n }\n }\n if (run.events.length < MAX_BUFFERED) {\n run.events.push(chunk);\n }\n for (const fn of run.subscribers) {\n try { fn(chunk); } catch { /* subscriber errored, ignore */ }\n }\n}\n\nexport function finishRun(run: ActiveRun, status: \"done\" | \"error\"): void {\n // Identity-check: a stale run finishing late must not flip the\n // replacement's status or evict it from the registry.\n if (runs.get(run.thread_id) !== run) return;\n run.status = status;\n run.finished_at = Date.now();\n // Drop subscribers — late attachers should NOT keep getting events on a\n // dead run. They'll get the buffered events on subscribe and that's it.\n run.subscribers.clear();\n // Auto-evict after TTL so memory doesn't grow with every conversation.\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur === run) runs.delete(run.thread_id);\n }, RECENT_TTL_MS).unref?.();\n}\n\nexport function getRun(thread_id: string): ActiveRun | null {\n return runs.get(thread_id) ?? null;\n}\n\n// Signal the agent stream to cancel. The stream loop in the route is wired\n// to listen on the AbortController and exit early, emitting an error chunk\n// the client (and the queue-drain hook) can react to. Idempotent.\nexport function abortRun(thread_id: string, reason = \"user_interrupted\"): boolean {\n const run = runs.get(thread_id);\n if (!run || run.status !== \"running\") return false;\n if (!run.abort.signal.aborted) {\n try { run.abort.abort(reason); } catch { /* */ }\n }\n return true;\n}\n\n// Abort every currently-running run. Used by the graceful-shutdown path so\n// LangGraph stream loops bail out instead of continuing past process exit.\n// Returns the number of runs that were signalled.\nexport function abortAllRuns(reason = \"server_shutdown\"): number {\n let count = 0;\n for (const run of runs.values()) {\n if (run.status !== \"running\") continue;\n if (run.abort.signal.aborted) continue;\n try { run.abort.abort(reason); count++; } catch { /* */ }\n }\n return count;\n}\n\n// Poll until every run has transitioned out of \"running\" (or until the\n// caller-supplied deadline elapses). Used during graceful shutdown after\n// `abortAllRuns()` so the stream `finally` blocks have a chance to flush\n// the trailing error chunk and call `finishRun()`. Resolves to the count\n// of runs still stuck in \"running\" when the deadline hit (0 = clean).\nexport async function waitForRunsToSettle(timeoutMs: number): Promise<number> {\n const deadline = Date.now() + Math.max(0, timeoutMs);\n while (Date.now() < deadline) {\n let stillRunning = 0;\n for (const run of runs.values()) if (run.status === \"running\") stillRunning++;\n if (stillRunning === 0) return 0;\n await new Promise<void>((resolve) => setTimeout(resolve, 50));\n }\n let stillRunning = 0;\n for (const run of runs.values()) if (run.status === \"running\") stillRunning++;\n return stillRunning;\n}\n\n// Replays buffered events synchronously, then subscribes for live ones.\n// Returns an unsubscribe fn. Caller is responsible for calling it.\nexport function subscribe(\n thread_id: string,\n onEvent: Subscriber,\n): { run: ActiveRun | null; unsubscribe: () => void } {\n const run = runs.get(thread_id);\n if (!run) return { run: null, unsubscribe: () => {} };\n // Replay buffered events first (so the new subscriber catches up).\n for (const ev of run.events) {\n try { onEvent(ev); } catch { /* */ }\n }\n if (run.status !== \"running\") {\n return { run, unsubscribe: () => {} };\n }\n run.subscribers.add(onEvent);\n return {\n run,\n unsubscribe: () => { run.subscribers.delete(onEvent); },\n };\n}\n","// Per-category context profile for an agent turn.\n//\n// Different turn sources need different slices of the agent's context.\n// A user chatting wants the full hot+warm history of their thread; a\n// one-shot extension \"fill this field\" call wants ONLY the per-call\n// instruction + page context so prior chat doesn't bleed in; a bridge\n// message wants hot+warm because chat messages are connected; a\n// scheduled task wants neither hot nor warm because each firing is a\n// standalone event.\n//\n// This module is the single source of truth. To change the policy for\n// a category, edit `TURN_PROFILES` below — every external runner\n// (extension, bridge, scheduler, watcher, trigger, delegate, HTTP user\n// run) resolves its profile through `resolveTurnProfile` and threads\n// it into `prepareThreadRun`, which applies the toggles at LLM-call\n// assembly time.\n//\n// Facts and recall are global to the agent (memory store + embeddings)\n// and tools come from the agent config — they're NOT per-thread state\n// — so disabling them here just means \"don't paste the recall/facts\n// blocks into THIS turn's system prompt\". The agent can still call\n// `memory_read` / `memory_list` / `web_search` etc. if its tool\n// allow-list includes them.\n\nimport type { AgentTurnQueueSource } from \"@/lib/agents/agent-turn\";\n\nexport interface TurnContextProfile {\n /** Paste the recent thread messages into the LLM call. */\n include_hot: boolean;\n /** Paste the warm-summary block into the system prompt. */\n include_warm: boolean;\n /** Paste the `--- Facts memory ---` block into the system prompt. */\n include_facts: boolean;\n /** Paste the embedding-based recall block into the system prompt. */\n include_recall: boolean;\n}\n\nexport const FULL_PROFILE: TurnContextProfile = {\n include_hot: true,\n include_warm: true,\n include_facts: true,\n include_recall: true,\n};\n\nexport const ONE_SHOT_PROFILE: TurnContextProfile = {\n include_hot: false,\n include_warm: false,\n include_facts: false,\n include_recall: false,\n};\n\n// Category → profile. Add new categories alongside `AgentTurnQueueSource`.\n// To change a category's behaviour, edit ONLY this table.\nexport const TURN_PROFILES: Record<AgentTurnQueueSource, TurnContextProfile> = {\n // Normal chat needs the full thread context.\n user: FULL_PROFILE,\n // Bridge messages are conversational — keep the connection between turns.\n bridge: FULL_PROFILE,\n // Delegate hand-offs need the parent's recent context so the child can\n // pick up the conversation thread.\n delegate: FULL_PROFILE,\n // One-shot automation events: each firing is standalone. Memory + tools\n // still available, but no prior chat history bleeds into the answer.\n extension: ONE_SHOT_PROFILE,\n scheduler: ONE_SHOT_PROFILE,\n watcher: ONE_SHOT_PROFILE,\n trigger: ONE_SHOT_PROFILE,\n};\n\nexport function resolveTurnProfile(\n source: AgentTurnQueueSource | null | undefined,\n override?: Partial<TurnContextProfile> | null,\n): TurnContextProfile {\n const base = source ? TURN_PROFILES[source] : FULL_PROFILE;\n if (!override) return base;\n return { ...base, ...override };\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 agent_id?: string;\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 agent_id=?, 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 patch.agent_id === undefined ? existing.agent_id : patch.agent_id,\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","// 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","// Periodic health-probe runner. Iterates the registered probes from\n// ./probes.ts, races each against a short timeout, and translates state\n// transitions into `health_alert` notification events.\n//\n// Why state transitions: the probe pool runs every ~10min server-side and\n// can also be triggered on demand. Without dedup the user would see the\n// same \"Atlassian rejected the token\" toast every cycle until they fixed\n// it. We publish:\n// * fail → first failure since last success, OR every RE_ALERT_MS while\n// still failing (so the user is reminded the integration is\n// still broken even if they dismissed the toast).\n// * recovered → the probe that was failing is now green again.\n//\n// \"Unconfigured\" probes (operator never set the credential) are silently\n// ignored — only configured-but-broken probes alert. State lives on\n// globalThis (per-process, in-memory) so a restart re-evaluates from\n// scratch.\n\nimport { publish } from \"@/lib/notifications/bus\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport {\n listProbes,\n probeCategory,\n probeLabel,\n runProbe,\n type HealthResult,\n type ProbeName,\n} from \"./probes\";\n\nconst RE_ALERT_MS = 30 * 60 * 1000; // re-fire after 30 min of continuous failure\n\nexport interface ProbeState {\n name: ProbeName;\n category: \"integration\" | \"llm\";\n label: string;\n lastResult: HealthResult | null;\n lastCheckedAt: number;\n // null when never failed; set to first-failure timestamp while failing.\n failingSince: number | null;\n // last time we published an alert for this probe — drives the re-alert\n // backoff. Reset to 0 on recovery.\n lastAlertAt: number;\n}\n\ninterface RunnerState {\n probes: Map<ProbeName, ProbeState>;\n lastRunAt: number;\n // Set while a run is in flight so two concurrent triggers (scheduler +\n // /api/v1/health?refresh=1) don't double-probe every vendor.\n inFlight: boolean;\n}\n\nconst state = getOrCreateGlobal<RunnerState>(\"__jarela_health_runner\", () => ({\n probes: new Map(),\n lastRunAt: 0,\n inFlight: false,\n}));\n\nfunction getOrInit(name: ProbeName): ProbeState {\n let s = state.probes.get(name);\n if (!s) {\n s = {\n name,\n category: probeCategory(name),\n label: probeLabel(name),\n lastResult: null,\n lastCheckedAt: 0,\n failingSince: null,\n lastAlertAt: 0,\n };\n state.probes.set(name, s);\n }\n return s;\n}\n\n// Public: snapshot for the /api/v1/health route.\nexport interface HealthSnapshot {\n ranAt: number;\n probes: Array<{\n name: string;\n category: \"integration\" | \"llm\";\n label: string;\n status: HealthResult[\"status\"] | \"never_checked\";\n ok: boolean;\n error: string | null;\n detail: Record<string, unknown> | null;\n lastCheckedAt: number;\n failingSince: number | null;\n }>;\n}\n\nexport function getHealthSnapshot(): HealthSnapshot {\n const probes: HealthSnapshot[\"probes\"] = [];\n for (const name of listProbes()) {\n const s = state.probes.get(name);\n if (!s) {\n probes.push({\n name,\n category: probeCategory(name),\n label: probeLabel(name),\n status: \"never_checked\",\n ok: false,\n error: null,\n detail: null,\n lastCheckedAt: 0,\n failingSince: null,\n });\n continue;\n }\n probes.push({\n name: s.name,\n category: s.category,\n label: s.label,\n status: s.lastResult?.status ?? \"never_checked\",\n ok: s.lastResult?.ok ?? false,\n error: s.lastResult?.error ?? null,\n detail: s.lastResult?.detail ?? null,\n lastCheckedAt: s.lastCheckedAt,\n failingSince: s.failingSince,\n });\n }\n return { ranAt: state.lastRunAt, probes };\n}\n\n// Publish-vs-skip decision for a single probe transition.\nfunction reconcileProbe(s: ProbeState, prev: HealthResult | null, next: HealthResult, now: number): void {\n if (next.ok) {\n if (s.failingSince !== null) {\n // Was failing, now green — publish a one-shot recovery.\n publish({\n type: \"health_alert\",\n probe: s.name,\n label: s.label,\n category: s.category,\n status: \"recovered\",\n error: null,\n ts: now,\n });\n }\n s.failingSince = null;\n s.lastAlertAt = 0;\n return;\n }\n // Unconfigured probes never alert — operator hasn't configured them.\n if (next.status === \"unconfigured\") {\n s.failingSince = null;\n s.lastAlertAt = 0;\n return;\n }\n // Failing: alert on first failure since last green, OR on re-alert\n // interval. Don't compare equal error strings — a flapping vendor\n // shouldn't fall through the cracks.\n const wasFailing = s.failingSince !== null;\n if (!wasFailing) s.failingSince = now;\n const sinceLastAlert = now - s.lastAlertAt;\n const shouldAlert = !wasFailing || sinceLastAlert >= RE_ALERT_MS;\n if (shouldAlert) {\n s.lastAlertAt = now;\n // Tag transient/error/auth_failed verbatim so the UI can colour-code.\n const alertStatus = next.status === \"auth_failed\" ? \"auth_failed\"\n : next.status === \"transient\" ? \"transient\" : \"error\";\n publish({\n type: \"health_alert\",\n probe: s.name,\n label: s.label,\n category: s.category,\n status: alertStatus,\n error: next.error ?? \"probe failed\",\n ts: now,\n });\n }\n // Keep prev referenced for future diff logic without leaking unused param.\n void prev;\n}\n\n/**\n * Run every registered probe in parallel and reconcile state. Returns the\n * fresh snapshot. Safe to call concurrently — re-entrant calls return the\n * stale snapshot until the in-flight run finishes.\n */\nexport async function runAllHealthProbes(now: number = Date.now()): Promise<HealthSnapshot> {\n if (state.inFlight) return getHealthSnapshot();\n state.inFlight = true;\n try {\n const probes = listProbes();\n const results = await Promise.allSettled(probes.map((p) => runProbe(p)));\n for (let i = 0; i < probes.length; i++) {\n const name = probes[i];\n const s = getOrInit(name);\n const r = results[i];\n const next: HealthResult = r.status === \"fulfilled\"\n ? r.value\n : { ok: false, status: \"error\", error: r.reason instanceof Error ? r.reason.message : String(r.reason) };\n const prev = s.lastResult;\n s.lastResult = next;\n s.lastCheckedAt = now;\n reconcileProbe(s, prev, next, now);\n }\n state.lastRunAt = now;\n return getHealthSnapshot();\n } finally {\n state.inFlight = false;\n }\n}\n\n/** Exposed for tests so they can reset state between cases. */\nexport function _resetHealthRunner(): void {\n state.probes.clear();\n state.lastRunAt = 0;\n state.inFlight = false;\n}\n","// Persistent env-var overrides written to ~/.jarela/env-overrides.json\n// (or $JARELA_DB_DIR/env-overrides.json). Read once at boot and injected\n// into process.env before any module reads its config. Mutated at runtime\n// by /api/v1/env PATCH/DELETE; a hot-reload path resets the config cache\n// so non-restart-required vars take effect immediately.\n//\n// Format: a flat JSON object of `JARELA_*` → string. Anything not in\n// ENV_SCHEMA is rejected at write time (no free-form keys).\n\nimport { promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { envSchemaByName, type EnvVarDef } from \"./schema\";\n\nconst FILE_NAME = \"env-overrides.json\";\n\nfunction overridesPath(): string {\n return join(getDataDir(), FILE_NAME);\n}\n\nexport interface OverridesFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst EMPTY: OverridesFile = { version: 1, entries: {} };\n\nexport async function readOverrides(): Promise<OverridesFile> {\n try {\n const raw = await fs.readFile(overridesPath(), \"utf8\");\n const parsed = JSON.parse(raw) as Partial<OverridesFile>;\n if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === \"object\") {\n // Defensive: keep only entries the current schema knows about.\n // Schema renames / removals should silently drop stale rows rather\n // than block boot.\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) continue;\n filtered[k] = v;\n }\n return { version: 1, entries: filtered };\n }\n return EMPTY;\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") return EMPTY;\n // Corrupt file — log + ignore. Don't kill boot over a bad overrides\n // file; the operator can delete it and restart.\n console.warn(`[env-overrides] failed to read ${overridesPath()}: ${e.message}`);\n return EMPTY;\n }\n}\n\nexport function readOverridesSync(): OverridesFile {\n // Sync read for the boot path, where async would force callers up the\n // module chain to await. Used exactly once in instrumentation-node.\n const fsSync = require(\"node:fs\") as typeof import(\"node:fs\");\n try {\n const raw = fsSync.readFileSync(overridesPath(), \"utf8\");\n const parsed = JSON.parse(raw) as Partial<OverridesFile>;\n if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === \"object\") {\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) continue;\n filtered[k] = v;\n }\n return { version: 1, entries: filtered };\n }\n return EMPTY;\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") return EMPTY;\n console.warn(`[env-overrides] failed to read ${overridesPath()}: ${e.message}`);\n return EMPTY;\n }\n}\n\nexport async function writeOverrides(next: OverridesFile): Promise<void> {\n const path = overridesPath();\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(next.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) {\n throw new Error(`unknown env var: ${k}`);\n }\n filtered[k] = v;\n }\n const out: OverridesFile = { version: 1, entries: filtered };\n // Validate every entry against its schema before persisting; refuse\n // bad values at write time so we never write garbage that boot would\n // then have to reject silently.\n for (const [name, value] of Object.entries(filtered)) {\n const def = known.get(name);\n if (!def) continue;\n const err = validateForSchema(def, value);\n if (err) throw new Error(`${name}: ${err}`);\n }\n await fs.mkdir(join(path, \"..\"), { recursive: true });\n await fs.writeFile(path, JSON.stringify(out, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport function validateForSchema(def: EnvVarDef, value: string): string | null {\n if (def.type === \"int\") {\n const n = Number(value);\n if (!Number.isFinite(n) || !Number.isInteger(n)) return \"expected integer\";\n if (def.min !== undefined && n < def.min) return `minimum is ${def.min}`;\n if (def.max !== undefined && n > def.max) return `maximum is ${def.max}`;\n return null;\n }\n if (def.type === \"bool\") {\n if (!/^(0|1|true|false)$/i.test(value.trim())) return \"expected bool (0/1/true/false)\";\n return null;\n }\n if (def.type === \"enum\") {\n if (!def.enumValues || !def.enumValues.includes(value)) {\n return `expected one of: ${def.enumValues?.join(\", \") ?? \"\"}`;\n }\n return null;\n }\n // string — accept anything non-empty by default\n if (def.type === \"string\") {\n return null;\n }\n return null;\n}\n\n/**\n * Apply persisted overrides into process.env. Called once at boot from\n * instrumentation-node BEFORE any module reads env. Idempotent — safe to\n * call multiple times (subsequent calls overwrite earlier values when\n * the file changes on disk).\n *\n * Skips keys that already have a non-empty value in process.env: the\n * env Jarela was launched with always wins over the persisted overrides.\n * That keeps explicit `JARELA_PORT=… npm start` behavior predictable\n * regardless of what's in the overrides file.\n */\nexport function applyOverridesToProcessEnv(): { applied: number; skipped: number } {\n const file = readOverridesSync();\n let applied = 0;\n let skipped = 0;\n for (const [k, v] of Object.entries(file.entries)) {\n const existing = process.env[k];\n if (existing && existing.trim() !== \"\") {\n skipped++;\n continue;\n }\n process.env[k] = v;\n applied++;\n }\n return { applied, skipped };\n}\n\n/**\n * Set or unset a single override and persist the result. value === null\n * unsets. Returns the resulting overrides snapshot.\n */\nexport async function patchOverride(\n name: string,\n value: string | null,\n): Promise<OverridesFile> {\n const known = envSchemaByName();\n if (!known.has(name)) throw new Error(`unknown env var: ${name}`);\n const current = await readOverrides();\n const next: Record<string, string> = { ...current.entries };\n if (value === null) {\n delete next[name];\n } else {\n next[name] = value;\n }\n const out: OverridesFile = { version: 1, entries: next };\n await writeOverrides(out);\n return out;\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 agent_id?: string;\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 agent_id=?, 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.agent_id ?? existing.agent_id,\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","runAgentTurn","QueueFullError","getScript","runTriggerAgent","firing","agent","agentId","status","preview","threadId","error","thread","category","effectivePrompt","silent","prompt","result","thread_id","queue_source","message","user_category","assistant_category","skippedAssistant","err","msg","Error","String","runTriggerScript","fn","script","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","length","prevEnd","currEnd","removed","slice","added","hunkHeader","Math","max","l","join","bytes","Buffer","byteLength","clipped","truncated","text","buildFiringPrompt","watcher","argsPretty","tool_args","directive","reaction_prompt","trim","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","replace","left","right","ctx","title","registerHandlers","startAllTriggerHandlers","stopAllTriggerHandlers","notifyTriggerHandlers","_reason","runTriggerTick","innerErr","runScheduledTaskFiringNow","runWatcherFiringNow","watcherId","listScripts","listReactionScripts","isReactionScript","REACTION_SCRIPT_PREFIX","tails","depths","DEFAULT_MAX_DEPTH","depth","enqueueThreadRun","_source","runner","options","maxDepth","currentDepth","position","Promise","resolve","next","then","finally","d","catch","getQueueDepth","__resetForTests","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","BaseChatModel","AIMessage","AIMessageChunk","isAIMessage","isHumanMessage","isSystemMessage","isToolMessage","ChatGenerationChunk","convertToOpenAITool","JarelaChatModel","fields","lc_namespace","lc_serializable","_provider","provider","_modelId","modelId","_params","params","_boundTools","boundTools","_llmType","bindTools","tools","_kwargs","_convertedTools","flatMap","oai","function","parameters","_generate","messages","_options","runManager","invokeMessages","toInvokeMessages","openaiTools","streamInvoke","finalChunk","_streamToFinalChunk","gen","aiMessageFromChunk","generations","aiMsg","tool_calls","tc","arguments","providerMessages","stream","chat","chunk","acc","_streamFromProvider","_streamResponseChunks","tool_call_chunks","index","emittedAny","stopReason","event","handleLLMNewToken","delta","additional_kwargs","reasoning_content","args_delta","reason","cacheCreation","cache_creation_input_tokens","cacheRead","cache_read_input_tokens","usage_metadata","input_tokens","output_tokens","total_tokens","input_token_details","cache_creation","cache_read","empty_stream_reason","stop_reason","invalid_tool_calls","lcContentToInvoke","block","b","image_url","dataUrl","media_type","src","every","ai","invokeMsg","reasoning","tool_call_id","BaseStore","getMemory","putMemory","deleteMemory","listMemory","SqliteMemoryStore","batch","operations","results","all","op","ns","namespace","row","key","_raw","createdAt","created_at","updatedAt","updated_at","undefined","prefix","namespacePrefix","limit","rows","r","createReactAgent","HumanMessage","SystemMessage","ToolMessage","getProvider","getModelConfig","getDefaultModelConfig","getModelParams","upsertModelConfig","getAllToolsAsync","getCheckpointer","toBaseMessages","systemPrompt","base","blocks","part","streamWithConfig","runCfg","agent_run_config","cfgName","model_config_name","cfg","toolPolicy","allowed_tools","allow","tool_policy","model_id","store","checkpointer","deleteThread","test","llm","announcedToolIds","pendingAIChunk","totalOutputTokens","usageInputTokens","usageOutputTokens","usageCacheCreationTokens","usageCacheReadTokens","sawUsage","truncatedByLength","needsParagraphBreak","textEmittedSinceLastBreak","flushPendingToolCalls","calls","agentStream","system_prompt","streamMode","configurable","delegation_depth","delegation","delegation_ancestors","ancestors","recursionLimit","payload","usage","details","baseMsg","stack","causeChain","c","cause","cMsg","cCode","rawMsg","aborted","message_id","friendly","isContextOverflowError","observed","parseContextLimitFromError","context_window_tokens","POSITIVE_INFINITY","corrected","nextParams","is_default","persistErr","toLocaleString","requested","firstAppFrame","trimmed","num","openai","match","openaiNoReq","anthropic","gemini","deepseek","ACTION_VERBS","VERB_GROUP","PATTERNS","RegExp","FUTURE_PATTERNS","findActionClaims","out","seen","re","lastIndex","verb","toLowerCase","window","some","VIA_RE","findCitations","tool","SUMMARY_PATTERNS","validateAssistantOutput","toolCalls","allowedTools","calledSet","allowedSet","citations","evidence","claims","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","round","frustration","urgency","positivity","targetExpressive","targetVerbosity","empathyBand","bandLabel","expressiveBand","verbosityBand","directives","mood","lower","frustrationHits","countMatches","urgencyHits","positivityHits","min","terms","term","includes","v","cutoffs","labels","getDefaultHarnessId","getHarness","getBuiltinHarness","DEFAULT_HARNESS_ID","HARNESS_SECTION_KEYS","resolveHarness","agentCfg","harness_id","harness","section","sections","enabled","transcriptText","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","config","contextWindowTokens","outputReserveTokens","max_tokens","overheadTokens","inputBudgetTokens","proportions","context_tier_proportions","tierPriority","context_tier_priority","tierBudgets","applyTierSpill","softCap","incomingSpill","used","cap","spill","takeRecentMessagesWithinBudget","tokenBudget","chosen","tokens","reverse","truncateLargestMessagesWithinBudget","total","reduce","a","idx","needed","nextTokens","nextChars","suffix","trimEnd","formatContextBudgetSummary","budget","fallback","os","parseCitationStrictness","getUserProfile","listIntegrations","getDocumentSourceStats","getAppName","APP_NAME","buildSystemPrompt","trimmedMessage","recallCtx","warmSummaryCtx","factsCtx","experienceMode","delegateRosterLines","sourceManifest","adaptivePersonaCtx","harnessParts","tierCtxByName","tierOrderCtx","identity","instructions","buildUserContext","buildIntegrationsContext","buildDocumentsContext","capabilities","plan_first","presentation","citation","buildSourceLinkContext","buildTimeContext","buildEnvContext","self_config","buildExperienceContext","buildOutputBudgetContext","buildMemoryContext","buildDelegatesContext","resolveExperienceMode","ui_experience_mode","userProfile","about","location_consent","location_lat","location_lng","ageSec","location_updated_at","ageStr","location_accuracy_m","location_label","toFixed","manifest","strictness","citation_strictness","intro","platform","arch","cwd","homedir","configured","lines","email","words","totalChunks","chunk_count","getRecentMessagesWindow","getThread","setThreadWarmSummary","summarizeTranscript","getKnownContextLength","buildHistoryWindow","providerParams","modelInfo","hotSince","history_limit","windowHours","history_window_hours","sinceISO","allWindowMessages","cached","cachedSummaryFresh","warm_summary","warm_summary_before","resolveFallbackContextWindow","hotMessages","hotCap","tier","sumMessageTokens","warmCap","hotForSlice","buildWarmSummary","providerName","factsCap","buildFactsContext","hotMessagesResolved","warmWasExpected","hotMessagesForPrompt","history","parseContent","hotTokensFinal","tierUsage","hot_tokens","warm_tokens","facts_tokens","overhead_tokens","hotCount","warmBudgetTokens","warmMessages","summaryInputChars","transcript","summary","query","factsBudgetTokens","charBudget","line","KNOWN_MODEL_RATES","inputPer1M","outputPer1M","knownRateFor","hit","inferred","confidence","knownRateModelIds","Object","readFileSync","statSync","EXPECTED_PROVIDERS","snapshotPath","readSnapshotSync","snapshot","getPricingTables","tables","byProvider","byProviderModel","byModel","normalizeProvider","inferRatesFromSignals","price_signals","modelInputRates","model_rates","input_per_1m_usd","sort","modelOutputRates","output_per_1m_usd","providerInput","providerOutput","providerDerivedFromModels","resolved_url","pricing_url","modelRate","normalizedModel","isBetterRate","generatedAt","generated_at","providerRatesFor","modelRatesFor","modelKey","providerKey","modelAliasCandidates","candidate","exact","upstream","inferProviderFromModelId","upstreamCandidates","viaUpstreamModel","upstreamProviderRate","viaModel","directModel","known","nextHas","prevHas","rank","high","medium","low","slash","lastIndexOf","signals","tokenRates","CACHE_CREATION_INPUT_RATE_MULTIPLIER","CACHE_READ_INPUT_RATE_MULTIPLIER","estimateCostUsd","inputTokens","outputTokens","rates","cache","inputRate","outputRate","inCost","outCost","cacheCost","create","read","isWriteLikeToolName","resolveDetector","rawMode","anti_hallucination_mode","hallucinationDetectorMode","modelName","anti_hallucination_model_config","hallucinationDetectorModel","modelConfigName","PROMPT_TAIL_BUDGET","SYSTEM_PROMPT","classifyStall","assistantText","toolNames","usedWriteTool","tail","userMsg","parseVerdict","stripped","obj","stalled","getMessages","isSensitiveMemoryNamespace","SOURCE_PRODUCING_TOOLS_CALL","SOURCE_PRODUCING_TOOLS_RESULT","normalizeSource","u","URL","protocol","host","pathname","normalized","home","extractSourcesFromEvents","events","ev","phase","collectStringsFromPayload","extractVisitedSources","freshEvents","tool_events","extractCitedLinks","href","extractCitedMarkers","buildSourceManifest","visited","labelForSource","hostname","labelForCitedSource","extractPriorDialogSources","assistant","nowMs","ageMs","formatAge","msg_id","ms","hr","day","extractMemorySources","items","extractDelegateSources","hits","agent_name","msgId","eventId","h","buildCombinedManifest","caps","toolsSet","delegates","childThread","memory","merged","DECLARED_REFS_FENCE_RE","extractDeclaredReferences","refs","item","stripStreamingDeclaredReferences","indexOf","mergeDeclaredReferences","declared","classifyCitations","tailBudget","citationCheckerTailChars","sent","portionLabel","sourcesList","trailer","parseCitationVerdict","byN","marker","link","verified","impactRank","med","impact","checker_model","unverified_links","claimsRaw","markerRaw","impactRaw","looksLikeSource","assetExt","hasFileExt","addMessage","setMessageMetadata","setThreadContextPin","touchThread","recordToolUsage","getAgentTierProportions","getAgentTools","parseDelegateTargets","startScheduler","recall","recordMessageUsage","RunThreadError","RECALL_BUDGET_MS","raceWithBudget","promise","settled","maxStallRetries","maxTransientRetries","MAX_DELEGATION_DEPTH","contentText","snapshotThreadModelConfigName","prepareThreadRun","req","attachments","stored","_skip_persist_message","_pinned_model_config_name","modelCfg","baseProviderParams","agentTierProportions","hot_since","effectiveHotSince","historyWindow","buildDelegateRoster","oldestInWindow","rawRecallCtx","context_profile","include_recall","buildRecallContext","profile","effectiveHistory","include_hot","effectiveWarmSummary","include_warm","effectiveFacts","include_facts","delegationDepth","_delegation_depth","delegationAncestors","_delegation_ancestors","streamOpts","finalHistory","_inject_message_into_history","rawStream","retriesLeft","_stall_retries_left","stallRetryStream","context_snapshot","hot_budget_tokens","warm_budget_tokens","facts_budget_tokens","source_manifest","delegateIds","delegate_targets","child","firstLine","inner","originalReq","textBuf","signatureCounts","loopedToolName","doneChunk","sawError","sig","toolCallSignature","count","TOOL_LOOP_THRESHOLD","trimmedText","isStallProse","looksLikeStall","zeroToolStall","promisedWriteStall","regexStalled","looped","detector","classifierStalled","classifierReason","verdict","fabrication","uncitedHighClaims","checkerModel","auditManifest","citationManifestMax","citationFail","nudge","retry","INTERRUPT_MARKER","withInterruptMarker","partial","endsWith","persistAssistantMessage","usedTools","toolEvents","contextSnapshot","final","toolList","wasInterrupted","noTool","noWriteTool","lookupAllowedToolsForThread","sanitizedEvents","capToolEventPayload","withoutAutoplay","stripAutoplayHints","persisted","declaredRefs","runCitationCheckerForRow","hasProviderUsage","agentName","cost","input_rate_usd_per_mtok","output_rate_usd_per_mtok","cost_usd","tier_usage","persistedText","_full","cleaned","MAX_PERSISTED_PAYLOAD_BYTES","serialized","__truncated","original_bytes","WRITE_VERB_SEGMENTS","sortedKeys","stable","k","detectToolLoop","threshold","counts","STALL_PATTERNS","current_thread_id","windowOldestContent","filtered","stamp","truncate","tag","flat","shouldEmitChunk","chunkType","includeTools","filters","include_tools","includeThinking","include_thinking","embedOne","cosine","searchDocuments","limitRows","qVec","scored","lowered","score","embedding","vec","substringScore","document_id","source_label","rel_path","abs_path","chunk_index","haystack","needleLower","hay","indexAllSources","runAllHealthProbes","isMasterKeyLocked","POLL_INTERVAL_MS","JARELA_SCHEDULER_TICK_MS","DOC_SWEEP_EVERY_TICKS","HEALTH_SWEEP_EVERY_TICKS","started","timer","running","tickCount","healthTickCount","setImmediate","tick","setInterval","stopScheduler","clearInterval","runScheduledTaskNow","summaryMessages","existsSync","readdirSync","getToolSecret","getToolsDir","toolsDir","isValidSlot","o","required","isValid","schema","secrets","loadExternalTools","builtinNames","categories","files","createRequire","getBuiltinModule","entries","mod","default","def","wrapped","_runManager","getSecret","collectStream","assistantContent","terminal","onChunk","errorMessage","z","registerTools","memoryReadTool","object","string","describe","memoryWriteTool","memoryListTool","search","optional","number","memoryDeleteTool","createDocumentSource","deleteDocumentSource","getDocumentSourceByPath","listDocumentSources","indexOnDemand","documentsSearch","int","documentsListSources","last_scan_at","documentsAddLocalSource","inputPath","note","REMOTE_KINDS","syntheticPath","space_key","cql","project_key","jql","owner","repo","validateRemoteConfig","documentsAddRemoteSource","enum","record","unknown","documentsRemoveSource","confirm","documentsReindexSource","documentsIndexUrl","input","resolveSafetyMode","JARELA_TOOL_SAFETY","SAFE_EXEC_ALLOWLIST","SAFE_SUBCOMMANDS","git","npm","npx","node","python","python3","deno","pip","pip3","COMPOSER_RE","checkExecAllowed","command","allowed","blockedByPattern","allowUnsafe","head","subAllowlist","sub","checkFsAllowed","STATE_KEY","Symbol","for","g","globalThis","DEFAULT_KEY","keyFor","tid","currentWorkspace","setWorkspace","ws","clearWorkspace","_resetWorkspaceContext","execSync","getInjectedSubprocessEnv","maxOutputBytes","execMaxOutputBytes","EXEC_DEFAULT_TIMEOUT_MS","BLOCKED_PATTERNS","isBlockedCommand","pattern","clipOutput","runLocalCommand","exit_code","stderr","timeout","timeout_ms","gate","allow_unsafe","safety_mode","workspaceRoot","output","encoding","maxBuffer","stdio","stdout","timedOut","killed","errText","timed_out","execSchema","boolean","localExecTool","root","shellExecTool","maxReadBytes","filesMaxReadBytes","maxWriteBytes","filesMaxWriteBytes","MAX_LIST_JSON_BYTES","FS_DEADLINE_BACKSTOP_MS","withFsDeadline","work","deadlineMs","_","reject","race","clip","resolvePath","isAbsolute","pathResolverFor","workspace","scoped","isInside","parent","sensitiveBase","sensitiveFiles","jarelaDataDir","JARELA_DB_DIR","assertSafePath","JARELA_ALLOW_SENSITIVE_FILES","basename","readSchema","start_line","end_line","fileReadTool","filePath","readFile","lineRange","end","line_range","total_lines","writeSchema","create_dirs","fileWriteTool","dirname","mkdir","existed","access","writeFile","bytes_written","created","editSchema","old_string","new_string","fileEditTool","first","second","match_count","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","readdir","withFileTypes","localeCompare","it","full","build","es","droppedForSize","total_in_dir_after_filters","truncated_hint","dropped_for_size","lo","hi","mid","mkdirSchema","fileMkdirTool","deleteSchema","fileDeleteTool","targetPath","rmdir","unlink","copySchema","fileCopyTool","copyFile","statSchema","fileStatTool","exists","modified_ms","created_ms","birthtimeMs","MAX_FILES_SCANNED","MAX_MATCHES","MAX_LINE_BYTES","MAX_GLOB_RESULTS","MAX_MULTI_EDITS","MAX_GREP_FILE_BYTES","DEFAULT_IGNORE","compileGlob","alts","escapeRegExp","toPosix","walk","ignore","scanned","visit","absDir","relDir","includeHidden","childRel","childAbs","maxFiles","globSchema","max_results","fileGlobTool","rawRoot","rootAbs","rootStat","walked","matches","files_scanned","grepSchema","literal","case_insensitive","glob","max_matches","context","fileGrepTool","fileRe","filesWithMatches","filesScanned","outer","fileHadMatch","clipLine","before","after","files_with_matches","multiEditSchema","edits","array","fileMultiEditTool","buf","failed","edits_applied","execFile","promisify","execFileP","PROBE_TIMEOUT_MS","MAX_TREE_DEFAULT","MAX_TREE_HARD_CAP","README_MAX_BYTES","sensitiveRoots","resolveAgentPath","withTimeout","probeGit","is_repo","safe","branch","remote","dirty","untracked_count","readJsonIfExists","fileExists","detectPackageManager","pkg","packageManager","pm","detectTestRunner","deps","dependencies","devDependencies","vitest","jest","mocha","ava","scripts","detectFrameworks","react","vue","svelte","express","fastify","tailwindcss","parseMakefileTargets","targets","detectLanguages","found","markLanguage","into","ext","extname","buildTree","maxEntries","dirAbs","dirRel","kids","readReadme","detectConventionFiles","claude","agents","contributing","adrDir","claude_md","agents_md","contributing_md","adr_dir","buildRequiredReading","conventions","readme","extra","extraPath","initSchema","include_tree","max_tree_entries","include_git","include_scripts","include_readme","extra_required_reading","workspaceInitTool","rawPath","opened_at","languages","makefileTargets","tree","hasDockerfile","hasDevcontainer","project","package_manager","framework_hints","test_runner","makefile_targets","has_dockerfile","has_devcontainer","required_reading","workspaceStatusTool","_input","active","workspaceCloseTool","cleared","was_active","tavilySearch","api_key","search_depth","snippet","UA_POOL","ddgSearch","lastStatus","attempt","ua","html","parseDDGHtml","blockRe","titleMatch","snippetMatch","unwrapDDGRedirect","decodeHTML","stripTags","real","searchParams","decodeURIComponent","webSearchTool","tavilyKey","TAVILY_API_KEY","dns","net","ipv4InCidr","addr","bits","mask","ipv4ToNumber","ip","isInteger","classifyIPv4","classifyIPv6","bare","v4","isIPv4","classifyAddress","isIPv6","isPrivateAddress","cls","checkPublicUrl","rawUrl","JARELA_ALLOW_PRIVATE_FETCH","isIP","resolved","addrs","lookup","address","stripHtml","maxBytes","fetchToolMaxBytes","FETCH_INTERNAL_TIMEOUT_MS","MAX_REDIRECTS","extractTitle","extractImages","baseUrl","og","twitter","samples","matchAll","resolveUrl","webFetchTool","max_chars","ctrl","AbortController","TIMEOUT_MS","MAX_BYTES","abort","initialCheck","currentUrl","hop","redirect","loc","hopCheck","contentType","finalUrl","reader","getReader","decoder","TextDecoder","bytesRead","done","decode","cancel","wantHtml","images","content_type","bytes_read","getUserLocationTool","available","how_to_enable","lat","lng","accuracy_m","age_seconds","randomUUID","writeBinaryFile","DEFAULT_MODEL","callGemini","imageTimeoutMs","describeError","callImagen","aspect","instances","sampleCount","aspectRatio","preds","predictions","bytesBase64Encoded","extForMime","generateImageTool","aspect_ratio","saved","img","markdown","hint","DEFAULT_VOICE","MAX_TEXT_CHARS","SpeakerSchema","voice_name","resolveAgentVoice","voice","voice_model","generateVoiceTool","autoplay","speakerList","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","listWatchersTool","safeParse","last_fired_at","cancelWatcherTool","createPendingAction","getPendingAction","proposeConfigChangeTool","proposal_id","checkProposalTool","decided_at","getManifest","listManifests","getIntegrationStatus","isKnownIntegration","manifestStatus","listIntegrationsTool","integrations","getIntegrationSetupTool","prerequisites","steps","troubleshooting","notes","googleFetch","resolveGoogleAuth","CALENDAR_BASE","calendarFetch","auth","init","slimEvent","location","dateTime","date","time_zone","timeZone","attendees","displayName","response","responseStatus","meet_link","hangoutLink","html_link","htmlLink","calendarListCalendarsTool","calendars","primary","access_role","accessRole","calendarListEventsTool","calendar_id","time_min","time_max","cal","URLSearchParams","singleEvents","orderBy","maxResults","inAWeek","calendarGetEventTool","event_id","eid","calendarCreateEventTool","subject","start_iso","end_iso","add_meet_link","eventSummary","conferenceData","createRequest","requestId","random","conferenceSolutionKey","calendarUpdateEventTool","patch","calendarDeleteEventTool","graphFetch","resolveMicrosoftAuth","bodyPreview","emailAddress","is_all_day","isAllDay","is_cancelled","isCancelled","show_as","showAs","teams_link","onlineMeeting","joinUrl","web_link","webLink","outlookCalendarListCalendarsTool","isDefaultCalendar","can_edit","canEdit","outlookCalendarListEventsTool","startISO","endISO","top","startDateTime","endDateTime","$top","$orderby","Prefer","outlookCalendarGetEventTool","outlookCalendarCreateEventTool","add_teams_link","eventSubject","tz","isOnlineMeeting","onlineMeetingProvider","outlookCalendarUpdateEventTool","outlookCalendarDeleteEventTool","resolveTurnProfile","readDelegateContext","ancestorsRaw","parentAgentId","fail","error_code","delegateToAgentTool","roster","startedAt","queued","prepared","collected","elapsed_ms","used_tools","cite_as","envSchemaByName","patchOverride","validateForSchema","resetConfigCache","setEnvSchema","nullable","setEnvVar","agentWritable","verr","requiresRestart","restartSchema","restartServer","port","JARELA_PORT","PORT","JARELA_HOSTNAME","HOSTNAME","getToolCategory","getToolCapability","getToolGroup","getToolSource","listToolsTool","capability","summaries","group","by_source","builtin","external","mcp","by_capability","execute","listProviderNames","BUILTIN_PROVIDER_NAMES","listKnownModels","sourceOf","listProvidersTool","names","providers","builtin_count","external_count","describeProviderTool","stream_invoke","embed","list_models","listModels","models","known_models","listMcpServers","listMcpServersTool","allTools","totalMcp","servers","transport","tool_count","enabled_count","total_mcp_tool_count","SURFACES","registration_entrypoint","doc_section","example_path","introspection_tool","related_adrs","describeExtensionSurfacesTool","surfaces","guide_path","contract_paths","registeredNames","registeredCategory","registeredCapability","registeredGroup","getMcpTools","disabledCategories","allBuiltins","getBuiltinToolNames","loadExternal","cat","applyPolicy","policy","allowSet","denySet","deny","applyCategoryToggles","disabled","getAllTools","mcpTools","toOpenAITools","executeTool","x","_initialized","initTools","builtinCount","externalCount","ANTHROPIC","context_length","max_output_tokens","GEMINI","OPENAI","DEEPSEEK","resolveCopilot","canon","matchPrefix","table","best","getKnownModelLimits","getKnownMaxOutputTokens","UPSERT_SQL","deltas","summarizeToolUsage","stmt","successes","listToolStats","getToolStatsMap","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","successful","isErrorPayload","payloadLooksUsed","totals","extractPayloadTerms","matched","stringifyPayload","unique","token","mkdirSync","writeFileSync","getDataDir","FILES_DIR","SAFE_NAME","isSafeFileName","fileAbsPath","isCategoryEnabled","listCategoryStates","setCategoryEnabled","startRun","finishRun","broadcast","NO_REPLY_RE","pinnedModelConfigName","contextProfile","context_profile_override","enqueued","skip_persist_user_message","skipSilent","contentToPersist","getIntegrationRaw","fromStore","GEMINI_API_KEY","GOOGLE_API_KEY","isUserPreset","upsertUserProfile","icon","setLocationConsent","consent","updateUserLocation","setUserPreset","preset","MAX_BUFFERED","runBufferSize","RECENT_TTL_MS","runRegistryTtlMs","runIdleMs","runMaxMs","runs","started_at","finished_at","subscribers","final_text","last_chunk_at","inflight_tools","tool_started_at","tool_time_ms_done","scheduleIdleWatchdog","scheduleMaxWatchdog","emitWatchdogTermination","errChunk","idleMs","fireIn","idle","effectiveElapsedMs","inflightToolMs","elapsed","getRun","abortRun","abortAllRuns","waitForRunsToSettle","timeoutMs","deadline","stillRunning","subscribe","onEvent","unsubscribe","FULL_PROFILE","ONE_SHOT_PROFILE","TURN_PROFILES","user","bridge","delegate","extension","scheduler","trigger","override","CronExpressionParser","resolveReaction","validateReactionScript","normaliseReactionScriptArgs","isNaN","currentDate","toDate","reaction","scriptArgs","updateScheduledTask","nextKind","nextSchedule","nextRunAt","nextPrompt","nextRun","__resetScriptRegistry","NAMESPACE","NAME_RE","validName","compoundKey","parseStored","setToolSecret","deleteToolSecret","describeToolSecrets","slots","is_set","purgeToolSecrets","listProbes","probeCategory","probeLabel","runProbe","RE_ALERT_MS","probes","inFlight","getOrInit","lastResult","lastCheckedAt","failingSince","lastAlertAt","getHealthSnapshot","detail","ranAt","reconcileProbe","probe","wasFailing","sinceLastAlert","shouldAlert","alertStatus","allSettled","_resetHealthRunner","FILE_NAME","overridesPath","EMPTY","version","readOverrides","readOverridesSync","fsSync","require","writeOverrides","enumValues","applyOverridesToProcessEnv","applied","skipped","MAX_REACTION_PROMPT_CHARS","MAX_REACTION_SCRIPT_ARGS_CHARS","normaliseReactionPrompt","MIN_INTERVAL_SECONDS","clampInterval","seconds","argsJson","updateWatcher"],"sourceRoot":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"239.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/agents/run-queue.ts","webpack://@circuitwall/jarela/./lib/voice/constants.ts","webpack://@circuitwall/jarela/./lib/voice/gemini.ts","webpack://@circuitwall/jarela/./lib/providers/jarela-chat-model.ts","webpack://@circuitwall/jarela/./lib/stores/langgraph-store.ts","webpack://@circuitwall/jarela/./lib/agents/llm.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/adaptive-persona.ts","webpack://@circuitwall/jarela/./lib/agents/harness/resolve.ts","webpack://@circuitwall/jarela/./lib/agents/context-budget.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/system-prompt.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/history-window.ts","webpack://@circuitwall/jarela/./lib/agents/prepare/index.ts","webpack://@circuitwall/jarela/./lib/stores/known-rates.ts","webpack://@circuitwall/jarela/./lib/stores/pricing.ts","webpack://@circuitwall/jarela/./lib/agents/hallucination-classifier.ts","webpack://@circuitwall/jarela/./lib/agents/citation-checker.ts","webpack://@circuitwall/jarela/./lib/agents/run-thread.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/providers/known-context-windows.ts","webpack://@circuitwall/jarela/./lib/stores/tool-stats.ts","webpack://@circuitwall/jarela/./lib/files.ts","webpack://@circuitwall/jarela/./lib/tools/memory.ts","webpack://@circuitwall/jarela/./lib/tools/documents.ts","webpack://@circuitwall/jarela/./lib/tools/safety.ts","webpack://@circuitwall/jarela/./lib/tools/workspace-context.ts","webpack://@circuitwall/jarela/./lib/tools/exec.ts","webpack://@circuitwall/jarela/./lib/tools/files.ts","webpack://@circuitwall/jarela/./lib/tools/files-search.ts","webpack://@circuitwall/jarela/./lib/tools/workspace.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/delegate.ts","webpack://@circuitwall/jarela/./lib/tools/system_config.ts","webpack://@circuitwall/jarela/./lib/tools/list-tools.ts","webpack://@circuitwall/jarela/./lib/tools/providers-info.ts","webpack://@circuitwall/jarela/./lib/tools/mcp-servers-info.ts","webpack://@circuitwall/jarela/./lib/tools/extension-surfaces.ts","webpack://@circuitwall/jarela/./lib/tools/async-results-tool.ts","webpack://@circuitwall/jarela/./lib/tools/builtins.ts","webpack://@circuitwall/jarela/./lib/tools/index.ts","webpack://@circuitwall/jarela/./lib/stores/builtin-tools.ts","webpack://@circuitwall/jarela/./lib/agents/agent-turn.ts","webpack://@circuitwall/jarela/./lib/utils/google-api.ts","webpack://@circuitwall/jarela/./lib/stores/user-profile.ts","webpack://@circuitwall/jarela/./lib/agents/run-registry.ts","webpack://@circuitwall/jarela/./lib/agents/turn-profile.ts","webpack://@circuitwall/jarela/./lib/stores/scheduled-tasks.ts","webpack://@circuitwall/jarela/./lib/triggers/scripts.ts","webpack://@circuitwall/jarela/./lib/stores/tool-secrets.ts","webpack://@circuitwall/jarela/./lib/health/runner.ts","webpack://@circuitwall/jarela/./lib/env/overrides.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 { runAgentTurn } from \"@/lib/agents/agent-turn\";\nimport { QueueFullError } from \"@/lib/agents/run-queue\";\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 result = await runAgentTurn({\n thread_id: thread.thread_id,\n queue_source: \"trigger\",\n message: effectivePrompt,\n user_category: category,\n assistant_category: category,\n silent: firing.silent === true,\n });\n return {\n status: result.skippedAssistant ? \"skipped\" : \"done\",\n preview: result.preview,\n threadId: thread.thread_id,\n };\n } catch (err) {\n const msg = err instanceof Error\n ? (err instanceof QueueFullError ? `queue full: ${err.message}` : err.message)\n : 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","// Per-thread FIFO queue for agent runs.\n//\n// Every entry point that drives an agent on a thread (HTTP POST, scheduler,\n// watcher, trigger, bridge) wraps its work with `enqueueThreadRun`. The\n// queue serialises execution per `thread_id`: a second job for the same\n// thread waits for the first to settle before starting. Different threads\n// stay parallel.\n//\n// Why: a single thread_id is shared across the chat UI, every bridge chat\n// routed to the same agent, every watcher fire, and every scheduled task\n// for that agent (one-thread-per-agent invariant). LangGraph's SQLite\n// checkpoint store is DB-level locked, not per-thread, so two concurrent\n// `agent.stream()` calls on the same thread_id will both read the same\n// checkpoint, both write, and the later write clobbers the earlier — one\n// turn's state can land in another turn's history. Serialising at this\n// layer is the cheapest fix.\n//\n// In-memory + single-process. Multi-instance deployment would need a\n// shared lock (Redis, Postgres advisory locks) — explicitly out of scope.\n// A process crash drops the in-flight head and discards every queued job\n// without ever invoking the runner: same blast radius as today's stranded\n// `running` registry entries.\n\ntype Source = \"user\" | \"scheduler\" | \"watcher\" | \"trigger\" | \"bridge\" | \"extension\" | \"delegate\";\n\n// Per-thread chain tail. Each enqueue chains onto the previous tail; the\n// new promise becomes the tail. When the tail settles AND no one chained\n// onto it in the meantime, the entry is removed to keep the map bounded.\nconst tails = new Map<string, Promise<unknown>>();\n\n// Per-thread depth counter. Bumped on enqueue, decremented when the job\n// settles. Used for queue_position reporting and the overflow guard.\nconst depths = new Map<string, number>();\n\nconst DEFAULT_MAX_DEPTH = 16;\n\nexport interface EnqueueOptions {\n /** Soft cap on per-thread queue depth. Returning above this throws a\n * `QueueFullError` so the caller can drop the fire instead of pinning\n * it in memory. Default 16. */\n maxDepth?: number;\n}\n\nexport interface EnqueueResult<T> {\n /** Promise that resolves when this job's runner completes. Awaiting\n * this is what blocks bridge/trigger callers until they have the\n * assistant content to reply / persist. The HTTP route can fire-and-\n * forget. */\n result: Promise<T>;\n /** 0-indexed slot at enqueue time. 0 means \"running now\" (no jobs\n * ahead), N means \"waiting behind N jobs\". Snapshot only — drains\n * monotonically as preceding jobs finish but we don't surface\n * progress updates. */\n position: number;\n}\n\nexport class QueueFullError extends Error {\n constructor(thread_id: string, depth: number) {\n super(`Per-thread run queue full for thread ${thread_id} (depth=${depth})`);\n this.name = \"QueueFullError\";\n }\n}\n\nexport function enqueueThreadRun<T>(\n thread_id: string,\n _source: Source,\n runner: () => Promise<T>,\n options: EnqueueOptions = {},\n): EnqueueResult<T> {\n const max = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n const currentDepth = depths.get(thread_id) ?? 0;\n if (currentDepth >= max) {\n throw new QueueFullError(thread_id, currentDepth);\n }\n const position = currentDepth;\n depths.set(thread_id, currentDepth + 1);\n\n // Chain onto the existing tail. Both fulfilled and rejected branches\n // run the new runner — one job's failure must not skip the next.\n const prev = tails.get(thread_id) ?? Promise.resolve();\n const next: Promise<T> = prev.then(() => runner(), () => runner());\n\n tails.set(thread_id, next);\n // Side-channel cleanup. `.finally` propagates the rejection, so absorb\n // it with a no-op `.catch` — the real rejection is still surfaced to\n // the caller via the returned `result` promise.\n next.finally(() => {\n const d = depths.get(thread_id) ?? 0;\n if (d <= 1) depths.delete(thread_id);\n else depths.set(thread_id, d - 1);\n if (tails.get(thread_id) === next) tails.delete(thread_id);\n }).catch(() => { /* handled by caller via result */ });\n\n return { result: next, position };\n}\n\n/** Current queue depth for a thread, including the running head. 0 means\n * no in-flight or pending work. Useful for diagnostics and tests. */\nexport function getQueueDepth(thread_id: string): number {\n return depths.get(thread_id) ?? 0;\n}\n\n/** Reset all queue state. Test-only — never call from production code. */\nexport function __resetForTests(): void {\n tails.clear();\n depths.clear();\n}\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","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 } else if (event.type === \"usage\") {\n // ADR-0041: surface real provider token counts on the final\n // AIMessageChunk via LangChain's standard `usage_metadata` field so\n // the agent loop can snapshot them into message_usage. PR #181 added\n // Anthropic prompt caching; carry the cache breakdown through\n // `input_token_details` (LangChain's standard channel) so cost\n // attribution downstream can apply the 1.25× / 0.1× rates.\n emittedAny = true;\n const cacheCreation = event.cache_creation_input_tokens ?? 0;\n const cacheRead = event.cache_read_input_tokens ?? 0;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n usage_metadata: {\n input_tokens: event.input_tokens ?? 0,\n output_tokens: event.output_tokens ?? 0,\n total_tokens: event.total_tokens\n ?? (event.input_tokens ?? 0) + (event.output_tokens ?? 0),\n ...(cacheCreation > 0 || cacheRead > 0\n ? { input_token_details: { cache_creation: cacheCreation, cache_read: cacheRead } }\n : {}),\n },\n }),\n text: \"\",\n });\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 { 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, getModelParams, upsertModelConfig } 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 const params: ProviderParams = getModelParams(cfg);\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 // ADR-0041: accumulate real per-call provider usage across the react loop\n // so the `done` chunk can carry authoritative token counts for snapshot.\n // Each LLM call inside the multi-step loop yields its own usage chunk via\n // JarelaChatModel; we sum them so the final figure covers the whole turn.\n let usageInputTokens = 0;\n let usageOutputTokens = 0;\n // PR #181 + cache-fidelity follow-up: Anthropic prompt-cache reads/writes\n // arrive as a separate breakdown via `input_token_details`. Sum them\n // independently so the dashboard can report cost correctly (cache reads\n // are 10× cheaper, cache writes 1.25× more expensive than fresh input).\n let usageCacheCreationTokens = 0;\n let usageCacheReadTokens = 0;\n let sawUsage = false;\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: {\n thread_id: threadId,\n delegation_depth: runCfg?.delegation?.depth ?? 0,\n delegation_ancestors: runCfg?.delegation?.ancestors ?? [],\n },\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 // ADR-0041: capture provider-reported token usage when present.\n const usage = chunk.usage_metadata;\n if (usage && (usage.input_tokens > 0 || usage.output_tokens > 0)) {\n usageInputTokens += usage.input_tokens ?? 0;\n usageOutputTokens += usage.output_tokens ?? 0;\n const details = usage.input_token_details;\n if (details) {\n usageCacheCreationTokens += details.cache_creation ?? 0;\n usageCacheReadTokens += details.cache_read ?? 0;\n }\n sawUsage = true;\n }\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: sawUsage\n ? {\n input_tokens: usageInputTokens,\n output_tokens: usageOutputTokens,\n cache_creation_input_tokens: usageCacheCreationTokens,\n cache_read_input_tokens: usageCacheReadTokens,\n source: \"provider\",\n }\n : { input_tokens: 0, output_tokens: totalOutputTokens, source: \"estimate\" },\n provider: cfg.provider,\n model_id: cfg.model_id,\n model_config_name: cfg.name,\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 (isContextOverflowError(rawMsg)) {\n // Hit the model's input window. Either the assumed/known context size\n // is bigger than what the provider actually serves on this tier, the\n // user's plan is throttled, or the conversation legitimately overflowed.\n // Either way the budget calculator's assumption was optimistic — tell\n // the user how to recover instead of dumping the provider stack.\n const observed = parseContextLimitFromError(rawMsg);\n if (observed && observed.limit > 0) {\n // Self-correct: persist the provider-reported limit back to the\n // model config so the next turn's budget calculator uses it. We\n // shrink by 10% as a safety margin (tokenisers disagree and tool\n // results we don't yet count add overhead). Only writes when the\n // new value is smaller than what's stored — never grows blindly.\n try {\n const current = typeof params.context_window_tokens === \"number\"\n ? params.context_window_tokens\n : Number.POSITIVE_INFINITY;\n const corrected = Math.max(2048, Math.floor(observed.limit * 0.9));\n if (corrected < current) {\n const nextParams = { ...params, context_window_tokens: corrected };\n upsertModelConfig(cfg.name, cfg.provider, cfg.model_id, nextParams, cfg.is_default === 1);\n console.warn(\n `[llm] context-window self-correct for ${cfg.name} (${cfg.provider}/${cfg.model_id}): ` +\n `provider reported ${observed.limit} tokens; persisted context_window_tokens=${corrected}`,\n );\n }\n } catch (persistErr) {\n console.error(\"[llm] failed to self-correct context_window_tokens\", persistErr);\n }\n friendly =\n `The request exceeded the model's context window (provider reported ~${observed.limit.toLocaleString()} tokens` +\n (observed.requested ? `, request had ~${observed.requested.toLocaleString()}` : \"\") +\n `). Persisted the corrected window on this model config; retry the turn or trim history.`;\n } else {\n friendly =\n \"The request exceeded the model's context window. \" +\n \"Trim history (lower `history_limit` / `history_window_hours` on the agent), \" +\n \"pin a smaller `context_window_tokens` in the model config so the budget calculator \" +\n \"leaves more headroom, or start a new thread.\";\n }\n code = \"context_length_exceeded\";\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: sawUsage\n ? {\n input_tokens: usageInputTokens,\n output_tokens: usageOutputTokens,\n cache_creation_input_tokens: usageCacheCreationTokens,\n cache_read_input_tokens: usageCacheReadTokens,\n source: \"provider\",\n }\n : { input_tokens: 0, output_tokens: totalOutputTokens, source: \"estimate\" },\n provider: cfg.provider,\n model_id: cfg.model_id,\n model_config_name: cfg.name,\n },\n };\n}\n\n// Detect provider error messages that indicate the request exceeded the\n// model's input/context window. Patterns sourced from OpenAI, Anthropic,\n// Gemini, DeepSeek, and the Copilot proxy.\nexport function isContextOverflowError(msg: string): boolean {\n if (!msg) return false;\n return (\n /context[_ ]length[_ ]exceeded/i.test(msg) ||\n /maximum context length/i.test(msg) ||\n /context window/i.test(msg) ||\n /prompt is too long/i.test(msg) ||\n /input(?:'s)? token count.*exceeds/i.test(msg) ||\n /exceeds the maximum number of tokens/i.test(msg) ||\n /request too large.*tokens/i.test(msg) ||\n /too many input tokens/i.test(msg) ||\n /string too long/i.test(msg)\n );\n}\n\n// Extract the model's actual context-window size (and, when present, the\n// request size) from a provider error message. Provider phrasings observed:\n// OpenAI: \"maximum context length is 128000 tokens. However, your\n// messages resulted in 213998 tokens\"\n// OpenAI: \"This model's maximum context length is 8192 tokens, however\n// you requested 9000 tokens\"\n// Anthropic: \"prompt is too long: 235812 tokens > 200000 maximum\"\n// Gemini: \"The input token count (1234567) exceeds the maximum number\n// of tokens allowed (1048576)\"\n// DeepSeek: \"Range of input length should be [1, 65536]\"\n// Returns null when no number pair can be confidently extracted.\nexport function parseContextLimitFromError(\n msg: string,\n): { limit: number; requested?: number } | null {\n if (!msg) return null;\n const num = (s: string) => parseInt(s.replace(/[,_\\s]/g, \"\"), 10);\n\n // OpenAI \"maximum context length is X tokens\" (+ optional \"resulted in Y\" / \"requested Y\")\n const openai = msg.match(\n /maximum context length is\\s+([\\d,_\\s]+)\\s*tokens?[\\s\\S]*?(?:resulted in|requested)\\s+([\\d,_\\s]+)/i,\n );\n if (openai) {\n const limit = num(openai[1]);\n const requested = num(openai[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n const openaiNoReq = msg.match(/maximum context length is\\s+([\\d,_\\s]+)/i);\n if (openaiNoReq) {\n const limit = num(openaiNoReq[1]);\n if (limit > 0) return { limit };\n }\n\n // Anthropic \"prompt is too long: N tokens > M maximum\"\n const anthropic = msg.match(/prompt is too long:\\s*([\\d,_\\s]+)\\s*tokens?\\s*>\\s*([\\d,_\\s]+)/i);\n if (anthropic) {\n const requested = num(anthropic[1]);\n const limit = num(anthropic[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n\n // Gemini \"input token count (N) exceeds the maximum number of tokens allowed (M)\"\n const gemini = msg.match(/input token count\\s*\\(([\\d,_\\s]+)\\)[\\s\\S]*?\\(([\\d,_\\s]+)\\)/i);\n if (gemini) {\n const requested = num(gemini[1]);\n const limit = num(gemini[2]);\n if (limit > 0) return { limit, requested: requested > 0 ? requested : undefined };\n }\n\n // DeepSeek \"Range of input length should be [1, N]\"\n const deepseek = msg.match(/range of input length should be\\s*\\[\\s*\\d+\\s*,\\s*([\\d,_\\s]+)\\s*\\]/i);\n if (deepseek) {\n const limit = num(deepseek[1]);\n if (limit > 0) return { limit };\n }\n\n return null;\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 { 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 { 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\n/**\n * Roll unused tier headroom into the spill pool that the next tier in\n * priority order will draw from. Each tier receives `softCap + incomingSpill`\n * to spend; whatever it doesn't use becomes the next tier's `incomingSpill`.\n *\n * Pure: no allocation order is assumed — callers walk `tierPriority` and\n * decide the data-flow ordering separately.\n */\nexport function applyTierSpill(\n softCap: number,\n incomingSpill: number,\n used: number,\n): { cap: number; spill: number } {\n const cap = softCap + incomingSpill;\n return { cap, spill: Math.max(0, cap - used) };\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}","// System-prompt assembly. Pure function: given the resolved context\n// (agent config, history budget, recall hits, etc.), returns the joined\n// system-prompt string passed to the provider. Each context block is a\n// file-private helper; the top-level `buildSystemPrompt` joins them in\n// the order the harness has documented since ADR-0033.\n//\n// See ADR-0039 for the decomposition rationale.\n\nimport os from \"node:os\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { parseCitationStrictness } from \"@/lib/stores/agent-configs\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { listIntegrations } from \"@/lib/stores/integrations\";\nimport { listEnabledDocumentSources, getDocumentSourceStats } from \"@/lib/stores/document-sources\";\nimport { buildAdaptivePersonaContext } from \"@/lib/agents/adaptive-persona\";\nimport { resolveHarness } from \"@/lib/agents/harness/resolve\";\nimport {\n type ContextBudget,\n formatContextBudgetSummary,\n} from \"@/lib/agents/context-budget\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport type { StreamOptions } from \"@/lib/agents/base\";\nimport type { SourceManifestEntry } from \"@/lib/agents/citation-checker\";\n\nconst APP_NAME = getAppName();\n\nexport interface SystemPromptContext {\n agentCfg: AgentConfigRow;\n trimmedMessage: string;\n budget: ContextBudget;\n recallCtx: string;\n warmSummaryCtx: string;\n factsCtx: string;\n experienceMode: \"essential\" | \"full\";\n delegateRosterLines: string[];\n /** Numbered source manifest the agent may cite via `[N]` markers. Built\n * by run-thread from the thread's visited-source set + prior-dialog\n * turns when the agent's `citation_strictness` is not `'off'`. Empty\n * array or undefined disables citation. */\n sourceManifest?: ReadonlyArray<SourceManifestEntry>;\n}\n\nexport function buildSystemPrompt(ctx: SystemPromptContext): string {\n const { agentCfg, trimmedMessage, budget, recallCtx, warmSummaryCtx, factsCtx, experienceMode, delegateRosterLines, sourceManifest } = ctx;\n\n const adaptivePersonaCtx = buildAdaptivePersonaContext(agentCfg, trimmedMessage);\n const harnessParts = resolveHarness(agentCfg);\n\n // Tier ordering follows the agent's configured priority (hot is the\n // in-prompt history itself, so it doesn't have a context block here).\n const tierCtxByName = { hot: \"\", warm: warmSummaryCtx, facts: factsCtx } as const;\n const tierOrderCtx = budget.tierPriority.map((t) => tierCtxByName[t]).filter(Boolean);\n\n const parts: (string | null | undefined)[] = [\n agentCfg.identity,\n agentCfg.instructions,\n adaptivePersonaCtx,\n buildUserContext(),\n buildIntegrationsContext(),\n buildDocumentsContext(),\n harnessParts.capabilities,\n harnessParts.plan_first,\n harnessParts.presentation,\n harnessParts.citation,\n buildSourceLinkContext(agentCfg, sourceManifest ?? []),\n buildTimeContext(),\n buildEnvContext(),\n harnessParts.self_config,\n buildExperienceContext(experienceMode),\n buildOutputBudgetContext(budget),\n buildMemoryContext(budget),\n ...tierOrderCtx,\n recallCtx,\n buildDelegatesContext(delegateRosterLines),\n ];\n\n return parts.filter(Boolean).join(\"\\n\\n\");\n}\n\nexport function resolveExperienceMode(options?: StreamOptions): \"essential\" | \"full\" {\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 raw = options?.ui_experience_mode;\n return raw === \"essential\" || raw === \"normal\" ? \"essential\" : \"full\";\n}\n\n// ── Context block builders (file-private) ────────────────────────────────\n\nfunction buildUserContext(): string {\n const userProfile = getUserProfile();\n const parts: string[] = [];\n if (userProfile?.name) parts.push(`Name: ${userProfile.name}`);\n if (userProfile?.about) parts.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 parts.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 return parts.length > 0 ? `--- User context ---\\n${parts.join(\"\\n\")}` : \"\";\n}\n\nfunction buildTimeContext(): string {\n return `Current time: ${new Date().toISOString()} (UTC). Use this when computing scheduled task timestamps.`;\n}\n\n// Citation enforcement directive. Empty unless the agent's\n// `citation_strictness` is not `'off'`. Shows the numbered source\n// manifest (tool-visited sources + memory items + prior assistant turns)\n// the agent may cite via inline `[N]` markers — the chat UI renders each\n// `[N]` as a clickable link or anchor. Invented numbers stay as plain\n// text and are flagged by the post-turn checker.\n//\n// Strictness levels:\n// informational — agent NOT asked to cite (checker still surfaces\n// references in the UI)\n// standard — agent nudged to cite KEY (load-bearing) claims\n// strict — agent asked to cite EVERY factual claim\n//\n// Numbered markers were chosen over free-form `[label](href)` because\n// long-form LLM output reliably regresses to its training distribution\n// when asked to type exact paths mid-sentence — Perplexity, Wikipedia,\n// and Anthropic's first-party Citations all sidestep that by letting the\n// model emit a short stable token (`[3]`) and resolving the link\n// out-of-band. Same idea here.\nfunction buildSourceLinkContext(\n agent: AgentConfigRow,\n manifest: ReadonlyArray<SourceManifestEntry>,\n): string {\n const strictness = parseCitationStrictness(agent.citation_strictness) ?? \"off\";\n if (strictness === \"off\" || strictness === \"informational\") return \"\";\n\n const intro =\n strictness === \"strict\"\n ? \"Your reply will be audited by a second-pass model that ranks every factual claim by impact. Cite EVERY factual claim — quoted numbers, file contents, API behavior, named facts, paraphrases of earlier turns. The audit downgrades unsupported claims as low-confidence; citing up front saves you from re-grounding rounds for things you already know.\"\n : \"Your reply will be audited by a second-pass model that ranks every factual claim by impact. Cite KEY load-bearing claims (quoted numbers, file contents, API behavior, named facts). Don't mark incidentals, summaries, plans, or your own derivations — over-citing is as bad as not citing. The audit re-grounds unsupported KEY claims; citing up front saves the extra round.\";\n\n // The pre-turn manifest is always empty under the current design — we\n // surface citable references in the post-turn manifest after tool\n // events have actually been recorded. So the only valid citation form\n // during drafting is the inline markdown link.\n void manifest;\n return [\n \"--- Citation format ---\",\n intro,\n \"PRIMARY (inline links): cite by writing a standard markdown link inline: `[short label](https://example.com/path)` or `[file name](/abs/path.ts)` or `[earlier reply](#msg-<id>)`. Wrap the cited PHRASE itself as the link text when natural — `Jade has [ice skating at 16:00](?thread=…&agent=…)` reads better than a trailing `[1]`.\",\n \"When a tool result contains a `cite_as` field (delegate_to_agent does, and so do some integrations), paste that exact value somewhere in your reply — it's a pre-built markdown link to the source. Anything you summarize from a delegate or from a web/file tool result MUST carry at least one inline link back to where it came from; a summary with zero links reads as if you made the facts up.\",\n \"For web_search / fetch_webpage results, the URL is right there in the tool output — use it: `[headline or short label](https://...)`. For file_read results, link the absolute path: `[filename.ext](/abs/path/filename.ext)`.\",\n \"FALLBACK (declared refs block): if a source is awkward to cite inline (e.g. you summarized 4 articles in one paragraph), you MAY end your reply with a fenced block exactly like this:\",\n \"```jarela-references\",\n \"[\",\n \" { \\\"label\\\": \\\"CNN — Mars mission\\\", \\\"href\\\": \\\"https://cnn.com/...\\\" },\",\n \" { \\\"label\\\": \\\"Postman's reply\\\", \\\"href\\\": \\\"?thread=...&agent=...\\\" }\",\n \"]\",\n \"```\",\n \"Rules for the declared-refs block: it MUST be the very last thing in your reply, MUST be valid JSON (an array of `{label, href}` objects, both strings), and MUST be inside a fenced code block tagged exactly `jarela-references`. The block is stripped from your reply before it's shown to the user — the entries appear as numbered chips in a References footer the UI builds automatically. Use this sparingly — inline links are always preferred because they show the user which words came from where.\",\n \"DO NOT write `[CNN, June 4]`, `[Reuters]`, `[AP News]`, or any other bare-text bracket without a URL — those are NOT citations, they render as plain text and the audit counts them as uncited.\",\n \"If a claim is central to your answer and you have no link to attach, ground it first via a tool (web_search, fetch_webpage, file_read, …) before stating it.\",\n ].join(\"\\n\");\n}\n\nfunction buildExperienceContext(mode: \"essential\" | \"full\"): string {\n return [\n \"--- UX mode ---\",\n `User interface mode: ${mode}.`,\n mode === \"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\nfunction buildEnvContext(): string {\n return [\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\nfunction buildIntegrationsContext(): string {\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 configured = listIntegrations().filter((i) => i.configured);\n if (configured.length === 0) return \"\";\n\n const lines: string[] = [\"--- Configured integrations (use the typed tools, not shell CLIs) ---\"];\n for (const i of configured) {\n if (i.name === \"atlassian\") {\n const url = i.values.url;\n lines.push(\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 } else if (i.name === \"jira_align\") {\n lines.push(\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 } else if (i.name === \"github\") {\n lines.push(\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 } else if (i.name === \"gmail\") {\n lines.push(\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 } else if (i.name === \"outlook\") {\n lines.push(\n \"Outlook + Calendar: configured.\",\n \" Use outlook_* for mail operations and outlook_calendar_* for event operations.\",\n );\n } else if (i.name === \"google\") {\n lines.push(\n \"Google AI: configured.\",\n \" Use generate_image when the user asks to create images; don't claim image generation is unavailable.\",\n );\n } else {\n lines.push(`${i.name}: configured.`);\n }\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction buildOutputBudgetContext(budget: ContextBudget): string {\n const tokens = budget.outputReserveTokens;\n const words = Math.round(tokens * 0.75);\n return [\n \"--- Output budget ---\",\n `Your reply is capped at ~${tokens} output tokens per turn (≈${words} words). The provider truncates mid-sentence if you exceed it — you will not get a chance to finish.`,\n \"- Lead with the answer. Skip preambles, restating the question, and recapping context the user already sees.\",\n \"- If the user asks for a long artifact (essay, plan, large code dump, exhaustive list), estimate the size first. If it won't fit, ask whether to split across turns, summarise, or stream only the requested section.\",\n \"- Prefer dense prose and tight bullets over verbose explanation. Don't repeat yourself across paragraphs.\",\n ].join(\"\\n\");\n}\n\nfunction buildMemoryContext(budget: ContextBudget): string {\n return [\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\nfunction buildDelegatesContext(lines: string[]): string {\n if (lines.length === 0) return \"\";\n return [\n \"--- Available delegates ---\",\n \"You can hand subtasks to these other agents via the `delegate_to_agent` tool. Only delegate when the target agent has specialized knowledge or tools you lack — don't delegate trivial subtasks.\",\n \"BEFORE you call delegate_to_agent, briefly tell the user in one sentence which agent you're handing to and why. The user will see the tool card with the delegate's name, task, and final result.\",\n ...lines,\n ].join(\"\\n\");\n}\n\n// Surface indexed Documents so the model knows the RAG corpus exists.\n// Without this nudge agents almost never call `documents_search` — they have\n// no signal that any local content is searchable. Gated on actually-indexed\n// chunks (not just configured sources) so an empty/erroring source doesn't\n// produce false advertising.\nfunction buildDocumentsContext(): string {\n const sources = listEnabledDocumentSources();\n if (sources.length === 0) return \"\";\n\n let totalChunks = 0;\n const lines: string[] = [];\n for (const s of sources) {\n const stats = getDocumentSourceStats(s.id);\n if (stats.chunk_count === 0) continue;\n totalChunks += stats.chunk_count;\n const label = s.label ?? s.path;\n lines.push(`- ${label} (${s.kind}, ${stats.chunk_count} chunks)`);\n }\n if (totalChunks === 0) return \"\";\n\n return [\n \"--- Indexed documents ---\",\n `The user has ${totalChunks} indexed chunks across ${lines.length} document source(s) available to you:`,\n ...lines,\n \"Call `documents_search` whenever the user asks about local files, notes, project docs, or any content that sounds like it lives in one of these sources. Prefer it over guessing from training data. Use `documents_list_sources` to enumerate, and pass `source_id` to scope a search.\",\n ].join(\"\\n\");\n}\n","// History-window assembly. Pulls the latest N messages within the agent's\n// time bound, computes the context budget, summarises overflow into a warm\n// recap, and pulls fact-memory hits relevant to the current turn.\n//\n// All work is synchronous SQLite + one optional LLM call (for the warm\n// summary). The LLM call is best-effort: if the provider errors, we return\n// an empty warm context rather than blocking the turn.\n//\n// See ADR-0039 for the decomposition rationale.\n\nimport { getRecentMessagesWindow, getThread, setThreadWarmSummary } from \"@/lib/stores/threads\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\nimport {\n applyTierSpill,\n computeContextBudget,\n estimateTokens,\n takeRecentMessagesWithinBudget,\n truncateLargestMessagesWithinBudget,\n type ContextBudget,\n} from \"@/lib/agents/context-budget\";\nimport { summarizeTranscript, transcriptText } from \"@/lib/agents/conversation-summary\";\nimport type { MessageRow } from \"@/lib/stores/threads\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getKnownContextLength } from \"@/lib/providers/known-context-windows\";\nimport type { ContentPart } from \"@/lib/tools/types\";\n\nexport interface ResolvedHistoryWindow {\n history: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>;\n budget: ContextBudget;\n warmSummaryCtx: string;\n factsCtx: string;\n // Per-tier *actual* input-token consumption derived from the assembled\n // window. Lets the chat UI render a diagnostic context-usage bar that\n // shows which tier is starving so the user can rebalance the agent's\n // hot/warm/facts split. Overhead is the system-prompt-side allowance\n // (caller may overwrite with a more precise measurement before persist).\n tierUsage: {\n hot_tokens: number;\n warm_tokens: number;\n facts_tokens: number;\n overhead_tokens: number;\n };\n}\n\n/**\n * Build the per-turn history window the LLM sees. Returns the in-prompt\n * message list (already JSON-content-parsed), the context budget, and\n * the warm-summary + facts context strings ready to slot into the system\n * prompt.\n *\n * `hotSince` (ADR-0042) is the user's explicit context boundary. When set,\n * it overrides the agent's `history_window_hours`-derived bound so the\n * boundary line in the chat is the source of truth for what enters hot.\n * When fresh, the cached `warm_summary` on the thread is reused; when the\n * boundary has moved since the last summary was computed (or no summary\n * exists), the warm tier re-summarises and the new text is persisted.\n */\nexport async function buildHistoryWindow(\n thread_id: string,\n agentCfg: AgentConfigRow,\n providerParams: ProviderParams,\n trimmedMessage: string,\n modelInfo: { providerName?: string; modelId?: string },\n hotSince?: string | null,\n): Promise<ResolvedHistoryWindow> {\n const limit = agentCfg.history_limit ?? 50;\n const windowHours = agentCfg.history_window_hours ?? 8;\n // Explicit pin wins over the agent default. NULL/undefined falls back to\n // the time-window heuristic; existing threads with no pin behave exactly\n // as they did before this ADR landed.\n const sinceISO = hotSince\n ? hotSince\n : windowHours > 0\n ? new Date(Date.now() - windowHours * 3600_000).toISOString()\n : undefined;\n const allWindowMessages = getRecentMessagesWindow(thread_id, limit, sinceISO);\n\n // Reuse the persisted warm summary when the boundary it covers still\n // matches the current pin — saves an LLM call on every turn that doesn't\n // change the boundary.\n const cached = hotSince ? getThread(thread_id) : null;\n const cachedSummaryFresh =\n !!cached?.warm_summary && cached.warm_summary_before === hotSince;\n\n const budget = computeContextBudget({\n context_window_tokens:\n typeof providerParams.context_window_tokens === \"number\"\n ? providerParams.context_window_tokens\n : resolveFallbackContextWindow(modelInfo),\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 // Walk tiers in the configured priority order, threading the unused-token\n // spill from each tier into the next so leftover headroom isn't wasted.\n // Default priority [hot, warm, facts] makes this identical to the natural\n // data-flow order; non-default priorities still respect the data-flow\n // dependency (warm needs hot's slice) by falling back to hot's soft cap\n // when warm is asked to evaluate before hot has run.\n let spill = 0;\n let hotMessages: MessageRow[] | undefined;\n let hotCap = 0;\n let warmSummaryCtx = \"\";\n let factsCtx = \"\";\n\n for (const tier of budget.tierPriority) {\n if (tier === \"hot\") {\n ({ cap: hotCap } = applyTierSpill(budget.tierBudgets.hot, spill, 0));\n hotMessages = takeRecentMessagesWithinBudget(allWindowMessages, hotCap);\n const used = sumMessageTokens(hotMessages);\n ({ spill } = applyTierSpill(budget.tierBudgets.hot, spill, used));\n } else if (tier === \"warm\") {\n const warmCap = budget.tierBudgets.warm + spill;\n if (cachedSummaryFresh && cached?.warm_summary) {\n // Pin-stable turn: don't pay the summariser tax again.\n warmSummaryCtx = cached.warm_summary;\n } else {\n // If priority evaluates warm before hot, do a provisional hot slice at\n // hot's soft cap so we know which messages to summarise. Hot's later\n // pass may then absorb more (its cap will include any warm spill back),\n // and the warm summary will harmlessly cover a few messages hot also\n // includes — better than not summarising at all.\n const hotForSlice = hotMessages ?? takeRecentMessagesWithinBudget(allWindowMessages, budget.tierBudgets.hot);\n warmSummaryCtx = await buildWarmSummary(\n allWindowMessages,\n hotForSlice.length,\n modelInfo.providerName,\n modelInfo.modelId,\n providerParams,\n warmCap,\n );\n // Persist the freshly-computed summary keyed on the boundary it\n // covers, so the chat UI can render it on the next page load and\n // subsequent same-pin turns can short-circuit the LLM call. Skipped\n // when there's no explicit pin because the time-windowed boundary\n // shifts every turn — caching it would never hit.\n if (warmSummaryCtx && hotSince) {\n setThreadWarmSummary(thread_id, warmSummaryCtx, hotSince);\n }\n }\n const used = estimateTokens(warmSummaryCtx);\n ({ spill } = applyTierSpill(budget.tierBudgets.warm, spill, used));\n } else {\n const factsCap = budget.tierBudgets.facts + spill;\n factsCtx = buildFactsContext(trimmedMessage, factsCap);\n const used = estimateTokens(factsCtx);\n ({ spill } = applyTierSpill(budget.tierBudgets.facts, spill, used));\n }\n }\n\n // Hot is always evaluated above (priority always contains all three tiers),\n // but TypeScript can't see that. Default to an empty list defensively.\n const hotMessagesResolved = hotMessages ?? [];\n\n // If the warm tier was expected but failed to summarise, fall back to\n // truncating the largest hot messages so the older context isn't silently\n // dropped — better to clip overlong messages than lose them entirely.\n const warmWasExpected = budget.tierBudgets.warm > 32 && (allWindowMessages.length - hotMessagesResolved.length) >= 2;\n const hotMessagesForPrompt = !warmSummaryCtx && warmWasExpected\n ? truncateLargestMessagesWithinBudget(hotMessagesResolved, hotCap || budget.tierBudgets.hot)\n : hotMessagesResolved;\n\n const history = hotMessagesForPrompt.map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: parseContent(m.content),\n }));\n\n // Re-measure hot AFTER any truncation so the recorded usage matches what\n // actually went into the prompt. Warm/facts are already finalised above.\n const hotTokensFinal = hotMessagesForPrompt.reduce(\n (acc, m) => acc + estimateTokens(transcriptText(m.content)),\n 0,\n );\n\n return {\n history,\n budget,\n warmSummaryCtx,\n factsCtx,\n tierUsage: {\n hot_tokens: hotTokensFinal,\n warm_tokens: estimateTokens(warmSummaryCtx),\n facts_tokens: estimateTokens(factsCtx),\n overhead_tokens: budget.overheadTokens,\n },\n };\n}\n\nfunction sumMessageTokens(messages: readonly MessageRow[]): number {\n return messages.reduce((acc, m) => acc + estimateTokens(transcriptText(m.content)), 0);\n}\n\n// When the agent's model config doesn't pin `context_window_tokens`, fall\n// back to the web-sourced known-models table keyed by (provider, model_id).\n// Returns undefined when the model is unrecognised — the budget calculator\n// then uses its hard-coded 8k default.\nfunction resolveFallbackContextWindow(\n modelInfo: { providerName?: string; modelId?: string },\n): number | undefined {\n if (!modelInfo.providerName || !modelInfo.modelId) return undefined;\n return getKnownContextLength(modelInfo.providerName, modelInfo.modelId) ?? undefined;\n}\n\n// Recover ContentPart[] from messages that were stored as JSON-encoded\n// arrays (text + attachments). Plain string messages pass through.\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\nasync function buildWarmSummary(\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","export type { ThreadRunRequest } from \"./request\";\nexport {\n buildSystemPrompt,\n resolveExperienceMode,\n type SystemPromptContext,\n} from \"./system-prompt\";\nexport {\n buildHistoryWindow,\n type ResolvedHistoryWindow,\n} from \"./history-window\";\n","// Authoritative published per-1M-token rates for canonical model ids.\n//\n// Used by `modelRatesFor` as the FINAL fallback after the live snapshot\n// lookup chain. The snapshot extractor can break when a provider redesigns\n// its pricing page (regex window misses the model name, LLM extraction\n// returns uniform garbage); without a baseline, the dashboard cost columns\n// silently go to null on the most-used models. This table guarantees a\n// non-null rate for the canonical ids regardless of snapshot health.\n//\n// **These rates ARE stale by construction.** Bump manually when a provider\n// updates published pricing. The live snapshot — when healthy — wins; this\n// is only consulted when nothing else matched. Confidence is reported as\n// \"medium\" so the dashboard's data-quality chip flags it as not-the-source-\n// of-truth.\n//\n// Keep the list short. Only include canonical ids the snapshot extractor\n// reliably struggles with. Aliases handled by `modelAliasCandidates` (e.g.\n// the post-`/` suffix of `openai/gpt-4o`) so we don't need separate entries\n// for aggregator-namespaced ids.\n//\n// Sources, last verified 2026-06:\n// - https://www.anthropic.com/pricing\n// - https://openai.com/api/pricing/\n// - https://ai.google.dev/gemini-api/docs/pricing\n// - https://platform.deepseek.com/pricing\n\nimport type { ProviderRates } from \"./pricing\";\n\ninterface KnownRate {\n inputPer1M: number;\n outputPer1M: number;\n}\n\nconst KNOWN_MODEL_RATES: Record<string, KnownRate> = {\n // Anthropic\n \"claude-opus-4-7\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4-6\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4-5\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-opus-4\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-sonnet-4-6\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-sonnet-4-5\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-sonnet-4\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-haiku-4-5\": { inputPer1M: 1, outputPer1M: 5 },\n \"claude-3-5-sonnet\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-3-5-haiku\": { inputPer1M: 0.8, outputPer1M: 4 },\n \"claude-3-opus\": { inputPer1M: 15, outputPer1M: 75 },\n \"claude-3-sonnet\": { inputPer1M: 3, outputPer1M: 15 },\n \"claude-3-haiku\": { inputPer1M: 0.25, outputPer1M: 1.25 },\n\n // OpenAI\n \"gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n \"gpt-4-turbo\": { inputPer1M: 10, outputPer1M: 30 },\n \"gpt-4\": { inputPer1M: 30, outputPer1M: 60 },\n \"gpt-3.5-turbo\": { inputPer1M: 0.5, outputPer1M: 1.5 },\n \"o1\": { inputPer1M: 15, outputPer1M: 60 },\n \"o1-mini\": { inputPer1M: 3, outputPer1M: 12 },\n \"o1-preview\": { inputPer1M: 15, outputPer1M: 60 },\n \"o3-mini\": { inputPer1M: 1.1, outputPer1M: 4.4 },\n\n // Google Gemini\n \"gemini-2.5-pro\": { inputPer1M: 1.25, outputPer1M: 5 },\n \"gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5 },\n \"gemini-2.5-flash-lite\": { inputPer1M: 0.1, outputPer1M: 0.4 },\n \"gemini-2.0-flash\": { inputPer1M: 0.1, outputPer1M: 0.4 },\n \"gemini-2.0-flash-lite\": { inputPer1M: 0.075, outputPer1M: 0.3 },\n \"gemini-1.5-pro\": { inputPer1M: 1.25, outputPer1M: 5 },\n \"gemini-1.5-flash\": { inputPer1M: 0.075, outputPer1M: 0.3 },\n\n // DeepSeek\n \"deepseek-chat\": { inputPer1M: 0.27, outputPer1M: 1.10 },\n \"deepseek-reasoner\": { inputPer1M: 0.55, outputPer1M: 2.19 },\n \"deepseek-coder\": { inputPer1M: 0.27, outputPer1M: 1.10 },\n\n // Cohere\n \"command-r-plus\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"command-r\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\nexport function knownRateFor(modelId: string): ProviderRates | null {\n const key = modelId.trim().toLowerCase();\n if (!key) return null;\n const hit = KNOWN_MODEL_RATES[key];\n if (!hit) return null;\n return {\n inputPer1M: hit.inputPer1M,\n outputPer1M: hit.outputPer1M,\n source: \"jarela:known-rates\",\n inferred: false,\n confidence: \"medium\",\n ok: true,\n status: null,\n error: null,\n };\n}\n\nexport function knownRateModelIds(): string[] {\n return Object.keys(KNOWN_MODEL_RATES);\n}\n","// Sync pricing lookups for both write-time cost snapshots (ADR-0041\n// `message_usage`) and read-time dashboard aggregation.\n//\n// The previous live in `lib/stores/dashboard-metrics.ts` was async because\n// the dashboard was the only consumer and it loaded the JSON via fs/promises.\n// The write path (persistAssistantMessage) needs sync access, so we read\n// the snapshot synchronously and cache it in process memory keyed by\n// mtime. Refreshing the pricing snapshot on disk invalidates the cache on\n// next read.\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { knownRateFor } from \"./known-rates\";\n\nexport type ProviderRates = {\n inputPer1M: number | null;\n outputPer1M: number | null;\n source: string;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n ok: boolean;\n status: number | null;\n error: string | null;\n};\n\ntype PricingSnapshotSource = {\n id: string;\n pricing_url: string;\n resolved_url?: string | null;\n ok?: boolean;\n status?: number | null;\n error?: string | null;\n price_signals?: string[];\n model_rates?: Array<{\n model_id: string;\n input_per_1m_usd: number | null;\n output_per_1m_usd: number | null;\n inferred?: boolean;\n confidence?: \"high\" | \"medium\" | \"low\";\n }>;\n};\n\ntype PricingSnapshot = {\n generated_at?: string;\n sources?: PricingSnapshotSource[];\n};\n\nexport interface PricingTables {\n byProvider: Map<string, ProviderRates>;\n byProviderModel: Map<string, ProviderRates>;\n // Aggregator-agnostic: lookup by model_id alone. Some providers proxy\n // upstream models (github-copilot, openrouter-style aggregators) and\n // don't expose per-model pricing themselves, so we also index every\n // model_rate by its model id. First-write wins; subsequent same-id\n // entries only overwrite when they improve confidence or fill a null.\n byModel: Map<string, ProviderRates>;\n generatedAt: string | null;\n}\n\nconst EXPECTED_PROVIDERS = [\"openai\", \"anthropic\", \"google\", \"deepseek\", \"cohere\", \"github-copilot\"];\n\nlet cached: { mtimeMs: number; tables: PricingTables } | null = null;\n\nfunction snapshotPath(): string {\n return join(process.cwd(), \"docs\", \"journal\", \"pricing-snapshot.json\");\n}\n\nfunction readSnapshotSync(): { snapshot: PricingSnapshot | null; mtimeMs: number } {\n try {\n const p = snapshotPath();\n const stat = statSync(p);\n const raw = readFileSync(p, \"utf8\");\n return { snapshot: JSON.parse(raw) as PricingSnapshot, mtimeMs: stat.mtimeMs };\n } catch {\n return { snapshot: null, mtimeMs: 0 };\n }\n}\n\nexport function getPricingTables(): PricingTables {\n const { snapshot, mtimeMs } = readSnapshotSync();\n if (cached && cached.mtimeMs === mtimeMs) return cached.tables;\n\n const byProvider = new Map<string, ProviderRates>();\n const byProviderModel = new Map<string, ProviderRates>();\n const byModel = new Map<string, ProviderRates>();\n\n for (const provider of EXPECTED_PROVIDERS) {\n byProvider.set(provider, {\n inputPer1M: null,\n outputPer1M: null,\n source: \"snapshot-missing\",\n inferred: true,\n confidence: \"low\",\n ok: false,\n status: null,\n error: \"provider missing in pricing snapshot\",\n });\n }\n\n if (snapshot?.sources) {\n for (const source of snapshot.sources) {\n const key = normalizeProvider(source.id);\n if (!key) continue;\n const parsed = inferRatesFromSignals(source.price_signals ?? []);\n const modelInputRates = (source.model_rates ?? [])\n .map((m) => m.input_per_1m_usd)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n const modelOutputRates = (source.model_rates ?? [])\n .map((m) => m.output_per_1m_usd)\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n\n const providerInput = parsed.inputPer1M ?? (modelInputRates[0] ?? null);\n const providerOutput = parsed.outputPer1M ?? (modelOutputRates[0] ?? null);\n const providerDerivedFromModels = parsed.inputPer1M == null && parsed.outputPer1M == null\n && (providerInput != null || providerOutput != null);\n\n byProvider.set(key, {\n inputPer1M: providerInput,\n outputPer1M: providerOutput,\n source: source.resolved_url ?? source.pricing_url,\n inferred: providerDerivedFromModels ? true : parsed.inferred,\n confidence: providerDerivedFromModels ? \"medium\" : parsed.confidence,\n ok: source.ok !== false || providerDerivedFromModels,\n status: source.status ?? null,\n error: source.error ?? null,\n });\n\n for (const modelRate of source.model_rates ?? []) {\n const normalizedModel = modelRate.model_id?.trim().toLowerCase();\n if (!normalizedModel) continue;\n const entry: ProviderRates = {\n inputPer1M: modelRate.input_per_1m_usd,\n outputPer1M: modelRate.output_per_1m_usd,\n source: source.resolved_url ?? source.pricing_url,\n inferred: modelRate.inferred !== false,\n confidence: modelRate.confidence ?? \"low\",\n ok: source.ok !== false,\n status: source.status ?? null,\n error: source.error ?? null,\n };\n byProviderModel.set(`${key}::${normalizedModel}`, entry);\n // Aggregator-agnostic index. Prefer entries with actual numbers and\n // higher confidence so that, e.g., anthropic's authoritative rate\n // for `claude-opus-4-7` beats a copilot proxy guess for the same id.\n const existing = byModel.get(normalizedModel);\n if (!existing || isBetterRate(entry, existing)) {\n byModel.set(normalizedModel, entry);\n }\n }\n }\n }\n\n const tables: PricingTables = {\n byProvider,\n byProviderModel,\n byModel,\n generatedAt: snapshot?.generated_at ?? null,\n };\n cached = { mtimeMs, tables };\n return tables;\n}\n\nexport function providerRatesFor(tables: PricingTables, provider: string | null): ProviderRates {\n if (!provider) {\n return {\n inputPer1M: null, outputPer1M: null, source: \"unknown\",\n inferred: true, confidence: \"low\", ok: false, status: null,\n error: \"no provider assigned\",\n };\n }\n return tables.byProvider.get(provider.toLowerCase()) ?? {\n inputPer1M: null, outputPer1M: null, source: \"unknown\",\n inferred: true, confidence: \"low\", ok: false, status: null,\n error: \"provider missing in pricing snapshot\",\n };\n}\n\nexport function modelRatesFor(\n tables: PricingTables,\n provider: string | null,\n modelId: string | null,\n): ProviderRates {\n if (!modelId) return providerRatesFor(tables, provider);\n const modelKey = modelId.trim().toLowerCase();\n if (!modelKey) return providerRatesFor(tables, provider);\n\n // 1. Prefer (provider, model_id) when both are known — authoritative.\n if (provider) {\n const providerKey = normalizeProvider(provider);\n if (providerKey) {\n const candidates = modelAliasCandidates(providerKey, modelKey);\n for (const candidate of candidates) {\n const exact = tables.byProviderModel.get(`${providerKey}::${candidate}`);\n if (exact) return exact;\n }\n\n // github-copilot (and similar aggregators) re-expose upstream models\n // without their own pricing entry. Resolve via the inferred upstream\n // vendor before falling back to plain model lookup.\n if (providerKey === \"github-copilot\") {\n const upstream = inferProviderFromModelId(modelKey);\n if (upstream) {\n const upstreamCandidates = modelAliasCandidates(upstream, modelKey);\n for (const candidate of upstreamCandidates) {\n const viaUpstreamModel = tables.byProviderModel.get(`${upstream}::${candidate}`);\n if (viaUpstreamModel) return viaUpstreamModel;\n }\n // Upstream had no per-model rate either — try its provider-level\n // rate before falling through to the model-only index.\n const upstreamProviderRate = tables.byProvider.get(upstream);\n if (upstreamProviderRate && upstreamProviderRate.ok) return upstreamProviderRate;\n }\n }\n }\n }\n\n // 2. Aggregator fallback: lookup by model_id alone. Covers the case where\n // the user-configured provider doesn't publish per-model pricing but the\n // same id is rated by its upstream vendor in the snapshot.\n for (const candidate of modelAliasCandidates(provider ? (normalizeProvider(provider) ?? \"\") : \"\", modelKey)) {\n const viaModel = tables.byModel.get(candidate);\n if (viaModel) return viaModel;\n }\n const directModel = tables.byModel.get(modelKey);\n if (directModel) return directModel;\n\n // 3. Hardcoded known-rates fallback. The live snapshot extractor can\n // silently lose data (anthropic page redesign zeroed model_rates,\n // LLM-extract returning uniform garbage); this table guarantees a\n // sane non-null rate for canonical ids. Rates are stale by design,\n // so confidence=\"medium\". Snapshot wins when present.\n for (const candidate of modelAliasCandidates(provider ? (normalizeProvider(provider) ?? \"\") : \"\", modelKey)) {\n const known = knownRateFor(candidate);\n if (known) return known;\n }\n\n // 4. Provider-level rate (or \"no provider assigned\" error).\n return providerRatesFor(tables, provider);\n}\n\n// Tie-breaker for the byModel index when multiple sources rate the same id.\n// Prefer entries that actually have numbers and the higher confidence band.\nfunction isBetterRate(next: ProviderRates, prev: ProviderRates): boolean {\n const nextHas = next.inputPer1M != null || next.outputPer1M != null;\n const prevHas = prev.inputPer1M != null || prev.outputPer1M != null;\n if (nextHas && !prevHas) return true;\n if (!nextHas && prevHas) return false;\n const rank = { high: 2, medium: 1, low: 0 } as const;\n return rank[next.confidence] > rank[prev.confidence];\n}\n\nexport function normalizeProvider(id: string): string | null {\n const lower = id.toLowerCase();\n if (lower.includes(\"github\") || lower.includes(\"copilot\")) return \"github-copilot\";\n if (lower.includes(\"google\") || lower.includes(\"gemini\")) return \"google\";\n if (lower.includes(\"openai\")) return \"openai\";\n if (lower.includes(\"anthropic\")) return \"anthropic\";\n if (lower.includes(\"cohere\")) return \"cohere\";\n if (lower.includes(\"deepseek\")) return \"deepseek\";\n return lower || null;\n}\n\nfunction modelAliasCandidates(provider: string, modelId: string): string[] {\n const out = new Set<string>();\n const id = modelId.trim().toLowerCase();\n if (!id) return [];\n out.add(id);\n // Aggregators (OpenRouter, LiteLLM, etc.) namespace upstream models as\n // `vendor/model` or `aggregator/vendor/model`. The snapshot only stores\n // the bare model id, so add the post-`/` suffix as a fallback candidate.\n const slash = id.lastIndexOf(\"/\");\n if (slash >= 0 && slash < id.length - 1) out.add(id.slice(slash + 1));\n if (provider === \"deepseek\") {\n if (/reasoner/.test(id) || /r1/.test(id)) out.add(\"deepseek-reasoner\");\n if (/chat/.test(id) || /v[0-9]/.test(id) || /coder/.test(id)) out.add(\"deepseek-chat\");\n }\n return [...out];\n}\n\nfunction inferProviderFromModelId(modelId: string): string | null {\n const raw = modelId.trim().toLowerCase();\n if (!raw) return null;\n const slash = raw.lastIndexOf(\"/\");\n const id = slash >= 0 && slash < raw.length - 1 ? raw.slice(slash + 1) : raw;\n if (id.startsWith(\"gpt-\") || /^o[1-4](?:-|$)/.test(id)) return \"openai\";\n if (id.startsWith(\"claude-\")) return \"anthropic\";\n if (id.startsWith(\"gemini-\")) return \"google\";\n if (id.startsWith(\"deepseek-\")) return \"deepseek\";\n if (id.startsWith(\"command-\") || id.startsWith(\"embed-\")) return \"cohere\";\n return null;\n}\n\nfunction inferRatesFromSignals(signals: string[]): {\n inputPer1M: number | null;\n outputPer1M: number | null;\n inferred: boolean;\n confidence: \"high\" | \"medium\" | \"low\";\n} {\n const tokenRates = signals\n .map((s) => {\n const m = /\\$\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\/?\\s*(?:1M\\s*tokens|M\\s*Tok|MTok)/i.exec(s);\n if (!m) return null;\n return Number(m[1]);\n })\n .filter((v): v is number => typeof v === \"number\" && Number.isFinite(v) && v > 0)\n .sort((a, b) => a - b);\n if (tokenRates.length === 0) {\n return { inputPer1M: null, outputPer1M: null, inferred: true, confidence: \"low\" };\n }\n return {\n inputPer1M: tokenRates[0],\n outputPer1M: tokenRates[tokenRates.length - 1],\n inferred: true,\n confidence: tokenRates.length >= 2 ? \"medium\" : \"low\",\n };\n}\n\n// Anthropic prompt-cache multipliers, applied against the standard input\n// rate. Cache writes are billed at 1.25× input (\"cache create\"); cache\n// reads are billed at 0.1× input (\"cache hit\"). Source:\n// https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#pricing\n// We apply the same multipliers to other providers that publish a\n// cache-token breakdown — OpenAI's prompt caching, for example, also\n// quotes a 0.5× read multiplier, but its API surfaces only `cached_tokens`\n// (no separate write count) and a future PR can split that out. For now\n// any provider that emits both fields will be priced as above.\nexport const CACHE_CREATION_INPUT_RATE_MULTIPLIER = 1.25;\nexport const CACHE_READ_INPUT_RATE_MULTIPLIER = 0.1;\n\nexport interface CacheTokenBreakdown {\n cache_creation_input_tokens?: number | null;\n cache_read_input_tokens?: number | null;\n}\n\nexport function estimateCostUsd(\n inputTokens: number,\n outputTokens: number,\n rates: Pick<ProviderRates, \"inputPer1M\" | \"outputPer1M\">,\n cache?: CacheTokenBreakdown | null,\n): number {\n const inputRate = rates.inputPer1M;\n const outputRate = rates.outputPer1M;\n if (inputRate == null && outputRate == null) return 0;\n const inCost = inputRate == null ? 0 : (inputTokens / 1_000_000) * inputRate;\n const outCost = outputRate == null ? 0 : (outputTokens / 1_000_000) * outputRate;\n let cacheCost = 0;\n if (cache && inputRate != null) {\n const create = cache.cache_creation_input_tokens ?? 0;\n const read = cache.cache_read_input_tokens ?? 0;\n if (create > 0) cacheCost += (create / 1_000_000) * inputRate * CACHE_CREATION_INPUT_RATE_MULTIPLIER;\n if (read > 0) cacheCost += (read / 1_000_000) * inputRate * CACHE_READ_INPUT_RATE_MULTIPLIER;\n }\n return inCost + outCost + cacheCost;\n}\n","// Anti-hallucination detector — judges whether an agent turn STALLED,\n// meaning the assistant narrated future work but didn't invoke a\n// write-class tool to actually do the thing.\n//\n// Two detection methods, picked by mode (one or the other, never both):\n// \"off\" — no detection.\n// \"regex\" — fast pattern match in lib/agents/run-thread.ts (default).\n// \"model\" — LLM classifier via this module. Requires a saved model\n// config name; falls back to \"regex\" if missing.\n//\n// Per-agent (lib/stores/agent-configs.ts):\n// anti_hallucination_mode + anti_hallucination_model_config\n// NULL on either column → inherit the env defaults below.\n//\n// Global (lib/env/schema.ts):\n// JARELA_HALLUCINATION_DETECTOR_MODE = off | regex | model (default: regex)\n// JARELA_HALLUCINATION_DETECTOR_MODEL = saved model config name\n//\n// Any invocation error / parse failure / abort returns null so the call\n// site can fall back; the classifier never blocks the turn.\n\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport { isWriteLikeToolName } from \"@/lib/agents/run-thread\";\nimport { getConfig } from \"@/lib/env/config\";\nimport type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\n\nexport type DetectorMode = \"off\" | \"regex\" | \"model\";\n\nexport interface ResolvedDetector {\n /** Effective mode after merging the agent override over the env default. */\n mode: DetectorMode;\n /** Effective model config name (only meaningful when mode === \"model\"). */\n modelConfigName: string;\n}\n\n/**\n * Merge the per-agent override (`anti_hallucination_mode` + `_model_config`)\n * over the env default (JARELA_HALLUCINATION_DETECTOR_MODE +\n * JARELA_HALLUCINATION_DETECTOR_MODEL).\n *\n * If the resolved mode is \"model\" but no model config name is available,\n * silently downgrade to \"regex\" — this is the cheaper safe fallback. We\n * also downgrade when the named config doesn't exist (typo, deleted\n * config); the call site can log if it cares.\n */\nexport function resolveDetector(agent: Pick<AgentConfigRow, \"anti_hallucination_mode\" | \"anti_hallucination_model_config\"> | null | undefined): ResolvedDetector {\n const env = getConfig();\n const rawMode = (agent?.anti_hallucination_mode as DetectorMode | null | undefined)\n ?? env.hallucinationDetectorMode;\n const modelName = (agent?.anti_hallucination_model_config?.trim() || env.hallucinationDetectorModel.trim());\n if (rawMode === \"model\" && (!modelName || !getModelConfig(modelName))) {\n // Asked for model classifier but it's not actually configured — fall\n // back to regex so the agent still has SOME guard.\n return { mode: \"regex\", modelConfigName: \"\" };\n }\n if (rawMode === \"off\" || rawMode === \"regex\" || rawMode === \"model\") {\n return { mode: rawMode, modelConfigName: modelName };\n }\n return { mode: \"regex\", modelConfigName: \"\" };\n}\n\nexport interface StallVerdict {\n stalled: boolean;\n reason: string;\n}\n\n// Keep the prompt tight so a fast model returns in ~1s. We feed only\n// the trailing prose (last 1500 chars) — the stall signal is at the end\n// of the turn, not in the middle, and longer payloads inflate cost\n// without helping accuracy.\nconst PROMPT_TAIL_BUDGET = 1500;\n\nconst SYSTEM_PROMPT = `You judge whether an agent turn STALLED.\n\nA stalled turn is one where the assistant narrated future work — promised to write/edit/save/update something, said \"I'll do X now\" or \"I'm doing X now\" — but did not actually invoke a write-class tool to make the change. Read-only tools (file_read, web_search, list_dir) DO NOT count as fulfilling a write promise.\n\nYou will receive: the list of tools the agent called this turn, whether any were write-class, and the trailing prose of the assistant text.\n\nReply with EXACTLY one JSON object on one line, no surrounding prose, no markdown fence:\n\n{\"stalled\": true|false, \"reason\": \"<one short sentence, max 120 chars>\"}\n\nIf the agent called a write-class tool and the prose is consistent with that, stalled=false.\nIf the prose promises a write but no write-class tool was called, stalled=true.\nIf the agent's text is a normal completion message (\"Here are the results\", \"Done\"), stalled=false even if no write tool was called.`;\n\nexport async function classifyStall(\n assistantText: string,\n toolNames: readonly string[],\n modelConfigName: string,\n signal?: AbortSignal,\n): Promise<StallVerdict | null> {\n const cfgName = modelConfigName.trim();\n if (!cfgName) return null;\n\n const cfg = getModelConfig(cfgName);\n if (!cfg) return null;\n const params = getModelParams(cfg);\n\n let provider;\n try {\n provider = getProvider(cfg.provider);\n } catch {\n return null;\n }\n if (!provider.invoke) return null;\n\n const usedWriteTool = toolNames.some(isWriteLikeToolName);\n const tail = assistantText.slice(-PROMPT_TAIL_BUDGET);\n const userMsg = `Tools called this turn: ${JSON.stringify(toolNames)}\nAny write-class tools called? ${usedWriteTool ? \"yes\" : \"no\"}\n\nAssistant text (trailing ${tail.length} chars):\n${tail}`;\n\n if (signal?.aborted) return null;\n\n let result;\n try {\n result = await provider.invoke(\n cfg.model_id,\n [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMsg },\n ],\n params,\n [],\n );\n } catch {\n return null;\n }\n\n const text = result?.text ?? \"\";\n return parseVerdict(text);\n}\n\n// Strict JSON parse — extract the first {...} that looks like a verdict\n// and validate fields. Returns null on any parse failure so the caller\n// can treat \"no opinion\" as \"fall back to regex\".\nexport function parseVerdict(text: string): StallVerdict | null {\n if (!text) return null;\n // Strip code fences a chatty model might wrap the JSON in.\n const stripped = text.replace(/```(?:json)?\\s*/gi, \"\").replace(/```/g, \"\").trim();\n // Find the first balanced-looking object literal.\n const m = /\\{[^{}]*\"stalled\"[^{}]*\\}/.exec(stripped);\n if (!m) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(m[0]);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n const obj = parsed as Record<string, unknown>;\n if (typeof obj.stalled !== \"boolean\") return null;\n const reason = typeof obj.reason === \"string\" ? obj.reason.slice(0, 200) : \"\";\n return { stalled: obj.stalled, reason };\n}\n","// Citation checker — second-pass LLM that decides whether the assistant\n// turn's factual claims are backed by sources the agent actually visited\n// in this thread.\n//\n// Pipeline:\n// 1. extractVisitedSources(threadId) walks every persisted tool event +\n// the just-produced events to build the {url|path} provenance set.\n// 2. buildSourceManifest / buildCombinedManifest number the most-recent N\n// sources (tool-visited files/URLs, memory items, prior assistant\n// turns) so the model can cite by writing an inline `[N]` marker\n// instead of typing the full path/URL in every claim.\n// 3. extractCitedMarkers(text) pulls every `[N]` marker out of\n// the assistant text so the checker can skip turns that carry no\n// citations at all.\n// 4. classifyCitations(text, manifest, modelConfigName) asks the checker\n// LLM to emit a strict-JSON verdict listing each factual claim, the\n// marker the agent attached (if any), and whether that marker is in\n// the manifest.\n//\n// Failure modes (timeout, parse error, missing model config, provider\n// throw) all return null. The caller writes metadata only on a non-null\n// verdict and the chat UI degrades to \"no badge\" when metadata is absent.\n//\n// Design choices:\n// - Provenance scope is the whole thread, not a rolling window. Matches\n// how focused chat threads work in practice and avoids false flags\n// when the agent legitimately re-cites a file it read five turns ago.\n// - The manifest is built BEFORE the LLM turn (in run-thread) and shown\n// to the model in the system prompt. The model only has to write a\n// small marker `[3]` instead of a full URL — long-form LLM output is\n// much more reliable at emitting short stable tokens than at typing\n// exact paths in the middle of prose.\n// - Reuses anti_hallucination_model_config as the checker model so the\n// user only configures one cheap classifier model per agent.\n\nimport type { PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { getMessages } from \"@/lib/stores/threads\";\nimport { listMemory } from \"@/lib/stores/memory\";\nimport { isSensitiveMemoryNamespace } from \"@/lib/crypto/sensitive\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport { getConfig } from \"@/lib/env/config\";\nimport os from \"node:os\";\n\nexport interface CitationClaim {\n text: string;\n marker: number | null;\n link: string | null;\n verified: boolean;\n reason: string;\n /** Load-bearing-ness as judged by the checker. The UI surfaces top-N\n * claims at `informational` strictness and uses this to colour the\n * reference panel. */\n impact: \"high\" | \"med\" | \"low\";\n}\n\nexport interface SourceManifestEntry {\n n: number;\n label: string;\n href: string;\n}\n\nexport interface CitationVerdict {\n checker_model: string;\n claims: CitationClaim[];\n unverified_links: string[];\n}\n\n// Tools whose calls/results contribute URLs or file paths to the visited\n// set. Anything not on this list is ignored — e.g. memory_read returns\n// stored notes, not external sources, so citing a memory hit as a \"source\"\n// shouldn't count as provenance.\n//\n// Split by phase: for listing/search tools (file_list, file_grep,\n// file_glob, file_stat) only the CALL args count — the agent visited\n// the directory, not every child path the listing returned. Without\n// this split, a single `file_list ~/Downloads` floods the manifest with\n// 50+ \"sources\" the agent never opened.\nconst SOURCE_PRODUCING_TOOLS_CALL = new Set([\n \"file_read\", \"file_edit\", \"file_multi_edit\", \"file_write\",\n \"file_list\", \"file_grep\", \"file_glob\", \"file_stat\",\n \"web_search\", \"fetch_webpage\", \"web_fetch\",\n]);\nconst SOURCE_PRODUCING_TOOLS_RESULT = new Set([\n \"file_read\", \"file_edit\", \"file_multi_edit\", \"file_write\",\n \"web_search\", \"fetch_webpage\", \"web_fetch\",\n]);\n\n// Strip query/fragment for URLs and normalize backslashes for paths so a\n// citation that drops `?utm=...` or uses forward slashes on Windows still\n// matches the visited entry. Also fold `~/...` to the resolved home dir\n// so `~/Downloads/x` and `C:\\Users\\andre\\Downloads\\x` de-dupe.\nexport function normalizeSource(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) return \"\";\n if (/^https?:\\/\\//i.test(trimmed)) {\n try {\n const u = new URL(trimmed);\n return `${u.protocol}//${u.host}${u.pathname}`.replace(/\\/+$/, \"\").toLowerCase();\n } catch {\n return trimmed.toLowerCase();\n }\n }\n let normalized = trimmed.replace(/\\\\/g, \"/\");\n if (normalized.startsWith(\"~/\") || normalized === \"~\") {\n try {\n const home = os.homedir().replace(/\\\\/g, \"/\");\n normalized = normalized === \"~\" ? home : home + normalized.slice(1);\n } catch { /* fall through */ }\n }\n return normalized.replace(/\\/+$/, \"\").toLowerCase();\n}\n\n/**\n * Extract every URL or path referenced by the given tool events. Walks\n * both call payloads (arguments the agent passed, e.g. file_read.path)\n * and result payloads (URLs the search engine returned). Returns a Set\n * of normalized source strings.\n */\nexport function extractSourcesFromEvents(events: readonly PersistedToolEvent[]): Set<string> {\n const out = new Set<string>();\n for (const ev of events) {\n const allow = ev.phase === \"call\"\n ? SOURCE_PRODUCING_TOOLS_CALL\n : SOURCE_PRODUCING_TOOLS_RESULT;\n if (!allow.has(ev.name)) continue;\n collectStringsFromPayload(ev.payload, out);\n }\n return out;\n}\n\n/**\n * Build the per-thread visited-source set: every file path / URL the\n * agent has touched via tool calls across the full thread history,\n * unioned with the just-produced events.\n */\nexport function extractVisitedSources(\n thread_id: string,\n freshEvents: readonly PersistedToolEvent[],\n): Set<string> {\n const out = extractSourcesFromEvents(freshEvents);\n for (const m of getMessages(thread_id)) {\n if (!m.tool_events) continue;\n let parsed: unknown;\n try { parsed = JSON.parse(m.tool_events); } catch { continue; }\n if (!Array.isArray(parsed)) continue;\n const events = parsed.filter((e): e is PersistedToolEvent =>\n !!e && typeof e === \"object\" && typeof (e as { name?: unknown }).name === \"string\",\n );\n for (const s of extractSourcesFromEvents(events)) out.add(s);\n }\n return out;\n}\n\n/**\n * Pull every markdown link target out of the assistant text. Kept for\n * back-compat and as a useful primitive; the new marker-based flow uses\n * extractCitedMarkers instead.\n */\nexport function extractCitedLinks(text: string): string[] {\n if (!text) return [];\n const out = new Set<string>();\n const re = /\\[[^\\]]*\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const href = m[1].trim();\n if (href) out.add(href);\n }\n return Array.from(out);\n}\n\n/**\n * Pull every numeric marker (`[1]`, `[12]`) out of the assistant text.\n * Skips reference-link tails like `[label][1]` via the lookbehind so the\n * checker doesn't misread accidental markdown reference-link syntax as a\n * citation marker. Returns unique numbers in first-seen order.\n */\nexport function extractCitedMarkers(text: string): number[] {\n if (!text) return [];\n const out = new Set<number>();\n const re = /(?<!\\])\\[(\\d+)\\]/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const n = parseInt(m[1], 10);\n if (Number.isFinite(n) && n > 0) out.add(n);\n }\n return Array.from(out);\n}\n\n/**\n * Build the numbered source manifest the agent will see in its system\n * prompt. Takes the visited-sources set (insertion-ordered ≈ chronological\n * because both Set and the events that filled it preserve order) and\n * returns the most-recent `max` entries numbered 1..N.\n *\n * Most-recent rather than first-N because old sources are less likely to\n * still be relevant on long threads; a tight cap keeps the prompt cheap.\n */\nexport function buildSourceManifest(\n visited: ReadonlySet<string>,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0 || visited.size === 0) return [];\n const all = Array.from(visited);\n const tail = all.slice(-max);\n return tail.map((href, i) => ({\n n: i + 1,\n label: labelForSource(href),\n href,\n }));\n}\n\nfunction labelForSource(href: string): string {\n if (href.startsWith(\"http://\") || href.startsWith(\"https://\")) {\n try {\n const u = new URL(href);\n const path = u.pathname.replace(/\\/$/, \"\");\n return `${u.hostname}${path}`;\n } catch { return href; }\n }\n return href;\n}\n\n/** Public re-export so callers building a manifest outside this module\n * (e.g. run-thread's post-turn refresh) use the same labeling rules. */\nexport const labelForCitedSource = labelForSource;\n\n/**\n * Pull prior assistant turns in this thread into citable manifest entries.\n * Used at all strictness levels (when citations are enabled). Each entry's\n * `href` is a `#msg-<id>` anchor the UI can scroll to; the label is a short\n * timestamp (\"12m ago\") so the agent has something readable to reference.\n *\n * Returns the most-recent `max` assistant turns, oldest-first so a later\n * `buildSourceManifest` call's \"tail = recent\" semantics keeps stable\n * numbering even as new turns land.\n */\nexport function extractPriorDialogSources(\n thread_id: string,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0) return [];\n const all = getMessages(thread_id);\n const assistant = all.filter((m) => m.role === \"assistant\" && (m.content ?? \"\").trim().length > 0);\n const tail = assistant.slice(-max);\n const nowMs = Date.now();\n return tail.map((m, i) => {\n const ts = Date.parse(m.created_at);\n const ageMs = Number.isFinite(ts) ? Math.max(0, nowMs - ts) : 0;\n return {\n n: i + 1,\n label: `Earlier in thread (${formatAge(ageMs)})`,\n href: `#msg-${m.msg_id}`,\n };\n });\n}\n\nfunction formatAge(ms: number): string {\n if (ms < 60_000) return \"just now\";\n const min = Math.round(ms / 60_000);\n if (min < 60) return `${min}m ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.round(hr / 24);\n return `${day}d ago`;\n}\n\n/**\n * Pull memory items into citable manifest entries. Memory is durable user\n * context (preferences, learned facts, scheduled-task state), so making\n * them citable lets the agent ground answers like \"as you mentioned last\n * week, …\" with a verifiable reference.\n *\n * Scope: most-recently-updated `max` items across all non-sensitive\n * namespaces. Sensitive namespaces are skipped — `listMemory(undefined)`\n * already decrypts them but exposing them in the system prompt and the\n * UI references panel would defeat the at-rest encryption (ADR-0005).\n */\nexport function extractMemorySources(max: number): SourceManifestEntry[] {\n if (max <= 0) return [];\n const items = listMemory(undefined, undefined, max);\n return items\n .filter((m) => !isSensitiveMemoryNamespace(m.namespace))\n .map((m, i) => ({\n n: i + 1,\n label: `Memory: ${m.namespace}/${m.key}`,\n href: `memory://${m.namespace}/${m.key}`,\n }));\n}\n\n/**\n * Pull every `delegate_to_agent` tool result in the thread into citable\n * manifest entries. The parent agent's reply often paraphrases the\n * delegate's answer (\"Postman says today's agenda is …\") — without this\n * bucket those claims have no matching source and the agent has nothing\n * legal to cite, so it just omits the marker entirely.\n *\n * Each entry's label is `{delegate_name} replied ({age})`; the href\n * points to the persisted-event anchor inside the parent message so the\n * UI can scroll to the delegate tool card and the user can expand it.\n */\nexport function extractDelegateSources(\n thread_id: string,\n max: number,\n): SourceManifestEntry[] {\n if (max <= 0) return [];\n type DelegateHit = { agent: string; createdAt: string; msgId: string; eventId: string };\n const hits: DelegateHit[] = [];\n for (const m of getMessages(thread_id)) {\n if (!m.tool_events) continue;\n let parsed: unknown;\n try { parsed = JSON.parse(m.tool_events); } catch { continue; }\n if (!Array.isArray(parsed)) continue;\n for (const ev of parsed) {\n if (!ev || typeof ev !== \"object\") continue;\n const e = ev as { id?: unknown; name?: unknown; phase?: unknown; payload?: unknown };\n if (e.name !== \"delegate_to_agent\" || e.phase !== \"result\") continue;\n let payload: unknown = e.payload;\n if (typeof payload === \"string\") {\n try { payload = JSON.parse(payload); } catch { /* keep raw */ }\n }\n const p = (payload && typeof payload === \"object\") ? payload as Record<string, unknown> : null;\n if (!p || p.ok === false) continue;\n const agent = typeof p.agent_name === \"string\" ? p.agent_name : \"delegate\";\n hits.push({\n agent,\n createdAt: m.created_at,\n msgId: m.msg_id,\n eventId: typeof e.id === \"string\" ? e.id : \"\",\n });\n }\n }\n const tail = hits.slice(-max);\n const nowMs = Date.now();\n return tail.map((h, i) => {\n const ts = Date.parse(h.createdAt);\n const ageMs = Number.isFinite(ts) ? Math.max(0, nowMs - ts) : 0;\n return {\n n: i + 1,\n label: `${h.agent} replied (${formatAge(ageMs)})`,\n href: `#msg-${h.msgId}`,\n };\n });\n}\n\n/**\n * Combine THIS TURN's tool-visited sources + delegate replies + (optional)\n * memory items into one numbered manifest. Caller controls which buckets\n * to include via the per-bucket caps. Numbering is stable within the\n * turn (tools, delegates, memory in that order).\n *\n * Scope is intentionally THIS-TURN-ONLY for tool sources. A reply about\n * iCloud cleanup shouldn't surface the agent's 8-hour-old web_search\n * results for \"today's news\" — those are visible in their own reply's\n * panel and dragging them across turns drowns the panel in noise the\n * user has to mentally filter every time.\n *\n * Cross-turn signal (prior dialog, memory items) is OPT-IN via the\n * caller's cap setting. Default 0 = don't surface; the agent can still\n * cite earlier turns by writing a markdown link with the `#msg-…` anchor\n * if it genuinely needs to.\n */\nexport function buildCombinedManifest(\n freshEvents: readonly PersistedToolEvent[],\n thread_id: string,\n caps: { tools: number; memory?: number; delegates?: number },\n): SourceManifestEntry[] {\n const toolsSet = extractSourcesFromEvents(freshEvents);\n const tools = buildSourceManifest(toolsSet, caps.tools);\n // Delegate replies from THIS turn only: walk freshEvents for delegate\n // tool-results and emit one entry per successful delegation. Older\n // delegations belong to their own turn's manifest.\n const delegates: SourceManifestEntry[] = [];\n if ((caps.delegates ?? 0) > 0) {\n for (const ev of freshEvents) {\n if (ev.name !== \"delegate_to_agent\" || ev.phase !== \"result\") continue;\n let payload: unknown = ev.payload;\n if (typeof payload === \"string\") {\n try { payload = JSON.parse(payload); } catch { /* keep raw */ }\n }\n const p = (payload && typeof payload === \"object\") ? payload as Record<string, unknown> : null;\n if (!p || p.ok === false) continue;\n const agent = typeof p.agent_name === \"string\" ? p.agent_name : \"delegate\";\n const childThread = typeof p.thread_id === \"string\" ? p.thread_id : \"\";\n delegates.push({\n n: 0,\n label: `${agent} replied`,\n href: childThread ? `?tab=threads&thread=${childThread}` : \"#\",\n });\n if (delegates.length >= (caps.delegates ?? 0)) break;\n }\n }\n const memory = (caps.memory ?? 0) > 0 ? extractMemorySources(caps.memory!) : [];\n void thread_id; // currently unused; reserved for future per-thread filters\n const merged = [...tools, ...delegates, ...memory];\n return merged.map((e, i) => ({ ...e, n: i + 1 }));\n}\n\n/**\n * Agent-declared references: an optional trailing fenced block\n * ```jarela-references` containing a JSON array of `{label, href}`\n * objects. The block is stripped from the persisted body, and each entry\n * is folded into the source manifest (deduped against tool-derived\n * entries by normalized href).\n *\n * Why: most modern LLMs handle structured side-channels (tool calls,\n * fenced JSON) more reliably than they handle \"remember to write [3]\n * after each claim\". Letting the agent declare its sources as a small\n * machine-readable list at the end of its reply gives us a high-signal\n * fallback when the agent didn't manage to put every link inline.\n *\n * Forgiving on malformed JSON / missing fields — the agent is allowed\n * to skip the block entirely, and a bad block is silently dropped (the\n * body still renders, just without the declared refs).\n */\nconst DECLARED_REFS_FENCE_RE = /\\n*```jarela-references\\s*\\n([\\s\\S]*?)\\n```[\\s\\n]*$/;\n\nexport interface DeclaredReference {\n label: string;\n href: string;\n}\n\nexport function extractDeclaredReferences(\n text: string,\n): { body: string; refs: DeclaredReference[] } {\n const m = DECLARED_REFS_FENCE_RE.exec(text);\n if (!m) return { body: text, refs: [] };\n let parsed: unknown;\n try {\n parsed = JSON.parse(m[1]);\n } catch {\n // Malformed JSON: leave the body untouched so the user at least sees\n // what the agent wrote, rather than silently dropping content.\n return { body: text, refs: [] };\n }\n if (!Array.isArray(parsed)) return { body: text, refs: [] };\n const refs: DeclaredReference[] = [];\n for (const item of parsed) {\n if (!item || typeof item !== \"object\") continue;\n const obj = item as Record<string, unknown>;\n const label = typeof obj.label === \"string\" ? obj.label.trim() : \"\";\n const href = typeof obj.href === \"string\" ? obj.href.trim() : \"\";\n if (label && href) refs.push({ label, href });\n }\n const body = text.slice(0, m.index).trimEnd();\n return { body, refs };\n}\n\n/**\n * Strip an in-progress `jarela-references` fence during streaming so the\n * user never sees raw JSON flash on screen between the opening fence and\n * the closing one. If the closing fence has arrived, defer to the full\n * parser via {@link extractDeclaredReferences}; otherwise cut everything\n * from the opening fence onward.\n */\nexport function stripStreamingDeclaredReferences(text: string): string {\n if (/```jarela-references[\\s\\S]*?\\n```/.test(text)) {\n return extractDeclaredReferences(text).body;\n }\n const idx = text.indexOf(\"```jarela-references\");\n if (idx < 0) return text;\n return text.slice(0, idx).trimEnd();\n}\n\n/**\n * Merge agent-declared refs into an existing manifest. Dedup is by\n * normalized href (same comparison the tool extractor uses), so an agent\n * that declares a URL the manifest already has gets de-duped silently\n * instead of double-listed. New refs are appended after existing ones\n * and renumbered.\n */\nexport function mergeDeclaredReferences(\n manifest: readonly SourceManifestEntry[],\n declared: readonly DeclaredReference[],\n): SourceManifestEntry[] {\n if (declared.length === 0) return [...manifest];\n const seen = new Set(manifest.map((e) => normalizeSource(e.href)));\n const merged = [...manifest];\n for (const d of declared) {\n const key = normalizeSource(d.href);\n if (key && seen.has(key)) continue;\n seen.add(key);\n merged.push({ n: 0, label: d.label, href: d.href });\n }\n return merged.map((e, i) => ({ ...e, n: i + 1 }));\n}\n\nconst SYSTEM_PROMPT = `You audit an assistant turn and list its FACTUAL CLAIMS, sorted by impact (most load-bearing first).\n\nYou will receive:\n- A numbered list of SOURCES the agent had available in this thread. Sources may be any of: a tool-visited file/URL, a memory item, or an earlier assistant turn in this thread.\n- The assistant text (or its trailing portion).\n\nThe agent cites a source by writing an inline marker like [3] right after the claim, where the number matches a row in the SOURCES list. A marker MAY appear mid-sentence or at the end of a sentence.\n\nFor each FACTUAL claim — a quoted number, file contents, API behavior, named fact (date, version, person), paraphrased finding, or a recap of a prior turn — emit one entry. IGNORE pure opinion, plans (\"I'll do X\"), conversational filler, and trivial syntactic glue.\n\nRank impact:\n- \"high\": load-bearing. The rest of the answer depends on this being right.\n- \"med\": meaningful but not load-bearing. Wrong would be misleading but not fatal.\n- \"low\": incidental. Wrong would be a minor blemish.\n\nSort by impact (high → med → low) within the array. Cap at 15 claims total; if more would qualify, keep the highest-impact 15 and drop the rest.\n\nFor each claim, report:\n- \"text\": short paraphrase of the claim (max 120 chars).\n- \"marker\": the integer the agent attached (e.g. 3 for [3]), or null if no marker.\n- \"impact\": one of \"high\" | \"med\" | \"low\".\n- \"verified\": true if marker is non-null AND that number is in the SOURCES list, else false.\n- \"reason\": one short sentence (max 120 chars) explaining the verdict.\n\nReply with EXACTLY one JSON object on one line, no surrounding prose, no markdown fence:\n\n{\"claims\":[{\"text\":\"...\",\"marker\":<integer-or-null>,\"impact\":\"high|med|low\",\"verified\":true|false,\"reason\":\"...\"}]}\n\nIf the turn has no factual claims (pure chitchat or plans), return {\"claims\":[]}.`;\n\nexport async function classifyCitations(\n assistantText: string,\n manifest: ReadonlyArray<SourceManifestEntry>,\n modelConfigName: string,\n signal?: AbortSignal,\n): Promise<CitationVerdict | null> {\n const cfgName = modelConfigName.trim();\n if (!cfgName) return null;\n const cfg = getModelConfig(cfgName);\n if (!cfg) return null;\n const params = getModelParams(cfg);\n\n let provider;\n try { provider = getProvider(cfg.provider); } catch { return null; }\n if (!provider.invoke) return null;\n\n // Tail the text so a 60KB turn doesn't blow the checker budget. Citations\n // are usually inline so any sub-window catches representative claims.\n // JARELA_CITATION_CHECKER_TAIL_CHARS=0 disables truncation entirely (use\n // when claims often appear early in long answers — costs more tokens).\n const tailBudget = getConfig().citationCheckerTailChars;\n const sent = tailBudget > 0 ? assistantText.slice(-tailBudget) : assistantText;\n const portionLabel = tailBudget > 0 && assistantText.length > tailBudget\n ? `trailing ${sent.length} chars of ${assistantText.length}`\n : `full ${sent.length} chars`;\n const sourcesList = manifest.map((e) => {\n const trailer = e.label === e.href ? \"\" : ` — ${e.href}`;\n return `[${e.n}] ${e.label}${trailer}`;\n }).join(\"\\n\");\n const userMsg = `Sources (${manifest.length}):\n${sourcesList || \"(none)\"}\n\nAssistant text (${portionLabel}):\n${sent}`;\n\n if (signal?.aborted) return null;\n let result;\n try {\n result = await provider.invoke(\n cfg.model_id,\n [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: userMsg },\n ],\n params,\n [],\n );\n } catch { return null; }\n\n const parsed = parseCitationVerdict(result?.text ?? \"\");\n if (!parsed) return null;\n // Resolve marker → manifest entry ourselves rather than trusting the LLM\n // for the membership decision — the LLM is good at extracting claims but\n // not at exact-integer set membership.\n const byN = new Map(manifest.map((e) => [e.n, e]));\n const claims = parsed.map((c) => {\n const marker = c.marker ?? null;\n const entry = marker !== null ? byN.get(marker) : undefined;\n const link = entry?.href ?? null;\n const verified = entry !== undefined;\n return { ...c, marker, link, verified };\n });\n // Stable sort by impact (high → med → low) so callers can slice the\n // top-N for the informational-strictness UI without re-sorting.\n const impactRank: Record<CitationClaim[\"impact\"], number> = { high: 0, med: 1, low: 2 };\n claims.sort((a, b) => impactRank[a.impact] - impactRank[b.impact]);\n return { checker_model: cfgName, claims, unverified_links: [] };\n}\n\n/**\n * Tolerant strict-JSON parser for the checker output. Returns null on any\n * shape mismatch so the caller can degrade to \"no metadata\". Parses both\n * `marker` (new manifest-based flow) and `link` (legacy free-form flow).\n */\nexport function parseCitationVerdict(text: string): CitationClaim[] | null {\n if (!text) return null;\n const stripped = text.replace(/```(?:json)?\\s*/gi, \"\").replace(/```/g, \"\").trim();\n const m = /\\{[^]*\"claims\"[^]*\\}/.exec(stripped);\n if (!m) return null;\n let parsed: unknown;\n try { parsed = JSON.parse(m[0]); } catch { return null; }\n if (!parsed || typeof parsed !== \"object\") return null;\n const claimsRaw = (parsed as { claims?: unknown }).claims;\n if (!Array.isArray(claimsRaw)) return null;\n const claims: CitationClaim[] = [];\n for (const item of claimsRaw) {\n if (!item || typeof item !== \"object\") continue;\n const r = item as Record<string, unknown>;\n const text = typeof r.text === \"string\" ? r.text.slice(0, 200) : \"\";\n if (!text) continue;\n const markerRaw = r.marker;\n const marker = typeof markerRaw === \"number\" && Number.isFinite(markerRaw) && markerRaw > 0\n ? Math.floor(markerRaw)\n : null;\n const link = typeof r.link === \"string\" && r.link.trim() ? r.link.trim() : null;\n const verified = r.verified === true;\n const reason = typeof r.reason === \"string\" ? r.reason.slice(0, 200) : \"\";\n const impactRaw = typeof r.impact === \"string\" ? r.impact.toLowerCase() : \"\";\n const impact: CitationClaim[\"impact\"] =\n impactRaw === \"high\" ? \"high\" : impactRaw === \"low\" ? \"low\" : \"med\";\n claims.push({ text, marker, link, verified, reason, impact });\n }\n return claims;\n}\n\nfunction collectStringsFromPayload(payload: unknown, out: Set<string>): void {\n if (!payload) return;\n if (typeof payload === \"string\") {\n const n = normalizeSource(payload);\n if (looksLikeSource(n)) out.add(n);\n return;\n }\n if (Array.isArray(payload)) {\n for (const item of payload) collectStringsFromPayload(item, out);\n return;\n }\n if (typeof payload === \"object\") {\n for (const v of Object.values(payload as Record<string, unknown>)) {\n collectStringsFromPayload(v, out);\n }\n }\n}\n\nfunction looksLikeSource(s: string): boolean {\n if (!s) return false;\n // URLs are bounded, single-line, no whitespace, no JSON syntax. Anything\n // longer than 2048 chars (browser-typical URL cap) is almost certainly a\n // tool-result payload dump and never a real source. Same for strings\n // that contain whitespace, control chars, or look like a JSON literal.\n if (s.length > 2048) return false;\n if (/[\\s\"'`<>{}]/.test(s)) return false;\n if (s.startsWith(\"{\") || s.startsWith(\"[\")) return false;\n // Asset / binary URLs: images, fonts, stylesheets, scripts, video,\n // audio, archives, favicons. fetch_webpage normalisation surfaces every\n // <img src> on the page; without this filter the references panel\n // drowns under CDN logos and profile thumbnails. Real content sources\n // are HTML or text, not assets.\n const assetExt = /\\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|tiff?|woff2?|ttf|otf|eot|css|js|mjs|map|mp4|webm|mov|m4v|avi|mkv|mp3|wav|ogg|m4a|flac|zip|tar|gz|rar|7z|pdf|epub)(?:\\?|#|$)/i;\n if (assetExt.test(s)) return false;\n // Image-CDN URLs without file extensions: services like dims.apnews.com,\n // images.unsplash.com, cloudinary, imgix, etc. encode transforms into\n // the URL path (`/resize/`, `/crop/`, `/strip/`, `/quality/`, `/fit/`,\n // `/format/`) and serve the rendered bytes off the trailing parameter.\n // No file extension to match — pattern-detect the path segments instead.\n if (/\\/(?:resize|crop|strip|quality|fit|format|trim|rotate|scale|smart|w_\\d+|h_\\d+|c_fill|q_\\d+)\\//i.test(s)) return false;\n if (s.startsWith(\"http://\") || s.startsWith(\"https://\")) return true;\n // Workspace-relative paths or URI-style refs picked up from file_*\n // tool args/results. Require a real path separator AND that the basename\n // has a recognisable extension. Drop bare directories — `~/Downloads`\n // isn't a citable source, only the files inside it are. This also\n // rejects sentence fragments like \"Earlier in thread (7h ago)\".\n if (s.startsWith(\"memory://\")) return true;\n const hasFileExt = /\\.[a-z0-9]{1,8}$/i.test(s);\n if (s.startsWith(\"file://\")) return hasFileExt;\n if (/^[a-z]:[\\\\/]/i.test(s)) return hasFileExt; // C:/ or C:\\\n if (s.startsWith(\"/\") || s.startsWith(\"./\") || s.startsWith(\"../\") || s.startsWith(\"~/\")) {\n return hasFileExt;\n }\n // Plain relative path: must contain `/` AND have a file extension.\n return /\\//.test(s) && hasFileExt;\n}\n","import { streamWithConfig } from \"@/lib/agents/llm\";\nimport { getConfig } from \"@/lib/env/config\";\nimport type { StreamChunk, StreamOptions } from \"@/lib/agents/base\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport { addMessage, getThread, setMessageMetadata, setThreadContextPin, touchThread, type PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { recordToolUsage } from \"@/lib/stores/tool-stats\";\nimport { getAgentConfig, getAgentTierProportions, getAgentTools, parseCitationStrictness, parseDelegateTargets } from \"@/lib/stores/agent-configs\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { recall, type RecalledMemory } from \"@/lib/embeddings\";\nimport { validateAssistantOutput } from \"@/lib/agents/output-validator\";\nimport { getDefaultModelConfig, getModelConfig, getModelParams } from \"@/lib/stores/model-config\";\nimport {\n buildHistoryWindow,\n buildSystemPrompt,\n resolveExperienceMode,\n type ThreadRunRequest,\n} from \"@/lib/agents/prepare\";\nimport { recordMessageUsage } from \"@/lib/stores/message-usage\";\nimport { getPricingTables, modelRatesFor, estimateCostUsd } from \"@/lib/stores/pricing\";\nimport { estimateTokens } from \"@/lib/agents/context-budget\";\nimport { classifyStall, resolveDetector } from \"@/lib/agents/hallucination-classifier\";\nimport {\n buildCombinedManifest,\n classifyCitations,\n extractCitedMarkers,\n extractDeclaredReferences,\n mergeDeclaredReferences,\n type SourceManifestEntry,\n} from \"@/lib/agents/citation-checker\";\n\nexport type { ThreadRunRequest } from \"@/lib/agents/prepare\";\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\nexport interface PreparedThreadRun {\n stream: AsyncIterable<StreamChunk>;\n thread_id: string;\n // Snapshot of how the per-turn context window was allocated and consumed.\n // Forwarded to `persistAssistantMessage` so message_usage carries the\n // per-tier breakdown the chat UI uses for its diagnostic context bar.\n context_snapshot?: ContextUsageSnapshot;\n // Numbered source manifest shown to the agent for this turn (when\n // `citation_strictness` is not `off`). Forwarded to `persistAssistantMessage`\n // so the EXACT list the agent saw is persisted with the message — the\n // chat UI uses it to resolve inline `[N]` markers to clickable links,\n // and the citation checker uses it to score marker validity. Empty when\n // the flag is off.\n source_manifest?: SourceManifestEntry[];\n}\n\nexport interface ContextUsageSnapshot {\n context_window_tokens: number;\n hot_tokens: number;\n warm_tokens: number;\n facts_tokens: number;\n overhead_tokens: number;\n hot_budget_tokens: number;\n warm_budget_tokens: number;\n facts_budget_tokens: number;\n}\n\n// JARELA_MAX_STALL_RETRIES / JARELA_MAX_TRANSIENT_RETRIES override these.\n// Read fresh per turn so non-restart-required reloads take effect.\nfunction maxStallRetries(): number { return getConfig().maxStallRetries; }\nfunction maxTransientRetries(): number { return getConfig().maxTransientRetries; }\n\n// Hard cap on how deep an A → B → C delegation chain can go via the\n// `delegate_to_agent` built-in tool. Public callers start at depth 0; the\n// delegate tool increments before recursively invoking prepareThreadRun. At\n// depth >= MAX_DELEGATION_DEPTH the tool refuses with `depth_exceeded` so a\n// mis-configured agent network can't runaway.\nexport const MAX_DELEGATION_DEPTH = 2;\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 function snapshotThreadModelConfigName(thread_id: string): string | null {\n const thread = getThread(thread_id);\n if (!thread) return null;\n\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) return null;\n\n return agentCfg.model_config_name ?? getDefaultModelConfig()?.name ?? null;\n}\n\n/**\n * Per-turn entry point. Validates the request, persists the user message,\n * builds the history window + system prompt, kicks off the LLM stream, and\n * wraps the result in `stallRetryStream` so flagged turns can auto-retry.\n *\n * The 7-positional-arg version was refactored into the `ThreadRunRequest`\n * shape in ADR-0039. Internal control fields are `_`-prefixed; public\n * callers leave them undefined.\n */\nexport async function prepareThreadRun(req: ThreadRunRequest): 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(req.thread_id);\n if (!thread) throw new RunThreadError(404, \"Thread not found\", \"thread_not_found\");\n\n const trimmed = req.message.trim();\n if (!trimmed && !req.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 // Persist the user turn (including any attachments) before the LLM stream\n // so reload-mid-stream still shows the prompt. The stall-retry path sets\n // `_skip_persist_message` to keep its synthetic `↻ Auto-retry: …` nudges\n // out of the durable history — otherwise every nudge becomes a permanent\n // user-role row that the LLM mistakes for real user input on every future\n // turn.\n const content: string | ContentPart[] =\n req.attachments?.length ? [{ type: \"text\", text: trimmed }, ...req.attachments] : trimmed;\n const stored = typeof content === \"string\" ? content : JSON.stringify(content);\n if (!req._skip_persist_message) {\n addMessage(req.thread_id, \"user\", stored, undefined, req.user_category ?? null);\n touchThread(req.thread_id, trimmed.slice(0, 80) || undefined);\n }\n\n // Resolve model config + provider params (for both the live stream and\n // the warm-summary recursion inside buildHistoryWindow).\n const modelConfigName = req._pinned_model_config_name\n ?? agentCfg.model_config_name\n ?? getDefaultModelConfig()?.name\n ?? null;\n const modelCfg = modelConfigName ? getModelConfig(modelConfigName) : null;\n const baseProviderParams = getModelParams(modelCfg);\n\n // ADR-0043 — per-agent override of context_tier_proportions. The agent's\n // value, when set, replaces the model's default for THIS run only; the\n // stream LLM call below still uses the unmodified params. Splitting them\n // keeps the override scoped to the budget computation.\n const agentTierProportions = getAgentTierProportions(agentCfg);\n const providerParams = agentTierProportions\n ? { ...baseProviderParams, context_tier_proportions: agentTierProportions }\n : baseProviderParams;\n\n // ADR-0042. Persist the user-chosen boundary before we build the window so\n // the history fetch and the cached-summary lookup both see the same pin.\n // `null` clears the pin; `undefined` leaves whatever's already on the row.\n if (req.hot_since !== undefined) {\n setThreadContextPin(req.thread_id, req.hot_since);\n }\n const effectiveHotSince = req.hot_since !== undefined ? req.hot_since : (thread.hot_since ?? null);\n\n const historyWindow = await buildHistoryWindow(\n req.thread_id,\n agentCfg,\n providerParams,\n trimmed,\n { providerName: modelCfg?.provider, modelId: modelCfg?.model_id },\n effectiveHotSince,\n );\n\n const allowedTools = getAgentTools(agentCfg);\n const delegateRosterLines = buildDelegateRoster(agentCfg, allowedTools);\n\n // Recall is best-effort: cap on RECALL_BUDGET_MS so a cold embeddings\n // round-trip doesn't block the LLM stream from starting.\n const oldestInWindow = historyWindow.history.length > 0\n ? contentText(historyWindow.history[0].content)\n : null;\n const rawRecallCtx = req.context_profile && req.context_profile.include_recall === false\n ? \"\"\n : await raceWithBudget(\n buildRecallContext(req.thread_id, trimmed, oldestInWindow),\n RECALL_BUDGET_MS,\n \"\",\n );\n\n // Apply the per-category context profile (see lib/agents/turn-profile.ts).\n // The toggles fire AFTER buildHistoryWindow so the budget snapshot still\n // shows what we *would have* spent on hot/warm — useful when debugging\n // why an extension turn answered with the field's own context only.\n const profile = req.context_profile;\n // include_hot=false strips PRIOR thread history but must keep the current\n // turn's user message, otherwise the LLM is called with only a system\n // prompt (e.g. Gemini rejects with \"contents is not specified\").\n const effectiveHistory = profile && profile.include_hot === false\n ? [{ role: \"user\" as const, content }]\n : historyWindow.history;\n const effectiveWarmSummary = profile && profile.include_warm === false\n ? \"\"\n : historyWindow.warmSummaryCtx;\n const effectiveFacts = profile && profile.include_facts === false\n ? \"\"\n : historyWindow.factsCtx;\n const recallCtx = rawRecallCtx;\n\n // Numbered source manifest, shown to the agent for `[N]` markers and\n // persisted on the assistant row so the chat UI can resolve markers →\n // clickable links/anchors. Built from every source the agent has touched\n // in this thread (tool calls), plus the user's memory items, plus prior\n // assistant turns — see ADR-0044. Empty (and the prompt block becomes a\n // \"no sources yet\" note) when strictness is `off` or the thread is fresh.\n // Pre-turn manifest: empty in practice. The agent hasn't called any\n // tools yet on this turn, so there are no `[N]` numbers it could\n // attach. Citations for THIS turn happen in two ways:\n // 1. Mid-prose markdown links `[label](https://…)` for sources the\n // agent fetches while drafting (web_search/web_fetch/file_read\n // results it just got back).\n // 2. Numeric `[N]` markers resolved AFTER the turn finishes — the\n // post-turn manifest refresh in `persistAssistantMessage` appends\n // this-turn tool + delegate sources and numbers them.\n // Old design dragged in every source from every prior turn in the\n // thread plus 10 memory items plus 10 dialog anchors — produced a\n // 38-entry panel of mostly-irrelevant noise on every reply. Dropped.\n const strictness = parseCitationStrictness(agentCfg.citation_strictness) ?? \"off\";\n const sourceManifest: SourceManifestEntry[] = [];\n void strictness; // strictness is read again at persist-time\n\n const systemPrompt = buildSystemPrompt({\n agentCfg,\n trimmedMessage: trimmed,\n budget: historyWindow.budget,\n recallCtx,\n warmSummaryCtx: effectiveWarmSummary,\n factsCtx: effectiveFacts,\n experienceMode: resolveExperienceMode(req.options),\n delegateRosterLines,\n sourceManifest,\n });\n\n const delegationDepth = req._delegation_depth ?? 0;\n const delegationAncestors = req._delegation_ancestors ?? [];\n const streamOpts: StreamOptions = {\n ...req.options,\n agent_run_config: {\n system_prompt: systemPrompt,\n allowed_tools: allowedTools,\n model_config_name: modelConfigName,\n delegation: delegationDepth > 0 || delegationAncestors.length > 0\n ? { depth: delegationDepth, ancestors: delegationAncestors }\n : undefined,\n },\n };\n\n // Stall-retry path: the nudge needs to reach the LLM but isn't (and\n // shouldn't be) in the DB. Append it to the in-memory history just for\n // this LLM call. Use the structured `content` form (not the JSON-\n // stringified fallback) so attachments survive into the LLM call.\n const finalHistory = req._inject_message_into_history\n ? [...effectiveHistory, { role: \"user\" as const, content }]\n : effectiveHistory;\n\n const rawStream = streamWithConfig(req.thread_id, finalHistory, streamOpts, req.signal);\n const retriesLeft = req._stall_retries_left ?? maxStallRetries();\n // Overhead = the assembled system prompt + per-message scaffolding, which\n // is more accurate than the budget's static overhead allowance.\n const overheadTokens = estimateTokens(systemPrompt);\n // One-shot callers (extension fill/rewrite) consume `assistantContent` as\n // raw text. The stall-retry wrapper would otherwise leak the `↻` separator\n // and the pre-retry stalled prose into the user's input field, and the\n // strict-citation audit (which lives inside the same wrapper) would do\n // the same with retry continuations. Bypass it entirely for those callers.\n const stream = req.disable_quality_gates\n ? rawStream\n : stallRetryStream(rawStream, req, allowedTools, retriesLeft);\n return {\n stream,\n thread_id: req.thread_id,\n context_snapshot: {\n context_window_tokens: historyWindow.budget.contextWindowTokens,\n hot_tokens: profile && profile.include_hot === false ? 0 : historyWindow.tierUsage.hot_tokens,\n warm_tokens: profile && profile.include_warm === false ? 0 : historyWindow.tierUsage.warm_tokens,\n facts_tokens: profile && profile.include_facts === false ? 0 : historyWindow.tierUsage.facts_tokens,\n overhead_tokens: overheadTokens,\n hot_budget_tokens: historyWindow.budget.tierBudgets.hot,\n warm_budget_tokens: historyWindow.budget.tierBudgets.warm,\n facts_budget_tokens: historyWindow.budget.tierBudgets.facts,\n },\n source_manifest: sourceManifest.length > 0 ? sourceManifest : undefined,\n };\n}\n\n/**\n * Build the `--- Available delegates ---` block lines for the system prompt\n * when the agent has the `delegate_to_agent` tool allowed and at least one\n * resolvable delegate target. Empty array short-circuits the block.\n */\nfunction buildDelegateRoster(\n agentCfg: { delegate_targets?: string | null },\n allowedTools: readonly string[],\n): string[] {\n const delegateIds = parseDelegateTargets(agentCfg.delegate_targets);\n if (delegateIds.length === 0) return [];\n if (!allowedTools.includes(\"delegate_to_agent\")) return [];\n\n return delegateIds\n .map((id) => {\n const child = getAgentConfig(id);\n if (!child) return null;\n const firstLine = (child.identity || child.instructions || \"\").split(\"\\n\")[0].slice(0, 120);\n return ` - ${child.id} — ${child.name}${firstLine ? `: ${firstLine}` : \"\"}`;\n })\n .filter((s): s is string => Boolean(s));\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 originalReq: ThreadRunRequest,\n allowedTools: readonly string[],\n retriesLeft: number,\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 // Track (name, args) signatures within the turn so we can detect a\n // ReAct loop where the model spins on the same tool call. Counts\n // increment only on tool_call chunks; tool_result echoes are ignored.\n const signatureCounts = new Map<string, number>();\n let loopedToolName: string | null = null;\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 data = chunk.data as { name?: unknown; arguments?: unknown } | undefined;\n const name = typeof data?.name === \"string\" ? data.name : \"\";\n const args = data?.arguments && typeof data.arguments === \"object\"\n ? (data.arguments as Record<string, unknown>)\n : {};\n if (name) {\n toolNames.push(name);\n const sig = toolCallSignature(name, args);\n const count = (signatureCounts.get(sig) ?? 0) + 1;\n signatureCounts.set(sig, count);\n if (count >= TOOL_LOOP_THRESHOLD && loopedToolName === null) {\n loopedToolName = name;\n // Leave a fingerprint so future loop incidents can be traced\n // to a specific provider/model — most often a sign the\n // aggregator's tool-use fidelity is poor (model narrates\n // \"writing now\" without emitting the corresponding tool_use\n // block).\n console.warn(\n `[stall-retry] tool-loop detected: tool=${name} repeats=${count} thread=${originalReq.thread_id}`,\n );\n yield chunk;\n break;\n }\n }\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 trimmedText = textBuf.trim();\n const isStallProse = trimmedText.length > 0 && looksLikeStall(trimmedText);\n // The original stall path: model produced narration but called nothing.\n const zeroToolStall = !sawError && toolNames.length === 0 && isStallProse;\n // The \"promised next-step\" path: model DID call read-only tools, ended\n // the turn with stall prose (\"Writing it now\", \"Saving the file now\"),\n // and never invoked a write-like tool. Real failure from the wild — the\n // read+narrate+stop loop slipped past the zero-tool gate.\n const promisedWriteStall =\n !sawError &&\n !zeroToolStall &&\n isStallProse &&\n toolNames.length > 0 &&\n !toolNames.some(isWriteLikeToolName);\n const regexStalled = zeroToolStall || promisedWriteStall;\n const looped = !sawError && loopedToolName !== null;\n\n // Anti-hallucination detector — picks ONE method per turn (regex or\n // model), based on the resolved per-agent (or global env) settings.\n // The classifier and the regex never run together; the model is more\n // accurate but adds latency + cost, the regex is fast but brittle.\n const agentCfg = getAgentConfig(originalReq.thread_id ? (getThread(originalReq.thread_id)?.agent_id ?? \"\") : \"\");\n const detector = resolveDetector(agentCfg);\n // Strict citation mode forces the stall classifier to model-based:\n // strict turns are higher-stakes, so the more accurate (but more\n // expensive) LLM judge is worth the extra round-trip. Falls back to\n // regex automatically if the agent has no checker model configured.\n const strictness = agentCfg ? parseCitationStrictness(agentCfg.citation_strictness) : null;\n if (strictness === \"strict\" && detector.modelConfigName) {\n detector.mode = \"model\";\n }\n let classifierStalled = false;\n let classifierReason = \"\";\n if (!sawError && !looped && detector.mode === \"model\") {\n const verdict = await classifyStall(textBuf, toolNames, detector.modelConfigName, originalReq.signal)\n .catch(() => null);\n if (verdict) {\n classifierStalled = verdict.stalled;\n classifierReason = verdict.reason;\n } else {\n // Classifier unavailable / errored / aborted — fall back to regex\n // for THIS turn so the agent isn't left ungovernable.\n console.warn(\n `[anti-hallucination] classifier unavailable, falling back to regex for thread ${originalReq.thread_id} (model=${detector.modelConfigName || \"<unset>\"})`,\n );\n }\n }\n\n // Effective stall verdict per the resolved mode:\n // off → no stall detection (whatever the regex thought, ignore)\n // regex → regex verdict\n // model → classifier verdict if we got one, else regex fallback\n const stalled =\n detector.mode === \"off\"\n ? false\n : detector.mode === \"regex\"\n ? regexStalled\n : (classifierStalled || (classifierReason === \"\" && regexStalled)); // \"model\" mode\n\n // Fabrication check (ADR-0037): only run when no other path claimed\n // this turn.\n const fabrication = !sawError && !stalled && !looped\n ? validateAssistantOutput(textBuf, toolNames, allowedTools)\n : ({ ok: true } as const);\n\n // Strict-mode citation audit. Runs ONLY at `citation_strictness === 'strict'`\n // when no earlier gate already claimed the turn — that's when we want to\n // catch hallucinated/uncited high-impact claims and force a correction\n // round. Standard / informational defer to the post-persist fire-and-\n // forget checker (no nudge, just surfacing). The audit is synchronous so\n // it adds one checker round-trip to strict turns; the cost is the price\n // of the stronger guarantee.\n let uncitedHighClaims: ReadonlyArray<{ text: string; reason: string; marker: number | null }> = [];\n if (\n !sawError && !stalled && !looped && fabrication.ok\n && agentCfg\n && parseCitationStrictness(agentCfg.citation_strictness) === \"strict\"\n && retriesLeft > 0\n && textBuf.trim().length > 0\n ) {\n const checkerModel = (agentCfg.anti_hallucination_model_config ?? \"\").trim();\n if (checkerModel) {\n // The audit grades against THIS turn's sources. We don't accumulate\n // tool-result payloads in this scope (only names + signatures for\n // loop detection), so the audit can only see what landed in the\n // text — pass an empty events array and let `classifyCitations`\n // judge purely on the markers/links in the prose. The post-persist\n // checker (which runs against the persisted manifest) catches\n // anything this scope misses.\n const auditManifest = buildCombinedManifest([], originalReq.thread_id, {\n tools: Math.max(0, getConfig().citationManifestMax - 10),\n delegates: 10,\n });\n try {\n const verdict = await classifyCitations(textBuf, auditManifest, checkerModel, originalReq.signal);\n if (verdict) {\n uncitedHighClaims = verdict.claims\n .filter((c) => c.impact === \"high\" && !c.verified)\n .map((c) => ({ text: c.text, reason: c.reason, marker: c.marker }));\n }\n } catch { /* audit failed — fall through, no retry */ }\n }\n }\n const citationFail = uncitedHighClaims.length > 0;\n\n if (!stalled && !looped && fabrication.ok && !citationFail) {\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. Each failure mode\n // gets its own reason-aware nudge.\n const nudge = looped\n ? `↻ Auto-retry: you called \\`${loopedToolName}\\` ${TOOL_LOOP_THRESHOLD}+ times in this turn with the same arguments without making progress. Either invoke a DIFFERENT tool to advance the task (for example, if you intend to write a file, call \\`file_write\\` now), or stop and explain what's blocking. Do NOT call \\`${loopedToolName}\\` again with the same arguments.`\n : promisedWriteStall\n ? `↻ Auto-retry: your reply ended with a 'writing/saving/creating ... now' style statement but you only called read-only tools (${[...new Set(toolNames)].slice(0, 6).join(\", \")}) — no write-like tool was invoked. Don't narrate the next step; CALL the actual write tool now (e.g. file_write, file_edit, memory_write). If you cannot, stop and explain why.`\n : zeroToolStall\n ? \"↻ 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 — just call the tool.\"\n : classifierStalled\n ? `↻ Auto-retry: the anti-hallucination classifier flagged your reply as a stall (${classifierReason || \"promise without a write tool\"}). Don't narrate the next step; either CALL the actual tool that fulfils what you promised, or stop and explain why you can't.`\n : citationFail\n ? `↻ Auto-retry: the citation audit flagged ${uncitedHighClaims.length} high-impact claim${uncitedHighClaims.length === 1 ? \"\" : \"s\"} without a verified source:\\n${uncitedHighClaims.slice(0, 5).map((c, i) => ` ${i + 1}. ${c.text}${c.reason ? ` — ${c.reason}` : \"\"}`).join(\"\\n\")}\\n\\nFix each one in exactly ONE of these three ways:\\n (a) cite an existing source from the manifest by appending the marker \\`[N]\\` to the claim,\\n (b) call a tool now (file_read, web_search, fetch_webpage, memory_read, …) to actually ground the claim before stating it,\\n (c) rephrase plainly — drop the specific number/fact, or say \"I don't have a source for this\" — so the claim is no longer load-bearing.\\n\\nDo NOT just restate the same claim. Do NOT invent a marker number that isn't in the manifest.`\n : `↻ Auto-retry: output validator flagged your reply. ${\"reason\" in fabrication ? fabrication.reason : \"\"} Redo this turn without the false claim — either call the actual tool, or rephrase as a proposal/question.`;\n\n const retry = await prepareThreadRun({\n ...originalReq,\n message: nudge,\n attachments: undefined,\n _stall_retries_left: retriesLeft - 1,\n // The nudge is in-memory only — never write it to `messages`. The\n // assistant's combined (original + ↻ + retry) text gets persisted\n // ONCE at end-of-turn via `persistAssistantMessage`, which is the\n // sole durable record of what happened. Without these flags the\n // nudge becomes a permanent user-role row the LLM mistakes for\n // user input on every future turn.\n _skip_persist_message: true,\n _inject_message_into_history: true,\n });\n for await (const chunk of retry.stream) yield chunk;\n}\n\nexport interface AssistantUsageSnapshot {\n input_tokens: number;\n output_tokens: number;\n // Anthropic prompt-cache breakdown (PR #181). Disjoint from input_tokens:\n // total billable input = input_tokens + cache_creation + cache_read,\n // priced at 1×, 1.25×, and 0.1× the input rate respectively.\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n provider: string;\n model_id: string;\n model_config_name: string | null;\n}\n\n// Footer appended to an assistant message that was cut off by the user\n// (Stop button or steer-while-streaming). Both human readers and the LLM\n// see this on the next turn — the agent treats it as \"the previous reply\n// was abandoned; the user's next message is the new direction\".\nexport const INTERRUPT_MARKER = \"*⏸ Interrupted by user.*\";\n\n/** Append the interrupt footer to a (possibly empty) partial reply. */\nexport function withInterruptMarker(partial: string): string {\n const trimmed = partial.trim();\n if (!trimmed) return INTERRUPT_MARKER;\n if (trimmed.endsWith(INTERRUPT_MARKER)) return trimmed;\n return `${trimmed}\\n\\n${INTERRUPT_MARKER}`;\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 usage?: AssistantUsageSnapshot | null,\n contextSnapshot?: ContextUsageSnapshot | null,\n sourceManifest?: readonly SourceManifestEntry[] | null,\n): void {\n const trimmed = content.trim();\n let final = trimmed;\n const toolList = usedTools ? Array.from(new Set(usedTools.filter(Boolean))) : [];\n // Skip stall + fabrication footers when the user explicitly interrupted\n // the run — the message wasn't a model stall, it was a deliberate stop,\n // and the interrupt marker already explains the cut to both reader and\n // the next agent turn.\n const wasInterrupted = trimmed.endsWith(INTERRUPT_MARKER);\n // Stall detector: model ended its turn with a promise-shaped tail but\n // either invoked no tool, OR called only read-only tools while\n // narrating a write. Both shapes look identical to the user — a chat\n // bubble that ends mid-task — so the warning footer covers both.\n // The retry budget (MAX_STALL_AUTO_RETRIES) is exhausted by the time\n // we hit this code path, so the footer is the user's manual recovery\n // affordance: \"Reply continue\".\n const isStallProse = !!trimmed && !wasInterrupted && looksLikeStall(trimmed);\n const noTool = toolList.length === 0;\n const noWriteTool = toolList.length > 0 && !toolList.some(isWriteLikeToolName);\n if (isStallProse && (noTool || noWriteTool)) {\n final = `${trimmed}\\n\\n*⚠️ Agent stalled — promised a next step but did not invoke a write tool. Reply \"continue\" to retry.*`;\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 && !wasInterrupted && !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 withoutAutoplay = stripAutoplayHints(final);\n // Split the optional trailing ```jarela-references` JSON block off the\n // body before persistence. The block is a machine-readable list of\n // {label, href} pairs the agent declared as its sources for this turn;\n // we merge it into the manifest below. The body stored in\n // messages.content is the clean prose without the fence.\n const { body: persisted, refs: declaredRefs } = extractDeclaredReferences(withoutAutoplay);\n if (persisted || (sanitizedEvents && sanitizedEvents.length > 0)) {\n const row = addMessage(thread_id, \"assistant\", persisted, sanitizedEvents, category);\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n recordToolUsage(sanitizedEvents, persisted);\n }\n // Persist the source manifest for THIS reply into the message's\n // metadata. The chat UI uses it to resolve inline `[N]` markers →\n // clickable links and to populate the References panel.\n //\n // Scope: ONLY this turn's tool events + this turn's delegate replies.\n // We deliberately don't include prior-turn sources, memory items, or\n // earlier-dialog anchors — each reply's panel must reflect what backs\n // THAT reply, otherwise the panel turns into a 40-entry haystack of\n // stale links from unrelated topics across the thread (real user\n // complaint, 2026-06-07: \"there are so many irrelevant citation\").\n //\n // The agent's mid-prose markdown links `[label](url)` need no\n // manifest entry — they linkify themselves.\n let manifest: SourceManifestEntry[] = [];\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n const strictness = agent ? parseCitationStrictness(agent.citation_strictness) ?? \"off\" : \"off\";\n if (strictness !== \"off\") {\n manifest = buildCombinedManifest(sanitizedEvents, thread_id, {\n tools: getConfig().citationManifestMax,\n delegates: 10,\n });\n }\n }\n // Fold the agent's declared refs into the manifest (dedup by\n // normalized href). These are appended after tool-derived entries\n // and renumbered. Skipped when strictness is `off` so off-mode\n // agents that ignore the fence don't suddenly get a References\n // panel (the strictness gate is the user's switch for this whole\n // feature).\n if (declaredRefs.length > 0) {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n const strictness = agent ? parseCitationStrictness(agent.citation_strictness) ?? \"off\" : \"off\";\n if (strictness !== \"off\") {\n manifest = mergeDeclaredReferences(manifest, declaredRefs);\n }\n }\n if (manifest.length > 0) {\n setMessageMetadata(row.msg_id, {\n citations: {\n checker_model: \"\",\n claims: [],\n unverified_links: [],\n sources: manifest.map((e) => ({ n: e.n, label: e.label, href: e.href })),\n },\n });\n }\n // Citation checker (fire-and-forget). Runs only when the agent's\n // `citation_strictness` is not `off`, the persisted text is non-empty,\n // the manifest is non-empty, and (at standard/informational levels)\n // the text actually carries at least one `[N]` marker to verify.\n // Strict mode skips the marker pre-check so the audit can flag\n // missing citations. Writes its verdict back into `messages.metadata`\n // alongside the manifest; the UI picks it up on the next refresh.\n // Any failure (timeout, parse error, missing checker model) leaves\n // the manifest in place and the message renders normally.\n if (persisted && manifest.length > 0) {\n void runCitationCheckerForRow(thread_id, row.msg_id, persisted, manifest);\n }\n // ADR-0041 wrote provider-reported token usage when available. The\n // per-tier context snapshot (hot/warm/facts/overhead) is computed\n // locally and is meaningful even when the provider didn't emit a\n // usage event (custom proxies, mid-stream errors, providers that\n // omit usage on tool turns), so persist the row whenever EITHER side\n // has data. The cost/rate columns simply stay null when there are\n // no provider tokens to price.\n const hasProviderUsage = !!(usage && (usage.input_tokens > 0 || usage.output_tokens > 0));\n if (hasProviderUsage || contextSnapshot) {\n try {\n const thread = getThread(thread_id);\n const agentId = thread?.agent_id ?? \"\";\n const agent = agentId ? getAgentConfig(agentId) : null;\n const agentName = agent?.name ?? agentId;\n const tables = getPricingTables();\n const rates = hasProviderUsage\n ? modelRatesFor(tables, usage!.provider, usage!.model_id)\n : { inputPer1M: null, outputPer1M: null };\n const cacheCreation = hasProviderUsage ? (usage!.cache_creation_input_tokens ?? 0) : 0;\n const cacheRead = hasProviderUsage ? (usage!.cache_read_input_tokens ?? 0) : 0;\n const cost = hasProviderUsage\n ? estimateCostUsd(usage!.input_tokens, usage!.output_tokens, rates, {\n cache_creation_input_tokens: cacheCreation,\n cache_read_input_tokens: cacheRead,\n })\n : 0;\n recordMessageUsage({\n message_id: row.msg_id,\n thread_id,\n agent_id: agentId,\n agent_name: agentName,\n provider: hasProviderUsage ? usage!.provider : \"\",\n model_id: hasProviderUsage ? usage!.model_id : \"\",\n model_config_name: hasProviderUsage ? usage!.model_config_name : null,\n input_tokens: hasProviderUsage ? usage!.input_tokens : 0,\n output_tokens: hasProviderUsage ? usage!.output_tokens : 0,\n input_rate_usd_per_mtok: rates.inputPer1M,\n output_rate_usd_per_mtok: rates.outputPer1M,\n cost_usd: cost,\n cache_creation_input_tokens: cacheCreation > 0 ? cacheCreation : null,\n cache_read_input_tokens: cacheRead > 0 ? cacheRead : null,\n tier_usage: contextSnapshot\n ? {\n hot_tokens: contextSnapshot.hot_tokens,\n warm_tokens: contextSnapshot.warm_tokens,\n facts_tokens: contextSnapshot.facts_tokens,\n overhead_tokens: contextSnapshot.overhead_tokens,\n hot_budget_tokens: contextSnapshot.hot_budget_tokens,\n warm_budget_tokens: contextSnapshot.warm_budget_tokens,\n facts_budget_tokens: contextSnapshot.facts_budget_tokens,\n context_window_tokens: contextSnapshot.context_window_tokens,\n }\n : null,\n });\n } catch (err) {\n console.error(\"[message_usage] snapshot failed\", err);\n }\n }\n }\n}\n\n/**\n * Fire-and-forget citation checker. Gated by the agent's\n * `citation_strictness` and the existence of a checker model. The checker\n * is intentionally permissive about failure — anything that goes wrong\n * (no model, provider throw, parse failure, timeout) leaves the manifest-\n * only metadata in place so the chat UI still renders `[N]` markers as\n * links.\n */\nasync function runCitationCheckerForRow(\n thread_id: string,\n msg_id: string,\n persistedText: string,\n sourceManifest: readonly SourceManifestEntry[],\n): Promise<void> {\n try {\n const thread = getThread(thread_id);\n const agent = thread?.agent_id ? getAgentConfig(thread.agent_id) : null;\n if (!agent) return;\n const strictness = parseCitationStrictness(agent.citation_strictness) ?? \"off\";\n if (strictness === \"off\") return;\n const checkerModel = (agent.anti_hallucination_model_config ?? \"\").trim();\n if (!checkerModel) return;\n // Strict mode runs the checker even when the agent emitted no markers\n // (it should have cited every claim — the audit will flag the\n // missing ones). Standard / informational skip the LLM round-trip\n // when there's literally nothing to verify, as a cost guard.\n if (strictness !== \"strict\" && extractCitedMarkers(persistedText).length === 0) return;\n const verdict = await classifyCitations(persistedText, sourceManifest, checkerModel);\n if (!verdict) return;\n setMessageMetadata(msg_id, {\n citations: {\n ...verdict,\n sources: sourceManifest.map((e) => ({ n: e.n, label: e.label, href: e.href })),\n },\n });\n } catch (err) {\n console.error(\"[citation-checker] failed\", err);\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 TOOL_LOOP_THRESHOLD = 3;\n\n// A \"write-like\" tool, by name, is one whose path segments contain a CRUD\n// verb. Per-segment match so e.g. `dataset_search` doesn't qualify on\n// `set`. Used to flag the \"called read-only tools then promised a write\"\n// stall pattern.\nconst WRITE_VERB_SEGMENTS = new Set([\n \"write\", \"edit\", \"create\", \"update\", \"delete\", \"move\", \"copy\", \"mkdir\",\n \"add\", \"insert\", \"patch\", \"post\", \"put\", \"send\", \"publish\", \"save\",\n \"upload\", \"transition\", \"rank\", \"merge\", \"set\", \"schedule\", \"cancel\",\n]);\n\nexport function isWriteLikeToolName(name: string): boolean {\n if (!name) return false;\n const segments = name.toLowerCase().split(/[._\\-/]+/).filter(Boolean);\n return segments.some((s) => WRITE_VERB_SEGMENTS.has(s));\n}\n\n// Stable signature of a tool call so repeated identical calls collapse to\n// the same key. JSON.stringify with sorted keys is good enough — the\n// argument shapes that matter here are small JSON objects, not graphs.\nexport function toolCallSignature(name: string, args: Record<string, unknown>): string {\n try {\n const sortedKeys = Object.keys(args).sort();\n const stable: Record<string, unknown> = {};\n for (const k of sortedKeys) stable[k] = args[k];\n return `${name}::${JSON.stringify(stable)}`;\n } catch {\n return `${name}::<unserializable>`;\n }\n}\n\n// Returns the FIRST tool name whose `(name, args)` signature appears\n// `threshold` or more times in `events`. Empty names and threshold <= 0\n// disable the check.\nexport function detectToolLoop(\n events: ReadonlyArray<{ name: string; args: Record<string, unknown> }>,\n threshold: number,\n): string | null {\n if (threshold <= 0) return null;\n const counts = new Map<string, number>();\n for (const ev of events) {\n if (!ev.name) continue;\n const sig = toolCallSignature(ev.name, ev.args);\n const c = (counts.get(sig) ?? 0) + 1;\n counts.set(sig, c);\n if (c >= threshold) return ev.name;\n }\n return null;\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 // Aspirational future-action family: \"Writing X now\", \"Saving the file\n // now\", \"Creating the report now\". Catches the read-only-tools +\n // narrate-the-write + end-of-turn loop where the model promises a\n // write but never invokes the corresponding tool.\n /\\b(writing|saving|creating|updating|deleting|adding|appending|generating|drafting|pushing|sending|posting|moving|copying|renaming|editing|regenerating)\\b[^.!?]*\\bnow\\b[!.]?\\s*$/i,\n // Broader promise-shape: any \"I'll <verb>\" or \"I will <verb>\" followed\n // by \"now\" anywhere in the trailing clause. Catches \"I will read it\n // now to understand the plan\" / \"I'll add the note now\" — variants the\n // narrow aspirational-verb list above misses because the verb is in\n // bare infinitive form and `now` is mid-sentence rather than at the\n // end.\n /\\b(?:i['’]?ll|i\\s+will)\\s+\\w+\\b[^.!?]*\\bnow\\b/i,\n // Present-continuous version: \"I'm reading … now to figure out …\" /\n // \"I am updating the dashboard now to reflect …\". Same idea, but the\n // model is narrating in progress rather than promising in future.\n // Same failure mode in practice — followed by no actual write call.\n /\\b(?:i['’]?m|i\\s+am)\\s+\\w+ing\\b[^.!?]*\\bnow\\b/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 const thread = getThread(thread_id);\n if (!thread) return [];\n const agentCfg = getAgentConfig(thread.agent_id);\n return getAgentTools(agentCfg);\n}\n\nexport function looksLikeStall(text: string): boolean {\n // Inspect the last paragraph / sentence — 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","// 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 { runAllHealthProbes } from \"@/lib/health/runner\";\nimport { isMasterKeyLocked } from \"@/lib/crypto/master-key\";\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// Probe integrations + LLM keys every Nth tick. 20 ticks × 30s = 10 min\n// — frequent enough that a freshly-expired token surfaces in roughly the\n// same window as a doc-source sweep, cheap enough that we don't hammer\n// the vendor /me endpoints. The health runner itself dedups alerts so\n// repeated failures only re-fire on its own (longer) backoff.\nconst HEALTH_SWEEP_EVERY_TICKS = 20;\n\ninterface SchedulerState {\n started: boolean;\n timer: NodeJS.Timeout | null;\n running: boolean;\n tickCount: number;\n healthTickCount: number;\n}\nconst state = getOrCreateGlobal<SchedulerState>(\"__jarela_scheduler\", () => ({\n started: false,\n timer: null,\n running: false,\n tickCount: 0,\n healthTickCount: 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 // Fire the first health probe immediately (instead of waiting 10min)\n // so a freshly-started server surfaces a broken token / unreachable\n // vendor on the first SSE subscription. Fire-and-forget; cheap.\n if (!isMasterKeyLocked()) {\n runAllHealthProbes().catch((err) => {\n console.error(\n \"[scheduler] initial health probe failed:\",\n err instanceof Error ? err.message : String(err),\n );\n });\n }\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 // Skip the entire tick while the at-rest key is locked (ADR-0063):\n // every encrypted store read would throw MasterKeyLockedError and\n // pollute the console. The tick resumes naturally once the user\n // unlocks via the splash.\n if (isMasterKeyLocked()) 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\n // Health probe sweep. Tracks integrations + LLM keys, publishes\n // health_alert notifications on state transitions. Runs out-of-band\n // from triggers so a slow vendor doesn't delay scheduled-task firing.\n state.healthTickCount = (state.healthTickCount + 1) % HEALTH_SWEEP_EVERY_TICKS;\n if (state.healthTickCount === 0) {\n runAllHealthProbes().catch((err) => {\n console.error(\n \"[scheduler] health probe 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\";\nimport type { AssistantUsageSnapshot } from \"@/lib/agents/run-thread\";\n\nexport interface CollectedRun {\n assistantContent: string;\n usedTools: string[];\n toolEvents: PersistedToolEvent[];\n terminal: \"done\" | \"error\";\n errorMessage?: string;\n // True when the run ended because the user hit Stop or steered. Distinct\n // from a generic stream error so persistence can mark the partial turn\n // with an interrupt footer instead of an error one — the next agent turn\n // reads the marker and knows the previous reply was cut, not stalled.\n aborted?: boolean;\n // ADR-0041: provider-reported token usage + model/provider snapshot from\n // the terminal `done` chunk. Undefined when the stream errored out before\n // a usage event arrived (or the provider didn't report one).\n usage?: AssistantUsageSnapshot;\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 data = chunk.data as { message?: unknown; code?: unknown };\n const msg = data?.message;\n if (typeof msg === \"string\") result.errorMessage = msg;\n if (data?.code === \"aborted\") result.aborted = true;\n return result;\n }\n case \"done\": {\n const d = chunk.data as {\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n source?: string;\n };\n provider?: string;\n model_id?: string;\n model_config_name?: string | null;\n };\n if (d?.usage && d.provider && d.model_id && d.usage.source === \"provider\") {\n result.usage = {\n input_tokens: d.usage.input_tokens ?? 0,\n output_tokens: d.usage.output_tokens ?? 0,\n cache_creation_input_tokens: d.usage.cache_creation_input_tokens ?? 0,\n cache_read_input_tokens: d.usage.cache_read_input_tokens ?? 0,\n provider: d.provider,\n model_id: d.model_id,\n model_config_name: d.model_config_name ?? null,\n };\n }\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 const name = err instanceof Error ? err.name : \"\";\n const msg = err instanceof Error ? err.message : String(err);\n result.errorMessage = msg;\n if (name === \"AbortError\" || /aborted/i.test(msg)) result.aborted = true;\n }\n\n return result;\n}\n","// Web-sourced fallback context-window sizes per (provider, model_id).\n// Used when the live `/models` endpoint doesn't report `context_length`\n// (OpenAI's catalog and GitHub Copilot's catalog both omit it) AND the\n// user hasn't pinned `context_window_tokens` on the model config.\n//\n// Resolution order at runtime is:\n// 1. user-set `params.context_window_tokens` (explicit override)\n// 2. live API value via `listModels()` / catalog cache (when populated)\n// 3. this static fallback (this file)\n// 4. `DEFAULT_CONTEXT_WINDOW_TOKENS` in lib/agents/context-budget.ts\n//\n// Verified from each vendor's public docs as of 2026-06. Bump when vendors\n// publish new families.\n\nexport interface KnownModelLimits {\n context_length: number;\n max_output_tokens?: number;\n}\n\nconst ANTHROPIC: Record<string, KnownModelLimits> = {\n \"claude-opus-4-7\": { context_length: 1_000_000, max_output_tokens: 8192 },\n \"claude-opus-4\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-sonnet-4-6\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-sonnet-4\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3.7-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-7-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-5-sonnet\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-3-5-haiku\": { context_length: 200_000, max_output_tokens: 8192 },\n \"claude-haiku-4-5\": { context_length: 200_000, max_output_tokens: 4096 },\n \"claude-haiku-4\": { context_length: 200_000, max_output_tokens: 4096 },\n \"claude-3-opus\": { context_length: 200_000, max_output_tokens: 4096 },\n};\n\nconst GEMINI: Record<string, KnownModelLimits> = {\n \"gemini-2.5-pro\": { context_length: 1_048_576, max_output_tokens: 65_536 },\n \"gemini-2.5-flash\": { context_length: 1_048_576, max_output_tokens: 65_536 },\n \"gemini-2.0-flash-lite\": { context_length: 1_048_576, max_output_tokens: 8192 },\n \"gemini-2.0-flash\": { context_length: 1_048_576, max_output_tokens: 8192 },\n \"gemini-1.5-pro\": { context_length: 2_097_152, max_output_tokens: 8192 },\n \"gemini-1.5-flash\": { context_length: 1_048_576, max_output_tokens: 8192 },\n};\n\nconst OPENAI: Record<string, KnownModelLimits> = {\n \"gpt-5-mini\": { context_length: 400_000, max_output_tokens: 128_000 },\n \"gpt-5\": { context_length: 400_000, max_output_tokens: 128_000 },\n \"gpt-4.1-mini\": { context_length: 1_047_576, max_output_tokens: 32_768 },\n \"gpt-4.1\": { context_length: 1_047_576, max_output_tokens: 32_768 },\n \"gpt-4o-mini\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"gpt-4o\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"gpt-4-turbo\": { context_length: 128_000, max_output_tokens: 4096 },\n \"gpt-4\": { context_length: 8192, max_output_tokens: 4096 },\n \"gpt-3.5-turbo\": { context_length: 16_385, max_output_tokens: 4096 },\n \"chatgpt-4o\": { context_length: 128_000, max_output_tokens: 16_384 },\n \"o4-mini\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o3-mini\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o3\": { context_length: 200_000, max_output_tokens: 100_000 },\n \"o1-mini\": { context_length: 128_000, max_output_tokens: 65_536 },\n \"o1\": { context_length: 200_000, max_output_tokens: 100_000 },\n};\n\nconst DEEPSEEK: Record<string, KnownModelLimits> = {\n \"deepseek-v4-flash\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-v4-pro\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-chat\": { context_length: 65_536, max_output_tokens: 8192 },\n \"deepseek-reasoner\": { context_length: 65_536, max_output_tokens: 8192 },\n};\n\n// GitHub Copilot proxies vendor models — sometimes under a transformed id\n// (e.g. `Github-Opus4.6`, `copilot-claude-3.5-sonnet`). Strip the proxy\n// prefix and dispatch to the underlying vendor table.\nfunction resolveCopilot(model_id: string): KnownModelLimits | null {\n const normalized = model_id\n .replace(/^(?:Github-|copilot-)/i, \"\")\n .toLowerCase();\n // Canonicalise a few proxy-specific spellings.\n const canon = normalized\n .replace(/^opus4\\.6/, \"claude-opus-4-7\")\n .replace(/^opus4/, \"claude-opus-4\")\n .replace(/^sonnet4\\.6/, \"claude-sonnet-4-6\")\n .replace(/^sonnet4/, \"claude-sonnet-4\")\n .replace(/^haiku4\\.5/, \"claude-haiku-4-5\");\n if (canon.startsWith(\"claude\")) return matchPrefix(ANTHROPIC, canon);\n if (canon.startsWith(\"gemini\")) return matchPrefix(GEMINI, canon);\n if (canon.startsWith(\"gpt\") || /^o[134](?:-|$)/.test(canon)) return matchPrefix(OPENAI, canon);\n return null;\n}\n\nfunction matchPrefix(table: Record<string, KnownModelLimits>, id: string): KnownModelLimits | null {\n const lower = id.toLowerCase();\n const exact = table[lower];\n if (exact) return exact;\n // Longest-prefix match so `gpt-4o-2024-08-06` resolves to `gpt-4o` and\n // not `gpt-4` (which would also prefix-match).\n let best: { key: string; v: KnownModelLimits } | null = null;\n for (const [k, v] of Object.entries(table)) {\n if (lower.startsWith(k) && (!best || k.length > best.key.length)) {\n best = { key: k, v };\n }\n }\n return best?.v ?? null;\n}\n\nexport function getKnownModelLimits(provider: string, model_id: string): KnownModelLimits | null {\n if (!provider || !model_id) return null;\n switch (provider) {\n case \"anthropic\": return matchPrefix(ANTHROPIC, model_id);\n case \"gemini\": return matchPrefix(GEMINI, model_id);\n case \"openai\": return matchPrefix(OPENAI, model_id);\n case \"deepseek\": return matchPrefix(DEEPSEEK, model_id);\n case \"github-copilot\": return resolveCopilot(model_id);\n default: return null;\n }\n}\n\nexport function getKnownContextLength(provider: string, model_id: string): number | null {\n return getKnownModelLimits(provider, model_id)?.context_length ?? null;\n}\n\nexport function getKnownMaxOutputTokens(provider: string, model_id: string): number | null {\n return getKnownModelLimits(provider, model_id)?.max_output_tokens ?? null;\n}\n\n// Flat catalog snapshot for one provider — used by introspection tools so\n// the agent can enumerate what's known statically. Returns [] for providers\n// without a static table (e.g. `langchain`, `mock`, externals).\nexport function listKnownModels(\n provider: string,\n): Array<{ model_id: string; context_length: number; max_output_tokens: number | null }> {\n let table: Record<string, KnownModelLimits> | null = null;\n switch (provider) {\n case \"anthropic\": table = ANTHROPIC; break;\n case \"gemini\": table = GEMINI; break;\n case \"openai\": table = OPENAI; break;\n case \"deepseek\": table = DEEPSEEK; break;\n default: return [];\n }\n return Object.entries(table).map(([model_id, l]) => ({\n model_id,\n context_length: l.context_length,\n max_output_tokens: l.max_output_tokens ?? null,\n }));\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","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getMemory, putMemory, listMemory, deleteMemory } 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\nexport const memoryDeleteTool = tool(\n async ({ namespace, key }) => {\n const removed = deleteMemory(namespace, key);\n return JSON.stringify({ ok: true, namespace, key, removed });\n },\n {\n name: \"memory_delete\",\n description:\n \"Delete a single memory entry by namespace and key. Returns { removed: true } if a row was removed, { removed: false } if no matching row existed. Bulk deletion by namespace is not supported by this tool — list-then-delete-loop if needed.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace\"),\n key: z.string().describe(\"Key within the namespace\"),\n }),\n },\n);\n\nregisterTools(\"Memory\", \"read\", [memoryReadTool, memoryListTool]);\nregisterTools(\"Memory\", \"write\", [memoryWriteTool, memoryDeleteTool]);\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\", \"read\", [documentsSearch, documentsListSources]);\nregisterTools(\"Documents\", \"write\", [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\", \"write\", [\n documentsAddRemoteSource,\n documentsRemoveSource,\n documentsReindexSource,\n documentsIndexUrl,\n]);\n","// Safety mode for destructive built-in tools (exec + filesystem writes).\n//\n// Resolved once per call from `JARELA_TOOL_SAFETY`. Three tiers:\n//\n// \"safe\" — read-only. Exec accepts only an allowlisted set of\n// inspection commands (ls, git status, …); filesystem\n// tools refuse every write, edit, move, copy, delete,\n// or mkdir. Per-call `allow_unsafe` is IGNORED.\n// \"mostly_safe\" — default. Exec blocks the obviously-dangerous pattern\n// list (rm -rf /, shutdown, fork bomb, …); filesystem\n// tools refuse credential paths and the Jarela data dir.\n// Per-call `allow_unsafe=true` lifts the exec block for\n// that single call.\n// \"bypass\" — every guard off. For local development on a machine\n// you control and trust completely. NOT for use behind\n// a tunnel or with untrusted prompt sources.\n//\n// The mode is process-wide so prompt injection cannot escalate by\n// passing arguments — the LLM can only ever *downgrade* (via\n// `allow_unsafe=false` semantics, which is just \"don't try to bypass\").\n\nexport type SafetyMode = \"safe\" | \"mostly_safe\" | \"bypass\";\n\nexport function resolveSafetyMode(): SafetyMode {\n const raw = (process.env.JARELA_TOOL_SAFETY ?? \"\").trim().toLowerCase();\n if (raw === \"safe\") return \"safe\";\n if (raw === \"bypass\" || raw === \"unsafe\") return \"bypass\";\n return \"mostly_safe\";\n}\n\n// Inspection-only commands allowed in `safe` mode. Matched as the FIRST\n// token (after stripping leading whitespace) — pipelines, redirections,\n// command substitution, &&, ;, etc. are all rejected because we cannot\n// reason about what the right-hand side will do.\nconst SAFE_EXEC_ALLOWLIST = new Set([\n \"ls\", \"dir\", \"pwd\", \"cd\", \"echo\", \"cat\", \"type\", \"head\", \"tail\",\n \"wc\", \"stat\", \"file\", \"which\", \"where\", \"whoami\", \"hostname\",\n \"date\", \"uname\", \"df\", \"du\", \"ps\", \"env\", \"printenv\",\n \"git\", \"node\", \"npm\", \"npx\", \"deno\", \"python\", \"python3\", \"pip\", \"pip3\",\n]);\n\n// Subcommands considered read-only for tools that take a verb. We only\n// need to enumerate the dangerous tools here — anything not listed falls\n// back to \"the whole tool is read-only\" (e.g. `cat`, `ls`).\nconst SAFE_SUBCOMMANDS: Record<string, Set<string>> = {\n git: new Set([\n \"status\", \"log\", \"diff\", \"show\", \"blame\", \"branch\", \"tag\",\n \"remote\", \"ls-files\", \"ls-tree\", \"config\", \"rev-parse\",\n \"describe\", \"shortlog\", \"reflog\",\n ]),\n npm: new Set([\"ls\", \"list\", \"view\", \"info\", \"outdated\", \"config\", \"whoami\", \"ping\", \"doctor\"]),\n npx: new Set([]), // npx runs arbitrary code; never allow under \"safe\"\n node: new Set([]), // bare `node` opens a REPL; `node script.js` runs anything\n python: new Set([]),\n python3: new Set([]),\n deno: new Set([\"info\", \"doc\"]),\n pip: new Set([\"list\", \"show\", \"freeze\", \"config\"]),\n pip3: new Set([\"list\", \"show\", \"freeze\", \"config\"]),\n};\n\n// Shell metacharacters that compose commands or redirect IO. Their\n// presence in `safe` mode is grounds for rejection because the\n// allowlist check only inspects the first token.\nconst COMPOSER_RE = /[|&;`$<>]|\\$\\(|\\|\\||&&/;\n\nexport interface ExecAllowResult {\n allowed: boolean;\n reason?: string;\n}\n\nexport function checkExecAllowed(\n command: string,\n opts: { mode: SafetyMode; allowUnsafe?: boolean; blockedByPattern: boolean },\n): ExecAllowResult {\n if (opts.mode === \"bypass\") return { allowed: true };\n if (opts.mode === \"mostly_safe\") {\n if (opts.blockedByPattern && !opts.allowUnsafe) {\n return {\n allowed: false,\n reason:\n \"Command blocked by safety policy (mode=mostly_safe). Pass allow_unsafe=true only when you fully trust the command.\",\n };\n }\n return { allowed: true };\n }\n // safe mode\n const trimmed = command.trim();\n if (!trimmed) return { allowed: false, reason: \"command is required\" };\n if (COMPOSER_RE.test(trimmed)) {\n return {\n allowed: false,\n reason:\n \"safe mode rejects pipelines, redirection, command substitution, &&, and ;. \" +\n \"Set JARELA_TOOL_SAFETY=mostly_safe (or bypass) to allow composite commands.\",\n };\n }\n const tokens = trimmed.split(/\\s+/);\n const head = tokens[0]?.toLowerCase();\n if (!head || !SAFE_EXEC_ALLOWLIST.has(head)) {\n return {\n allowed: false,\n reason:\n `safe mode allows only inspection commands (${[...SAFE_EXEC_ALLOWLIST].sort().join(\", \")}). ` +\n \"Set JARELA_TOOL_SAFETY=mostly_safe to enable the broader policy.\",\n };\n }\n const subAllowlist = SAFE_SUBCOMMANDS[head];\n if (subAllowlist) {\n const sub = tokens[1]?.toLowerCase().replace(/^--?/, \"\");\n // Allow bare invocations that are themselves read-only (e.g. `git`\n // alone prints help). Reject if the subcommand is missing for tools\n // that need one to be safe (node/python/npx → arbitrary code).\n if (subAllowlist.size === 0) {\n return {\n allowed: false,\n reason: `safe mode refuses '${head}' because it can execute arbitrary code. Use mostly_safe or bypass.`,\n };\n }\n if (sub && !subAllowlist.has(sub)) {\n return {\n allowed: false,\n reason:\n `safe mode allows '${head}' only for: ${[...subAllowlist].sort().join(\", \")}. ` +\n \"Use mostly_safe or bypass for other subcommands.\",\n };\n }\n }\n return { allowed: true };\n}\n\n// File-system op classification.\nexport type FsOp = \"read\" | \"write\";\n\nexport function checkFsAllowed(\n op: FsOp,\n opts: { mode: SafetyMode },\n): ExecAllowResult {\n if (opts.mode === \"bypass\" || opts.mode === \"mostly_safe\") return { allowed: true };\n // safe mode: reads are fine, writes are not.\n if (op === \"read\") return { allowed: true };\n return {\n allowed: false,\n reason:\n \"safe mode refuses filesystem mutations (write/edit/move/copy/delete/mkdir). \" +\n \"Set JARELA_TOOL_SAFETY=mostly_safe to enable writes outside credential dirs.\",\n };\n}\n","// Per-thread workspace context for software-development agents.\n//\n// `workspace_init` registers a project root for the active thread; from\n// then on, every `file_*` and `local_exec` call with a relative path\n// resolves against that root instead of the user's HOME directory.\n//\n// State lives on globalThis under a Symbol so multiple module instances\n// (Next.js route bundles, dev HMR) share the same map. Same idempotency\n// pattern as lib/logging/sink.ts.\n//\n// Tools read the active workspace by passing the langchain tool config\n// through to `currentWorkspace(config)`. The config carries\n// `configurable.thread_id` set by the agent runner; tools invoked\n// outside a thread (live tests, ad-hoc CLI use) fall through to the\n// \"_default\" slot.\n\nexport interface WorkspaceContext {\n root: string;\n scoped: boolean;\n /** Set when initialised; useful for status output. */\n opened_at: number;\n}\n\nconst STATE_KEY: unique symbol = Symbol.for(\"@jarela/workspace-context\");\ntype GlobalWithWorkspace = typeof globalThis & {\n [STATE_KEY]?: Map<string, WorkspaceContext>;\n};\n\nfunction store(): Map<string, WorkspaceContext> {\n const g = globalThis as GlobalWithWorkspace;\n if (!g[STATE_KEY]) g[STATE_KEY] = new Map();\n return g[STATE_KEY]!;\n}\n\nconst DEFAULT_KEY = \"_default\";\n\n/** Langchain tool config shape (only the parts we care about). */\nexport interface ToolConfig {\n configurable?: {\n thread_id?: string;\n [k: string]: unknown;\n };\n}\n\nfunction keyFor(config?: ToolConfig): string {\n const tid = config?.configurable?.thread_id;\n return typeof tid === \"string\" && tid ? tid : DEFAULT_KEY;\n}\n\nexport function currentWorkspace(config?: ToolConfig): WorkspaceContext | undefined {\n return store().get(keyFor(config));\n}\n\nexport function setWorkspace(ws: WorkspaceContext, config?: ToolConfig): void {\n store().set(keyFor(config), ws);\n}\n\nexport function clearWorkspace(config?: ToolConfig): boolean {\n return store().delete(keyFor(config));\n}\n\n/** Test-only: wipe every registered workspace. */\nexport function _resetWorkspaceContext(): void {\n store().clear();\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\";\nimport { checkExecAllowed, resolveSafetyMode } from \"./safety\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\n\n// JARELA_EXEC_MAX_OUTPUT_BYTES overrides the output cap.\nfunction maxOutputBytes(): number { return getConfig().execMaxOutputBytes; }\n// Internal subprocess timeout. The agent's wall-clock budget on the tool\n// call (see lib/tools/wallclock.ts) is the primary deadline; this kills\n// the child process so a runaway shell can't keep burning CPU after the\n// wallclock abandons the promise.\nconst EXEC_DEFAULT_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 = maxOutputBytes()): { 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 workspaceRoot?: string;\n },\n): string {\n if (!command.trim()) {\n return JSON.stringify({ exit_code: 1, stderr: \"command is required\" });\n }\n\n const timeout = options.timeout_ms ?? EXEC_DEFAULT_TIMEOUT_MS;\n\n const mode = resolveSafetyMode();\n const gate = checkExecAllowed(command, {\n mode,\n allowUnsafe: options.allow_unsafe,\n blockedByPattern: isBlockedCommand(command),\n });\n if (!gate.allowed) {\n return JSON.stringify({ exit_code: 126, stderr: gate.reason, safety_mode: mode });\n }\n\n // Precedence: explicit options.cwd > active workspace root > process.cwd().\n // The workspace root takes priority over process.cwd() so the agent\n // doesn't have to thread `cwd` into every shell call once it's called\n // workspace_init.\n const cwd = options.cwd?.trim()\n ? options.cwd\n : options.workspaceRoot ?? 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: maxOutputBytes() * 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; signal?: string; code?: string; killed?: boolean };\n const out = clipOutput(String(e.stdout ?? \"\"));\n // Node's execSync surfaces a `timeout` kill as `signal: \"SIGTERM\"`\n // and/or `killed: true` with no exit status. Bare exit_code=1 +\n // empty stderr would lead the agent to retry the same command;\n // call out the timeout explicitly so it narrows scope or raises\n // timeout_ms instead.\n const timedOut = e.code === \"ETIMEDOUT\"\n || e.signal === \"SIGTERM\"\n || (e.killed === true && (e.status == null || e.status === 0));\n if (timedOut) {\n const errText = clipOutput(String(e.stderr ?? \"\"), 2_000);\n return JSON.stringify({\n exit_code: 124,\n stdout: out.value,\n stderr: errText.value,\n truncated: out.truncated || errText.truncated,\n cwd,\n timed_out: true,\n timeout_ms: timeout,\n error: `command timed out after ${Math.round(timeout / 1000)}s. Try a narrower scope, a smaller working set, or pass a larger timeout_ms.`,\n });\n }\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(\"Subprocess kill timeout in milliseconds (default 60000). Independent of the agent's wall-clock budget on this call.\"),\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 }, config?: ToolConfig) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe, workspaceRoot: currentWorkspace(config)?.root }),\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 }, config?: ToolConfig) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe, workspaceRoot: currentWorkspace(config)?.root }),\n {\n name: \"shell_exec\",\n description: \"Backward-compatible alias for local_exec.\",\n schema: execSchema,\n },\n);\n\nregisterTools(\"Shell\", \"execute\", [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\";\nimport { checkFsAllowed, resolveSafetyMode } from \"./safety\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\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\n// JARELA_FILES_MAX_READ_BYTES / JARELA_FILES_MAX_WRITE_BYTES override these.\n// MAX_LIST_JSON_BYTES isn't user-tunable: the cap exists to keep file_list\n// JSON inside one LLM context budget; raising it just shifts the failure.\nfunction maxReadBytes(): number { return getConfig().filesMaxReadBytes; }\nfunction maxWriteBytes(): number { return getConfig().filesMaxWriteBytes; }\nconst MAX_LIST_JSON_BYTES = 24_000;\n\n// Wall-clock deadline for a single fs.* call. Cloud-sync filesystem\n// providers (OneDrive, iCloud, Dropbox), network mounts, and aggressive\n// AV scanners can wedge fs.writeFile/readFile/mkdir indefinitely. Without\n// a deadline the agent loop just spins until the run-registry idle\n// watchdog (90s default) force-finishes the run with a generic \"run\n// timed out\" — the user never learns it was a stuck fs op. With this,\n// the deadline fires first and a structured error envelope tells the\n// agent (and the user) which path stalled.\n//\n// This is a hardcoded leak-prevention backstop. The agent-controlled\n// wall-clock budget on every tool call (see lib/tools/wallclock.ts) is\n// the primary deadline; this only fires when the wallclock is even\n// longer than the backstop (e.g. a 10-minute build that includes a\n// stuck file op).\nconst FS_DEADLINE_BACKSTOP_MS = 360_000;\nexport async function withFsDeadline<T>(\n label: string,\n abs: string,\n work: () => Promise<T>,\n deadlineMs: number = FS_DEADLINE_BACKSTOP_MS,\n): Promise<T> {\n const ms = deadlineMs;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\n `${label} on '${abs}' timed out after ${Math.round(ms / 1000)}s — the path may be on a stalled filesystem (cloud-sync provider, network mount, AV scanner). Try a different location.`,\n )), ms);\n });\n try {\n return await Promise.race([work(), timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\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.\n//\n// - `~` and `~/foo` always resolve against $HOME.\n// - Absolute paths are honoured verbatim.\n// - Bare relative paths resolve against `workspaceRoot` if one is set\n// (the agent called `workspace_init`), otherwise against $HOME.\n//\n// 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\"; the workspace root takes\n// priority once the agent has declared one.\nfunction resolvePath(p: string, workspaceRoot?: 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(workspaceRoot ?? os.homedir(), s);\n}\n\n/**\n * Resolver factory bound to the current tool call's workspace context.\n * Returns a `resolve()` that handles ~/abs/relative paths and enforces\n * `scoped: true` (absolute paths outside the workspace root are refused).\n */\nexport function pathResolverFor(config?: ToolConfig): {\n resolve: (p: string) => string;\n workspace?: ReturnType<typeof currentWorkspace>;\n} {\n const workspace = currentWorkspace(config);\n return {\n workspace,\n resolve: (p: string): string => {\n const abs = resolvePath(p, workspace?.root);\n if (workspace?.scoped && !isInside(abs, workspace.root)) {\n throw new Error(\n `refused: '${abs}' is outside the scoped workspace '${workspace.root}'. ` +\n `Call workspace_init with scoped=false to allow paths outside the project, or use a relative path.`,\n );\n }\n return abs;\n },\n };\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\nexport function assertSafePath(abs: string, op: \"read\" | \"write\"): void {\n const mode = resolveSafetyMode();\n const gate = checkFsAllowed(op, { mode });\n if (!gate.allowed) throw new Error(gate.reason);\n // bypass mode disables every guard, including the credential denylist.\n if (mode === \"bypass\") return;\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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"read\");\n const raw = await withFsDeadline(\"file_read\", abs, () => 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, maxReadBytes());\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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n const cap = maxWriteBytes();\n if (content.length > cap) {\n return JSON.stringify({ ok: false, path: abs, error: `content exceeds ${cap} bytes` });\n }\n assertSafePath(abs, \"write\");\n if (create_dirs !== false) {\n await withFsDeadline(\"file_write.mkdir\", path.dirname(abs), () => fs.mkdir(path.dirname(abs), { recursive: true }));\n }\n let existed = true;\n try {\n await withFsDeadline(\"file_write.access\", abs, () => fs.access(abs));\n } catch {\n existed = false;\n }\n await withFsDeadline(\"file_write\", abs, () => 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 }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"write\");\n const raw = await withFsDeadline(\"file_edit.read\", abs, () => 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 withFsDeadline(\"file_edit\", abs, () => 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 }, config?: ToolConfig) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n const { resolve } = pathResolverFor(config);\n srcAbs = resolve(source);\n dstAbs = resolve(destination);\n assertSafePath(srcAbs, \"write\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await withFsDeadline(\"file_move.stat\", srcAbs, () => 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 withFsDeadline(\"file_move.stat\", dstAbs, () => 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 withFsDeadline(\"file_move.stat\", dstAbs, () => 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 withFsDeadline(\"file_move.mkdir\", path.dirname(dstAbs), () => fs.mkdir(path.dirname(dstAbs), { recursive: true }));\n }\n await withFsDeadline(\"file_move\", srcAbs, () => 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 withFsDeadline(\"file_move.cp\", dstAbs, () => fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite }));\n await withFsDeadline(\"file_move.rm\", srcAbs, () => 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 }, config?: ToolConfig) => {\n let abs = dirPath;\n try {\n abs = pathResolverFor(config).resolve(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 withFsDeadline(\"file_list\", abs, () => 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 withFsDeadline(\"file_list.stat\", full, () => 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 }, config?: ToolConfig) => {\n let abs = dirPath;\n try {\n abs = pathResolverFor(config).resolve(dirPath);\n assertSafePath(abs, \"write\");\n await withFsDeadline(\"file_mkdir\", abs, () => 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 }, config?: ToolConfig) => {\n let abs = targetPath;\n try {\n abs = pathResolverFor(config).resolve(targetPath);\n assertSafePath(abs, \"write\");\n const st = await withFsDeadline(\"file_delete.stat\", abs, () => fs.stat(abs));\n if (st.isDirectory()) {\n if (!recursive) {\n // Try non-recursive rmdir first — succeeds only if empty.\n try {\n await withFsDeadline(\"file_delete.rmdir\", abs, () => 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 withFsDeadline(\"file_delete.rm\", abs, () => fs.rm(abs, { recursive: true, force: false }));\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"recursive\" });\n }\n await withFsDeadline(\"file_delete\", abs, () => 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 }, config?: ToolConfig) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n const { resolve } = pathResolverFor(config);\n srcAbs = resolve(source);\n dstAbs = resolve(destination);\n assertSafePath(srcAbs, \"read\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await withFsDeadline(\"file_copy.stat\", srcAbs, () => fs.stat(srcAbs));\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await withFsDeadline(\"file_copy.stat\", dstAbs, () => 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 withFsDeadline(\"file_copy.stat\", dstAbs, () => 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 withFsDeadline(\"file_copy.mkdir\", path.dirname(dstAbs), () => 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 withFsDeadline(\"file_copy.cp\", dstAbs, () => fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite }));\n } else {\n await withFsDeadline(\"file_copy\", dstAbs, () => 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 }, config?: ToolConfig) => {\n let abs = targetPath;\n try {\n abs = pathResolverFor(config).resolve(targetPath);\n const st = await withFsDeadline(\"file_stat\", abs, () => 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\", \"read\", [fileReadTool, fileListTool, fileStatTool]);\nregisterTools(\"Files\", \"write\", [\n fileWriteTool, fileEditTool, fileMoveTool, fileCopyTool, fileDeleteTool, fileMkdirTool,\n]);\n","// Search + bulk-edit tools for SWE agents.\n//\n// - `file_glob` — find files by glob pattern under a root (workspace-aware).\n// - `file_grep` — search file contents with a regex or literal, optionally\n// scoped to a glob. Replaces ad-hoc `rg`/`grep`/`Get-ChildItem`\n// calls through local_exec that break across shells.\n// - `file_multi_edit` — apply N anchored str_replace edits to one file in a\n// single transaction. All edits must apply cleanly or none do.\n//\n// All three honour the active workspace from workspace-context: bare\n// relative paths and glob roots resolve against the workspace root if\n// one is open. The credential-file denylist applies to every match.\n\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { currentWorkspace, type ToolConfig } from \"./workspace-context\";\nimport { pathResolverFor, assertSafePath, withFsDeadline } from \"./files\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// ---------------------------------------------------------------------------\n// Limits.\n//\n// Capped to keep one tool call inside an LLM context budget. file_grep\n// returns at most MAX_MATCHES across at most MAX_FILES_SCANNED — if the\n// agent's pattern is too broad, it gets a `truncated: true` hint and an\n// instruction to narrow.\n// ---------------------------------------------------------------------------\nconst MAX_FILES_SCANNED = 5_000; // hard cap on files visited\nconst MAX_MATCHES = 200; // hard cap on grep hits returned\nconst MAX_LINE_BYTES = 2_000; // truncate any matched line longer than this\nconst MAX_GLOB_RESULTS = 1_000; // hard cap on file_glob returns\nconst MAX_MULTI_EDITS = 50; // hard cap on edits per multi_edit call\nconst MAX_GREP_FILE_BYTES = 1_000_000; // skip files larger than ~1 MB (likely binary or vendored)\n\n// Directories we never recurse into — same list as workspace_init's tree\n// walker. Keeps grep snappy on real projects.\nconst DEFAULT_IGNORE = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"out\",\n \"coverage\", \"__pycache__\", \"target\", \"vendor\", \".venv\", \"venv\",\n \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\n// ---------------------------------------------------------------------------\n// Tiny glob compiler.\n//\n// Supports the subset the agent actually needs: `*` (any chars except /),\n// `**` (any chars including /), `?` (single non-/ char), and `{a,b,c}`\n// alternation. No bracket character classes — they're rarely useful at\n// this level and add escaping complexity. The pattern is matched against\n// the POSIX-style relative path (forward slashes) from the search root.\n// ---------------------------------------------------------------------------\nfunction compileGlob(pattern: string): RegExp {\n // Tokenise so `{a,b}` doesn't get its commas/braces escaped.\n let i = 0;\n let out = \"^\";\n while (i < pattern.length) {\n const c = pattern[i];\n if (c === \"*\") {\n if (pattern[i + 1] === \"*\") {\n // `**/` or `**` — match across directory separators.\n out += \".*\";\n i += 2;\n if (pattern[i] === \"/\") i++;\n } else {\n out += \"[^/]*\";\n i++;\n }\n } else if (c === \"?\") {\n out += \"[^/]\";\n i++;\n } else if (c === \"{\") {\n const end = pattern.indexOf(\"}\", i);\n if (end === -1) {\n out += \"\\\\{\";\n i++;\n continue;\n }\n const alts = pattern.slice(i + 1, end).split(\",\").map(escapeRegExp);\n out += `(?:${alts.join(\"|\")})`;\n i = end + 1;\n } else {\n out += escapeRegExp(c);\n i++;\n }\n }\n out += \"$\";\n return new RegExp(out);\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\ninterface WalkResult {\n files: string[]; // POSIX-relative paths from root\n scanned: number;\n truncated: boolean;\n}\n\nasync function walk(\n root: string,\n options: { includeHidden?: boolean; maxFiles: number; ignore?: Set<string> },\n): Promise<WalkResult> {\n const ignore = options.ignore ?? DEFAULT_IGNORE;\n const files: string[] = [];\n let scanned = 0;\n let truncated = false;\n\n async function visit(absDir: string, relDir: string): Promise<void> {\n if (truncated) return;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(absDir, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const e of entries) {\n if (truncated) return;\n if (!options.includeHidden && e.name.startsWith(\".\") && e.name !== \".\") continue;\n if (ignore.has(e.name)) continue;\n const childRel = relDir ? `${relDir}/${e.name}` : e.name;\n const childAbs = path.join(absDir, e.name);\n if (e.isDirectory()) {\n await visit(childAbs, childRel);\n } else if (e.isFile()) {\n scanned++;\n files.push(childRel);\n if (files.length >= options.maxFiles) {\n truncated = true;\n return;\n }\n }\n }\n }\n\n await visit(root, \"\");\n return { files, scanned, truncated };\n}\n\n// ---------------------------------------------------------------------------\n// file_glob\n// ---------------------------------------------------------------------------\n\nconst globSchema = z.object({\n pattern: z.string().min(1).describe(\"Glob pattern matched against POSIX-relative paths from `root`. Supports *, **, ?, and {a,b} alternation. Example: 'src/**/*.{ts,tsx}'.\"),\n root: z.string().optional().describe(\"Directory to search under. Defaults to the active workspace root, or $HOME if no workspace is open. Absolute / ~/ / relative paths accepted.\"),\n include_hidden: z.boolean().optional().describe(\"Include dot-prefixed directories and files. Default false.\"),\n max_results: z.number().int().min(1).max(MAX_GLOB_RESULTS).optional().describe(`Cap on returned matches (default 200, max ${MAX_GLOB_RESULTS}).`),\n});\n\nexport const fileGlobTool = tool(\n async (input, config?: ToolConfig) => {\n const { pattern, root: rawRoot, include_hidden, max_results } = input;\n const { resolve, workspace } = pathResolverFor(config);\n\n let rootAbs: string;\n try {\n rootAbs = rawRoot ? resolve(rawRoot) : (workspace?.root ?? resolve(\".\"));\n assertSafePath(rootAbs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message });\n }\n\n let rootStat: import(\"node:fs\").Stats;\n try {\n rootStat = await withFsDeadline(\"file_glob.stat\", rootAbs, () => fs.stat(rootAbs));\n } catch (err) {\n return JSON.stringify({ ok: false, root: rootAbs, error: (err as Error).message });\n }\n if (!rootStat.isDirectory()) {\n return JSON.stringify({ ok: false, root: rootAbs, error: \"root is not a directory\" });\n }\n\n const re = compileGlob(pattern);\n const cap = max_results ?? 200;\n\n const walked = await withFsDeadline(\"file_glob\", rootAbs, () =>\n walk(rootAbs, { includeHidden: include_hidden, maxFiles: MAX_FILES_SCANNED }),\n );\n\n const matches: string[] = [];\n for (const rel of walked.files) {\n if (re.test(rel)) {\n matches.push(rel);\n if (matches.length >= cap) break;\n }\n }\n\n return JSON.stringify({\n ok: true,\n root: rootAbs,\n pattern,\n matches,\n count: matches.length,\n files_scanned: walked.scanned,\n truncated: walked.truncated || matches.length >= cap,\n truncated_hint: (walked.truncated || matches.length >= cap)\n ? \"Narrow the pattern, raise max_results, or set a more specific root.\"\n : undefined,\n });\n },\n {\n name: \"file_glob\",\n description:\n \"Find files by glob pattern under a directory. Supports *, **, ?, and {a,b} alternation. Skips node_modules/.git/dist/build/.next/coverage/etc by default. Returns POSIX-relative paths from the search root.\",\n schema: globSchema,\n },\n);\n\n// ---------------------------------------------------------------------------\n// file_grep\n// ---------------------------------------------------------------------------\n\nconst grepSchema = z.object({\n pattern: z.string().min(1).describe(\"Search pattern. Regex by default; pass literal=true to treat as a plain substring.\"),\n literal: z.boolean().optional().describe(\"Treat `pattern` as a literal substring instead of a regex. Default false.\"),\n case_insensitive: z.boolean().optional().describe(\"Case-insensitive match. Default false.\"),\n root: z.string().optional().describe(\"Directory to search under. Defaults to the active workspace root, or $HOME.\"),\n glob: z.string().optional().describe(\"Optional file-name glob (e.g. '**/*.ts') to restrict which files are scanned.\"),\n include_hidden: z.boolean().optional().describe(\"Search inside dot-prefixed directories. Default false.\"),\n max_matches: z.number().int().min(1).max(MAX_MATCHES).optional().describe(`Cap on returned matches (default 100, max ${MAX_MATCHES}).`),\n context: z.number().int().min(0).max(5).optional().describe(\"Lines of context to return around each match (default 0).\"),\n});\n\ninterface GrepMatch {\n path: string; // POSIX-relative to root\n line: number; // 1-based\n text: string;\n before?: string[];\n after?: string[];\n}\n\nexport const fileGrepTool = tool(\n async (input, config?: ToolConfig) => {\n const {\n pattern, literal, case_insensitive,\n root: rawRoot, glob, include_hidden,\n max_matches, context,\n } = input;\n const { resolve, workspace } = pathResolverFor(config);\n\n let rootAbs: string;\n try {\n rootAbs = rawRoot ? resolve(rawRoot) : (workspace?.root ?? resolve(\".\"));\n assertSafePath(rootAbs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message });\n }\n\n let re: RegExp;\n try {\n const src = literal ? escapeRegExp(pattern) : pattern;\n re = new RegExp(src, case_insensitive ? \"i\" : \"\");\n } catch (err) {\n return JSON.stringify({ ok: false, error: `invalid pattern: ${(err as Error).message}` });\n }\n\n const fileRe = glob ? compileGlob(glob) : null;\n const cap = max_matches ?? 100;\n const ctx = context ?? 0;\n\n const walked = await withFsDeadline(\"file_grep.walk\", rootAbs, () =>\n walk(rootAbs, { includeHidden: include_hidden, maxFiles: MAX_FILES_SCANNED }),\n );\n\n const matches: GrepMatch[] = [];\n let filesWithMatches = 0;\n let filesScanned = 0;\n let truncated = walked.truncated;\n\n outer: for (const rel of walked.files) {\n if (fileRe && !fileRe.test(rel)) continue;\n const abs = path.join(rootAbs, rel);\n let stat: import(\"node:fs\").Stats;\n try {\n stat = await fs.stat(abs);\n } catch {\n continue;\n }\n if (stat.size > MAX_GREP_FILE_BYTES) continue;\n filesScanned++;\n\n let raw: string;\n try {\n raw = await fs.readFile(abs, \"utf8\");\n } catch {\n continue; // unreadable / binary\n }\n // Quick binary heuristic — if a NUL byte is in the first 8 KB, skip.\n if (raw.length > 0 && raw.indexOf(\"\\u0000\") !== -1) continue;\n\n const lines = raw.split(/\\r?\\n/);\n let fileHadMatch = false;\n for (let i = 0; i < lines.length; i++) {\n // Use exec so we don't share a global regex's lastIndex across calls.\n if (re.test(lines[i])) {\n // Reset lastIndex defensively in case the user passed /g.\n re.lastIndex = 0;\n fileHadMatch = true;\n const text = clipLine(lines[i]);\n const m: GrepMatch = { path: rel, line: i + 1, text };\n if (ctx > 0) {\n m.before = lines.slice(Math.max(0, i - ctx), i).map(clipLine);\n m.after = lines.slice(i + 1, Math.min(lines.length, i + 1 + ctx)).map(clipLine);\n }\n matches.push(m);\n if (matches.length >= cap) {\n truncated = true;\n break outer;\n }\n }\n }\n if (fileHadMatch) filesWithMatches++;\n }\n\n return JSON.stringify({\n ok: true,\n root: rootAbs,\n pattern,\n literal: !!literal,\n case_insensitive: !!case_insensitive,\n glob: glob ?? null,\n matches,\n count: matches.length,\n files_with_matches: filesWithMatches,\n files_scanned: filesScanned,\n truncated,\n truncated_hint: truncated\n ? \"Narrow the pattern, add a glob filter, raise max_matches, or set a more specific root.\"\n : undefined,\n });\n },\n {\n name: \"file_grep\",\n description:\n \"Search file contents under a directory by regex (or literal substring with literal=true). Optional glob filter (e.g. '**/*.ts'). Returns POSIX-relative paths and 1-based line numbers, with optional N-line context. Skips node_modules/.git/etc, binary files (NUL-byte heuristic), and files >1 MB.\",\n schema: grepSchema,\n },\n);\n\nfunction clipLine(s: string): string {\n return s.length > MAX_LINE_BYTES ? `${s.slice(0, MAX_LINE_BYTES)}…[truncated]` : s;\n}\n\n// ---------------------------------------------------------------------------\n// file_multi_edit\n//\n// Applies N anchored str_replace edits to one file atomically: we read\n// once, apply all edits in order to the in-memory buffer, and only write\n// if every edit found exactly one match. If any edit fails (no match or\n// multiple matches), the file is left untouched and we return per-edit\n// status so the agent knows which one to fix.\n// ---------------------------------------------------------------------------\n\nconst multiEditSchema = z.object({\n path: z.string().describe(\"File path. Absolute / ~/ / relative to workspace root.\"),\n edits: z\n .array(z.object({\n old_string: z.string().min(1).describe(\"Exact literal substring to replace. Must match EXACTLY ONCE in the (current, partially-edited) buffer at the time it's applied.\"),\n new_string: z.string().describe(\"Replacement text. May be empty to delete.\"),\n }))\n .min(1)\n .max(MAX_MULTI_EDITS)\n .describe(`Up to ${MAX_MULTI_EDITS} edits, applied in order. All-or-nothing: if any edit fails to find exactly one match, the file is not modified.`),\n});\n\nexport const fileMultiEditTool = tool(\n async ({ path: filePath, edits }, config?: ToolConfig) => {\n let abs = filePath;\n try {\n abs = pathResolverFor(config).resolve(filePath);\n assertSafePath(abs, \"write\");\n\n const raw = await withFsDeadline(\"file_multi_edit.read\", abs, () => fs.readFile(abs, \"utf8\"));\n let buf = raw;\n const results: Array<{ index: number; ok: boolean; match_count?: number; error?: string }> = [];\n let failed = false;\n\n for (let i = 0; i < edits.length; i++) {\n const { old_string, new_string } = edits[i];\n const first = buf.indexOf(old_string);\n if (first === -1) {\n results.push({\n index: i, ok: false,\n error: \"old_string not found in the current buffer (note: earlier edits may have already changed it).\",\n });\n failed = true;\n continue;\n }\n const second = buf.indexOf(old_string, first + old_string.length);\n if (second !== -1) {\n const count = buf.split(old_string).length - 1;\n results.push({\n index: i, ok: false, match_count: count,\n error: \"old_string matches multiple times. Add surrounding context to make it unique.\",\n });\n failed = true;\n continue;\n }\n buf = buf.slice(0, first) + new_string + buf.slice(first + old_string.length);\n results.push({ index: i, ok: true });\n }\n\n if (failed) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"one or more edits failed; file was not modified\",\n edits: results,\n });\n }\n\n await withFsDeadline(\"file_multi_edit.write\", abs, () => fs.writeFile(abs, buf, \"utf8\"));\n return JSON.stringify({\n ok: true,\n path: abs,\n edits_applied: edits.length,\n bytes_before: Buffer.byteLength(raw, \"utf8\"),\n bytes_after: Buffer.byteLength(buf, \"utf8\"),\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_multi_edit\",\n description:\n \"Apply multiple anchored str_replace edits to one file atomically. Each edit's old_string must match EXACTLY ONCE in the (partially-edited) buffer at the time it's applied. All-or-nothing: if any edit fails, the file is not modified and per-edit status is returned. Prefer this over multiple file_edit round-trips when refactoring within a single file.\",\n schema: multiEditSchema,\n },\n);\n\n// Reference getConfig so dead-code elimination doesn't drop the import —\n// used indirectly via withFsDeadline / assertSafePath, but keeping a\n// direct reference helps the typecheck if those signatures ever change.\nvoid getConfig;\n\nregisterTools(\"Files\", \"read\", [fileGlobTool, fileGrepTool]);\nregisterTools(\"Files\", \"write\", [fileMultiEditTool]);\n","// `workspace_init` / `workspace_status` / `workspace_close`.\n//\n// Single agent-driven entry point for \"I am working in this directory\".\n// Returns a context bundle so the agent doesn't have to make a dozen\n// exploratory shell calls before it can start working: git state,\n// detected language / package manager / scripts, README head,\n// convention files (CLAUDE.md, CONTRIBUTING.md, ADR dir).\n//\n// Once set, every `file_*` and `local_exec` call with a relative path\n// resolves against the workspace root instead of the user's HOME.\n// Absolute paths are honoured as-is. Set `scoped: true` to refuse\n// absolute paths outside the root (off by default so the agent can\n// still read e.g. ~/Downloads to copy a file into the project).\n\nimport { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n currentWorkspace,\n setWorkspace,\n clearWorkspace,\n type ToolConfig,\n} from \"./workspace-context\";\n\nconst execFileP = promisify(execFile);\n\n// Probe budget. Keep generous enough for slow filesystems but short\n// enough that the agent isn't blocked for tens of seconds on a stalled\n// cloud-sync provider.\nconst PROBE_TIMEOUT_MS = 8_000;\n\nconst MAX_TREE_DEFAULT = 200;\nconst MAX_TREE_HARD_CAP = 1_000;\nconst README_MAX_BYTES = 2_048;\n\n// Reuse the credential denylist shape from files.ts — keep this list in\n// sync if files.ts grows new sensitive bases. We intentionally don't\n// import from files.ts to avoid a tight coupling; workspace_init is the\n// only place where the *whole root* is gated (file tools gate per call).\nfunction sensitiveRoots(): 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 process.env.JARELA_DB_DIR\n ? path.resolve(process.env.JARELA_DB_DIR)\n : path.join(home, \".jarela\"),\n ];\n}\n\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 resolveAgentPath(p: string): string {\n let s = p.trim();\n if (!s) throw new Error(\"path is required\");\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\nasync function withTimeout<T>(label: string, p: Promise<T>): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${PROBE_TIMEOUT_MS}ms`)),\n PROBE_TIMEOUT_MS,\n );\n });\n try {\n return await Promise.race([p, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\ninterface GitProbe {\n is_repo: boolean;\n branch?: string;\n remote?: string;\n head?: string;\n dirty?: boolean;\n untracked_count?: number;\n}\n\nasync function probeGit(root: string): Promise<GitProbe> {\n // `git rev-parse --is-inside-work-tree` is the canonical \"is this a repo?\" check.\n try {\n await execFileP(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], { cwd: root, timeout: PROBE_TIMEOUT_MS });\n } catch {\n return { is_repo: false };\n }\n const out: GitProbe = { is_repo: true };\n const safe = async (args: string[]): Promise<string> => {\n try {\n const { stdout } = await execFileP(\"git\", args, { cwd: root, timeout: PROBE_TIMEOUT_MS });\n return stdout.trim();\n } catch {\n return \"\";\n }\n };\n const [branch, head, remote, status] = await Promise.all([\n safe([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"]),\n safe([\"rev-parse\", \"--short\", \"HEAD\"]),\n safe([\"config\", \"--get\", \"remote.origin.url\"]),\n safe([\"status\", \"--porcelain\"]),\n ]);\n if (branch) out.branch = branch;\n if (head) out.head = head;\n if (remote) out.remote = remote;\n if (status !== undefined) {\n const lines = status ? status.split(/\\r?\\n/) : [];\n out.dirty = lines.length > 0;\n out.untracked_count = lines.filter((l) => l.startsWith(\"??\")).length;\n }\n return out;\n}\n\ninterface PackageManifest {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n packageManager?: string;\n}\n\nasync function readJsonIfExists(p: string): Promise<PackageManifest | null> {\n try {\n const raw = await fs.readFile(p, \"utf8\");\n return JSON.parse(raw) as PackageManifest;\n } catch {\n return null;\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function detectPackageManager(root: string, pkg: PackageManifest | null): Promise<string> {\n if (pkg?.packageManager) {\n const pm = pkg.packageManager.split(\"@\")[0];\n if (pm) return pm;\n }\n if (await fileExists(path.join(root, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (await fileExists(path.join(root, \"yarn.lock\"))) return \"yarn\";\n if (await fileExists(path.join(root, \"bun.lockb\"))) return \"bun\";\n if (await fileExists(path.join(root, \"package-lock.json\"))) return \"npm\";\n if (await fileExists(path.join(root, \"Pipfile\"))) return \"pipenv\";\n if (await fileExists(path.join(root, \"poetry.lock\"))) return \"poetry\";\n if (await fileExists(path.join(root, \"requirements.txt\"))) return \"pip\";\n if (await fileExists(path.join(root, \"Cargo.toml\"))) return \"cargo\";\n if (await fileExists(path.join(root, \"go.mod\"))) return \"go\";\n return \"none\";\n}\n\nfunction detectTestRunner(pkg: PackageManifest | null): string | undefined {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n if (deps.vitest) return \"vitest\";\n if (deps.jest) return \"jest\";\n if (deps.mocha) return \"mocha\";\n if (deps.ava) return \"ava\";\n if (pkg?.scripts?.test) return \"npm:test\";\n return undefined;\n}\n\nfunction detectFrameworks(pkg: PackageManifest | null): string[] {\n const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };\n const out: string[] = [];\n if (deps.next) out.push(\"next\");\n if (deps.react) out.push(\"react\");\n if (deps.vue) out.push(\"vue\");\n if (deps.svelte) out.push(\"svelte\");\n if (deps[\"@angular/core\"]) out.push(\"angular\");\n if (deps.express) out.push(\"express\");\n if (deps.fastify) out.push(\"fastify\");\n if (deps.tailwindcss) out.push(\"tailwind\");\n if (deps[\"@langchain/core\"]) out.push(\"langchain\");\n return out;\n}\n\nasync function parseMakefileTargets(root: string): Promise<string[]> {\n const p = path.join(root, \"Makefile\");\n try {\n const raw = await fs.readFile(p, \"utf8\");\n const targets: string[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n // Match `target:` or `target: dep1 dep2` but skip variable assignments\n // and indented recipe lines.\n const m = /^([A-Za-z0-9_.-]+)\\s*:(?!=)/.exec(line);\n if (m && !line.startsWith(\"\\t\")) targets.push(m[1]);\n }\n // Dedupe preserving order; cap at 50.\n return Array.from(new Set(targets)).slice(0, 50);\n } catch {\n return [];\n }\n}\n\nasync function detectLanguages(root: string): Promise<string[]> {\n const found = new Set<string>();\n // Quick scan: top-level + one level of children. Avoids full recursive walk.\n try {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n if (e.isFile()) markLanguage(e.name, found);\n }\n if (await fileExists(path.join(root, \"tsconfig.json\"))) found.add(\"typescript\");\n if (await fileExists(path.join(root, \"go.mod\"))) found.add(\"go\");\n if (await fileExists(path.join(root, \"Cargo.toml\"))) found.add(\"rust\");\n if (await fileExists(path.join(root, \"pyproject.toml\"))) found.add(\"python\");\n if (await fileExists(path.join(root, \"pom.xml\"))) found.add(\"java\");\n if (await fileExists(path.join(root, \"build.gradle\")) || await fileExists(path.join(root, \"build.gradle.kts\"))) found.add(\"java\");\n } catch {\n /* ignore */\n }\n return Array.from(found);\n}\n\nfunction markLanguage(filename: string, into: Set<string>): void {\n const ext = path.extname(filename).toLowerCase();\n const map: Record<string, string> = {\n \".ts\": \"typescript\", \".tsx\": \"typescript\",\n \".js\": \"javascript\", \".jsx\": \"javascript\", \".mjs\": \"javascript\", \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\", \".kt\": \"kotlin\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n \".cs\": \"csharp\",\n \".swift\": \"swift\",\n };\n const l = map[ext];\n if (l) into.add(l);\n}\n\n// Lightweight directory tree honouring a small ignore list. We don't\n// fully parse .gitignore — that's a heavy dep for this probe; the\n// default ignores cover the 95% case (node_modules, .git, dist, build,\n// .next, coverage, __pycache__, target, vendor). Returns at most\n// `maxEntries` rows; sets `truncated=true` if more existed.\ninterface TreeEntry {\n path: string;\n kind: \"file\" | \"dir\";\n size?: number;\n}\n\nconst DEFAULT_IGNORE = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"out\",\n \"coverage\", \"__pycache__\", \"target\", \"vendor\", \".venv\", \"venv\",\n \".turbo\", \".cache\", \".idea\", \".vscode\",\n]);\n\nasync function buildTree(\n root: string,\n maxEntries: number,\n): Promise<{ entries: TreeEntry[]; truncated: boolean }> {\n const entries: TreeEntry[] = [];\n let truncated = false;\n\n async function walk(dirAbs: string, dirRel: string, depth: number): Promise<void> {\n if (entries.length >= maxEntries) {\n truncated = true;\n return;\n }\n if (depth > 4) return; // hard depth cap to keep probe bounded\n let kids: import(\"node:fs\").Dirent[];\n try {\n kids = await fs.readdir(dirAbs, { withFileTypes: true });\n } catch {\n return;\n }\n kids.sort((a, b) => {\n // dirs first, then files; alpha within group\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n for (const k of kids) {\n if (entries.length >= maxEntries) {\n truncated = true;\n return;\n }\n if (DEFAULT_IGNORE.has(k.name)) continue;\n const childAbs = path.join(dirAbs, k.name);\n const childRel = dirRel ? `${dirRel}/${k.name}` : k.name;\n if (k.isDirectory()) {\n entries.push({ path: `${childRel}/`, kind: \"dir\" });\n await walk(childAbs, childRel, depth + 1);\n } else if (k.isFile()) {\n let size: number | undefined;\n try {\n const st = await fs.stat(childAbs);\n size = st.size;\n } catch {\n /* ignore */\n }\n entries.push({ path: childRel, kind: \"file\", size });\n }\n }\n }\n\n await walk(root, \"\", 0);\n return { entries, truncated };\n}\n\nasync function readReadme(root: string): Promise<{ path: string; head: string; truncated: boolean } | null> {\n try {\n const entries = await fs.readdir(root);\n const candidate = entries.find((e) => /^readme(\\.[a-z0-9]+)?$/i.test(e));\n if (!candidate) return null;\n const abs = path.join(root, candidate);\n const raw = await fs.readFile(abs, \"utf8\");\n const head = raw.slice(0, README_MAX_BYTES);\n return { path: candidate, head, truncated: raw.length > README_MAX_BYTES };\n } catch {\n return null;\n }\n}\n\nasync function detectConventionFiles(root: string): Promise<{\n claude_md: string | null;\n agents_md: string | null;\n contributing_md: string | null;\n adr_dir: string | null;\n}> {\n const claude = (await fileExists(path.join(root, \"CLAUDE.md\"))) ? \"CLAUDE.md\" : null;\n const agents = (await fileExists(path.join(root, \"AGENTS.md\"))) ? \"AGENTS.md\" : null;\n const contributing = (await fileExists(path.join(root, \"CONTRIBUTING.md\"))) ? \"CONTRIBUTING.md\" : null;\n // ADR dir conventions: docs/adr, docs/decisions, adr\n let adrDir: string | null = null;\n for (const candidate of [\"docs/adr\", \"docs/decisions\", \"adr\"]) {\n if (await fileExists(path.join(root, candidate))) {\n adrDir = candidate;\n break;\n }\n }\n return { claude_md: claude, agents_md: agents, contributing_md: contributing, adr_dir: adrDir };\n}\n\n// Build the prioritised required-reading list the agent MUST read before\n// taking any other action. Order matters — earlier entries are higher\n// priority. We resolve each candidate to (relative path, byte size) so\n// the agent knows what it's about to spend tokens on.\n//\n// We deliberately do NOT inline contents here: the agent already has\n// file_read for that, the user sees the read calls in the tool stream,\n// and large convention files don't get force-loaded on every init.\nasync function buildRequiredReading(\n root: string,\n conventions: Awaited<ReturnType<typeof detectConventionFiles>>,\n readme: { path: string } | null,\n extra: string[],\n): Promise<Array<{ path: string; bytes: number; reason: string }>> {\n const seen = new Set<string>();\n const out: Array<{ path: string; bytes: number; reason: string }> = [];\n\n const push = async (rel: string | null, reason: string): Promise<void> => {\n if (!rel || seen.has(rel)) return;\n try {\n const st = await fs.stat(path.join(root, rel));\n if (!st.isFile()) return;\n seen.add(rel);\n out.push({ path: rel, bytes: st.size, reason });\n } catch {\n /* file vanished between detect and stat — skip */\n }\n };\n\n // Priority order:\n // 1. CLAUDE.md / AGENTS.md — agent-specific operating instructions.\n // 2. CONTRIBUTING.md — contribution + commit + release rules.\n // 3. README.md — project overview & invariants.\n // 4. Top-level ADR index — architectural decisions if a docs/adr exists.\n // 5. Caller-supplied extras — project-specific must-reads.\n await push(conventions.claude_md, \"agent operating instructions\");\n await push(conventions.agents_md, \"agent operating instructions\");\n await push(conventions.contributing_md, \"contribution + commit + release rules\");\n await push(readme?.path ?? null, \"project overview\");\n\n if (conventions.adr_dir) {\n for (const idx of [\"README.md\", \"index.md\", \"0000-index.md\"]) {\n const rel = `${conventions.adr_dir}/${idx}`;\n await push(rel, \"architectural decision records (index)\");\n }\n }\n\n for (const extraPath of extra) {\n const cleaned = extraPath.trim();\n if (!cleaned) continue;\n // Refuse absolute paths or parent-escape — required_reading is always\n // workspace-relative so the agent can't be coaxed into reading\n // /etc/passwd via a prompt-injected init call.\n if (path.isAbsolute(cleaned) || cleaned.startsWith(\"..\") || cleaned.split(/[\\\\/]/).includes(\"..\")) {\n continue;\n }\n await push(cleaned.replace(/\\\\/g, \"/\"), \"caller-supplied\");\n }\n\n return out;\n}\n\n// --- init ---------------------------------------------------------------\n\nconst initSchema = z.object({\n path: z.string().describe(\"Project root directory. Absolute or ~/foo; bare relative paths resolve against the user's HOME.\"),\n scoped: z.boolean().optional().describe(\"When true, later file_*/local_exec calls refuse absolute paths outside the root. Default false.\"),\n include_tree: z.boolean().optional().describe(\"Include a bounded directory tree in the response. Default true.\"),\n max_tree_entries: z.number().int().min(0).max(MAX_TREE_HARD_CAP).optional().describe(`Cap on tree rows. Default ${MAX_TREE_DEFAULT}, max ${MAX_TREE_HARD_CAP}.`),\n include_git: z.boolean().optional().describe(\"Probe git state. Default true.\"),\n include_scripts: z.boolean().optional().describe(\"Parse package.json scripts and Makefile targets. Default true.\"),\n include_readme: z.boolean().optional().describe(\"Return the head of the project README. Default true.\"),\n extra_required_reading: z\n .array(z.string())\n .optional()\n .describe(\"Additional workspace-relative paths to append to required_reading. Absolute paths and '..' segments are rejected.\"),\n});\n\nexport const workspaceInitTool = tool(\n async (input, config?: ToolConfig) => {\n const {\n path: rawPath,\n scoped = false,\n include_tree = true,\n max_tree_entries,\n include_git = true,\n include_scripts = true,\n include_readme = true,\n extra_required_reading = [],\n } = input;\n\n let abs: string;\n try {\n abs = resolveAgentPath(rawPath);\n } catch (err) {\n return JSON.stringify({ ok: false, error: (err as Error).message, code: \"WORKSPACE_BAD_PATH\" });\n }\n\n // Validate the path exists and is a directory.\n let stat: import(\"node:fs\").Stats;\n try {\n stat = await withTimeout(\"workspace_init.stat\", fs.stat(abs));\n } catch (err) {\n const msg = (err as Error).message;\n const code = msg.includes(\"ENOENT\") ? \"WORKSPACE_NOT_FOUND\" : msg.includes(\"timed out\") ? \"WORKSPACE_TIMEOUT\" : \"WORKSPACE_ERROR\";\n return JSON.stringify({ ok: false, path: abs, error: msg, code });\n }\n if (!stat.isDirectory()) {\n return JSON.stringify({ ok: false, path: abs, error: \"path is not a directory\", code: \"WORKSPACE_NOT_DIR\" });\n }\n\n // Sensitive-root guard. Override by setting JARELA_ALLOW_SENSITIVE_FILES=1\n // (same opt-out as the per-file denylist in files.ts).\n if (process.env.JARELA_ALLOW_SENSITIVE_FILES !== \"1\") {\n for (const base of sensitiveRoots()) {\n if (isInside(abs, base)) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: `refused: '${abs}' is inside a sensitive directory (${path.basename(base)}). Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n code: \"WORKSPACE_SENSITIVE\",\n });\n }\n }\n }\n\n // Install the workspace before probing — so probe-time errors don't\n // leave the agent without an active workspace.\n setWorkspace({ root: abs, scoped, opened_at: Date.now() }, config);\n\n // Probe everything in parallel and tolerate individual failures.\n const pkg = include_scripts ? await readJsonIfExists(path.join(abs, \"package.json\")) : null;\n\n const [git, languages, packageManager, makefileTargets, tree, readme, conventions, hasDockerfile, hasDevcontainer] = await Promise.all([\n include_git ? withTimeout(\"workspace_init.git\", probeGit(abs)).catch(() => ({ is_repo: false } as GitProbe)) : Promise.resolve({ is_repo: false } as GitProbe),\n detectLanguages(abs),\n include_scripts ? detectPackageManager(abs, pkg) : Promise.resolve(\"none\"),\n include_scripts ? parseMakefileTargets(abs) : Promise.resolve([] as string[]),\n include_tree\n ? buildTree(abs, Math.min(max_tree_entries ?? MAX_TREE_DEFAULT, MAX_TREE_HARD_CAP))\n : Promise.resolve({ entries: [] as TreeEntry[], truncated: false }),\n include_readme ? readReadme(abs) : Promise.resolve(null),\n detectConventionFiles(abs),\n fileExists(path.join(abs, \"Dockerfile\")),\n fileExists(path.join(abs, \".devcontainer\", \"devcontainer.json\")),\n ]);\n\n return JSON.stringify({\n ok: true,\n root: abs,\n scoped,\n git,\n project: {\n languages,\n package_manager: packageManager,\n framework_hints: detectFrameworks(pkg),\n test_runner: detectTestRunner(pkg),\n scripts: pkg?.scripts ?? {},\n makefile_targets: makefileTargets,\n has_dockerfile: hasDockerfile,\n has_devcontainer: hasDevcontainer,\n },\n tree: include_tree ? tree : undefined,\n readme,\n conventions,\n required_reading: await buildRequiredReading(abs, conventions, readme, extra_required_reading),\n });\n },\n {\n name: \"workspace_init\",\n description:\n \"Register a project directory as the active workspace for this thread and return its context bundle (git state, languages, scripts, tree, README head, convention files, required_reading). After this call, file_*/local_exec calls with relative paths resolve against the workspace root instead of $HOME. Call this once at the start of any coding task. CRITICAL: the response includes a `required_reading` array of workspace-relative documentation files (CLAUDE.md, AGENTS.md, CONTRIBUTING.md, README, ADR index, plus any caller-supplied extras). You MUST `file_read` every entry in `required_reading` before taking any other action (no edits, no shell commands, no further tool calls beyond file_read for those paths). These files define the project's contribution rules, commit format, release process, and architectural invariants — skipping them produces output that fails review.\",\n schema: initSchema,\n },\n);\n\n// --- status -------------------------------------------------------------\n\nexport const workspaceStatusTool = tool(\n async (_input, config?: ToolConfig) => {\n const ws = currentWorkspace(config);\n if (!ws) {\n return JSON.stringify({ ok: true, active: false });\n }\n // Re-probe git state cheaply — that's the only field that drifts.\n const git = await probeGit(ws.root).catch(() => ({ is_repo: false } as GitProbe));\n return JSON.stringify({\n ok: true,\n active: true,\n root: ws.root,\n scoped: ws.scoped,\n opened_at: ws.opened_at,\n git,\n });\n },\n {\n name: \"workspace_status\",\n description:\n \"Return the currently active workspace (if any) plus fresh git status. Cheap — no tree walk. Use to check 'am I where I think I am?' before destructive operations.\",\n schema: z.object({}).describe(\"No arguments.\"),\n },\n);\n\n// --- close --------------------------------------------------------------\n\nexport const workspaceCloseTool = tool(\n async (_input, config?: ToolConfig) => {\n const cleared = clearWorkspace(config);\n return JSON.stringify({ ok: true, was_active: cleared });\n },\n {\n name: \"workspace_close\",\n description:\n \"Clear the active workspace for this thread. Subsequent file_*/local_exec calls with relative paths return to resolving against $HOME / process cwd.\",\n schema: z.object({}).describe(\"No arguments.\"),\n },\n);\n\nregisterTools(\"Files\", \"read\", [workspaceInitTool, workspaceStatusTool, workspaceCloseTool]);\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(/&/g, \"&\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/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\", \"read\", [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\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// JARELA_FETCH_TOOL_MAX_BYTES overrides the byte cap.\nfunction maxBytes(): number { return getConfig().fetchToolMaxBytes; }\n// Internal cap on a single fetch. The agent's wall-clock budget on the\n// tool call (see lib/tools/wallclock.ts) is the primary deadline; this is\n// a leak backstop that actually closes the socket via AbortController so a\n// stuck server can't tie up an fd indefinitely.\nconst FETCH_INTERNAL_TIMEOUT_MS = 120_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 ``. 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_MS = FETCH_INTERNAL_TIMEOUT_MS;\n const MAX_BYTES = maxBytes();\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 const aborted = ctrl.signal.aborted\n || (err instanceof Error && (err.name === \"AbortError\" || /abort/i.test(msg)));\n if (aborted) {\n return JSON.stringify({\n url,\n error: `timed out after ${Math.round(TIMEOUT_MS / 1000)}s. The page is slow or unresponsive — try a different URL or pass a larger deadline_ms.`,\n timed_out: true,\n timeout_ms: TIMEOUT_MS,\n });\n }\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 `` 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\", \"read\", [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\", \"read\", [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 ``.\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) => ``).join(\"\\n\\n\"),\n hint: \"Embed images in your reply using the `markdown` field verbatim, or build your own `` 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 ``. 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\", \"execute\", [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\", \"execute\", [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\", \"read\", [listScheduledTasksTool]);\nregisterTools(\"Schedule\", \"write\", [scheduleTaskTool, 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\", \"read\", [listWatchersTool, listReactionScriptsTool]);\nregisterTools(\"Schedule\", \"write\", [scheduleWatcherTool, cancelWatcherTool]);\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\", \"read\", [checkProposalTool]);\nregisterTools(\"Config\", \"write\", [proposeConfigChangeTool]);\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\", \"read\", [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, subject, 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 // `subject` is accepted as an alias for `summary` so agents trained on\n // Outlook vocabulary don't fail the schema on first try.\n const eventSummary = summary ?? subject;\n if (!eventSummary) {\n return JSON.stringify({ error: \"summary (or subject) is required\" });\n }\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: eventSummary,\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).optional().describe(\"Event title shown on the calendar (alias: subject)\"),\n subject: z.string().min(1).optional().describe(\"Alias for summary (Outlook vocabulary)\"),\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, subject, 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 const eventSummary = summary ?? subject;\n if (eventSummary !== undefined) patch.summary = eventSummary;\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 (alias: subject)\"),\n subject: z.string().optional().describe(\"Alias for summary (Outlook vocabulary)\"),\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\", \"read\", [\n calendarListCalendarsTool, calendarListEventsTool, calendarGetEventTool,\n]);\nregisterTools(\"Calendar\", \"write\", [\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, summary, 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 // `summary` is accepted as an alias for `subject` so agents trained on\n // Google Calendar's vocabulary don't fail the schema on first try.\n const eventSubject = subject ?? summary;\n if (!eventSubject) {\n return JSON.stringify({ error: \"subject (or summary) is required\" });\n }\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: eventSubject,\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).optional().describe(\"Event title shown on the calendar (alias: summary)\"),\n summary: z.string().min(1).optional().describe(\"Alias for subject (Google Calendar vocabulary)\"),\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, summary, 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 const eventSubject = subject ?? summary;\n if (eventSubject !== undefined) patch.subject = eventSubject;\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 (alias: summary)\"),\n summary: z.string().optional().describe(\"Alias for subject (Google Calendar vocabulary)\"),\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\", \"read\", [\n outlookCalendarListCalendarsTool, outlookCalendarListEventsTool, outlookCalendarGetEventTool,\n]);\nregisterTools(\"Calendar\", \"write\", [\n outlookCalendarCreateEventTool, outlookCalendarUpdateEventTool, outlookCalendarDeleteEventTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport {\n getAgentConfig,\n parseDelegateTargets,\n} from \"@/lib/stores/agent-configs\";\nimport { getThread, getOrCreateAgentThread } from \"@/lib/stores/threads\";\nimport {\n MAX_DELEGATION_DEPTH,\n prepareThreadRun,\n persistAssistantMessage,\n} from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { enqueueThreadRun } from \"@/lib/agents/run-queue\";\nimport { resolveTurnProfile } from \"@/lib/agents/turn-profile\";\n\ninterface DelegateContext {\n parentAgentId: string;\n depth: number;\n ancestors: readonly string[];\n}\n\nfunction readDelegateContext(config?: RunnableConfig): DelegateContext | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n if (!thread) return null;\n const depth = (config?.configurable?.delegation_depth as number | undefined) ?? 0;\n const ancestorsRaw = config?.configurable?.delegation_ancestors as\n | readonly string[]\n | undefined;\n const ancestors = Array.isArray(ancestorsRaw) ? ancestorsRaw : [];\n return { parentAgentId: thread.agent_id, depth, ancestors };\n}\n\nfunction fail(code: string, message: string, extra: Record<string, unknown> = {}): string {\n return JSON.stringify({ ok: false, error_code: code, message, ...extra });\n}\n\nexport const delegateToAgentTool = tool(\n async ({ agent_id, task }, config) => {\n const ctx = readDelegateContext(config);\n if (!ctx) return fail(\"no_context\", \"No agent context (missing thread_id)\");\n\n const parent = getAgentConfig(ctx.parentAgentId);\n if (!parent) return fail(\"agent_not_found\", `Parent agent \"${ctx.parentAgentId}\" not found`);\n\n if (agent_id === ctx.parentAgentId) {\n return fail(\"cycle_detected\", \"Cannot delegate to self\");\n }\n if (ctx.ancestors.includes(agent_id)) {\n return fail(\"cycle_detected\", `Delegation cycle: ${agent_id} is already in the chain [${ctx.ancestors.join(\" -> \")}]`);\n }\n if (ctx.depth >= MAX_DELEGATION_DEPTH) {\n return fail(\n \"depth_exceeded\",\n `Maximum delegation depth (${MAX_DELEGATION_DEPTH}) reached. Chain: [${[...ctx.ancestors, ctx.parentAgentId].join(\" -> \")}]`,\n );\n }\n\n const roster = parseDelegateTargets(parent.delegate_targets);\n if (!roster.includes(agent_id)) {\n return fail(\n \"not_in_roster\",\n `Agent \"${agent_id}\" is not in the delegate roster for \"${parent.id}\". Available: [${roster.join(\", \") || \"none\"}]`,\n );\n }\n\n const child = getAgentConfig(agent_id);\n if (!child) return fail(\"agent_not_found\", `Delegate agent \"${agent_id}\" not found`);\n\n const childThread = getOrCreateAgentThread(agent_id);\n const startedAt = Date.now();\n\n try {\n // Serialise on the child thread_id with every other entry point\n // (HTTP POST, scheduler, watcher, bridge, sibling delegations) —\n // see lib/agents/run-queue.ts. A delegate fired while the child is\n // already running waits in the child's queue instead of racing the\n // checkpoint store.\n const queued = await enqueueThreadRun(childThread.thread_id, \"delegate\", async () => {\n const prepared = await prepareThreadRun({\n thread_id: childThread.thread_id,\n message: task,\n user_category: \"delegation\",\n context_profile: resolveTurnProfile(\"delegate\"),\n _delegation_depth: ctx.depth + 1,\n _delegation_ancestors: [...ctx.ancestors, ctx.parentAgentId],\n });\n const collected = await collectStream(prepared.stream);\n if (collected.terminal !== \"error\") {\n persistAssistantMessage(\n childThread.thread_id,\n collected.assistantContent,\n collected.usedTools,\n collected.toolEvents,\n \"delegation\",\n collected.usage ?? null,\n prepared.context_snapshot ?? null,\n prepared.source_manifest ?? null,\n );\n }\n return collected;\n }).result;\n const elapsed_ms = Date.now() - startedAt;\n\n if (queued.terminal === \"error\") {\n return fail(\"child_error\", queued.errorMessage ?? \"Child agent run failed\", {\n agent_id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n });\n }\n\n return JSON.stringify({\n ok: true,\n agent_id: child.id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n depth: ctx.depth + 1,\n result: queued.assistantContent.trim(),\n used_tools: Array.from(new Set(queued.usedTools)),\n elapsed_ms,\n // Ready-to-paste markdown link the parent agent can drop into its\n // reply so the user can trace the summary back to the delegate's\n // full thread. The chat UI resolves `?thread=<tid>&agent=<aid>`\n // via parseHref → SELECT_THREAD, which atomically sets both\n // activeThreadId and activeAgentId (chat tab won't render the\n // thread without the agent id).\n cite_as: `[${child.name}'s reply](?thread=${childThread.thread_id}&agent=${child.id})`,\n });\n } catch (err) {\n return fail(\"child_error\", err instanceof Error ? err.message : String(err), {\n agent_id,\n agent_name: child.name,\n thread_id: childThread.thread_id,\n });\n }\n },\n {\n name: \"delegate_to_agent\",\n description:\n \"Hand a subtask to another agent that has specialized knowledge or tools you lack. \" +\n \"The delegate runs in its own thread; the user sees a tool card with the delegate's name, \" +\n \"the task you sent, and the delegate's final answer (plus a link to open the delegate's thread). \" +\n \"Only delegate when the target agent is genuinely better-suited — do NOT delegate trivial subtasks \" +\n \"you can handle yourself. Before calling this tool, tell the user in one sentence which agent you \" +\n \"are handing to and why. Available delegate ids are listed in the 'Available delegates' system \" +\n \"section; calling with an id outside that list will be refused.\",\n schema: z.object({\n agent_id: z.string().describe(\n \"The id of the delegate agent. Must appear in the 'Available delegates' list in your system prompt.\",\n ),\n task: z.string().min(1).describe(\n \"A self-contained task description for the delegate. Include all context the delegate needs — \" +\n \"the delegate does NOT see your conversation history with the user, only this task string.\",\n ),\n }),\n },\n);\n\nregisterTools(\"Agent\", \"execute\", [delegateToAgentTool]);\n","// Agent-callable knobs for the JARELA_* override store.\n//\n// Both tools are gated by the per-var schema flag `agentWritable` —\n// agents cannot write to anything not flagged true (defaults to false).\n// `restart_server` is only wired here; agents still need the tool to be\n// in their selected toolset to call it (default agents do not include\n// these).\n//\n// Use cases the user explicitly asked to support:\n// - \"agent, lower the run idle timeout to 30s and restart\"\n// - \"agent, switch the log level to debug for the next hour\"\n//\n// We surface the schema's tier/restart flags in the response so the\n// agent's reply can tell the user what changed and whether a restart\n// fired (or is needed but skipped).\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { envSchemaByName } from \"@/lib/env/schema\";\nimport { patchOverride, validateForSchema } from \"@/lib/env/overrides\";\nimport { resetConfigCache } from \"@/lib/env/config\";\n\nconst setEnvSchema = z.object({\n name: z.string().describe(\"Env var name. Must be a JARELA_* knob the schema flags as agent-writable; otherwise the call returns code=forbidden.\"),\n value: z\n .string()\n .nullable()\n .describe(\"New value as a string (numbers/bools come as their string form: '5000' / 'true'). Pass null to clear the override and revert to the default.\"),\n reason: z\n .string()\n .optional()\n .describe(\"Short note explaining the change — logged for postmortems.\"),\n});\n\nconst setEnvVar = tool(\n async ({ name, value, reason }) => {\n const def = envSchemaByName().get(name);\n if (!def) {\n return JSON.stringify({\n ok: false,\n code: \"unknown_var\",\n error: `unknown env var: ${name}`,\n hint: \"List the schema with /api/v1/env (GET) before guessing names. Only JARELA_* keys defined in lib/env/schema.ts are accepted.\",\n });\n }\n if (!def.agentWritable) {\n return JSON.stringify({\n ok: false,\n code: \"forbidden\",\n error: `${name} is not flagged agentWritable in the schema`,\n hint: \"Agents cannot edit infra knobs (port, hostname, dataDir, …). Tell the user to change this from the Environment panel themselves.\",\n });\n }\n if (value !== null) {\n const verr = validateForSchema(def, value);\n if (verr) {\n return JSON.stringify({\n ok: false,\n code: \"invalid_value\",\n error: `${name}: ${verr}`,\n hint: \"Re-issue the call with a value that matches the schema's type/min/max/enum.\",\n });\n }\n }\n await patchOverride(name, value);\n if (value === null) delete process.env[name];\n else process.env[name] = value;\n resetConfigCache();\n return JSON.stringify({\n ok: true,\n name,\n value,\n requiresRestart: def.requiresRestart,\n reason: reason ?? null,\n hint: def.requiresRestart\n ? \"Override persisted. The change requires a server restart — call restart_server to apply, OR tell the user to click Restart in the Environment panel.\"\n : \"Override persisted and is in effect immediately. No restart needed.\",\n });\n },\n {\n name: \"set_env_var\",\n description:\n \"Set or unset a JARELA_* runtime override. Only schema-flagged agent-writable knobs are accepted; everything else returns code=forbidden. Use this when the user explicitly asks to change a runtime setting (e.g. log level, retry budget). Pair with restart_server when the result reports requiresRestart=true.\",\n schema: setEnvSchema,\n },\n);\n\nconst restartSchema = z.object({\n reason: z.string().min(1).describe(\"Why the restart is needed (logged + included in /api/v1/system/restart payload). Required.\"),\n});\n\nconst restartServer = tool(\n async ({ reason }) => {\n // Use the same endpoint the UI hits. Doing it via fetch instead of\n // calling process.exit() directly here means the request response\n // flushes back to the agent (and through it, the user) before the\n // process tears down.\n try {\n const port = Number(process.env.JARELA_PORT ?? process.env.PORT ?? 4312);\n const host = process.env.JARELA_HOSTNAME ?? process.env.HOSTNAME ?? \"127.0.0.1\";\n const r = await fetch(`http://${host}:${port}/api/v1/system/restart`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ reason: `[agent] ${reason}` }),\n });\n const body = (await r.json().catch(() => ({}))) as { hint?: string };\n return JSON.stringify({\n ok: r.ok,\n status: r.status,\n reason,\n hint: body.hint ?? \"Restart request sent. The supervisor will relaunch the process; the user's UI will reconnect automatically.\",\n });\n } catch (e) {\n return JSON.stringify({\n ok: false,\n code: \"restart_failed\",\n error: (e as Error).message,\n hint: \"Could not reach /api/v1/system/restart from inside the same process. Tell the user they need to restart manually.\",\n });\n }\n },\n {\n name: \"restart_server\",\n description:\n \"Restart the Jarela server. Only call this when the user explicitly asks for a restart, OR when set_env_var returned requiresRestart=true and the user agreed. The UI reconnects automatically once the supervisor (launchd/systemd/Task Scheduler) relaunches.\",\n schema: restartSchema,\n },\n);\n\nregisterTools(\"Config\", \"execute\", [setEnvVar, restartServer]);\n","// Read-only introspection tool — lets the agent enumerate every tool it has\n// access to right now (built-in + external + MCP), so it can answer\n// \"what's in my toolbox / is X available\" without the user having to\n// describe the project's tool surface in the prompt.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport {\n getAllToolsAsync,\n getToolCategory,\n getToolCapability,\n getToolGroup,\n getToolSource,\n type ToolSource,\n} from \"./index\";\nimport type { Capability, ToolCategory } from \"./registry\";\nimport { registerTools } from \"./registry\";\n\ninterface ToolSummary {\n name: string;\n description: string;\n category: ToolCategory;\n capability: Capability;\n source: ToolSource;\n group: string | null;\n}\n\nexport const listToolsTool = tool(\n async ({ category, capability, source }) => {\n const all = await getAllToolsAsync();\n const summaries: ToolSummary[] = all.map((t) => ({\n name: t.name,\n description: typeof t.description === \"string\" ? t.description : \"\",\n category: getToolCategory(t.name),\n capability: getToolCapability(t.name),\n source: getToolSource(t.name),\n group: getToolGroup(t.name),\n }));\n\n const filtered = summaries.filter((s) =>\n (!category || s.category === category) &&\n (!capability || s.capability === capability) &&\n (!source || s.source === source),\n );\n\n const counts = {\n total: filtered.length,\n by_source: { builtin: 0, external: 0, mcp: 0 } as Record<ToolSource, number>,\n by_capability: { read: 0, write: 0, execute: 0 } as Record<Capability, number>,\n };\n for (const s of filtered) {\n counts.by_source[s.source]++;\n counts.by_capability[s.capability]++;\n }\n\n return JSON.stringify({ tools: filtered, counts });\n },\n {\n name: \"list_tools\",\n description:\n \"List every tool currently available to this agent — built-in tools, \" +\n \"external (~/.jarela/providers JS plugins), and MCP server tools — with \" +\n \"category, capability (read/write/execute), and source. Read-only. \" +\n \"Use this when the user asks 'what can you do?', when picking between \" +\n \"tools for a task, or when troubleshooting whether a specific tool is \" +\n \"registered. Optional filters narrow by category, capability, or source.\",\n schema: z.object({\n category: z\n .string()\n .optional()\n .describe(\"Optional category filter (e.g. 'Files', 'Mail', 'GitHub', 'MCP')\"),\n capability: z\n .enum([\"read\", \"write\", \"execute\"])\n .optional()\n .describe(\"Optional capability filter — the safety class of the tool\"),\n source: z\n .enum([\"builtin\", \"external\", \"mcp\"])\n .optional()\n .describe(\"Optional source filter — where the tool came from\"),\n }),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listToolsTool]);\n","// Read-only introspection for LLM provider adapters. Two paired tools:\n// - list_providers: enumerate every adapter (built-in + external).\n// - describe_provider: capability map + known model context windows for one.\n// Together they let the agent answer \"what can we route to\" or pick a model\n// by capability without hand-coded knowledge of the provider catalog.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport {\n listProviderNames,\n getProvider,\n BUILTIN_PROVIDER_NAMES,\n} from \"@/lib/providers\";\nimport { listKnownModels } from \"@/lib/providers/known-context-windows\";\nimport { registerTools } from \"./registry\";\n\ntype ProviderSource = \"builtin\" | \"external\";\n\nfunction sourceOf(name: string): ProviderSource {\n return BUILTIN_PROVIDER_NAMES.has(name) ? \"builtin\" : \"external\";\n}\n\nexport const listProvidersTool = tool(\n async () => {\n const names = listProviderNames();\n const providers = names.map((name) => ({\n name,\n source: sourceOf(name),\n }));\n return JSON.stringify({\n providers,\n count: providers.length,\n builtin_count: providers.filter((p) => p.source === \"builtin\").length,\n external_count: providers.filter((p) => p.source === \"external\").length,\n });\n },\n {\n name: \"list_providers\",\n description:\n \"List every LLM provider adapter registered in this app (built-in like \" +\n \"anthropic / openai / gemini / deepseek / github-copilot / langchain, plus \" +\n \"any external `.cjs` plugins under ~/.jarela/providers/). Read-only. \" +\n \"Use this before suggesting a model swap, or when answering 'what can \" +\n \"we route to.' Call describe_provider afterwards for capability details.\",\n schema: z.object({}),\n },\n);\n\nexport const describeProviderTool = tool(\n async ({ name }) => {\n let provider;\n try {\n provider = getProvider(name);\n } catch (err) {\n return JSON.stringify({\n error: err instanceof Error ? err.message : String(err),\n hint: \"Call list_providers to see registered names.\",\n });\n }\n\n // Capability inferred from which methods the adapter implements. We\n // intentionally don't call listModels() here — that would hit the\n // network and require valid credentials, which makes this a \"read\"-class\n // tool that sometimes fails for credential reasons. Static introspection\n // only.\n const capabilities = {\n chat: typeof provider.chat === \"function\",\n invoke: typeof provider.invoke === \"function\",\n stream_invoke: typeof provider.streamInvoke === \"function\",\n embed: typeof provider.embed === \"function\",\n list_models: typeof provider.listModels === \"function\",\n };\n\n const models = listKnownModels(name);\n\n return JSON.stringify({\n name,\n source: sourceOf(name),\n capabilities,\n known_models: models,\n notes: [\n models.length === 0\n ? \"No static model catalog for this provider — call /api/v1/models?provider=\" +\n name + \" for live discovery if the adapter implements list_models.\"\n : \"Static catalog only. Live `list_models` (when supported) may include \" +\n \"newer models not listed here.\",\n ],\n });\n },\n {\n name: \"describe_provider\",\n description:\n \"Return capability flags (chat / invoke / stream / embed / list_models) \" +\n \"and the static known-models catalog (with context windows) for one \" +\n \"registered provider. Read-only. Use this to choose a model by capability, \" +\n \"or to explain provider differences to the user. Call list_providers first \" +\n \"if you don't know the provider name.\",\n schema: z.object({\n name: z\n .string()\n .describe(\"Provider name from list_providers, e.g. 'anthropic', 'openai', 'gemini'\"),\n }),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listProvidersTool, describeProviderTool]);\n","// Read-only introspection of configured MCP servers — names, transports,\n// enabled/disabled state, last connection error, and the count of tools each\n// server contributes to the live tool pool. Lets the agent answer \"why is\n// my Jira tool unavailable?\" without bouncing the user through the UI.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { listMcpServers } from \"@/lib/stores/mcp-servers\";\nimport { getAllToolsAsync } from \"./index\";\nimport { getToolSource } from \"./index\";\nimport { registerTools } from \"./registry\";\n\ninterface McpServerSummary {\n name: string;\n transport: \"stdio\" | \"http\";\n enabled: boolean;\n last_error: string | null;\n tool_count: number;\n created_at: string;\n updated_at: string;\n}\n\nexport const listMcpServersTool = tool(\n async () => {\n const rows = listMcpServers();\n const allTools = await getAllToolsAsync();\n // MCP tools don't carry their server name as a structured field — for\n // the per-server count we count every tool whose source is \"mcp\", and\n // we surface the total separately. Per-server attribution would require\n // a deeper hook into MultiServerMCPClient's tool-namespace metadata,\n // which is a bigger change than this introspection step warrants today.\n const totalMcp = allTools.filter((t) => getToolSource(t.name) === \"mcp\").length;\n\n const servers: McpServerSummary[] = rows.map((r) => ({\n name: r.name,\n transport: r.transport,\n enabled: r.enabled === 1,\n last_error: r.last_error,\n // Per-server tool count not yet attributable; surface total on every\n // row for now and document the limitation in `notes` below.\n tool_count: r.enabled === 1 ? totalMcp : 0,\n created_at: r.created_at,\n updated_at: r.updated_at,\n }));\n\n return JSON.stringify({\n servers,\n count: servers.length,\n enabled_count: servers.filter((s) => s.enabled).length,\n total_mcp_tool_count: totalMcp,\n notes: [\n \"tool_count is an aggregate across all enabled MCP servers — per-server \" +\n \"attribution requires deeper namespace tracking that's not implemented yet.\",\n \"last_error shows the most recent connection error if any; null means \" +\n \"the server has never failed since last config change.\",\n ],\n });\n },\n {\n name: \"list_mcp_servers\",\n description:\n \"List every configured MCP server (stdio or http transport) with its \" +\n \"enabled state, last connection error, and the aggregate count of MCP \" +\n \"tools currently in the agent's pool. Read-only. Use this when \" +\n \"diagnosing 'my <X> tool isn't working' — check enabled and last_error \" +\n \"before assuming the tool itself is broken.\",\n schema: z.object({}),\n },\n);\n\nregisterTools(\"Config\", \"read\", [listMcpServersTool]);\n","// Meta-introspection: a hand-curated catalog of every place a third party\n// (or the agent itself, on behalf of the user) can extend or customize the\n// app. Read-only. The tool returns a structured map that points to the\n// registration entrypoint, the integration guide section, and an example\n// file for each surface — so the agent can answer \"how do I add an X?\"\n// or \"what can be customized\" without needing the docs in its context.\n//\n// SOURCE OF TRUTH: this file. When a new extension surface lands, add an\n// entry below — it's a single source for both the agent runtime and the\n// `docs/EXTENDING.md` table-of-contents anchor.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\ninterface ExtensionSurface {\n id: string;\n name: string;\n summary: string;\n registration_entrypoint: string;\n doc_section: string;\n example_path?: string;\n introspection_tool?: string;\n related_adrs: string[];\n}\n\nconst SURFACES: readonly ExtensionSurface[] = [\n {\n id: \"llm_provider_builtin\",\n name: \"Built-in LLM provider\",\n summary:\n \"Add a new in-tree adapter (Anthropic, OpenAI, Gemini, … pattern). \" +\n \"Implements the ModelProvider interface and is registered via the static \" +\n \"BUILTINS map in lib/providers/index.ts.\",\n registration_entrypoint: \"lib/providers/index.ts (BUILTINS map)\",\n doc_section: \"docs/EXTENDING.md#adding-an-llm-provider-built-in\",\n example_path: \"lib/providers/anthropic.ts\",\n introspection_tool: \"list_providers\",\n related_adrs: [\"ADR-0013\"],\n },\n {\n id: \"llm_provider_external\",\n name: \"External LLM provider plugin\",\n summary:\n \"Drop a `.cjs` plugin into ~/.jarela/providers/ that exports an object \" +\n \"matching ModelProvider. Hot-loaded per call (no rebuild).\",\n registration_entrypoint: \"~/.jarela/providers/<name>.cjs\",\n doc_section: \"docs/EXTENDING.md#adding-an-llm-provider-external\",\n example_path: \"lib/providers/template-external.cjs.example\",\n introspection_tool: \"list_providers\",\n related_adrs: [\"ADR-0013\"],\n },\n {\n id: \"builtin_tool\",\n name: \"Built-in tool\",\n summary:\n \"Add a tool callable by the agent. Implement with @langchain/core/tools, \" +\n \"register with `registerTools(category, capability, [tool])`, and add a \" +\n \"side-effect import in lib/tools/builtins.ts. Capability gating is \" +\n \"read | write | execute.\",\n registration_entrypoint: \"lib/tools/<name>.ts (registerTools call) + lib/tools/builtins.ts\",\n doc_section: \"docs/EXTENDING.md#adding-a-built-in-tool\",\n example_path: \"lib/tools/template.ts\",\n introspection_tool: \"list_tools\",\n related_adrs: [\"ADR-0038\"],\n },\n {\n id: \"mcp_server\",\n name: \"MCP server\",\n summary:\n \"Connect a Model Context Protocol server (stdio or http transport). \" +\n \"Configured via the UI (mcp_servers DB table) or programmatically through \" +\n \"lib/stores/mcp-servers.ts. Tools auto-merge into the same pool as \" +\n \"built-ins. Online discovery via the MCP registry is also supported.\",\n registration_entrypoint: \"lib/stores/mcp-servers.ts (upsertMcpServer)\",\n doc_section: \"docs/EXTENDING.md#adding-an-mcp-server\",\n introspection_tool: \"list_mcp_servers\",\n related_adrs: [\"ADR-0014\"],\n },\n {\n id: \"agent_harness\",\n name: \"Agent harness\",\n summary:\n \"Compose system-prompt sections that shape an agent's behaviour \" +\n \"(plan-first, self-config, capability-listing, etc.). Built-in presets \" +\n \"live in lib/agents/harness/presets.ts; custom harnesses are stored in \" +\n \"the memory_store under the `app-settings` namespace.\",\n registration_entrypoint: \"lib/agents/harness/presets.ts (built-in) or memory_store (custom)\",\n doc_section: \"docs/EXTENDING.md#adding-a-custom-harness\",\n related_adrs: [\"ADR-0036\"],\n },\n {\n id: \"integration_manifest\",\n name: \"Integration manifest\",\n summary:\n \"Add a new agent-led setup recipe — prerequisites, ordered steps, \" +\n \"troubleshooting hints. The agent narrates the recipe and proposes \" +\n \"the corresponding config changes through propose_config_change.\",\n registration_entrypoint: \"lib/integrations/registry.ts\",\n doc_section: \"docs/EXTENDING.md#adding-an-integration-manifest\",\n introspection_tool: \"list_integrations\",\n related_adrs: [\"ADR-0010\"],\n },\n {\n id: \"brand_overlay\",\n name: \"Brand / app identity\",\n summary:\n \"Customize the app's name, description, and issue URL via environment \" +\n \"variables. No code change required. Used by downstream packages that \" +\n \"consume @circuitwall/jarela as an npm dep (e.g. brand overlays).\",\n registration_entrypoint: \"NEXT_PUBLIC_APP_NAME, NEXT_PUBLIC_APP_DESCRIPTION, NEXT_PUBLIC_APP_ISSUE_URL\",\n doc_section: \"docs/EXTENDING.md#branding-the-app\",\n related_adrs: [\"ADR-0005\"],\n },\n];\n\nexport const describeExtensionSurfacesTool = tool(\n async () => {\n return JSON.stringify({\n surfaces: SURFACES,\n count: SURFACES.length,\n guide_path: \"docs/EXTENDING.md\",\n contract_paths: [\n \"lib/providers/types.ts (ModelProvider interface)\",\n \"lib/tools/types.ts (OpenAITool, ToolContext, InvokeMessage)\",\n \"lib/tools/registry.ts (registerTools, ToolCategory, Capability)\",\n \"lib/mcp/registry.ts (RegistryEntry, applyVariables)\",\n ],\n notes: [\n \"Each surface's introspection_tool, when set, lets you enumerate what's \" +\n \"currently registered. Call those when the user asks 'what's available' \" +\n \"rather than describing the type from memory.\",\n \"A surface can have either a static example_path (for external plugins) or \" +\n \"no example (for surfaces wired entirely through the UI / DB). When in \" +\n \"doubt, the doc_section under EXTENDING.md is the canonical walk-through.\",\n ],\n });\n },\n {\n name: \"describe_extension_surfaces\",\n description:\n \"Return the curated catalog of every extension surface in this app — \" +\n \"providers, tools, MCP servers, harnesses, integration manifests, brand \" +\n \"overlay. Each entry has a registration entrypoint, an EXTENDING.md \" +\n \"section anchor, and (when applicable) the introspection tool that lists \" +\n \"what's currently registered. Read-only. Call this when the user asks \" +\n \"'how do I add an X?' or 'what can be customized?' so you can guide \" +\n \"them with the right files and docs.\",\n schema: z.object({}),\n },\n);\n\nregisterTools(\"Config\", \"read\", [describeExtensionSurfacesTool]);\n","// Built-in tools that pair with the wallclock wrapper's `async_run` mode.\n//\n// `async_run: true` on any tool returns immediately with a key; the\n// agent later calls these tools to retrieve the result.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n consumeAsyncResult,\n getAsyncResult,\n listAsyncResults,\n type AsyncResultRecord,\n} from \"./async-results\";\n\nfunction serialize(rec: AsyncResultRecord, includeResult: boolean): Record<string, unknown> {\n const out: Record<string, unknown> = {\n key: rec.key,\n tool: rec.tool,\n status: rec.status,\n started_at: rec.started_at,\n finished_at: rec.finished_at,\n elapsed_ms: (rec.finished_at ?? Date.now()) - rec.started_at,\n };\n if (includeResult && rec.status === \"done\") out.result = rec.result;\n if (includeResult && rec.status === \"error\") out.error = rec.error;\n return out;\n}\n\nasync function waitForFinish(key: string, waitMs: number): Promise<AsyncResultRecord | null> {\n const deadline = Date.now() + Math.max(0, waitMs);\n // 50ms poll — cheap on a Map.get, and bounded by waitMs.\n while (Date.now() < deadline) {\n const rec = getAsyncResult(key);\n if (!rec) return null;\n if (rec.status !== \"pending\") return rec;\n await new Promise((r) => setTimeout(r, 50));\n }\n return getAsyncResult(key);\n}\n\nexport const toolResultGetTool = tool(\n async ({ key, wait_ms, consume }) => {\n let rec: AsyncResultRecord | null = getAsyncResult(key);\n if (!rec) {\n return JSON.stringify({\n ok: false,\n status: \"unknown\",\n key,\n error: \"no async result for that key (it may have expired or never existed)\",\n });\n }\n if (rec.status === \"pending\" && typeof wait_ms === \"number\" && wait_ms > 0) {\n rec = (await waitForFinish(key, wait_ms)) ?? rec;\n }\n if (!rec) {\n return JSON.stringify({ ok: false, status: \"unknown\", key });\n }\n const finished = rec.status !== \"pending\";\n if (consume && finished) {\n consumeAsyncResult(key);\n }\n return JSON.stringify({ ok: true, ...serialize(rec, /* includeResult */ true) });\n },\n {\n name: \"tool_result_get\",\n description:\n \"Retrieve the result of a previously async-fired tool call by its key. \" +\n \"Pass `wait_ms` to short-poll up to that long for a pending call to finish. \" +\n \"Pass `consume: true` to delete the entry after reading a finished result. \" +\n \"Status will be 'pending' (still running), 'done' (success — `result` populated), \" +\n \"'error' (failed — `error` populated), or 'unknown' (no such key).\",\n schema: z.object({\n key: z.string().describe(\"The key returned by the original async tool call.\"),\n wait_ms: z\n .number()\n .int()\n .min(0)\n .max(60_000)\n .optional()\n .describe(\"Optional short-poll budget (0–60000 ms). Returns as soon as the call finishes or the budget elapses.\"),\n consume: z\n .boolean()\n .optional()\n .describe(\"If true and the call has finished, delete the entry after returning it. Default false.\"),\n }),\n },\n);\n\nexport const toolResultListTool = tool(\n async ({ status }) => {\n let recs = listAsyncResults();\n if (status) recs = recs.filter((r) => r.status === status);\n return JSON.stringify({\n ok: true,\n count: recs.length,\n // Lightweight summary only — full result/error stays behind tool_result_get.\n results: recs.map((r) => serialize(r, /* includeResult */ false)),\n });\n },\n {\n name: \"tool_result_list\",\n description:\n \"List currently tracked async tool results (newest first). Useful when you've forgotten \" +\n \"a key or want a quick status check across pending background calls. Optional `status` \" +\n \"filter narrows to 'pending' / 'done' / 'error'.\",\n schema: z.object({\n status: z.enum([\"pending\", \"done\", \"error\"]).optional()\n .describe(\"Optional status filter.\"),\n }),\n },\n);\n\nregisterTools(\"Agent\", \"read\", [toolResultGetTool, toolResultListTool]);\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 \"./files-search\";\nimport \"./workspace\";\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\";\nimport \"./delegate\";\nimport \"./system_config\";\nimport \"./list-tools\";\nimport \"./providers-info\";\nimport \"./mcp-servers-info\";\nimport \"./extension-surfaces\";\nimport \"./async-results-tool\";\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>\", \"<read|write|execute>\", [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 registeredCapability,\n registeredGroup,\n type Capability,\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 {\n registerTools,\n type Capability,\n type ToolCategory,\n type ToolGroup,\n} from \"./registry\";\n\n// Live accessors — DO NOT snapshot at module-load time. Some tool modules\n// import back from this file (for `getAllToolsAsync` etc.) and would create\n// a circular import cycle: their `registerTools(...)` call runs AFTER this\n// module finishes evaluating, so any captured snapshot here would miss them\n// and they'd silently disappear from the agent's tool pool. Live calls dodge\n// the problem — by the time anyone INVOKES `getAllTools()` / etc., every\n// builtin has registered.\nfunction allBuiltins(): StructuredToolInterface[] {\n return registeredTools();\n}\nfunction builtinNames(): ReadonlySet<string> {\n return registeredNames();\n}\n\n// Backwards-compatible export. Callers that import this Set get its current\n// contents at the moment they read it (a fresh Set each access). Internal\n// code prefers `builtinNames()` directly; this stays for external consumers\n// like the extensions API route.\nexport function getBuiltinToolNames(): ReadonlySet<string> {\n return builtinNames();\n}\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(builtinNames());\n}\n\nexport type ToolSource = \"builtin\" | \"external\" | \"mcp\";\n\n// Resolve a tool's origin from its name. Used to label rows in the tools\n// API and to route metadata lookups. Returns \"mcp\" for any name that is\n// neither a registered built-in nor an external (JARELA_TOOLS_DIR) tool —\n// matches today's behavior where MCP tools are everything else.\nexport function getToolSource(name: string): ToolSource {\n if (builtinNames().has(name)) return \"builtin\";\n if (loadExternal().tools.some((t) => t.name === name)) return \"external\";\n return \"mcp\";\n}\n\n// Look up a tool's safety class. Built-in tools have a declared capability;\n// external (JARELA_TOOLS_DIR) and MCP tools default to \"execute\" — the\n// conservative choice until manifest-level overrides land (ADR-0038).\n// Source is derived internally so callers can't mis-tag external tools as\n// MCP (or vice versa).\nexport function getToolCapability(name: string): Capability {\n return registeredCapability(name) ?? \"execute\";\n}\n\nexport function getToolCategory(name: string): 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 getToolSource(name) === \"mcp\" ? \"MCP\" : \"Config\";\n}\n\nexport function getToolGroup(name: string): ToolGroup {\n const cat = getToolCategory(name);\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(allBuiltins()), ...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(allBuiltins()), ...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 = allBuiltins().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: allBuiltins().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","// 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 type { ContentPart } from \"@/lib/tools/types\";\nimport { prepareThreadRun, persistAssistantMessage, snapshotThreadModelConfigName, withInterruptMarker } from \"@/lib/agents/run-thread\";\nimport type { AssistantUsageSnapshot } from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { enqueueThreadRun } from \"@/lib/agents/run-queue\";\nimport { startRun, finishRun, broadcast } from \"@/lib/agents/run-registry\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { resolveTurnProfile, type TurnContextProfile } from \"@/lib/agents/turn-profile\";\n\nconst NO_REPLY_RE = /^\\s*NO[_ ]?REPLY\\b/i;\n\nexport type AgentTurnQueueSource =\n | \"user\"\n | \"scheduler\"\n | \"watcher\"\n | \"trigger\"\n | \"bridge\"\n | \"extension\"\n | \"delegate\";\n\nexport interface RunAgentTurnRequest {\n thread_id: string;\n queue_source: AgentTurnQueueSource;\n message: string;\n attachments?: ContentPart[];\n user_category?: string | null;\n assistant_category?: string | null;\n silent?: boolean;\n /**\n * When true, `prepareThreadRun` will NOT add the message to the DB.\n * Use this when the caller has already persisted the user message and\n * only wants to run the agent against it (e.g. page-capture observer).\n */\n skip_persist_user_message?: boolean;\n\n /**\n * Per-call override of the context profile (see\n * `@/lib/agents/turn-profile`). When omitted, the profile is resolved\n * from `queue_source` via `TURN_PROFILES`. Provide partial overrides\n * to flip an individual toggle for a specific call without changing\n * the category default.\n */\n context_profile_override?: Partial<TurnContextProfile> | null;\n\n /**\n * Skip the stall-retry + strict-citation audit wrapper. One-shot\n * callers (browser-extension fill / rewrite) want the raw assistant\n * text without the `↻` separator or pre-retry stall prose that the\n * wrapper would otherwise inject into the streamed content.\n */\n disable_quality_gates?: boolean;\n}\n\nexport interface RunAgentTurnResult {\n assistantContent: string;\n preview: string;\n skippedAssistant: boolean;\n usage: AssistantUsageSnapshot | null;\n}\n\n/**\n * Canonical external-turn runner: queue -> prepare -> collect -> persist.\n *\n * Use this for non-UI callers (bridges, triggers, watchers, schedulers) so\n * they all share the same silent-mode and persistence rules.\n */\nexport async function runAgentTurn(req: RunAgentTurnRequest): Promise<RunAgentTurnResult> {\n const pinnedModelConfigName = snapshotThreadModelConfigName(req.thread_id);\n const contextProfile = resolveTurnProfile(req.queue_source, req.context_profile_override);\n const thread = getThread(req.thread_id);\n const enqueued = enqueueThreadRun(req.thread_id, req.queue_source, async () => {\n // Register in the run-registry like the HTTP route does so the idle\n // and wall-clock watchdogs bound this execution. Without this, a\n // hung provider stream (bad creds, dead upstream, runaway tool loop)\n // from any non-HTTP entry point would pin the per-thread queue head\n // indefinitely. Lives inside the queued callback so registry slots\n // serialise with the queue.\n const active = startRun(req.thread_id, thread?.agent_id ?? null);\n let terminal: \"done\" | \"error\" = \"error\";\n try {\n const prepared = await prepareThreadRun({\n thread_id: req.thread_id,\n message: req.message,\n attachments: req.attachments,\n user_category: req.user_category ?? null,\n context_profile: contextProfile,\n disable_quality_gates: req.disable_quality_gates,\n signal: active.abort.signal,\n _pinned_model_config_name: pinnedModelConfigName,\n _skip_persist_message: req.skip_persist_user_message,\n });\n\n const collected = await collectStream(prepared.stream, {\n onChunk: (chunk) => broadcast(active, chunk),\n });\n const trimmed = collected.assistantContent.trim();\n // Silent-mode runners (bridges, watchers, schedulers) skip persistence\n // when the model emitted nothing meaningful — but if the run was\n // user-aborted, we still want a record so the next turn isn't blind to\n // the interruption.\n const skipSilent = req.silent === true\n && !collected.aborted\n && (trimmed.length === 0 || NO_REPLY_RE.test(trimmed));\n\n if (!skipSilent) {\n const contentToPersist = collected.aborted\n ? withInterruptMarker(collected.assistantContent)\n : collected.assistantContent;\n persistAssistantMessage(\n req.thread_id,\n contentToPersist,\n collected.usedTools,\n collected.toolEvents,\n req.assistant_category ?? req.user_category ?? null,\n collected.usage ?? null,\n prepared.context_snapshot ?? null,\n prepared.source_manifest ?? null,\n );\n }\n\n terminal = collected.terminal === \"error\" ? \"error\" : \"done\";\n return {\n assistantContent: collected.assistantContent,\n skippedAssistant: skipSilent,\n usage: collected.usage ?? null,\n };\n } finally {\n finishRun(active, terminal);\n }\n });\n\n const done = await enqueued.result;\n return {\n assistantContent: done.assistantContent,\n skippedAssistant: done.skippedAssistant,\n usage: done.usage,\n preview: done.skippedAssistant\n ? \"\"\n : done.assistantContent.replace(/\\s+/g, \" \").trim().slice(0, 120),\n };\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","import type { StreamChunk } from \"./base\";\nimport { getConfig } from \"@/lib/env/config\";\n\n// In-memory registry of in-flight agent runs, keyed by thread_id. When the user\n// switches agents mid-stream, the run keeps going server-side; if they return\n// (or open a second tab), they re-attach via subscribe() and see live deltas.\n//\n// Trade-offs:\n// - Single Node process only. Multi-instance deploys would need a shared\n// pubsub (Redis, NATS) — not in scope for a local app.\n// - Buffered events are capped to MAX_BUFFERED so a 100k-token response\n// doesn't pin GBs of memory if every chunk lingers. Late attachers see the\n// most recent slice plus all subsequent events.\n\ntype Subscriber = (chunk: StreamChunk) => void;\n\n// Read once at module init. JARELA_RUN_BUFFER_SIZE / JARELA_RUN_REGISTRY_TTL_MS\n// override the defaults.\nconst MAX_BUFFERED = getConfig().runBufferSize;\nconst RECENT_TTL_MS = getConfig().runRegistryTtlMs;\n// Idle (no-progress) ceiling and wall-clock ceiling: read fresh per-run\n// from getConfig() so non-restart-required env reloads take effect.\nfunction runIdleMs(): number { return getConfig().runIdleMs; }\nfunction runMaxMs(): number { return getConfig().runMaxMs; }\n\nexport interface ActiveRun {\n thread_id: string;\n agent_id: string | null;\n started_at: number;\n finished_at: number | null;\n status: \"running\" | \"done\" | \"error\";\n events: StreamChunk[];\n subscribers: Set<Subscriber>;\n // Final assistant text — useful for notification body without replaying every event.\n final_text: string;\n // Server-side abort: when the user clicks Stop (or the last client\n // disconnects), we signal this controller so the LangGraph stream cancels\n // itself instead of running to completion in the background.\n abort: AbortController;\n // Last activity timestamp — bumped on every broadcast() so the idle\n // watchdog can tell live progress from a wedged stream.\n last_chunk_at: number;\n // Tool-call ids that have been announced (tool_call) but not yet\n // resolved (tool_result). The idle watchdog pauses while this is\n // non-empty: silence between a tool_call and its tool_result is the\n // tool executing, not a wedged provider stream, and tools have their\n // own per-tool timeouts.\n inflight_tools: Set<string>;\n // Per-tool start timestamps for the entries in `inflight_tools`. The\n // wall-clock watchdog uses these (plus `tool_time_ms_done`) to\n // discount tool execution from the agent's wall-clock budget — see\n // `effectiveElapsedMs()`. The agent's wall-clock bounds *agent +\n // provider* time; long-running tools (a big shell exec, a slow MCP\n // call) shouldn't burn it. Each tool already enforces its own\n // per-call timeout (lib/tools/exec.ts, lib/tools/fetch.ts, MCP SDKs)\n // so a hung tool still terminates — it just doesn't pull the agent\n // loop down with it.\n tool_started_at: Map<string, number>;\n // Cumulative wall-clock time spent inside completed tool calls. Adds\n // on each tool_result; never decreases.\n tool_time_ms_done: number;\n}\n\nconst runs = new Map<string, ActiveRun>();\n\nexport function startRun(thread_id: string, agent_id: string | null): ActiveRun {\n // If a stale completed run exists, drop it before starting a new one.\n const existing = runs.get(thread_id);\n if (existing && existing.status === \"running\") {\n throw new Error(`A run is already active for thread ${thread_id}`);\n }\n const now = Date.now();\n const run: ActiveRun = {\n thread_id,\n agent_id,\n started_at: now,\n finished_at: null,\n status: \"running\",\n events: [],\n subscribers: new Set(),\n final_text: \"\",\n abort: new AbortController(),\n last_chunk_at: now,\n inflight_tools: new Set<string>(),\n tool_started_at: new Map<string, number>(),\n tool_time_ms_done: 0,\n };\n runs.set(thread_id, run);\n scheduleIdleWatchdog(run);\n scheduleMaxWatchdog(run);\n return run;\n}\n\n// Synthesise a typed error chunk for the watchdog termination paths and\n// fan it out to subscribers BEFORE flipping `status` to \"error\". The order\n// matters: `broadcast()`'s status guard drops any chunk delivered after\n// `finishRun()` has run, so calling finishRun first would silently swallow\n// the error and the client's EventSource would just see the connection\n// close with no terminal event — bubble keeps spinning, no toast. Doing\n// it the other way around lets the client receive a real error event,\n// render a \"Run timed out\" toast, and (if the consumer wires it up)\n// trigger an auto-retry path. Followed by `done` so the consumer's\n// for-await loop can break cleanly without waiting for an EOF.\nfunction emitWatchdogTermination(\n run: ActiveRun,\n code: \"run_idle_timeout\" | \"run_max_timeout\",\n message: string,\n): void {\n if (run.status !== \"running\") return;\n // Direct registry mutation so the broadcast goes through the regular\n // path (subscribers + buffer + seq stamp) without re-entering any of\n // the watchdog scheduling. Mirrors broadcast() but bypasses the\n // status check we'd otherwise be racing against.\n run.last_chunk_at = Date.now();\n const errChunk: StreamChunk = { type: \"error\", data: { message, code } };\n if (run.events.length < MAX_BUFFERED) run.events.push(errChunk);\n for (const fn of run.subscribers) {\n try { fn(errChunk); } catch { /* subscriber errored, ignore */ }\n }\n // Pair with a synthetic `done` so the client's consume() loop breaks\n // on a terminal event rather than waiting for the EventSource to close.\n const doneChunk: StreamChunk = { type: \"done\", data: {} };\n if (run.events.length < MAX_BUFFERED) run.events.push(doneChunk);\n for (const fn of run.subscribers) {\n try { fn(doneChunk); } catch { /* */ }\n }\n}\n\n// Self-rearming idle watchdog. Fires when no chunk has arrived for\n// `idleMs`; otherwise reschedules itself for `(last_chunk_at + idleMs) -\n// now`. We never carry a handle on the run — the closure just bails if\n// the run is no longer the registry's entry or no longer running.\nfunction scheduleIdleWatchdog(run: ActiveRun): void {\n const idleMs = runIdleMs();\n const fireIn = Math.max(0, (run.last_chunk_at + idleMs) - Date.now());\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur !== run) return;\n if (run.status !== \"running\") return;\n const idle = Date.now() - run.last_chunk_at;\n if (idle < idleMs) {\n scheduleIdleWatchdog(run);\n return;\n }\n if (run.inflight_tools.size > 0) {\n // Tool execution in progress — silence here is the tool working,\n // not a wedged provider stream. Skip the kill, re-check in idleMs.\n // The tool_result will bump last_chunk_at when it lands.\n setTimeout(() => scheduleIdleWatchdog(run), idleMs).unref?.();\n return;\n }\n console.warn(`[run-registry] idle watchdog: force-finishing stalled run for thread ${run.thread_id} after ${idle}ms of no progress`);\n emitWatchdogTermination(\n run,\n \"run_idle_timeout\",\n `Run timed out — no progress for ${Math.round(idle / 1000)}s. The provider stream went silent before the agent finished. Try again, or split the request into smaller steps.`,\n );\n try { run.abort.abort(\"run_idle_timeout\"); } catch { /* */ }\n finishRun(run, \"error\");\n }, fireIn).unref?.();\n}\n\n// Wall-clock elapsed minus time spent inside tool calls (both completed and\n// currently in flight). The wall-clock watchdog uses this so a 5-minute\n// shell exec or a slow MCP roundtrip doesn't burn the agent's budget;\n// tools enforce their own timeouts. See ActiveRun.tool_started_at for the\n// rationale.\nfunction effectiveElapsedMs(run: ActiveRun, now: number): number {\n let inflightToolMs = 0;\n for (const startedAt of run.tool_started_at.values()) {\n inflightToolMs += Math.max(0, now - startedAt);\n }\n return Math.max(0, (now - run.started_at) - run.tool_time_ms_done - inflightToolMs);\n}\n\nfunction scheduleMaxWatchdog(run: ActiveRun): void {\n const max = runMaxMs();\n const now = Date.now();\n const fireIn = Math.max(0, max - effectiveElapsedMs(run, now));\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur !== run) return;\n if (run.status !== \"running\") return;\n const elapsed = effectiveElapsedMs(run, Date.now());\n if (elapsed < max) {\n // Tool time pushed the effective elapsed back below the ceiling —\n // re-arm for the remaining budget. Without this, a tool that runs\n // for longer than `max` between firing and resolving would let\n // the next setTimeout overshoot.\n scheduleMaxWatchdog(run);\n return;\n }\n console.warn(`[run-registry] wall-clock watchdog: force-finishing run for thread ${run.thread_id} after ${elapsed}ms of agent time (excluding tool execution)`);\n emitWatchdogTermination(\n run,\n \"run_max_timeout\",\n `Run exceeded the wall-clock limit (${Math.round(max / 1000)}s of agent time, excluding tool execution). The agent was force-stopped. Try a smaller scope or raise JARELA_RUN_MAX_MS if this is expected.`,\n );\n try { run.abort.abort(\"run_watchdog_timeout\"); } catch { /* */ }\n finishRun(run, \"error\");\n }, fireIn).unref?.();\n}\n\nexport function broadcast(run: ActiveRun, chunk: StreamChunk): void {\n // Identity-check: a superseded run must not smear trailing chunks onto\n // the replacement entry in the registry.\n if (runs.get(run.thread_id) !== run) return;\n run.last_chunk_at = Date.now();\n if (chunk.type === \"text_delta\") {\n run.final_text += (chunk.data.delta as string) ?? \"\";\n } else if (chunk.type === \"tool_call\") {\n const id = (chunk.data as { id?: string }).id;\n if (id) {\n run.inflight_tools.add(id);\n run.tool_started_at.set(id, Date.now());\n }\n } else if (chunk.type === \"tool_result\") {\n const id = (chunk.data as { id?: string }).id;\n if (id) {\n run.inflight_tools.delete(id);\n const startedAt = run.tool_started_at.get(id);\n if (startedAt !== undefined) {\n run.tool_time_ms_done += Math.max(0, Date.now() - startedAt);\n run.tool_started_at.delete(id);\n // The tool just gave the agent its budget back; re-arm the\n // wall-clock watchdog against the new effective elapsed.\n scheduleMaxWatchdog(run);\n }\n }\n }\n if (run.events.length < MAX_BUFFERED) {\n run.events.push(chunk);\n }\n for (const fn of run.subscribers) {\n try { fn(chunk); } catch { /* subscriber errored, ignore */ }\n }\n}\n\nexport function finishRun(run: ActiveRun, status: \"done\" | \"error\"): void {\n // Identity-check: a stale run finishing late must not flip the\n // replacement's status or evict it from the registry.\n if (runs.get(run.thread_id) !== run) return;\n run.status = status;\n run.finished_at = Date.now();\n // Drop subscribers — late attachers should NOT keep getting events on a\n // dead run. They'll get the buffered events on subscribe and that's it.\n run.subscribers.clear();\n // Auto-evict after TTL so memory doesn't grow with every conversation.\n setTimeout(() => {\n const cur = runs.get(run.thread_id);\n if (cur === run) runs.delete(run.thread_id);\n }, RECENT_TTL_MS).unref?.();\n}\n\nexport function getRun(thread_id: string): ActiveRun | null {\n return runs.get(thread_id) ?? null;\n}\n\n// Signal the agent stream to cancel. The stream loop in the route is wired\n// to listen on the AbortController and exit early, emitting an error chunk\n// the client (and the queue-drain hook) can react to. Idempotent.\nexport function abortRun(thread_id: string, reason = \"user_interrupted\"): boolean {\n const run = runs.get(thread_id);\n if (!run || run.status !== \"running\") return false;\n if (!run.abort.signal.aborted) {\n try { run.abort.abort(reason); } catch { /* */ }\n }\n return true;\n}\n\n// Abort every currently-running run. Used by the graceful-shutdown path so\n// LangGraph stream loops bail out instead of continuing past process exit.\n// Returns the number of runs that were signalled.\nexport function abortAllRuns(reason = \"server_shutdown\"): number {\n let count = 0;\n for (const run of runs.values()) {\n if (run.status !== \"running\") continue;\n if (run.abort.signal.aborted) continue;\n try { run.abort.abort(reason); count++; } catch { /* */ }\n }\n return count;\n}\n\n// Poll until every run has transitioned out of \"running\" (or until the\n// caller-supplied deadline elapses). Used during graceful shutdown after\n// `abortAllRuns()` so the stream `finally` blocks have a chance to flush\n// the trailing error chunk and call `finishRun()`. Resolves to the count\n// of runs still stuck in \"running\" when the deadline hit (0 = clean).\nexport async function waitForRunsToSettle(timeoutMs: number): Promise<number> {\n const deadline = Date.now() + Math.max(0, timeoutMs);\n while (Date.now() < deadline) {\n let stillRunning = 0;\n for (const run of runs.values()) if (run.status === \"running\") stillRunning++;\n if (stillRunning === 0) return 0;\n await new Promise<void>((resolve) => setTimeout(resolve, 50));\n }\n let stillRunning = 0;\n for (const run of runs.values()) if (run.status === \"running\") stillRunning++;\n return stillRunning;\n}\n\n// Replays buffered events synchronously, then subscribes for live ones.\n// Returns an unsubscribe fn. Caller is responsible for calling it.\nexport function subscribe(\n thread_id: string,\n onEvent: Subscriber,\n): { run: ActiveRun | null; unsubscribe: () => void } {\n const run = runs.get(thread_id);\n if (!run) return { run: null, unsubscribe: () => {} };\n // Replay buffered events first (so the new subscriber catches up).\n for (const ev of run.events) {\n try { onEvent(ev); } catch { /* */ }\n }\n if (run.status !== \"running\") {\n return { run, unsubscribe: () => {} };\n }\n run.subscribers.add(onEvent);\n return {\n run,\n unsubscribe: () => { run.subscribers.delete(onEvent); },\n };\n}\n","// Per-category context profile for an agent turn.\n//\n// Different turn sources need different slices of the agent's context.\n// A user chatting wants the full hot+warm history of their thread; a\n// one-shot extension \"fill this field\" call wants ONLY the per-call\n// instruction + page context so prior chat doesn't bleed in; a bridge\n// message wants hot+warm because chat messages are connected; a\n// scheduled task wants neither hot nor warm because each firing is a\n// standalone event.\n//\n// This module is the single source of truth. To change the policy for\n// a category, edit `TURN_PROFILES` below — every external runner\n// (extension, bridge, scheduler, watcher, trigger, delegate, HTTP user\n// run) resolves its profile through `resolveTurnProfile` and threads\n// it into `prepareThreadRun`, which applies the toggles at LLM-call\n// assembly time.\n//\n// Facts and recall are global to the agent (memory store + embeddings)\n// and tools come from the agent config — they're NOT per-thread state\n// — so disabling them here just means \"don't paste the recall/facts\n// blocks into THIS turn's system prompt\". The agent can still call\n// `memory_read` / `memory_list` / `web_search` etc. if its tool\n// allow-list includes them.\n\nimport type { AgentTurnQueueSource } from \"@/lib/agents/agent-turn\";\n\nexport interface TurnContextProfile {\n /** Paste the recent thread messages into the LLM call. */\n include_hot: boolean;\n /** Paste the warm-summary block into the system prompt. */\n include_warm: boolean;\n /** Paste the `--- Facts memory ---` block into the system prompt. */\n include_facts: boolean;\n /** Paste the embedding-based recall block into the system prompt. */\n include_recall: boolean;\n}\n\nexport const FULL_PROFILE: TurnContextProfile = {\n include_hot: true,\n include_warm: true,\n include_facts: true,\n include_recall: true,\n};\n\nexport const ONE_SHOT_PROFILE: TurnContextProfile = {\n include_hot: false,\n include_warm: false,\n include_facts: false,\n include_recall: false,\n};\n\n// Category → profile. Add new categories alongside `AgentTurnQueueSource`.\n// To change a category's behaviour, edit ONLY this table.\nexport const TURN_PROFILES: Record<AgentTurnQueueSource, TurnContextProfile> = {\n // Normal chat needs the full thread context.\n user: FULL_PROFILE,\n // Bridge messages are conversational — keep the connection between turns.\n bridge: FULL_PROFILE,\n // Delegate hand-offs need the parent's recent context so the child can\n // pick up the conversation thread.\n delegate: FULL_PROFILE,\n // One-shot automation events: each firing is standalone. Memory + tools\n // still available, but no prior chat history bleeds into the answer.\n extension: ONE_SHOT_PROFILE,\n scheduler: ONE_SHOT_PROFILE,\n watcher: ONE_SHOT_PROFILE,\n trigger: ONE_SHOT_PROFILE,\n};\n\nexport function resolveTurnProfile(\n source: AgentTurnQueueSource | null | undefined,\n override?: Partial<TurnContextProfile> | null,\n): TurnContextProfile {\n const base = source ? TURN_PROFILES[source] : FULL_PROFILE;\n if (!override) return base;\n return { ...base, ...override };\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 agent_id?: string;\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 agent_id=?, 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 patch.agent_id === undefined ? existing.agent_id : patch.agent_id,\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","// 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","// Periodic health-probe runner. Iterates the registered probes from\n// ./probes.ts, races each against a short timeout, and translates state\n// transitions into `health_alert` notification events.\n//\n// Why state transitions: the probe pool runs every ~10min server-side and\n// can also be triggered on demand. Without dedup the user would see the\n// same \"Atlassian rejected the token\" toast every cycle until they fixed\n// it. We publish:\n// * fail → first failure since last success, OR every RE_ALERT_MS while\n// still failing (so the user is reminded the integration is\n// still broken even if they dismissed the toast).\n// * recovered → the probe that was failing is now green again.\n//\n// \"Unconfigured\" probes (operator never set the credential) are silently\n// ignored — only configured-but-broken probes alert. State lives on\n// globalThis (per-process, in-memory) so a restart re-evaluates from\n// scratch.\n\nimport { publish } from \"@/lib/notifications/bus\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport {\n listProbes,\n probeCategory,\n probeLabel,\n runProbe,\n type HealthResult,\n type ProbeName,\n} from \"./probes\";\n\nconst RE_ALERT_MS = 30 * 60 * 1000; // re-fire after 30 min of continuous failure\n\nexport interface ProbeState {\n name: ProbeName;\n category: \"integration\" | \"llm\";\n label: string;\n lastResult: HealthResult | null;\n lastCheckedAt: number;\n // null when never failed; set to first-failure timestamp while failing.\n failingSince: number | null;\n // last time we published an alert for this probe — drives the re-alert\n // backoff. Reset to 0 on recovery.\n lastAlertAt: number;\n}\n\ninterface RunnerState {\n probes: Map<ProbeName, ProbeState>;\n lastRunAt: number;\n // Set while a run is in flight so two concurrent triggers (scheduler +\n // /api/v1/health?refresh=1) don't double-probe every vendor.\n inFlight: boolean;\n}\n\nconst state = getOrCreateGlobal<RunnerState>(\"__jarela_health_runner\", () => ({\n probes: new Map(),\n lastRunAt: 0,\n inFlight: false,\n}));\n\nfunction getOrInit(name: ProbeName): ProbeState {\n let s = state.probes.get(name);\n if (!s) {\n s = {\n name,\n category: probeCategory(name),\n label: probeLabel(name),\n lastResult: null,\n lastCheckedAt: 0,\n failingSince: null,\n lastAlertAt: 0,\n };\n state.probes.set(name, s);\n }\n return s;\n}\n\n// Public: snapshot for the /api/v1/health route.\nexport interface HealthSnapshot {\n ranAt: number;\n probes: Array<{\n name: string;\n category: \"integration\" | \"llm\";\n label: string;\n status: HealthResult[\"status\"] | \"never_checked\";\n ok: boolean;\n error: string | null;\n detail: Record<string, unknown> | null;\n lastCheckedAt: number;\n failingSince: number | null;\n }>;\n}\n\nexport function getHealthSnapshot(): HealthSnapshot {\n const probes: HealthSnapshot[\"probes\"] = [];\n for (const name of listProbes()) {\n const s = state.probes.get(name);\n if (!s) {\n probes.push({\n name,\n category: probeCategory(name),\n label: probeLabel(name),\n status: \"never_checked\",\n ok: false,\n error: null,\n detail: null,\n lastCheckedAt: 0,\n failingSince: null,\n });\n continue;\n }\n probes.push({\n name: s.name,\n category: s.category,\n label: s.label,\n status: s.lastResult?.status ?? \"never_checked\",\n ok: s.lastResult?.ok ?? false,\n error: s.lastResult?.error ?? null,\n detail: s.lastResult?.detail ?? null,\n lastCheckedAt: s.lastCheckedAt,\n failingSince: s.failingSince,\n });\n }\n return { ranAt: state.lastRunAt, probes };\n}\n\n// Publish-vs-skip decision for a single probe transition.\nfunction reconcileProbe(s: ProbeState, prev: HealthResult | null, next: HealthResult, now: number): void {\n if (next.ok) {\n if (s.failingSince !== null) {\n // Was failing, now green — publish a one-shot recovery.\n publish({\n type: \"health_alert\",\n probe: s.name,\n label: s.label,\n category: s.category,\n status: \"recovered\",\n error: null,\n ts: now,\n });\n }\n s.failingSince = null;\n s.lastAlertAt = 0;\n return;\n }\n // Unconfigured probes never alert — operator hasn't configured them.\n if (next.status === \"unconfigured\") {\n s.failingSince = null;\n s.lastAlertAt = 0;\n return;\n }\n // Failing: alert on first failure since last green, OR on re-alert\n // interval. Don't compare equal error strings — a flapping vendor\n // shouldn't fall through the cracks.\n const wasFailing = s.failingSince !== null;\n if (!wasFailing) s.failingSince = now;\n const sinceLastAlert = now - s.lastAlertAt;\n const shouldAlert = !wasFailing || sinceLastAlert >= RE_ALERT_MS;\n if (shouldAlert) {\n s.lastAlertAt = now;\n // Tag transient/error/auth_failed verbatim so the UI can colour-code.\n const alertStatus = next.status === \"auth_failed\" ? \"auth_failed\"\n : next.status === \"transient\" ? \"transient\" : \"error\";\n publish({\n type: \"health_alert\",\n probe: s.name,\n label: s.label,\n category: s.category,\n status: alertStatus,\n error: next.error ?? \"probe failed\",\n ts: now,\n });\n }\n // Keep prev referenced for future diff logic without leaking unused param.\n void prev;\n}\n\n/**\n * Run every registered probe in parallel and reconcile state. Returns the\n * fresh snapshot. Safe to call concurrently — re-entrant calls return the\n * stale snapshot until the in-flight run finishes.\n */\nexport async function runAllHealthProbes(now: number = Date.now()): Promise<HealthSnapshot> {\n if (state.inFlight) return getHealthSnapshot();\n state.inFlight = true;\n try {\n const probes = listProbes();\n const results = await Promise.allSettled(probes.map((p) => runProbe(p)));\n for (let i = 0; i < probes.length; i++) {\n const name = probes[i];\n const s = getOrInit(name);\n const r = results[i];\n const next: HealthResult = r.status === \"fulfilled\"\n ? r.value\n : { ok: false, status: \"error\", error: r.reason instanceof Error ? r.reason.message : String(r.reason) };\n const prev = s.lastResult;\n s.lastResult = next;\n s.lastCheckedAt = now;\n reconcileProbe(s, prev, next, now);\n }\n state.lastRunAt = now;\n return getHealthSnapshot();\n } finally {\n state.inFlight = false;\n }\n}\n\n/** Exposed for tests so they can reset state between cases. */\nexport function _resetHealthRunner(): void {\n state.probes.clear();\n state.lastRunAt = 0;\n state.inFlight = false;\n}\n","// Persistent env-var overrides written to ~/.jarela/env-overrides.json\n// (or $JARELA_DB_DIR/env-overrides.json). Read once at boot and injected\n// into process.env before any module reads its config. Mutated at runtime\n// by /api/v1/env PATCH/DELETE; a hot-reload path resets the config cache\n// so non-restart-required vars take effect immediately.\n//\n// Format: a flat JSON object of `JARELA_*` → string. Anything not in\n// ENV_SCHEMA is rejected at write time (no free-form keys).\n\nimport { promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { envSchemaByName, type EnvVarDef } from \"./schema\";\n\nconst FILE_NAME = \"env-overrides.json\";\n\nfunction overridesPath(): string {\n return join(getDataDir(), FILE_NAME);\n}\n\nexport interface OverridesFile {\n readonly version: 1;\n readonly entries: Readonly<Record<string, string>>;\n}\n\nconst EMPTY: OverridesFile = { version: 1, entries: {} };\n\nexport async function readOverrides(): Promise<OverridesFile> {\n try {\n const raw = await fs.readFile(overridesPath(), \"utf8\");\n const parsed = JSON.parse(raw) as Partial<OverridesFile>;\n if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === \"object\") {\n // Defensive: keep only entries the current schema knows about.\n // Schema renames / removals should silently drop stale rows rather\n // than block boot.\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) continue;\n filtered[k] = v;\n }\n return { version: 1, entries: filtered };\n }\n return EMPTY;\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") return EMPTY;\n // Corrupt file — log + ignore. Don't kill boot over a bad overrides\n // file; the operator can delete it and restart.\n console.warn(`[env-overrides] failed to read ${overridesPath()}: ${e.message}`);\n return EMPTY;\n }\n}\n\nexport function readOverridesSync(): OverridesFile {\n // Sync read for the boot path, where async would force callers up the\n // module chain to await. Used exactly once in instrumentation-node.\n const fsSync = require(\"node:fs\") as typeof import(\"node:fs\");\n try {\n const raw = fsSync.readFileSync(overridesPath(), \"utf8\");\n const parsed = JSON.parse(raw) as Partial<OverridesFile>;\n if (parsed && parsed.version === 1 && parsed.entries && typeof parsed.entries === \"object\") {\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) continue;\n filtered[k] = v;\n }\n return { version: 1, entries: filtered };\n }\n return EMPTY;\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") return EMPTY;\n console.warn(`[env-overrides] failed to read ${overridesPath()}: ${e.message}`);\n return EMPTY;\n }\n}\n\nexport async function writeOverrides(next: OverridesFile): Promise<void> {\n const path = overridesPath();\n const known = envSchemaByName();\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(next.entries)) {\n if (typeof v !== \"string\") continue;\n if (!known.has(k)) {\n throw new Error(`unknown env var: ${k}`);\n }\n filtered[k] = v;\n }\n const out: OverridesFile = { version: 1, entries: filtered };\n // Validate every entry against its schema before persisting; refuse\n // bad values at write time so we never write garbage that boot would\n // then have to reject silently.\n for (const [name, value] of Object.entries(filtered)) {\n const def = known.get(name);\n if (!def) continue;\n const err = validateForSchema(def, value);\n if (err) throw new Error(`${name}: ${err}`);\n }\n await fs.mkdir(join(path, \"..\"), { recursive: true });\n await fs.writeFile(path, JSON.stringify(out, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport function validateForSchema(def: EnvVarDef, value: string): string | null {\n if (def.type === \"int\") {\n const n = Number(value);\n if (!Number.isFinite(n) || !Number.isInteger(n)) return \"expected integer\";\n if (def.min !== undefined && n < def.min) return `minimum is ${def.min}`;\n if (def.max !== undefined && n > def.max) return `maximum is ${def.max}`;\n return null;\n }\n if (def.type === \"bool\") {\n if (!/^(0|1|true|false)$/i.test(value.trim())) return \"expected bool (0/1/true/false)\";\n return null;\n }\n if (def.type === \"enum\") {\n if (!def.enumValues || !def.enumValues.includes(value)) {\n return `expected one of: ${def.enumValues?.join(\", \") ?? \"\"}`;\n }\n return null;\n }\n // string — accept anything non-empty by default\n if (def.type === \"string\") {\n return null;\n }\n return null;\n}\n\n/**\n * Apply persisted overrides into process.env. Called once at boot from\n * instrumentation-node BEFORE any module reads env. Idempotent — safe to\n * call multiple times (subsequent calls overwrite earlier values when\n * the file changes on disk).\n *\n * Skips keys that already have a non-empty value in process.env: the\n * env Jarela was launched with always wins over the persisted overrides.\n * That keeps explicit `JARELA_PORT=… npm start` behavior predictable\n * regardless of what's in the overrides file.\n */\nexport function applyOverridesToProcessEnv(): { applied: number; skipped: number } {\n const file = readOverridesSync();\n let applied = 0;\n let skipped = 0;\n for (const [k, v] of Object.entries(file.entries)) {\n const existing = process.env[k];\n if (existing && existing.trim() !== \"\") {\n skipped++;\n continue;\n }\n process.env[k] = v;\n applied++;\n }\n return { applied, skipped };\n}\n\n/**\n * Set or unset a single override and persist the result. value === null\n * unsets. Returns the resulting overrides snapshot.\n */\nexport async function patchOverride(\n name: string,\n value: string | null,\n): Promise<OverridesFile> {\n const known = envSchemaByName();\n if (!known.has(name)) throw new Error(`unknown env var: ${name}`);\n const current = await readOverrides();\n const next: Record<string, string> = { ...current.entries };\n if (value === null) {\n delete next[name];\n } else {\n next[name] = value;\n }\n const out: OverridesFile = { version: 1, entries: next };\n await writeOverrides(out);\n return out;\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 agent_id?: string;\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 agent_id=?, 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.agent_id ?? existing.agent_id,\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","runAgentTurn","QueueFullError","getScript","runTriggerAgent","firing","agent","agentId","status","preview","threadId","error","thread","category","effectivePrompt","silent","prompt","result","thread_id","queue_source","message","user_category","assistant_category","skippedAssistant","err","msg","Error","String","runTriggerScript","fn","script","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","length","prevEnd","currEnd","removed","slice","added","hunkHeader","Math","max","l","join","bytes","Buffer","byteLength","clipped","truncated","text","buildFiringPrompt","watcher","argsPretty","tool_args","directive","reaction_prompt","trim","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","replace","left","right","ctx","title","registerHandlers","startAllTriggerHandlers","stopAllTriggerHandlers","notifyTriggerHandlers","_reason","runTriggerTick","innerErr","runScheduledTaskFiringNow","runWatcherFiringNow","watcherId","listScripts","listReactionScripts","isReactionScript","REACTION_SCRIPT_PREFIX","tails","depths","DEFAULT_MAX_DEPTH","depth","enqueueThreadRun","_source","runner","options","maxDepth","currentDepth","position","Promise","resolve","next","then","finally","d","catch","getQueueDepth","__resetForTests","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","BaseChatModel","AIMessage","AIMessageChunk","isAIMessage","isHumanMessage","isSystemMessage","isToolMessage","ChatGenerationChunk","convertToOpenAITool","JarelaChatModel","fields","lc_namespace","lc_serializable","_provider","provider","_modelId","modelId","_params","params","_boundTools","boundTools","_llmType","bindTools","tools","_kwargs","_convertedTools","flatMap","oai","function","parameters","_generate","messages","_options","runManager","invokeMessages","toInvokeMessages","openaiTools","streamInvoke","finalChunk","_streamToFinalChunk","gen","aiMessageFromChunk","generations","aiMsg","tool_calls","tc","arguments","providerMessages","stream","chat","chunk","acc","_streamFromProvider","_streamResponseChunks","tool_call_chunks","index","emittedAny","stopReason","event","handleLLMNewToken","delta","additional_kwargs","reasoning_content","args_delta","reason","cacheCreation","cache_creation_input_tokens","cacheRead","cache_read_input_tokens","usage_metadata","input_tokens","output_tokens","total_tokens","input_token_details","cache_creation","cache_read","empty_stream_reason","stop_reason","invalid_tool_calls","lcContentToInvoke","block","b","image_url","dataUrl","media_type","src","every","ai","invokeMsg","reasoning","tool_call_id","BaseStore","getMemory","putMemory","deleteMemory","listMemory","SqliteMemoryStore","batch","operations","results","all","op","ns","namespace","row","key","_raw","createdAt","created_at","updatedAt","updated_at","undefined","prefix","namespacePrefix","limit","rows","r","createReactAgent","HumanMessage","SystemMessage","ToolMessage","getProvider","getModelConfig","getDefaultModelConfig","getModelParams","upsertModelConfig","getAllToolsAsync","getCheckpointer","toBaseMessages","systemPrompt","base","blocks","part","streamWithConfig","runCfg","agent_run_config","cfgName","model_config_name","cfg","toolPolicy","allowed_tools","allow","tool_policy","model_id","store","checkpointer","deleteThread","test","llm","announcedToolIds","pendingAIChunk","totalOutputTokens","usageInputTokens","usageOutputTokens","usageCacheCreationTokens","usageCacheReadTokens","sawUsage","truncatedByLength","needsParagraphBreak","textEmittedSinceLastBreak","flushPendingToolCalls","calls","agentStream","system_prompt","streamMode","configurable","delegation_depth","delegation","delegation_ancestors","ancestors","recursionLimit","payload","usage","details","baseMsg","stack","causeChain","c","cause","cMsg","cCode","rawMsg","aborted","message_id","friendly","isContextOverflowError","observed","parseContextLimitFromError","context_window_tokens","POSITIVE_INFINITY","corrected","nextParams","is_default","persistErr","toLocaleString","requested","firstAppFrame","trimmed","num","openai","match","openaiNoReq","anthropic","gemini","deepseek","ACTION_VERBS","VERB_GROUP","PATTERNS","RegExp","FUTURE_PATTERNS","findActionClaims","out","seen","re","lastIndex","verb","toLowerCase","window","some","VIA_RE","findCitations","tool","SUMMARY_PATTERNS","validateAssistantOutput","toolCalls","allowedTools","calledSet","allowedSet","citations","evidence","claims","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","round","frustration","urgency","positivity","targetExpressive","targetVerbosity","empathyBand","bandLabel","expressiveBand","verbosityBand","directives","mood","lower","frustrationHits","countMatches","urgencyHits","positivityHits","min","terms","term","includes","v","cutoffs","labels","getDefaultHarnessId","getHarness","getBuiltinHarness","DEFAULT_HARNESS_ID","HARNESS_SECTION_KEYS","resolveHarness","agentCfg","harness_id","harness","section","sections","enabled","transcriptText","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","config","contextWindowTokens","outputReserveTokens","max_tokens","overheadTokens","inputBudgetTokens","proportions","context_tier_proportions","tierPriority","context_tier_priority","tierBudgets","applyTierSpill","softCap","incomingSpill","used","cap","spill","takeRecentMessagesWithinBudget","tokenBudget","chosen","tokens","reverse","truncateLargestMessagesWithinBudget","total","reduce","a","idx","needed","nextTokens","nextChars","suffix","trimEnd","formatContextBudgetSummary","budget","fallback","os","parseCitationStrictness","getUserProfile","listIntegrations","getDocumentSourceStats","getAppName","APP_NAME","buildSystemPrompt","trimmedMessage","recallCtx","warmSummaryCtx","factsCtx","experienceMode","delegateRosterLines","sourceManifest","adaptivePersonaCtx","harnessParts","tierCtxByName","tierOrderCtx","identity","instructions","buildUserContext","buildIntegrationsContext","buildDocumentsContext","capabilities","plan_first","presentation","citation","buildSourceLinkContext","buildTimeContext","buildEnvContext","self_config","buildExperienceContext","buildOutputBudgetContext","buildMemoryContext","buildDelegatesContext","resolveExperienceMode","ui_experience_mode","userProfile","about","location_consent","location_lat","location_lng","ageSec","location_updated_at","ageStr","location_accuracy_m","location_label","toFixed","manifest","strictness","citation_strictness","intro","platform","arch","cwd","homedir","configured","lines","email","words","totalChunks","chunk_count","getRecentMessagesWindow","getThread","setThreadWarmSummary","summarizeTranscript","getKnownContextLength","buildHistoryWindow","providerParams","modelInfo","hotSince","history_limit","windowHours","history_window_hours","sinceISO","allWindowMessages","cached","cachedSummaryFresh","warm_summary","warm_summary_before","resolveFallbackContextWindow","hotMessages","hotCap","tier","sumMessageTokens","warmCap","hotForSlice","buildWarmSummary","providerName","factsCap","buildFactsContext","hotMessagesResolved","warmWasExpected","hotMessagesForPrompt","history","parseContent","hotTokensFinal","tierUsage","hot_tokens","warm_tokens","facts_tokens","overhead_tokens","hotCount","warmBudgetTokens","warmMessages","summaryInputChars","transcript","summary","query","factsBudgetTokens","charBudget","line","KNOWN_MODEL_RATES","inputPer1M","outputPer1M","knownRateFor","hit","inferred","confidence","knownRateModelIds","Object","readFileSync","statSync","EXPECTED_PROVIDERS","snapshotPath","readSnapshotSync","snapshot","getPricingTables","tables","byProvider","byProviderModel","byModel","normalizeProvider","inferRatesFromSignals","price_signals","modelInputRates","model_rates","input_per_1m_usd","sort","modelOutputRates","output_per_1m_usd","providerInput","providerOutput","providerDerivedFromModels","resolved_url","pricing_url","modelRate","normalizedModel","isBetterRate","generatedAt","generated_at","providerRatesFor","modelRatesFor","modelKey","providerKey","modelAliasCandidates","candidate","exact","upstream","inferProviderFromModelId","upstreamCandidates","viaUpstreamModel","upstreamProviderRate","viaModel","directModel","known","nextHas","prevHas","rank","high","medium","low","slash","lastIndexOf","signals","tokenRates","CACHE_CREATION_INPUT_RATE_MULTIPLIER","CACHE_READ_INPUT_RATE_MULTIPLIER","estimateCostUsd","inputTokens","outputTokens","rates","cache","inputRate","outputRate","inCost","outCost","cacheCost","create","read","isWriteLikeToolName","resolveDetector","rawMode","anti_hallucination_mode","hallucinationDetectorMode","modelName","anti_hallucination_model_config","hallucinationDetectorModel","modelConfigName","PROMPT_TAIL_BUDGET","SYSTEM_PROMPT","classifyStall","assistantText","toolNames","usedWriteTool","tail","userMsg","parseVerdict","stripped","obj","stalled","getMessages","isSensitiveMemoryNamespace","SOURCE_PRODUCING_TOOLS_CALL","SOURCE_PRODUCING_TOOLS_RESULT","normalizeSource","u","URL","protocol","host","pathname","normalized","home","extractSourcesFromEvents","events","ev","phase","collectStringsFromPayload","extractVisitedSources","freshEvents","tool_events","extractCitedLinks","href","extractCitedMarkers","buildSourceManifest","visited","labelForSource","hostname","labelForCitedSource","extractPriorDialogSources","assistant","nowMs","ageMs","formatAge","msg_id","ms","hr","day","extractMemorySources","items","extractDelegateSources","hits","agent_name","msgId","eventId","h","buildCombinedManifest","caps","toolsSet","delegates","childThread","memory","merged","DECLARED_REFS_FENCE_RE","extractDeclaredReferences","refs","item","stripStreamingDeclaredReferences","indexOf","mergeDeclaredReferences","declared","classifyCitations","tailBudget","citationCheckerTailChars","sent","portionLabel","sourcesList","trailer","parseCitationVerdict","byN","marker","link","verified","impactRank","med","impact","checker_model","unverified_links","claimsRaw","markerRaw","impactRaw","looksLikeSource","assetExt","hasFileExt","addMessage","setMessageMetadata","setThreadContextPin","touchThread","recordToolUsage","getAgentTierProportions","getAgentTools","parseDelegateTargets","startScheduler","recall","recordMessageUsage","RunThreadError","RECALL_BUDGET_MS","raceWithBudget","promise","settled","maxStallRetries","maxTransientRetries","MAX_DELEGATION_DEPTH","contentText","snapshotThreadModelConfigName","prepareThreadRun","req","attachments","stored","_skip_persist_message","_pinned_model_config_name","modelCfg","baseProviderParams","agentTierProportions","hot_since","effectiveHotSince","historyWindow","buildDelegateRoster","oldestInWindow","rawRecallCtx","context_profile","include_recall","buildRecallContext","profile","effectiveHistory","include_hot","effectiveWarmSummary","include_warm","effectiveFacts","include_facts","delegationDepth","_delegation_depth","delegationAncestors","_delegation_ancestors","streamOpts","finalHistory","_inject_message_into_history","rawStream","retriesLeft","_stall_retries_left","disable_quality_gates","stallRetryStream","context_snapshot","hot_budget_tokens","warm_budget_tokens","facts_budget_tokens","source_manifest","delegateIds","delegate_targets","child","firstLine","inner","originalReq","textBuf","signatureCounts","loopedToolName","doneChunk","sawError","sig","toolCallSignature","count","TOOL_LOOP_THRESHOLD","trimmedText","isStallProse","looksLikeStall","zeroToolStall","promisedWriteStall","regexStalled","looped","detector","classifierStalled","classifierReason","verdict","fabrication","uncitedHighClaims","checkerModel","auditManifest","citationManifestMax","citationFail","nudge","retry","INTERRUPT_MARKER","withInterruptMarker","partial","endsWith","persistAssistantMessage","usedTools","toolEvents","contextSnapshot","final","toolList","wasInterrupted","noTool","noWriteTool","lookupAllowedToolsForThread","sanitizedEvents","capToolEventPayload","withoutAutoplay","stripAutoplayHints","persisted","declaredRefs","runCitationCheckerForRow","hasProviderUsage","agentName","cost","input_rate_usd_per_mtok","output_rate_usd_per_mtok","cost_usd","tier_usage","persistedText","_full","cleaned","MAX_PERSISTED_PAYLOAD_BYTES","serialized","__truncated","original_bytes","WRITE_VERB_SEGMENTS","sortedKeys","stable","k","detectToolLoop","threshold","counts","STALL_PATTERNS","current_thread_id","windowOldestContent","filtered","stamp","truncate","tag","flat","shouldEmitChunk","chunkType","includeTools","filters","include_tools","includeThinking","include_thinking","embedOne","cosine","searchDocuments","limitRows","qVec","scored","lowered","score","embedding","vec","substringScore","document_id","source_label","rel_path","abs_path","chunk_index","haystack","needleLower","hay","indexAllSources","runAllHealthProbes","isMasterKeyLocked","POLL_INTERVAL_MS","JARELA_SCHEDULER_TICK_MS","DOC_SWEEP_EVERY_TICKS","HEALTH_SWEEP_EVERY_TICKS","started","timer","running","tickCount","healthTickCount","setImmediate","tick","setInterval","stopScheduler","clearInterval","runScheduledTaskNow","summaryMessages","existsSync","readdirSync","getToolSecret","getToolsDir","toolsDir","isValidSlot","o","required","isValid","schema","secrets","loadExternalTools","builtinNames","categories","files","createRequire","getBuiltinModule","entries","mod","default","def","wrapped","_runManager","getSecret","collectStream","assistantContent","terminal","onChunk","errorMessage","ANTHROPIC","context_length","max_output_tokens","GEMINI","OPENAI","DEEPSEEK","resolveCopilot","canon","matchPrefix","table","best","getKnownModelLimits","getKnownMaxOutputTokens","listKnownModels","UPSERT_SQL","deltas","summarizeToolUsage","stmt","successes","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","successful","isErrorPayload","payloadLooksUsed","totals","extractPayloadTerms","matched","stringifyPayload","unique","token","mkdirSync","writeFileSync","getDataDir","FILES_DIR","SAFE_NAME","isSafeFileName","fileAbsPath","writeBinaryFile","z","registerTools","memoryReadTool","object","string","describe","memoryWriteTool","memoryListTool","search","optional","number","memoryDeleteTool","createDocumentSource","deleteDocumentSource","getDocumentSourceByPath","listDocumentSources","indexOnDemand","documentsSearch","int","documentsListSources","last_scan_at","documentsAddLocalSource","inputPath","note","REMOTE_KINDS","syntheticPath","space_key","cql","project_key","jql","owner","repo","validateRemoteConfig","documentsAddRemoteSource","enum","record","unknown","documentsRemoveSource","confirm","documentsReindexSource","documentsIndexUrl","input","resolveSafetyMode","JARELA_TOOL_SAFETY","SAFE_EXEC_ALLOWLIST","SAFE_SUBCOMMANDS","git","npm","npx","node","python","python3","deno","pip","pip3","COMPOSER_RE","checkExecAllowed","command","allowed","blockedByPattern","allowUnsafe","head","subAllowlist","sub","checkFsAllowed","STATE_KEY","Symbol","for","g","globalThis","DEFAULT_KEY","keyFor","tid","currentWorkspace","setWorkspace","ws","clearWorkspace","_resetWorkspaceContext","execSync","getInjectedSubprocessEnv","maxOutputBytes","execMaxOutputBytes","EXEC_DEFAULT_TIMEOUT_MS","BLOCKED_PATTERNS","isBlockedCommand","pattern","clipOutput","runLocalCommand","exit_code","stderr","timeout","timeout_ms","gate","allow_unsafe","safety_mode","workspaceRoot","output","encoding","maxBuffer","stdio","stdout","timedOut","killed","errText","timed_out","execSchema","boolean","localExecTool","root","shellExecTool","maxReadBytes","filesMaxReadBytes","maxWriteBytes","filesMaxWriteBytes","MAX_LIST_JSON_BYTES","FS_DEADLINE_BACKSTOP_MS","withFsDeadline","work","deadlineMs","_","reject","race","clip","resolvePath","isAbsolute","pathResolverFor","workspace","scoped","isInside","parent","sensitiveBase","sensitiveFiles","jarelaDataDir","JARELA_DB_DIR","assertSafePath","JARELA_ALLOW_SENSITIVE_FILES","basename","readSchema","start_line","end_line","fileReadTool","filePath","readFile","lineRange","end","line_range","total_lines","writeSchema","create_dirs","fileWriteTool","dirname","mkdir","existed","access","writeFile","bytes_written","created","editSchema","old_string","new_string","fileEditTool","first","second","match_count","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","readdir","withFileTypes","localeCompare","it","full","build","es","droppedForSize","total_in_dir_after_filters","truncated_hint","dropped_for_size","lo","hi","mid","mkdirSchema","fileMkdirTool","deleteSchema","fileDeleteTool","targetPath","rmdir","unlink","copySchema","fileCopyTool","copyFile","statSchema","fileStatTool","exists","modified_ms","created_ms","birthtimeMs","MAX_FILES_SCANNED","MAX_MATCHES","MAX_LINE_BYTES","MAX_GLOB_RESULTS","MAX_MULTI_EDITS","MAX_GREP_FILE_BYTES","DEFAULT_IGNORE","compileGlob","alts","escapeRegExp","toPosix","walk","ignore","scanned","visit","absDir","relDir","includeHidden","childRel","childAbs","maxFiles","globSchema","max_results","fileGlobTool","rawRoot","rootAbs","rootStat","walked","matches","files_scanned","grepSchema","literal","case_insensitive","glob","max_matches","context","fileGrepTool","fileRe","filesWithMatches","filesScanned","outer","fileHadMatch","clipLine","before","after","files_with_matches","multiEditSchema","edits","array","fileMultiEditTool","buf","failed","edits_applied","execFile","promisify","execFileP","PROBE_TIMEOUT_MS","MAX_TREE_DEFAULT","MAX_TREE_HARD_CAP","README_MAX_BYTES","sensitiveRoots","resolveAgentPath","withTimeout","probeGit","is_repo","safe","branch","remote","dirty","untracked_count","readJsonIfExists","fileExists","detectPackageManager","pkg","packageManager","pm","detectTestRunner","deps","dependencies","devDependencies","vitest","jest","mocha","ava","scripts","detectFrameworks","react","vue","svelte","express","fastify","tailwindcss","parseMakefileTargets","targets","detectLanguages","found","markLanguage","into","ext","extname","buildTree","maxEntries","dirAbs","dirRel","kids","readReadme","detectConventionFiles","claude","agents","contributing","adrDir","claude_md","agents_md","contributing_md","adr_dir","buildRequiredReading","conventions","readme","extra","extraPath","initSchema","include_tree","max_tree_entries","include_git","include_scripts","include_readme","extra_required_reading","workspaceInitTool","rawPath","opened_at","languages","makefileTargets","tree","hasDockerfile","hasDevcontainer","project","package_manager","framework_hints","test_runner","makefile_targets","has_dockerfile","has_devcontainer","required_reading","workspaceStatusTool","_input","active","workspaceCloseTool","cleared","was_active","tavilySearch","api_key","search_depth","snippet","UA_POOL","ddgSearch","lastStatus","attempt","ua","html","parseDDGHtml","blockRe","titleMatch","snippetMatch","unwrapDDGRedirect","decodeHTML","stripTags","real","searchParams","decodeURIComponent","webSearchTool","tavilyKey","TAVILY_API_KEY","dns","net","ipv4InCidr","addr","bits","mask","ipv4ToNumber","ip","isInteger","classifyIPv4","classifyIPv6","bare","v4","isIPv4","classifyAddress","isIPv6","isPrivateAddress","cls","checkPublicUrl","rawUrl","JARELA_ALLOW_PRIVATE_FETCH","isIP","resolved","addrs","lookup","address","stripHtml","maxBytes","fetchToolMaxBytes","FETCH_INTERNAL_TIMEOUT_MS","MAX_REDIRECTS","extractTitle","extractImages","baseUrl","og","twitter","samples","matchAll","resolveUrl","webFetchTool","max_chars","ctrl","AbortController","TIMEOUT_MS","MAX_BYTES","abort","initialCheck","currentUrl","hop","redirect","loc","hopCheck","contentType","finalUrl","reader","getReader","decoder","TextDecoder","bytesRead","done","decode","cancel","wantHtml","images","content_type","bytes_read","getUserLocationTool","available","how_to_enable","lat","lng","accuracy_m","age_seconds","randomUUID","DEFAULT_MODEL","callGemini","imageTimeoutMs","describeError","callImagen","aspect","instances","sampleCount","aspectRatio","preds","predictions","bytesBase64Encoded","extForMime","generateImageTool","aspect_ratio","saved","img","markdown","hint","DEFAULT_VOICE","MAX_TEXT_CHARS","SpeakerSchema","voice_name","resolveAgentVoice","voice","voice_model","generateVoiceTool","autoplay","speakerList","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","listWatchersTool","safeParse","last_fired_at","cancelWatcherTool","createPendingAction","getPendingAction","proposeConfigChangeTool","proposal_id","checkProposalTool","decided_at","getManifest","listManifests","getIntegrationStatus","isKnownIntegration","manifestStatus","listIntegrationsTool","integrations","getIntegrationSetupTool","prerequisites","steps","troubleshooting","notes","googleFetch","resolveGoogleAuth","CALENDAR_BASE","calendarFetch","auth","init","slimEvent","location","dateTime","date","time_zone","timeZone","attendees","displayName","response","responseStatus","meet_link","hangoutLink","html_link","htmlLink","calendarListCalendarsTool","calendars","primary","access_role","accessRole","calendarListEventsTool","calendar_id","time_min","time_max","cal","URLSearchParams","singleEvents","orderBy","maxResults","inAWeek","calendarGetEventTool","event_id","eid","calendarCreateEventTool","subject","start_iso","end_iso","add_meet_link","eventSummary","conferenceData","createRequest","requestId","random","conferenceSolutionKey","calendarUpdateEventTool","patch","calendarDeleteEventTool","graphFetch","resolveMicrosoftAuth","bodyPreview","emailAddress","is_all_day","isAllDay","is_cancelled","isCancelled","show_as","showAs","teams_link","onlineMeeting","joinUrl","web_link","webLink","outlookCalendarListCalendarsTool","isDefaultCalendar","can_edit","canEdit","outlookCalendarListEventsTool","startISO","endISO","top","startDateTime","endDateTime","$top","$orderby","Prefer","outlookCalendarGetEventTool","outlookCalendarCreateEventTool","add_teams_link","eventSubject","tz","isOnlineMeeting","onlineMeetingProvider","outlookCalendarUpdateEventTool","outlookCalendarDeleteEventTool","resolveTurnProfile","readDelegateContext","ancestorsRaw","parentAgentId","fail","error_code","delegateToAgentTool","roster","startedAt","queued","prepared","collected","elapsed_ms","used_tools","cite_as","envSchemaByName","patchOverride","validateForSchema","resetConfigCache","setEnvSchema","nullable","setEnvVar","agentWritable","verr","requiresRestart","restartSchema","restartServer","port","JARELA_PORT","PORT","JARELA_HOSTNAME","HOSTNAME","getToolCategory","getToolCapability","getToolGroup","getToolSource","listToolsTool","capability","summaries","group","by_source","builtin","external","mcp","by_capability","execute","listProviderNames","BUILTIN_PROVIDER_NAMES","sourceOf","listProvidersTool","providers","builtin_count","external_count","describeProviderTool","stream_invoke","embed","list_models","listModels","models","known_models","listMcpServers","listMcpServersTool","allTools","totalMcp","servers","transport","tool_count","enabled_count","total_mcp_tool_count","SURFACES","registration_entrypoint","doc_section","example_path","introspection_tool","related_adrs","describeExtensionSurfacesTool","surfaces","guide_path","contract_paths","consumeAsyncResult","getAsyncResult","listAsyncResults","serialize","rec","includeResult","started_at","finished_at","waitForFinish","waitMs","deadline","toolResultGetTool","wait_ms","consume","finished","toolResultListTool","recs","registeredNames","registeredCategory","registeredCapability","registeredGroup","getMcpTools","disabledCategories","allBuiltins","getBuiltinToolNames","loadExternal","cat","applyPolicy","policy","allowSet","denySet","deny","applyCategoryToggles","disabled","getAllTools","mcpTools","toOpenAITools","executeTool","x","_initialized","initTools","builtinCount","externalCount","isCategoryEnabled","listCategoryStates","setCategoryEnabled","startRun","finishRun","broadcast","NO_REPLY_RE","pinnedModelConfigName","contextProfile","context_profile_override","enqueued","skip_persist_user_message","skipSilent","contentToPersist","getIntegrationRaw","fromStore","GEMINI_API_KEY","GOOGLE_API_KEY","isUserPreset","upsertUserProfile","icon","setLocationConsent","consent","updateUserLocation","setUserPreset","preset","MAX_BUFFERED","runBufferSize","RECENT_TTL_MS","runRegistryTtlMs","runIdleMs","runMaxMs","runs","subscribers","final_text","last_chunk_at","inflight_tools","tool_started_at","tool_time_ms_done","scheduleIdleWatchdog","scheduleMaxWatchdog","emitWatchdogTermination","errChunk","idleMs","fireIn","idle","effectiveElapsedMs","inflightToolMs","elapsed","getRun","abortRun","abortAllRuns","waitForRunsToSettle","timeoutMs","stillRunning","subscribe","onEvent","unsubscribe","FULL_PROFILE","ONE_SHOT_PROFILE","TURN_PROFILES","user","bridge","delegate","extension","scheduler","trigger","override","CronExpressionParser","resolveReaction","validateReactionScript","normaliseReactionScriptArgs","isNaN","currentDate","toDate","reaction","scriptArgs","updateScheduledTask","nextKind","nextSchedule","nextRunAt","nextPrompt","nextRun","__resetScriptRegistry","NAMESPACE","NAME_RE","validName","compoundKey","parseStored","setToolSecret","deleteToolSecret","describeToolSecrets","slots","is_set","purgeToolSecrets","listProbes","probeCategory","probeLabel","runProbe","RE_ALERT_MS","probes","inFlight","getOrInit","lastResult","lastCheckedAt","failingSince","lastAlertAt","getHealthSnapshot","detail","ranAt","reconcileProbe","probe","wasFailing","sinceLastAlert","shouldAlert","alertStatus","allSettled","_resetHealthRunner","FILE_NAME","overridesPath","EMPTY","version","readOverrides","readOverridesSync","fsSync","require","writeOverrides","enumValues","applyOverridesToProcessEnv","applied","skipped","MAX_REACTION_PROMPT_CHARS","MAX_REACTION_SCRIPT_ARGS_CHARS","normaliseReactionPrompt","MIN_INTERVAL_SECONDS","clampInterval","seconds","argsJson","updateWatcher"],"sourceRoot":"","ignoreList":[]}
|