@xopcai/xopc 0.0.116 → 0.0.118

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 (677) hide show
  1. package/README.md +44 -28
  2. package/README.zh-CN.md +63 -45
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/demo-memory/src/index.d.ts +6 -0
  5. package/dist/extensions/demo-memory/src/index.js +132 -0
  6. package/dist/extensions/demo-memory/src/index.js.map +1 -0
  7. package/dist/extensions/demo-memory/xopc.extension.json +15 -0
  8. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  9. package/dist/extensions/feishu/src/schema/config-schema.d.ts +3 -3
  10. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  11. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  12. package/dist/extensions/telegram/src/command-handler.js +1 -2
  13. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  14. package/dist/extensions/telegram/src/config-schema.d.ts +8 -8
  15. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  16. package/dist/extensions/telegram/src/plugin.js +1 -1
  17. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  18. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  19. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  20. package/dist/extensions/telegram/xopc.extension.json +1 -1
  21. package/dist/extensions/weixin/src/api/api.js +2 -2
  22. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  23. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  24. package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
  25. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  26. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  27. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  28. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  29. package/dist/extensions/weixin/src/plugin.js +1 -1
  30. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  31. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  32. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CWM1UU5P.js → agent-avatar-dicebear-dzUrQoeZ.js} +1 -1
  33. package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +2 -0
  34. package/dist/gateway/static/root/assets/{app-management-settings-panel-yXSXY_bu.js → app-management-settings-panel-bxYJVJpx.js} +1 -1
  35. package/dist/gateway/static/root/assets/{appearance-settings-DjY1P_ug.js → appearance-settings-BCIykXlI.js} +1 -1
  36. package/dist/gateway/static/root/assets/apps-page--wMEL00f.js +1 -0
  37. package/dist/gateway/static/root/assets/{archive-plugin-CytE5j-e.js → archive-plugin-Cki4SfU2.js} +1 -1
  38. package/dist/gateway/static/root/assets/{attachment-load-BvvrN6rF.js → attachment-load-D-KnS2Do.js} +1 -1
  39. package/dist/gateway/static/root/assets/{binary-plugins-IBWSitnj.js → binary-plugins-D2sgvJja.js} +1 -1
  40. package/dist/gateway/static/root/assets/{block-editor-C-wDpsf-.js → block-editor-DIq-4Gvb.js} +27 -27
  41. package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +8 -0
  42. package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +1 -0
  43. package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +1 -0
  44. package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +1 -0
  45. package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +2 -0
  46. package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +1 -0
  47. package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +3 -0
  48. package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +1 -0
  49. package/dist/gateway/static/root/assets/{extension-debug-page-BAIyjDlq.js → extension-debug-page-DYu1KaFQ.js} +1 -1
  50. package/dist/gateway/static/root/assets/{extension-page-DEhv2GpC.js → extension-page-B3W6QwlZ.js} +1 -1
  51. package/dist/gateway/static/root/assets/{extension-settings-page-DOuAxTDW.js → extension-settings-page-D7VQ-cxE.js} +1 -1
  52. package/dist/gateway/static/root/assets/{fetch-CTsREQIe.js → fetch-B7xDPu-R.js} +1 -1
  53. package/dist/gateway/static/root/assets/{format-interval-label-D35Bfhtx.js → format-interval-label-BzxafKxR.js} +1 -1
  54. package/dist/gateway/static/root/assets/gateway-config-api-BTBLSeUu.js +1 -0
  55. package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +1 -0
  56. package/dist/gateway/static/root/assets/{gateway-startup-retry-C1KAHrd2.js → gateway-startup-retry-CYj9FWCp.js} +1 -1
  57. package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +1 -0
  58. package/dist/gateway/static/root/assets/{goals-config-api-KnLGpu6h.js → goals-config-api-CQQgzPr3.js} +1 -1
  59. package/dist/gateway/static/root/assets/goals-page-BHitvJAv.js +2 -0
  60. package/dist/gateway/static/root/assets/{goals-settings-DtPtqZi8.js → goals-settings-CYVY4NGp.js} +1 -1
  61. package/dist/gateway/static/root/assets/{heartbeat-config-api-uKw1f0IG.js → heartbeat-config-api-DriO_CN9.js} +1 -1
  62. package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +1 -0
  63. package/dist/gateway/static/root/assets/index-C17Tsd_b.css +1 -0
  64. package/dist/gateway/static/root/assets/index-Cc41r16l.js +191 -0
  65. package/dist/gateway/static/root/assets/{interval-presets-Dq0FXJ65.js → interval-presets-DFPCKW_W.js} +1 -1
  66. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C9_t4m7t.js → keyboard-shortcuts-settings-CcVcqstx.js} +1 -1
  67. package/dist/gateway/static/root/assets/{logs-page-SNkWzidV.js → logs-page-C2Uqvae9.js} +2 -2
  68. package/dist/gateway/static/root/assets/{markdown-split-Ca87W8-h.js → markdown-split-BwOFrJ2E.js} +1 -1
  69. package/dist/gateway/static/root/assets/{media-plugins-BAcUjPRJ.js → media-plugins-Cnz6Q5G6.js} +1 -1
  70. package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +3 -0
  71. package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +2 -0
  72. package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +2 -0
  73. package/dist/gateway/static/root/assets/{note-image-lightbox-hnSX5SSn.js → note-image-lightbox-B-Svpmza.js} +1 -1
  74. package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +1 -0
  75. package/dist/gateway/static/root/assets/{preview-open-alternatives-CNgM20H5.js → preview-open-alternatives-Bss4TiwP.js} +1 -1
  76. package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +1 -0
  77. package/dist/gateway/static/root/assets/{save-bar-controls-CcdjGcfT.js → save-bar-controls-BRNjdgKq.js} +1 -1
  78. package/dist/gateway/static/root/assets/{schedule-field-CYr39z76.js → schedule-field-CUCKODde.js} +1 -1
  79. package/dist/gateway/static/root/assets/{schema-form-BRAJgZQ2.js → schema-form-Dub9sy8r.js} +1 -1
  80. package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +1 -0
  81. package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +1 -0
  82. package/dist/gateway/static/root/assets/{settings-collapsible-section-BhzjeGWi.js → settings-collapsible-section-BeFLavGi.js} +1 -1
  83. package/dist/gateway/static/root/assets/{settings-form-section-Cz3Pcr9b.js → settings-form-section-dmyaPOTG.js} +1 -1
  84. package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +1 -0
  85. package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +1 -0
  86. package/dist/gateway/static/root/assets/{share-preview-page-DL4y9K5e.js → share-preview-page-C8glrdqe.js} +1 -1
  87. package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +1 -0
  88. package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +1 -0
  89. package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +2 -0
  90. package/dist/gateway/static/root/assets/{system-settings-panel-FD2jxRZ3.js → system-settings-panel-DI-LN_8G.js} +1 -1
  91. package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +1 -0
  92. package/dist/gateway/static/root/assets/{use-channel-catalog-BInPrfR5.js → use-channel-catalog-DqlWTsDb.js} +1 -1
  93. package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +1 -0
  94. package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +1 -0
  95. package/dist/gateway/static/root/assets/voice-api-key-field-C73IVZeC.js +1 -0
  96. package/dist/gateway/static/root/assets/{voice-player-store-1U3vFppm.js → voice-player-store-C_ArLJPM.js} +1 -1
  97. package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +18 -0
  98. package/dist/gateway/static/root/index.html +5 -5
  99. package/dist/package.js +1 -1
  100. package/dist/src/agent/agent-manager.d.ts +1 -1
  101. package/dist/src/agent/agent-manager.js +14 -14
  102. package/dist/src/agent/agent-manager.js.map +1 -1
  103. package/dist/src/agent/agent-scope.js +5 -9
  104. package/dist/src/agent/agent-scope.js.map +1 -1
  105. package/dist/src/agent/background-review/coordinator.js +0 -1
  106. package/dist/src/agent/background-review/coordinator.js.map +1 -1
  107. package/dist/src/agent/background-review/prompts.d.ts +2 -2
  108. package/dist/src/agent/background-review/prompts.js +2 -2
  109. package/dist/src/agent/background-review/prompts.js.map +1 -1
  110. package/dist/src/agent/background-review/run-background-review.d.ts +0 -2
  111. package/dist/src/agent/background-review/run-background-review.js +2 -4
  112. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  113. package/dist/src/agent/background-review/settings.d.ts +1 -1
  114. package/dist/src/agent/background-review/settings.js +8 -8
  115. package/dist/src/agent/background-review/settings.js.map +1 -1
  116. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +1 -0
  117. package/dist/src/agent/bootstrap/bootstrap-cache.js +4 -3
  118. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  119. package/dist/src/agent/bootstrap/bootstrap-context.d.ts +2 -2
  120. package/dist/src/agent/bootstrap/bootstrap-context.js +4 -4
  121. package/dist/src/agent/bootstrap/bootstrap-context.js.map +1 -1
  122. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +4 -0
  123. package/dist/src/agent/bootstrap/bootstrap-files.js +4 -3
  124. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  125. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +4 -2
  126. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  127. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +2 -1
  128. package/dist/src/agent/bootstrap/load-bootstrap-files.js +18 -17
  129. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  130. package/dist/src/agent/bootstrap/project-agents-context.js +1 -1
  131. package/dist/src/agent/bootstrap/types.d.ts +1 -1
  132. package/dist/src/agent/context/workspace-seed.js +3 -3
  133. package/dist/src/agent/context/workspace-state.js +1 -1
  134. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  135. package/dist/src/agent/context/workspace.d.ts +4 -2
  136. package/dist/src/agent/context/workspace.js +6 -5
  137. package/dist/src/agent/context/workspace.js.map +1 -1
  138. package/dist/src/agent/embedded/run-for-session.js +4 -1
  139. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  140. package/dist/src/agent/fallback/candidates.js +11 -9
  141. package/dist/src/agent/fallback/candidates.js.map +1 -1
  142. package/dist/src/agent/goals/goal-locale.js +2 -2
  143. package/dist/src/agent/goals/post-turn.js +3 -3
  144. package/dist/src/agent/image/generation/runtime-types.d.ts +2 -0
  145. package/dist/src/agent/image/generation/runtime.js +1 -1
  146. package/dist/src/agent/image/generation/runtime.js.map +1 -1
  147. package/dist/src/agent/image/image-helpers.d.ts +1 -1
  148. package/dist/src/agent/image/image-helpers.js +4 -17
  149. package/dist/src/agent/image/image-helpers.js.map +1 -1
  150. package/dist/src/agent/image/image-model-fallback.js +1 -1
  151. package/dist/src/agent/image/image-model-fallback.js.map +1 -1
  152. package/dist/src/agent/image/inbound-image-handling.js +1 -1
  153. package/dist/src/agent/image/inbound-image-handling.js.map +1 -1
  154. package/dist/src/agent/image/load-image-media.js +2 -2
  155. package/dist/src/agent/image/tool-model-config.d.ts +1 -1
  156. package/dist/src/agent/image/tool-model-config.js +2 -2
  157. package/dist/src/agent/image/tool-model-config.js.map +1 -1
  158. package/dist/src/agent/ipc/inbox.js +3 -3
  159. package/dist/src/agent/ipc/socket.js +1 -1
  160. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  161. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  162. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  163. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  164. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js +1 -1
  165. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js.map +1 -1
  166. package/dist/src/agent/media-generation/runtime-shared.d.ts +5 -2
  167. package/dist/src/agent/media-generation/runtime-shared.js +1 -1
  168. package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
  169. package/dist/src/agent/memory/builtin-memory-store.d.ts +6 -2
  170. package/dist/src/agent/memory/builtin-memory-store.js +15 -6
  171. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  172. package/dist/src/agent/memory/builtin-provider.d.ts +31 -9
  173. package/dist/src/agent/memory/builtin-provider.js +290 -11
  174. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  175. package/dist/src/agent/memory/candidate-extractor.d.ts +6 -0
  176. package/dist/src/agent/memory/candidate-extractor.js +60 -0
  177. package/dist/src/agent/memory/candidate-extractor.js.map +1 -0
  178. package/dist/src/agent/memory/context-assembler.d.ts +10 -0
  179. package/dist/src/agent/memory/context-assembler.js +26 -0
  180. package/dist/src/agent/memory/context-assembler.js.map +1 -0
  181. package/dist/src/agent/memory/create-memory-manager.js +25 -7
  182. package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
  183. package/dist/src/agent/memory/dreaming/config.d.ts +1 -6
  184. package/dist/src/agent/memory/dreaming/config.js +8 -8
  185. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  186. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +2 -0
  187. package/dist/src/agent/memory/dreaming/deep-promotion.js +25 -1
  188. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  189. package/dist/src/agent/memory/dreaming/events.js +1 -1
  190. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  191. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  192. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  193. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  194. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  195. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  196. package/dist/src/agent/memory/index.d.ts +1 -0
  197. package/dist/src/agent/memory/index.js +4 -3
  198. package/dist/src/agent/memory/inject-prefetch.js +6 -2
  199. package/dist/src/agent/memory/inject-prefetch.js.map +1 -1
  200. package/dist/src/agent/memory/manager.d.ts +39 -2
  201. package/dist/src/agent/memory/manager.js +355 -39
  202. package/dist/src/agent/memory/manager.js.map +1 -1
  203. package/dist/src/agent/memory/memory-config.js +15 -15
  204. package/dist/src/agent/memory/memory-config.js.map +1 -1
  205. package/dist/src/agent/memory/memory-flush.js +1 -1
  206. package/dist/src/agent/memory/plugin-discovery.d.ts +19 -5
  207. package/dist/src/agent/memory/plugin-discovery.js +97 -31
  208. package/dist/src/agent/memory/plugin-discovery.js.map +1 -1
  209. package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -1
  210. package/dist/src/agent/memory/provider.d.ts +20 -15
  211. package/dist/src/agent/memory/stub-memory-provider.d.ts +17 -2
  212. package/dist/src/agent/memory/stub-memory-provider.js +20 -3
  213. package/dist/src/agent/memory/stub-memory-provider.js.map +1 -1
  214. package/dist/src/agent/memory/types.d.ts +162 -3
  215. package/dist/src/agent/models/manager.d.ts +1 -1
  216. package/dist/src/agent/models/manager.js +2 -2
  217. package/dist/src/agent/models/manager.js.map +1 -1
  218. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +1 -1
  219. package/dist/src/agent/orchestration/agent-orchestrator.js +2 -1
  220. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  221. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +2 -2
  222. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  223. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  224. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -6
  225. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +2 -8
  226. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js.map +1 -1
  227. package/dist/src/agent/prompt/memory/index.d.ts +4 -2
  228. package/dist/src/agent/prompt/memory/index.js +19 -13
  229. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  230. package/dist/src/agent/prompt/sections/memory-skills.js +1 -1
  231. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
  232. package/dist/src/agent/prompt/service-prompt-builder.js +5 -20
  233. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  234. package/dist/src/agent/reply/post-compaction-context.js +10 -7
  235. package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
  236. package/dist/src/agent/reply/startup-context.js +7 -12
  237. package/dist/src/agent/reply/startup-context.js.map +1 -1
  238. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  239. package/dist/src/agent/sandbox/path-policy.js +2 -2
  240. package/dist/src/agent/service/process-direct-streaming.js +1 -4
  241. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  242. package/dist/src/agent/service/session-context-report.js +1 -1
  243. package/dist/src/agent/service/session-context-report.js.map +1 -1
  244. package/dist/src/agent/service.d.ts +3 -3
  245. package/dist/src/agent/service.js +30 -35
  246. package/dist/src/agent/service.js.map +1 -1
  247. package/dist/src/agent/service.types.d.ts +1 -2
  248. package/dist/src/agent/session/session-hydrator.js +1 -2
  249. package/dist/src/agent/session/session-hydrator.js.map +1 -1
  250. package/dist/src/agent/session/session-inspector.d.ts +1 -1
  251. package/dist/src/agent/session/session-inspector.js +10 -15
  252. package/dist/src/agent/session/session-inspector.js.map +1 -1
  253. package/dist/src/agent/skills/config.js +2 -2
  254. package/dist/src/agent/skills/filesystem-watcher.js +1 -1
  255. package/dist/src/agent/skills/hub-hash.js +2 -2
  256. package/dist/src/agent/skills/hub-lock.js +1 -1
  257. package/dist/src/agent/skills/hub-pull.js +3 -3
  258. package/dist/src/agent/skills/index.js +2 -2
  259. package/dist/src/agent/skills/installer.js +2 -2
  260. package/dist/src/agent/skills/managed-store.js +1 -1
  261. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  262. package/dist/src/agent/skills/skill-manager.js +1 -1
  263. package/dist/src/agent/skills/skill-view-path.js +1 -1
  264. package/dist/src/agent/skills/test-framework.js +1 -1
  265. package/dist/src/agent/starter-agents.d.ts +1 -3
  266. package/dist/src/agent/starter-agents.js +14 -22
  267. package/dist/src/agent/starter-agents.js.map +1 -1
  268. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -2
  269. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  270. package/dist/src/agent/tools/curated-memory-tool.d.ts +2 -5
  271. package/dist/src/agent/tools/curated-memory-tool.js +77 -18
  272. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  273. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  274. package/dist/src/agent/tools/factory.d.ts +0 -4
  275. package/dist/src/agent/tools/factory.js +19 -58
  276. package/dist/src/agent/tools/factory.js.map +1 -1
  277. package/dist/src/agent/tools/find.js +1 -1
  278. package/dist/src/agent/tools/grep.js +1 -1
  279. package/dist/src/agent/tools/image-generate-tool.d.ts +1 -1
  280. package/dist/src/agent/tools/image-generate-tool.js +20 -15
  281. package/dist/src/agent/tools/image-generate-tool.js.map +1 -1
  282. package/dist/src/agent/tools/image-tool.js +1 -3
  283. package/dist/src/agent/tools/image-tool.js.map +1 -1
  284. package/dist/src/agent/tools/memory-tool.d.ts +2 -2
  285. package/dist/src/agent/tools/memory-tool.js +39 -14
  286. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  287. package/dist/src/agent/tools/session-search-tool.js +1 -3
  288. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  289. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  290. package/dist/src/agent/tools/web-extract.js +8 -9
  291. package/dist/src/agent/tools/web-extract.js.map +1 -1
  292. package/dist/src/agent/tools/workflow-tool.js +1 -1
  293. package/dist/src/agent/workflow/catalog.js +1 -1
  294. package/dist/src/agent/workflow/subagent-runner.js +1 -3
  295. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  296. package/dist/src/agent-manifest/index.d.ts +4 -0
  297. package/dist/src/agent-manifest/index.js +10 -0
  298. package/dist/src/agent-manifest/index.js.map +1 -0
  299. package/dist/src/agent-manifest/prompt.d.ts +2 -0
  300. package/dist/src/agent-manifest/prompt.js +57 -0
  301. package/dist/src/agent-manifest/prompt.js.map +1 -0
  302. package/dist/src/agent-manifest/resolver.d.ts +12 -0
  303. package/dist/src/agent-manifest/resolver.js +95 -0
  304. package/dist/src/agent-manifest/resolver.js.map +1 -0
  305. package/dist/src/agent-manifest/schema.d.ts +1010 -0
  306. package/dist/src/agent-manifest/schema.js +269 -0
  307. package/dist/src/agent-manifest/schema.js.map +1 -0
  308. package/dist/src/agent-manifest/validator.d.ts +25 -0
  309. package/dist/src/agent-manifest/validator.js +88 -0
  310. package/dist/src/agent-manifest/validator.js.map +1 -0
  311. package/dist/src/agent-runtime/boundary-guard.d.ts +12 -0
  312. package/dist/src/agent-runtime/boundary-guard.js +23 -0
  313. package/dist/src/agent-runtime/boundary-guard.js.map +1 -0
  314. package/dist/src/agent-runtime/index.d.ts +7 -0
  315. package/dist/src/agent-runtime/index.js +8 -0
  316. package/dist/src/agent-runtime/memory-runtime.d.ts +21 -0
  317. package/dist/src/agent-runtime/memory-runtime.js +50 -0
  318. package/dist/src/agent-runtime/memory-runtime.js.map +1 -0
  319. package/dist/src/agent-runtime/model-router.d.ts +11 -0
  320. package/dist/src/agent-runtime/model-router.js +16 -0
  321. package/dist/src/agent-runtime/model-router.js.map +1 -0
  322. package/dist/src/agent-runtime/run-trace.d.ts +27 -0
  323. package/dist/src/agent-runtime/run-trace.js +53 -0
  324. package/dist/src/agent-runtime/run-trace.js.map +1 -0
  325. package/dist/src/agent-runtime/runtime-profile.d.ts +24 -0
  326. package/dist/src/agent-runtime/runtime-profile.js +44 -0
  327. package/dist/src/agent-runtime/runtime-profile.js.map +1 -0
  328. package/dist/src/agent-runtime/tool-registry.d.ts +28 -0
  329. package/dist/src/agent-runtime/tool-registry.js +52 -0
  330. package/dist/src/agent-runtime/tool-registry.js.map +1 -0
  331. package/dist/src/agent-runtime/workflow-runtime.d.ts +31 -0
  332. package/dist/src/agent-runtime/workflow-runtime.js +34 -0
  333. package/dist/src/agent-runtime/workflow-runtime.js.map +1 -0
  334. package/dist/src/ai-assist/text-assist.js +1 -1
  335. package/dist/src/auth/credentials.js +2 -2
  336. package/dist/src/auth/profiles/store.js +2 -2
  337. package/dist/src/auth/sync-provider-auth.js +1 -1
  338. package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
  339. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  340. package/dist/src/browser/actions/registry.js +5 -8
  341. package/dist/src/browser/actions/registry.js.map +1 -1
  342. package/dist/src/browser/backend-from-config.d.ts +1 -1
  343. package/dist/src/browser/backend-from-config.js +50 -71
  344. package/dist/src/browser/backend-from-config.js.map +1 -1
  345. package/dist/src/browser/browser-command-timeout.d.ts +0 -1
  346. package/dist/src/browser/browser-command-timeout.js +3 -7
  347. package/dist/src/browser/browser-command-timeout.js.map +1 -1
  348. package/dist/src/browser/cache-dir-policy.js +1 -1
  349. package/dist/src/browser/cdp-local-launcher.js +2 -2
  350. package/dist/src/browser/pipeline/source.js +1 -1
  351. package/dist/src/browser/providers/browser-ext-install.d.ts +2 -12
  352. package/dist/src/browser/providers/browser-ext-install.js +7 -12
  353. package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
  354. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  355. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  356. package/dist/src/browser/readiness.js +16 -16
  357. package/dist/src/browser/readiness.js.map +1 -1
  358. package/dist/src/browser/schemas.js +1 -1
  359. package/dist/src/browser/schemas.js.map +1 -1
  360. package/dist/src/browser/stealth.js +1 -1
  361. package/dist/src/channels/catalog/channel-catalog-service.js +1 -1
  362. package/dist/src/channels/outbound/persist-store.js +1 -1
  363. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  364. package/dist/src/channels/pairing/pairing-store.js +2 -2
  365. package/dist/src/channels/pipeline.d.ts +1 -1
  366. package/dist/src/channels/pipeline.js.map +1 -1
  367. package/dist/src/chat-commands/agent-edit.js +2 -3
  368. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  369. package/dist/src/chat-commands/builtins/config.js +6 -6
  370. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  371. package/dist/src/chat-commands/builtins/model.js +2 -2
  372. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  373. package/dist/src/chat-commands/builtins/thinking.js +16 -42
  374. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  375. package/dist/src/chat-commands/config-paths.js +1 -1
  376. package/dist/src/chat-commands/config-paths.js.map +1 -1
  377. package/dist/src/chat-commands/context.js +3 -4
  378. package/dist/src/chat-commands/context.js.map +1 -1
  379. package/dist/src/cli/command-manifest.d.ts +1 -1
  380. package/dist/src/cli/command-manifest.js +2 -2
  381. package/dist/src/cli/command-manifest.js.map +1 -1
  382. package/dist/src/cli/commands/agent.js +3 -1
  383. package/dist/src/cli/commands/agent.js.map +1 -1
  384. package/dist/src/cli/commands/agents.js +3 -6
  385. package/dist/src/cli/commands/agents.js.map +1 -1
  386. package/dist/src/cli/commands/browser-cli-helpers.js +9 -11
  387. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  388. package/dist/src/cli/commands/config.js +6 -6
  389. package/dist/src/cli/commands/config.js.map +1 -1
  390. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  391. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  392. package/dist/src/cli/commands/doctor/checks/provider-auth.js +3 -18
  393. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  394. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  395. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -2
  396. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
  397. package/dist/src/cli/commands/extension-create.js +1 -1
  398. package/dist/src/cli/commands/extension-dev.js +2 -2
  399. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  400. package/dist/src/cli/commands/extension-pack.js +2 -2
  401. package/dist/src/cli/commands/extension.js +3 -3
  402. package/dist/src/cli/commands/gateway/logs.js +1 -1
  403. package/dist/src/cli/commands/goal.js +1 -1
  404. package/dist/src/cli/commands/image.js +13 -372
  405. package/dist/src/cli/commands/image.js.map +1 -1
  406. package/dist/src/cli/commands/init.js +7 -6
  407. package/dist/src/cli/commands/init.js.map +1 -1
  408. package/dist/src/cli/commands/models.js +14 -16
  409. package/dist/src/cli/commands/models.js.map +1 -1
  410. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  411. package/dist/src/cli/commands/onboard/model.js +28 -23
  412. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  413. package/dist/src/cli/commands/onboard.js +3 -3
  414. package/dist/src/cli/commands/onboard.js.map +1 -1
  415. package/dist/src/cli/commands/skills-test.js +1 -1
  416. package/dist/src/cli/commands/tui.js +2 -2
  417. package/dist/src/cli/commands/tui.js.map +1 -1
  418. package/dist/src/cli/index.d.ts +1 -0
  419. package/dist/src/cli/index.js +10 -5
  420. package/dist/src/cli/index.js.map +1 -1
  421. package/dist/src/cli/registry.js +1 -1
  422. package/dist/src/cli/registry.js.map +1 -1
  423. package/dist/src/cli/templates.d.ts +1 -1
  424. package/dist/src/cli/templates.js +2 -12
  425. package/dist/src/cli/templates.js.map +1 -1
  426. package/dist/src/cli/utils/gateway-client.js +1 -1
  427. package/dist/src/cli/utils/init-workspace-core.d.ts +1 -4
  428. package/dist/src/cli/utils/init-workspace-core.js +9 -8
  429. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  430. package/dist/src/commands/agents.config.d.ts +0 -1
  431. package/dist/src/commands/agents.config.js +59 -13
  432. package/dist/src/commands/agents.config.js.map +1 -1
  433. package/dist/src/config/agent-profile.d.ts +5 -17
  434. package/dist/src/config/agent-profile.js +32 -64
  435. package/dist/src/config/agent-profile.js.map +1 -1
  436. package/dist/src/config/agent-typed-models.d.ts +1 -1
  437. package/dist/src/config/agent-typed-models.js +3 -6
  438. package/dist/src/config/agent-typed-models.js.map +1 -1
  439. package/dist/src/config/gateway-bind.js +1 -1
  440. package/dist/src/config/index.js +9 -9
  441. package/dist/src/config/integration.d.ts +1 -1
  442. package/dist/src/config/loader.js +4 -4
  443. package/dist/src/config/models-json.js +2 -2
  444. package/dist/src/config/paths-state.js +1 -1
  445. package/dist/src/config/paths.d.ts +8 -1
  446. package/dist/src/config/paths.js +17 -4
  447. package/dist/src/config/paths.js.map +1 -1
  448. package/dist/src/config/profile.js +1 -1
  449. package/dist/src/config/reload.js +2 -2
  450. package/dist/src/config/reload.js.map +1 -1
  451. package/dist/src/config/rules.js +6 -56
  452. package/dist/src/config/rules.js.map +1 -1
  453. package/dist/src/config/schema.d.ts +916 -779
  454. package/dist/src/config/schema.js +174 -423
  455. package/dist/src/config/schema.js.map +1 -1
  456. package/dist/src/config/workspace-path.js +1 -1
  457. package/dist/src/connectors/composio-triggers.js +1 -1
  458. package/dist/src/cron/executor.js +1 -1
  459. package/dist/src/cron/index.js +1 -1
  460. package/dist/src/cron/service.js +2 -2
  461. package/dist/src/cron/validation.d.ts +3 -3
  462. package/dist/src/daemon/constants.js +1 -1
  463. package/dist/src/daemon/install-plan.js +2 -2
  464. package/dist/src/daemon/launchd.js +2 -2
  465. package/dist/src/daemon/schtasks.js +2 -2
  466. package/dist/src/daemon/systemd.js +2 -2
  467. package/dist/src/extensions/activation-context.js +13 -7
  468. package/dist/src/extensions/activation-context.js.map +1 -1
  469. package/dist/src/extensions/bundle-mcp.js +1 -1
  470. package/dist/src/extensions/discover-extensions.js +2 -2
  471. package/dist/src/extensions/health.js +1 -1
  472. package/dist/src/extensions/install.js +2 -2
  473. package/dist/src/extensions/loader.js +2 -2
  474. package/dist/src/extensions/lockfile.js +3 -3
  475. package/dist/src/extensions/security.js +1 -1
  476. package/dist/src/extensions/update.js +2 -2
  477. package/dist/src/gateway/agents-admin.d.ts +24 -18
  478. package/dist/src/gateway/agents-admin.js +158 -92
  479. package/dist/src/gateway/agents-admin.js.map +1 -1
  480. package/dist/src/gateway/capability-presets-admin.d.ts +56 -0
  481. package/dist/src/gateway/capability-presets-admin.js +214 -0
  482. package/dist/src/gateway/capability-presets-admin.js.map +1 -0
  483. package/dist/src/gateway/chat-stream/mapper.js +9 -2
  484. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  485. package/dist/src/gateway/file-path-classifier.js +2 -2
  486. package/dist/src/gateway/global-defaults-admin.d.ts +36 -0
  487. package/dist/src/gateway/global-defaults-admin.js +146 -0
  488. package/dist/src/gateway/global-defaults-admin.js.map +1 -0
  489. package/dist/src/gateway/hono/lib/agent-model.d.ts +1 -1
  490. package/dist/src/gateway/hono/lib/agent-model.js +1 -1
  491. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  492. package/dist/src/gateway/hono/lib/config-payload.d.ts +234 -127
  493. package/dist/src/gateway/hono/lib/config-payload.js +14 -38
  494. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  495. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  496. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  497. package/dist/src/gateway/hono/routes/agents.js +88 -33
  498. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  499. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  500. package/dist/src/gateway/hono/routes/browser.js +8 -15
  501. package/dist/src/gateway/hono/routes/browser.js.map +1 -1
  502. package/dist/src/gateway/hono/routes/capability-presets.d.ts +3 -0
  503. package/dist/src/gateway/hono/routes/capability-presets.js +145 -0
  504. package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -0
  505. package/dist/src/gateway/hono/routes/commands-skills.js +4 -5
  506. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  507. package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +1 -17
  508. package/dist/src/gateway/hono/routes/config-patch/agents.js +2 -443
  509. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  510. package/dist/src/gateway/hono/routes/config-patch/misc.js +7 -1
  511. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  512. package/dist/src/gateway/hono/routes/config.js +1 -1
  513. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  514. package/dist/src/gateway/hono/routes/dreaming.js +8 -1
  515. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  516. package/dist/src/gateway/hono/routes/global-defaults.d.ts +3 -0
  517. package/dist/src/gateway/hono/routes/global-defaults.js +61 -0
  518. package/dist/src/gateway/hono/routes/global-defaults.js.map +1 -0
  519. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  520. package/dist/src/gateway/hono/routes/index.js +2 -0
  521. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  522. package/dist/src/gateway/hono/routes/lazy-bundles.js +17 -1
  523. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  524. package/dist/src/gateway/hono/routes/memory.d.ts +3 -0
  525. package/dist/src/gateway/hono/routes/memory.js +361 -0
  526. package/dist/src/gateway/hono/routes/memory.js.map +1 -0
  527. package/dist/src/gateway/hono/routes/models.js +2 -2
  528. package/dist/src/gateway/hono/routes/shares.js +1 -1
  529. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  530. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  531. package/dist/src/gateway/lock.js +3 -3
  532. package/dist/src/gateway/ports.js +1 -1
  533. package/dist/src/gateway/service/config-coordinator.js +1 -1
  534. package/dist/src/gateway/service/marketplace-service.d.ts +4 -4
  535. package/dist/src/gateway/service/marketplace-service.js +13 -9
  536. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  537. package/dist/src/gateway/service.d.ts +1 -1
  538. package/dist/src/gateway/service.js +15 -16
  539. package/dist/src/gateway/service.js.map +1 -1
  540. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  541. package/dist/src/goals/goal-workflow-judge.js +2 -2
  542. package/dist/src/i18n/goals-bundle.js +1 -1
  543. package/dist/src/i18n/index.js +1 -1
  544. package/dist/src/i18n/share-tool-bundle.js +2 -2
  545. package/dist/src/infra/brew.js +1 -1
  546. package/dist/src/infra/package-json.js +1 -1
  547. package/dist/src/infra/package-update-steps.js +1 -1
  548. package/dist/src/infra/path-env.js +2 -2
  549. package/dist/src/infra/restart.js +1 -1
  550. package/dist/src/infra/stable-node-path.js +1 -1
  551. package/dist/src/infra/update-check.js +1 -1
  552. package/dist/src/infra/update-global.js +1 -1
  553. package/dist/src/infra/update-lock.js +2 -2
  554. package/dist/src/infra/update-restart.js +1 -1
  555. package/dist/src/infra/update-runner.js +1 -1
  556. package/dist/src/infra/update-startup.js +1 -1
  557. package/dist/src/infra/write-file-atomic.js +2 -2
  558. package/dist/src/media/store.js +1 -1
  559. package/dist/src/notes/agent-context.js +3 -3
  560. package/dist/src/notes/service.js +4 -2
  561. package/dist/src/notes/service.js.map +1 -1
  562. package/dist/src/notes/store.js +2 -2
  563. package/dist/src/project-trust/trust-store.js +2 -2
  564. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  565. package/dist/src/providers/index.d.ts +5 -6
  566. package/dist/src/providers/index.js +26 -30
  567. package/dist/src/providers/index.js.map +1 -1
  568. package/dist/src/providers/model-registry.js +4 -4
  569. package/dist/src/session/index.js +1 -1
  570. package/dist/src/session/init-session-turn.js +1 -1
  571. package/dist/src/session/resolve-session.js +1 -1
  572. package/dist/src/session/session-title.js +2 -2
  573. package/dist/src/session/store.js +1 -1
  574. package/dist/src/session/thinking-resolve.d.ts +1 -1
  575. package/dist/src/session/thinking-resolve.js +1 -1
  576. package/dist/src/session/thinking-resolve.js.map +1 -1
  577. package/dist/src/share/share-auto.js +2 -2
  578. package/dist/src/share/share-store.js +3 -3
  579. package/dist/src/share/share-thumbnail.js +2 -2
  580. package/dist/src/share/share-zip.js +1 -1
  581. package/dist/src/share/site-share-store.js +3 -3
  582. package/dist/src/share/site-static-serve.js +1 -1
  583. package/dist/src/storage/sqlite/connection.js +2 -2
  584. package/dist/src/storage/sqlite/index.d.ts +1 -0
  585. package/dist/src/storage/sqlite/index.js +2 -1
  586. package/dist/src/storage/sqlite/memory-index-repository.d.ts +1 -0
  587. package/dist/src/storage/sqlite/memory-index-repository.js +17 -16
  588. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  589. package/dist/src/storage/sqlite/memory-records-repository.d.ts +144 -0
  590. package/dist/src/storage/sqlite/memory-records-repository.js +453 -0
  591. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -0
  592. package/dist/src/storage/sqlite/migrations/012_memory_records.sql +63 -0
  593. package/dist/src/storage/sqlite/migrations/013_memory_trace_events.sql +21 -0
  594. package/dist/src/storage/sqlite/migrations/014_memory_record_governance.sql +10 -0
  595. package/dist/src/storage/sqlite/migrations/015_memory_trace_feedback.sql +4 -0
  596. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  597. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  598. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  599. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  600. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  601. package/dist/src/storage/sqlite/schema.js +2 -2
  602. package/dist/src/storage/sqlite/schema.sql +86 -0
  603. package/dist/src/tui/backends/embedded-backend.d.ts +3 -0
  604. package/dist/src/tui/backends/embedded-backend.js +43 -24
  605. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  606. package/dist/src/tui/backends/gateway-sse-backend.d.ts +1 -0
  607. package/dist/src/tui/backends/gateway-sse-backend.js +16 -3
  608. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  609. package/dist/src/tui/clipboard-image.js +3 -3
  610. package/dist/src/tui/components/tui-header.d.ts +0 -1
  611. package/dist/src/tui/components/tui-header.js +3 -8
  612. package/dist/src/tui/components/tui-header.js.map +1 -1
  613. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  614. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  615. package/dist/src/tui/theme-manager.js +1 -1
  616. package/dist/src/tui/tui-command-formatters.js +4 -4
  617. package/dist/src/tui/tui-commands.js +2 -2
  618. package/dist/src/tui/tui-keybindings-file.js +1 -1
  619. package/dist/src/tui/tui-scoped-models.js +2 -2
  620. package/dist/src/tui/tui-settings.js +1 -1
  621. package/dist/src/tui/tui-startup-resources.js +2 -1
  622. package/dist/src/tui/tui-startup-resources.js.map +1 -1
  623. package/dist/src/tui/tui-startup-text.js +12 -12
  624. package/dist/src/tui/tui-startup-text.js.map +1 -1
  625. package/dist/src/tui/tui.js +10 -7
  626. package/dist/src/tui/tui.js.map +1 -1
  627. package/dist/src/tunnel/frpc-binary.js +4 -4
  628. package/dist/src/tunnel/frpc-config.js +1 -1
  629. package/dist/src/tunnel/frpc-extract.js +1 -1
  630. package/dist/src/tunnel/tunnel-state.js +1 -1
  631. package/dist/src/utils/logger/audit.js +1 -1
  632. package/dist/src/utils/logger/log-store.js +1 -1
  633. package/dist/src/utils/logger/rotation.js +1 -1
  634. package/dist/src/utils/logger/streams.js +1 -1
  635. package/dist/src/voice/tts/audio.js +1 -1
  636. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  637. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  638. package/dist/src/workflows/service/workflow-run-service.js +4 -5
  639. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  640. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  641. package/dist/src/workflows/store/event-store.js +1 -1
  642. package/dist/src/workflows/store/run-store.js +1 -1
  643. package/package.json +3 -2
  644. package/dist/gateway/static/root/assets/agent-browser-settings-page-D1SyFYeh.js +0 -6
  645. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-C9YxgvuI.js +0 -1
  646. package/dist/gateway/static/root/assets/agents-CteVs3UO.js +0 -71
  647. package/dist/gateway/static/root/assets/apps-page-CVQ1M8Ax.js +0 -1
  648. package/dist/gateway/static/root/assets/channels-settings-Cd3JbeQ1.js +0 -1
  649. package/dist/gateway/static/root/assets/config-api-C4RAtTKW.js +0 -3
  650. package/dist/gateway/static/root/assets/connectors-page-MsMa5qBr.js +0 -2
  651. package/dist/gateway/static/root/assets/cron-api-sJNMqB6P.js +0 -1
  652. package/dist/gateway/static/root/assets/cron-page-D30CSwkn.js +0 -3
  653. package/dist/gateway/static/root/assets/dreaming-settings-6fCUWRQf.js +0 -1
  654. package/dist/gateway/static/root/assets/gateway-config-api-C6989a-W.js +0 -1
  655. package/dist/gateway/static/root/assets/gateway-settings-BpF26t91.js +0 -1
  656. package/dist/gateway/static/root/assets/goal-detail-page-DOjhmRyf.js +0 -1
  657. package/dist/gateway/static/root/assets/goals-page-Xl9_wrFc.js +0 -2
  658. package/dist/gateway/static/root/assets/heartbeat-settings-DN9vEj9P.js +0 -1
  659. package/dist/gateway/static/root/assets/index-C8ytlAF2.js +0 -122
  660. package/dist/gateway/static/root/assets/index-CVpJW2NS.css +0 -1
  661. package/dist/gateway/static/root/assets/messages-BqzIDrlr.js +0 -3
  662. package/dist/gateway/static/root/assets/models-hub-panel-BO4o-GmO.js +0 -2
  663. package/dist/gateway/static/root/assets/note-detail-page-DLV_XDmT.js +0 -2
  664. package/dist/gateway/static/root/assets/notes-page-ycsDlkFA.js +0 -1
  665. package/dist/gateway/static/root/assets/remote-access-hub-DQpnE8K9.js +0 -1
  666. package/dist/gateway/static/root/assets/sessions-page-BZui7iAY.js +0 -1
  667. package/dist/gateway/static/root/assets/settings-advanced-gate-DEfzZ1ax.js +0 -1
  668. package/dist/gateway/static/root/assets/settings-page-CLuSsu1-.js +0 -1
  669. package/dist/gateway/static/root/assets/setup-status-panel-Cq4qpXLi.js +0 -1
  670. package/dist/gateway/static/root/assets/shares-settings-B9F3HyYQ.js +0 -1
  671. package/dist/gateway/static/root/assets/skill-reload-api-Bp9UPPwm.js +0 -1
  672. package/dist/gateway/static/root/assets/skills-page-BIoBsfSV.js +0 -2
  673. package/dist/gateway/static/root/assets/use-agent-defaults-form-Cz2_pPzu.js +0 -1
  674. package/dist/gateway/static/root/assets/use-settings-tab-guard-nuHMmZQv.js +0 -1
  675. package/dist/gateway/static/root/assets/voice-api-key-field-BUIrKb8s.js +0 -1
  676. package/dist/gateway/static/root/assets/workflows-page-qE3SexnO.js +0 -18
  677. package/dist/src/agent/context/workspace-templates/USER.md +0 -24
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-shared.js","names":[],"sources":["../../../../src/agent/media-generation/runtime-shared.ts"],"sourcesContent":["/**\n * Cross-capability runtime helpers shared by image / audio / video\n * generation. Pure functions (no IO) so they can be unit-tested without\n * touching providers.\n *\n * - candidate model resolution\n * - geometry/value nearest-neighbour matching\n * - terminal failure aggregation (FailoverError)\n * - \"no model configured\" message builder\n */\n\nimport type { Config, AgentModelConfig } from '../../config/schema.js';\nimport {\n classifyAttemptError,\n FailoverError,\n type FallbackAttempt,\n type FailoverReason,\n} from '../failover-error.js';\nimport { parseCapabilityModelRef, type ParsedCapabilityModelRef } from './model-ref.js';\n\n// ============================================\n// Candidate resolution\n// ============================================\n\nexport interface CapabilityProviderCandidate {\n id: string;\n aliases?: readonly string[];\n defaultModel?: string | null;\n models?: readonly string[];\n isConfigured?: (ctx: { cfg?: Config; agentDir?: string }) => boolean;\n}\n\nexport interface ResolveCapabilityModelCandidatesParams {\n cfg?: Config;\n /** Active capability model config, e.g. cfg.agents.defaults.imageGenerationModel. */\n modelConfig: AgentModelConfig | undefined;\n /** Caller-supplied per-call override (highest priority). */\n modelOverride?: string;\n /** Optional ref parser; defaults to {@link parseCapabilityModelRef}. */\n parseModelRef?: (raw: string | undefined) => ParsedCapabilityModelRef | null;\n agentDir?: string;\n /** Snapshot of registered providers used to enumerate fallbacks. */\n listProviders: (cfg?: Config) => CapabilityProviderCandidate[];\n /**\n * When true and the explicit candidates fail, append every configured\n * provider's default model.\n */\n autoProviderFallback?: boolean;\n}\n\nexport interface ResolvedCapabilityModelCandidate {\n provider: string;\n model: string;\n}\n\n/**\n * Build the ordered candidate list from:\n * 1. modelOverride\n * 2. modelConfig.primary\n * 3. modelConfig.fallbacks[]\n * 4. (optional) every isConfigured() provider's defaultModel\n *\n * Duplicates are dropped (case-insensitive on provider, exact on model).\n */\nexport function resolveCapabilityModelCandidates(\n params: ResolveCapabilityModelCandidatesParams,\n): ResolvedCapabilityModelCandidate[] {\n const parse = params.parseModelRef ?? parseCapabilityModelRef;\n const out: ResolvedCapabilityModelCandidate[] = [];\n const seen = new Set<string>();\n\n const push = (raw: string | undefined) => {\n const parsed = parse(raw);\n if (!parsed) return;\n const key = `${parsed.provider}::${parsed.model}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ provider: parsed.provider, model: parsed.model });\n };\n\n const normalizedModelConfig = normalizeModelConfig(params.modelConfig);\n push(params.modelOverride);\n push(normalizedModelConfig.primary);\n for (const fb of normalizedModelConfig.fallbacks) push(fb);\n\n if (params.autoProviderFallback) {\n const providers = safeListProviders(params.listProviders, params.cfg);\n for (const provider of providers) {\n if (!provider.defaultModel) continue;\n let configured = true;\n try {\n configured = provider.isConfigured?.({ cfg: params.cfg, agentDir: params.agentDir }) ?? true;\n } catch {\n configured = false;\n }\n if (!configured) continue;\n push(`${provider.id}/${provider.defaultModel}`);\n }\n }\n\n return out;\n}\n\nfunction safeListProviders(\n fn: (cfg?: Config) => CapabilityProviderCandidate[],\n cfg?: Config,\n): CapabilityProviderCandidate[] {\n try {\n return fn(cfg) ?? [];\n } catch {\n return [];\n }\n}\n\n/** Normalize an {@link AgentModelConfig} to `{ primary?, fallbacks }`. */\nfunction normalizeModelConfig(\n cfg: AgentModelConfig | undefined,\n): { primary?: string; fallbacks: string[] } {\n if (!cfg) return { fallbacks: [] };\n return {\n primary: typeof cfg.primary === 'string' ? cfg.primary : undefined,\n fallbacks: Array.isArray(cfg.fallbacks)\n ? cfg.fallbacks.filter((s): s is string => typeof s === 'string')\n : [],\n };\n}\n\n// ============================================\n// Geometry helpers (nearest-neighbour)\n// ============================================\n\nexport function resolveClosestSize(params: {\n requestedSize?: string;\n requestedAspectRatio?: string;\n supportedSizes?: ReadonlyArray<string>;\n}): string | undefined {\n const supported = (params.supportedSizes ?? []).filter((s) => parseSize(s) !== null);\n if (supported.length === 0) return undefined;\n\n const target =\n parseSize(params.requestedSize) ??\n sizeFromAspectRatio(params.requestedAspectRatio, supported.map((s) => parseSize(s)!.totalPixels));\n\n if (!target) return supported[0];\n return supported\n .map((s) => ({ s, parsed: parseSize(s)! }))\n .reduce((best, cur) => {\n const score = sizeDistance(target, cur.parsed);\n return score < best.score ? { s: cur.s, score } : best;\n }, { s: supported[0], score: Number.POSITIVE_INFINITY })\n .s;\n}\n\nexport function resolveClosestAspectRatio(params: {\n requestedAspectRatio?: string;\n requestedSize?: string;\n supportedAspectRatios?: ReadonlyArray<string>;\n}): string | undefined {\n const supported = (params.supportedAspectRatios ?? []).filter((r) => parseAspectRatio(r) !== null);\n if (supported.length === 0) return undefined;\n\n const targetRatio =\n parseAspectRatio(params.requestedAspectRatio)?.value ??\n (() => {\n const sz = parseSize(params.requestedSize);\n return sz ? sz.width / sz.height : undefined;\n })();\n\n if (typeof targetRatio !== 'number' || !Number.isFinite(targetRatio)) {\n return supported[0];\n }\n\n return supported.reduce((best, cur) => {\n const v = parseAspectRatio(cur)!.value;\n const d = Math.abs(Math.log(v) - Math.log(targetRatio));\n return d < best.score ? { s: cur, score: d } : best;\n }, { s: supported[0], score: Number.POSITIVE_INFINITY }).s;\n}\n\nexport function resolveClosestResolution<T extends string>(params: {\n requestedResolution?: T;\n supportedResolutions?: ReadonlyArray<T>;\n}): T | undefined {\n const supported = params.supportedResolutions ?? [];\n if (supported.length === 0) return undefined;\n const requested = params.requestedResolution;\n if (!requested) return undefined;\n if (supported.includes(requested)) return requested;\n\n const order = ['1K', '2K', '4K', '8K'];\n const want = order.indexOf(String(requested));\n if (want < 0) return supported[0];\n\n // Prefer the largest supported value <= requested; otherwise pick the smallest available.\n const ranked = supported\n .map((r) => ({ r, idx: order.indexOf(String(r)) }))\n .filter((x) => x.idx >= 0)\n .sort((a, b) => a.idx - b.idx);\n if (ranked.length === 0) return supported[0];\n\n let chosen = ranked[0].r;\n for (const x of ranked) {\n if (x.idx <= want) chosen = x.r;\n }\n return chosen;\n}\n\nfunction parseSize(raw: string | undefined): { width: number; height: number; totalPixels: number } | null {\n if (typeof raw !== 'string') return null;\n const m = raw.trim().toLowerCase().match(/^(\\d{2,5})\\s*[x×*]\\s*(\\d{2,5})$/);\n if (!m) return null;\n const width = Number(m[1]);\n const height = Number(m[2]);\n if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;\n return { width, height, totalPixels: width * height };\n}\n\nfunction parseAspectRatio(raw: string | undefined): { value: number } | null {\n if (typeof raw !== 'string') return null;\n const m = raw.trim().match(/^(\\d{1,3})\\s*[:x×/]\\s*(\\d{1,3})$/);\n if (!m) return null;\n const w = Number(m[1]);\n const h = Number(m[2]);\n if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) return null;\n return { value: w / h };\n}\n\nfunction sizeFromAspectRatio(\n ratioStr: string | undefined,\n pixelHints: number[],\n): { width: number; height: number; totalPixels: number } | null {\n const r = parseAspectRatio(ratioStr);\n if (!r) return null;\n const pixels = pixelHints.length > 0 ? Math.round(pixelHints.reduce((a, b) => a + b, 0) / pixelHints.length) : 1024 * 1024;\n const height = Math.round(Math.sqrt(pixels / r.value));\n const width = Math.round(height * r.value);\n return { width, height, totalPixels: width * height };\n}\n\nfunction sizeDistance(\n a: { width: number; height: number; totalPixels: number },\n b: { width: number; height: number; totalPixels: number },\n): number {\n // Combined area + aspect-ratio difference (log-scale on both for stability).\n const areaDelta = Math.abs(Math.log(a.totalPixels) - Math.log(b.totalPixels));\n const ratioA = a.width / a.height;\n const ratioB = b.width / b.height;\n const ratioDelta = Math.abs(Math.log(ratioA) - Math.log(ratioB));\n return areaDelta + ratioDelta * 1.5;\n}\n\n// ============================================\n// Failure aggregation\n// ============================================\n\nexport interface RecordCapabilityCandidateFailureParams {\n attempts: FallbackAttempt[];\n provider: string;\n model: string;\n error: unknown;\n durationMs?: number;\n}\n\n/** Push a structured {@link FallbackAttempt} entry derived from `error`. */\nexport function recordCapabilityCandidateFailure(\n params: RecordCapabilityCandidateFailureParams,\n): FallbackAttempt {\n const cls = classifyAttemptError(params.error);\n const attempt: FallbackAttempt = {\n provider: params.provider,\n model: params.model,\n error: cls.message,\n reason: cls.reason,\n ...(cls.status !== undefined ? { status: cls.status } : {}),\n ...(cls.code !== undefined ? { code: cls.code } : {}),\n ...(params.durationMs !== undefined ? { durationMs: params.durationMs } : {}),\n };\n params.attempts.push(attempt);\n return attempt;\n}\n\nexport interface ThrowCapabilityGenerationFailureParams {\n capabilityLabel: string;\n attempts: FallbackAttempt[];\n lastError: unknown;\n}\n\n/** Throw a unified {@link FailoverError} after all candidates have been exhausted. */\nexport function throwCapabilityGenerationFailure(params: ThrowCapabilityGenerationFailureParams): never {\n // capabilityLabel like \"image generation\" → identifier \"image-generation\"\n const capability = params.capabilityLabel.trim().toLowerCase().replace(/\\s+/g, '-') || 'capability';\n throw new FailoverError({\n capability,\n attempts: params.attempts,\n cause: params.lastError,\n });\n}\n\n// ============================================\n// \"No model configured\" message\n// ============================================\n\nexport interface BuildNoCapabilityModelConfiguredMessageParams {\n /** Display label, e.g. \"image-generation\". */\n capabilityLabel: string;\n /** Config key path, e.g. \"imageGenerationModel\". */\n modelConfigKey: string;\n providers: ReadonlyArray<CapabilityProviderCandidate>;\n /** Optional env-var lookup, e.g. (id) => PROVIDER_ENV_MAP[id]. */\n getProviderEnvVars?: (id: string) => readonly string[] | undefined;\n}\n\nexport function buildNoCapabilityModelConfiguredMessage(\n params: BuildNoCapabilityModelConfiguredMessageParams,\n): string {\n const lines: string[] = [\n `No ${params.capabilityLabel} model configured. Set agents.defaults.${params.modelConfigKey} ` +\n `to a \"<provider>/<model>\" value (or pass modelOverride at call site).`,\n ];\n if (params.providers.length > 0) {\n lines.push('Registered providers:');\n for (const p of params.providers) {\n const envs = params.getProviderEnvVars?.(p.id) ?? [];\n const env = envs.length > 0 ? ` (env: ${envs.join(' | ')})` : '';\n const def = p.defaultModel ? ` default=${p.defaultModel}` : '';\n lines.push(` - ${p.id}${def}${env}`);\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build a `metadata.normalization` snapshot from a completed normalization\n * pass. Providers / runtime can spread it into their result metadata.\n */\nexport function buildMediaGenerationNormalizationMetadata(params: {\n normalization?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (!params.normalization || Object.keys(params.normalization).length === 0) return {};\n return { normalization: params.normalization };\n}\n\n// Re-export the union for downstream type narrowing.\nexport type { FailoverReason };\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime-shared.js","names":[],"sources":["../../../../src/agent/media-generation/runtime-shared.ts"],"sourcesContent":["/**\n * Cross-capability runtime helpers shared by image / audio / video\n * generation. Pure functions (no IO) so they can be unit-tested without\n * touching providers.\n *\n * - candidate model resolution\n * - geometry/value nearest-neighbour matching\n * - terminal failure aggregation (FailoverError)\n * - \"no model configured\" message builder\n */\n\nimport type { Config, AgentModelConfig } from '../../config/schema.js';\nimport {\n classifyAttemptError,\n FailoverError,\n type FallbackAttempt,\n type FailoverReason,\n} from '../failover-error.js';\nimport { parseCapabilityModelRef, type ParsedCapabilityModelRef } from './model-ref.js';\n\n// ============================================\n// Candidate resolution\n// ============================================\n\nexport interface CapabilityProviderCandidate {\n id: string;\n aliases?: readonly string[];\n defaultModel?: string | null;\n models?: readonly string[];\n isConfigured?: (ctx: { cfg?: Config; agentDir?: string }) => boolean;\n}\n\nexport interface ResolveCapabilityModelCandidatesParams {\n cfg?: Config;\n /** Active capability model config from a manifest/runtime policy. */\n modelConfig: { primary?: string; fallbacks?: string[] } | AgentModelConfig | undefined;\n /** Caller-supplied per-call override (highest priority). */\n modelOverride?: string;\n /** Optional ref parser; defaults to {@link parseCapabilityModelRef}. */\n parseModelRef?: (raw: string | undefined) => ParsedCapabilityModelRef | null;\n agentDir?: string;\n /** Snapshot of registered providers used to enumerate fallbacks. */\n listProviders: (cfg?: Config) => CapabilityProviderCandidate[];\n /**\n * When true and the explicit candidates fail, append every configured\n * provider's default model.\n */\n autoProviderFallback?: boolean;\n}\n\nexport interface ResolvedCapabilityModelCandidate {\n provider: string;\n model: string;\n}\n\n/**\n * Build the ordered candidate list from:\n * 1. modelOverride\n * 2. modelConfig.primary\n * 3. modelConfig.fallbacks[]\n * 4. (optional) every isConfigured() provider's defaultModel\n *\n * Duplicates are dropped (case-insensitive on provider, exact on model).\n */\nexport function resolveCapabilityModelCandidates(\n params: ResolveCapabilityModelCandidatesParams,\n): ResolvedCapabilityModelCandidate[] {\n const parse = params.parseModelRef ?? parseCapabilityModelRef;\n const out: ResolvedCapabilityModelCandidate[] = [];\n const seen = new Set<string>();\n\n const push = (raw: string | undefined) => {\n const parsed = parse(raw);\n if (!parsed) return;\n const key = `${parsed.provider}::${parsed.model}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ provider: parsed.provider, model: parsed.model });\n };\n\n const normalizedModelConfig = normalizeModelConfig(params.modelConfig);\n push(params.modelOverride);\n push(normalizedModelConfig.primary);\n for (const fb of normalizedModelConfig.fallbacks) push(fb);\n\n if (params.autoProviderFallback) {\n const providers = safeListProviders(params.listProviders, params.cfg);\n for (const provider of providers) {\n if (!provider.defaultModel) continue;\n let configured = true;\n try {\n configured = provider.isConfigured?.({ cfg: params.cfg, agentDir: params.agentDir }) ?? true;\n } catch {\n configured = false;\n }\n if (!configured) continue;\n push(`${provider.id}/${provider.defaultModel}`);\n }\n }\n\n return out;\n}\n\nfunction safeListProviders(\n fn: (cfg?: Config) => CapabilityProviderCandidate[],\n cfg?: Config,\n): CapabilityProviderCandidate[] {\n try {\n return fn(cfg) ?? [];\n } catch {\n return [];\n }\n}\n\n/** Normalize an {@link AgentModelConfig} to `{ primary?, fallbacks }`. */\nfunction normalizeModelConfig(\n cfg: ResolveCapabilityModelCandidatesParams['modelConfig'],\n): { primary?: string; fallbacks: string[] } {\n if (!cfg) return { fallbacks: [] };\n return {\n primary: typeof cfg.primary === 'string' ? cfg.primary : undefined,\n fallbacks: Array.isArray(cfg.fallbacks)\n ? cfg.fallbacks.filter((s): s is string => typeof s === 'string')\n : [],\n };\n}\n\n// ============================================\n// Geometry helpers (nearest-neighbour)\n// ============================================\n\nexport function resolveClosestSize(params: {\n requestedSize?: string;\n requestedAspectRatio?: string;\n supportedSizes?: ReadonlyArray<string>;\n}): string | undefined {\n const supported = (params.supportedSizes ?? []).filter((s) => parseSize(s) !== null);\n if (supported.length === 0) return undefined;\n\n const target =\n parseSize(params.requestedSize) ??\n sizeFromAspectRatio(params.requestedAspectRatio, supported.map((s) => parseSize(s)!.totalPixels));\n\n if (!target) return supported[0];\n return supported\n .map((s) => ({ s, parsed: parseSize(s)! }))\n .reduce((best, cur) => {\n const score = sizeDistance(target, cur.parsed);\n return score < best.score ? { s: cur.s, score } : best;\n }, { s: supported[0], score: Number.POSITIVE_INFINITY })\n .s;\n}\n\nexport function resolveClosestAspectRatio(params: {\n requestedAspectRatio?: string;\n requestedSize?: string;\n supportedAspectRatios?: ReadonlyArray<string>;\n}): string | undefined {\n const supported = (params.supportedAspectRatios ?? []).filter((r) => parseAspectRatio(r) !== null);\n if (supported.length === 0) return undefined;\n\n const targetRatio =\n parseAspectRatio(params.requestedAspectRatio)?.value ??\n (() => {\n const sz = parseSize(params.requestedSize);\n return sz ? sz.width / sz.height : undefined;\n })();\n\n if (typeof targetRatio !== 'number' || !Number.isFinite(targetRatio)) {\n return supported[0];\n }\n\n return supported.reduce((best, cur) => {\n const v = parseAspectRatio(cur)!.value;\n const d = Math.abs(Math.log(v) - Math.log(targetRatio));\n return d < best.score ? { s: cur, score: d } : best;\n }, { s: supported[0], score: Number.POSITIVE_INFINITY }).s;\n}\n\nexport function resolveClosestResolution<T extends string>(params: {\n requestedResolution?: T;\n supportedResolutions?: ReadonlyArray<T>;\n}): T | undefined {\n const supported = params.supportedResolutions ?? [];\n if (supported.length === 0) return undefined;\n const requested = params.requestedResolution;\n if (!requested) return undefined;\n if (supported.includes(requested)) return requested;\n\n const order = ['1K', '2K', '4K', '8K'];\n const want = order.indexOf(String(requested));\n if (want < 0) return supported[0];\n\n // Prefer the largest supported value <= requested; otherwise pick the smallest available.\n const ranked = supported\n .map((r) => ({ r, idx: order.indexOf(String(r)) }))\n .filter((x) => x.idx >= 0)\n .sort((a, b) => a.idx - b.idx);\n if (ranked.length === 0) return supported[0];\n\n let chosen = ranked[0].r;\n for (const x of ranked) {\n if (x.idx <= want) chosen = x.r;\n }\n return chosen;\n}\n\nfunction parseSize(raw: string | undefined): { width: number; height: number; totalPixels: number } | null {\n if (typeof raw !== 'string') return null;\n const m = raw.trim().toLowerCase().match(/^(\\d{2,5})\\s*[x×*]\\s*(\\d{2,5})$/);\n if (!m) return null;\n const width = Number(m[1]);\n const height = Number(m[2]);\n if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;\n return { width, height, totalPixels: width * height };\n}\n\nfunction parseAspectRatio(raw: string | undefined): { value: number } | null {\n if (typeof raw !== 'string') return null;\n const m = raw.trim().match(/^(\\d{1,3})\\s*[:x×/]\\s*(\\d{1,3})$/);\n if (!m) return null;\n const w = Number(m[1]);\n const h = Number(m[2]);\n if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) return null;\n return { value: w / h };\n}\n\nfunction sizeFromAspectRatio(\n ratioStr: string | undefined,\n pixelHints: number[],\n): { width: number; height: number; totalPixels: number } | null {\n const r = parseAspectRatio(ratioStr);\n if (!r) return null;\n const pixels = pixelHints.length > 0 ? Math.round(pixelHints.reduce((a, b) => a + b, 0) / pixelHints.length) : 1024 * 1024;\n const height = Math.round(Math.sqrt(pixels / r.value));\n const width = Math.round(height * r.value);\n return { width, height, totalPixels: width * height };\n}\n\nfunction sizeDistance(\n a: { width: number; height: number; totalPixels: number },\n b: { width: number; height: number; totalPixels: number },\n): number {\n // Combined area + aspect-ratio difference (log-scale on both for stability).\n const areaDelta = Math.abs(Math.log(a.totalPixels) - Math.log(b.totalPixels));\n const ratioA = a.width / a.height;\n const ratioB = b.width / b.height;\n const ratioDelta = Math.abs(Math.log(ratioA) - Math.log(ratioB));\n return areaDelta + ratioDelta * 1.5;\n}\n\n// ============================================\n// Failure aggregation\n// ============================================\n\nexport interface RecordCapabilityCandidateFailureParams {\n attempts: FallbackAttempt[];\n provider: string;\n model: string;\n error: unknown;\n durationMs?: number;\n}\n\n/** Push a structured {@link FallbackAttempt} entry derived from `error`. */\nexport function recordCapabilityCandidateFailure(\n params: RecordCapabilityCandidateFailureParams,\n): FallbackAttempt {\n const cls = classifyAttemptError(params.error);\n const attempt: FallbackAttempt = {\n provider: params.provider,\n model: params.model,\n error: cls.message,\n reason: cls.reason,\n ...(cls.status !== undefined ? { status: cls.status } : {}),\n ...(cls.code !== undefined ? { code: cls.code } : {}),\n ...(params.durationMs !== undefined ? { durationMs: params.durationMs } : {}),\n };\n params.attempts.push(attempt);\n return attempt;\n}\n\nexport interface ThrowCapabilityGenerationFailureParams {\n capabilityLabel: string;\n attempts: FallbackAttempt[];\n lastError: unknown;\n}\n\n/** Throw a unified {@link FailoverError} after all candidates have been exhausted. */\nexport function throwCapabilityGenerationFailure(params: ThrowCapabilityGenerationFailureParams): never {\n // capabilityLabel like \"image generation\" → identifier \"image-generation\"\n const capability = params.capabilityLabel.trim().toLowerCase().replace(/\\s+/g, '-') || 'capability';\n throw new FailoverError({\n capability,\n attempts: params.attempts,\n cause: params.lastError,\n });\n}\n\n// ============================================\n// \"No model configured\" message\n// ============================================\n\nexport interface BuildNoCapabilityModelConfiguredMessageParams {\n /** Display label, e.g. \"image-generation\". */\n capabilityLabel: string;\n /** Config key path, e.g. \"imageGenerationModel\". */\n modelConfigKey: string;\n providers: ReadonlyArray<CapabilityProviderCandidate>;\n /** Optional env-var lookup, e.g. (id) => PROVIDER_ENV_MAP[id]. */\n getProviderEnvVars?: (id: string) => readonly string[] | undefined;\n}\n\nexport function buildNoCapabilityModelConfiguredMessage(\n params: BuildNoCapabilityModelConfiguredMessageParams,\n): string {\n const lines: string[] = [\n `No ${params.capabilityLabel} model configured. Add a manifest/runtime model policy for ${params.modelConfigKey} ` +\n `or pass modelOverride at call site.`,\n ];\n if (params.providers.length > 0) {\n lines.push('Registered providers:');\n for (const p of params.providers) {\n const envs = params.getProviderEnvVars?.(p.id) ?? [];\n const env = envs.length > 0 ? ` (env: ${envs.join(' | ')})` : '';\n const def = p.defaultModel ? ` default=${p.defaultModel}` : '';\n lines.push(` - ${p.id}${def}${env}`);\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build a `metadata.normalization` snapshot from a completed normalization\n * pass. Providers / runtime can spread it into their result metadata.\n */\nexport function buildMediaGenerationNormalizationMetadata(params: {\n normalization?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (!params.normalization || Object.keys(params.normalization).length === 0) return {};\n return { normalization: params.normalization };\n}\n\n// Re-export the union for downstream type narrowing.\nexport type { FailoverReason };\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Bounded curated memory: agent home `memories/MEMORY.md` + `USER.md`, §-delimited entries.
2
+ * Bounded curated memory: agent home `memories/MEMORY.md` + global `user/MEMORY.md`, §-delimited entries.
3
3
  * Snapshot for system prompt is captured at load time and not mutated until next load.
4
4
  */
5
5
  import type { MemorySnapshot, MemoryStoreConfig } from './types.js';
@@ -10,10 +10,14 @@ export declare class BuiltinMemoryStore {
10
10
  private userEntries;
11
11
  private snapshot;
12
12
  constructor(config: MemoryStoreConfig);
13
- /** When false, USER.md is omitted from the snapshot and should not be edited via `curated_memory`. */
13
+ /** When false, global user memory is omitted from the snapshot and should not be edited via `curated_memory`. */
14
14
  isUserProfileEnabled(): boolean;
15
15
  /** Agent-scoped curated memory directory (`~/.xopc/agents/<id>/memories/`). */
16
16
  get memoriesDir(): string;
17
+ /** Global user memory file (`~/.xopc/user/MEMORY.md`). */
18
+ get userMemoryPath(): string;
19
+ /** Workspace whose MEMORY.md and daily notes participate in local memory search. */
20
+ get workspaceDir(): string;
17
21
  pathFor(target: 'memory' | 'user'): string;
18
22
  /**
19
23
  * Load from disk and freeze {@link getSnapshot}. Sync for agent creation (prefix cache stability).
@@ -1,10 +1,10 @@
1
+ import { dirname, join } from "node:path";
1
2
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
2
3
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
4
  import lockfile from "proper-lockfile";
5
5
  //#region src/agent/memory/builtin-memory-store.ts
6
6
  /**
7
- * Bounded curated memory: agent home `memories/MEMORY.md` + `USER.md`, §-delimited entries.
7
+ * Bounded curated memory: agent home `memories/MEMORY.md` + global `user/MEMORY.md`, §-delimited entries.
8
8
  * Snapshot for system prompt is captured at load time and not mutated until next load.
9
9
  */
10
10
  const MEMORY_ENTRY_DELIMITER = "\n§\n";
@@ -20,7 +20,7 @@ var BuiltinMemoryStore = class {
20
20
  constructor(config) {
21
21
  this.config = config;
22
22
  }
23
- /** When false, USER.md is omitted from the snapshot and should not be edited via `curated_memory`. */
23
+ /** When false, global user memory is omitted from the snapshot and should not be edited via `curated_memory`. */
24
24
  isUserProfileEnabled() {
25
25
  return this.config.userProfileEnabled !== false;
26
26
  }
@@ -28,8 +28,16 @@ var BuiltinMemoryStore = class {
28
28
  get memoriesDir() {
29
29
  return this.config.memoriesDir;
30
30
  }
31
+ /** Global user memory file (`~/.xopc/user/MEMORY.md`). */
32
+ get userMemoryPath() {
33
+ return this.config.userMemoryPath;
34
+ }
35
+ /** Workspace whose MEMORY.md and daily notes participate in local memory search. */
36
+ get workspaceDir() {
37
+ return this.config.workspaceDir;
38
+ }
31
39
  pathFor(target) {
32
- return join(this.memoriesDir, target === "memory" ? "MEMORY.md" : "USER.md");
40
+ return target === "memory" ? join(this.memoriesDir, "MEMORY.md") : this.userMemoryPath;
33
41
  }
34
42
  /**
35
43
  * Load from disk and freeze {@link getSnapshot}. Sync for agent creation (prefix cache stability).
@@ -37,7 +45,7 @@ var BuiltinMemoryStore = class {
37
45
  loadFromDiskSync() {
38
46
  mkdirSync(this.memoriesDir, { recursive: true });
39
47
  this.memoryEntries = this.parseFileContent(this.readPathSync(join(this.memoriesDir, "MEMORY.md")));
40
- this.userEntries = this.config.userProfileEnabled === false ? [] : this.parseFileContent(this.readPathSync(join(this.memoriesDir, "USER.md")));
48
+ this.userEntries = this.config.userProfileEnabled === false ? [] : this.parseFileContent(this.readPathSync(this.userMemoryPath));
41
49
  this.memoryEntries = dedupePreserveOrder(this.memoryEntries);
42
50
  this.userEntries = dedupePreserveOrder(this.userEntries);
43
51
  this.snapshot = {
@@ -181,7 +189,7 @@ var BuiltinMemoryStore = class {
181
189
  }
182
190
  async withFileLock(target, fn) {
183
191
  const filePath = this.pathFor(target);
184
- await mkdir(this.memoriesDir, { recursive: true });
192
+ await mkdir(dirname(filePath), { recursive: true });
185
193
  if (!existsSync(filePath)) await writeFile(filePath, "", "utf-8");
186
194
  await lockfile.lock(filePath, {
187
195
  retries: 3,
@@ -210,6 +218,7 @@ var BuiltinMemoryStore = class {
210
218
  const filePath = this.pathFor(target);
211
219
  const content = entries.join(MEMORY_ENTRY_DELIMITER);
212
220
  const tmpPath = `${filePath}.tmp.${Date.now()}`;
221
+ await mkdir(dirname(filePath), { recursive: true });
213
222
  await writeFile(tmpPath, content, "utf-8");
214
223
  await rename(tmpPath, filePath);
215
224
  }
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-memory-store.js","names":[],"sources":["../../../../src/agent/memory/builtin-memory-store.ts"],"sourcesContent":["/**\n * Bounded curated memory: agent home `memories/MEMORY.md` + `USER.md`, §-delimited entries.\n * Snapshot for system prompt is captured at load time and not mutated until next load.\n */\n\nimport { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport lockfile from 'proper-lockfile';\n\nimport type { MemorySnapshot, MemoryStoreConfig } from './types.js';\n\nexport const MEMORY_ENTRY_DELIMITER = '\\n§\\n';\n\nconst DEFAULT_MEMORY_LIMIT = 2200;\nconst DEFAULT_USER_LIMIT = 1375;\n\nexport class BuiltinMemoryStore {\n private memoryEntries: string[] = [];\n private userEntries: string[] = [];\n private snapshot: MemorySnapshot = { memory: '', user: '' };\n\n constructor(private readonly config: MemoryStoreConfig) {}\n\n /** When false, USER.md is omitted from the snapshot and should not be edited via `curated_memory`. */\n isUserProfileEnabled(): boolean {\n return this.config.userProfileEnabled !== false;\n }\n\n /** Agent-scoped curated memory directory (`~/.xopc/agents/<id>/memories/`). */\n get memoriesDir(): string {\n return this.config.memoriesDir;\n }\n\n pathFor(target: 'memory' | 'user'): string {\n return join(this.memoriesDir, target === 'memory' ? 'MEMORY.md' : 'USER.md');\n }\n\n /**\n * Load from disk and freeze {@link getSnapshot}. Sync for agent creation (prefix cache stability).\n */\n loadFromDiskSync(): void {\n mkdirSync(this.memoriesDir, { recursive: true });\n this.memoryEntries = this.parseFileContent(\n this.readPathSync(join(this.memoriesDir, 'MEMORY.md')),\n );\n this.userEntries =\n this.config.userProfileEnabled === false\n ? []\n : this.parseFileContent(this.readPathSync(join(this.memoriesDir, 'USER.md')));\n this.memoryEntries = dedupePreserveOrder(this.memoryEntries);\n this.userEntries = dedupePreserveOrder(this.userEntries);\n this.snapshot = {\n memory: this.renderBlock('memory', this.memoryEntries),\n user: this.renderBlock('user', this.userEntries),\n };\n }\n\n private readPathSync(path: string): string {\n try {\n if (!existsSync(path)) return '';\n return readFileSync(path, { encoding: 'utf-8' });\n } catch {\n return '';\n }\n }\n\n private parseFileContent(raw: string): string[] {\n if (!raw.trim()) return [];\n return raw\n .split(MEMORY_ENTRY_DELIMITER)\n .map((e) => e.trim())\n .filter(Boolean);\n }\n\n getSnapshot(): MemorySnapshot {\n return this.snapshot;\n }\n\n /**\n * Live entries for read/debug (may differ from snapshot after mutations).\n */\n getLiveEntries(target: 'memory' | 'user'): string[] {\n return target === 'memory' ? [...this.memoryEntries] : [...this.userEntries];\n }\n\n async add(\n target: 'memory' | 'user',\n content: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const trimmed = content.trim();\n if (!trimmed) {\n return { success: false, error: 'Content cannot be empty.' };\n }\n const scanError = scanForThreats(trimmed);\n if (scanError) {\n return { success: false, error: scanError };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const limit = this.charLimit(target);\n\n if (entries.includes(trimmed)) {\n return { success: false, error: 'Entry already exists' };\n }\n\n const newTotal = calculateTotal([...entries, trimmed]);\n if (newTotal > limit) {\n return {\n success: false,\n error: `Memory at ${calculateTotal(entries)}/${limit} chars. Adding would exceed limit.`,\n };\n }\n\n entries.push(trimmed);\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry added.' };\n });\n }\n\n async replace(\n target: 'memory' | 'user',\n oldText: string,\n newContent: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const ot = oldText.trim();\n const nc = newContent.trim();\n if (!ot) {\n return { success: false, error: 'old_text cannot be empty.' };\n }\n if (!nc) {\n return { success: false, error: 'new_content cannot be empty. Use remove to delete entries.' };\n }\n const scanError = scanForThreats(nc);\n if (scanError) {\n return { success: false, error: scanError };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const matches: Array<{ index: number; entry: string }> = [];\n for (let i = 0; i < entries.length; i++) {\n if (entries[i].includes(ot)) {\n matches.push({ index: i, entry: entries[i] });\n }\n }\n\n if (matches.length === 0) {\n return { success: false, error: `No entry matched '${ot}'.` };\n }\n\n if (matches.length > 1) {\n const uniqueTexts = new Set(matches.map((m) => m.entry));\n if (uniqueTexts.size > 1) {\n const previews = matches.map((m) =>\n m.entry.length > 80 ? `${m.entry.slice(0, 80)}...` : m.entry,\n );\n return {\n success: false,\n error: `Multiple entries matched '${ot}'. Be more specific. Previews: ${previews.join(' | ')}`,\n };\n }\n }\n\n const idx = matches[0].index;\n const limit = this.charLimit(target);\n const testEntries = [...entries];\n testEntries[idx] = nc;\n\n if (calculateTotal(testEntries) > limit) {\n return {\n success: false,\n error: `Replacement would put memory at ${calculateTotal(testEntries)}/${limit} chars.`,\n };\n }\n\n entries[idx] = nc;\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry replaced.' };\n });\n }\n\n async remove(\n target: 'memory' | 'user',\n oldText: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const ot = oldText.trim();\n if (!ot) {\n return { success: false, error: 'old_text cannot be empty.' };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const matches: number[] = [];\n for (let i = 0; i < entries.length; i++) {\n if (entries[i].includes(ot)) {\n matches.push(i);\n }\n }\n\n if (matches.length === 0) {\n return { success: false, error: `No entry matched '${ot}'.` };\n }\n\n if (matches.length > 1) {\n const uniqueTexts = new Set(matches.map((i) => entries[i]));\n if (uniqueTexts.size > 1) {\n const previews = matches.map((i) => {\n const e = entries[i];\n return e.length > 80 ? `${e.slice(0, 80)}...` : e;\n });\n return {\n success: false,\n error: `Multiple entries matched '${ot}'. Be more specific. Previews: ${previews.join(' | ')}`,\n };\n }\n }\n\n entries.splice(matches[0], 1);\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry removed.' };\n });\n }\n\n private async withFileLock<T>(\n target: 'memory' | 'user',\n fn: () => Promise<T>,\n ): Promise<T> {\n const filePath = this.pathFor(target);\n await mkdir(this.memoriesDir, { recursive: true });\n if (!existsSync(filePath)) {\n await writeFile(filePath, '', 'utf-8');\n }\n await lockfile.lock(filePath, { retries: 3, stale: 10_000 });\n try {\n return await fn();\n } finally {\n await lockfile.unlock(filePath);\n }\n }\n\n private async reloadTargetFromDisk(target: 'memory' | 'user'): Promise<void> {\n const path = this.pathFor(target);\n let raw = '';\n try {\n raw = await readFile(path, 'utf-8');\n } catch {\n raw = '';\n }\n const parsed = dedupePreserveOrder(this.parseFileContent(raw));\n if (target === 'memory') {\n this.memoryEntries = parsed;\n } else {\n this.userEntries = parsed;\n }\n }\n\n private async flushTargetToDisk(target: 'memory' | 'user'): Promise<void> {\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const filePath = this.pathFor(target);\n const content = entries.join(MEMORY_ENTRY_DELIMITER);\n const tmpPath = `${filePath}.tmp.${Date.now()}`;\n await writeFile(tmpPath, content, 'utf-8');\n await rename(tmpPath, filePath);\n }\n\n private charLimit(target: 'memory' | 'user'): number {\n return target === 'memory'\n ? (this.config.memoryCharLimit ?? DEFAULT_MEMORY_LIMIT)\n : (this.config.userCharLimit ?? DEFAULT_USER_LIMIT);\n }\n\n private renderBlock(target: 'memory' | 'user', entries: string[]): string {\n if (entries.length === 0) {\n return '';\n }\n\n const limit = this.charLimit(target);\n const content = entries.join(MEMORY_ENTRY_DELIMITER);\n const current = content.length;\n const pct = Math.min(100, Math.round((current / limit) * 100));\n\n const header =\n target === 'user'\n ? `USER PROFILE (who the user is) [${pct}% — ${current.toLocaleString()}/${limit.toLocaleString()} chars]`\n : `MEMORY (your personal notes) [${pct}% — ${current.toLocaleString()}/${limit.toLocaleString()} chars]`;\n\n const separator = '═'.repeat(46);\n return `${separator}\\n${header}\\n${separator}\\n${content}`;\n }\n}\n\nfunction dedupePreserveOrder(entries: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const e of entries) {\n if (seen.has(e)) {\n continue;\n }\n seen.add(e);\n out.push(e);\n }\n return out;\n}\n\nfunction calculateTotal(entries: string[]): number {\n if (entries.length === 0) {\n return 0;\n }\n return entries.join(MEMORY_ENTRY_DELIMITER).length;\n}\n\nexport function scanForThreats(content: string): string | null {\n const patterns: Array<{ regex: RegExp; id: string }> = [\n { regex: /ignore\\s+(previous|all|above|prior)\\s+instructions/i, id: 'prompt_injection' },\n { regex: /you\\s+are\\s+now\\s+/i, id: 'role_hijack' },\n { regex: /do\\s+not\\s+tell\\s+the\\s+user/i, id: 'deception_hide' },\n { regex: /system\\s+prompt\\s+override/i, id: 'sys_prompt_override' },\n {\n regex: /disregard\\s+(your|all|any)\\s+(instructions|rules|guidelines)/i,\n id: 'disregard_rules',\n },\n {\n regex: /act\\s+as\\s+(if|though)\\s+you\\s+(have\\s+no|don't\\s+have)\\s+(restrictions|limits|rules)/i,\n id: 'bypass_restrictions',\n },\n { regex: /curl\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|API)/i, id: 'exfil_curl' },\n { regex: /wget\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|API)/i, id: 'exfil_wget' },\n {\n regex: /cat\\s+[^\\n]*(\\.env|credentials|\\.netrc|\\.pgpass|\\.npmrc|\\.pypirc)/i,\n id: 'read_secrets',\n },\n { regex: /authorized_keys/i, id: 'ssh_backdoor' },\n { regex: /\\$HOME\\/\\.ssh|\\~\\/\\.ssh/i, id: 'ssh_access' },\n ];\n\n for (const { regex, id } of patterns) {\n if (regex.test(content)) {\n return `Blocked: content matches threat pattern '${id}'. Memory entries are injected into the system prompt and must not contain injection payloads.`;\n }\n }\n\n const invisibleChars = [\n '\\u200b',\n '\\u200c',\n '\\u200d',\n '\\u2060',\n '\\ufeff',\n '\\u202a',\n '\\u202b',\n '\\u202c',\n '\\u202d',\n '\\u202e',\n ];\n for (const char of invisibleChars) {\n if (content.includes(char)) {\n const code = char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0');\n return `Blocked: content contains invisible unicode character U+${code} (possible injection).`;\n }\n }\n\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"builtin-memory-store.js","names":[],"sources":["../../../../src/agent/memory/builtin-memory-store.ts"],"sourcesContent":["/**\n * Bounded curated memory: agent home `memories/MEMORY.md` + global `user/MEMORY.md`, §-delimited entries.\n * Snapshot for system prompt is captured at load time and not mutated until next load.\n */\n\nimport { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport lockfile from 'proper-lockfile';\n\nimport type { MemorySnapshot, MemoryStoreConfig } from './types.js';\n\nexport const MEMORY_ENTRY_DELIMITER = '\\n§\\n';\n\nconst DEFAULT_MEMORY_LIMIT = 2200;\nconst DEFAULT_USER_LIMIT = 1375;\n\nexport class BuiltinMemoryStore {\n private memoryEntries: string[] = [];\n private userEntries: string[] = [];\n private snapshot: MemorySnapshot = { memory: '', user: '' };\n\n constructor(private readonly config: MemoryStoreConfig) {}\n\n /** When false, global user memory is omitted from the snapshot and should not be edited via `curated_memory`. */\n isUserProfileEnabled(): boolean {\n return this.config.userProfileEnabled !== false;\n }\n\n /** Agent-scoped curated memory directory (`~/.xopc/agents/<id>/memories/`). */\n get memoriesDir(): string {\n return this.config.memoriesDir;\n }\n\n /** Global user memory file (`~/.xopc/user/MEMORY.md`). */\n get userMemoryPath(): string {\n return this.config.userMemoryPath;\n }\n\n /** Workspace whose MEMORY.md and daily notes participate in local memory search. */\n get workspaceDir(): string {\n return this.config.workspaceDir;\n }\n\n pathFor(target: 'memory' | 'user'): string {\n return target === 'memory' ? join(this.memoriesDir, 'MEMORY.md') : this.userMemoryPath;\n }\n\n /**\n * Load from disk and freeze {@link getSnapshot}. Sync for agent creation (prefix cache stability).\n */\n loadFromDiskSync(): void {\n mkdirSync(this.memoriesDir, { recursive: true });\n this.memoryEntries = this.parseFileContent(\n this.readPathSync(join(this.memoriesDir, 'MEMORY.md')),\n );\n this.userEntries =\n this.config.userProfileEnabled === false\n ? []\n : this.parseFileContent(this.readPathSync(this.userMemoryPath));\n this.memoryEntries = dedupePreserveOrder(this.memoryEntries);\n this.userEntries = dedupePreserveOrder(this.userEntries);\n this.snapshot = {\n memory: this.renderBlock('memory', this.memoryEntries),\n user: this.renderBlock('user', this.userEntries),\n };\n }\n\n private readPathSync(path: string): string {\n try {\n if (!existsSync(path)) return '';\n return readFileSync(path, { encoding: 'utf-8' });\n } catch {\n return '';\n }\n }\n\n private parseFileContent(raw: string): string[] {\n if (!raw.trim()) return [];\n return raw\n .split(MEMORY_ENTRY_DELIMITER)\n .map((e) => e.trim())\n .filter(Boolean);\n }\n\n getSnapshot(): MemorySnapshot {\n return this.snapshot;\n }\n\n /**\n * Live entries for read/debug (may differ from snapshot after mutations).\n */\n getLiveEntries(target: 'memory' | 'user'): string[] {\n return target === 'memory' ? [...this.memoryEntries] : [...this.userEntries];\n }\n\n async add(\n target: 'memory' | 'user',\n content: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const trimmed = content.trim();\n if (!trimmed) {\n return { success: false, error: 'Content cannot be empty.' };\n }\n const scanError = scanForThreats(trimmed);\n if (scanError) {\n return { success: false, error: scanError };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const limit = this.charLimit(target);\n\n if (entries.includes(trimmed)) {\n return { success: false, error: 'Entry already exists' };\n }\n\n const newTotal = calculateTotal([...entries, trimmed]);\n if (newTotal > limit) {\n return {\n success: false,\n error: `Memory at ${calculateTotal(entries)}/${limit} chars. Adding would exceed limit.`,\n };\n }\n\n entries.push(trimmed);\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry added.' };\n });\n }\n\n async replace(\n target: 'memory' | 'user',\n oldText: string,\n newContent: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const ot = oldText.trim();\n const nc = newContent.trim();\n if (!ot) {\n return { success: false, error: 'old_text cannot be empty.' };\n }\n if (!nc) {\n return { success: false, error: 'new_content cannot be empty. Use remove to delete entries.' };\n }\n const scanError = scanForThreats(nc);\n if (scanError) {\n return { success: false, error: scanError };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const matches: Array<{ index: number; entry: string }> = [];\n for (let i = 0; i < entries.length; i++) {\n if (entries[i].includes(ot)) {\n matches.push({ index: i, entry: entries[i] });\n }\n }\n\n if (matches.length === 0) {\n return { success: false, error: `No entry matched '${ot}'.` };\n }\n\n if (matches.length > 1) {\n const uniqueTexts = new Set(matches.map((m) => m.entry));\n if (uniqueTexts.size > 1) {\n const previews = matches.map((m) =>\n m.entry.length > 80 ? `${m.entry.slice(0, 80)}...` : m.entry,\n );\n return {\n success: false,\n error: `Multiple entries matched '${ot}'. Be more specific. Previews: ${previews.join(' | ')}`,\n };\n }\n }\n\n const idx = matches[0].index;\n const limit = this.charLimit(target);\n const testEntries = [...entries];\n testEntries[idx] = nc;\n\n if (calculateTotal(testEntries) > limit) {\n return {\n success: false,\n error: `Replacement would put memory at ${calculateTotal(testEntries)}/${limit} chars.`,\n };\n }\n\n entries[idx] = nc;\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry replaced.' };\n });\n }\n\n async remove(\n target: 'memory' | 'user',\n oldText: string,\n ): Promise<{ success: boolean; error?: string; message?: string }> {\n const ot = oldText.trim();\n if (!ot) {\n return { success: false, error: 'old_text cannot be empty.' };\n }\n\n return this.withFileLock(target, async () => {\n await this.reloadTargetFromDisk(target);\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const matches: number[] = [];\n for (let i = 0; i < entries.length; i++) {\n if (entries[i].includes(ot)) {\n matches.push(i);\n }\n }\n\n if (matches.length === 0) {\n return { success: false, error: `No entry matched '${ot}'.` };\n }\n\n if (matches.length > 1) {\n const uniqueTexts = new Set(matches.map((i) => entries[i]));\n if (uniqueTexts.size > 1) {\n const previews = matches.map((i) => {\n const e = entries[i];\n return e.length > 80 ? `${e.slice(0, 80)}...` : e;\n });\n return {\n success: false,\n error: `Multiple entries matched '${ot}'. Be more specific. Previews: ${previews.join(' | ')}`,\n };\n }\n }\n\n entries.splice(matches[0], 1);\n await this.flushTargetToDisk(target);\n return { success: true, message: 'Entry removed.' };\n });\n }\n\n private async withFileLock<T>(\n target: 'memory' | 'user',\n fn: () => Promise<T>,\n ): Promise<T> {\n const filePath = this.pathFor(target);\n await mkdir(dirname(filePath), { recursive: true });\n if (!existsSync(filePath)) {\n await writeFile(filePath, '', 'utf-8');\n }\n await lockfile.lock(filePath, { retries: 3, stale: 10_000 });\n try {\n return await fn();\n } finally {\n await lockfile.unlock(filePath);\n }\n }\n\n private async reloadTargetFromDisk(target: 'memory' | 'user'): Promise<void> {\n const path = this.pathFor(target);\n let raw = '';\n try {\n raw = await readFile(path, 'utf-8');\n } catch {\n raw = '';\n }\n const parsed = dedupePreserveOrder(this.parseFileContent(raw));\n if (target === 'memory') {\n this.memoryEntries = parsed;\n } else {\n this.userEntries = parsed;\n }\n }\n\n private async flushTargetToDisk(target: 'memory' | 'user'): Promise<void> {\n const entries = target === 'memory' ? this.memoryEntries : this.userEntries;\n const filePath = this.pathFor(target);\n const content = entries.join(MEMORY_ENTRY_DELIMITER);\n const tmpPath = `${filePath}.tmp.${Date.now()}`;\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(tmpPath, content, 'utf-8');\n await rename(tmpPath, filePath);\n }\n\n private charLimit(target: 'memory' | 'user'): number {\n return target === 'memory'\n ? (this.config.memoryCharLimit ?? DEFAULT_MEMORY_LIMIT)\n : (this.config.userCharLimit ?? DEFAULT_USER_LIMIT);\n }\n\n private renderBlock(target: 'memory' | 'user', entries: string[]): string {\n if (entries.length === 0) {\n return '';\n }\n\n const limit = this.charLimit(target);\n const content = entries.join(MEMORY_ENTRY_DELIMITER);\n const current = content.length;\n const pct = Math.min(100, Math.round((current / limit) * 100));\n\n const header =\n target === 'user'\n ? `USER PROFILE (who the user is) [${pct}% — ${current.toLocaleString()}/${limit.toLocaleString()} chars]`\n : `MEMORY (your personal notes) [${pct}% — ${current.toLocaleString()}/${limit.toLocaleString()} chars]`;\n\n const separator = '═'.repeat(46);\n return `${separator}\\n${header}\\n${separator}\\n${content}`;\n }\n}\n\nfunction dedupePreserveOrder(entries: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const e of entries) {\n if (seen.has(e)) {\n continue;\n }\n seen.add(e);\n out.push(e);\n }\n return out;\n}\n\nfunction calculateTotal(entries: string[]): number {\n if (entries.length === 0) {\n return 0;\n }\n return entries.join(MEMORY_ENTRY_DELIMITER).length;\n}\n\nexport function scanForThreats(content: string): string | null {\n const patterns: Array<{ regex: RegExp; id: string }> = [\n { regex: /ignore\\s+(previous|all|above|prior)\\s+instructions/i, id: 'prompt_injection' },\n { regex: /you\\s+are\\s+now\\s+/i, id: 'role_hijack' },\n { regex: /do\\s+not\\s+tell\\s+the\\s+user/i, id: 'deception_hide' },\n { regex: /system\\s+prompt\\s+override/i, id: 'sys_prompt_override' },\n {\n regex: /disregard\\s+(your|all|any)\\s+(instructions|rules|guidelines)/i,\n id: 'disregard_rules',\n },\n {\n regex: /act\\s+as\\s+(if|though)\\s+you\\s+(have\\s+no|don't\\s+have)\\s+(restrictions|limits|rules)/i,\n id: 'bypass_restrictions',\n },\n { regex: /curl\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|API)/i, id: 'exfil_curl' },\n { regex: /wget\\s+[^\\n]*\\$\\{?\\w*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|API)/i, id: 'exfil_wget' },\n {\n regex: /cat\\s+[^\\n]*(\\.env|credentials|\\.netrc|\\.pgpass|\\.npmrc|\\.pypirc)/i,\n id: 'read_secrets',\n },\n { regex: /authorized_keys/i, id: 'ssh_backdoor' },\n { regex: /\\$HOME\\/\\.ssh|\\~\\/\\.ssh/i, id: 'ssh_access' },\n ];\n\n for (const { regex, id } of patterns) {\n if (regex.test(content)) {\n return `Blocked: content matches threat pattern '${id}'. Memory entries are injected into the system prompt and must not contain injection payloads.`;\n }\n }\n\n const invisibleChars = [\n '\\u200b',\n '\\u200c',\n '\\u200d',\n '\\u2060',\n '\\ufeff',\n '\\u202a',\n '\\u202b',\n '\\u202c',\n '\\u202d',\n '\\u202e',\n ];\n for (const char of invisibleChars) {\n if (content.includes(char)) {\n const code = char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0');\n return `Blocked: content contains invisible unicode character U+${code} (possible injection).`;\n }\n }\n\n return null;\n}\n"],"mappings":"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"}
@@ -1,21 +1,43 @@
1
1
  import type { BuiltinMemoryStore } from './builtin-memory-store.js';
2
2
  import type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';
3
+ import type { MemoryDeleteRequest, MemoryListRequest, MemoryReadRequest, MemoryReadResult, MemoryRecord, MemorySearchRequest, MemorySearchResult, MemoryUpdateRequest, MemoryWriteRequest, MemoryWriteResult, MemorySyncEvent } from './types.js';
3
4
  /**
4
- * Builtin curated store: snapshot is injected via {@link MemorySnapshot} in the system prompt builder.
5
- * This provider participates in prefetch/sync orchestration only as a no-op.
5
+ * Builtin local memory provider backed by agent-home curated files, workspace MEMORY.md,
6
+ * daily notes, and the local SQLite FTS index.
6
7
  */
7
8
  export declare class BuiltinMemoryProvider implements MemoryProvider {
8
- private readonly _store;
9
- readonly name = "builtin";
10
- constructor(_store: BuiltinMemoryStore);
9
+ private readonly store;
10
+ readonly id = "local";
11
+ readonly displayName = "Local Markdown Memory";
12
+ readonly capabilities: {
13
+ search: boolean;
14
+ read: boolean;
15
+ write: boolean;
16
+ update: boolean;
17
+ delete: boolean;
18
+ keywordSearch: boolean;
19
+ semanticSearch: boolean;
20
+ hybridSearch: boolean;
21
+ citations: boolean;
22
+ sync: boolean;
23
+ local: boolean;
24
+ };
25
+ private workspaceDir;
26
+ private agentId;
27
+ constructor(store: BuiltinMemoryStore);
11
28
  isAvailable(): boolean;
12
- initialize(_sessionId: string, _options?: MemoryProviderInitOptions): Promise<void>;
13
- /** Curated blocks are injected separately as frozen snapshot; avoid duplicating in provider merge. */
29
+ initialize(_sessionId: string, options?: MemoryProviderInitOptions): Promise<void>;
14
30
  systemPromptBlock(): string;
15
31
  prefetch(): Promise<string>;
16
32
  queuePrefetch(): void;
17
- syncTurn(): void;
18
33
  getToolSchemas(): any[];
19
- handleToolCall(): Promise<string>;
34
+ search(request: MemorySearchRequest): Promise<MemorySearchResult[]>;
35
+ read(request: MemoryReadRequest): Promise<MemoryReadResult | null>;
36
+ get(id: string): Promise<MemoryRecord | null>;
37
+ list(request: MemoryListRequest): Promise<MemoryRecord[]>;
38
+ write(request: MemoryWriteRequest): Promise<MemoryWriteResult>;
39
+ update(request: MemoryUpdateRequest): Promise<MemoryWriteResult>;
40
+ delete(request: MemoryDeleteRequest): Promise<MemoryWriteResult>;
41
+ sync(event: MemorySyncEvent): void;
20
42
  shutdown(): Promise<void>;
21
43
  }
@@ -1,20 +1,39 @@
1
+ import { appendMemorySignal, deleteMemoryRecord, getMemoryRecord, listMemoryRecords, searchMemoryRecords, upsertMemoryRecord } from "../../storage/sqlite/memory-records-repository.js";
2
+ import "../../storage/sqlite/index.js";
3
+ import { memoryGet, memorySearch } from "../prompt/memory/index.js";
1
4
  //#region src/agent/memory/builtin-provider.ts
2
5
  /**
3
- * Builtin curated store: snapshot is injected via {@link MemorySnapshot} in the system prompt builder.
4
- * This provider participates in prefetch/sync orchestration only as a no-op.
6
+ * Builtin local memory provider backed by agent-home curated files, workspace MEMORY.md,
7
+ * daily notes, and the local SQLite FTS index.
5
8
  */
6
9
  var BuiltinMemoryProvider = class {
7
- name = "builtin";
8
- constructor(_store) {
9
- this._store = _store;
10
+ id = "local";
11
+ displayName = "Local Markdown Memory";
12
+ capabilities = {
13
+ search: true,
14
+ read: true,
15
+ write: true,
16
+ update: true,
17
+ delete: true,
18
+ keywordSearch: true,
19
+ semanticSearch: false,
20
+ hybridSearch: false,
21
+ citations: true,
22
+ sync: false,
23
+ local: true
24
+ };
25
+ workspaceDir = "";
26
+ agentId = "main";
27
+ constructor(store) {
28
+ this.store = store;
10
29
  }
11
30
  isAvailable() {
12
31
  return true;
13
32
  }
14
- async initialize(_sessionId, _options) {
15
- this._store;
33
+ async initialize(_sessionId, options) {
34
+ this.workspaceDir = options?.workspace ?? options?.agentWorkspace ?? this.store.workspaceDir;
35
+ this.agentId = String(options?.agentId ?? this.agentId);
16
36
  }
17
- /** Curated blocks are injected separately as frozen snapshot; avoid duplicating in provider merge. */
18
37
  systemPromptBlock() {
19
38
  return "";
20
39
  }
@@ -22,15 +41,275 @@ var BuiltinMemoryProvider = class {
22
41
  return "";
23
42
  }
24
43
  queuePrefetch() {}
25
- syncTurn() {}
26
44
  getToolSchemas() {
27
45
  return [];
28
46
  }
29
- async handleToolCall() {
30
- return JSON.stringify({ error: "Built-in memory uses curated_memory tool" });
47
+ async search(request) {
48
+ const agentId = request.scope?.agentId ?? this.agentId;
49
+ const workspaceId = request.scope?.workspaceId ?? this.workspaceDir;
50
+ const recordHits = searchMemoryRecords({
51
+ query: request.query,
52
+ agentId,
53
+ workspaceId,
54
+ providerId: this.id,
55
+ kinds: request.kinds,
56
+ maxResults: request.maxResults,
57
+ minScore: request.minScore
58
+ });
59
+ if (recordHits.length > 0) return recordHits;
60
+ return (await memorySearch(this.workspaceDir, request.query, {
61
+ maxResults: request.maxResults,
62
+ minScore: request.minScore,
63
+ memoriesDir: this.store.memoriesDir,
64
+ userMemoryPath: this.store.userMemoryPath,
65
+ agentId
66
+ })).map((entry) => {
67
+ const start = entry.lineNumbers[0] ?? 1;
68
+ const end = entry.lineNumbers[entry.lineNumbers.length - 1] ?? start;
69
+ const id = `${entry.file}#L${start}-L${end}`;
70
+ const kind = inferKindFromPath(entry.file);
71
+ return {
72
+ record: upsertMemoryRecord({
73
+ id,
74
+ providerId: this.id,
75
+ kind,
76
+ agentId,
77
+ workspaceId,
78
+ content: entry.lines,
79
+ source: {
80
+ provider: this.id,
81
+ path: entry.file,
82
+ lineStart: start,
83
+ lineEnd: end
84
+ },
85
+ confidence: entry.score
86
+ }),
87
+ score: entry.score,
88
+ snippet: entry.lines,
89
+ citation: {
90
+ providerId: this.id,
91
+ recordId: id,
92
+ path: entry.file,
93
+ lineStart: start,
94
+ lineEnd: end
95
+ }
96
+ };
97
+ });
98
+ }
99
+ async read(request) {
100
+ if (request.id && !request.path) {
101
+ const existing = getMemoryRecord(request.id);
102
+ if (existing) return { record: existing };
103
+ }
104
+ const result = memoryGet(this.workspaceDir, request.path ?? request.id ?? "", request.from, request.lines, this.store.memoriesDir, this.store.userMemoryPath);
105
+ if (!result) return null;
106
+ const path = request.path ?? request.id ?? "";
107
+ return {
108
+ record: upsertMemoryRecord({
109
+ id: `${path}#L${result.lineNumbers.start}-L${result.lineNumbers.end}`,
110
+ providerId: this.id,
111
+ kind: inferKindFromPath(path),
112
+ agentId: request.scope?.agentId ?? this.agentId,
113
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
114
+ content: result.content,
115
+ source: {
116
+ provider: this.id,
117
+ path,
118
+ lineStart: result.lineNumbers.start,
119
+ lineEnd: result.lineNumbers.end
120
+ }
121
+ }),
122
+ lineNumbers: result.lineNumbers
123
+ };
124
+ }
125
+ async get(id) {
126
+ const parsed = parseLineAddress(id);
127
+ return (await this.read({
128
+ path: parsed.path,
129
+ from: parsed.lineStart,
130
+ lines: parsed.lineEnd != null ? parsed.lineEnd - parsed.lineStart + 1 : void 0
131
+ }))?.record ?? null;
132
+ }
133
+ async list(request) {
134
+ const records = listMemoryRecords({
135
+ providerId: this.id,
136
+ agentId: request.scope?.agentId ?? this.agentId,
137
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
138
+ kind: request.kind,
139
+ limit: 200
140
+ });
141
+ if (records.length > 0 || request.kind) return request.target ? records.filter((record) => targetForKind(record.kind) === request.target) : records;
142
+ const target = request.target ?? (request.kind === "user_profile" ? "user" : "memory");
143
+ return this.store.getLiveEntries(target).map((content, index) => upsertMemoryRecord({
144
+ id: `curated:${target}:${index + 1}`,
145
+ providerId: this.id,
146
+ kind: target === "user" ? "user_profile" : "agent_note",
147
+ agentId: request.scope?.agentId ?? this.agentId,
148
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
149
+ content,
150
+ source: {
151
+ provider: this.id,
152
+ path: sourcePathForTarget(target)
153
+ }
154
+ }));
155
+ }
156
+ async write(request) {
157
+ const target = request.target ?? (request.kind === "user_profile" ? "user" : "memory");
158
+ if (request.status === "candidate") return {
159
+ success: true,
160
+ message: "Memory candidate added to inbox",
161
+ record: upsertMemoryRecord({
162
+ providerId: this.id,
163
+ kind: target === "user" ? "user_profile" : request.kind,
164
+ agentId: request.scope?.agentId ?? this.agentId,
165
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
166
+ sessionKey: request.scope?.sessionKey,
167
+ content: request.content,
168
+ source: {
169
+ ...request.source ?? {},
170
+ provider: this.id,
171
+ path: sourcePathForTarget(target)
172
+ },
173
+ confidence: request.confidence,
174
+ tags: request.tags,
175
+ status: "candidate",
176
+ sensitivity: request.sensitivity,
177
+ evidence: request.evidence,
178
+ reviewAfter: request.reviewAfter,
179
+ expiresAt: request.expiresAt
180
+ })
181
+ };
182
+ const result = await this.store.add(target, request.content);
183
+ if (!result.success) return {
184
+ success: false,
185
+ error: result.error
186
+ };
187
+ return {
188
+ success: true,
189
+ message: result.message,
190
+ record: upsertMemoryRecord({
191
+ id: `curated:${target}:${Date.now()}`,
192
+ providerId: this.id,
193
+ kind: target === "user" ? "user_profile" : request.kind,
194
+ agentId: request.scope?.agentId ?? this.agentId,
195
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
196
+ sessionKey: request.scope?.sessionKey,
197
+ content: request.content,
198
+ source: {
199
+ ...request.source ?? {},
200
+ provider: this.id,
201
+ path: sourcePathForTarget(target)
202
+ },
203
+ tags: request.tags
204
+ })
205
+ };
206
+ }
207
+ async update(request) {
208
+ const target = request.target ?? "memory";
209
+ const result = await this.store.replace(target, request.matchText ?? request.id ?? "", request.content);
210
+ if (!result.success) return {
211
+ success: false,
212
+ error: result.error
213
+ };
214
+ if (request.id) {
215
+ const existing = getMemoryRecord(request.id);
216
+ upsertMemoryRecord({
217
+ id: request.id,
218
+ providerId: this.id,
219
+ kind: existing?.kind ?? (target === "user" ? "user_profile" : "agent_note"),
220
+ agentId: existing?.scope.agentId ?? request.scope?.agentId ?? this.agentId,
221
+ workspaceId: existing?.scope.workspaceId ?? request.scope?.workspaceId ?? this.workspaceDir,
222
+ sessionKey: existing?.scope.sessionKey ?? request.scope?.sessionKey,
223
+ content: request.content,
224
+ source: existing?.source ?? {
225
+ provider: this.id,
226
+ path: sourcePathForTarget(target)
227
+ },
228
+ tags: existing?.tags
229
+ });
230
+ } else if (request.matchText) for (const existing of listMemoryRecords({
231
+ providerId: this.id,
232
+ agentId: request.scope?.agentId ?? this.agentId,
233
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
234
+ kind: target === "user" ? "user_profile" : "agent_note",
235
+ limit: 200
236
+ })) {
237
+ if (!existing.content.includes(request.matchText)) continue;
238
+ upsertMemoryRecord({
239
+ id: existing.id,
240
+ providerId: this.id,
241
+ kind: existing.kind,
242
+ agentId: existing.scope.agentId,
243
+ workspaceId: existing.scope.workspaceId,
244
+ sessionKey: existing.scope.sessionKey,
245
+ content: request.content,
246
+ source: existing.source,
247
+ tags: existing.tags
248
+ });
249
+ }
250
+ return {
251
+ success: true,
252
+ message: result.message
253
+ };
254
+ }
255
+ async delete(request) {
256
+ const target = request.target ?? "memory";
257
+ const result = await this.store.remove(target, request.matchText ?? request.id ?? "");
258
+ if (!result.success) return {
259
+ success: false,
260
+ error: result.error
261
+ };
262
+ if (request.id) deleteMemoryRecord(request.id);
263
+ else if (request.matchText) {
264
+ for (const existing of listMemoryRecords({
265
+ providerId: this.id,
266
+ agentId: request.scope?.agentId ?? this.agentId,
267
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
268
+ kind: target === "user" ? "user_profile" : "agent_note",
269
+ limit: 200
270
+ })) if (existing.content.includes(request.matchText)) deleteMemoryRecord(existing.id);
271
+ }
272
+ return {
273
+ success: true,
274
+ message: result.message
275
+ };
276
+ }
277
+ sync(event) {
278
+ if (event.type !== "signal") return;
279
+ appendMemorySignal({
280
+ signal: event.signal,
281
+ providerId: this.id,
282
+ agentId: this.agentId,
283
+ workspaceId: this.workspaceDir,
284
+ sessionKey: typeof event.signal.metadata?.sessionKey === "string" ? event.signal.metadata.sessionKey : void 0
285
+ });
31
286
  }
32
287
  async shutdown() {}
33
288
  };
289
+ function inferKindFromPath(path) {
290
+ const normalized = path.replace(/\\/g, "/");
291
+ if (normalized === "user/MEMORY.md" || normalized.endsWith("/user/MEMORY.md")) return "user_profile";
292
+ if (/^memory\/\d{4}-\d{2}-\d{2}\.md$/.test(normalized)) return "daily_note";
293
+ if (normalized.endsWith("MEMORY.md")) return "agent_note";
294
+ return "workspace_fact";
295
+ }
296
+ function targetForKind(kind) {
297
+ return kind === "user_profile" ? "user" : "memory";
298
+ }
299
+ function sourcePathForTarget(target) {
300
+ return target === "user" ? "user/MEMORY.md" : "MEMORY.md";
301
+ }
302
+ function parseLineAddress(id) {
303
+ const match = /^(.*)#L(\d+)(?:-L(\d+))?$/.exec(id);
304
+ if (!match) return { path: id };
305
+ const lineStart = Number.parseInt(match[2] ?? "1", 10);
306
+ const lineEnd = Number.parseInt(match[3] ?? match[2] ?? "1", 10);
307
+ return {
308
+ path: match[1] ?? id,
309
+ lineStart: Number.isFinite(lineStart) ? lineStart : void 0,
310
+ lineEnd: Number.isFinite(lineEnd) ? lineEnd : void 0
311
+ };
312
+ }
34
313
  //#endregion
35
314
  export { BuiltinMemoryProvider };
36
315