@xopcai/xopc 0.0.136 → 0.0.138

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 (271) hide show
  1. package/README.md +4 -0
  2. package/README.zh-CN.md +4 -0
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/demo-memory/src/index.js +4 -0
  5. package/dist/extensions/demo-memory/src/index.js.map +1 -1
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CER17NHM.js → agent-avatar-dicebear-CIsGDJzd.js} +1 -1
  8. package/dist/gateway/static/root/assets/agents-fX97A6iN.js +2 -0
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-B3Ap_wpX.js → app-management-settings-panel-ByM4Bzwm.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-3kBO22Xd.js → appearance-settings-BF_poRd3.js} +1 -1
  11. package/dist/gateway/static/root/assets/{apps-page-BHYbGQcZ.js → apps-page-BssdA5Qc.js} +1 -1
  12. package/dist/gateway/static/root/assets/{archive-plugin-D_vGeNB8.js → archive-plugin-DJaYoyGn.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-hWV_8pHL.js → attachment-load-xx6dBaZU.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automation-suggestion-card-DVKmVTIo.js → automation-suggestion-card-BMvGqYob.js} +1 -1
  15. package/dist/gateway/static/root/assets/{automations-page-BCTXpOBp.js → automations-page-Dip8ZFmx.js} +1 -1
  16. package/dist/gateway/static/root/assets/{binary-plugins-BuXIeSPc.js → binary-plugins-CuPLWibr.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-C1m0u-UU.js → block-editor-bzfvlJnh.js} +58 -54
  18. package/dist/gateway/static/root/assets/{browser-settings-page-ChUF08V5.js → browser-settings-page-lbx_8Dku.js} +4 -4
  19. package/dist/gateway/static/root/assets/{capability-presets-api-B7WWYaEh.js → capability-presets-api-X4Imbf8n.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-D_Bh1PnA.js → capability-presets-settings-panel-v9JgKjJu.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-sV06LCht.js → channel-recipient-api-DllrPmp-.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-settings-BI2ChQc7.js → channels-settings-CED7Oy5Y.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-status-swr-EUwWYx8l.js +1 -0
  24. package/dist/gateway/static/root/assets/{connectors-page-qgvEp09M.js → connectors-page-BMfp0jWL.js} +1 -1
  25. package/dist/gateway/static/root/assets/{desktop-pet-BxMJlvb-.js → desktop-pet-oTig6qFO.js} +1 -1
  26. package/dist/gateway/static/root/assets/{desktop-pet-settings-DCvpDImn.js → desktop-pet-settings-DXJiPL_H.js} +1 -1
  27. package/dist/gateway/static/root/assets/{directory-picker-path-field-D1nxs9PA.js → directory-picker-path-field-CltkXSR2.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dreaming-settings-EAWkpOgw.js → dreaming-settings-CYrZQxoL.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-debug-page-LUQ8dE8z.js → extension-debug-page-C-4BOy1R.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-page-B_mnhoRd.js → extension-page-C8nMpXqh.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-settings-page-BWQsGmvW.js → extension-settings-page-CXWYOwka.js} +1 -1
  32. package/dist/gateway/static/root/assets/{fetch-BWXmBizE.js → fetch-BID89uCH.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-M9bzPASf.js → gateway-config-api-B3TGdim5.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-CbgtpprN.js → gateway-settings-D7tOnGAJ.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-BALL91S7.js → gateway-startup-retry-BkrLLlpE.js} +1 -1
  36. package/dist/gateway/static/root/assets/{goal-create-dialog-CbP4t9aM.js → goal-create-dialog-BL_cRshf.js} +1 -1
  37. package/dist/gateway/static/root/assets/{goal-detail-page-DlwI-MZZ.js → goal-detail-page-T1vg6Ng_.js} +1 -1
  38. package/dist/gateway/static/root/assets/{goals-config-api-BBhFVzBS.js → goals-config-api-D-WZWhP2.js} +1 -1
  39. package/dist/gateway/static/root/assets/{goals-page-D26r7knp.js → goals-page-1vzWXl5W.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goals-settings-DdmVG_TR.js → goals-settings-DgGwvLVC.js} +1 -1
  41. package/dist/gateway/static/root/assets/{heartbeat-settings-DZW2Xq-U.js → heartbeat-settings-yh0bEIwQ.js} +1 -1
  42. package/dist/gateway/static/root/assets/index-B8s8Pq5U.css +1 -0
  43. package/dist/gateway/static/root/assets/index-NwiCnzI-.js +262 -0
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-1IWd88-T.js → keyboard-shortcuts-settings-CnxRFbgA.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-DxoKJO7-.js → logs-page-DebnvTpD.js} +1 -1
  46. package/dist/gateway/static/root/assets/{markdown-split-BtdBj32h.js → markdown-split-BU69Nof8.js} +1 -1
  47. package/dist/gateway/static/root/assets/{media-plugins-CpoPj3s8.js → media-plugins-CDs7OvWt.js} +1 -1
  48. package/dist/gateway/static/root/assets/messages-DbNQuFdA.js +3 -0
  49. package/dist/gateway/static/root/assets/{models-hub-panel-D1Rp__dV.js → models-hub-panel-Ca_jy26S.js} +1 -1
  50. package/dist/gateway/static/root/assets/{notes-page-CgR1bO2W.js → notes-page-DTpeaI65.js} +1 -1
  51. package/dist/gateway/static/root/assets/{notes-workbench-ozsnmDTV.js → notes-workbench-uKMYsjUU.js} +2 -2
  52. package/dist/gateway/static/root/assets/{page-tabs-CVLqCfQB.js → page-tabs-CROo8Vgz.js} +1 -1
  53. package/dist/gateway/static/root/assets/{preview-open-alternatives-CKUXJk2t.js → preview-open-alternatives-BxsS9i1G.js} +1 -1
  54. package/dist/gateway/static/root/assets/{project-detail-page-B4dqFAQF.js → project-detail-page-BWKOhshy.js} +1 -1
  55. package/dist/gateway/static/root/assets/{projects-page-DlRGXv4a.js → projects-page-CoowiCLe.js} +1 -1
  56. package/dist/gateway/static/root/assets/{remote-access-hub-rZEYQMZV.js → remote-access-hub-CiOaX1wd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{save-bar-controls-BtGni268.js → save-bar-controls-B4N17dMG.js} +1 -1
  58. package/dist/gateway/static/root/assets/{schedule-field-BDGzKVWn.js → schedule-field-ClJzQ2vz.js} +1 -1
  59. package/dist/gateway/static/root/assets/{schema-form-DQJsKMCE.js → schema-form-oZvQUfDg.js} +1 -1
  60. package/dist/gateway/static/root/assets/{sessions-page-DxGoCGU8.js → sessions-page-Sx9Gc0cv.js} +1 -1
  61. package/dist/gateway/static/root/assets/settings-advanced-gate-CnbVdze4.js +1 -0
  62. package/dist/gateway/static/root/assets/{settings-collapsible-section-c8XGd4-8.js → settings-collapsible-section-B0kOLXUf.js} +1 -1
  63. package/dist/gateway/static/root/assets/{settings-form-section-By0YiDWo.js → settings-form-section-DoVPlVFd.js} +1 -1
  64. package/dist/gateway/static/root/assets/{settings-loading-skeleton-SYCPY-WM.js → settings-loading-skeleton-C7J96bLc.js} +1 -1
  65. package/dist/gateway/static/root/assets/{settings-page-D9NwvnBt.js → settings-page-CXiAByF0.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-layout-CrICyGob.js → settings-page-layout-R-6ArlMI.js} +1 -1
  67. package/dist/gateway/static/root/assets/{setup-status-panel-IjK-hDxf.js → setup-status-panel-Drz23n9l.js} +1 -1
  68. package/dist/gateway/static/root/assets/{share-preview-page-Dfnk9M_m.js → share-preview-page-Bn1umseg.js} +1 -1
  69. package/dist/gateway/static/root/assets/{shares-settings-vQiRBra7.js → shares-settings-Bb-pcMWg.js} +1 -1
  70. package/dist/gateway/static/root/assets/skill-reload-api-DE9HCHct.js +1 -0
  71. package/dist/gateway/static/root/assets/{skills-page-CruV215G.js → skills-page-B6cDPqkk.js} +1 -1
  72. package/dist/gateway/static/root/assets/{system-settings-panel-BBVbSDFD.js → system-settings-panel-CtEddAy-.js} +1 -1
  73. package/dist/gateway/static/root/assets/{typed-models-lib-CwFayhxu.js → typed-models-lib-BkhSnYq7.js} +1 -1
  74. package/dist/gateway/static/root/assets/{use-channel-catalog-BKtHOM50.js → use-channel-catalog-EA4hfbsP.js} +1 -1
  75. package/dist/gateway/static/root/assets/{user-profile-settings-panel-_KDWzagh.js → user-profile-settings-panel-BssTVOBS.js} +1 -1
  76. package/dist/gateway/static/root/assets/{utils-BiUjIHb4.js → utils-CI3ywKLT.js} +1 -1
  77. package/dist/gateway/static/root/assets/{voice-api-key-field-agJqlm4o.js → voice-api-key-field-DXMEGw9O.js} +1 -1
  78. package/dist/gateway/static/root/assets/{work-item-detail-page-Bdw4ATCb.js → work-item-detail-page-DsFqU0tK.js} +1 -1
  79. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D-Dy6mTy.js → workflow-run-setup-panel-DImBi-m6.js} +1 -1
  80. package/dist/gateway/static/root/assets/{workflow-start-dialog-GammZ2GK.js → workflow-start-dialog-DuPpKAAc.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflows-page-Cw5zrqti.js → workflows-page-DfTVzTNY.js} +1 -1
  82. package/dist/gateway/static/root/index.html +5 -5
  83. package/dist/package.js +1 -1
  84. package/dist/src/agent/agent-instance-gateway.d.ts +3 -3
  85. package/dist/src/agent/agent-manager.d.ts +7 -8
  86. package/dist/src/agent/agent-manager.js +24 -25
  87. package/dist/src/agent/agent-manager.js.map +1 -1
  88. package/dist/src/agent/background-review/coordinator.d.ts +9 -23
  89. package/dist/src/agent/background-review/coordinator.js +45 -54
  90. package/dist/src/agent/background-review/coordinator.js.map +1 -1
  91. package/dist/src/agent/background-review/prompts.d.ts +2 -4
  92. package/dist/src/agent/background-review/prompts.js +7 -19
  93. package/dist/src/agent/background-review/prompts.js.map +1 -1
  94. package/dist/src/agent/background-review/run-background-review.d.ts +0 -8
  95. package/dist/src/agent/background-review/run-background-review.js +87 -72
  96. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  97. package/dist/src/agent/background-review/settings.d.ts +4 -4
  98. package/dist/src/agent/background-review/settings.js +25 -10
  99. package/dist/src/agent/background-review/settings.js.map +1 -1
  100. package/dist/src/agent/code-intelligence/binary.d.ts +1 -0
  101. package/dist/src/agent/code-intelligence/binary.js +42 -0
  102. package/dist/src/agent/code-intelligence/binary.js.map +1 -0
  103. package/dist/src/agent/code-intelligence/index.d.ts +4 -0
  104. package/dist/src/agent/code-intelligence/index.js +4 -0
  105. package/dist/src/agent/code-intelligence/runtime.d.ts +34 -0
  106. package/dist/src/agent/code-intelligence/runtime.js +282 -0
  107. package/dist/src/agent/code-intelligence/runtime.js.map +1 -0
  108. package/dist/src/agent/code-intelligence/tools.d.ts +6 -0
  109. package/dist/src/agent/code-intelligence/tools.js +268 -0
  110. package/dist/src/agent/code-intelligence/tools.js.map +1 -0
  111. package/dist/src/agent/code-intelligence/types.d.ts +22 -0
  112. package/dist/src/agent/code-intelligence/types.js +1 -0
  113. package/dist/src/agent/memory/builtin-provider.d.ts +1 -2
  114. package/dist/src/agent/memory/builtin-provider.js +31 -12
  115. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  116. package/dist/src/agent/memory/context/planner.d.ts +11 -0
  117. package/dist/src/agent/memory/context/planner.js +163 -0
  118. package/dist/src/agent/memory/context/planner.js.map +1 -0
  119. package/dist/src/agent/memory/context/types.d.ts +19 -0
  120. package/dist/src/agent/memory/context/types.js +1 -0
  121. package/dist/src/agent/memory/context-fence.d.ts +3 -3
  122. package/dist/src/agent/memory/context-fence.js +9 -9
  123. package/dist/src/agent/memory/context-fence.js.map +1 -1
  124. package/dist/src/agent/memory/index.d.ts +6 -4
  125. package/dist/src/agent/memory/index.js +5 -5
  126. package/dist/src/agent/memory/manager.d.ts +16 -4
  127. package/dist/src/agent/memory/manager.js +32 -34
  128. package/dist/src/agent/memory/manager.js.map +1 -1
  129. package/dist/src/agent/memory/memory-config.d.ts +1 -1
  130. package/dist/src/agent/memory/memory-config.js +2 -2
  131. package/dist/src/agent/memory/memory-config.js.map +1 -1
  132. package/dist/src/agent/memory/provider.d.ts +1 -3
  133. package/dist/src/agent/memory/stub-memory-provider.d.ts +0 -1
  134. package/dist/src/agent/memory/stub-memory-provider.js +0 -5
  135. package/dist/src/agent/memory/stub-memory-provider.js.map +1 -1
  136. package/dist/src/agent/memory/types.d.ts +31 -2
  137. package/dist/src/agent/memory/understanding/correction.d.ts +3 -0
  138. package/dist/src/agent/memory/understanding/correction.js +41 -0
  139. package/dist/src/agent/memory/understanding/correction.js.map +1 -0
  140. package/dist/src/agent/memory/understanding/quality.d.ts +8 -0
  141. package/dist/src/agent/memory/understanding/quality.js +20 -0
  142. package/dist/src/agent/memory/understanding/quality.js.map +1 -0
  143. package/dist/src/agent/memory/understanding/service.d.ts +26 -0
  144. package/dist/src/agent/memory/understanding/service.js +233 -0
  145. package/dist/src/agent/memory/understanding/service.js.map +1 -0
  146. package/dist/src/agent/memory/understanding/types.d.ts +22 -0
  147. package/dist/src/agent/memory/understanding/types.js +1 -0
  148. package/dist/src/agent/memory/user-context-coordinator.d.ts +21 -0
  149. package/dist/src/agent/memory/user-context-coordinator.js +90 -0
  150. package/dist/src/agent/memory/user-context-coordinator.js.map +1 -0
  151. package/dist/src/agent/orchestration/agent-event-handler.d.ts +1 -0
  152. package/dist/src/agent/orchestration/agent-event-handler.js +1 -1
  153. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  154. package/dist/src/agent/orchestration/agent-orchestrator.js +2 -2
  155. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  156. package/dist/src/agent/orchestration/index.d.ts +1 -1
  157. package/dist/src/agent/orchestration/index.js +2 -2
  158. package/dist/src/agent/prompt/sections/tooling.js +10 -0
  159. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  160. package/dist/src/agent/prompt/system-prompt.js +2 -0
  161. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  162. package/dist/src/agent/service/direct-turn-helpers.js +2 -2
  163. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  164. package/dist/src/agent/service.js +7 -1
  165. package/dist/src/agent/service.js.map +1 -1
  166. package/dist/src/agent/session/session-inspector.d.ts +1 -0
  167. package/dist/src/agent/session/session-inspector.js +8 -2
  168. package/dist/src/agent/session/session-inspector.js.map +1 -1
  169. package/dist/src/agent/tools/factory.d.ts +3 -0
  170. package/dist/src/agent/tools/factory.js +17 -10
  171. package/dist/src/agent/tools/factory.js.map +1 -1
  172. package/dist/src/agent/tools/index.d.ts +1 -0
  173. package/dist/src/agent/tools/index.js +2 -1
  174. package/dist/src/agent/workspace-runtime/registry.d.ts +2 -0
  175. package/dist/src/agent/workspace-runtime/registry.js +11 -3
  176. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  177. package/dist/src/agent-manifest/index.js +2 -2
  178. package/dist/src/agent-manifest/schema.d.ts +91 -0
  179. package/dist/src/agent-manifest/schema.js +27 -5
  180. package/dist/src/agent-manifest/schema.js.map +1 -1
  181. package/dist/src/agent-runtime/memory-runtime.d.ts +1 -1
  182. package/dist/src/agent-runtime/memory-runtime.js.map +1 -1
  183. package/dist/src/automations/domain/validation.d.ts +22 -22
  184. package/dist/src/automations/draft/automation-draft-validator.d.ts +4 -4
  185. package/dist/src/cli/command-loaders.js +1 -0
  186. package/dist/src/cli/command-loaders.js.map +1 -1
  187. package/dist/src/cli/command-manifest.js +4 -0
  188. package/dist/src/cli/command-manifest.js.map +1 -1
  189. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  190. package/dist/src/cli/commands/resume.d.ts +1 -0
  191. package/dist/src/cli/commands/resume.js +31 -0
  192. package/dist/src/cli/commands/resume.js.map +1 -0
  193. package/dist/src/cli/commands/tui-runner.d.ts +9 -0
  194. package/dist/src/cli/commands/tui-runner.js +40 -0
  195. package/dist/src/cli/commands/tui-runner.js.map +1 -0
  196. package/dist/src/cli/commands/tui.js +4 -28
  197. package/dist/src/cli/commands/tui.js.map +1 -1
  198. package/dist/src/config/agent-profile.js +1 -1
  199. package/dist/src/config/index.js +2 -2
  200. package/dist/src/config/schema.d.ts +115 -0
  201. package/dist/src/config/schema.js +53 -4
  202. package/dist/src/config/schema.js.map +1 -1
  203. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  204. package/dist/src/gateway/agent-builtin-tools.js +5 -0
  205. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  206. package/dist/src/gateway/agents-admin.js +1 -1
  207. package/dist/src/gateway/hono/lib/config-payload.d.ts +18 -4
  208. package/dist/src/gateway/hono/routes/home.js +37 -2
  209. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  210. package/dist/src/gateway/hono/routes/memory.js +129 -4
  211. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  212. package/dist/src/gateway/hono/routes/projects.js +16 -0
  213. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  214. package/dist/src/knowledge/index.d.ts +2 -0
  215. package/dist/src/knowledge/index.js +2 -0
  216. package/dist/src/knowledge/ingestion-service.d.ts +20 -0
  217. package/dist/src/knowledge/ingestion-service.js +75 -0
  218. package/dist/src/knowledge/ingestion-service.js.map +1 -0
  219. package/dist/src/knowledge/types.d.ts +70 -0
  220. package/dist/src/knowledge/types.js +1 -0
  221. package/dist/src/projects/project-kind.js +0 -1
  222. package/dist/src/projects/project-kind.js.map +1 -1
  223. package/dist/src/providers/presentation.js +1 -1
  224. package/dist/src/providers/presentation.js.map +1 -1
  225. package/dist/src/storage/sqlite/index.d.ts +2 -1
  226. package/dist/src/storage/sqlite/index.js +3 -2
  227. package/dist/src/storage/sqlite/knowledge-repository.d.ts +50 -0
  228. package/dist/src/storage/sqlite/knowledge-repository.js +237 -0
  229. package/dist/src/storage/sqlite/knowledge-repository.js.map +1 -0
  230. package/dist/src/storage/sqlite/memory-records-repository.d.ts +80 -2
  231. package/dist/src/storage/sqlite/memory-records-repository.js +271 -9
  232. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  233. package/dist/src/storage/sqlite/migrations/029_user_understanding.sql +133 -0
  234. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  235. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  236. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  237. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  238. package/dist/src/storage/sqlite/schema.js +1 -1
  239. package/dist/src/tui/tui-picker-overlay.d.ts +6 -1
  240. package/dist/src/tui/tui-picker-overlay.js +4 -1
  241. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  242. package/dist/src/tui/tui-types.d.ts +2 -0
  243. package/dist/src/tui/tui-types.js.map +1 -1
  244. package/dist/src/tui/tui.js +17 -2
  245. package/dist/src/tui/tui.js.map +1 -1
  246. package/dist/src/work-items/work-item-service.d.ts +1 -0
  247. package/dist/src/work-items/work-item-service.js +3 -0
  248. package/dist/src/work-items/work-item-service.js.map +1 -1
  249. package/dist/src/work-items/work-item-store.d.ts +1 -0
  250. package/dist/src/work-items/work-item-store.js +13 -0
  251. package/dist/src/work-items/work-item-store.js.map +1 -1
  252. package/package.json +2 -1
  253. package/dist/gateway/static/root/assets/agents-Bv5R-N8Q.js +0 -2
  254. package/dist/gateway/static/root/assets/channels-status-swr-MY4Xh4fM.js +0 -1
  255. package/dist/gateway/static/root/assets/index-CPwVzi9x.css +0 -1
  256. package/dist/gateway/static/root/assets/index-DZOm5_ex.js +0 -262
  257. package/dist/gateway/static/root/assets/messages-CQ_k8RHj.js +0 -3
  258. package/dist/gateway/static/root/assets/settings-advanced-gate-4e8ZQwxr.js +0 -1
  259. package/dist/gateway/static/root/assets/skill-reload-api-BIWv778A.js +0 -1
  260. package/dist/src/agent/memory/candidate-extractor.d.ts +0 -6
  261. package/dist/src/agent/memory/candidate-extractor.js +0 -60
  262. package/dist/src/agent/memory/candidate-extractor.js.map +0 -1
  263. package/dist/src/agent/memory/context-assembler.d.ts +0 -10
  264. package/dist/src/agent/memory/context-assembler.js +0 -26
  265. package/dist/src/agent/memory/context-assembler.js.map +0 -1
  266. package/dist/src/agent/memory/inject-prefetch.d.ts +0 -6
  267. package/dist/src/agent/memory/inject-prefetch.js +0 -48
  268. package/dist/src/agent/memory/inject-prefetch.js.map +0 -1
  269. package/dist/src/agent/memory/prefetch-coordinator.d.ts +0 -37
  270. package/dist/src/agent/memory/prefetch-coordinator.js +0 -45
  271. package/dist/src/agent/memory/prefetch-coordinator.js.map +0 -1
@@ -31,13 +31,13 @@ function resolveBuiltinMemoryStoreConfig(workspaceDir, config) {
31
31
  * Whether to prefix the user message with prefetched external memory this turn.
32
32
  * `first-turn` only injects on turn 1. `contextCadence` N injects on turns 1, N+1, 2N+1, …
33
33
  */
34
- function shouldInjectMemoryPrefetchThisTurn(config, turnNumber) {
34
+ function shouldPlanUserContextThisTurn(_config, turnNumber) {
35
35
  return turnNumber >= 1;
36
36
  }
37
37
  function shouldRegisterCuratedMemoryTool(config) {
38
38
  return isCuratedMemoryInPrompt(config);
39
39
  }
40
40
  //#endregion
41
- export { isCuratedMemoryInPrompt, isMemorySubsystemEnabled, resolveBuiltinMemoryStoreConfig, shouldInjectMemoryPrefetchThisTurn, shouldRegisterCuratedMemoryTool };
41
+ export { isCuratedMemoryInPrompt, isMemorySubsystemEnabled, resolveBuiltinMemoryStoreConfig, shouldPlanUserContextThisTurn, shouldRegisterCuratedMemoryTool };
42
42
 
43
43
  //# sourceMappingURL=memory-config.js.map
@@ -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): MemoryStoreConfig {\n const agentId = config != null ? resolveAgentIdForWorkspacePath(config, workspaceDir) : 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?.maxItems ?? 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 shouldInjectMemoryPrefetchThisTurn(\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,QACmB;CACnB,MAAM,UAAU,UAAU,OAAO,+BAA+B,QAAQ,aAAa,GAAG,KAAA;CACxF,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,mCACd,QACA,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 { 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): MemoryStoreConfig {\n const agentId = config != null ? resolveAgentIdForWorkspacePath(config, workspaceDir) : 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?.maxItems ?? 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,QACmB;CACnB,MAAM,UAAU,UAAU,OAAO,+BAA+B,QAAQ,aAAa,GAAG,KAAA;CACxF,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"}
@@ -3,6 +3,7 @@ import type { MemoryCapabilities, MemoryDeleteRequest, MemoryListRequest, Memory
3
3
  export interface MemoryProviderInitOptions {
4
4
  workspace?: string;
5
5
  agentWorkspace?: string;
6
+ agentId?: string;
6
7
  sessionId?: string;
7
8
  config?: Record<string, unknown>;
8
9
  [key: string]: unknown;
@@ -16,9 +17,6 @@ export interface MemoryProvider {
16
17
  initialize(sessionId: string, options?: MemoryProviderInitOptions): Promise<void> | void;
17
18
  /** Static text merged into the system prompt. */
18
19
  systemPromptBlock?(): string;
19
- prefetch?(query: string, options?: {
20
- sessionId?: string;
21
- }): Promise<string>;
22
20
  queuePrefetch?(query: string, options?: {
23
21
  sessionId?: string;
24
22
  }): void;
@@ -21,7 +21,6 @@ export declare class StubMemoryProvider implements MemoryProvider {
21
21
  isAvailable(): boolean;
22
22
  initialize(_sessionId: string, _options?: MemoryProviderInitOptions): Promise<void>;
23
23
  systemPromptBlock(): string;
24
- prefetch(query: string): Promise<string>;
25
24
  queuePrefetch(): void;
26
25
  sync(): void;
27
26
  getToolSchemas(): any[];
@@ -25,11 +25,6 @@ var StubMemoryProvider = class {
25
25
  systemPromptBlock() {
26
26
  return "External memory provider: stub (wiring only; no cloud backend).";
27
27
  }
28
- async prefetch(query) {
29
- const q = query.trim();
30
- if (!q) return "";
31
- return `[stub prefetch] query length=${q.length}`;
32
- }
33
28
  queuePrefetch() {}
34
29
  sync() {}
35
30
  getToolSchemas() {
@@ -1 +1 @@
1
- {"version":3,"file":"stub-memory-provider.js","names":[],"sources":["../../../../src/agent/memory/stub-memory-provider.ts"],"sourcesContent":["import type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';\n\n/**\n * Placeholder external provider — enables wiring tests without cloud deps.\n */\nexport class StubMemoryProvider implements MemoryProvider {\n readonly id = 'stub';\n readonly displayName = 'Stub Memory Provider';\n readonly capabilities = {\n search: true,\n read: false,\n write: false,\n update: false,\n delete: false,\n keywordSearch: false,\n semanticSearch: false,\n hybridSearch: false,\n citations: false,\n sync: true,\n local: false,\n };\n\n isAvailable(): boolean {\n return true;\n }\n\n async initialize(_sessionId: string, _options?: MemoryProviderInitOptions): Promise<void> {}\n\n systemPromptBlock(): string {\n return 'External memory provider: stub (wiring only; no cloud backend).';\n }\n\n async prefetch(query: string): Promise<string> {\n const q = query.trim();\n if (!q) {\n return '';\n }\n return `[stub prefetch] query length=${q.length}`;\n }\n\n queuePrefetch(): void {}\n\n sync(): void {}\n\n getToolSchemas() {\n return [];\n }\n\n async handleToolCall(toolName: string): Promise<string> {\n return JSON.stringify({ error: `stub provider has no tools (${toolName})` });\n }\n\n async search(): Promise<[]> {\n return [];\n }\n\n async shutdown(): Promise<void> {}\n}\n"],"mappings":";;;;AAKA,IAAa,qBAAb,MAA0D;CACxD,KAAc;CACd,cAAuB;CACvB,eAAwB;EACtB,QAAQ;EACR,MAAM;EACN,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,WAAW;EACX,MAAM;EACN,OAAO;EACR;CAED,cAAuB;AACrB,SAAO;;CAGT,MAAM,WAAW,YAAoB,UAAqD;CAE1F,oBAA4B;AAC1B,SAAO;;CAGT,MAAM,SAAS,OAAgC;EAC7C,MAAM,IAAI,MAAM,MAAM;AACtB,MAAI,CAAC,EACH,QAAO;AAET,SAAO,gCAAgC,EAAE;;CAG3C,gBAAsB;CAEtB,OAAa;CAEb,iBAAiB;AACf,SAAO,EAAE;;CAGX,MAAM,eAAe,UAAmC;AACtD,SAAO,KAAK,UAAU,EAAE,OAAO,+BAA+B,SAAS,IAAI,CAAC;;CAG9E,MAAM,SAAsB;AAC1B,SAAO,EAAE;;CAGX,MAAM,WAA0B"}
1
+ {"version":3,"file":"stub-memory-provider.js","names":[],"sources":["../../../../src/agent/memory/stub-memory-provider.ts"],"sourcesContent":["import type { MemoryProvider, MemoryProviderInitOptions } from './provider.js';\n\n/**\n * Placeholder external provider — enables wiring tests without cloud deps.\n */\nexport class StubMemoryProvider implements MemoryProvider {\n readonly id = 'stub';\n readonly displayName = 'Stub Memory Provider';\n readonly capabilities = {\n search: true,\n read: false,\n write: false,\n update: false,\n delete: false,\n keywordSearch: false,\n semanticSearch: false,\n hybridSearch: false,\n citations: false,\n sync: true,\n local: false,\n };\n\n isAvailable(): boolean {\n return true;\n }\n\n async initialize(_sessionId: string, _options?: MemoryProviderInitOptions): Promise<void> {}\n\n systemPromptBlock(): string {\n return 'External memory provider: stub (wiring only; no cloud backend).';\n }\n\n queuePrefetch(): void {}\n\n sync(): void {}\n\n getToolSchemas() {\n return [];\n }\n\n async handleToolCall(toolName: string): Promise<string> {\n return JSON.stringify({ error: `stub provider has no tools (${toolName})` });\n }\n\n async search(): Promise<[]> {\n return [];\n }\n\n async shutdown(): Promise<void> {}\n}\n"],"mappings":";;;;AAKA,IAAa,qBAAb,MAA0D;CACxD,KAAc;CACd,cAAuB;CACvB,eAAwB;EACtB,QAAQ;EACR,MAAM;EACN,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,WAAW;EACX,MAAM;EACN,OAAO;EACR;CAED,cAAuB;AACrB,SAAO;;CAGT,MAAM,WAAW,YAAoB,UAAqD;CAE1F,oBAA4B;AAC1B,SAAO;;CAGT,gBAAsB;CAEtB,OAAa;CAEb,iBAAiB;AACf,SAAO,EAAE;;CAGX,MAAM,eAAe,UAAmC;AACtD,SAAO,KAAK,UAAU,EAAE,OAAO,+BAA+B,SAAS,IAAI,CAAC;;CAG9E,MAAM,SAAsB;AAC1B,SAAO,EAAE;;CAGX,MAAM,WAA0B"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Built-in curated memory:
2
+ * Curated Markdown compatibility store:
3
3
  * - agent notes: `~/.xopc/agents/<id>/memories/MEMORY.md`
4
4
  * - user memory: `~/.xopc/user/MEMORY.md`
5
5
  */
@@ -21,14 +21,23 @@ export interface MemorySnapshot {
21
21
  memory: string;
22
22
  user: string;
23
23
  }
24
- export type MemoryKind = 'user_profile' | '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' | 'agent_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
+ export type MemoryExplicitness = 'explicit' | 'observed' | 'inferred';
28
+ export type MemoryDurability = 'ephemeral' | 'durable' | 'recurring';
29
+ export type MemoryDisclosurePolicy = 'silent' | 'referenceable' | 'ask_before_reference';
30
+ export type MemoryEvidenceRelation = 'supports' | 'contradicts' | 'supersedes' | 'derived_from';
27
31
  export interface MemoryEvidence {
32
+ evidenceId?: string;
33
+ sourceItemId?: string;
34
+ relation?: MemoryEvidenceRelation;
28
35
  sessionKey?: string;
29
36
  turnId?: string;
30
37
  toolCallId?: string;
31
38
  sourceText?: string;
39
+ observedAt?: string;
40
+ confidence?: number;
32
41
  }
33
42
  export interface MemoryScope {
34
43
  agentId: string;
@@ -50,6 +59,7 @@ export interface MemoryRecord {
50
59
  id: string;
51
60
  kind: MemoryKind;
52
61
  status?: MemoryStatus;
62
+ canonicalKey?: string;
53
63
  scope: MemoryScope;
54
64
  content: string;
55
65
  source: {
@@ -61,9 +71,17 @@ export interface MemoryRecord {
61
71
  };
62
72
  confidence?: number;
63
73
  sensitivity?: MemorySensitivity;
74
+ explicitness: MemoryExplicitness;
75
+ durability: MemoryDurability;
76
+ importance: number;
77
+ disclosurePolicy: MemoryDisclosurePolicy;
64
78
  evidence?: MemoryEvidence[];
79
+ validFrom?: string;
80
+ validTo?: string;
65
81
  reviewAfter?: string;
66
82
  expiresAt?: string;
83
+ supersedesRecordId?: string;
84
+ conflictGroupId?: string;
67
85
  createdAt: string;
68
86
  updatedAt: string;
69
87
  tags?: string[];
@@ -97,12 +115,15 @@ export interface MemoryReadResult {
97
115
  }
98
116
  export interface MemoryListRequest {
99
117
  kind?: MemoryKind;
118
+ status?: MemoryStatus;
119
+ canonicalKey?: string;
100
120
  target?: 'memory' | 'user';
101
121
  scope?: Partial<MemoryScope>;
102
122
  }
103
123
  export interface MemoryWriteRequest {
104
124
  kind: MemoryKind;
105
125
  content: string;
126
+ canonicalKey?: string;
106
127
  scope?: Partial<MemoryScope>;
107
128
  target?: 'memory' | 'user';
108
129
  tags?: string[];
@@ -110,9 +131,17 @@ export interface MemoryWriteRequest {
110
131
  confidence?: number;
111
132
  status?: MemoryStatus;
112
133
  sensitivity?: MemorySensitivity;
134
+ explicitness?: MemoryExplicitness;
135
+ durability?: MemoryDurability;
136
+ importance?: number;
137
+ disclosurePolicy?: MemoryDisclosurePolicy;
113
138
  evidence?: MemoryEvidence[];
139
+ validFrom?: string;
140
+ validTo?: string;
114
141
  reviewAfter?: string;
115
142
  expiresAt?: string;
143
+ supersedesRecordId?: string;
144
+ conflictGroupId?: string;
116
145
  approved?: boolean;
117
146
  }
118
147
  export interface MemoryUpdateRequest {
@@ -0,0 +1,3 @@
1
+ export declare function isExplicitUnderstandingCorrection(text: string): boolean;
2
+ /** Returns only a concrete replacement statement; pure denials intentionally return null. */
3
+ export declare function extractExplicitUnderstandingCorrectionContent(text: string): string | null;
@@ -0,0 +1,41 @@
1
+ //#region src/agent/memory/understanding/correction.ts
2
+ const UNDERSTANDING_CORRECTION_PATTERNS = [
3
+ /(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)/,
4
+ /(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)/,
5
+ /我(?:没有|从没|从未)(?:说过|表示过|要求过)(?:这|那|这个|那个)/,
6
+ /(?:不要|别再)(?:认为|假设|记成)(?:我|我的)/,
7
+ /you (?:remembered|understood|got) (?:me|my .+?) wrong\b/i,
8
+ /that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\b/i,
9
+ /i (?:never|did not|didn't) (?:say|said|tell you|told you|ask for|asked for) that\b/i,
10
+ /do not assume that about me\b/i
11
+ ];
12
+ const UNDERSTANDING_CORRECTION_CONTENT_PATTERNS = [
13
+ /(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)(?:偏好|习惯|情况|信息|边界|工作方式)?[,,::;;。]\s*(?:其实|实际上|正确的是)?\s*(.+)$/,
14
+ /(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)[,,::;;。]\s*(.+)$/,
15
+ /you (?:remembered|understood|got) (?:me|my .+?) wrong\b[,:;.]?\s*(?:actually[,:]?\s*)?(.+)$/i,
16
+ /that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\b[,:;.]?\s*(.+)$/i
17
+ ];
18
+ function normalizeCorrectionContent(content) {
19
+ const normalized = content.replace(/^[“”‘’"'\s]+|[“”‘’"'\s]+$/g, "").replace(/\s+/g, " ").trim();
20
+ return normalized.length >= 4 ? normalized.slice(0, 600) : null;
21
+ }
22
+ function isExplicitUnderstandingCorrection(text) {
23
+ const normalized = text.replace(/\s+/g, " ").trim();
24
+ return normalized.length > 0 && UNDERSTANDING_CORRECTION_PATTERNS.some((pattern) => pattern.test(normalized));
25
+ }
26
+ /** Returns only a concrete replacement statement; pure denials intentionally return null. */
27
+ function extractExplicitUnderstandingCorrectionContent(text) {
28
+ const normalized = text.replace(/\s+/g, " ").trim();
29
+ if (!isExplicitUnderstandingCorrection(normalized)) return null;
30
+ for (const pattern of UNDERSTANDING_CORRECTION_CONTENT_PATTERNS) {
31
+ const match = pattern.exec(normalized);
32
+ if (!match?.[1]) continue;
33
+ const content = normalizeCorrectionContent(match[1]);
34
+ if (content) return content;
35
+ }
36
+ return null;
37
+ }
38
+ //#endregion
39
+ export { extractExplicitUnderstandingCorrectionContent, isExplicitUnderstandingCorrection };
40
+
41
+ //# sourceMappingURL=correction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correction.js","names":[],"sources":["../../../../../src/agent/memory/understanding/correction.ts"],"sourcesContent":["const UNDERSTANDING_CORRECTION_PATTERNS: RegExp[] = [\n /(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)/,\n /(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)/,\n /我(?:没有|从没|从未)(?:说过|表示过|要求过)(?:这|那|这个|那个)/,\n /(?:不要|别再)(?:认为|假设|记成)(?:我|我的)/,\n /you (?:remembered|understood|got) (?:me|my .+?) wrong\\b/i,\n /that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\\b/i,\n /i (?:never|did not|didn't) (?:say|said|tell you|told you|ask for|asked for) that\\b/i,\n /do not assume that about me\\b/i,\n];\n\nconst UNDERSTANDING_CORRECTION_CONTENT_PATTERNS: RegExp[] = [\n /(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)(?:偏好|习惯|情况|信息|边界|工作方式)?[,,::;;。]\\s*(?:其实|实际上|正确的是)?\\s*(.+)$/,\n /(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)[,,::;;。]\\s*(.+)$/,\n /you (?:remembered|understood|got) (?:me|my .+?) wrong\\b[,:;.]?\\s*(?:actually[,:]?\\s*)?(.+)$/i,\n /that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\\b[,:;.]?\\s*(.+)$/i,\n];\n\nfunction normalizeCorrectionContent(content: string): string | null {\n const normalized = content\n .replace(/^[“”‘’\"'\\s]+|[“”‘’\"'\\s]+$/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n return normalized.length >= 4 ? normalized.slice(0, 600) : null;\n}\n\nexport function isExplicitUnderstandingCorrection(text: string): boolean {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n return normalized.length > 0\n && UNDERSTANDING_CORRECTION_PATTERNS.some((pattern) => pattern.test(normalized));\n}\n\n/** Returns only a concrete replacement statement; pure denials intentionally return null. */\nexport function extractExplicitUnderstandingCorrectionContent(text: string): string | null {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n if (!isExplicitUnderstandingCorrection(normalized)) return null;\n for (const pattern of UNDERSTANDING_CORRECTION_CONTENT_PATTERNS) {\n const match = pattern.exec(normalized);\n if (!match?.[1]) continue;\n const content = normalizeCorrectionContent(match[1]);\n if (content) return content;\n }\n return null;\n}\n"],"mappings":";AAAA,MAAM,oCAA8C;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAM,4CAAsD;CAC1D;CACA;CACA;CACA;CACD;AAED,SAAS,2BAA2B,SAAgC;CAClE,MAAM,aAAa,QAChB,QAAQ,8BAA8B,GAAG,CACzC,QAAQ,QAAQ,IAAI,CACpB,MAAM;AACT,QAAO,WAAW,UAAU,IAAI,WAAW,MAAM,GAAG,IAAI,GAAG;;AAG7D,SAAgB,kCAAkC,MAAuB;CACvE,MAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM;AACnD,QAAO,WAAW,SAAS,KACtB,kCAAkC,MAAM,YAAY,QAAQ,KAAK,WAAW,CAAC;;;AAIpF,SAAgB,8CAA8C,MAA6B;CACzF,MAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM;AACnD,KAAI,CAAC,kCAAkC,WAAW,CAAE,QAAO;AAC3D,MAAK,MAAM,WAAW,2CAA2C;EAC/D,MAAM,QAAQ,QAAQ,KAAK,WAAW;AACtC,MAAI,CAAC,QAAQ,GAAI;EACjB,MAAM,UAAU,2BAA2B,MAAM,GAAG;AACpD,MAAI,QAAS,QAAO;;AAEtB,QAAO"}
@@ -0,0 +1,8 @@
1
+ import type { UserUnderstandingQualityMetrics } from '../../../storage/sqlite/index.js';
2
+ export interface UnderstandingCadenceDecision {
3
+ baseIntervalTurns: number;
4
+ effectiveIntervalTurns: number;
5
+ slowed: boolean;
6
+ reasons: Array<'candidate_backlog' | 'low_acceptance' | 'low_recall_quality'>;
7
+ }
8
+ export declare function resolveAdaptiveUnderstandingCadence(baseIntervalTurns: number, metrics: UserUnderstandingQualityMetrics, enabled?: boolean): UnderstandingCadenceDecision;
@@ -0,0 +1,20 @@
1
+ //#region src/agent/memory/understanding/quality.ts
2
+ function resolveAdaptiveUnderstandingCadence(baseIntervalTurns, metrics, enabled = true) {
3
+ const base = Math.max(1, Math.min(1e3, Math.floor(baseIntervalTurns)));
4
+ const reasons = [];
5
+ if (enabled) {
6
+ if (metrics.records.candidate >= 20 || metrics.records.agingCandidates >= 10) reasons.push("candidate_backlog");
7
+ if (metrics.decisions.total >= 10 && metrics.decisions.acceptanceRate != null && metrics.decisions.acceptanceRate < .25) reasons.push("low_acceptance");
8
+ if (metrics.recall.total >= 10 && metrics.recall.helpfulRate != null && metrics.recall.helpfulRate < .4) reasons.push("low_recall_quality");
9
+ }
10
+ return {
11
+ baseIntervalTurns: base,
12
+ effectiveIntervalTurns: reasons.length > 0 ? Math.min(1e3, base * 2) : base,
13
+ slowed: reasons.length > 0,
14
+ reasons
15
+ };
16
+ }
17
+ //#endregion
18
+ export { resolveAdaptiveUnderstandingCadence };
19
+
20
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","names":[],"sources":["../../../../../src/agent/memory/understanding/quality.ts"],"sourcesContent":["import type { UserUnderstandingQualityMetrics } from '../../../storage/sqlite/index.js';\n\nexport interface UnderstandingCadenceDecision {\n baseIntervalTurns: number;\n effectiveIntervalTurns: number;\n slowed: boolean;\n reasons: Array<'candidate_backlog' | 'low_acceptance' | 'low_recall_quality'>;\n}\n\nexport function resolveAdaptiveUnderstandingCadence(\n baseIntervalTurns: number,\n metrics: UserUnderstandingQualityMetrics,\n enabled = true,\n): UnderstandingCadenceDecision {\n const base = Math.max(1, Math.min(1_000, Math.floor(baseIntervalTurns)));\n const reasons: UnderstandingCadenceDecision['reasons'] = [];\n if (enabled) {\n if (metrics.records.candidate >= 20 || metrics.records.agingCandidates >= 10) {\n reasons.push('candidate_backlog');\n }\n if (\n metrics.decisions.total >= 10\n && metrics.decisions.acceptanceRate != null\n && metrics.decisions.acceptanceRate < 0.25\n ) {\n reasons.push('low_acceptance');\n }\n if (\n metrics.recall.total >= 10\n && metrics.recall.helpfulRate != null\n && metrics.recall.helpfulRate < 0.4\n ) {\n reasons.push('low_recall_quality');\n }\n }\n return {\n baseIntervalTurns: base,\n effectiveIntervalTurns: reasons.length > 0 ? Math.min(1_000, base * 2) : base,\n slowed: reasons.length > 0,\n reasons,\n };\n}\n"],"mappings":";AASA,SAAgB,oCACd,mBACA,SACA,UAAU,MACoB;CAC9B,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAO,KAAK,MAAM,kBAAkB,CAAC,CAAC;CACxE,MAAM,UAAmD,EAAE;AAC3D,KAAI,SAAS;AACX,MAAI,QAAQ,QAAQ,aAAa,MAAM,QAAQ,QAAQ,mBAAmB,GACxE,SAAQ,KAAK,oBAAoB;AAEnC,MACE,QAAQ,UAAU,SAAS,MACxB,QAAQ,UAAU,kBAAkB,QACpC,QAAQ,UAAU,iBAAiB,IAEtC,SAAQ,KAAK,iBAAiB;AAEhC,MACE,QAAQ,OAAO,SAAS,MACrB,QAAQ,OAAO,eAAe,QAC9B,QAAQ,OAAO,cAAc,GAEhC,SAAQ,KAAK,qBAAqB;;AAGtC,QAAO;EACL,mBAAmB;EACnB,wBAAwB,QAAQ,SAAS,IAAI,KAAK,IAAI,KAAO,OAAO,EAAE,GAAG;EACzE,QAAQ,QAAQ,SAAS;EACzB;EACD"}
@@ -0,0 +1,26 @@
1
+ import type { MemoryRecord, MemoryWriteRequest, MemoryWriteResult } from '../types.js';
2
+ import type { UnderstandingCandidate, UnderstandingReviewResult } from './types.js';
3
+ export declare function extractExplicitUnderstandingCandidates(userContent: string): UnderstandingCandidate[];
4
+ export interface UserUnderstandingServiceOptions {
5
+ write: (request: MemoryWriteRequest) => Promise<MemoryWriteResult>;
6
+ list: (canonicalKey: string) => Promise<MemoryRecord[]>;
7
+ }
8
+ export declare class UserUnderstandingService {
9
+ private readonly options;
10
+ constructor(options: UserUnderstandingServiceOptions);
11
+ reviewTurn(params: {
12
+ agentId?: string;
13
+ userContent: string;
14
+ assistantContent: string;
15
+ sessionKey?: string;
16
+ correctionTargetRecordIds?: string[];
17
+ }): Promise<UnderstandingReviewResult>;
18
+ applyCandidates(candidates: UnderstandingCandidate[], context: {
19
+ agentId?: string;
20
+ sessionKey?: string;
21
+ sourceItemId?: string;
22
+ sourceText?: string;
23
+ reviewSource?: 'turn' | 'background';
24
+ supersedesRecordIds?: string[];
25
+ }): Promise<Omit<UnderstandingReviewResult, 'sourceItemId'>>;
26
+ }
@@ -0,0 +1,233 @@
1
+ import { createLogger } from "../../../utils/logger/index.js";
2
+ import { init_logger } from "../../../utils/logger.js";
3
+ import { appendMemoryTraceEvent } from "../../../storage/sqlite/memory-records-repository.js";
4
+ import { attachMemoryEvidence, upsertKnowledgeSourceItems } from "../../../storage/sqlite/knowledge-repository.js";
5
+ import "../../../storage/sqlite/index.js";
6
+ import { extractExplicitUnderstandingCorrectionContent } from "./correction.js";
7
+ import { createHash } from "node:crypto";
8
+ //#region src/agent/memory/understanding/service.ts
9
+ init_logger();
10
+ const log = createLogger("UserUnderstanding");
11
+ const MAX_CANDIDATE_CHARS = 600;
12
+ const EXPLICIT_PATTERNS = [
13
+ /\b(?:please\s+)?remember(?:\s+that)?\s+(.+)/i,
14
+ /\bkeep\s+in\s+mind(?:\s+that)?\s+(.+)/i,
15
+ /(?:请)?记住[::\s]*(.+)/,
16
+ /以后(?:都)?(?:请)?[::\s]*(.+)/,
17
+ /下次(?:请)?[::\s]*(.+)/
18
+ ];
19
+ function normalizeContent(raw) {
20
+ return raw.replace(/^["'“”‘’\s]+|["'“”‘’\s]+$/g, "").replace(/\s+/g, " ").trim().slice(0, MAX_CANDIDATE_CHARS);
21
+ }
22
+ function inferKind(content) {
23
+ if (/\b(don't|do not|never|avoid)\b/i.test(content) || /不要|别再|禁止|底线/.test(content)) return "boundary";
24
+ if (/\b(prefer|preference|like)\b/i.test(content) || /喜欢|偏好|习惯/.test(content)) return "preference";
25
+ if (/\b(tool|command|pnpm|npm|git|ripgrep|rg)\b/i.test(content) || /工具|命令/.test(content)) return "tool_preference";
26
+ if (/\b(project|repo|codebase|workspace)\b/i.test(content) || /项目|仓库|代码库/.test(content)) return "project_context";
27
+ if (/\b(goal|plan|commit|deadline)\b/i.test(content) || /目标|计划|承诺|截止/.test(content)) return "commitment";
28
+ if (/\b(next time|lesson|failed|error)\b/i.test(content) || /下次|教训|失败|错误/.test(content)) return "task_lesson";
29
+ return "agent_note";
30
+ }
31
+ function inferSensitivity(content) {
32
+ if (/\b(api[_-]?key|access[_-]?key|token|password|secret|credential|private[_-]?key|bearer)\b/i.test(content) || /密钥|密码|令牌|私钥/.test(content) || /\b(?:sk|gh[opsu]|xox[abprs])-[a-z0-9_-]{8,}\b/i.test(content) || /\bAKIA[A-Z0-9]{12,}\b/.test(content) || /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(content)) return "secret";
33
+ if (/\b(ssn|social security|bank account|credit card|medical record)\b/i.test(content) || /身份证|银行卡|信用卡|医疗记录/.test(content)) return "regulated";
34
+ return /家庭|住址|生日|健康|关系|family|address|birthday|health/i.test(content) ? "personal" : "normal";
35
+ }
36
+ function redactSensitiveText(content) {
37
+ return content.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, "[REDACTED PRIVATE KEY]").replace(/\b(api[_-]?key|access[_-]?key|token|password|secret|credential|private[_-]?key|bearer)\b\s*[:=]?\s*[^\s,;]+/gi, "$1=[REDACTED]").replace(/(密钥|密码|令牌|私钥)\s*[::=]?\s*[^\s,;]+/g, "$1=[REDACTED]").replace(/\b(?:sk|gh[opsu]|xox[abprs])-[a-z0-9_-]{8,}\b/gi, "[REDACTED TOKEN]").replace(/\bAKIA[A-Z0-9]{12,}\b/g, "[REDACTED ACCESS KEY]");
38
+ }
39
+ const SENSITIVITY_RANK = {
40
+ normal: 0,
41
+ personal: 1,
42
+ regulated: 2,
43
+ secret: 3
44
+ };
45
+ function stricterSensitivity(content, declared) {
46
+ const inferred = inferSensitivity(content);
47
+ return SENSITIVITY_RANK[inferred] > SENSITIVITY_RANK[declared] ? inferred : declared;
48
+ }
49
+ function canonicalKey(kind, content) {
50
+ const normalized = content.toLocaleLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
51
+ return `${kind}:${createHash("sha256").update(normalized).digest("hex").slice(0, 20)}`;
52
+ }
53
+ function extractExplicitUnderstandingCandidates(userContent) {
54
+ const correction = extractExplicitUnderstandingCorrectionContent(userContent);
55
+ if (correction) {
56
+ const kind = inferKind(correction);
57
+ return [{
58
+ kind,
59
+ content: correction,
60
+ canonicalKey: canonicalKey(kind, correction),
61
+ confidence: .95,
62
+ importance: kind === "boundary" ? .9 : .8,
63
+ explicitness: "explicit",
64
+ durability: "durable",
65
+ sensitivity: inferSensitivity(correction),
66
+ disclosurePolicy: kind === "boundary" ? "silent" : "referenceable",
67
+ tags: ["user-understanding", "explicit-user-correction"]
68
+ }];
69
+ }
70
+ const lines = userContent.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
71
+ for (const line of lines.length > 0 ? lines : [userContent.trim()]) for (const pattern of EXPLICIT_PATTERNS) {
72
+ const content = normalizeContent(pattern.exec(line)?.[1] ?? "");
73
+ if (content.length < 8) continue;
74
+ const kind = inferKind(content);
75
+ return [{
76
+ kind,
77
+ content,
78
+ canonicalKey: canonicalKey(kind, content),
79
+ confidence: .92,
80
+ importance: kind === "boundary" ? .9 : .75,
81
+ explicitness: "explicit",
82
+ durability: "durable",
83
+ sensitivity: inferSensitivity(content),
84
+ disclosurePolicy: kind === "boundary" ? "silent" : "referenceable",
85
+ tags: ["user-understanding", "explicit-user-request"]
86
+ }];
87
+ }
88
+ return [];
89
+ }
90
+ var UserUnderstandingService = class {
91
+ constructor(options) {
92
+ this.options = options;
93
+ }
94
+ async reviewTurn(params) {
95
+ const candidates = extractExplicitUnderstandingCandidates(params.userContent);
96
+ const sourceText = `User:\n${params.userContent.trim()}\n\nAssistant:\n${params.assistantContent.trim()}`;
97
+ const normalizedText = redactSensitiveText(sourceText);
98
+ const contentHash = createHash("sha256").update(sourceText).digest("hex");
99
+ const sourceItemId = upsertKnowledgeSourceItems([{
100
+ sourceInstanceId: params.sessionKey ? `session:${params.sessionKey}` : "session:unknown",
101
+ externalId: contentHash,
102
+ itemType: "conversation_turn",
103
+ authorRole: "user",
104
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ contentHash,
106
+ normalizedText,
107
+ metadata: params.sessionKey ? { sessionKey: params.sessionKey } : {},
108
+ sensitivity: "personal",
109
+ retentionClass: "bounded",
110
+ synthesisStatus: "pending"
111
+ }]).items[0]?.id;
112
+ return {
113
+ ...await this.applyCandidates(candidates, {
114
+ agentId: params.agentId,
115
+ sessionKey: params.sessionKey,
116
+ sourceItemId,
117
+ sourceText: params.userContent,
118
+ reviewSource: "turn",
119
+ supersedesRecordIds: params.correctionTargetRecordIds
120
+ }),
121
+ sourceItemId
122
+ };
123
+ }
124
+ async applyCandidates(candidates, context) {
125
+ const startedAt = Date.now();
126
+ let created = 0;
127
+ let deduplicated = 0;
128
+ let rejected = 0;
129
+ const recordIds = [];
130
+ for (const candidate of candidates.slice(0, 10)) {
131
+ const content = normalizeContent(candidate.content);
132
+ const sensitivity = stricterSensitivity(content, candidate.sensitivity);
133
+ if (content.length < 4 || candidate.confidence < .55 || sensitivity === "secret" || sensitivity === "regulated") {
134
+ rejected += 1;
135
+ continue;
136
+ }
137
+ const evidenceText = context.sourceText ? redactSensitiveText(context.sourceText).slice(0, MAX_CANDIDATE_CHARS) : void 0;
138
+ const key = candidate.canonicalKey ?? canonicalKey(candidate.kind, content);
139
+ const supersedesRecordId = context.supersedesRecordIds && [...new Set(context.supersedesRecordIds)].length === 1 ? context.supersedesRecordIds[0] : void 0;
140
+ const existing = await this.options.list(key);
141
+ const evidence = {
142
+ ...context.sourceItemId ? { sourceItemId: context.sourceItemId } : {},
143
+ relation: "supports",
144
+ ...context.sessionKey ? { sessionKey: context.sessionKey } : {},
145
+ ...evidenceText ? { sourceText: evidenceText } : {},
146
+ observedAt: (/* @__PURE__ */ new Date()).toISOString(),
147
+ confidence: candidate.confidence
148
+ };
149
+ if (existing[0]) {
150
+ deduplicated += 1;
151
+ recordIds.push(existing[0].id);
152
+ if (context.sourceItemId) attachMemoryEvidence({
153
+ recordId: existing[0].id,
154
+ sourceItemId: context.sourceItemId,
155
+ relation: "supports",
156
+ excerpt: evidenceText,
157
+ confidence: candidate.confidence
158
+ });
159
+ continue;
160
+ }
161
+ const write = await this.options.write({
162
+ kind: candidate.kind,
163
+ content,
164
+ canonicalKey: key,
165
+ scope: context.sessionKey ? { sessionKey: context.sessionKey } : void 0,
166
+ target: candidate.kind === "preference" ? "user" : "memory",
167
+ tags: [...new Set(["user-understanding", ...candidate.tags ?? []])],
168
+ source: { provider: "user-understanding" },
169
+ confidence: candidate.confidence,
170
+ status: "candidate",
171
+ sensitivity,
172
+ explicitness: candidate.explicitness,
173
+ durability: candidate.durability,
174
+ importance: candidate.importance,
175
+ disclosurePolicy: candidate.disclosurePolicy,
176
+ evidence: [evidence],
177
+ validFrom: candidate.validFrom,
178
+ validTo: candidate.validTo,
179
+ supersedesRecordId
180
+ });
181
+ if (write.success) {
182
+ created += 1;
183
+ if (write.record) recordIds.push(write.record.id);
184
+ if (write.record && context.sourceItemId) attachMemoryEvidence({
185
+ recordId: write.record.id,
186
+ sourceItemId: context.sourceItemId,
187
+ relation: "supports",
188
+ excerpt: evidenceText,
189
+ confidence: candidate.confidence
190
+ });
191
+ } else {
192
+ rejected += 1;
193
+ log.debug({
194
+ errorMessage: write.error,
195
+ canonicalKey: key
196
+ }, "Understanding candidate was not stored");
197
+ }
198
+ }
199
+ try {
200
+ appendMemoryTraceEvent({
201
+ sessionKey: context.sessionKey,
202
+ phase: "understanding",
203
+ providerId: "user-understanding",
204
+ request: {
205
+ ...context.agentId ? { agentId: context.agentId } : {},
206
+ source: context.reviewSource ?? "turn",
207
+ proposed: candidates.length,
208
+ created,
209
+ deduplicated,
210
+ rejected
211
+ },
212
+ resultCount: created,
213
+ selectedRecordIds: recordIds,
214
+ durationMs: Date.now() - startedAt
215
+ });
216
+ } catch (err) {
217
+ log.debug({
218
+ err,
219
+ sessionKey: context.sessionKey
220
+ }, "Understanding quality trace append failed");
221
+ }
222
+ return {
223
+ proposed: candidates.length,
224
+ created,
225
+ deduplicated,
226
+ rejected
227
+ };
228
+ }
229
+ };
230
+ //#endregion
231
+ export { UserUnderstandingService, extractExplicitUnderstandingCandidates };
232
+
233
+ //# sourceMappingURL=service.js.map
@@ -0,0 +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 { extractExplicitUnderstandingCorrectionContent } from './correction.js';\nimport type { UnderstandingCandidate, UnderstandingReviewResult } from './types.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\nfunction inferSensitivity(content: string): UnderstandingCandidate['sensitivity'] {\n if (\n /\\b(api[_-]?key|access[_-]?key|token|password|secret|credential|private[_-]?key|bearer)\\b/i.test(content)\n || /密钥|密码|令牌|私钥/.test(content)\n || /\\b(?:sk|gh[opsu]|xox[abprs])-[a-z0-9_-]{8,}\\b/i.test(content)\n || /\\bAKIA[A-Z0-9]{12,}\\b/.test(content)\n || /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(content)\n ) {\n return 'secret';\n }\n if (\n /\\b(ssn|social security|bank account|credit card|medical record)\\b/i.test(content)\n || /身份证|银行卡|信用卡|医疗记录/.test(content)\n ) {\n return 'regulated';\n }\n return /家庭|住址|生日|健康|关系|family|address|birthday|health/i.test(content)\n ? 'personal'\n : 'normal';\n}\n\nfunction redactSensitiveText(content: string): string {\n return content\n .replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, '[REDACTED PRIVATE KEY]')\n .replace(/\\b(api[_-]?key|access[_-]?key|token|password|secret|credential|private[_-]?key|bearer)\\b\\s*[:=]?\\s*[^\\s,;]+/gi, '$1=[REDACTED]')\n .replace(/(密钥|密码|令牌|私钥)\\s*[::=]?\\s*[^\\s,;]+/g, '$1=[REDACTED]')\n .replace(/\\b(?:sk|gh[opsu]|xox[abprs])-[a-z0-9_-]{8,}\\b/gi, '[REDACTED TOKEN]')\n .replace(/\\bAKIA[A-Z0-9]{12,}\\b/g, '[REDACTED ACCESS KEY]');\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 = inferSensitivity(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: inferSensitivity(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: inferSensitivity(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 = redactSensitiveText(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 ? redactSensitiveText(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.sessionKey ? { sessionKey: context.sessionKey } : 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 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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"}
@@ -0,0 +1,22 @@
1
+ import type { MemoryDisclosurePolicy, MemoryDurability, MemoryExplicitness, MemoryKind, MemorySensitivity } from '../types.js';
2
+ export interface UnderstandingCandidate {
3
+ kind: MemoryKind;
4
+ content: string;
5
+ canonicalKey?: string;
6
+ confidence: number;
7
+ importance: number;
8
+ explicitness: MemoryExplicitness;
9
+ durability: MemoryDurability;
10
+ sensitivity: MemorySensitivity;
11
+ disclosurePolicy: MemoryDisclosurePolicy;
12
+ tags?: string[];
13
+ validFrom?: string;
14
+ validTo?: string;
15
+ }
16
+ export interface UnderstandingReviewResult {
17
+ sourceItemId?: string;
18
+ proposed: number;
19
+ created: number;
20
+ deduplicated: number;
21
+ rejected: number;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ import type { Config } from '../../config/schema.js';
3
+ import type { UserContextPlan } from './context/types.js';
4
+ import type { MemoryManager } from './manager.js';
5
+ export interface UserContextCoordinatorOptions {
6
+ getConfig: () => Config | undefined;
7
+ isEnabledForSession: (sessionKey: string) => boolean;
8
+ getMemoryManagerForSession: (sessionKey: string) => MemoryManager;
9
+ getLastAssistantContent: (sessionKey: string) => string | null;
10
+ }
11
+ export declare class UserContextCoordinator {
12
+ private readonly options;
13
+ private readonly userTurn;
14
+ private readonly correctionTargets;
15
+ private readonly planner;
16
+ constructor(options: UserContextCoordinatorOptions);
17
+ forgetSession(sessionKey: string): void;
18
+ clear(): void;
19
+ prepare(userMessage: AgentMessage, sessionKey: string): Promise<UserContextPlan>;
20
+ afterTurn(sessionKey: string, userPlainText: string): Promise<void>;
21
+ }