shadow-claw 1.23.3 → 1.24.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 (286) hide show
  1. package/README.md +42 -5
  2. package/bin/assert-version-bump.mjs +60 -38
  3. package/bin/assert-version-bump.test.mjs +74 -11
  4. package/bin/cli.mjs +166 -0
  5. package/bin/cli.test.mjs +60 -0
  6. package/bin/commands/backup.mjs +70 -0
  7. package/bin/commands/clients.mjs +41 -0
  8. package/bin/commands/peer-id.mjs +76 -0
  9. package/bin/commands/peer-id.test.mjs +104 -0
  10. package/bin/commands/send.mjs +51 -0
  11. package/bin/commands/tasks.mjs +59 -0
  12. package/bin/commands/webrtc-listen.mjs +254 -0
  13. package/bin/prerender-dsd-shell/prerender-dsd-shell.test.mjs +46 -0
  14. package/bin/rolldown.config.test.mjs +401 -8
  15. package/bin/utils/control-client.mjs +243 -0
  16. package/bin/utils/control-client.test.mjs +83 -0
  17. package/bin/utils/ulid.mjs +45 -0
  18. package/bin/utils/webrtc-control-client.mjs +699 -0
  19. package/bin/utils/webrtc-control-client.test.mjs +318 -0
  20. package/dist/electron/main.cjs +1 -1
  21. package/dist/public/AGENTS.md +5 -3
  22. package/dist/public/README.md +42 -5
  23. package/dist/public/agent.worker.js +6 -6
  24. package/dist/public/{app-routes-B0ePT49v.js → app-routes-Bs-riIvr.js} +1 -1
  25. package/dist/public/backup-controller-C_s9in2t.js +1 -0
  26. package/dist/public/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.css +1 -0
  27. package/dist/public/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.html +1 -0
  28. package/dist/public/components/settings/shadow-claw-storage/shadow-claw-storage.html +1 -1
  29. package/dist/public/components/settings/shadow-claw-task-server/shadow-claw-task-server.css +1 -1
  30. package/dist/public/components/settings/shadow-claw-task-server/shadow-claw-task-server.html +1 -1
  31. package/dist/public/components/shadow-claw-files/shadow-claw-files.css +1 -1
  32. package/dist/public/components/shadow-claw-files/shadow-claw-files.html +1 -1
  33. package/dist/public/components/shadow-claw-settings/shadow-claw-settings.html +1 -1
  34. package/dist/public/config-CrHchneq.js +1 -0
  35. package/dist/public/{configurePeerJs-B7kNU8AQ.js → configurePeerJs-CxpZeDJJ.js} +1 -1
  36. package/dist/public/{connections-xd_66YVU.js → connections-DvbgdkaB.js} +1 -1
  37. package/dist/public/{custom-element-security-CZ92anB8.js → custom-element-security-NCqQ5lmC.js} +1 -1
  38. package/dist/public/docs/README.md +3 -1
  39. package/dist/public/docs/architecture/overview.md +12 -12
  40. package/dist/public/docs/architecture/storage.md +5 -2
  41. package/dist/public/docs/decisions/bundled-typescript-architecture.md +1 -1
  42. package/dist/public/docs/decisions/indexeddb-and-opfs-storage.md +6 -3
  43. package/dist/public/docs/decisions/native-web-components-and-signals.md +1 -1
  44. package/dist/public/docs/example/article/index.html +2 -2
  45. package/dist/public/docs/guides/configuring-messaging-channels.md +41 -6
  46. package/dist/public/docs/guides/server-development-configuration.md +24 -0
  47. package/dist/public/docs/publishing/index.html +19 -76
  48. package/dist/public/docs/skill-creator/index.html +2 -2
  49. package/dist/public/docs/subsystems/backup.md +56 -0
  50. package/dist/public/docs/subsystems/cli.md +124 -0
  51. package/dist/public/docs/subsystems/control-plane.md +158 -0
  52. package/dist/public/docs/subsystems/notifications.md +54 -2
  53. package/dist/public/docs/subsystems/reactive-ui.md +1 -0
  54. package/dist/public/downloadGroupFile-By0GR6eV.js +1 -0
  55. package/dist/public/e2e/README.md +5 -1
  56. package/dist/public/{e2e-bridge-DkS5xFGX.js → e2e-bridge-IGWsRl4i.js} +1 -1
  57. package/dist/public/file-viewer-D0eflgt6.js +1 -0
  58. package/dist/public/files/main/~/docs/publishing-to-github-pages.md +17 -82
  59. package/dist/public/getAllTasks-vpBlgGsc.js +1 -0
  60. package/dist/public/getGroupDir-P1h9wl6S.js +1 -0
  61. package/dist/public/{git-BkjrsRXX.js → git-7Vq_SJSp.js} +2 -2
  62. package/dist/public/{iframe-sanitizer-L6Jyu__Z.js → iframe-sanitizer-y2Z1pPwY.js} +1 -1
  63. package/dist/public/index.html +2 -2
  64. package/dist/public/index.js +1 -1
  65. package/dist/public/{initChatSplitResize-BslPXAXS.js → initChatSplitResize-CzV2E7Ul.js} +1 -1
  66. package/dist/public/initControlPlane-C9jpnWev.js +1 -0
  67. package/dist/public/llms.txt +1 -1
  68. package/dist/public/main/index.html +2 -2
  69. package/dist/public/main/memory/index.html +2 -2
  70. package/dist/public/{markdown-6MBrIo-S.js → markdown-BnpKxSxl.js} +1 -1
  71. package/dist/public/mcp-reconnect-9emsqGRe.js +1 -0
  72. package/dist/public/{memoryStorage-CjGseKI1.js → memoryStorage-C0KvLNUp.js} +1 -1
  73. package/dist/public/{orchestrator-B9KmIj8Q.js → orchestrator-3h9xxHUm.js} +676 -676
  74. package/dist/public/orchestrator-nJj59RqD.js +15 -0
  75. package/dist/public/pages/main/~/docs/publishing-to-github-pages.md +17 -82
  76. package/dist/public/{peerjs-Dv8JNm7v.js → peerjs-BP4laMXj.js} +1 -1
  77. package/dist/public/{push-client-Dqq06wbB.js → push-client-CrjEXK3U.js} +1 -1
  78. package/dist/public/service-worker/fetch-proxy.js +1 -1
  79. package/dist/public/service-worker/push-handler.js +1 -1
  80. package/dist/public/service-worker.js +1 -1
  81. package/dist/public/{shadow-claw-Bd1rfuVC.js → shadow-claw-CbwETBWf.js} +2 -2
  82. package/dist/public/{shadow-claw-accounts-DL2l3oM0.js → shadow-claw-accounts-B4sBTQEj.js} +3 -3
  83. package/dist/public/{shadow-claw-channels-BGXDsQ38.js → shadow-claw-channels-BDWG5Qa3.js} +1 -1
  84. package/dist/public/{shadow-claw-chat-NXg6zz_l.js → shadow-claw-chat-Crv0DTCY.js} +6 -6
  85. package/dist/public/shadow-claw-control-plane-CX1IGbh9.js +199 -0
  86. package/dist/public/{shadow-claw-conversations-C8eqGpP9.js → shadow-claw-conversations-_9qAaRXk.js} +1 -1
  87. package/dist/public/shadow-claw-dialog-BrOwAOdk.js +1 -0
  88. package/dist/public/shadow-claw-file-viewer-Blf6yGVD.js +577 -0
  89. package/dist/public/shadow-claw-files-CYySBDCl.js +840 -0
  90. package/dist/public/{shadow-claw-git-C0ntz7aX.js → shadow-claw-git-v8S0JjuR.js} +3 -3
  91. package/dist/public/{shadow-claw-integrations-DCXV2r69.js → shadow-claw-integrations-D7ufpwhX.js} +1 -1
  92. package/dist/public/{shadow-claw-llm-CudgFQsS.js → shadow-claw-llm-GWgoVfhI.js} +2 -2
  93. package/dist/public/{shadow-claw-mcp-remote-B8RkpX28.js → shadow-claw-mcp-remote-kY4LMFNN.js} +1 -1
  94. package/dist/public/{shadow-claw-networking-BLiRsrsK.js → shadow-claw-networking-qHbP95z9.js} +1 -1
  95. package/dist/public/{shadow-claw-notifications-CQhQcjtL.js → shadow-claw-notifications-YyHOK2Fr.js} +1 -1
  96. package/dist/public/{shadow-claw-page-header-NeRD0tKU.js → shadow-claw-page-header-DMKbkv3s.js} +1 -1
  97. package/dist/public/{shadow-claw-pages-DCHnFh6r.js → shadow-claw-pages-DFZHhzFZ.js} +3 -3
  98. package/dist/public/{shadow-claw-settings-VAfjKFQg.js → shadow-claw-settings-DhxrKIfA.js} +10 -3
  99. package/dist/public/shadow-claw-storage-BFynbP0j.js +219 -0
  100. package/dist/public/{shadow-claw-task-server-Dk33N_1G.js → shadow-claw-task-server-3BIeb5oZ.js} +25 -4
  101. package/dist/public/{shadow-claw-tasks-xA1VfmWN.js → shadow-claw-tasks-Caxc9atL.js} +4 -4
  102. package/dist/public/{shadow-claw-terminal-Du2r0ciq.js → shadow-claw-terminal-Beb5qF-U.js} +1 -1
  103. package/dist/public/{shadow-claw-tools-CZj4rq7l.js → shadow-claw-tools-BfJx3A9W.js} +2 -2
  104. package/dist/public/{shadow-claw-webvm-JYUkWICG.js → shadow-claw-webvm-BCS8ykeP.js} +1 -1
  105. package/dist/public/static-main/~/docs/publishing-to-github-pages.md +17 -82
  106. package/dist/public/static-main-manifest.json +1 -1
  107. package/dist/public/{syncWebMcpRegistration-DfpvASnh.js → syncWebMcpRegistration-B_M2fCjH.js} +1 -1
  108. package/dist/server.js +286 -189
  109. package/package.json +2 -1
  110. package/src/__mocks__/jszip.cjs +15 -5
  111. package/src/components/settings/shadow-claw-accounts/shadow-claw-accounts.test.ts +35 -0
  112. package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.css +117 -0
  113. package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.html +81 -0
  114. package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.test.ts +127 -0
  115. package/src/components/settings/shadow-claw-control-plane/shadow-claw-control-plane.ts +292 -0
  116. package/src/components/settings/shadow-claw-git/shadow-claw-git.test.ts +72 -0
  117. package/src/components/settings/shadow-claw-integrations/connection-test-auth.test.ts +20 -30
  118. package/src/components/settings/shadow-claw-integrations/shadow-claw-integrations.test.ts +116 -0
  119. package/src/components/settings/shadow-claw-llm/model-ranking.test.ts +143 -51
  120. package/src/components/settings/shadow-claw-llm/shadow-claw-llm.test.ts +307 -4
  121. package/src/components/settings/shadow-claw-llm/shadow-claw-llm.ts +8 -8
  122. package/src/components/settings/shadow-claw-mcp-remote/shadow-claw-mcp-remote.test.ts +31 -0
  123. package/src/components/settings/shadow-claw-peerjs/shadow-claw-peerjs.test.ts +186 -0
  124. package/src/components/settings/shadow-claw-storage/shadow-claw-storage.html +17 -0
  125. package/src/components/settings/shadow-claw-storage/shadow-claw-storage.test.ts +120 -0
  126. package/src/components/settings/shadow-claw-storage/shadow-claw-storage.ts +56 -0
  127. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.css +23 -2
  128. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.html +1 -1
  129. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.test.ts +19 -0
  130. package/src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts +2 -1
  131. package/src/components/shadow-claw/utils/initChatSplitResize.test.ts +180 -13
  132. package/src/components/shadow-claw/utils/setupEffects.test.ts +39 -0
  133. package/src/components/shadow-claw-a2ui/catalog/basic/shared.test.ts +117 -0
  134. package/src/components/shadow-claw-a2ui/shadow-claw-a2ui.test.ts +1159 -1
  135. package/src/components/shadow-claw-chat/shadow-claw-chat.test.ts +1523 -19
  136. package/src/components/shadow-claw-chat/utils/escapeHtml.test.ts +13 -0
  137. package/src/components/shadow-claw-chat/utils/getPeerChatDisplayStatus.test.ts +20 -0
  138. package/src/components/shadow-claw-conversations/shadow-claw-conversations.test.ts +494 -0
  139. package/src/components/shadow-claw-dialog/shadow-claw-dialog.ts +13 -2
  140. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.test.ts +378 -0
  141. package/src/components/shadow-claw-file-viewer/shadow-claw-file-viewer.ts +11 -9
  142. package/src/components/shadow-claw-files/shadow-claw-files.css +41 -17
  143. package/src/components/shadow-claw-files/shadow-claw-files.html +35 -0
  144. package/src/components/shadow-claw-files/shadow-claw-files.test.ts +627 -1
  145. package/src/components/shadow-claw-files/shadow-claw-files.ts +170 -6
  146. package/src/components/shadow-claw-pages/utils/resolveWorkspaceLinkPath.test.ts +31 -0
  147. package/src/components/shadow-claw-pages/utils/resolveWorkspaceLinkPath.ts +2 -1
  148. package/src/components/shadow-claw-pages/utils/rewriteWorkspacePreviewHtml.test.ts +15 -0
  149. package/src/components/shadow-claw-pdf-viewer/utils/installGetOrInsertComputedPolyfill.test.ts +65 -0
  150. package/src/components/shadow-claw-settings/shadow-claw-settings.html +7 -0
  151. package/src/components/shadow-claw-settings/shadow-claw-settings.test.ts +221 -0
  152. package/src/components/shadow-claw-settings/shadow-claw-settings.ts +2 -0
  153. package/src/components/shadow-claw-tasks/shadow-claw-tasks.test.ts +407 -0
  154. package/src/components/shadow-claw-terminal/utils/consumeEscapeSequence.test.ts +58 -0
  155. package/src/components/shadow-claw-tools/shadow-claw-tools.test.ts +80 -0
  156. package/src/config/config.test.ts +9 -0
  157. package/src/config/config.ts +15 -0
  158. package/src/core/app-routes.test.ts +56 -0
  159. package/src/core/app-routes.ts +8 -1
  160. package/src/core/backup-controller.test.ts +101 -0
  161. package/src/core/backup-controller.ts +137 -0
  162. package/src/core/control-plane-client.test.ts +408 -0
  163. package/src/core/control-plane-client.ts +425 -0
  164. package/src/core/orchestrator/orchestrator.ts +4 -0
  165. package/src/core/orchestrator/utils/compactContext.test.ts +78 -0
  166. package/src/core/orchestrator/utils/operations/channel.test.ts +254 -9
  167. package/src/core/orchestrator/utils/operations/provider.test.ts +326 -34
  168. package/src/core/orchestrator/utils/operations/vm.test.ts +114 -2
  169. package/src/core/orchestrator/utils/syncProxyConfigToServiceWorker.test.ts +60 -0
  170. package/src/core/utils/initControlPlane.test.ts +276 -0
  171. package/src/core/utils/initControlPlane.ts +437 -0
  172. package/src/core/utils/initializeApp.ts +18 -0
  173. package/src/db/getSession.test.ts +13 -1
  174. package/src/db/openDatabase.test.ts +10 -1
  175. package/src/db/openDatabase.ts +3 -1
  176. package/src/server/app.test.ts +12 -0
  177. package/src/server/app.ts +18 -8
  178. package/src/server/client-registry.test.ts +250 -0
  179. package/src/server/client-registry.ts +477 -0
  180. package/src/server/config.ts +15 -0
  181. package/src/server/control-plane-types.ts +120 -0
  182. package/src/server/control-plane.test.ts +472 -0
  183. package/src/server/control-plane.ts +581 -0
  184. package/src/server/routes/backup.test.ts +263 -0
  185. package/src/server/routes/backup.ts +262 -0
  186. package/src/server/routes/integrations-email.test.ts +532 -0
  187. package/src/server/routes/llamafile.test.ts +172 -48
  188. package/src/server/routes/mesh-llm.test.ts +192 -0
  189. package/src/server/routes/ollama.test.ts +49 -0
  190. package/src/server/server-peer.test.ts +86 -0
  191. package/src/server/server-peer.ts +330 -0
  192. package/src/server/server.ts +35 -0
  193. package/src/server/services/llamafile-manager.test.ts +230 -6
  194. package/src/server/services/transformers-runtime.test.ts +186 -18
  195. package/src/server/webrtc.test.ts +21 -0
  196. package/src/server/webrtc.ts +72 -0
  197. package/src/service-worker/fetch-proxy.test.ts +64 -1
  198. package/src/service-worker/push-handler.ts +39 -0
  199. package/src/shell/vm.test.ts +744 -12
  200. package/src/storage/ensureMainGroupIndex.test.ts +153 -0
  201. package/src/storage/getGroupFile.test.ts +66 -0
  202. package/src/storage/memoryStorage.test.ts +82 -2
  203. package/src/storage/migrateLegacyOpfs.test.ts +327 -0
  204. package/src/storage/migrateLegacyOpfs.ts +117 -0
  205. package/src/storage/writeGroupFileBytes.test.ts +143 -0
  206. package/src/stores/chat-ui.test.ts +20 -0
  207. package/src/stores/orchestrator.test.ts +134 -0
  208. package/src/stores/toast.test.ts +50 -0
  209. package/src/stores/tools.test.ts +147 -10
  210. package/src/subsystems/channels/imessage.test.ts +59 -0
  211. package/src/subsystems/channels/peerjs.test.ts +500 -62
  212. package/src/subsystems/channels/peerjs.ts +71 -4
  213. package/src/subsystems/channels/telegram.test.ts +177 -0
  214. package/src/subsystems/email/catalog.test.ts +1 -0
  215. package/src/subsystems/email/connections.test.ts +39 -1
  216. package/src/subsystems/git/credentials.test.ts +160 -825
  217. package/src/subsystems/git/git.test.ts +463 -0
  218. package/src/subsystems/notifications/__mocks__/node-sqlite.cjs +12 -1
  219. package/src/subsystems/notifications/push-routes.test.ts +33 -0
  220. package/src/subsystems/notifications/push-routes.ts +23 -0
  221. package/src/subsystems/notifications/push-store.ts +1 -1
  222. package/src/subsystems/providers/builtin-ai-tasks.test.ts +74 -0
  223. package/src/subsystems/providers/litert-lm-provider.test.ts +212 -51
  224. package/src/subsystems/providers/model-registry.test.ts +115 -0
  225. package/src/subsystems/providers/providers.test.ts +94 -1
  226. package/src/subsystems/providers/transformers-js-provider.test.ts +279 -0
  227. package/src/subsystems/providers/utils/createModelCacheFetch.test.ts +2 -2
  228. package/src/subsystems/providers/utils/downloadModelToCache.test.ts +2 -2
  229. package/src/subsystems/providers/utils/loadModelStream.test.ts +2 -2
  230. package/src/subsystems/skills/activateSkill.test.ts +101 -0
  231. package/src/subsystems/skills/discoverSkills.test.ts +251 -0
  232. package/src/subsystems/tools/cron.test.ts +64 -0
  233. package/src/subsystems/tools/declarative.test.ts +255 -89
  234. package/src/testing/assets/v86.9pfs/libv86.mjs +63 -0
  235. package/src/testing/assets/v86.ext2/libv86.mjs +3 -0
  236. package/src/testing/assets_missing_v86/assets/v86.9pfs/libv86.mjs +1 -0
  237. package/src/testing/jest-setup.ts +328 -40
  238. package/src/testing/mock-v86.mjs +49 -0
  239. package/src/ui/a2ui/types.ts +4 -3
  240. package/src/ui/a2ui/utils/normaliseComponentsToMap.test.ts +102 -0
  241. package/src/ui/a2ui/utils/resolveChildIds.test.ts +63 -0
  242. package/src/ui/a2ui/utils/resolveDynamicNumber.test.ts +13 -1
  243. package/src/worker/tools/bash/utils/waitForVMReady.test.ts +40 -0
  244. package/src/worker/tools/email/email.test.ts +193 -8
  245. package/src/worker/tools/email/utils/asEmailAttachmentInputs.test.ts +47 -0
  246. package/src/worker/tools/git/git.test.ts +214 -3
  247. package/src/worker/tools/rooms/invite-to-room.test.ts +54 -0
  248. package/src/worker/tools/rooms/leave-room.test.ts +40 -0
  249. package/src/worker/tools/rooms/list-room-members.test.ts +75 -0
  250. package/src/worker/tools/tasks/tasks-utils.test.ts +22 -0
  251. package/src/worker/tools/ui/ask-user.test.ts +50 -0
  252. package/src/worker/tools/ui/clear-chat.test.ts +19 -0
  253. package/src/worker/tools/ui/get-current-time.test.ts +19 -0
  254. package/src/worker/tools/ui/javascript.test.ts +116 -0
  255. package/src/worker/tools/ui/list-components.test.ts +10 -0
  256. package/src/worker/tools/ui/list-tool-profiles.test.ts +42 -0
  257. package/src/worker/tools/ui/manage-tools.test.ts +34 -0
  258. package/src/worker/tools/ui/render-component.test.ts +346 -0
  259. package/src/worker/tools/ui/send-notification.test.ts +40 -0
  260. package/src/worker/tools/ui/utils/getAllowFullInternetAccess.test.ts +31 -0
  261. package/src/worker/tools/ui/utils/parseBooleanConfig.test.ts +25 -0
  262. package/src/worker/tools/workspace/attach-file.test.ts +84 -0
  263. package/src/worker/tools/workspace/copy-file.test.ts +69 -0
  264. package/src/worker/tools/workspace/create-directory.test.ts +40 -0
  265. package/src/worker/tools/workspace/delete-file.test.ts +73 -0
  266. package/src/worker/tools/workspace/diff-files.test.ts +94 -0
  267. package/src/worker/tools/workspace/list-files.test.ts +36 -0
  268. package/src/worker/tools/workspace/move-file.test.ts +66 -0
  269. package/src/worker/tools/workspace/open-file.test.ts +57 -0
  270. package/src/worker/tools/workspace/patch-file.test.ts +81 -0
  271. package/src/worker/tools/workspace/read-file.test.ts +116 -0
  272. package/src/worker/tools/workspace/send-file.test.ts +82 -0
  273. package/src/worker/tools/workspace/update-memory.test.ts +29 -0
  274. package/src/worker/tools/workspace/write-file.test.ts +28 -0
  275. package/src/worker/utils/rate-limit.test.ts +199 -0
  276. package/src/worker/utils/tool-state.test.ts +29 -0
  277. package/src/worker/utils/transformers-js-utils.test.ts +59 -0
  278. package/dist/public/config-AL77QAx4.js +0 -1
  279. package/dist/public/downloadGroupFile-BABv_1mJ.js +0 -1
  280. package/dist/public/file-viewer-CCSABMsE.js +0 -1
  281. package/dist/public/mcp-reconnect-DoicazQd.js +0 -1
  282. package/dist/public/orchestrator-4su7iyWj.js +0 -15
  283. package/dist/public/shadow-claw-dialog-ByyHgxM9.js +0 -1
  284. package/dist/public/shadow-claw-file-viewer-9Qkwc30T.js +0 -577
  285. package/dist/public/shadow-claw-files-aDyq6Hv7.js +0 -781
  286. package/dist/public/shadow-claw-storage-Cf31np81.js +0 -202
@@ -0,0 +1,199 @@
1
+ import { jest } from "@jest/globals";
2
+
3
+ const mockPost = jest.fn() as any;
4
+
5
+ jest.unstable_mockModule("./post.js", () => ({
6
+ post: mockPost,
7
+ }));
8
+
9
+ const { waitForRateLimitSlot, updateRateLimitFromHeaders } =
10
+ await import("./rate-limit.js");
11
+
12
+ describe("rate-limit", () => {
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ });
16
+
17
+ describe("updateRateLimitFromHeaders", () => {
18
+ it("does nothing when autoAdapt is false or headers is null", () => {
19
+ const headers = { get: jest.fn() };
20
+ updateRateLimitFromHeaders("p-disabled", headers as any, {
21
+ callsPerMinute: 60,
22
+ autoAdapt: false,
23
+ });
24
+ expect(headers.get).not.toHaveBeenCalled();
25
+
26
+ updateRateLimitFromHeaders("p-null", null, {
27
+ callsPerMinute: 60,
28
+ autoAdapt: true,
29
+ });
30
+ });
31
+
32
+ it("parses x-ratelimit headers and updates state", () => {
33
+ const headersMap: Record<string, string> = {
34
+ "x-ratelimit-limit": "100",
35
+ "x-ratelimit-remaining": "50",
36
+ "x-ratelimit-reset": "2", // delta seconds
37
+ };
38
+ const headers = {
39
+ get: (name: string) => headersMap[name.toLowerCase()] ?? null,
40
+ };
41
+
42
+ updateRateLimitFromHeaders("p-1", headers as any, {
43
+ callsPerMinute: 0,
44
+ autoAdapt: true,
45
+ });
46
+ });
47
+
48
+ it("parses retry-after numeric and HTTP date formats", () => {
49
+ const headersNumeric = {
50
+ get: (name: string) =>
51
+ name.toLowerCase() === "retry-after" ? "5" : null,
52
+ };
53
+ updateRateLimitFromHeaders("p-retry-num", headersNumeric as any, {
54
+ callsPerMinute: 0,
55
+ autoAdapt: true,
56
+ });
57
+
58
+ const futureDate = new Date(Date.now() + 10000).toUTCString();
59
+ const headersDate = {
60
+ get: (name: string) =>
61
+ name.toLowerCase() === "retry-after" ? futureDate : null,
62
+ };
63
+ updateRateLimitFromHeaders("p-retry-date", headersDate as any, {
64
+ callsPerMinute: 0,
65
+ autoAdapt: true,
66
+ });
67
+
68
+ const pastDate = new Date(Date.now() - 10000).toUTCString();
69
+ const headersPastDate = {
70
+ get: (name: string) =>
71
+ name.toLowerCase() === "retry-after" ? pastDate : null,
72
+ };
73
+ updateRateLimitFromHeaders("p-retry-past", headersPastDate as any, {
74
+ callsPerMinute: 0,
75
+ autoAdapt: true,
76
+ });
77
+ });
78
+
79
+ it("parses x-ratelimit-reset as 13-digit epoch ms and 10-digit epoch seconds", () => {
80
+ const epochMs = Date.now() + 5000;
81
+ const headersEpochMs = {
82
+ get: (name: string) =>
83
+ name.toLowerCase() === "x-ratelimit-reset" ? String(epochMs) : null,
84
+ };
85
+ updateRateLimitFromHeaders("p-epoch-ms", headersEpochMs as any, {
86
+ callsPerMinute: 0,
87
+ autoAdapt: true,
88
+ });
89
+
90
+ const epochSec = Math.floor(Date.now() / 1000) + 10;
91
+ const headersEpochSec = {
92
+ get: (name: string) =>
93
+ name.toLowerCase() === "x-ratelimit-reset" ? String(epochSec) : null,
94
+ };
95
+ updateRateLimitFromHeaders("p-epoch-sec", headersEpochSec as any, {
96
+ callsPerMinute: 0,
97
+ autoAdapt: true,
98
+ });
99
+ });
100
+
101
+ it("sets nextAllowedAt to remoteResetAt when remoteRemaining is 0", () => {
102
+ const resetTime = Date.now() + 3000;
103
+ const headersMap: Record<string, string> = {
104
+ "x-ratelimit-remaining": "0",
105
+ "x-ratelimit-reset": String(resetTime),
106
+ };
107
+ const headers = {
108
+ get: (name: string) => headersMap[name.toLowerCase()] ?? null,
109
+ };
110
+
111
+ updateRateLimitFromHeaders("p-exhausted", headers as any, {
112
+ callsPerMinute: 0,
113
+ autoAdapt: true,
114
+ });
115
+ });
116
+ });
117
+
118
+ describe("waitForRateLimitSlot", () => {
119
+ it("allows immediate call when within callsPerMinute limit", async () => {
120
+ await waitForRateLimitSlot("p-instant", "g1", {
121
+ callsPerMinute: 10,
122
+ autoAdapt: false,
123
+ });
124
+ });
125
+
126
+ it("paces future calls when autoAdapt has remaining quota and reset window", async () => {
127
+ const resetTime = Date.now() + 1000;
128
+ const headersMap: Record<string, string> = {
129
+ "x-ratelimit-limit": "100",
130
+ "x-ratelimit-remaining": "10",
131
+ "x-ratelimit-reset": String(resetTime),
132
+ };
133
+ const headers = {
134
+ get: (name: string) => headersMap[name.toLowerCase()] ?? null,
135
+ };
136
+
137
+ updateRateLimitFromHeaders("p-pacing", headers as any, {
138
+ callsPerMinute: 0,
139
+ autoAdapt: true,
140
+ });
141
+
142
+ await waitForRateLimitSlot("p-pacing", "g1", {
143
+ callsPerMinute: 0,
144
+ autoAdapt: true,
145
+ });
146
+ });
147
+
148
+ it("aborts when signal is already aborted", async () => {
149
+ const controller = new AbortController();
150
+ controller.abort();
151
+
152
+ const headers = {
153
+ get: (name: string) => (name === "retry-after" ? "10" : null),
154
+ };
155
+ updateRateLimitFromHeaders("p-abort-now", headers as any, {
156
+ callsPerMinute: 0,
157
+ autoAdapt: true,
158
+ });
159
+
160
+ await expect(
161
+ waitForRateLimitSlot(
162
+ "p-abort-now",
163
+ "g1",
164
+ {
165
+ callsPerMinute: 0,
166
+ autoAdapt: true,
167
+ },
168
+ controller.signal,
169
+ ),
170
+ ).rejects.toThrow("Aborted");
171
+ });
172
+
173
+ it("aborts when signal fires while waiting", async () => {
174
+ const controller = new AbortController();
175
+
176
+ const headers = {
177
+ get: (name: string) => (name === "retry-after" ? "10" : null),
178
+ };
179
+ updateRateLimitFromHeaders("p-abort-later", headers as any, {
180
+ callsPerMinute: 0,
181
+ autoAdapt: true,
182
+ });
183
+
184
+ setTimeout(() => controller.abort(), 20);
185
+
186
+ await expect(
187
+ waitForRateLimitSlot(
188
+ "p-abort-later",
189
+ "g1",
190
+ {
191
+ callsPerMinute: 0,
192
+ autoAdapt: true,
193
+ },
194
+ controller.signal,
195
+ ),
196
+ ).rejects.toThrow("Aborted");
197
+ });
198
+ });
199
+ });
@@ -0,0 +1,29 @@
1
+ import { setToolState, getToolState, clearToolState } from "./tool-state.js";
2
+
3
+ describe("tool-state", () => {
4
+ beforeEach(() => {
5
+ clearToolState("group-1");
6
+ clearToolState("group-2");
7
+ });
8
+
9
+ it("sets, gets, and clears tool state for a group", () => {
10
+ expect(getToolState("group-1")).toBeUndefined();
11
+
12
+ const tools: any[] = [
13
+ { name: "test_tool", description: "test", input_schema: {} },
14
+ ];
15
+ setToolState("group-1", tools, "Custom prompt override");
16
+
17
+ const state = getToolState("group-1");
18
+ expect(state).toEqual({
19
+ enabledTools: tools,
20
+ systemPromptOverride: "Custom prompt override",
21
+ });
22
+
23
+ // Check isolation from other groups
24
+ expect(getToolState("group-2")).toBeUndefined();
25
+
26
+ clearToolState("group-1");
27
+ expect(getToolState("group-1")).toBeUndefined();
28
+ });
29
+ });
@@ -0,0 +1,59 @@
1
+ import { jest } from "@jest/globals";
2
+ import {
3
+ getHuggingFaceDomain,
4
+ isRemoteEnvironment,
5
+ } from "./transformers-js-utils.js";
6
+
7
+ describe("transformers-js-utils", () => {
8
+ describe("isRemoteEnvironment", () => {
9
+ it("returns false in local jsdom environment", () => {
10
+ expect(isRemoteEnvironment()).toBe(false);
11
+ });
12
+ });
13
+
14
+ describe("getHuggingFaceDomain", () => {
15
+ const originalFetch = globalThis.fetch;
16
+
17
+ afterEach(() => {
18
+ globalThis.fetch = originalFetch;
19
+ });
20
+
21
+ it("returns cached domain if already resolved", async () => {
22
+ const domain = await getHuggingFaceDomain();
23
+ expect(domain).toBe("huggingface.co");
24
+ });
25
+
26
+ it("switches to mirror when main domain is unreachable", async () => {
27
+ globalThis.fetch = jest
28
+ .fn<any>()
29
+ .mockImplementation(async (url: string) => {
30
+ if (url.includes("huggingface.co")) {
31
+ throw new Error("Network error");
32
+ }
33
+ return { ok: true };
34
+ });
35
+
36
+ let mod: any;
37
+ await jest.isolateModulesAsync(async () => {
38
+ mod = await import("./transformers-js-utils.js");
39
+ });
40
+
41
+ const domain = await mod.getHuggingFaceDomain();
42
+ expect(domain).toBe("hf-mirror.com");
43
+ });
44
+
45
+ it("falls back to main domain when both are unreachable", async () => {
46
+ globalThis.fetch = jest
47
+ .fn<any>()
48
+ .mockRejectedValue(new Error("Both down"));
49
+
50
+ let mod: any;
51
+ await jest.isolateModulesAsync(async () => {
52
+ mod = await import("./transformers-js-utils.js");
53
+ });
54
+
55
+ const domain = await mod.getHuggingFaceDomain();
56
+ expect(domain).toBe("huggingface.co");
57
+ });
58
+ });
59
+ });
@@ -1 +0,0 @@
1
- import{n as e}from"./rolldown-runtime-aKtaBQYM.js";import{i as t}from"./app-routes-B0ePT49v.js";const n=new class{loading=!1;models=new Map;getModelInfo(e){return this.models.get(e.toLowerCase())??null}registerModelInfo(e,t){this.models.set(e.toLowerCase(),t)}clear(){this.models.clear()}async fetchModelInfo(e,t,n){if(e.modelsUrl){this.loading=!0;try{let r=new Headers;if(r.set(`Content-Type`,`application/json`),e.headers)for(let[t,n]of Object.entries(e.headers))r.set(t,n);if(n)for(let[e,t]of Object.entries(n))r.set(e,t);if(t&&e.apiKeyHeader){let n=e.apiKeyHeaderFormat;r.set(e.apiKeyHeader,n?n.replace(`{key}`,t):t)}let i=await fetch(e.modelsUrl,{headers:r});if(!i.ok)throw Error(`HTTP ${i.status} ${i.statusText}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];for(let e of o){if(!e.id)continue;let t=e.context_length??e.context_window??0,n=e.max_completion_tokens||e.per_request_limits?.completion_tokens||e.top_provider?.max_completion_tokens||null,r=typeof e.supports_tools==`boolean`?e.supports_tools:typeof e.supportsTools==`boolean`?e.supportsTools:void 0,i=this.extractModalities(e,`input`),a=this.extractModalities(e,`output`),o=this.modalitiesInclude(i,`image`,`vision`),s=this.modalitiesInclude(i,`audio`,`voice`,`hearing`),c=this.modalitiesInclude(i,`video`),l=e.id===`openrouter/free`||this.supportedParametersInclude(e,`image`,`vision`,`audio`,`tool`,`structured`),u=this.extractReasoning(e);!t&&Array.isArray(e.providers)&&e.providers.length>0&&(t=e.providers[0]?.context_length||0),this.registerModelInfo(e.id,{contextWindow:t,maxOutput:n,...r!==void 0&&{supportsTools:r},...i.length>0&&{inputModalities:i},...a.length>0&&{outputModalities:a},...o!==void 0&&{supportsImageInput:o},...s!==void 0&&{supportsAudioInput:s},...c!==void 0&&{supportsVideoInput:c},...u&&{reasoning:u},...l&&{routesByRequestFeatures:l}})}o.length>0&&console.log(`[ModelRegistry] Registered ${o.length} models for provider "${e.id}"`)}catch(t){console.error(`[ModelRegistry] Error fetching models for ${e.id}:`,t)}finally{this.loading=!1}}}extractModalities(e,t){let n=t===`input`?e.input_modalities||e.inputModalities:e.output_modalities||e.outputModalities,r=e.architecture||{},i=t===`input`?r.input_modalities||r.inputModalities:r.output_modalities||r.outputModalities,a=typeof r.modality==`string`?r.modality:``,o=this.parseArchitectureModality(a,t),s=[...this.normalizeStringArray(n),...this.normalizeStringArray(i),...o];return Array.from(new Set(s))}extractReasoning(e){let t=e?.reasoning;if(!t||typeof t!=`object`)return;let n=this.normalizeStringArray(t.supported_efforts),r=typeof t.default_effort==`string`?t.default_effort.toLowerCase():void 0,i=typeof t.default_enabled==`boolean`?t.default_enabled:void 0,a=typeof t.supports_max_tokens==`boolean`?t.supports_max_tokens:void 0,o=typeof t.mandatory==`boolean`?t.mandatory:void 0;if(!(n.length===0&&r===void 0&&i===void 0&&a===void 0&&o===void 0))return{...n.length>0&&{supportedEfforts:n},...r!==void 0&&{defaultEffort:r},...i!==void 0&&{defaultEnabled:i},...a!==void 0&&{supportsMaxTokens:a},...o!==void 0&&{mandatory:o}}}modalitiesInclude(e,...t){if(e.length!==0)return t.some(t=>e.some(e=>e.includes(t)))}normalizeStringArray(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.toLowerCase()):[]}parseArchitectureModality(e,t){if(!e)return[];let[n=``,r=``]=e.toLowerCase().split(`->`).map(e=>e.trim());return(t===`input`?n:r).split(/[+,/\s]+/).map(e=>e.trim()).filter(Boolean)}supportedParametersInclude(e,...t){let n=this.normalizeStringArray(e.supported_parameters||e.supportedParameters);return t.some(e=>n.some(t=>t.includes(e)))}};var r=e({ASSISTANT_NAME:()=>i,BASH_DEFAULT_TIMEOUT_SEC:()=>900,BASH_MAX_TIMEOUT_SEC:()=>f,BEDROCK_PROXY_MODELS_URL:()=>T,BEDROCK_PROXY_URL:()=>w,CONFIG_KEYS:()=>V,CONTEXT_WINDOW_SIZE:()=>50,DB_VERSION:()=>2,DEFAULT_DEV_HOST:()=>H,DEFAULT_DEV_IP:()=>DEFAULT_DEV_IP,DEFAULT_DEV_PORT:()=>U,DEFAULT_GROUP_ID:()=>v,DEFAULT_MAX_ITERATIONS:()=>50,DEFAULT_MAX_TOKENS:()=>o,DEFAULT_PROMPT_API_BACKEND:()=>DEFAULT_PROMPT_API_BACKEND,DEFAULT_PROMPT_API_DTYPE_STRATEGY:()=>DEFAULT_PROMPT_API_DTYPE_STRATEGY,DEFAULT_PROMPT_API_FALLBACK_MODEL:()=>G,DEFAULT_PROVIDER:()=>l,DEFAULT_SUBAGENT_MAX_PARALLEL:()=>5,DEFAULT_SUBAGENT_WORKSPACE_MODE:()=>W,DEFAULT_TASK_SERVER_ENABLED:()=>!1,DEFAULT_TASK_SERVER_URL:()=>K,DEFAULT_TRANSFORMERS_JS_BACKEND:()=>DEFAULT_TRANSFORMERS_JS_BACKEND,DEFAULT_TRANSFORMERS_JS_DTYPE_STRATEGY:()=>DEFAULT_TRANSFORMERS_JS_DTYPE_STRATEGY,DEFAULT_TRANSFORMERS_JS_MODEL:()=>DEFAULT_TRANSFORMERS_JS_MODEL,DEFAULT_VM_BOOT_HOST:()=>m,DEFAULT_VM_NETWORK_RELAY_URL:()=>p,FETCH_MAX_RESPONSE:()=>d,GENERAL_ACCOUNT_PROVIDER_CAPABILITIES:()=>M,IMESSAGE_POLL_TIMEOUT:()=>25,IMESSAGE_REQUEST_TIMEOUT_MS:()=>S,LEGACY_DB_NAME:()=>h,LEGACY_OPFS_ROOT:()=>LEGACY_OPFS_ROOT,LLAMAFILE_PROXY_MODELS_URL:()=>k,LLAMAFILE_PROXY_URL:()=>O,MODEL_OUTPUT_LIMITS:()=>s,OAUTH_PROVIDER_DEFINITIONS:()=>N,OLLAMA_PROXY_MODELS_URL:()=>j,OLLAMA_PROXY_URL:()=>A,OPFS_ROOT:()=>_,PEERJS_DEFAULT_HOST:()=>C,PEERJS_DEFAULT_PATH:()=>`/`,PEERJS_DEFAULT_PORT:()=>443,PEERJS_DEFAULT_SECURE:()=>!0,PROCESS_LOOP_INTERVAL:()=>100,PROVIDERS:()=>P,SCHEDULER_INTERVAL:()=>u,TELEGRAM_API_BASE:()=>y,TELEGRAM_MAX_LENGTH:()=>x,TELEGRAM_POLL_TIMEOUT:()=>30,TELEGRAM_PROXY_BASE:()=>b,TRANSFORMERS_JS_PROXY_MODELS_URL:()=>D,TRANSFORMERS_JS_PROXY_URL:()=>E,buildTriggerPattern:()=>a,getAvailableProviders:()=>L,getDbName:()=>g,getDefaultProvider:()=>I,getGeneralAccountProviderCapabilities:()=>z,getModelMaxTokens:()=>c,getProvider:()=>F,getProviderApiKeyConfigKey:()=>R,getProviderTokenAuthScheme:()=>B});const i=`ShadowClaw`;function a(e){let t=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(^|\\s)@${t}\\b`,`i`)}a(i);const o=8192,s=[{pattern:`claude-fable-5`,maxTokens:128e3},{pattern:`claude-sonnet-5`,maxTokens:128e3},{pattern:`claude-opus-5`,maxTokens:128e3},{pattern:`claude-opus-4-8`,maxTokens:128e3},{pattern:`claude-opus-4`,maxTokens:128e3},{pattern:`claude-sonnet-4`,maxTokens:64e3},{pattern:`claude-haiku-4`,maxTokens:64e3},{pattern:`claude-3-5`,maxTokens:8192},{pattern:`claude-3`,maxTokens:4096},{pattern:`gpt-5`,maxTokens:128e3},{pattern:`gpt-4o`,maxTokens:16384},{pattern:`gpt-4.1`,maxTokens:32768},{pattern:`gpt-4-turbo`,maxTokens:4096},{pattern:`gpt-4`,maxTokens:8192},{pattern:`gpt-3.5`,maxTokens:4096},{pattern:`qwen-2.5`,maxTokens:32768},{pattern:`Qwen3.5`,maxTokens:32768},{pattern:`qwen3.5`,maxTokens:32768},{pattern:`Qwen3`,maxTokens:32768},{pattern:`qwen3`,maxTokens:32768},{pattern:`gemma-4`,maxTokens:16384},{pattern:`gemini-nano`,maxTokens:4096},{pattern:`phi-mini`,maxTokens:9216},{pattern:`aion`,maxTokens:9216},{pattern:`gemma-3-1b-it-ONNX-GQA`,maxTokens:32768},{pattern:`gemma-3-1b-it-ONNX`,maxTokens:32768},{pattern:`gemma-3`,maxTokens:32768},{pattern:`Qwen3-0.6B-ONNX`,maxTokens:32768},{pattern:`Qwen3.5`,maxTokens:32768},{pattern:`Llama-3.2`,maxTokens:32768},{pattern:`SmolLM`,maxTokens:8192},{pattern:`DeepSeek-R1`,maxTokens:32768},{pattern:`Phi-4`,maxTokens:16384},{pattern:`Phi-3.5`,maxTokens:16384},{pattern:`LFM2`,maxTokens:16384},{pattern:`gpt-oss`,maxTokens:32768},{pattern:`browser-built-in`,maxTokens:4096},{pattern:`mesh`,maxTokens:32768},{pattern:`openrouter/free`,maxTokens:32768},{pattern:`qwen3:8b`,maxTokens:4096},{pattern:`llama3:8b`,maxTokens:8192}];function c(e){if(!e)return o;let t=n.getModelInfo(e);if(t){if(typeof t.maxOutput==`number`){let e=t.contextWindow?Math.max(8192,Math.floor(t.contextWindow/2)):32768;return Math.min(t.maxOutput,e)}if(t.contextWindow){let e;return e=t.contextWindow>=2e5?131072:t.contextWindow>=1e5?65536:32768,Math.min(e,Math.floor(t.contextWindow/2))}}for(let{pattern:t,maxTokens:n}of s)if(e.includes(t))return n;return o}const l=`prompt_api`,u=6e4,d=102400,f=1800,p=`wss://relay.widgetry.org/`,m=`http://localhost:8888`,h=`shadowclaw`;function g(){let e=t();return e?`shadowclaw-${e}`:h}g();const _=`shadowclaw`,v=`br:main`,y=`https://api.telegram.org/bot`,b=`/telegram/bot`,x=4096,S=15e3,C=`0.peerjs.com`,w=`http://localhost:8888/bedrock-proxy/invoke`,T=`http://localhost:8888/bedrock-proxy/models`,E=`http://localhost:8888/transformers-js-proxy/chat/completions`,D=`http://localhost:8888/transformers-js-proxy/models`,O=`http://localhost:8888/llamafile-proxy/chat/completions`,k=`http://localhost:8888/llamafile-proxy/models`,A=`http://localhost:8888/ollama-proxy/chat/completions`,j=`http://localhost:8888/ollama-proxy/models`,M={github:{providerId:`github`,name:`GitHub`,aliases:[`github`,`api.github.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`token `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://github.com/login/oauth/authorize`,tokenUrl:`https://github.com/login/oauth/access_token`,defaultScopes:[`repo`,`read:user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},gitlab:{providerId:`gitlab`,name:`GitLab`,aliases:[`gitlab`,`gitlab.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`PRIVATE-TOKEN`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}}},oauth:{authorizeUrl:`https://gitlab.com/oauth/authorize`,tokenUrl:`https://gitlab.com/oauth/token`,defaultScopes:[`read_api`,`read_user`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},figma:{providerId:`figma`,name:`Figma`,aliases:[`figma`,`api.figma.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`X-Figma-Token`,headerPrefix:``},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://www.figma.com/oauth`,tokenUrl:`https://api.figma.com/v1/oauth/token`,refreshUrl:`https://api.figma.com/v1/oauth/refresh`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},notion:{providerId:`notion`,name:`Notion`,aliases:[`notion`,`api.notion.com`,`notion.so`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.notion.com/v1/oauth/authorize`,tokenUrl:`https://api.notion.com/v1/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`basic_header`,scopeSeparator:`space`}},microsoft_graph:{providerId:`microsoft_graph`,name:`Microsoft Graph`,aliases:[`microsoft`,`graph.microsoft.com`,`microsoft_graph`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/authorize`,tokenUrl:`https://login.microsoftonline.com/common/oauth2/v2.0/token`,defaultScopes:[`openid`,`profile`,`offline_access`,`User.Read`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},yahoo_mail:{providerId:`yahoo_mail`,name:`Yahoo Mail`,aliases:[`yahoo`,`yahoo_mail`,`mail.yahoo.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://api.login.yahoo.com/oauth2/request_auth`,tokenUrl:`https://api.login.yahoo.com/oauth2/get_token`,defaultScopes:[`mail-r`,`mail-w`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},google:{providerId:`google`,name:`Google`,aliases:[`google`,`googleapis.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://accounts.google.com/o/oauth2/v2/auth`,tokenUrl:`https://oauth2.googleapis.com/token`,defaultScopes:[`openid`,`profile`,`email`],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},atlassian:{providerId:`atlassian`,name:`Atlassian`,aliases:[`atlassian`,`api.atlassian.com`],modes:[`oauth`,`token`,`basic`],defaultMode:`basic`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `},basic:{headerName:`Authorization`,headerPrefix:`Basic `}},oauth:{authorizeUrl:`https://auth.atlassian.com/authorize`,tokenUrl:`https://auth.atlassian.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},slack:{providerId:`slack`,name:`Slack`,aliases:[`slack`,`slack.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://slack.com/oauth/v2/authorize`,tokenUrl:`https://slack.com/api/oauth.v2.access`,defaultScopes:[],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`comma`}},linear:{providerId:`linear`,name:`Linear`,aliases:[`linear`,`api.linear.app`,`linear.app`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`],authTypes:[`token`,`oauth`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://linear.app/oauth/authorize`,tokenUrl:`https://api.linear.app/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}},azure_devops:{providerId:`azure_devops`,name:`Azure DevOps`,aliases:[`azure_devops`,`dev.azure.com`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`http_api`,`git_remote`],authTypes:[`token`,`oauth`,`basic_userpass`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},tokenAuthByServiceType:{git_remote:{token:{headerName:`Authorization`,headerPrefix:`Basic `},oauth:{headerName:`Authorization`,headerPrefix:`Basic `}}},oauth:{authorizeUrl:`https://app.vssps.visualstudio.com/oauth2/authorize`,tokenUrl:`https://app.vssps.visualstudio.com/oauth2/token`,defaultScopes:[`vso.code`,`vso.profile`,`offline_access`],usePkce:!1,clientAuthMethod:`request_body`,scopeSeparator:`space`}},custom_mcp:{providerId:`custom_mcp`,name:`Custom MCP`,aliases:[`custom_mcp`],modes:[`oauth`,`token`],defaultMode:`oauth`,serviceTypes:[`mcp_remote`,`webmcp_local`],authTypes:[`none`,`token`,`oauth`,`custom_header`,`ssh_key`],tokenAuth:{token:{headerName:`Authorization`,headerPrefix:`Bearer `},oauth:{headerName:`Authorization`,headerPrefix:`Bearer `}},oauth:{authorizeUrl:`https://example.com/oauth/authorize`,tokenUrl:`https://example.com/oauth/token`,defaultScopes:[],usePkce:!0,clientAuthMethod:`request_body`,scopeSeparator:`space`}}},N=Object.fromEntries(Object.values(M).filter(e=>!!e.oauth).map(e=>{let t=e.oauth;return[e.providerId,{id:e.providerId,name:e.name,authorizeUrl:t.authorizeUrl,tokenUrl:t.tokenUrl,redirectUri:t.redirectUri,defaultScopes:t.defaultScopes,usePkce:t.usePkce,clientAuthMethod:t.clientAuthMethod,scopeSeparator:t.scopeSeparator}]}));Object.fromEntries(Object.values(M).map(e=>[e.providerId,{providerId:e.providerId,modes:e.modes,defaultMode:e.defaultMode}]));const P={openrouter:{id:`openrouter`,name:`OpenRouter`,baseUrl:`https://openrouter.ai/api/v1/chat/completions`,format:`openai`,apiKeyHeader:`Authorization`,apiKeyHeaderFormat:`Bearer {key}`,headers:{"HTTP-Referer":`https://xt-ml.github.io/shadow-claw/`,"X-OpenRouter-Title":`ShadowClaw`},defaultModel:`openrouter/free`,modelsUrl:`https://openrouter.ai/api/v1/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`reasoning`},huggingface:{id:`huggingface`,name:`HuggingFace`,baseUrl:`https://router.huggingface.co/v1/chat/completions`,format:`openai`,apiKeyHeader:`Authorization`,apiKeyHeaderFormat:`Bearer {key}`,headers:{},defaultModel:`meta-llama/Llama-3.1-8B-Instruct`,modelsUrl:`https://router.huggingface.co/v1/models`,requiresApiKey:!0,supportsStreaming:!0},bedrock_proxy:{id:`bedrock_proxy`,name:`AWS Bedrock (Local Proxy)`,baseUrl:w,format:`anthropic`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`anthropic.claude-sonnet-4-6-v1:0`,modelsUrl:T,requiresApiKey:!1,supportsStreaming:!0,reasoningParam:`thinking`},gemini_proxy:{id:`gemini_proxy`,name:`Gemini (Local Proxy)`,baseUrl:`http://localhost:8888/gemini-proxy/chat/completions`,format:`openai`,apiKeyHeader:`x-goog-api-key`,headers:{},defaultModel:`gemini-2.0-flash`,modelsUrl:`http://localhost:8888/gemini-proxy/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`thinkingConfig`},vertex_ai:{id:`vertex_ai`,name:`Vertex AI (Local Proxy)`,baseUrl:`http://localhost:8888/vertex-ai-proxy/chat/completions`,format:`openai`,apiKeyHeader:`x-vertex-project`,headers:{},defaultModel:`gemini-2.5-flash`,modelsUrl:`http://localhost:8888/vertex-ai-proxy/models`,requiresApiKey:!0,supportsStreaming:!0,reasoningParam:`thinkingConfig`},"mesh-llm":{id:`mesh-llm`,name:`Mesh LLM (Local Proxy)`,baseUrl:`http://localhost:8888/mesh-llm-proxy/chat/completions`,format:`mesh-llm`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`mesh`,modelsUrl:`http://localhost:8888/mesh-llm-proxy/models`,requiresApiKey:!1,supportsStreaming:!0},ollama:{id:`ollama`,name:`Ollama (Local Proxy)`,baseUrl:A,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`qwen3:8b`,modelsUrl:j,requiresApiKey:!1,supportsStreaming:!0},llamafile:{id:`llamafile`,name:`Llamafile (Local Proxy)`,baseUrl:O,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`Qwen3.5-9B-Q5_K_S`,modelsUrl:k,requiresApiKey:!1,supportsStreaming:!0},transformers_js_local:{id:`transformers_js_local`,name:`Transformers.js (Local Proxy)`,baseUrl:E,format:`openai`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`onnx-community/Qwen3-0.6B-ONNX`,modelsUrl:D,models:[`onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX`,`onnx-community/gemma-3-1b-it-ONNX-GQA`,`onnx-community/gemma-3-1b-it-ONNX`,`onnx-community/gemma-4-E2B-it-ONNX`,`onnx-community/gemma-4-E2B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E4B-it-ONNX`,`onnx-community/gemma-4-E4B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E9B-it-ONNX`,`onnx-community/gemma-4-12B-it-ONNX`,`onnx-community/gemma-4-12B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E27B-it-ONNX`,`onnx-community/gpt-oss-20b-ONNX`,`onnx-community/LFM2-1.2B-ONNX`,`onnx-community/Llama-3.2-1B-Instruct-ONNX`,`onnx-community/Llama-3.2-3B-Instruct-ONNX`,`onnx-community/Phi-3.5-mini-instruct-onnx-web`,`onnx-community/Phi-4-mini-instruct-ONNX`,`onnx-community/Qwen3-0.6B-ONNX`,`onnx-community/Qwen3.5-0.8B-ONNX-OPT`,`onnx-community/Qwen3.5-4B-ONNX-OPT`,`HuggingFaceTB/SmolLM3-3B-ONNX`,`LiquidAI/LFM2.5-1.2B-Thinking-ONNX`,`webgpu/Qwen3-4B-ONNX`],requiresApiKey:!1,supportsStreaming:!0},transformers_js_browser:{id:`transformers_js_browser`,name:`Transformers.js (Browser)`,baseUrl:`local://transformers-js`,format:`transformers_js`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`onnx-community/Qwen3-0.6B-ONNX`,modelsUrl:`https://huggingface.co/api/models?author=onnx-community`,models:[`onnx-community/Qwen3-0.6B-ONNX`,`onnx-community/gemma-3-1b-it-ONNX`,`onnx-community/gemma-3-1b-it-ONNX-GQA`,`onnx-community/gemma-4-E2B-it-ONNX`,`onnx-community/gemma-4-E4B-it-ONNX`,`onnx-community/gemma-4-E9B-it-ONNX`,`onnx-community/gemma-4-E27B-it-ONNX`,`onnx-community/gemma-4-12B-it-ONNX`,`onnx-community/gemma-4-E2B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-E4B-it-qat-mobile-ONNX`,`onnx-community/gemma-4-12B-it-qat-mobile-ONNX`,`onnx-community/Phi-3.5-mini-instruct-onnx-web`,`onnx-community/Phi-4-mini-instruct-ONNX`,`onnx-community/Llama-3.2-1B-Instruct-ONNX`,`onnx-community/Llama-3.2-3B-Instruct-ONNX`,`webgpu/Qwen3-4B-ONNX`,`onnx-community/DeepSeek-R1-Distill-Qwen-1.5B-ONNX`,`onnx-community/gpt-oss-20b-ONNX`,`onnx-community/LFM2-1.2B-ONNX`,`LiquidAI/LFM2.5-1.2B-Thinking-ONNX`,`HuggingFaceTB/SmolLM3-3B-ONNX`,`onnx-community/Qwen3.5-0.8B-ONNX-OPT`,`onnx-community/Qwen3.5-4B-ONNX-OPT`],requiresApiKey:!1,supportsStreaming:!1},litert_lm_browser:{id:`litert_lm_browser`,name:`LiteRT-LM (Browser)`,baseUrl:`local://litert-lm`,format:`transformers_js`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`litert-community/gemma-4-E2B-it-litert-lm`,models:[`litert-community/gemma-4-E2B-it-litert-lm`,`litert-community/gemma-4-E4B-it-litert-lm`],requiresApiKey:!1,supportsStreaming:!1},prompt_api:{id:`prompt_api`,name:`Prompt API (Browser)`,baseUrl:`builtin://language-model`,format:`prompt_api`,apiKeyHeader:`Authorization`,headers:{},defaultModel:`browser-built-in`,models:[`browser-built-in`],requiresApiKey:!1,supportsStreaming:!1}};function F(e){return P[e]||null}function I(){return P[l]}function L(){return Object.keys(P)}function R(e){return`api_key:${e}`}function z(e){return M[e]||null}function B(e,t,n=`http_api`){let r=z(e);return r&&(r.tokenAuthByServiceType?.[n]?.[t]||r.tokenAuth[t])||null}const V={ACTIVE_TOOL_PROFILE:`active_tool_profile`,ACTIVITY_LOG_DISK_LOGGING_ENABLED:`activity_log_disk_logging_enabled`,ALLOWED_CUSTOM_ELEMENTS:`allowed_custom_elements`,ALLOWED_CUSTOM_ELEMENT_HOST_PATTERNS:`allowed_custom_element_host_patterns`,ALLOWED_IFRAME_HOST_PATTERNS:`allowed_iframe_host_patterns`,API_KEY:`api_key`,ASSISTANT_NAME:`assistant_name`,BEDROCK_AUTH_MODE:`bedrock_auth_mode`,BEDROCK_PROFILE_FALLBACK:`bedrock_profile_fallback`,BEDROCK_REGION_FALLBACK:`bedrock_region_fallback`,BUILTIN_AI_SUBAGENT_ROUTING:`builtin_ai_subagent_routing`,BUILTIN_AI_TOOLS_BACKEND:`builtin_ai_tools_backend`,CHANNEL_ENABLED_PREFIX:`channel_enabled:`,CHAT_INPUT_AREA_HEIGHT:`chat_input_area_height`,CHAT_SPLIT_VIEW_ENABLED:`chat_split_view_enabled`,CHAT_SPLIT_VIEW_HEIGHT:`chat_split_view_height`,COMPACTION_ENGINE_PREFERENCE:`compaction_engine_preference`,CONTEXT_COMPRESSION_ENABLED:`context_compression_enabled`,CONVERSATIONS_HEIGHT:`conversations_height`,CUSTOM_TOOLS:`custom_tools`,DB_MIGRATED_FROM_LEGACY:`db_migrated_from_legacy`,DECLARATIVE_TOOLS_ENABLED:`declarative_tools_enabled`,DEFAULT_PINNED_PAGE:`default_pinned_page`,DIRECT_TOOL_COMMAND_POLICY:`direct_tool_command_policy`,ENABLED_TOOLS:`enabled_tools`,GIT_ACCOUNTS:`git_accounts`,GIT_AUTHOR_EMAIL:`git_author_email`,GIT_AUTHOR_NAME:`git_author_name`,GIT_CORS_PROXY:`git_cors_proxy`,GIT_DEFAULT_ACCOUNT:`git_default_account`,GIT_PASSWORD:`git_password`,GIT_PROXY_URL:`git_proxy_url`,GIT_TOKEN:`git_token`,GIT_USERNAME:`git_username`,IMESSAGE_API_KEY:`imessage_api_key`,IMESSAGE_CHAT_IDS:`imessage_chat_ids`,IMESSAGE_SERVER_URL:`imessage_server_url`,INTEGRATION_CONNECTIONS:`integration_connections`,MARKDOWN_FRONTMATTER_CHAT:`markdown_frontmatter_chat`,MARKDOWN_FRONTMATTER_FILE_VIEWER:`markdown_frontmatter_file_viewer`,MARKDOWN_FRONTMATTER_PAGES:`markdown_frontmatter_pages`,MARKDOWN_FRONTMATTER_TASKS:`markdown_frontmatter_tasks`,LAST_ACTIVE_GROUP:`last_active_group`,LAST_ACTIVE_PAGE:`last_active_page`,LAST_SELECTED_PINNED_PAGE:`last_selected_pinned_page`,LLAMAFILE_HOST:`llamafile_host`,LLAMAFILE_MODE:`llamafile_mode`,LLAMAFILE_OFFLINE:`llamafile_offline`,LLAMAFILE_PORT:`llamafile_port`,MAIN_GROUP_INDEX_SUPPRESSED:`main_group_index_suppressed`,MAIN_GROUP_README_SUPPRESSED:`main_group_readme_suppressed`,MAX_ITERATIONS:`max_iterations`,MAX_TOKENS:`max_tokens`,MESH_LLM_HOST:`mesh_llm_host`,MODEL:`model`,OAUTH_PROVIDER_DEFINITIONS:`oauth_provider_definitions`,OVERRIDE_PRERENDER_SKELETON:`override_prerender_skeleton`,PAGES_AUTO_REFRESH_INTERVAL:`pages_auto_refresh_interval`,PAGES_LIST:`pages_list`,PASSPHRASE_SALT:`passphrase_salt`,PASSPHRASE_VERIFY:`passphrase_verify`,PROMPT_API_BACKEND:`prompt_api_backend`,PROMPT_API_DTYPE_STRATEGY:`prompt_api_dtype_strategy`,PROMPT_API_FALLBACK_MODEL:`prompt_api_fallback_model`,PROMPT_API_ONBOARDING_SEEN:`prompt_api_onboarding_seen`,PEERJS_MY_ALIAS:`peerjs_my_alias`,PEERJS_MY_PEER_ID:`peerjs_my_peer_id`,PEERJS_PEER_ALIASES:`peerjs_peer_aliases`,PEERJS_SERVER_HOST:`peerjs_server_host`,PEERJS_SERVER_PATH:`peerjs_server_path`,PEERJS_SERVER_PORT:`peerjs_server_port`,PEERJS_SERVER_SECURE:`peerjs_server_secure`,PEERJS_TRUSTED_PEER_IDS:`peerjs_trusted_peer_ids`,PROVIDER:`provider`,PROXY_URL:`proxy_url`,PUSH_PROXY_URL:`push_proxy_url`,RATE_LIMIT_AUTO_ADAPT:`rate_limit_auto_adapt`,RATE_LIMIT_CALLS_PER_MINUTE:`rate_limit_calls_per_minute`,REASONING_EFFORT:`reasoning_effort`,REMOTE_MCP_CONNECTIONS:`remote_mcp_connections`,SERVICE_ACCOUNTS:`service_accounts`,SERVICE_DEFAULT_ACCOUNT:`service_default_account`,SIDEBAR_CHAT_HIDDEN:`sidebar_chat_hidden`,SIDEBAR_DEFAULT_PAGE:`sidebar_default_page`,SIDEBAR_FILES_HIDDEN:`sidebar_files_hidden`,SIDEBAR_PAGES_HIDDEN:`sidebar_pages_hidden`,SIDEBAR_TASKS_HIDDEN:`sidebar_tasks_hidden`,SIDEBAR_WIDTH:`sidebar_width`,SITE_CONFIG_SEEDED:`site_config_seeded`,STATIC_MAIN_SITE_SEEDED:`static_main_site_seeded`,STORAGE_HANDLE:`storage_handle`,SUBSCRIBER_ID:`subscriber_id`,STREAMING_ENABLED:`streaming_enabled`,SUBAGENT_MAX_PARALLEL:`subagent_max_parallel`,SUBAGENT_WORKSPACE_MODE:`subagent_workspace_mode`,SUPPRESSED_PAGES_LIST:`suppressed_pages_list`,SYSTEM_PROMPT_OVERRIDE:`system_prompt_override`,TASK_SERVER_ENABLED:`task_server_enabled`,TASK_SERVER_URL:`task_server_url`,TASK_SYNC_OUTBOX:`task_sync_outbox`,TELEGRAM_BOT_TOKEN:`telegram_bot_token`,TELEGRAM_CHAT_IDS:`telegram_chat_ids`,TELEGRAM_USE_PROXY:`telegram_use_proxy`,TOOL_PROFILES:`tool_profiles`,TRANSFORMERS_JS_BACKEND:`transformers_js_backend`,TRANSFORMERS_JS_DTYPE_STRATEGY:`transformers_js_dtype_strategy`,TRIGGER_PATTERN:`trigger_pattern`,USE_PROXY:`use_proxy`,VAPID_SUBJECT:`vapid_subject`,VM_BASH_FULL_INTERNET_ACCESS:`vm_bash_full_internet_access`,VM_BASH_TIMEOUT_SEC:`vm_bash_timeout_sec`,VM_BOOT_HOST:`vm_boot_host`,VM_BOOT_MODE:`vm_boot_mode`,VM_NETWORK_RELAY_URL:`vm_network_relay_url`,WEBMCP_MODE:`webmcp_mode`,WEBMCP_TOOLS_ENABLED:`webmcp_tools_enabled`,WEB_SEARCH_PROXY_URL:`web_search_proxy_url`,WEB_SEARCH_URL:`web_search_url`,WEB_SEARCH_USE_PROXY:`web_search_use_proxy`,SEARCH_FILES_MAX_FILE_BYTES:`search_files_max_file_bytes`,SEARCH_FILES_MAX_FILES_VISITED:`search_files_max_files_visited`,SEARCH_FILES_SKIP_DIRS:`search_files_skip_dirs`},H=`localhost`,U=8888,W=`automatic`,G=`onnx-community/Qwen3-0.6B-ONNX`,K=`http://localhost:8888/schedule`;export{g as A,u as C,a as D,b as E,R as F,B as I,n as L,z as M,c as N,r as O,F as P,P as S,x as T,h as _,U as a,_ as b,G as c,K as d,m as f,S as g,M as h,H as i,I as j,L as k,l,d as m,f as n,v as o,p,V as r,o as s,i as t,W as u,O as v,y as w,C as x,N as y};
@@ -1 +0,0 @@
1
- import{Sn as e,xn as t}from"./orchestrator-B9KmIj8Q.js";async function n(n,r,i){let a=await e(n,r),{dirs:o,filename:s}=t(i),c=a;for(let e of o)c=await c.getDirectoryHandle(e);let l=await(await c.getFileHandle(s)).getFile(),u=URL.createObjectURL(l),d=document.createElement(`a`);d.href=u,d.download=s,document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u)}export{n as t};
@@ -1 +0,0 @@
1
- import{o as e}from"./config-AL77QAx4.js";import{n as t}from"./toast-60iDlgiH.js";import{Sn as n,_n as r,bn as i,xn as a}from"./orchestrator-B9KmIj8Q.js";async function o(e,t,r){let i=await n(e,t),{dirs:o,filename:s}=a(r),c=i;for(let e of o)c=await c.getDirectoryHandle(e);return await(await c.getFileHandle(s)).getFile()}const s=new class{_file;constructor(){this._file=new t.State(null)}closeFile(){this._file.set(null)}get file(){return this._file.get()}getFile(){return this.file}getPreviewBinaryMimeType(e){return{"3gp":`video/3gpp`,"7z":`application/x-7z-compressed`,aac:`audio/aac`,apng:`image/apng`,avi:`video/x-msvideo`,avif:`image/avif`,bin:`application/octet-stream`,bmp:`image/bmp`,db:`application/vnd.sqlite3`,dll:`application/octet-stream`,dmg:`application/octet-stream`,dylib:`application/octet-stream`,exe:`application/vnd.microsoft.portable-executable`,flac:`audio/flac`,flv:`video/x-flv`,gif:`image/gif`,gz:`application/gzip`,heic:`image/heic`,heif:`image/heif`,ico:`image/x-icon`,iso:`application/octet-stream`,jpeg:`image/jpeg`,jpg:`image/jpeg`,m4a:`audio/mp4`,m4v:`video/mp4`,mkv:`video/x-matroska`,mov:`video/mp4`,mp3:`audio/mpeg`,mp4:`video/mp4`,oga:`audio/ogg`,ogg:`audio/ogg`,ogv:`video/ogg`,png:`image/png`,rar:`application/vnd.rar`,so:`application/octet-stream`,sqlite:`application/vnd.sqlite3`,sqlite3:`application/vnd.sqlite3`,tar:`application/x-tar`,tif:`image/tiff`,tiff:`image/tiff`,wasm:`application/wasm`,wav:`audio/wav`,weba:`audio/webm`,webm:`video/webm`,webp:`image/webp`,wmv:`video/x-ms-wmv`,zip:`application/zip`}[e.toLowerCase().split(`.`).pop()||``]||``}async openFile(t,n,a=e){try{let e=n.split(`/`).pop()||n,s=/\.pdf$/i.test(e),c=this.getPreviewBinaryMimeType(e);if(s){let r=await i(t,a,n);this._file.set({name:e,path:n,groupId:a,content:``,kind:`pdf`,binaryContent:r,mimeType:`application/pdf`});return}if(c){let r=await o(t,a,n);this._file.set({name:e,path:n,groupId:a,content:``,kind:`binary`,binaryContent:null,nativeFile:r,mimeType:c});return}let l=await r(t,a,n);this._file.set({name:e,path:n,groupId:a,content:l,kind:`text`,binaryContent:null,mimeType:`text/plain`})}catch(e){throw console.error(`Failed to open file:`,n,e),e}}};export{s as t};
@@ -1 +0,0 @@
1
- import{I as e,M as t,h as n,r,y as i}from"./config-AL77QAx4.js";import{t as a}from"./getConfig-D89uJgo5.js";import{t as o}from"./setConfig-DFMYnYLE.js";import{t as s}from"./ulid-BY7rQVLN.js";import{n as c,r as l}from"./crypto-C8c5wMzN.js";function u(e){return!e||e.authMode===`token`||e.authMode===`pat`?`token`:e.authMode===`basic`?`basic`:e.authMode===`oauth`||e.oauthProviderId||e.oauthClientId||e.oauthClientSecret||e.refreshToken||e.accessTokenExpiresAt||e.tokenType||e.oauthReauthRequired?`oauth`:`token`}function d(e){return u(e)}function f(e,t){return d(e)!==`oauth`||e.oauthReauthRequired||!e.refreshToken||!e.oauthProviderId||!e.oauthClientId?!1:t.forceRefresh?!0:e.accessTokenExpiresAt?e.accessTokenExpiresAt<=Date.now()+6e4:!1}async function p(e,t,n){if(!n.refreshToken||!n.oauthProviderId||!n.oauthClientId)return n;let i=await c(n.refreshToken);if(!i)return n;let a=n.oauthClientSecret?await c(n.oauthClientSecret):void 0,s=async i=>{let a=t.findIndex(e=>e.id===n.id);a!==-1&&(t[a]=i,await o(e,r.SERVICE_ACCOUNTS,t))},u=async()=>{let e=(n.oauthRefreshFailureCount||0)+1,t=e>=3,r={...n,oauthRefreshFailureCount:e,oauthReauthRequired:t,oauthReauthRequiredAt:t?n.oauthReauthRequiredAt||Date.now():void 0};return await s(r),r};try{let e=await fetch(`/oauth/refresh`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({providerId:n.oauthProviderId,clientId:n.oauthClientId,clientSecret:a,refreshToken:i,scope:n.scopes,tokenUrl:n.oauthCustomTokenUrl})});if(!e.ok)return u();let t=await e.json();if(!t.accessToken)return u();let r=await l(t.accessToken);if(!r)return u();let o=n.refreshToken;if(t.refreshToken){let e=await l(t.refreshToken);e&&(o=e)}let c={...n,token:r,refreshToken:o,accessTokenExpiresAt:t.expiresIn?Date.now()+t.expiresIn*1e3:n.accessTokenExpiresAt,tokenType:t.tokenType||n.tokenType,scopes:t.scope?t.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):n.scopes,oauthRefreshFailureCount:0,oauthReauthRequired:!1,oauthReauthRequiredAt:void 0};return await s(c),c}catch{return u()}}function m(e,r){if(e.oauthProviderId){let n=t(e.oauthProviderId);if(n)return n}let i=[e.service,e.hostPattern,r].filter(e=>!!e).map(e=>e.toLowerCase());for(let e of Object.values(n))if([e.providerId,...e.aliases||[]].map(e=>e.toLowerCase()).some(e=>i.some(t=>t.includes(e))))return e;return null}function h(e,t){let n=d(e),r=m(e,t);if(r){let e;return e=n===`oauth`?r.tokenAuth.oauth:n===`basic`&&r.tokenAuth.basic?r.tokenAuth.basic:r.tokenAuth.token,{headerName:e.headerName,headerPrefix:e.headerPrefix||``}}return{headerName:`Authorization`,headerPrefix:n===`basic`?`Basic `:`Bearer `}}function g(e,t){let n=[],r=-1,i=t.toLowerCase();for(let t of e){if(!t.hostPattern)continue;let e=t.hostPattern.toLowerCase();i.includes(e)&&(e.length>r?(r=e.length,n.length=0,n.push(t)):e.length===r&&n.push(t))}return n}function _(e,t){return e.length?t&&e.find(e=>d(e)===t)||e[0]:void 0}async function v(e,t,n={}){let i=await a(e,r.SERVICE_ACCOUNTS),o=Array.isArray(i)?i:[];if(o.length===0)return;let s;if(n.accountId&&(s=o.find(e=>e.id===n.accountId)),!s&&t){let e=g(o,t);s=n.authMode?_(e,n.authMode):_(e,e[0]?m(e[0],t)?.defaultMode:void 0)}if(!s){let t=await a(e,r.SERVICE_DEFAULT_ACCOUNT);t&&(s=o.find(e=>e.id===t))}if(!s&&n.authMode&&(s=_(o,n.authMode)),s||=o[0],!s)return;if(f(s,n)&&(s=await p(e,o,s)),d(s)===`oauth`&&s.oauthReauthRequired)return{token:``,service:s.service,hostPattern:s.hostPattern,headerName:`Authorization`,headerValue:``,accountId:s.id,authMode:`oauth`,reauthRequired:!0};let l=``;s.token&&(l=await c(s.token)??``);let{headerName:u,headerPrefix:v}=h(s,t),y=l;d(s)===`basic`&&s.basicUsername&&(y=btoa(`${s.basicUsername}:${l}`));let b=v?`${v}${y}`:y;return{token:l,service:s.service,hostPattern:s.hostPattern,headerName:u,headerValue:b,accountId:s.id,authMode:d(s)}}function y(e){return u(e)}function b(e){switch(e){case`azure-devops`:return`azure_devops`;default:return e}}function x(e){if(!e)return`generic`;let t=e.toLowerCase();return t.includes(`github`)?`github`:t.includes(`dev.azure.com`)||t.includes(`visualstudio.com`)?`azure-devops`:t.includes(`gitlab`)?`gitlab`:`generic`}function S(t){if(t.reauthRequired)return{};let n=t.provider||x(t.hostPattern||``),r=b(n),i=t.authMode||`token`;if(t.token&&r===`azure_devops`&&e(r,i,`git_remote`)?.headerPrefix===`Basic `)return{Authorization:`Basic ${btoa(`:`+t.token)}`};switch(n){case`azure-devops`:if(t.username&&t.password)return{Authorization:`Basic ${btoa(t.username+`:`+t.password)}`};break;default:break}if(t.token){let n=e(r,i,`git_remote`);return n?.headerName?{[n.headerName]:`${n.headerPrefix||``}${t.token}`}:{Authorization:`Bearer ${t.token}`}}return{}}function C(e){try{let t=new URL(e),n=t.pathname.replace(/\/+$/,``);return n?t.hostname+n:t.hostname}catch{return}}function w(e,t){let n=t.toLowerCase(),r=[],i=-1;for(let t of e){if(!t.hostPattern)continue;let e=t.hostPattern.toLowerCase();n.includes(e)&&(e.length>i?(i=e.length,r.length=0,r.push(t)):e.length===i&&r.push(t))}return r}function T(e,t){if(!e.length)return;if(!t)return e[0];let n=e.find(e=>y(e)===t);if(n)return n;if(t===`token`){let t=e.find(e=>y(e)===`token`&&!e.authMode);if(t)return t}return e[0]}async function E(e){if(e)return await c(e)??void 0}function D(e,t){return y(e)!==`oauth`||e.oauthReauthRequired||!e.refreshToken||!e.oauthProviderId||!e.oauthClientId?!1:t.forceRefresh?!0:e.accessTokenExpiresAt?e.accessTokenExpiresAt<=Date.now()+6e4:!1}async function O(e,t,n){if(!n.refreshToken||!n.oauthProviderId||!n.oauthClientId)return n;let i=await E(n.refreshToken);if(!i)return n;let a=n.oauthClientSecret?await E(n.oauthClientSecret):void 0,s=async i=>{let a=t.findIndex(e=>e.id===n.id);a!==-1&&(t[a]=i,await o(e,r.GIT_ACCOUNTS,t))},c=async()=>{let e=(n.oauthRefreshFailureCount||0)+1,t=e>=3,r={...n,oauthRefreshFailureCount:e,oauthReauthRequired:t,oauthReauthRequiredAt:t?n.oauthReauthRequiredAt||Date.now():void 0};return await s(r),r};try{let e=await fetch(`/oauth/refresh`,{body:JSON.stringify({clientId:n.oauthClientId,clientSecret:a,providerId:n.oauthProviderId,refreshToken:i,scope:n.scopes}),headers:{"content-type":`application/json`},method:`POST`});if(!e.ok)return c();let t=await e.json();if(!t.accessToken)return c();let r=await l(t.accessToken);if(!r)return c();let o=n.refreshToken;if(t.refreshToken){let e=await l(t.refreshToken);e&&(o=e)}let u={...n,token:r,refreshToken:o,accessTokenExpiresAt:t.expiresIn?Date.now()+t.expiresIn*1e3:n.accessTokenExpiresAt,tokenType:t.tokenType||n.tokenType,scopes:t.scope?t.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):n.scopes,oauthRefreshFailureCount:0,oauthReauthRequired:!1,oauthReauthRequiredAt:void 0};return await s(u),u}catch{return c()}}async function k(e,t,n={}){let i=await a(e,r.GIT_ACCOUNTS);return Array.isArray(i)&&i.length>0?ee(e,i,t,n):A(e)}async function ee(e,t,n,i={}){let o;if(i.accountId&&(o=t.find(e=>e.id===i.accountId)),!o&&n){let e=C(n);e&&(o=T(w(t,e),i.authMode))}if(!o){let i=await a(e,r.GIT_DEFAULT_ACCOUNT);if(i){let e=t.find(e=>e.id===i);if(e)if(!n)o=e;else{let t=C(n);if(t&&e.hostPattern){let n=t?.toLowerCase(),r=e.hostPattern.toLowerCase();n?.includes(r)&&(o=e)}}}}if(!o&&!n&&i.authMode&&(o=T(t,i.authMode)),!o&&!n&&(o=t[0]),!o)return{authMode:`token`,authorEmail:void 0,authorName:void 0,password:void 0,provider:`generic`,token:void 0,username:void 0};D(o,i)&&(o=await O(e,t,o));let s=o.provider||x(o.hostPattern||``);return y(o)===`oauth`&&o.oauthReauthRequired?{accountId:o.id,authMode:`oauth`,authorEmail:o.authorEmail||void 0,authorName:o.authorName||void 0,hostPattern:o.hostPattern||void 0,password:void 0,provider:s,reauthRequired:!0,token:void 0,username:o.username||void 0}:{accountId:o.id,authMode:y(o),authorEmail:o.authorEmail||void 0,authorName:o.authorName||void 0,hostPattern:o.hostPattern||void 0,password:await E(o.password),provider:s,token:await E(o.token),username:o.username||void 0}}async function A(e){let t=await a(e,r.GIT_TOKEN),n=await a(e,r.GIT_PASSWORD);return{authMode:`token`,authorEmail:await a(e,r.GIT_AUTHOR_EMAIL)||void 0,authorName:await a(e,r.GIT_AUTHOR_NAME)||void 0,password:n?await E(n):void 0,provider:`generic`,token:t?await E(t):void 0,username:await a(e,r.GIT_USERNAME)||void 0}}function j(e){if(typeof e!=`string`||!e.trim())return!1;try{let t=new URL(e);return t.protocol===`https:`||t.protocol===`http:`}catch{return!1}}function M(e,t){if(!e||typeof e!=`object`)return null;let n=e;if(!n.serviceType||!n.authType)return null;if(n.serviceType!==t)throw Error(`Credential ref serviceType must match connection serviceType`);return{serviceType:n.serviceType,authType:n.authType,providerId:n.providerId||void 0,accountId:n.accountId||void 0,gitAccountId:n.gitAccountId||void 0,headerName:n.headerName||void 0,encryptedValue:n.encryptedValue||void 0}}function N(e){if(!e||typeof e!=`object`)return null;let t=e;return!t.id||!t.label||!t.serviceType||!t.transport||typeof t.enabled!=`boolean`||typeof t.createdAt!=`number`||typeof t.updatedAt!=`number`||!j(t.serverUrl)||t.serviceType!==`mcp_remote`&&t.serviceType!==`webmcp_local`||t.transport!==`streamable_http`&&t.transport!==`sse`&&t.transport!==`websocket`?null:{id:t.id,label:t.label,serviceType:t.serviceType,serverUrl:t.serverUrl,transport:t.transport,enabled:t.enabled,autoReconnectOAuth:t.autoReconnectOAuth===!0,createdAt:t.createdAt,updatedAt:t.updatedAt,credentialRef:M(t.credentialRef,t.serviceType)}}async function P(e){let t=await a(e,r.REMOTE_MCP_CONNECTIONS);if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=N(e);t&&n.push(t)}return n}async function F(e,t){await o(e,r.REMOTE_MCP_CONNECTIONS,t)}async function te(e){return P(e)}async function I(e,t){if(!t)return null;let n=await P(e);return n.find(e=>e.id===t)||n.find(e=>e.label.toLowerCase()===t.toLowerCase())||null}async function ne(e,t){if(!t?.label?.trim())throw Error(`Connection label is required`);if(!j(t.serverUrl))throw Error(`Connection serverUrl must be an absolute http(s) URL`);let n=t.serviceType||`mcp_remote`;if(n!==`mcp_remote`&&n!==`webmcp_local`)throw Error(`Unsupported serviceType for remote MCP connection`);let r=await P(e),i=Date.now();if(t.id){let a=r.findIndex(e=>e.id===t.id);if(a!==-1){let o=r[a],s={...o,label:t.label.trim(),serviceType:n,serverUrl:t.serverUrl,transport:t.transport,enabled:t.enabled??o.enabled,autoReconnectOAuth:t.autoReconnectOAuth??o.autoReconnectOAuth,updatedAt:i};return r[a]=s,await F(e,r),s}}let a={id:t.id||s(),label:t.label.trim(),serviceType:n,serverUrl:t.serverUrl,transport:t.transport,enabled:t.enabled??!0,autoReconnectOAuth:t.autoReconnectOAuth??!1,createdAt:i,updatedAt:i,credentialRef:null};return r.push(a),await F(e,r),a}async function re(e,t,n){if(!t)return null;let r=await P(e),i=r.findIndex(e=>e.id===t);if(i===-1)return null;let a=r[i],o=n?M(n,a.serviceType):null,s={...a,credentialRef:o,updatedAt:Date.now()};return r[i]=s,await F(e,r),s}async function L(e,t){if(!t)return!1;let n=await P(e),r=n.filter(e=>e.id!==t);return r.length===n.length?!1:(await F(e,r),!0)}function R(e){return e===`oauth`?`oauth`:`token`}async function z(e,t,n={}){let r=await I(e,t);if(!r)return null;let i=r.credentialRef;if(!i||i.authType===`none`)return{connection:r,authType:`none`,headers:{}};if(i.authType===`custom_header`){if(!i.headerName||!i.encryptedValue)return{connection:r,authType:`custom_header`,headers:{}};let e=await c(i.encryptedValue);return{connection:r,authType:`custom_header`,headers:e?{[i.headerName]:e}:{}}}let a=R(i.authType);if(i.accountId){let t=await v(e,r.serverUrl,{accountId:i.accountId,authMode:a,forceRefresh:n.forceRefresh});return t?t.reauthRequired?{connection:r,authType:i.authType,headers:{},reauthRequired:!0}:{connection:r,authType:i.authType,headers:t.headerValue?{[t.headerName]:t.headerValue}:{}}:{connection:r,authType:i.authType,headers:{}}}if(i.gitAccountId){let t=await k(e,r.serverUrl,{accountId:i.gitAccountId,authMode:a,forceRefresh:n.forceRefresh});return t.reauthRequired?{connection:r,authType:i.authType,headers:{},reauthRequired:!0}:{connection:r,authType:i.authType,headers:S(t)}}return{connection:r,authType:i.authType,headers:{}}}const B=new Map;function V(e){return typeof e==`object`&&!!e&&`method`in e&&`id`in e&&!(`result`in e)&&!(`error`in e)}function H(e){let t=(e.requestedSchema||{}).properties||{},n={};for(let[e,r]of Object.entries(t))`default`in r?n[e]=r.default:r.type===`boolean`&&(n[e]=!0);return n}var U=class extends Error{constructor(e){super(e),this.name=`InvalidRemoteMcpSessionError`}},W=class extends Error{status;constructor(e,t){super(t),this.name=`HttpRemoteMcpError`,this.status=e}},G=class extends Error{connectionId;constructor(e){super(`OAuth reconnect required for remote MCP connection`),this.name=`McpReauthRequiredError`,this.connectionId=e}};function K(e,t){return!e.headers||typeof e.headers.get!=`function`?null:e.headers.get(t)}function ie(e){return/no valid session id provided/i.test(e)}function q(e,t){let n=t&&`error`in t?t.error.message||`Remote MCP JSON-RPC error`:``;return ie(n)?new U(n):e.ok?Error(n||`Remote MCP JSON-RPC error`):new W(e.status,n?`Remote MCP HTTP error: ${e.status} (${n})`:`Remote MCP HTTP error: ${e.status}`)}function ae(e){if(!e)return null;let t=null,n=e.split(/\r?\n/);for(let e of n){let n=e.trim();if(!n.startsWith(`data:`))continue;let r=n.slice(5).trim();if(!(!r||r===`[DONE]`))try{let e=JSON.parse(r);e&&typeof e==`object`&&`jsonrpc`in e&&(t=e)}catch{}}return t}function oe(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function J(e,t,n){let r=await fetch(e,{method:`POST`,headers:{"content-type":`application/json`,accept:`application/json, text/event-stream`,...t},body:JSON.stringify(n)}),i=(K(r,`content-type`)||``).toLowerCase(),a=null;if(typeof r.text==`function`){let e=await r.text();a=i.includes(`text/event-stream`)?ae(e):oe(e)}else try{a=await r.json()}catch{a=null}return{response:r,payload:a}}async function se(e,t,n){let{response:r,payload:i}=await J(e,{...t,"mcp-session-id":n},{jsonrpc:`2.0`,method:`notifications/initialized`,params:{}});if(!r.ok||i&&`error`in i)throw q(r,i)}async function Y(e,t,n){let r=B.get(e);if(r?.sessionId)return r;let{response:i,payload:a}=await J(t,n,{jsonrpc:`2.0`,id:`initialize-${Date.now().toString(36)}`,method:`initialize`,params:{protocolVersion:`2025-03-26`,capabilities:{elicitation:{}},clientInfo:{name:`shadowclaw-remote-mcp-client`,version:`1.0.0`}}});if(!i.ok||a&&`error`in a)throw q(i,a);let o=K(i,`mcp-session-id`)||`local-${Date.now()}-${Math.random().toString(36).slice(2)}`,s={sessionId:o,protocolVersion:K(i,`mcp-protocol-version`)||a?.result?.protocolVersion,lastUsedAt:Date.now()};return await se(t,n,o),B.set(e,s),s}async function X(e,t,n,r,i){let a=await Y(e,t,n),o=async e=>{let a={jsonrpc:`2.0`,id:Date.now().toString(),method:r,params:i||{}},o={...n,"mcp-session-id":e},{response:s,payload:c}=await J(t,o,a),l=0;for(;V(c)&&l<5&&(l++,c.method===`elicitation/create`);){let e=H(c.params||{});({response:s,payload:c}=await J(t,o,{jsonrpc:`2.0`,id:c.id,result:{action:`accept`,content:e}}))}if(V(c))throw Error(`Unsupported server request: ${c.method}`);if(!s.ok||!c||`error`in c)throw q(s,c);return c.result};try{let t=await o(a.sessionId);return a.lastUsedAt=Date.now(),B.set(e,a),t}catch(r){if(!(r instanceof U))throw r;B.delete(e),a=await Y(e,t,n);let i=await o(a.sessionId);return a.lastUsedAt=Date.now(),B.set(e,a),i}}function Z(e){e&&B.delete(e)}async function Q(e,t,n,r){let i=await z(e,t);if(!i)throw Error(`Remote MCP connection not found`);if(i.reauthRequired)throw new G(t);let{connection:a,authType:o,headers:s}=i;if(a.transport!==`streamable_http`)throw Error(`Unsupported remote MCP transport`);try{return await X(t,a.serverUrl,s,n,r)}catch(i){if(!(i instanceof W)||i.status!==401||o!==`oauth`)throw i;Z(t);let a=await z(e,t,{forceRefresh:!0});if(!a||a.reauthRequired)throw new G(t);try{return await X(t,a.connection.serverUrl,a.headers,n,r)}catch(e){throw e instanceof W&&e.status===401?new G(t):e}}}async function ce(e,t){let n=await Q(e,t,`tools/list`);return Array.isArray(n.tools)?n.tools:[]}async function le(e,t,n,r={}){return Q(e,t,`tools/call`,{name:n,arguments:r})}async function ue(e,t){let n=[],r;try{r=await z(e,t)}catch(e){let t=e instanceof Error?e.message:String(e);return n.push({step:`Resolve authentication`,status:`error`,detail:t}),{success:!1,error:t,toolCount:0,toolNames:[],steps:n}}if(!r)return n.push({step:`Resolve authentication`,status:`error`,detail:`Connection not found`}),{success:!1,error:`Connection not found`,toolCount:0,toolNames:[],steps:n};if(r.reauthRequired){let e=`OAuth token expired or revoked — re-authenticate in Settings`;return n.push({step:`Resolve authentication`,status:`error`,detail:e}),{success:!1,error:e,toolCount:0,toolNames:[],steps:n}}n.push({step:`Resolve authentication`,status:`ok`,detail:`Auth type: ${r.authType}`});let{connection:i,authType:a,headers:o}=r;if(i.transport!==`streamable_http`){let e=`Unsupported transport: ${i.transport}`;return n.push({step:`Establish MCP session`,status:`error`,detail:e}),{success:!1,error:e,toolCount:0,toolNames:[],steps:n}}Z(t);try{await Y(t,i.serverUrl,o),n.push({step:`Establish MCP session`,status:`ok`,detail:`Session established`})}catch(r){let s=r instanceof Error?r.message:String(r);if(n.push({step:`Establish MCP session`,status:`error`,detail:s}),r instanceof W&&r.status===401&&a===`oauth`){Z(t);let r=await z(e,t,{forceRefresh:!0});if(r&&!r.reauthRequired){n.push({step:`Refresh OAuth token`,status:`ok`,detail:`Token refreshed, retrying`}),i=r.connection,o=r.headers;try{await Y(t,i.serverUrl,o),n.push({step:`Establish MCP session`,status:`ok`,detail:`Session established`})}catch(e){let t=e instanceof Error?e.message:String(e),r=e instanceof W&&e.status===401?`${t} — re-authorize in Settings → Accounts`:t;return n.push({step:`Establish MCP session`,status:`error`,detail:r}),{success:!1,error:r,toolCount:0,toolNames:[],steps:n}}}else return n.push({step:`Refresh OAuth token`,status:`error`,detail:`Token refresh failed — re-authenticate in Settings`}),{success:!1,error:s,toolCount:0,toolNames:[],steps:n}}else return{success:!1,error:s,toolCount:0,toolNames:[],steps:n}}try{let e=await X(t,i.serverUrl,o,`tools/list`),r=Array.isArray(e.tools)?e.tools:[],a=r.map(e=>e.name);return n.push({step:`Discover tools`,status:`ok`,detail:`${r.length} tool${r.length===1?``:`s`} available`}),{success:!0,error:null,toolCount:r.length,toolNames:a,steps:n}}catch(e){let t=e instanceof Error?e.message:String(e);return n.push({step:`Discover tools`,status:`error`,detail:t}),{success:!1,error:t,toolCount:0,toolNames:[],steps:n}}}function $(e,t,n,r){return{accessTokenExpiresAt:e.expiresIn?Date.now()+e.expiresIn*1e3:t.accessTokenExpiresAt,oauthReauthRequired:!1,oauthReauthRequiredAt:void 0,oauthRefreshFailureCount:0,refreshToken:r,scopes:e.scope?e.scope.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean):t.scopes,token:n,tokenType:e.tokenType||t.tokenType}}async function de(e,t,n,i,a,s,u){if(!t.refreshToken)return{success:!1,error:`No refresh token available.`};let d=await c(t.refreshToken);if(!d)return{success:!1,error:`Failed to decrypt refresh token.`};let f=t.oauthClientSecret?await c(t.oauthClientSecret):void 0;try{let c=await fetch(`/oauth/refresh`,{body:JSON.stringify({clientId:t.oauthClientId,clientSecret:f||void 0,providerId:t.oauthProviderId,refreshToken:d,scope:t.scopes,tokenUrl:t.oauthCustomTokenUrl}),headers:{"content-type":`application/json`},method:`POST`});if(!c.ok)return{success:!1,error:`Token refresh request failed.`};let p=await c.json();if(!p.accessToken)return{success:!1,error:`No access token in refresh response.`};let m=await l(p.accessToken);if(!m)return{success:!1,error:`Failed to encrypt access token.`};let h=t.refreshToken;if(p.refreshToken){let e=await l(p.refreshToken);e&&(h=e)}let g=$({accessToken:p.accessToken,expiresIn:p.expiresIn,refreshToken:p.refreshToken,scope:p.scope,tokenType:p.tokenType},t,m,h);if(n===`service`&&s.accountId){let t=i.findIndex(e=>e.id===s.accountId);t!==-1&&(Object.assign(i[t],g),await o(e,r.SERVICE_ACCOUNTS,i))}else if(n===`git`&&s.gitAccountId){let t=a.findIndex(e=>e.id===s.gitAccountId);t!==-1&&(Object.assign(a[t],g),await o(e,r.GIT_ACCOUNTS,a))}return Z(u),{success:!0}}catch(e){return{success:!1,error:`Silent refresh failed: ${e instanceof Error?e.message:String(e)}`}}}async function fe(e,t,n={}){let s=await I(e,t);if(!s?.credentialRef)return{success:!1,error:`Connection not found.`};let u=s.credentialRef;if(u.authType!==`oauth`)return{success:!1,error:`This connection does not use OAuth authentication.`};let d=await a(e,r.SERVICE_ACCOUNTS),f=Array.isArray(d)?d:[],p=await a(e,r.GIT_ACCOUNTS),m=Array.isArray(p)?p:[],h,g=null;if(u.accountId?(h=f.find(e=>e.id===u.accountId),g=`service`):u.gitAccountId&&(h=m.find(e=>e.id===u.gitAccountId),g=`git`),!h||!g)return{error:`Linked account not found. Edit the connection to re-configure authentication.`,success:!1};let _=h.oauthClientId,v=h.oauthProviderId;if(!v||!_)return{error:`Account is missing OAuth provider or client ID. Edit the account in Settings → Accounts to fix.`,success:!1};if(h.refreshToken){let n=await de(e,h,g,f,m,u,t);if(n.success)return n}if(n.silentOnly)return{error:`Silent token refresh failed. Use Settings → Remote MCP → Reconnect OAuth for full re-authorization.`,success:!1};let y=h.oauthClientSecret?await c(h.oauthClientSecret):void 0,b=h.scopes,x=i[v],S=v===`custom_mcp`,C=S&&h.oauthCustomRedirectUri?h.oauthCustomRedirectUri:x?.redirectUri?x.redirectUri:`${globalThis.location?.origin||``}/oauth/callback`;try{let n=await fetch(`/oauth/authorize`,{body:JSON.stringify({providerId:v,clientId:_,clientSecret:y||void 0,redirectUri:C,scope:b,...S&&h.oauthCustomAuthorizeUrl?{authorizeUrl:h.oauthCustomAuthorizeUrl}:{},...S&&h.oauthCustomTokenUrl?{tokenUrl:h.oauthCustomTokenUrl}:{},...S&&typeof h.oauthCustomUsePkce==`boolean`?{usePkce:h.oauthCustomUsePkce}:{}}),headers:{"content-type":`application/json`},method:`POST`}),i=await n.json();if(!n.ok||!i.state||!i.authorizeUrl)throw Error(i.error||`OAuth authorize failed`);let a=window.open(i.authorizeUrl,`shadowclaw-oauth`,`popup=yes,width=540,height=720`);if(!a||a.closed||a.closed===void 0)throw Error(`OAuth popup was blocked by the browser. Please enable popups for this site and try again.`);let s=i.state,c=`pending`;for(let e=0;e<60;e++){let e=await fetch(`/oauth/session/${encodeURIComponent(s)}`),t=await e.json();if(!e.ok)throw Error(t.error||`OAuth session not found`);if(c=t.status||`pending`,c===`authorized`)break;if(c===`error`)throw Error(t.error||`OAuth authorization failed`);await new Promise(e=>setTimeout(e,1e3))}if(c!==`authorized`)throw Error(`OAuth authorization timed out`);let d=await fetch(`/oauth/token`,{body:JSON.stringify({state:s}),headers:{"content-type":`application/json`},method:`POST`}),p=await d.json();if(!d.ok||!p.accessToken)throw Error(p.error||`OAuth token exchange failed`);let x=await l(p.accessToken);if(!x)throw Error(`Failed to encrypt access token`);let w=h.refreshToken;if(p.refreshToken){let e=await l(p.refreshToken);e&&(w=e)}let T=$({accessToken:p.accessToken,expiresIn:p.expiresIn,refreshToken:p.refreshToken,scope:p.scope,tokenType:p.tokenType},h,x,w);if(g===`service`&&u.accountId){let t=f.findIndex(e=>e.id===u.accountId);t!==-1&&(Object.assign(f[t],T),await o(e,r.SERVICE_ACCOUNTS,f))}else if(g===`git`&&u.gitAccountId){let t=m.findIndex(e=>e.id===u.gitAccountId);t!==-1&&(Object.assign(m[t],T),await o(e,r.GIT_ACCOUNTS,m))}return Z(t),{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}export{ue as a,I as c,S as d,x as f,u as h,ce as i,te as l,v as m,G as n,re as o,k as p,le as r,L as s,fe as t,ne as u};
@@ -1,15 +0,0 @@
1
- import{A as e,C as t,D as n,E as r,F as i,L as a,N as o,P as s,T as c,_ as l,g as u,j as d,l as f,o as p,r as m,s as h,t as g,w as _}from"./config-AL77QAx4.js";import{n as v,r as y}from"./txPromise-EBECky1b.js";import{t as b}from"./getConfig-D89uJgo5.js";import{p as x}from"./custom-element-security-CZ92anB8.js";import{n as S}from"./toast-60iDlgiH.js";import{At as C,C as w,Ct as T,Dt as ee,Et as te,Fn as E,Ft as D,G as O,Gt as k,H as A,Ht as j,I as ne,It as M,Jt as N,Kt as P,Lt as F,M as re,Mn as ie,Mt as ae,N as I,Nn as oe,Nt as L,On as se,Ot as R,P as ce,Pt as le,St as z,Tt as ue,U as B,Ut as de,V as fe,W as pe,Wt as me,X as he,Xt as ge,Y as _e,Yt as ve,_n as ye,an as be,at as xe,bn as Se,bt as Ce,dn as V,dt as we,fn as Te,ft as Ee,gn as De,gt as Oe,hn as ke,in as Ae,j as je,jt as Me,kt as H,l as Ne,mn as U,on as Pe,ot as Fe,pn as W,qt as Ie,rn as G,t as K,u as Le,ut as Re,vn as ze,yn as Be}from"./orchestrator-B9KmIj8Q.js";import{t as q}from"./setConfig-DFMYnYLE.js";import{t as J}from"./ulid-BY7rQVLN.js";import{a as Ve,o as He,r as Ue,s as We}from"./syncWebMcpRegistration-DfpvASnh.js";import{n as Ge,r as Ke}from"./crypto-C8c5wMzN.js";import{a as qe,i as Je,r as Y,t as Ye}from"./peerjs-Dv8JNm7v.js";async function Xe(e){if(!(!e||e.name===`shadowclaw`)){try{if(await b(e,m.DB_MIGRATED_FROM_LEGACY)===`true`)return}catch{}try{let t=await new Promise(e=>{let t=indexedDB.open(l);t.onsuccess=()=>{let n=t.result;if(!n.objectStoreNames||n.objectStoreNames.length===0){n.close(),e(null);return}e(n)},t.onerror=()=>e(null)});if(t){let n=Array.from(t.objectStoreNames).filter(t=>e.objectStoreNames.contains(t));for(let r of n)await new Promise(n=>{try{let i=t.transaction(r,`readonly`).objectStore(r).getAll();i.onsuccess=()=>{let t=i.result||[];if(t.length>0)try{let i=e.transaction(r,`readwrite`),a=i.objectStore(r);for(let e of t)a.put(e);i.oncomplete=()=>n(),i.onerror=()=>n(),i.onabort=()=>n()}catch{n()}else n()},i.onerror=()=>n()}catch{n()}});t.close()}}catch(e){console.warn(`Legacy IndexedDB migration warning:`,e)}finally{try{await q(e,m.DB_MIGRATED_FROM_LEGACY,`true`)}catch{}}}}function Ze(){return new Promise(async(t,n)=>{let r,i=e(),a=indexedDB.open(i,2);a.onupgradeneeded=()=>{let e=a.result;if(!e.objectStoreNames.contains(`messages`)){let t=e.createObjectStore(`messages`,{keyPath:`id`});t.createIndex(`by-group-time`,[`groupId`,`timestamp`]),t.createIndex(`by-group`,`groupId`)}if(e.objectStoreNames.contains(`sessions`)||e.createObjectStore(`sessions`,{keyPath:`groupId`}),!e.objectStoreNames.contains(`tasks`)){let t=e.createObjectStore(`tasks`,{keyPath:`id`});t.createIndex(`by-group`,`groupId`),t.createIndex(`by-enabled`,`enabled`)}e.objectStoreNames.contains(`config`)||e.createObjectStore(`config`,{keyPath:`key`}),e.objectStoreNames.contains(`pendingShares`)||e.createObjectStore(`pendingShares`,{keyPath:`id`}).createIndex(`by-createdAt`,`createdAt`)},a.onsuccess=async()=>{r=a.result,y(r);try{await Xe(r)}catch(e){console.warn(`Error running IndexedDB legacy migration:`,e)}t(r)},a.onerror=()=>{n(Error(`Failed to open IndexedDB: ${a.error?.message}`))}})}var Qe=class{activeGroupId;displayCallback;messageCallback;type;typingCallback;constructor(){this.type=`browser`,this.messageCallback=null,this.typingCallback=null,this.displayCallback=null,this.activeGroupId=p}getActiveGroup(){return this.activeGroupId}onDisplay(e){this.displayCallback=e}onMessage(e){this.messageCallback=e}onTyping(e){this.typingCallback=e}setActiveGroup(e){this.activeGroupId=e}setTyping(e,t){this.typingCallback?.(e,t)}start(){}stop(){}submit(e,t,n=[],r,i,a){let o=t||this.activeGroupId,s={id:J(),groupId:o,sender:`You`,content:e,timestamp:Date.now(),channel:`browser`,attachments:n,a2uiAction:r,freshContext:i,subagent:a};this.messageCallback?.(s)}async send(e,t,n){this.displayCallback?.(e,t,!0)}},$e=class{_entries;constructor(){this._entries=[]}find(e){return this.resolve(e)?.channel??null}get(e){return this._entries.find(t=>t.prefix===e)?.channel}getBadge(e){return this.resolve(e)?.badge??``}getChannelType(e){return this.resolve(e)?.channel.type??null}onMessage(e){for(let t of this._entries)t.channel.onMessage(e)}onTyping(e){for(let t of this._entries)t.channel.onTyping&&t.channel.onTyping(e)}prefixes(){return this._entries.map(e=>e.prefix)}register(e,t,n){let r=typeof n==`string`?{badge:n}:n??{};this._entries.push({prefix:e,channel:t,badge:r.badge??e.replace(/:$/,``),autoTrigger:r.autoTrigger??!1}),this._entries.sort((e,t)=>t.prefix.length-e.prefix.length)}resolve(e){for(let t of this._entries)if(e.startsWith(t.prefix))return t;return null}shouldAutoTrigger(e){return this.resolve(e)?.autoTrigger??!1}startAll(){for(let e of this._entries)e.channel.start()}stopAll(){for(let e of this._entries)e.channel.stop()}},et=class{abortController=null;apiKey=``;apiMode=`unknown`;cursor=null;fileReader=null;messageCallback=null;reconnectDelayMs=1e3;registeredChatIds=new Set;running=!1;seenMessageIds=new Map;serverUrl=``;type=`imessage`;configure(e,t,n){this.serverUrl=tt(e),this.apiKey=t.trim(),this.registeredChatIds=new Set(n.map(e=>e.trim()).filter(Boolean)),this.cursor=null,this.apiMode=`unknown`}handleIncomingMessage(e){this.pruneSeenMessageIds();let t=String(e.chatId||e.conversationId||``).trim();if(!t||this.registeredChatIds.size>0&&!this.registeredChatIds.has(t))return;let n=`${e.text||e.body||``}`.trim();if(!n)return;let r=`${e.id||e.guid||`${t}:${e.timestamp||e.createdAt||n}`}`;if(this.seenMessageIds.has(r))return;this.seenMessageIds.set(r,Date.now());let i={id:r,groupId:`im:${t}`,sender:`${e.sender||e.handle||e.from||`iMessage`}`,content:n,timestamp:nt(e.timestamp||e.createdAt),channel:`imessage`};this.messageCallback?.(i)}handlePollResponse(e){e.nextCursor!==void 0&&e.nextCursor!==null?this.cursor=String(e.nextCursor):e.cursor!==void 0&&e.cursor!==null&&(this.cursor=String(e.cursor));let t=Array.isArray(e.messages)?e.messages:[];for(let e of t)this.handleIncomingMessage(e)}isConfigured(){return this.serverUrl.length>0}onMessage(e){this.messageCallback=e}pruneSeenMessageIds(){let e=Date.now();for(let[t,n]of this.seenMessageIds.entries())e-n>6e4&&this.seenMessageIds.delete(t)}setTyping(e,t){if(!t)return;let n=e.replace(/^im:/,``);this.requestJson(`/messages/typing`,{method:`POST`,body:JSON.stringify({chatId:n,typing:!0})}).catch(()=>{})}start(){!this.isConfigured()||this.running||(this.running=!0,this.abortController=new AbortController,this.poll())}stop(){this.running=!1,this.abortController?.abort(),this.abortController=null}async ensureApiMode(){if(this.apiMode!==`unknown`)return this.apiMode;try{await this.requestJson(`/v1/info`,{method:`GET`}),this.apiMode=`beeper-desktop`}catch{this.apiMode=`legacy`}return this.apiMode}async poll(){for(;this.running&&this.abortController&&!this.abortController.signal.aborted;)try{let e=new URLSearchParams({timeout:`25`});this.cursor&&e.set(`cursor`,this.cursor);let t=await this.requestJson(`/messages?${e.toString()}`,{method:`GET`},u+5e3,this.abortController.signal);this.reconnectDelayMs=1e3,this.handlePollResponse(t)}catch(e){if(e instanceof Error&&e.name===`AbortError`)break;console.error(`iMessage bridge poll error:`,e),await rt(this.reconnectDelayMs),this.reconnectDelayMs=Math.min(this.reconnectDelayMs*2,3e4)}}async requestJson(e,t,n=u,r){let i=new AbortController,a=setTimeout(()=>i.abort(),n),o=()=>i.abort();r?.addEventListener(`abort`,o,{once:!0});try{let n=new Headers(t.headers);n.set(`Accept`,`application/json`),!n.has(`Content-Type`)&&t.body&&!(t.body instanceof FormData)&&n.set(`Content-Type`,`application/json`),this.apiKey&&(n.set(`Authorization`,`Bearer ${this.apiKey}`),n.set(`X-API-Key`,this.apiKey));let r=await fetch(`${this.serverUrl}${e}`,{...t,headers:n,signal:i.signal});if(!r.ok){let e=await r.text();throw Error(`iMessage bridge request failed: ${r.status} ${e}`)}return r.status===204?{messages:[]}:await r.json()}finally{clearTimeout(a),r?.removeEventListener(`abort`,o)}}async send(e,t,n){let r=e.replace(/^im:/,``),{remainingText:i,attachments:a}=it(t);for(let t of a){if(!this.fileReader){await this.sendText(r,`[${t.alt}] (file: ${t.path})`);continue}try{let n=await this.fileReader(e,t.path);if(!n||n.size===0)throw Error(`Attachment file is empty or unavailable.`);await this.sendAttachment(r,n,t)}catch(e){console.warn(`iMessage attachment send failed for ${t.path}:`,e),await this.sendText(r,`[${t.alt}] (file: ${t.path})`)}}let o=i.trim();o&&await this.sendText(r,o)}async sendAttachment(e,t,n){if(await this.ensureApiMode()===`beeper-desktop`){await this.sendAttachmentViaBeeperDesktop(e,t,n);return}await this.sendAttachmentViaLegacyBridge(e,t,n)}async sendAttachmentViaBeeperDesktop(e,t,n){let r=n.path.split(`/`).pop()||`attachment.bin`,i=new FormData;i.append(`file`,t,r),i.append(`fileName`,r),t.type&&i.append(`mimeType`,t.type);let a=`${(await this.requestJson(`/v1/assets/upload`,{method:`POST`,body:i})).uploadID||``}`.trim();if(!a)throw Error(`Beeper asset upload failed: missing uploadID`);await this.requestJson(`/v1/chats/${encodeURIComponent(e)}/messages`,{method:`POST`,body:JSON.stringify({text:n.alt||void 0,attachment:{uploadID:a,fileName:r,mimeType:t.type||void 0}})})}async sendAttachmentViaLegacyBridge(e,t,n){let r=n.path.split(`/`).pop()||`attachment.bin`,i=new FormData;i.append(`chatId`,e),n.alt&&i.append(`text`,n.alt),i.append(`file`,t,r),await this.requestJson(`/messages/send`,{method:`POST`,body:i})}async sendText(e,t){if(await this.ensureApiMode()===`beeper-desktop`){await this.requestJson(`/v1/chats/${encodeURIComponent(e)}/messages`,{method:`POST`,body:JSON.stringify({text:t})});return}await this.requestJson(`/messages/send`,{method:`POST`,body:JSON.stringify({chatId:e,text:t})})}};function tt(e){return e.trim().replace(/\/+$/,``)}function nt(e){if(typeof e==`number`&&Number.isFinite(e))return e>0xe8d4a51000?e:e*1e3;if(typeof e==`string`){let t=Number(e);if(Number.isFinite(t))return nt(t);let n=Date.parse(e);if(Number.isFinite(n))return n}return Date.now()}function rt(e){return new Promise(t=>setTimeout(t,e))}function it(e){let t=[],n=/!?\[([^\]]*)\]\(([^)]+)\)/g,r=null,i=e;for(;(r=n.exec(e))!==null;){let e=r[1]||``,n=at((r[2]||``).trim());n&&(t.push({alt:e,path:n}),i=i.replace(r[0],``))}return{remainingText:i,attachments:t}}function at(e){if(!e)return null;let t=e.trim();if(/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(t)||t.startsWith(`//`))return null;let n=t.replace(/\\/g,`/`).replace(/^\/+/,``).replace(/^\.\//,``);if(!n)return null;let r=n.split(`/`).filter(Boolean);return r.some(e=>e===`..`)?null:r.join(`/`)}var ot=class{messageCallback=null;running=!1;type=`room`;typingCallback=null;_manager=null;deliverInbound(e){this.messageCallback?.(e)}onMessage(e){this.messageCallback=e}onTyping(e){this.typingCallback=e}setManager(e){this._manager=e}setTyping(e,t){}start(){this.running=!0}stop(){this.running=!1}async send(e,t,n){if(!this._manager)return;let r=ve(e);this._manager.broadcast(r,t,n)}};const st=1e3;var ct=class{abortController=null;fileReader=null;messageCallback=null;offset=0;pollRetryDelayMs=st;pollSessionId=0;registeredChatIds=new Set;running=!1;token=``;type=`telegram`;useProxy=!1;buildFileUrl(e){let t=e.split(`/`).filter(Boolean).map(e=>encodeURIComponent(e)).join(`/`);return`${this.useProxy?`/telegram/file/bot`:`https://api.telegram.org/file/bot`}${this.token}/${t}`}buildMethodUrl(e){let t=e.replace(/^\/+/,``);return`${this.useProxy?r:_}${this.token}/${t}`}configure(e,t,n=!1){this.token=e.trim(),this.registeredChatIds=new Set(t.map(e=>e.trim()).filter(Boolean)),this.useProxy=!!n}isConfigured(){return this.token.length>0}nextPollRetryDelay(){let e=this.pollRetryDelayMs;return this.pollRetryDelayMs=Math.min(this.pollRetryDelayMs*2,6e4),e}onMessage(e){this.messageCallback=e}registerChatId(e){let t=e.trim();t&&this.registeredChatIds.add(t)}resetPollBackoff(){this.pollRetryDelayMs=st}setTyping(e,t){if(!t)return;let n=e.replace(/^tg:/,``);this.apiCall(`sendChatAction`,{chat_id:n,action:`typing`}).catch(()=>{})}start(){if(!this.token||this.running)return;this.running=!0,this.resetPollBackoff();let e=++this.pollSessionId,t=new AbortController;this.abortController=t,this.poll(e,t)}stop(){this.running=!1,this.resetPollBackoff(),this.pollSessionId+=1,this.abortController?.abort(),this.abortController=null}async apiCall(e,t){let n=await fetch(this.buildMethodUrl(e),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let t=await n.text();throw Error(`Telegram API ${e} failed: ${n.status} ${t}`)}return await n.json()}async extractAttachments(e){let t=[],n=Array.isArray(e.photo)?e.photo.at(-1):null;n?.file_id&&t.push({id:n.file_id,fileName:`photo-${e.message_id}.png`,mimeType:`image/png`,previewDisposition:`inline`}),e.document?.file_id&&t.push({id:e.document.file_id,fileName:e.document.file_name||`document-${e.message_id}`,mimeType:e.document.mime_type}),e.video?.file_id&&t.push({id:e.video.file_id,fileName:e.video.file_name||`video-${e.message_id}.mp4`,mimeType:e.video.mime_type||`video/mp4`}),e.audio?.file_id&&t.push({id:e.audio.file_id,fileName:e.audio.file_name||`audio-${e.message_id}.mp3`,mimeType:e.audio.mime_type||`audio/mpeg`}),e.voice?.file_id&&t.push({id:e.voice.file_id,fileName:`voice-${e.message_id}.ogg`,mimeType:e.voice.mime_type||`audio/ogg`}),e.animation?.file_id&&t.push({id:e.animation.file_id,fileName:e.animation.file_name||`animation-${e.message_id}.mp4`,mimeType:e.animation.mime_type||`video/mp4`}),e.sticker?.file_id&&t.push({id:e.sticker.file_id,fileName:`sticker-${e.message_id}.${dt(e.sticker)}`,mimeType:e.sticker.is_animated?`application/x-tgsticker`:e.sticker.is_video?`video/webm`:`image/webp`});let r=[];for(let e of t){let t=await this.fetchTelegramFileInfo(e.id);r.push({id:e.id,fileName:e.fileName,mimeType:e.mimeType,size:t.file_size,previewDisposition:e.previewDisposition,source:{kind:`remote-url`,url:this.buildFileUrl(t.file_path)}})}return r}async fetchTelegramFileInfo(e){let t=await this.apiCall(`getFile`,{file_id:e});if(!t.ok||!t.result?.file_path)throw Error(`Telegram getFile failed for attachment ${e}`);return t.result}async handleUpdate(e){let t=e.message;if(!t)return;let n=String(t.chat.id);if(t.text===`/chatid`){this.apiCall(`sendMessage`,{chat_id:n,text:`Chat ID: ${n}\nRegister this ID in ShadowClaw settings.`}).catch(console.error);return}if(t.text===`/ping`){this.apiCall(`sendMessage`,{chat_id:n,text:`Pong! ShadowClaw is running.`}).catch(console.error);return}if(!this.registeredChatIds.has(n))return;let r=await this.extractAttachments(t),i=`${t.text||t.caption||``}`.trim()||(t.photo?.length?`[Photo]`:null)||(t.voice?`[Voice message]`:null)||(t.video?`[Video]`:null)||(t.audio?`[Audio]`:null)||(t.animation?`[Animation]`:null)||(t.document?`[Document: ${t.document.file_name||`unnamed`}]`:null)||(t.sticker?`[Sticker: ${t.sticker.emoji||``}]`:null)||(t.location?`[Location: ${t.location.latitude}, ${t.location.longitude}]`:null)||(t.contact?`[Contact: ${t.contact.first_name}]`:null)||`[Unsupported message type]`,a=t.from?.first_name||t.from?.username||String(t.from?.id||`Unknown`),o={id:String(t.message_id),groupId:`tg:${n}`,sender:a,content:i,timestamp:t.date*1e3,channel:`telegram`,attachments:r};this.messageCallback?.(o)}async poll(e,t){for(;this.running&&this.pollSessionId===e&&!t.signal.aborted;)try{let e=await fetch(this.buildMethodUrl(`getUpdates?offset=${this.offset}&timeout=30`),{signal:t.signal});if(!e.ok){console.error(`Telegram poll error: HTTP ${e.status}`),await this.waitForRetry(this.nextPollRetryDelay());continue}let n=await e.json();if(!n.ok||!Array.isArray(n.result)){await this.waitForRetry(this.nextPollRetryDelay());continue}this.resetPollBackoff();for(let e of n.result)this.offset=e.update_id+1,await this.handleUpdate(e)}catch(e){if(e instanceof Error&&e.name===`AbortError`)break;console.error(`Telegram poll error:`,e),await this.waitForRetry(this.nextPollRetryDelay())}}async send(e,t,n){let r=e.replace(/^tg:/,``),{remainingText:i,attachments:a}=ft(t);for(let t of a){if(this.fileReader)try{let n=await this.fileReader(e,t.path);if(n&&n.size>0){let e=t.path.toLowerCase();e.endsWith(`.png`)||e.endsWith(`.jpg`)||e.endsWith(`.jpeg`)||e.endsWith(`.gif`)||e.endsWith(`.webp`)?await this.sendPhoto(r,n,t.alt,t.path):await this.sendDocument(r,n,t.alt,t.path);continue}}catch(e){console.warn(`TelegramChannel: failed to read file ${t.path}:`,e)}await this.apiCall(`sendMessage`,{chat_id:r,text:`[${t.alt}] (file: ${t.path})`})}let o=i.trim();if(o){let e=lt(o,c);for(let t of e)await this.apiCall(`sendMessage`,{chat_id:r,text:t})}}async sendDocument(e,t,n,r){let i=r.split(`/`).pop()||`document.file`,a=new FormData;a.append(`chat_id`,e),a.append(`document`,t,i),n&&a.append(`caption`,n);let o=await fetch(this.buildMethodUrl(`sendDocument`),{method:`POST`,body:a});if(!o.ok){let e=await o.text();throw Error(`Telegram sendDocument failed: ${o.status} ${e}`)}}async sendPhoto(e,t,n,r){let i=r.split(`/`).pop()||`image.png`,a=new FormData;a.append(`chat_id`,e),a.append(`photo`,t,i),n&&a.append(`caption`,n);let o=await fetch(this.buildMethodUrl(`sendPhoto`),{method:`POST`,body:a});if(!o.ok){let e=await o.text();throw Error(`Telegram sendPhoto failed: ${o.status} ${e}`)}}async waitForRetry(e){await ut(e)}};function lt(e,t){if(e.length<=t)return[e];let n=[],r=e;for(;r.length>0;){if(r.length<=t){n.push(r);break}let e=t,i=r.lastIndexOf(`
2
- `,t);i>t*.5&&(e=i),n.push(r.slice(0,e)),r=r.slice(e)}return n}function ut(e){return new Promise(t=>setTimeout(t,e))}function dt(e){return e?.is_animated?`tgs`:e?.is_video?`webm`:`webp`}function ft(e){let t=[],n=/!?\[([^\]]*)\]\(([^)]+)\)/g,r,i=e;for(;(r=n.exec(e))!==null;){let e=r[1],n=pt((r[2]||``).trim());n&&(t.push({alt:e,path:n}),i=i.replace(r[0],``))}return{remainingText:i,attachments:t}}function pt(e){if(!e)return null;let t=e.trim();if(/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(t)||t.startsWith(`//`))return null;let n=t.replace(/\\/g,`/`).replace(/^\/+/,``).replace(/^\.\//,``);if(!n)return null;let r=n.split(`/`).filter(Boolean);return r.some(e=>e===`..`)?null:r.join(`/`)}function mt(e,t){let n=JSON.stringify(e.dataModel??{},null,2),r=t?`${t}`:`The user`;return`[A2UI ACTION]\nsurfaceId: "${e.surfaceId}"\nactionId: "${e.actionId}"\n`+(t?`firedBy: "${t}"\n`:``)+`dataModel:\n${n}\n\nInstructions: ${r} triggered the "${e.actionId}" action on surface "${e.surfaceId}". The dataModel above contains the current form values. Use the appropriate tool(s) to fulfill the action based on the actionId and dataModel values. After you have a result, call render_component with action "updateDataModel" on surfaceId "${e.surfaceId}" to update the surface (e.g. set path "/result" to the output value). Do NOT respond with plain text only — always update the surface via render_component.`}var ht=class{static formatMessagesXml(e){let t=e=>e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`);return`<messages>\n${e.map(e=>`<message sender="${t(e.sender)}" time="${new Date(e.timestamp).toISOString()}">${t(e.content)}</message>`).join(`
3
- `)}\n</messages>`}static formatOutbound(e){return e.replace(/<internal>[\s\S]*?<\/internal>/g,``).trim()}registry;constructor(e){this.registry=e}findChannel(e){return this.registry.find(e)}setTyping(e,t){this.findChannel(e)?.setTyping(e,t)}async send(e,t,n){let r=this.findChannel(e);if(!r){console.warn(`No channel for groupId: ${e}`);return}await r.send(e,t,n)}};const gt={"litert-community/gemma-4-E2B-it-litert-lm":`https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm/resolve/main/gemma-4-E2B-it-web.litertlm`,"litert-community/gemma-4-E4B-it-litert-lm":`https://huggingface.co/litert-community/gemma-4-E4B-it-litert-lm/resolve/main/gemma-4-E4B-it-web.litertlm`},_t=Object.keys(gt);function vt(){return typeof navigator<`u`&&`gpu`in navigator&&typeof WebAssembly<`u`&&`Suspending`in WebAssembly}let yt=null,bt=null,xt=null,St=null;const Ct=k;async function wt(e,t,n){return me(e,t,n,{cacheName:`shadow-claw-litertlm-models`,chunkSize:Ct})}async function Tt(e,t,n){if(bt===e&&yt)return yt;if(xt&&St===e)return xt;St=e,xt=(async()=>{if(yt){try{await yt.delete?.()}catch{}yt=null,bt=null}let r=gt[e];if(!r)throw Error(`LiteRT-LM: Model '${e} is not supported. Supported models: ${_t.join(`, `)}`);let i=await import(`./dist-DUy1CvmT.js`).catch(()=>{throw Error(`LiteRT-LM: The @litert-lm/core package is not installed. Run: npm install @litert-lm/core`)}),a=i.Engine??i.default?.Engine;if(typeof a?.create!=`function`)throw Error(`LiteRT-LM: Could not locate Engine.create in @litert-lm/core. Ensure you have the latest version installed.`);let o=await wt(r,t??(()=>{}),n),s=await a.create({model:o,mainExecutorSettings:{maxNumTokens:8192}});return yt=s,bt=e,s})();try{return await xt}finally{xt=null,St=null}}function Et(e){if(!e)return null;let t=e.match(/<\|tool_call>call:([A-Za-z0-9_]+)(\{[\s\S]*?)(?:<tool_call\|>|$)/);if(!t)return null;let n=t[1],r=t[2];r=r.replace(/<\|"\|>/g,`"`);function i(e){return e.replace(/([{,]\s*)([A-Za-z_$][A-Za-z0-9_$]*)(\s*:)/g,`$1"$2"$3`)}let a={},o=[r,i(r)];for(let e of o)try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){a=t;break}}catch{}if(Object.keys(a).length===0){let e=r.indexOf(`{`),t=r.lastIndexOf(`}`);if(e>=0&&t>e){let n=r.slice(e,t+1);for(let e of[n,i(n)])try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){a=t;break}}catch{}}}return{name:n,input:a}}function Dt(e){let t=W(String(e||``),`litert_lm`).trim();if(!t)return null;let n=e=>{try{let t=JSON.parse(e);if(t&&typeof t==`object`&&(t.type===`tool_use`||t.type===`response`))return t.tools_calls&&!t.tool_calls&&(t.tool_calls=t.tools_calls),{...t,format:`json`}}catch{}return null},r=n(t);if(r)return r;let i=t.indexOf(`{`),a=t.lastIndexOf(`}`);if(i>=0&&a>i&&(r=n(t.slice(i,a+1)),r))return r;if(t.includes(`"tool_use"`)){let e=/"name"\s*:\s*"([^"]+)"/.exec(t);if(e){let n={},r=/"input"\s*:\s*(\{.*?\})\s*(?:]|\}|"|$)/s.exec(t);if(r)try{n=JSON.parse(r[1])}catch{}return{type:`tool_use`,format:`json`,tool_calls:[{id:`litert_${Date.now()}`,name:e[1],input:n}]}}}let o=Et(t);return o?{type:`tool_use`,format:`model_specific`,tool_calls:[{id:`litert_${Date.now()}`,name:o.name,input:o.input}]}:null}function Ot(e,t,n){let r=[],i=e||``;if(n.length>0){let e=[``,`TOOL CALLING INSTRUCTIONS:`,`Return ONLY valid JSON (no markdown fences).`,`To call a tool: {"type":"tool_use","tool_calls":[{"name":"<tool>","input":{...}}]}`,`To reply: {"type":"response","response":"<your answer>"}`,`IMPORTANT: When you need to use a tool, output ONLY the JSON above — do NOT describe the call as text.`,``,`Available tools:`,n.map(e=>{let t=Object.keys(e.input_schema.properties||{}).join(`, `),n=e.description.split(`. `)[0];return`${e.name}(${t}): ${n}`}).join(`
4
- `)].join(`
5
- `);i=i?i+e:e}i&&r.push({role:`system`,content:i});let a=[];for(let e of t)if(e.role===`user`){let t=Array.isArray(e.content)?e.content.map(e=>e?.type===`text`?e.text:e?.type===`tool_result`?`[TOOL_RESULT ${e.tool_use_id}] ${String(e.content||``)}`:``).filter(Boolean).join(`
6
- `):String(e.content||``);t&&a.push(t)}else e.role;return{preface:r,turns:a}}async function kt(e,t,n,r,i,a,o,s,c,l){if(!vt()){await a({type:`response`,payload:{groupId:t,text:`⚠️ LiteRT-LM requires WebGPU and WebAssembly.Suspending. These are not both available in this browser.`}});return}await a(Te(t,`info`,`Starting`,`Provider: LiteRT-LM (Browser · WebGPU) · Model: ${s}`)),await a({type:`model-download-progress`,payload:{groupId:t,status:`running`,progress:0,message:`Loading LiteRT-LM model: ${s}…`}});let u=e=>(e/(1024*1024)).toFixed(0),d=-1,f=(e,n,r)=>{let i=n?e/n:null,o=i==null?-1:Math.floor(i*100);o===d&&!r||(d=o,a({type:`model-download-progress`,payload:{groupId:t,status:`running`,progress:i,message:r?`Loaded ${s} from cache (${u(e)} MB )`:n?`Downloading ${s}: ${u(e)} / ${u(n)} MB`:`Downloading ${s}: ${u(e)} MB`}}))},p;try{p=await Tt(s,f,o)}catch(e){if(o?.aborted||e?.name===`AbortError`){await a({type:`model-download-progress`,payload:{groupId:t,status:`error`,progress:null,message:`LiteRT-LM model download cancelled.`}});return}await a({type:`model-download-progress`,payload:{groupId:t,status:`error`,progress:null,message:`LiteRT-LM model failed to load: ${e?.message??String(e)}`}}),await a({type:`response`,payload:{groupId:t,text:`⚠️ LiteRT-LM failed to initialize: ${e?.message??String(e)}`}});return}await a({type:`model-download-progress`,payload:{groupId:t,status:`done`,progress:1,message:`LiteRT-LM model ready.`}});let m=c??[],{preface:h,turns:g}=Ot(n,r,m),_;try{_=await p.createConversation({preface:{messages:h}})}catch(e){await a({type:`response`,payload:{groupId:t,text:`⚠️ LiteRT-LM failed to create conversation: ${e?.message??String(e)}`}});return}let v=g.slice(0,-1),y=g[g.length-1]??`Hello.`;for(let e of v){if(o?.aborted)return;try{await _.sendMessage(e)}catch{}}if(o?.aborted)return;let b=y;for(let n=0;n<10;n++){if(o?.aborted)return;await a({type:`streaming-start`,payload:{groupId:t}});let n=``;try{let e=_.sendMessageStreaming(b);for await(let r of e){if(o?.aborted)break;let e=r?.content?.[0]?.text??``;if(e){let r=W(e,`litert_lm`);r&&(n+=r,await a({type:`streaming-chunk`,payload:{groupId:t,text:r}}))}}}catch(e){if(o?.aborted)return;await a({type:`response`,payload:{groupId:t,text:`⚠️ LiteRT-LM generation error: ${e?.message??String(e)}`}});return}let r=m.length>0?Dt(n):null;if(r?.type===`tool_use`){await a({type:`streaming-end`,payload:{groupId:t}});let n=Array.isArray(r.tool_calls)?r.tool_calls:[];if(n.length===0){await a({type:`streaming-done`,payload:{groupId:t,text:`(no response)`}}),await a({type:`response`,payload:{groupId:t,text:`(no response)`}});return}let i=[],o=r.format===`model_specific`;for(let r of n){await a(V(t,r.name,`running`)),be(e=>{a(e)});let n;try{n=await le(e,r.name,r.input||{},t,{allowedTools:m,invokeContext:l})}catch(e){n=`Error: ${e?.message??String(e)}`}finally{be(null)}await a(V(t,r.name,`done`));let s=typeof n==`string`?n:JSON.stringify(n);o?i.push(`<|tool_response>${s}<|tool_response|>`):i.push(`[TOOL_RESULT ${r.id??r.name}] ${s}`)}if(o)b=i.join(`
7
- `);else{let e=g[g.length-1]??``;b=[...i,``,`Based on the above tool results, please respond to the original request.`,e?`Original request: "${e}"`:``].filter(Boolean).join(`
8
- `)}continue}let i;i=r?.type===`response`&&r.response?W(r.response,`litert_lm`):W(n,`litert_lm`),await a({type:`streaming-done`,payload:{groupId:t,text:i}}),await a({type:`response`,payload:{groupId:t,text:i}});return}await a({type:`response`,payload:{groupId:t,text:`⚠️ LiteRT-LM reached the maximum number of tool-calling iterations without producing a final response.`}})}const At=new class{chunkCallbacks=new Map;loadRejects=new Map;loadResolves=new Map;pendingRejects=new Map;pendingResolves=new Map;progressCallbacks=new Map;thinkingCallbacks=new Map;worker=null;async generate(e,t,n,r,i,a){let o=this.getWorker();return new Promise((s,c)=>{this.pendingResolves.set(n,s),this.pendingRejects.set(n,c),this.chunkCallbacks.set(n,e=>r(e.text)),i&&this.thinkingCallbacks.set(n,i),o.postMessage({type:`generate`,payload:{messages:e,maxTokens:t,groupId:n,tools:a}})})}async load(e,t,n,r,i){let a=this.getWorker();return new Promise((o,s)=>{this.loadResolves.set(r,o),this.loadRejects.set(r,s),this.progressCallbacks.set(r,i),a.postMessage({type:`load`,payload:{modelId:e,device:t,dtypeStrategy:n,groupId:r}})})}cleanup(e){this.pendingResolves.delete(e),this.pendingRejects.delete(e),this.progressCallbacks.delete(e),this.chunkCallbacks.delete(e),this.thinkingCallbacks.delete(e)}getWorker(){return this.worker||(this.worker=new Worker(x(new URL(`./transformers-js.worker.js`,import.meta.url).href),{type:`module`}),this.worker.onmessage=e=>{let{type:t,payload:n}=e.data,r=n?.groupId;switch(t){case`progress`:this.progressCallbacks.get(r)?.(n),n.status===`done`&&(this.loadResolves.get(r)?.(),this.loadResolves.delete(r),this.loadRejects.delete(r));break;case`chunk`:this.chunkCallbacks.get(r)?.(n);break;case`thinking-chunk`:this.thinkingCallbacks.get(r)?.(n.text);break;case`done`:this.pendingResolves.get(r)?.(n.text),this.cleanup(r);break;case`error`:this.pendingRejects.get(r)?.(n.error),this.loadRejects.get(r)?.(n.error),this.cleanup(r),this.loadResolves.delete(r),this.loadRejects.delete(r);break}}),this.worker}};function jt(e){return typeof e?.content==`string`?e.content:Array.isArray(e?.content)?e.content.map(e=>e?.type===`text`?e.text||``:e?.type===`tool_use`?`[TOOL_CALL ${e.name}] ${JSON.stringify(e.input||{})}`:e?.type===`tool_result`?`[TOOL_RESULT ${e.tool_use_id}] ${String(e.content||``)}`:e?.type===`attachment`?`[ATTACHMENT ${e.mediaType}] ${e.fileName} (${e.mimeType})`:``).filter(Boolean).join(`
9
- `):``}function Mt(e){let t=W(String(e||``),`transformers_js`).trim();if(!t)return null;let n=t.match(/<tool_call>([\s\S]*?)<\/tool_call>/);if(n)try{let e=JSON.parse(n[1]);if(e.name)return{type:`tool_use`,tool_calls:[{name:e.name,input:e.arguments||e.parameters||{}}]}}catch{}try{return JSON.parse(t)}catch{let e=t.indexOf(`{`),n=t.lastIndexOf(`}`);if(e>=0&&n>e)try{return JSON.parse(t.slice(e,n+1))}catch{return null}return null}}async function Nt(e,t,n,r,i,a,o,s,c,l){let u=s||[],d=await b(e,m.TRANSFORMERS_JS_BACKEND)||`auto`,f=await b(e,m.TRANSFORMERS_JS_DTYPE_STRATEGY)||`auto`;await a(Te(t,`info`,`Starting`,`Provider: Transformers.js (Local Worker) · Model: ${c} · Backend: ${d} · Dtype: ${f}`)),await At.load(c,d,f,t,e=>{a({type:`model-download-progress`,payload:e})});let p=[...r];for(let r=0;r<10;r++){let r=[{role:`system`,content:n},...p.map(e=>({role:e.role===`assistant`?`assistant`:`user`,content:jt(e)}))];await a({type:`streaming-start`,payload:{groupId:t}});let o=``,s=``,c=await At.generate(r,i,t,e=>{s+=e,a({type:`streaming-chunk`,payload:{groupId:t,text:e}})},e=>{o+=e,a(Te(t,`text`,`Thinking`,o))},u);await a({type:`typing`,payload:{groupId:t}});let d=Mt(c);if(d?.type===`tool_use`?await a({type:`streaming-end`,payload:{groupId:t}}):await a({type:`streaming-done`,payload:{groupId:t,text:d?.response?W(d.response,`transformers_js`):W(c,`transformers_js`)}}),!d||d.type===`response`){await a({type:`response`,payload:{groupId:t,text:d?.response?W(d.response,`transformers_js`):W(c,`transformers_js`)}});return}let f=Array.isArray(d.tool_calls)?d.tool_calls:[];if(f.length===0){await a({type:`response`,payload:{groupId:t,text:W(d.response||c,`transformers_js`)}});return}let m=[];for(let n of f){await a(V(t,n.name,`running`)),be(e=>{a(e)});let r;try{r=await le(e,n.name,n.input||{},t,{allowedTools:u,invokeContext:l})}finally{be(null)}await a(V(t,n.name,`done`)),m.push({type:`tool_result`,tool_use_id:n.id||`call_${Date.now()}`,content:typeof r==`string`?r:JSON.stringify(r)})}p.push({role:`assistant`,content:[...d.response?[{type:`text`,text:d.response}]:[],...f.map(e=>({type:`tool_use`,id:e.id||`call_${Date.now()}_${Math.random()}`,name:e.name,input:e.input||{}}))]}),p.push({role:`user`,content:m})}}function Pt(e,t,n){let r=t.input_tokens||0,i=t.output_tokens||0,a=t.cache_read_input_tokens||0,o=t.cache_creation_input_tokens||0;return{type:`token-usage`,payload:{groupId:e,inputTokens:r,outputTokens:i,cacheReadTokens:a,cacheCreationTokens:o,totalTokens:r+i+a+o,contextLimit:n}}}function X(e,t,n,r){G(Te(e,t,n,r))}async function*Ft(e,t){let n=e.getReader(),r=new TextDecoder,i=``;try{for(;!t?.aborted;){let{done:e,value:t}=await n.read();if(e)break;i+=r.decode(t,{stream:!0});let a=i.split(`
10
-
11
- `);i=a.pop()||``;for(let e of a){let t=e.split(`
12
- `);for(let e of t)if(!(!e||e.startsWith(`:`))&&e.startsWith(`data: `)){let t=e.slice(6).trim();if(t===`[DONE]`)continue;try{yield JSON.parse(t)}catch{}}}}}finally{n.releaseLock()}}const It=6e4,Lt=new Map;function Rt(e){let t=Lt.get(e);if(t)return t;let n={recentCalls:[],nextAllowedAt:0,remoteLimit:null,remoteRemaining:null,remoteResetAt:null};return Lt.set(e,n),n}function Z(){return Date.now()}function zt(e){if(!e)return null;let t=Number(e.trim());return Number.isFinite(t)?t:null}function Bt(e){if(!e)return null;let t=e.trim(),n=Number(t);if(Number.isFinite(n))return n<=0?null:Math.round(n*1e3);let r=Date.parse(t);if(!Number.isFinite(r))return null;let i=r-Z();return i>0?i:null}function Vt(e){let t=zt(e);return t===null||t<=0?null:t>=0xe8d4a51000?Math.round(t):t>=1e9?Math.round(t*1e3):Z()+Math.round(t*1e3)}async function Ht(e,t){e<=0||await new Promise((n,r)=>{let i=setTimeout(()=>{o(),n()},e),a=()=>{o(),r(new DOMException(`Aborted`,`AbortError`))},o=()=>{i&&=(clearTimeout(i),null),t?.removeEventListener(`abort`,a)};if(t?.aborted){a();return}t?.addEventListener(`abort`,a)})}function Ut(e,t){if(!Number.isFinite(t)||t<=0)return 0;let n=Z();if(e.recentCalls=e.recentCalls.filter(e=>n-e<It),e.recentCalls.length<t)return 0;let r=e.recentCalls[0]||n;return Math.max(0,It-(n-r))}function Wt(e){let t=Z(),n=0;return e.nextAllowedAt>t&&(n=Math.max(n,e.nextAllowedAt-t)),e.remoteRemaining!==null&&e.remoteRemaining<=0&&e.remoteResetAt!==null&&e.remoteResetAt>t&&(n=Math.max(n,e.remoteResetAt-t)),n}async function Gt(e,t,n,r){let i=Rt(e);for(;;){let e=Ut(i,n.callsPerMinute),a=n.autoAdapt?Wt(i):0,o=Math.max(e,a);if(o<=0){let e=Z();if(n.callsPerMinute>0&&i.recentCalls.push(e),n.autoAdapt&&i.remoteRemaining!==null&&i.remoteRemaining>0&&i.remoteResetAt!==null&&i.remoteResetAt>e){let t=i.remoteResetAt-e,n=Math.max(1,i.remoteRemaining),r=Math.ceil(t/n);i.nextAllowedAt=Math.max(i.nextAllowedAt,e+r)}return}o>=1e3&&G({type:`thinking-log`,payload:{groupId:t,level:`info`,label:`Rate limiter`,message:`Waiting ${Math.ceil(o/1e3)}s before next provider call to avoid 429s.`,timestamp:Date.now()}}),await Ht(o,r)}}function Kt(e,t,n){if(!n.autoAdapt||!t||typeof t.get!=`function`)return;let r=Rt(e),i=Z(),a=zt(t.get(`x-ratelimit-limit`)),o=zt(t.get(`x-ratelimit-remaining`)),s=Vt(t.get(`x-ratelimit-reset`));a!==null&&(r.remoteLimit=Math.max(0,Math.floor(a))),o!==null&&(r.remoteRemaining=Math.max(0,Math.floor(o))),s!==null&&(r.remoteResetAt=s);let c=Bt(t.get(`retry-after`));c!==null&&(r.nextAllowedAt=Math.max(r.nextAllowedAt,i+c)),r.remoteRemaining!==null&&r.remoteRemaining<=0&&r.remoteResetAt!==null&&r.remoteResetAt>i&&(r.nextAllowedAt=Math.max(r.nextAllowedAt,r.remoteResetAt))}var qt=class{callbacks;contentBlocks=[];format;stopReason=`end_turn`;usage={input_tokens:0,output_tokens:0};#e=new Map;#t=``;#n=``;#r=new Map;constructor(e,t={}){this.format=e,this.callbacks=t}finalize(){return this.format===`openai`||this.format===`mesh-llm`?this.#a():this.#i()}push(e){this.format===`openai`||this.format===`mesh-llm`?this.#s(e):this.#o(e)}#i(){let e=[];for(let[,t]of[...this.#e.entries()].sort((e,t)=>e[0]-t[0]))if(t.type===`text`){let n=this.#c(t.text||``);n&&e.push({type:`text`,text:n})}else if(t.type===`tool_use`){let n;try{n=t.partialJson?JSON.parse(t.partialJson):{}}catch{n={}}e.push({type:`tool_use`,id:t.id||`call_${Date.now()}_${Math.random()}`,name:t.name,input:n})}else t.type===`thinking`?typeof t.text==`string`&&t.text.length>0&&e.push({type:`thinking`,thinking:t.text,...typeof t.id==`string`?{signature:t.id}:{}}):t.type===`redacted_thinking`&&typeof t.text==`string`&&t.text.length>0&&e.push({type:`redacted_thinking`,data:t.text});return{content:e,stop_reason:this.stopReason,usage:{...this.usage}}}#a(){let e=[];if(this.#n){let t=this.#c(this.#n);t&&e.push({type:`text`,text:t})}if(this.#t&&e.unshift({type:`thinking`,thinking:this.#t}),this.#r.size>0){this.stopReason=`tool_use`;for(let[,t]of[...this.#r.entries()].sort((e,t)=>e[0]-t[0])){let n;try{n=t.args?JSON.parse(t.args):{}}catch{n={}}e.push({type:`tool_use`,id:t.id||`call_${Date.now()}_${Math.random()}`,name:t.name,input:n})}}return{content:e,stop_reason:this.stopReason,usage:{...this.usage}}}#o(e){switch(e.type){case`message_start`:e.message?.usage&&(this.usage.input_tokens=e.message.usage.input_tokens||0,this.usage.cache_read_input_tokens=e.message.usage.cache_read_input_tokens||0,this.usage.cache_creation_input_tokens=e.message.usage.cache_creation_input_tokens||0);break;case`content_block_start`:{let t=e.index??this.#e.size,n=e.content_block||{};this.#e.set(t,{type:n.type||`text`,id:n.type===`thinking`?n.signature:n.id,name:n.name,text:n.text||n.thinking||n.data||``,partialJson:n.type===`tool_use`?``:void 0}),n.type===`tool_use`&&n.name&&this.callbacks.onToolStart?.(n.name);break}case`content_block_delta`:{let t=e.index??0,n=this.#e.get(t);if(!n){let r=e.delta?.type===`input_json_delta`?`tool_use`:`text`;n={type:r,text:r===`text`?``:void 0,partialJson:r===`tool_use`?``:void 0},this.#e.set(t,n)}let r=e.delta;if(!r)break;if(r.type===`text_delta`&&typeof r.text==`string`){let e=this.#c(r.text);if(!e)break;n.text=(n.text||``)+e,this.callbacks.onText?.(e)}r.type===`thinking_delta`&&typeof r.thinking==`string`&&(n.type=`thinking`,n.text=(n.text||``)+r.thinking,this.callbacks.onThinking?.(r.thinking)),r.type===`signature_delta`&&typeof r.signature==`string`&&(n.type=`thinking`,n.id=r.signature),r.type===`redacted_thinking_delta`&&typeof r.data==`string`&&(n.type=`redacted_thinking`,n.text=(n.text||``)+r.data),r.type===`input_json_delta`&&typeof r.partial_json==`string`&&(n.partialJson=(n.partialJson||``)+r.partial_json);break}case`content_block_stop`:break;case`message_delta`:e.delta?.stop_reason&&(this.stopReason=e.delta.stop_reason),e.usage&&(this.usage.output_tokens=e.usage.output_tokens||0,this.callbacks.onUsage?.(this.usage));break;case`message_stop`:break;default:break}}#s(e){e.usage&&(this.usage.input_tokens=e.usage.prompt_tokens||0,this.usage.output_tokens=e.usage.completion_tokens||0,this.usage.cache_read_input_tokens=e.usage.prompt_tokens_details?.cached_tokens||0,this.callbacks.onUsage?.(this.usage));let t=e.choices?.[0];if(!t)return;let n=t.delta;if(n){if(typeof n.content==`string`){let e=this.#c(n.content);e&&(this.#n+=e,this.callbacks.onText?.(e))}if(typeof n.reasoning==`string`)this.#t+=n.reasoning,this.callbacks.onThinking?.(n.reasoning);else if(n.reasoning&&typeof n.reasoning==`object`){let e=n.reasoning;typeof e.content==`string`?(this.#t+=e.content,this.callbacks.onThinking?.(e.content)):typeof e.text==`string`&&(this.#t+=e.text,this.callbacks.onThinking?.(e.text))}if(Array.isArray(n.tool_calls))for(let e of n.tool_calls){let t=e.index??0;this.#r.has(t)||(this.#r.set(t,{id:e.id||``,name:e.function?.name||``,args:``}),e.function?.name&&this.callbacks.onToolStart?.(e.function.name));let n=this.#r.get(t);n&&(e.id&&(n.id=e.id),e.function?.name&&(n.name=e.function.name),e.function?.arguments&&(n.args+=e.function.arguments))}t.finish_reason&&(t.finish_reason===`tool_calls`?this.stopReason=`tool_use`:t.finish_reason===`stop`?this.stopReason=`end_turn`:this.stopReason=t.finish_reason)}}#c(e){return W(e,this.callbacks.source??this.format)}};const Jt=new Map;function Yt(e){return Jt.get(e)}function Xt(e){Jt.delete(e)}function Zt(e,t){let n=e.trim().match(/^\[tool_code\]([\s\S]*?)\[\/tool_code\]$/i);if(!n?.[1])return{toolBlocks:[],residualText:e};let r=n[1].trim(),i=r.match(/^print\s*\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\s*(.*?)\s*\)\s*\)$/s),a=r.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(\s*(.*?)\s*\)$/s),o=i||a;if(!o?.[1])return{toolBlocks:[],residualText:e};let s=o[1];if(!t.has(s))return{toolBlocks:[],residualText:e};let c=(o[2]||``).trim(),l={};if(c){if(!c.startsWith(`{`)||!c.endsWith(`}`))return{toolBlocks:[],residualText:e};try{let t=JSON.parse(c);if(!t||typeof t!=`object`||Array.isArray(t))return{toolBlocks:[],residualText:e};l=t}catch{return{toolBlocks:[],residualText:e}}}return{toolBlocks:[{type:`tool_use`,id:`tool_code_${Date.now()}_${Math.random()}`,name:s,input:l}],residualText:``}}function Qt(e,t){if(!e||e.stop_reason===`tool_use`||!Array.isArray(e.content))return e;let n=new Set((t||[]).map(e=>typeof e?.name==`string`?e.name:``).filter(Boolean));if(n.size===0)return e;let r=[],i=!1;for(let t of e.content){if(t?.type!==`text`||typeof t.text!=`string`){r.push(t);continue}let e=Zt(t.text,n);if(e.toolBlocks.length>0){i=!0,e.residualText.trim()&&r.push({type:`text`,text:e.residualText}),r.push(...e.toolBlocks);continue}r.push(t)}return i?{...e,content:r,stop_reason:`tool_use`}:e}function $t(e){let t=e.filter(e=>e?.type===`tool_result`).map(e=>typeof e.content==`string`?e.content.trim():Array.isArray(e.content)?e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
13
- `).trim():JSON.stringify(e.content).trim()).filter(Boolean);return t.length===0?``:t.join(`
14
-
15
- `).slice(0,1e4)}function en(e){let t=e.trim();return t?`Tool result:\n${t}`:``}async function tn(e,t,n){let{apiKey:r,assistantName:i,contextCompression:a=!1,contextLimit:o,enabledTools:c,groupId:l,isScheduledTask:u=!1,maxIterations:d,maxTokens:f,memory:p,messages:m,model:h,provider:g,providerHeaders:_={},providerRuntimeOverrides:v,reasoning:y,rateLimitAutoAdapt:b=!0,rateLimitCallsPerMinute:x=0,storageHandle:S,streaming:C=!1,subagentModelSelectionMode:w,subagentMaxTokens:T,subagentPinnedModel:E,subagentPinnedProvider:D,systemPrompt:O,workspaceGroupId:k}=t,A=!!t.subagentTask,j=A?l.startsWith(`subagent:`)?l:`subagent:${J()}`:l,ne=k||l;A&&Ae(j,[]);let M={autoAdapt:b!==!1,callsPerMinute:Number.isFinite(x)?Math.max(0,Math.floor(x)):0};S&&se(S);let N=s(g);if(!N){G({payload:{groupId:j,error:`Unknown provider: ${g}`},type:`error`});return}let P=N,F=C&&P.supportsStreaming===!0&&P.format!==`prompt_api`;G({type:`typing`,payload:{groupId:j}}),X(j,`info`,`Starting`,`Provider: ${P.name} · Model: ${h} · Max tokens: ${f} · Streaming: ${F?`on`:`off`}${C&&!F?` (provider does not support streaming)`:``}`);try{let t=[...m],s=0,l=typeof d==`number`&&d>0?d:50,b=Array.isArray(c)?c:De,x=O,C=``,k={apiKey:r,assistantName:i??``,db:e,enabledTools:b,invokeSubagent:t=>an(e,t,n),maxTokens:f,memory:p??``,model:h,provider:g,subagentModelSelectionMode:w,subagentMaxTokens:T,subagentPinnedProvider:D,subagentPinnedModel:E,providerHeaders:_,providerRuntimeOverrides:v,storageHandle:S,streaming:!1,systemPrompt:x??``},A=[];for(;s<l;){s++;let c=Yt(j);c&&(b=c.enabledTools,x=te(i,p,b,c.systemPromptOverride));let l=o??H(h),d=oe(x),{messages:m,estimatedTokens:v}=ie(t,{contextLimit:l,maxOutputTokens:f,skimTop:a,systemPromptTokens:d}),S=v+d,w=Math.max(100,Math.min(f,l-S-500)),T=R(P,m,b,{contextCompression:a,maxTokens:w,model:h,reasoning:y,system:x});X(j,`api-call`,`API call #${s}`,`${m.length} messages in context`);let E={...ee(P,r),..._},D=P.baseUrl,O;O=F?await rn(g,P,D,E,T,j,h,M,n):await nn(g,P,D,E,T,j,M,n),O=Qt(O,b),O.usage&&G(Pt(j,O.usage,H(h)));for(let e of O.content)e.type===`text`&&e.text&&X(j,`text`,`Response text`,e.text.length>200?e.text.slice(0,200)+`…`:e.text);if(O.stop_reason===`tool_use`){let n=new Set(b.map(e=>typeof e?.name==`string`?e.name:``).filter(Boolean)),r=O.content.filter(e=>e.type===`text`).map(e=>e.text).join(``).replace(/<internal>[\s\S]*?<\/internal>/g,``).trim();r&&G({payload:{groupId:j,text:r},type:`intermediate-response`}),F&&G({payload:{groupId:j},type:`streaming-end`});let i=[];for(let t of O.content)if(t.type===`tool_use`){let r=n.has(t.name),a=`${t.name}:${JSON.stringify(t.input)}`,o=A.filter(e=>e===a).length;if(A.push(a),!r){let e=`SYSTEM ERROR: Tool '${t.name}' is disabled or unavailable for this request. Do not call it again. Try a different approach or ask the user for help.`;X(j,`warning`,`Tool blocked`,e),i.push({content:e,tool_use_id:t.id,type:`tool_result`});continue}let s=JSON.stringify(t.input),c=s.length>300?s.slice(0,300)+`…`:s;X(j,`tool-call`,`Tool: ${t.name}`,c),G(V(j,t.name,`running`));let l;o>=3?(l=`SYSTEM ERROR: You have repeatedly called this tool with the exact same input (${o+1} times). This is a rigid loop. STOP calling this tool with these arguments. Try a different approach, fix the underlying issue, or ask the user for help.`,console.warn(`[Worker] Blocked repetitive tool call:`,a)):l=await le(e,t.name,t.input,ne,{allowedTools:b,isScheduledTask:u,invokeContext:k});let d=typeof l==`string`?l:JSON.stringify(l),f=d.length>500?d.slice(0,500)+`…`:d;X(j,`tool-result`,`Result: ${t.name}`,f),G(V(j,t.name,`done`)),Array.isArray(l)?i.push({content:l,tool_use_id:t.id,type:`tool_result`}):i.push({content:typeof l==`string`?l.slice(0,1e5):JSON.stringify(l).slice(0,1e5),tool_use_id:t.id,type:`tool_result`})}C=$t(i),t.push({role:`assistant`,content:O.content}),t.push({role:`user`,content:i}),G({type:`typing`,payload:{groupId:j}})}else{let e=O.content.filter(e=>e.type===`text`).map(e=>e.text).join(``).replace(/<internal>[\s\S]*?<\/internal>/g,``).trim(),t=(e.toLowerCase()===`(no response)`?``:e)||(C?en(C):`(no response)`);F&&G({payload:{groupId:j,text:t},type:`streaming-done`}),G({payload:{groupId:j,text:t},type:`response`});return}}G({payload:{text:`⚠️ Reached maximum tool-use iterations (${l}). Stopping to avoid excessive API usage.`,groupId:j},type:`response`})}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;let t=e instanceof Error?e.message:String(e);F&&G({payload:{groupId:j,error:t},type:`streaming-error`}),G({type:`error`,payload:{groupId:j,error:t}})}finally{Xt(j),A&&Pe(j)}}async function nn(e,t,n,r,i,a,o,s){return M(async()=>{await Gt(e,a,o,s);let c=await fetch(n,{body:JSON.stringify(i),headers:r,method:`POST`,signal:s});if(Kt(e,c.headers,o),!c.ok){let e=await c.text(),n=Error(`${t.name} API error ${c.status}: ${e}`);throw n.status=c.status,n}return Me(t,await c.json())},{baseDelayMs:2e3,jitterFactor:.5,maxDelayMs:3e4,maxRetries:3,onRetry:(e,t,n,r)=>{let i=r instanceof Error?r.message:String(r);X(a,`warning`,`Retrying API call (${e}/${t})`,i),G({type:`show-toast`,payload:{message:`LLM API: Retrying (${e}/${t})… ${i.slice(0,120)}`,type:`warning`,duration:5e3}})},shouldRetry:e=>D(e),signal:s})}async function rn(e,t,n,r,i,a,o,s,c){let l={...i,stream:!0,...(t.format===`openai`||t.format===`mesh-llm`)&&{stream_options:{include_usage:!0}}};await Gt(e,a,s,c);let u=await fetch(n,{body:JSON.stringify(l),headers:r,method:`POST`,signal:c});if(Kt(e,u.headers,s),!u.ok){let e=await u.text(),n=Error(`${t.name} API error ${u.status}: ${e}`);throw n.status=u.status,n}if(!u.body)throw Error(`Streaming response has no body`);G({payload:{groupId:a},type:`streaming-start`});let d=0,f=``,p=0,m=``,h=(e=!1)=>{let t=Date.now();m&&(!e&&t-p<50||(X(a,`info`,`Reasoning`,m.length>400?`${m.slice(0,400)}…`:m),m=``,p=t))},g=new qt(t.format,{source:t.id,onText:e=>{let t=Date.now();f+=e,t-d>=50&&(G({payload:{groupId:a,text:f},type:`streaming-chunk`}),f=``,d=t)},onToolStart:e=>{G(V(a,e,`running`))},onUsage:e=>{G(Pt(a,e,H(o)))},onThinking:e=>{m+=e,h(!1)}});for await(let e of Ft(u.body,c))g.push(e);f&&G({payload:{groupId:a,text:f},type:`streaming-chunk`}),h(!0);let _=g.finalize();return t.format===`mesh-llm`&&(_=C(_)),_}async function an(e,t,n){let r=t.provider,i=async e=>{G(e)};if(r===`transformers_js_browser`){await Nt(e,t.groupId,t.systemPrompt,t.messages,t.maxTokens,i,n,t.enabledTools,t.model);return}if(r===`prompt_api`){if(!L())throw Error(`Prompt API provider is not supported in this environment.`);await ae(e,t.groupId,t.systemPrompt,t.messages,t.maxTokens,i,n,t.enabledTools);return}if(r===`litert_lm_browser`){if(!vt())throw Error(`Litert LM Browser provider is not supported in this environment.`);await kt(e,t.groupId,t.systemPrompt,t.messages,t.maxTokens,i,n,t.model,t.enabledTools);return}await tn(e,t,n)}async function on(e,t,n,r,i=!1,a=!1){let c=a?`subagent:${J()}`:n;if(e.inFlightTriggerByGroup.set(c,r),e.setState(`thinking`,c),e.router?.setTyping(c,!0),e.events.emit(`typing`,{groupId:c,typing:!0}),r.startsWith(`[SCHEDULED TASK]`)){e.pendingScheduledTasks.add(n);let i={id:J(),groupId:n,sender:`Scheduler`,content:r,timestamp:Date.now(),channel:Oe(e,n),isFromMe:!1,isTrigger:!0};await ue(t,i),e.events.emit(`message`,i)}let l=``;try{l=await ye(t,n,`MEMORY.md`)}catch{}let u=(await ze(t)).find(e=>e.groupId===n),d=u?.pinnedProvider??e.provider,f=u?.pinnedModel??(u?.pinnedProvider?s(u.pinnedProvider)?.defaultModel??e.model:e.model),p=typeof u?.pinnedMaxTokens==`number`&&Number.isFinite(u.pinnedMaxTokens)&&u.pinnedMaxTokens>0?Math.floor(u.pinnedMaxTokens):e.maxTokens,h=f;d===`prompt_api`&&(f===`browser-built-in`||!f)&&!L()&&(h=await b(t,m.PROMPT_API_FALLBACK_MODEL)||`onnx-community/Qwen3-0.6B-ONNX`);let g=Math.max(1,Math.min(p,o(h))),_=s(d)??e.providerConfig;e.inFlightEffectiveProviderByGroup.set(c,{providerId:d,providerConfig:_,model:f});let v=Array.isArray(u?.toolTags)?U.allTools.filter(e=>u.toolTags.includes(e.name)):U.enabledTools,y=(await ke(t,c)).tools.filter(e=>!U.allTools.some(t=>t.name===e.name)),x=Array.isArray(u?.toolTags)?y.filter(e=>u.toolTags.includes(e.name)):y.filter(e=>U.isDeclarativeToolEnabled(e.name)),S=[...v,...x],C=await F(t,c),w=C.skills.length>0&&!S.some(e=>e.name===We.name)?[...S,We]:S,T=u?.subagentModelSelectionMode===`manual`?`manual`:`automatic`,ee=u?.subagentMaxTokens,E=u?.subagentPinnedProvider,D=u?.subagentPinnedModel,k=u?.subagentFastProvider,A=u?.subagentFastModel,ne=u?.subagentSmartProvider,M=u?.subagentSmartModel,N=u?.subagentPowerfulProvider,P=u?.subagentPowerfulModel,I=u?.providerRuntimeOverrides,se=K.getPeerState(n)||void 0,R=te(e.assistantName,l,w,U.systemPromptOverride,se,C.skills),ce=H(h),le=oe(R)+(w?.reduce((e,t)=>e+oe(JSON.stringify(t)),0)??0),z=await Be(n,200);i&&(z=z.length>0?[z[z.length-1]]:[{role:`user`,content:r}]);let B=ie(z,{contextLimit:ce,systemPromptTokens:le,maxOutputTokens:g,skimTop:e.contextCompressionEnabled}),de=B.messages,fe=B.estimatedTokens+le;if(K.tokenUsage){let e=K.tokenUsage,t=(e.inputTokens||0)+(e.cacheReadTokens||0)+(e.outputTokens||0);fe=Math.max(fe,t)}if(e.events.emit(`context-usage`,{estimatedTokens:fe,contextLimit:ce,usagePercent:Math.min(100,Math.max(B.usagePercent,fe/ce*100)),truncatedCount:B.truncatedCount}),B.usagePercent>80&&B.truncatedCount>0&&z.length>10&&(e.events.emit(`show-toast`,{message:`Context ${B.usagePercent.toFixed(0)}% full — auto-compacting older messages…`,type:`info`,duration:4e3}),queueMicrotask(()=>je(e,t,n))),d===`transformers_js_browser`){let n=new AbortController;e.promptControllers.set(c,n);let r={apiKey:``,assistantName:e.assistantName,db:t,enabledTools:w,invokeSubagent:async e=>{await an(t,e,n.signal)},maxTokens:g,memory:l??``,model:f,provider:d,providerHeaders:_e(e,d,``,I),providerRuntimeOverrides:I,streaming:!1,subagentModelSelectionMode:T,subagentMaxTokens:ee,subagentPinnedProvider:E,subagentPinnedModel:D,subagentFastProvider:k,subagentFastModel:A,subagentSmartProvider:ne,subagentSmartModel:M,subagentPowerfulProvider:N,subagentPowerfulModel:P,systemPrompt:R};try{await Nt(t,c,R,de,g,async n=>{await re(e,t,n)},n.signal,w,f,r)}catch(n){if(n instanceof Error&&n.name===`AbortError`)return;await Re(e,t,c,`⚠️ Error: ${n instanceof Error?n.message:String(n)}`)}finally{e.promptControllers.delete(c)}return}if(d===`prompt_api`){if(L()||await j(),!L()){await Re(e,t,c,`⚠️ Error: Prompt API is not available in this browser. Switch provider or enable experimental browser flags.`);return}let n=new AbortController;e.promptControllers.set(c,n);let r={apiKey:``,assistantName:e.assistantName,db:t,enabledTools:w,invokeSubagent:async e=>{await an(t,e,n.signal)},maxTokens:g,memory:l??``,model:f,provider:d,providerHeaders:_e(e,d,``,I),providerRuntimeOverrides:I,streaming:!1,subagentModelSelectionMode:T,subagentMaxTokens:ee,subagentPinnedProvider:E,subagentPinnedModel:D,subagentFastProvider:k,subagentFastModel:A,subagentSmartProvider:ne,subagentSmartModel:M,subagentPowerfulProvider:N,subagentPowerfulModel:P,systemPrompt:R};try{await ae(t,c,R,de,g,async n=>{await re(e,t,n)},n.signal,w,r)}catch(n){if(n instanceof Error&&n.name===`AbortError`)return;await Re(e,t,c,`⚠️ Error: ${n instanceof Error?n.message:String(n)}`)}finally{e.promptControllers.delete(c)}return}if(d===`litert_lm_browser`){if(!vt()){await Re(e,t,c,`⚠️ LiteRT-LM requires WebGPU and WebAssembly.Suspending. These are not both available in this browser.`);return}let n=new AbortController;e.promptControllers.set(c,n);let r={apiKey:``,assistantName:e.assistantName,db:t,enabledTools:w,invokeSubagent:async e=>{await an(t,e,n.signal)},maxTokens:g,memory:l??``,model:f,provider:d,providerHeaders:_e(e,d,``,I),providerRuntimeOverrides:I,streaming:!1,subagentModelSelectionMode:T,subagentMaxTokens:ee,subagentPinnedProvider:E,subagentPinnedModel:D,subagentFastProvider:k,subagentFastModel:A,subagentSmartProvider:ne,subagentSmartModel:M,subagentPowerfulProvider:N,subagentPowerfulModel:P,systemPrompt:R};try{await kt(t,c,R,de,g,async n=>{await re(e,t,n)},n.signal,f,w,r)}catch(n){if(n instanceof Error&&n.name===`AbortError`)return;await Re(e,t,c,`⚠️ Error: ${n instanceof Error?n.message:String(n)}`)}finally{e.promptControllers.delete(c)}return}let pe=e.streamingEnabled&&_.supportsStreaming===!0&&(_.format===`openai`||_.format===`anthropic`);d===`transformers_js_local`&&xe(e,e.events,c);let me=e.createProviderRequestId(c);e.agentWorker?.postMessage({type:`invoke`,payload:{apiKey:d===e.provider?await O(e):await e.getApiKeyForSpecificProvider(t,d),assistantName:e.assistantName,contextCompression:e.contextCompressionEnabled,contextLimit:H(h),enabledTools:w,groupId:c,isScheduledTask:e.schedulerTriggeredGroups.has(n),maxIterations:e.maxIterations,maxTokens:g,memory:l,messages:de,model:f,provider:d,providerHeaders:_e(e,d,me,I),providerRuntimeOverrides:I,reasoning:he(e),rateLimitAutoAdapt:e.rateLimitAutoAdapt,rateLimitCallsPerMinute:e.rateLimitCallsPerMinute,storageHandle:await b(t,m.STORAGE_HANDLE),streaming:pe,subagentModelSelectionMode:T,subagentMaxTokens:ee,subagentPinnedProvider:E,subagentPinnedModel:D,subagentFastProvider:k,subagentFastModel:A,subagentSmartProvider:ne,subagentSmartModel:M,subagentPowerfulProvider:N,subagentPowerfulModel:P,systemPrompt:R,subagentTask:a}})}function sn(e,t,n){if(!e.enabledChannelTypes.includes(n.channel))return null;let r=n.content.trim(),i=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),a=r;if(e.requireMention){let e=RegExp(`^@${i}\\b\\s*(?:-|:)?\\s*`,`i`);if(!e.test(a))return null;a=a.replace(e,``).trim()}let o=a.match(/^\/([a-zA-Z0-9_]+)(?:\s+([\s\S]+))?$/);if(!o)return null;let s=o[1];if(!e.allowedTools.includes(s))return null;let c=(o[2]||``).trim();if(!c)return{toolName:s,input:{}};let l=c.startsWith(`'`)&&c.endsWith(`'`)||c.startsWith(`"`)&&c.endsWith(`"`)?c.slice(1,-1).trim():c;try{let e=JSON.parse(l);return e&&typeof e==`object`?{toolName:s,input:e}:null}catch{return null}}function cn(e,t){let n=e.trim().match(/^\/([a-z0-9](?:[a-z0-9]|-(?!-))*[a-z0-9]|[a-z0-9])(?:\s+([\s\S]+))?$/u);if(!n)return null;let r=t.find(e=>e.name===n[1]&&e.userInvocable!==!1);return r?{skill:r,arguments:(n[2]||``).trim()}:null}async function ln(e,t,n){if(n.a2uiEnvelopes&&n.a2uiEnvelopes.length>0)for(let t of n.a2uiEnvelopes)e.events.emit(`a2ui-surface`,{groupId:n.groupId,envelope:t});n.a2uiAction&&e.events.emit(`a2ui-action`,{groupId:n.groupId,action:n.a2uiAction});let r=!!n.content,i=(n.attachments?.length??0)>0;if(!r&&!i&&(n.a2uiEnvelopes?.length??0)>0)return;let a=sn(e.directToolCommandPolicy,e.assistantName,n),o=a?null:cn(n.content,(await F(t,n.groupId)).skills),s=n.channel===`browser`,c=e.channelRegistry.shouldAutoTrigger(n.groupId),l=!1;(n.channel===`browser`||n.groupId.startsWith(`room:`))&&(l=e.triggerPattern.test(n.content.trim())),o&&(l=!0),s&&n.groupId.startsWith(`peer:`)&&e.peerCompletedContexts.delete(n.groupId);let u=!!a;if(!l&&e.peerjsMyPeerId){if(n.content.includes(`@${e.peerjsMyPeerId}`))l=!0;else if(e.peerjsMyAlias&&n.content.includes(`@${e.peerjsMyAlias}`))l=!0;else for(let[t,r]of Object.entries(e.peerjsPeerAliases))if(r===e.peerjsMyPeerId&&n.content.includes(`@${t}`)){l=!0;break}}n.content.trim().startsWith(`[SCHEDULED TASK]`)&&(l=!0),n.content.trim().startsWith(`[A2UI ACTION]`)&&(l=!0);let d=!1;d=u||l?!0:s?!(n.groupId.startsWith(`peer:`)||n.groupId.startsWith(`room:`)):c,d&&!s&&!o&&n.groupId.startsWith(`peer:`)&&e.peerCompletedContexts.has(n.groupId)&&(d=!1);let f=await qe(t,n.groupId,n.attachments||[]),p={...n,attachments:f,isFromMe:!1,isTrigger:d};if(d&&!u&&!o?.skill.execution&&e.messageQueue.push(o?{...n,content:`[SKILL COMMAND] Activate the "${o.skill.name}" skill and follow its instructions.\n${o.arguments}`}:n),await ue(t,p),e.events.emit(`message`,p),o?.skill.execution&&e.agentWorker){let t=o.skill.execution.tools.map(e=>{let t=e.input&&typeof e.input==`object`?{...e.input}:{};return o.arguments&&Object.keys(t).length===0&&(t.rawInput=o.arguments),{...e,input:t}});e.agentWorker.postMessage({type:`execute-skill-tools`,payload:{groupId:n.groupId,skillName:o.skill.name,tools:t}});return}if(n.channel===`peerjs`&&Ee(n.groupId),s&&(n.groupId.startsWith(`peer:`)||n.groupId.startsWith(`room:`))&&e.router?.send(n.groupId,n.content,f).catch(e=>{console.error(`Failed to route browser message to peer:`,e)}),a&&e.agentWorker){e.agentWorker.postMessage({type:`execute-direct-tool`,payload:{groupId:n.groupId,name:a.toolName,input:a.input}});return}un(e,t)}async function un(e,t){if(e.processing||e.messageQueue.length===0)return;let n=e.messageQueue[0]?.groupId,r=e.providerConfig,i=e.provider;if(n)try{let e=(await ze(t)).find(e=>e.groupId===n);if(e?.pinnedProvider){let t=s(e.pinnedProvider);t&&(r=t,i=e.pinnedProvider)}}catch{}let a=r?.requiresApiKey!==!1,o=!0;if(a&&(o=i===e.provider?!!await O(e):!!await e.getApiKeyForSpecificProvider(t,i)),a&&!o){let t=`API key not configured. Go to Settings to add your API key.`;e.events.emit(`provider-help`,{providerId:i,reason:t,helpType:E(i,t,a)});let n=e.messageQueue.shift();e.events.emit(`error`,{groupId:n.groupId,error:t});return}e.processing=!0;let c=e.messageQueue.shift();try{await on(e,t,c.groupId,c.content,c.freshContext,c.subagent)}catch(e){console.error(`Failed to invoke agent:`,e)}finally{e.processing=!1,e.messageQueue.length>0&&un(e,t)}}var dn=class{listeners;constructor(){this.listeners=new Map}emit(e,t){this.listeners.get(e)?.forEach(e=>e(t))}off(e,t){this.listeners.get(e)?.delete(t)}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e)?.add(t)}};function Q(e,t){return{jsonrpc:`2.0`,method:e,params:t}}var fn=class{static isRoomMethod(e){return e===Y.JOIN||e===Y.ROSTER||e===Y.LEAVE||e===Y.MESSAGE||e===Y.INVITE||e===Y.RELAY||e===Y.A2UI||e===Y.A2UI_ACTION}roomsSignal=new S.State([]);_opts;_rooms=new Map;_seen=new Map;_surfaceOwners=new Map;constructor(e){this._opts=e}broadcast(e,t,n){let r=this._rooms.get(e);if(!r)return null;let i=this._opts.getLocalMember(),a=J(),o={roomId:e,messageId:a,senderPeerId:i.peerId,senderAlias:i.alias,text:t,attachments:n?.map(e=>({fileName:e.fileName,mimeType:e.mimeType,path:e.path,size:e.size}))};return this._markSeen(e,a),this._deliverToMembers(r,Q(Y.MESSAGE,o)),a}broadcastA2UI(e,t){let n=this._rooms.get(e);if(!n)return null;let r=this._myPeerId;this._surfaceOwners.set(t.surfaceId,r);let i=J(),a={roomId:e,broadcastId:i,ownerPeerId:r,senderPeerId:r,envelope:t};return this._markSeen(e,i),this._deliverToMembers(n,Q(Y.A2UI,a)),i}broadcastA2UIAction(e,t){let n=this._rooms.get(e);if(!n)return null;let r=this._opts.getLocalMember(),i=this._surfaceOwners.get(t.surfaceId)??``,a=J(),o={roomId:e,broadcastId:a,ownerPeerId:i,senderPeerId:r.peerId,senderAlias:r.alias,action:t};return this._markSeen(e,a),this._deliverToMembers(n,Q(Y.A2UI_ACTION,o)),a}createRoom(e){let t=this._opts.getLocalMember(),n={roomId:J(),name:e,hostPeerId:t.peerId,members:[t],createdAt:Date.now()};return this._save(n),n}get(e){return this._rooms.get(e)??null}getSurfaceOwner(e){return this._surfaceOwners.get(e)}handleNotification(e,t,n){switch(t){case Y.JOIN:this._onJoin(e,n);break;case Y.ROSTER:this._onRoster(n);break;case Y.LEAVE:this._onLeave(e,n);break;case Y.MESSAGE:this._onMessage(n);break;case Y.INVITE:this._opts.onInvite?.(n);break;case Y.RELAY:this._onRelay(n);break;case Y.A2UI:this._onA2UI(n);break;case Y.A2UI_ACTION:this._onA2UIAction(n);break}}invite(e,t){let n=this._rooms.get(e);if(!n)return!1;let r=this._opts.getLocalMember(),i={roomId:e,roomName:n.name,hostPeerId:n.hostPeerId,fromPeerId:r.peerId,fromAlias:r.alias},a=this._opts.transport;return a.connectToPeer(t),a.sendToPeer(t,Q(Y.INVITE,i))}isHost(e){let t=this._rooms.get(e);return!!t&&t.hostPeerId===this._myPeerId}joinRoom(e,t,n){let r=this._opts.getLocalMember(),i=this._rooms.get(e)??{roomId:e,name:n,hostPeerId:t,members:[{peerId:t,alias:t,kind:`agent`},r],createdAt:Date.now()};this._save(i);let a=this._opts.transport;a.connectToPeer(t);let o={roomId:e,member:r};return a.sendToPeer(t,Q(Y.JOIN,o)),i}leaveRoom(e){let t=this._rooms.get(e);if(!t)return;let n=this._myPeerId;if(t.hostPeerId===n){let r={roomId:e,peerId:n,disbanded:!0};this._deliverToMembers(t,Q(Y.LEAVE,r))}else{let r={roomId:e,peerId:n};this._opts.transport.sendToPeer(t.hostPeerId,Q(Y.LEAVE,r))}this._rooms.delete(e),this._seen.delete(e),this._opts.removeRoom?.(e),this._publish()}list(){return Array.from(this._rooms.values())}loadRooms(e){this._rooms.clear();for(let t of e)this._rooms.set(t.roomId,t);this._publish()}_broadcastRoster(e){let t={roomId:e.roomId,name:e.name,hostPeerId:e.hostPeerId,members:e.members};this._deliverToMembers(e,Q(Y.ROSTER,t))}_deliverToMembers(e,t){let n=this._myPeerId;for(let r of e.members)r.peerId!==n&&this._deliverToPeer(e,r.peerId,t)}_deliverToPeer(e,t,n){let r=this._opts.transport;if(r.isConnected(t)){r.sendToPeer(t,n);return}let i=this._myPeerId;if(e.hostPeerId!==i&&e.hostPeerId!==t&&r.isConnected(e.hostPeerId)){let i={roomId:e.roomId,targetPeerId:t,inner:n};r.sendToPeer(e.hostPeerId,Q(Y.RELAY,i)),r.connectToPeer(t);return}r.connectToPeer(t),r.sendToPeer(t,n)}_hasSeen(e,t){return this._seen.get(e)?.has(t)??!1}_markSeen(e,t){let n=this._seen.get(e);if(n||(n=new Set,this._seen.set(e,n)),n.add(t),n.size>500){let e=n.values().next().value;e!==void 0&&n.delete(e)}}get _myPeerId(){return this._opts.transport.myPeerId}_onA2UI(e){if(!e||typeof e.roomId!=`string`||typeof e.broadcastId!=`string`||!e.envelope||!this._rooms.get(e.roomId)||this._hasSeen(e.roomId,e.broadcastId))return;this._markSeen(e.roomId,e.broadcastId);let t=e.envelope.surfaceId;this._surfaceOwners.get(t)!==this._myPeerId&&this._surfaceOwners.set(t,e.ownerPeerId);let n={id:e.broadcastId,groupId:N(e.roomId),sender:e.senderPeerId,content:``,timestamp:Date.now(),channel:`room`,a2uiEnvelopes:[e.envelope]};this._opts.onMessage(n)}_onA2UIAction(e){if(!e||typeof e.roomId!=`string`||typeof e.broadcastId!=`string`||!e.action||!this._rooms.get(e.roomId)||this._hasSeen(e.roomId,e.broadcastId)||(this._markSeen(e.roomId,e.broadcastId),this._surfaceOwners.get(e.action.surfaceId)!==this._myPeerId))return;let t={id:e.broadcastId,groupId:N(e.roomId),sender:e.senderAlias||e.senderPeerId,content:mt(e.action,e.senderAlias),timestamp:Date.now(),channel:`room`,a2uiAction:e.action};this._opts.onMessage(t)}_onJoin(e,t){if(!t||typeof t.roomId!=`string`)return;let n=this._rooms.get(t.roomId);if(!n||n.hostPeerId!==this._myPeerId)return;let r=t.member??{peerId:e,alias:e,kind:`human`};r.peerId=e;let i=n.members.findIndex(t=>t.peerId===e);i>=0?n.members[i]=r:n.members.push(r),this._save(n),this._broadcastRoster(n)}_onLeave(e,t){if(!t||typeof t.roomId!=`string`)return;let n=this._rooms.get(t.roomId);if(n){if(t.disbanded){this._rooms.delete(t.roomId),this._seen.delete(t.roomId),this._opts.removeRoom?.(t.roomId),this._publish();return}n.hostPeerId===this._myPeerId&&(n.members=n.members.filter(n=>n.peerId!==(t.peerId||e)),this._save(n),this._broadcastRoster(n))}}_onMessage(e){if(!e||typeof e.roomId!=`string`||typeof e.messageId!=`string`||!this._rooms.get(e.roomId)||this._hasSeen(e.roomId,e.messageId))return;this._markSeen(e.roomId,e.messageId);let t={id:e.messageId,groupId:N(e.roomId),sender:e.senderAlias||e.senderPeerId,content:e.text??``,timestamp:Date.now(),channel:`room`,attachments:e.attachments?.map(e=>({fileName:e.fileName,mimeType:e.mimeType,path:e.path,size:e.size}))};this._opts.onMessage(t)}_onRelay(e){!e||typeof e.targetPeerId!=`string`||!e.inner||this.isHost(e.roomId)&&this._opts.transport.sendToPeer(e.targetPeerId,e.inner)}_onRoster(e){if(!e||typeof e.roomId!=`string`)return;let t=this._rooms.get(e.roomId),n={roomId:e.roomId,name:e.name??t?.name??e.roomId,hostPeerId:e.hostPeerId,members:Array.isArray(e.members)?e.members:[],createdAt:t?.createdAt??Date.now()};this._save(n)}_publish(){this.roomsSignal.set(this.list())}_save(e){this._rooms.set(e.roomId,e),this._opts.persistRoom?.(e),this._publish()}};function pn(){return new Promise(async(e,t)=>{try{let n=await v();if(!n)return t(Error(`failed to get transaction, cannot get enabled tasks.`));let r=n.transaction(`tasks`,`readonly`);if(!r)return t(Error(`failed to get transaction`));let i=r.objectStore(`tasks`).index(`by-enabled`).getAll(1);i.onsuccess=()=>{e(i.result.map(e=>({...e,enabled:!0})))},i.onerror=()=>t(i.error)}catch(e){t(e)}})}function mn(e,t){if(typeof e!=`string`||!e.trim())return!1;let n=e.trim().split(/\s+/);if(n.length!==5)return!1;let[r,i,a,o,s]=n;return hn(r,t.getMinutes())&&hn(i,t.getHours())&&hn(a,t.getDate())&&hn(o,t.getMonth()+1)&&hn(s,t.getDay())}function hn(e,t){return e===`*`||e.split(`,`).some(e=>{if(e.includes(`/`)){let[n,r]=e.split(`/`),i=parseInt(r,10);if(isNaN(i)||i<=0)return!1;if(n===`*`)return t%i===0;if(n.includes(`-`)){let[e,r]=n.split(`-`).map(Number);return t>=e&&t<=r&&(t-e)%i===0}let a=parseInt(n,10);return t>=a&&(t-a)%i===0}if(e.includes(`-`)){let[n,r]=e.split(`-`).map(Number);return t>=n&&t<=r}return parseInt(e,10)===t})}var gn=class{interval=null;onTaskChange;runner;constructor(e,t){this.runner=e,this.onTaskChange=t}ranThisMinute(e,t){if(!e.lastRun)return!1;let n=new Date(e.lastRun);return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()&&n.getHours()===t.getHours()&&n.getMinutes()===t.getMinutes()}start(){this.interval||(this.interval=setInterval(()=>this.tick(),t),this.tick())}stop(){this.interval&&=(clearInterval(this.interval),null)}async tick(){try{let e=await pn(),t=new Date;for(let n of e){let e=n.schedule||``;e!==``&&mn(e,t)&&!this.ranThisMinute(n,t)&&(await Ne(n.id,t.getTime()),this.onTaskChange?.(),this.runner(n).catch(e=>{console.error(`Task ${n.id} failed:`,e)}))}}catch(e){console.error(`Scheduler tick error:`,e)}}};function _n(e){if(!e)return[];try{let t=JSON.parse(e);if(Array.isArray(t))return T(t.map(e=>String(e)))}catch{}return T(e.split(`,`))}async function vn(e,t){e.channelEnabledByType.telegram=await Ce(`telegram`,t),e.channelEnabledByType.imessage=await Ce(`imessage`,t);let n=await e.loadSecretConfig(t,m.TELEGRAM_BOT_TOKEN),r=_n(await b(t,m.TELEGRAM_CHAT_IDS)),i=await b(t,m.TELEGRAM_USE_PROXY)===`true`;e.telegramBotToken=n,e.telegramChatIds=r,e.telegramUseProxy=i,e.telegram.configure(n,r,i);let a=async(e,n)=>{try{let r=await Se(t,e,n),i=new Uint8Array(r.byteLength);i.set(r);let a=Je(n.split(`/`).pop()||n);return new Blob([i],{type:a})}catch(e){return console.warn(`Orchestrator: channel fileReader failed for ${n}:`,e),null}};e.telegram.fileReader=a,e.imessage.fileReader=a;let o=(await b(t,m.IMESSAGE_SERVER_URL)||``).trim().replace(/\/+$/,``),s=await e.loadSecretConfig(t,m.IMESSAGE_API_KEY),c=_n(await b(t,m.IMESSAGE_CHAT_IDS));e.imessageServerUrl=o,e.imessageApiKey=s,e.imessageChatIds=c,e.imessage.configure(o,s,c),e.channelEnabledByType.peerjs=await Ce(`peerjs`,t);let l=(await b(t,m.PEERJS_MY_PEER_ID)||``).trim(),u=_n(await b(t,m.PEERJS_TRUSTED_PEER_IDS)),d=(await b(t,m.PEERJS_SERVER_HOST)||``).trim(),f=await b(t,m.PEERJS_SERVER_PORT),p=f&&parseInt(f,10)||0,h=(await b(t,m.PEERJS_SERVER_PATH)||``).trim(),g=await b(t,m.PEERJS_SERVER_SECURE)!==`false`,_={},v=await b(t,m.PEERJS_PEER_ALIASES);if(v)try{_=JSON.parse(v)}catch(e){console.warn(`Failed to parse peerjs_peer_aliases`,e)}e.peerjsMyPeerId=l,e.peerjsMyAlias=(await b(t,m.PEERJS_MY_ALIAS)||``).trim(),e.peerjsTrustedPeerIds=u,e.peerjsPeerAliases=_,e.peerjsServerHost=d,e.peerjsServerPort=p,e.peerjsServerPath=h,e.peerjsServerSecure=g;let y=d?{host:d,port:p||void 0,path:h||void 0,secure:g}:{};e.peerjs.configure(l,u,y)}const $={allowedTools:[`clear_chat`,`show_toast`],enabledChannelTypes:[`telegram`],requireMention:!0};function yn(e){if(!e)return{allowedTools:[...$.allowedTools],enabledChannelTypes:[...$.enabledChannelTypes],requireMention:$.requireMention};try{let t=JSON.parse(e),n=Array.isArray(t.enabledChannelTypes)?t.enabledChannelTypes.filter(e=>typeof e==`string`&&e.trim().length>0):$.enabledChannelTypes;return{allowedTools:Array.isArray(t.allowedTools)?t.allowedTools.filter(e=>typeof e==`string`&&e.trim().length>0):$.allowedTools,enabledChannelTypes:n,requireMention:typeof t.requireMention==`boolean`?t.requireMention:$.requireMention}}catch{return{allowedTools:[...$.allowedTools],enabledChannelTypes:[...$.enabledChannelTypes],requireMention:$.requireMention}}}function bn(e,t){typeof navigator>`u`||!navigator.serviceWorker||navigator.serviceWorker.addEventListener(`message`,t=>{if(t.data?.type===`request-proxy-config`){w(e);return}if(t.data?.type!==`scheduled-task-trigger`)return;let{taskId:n,groupId:r,prompt:i,taskType:a,tools:o}=t.data;r&&(e.schedulerTriggeredGroups.add(r),(async()=>{let t=K.tasks.find(e=>e.id===n);if(t){K.runTask(t);return}if(a===`tools`&&Array.isArray(o)&&o.length>0){K.runTask({id:n||`push-task-${Date.now()}`,groupId:r,createdAt:Date.now(),enabled:!0,prompt:i||``,type:`tools`,tools:o,lastRun:null});return}i&&z(e,i,r)})().catch(e=>console.error(`Push-triggered task ${n} failed:`,e)).finally(()=>{e.schedulerTriggeredGroups.delete(r)}))})}function xn(e){return new fn({transport:{get myPeerId(){return e.peerjs.myPeerId||e.peerjsMyPeerId},sendToPeer:(t,n)=>e.peerjs.sendRoomNotification(t,n),isConnected:t=>e.peerjs.isPeerConnected(t),connectToPeer:t=>e.peerjs.connectPeer(t)},getLocalMember:()=>({peerId:e.peerjs.myPeerId||e.peerjsMyPeerId,alias:e.peerjsMyAlias||e.peerjs.myPeerId||e.peerjsMyPeerId||e.assistantName,kind:`agent`,agentName:e.assistantName}),onMessage:t=>e.roomChannel.deliverInbound(t),onInvite:t=>ne(e,t),persistRoom:t=>{e.db&&ge(e.db,t).catch(e=>console.error(`Failed to persist room:`,e))},removeRoom:t=>{e.db&&P(e.db,t).catch(e=>console.error(`Failed to delete room:`,e))}})}async function Sn(e,t){e.initializeChannelRegistry(),e.channelRegistry.onMessage(n=>{ln(e,t,n).catch(e=>{console.error(`Failed to enqueue inbound message:`,e)})}),e.channelRegistry.onTyping((t,n)=>{e.events.emit(`typing`,{groupId:t,typing:n}),t.startsWith(`peer:`)&&K.setRemoteAgentTyping(t,n)}),e.peerjs.onTaskComplete(t=>{e.peerCompletedContexts.add(t)}),await vn(e,t),we(e);try{let n=await Ie(t);e.roomManager.loadRooms(n)}catch(e){console.error(`Failed to load rooms:`,e)}}async function Cn(e,t){e.assistantName=await b(t,m.ASSISTANT_NAME)||`ShadowClaw`,e.triggerPattern=n(e.assistantName)}async function wn(e,t){let n=await b(t,m.VM_BOOT_MODE);e.vmBootMode=n===`disabled`||n===`auto`||n===`9p`||n===`ext2`?n:`disabled`,e.streamingEnabled=await b(t,m.STREAMING_ENABLED)!==`false`,e.webMcpToolsEnabled=await b(t,m.WEBMCP_TOOLS_ENABLED)!==`false`,e.vmBashFullInternetAccess=await b(t,m.VM_BASH_FULL_INTERNET_ACCESS)===`true`;let r=await b(t,m.WEBMCP_MODE);(r===`native`||r===`polyfill`)&&Ve(r),e.contextCompressionEnabled=await b(t,m.CONTEXT_COMPRESSION_ENABLED)===`true`;let i=await b(t,m.REASONING_EFFORT);e.reasoningEffort=i?i.trim().toLowerCase():`none`,e.directToolCommandPolicy=yn(await b(t,m.DIRECT_TOOL_COMMAND_POLICY)),e.useProxy=await b(t,m.USE_PROXY)===`true`,e.proxyUrl=await b(t,m.PROXY_URL)||`/proxy`,e.gitProxyUrl=await b(t,m.GIT_PROXY_URL)||`/git-proxy`,e.taskServerEnabled=await b(t,m.TASK_SERVER_ENABLED)===`true`,e.taskServerUrl=await b(t,m.TASK_SERVER_URL)||(await import(`./config-AL77QAx4.js`).then(e=>e.O)).DEFAULT_TASK_SERVER_URL}async function Tn(e,t){let n=await b(t,m.LLAMAFILE_MODE);n===`cli`||n===`server`?e.llamafileMode=n:await q(t,m.LLAMAFILE_MODE,e.llamafileMode);let r=await b(t,m.LLAMAFILE_HOST);r&&(e.llamafileHost=r);let i=await b(t,m.LLAMAFILE_PORT);if(i){let t=parseInt(i,10);Number.isFinite(t)&&t>=1&&t<=65535&&(e.llamafilePort=t)}await b(t,m.LLAMAFILE_OFFLINE)===`false`&&(e.llamafileOffline=!1),fe(e);let a=await b(t,m.MESH_LLM_HOST);a&&(e.meshLlmHost=a),A(e)}async function En(e,t){let[n,r,i,c,l,u,f,p,h]=await Promise.all([b(t,m.PROVIDER),b(t,m.BEDROCK_REGION_FALLBACK),b(t,m.BEDROCK_PROFILE_FALLBACK),b(t,m.BEDROCK_AUTH_MODE),b(t,m.MODEL),b(t,m.MAX_TOKENS),b(t,m.MAX_ITERATIONS),b(t,m.RATE_LIMIT_CALLS_PER_MINUTE),b(t,m.RATE_LIMIT_AUTO_ADAPT)]);n&&s(n)&&(e.provider=n,e.providerConfig=s(n)||d()),await e.loadApiKeyForProvider(t,e.provider),e.bedrockRegionFallback=(r||``).trim(),e.bedrockProfileFallback=(i||``).trim(),e.bedrockAuthMode=(c||`provider_chain`).trim();let g=()=>{let t=()=>{pe(e).then(t=>a.fetchModelInfo(e.providerConfig,t||void 0,_e(e,e.provider)))};typeof globalThis.requestIdleCallback==`function`?globalThis.requestIdleCallback(t,{timeout:5e3}):setTimeout(t,2e3)};typeof window<`u`&&typeof document<`u`?document.readyState===`complete`?g():window.addEventListener(`load`,g,{once:!0}):g(),l?e.model=l:e.model=e.providerConfig.defaultModel;let _=e.model;e.provider===`prompt_api`&&!L()&&(e.model===`browser-built-in`||!e.model)&&(_=await b(t,m.PROMPT_API_FALLBACK_MODEL)||`onnx-community/Qwen3-0.6B-ONNX`,de(_).catch(()=>{}));let v=o(_);if(u===`8192`||e.provider===`prompt_api`&&!L()&&u===`4096`?e.maxTokens=v:e.maxTokens=Math.max(1,parseInt(u||String(v),10)),f&&(e.maxIterations=parseInt(f,10)||50),p){let t=parseInt(p,10);e.rateLimitCallsPerMinute=Number.isFinite(t)?Math.max(0,t):0}e.rateLimitAutoAdapt=h!==`false`}async function Dn(e,t){e.agentWorker=new Worker(x(new URL(`./agent.worker.js`,import.meta.url).href),{type:`module`}),e.agentWorker.onmessage=n=>re(e,t,n.data),e.agentWorker.onerror=e=>{console.error(`Agent worker error:`,e)};let n=await b(t,m.STORAGE_HANDLE);n&&e.agentWorker.postMessage({payload:{storageHandle:n},type:`set-storage`}),w(e),e.scheduler=new gn(async t=>{await I(e,t)},()=>{e.events.emit(`task-change`,{type:`executed`})}),ce().then(t=>{t&&e.scheduler?.start()}),bn(e,t)}var On=class{agentWorker=null;assistantName=g;bedrockAuthMode=`provider_chain`;bedrockProfileFallback=``;bedrockRegionFallback=``;browserChat=new Qe;channelEnabledByType={browser:!0,peerjs:!1,telegram:!1,imessage:!1};channelRegistry=new $e;contextCompressionEnabled=!1;db=null;directToolCommandPolicy={...$};events=new dn;gitProxyUrl=`/git-proxy`;imessage=new et;imessageApiKey=``;imessageChatIds=[];imessageServerUrl=``;inFlightEffectiveProviderByGroup=new Map;inFlightProviderRequestIds=new Map;inFlightTriggerByGroup=new Map;llamafileHost=`127.0.0.1`;llamafileMode=`cli`;llamafileOffline=!0;llamafilePort=8080;maxIterations=50;maxTokens=h;meshLlmHost=``;messageQueue=[];model=d().defaultModel;peerCompletedContexts=new Set;peerjs=new Ye;peerjsMyAlias=``;peerjsMyPeerId=``;peerjsPeerAliases={};peerjsServerHost=``;peerjsServerPath=``;peerjsServerPort=0;peerjsServerSecure=!0;peerjsTrustedPeerIds=[];pendingScheduledTasks=new Set;processing=!1;promptControllers=new Map;provider=f;providerConfig=d();proxyUrl=`/proxy`;pushSubscriptionWarned=!1;rateLimitAutoAdapt=!0;rateLimitCallsPerMinute=0;reasoningEffort=`none`;roomChannel=new ot;roomManager;router=null;scheduler=null;schedulerTriggeredGroups=new Set;state=`idle`;streamingEnabled=!0;taskServerEnabled=!1;taskServerUrl=`/schedule`;telegram=new ct;telegramBotToken=``;telegramChatIds=[];telegramUseProxy=!1;transformersProgressPollers=new Map;triggerPattern=n(g);useProxy=!1;vmBashFullInternetAccess=!1;vmBootMode=`disabled`;vmStatus={ready:!1,booting:!1,bootAttempted:!1,error:null};webMcpEffectCleanup=null;webMcpRegistrationLock=Promise.resolve();webMcpToolsEnabled=!0;#e=null;#t=null;constructor(){this.roomManager=xn(this),this.initializeChannelRegistry()}clearProviderRequest(e){this.inFlightProviderRequestIds.delete(e)}createProviderRequestId(e){if(this.provider!==`llamafile`)return this.inFlightProviderRequestIds.delete(e),``;let t=`${e}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2,10)}`;return this.inFlightProviderRequestIds.set(e,t),t}initializeChannelRegistry(){this.channelRegistry=new $e,this.channelRegistry.register(`br:`,this.browserChat,{badge:`Browser`,autoTrigger:!0}),this.channelRegistry.register(`tg:`,this.telegram,{badge:`Telegram`,autoTrigger:!1}),this.channelRegistry.register(`im:`,this.imessage,{badge:`iMessage`,autoTrigger:!0}),this.channelRegistry.register(`peer:`,this.peerjs,{badge:`PeerJS`,autoTrigger:!1}),this.channelRegistry.register(`room:`,this.roomChannel,{badge:`Room`,autoTrigger:!1}),this.roomChannel.setManager(this.roomManager),this.peerjs.setRoomNotificationHandler((e,t,n)=>this.roomManager.handleNotification(e,t,n)),this.router=new ht(this.channelRegistry)}setState(e,t){this.state=e,this.events.emit(`state-change`,{state:e,groupId:t})}shutdown(){this.channelRegistry.stopAll(),this.scheduler?.stop();for(let e of this.transformersProgressPollers.keys())Fe(this,e);this.agentWorker?.terminate(),typeof this.webMcpEffectCleanup==`function`&&this.webMcpEffectCleanup(),He()}stopCurrentRequest(e=p){if(this.state!==`thinking`&&this.state!==`responding`)return;Fe(this,e);let t=this.inFlightProviderRequestIds.get(e)||``;this.clearProviderRequest(e),this.agentWorker?.postMessage({type:`cancel`,payload:{groupId:e}}),this.provider===`llamafile`&&t&&B(t);let n=this.promptControllers.get(e);n&&(n.abort(),this.promptControllers.delete(e)),this.inFlightTriggerByGroup.delete(e),this.inFlightEffectiveProviderByGroup.delete(e),this.events.emit(`typing`,{groupId:e,typing:!1}),this.router?.setTyping(e,!1),this.setState(`idle`,e)}async getApiKey(){if(!this.#t)return null;let e=Date.now();if(this.#e&&this.#e.expiresAt>e)return this.#e.value;try{let t=await Ge(this.#t);return t===null?null:(this.#e={expiresAt:e+3e4,value:t},t)}catch(e){return console.error(`[Orchestrator] Failed to decrypt API key:`,e),null}}async getApiKeyForSpecificProvider(e,t){let n=await b(e,i(t));if(!n&&t===`openrouter`){let t=await b(e,m.API_KEY);t&&(n=t)}if(!n)return``;try{return await Ge(n)||``}catch(e){return console.error(`[Orchestrator] Failed to decrypt API key:`,e),``}}async handleCompactDone(e,t,n){await Le(e,t),await ue(e,{channel:this.channelRegistry.getChannelType(t)??`browser`,content:`📝 **Context Compacted**\n\n${n}`,groupId:t,id:J(),isFromMe:!0,isTrigger:!1,sender:this.assistantName,timestamp:Date.now()}),this.events.emit(`context-compacted`,{groupId:t,summary:n}),this.events.emit(`typing`,{groupId:t,typing:!1}),this.setState(`idle`,t)}async init(){let e=await Ze();return this.db=e,await Promise.all([Cn(this,e),En(this,e),Tn(this,e),wn(this,e)]),await Dn(this,e),Sn(this,e).then(()=>{this.browserChat.onDisplay(()=>{})}),this.events.emit(`ready`,void 0),await U.load(e),Ue(this,e),e}async loadApiKeyForProvider(e,t){let n=await b(e,i(t));if(!n&&t===`openrouter`){let r=await b(e,m.API_KEY);r&&(n=r,await q(e,i(t),r))}if(!n)this.#t=``;else try{this.#t=n}catch(e){console.warn(`[Orchestrator] Failed to load API key:`,e),this.#t=``}this.#e=null}async loadSecretConfig(e,t){let n=await b(e,t);if(!n)return``;try{return await Ge(n)||``}catch{let r=await Ke(n);return r&&await q(e,t,r),n}}async newSession(e,t=p){await Le(e,t),this.events.emit(`session-reset`,{groupId:t})}async refreshContextUsage(e,t=p){let n=``;try{n=await ye(e,t,`MEMORY.md`)}catch{}let r=U.enabledTools,i=K.getPeerState(t)||void 0,a=te(this.assistantName,n,r,U.systemPromptOverride,i),c=(await ze(e)).find(e=>e.groupId===t),l=c?.pinnedModel??(c?.pinnedProvider?s(c.pinnedProvider)?.defaultModel??this.model:this.model),u=l;(c?.pinnedProvider??this.provider)===`prompt_api`&&(l===`browser-built-in`||!l)&&!L()&&(u=await b(this.db,m.PROMPT_API_FALLBACK_MODEL)||`onnx-community/Qwen3-0.6B-ONNX`);let d=typeof c?.pinnedMaxTokens==`number`&&Number.isFinite(c.pinnedMaxTokens)&&c.pinnedMaxTokens>0?Math.floor(c.pinnedMaxTokens):this.maxTokens,f=Math.max(1,Math.min(d,o(u))),h=H(u),g=oe(a)+(r?.reduce((e,t)=>e+oe(JSON.stringify(t)),0)??0),_=ie(await Be(t,200),{contextLimit:h,systemPromptTokens:g,maxOutputTokens:f,skimTop:this.contextCompressionEnabled}),v=_.estimatedTokens+g;if(K.tokenUsage){let e=K.tokenUsage,t=(e.inputTokens||0)+(e.cacheReadTokens||0)+(e.outputTokens||0);v=Math.max(v,t)}this.events.emit(`context-usage`,{estimatedTokens:v,contextLimit:h,usagePercent:Math.min(100,Math.max(_.usagePercent,v/h*100)),truncatedCount:_.truncatedCount})}async restartCurrentRequest(e=p){if(this.state!==`thinking`&&this.state!==`responding`||!this.db)return!1;let t=this.inFlightTriggerByGroup.get(e);return t?(this.stopCurrentRequest(e),await on(this,this.db,e,t),!0):!1}async routeRoomA2UIAction(e,t){let n=ve(e),r=this.peerjs.myPeerId||this.peerjsMyPeerId,i=this.roomManager.getSurfaceOwner(t.surfaceId);if(!i||i===r){if(!this.db)return;await ln(this,this.db,{id:J(),groupId:e,sender:this.peerjsMyAlias||r||`you`,content:mt(t),timestamp:Date.now(),channel:`room`,a2uiAction:t});return}this.roomManager.broadcastA2UIAction(n,t)}async saveSecretConfig(e,t,n){if(!n){await q(e,t,``);return}let r=await Ke(n);if(!r)throw Error(`Failed to encrypt secret config for ${t}`);await q(e,t,r)}async setApiKey(e,t){this.#t=await Ke(t),this.#e=null;let n=await Ke(t);if(!n)throw Error(`key failed to encrypt. config cannot set.`);await q(e,i(this.provider),n)}};export{On as Orchestrator};