@xopcai/xopc 0.0.140 → 0.0.142

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 (250) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DtONoxBN.js → agent-avatar-dicebear-BawPxiu5.js} +1 -1
  4. package/dist/gateway/static/root/assets/agents-CyvCIHnB.js +2 -0
  5. package/dist/gateway/static/root/assets/{app-management-settings-panel-BRBxLECY.js → app-management-settings-panel-81xd1p9R.js} +1 -1
  6. package/dist/gateway/static/root/assets/{appearance-settings-ChvyuSEt.js → appearance-settings-DYeQsYU8.js} +1 -1
  7. package/dist/gateway/static/root/assets/{apps-page-DgHWTnjs.js → apps-page-DK_Vx6nl.js} +1 -1
  8. package/dist/gateway/static/root/assets/{archive-plugin-CdIoagem.js → archive-plugin-D_oa7oti.js} +1 -1
  9. package/dist/gateway/static/root/assets/{attachment-load-Ch411Kht.js → attachment-load-Cd-bwI2N.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automation-suggestion-card-SVq27yw2.js → automation-suggestion-card-B1LV3YYv.js} +1 -1
  11. package/dist/gateway/static/root/assets/automations-page-fzrovqhv.js +4 -0
  12. package/dist/gateway/static/root/assets/{binary-plugins-D8cV-emn.js → binary-plugins-O8svLKWw.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-CXDkby6y.js → block-editor-Dhj5f4Bx.js} +47 -47
  14. package/dist/gateway/static/root/assets/browser-settings-page-BDn-n-UB.js +8 -0
  15. package/dist/gateway/static/root/assets/{capability-presets-api-DLxI--Ge.js → capability-presets-api-dJy1Eqgx.js} +1 -1
  16. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-DKyRbnlH.js → capability-presets-settings-panel-Co5ipo_Q.js} +1 -1
  17. package/dist/gateway/static/root/assets/{channel-recipient-api-DllrPmp-.js → channel-recipient-api-Bfuhp2ty.js} +1 -1
  18. package/dist/gateway/static/root/assets/channels-settings-BWlpaxg9.js +1 -0
  19. package/dist/gateway/static/root/assets/channels-status-swr-D_jkIZLV.js +1 -0
  20. package/dist/gateway/static/root/assets/connectors-page-BcekbW4q.js +2 -0
  21. package/dist/gateway/static/root/assets/{desktop-pet-Bz9ommjr.js → desktop-pet-DFMfIb5F.js} +1 -1
  22. package/dist/gateway/static/root/assets/{desktop-pet-settings-BnLgxgoR.js → desktop-pet-settings-BJCUuL8Y.js} +1 -1
  23. package/dist/gateway/static/root/assets/{directory-picker-path-field-DLsCwFaf.js → directory-picker-path-field-BrYt1gAr.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dreaming-settings-BzkF1-XT.js → dreaming-settings-BN1Z2mIo.js} +3 -3
  25. package/dist/gateway/static/root/assets/{extension-debug-page-CdERvf3L.js → extension-debug-page-Bh630pLD.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-D1fz474Z.js → extension-page-B-1KxvVy.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-DoQMkNOK.js → extension-settings-page-BF9NACI3.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-BID89uCH.js → fetch-B1WtuprY.js} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-config-api-Rygo8UAs.js → gateway-config-api-De2N821l.js} +1 -1
  30. package/dist/gateway/static/root/assets/{gateway-settings-kb8KIeQL.js → gateway-settings-DN9sNREz.js} +1 -1
  31. package/dist/gateway/static/root/assets/{gateway-startup-retry-BkrLLlpE.js → gateway-startup-retry-nEujFSDj.js} +1 -1
  32. package/dist/gateway/static/root/assets/goal-create-dialog-BpoQW8cD.js +1 -0
  33. package/dist/gateway/static/root/assets/goal-detail-page-CBRSPd0b.js +4 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-BuY6-l0a.js → goals-config-api-DUy3eEse.js} +1 -1
  35. package/dist/gateway/static/root/assets/goals-page-BCcBi407.js +2 -0
  36. package/dist/gateway/static/root/assets/{goals-settings-DoH5fZWo.js → goals-settings-pkTXzXkh.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-BqDs48B-.js → heartbeat-settings-ezsufgLQ.js} +1 -1
  38. package/dist/gateway/static/root/assets/{index-CrPRlGMg.js → index-DcUaXYeb.js} +65 -65
  39. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CVIwwM15.js +1 -0
  40. package/dist/gateway/static/root/assets/logs-page-DQtTRXtj.js +7 -0
  41. package/dist/gateway/static/root/assets/{markdown-split-CSt32FWE.js → markdown-split-B_6us9j7.js} +1 -1
  42. package/dist/gateway/static/root/assets/{media-plugins-ByItHxBj.js → media-plugins-D_fryIyj.js} +1 -1
  43. package/dist/gateway/static/root/assets/messages-BXNELNBa.js +3 -0
  44. package/dist/gateway/static/root/assets/models-hub-panel-BP2M9n6Q.js +2 -0
  45. package/dist/gateway/static/root/assets/notes-page-CspveYaO.js +1 -0
  46. package/dist/gateway/static/root/assets/notes-workbench-BHwzJ0OC.js +2 -0
  47. package/dist/gateway/static/root/assets/{page-tabs-DOfMaq_L.js → page-tabs-D_8jGlqx.js} +1 -1
  48. package/dist/gateway/static/root/assets/{preview-open-alternatives-BArxASu7.js → preview-open-alternatives-BBLMK8Mp.js} +1 -1
  49. package/dist/gateway/static/root/assets/project-detail-page-Dy3rsobs.js +1 -0
  50. package/dist/gateway/static/root/assets/projects-page-CWKpPE0L.js +1 -0
  51. package/dist/gateway/static/root/assets/remote-access-hub-CqNRyXEo.js +1 -0
  52. package/dist/gateway/static/root/assets/{save-bar-controls-BRxlkhG8.js → save-bar-controls-DVS3FR5r.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schedule-field-BzM1iyOc.js → schedule-field-D6vKd6-T.js} +1 -1
  54. package/dist/gateway/static/root/assets/{schema-form-ChVcm0DX.js → schema-form-BPy4lbIh.js} +1 -1
  55. package/dist/gateway/static/root/assets/sessions-page-MEME7ivF.js +1 -0
  56. package/dist/gateway/static/root/assets/settings-advanced-gate-JVd0qaSF.js +1 -0
  57. package/dist/gateway/static/root/assets/{settings-collapsible-section-BcD9xrvY.js → settings-collapsible-section-WzdikxPt.js} +1 -1
  58. package/dist/gateway/static/root/assets/{settings-form-section-Cu30CXVl.js → settings-form-section-CvfzhBV-.js} +1 -1
  59. package/dist/gateway/static/root/assets/{settings-loading-skeleton-Cfd37IYb.js → settings-loading-skeleton-BxR-Ulhi.js} +1 -1
  60. package/dist/gateway/static/root/assets/{settings-page-EINHyzLo.js → settings-page-DYEbB1EV.js} +1 -1
  61. package/dist/gateway/static/root/assets/{settings-page-layout-C15zixct.js → settings-page-layout-CKefvbYi.js} +1 -1
  62. package/dist/gateway/static/root/assets/{setup-status-panel-Bu7SdpD4.js → setup-status-panel-dWN8BJ3z.js} +1 -1
  63. package/dist/gateway/static/root/assets/{share-preview-page-CjjAFV-v.js → share-preview-page-D8foINzP.js} +1 -1
  64. package/dist/gateway/static/root/assets/shares-settings-Tgbv1s7G.js +1 -0
  65. package/dist/gateway/static/root/assets/skill-reload-api-D_YK0b_Z.js +1 -0
  66. package/dist/gateway/static/root/assets/skills-page-DGytfoZK.js +2 -0
  67. package/dist/gateway/static/root/assets/{system-settings-panel-DlQMtzPf.js → system-settings-panel-BokgAgf7.js} +1 -1
  68. package/dist/gateway/static/root/assets/{typed-models-lib-BS1BwExE.js → typed-models-lib-BwHlNL3L.js} +1 -1
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-EA4hfbsP.js → use-channel-catalog-DR11ap3A.js} +1 -1
  70. package/dist/gateway/static/root/assets/{user-profile-settings-panel-B7RCdmSp.js → user-profile-settings-panel-8YtygcJp.js} +1 -1
  71. package/dist/gateway/static/root/assets/{utils-BrhEgVaa.js → utils-BKUWB-TT.js} +1 -1
  72. package/dist/gateway/static/root/assets/voice-api-key-field-BVH71EFf.js +1 -0
  73. package/dist/gateway/static/root/assets/work-item-detail-page-JeTE7XNM.js +1 -0
  74. package/dist/gateway/static/root/assets/workflow-run-setup-panel-CL_rnAUB.js +3 -0
  75. package/dist/gateway/static/root/assets/{workflow-start-dialog-BZCY7N42.js → workflow-start-dialog-_u8Uc1ze.js} +1 -1
  76. package/dist/gateway/static/root/assets/workflows-page-ixgk_y1l.js +18 -0
  77. package/dist/gateway/static/root/index.html +4 -4
  78. package/dist/package.js +1 -1
  79. package/dist/src/agent/agent-manager.js +13 -21
  80. package/dist/src/agent/agent-manager.js.map +1 -1
  81. package/dist/src/agent/background-review/run-background-review.js +1 -0
  82. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  83. package/dist/src/agent/embedded/session-runner.js +5 -5
  84. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  85. package/dist/src/agent/embedded/xopc-auth-storage.d.ts +4 -3
  86. package/dist/src/agent/embedded/xopc-auth-storage.js +6 -6
  87. package/dist/src/agent/embedded/xopc-auth-storage.js.map +1 -1
  88. package/dist/src/agent/embedded/xopc-stream-bridge.js +1 -0
  89. package/dist/src/agent/embedded/xopc-stream-bridge.js.map +1 -1
  90. package/dist/src/agent/goals/checklist-judge.js +3 -3
  91. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  92. package/dist/src/agent/goals/judge.js +2 -2
  93. package/dist/src/agent/goals/judge.js.map +1 -1
  94. package/dist/src/agent/image/understanding/pi-ai-provider.js +2 -2
  95. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  96. package/dist/src/agent/memory/access-policy.d.ts +12 -0
  97. package/dist/src/agent/memory/access-policy.js +44 -0
  98. package/dist/src/agent/memory/access-policy.js.map +1 -0
  99. package/dist/src/agent/memory/builtin-provider.d.ts +4 -1
  100. package/dist/src/agent/memory/builtin-provider.js +51 -16
  101. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  102. package/dist/src/agent/memory/compaction.js +2 -2
  103. package/dist/src/agent/memory/compaction.js.map +1 -1
  104. package/dist/src/agent/memory/context/planner.d.ts +1 -0
  105. package/dist/src/agent/memory/context/planner.js +9 -5
  106. package/dist/src/agent/memory/context/planner.js.map +1 -1
  107. package/dist/src/agent/memory/create-memory-manager.d.ts +1 -1
  108. package/dist/src/agent/memory/create-memory-manager.js +8 -5
  109. package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
  110. package/dist/src/agent/memory/dreaming/config.d.ts +2 -0
  111. package/dist/src/agent/memory/dreaming/config.js +13 -1
  112. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  113. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +2 -0
  114. package/dist/src/agent/memory/dreaming/deep-promotion.js +24 -3
  115. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  116. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +1 -0
  117. package/dist/src/agent/memory/dreaming/light-sweep.js +184 -16
  118. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  119. package/dist/src/agent/memory/dreaming/promotion-lifecycle.d.ts +30 -0
  120. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +85 -0
  121. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js.map +1 -0
  122. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +4 -0
  123. package/dist/src/agent/memory/dreaming/rem-patterns.js +76 -53
  124. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  125. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +10 -0
  126. package/dist/src/agent/memory/dreaming/short-term-store.js +157 -79
  127. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  128. package/dist/src/agent/memory/manager.d.ts +7 -0
  129. package/dist/src/agent/memory/manager.js +31 -6
  130. package/dist/src/agent/memory/manager.js.map +1 -1
  131. package/dist/src/agent/memory/memory-config.d.ts +1 -1
  132. package/dist/src/agent/memory/memory-config.js +3 -3
  133. package/dist/src/agent/memory/memory-config.js.map +1 -1
  134. package/dist/src/agent/memory/sensitivity.d.ts +3 -0
  135. package/dist/src/agent/memory/sensitivity.js +13 -0
  136. package/dist/src/agent/memory/sensitivity.js.map +1 -0
  137. package/dist/src/agent/memory/understanding/service.js +10 -14
  138. package/dist/src/agent/memory/understanding/service.js.map +1 -1
  139. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -0
  140. package/dist/src/agent/memory/user-context-coordinator.js +2 -0
  141. package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
  142. package/dist/src/agent/orchestration/agent-orchestrator.js +8 -1
  143. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  144. package/dist/src/agent/service/btw-query.d.ts +4 -0
  145. package/dist/src/agent/service/btw-query.js +94 -13
  146. package/dist/src/agent/service/btw-query.js.map +1 -1
  147. package/dist/src/agent/session/session-inspector.js +9 -1
  148. package/dist/src/agent/session/session-inspector.js.map +1 -1
  149. package/dist/src/agent/tools/dreaming-tool.js +3 -12
  150. package/dist/src/agent/tools/dreaming-tool.js.map +1 -1
  151. package/dist/src/agent/tools/factory.js +14 -2
  152. package/dist/src/agent/tools/factory.js.map +1 -1
  153. package/dist/src/agent/tools/memory-tool.d.ts +3 -0
  154. package/dist/src/agent/tools/memory-tool.js +6 -3
  155. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  156. package/dist/src/agent/tools/session-search-tool.js +2 -2
  157. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  158. package/dist/src/agent/tools/web-extract.js +2 -2
  159. package/dist/src/agent/tools/web-extract.js.map +1 -1
  160. package/dist/src/agent/workspace-runtime/registry.d.ts +6 -6
  161. package/dist/src/agent/workspace-runtime/registry.js +19 -12
  162. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  163. package/dist/src/agent-manifest/schema.d.ts +4 -0
  164. package/dist/src/agent-manifest/schema.js +2 -1
  165. package/dist/src/agent-manifest/schema.js.map +1 -1
  166. package/dist/src/agent-runtime/index.js +1 -1
  167. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  168. package/dist/src/ai-assist/text-assist.d.ts +2 -1
  169. package/dist/src/ai-assist/text-assist.js +10 -23
  170. package/dist/src/ai-assist/text-assist.js.map +1 -1
  171. package/dist/src/auth/credentials.js +5 -2
  172. package/dist/src/auth/credentials.js.map +1 -1
  173. package/dist/src/auth/oauth/github-copilot.d.ts +3 -4
  174. package/dist/src/auth/oauth/github-copilot.js +66 -2
  175. package/dist/src/auth/oauth/github-copilot.js.map +1 -0
  176. package/dist/src/auth/oauth/index.js +2 -2
  177. package/dist/src/automations/draft/automation-draft-service.js +3 -3
  178. package/dist/src/automations/draft/automation-draft-service.js.map +1 -1
  179. package/dist/src/chat-commands/builtins/review.js +22 -5
  180. package/dist/src/chat-commands/builtins/review.js.map +1 -1
  181. package/dist/src/chat-commands/types.d.ts +4 -0
  182. package/dist/src/config/schema.d.ts +4 -0
  183. package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -0
  184. package/dist/src/gateway/hono/routes/dreaming.js +28 -21
  185. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  186. package/dist/src/gateway/hono/routes/memory.js +16 -4
  187. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  188. package/dist/src/gateway/hono/routes/models.js +1 -0
  189. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  190. package/dist/src/gateway/hono/routes/voice.js +2 -2
  191. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  192. package/dist/src/goals/goal-contract-draft.js +2 -2
  193. package/dist/src/goals/goal-contract-draft.js.map +1 -1
  194. package/dist/src/goals/goal-evidence-review.js +2 -2
  195. package/dist/src/goals/goal-evidence-review.js.map +1 -1
  196. package/dist/src/notes/service.js +2 -2
  197. package/dist/src/notes/service.js.map +1 -1
  198. package/dist/src/providers/constants.d.ts +2 -0
  199. package/dist/src/providers/constants.js +11 -0
  200. package/dist/src/providers/constants.js.map +1 -0
  201. package/dist/src/providers/extension-stream-bridge.js +1 -0
  202. package/dist/src/providers/extension-stream-bridge.js.map +1 -1
  203. package/dist/src/providers/index.d.ts +3 -3
  204. package/dist/src/providers/index.js +5 -4
  205. package/dist/src/providers/index.js.map +1 -1
  206. package/dist/src/providers/model-call.d.ts +17 -0
  207. package/dist/src/providers/model-call.js +60 -0
  208. package/dist/src/providers/model-call.js.map +1 -0
  209. package/dist/src/session/session-title.js +2 -2
  210. package/dist/src/session/session-title.js.map +1 -1
  211. package/dist/src/storage/sqlite/fts.d.ts +6 -0
  212. package/dist/src/storage/sqlite/fts.js +70 -1
  213. package/dist/src/storage/sqlite/fts.js.map +1 -1
  214. package/dist/src/storage/sqlite/memory-index-repository.js +16 -7
  215. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  216. package/dist/src/storage/sqlite/memory-records-repository.d.ts +18 -0
  217. package/dist/src/storage/sqlite/memory-records-repository.js +55 -8
  218. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  219. package/dist/src/voice/tts/summarize.js +2 -2
  220. package/dist/src/voice/tts/summarize.js.map +1 -1
  221. package/dist/src/workflows/draft/workflow-draft-service.js +2 -2
  222. package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
  223. package/package.json +5 -5
  224. package/dist/gateway/static/root/assets/agents-Dl9EWnUh.js +0 -2
  225. package/dist/gateway/static/root/assets/automations-page-CFt5Ik4q.js +0 -4
  226. package/dist/gateway/static/root/assets/browser-settings-page-ColJPwer.js +0 -8
  227. package/dist/gateway/static/root/assets/channels-settings-BDLHV3Jx.js +0 -1
  228. package/dist/gateway/static/root/assets/channels-status-swr-EUwWYx8l.js +0 -1
  229. package/dist/gateway/static/root/assets/connectors-page-CA752gY8.js +0 -2
  230. package/dist/gateway/static/root/assets/goal-create-dialog-DVAHnifk.js +0 -1
  231. package/dist/gateway/static/root/assets/goal-detail-page-BuOEQZn_.js +0 -4
  232. package/dist/gateway/static/root/assets/goals-page-WV4cHvD-.js +0 -2
  233. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-D51yogNZ.js +0 -1
  234. package/dist/gateway/static/root/assets/logs-page-CL22jleU.js +0 -7
  235. package/dist/gateway/static/root/assets/messages-DbNQuFdA.js +0 -3
  236. package/dist/gateway/static/root/assets/models-hub-panel-BkV9hDc-.js +0 -2
  237. package/dist/gateway/static/root/assets/notes-page-BK9yydrL.js +0 -1
  238. package/dist/gateway/static/root/assets/notes-workbench-Dd0v-hK2.js +0 -2
  239. package/dist/gateway/static/root/assets/project-detail-page-DSPhB3do.js +0 -1
  240. package/dist/gateway/static/root/assets/projects-page-C-fZk1f7.js +0 -1
  241. package/dist/gateway/static/root/assets/remote-access-hub-BGaVc3t7.js +0 -1
  242. package/dist/gateway/static/root/assets/sessions-page-DbnzgQOP.js +0 -1
  243. package/dist/gateway/static/root/assets/settings-advanced-gate-CuDBoz5k.js +0 -1
  244. package/dist/gateway/static/root/assets/shares-settings-06IYvwDt.js +0 -1
  245. package/dist/gateway/static/root/assets/skill-reload-api-0ODH0DXl.js +0 -1
  246. package/dist/gateway/static/root/assets/skills-page-3W2-wDyO.js +0 -2
  247. package/dist/gateway/static/root/assets/voice-api-key-field-BPn1ZEga.js +0 -1
  248. package/dist/gateway/static/root/assets/work-item-detail-page-BQGTTsz1.js +0 -1
  249. package/dist/gateway/static/root/assets/workflow-run-setup-panel-na-N4jZ6.js +0 -3
  250. package/dist/gateway/static/root/assets/workflows-page-CjeVDs4h.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"deep-promotion.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/deep-promotion.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport {\n loadDreamingStore,\n saveDreamingStore,\n withDreamingPromotionLock,\n type DreamingStoreEntry,\n} from './short-term-store.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n emptyDeepPhaseSkipped,\n writeDreamingDeepLastRun,\n type DreamingDeepLastRun,\n type DreamingDeepPhaseSkipped,\n} from './last-run.js';\nimport type { DreamingDeepConfig } from './config.js';\nimport type { MemoryManager } from '../manager.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n isoDay,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\nconst log = createLogger('Dreaming:Deep');\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingPromotionCandidate = DreamingStoreEntry & {\n avgScore: number;\n /** Time-decay-adjusted final score used for ranking. */\n score: number;\n /** Raw recency decay multiplier (0–1). */\n recencyDecay: number;\n};\n\n\nfunction markerForPromotion(key: string, hash: string): string {\n // Quote values to allow spaces/colons in key.\n return `<!-- xopc-memory-promotion key=\"${key}\" hash=\"${hash}\" -->`;\n}\n\n\nasync function rehydrateSnippet(params: {\n workspaceDir: string;\n candidate: DreamingPromotionCandidate;\n}): Promise<{ snippet: string; startLine: number; endLine: number } | null> {\n const fullPath = path.join(params.workspaceDir, params.candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) return null;\n\n const startLine = Math.max(1, Math.floor(params.candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(params.candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) return null;\n return { snippet, startLine, endLine };\n}\n\n\nfunction buildDeepLastRun(base: {\n runId: string;\n startedAt: string;\n finishedAt: string;\n t0: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: DreamingDeepLastRun['deep'];\n}): DreamingDeepLastRun {\n const durationMs = Math.max(0, Date.now() - base.t0);\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: base.runId,\n startedAt: base.startedAt,\n finishedAt: base.finishedAt,\n durationMs,\n ok: base.ok,\n reason: base.reason,\n config: base.config,\n memoryPath: base.memoryPath,\n ...(base.errorMessage ? { errorMessage: base.errorMessage } : {}),\n deep: base.deep,\n };\n}\n\nexport async function runDreamingDeepPromotion(params: {\n workspaceDir: string;\n dreamingRoot: string;\n config?: Partial<DreamingDeepConfig>;\n memoryManager?: MemoryManager;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n candidates: number;\n applied: number;\n memoryPath: string;\n}> {\n const cfg = resolveDeepDefaults(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;\n const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);\n const t0 = Date.now();\n\n // Early exit for disabled or zero-limit configurations.\n const earlyExitReason = !cfg.enabled ? 'dreaming disabled' : cfg.limit === 0 ? 'dreaming limit=0' : null;\n if (earlyExitReason) {\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: true,\n reason: earlyExitReason,\n config: cfg,\n memoryPath,\n deep: { candidatesRanked: 0, applied: 0, skipped: empty },\n }),\n }).catch(() => undefined);\n return { ok: true, reason: earlyExitReason, candidates: 0, applied: 0, memoryPath };\n }\n\n try {\n const result = await withDreamingPromotionLock(params.dreamingRoot, async () => {\n const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });\n\n const nowMs = now.getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n // Require minimum unique queries to avoid single-query inflation.\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n // Expire entries older than maxAgeDays since last recall.\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked: DreamingPromotionCandidate[] = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore)\n .slice(0, cfg.limit);\n\n if (ranked.length === 0) {\n const z = emptyDeepPhaseSkipped();\n return { ok: true, reason: 'no eligible candidates', candidates: 0, applied: 0, memoryPath, skipped: z };\n }\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const existingMarkers = extractPromotionMarkers(existing);\n\n const appliedCandidates: Array<{\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n recallCount: number;\n avgScore: number;\n }> = [];\n\n const skipped: DreamingDeepPhaseSkipped = emptyDeepPhaseSkipped();\n for (const candidate of ranked) {\n if (existingMarkers.keys.has(candidate.key)) {\n skipped.alreadyPromotedKey += 1;\n // Treat as already applied; mark promotedAt for idempotency and keep going.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n const rehydrated = await rehydrateSnippet({ workspaceDir: params.workspaceDir, candidate });\n if (!rehydrated) {\n skipped.rehydrateFailed += 1;\n continue;\n }\n if (isContaminatedSnippet(rehydrated.snippet)) {\n skipped.contaminated += 1;\n continue;\n }\n const hash = snippetHash(rehydrated.snippet);\n if (existingMarkers.hashes.has(hash)) {\n skipped.hashDuplicate += 1;\n // Already promoted (possibly from a different key/line range). Mark promoted for idempotency.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n appliedCandidates.push({\n key: candidate.key,\n hash,\n snippet: rehydrated.snippet,\n path: candidate.path,\n startLine: rehydrated.startLine,\n endLine: rehydrated.endLine,\n score: candidate.score,\n recallCount: candidate.recallCount,\n avgScore: candidate.avgScore,\n });\n }\n\n if (appliedCandidates.length === 0) {\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n return {\n ok: true,\n reason: 'candidates were stale or already applied',\n candidates: ranked.length,\n applied: 0,\n memoryPath,\n skipped,\n };\n }\n\n const day = isoDay(now);\n const header = existing.trim().length > 0 ? '' : '# Long-Term Memory\\n\\n';\n const sectionLines: string[] = ['', `## Promoted From Short-Term Memory (${day})`, ''];\n for (const c of appliedCandidates) {\n const src = `${c.path}:${c.startLine}-${c.endLine}`;\n sectionLines.push(markerForPromotion(c.key, c.hash));\n sectionLines.push(\n `- ${c.snippet} [score=${c.score.toFixed(3)} recalls=${c.recallCount} avg=${c.avgScore.toFixed(3)} source=${src}]`,\n );\n }\n sectionLines.push('');\n\n const next = `${header}${existing.endsWith('\\n') || existing.length === 0 ? existing : `${existing}\\n`}${sectionLines.join('\\n')}`;\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, next, 'utf-8');\n\n const nowIso = now.toISOString();\n for (const c of appliedCandidates) {\n params.memoryManager?.recordSignal({\n source: 'dreaming',\n recordId: `dreaming:${c.key}`,\n score: c.score,\n content: c.snippet,\n metadata: {\n path: c.path,\n startLine: c.startLine,\n endLine: c.endLine,\n recallCount: c.recallCount,\n avgScore: c.avgScore,\n },\n });\n const entry = store.entries[c.key];\n if (entry) {\n entry.promotedAt = nowIso;\n entry.snippet = c.snippet;\n entry.startLine = c.startLine;\n entry.endLine = c.endLine;\n }\n }\n store.updatedAt = nowIso;\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n\n log.info(\n {\n workspaceDir: params.workspaceDir,\n dreamingRoot: params.dreamingRoot,\n candidates: ranked.length,\n applied: appliedCandidates.length,\n },\n 'Dreaming deep promotion complete',\n );\n\n return {\n ok: true,\n reason: 'applied promotions',\n candidates: ranked.length,\n applied: appliedCandidates.length,\n memoryPath,\n skipped,\n };\n });\n\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n const resultSkipped = 'skipped' in result ? result.skipped : empty;\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: result.ok,\n reason: result.reason,\n config: cfg,\n memoryPath: result.memoryPath,\n deep: {\n candidatesRanked: result.candidates,\n applied: result.applied,\n skipped: resultSkipped,\n },\n }),\n }).catch(() => undefined);\n\n return {\n ok: result.ok,\n reason: result.reason,\n candidates: result.candidates,\n applied: result.applied,\n memoryPath: result.memoryPath,\n };\n } catch (err) {\n const finishedAt = new Date().toISOString();\n const em = err instanceof Error ? err.message : String(err);\n const z = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: false,\n reason: 'error',\n config: cfg,\n memoryPath,\n errorMessage: em,\n deep: { candidatesRanked: 0, applied: 0, skipped: z },\n }),\n }).catch(() => undefined);\n throw err;\n }\n}\n"],"mappings":";;;;;;;;;aAGwD;AA+BxD,MAAM,MAAM,aAAa,gBAAgB;AAazC,SAAS,mBAAmB,KAAa,MAAsB;AAE7D,QAAO,mCAAmC,IAAI,UAAU,KAAK;;AAI/D,eAAe,iBAAiB,QAG4C;CAE1E,MAAM,QAAQ,MAAM,cADH,KAAK,KAAK,OAAO,cAAc,OAAO,UAAU,KACvB,CAAC;AAC3C,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,UAAU,UAAU,CAAC;CACrE,MAAM,UAAU,KAAK,IAAI,WAAW,KAAK,MAAM,OAAO,UAAU,QAAQ,CAAC;CACzE,MAAM,UAAU,WAAW,OAAO,WAAW,QAAQ;AACrD,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO;EAAE;EAAS;EAAW;EAAS;;AAIxC,SAAS,iBAAiB,MAWF;CACtB,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,KAAK,GAAG;AACpD,QAAO;EACL,SAAA;EACA,OAAO;EACP,OAAO,KAAK;EACZ,WAAW,KAAK;EAChB,YAAY,KAAK;EACjB;EACA,IAAI,KAAK;EACT,QAAQ,KAAK;EACb,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,GAAI,KAAK,eAAe,EAAE,cAAc,KAAK,cAAc,GAAG,EAAE;EAChE,MAAM,KAAK;EACZ;;AAGH,eAAsB,yBAAyB,QAY5C;CACD,MAAM,MAAM,oBAAoB,OAAO,OAAO;CAC9C,MAAM,MAAM,OAAO,uBAAO,IAAI,MAAM;CACpC,MAAM,YAAY,IAAI,aAAa;CACnC,MAAM,QAAQ,GAAG,UAAU,GAAG,QAAQ,IAAI,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;CAChF,MAAM,aAAa,KAAK,KAAK,OAAO,cAAc,mBAAmB;CACrE,MAAM,KAAK,KAAK,KAAK;CAGrB,MAAM,kBAAkB,CAAC,IAAI,UAAU,sBAAsB,IAAI,UAAU,IAAI,qBAAqB;AACpG,KAAI,iBAAiB;EACnB,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,QAAQ,uBAAuB;AACrC,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR;IACA,MAAM;KAAE,kBAAkB;KAAG,SAAS;KAAG,SAAS;KAAO;IAC1D,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AACzB,SAAO;GAAE,IAAI;GAAM,QAAQ;GAAiB,YAAY;GAAG,SAAS;GAAG;GAAY;;AAGrF,KAAI;EACF,MAAM,SAAS,MAAM,0BAA0B,OAAO,cAAc,YAAY;GAC9E,MAAM,EAAE,UAAU,MAAM,kBAAkB,EAAE,cAAc,OAAO,cAAc,CAAC;GAEhF,MAAM,QAAQ,IAAI,SAAS;GAe3B,MAAM,SAbM,OAAO,OAAO,MAAM,WAAW,EAAE,CAAC,CAAC,QAAQ,MAA+B;AACpF,QAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAI,EAAE,WAAY,QAAO;AACzB,QAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,WAAW,UAAU,CAAE,QAAO;AACrD,QAAI,EAAE,cAAc,IAAI,eAAgB,QAAO;AAE/C,SAAK,EAAE,aAAa,UAAU,KAAK,IAAI,iBAAkB,QAAO;AAEhE,QAAI,eAAe,EAAE,gBAAgB,OAAO,IAAI,WAAW,CAAE,QAAO;AAEpE,WAAO,QADK,EAAE,cAAc,IAAI,EAAE,aAAa,EAAE,cAAc,EAC5C,IAAI,IAAI;KAGmB,CAC7C,KAAK,MAAM;IACV,MAAM,EAAE,UAAU,OAAO,iBAAiB,sBAAsB,GAAG,OAAO,IAAI,oBAAoB;AAClG,WAAO;KAAE,GAAG;KAAG;KAAU;KAAO;KAAc;KAC9C,CACD,KAAK,yBAAyB,CAC9B,MAAM,GAAG,IAAI,MAAM;AAEtB,OAAI,OAAO,WAAW,EAEpB,QAAO;IAAE,IAAI;IAAM,QAAQ;IAA0B,YAAY;IAAG,SAAS;IAAG;IAAY,SADlF,uBAC4F;IAAE;GAG1G,MAAM,WAAW,MAAM,GAAG,SAAS,YAAY,QAAQ,CAAC,OAAO,QAAiB;AAC9E,QAAK,KAA2C,SAAS,SAAU,QAAO;AAC1E,UAAM;KACN;GACF,MAAM,kBAAkB,wBAAwB,SAAS;GAEzD,MAAM,oBAUD,EAAE;GAEP,MAAM,UAAoC,uBAAuB;AACjE,QAAK,MAAM,aAAa,QAAQ;AAC9B,QAAI,gBAAgB,KAAK,IAAI,UAAU,IAAI,EAAE;AAC3C,aAAQ,sBAAsB;KAE9B,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAI,SAAS,CAAC,MAAM,WAClB,OAAM,aAAa,IAAI,aAAa;AAEtC;;IAEF,MAAM,aAAa,MAAM,iBAAiB;KAAE,cAAc,OAAO;KAAc;KAAW,CAAC;AAC3F,QAAI,CAAC,YAAY;AACf,aAAQ,mBAAmB;AAC3B;;AAEF,QAAI,sBAAsB,WAAW,QAAQ,EAAE;AAC7C,aAAQ,gBAAgB;AACxB;;IAEF,MAAM,OAAO,YAAY,WAAW,QAAQ;AAC5C,QAAI,gBAAgB,OAAO,IAAI,KAAK,EAAE;AACpC,aAAQ,iBAAiB;KAEzB,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAI,SAAS,CAAC,MAAM,WAClB,OAAM,aAAa,IAAI,aAAa;AAEtC;;AAEF,sBAAkB,KAAK;KACrB,KAAK,UAAU;KACf;KACA,SAAS,WAAW;KACpB,MAAM,UAAU;KAChB,WAAW,WAAW;KACtB,SAAS,WAAW;KACpB,OAAO,UAAU;KACjB,aAAa,UAAU;KACvB,UAAU,UAAU;KACrB,CAAC;;AAGJ,OAAI,kBAAkB,WAAW,GAAG;AAClC,UAAM,kBAAkB;KAAE,cAAc,OAAO;KAAc;KAAO,CAAC;AACrE,WAAO;KACL,IAAI;KACJ,QAAQ;KACR,YAAY,OAAO;KACnB,SAAS;KACT;KACA;KACD;;GAGH,MAAM,MAAM,OAAO,IAAI;GACvB,MAAM,SAAS,SAAS,MAAM,CAAC,SAAS,IAAI,KAAK;GACjD,MAAM,eAAyB;IAAC;IAAI,uCAAuC,IAAI;IAAI;IAAG;AACtF,QAAK,MAAM,KAAK,mBAAmB;IACjC,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,EAAE,UAAU,GAAG,EAAE;AAC1C,iBAAa,KAAK,mBAAmB,EAAE,KAAK,EAAE,KAAK,CAAC;AACpD,iBAAa,KACX,KAAK,EAAE,QAAQ,UAAU,EAAE,MAAM,QAAQ,EAAE,CAAC,WAAW,EAAE,YAAY,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC,UAAU,IAAI,GACjH;;AAEH,gBAAa,KAAK,GAAG;GAErB,MAAM,OAAO,GAAG,SAAS,SAAS,SAAS,KAAK,IAAI,SAAS,WAAW,IAAI,WAAW,GAAG,SAAS,MAAM,aAAa,KAAK,KAAK;AAChI,SAAM,GAAG,MAAM,KAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AAC7D,SAAM,GAAG,UAAU,YAAY,MAAM,QAAQ;GAE7C,MAAM,SAAS,IAAI,aAAa;AAChC,QAAK,MAAM,KAAK,mBAAmB;AACjC,WAAO,eAAe,aAAa;KACjC,QAAQ;KACR,UAAU,YAAY,EAAE;KACxB,OAAO,EAAE;KACT,SAAS,EAAE;KACX,UAAU;MACR,MAAM,EAAE;MACR,WAAW,EAAE;MACb,SAAS,EAAE;MACX,aAAa,EAAE;MACf,UAAU,EAAE;MACb;KACF,CAAC;IACF,MAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,QAAI,OAAO;AACT,WAAM,aAAa;AACnB,WAAM,UAAU,EAAE;AAClB,WAAM,YAAY,EAAE;AACpB,WAAM,UAAU,EAAE;;;AAGtB,SAAM,YAAY;AAClB,SAAM,kBAAkB;IAAE,cAAc,OAAO;IAAc;IAAO,CAAC;AAErE,OAAI,KACF;IACE,cAAc,OAAO;IACrB,cAAc,OAAO;IACrB,YAAY,OAAO;IACnB,SAAS,kBAAkB;IAC5B,EACD,mCACD;AAED,UAAO;IACL,IAAI;IACJ,QAAQ;IACR,YAAY,OAAO;IACnB,SAAS,kBAAkB;IAC3B;IACA;IACD;IACD;EAEF,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,QAAQ,uBAAuB;EACrC,MAAM,gBAAgB,aAAa,SAAS,OAAO,UAAU;AAC7D,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI,OAAO;IACX,QAAQ,OAAO;IACf,QAAQ;IACR,YAAY,OAAO;IACnB,MAAM;KACJ,kBAAkB,OAAO;KACzB,SAAS,OAAO;KAChB,SAAS;KACV;IACF,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AAEzB,SAAO;GACL,IAAI,OAAO;GACX,QAAQ,OAAO;GACf,YAAY,OAAO;GACnB,SAAS,OAAO;GAChB,YAAY,OAAO;GACpB;UACM,KAAK;EACZ,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC3C,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;EAC3D,MAAM,IAAI,uBAAuB;AACjC,QAAM,yBAAyB;GAC7B,cAAc,OAAO;GACrB,SAAS,iBAAiB;IACxB;IACA;IACA;IACA;IACA,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR;IACA,cAAc;IACd,MAAM;KAAE,kBAAkB;KAAG,SAAS;KAAG,SAAS;KAAG;IACtD,CAAC;GACH,CAAC,CAAC,YAAY,KAAA,EAAU;AACzB,QAAM"}
1
+ {"version":3,"file":"deep-promotion.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/deep-promotion.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { MEMORY_MD_FILENAME } from './constants.js';\nimport {\n loadDreamingStore,\n saveDreamingStore,\n withDreamingStoreLock,\n type DreamingStoreEntry,\n} from './short-term-store.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n emptyDeepPhaseSkipped,\n writeDreamingDeepLastRun,\n type DreamingDeepLastRun,\n type DreamingDeepPhaseSkipped,\n} from './last-run.js';\nimport type { DreamingDeepConfig } from './config.js';\nimport type { MemoryManager } from '../manager.js';\nimport { activateDreamingPromotion } from './promotion-lifecycle.js';\nimport { inferMemorySensitivity } from '../sensitivity.js';\nimport {\n clamp01,\n compareCandidatesByScore,\n computeCandidateScore,\n extractPromotionMarkers,\n isContaminatedSnippet,\n isExpiredEntry,\n isoDay,\n readFileLines,\n resolveDeepDefaults,\n sliceRange,\n snippetHash,\n} from './utils.js';\n\nconst log = createLogger('Dreaming:Deep');\n\nexport type { DreamingDeepConfig } from './config.js';\n\nexport type DreamingPromotionCandidate = DreamingStoreEntry & {\n avgScore: number;\n /** Time-decay-adjusted final score used for ranking. */\n score: number;\n /** Raw recency decay multiplier (0–1). */\n recencyDecay: number;\n};\n\n\nfunction markerForPromotion(key: string, hash: string): string {\n // Quote values to allow spaces/colons in key.\n return `<!-- xopc-memory-promotion key=\"${key}\" hash=\"${hash}\" -->`;\n}\n\n\nasync function rehydrateSnippet(params: {\n workspaceDir: string;\n candidate: DreamingPromotionCandidate;\n}): Promise<{ snippet: string; startLine: number; endLine: number } | null> {\n const fullPath = path.join(params.workspaceDir, params.candidate.path);\n const lines = await readFileLines(fullPath);\n if (!lines) return null;\n\n const startLine = Math.max(1, Math.floor(params.candidate.startLine));\n const endLine = Math.max(startLine, Math.floor(params.candidate.endLine));\n const snippet = sliceRange(lines, startLine, endLine);\n if (!snippet) return null;\n return { snippet, startLine, endLine };\n}\n\n\nfunction buildDeepLastRun(base: {\n runId: string;\n startedAt: string;\n finishedAt: string;\n t0: number;\n ok: boolean;\n reason: string;\n config: DreamingDeepConfig;\n memoryPath: string;\n errorMessage?: string;\n deep: DreamingDeepLastRun['deep'];\n}): DreamingDeepLastRun {\n const durationMs = Math.max(0, Date.now() - base.t0);\n return {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'deep',\n runId: base.runId,\n startedAt: base.startedAt,\n finishedAt: base.finishedAt,\n durationMs,\n ok: base.ok,\n reason: base.reason,\n config: base.config,\n memoryPath: base.memoryPath,\n ...(base.errorMessage ? { errorMessage: base.errorMessage } : {}),\n deep: base.deep,\n };\n}\n\nexport async function runDreamingDeepPromotion(params: {\n agentId: string;\n workspaceDir: string;\n dreamingRoot: string;\n config?: Partial<DreamingDeepConfig>;\n sensitiveWritePolicy?: 'deny' | 'confirm' | 'allow';\n memoryManager?: MemoryManager;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n candidates: number;\n applied: number;\n memoryPath: string;\n}> {\n const cfg = resolveDeepDefaults(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;\n const memoryPath = path.join(params.dreamingRoot, MEMORY_MD_FILENAME);\n const t0 = Date.now();\n\n // Early exit for disabled or zero-limit configurations.\n const earlyExitReason = !cfg.enabled ? 'dreaming disabled' : cfg.limit === 0 ? 'dreaming limit=0' : null;\n if (earlyExitReason) {\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: true,\n reason: earlyExitReason,\n config: cfg,\n memoryPath,\n deep: { candidatesRanked: 0, applied: 0, skipped: empty },\n }),\n }).catch(() => undefined);\n return { ok: true, reason: earlyExitReason, candidates: 0, applied: 0, memoryPath };\n }\n\n try {\n const result = await withDreamingStoreLock(params.dreamingRoot, async () => {\n const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });\n\n const nowMs = now.getTime();\n\n const all = Object.values(store.entries ?? {}).filter((e): e is DreamingStoreEntry => {\n if (!e || typeof e !== 'object') return false;\n if (e.promotedAt) return false;\n if (!e.path || !e.path.startsWith('memory/')) return false;\n if (e.recallCount < cfg.minRecallCount) return false;\n // Require minimum unique queries to avoid single-query inflation.\n if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;\n // Expire entries older than maxAgeDays since last recall.\n if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;\n const avg = e.recallCount > 0 ? e.totalScore / e.recallCount : 0;\n return clamp01(avg) >= cfg.minScore;\n });\n\n const ranked: DreamingPromotionCandidate[] = all\n .map((e) => {\n const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);\n return { ...e, avgScore, score, recencyDecay };\n })\n .sort(compareCandidatesByScore)\n .slice(0, cfg.limit);\n\n if (ranked.length === 0) {\n const z = emptyDeepPhaseSkipped();\n return { ok: true, reason: 'no eligible candidates', candidates: 0, applied: 0, memoryPath, skipped: z };\n }\n\n const existing = await fs.readFile(memoryPath, 'utf-8').catch((err: unknown) => {\n if ((err as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return '';\n throw err;\n });\n const existingMarkers = extractPromotionMarkers(existing);\n\n const appliedCandidates: Array<{\n key: string;\n hash: string;\n snippet: string;\n path: string;\n startLine: number;\n endLine: number;\n score: number;\n recallCount: number;\n avgScore: number;\n sensitivity: ReturnType<typeof inferMemorySensitivity>;\n }> = [];\n\n const skipped: DreamingDeepPhaseSkipped = emptyDeepPhaseSkipped();\n for (const candidate of ranked) {\n if (existingMarkers.keys.has(candidate.key)) {\n skipped.alreadyPromotedKey += 1;\n // Treat as already applied; mark promotedAt for idempotency and keep going.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n const rehydrated = await rehydrateSnippet({ workspaceDir: params.workspaceDir, candidate });\n if (!rehydrated) {\n skipped.rehydrateFailed += 1;\n continue;\n }\n if (isContaminatedSnippet(rehydrated.snippet)) {\n skipped.contaminated += 1;\n continue;\n }\n const sensitivity = inferMemorySensitivity(rehydrated.snippet);\n if (sensitivity !== 'normal' && params.sensitiveWritePolicy !== 'allow') {\n skipped.contaminated += 1;\n continue;\n }\n const hash = snippetHash(rehydrated.snippet);\n if (existingMarkers.hashes.has(hash)) {\n skipped.hashDuplicate += 1;\n // Already promoted (possibly from a different key/line range). Mark promoted for idempotency.\n const entry = store.entries[candidate.key];\n if (entry && !entry.promotedAt) {\n entry.promotedAt = now.toISOString();\n }\n continue;\n }\n appliedCandidates.push({\n key: candidate.key,\n hash,\n snippet: rehydrated.snippet,\n path: candidate.path,\n startLine: rehydrated.startLine,\n endLine: rehydrated.endLine,\n score: candidate.score,\n recallCount: candidate.recallCount,\n avgScore: candidate.avgScore,\n sensitivity,\n });\n }\n\n if (appliedCandidates.length === 0) {\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n return {\n ok: true,\n reason: 'candidates were stale or already applied',\n candidates: ranked.length,\n applied: 0,\n memoryPath,\n skipped,\n };\n }\n\n const day = isoDay(now);\n const header = existing.trim().length > 0 ? '' : '# Long-Term Memory\\n\\n';\n const sectionLines: string[] = ['', `## Promoted From Short-Term Memory (${day})`, ''];\n for (const c of appliedCandidates) {\n const src = `${c.path}:${c.startLine}-${c.endLine}`;\n sectionLines.push(markerForPromotion(c.key, c.hash));\n sectionLines.push(\n `- ${c.snippet} [score=${c.score.toFixed(3)} recalls=${c.recallCount} avg=${c.avgScore.toFixed(3)} source=${src}]`,\n );\n }\n sectionLines.push('');\n\n const next = `${header}${existing.endsWith('\\n') || existing.length === 0 ? existing : `${existing}\\n`}${sectionLines.join('\\n')}`;\n for (const c of appliedCandidates) {\n activateDreamingPromotion({\n agentId: params.agentId,\n workspaceId: params.workspaceDir,\n candidateKey: c.key,\n content: c.snippet,\n sourcePath: c.path,\n lineStart: c.startLine,\n lineEnd: c.endLine,\n score: c.score,\n recallCount: c.recallCount,\n observedAt: now.toISOString(),\n sensitivity: c.sensitivity,\n });\n }\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, next, 'utf-8');\n\n const nowIso = now.toISOString();\n for (const c of appliedCandidates) {\n params.memoryManager?.recordSignal({\n source: 'dreaming',\n recordId: `dreaming:${c.key}`,\n score: c.score,\n content: c.snippet,\n metadata: {\n path: c.path,\n startLine: c.startLine,\n endLine: c.endLine,\n recallCount: c.recallCount,\n avgScore: c.avgScore,\n },\n });\n const entry = store.entries[c.key];\n if (entry) {\n entry.promotedAt = nowIso;\n entry.snippet = c.snippet;\n entry.startLine = c.startLine;\n entry.endLine = c.endLine;\n }\n }\n store.updatedAt = nowIso;\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n\n log.info(\n {\n workspaceDir: params.workspaceDir,\n dreamingRoot: params.dreamingRoot,\n candidates: ranked.length,\n applied: appliedCandidates.length,\n },\n 'Dreaming deep promotion complete',\n );\n\n return {\n ok: true,\n reason: 'applied promotions',\n candidates: ranked.length,\n applied: appliedCandidates.length,\n memoryPath,\n skipped,\n };\n });\n\n const finishedAt = new Date().toISOString();\n const empty = emptyDeepPhaseSkipped();\n const resultSkipped = 'skipped' in result ? result.skipped : empty;\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: result.ok,\n reason: result.reason,\n config: cfg,\n memoryPath: result.memoryPath,\n deep: {\n candidatesRanked: result.candidates,\n applied: result.applied,\n skipped: resultSkipped,\n },\n }),\n }).catch(() => undefined);\n\n return {\n ok: result.ok,\n reason: result.reason,\n candidates: result.candidates,\n applied: result.applied,\n memoryPath: result.memoryPath,\n };\n } catch (err) {\n const finishedAt = new Date().toISOString();\n const em = err instanceof Error ? err.message : String(err);\n const z = emptyDeepPhaseSkipped();\n await writeDreamingDeepLastRun({\n dreamingRoot: params.dreamingRoot,\n lastRun: buildDeepLastRun({\n runId,\n startedAt,\n finishedAt,\n t0,\n ok: false,\n reason: 'error',\n config: cfg,\n memoryPath,\n errorMessage: em,\n deep: { candidatesRanked: 0, applied: 0, skipped: z },\n }),\n }).catch(() => undefined);\n throw err;\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { DreamingLightConfig } from './config.js';
2
2
  export declare function runLightSweep(params: {
3
+ workspaceDir: string;
3
4
  dreamingRoot: string;
4
5
  config?: Partial<DreamingLightConfig>;
5
6
  now?: Date;
@@ -1,4 +1,6 @@
1
1
  import { DREAMING_DIR_RELATIVE } from "./constants.js";
2
+ import { buildEntryKey, normalizeMemoryPath } from "./utils.js";
3
+ import { bumpEntryPhaseSignal, loadDreamingStore, saveDreamingStore, withDreamingStoreLock } from "./short-term-store.js";
2
4
  import "./last-run.js";
3
5
  import path from "node:path";
4
6
  import fs from "node:fs/promises";
@@ -14,29 +16,195 @@ function resolveConfig(overrides) {
14
16
  }
15
17
  async function runLightSweep(params) {
16
18
  const cfg = resolveConfig(params.config);
17
- const startedAt = (params.now ?? /* @__PURE__ */ new Date()).toISOString();
19
+ const now = params.now ?? /* @__PURE__ */ new Date();
20
+ const startedAt = now.toISOString();
18
21
  const runId = `light:${startedAt}:${process.pid}`;
19
22
  const startMs = Date.now();
20
- const reason = cfg.enabled ? "light sweep disabled: no implicit file source" : "light sweep disabled";
21
- await writeLastRun(params.dreamingRoot, {
22
- runId,
23
- startedAt,
24
- cfg,
25
- ok: true,
26
- reason,
27
- startMs,
28
- light: {
23
+ if (!cfg.enabled) {
24
+ const reason = "light sweep disabled";
25
+ await writeLastRun(params.dreamingRoot, {
26
+ runId,
27
+ startedAt,
28
+ cfg,
29
+ ok: true,
30
+ reason,
31
+ startMs,
32
+ light: {
33
+ scannedEntries: 0,
34
+ newSignals: 0,
35
+ deduped: 0
36
+ }
37
+ });
38
+ return {
39
+ ok: true,
40
+ reason,
29
41
  scannedEntries: 0,
30
42
  newSignals: 0,
31
43
  deduped: 0
44
+ };
45
+ }
46
+ try {
47
+ const result = await withDreamingStoreLock(params.dreamingRoot, async () => {
48
+ const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });
49
+ const candidates = await scanRecentMemoryLines(params.workspaceDir, cfg.lookbackDays, now);
50
+ let scannedEntries = 0;
51
+ let newSignals = 0;
52
+ let deduped = 0;
53
+ for (const candidate of candidates.slice(0, cfg.limit)) {
54
+ scannedEntries += 1;
55
+ const key = buildEntryKey(candidate);
56
+ const existing = store.entries[key];
57
+ if (existing) {
58
+ if (observedAtOrZero(existing) >= candidate.observedAtMs) {
59
+ deduped += 1;
60
+ continue;
61
+ }
62
+ existing.snippet = candidate.snippet;
63
+ existing.lastObservedAt = candidate.observedAt;
64
+ bumpEntryPhaseSignal(existing, "sourceCount");
65
+ bumpEntryPhaseSignal(existing, "lightHits");
66
+ continue;
67
+ }
68
+ const duplicate = Object.values(store.entries).find((entry) => similarity(entry.snippet, candidate.snippet) >= cfg.dedupeSimilarity);
69
+ if (duplicate) {
70
+ if (observedAtOrZero(duplicate) < candidate.observedAtMs) {
71
+ duplicate.lastObservedAt = candidate.observedAt;
72
+ bumpEntryPhaseSignal(duplicate, "sourceCount");
73
+ bumpEntryPhaseSignal(duplicate, "lightHits");
74
+ }
75
+ deduped += 1;
76
+ continue;
77
+ }
78
+ store.entries[key] = newLightEntry(candidate);
79
+ newSignals += 1;
80
+ }
81
+ if (scannedEntries > 0) {
82
+ store.updatedAt = startedAt;
83
+ await saveDreamingStore({
84
+ dreamingRoot: params.dreamingRoot,
85
+ store
86
+ });
87
+ }
88
+ return {
89
+ scannedEntries,
90
+ newSignals,
91
+ deduped
92
+ };
93
+ });
94
+ await writeLastRun(params.dreamingRoot, {
95
+ runId,
96
+ startedAt,
97
+ cfg,
98
+ ok: true,
99
+ reason: "light sweep complete",
100
+ startMs,
101
+ light: result
102
+ });
103
+ return {
104
+ ok: true,
105
+ reason: "light sweep complete",
106
+ ...result
107
+ };
108
+ } catch (error) {
109
+ const errorMessage = error instanceof Error ? error.message : String(error);
110
+ await writeLastRun(params.dreamingRoot, {
111
+ runId,
112
+ startedAt,
113
+ cfg,
114
+ ok: false,
115
+ reason: `light error: ${errorMessage}`,
116
+ startMs,
117
+ light: {
118
+ scannedEntries: 0,
119
+ newSignals: 0,
120
+ deduped: 0
121
+ },
122
+ errorMessage
123
+ }).catch(() => void 0);
124
+ return {
125
+ ok: false,
126
+ reason: errorMessage,
127
+ scannedEntries: 0,
128
+ newSignals: 0,
129
+ deduped: 0
130
+ };
131
+ }
132
+ }
133
+ async function scanRecentMemoryLines(workspaceDir, lookbackDays, now) {
134
+ const root = path.join(workspaceDir, "memory");
135
+ const cutoffMs = now.getTime() - lookbackDays * 24 * 60 * 60 * 1e3;
136
+ const files = await listMarkdownFiles(root);
137
+ const out = [];
138
+ for (const filePath of files) {
139
+ const stat = await fs.stat(filePath).catch(() => null);
140
+ if (!stat || stat.mtimeMs < cutoffMs) continue;
141
+ const content = await fs.readFile(filePath, "utf-8").catch(() => "");
142
+ const relativePath = normalizeMemoryPath(path.relative(workspaceDir, filePath));
143
+ let inFence = false;
144
+ for (const [index, rawLine] of content.split(/\r?\n/).entries()) {
145
+ if (/^\s*```/.test(rawLine)) {
146
+ inFence = !inFence;
147
+ continue;
148
+ }
149
+ if (inFence) continue;
150
+ const snippet = rawLine.replace(/^\s*[-*]\s+/, "").trim();
151
+ if (snippet.length < 8 || snippet.startsWith("#") || snippet.startsWith("<!--")) continue;
152
+ out.push({
153
+ path: relativePath,
154
+ startLine: index + 1,
155
+ endLine: index + 1,
156
+ snippet: snippet.slice(0, 360),
157
+ observedAt: stat.mtime.toISOString(),
158
+ observedAtMs: stat.mtimeMs
159
+ });
32
160
  }
33
- });
161
+ }
162
+ return out.sort((left, right) => right.observedAtMs - left.observedAtMs || left.path.localeCompare(right.path) || left.startLine - right.startLine);
163
+ }
164
+ async function listMarkdownFiles(root) {
165
+ const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
166
+ const out = [];
167
+ for (const entry of entries) {
168
+ const fullPath = path.join(root, entry.name);
169
+ if (entry.isDirectory()) out.push(...await listMarkdownFiles(fullPath));
170
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) out.push(fullPath);
171
+ }
172
+ return out;
173
+ }
174
+ function similarity(left, right) {
175
+ const tokens = (value) => new Set(value.toLocaleLowerCase().match(/[\p{L}\p{N}]+/gu) ?? []);
176
+ const a = tokens(left);
177
+ const b = tokens(right);
178
+ if (a.size === 0 || b.size === 0) return 0;
179
+ let intersection = 0;
180
+ for (const token of a) if (b.has(token)) intersection += 1;
181
+ return intersection / (a.size + b.size - intersection);
182
+ }
183
+ function observedAtOrZero(entry) {
184
+ const parsed = entry.lastObservedAt ? Date.parse(entry.lastObservedAt) : 0;
185
+ return Number.isFinite(parsed) ? parsed : 0;
186
+ }
187
+ function newLightEntry(candidate) {
34
188
  return {
35
- ok: true,
36
- reason,
37
- scannedEntries: 0,
38
- newSignals: 0,
39
- deduped: 0
189
+ key: buildEntryKey(candidate),
190
+ path: candidate.path,
191
+ startLine: candidate.startLine,
192
+ endLine: candidate.endLine,
193
+ snippet: candidate.snippet,
194
+ recallCount: 0,
195
+ sourceCount: 1,
196
+ groundedCount: 0,
197
+ lightHits: 1,
198
+ remHits: 0,
199
+ phaseHitCount: 2,
200
+ totalSignalCount: 2,
201
+ totalScore: 0,
202
+ maxScore: 0,
203
+ queryHashes: [],
204
+ recallDays: [],
205
+ firstRecalledAt: candidate.observedAt,
206
+ lastRecalledAt: candidate.observedAt,
207
+ lastObservedAt: candidate.observedAt
40
208
  };
41
209
  }
42
210
  async function writeLastRun(dreamingRoot, params) {
@@ -1 +1 @@
1
- {"version":3,"file":"light-sweep.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/light-sweep.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE } from './constants.js';\nimport type { DreamingLightConfig } from './config.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n type DreamingLightLastRun,\n} from './last-run.js';\n\nfunction resolveConfig(overrides?: Partial<DreamingLightConfig>): DreamingLightConfig {\n return {\n enabled: overrides?.enabled === true,\n cron: typeof overrides?.cron === 'string' ? overrides.cron : '0 */6 * * *',\n lookbackDays: Math.max(1, Math.floor(Number(overrides?.lookbackDays) || 2)),\n limit: Math.max(0, Math.floor(Number(overrides?.limit) || 100)),\n dedupeSimilarity: Math.max(0, Math.min(1, Number(overrides?.dedupeSimilarity) || 0.9)),\n };\n}\n\nexport async function runLightSweep(params: {\n dreamingRoot: string;\n config?: Partial<DreamingLightConfig>;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n}> {\n const cfg = resolveConfig(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `light:${startedAt}:${process.pid}`;\n const startMs = Date.now();\n const reason = cfg.enabled\n ? 'light sweep disabled: no implicit file source'\n : 'light sweep disabled';\n\n await writeLastRun(params.dreamingRoot, {\n runId, startedAt, cfg, ok: true, reason, startMs,\n light: { scannedEntries: 0, newSignals: 0, deduped: 0 },\n });\n return { ok: true, reason, scannedEntries: 0, newSignals: 0, deduped: 0 };\n}\n\n// ── Last-run writer ────────────────────────────────────────────────────\n\nasync function writeLastRun(\n dreamingRoot: string,\n params: {\n runId: string;\n startedAt: string;\n cfg: DreamingLightConfig;\n ok: boolean;\n reason: string;\n startMs: number;\n light: DreamingLightLastRun['light'];\n errorMessage?: string;\n },\n): Promise<void> {\n const finishedAt = new Date().toISOString();\n const durationMs = Math.max(0, Date.now() - params.startMs);\n\n const lastRun: DreamingLightLastRun = {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'light',\n runId: params.runId,\n startedAt: params.startedAt,\n finishedAt,\n durationMs,\n ok: params.ok,\n reason: params.reason,\n config: params.cfg,\n light: params.light,\n ...(params.errorMessage ? { errorMessage: params.errorMessage } : {}),\n };\n\n const lastRunPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE, 'last-run-light.json');\n await fs.mkdir(path.dirname(lastRunPath), { recursive: true });\n const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, lastRunPath);\n}\n"],"mappings":";;;;;AAUA,SAAS,cAAc,WAA+D;AACpF,QAAO;EACL,SAAS,WAAW,YAAY;EAChC,MAAM,OAAO,WAAW,SAAS,WAAW,UAAU,OAAO;EAC7D,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,aAAa,IAAI,EAAE,CAAC;EAC3E,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,WAAW,MAAM,IAAI,IAAI,CAAC;EAC/D,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,WAAW,iBAAiB,IAAI,GAAI,CAAC;EACvF;;AAGH,eAAsB,cAAc,QAUjC;CACD,MAAM,MAAM,cAAc,OAAO,OAAO;CAExC,MAAM,aADM,OAAO,uBAAO,IAAI,MAAM,EACd,aAAa;CACnC,MAAM,QAAQ,SAAS,UAAU,GAAG,QAAQ;CAC5C,MAAM,UAAU,KAAK,KAAK;CAC1B,MAAM,SAAS,IAAI,UACf,kDACA;AAEJ,OAAM,aAAa,OAAO,cAAc;EACtC;EAAO;EAAW;EAAK,IAAI;EAAM;EAAQ;EACzC,OAAO;GAAE,gBAAgB;GAAG,YAAY;GAAG,SAAS;GAAG;EACxD,CAAC;AACF,QAAO;EAAE,IAAI;EAAM;EAAQ,gBAAgB;EAAG,YAAY;EAAG,SAAS;EAAG;;AAK3E,eAAe,aACb,cACA,QAUe;CACf,MAAM,8BAAa,IAAI,MAAM,EAAC,aAAa;CAC3C,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,OAAO,QAAQ;CAE3D,MAAM,UAAgC;EACpC,SAAA;EACA,OAAO;EACP,OAAO,OAAO;EACd,WAAW,OAAO;EAClB;EACA;EACA,IAAI,OAAO;EACX,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,OAAO,OAAO;EACd,GAAI,OAAO,eAAe,EAAE,cAAc,OAAO,cAAc,GAAG,EAAE;EACrE;CAED,MAAM,cAAc,KAAK,KAAK,cAAc,uBAAuB,sBAAsB;AACzF,OAAM,GAAG,MAAM,KAAK,QAAQ,YAAY,EAAE,EAAE,WAAW,MAAM,CAAC;CAC9D,MAAM,MAAM,GAAG,YAAY,GAAG,QAAQ,IAAI,GAAG,KAAK,KAAK,CAAC;AACxD,OAAM,GAAG,UAAU,KAAK,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,KAAK,QAAQ;AACzE,OAAM,GAAG,OAAO,KAAK,YAAY"}
1
+ {"version":3,"file":"light-sweep.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/light-sweep.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { DREAMING_DIR_RELATIVE } from './constants.js';\nimport type { DreamingLightConfig } from './config.js';\nimport {\n bumpEntryPhaseSignal,\n loadDreamingStore,\n saveDreamingStore,\n withDreamingStoreLock,\n type DreamingStoreEntry,\n} from './short-term-store.js';\nimport { buildEntryKey, normalizeMemoryPath } from './utils.js';\nimport {\n DREAMING_LAST_RUN_FORMAT_VERSION,\n type DreamingLightLastRun,\n} from './last-run.js';\n\nfunction resolveConfig(overrides?: Partial<DreamingLightConfig>): DreamingLightConfig {\n return {\n enabled: overrides?.enabled === true,\n cron: typeof overrides?.cron === 'string' ? overrides.cron : '0 */6 * * *',\n lookbackDays: Math.max(1, Math.floor(Number(overrides?.lookbackDays) || 2)),\n limit: Math.max(0, Math.floor(Number(overrides?.limit) || 100)),\n dedupeSimilarity: Math.max(0, Math.min(1, Number(overrides?.dedupeSimilarity) || 0.9)),\n };\n}\n\nexport async function runLightSweep(params: {\n workspaceDir: string;\n dreamingRoot: string;\n config?: Partial<DreamingLightConfig>;\n now?: Date;\n}): Promise<{\n ok: boolean;\n reason: string;\n scannedEntries: number;\n newSignals: number;\n deduped: number;\n}> {\n const cfg = resolveConfig(params.config);\n const now = params.now ?? new Date();\n const startedAt = now.toISOString();\n const runId = `light:${startedAt}:${process.pid}`;\n const startMs = Date.now();\n if (!cfg.enabled) {\n const reason = 'light sweep disabled';\n await writeLastRun(params.dreamingRoot, {\n runId, startedAt, cfg, ok: true, reason, startMs,\n light: { scannedEntries: 0, newSignals: 0, deduped: 0 },\n });\n return { ok: true, reason, scannedEntries: 0, newSignals: 0, deduped: 0 };\n }\n\n try {\n const result = await withDreamingStoreLock(params.dreamingRoot, async () => {\n const { store } = await loadDreamingStore({ dreamingRoot: params.dreamingRoot });\n const candidates = await scanRecentMemoryLines(params.workspaceDir, cfg.lookbackDays, now);\n let scannedEntries = 0;\n let newSignals = 0;\n let deduped = 0;\n for (const candidate of candidates.slice(0, cfg.limit)) {\n scannedEntries += 1;\n const key = buildEntryKey(candidate);\n const existing = store.entries[key];\n if (existing) {\n if (observedAtOrZero(existing) >= candidate.observedAtMs) {\n deduped += 1;\n continue;\n }\n existing.snippet = candidate.snippet;\n existing.lastObservedAt = candidate.observedAt;\n bumpEntryPhaseSignal(existing, 'sourceCount');\n bumpEntryPhaseSignal(existing, 'lightHits');\n continue;\n }\n const duplicate = Object.values(store.entries).find((entry) =>\n similarity(entry.snippet, candidate.snippet) >= cfg.dedupeSimilarity,\n );\n if (duplicate) {\n if (observedAtOrZero(duplicate) < candidate.observedAtMs) {\n duplicate.lastObservedAt = candidate.observedAt;\n bumpEntryPhaseSignal(duplicate, 'sourceCount');\n bumpEntryPhaseSignal(duplicate, 'lightHits');\n }\n deduped += 1;\n continue;\n }\n store.entries[key] = newLightEntry(candidate);\n newSignals += 1;\n }\n if (scannedEntries > 0) {\n store.updatedAt = startedAt;\n await saveDreamingStore({ dreamingRoot: params.dreamingRoot, store });\n }\n return { scannedEntries, newSignals, deduped };\n });\n await writeLastRun(params.dreamingRoot, {\n runId, startedAt, cfg, ok: true, reason: 'light sweep complete', startMs, light: result,\n });\n return { ok: true, reason: 'light sweep complete', ...result };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n await writeLastRun(params.dreamingRoot, {\n runId, startedAt, cfg, ok: false, reason: `light error: ${errorMessage}`, startMs,\n light: { scannedEntries: 0, newSignals: 0, deduped: 0 }, errorMessage,\n }).catch(() => undefined);\n return { ok: false, reason: errorMessage, scannedEntries: 0, newSignals: 0, deduped: 0 };\n }\n}\n\ntype LightCandidate = {\n path: string;\n startLine: number;\n endLine: number;\n snippet: string;\n observedAt: string;\n observedAtMs: number;\n};\n\nasync function scanRecentMemoryLines(workspaceDir: string, lookbackDays: number, now: Date): Promise<LightCandidate[]> {\n const root = path.join(workspaceDir, 'memory');\n const cutoffMs = now.getTime() - lookbackDays * 24 * 60 * 60 * 1_000;\n const files = await listMarkdownFiles(root);\n const out: LightCandidate[] = [];\n for (const filePath of files) {\n const stat = await fs.stat(filePath).catch(() => null);\n if (!stat || stat.mtimeMs < cutoffMs) continue;\n const content = await fs.readFile(filePath, 'utf-8').catch(() => '');\n const relativePath = normalizeMemoryPath(path.relative(workspaceDir, filePath));\n let inFence = false;\n for (const [index, rawLine] of content.split(/\\r?\\n/).entries()) {\n if (/^\\s*```/.test(rawLine)) {\n inFence = !inFence;\n continue;\n }\n if (inFence) continue;\n const snippet = rawLine.replace(/^\\s*[-*]\\s+/, '').trim();\n if (snippet.length < 8 || snippet.startsWith('#') || snippet.startsWith('<!--')) continue;\n out.push({\n path: relativePath,\n startLine: index + 1,\n endLine: index + 1,\n snippet: snippet.slice(0, 360),\n observedAt: stat.mtime.toISOString(),\n observedAtMs: stat.mtimeMs,\n });\n }\n }\n return out.sort((left, right) =>\n right.observedAtMs - left.observedAtMs\n || left.path.localeCompare(right.path)\n || left.startLine - right.startLine,\n );\n}\n\nasync function listMarkdownFiles(root: string): Promise<string[]> {\n const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);\n const out: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(root, entry.name);\n if (entry.isDirectory()) out.push(...await listMarkdownFiles(fullPath));\n else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) out.push(fullPath);\n }\n return out;\n}\n\nfunction similarity(left: string, right: string): number {\n const tokens = (value: string) => new Set(value.toLocaleLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []);\n const a = tokens(left);\n const b = tokens(right);\n if (a.size === 0 || b.size === 0) return 0;\n let intersection = 0;\n for (const token of a) if (b.has(token)) intersection += 1;\n return intersection / (a.size + b.size - intersection);\n}\n\nfunction observedAtOrZero(entry: DreamingStoreEntry): number {\n const parsed = entry.lastObservedAt ? Date.parse(entry.lastObservedAt) : 0;\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction newLightEntry(candidate: LightCandidate): DreamingStoreEntry {\n const key = buildEntryKey(candidate);\n return {\n key,\n path: candidate.path,\n startLine: candidate.startLine,\n endLine: candidate.endLine,\n snippet: candidate.snippet,\n recallCount: 0,\n sourceCount: 1,\n groundedCount: 0,\n lightHits: 1,\n remHits: 0,\n phaseHitCount: 2,\n totalSignalCount: 2,\n totalScore: 0,\n maxScore: 0,\n queryHashes: [],\n recallDays: [],\n firstRecalledAt: candidate.observedAt,\n lastRecalledAt: candidate.observedAt,\n lastObservedAt: candidate.observedAt,\n };\n}\n\n// ── Last-run writer ────────────────────────────────────────────────────\n\nasync function writeLastRun(\n dreamingRoot: string,\n params: {\n runId: string;\n startedAt: string;\n cfg: DreamingLightConfig;\n ok: boolean;\n reason: string;\n startMs: number;\n light: DreamingLightLastRun['light'];\n errorMessage?: string;\n },\n): Promise<void> {\n const finishedAt = new Date().toISOString();\n const durationMs = Math.max(0, Date.now() - params.startMs);\n\n const lastRun: DreamingLightLastRun = {\n version: DREAMING_LAST_RUN_FORMAT_VERSION,\n phase: 'light',\n runId: params.runId,\n startedAt: params.startedAt,\n finishedAt,\n durationMs,\n ok: params.ok,\n reason: params.reason,\n config: params.cfg,\n light: params.light,\n ...(params.errorMessage ? { errorMessage: params.errorMessage } : {}),\n };\n\n const lastRunPath = path.join(dreamingRoot, DREAMING_DIR_RELATIVE, 'last-run-light.json');\n await fs.mkdir(path.dirname(lastRunPath), { recursive: true });\n const tmp = `${lastRunPath}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(lastRun, null, 2)}\\n`, 'utf-8');\n await fs.rename(tmp, lastRunPath);\n}\n"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { MemoryRecord, MemorySensitivity } from '../types.js';
2
+ export interface DreamingPromotionInput {
3
+ agentId: string;
4
+ workspaceId: string;
5
+ candidateKey: string;
6
+ content: string;
7
+ sourcePath: string;
8
+ lineStart: number;
9
+ lineEnd: number;
10
+ score: number;
11
+ recallCount: number;
12
+ observedAt: string;
13
+ sensitivity: MemorySensitivity;
14
+ }
15
+ /** Persist a promoted Dreaming insight as the authoritative structured record. */
16
+ export declare function activateDreamingPromotion(input: DreamingPromotionInput): MemoryRecord;
17
+ export interface RemInsightInput {
18
+ agentId: string;
19
+ workspaceId: string;
20
+ memberKeys: string[];
21
+ representative: string;
22
+ distinctPaths: string[];
23
+ strength: number;
24
+ observedAt: string;
25
+ evidence: string[];
26
+ sensitivity: MemorySensitivity;
27
+ }
28
+ export declare function remPatternKey(memberKeys: string[]): string;
29
+ /** Persist a REM cluster as a stable, recallable derived insight. */
30
+ export declare function activateRemInsight(input: RemInsightInput): MemoryRecord;
@@ -0,0 +1,85 @@
1
+ import { upsertMemoryRecord } from "../../../storage/sqlite/memory-records-repository.js";
2
+ import "../../../storage/sqlite/index.js";
3
+ import { createHash } from "node:crypto";
4
+ //#region src/agent/memory/dreaming/promotion-lifecycle.ts
5
+ /** Persist a promoted Dreaming insight as the authoritative structured record. */
6
+ function activateDreamingPromotion(input) {
7
+ return upsertMemoryRecord({
8
+ id: `dreaming:${createHash("sha256").update(`${input.agentId}\0${input.candidateKey}`).digest("hex").slice(0, 32)}`,
9
+ providerId: "local",
10
+ kind: "project_context",
11
+ agentId: input.agentId,
12
+ workspaceId: input.workspaceId,
13
+ content: input.content,
14
+ source: {
15
+ provider: "dreaming",
16
+ path: input.sourcePath,
17
+ lineStart: input.lineStart,
18
+ lineEnd: input.lineEnd
19
+ },
20
+ confidence: input.score,
21
+ status: "active",
22
+ sensitivity: input.sensitivity,
23
+ canonicalKey: `dreaming:${input.candidateKey}`,
24
+ explicitness: "observed",
25
+ durability: "durable",
26
+ importance: input.score,
27
+ disclosurePolicy: "referenceable",
28
+ evidence: [{
29
+ relation: "derived_from",
30
+ sourceText: input.content,
31
+ observedAt: input.observedAt,
32
+ confidence: input.score
33
+ }],
34
+ tags: [
35
+ "dreaming",
36
+ "promoted",
37
+ `recalls:${input.recallCount}`
38
+ ]
39
+ });
40
+ }
41
+ function remPatternKey(memberKeys) {
42
+ return createHash("sha256").update([...memberKeys].sort().join("\0")).digest("hex").slice(0, 24);
43
+ }
44
+ /** Persist a REM cluster as a stable, recallable derived insight. */
45
+ function activateRemInsight(input) {
46
+ const patternKey = remPatternKey(input.memberKeys);
47
+ const content = `Recurring context across ${input.distinctPaths.length} memory sources: ${input.representative}`;
48
+ return upsertMemoryRecord({
49
+ id: `dreaming-rem:${input.agentId}:${patternKey}`,
50
+ providerId: "local",
51
+ kind: "derived_insight",
52
+ agentId: input.agentId,
53
+ workspaceId: input.workspaceId,
54
+ content,
55
+ source: {
56
+ provider: "dreaming",
57
+ path: "DREAMS.md"
58
+ },
59
+ confidence: input.strength,
60
+ status: "active",
61
+ sensitivity: input.sensitivity,
62
+ canonicalKey: `dreaming-rem:${patternKey}`,
63
+ explicitness: "inferred",
64
+ durability: "recurring",
65
+ importance: input.strength,
66
+ disclosurePolicy: "referenceable",
67
+ evidence: input.evidence.slice(0, 8).map((sourceText) => ({
68
+ relation: "derived_from",
69
+ sourceText,
70
+ observedAt: input.observedAt,
71
+ confidence: input.strength
72
+ })),
73
+ tags: [
74
+ "dreaming",
75
+ "rem",
76
+ "derived-insight",
77
+ `strength:${input.strength.toFixed(2)}`,
78
+ `sources:${input.distinctPaths.length}`
79
+ ]
80
+ });
81
+ }
82
+ //#endregion
83
+ export { activateDreamingPromotion, activateRemInsight, remPatternKey };
84
+
85
+ //# sourceMappingURL=promotion-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-lifecycle.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/promotion-lifecycle.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport { upsertMemoryRecord } from '../../../storage/sqlite/index.js';\nimport type { MemoryRecord, MemorySensitivity } from '../types.js';\n\nexport interface DreamingPromotionInput {\n agentId: string;\n workspaceId: string;\n candidateKey: string;\n content: string;\n sourcePath: string;\n lineStart: number;\n lineEnd: number;\n score: number;\n recallCount: number;\n observedAt: string;\n sensitivity: MemorySensitivity;\n}\n\n/** Persist a promoted Dreaming insight as the authoritative structured record. */\nexport function activateDreamingPromotion(input: DreamingPromotionInput): MemoryRecord {\n const stableId = createHash('sha256')\n .update(`${input.agentId}\\0${input.candidateKey}`)\n .digest('hex')\n .slice(0, 32);\n return upsertMemoryRecord({\n id: `dreaming:${stableId}`,\n providerId: 'local',\n kind: 'project_context',\n agentId: input.agentId,\n workspaceId: input.workspaceId,\n content: input.content,\n source: {\n provider: 'dreaming',\n path: input.sourcePath,\n lineStart: input.lineStart,\n lineEnd: input.lineEnd,\n },\n confidence: input.score,\n status: 'active',\n sensitivity: input.sensitivity,\n canonicalKey: `dreaming:${input.candidateKey}`,\n explicitness: 'observed',\n durability: 'durable',\n importance: input.score,\n disclosurePolicy: 'referenceable',\n evidence: [{\n relation: 'derived_from',\n sourceText: input.content,\n observedAt: input.observedAt,\n confidence: input.score,\n }],\n tags: ['dreaming', 'promoted', `recalls:${input.recallCount}`],\n });\n}\n\nexport interface RemInsightInput {\n agentId: string;\n workspaceId: string;\n memberKeys: string[];\n representative: string;\n distinctPaths: string[];\n strength: number;\n observedAt: string;\n evidence: string[];\n sensitivity: MemorySensitivity;\n}\n\nexport function remPatternKey(memberKeys: string[]): string {\n return createHash('sha256').update([...memberKeys].sort().join('\\0')).digest('hex').slice(0, 24);\n}\n\n/** Persist a REM cluster as a stable, recallable derived insight. */\nexport function activateRemInsight(input: RemInsightInput): MemoryRecord {\n const patternKey = remPatternKey(input.memberKeys);\n const content = `Recurring context across ${input.distinctPaths.length} memory sources: ${input.representative}`;\n return upsertMemoryRecord({\n id: `dreaming-rem:${input.agentId}:${patternKey}`,\n providerId: 'local',\n kind: 'derived_insight',\n agentId: input.agentId,\n workspaceId: input.workspaceId,\n content,\n source: { provider: 'dreaming', path: 'DREAMS.md' },\n confidence: input.strength,\n status: 'active',\n sensitivity: input.sensitivity,\n canonicalKey: `dreaming-rem:${patternKey}`,\n explicitness: 'inferred',\n durability: 'recurring',\n importance: input.strength,\n disclosurePolicy: 'referenceable',\n evidence: input.evidence.slice(0, 8).map((sourceText) => ({\n relation: 'derived_from',\n sourceText,\n observedAt: input.observedAt,\n confidence: input.strength,\n })),\n tags: [\n 'dreaming',\n 'rem',\n 'derived-insight',\n `strength:${input.strength.toFixed(2)}`,\n `sources:${input.distinctPaths.length}`,\n ],\n });\n}\n"],"mappings":";;;;;AAoBA,SAAgB,0BAA0B,OAA6C;AAKrF,QAAO,mBAAmB;EACxB,IAAI,YALW,WAAW,SAAS,CAClC,OAAO,GAAG,MAAM,QAAQ,IAAI,MAAM,eAAe,CACjD,OAAO,MAAM,CACb,MAAM,GAAG,GAEc;EACxB,YAAY;EACZ,MAAM;EACN,SAAS,MAAM;EACf,aAAa,MAAM;EACnB,SAAS,MAAM;EACf,QAAQ;GACN,UAAU;GACV,MAAM,MAAM;GACZ,WAAW,MAAM;GACjB,SAAS,MAAM;GAChB;EACD,YAAY,MAAM;EAClB,QAAQ;EACR,aAAa,MAAM;EACnB,cAAc,YAAY,MAAM;EAChC,cAAc;EACd,YAAY;EACZ,YAAY,MAAM;EAClB,kBAAkB;EAClB,UAAU,CAAC;GACT,UAAU;GACV,YAAY,MAAM;GAClB,YAAY,MAAM;GAClB,YAAY,MAAM;GACnB,CAAC;EACF,MAAM;GAAC;GAAY;GAAY,WAAW,MAAM;GAAc;EAC/D,CAAC;;AAeJ,SAAgB,cAAc,YAA8B;AAC1D,QAAO,WAAW,SAAS,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;AAIlG,SAAgB,mBAAmB,OAAsC;CACvE,MAAM,aAAa,cAAc,MAAM,WAAW;CAClD,MAAM,UAAU,4BAA4B,MAAM,cAAc,OAAO,mBAAmB,MAAM;AAChG,QAAO,mBAAmB;EACxB,IAAI,gBAAgB,MAAM,QAAQ,GAAG;EACrC,YAAY;EACZ,MAAM;EACN,SAAS,MAAM;EACf,aAAa,MAAM;EACnB;EACA,QAAQ;GAAE,UAAU;GAAY,MAAM;GAAa;EACnD,YAAY,MAAM;EAClB,QAAQ;EACR,aAAa,MAAM;EACnB,cAAc,gBAAgB;EAC9B,cAAc;EACd,YAAY;EACZ,YAAY,MAAM;EAClB,kBAAkB;EAClB,UAAU,MAAM,SAAS,MAAM,GAAG,EAAE,CAAC,KAAK,gBAAgB;GACxD,UAAU;GACV;GACA,YAAY,MAAM;GAClB,YAAY,MAAM;GACnB,EAAE;EACH,MAAM;GACJ;GACA;GACA;GACA,YAAY,MAAM,SAAS,QAAQ,EAAE;GACrC,WAAW,MAAM,cAAc;GAChC;EACF,CAAC"}
@@ -10,8 +10,12 @@ import type { DreamingRemConfig } from './config.js';
10
10
  * Runs weekly; expensive but insightful.
11
11
  */
12
12
  export declare function runRemPatterns(params: {
13
+ agentId: string;
14
+ workspaceDir: string;
13
15
  dreamingRoot: string;
14
16
  config?: Partial<DreamingRemConfig>;
17
+ sensitiveWritePolicy?: 'deny' | 'confirm' | 'allow';
18
+ promotionWritePolicy?: 'deny' | 'confirm' | 'allow';
15
19
  now?: Date;
16
20
  }): Promise<{
17
21
  ok: boolean;