@xopcai/xopc 0.0.116 → 0.0.117

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 (599) hide show
  1. package/README.md +21 -6
  2. package/README.zh-CN.md +21 -6
  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-BBLhJ2C6.js} +1 -1
  33. package/dist/gateway/static/root/assets/agents-C6xgagZd.js +71 -0
  34. package/dist/gateway/static/root/assets/{app-management-settings-panel-yXSXY_bu.js → app-management-settings-panel-CBpLONvG.js} +1 -1
  35. package/dist/gateway/static/root/assets/{appearance-settings-DjY1P_ug.js → appearance-settings-CGcc54yj.js} +1 -1
  36. package/dist/gateway/static/root/assets/apps-page-DdDx0V4z.js +1 -0
  37. package/dist/gateway/static/root/assets/{archive-plugin-CytE5j-e.js → archive-plugin-DZsVqMhU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{attachment-load-BvvrN6rF.js → attachment-load-CIol6JWX.js} +1 -1
  39. package/dist/gateway/static/root/assets/{binary-plugins-IBWSitnj.js → binary-plugins-B3UauMfp.js} +1 -1
  40. package/dist/gateway/static/root/assets/{block-editor-C-wDpsf-.js → block-editor-2HJoFchH.js} +3 -3
  41. package/dist/gateway/static/root/assets/browser-settings-page-CUOO-PQk.js +8 -0
  42. package/dist/gateway/static/root/assets/capability-presets-api-XQoMTI0A.js +1 -0
  43. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CfqF-kGr.js +1 -0
  44. package/dist/gateway/static/root/assets/{channels-settings-Cd3JbeQ1.js → channels-settings-BYyRzsex.js} +1 -1
  45. package/dist/gateway/static/root/assets/connectors-page-DIvEz4NX.js +2 -0
  46. package/dist/gateway/static/root/assets/cron-api-R41aQCX9.js +1 -0
  47. package/dist/gateway/static/root/assets/cron-page-D97nFqQD.js +3 -0
  48. package/dist/gateway/static/root/assets/dreaming-settings-Bceaw1PG.js +1 -0
  49. package/dist/gateway/static/root/assets/{extension-debug-page-BAIyjDlq.js → extension-debug-page-DX5WRE_t.js} +1 -1
  50. package/dist/gateway/static/root/assets/{extension-page-DEhv2GpC.js → extension-page-Buah7Bw-.js} +1 -1
  51. package/dist/gateway/static/root/assets/{extension-settings-page-DOuAxTDW.js → extension-settings-page-DuroLVnf.js} +1 -1
  52. package/dist/gateway/static/root/assets/{fetch-CTsREQIe.js → fetch-B5zdl27C.js} +1 -1
  53. package/dist/gateway/static/root/assets/{format-interval-label-D35Bfhtx.js → format-interval-label-Dn_QKIqb.js} +1 -1
  54. package/dist/gateway/static/root/assets/gateway-config-api-gT4ZhE7h.js +1 -0
  55. package/dist/gateway/static/root/assets/gateway-settings-iISWAZRm.js +1 -0
  56. package/dist/gateway/static/root/assets/{gateway-startup-retry-C1KAHrd2.js → gateway-startup-retry-B3kL8KGY.js} +1 -1
  57. package/dist/gateway/static/root/assets/goal-detail-page-DCUROLMQ.js +1 -0
  58. package/dist/gateway/static/root/assets/{goals-config-api-KnLGpu6h.js → goals-config-api-AR-fVh0P.js} +1 -1
  59. package/dist/gateway/static/root/assets/goals-page-Cpb21ezg.js +2 -0
  60. package/dist/gateway/static/root/assets/{goals-settings-DtPtqZi8.js → goals-settings-CPAuFwoD.js} +1 -1
  61. package/dist/gateway/static/root/assets/{heartbeat-config-api-uKw1f0IG.js → heartbeat-config-api-D7bKFEeO.js} +1 -1
  62. package/dist/gateway/static/root/assets/{heartbeat-settings-DN9vEj9P.js → heartbeat-settings-CC69vNx0.js} +1 -1
  63. package/dist/gateway/static/root/assets/index-CwhK8qCh.js +122 -0
  64. package/dist/gateway/static/root/assets/index-CyfhARL-.css +1 -0
  65. package/dist/gateway/static/root/assets/{interval-presets-Dq0FXJ65.js → interval-presets-0DtsnxE0.js} +1 -1
  66. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C9_t4m7t.js → keyboard-shortcuts-settings-BPREtN8B.js} +1 -1
  67. package/dist/gateway/static/root/assets/{logs-page-SNkWzidV.js → logs-page-DefCgF4o.js} +2 -2
  68. package/dist/gateway/static/root/assets/{markdown-split-Ca87W8-h.js → markdown-split-ChbR9LGO.js} +1 -1
  69. package/dist/gateway/static/root/assets/{media-plugins-BAcUjPRJ.js → media-plugins-B82oP80n.js} +1 -1
  70. package/dist/gateway/static/root/assets/messages-Cf1O9JB0.js +3 -0
  71. package/dist/gateway/static/root/assets/models-hub-panel-DmKiIihT.js +2 -0
  72. package/dist/gateway/static/root/assets/note-detail-page-CxxfLRJZ.js +2 -0
  73. package/dist/gateway/static/root/assets/{note-image-lightbox-hnSX5SSn.js → note-image-lightbox-CDknITM3.js} +1 -1
  74. package/dist/gateway/static/root/assets/{notes-page-ycsDlkFA.js → notes-page-X2slSx7V.js} +1 -1
  75. package/dist/gateway/static/root/assets/{preview-open-alternatives-CNgM20H5.js → preview-open-alternatives-DV3xQsWB.js} +1 -1
  76. package/dist/gateway/static/root/assets/remote-access-hub-BvmUWqgu.js +1 -0
  77. package/dist/gateway/static/root/assets/{save-bar-controls-CcdjGcfT.js → save-bar-controls-BODCXnvY.js} +1 -1
  78. package/dist/gateway/static/root/assets/{schedule-field-CYr39z76.js → schedule-field-CgJSCD3B.js} +1 -1
  79. package/dist/gateway/static/root/assets/{schema-form-BRAJgZQ2.js → schema-form-qtfEI6QM.js} +1 -1
  80. package/dist/gateway/static/root/assets/sessions-page-B0yESuuL.js +1 -0
  81. package/dist/gateway/static/root/assets/settings-advanced-gate-q2M8RKOo.js +1 -0
  82. package/dist/gateway/static/root/assets/{settings-collapsible-section-BhzjeGWi.js → settings-collapsible-section-BHZKjVcS.js} +1 -1
  83. package/dist/gateway/static/root/assets/{settings-form-section-Cz3Pcr9b.js → settings-form-section-5i35D-J1.js} +1 -1
  84. package/dist/gateway/static/root/assets/settings-page-CGozabLD.js +1 -0
  85. package/dist/gateway/static/root/assets/setup-status-panel-FoOSe6nU.js +1 -0
  86. package/dist/gateway/static/root/assets/{share-preview-page-DL4y9K5e.js → share-preview-page-B0H63tDv.js} +1 -1
  87. package/dist/gateway/static/root/assets/shares-settings-Cy5zWyYQ.js +1 -0
  88. package/dist/gateway/static/root/assets/skill-reload-api-DaZNFro9.js +1 -0
  89. package/dist/gateway/static/root/assets/skills-page-CnwtUzvw.js +2 -0
  90. package/dist/gateway/static/root/assets/{system-settings-panel-FD2jxRZ3.js → system-settings-panel-DXs2VmBt.js} +1 -1
  91. package/dist/gateway/static/root/assets/typed-models-lib-4gPuydz_.js +1 -0
  92. package/dist/gateway/static/root/assets/{use-channel-catalog-BInPrfR5.js → use-channel-catalog-BCjP_VHb.js} +1 -1
  93. package/dist/gateway/static/root/assets/voice-api-key-field-DvKiOglO.js +1 -0
  94. package/dist/gateway/static/root/assets/{voice-player-store-1U3vFppm.js → voice-player-store-BlF9V05n.js} +1 -1
  95. package/dist/gateway/static/root/assets/workflows-page-CAVZcONQ.js +18 -0
  96. package/dist/gateway/static/root/index.html +5 -5
  97. package/dist/package.js +1 -1
  98. package/dist/src/agent/agent-manager.d.ts +1 -1
  99. package/dist/src/agent/agent-manager.js +13 -14
  100. package/dist/src/agent/agent-manager.js.map +1 -1
  101. package/dist/src/agent/agent-scope.js +7 -9
  102. package/dist/src/agent/agent-scope.js.map +1 -1
  103. package/dist/src/agent/background-review/coordinator.js +0 -1
  104. package/dist/src/agent/background-review/coordinator.js.map +1 -1
  105. package/dist/src/agent/background-review/run-background-review.d.ts +0 -2
  106. package/dist/src/agent/background-review/run-background-review.js +2 -4
  107. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  108. package/dist/src/agent/background-review/settings.js +8 -7
  109. package/dist/src/agent/background-review/settings.js.map +1 -1
  110. package/dist/src/agent/bootstrap/bootstrap-context.d.ts +2 -2
  111. package/dist/src/agent/bootstrap/bootstrap-context.js +4 -4
  112. package/dist/src/agent/bootstrap/bootstrap-context.js.map +1 -1
  113. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  114. package/dist/src/agent/bootstrap/project-agents-context.js +1 -1
  115. package/dist/src/agent/context/workspace-seed.js +3 -3
  116. package/dist/src/agent/context/workspace-state.js +1 -1
  117. package/dist/src/agent/context/workspace.js +1 -1
  118. package/dist/src/agent/embedded/run-for-session.js +1 -1
  119. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  120. package/dist/src/agent/fallback/candidates.js +6 -3
  121. package/dist/src/agent/fallback/candidates.js.map +1 -1
  122. package/dist/src/agent/goals/goal-locale.js +2 -2
  123. package/dist/src/agent/goals/post-turn.js +3 -3
  124. package/dist/src/agent/image/generation/runtime-types.d.ts +2 -0
  125. package/dist/src/agent/image/generation/runtime.js +1 -1
  126. package/dist/src/agent/image/generation/runtime.js.map +1 -1
  127. package/dist/src/agent/image/image-helpers.d.ts +1 -1
  128. package/dist/src/agent/image/image-helpers.js +4 -17
  129. package/dist/src/agent/image/image-helpers.js.map +1 -1
  130. package/dist/src/agent/image/image-model-fallback.js +1 -1
  131. package/dist/src/agent/image/image-model-fallback.js.map +1 -1
  132. package/dist/src/agent/image/inbound-image-handling.js +1 -1
  133. package/dist/src/agent/image/inbound-image-handling.js.map +1 -1
  134. package/dist/src/agent/image/load-image-media.js +2 -2
  135. package/dist/src/agent/image/tool-model-config.d.ts +1 -1
  136. package/dist/src/agent/image/tool-model-config.js +2 -2
  137. package/dist/src/agent/image/tool-model-config.js.map +1 -1
  138. package/dist/src/agent/ipc/inbox.js +3 -3
  139. package/dist/src/agent/ipc/socket.js +1 -1
  140. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  141. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  142. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  143. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  144. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js +1 -1
  145. package/dist/src/agent/mcp/resolve-embedded-mcp-tools.js.map +1 -1
  146. package/dist/src/agent/media-generation/runtime-shared.d.ts +5 -2
  147. package/dist/src/agent/media-generation/runtime-shared.js +1 -1
  148. package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
  149. package/dist/src/agent/memory/builtin-memory-store.d.ts +2 -0
  150. package/dist/src/agent/memory/builtin-memory-store.js +5 -1
  151. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  152. package/dist/src/agent/memory/builtin-provider.d.ts +31 -9
  153. package/dist/src/agent/memory/builtin-provider.js +261 -11
  154. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  155. package/dist/src/agent/memory/context-assembler.d.ts +10 -0
  156. package/dist/src/agent/memory/context-assembler.js +26 -0
  157. package/dist/src/agent/memory/context-assembler.js.map +1 -0
  158. package/dist/src/agent/memory/create-memory-manager.js +25 -7
  159. package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
  160. package/dist/src/agent/memory/dreaming/config.d.ts +1 -6
  161. package/dist/src/agent/memory/dreaming/config.js +8 -8
  162. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  163. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +2 -0
  164. package/dist/src/agent/memory/dreaming/deep-promotion.js +25 -1
  165. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  166. package/dist/src/agent/memory/dreaming/events.js +1 -1
  167. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  168. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  169. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  170. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  171. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  172. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  173. package/dist/src/agent/memory/index.d.ts +1 -0
  174. package/dist/src/agent/memory/index.js +4 -3
  175. package/dist/src/agent/memory/inject-prefetch.js +6 -2
  176. package/dist/src/agent/memory/inject-prefetch.js.map +1 -1
  177. package/dist/src/agent/memory/manager.d.ts +37 -1
  178. package/dist/src/agent/memory/manager.js +332 -40
  179. package/dist/src/agent/memory/manager.js.map +1 -1
  180. package/dist/src/agent/memory/memory-config.js +12 -15
  181. package/dist/src/agent/memory/memory-config.js.map +1 -1
  182. package/dist/src/agent/memory/memory-flush.js +1 -1
  183. package/dist/src/agent/memory/plugin-discovery.d.ts +19 -5
  184. package/dist/src/agent/memory/plugin-discovery.js +97 -31
  185. package/dist/src/agent/memory/plugin-discovery.js.map +1 -1
  186. package/dist/src/agent/memory/provider.d.ts +20 -15
  187. package/dist/src/agent/memory/stub-memory-provider.d.ts +17 -2
  188. package/dist/src/agent/memory/stub-memory-provider.js +20 -3
  189. package/dist/src/agent/memory/stub-memory-provider.js.map +1 -1
  190. package/dist/src/agent/memory/types.d.ts +136 -0
  191. package/dist/src/agent/models/manager.d.ts +1 -1
  192. package/dist/src/agent/models/manager.js +2 -2
  193. package/dist/src/agent/models/manager.js.map +1 -1
  194. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +1 -1
  195. package/dist/src/agent/orchestration/agent-orchestrator.js +2 -1
  196. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  197. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +2 -2
  198. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  199. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  200. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -6
  201. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +2 -8
  202. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js.map +1 -1
  203. package/dist/src/agent/prompt/memory/index.js +1 -1
  204. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  205. package/dist/src/agent/reply/post-compaction-context.js +12 -7
  206. package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
  207. package/dist/src/agent/reply/startup-context.js +8 -9
  208. package/dist/src/agent/reply/startup-context.js.map +1 -1
  209. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  210. package/dist/src/agent/sandbox/path-policy.js +2 -2
  211. package/dist/src/agent/service/process-direct-streaming.js +1 -4
  212. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  213. package/dist/src/agent/service/session-context-report.js +1 -1
  214. package/dist/src/agent/service/session-context-report.js.map +1 -1
  215. package/dist/src/agent/service.js +25 -29
  216. package/dist/src/agent/service.js.map +1 -1
  217. package/dist/src/agent/service.types.d.ts +1 -2
  218. package/dist/src/agent/session/session-hydrator.js +1 -2
  219. package/dist/src/agent/session/session-hydrator.js.map +1 -1
  220. package/dist/src/agent/session/session-inspector.d.ts +1 -1
  221. package/dist/src/agent/session/session-inspector.js +10 -15
  222. package/dist/src/agent/session/session-inspector.js.map +1 -1
  223. package/dist/src/agent/skills/config.js +2 -2
  224. package/dist/src/agent/skills/filesystem-watcher.js +1 -1
  225. package/dist/src/agent/skills/hub-hash.js +2 -2
  226. package/dist/src/agent/skills/hub-lock.js +1 -1
  227. package/dist/src/agent/skills/hub-pull.js +3 -3
  228. package/dist/src/agent/skills/index.js +2 -2
  229. package/dist/src/agent/skills/installer.js +2 -2
  230. package/dist/src/agent/skills/managed-store.js +1 -1
  231. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  232. package/dist/src/agent/skills/skill-manager.js +1 -1
  233. package/dist/src/agent/skills/skill-view-path.js +1 -1
  234. package/dist/src/agent/skills/test-framework.js +1 -1
  235. package/dist/src/agent/starter-agents.d.ts +1 -3
  236. package/dist/src/agent/starter-agents.js +14 -22
  237. package/dist/src/agent/starter-agents.js.map +1 -1
  238. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -2
  239. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  240. package/dist/src/agent/tools/curated-memory-tool.d.ts +2 -5
  241. package/dist/src/agent/tools/curated-memory-tool.js +20 -16
  242. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  243. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  244. package/dist/src/agent/tools/factory.d.ts +0 -4
  245. package/dist/src/agent/tools/factory.js +19 -58
  246. package/dist/src/agent/tools/factory.js.map +1 -1
  247. package/dist/src/agent/tools/find.js +1 -1
  248. package/dist/src/agent/tools/grep.js +1 -1
  249. package/dist/src/agent/tools/image-generate-tool.d.ts +1 -1
  250. package/dist/src/agent/tools/image-generate-tool.js +20 -15
  251. package/dist/src/agent/tools/image-generate-tool.js.map +1 -1
  252. package/dist/src/agent/tools/image-tool.js +1 -3
  253. package/dist/src/agent/tools/image-tool.js.map +1 -1
  254. package/dist/src/agent/tools/memory-tool.d.ts +2 -2
  255. package/dist/src/agent/tools/memory-tool.js +39 -14
  256. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  257. package/dist/src/agent/tools/session-search-tool.js +1 -3
  258. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  259. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  260. package/dist/src/agent/tools/web-extract.js +6 -5
  261. package/dist/src/agent/tools/web-extract.js.map +1 -1
  262. package/dist/src/agent/tools/workflow-tool.js +1 -1
  263. package/dist/src/agent/workflow/catalog.js +1 -1
  264. package/dist/src/agent/workflow/subagent-runner.js +1 -3
  265. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  266. package/dist/src/agent-manifest/index.d.ts +4 -0
  267. package/dist/src/agent-manifest/index.js +10 -0
  268. package/dist/src/agent-manifest/index.js.map +1 -0
  269. package/dist/src/agent-manifest/prompt.d.ts +2 -0
  270. package/dist/src/agent-manifest/prompt.js +57 -0
  271. package/dist/src/agent-manifest/prompt.js.map +1 -0
  272. package/dist/src/agent-manifest/resolver.d.ts +11 -0
  273. package/dist/src/agent-manifest/resolver.js +93 -0
  274. package/dist/src/agent-manifest/resolver.js.map +1 -0
  275. package/dist/src/agent-manifest/schema.d.ts +778 -0
  276. package/dist/src/agent-manifest/schema.js +267 -0
  277. package/dist/src/agent-manifest/schema.js.map +1 -0
  278. package/dist/src/agent-manifest/validator.d.ts +24 -0
  279. package/dist/src/agent-manifest/validator.js +87 -0
  280. package/dist/src/agent-manifest/validator.js.map +1 -0
  281. package/dist/src/agent-runtime/boundary-guard.d.ts +12 -0
  282. package/dist/src/agent-runtime/boundary-guard.js +23 -0
  283. package/dist/src/agent-runtime/boundary-guard.js.map +1 -0
  284. package/dist/src/agent-runtime/index.d.ts +7 -0
  285. package/dist/src/agent-runtime/index.js +8 -0
  286. package/dist/src/agent-runtime/memory-runtime.d.ts +21 -0
  287. package/dist/src/agent-runtime/memory-runtime.js +50 -0
  288. package/dist/src/agent-runtime/memory-runtime.js.map +1 -0
  289. package/dist/src/agent-runtime/model-router.d.ts +11 -0
  290. package/dist/src/agent-runtime/model-router.js +16 -0
  291. package/dist/src/agent-runtime/model-router.js.map +1 -0
  292. package/dist/src/agent-runtime/run-trace.d.ts +27 -0
  293. package/dist/src/agent-runtime/run-trace.js +53 -0
  294. package/dist/src/agent-runtime/run-trace.js.map +1 -0
  295. package/dist/src/agent-runtime/runtime-profile.d.ts +24 -0
  296. package/dist/src/agent-runtime/runtime-profile.js +44 -0
  297. package/dist/src/agent-runtime/runtime-profile.js.map +1 -0
  298. package/dist/src/agent-runtime/tool-registry.d.ts +28 -0
  299. package/dist/src/agent-runtime/tool-registry.js +52 -0
  300. package/dist/src/agent-runtime/tool-registry.js.map +1 -0
  301. package/dist/src/agent-runtime/workflow-runtime.d.ts +31 -0
  302. package/dist/src/agent-runtime/workflow-runtime.js +34 -0
  303. package/dist/src/agent-runtime/workflow-runtime.js.map +1 -0
  304. package/dist/src/ai-assist/text-assist.js +1 -1
  305. package/dist/src/auth/credentials.js +2 -2
  306. package/dist/src/auth/profiles/store.js +2 -2
  307. package/dist/src/auth/sync-provider-auth.js +1 -1
  308. package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
  309. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  310. package/dist/src/browser/actions/registry.js +5 -8
  311. package/dist/src/browser/actions/registry.js.map +1 -1
  312. package/dist/src/browser/backend-from-config.d.ts +1 -1
  313. package/dist/src/browser/backend-from-config.js +50 -71
  314. package/dist/src/browser/backend-from-config.js.map +1 -1
  315. package/dist/src/browser/browser-command-timeout.d.ts +0 -1
  316. package/dist/src/browser/browser-command-timeout.js +3 -7
  317. package/dist/src/browser/browser-command-timeout.js.map +1 -1
  318. package/dist/src/browser/cache-dir-policy.js +1 -1
  319. package/dist/src/browser/cdp-local-launcher.js +2 -2
  320. package/dist/src/browser/pipeline/source.js +1 -1
  321. package/dist/src/browser/providers/browser-ext-install.d.ts +2 -12
  322. package/dist/src/browser/providers/browser-ext-install.js +7 -12
  323. package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
  324. package/dist/src/browser/providers/cloakbrowser.js +5 -5
  325. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  326. package/dist/src/browser/readiness.js +16 -16
  327. package/dist/src/browser/readiness.js.map +1 -1
  328. package/dist/src/browser/schemas.js +1 -1
  329. package/dist/src/browser/schemas.js.map +1 -1
  330. package/dist/src/browser/stealth.js +1 -1
  331. package/dist/src/channels/catalog/channel-catalog-service.js +1 -1
  332. package/dist/src/channels/outbound/persist-store.js +1 -1
  333. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  334. package/dist/src/channels/pairing/pairing-store.js +2 -2
  335. package/dist/src/chat-commands/agent-edit.js +2 -2
  336. package/dist/src/chat-commands/builtins/config.js +6 -6
  337. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  338. package/dist/src/chat-commands/builtins/thinking.js +16 -42
  339. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  340. package/dist/src/chat-commands/config-paths.js +1 -1
  341. package/dist/src/chat-commands/config-paths.js.map +1 -1
  342. package/dist/src/chat-commands/context.js +3 -4
  343. package/dist/src/chat-commands/context.js.map +1 -1
  344. package/dist/src/cli/command-manifest.js +1 -1
  345. package/dist/src/cli/command-manifest.js.map +1 -1
  346. package/dist/src/cli/commands/agent.js +3 -1
  347. package/dist/src/cli/commands/agent.js.map +1 -1
  348. package/dist/src/cli/commands/agents.js +3 -6
  349. package/dist/src/cli/commands/agents.js.map +1 -1
  350. package/dist/src/cli/commands/browser-cli-helpers.js +9 -11
  351. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  352. package/dist/src/cli/commands/config.js +6 -6
  353. package/dist/src/cli/commands/config.js.map +1 -1
  354. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  355. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  356. package/dist/src/cli/commands/doctor/checks/provider-auth.js +2 -18
  357. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  358. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  359. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  360. package/dist/src/cli/commands/extension-create.js +1 -1
  361. package/dist/src/cli/commands/extension-dev.js +2 -2
  362. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  363. package/dist/src/cli/commands/extension-pack.js +2 -2
  364. package/dist/src/cli/commands/extension.js +3 -3
  365. package/dist/src/cli/commands/gateway/logs.js +1 -1
  366. package/dist/src/cli/commands/goal.js +1 -1
  367. package/dist/src/cli/commands/image.js +13 -372
  368. package/dist/src/cli/commands/image.js.map +1 -1
  369. package/dist/src/cli/commands/init.js +2 -2
  370. package/dist/src/cli/commands/models.js +27 -11
  371. package/dist/src/cli/commands/models.js.map +1 -1
  372. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  373. package/dist/src/cli/commands/onboard/model.js +20 -22
  374. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  375. package/dist/src/cli/commands/onboard.js +1 -1
  376. package/dist/src/cli/commands/onboard.js.map +1 -1
  377. package/dist/src/cli/commands/skills-test.js +1 -1
  378. package/dist/src/cli/templates.js +1 -1
  379. package/dist/src/cli/utils/gateway-client.js +1 -1
  380. package/dist/src/cli/utils/init-workspace-core.d.ts +1 -4
  381. package/dist/src/cli/utils/init-workspace-core.js +9 -8
  382. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  383. package/dist/src/commands/agents.config.d.ts +0 -1
  384. package/dist/src/commands/agents.config.js +66 -12
  385. package/dist/src/commands/agents.config.js.map +1 -1
  386. package/dist/src/config/agent-profile.d.ts +5 -17
  387. package/dist/src/config/agent-profile.js +31 -64
  388. package/dist/src/config/agent-profile.js.map +1 -1
  389. package/dist/src/config/agent-typed-models.d.ts +1 -1
  390. package/dist/src/config/agent-typed-models.js +1 -2
  391. package/dist/src/config/agent-typed-models.js.map +1 -1
  392. package/dist/src/config/gateway-bind.js +1 -1
  393. package/dist/src/config/index.js +8 -8
  394. package/dist/src/config/integration.d.ts +1 -1
  395. package/dist/src/config/loader.js +4 -4
  396. package/dist/src/config/models-json.js +2 -2
  397. package/dist/src/config/paths-state.js +1 -1
  398. package/dist/src/config/paths.js +1 -1
  399. package/dist/src/config/profile.js +1 -1
  400. package/dist/src/config/reload.js +2 -2
  401. package/dist/src/config/reload.js.map +1 -1
  402. package/dist/src/config/rules.js +6 -56
  403. package/dist/src/config/rules.js.map +1 -1
  404. package/dist/src/config/schema.d.ts +918 -781
  405. package/dist/src/config/schema.js +154 -423
  406. package/dist/src/config/schema.js.map +1 -1
  407. package/dist/src/config/workspace-path.js +1 -1
  408. package/dist/src/connectors/composio-triggers.js +1 -1
  409. package/dist/src/cron/executor.js +1 -1
  410. package/dist/src/cron/index.js +1 -1
  411. package/dist/src/cron/service.js +2 -2
  412. package/dist/src/cron/validation.d.ts +3 -3
  413. package/dist/src/daemon/constants.js +1 -1
  414. package/dist/src/daemon/install-plan.js +2 -2
  415. package/dist/src/daemon/launchd.js +2 -2
  416. package/dist/src/daemon/schtasks.js +2 -2
  417. package/dist/src/daemon/systemd.js +2 -2
  418. package/dist/src/extensions/activation-context.js +13 -7
  419. package/dist/src/extensions/activation-context.js.map +1 -1
  420. package/dist/src/extensions/bundle-mcp.js +1 -1
  421. package/dist/src/extensions/discover-extensions.js +2 -2
  422. package/dist/src/extensions/health.js +1 -1
  423. package/dist/src/extensions/install.js +2 -2
  424. package/dist/src/extensions/loader.js +2 -2
  425. package/dist/src/extensions/lockfile.js +3 -3
  426. package/dist/src/extensions/security.js +1 -1
  427. package/dist/src/extensions/update.js +2 -2
  428. package/dist/src/gateway/agents-admin.d.ts +17 -18
  429. package/dist/src/gateway/agents-admin.js +125 -90
  430. package/dist/src/gateway/agents-admin.js.map +1 -1
  431. package/dist/src/gateway/capability-presets-admin.d.ts +56 -0
  432. package/dist/src/gateway/capability-presets-admin.js +214 -0
  433. package/dist/src/gateway/capability-presets-admin.js.map +1 -0
  434. package/dist/src/gateway/file-path-classifier.js +2 -2
  435. package/dist/src/gateway/hono/lib/agent-model.d.ts +1 -1
  436. package/dist/src/gateway/hono/lib/agent-model.js +1 -1
  437. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  438. package/dist/src/gateway/hono/lib/config-payload.d.ts +234 -127
  439. package/dist/src/gateway/hono/lib/config-payload.js +14 -38
  440. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  441. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  442. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  443. package/dist/src/gateway/hono/routes/agents.js +56 -33
  444. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  445. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  446. package/dist/src/gateway/hono/routes/browser.js +8 -15
  447. package/dist/src/gateway/hono/routes/browser.js.map +1 -1
  448. package/dist/src/gateway/hono/routes/capability-presets.d.ts +3 -0
  449. package/dist/src/gateway/hono/routes/capability-presets.js +145 -0
  450. package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -0
  451. package/dist/src/gateway/hono/routes/config-patch/agents.d.ts +1 -17
  452. package/dist/src/gateway/hono/routes/config-patch/agents.js +2 -443
  453. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  454. package/dist/src/gateway/hono/routes/config-patch/misc.js +7 -1
  455. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  456. package/dist/src/gateway/hono/routes/config.js +1 -1
  457. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  458. package/dist/src/gateway/hono/routes/dreaming.js +8 -1
  459. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  460. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  461. package/dist/src/gateway/hono/routes/index.js +2 -0
  462. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  463. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  464. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  465. package/dist/src/gateway/hono/routes/memory.d.ts +3 -0
  466. package/dist/src/gateway/hono/routes/memory.js +290 -0
  467. package/dist/src/gateway/hono/routes/memory.js.map +1 -0
  468. package/dist/src/gateway/hono/routes/models.js +1 -1
  469. package/dist/src/gateway/hono/routes/shares.js +1 -1
  470. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  471. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  472. package/dist/src/gateway/lock.js +3 -3
  473. package/dist/src/gateway/ports.js +1 -1
  474. package/dist/src/gateway/service/config-coordinator.js +1 -1
  475. package/dist/src/gateway/service/marketplace-service.js +2 -2
  476. package/dist/src/gateway/service.d.ts +1 -1
  477. package/dist/src/gateway/service.js +15 -16
  478. package/dist/src/gateway/service.js.map +1 -1
  479. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  480. package/dist/src/goals/goal-workflow-judge.js +2 -2
  481. package/dist/src/i18n/goals-bundle.js +1 -1
  482. package/dist/src/i18n/index.js +1 -1
  483. package/dist/src/i18n/share-tool-bundle.js +2 -2
  484. package/dist/src/infra/brew.js +1 -1
  485. package/dist/src/infra/package-json.js +1 -1
  486. package/dist/src/infra/package-update-steps.js +1 -1
  487. package/dist/src/infra/path-env.js +2 -2
  488. package/dist/src/infra/restart.js +1 -1
  489. package/dist/src/infra/stable-node-path.js +1 -1
  490. package/dist/src/infra/update-check.js +1 -1
  491. package/dist/src/infra/update-global.js +1 -1
  492. package/dist/src/infra/update-lock.js +2 -2
  493. package/dist/src/infra/update-restart.js +1 -1
  494. package/dist/src/infra/update-runner.js +1 -1
  495. package/dist/src/infra/update-startup.js +1 -1
  496. package/dist/src/infra/write-file-atomic.js +2 -2
  497. package/dist/src/media/store.js +1 -1
  498. package/dist/src/notes/agent-context.js +3 -3
  499. package/dist/src/notes/service.js +1 -1
  500. package/dist/src/notes/store.js +2 -2
  501. package/dist/src/project-trust/trust-store.js +2 -2
  502. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  503. package/dist/src/providers/index.d.ts +2 -2
  504. package/dist/src/providers/index.js +11 -15
  505. package/dist/src/providers/index.js.map +1 -1
  506. package/dist/src/providers/model-registry.js +4 -4
  507. package/dist/src/session/index.js +1 -1
  508. package/dist/src/session/init-session-turn.js +1 -1
  509. package/dist/src/session/resolve-session.js +1 -1
  510. package/dist/src/session/session-title.js +2 -2
  511. package/dist/src/session/session-workspace.js +7 -2
  512. package/dist/src/session/session-workspace.js.map +1 -1
  513. package/dist/src/session/store.js +6 -1
  514. package/dist/src/session/store.js.map +1 -1
  515. package/dist/src/session/thinking-resolve.d.ts +1 -1
  516. package/dist/src/session/thinking-resolve.js +1 -1
  517. package/dist/src/session/thinking-resolve.js.map +1 -1
  518. package/dist/src/share/share-auto.js +2 -2
  519. package/dist/src/share/share-store.js +3 -3
  520. package/dist/src/share/share-thumbnail.js +2 -2
  521. package/dist/src/share/share-zip.js +1 -1
  522. package/dist/src/share/site-share-store.js +3 -3
  523. package/dist/src/share/site-static-serve.js +1 -1
  524. package/dist/src/storage/sqlite/connection.js +2 -2
  525. package/dist/src/storage/sqlite/index.d.ts +1 -0
  526. package/dist/src/storage/sqlite/index.js +2 -1
  527. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  528. package/dist/src/storage/sqlite/memory-records-repository.d.ts +101 -0
  529. package/dist/src/storage/sqlite/memory-records-repository.js +309 -0
  530. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -0
  531. package/dist/src/storage/sqlite/migrations/012_memory_records.sql +63 -0
  532. package/dist/src/storage/sqlite/migrations/013_memory_trace_events.sql +21 -0
  533. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  534. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  535. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  536. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  537. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  538. package/dist/src/storage/sqlite/schema.js +2 -2
  539. package/dist/src/storage/sqlite/schema.sql +86 -0
  540. package/dist/src/tui/backends/embedded-backend.js +7 -5
  541. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  542. package/dist/src/tui/clipboard-image.js +3 -3
  543. package/dist/src/tui/extension-host/load-extensions.js +1 -1
  544. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  545. package/dist/src/tui/theme-manager.js +1 -1
  546. package/dist/src/tui/tui-command-formatters.js +4 -4
  547. package/dist/src/tui/tui-commands.js +2 -2
  548. package/dist/src/tui/tui-keybindings-file.js +1 -1
  549. package/dist/src/tui/tui-scoped-models.js +2 -2
  550. package/dist/src/tui/tui-settings.js +1 -1
  551. package/dist/src/tui/tui-startup-resources.js +1 -1
  552. package/dist/src/tui/tui.js +6 -6
  553. package/dist/src/tunnel/frpc-binary.js +4 -4
  554. package/dist/src/tunnel/frpc-config.js +1 -1
  555. package/dist/src/tunnel/frpc-extract.js +1 -1
  556. package/dist/src/tunnel/tunnel-state.js +1 -1
  557. package/dist/src/utils/logger/audit.js +1 -1
  558. package/dist/src/utils/logger/log-store.js +1 -1
  559. package/dist/src/utils/logger/rotation.js +1 -1
  560. package/dist/src/utils/logger/streams.js +1 -1
  561. package/dist/src/voice/tts/audio.js +1 -1
  562. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  563. package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
  564. package/dist/src/workflows/service/workflow-run-service.js +4 -5
  565. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  566. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  567. package/dist/src/workflows/store/event-store.js +1 -1
  568. package/dist/src/workflows/store/run-store.js +1 -1
  569. package/package.json +3 -2
  570. package/dist/gateway/static/root/assets/agent-browser-settings-page-D1SyFYeh.js +0 -6
  571. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-C9YxgvuI.js +0 -1
  572. package/dist/gateway/static/root/assets/agents-CteVs3UO.js +0 -71
  573. package/dist/gateway/static/root/assets/apps-page-CVQ1M8Ax.js +0 -1
  574. package/dist/gateway/static/root/assets/config-api-C4RAtTKW.js +0 -3
  575. package/dist/gateway/static/root/assets/connectors-page-MsMa5qBr.js +0 -2
  576. package/dist/gateway/static/root/assets/cron-api-sJNMqB6P.js +0 -1
  577. package/dist/gateway/static/root/assets/cron-page-D30CSwkn.js +0 -3
  578. package/dist/gateway/static/root/assets/dreaming-settings-6fCUWRQf.js +0 -1
  579. package/dist/gateway/static/root/assets/gateway-config-api-C6989a-W.js +0 -1
  580. package/dist/gateway/static/root/assets/gateway-settings-BpF26t91.js +0 -1
  581. package/dist/gateway/static/root/assets/goal-detail-page-DOjhmRyf.js +0 -1
  582. package/dist/gateway/static/root/assets/goals-page-Xl9_wrFc.js +0 -2
  583. package/dist/gateway/static/root/assets/index-C8ytlAF2.js +0 -122
  584. package/dist/gateway/static/root/assets/index-CVpJW2NS.css +0 -1
  585. package/dist/gateway/static/root/assets/messages-BqzIDrlr.js +0 -3
  586. package/dist/gateway/static/root/assets/models-hub-panel-BO4o-GmO.js +0 -2
  587. package/dist/gateway/static/root/assets/note-detail-page-DLV_XDmT.js +0 -2
  588. package/dist/gateway/static/root/assets/remote-access-hub-DQpnE8K9.js +0 -1
  589. package/dist/gateway/static/root/assets/sessions-page-BZui7iAY.js +0 -1
  590. package/dist/gateway/static/root/assets/settings-advanced-gate-DEfzZ1ax.js +0 -1
  591. package/dist/gateway/static/root/assets/settings-page-CLuSsu1-.js +0 -1
  592. package/dist/gateway/static/root/assets/setup-status-panel-Cq4qpXLi.js +0 -1
  593. package/dist/gateway/static/root/assets/shares-settings-B9F3HyYQ.js +0 -1
  594. package/dist/gateway/static/root/assets/skill-reload-api-Bp9UPPwm.js +0 -1
  595. package/dist/gateway/static/root/assets/skills-page-BIoBsfSV.js +0 -2
  596. package/dist/gateway/static/root/assets/use-agent-defaults-form-Cz2_pPzu.js +0 -1
  597. package/dist/gateway/static/root/assets/use-settings-tab-guard-nuHMmZQv.js +0 -1
  598. package/dist/gateway/static/root/assets/voice-api-key-field-BUIrKb8s.js +0 -1
  599. package/dist/gateway/static/root/assets/workflows-page-qE3SexnO.js +0 -18
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
5
5
  import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
6
6
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
@@ -5,7 +5,7 @@ import { materializeBundleMcpToolsForRun } from "./bundle-mcp-materialize.js";
5
5
  import "./bundle-mcp-tools.js";
6
6
  //#region src/agent/mcp/resolve-embedded-mcp-tools.ts
7
7
  async function resolveEmbeddedMcpToolsForTurn(params) {
8
- const disabledTools = (params.cfg ? resolveEffectiveAgentProfileForSession(params.cfg, params.sessionKey) : void 0)?.tools.disable;
8
+ const disabledTools = (params.cfg ? resolveEffectiveAgentProfileForSession(params.cfg, params.sessionKey) : void 0)?.tools.denied;
9
9
  if (!shouldCreateBundleMcpRuntimeForAttempt({
10
10
  cfg: params.cfg,
11
11
  disabledTools
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-embedded-mcp-tools.js","names":[],"sources":["../../../../src/agent/mcp/resolve-embedded-mcp-tools.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport {\n getOrCreateSessionMcpRuntime,\n materializeBundleMcpToolsForRun,\n} from './bundle-mcp-tools.js';\nimport { shouldCreateBundleMcpRuntimeForAttempt } from './bundle-mcp-policy.js';\nimport type { BundleMcpToolRuntime } from './bundle-mcp-types.js';\n\nexport type ResolvedEmbeddedMcpTools = {\n tools: AgentTool[];\n dispose: () => Promise<void>;\n};\n\nexport async function resolveEmbeddedMcpToolsForTurn(params: {\n sessionKey: string;\n workspaceDir: string;\n cfg?: Config;\n baseTools: AgentTool[];\n cleanupOnTurnEnd?: boolean;\n}): Promise<ResolvedEmbeddedMcpTools> {\n const profile = params.cfg\n ? resolveEffectiveAgentProfileForSession(params.cfg, params.sessionKey)\n : undefined;\n const disabledTools = profile?.tools.disable;\n\n if (\n !shouldCreateBundleMcpRuntimeForAttempt({\n cfg: params.cfg,\n disabledTools,\n })\n ) {\n return { tools: [], dispose: async () => {} };\n }\n\n const reserved = new Set(params.baseTools.map((t) => t.name));\n const runtime = await getOrCreateSessionMcpRuntime({\n sessionId: params.sessionKey,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n\n let materialized: BundleMcpToolRuntime;\n try {\n materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: reserved,\n disposeRuntime: params.cleanupOnTurnEnd\n ? async () => {\n await runtime.dispose();\n }\n : undefined,\n });\n } catch (error) {\n await runtime.dispose().catch(() => {});\n throw error;\n }\n\n const filtered = materialized.tools.filter((tool) => {\n if (disabledTools?.has(tool.name)) {\n return false;\n }\n return true;\n });\n\n return {\n tools: filtered,\n dispose: materialized.dispose,\n };\n}\n\nexport function mergeTurnTools(baseTools: AgentTool[], mcpTools: AgentTool[]): AgentTool[] {\n if (mcpTools.length === 0) {\n return baseTools;\n }\n return [...baseTools, ...mcpTools];\n}\n"],"mappings":";;;;;;AAeA,eAAsB,+BAA+B,QAMf;CAIpC,MAAM,iBAHU,OAAO,MACnB,uCAAuC,OAAO,KAAK,OAAO,WAAW,GACrE,KAAA,IAC2B,MAAM;AAErC,KACE,CAAC,uCAAuC;EACtC,KAAK,OAAO;EACZ;EACD,CAAC,CAEF,QAAO;EAAE,OAAO,EAAE;EAAE,SAAS,YAAY;EAAI;CAG/C,MAAM,WAAW,IAAI,IAAI,OAAO,UAAU,KAAK,MAAM,EAAE,KAAK,CAAC;CAC7D,MAAM,UAAU,MAAM,6BAA6B;EACjD,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,cAAc,OAAO;EACrB,KAAK,OAAO;EACb,CAAC;CAEF,IAAI;AACJ,KAAI;AACF,iBAAe,MAAM,gCAAgC;GACnD;GACA,mBAAmB;GACnB,gBAAgB,OAAO,mBACnB,YAAY;AACV,UAAM,QAAQ,SAAS;OAEzB,KAAA;GACL,CAAC;UACK,OAAO;AACd,QAAM,QAAQ,SAAS,CAAC,YAAY,GAAG;AACvC,QAAM;;AAUR,QAAO;EACL,OARe,aAAa,MAAM,QAAQ,SAAS;AACnD,OAAI,eAAe,IAAI,KAAK,KAAK,CAC/B,QAAO;AAET,UAAO;IAIQ;EACf,SAAS,aAAa;EACvB;;AAGH,SAAgB,eAAe,WAAwB,UAAoC;AACzF,KAAI,SAAS,WAAW,EACtB,QAAO;AAET,QAAO,CAAC,GAAG,WAAW,GAAG,SAAS"}
1
+ {"version":3,"file":"resolve-embedded-mcp-tools.js","names":[],"sources":["../../../../src/agent/mcp/resolve-embedded-mcp-tools.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport {\n getOrCreateSessionMcpRuntime,\n materializeBundleMcpToolsForRun,\n} from './bundle-mcp-tools.js';\nimport { shouldCreateBundleMcpRuntimeForAttempt } from './bundle-mcp-policy.js';\nimport type { BundleMcpToolRuntime } from './bundle-mcp-types.js';\n\nexport type ResolvedEmbeddedMcpTools = {\n tools: AgentTool[];\n dispose: () => Promise<void>;\n};\n\nexport async function resolveEmbeddedMcpToolsForTurn(params: {\n sessionKey: string;\n workspaceDir: string;\n cfg?: Config;\n baseTools: AgentTool[];\n cleanupOnTurnEnd?: boolean;\n}): Promise<ResolvedEmbeddedMcpTools> {\n const profile = params.cfg\n ? resolveEffectiveAgentProfileForSession(params.cfg, params.sessionKey)\n : undefined;\n const disabledTools = profile?.tools.denied;\n\n if (\n !shouldCreateBundleMcpRuntimeForAttempt({\n cfg: params.cfg,\n disabledTools,\n })\n ) {\n return { tools: [], dispose: async () => {} };\n }\n\n const reserved = new Set(params.baseTools.map((t) => t.name));\n const runtime = await getOrCreateSessionMcpRuntime({\n sessionId: params.sessionKey,\n sessionKey: params.sessionKey,\n workspaceDir: params.workspaceDir,\n cfg: params.cfg,\n });\n\n let materialized: BundleMcpToolRuntime;\n try {\n materialized = await materializeBundleMcpToolsForRun({\n runtime,\n reservedToolNames: reserved,\n disposeRuntime: params.cleanupOnTurnEnd\n ? async () => {\n await runtime.dispose();\n }\n : undefined,\n });\n } catch (error) {\n await runtime.dispose().catch(() => {});\n throw error;\n }\n\n const filtered = materialized.tools.filter((tool) => {\n if (disabledTools?.has(tool.name)) {\n return false;\n }\n return true;\n });\n\n return {\n tools: filtered,\n dispose: materialized.dispose,\n };\n}\n\nexport function mergeTurnTools(baseTools: AgentTool[], mcpTools: AgentTool[]): AgentTool[] {\n if (mcpTools.length === 0) {\n return baseTools;\n }\n return [...baseTools, ...mcpTools];\n}\n"],"mappings":";;;;;;AAeA,eAAsB,+BAA+B,QAMf;CAIpC,MAAM,iBAHU,OAAO,MACnB,uCAAuC,OAAO,KAAK,OAAO,WAAW,GACrE,KAAA,IAC2B,MAAM;AAErC,KACE,CAAC,uCAAuC;EACtC,KAAK,OAAO;EACZ;EACD,CAAC,CAEF,QAAO;EAAE,OAAO,EAAE;EAAE,SAAS,YAAY;EAAI;CAG/C,MAAM,WAAW,IAAI,IAAI,OAAO,UAAU,KAAK,MAAM,EAAE,KAAK,CAAC;CAC7D,MAAM,UAAU,MAAM,6BAA6B;EACjD,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,cAAc,OAAO;EACrB,KAAK,OAAO;EACb,CAAC;CAEF,IAAI;AACJ,KAAI;AACF,iBAAe,MAAM,gCAAgC;GACnD;GACA,mBAAmB;GACnB,gBAAgB,OAAO,mBACnB,YAAY;AACV,UAAM,QAAQ,SAAS;OAEzB,KAAA;GACL,CAAC;UACK,OAAO;AACd,QAAM,QAAQ,SAAS,CAAC,YAAY,GAAG;AACvC,QAAM;;AAUR,QAAO;EACL,OARe,aAAa,MAAM,QAAQ,SAAS;AACnD,OAAI,eAAe,IAAI,KAAK,KAAK,CAC/B,QAAO;AAET,UAAO;IAIQ;EACf,SAAS,aAAa;EACvB;;AAGH,SAAgB,eAAe,WAAwB,UAAoC;AACzF,KAAI,SAAS,WAAW,EACtB,QAAO;AAET,QAAO,CAAC,GAAG,WAAW,GAAG,SAAS"}
@@ -23,8 +23,11 @@ export interface CapabilityProviderCandidate {
23
23
  }
24
24
  export interface ResolveCapabilityModelCandidatesParams {
25
25
  cfg?: Config;
26
- /** Active capability model config, e.g. cfg.agents.defaults.imageGenerationModel. */
27
- modelConfig: AgentModelConfig | undefined;
26
+ /** Active capability model config from a manifest/runtime policy. */
27
+ modelConfig: {
28
+ primary?: string;
29
+ fallbacks?: string[];
30
+ } | AgentModelConfig | undefined;
28
31
  /** Caller-supplied per-call override (highest priority). */
29
32
  modelOverride?: string;
30
33
  /** Optional ref parser; defaults to {@link parseCapabilityModelRef}. */
@@ -189,7 +189,7 @@ function throwCapabilityGenerationFailure(params) {
189
189
  });
190
190
  }
191
191
  function buildNoCapabilityModelConfiguredMessage(params) {
192
- const lines = [`No ${params.capabilityLabel} model configured. Set agents.defaults.${params.modelConfigKey} to a "<provider>/<model>" value (or pass modelOverride at call site).`];
192
+ const lines = [`No ${params.capabilityLabel} model configured. Add a manifest/runtime model policy for ${params.modelConfigKey} or pass modelOverride at call site.`];
193
193
  if (params.providers.length > 0) {
194
194
  lines.push("Registered providers:");
195
195
  for (const p of params.providers) {
@@ -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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"}
@@ -14,6 +14,8 @@ export declare class BuiltinMemoryStore {
14
14
  isUserProfileEnabled(): boolean;
15
15
  /** Agent-scoped curated memory directory (`~/.xopc/agents/<id>/memories/`). */
16
16
  get memoriesDir(): string;
17
+ /** Workspace whose MEMORY.md and daily notes participate in local memory search. */
18
+ get workspaceDir(): string;
17
19
  pathFor(target: 'memory' | 'user'): string;
18
20
  /**
19
21
  * Load from disk and freeze {@link getSnapshot}. Sync for agent creation (prefix cache stability).
@@ -1,6 +1,6 @@
1
+ import { 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
  /**
@@ -28,6 +28,10 @@ var BuiltinMemoryStore = class {
28
28
  get memoriesDir() {
29
29
  return this.config.memoriesDir;
30
30
  }
31
+ /** Workspace whose MEMORY.md and daily notes participate in local memory search. */
32
+ get workspaceDir() {
33
+ return this.config.workspaceDir;
34
+ }
31
35
  pathFor(target) {
32
36
  return join(this.memoriesDir, target === "memory" ? "MEMORY.md" : "USER.md");
33
37
  }
@@ -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` + `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 /** 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 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":";;;;;;;;;AAYA,MAAa,yBAAyB;AAEtC,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAE3B,IAAa,qBAAb,MAAgC;CAC9B,gBAAkC,EAAE;CACpC,cAAgC,EAAE;CAClC,WAAmC;EAAE,QAAQ;EAAI,MAAM;EAAI;CAE3D,YAAY,QAA4C;AAA3B,OAAA,SAAA;;;CAG7B,uBAAgC;AAC9B,SAAO,KAAK,OAAO,uBAAuB;;;CAI5C,IAAI,cAAsB;AACxB,SAAO,KAAK,OAAO;;;CAIrB,IAAI,eAAuB;AACzB,SAAO,KAAK,OAAO;;CAGrB,QAAQ,QAAmC;AACzC,SAAO,KAAK,KAAK,aAAa,WAAW,WAAW,cAAc,UAAU;;;;;CAM9E,mBAAyB;AACvB,YAAU,KAAK,aAAa,EAAE,WAAW,MAAM,CAAC;AAChD,OAAK,gBAAgB,KAAK,iBACxB,KAAK,aAAa,KAAK,KAAK,aAAa,YAAY,CAAC,CACvD;AACD,OAAK,cACH,KAAK,OAAO,uBAAuB,QAC/B,EAAE,GACF,KAAK,iBAAiB,KAAK,aAAa,KAAK,KAAK,aAAa,UAAU,CAAC,CAAC;AACjF,OAAK,gBAAgB,oBAAoB,KAAK,cAAc;AAC5D,OAAK,cAAc,oBAAoB,KAAK,YAAY;AACxD,OAAK,WAAW;GACd,QAAQ,KAAK,YAAY,UAAU,KAAK,cAAc;GACtD,MAAM,KAAK,YAAY,QAAQ,KAAK,YAAY;GACjD;;CAGH,aAAqB,MAAsB;AACzC,MAAI;AACF,OAAI,CAAC,WAAW,KAAK,CAAE,QAAO;AAC9B,UAAO,aAAa,MAAM,EAAE,UAAU,SAAS,CAAC;UAC1C;AACN,UAAO;;;CAIX,iBAAyB,KAAuB;AAC9C,MAAI,CAAC,IAAI,MAAM,CAAE,QAAO,EAAE;AAC1B,SAAO,IACJ,MAAM,uBAAuB,CAC7B,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ;;CAGpB,cAA8B;AAC5B,SAAO,KAAK;;;;;CAMd,eAAe,QAAqC;AAClD,SAAO,WAAW,WAAW,CAAC,GAAG,KAAK,cAAc,GAAG,CAAC,GAAG,KAAK,YAAY;;CAG9E,MAAM,IACJ,QACA,SACiE;EACjE,MAAM,UAAU,QAAQ,MAAM;AAC9B,MAAI,CAAC,QACH,QAAO;GAAE,SAAS;GAAO,OAAO;GAA4B;EAE9D,MAAM,YAAY,eAAe,QAAQ;AACzC,MAAI,UACF,QAAO;GAAE,SAAS;GAAO,OAAO;GAAW;AAG7C,SAAO,KAAK,aAAa,QAAQ,YAAY;AAC3C,SAAM,KAAK,qBAAqB,OAAO;GACvC,MAAM,UAAU,WAAW,WAAW,KAAK,gBAAgB,KAAK;GAChE,MAAM,QAAQ,KAAK,UAAU,OAAO;AAEpC,OAAI,QAAQ,SAAS,QAAQ,CAC3B,QAAO;IAAE,SAAS;IAAO,OAAO;IAAwB;AAI1D,OADiB,eAAe,CAAC,GAAG,SAAS,QAAQ,CACzC,GAAG,MACb,QAAO;IACL,SAAS;IACT,OAAO,aAAa,eAAe,QAAQ,CAAC,GAAG,MAAM;IACtD;AAGH,WAAQ,KAAK,QAAQ;AACrB,SAAM,KAAK,kBAAkB,OAAO;AACpC,UAAO;IAAE,SAAS;IAAM,SAAS;IAAgB;IACjD;;CAGJ,MAAM,QACJ,QACA,SACA,YACiE;EACjE,MAAM,KAAK,QAAQ,MAAM;EACzB,MAAM,KAAK,WAAW,MAAM;AAC5B,MAAI,CAAC,GACH,QAAO;GAAE,SAAS;GAAO,OAAO;GAA6B;AAE/D,MAAI,CAAC,GACH,QAAO;GAAE,SAAS;GAAO,OAAO;GAA8D;EAEhG,MAAM,YAAY,eAAe,GAAG;AACpC,MAAI,UACF,QAAO;GAAE,SAAS;GAAO,OAAO;GAAW;AAG7C,SAAO,KAAK,aAAa,QAAQ,YAAY;AAC3C,SAAM,KAAK,qBAAqB,OAAO;GACvC,MAAM,UAAU,WAAW,WAAW,KAAK,gBAAgB,KAAK;GAChE,MAAM,UAAmD,EAAE;AAC3D,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,KAAI,QAAQ,GAAG,SAAS,GAAG,CACzB,SAAQ,KAAK;IAAE,OAAO;IAAG,OAAO,QAAQ;IAAI,CAAC;AAIjD,OAAI,QAAQ,WAAW,EACrB,QAAO;IAAE,SAAS;IAAO,OAAO,qBAAqB,GAAG;IAAK;AAG/D,OAAI,QAAQ,SAAS;QAEf,IADoB,IAAI,QAAQ,KAAK,MAAM,EAAE,MAAM,CACxC,CAAC,OAAO,EAIrB,QAAO;KACL,SAAS;KACT,OAAO,6BAA6B,GAAG,iCALxB,QAAQ,KAAK,MAC5B,EAAE,MAAM,SAAS,KAAK,GAAG,EAAE,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,MAIyB,CAAC,KAAK,MAAM;KAC7F;;GAIL,MAAM,MAAM,QAAQ,GAAG;GACvB,MAAM,QAAQ,KAAK,UAAU,OAAO;GACpC,MAAM,cAAc,CAAC,GAAG,QAAQ;AAChC,eAAY,OAAO;AAEnB,OAAI,eAAe,YAAY,GAAG,MAChC,QAAO;IACL,SAAS;IACT,OAAO,mCAAmC,eAAe,YAAY,CAAC,GAAG,MAAM;IAChF;AAGH,WAAQ,OAAO;AACf,SAAM,KAAK,kBAAkB,OAAO;AACpC,UAAO;IAAE,SAAS;IAAM,SAAS;IAAmB;IACpD;;CAGJ,MAAM,OACJ,QACA,SACiE;EACjE,MAAM,KAAK,QAAQ,MAAM;AACzB,MAAI,CAAC,GACH,QAAO;GAAE,SAAS;GAAO,OAAO;GAA6B;AAG/D,SAAO,KAAK,aAAa,QAAQ,YAAY;AAC3C,SAAM,KAAK,qBAAqB,OAAO;GACvC,MAAM,UAAU,WAAW,WAAW,KAAK,gBAAgB,KAAK;GAChE,MAAM,UAAoB,EAAE;AAC5B,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,KAAI,QAAQ,GAAG,SAAS,GAAG,CACzB,SAAQ,KAAK,EAAE;AAInB,OAAI,QAAQ,WAAW,EACrB,QAAO;IAAE,SAAS;IAAO,OAAO,qBAAqB,GAAG;IAAK;AAG/D,OAAI,QAAQ,SAAS;QAEf,IADoB,IAAI,QAAQ,KAAK,MAAM,QAAQ,GAAG,CAC3C,CAAC,OAAO,EAKrB,QAAO;KACL,SAAS;KACT,OAAO,6BAA6B,GAAG,iCANxB,QAAQ,KAAK,MAAM;MAClC,MAAM,IAAI,QAAQ;AAClB,aAAO,EAAE,SAAS,KAAK,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,OAAO;OAIgC,CAAC,KAAK,MAAM;KAC7F;;AAIL,WAAQ,OAAO,QAAQ,IAAI,EAAE;AAC7B,SAAM,KAAK,kBAAkB,OAAO;AACpC,UAAO;IAAE,SAAS;IAAM,SAAS;IAAkB;IACnD;;CAGJ,MAAc,aACZ,QACA,IACY;EACZ,MAAM,WAAW,KAAK,QAAQ,OAAO;AACrC,QAAM,MAAM,KAAK,aAAa,EAAE,WAAW,MAAM,CAAC;AAClD,MAAI,CAAC,WAAW,SAAS,CACvB,OAAM,UAAU,UAAU,IAAI,QAAQ;AAExC,QAAM,SAAS,KAAK,UAAU;GAAE,SAAS;GAAG,OAAO;GAAQ,CAAC;AAC5D,MAAI;AACF,UAAO,MAAM,IAAI;YACT;AACR,SAAM,SAAS,OAAO,SAAS;;;CAInC,MAAc,qBAAqB,QAA0C;EAC3E,MAAM,OAAO,KAAK,QAAQ,OAAO;EACjC,IAAI,MAAM;AACV,MAAI;AACF,SAAM,MAAM,SAAS,MAAM,QAAQ;UAC7B;AACN,SAAM;;EAER,MAAM,SAAS,oBAAoB,KAAK,iBAAiB,IAAI,CAAC;AAC9D,MAAI,WAAW,SACb,MAAK,gBAAgB;MAErB,MAAK,cAAc;;CAIvB,MAAc,kBAAkB,QAA0C;EACxE,MAAM,UAAU,WAAW,WAAW,KAAK,gBAAgB,KAAK;EAChE,MAAM,WAAW,KAAK,QAAQ,OAAO;EACrC,MAAM,UAAU,QAAQ,KAAK,uBAAuB;EACpD,MAAM,UAAU,GAAG,SAAS,OAAO,KAAK,KAAK;AAC7C,QAAM,UAAU,SAAS,SAAS,QAAQ;AAC1C,QAAM,OAAO,SAAS,SAAS;;CAGjC,UAAkB,QAAmC;AACnD,SAAO,WAAW,WACb,KAAK,OAAO,mBAAmB,uBAC/B,KAAK,OAAO,iBAAiB;;CAGpC,YAAoB,QAA2B,SAA2B;AACxE,MAAI,QAAQ,WAAW,EACrB,QAAO;EAGT,MAAM,QAAQ,KAAK,UAAU,OAAO;EACpC,MAAM,UAAU,QAAQ,KAAK,uBAAuB;EACpD,MAAM,UAAU,QAAQ;EACxB,MAAM,MAAM,KAAK,IAAI,KAAK,KAAK,MAAO,UAAU,QAAS,IAAI,CAAC;EAE9D,MAAM,SACJ,WAAW,SACP,mCAAmC,IAAI,MAAM,QAAQ,gBAAgB,CAAC,GAAG,MAAM,gBAAgB,CAAC,WAChG,iCAAiC,IAAI,MAAM,QAAQ,gBAAgB,CAAC,GAAG,MAAM,gBAAgB,CAAC;EAEpG,MAAM,YAAY,IAAI,OAAO,GAAG;AAChC,SAAO,GAAG,UAAU,IAAI,OAAO,IAAI,UAAU,IAAI;;;AAIrD,SAAS,oBAAoB,SAA6B;CACxD,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,KAAK,SAAS;AACvB,MAAI,KAAK,IAAI,EAAE,CACb;AAEF,OAAK,IAAI,EAAE;AACX,MAAI,KAAK,EAAE;;AAEb,QAAO;;AAGT,SAAS,eAAe,SAA2B;AACjD,KAAI,QAAQ,WAAW,EACrB,QAAO;AAET,QAAO,QAAQ,KAAK,uBAAuB,CAAC;;AAG9C,SAAgB,eAAe,SAAgC;AAwB7D,MAAK,MAAM,EAAE,OAAO,QAAQ;EAtB1B;GAAE,OAAO;GAAuD,IAAI;GAAoB;EACxF;GAAE,OAAO;GAAuB,IAAI;GAAe;EACnD;GAAE,OAAO;GAAiC,IAAI;GAAkB;EAChE;GAAE,OAAO;GAA+B,IAAI;GAAuB;EACnE;GACE,OAAO;GACP,IAAI;GACL;EACD;GACE,OAAO;GACP,IAAI;GACL;EACD;GAAE,OAAO;GAAoE,IAAI;GAAc;EAC/F;GAAE,OAAO;GAAoE,IAAI;GAAc;EAC/F;GACE,OAAO;GACP,IAAI;GACL;EACD;GAAE,OAAO;GAAoB,IAAI;GAAgB;EACjD;GAAE,OAAO;GAA4B,IAAI;GAAc;EAGrB,CAClC,KAAI,MAAM,KAAK,QAAQ,CACrB,QAAO,4CAA4C,GAAG;AAgB1D,MAAK,MAAM,QAAQ;EAXjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAE+B,CAC/B,KAAI,QAAQ,SAAS,KAAK,CAExB,QAAO,2DADM,KAAK,WAAW,EAAE,CAAC,SAAS,GAAG,CAAC,aAAa,CAAC,SAAS,GAAG,IACD,CAAC;AAI3E,QAAO"}
@@ -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,246 @@ 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
+ agentId
65
+ })).map((entry) => {
66
+ const start = entry.lineNumbers[0] ?? 1;
67
+ const end = entry.lineNumbers[entry.lineNumbers.length - 1] ?? start;
68
+ const id = `${entry.file}#L${start}-L${end}`;
69
+ const kind = inferKindFromPath(entry.file);
70
+ return {
71
+ record: upsertMemoryRecord({
72
+ id,
73
+ providerId: this.id,
74
+ kind,
75
+ agentId,
76
+ workspaceId,
77
+ content: entry.lines,
78
+ source: {
79
+ provider: this.id,
80
+ path: entry.file,
81
+ lineStart: start,
82
+ lineEnd: end
83
+ },
84
+ confidence: entry.score
85
+ }),
86
+ score: entry.score,
87
+ snippet: entry.lines,
88
+ citation: {
89
+ providerId: this.id,
90
+ recordId: id,
91
+ path: entry.file,
92
+ lineStart: start,
93
+ lineEnd: end
94
+ }
95
+ };
96
+ });
97
+ }
98
+ async read(request) {
99
+ if (request.id && !request.path) {
100
+ const existing = getMemoryRecord(request.id);
101
+ if (existing) return { record: existing };
102
+ }
103
+ const result = memoryGet(this.workspaceDir, request.path ?? request.id ?? "", request.from, request.lines, this.store.memoriesDir);
104
+ if (!result) return null;
105
+ const path = request.path ?? request.id ?? "";
106
+ return {
107
+ record: upsertMemoryRecord({
108
+ id: `${path}#L${result.lineNumbers.start}-L${result.lineNumbers.end}`,
109
+ providerId: this.id,
110
+ kind: inferKindFromPath(path),
111
+ agentId: request.scope?.agentId ?? this.agentId,
112
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
113
+ content: result.content,
114
+ source: {
115
+ provider: this.id,
116
+ path,
117
+ lineStart: result.lineNumbers.start,
118
+ lineEnd: result.lineNumbers.end
119
+ }
120
+ }),
121
+ lineNumbers: result.lineNumbers
122
+ };
123
+ }
124
+ async get(id) {
125
+ const parsed = parseLineAddress(id);
126
+ return (await this.read({
127
+ path: parsed.path,
128
+ from: parsed.lineStart,
129
+ lines: parsed.lineEnd != null ? parsed.lineEnd - parsed.lineStart + 1 : void 0
130
+ }))?.record ?? null;
131
+ }
132
+ async list(request) {
133
+ const records = listMemoryRecords({
134
+ providerId: this.id,
135
+ agentId: request.scope?.agentId ?? this.agentId,
136
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
137
+ kind: request.kind,
138
+ limit: 200
139
+ });
140
+ if (records.length > 0 || request.kind) return request.target ? records.filter((record) => targetForKind(record.kind) === request.target) : records;
141
+ const target = request.target ?? (request.kind === "user_profile" ? "user" : "memory");
142
+ return this.store.getLiveEntries(target).map((content, index) => upsertMemoryRecord({
143
+ id: `curated:${target}:${index + 1}`,
144
+ providerId: this.id,
145
+ kind: target === "user" ? "user_profile" : "agent_note",
146
+ agentId: request.scope?.agentId ?? this.agentId,
147
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
148
+ content,
149
+ source: {
150
+ provider: this.id,
151
+ path: target === "user" ? "USER.md" : "MEMORY.md"
152
+ }
153
+ }));
154
+ }
155
+ async write(request) {
156
+ const target = request.target ?? (request.kind === "user_profile" ? "user" : "memory");
157
+ const result = await this.store.add(target, request.content);
158
+ if (!result.success) return {
159
+ success: false,
160
+ error: result.error
161
+ };
162
+ return {
163
+ success: true,
164
+ message: result.message,
165
+ record: upsertMemoryRecord({
166
+ id: `curated:${target}:${Date.now()}`,
167
+ providerId: this.id,
168
+ kind: target === "user" ? "user_profile" : request.kind,
169
+ agentId: request.scope?.agentId ?? this.agentId,
170
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
171
+ sessionKey: request.scope?.sessionKey,
172
+ content: request.content,
173
+ source: {
174
+ ...request.source ?? {},
175
+ provider: this.id,
176
+ path: target === "user" ? "USER.md" : "MEMORY.md"
177
+ },
178
+ tags: request.tags
179
+ })
180
+ };
181
+ }
182
+ async update(request) {
183
+ const target = request.target ?? "memory";
184
+ const result = await this.store.replace(target, request.matchText ?? request.id ?? "", request.content);
185
+ if (!result.success) return {
186
+ success: false,
187
+ error: result.error
188
+ };
189
+ if (request.id) {
190
+ const existing = getMemoryRecord(request.id);
191
+ upsertMemoryRecord({
192
+ id: request.id,
193
+ providerId: this.id,
194
+ kind: existing?.kind ?? (target === "user" ? "user_profile" : "agent_note"),
195
+ agentId: existing?.scope.agentId ?? request.scope?.agentId ?? this.agentId,
196
+ workspaceId: existing?.scope.workspaceId ?? request.scope?.workspaceId ?? this.workspaceDir,
197
+ sessionKey: existing?.scope.sessionKey ?? request.scope?.sessionKey,
198
+ content: request.content,
199
+ source: existing?.source ?? {
200
+ provider: this.id,
201
+ path: target === "user" ? "USER.md" : "MEMORY.md"
202
+ },
203
+ tags: existing?.tags
204
+ });
205
+ } else if (request.matchText) for (const existing of listMemoryRecords({
206
+ providerId: this.id,
207
+ agentId: request.scope?.agentId ?? this.agentId,
208
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
209
+ kind: target === "user" ? "user_profile" : "agent_note",
210
+ limit: 200
211
+ })) {
212
+ if (!existing.content.includes(request.matchText)) continue;
213
+ upsertMemoryRecord({
214
+ id: existing.id,
215
+ providerId: this.id,
216
+ kind: existing.kind,
217
+ agentId: existing.scope.agentId,
218
+ workspaceId: existing.scope.workspaceId,
219
+ sessionKey: existing.scope.sessionKey,
220
+ content: request.content,
221
+ source: existing.source,
222
+ tags: existing.tags
223
+ });
224
+ }
225
+ return {
226
+ success: true,
227
+ message: result.message
228
+ };
229
+ }
230
+ async delete(request) {
231
+ const target = request.target ?? "memory";
232
+ const result = await this.store.remove(target, request.matchText ?? request.id ?? "");
233
+ if (!result.success) return {
234
+ success: false,
235
+ error: result.error
236
+ };
237
+ if (request.id) deleteMemoryRecord(request.id);
238
+ else if (request.matchText) {
239
+ for (const existing of listMemoryRecords({
240
+ providerId: this.id,
241
+ agentId: request.scope?.agentId ?? this.agentId,
242
+ workspaceId: request.scope?.workspaceId ?? this.workspaceDir,
243
+ kind: target === "user" ? "user_profile" : "agent_note",
244
+ limit: 200
245
+ })) if (existing.content.includes(request.matchText)) deleteMemoryRecord(existing.id);
246
+ }
247
+ return {
248
+ success: true,
249
+ message: result.message
250
+ };
251
+ }
252
+ sync(event) {
253
+ if (event.type !== "signal") return;
254
+ appendMemorySignal({
255
+ signal: event.signal,
256
+ providerId: this.id,
257
+ agentId: this.agentId,
258
+ workspaceId: this.workspaceDir,
259
+ sessionKey: typeof event.signal.metadata?.sessionKey === "string" ? event.signal.metadata.sessionKey : void 0
260
+ });
31
261
  }
32
262
  async shutdown() {}
33
263
  };
264
+ function inferKindFromPath(path) {
265
+ if (path.endsWith("USER.md")) return "user_profile";
266
+ if (path.endsWith("MEMORY.md")) return "agent_note";
267
+ if (/^memory\/\d{4}-\d{2}-\d{2}\.md$/.test(path)) return "daily_note";
268
+ return "workspace_fact";
269
+ }
270
+ function targetForKind(kind) {
271
+ return kind === "user_profile" ? "user" : "memory";
272
+ }
273
+ function parseLineAddress(id) {
274
+ const match = /^(.*)#L(\d+)(?:-L(\d+))?$/.exec(id);
275
+ if (!match) return { path: id };
276
+ const lineStart = Number.parseInt(match[2] ?? "1", 10);
277
+ const lineEnd = Number.parseInt(match[3] ?? match[2] ?? "1", 10);
278
+ return {
279
+ path: match[1] ?? id,
280
+ lineStart: Number.isFinite(lineStart) ? lineStart : void 0,
281
+ lineEnd: Number.isFinite(lineEnd) ? lineEnd : void 0
282
+ };
283
+ }
34
284
  //#endregion
35
285
  export { BuiltinMemoryProvider };
36
286