@circuitwall/jarela 0.14.0 → 1.0.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.
Files changed (164) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +6 -1
  24. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js.map +1 -1
  25. package/.next/standalone/.next/server/app/api/v1/agents/route.js +6 -1
  26. package/.next/standalone/.next/server/app/api/v1/agents/route.js.map +1 -1
  27. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +9 -1
  28. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.map +1 -1
  29. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +9 -1
  30. package/.next/standalone/.next/server/app/api/v1/bridges/route.js.map +1 -1
  31. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +36 -29
  32. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.map +1 -1
  33. package/.next/standalone/.next/server/app/api/v1/events/route.js +7 -1
  34. package/.next/standalone/.next/server/app/api/v1/events/route.js.map +1 -1
  35. package/.next/standalone/.next/server/app/api/v1/extensions/route.js +3 -3
  36. package/.next/standalone/.next/server/app/api/v1/extensions/route.js.map +1 -1
  37. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +4 -4
  38. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.map +1 -1
  39. package/.next/standalone/.next/server/app/api/v1/health/route.js +7 -1
  40. package/.next/standalone/.next/server/app/api/v1/health/route.js.map +1 -1
  41. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +9 -1
  42. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js.map +1 -1
  43. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +9 -1
  44. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js.map +1 -1
  45. package/.next/standalone/.next/server/app/api/v1/models/route.js +6 -1
  46. package/.next/standalone/.next/server/app/api/v1/models/route.js.map +1 -1
  47. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +7 -1
  48. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.map +1 -1
  49. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +14 -7
  50. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.map +1 -1
  51. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +28 -0
  52. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js.map +1 -1
  53. package/.next/standalone/.next/server/app/api/v1/providers/route.js +7 -1
  54. package/.next/standalone/.next/server/app/api/v1/providers/route.js.map +1 -1
  55. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +16 -2
  56. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.map +1 -1
  57. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +8 -1
  58. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.map +1 -1
  59. package/.next/standalone/.next/server/app/api/v1/threads/route.js +6 -1
  60. package/.next/standalone/.next/server/app/api/v1/threads/route.js.map +1 -1
  61. package/.next/standalone/.next/server/app/api/v1/tools/route.js +10 -3
  62. package/.next/standalone/.next/server/app/api/v1/tools/route.js.map +1 -1
  63. package/.next/standalone/.next/server/app/index.html +2 -2
  64. package/.next/standalone/.next/server/app/index.rsc +3 -3
  65. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  66. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  67. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  69. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  70. package/.next/standalone/.next/server/app/page.js +56 -0
  71. package/.next/standalone/.next/server/app/page.js.map +1 -1
  72. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/setup.html +1 -1
  75. package/.next/standalone/.next/server/app/setup.rsc +2 -2
  76. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +2 -2
  77. package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
  78. package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +2 -2
  79. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  80. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
  81. package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
  82. package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
  83. package/.next/standalone/.next/server/chunks/1683.js +2 -2
  84. package/.next/standalone/.next/server/chunks/2082.js +122 -13
  85. package/.next/standalone/.next/server/chunks/2082.js.map +1 -1
  86. package/.next/standalone/.next/server/chunks/210.js +3 -3
  87. package/.next/standalone/.next/server/chunks/210.js.map +1 -1
  88. package/.next/standalone/.next/server/chunks/239.js +1902 -1487
  89. package/.next/standalone/.next/server/chunks/239.js.map +1 -1
  90. package/.next/standalone/.next/server/chunks/2447.js +9 -1
  91. package/.next/standalone/.next/server/chunks/2447.js.map +1 -1
  92. package/.next/standalone/.next/server/chunks/423.js +125 -16
  93. package/.next/standalone/.next/server/chunks/423.js.map +1 -1
  94. package/.next/standalone/.next/server/chunks/4631.js +36 -29
  95. package/.next/standalone/.next/server/chunks/4631.js.map +1 -1
  96. package/.next/standalone/.next/server/chunks/5937.js +3 -2
  97. package/.next/standalone/.next/server/chunks/5937.js.map +1 -1
  98. package/.next/standalone/.next/server/chunks/{947.js → 8866.js} +11321 -10883
  99. package/.next/standalone/.next/server/chunks/8866.js.map +1 -0
  100. package/.next/standalone/.next/server/chunks/9032.js +3 -3
  101. package/.next/standalone/.next/server/chunks/9032.js.map +1 -1
  102. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  103. package/.next/standalone/.next/server/middleware.js +122 -13
  104. package/.next/standalone/.next/server/pages/404.html +2 -2
  105. package/.next/standalone/.next/server/pages/500.html +1 -1
  106. package/.next/standalone/.next/server/proxy.js.map +1 -1
  107. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  108. package/.next/standalone/.next/static/chunks/app/{page-473b39ec30c7f569.js → page-a7cae65f235e2942.js} +57 -1
  109. package/.next/standalone/.next/static/chunks/app/page-a7cae65f235e2942.js.map +1 -0
  110. package/.next/standalone/.next/static/css/{6f8b1a84bcbcd467.css → e57bdbbbb5a05779.css} +2 -2
  111. package/.next/standalone/.next/static/css/e57bdbbbb5a05779.css.map +1 -0
  112. package/.next/standalone/package.json +9 -1
  113. package/CHANGELOG.md +90 -0
  114. package/README.md +30 -2
  115. package/api/types.ts +8 -0
  116. package/app/api/v1/agents/[id]/route.ts +7 -0
  117. package/app/api/v1/agents/route.ts +7 -0
  118. package/app/api/v1/events/route.ts +8 -0
  119. package/app/api/v1/extensions/route.ts +2 -2
  120. package/app/api/v1/extensions/tools/[name]/secrets/route.ts +3 -3
  121. package/app/api/v1/health/route.ts +8 -0
  122. package/app/api/v1/models/route.ts +7 -0
  123. package/app/api/v1/page-capture/route.ts +8 -0
  124. package/app/api/v1/providers/route.ts +8 -0
  125. package/app/api/v1/threads/[thread_id]/route.ts +8 -0
  126. package/app/api/v1/threads/[thread_id]/run/route.ts +9 -0
  127. package/app/api/v1/threads/route.ts +7 -0
  128. package/app/api/v1/tools/route.ts +9 -0
  129. package/components/chat/ContextUsageBar.tsx +44 -0
  130. package/lib/agents/llm.ts +25 -2
  131. package/lib/agents/run-thread.ts +13 -1
  132. package/lib/agents/stream-collector.ts +9 -1
  133. package/lib/api/serializers.test.ts +15 -0
  134. package/lib/api/serializers.ts +8 -0
  135. package/lib/db/migrations.ts +15 -0
  136. package/lib/health/runner.test.ts +24 -2
  137. package/lib/mcp/registry.ts +14 -6
  138. package/lib/providers/anthropic.test.ts +95 -0
  139. package/lib/providers/anthropic.ts +106 -10
  140. package/lib/providers/jarela-chat-model.ts +9 -1
  141. package/lib/providers/known-context-windows.ts +21 -0
  142. package/lib/providers/types.ts +21 -1
  143. package/lib/stores/message-usage.test.ts +34 -0
  144. package/lib/stores/message-usage.ts +15 -3
  145. package/lib/stores/pricing.test.ts +52 -0
  146. package/lib/stores/pricing.ts +26 -1
  147. package/lib/tools/builtins.ts +4 -0
  148. package/lib/tools/extension-surfaces.test.ts +79 -0
  149. package/lib/tools/extension-surfaces.ts +153 -0
  150. package/lib/tools/index.ts +27 -8
  151. package/lib/tools/list-tools.test.ts +76 -0
  152. package/lib/tools/list-tools.ts +84 -0
  153. package/lib/tools/mcp-servers-info.test.ts +73 -0
  154. package/lib/tools/mcp-servers-info.ts +71 -0
  155. package/lib/tools/providers-info.test.ts +73 -0
  156. package/lib/tools/providers-info.ts +106 -0
  157. package/lib/tools/registry.ts +36 -25
  158. package/lib/tools/types.ts +13 -0
  159. package/package.json +9 -1
  160. package/.next/standalone/.next/server/chunks/947.js.map +0 -1
  161. package/.next/standalone/.next/static/chunks/app/page-473b39ec30c7f569.js.map +0 -1
  162. package/.next/standalone/.next/static/css/6f8b1a84bcbcd467.css.map +0 -1
  163. /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_buildManifest.js +0 -0
  164. /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_ssgManifest.js +0 -0
@@ -119,7 +119,7 @@ async function runShutdown() {
119
119
  }
120
120
  // 2. Stop the scheduler so no firing kicks off mid-drain.
121
121
  try {
122
- const { stopScheduler } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(947)]).then(__webpack_require__.bind(__webpack_require__, 3464));
122
+ const { stopScheduler } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(8866)]).then(__webpack_require__.bind(__webpack_require__, 3464));
123
123
  stopScheduler();
124
124
  } catch (err) {
125
125
  console.error("[jarela] stopping scheduler failed:", err);
@@ -129,14 +129,14 @@ async function runShutdown() {
129
129
  // scheduler tick (those are run-loop ownership; this is per-handler
130
130
  // ownership of OS resources).
131
131
  try {
132
- const { stopAllTriggerHandlers } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(947)]).then(__webpack_require__.bind(__webpack_require__, 64439));
132
+ const { stopAllTriggerHandlers } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(8866)]).then(__webpack_require__.bind(__webpack_require__, 64439));
133
133
  await stopAllTriggerHandlers();
134
134
  } catch (err) {
135
135
  console.error("[jarela] stopping trigger handlers failed:", err);
136
136
  }
137
137
  // 3. Close bridges (WhatsApp Baileys WS, etc).
138
138
  try {
139
- const { stopAllBridges } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(947), __webpack_require__.e(1683)]).then(__webpack_require__.bind(__webpack_require__, 71683));
139
+ const { stopAllBridges } = await Promise.all(/* import() */[__webpack_require__.e(1218), __webpack_require__.e(6447), __webpack_require__.e(127), __webpack_require__.e(3169), __webpack_require__.e(423), __webpack_require__.e(8866), __webpack_require__.e(1683)]).then(__webpack_require__.bind(__webpack_require__, 71683));
140
140
  await stopAllBridges();
141
141
  } catch (err) {
142
142
  console.error("[jarela] stopping bridges failed:", err);
@@ -1 +1 @@
1
- {"version":3,"file":"9032.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/utils/global-state.ts","webpack://@circuitwall/jarela/./lib/lifecycle/shutdown.ts","webpack://@circuitwall/jarela/./lib/env/app-config.ts","webpack://@circuitwall/jarela/./lib/env/config.ts"],"sourcesContent":["// Pin a piece of state to globalThis so it survives Next.js dev hot-reload.\n//\n// Without this, every code edit re-evaluates the module, replacing the\n// in-memory state with empty containers — but any active closure still\n// references the OLD set, so listeners/timers/maps go silently dead.\n// The globalThis trick is the standard Next pattern for singletons.\n//\n// `key` must be unique across the app (it lives on globalThis); pick a\n// \"__jarela_<name>\" prefix to keep the namespace tidy.\nexport function getOrCreateGlobal<T>(key: string, factory: () => T): T {\n const g = globalThis as unknown as Record<string, unknown>;\n if (g[key] === undefined) g[key] = factory();\n return g[key] as T;\n}\n","// Graceful shutdown coordinator.\n//\n// Registers SIGINT / SIGTERM (and SIGBREAK on Windows) so Ctrl-C in the\n// foreground and `kill`/`systemctl stop`/Task Scheduler \"End task\" all\n// trigger the same drain sequence:\n//\n// 1. abort every in-flight LangGraph run so stream loops bail out\n// 2. stop the scheduler tick so no new firings start\n// 3. close every bridge adapter (WhatsApp WS, future kinds) cleanly\n// 4. wait briefly for the runs to actually finish flushing\n// 5. close the SQLite handle so WAL is checkpointed\n// 6. exit 0\n//\n// A hard timeout aborts the drain if any subsystem hangs — the supervisor\n// (Task Scheduler / systemd / installed-launcher.ps1) will then restart us\n// instead of leaving a zombie holding the port.\n//\n// Wired from `instrumentation.ts` so it runs once per server process at\n// boot. Idempotent: only the first call installs handlers.\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { getConfig } from \"@/lib/env/config\";\n\ninterface ShutdownState {\n registered: boolean;\n shuttingDown: boolean;\n}\nconst state = getOrCreateGlobal<ShutdownState>(\"__jarela_shutdown\", () => ({\n registered: false,\n shuttingDown: false,\n}));\n\n// JARELA_SHUTDOWN_DRAIN_MS / JARELA_SHUTDOWN_SETTLE_MS override these.\n// Captured at handler-install time (boot); these don't hot-reload because\n// the handlers close over the values.\nconst HARD_TIMEOUT_MS = getConfig().shutdownDrainMs;\nconst RUN_DRAIN_MS = getConfig().shutdownSettleMs;\n\nexport function registerShutdownHandlers(): void {\n if (state.registered) return;\n state.registered = true;\n\n const handler = (signal: NodeJS.Signals) => {\n if (state.shuttingDown) {\n // Second signal while already draining: operator is impatient, exit\n // immediately. Mirrors the behaviour every well-behaved daemon has —\n // first Ctrl-C drains, second Ctrl-C kills.\n console.log(`[jarela] received ${signal} during shutdown; forcing exit.`);\n process.exit(130);\n }\n state.shuttingDown = true;\n console.log(`[jarela] ${signal} received, draining…`);\n void runShutdown().catch((err) => {\n console.error(`[jarela] shutdown error:`, err);\n process.exit(1);\n });\n };\n\n // Replace any default handlers Next's standalone server may have\n // installed for these signals. Next's default just calls\n // `server.close(() => process.exit(0))`, which races our drain and can\n // exit the process before bridges/DB have flushed. We take over and\n // exit ourselves once drain completes.\n process.removeAllListeners(\"SIGINT\");\n process.removeAllListeners(\"SIGTERM\");\n process.on(\"SIGINT\", handler);\n process.on(\"SIGTERM\", handler);\n if (process.platform === \"win32\") {\n // Ctrl-Break in a foreground PowerShell session lands as SIGBREAK,\n // not SIGINT. Task Scheduler \"End task\" delivers SIGBREAK as well.\n process.removeAllListeners(\"SIGBREAK\");\n process.on(\"SIGBREAK\", handler);\n }\n}\n\nasync function runShutdown(): Promise<void> {\n // Safety net: if any drain step deadlocks (e.g. a bridge adapter's\n // socket.close() never resolves), force-exit so the supervisor can\n // restart cleanly instead of holding the port forever.\n const forceExit = setTimeout(() => {\n console.warn(`[jarela] drain exceeded ${HARD_TIMEOUT_MS}ms; forcing exit.`);\n process.exit(130);\n }, HARD_TIMEOUT_MS);\n forceExit.unref?.();\n\n // 1. Abort in-flight LLM runs. The route's stream loop watches this\n // AbortController and exits early, emitting a trailing error chunk.\n try {\n const { abortAllRuns } = await import(\"@/lib/agents/run-registry\");\n const n = abortAllRuns(\"server_shutdown\");\n if (n > 0) console.log(`[jarela] aborted ${n} in-flight run(s).`);\n } catch (err) {\n console.error(\"[jarela] aborting runs failed:\", err);\n }\n\n // 2. Stop the scheduler so no firing kicks off mid-drain.\n try {\n const { stopScheduler } = await import(\"@/lib/scheduler\");\n stopScheduler();\n } catch (err) {\n console.error(\"[jarela] stopping scheduler failed:\", err);\n }\n\n // 2b. Drain trigger handlers — closes fs.watch watchers and any other\n // handler that has timers / sockets attached. Independent of the\n // scheduler tick (those are run-loop ownership; this is per-handler\n // ownership of OS resources).\n try {\n const { stopAllTriggerHandlers } = await import(\"@/lib/triggers\");\n await stopAllTriggerHandlers();\n } catch (err) {\n console.error(\"[jarela] stopping trigger handlers failed:\", err);\n }\n\n // 3. Close bridges (WhatsApp Baileys WS, etc).\n try {\n const { stopAllBridges } = await import(\"@/lib/bridges/runtime\");\n await stopAllBridges();\n } catch (err) {\n console.error(\"[jarela] stopping bridges failed:\", err);\n }\n\n // 4. Give aborted runs a beat to actually finish — they were signalled\n // in step 1, but the `finally` blocks need ticks to flush trailing\n // events and persist the partial assistant message.\n try {\n const { waitForRunsToSettle } = await import(\"@/lib/agents/run-registry\");\n const stuck = await waitForRunsToSettle(RUN_DRAIN_MS);\n if (stuck > 0) console.warn(`[jarela] ${stuck} run(s) still active after drain window.`);\n } catch (err) {\n console.error(\"[jarela] waiting for runs failed:\", err);\n }\n\n // 5. Close the DB. WAL is checkpointed so the next boot is fast and we\n // leave no stale -shm/-wal sidecars on disk.\n try {\n const { closeDb } = await import(\"@/lib/db\");\n closeDb();\n } catch (err) {\n console.error(\"[jarela] closing db failed:\", err);\n }\n\n clearTimeout(forceExit);\n console.log(\"[jarela] shutdown complete.\");\n process.exit(0);\n}\n","// Branding knobs sourced from NEXT_PUBLIC_* env vars so forks can rebrand\n// the app without patching source. NEXT_PUBLIC_* is the right\n// channel here because Next.js inlines these at build time, which lets\n// client components read them directly (no React Context, no server\n// round-trip). Server-only modules read the same keys at runtime.\n//\n// Keep this module client-safe — no Node-only imports, no DB/FS access.\n\nconst DEFAULT_APP_NAME = \"Jarela\";\nconst DEFAULT_APP_DESCRIPTION = \"Jarela — local chat interface for LangGraph agents\";\nconst DEFAULT_ISSUE_URL = \"https://github.com/CircuitWall/jarela/issues/new\";\n\nexport function getAppName(): string {\n return process.env.NEXT_PUBLIC_APP_NAME?.trim() || DEFAULT_APP_NAME;\n}\n\nexport function getAppDescription(): string {\n return process.env.NEXT_PUBLIC_APP_DESCRIPTION?.trim() || DEFAULT_APP_DESCRIPTION;\n}\n\nexport function getAppIssueUrl(): string {\n return process.env.NEXT_PUBLIC_APP_ISSUE_URL?.trim() || DEFAULT_ISSUE_URL;\n}\n","// Central runtime configuration, resolved from environment variables.\n//\n// All operational knobs (port, host, data dir, timeouts, agent limits) flow\n// through this module so there is exactly one place documenting which env\n// vars Jarela respects and what the defaults are. Code MUST NOT read these\n// `process.env` keys directly — import `config` instead.\n//\n// Resolution order for every entry: explicit JARELA_* var → legacy/standard\n// var (where one exists, e.g. PORT/HOSTNAME for Next.js compatibility) →\n// schema default (lib/env/schema.ts).\n//\n// Values are resolved lazily on first read and cached. Tests + the env-\n// override PATCH endpoint must call `resetConfigCache()` between cases.\n\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { getAppName, getAppDescription, getAppIssueUrl } from \"./app-config\";\nimport { ENV_DEFAULTS } from \"./schema\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface JarelaConfig {\n // network\n readonly port: number;\n readonly hostname: string;\n readonly dataDir: string;\n readonly toolsDir: string;\n readonly httpRequestTimeoutMs: number;\n readonly sseConnectTimeoutMs: number;\n readonly healthCheckTimeoutMs: number;\n readonly httpMaxAttempts: number;\n\n // agent\n readonly recursionLimit: number;\n readonly llmStreamMaxMs: number;\n readonly runIdleMs: number;\n readonly runMaxMs: number;\n readonly runRegistryTtlMs: number;\n readonly runBufferSize: number;\n readonly maxStallRetries: number;\n readonly maxTransientRetries: number;\n readonly maxDelegationDepth: number;\n readonly streamParseTripwire: number;\n\n // tools\n readonly voiceTimeoutMs: number;\n readonly imageTimeoutMs: number;\n readonly fetchToolMaxBytes: number;\n readonly mcpRegistryTimeoutMs: number;\n readonly execMaxOutputBytes: number;\n readonly filesMaxReadBytes: number;\n readonly filesMaxWriteBytes: number;\n\n // lifecycle\n readonly updateCheckTimeoutMs: number;\n readonly shutdownDrainMs: number;\n readonly shutdownSettleMs: number;\n readonly disableUpdateCheck: boolean;\n\n // limits\n readonly notificationRingSize: number;\n\n // logging\n readonly logsRingSize: number;\n readonly logLevel: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n // scheduler\n readonly schedulerTickMs: number;\n readonly fastRemoteSweepMs: number;\n\n // documents\n readonly docMaxFileBytes: number;\n readonly docMaxFilesPerSource: number;\n\n // anti-hallucination detector\n readonly hallucinationDetectorMode: \"off\" | \"regex\" | \"model\";\n readonly hallucinationDetectorModel: string;\n readonly citationCheckerTailChars: number;\n readonly citationManifestMax: number;\n\n // app metadata\n readonly appName: string;\n readonly appDescription: string;\n readonly issueUrl: string;\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\n// Like parsePositiveInt but accepts 0 as a valid value (used to disable\n// deadlines explicitly). Negative / NaN still fall through to the default.\nfunction parseNonNegativeInt(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n >= 0 ? Math.floor(n) : fallback;\n}\n\nfunction parsePort(value: string | undefined, fallback: number): number {\n const n = parsePositiveInt(value, fallback);\n return n >= 1 && n <= 65_535 ? n : fallback;\n}\n\nfunction parseBool(value: string | undefined, fallback: boolean): boolean {\n if (value === undefined) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"1\" || v === \"true\") return true;\n if (v === \"0\" || v === \"false\") return false;\n return fallback;\n}\n\nfunction parseHallucinationMode(\n value: string | undefined,\n fallback: JarelaConfig[\"hallucinationDetectorMode\"],\n): JarelaConfig[\"hallucinationDetectorMode\"] {\n if (!value) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"off\" || v === \"regex\" || v === \"model\") return v;\n return fallback;\n}\n\nfunction parseLogLevel(value: string | undefined, fallback: \"debug\" | \"info\" | \"warn\" | \"error\"): JarelaConfig[\"logLevel\"] {\n if (!value) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"debug\" || v === \"info\" || v === \"warn\" || v === \"error\") return v;\n return fallback;\n}\n\nlet cached: JarelaConfig | null = null;\n\nfunction expandHome(p: string): string {\n return p.startsWith(\"~\") ? p.replace(/^~/, homedir()) : p;\n}\n\nexport function getConfig(): JarelaConfig {\n if (cached) return cached;\n const env = process.env;\n const dataDir = getDataDir();\n cached = {\n // network\n port: parsePort(env.JARELA_PORT ?? env.PORT, ENV_DEFAULTS.port),\n hostname: (env.JARELA_HOSTNAME ?? env.HOSTNAME ?? ENV_DEFAULTS.hostname).trim() || ENV_DEFAULTS.hostname,\n dataDir,\n toolsDir: env.JARELA_TOOLS_DIR ? expandHome(env.JARELA_TOOLS_DIR) : join(dataDir, \"tools\"),\n httpRequestTimeoutMs: parsePositiveInt(env.JARELA_HTTP_REQUEST_TIMEOUT_MS, ENV_DEFAULTS.httpRequestTimeoutMs),\n sseConnectTimeoutMs: parsePositiveInt(env.JARELA_SSE_CONNECT_TIMEOUT_MS, ENV_DEFAULTS.sseConnectTimeoutMs),\n healthCheckTimeoutMs: parsePositiveInt(env.JARELA_HEALTH_CHECK_TIMEOUT_MS, ENV_DEFAULTS.healthCheckTimeoutMs),\n httpMaxAttempts: parsePositiveInt(env.JARELA_HTTP_MAX_ATTEMPTS, ENV_DEFAULTS.httpMaxAttempts),\n\n // agent\n recursionLimit: parsePositiveInt(env.JARELA_RECURSION_LIMIT, ENV_DEFAULTS.recursionLimit),\n llmStreamMaxMs: parseNonNegativeInt(env.JARELA_LLM_STREAM_MAX_MS, ENV_DEFAULTS.llmStreamMaxMs),\n runIdleMs: parsePositiveInt(env.JARELA_RUN_IDLE_MS, ENV_DEFAULTS.runIdleMs),\n runMaxMs: parsePositiveInt(env.JARELA_RUN_MAX_MS, ENV_DEFAULTS.runMaxMs),\n runRegistryTtlMs: parsePositiveInt(env.JARELA_RUN_REGISTRY_TTL_MS, ENV_DEFAULTS.runRegistryTtlMs),\n runBufferSize: parsePositiveInt(env.JARELA_RUN_BUFFER_SIZE, ENV_DEFAULTS.runBufferSize),\n maxStallRetries: parseNonNegativeInt(env.JARELA_MAX_STALL_RETRIES, ENV_DEFAULTS.maxStallRetries),\n maxTransientRetries: parseNonNegativeInt(env.JARELA_MAX_TRANSIENT_RETRIES, ENV_DEFAULTS.maxTransientRetries),\n maxDelegationDepth: parseNonNegativeInt(env.JARELA_MAX_DELEGATION_DEPTH, ENV_DEFAULTS.maxDelegationDepth),\n streamParseTripwire: parsePositiveInt(env.JARELA_STREAM_PARSE_TRIPWIRE, ENV_DEFAULTS.streamParseTripwire),\n\n // tools\n voiceTimeoutMs: parsePositiveInt(env.JARELA_VOICE_TIMEOUT_MS, ENV_DEFAULTS.voiceTimeoutMs),\n imageTimeoutMs: parsePositiveInt(env.JARELA_IMAGE_TIMEOUT_MS, ENV_DEFAULTS.imageTimeoutMs),\n fetchToolMaxBytes: parsePositiveInt(env.JARELA_FETCH_TOOL_MAX_BYTES, ENV_DEFAULTS.fetchToolMaxBytes),\n mcpRegistryTimeoutMs: parsePositiveInt(env.JARELA_MCP_REGISTRY_TIMEOUT_MS, ENV_DEFAULTS.mcpRegistryTimeoutMs),\n execMaxOutputBytes: parsePositiveInt(env.JARELA_EXEC_MAX_OUTPUT_BYTES, ENV_DEFAULTS.execMaxOutputBytes),\n filesMaxReadBytes: parsePositiveInt(env.JARELA_FILES_MAX_READ_BYTES, ENV_DEFAULTS.filesMaxReadBytes),\n filesMaxWriteBytes: parsePositiveInt(env.JARELA_FILES_MAX_WRITE_BYTES, ENV_DEFAULTS.filesMaxWriteBytes),\n\n // lifecycle\n updateCheckTimeoutMs: parsePositiveInt(env.JARELA_UPDATE_CHECK_TIMEOUT_MS, ENV_DEFAULTS.updateCheckTimeoutMs),\n shutdownDrainMs: parsePositiveInt(env.JARELA_SHUTDOWN_DRAIN_MS, ENV_DEFAULTS.shutdownDrainMs),\n shutdownSettleMs: parseNonNegativeInt(env.JARELA_SHUTDOWN_SETTLE_MS, ENV_DEFAULTS.shutdownSettleMs),\n disableUpdateCheck: parseBool(env.JARELA_DISABLE_UPDATE_CHECK, false),\n\n // limits\n notificationRingSize: parsePositiveInt(env.JARELA_NOTIFICATION_RING_SIZE, ENV_DEFAULTS.notificationRingSize),\n\n // logging\n logsRingSize: parsePositiveInt(env.JARELA_LOGS_RING_SIZE, ENV_DEFAULTS.logsRingSize),\n logLevel: parseLogLevel(env.JARELA_LOG_LEVEL, ENV_DEFAULTS.logLevel),\n\n // scheduler\n schedulerTickMs: parsePositiveInt(env.JARELA_SCHEDULER_TICK_MS, ENV_DEFAULTS.schedulerTickMs),\n fastRemoteSweepMs: parsePositiveInt(env.JARELA_FAST_REMOTE_SWEEP_MS, ENV_DEFAULTS.fastRemoteSweepMs),\n\n // documents\n docMaxFileBytes: parsePositiveInt(env.JARELA_DOC_MAX_FILE_BYTES, ENV_DEFAULTS.docMaxFileBytes),\n docMaxFilesPerSource: parsePositiveInt(env.JARELA_DOC_MAX_FILES_PER_SOURCE, ENV_DEFAULTS.docMaxFilesPerSource),\n\n // anti-hallucination classifier\n hallucinationDetectorMode: parseHallucinationMode(\n env.JARELA_HALLUCINATION_DETECTOR_MODE,\n ENV_DEFAULTS.hallucinationDetectorMode,\n ),\n hallucinationDetectorModel: (env.JARELA_HALLUCINATION_DETECTOR_MODEL ?? ENV_DEFAULTS.hallucinationDetectorModel).trim(),\n citationCheckerTailChars: parseNonNegativeInt(env.JARELA_CITATION_CHECKER_TAIL_CHARS, ENV_DEFAULTS.citationCheckerTailChars),\n citationManifestMax: parseNonNegativeInt(env.JARELA_CITATION_MANIFEST_MAX, ENV_DEFAULTS.citationManifestMax),\n\n // app metadata\n appName: getAppName(),\n appDescription: getAppDescription(),\n issueUrl: getAppIssueUrl(),\n };\n return cached;\n}\n\n/** Drop the memoised config so the next read picks up env edits. Used by tests + the env-override PATCH endpoint. */\nexport function resetConfigCache(): void {\n cached = null;\n}\n"],"names":["getOrCreateGlobal","key","factory","g","globalThis","undefined","getConfig","state","registered","shuttingDown","HARD_TIMEOUT_MS","shutdownDrainMs","RUN_DRAIN_MS","shutdownSettleMs","registerShutdownHandlers","handler","signal","console","log","process","exit","runShutdown","catch","err","error","removeAllListeners","on","platform","forceExit","setTimeout","warn","unref","abortAllRuns","n","stopScheduler","stopAllTriggerHandlers","stopAllBridges","waitForRunsToSettle","stuck","closeDb","clearTimeout","DEFAULT_APP_NAME","DEFAULT_APP_DESCRIPTION","DEFAULT_ISSUE_URL","getAppName","env","NEXT_PUBLIC_APP_NAME","trim","getAppDescription","NEXT_PUBLIC_APP_DESCRIPTION","getAppIssueUrl","NEXT_PUBLIC_APP_ISSUE_URL","getDataDir","ENV_DEFAULTS","join","homedir","parsePositiveInt","value","fallback","Number","isFinite","Math","floor","parseNonNegativeInt","parsePort","parseBool","v","toLowerCase","parseHallucinationMode","parseLogLevel","cached","expandHome","p","startsWith","replace","dataDir","port","JARELA_PORT","PORT","hostname","JARELA_HOSTNAME","HOSTNAME","toolsDir","JARELA_TOOLS_DIR","httpRequestTimeoutMs","JARELA_HTTP_REQUEST_TIMEOUT_MS","sseConnectTimeoutMs","JARELA_SSE_CONNECT_TIMEOUT_MS","healthCheckTimeoutMs","JARELA_HEALTH_CHECK_TIMEOUT_MS","httpMaxAttempts","JARELA_HTTP_MAX_ATTEMPTS","recursionLimit","JARELA_RECURSION_LIMIT","llmStreamMaxMs","JARELA_LLM_STREAM_MAX_MS","runIdleMs","JARELA_RUN_IDLE_MS","runMaxMs","JARELA_RUN_MAX_MS","runRegistryTtlMs","JARELA_RUN_REGISTRY_TTL_MS","runBufferSize","JARELA_RUN_BUFFER_SIZE","maxStallRetries","JARELA_MAX_STALL_RETRIES","maxTransientRetries","JARELA_MAX_TRANSIENT_RETRIES","maxDelegationDepth","JARELA_MAX_DELEGATION_DEPTH","streamParseTripwire","JARELA_STREAM_PARSE_TRIPWIRE","voiceTimeoutMs","JARELA_VOICE_TIMEOUT_MS","imageTimeoutMs","JARELA_IMAGE_TIMEOUT_MS","fetchToolMaxBytes","JARELA_FETCH_TOOL_MAX_BYTES","mcpRegistryTimeoutMs","JARELA_MCP_REGISTRY_TIMEOUT_MS","execMaxOutputBytes","JARELA_EXEC_MAX_OUTPUT_BYTES","filesMaxReadBytes","JARELA_FILES_MAX_READ_BYTES","filesMaxWriteBytes","JARELA_FILES_MAX_WRITE_BYTES","updateCheckTimeoutMs","JARELA_UPDATE_CHECK_TIMEOUT_MS","JARELA_SHUTDOWN_DRAIN_MS","JARELA_SHUTDOWN_SETTLE_MS","disableUpdateCheck","JARELA_DISABLE_UPDATE_CHECK","notificationRingSize","JARELA_NOTIFICATION_RING_SIZE","logsRingSize","JARELA_LOGS_RING_SIZE","logLevel","JARELA_LOG_LEVEL","schedulerTickMs","JARELA_SCHEDULER_TICK_MS","fastRemoteSweepMs","JARELA_FAST_REMOTE_SWEEP_MS","docMaxFileBytes","JARELA_DOC_MAX_FILE_BYTES","docMaxFilesPerSource","JARELA_DOC_MAX_FILES_PER_SOURCE","hallucinationDetectorMode","JARELA_HALLUCINATION_DETECTOR_MODE","hallucinationDetectorModel","JARELA_HALLUCINATION_DETECTOR_MODEL","citationCheckerTailChars","JARELA_CITATION_CHECKER_TAIL_CHARS","citationManifestMax","JARELA_CITATION_MANIFEST_MAX","appName","appDescription","issueUrl","resetConfigCache"],"sourceRoot":"","ignoreList":[]}
1
+ {"version":3,"file":"9032.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/utils/global-state.ts","webpack://@circuitwall/jarela/./lib/lifecycle/shutdown.ts","webpack://@circuitwall/jarela/./lib/env/app-config.ts","webpack://@circuitwall/jarela/./lib/env/config.ts"],"sourcesContent":["// Pin a piece of state to globalThis so it survives Next.js dev hot-reload.\n//\n// Without this, every code edit re-evaluates the module, replacing the\n// in-memory state with empty containers — but any active closure still\n// references the OLD set, so listeners/timers/maps go silently dead.\n// The globalThis trick is the standard Next pattern for singletons.\n//\n// `key` must be unique across the app (it lives on globalThis); pick a\n// \"__jarela_<name>\" prefix to keep the namespace tidy.\nexport function getOrCreateGlobal<T>(key: string, factory: () => T): T {\n const g = globalThis as unknown as Record<string, unknown>;\n if (g[key] === undefined) g[key] = factory();\n return g[key] as T;\n}\n","// Graceful shutdown coordinator.\n//\n// Registers SIGINT / SIGTERM (and SIGBREAK on Windows) so Ctrl-C in the\n// foreground and `kill`/`systemctl stop`/Task Scheduler \"End task\" all\n// trigger the same drain sequence:\n//\n// 1. abort every in-flight LangGraph run so stream loops bail out\n// 2. stop the scheduler tick so no new firings start\n// 3. close every bridge adapter (WhatsApp WS, future kinds) cleanly\n// 4. wait briefly for the runs to actually finish flushing\n// 5. close the SQLite handle so WAL is checkpointed\n// 6. exit 0\n//\n// A hard timeout aborts the drain if any subsystem hangs — the supervisor\n// (Task Scheduler / systemd / installed-launcher.ps1) will then restart us\n// instead of leaving a zombie holding the port.\n//\n// Wired from `instrumentation.ts` so it runs once per server process at\n// boot. Idempotent: only the first call installs handlers.\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { getConfig } from \"@/lib/env/config\";\n\ninterface ShutdownState {\n registered: boolean;\n shuttingDown: boolean;\n}\nconst state = getOrCreateGlobal<ShutdownState>(\"__jarela_shutdown\", () => ({\n registered: false,\n shuttingDown: false,\n}));\n\n// JARELA_SHUTDOWN_DRAIN_MS / JARELA_SHUTDOWN_SETTLE_MS override these.\n// Captured at handler-install time (boot); these don't hot-reload because\n// the handlers close over the values.\nconst HARD_TIMEOUT_MS = getConfig().shutdownDrainMs;\nconst RUN_DRAIN_MS = getConfig().shutdownSettleMs;\n\nexport function registerShutdownHandlers(): void {\n if (state.registered) return;\n state.registered = true;\n\n const handler = (signal: NodeJS.Signals) => {\n if (state.shuttingDown) {\n // Second signal while already draining: operator is impatient, exit\n // immediately. Mirrors the behaviour every well-behaved daemon has —\n // first Ctrl-C drains, second Ctrl-C kills.\n console.log(`[jarela] received ${signal} during shutdown; forcing exit.`);\n process.exit(130);\n }\n state.shuttingDown = true;\n console.log(`[jarela] ${signal} received, draining…`);\n void runShutdown().catch((err) => {\n console.error(`[jarela] shutdown error:`, err);\n process.exit(1);\n });\n };\n\n // Replace any default handlers Next's standalone server may have\n // installed for these signals. Next's default just calls\n // `server.close(() => process.exit(0))`, which races our drain and can\n // exit the process before bridges/DB have flushed. We take over and\n // exit ourselves once drain completes.\n process.removeAllListeners(\"SIGINT\");\n process.removeAllListeners(\"SIGTERM\");\n process.on(\"SIGINT\", handler);\n process.on(\"SIGTERM\", handler);\n if (process.platform === \"win32\") {\n // Ctrl-Break in a foreground PowerShell session lands as SIGBREAK,\n // not SIGINT. Task Scheduler \"End task\" delivers SIGBREAK as well.\n process.removeAllListeners(\"SIGBREAK\");\n process.on(\"SIGBREAK\", handler);\n }\n}\n\nasync function runShutdown(): Promise<void> {\n // Safety net: if any drain step deadlocks (e.g. a bridge adapter's\n // socket.close() never resolves), force-exit so the supervisor can\n // restart cleanly instead of holding the port forever.\n const forceExit = setTimeout(() => {\n console.warn(`[jarela] drain exceeded ${HARD_TIMEOUT_MS}ms; forcing exit.`);\n process.exit(130);\n }, HARD_TIMEOUT_MS);\n forceExit.unref?.();\n\n // 1. Abort in-flight LLM runs. The route's stream loop watches this\n // AbortController and exits early, emitting a trailing error chunk.\n try {\n const { abortAllRuns } = await import(\"@/lib/agents/run-registry\");\n const n = abortAllRuns(\"server_shutdown\");\n if (n > 0) console.log(`[jarela] aborted ${n} in-flight run(s).`);\n } catch (err) {\n console.error(\"[jarela] aborting runs failed:\", err);\n }\n\n // 2. Stop the scheduler so no firing kicks off mid-drain.\n try {\n const { stopScheduler } = await import(\"@/lib/scheduler\");\n stopScheduler();\n } catch (err) {\n console.error(\"[jarela] stopping scheduler failed:\", err);\n }\n\n // 2b. Drain trigger handlers — closes fs.watch watchers and any other\n // handler that has timers / sockets attached. Independent of the\n // scheduler tick (those are run-loop ownership; this is per-handler\n // ownership of OS resources).\n try {\n const { stopAllTriggerHandlers } = await import(\"@/lib/triggers\");\n await stopAllTriggerHandlers();\n } catch (err) {\n console.error(\"[jarela] stopping trigger handlers failed:\", err);\n }\n\n // 3. Close bridges (WhatsApp Baileys WS, etc).\n try {\n const { stopAllBridges } = await import(\"@/lib/bridges/runtime\");\n await stopAllBridges();\n } catch (err) {\n console.error(\"[jarela] stopping bridges failed:\", err);\n }\n\n // 4. Give aborted runs a beat to actually finish — they were signalled\n // in step 1, but the `finally` blocks need ticks to flush trailing\n // events and persist the partial assistant message.\n try {\n const { waitForRunsToSettle } = await import(\"@/lib/agents/run-registry\");\n const stuck = await waitForRunsToSettle(RUN_DRAIN_MS);\n if (stuck > 0) console.warn(`[jarela] ${stuck} run(s) still active after drain window.`);\n } catch (err) {\n console.error(\"[jarela] waiting for runs failed:\", err);\n }\n\n // 5. Close the DB. WAL is checkpointed so the next boot is fast and we\n // leave no stale -shm/-wal sidecars on disk.\n try {\n const { closeDb } = await import(\"@/lib/db\");\n closeDb();\n } catch (err) {\n console.error(\"[jarela] closing db failed:\", err);\n }\n\n clearTimeout(forceExit);\n console.log(\"[jarela] shutdown complete.\");\n process.exit(0);\n}\n","// Branding knobs sourced from NEXT_PUBLIC_* env vars so forks can rebrand\n// the app without patching source. NEXT_PUBLIC_* is the right\n// channel here because Next.js inlines these at build time, which lets\n// client components read them directly (no React Context, no server\n// round-trip). Server-only modules read the same keys at runtime.\n//\n// Keep this module client-safe — no Node-only imports, no DB/FS access.\n\nconst DEFAULT_APP_NAME = \"Jarela\";\nconst DEFAULT_APP_DESCRIPTION = \"Jarela — local chat interface for LangGraph agents\";\nconst DEFAULT_ISSUE_URL = \"https://github.com/CircuitWall/jarela/issues/new\";\n\nexport function getAppName(): string {\n return process.env.NEXT_PUBLIC_APP_NAME?.trim() || DEFAULT_APP_NAME;\n}\n\nexport function getAppDescription(): string {\n return process.env.NEXT_PUBLIC_APP_DESCRIPTION?.trim() || DEFAULT_APP_DESCRIPTION;\n}\n\nexport function getAppIssueUrl(): string {\n return process.env.NEXT_PUBLIC_APP_ISSUE_URL?.trim() || DEFAULT_ISSUE_URL;\n}\n","// Central runtime configuration, resolved from environment variables.\n//\n// All operational knobs (port, host, data dir, timeouts, agent limits) flow\n// through this module so there is exactly one place documenting which env\n// vars Jarela respects and what the defaults are. Code MUST NOT read these\n// `process.env` keys directly — import `config` instead.\n//\n// Resolution order for every entry: explicit JARELA_* var → legacy/standard\n// var (where one exists, e.g. PORT/HOSTNAME for Next.js compatibility) →\n// schema default (lib/env/schema.ts).\n//\n// Values are resolved lazily on first read and cached. Tests + the env-\n// override PATCH endpoint must call `resetConfigCache()` between cases.\n\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { getAppName, getAppDescription, getAppIssueUrl } from \"./app-config\";\nimport { ENV_DEFAULTS } from \"./schema\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface JarelaConfig {\n // network\n readonly port: number;\n readonly hostname: string;\n readonly dataDir: string;\n readonly toolsDir: string;\n readonly httpRequestTimeoutMs: number;\n readonly sseConnectTimeoutMs: number;\n readonly healthCheckTimeoutMs: number;\n readonly httpMaxAttempts: number;\n\n // agent\n readonly recursionLimit: number;\n readonly llmStreamMaxMs: number;\n readonly runIdleMs: number;\n readonly runMaxMs: number;\n readonly runRegistryTtlMs: number;\n readonly runBufferSize: number;\n readonly maxStallRetries: number;\n readonly maxTransientRetries: number;\n readonly maxDelegationDepth: number;\n readonly streamParseTripwire: number;\n\n // tools\n readonly voiceTimeoutMs: number;\n readonly imageTimeoutMs: number;\n readonly fetchToolMaxBytes: number;\n readonly mcpRegistryTimeoutMs: number;\n readonly execMaxOutputBytes: number;\n readonly filesMaxReadBytes: number;\n readonly filesMaxWriteBytes: number;\n\n // lifecycle\n readonly updateCheckTimeoutMs: number;\n readonly shutdownDrainMs: number;\n readonly shutdownSettleMs: number;\n readonly disableUpdateCheck: boolean;\n\n // limits\n readonly notificationRingSize: number;\n\n // logging\n readonly logsRingSize: number;\n readonly logLevel: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n // scheduler\n readonly schedulerTickMs: number;\n readonly fastRemoteSweepMs: number;\n\n // documents\n readonly docMaxFileBytes: number;\n readonly docMaxFilesPerSource: number;\n\n // anti-hallucination detector\n readonly hallucinationDetectorMode: \"off\" | \"regex\" | \"model\";\n readonly hallucinationDetectorModel: string;\n readonly citationCheckerTailChars: number;\n readonly citationManifestMax: number;\n\n // app metadata\n readonly appName: string;\n readonly appDescription: string;\n readonly issueUrl: string;\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\n// Like parsePositiveInt but accepts 0 as a valid value (used to disable\n// deadlines explicitly). Negative / NaN still fall through to the default.\nfunction parseNonNegativeInt(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n >= 0 ? Math.floor(n) : fallback;\n}\n\nfunction parsePort(value: string | undefined, fallback: number): number {\n const n = parsePositiveInt(value, fallback);\n return n >= 1 && n <= 65_535 ? n : fallback;\n}\n\nfunction parseBool(value: string | undefined, fallback: boolean): boolean {\n if (value === undefined) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"1\" || v === \"true\") return true;\n if (v === \"0\" || v === \"false\") return false;\n return fallback;\n}\n\nfunction parseHallucinationMode(\n value: string | undefined,\n fallback: JarelaConfig[\"hallucinationDetectorMode\"],\n): JarelaConfig[\"hallucinationDetectorMode\"] {\n if (!value) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"off\" || v === \"regex\" || v === \"model\") return v;\n return fallback;\n}\n\nfunction parseLogLevel(value: string | undefined, fallback: \"debug\" | \"info\" | \"warn\" | \"error\"): JarelaConfig[\"logLevel\"] {\n if (!value) return fallback;\n const v = value.trim().toLowerCase();\n if (v === \"debug\" || v === \"info\" || v === \"warn\" || v === \"error\") return v;\n return fallback;\n}\n\nlet cached: JarelaConfig | null = null;\n\nfunction expandHome(p: string): string {\n return p.startsWith(\"~\") ? p.replace(/^~/, homedir()) : p;\n}\n\nexport function getConfig(): JarelaConfig {\n if (cached) return cached;\n const env = process.env;\n const dataDir = getDataDir();\n cached = {\n // network\n port: parsePort(env.JARELA_PORT ?? env.PORT, ENV_DEFAULTS.port),\n hostname: (env.JARELA_HOSTNAME ?? env.HOSTNAME ?? ENV_DEFAULTS.hostname).trim() || ENV_DEFAULTS.hostname,\n dataDir,\n toolsDir: env.JARELA_TOOLS_DIR ? expandHome(env.JARELA_TOOLS_DIR) : join(dataDir, \"tools\"),\n httpRequestTimeoutMs: parsePositiveInt(env.JARELA_HTTP_REQUEST_TIMEOUT_MS, ENV_DEFAULTS.httpRequestTimeoutMs),\n sseConnectTimeoutMs: parsePositiveInt(env.JARELA_SSE_CONNECT_TIMEOUT_MS, ENV_DEFAULTS.sseConnectTimeoutMs),\n healthCheckTimeoutMs: parsePositiveInt(env.JARELA_HEALTH_CHECK_TIMEOUT_MS, ENV_DEFAULTS.healthCheckTimeoutMs),\n httpMaxAttempts: parsePositiveInt(env.JARELA_HTTP_MAX_ATTEMPTS, ENV_DEFAULTS.httpMaxAttempts),\n\n // agent\n recursionLimit: parsePositiveInt(env.JARELA_RECURSION_LIMIT, ENV_DEFAULTS.recursionLimit),\n llmStreamMaxMs: parseNonNegativeInt(env.JARELA_LLM_STREAM_MAX_MS, ENV_DEFAULTS.llmStreamMaxMs),\n runIdleMs: parsePositiveInt(env.JARELA_RUN_IDLE_MS, ENV_DEFAULTS.runIdleMs),\n runMaxMs: parsePositiveInt(env.JARELA_RUN_MAX_MS, ENV_DEFAULTS.runMaxMs),\n runRegistryTtlMs: parsePositiveInt(env.JARELA_RUN_REGISTRY_TTL_MS, ENV_DEFAULTS.runRegistryTtlMs),\n runBufferSize: parsePositiveInt(env.JARELA_RUN_BUFFER_SIZE, ENV_DEFAULTS.runBufferSize),\n maxStallRetries: parseNonNegativeInt(env.JARELA_MAX_STALL_RETRIES, ENV_DEFAULTS.maxStallRetries),\n maxTransientRetries: parseNonNegativeInt(env.JARELA_MAX_TRANSIENT_RETRIES, ENV_DEFAULTS.maxTransientRetries),\n maxDelegationDepth: parseNonNegativeInt(env.JARELA_MAX_DELEGATION_DEPTH, ENV_DEFAULTS.maxDelegationDepth),\n streamParseTripwire: parsePositiveInt(env.JARELA_STREAM_PARSE_TRIPWIRE, ENV_DEFAULTS.streamParseTripwire),\n\n // tools\n voiceTimeoutMs: parsePositiveInt(env.JARELA_VOICE_TIMEOUT_MS, ENV_DEFAULTS.voiceTimeoutMs),\n imageTimeoutMs: parsePositiveInt(env.JARELA_IMAGE_TIMEOUT_MS, ENV_DEFAULTS.imageTimeoutMs),\n fetchToolMaxBytes: parsePositiveInt(env.JARELA_FETCH_TOOL_MAX_BYTES, ENV_DEFAULTS.fetchToolMaxBytes),\n mcpRegistryTimeoutMs: parsePositiveInt(env.JARELA_MCP_REGISTRY_TIMEOUT_MS, ENV_DEFAULTS.mcpRegistryTimeoutMs),\n execMaxOutputBytes: parsePositiveInt(env.JARELA_EXEC_MAX_OUTPUT_BYTES, ENV_DEFAULTS.execMaxOutputBytes),\n filesMaxReadBytes: parsePositiveInt(env.JARELA_FILES_MAX_READ_BYTES, ENV_DEFAULTS.filesMaxReadBytes),\n filesMaxWriteBytes: parsePositiveInt(env.JARELA_FILES_MAX_WRITE_BYTES, ENV_DEFAULTS.filesMaxWriteBytes),\n\n // lifecycle\n updateCheckTimeoutMs: parsePositiveInt(env.JARELA_UPDATE_CHECK_TIMEOUT_MS, ENV_DEFAULTS.updateCheckTimeoutMs),\n shutdownDrainMs: parsePositiveInt(env.JARELA_SHUTDOWN_DRAIN_MS, ENV_DEFAULTS.shutdownDrainMs),\n shutdownSettleMs: parseNonNegativeInt(env.JARELA_SHUTDOWN_SETTLE_MS, ENV_DEFAULTS.shutdownSettleMs),\n disableUpdateCheck: parseBool(env.JARELA_DISABLE_UPDATE_CHECK, false),\n\n // limits\n notificationRingSize: parsePositiveInt(env.JARELA_NOTIFICATION_RING_SIZE, ENV_DEFAULTS.notificationRingSize),\n\n // logging\n logsRingSize: parsePositiveInt(env.JARELA_LOGS_RING_SIZE, ENV_DEFAULTS.logsRingSize),\n logLevel: parseLogLevel(env.JARELA_LOG_LEVEL, ENV_DEFAULTS.logLevel),\n\n // scheduler\n schedulerTickMs: parsePositiveInt(env.JARELA_SCHEDULER_TICK_MS, ENV_DEFAULTS.schedulerTickMs),\n fastRemoteSweepMs: parsePositiveInt(env.JARELA_FAST_REMOTE_SWEEP_MS, ENV_DEFAULTS.fastRemoteSweepMs),\n\n // documents\n docMaxFileBytes: parsePositiveInt(env.JARELA_DOC_MAX_FILE_BYTES, ENV_DEFAULTS.docMaxFileBytes),\n docMaxFilesPerSource: parsePositiveInt(env.JARELA_DOC_MAX_FILES_PER_SOURCE, ENV_DEFAULTS.docMaxFilesPerSource),\n\n // anti-hallucination classifier\n hallucinationDetectorMode: parseHallucinationMode(\n env.JARELA_HALLUCINATION_DETECTOR_MODE,\n ENV_DEFAULTS.hallucinationDetectorMode,\n ),\n hallucinationDetectorModel: (env.JARELA_HALLUCINATION_DETECTOR_MODEL ?? ENV_DEFAULTS.hallucinationDetectorModel).trim(),\n citationCheckerTailChars: parseNonNegativeInt(env.JARELA_CITATION_CHECKER_TAIL_CHARS, ENV_DEFAULTS.citationCheckerTailChars),\n citationManifestMax: parseNonNegativeInt(env.JARELA_CITATION_MANIFEST_MAX, ENV_DEFAULTS.citationManifestMax),\n\n // app metadata\n appName: getAppName(),\n appDescription: getAppDescription(),\n issueUrl: getAppIssueUrl(),\n };\n return cached;\n}\n\n/** Drop the memoised config so the next read picks up env edits. Used by tests + the env-override PATCH endpoint. */\nexport function resetConfigCache(): void {\n cached = null;\n}\n"],"names":["getOrCreateGlobal","key","factory","g","globalThis","undefined","getConfig","state","registered","shuttingDown","HARD_TIMEOUT_MS","shutdownDrainMs","RUN_DRAIN_MS","shutdownSettleMs","registerShutdownHandlers","handler","signal","console","log","process","exit","runShutdown","catch","err","error","removeAllListeners","on","platform","forceExit","setTimeout","warn","unref","abortAllRuns","n","stopScheduler","stopAllTriggerHandlers","stopAllBridges","waitForRunsToSettle","stuck","closeDb","clearTimeout","DEFAULT_APP_NAME","DEFAULT_APP_DESCRIPTION","DEFAULT_ISSUE_URL","getAppName","env","NEXT_PUBLIC_APP_NAME","trim","getAppDescription","NEXT_PUBLIC_APP_DESCRIPTION","getAppIssueUrl","NEXT_PUBLIC_APP_ISSUE_URL","getDataDir","ENV_DEFAULTS","join","homedir","parsePositiveInt","value","fallback","Number","isFinite","Math","floor","parseNonNegativeInt","parsePort","parseBool","v","toLowerCase","parseHallucinationMode","parseLogLevel","cached","expandHome","p","startsWith","replace","dataDir","port","JARELA_PORT","PORT","hostname","JARELA_HOSTNAME","HOSTNAME","toolsDir","JARELA_TOOLS_DIR","httpRequestTimeoutMs","JARELA_HTTP_REQUEST_TIMEOUT_MS","sseConnectTimeoutMs","JARELA_SSE_CONNECT_TIMEOUT_MS","healthCheckTimeoutMs","JARELA_HEALTH_CHECK_TIMEOUT_MS","httpMaxAttempts","JARELA_HTTP_MAX_ATTEMPTS","recursionLimit","JARELA_RECURSION_LIMIT","llmStreamMaxMs","JARELA_LLM_STREAM_MAX_MS","runIdleMs","JARELA_RUN_IDLE_MS","runMaxMs","JARELA_RUN_MAX_MS","runRegistryTtlMs","JARELA_RUN_REGISTRY_TTL_MS","runBufferSize","JARELA_RUN_BUFFER_SIZE","maxStallRetries","JARELA_MAX_STALL_RETRIES","maxTransientRetries","JARELA_MAX_TRANSIENT_RETRIES","maxDelegationDepth","JARELA_MAX_DELEGATION_DEPTH","streamParseTripwire","JARELA_STREAM_PARSE_TRIPWIRE","voiceTimeoutMs","JARELA_VOICE_TIMEOUT_MS","imageTimeoutMs","JARELA_IMAGE_TIMEOUT_MS","fetchToolMaxBytes","JARELA_FETCH_TOOL_MAX_BYTES","mcpRegistryTimeoutMs","JARELA_MCP_REGISTRY_TIMEOUT_MS","execMaxOutputBytes","JARELA_EXEC_MAX_OUTPUT_BYTES","filesMaxReadBytes","JARELA_FILES_MAX_READ_BYTES","filesMaxWriteBytes","JARELA_FILES_MAX_WRITE_BYTES","updateCheckTimeoutMs","JARELA_UPDATE_CHECK_TIMEOUT_MS","JARELA_SHUTDOWN_DRAIN_MS","JARELA_SHUTDOWN_SETTLE_MS","disableUpdateCheck","JARELA_DISABLE_UPDATE_CHECK","notificationRingSize","JARELA_NOTIFICATION_RING_SIZE","logsRingSize","JARELA_LOGS_RING_SIZE","logLevel","JARELA_LOG_LEVEL","schedulerTickMs","JARELA_SCHEDULER_TICK_MS","fastRemoteSweepMs","JARELA_FAST_REMOTE_SWEEP_MS","docMaxFileBytes","JARELA_DOC_MAX_FILE_BYTES","docMaxFilesPerSource","JARELA_DOC_MAX_FILES_PER_SOURCE","hallucinationDetectorMode","JARELA_HALLUCINATION_DETECTOR_MODE","hallucinationDetectorModel","JARELA_HALLUCINATION_DETECTOR_MODEL","citationCheckerTailChars","JARELA_CITATION_CHECKER_TAIL_CHARS","citationManifestMax","JARELA_CITATION_MANIFEST_MAX","appName","appDescription","issueUrl","resetConfigCache"],"sourceRoot":"","ignoreList":[]}
@@ -4,8 +4,8 @@ globalThis.__BUILD_MANIFEST = {
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/T0p2VVPsJPj44rwbmjaFb/_buildManifest.js",
8
- "static/T0p2VVPsJPj44rwbmjaFb/_ssgManifest.js"
7
+ "static/d_vhp-lJqfdjRFpnLVIqZ/_buildManifest.js",
8
+ "static/d_vhp-lJqfdjRFpnLVIqZ/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
11
  "static/chunks/webpack-ff5627013a5e3842.js",
@@ -39293,6 +39293,7 @@ function runMigrations(db) {
39293
39293
  ensureScheduledTasksReactionKindColumns(db);
39294
39294
  ensureMessageUsageTable(db);
39295
39295
  ensureMessageUsageTierColumns(db);
39296
+ ensureMessageUsageCacheColumns(db);
39296
39297
  ensureThreadContextPinColumns(db);
39297
39298
  ensureThreadChannelSummariesTable(db);
39298
39299
  seedModelConfigs(db);
@@ -39703,6 +39704,19 @@ function ensureMessageUsageTierColumns(db) {
39703
39704
  if (!names.has("facts_budget_tokens")) db.exec("ALTER TABLE message_usage ADD COLUMN facts_budget_tokens INTEGER");
39704
39705
  if (!names.has("context_window_tokens")) db.exec("ALTER TABLE message_usage ADD COLUMN context_window_tokens INTEGER");
39705
39706
  }
39707
+ // PR #181 enabled Anthropic prompt caching, but the per-turn usage snapshot
39708
+ // only captured `input_tokens` / `output_tokens`. Anthropic returns cache
39709
+ // reads and writes as separate counts (priced at 0.1× and 1.25× the input
39710
+ // rate respectively), so without these columns the dashboard underreports
39711
+ // cost on cache-creating turns and *over*reports on cache-hitting turns.
39712
+ // Both columns are nullable: legacy rows and non-Anthropic providers leave
39713
+ // them NULL.
39714
+ function ensureMessageUsageCacheColumns(db) {
39715
+ const cols = db.prepare("PRAGMA table_info(message_usage)").all();
39716
+ const names = new Set(cols.map((c)=>c.name));
39717
+ if (!names.has("cache_creation_input_tokens")) db.exec("ALTER TABLE message_usage ADD COLUMN cache_creation_input_tokens INTEGER");
39718
+ if (!names.has("cache_read_input_tokens")) db.exec("ALTER TABLE message_usage ADD COLUMN cache_read_input_tokens INTEGER");
39719
+ }
39706
39720
  function seedAgentConfigs(db) {
39707
39721
  // Only seed on first run — once the user has any agents we must not
39708
39722
  // resurrect ones they've deleted (e.g. the legacy "echo" / "llm" defaults).
@@ -49755,6 +49769,87 @@ function appendServerTools(anthropicTools, params) {
49755
49769
  }
49756
49770
  return merged;
49757
49771
  }
49772
+ // Anthropic prompt-caching breakpoints. Within a multi-tool ReAct turn the
49773
+ // system prompt + tools are stable across every LLM call, and tool_results
49774
+ // only grow at the tail — exactly the prefix Anthropic's ephemeral cache is
49775
+ // built for. We mark three breakpoints (system, last tool, last tool_result)
49776
+ // so calls 2..N read the prefix at ~10% the input rate. The prefix below the
49777
+ // minimum cacheable size is silently ignored by the API at no extra cost,
49778
+ // so it is safe to mark unconditionally.
49779
+ const EPHEMERAL = {
49780
+ type: "ephemeral"
49781
+ };
49782
+ function withSystemCacheControl(text) {
49783
+ if (!text) return undefined;
49784
+ return [
49785
+ {
49786
+ type: "text",
49787
+ text,
49788
+ cache_control: EPHEMERAL
49789
+ }
49790
+ ];
49791
+ }
49792
+ function withToolsCacheControl(tools) {
49793
+ if (tools.length === 0) return tools;
49794
+ const last = tools[tools.length - 1];
49795
+ return [
49796
+ ...tools.slice(0, -1),
49797
+ {
49798
+ ...last,
49799
+ cache_control: EPHEMERAL
49800
+ }
49801
+ ];
49802
+ }
49803
+ function withLastToolResultCacheControl(messages) {
49804
+ for(let i = messages.length - 1; i >= 0; i--){
49805
+ const m = messages[i];
49806
+ if (typeof m.content === "string") continue;
49807
+ const blocks = m.content;
49808
+ for(let j = blocks.length - 1; j >= 0; j--){
49809
+ const b = blocks[j];
49810
+ if (b.type === "tool_result") {
49811
+ const newBlocks = [
49812
+ ...blocks
49813
+ ];
49814
+ newBlocks[j] = {
49815
+ ...b,
49816
+ cache_control: EPHEMERAL
49817
+ };
49818
+ const next = [
49819
+ ...messages
49820
+ ];
49821
+ next[i] = {
49822
+ ...m,
49823
+ content: newBlocks
49824
+ };
49825
+ return next;
49826
+ }
49827
+ }
49828
+ }
49829
+ return messages;
49830
+ }
49831
+ function usageEventFromStart(usage) {
49832
+ if (!usage) return null;
49833
+ return {
49834
+ type: "usage",
49835
+ input_tokens: usage.input_tokens ?? 0,
49836
+ output_tokens: usage.output_tokens ?? 0,
49837
+ cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0,
49838
+ cache_read_input_tokens: usage.cache_read_input_tokens ?? 0
49839
+ };
49840
+ }
49841
+ function usageEventFromDelta(usage) {
49842
+ if (!usage) return null;
49843
+ // message_delta only carries the *final* output_tokens; input/cache fields
49844
+ // are already accounted for from message_start. Emitting just the output
49845
+ // delta here keeps the agent loop's running total accurate without
49846
+ // double-counting cache reads.
49847
+ return {
49848
+ type: "usage",
49849
+ input_tokens: 0,
49850
+ output_tokens: usage.output_tokens ?? 0
49851
+ };
49852
+ }
49758
49853
  const anthropicProvider = {
49759
49854
  name: "anthropic",
49760
49855
  async chat (model_id, messages, params) {
@@ -49772,7 +49867,7 @@ const anthropicProvider = {
49772
49867
  const stream = await client.messages.stream({
49773
49868
  model: model_id,
49774
49869
  max_tokens: params.max_tokens ?? 4096,
49775
- system: systemText || undefined,
49870
+ system: withSystemCacheControl(systemText),
49776
49871
  messages: userMessages
49777
49872
  });
49778
49873
  return {
@@ -49792,12 +49887,13 @@ const anthropicProvider = {
49792
49887
  defaultHeaders: params.extra_headers
49793
49888
  });
49794
49889
  const systemMsg = messages.find((m)=>m.role === "system");
49795
- const msgList = toAnthropicMessages(messages.filter((m)=>m.role !== "system"));
49796
- const anthropicTools = appendServerTools(toAnthropicTools(tools), params);
49890
+ const systemText = typeof systemMsg?.content === "string" ? systemMsg.content : "";
49891
+ const msgList = withLastToolResultCacheControl(toAnthropicMessages(messages.filter((m)=>m.role !== "system")));
49892
+ const anthropicTools = withToolsCacheControl(appendServerTools(toAnthropicTools(tools), params));
49797
49893
  const resp = await client.messages.create({
49798
49894
  model: model_id,
49799
49895
  max_tokens: params.max_tokens ?? 4096,
49800
- system: typeof systemMsg?.content === "string" ? systemMsg.content : undefined,
49896
+ system: withSystemCacheControl(systemText),
49801
49897
  messages: msgList,
49802
49898
  tools: anthropicTools,
49803
49899
  ...params.thinking ? {
@@ -49825,15 +49921,17 @@ const anthropicProvider = {
49825
49921
  defaultHeaders: params.extra_headers
49826
49922
  });
49827
49923
  const systemMsg = messages.find((m)=>m.role === "system");
49828
- const msgList = toAnthropicMessages(messages.filter((m)=>m.role !== "system"));
49829
- const anthropicTools = appendServerTools(toAnthropicTools(tools), params);
49924
+ const systemText = typeof systemMsg?.content === "string" ? systemMsg.content : "";
49925
+ const msgList = withLastToolResultCacheControl(toAnthropicMessages(messages.filter((m)=>m.role !== "system")));
49926
+ const anthropicTools = withToolsCacheControl(appendServerTools(toAnthropicTools(tools), params));
49830
49927
  const body = {
49831
49928
  model: model_id,
49832
49929
  max_tokens: params.max_tokens ?? 4096,
49833
49930
  messages: msgList,
49834
49931
  ...pickAnthropicOptions(params)
49835
49932
  };
49836
- if (typeof systemMsg?.content === "string") body.system = systemMsg.content;
49933
+ const systemParam = withSystemCacheControl(systemText);
49934
+ if (systemParam) body.system = systemParam;
49837
49935
  if (anthropicTools.length > 0) body.tools = anthropicTools;
49838
49936
  if (params.thinking) {
49839
49937
  body.thinking = params.thinking;
@@ -49842,6 +49940,12 @@ const anthropicProvider = {
49842
49940
  const stream = client.messages.stream(body);
49843
49941
  const blockType = new Map();
49844
49942
  for await (const event of stream){
49943
+ if (event.type === "message_start") {
49944
+ const ev = event;
49945
+ const u = usageEventFromStart(ev.message?.usage);
49946
+ if (u) yield u;
49947
+ continue;
49948
+ }
49845
49949
  if (event.type === "content_block_start") {
49846
49950
  const cb = event.content_block;
49847
49951
  if (cb.type === "tool_use") {
@@ -49876,12 +49980,17 @@ const anthropicProvider = {
49876
49980
  args_delta: d.partial_json
49877
49981
  };
49878
49982
  }
49879
- } else if (event.type === "message_delta" && event.delta?.stop_reason) {
49880
- const reason = event.delta.stop_reason;
49881
- yield {
49882
- type: "stop",
49883
- reason: reason === "tool_use" ? "tool_use" : reason === "max_tokens" ? "length" : "stop"
49884
- };
49983
+ } else if (event.type === "message_delta") {
49984
+ const delta = event;
49985
+ const u = usageEventFromDelta(delta.usage);
49986
+ if (u) yield u;
49987
+ if (event.delta?.stop_reason) {
49988
+ const reason = event.delta.stop_reason;
49989
+ yield {
49990
+ type: "stop",
49991
+ reason: reason === "tool_use" ? "tool_use" : reason === "max_tokens" ? "length" : "stop"
49992
+ };
49993
+ }
49885
49994
  }
49886
49995
  }
49887
49996
  }();
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html lang="en" data-theme="system"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"/><link rel="stylesheet" href="/_next/static/css/6f8b1a84bcbcd467.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-ff5627013a5e3842.js"/><script src="/_next/static/chunks/4bd1b696-f4afdf0ad1d556a5.js" async=""></script><script src="/_next/static/chunks/3457-5218e06617c4db2a.js" async=""></script><script src="/_next/static/chunks/main-app-3f37bcefd1eaffaf.js" async=""></script><script src="/_next/static/chunks/app/layout-84c6f211a7a1ca36.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#09090b" media="(prefers-color-scheme: dark)"/><title>Jarela</title><meta name="description" content="Jarela — local chat interface for LangGraph agents"/><link rel="manifest" href="/manifest.json"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-title" content="Jarela"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"/><link rel="icon" href="/icon-512.png" type="image/png" sizes="512x512"/><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180"/><script>(() => {
1
+ <!DOCTYPE html><html lang="en" data-theme="system"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"/><link rel="stylesheet" href="/_next/static/css/e57bdbbbb5a05779.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-ff5627013a5e3842.js"/><script src="/_next/static/chunks/4bd1b696-f4afdf0ad1d556a5.js" async=""></script><script src="/_next/static/chunks/3457-5218e06617c4db2a.js" async=""></script><script src="/_next/static/chunks/main-app-3f37bcefd1eaffaf.js" async=""></script><script src="/_next/static/chunks/app/layout-84c6f211a7a1ca36.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#09090b" media="(prefers-color-scheme: dark)"/><title>Jarela</title><meta name="description" content="Jarela — local chat interface for LangGraph agents"/><link rel="manifest" href="/manifest.json"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-title" content="Jarela"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"/><link rel="icon" href="/icon-512.png" type="image/png" sizes="512x512"/><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180"/><script>(() => {
2
2
  var LIGHT = "#ffffff", DARK = "#09090b";
3
3
  function resolve(t) {
4
4
  if (t === "light") return LIGHT;
@@ -27,4 +27,4 @@
27
27
  } catch (e) {
28
28
  document.documentElement.setAttribute("data-theme", "system");
29
29
  }
30
- })();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-ff5627013a5e3842.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n3:I[737,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"ThemeProvider\"]\n4:I[3639,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"AppProvider\"]\n5:I[7121,[],\"\"]\n6:I[4581,[],\"\"]\n7:I[722,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"ServiceWorkerRegistration\"]\n8:I[484,[],\"OutletBoundary\"]\n9:\"$Sreact.suspense\"\nc:I[484,[],\"ViewportBoundary\"]\ne:I[484,[],\"MetadataBoundary\"]\n10:I[7123,[],\"default\",1]\n:HL[\"/_next/static/css/6f8b1a84bcbcd467.css\",\"style\"]\n2:T4b9,(() =\u003e {\n var LIGHT = \"#ffffff\", DARK = \"#09090b\";\n function resolve(t) {\n if (t === \"light\") return LIGHT;\n if (t === \"dark\") return DARK;\n try {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK : LIGHT;\n } catch (e) { return DARK; }\n }\n try {\n var t = localStorage.getItem(\"jarela-theme\");\n if (t !== \"light\" \u0026\u0026 t !== \"dark\" \u0026\u0026 t !== \"system\") t = \"system\";\n document.documentElement.setAttribute(\"data-theme\", t);\n // Collapse any media-scoped theme-color metas Next emits to a single tag\n // so the PWA window chrome matches the user's explicit choice (not just\n // prefers-color-scheme). ThemeContext keeps this in sync on change.\n var metas = document.querySelectorAll('meta[name=\"theme-color\"]');\n for (var i = 1; i \u003c metas.length; i++) metas[i].parentNode.removeChild(metas[i]);\n var meta = metas[0];\n if (!meta) {\n meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"theme-color\");\n document.head.appendChild(meta);\n }\n meta.removeAttribute(\"media\");\n meta.setAttribute(\"content\", resolve(t));\n } catch (e) {\n document.documentElement.setAttribute(\"data-theme\", \"system\");\n }\n})();"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/6f8b1a84bcbcd467.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"system\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$2\"}}]}],[\"$\",\"body\",null,{\"children\":[[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}],[\"$\",\"$L7\",null,{}]]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L8\",null,{\"children\":[\"$\",\"$9\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@a\"}]}]]}],{},null,false,null]},null,false,\"$@b\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$Lc\",null,{\"children\":\"$Ld\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$9\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lf\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$10\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"T0p2VVPsJPj44rwbmjaFb\"}\n"])</script><script>self.__next_f.push([1,"11:[]\nb:\"$W11\"\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#ffffff\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"content\":\"#09090b\",\"media\":\"(prefers-color-scheme: dark)\"}]]\n"])</script><script>self.__next_f.push([1,"12:I[6869,[],\"IconMark\"]\na:null\nf:[[\"$\",\"title\",\"0\",{\"children\":\"Jarela\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Jarela — local chat interface for LangGraph agents\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.json\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"meta\",\"3\",{\"name\":\"mobile-web-app-capable\",\"content\":\"yes\"}],[\"$\",\"meta\",\"4\",{\"name\":\"apple-mobile-web-app-title\",\"content\":\"Jarela\"}],[\"$\",\"meta\",\"5\",{\"name\":\"apple-mobile-web-app-status-bar-style\",\"content\":\"black-translucent\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"7\",{\"rel\":\"icon\",\"href\":\"/icon-192.png\",\"type\":\"image/png\",\"sizes\":\"192x192\"}],[\"$\",\"link\",\"8\",{\"rel\":\"icon\",\"href\":\"/icon-512.png\",\"type\":\"image/png\",\"sizes\":\"512x512\"}],[\"$\",\"link\",\"9\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\",\"sizes\":\"180x180\"}],[\"$\",\"$L12\",\"10\",{}]]\n"])</script></body></html>
30
+ })();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-ff5627013a5e3842.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n3:I[737,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"ThemeProvider\"]\n4:I[3639,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"AppProvider\"]\n5:I[7121,[],\"\"]\n6:I[4581,[],\"\"]\n7:I[722,[\"7177\",\"static/chunks/app/layout-84c6f211a7a1ca36.js\"],\"ServiceWorkerRegistration\"]\n8:I[484,[],\"OutletBoundary\"]\n9:\"$Sreact.suspense\"\nc:I[484,[],\"ViewportBoundary\"]\ne:I[484,[],\"MetadataBoundary\"]\n10:I[7123,[],\"default\",1]\n:HL[\"/_next/static/css/e57bdbbbb5a05779.css\",\"style\"]\n2:T4b9,(() =\u003e {\n var LIGHT = \"#ffffff\", DARK = \"#09090b\";\n function resolve(t) {\n if (t === \"light\") return LIGHT;\n if (t === \"dark\") return DARK;\n try {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK : LIGHT;\n } catch (e) { return DARK; }\n }\n try {\n var t = localStorage.getItem(\"jarela-theme\");\n if (t !== \"light\" \u0026\u0026 t !== \"dark\" \u0026\u0026 t !== \"system\") t = \"system\";\n document.documentElement.setAttribute(\"data-theme\", t);\n // Collapse any media-scoped theme-color metas Next emits to a single tag\n // so the PWA window chrome matches the user's explicit choice (not just\n // prefers-color-scheme). ThemeContext keeps this in sync on change.\n var metas = document.querySelectorAll('meta[name=\"theme-color\"]');\n for (var i = 1; i \u003c metas.length; i++) metas[i].parentNode.removeChild(metas[i]);\n var meta = metas[0];\n if (!meta) {\n meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"theme-color\");\n document.head.appendChild(meta);\n }\n meta.removeAttribute(\"media\");\n meta.setAttribute(\"content\", resolve(t));\n } catch (e) {\n document.documentElement.setAttribute(\"data-theme\", \"system\");\n }\n})();"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/e57bdbbbb5a05779.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"system\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$2\"}}]}],[\"$\",\"body\",null,{\"children\":[[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}],[\"$\",\"$L7\",null,{}]]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L8\",null,{\"children\":[\"$\",\"$9\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@a\"}]}]]}],{},null,false,null]},null,false,\"$@b\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$Lc\",null,{\"children\":\"$Ld\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$9\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lf\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$10\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"d_vhp-lJqfdjRFpnLVIqZ\"}\n"])</script><script>self.__next_f.push([1,"11:[]\nb:\"$W11\"\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#ffffff\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"content\":\"#09090b\",\"media\":\"(prefers-color-scheme: dark)\"}]]\n"])</script><script>self.__next_f.push([1,"12:I[6869,[],\"IconMark\"]\na:null\nf:[[\"$\",\"title\",\"0\",{\"children\":\"Jarela\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Jarela — local chat interface for LangGraph agents\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.json\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"meta\",\"3\",{\"name\":\"mobile-web-app-capable\",\"content\":\"yes\"}],[\"$\",\"meta\",\"4\",{\"name\":\"apple-mobile-web-app-title\",\"content\":\"Jarela\"}],[\"$\",\"meta\",\"5\",{\"name\":\"apple-mobile-web-app-status-bar-style\",\"content\":\"black-translucent\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"7\",{\"rel\":\"icon\",\"href\":\"/icon-192.png\",\"type\":\"image/png\",\"sizes\":\"192x192\"}],[\"$\",\"link\",\"8\",{\"rel\":\"icon\",\"href\":\"/icon-512.png\",\"type\":\"image/png\",\"sizes\":\"512x512\"}],[\"$\",\"link\",\"9\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\",\"sizes\":\"180x180\"}],[\"$\",\"$L12\",\"10\",{}]]\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-ff5627013a5e3842.js"/><script src="/_next/static/chunks/4bd1b696-f4afdf0ad1d556a5.js" async=""></script><script src="/_next/static/chunks/3457-5218e06617c4db2a.js" async=""></script><script src="/_next/static/chunks/main-app-3f37bcefd1eaffaf.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-ff5627013a5e3842.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[7121,[],\"\"]\n3:I[4581,[],\"\"]\n4:I[484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[484,[],\"ViewportBoundary\"]\na:I[484,[],\"MetadataBoundary\"]\nc:I[7123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"T0p2VVPsJPj44rwbmjaFb\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-ff5627013a5e3842.js"/><script src="/_next/static/chunks/4bd1b696-f4afdf0ad1d556a5.js" async=""></script><script src="/_next/static/chunks/3457-5218e06617c4db2a.js" async=""></script><script src="/_next/static/chunks/main-app-3f37bcefd1eaffaf.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-ff5627013a5e3842.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[7121,[],\"\"]\n3:I[4581,[],\"\"]\n4:I[484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[484,[],\"ViewportBoundary\"]\na:I[484,[],\"MetadataBoundary\"]\nc:I[7123,[],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"d_vhp-lJqfdjRFpnLVIqZ\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>