@xopcai/xopc 0.0.145 → 0.0.147

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 (380) hide show
  1. package/README.md +2 -2
  2. package/dist/browser-ext/manifest.json +1 -1
  3. package/dist/extensions/demo-memory/src/index.js +6 -4
  4. package/dist/extensions/demo-memory/src/index.js.map +1 -1
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/Combination-14nmIgxH.js +41 -0
  7. package/dist/gateway/static/root/assets/activity-store-DXeSSlw1.js +1 -0
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BEUxdhZx.js → agent-avatar-dicebear-CFdJKSjY.js} +1 -1
  9. package/dist/gateway/static/root/assets/agents-DKjbRpbA.js +2 -0
  10. package/dist/gateway/static/root/assets/api-Bs69B5zA.js +1 -0
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-CRHSZJWi.js → app-management-settings-panel-ag1ViXT_.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-BunADYJb.js → appearance-settings-C6iMpwOM.js} +1 -1
  13. package/dist/gateway/static/root/assets/apps-page-CpX3lBFF.js +1 -0
  14. package/dist/gateway/static/root/assets/{archive-plugin-B6vTkH2A.js → archive-plugin-Dwi3mIBy.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-BjZXzaNv.js → attachment-load-BaCDoq40.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automation-suggestion-card-ZDA-Stg1.js → automation-suggestion-card-CwqtFgnw.js} +1 -1
  17. package/dist/gateway/static/root/assets/automations-page-DlupOxFQ.js +6 -0
  18. package/dist/gateway/static/root/assets/{binary-plugins-DYZfLvPz.js → binary-plugins-DoAYhsxa.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-C3MUlYC9.js → block-editor-Bw72pO7S.js} +31 -31
  20. package/dist/gateway/static/root/assets/browser-settings-page-BwLoUBcZ.js +8 -0
  21. package/dist/gateway/static/root/assets/capability-presets-api-vdbAR65Q.js +1 -0
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BAsKbJgm.js +2 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-fTlTnWB4.js → channel-recipient-api-rTG26jpV.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-CxFWy0cE.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-OKlqTtKJ.js +1 -0
  26. package/dist/gateway/static/root/assets/{connector-logo-BVFNT2zW.js → connector-logo-DIMP4NWY.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-BjQQwX62.js +2 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-_jUmoXd3.js → desktop-pet-kQq2e0BN.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-DwGOy4AQ.js → desktop-pet-settings-B6vtozMY.js} +1 -1
  30. package/dist/gateway/static/root/assets/{directory-picker-path-field-akvF0F-u.js → directory-picker-path-field-Dn5-e3v4.js} +1 -1
  31. package/dist/gateway/static/root/assets/dist-C230izr8.js +1 -0
  32. package/dist/gateway/static/root/assets/dist-CxGUk8J-.js +1 -0
  33. package/dist/gateway/static/root/assets/dreaming-settings-BzwIujPG.js +3 -0
  34. package/dist/gateway/static/root/assets/extension-debug-page-D_e_hsEy.js +1 -0
  35. package/dist/gateway/static/root/assets/{extension-page-CwWktRNz.js → extension-page-D15CWHBd.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-CuggWOIl.js → extension-settings-page-D4P0n1om.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-api-B7sxIbza.js → gateway-config-api-B4qZctjG.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-DIv0eKMf.js → gateway-settings-BvndV7TP.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-DtoLihQE.js → gateway-startup-retry-BpgMunEb.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goal-create-dialog-C4Kw0mfS.js → goal-create-dialog-DrVHKXHq.js} +1 -1
  41. package/dist/gateway/static/root/assets/goal-detail-page-PHlCwv68.js +4 -0
  42. package/dist/gateway/static/root/assets/{goals-config-api-B0jm5JaA.js → goals-config-api-B6YJB_ct.js} +1 -1
  43. package/dist/gateway/static/root/assets/goals-page-Hg9uyO6e.js +2 -0
  44. package/dist/gateway/static/root/assets/{goals-settings-N5_iL7es.js → goals-settings-BROWCIcL.js} +1 -1
  45. package/dist/gateway/static/root/assets/{heartbeat-settings-XzH3lbRR.js → heartbeat-settings-CoCwIOIg.js} +1 -1
  46. package/dist/gateway/static/root/assets/index-CxkNzw3e.js +259 -0
  47. package/dist/gateway/static/root/assets/index-DjCSOyaN.css +1 -0
  48. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Bm_AIYQ7.js +1 -0
  49. package/dist/gateway/static/root/assets/local-app-workbench-page-BJWFcxwG.js +2 -0
  50. package/dist/gateway/static/root/assets/local-apps-page-BsiZMrEf.js +1 -0
  51. package/dist/gateway/static/root/assets/{locale-store-CiM-D9jA.js → locale-store-Bp8joZck.js} +1 -1
  52. package/dist/gateway/static/root/assets/logs-page-DOmK61ey.js +7 -0
  53. package/dist/gateway/static/root/assets/{markdown-split-5rJx5flj.js → markdown-split-Dy7QpaAz.js} +1 -1
  54. package/dist/gateway/static/root/assets/{media-plugins-DYXccwAd.js → media-plugins-3Lxliy9D.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-CQGpD-dC.js +5 -0
  56. package/dist/gateway/static/root/assets/models-hub-panel-DGCZom4o.js +2 -0
  57. package/dist/gateway/static/root/assets/{notes-page-BgLyndCO.js → notes-page-BJtT4vSf.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-B_bN7cOR.js +4 -0
  59. package/dist/gateway/static/root/assets/{page-tabs-6Al9_sGz.js → page-tabs-DKB6RDre.js} +1 -1
  60. package/dist/gateway/static/root/assets/{preview-open-alternatives-Cm3G72Hv.js → preview-open-alternatives-Br_YhYHp.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-Dq8JouJj.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-DvfL7fSe.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-DqwMXSXP.js +1 -0
  64. package/dist/gateway/static/root/assets/{save-bar-controls-BYtfzu_F.js → save-bar-controls-BgIE9BBh.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schedule-field-CvIRc6yK.js → schedule-field-BXDP-oMz.js} +1 -1
  66. package/dist/gateway/static/root/assets/{schema-form-CQuKx0n7.js → schema-form-Dhv-SmjG.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-B_mOZkQk.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-BHGmH6YS.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-collapsible-section-CF3HHM-t.js → settings-collapsible-section-CUTExnlK.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-form-section-CwWjoRN6.js → settings-form-section-CmnDhsf0.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-loading-skeleton-aUFmJa13.js → settings-loading-skeleton-B79dq-XY.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-B2UUU9TF.js → settings-page-Db8uAv3X.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-page-layout-DqpbTWqI.js → settings-page-layout-DaFwstQw.js} +1 -1
  74. package/dist/gateway/static/root/assets/setup-status-panel-BUSEj0KK.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-BOhlPsS1.js → share-preview-page-Bi00uXzV.js} +1 -1
  76. package/dist/gateway/static/root/assets/shares-settings-DzsTYfuX.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-DSsdU081.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-DeB1tQZL.js +2 -0
  79. package/dist/gateway/static/root/assets/{system-settings-panel-CWxSvuwD.js → system-settings-panel-Cxaph7hW.js} +1 -1
  80. package/dist/gateway/static/root/assets/{theme-store-C9Dxcppm.js → theme-store-eCTN1RpG.js} +1 -1
  81. package/dist/gateway/static/root/assets/{typed-models-lib-qROAvqTw.js → typed-models-lib-CcZ_tyFY.js} +1 -1
  82. package/dist/gateway/static/root/assets/{use-channel-catalog-DE9cpn4G.js → use-channel-catalog-C4PWbNoi.js} +1 -1
  83. package/dist/gateway/static/root/assets/user-context-page-QTVMx_hG.js +1 -0
  84. package/dist/gateway/static/root/assets/{user-profile-fields-editor-CWxc0ghP.js → user-profile-fields-editor-CPOO9Jz5.js} +1 -1
  85. package/dist/gateway/static/root/assets/{user-profile-settings-panel-DW-Up6vt.js → user-profile-settings-panel-C8cgtSF7.js} +1 -1
  86. package/dist/gateway/static/root/assets/{utils-D53uRXVr.js → utils-CiZK2KwH.js} +1 -1
  87. package/dist/gateway/static/root/assets/voice-api-key-field-b-YZtvUu.js +1 -0
  88. package/dist/gateway/static/root/assets/work-discovery-page-4zVDOl2G.js +1 -0
  89. package/dist/gateway/static/root/assets/work-item-detail-page-CHe2tfkc.js +1 -0
  90. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D_x9ELJp.js → workflow-run-setup-panel-8SLCYeXE.js} +2 -2
  91. package/dist/gateway/static/root/assets/workflows-page-DEOFqiWn.js +11 -0
  92. package/dist/gateway/static/root/index.html +10 -9
  93. package/dist/package.js +1 -1
  94. package/dist/src/activity/types.d.ts +1 -1
  95. package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
  96. package/dist/src/agent/agent-manager.d.ts +1 -1
  97. package/dist/src/agent/agent-manager.js +5 -4
  98. package/dist/src/agent/agent-manager.js.map +1 -1
  99. package/dist/src/agent/background-review/coordinator.js +0 -1
  100. package/dist/src/agent/background-review/coordinator.js.map +1 -1
  101. package/dist/src/agent/background-review/settings.d.ts +1 -1
  102. package/dist/src/agent/background-review/settings.js +10 -17
  103. package/dist/src/agent/background-review/settings.js.map +1 -1
  104. package/dist/src/agent/bootstrap/filter-bootstrap-files.d.ts +1 -1
  105. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  106. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  107. package/dist/src/agent/bootstrap/load-bootstrap-files.js +2 -3
  108. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  109. package/dist/src/agent/code-intelligence/binary.js +1 -1
  110. package/dist/src/agent/context/project-context.d.ts +14 -0
  111. package/dist/src/agent/context/project-context.js +23 -1
  112. package/dist/src/agent/context/project-context.js.map +1 -1
  113. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  114. package/dist/src/agent/context/workspace.d.ts +1 -2
  115. package/dist/src/agent/context/workspace.js +2 -4
  116. package/dist/src/agent/context/workspace.js.map +1 -1
  117. package/dist/src/agent/embedded/run-for-session.js +1 -2
  118. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  119. package/dist/src/agent/embedded/run-turn.js +6 -1
  120. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  121. package/dist/src/agent/embedded/types.d.ts +17 -0
  122. package/dist/src/agent/memory/builtin-memory-store.d.ts +2 -2
  123. package/dist/src/agent/memory/builtin-memory-store.js +2 -2
  124. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  125. package/dist/src/agent/memory/builtin-provider.d.ts +1 -3
  126. package/dist/src/agent/memory/builtin-provider.js +21 -48
  127. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  128. package/dist/src/agent/memory/context/planner.js +48 -9
  129. package/dist/src/agent/memory/context/planner.js.map +1 -1
  130. package/dist/src/agent/memory/context/types.d.ts +7 -1
  131. package/dist/src/agent/memory/context-fence.js +1 -1
  132. package/dist/src/agent/memory/context-fence.js.map +1 -1
  133. package/dist/src/agent/memory/create-memory-manager.js +2 -9
  134. package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
  135. package/dist/src/agent/memory/dreaming/config.js +5 -10
  136. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  137. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +2 -2
  138. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js.map +1 -1
  139. package/dist/src/agent/memory/dreaming/scope.d.ts +2 -3
  140. package/dist/src/agent/memory/dreaming/scope.js +8 -8
  141. package/dist/src/agent/memory/dreaming/scope.js.map +1 -1
  142. package/dist/src/agent/memory/manager.d.ts +1 -5
  143. package/dist/src/agent/memory/manager.js +2 -23
  144. package/dist/src/agent/memory/manager.js.map +1 -1
  145. package/dist/src/agent/memory/memory-config.d.ts +3 -3
  146. package/dist/src/agent/memory/memory-config.js +9 -14
  147. package/dist/src/agent/memory/memory-config.js.map +1 -1
  148. package/dist/src/agent/memory/types.d.ts +9 -5
  149. package/dist/src/agent/memory/understanding/service.js +21 -8
  150. package/dist/src/agent/memory/understanding/service.js.map +1 -1
  151. package/dist/src/agent/memory/understanding/types.d.ts +5 -0
  152. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -1
  153. package/dist/src/agent/memory/user-context-coordinator.js +6 -2
  154. package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
  155. package/dist/src/agent/orchestration/agent-orchestrator.js +2 -2
  156. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  157. package/dist/src/agent/prompt/memory/index.d.ts +1 -2
  158. package/dist/src/agent/prompt/memory/index.js +6 -7
  159. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  160. package/dist/src/agent/prompt/sections/tooling.js +1 -1
  161. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  162. package/dist/src/agent/service/direct-turn-helpers.js +13 -2
  163. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  164. package/dist/src/agent/tools/curated-memory-tool.js +4 -4
  165. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  166. package/dist/src/agent/tools/factory.d.ts +1 -1
  167. package/dist/src/agent/tools/factory.js +2 -2
  168. package/dist/src/agent/tools/factory.js.map +1 -1
  169. package/dist/src/agent/tools/memory-tool.js +1 -1
  170. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  171. package/dist/src/agent/workflow/workflow-child-tools.js +2 -3
  172. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
  173. package/dist/src/agent/workspace-runtime/registry.d.ts +5 -5
  174. package/dist/src/agent/workspace-runtime/registry.js +6 -11
  175. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  176. package/dist/src/agent-manifest/index.js +2 -2
  177. package/dist/src/agent-manifest/prompt.js +1 -7
  178. package/dist/src/agent-manifest/prompt.js.map +1 -1
  179. package/dist/src/agent-manifest/schema.d.ts +0 -598
  180. package/dist/src/agent-manifest/schema.js +2 -143
  181. package/dist/src/agent-manifest/schema.js.map +1 -1
  182. package/dist/src/agent-manifest/validator.js +0 -12
  183. package/dist/src/agent-manifest/validator.js.map +1 -1
  184. package/dist/src/agent-runtime/index.js +1 -1
  185. package/dist/src/agent-runtime/memory-runtime.d.ts +2 -2
  186. package/dist/src/agent-runtime/memory-runtime.js +8 -7
  187. package/dist/src/agent-runtime/memory-runtime.js.map +1 -1
  188. package/dist/src/agent-runtime/runtime-profile.d.ts +2 -0
  189. package/dist/src/agent-runtime/runtime-profile.js +2 -2
  190. package/dist/src/agent-runtime/runtime-profile.js.map +1 -1
  191. package/dist/src/chat-commands/agent-edit.js +1 -2
  192. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  193. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  194. package/dist/src/cli/commands/init.js +0 -22
  195. package/dist/src/cli/commands/init.js.map +1 -1
  196. package/dist/src/cli/templates.d.ts +1 -1
  197. package/dist/src/cli/templates.js +1 -16
  198. package/dist/src/cli/templates.js.map +1 -1
  199. package/dist/src/commands/agents.config.js +0 -10
  200. package/dist/src/commands/agents.config.js.map +1 -1
  201. package/dist/src/config/agent-profile.js +1 -1
  202. package/dist/src/config/index.js +2 -2
  203. package/dist/src/config/paths.d.ts +0 -1
  204. package/dist/src/config/paths.js +1 -2
  205. package/dist/src/config/paths.js.map +1 -1
  206. package/dist/src/config/schema.d.ts +118 -532
  207. package/dist/src/config/schema.js +32 -26
  208. package/dist/src/config/schema.js.map +1 -1
  209. package/dist/src/extensions/loader.js +2 -1
  210. package/dist/src/extensions/loader.js.map +1 -1
  211. package/dist/src/gateway/agents-admin.d.ts +0 -2
  212. package/dist/src/gateway/agents-admin.js +1 -7
  213. package/dist/src/gateway/agents-admin.js.map +1 -1
  214. package/dist/src/gateway/capability-presets-admin.d.ts +0 -2
  215. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  216. package/dist/src/gateway/chat-stream/mapper.js +26 -0
  217. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  218. package/dist/src/gateway/chat-stream/protocol.d.ts +16 -1
  219. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +0 -1
  220. package/dist/src/gateway/dreaming-automation-reconciler.js +41 -63
  221. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
  222. package/dist/src/gateway/heartbeat/service.js +1 -1
  223. package/dist/src/gateway/hono/app.js +3 -1
  224. package/dist/src/gateway/hono/app.js.map +1 -1
  225. package/dist/src/gateway/hono/lib/config-payload.d.ts +0 -130
  226. package/dist/src/gateway/hono/lib/config-payload.js +0 -1
  227. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  228. package/dist/src/gateway/hono/routes/agents.js +6 -12
  229. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  230. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +6 -0
  231. package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
  232. package/dist/src/gateway/hono/routes/capability-presets.js +2 -2
  233. package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
  234. package/dist/src/gateway/hono/routes/dreaming.js +9 -20
  235. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  236. package/dist/src/gateway/hono/routes/index.js +4 -0
  237. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  238. package/dist/src/gateway/hono/routes/local-apps.d.ts +5 -0
  239. package/dist/src/gateway/hono/routes/local-apps.js +99 -0
  240. package/dist/src/gateway/hono/routes/local-apps.js.map +1 -0
  241. package/dist/src/gateway/hono/routes/memory.js +48 -65
  242. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/projects.js +2 -2
  244. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  245. package/dist/src/gateway/hono/routes/work-discovery.d.ts +3 -0
  246. package/dist/src/gateway/hono/routes/work-discovery.js +150 -0
  247. package/dist/src/gateway/hono/routes/work-discovery.js.map +1 -0
  248. package/dist/src/gateway/hono/routes/you.d.ts +3 -0
  249. package/dist/src/gateway/hono/routes/you.js +358 -91
  250. package/dist/src/gateway/hono/routes/you.js.map +1 -1
  251. package/dist/src/gateway/service.d.ts +3 -0
  252. package/dist/src/gateway/service.js +12 -0
  253. package/dist/src/gateway/service.js.map +1 -1
  254. package/dist/src/heartbeat/index.js +1 -1
  255. package/dist/src/knowledge/connected-knowledge-pipeline.js +9 -5
  256. package/dist/src/knowledge/connected-knowledge-pipeline.js.map +1 -1
  257. package/dist/src/local-apps/acceptance.d.ts +30 -0
  258. package/dist/src/local-apps/acceptance.js +93 -0
  259. package/dist/src/local-apps/acceptance.js.map +1 -0
  260. package/dist/src/local-apps/index.d.ts +5 -0
  261. package/dist/src/local-apps/index.js +4 -0
  262. package/dist/src/local-apps/preview-runtime-bridge.d.ts +4 -0
  263. package/dist/src/local-apps/preview-runtime-bridge.js +171 -0
  264. package/dist/src/local-apps/preview-runtime-bridge.js.map +1 -0
  265. package/dist/src/local-apps/runtime-entry.d.ts +8 -0
  266. package/dist/src/local-apps/runtime-entry.js +25 -0
  267. package/dist/src/local-apps/runtime-entry.js.map +1 -0
  268. package/dist/src/local-apps/scaffold.d.ts +8 -0
  269. package/dist/src/local-apps/scaffold.js +122 -0
  270. package/dist/src/local-apps/scaffold.js.map +1 -0
  271. package/dist/src/local-apps/service.d.ts +37 -0
  272. package/dist/src/local-apps/service.js +553 -0
  273. package/dist/src/local-apps/service.js.map +1 -0
  274. package/dist/src/local-apps/store.d.ts +44 -0
  275. package/dist/src/local-apps/store.js +195 -0
  276. package/dist/src/local-apps/store.js.map +1 -0
  277. package/dist/src/local-apps/types.d.ts +105 -0
  278. package/dist/src/local-apps/types.js +1 -0
  279. package/dist/src/storage/sqlite/index.d.ts +3 -2
  280. package/dist/src/storage/sqlite/index.js +4 -3
  281. package/dist/src/storage/sqlite/memory-index-repository.d.ts +2 -3
  282. package/dist/src/storage/sqlite/memory-index-repository.js +16 -20
  283. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  284. package/dist/src/storage/sqlite/memory-records-repository.d.ts +18 -10
  285. package/dist/src/storage/sqlite/memory-records-repository.js +79 -34
  286. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  287. package/dist/src/storage/sqlite/memory-reference-consent-repository.d.ts +27 -0
  288. package/dist/src/storage/sqlite/memory-reference-consent-repository.js +109 -0
  289. package/dist/src/storage/sqlite/memory-reference-consent-repository.js.map +1 -0
  290. package/dist/src/storage/sqlite/migrations/038_user_owned_memory.sql +68 -0
  291. package/dist/src/storage/sqlite/migrations/039_memory_reference_consents.sql +19 -0
  292. package/dist/src/storage/sqlite/migrations/040_local_apps.sql +32 -0
  293. package/dist/src/storage/sqlite/migrations/041_local_app_release_lifecycle.sql +17 -0
  294. package/dist/src/storage/sqlite/migrations/042_work_discovery.sql +41 -0
  295. package/dist/src/storage/sqlite/migrations/043_local_app_acceptance_runs.sql +16 -0
  296. package/dist/src/storage/sqlite/migrations/044_repair_work_discovery_foreign_keys.sql +75 -0
  297. package/dist/src/storage/sqlite/migrations/045_extension_ui_grants.sql +13 -0
  298. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  299. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  300. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  301. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  302. package/dist/src/storage/sqlite/schema.js +1 -1
  303. package/dist/src/storage/sqlite/schema.sql +20 -0
  304. package/dist/src/user-context/config.d.ts +227 -0
  305. package/dist/src/user-context/config.js +158 -0
  306. package/dist/src/user-context/config.js.map +1 -0
  307. package/dist/src/user-context/import.d.ts +1 -1
  308. package/dist/src/user-context/import.js +6 -1
  309. package/dist/src/user-context/import.js.map +1 -1
  310. package/dist/src/user-context/owner.d.ts +5 -0
  311. package/dist/src/user-context/owner.js +9 -0
  312. package/dist/src/user-context/owner.js.map +1 -0
  313. package/dist/src/user-context/projection.d.ts +11 -9
  314. package/dist/src/user-context/projection.js +74 -47
  315. package/dist/src/user-context/projection.js.map +1 -1
  316. package/dist/src/user-context/runtime.d.ts +13 -0
  317. package/dist/src/user-context/runtime.js +36 -0
  318. package/dist/src/user-context/runtime.js.map +1 -0
  319. package/dist/src/work-discovery/analyzer.d.ts +11 -0
  320. package/dist/src/work-discovery/analyzer.js +171 -0
  321. package/dist/src/work-discovery/analyzer.js.map +1 -0
  322. package/dist/src/work-discovery/index.d.ts +5 -0
  323. package/dist/src/work-discovery/index.js +5 -0
  324. package/dist/src/work-discovery/probe.d.ts +12 -0
  325. package/dist/src/work-discovery/probe.js +335 -0
  326. package/dist/src/work-discovery/probe.js.map +1 -0
  327. package/dist/src/work-discovery/repository.d.ts +11 -0
  328. package/dist/src/work-discovery/repository.js +100 -0
  329. package/dist/src/work-discovery/repository.js.map +1 -0
  330. package/dist/src/work-discovery/service.d.ts +30 -0
  331. package/dist/src/work-discovery/service.js +387 -0
  332. package/dist/src/work-discovery/service.js.map +1 -0
  333. package/dist/src/work-discovery/types.d.ts +114 -0
  334. package/dist/src/work-discovery/types.js +1 -0
  335. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  336. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  337. package/package.json +5 -3
  338. package/skills/engineering/build-xopc-local-app/SKILL.md +45 -0
  339. package/skills/engineering/build-xopc-local-app/references/app-contract.md +33 -0
  340. package/skills/engineering/build-xopc-local-app/scripts/validate-local-app.mjs +72 -0
  341. package/dist/gateway/static/root/assets/Combination-DolwnuKi.js +0 -41
  342. package/dist/gateway/static/root/assets/activity-center-store-3l9ahUqb.js +0 -1
  343. package/dist/gateway/static/root/assets/agents-1bpT0xRO.js +0 -2
  344. package/dist/gateway/static/root/assets/apps-page-Cc4JgVUQ.js +0 -1
  345. package/dist/gateway/static/root/assets/automations-page-mb0fdVpq.js +0 -6
  346. package/dist/gateway/static/root/assets/browser-settings-page-Bb0xhaMN.js +0 -8
  347. package/dist/gateway/static/root/assets/capability-presets-api-BV76yN9a.js +0 -1
  348. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUcGKZqC.js +0 -2
  349. package/dist/gateway/static/root/assets/channels-settings-BlSDMGdy.js +0 -1
  350. package/dist/gateway/static/root/assets/channels-status-swr-CJauF1CW.js +0 -1
  351. package/dist/gateway/static/root/assets/connectors-page-CMgAFGvb.js +0 -2
  352. package/dist/gateway/static/root/assets/dist-C99RGfAH.js +0 -1
  353. package/dist/gateway/static/root/assets/dreaming-settings-BLetQiYY.js +0 -3
  354. package/dist/gateway/static/root/assets/extension-debug-page-Cof2ncxE.js +0 -1
  355. package/dist/gateway/static/root/assets/goal-detail-page-BMmzYpZL.js +0 -4
  356. package/dist/gateway/static/root/assets/goals-page-CGeT77PC.js +0 -2
  357. package/dist/gateway/static/root/assets/index-CSLF84-Q.css +0 -1
  358. package/dist/gateway/static/root/assets/index-I-ZCenVw.js +0 -259
  359. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-x_v0nrIi.js +0 -1
  360. package/dist/gateway/static/root/assets/logs-page-BSh1t8cD.js +0 -7
  361. package/dist/gateway/static/root/assets/messages-Cb1VMeqP.js +0 -5
  362. package/dist/gateway/static/root/assets/models-hub-panel-BNpTenAI.js +0 -2
  363. package/dist/gateway/static/root/assets/notes-workbench-teklkhcE.js +0 -4
  364. package/dist/gateway/static/root/assets/project-detail-page-CCB_dKoh.js +0 -1
  365. package/dist/gateway/static/root/assets/projects-page-VOAFAHYj.js +0 -1
  366. package/dist/gateway/static/root/assets/remote-access-hub-USYu64Ru.js +0 -1
  367. package/dist/gateway/static/root/assets/sessions-page-oGC8O5h_.js +0 -1
  368. package/dist/gateway/static/root/assets/settings-advanced-gate-D4rP66R1.js +0 -1
  369. package/dist/gateway/static/root/assets/setup-status-panel-Ck9keROI.js +0 -1
  370. package/dist/gateway/static/root/assets/shares-settings-BYLsCuqj.js +0 -1
  371. package/dist/gateway/static/root/assets/skill-reload-api-BNHUyVML.js +0 -1
  372. package/dist/gateway/static/root/assets/skills-page-CpXbQH4n.js +0 -2
  373. package/dist/gateway/static/root/assets/user-context-page-DbNEK4Yp.js +0 -1
  374. package/dist/gateway/static/root/assets/voice-api-key-field-Cs7MOrg0.js +0 -1
  375. package/dist/gateway/static/root/assets/work-item-detail-page-D1ziG1Pp.js +0 -1
  376. package/dist/gateway/static/root/assets/workflows-page-DHGV_n6i.js +0 -11
  377. package/dist/src/agent/context/workspace-templates/MEMORY.md +0 -33
  378. package/dist/src/agent/memory/access-policy.d.ts +0 -12
  379. package/dist/src/agent/memory/access-policy.js +0 -44
  380. package/dist/src/agent/memory/access-policy.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","names":[],"sources":["../../../../src/agent/memory/manager.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport { appendMemoryTraceEvent, setKnowledgeSourceItemSynthesisStatus } from '../../storage/sqlite/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';\nimport { UserUnderstandingService } from './understanding/service.js';\nimport type { UnderstandingCandidate } from './understanding/types.js';\nimport type { MemoryAccessPolicy } from './access-policy.js';\nimport type {\n MemoryDeleteRequest,\n MemoryListRequest,\n MemoryReadRequest,\n MemoryReadResult,\n MemorySearchRequest,\n MemorySearchResult,\n MemorySyncEvent,\n MemoryUpdateRequest,\n MemoryWriteRequest,\n MemoryWriteResult,\n MemoryRecord,\n MemorySignal,\n MemoryKind,\n} from './types.js';\n\nconst log = createLogger('MemoryManager');\n\nexport type MemorySearchStrategy = 'local-first' | 'external-first' | 'fanout' | 'local-only' | 'external-only';\nexport type MemoryWriteStrategy = 'local-first' | 'external-first' | 'write-through' | 'local-only' | 'external-only';\n\nexport interface MemoryRoutingOptions {\n searchStrategy?: MemorySearchStrategy;\n writeStrategy?: MemoryWriteStrategy;\n replicateTo?: string[];\n}\n\nexport interface MemoryManagerOptions extends MemoryRoutingOptions {\n loadProviders?: () => Promise<MemoryProvider[]>;\n writePolicy?: MemoryWritePolicy;\n accessPolicy?: MemoryAccessPolicy;\n}\n\nexport interface MemoryWritePolicy {\n allowExternalWrites?: boolean;\n allowedProviderIds?: string[];\n autoWriteKinds?: MemoryKind[];\n requireUserProfileApproval?: boolean;\n}\n\nexport class MemoryManager {\n private providers: MemoryProvider[] = [];\n private toolToProvider = new Map<string, MemoryProvider>();\n private readonly routing: Required<MemoryRoutingOptions>;\n private readonly loadProviders?: () => Promise<MemoryProvider[]>;\n private readonly writePolicy: Required<Pick<MemoryWritePolicy, 'allowExternalWrites' | 'requireUserProfileApproval'>> &\n Omit<MemoryWritePolicy, 'allowExternalWrites' | 'requireUserProfileApproval'>;\n private pluginProvidersLoaded = false;\n private readonly understanding: UserUnderstandingService;\n private readonly lastTurnSourceItem = new Map<string, string>();\n private understandingAgentId: string | undefined;\n private readonly accessPolicy?: MemoryAccessPolicy;\n\n constructor(options: MemoryManagerOptions = {}) {\n this.routing = {\n searchStrategy: options.searchStrategy ?? 'fanout',\n writeStrategy: options.writeStrategy ?? 'local-first',\n replicateTo: options.replicateTo ?? [],\n };\n this.loadProviders = options.loadProviders;\n this.accessPolicy = options.accessPolicy;\n this.writePolicy = {\n allowExternalWrites: options.writePolicy?.allowExternalWrites ?? false,\n requireUserProfileApproval: options.writePolicy?.requireUserProfileApproval ?? false,\n allowedProviderIds: options.writePolicy?.allowedProviderIds,\n autoWriteKinds: options.writePolicy?.autoWriteKinds,\n };\n this.understanding = new UserUnderstandingService({\n write: (request) => this.write(request),\n list: (canonicalKey) => this.list({ canonicalKey }),\n });\n }\n\n addProvider(provider: MemoryProvider): void {\n this.providers.push(provider);\n\n for (const schema of provider.getToolSchemas?.() ?? []) {\n const toolName = schema.name;\n if (!toolName) {\n continue;\n }\n if (!this.toolToProvider.has(toolName)) {\n this.toolToProvider.set(toolName, provider);\n } else {\n log.warn(\n { toolName, existing: this.toolToProvider.get(toolName)?.id, ignored: provider.id },\n 'Memory tool name conflict',\n );\n }\n }\n\n log.info(\n { id: provider.id, toolCount: provider.getToolSchemas?.().length ?? 0, capabilities: provider.capabilities },\n 'Memory provider registered',\n );\n }\n\n get providersList(): MemoryProvider[] {\n return [...this.providers];\n }\n\n /**\n * Non-builtin static instructions (builtin uses curated snapshot in system prompt builder).\n */\n buildExternalSystemPrompt(): string {\n const blocks: string[] = [];\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n const block = p.systemPromptBlock?.();\n if (block?.trim()) {\n blocks.push(block.trim());\n }\n } catch (err) {\n log.warn({ err, id: p.id }, 'systemPromptBlock failed');\n }\n }\n return blocks.join('\\n\\n');\n }\n\n queuePrefetchAll(query: string, options?: { sessionId?: string }): void {\n for (const p of this.providers) {\n try {\n p.queuePrefetch?.(query, options);\n } catch (err) {\n log.debug({ err, id: p.id }, 'queuePrefetch failed (non-fatal)');\n }\n }\n }\n\n async syncAll(userContent: string, assistantContent: string, options?: { sessionId?: string }): Promise<void> {\n await this.captureTurnUnderstanding(userContent, assistantContent, options);\n await this.syncProvidersForTurn(userContent, assistantContent, options);\n }\n\n async captureTurnUnderstanding(\n userContent: string,\n assistantContent: string,\n options?: { agentId?: string; sessionId?: string; correctionTargetRecordIds?: string[] },\n ): Promise<void> {\n const review = await this.understanding.reviewTurn({\n agentId: options?.agentId ?? this.understandingAgentId,\n userContent,\n assistantContent,\n sessionKey: options?.sessionId,\n correctionTargetRecordIds: options?.correctionTargetRecordIds,\n });\n if (options?.sessionId && review.sourceItemId) {\n this.lastTurnSourceItem.set(options.sessionId, review.sourceItemId);\n }\n }\n\n async syncProvidersForTurn(\n userContent: string,\n assistantContent: string,\n options?: { sessionId?: string },\n ): Promise<void> {\n const event: MemorySyncEvent = {\n type: 'turn',\n userContent,\n assistantContent,\n sessionId: options?.sessionId,\n };\n for (const p of this.providers) {\n const started = Date.now();\n try {\n await p.sync?.(event);\n this.trace('sync', p.id, event, {\n resultCount: 1,\n durationMs: Date.now() - started,\n sessionKey: options?.sessionId,\n });\n } catch (err) {\n this.trace('sync', p.id, event, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: options?.sessionId,\n });\n log.warn({ err, id: p.id }, 'memory sync failed');\n }\n }\n }\n\n async applyUnderstandingCandidates(\n candidates: UnderstandingCandidate[],\n context: {\n agentId?: string;\n sessionKey?: string;\n sourceText?: string;\n reviewSource?: 'turn' | 'background';\n } = {},\n ): Promise<void> {\n const sourceItemId = context.sessionKey\n ? this.lastTurnSourceItem.get(context.sessionKey)\n : undefined;\n await this.understanding.applyCandidates(candidates, {\n ...context,\n agentId: context.agentId ?? this.understandingAgentId,\n sourceItemId,\n });\n if (sourceItemId) {\n setKnowledgeSourceItemSynthesisStatus([sourceItemId], 'completed');\n }\n }\n\n getAdditionalTools(): AgentTool[] {\n const out: AgentTool[] = [];\n const seen = new Set<string>();\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n for (const t of p.getToolSchemas?.() ?? []) {\n if (t.name && !seen.has(t.name)) {\n seen.add(t.name);\n out.push(t);\n }\n }\n } catch (err) {\n log.warn({ err, id: p.id }, 'getToolSchemas failed');\n }\n }\n return out;\n }\n\n async handleToolCall(toolName: string, args: Record<string, unknown>): Promise<string> {\n const provider = this.toolToProvider.get(toolName);\n if (!provider) {\n throw new Error(`No memory provider handles tool '${toolName}'`);\n }\n if (!provider.handleToolCall) {\n throw new Error(`Memory provider '${provider.id}' does not handle tool calls`);\n }\n return provider.handleToolCall(toolName, args);\n }\n\n async search(request: MemorySearchRequest): Promise<MemorySearchResult[]> {\n const providers = this.providersForSearch();\n const results: MemorySearchResult[] = [];\n\n for (const p of providers) {\n if (!p.capabilities.search || !p.search) continue;\n const started = Date.now();\n try {\n const providerResults = await p.search(request);\n this.trace('search', p.id, request, {\n resultCount: providerResults.length,\n selectedRecordIds: providerResults.map((result) => result.record.id),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n results.push(...providerResults);\n if (providerResults.length > 0 && this.routing.searchStrategy !== 'fanout') {\n break;\n }\n } catch (err) {\n this.trace('search', p.id, request, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n log.warn({ err, id: p.id }, 'memory search failed');\n }\n }\n\n const seen = new Set<string>();\n return results\n .sort((a, b) => b.score - a.score)\n .filter((result) => this.canReadRecord(result.record, request.scope))\n .filter((result) => {\n const key = `${result.citation.providerId}:${result.citation.recordId}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .slice(0, request.maxResults ?? 5);\n }\n\n async read(request: MemoryReadRequest): Promise<MemoryReadResult | null> {\n for (const p of this.providersForSearch()) {\n if (!p.capabilities.read || !p.read) continue;\n const started = Date.now();\n try {\n const result = await p.read(request);\n this.trace('read', p.id, request, {\n resultCount: result ? 1 : 0,\n selectedRecordIds: result ? [result.record.id] : [],\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n if (result && this.canReadRecord(result.record, request.scope)) return result;\n } catch (err) {\n this.trace('read', p.id, request, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n log.warn({ err, id: p.id }, 'memory read failed');\n }\n }\n return null;\n }\n\n async get(id: string): Promise<MemoryRecord | null> {\n for (const p of this.providers) {\n if (!p.capabilities.read) continue;\n try {\n const direct = await p.get?.(id);\n if (direct && this.canReadRecord(direct)) return direct;\n } catch (err) {\n log.warn({ err, id: p.id, recordId: id }, 'memory get failed');\n }\n }\n return null;\n }\n\n async list(request: MemoryListRequest): Promise<MemoryRecord[]> {\n const out: MemoryRecord[] = [];\n for (const p of this.providersForSearch()) {\n if (!p.capabilities.read || !p.list) continue;\n try {\n out.push(...(await p.list(request)).filter((record) => this.canReadRecord(record, request.scope)));\n } catch (err) {\n log.warn({ err, id: p.id }, 'memory list failed');\n }\n }\n return out;\n }\n\n async write(request: MemoryWriteRequest): Promise<MemoryWriteResult> {\n const denied = this.crossAgentWriteDenied('write', request);\n if (denied) return denied;\n return this.writeWithStrategy('write', request);\n }\n\n async update(request: MemoryUpdateRequest): Promise<MemoryWriteResult> {\n const denied = this.crossAgentWriteDenied('update', request);\n if (denied) return denied;\n return this.writeWithStrategy('update', request);\n }\n\n async delete(request: MemoryDeleteRequest): Promise<MemoryWriteResult> {\n const denied = this.crossAgentWriteDenied('delete', request);\n if (denied) return denied;\n return this.writeWithStrategy('delete', request);\n }\n\n private canReadRecord(record: MemoryRecord, scope?: MemorySearchRequest['scope']): boolean {\n return this.accessPolicy?.canReadRecord(record, scope) ?? true;\n }\n\n private crossAgentWriteDenied(\n action: 'write' | 'update' | 'delete',\n request: MemoryWriteRequest | MemoryUpdateRequest | MemoryDeleteRequest,\n ): MemoryWriteResult | null {\n if (!this.accessPolicy) return null;\n const ownerAgentId = request.scope?.agentId ?? this.accessPolicy.requesterAgentId;\n if (ownerAgentId === this.accessPolicy.requesterAgentId) return null;\n if (action !== 'write' || !('status' in request) || request.status !== 'candidate') {\n return { success: false, error: 'Cross-agent changes must be submitted as memory candidates' };\n }\n if (!this.accessPolicy.canSubmitCandidate(ownerAgentId)) {\n return { success: false, error: 'Cross-agent candidate submission is not allowed' };\n }\n return null;\n }\n\n onMemoryWrite(action: 'add' | 'replace' | 'remove', target: 'memory' | 'user', content: string): void {\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n p.sync?.({ type: 'write', action, target, content });\n } catch (err) {\n log.debug({ err, id: p.id }, 'memory write sync failed');\n }\n }\n }\n\n recordSignal(signal: MemorySignal): void {\n for (const p of this.providers) {\n const started = Date.now();\n try {\n p.sync?.({ type: 'signal', signal });\n this.trace('sync', p.id, { type: 'signal', signal }, {\n resultCount: 1,\n durationMs: Date.now() - started,\n });\n } catch (err) {\n this.trace('sync', p.id, { type: 'signal', signal }, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n });\n log.debug({ err, id: p.id, source: signal.source }, 'memory signal sync failed');\n }\n }\n }\n\n async initializeAll(sessionId: string, options?: MemoryProviderInitOptions): Promise<void> {\n this.understandingAgentId = options?.agentId;\n await this.loadPluginProvidersOnce();\n for (const p of this.providers) {\n try {\n await p.initialize(sessionId, options);\n } catch (err) {\n log.warn({ err, id: p.id }, 'initialize failed');\n }\n }\n }\n\n private async loadPluginProvidersOnce(): Promise<void> {\n if (this.pluginProvidersLoaded || !this.loadProviders) return;\n this.pluginProvidersLoaded = true;\n try {\n const providers = await this.loadProviders();\n const existingIds = new Set(this.providers.map((p) => p.id));\n for (const provider of providers) {\n if (existingIds.has(provider.id)) {\n log.warn({ id: provider.id }, 'Skipped duplicate memory provider');\n continue;\n }\n this.addProvider(provider);\n existingIds.add(provider.id);\n }\n } catch (err) {\n log.warn({ err }, 'Memory provider plugin loading failed');\n }\n }\n\n async shutdownAll(): Promise<void> {\n this.lastTurnSourceItem.clear();\n for (const p of [...this.providers].reverse()) {\n try {\n await p.shutdown();\n } catch (err) {\n log.warn({ err, id: p.id }, 'shutdown failed');\n }\n }\n }\n\n private providersForSearch(): MemoryProvider[] {\n const locals = this.providers.filter((p) => p.capabilities.local);\n const externals = this.providers.filter((p) => !p.capabilities.local);\n switch (this.routing.searchStrategy) {\n case 'local-only':\n return locals;\n case 'external-only':\n return externals;\n case 'external-first':\n return [...externals, ...locals];\n case 'local-first':\n case 'fanout':\n default:\n return [...locals, ...externals];\n }\n }\n\n private providersForWrite(): MemoryProvider[] {\n const locals = this.providers.filter((p) => p.capabilities.local);\n const externals = this.providers.filter((p) => !p.capabilities.local);\n switch (this.routing.writeStrategy) {\n case 'local-only':\n return locals;\n case 'external-only':\n return externals;\n case 'external-first':\n return [...externals, ...locals];\n case 'write-through':\n case 'local-first':\n default:\n return [...locals, ...externals];\n }\n }\n\n private async writeWithStrategy(\n operation: 'write' | 'update' | 'delete',\n request: MemoryWriteRequest | MemoryUpdateRequest | MemoryDeleteRequest,\n ): Promise<MemoryWriteResult> {\n const providers =\n operation === 'write' && (request as MemoryWriteRequest).status === 'candidate'\n ? this.providers.filter((provider) => provider.capabilities.local)\n : this.providersForWrite();\n const errors: string[] = [];\n let firstSuccess: MemoryWriteResult | null = null;\n\n for (const p of providers) {\n const fn = p[operation];\n if (!this.providerAllowedForWrite(p, operation, request)) {\n this.trace(operation, p.id, request, {\n skippedReason: 'policy',\n sessionKey: request.scope?.sessionKey,\n });\n continue;\n }\n const canWrite =\n (operation === 'write' && p.capabilities.write) ||\n (operation === 'update' && p.capabilities.update) ||\n (operation === 'delete' && p.capabilities.delete);\n if (!canWrite || !fn) continue;\n const started = Date.now();\n try {\n const result = await fn.call(p, request as never);\n this.trace(operation, p.id, request, {\n resultCount: result.record ? 1 : 0,\n selectedRecordIds: result.record ? [result.record.id] : [],\n error: result.success ? undefined : result.error,\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n if (result.success) {\n firstSuccess ??= result;\n if (this.routing.writeStrategy !== 'write-through') {\n return result;\n }\n } else if (result.error) {\n errors.push(`${p.id}: ${result.error}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.trace(operation, p.id, request, {\n error: message,\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n errors.push(`${p.id}: ${message}`);\n log.warn({ err, id: p.id, operation }, 'memory write operation failed');\n }\n }\n\n if (firstSuccess) return firstSuccess;\n return { success: false, error: errors.join('; ') || `No provider supports memory ${operation}` };\n }\n\n private providerAllowedForWrite(\n provider: MemoryProvider,\n operation: 'write' | 'update' | 'delete',\n request: MemoryWriteRequest | MemoryUpdateRequest | MemoryDeleteRequest,\n ): boolean {\n if (!provider.capabilities.local && !this.writePolicy.allowExternalWrites) {\n return false;\n }\n if (\n !provider.capabilities.local &&\n this.writePolicy.allowedProviderIds &&\n this.writePolicy.allowedProviderIds.length > 0 &&\n !this.writePolicy.allowedProviderIds.includes(provider.id)\n ) {\n return false;\n }\n if (operation === 'write') {\n const writeRequest = request as MemoryWriteRequest;\n if (writeRequest.status === 'candidate' && !provider.capabilities.local) {\n return false;\n }\n if (\n this.writePolicy.autoWriteKinds &&\n this.writePolicy.autoWriteKinds.length > 0 &&\n !this.writePolicy.autoWriteKinds.includes(writeRequest.kind)\n ) {\n return false;\n }\n if (\n this.writePolicy.requireUserProfileApproval &&\n writeRequest.kind === 'user_profile' &&\n !writeRequest.approved\n ) {\n return false;\n }\n }\n if (operation === 'update' && this.writePolicy.requireUserProfileApproval) {\n const updateRequest = request as MemoryUpdateRequest;\n if (updateRequest.target === 'user' && !updateRequest.approved) {\n return false;\n }\n }\n return true;\n }\n\n private trace(\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test',\n providerId: string,\n request: unknown,\n meta: {\n sessionKey?: string;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n durationMs?: number;\n } = {},\n ): void {\n try {\n appendMemoryTraceEvent({\n phase,\n providerId,\n request: sanitizeTraceRequest(request),\n ...meta,\n });\n } catch (err) {\n log.debug({ err, providerId, phase }, 'memory trace append failed');\n }\n }\n}\n\nfunction sanitizeTraceRequest(request: unknown): unknown {\n if (!request || typeof request !== 'object') return request;\n const copy = { ...(request as Record<string, unknown>) };\n if (typeof copy.content === 'string' && copy.content.length > 500) {\n copy.content = `${copy.content.slice(0, 500)}…`;\n }\n return copy;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manager.js","names":[],"sources":["../../../../src/agent/memory/manager.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport { appendMemoryTraceEvent, setKnowledgeSourceItemSynthesisStatus } from '../../storage/sqlite/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';\nimport { UserUnderstandingService } from './understanding/service.js';\nimport type { UnderstandingCandidate } from './understanding/types.js';\nimport type {\n MemoryDeleteRequest,\n MemoryListRequest,\n MemoryReadRequest,\n MemoryReadResult,\n MemorySearchRequest,\n MemorySearchResult,\n MemorySyncEvent,\n MemoryUpdateRequest,\n MemoryWriteRequest,\n MemoryWriteResult,\n MemoryRecord,\n MemorySignal,\n MemoryKind,\n} from './types.js';\n\nconst log = createLogger('MemoryManager');\n\nexport type MemorySearchStrategy = 'local-first' | 'external-first' | 'fanout' | 'local-only' | 'external-only';\nexport type MemoryWriteStrategy = 'local-first' | 'external-first' | 'write-through' | 'local-only' | 'external-only';\n\nexport interface MemoryRoutingOptions {\n searchStrategy?: MemorySearchStrategy;\n writeStrategy?: MemoryWriteStrategy;\n replicateTo?: string[];\n}\n\nexport interface MemoryManagerOptions extends MemoryRoutingOptions {\n loadProviders?: () => Promise<MemoryProvider[]>;\n writePolicy?: MemoryWritePolicy;\n}\n\nexport interface MemoryWritePolicy {\n allowExternalWrites?: boolean;\n allowedProviderIds?: string[];\n autoWriteKinds?: MemoryKind[];\n requireUserProfileApproval?: boolean;\n}\n\nexport class MemoryManager {\n private providers: MemoryProvider[] = [];\n private toolToProvider = new Map<string, MemoryProvider>();\n private readonly routing: Required<MemoryRoutingOptions>;\n private readonly loadProviders?: () => Promise<MemoryProvider[]>;\n private readonly writePolicy: Required<Pick<MemoryWritePolicy, 'allowExternalWrites' | 'requireUserProfileApproval'>> &\n Omit<MemoryWritePolicy, 'allowExternalWrites' | 'requireUserProfileApproval'>;\n private pluginProvidersLoaded = false;\n private readonly understanding: UserUnderstandingService;\n private readonly lastTurnSourceItem = new Map<string, string>();\n private understandingAgentId: string | undefined;\n\n constructor(options: MemoryManagerOptions = {}) {\n this.routing = {\n searchStrategy: options.searchStrategy ?? 'fanout',\n writeStrategy: options.writeStrategy ?? 'local-first',\n replicateTo: options.replicateTo ?? [],\n };\n this.loadProviders = options.loadProviders;\n this.writePolicy = {\n allowExternalWrites: options.writePolicy?.allowExternalWrites ?? false,\n requireUserProfileApproval: options.writePolicy?.requireUserProfileApproval ?? false,\n allowedProviderIds: options.writePolicy?.allowedProviderIds,\n autoWriteKinds: options.writePolicy?.autoWriteKinds,\n };\n this.understanding = new UserUnderstandingService({\n write: (request) => this.write(request),\n list: (canonicalKey) => this.list({ canonicalKey }),\n });\n }\n\n addProvider(provider: MemoryProvider): void {\n this.providers.push(provider);\n\n for (const schema of provider.getToolSchemas?.() ?? []) {\n const toolName = schema.name;\n if (!toolName) {\n continue;\n }\n if (!this.toolToProvider.has(toolName)) {\n this.toolToProvider.set(toolName, provider);\n } else {\n log.warn(\n { toolName, existing: this.toolToProvider.get(toolName)?.id, ignored: provider.id },\n 'Memory tool name conflict',\n );\n }\n }\n\n log.info(\n { id: provider.id, toolCount: provider.getToolSchemas?.().length ?? 0, capabilities: provider.capabilities },\n 'Memory provider registered',\n );\n }\n\n get providersList(): MemoryProvider[] {\n return [...this.providers];\n }\n\n /**\n * Non-builtin static instructions (builtin uses curated snapshot in system prompt builder).\n */\n buildExternalSystemPrompt(): string {\n const blocks: string[] = [];\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n const block = p.systemPromptBlock?.();\n if (block?.trim()) {\n blocks.push(block.trim());\n }\n } catch (err) {\n log.warn({ err, id: p.id }, 'systemPromptBlock failed');\n }\n }\n return blocks.join('\\n\\n');\n }\n\n queuePrefetchAll(query: string, options?: { sessionId?: string }): void {\n for (const p of this.providers) {\n try {\n p.queuePrefetch?.(query, options);\n } catch (err) {\n log.debug({ err, id: p.id }, 'queuePrefetch failed (non-fatal)');\n }\n }\n }\n\n async syncAll(userContent: string, assistantContent: string, options?: { sessionId?: string }): Promise<void> {\n await this.captureTurnUnderstanding(userContent, assistantContent, options);\n await this.syncProvidersForTurn(userContent, assistantContent, options);\n }\n\n async captureTurnUnderstanding(\n userContent: string,\n assistantContent: string,\n options?: { agentId?: string; sessionId?: string; correctionTargetRecordIds?: string[] },\n ): Promise<import('./understanding/types.js').UnderstandingReviewResult> {\n const review = await this.understanding.reviewTurn({\n agentId: options?.agentId ?? this.understandingAgentId,\n userContent,\n assistantContent,\n sessionKey: options?.sessionId,\n correctionTargetRecordIds: options?.correctionTargetRecordIds,\n });\n if (options?.sessionId && review.sourceItemId) {\n this.lastTurnSourceItem.set(options.sessionId, review.sourceItemId);\n }\n return review;\n }\n\n async syncProvidersForTurn(\n userContent: string,\n assistantContent: string,\n options?: { sessionId?: string },\n ): Promise<void> {\n const event: MemorySyncEvent = {\n type: 'turn',\n userContent,\n assistantContent,\n sessionId: options?.sessionId,\n };\n for (const p of this.providers) {\n const started = Date.now();\n try {\n await p.sync?.(event);\n this.trace('sync', p.id, event, {\n resultCount: 1,\n durationMs: Date.now() - started,\n sessionKey: options?.sessionId,\n });\n } catch (err) {\n this.trace('sync', p.id, event, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: options?.sessionId,\n });\n log.warn({ err, id: p.id }, 'memory sync failed');\n }\n }\n }\n\n async applyUnderstandingCandidates(\n candidates: UnderstandingCandidate[],\n context: {\n agentId?: string;\n sessionKey?: string;\n sourceText?: string;\n reviewSource?: 'turn' | 'background';\n } = {},\n ): Promise<void> {\n const sourceItemId = context.sessionKey\n ? this.lastTurnSourceItem.get(context.sessionKey)\n : undefined;\n await this.understanding.applyCandidates(candidates, {\n ...context,\n agentId: context.agentId ?? this.understandingAgentId,\n sourceItemId,\n });\n if (sourceItemId) {\n setKnowledgeSourceItemSynthesisStatus([sourceItemId], 'completed');\n }\n }\n\n getAdditionalTools(): AgentTool[] {\n const out: AgentTool[] = [];\n const seen = new Set<string>();\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n for (const t of p.getToolSchemas?.() ?? []) {\n if (t.name && !seen.has(t.name)) {\n seen.add(t.name);\n out.push(t);\n }\n }\n } catch (err) {\n log.warn({ err, id: p.id }, 'getToolSchemas failed');\n }\n }\n return out;\n }\n\n async handleToolCall(toolName: string, args: Record<string, unknown>): Promise<string> {\n const provider = this.toolToProvider.get(toolName);\n if (!provider) {\n throw new Error(`No memory provider handles tool '${toolName}'`);\n }\n if (!provider.handleToolCall) {\n throw new Error(`Memory provider '${provider.id}' does not handle tool calls`);\n }\n return provider.handleToolCall(toolName, args);\n }\n\n async search(request: MemorySearchRequest): Promise<MemorySearchResult[]> {\n const providers = this.providersForSearch();\n const results: MemorySearchResult[] = [];\n\n for (const p of providers) {\n if (!p.capabilities.search || !p.search) continue;\n const started = Date.now();\n try {\n const providerResults = await p.search(request);\n this.trace('search', p.id, request, {\n resultCount: providerResults.length,\n selectedRecordIds: providerResults.map((result) => result.record.id),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n results.push(...providerResults);\n if (providerResults.length > 0 && this.routing.searchStrategy !== 'fanout') {\n break;\n }\n } catch (err) {\n this.trace('search', p.id, request, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n log.warn({ err, id: p.id }, 'memory search failed');\n }\n }\n\n const seen = new Set<string>();\n return results\n .sort((a, b) => b.score - a.score)\n .filter((result) => this.canReadRecord(result.record, request.scope))\n .filter((result) => {\n const key = `${result.citation.providerId}:${result.citation.recordId}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .slice(0, request.maxResults ?? 5);\n }\n\n async read(request: MemoryReadRequest): Promise<MemoryReadResult | null> {\n for (const p of this.providersForSearch()) {\n if (!p.capabilities.read || !p.read) continue;\n const started = Date.now();\n try {\n const result = await p.read(request);\n this.trace('read', p.id, request, {\n resultCount: result ? 1 : 0,\n selectedRecordIds: result ? [result.record.id] : [],\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n if (result && this.canReadRecord(result.record, request.scope)) return result;\n } catch (err) {\n this.trace('read', p.id, request, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n log.warn({ err, id: p.id }, 'memory read failed');\n }\n }\n return null;\n }\n\n async get(id: string): Promise<MemoryRecord | null> {\n for (const p of this.providers) {\n if (!p.capabilities.read) continue;\n try {\n const direct = await p.get?.(id);\n if (direct && this.canReadRecord(direct)) return direct;\n } catch (err) {\n log.warn({ err, id: p.id, recordId: id }, 'memory get failed');\n }\n }\n return null;\n }\n\n async list(request: MemoryListRequest): Promise<MemoryRecord[]> {\n const out: MemoryRecord[] = [];\n for (const p of this.providersForSearch()) {\n if (!p.capabilities.read || !p.list) continue;\n try {\n out.push(...(await p.list(request)).filter((record) => this.canReadRecord(record, request.scope)));\n } catch (err) {\n log.warn({ err, id: p.id }, 'memory list failed');\n }\n }\n return out;\n }\n\n async write(request: MemoryWriteRequest): Promise<MemoryWriteResult> {\n return this.writeWithStrategy('write', request);\n }\n\n async update(request: MemoryUpdateRequest): Promise<MemoryWriteResult> {\n return this.writeWithStrategy('update', request);\n }\n\n async delete(request: MemoryDeleteRequest): Promise<MemoryWriteResult> {\n return this.writeWithStrategy('delete', request);\n }\n\n private canReadRecord(record: MemoryRecord, scope?: MemorySearchRequest['scope']): boolean {\n void record;\n void scope;\n return true;\n }\n\n onMemoryWrite(action: 'add' | 'replace' | 'remove', target: 'memory' | 'user', content: string): void {\n for (const p of this.providers) {\n if (p.capabilities.local) {\n continue;\n }\n try {\n p.sync?.({ type: 'write', action, target, content });\n } catch (err) {\n log.debug({ err, id: p.id }, 'memory write sync failed');\n }\n }\n }\n\n recordSignal(signal: MemorySignal): void {\n for (const p of this.providers) {\n const started = Date.now();\n try {\n p.sync?.({ type: 'signal', signal });\n this.trace('sync', p.id, { type: 'signal', signal }, {\n resultCount: 1,\n durationMs: Date.now() - started,\n });\n } catch (err) {\n this.trace('sync', p.id, { type: 'signal', signal }, {\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - started,\n });\n log.debug({ err, id: p.id, source: signal.source }, 'memory signal sync failed');\n }\n }\n }\n\n async initializeAll(sessionId: string, options?: MemoryProviderInitOptions): Promise<void> {\n this.understandingAgentId = options?.agentId;\n await this.loadPluginProvidersOnce();\n for (const p of this.providers) {\n try {\n await p.initialize(sessionId, options);\n } catch (err) {\n log.warn({ err, id: p.id }, 'initialize failed');\n }\n }\n }\n\n private async loadPluginProvidersOnce(): Promise<void> {\n if (this.pluginProvidersLoaded || !this.loadProviders) return;\n this.pluginProvidersLoaded = true;\n try {\n const providers = await this.loadProviders();\n const existingIds = new Set(this.providers.map((p) => p.id));\n for (const provider of providers) {\n if (existingIds.has(provider.id)) {\n log.warn({ id: provider.id }, 'Skipped duplicate memory provider');\n continue;\n }\n this.addProvider(provider);\n existingIds.add(provider.id);\n }\n } catch (err) {\n log.warn({ err }, 'Memory provider plugin loading failed');\n }\n }\n\n async shutdownAll(): Promise<void> {\n this.lastTurnSourceItem.clear();\n for (const p of [...this.providers].reverse()) {\n try {\n await p.shutdown();\n } catch (err) {\n log.warn({ err, id: p.id }, 'shutdown failed');\n }\n }\n }\n\n private providersForSearch(): MemoryProvider[] {\n const locals = this.providers.filter((p) => p.capabilities.local);\n const externals = this.providers.filter((p) => !p.capabilities.local);\n switch (this.routing.searchStrategy) {\n case 'local-only':\n return locals;\n case 'external-only':\n return externals;\n case 'external-first':\n return [...externals, ...locals];\n case 'local-first':\n case 'fanout':\n default:\n return [...locals, ...externals];\n }\n }\n\n private providersForWrite(): MemoryProvider[] {\n const locals = this.providers.filter((p) => p.capabilities.local);\n const externals = this.providers.filter((p) => !p.capabilities.local);\n switch (this.routing.writeStrategy) {\n case 'local-only':\n return locals;\n case 'external-only':\n return externals;\n case 'external-first':\n return [...externals, ...locals];\n case 'write-through':\n case 'local-first':\n default:\n return [...locals, ...externals];\n }\n }\n\n private async writeWithStrategy(\n operation: 'write' | 'update' | 'delete',\n request: MemoryWriteRequest | MemoryUpdateRequest | MemoryDeleteRequest,\n ): Promise<MemoryWriteResult> {\n const providers =\n operation === 'write' && (request as MemoryWriteRequest).status === 'candidate'\n ? this.providers.filter((provider) => provider.capabilities.local)\n : this.providersForWrite();\n const errors: string[] = [];\n let firstSuccess: MemoryWriteResult | null = null;\n\n for (const p of providers) {\n const fn = p[operation];\n if (!this.providerAllowedForWrite(p, operation, request)) {\n this.trace(operation, p.id, request, {\n skippedReason: 'policy',\n sessionKey: request.scope?.sessionKey,\n });\n continue;\n }\n const canWrite =\n (operation === 'write' && p.capabilities.write) ||\n (operation === 'update' && p.capabilities.update) ||\n (operation === 'delete' && p.capabilities.delete);\n if (!canWrite || !fn) continue;\n const started = Date.now();\n try {\n const result = await fn.call(p, request as never);\n this.trace(operation, p.id, request, {\n resultCount: result.record ? 1 : 0,\n selectedRecordIds: result.record ? [result.record.id] : [],\n error: result.success ? undefined : result.error,\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n if (result.success) {\n firstSuccess ??= result;\n if (this.routing.writeStrategy !== 'write-through') {\n return result;\n }\n } else if (result.error) {\n errors.push(`${p.id}: ${result.error}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.trace(operation, p.id, request, {\n error: message,\n durationMs: Date.now() - started,\n sessionKey: request.scope?.sessionKey,\n });\n errors.push(`${p.id}: ${message}`);\n log.warn({ err, id: p.id, operation }, 'memory write operation failed');\n }\n }\n\n if (firstSuccess) return firstSuccess;\n return { success: false, error: errors.join('; ') || `No provider supports memory ${operation}` };\n }\n\n private providerAllowedForWrite(\n provider: MemoryProvider,\n operation: 'write' | 'update' | 'delete',\n request: MemoryWriteRequest | MemoryUpdateRequest | MemoryDeleteRequest,\n ): boolean {\n if (!provider.capabilities.local && !this.writePolicy.allowExternalWrites) {\n return false;\n }\n if (\n !provider.capabilities.local &&\n this.writePolicy.allowedProviderIds &&\n this.writePolicy.allowedProviderIds.length > 0 &&\n !this.writePolicy.allowedProviderIds.includes(provider.id)\n ) {\n return false;\n }\n if (operation === 'write') {\n const writeRequest = request as MemoryWriteRequest;\n if (writeRequest.status === 'candidate' && !provider.capabilities.local) {\n return false;\n }\n if (\n this.writePolicy.autoWriteKinds &&\n this.writePolicy.autoWriteKinds.length > 0 &&\n !this.writePolicy.autoWriteKinds.includes(writeRequest.kind)\n ) {\n return false;\n }\n if (\n this.writePolicy.requireUserProfileApproval &&\n writeRequest.kind === 'user_profile' &&\n !writeRequest.approved\n ) {\n return false;\n }\n }\n if (operation === 'update' && this.writePolicy.requireUserProfileApproval) {\n const updateRequest = request as MemoryUpdateRequest;\n if (updateRequest.target === 'user' && !updateRequest.approved) {\n return false;\n }\n }\n return true;\n }\n\n private trace(\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test',\n providerId: string,\n request: unknown,\n meta: {\n sessionKey?: string;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n durationMs?: number;\n } = {},\n ): void {\n try {\n appendMemoryTraceEvent({\n phase,\n providerId,\n request: sanitizeTraceRequest(request),\n ...meta,\n });\n } catch (err) {\n log.debug({ err, providerId, phase }, 'memory trace append failed');\n }\n }\n}\n\nfunction sanitizeTraceRequest(request: unknown): unknown {\n if (!request || typeof request !== 'object') return request;\n const copy = { ...(request as Record<string, unknown>) };\n if (typeof copy.content === 'string' && copy.content.length > 500) {\n copy.content = `${copy.content.slice(0, 500)}…`;\n }\n return copy;\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import type { Config } from '../../config/schema.js';
2
2
  import type { MemoryStoreConfig } from './types.js';
3
- /** When false, curated `memories/` (under agent home) + external memory providers are off. */
3
+ /** When false, shared curated memory and external memory providers are off. */
4
4
  export declare function isMemorySubsystemEnabled(config: Config | undefined): boolean;
5
- /** Curated memory tool + agent-home `memories/` store (not injected into system prompt). */
5
+ /** Curated memory tool + shared user `memories/` store (not injected into system prompt). */
6
6
  export declare function isCuratedMemoryInPrompt(config: Config | undefined): boolean;
7
- export declare function resolveBuiltinMemoryStoreConfig(workspaceDir: string, config: Config | undefined, requestedAgentId?: string): MemoryStoreConfig;
7
+ export declare function resolveBuiltinMemoryStoreConfig(workspaceDir: string, config: Config | undefined, _requestedAgentId?: string): MemoryStoreConfig;
8
8
  /**
9
9
  * Whether to prefix the user message with prefetched external memory this turn.
10
10
  * `first-turn` only injects on turn 1. `contextCadence` N injects on turns 1, N+1, 2N+1, …
@@ -1,30 +1,25 @@
1
- import { init_agent_scope, resolveAgentHomeDir, resolveAgentIdForWorkspacePath } from "../agent-scope.js";
2
- import { resolveEffectiveAgentManifestForAgent } from "../../config/agent-profile.js";
3
- import { init_paths, resolveUserMemoryPath } from "../../config/paths.js";
1
+ import { init_paths, resolveUserDir, resolveUserMemoryPath } from "../../config/paths.js";
4
2
  import { join } from "node:path";
5
3
  //#region src/agent/memory/memory-config.ts
6
4
  init_paths();
7
- init_agent_scope();
8
- /** When false, curated `memories/` (under agent home) + external memory providers are off. */
5
+ /** When false, shared curated memory and external memory providers are off. */
9
6
  function isMemorySubsystemEnabled(config) {
10
7
  if (!config) return true;
11
- return config.agents.list.some((agent) => agent.enabled !== false && agent.memory.mode !== "off");
8
+ return config.userContext.enabled && config.userContext.memory.mode !== "off";
12
9
  }
13
- /** Curated memory tool + agent-home `memories/` store (not injected into system prompt). */
10
+ /** Curated memory tool + shared user `memories/` store (not injected into system prompt). */
14
11
  function isCuratedMemoryInPrompt(config) {
15
12
  if (!config) return true;
16
- return config.agents.list.some((agent) => agent.enabled !== false && agent.memory.sources.includes("curated"));
13
+ return config.userContext.enabled && config.userContext.memory.sources.includes("curated");
17
14
  }
18
- function resolveBuiltinMemoryStoreConfig(workspaceDir, config, requestedAgentId) {
19
- const agentId = config != null ? requestedAgentId?.trim() || resolveAgentIdForWorkspacePath(config, workspaceDir) : void 0;
20
- const manifest = config && agentId ? resolveEffectiveAgentManifestForAgent(config, agentId) : void 0;
15
+ function resolveBuiltinMemoryStoreConfig(workspaceDir, config, _requestedAgentId) {
21
16
  return {
22
17
  workspaceDir,
23
- memoriesDir: config != null ? join(resolveAgentHomeDir(config, agentId ?? "main"), "memories") : join(workspaceDir, "memories"),
18
+ memoriesDir: config != null ? join(resolveUserDir(), "memories") : join(workspaceDir, "memories"),
24
19
  userMemoryPath: config != null ? resolveUserMemoryPath() : join(workspaceDir, "user", "MEMORY.md"),
25
- memoryCharLimit: manifest?.memory.retention?.maxChars ?? 2200,
20
+ memoryCharLimit: config?.userContext.memory.retention?.maxChars ?? 2200,
26
21
  userCharLimit: 1375,
27
- userProfileEnabled: manifest?.memory.sources.includes("userProfile") ?? true
22
+ userProfileEnabled: config?.userContext.memory.sources.includes("userProfile") ?? true
28
23
  };
29
24
  }
30
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"memory-config.js","names":[],"sources":["../../../../src/agent/memory/memory-config.ts"],"sourcesContent":["import { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveUserMemoryPath } from '../../config/paths.js';\nimport { resolveEffectiveAgentManifestForAgent } from '../../config/agent-profile.js';\nimport { resolveAgentHomeDir, resolveAgentIdForWorkspacePath } from '../agent-scope.js';\n\nimport type { MemoryStoreConfig } from './types.js';\n\n/** When false, curated `memories/` (under agent home) + external memory providers are off. */\nexport function isMemorySubsystemEnabled(config: Config | undefined): boolean {\n if (!config) return true;\n return config.agents.list.some((agent) => agent.enabled !== false && agent.memory.mode !== 'off');\n}\n\n/** Curated memory tool + agent-home `memories/` store (not injected into system prompt). */\nexport function isCuratedMemoryInPrompt(config: Config | undefined): boolean {\n if (!config) return true;\n return config.agents.list.some((agent) => agent.enabled !== false && agent.memory.sources.includes('curated'));\n}\n\nexport function resolveBuiltinMemoryStoreConfig(\n workspaceDir: string,\n config: Config | undefined,\n requestedAgentId?: string,\n): MemoryStoreConfig {\n const agentId = config != null\n ? requestedAgentId?.trim() || resolveAgentIdForWorkspacePath(config, workspaceDir)\n : undefined;\n const manifest = config && agentId ? resolveEffectiveAgentManifestForAgent(config, agentId) : undefined;\n const memoriesDir =\n config != null\n ? join(\n resolveAgentHomeDir(config, agentId ?? 'main'),\n 'memories',\n )\n : join(workspaceDir, 'memories');\n return {\n workspaceDir,\n memoriesDir,\n userMemoryPath: config != null ? resolveUserMemoryPath() : join(workspaceDir, 'user', 'MEMORY.md'),\n memoryCharLimit: manifest?.memory.retention?.maxChars ?? 2200,\n userCharLimit: 1375,\n userProfileEnabled: manifest?.memory.sources.includes('userProfile') ?? true,\n };\n}\n\n/**\n * Whether to prefix the user message with prefetched external memory this turn.\n * `first-turn` only injects on turn 1. `contextCadence` N injects on turns 1, N+1, 2N+1, …\n */\nexport function shouldPlanUserContextThisTurn(\n _config: Config | undefined,\n turnNumber: number,\n): boolean {\n return turnNumber >= 1;\n}\n\nexport function shouldRegisterCuratedMemoryTool(config: Config | undefined): boolean {\n return isCuratedMemoryInPrompt(config);\n}\n"],"mappings":";;;;;YAG8D;kBAE0B;;AAKxF,SAAgB,yBAAyB,QAAqC;AAC5E,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,OAAO,KAAK,MAAM,UAAU,MAAM,YAAY,SAAS,MAAM,OAAO,SAAS,MAAM;;;AAInG,SAAgB,wBAAwB,QAAqC;AAC3E,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,OAAO,KAAK,MAAM,UAAU,MAAM,YAAY,SAAS,MAAM,OAAO,QAAQ,SAAS,UAAU,CAAC;;AAGhH,SAAgB,gCACd,cACA,QACA,kBACmB;CACnB,MAAM,UAAU,UAAU,OACtB,kBAAkB,MAAM,IAAI,+BAA+B,QAAQ,aAAa,GAChF,KAAA;CACJ,MAAM,WAAW,UAAU,UAAU,sCAAsC,QAAQ,QAAQ,GAAG,KAAA;AAQ9F,QAAO;EACL;EACA,aARA,UAAU,OACN,KACE,oBAAoB,QAAQ,WAAW,OAAO,EAC9C,WACD,GACD,KAAK,cAAc,WAAW;EAIlC,gBAAgB,UAAU,OAAO,uBAAuB,GAAG,KAAK,cAAc,QAAQ,YAAY;EAClG,iBAAiB,UAAU,OAAO,WAAW,YAAY;EACzD,eAAe;EACf,oBAAoB,UAAU,OAAO,QAAQ,SAAS,cAAc,IAAI;EACzE;;;;;;AAOH,SAAgB,8BACd,SACA,YACS;AACT,QAAO,cAAc;;AAGvB,SAAgB,gCAAgC,QAAqC;AACnF,QAAO,wBAAwB,OAAO"}
1
+ {"version":3,"file":"memory-config.js","names":[],"sources":["../../../../src/agent/memory/memory-config.ts"],"sourcesContent":["import { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveUserMemoryPath } from '../../config/paths.js';\nimport { resolveUserDir } from '../../config/paths.js';\n\nimport type { MemoryStoreConfig } from './types.js';\n\n/** When false, shared curated memory and external memory providers are off. */\nexport function isMemorySubsystemEnabled(config: Config | undefined): boolean {\n if (!config) return true;\n return config.userContext.enabled && config.userContext.memory.mode !== 'off';\n}\n\n/** Curated memory tool + shared user `memories/` store (not injected into system prompt). */\nexport function isCuratedMemoryInPrompt(config: Config | undefined): boolean {\n if (!config) return true;\n return config.userContext.enabled && config.userContext.memory.sources.includes('curated');\n}\n\nexport function resolveBuiltinMemoryStoreConfig(\n workspaceDir: string,\n config: Config | undefined,\n _requestedAgentId?: string,\n): MemoryStoreConfig {\n const memoriesDir = config != null ? join(resolveUserDir(), 'memories') : join(workspaceDir, 'memories');\n return {\n workspaceDir,\n memoriesDir,\n userMemoryPath: config != null ? resolveUserMemoryPath() : join(workspaceDir, 'user', 'MEMORY.md'),\n memoryCharLimit: config?.userContext.memory.retention?.maxChars ?? 2200,\n userCharLimit: 1375,\n userProfileEnabled: config?.userContext.memory.sources.includes('userProfile') ?? true,\n };\n}\n\n/**\n * Whether to prefix the user message with prefetched external memory this turn.\n * `first-turn` only injects on turn 1. `contextCadence` N injects on turns 1, N+1, 2N+1, …\n */\nexport function shouldPlanUserContextThisTurn(\n _config: Config | undefined,\n turnNumber: number,\n): boolean {\n return turnNumber >= 1;\n}\n\nexport function shouldRegisterCuratedMemoryTool(config: Config | undefined): boolean {\n return isCuratedMemoryInPrompt(config);\n}\n"],"mappings":";;;YAG8D;;AAM9D,SAAgB,yBAAyB,QAAqC;AAC5E,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,YAAY,WAAW,OAAO,YAAY,OAAO,SAAS;;;AAI1E,SAAgB,wBAAwB,QAAqC;AAC3E,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,YAAY,WAAW,OAAO,YAAY,OAAO,QAAQ,SAAS,UAAU;;AAG5F,SAAgB,gCACd,cACA,QACA,mBACmB;AAEnB,QAAO;EACL;EACA,aAHkB,UAAU,OAAO,KAAK,gBAAgB,EAAE,WAAW,GAAG,KAAK,cAAc,WAAW;EAItG,gBAAgB,UAAU,OAAO,uBAAuB,GAAG,KAAK,cAAc,QAAQ,YAAY;EAClG,iBAAiB,QAAQ,YAAY,OAAO,WAAW,YAAY;EACnE,eAAe;EACf,oBAAoB,QAAQ,YAAY,OAAO,QAAQ,SAAS,cAAc,IAAI;EACnF;;;;;;AAOH,SAAgB,8BACd,SACA,YACS;AACT,QAAO,cAAc;;AAGvB,SAAgB,gCAAgC,QAAqC;AACnF,QAAO,wBAAwB,OAAO"}
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Curated Markdown compatibility store:
3
- * - agent notes: `~/.xopc/agents/<id>/memories/MEMORY.md`
4
- * - user memory: `~/.xopc/user/MEMORY.md`
3
+ * - shared memories: `~/.xopc/user/memories/MEMORY.md`
4
+ * - user profile: `~/.xopc/user/MEMORY.md`
5
5
  */
6
6
  export interface MemoryStoreConfig {
7
7
  workspaceDir: string;
8
- /** Absolute path to `…/agents/<id>/memories/` (not under markdown workspace). */
8
+ /** Absolute path to the shared user memories directory. */
9
9
  memoriesDir: string;
10
10
  /** Absolute path to global user memory (`~/.xopc/user/MEMORY.md`). */
11
11
  userMemoryPath: string;
@@ -21,7 +21,7 @@ export interface MemorySnapshot {
21
21
  memory: string;
22
22
  user: string;
23
23
  }
24
- export type MemoryKind = 'user_profile' | 'preference' | 'boundary' | 'relationship' | 'project_context' | 'commitment' | 'routine' | 'personal_logistics' | 'open_question' | 'milestone' | 'current_state' | 'agent_note' | 'workspace_fact' | 'daily_note' | 'session_summary' | 'derived_insight' | 'task_lesson' | 'tool_preference' | 'long_term_goal';
24
+ export type MemoryKind = 'user_profile' | 'preference' | 'boundary' | 'relationship' | 'project_context' | 'commitment' | 'routine' | 'personal_logistics' | 'open_question' | 'milestone' | 'current_state' | 'curated_note' | 'workspace_fact' | 'daily_note' | 'session_summary' | 'derived_insight' | 'task_lesson' | 'tool_preference' | 'long_term_goal';
25
25
  export type MemoryStatus = 'candidate' | 'active' | 'needs_review' | 'stale' | 'archived' | 'rejected';
26
26
  export type MemorySensitivity = 'normal' | 'personal' | 'secret' | 'regulated';
27
27
  export type MemoryExplicitness = 'explicit' | 'observed' | 'inferred';
@@ -40,7 +40,7 @@ export interface MemoryEvidence {
40
40
  confidence?: number;
41
41
  }
42
42
  export interface MemoryScope {
43
- agentId: string;
43
+ userId: string;
44
44
  workspaceId?: string;
45
45
  sessionKey?: string;
46
46
  projectId?: string;
@@ -61,8 +61,12 @@ export interface MemoryRecord {
61
61
  status?: MemoryStatus;
62
62
  canonicalKey?: string;
63
63
  scope: MemoryScope;
64
+ provenance: {
65
+ sourceAgentId: string;
66
+ };
64
67
  content: string;
65
68
  source: {
69
+ sourceInstanceId?: string;
66
70
  path?: string;
67
71
  lineStart?: number;
68
72
  lineEnd?: number;
@@ -1,12 +1,12 @@
1
1
  import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
- import { appendMemoryTraceEvent } from "../../../storage/sqlite/memory-records-repository.js";
3
+ import { appendMemoryTraceEvent, markMemoryRecordsConflicted } from "../../../storage/sqlite/memory-records-repository.js";
4
4
  import { attachMemoryEvidence, upsertKnowledgeSourceItems } from "../../../storage/sqlite/knowledge-repository.js";
5
5
  import "../../../storage/sqlite/index.js";
6
6
  import { nextMemoryReviewAt } from "../lifecycle.js";
7
7
  import { extractExplicitUnderstandingCorrectionContent } from "./correction.js";
8
8
  import { inferMemorySensitivity, redactSensitiveMemoryText } from "../sensitivity.js";
9
- import { createHash } from "node:crypto";
9
+ import { createHash, randomUUID } from "node:crypto";
10
10
  //#region src/agent/memory/understanding/service.ts
11
11
  init_logger();
12
12
  const log = createLogger("UserUnderstanding");
@@ -28,7 +28,7 @@ function inferKind(content) {
28
28
  if (/\b(project|repo|codebase|workspace)\b/i.test(content) || /项目|仓库|代码库/.test(content)) return "project_context";
29
29
  if (/\b(goal|plan|commit|deadline)\b/i.test(content) || /目标|计划|承诺|截止/.test(content)) return "commitment";
30
30
  if (/\b(next time|lesson|failed|error)\b/i.test(content) || /下次|教训|失败|错误/.test(content)) return "task_lesson";
31
- return "agent_note";
31
+ return "curated_note";
32
32
  }
33
33
  const SENSITIVITY_RANK = {
34
34
  normal: 0,
@@ -121,6 +121,10 @@ var UserUnderstandingService = class {
121
121
  let deduplicated = 0;
122
122
  let rejected = 0;
123
123
  const recordIds = [];
124
+ const createdRecords = [];
125
+ const correctionTargets = [...new Set(context.supersedesRecordIds ?? [])];
126
+ const conflictGroupId = correctionTargets.length > 1 ? randomUUID() : void 0;
127
+ if (conflictGroupId) markMemoryRecordsConflicted(correctionTargets, conflictGroupId);
124
128
  for (const candidate of candidates.slice(0, 10)) {
125
129
  const content = normalizeContent(candidate.content);
126
130
  const sensitivity = stricterSensitivity(content, candidate.sensitivity);
@@ -130,7 +134,7 @@ var UserUnderstandingService = class {
130
134
  }
131
135
  const evidenceText = context.sourceText ? redactSensitiveMemoryText(context.sourceText).slice(0, MAX_CANDIDATE_CHARS) : void 0;
132
136
  const key = candidate.canonicalKey ?? canonicalKey(candidate.kind, content);
133
- const supersedesRecordId = context.supersedesRecordIds && [...new Set(context.supersedesRecordIds)].length === 1 ? context.supersedesRecordIds[0] : void 0;
137
+ const supersedesRecordId = correctionTargets.length === 1 ? correctionTargets[0] : void 0;
134
138
  const existing = await this.options.list(key);
135
139
  const evidence = {
136
140
  ...context.sourceItemId ? { sourceItemId: context.sourceItemId } : {},
@@ -157,7 +161,7 @@ var UserUnderstandingService = class {
157
161
  content,
158
162
  canonicalKey: key,
159
163
  scope: context.agentId || context.sessionKey ? {
160
- agentId: context.agentId,
164
+ userId: "local-owner",
161
165
  sessionKey: context.sessionKey
162
166
  } : void 0,
163
167
  target: candidate.kind === "preference" ? "user" : "memory",
@@ -177,11 +181,19 @@ var UserUnderstandingService = class {
177
181
  durability: candidate.durability,
178
182
  explicitness: candidate.explicitness
179
183
  }),
180
- supersedesRecordId
184
+ supersedesRecordId,
185
+ conflictGroupId
181
186
  });
182
187
  if (write.success) {
183
188
  created += 1;
184
- if (write.record) recordIds.push(write.record.id);
189
+ if (write.record) {
190
+ recordIds.push(write.record.id);
191
+ createdRecords.push({
192
+ id: write.record.id,
193
+ content: write.record.content,
194
+ kind: write.record.kind
195
+ });
196
+ }
185
197
  if (write.record && context.sourceItemId) attachMemoryEvidence({
186
198
  recordId: write.record.id,
187
199
  sourceItemId: context.sourceItemId,
@@ -224,7 +236,8 @@ var UserUnderstandingService = class {
224
236
  proposed: candidates.length,
225
237
  created,
226
238
  deduplicated,
227
- rejected
239
+ rejected,
240
+ createdRecords
228
241
  };
229
242
  }
230
243
  };
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../../../src/agent/memory/understanding/service.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport {\n appendMemoryTraceEvent,\n attachMemoryEvidence,\n upsertKnowledgeSourceItems,\n} from '../../../storage/sqlite/index.js';\nimport { createLogger } from '../../../utils/logger.js';\nimport type {\n MemoryEvidence,\n MemoryKind,\n MemoryRecord,\n MemorySensitivity,\n MemoryWriteRequest,\n MemoryWriteResult,\n} from '../types.js';\nimport { nextMemoryReviewAt } from '../lifecycle.js';\nimport { extractExplicitUnderstandingCorrectionContent } from './correction.js';\nimport type { UnderstandingCandidate, UnderstandingReviewResult } from './types.js';\nimport { inferMemorySensitivity, redactSensitiveMemoryText } from '../sensitivity.js';\n\nconst log = createLogger('UserUnderstanding');\nconst MAX_CANDIDATE_CHARS = 600;\n\nconst EXPLICIT_PATTERNS: RegExp[] = [\n /\\b(?:please\\s+)?remember(?:\\s+that)?\\s+(.+)/i,\n /\\bkeep\\s+in\\s+mind(?:\\s+that)?\\s+(.+)/i,\n /(?:请)?记住[::\\s]*(.+)/,\n /以后(?:都)?(?:请)?[::\\s]*(.+)/,\n /下次(?:请)?[::\\s]*(.+)/,\n];\n\nfunction normalizeContent(raw: string): string {\n return raw\n .replace(/^[\"'“”‘’\\s]+|[\"'“”‘’\\s]+$/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, MAX_CANDIDATE_CHARS);\n}\n\nfunction inferKind(content: string): MemoryKind {\n if (/\\b(don't|do not|never|avoid)\\b/i.test(content) || /不要|别再|禁止|底线/.test(content)) {\n return 'boundary';\n }\n if (/\\b(prefer|preference|like)\\b/i.test(content) || /喜欢|偏好|习惯/.test(content)) {\n return 'preference';\n }\n if (/\\b(tool|command|pnpm|npm|git|ripgrep|rg)\\b/i.test(content) || /工具|命令/.test(content)) {\n return 'tool_preference';\n }\n if (/\\b(project|repo|codebase|workspace)\\b/i.test(content) || /项目|仓库|代码库/.test(content)) {\n return 'project_context';\n }\n if (/\\b(goal|plan|commit|deadline)\\b/i.test(content) || /目标|计划|承诺|截止/.test(content)) {\n return 'commitment';\n }\n if (/\\b(next time|lesson|failed|error)\\b/i.test(content) || /下次|教训|失败|错误/.test(content)) {\n return 'task_lesson';\n }\n return 'agent_note';\n}\n\nconst SENSITIVITY_RANK: Record<MemorySensitivity, number> = {\n normal: 0,\n personal: 1,\n regulated: 2,\n secret: 3,\n};\n\nfunction stricterSensitivity(content: string, declared: MemorySensitivity): MemorySensitivity {\n const inferred = inferMemorySensitivity(content);\n return SENSITIVITY_RANK[inferred] > SENSITIVITY_RANK[declared] ? inferred : declared;\n}\n\nfunction canonicalKey(kind: MemoryKind, content: string): string {\n const normalized = content\n .toLocaleLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, ' ')\n .trim();\n return `${kind}:${createHash('sha256').update(normalized).digest('hex').slice(0, 20)}`;\n}\n\nexport function extractExplicitUnderstandingCandidates(userContent: string): UnderstandingCandidate[] {\n const correction = extractExplicitUnderstandingCorrectionContent(userContent);\n if (correction) {\n const kind = inferKind(correction);\n return [{\n kind,\n content: correction,\n canonicalKey: canonicalKey(kind, correction),\n confidence: 0.95,\n importance: kind === 'boundary' ? 0.9 : 0.8,\n explicitness: 'explicit',\n durability: 'durable',\n sensitivity: inferMemorySensitivity(correction),\n disclosurePolicy: kind === 'boundary' ? 'silent' : 'referenceable',\n tags: ['user-understanding', 'explicit-user-correction'],\n }];\n }\n const lines = userContent.split(/\\r?\\n/).map((line) => line.trim()).filter(Boolean);\n for (const line of lines.length > 0 ? lines : [userContent.trim()]) {\n for (const pattern of EXPLICIT_PATTERNS) {\n const content = normalizeContent(pattern.exec(line)?.[1] ?? '');\n if (content.length < 8) continue;\n const kind = inferKind(content);\n return [{\n kind,\n content,\n canonicalKey: canonicalKey(kind, content),\n confidence: 0.92,\n importance: kind === 'boundary' ? 0.9 : 0.75,\n explicitness: 'explicit',\n durability: 'durable',\n sensitivity: inferMemorySensitivity(content),\n disclosurePolicy: kind === 'boundary' ? 'silent' : 'referenceable',\n tags: ['user-understanding', 'explicit-user-request'],\n }];\n }\n }\n return [];\n}\n\nexport interface UserUnderstandingServiceOptions {\n write: (request: MemoryWriteRequest) => Promise<MemoryWriteResult>;\n list: (canonicalKey: string) => Promise<MemoryRecord[]>;\n}\n\nexport class UserUnderstandingService {\n constructor(private readonly options: UserUnderstandingServiceOptions) {}\n\n async reviewTurn(params: {\n agentId?: string;\n userContent: string;\n assistantContent: string;\n sessionKey?: string;\n correctionTargetRecordIds?: string[];\n }): Promise<UnderstandingReviewResult> {\n const candidates = extractExplicitUnderstandingCandidates(params.userContent);\n const sourceText = `User:\\n${params.userContent.trim()}\\n\\nAssistant:\\n${params.assistantContent.trim()}`;\n const normalizedText = redactSensitiveMemoryText(sourceText);\n const contentHash = createHash('sha256').update(sourceText).digest('hex');\n const stored = upsertKnowledgeSourceItems([{\n sourceInstanceId: params.sessionKey ? `session:${params.sessionKey}` : 'session:unknown',\n externalId: contentHash,\n itemType: 'conversation_turn',\n authorRole: 'user',\n occurredAt: new Date().toISOString(),\n contentHash,\n normalizedText,\n metadata: params.sessionKey ? { sessionKey: params.sessionKey } : {},\n sensitivity: 'personal',\n retentionClass: 'bounded',\n synthesisStatus: 'pending',\n }]);\n const sourceItemId = stored.items[0]?.id;\n const result = await this.applyCandidates(candidates, {\n agentId: params.agentId,\n sessionKey: params.sessionKey,\n sourceItemId,\n sourceText: params.userContent,\n reviewSource: 'turn',\n supersedesRecordIds: params.correctionTargetRecordIds,\n });\n return { ...result, sourceItemId };\n }\n\n async applyCandidates(\n candidates: UnderstandingCandidate[],\n context: {\n agentId?: string;\n sessionKey?: string;\n sourceItemId?: string;\n sourceText?: string;\n reviewSource?: 'turn' | 'background';\n supersedesRecordIds?: string[];\n },\n ): Promise<Omit<UnderstandingReviewResult, 'sourceItemId'>> {\n const startedAt = Date.now();\n let created = 0;\n let deduplicated = 0;\n let rejected = 0;\n const recordIds: string[] = [];\n for (const candidate of candidates.slice(0, 10)) {\n const content = normalizeContent(candidate.content);\n const sensitivity = stricterSensitivity(content, candidate.sensitivity);\n if (\n content.length < 4\n || candidate.confidence < 0.55\n || sensitivity === 'secret'\n || sensitivity === 'regulated'\n ) {\n rejected += 1;\n continue;\n }\n const evidenceText = context.sourceText\n ? redactSensitiveMemoryText(context.sourceText).slice(0, MAX_CANDIDATE_CHARS)\n : undefined;\n const key = candidate.canonicalKey ?? canonicalKey(candidate.kind, content);\n const supersedesRecordId = context.supersedesRecordIds\n && [...new Set(context.supersedesRecordIds)].length === 1\n ? context.supersedesRecordIds[0]\n : undefined;\n const existing = await this.options.list(key);\n const evidence: MemoryEvidence = {\n ...(context.sourceItemId ? { sourceItemId: context.sourceItemId } : {}),\n relation: 'supports',\n ...(context.sessionKey ? { sessionKey: context.sessionKey } : {}),\n ...(evidenceText ? { sourceText: evidenceText } : {}),\n observedAt: new Date().toISOString(),\n confidence: candidate.confidence,\n };\n if (existing[0]) {\n deduplicated += 1;\n recordIds.push(existing[0].id);\n if (context.sourceItemId) {\n attachMemoryEvidence({\n recordId: existing[0].id,\n sourceItemId: context.sourceItemId,\n relation: 'supports',\n excerpt: evidenceText,\n confidence: candidate.confidence,\n });\n }\n continue;\n }\n const write = await this.options.write({\n kind: candidate.kind,\n content,\n canonicalKey: key,\n scope: context.agentId || context.sessionKey\n ? { agentId: context.agentId, sessionKey: context.sessionKey }\n : undefined,\n target: candidate.kind === 'preference' ? 'user' : 'memory',\n tags: [...new Set(['user-understanding', ...(candidate.tags ?? [])])],\n source: { provider: 'user-understanding' },\n confidence: candidate.confidence,\n status: 'candidate',\n sensitivity,\n explicitness: candidate.explicitness,\n durability: candidate.durability,\n importance: candidate.importance,\n disclosurePolicy: candidate.disclosurePolicy,\n evidence: [evidence],\n validFrom: candidate.validFrom,\n validTo: candidate.validTo,\n reviewAfter: nextMemoryReviewAt({\n durability: candidate.durability,\n explicitness: candidate.explicitness,\n }),\n supersedesRecordId,\n });\n if (write.success) {\n created += 1;\n if (write.record) recordIds.push(write.record.id);\n if (write.record && context.sourceItemId) {\n attachMemoryEvidence({\n recordId: write.record.id,\n sourceItemId: context.sourceItemId,\n relation: 'supports',\n excerpt: evidenceText,\n confidence: candidate.confidence,\n });\n }\n } else {\n rejected += 1;\n log.debug({ errorMessage: write.error, canonicalKey: key }, 'Understanding candidate was not stored');\n }\n }\n try {\n appendMemoryTraceEvent({\n sessionKey: context.sessionKey,\n phase: 'understanding',\n providerId: 'user-understanding',\n request: {\n ...(context.agentId ? { agentId: context.agentId } : {}),\n source: context.reviewSource ?? 'turn',\n proposed: candidates.length,\n created,\n deduplicated,\n rejected,\n },\n resultCount: created,\n selectedRecordIds: recordIds,\n durationMs: Date.now() - startedAt,\n });\n } catch (err) {\n log.debug({ err, sessionKey: context.sessionKey }, 'Understanding quality trace append failed');\n }\n return { proposed: candidates.length, created, deduplicated, rejected };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.js","names":[],"sources":["../../../../../src/agent/memory/understanding/service.ts"],"sourcesContent":["import { createHash, randomUUID } from 'node:crypto';\n\nimport {\n appendMemoryTraceEvent,\n attachMemoryEvidence,\n markMemoryRecordsConflicted,\n upsertKnowledgeSourceItems,\n} from '../../../storage/sqlite/index.js';\nimport { createLogger } from '../../../utils/logger.js';\nimport type {\n MemoryEvidence,\n MemoryKind,\n MemoryRecord,\n MemorySensitivity,\n MemoryWriteRequest,\n MemoryWriteResult,\n} from '../types.js';\nimport { nextMemoryReviewAt } from '../lifecycle.js';\nimport { extractExplicitUnderstandingCorrectionContent } from './correction.js';\nimport type { UnderstandingCandidate, UnderstandingReviewResult } from './types.js';\nimport { inferMemorySensitivity, redactSensitiveMemoryText } from '../sensitivity.js';\n\nconst log = createLogger('UserUnderstanding');\nconst MAX_CANDIDATE_CHARS = 600;\n\nconst EXPLICIT_PATTERNS: RegExp[] = [\n /\\b(?:please\\s+)?remember(?:\\s+that)?\\s+(.+)/i,\n /\\bkeep\\s+in\\s+mind(?:\\s+that)?\\s+(.+)/i,\n /(?:请)?记住[::\\s]*(.+)/,\n /以后(?:都)?(?:请)?[::\\s]*(.+)/,\n /下次(?:请)?[::\\s]*(.+)/,\n];\n\nfunction normalizeContent(raw: string): string {\n return raw\n .replace(/^[\"'“”‘’\\s]+|[\"'“”‘’\\s]+$/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, MAX_CANDIDATE_CHARS);\n}\n\nfunction inferKind(content: string): MemoryKind {\n if (/\\b(don't|do not|never|avoid)\\b/i.test(content) || /不要|别再|禁止|底线/.test(content)) {\n return 'boundary';\n }\n if (/\\b(prefer|preference|like)\\b/i.test(content) || /喜欢|偏好|习惯/.test(content)) {\n return 'preference';\n }\n if (/\\b(tool|command|pnpm|npm|git|ripgrep|rg)\\b/i.test(content) || /工具|命令/.test(content)) {\n return 'tool_preference';\n }\n if (/\\b(project|repo|codebase|workspace)\\b/i.test(content) || /项目|仓库|代码库/.test(content)) {\n return 'project_context';\n }\n if (/\\b(goal|plan|commit|deadline)\\b/i.test(content) || /目标|计划|承诺|截止/.test(content)) {\n return 'commitment';\n }\n if (/\\b(next time|lesson|failed|error)\\b/i.test(content) || /下次|教训|失败|错误/.test(content)) {\n return 'task_lesson';\n }\n return 'curated_note';\n}\n\nconst SENSITIVITY_RANK: Record<MemorySensitivity, number> = {\n normal: 0,\n personal: 1,\n regulated: 2,\n secret: 3,\n};\n\nfunction stricterSensitivity(content: string, declared: MemorySensitivity): MemorySensitivity {\n const inferred = inferMemorySensitivity(content);\n return SENSITIVITY_RANK[inferred] > SENSITIVITY_RANK[declared] ? inferred : declared;\n}\n\nfunction canonicalKey(kind: MemoryKind, content: string): string {\n const normalized = content\n .toLocaleLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, ' ')\n .trim();\n return `${kind}:${createHash('sha256').update(normalized).digest('hex').slice(0, 20)}`;\n}\n\nexport function extractExplicitUnderstandingCandidates(userContent: string): UnderstandingCandidate[] {\n const correction = extractExplicitUnderstandingCorrectionContent(userContent);\n if (correction) {\n const kind = inferKind(correction);\n return [{\n kind,\n content: correction,\n canonicalKey: canonicalKey(kind, correction),\n confidence: 0.95,\n importance: kind === 'boundary' ? 0.9 : 0.8,\n explicitness: 'explicit',\n durability: 'durable',\n sensitivity: inferMemorySensitivity(correction),\n disclosurePolicy: kind === 'boundary' ? 'silent' : 'referenceable',\n tags: ['user-understanding', 'explicit-user-correction'],\n }];\n }\n const lines = userContent.split(/\\r?\\n/).map((line) => line.trim()).filter(Boolean);\n for (const line of lines.length > 0 ? lines : [userContent.trim()]) {\n for (const pattern of EXPLICIT_PATTERNS) {\n const content = normalizeContent(pattern.exec(line)?.[1] ?? '');\n if (content.length < 8) continue;\n const kind = inferKind(content);\n return [{\n kind,\n content,\n canonicalKey: canonicalKey(kind, content),\n confidence: 0.92,\n importance: kind === 'boundary' ? 0.9 : 0.75,\n explicitness: 'explicit',\n durability: 'durable',\n sensitivity: inferMemorySensitivity(content),\n disclosurePolicy: kind === 'boundary' ? 'silent' : 'referenceable',\n tags: ['user-understanding', 'explicit-user-request'],\n }];\n }\n }\n return [];\n}\n\nexport interface UserUnderstandingServiceOptions {\n write: (request: MemoryWriteRequest) => Promise<MemoryWriteResult>;\n list: (canonicalKey: string) => Promise<MemoryRecord[]>;\n}\n\nexport class UserUnderstandingService {\n constructor(private readonly options: UserUnderstandingServiceOptions) {}\n\n async reviewTurn(params: {\n agentId?: string;\n userContent: string;\n assistantContent: string;\n sessionKey?: string;\n correctionTargetRecordIds?: string[];\n }): Promise<UnderstandingReviewResult> {\n const candidates = extractExplicitUnderstandingCandidates(params.userContent);\n const sourceText = `User:\\n${params.userContent.trim()}\\n\\nAssistant:\\n${params.assistantContent.trim()}`;\n const normalizedText = redactSensitiveMemoryText(sourceText);\n const contentHash = createHash('sha256').update(sourceText).digest('hex');\n const stored = upsertKnowledgeSourceItems([{\n sourceInstanceId: params.sessionKey ? `session:${params.sessionKey}` : 'session:unknown',\n externalId: contentHash,\n itemType: 'conversation_turn',\n authorRole: 'user',\n occurredAt: new Date().toISOString(),\n contentHash,\n normalizedText,\n metadata: params.sessionKey ? { sessionKey: params.sessionKey } : {},\n sensitivity: 'personal',\n retentionClass: 'bounded',\n synthesisStatus: 'pending',\n }]);\n const sourceItemId = stored.items[0]?.id;\n const result = await this.applyCandidates(candidates, {\n agentId: params.agentId,\n sessionKey: params.sessionKey,\n sourceItemId,\n sourceText: params.userContent,\n reviewSource: 'turn',\n supersedesRecordIds: params.correctionTargetRecordIds,\n });\n return { ...result, sourceItemId };\n }\n\n async applyCandidates(\n candidates: UnderstandingCandidate[],\n context: {\n agentId?: string;\n sessionKey?: string;\n sourceItemId?: string;\n sourceText?: string;\n reviewSource?: 'turn' | 'background';\n supersedesRecordIds?: string[];\n },\n ): Promise<Omit<UnderstandingReviewResult, 'sourceItemId'>> {\n const startedAt = Date.now();\n let created = 0;\n let deduplicated = 0;\n let rejected = 0;\n const recordIds: string[] = [];\n const createdRecords: UnderstandingReviewResult['createdRecords'] = [];\n const correctionTargets = [...new Set(context.supersedesRecordIds ?? [])];\n const conflictGroupId = correctionTargets.length > 1 ? randomUUID() : undefined;\n if (conflictGroupId) markMemoryRecordsConflicted(correctionTargets, conflictGroupId);\n for (const candidate of candidates.slice(0, 10)) {\n const content = normalizeContent(candidate.content);\n const sensitivity = stricterSensitivity(content, candidate.sensitivity);\n if (\n content.length < 4\n || candidate.confidence < 0.55\n || sensitivity === 'secret'\n || sensitivity === 'regulated'\n ) {\n rejected += 1;\n continue;\n }\n const evidenceText = context.sourceText\n ? redactSensitiveMemoryText(context.sourceText).slice(0, MAX_CANDIDATE_CHARS)\n : undefined;\n const key = candidate.canonicalKey ?? canonicalKey(candidate.kind, content);\n const supersedesRecordId = correctionTargets.length === 1\n ? correctionTargets[0]\n : undefined;\n const existing = await this.options.list(key);\n const evidence: MemoryEvidence = {\n ...(context.sourceItemId ? { sourceItemId: context.sourceItemId } : {}),\n relation: 'supports',\n ...(context.sessionKey ? { sessionKey: context.sessionKey } : {}),\n ...(evidenceText ? { sourceText: evidenceText } : {}),\n observedAt: new Date().toISOString(),\n confidence: candidate.confidence,\n };\n if (existing[0]) {\n deduplicated += 1;\n recordIds.push(existing[0].id);\n if (context.sourceItemId) {\n attachMemoryEvidence({\n recordId: existing[0].id,\n sourceItemId: context.sourceItemId,\n relation: 'supports',\n excerpt: evidenceText,\n confidence: candidate.confidence,\n });\n }\n continue;\n }\n const write = await this.options.write({\n kind: candidate.kind,\n content,\n canonicalKey: key,\n scope: context.agentId || context.sessionKey\n ? { userId: 'local-owner', sessionKey: context.sessionKey }\n : undefined,\n target: candidate.kind === 'preference' ? 'user' : 'memory',\n tags: [...new Set(['user-understanding', ...(candidate.tags ?? [])])],\n source: { provider: 'user-understanding' },\n confidence: candidate.confidence,\n status: 'candidate',\n sensitivity,\n explicitness: candidate.explicitness,\n durability: candidate.durability,\n importance: candidate.importance,\n disclosurePolicy: candidate.disclosurePolicy,\n evidence: [evidence],\n validFrom: candidate.validFrom,\n validTo: candidate.validTo,\n reviewAfter: nextMemoryReviewAt({\n durability: candidate.durability,\n explicitness: candidate.explicitness,\n }),\n supersedesRecordId,\n conflictGroupId,\n });\n if (write.success) {\n created += 1;\n if (write.record) {\n recordIds.push(write.record.id);\n createdRecords.push({ id: write.record.id, content: write.record.content, kind: write.record.kind });\n }\n if (write.record && context.sourceItemId) {\n attachMemoryEvidence({\n recordId: write.record.id,\n sourceItemId: context.sourceItemId,\n relation: 'supports',\n excerpt: evidenceText,\n confidence: candidate.confidence,\n });\n }\n } else {\n rejected += 1;\n log.debug({ errorMessage: write.error, canonicalKey: key }, 'Understanding candidate was not stored');\n }\n }\n try {\n appendMemoryTraceEvent({\n sessionKey: context.sessionKey,\n phase: 'understanding',\n providerId: 'user-understanding',\n request: {\n ...(context.agentId ? { agentId: context.agentId } : {}),\n source: context.reviewSource ?? 'turn',\n proposed: candidates.length,\n created,\n deduplicated,\n rejected,\n },\n resultCount: created,\n selectedRecordIds: recordIds,\n durationMs: Date.now() - startedAt,\n });\n } catch (err) {\n log.debug({ err, sessionKey: context.sessionKey }, 'Understanding quality trace append failed');\n }\n return { proposed: candidates.length, created, deduplicated, rejected, createdRecords };\n }\n}\n"],"mappings":"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"}
@@ -19,4 +19,9 @@ export interface UnderstandingReviewResult {
19
19
  created: number;
20
20
  deduplicated: number;
21
21
  rejected: number;
22
+ createdRecords: Array<{
23
+ id: string;
24
+ content: string;
25
+ kind: MemoryKind;
26
+ }>;
22
27
  }
@@ -18,5 +18,5 @@ export declare class UserContextCoordinator {
18
18
  forgetSession(sessionKey: string): void;
19
19
  clear(): void;
20
20
  prepare(userMessage: AgentMessage, sessionKey: string): Promise<UserContextPlan>;
21
- afterTurn(sessionKey: string, userPlainText: string): Promise<void>;
21
+ afterTurn(sessionKey: string, userPlainText: string): Promise<import('./understanding/types.js').UnderstandingReviewResult | undefined>;
22
22
  }
@@ -30,6 +30,7 @@ var UserContextCoordinator = class {
30
30
  modelMessage: userMessage,
31
31
  items: [],
32
32
  rejected: [],
33
+ consentRequests: [],
33
34
  estimatedTokens: 0
34
35
  });
35
36
  const config = this.options.getConfig();
@@ -70,17 +71,20 @@ var UserContextCoordinator = class {
70
71
  });
71
72
  }
72
73
  async afterTurn(sessionKey, userPlainText) {
73
- if (!this.options.isEnabledForSession(sessionKey)) return;
74
+ if (!this.options.isEnabledForSession(sessionKey)) return void 0;
74
75
  const memoryManager = this.options.getMemoryManagerForSession(sessionKey);
75
76
  const assistantContent = this.options.getLastAssistantContent(sessionKey) ?? "";
76
77
  const correctionTargetRecordIds = this.correctionTargets.get(sessionKey);
77
78
  this.correctionTargets.delete(sessionKey);
78
79
  try {
79
- await memoryManager.captureTurnUnderstanding(userPlainText, assistantContent, {
80
+ const review = await memoryManager.captureTurnUnderstanding(userPlainText, assistantContent, {
80
81
  agentId: this.options.getAgentIdForSession(sessionKey),
81
82
  sessionId: sessionKey,
82
83
  correctionTargetRecordIds
83
84
  });
85
+ memoryManager.syncProvidersForTurn(userPlainText, assistantContent, { sessionId: sessionKey });
86
+ memoryManager.queuePrefetchAll(userPlainText, { sessionId: sessionKey });
87
+ return review;
84
88
  } catch (err) {
85
89
  log.warn({
86
90
  err,
@@ -1 +1 @@
1
- {"version":3,"file":"user-context-coordinator.js","names":[],"sources":["../../../../src/agent/memory/user-context-coordinator.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport { setLatestMemoryInjectFeedback } from '../../storage/sqlite/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { UserContextPlanner } from './context/planner.js';\nimport type { UserContextPlan } from './context/types.js';\nimport type { MemoryManager } from './manager.js';\nimport {\n shouldPlanUserContextThisTurn,\n} from './memory-config.js';\nimport { isExplicitUnderstandingCorrection } from './understanding/correction.js';\nimport { extractAgentUserPlainText } from './user-message-text.js';\n\nconst log = createLogger('UserContextCoordinator');\n\nexport interface UserContextCoordinatorOptions {\n getConfig: () => Config | undefined;\n isEnabledForSession: (sessionKey: string) => boolean;\n getAgentIdForSession: (sessionKey: string) => string;\n getMemoryManagerForSession: (sessionKey: string) => MemoryManager;\n getLastAssistantContent: (sessionKey: string) => string | null;\n}\n\nexport class UserContextCoordinator {\n private readonly userTurn = new Map<string, number>();\n private readonly correctionTargets = new Map<string, string[]>();\n private readonly planner = new UserContextPlanner();\n\n constructor(private readonly options: UserContextCoordinatorOptions) {}\n\n forgetSession(sessionKey: string): void {\n this.userTurn.delete(sessionKey);\n this.correctionTargets.delete(sessionKey);\n }\n\n clear(): void {\n this.userTurn.clear();\n this.correctionTargets.clear();\n }\n\n async prepare(userMessage: AgentMessage, sessionKey: string): Promise<UserContextPlan> {\n const empty = (): UserContextPlan => ({\n traceId: '',\n modelMessage: userMessage,\n items: [],\n rejected: [],\n estimatedTokens: 0,\n });\n const config = this.options.getConfig();\n if (!this.options.isEnabledForSession(sessionKey)) return empty();\n const query = extractAgentUserPlainText(userMessage);\n this.correctionTargets.delete(sessionKey);\n let excludedRecordIds: string[] | undefined;\n if (isExplicitUnderstandingCorrection(query)) {\n try {\n const trace = setLatestMemoryInjectFeedback({\n sessionKey,\n requireSelectedRecords: true,\n feedback: {\n outcome: 'not_helpful',\n source: 'system',\n reason: 'detected_explicit_user_correction',\n },\n });\n if (trace?.selectedRecordIds.length) {\n this.correctionTargets.set(sessionKey, trace.selectedRecordIds);\n excludedRecordIds = trace.selectedRecordIds;\n }\n } catch (err) {\n log.debug({ err, sessionKey }, 'Understanding correction feedback was not persisted');\n }\n }\n const turn = (this.userTurn.get(sessionKey) ?? 0) + 1;\n this.userTurn.set(sessionKey, turn);\n if (!shouldPlanUserContextThisTurn(config, turn)) return empty();\n return this.planner.plan({\n memoryManager: this.options.getMemoryManagerForSession(sessionKey),\n agentId: this.options.getAgentIdForSession(sessionKey),\n sessionKey,\n query,\n userMessage,\n excludedRecordIds,\n });\n }\n\n async afterTurn(sessionKey: string, userPlainText: string): Promise<void> {\n if (!this.options.isEnabledForSession(sessionKey)) return;\n const memoryManager = this.options.getMemoryManagerForSession(sessionKey);\n const assistantContent = this.options.getLastAssistantContent(sessionKey) ?? '';\n const correctionTargetRecordIds = this.correctionTargets.get(sessionKey);\n this.correctionTargets.delete(sessionKey);\n try {\n await memoryManager.captureTurnUnderstanding(\n userPlainText,\n assistantContent,\n {\n agentId: this.options.getAgentIdForSession(sessionKey),\n sessionId: sessionKey,\n correctionTargetRecordIds,\n },\n );\n } catch (err) {\n log.warn({ err, sessionKey }, 'Turn understanding capture failed');\n }\n void memoryManager.syncProvidersForTurn(userPlainText, assistantContent, { sessionId: sessionKey });\n memoryManager.queuePrefetchAll(userPlainText, { sessionId: sessionKey });\n }\n}\n"],"mappings":";;;;;;;;;aAIqD;AAUrD,MAAM,MAAM,aAAa,yBAAyB;AAUlD,IAAa,yBAAb,MAAoC;CAClC,2BAA4B,IAAI,KAAqB;CACrD,oCAAqC,IAAI,KAAuB;CAChE,UAA2B,IAAI,oBAAoB;CAEnD,YAAY,SAAyD;AAAxC,OAAA,UAAA;;CAE7B,cAAc,YAA0B;AACtC,OAAK,SAAS,OAAO,WAAW;AAChC,OAAK,kBAAkB,OAAO,WAAW;;CAG3C,QAAc;AACZ,OAAK,SAAS,OAAO;AACrB,OAAK,kBAAkB,OAAO;;CAGhC,MAAM,QAAQ,aAA2B,YAA8C;EACrF,MAAM,eAAgC;GACpC,SAAS;GACT,cAAc;GACd,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,iBAAiB;GAClB;EACD,MAAM,SAAS,KAAK,QAAQ,WAAW;AACvC,MAAI,CAAC,KAAK,QAAQ,oBAAoB,WAAW,CAAE,QAAO,OAAO;EACjE,MAAM,QAAQ,0BAA0B,YAAY;AACpD,OAAK,kBAAkB,OAAO,WAAW;EACzC,IAAI;AACJ,MAAI,kCAAkC,MAAM,CAC1C,KAAI;GACF,MAAM,QAAQ,8BAA8B;IAC1C;IACA,wBAAwB;IACxB,UAAU;KACR,SAAS;KACT,QAAQ;KACR,QAAQ;KACT;IACF,CAAC;AACF,OAAI,OAAO,kBAAkB,QAAQ;AACnC,SAAK,kBAAkB,IAAI,YAAY,MAAM,kBAAkB;AAC/D,wBAAoB,MAAM;;WAErB,KAAK;AACZ,OAAI,MAAM;IAAE;IAAK;IAAY,EAAE,sDAAsD;;EAGzF,MAAM,QAAQ,KAAK,SAAS,IAAI,WAAW,IAAI,KAAK;AACpD,OAAK,SAAS,IAAI,YAAY,KAAK;AACnC,MAAI,CAAC,8BAA8B,QAAQ,KAAK,CAAE,QAAO,OAAO;AAChE,SAAO,KAAK,QAAQ,KAAK;GACvB,eAAe,KAAK,QAAQ,2BAA2B,WAAW;GAClE,SAAS,KAAK,QAAQ,qBAAqB,WAAW;GACtD;GACA;GACA;GACA;GACD,CAAC;;CAGJ,MAAM,UAAU,YAAoB,eAAsC;AACxE,MAAI,CAAC,KAAK,QAAQ,oBAAoB,WAAW,CAAE;EACnD,MAAM,gBAAgB,KAAK,QAAQ,2BAA2B,WAAW;EACzE,MAAM,mBAAmB,KAAK,QAAQ,wBAAwB,WAAW,IAAI;EAC7E,MAAM,4BAA4B,KAAK,kBAAkB,IAAI,WAAW;AACxE,OAAK,kBAAkB,OAAO,WAAW;AACzC,MAAI;AACF,SAAM,cAAc,yBAClB,eACA,kBACA;IACE,SAAS,KAAK,QAAQ,qBAAqB,WAAW;IACtD,WAAW;IACX;IACD,CACF;WACM,KAAK;AACZ,OAAI,KAAK;IAAE;IAAK;IAAY,EAAE,oCAAoC;;AAE/D,gBAAc,qBAAqB,eAAe,kBAAkB,EAAE,WAAW,YAAY,CAAC;AACnG,gBAAc,iBAAiB,eAAe,EAAE,WAAW,YAAY,CAAC"}
1
+ {"version":3,"file":"user-context-coordinator.js","names":[],"sources":["../../../../src/agent/memory/user-context-coordinator.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport { setLatestMemoryInjectFeedback } from '../../storage/sqlite/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { UserContextPlanner } from './context/planner.js';\nimport type { UserContextPlan } from './context/types.js';\nimport type { MemoryManager } from './manager.js';\nimport {\n shouldPlanUserContextThisTurn,\n} from './memory-config.js';\nimport { isExplicitUnderstandingCorrection } from './understanding/correction.js';\nimport { extractAgentUserPlainText } from './user-message-text.js';\n\nconst log = createLogger('UserContextCoordinator');\n\nexport interface UserContextCoordinatorOptions {\n getConfig: () => Config | undefined;\n isEnabledForSession: (sessionKey: string) => boolean;\n getAgentIdForSession: (sessionKey: string) => string;\n getMemoryManagerForSession: (sessionKey: string) => MemoryManager;\n getLastAssistantContent: (sessionKey: string) => string | null;\n}\n\nexport class UserContextCoordinator {\n private readonly userTurn = new Map<string, number>();\n private readonly correctionTargets = new Map<string, string[]>();\n private readonly planner = new UserContextPlanner();\n\n constructor(private readonly options: UserContextCoordinatorOptions) {}\n\n forgetSession(sessionKey: string): void {\n this.userTurn.delete(sessionKey);\n this.correctionTargets.delete(sessionKey);\n }\n\n clear(): void {\n this.userTurn.clear();\n this.correctionTargets.clear();\n }\n\n async prepare(userMessage: AgentMessage, sessionKey: string): Promise<UserContextPlan> {\n const empty = (): UserContextPlan => ({\n traceId: '',\n modelMessage: userMessage,\n items: [],\n rejected: [],\n consentRequests: [],\n estimatedTokens: 0,\n });\n const config = this.options.getConfig();\n if (!this.options.isEnabledForSession(sessionKey)) return empty();\n const query = extractAgentUserPlainText(userMessage);\n this.correctionTargets.delete(sessionKey);\n let excludedRecordIds: string[] | undefined;\n if (isExplicitUnderstandingCorrection(query)) {\n try {\n const trace = setLatestMemoryInjectFeedback({\n sessionKey,\n requireSelectedRecords: true,\n feedback: {\n outcome: 'not_helpful',\n source: 'system',\n reason: 'detected_explicit_user_correction',\n },\n });\n if (trace?.selectedRecordIds.length) {\n this.correctionTargets.set(sessionKey, trace.selectedRecordIds);\n excludedRecordIds = trace.selectedRecordIds;\n }\n } catch (err) {\n log.debug({ err, sessionKey }, 'Understanding correction feedback was not persisted');\n }\n }\n const turn = (this.userTurn.get(sessionKey) ?? 0) + 1;\n this.userTurn.set(sessionKey, turn);\n if (!shouldPlanUserContextThisTurn(config, turn)) return empty();\n return this.planner.plan({\n memoryManager: this.options.getMemoryManagerForSession(sessionKey),\n agentId: this.options.getAgentIdForSession(sessionKey),\n sessionKey,\n query,\n userMessage,\n excludedRecordIds,\n });\n }\n\n async afterTurn(sessionKey: string, userPlainText: string): Promise<import('./understanding/types.js').UnderstandingReviewResult | undefined> {\n if (!this.options.isEnabledForSession(sessionKey)) return undefined;\n const memoryManager = this.options.getMemoryManagerForSession(sessionKey);\n const assistantContent = this.options.getLastAssistantContent(sessionKey) ?? '';\n const correctionTargetRecordIds = this.correctionTargets.get(sessionKey);\n this.correctionTargets.delete(sessionKey);\n try {\n const review = await memoryManager.captureTurnUnderstanding(\n userPlainText,\n assistantContent,\n {\n agentId: this.options.getAgentIdForSession(sessionKey),\n sessionId: sessionKey,\n correctionTargetRecordIds,\n },\n );\n void memoryManager.syncProvidersForTurn(userPlainText, assistantContent, { sessionId: sessionKey });\n memoryManager.queuePrefetchAll(userPlainText, { sessionId: sessionKey });\n return review;\n } catch (err) {\n log.warn({ err, sessionKey }, 'Turn understanding capture failed');\n }\n void memoryManager.syncProvidersForTurn(userPlainText, assistantContent, { sessionId: sessionKey });\n memoryManager.queuePrefetchAll(userPlainText, { sessionId: sessionKey });\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;aAIqD;AAUrD,MAAM,MAAM,aAAa,yBAAyB;AAUlD,IAAa,yBAAb,MAAoC;CAClC,2BAA4B,IAAI,KAAqB;CACrD,oCAAqC,IAAI,KAAuB;CAChE,UAA2B,IAAI,oBAAoB;CAEnD,YAAY,SAAyD;AAAxC,OAAA,UAAA;;CAE7B,cAAc,YAA0B;AACtC,OAAK,SAAS,OAAO,WAAW;AAChC,OAAK,kBAAkB,OAAO,WAAW;;CAG3C,QAAc;AACZ,OAAK,SAAS,OAAO;AACrB,OAAK,kBAAkB,OAAO;;CAGhC,MAAM,QAAQ,aAA2B,YAA8C;EACrF,MAAM,eAAgC;GACpC,SAAS;GACT,cAAc;GACd,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,iBAAiB,EAAE;GACnB,iBAAiB;GAClB;EACD,MAAM,SAAS,KAAK,QAAQ,WAAW;AACvC,MAAI,CAAC,KAAK,QAAQ,oBAAoB,WAAW,CAAE,QAAO,OAAO;EACjE,MAAM,QAAQ,0BAA0B,YAAY;AACpD,OAAK,kBAAkB,OAAO,WAAW;EACzC,IAAI;AACJ,MAAI,kCAAkC,MAAM,CAC1C,KAAI;GACF,MAAM,QAAQ,8BAA8B;IAC1C;IACA,wBAAwB;IACxB,UAAU;KACR,SAAS;KACT,QAAQ;KACR,QAAQ;KACT;IACF,CAAC;AACF,OAAI,OAAO,kBAAkB,QAAQ;AACnC,SAAK,kBAAkB,IAAI,YAAY,MAAM,kBAAkB;AAC/D,wBAAoB,MAAM;;WAErB,KAAK;AACZ,OAAI,MAAM;IAAE;IAAK;IAAY,EAAE,sDAAsD;;EAGzF,MAAM,QAAQ,KAAK,SAAS,IAAI,WAAW,IAAI,KAAK;AACpD,OAAK,SAAS,IAAI,YAAY,KAAK;AACnC,MAAI,CAAC,8BAA8B,QAAQ,KAAK,CAAE,QAAO,OAAO;AAChE,SAAO,KAAK,QAAQ,KAAK;GACvB,eAAe,KAAK,QAAQ,2BAA2B,WAAW;GAClE,SAAS,KAAK,QAAQ,qBAAqB,WAAW;GACtD;GACA;GACA;GACA;GACD,CAAC;;CAGJ,MAAM,UAAU,YAAoB,eAA0G;AAC5I,MAAI,CAAC,KAAK,QAAQ,oBAAoB,WAAW,CAAE,QAAO,KAAA;EAC1D,MAAM,gBAAgB,KAAK,QAAQ,2BAA2B,WAAW;EACzE,MAAM,mBAAmB,KAAK,QAAQ,wBAAwB,WAAW,IAAI;EAC7E,MAAM,4BAA4B,KAAK,kBAAkB,IAAI,WAAW;AACxE,OAAK,kBAAkB,OAAO,WAAW;AACzC,MAAI;GACF,MAAM,SAAS,MAAM,cAAc,yBACjC,eACA,kBACA;IACE,SAAS,KAAK,QAAQ,qBAAqB,WAAW;IACtD,WAAW;IACX;IACD,CACF;AACI,iBAAc,qBAAqB,eAAe,kBAAkB,EAAE,WAAW,YAAY,CAAC;AACnG,iBAAc,iBAAiB,eAAe,EAAE,WAAW,YAAY,CAAC;AACxE,UAAO;WACA,KAAK;AACZ,OAAI,KAAK;IAAE;IAAK;IAAY,EAAE,oCAAoC;;AAE/D,gBAAc,qBAAqB,eAAe,kBAAkB,EAAE,WAAW,YAAY,CAAC;AACnG,gBAAc,iBAAiB,eAAe,EAAE,WAAW,YAAY,CAAC"}
@@ -84,7 +84,7 @@ var AgentOrchestrator = class {
84
84
  workspaceDir: scope.workspaceDir,
85
85
  dreamingRoot: scope.memoriesDir,
86
86
  config: resolved.phases.rem,
87
- sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy,
87
+ sensitiveWritePolicy: cfg.userContext.privacy.sensitiveWritePolicy,
88
88
  promotionWritePolicy: resolved.promotionWritePolicy.decision
89
89
  });
90
90
  const event = {
@@ -103,7 +103,7 @@ var AgentOrchestrator = class {
103
103
  workspaceDir: scope.workspaceDir,
104
104
  dreamingRoot: scope.memoriesDir,
105
105
  config: resolved.phases.deep,
106
- sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy,
106
+ sensitiveWritePolicy: cfg.userContext.privacy.sensitiveWritePolicy,
107
107
  memoryManager: this.agentManager.getMemoryManagerForSession(sessionKey)
108
108
  });
109
109
  const event = {