@captain-app/openclaw 2026.2.4

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 (1686) hide show
  1. package/CHANGELOG.md +1528 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +539 -0
  5. package/assets/avatar-placeholder.svg +19 -0
  6. package/assets/chrome-extension/README.md +22 -0
  7. package/assets/chrome-extension/background.js +438 -0
  8. package/assets/chrome-extension/icons/icon128.png +0 -0
  9. package/assets/chrome-extension/icons/icon16.png +0 -0
  10. package/assets/chrome-extension/icons/icon32.png +0 -0
  11. package/assets/chrome-extension/icons/icon48.png +0 -0
  12. package/assets/chrome-extension/manifest.json +25 -0
  13. package/assets/chrome-extension/options.html +196 -0
  14. package/assets/chrome-extension/options.js +59 -0
  15. package/assets/dmg-background-small.png +0 -0
  16. package/assets/dmg-background.png +0 -0
  17. package/dist/accounts-ClnuDahN.js +250 -0
  18. package/dist/accounts-DzBgAM3C.js +251 -0
  19. package/dist/acp-cli-BEDDkzXH.js +926 -0
  20. package/dist/acp-cli-CwV4mdnW.js +923 -0
  21. package/dist/agent-CArjbSeE.js +695 -0
  22. package/dist/agent-CB7x5HLT.js +695 -0
  23. package/dist/agent-scope-BbT4OG2N.js +545 -0
  24. package/dist/agent-scope-C_O6Vpl0.js +545 -0
  25. package/dist/agent-scope-Csu2B6AM.js +606 -0
  26. package/dist/archive-CWrnG1CH.js +85 -0
  27. package/dist/archive-ccN9aDgq.js +85 -0
  28. package/dist/audit-DXPkQ275.js +1686 -0
  29. package/dist/audit-eH7nwgsM.js +1686 -0
  30. package/dist/auth-health-Bj7Gjbv0.js +149 -0
  31. package/dist/auth-health-CjjJhHey.js +149 -0
  32. package/dist/auth-nnRYiqpH.js +192 -0
  33. package/dist/auth-profiles-DVLfuixr.js +2954 -0
  34. package/dist/auth-y1BLPUhX.js +192 -0
  35. package/dist/boolean-Wzu0-e0P.js +30 -0
  36. package/dist/brew-Cqi8b49_.js +46 -0
  37. package/dist/brew-DyBGNK8A.js +46 -0
  38. package/dist/build-info.json +5 -0
  39. package/dist/call-B7EveN4V.js +252 -0
  40. package/dist/call-vuUQIjOj.js +252 -0
  41. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  42. package/dist/canvas-host/a2ui/a2ui.bundle.js +17780 -0
  43. package/dist/canvas-host/a2ui/index.html +307 -0
  44. package/dist/channel-options-CJfmOkol.js +32 -0
  45. package/dist/channel-options-lFguMTz1.js +62 -0
  46. package/dist/channel-selection-BmND9mWj.js +51 -0
  47. package/dist/channel-selection-cGhL9G0c.js +51 -0
  48. package/dist/channel-summary-B4G513Eb.js +1154 -0
  49. package/dist/channel-summary-MCwBCa5y.js +1154 -0
  50. package/dist/channels-cli-C2Of1mZG.js +1411 -0
  51. package/dist/channels-cli-DFynrP1H.js +1413 -0
  52. package/dist/channels-status-issues-YohTjZ-I.js +18 -0
  53. package/dist/channels-status-issues-ZcR1U-m5.js +18 -0
  54. package/dist/chrome-B3IuUad-.js +1953 -0
  55. package/dist/chrome-BZ9K48w9.js +1973 -0
  56. package/dist/clack-prompter-B9yLhyOm.js +92 -0
  57. package/dist/clack-prompter-BybM9xdL.js +92 -0
  58. package/dist/cli/daemon-cli.js +2 -0
  59. package/dist/cli-BJZdJwug.js +89 -0
  60. package/dist/cli-BQSoKu3d.js +86 -0
  61. package/dist/cli-utils-CO4jEMn0.js +43 -0
  62. package/dist/cli-utils-gtE-0a0D.js +43 -0
  63. package/dist/client-DPqNOpK3.js +1609 -0
  64. package/dist/client-DySXIFCA.js +1609 -0
  65. package/dist/command-format-CFzL448l.js +52 -0
  66. package/dist/command-format-DELazozB.js +52 -0
  67. package/dist/command-format-ayFsmwwz.js +38 -0
  68. package/dist/command-options-CsjxK4cZ.js +33 -0
  69. package/dist/commands-BRe9VTyU.js +229 -0
  70. package/dist/completion-cli-DlkjK0iC.js +390 -0
  71. package/dist/completion-cli-E6Pt41AL.js +387 -0
  72. package/dist/config-BtSTwPcH.js +4882 -0
  73. package/dist/config-DfMIMT-f.js +4881 -0
  74. package/dist/config-_d7_WcRv.js +5623 -0
  75. package/dist/config-guard-wSnm-U8a.js +5628 -0
  76. package/dist/configure-CPHAFKlg.js +895 -0
  77. package/dist/configure-DK1XgXYx.js +894 -0
  78. package/dist/constants-CNTiY-ZN.js +65 -0
  79. package/dist/constants-hpmbslG7.js +65 -0
  80. package/dist/control-service-CqX5g_ko.js +61 -0
  81. package/dist/control-service-o6xe3hEb.js +61 -0
  82. package/dist/control-ui/apple-touch-icon.png +0 -0
  83. package/dist/control-ui/assets/index-RwcW4Xl0.css +1 -0
  84. package/dist/control-ui/assets/index-ryaCcbyp.js +4584 -0
  85. package/dist/control-ui/assets/index-ryaCcbyp.js.map +1 -0
  86. package/dist/control-ui/favicon-32.png +0 -0
  87. package/dist/control-ui/favicon.ico +0 -0
  88. package/dist/control-ui/favicon.svg +22 -0
  89. package/dist/control-ui/index.html +17 -0
  90. package/dist/cron-cli-BoSaDgvH.js +453 -0
  91. package/dist/cron-cli-qVandvsD.js +456 -0
  92. package/dist/daemon-cli-C4gGWa15.js +760 -0
  93. package/dist/daemon-cli-DV_X0Krf.js +761 -0
  94. package/dist/daemon-runtime-D5hbSrdO.js +460 -0
  95. package/dist/daemon-runtime-DXUfrXBC.js +460 -0
  96. package/dist/deliver-BxK5nI2P.js +2587 -0
  97. package/dist/deliver-Dwzg9LUd.js +2557 -0
  98. package/dist/deliver-qpYZp20m.js +2587 -0
  99. package/dist/deps-CUXtMV9d.js +27 -0
  100. package/dist/deps-WBvZpFV_.js +27 -0
  101. package/dist/devices-cli-B2s18Qrh.js +207 -0
  102. package/dist/devices-cli-D1UEtMUJ.js +204 -0
  103. package/dist/directory-cli-BXQbrkfM.js +247 -0
  104. package/dist/directory-cli-CqA7tRbq.js +244 -0
  105. package/dist/dispatcher-Dyv7T-1r.js +160 -0
  106. package/dist/dns-cli-CWxKD22D.js +198 -0
  107. package/dist/dns-cli-CzKr_Fxj.js +201 -0
  108. package/dist/docs-cli-BNyxUbWr.js +159 -0
  109. package/dist/docs-cli-DYpTbo3i.js +161 -0
  110. package/dist/doctor-C8fDYZLq.js +2583 -0
  111. package/dist/doctor-hYcqp7c0.js +2585 -0
  112. package/dist/entry.js +1326 -0
  113. package/dist/env-l7QVNj6j.js +32 -0
  114. package/dist/errors-CMCg46fK.js +1952 -0
  115. package/dist/exec-B8JKbXKW.js +246 -0
  116. package/dist/exec-BMnoMcZW.js +1099 -0
  117. package/dist/exec-HEWTMJ7j.js +246 -0
  118. package/dist/exec-approvals-DtrnHx6M.js +1026 -0
  119. package/dist/exec-approvals-Y42bE8ud.js +1026 -0
  120. package/dist/exec-approvals-cli-CIedYxP3.js +385 -0
  121. package/dist/exec-approvals-cli-xpbxnj4O.js +388 -0
  122. package/dist/extensionAPI.js +66572 -0
  123. package/dist/format-Dzy9uRLE.js +34 -0
  124. package/dist/format-sj0fELBK.js +34 -0
  125. package/dist/gateway-cli-5A-KNLEC.js +16635 -0
  126. package/dist/gateway-cli-B8kS4chb.js +16637 -0
  127. package/dist/gateway-rpc-15n38Ize.js +28 -0
  128. package/dist/gateway-rpc-TMVRgGfj.js +28 -0
  129. package/dist/github-copilot-auth-DVZj4Zgh.js +1104 -0
  130. package/dist/github-copilot-auth-DeGYyLY9.js +1104 -0
  131. package/dist/github-copilot-token-B3SA95yo.js +103 -0
  132. package/dist/github-copilot-token-C8XFYz0i.js +103 -0
  133. package/dist/github-copilot-token-CnxakiSC.js +103 -0
  134. package/dist/gmail-setup-utils-CWPC386a.js +428 -0
  135. package/dist/gmail-setup-utils-eJVB5Ewp.js +428 -0
  136. package/dist/health-format-B0tMTk3C.js +1189 -0
  137. package/dist/health-format-DaURVaUn.js +1188 -0
  138. package/dist/help-format-CEsRHU2f.js +17 -0
  139. package/dist/help-format-GuCWws6r.js +17 -0
  140. package/dist/helpers-BEJ-phFf.js +25 -0
  141. package/dist/helpers-BtbBZVKZ.js +10 -0
  142. package/dist/helpers-C12w9zxf.js +10 -0
  143. package/dist/helpers-CzjGJZmJ.js +25 -0
  144. package/dist/hooks/bundled/boot-md/HOOK.md +19 -0
  145. package/dist/hooks/bundled/command-logger/HOOK.md +122 -0
  146. package/dist/hooks/bundled/session-memory/HOOK.md +109 -0
  147. package/dist/hooks/bundled/soul-evil/HOOK.md +71 -0
  148. package/dist/hooks-cli-BZCMAnW2.js +1058 -0
  149. package/dist/hooks-cli-D0CEFg3P.js +1061 -0
  150. package/dist/hooks-status-Bn7_O8PM.js +443 -0
  151. package/dist/hooks-status-BrWVfIn0.js +443 -0
  152. package/dist/image-BS022pvv.js +1421 -0
  153. package/dist/image-BzJtY34J.js +629 -0
  154. package/dist/image-CBqmIbQQ.js +629 -0
  155. package/dist/index.js +5809 -0
  156. package/dist/installs-BP4K5L33.js +388 -0
  157. package/dist/installs-DOpTt7VZ.js +388 -0
  158. package/dist/is-main-B4o72sqg.js +25 -0
  159. package/dist/is-main-PYGa3tDA.js +25 -0
  160. package/dist/links-B4nk2iDf.js +15 -0
  161. package/dist/links-DwjRqxgR.js +15 -0
  162. package/dist/loader-Cn4EV_pf.js +63690 -0
  163. package/dist/logging-CS3tbYDj.js +15 -0
  164. package/dist/logging-CY-Q5cwf.js +1 -0
  165. package/dist/logging-DhiLkhLw.js +15 -0
  166. package/dist/logging-pqyrk15z.js +1 -0
  167. package/dist/login-qr-CD164Aw1.js +478 -0
  168. package/dist/login-qr-D7Zdgji2.js +478 -0
  169. package/dist/login-qr-YgILJ4VC.js +475 -0
  170. package/dist/logs-cli-BdS0Uv0I.js +227 -0
  171. package/dist/logs-cli-CqSN1GzB.js +230 -0
  172. package/dist/manager-CfGY5zND.js +2870 -0
  173. package/dist/manager-CjuBqFRL.js +2870 -0
  174. package/dist/manager-CoBEAQKm.js +2872 -0
  175. package/dist/manifest-registry-Bwjq9Iev.js +668 -0
  176. package/dist/manifest-registry-D2Yntqcb.js +668 -0
  177. package/dist/message-channel-Cjsiqxok.js +105 -0
  178. package/dist/message-channel-D6v_oPAg.js +105 -0
  179. package/dist/model-selection-Cv5Ox_tY.js +2956 -0
  180. package/dist/model-selection-Dr-5U5-l.js +2708 -0
  181. package/dist/models-cli-B39ckynD.js +2541 -0
  182. package/dist/models-cli-DoiYsBYw.js +2544 -0
  183. package/dist/net-CFCxaipF.js +137 -0
  184. package/dist/net-DKJPqXuW.js +137 -0
  185. package/dist/node-cli-C_FYF-RA.js +1456 -0
  186. package/dist/node-cli-DWPoNsQS.js +1459 -0
  187. package/dist/node-service-DcJREOww.js +67 -0
  188. package/dist/node-service-DuZ9Us9h.js +67 -0
  189. package/dist/nodes-cli-Elo6tlen.js +1210 -0
  190. package/dist/nodes-cli-zqryRUWB.js +1207 -0
  191. package/dist/nodes-screen-C4aCrxie.js +157 -0
  192. package/dist/nodes-screen-D4PSynkR.js +157 -0
  193. package/dist/note-CQhSvgQv.js +73 -0
  194. package/dist/note-_C44YfAQ.js +73 -0
  195. package/dist/onboard-channels-CHBDi-ZA.js +670 -0
  196. package/dist/onboard-channels-DOEKyxaL.js +670 -0
  197. package/dist/onboard-skills-BUTXREDZ.js +3327 -0
  198. package/dist/onboard-skills-CSLYZmZA.js +3327 -0
  199. package/dist/onboarding-CgKb8b39.js +3232 -0
  200. package/dist/openclaw-root-9ILYSmJ9.js +84 -0
  201. package/dist/openclaw-root-Cvotktkd.js +84 -0
  202. package/dist/pairing-cli-B4UGR2at.js +114 -0
  203. package/dist/pairing-cli-BWDDl8cf.js +117 -0
  204. package/dist/pairing-labels-ClZ-fTWT.js +9 -0
  205. package/dist/pairing-labels-Ds7BPOkj.js +9 -0
  206. package/dist/pairing-store-DDLNuzmx.js +391 -0
  207. package/dist/pairing-store-DRn08lZD.js +391 -0
  208. package/dist/parse-87ybtYW1.js +23 -0
  209. package/dist/parse-OCFfznr3.js +23 -0
  210. package/dist/parse-log-line-C9aL5PUL.js +44 -0
  211. package/dist/parse-log-line-DxRaGzQb.js +44 -0
  212. package/dist/parse-timeout-CFqNj7No.js +16 -0
  213. package/dist/parse-timeout-DV8NQQWk.js +16 -0
  214. package/dist/path-env-C7kiJUgG.js +77 -0
  215. package/dist/path-env-DEj4CiFN.js +77 -0
  216. package/dist/paths-B-q1nXdY.js +43 -0
  217. package/dist/paths-B1kfl4h5.js +164 -0
  218. package/dist/paths-B4kigINg.js +40 -0
  219. package/dist/paths-CHGbP1-A.js +43 -0
  220. package/dist/paths-scjhy7N2.js +180 -0
  221. package/dist/pi-embedded-helpers-C19wUpMB.js +8451 -0
  222. package/dist/pi-embedded-helpers-CT5VuLCb.js +1293 -0
  223. package/dist/pi-embedded-helpers-Dl8e5Rf8.js +1293 -0
  224. package/dist/pi-model-discovery-B6CsmK6Y.js +20 -0
  225. package/dist/pi-model-discovery-DsRqYJLy.js +20 -0
  226. package/dist/pi-model-discovery-EhM2JAQo.js +20 -0
  227. package/dist/pi-tools.policy-BvkSDFDN.js +229 -0
  228. package/dist/plugin-auto-enable-Bd_StZzz.js +461 -0
  229. package/dist/plugin-auto-enable-DBhXb_0x.js +461 -0
  230. package/dist/plugin-sdk/agent-scope-DdwUKIOe.js +606 -0
  231. package/dist/plugin-sdk/chrome-G8apFa5p.js +1953 -0
  232. package/dist/plugin-sdk/command-format-qUVxzqYm.js +52 -0
  233. package/dist/plugin-sdk/config-Cm1M7tgH.js +5623 -0
  234. package/dist/plugin-sdk/deliver-Cl8uowiO.js +2557 -0
  235. package/dist/plugin-sdk/exec-Cm9b2r9Q.js +1107 -0
  236. package/dist/plugin-sdk/github-copilot-token-BHNcM4_B.js +103 -0
  237. package/dist/plugin-sdk/image-7PgoS2VD.js +1421 -0
  238. package/dist/plugin-sdk/index.d.ts +8908 -0
  239. package/dist/plugin-sdk/index.js +70888 -0
  240. package/dist/plugin-sdk/login-qr-qTALvWi2.js +475 -0
  241. package/dist/plugin-sdk/manager-Cs3EQZCb.js +2870 -0
  242. package/dist/plugin-sdk/model-selection-BgC1E1a7.js +2708 -0
  243. package/dist/plugin-sdk/paths-BYpoyRv5.js +164 -0
  244. package/dist/plugin-sdk/paths-DNQE-bvr.js +40 -0
  245. package/dist/plugin-sdk/pi-embedded-helpers-5jNqW_dE.js +8755 -0
  246. package/dist/plugin-sdk/pi-model-discovery-BUGEht9A.js +20 -0
  247. package/dist/plugin-sdk/pw-ai-COTtei4a.js +1649 -0
  248. package/dist/plugin-sdk/qmd-manager-ClSwiAJl.js +615 -0
  249. package/dist/plugin-sdk/redact-2AzjOfk2.js +94 -0
  250. package/dist/plugin-sdk/rolldown-runtime-Cbj13DAv.js +20 -0
  251. package/dist/plugin-sdk/sqlite-gCW7MlLs.js +215 -0
  252. package/dist/plugin-sdk/transcript-events-DGF257vD.js +17 -0
  253. package/dist/plugins-C3Bm-HQV.js +494 -0
  254. package/dist/plugins-QJjTXliB.js +495 -0
  255. package/dist/plugins-cli-DTci0JQb.js +443 -0
  256. package/dist/plugins-cli-wJsN1HHK.js +440 -0
  257. package/dist/ports-CiW9dmMq.js +96 -0
  258. package/dist/program-BWpTHh1I.js +188 -0
  259. package/dist/progress-Bcjniu7m.js +133 -0
  260. package/dist/progress-CvaSPjS9.js +133 -0
  261. package/dist/prompt-style-CFsleyxV.js +9 -0
  262. package/dist/prompt-style-DYJdrXyV.js +9 -0
  263. package/dist/prompts-Bt9fwsg2.js +10 -0
  264. package/dist/prompts-CudpZgTI.js +10 -0
  265. package/dist/pw-ai-08F3GD-3.js +1649 -0
  266. package/dist/pw-ai-ZmHxHQnx.js +1651 -0
  267. package/dist/pw-ai-tNPuRNn3.js +1649 -0
  268. package/dist/qmd-manager-2r-4n3sP.js +617 -0
  269. package/dist/qmd-manager-CF52nuBg.js +615 -0
  270. package/dist/qmd-manager-HEm5H2mk.js +616 -0
  271. package/dist/redact-BICFkpn7.js +97 -0
  272. package/dist/redact-BIMJ3ntQ.js +94 -0
  273. package/dist/redact-KzWHRS5J.js +97 -0
  274. package/dist/register.subclis-D2K25c84.js +348 -0
  275. package/dist/register.subclis-Dd8LbOLi.js +342 -0
  276. package/dist/reply-5UNWRwMn.js +63693 -0
  277. package/dist/restart-sentinel-Cr0vUxB8.js +65 -0
  278. package/dist/restart-sentinel-DUemCjgU.js +65 -0
  279. package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
  280. package/dist/routes-C6UpTPas.js +2410 -0
  281. package/dist/routes-ClNyEvlm.js +2410 -0
  282. package/dist/rpc-D0mf7DIw.js +95 -0
  283. package/dist/rpc-DYdOrgd9.js +95 -0
  284. package/dist/run-main-CojI7gWx.js +194 -0
  285. package/dist/runtime-guard-68M_evhb.js +60 -0
  286. package/dist/runtime-guard-DkjmhnBD.js +60 -0
  287. package/dist/sandbox-Ca81z3Tw.js +2924 -0
  288. package/dist/sandbox-cli-D75GApgp.js +459 -0
  289. package/dist/sandbox-cli-E4SJsC1C.js +462 -0
  290. package/dist/sandbox-knontqD9.js +2925 -0
  291. package/dist/security-cli-BLihvXO-.js +503 -0
  292. package/dist/security-cli-IGQCsK4g.js +506 -0
  293. package/dist/server-context-B9GX5GOI.js +740 -0
  294. package/dist/server-context-BFH7HB_M.js +740 -0
  295. package/dist/server-node-events-CTdHBiEA.js +218 -0
  296. package/dist/server-node-events-DAV14qPr.js +215 -0
  297. package/dist/service-BZNBq9hq.js +680 -0
  298. package/dist/service-C-BLXx9U.js +680 -0
  299. package/dist/service-audit-BfJv4NqZ.js +542 -0
  300. package/dist/service-audit-Bw3M2OEI.js +542 -0
  301. package/dist/shared-5SH-45AX.js +74 -0
  302. package/dist/shared-BxRm5uLU.js +74 -0
  303. package/dist/shared-C80Rmxsd.js +150 -0
  304. package/dist/shared-fGK6_D2v.js +150 -0
  305. package/dist/skills-Bhp0l6UK.js +693 -0
  306. package/dist/skills-Tky2kCMO.js +694 -0
  307. package/dist/skills-cli-6rCClAE4.js +287 -0
  308. package/dist/skills-cli-C4nLCrLw.js +290 -0
  309. package/dist/skills-status-CENcKr3I.js +187 -0
  310. package/dist/skills-status-DX1eUYvk.js +187 -0
  311. package/dist/sqlite-CmdZSZRx.js +197 -0
  312. package/dist/sqlite-Dnmf3LS7.js +215 -0
  313. package/dist/sqlite-QDf0yuU0.js +215 -0
  314. package/dist/status-BSfGAp2D.js +27 -0
  315. package/dist/status-Bp_2NMjt.js +27 -0
  316. package/dist/status-C0ANDr0T.js +3140 -0
  317. package/dist/status-CCHBIZnm.js +21 -0
  318. package/dist/status-Vuqbw2Bb.js +21 -0
  319. package/dist/status.update-BZW5r8Su.js +79 -0
  320. package/dist/status.update-BnD93_O8.js +79 -0
  321. package/dist/subsystem-CAq3uyo7.js +834 -0
  322. package/dist/system-cli-Bb9zmCO1.js +83 -0
  323. package/dist/system-cli-TIIQ04ls.js +80 -0
  324. package/dist/systemd-0Qa_nGqe.js +438 -0
  325. package/dist/systemd-Czb0Xsm7.js +438 -0
  326. package/dist/systemd-hints-CWoEOQRb.js +19 -0
  327. package/dist/systemd-hints-Cv3RN_mZ.js +19 -0
  328. package/dist/systemd-linger-CsdvcIoS.js +75 -0
  329. package/dist/systemd-linger-DKUFHcLn.js +75 -0
  330. package/dist/table-DNPESyNj.js +279 -0
  331. package/dist/table-DS4-gmkV.js +279 -0
  332. package/dist/tailnet-Bg_vE5qi.js +42 -0
  333. package/dist/tailnet-CrNWlQRJ.js +42 -0
  334. package/dist/tailscale-CBv58toW.js +252 -0
  335. package/dist/tailscale-DCnMs7_q.js +225 -0
  336. package/dist/tool-display-BEACy9rK.js +795 -0
  337. package/dist/tool-display-NYQnSpdo.js +795 -0
  338. package/dist/transcript-events-CsB1Saa6.js +17 -0
  339. package/dist/transcript-events-DDYvbmRV.js +17 -0
  340. package/dist/transcript-events-JLH5W4He.js +17 -0
  341. package/dist/tui--NY0rnjr.js +2542 -0
  342. package/dist/tui-DqJfGtvM.js +2543 -0
  343. package/dist/tui-cli-BuHNY6wF.js +54 -0
  344. package/dist/tui-cli-LMFV982e.js +57 -0
  345. package/dist/update-CRpHtCgz.js +317 -0
  346. package/dist/update-D3qruxhj.js +317 -0
  347. package/dist/update-cli-CFF-pslM.js +948 -0
  348. package/dist/update-cli-cn9pEMX7.js +951 -0
  349. package/dist/update-runner-CxGU142L.js +1221 -0
  350. package/dist/update-runner-DNobz_ft.js +1221 -0
  351. package/dist/utils-CKSrBNwq.js +192 -0
  352. package/dist/utils-DX85MiPR.js +188 -0
  353. package/dist/webhooks-cli-BGtt2HAR.js +312 -0
  354. package/dist/webhooks-cli-DHLZrEO_.js +309 -0
  355. package/dist/widearea-dns-BpG7ATO8.js +127 -0
  356. package/dist/widearea-dns-D4wkCJly.js +127 -0
  357. package/dist/ws-3zr8WUwL.js +13 -0
  358. package/dist/ws-log-BXcT2xQk.js +267 -0
  359. package/dist/ws-log-DbDIUsgz.js +267 -0
  360. package/dist/ws-lzrgabja.js +13 -0
  361. package/dist/wsl-D2O2qOrl.js +160 -0
  362. package/docs/.i18n/README.md +31 -0
  363. package/docs/.i18n/glossary.zh-CN.json +190 -0
  364. package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
  365. package/docs/CNAME +1 -0
  366. package/docs/_config.yml +53 -0
  367. package/docs/_layouts/default.html +145 -0
  368. package/docs/assets/markdown.css +179 -0
  369. package/docs/assets/openclaw-logo-text-dark.png +0 -0
  370. package/docs/assets/openclaw-logo-text.png +0 -0
  371. package/docs/assets/pixel-lobster.svg +60 -0
  372. package/docs/assets/showcase/agents-ui.jpg +0 -0
  373. package/docs/assets/showcase/bambu-cli.png +0 -0
  374. package/docs/assets/showcase/codexmonitor.png +0 -0
  375. package/docs/assets/showcase/gohome-grafana.png +0 -0
  376. package/docs/assets/showcase/ios-testflight.jpg +0 -0
  377. package/docs/assets/showcase/oura-health.png +0 -0
  378. package/docs/assets/showcase/padel-cli.svg +11 -0
  379. package/docs/assets/showcase/padel-screenshot.jpg +0 -0
  380. package/docs/assets/showcase/papla-tts.jpg +0 -0
  381. package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
  382. package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
  383. package/docs/assets/showcase/roborock-status.svg +13 -0
  384. package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
  385. package/docs/assets/showcase/snag.png +0 -0
  386. package/docs/assets/showcase/tesco-shop.jpg +0 -0
  387. package/docs/assets/showcase/wienerlinien.png +0 -0
  388. package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
  389. package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
  390. package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
  391. package/docs/assets/terminal.css +473 -0
  392. package/docs/assets/theme.js +55 -0
  393. package/docs/automation/auth-monitoring.md +44 -0
  394. package/docs/automation/cron-jobs.md +468 -0
  395. package/docs/automation/cron-vs-heartbeat.md +282 -0
  396. package/docs/automation/gmail-pubsub.md +256 -0
  397. package/docs/automation/poll.md +69 -0
  398. package/docs/automation/webhook.md +163 -0
  399. package/docs/bedrock.md +176 -0
  400. package/docs/brave-search.md +41 -0
  401. package/docs/broadcast-groups.md +442 -0
  402. package/docs/channels/bluebubbles.md +338 -0
  403. package/docs/channels/discord.md +475 -0
  404. package/docs/channels/feishu.md +507 -0
  405. package/docs/channels/googlechat.md +250 -0
  406. package/docs/channels/grammy.md +31 -0
  407. package/docs/channels/imessage.md +299 -0
  408. package/docs/channels/index.md +46 -0
  409. package/docs/channels/line.md +186 -0
  410. package/docs/channels/location.md +56 -0
  411. package/docs/channels/matrix.md +233 -0
  412. package/docs/channels/mattermost.md +138 -0
  413. package/docs/channels/msteams.md +768 -0
  414. package/docs/channels/nextcloud-talk.md +136 -0
  415. package/docs/channels/nostr.md +233 -0
  416. package/docs/channels/signal.md +202 -0
  417. package/docs/channels/slack.md +548 -0
  418. package/docs/channels/telegram.md +750 -0
  419. package/docs/channels/tlon.md +132 -0
  420. package/docs/channels/troubleshooting.md +29 -0
  421. package/docs/channels/twitch.md +379 -0
  422. package/docs/channels/whatsapp.md +404 -0
  423. package/docs/channels/zalo.md +189 -0
  424. package/docs/channels/zalouser.md +140 -0
  425. package/docs/cli/acp.md +170 -0
  426. package/docs/cli/agent.md +24 -0
  427. package/docs/cli/agents.md +75 -0
  428. package/docs/cli/approvals.md +50 -0
  429. package/docs/cli/browser.md +107 -0
  430. package/docs/cli/channels.md +79 -0
  431. package/docs/cli/config.md +50 -0
  432. package/docs/cli/configure.md +33 -0
  433. package/docs/cli/cron.md +42 -0
  434. package/docs/cli/dashboard.md +16 -0
  435. package/docs/cli/devices.md +67 -0
  436. package/docs/cli/directory.md +63 -0
  437. package/docs/cli/dns.md +23 -0
  438. package/docs/cli/docs.md +15 -0
  439. package/docs/cli/doctor.md +41 -0
  440. package/docs/cli/gateway.md +199 -0
  441. package/docs/cli/health.md +21 -0
  442. package/docs/cli/hooks.md +304 -0
  443. package/docs/cli/index.md +1029 -0
  444. package/docs/cli/logs.md +24 -0
  445. package/docs/cli/memory.md +45 -0
  446. package/docs/cli/message.md +239 -0
  447. package/docs/cli/models.md +79 -0
  448. package/docs/cli/node.md +112 -0
  449. package/docs/cli/nodes.md +73 -0
  450. package/docs/cli/onboard.md +29 -0
  451. package/docs/cli/pairing.md +21 -0
  452. package/docs/cli/plugins.md +62 -0
  453. package/docs/cli/reset.md +17 -0
  454. package/docs/cli/sandbox.md +152 -0
  455. package/docs/cli/security.md +26 -0
  456. package/docs/cli/sessions.md +16 -0
  457. package/docs/cli/setup.md +29 -0
  458. package/docs/cli/skills.md +26 -0
  459. package/docs/cli/status.md +26 -0
  460. package/docs/cli/system.md +60 -0
  461. package/docs/cli/tui.md +23 -0
  462. package/docs/cli/uninstall.md +17 -0
  463. package/docs/cli/update.md +98 -0
  464. package/docs/cli/voicecall.md +34 -0
  465. package/docs/cli/webhooks.md +25 -0
  466. package/docs/concepts/agent-loop.md +146 -0
  467. package/docs/concepts/agent-workspace.md +233 -0
  468. package/docs/concepts/agent.md +123 -0
  469. package/docs/concepts/architecture.md +129 -0
  470. package/docs/concepts/channel-routing.md +114 -0
  471. package/docs/concepts/compaction.md +61 -0
  472. package/docs/concepts/context.md +161 -0
  473. package/docs/concepts/group-messages.md +84 -0
  474. package/docs/concepts/groups.md +373 -0
  475. package/docs/concepts/markdown-formatting.md +130 -0
  476. package/docs/concepts/memory.md +546 -0
  477. package/docs/concepts/messages.md +154 -0
  478. package/docs/concepts/model-failover.md +149 -0
  479. package/docs/concepts/model-providers.md +316 -0
  480. package/docs/concepts/models.md +208 -0
  481. package/docs/concepts/multi-agent.md +376 -0
  482. package/docs/concepts/oauth.md +145 -0
  483. package/docs/concepts/presence.md +102 -0
  484. package/docs/concepts/queue.md +89 -0
  485. package/docs/concepts/retry.md +69 -0
  486. package/docs/concepts/session-pruning.md +122 -0
  487. package/docs/concepts/session-tool.md +193 -0
  488. package/docs/concepts/session.md +188 -0
  489. package/docs/concepts/sessions.md +10 -0
  490. package/docs/concepts/streaming.md +135 -0
  491. package/docs/concepts/system-prompt.md +115 -0
  492. package/docs/concepts/timezone.md +91 -0
  493. package/docs/concepts/typebox.md +289 -0
  494. package/docs/concepts/typing-indicators.md +68 -0
  495. package/docs/concepts/usage-tracking.md +35 -0
  496. package/docs/date-time.md +128 -0
  497. package/docs/debug/node-issue.md +83 -0
  498. package/docs/debugging.md +162 -0
  499. package/docs/diagnostics/flags.md +91 -0
  500. package/docs/docs.json +1587 -0
  501. package/docs/environment.md +81 -0
  502. package/docs/experiments/onboarding-config-protocol.md +40 -0
  503. package/docs/experiments/plans/cron-add-hardening.md +63 -0
  504. package/docs/experiments/plans/group-policy-hardening.md +40 -0
  505. package/docs/experiments/plans/openresponses-gateway.md +123 -0
  506. package/docs/experiments/proposals/model-config.md +36 -0
  507. package/docs/experiments/research/memory.md +228 -0
  508. package/docs/gateway/authentication.md +145 -0
  509. package/docs/gateway/background-process.md +93 -0
  510. package/docs/gateway/bonjour.md +167 -0
  511. package/docs/gateway/bridge-protocol.md +89 -0
  512. package/docs/gateway/cli-backends.md +223 -0
  513. package/docs/gateway/configuration-examples.md +606 -0
  514. package/docs/gateway/configuration.md +3393 -0
  515. package/docs/gateway/discovery.md +116 -0
  516. package/docs/gateway/doctor.md +282 -0
  517. package/docs/gateway/gateway-lock.md +34 -0
  518. package/docs/gateway/health.md +35 -0
  519. package/docs/gateway/heartbeat.md +302 -0
  520. package/docs/gateway/index.md +328 -0
  521. package/docs/gateway/local-models.md +150 -0
  522. package/docs/gateway/logging.md +113 -0
  523. package/docs/gateway/multiple-gateways.md +112 -0
  524. package/docs/gateway/openai-http-api.md +118 -0
  525. package/docs/gateway/openresponses-http-api.md +317 -0
  526. package/docs/gateway/pairing.md +99 -0
  527. package/docs/gateway/protocol.md +221 -0
  528. package/docs/gateway/remote-gateway-readme.md +157 -0
  529. package/docs/gateway/remote.md +127 -0
  530. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +128 -0
  531. package/docs/gateway/sandboxing.md +193 -0
  532. package/docs/gateway/security/formal-verification.md +164 -0
  533. package/docs/gateway/security/index.md +825 -0
  534. package/docs/gateway/tailscale.md +127 -0
  535. package/docs/gateway/tools-invoke-http-api.md +85 -0
  536. package/docs/gateway/troubleshooting.md +767 -0
  537. package/docs/help/faq.md +2830 -0
  538. package/docs/help/index.md +21 -0
  539. package/docs/help/troubleshooting.md +98 -0
  540. package/docs/hooks/soul-evil.md +69 -0
  541. package/docs/hooks.md +913 -0
  542. package/docs/images/feishu-step2-create-app.png +0 -0
  543. package/docs/images/feishu-step3-credentials.png +0 -0
  544. package/docs/images/feishu-step4-permissions.png +0 -0
  545. package/docs/images/feishu-step5-bot-capability.png +0 -0
  546. package/docs/images/feishu-step6-event-subscription.png +0 -0
  547. package/docs/images/groups-flow.svg +52 -0
  548. package/docs/images/mobile-ui-screenshot.png +0 -0
  549. package/docs/index.md +258 -0
  550. package/docs/install/ansible.md +208 -0
  551. package/docs/install/bun.md +59 -0
  552. package/docs/install/development-channels.md +75 -0
  553. package/docs/install/docker.md +567 -0
  554. package/docs/install/index.md +185 -0
  555. package/docs/install/installer.md +123 -0
  556. package/docs/install/migrating.md +192 -0
  557. package/docs/install/nix.md +96 -0
  558. package/docs/install/node.md +78 -0
  559. package/docs/install/uninstall.md +128 -0
  560. package/docs/install/updating.md +228 -0
  561. package/docs/logging.md +350 -0
  562. package/docs/multi-agent-sandbox-tools.md +395 -0
  563. package/docs/network.md +54 -0
  564. package/docs/nodes/audio.md +114 -0
  565. package/docs/nodes/camera.md +156 -0
  566. package/docs/nodes/images.md +72 -0
  567. package/docs/nodes/index.md +341 -0
  568. package/docs/nodes/location-command.md +113 -0
  569. package/docs/nodes/media-understanding.md +379 -0
  570. package/docs/nodes/talk.md +90 -0
  571. package/docs/nodes/voicewake.md +65 -0
  572. package/docs/northflank.mdx +53 -0
  573. package/docs/perplexity.md +80 -0
  574. package/docs/pi-dev.md +70 -0
  575. package/docs/pi.md +612 -0
  576. package/docs/platforms/android.md +148 -0
  577. package/docs/platforms/digitalocean.md +262 -0
  578. package/docs/platforms/exe-dev.md +125 -0
  579. package/docs/platforms/fly.md +486 -0
  580. package/docs/platforms/gcp.md +503 -0
  581. package/docs/platforms/hetzner.md +330 -0
  582. package/docs/platforms/index.md +53 -0
  583. package/docs/platforms/ios.md +107 -0
  584. package/docs/platforms/linux.md +94 -0
  585. package/docs/platforms/mac/bundled-gateway.md +73 -0
  586. package/docs/platforms/mac/canvas.md +125 -0
  587. package/docs/platforms/mac/child-process.md +69 -0
  588. package/docs/platforms/mac/dev-setup.md +102 -0
  589. package/docs/platforms/mac/health.md +34 -0
  590. package/docs/platforms/mac/icon.md +31 -0
  591. package/docs/platforms/mac/logging.md +57 -0
  592. package/docs/platforms/mac/menu-bar.md +81 -0
  593. package/docs/platforms/mac/peekaboo.md +65 -0
  594. package/docs/platforms/mac/permissions.md +44 -0
  595. package/docs/platforms/mac/release.md +85 -0
  596. package/docs/platforms/mac/remote.md +83 -0
  597. package/docs/platforms/mac/signing.md +47 -0
  598. package/docs/platforms/mac/skills.md +33 -0
  599. package/docs/platforms/mac/voice-overlay.md +60 -0
  600. package/docs/platforms/mac/voicewake.md +67 -0
  601. package/docs/platforms/mac/webchat.md +41 -0
  602. package/docs/platforms/mac/xpc.md +61 -0
  603. package/docs/platforms/macos-vm.md +281 -0
  604. package/docs/platforms/macos.md +203 -0
  605. package/docs/platforms/oracle.md +303 -0
  606. package/docs/platforms/raspberry-pi.md +358 -0
  607. package/docs/platforms/windows.md +159 -0
  608. package/docs/plugin.md +664 -0
  609. package/docs/plugins/agent-tools.md +99 -0
  610. package/docs/plugins/manifest.md +71 -0
  611. package/docs/plugins/voice-call.md +284 -0
  612. package/docs/plugins/zalouser.md +81 -0
  613. package/docs/prose.md +134 -0
  614. package/docs/providers/anthropic.md +152 -0
  615. package/docs/providers/claude-max-api-proxy.md +148 -0
  616. package/docs/providers/cloudflare-ai-gateway.md +71 -0
  617. package/docs/providers/deepgram.md +93 -0
  618. package/docs/providers/github-copilot.md +72 -0
  619. package/docs/providers/glm.md +33 -0
  620. package/docs/providers/index.md +63 -0
  621. package/docs/providers/minimax.md +208 -0
  622. package/docs/providers/models.md +51 -0
  623. package/docs/providers/moonshot.md +142 -0
  624. package/docs/providers/ollama.md +223 -0
  625. package/docs/providers/openai.md +62 -0
  626. package/docs/providers/opencode.md +36 -0
  627. package/docs/providers/openrouter.md +37 -0
  628. package/docs/providers/qwen.md +53 -0
  629. package/docs/providers/synthetic.md +99 -0
  630. package/docs/providers/venice.md +267 -0
  631. package/docs/providers/vercel-ai-gateway.md +50 -0
  632. package/docs/providers/xiaomi.md +64 -0
  633. package/docs/providers/zai.md +36 -0
  634. package/docs/railway.mdx +99 -0
  635. package/docs/refactor/clawnet.md +417 -0
  636. package/docs/refactor/exec-host.md +316 -0
  637. package/docs/refactor/outbound-session-mirroring.md +85 -0
  638. package/docs/refactor/plugin-sdk.md +214 -0
  639. package/docs/refactor/strict-config.md +93 -0
  640. package/docs/reference/AGENTS.default.md +124 -0
  641. package/docs/reference/RELEASING.md +120 -0
  642. package/docs/reference/api-usage-costs.md +137 -0
  643. package/docs/reference/device-models.md +47 -0
  644. package/docs/reference/rpc.md +43 -0
  645. package/docs/reference/session-management-compaction.md +285 -0
  646. package/docs/reference/templates/AGENTS.dev.md +83 -0
  647. package/docs/reference/templates/AGENTS.md +218 -0
  648. package/docs/reference/templates/BOOT.md +10 -0
  649. package/docs/reference/templates/BOOTSTRAP.md +61 -0
  650. package/docs/reference/templates/HEARTBEAT.md +11 -0
  651. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  652. package/docs/reference/templates/IDENTITY.md +27 -0
  653. package/docs/reference/templates/SOUL.dev.md +76 -0
  654. package/docs/reference/templates/SOUL.md +42 -0
  655. package/docs/reference/templates/TOOLS.dev.md +24 -0
  656. package/docs/reference/templates/TOOLS.md +46 -0
  657. package/docs/reference/templates/USER.dev.md +18 -0
  658. package/docs/reference/templates/USER.md +22 -0
  659. package/docs/reference/test.md +50 -0
  660. package/docs/reference/transcript-hygiene.md +129 -0
  661. package/docs/render.mdx +165 -0
  662. package/docs/scripts.md +28 -0
  663. package/docs/security/formal-verification.md +164 -0
  664. package/docs/start/getting-started.md +208 -0
  665. package/docs/start/hubs.md +185 -0
  666. package/docs/start/lore.md +219 -0
  667. package/docs/start/onboarding.md +110 -0
  668. package/docs/start/openclaw.md +241 -0
  669. package/docs/start/pairing.md +86 -0
  670. package/docs/start/setup.md +149 -0
  671. package/docs/start/showcase.md +416 -0
  672. package/docs/start/wizard.md +349 -0
  673. package/docs/testing.md +368 -0
  674. package/docs/token-use.md +112 -0
  675. package/docs/tools/agent-send.md +53 -0
  676. package/docs/tools/apply-patch.md +50 -0
  677. package/docs/tools/browser-linux-troubleshooting.md +139 -0
  678. package/docs/tools/browser-login.md +68 -0
  679. package/docs/tools/browser.md +576 -0
  680. package/docs/tools/chrome-extension.md +178 -0
  681. package/docs/tools/clawhub.md +257 -0
  682. package/docs/tools/creating-skills.md +54 -0
  683. package/docs/tools/elevated.md +57 -0
  684. package/docs/tools/exec-approvals.md +246 -0
  685. package/docs/tools/exec.md +179 -0
  686. package/docs/tools/firecrawl.md +61 -0
  687. package/docs/tools/index.md +509 -0
  688. package/docs/tools/llm-task.md +115 -0
  689. package/docs/tools/lobster.md +342 -0
  690. package/docs/tools/reactions.md +22 -0
  691. package/docs/tools/skills-config.md +76 -0
  692. package/docs/tools/skills.md +300 -0
  693. package/docs/tools/slash-commands.md +198 -0
  694. package/docs/tools/subagents.md +151 -0
  695. package/docs/tools/thinking.md +73 -0
  696. package/docs/tools/web.md +261 -0
  697. package/docs/tts.md +396 -0
  698. package/docs/tui.md +159 -0
  699. package/docs/vps.md +43 -0
  700. package/docs/web/control-ui.md +221 -0
  701. package/docs/web/dashboard.md +46 -0
  702. package/docs/web/index.md +116 -0
  703. package/docs/web/webchat.md +49 -0
  704. package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
  705. package/docs/whatsapp-openclaw.jpg +0 -0
  706. package/docs/zh-CN/AGENTS.md +59 -0
  707. package/docs/zh-CN/automation/auth-monitoring.md +47 -0
  708. package/docs/zh-CN/automation/cron-jobs.md +424 -0
  709. package/docs/zh-CN/automation/cron-vs-heartbeat.md +286 -0
  710. package/docs/zh-CN/automation/gmail-pubsub.md +249 -0
  711. package/docs/zh-CN/automation/poll.md +76 -0
  712. package/docs/zh-CN/automation/webhook.md +163 -0
  713. package/docs/zh-CN/bedrock.md +170 -0
  714. package/docs/zh-CN/brave-search.md +48 -0
  715. package/docs/zh-CN/broadcast-groups.md +449 -0
  716. package/docs/zh-CN/channels/bluebubbles.md +271 -0
  717. package/docs/zh-CN/channels/discord.md +468 -0
  718. package/docs/zh-CN/channels/feishu.md +513 -0
  719. package/docs/zh-CN/channels/googlechat.md +257 -0
  720. package/docs/zh-CN/channels/grammy.md +38 -0
  721. package/docs/zh-CN/channels/imessage.md +302 -0
  722. package/docs/zh-CN/channels/index.md +53 -0
  723. package/docs/zh-CN/channels/line.md +180 -0
  724. package/docs/zh-CN/channels/location.md +63 -0
  725. package/docs/zh-CN/channels/matrix.md +221 -0
  726. package/docs/zh-CN/channels/mattermost.md +144 -0
  727. package/docs/zh-CN/channels/msteams.md +775 -0
  728. package/docs/zh-CN/channels/nextcloud-talk.md +142 -0
  729. package/docs/zh-CN/channels/nostr.md +240 -0
  730. package/docs/zh-CN/channels/signal.md +209 -0
  731. package/docs/zh-CN/channels/slack.md +531 -0
  732. package/docs/zh-CN/channels/telegram.md +751 -0
  733. package/docs/zh-CN/channels/tlon.md +136 -0
  734. package/docs/zh-CN/channels/troubleshooting.md +36 -0
  735. package/docs/zh-CN/channels/twitch.md +385 -0
  736. package/docs/zh-CN/channels/whatsapp.md +411 -0
  737. package/docs/zh-CN/channels/zalo.md +196 -0
  738. package/docs/zh-CN/channels/zalouser.md +147 -0
  739. package/docs/zh-CN/cli/acp.md +173 -0
  740. package/docs/zh-CN/cli/agent.md +30 -0
  741. package/docs/zh-CN/cli/agents.md +82 -0
  742. package/docs/zh-CN/cli/approvals.md +57 -0
  743. package/docs/zh-CN/cli/browser.md +114 -0
  744. package/docs/zh-CN/cli/channels.md +86 -0
  745. package/docs/zh-CN/cli/config.md +57 -0
  746. package/docs/zh-CN/cli/configure.md +38 -0
  747. package/docs/zh-CN/cli/cron.md +43 -0
  748. package/docs/zh-CN/cli/dashboard.md +23 -0
  749. package/docs/zh-CN/cli/devices.md +74 -0
  750. package/docs/zh-CN/cli/directory.md +70 -0
  751. package/docs/zh-CN/cli/dns.md +30 -0
  752. package/docs/zh-CN/cli/docs.md +22 -0
  753. package/docs/zh-CN/cli/doctor.md +48 -0
  754. package/docs/zh-CN/cli/gateway.md +206 -0
  755. package/docs/zh-CN/cli/health.md +28 -0
  756. package/docs/zh-CN/cli/hooks.md +311 -0
  757. package/docs/zh-CN/cli/index.md +1032 -0
  758. package/docs/zh-CN/cli/logs.md +31 -0
  759. package/docs/zh-CN/cli/memory.md +52 -0
  760. package/docs/zh-CN/cli/message.md +246 -0
  761. package/docs/zh-CN/cli/models.md +85 -0
  762. package/docs/zh-CN/cli/node.md +115 -0
  763. package/docs/zh-CN/cli/nodes.md +80 -0
  764. package/docs/zh-CN/cli/onboard.md +36 -0
  765. package/docs/zh-CN/cli/pairing.md +28 -0
  766. package/docs/zh-CN/cli/plugins.md +66 -0
  767. package/docs/zh-CN/cli/reset.md +24 -0
  768. package/docs/zh-CN/cli/sandbox.md +158 -0
  769. package/docs/zh-CN/cli/security.md +33 -0
  770. package/docs/zh-CN/cli/sessions.md +23 -0
  771. package/docs/zh-CN/cli/setup.md +36 -0
  772. package/docs/zh-CN/cli/skills.md +33 -0
  773. package/docs/zh-CN/cli/status.md +33 -0
  774. package/docs/zh-CN/cli/system.md +63 -0
  775. package/docs/zh-CN/cli/tui.md +30 -0
  776. package/docs/zh-CN/cli/uninstall.md +24 -0
  777. package/docs/zh-CN/cli/update.md +101 -0
  778. package/docs/zh-CN/cli/voicecall.md +41 -0
  779. package/docs/zh-CN/cli/webhooks.md +32 -0
  780. package/docs/zh-CN/concepts/agent-loop.md +146 -0
  781. package/docs/zh-CN/concepts/agent-workspace.md +219 -0
  782. package/docs/zh-CN/concepts/agent.md +115 -0
  783. package/docs/zh-CN/concepts/architecture.md +123 -0
  784. package/docs/zh-CN/concepts/channel-routing.md +117 -0
  785. package/docs/zh-CN/concepts/compaction.md +67 -0
  786. package/docs/zh-CN/concepts/context.md +168 -0
  787. package/docs/zh-CN/concepts/group-messages.md +91 -0
  788. package/docs/zh-CN/concepts/groups.md +379 -0
  789. package/docs/zh-CN/concepts/markdown-formatting.md +117 -0
  790. package/docs/zh-CN/concepts/memory.md +412 -0
  791. package/docs/zh-CN/concepts/messages.md +141 -0
  792. package/docs/zh-CN/concepts/model-failover.md +145 -0
  793. package/docs/zh-CN/concepts/model-providers.md +320 -0
  794. package/docs/zh-CN/concepts/models.md +196 -0
  795. package/docs/zh-CN/concepts/multi-agent.md +372 -0
  796. package/docs/zh-CN/concepts/oauth.md +151 -0
  797. package/docs/zh-CN/concepts/presence.md +99 -0
  798. package/docs/zh-CN/concepts/queue.md +94 -0
  799. package/docs/zh-CN/concepts/retry.md +76 -0
  800. package/docs/zh-CN/concepts/session-pruning.md +129 -0
  801. package/docs/zh-CN/concepts/session-tool.md +200 -0
  802. package/docs/zh-CN/concepts/session.md +166 -0
  803. package/docs/zh-CN/concepts/sessions.md +17 -0
  804. package/docs/zh-CN/concepts/streaming.md +133 -0
  805. package/docs/zh-CN/concepts/system-prompt.md +101 -0
  806. package/docs/zh-CN/concepts/timezone.md +96 -0
  807. package/docs/zh-CN/concepts/typebox.md +284 -0
  808. package/docs/zh-CN/concepts/typing-indicators.md +74 -0
  809. package/docs/zh-CN/concepts/usage-tracking.md +42 -0
  810. package/docs/zh-CN/date-time.md +129 -0
  811. package/docs/zh-CN/debug/node-issue.md +90 -0
  812. package/docs/zh-CN/debugging.md +160 -0
  813. package/docs/zh-CN/diagnostics/flags.md +98 -0
  814. package/docs/zh-CN/environment.md +88 -0
  815. package/docs/zh-CN/experiments/onboarding-config-protocol.md +47 -0
  816. package/docs/zh-CN/experiments/plans/cron-add-hardening.md +70 -0
  817. package/docs/zh-CN/experiments/plans/group-policy-hardening.md +45 -0
  818. package/docs/zh-CN/experiments/plans/openresponses-gateway.md +121 -0
  819. package/docs/zh-CN/experiments/proposals/model-config.md +42 -0
  820. package/docs/zh-CN/experiments/research/memory.md +235 -0
  821. package/docs/zh-CN/gateway/authentication.md +142 -0
  822. package/docs/zh-CN/gateway/background-process.md +100 -0
  823. package/docs/zh-CN/gateway/bonjour.md +174 -0
  824. package/docs/zh-CN/gateway/bridge-protocol.md +86 -0
  825. package/docs/zh-CN/gateway/cli-backends.md +213 -0
  826. package/docs/zh-CN/gateway/configuration-examples.md +587 -0
  827. package/docs/zh-CN/gateway/configuration.md +3332 -0
  828. package/docs/zh-CN/gateway/discovery.md +123 -0
  829. package/docs/zh-CN/gateway/doctor.md +238 -0
  830. package/docs/zh-CN/gateway/gateway-lock.md +41 -0
  831. package/docs/zh-CN/gateway/health.md +42 -0
  832. package/docs/zh-CN/gateway/heartbeat.md +274 -0
  833. package/docs/zh-CN/gateway/index.md +335 -0
  834. package/docs/zh-CN/gateway/local-models.md +157 -0
  835. package/docs/zh-CN/gateway/logging.md +114 -0
  836. package/docs/zh-CN/gateway/multiple-gateways.md +119 -0
  837. package/docs/zh-CN/gateway/openai-http-api.md +125 -0
  838. package/docs/zh-CN/gateway/openresponses-http-api.md +317 -0
  839. package/docs/zh-CN/gateway/pairing.md +99 -0
  840. package/docs/zh-CN/gateway/protocol.md +220 -0
  841. package/docs/zh-CN/gateway/remote-gateway-readme.md +164 -0
  842. package/docs/zh-CN/gateway/remote.md +133 -0
  843. package/docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md +135 -0
  844. package/docs/zh-CN/gateway/sandboxing.md +188 -0
  845. package/docs/zh-CN/gateway/security/formal-verification.md +169 -0
  846. package/docs/zh-CN/gateway/security/index.md +777 -0
  847. package/docs/zh-CN/gateway/tailscale.md +124 -0
  848. package/docs/zh-CN/gateway/tools-invoke-http-api.md +92 -0
  849. package/docs/zh-CN/gateway/troubleshooting.md +771 -0
  850. package/docs/zh-CN/help/faq.md +2628 -0
  851. package/docs/zh-CN/help/index.md +28 -0
  852. package/docs/zh-CN/help/troubleshooting.md +104 -0
  853. package/docs/zh-CN/hooks/soul-evil.md +72 -0
  854. package/docs/zh-CN/hooks.md +919 -0
  855. package/docs/zh-CN/index.md +264 -0
  856. package/docs/zh-CN/install/ansible.md +215 -0
  857. package/docs/zh-CN/install/bun.md +65 -0
  858. package/docs/zh-CN/install/development-channels.md +81 -0
  859. package/docs/zh-CN/install/docker.md +532 -0
  860. package/docs/zh-CN/install/index.md +193 -0
  861. package/docs/zh-CN/install/installer.md +128 -0
  862. package/docs/zh-CN/install/migrating.md +199 -0
  863. package/docs/zh-CN/install/nix.md +99 -0
  864. package/docs/zh-CN/install/node.md +85 -0
  865. package/docs/zh-CN/install/uninstall.md +135 -0
  866. package/docs/zh-CN/install/updating.md +233 -0
  867. package/docs/zh-CN/logging.md +329 -0
  868. package/docs/zh-CN/multi-agent-sandbox-tools.md +401 -0
  869. package/docs/zh-CN/network.md +59 -0
  870. package/docs/zh-CN/nodes/audio.md +120 -0
  871. package/docs/zh-CN/nodes/camera.md +162 -0
  872. package/docs/zh-CN/nodes/images.md +79 -0
  873. package/docs/zh-CN/nodes/index.md +348 -0
  874. package/docs/zh-CN/nodes/location-command.md +120 -0
  875. package/docs/zh-CN/nodes/media-understanding.md +380 -0
  876. package/docs/zh-CN/nodes/talk.md +97 -0
  877. package/docs/zh-CN/nodes/voicewake.md +72 -0
  878. package/docs/zh-CN/northflank.mdx +60 -0
  879. package/docs/zh-CN/perplexity.md +84 -0
  880. package/docs/zh-CN/pi-dev.md +77 -0
  881. package/docs/zh-CN/pi.md +619 -0
  882. package/docs/zh-CN/platforms/android.md +155 -0
  883. package/docs/zh-CN/platforms/digitalocean.md +269 -0
  884. package/docs/zh-CN/platforms/exe-dev.md +127 -0
  885. package/docs/zh-CN/platforms/fly.md +490 -0
  886. package/docs/zh-CN/platforms/gcp.md +510 -0
  887. package/docs/zh-CN/platforms/hetzner.md +337 -0
  888. package/docs/zh-CN/platforms/index.md +60 -0
  889. package/docs/zh-CN/platforms/ios.md +114 -0
  890. package/docs/zh-CN/platforms/linux.md +101 -0
  891. package/docs/zh-CN/platforms/mac/bundled-gateway.md +75 -0
  892. package/docs/zh-CN/platforms/mac/canvas.md +128 -0
  893. package/docs/zh-CN/platforms/mac/child-process.md +73 -0
  894. package/docs/zh-CN/platforms/mac/dev-setup.md +109 -0
  895. package/docs/zh-CN/platforms/mac/health.md +41 -0
  896. package/docs/zh-CN/platforms/mac/icon.md +38 -0
  897. package/docs/zh-CN/platforms/mac/logging.md +64 -0
  898. package/docs/zh-CN/platforms/mac/menu-bar.md +88 -0
  899. package/docs/zh-CN/platforms/mac/peekaboo.md +62 -0
  900. package/docs/zh-CN/platforms/mac/permissions.md +46 -0
  901. package/docs/zh-CN/platforms/mac/release.md +92 -0
  902. package/docs/zh-CN/platforms/mac/remote.md +90 -0
  903. package/docs/zh-CN/platforms/mac/signing.md +54 -0
  904. package/docs/zh-CN/platforms/mac/skills.md +40 -0
  905. package/docs/zh-CN/platforms/mac/voice-overlay.md +67 -0
  906. package/docs/zh-CN/platforms/mac/voicewake.md +74 -0
  907. package/docs/zh-CN/platforms/mac/webchat.md +43 -0
  908. package/docs/zh-CN/platforms/mac/xpc.md +68 -0
  909. package/docs/zh-CN/platforms/macos-vm.md +288 -0
  910. package/docs/zh-CN/platforms/macos.md +193 -0
  911. package/docs/zh-CN/platforms/oracle.md +310 -0
  912. package/docs/zh-CN/platforms/raspberry-pi.md +365 -0
  913. package/docs/zh-CN/platforms/windows.md +156 -0
  914. package/docs/zh-CN/plugin.md +639 -0
  915. package/docs/zh-CN/plugins/agent-tools.md +99 -0
  916. package/docs/zh-CN/plugins/manifest.md +68 -0
  917. package/docs/zh-CN/plugins/voice-call.md +250 -0
  918. package/docs/zh-CN/plugins/zalouser.md +88 -0
  919. package/docs/zh-CN/prose.md +141 -0
  920. package/docs/zh-CN/providers/anthropic.md +159 -0
  921. package/docs/zh-CN/providers/claude-max-api-proxy.md +155 -0
  922. package/docs/zh-CN/providers/deepgram.md +97 -0
  923. package/docs/zh-CN/providers/github-copilot.md +67 -0
  924. package/docs/zh-CN/providers/glm.md +39 -0
  925. package/docs/zh-CN/providers/index.md +68 -0
  926. package/docs/zh-CN/providers/minimax.md +206 -0
  927. package/docs/zh-CN/providers/models.md +55 -0
  928. package/docs/zh-CN/providers/moonshot.md +145 -0
  929. package/docs/zh-CN/providers/ollama.md +230 -0
  930. package/docs/zh-CN/providers/openai.md +68 -0
  931. package/docs/zh-CN/providers/opencode.md +41 -0
  932. package/docs/zh-CN/providers/openrouter.md +43 -0
  933. package/docs/zh-CN/providers/qwen.md +55 -0
  934. package/docs/zh-CN/providers/synthetic.md +102 -0
  935. package/docs/zh-CN/providers/venice.md +274 -0
  936. package/docs/zh-CN/providers/vercel-ai-gateway.md +57 -0
  937. package/docs/zh-CN/providers/xiaomi.md +68 -0
  938. package/docs/zh-CN/providers/zai.md +41 -0
  939. package/docs/zh-CN/railway.mdx +106 -0
  940. package/docs/zh-CN/refactor/clawnet.md +424 -0
  941. package/docs/zh-CN/refactor/exec-host.md +323 -0
  942. package/docs/zh-CN/refactor/outbound-session-mirroring.md +92 -0
  943. package/docs/zh-CN/refactor/plugin-sdk.md +221 -0
  944. package/docs/zh-CN/refactor/strict-config.md +100 -0
  945. package/docs/zh-CN/reference/AGENTS.default.md +131 -0
  946. package/docs/zh-CN/reference/RELEASING.md +123 -0
  947. package/docs/zh-CN/reference/api-usage-costs.md +136 -0
  948. package/docs/zh-CN/reference/device-models.md +54 -0
  949. package/docs/zh-CN/reference/rpc.md +48 -0
  950. package/docs/zh-CN/reference/session-management-compaction.md +287 -0
  951. package/docs/zh-CN/reference/templates/AGENTS.dev.md +89 -0
  952. package/docs/zh-CN/reference/templates/AGENTS.md +225 -0
  953. package/docs/zh-CN/reference/templates/BOOT.md +17 -0
  954. package/docs/zh-CN/reference/templates/BOOTSTRAP.md +68 -0
  955. package/docs/zh-CN/reference/templates/HEARTBEAT.md +18 -0
  956. package/docs/zh-CN/reference/templates/IDENTITY.dev.md +54 -0
  957. package/docs/zh-CN/reference/templates/IDENTITY.md +35 -0
  958. package/docs/zh-CN/reference/templates/SOUL.dev.md +83 -0
  959. package/docs/zh-CN/reference/templates/SOUL.md +49 -0
  960. package/docs/zh-CN/reference/templates/TOOLS.dev.md +31 -0
  961. package/docs/zh-CN/reference/templates/TOOLS.md +53 -0
  962. package/docs/zh-CN/reference/templates/USER.dev.md +25 -0
  963. package/docs/zh-CN/reference/templates/USER.md +30 -0
  964. package/docs/zh-CN/reference/test.md +57 -0
  965. package/docs/zh-CN/reference/transcript-hygiene.md +109 -0
  966. package/docs/zh-CN/render.mdx +169 -0
  967. package/docs/zh-CN/scripts.md +35 -0
  968. package/docs/zh-CN/security/formal-verification.md +171 -0
  969. package/docs/zh-CN/start/getting-started.md +206 -0
  970. package/docs/zh-CN/start/hubs.md +191 -0
  971. package/docs/zh-CN/start/lore.md +226 -0
  972. package/docs/zh-CN/start/onboarding.md +105 -0
  973. package/docs/zh-CN/start/openclaw.md +248 -0
  974. package/docs/zh-CN/start/pairing.md +89 -0
  975. package/docs/zh-CN/start/setup.md +153 -0
  976. package/docs/zh-CN/start/showcase.md +423 -0
  977. package/docs/zh-CN/start/wizard.md +331 -0
  978. package/docs/zh-CN/testing.md +375 -0
  979. package/docs/zh-CN/token-use.md +119 -0
  980. package/docs/zh-CN/tools/agent-send.md +59 -0
  981. package/docs/zh-CN/tools/apply-patch.md +57 -0
  982. package/docs/zh-CN/tools/browser-linux-troubleshooting.md +144 -0
  983. package/docs/zh-CN/tools/browser-login.md +75 -0
  984. package/docs/zh-CN/tools/browser.md +553 -0
  985. package/docs/zh-CN/tools/chrome-extension.md +183 -0
  986. package/docs/zh-CN/tools/clawhub.md +209 -0
  987. package/docs/zh-CN/tools/creating-skills.md +61 -0
  988. package/docs/zh-CN/tools/elevated.md +64 -0
  989. package/docs/zh-CN/tools/exec-approvals.md +234 -0
  990. package/docs/zh-CN/tools/exec.md +169 -0
  991. package/docs/zh-CN/tools/firecrawl.md +68 -0
  992. package/docs/zh-CN/tools/index.md +515 -0
  993. package/docs/zh-CN/tools/llm-task.md +117 -0
  994. package/docs/zh-CN/tools/lobster.md +349 -0
  995. package/docs/zh-CN/tools/reactions.md +29 -0
  996. package/docs/zh-CN/tools/skills-config.md +78 -0
  997. package/docs/zh-CN/tools/skills.md +279 -0
  998. package/docs/zh-CN/tools/slash-commands.md +205 -0
  999. package/docs/zh-CN/tools/subagents.md +156 -0
  1000. package/docs/zh-CN/tools/thinking.md +80 -0
  1001. package/docs/zh-CN/tools/web.md +257 -0
  1002. package/docs/zh-CN/tts.md +375 -0
  1003. package/docs/zh-CN/tui.md +166 -0
  1004. package/docs/zh-CN/vps.md +47 -0
  1005. package/docs/zh-CN/web/control-ui.md +191 -0
  1006. package/docs/zh-CN/web/dashboard.md +53 -0
  1007. package/docs/zh-CN/web/index.md +118 -0
  1008. package/docs/zh-CN/web/webchat.md +56 -0
  1009. package/extensions/bluebubbles/README.md +45 -0
  1010. package/extensions/bluebubbles/index.ts +19 -0
  1011. package/extensions/bluebubbles/node_modules/.bin/openclaw +21 -0
  1012. package/extensions/bluebubbles/openclaw.plugin.json +9 -0
  1013. package/extensions/bluebubbles/package.json +36 -0
  1014. package/extensions/bluebubbles/src/accounts.ts +88 -0
  1015. package/extensions/bluebubbles/src/actions.test.ts +650 -0
  1016. package/extensions/bluebubbles/src/actions.ts +438 -0
  1017. package/extensions/bluebubbles/src/attachments.test.ts +345 -0
  1018. package/extensions/bluebubbles/src/attachments.ts +300 -0
  1019. package/extensions/bluebubbles/src/channel.ts +414 -0
  1020. package/extensions/bluebubbles/src/chat.test.ts +461 -0
  1021. package/extensions/bluebubbles/src/chat.ts +378 -0
  1022. package/extensions/bluebubbles/src/config-schema.ts +51 -0
  1023. package/extensions/bluebubbles/src/media-send.ts +174 -0
  1024. package/extensions/bluebubbles/src/monitor.test.ts +2342 -0
  1025. package/extensions/bluebubbles/src/monitor.ts +2490 -0
  1026. package/extensions/bluebubbles/src/onboarding.ts +352 -0
  1027. package/extensions/bluebubbles/src/probe.ts +135 -0
  1028. package/extensions/bluebubbles/src/reactions.test.ts +392 -0
  1029. package/extensions/bluebubbles/src/reactions.ts +188 -0
  1030. package/extensions/bluebubbles/src/runtime.ts +14 -0
  1031. package/extensions/bluebubbles/src/send.test.ts +808 -0
  1032. package/extensions/bluebubbles/src/send.ts +467 -0
  1033. package/extensions/bluebubbles/src/targets.test.ts +183 -0
  1034. package/extensions/bluebubbles/src/targets.ts +422 -0
  1035. package/extensions/bluebubbles/src/types.ts +127 -0
  1036. package/extensions/copilot-proxy/README.md +24 -0
  1037. package/extensions/copilot-proxy/index.ts +148 -0
  1038. package/extensions/copilot-proxy/node_modules/.bin/openclaw +21 -0
  1039. package/extensions/copilot-proxy/openclaw.plugin.json +9 -0
  1040. package/extensions/copilot-proxy/package.json +14 -0
  1041. package/extensions/diagnostics-otel/index.ts +15 -0
  1042. package/extensions/diagnostics-otel/node_modules/.bin/openclaw +21 -0
  1043. package/extensions/diagnostics-otel/openclaw.plugin.json +8 -0
  1044. package/extensions/diagnostics-otel/package.json +27 -0
  1045. package/extensions/diagnostics-otel/src/service.test.ts +226 -0
  1046. package/extensions/diagnostics-otel/src/service.ts +635 -0
  1047. package/extensions/discord/index.ts +17 -0
  1048. package/extensions/discord/node_modules/.bin/openclaw +21 -0
  1049. package/extensions/discord/openclaw.plugin.json +9 -0
  1050. package/extensions/discord/package.json +14 -0
  1051. package/extensions/discord/src/channel.ts +422 -0
  1052. package/extensions/discord/src/runtime.ts +14 -0
  1053. package/extensions/feishu/README.md +47 -0
  1054. package/extensions/feishu/index.ts +15 -0
  1055. package/extensions/feishu/node_modules/.bin/openclaw +21 -0
  1056. package/extensions/feishu/openclaw.plugin.json +9 -0
  1057. package/extensions/feishu/package.json +33 -0
  1058. package/extensions/feishu/src/channel.ts +276 -0
  1059. package/extensions/feishu/src/config-schema.ts +46 -0
  1060. package/extensions/feishu/src/onboarding.ts +278 -0
  1061. package/extensions/google-antigravity-auth/README.md +24 -0
  1062. package/extensions/google-antigravity-auth/index.ts +461 -0
  1063. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw +21 -0
  1064. package/extensions/google-antigravity-auth/openclaw.plugin.json +9 -0
  1065. package/extensions/google-antigravity-auth/package.json +14 -0
  1066. package/extensions/google-gemini-cli-auth/README.md +35 -0
  1067. package/extensions/google-gemini-cli-auth/index.ts +88 -0
  1068. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw +21 -0
  1069. package/extensions/google-gemini-cli-auth/oauth.test.ts +240 -0
  1070. package/extensions/google-gemini-cli-auth/oauth.ts +662 -0
  1071. package/extensions/google-gemini-cli-auth/openclaw.plugin.json +9 -0
  1072. package/extensions/google-gemini-cli-auth/package.json +14 -0
  1073. package/extensions/googlechat/index.ts +19 -0
  1074. package/extensions/googlechat/node_modules/.bin/openclaw +21 -0
  1075. package/extensions/googlechat/openclaw.plugin.json +9 -0
  1076. package/extensions/googlechat/package.json +39 -0
  1077. package/extensions/googlechat/src/accounts.ts +147 -0
  1078. package/extensions/googlechat/src/actions.ts +181 -0
  1079. package/extensions/googlechat/src/api.test.ts +61 -0
  1080. package/extensions/googlechat/src/api.ts +282 -0
  1081. package/extensions/googlechat/src/auth.ts +123 -0
  1082. package/extensions/googlechat/src/channel.ts +583 -0
  1083. package/extensions/googlechat/src/monitor.test.ts +22 -0
  1084. package/extensions/googlechat/src/monitor.ts +949 -0
  1085. package/extensions/googlechat/src/onboarding.ts +269 -0
  1086. package/extensions/googlechat/src/runtime.ts +14 -0
  1087. package/extensions/googlechat/src/targets.test.ts +32 -0
  1088. package/extensions/googlechat/src/targets.ts +65 -0
  1089. package/extensions/googlechat/src/types.config.ts +3 -0
  1090. package/extensions/googlechat/src/types.ts +73 -0
  1091. package/extensions/imessage/index.ts +17 -0
  1092. package/extensions/imessage/node_modules/.bin/openclaw +21 -0
  1093. package/extensions/imessage/openclaw.plugin.json +9 -0
  1094. package/extensions/imessage/package.json +14 -0
  1095. package/extensions/imessage/src/channel.ts +294 -0
  1096. package/extensions/imessage/src/runtime.ts +14 -0
  1097. package/extensions/line/index.ts +19 -0
  1098. package/extensions/line/node_modules/.bin/openclaw +21 -0
  1099. package/extensions/line/openclaw.plugin.json +9 -0
  1100. package/extensions/line/package.json +29 -0
  1101. package/extensions/line/src/card-command.ts +344 -0
  1102. package/extensions/line/src/channel.logout.test.ts +99 -0
  1103. package/extensions/line/src/channel.sendPayload.test.ts +306 -0
  1104. package/extensions/line/src/channel.ts +780 -0
  1105. package/extensions/line/src/runtime.ts +14 -0
  1106. package/extensions/llm-task/README.md +97 -0
  1107. package/extensions/llm-task/index.ts +6 -0
  1108. package/extensions/llm-task/node_modules/.bin/openclaw +21 -0
  1109. package/extensions/llm-task/openclaw.plugin.json +21 -0
  1110. package/extensions/llm-task/package.json +14 -0
  1111. package/extensions/llm-task/src/llm-task-tool.test.ts +138 -0
  1112. package/extensions/llm-task/src/llm-task-tool.ts +245 -0
  1113. package/extensions/lobster/README.md +75 -0
  1114. package/extensions/lobster/SKILL.md +97 -0
  1115. package/extensions/lobster/index.ts +14 -0
  1116. package/extensions/lobster/node_modules/.bin/openclaw +21 -0
  1117. package/extensions/lobster/openclaw.plugin.json +10 -0
  1118. package/extensions/lobster/package.json +14 -0
  1119. package/extensions/lobster/src/lobster-tool.test.ts +247 -0
  1120. package/extensions/lobster/src/lobster-tool.ts +328 -0
  1121. package/extensions/matrix/CHANGELOG.md +87 -0
  1122. package/extensions/matrix/index.ts +17 -0
  1123. package/extensions/matrix/node_modules/.bin/markdown-it +21 -0
  1124. package/extensions/matrix/node_modules/.bin/openclaw +21 -0
  1125. package/extensions/matrix/openclaw.plugin.json +9 -0
  1126. package/extensions/matrix/package.json +36 -0
  1127. package/extensions/matrix/src/actions.ts +195 -0
  1128. package/extensions/matrix/src/channel.directory.test.ts +64 -0
  1129. package/extensions/matrix/src/channel.ts +439 -0
  1130. package/extensions/matrix/src/config-schema.ts +62 -0
  1131. package/extensions/matrix/src/directory-live.ts +188 -0
  1132. package/extensions/matrix/src/group-mentions.ts +66 -0
  1133. package/extensions/matrix/src/matrix/accounts.test.ts +82 -0
  1134. package/extensions/matrix/src/matrix/accounts.ts +65 -0
  1135. package/extensions/matrix/src/matrix/actions/client.ts +57 -0
  1136. package/extensions/matrix/src/matrix/actions/messages.ts +128 -0
  1137. package/extensions/matrix/src/matrix/actions/pins.ts +76 -0
  1138. package/extensions/matrix/src/matrix/actions/reactions.ts +96 -0
  1139. package/extensions/matrix/src/matrix/actions/room.ts +85 -0
  1140. package/extensions/matrix/src/matrix/actions/summary.ts +75 -0
  1141. package/extensions/matrix/src/matrix/actions/types.ts +84 -0
  1142. package/extensions/matrix/src/matrix/actions.ts +15 -0
  1143. package/extensions/matrix/src/matrix/active-client.ts +11 -0
  1144. package/extensions/matrix/src/matrix/client/config.ts +160 -0
  1145. package/extensions/matrix/src/matrix/client/create-client.ts +123 -0
  1146. package/extensions/matrix/src/matrix/client/logging.ts +36 -0
  1147. package/extensions/matrix/src/matrix/client/runtime.ts +4 -0
  1148. package/extensions/matrix/src/matrix/client/shared.ts +170 -0
  1149. package/extensions/matrix/src/matrix/client/storage.ts +131 -0
  1150. package/extensions/matrix/src/matrix/client/types.ts +34 -0
  1151. package/extensions/matrix/src/matrix/client.test.ts +56 -0
  1152. package/extensions/matrix/src/matrix/client.ts +5 -0
  1153. package/extensions/matrix/src/matrix/credentials.ts +105 -0
  1154. package/extensions/matrix/src/matrix/deps.ts +60 -0
  1155. package/extensions/matrix/src/matrix/format.test.ts +33 -0
  1156. package/extensions/matrix/src/matrix/format.ts +22 -0
  1157. package/extensions/matrix/src/matrix/index.ts +11 -0
  1158. package/extensions/matrix/src/matrix/monitor/allowlist.test.ts +45 -0
  1159. package/extensions/matrix/src/matrix/monitor/allowlist.ts +103 -0
  1160. package/extensions/matrix/src/matrix/monitor/auto-join.ts +71 -0
  1161. package/extensions/matrix/src/matrix/monitor/direct.ts +104 -0
  1162. package/extensions/matrix/src/matrix/monitor/events.ts +101 -0
  1163. package/extensions/matrix/src/matrix/monitor/handler.ts +661 -0
  1164. package/extensions/matrix/src/matrix/monitor/index.ts +338 -0
  1165. package/extensions/matrix/src/matrix/monitor/location.ts +100 -0
  1166. package/extensions/matrix/src/matrix/monitor/media.test.ts +102 -0
  1167. package/extensions/matrix/src/matrix/monitor/media.ts +113 -0
  1168. package/extensions/matrix/src/matrix/monitor/mentions.ts +31 -0
  1169. package/extensions/matrix/src/matrix/monitor/replies.ts +97 -0
  1170. package/extensions/matrix/src/matrix/monitor/room-info.ts +55 -0
  1171. package/extensions/matrix/src/matrix/monitor/rooms.test.ts +39 -0
  1172. package/extensions/matrix/src/matrix/monitor/rooms.ts +47 -0
  1173. package/extensions/matrix/src/matrix/monitor/threads.ts +68 -0
  1174. package/extensions/matrix/src/matrix/monitor/types.ts +39 -0
  1175. package/extensions/matrix/src/matrix/poll-types.test.ts +21 -0
  1176. package/extensions/matrix/src/matrix/poll-types.ts +166 -0
  1177. package/extensions/matrix/src/matrix/probe.ts +70 -0
  1178. package/extensions/matrix/src/matrix/send/client.ts +66 -0
  1179. package/extensions/matrix/src/matrix/send/formatting.ts +89 -0
  1180. package/extensions/matrix/src/matrix/send/media.ts +229 -0
  1181. package/extensions/matrix/src/matrix/send/targets.test.ts +98 -0
  1182. package/extensions/matrix/src/matrix/send/targets.ts +136 -0
  1183. package/extensions/matrix/src/matrix/send/types.ts +109 -0
  1184. package/extensions/matrix/src/matrix/send.test.ts +171 -0
  1185. package/extensions/matrix/src/matrix/send.ts +260 -0
  1186. package/extensions/matrix/src/onboarding.ts +449 -0
  1187. package/extensions/matrix/src/outbound.ts +52 -0
  1188. package/extensions/matrix/src/resolve-targets.test.ts +48 -0
  1189. package/extensions/matrix/src/resolve-targets.ts +135 -0
  1190. package/extensions/matrix/src/runtime.ts +14 -0
  1191. package/extensions/matrix/src/tool-actions.ts +164 -0
  1192. package/extensions/matrix/src/types.ts +95 -0
  1193. package/extensions/mattermost/index.ts +17 -0
  1194. package/extensions/mattermost/node_modules/.bin/openclaw +21 -0
  1195. package/extensions/mattermost/openclaw.plugin.json +9 -0
  1196. package/extensions/mattermost/package.json +28 -0
  1197. package/extensions/mattermost/src/channel.test.ts +48 -0
  1198. package/extensions/mattermost/src/channel.ts +337 -0
  1199. package/extensions/mattermost/src/config-schema.ts +55 -0
  1200. package/extensions/mattermost/src/group-mentions.ts +15 -0
  1201. package/extensions/mattermost/src/mattermost/accounts.ts +128 -0
  1202. package/extensions/mattermost/src/mattermost/client.ts +220 -0
  1203. package/extensions/mattermost/src/mattermost/index.ts +9 -0
  1204. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +166 -0
  1205. package/extensions/mattermost/src/mattermost/monitor.ts +987 -0
  1206. package/extensions/mattermost/src/mattermost/probe.ts +74 -0
  1207. package/extensions/mattermost/src/mattermost/send.ts +231 -0
  1208. package/extensions/mattermost/src/normalize.ts +46 -0
  1209. package/extensions/mattermost/src/onboarding-helpers.ts +44 -0
  1210. package/extensions/mattermost/src/onboarding.ts +186 -0
  1211. package/extensions/mattermost/src/runtime.ts +14 -0
  1212. package/extensions/mattermost/src/types.ts +50 -0
  1213. package/extensions/memory-core/index.ts +38 -0
  1214. package/extensions/memory-core/node_modules/.bin/openclaw +21 -0
  1215. package/extensions/memory-core/openclaw.plugin.json +9 -0
  1216. package/extensions/memory-core/package.json +17 -0
  1217. package/extensions/memory-lancedb/config.ts +139 -0
  1218. package/extensions/memory-lancedb/index.test.ts +295 -0
  1219. package/extensions/memory-lancedb/index.ts +608 -0
  1220. package/extensions/memory-lancedb/node_modules/.bin/openai +21 -0
  1221. package/extensions/memory-lancedb/node_modules/.bin/openclaw +21 -0
  1222. package/extensions/memory-lancedb/openclaw.plugin.json +60 -0
  1223. package/extensions/memory-lancedb/package.json +19 -0
  1224. package/extensions/minimax-portal-auth/README.md +33 -0
  1225. package/extensions/minimax-portal-auth/index.ts +155 -0
  1226. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw +21 -0
  1227. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  1228. package/extensions/minimax-portal-auth/openclaw.plugin.json +9 -0
  1229. package/extensions/minimax-portal-auth/package.json +14 -0
  1230. package/extensions/msteams/CHANGELOG.md +83 -0
  1231. package/extensions/msteams/index.ts +17 -0
  1232. package/extensions/msteams/node_modules/.bin/openclaw +21 -0
  1233. package/extensions/msteams/openclaw.plugin.json +9 -0
  1234. package/extensions/msteams/package.json +39 -0
  1235. package/extensions/msteams/src/attachments/download.ts +283 -0
  1236. package/extensions/msteams/src/attachments/graph.ts +353 -0
  1237. package/extensions/msteams/src/attachments/html.ts +90 -0
  1238. package/extensions/msteams/src/attachments/payload.ts +22 -0
  1239. package/extensions/msteams/src/attachments/shared.ts +291 -0
  1240. package/extensions/msteams/src/attachments/types.ts +37 -0
  1241. package/extensions/msteams/src/attachments.test.ts +459 -0
  1242. package/extensions/msteams/src/attachments.ts +18 -0
  1243. package/extensions/msteams/src/channel.directory.test.ts +48 -0
  1244. package/extensions/msteams/src/channel.ts +459 -0
  1245. package/extensions/msteams/src/conversation-store-fs.test.ts +88 -0
  1246. package/extensions/msteams/src/conversation-store-fs.ts +165 -0
  1247. package/extensions/msteams/src/conversation-store-memory.ts +47 -0
  1248. package/extensions/msteams/src/conversation-store.ts +41 -0
  1249. package/extensions/msteams/src/directory-live.ts +205 -0
  1250. package/extensions/msteams/src/errors.test.ts +45 -0
  1251. package/extensions/msteams/src/errors.ts +190 -0
  1252. package/extensions/msteams/src/file-consent-helpers.test.ts +243 -0
  1253. package/extensions/msteams/src/file-consent-helpers.ts +73 -0
  1254. package/extensions/msteams/src/file-consent.ts +126 -0
  1255. package/extensions/msteams/src/graph-chat.ts +53 -0
  1256. package/extensions/msteams/src/graph-upload.ts +453 -0
  1257. package/extensions/msteams/src/inbound.test.ts +66 -0
  1258. package/extensions/msteams/src/inbound.ts +48 -0
  1259. package/extensions/msteams/src/index.ts +4 -0
  1260. package/extensions/msteams/src/media-helpers.test.ts +189 -0
  1261. package/extensions/msteams/src/media-helpers.ts +86 -0
  1262. package/extensions/msteams/src/messenger.test.ts +248 -0
  1263. package/extensions/msteams/src/messenger.ts +495 -0
  1264. package/extensions/msteams/src/monitor-handler/inbound-media.ts +128 -0
  1265. package/extensions/msteams/src/monitor-handler/message-handler.ts +640 -0
  1266. package/extensions/msteams/src/monitor-handler.ts +162 -0
  1267. package/extensions/msteams/src/monitor-types.ts +5 -0
  1268. package/extensions/msteams/src/monitor.ts +295 -0
  1269. package/extensions/msteams/src/onboarding.ts +431 -0
  1270. package/extensions/msteams/src/outbound.ts +46 -0
  1271. package/extensions/msteams/src/pending-uploads.ts +89 -0
  1272. package/extensions/msteams/src/policy.test.ts +209 -0
  1273. package/extensions/msteams/src/policy.ts +273 -0
  1274. package/extensions/msteams/src/polls-store-memory.ts +32 -0
  1275. package/extensions/msteams/src/polls-store.test.ts +38 -0
  1276. package/extensions/msteams/src/polls.test.ts +72 -0
  1277. package/extensions/msteams/src/polls.ts +315 -0
  1278. package/extensions/msteams/src/probe.test.ts +58 -0
  1279. package/extensions/msteams/src/probe.ts +107 -0
  1280. package/extensions/msteams/src/reply-dispatcher.ts +130 -0
  1281. package/extensions/msteams/src/resolve-allowlist.ts +297 -0
  1282. package/extensions/msteams/src/runtime.ts +14 -0
  1283. package/extensions/msteams/src/sdk-types.ts +19 -0
  1284. package/extensions/msteams/src/sdk.ts +33 -0
  1285. package/extensions/msteams/src/send-context.ts +164 -0
  1286. package/extensions/msteams/src/send.ts +519 -0
  1287. package/extensions/msteams/src/sent-message-cache.test.ts +15 -0
  1288. package/extensions/msteams/src/sent-message-cache.ts +47 -0
  1289. package/extensions/msteams/src/storage.ts +25 -0
  1290. package/extensions/msteams/src/store-fs.ts +83 -0
  1291. package/extensions/msteams/src/token.ts +19 -0
  1292. package/extensions/nextcloud-talk/index.ts +17 -0
  1293. package/extensions/nextcloud-talk/node_modules/.bin/openclaw +21 -0
  1294. package/extensions/nextcloud-talk/openclaw.plugin.json +9 -0
  1295. package/extensions/nextcloud-talk/package.json +33 -0
  1296. package/extensions/nextcloud-talk/src/accounts.ts +174 -0
  1297. package/extensions/nextcloud-talk/src/channel.ts +409 -0
  1298. package/extensions/nextcloud-talk/src/config-schema.ts +78 -0
  1299. package/extensions/nextcloud-talk/src/format.ts +79 -0
  1300. package/extensions/nextcloud-talk/src/inbound.ts +317 -0
  1301. package/extensions/nextcloud-talk/src/monitor.ts +246 -0
  1302. package/extensions/nextcloud-talk/src/normalize.ts +39 -0
  1303. package/extensions/nextcloud-talk/src/onboarding.ts +343 -0
  1304. package/extensions/nextcloud-talk/src/policy.test.ts +33 -0
  1305. package/extensions/nextcloud-talk/src/policy.ts +180 -0
  1306. package/extensions/nextcloud-talk/src/room-info.ts +125 -0
  1307. package/extensions/nextcloud-talk/src/runtime.ts +14 -0
  1308. package/extensions/nextcloud-talk/src/send.ts +210 -0
  1309. package/extensions/nextcloud-talk/src/signature.ts +72 -0
  1310. package/extensions/nextcloud-talk/src/types.ts +179 -0
  1311. package/extensions/nostr/CHANGELOG.md +74 -0
  1312. package/extensions/nostr/README.md +136 -0
  1313. package/extensions/nostr/index.ts +68 -0
  1314. package/extensions/nostr/node_modules/.bin/openclaw +21 -0
  1315. package/extensions/nostr/openclaw.plugin.json +9 -0
  1316. package/extensions/nostr/package.json +34 -0
  1317. package/extensions/nostr/src/channel.test.ts +151 -0
  1318. package/extensions/nostr/src/channel.ts +353 -0
  1319. package/extensions/nostr/src/config-schema.ts +90 -0
  1320. package/extensions/nostr/src/metrics.ts +478 -0
  1321. package/extensions/nostr/src/nostr-bus.fuzz.test.ts +533 -0
  1322. package/extensions/nostr/src/nostr-bus.integration.test.ts +448 -0
  1323. package/extensions/nostr/src/nostr-bus.test.ts +199 -0
  1324. package/extensions/nostr/src/nostr-bus.ts +715 -0
  1325. package/extensions/nostr/src/nostr-profile-http.test.ts +378 -0
  1326. package/extensions/nostr/src/nostr-profile-http.ts +519 -0
  1327. package/extensions/nostr/src/nostr-profile-import.test.ts +119 -0
  1328. package/extensions/nostr/src/nostr-profile-import.ts +262 -0
  1329. package/extensions/nostr/src/nostr-profile.fuzz.test.ts +477 -0
  1330. package/extensions/nostr/src/nostr-profile.test.ts +410 -0
  1331. package/extensions/nostr/src/nostr-profile.ts +277 -0
  1332. package/extensions/nostr/src/nostr-state-store.test.ts +131 -0
  1333. package/extensions/nostr/src/nostr-state-store.ts +226 -0
  1334. package/extensions/nostr/src/runtime.ts +14 -0
  1335. package/extensions/nostr/src/seen-tracker.ts +303 -0
  1336. package/extensions/nostr/src/types.test.ts +157 -0
  1337. package/extensions/nostr/src/types.ts +101 -0
  1338. package/extensions/nostr/test/setup.ts +5 -0
  1339. package/extensions/open-prose/README.md +25 -0
  1340. package/extensions/open-prose/index.ts +5 -0
  1341. package/extensions/open-prose/node_modules/.bin/openclaw +21 -0
  1342. package/extensions/open-prose/openclaw.plugin.json +11 -0
  1343. package/extensions/open-prose/package.json +14 -0
  1344. package/extensions/open-prose/skills/prose/LICENSE +21 -0
  1345. package/extensions/open-prose/skills/prose/SKILL.md +323 -0
  1346. package/extensions/open-prose/skills/prose/alt-borges.md +141 -0
  1347. package/extensions/open-prose/skills/prose/alts/arabian-nights.md +358 -0
  1348. package/extensions/open-prose/skills/prose/alts/borges.md +360 -0
  1349. package/extensions/open-prose/skills/prose/alts/folk.md +322 -0
  1350. package/extensions/open-prose/skills/prose/alts/homer.md +346 -0
  1351. package/extensions/open-prose/skills/prose/alts/kafka.md +373 -0
  1352. package/extensions/open-prose/skills/prose/compiler.md +2971 -0
  1353. package/extensions/open-prose/skills/prose/examples/01-hello-world.prose +4 -0
  1354. package/extensions/open-prose/skills/prose/examples/02-research-and-summarize.prose +6 -0
  1355. package/extensions/open-prose/skills/prose/examples/03-code-review.prose +17 -0
  1356. package/extensions/open-prose/skills/prose/examples/04-write-and-refine.prose +14 -0
  1357. package/extensions/open-prose/skills/prose/examples/05-debug-issue.prose +20 -0
  1358. package/extensions/open-prose/skills/prose/examples/06-explain-codebase.prose +17 -0
  1359. package/extensions/open-prose/skills/prose/examples/07-refactor.prose +20 -0
  1360. package/extensions/open-prose/skills/prose/examples/08-blog-post.prose +20 -0
  1361. package/extensions/open-prose/skills/prose/examples/09-research-with-agents.prose +25 -0
  1362. package/extensions/open-prose/skills/prose/examples/10-code-review-agents.prose +32 -0
  1363. package/extensions/open-prose/skills/prose/examples/11-skills-and-imports.prose +27 -0
  1364. package/extensions/open-prose/skills/prose/examples/12-secure-agent-permissions.prose +43 -0
  1365. package/extensions/open-prose/skills/prose/examples/13-variables-and-context.prose +51 -0
  1366. package/extensions/open-prose/skills/prose/examples/14-composition-blocks.prose +48 -0
  1367. package/extensions/open-prose/skills/prose/examples/15-inline-sequences.prose +23 -0
  1368. package/extensions/open-prose/skills/prose/examples/16-parallel-reviews.prose +19 -0
  1369. package/extensions/open-prose/skills/prose/examples/17-parallel-research.prose +19 -0
  1370. package/extensions/open-prose/skills/prose/examples/18-mixed-parallel-sequential.prose +36 -0
  1371. package/extensions/open-prose/skills/prose/examples/19-advanced-parallel.prose +71 -0
  1372. package/extensions/open-prose/skills/prose/examples/20-fixed-loops.prose +20 -0
  1373. package/extensions/open-prose/skills/prose/examples/21-pipeline-operations.prose +35 -0
  1374. package/extensions/open-prose/skills/prose/examples/22-error-handling.prose +51 -0
  1375. package/extensions/open-prose/skills/prose/examples/23-retry-with-backoff.prose +63 -0
  1376. package/extensions/open-prose/skills/prose/examples/24-choice-blocks.prose +86 -0
  1377. package/extensions/open-prose/skills/prose/examples/25-conditionals.prose +114 -0
  1378. package/extensions/open-prose/skills/prose/examples/26-parameterized-blocks.prose +100 -0
  1379. package/extensions/open-prose/skills/prose/examples/27-string-interpolation.prose +105 -0
  1380. package/extensions/open-prose/skills/prose/examples/28-automated-pr-review.prose +37 -0
  1381. package/extensions/open-prose/skills/prose/examples/28-gas-town.prose +1572 -0
  1382. package/extensions/open-prose/skills/prose/examples/29-captains-chair.prose +218 -0
  1383. package/extensions/open-prose/skills/prose/examples/30-captains-chair-simple.prose +42 -0
  1384. package/extensions/open-prose/skills/prose/examples/31-captains-chair-with-memory.prose +145 -0
  1385. package/extensions/open-prose/skills/prose/examples/33-pr-review-autofix.prose +168 -0
  1386. package/extensions/open-prose/skills/prose/examples/34-content-pipeline.prose +204 -0
  1387. package/extensions/open-prose/skills/prose/examples/35-feature-factory.prose +296 -0
  1388. package/extensions/open-prose/skills/prose/examples/36-bug-hunter.prose +237 -0
  1389. package/extensions/open-prose/skills/prose/examples/37-the-forge.prose +1474 -0
  1390. package/extensions/open-prose/skills/prose/examples/38-skill-scan.prose +455 -0
  1391. package/extensions/open-prose/skills/prose/examples/39-architect-by-simulation.prose +277 -0
  1392. package/extensions/open-prose/skills/prose/examples/40-rlm-self-refine.prose +32 -0
  1393. package/extensions/open-prose/skills/prose/examples/41-rlm-divide-conquer.prose +38 -0
  1394. package/extensions/open-prose/skills/prose/examples/42-rlm-filter-recurse.prose +46 -0
  1395. package/extensions/open-prose/skills/prose/examples/43-rlm-pairwise.prose +50 -0
  1396. package/extensions/open-prose/skills/prose/examples/44-run-endpoint-ux-test.prose +261 -0
  1397. package/extensions/open-prose/skills/prose/examples/45-plugin-release.prose +159 -0
  1398. package/extensions/open-prose/skills/prose/examples/45-run-endpoint-ux-test-with-remediation.prose +637 -0
  1399. package/extensions/open-prose/skills/prose/examples/46-run-endpoint-ux-test-fast.prose +148 -0
  1400. package/extensions/open-prose/skills/prose/examples/46-workflow-crystallizer.prose +225 -0
  1401. package/extensions/open-prose/skills/prose/examples/47-language-self-improvement.prose +356 -0
  1402. package/extensions/open-prose/skills/prose/examples/48-habit-miner.prose +445 -0
  1403. package/extensions/open-prose/skills/prose/examples/49-prose-run-retrospective.prose +210 -0
  1404. package/extensions/open-prose/skills/prose/examples/README.md +391 -0
  1405. package/extensions/open-prose/skills/prose/examples/roadmap/README.md +22 -0
  1406. package/extensions/open-prose/skills/prose/examples/roadmap/iterative-refinement.prose +20 -0
  1407. package/extensions/open-prose/skills/prose/examples/roadmap/parallel-review.prose +18 -0
  1408. package/extensions/open-prose/skills/prose/examples/roadmap/simple-pipeline.prose +17 -0
  1409. package/extensions/open-prose/skills/prose/examples/roadmap/syntax/open-prose-syntax.prose +223 -0
  1410. package/extensions/open-prose/skills/prose/guidance/antipatterns.md +951 -0
  1411. package/extensions/open-prose/skills/prose/guidance/patterns.md +700 -0
  1412. package/extensions/open-prose/skills/prose/guidance/system-prompt.md +180 -0
  1413. package/extensions/open-prose/skills/prose/help.md +144 -0
  1414. package/extensions/open-prose/skills/prose/lib/README.md +108 -0
  1415. package/extensions/open-prose/skills/prose/lib/calibrator.prose +215 -0
  1416. package/extensions/open-prose/skills/prose/lib/cost-analyzer.prose +174 -0
  1417. package/extensions/open-prose/skills/prose/lib/error-forensics.prose +250 -0
  1418. package/extensions/open-prose/skills/prose/lib/inspector.prose +196 -0
  1419. package/extensions/open-prose/skills/prose/lib/profiler.prose +460 -0
  1420. package/extensions/open-prose/skills/prose/lib/program-improver.prose +275 -0
  1421. package/extensions/open-prose/skills/prose/lib/project-memory.prose +118 -0
  1422. package/extensions/open-prose/skills/prose/lib/user-memory.prose +93 -0
  1423. package/extensions/open-prose/skills/prose/lib/vm-improver.prose +243 -0
  1424. package/extensions/open-prose/skills/prose/primitives/session.md +593 -0
  1425. package/extensions/open-prose/skills/prose/prose.md +1237 -0
  1426. package/extensions/open-prose/skills/prose/state/filesystem.md +498 -0
  1427. package/extensions/open-prose/skills/prose/state/in-context.md +384 -0
  1428. package/extensions/open-prose/skills/prose/state/postgres.md +880 -0
  1429. package/extensions/open-prose/skills/prose/state/sqlite.md +574 -0
  1430. package/extensions/qwen-portal-auth/README.md +24 -0
  1431. package/extensions/qwen-portal-auth/index.ts +130 -0
  1432. package/extensions/qwen-portal-auth/oauth.ts +190 -0
  1433. package/extensions/qwen-portal-auth/openclaw.plugin.json +9 -0
  1434. package/extensions/signal/index.ts +17 -0
  1435. package/extensions/signal/node_modules/.bin/openclaw +21 -0
  1436. package/extensions/signal/openclaw.plugin.json +9 -0
  1437. package/extensions/signal/package.json +14 -0
  1438. package/extensions/signal/src/channel.ts +315 -0
  1439. package/extensions/signal/src/runtime.ts +14 -0
  1440. package/extensions/slack/index.ts +17 -0
  1441. package/extensions/slack/node_modules/.bin/openclaw +21 -0
  1442. package/extensions/slack/openclaw.plugin.json +9 -0
  1443. package/extensions/slack/package.json +14 -0
  1444. package/extensions/slack/src/channel.ts +604 -0
  1445. package/extensions/slack/src/runtime.ts +14 -0
  1446. package/extensions/telegram/index.ts +17 -0
  1447. package/extensions/telegram/node_modules/.bin/openclaw +21 -0
  1448. package/extensions/telegram/openclaw.plugin.json +9 -0
  1449. package/extensions/telegram/package.json +14 -0
  1450. package/extensions/telegram/src/channel.ts +482 -0
  1451. package/extensions/telegram/src/runtime.ts +14 -0
  1452. package/extensions/tlon/README.md +5 -0
  1453. package/extensions/tlon/index.ts +17 -0
  1454. package/extensions/tlon/node_modules/.bin/openclaw +21 -0
  1455. package/extensions/tlon/openclaw.plugin.json +9 -0
  1456. package/extensions/tlon/package.json +33 -0
  1457. package/extensions/tlon/src/channel.ts +392 -0
  1458. package/extensions/tlon/src/config-schema.test.ts +31 -0
  1459. package/extensions/tlon/src/config-schema.ts +43 -0
  1460. package/extensions/tlon/src/monitor/discovery.ts +76 -0
  1461. package/extensions/tlon/src/monitor/history.ts +90 -0
  1462. package/extensions/tlon/src/monitor/index.ts +553 -0
  1463. package/extensions/tlon/src/monitor/processed-messages.test.ts +23 -0
  1464. package/extensions/tlon/src/monitor/processed-messages.ts +46 -0
  1465. package/extensions/tlon/src/monitor/utils.ts +105 -0
  1466. package/extensions/tlon/src/onboarding.ts +214 -0
  1467. package/extensions/tlon/src/runtime.ts +14 -0
  1468. package/extensions/tlon/src/targets.ts +89 -0
  1469. package/extensions/tlon/src/types.ts +92 -0
  1470. package/extensions/tlon/src/urbit/auth.ts +18 -0
  1471. package/extensions/tlon/src/urbit/http-api.ts +38 -0
  1472. package/extensions/tlon/src/urbit/send.test.ts +38 -0
  1473. package/extensions/tlon/src/urbit/send.ts +131 -0
  1474. package/extensions/tlon/src/urbit/sse-client.test.ts +40 -0
  1475. package/extensions/tlon/src/urbit/sse-client.ts +395 -0
  1476. package/extensions/twitch/CHANGELOG.md +45 -0
  1477. package/extensions/twitch/README.md +89 -0
  1478. package/extensions/twitch/index.ts +20 -0
  1479. package/extensions/twitch/node_modules/.bin/openclaw +21 -0
  1480. package/extensions/twitch/openclaw.plugin.json +9 -0
  1481. package/extensions/twitch/package.json +20 -0
  1482. package/extensions/twitch/src/access-control.test.ts +489 -0
  1483. package/extensions/twitch/src/access-control.ts +166 -0
  1484. package/extensions/twitch/src/actions.ts +173 -0
  1485. package/extensions/twitch/src/client-manager-registry.ts +115 -0
  1486. package/extensions/twitch/src/config-schema.ts +82 -0
  1487. package/extensions/twitch/src/config.test.ts +87 -0
  1488. package/extensions/twitch/src/config.ts +116 -0
  1489. package/extensions/twitch/src/monitor.ts +261 -0
  1490. package/extensions/twitch/src/onboarding.test.ts +311 -0
  1491. package/extensions/twitch/src/onboarding.ts +417 -0
  1492. package/extensions/twitch/src/outbound.test.ts +373 -0
  1493. package/extensions/twitch/src/outbound.ts +184 -0
  1494. package/extensions/twitch/src/plugin.test.ts +39 -0
  1495. package/extensions/twitch/src/plugin.ts +274 -0
  1496. package/extensions/twitch/src/probe.test.ts +195 -0
  1497. package/extensions/twitch/src/probe.ts +120 -0
  1498. package/extensions/twitch/src/resolver.ts +137 -0
  1499. package/extensions/twitch/src/runtime.ts +14 -0
  1500. package/extensions/twitch/src/send.test.ts +289 -0
  1501. package/extensions/twitch/src/send.ts +136 -0
  1502. package/extensions/twitch/src/status.test.ts +270 -0
  1503. package/extensions/twitch/src/status.ts +178 -0
  1504. package/extensions/twitch/src/token.test.ts +171 -0
  1505. package/extensions/twitch/src/token.ts +91 -0
  1506. package/extensions/twitch/src/twitch-client.test.ts +589 -0
  1507. package/extensions/twitch/src/twitch-client.ts +277 -0
  1508. package/extensions/twitch/src/types.ts +141 -0
  1509. package/extensions/twitch/src/utils/markdown.ts +98 -0
  1510. package/extensions/twitch/src/utils/twitch.ts +78 -0
  1511. package/extensions/twitch/test/setup.ts +7 -0
  1512. package/extensions/voice-call/CHANGELOG.md +109 -0
  1513. package/extensions/voice-call/README.md +139 -0
  1514. package/extensions/voice-call/index.ts +493 -0
  1515. package/extensions/voice-call/node_modules/.bin/openclaw +21 -0
  1516. package/extensions/voice-call/openclaw.plugin.json +559 -0
  1517. package/extensions/voice-call/package.json +19 -0
  1518. package/extensions/voice-call/src/allowlist.ts +19 -0
  1519. package/extensions/voice-call/src/cli.ts +279 -0
  1520. package/extensions/voice-call/src/config.test.ts +234 -0
  1521. package/extensions/voice-call/src/config.ts +523 -0
  1522. package/extensions/voice-call/src/core-bridge.ts +159 -0
  1523. package/extensions/voice-call/src/manager/context.ts +21 -0
  1524. package/extensions/voice-call/src/manager/events.ts +188 -0
  1525. package/extensions/voice-call/src/manager/lookup.ts +35 -0
  1526. package/extensions/voice-call/src/manager/outbound.ts +275 -0
  1527. package/extensions/voice-call/src/manager/state.ts +48 -0
  1528. package/extensions/voice-call/src/manager/store.ts +91 -0
  1529. package/extensions/voice-call/src/manager/timers.ts +89 -0
  1530. package/extensions/voice-call/src/manager/twiml.ts +9 -0
  1531. package/extensions/voice-call/src/manager.test.ts +194 -0
  1532. package/extensions/voice-call/src/manager.ts +887 -0
  1533. package/extensions/voice-call/src/media-stream.test.ts +96 -0
  1534. package/extensions/voice-call/src/media-stream.ts +411 -0
  1535. package/extensions/voice-call/src/providers/base.ts +67 -0
  1536. package/extensions/voice-call/src/providers/index.ts +10 -0
  1537. package/extensions/voice-call/src/providers/mock.ts +165 -0
  1538. package/extensions/voice-call/src/providers/plivo.test.ts +27 -0
  1539. package/extensions/voice-call/src/providers/plivo.ts +515 -0
  1540. package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
  1541. package/extensions/voice-call/src/providers/telnyx.ts +371 -0
  1542. package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
  1543. package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
  1544. package/extensions/voice-call/src/providers/twilio/webhook.ts +32 -0
  1545. package/extensions/voice-call/src/providers/twilio.test.ts +60 -0
  1546. package/extensions/voice-call/src/providers/twilio.ts +626 -0
  1547. package/extensions/voice-call/src/response-generator.ts +158 -0
  1548. package/extensions/voice-call/src/runtime.ts +212 -0
  1549. package/extensions/voice-call/src/telephony-audio.ts +90 -0
  1550. package/extensions/voice-call/src/telephony-tts.ts +104 -0
  1551. package/extensions/voice-call/src/tunnel.ts +314 -0
  1552. package/extensions/voice-call/src/types.ts +272 -0
  1553. package/extensions/voice-call/src/utils.ts +14 -0
  1554. package/extensions/voice-call/src/voice-mapping.ts +67 -0
  1555. package/extensions/voice-call/src/webhook-security.test.ts +377 -0
  1556. package/extensions/voice-call/src/webhook-security.ts +689 -0
  1557. package/extensions/voice-call/src/webhook.ts +491 -0
  1558. package/extensions/whatsapp/index.ts +17 -0
  1559. package/extensions/whatsapp/node_modules/.bin/openclaw +21 -0
  1560. package/extensions/whatsapp/openclaw.plugin.json +9 -0
  1561. package/extensions/whatsapp/package.json +14 -0
  1562. package/extensions/whatsapp/src/channel.ts +508 -0
  1563. package/extensions/whatsapp/src/runtime.ts +14 -0
  1564. package/extensions/zalo/CHANGELOG.md +89 -0
  1565. package/extensions/zalo/README.md +50 -0
  1566. package/extensions/zalo/index.ts +19 -0
  1567. package/extensions/zalo/node_modules/.bin/openclaw +21 -0
  1568. package/extensions/zalo/openclaw.plugin.json +9 -0
  1569. package/extensions/zalo/package.json +36 -0
  1570. package/extensions/zalo/src/accounts.ts +80 -0
  1571. package/extensions/zalo/src/actions.ts +67 -0
  1572. package/extensions/zalo/src/api.ts +208 -0
  1573. package/extensions/zalo/src/channel.directory.test.ts +43 -0
  1574. package/extensions/zalo/src/channel.ts +414 -0
  1575. package/extensions/zalo/src/config-schema.ts +24 -0
  1576. package/extensions/zalo/src/monitor.ts +753 -0
  1577. package/extensions/zalo/src/monitor.webhook.test.ts +73 -0
  1578. package/extensions/zalo/src/onboarding.ts +401 -0
  1579. package/extensions/zalo/src/probe.ts +46 -0
  1580. package/extensions/zalo/src/proxy.ts +21 -0
  1581. package/extensions/zalo/src/runtime.ts +14 -0
  1582. package/extensions/zalo/src/send.ts +124 -0
  1583. package/extensions/zalo/src/status-issues.ts +53 -0
  1584. package/extensions/zalo/src/token.ts +63 -0
  1585. package/extensions/zalo/src/types.ts +42 -0
  1586. package/extensions/zalouser/CHANGELOG.md +61 -0
  1587. package/extensions/zalouser/README.md +225 -0
  1588. package/extensions/zalouser/index.ts +31 -0
  1589. package/extensions/zalouser/node_modules/.bin/openclaw +21 -0
  1590. package/extensions/zalouser/openclaw.plugin.json +9 -0
  1591. package/extensions/zalouser/package.json +36 -0
  1592. package/extensions/zalouser/src/accounts.ts +135 -0
  1593. package/extensions/zalouser/src/channel.test.ts +18 -0
  1594. package/extensions/zalouser/src/channel.ts +686 -0
  1595. package/extensions/zalouser/src/config-schema.ts +27 -0
  1596. package/extensions/zalouser/src/monitor.ts +590 -0
  1597. package/extensions/zalouser/src/onboarding.ts +504 -0
  1598. package/extensions/zalouser/src/probe.ts +28 -0
  1599. package/extensions/zalouser/src/runtime.ts +14 -0
  1600. package/extensions/zalouser/src/send.ts +160 -0
  1601. package/extensions/zalouser/src/status-issues.test.ts +57 -0
  1602. package/extensions/zalouser/src/status-issues.ts +89 -0
  1603. package/extensions/zalouser/src/tool.ts +164 -0
  1604. package/extensions/zalouser/src/types.ts +108 -0
  1605. package/extensions/zalouser/src/zca.ts +202 -0
  1606. package/openclaw.mjs +14 -0
  1607. package/package.json +245 -0
  1608. package/skills/1password/SKILL.md +70 -0
  1609. package/skills/1password/references/cli-examples.md +29 -0
  1610. package/skills/1password/references/get-started.md +17 -0
  1611. package/skills/apple-notes/SKILL.md +77 -0
  1612. package/skills/apple-reminders/SKILL.md +96 -0
  1613. package/skills/bear-notes/SKILL.md +107 -0
  1614. package/skills/bird/SKILL.md +224 -0
  1615. package/skills/blogwatcher/SKILL.md +69 -0
  1616. package/skills/blucli/SKILL.md +47 -0
  1617. package/skills/bluebubbles/SKILL.md +131 -0
  1618. package/skills/camsnap/SKILL.md +45 -0
  1619. package/skills/canvas/SKILL.md +198 -0
  1620. package/skills/clawhub/SKILL.md +77 -0
  1621. package/skills/coding-agent/SKILL.md +284 -0
  1622. package/skills/discord/SKILL.md +578 -0
  1623. package/skills/eightctl/SKILL.md +50 -0
  1624. package/skills/food-order/SKILL.md +48 -0
  1625. package/skills/gemini/SKILL.md +43 -0
  1626. package/skills/ghostly-projects/SKILL.md +160 -0
  1627. package/skills/gifgrep/SKILL.md +79 -0
  1628. package/skills/github/SKILL.md +77 -0
  1629. package/skills/gog/SKILL.md +116 -0
  1630. package/skills/goplaces/SKILL.md +52 -0
  1631. package/skills/healthcheck/SKILL.md +245 -0
  1632. package/skills/himalaya/SKILL.md +257 -0
  1633. package/skills/himalaya/references/configuration.md +184 -0
  1634. package/skills/himalaya/references/message-composition.md +199 -0
  1635. package/skills/imsg/SKILL.md +74 -0
  1636. package/skills/linear/SKILL.md +111 -0
  1637. package/skills/linear/linear.sh +204 -0
  1638. package/skills/local-places/SERVER_README.md +101 -0
  1639. package/skills/local-places/SKILL.md +102 -0
  1640. package/skills/local-places/pyproject.toml +21 -0
  1641. package/skills/local-places/src/local_places/__init__.py +2 -0
  1642. package/skills/local-places/src/local_places/google_places.py +314 -0
  1643. package/skills/local-places/src/local_places/main.py +65 -0
  1644. package/skills/local-places/src/local_places/schemas.py +107 -0
  1645. package/skills/mcporter/SKILL.md +61 -0
  1646. package/skills/model-usage/SKILL.md +69 -0
  1647. package/skills/model-usage/references/codexbar-cli.md +33 -0
  1648. package/skills/model-usage/scripts/model_usage.py +310 -0
  1649. package/skills/nano-banana-pro/SKILL.md +58 -0
  1650. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  1651. package/skills/nano-pdf/SKILL.md +38 -0
  1652. package/skills/notion/SKILL.md +172 -0
  1653. package/skills/obsidian/SKILL.md +81 -0
  1654. package/skills/openai-image-gen/SKILL.md +89 -0
  1655. package/skills/openai-image-gen/scripts/gen.py +240 -0
  1656. package/skills/openai-whisper/SKILL.md +38 -0
  1657. package/skills/openai-whisper-api/SKILL.md +52 -0
  1658. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  1659. package/skills/openhue/SKILL.md +51 -0
  1660. package/skills/oracle/SKILL.md +125 -0
  1661. package/skills/ordercli/SKILL.md +78 -0
  1662. package/skills/peekaboo/SKILL.md +190 -0
  1663. package/skills/sag/SKILL.md +87 -0
  1664. package/skills/session-logs/SKILL.md +115 -0
  1665. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  1666. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  1667. package/skills/skill-creator/SKILL.md +370 -0
  1668. package/skills/skill-creator/license.txt +202 -0
  1669. package/skills/skill-creator/scripts/init_skill.py +378 -0
  1670. package/skills/skill-creator/scripts/package_skill.py +111 -0
  1671. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  1672. package/skills/slack/SKILL.md +144 -0
  1673. package/skills/songsee/SKILL.md +49 -0
  1674. package/skills/sonoscli/SKILL.md +46 -0
  1675. package/skills/spotify-player/SKILL.md +64 -0
  1676. package/skills/summarize/SKILL.md +87 -0
  1677. package/skills/things-mac/SKILL.md +86 -0
  1678. package/skills/tmux/SKILL.md +135 -0
  1679. package/skills/tmux/scripts/find-sessions.sh +112 -0
  1680. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  1681. package/skills/trello/SKILL.md +95 -0
  1682. package/skills/video-frames/SKILL.md +46 -0
  1683. package/skills/video-frames/scripts/frame.sh +81 -0
  1684. package/skills/voice-call/SKILL.md +45 -0
  1685. package/skills/wacli/SKILL.md +72 -0
  1686. package/skills/weather/SKILL.md +54 -0
@@ -0,0 +1,2870 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
+ import { A as truncateUtf16Safe, D as sleep, g as clampNumber$1, h as clampInt, l as createSubsystemLogger, w as resolveUserPath } from "./exec-Cm9b2r9Q.js";
3
+ import { n as resolveAgentConfig, r as resolveAgentDir, s as resolveAgentWorkspaceDir } from "./agent-scope-DdwUKIOe.js";
4
+ import { s as resolveStateDir } from "./paths-BYpoyRv5.js";
5
+ import { H as isTruthyEnvValue, v as requireApiKey, y as resolveApiKeyForProvider } from "./model-selection-BgC1E1a7.js";
6
+ import { i as resolveSessionTranscriptsDirForAgent } from "./paths-DNQE-bvr.js";
7
+ import { n as onSessionTranscriptUpdate } from "./transcript-events-DGF257vD.js";
8
+ import { a as ensureDir, c as listMemoryFiles, i as cosineSimilarity, l as normalizeExtraMemoryPaths, n as buildFileEntry, o as hashText, r as chunkMarkdown, s as isMemoryPath, t as requireNodeSqlite, u as parseEmbedding } from "./sqlite-gCW7MlLs.js";
9
+ import os from "node:os";
10
+ import path from "node:path";
11
+ import fs from "node:fs";
12
+ import fs$1 from "node:fs/promises";
13
+ import { randomUUID } from "node:crypto";
14
+ import chokidar from "chokidar";
15
+
16
+ //#region src/infra/retry.ts
17
+ const DEFAULT_RETRY_CONFIG = {
18
+ attempts: 3,
19
+ minDelayMs: 300,
20
+ maxDelayMs: 3e4,
21
+ jitter: 0
22
+ };
23
+ const asFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
24
+ const clampNumber = (value, fallback, min, max) => {
25
+ const next = asFiniteNumber(value);
26
+ if (next === void 0) return fallback;
27
+ const floor = typeof min === "number" ? min : Number.NEGATIVE_INFINITY;
28
+ const ceiling = typeof max === "number" ? max : Number.POSITIVE_INFINITY;
29
+ return Math.min(Math.max(next, floor), ceiling);
30
+ };
31
+ function resolveRetryConfig(defaults = DEFAULT_RETRY_CONFIG, overrides) {
32
+ const attempts = Math.max(1, Math.round(clampNumber(overrides?.attempts, defaults.attempts, 1)));
33
+ const minDelayMs = Math.max(0, Math.round(clampNumber(overrides?.minDelayMs, defaults.minDelayMs, 0)));
34
+ return {
35
+ attempts,
36
+ minDelayMs,
37
+ maxDelayMs: Math.max(minDelayMs, Math.round(clampNumber(overrides?.maxDelayMs, defaults.maxDelayMs, 0))),
38
+ jitter: clampNumber(overrides?.jitter, defaults.jitter, 0, 1)
39
+ };
40
+ }
41
+ function applyJitter(delayMs, jitter) {
42
+ if (jitter <= 0) return delayMs;
43
+ const offset = (Math.random() * 2 - 1) * jitter;
44
+ return Math.max(0, Math.round(delayMs * (1 + offset)));
45
+ }
46
+ async function retryAsync(fn, attemptsOrOptions = 3, initialDelayMs = 300) {
47
+ if (typeof attemptsOrOptions === "number") {
48
+ const attempts = Math.max(1, Math.round(attemptsOrOptions));
49
+ let lastErr;
50
+ for (let i = 0; i < attempts; i += 1) try {
51
+ return await fn();
52
+ } catch (err) {
53
+ lastErr = err;
54
+ if (i === attempts - 1) break;
55
+ await sleep(initialDelayMs * 2 ** i);
56
+ }
57
+ throw lastErr ?? /* @__PURE__ */ new Error("Retry failed");
58
+ }
59
+ const options = attemptsOrOptions;
60
+ const resolved = resolveRetryConfig(DEFAULT_RETRY_CONFIG, options);
61
+ const maxAttempts = resolved.attempts;
62
+ const minDelayMs = resolved.minDelayMs;
63
+ const maxDelayMs = Number.isFinite(resolved.maxDelayMs) && resolved.maxDelayMs > 0 ? resolved.maxDelayMs : Number.POSITIVE_INFINITY;
64
+ const jitter = resolved.jitter;
65
+ const shouldRetry = options.shouldRetry ?? (() => true);
66
+ let lastErr;
67
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) try {
68
+ return await fn();
69
+ } catch (err) {
70
+ lastErr = err;
71
+ if (attempt >= maxAttempts || !shouldRetry(err, attempt)) break;
72
+ const retryAfterMs = options.retryAfterMs?.(err);
73
+ const baseDelay = typeof retryAfterMs === "number" && Number.isFinite(retryAfterMs) ? Math.max(retryAfterMs, minDelayMs) : minDelayMs * 2 ** (attempt - 1);
74
+ let delay = Math.min(baseDelay, maxDelayMs);
75
+ delay = applyJitter(delay, jitter);
76
+ delay = Math.min(Math.max(delay, minDelayMs), maxDelayMs);
77
+ options.onRetry?.({
78
+ attempt,
79
+ maxAttempts,
80
+ delayMs: delay,
81
+ err,
82
+ label: options.label
83
+ });
84
+ await sleep(delay);
85
+ }
86
+ throw lastErr ?? /* @__PURE__ */ new Error("Retry failed");
87
+ }
88
+
89
+ //#endregion
90
+ //#region src/agents/memory-search.ts
91
+ const DEFAULT_OPENAI_MODEL = "text-embedding-3-small";
92
+ const DEFAULT_GEMINI_MODEL = "gemini-embedding-001";
93
+ const DEFAULT_CHUNK_TOKENS = 400;
94
+ const DEFAULT_CHUNK_OVERLAP = 80;
95
+ const DEFAULT_WATCH_DEBOUNCE_MS = 1500;
96
+ const DEFAULT_SESSION_DELTA_BYTES = 1e5;
97
+ const DEFAULT_SESSION_DELTA_MESSAGES = 50;
98
+ const DEFAULT_MAX_RESULTS = 6;
99
+ const DEFAULT_MIN_SCORE = .35;
100
+ const DEFAULT_HYBRID_ENABLED = true;
101
+ const DEFAULT_HYBRID_VECTOR_WEIGHT = .7;
102
+ const DEFAULT_HYBRID_TEXT_WEIGHT = .3;
103
+ const DEFAULT_HYBRID_CANDIDATE_MULTIPLIER = 4;
104
+ const DEFAULT_CACHE_ENABLED = true;
105
+ const DEFAULT_SOURCES = ["memory"];
106
+ function normalizeSources(sources, sessionMemoryEnabled) {
107
+ const normalized = /* @__PURE__ */ new Set();
108
+ const input = sources?.length ? sources : DEFAULT_SOURCES;
109
+ for (const source of input) {
110
+ if (source === "memory") normalized.add("memory");
111
+ if (source === "sessions" && sessionMemoryEnabled) normalized.add("sessions");
112
+ }
113
+ if (normalized.size === 0) normalized.add("memory");
114
+ return Array.from(normalized);
115
+ }
116
+ function resolveStorePath(agentId, raw) {
117
+ const stateDir = resolveStateDir(process.env, os.homedir);
118
+ const fallback = path.join(stateDir, "memory", `${agentId}.sqlite`);
119
+ if (!raw) return fallback;
120
+ return resolveUserPath(raw.includes("{agentId}") ? raw.replaceAll("{agentId}", agentId) : raw);
121
+ }
122
+ function mergeConfig(defaults, overrides, agentId) {
123
+ const enabled = overrides?.enabled ?? defaults?.enabled ?? true;
124
+ const sessionMemory = overrides?.experimental?.sessionMemory ?? defaults?.experimental?.sessionMemory ?? false;
125
+ const provider = overrides?.provider ?? defaults?.provider ?? "auto";
126
+ const defaultRemote = defaults?.remote;
127
+ const overrideRemote = overrides?.remote;
128
+ const includeRemote = Boolean(overrideRemote?.baseUrl || overrideRemote?.apiKey || overrideRemote?.headers || defaultRemote?.baseUrl || defaultRemote?.apiKey || defaultRemote?.headers) || provider === "openai" || provider === "gemini" || provider === "auto";
129
+ const batch = {
130
+ enabled: overrideRemote?.batch?.enabled ?? defaultRemote?.batch?.enabled ?? true,
131
+ wait: overrideRemote?.batch?.wait ?? defaultRemote?.batch?.wait ?? true,
132
+ concurrency: Math.max(1, overrideRemote?.batch?.concurrency ?? defaultRemote?.batch?.concurrency ?? 2),
133
+ pollIntervalMs: overrideRemote?.batch?.pollIntervalMs ?? defaultRemote?.batch?.pollIntervalMs ?? 2e3,
134
+ timeoutMinutes: overrideRemote?.batch?.timeoutMinutes ?? defaultRemote?.batch?.timeoutMinutes ?? 60
135
+ };
136
+ const remote = includeRemote ? {
137
+ baseUrl: overrideRemote?.baseUrl ?? defaultRemote?.baseUrl,
138
+ apiKey: overrideRemote?.apiKey ?? defaultRemote?.apiKey,
139
+ headers: overrideRemote?.headers ?? defaultRemote?.headers,
140
+ batch
141
+ } : void 0;
142
+ const fallback = overrides?.fallback ?? defaults?.fallback ?? "none";
143
+ const modelDefault = provider === "gemini" ? DEFAULT_GEMINI_MODEL : provider === "openai" ? DEFAULT_OPENAI_MODEL : void 0;
144
+ const model = overrides?.model ?? defaults?.model ?? modelDefault ?? "";
145
+ const local = {
146
+ modelPath: overrides?.local?.modelPath ?? defaults?.local?.modelPath,
147
+ modelCacheDir: overrides?.local?.modelCacheDir ?? defaults?.local?.modelCacheDir
148
+ };
149
+ const sources = normalizeSources(overrides?.sources ?? defaults?.sources, sessionMemory);
150
+ const rawPaths = [...defaults?.extraPaths ?? [], ...overrides?.extraPaths ?? []].map((value) => value.trim()).filter(Boolean);
151
+ const extraPaths = Array.from(new Set(rawPaths));
152
+ const vector = {
153
+ enabled: overrides?.store?.vector?.enabled ?? defaults?.store?.vector?.enabled ?? true,
154
+ extensionPath: overrides?.store?.vector?.extensionPath ?? defaults?.store?.vector?.extensionPath
155
+ };
156
+ const store = {
157
+ driver: overrides?.store?.driver ?? defaults?.store?.driver ?? "sqlite",
158
+ path: resolveStorePath(agentId, overrides?.store?.path ?? defaults?.store?.path),
159
+ vector
160
+ };
161
+ const chunking = {
162
+ tokens: overrides?.chunking?.tokens ?? defaults?.chunking?.tokens ?? DEFAULT_CHUNK_TOKENS,
163
+ overlap: overrides?.chunking?.overlap ?? defaults?.chunking?.overlap ?? DEFAULT_CHUNK_OVERLAP
164
+ };
165
+ const sync = {
166
+ onSessionStart: overrides?.sync?.onSessionStart ?? defaults?.sync?.onSessionStart ?? true,
167
+ onSearch: overrides?.sync?.onSearch ?? defaults?.sync?.onSearch ?? true,
168
+ watch: overrides?.sync?.watch ?? defaults?.sync?.watch ?? true,
169
+ watchDebounceMs: overrides?.sync?.watchDebounceMs ?? defaults?.sync?.watchDebounceMs ?? DEFAULT_WATCH_DEBOUNCE_MS,
170
+ intervalMinutes: overrides?.sync?.intervalMinutes ?? defaults?.sync?.intervalMinutes ?? 0,
171
+ sessions: {
172
+ deltaBytes: overrides?.sync?.sessions?.deltaBytes ?? defaults?.sync?.sessions?.deltaBytes ?? DEFAULT_SESSION_DELTA_BYTES,
173
+ deltaMessages: overrides?.sync?.sessions?.deltaMessages ?? defaults?.sync?.sessions?.deltaMessages ?? DEFAULT_SESSION_DELTA_MESSAGES
174
+ }
175
+ };
176
+ const query = {
177
+ maxResults: overrides?.query?.maxResults ?? defaults?.query?.maxResults ?? DEFAULT_MAX_RESULTS,
178
+ minScore: overrides?.query?.minScore ?? defaults?.query?.minScore ?? DEFAULT_MIN_SCORE
179
+ };
180
+ const hybrid = {
181
+ enabled: overrides?.query?.hybrid?.enabled ?? defaults?.query?.hybrid?.enabled ?? DEFAULT_HYBRID_ENABLED,
182
+ vectorWeight: overrides?.query?.hybrid?.vectorWeight ?? defaults?.query?.hybrid?.vectorWeight ?? DEFAULT_HYBRID_VECTOR_WEIGHT,
183
+ textWeight: overrides?.query?.hybrid?.textWeight ?? defaults?.query?.hybrid?.textWeight ?? DEFAULT_HYBRID_TEXT_WEIGHT,
184
+ candidateMultiplier: overrides?.query?.hybrid?.candidateMultiplier ?? defaults?.query?.hybrid?.candidateMultiplier ?? DEFAULT_HYBRID_CANDIDATE_MULTIPLIER
185
+ };
186
+ const cache = {
187
+ enabled: overrides?.cache?.enabled ?? defaults?.cache?.enabled ?? DEFAULT_CACHE_ENABLED,
188
+ maxEntries: overrides?.cache?.maxEntries ?? defaults?.cache?.maxEntries
189
+ };
190
+ const overlap = clampNumber$1(chunking.overlap, 0, Math.max(0, chunking.tokens - 1));
191
+ const minScore = clampNumber$1(query.minScore, 0, 1);
192
+ const vectorWeight = clampNumber$1(hybrid.vectorWeight, 0, 1);
193
+ const textWeight = clampNumber$1(hybrid.textWeight, 0, 1);
194
+ const sum = vectorWeight + textWeight;
195
+ const normalizedVectorWeight = sum > 0 ? vectorWeight / sum : DEFAULT_HYBRID_VECTOR_WEIGHT;
196
+ const normalizedTextWeight = sum > 0 ? textWeight / sum : DEFAULT_HYBRID_TEXT_WEIGHT;
197
+ const candidateMultiplier = clampInt(hybrid.candidateMultiplier, 1, 20);
198
+ const deltaBytes = clampInt(sync.sessions.deltaBytes, 0, Number.MAX_SAFE_INTEGER);
199
+ const deltaMessages = clampInt(sync.sessions.deltaMessages, 0, Number.MAX_SAFE_INTEGER);
200
+ return {
201
+ enabled,
202
+ sources,
203
+ extraPaths,
204
+ provider,
205
+ remote,
206
+ experimental: { sessionMemory },
207
+ fallback,
208
+ model,
209
+ local,
210
+ store,
211
+ chunking: {
212
+ tokens: Math.max(1, chunking.tokens),
213
+ overlap
214
+ },
215
+ sync: {
216
+ ...sync,
217
+ sessions: {
218
+ deltaBytes,
219
+ deltaMessages
220
+ }
221
+ },
222
+ query: {
223
+ ...query,
224
+ minScore,
225
+ hybrid: {
226
+ enabled: Boolean(hybrid.enabled),
227
+ vectorWeight: normalizedVectorWeight,
228
+ textWeight: normalizedTextWeight,
229
+ candidateMultiplier
230
+ }
231
+ },
232
+ cache: {
233
+ enabled: Boolean(cache.enabled),
234
+ maxEntries: typeof cache.maxEntries === "number" && Number.isFinite(cache.maxEntries) ? Math.max(1, Math.floor(cache.maxEntries)) : void 0
235
+ }
236
+ };
237
+ }
238
+ function resolveMemorySearchConfig(cfg, agentId) {
239
+ const defaults = cfg.agents?.defaults?.memorySearch;
240
+ const overrides = resolveAgentConfig(cfg, agentId)?.memorySearch;
241
+ const resolved = mergeConfig(defaults, overrides, agentId);
242
+ if (!resolved.enabled) return null;
243
+ return resolved;
244
+ }
245
+
246
+ //#endregion
247
+ //#region src/memory/batch-gemini.ts
248
+ const GEMINI_BATCH_MAX_REQUESTS = 5e4;
249
+ const debugEmbeddings$1 = isTruthyEnvValue(process.env.OPENCLAW_DEBUG_MEMORY_EMBEDDINGS);
250
+ const log$2 = createSubsystemLogger("memory/embeddings");
251
+ const debugLog$1 = (message, meta) => {
252
+ if (!debugEmbeddings$1) return;
253
+ const suffix = meta ? ` ${JSON.stringify(meta)}` : "";
254
+ log$2.raw(`${message}${suffix}`);
255
+ };
256
+ function getGeminiBaseUrl(gemini) {
257
+ return gemini.baseUrl?.replace(/\/$/, "") ?? "";
258
+ }
259
+ function getGeminiHeaders(gemini, params) {
260
+ const headers = gemini.headers ? { ...gemini.headers } : {};
261
+ if (params.json) {
262
+ if (!headers["Content-Type"] && !headers["content-type"]) headers["Content-Type"] = "application/json";
263
+ } else {
264
+ delete headers["Content-Type"];
265
+ delete headers["content-type"];
266
+ }
267
+ return headers;
268
+ }
269
+ function getGeminiUploadUrl(baseUrl) {
270
+ if (baseUrl.includes("/v1beta")) return baseUrl.replace(/\/v1beta\/?$/, "/upload/v1beta");
271
+ return `${baseUrl.replace(/\/$/, "")}/upload`;
272
+ }
273
+ function splitGeminiBatchRequests(requests) {
274
+ if (requests.length <= GEMINI_BATCH_MAX_REQUESTS) return [requests];
275
+ const groups = [];
276
+ for (let i = 0; i < requests.length; i += GEMINI_BATCH_MAX_REQUESTS) groups.push(requests.slice(i, i + GEMINI_BATCH_MAX_REQUESTS));
277
+ return groups;
278
+ }
279
+ function buildGeminiUploadBody(params) {
280
+ const boundary = `openclaw-${hashText(params.displayName)}`;
281
+ const jsonPart = JSON.stringify({ file: {
282
+ displayName: params.displayName,
283
+ mimeType: "application/jsonl"
284
+ } });
285
+ const delimiter = `--${boundary}\r\n`;
286
+ const closeDelimiter = `--${boundary}--\r\n`;
287
+ const parts = [
288
+ `${delimiter}Content-Type: application/json; charset=UTF-8\r\n\r\n${jsonPart}\r\n`,
289
+ `${delimiter}Content-Type: application/jsonl; charset=UTF-8\r\n\r\n${params.jsonl}\r\n`,
290
+ closeDelimiter
291
+ ];
292
+ return {
293
+ body: new Blob([parts.join("")], { type: "multipart/related" }),
294
+ contentType: `multipart/related; boundary=${boundary}`
295
+ };
296
+ }
297
+ async function submitGeminiBatch(params) {
298
+ const baseUrl = getGeminiBaseUrl(params.gemini);
299
+ const uploadPayload = buildGeminiUploadBody({
300
+ jsonl: params.requests.map((request) => JSON.stringify({
301
+ key: request.custom_id,
302
+ request: {
303
+ content: request.content,
304
+ task_type: request.taskType
305
+ }
306
+ })).join("\n"),
307
+ displayName: `memory-embeddings-${hashText(String(Date.now()))}`
308
+ });
309
+ const uploadUrl = `${getGeminiUploadUrl(baseUrl)}/files?uploadType=multipart`;
310
+ debugLog$1("memory embeddings: gemini batch upload", {
311
+ uploadUrl,
312
+ baseUrl,
313
+ requests: params.requests.length
314
+ });
315
+ const fileRes = await fetch(uploadUrl, {
316
+ method: "POST",
317
+ headers: {
318
+ ...getGeminiHeaders(params.gemini, { json: false }),
319
+ "Content-Type": uploadPayload.contentType
320
+ },
321
+ body: uploadPayload.body
322
+ });
323
+ if (!fileRes.ok) {
324
+ const text = await fileRes.text();
325
+ throw new Error(`gemini batch file upload failed: ${fileRes.status} ${text}`);
326
+ }
327
+ const filePayload = await fileRes.json();
328
+ const fileId = filePayload.name ?? filePayload.file?.name;
329
+ if (!fileId) throw new Error("gemini batch file upload failed: missing file id");
330
+ const batchBody = { batch: {
331
+ displayName: `memory-embeddings-${params.agentId}`,
332
+ inputConfig: { file_name: fileId }
333
+ } };
334
+ const batchEndpoint = `${baseUrl}/${params.gemini.modelPath}:asyncBatchEmbedContent`;
335
+ debugLog$1("memory embeddings: gemini batch create", {
336
+ batchEndpoint,
337
+ fileId
338
+ });
339
+ const batchRes = await fetch(batchEndpoint, {
340
+ method: "POST",
341
+ headers: getGeminiHeaders(params.gemini, { json: true }),
342
+ body: JSON.stringify(batchBody)
343
+ });
344
+ if (batchRes.ok) return await batchRes.json();
345
+ const text = await batchRes.text();
346
+ if (batchRes.status === 404) throw new Error("gemini batch create failed: 404 (asyncBatchEmbedContent not available for this model/baseUrl). Disable remote.batch.enabled or switch providers.");
347
+ throw new Error(`gemini batch create failed: ${batchRes.status} ${text}`);
348
+ }
349
+ async function fetchGeminiBatchStatus(params) {
350
+ const statusUrl = `${getGeminiBaseUrl(params.gemini)}/${params.batchName.startsWith("batches/") ? params.batchName : `batches/${params.batchName}`}`;
351
+ debugLog$1("memory embeddings: gemini batch status", { statusUrl });
352
+ const res = await fetch(statusUrl, { headers: getGeminiHeaders(params.gemini, { json: true }) });
353
+ if (!res.ok) {
354
+ const text = await res.text();
355
+ throw new Error(`gemini batch status failed: ${res.status} ${text}`);
356
+ }
357
+ return await res.json();
358
+ }
359
+ async function fetchGeminiFileContent(params) {
360
+ const downloadUrl = `${getGeminiBaseUrl(params.gemini)}/${params.fileId.startsWith("files/") ? params.fileId : `files/${params.fileId}`}:download`;
361
+ debugLog$1("memory embeddings: gemini batch download", { downloadUrl });
362
+ const res = await fetch(downloadUrl, { headers: getGeminiHeaders(params.gemini, { json: true }) });
363
+ if (!res.ok) {
364
+ const text = await res.text();
365
+ throw new Error(`gemini batch file content failed: ${res.status} ${text}`);
366
+ }
367
+ return await res.text();
368
+ }
369
+ function parseGeminiBatchOutput(text) {
370
+ if (!text.trim()) return [];
371
+ return text.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => JSON.parse(line));
372
+ }
373
+ async function waitForGeminiBatch(params) {
374
+ const start = Date.now();
375
+ let current = params.initial;
376
+ while (true) {
377
+ const status = current ?? await fetchGeminiBatchStatus({
378
+ gemini: params.gemini,
379
+ batchName: params.batchName
380
+ });
381
+ const state = status.state ?? "UNKNOWN";
382
+ if ([
383
+ "SUCCEEDED",
384
+ "COMPLETED",
385
+ "DONE"
386
+ ].includes(state)) {
387
+ const outputFileId = status.outputConfig?.file ?? status.outputConfig?.fileId ?? status.metadata?.output?.responsesFile;
388
+ if (!outputFileId) throw new Error(`gemini batch ${params.batchName} completed without output file`);
389
+ return { outputFileId };
390
+ }
391
+ if ([
392
+ "FAILED",
393
+ "CANCELLED",
394
+ "CANCELED",
395
+ "EXPIRED"
396
+ ].includes(state)) {
397
+ const message = status.error?.message ?? "unknown error";
398
+ throw new Error(`gemini batch ${params.batchName} ${state}: ${message}`);
399
+ }
400
+ if (!params.wait) throw new Error(`gemini batch ${params.batchName} still ${state}; wait disabled`);
401
+ if (Date.now() - start > params.timeoutMs) throw new Error(`gemini batch ${params.batchName} timed out after ${params.timeoutMs}ms`);
402
+ params.debug?.(`gemini batch ${params.batchName} ${state}; waiting ${params.pollIntervalMs}ms`);
403
+ await new Promise((resolve) => setTimeout(resolve, params.pollIntervalMs));
404
+ current = void 0;
405
+ }
406
+ }
407
+ async function runWithConcurrency$1(tasks, limit) {
408
+ if (tasks.length === 0) return [];
409
+ const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
410
+ const results = Array.from({ length: tasks.length });
411
+ let next = 0;
412
+ let firstError = null;
413
+ const workers = Array.from({ length: resolvedLimit }, async () => {
414
+ while (true) {
415
+ if (firstError) return;
416
+ const index = next;
417
+ next += 1;
418
+ if (index >= tasks.length) return;
419
+ try {
420
+ results[index] = await tasks[index]();
421
+ } catch (err) {
422
+ firstError = err;
423
+ return;
424
+ }
425
+ }
426
+ });
427
+ await Promise.allSettled(workers);
428
+ if (firstError) throw firstError;
429
+ return results;
430
+ }
431
+ async function runGeminiEmbeddingBatches(params) {
432
+ if (params.requests.length === 0) return /* @__PURE__ */ new Map();
433
+ const groups = splitGeminiBatchRequests(params.requests);
434
+ const byCustomId = /* @__PURE__ */ new Map();
435
+ const tasks = groups.map((group, groupIndex) => async () => {
436
+ const batchInfo = await submitGeminiBatch({
437
+ gemini: params.gemini,
438
+ requests: group,
439
+ agentId: params.agentId
440
+ });
441
+ const batchName = batchInfo.name ?? "";
442
+ if (!batchName) throw new Error("gemini batch create failed: missing batch name");
443
+ params.debug?.("memory embeddings: gemini batch created", {
444
+ batchName,
445
+ state: batchInfo.state,
446
+ group: groupIndex + 1,
447
+ groups: groups.length,
448
+ requests: group.length
449
+ });
450
+ if (!params.wait && batchInfo.state && ![
451
+ "SUCCEEDED",
452
+ "COMPLETED",
453
+ "DONE"
454
+ ].includes(batchInfo.state)) throw new Error(`gemini batch ${batchName} submitted; enable remote.batch.wait to await completion`);
455
+ const completed = batchInfo.state && [
456
+ "SUCCEEDED",
457
+ "COMPLETED",
458
+ "DONE"
459
+ ].includes(batchInfo.state) ? { outputFileId: batchInfo.outputConfig?.file ?? batchInfo.outputConfig?.fileId ?? batchInfo.metadata?.output?.responsesFile ?? "" } : await waitForGeminiBatch({
460
+ gemini: params.gemini,
461
+ batchName,
462
+ wait: params.wait,
463
+ pollIntervalMs: params.pollIntervalMs,
464
+ timeoutMs: params.timeoutMs,
465
+ debug: params.debug,
466
+ initial: batchInfo
467
+ });
468
+ if (!completed.outputFileId) throw new Error(`gemini batch ${batchName} completed without output file`);
469
+ const outputLines = parseGeminiBatchOutput(await fetchGeminiFileContent({
470
+ gemini: params.gemini,
471
+ fileId: completed.outputFileId
472
+ }));
473
+ const errors = [];
474
+ const remaining = new Set(group.map((request) => request.custom_id));
475
+ for (const line of outputLines) {
476
+ const customId = line.key ?? line.custom_id ?? line.request_id;
477
+ if (!customId) continue;
478
+ remaining.delete(customId);
479
+ if (line.error?.message) {
480
+ errors.push(`${customId}: ${line.error.message}`);
481
+ continue;
482
+ }
483
+ if (line.response?.error?.message) {
484
+ errors.push(`${customId}: ${line.response.error.message}`);
485
+ continue;
486
+ }
487
+ const embedding = line.embedding?.values ?? line.response?.embedding?.values ?? [];
488
+ if (embedding.length === 0) {
489
+ errors.push(`${customId}: empty embedding`);
490
+ continue;
491
+ }
492
+ byCustomId.set(customId, embedding);
493
+ }
494
+ if (errors.length > 0) throw new Error(`gemini batch ${batchName} failed: ${errors.join("; ")}`);
495
+ if (remaining.size > 0) throw new Error(`gemini batch ${batchName} missing ${remaining.size} embedding responses`);
496
+ });
497
+ params.debug?.("memory embeddings: gemini batch submit", {
498
+ requests: params.requests.length,
499
+ groups: groups.length,
500
+ wait: params.wait,
501
+ concurrency: params.concurrency,
502
+ pollIntervalMs: params.pollIntervalMs,
503
+ timeoutMs: params.timeoutMs
504
+ });
505
+ await runWithConcurrency$1(tasks, params.concurrency);
506
+ return byCustomId;
507
+ }
508
+
509
+ //#endregion
510
+ //#region src/memory/batch-openai.ts
511
+ const OPENAI_BATCH_ENDPOINT = "/v1/embeddings";
512
+ const OPENAI_BATCH_COMPLETION_WINDOW = "24h";
513
+ const OPENAI_BATCH_MAX_REQUESTS = 5e4;
514
+ function getOpenAiBaseUrl(openAi) {
515
+ return openAi.baseUrl?.replace(/\/$/, "") ?? "";
516
+ }
517
+ function getOpenAiHeaders(openAi, params) {
518
+ const headers = openAi.headers ? { ...openAi.headers } : {};
519
+ if (params.json) {
520
+ if (!headers["Content-Type"] && !headers["content-type"]) headers["Content-Type"] = "application/json";
521
+ } else {
522
+ delete headers["Content-Type"];
523
+ delete headers["content-type"];
524
+ }
525
+ return headers;
526
+ }
527
+ function splitOpenAiBatchRequests(requests) {
528
+ if (requests.length <= OPENAI_BATCH_MAX_REQUESTS) return [requests];
529
+ const groups = [];
530
+ for (let i = 0; i < requests.length; i += OPENAI_BATCH_MAX_REQUESTS) groups.push(requests.slice(i, i + OPENAI_BATCH_MAX_REQUESTS));
531
+ return groups;
532
+ }
533
+ async function submitOpenAiBatch(params) {
534
+ const baseUrl = getOpenAiBaseUrl(params.openAi);
535
+ const jsonl = params.requests.map((request) => JSON.stringify(request)).join("\n");
536
+ const form = new FormData();
537
+ form.append("purpose", "batch");
538
+ form.append("file", new Blob([jsonl], { type: "application/jsonl" }), `memory-embeddings.${hashText(String(Date.now()))}.jsonl`);
539
+ const fileRes = await fetch(`${baseUrl}/files`, {
540
+ method: "POST",
541
+ headers: getOpenAiHeaders(params.openAi, { json: false }),
542
+ body: form
543
+ });
544
+ if (!fileRes.ok) {
545
+ const text = await fileRes.text();
546
+ throw new Error(`openai batch file upload failed: ${fileRes.status} ${text}`);
547
+ }
548
+ const filePayload = await fileRes.json();
549
+ if (!filePayload.id) throw new Error("openai batch file upload failed: missing file id");
550
+ return await (await retryAsync(async () => {
551
+ const res = await fetch(`${baseUrl}/batches`, {
552
+ method: "POST",
553
+ headers: getOpenAiHeaders(params.openAi, { json: true }),
554
+ body: JSON.stringify({
555
+ input_file_id: filePayload.id,
556
+ endpoint: OPENAI_BATCH_ENDPOINT,
557
+ completion_window: OPENAI_BATCH_COMPLETION_WINDOW,
558
+ metadata: {
559
+ source: "openclaw-memory",
560
+ agent: params.agentId
561
+ }
562
+ })
563
+ });
564
+ if (!res.ok) {
565
+ const text = await res.text();
566
+ const err = /* @__PURE__ */ new Error(`openai batch create failed: ${res.status} ${text}`);
567
+ err.status = res.status;
568
+ throw err;
569
+ }
570
+ return res;
571
+ }, {
572
+ attempts: 3,
573
+ minDelayMs: 300,
574
+ maxDelayMs: 2e3,
575
+ jitter: .2,
576
+ shouldRetry: (err) => {
577
+ const status = err.status;
578
+ return status === 429 || typeof status === "number" && status >= 500;
579
+ }
580
+ })).json();
581
+ }
582
+ async function fetchOpenAiBatchStatus(params) {
583
+ const baseUrl = getOpenAiBaseUrl(params.openAi);
584
+ const res = await fetch(`${baseUrl}/batches/${params.batchId}`, { headers: getOpenAiHeaders(params.openAi, { json: true }) });
585
+ if (!res.ok) {
586
+ const text = await res.text();
587
+ throw new Error(`openai batch status failed: ${res.status} ${text}`);
588
+ }
589
+ return await res.json();
590
+ }
591
+ async function fetchOpenAiFileContent(params) {
592
+ const baseUrl = getOpenAiBaseUrl(params.openAi);
593
+ const res = await fetch(`${baseUrl}/files/${params.fileId}/content`, { headers: getOpenAiHeaders(params.openAi, { json: true }) });
594
+ if (!res.ok) {
595
+ const text = await res.text();
596
+ throw new Error(`openai batch file content failed: ${res.status} ${text}`);
597
+ }
598
+ return await res.text();
599
+ }
600
+ function parseOpenAiBatchOutput(text) {
601
+ if (!text.trim()) return [];
602
+ return text.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => JSON.parse(line));
603
+ }
604
+ async function readOpenAiBatchError(params) {
605
+ try {
606
+ const first = parseOpenAiBatchOutput(await fetchOpenAiFileContent({
607
+ openAi: params.openAi,
608
+ fileId: params.errorFileId
609
+ })).find((line) => line.error?.message || line.response?.body?.error);
610
+ return first?.error?.message ?? (typeof first?.response?.body?.error?.message === "string" ? first?.response?.body?.error?.message : void 0);
611
+ } catch (err) {
612
+ const message = err instanceof Error ? err.message : String(err);
613
+ return message ? `error file unavailable: ${message}` : void 0;
614
+ }
615
+ }
616
+ async function waitForOpenAiBatch(params) {
617
+ const start = Date.now();
618
+ let current = params.initial;
619
+ while (true) {
620
+ const status = current ?? await fetchOpenAiBatchStatus({
621
+ openAi: params.openAi,
622
+ batchId: params.batchId
623
+ });
624
+ const state = status.status ?? "unknown";
625
+ if (state === "completed") {
626
+ if (!status.output_file_id) throw new Error(`openai batch ${params.batchId} completed without output file`);
627
+ return {
628
+ outputFileId: status.output_file_id,
629
+ errorFileId: status.error_file_id ?? void 0
630
+ };
631
+ }
632
+ if ([
633
+ "failed",
634
+ "expired",
635
+ "cancelled",
636
+ "canceled"
637
+ ].includes(state)) {
638
+ const detail = status.error_file_id ? await readOpenAiBatchError({
639
+ openAi: params.openAi,
640
+ errorFileId: status.error_file_id
641
+ }) : void 0;
642
+ const suffix = detail ? `: ${detail}` : "";
643
+ throw new Error(`openai batch ${params.batchId} ${state}${suffix}`);
644
+ }
645
+ if (!params.wait) throw new Error(`openai batch ${params.batchId} still ${state}; wait disabled`);
646
+ if (Date.now() - start > params.timeoutMs) throw new Error(`openai batch ${params.batchId} timed out after ${params.timeoutMs}ms`);
647
+ params.debug?.(`openai batch ${params.batchId} ${state}; waiting ${params.pollIntervalMs}ms`);
648
+ await new Promise((resolve) => setTimeout(resolve, params.pollIntervalMs));
649
+ current = void 0;
650
+ }
651
+ }
652
+ async function runWithConcurrency(tasks, limit) {
653
+ if (tasks.length === 0) return [];
654
+ const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
655
+ const results = Array.from({ length: tasks.length });
656
+ let next = 0;
657
+ let firstError = null;
658
+ const workers = Array.from({ length: resolvedLimit }, async () => {
659
+ while (true) {
660
+ if (firstError) return;
661
+ const index = next;
662
+ next += 1;
663
+ if (index >= tasks.length) return;
664
+ try {
665
+ results[index] = await tasks[index]();
666
+ } catch (err) {
667
+ firstError = err;
668
+ return;
669
+ }
670
+ }
671
+ });
672
+ await Promise.allSettled(workers);
673
+ if (firstError) throw firstError;
674
+ return results;
675
+ }
676
+ async function runOpenAiEmbeddingBatches(params) {
677
+ if (params.requests.length === 0) return /* @__PURE__ */ new Map();
678
+ const groups = splitOpenAiBatchRequests(params.requests);
679
+ const byCustomId = /* @__PURE__ */ new Map();
680
+ const tasks = groups.map((group, groupIndex) => async () => {
681
+ const batchInfo = await submitOpenAiBatch({
682
+ openAi: params.openAi,
683
+ requests: group,
684
+ agentId: params.agentId
685
+ });
686
+ if (!batchInfo.id) throw new Error("openai batch create failed: missing batch id");
687
+ params.debug?.("memory embeddings: openai batch created", {
688
+ batchId: batchInfo.id,
689
+ status: batchInfo.status,
690
+ group: groupIndex + 1,
691
+ groups: groups.length,
692
+ requests: group.length
693
+ });
694
+ if (!params.wait && batchInfo.status !== "completed") throw new Error(`openai batch ${batchInfo.id} submitted; enable remote.batch.wait to await completion`);
695
+ const completed = batchInfo.status === "completed" ? {
696
+ outputFileId: batchInfo.output_file_id ?? "",
697
+ errorFileId: batchInfo.error_file_id ?? void 0
698
+ } : await waitForOpenAiBatch({
699
+ openAi: params.openAi,
700
+ batchId: batchInfo.id,
701
+ wait: params.wait,
702
+ pollIntervalMs: params.pollIntervalMs,
703
+ timeoutMs: params.timeoutMs,
704
+ debug: params.debug,
705
+ initial: batchInfo
706
+ });
707
+ if (!completed.outputFileId) throw new Error(`openai batch ${batchInfo.id} completed without output file`);
708
+ const outputLines = parseOpenAiBatchOutput(await fetchOpenAiFileContent({
709
+ openAi: params.openAi,
710
+ fileId: completed.outputFileId
711
+ }));
712
+ const errors = [];
713
+ const remaining = new Set(group.map((request) => request.custom_id));
714
+ for (const line of outputLines) {
715
+ const customId = line.custom_id;
716
+ if (!customId) continue;
717
+ remaining.delete(customId);
718
+ if (line.error?.message) {
719
+ errors.push(`${customId}: ${line.error.message}`);
720
+ continue;
721
+ }
722
+ const response = line.response;
723
+ if ((response?.status_code ?? 0) >= 400) {
724
+ const message = response?.body?.error?.message ?? (typeof response?.body === "string" ? response.body : void 0) ?? "unknown error";
725
+ errors.push(`${customId}: ${message}`);
726
+ continue;
727
+ }
728
+ const embedding = (response?.body?.data ?? [])[0]?.embedding ?? [];
729
+ if (embedding.length === 0) {
730
+ errors.push(`${customId}: empty embedding`);
731
+ continue;
732
+ }
733
+ byCustomId.set(customId, embedding);
734
+ }
735
+ if (errors.length > 0) throw new Error(`openai batch ${batchInfo.id} failed: ${errors.join("; ")}`);
736
+ if (remaining.size > 0) throw new Error(`openai batch ${batchInfo.id} missing ${remaining.size} embedding responses`);
737
+ });
738
+ params.debug?.("memory embeddings: openai batch submit", {
739
+ requests: params.requests.length,
740
+ groups: groups.length,
741
+ wait: params.wait,
742
+ concurrency: params.concurrency,
743
+ pollIntervalMs: params.pollIntervalMs,
744
+ timeoutMs: params.timeoutMs
745
+ });
746
+ await runWithConcurrency(tasks, params.concurrency);
747
+ return byCustomId;
748
+ }
749
+
750
+ //#endregion
751
+ //#region src/memory/embeddings-gemini.ts
752
+ const DEFAULT_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
753
+ const DEFAULT_GEMINI_EMBEDDING_MODEL = "gemini-embedding-001";
754
+ const debugEmbeddings = isTruthyEnvValue(process.env.OPENCLAW_DEBUG_MEMORY_EMBEDDINGS);
755
+ const log$1 = createSubsystemLogger("memory/embeddings");
756
+ const debugLog = (message, meta) => {
757
+ if (!debugEmbeddings) return;
758
+ const suffix = meta ? ` ${JSON.stringify(meta)}` : "";
759
+ log$1.raw(`${message}${suffix}`);
760
+ };
761
+ function resolveRemoteApiKey(remoteApiKey) {
762
+ const trimmed = remoteApiKey?.trim();
763
+ if (!trimmed) return;
764
+ if (trimmed === "GOOGLE_API_KEY" || trimmed === "GEMINI_API_KEY") return process.env[trimmed]?.trim();
765
+ return trimmed;
766
+ }
767
+ function normalizeGeminiModel(model) {
768
+ const trimmed = model.trim();
769
+ if (!trimmed) return DEFAULT_GEMINI_EMBEDDING_MODEL;
770
+ const withoutPrefix = trimmed.replace(/^models\//, "");
771
+ if (withoutPrefix.startsWith("gemini/")) return withoutPrefix.slice(7);
772
+ if (withoutPrefix.startsWith("google/")) return withoutPrefix.slice(7);
773
+ return withoutPrefix;
774
+ }
775
+ function normalizeGeminiBaseUrl(raw) {
776
+ const trimmed = raw.replace(/\/+$/, "");
777
+ const openAiIndex = trimmed.indexOf("/openai");
778
+ if (openAiIndex > -1) return trimmed.slice(0, openAiIndex);
779
+ return trimmed;
780
+ }
781
+ function buildGeminiModelPath(model) {
782
+ return model.startsWith("models/") ? model : `models/${model}`;
783
+ }
784
+ async function createGeminiEmbeddingProvider(options) {
785
+ const client = await resolveGeminiEmbeddingClient(options);
786
+ const baseUrl = client.baseUrl.replace(/\/$/, "");
787
+ const embedUrl = `${baseUrl}/${client.modelPath}:embedContent`;
788
+ const batchUrl = `${baseUrl}/${client.modelPath}:batchEmbedContents`;
789
+ const embedQuery = async (text) => {
790
+ if (!text.trim()) return [];
791
+ const res = await fetch(embedUrl, {
792
+ method: "POST",
793
+ headers: client.headers,
794
+ body: JSON.stringify({
795
+ content: { parts: [{ text }] },
796
+ taskType: "RETRIEVAL_QUERY"
797
+ })
798
+ });
799
+ if (!res.ok) {
800
+ const payload = await res.text();
801
+ throw new Error(`gemini embeddings failed: ${res.status} ${payload}`);
802
+ }
803
+ return (await res.json()).embedding?.values ?? [];
804
+ };
805
+ const embedBatch = async (texts) => {
806
+ if (texts.length === 0) return [];
807
+ const requests = texts.map((text) => ({
808
+ model: client.modelPath,
809
+ content: { parts: [{ text }] },
810
+ taskType: "RETRIEVAL_DOCUMENT"
811
+ }));
812
+ const res = await fetch(batchUrl, {
813
+ method: "POST",
814
+ headers: client.headers,
815
+ body: JSON.stringify({ requests })
816
+ });
817
+ if (!res.ok) {
818
+ const payload = await res.text();
819
+ throw new Error(`gemini embeddings failed: ${res.status} ${payload}`);
820
+ }
821
+ const payload = await res.json();
822
+ const embeddings = Array.isArray(payload.embeddings) ? payload.embeddings : [];
823
+ return texts.map((_, index) => embeddings[index]?.values ?? []);
824
+ };
825
+ return {
826
+ provider: {
827
+ id: "gemini",
828
+ model: client.model,
829
+ embedQuery,
830
+ embedBatch
831
+ },
832
+ client
833
+ };
834
+ }
835
+ async function resolveGeminiEmbeddingClient(options) {
836
+ const remote = options.remote;
837
+ const remoteApiKey = resolveRemoteApiKey(remote?.apiKey);
838
+ const remoteBaseUrl = remote?.baseUrl?.trim();
839
+ const apiKey = remoteApiKey ? remoteApiKey : requireApiKey(await resolveApiKeyForProvider({
840
+ provider: "google",
841
+ cfg: options.config,
842
+ agentDir: options.agentDir
843
+ }), "google");
844
+ const providerConfig = options.config.models?.providers?.google;
845
+ const rawBaseUrl = remoteBaseUrl || providerConfig?.baseUrl?.trim() || DEFAULT_GEMINI_BASE_URL;
846
+ const baseUrl = normalizeGeminiBaseUrl(rawBaseUrl);
847
+ const headerOverrides = Object.assign({}, providerConfig?.headers, remote?.headers);
848
+ const headers = {
849
+ "Content-Type": "application/json",
850
+ "x-goog-api-key": apiKey,
851
+ ...headerOverrides
852
+ };
853
+ const model = normalizeGeminiModel(options.model);
854
+ const modelPath = buildGeminiModelPath(model);
855
+ debugLog("memory embeddings: gemini client", {
856
+ rawBaseUrl,
857
+ baseUrl,
858
+ model,
859
+ modelPath,
860
+ embedEndpoint: `${baseUrl}/${modelPath}:embedContent`,
861
+ batchEndpoint: `${baseUrl}/${modelPath}:batchEmbedContents`
862
+ });
863
+ return {
864
+ baseUrl,
865
+ headers,
866
+ model,
867
+ modelPath
868
+ };
869
+ }
870
+
871
+ //#endregion
872
+ //#region src/memory/embeddings-openai.ts
873
+ const DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
874
+ const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
875
+ function normalizeOpenAiModel(model) {
876
+ const trimmed = model.trim();
877
+ if (!trimmed) return DEFAULT_OPENAI_EMBEDDING_MODEL;
878
+ if (trimmed.startsWith("openai/")) return trimmed.slice(7);
879
+ return trimmed;
880
+ }
881
+ async function createOpenAiEmbeddingProvider(options) {
882
+ const client = await resolveOpenAiEmbeddingClient(options);
883
+ const url = `${client.baseUrl.replace(/\/$/, "")}/embeddings`;
884
+ const embed = async (input) => {
885
+ if (input.length === 0) return [];
886
+ const res = await fetch(url, {
887
+ method: "POST",
888
+ headers: client.headers,
889
+ body: JSON.stringify({
890
+ model: client.model,
891
+ input
892
+ })
893
+ });
894
+ if (!res.ok) {
895
+ const text = await res.text();
896
+ throw new Error(`openai embeddings failed: ${res.status} ${text}`);
897
+ }
898
+ return ((await res.json()).data ?? []).map((entry) => entry.embedding ?? []);
899
+ };
900
+ return {
901
+ provider: {
902
+ id: "openai",
903
+ model: client.model,
904
+ embedQuery: async (text) => {
905
+ const [vec] = await embed([text]);
906
+ return vec ?? [];
907
+ },
908
+ embedBatch: embed
909
+ },
910
+ client
911
+ };
912
+ }
913
+ async function resolveOpenAiEmbeddingClient(options) {
914
+ const remote = options.remote;
915
+ const remoteApiKey = remote?.apiKey?.trim();
916
+ const remoteBaseUrl = remote?.baseUrl?.trim();
917
+ const apiKey = remoteApiKey ? remoteApiKey : requireApiKey(await resolveApiKeyForProvider({
918
+ provider: "openai",
919
+ cfg: options.config,
920
+ agentDir: options.agentDir
921
+ }), "openai");
922
+ const providerConfig = options.config.models?.providers?.openai;
923
+ const baseUrl = remoteBaseUrl || providerConfig?.baseUrl?.trim() || DEFAULT_OPENAI_BASE_URL;
924
+ const headerOverrides = Object.assign({}, providerConfig?.headers, remote?.headers);
925
+ return {
926
+ baseUrl,
927
+ headers: {
928
+ "Content-Type": "application/json",
929
+ Authorization: `Bearer ${apiKey}`,
930
+ ...headerOverrides
931
+ },
932
+ model: normalizeOpenAiModel(options.model)
933
+ };
934
+ }
935
+
936
+ //#endregion
937
+ //#region src/memory/node-llama.ts
938
+ async function importNodeLlamaCpp() {
939
+ return import("node-llama-cpp");
940
+ }
941
+
942
+ //#endregion
943
+ //#region src/memory/embeddings.ts
944
+ function sanitizeAndNormalizeEmbedding(vec) {
945
+ const sanitized = vec.map((value) => Number.isFinite(value) ? value : 0);
946
+ const magnitude = Math.sqrt(sanitized.reduce((sum, value) => sum + value * value, 0));
947
+ if (magnitude < 1e-10) return sanitized;
948
+ return sanitized.map((value) => value / magnitude);
949
+ }
950
+ const DEFAULT_LOCAL_MODEL = "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf";
951
+ function canAutoSelectLocal(options) {
952
+ const modelPath = options.local?.modelPath?.trim();
953
+ if (!modelPath) return false;
954
+ if (/^(hf:|https?:)/i.test(modelPath)) return false;
955
+ const resolved = resolveUserPath(modelPath);
956
+ try {
957
+ return fs.statSync(resolved).isFile();
958
+ } catch {
959
+ return false;
960
+ }
961
+ }
962
+ function isMissingApiKeyError(err) {
963
+ return formatError(err).includes("No API key found for provider");
964
+ }
965
+ async function createLocalEmbeddingProvider(options) {
966
+ const modelPath = options.local?.modelPath?.trim() || DEFAULT_LOCAL_MODEL;
967
+ const modelCacheDir = options.local?.modelCacheDir?.trim();
968
+ const { getLlama, resolveModelFile, LlamaLogLevel } = await importNodeLlamaCpp();
969
+ let llama = null;
970
+ let embeddingModel = null;
971
+ let embeddingContext = null;
972
+ const ensureContext = async () => {
973
+ if (!llama) llama = await getLlama({ logLevel: LlamaLogLevel.error });
974
+ if (!embeddingModel) {
975
+ const resolved = await resolveModelFile(modelPath, modelCacheDir || void 0);
976
+ embeddingModel = await llama.loadModel({ modelPath: resolved });
977
+ }
978
+ if (!embeddingContext) embeddingContext = await embeddingModel.createEmbeddingContext();
979
+ return embeddingContext;
980
+ };
981
+ return {
982
+ id: "local",
983
+ model: modelPath,
984
+ embedQuery: async (text) => {
985
+ const embedding = await (await ensureContext()).getEmbeddingFor(text);
986
+ return sanitizeAndNormalizeEmbedding(Array.from(embedding.vector));
987
+ },
988
+ embedBatch: async (texts) => {
989
+ const ctx = await ensureContext();
990
+ return await Promise.all(texts.map(async (text) => {
991
+ const embedding = await ctx.getEmbeddingFor(text);
992
+ return sanitizeAndNormalizeEmbedding(Array.from(embedding.vector));
993
+ }));
994
+ }
995
+ };
996
+ }
997
+ async function createEmbeddingProvider(options) {
998
+ const requestedProvider = options.provider;
999
+ const fallback = options.fallback;
1000
+ const createProvider = async (id) => {
1001
+ if (id === "local") return { provider: await createLocalEmbeddingProvider(options) };
1002
+ if (id === "gemini") {
1003
+ const { provider, client } = await createGeminiEmbeddingProvider(options);
1004
+ return {
1005
+ provider,
1006
+ gemini: client
1007
+ };
1008
+ }
1009
+ const { provider, client } = await createOpenAiEmbeddingProvider(options);
1010
+ return {
1011
+ provider,
1012
+ openAi: client
1013
+ };
1014
+ };
1015
+ const formatPrimaryError = (err, provider) => provider === "local" ? formatLocalSetupError(err) : formatError(err);
1016
+ if (requestedProvider === "auto") {
1017
+ const missingKeyErrors = [];
1018
+ let localError = null;
1019
+ if (canAutoSelectLocal(options)) try {
1020
+ return {
1021
+ ...await createProvider("local"),
1022
+ requestedProvider
1023
+ };
1024
+ } catch (err) {
1025
+ localError = formatLocalSetupError(err);
1026
+ }
1027
+ for (const provider of ["openai", "gemini"]) try {
1028
+ return {
1029
+ ...await createProvider(provider),
1030
+ requestedProvider
1031
+ };
1032
+ } catch (err) {
1033
+ const message = formatPrimaryError(err, provider);
1034
+ if (isMissingApiKeyError(err)) {
1035
+ missingKeyErrors.push(message);
1036
+ continue;
1037
+ }
1038
+ throw new Error(message, { cause: err });
1039
+ }
1040
+ const details = [...missingKeyErrors, localError].filter(Boolean);
1041
+ if (details.length > 0) throw new Error(details.join("\n\n"));
1042
+ throw new Error("No embeddings provider available.");
1043
+ }
1044
+ try {
1045
+ return {
1046
+ ...await createProvider(requestedProvider),
1047
+ requestedProvider
1048
+ };
1049
+ } catch (primaryErr) {
1050
+ const reason = formatPrimaryError(primaryErr, requestedProvider);
1051
+ if (fallback && fallback !== "none" && fallback !== requestedProvider) try {
1052
+ return {
1053
+ ...await createProvider(fallback),
1054
+ requestedProvider,
1055
+ fallbackFrom: requestedProvider,
1056
+ fallbackReason: reason
1057
+ };
1058
+ } catch (fallbackErr) {
1059
+ throw new Error(`${reason}\n\nFallback to ${fallback} failed: ${formatError(fallbackErr)}`, { cause: fallbackErr });
1060
+ }
1061
+ throw new Error(reason, { cause: primaryErr });
1062
+ }
1063
+ }
1064
+ function formatError(err) {
1065
+ if (err instanceof Error) return err.message;
1066
+ return String(err);
1067
+ }
1068
+ function isNodeLlamaCppMissing(err) {
1069
+ if (!(err instanceof Error)) return false;
1070
+ if (err.code === "ERR_MODULE_NOT_FOUND") return err.message.includes("node-llama-cpp");
1071
+ return false;
1072
+ }
1073
+ function formatLocalSetupError(err) {
1074
+ const detail = formatError(err);
1075
+ const missing = isNodeLlamaCppMissing(err);
1076
+ return [
1077
+ "Local embeddings unavailable.",
1078
+ missing ? "Reason: optional dependency node-llama-cpp is missing (or failed to install)." : detail ? `Reason: ${detail}` : void 0,
1079
+ missing && detail ? `Detail: ${detail}` : null,
1080
+ "To enable local embeddings:",
1081
+ "1) Use Node 22 LTS (recommended for installs/updates)",
1082
+ missing ? "2) Reinstall OpenClaw (this should install node-llama-cpp): npm i -g openclaw@latest" : null,
1083
+ "3) If you use pnpm: pnpm approve-builds (select node-llama-cpp), then pnpm rebuild node-llama-cpp",
1084
+ "Or set agents.defaults.memorySearch.provider = \"openai\" (remote)."
1085
+ ].filter(Boolean).join("\n");
1086
+ }
1087
+
1088
+ //#endregion
1089
+ //#region src/memory/hybrid.ts
1090
+ function buildFtsQuery(raw) {
1091
+ const tokens = raw.match(/[A-Za-z0-9_]+/g)?.map((t) => t.trim()).filter(Boolean) ?? [];
1092
+ if (tokens.length === 0) return null;
1093
+ return tokens.map((t) => `"${t.replaceAll("\"", "")}"`).join(" AND ");
1094
+ }
1095
+ function bm25RankToScore(rank) {
1096
+ return 1 / (1 + (Number.isFinite(rank) ? Math.max(0, rank) : 999));
1097
+ }
1098
+ function mergeHybridResults(params) {
1099
+ const byId = /* @__PURE__ */ new Map();
1100
+ for (const r of params.vector) byId.set(r.id, {
1101
+ id: r.id,
1102
+ path: r.path,
1103
+ startLine: r.startLine,
1104
+ endLine: r.endLine,
1105
+ source: r.source,
1106
+ snippet: r.snippet,
1107
+ vectorScore: r.vectorScore,
1108
+ textScore: 0
1109
+ });
1110
+ for (const r of params.keyword) {
1111
+ const existing = byId.get(r.id);
1112
+ if (existing) {
1113
+ existing.textScore = r.textScore;
1114
+ if (r.snippet && r.snippet.length > 0) existing.snippet = r.snippet;
1115
+ } else byId.set(r.id, {
1116
+ id: r.id,
1117
+ path: r.path,
1118
+ startLine: r.startLine,
1119
+ endLine: r.endLine,
1120
+ source: r.source,
1121
+ snippet: r.snippet,
1122
+ vectorScore: 0,
1123
+ textScore: r.textScore
1124
+ });
1125
+ }
1126
+ return Array.from(byId.values()).map((entry) => {
1127
+ const score = params.vectorWeight * entry.vectorScore + params.textWeight * entry.textScore;
1128
+ return {
1129
+ path: entry.path,
1130
+ startLine: entry.startLine,
1131
+ endLine: entry.endLine,
1132
+ score,
1133
+ snippet: entry.snippet,
1134
+ source: entry.source
1135
+ };
1136
+ }).toSorted((a, b) => b.score - a.score);
1137
+ }
1138
+
1139
+ //#endregion
1140
+ //#region src/memory/manager-search.ts
1141
+ const vectorToBlob$1 = (embedding) => Buffer.from(new Float32Array(embedding).buffer);
1142
+ async function searchVector(params) {
1143
+ if (params.queryVec.length === 0 || params.limit <= 0) return [];
1144
+ if (await params.ensureVectorReady(params.queryVec.length)) return params.db.prepare(`SELECT c.id, c.path, c.start_line, c.end_line, c.text,
1145
+ c.source,
1146
+ vec_distance_cosine(v.embedding, ?) AS dist
1147
+ FROM ${params.vectorTable} v\n JOIN chunks c ON c.id = v.id\n WHERE c.model = ?${params.sourceFilterVec.sql}\n ORDER BY dist ASC\n LIMIT ?`).all(vectorToBlob$1(params.queryVec), params.providerModel, ...params.sourceFilterVec.params, params.limit).map((row) => ({
1148
+ id: row.id,
1149
+ path: row.path,
1150
+ startLine: row.start_line,
1151
+ endLine: row.end_line,
1152
+ score: 1 - row.dist,
1153
+ snippet: truncateUtf16Safe(row.text, params.snippetMaxChars),
1154
+ source: row.source
1155
+ }));
1156
+ return listChunks({
1157
+ db: params.db,
1158
+ providerModel: params.providerModel,
1159
+ sourceFilter: params.sourceFilterChunks
1160
+ }).map((chunk) => ({
1161
+ chunk,
1162
+ score: cosineSimilarity(params.queryVec, chunk.embedding)
1163
+ })).filter((entry) => Number.isFinite(entry.score)).toSorted((a, b) => b.score - a.score).slice(0, params.limit).map((entry) => ({
1164
+ id: entry.chunk.id,
1165
+ path: entry.chunk.path,
1166
+ startLine: entry.chunk.startLine,
1167
+ endLine: entry.chunk.endLine,
1168
+ score: entry.score,
1169
+ snippet: truncateUtf16Safe(entry.chunk.text, params.snippetMaxChars),
1170
+ source: entry.chunk.source
1171
+ }));
1172
+ }
1173
+ function listChunks(params) {
1174
+ return params.db.prepare(`SELECT id, path, start_line, end_line, text, embedding, source
1175
+ FROM chunks
1176
+ WHERE model = ?${params.sourceFilter.sql}`).all(params.providerModel, ...params.sourceFilter.params).map((row) => ({
1177
+ id: row.id,
1178
+ path: row.path,
1179
+ startLine: row.start_line,
1180
+ endLine: row.end_line,
1181
+ text: row.text,
1182
+ embedding: parseEmbedding(row.embedding),
1183
+ source: row.source
1184
+ }));
1185
+ }
1186
+ async function searchKeyword(params) {
1187
+ if (params.limit <= 0) return [];
1188
+ const ftsQuery = params.buildFtsQuery(params.query);
1189
+ if (!ftsQuery) return [];
1190
+ return params.db.prepare(`SELECT id, path, source, start_line, end_line, text,\n bm25(${params.ftsTable}) AS rank\n FROM ${params.ftsTable}\n WHERE ${params.ftsTable} MATCH ? AND model = ?${params.sourceFilter.sql}\n ORDER BY rank ASC\n LIMIT ?`).all(ftsQuery, params.providerModel, ...params.sourceFilter.params, params.limit).map((row) => {
1191
+ const textScore = params.bm25RankToScore(row.rank);
1192
+ return {
1193
+ id: row.id,
1194
+ path: row.path,
1195
+ startLine: row.start_line,
1196
+ endLine: row.end_line,
1197
+ score: textScore,
1198
+ textScore,
1199
+ snippet: truncateUtf16Safe(row.text, params.snippetMaxChars),
1200
+ source: row.source
1201
+ };
1202
+ });
1203
+ }
1204
+
1205
+ //#endregion
1206
+ //#region src/memory/memory-schema.ts
1207
+ function ensureMemoryIndexSchema(params) {
1208
+ params.db.exec(`
1209
+ CREATE TABLE IF NOT EXISTS meta (
1210
+ key TEXT PRIMARY KEY,
1211
+ value TEXT NOT NULL
1212
+ );
1213
+ `);
1214
+ params.db.exec(`
1215
+ CREATE TABLE IF NOT EXISTS files (
1216
+ path TEXT PRIMARY KEY,
1217
+ source TEXT NOT NULL DEFAULT 'memory',
1218
+ hash TEXT NOT NULL,
1219
+ mtime INTEGER NOT NULL,
1220
+ size INTEGER NOT NULL
1221
+ );
1222
+ `);
1223
+ params.db.exec(`
1224
+ CREATE TABLE IF NOT EXISTS chunks (
1225
+ id TEXT PRIMARY KEY,
1226
+ path TEXT NOT NULL,
1227
+ source TEXT NOT NULL DEFAULT 'memory',
1228
+ start_line INTEGER NOT NULL,
1229
+ end_line INTEGER NOT NULL,
1230
+ hash TEXT NOT NULL,
1231
+ model TEXT NOT NULL,
1232
+ text TEXT NOT NULL,
1233
+ embedding TEXT NOT NULL,
1234
+ updated_at INTEGER NOT NULL
1235
+ );
1236
+ `);
1237
+ params.db.exec(`
1238
+ CREATE TABLE IF NOT EXISTS ${params.embeddingCacheTable} (
1239
+ provider TEXT NOT NULL,
1240
+ model TEXT NOT NULL,
1241
+ provider_key TEXT NOT NULL,
1242
+ hash TEXT NOT NULL,
1243
+ embedding TEXT NOT NULL,
1244
+ dims INTEGER,
1245
+ updated_at INTEGER NOT NULL,
1246
+ PRIMARY KEY (provider, model, provider_key, hash)
1247
+ );
1248
+ `);
1249
+ params.db.exec(`CREATE INDEX IF NOT EXISTS idx_embedding_cache_updated_at ON ${params.embeddingCacheTable}(updated_at);`);
1250
+ let ftsAvailable = false;
1251
+ let ftsError;
1252
+ if (params.ftsEnabled) try {
1253
+ params.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${params.ftsTable} USING fts5(\n text,\n id UNINDEXED,\n path UNINDEXED,\n source UNINDEXED,\n model UNINDEXED,\n start_line UNINDEXED,\n end_line UNINDEXED\n);`);
1254
+ ftsAvailable = true;
1255
+ } catch (err) {
1256
+ const message = err instanceof Error ? err.message : String(err);
1257
+ ftsAvailable = false;
1258
+ ftsError = message;
1259
+ }
1260
+ ensureColumn(params.db, "files", "source", "TEXT NOT NULL DEFAULT 'memory'");
1261
+ ensureColumn(params.db, "chunks", "source", "TEXT NOT NULL DEFAULT 'memory'");
1262
+ params.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);`);
1263
+ params.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_source ON chunks(source);`);
1264
+ return {
1265
+ ftsAvailable,
1266
+ ...ftsError ? { ftsError } : {}
1267
+ };
1268
+ }
1269
+ function ensureColumn(db, table, column, definition) {
1270
+ if (db.prepare(`PRAGMA table_info(${table})`).all().some((row) => row.name === column)) return;
1271
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
1272
+ }
1273
+
1274
+ //#endregion
1275
+ //#region src/memory/sqlite-vec.ts
1276
+ async function loadSqliteVecExtension(params) {
1277
+ try {
1278
+ const sqliteVec = await import("sqlite-vec");
1279
+ const resolvedPath = params.extensionPath?.trim() ? params.extensionPath.trim() : void 0;
1280
+ const extensionPath = resolvedPath ?? sqliteVec.getLoadablePath();
1281
+ params.db.enableLoadExtension(true);
1282
+ if (resolvedPath) params.db.loadExtension(extensionPath);
1283
+ else sqliteVec.load(params.db);
1284
+ return {
1285
+ ok: true,
1286
+ extensionPath
1287
+ };
1288
+ } catch (err) {
1289
+ return {
1290
+ ok: false,
1291
+ error: err instanceof Error ? err.message : String(err)
1292
+ };
1293
+ }
1294
+ }
1295
+
1296
+ //#endregion
1297
+ //#region src/memory/manager.ts
1298
+ var manager_exports = /* @__PURE__ */ __exportAll({ MemoryIndexManager: () => MemoryIndexManager });
1299
+ const META_KEY = "memory_index_meta_v1";
1300
+ const SNIPPET_MAX_CHARS = 700;
1301
+ const VECTOR_TABLE = "chunks_vec";
1302
+ const FTS_TABLE = "chunks_fts";
1303
+ const EMBEDDING_CACHE_TABLE = "embedding_cache";
1304
+ const SESSION_DIRTY_DEBOUNCE_MS = 5e3;
1305
+ const EMBEDDING_BATCH_MAX_TOKENS = 8e3;
1306
+ const EMBEDDING_APPROX_CHARS_PER_TOKEN = 1;
1307
+ const EMBEDDING_INDEX_CONCURRENCY = 4;
1308
+ const EMBEDDING_RETRY_MAX_ATTEMPTS = 3;
1309
+ const EMBEDDING_RETRY_BASE_DELAY_MS = 500;
1310
+ const EMBEDDING_RETRY_MAX_DELAY_MS = 8e3;
1311
+ const BATCH_FAILURE_LIMIT = 2;
1312
+ const SESSION_DELTA_READ_CHUNK_BYTES = 64 * 1024;
1313
+ const VECTOR_LOAD_TIMEOUT_MS = 3e4;
1314
+ const EMBEDDING_QUERY_TIMEOUT_REMOTE_MS = 6e4;
1315
+ const EMBEDDING_QUERY_TIMEOUT_LOCAL_MS = 5 * 6e4;
1316
+ const EMBEDDING_BATCH_TIMEOUT_REMOTE_MS = 2 * 6e4;
1317
+ const EMBEDDING_BATCH_TIMEOUT_LOCAL_MS = 10 * 6e4;
1318
+ const log = createSubsystemLogger("memory");
1319
+ const INDEX_CACHE = /* @__PURE__ */ new Map();
1320
+ const vectorToBlob = (embedding) => Buffer.from(new Float32Array(embedding).buffer);
1321
+ var MemoryIndexManager = class MemoryIndexManager {
1322
+ static async get(params) {
1323
+ const { cfg, agentId } = params;
1324
+ const settings = resolveMemorySearchConfig(cfg, agentId);
1325
+ if (!settings) return null;
1326
+ const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);
1327
+ const key = `${agentId}:${workspaceDir}:${JSON.stringify(settings)}`;
1328
+ const existing = INDEX_CACHE.get(key);
1329
+ if (existing) return existing;
1330
+ const manager = new MemoryIndexManager({
1331
+ cacheKey: key,
1332
+ cfg,
1333
+ agentId,
1334
+ workspaceDir,
1335
+ settings,
1336
+ providerResult: await createEmbeddingProvider({
1337
+ config: cfg,
1338
+ agentDir: resolveAgentDir(cfg, agentId),
1339
+ provider: settings.provider,
1340
+ remote: settings.remote,
1341
+ model: settings.model,
1342
+ fallback: settings.fallback,
1343
+ local: settings.local
1344
+ })
1345
+ });
1346
+ INDEX_CACHE.set(key, manager);
1347
+ return manager;
1348
+ }
1349
+ constructor(params) {
1350
+ this.batchFailureCount = 0;
1351
+ this.batchFailureLock = Promise.resolve();
1352
+ this.vectorReady = null;
1353
+ this.watcher = null;
1354
+ this.watchTimer = null;
1355
+ this.sessionWatchTimer = null;
1356
+ this.sessionUnsubscribe = null;
1357
+ this.intervalTimer = null;
1358
+ this.closed = false;
1359
+ this.dirty = false;
1360
+ this.sessionsDirty = false;
1361
+ this.sessionsDirtyFiles = /* @__PURE__ */ new Set();
1362
+ this.sessionPendingFiles = /* @__PURE__ */ new Set();
1363
+ this.sessionDeltas = /* @__PURE__ */ new Map();
1364
+ this.sessionWarm = /* @__PURE__ */ new Set();
1365
+ this.syncing = null;
1366
+ this.cacheKey = params.cacheKey;
1367
+ this.cfg = params.cfg;
1368
+ this.agentId = params.agentId;
1369
+ this.workspaceDir = params.workspaceDir;
1370
+ this.settings = params.settings;
1371
+ this.provider = params.providerResult.provider;
1372
+ this.requestedProvider = params.providerResult.requestedProvider;
1373
+ this.fallbackFrom = params.providerResult.fallbackFrom;
1374
+ this.fallbackReason = params.providerResult.fallbackReason;
1375
+ this.openAi = params.providerResult.openAi;
1376
+ this.gemini = params.providerResult.gemini;
1377
+ this.sources = new Set(params.settings.sources);
1378
+ this.db = this.openDatabase();
1379
+ this.providerKey = this.computeProviderKey();
1380
+ this.cache = {
1381
+ enabled: params.settings.cache.enabled,
1382
+ maxEntries: params.settings.cache.maxEntries
1383
+ };
1384
+ this.fts = {
1385
+ enabled: params.settings.query.hybrid.enabled,
1386
+ available: false
1387
+ };
1388
+ this.ensureSchema();
1389
+ this.vector = {
1390
+ enabled: params.settings.store.vector.enabled,
1391
+ available: null,
1392
+ extensionPath: params.settings.store.vector.extensionPath
1393
+ };
1394
+ const meta = this.readMeta();
1395
+ if (meta?.vectorDims) this.vector.dims = meta.vectorDims;
1396
+ this.ensureWatcher();
1397
+ this.ensureSessionListener();
1398
+ this.ensureIntervalSync();
1399
+ this.dirty = this.sources.has("memory");
1400
+ this.batch = this.resolveBatchConfig();
1401
+ }
1402
+ async warmSession(sessionKey) {
1403
+ if (!this.settings.sync.onSessionStart) return;
1404
+ const key = sessionKey?.trim() || "";
1405
+ if (key && this.sessionWarm.has(key)) return;
1406
+ this.sync({ reason: "session-start" }).catch((err) => {
1407
+ log.warn(`memory sync failed (session-start): ${String(err)}`);
1408
+ });
1409
+ if (key) this.sessionWarm.add(key);
1410
+ }
1411
+ async search(query, opts) {
1412
+ this.warmSession(opts?.sessionKey);
1413
+ if (this.settings.sync.onSearch && (this.dirty || this.sessionsDirty)) this.sync({ reason: "search" }).catch((err) => {
1414
+ log.warn(`memory sync failed (search): ${String(err)}`);
1415
+ });
1416
+ const cleaned = query.trim();
1417
+ if (!cleaned) return [];
1418
+ const minScore = opts?.minScore ?? this.settings.query.minScore;
1419
+ const maxResults = opts?.maxResults ?? this.settings.query.maxResults;
1420
+ const hybrid = this.settings.query.hybrid;
1421
+ const candidates = Math.min(200, Math.max(1, Math.floor(maxResults * hybrid.candidateMultiplier)));
1422
+ const keywordResults = hybrid.enabled ? await this.searchKeyword(cleaned, candidates).catch(() => []) : [];
1423
+ const queryVec = await this.embedQueryWithTimeout(cleaned);
1424
+ const vectorResults = queryVec.some((v) => v !== 0) ? await this.searchVector(queryVec, candidates).catch(() => []) : [];
1425
+ if (!hybrid.enabled) return vectorResults.filter((entry) => entry.score >= minScore).slice(0, maxResults);
1426
+ return this.mergeHybridResults({
1427
+ vector: vectorResults,
1428
+ keyword: keywordResults,
1429
+ vectorWeight: hybrid.vectorWeight,
1430
+ textWeight: hybrid.textWeight
1431
+ }).filter((entry) => entry.score >= minScore).slice(0, maxResults);
1432
+ }
1433
+ async searchVector(queryVec, limit) {
1434
+ return (await searchVector({
1435
+ db: this.db,
1436
+ vectorTable: VECTOR_TABLE,
1437
+ providerModel: this.provider.model,
1438
+ queryVec,
1439
+ limit,
1440
+ snippetMaxChars: SNIPPET_MAX_CHARS,
1441
+ ensureVectorReady: async (dimensions) => await this.ensureVectorReady(dimensions),
1442
+ sourceFilterVec: this.buildSourceFilter("c"),
1443
+ sourceFilterChunks: this.buildSourceFilter()
1444
+ })).map((entry) => entry);
1445
+ }
1446
+ buildFtsQuery(raw) {
1447
+ return buildFtsQuery(raw);
1448
+ }
1449
+ async searchKeyword(query, limit) {
1450
+ if (!this.fts.enabled || !this.fts.available) return [];
1451
+ const sourceFilter = this.buildSourceFilter();
1452
+ return (await searchKeyword({
1453
+ db: this.db,
1454
+ ftsTable: FTS_TABLE,
1455
+ providerModel: this.provider.model,
1456
+ query,
1457
+ limit,
1458
+ snippetMaxChars: SNIPPET_MAX_CHARS,
1459
+ sourceFilter,
1460
+ buildFtsQuery: (raw) => this.buildFtsQuery(raw),
1461
+ bm25RankToScore
1462
+ })).map((entry) => entry);
1463
+ }
1464
+ mergeHybridResults(params) {
1465
+ return mergeHybridResults({
1466
+ vector: params.vector.map((r) => ({
1467
+ id: r.id,
1468
+ path: r.path,
1469
+ startLine: r.startLine,
1470
+ endLine: r.endLine,
1471
+ source: r.source,
1472
+ snippet: r.snippet,
1473
+ vectorScore: r.score
1474
+ })),
1475
+ keyword: params.keyword.map((r) => ({
1476
+ id: r.id,
1477
+ path: r.path,
1478
+ startLine: r.startLine,
1479
+ endLine: r.endLine,
1480
+ source: r.source,
1481
+ snippet: r.snippet,
1482
+ textScore: r.textScore
1483
+ })),
1484
+ vectorWeight: params.vectorWeight,
1485
+ textWeight: params.textWeight
1486
+ }).map((entry) => entry);
1487
+ }
1488
+ async sync(params) {
1489
+ if (this.syncing) return this.syncing;
1490
+ this.syncing = this.runSync(params).finally(() => {
1491
+ this.syncing = null;
1492
+ });
1493
+ return this.syncing;
1494
+ }
1495
+ async readFile(params) {
1496
+ const rawPath = params.relPath.trim();
1497
+ if (!rawPath) throw new Error("path required");
1498
+ const absPath = path.isAbsolute(rawPath) ? path.resolve(rawPath) : path.resolve(this.workspaceDir, rawPath);
1499
+ const relPath = path.relative(this.workspaceDir, absPath).replace(/\\/g, "/");
1500
+ const allowedWorkspace = relPath.length > 0 && !relPath.startsWith("..") && !path.isAbsolute(relPath) && isMemoryPath(relPath);
1501
+ let allowedAdditional = false;
1502
+ if (!allowedWorkspace && this.settings.extraPaths.length > 0) {
1503
+ const additionalPaths = normalizeExtraMemoryPaths(this.workspaceDir, this.settings.extraPaths);
1504
+ for (const additionalPath of additionalPaths) try {
1505
+ const stat = await fs$1.lstat(additionalPath);
1506
+ if (stat.isSymbolicLink()) continue;
1507
+ if (stat.isDirectory()) {
1508
+ if (absPath === additionalPath || absPath.startsWith(`${additionalPath}${path.sep}`)) {
1509
+ allowedAdditional = true;
1510
+ break;
1511
+ }
1512
+ continue;
1513
+ }
1514
+ if (stat.isFile()) {
1515
+ if (absPath === additionalPath && absPath.endsWith(".md")) {
1516
+ allowedAdditional = true;
1517
+ break;
1518
+ }
1519
+ }
1520
+ } catch {}
1521
+ }
1522
+ if (!allowedWorkspace && !allowedAdditional) throw new Error("path required");
1523
+ if (!absPath.endsWith(".md")) throw new Error("path required");
1524
+ const stat = await fs$1.lstat(absPath);
1525
+ if (stat.isSymbolicLink() || !stat.isFile()) throw new Error("path required");
1526
+ const content = await fs$1.readFile(absPath, "utf-8");
1527
+ if (!params.from && !params.lines) return {
1528
+ text: content,
1529
+ path: relPath
1530
+ };
1531
+ const lines = content.split("\n");
1532
+ const start = Math.max(1, params.from ?? 1);
1533
+ const count = Math.max(1, params.lines ?? lines.length);
1534
+ return {
1535
+ text: lines.slice(start - 1, start - 1 + count).join("\n"),
1536
+ path: relPath
1537
+ };
1538
+ }
1539
+ status() {
1540
+ const sourceFilter = this.buildSourceFilter();
1541
+ const files = this.db.prepare(`SELECT COUNT(*) as c FROM files WHERE 1=1${sourceFilter.sql}`).get(...sourceFilter.params);
1542
+ const chunks = this.db.prepare(`SELECT COUNT(*) as c FROM chunks WHERE 1=1${sourceFilter.sql}`).get(...sourceFilter.params);
1543
+ const sourceCounts = (() => {
1544
+ const sources = Array.from(this.sources);
1545
+ if (sources.length === 0) return [];
1546
+ const bySource = /* @__PURE__ */ new Map();
1547
+ for (const source of sources) bySource.set(source, {
1548
+ files: 0,
1549
+ chunks: 0
1550
+ });
1551
+ const fileRows = this.db.prepare(`SELECT source, COUNT(*) as c FROM files WHERE 1=1${sourceFilter.sql} GROUP BY source`).all(...sourceFilter.params);
1552
+ for (const row of fileRows) {
1553
+ const entry = bySource.get(row.source) ?? {
1554
+ files: 0,
1555
+ chunks: 0
1556
+ };
1557
+ entry.files = row.c ?? 0;
1558
+ bySource.set(row.source, entry);
1559
+ }
1560
+ const chunkRows = this.db.prepare(`SELECT source, COUNT(*) as c FROM chunks WHERE 1=1${sourceFilter.sql} GROUP BY source`).all(...sourceFilter.params);
1561
+ for (const row of chunkRows) {
1562
+ const entry = bySource.get(row.source) ?? {
1563
+ files: 0,
1564
+ chunks: 0
1565
+ };
1566
+ entry.chunks = row.c ?? 0;
1567
+ bySource.set(row.source, entry);
1568
+ }
1569
+ return sources.map((source) => Object.assign({ source }, bySource.get(source)));
1570
+ })();
1571
+ return {
1572
+ backend: "builtin",
1573
+ files: files?.c ?? 0,
1574
+ chunks: chunks?.c ?? 0,
1575
+ dirty: this.dirty || this.sessionsDirty,
1576
+ workspaceDir: this.workspaceDir,
1577
+ dbPath: this.settings.store.path,
1578
+ provider: this.provider.id,
1579
+ model: this.provider.model,
1580
+ requestedProvider: this.requestedProvider,
1581
+ sources: Array.from(this.sources),
1582
+ extraPaths: this.settings.extraPaths,
1583
+ sourceCounts,
1584
+ cache: this.cache.enabled ? {
1585
+ enabled: true,
1586
+ entries: this.db.prepare(`SELECT COUNT(*) as c FROM ${EMBEDDING_CACHE_TABLE}`).get()?.c ?? 0,
1587
+ maxEntries: this.cache.maxEntries
1588
+ } : {
1589
+ enabled: false,
1590
+ maxEntries: this.cache.maxEntries
1591
+ },
1592
+ fts: {
1593
+ enabled: this.fts.enabled,
1594
+ available: this.fts.available,
1595
+ error: this.fts.loadError
1596
+ },
1597
+ fallback: this.fallbackReason ? {
1598
+ from: this.fallbackFrom ?? "local",
1599
+ reason: this.fallbackReason
1600
+ } : void 0,
1601
+ vector: {
1602
+ enabled: this.vector.enabled,
1603
+ available: this.vector.available ?? void 0,
1604
+ extensionPath: this.vector.extensionPath,
1605
+ loadError: this.vector.loadError,
1606
+ dims: this.vector.dims
1607
+ },
1608
+ batch: {
1609
+ enabled: this.batch.enabled,
1610
+ failures: this.batchFailureCount,
1611
+ limit: BATCH_FAILURE_LIMIT,
1612
+ wait: this.batch.wait,
1613
+ concurrency: this.batch.concurrency,
1614
+ pollIntervalMs: this.batch.pollIntervalMs,
1615
+ timeoutMs: this.batch.timeoutMs,
1616
+ lastError: this.batchFailureLastError,
1617
+ lastProvider: this.batchFailureLastProvider
1618
+ }
1619
+ };
1620
+ }
1621
+ async probeVectorAvailability() {
1622
+ if (!this.vector.enabled) return false;
1623
+ return this.ensureVectorReady();
1624
+ }
1625
+ async probeEmbeddingAvailability() {
1626
+ try {
1627
+ await this.embedBatchWithRetry(["ping"]);
1628
+ return { ok: true };
1629
+ } catch (err) {
1630
+ return {
1631
+ ok: false,
1632
+ error: err instanceof Error ? err.message : String(err)
1633
+ };
1634
+ }
1635
+ }
1636
+ async close() {
1637
+ if (this.closed) return;
1638
+ this.closed = true;
1639
+ if (this.watchTimer) {
1640
+ clearTimeout(this.watchTimer);
1641
+ this.watchTimer = null;
1642
+ }
1643
+ if (this.sessionWatchTimer) {
1644
+ clearTimeout(this.sessionWatchTimer);
1645
+ this.sessionWatchTimer = null;
1646
+ }
1647
+ if (this.intervalTimer) {
1648
+ clearInterval(this.intervalTimer);
1649
+ this.intervalTimer = null;
1650
+ }
1651
+ if (this.watcher) {
1652
+ await this.watcher.close();
1653
+ this.watcher = null;
1654
+ }
1655
+ if (this.sessionUnsubscribe) {
1656
+ this.sessionUnsubscribe();
1657
+ this.sessionUnsubscribe = null;
1658
+ }
1659
+ this.db.close();
1660
+ INDEX_CACHE.delete(this.cacheKey);
1661
+ }
1662
+ async ensureVectorReady(dimensions) {
1663
+ if (!this.vector.enabled) return false;
1664
+ if (!this.vectorReady) this.vectorReady = this.withTimeout(this.loadVectorExtension(), VECTOR_LOAD_TIMEOUT_MS, `sqlite-vec load timed out after ${Math.round(VECTOR_LOAD_TIMEOUT_MS / 1e3)}s`);
1665
+ let ready = false;
1666
+ try {
1667
+ ready = await this.vectorReady;
1668
+ } catch (err) {
1669
+ const message = err instanceof Error ? err.message : String(err);
1670
+ this.vector.available = false;
1671
+ this.vector.loadError = message;
1672
+ this.vectorReady = null;
1673
+ log.warn(`sqlite-vec unavailable: ${message}`);
1674
+ return false;
1675
+ }
1676
+ if (ready && typeof dimensions === "number" && dimensions > 0) this.ensureVectorTable(dimensions);
1677
+ return ready;
1678
+ }
1679
+ async loadVectorExtension() {
1680
+ if (this.vector.available !== null) return this.vector.available;
1681
+ if (!this.vector.enabled) {
1682
+ this.vector.available = false;
1683
+ return false;
1684
+ }
1685
+ try {
1686
+ const resolvedPath = this.vector.extensionPath?.trim() ? resolveUserPath(this.vector.extensionPath) : void 0;
1687
+ const loaded = await loadSqliteVecExtension({
1688
+ db: this.db,
1689
+ extensionPath: resolvedPath
1690
+ });
1691
+ if (!loaded.ok) throw new Error(loaded.error ?? "unknown sqlite-vec load error");
1692
+ this.vector.extensionPath = loaded.extensionPath;
1693
+ this.vector.available = true;
1694
+ return true;
1695
+ } catch (err) {
1696
+ const message = err instanceof Error ? err.message : String(err);
1697
+ this.vector.available = false;
1698
+ this.vector.loadError = message;
1699
+ log.warn(`sqlite-vec unavailable: ${message}`);
1700
+ return false;
1701
+ }
1702
+ }
1703
+ ensureVectorTable(dimensions) {
1704
+ if (this.vector.dims === dimensions) return;
1705
+ if (this.vector.dims && this.vector.dims !== dimensions) this.dropVectorTable();
1706
+ this.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${VECTOR_TABLE} USING vec0(\n id TEXT PRIMARY KEY,\n embedding FLOAT[${dimensions}]\n)`);
1707
+ this.vector.dims = dimensions;
1708
+ }
1709
+ dropVectorTable() {
1710
+ try {
1711
+ this.db.exec(`DROP TABLE IF EXISTS ${VECTOR_TABLE}`);
1712
+ } catch (err) {
1713
+ const message = err instanceof Error ? err.message : String(err);
1714
+ log.debug(`Failed to drop ${VECTOR_TABLE}: ${message}`);
1715
+ }
1716
+ }
1717
+ buildSourceFilter(alias) {
1718
+ const sources = Array.from(this.sources);
1719
+ if (sources.length === 0) return {
1720
+ sql: "",
1721
+ params: []
1722
+ };
1723
+ return {
1724
+ sql: ` AND ${alias ? `${alias}.source` : "source"} IN (${sources.map(() => "?").join(", ")})`,
1725
+ params: sources
1726
+ };
1727
+ }
1728
+ openDatabase() {
1729
+ const dbPath = resolveUserPath(this.settings.store.path);
1730
+ return this.openDatabaseAtPath(dbPath);
1731
+ }
1732
+ openDatabaseAtPath(dbPath) {
1733
+ ensureDir(path.dirname(dbPath));
1734
+ const { DatabaseSync } = requireNodeSqlite();
1735
+ return new DatabaseSync(dbPath, { allowExtension: this.settings.store.vector.enabled });
1736
+ }
1737
+ seedEmbeddingCache(sourceDb) {
1738
+ if (!this.cache.enabled) return;
1739
+ try {
1740
+ const rows = sourceDb.prepare(`SELECT provider, model, provider_key, hash, embedding, dims, updated_at FROM ${EMBEDDING_CACHE_TABLE}`).all();
1741
+ if (!rows.length) return;
1742
+ const insert = this.db.prepare(`INSERT INTO ${EMBEDDING_CACHE_TABLE} (provider, model, provider_key, hash, embedding, dims, updated_at)
1743
+ VALUES (?, ?, ?, ?, ?, ?, ?)
1744
+ ON CONFLICT(provider, model, provider_key, hash) DO UPDATE SET
1745
+ embedding=excluded.embedding,
1746
+ dims=excluded.dims,
1747
+ updated_at=excluded.updated_at`);
1748
+ this.db.exec("BEGIN");
1749
+ for (const row of rows) insert.run(row.provider, row.model, row.provider_key, row.hash, row.embedding, row.dims, row.updated_at);
1750
+ this.db.exec("COMMIT");
1751
+ } catch (err) {
1752
+ try {
1753
+ this.db.exec("ROLLBACK");
1754
+ } catch {}
1755
+ throw err;
1756
+ }
1757
+ }
1758
+ async swapIndexFiles(targetPath, tempPath) {
1759
+ const backupPath = `${targetPath}.backup-${randomUUID()}`;
1760
+ await this.moveIndexFiles(targetPath, backupPath);
1761
+ try {
1762
+ await this.moveIndexFiles(tempPath, targetPath);
1763
+ } catch (err) {
1764
+ await this.moveIndexFiles(backupPath, targetPath);
1765
+ throw err;
1766
+ }
1767
+ await this.removeIndexFiles(backupPath);
1768
+ }
1769
+ async moveIndexFiles(sourceBase, targetBase) {
1770
+ for (const suffix of [
1771
+ "",
1772
+ "-wal",
1773
+ "-shm"
1774
+ ]) {
1775
+ const source = `${sourceBase}${suffix}`;
1776
+ const target = `${targetBase}${suffix}`;
1777
+ try {
1778
+ await fs$1.rename(source, target);
1779
+ } catch (err) {
1780
+ if (err.code !== "ENOENT") throw err;
1781
+ }
1782
+ }
1783
+ }
1784
+ async removeIndexFiles(basePath) {
1785
+ await Promise.all([
1786
+ "",
1787
+ "-wal",
1788
+ "-shm"
1789
+ ].map((suffix) => fs$1.rm(`${basePath}${suffix}`, { force: true })));
1790
+ }
1791
+ ensureSchema() {
1792
+ const result = ensureMemoryIndexSchema({
1793
+ db: this.db,
1794
+ embeddingCacheTable: EMBEDDING_CACHE_TABLE,
1795
+ ftsTable: FTS_TABLE,
1796
+ ftsEnabled: this.fts.enabled
1797
+ });
1798
+ this.fts.available = result.ftsAvailable;
1799
+ if (result.ftsError) {
1800
+ this.fts.loadError = result.ftsError;
1801
+ log.warn(`fts unavailable: ${result.ftsError}`);
1802
+ }
1803
+ }
1804
+ ensureWatcher() {
1805
+ if (!this.sources.has("memory") || !this.settings.sync.watch || this.watcher) return;
1806
+ const additionalPaths = normalizeExtraMemoryPaths(this.workspaceDir, this.settings.extraPaths).map((entry) => {
1807
+ try {
1808
+ return fs.lstatSync(entry).isSymbolicLink() ? null : entry;
1809
+ } catch {
1810
+ return null;
1811
+ }
1812
+ }).filter((entry) => Boolean(entry));
1813
+ const watchPaths = new Set([
1814
+ path.join(this.workspaceDir, "MEMORY.md"),
1815
+ path.join(this.workspaceDir, "memory.md"),
1816
+ path.join(this.workspaceDir, "memory"),
1817
+ ...additionalPaths
1818
+ ]);
1819
+ this.watcher = chokidar.watch(Array.from(watchPaths), {
1820
+ ignoreInitial: true,
1821
+ awaitWriteFinish: {
1822
+ stabilityThreshold: this.settings.sync.watchDebounceMs,
1823
+ pollInterval: 100
1824
+ }
1825
+ });
1826
+ const markDirty = () => {
1827
+ this.dirty = true;
1828
+ this.scheduleWatchSync();
1829
+ };
1830
+ this.watcher.on("add", markDirty);
1831
+ this.watcher.on("change", markDirty);
1832
+ this.watcher.on("unlink", markDirty);
1833
+ }
1834
+ ensureSessionListener() {
1835
+ if (!this.sources.has("sessions") || this.sessionUnsubscribe) return;
1836
+ this.sessionUnsubscribe = onSessionTranscriptUpdate((update) => {
1837
+ if (this.closed) return;
1838
+ const sessionFile = update.sessionFile;
1839
+ if (!this.isSessionFileForAgent(sessionFile)) return;
1840
+ this.scheduleSessionDirty(sessionFile);
1841
+ });
1842
+ }
1843
+ scheduleSessionDirty(sessionFile) {
1844
+ this.sessionPendingFiles.add(sessionFile);
1845
+ if (this.sessionWatchTimer) return;
1846
+ this.sessionWatchTimer = setTimeout(() => {
1847
+ this.sessionWatchTimer = null;
1848
+ this.processSessionDeltaBatch().catch((err) => {
1849
+ log.warn(`memory session delta failed: ${String(err)}`);
1850
+ });
1851
+ }, SESSION_DIRTY_DEBOUNCE_MS);
1852
+ }
1853
+ async processSessionDeltaBatch() {
1854
+ if (this.sessionPendingFiles.size === 0) return;
1855
+ const pending = Array.from(this.sessionPendingFiles);
1856
+ this.sessionPendingFiles.clear();
1857
+ let shouldSync = false;
1858
+ for (const sessionFile of pending) {
1859
+ const delta = await this.updateSessionDelta(sessionFile);
1860
+ if (!delta) continue;
1861
+ const bytesThreshold = delta.deltaBytes;
1862
+ const messagesThreshold = delta.deltaMessages;
1863
+ const bytesHit = bytesThreshold <= 0 ? delta.pendingBytes > 0 : delta.pendingBytes >= bytesThreshold;
1864
+ const messagesHit = messagesThreshold <= 0 ? delta.pendingMessages > 0 : delta.pendingMessages >= messagesThreshold;
1865
+ if (!bytesHit && !messagesHit) continue;
1866
+ this.sessionsDirtyFiles.add(sessionFile);
1867
+ this.sessionsDirty = true;
1868
+ delta.pendingBytes = bytesThreshold > 0 ? Math.max(0, delta.pendingBytes - bytesThreshold) : 0;
1869
+ delta.pendingMessages = messagesThreshold > 0 ? Math.max(0, delta.pendingMessages - messagesThreshold) : 0;
1870
+ shouldSync = true;
1871
+ }
1872
+ if (shouldSync) this.sync({ reason: "session-delta" }).catch((err) => {
1873
+ log.warn(`memory sync failed (session-delta): ${String(err)}`);
1874
+ });
1875
+ }
1876
+ async updateSessionDelta(sessionFile) {
1877
+ const thresholds = this.settings.sync.sessions;
1878
+ if (!thresholds) return null;
1879
+ let stat;
1880
+ try {
1881
+ stat = await fs$1.stat(sessionFile);
1882
+ } catch {
1883
+ return null;
1884
+ }
1885
+ const size = stat.size;
1886
+ let state = this.sessionDeltas.get(sessionFile);
1887
+ if (!state) {
1888
+ state = {
1889
+ lastSize: 0,
1890
+ pendingBytes: 0,
1891
+ pendingMessages: 0
1892
+ };
1893
+ this.sessionDeltas.set(sessionFile, state);
1894
+ }
1895
+ const deltaBytes = Math.max(0, size - state.lastSize);
1896
+ if (deltaBytes === 0 && size === state.lastSize) return {
1897
+ deltaBytes: thresholds.deltaBytes,
1898
+ deltaMessages: thresholds.deltaMessages,
1899
+ pendingBytes: state.pendingBytes,
1900
+ pendingMessages: state.pendingMessages
1901
+ };
1902
+ if (size < state.lastSize) {
1903
+ state.lastSize = size;
1904
+ state.pendingBytes += size;
1905
+ if (thresholds.deltaMessages > 0 && (thresholds.deltaBytes <= 0 || state.pendingBytes < thresholds.deltaBytes)) state.pendingMessages += await this.countNewlines(sessionFile, 0, size);
1906
+ } else {
1907
+ state.pendingBytes += deltaBytes;
1908
+ if (thresholds.deltaMessages > 0 && (thresholds.deltaBytes <= 0 || state.pendingBytes < thresholds.deltaBytes)) state.pendingMessages += await this.countNewlines(sessionFile, state.lastSize, size);
1909
+ state.lastSize = size;
1910
+ }
1911
+ this.sessionDeltas.set(sessionFile, state);
1912
+ return {
1913
+ deltaBytes: thresholds.deltaBytes,
1914
+ deltaMessages: thresholds.deltaMessages,
1915
+ pendingBytes: state.pendingBytes,
1916
+ pendingMessages: state.pendingMessages
1917
+ };
1918
+ }
1919
+ async countNewlines(absPath, start, end) {
1920
+ if (end <= start) return 0;
1921
+ const handle = await fs$1.open(absPath, "r");
1922
+ try {
1923
+ let offset = start;
1924
+ let count = 0;
1925
+ const buffer = Buffer.alloc(SESSION_DELTA_READ_CHUNK_BYTES);
1926
+ while (offset < end) {
1927
+ const toRead = Math.min(buffer.length, end - offset);
1928
+ const { bytesRead } = await handle.read(buffer, 0, toRead, offset);
1929
+ if (bytesRead <= 0) break;
1930
+ for (let i = 0; i < bytesRead; i += 1) if (buffer[i] === 10) count += 1;
1931
+ offset += bytesRead;
1932
+ }
1933
+ return count;
1934
+ } finally {
1935
+ await handle.close();
1936
+ }
1937
+ }
1938
+ resetSessionDelta(absPath, size) {
1939
+ const state = this.sessionDeltas.get(absPath);
1940
+ if (!state) return;
1941
+ state.lastSize = size;
1942
+ state.pendingBytes = 0;
1943
+ state.pendingMessages = 0;
1944
+ }
1945
+ isSessionFileForAgent(sessionFile) {
1946
+ if (!sessionFile) return false;
1947
+ const sessionsDir = resolveSessionTranscriptsDirForAgent(this.agentId);
1948
+ const resolvedFile = path.resolve(sessionFile);
1949
+ const resolvedDir = path.resolve(sessionsDir);
1950
+ return resolvedFile.startsWith(`${resolvedDir}${path.sep}`);
1951
+ }
1952
+ ensureIntervalSync() {
1953
+ const minutes = this.settings.sync.intervalMinutes;
1954
+ if (!minutes || minutes <= 0 || this.intervalTimer) return;
1955
+ const ms = minutes * 60 * 1e3;
1956
+ this.intervalTimer = setInterval(() => {
1957
+ this.sync({ reason: "interval" }).catch((err) => {
1958
+ log.warn(`memory sync failed (interval): ${String(err)}`);
1959
+ });
1960
+ }, ms);
1961
+ }
1962
+ scheduleWatchSync() {
1963
+ if (!this.sources.has("memory") || !this.settings.sync.watch) return;
1964
+ if (this.watchTimer) clearTimeout(this.watchTimer);
1965
+ this.watchTimer = setTimeout(() => {
1966
+ this.watchTimer = null;
1967
+ this.sync({ reason: "watch" }).catch((err) => {
1968
+ log.warn(`memory sync failed (watch): ${String(err)}`);
1969
+ });
1970
+ }, this.settings.sync.watchDebounceMs);
1971
+ }
1972
+ shouldSyncSessions(params, needsFullReindex = false) {
1973
+ if (!this.sources.has("sessions")) return false;
1974
+ if (params?.force) return true;
1975
+ const reason = params?.reason;
1976
+ if (reason === "session-start" || reason === "watch") return false;
1977
+ if (needsFullReindex) return true;
1978
+ return this.sessionsDirty && this.sessionsDirtyFiles.size > 0;
1979
+ }
1980
+ async syncMemoryFiles(params) {
1981
+ const files = await listMemoryFiles(this.workspaceDir, this.settings.extraPaths);
1982
+ const fileEntries = await Promise.all(files.map(async (file) => buildFileEntry(file, this.workspaceDir)));
1983
+ log.debug("memory sync: indexing memory files", {
1984
+ files: fileEntries.length,
1985
+ needsFullReindex: params.needsFullReindex,
1986
+ batch: this.batch.enabled,
1987
+ concurrency: this.getIndexConcurrency()
1988
+ });
1989
+ const activePaths = new Set(fileEntries.map((entry) => entry.path));
1990
+ if (params.progress) {
1991
+ params.progress.total += fileEntries.length;
1992
+ params.progress.report({
1993
+ completed: params.progress.completed,
1994
+ total: params.progress.total,
1995
+ label: this.batch.enabled ? "Indexing memory files (batch)..." : "Indexing memory files…"
1996
+ });
1997
+ }
1998
+ const tasks = fileEntries.map((entry) => async () => {
1999
+ const record = this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(entry.path, "memory");
2000
+ if (!params.needsFullReindex && record?.hash === entry.hash) {
2001
+ if (params.progress) {
2002
+ params.progress.completed += 1;
2003
+ params.progress.report({
2004
+ completed: params.progress.completed,
2005
+ total: params.progress.total
2006
+ });
2007
+ }
2008
+ return;
2009
+ }
2010
+ await this.indexFile(entry, { source: "memory" });
2011
+ if (params.progress) {
2012
+ params.progress.completed += 1;
2013
+ params.progress.report({
2014
+ completed: params.progress.completed,
2015
+ total: params.progress.total
2016
+ });
2017
+ }
2018
+ });
2019
+ await this.runWithConcurrency(tasks, this.getIndexConcurrency());
2020
+ const staleRows = this.db.prepare(`SELECT path FROM files WHERE source = ?`).all("memory");
2021
+ for (const stale of staleRows) {
2022
+ if (activePaths.has(stale.path)) continue;
2023
+ this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(stale.path, "memory");
2024
+ try {
2025
+ this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(stale.path, "memory");
2026
+ } catch {}
2027
+ this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(stale.path, "memory");
2028
+ if (this.fts.enabled && this.fts.available) try {
2029
+ this.db.prepare(`DELETE FROM ${FTS_TABLE} WHERE path = ? AND source = ? AND model = ?`).run(stale.path, "memory", this.provider.model);
2030
+ } catch {}
2031
+ }
2032
+ }
2033
+ async syncSessionFiles(params) {
2034
+ const files = await this.listSessionFiles();
2035
+ const activePaths = new Set(files.map((file) => this.sessionPathForFile(file)));
2036
+ const indexAll = params.needsFullReindex || this.sessionsDirtyFiles.size === 0;
2037
+ log.debug("memory sync: indexing session files", {
2038
+ files: files.length,
2039
+ indexAll,
2040
+ dirtyFiles: this.sessionsDirtyFiles.size,
2041
+ batch: this.batch.enabled,
2042
+ concurrency: this.getIndexConcurrency()
2043
+ });
2044
+ if (params.progress) {
2045
+ params.progress.total += files.length;
2046
+ params.progress.report({
2047
+ completed: params.progress.completed,
2048
+ total: params.progress.total,
2049
+ label: this.batch.enabled ? "Indexing session files (batch)..." : "Indexing session files…"
2050
+ });
2051
+ }
2052
+ const tasks = files.map((absPath) => async () => {
2053
+ if (!indexAll && !this.sessionsDirtyFiles.has(absPath)) {
2054
+ if (params.progress) {
2055
+ params.progress.completed += 1;
2056
+ params.progress.report({
2057
+ completed: params.progress.completed,
2058
+ total: params.progress.total
2059
+ });
2060
+ }
2061
+ return;
2062
+ }
2063
+ const entry = await this.buildSessionEntry(absPath);
2064
+ if (!entry) {
2065
+ if (params.progress) {
2066
+ params.progress.completed += 1;
2067
+ params.progress.report({
2068
+ completed: params.progress.completed,
2069
+ total: params.progress.total
2070
+ });
2071
+ }
2072
+ return;
2073
+ }
2074
+ const record = this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(entry.path, "sessions");
2075
+ if (!params.needsFullReindex && record?.hash === entry.hash) {
2076
+ if (params.progress) {
2077
+ params.progress.completed += 1;
2078
+ params.progress.report({
2079
+ completed: params.progress.completed,
2080
+ total: params.progress.total
2081
+ });
2082
+ }
2083
+ this.resetSessionDelta(absPath, entry.size);
2084
+ return;
2085
+ }
2086
+ await this.indexFile(entry, {
2087
+ source: "sessions",
2088
+ content: entry.content
2089
+ });
2090
+ this.resetSessionDelta(absPath, entry.size);
2091
+ if (params.progress) {
2092
+ params.progress.completed += 1;
2093
+ params.progress.report({
2094
+ completed: params.progress.completed,
2095
+ total: params.progress.total
2096
+ });
2097
+ }
2098
+ });
2099
+ await this.runWithConcurrency(tasks, this.getIndexConcurrency());
2100
+ const staleRows = this.db.prepare(`SELECT path FROM files WHERE source = ?`).all("sessions");
2101
+ for (const stale of staleRows) {
2102
+ if (activePaths.has(stale.path)) continue;
2103
+ this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(stale.path, "sessions");
2104
+ try {
2105
+ this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(stale.path, "sessions");
2106
+ } catch {}
2107
+ this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(stale.path, "sessions");
2108
+ if (this.fts.enabled && this.fts.available) try {
2109
+ this.db.prepare(`DELETE FROM ${FTS_TABLE} WHERE path = ? AND source = ? AND model = ?`).run(stale.path, "sessions", this.provider.model);
2110
+ } catch {}
2111
+ }
2112
+ }
2113
+ createSyncProgress(onProgress) {
2114
+ const state = {
2115
+ completed: 0,
2116
+ total: 0,
2117
+ label: void 0,
2118
+ report: (update) => {
2119
+ if (update.label) state.label = update.label;
2120
+ const label = update.total > 0 && state.label ? `${state.label} ${update.completed}/${update.total}` : state.label;
2121
+ onProgress({
2122
+ completed: update.completed,
2123
+ total: update.total,
2124
+ label
2125
+ });
2126
+ }
2127
+ };
2128
+ return state;
2129
+ }
2130
+ async runSync(params) {
2131
+ const progress = params?.progress ? this.createSyncProgress(params.progress) : void 0;
2132
+ if (progress) progress.report({
2133
+ completed: progress.completed,
2134
+ total: progress.total,
2135
+ label: "Loading vector extension…"
2136
+ });
2137
+ const vectorReady = await this.ensureVectorReady();
2138
+ const meta = this.readMeta();
2139
+ const needsFullReindex = params?.force || !meta || meta.model !== this.provider.model || meta.provider !== this.provider.id || meta.providerKey !== this.providerKey || meta.chunkTokens !== this.settings.chunking.tokens || meta.chunkOverlap !== this.settings.chunking.overlap || vectorReady && !meta?.vectorDims;
2140
+ try {
2141
+ if (needsFullReindex) {
2142
+ await this.runSafeReindex({
2143
+ reason: params?.reason,
2144
+ force: params?.force,
2145
+ progress: progress ?? void 0
2146
+ });
2147
+ return;
2148
+ }
2149
+ const shouldSyncMemory = this.sources.has("memory") && (params?.force || needsFullReindex || this.dirty);
2150
+ const shouldSyncSessions = this.shouldSyncSessions(params, needsFullReindex);
2151
+ if (shouldSyncMemory) {
2152
+ await this.syncMemoryFiles({
2153
+ needsFullReindex,
2154
+ progress: progress ?? void 0
2155
+ });
2156
+ this.dirty = false;
2157
+ }
2158
+ if (shouldSyncSessions) {
2159
+ await this.syncSessionFiles({
2160
+ needsFullReindex,
2161
+ progress: progress ?? void 0
2162
+ });
2163
+ this.sessionsDirty = false;
2164
+ this.sessionsDirtyFiles.clear();
2165
+ } else if (this.sessionsDirtyFiles.size > 0) this.sessionsDirty = true;
2166
+ else this.sessionsDirty = false;
2167
+ } catch (err) {
2168
+ const reason = err instanceof Error ? err.message : String(err);
2169
+ if (this.shouldFallbackOnError(reason) && await this.activateFallbackProvider(reason)) {
2170
+ await this.runSafeReindex({
2171
+ reason: params?.reason ?? "fallback",
2172
+ force: true,
2173
+ progress: progress ?? void 0
2174
+ });
2175
+ return;
2176
+ }
2177
+ throw err;
2178
+ }
2179
+ }
2180
+ shouldFallbackOnError(message) {
2181
+ return /embedding|embeddings|batch/i.test(message);
2182
+ }
2183
+ resolveBatchConfig() {
2184
+ const batch = this.settings.remote?.batch;
2185
+ return {
2186
+ enabled: Boolean(batch?.enabled && (this.openAi && this.provider.id === "openai" || this.gemini && this.provider.id === "gemini")),
2187
+ wait: batch?.wait ?? true,
2188
+ concurrency: Math.max(1, batch?.concurrency ?? 2),
2189
+ pollIntervalMs: batch?.pollIntervalMs ?? 2e3,
2190
+ timeoutMs: (batch?.timeoutMinutes ?? 60) * 60 * 1e3
2191
+ };
2192
+ }
2193
+ async activateFallbackProvider(reason) {
2194
+ const fallback = this.settings.fallback;
2195
+ if (!fallback || fallback === "none" || fallback === this.provider.id) return false;
2196
+ if (this.fallbackFrom) return false;
2197
+ const fallbackFrom = this.provider.id;
2198
+ const fallbackModel = fallback === "gemini" ? DEFAULT_GEMINI_EMBEDDING_MODEL : fallback === "openai" ? DEFAULT_OPENAI_EMBEDDING_MODEL : this.settings.model;
2199
+ const fallbackResult = await createEmbeddingProvider({
2200
+ config: this.cfg,
2201
+ agentDir: resolveAgentDir(this.cfg, this.agentId),
2202
+ provider: fallback,
2203
+ remote: this.settings.remote,
2204
+ model: fallbackModel,
2205
+ fallback: "none",
2206
+ local: this.settings.local
2207
+ });
2208
+ this.fallbackFrom = fallbackFrom;
2209
+ this.fallbackReason = reason;
2210
+ this.provider = fallbackResult.provider;
2211
+ this.openAi = fallbackResult.openAi;
2212
+ this.gemini = fallbackResult.gemini;
2213
+ this.providerKey = this.computeProviderKey();
2214
+ this.batch = this.resolveBatchConfig();
2215
+ log.warn(`memory embeddings: switched to fallback provider (${fallback})`, { reason });
2216
+ return true;
2217
+ }
2218
+ async runSafeReindex(params) {
2219
+ const dbPath = resolveUserPath(this.settings.store.path);
2220
+ const tempDbPath = `${dbPath}.tmp-${randomUUID()}`;
2221
+ const tempDb = this.openDatabaseAtPath(tempDbPath);
2222
+ const originalDb = this.db;
2223
+ let originalDbClosed = false;
2224
+ const originalState = {
2225
+ ftsAvailable: this.fts.available,
2226
+ ftsError: this.fts.loadError,
2227
+ vectorAvailable: this.vector.available,
2228
+ vectorLoadError: this.vector.loadError,
2229
+ vectorDims: this.vector.dims,
2230
+ vectorReady: this.vectorReady
2231
+ };
2232
+ const restoreOriginalState = () => {
2233
+ if (originalDbClosed) this.db = this.openDatabaseAtPath(dbPath);
2234
+ else this.db = originalDb;
2235
+ this.fts.available = originalState.ftsAvailable;
2236
+ this.fts.loadError = originalState.ftsError;
2237
+ this.vector.available = originalDbClosed ? null : originalState.vectorAvailable;
2238
+ this.vector.loadError = originalState.vectorLoadError;
2239
+ this.vector.dims = originalState.vectorDims;
2240
+ this.vectorReady = originalDbClosed ? null : originalState.vectorReady;
2241
+ };
2242
+ this.db = tempDb;
2243
+ this.vectorReady = null;
2244
+ this.vector.available = null;
2245
+ this.vector.loadError = void 0;
2246
+ this.vector.dims = void 0;
2247
+ this.fts.available = false;
2248
+ this.fts.loadError = void 0;
2249
+ this.ensureSchema();
2250
+ let nextMeta = null;
2251
+ try {
2252
+ this.seedEmbeddingCache(originalDb);
2253
+ const shouldSyncMemory = this.sources.has("memory");
2254
+ const shouldSyncSessions = this.shouldSyncSessions({
2255
+ reason: params.reason,
2256
+ force: params.force
2257
+ }, true);
2258
+ if (shouldSyncMemory) {
2259
+ await this.syncMemoryFiles({
2260
+ needsFullReindex: true,
2261
+ progress: params.progress
2262
+ });
2263
+ this.dirty = false;
2264
+ }
2265
+ if (shouldSyncSessions) {
2266
+ await this.syncSessionFiles({
2267
+ needsFullReindex: true,
2268
+ progress: params.progress
2269
+ });
2270
+ this.sessionsDirty = false;
2271
+ this.sessionsDirtyFiles.clear();
2272
+ } else if (this.sessionsDirtyFiles.size > 0) this.sessionsDirty = true;
2273
+ else this.sessionsDirty = false;
2274
+ nextMeta = {
2275
+ model: this.provider.model,
2276
+ provider: this.provider.id,
2277
+ providerKey: this.providerKey,
2278
+ chunkTokens: this.settings.chunking.tokens,
2279
+ chunkOverlap: this.settings.chunking.overlap
2280
+ };
2281
+ if (this.vector.available && this.vector.dims) nextMeta.vectorDims = this.vector.dims;
2282
+ this.writeMeta(nextMeta);
2283
+ this.pruneEmbeddingCacheIfNeeded();
2284
+ this.db.close();
2285
+ originalDb.close();
2286
+ originalDbClosed = true;
2287
+ await this.swapIndexFiles(dbPath, tempDbPath);
2288
+ this.db = this.openDatabaseAtPath(dbPath);
2289
+ this.vectorReady = null;
2290
+ this.vector.available = null;
2291
+ this.vector.loadError = void 0;
2292
+ this.ensureSchema();
2293
+ this.vector.dims = nextMeta.vectorDims;
2294
+ } catch (err) {
2295
+ try {
2296
+ this.db.close();
2297
+ } catch {}
2298
+ await this.removeIndexFiles(tempDbPath);
2299
+ restoreOriginalState();
2300
+ throw err;
2301
+ }
2302
+ }
2303
+ resetIndex() {
2304
+ this.db.exec(`DELETE FROM files`);
2305
+ this.db.exec(`DELETE FROM chunks`);
2306
+ if (this.fts.enabled && this.fts.available) try {
2307
+ this.db.exec(`DELETE FROM ${FTS_TABLE}`);
2308
+ } catch {}
2309
+ this.dropVectorTable();
2310
+ this.vector.dims = void 0;
2311
+ this.sessionsDirtyFiles.clear();
2312
+ }
2313
+ readMeta() {
2314
+ const row = this.db.prepare(`SELECT value FROM meta WHERE key = ?`).get(META_KEY);
2315
+ if (!row?.value) return null;
2316
+ try {
2317
+ return JSON.parse(row.value);
2318
+ } catch {
2319
+ return null;
2320
+ }
2321
+ }
2322
+ writeMeta(meta) {
2323
+ const value = JSON.stringify(meta);
2324
+ this.db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(META_KEY, value);
2325
+ }
2326
+ async listSessionFiles() {
2327
+ const dir = resolveSessionTranscriptsDirForAgent(this.agentId);
2328
+ try {
2329
+ return (await fs$1.readdir(dir, { withFileTypes: true })).filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.endsWith(".jsonl")).map((name) => path.join(dir, name));
2330
+ } catch {
2331
+ return [];
2332
+ }
2333
+ }
2334
+ sessionPathForFile(absPath) {
2335
+ return path.join("sessions", path.basename(absPath)).replace(/\\/g, "/");
2336
+ }
2337
+ normalizeSessionText(value) {
2338
+ return value.replace(/\s*\n+\s*/g, " ").replace(/\s+/g, " ").trim();
2339
+ }
2340
+ extractSessionText(content) {
2341
+ if (typeof content === "string") {
2342
+ const normalized = this.normalizeSessionText(content);
2343
+ return normalized ? normalized : null;
2344
+ }
2345
+ if (!Array.isArray(content)) return null;
2346
+ const parts = [];
2347
+ for (const block of content) {
2348
+ if (!block || typeof block !== "object") continue;
2349
+ const record = block;
2350
+ if (record.type !== "text" || typeof record.text !== "string") continue;
2351
+ const normalized = this.normalizeSessionText(record.text);
2352
+ if (normalized) parts.push(normalized);
2353
+ }
2354
+ if (parts.length === 0) return null;
2355
+ return parts.join(" ");
2356
+ }
2357
+ async buildSessionEntry(absPath) {
2358
+ try {
2359
+ const stat = await fs$1.stat(absPath);
2360
+ const lines = (await fs$1.readFile(absPath, "utf-8")).split("\n");
2361
+ const collected = [];
2362
+ for (const line of lines) {
2363
+ if (!line.trim()) continue;
2364
+ let record;
2365
+ try {
2366
+ record = JSON.parse(line);
2367
+ } catch {
2368
+ continue;
2369
+ }
2370
+ if (!record || typeof record !== "object" || record.type !== "message") continue;
2371
+ const message = record.message;
2372
+ if (!message || typeof message.role !== "string") continue;
2373
+ if (message.role !== "user" && message.role !== "assistant") continue;
2374
+ const text = this.extractSessionText(message.content);
2375
+ if (!text) continue;
2376
+ const label = message.role === "user" ? "User" : "Assistant";
2377
+ collected.push(`${label}: ${text}`);
2378
+ }
2379
+ const content = collected.join("\n");
2380
+ return {
2381
+ path: this.sessionPathForFile(absPath),
2382
+ absPath,
2383
+ mtimeMs: stat.mtimeMs,
2384
+ size: stat.size,
2385
+ hash: hashText(content),
2386
+ content
2387
+ };
2388
+ } catch (err) {
2389
+ log.debug(`Failed reading session file ${absPath}: ${String(err)}`);
2390
+ return null;
2391
+ }
2392
+ }
2393
+ estimateEmbeddingTokens(text) {
2394
+ if (!text) return 0;
2395
+ return Math.ceil(text.length / EMBEDDING_APPROX_CHARS_PER_TOKEN);
2396
+ }
2397
+ buildEmbeddingBatches(chunks) {
2398
+ const batches = [];
2399
+ let current = [];
2400
+ let currentTokens = 0;
2401
+ for (const chunk of chunks) {
2402
+ const estimate = this.estimateEmbeddingTokens(chunk.text);
2403
+ if (current.length > 0 && currentTokens + estimate > EMBEDDING_BATCH_MAX_TOKENS) {
2404
+ batches.push(current);
2405
+ current = [];
2406
+ currentTokens = 0;
2407
+ }
2408
+ if (current.length === 0 && estimate > EMBEDDING_BATCH_MAX_TOKENS) {
2409
+ batches.push([chunk]);
2410
+ continue;
2411
+ }
2412
+ current.push(chunk);
2413
+ currentTokens += estimate;
2414
+ }
2415
+ if (current.length > 0) batches.push(current);
2416
+ return batches;
2417
+ }
2418
+ loadEmbeddingCache(hashes) {
2419
+ if (!this.cache.enabled) return /* @__PURE__ */ new Map();
2420
+ if (hashes.length === 0) return /* @__PURE__ */ new Map();
2421
+ const unique = [];
2422
+ const seen = /* @__PURE__ */ new Set();
2423
+ for (const hash of hashes) {
2424
+ if (!hash) continue;
2425
+ if (seen.has(hash)) continue;
2426
+ seen.add(hash);
2427
+ unique.push(hash);
2428
+ }
2429
+ if (unique.length === 0) return /* @__PURE__ */ new Map();
2430
+ const out = /* @__PURE__ */ new Map();
2431
+ const baseParams = [
2432
+ this.provider.id,
2433
+ this.provider.model,
2434
+ this.providerKey
2435
+ ];
2436
+ const batchSize = 400;
2437
+ for (let start = 0; start < unique.length; start += batchSize) {
2438
+ const batch = unique.slice(start, start + batchSize);
2439
+ const placeholders = batch.map(() => "?").join(", ");
2440
+ const rows = this.db.prepare(`SELECT hash, embedding FROM ${EMBEDDING_CACHE_TABLE}\n WHERE provider = ? AND model = ? AND provider_key = ? AND hash IN (${placeholders})`).all(...baseParams, ...batch);
2441
+ for (const row of rows) out.set(row.hash, parseEmbedding(row.embedding));
2442
+ }
2443
+ return out;
2444
+ }
2445
+ upsertEmbeddingCache(entries) {
2446
+ if (!this.cache.enabled) return;
2447
+ if (entries.length === 0) return;
2448
+ const now = Date.now();
2449
+ const stmt = this.db.prepare(`INSERT INTO ${EMBEDDING_CACHE_TABLE} (provider, model, provider_key, hash, embedding, dims, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(provider, model, provider_key, hash) DO UPDATE SET\n embedding=excluded.embedding,\n dims=excluded.dims,\n updated_at=excluded.updated_at`);
2450
+ for (const entry of entries) {
2451
+ const embedding = entry.embedding ?? [];
2452
+ stmt.run(this.provider.id, this.provider.model, this.providerKey, entry.hash, JSON.stringify(embedding), embedding.length, now);
2453
+ }
2454
+ }
2455
+ pruneEmbeddingCacheIfNeeded() {
2456
+ if (!this.cache.enabled) return;
2457
+ const max = this.cache.maxEntries;
2458
+ if (!max || max <= 0) return;
2459
+ const count = this.db.prepare(`SELECT COUNT(*) as c FROM ${EMBEDDING_CACHE_TABLE}`).get()?.c ?? 0;
2460
+ if (count <= max) return;
2461
+ const excess = count - max;
2462
+ this.db.prepare(`DELETE FROM ${EMBEDDING_CACHE_TABLE}\n WHERE rowid IN (\n SELECT rowid FROM ${EMBEDDING_CACHE_TABLE}\n ORDER BY updated_at ASC\n LIMIT ?\n )`).run(excess);
2463
+ }
2464
+ async embedChunksInBatches(chunks) {
2465
+ if (chunks.length === 0) return [];
2466
+ const cached = this.loadEmbeddingCache(chunks.map((chunk) => chunk.hash));
2467
+ const embeddings = Array.from({ length: chunks.length }, () => []);
2468
+ const missing = [];
2469
+ for (let i = 0; i < chunks.length; i += 1) {
2470
+ const chunk = chunks[i];
2471
+ const hit = chunk?.hash ? cached.get(chunk.hash) : void 0;
2472
+ if (hit && hit.length > 0) embeddings[i] = hit;
2473
+ else if (chunk) missing.push({
2474
+ index: i,
2475
+ chunk
2476
+ });
2477
+ }
2478
+ if (missing.length === 0) return embeddings;
2479
+ const missingChunks = missing.map((m) => m.chunk);
2480
+ const batches = this.buildEmbeddingBatches(missingChunks);
2481
+ const toCache = [];
2482
+ let cursor = 0;
2483
+ for (const batch of batches) {
2484
+ const batchEmbeddings = await this.embedBatchWithRetry(batch.map((chunk) => chunk.text));
2485
+ for (let i = 0; i < batch.length; i += 1) {
2486
+ const item = missing[cursor + i];
2487
+ const embedding = batchEmbeddings[i] ?? [];
2488
+ if (item) {
2489
+ embeddings[item.index] = embedding;
2490
+ toCache.push({
2491
+ hash: item.chunk.hash,
2492
+ embedding
2493
+ });
2494
+ }
2495
+ }
2496
+ cursor += batch.length;
2497
+ }
2498
+ this.upsertEmbeddingCache(toCache);
2499
+ return embeddings;
2500
+ }
2501
+ computeProviderKey() {
2502
+ if (this.provider.id === "openai" && this.openAi) {
2503
+ const entries = Object.entries(this.openAi.headers).filter(([key]) => key.toLowerCase() !== "authorization").toSorted(([a], [b]) => a.localeCompare(b)).map(([key, value]) => [key, value]);
2504
+ return hashText(JSON.stringify({
2505
+ provider: "openai",
2506
+ baseUrl: this.openAi.baseUrl,
2507
+ model: this.openAi.model,
2508
+ headers: entries
2509
+ }));
2510
+ }
2511
+ if (this.provider.id === "gemini" && this.gemini) {
2512
+ const entries = Object.entries(this.gemini.headers).filter(([key]) => {
2513
+ const lower = key.toLowerCase();
2514
+ return lower !== "authorization" && lower !== "x-goog-api-key";
2515
+ }).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, value]) => [key, value]);
2516
+ return hashText(JSON.stringify({
2517
+ provider: "gemini",
2518
+ baseUrl: this.gemini.baseUrl,
2519
+ model: this.gemini.model,
2520
+ headers: entries
2521
+ }));
2522
+ }
2523
+ return hashText(JSON.stringify({
2524
+ provider: this.provider.id,
2525
+ model: this.provider.model
2526
+ }));
2527
+ }
2528
+ async embedChunksWithBatch(chunks, entry, source) {
2529
+ if (this.provider.id === "openai" && this.openAi) return this.embedChunksWithOpenAiBatch(chunks, entry, source);
2530
+ if (this.provider.id === "gemini" && this.gemini) return this.embedChunksWithGeminiBatch(chunks, entry, source);
2531
+ return this.embedChunksInBatches(chunks);
2532
+ }
2533
+ async embedChunksWithOpenAiBatch(chunks, entry, source) {
2534
+ const openAi = this.openAi;
2535
+ if (!openAi) return this.embedChunksInBatches(chunks);
2536
+ if (chunks.length === 0) return [];
2537
+ const cached = this.loadEmbeddingCache(chunks.map((chunk) => chunk.hash));
2538
+ const embeddings = Array.from({ length: chunks.length }, () => []);
2539
+ const missing = [];
2540
+ for (let i = 0; i < chunks.length; i += 1) {
2541
+ const chunk = chunks[i];
2542
+ const hit = chunk?.hash ? cached.get(chunk.hash) : void 0;
2543
+ if (hit && hit.length > 0) embeddings[i] = hit;
2544
+ else if (chunk) missing.push({
2545
+ index: i,
2546
+ chunk
2547
+ });
2548
+ }
2549
+ if (missing.length === 0) return embeddings;
2550
+ const requests = [];
2551
+ const mapping = /* @__PURE__ */ new Map();
2552
+ for (const item of missing) {
2553
+ const chunk = item.chunk;
2554
+ const customId = hashText(`${source}:${entry.path}:${chunk.startLine}:${chunk.endLine}:${chunk.hash}:${item.index}`);
2555
+ mapping.set(customId, {
2556
+ index: item.index,
2557
+ hash: chunk.hash
2558
+ });
2559
+ requests.push({
2560
+ custom_id: customId,
2561
+ method: "POST",
2562
+ url: OPENAI_BATCH_ENDPOINT,
2563
+ body: {
2564
+ model: this.openAi?.model ?? this.provider.model,
2565
+ input: chunk.text
2566
+ }
2567
+ });
2568
+ }
2569
+ const batchResult = await this.runBatchWithFallback({
2570
+ provider: "openai",
2571
+ run: async () => await runOpenAiEmbeddingBatches({
2572
+ openAi,
2573
+ agentId: this.agentId,
2574
+ requests,
2575
+ wait: this.batch.wait,
2576
+ concurrency: this.batch.concurrency,
2577
+ pollIntervalMs: this.batch.pollIntervalMs,
2578
+ timeoutMs: this.batch.timeoutMs,
2579
+ debug: (message, data) => log.debug(message, {
2580
+ ...data,
2581
+ source,
2582
+ chunks: chunks.length
2583
+ })
2584
+ }),
2585
+ fallback: async () => await this.embedChunksInBatches(chunks)
2586
+ });
2587
+ if (Array.isArray(batchResult)) return batchResult;
2588
+ const byCustomId = batchResult;
2589
+ const toCache = [];
2590
+ for (const [customId, embedding] of byCustomId.entries()) {
2591
+ const mapped = mapping.get(customId);
2592
+ if (!mapped) continue;
2593
+ embeddings[mapped.index] = embedding;
2594
+ toCache.push({
2595
+ hash: mapped.hash,
2596
+ embedding
2597
+ });
2598
+ }
2599
+ this.upsertEmbeddingCache(toCache);
2600
+ return embeddings;
2601
+ }
2602
+ async embedChunksWithGeminiBatch(chunks, entry, source) {
2603
+ const gemini = this.gemini;
2604
+ if (!gemini) return this.embedChunksInBatches(chunks);
2605
+ if (chunks.length === 0) return [];
2606
+ const cached = this.loadEmbeddingCache(chunks.map((chunk) => chunk.hash));
2607
+ const embeddings = Array.from({ length: chunks.length }, () => []);
2608
+ const missing = [];
2609
+ for (let i = 0; i < chunks.length; i += 1) {
2610
+ const chunk = chunks[i];
2611
+ const hit = chunk?.hash ? cached.get(chunk.hash) : void 0;
2612
+ if (hit && hit.length > 0) embeddings[i] = hit;
2613
+ else if (chunk) missing.push({
2614
+ index: i,
2615
+ chunk
2616
+ });
2617
+ }
2618
+ if (missing.length === 0) return embeddings;
2619
+ const requests = [];
2620
+ const mapping = /* @__PURE__ */ new Map();
2621
+ for (const item of missing) {
2622
+ const chunk = item.chunk;
2623
+ const customId = hashText(`${source}:${entry.path}:${chunk.startLine}:${chunk.endLine}:${chunk.hash}:${item.index}`);
2624
+ mapping.set(customId, {
2625
+ index: item.index,
2626
+ hash: chunk.hash
2627
+ });
2628
+ requests.push({
2629
+ custom_id: customId,
2630
+ content: { parts: [{ text: chunk.text }] },
2631
+ taskType: "RETRIEVAL_DOCUMENT"
2632
+ });
2633
+ }
2634
+ const batchResult = await this.runBatchWithFallback({
2635
+ provider: "gemini",
2636
+ run: async () => await runGeminiEmbeddingBatches({
2637
+ gemini,
2638
+ agentId: this.agentId,
2639
+ requests,
2640
+ wait: this.batch.wait,
2641
+ concurrency: this.batch.concurrency,
2642
+ pollIntervalMs: this.batch.pollIntervalMs,
2643
+ timeoutMs: this.batch.timeoutMs,
2644
+ debug: (message, data) => log.debug(message, {
2645
+ ...data,
2646
+ source,
2647
+ chunks: chunks.length
2648
+ })
2649
+ }),
2650
+ fallback: async () => await this.embedChunksInBatches(chunks)
2651
+ });
2652
+ if (Array.isArray(batchResult)) return batchResult;
2653
+ const byCustomId = batchResult;
2654
+ const toCache = [];
2655
+ for (const [customId, embedding] of byCustomId.entries()) {
2656
+ const mapped = mapping.get(customId);
2657
+ if (!mapped) continue;
2658
+ embeddings[mapped.index] = embedding;
2659
+ toCache.push({
2660
+ hash: mapped.hash,
2661
+ embedding
2662
+ });
2663
+ }
2664
+ this.upsertEmbeddingCache(toCache);
2665
+ return embeddings;
2666
+ }
2667
+ async embedBatchWithRetry(texts) {
2668
+ if (texts.length === 0) return [];
2669
+ let attempt = 0;
2670
+ let delayMs = EMBEDDING_RETRY_BASE_DELAY_MS;
2671
+ while (true) try {
2672
+ const timeoutMs = this.resolveEmbeddingTimeout("batch");
2673
+ log.debug("memory embeddings: batch start", {
2674
+ provider: this.provider.id,
2675
+ items: texts.length,
2676
+ timeoutMs
2677
+ });
2678
+ return await this.withTimeout(this.provider.embedBatch(texts), timeoutMs, `memory embeddings batch timed out after ${Math.round(timeoutMs / 1e3)}s`);
2679
+ } catch (err) {
2680
+ const message = err instanceof Error ? err.message : String(err);
2681
+ if (!this.isRetryableEmbeddingError(message) || attempt >= EMBEDDING_RETRY_MAX_ATTEMPTS) throw err;
2682
+ const waitMs = Math.min(EMBEDDING_RETRY_MAX_DELAY_MS, Math.round(delayMs * (1 + Math.random() * .2)));
2683
+ log.warn(`memory embeddings rate limited; retrying in ${waitMs}ms`);
2684
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
2685
+ delayMs *= 2;
2686
+ attempt += 1;
2687
+ }
2688
+ }
2689
+ isRetryableEmbeddingError(message) {
2690
+ return /(rate[_ ]limit|too many requests|429|resource has been exhausted|5\d\d|cloudflare)/i.test(message);
2691
+ }
2692
+ resolveEmbeddingTimeout(kind) {
2693
+ const isLocal = this.provider.id === "local";
2694
+ if (kind === "query") return isLocal ? EMBEDDING_QUERY_TIMEOUT_LOCAL_MS : EMBEDDING_QUERY_TIMEOUT_REMOTE_MS;
2695
+ return isLocal ? EMBEDDING_BATCH_TIMEOUT_LOCAL_MS : EMBEDDING_BATCH_TIMEOUT_REMOTE_MS;
2696
+ }
2697
+ async embedQueryWithTimeout(text) {
2698
+ const timeoutMs = this.resolveEmbeddingTimeout("query");
2699
+ log.debug("memory embeddings: query start", {
2700
+ provider: this.provider.id,
2701
+ timeoutMs
2702
+ });
2703
+ return await this.withTimeout(this.provider.embedQuery(text), timeoutMs, `memory embeddings query timed out after ${Math.round(timeoutMs / 1e3)}s`);
2704
+ }
2705
+ async withTimeout(promise, timeoutMs, message) {
2706
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) return await promise;
2707
+ let timer = null;
2708
+ const timeoutPromise = new Promise((_, reject) => {
2709
+ timer = setTimeout(() => reject(new Error(message)), timeoutMs);
2710
+ });
2711
+ try {
2712
+ return await Promise.race([promise, timeoutPromise]);
2713
+ } finally {
2714
+ if (timer) clearTimeout(timer);
2715
+ }
2716
+ }
2717
+ async runWithConcurrency(tasks, limit) {
2718
+ if (tasks.length === 0) return [];
2719
+ const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
2720
+ const results = Array.from({ length: tasks.length });
2721
+ let next = 0;
2722
+ let firstError = null;
2723
+ const workers = Array.from({ length: resolvedLimit }, async () => {
2724
+ while (true) {
2725
+ if (firstError) return;
2726
+ const index = next;
2727
+ next += 1;
2728
+ if (index >= tasks.length) return;
2729
+ try {
2730
+ results[index] = await tasks[index]();
2731
+ } catch (err) {
2732
+ firstError = err;
2733
+ return;
2734
+ }
2735
+ }
2736
+ });
2737
+ await Promise.allSettled(workers);
2738
+ if (firstError) throw firstError;
2739
+ return results;
2740
+ }
2741
+ async withBatchFailureLock(fn) {
2742
+ let release;
2743
+ const wait = this.batchFailureLock;
2744
+ this.batchFailureLock = new Promise((resolve) => {
2745
+ release = resolve;
2746
+ });
2747
+ await wait;
2748
+ try {
2749
+ return await fn();
2750
+ } finally {
2751
+ release();
2752
+ }
2753
+ }
2754
+ async resetBatchFailureCount() {
2755
+ await this.withBatchFailureLock(async () => {
2756
+ if (this.batchFailureCount > 0) log.debug("memory embeddings: batch recovered; resetting failure count");
2757
+ this.batchFailureCount = 0;
2758
+ this.batchFailureLastError = void 0;
2759
+ this.batchFailureLastProvider = void 0;
2760
+ });
2761
+ }
2762
+ async recordBatchFailure(params) {
2763
+ return await this.withBatchFailureLock(async () => {
2764
+ if (!this.batch.enabled) return {
2765
+ disabled: true,
2766
+ count: this.batchFailureCount
2767
+ };
2768
+ const increment = params.forceDisable ? BATCH_FAILURE_LIMIT : Math.max(1, params.attempts ?? 1);
2769
+ this.batchFailureCount += increment;
2770
+ this.batchFailureLastError = params.message;
2771
+ this.batchFailureLastProvider = params.provider;
2772
+ const disabled = params.forceDisable || this.batchFailureCount >= BATCH_FAILURE_LIMIT;
2773
+ if (disabled) this.batch.enabled = false;
2774
+ return {
2775
+ disabled,
2776
+ count: this.batchFailureCount
2777
+ };
2778
+ });
2779
+ }
2780
+ isBatchTimeoutError(message) {
2781
+ return /timed out|timeout/i.test(message);
2782
+ }
2783
+ async runBatchWithTimeoutRetry(params) {
2784
+ try {
2785
+ return await params.run();
2786
+ } catch (err) {
2787
+ const message = err instanceof Error ? err.message : String(err);
2788
+ if (this.isBatchTimeoutError(message)) {
2789
+ log.warn(`memory embeddings: ${params.provider} batch timed out; retrying once`);
2790
+ try {
2791
+ return await params.run();
2792
+ } catch (retryErr) {
2793
+ retryErr.batchAttempts = 2;
2794
+ throw retryErr;
2795
+ }
2796
+ }
2797
+ throw err;
2798
+ }
2799
+ }
2800
+ async runBatchWithFallback(params) {
2801
+ if (!this.batch.enabled) return await params.fallback();
2802
+ try {
2803
+ const result = await this.runBatchWithTimeoutRetry({
2804
+ provider: params.provider,
2805
+ run: params.run
2806
+ });
2807
+ await this.resetBatchFailureCount();
2808
+ return result;
2809
+ } catch (err) {
2810
+ const message = err instanceof Error ? err.message : String(err);
2811
+ const attempts = err.batchAttempts ?? 1;
2812
+ const forceDisable = /asyncBatchEmbedContent not available/i.test(message);
2813
+ const failure = await this.recordBatchFailure({
2814
+ provider: params.provider,
2815
+ message,
2816
+ attempts,
2817
+ forceDisable
2818
+ });
2819
+ const suffix = failure.disabled ? "disabling batch" : "keeping batch enabled";
2820
+ log.warn(`memory embeddings: ${params.provider} batch failed (${failure.count}/${BATCH_FAILURE_LIMIT}); ${suffix}; falling back to non-batch embeddings: ${message}`);
2821
+ return await params.fallback();
2822
+ }
2823
+ }
2824
+ getIndexConcurrency() {
2825
+ return this.batch.enabled ? this.batch.concurrency : EMBEDDING_INDEX_CONCURRENCY;
2826
+ }
2827
+ async indexFile(entry, options) {
2828
+ const chunks = chunkMarkdown(options.content ?? await fs$1.readFile(entry.absPath, "utf-8"), this.settings.chunking).filter((chunk) => chunk.text.trim().length > 0);
2829
+ const embeddings = this.batch.enabled ? await this.embedChunksWithBatch(chunks, entry, options.source) : await this.embedChunksInBatches(chunks);
2830
+ const sample = embeddings.find((embedding) => embedding.length > 0);
2831
+ const vectorReady = sample ? await this.ensureVectorReady(sample.length) : false;
2832
+ const now = Date.now();
2833
+ if (vectorReady) try {
2834
+ this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(entry.path, options.source);
2835
+ } catch {}
2836
+ if (this.fts.enabled && this.fts.available) try {
2837
+ this.db.prepare(`DELETE FROM ${FTS_TABLE} WHERE path = ? AND source = ? AND model = ?`).run(entry.path, options.source, this.provider.model);
2838
+ } catch {}
2839
+ this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(entry.path, options.source);
2840
+ for (let i = 0; i < chunks.length; i++) {
2841
+ const chunk = chunks[i];
2842
+ const embedding = embeddings[i] ?? [];
2843
+ const id = hashText(`${options.source}:${entry.path}:${chunk.startLine}:${chunk.endLine}:${chunk.hash}:${this.provider.model}`);
2844
+ this.db.prepare(`INSERT INTO chunks (id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)
2845
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2846
+ ON CONFLICT(id) DO UPDATE SET
2847
+ hash=excluded.hash,
2848
+ model=excluded.model,
2849
+ text=excluded.text,
2850
+ embedding=excluded.embedding,
2851
+ updated_at=excluded.updated_at`).run(id, entry.path, options.source, chunk.startLine, chunk.endLine, chunk.hash, this.provider.model, chunk.text, JSON.stringify(embedding), now);
2852
+ if (vectorReady && embedding.length > 0) {
2853
+ try {
2854
+ this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE id = ?`).run(id);
2855
+ } catch {}
2856
+ this.db.prepare(`INSERT INTO ${VECTOR_TABLE} (id, embedding) VALUES (?, ?)`).run(id, vectorToBlob(embedding));
2857
+ }
2858
+ if (this.fts.enabled && this.fts.available) this.db.prepare(`INSERT INTO ${FTS_TABLE} (text, id, path, source, model, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`).run(chunk.text, id, entry.path, options.source, this.provider.model, chunk.startLine, chunk.endLine);
2859
+ }
2860
+ this.db.prepare(`INSERT INTO files (path, source, hash, mtime, size) VALUES (?, ?, ?, ?, ?)
2861
+ ON CONFLICT(path) DO UPDATE SET
2862
+ source=excluded.source,
2863
+ hash=excluded.hash,
2864
+ mtime=excluded.mtime,
2865
+ size=excluded.size`).run(entry.path, options.source, entry.hash, entry.mtimeMs, entry.size);
2866
+ }
2867
+ };
2868
+
2869
+ //#endregion
2870
+ export { retryAsync as i, resolveMemorySearchConfig as n, resolveRetryConfig as r, manager_exports as t };