@xopcai/xopc 0.0.137 → 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 (234) 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-BVGEvspi.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-BmdZifqk.js → app-management-settings-panel-ByM4Bzwm.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-CI-Cony7.js → appearance-settings-BF_poRd3.js} +1 -1
  11. package/dist/gateway/static/root/assets/{apps-page-8yKgtRah.js → apps-page-BssdA5Qc.js} +1 -1
  12. package/dist/gateway/static/root/assets/{archive-plugin-hMye7wu9.js → archive-plugin-DJaYoyGn.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-qKR5CPYj.js → attachment-load-xx6dBaZU.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automation-suggestion-card-BrtqTkO2.js → automation-suggestion-card-BMvGqYob.js} +1 -1
  15. package/dist/gateway/static/root/assets/{automations-page-CTbY1_xq.js → automations-page-Dip8ZFmx.js} +1 -1
  16. package/dist/gateway/static/root/assets/{binary-plugins-DURU6npf.js → binary-plugins-CuPLWibr.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-BQIHfg8Q.js → block-editor-bzfvlJnh.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-settings-page-BTlEo9yH.js → browser-settings-page-lbx_8Dku.js} +4 -4
  19. package/dist/gateway/static/root/assets/{capability-presets-api-DowJXE85.js → capability-presets-api-X4Imbf8n.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-CUBsiEWT.js → capability-presets-settings-panel-v9JgKjJu.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-BqbZNCJJ.js → channel-recipient-api-DllrPmp-.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-settings-BzPicGm_.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-BryXzajG.js → connectors-page-BMfp0jWL.js} +1 -1
  25. package/dist/gateway/static/root/assets/{desktop-pet-DxLTNBD2.js → desktop-pet-oTig6qFO.js} +1 -1
  26. package/dist/gateway/static/root/assets/{desktop-pet-settings-D_EgKbEB.js → desktop-pet-settings-DXJiPL_H.js} +1 -1
  27. package/dist/gateway/static/root/assets/{directory-picker-path-field-DmzW9Mwg.js → directory-picker-path-field-CltkXSR2.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dreaming-settings-D3DNPePf.js → dreaming-settings-CYrZQxoL.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-debug-page-hUg0oHQR.js → extension-debug-page-C-4BOy1R.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-page-Bl1aQuV_.js → extension-page-C8nMpXqh.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-settings-page-BghvkAL8.js → extension-settings-page-CXWYOwka.js} +1 -1
  32. package/dist/gateway/static/root/assets/{fetch-hvbCiP2J.js → fetch-BID89uCH.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-Dk4b3f7r.js → gateway-config-api-B3TGdim5.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-DKNhpqYg.js → gateway-settings-D7tOnGAJ.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-BzbrcQLJ.js → gateway-startup-retry-BkrLLlpE.js} +1 -1
  36. package/dist/gateway/static/root/assets/{goal-create-dialog-Z_oEJXTZ.js → goal-create-dialog-BL_cRshf.js} +1 -1
  37. package/dist/gateway/static/root/assets/{goal-detail-page-CIFnmZ2W.js → goal-detail-page-T1vg6Ng_.js} +1 -1
  38. package/dist/gateway/static/root/assets/{goals-config-api-DpQ3Hj8X.js → goals-config-api-D-WZWhP2.js} +1 -1
  39. package/dist/gateway/static/root/assets/{goals-page-BYWfLxSr.js → goals-page-1vzWXl5W.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goals-settings-DW6d-W79.js → goals-settings-DgGwvLVC.js} +1 -1
  41. package/dist/gateway/static/root/assets/{heartbeat-settings-CSGeVzW8.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-B-SGXAZ7.js → index-NwiCnzI-.js} +23 -23
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Bh85DLbN.js → keyboard-shortcuts-settings-CnxRFbgA.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-BYG_JKr5.js → logs-page-DebnvTpD.js} +1 -1
  46. package/dist/gateway/static/root/assets/{markdown-split-BLOUZPDJ.js → markdown-split-BU69Nof8.js} +1 -1
  47. package/dist/gateway/static/root/assets/{media-plugins-vlqpbsN0.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-BihK16QP.js → models-hub-panel-Ca_jy26S.js} +1 -1
  50. package/dist/gateway/static/root/assets/{notes-page-DJGOihcg.js → notes-page-DTpeaI65.js} +1 -1
  51. package/dist/gateway/static/root/assets/{notes-workbench-CtdxRaAk.js → notes-workbench-uKMYsjUU.js} +2 -2
  52. package/dist/gateway/static/root/assets/{page-tabs-BOKnavua.js → page-tabs-CROo8Vgz.js} +1 -1
  53. package/dist/gateway/static/root/assets/{preview-open-alternatives-07J39ZIq.js → preview-open-alternatives-BxsS9i1G.js} +1 -1
  54. package/dist/gateway/static/root/assets/{project-detail-page-BC26Zx8C.js → project-detail-page-BWKOhshy.js} +1 -1
  55. package/dist/gateway/static/root/assets/{projects-page-kQNhzpLr.js → projects-page-CoowiCLe.js} +1 -1
  56. package/dist/gateway/static/root/assets/{remote-access-hub-CN1ioJ0X.js → remote-access-hub-CiOaX1wd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{save-bar-controls-CDGmAkP7.js → save-bar-controls-B4N17dMG.js} +1 -1
  58. package/dist/gateway/static/root/assets/{schedule-field-7Cvi7W5t.js → schedule-field-ClJzQ2vz.js} +1 -1
  59. package/dist/gateway/static/root/assets/{schema-form-xobSdD8a.js → schema-form-oZvQUfDg.js} +1 -1
  60. package/dist/gateway/static/root/assets/{sessions-page-DEGTTMvU.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-CnqjZAfV.js → settings-collapsible-section-B0kOLXUf.js} +1 -1
  63. package/dist/gateway/static/root/assets/{settings-form-section-DRzUUAOA.js → settings-form-section-DoVPlVFd.js} +1 -1
  64. package/dist/gateway/static/root/assets/{settings-loading-skeleton-ke39n0bn.js → settings-loading-skeleton-C7J96bLc.js} +1 -1
  65. package/dist/gateway/static/root/assets/{settings-page-BDP9GD1j.js → settings-page-CXiAByF0.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-layout-CIf2rF-q.js → settings-page-layout-R-6ArlMI.js} +1 -1
  67. package/dist/gateway/static/root/assets/{setup-status-panel-CiiWlcKj.js → setup-status-panel-Drz23n9l.js} +1 -1
  68. package/dist/gateway/static/root/assets/{share-preview-page-CwJ2tj2j.js → share-preview-page-Bn1umseg.js} +1 -1
  69. package/dist/gateway/static/root/assets/{shares-settings-dm7VKGsi.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-Bc0rxqmf.js → skills-page-B6cDPqkk.js} +1 -1
  72. package/dist/gateway/static/root/assets/{system-settings-panel-1a3I3zIl.js → system-settings-panel-CtEddAy-.js} +1 -1
  73. package/dist/gateway/static/root/assets/{typed-models-lib-C3NCA3Nd.js → typed-models-lib-BkhSnYq7.js} +1 -1
  74. package/dist/gateway/static/root/assets/{use-channel-catalog-DUOMGhwc.js → use-channel-catalog-EA4hfbsP.js} +1 -1
  75. package/dist/gateway/static/root/assets/{user-profile-settings-panel-dKptBh4U.js → user-profile-settings-panel-BssTVOBS.js} +1 -1
  76. package/dist/gateway/static/root/assets/{utils-BqnHAm5O.js → utils-CI3ywKLT.js} +1 -1
  77. package/dist/gateway/static/root/assets/{voice-api-key-field-D4dtA6k3.js → voice-api-key-field-DXMEGw9O.js} +1 -1
  78. package/dist/gateway/static/root/assets/{work-item-detail-page-DpUYYeDf.js → work-item-detail-page-DsFqU0tK.js} +1 -1
  79. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BQ8aBXA1.js → workflow-run-setup-panel-DImBi-m6.js} +1 -1
  80. package/dist/gateway/static/root/assets/{workflow-start-dialog-jHmIHxTR.js → workflow-start-dialog-DuPpKAAc.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflows-page-DzjPClwt.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/tools/factory.d.ts +3 -0
  167. package/dist/src/agent/tools/factory.js +17 -10
  168. package/dist/src/agent/tools/factory.js.map +1 -1
  169. package/dist/src/agent/tools/index.d.ts +1 -0
  170. package/dist/src/agent/tools/index.js +2 -1
  171. package/dist/src/agent/workspace-runtime/registry.d.ts +2 -0
  172. package/dist/src/agent/workspace-runtime/registry.js +11 -3
  173. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  174. package/dist/src/agent-manifest/index.js +2 -2
  175. package/dist/src/agent-manifest/schema.d.ts +91 -0
  176. package/dist/src/agent-manifest/schema.js +27 -5
  177. package/dist/src/agent-manifest/schema.js.map +1 -1
  178. package/dist/src/agent-runtime/memory-runtime.d.ts +1 -1
  179. package/dist/src/agent-runtime/memory-runtime.js.map +1 -1
  180. package/dist/src/automations/domain/validation.d.ts +22 -22
  181. package/dist/src/automations/draft/automation-draft-validator.d.ts +4 -4
  182. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  183. package/dist/src/config/index.js +2 -2
  184. package/dist/src/config/schema.d.ts +115 -0
  185. package/dist/src/config/schema.js +53 -4
  186. package/dist/src/config/schema.js.map +1 -1
  187. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  188. package/dist/src/gateway/agent-builtin-tools.js +5 -0
  189. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  190. package/dist/src/gateway/hono/lib/config-payload.d.ts +18 -4
  191. package/dist/src/gateway/hono/routes/memory.js +129 -4
  192. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  193. package/dist/src/knowledge/index.d.ts +2 -0
  194. package/dist/src/knowledge/index.js +2 -0
  195. package/dist/src/knowledge/ingestion-service.d.ts +20 -0
  196. package/dist/src/knowledge/ingestion-service.js +75 -0
  197. package/dist/src/knowledge/ingestion-service.js.map +1 -0
  198. package/dist/src/knowledge/types.d.ts +70 -0
  199. package/dist/src/knowledge/types.js +1 -0
  200. package/dist/src/providers/presentation.js +1 -1
  201. package/dist/src/providers/presentation.js.map +1 -1
  202. package/dist/src/storage/sqlite/index.d.ts +2 -1
  203. package/dist/src/storage/sqlite/index.js +3 -2
  204. package/dist/src/storage/sqlite/knowledge-repository.d.ts +50 -0
  205. package/dist/src/storage/sqlite/knowledge-repository.js +237 -0
  206. package/dist/src/storage/sqlite/knowledge-repository.js.map +1 -0
  207. package/dist/src/storage/sqlite/memory-records-repository.d.ts +80 -2
  208. package/dist/src/storage/sqlite/memory-records-repository.js +271 -9
  209. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  210. package/dist/src/storage/sqlite/migrations/029_user_understanding.sql +133 -0
  211. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  212. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  213. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  214. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  215. package/dist/src/storage/sqlite/schema.js +1 -1
  216. package/package.json +2 -1
  217. package/dist/gateway/static/root/assets/agents-Bmfl5l9o.js +0 -2
  218. package/dist/gateway/static/root/assets/channels-status-swr-BCkcagDP.js +0 -1
  219. package/dist/gateway/static/root/assets/index-CPwVzi9x.css +0 -1
  220. package/dist/gateway/static/root/assets/messages-CD-qhazm.js +0 -3
  221. package/dist/gateway/static/root/assets/settings-advanced-gate-DgMxVBrX.js +0 -1
  222. package/dist/gateway/static/root/assets/skill-reload-api-ZzOv59qM.js +0 -1
  223. package/dist/src/agent/memory/candidate-extractor.d.ts +0 -6
  224. package/dist/src/agent/memory/candidate-extractor.js +0 -60
  225. package/dist/src/agent/memory/candidate-extractor.js.map +0 -1
  226. package/dist/src/agent/memory/context-assembler.d.ts +0 -10
  227. package/dist/src/agent/memory/context-assembler.js +0 -26
  228. package/dist/src/agent/memory/context-assembler.js.map +0 -1
  229. package/dist/src/agent/memory/inject-prefetch.d.ts +0 -6
  230. package/dist/src/agent/memory/inject-prefetch.js +0 -48
  231. package/dist/src/agent/memory/inject-prefetch.js.map +0 -1
  232. package/dist/src/agent/memory/prefetch-coordinator.d.ts +0 -37
  233. package/dist/src/agent/memory/prefetch-coordinator.js +0 -45
  234. package/dist/src/agent/memory/prefetch-coordinator.js.map +0 -1
@@ -2,6 +2,10 @@ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
2
  import { escapeFts5Query } from "./fts.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
  //#region src/storage/sqlite/memory-records-repository.ts
5
+ const USER_UNDERSTANDING_REMEDIATION_POLICY = {
6
+ minNotHelpful: 2,
7
+ confidencePenalty: .2
8
+ };
5
9
  function parseStringArray(json) {
6
10
  try {
7
11
  const parsed = JSON.parse(json);
@@ -90,6 +94,7 @@ function rowToRecord(row) {
90
94
  id: row.record_id,
91
95
  kind: row.kind,
92
96
  status: row.status,
97
+ ...row.canonical_key ? { canonicalKey: row.canonical_key } : {},
93
98
  scope: {
94
99
  agentId: row.agent_id,
95
100
  ...row.workspace_id ? { workspaceId: row.workspace_id } : {},
@@ -100,9 +105,17 @@ function rowToRecord(row) {
100
105
  source: parseSource(row.source_json),
101
106
  ...row.confidence != null ? { confidence: row.confidence } : {},
102
107
  sensitivity: row.sensitivity,
108
+ explicitness: row.explicitness,
109
+ durability: row.durability,
110
+ importance: row.importance,
111
+ disclosurePolicy: row.disclosure_policy,
103
112
  evidence: parseEvidence(row.evidence_json),
113
+ ...timestampToIso(row.valid_from) ? { validFrom: timestampToIso(row.valid_from) } : {},
114
+ ...timestampToIso(row.valid_to) ? { validTo: timestampToIso(row.valid_to) } : {},
104
115
  ...timestampToIso(row.review_after) ? { reviewAfter: timestampToIso(row.review_after) } : {},
105
116
  ...timestampToIso(row.expires_at) ? { expiresAt: timestampToIso(row.expires_at) } : {},
117
+ ...row.supersedes_record_id ? { supersedesRecordId: row.supersedes_record_id } : {},
118
+ ...row.conflict_group_id ? { conflictGroupId: row.conflict_group_id } : {},
106
119
  createdAt: new Date(row.created_at).toISOString(),
107
120
  updatedAt: new Date(row.updated_at).toISOString(),
108
121
  tags: parseStringArray(row.tags_json)
@@ -123,6 +136,12 @@ function upsertMemoryRecord(input) {
123
136
  const now = input.nowMs ?? Date.now();
124
137
  const status = input.status ?? "active";
125
138
  const sensitivity = input.sensitivity ?? "normal";
139
+ const explicitness = input.explicitness ?? "inferred";
140
+ const durability = input.durability ?? "durable";
141
+ const importance = Math.max(0, Math.min(1, input.importance ?? .5));
142
+ const disclosurePolicy = input.disclosurePolicy ?? "referenceable";
143
+ const validFrom = parseOptionalTimestamp(input.validFrom);
144
+ const validTo = parseOptionalTimestamp(input.validTo);
126
145
  const reviewAfter = parseOptionalTimestamp(input.reviewAfter);
127
146
  const expiresAt = parseOptionalTimestamp(input.expiresAt);
128
147
  const source = {
@@ -133,8 +152,10 @@ function upsertMemoryRecord(input) {
133
152
  db.prepare(`INSERT INTO memory_records (
134
153
  record_id, provider_id, kind, agent_id, workspace_id, session_key, project_id,
135
154
  content, source_json, confidence, tags_json, status, sensitivity,
136
- evidence_json, review_after, expires_at, created_at, updated_at
137
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
155
+ evidence_json, canonical_key, explicitness, durability, importance,
156
+ disclosure_policy, valid_from, valid_to, review_after, expires_at,
157
+ supersedes_record_id, conflict_group_id, created_at, updated_at
158
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
138
159
  ON CONFLICT(record_id) DO UPDATE SET
139
160
  provider_id = excluded.provider_id,
140
161
  kind = excluded.kind,
@@ -149,18 +170,44 @@ function upsertMemoryRecord(input) {
149
170
  status = excluded.status,
150
171
  sensitivity = excluded.sensitivity,
151
172
  evidence_json = excluded.evidence_json,
173
+ canonical_key = excluded.canonical_key,
174
+ explicitness = excluded.explicitness,
175
+ durability = excluded.durability,
176
+ importance = excluded.importance,
177
+ disclosure_policy = excluded.disclosure_policy,
178
+ valid_from = excluded.valid_from,
179
+ valid_to = excluded.valid_to,
152
180
  review_after = excluded.review_after,
153
181
  expires_at = excluded.expires_at,
154
- updated_at = excluded.updated_at`).run(id, input.providerId, input.kind, input.agentId, input.workspaceId ?? null, input.sessionKey ?? null, input.projectId ?? null, input.content, JSON.stringify(source), input.confidence ?? null, JSON.stringify(input.tags ?? []), status, sensitivity, JSON.stringify(input.evidence ?? []), reviewAfter, expiresAt, now, now);
182
+ supersedes_record_id = excluded.supersedes_record_id,
183
+ conflict_group_id = excluded.conflict_group_id,
184
+ updated_at = excluded.updated_at`).run(id, input.providerId, input.kind, input.agentId, input.workspaceId ?? null, input.sessionKey ?? null, input.projectId ?? null, input.content, JSON.stringify(source), input.confidence ?? null, JSON.stringify(input.tags ?? []), status, sensitivity, JSON.stringify(input.evidence ?? []), input.canonicalKey ?? null, explicitness, durability, importance, disclosurePolicy, validFrom, validTo, reviewAfter, expiresAt, input.supersedesRecordId ?? null, input.conflictGroupId ?? null, now, now);
155
185
  upsertMemoryRecordFts(db, {
156
186
  ...input,
157
187
  id
158
188
  });
189
+ if (input.supersedesRecordId && input.supersedesRecordId !== id) {
190
+ if (db.prepare(`SELECT 1 FROM memory_records WHERE record_id = ?`).get(input.supersedesRecordId)) {
191
+ db.prepare(`INSERT INTO memory_relations (
192
+ relation_id, from_record_id, relation_type, to_record_id,
193
+ confidence, valid_from, valid_to, created_at, updated_at
194
+ ) VALUES (?, ?, 'supersedes', ?, ?, ?, NULL, ?, ?)
195
+ ON CONFLICT(from_record_id, relation_type, to_record_id) DO UPDATE SET
196
+ confidence = excluded.confidence,
197
+ valid_from = excluded.valid_from,
198
+ valid_to = NULL,
199
+ updated_at = excluded.updated_at`).run(randomUUID(), id, input.supersedesRecordId, input.confidence ?? 1, validFrom ?? now, now, now);
200
+ if (status === "active") db.prepare(`UPDATE memory_records
201
+ SET status = 'archived', valid_to = COALESCE(valid_to, ?), updated_at = ?
202
+ WHERE record_id = ? AND status IN ('active', 'needs_review', 'stale')`).run(now, now, input.supersedesRecordId);
203
+ }
204
+ }
159
205
  });
160
206
  return {
161
207
  id,
162
208
  kind: input.kind,
163
209
  status,
210
+ ...input.canonicalKey ? { canonicalKey: input.canonicalKey } : {},
164
211
  scope: {
165
212
  agentId: input.agentId,
166
213
  ...input.workspaceId ? { workspaceId: input.workspaceId } : {},
@@ -171,9 +218,17 @@ function upsertMemoryRecord(input) {
171
218
  source,
172
219
  ...input.confidence != null ? { confidence: input.confidence } : {},
173
220
  sensitivity,
221
+ explicitness,
222
+ durability,
223
+ importance,
224
+ disclosurePolicy,
174
225
  evidence: input.evidence ?? [],
226
+ ...validFrom != null ? { validFrom: new Date(validFrom).toISOString() } : {},
227
+ ...validTo != null ? { validTo: new Date(validTo).toISOString() } : {},
175
228
  ...reviewAfter != null ? { reviewAfter: new Date(reviewAfter).toISOString() } : {},
176
229
  ...expiresAt != null ? { expiresAt: new Date(expiresAt).toISOString() } : {},
230
+ ...input.supersedesRecordId ? { supersedesRecordId: input.supersedesRecordId } : {},
231
+ ...input.conflictGroupId ? { conflictGroupId: input.conflictGroupId } : {},
177
232
  createdAt: new Date(now).toISOString(),
178
233
  updatedAt: new Date(now).toISOString(),
179
234
  tags: input.tags ?? []
@@ -210,6 +265,10 @@ function listMemoryRecords(options = {}) {
210
265
  where.push("status = ?");
211
266
  params.push(options.status);
212
267
  }
268
+ if (options.canonicalKey) {
269
+ where.push("canonical_key = ?");
270
+ params.push(options.canonicalKey);
271
+ }
213
272
  const limit = Math.max(1, Math.min(500, options.limit ?? 100));
214
273
  const offset = Math.max(0, options.offset ?? 0);
215
274
  return getSqliteDatabase().prepare(`SELECT * FROM memory_records
@@ -357,7 +416,7 @@ function setMemoryProviderState(providerId, scopeKey, state) {
357
416
  });
358
417
  }
359
418
  function appendMemoryTraceEvent(input) {
360
- const id = randomUUID();
419
+ const id = input.traceId ?? randomUUID();
361
420
  const now = input.nowMs ?? Date.now();
362
421
  const feedback = input.feedback ? normalizeMemoryTraceFeedback(input.feedback, now) : void 0;
363
422
  runSqliteWriteTransaction((db) => {
@@ -392,13 +451,100 @@ function listMemoryTraceEvents(options = {}) {
392
451
  function setMemoryTraceFeedback(input) {
393
452
  const existing = getSqliteDatabase().prepare(`SELECT * FROM memory_trace_events WHERE trace_id = ?`).get(input.traceId);
394
453
  if (!existing) return null;
395
- const feedback = normalizeMemoryTraceFeedback(input.feedback, input.nowMs, parseMemoryTraceFeedback(existing.feedback_json));
454
+ const nowMs = input.nowMs ?? Date.now();
455
+ const feedback = normalizeMemoryTraceFeedback(input.feedback, nowMs, parseMemoryTraceFeedback(existing.feedback_json));
456
+ let remediation;
396
457
  runSqliteWriteTransaction((db) => {
397
458
  db.prepare(`UPDATE memory_trace_events SET feedback_json = ? WHERE trace_id = ?`).run(JSON.stringify(feedback), input.traceId);
459
+ remediation = reconcileUserUnderstandingFeedback(db, existing, feedback, nowMs);
398
460
  });
399
- return memoryTraceRowToPayload({
400
- ...existing,
401
- feedback_json: JSON.stringify(feedback)
461
+ return {
462
+ ...memoryTraceRowToPayload({
463
+ ...existing,
464
+ feedback_json: JSON.stringify(feedback)
465
+ }),
466
+ ...remediation ? { remediation } : {}
467
+ };
468
+ }
469
+ function reconcileUserUnderstandingFeedback(db, trace, feedback, nowMs) {
470
+ if (trace.phase !== "inject" || feedback.outcome !== "not_helpful") return void 0;
471
+ const explicitCorrection = feedback.source === "system" && feedback.reason === "detected_explicit_user_correction";
472
+ const evaluatedRecordIds = [];
473
+ const needsReviewRecordIds = [];
474
+ const actions = [];
475
+ for (const recordId of new Set(parseStringArray(trace.selected_record_ids_json))) {
476
+ const record = db.prepare(`SELECT * FROM memory_records
477
+ WHERE record_id = ?
478
+ AND status = 'active'
479
+ AND tags_json LIKE '%\"user-understanding\"%'`).get(recordId);
480
+ if (!record) continue;
481
+ evaluatedRecordIds.push(recordId);
482
+ const feedbackRows = db.prepare(`SELECT trace.feedback_json
483
+ FROM memory_trace_events AS trace
484
+ JOIN json_each(trace.selected_record_ids_json) AS selected
485
+ ON selected.value = ?
486
+ WHERE trace.phase = 'inject'`).all(recordId);
487
+ let helpful = 0;
488
+ let notHelpful = 0;
489
+ for (const row of feedbackRows) {
490
+ const recordFeedback = parseMemoryTraceFeedback(row.feedback_json);
491
+ if (recordFeedback?.outcome === "helpful") helpful += 1;
492
+ if (recordFeedback?.outcome === "not_helpful") notHelpful += 1;
493
+ }
494
+ if (!explicitCorrection && (notHelpful < USER_UNDERSTANDING_REMEDIATION_POLICY.minNotHelpful || notHelpful <= helpful)) continue;
495
+ const nextConfidence = record.confidence == null ? null : Math.round(Math.max(.1, record.confidence - USER_UNDERSTANDING_REMEDIATION_POLICY.confidencePenalty) * 1e3) / 1e3;
496
+ if (db.prepare(`UPDATE memory_records
497
+ SET status = 'needs_review', confidence = ?, review_after = ?, updated_at = ?
498
+ WHERE record_id = ? AND status = 'active'`).run(nextConfidence, nowMs, nowMs, recordId).changes === 0) continue;
499
+ needsReviewRecordIds.push(recordId);
500
+ actions.push({
501
+ recordId,
502
+ previousStatus: record.status,
503
+ nextStatus: "needs_review",
504
+ previousConfidence: record.confidence,
505
+ nextConfidence,
506
+ helpful,
507
+ notHelpful
508
+ });
509
+ }
510
+ const result = {
511
+ triggerTraceId: trace.trace_id,
512
+ evaluatedRecordIds,
513
+ needsReviewRecordIds
514
+ };
515
+ if (needsReviewRecordIds.length > 0) db.prepare(`INSERT INTO memory_trace_events (
516
+ trace_id, session_key, turn_id, phase, provider_id, request_json,
517
+ result_count, selected_record_ids_json, skipped_reason, error,
518
+ feedback_json, duration_ms, created_at
519
+ ) VALUES (?, ?, ?, 'remediation', 'user-understanding', ?, ?, ?, NULL, NULL, '{}', 0, ?)`).run(randomUUID(), trace.session_key, trace.turn_id, JSON.stringify({
520
+ triggerTraceId: trace.trace_id,
521
+ reason: explicitCorrection ? "explicit_user_correction" : "repeated_not_helpful_feedback",
522
+ policy: USER_UNDERSTANDING_REMEDIATION_POLICY,
523
+ actions
524
+ }), needsReviewRecordIds.length, JSON.stringify(needsReviewRecordIds), nowMs);
525
+ return result;
526
+ }
527
+ function findLatestMemoryInjectTrace(input) {
528
+ const row = getSqliteDatabase().prepare(`SELECT * FROM memory_trace_events
529
+ WHERE ${[
530
+ `session_key = ?`,
531
+ `phase = 'inject'`,
532
+ `created_at <= ?`
533
+ ].join(" AND ")}
534
+ ORDER BY created_at DESC
535
+ LIMIT 1`).get(input.sessionKey, input.beforeMs ?? Date.now());
536
+ if (!row) return null;
537
+ const trace = memoryTraceRowToPayload(row);
538
+ if (input.requireSelectedRecords && trace.selectedRecordIds.length === 0) return null;
539
+ return trace;
540
+ }
541
+ function setLatestMemoryInjectFeedback(input) {
542
+ const row = findLatestMemoryInjectTrace(input);
543
+ if (!row) return null;
544
+ return setMemoryTraceFeedback({
545
+ traceId: row.traceId,
546
+ feedback: input.feedback,
547
+ nowMs: input.nowMs
402
548
  });
403
549
  }
404
550
  function summarizeMemoryRecallFeedback(options = {}) {
@@ -451,6 +597,122 @@ function summarizeMemoryRecallFeedback(options = {}) {
451
597
  }
452
598
  return [...summaries.values()].map(({ scoreTotal: _scoreTotal, scoreCount: _scoreCount, ...summary }) => summary).sort((a, b) => b.total - a.total);
453
599
  }
600
+ function boundedMetricCount(value) {
601
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
602
+ }
603
+ function metricRate(numerator, denominator) {
604
+ return denominator > 0 ? Math.round(numerator / denominator * 1e4) / 1e4 : null;
605
+ }
606
+ function summarizeUserUnderstandingQuality(options = {}) {
607
+ const nowMs = options.nowMs ?? Date.now();
608
+ const windowDays = Math.max(1, Math.min(365, Math.floor(options.windowDays ?? 30)));
609
+ const sinceMs = nowMs - windowDays * 24 * 60 * 60 * 1e3;
610
+ const agingCutoffMs = nowMs - Math.max(1, Math.min(windowDays, Math.floor(options.agingCandidateDays ?? 7))) * 24 * 60 * 60 * 1e3;
611
+ const db = getSqliteDatabase();
612
+ const agentWhere = options.agentId ? "AND agent_id = ?" : "";
613
+ const recordRows = db.prepare(`SELECT record_id, status, explicitness, confidence, created_at, updated_at
614
+ FROM memory_records
615
+ WHERE tags_json LIKE '%"user-understanding"%'
616
+ ${agentWhere}`).all(...options.agentId ? [options.agentId] : []);
617
+ const records = {
618
+ total: recordRows.length,
619
+ candidate: 0,
620
+ active: 0,
621
+ rejected: 0,
622
+ needsReview: 0,
623
+ stale: 0,
624
+ archived: 0,
625
+ agingCandidates: 0,
626
+ explicit: 0,
627
+ inferred: 0,
628
+ averageConfidence: null
629
+ };
630
+ let confidenceTotal = 0;
631
+ let confidenceCount = 0;
632
+ const understandingRecordIds = /* @__PURE__ */ new Set();
633
+ for (const row of recordRows) {
634
+ understandingRecordIds.add(row.record_id);
635
+ if (row.status === "candidate") records.candidate += 1;
636
+ if (row.status === "active") records.active += 1;
637
+ if (row.status === "rejected") records.rejected += 1;
638
+ if (row.status === "needs_review") records.needsReview += 1;
639
+ if (row.status === "stale") records.stale += 1;
640
+ if (row.status === "archived") records.archived += 1;
641
+ if (row.status === "candidate" && row.created_at <= agingCutoffMs) records.agingCandidates += 1;
642
+ if (row.explicitness === "explicit") records.explicit += 1;
643
+ if (row.explicitness === "inferred") records.inferred += 1;
644
+ if (typeof row.confidence === "number") {
645
+ confidenceTotal += row.confidence;
646
+ confidenceCount += 1;
647
+ }
648
+ }
649
+ records.averageConfidence = confidenceCount > 0 ? Math.round(confidenceTotal / confidenceCount * 1e4) / 1e4 : null;
650
+ const attempts = {
651
+ total: 0,
652
+ turn: 0,
653
+ background: 0
654
+ };
655
+ const candidates = {
656
+ proposed: 0,
657
+ created: 0,
658
+ deduplicated: 0,
659
+ rejectedByPolicy: 0
660
+ };
661
+ const understandingTraces = db.prepare(`SELECT request_json FROM memory_trace_events
662
+ WHERE phase = 'understanding' AND created_at >= ?`).all(sinceMs);
663
+ for (const row of understandingTraces) {
664
+ const parsed = parseJsonValue(row.request_json, {});
665
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
666
+ const request = parsed;
667
+ if (options.agentId && request.agentId !== options.agentId) continue;
668
+ attempts.total += 1;
669
+ if (request.source === "turn") attempts.turn += 1;
670
+ if (request.source === "background") attempts.background += 1;
671
+ candidates.proposed += boundedMetricCount(request.proposed);
672
+ candidates.created += boundedMetricCount(request.created);
673
+ candidates.deduplicated += boundedMetricCount(request.deduplicated);
674
+ candidates.rejectedByPolicy += boundedMetricCount(request.rejected);
675
+ }
676
+ const recall = {
677
+ total: 0,
678
+ helpful: 0,
679
+ notHelpful: 0,
680
+ mixed: 0,
681
+ irrelevant: 0,
682
+ helpfulRate: null
683
+ };
684
+ if (understandingRecordIds.size > 0) {
685
+ const recallRows = db.prepare(`SELECT selected_record_ids_json, feedback_json FROM memory_trace_events
686
+ WHERE phase IN ('search', 'inject') AND created_at >= ?`).all(sinceMs);
687
+ for (const row of recallRows) {
688
+ const feedback = parseMemoryTraceFeedback(row.feedback_json);
689
+ if (!feedback) continue;
690
+ if (!parseStringArray(row.selected_record_ids_json).some((recordId) => understandingRecordIds.has(recordId))) continue;
691
+ recall.total += 1;
692
+ if (feedback.outcome === "helpful") recall.helpful += 1;
693
+ if (feedback.outcome === "not_helpful") recall.notHelpful += 1;
694
+ if (feedback.outcome === "mixed") recall.mixed += 1;
695
+ if (feedback.outcome === "irrelevant") recall.irrelevant += 1;
696
+ }
697
+ }
698
+ recall.helpfulRate = metricRate(recall.helpful, recall.total);
699
+ const recentDecisions = recordRows.filter((row) => (row.status === "active" || row.status === "rejected") && row.updated_at >= sinceMs);
700
+ const acceptedDecisions = recentDecisions.filter((row) => row.status === "active").length;
701
+ const decisionTotal = recentDecisions.length;
702
+ return {
703
+ ...options.agentId ? { agentId: options.agentId } : {},
704
+ windowDays,
705
+ since: new Date(sinceMs).toISOString(),
706
+ attempts,
707
+ candidates,
708
+ records,
709
+ decisions: {
710
+ total: decisionTotal,
711
+ acceptanceRate: metricRate(acceptedDecisions, decisionTotal)
712
+ },
713
+ recall
714
+ };
715
+ }
454
716
  function parseJsonValue(json, fallback) {
455
717
  try {
456
718
  return JSON.parse(json);
@@ -459,6 +721,6 @@ function parseJsonValue(json, fallback) {
459
721
  }
460
722
  }
461
723
  //#endregion
462
- export { appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, getMemoryProviderState, getMemoryRecord, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, searchMemoryRecords, setMemoryProviderState, setMemoryTraceFeedback, summarizeMemoryRecallFeedback, upsertMemoryRecord };
724
+ export { USER_UNDERSTANDING_REMEDIATION_POLICY, appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, findLatestMemoryInjectTrace, getMemoryProviderState, getMemoryRecord, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, searchMemoryRecords, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, upsertMemoryRecord };
463
725
 
464
726
  //# sourceMappingURL=memory-records-repository.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-records-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-records-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n MemoryKind,\n MemoryRecord,\n MemorySensitivity,\n MemorySearchResult,\n MemorySignal,\n MemoryStatus,\n} from '../../agent/memory/types.js';\nimport { escapeFts5Query } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\ntype MemoryRecordRow = {\n record_id: string;\n provider_id: string;\n kind: string;\n agent_id: string;\n workspace_id: string | null;\n session_key: string | null;\n project_id: string | null;\n content: string;\n source_json: string;\n confidence: number | null;\n tags_json: string;\n status: string;\n sensitivity: string;\n evidence_json: string;\n review_after: number | null;\n expires_at: number | null;\n created_at: number;\n updated_at: number;\n};\n\ntype MemoryRecordSearchRow = MemoryRecordRow & {\n rank: number;\n};\n\nexport interface UpsertMemoryRecordInput {\n id?: string;\n providerId: string;\n kind: MemoryKind;\n agentId: string;\n workspaceId?: string;\n sessionKey?: string;\n projectId?: string;\n content: string;\n source?: MemoryRecord['source'];\n confidence?: number;\n tags?: string[];\n status?: MemoryStatus;\n sensitivity?: MemorySensitivity;\n evidence?: MemoryRecord['evidence'];\n reviewAfter?: string;\n expiresAt?: string;\n nowMs?: number;\n}\n\nexport interface ListMemoryRecordsOptions {\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n projectId?: string;\n kind?: MemoryKind;\n status?: MemoryStatus;\n limit?: number;\n offset?: number;\n}\n\nexport interface SearchMemoryRecordsOptions {\n query: string;\n agentId?: string;\n workspaceId?: string;\n projectId?: string;\n providerId?: string;\n kinds?: MemoryKind[];\n statuses?: MemoryStatus[];\n maxResults?: number;\n minScore?: number;\n}\n\nexport interface AppendMemorySignalInput {\n signal: MemorySignal;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n nowMs?: number;\n}\n\nexport interface MemorySignalRowPayload {\n signalId: string;\n source: string;\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n score?: number;\n content?: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\ntype MemorySignalRow = {\n signal_id: string;\n source: string;\n record_id: string | null;\n provider_id: string | null;\n agent_id: string | null;\n workspace_id: string | null;\n session_key: string | null;\n score: number | null;\n content: string | null;\n metadata_json: string;\n created_at: number;\n};\n\ntype MemoryTraceRow = {\n trace_id: string;\n session_key: string | null;\n turn_id: string | null;\n phase: string;\n provider_id: string;\n request_json: string;\n result_count: number | null;\n selected_record_ids_json: string;\n skipped_reason: string | null;\n error: string | null;\n feedback_json: string;\n duration_ms: number;\n created_at: number;\n};\n\nexport type MemoryTraceFeedbackOutcome = 'helpful' | 'not_helpful' | 'mixed' | 'irrelevant';\n\nexport interface MemoryTraceFeedback {\n outcome: MemoryTraceFeedbackOutcome;\n score?: number;\n reason?: string;\n source?: 'user' | 'evaluator' | 'system';\n createdAt: string;\n updatedAt?: string;\n}\n\nexport interface AppendMemoryTraceEventInput {\n sessionKey?: string;\n turnId?: string;\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test';\n providerId: string;\n request?: unknown;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n durationMs?: number;\n nowMs?: number;\n}\n\nexport interface SetMemoryTraceFeedbackInput {\n traceId: string;\n feedback: Omit<MemoryTraceFeedback, 'createdAt' | 'updatedAt'> & {\n createdAt?: string;\n updatedAt?: string;\n };\n nowMs?: number;\n}\n\nexport interface MemoryTraceEventPayload {\n traceId: string;\n sessionKey?: string;\n turnId?: string;\n phase: string;\n providerId: string;\n request: unknown;\n resultCount?: number;\n selectedRecordIds: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n durationMs: number;\n createdAt: string;\n}\n\nexport interface MemoryRecallFeedbackSummary {\n recordId: string;\n helpful: number;\n notHelpful: number;\n mixed: number;\n irrelevant: number;\n total: number;\n averageScore: number | null;\n lastFeedbackAt?: string;\n}\n\nfunction parseStringArray(json: string): string[] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction parseEvidence(json: string): MemoryRecord['evidence'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((item): item is NonNullable<MemoryRecord['evidence']>[number] =>\n Boolean(item) && typeof item === 'object',\n );\n } catch {\n return [];\n }\n}\n\nfunction parseMemoryTraceFeedback(json: string): MemoryTraceFeedback | undefined {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!parsed || typeof parsed !== 'object') return undefined;\n const obj = parsed as Record<string, unknown>;\n const outcome = obj.outcome;\n if (\n outcome !== 'helpful' &&\n outcome !== 'not_helpful' &&\n outcome !== 'mixed' &&\n outcome !== 'irrelevant'\n ) {\n return undefined;\n }\n return {\n outcome,\n ...(typeof obj.score === 'number' ? { score: obj.score } : {}),\n ...(typeof obj.reason === 'string' ? { reason: obj.reason } : {}),\n ...(obj.source === 'user' || obj.source === 'evaluator' || obj.source === 'system'\n ? { source: obj.source }\n : {}),\n createdAt: typeof obj.createdAt === 'string' ? obj.createdAt : new Date(0).toISOString(),\n ...(typeof obj.updatedAt === 'string' ? { updatedAt: obj.updatedAt } : {}),\n };\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeMemoryTraceFeedback(\n input: SetMemoryTraceFeedbackInput['feedback'],\n nowMs = Date.now(),\n existing?: MemoryTraceFeedback,\n): MemoryTraceFeedback {\n const score = typeof input.score === 'number'\n ? Math.max(-1, Math.min(1, input.score))\n : undefined;\n const reason = typeof input.reason === 'string' && input.reason.trim()\n ? input.reason.trim().slice(0, 1000)\n : undefined;\n const nowIso = new Date(nowMs).toISOString();\n return {\n outcome: input.outcome,\n ...(score != null ? { score } : {}),\n ...(reason ? { reason } : {}),\n ...(input.source ? { source: input.source } : {}),\n createdAt: input.createdAt ?? existing?.createdAt ?? nowIso,\n updatedAt: input.updatedAt ?? nowIso,\n };\n}\n\nfunction memoryTraceRowToPayload(row: MemoryTraceRow): MemoryTraceEventPayload {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n return {\n traceId: row.trace_id,\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.turn_id ? { turnId: row.turn_id } : {}),\n phase: row.phase,\n providerId: row.provider_id,\n request: parseJsonValue(row.request_json, {}),\n ...(row.result_count != null ? { resultCount: row.result_count } : {}),\n selectedRecordIds: parseStringArray(row.selected_record_ids_json),\n ...(row.skipped_reason ? { skippedReason: row.skipped_reason } : {}),\n ...(row.error ? { error: row.error } : {}),\n ...(feedback ? { feedback } : {}),\n durationMs: row.duration_ms,\n createdAt: new Date(row.created_at).toISOString(),\n };\n}\n\nfunction parseOptionalTimestamp(value: string | undefined): number | null {\n if (!value?.trim()) return null;\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction timestampToIso(value: number | null): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\nfunction parseSource(json: string): MemoryRecord['source'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return parsed && typeof parsed === 'object' ? (parsed as MemoryRecord['source']) : {};\n } catch {\n return {};\n }\n}\n\nfunction rowToRecord(row: MemoryRecordRow): MemoryRecord {\n return {\n id: row.record_id,\n kind: row.kind as MemoryKind,\n status: row.status as MemoryStatus,\n scope: {\n agentId: row.agent_id,\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.project_id ? { projectId: row.project_id } : {}),\n },\n content: row.content,\n source: parseSource(row.source_json),\n ...(row.confidence != null ? { confidence: row.confidence } : {}),\n sensitivity: row.sensitivity as MemorySensitivity,\n evidence: parseEvidence(row.evidence_json),\n ...(timestampToIso(row.review_after) ? { reviewAfter: timestampToIso(row.review_after) } : {}),\n ...(timestampToIso(row.expires_at) ? { expiresAt: timestampToIso(row.expires_at) } : {}),\n createdAt: new Date(row.created_at).toISOString(),\n updatedAt: new Date(row.updated_at).toISOString(),\n tags: parseStringArray(row.tags_json),\n };\n}\n\nfunction bm25ToScore(rank: number): number {\n return Math.max(0, Math.min(1, 1 / (1 + Math.max(0, rank))));\n}\n\nfunction upsertMemoryRecordFts(\n db: ReturnType<typeof getSqliteDatabase>,\n row: Pick<UpsertMemoryRecordInput, 'providerId' | 'kind' | 'agentId' | 'workspaceId' | 'content'> & { id: string },\n): void {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(row.id);\n if (!row.content.trim()) return;\n db.prepare(\n `INSERT INTO memory_records_fts (\n content, record_id, provider_id, kind, agent_id, workspace_id\n ) VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(row.content, row.id, row.providerId, row.kind, row.agentId, row.workspaceId ?? null);\n}\n\nexport function upsertMemoryRecord(input: UpsertMemoryRecordInput): MemoryRecord {\n const id = input.id ?? randomUUID();\n const now = input.nowMs ?? Date.now();\n const status = input.status ?? 'active';\n const sensitivity = input.sensitivity ?? 'normal';\n const reviewAfter = parseOptionalTimestamp(input.reviewAfter);\n const expiresAt = parseOptionalTimestamp(input.expiresAt);\n const source = {\n ...(input.source ?? {}),\n provider: input.source?.provider ?? input.providerId,\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_records (\n record_id, provider_id, kind, agent_id, workspace_id, session_key, project_id,\n content, source_json, confidence, tags_json, status, sensitivity,\n evidence_json, review_after, expires_at, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(record_id) DO UPDATE SET\n provider_id = excluded.provider_id,\n kind = excluded.kind,\n agent_id = excluded.agent_id,\n workspace_id = excluded.workspace_id,\n session_key = excluded.session_key,\n project_id = excluded.project_id,\n content = excluded.content,\n source_json = excluded.source_json,\n confidence = excluded.confidence,\n tags_json = excluded.tags_json,\n status = excluded.status,\n sensitivity = excluded.sensitivity,\n evidence_json = excluded.evidence_json,\n review_after = excluded.review_after,\n expires_at = excluded.expires_at,\n updated_at = excluded.updated_at`,\n ).run(\n id,\n input.providerId,\n input.kind,\n input.agentId,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.projectId ?? null,\n input.content,\n JSON.stringify(source),\n input.confidence ?? null,\n JSON.stringify(input.tags ?? []),\n status,\n sensitivity,\n JSON.stringify(input.evidence ?? []),\n reviewAfter,\n expiresAt,\n now,\n now,\n );\n upsertMemoryRecordFts(db, { ...input, id });\n });\n\n return {\n id,\n kind: input.kind,\n status,\n scope: {\n agentId: input.agentId,\n ...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),\n ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),\n ...(input.projectId ? { projectId: input.projectId } : {}),\n },\n content: input.content,\n source,\n ...(input.confidence != null ? { confidence: input.confidence } : {}),\n sensitivity,\n evidence: input.evidence ?? [],\n ...(reviewAfter != null ? { reviewAfter: new Date(reviewAfter).toISOString() } : {}),\n ...(expiresAt != null ? { expiresAt: new Date(expiresAt).toISOString() } : {}),\n createdAt: new Date(now).toISOString(),\n updatedAt: new Date(now).toISOString(),\n tags: input.tags ?? [],\n };\n}\n\nexport function getMemoryRecord(recordId: string): MemoryRecord | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_records WHERE record_id = ?`)\n .get(recordId) as MemoryRecordRow | undefined;\n return row ? rowToRecord(row) : null;\n}\n\nexport function listMemoryRecords(options: ListMemoryRecordsOptions = {}): MemoryRecord[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.projectId) {\n where.push('project_id = ?');\n params.push(options.projectId);\n }\n if (options.kind) {\n where.push('kind = ?');\n params.push(options.kind);\n }\n if (options.status) {\n where.push('status = ?');\n params.push(options.status);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const offset = Math.max(0, options.offset ?? 0);\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_records\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as MemoryRecordRow[];\n return rows.map(rowToRecord);\n}\n\nexport function searchMemoryRecords(options: SearchMemoryRecordsOptions): MemorySearchResult[] {\n const query = escapeFts5Query(options.query);\n if (!query) return [];\n\n const filters: string[] = ['memory_records_fts MATCH ?'];\n const params: Array<string | number | null> = [query];\n if (options.agentId) {\n filters.push('f.agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n filters.push('f.workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.projectId) {\n filters.push('r.project_id = ?');\n params.push(options.projectId);\n }\n if (options.providerId) {\n filters.push('f.provider_id = ?');\n params.push(options.providerId);\n }\n if (options.kinds && options.kinds.length > 0) {\n filters.push(`f.kind IN (${options.kinds.map(() => '?').join(', ')})`);\n params.push(...options.kinds);\n }\n const statuses = options.statuses && options.statuses.length > 0 ? options.statuses : ['active'];\n filters.push(`r.status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n\n const maxResults = Math.max(1, Math.min(50, options.maxResults ?? 5));\n const minScore = options.minScore ?? 0;\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT\n r.*,\n bm25(memory_records_fts) AS rank\n FROM memory_records_fts f\n JOIN memory_records r ON r.record_id = f.record_id\n WHERE ${filters.join(' AND ')}\n ORDER BY rank\n LIMIT ?`,\n )\n .all(...params, maxResults * 3) as MemoryRecordSearchRow[];\n\n return rows\n .map((row) => {\n const record = rowToRecord(row);\n const score = bm25ToScore(row.rank);\n return {\n record,\n score,\n snippet: record.content,\n citation: {\n providerId: row.provider_id,\n recordId: row.record_id,\n path: record.source.path,\n lineStart: record.source.lineStart,\n lineEnd: record.source.lineEnd,\n createdAt: record.createdAt,\n },\n };\n })\n .filter((result) => result.score >= minScore)\n .slice(0, maxResults);\n}\n\nexport function deleteMemoryRecord(recordId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(recordId);\n const result = db.prepare(`DELETE FROM memory_records WHERE record_id = ?`).run(recordId);\n return result.changes > 0;\n });\n}\n\nexport function appendMemorySignal(input: AppendMemorySignalInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_signals (\n signal_id, source, record_id, provider_id, agent_id, workspace_id,\n session_key, score, content, metadata_json, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.signal.source,\n input.signal.recordId ?? null,\n input.providerId ?? null,\n input.agentId ?? null,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.signal.score ?? null,\n input.signal.content ?? null,\n JSON.stringify(input.signal.metadata ?? {}),\n now,\n );\n if (input.signal.recordId) {\n db.prepare(\n `UPDATE memory_records\n SET recall_count = recall_count + 1, last_recalled_at = ?, updated_at = MAX(updated_at, ?)\n WHERE record_id = ?`,\n ).run(now, now, input.signal.recordId);\n }\n });\n return id;\n}\n\nexport function listMemorySignals(options: {\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n limit?: number;\n} = {}): MemorySignalRowPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.recordId) {\n where.push('record_id = ?');\n params.push(options.recordId);\n }\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_signals\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemorySignalRow[];\n return rows.map((row) => {\n let metadata: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(row.metadata_json) as unknown;\n if (parsed && typeof parsed === 'object') metadata = parsed as Record<string, unknown>;\n } catch {\n metadata = {};\n }\n return {\n signalId: row.signal_id,\n source: row.source,\n ...(row.record_id ? { recordId: row.record_id } : {}),\n ...(row.provider_id ? { providerId: row.provider_id } : {}),\n ...(row.agent_id ? { agentId: row.agent_id } : {}),\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.score != null ? { score: row.score } : {}),\n ...(row.content ? { content: row.content } : {}),\n metadata,\n createdAt: new Date(row.created_at).toISOString(),\n };\n });\n}\n\nexport function getMemoryProviderState(providerId: string, scopeKey: string): unknown | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT state_json FROM memory_provider_state WHERE provider_id = ? AND scope_key = ?`)\n .get(providerId, scopeKey) as { state_json: string } | undefined;\n if (!row) return null;\n try {\n return JSON.parse(row.state_json) as unknown;\n } catch {\n return null;\n }\n}\n\nexport function setMemoryProviderState(providerId: string, scopeKey: string, state: unknown): void {\n const now = Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_provider_state (provider_id, scope_key, state_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(provider_id, scope_key) DO UPDATE SET\n state_json = excluded.state_json,\n updated_at = excluded.updated_at`,\n ).run(providerId, scopeKey, JSON.stringify(state ?? null), now);\n });\n}\n\nexport function appendMemoryTraceEvent(input: AppendMemoryTraceEventInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n const feedback = input.feedback\n ? normalizeMemoryTraceFeedback(input.feedback, now)\n : undefined;\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_trace_events (\n trace_id, session_key, turn_id, phase, provider_id, request_json,\n result_count, selected_record_ids_json, skipped_reason, error, feedback_json, duration_ms, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.sessionKey ?? null,\n input.turnId ?? null,\n input.phase,\n input.providerId,\n JSON.stringify(input.request ?? {}),\n input.resultCount ?? null,\n JSON.stringify(input.selectedRecordIds ?? []),\n input.skippedReason ?? null,\n input.error ?? null,\n JSON.stringify(feedback ?? {}),\n Math.max(0, Math.floor(input.durationMs ?? 0)),\n now,\n );\n });\n return id;\n}\n\nexport function listMemoryTraceEvents(options: {\n providerId?: string;\n sessionKey?: string;\n phase?: string;\n limit?: number;\n} = {}): MemoryTraceEventPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n if (options.phase) {\n where.push('phase = ?');\n params.push(options.phase);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n return rows.map(memoryTraceRowToPayload);\n}\n\nexport function setMemoryTraceFeedback(input: SetMemoryTraceFeedbackInput): MemoryTraceEventPayload | null {\n const existing = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_trace_events WHERE trace_id = ?`)\n .get(input.traceId) as MemoryTraceRow | undefined;\n if (!existing) {\n return null;\n }\n const feedback = normalizeMemoryTraceFeedback(\n input.feedback,\n input.nowMs,\n parseMemoryTraceFeedback(existing.feedback_json),\n );\n runSqliteWriteTransaction((db) => {\n db.prepare(`UPDATE memory_trace_events SET feedback_json = ? WHERE trace_id = ?`)\n .run(JSON.stringify(feedback), input.traceId);\n });\n return memoryTraceRowToPayload({ ...existing, feedback_json: JSON.stringify(feedback) });\n}\n\nexport function summarizeMemoryRecallFeedback(options: {\n recordId?: string;\n providerId?: string;\n sessionKey?: string;\n limit?: number;\n} = {}): MemoryRecallFeedbackSummary[] {\n const where = ['phase IN (?, ?)'];\n const params: Array<string | number> = ['search', 'inject'];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n const limit = Math.max(1, Math.min(5000, options.limit ?? 1000));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n WHERE ${where.join(' AND ')}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n\n const summaries = new Map<string, MemoryRecallFeedbackSummary & { scoreTotal: number; scoreCount: number }>();\n for (const row of rows) {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n if (!feedback) continue;\n const recordIds = parseStringArray(row.selected_record_ids_json);\n for (const recordId of recordIds) {\n if (options.recordId && recordId !== options.recordId) continue;\n const current = summaries.get(recordId) ?? {\n recordId,\n helpful: 0,\n notHelpful: 0,\n mixed: 0,\n irrelevant: 0,\n total: 0,\n averageScore: null,\n scoreTotal: 0,\n scoreCount: 0,\n };\n if (feedback.outcome === 'helpful') current.helpful += 1;\n if (feedback.outcome === 'not_helpful') current.notHelpful += 1;\n if (feedback.outcome === 'mixed') current.mixed += 1;\n if (feedback.outcome === 'irrelevant') current.irrelevant += 1;\n current.total += 1;\n if (typeof feedback.score === 'number') {\n current.scoreTotal += feedback.score;\n current.scoreCount += 1;\n current.averageScore = current.scoreTotal / current.scoreCount;\n }\n current.lastFeedbackAt ??= feedback.updatedAt ?? feedback.createdAt;\n summaries.set(recordId, current);\n }\n }\n\n return [...summaries.values()]\n .map(({ scoreTotal: _scoreTotal, scoreCount: _scoreCount, ...summary }) => summary)\n .sort((a, b) => b.total - a.total);\n}\n\nfunction parseJsonValue(json: string, fallback: unknown): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"memory-records-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-records-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n MemoryDisclosurePolicy,\n MemoryDurability,\n MemoryExplicitness,\n MemoryKind,\n MemoryRecord,\n MemorySensitivity,\n MemorySearchResult,\n MemorySignal,\n MemoryStatus,\n} from '../../agent/memory/types.js';\nimport { escapeFts5Query } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\ntype MemoryRecordRow = {\n record_id: string;\n provider_id: string;\n kind: string;\n agent_id: string;\n workspace_id: string | null;\n session_key: string | null;\n project_id: string | null;\n content: string;\n source_json: string;\n confidence: number | null;\n tags_json: string;\n status: string;\n sensitivity: string;\n evidence_json: string;\n canonical_key: string | null;\n explicitness: string;\n durability: string;\n importance: number;\n disclosure_policy: string;\n valid_from: number | null;\n valid_to: number | null;\n review_after: number | null;\n expires_at: number | null;\n supersedes_record_id: string | null;\n conflict_group_id: string | null;\n created_at: number;\n updated_at: number;\n};\n\ntype MemoryRecordSearchRow = MemoryRecordRow & {\n rank: number;\n};\n\nexport interface UpsertMemoryRecordInput {\n id?: string;\n providerId: string;\n kind: MemoryKind;\n agentId: string;\n workspaceId?: string;\n sessionKey?: string;\n projectId?: string;\n content: string;\n canonicalKey?: string;\n source?: MemoryRecord['source'];\n confidence?: number;\n tags?: string[];\n status?: MemoryStatus;\n sensitivity?: MemorySensitivity;\n explicitness?: MemoryExplicitness;\n durability?: MemoryDurability;\n importance?: number;\n disclosurePolicy?: MemoryDisclosurePolicy;\n evidence?: MemoryRecord['evidence'];\n validFrom?: string;\n validTo?: string;\n reviewAfter?: string;\n expiresAt?: string;\n supersedesRecordId?: string;\n conflictGroupId?: string;\n nowMs?: number;\n}\n\nexport interface ListMemoryRecordsOptions {\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n projectId?: string;\n kind?: MemoryKind;\n status?: MemoryStatus;\n canonicalKey?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface SearchMemoryRecordsOptions {\n query: string;\n agentId?: string;\n workspaceId?: string;\n projectId?: string;\n providerId?: string;\n kinds?: MemoryKind[];\n statuses?: MemoryStatus[];\n maxResults?: number;\n minScore?: number;\n}\n\nexport interface AppendMemorySignalInput {\n signal: MemorySignal;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n nowMs?: number;\n}\n\nexport interface MemorySignalRowPayload {\n signalId: string;\n source: string;\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n score?: number;\n content?: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\ntype MemorySignalRow = {\n signal_id: string;\n source: string;\n record_id: string | null;\n provider_id: string | null;\n agent_id: string | null;\n workspace_id: string | null;\n session_key: string | null;\n score: number | null;\n content: string | null;\n metadata_json: string;\n created_at: number;\n};\n\ntype MemoryTraceRow = {\n trace_id: string;\n session_key: string | null;\n turn_id: string | null;\n phase: string;\n provider_id: string;\n request_json: string;\n result_count: number | null;\n selected_record_ids_json: string;\n skipped_reason: string | null;\n error: string | null;\n feedback_json: string;\n duration_ms: number;\n created_at: number;\n};\n\nexport type MemoryTraceFeedbackOutcome = 'helpful' | 'not_helpful' | 'mixed' | 'irrelevant';\n\nexport interface MemoryTraceFeedback {\n outcome: MemoryTraceFeedbackOutcome;\n score?: number;\n reason?: string;\n source?: 'user' | 'evaluator' | 'system';\n createdAt: string;\n updatedAt?: string;\n}\n\nexport interface AppendMemoryTraceEventInput {\n traceId?: string;\n sessionKey?: string;\n turnId?: string;\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test' | 'understanding' | 'remediation';\n providerId: string;\n request?: unknown;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n durationMs?: number;\n nowMs?: number;\n}\n\nexport interface SetMemoryTraceFeedbackInput {\n traceId: string;\n feedback: Omit<MemoryTraceFeedback, 'createdAt' | 'updatedAt'> & {\n createdAt?: string;\n updatedAt?: string;\n };\n nowMs?: number;\n}\n\nexport interface SetLatestMemoryInjectFeedbackInput {\n sessionKey: string;\n beforeMs?: number;\n requireSelectedRecords?: boolean;\n feedback: SetMemoryTraceFeedbackInput['feedback'];\n nowMs?: number;\n}\n\nexport type FindLatestMemoryInjectTraceInput = Pick<\n SetLatestMemoryInjectFeedbackInput,\n 'sessionKey' | 'beforeMs' | 'requireSelectedRecords'\n>;\n\nexport interface MemoryTraceEventPayload {\n traceId: string;\n sessionKey?: string;\n turnId?: string;\n phase: string;\n providerId: string;\n request: unknown;\n resultCount?: number;\n selectedRecordIds: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n remediation?: MemoryFeedbackRemediationResult;\n durationMs: number;\n createdAt: string;\n}\n\nexport interface MemoryFeedbackRemediationResult {\n triggerTraceId: string;\n evaluatedRecordIds: string[];\n needsReviewRecordIds: string[];\n}\n\nexport const USER_UNDERSTANDING_REMEDIATION_POLICY = {\n minNotHelpful: 2,\n confidencePenalty: 0.2,\n} as const;\n\nexport interface MemoryRecallFeedbackSummary {\n recordId: string;\n helpful: number;\n notHelpful: number;\n mixed: number;\n irrelevant: number;\n total: number;\n averageScore: number | null;\n lastFeedbackAt?: string;\n}\n\nexport interface UserUnderstandingQualityMetrics {\n agentId?: string;\n windowDays: number;\n since: string;\n attempts: {\n total: number;\n turn: number;\n background: number;\n };\n candidates: {\n proposed: number;\n created: number;\n deduplicated: number;\n rejectedByPolicy: number;\n };\n records: {\n total: number;\n candidate: number;\n active: number;\n rejected: number;\n needsReview: number;\n stale: number;\n archived: number;\n agingCandidates: number;\n explicit: number;\n inferred: number;\n averageConfidence: number | null;\n };\n decisions: {\n total: number;\n acceptanceRate: number | null;\n };\n recall: {\n total: number;\n helpful: number;\n notHelpful: number;\n mixed: number;\n irrelevant: number;\n helpfulRate: number | null;\n };\n}\n\nfunction parseStringArray(json: string): string[] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction parseEvidence(json: string): MemoryRecord['evidence'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((item): item is NonNullable<MemoryRecord['evidence']>[number] =>\n Boolean(item) && typeof item === 'object',\n );\n } catch {\n return [];\n }\n}\n\nfunction parseMemoryTraceFeedback(json: string): MemoryTraceFeedback | undefined {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!parsed || typeof parsed !== 'object') return undefined;\n const obj = parsed as Record<string, unknown>;\n const outcome = obj.outcome;\n if (\n outcome !== 'helpful' &&\n outcome !== 'not_helpful' &&\n outcome !== 'mixed' &&\n outcome !== 'irrelevant'\n ) {\n return undefined;\n }\n return {\n outcome,\n ...(typeof obj.score === 'number' ? { score: obj.score } : {}),\n ...(typeof obj.reason === 'string' ? { reason: obj.reason } : {}),\n ...(obj.source === 'user' || obj.source === 'evaluator' || obj.source === 'system'\n ? { source: obj.source }\n : {}),\n createdAt: typeof obj.createdAt === 'string' ? obj.createdAt : new Date(0).toISOString(),\n ...(typeof obj.updatedAt === 'string' ? { updatedAt: obj.updatedAt } : {}),\n };\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeMemoryTraceFeedback(\n input: SetMemoryTraceFeedbackInput['feedback'],\n nowMs = Date.now(),\n existing?: MemoryTraceFeedback,\n): MemoryTraceFeedback {\n const score = typeof input.score === 'number'\n ? Math.max(-1, Math.min(1, input.score))\n : undefined;\n const reason = typeof input.reason === 'string' && input.reason.trim()\n ? input.reason.trim().slice(0, 1000)\n : undefined;\n const nowIso = new Date(nowMs).toISOString();\n return {\n outcome: input.outcome,\n ...(score != null ? { score } : {}),\n ...(reason ? { reason } : {}),\n ...(input.source ? { source: input.source } : {}),\n createdAt: input.createdAt ?? existing?.createdAt ?? nowIso,\n updatedAt: input.updatedAt ?? nowIso,\n };\n}\n\nfunction memoryTraceRowToPayload(row: MemoryTraceRow): MemoryTraceEventPayload {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n return {\n traceId: row.trace_id,\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.turn_id ? { turnId: row.turn_id } : {}),\n phase: row.phase,\n providerId: row.provider_id,\n request: parseJsonValue(row.request_json, {}),\n ...(row.result_count != null ? { resultCount: row.result_count } : {}),\n selectedRecordIds: parseStringArray(row.selected_record_ids_json),\n ...(row.skipped_reason ? { skippedReason: row.skipped_reason } : {}),\n ...(row.error ? { error: row.error } : {}),\n ...(feedback ? { feedback } : {}),\n durationMs: row.duration_ms,\n createdAt: new Date(row.created_at).toISOString(),\n };\n}\n\nfunction parseOptionalTimestamp(value: string | undefined): number | null {\n if (!value?.trim()) return null;\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction timestampToIso(value: number | null): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\nfunction parseSource(json: string): MemoryRecord['source'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return parsed && typeof parsed === 'object' ? (parsed as MemoryRecord['source']) : {};\n } catch {\n return {};\n }\n}\n\nfunction rowToRecord(row: MemoryRecordRow): MemoryRecord {\n return {\n id: row.record_id,\n kind: row.kind as MemoryKind,\n status: row.status as MemoryStatus,\n ...(row.canonical_key ? { canonicalKey: row.canonical_key } : {}),\n scope: {\n agentId: row.agent_id,\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.project_id ? { projectId: row.project_id } : {}),\n },\n content: row.content,\n source: parseSource(row.source_json),\n ...(row.confidence != null ? { confidence: row.confidence } : {}),\n sensitivity: row.sensitivity as MemorySensitivity,\n explicitness: row.explicitness as MemoryExplicitness,\n durability: row.durability as MemoryDurability,\n importance: row.importance,\n disclosurePolicy: row.disclosure_policy as MemoryDisclosurePolicy,\n evidence: parseEvidence(row.evidence_json),\n ...(timestampToIso(row.valid_from) ? { validFrom: timestampToIso(row.valid_from) } : {}),\n ...(timestampToIso(row.valid_to) ? { validTo: timestampToIso(row.valid_to) } : {}),\n ...(timestampToIso(row.review_after) ? { reviewAfter: timestampToIso(row.review_after) } : {}),\n ...(timestampToIso(row.expires_at) ? { expiresAt: timestampToIso(row.expires_at) } : {}),\n ...(row.supersedes_record_id ? { supersedesRecordId: row.supersedes_record_id } : {}),\n ...(row.conflict_group_id ? { conflictGroupId: row.conflict_group_id } : {}),\n createdAt: new Date(row.created_at).toISOString(),\n updatedAt: new Date(row.updated_at).toISOString(),\n tags: parseStringArray(row.tags_json),\n };\n}\n\nfunction bm25ToScore(rank: number): number {\n return Math.max(0, Math.min(1, 1 / (1 + Math.max(0, rank))));\n}\n\nfunction upsertMemoryRecordFts(\n db: ReturnType<typeof getSqliteDatabase>,\n row: Pick<UpsertMemoryRecordInput, 'providerId' | 'kind' | 'agentId' | 'workspaceId' | 'content'> & { id: string },\n): void {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(row.id);\n if (!row.content.trim()) return;\n db.prepare(\n `INSERT INTO memory_records_fts (\n content, record_id, provider_id, kind, agent_id, workspace_id\n ) VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(row.content, row.id, row.providerId, row.kind, row.agentId, row.workspaceId ?? null);\n}\n\nexport function upsertMemoryRecord(input: UpsertMemoryRecordInput): MemoryRecord {\n const id = input.id ?? randomUUID();\n const now = input.nowMs ?? Date.now();\n const status = input.status ?? 'active';\n const sensitivity = input.sensitivity ?? 'normal';\n const explicitness = input.explicitness ?? 'inferred';\n const durability = input.durability ?? 'durable';\n const importance = Math.max(0, Math.min(1, input.importance ?? 0.5));\n const disclosurePolicy = input.disclosurePolicy ?? 'referenceable';\n const validFrom = parseOptionalTimestamp(input.validFrom);\n const validTo = parseOptionalTimestamp(input.validTo);\n const reviewAfter = parseOptionalTimestamp(input.reviewAfter);\n const expiresAt = parseOptionalTimestamp(input.expiresAt);\n const source = {\n ...(input.source ?? {}),\n provider: input.source?.provider ?? input.providerId,\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_records (\n record_id, provider_id, kind, agent_id, workspace_id, session_key, project_id,\n content, source_json, confidence, tags_json, status, sensitivity,\n evidence_json, canonical_key, explicitness, durability, importance,\n disclosure_policy, valid_from, valid_to, review_after, expires_at,\n supersedes_record_id, conflict_group_id, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(record_id) DO UPDATE SET\n provider_id = excluded.provider_id,\n kind = excluded.kind,\n agent_id = excluded.agent_id,\n workspace_id = excluded.workspace_id,\n session_key = excluded.session_key,\n project_id = excluded.project_id,\n content = excluded.content,\n source_json = excluded.source_json,\n confidence = excluded.confidence,\n tags_json = excluded.tags_json,\n status = excluded.status,\n sensitivity = excluded.sensitivity,\n evidence_json = excluded.evidence_json,\n canonical_key = excluded.canonical_key,\n explicitness = excluded.explicitness,\n durability = excluded.durability,\n importance = excluded.importance,\n disclosure_policy = excluded.disclosure_policy,\n valid_from = excluded.valid_from,\n valid_to = excluded.valid_to,\n review_after = excluded.review_after,\n expires_at = excluded.expires_at,\n supersedes_record_id = excluded.supersedes_record_id,\n conflict_group_id = excluded.conflict_group_id,\n updated_at = excluded.updated_at`,\n ).run(\n id,\n input.providerId,\n input.kind,\n input.agentId,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.projectId ?? null,\n input.content,\n JSON.stringify(source),\n input.confidence ?? null,\n JSON.stringify(input.tags ?? []),\n status,\n sensitivity,\n JSON.stringify(input.evidence ?? []),\n input.canonicalKey ?? null,\n explicitness,\n durability,\n importance,\n disclosurePolicy,\n validFrom,\n validTo,\n reviewAfter,\n expiresAt,\n input.supersedesRecordId ?? null,\n input.conflictGroupId ?? null,\n now,\n now,\n );\n upsertMemoryRecordFts(db, { ...input, id });\n if (input.supersedesRecordId && input.supersedesRecordId !== id) {\n const target = db.prepare(`SELECT 1 FROM memory_records WHERE record_id = ?`)\n .get(input.supersedesRecordId);\n if (target) {\n db.prepare(\n `INSERT INTO memory_relations (\n relation_id, from_record_id, relation_type, to_record_id,\n confidence, valid_from, valid_to, created_at, updated_at\n ) VALUES (?, ?, 'supersedes', ?, ?, ?, NULL, ?, ?)\n ON CONFLICT(from_record_id, relation_type, to_record_id) DO UPDATE SET\n confidence = excluded.confidence,\n valid_from = excluded.valid_from,\n valid_to = NULL,\n updated_at = excluded.updated_at`,\n ).run(\n randomUUID(),\n id,\n input.supersedesRecordId,\n input.confidence ?? 1,\n validFrom ?? now,\n now,\n now,\n );\n if (status === 'active') {\n db.prepare(\n `UPDATE memory_records\n SET status = 'archived', valid_to = COALESCE(valid_to, ?), updated_at = ?\n WHERE record_id = ? AND status IN ('active', 'needs_review', 'stale')`,\n ).run(now, now, input.supersedesRecordId);\n }\n }\n }\n });\n\n return {\n id,\n kind: input.kind,\n status,\n ...(input.canonicalKey ? { canonicalKey: input.canonicalKey } : {}),\n scope: {\n agentId: input.agentId,\n ...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),\n ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),\n ...(input.projectId ? { projectId: input.projectId } : {}),\n },\n content: input.content,\n source,\n ...(input.confidence != null ? { confidence: input.confidence } : {}),\n sensitivity,\n explicitness,\n durability,\n importance,\n disclosurePolicy,\n evidence: input.evidence ?? [],\n ...(validFrom != null ? { validFrom: new Date(validFrom).toISOString() } : {}),\n ...(validTo != null ? { validTo: new Date(validTo).toISOString() } : {}),\n ...(reviewAfter != null ? { reviewAfter: new Date(reviewAfter).toISOString() } : {}),\n ...(expiresAt != null ? { expiresAt: new Date(expiresAt).toISOString() } : {}),\n ...(input.supersedesRecordId ? { supersedesRecordId: input.supersedesRecordId } : {}),\n ...(input.conflictGroupId ? { conflictGroupId: input.conflictGroupId } : {}),\n createdAt: new Date(now).toISOString(),\n updatedAt: new Date(now).toISOString(),\n tags: input.tags ?? [],\n };\n}\n\nexport function getMemoryRecord(recordId: string): MemoryRecord | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_records WHERE record_id = ?`)\n .get(recordId) as MemoryRecordRow | undefined;\n return row ? rowToRecord(row) : null;\n}\n\nexport function listMemoryRecords(options: ListMemoryRecordsOptions = {}): MemoryRecord[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.projectId) {\n where.push('project_id = ?');\n params.push(options.projectId);\n }\n if (options.kind) {\n where.push('kind = ?');\n params.push(options.kind);\n }\n if (options.status) {\n where.push('status = ?');\n params.push(options.status);\n }\n if (options.canonicalKey) {\n where.push('canonical_key = ?');\n params.push(options.canonicalKey);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const offset = Math.max(0, options.offset ?? 0);\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_records\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as MemoryRecordRow[];\n return rows.map(rowToRecord);\n}\n\nexport function searchMemoryRecords(options: SearchMemoryRecordsOptions): MemorySearchResult[] {\n const query = escapeFts5Query(options.query);\n if (!query) return [];\n\n const filters: string[] = ['memory_records_fts MATCH ?'];\n const params: Array<string | number | null> = [query];\n if (options.agentId) {\n filters.push('f.agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n filters.push('f.workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.projectId) {\n filters.push('r.project_id = ?');\n params.push(options.projectId);\n }\n if (options.providerId) {\n filters.push('f.provider_id = ?');\n params.push(options.providerId);\n }\n if (options.kinds && options.kinds.length > 0) {\n filters.push(`f.kind IN (${options.kinds.map(() => '?').join(', ')})`);\n params.push(...options.kinds);\n }\n const statuses = options.statuses && options.statuses.length > 0 ? options.statuses : ['active'];\n filters.push(`r.status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n\n const maxResults = Math.max(1, Math.min(50, options.maxResults ?? 5));\n const minScore = options.minScore ?? 0;\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT\n r.*,\n bm25(memory_records_fts) AS rank\n FROM memory_records_fts f\n JOIN memory_records r ON r.record_id = f.record_id\n WHERE ${filters.join(' AND ')}\n ORDER BY rank\n LIMIT ?`,\n )\n .all(...params, maxResults * 3) as MemoryRecordSearchRow[];\n\n return rows\n .map((row) => {\n const record = rowToRecord(row);\n const score = bm25ToScore(row.rank);\n return {\n record,\n score,\n snippet: record.content,\n citation: {\n providerId: row.provider_id,\n recordId: row.record_id,\n path: record.source.path,\n lineStart: record.source.lineStart,\n lineEnd: record.source.lineEnd,\n createdAt: record.createdAt,\n },\n };\n })\n .filter((result) => result.score >= minScore)\n .slice(0, maxResults);\n}\n\nexport function deleteMemoryRecord(recordId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(recordId);\n const result = db.prepare(`DELETE FROM memory_records WHERE record_id = ?`).run(recordId);\n return result.changes > 0;\n });\n}\n\nexport function appendMemorySignal(input: AppendMemorySignalInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_signals (\n signal_id, source, record_id, provider_id, agent_id, workspace_id,\n session_key, score, content, metadata_json, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.signal.source,\n input.signal.recordId ?? null,\n input.providerId ?? null,\n input.agentId ?? null,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.signal.score ?? null,\n input.signal.content ?? null,\n JSON.stringify(input.signal.metadata ?? {}),\n now,\n );\n if (input.signal.recordId) {\n db.prepare(\n `UPDATE memory_records\n SET recall_count = recall_count + 1, last_recalled_at = ?, updated_at = MAX(updated_at, ?)\n WHERE record_id = ?`,\n ).run(now, now, input.signal.recordId);\n }\n });\n return id;\n}\n\nexport function listMemorySignals(options: {\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n limit?: number;\n} = {}): MemorySignalRowPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.recordId) {\n where.push('record_id = ?');\n params.push(options.recordId);\n }\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_signals\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemorySignalRow[];\n return rows.map((row) => {\n let metadata: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(row.metadata_json) as unknown;\n if (parsed && typeof parsed === 'object') metadata = parsed as Record<string, unknown>;\n } catch {\n metadata = {};\n }\n return {\n signalId: row.signal_id,\n source: row.source,\n ...(row.record_id ? { recordId: row.record_id } : {}),\n ...(row.provider_id ? { providerId: row.provider_id } : {}),\n ...(row.agent_id ? { agentId: row.agent_id } : {}),\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.score != null ? { score: row.score } : {}),\n ...(row.content ? { content: row.content } : {}),\n metadata,\n createdAt: new Date(row.created_at).toISOString(),\n };\n });\n}\n\nexport function getMemoryProviderState(providerId: string, scopeKey: string): unknown | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT state_json FROM memory_provider_state WHERE provider_id = ? AND scope_key = ?`)\n .get(providerId, scopeKey) as { state_json: string } | undefined;\n if (!row) return null;\n try {\n return JSON.parse(row.state_json) as unknown;\n } catch {\n return null;\n }\n}\n\nexport function setMemoryProviderState(providerId: string, scopeKey: string, state: unknown): void {\n const now = Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_provider_state (provider_id, scope_key, state_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(provider_id, scope_key) DO UPDATE SET\n state_json = excluded.state_json,\n updated_at = excluded.updated_at`,\n ).run(providerId, scopeKey, JSON.stringify(state ?? null), now);\n });\n}\n\nexport function appendMemoryTraceEvent(input: AppendMemoryTraceEventInput): string {\n const id = input.traceId ?? randomUUID();\n const now = input.nowMs ?? Date.now();\n const feedback = input.feedback\n ? normalizeMemoryTraceFeedback(input.feedback, now)\n : undefined;\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_trace_events (\n trace_id, session_key, turn_id, phase, provider_id, request_json,\n result_count, selected_record_ids_json, skipped_reason, error, feedback_json, duration_ms, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.sessionKey ?? null,\n input.turnId ?? null,\n input.phase,\n input.providerId,\n JSON.stringify(input.request ?? {}),\n input.resultCount ?? null,\n JSON.stringify(input.selectedRecordIds ?? []),\n input.skippedReason ?? null,\n input.error ?? null,\n JSON.stringify(feedback ?? {}),\n Math.max(0, Math.floor(input.durationMs ?? 0)),\n now,\n );\n });\n return id;\n}\n\nexport function listMemoryTraceEvents(options: {\n providerId?: string;\n sessionKey?: string;\n phase?: string;\n limit?: number;\n} = {}): MemoryTraceEventPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n if (options.phase) {\n where.push('phase = ?');\n params.push(options.phase);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n return rows.map(memoryTraceRowToPayload);\n}\n\nexport function setMemoryTraceFeedback(input: SetMemoryTraceFeedbackInput): MemoryTraceEventPayload | null {\n const existing = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_trace_events WHERE trace_id = ?`)\n .get(input.traceId) as MemoryTraceRow | undefined;\n if (!existing) {\n return null;\n }\n const nowMs = input.nowMs ?? Date.now();\n const feedback = normalizeMemoryTraceFeedback(\n input.feedback,\n nowMs,\n parseMemoryTraceFeedback(existing.feedback_json),\n );\n let remediation: MemoryFeedbackRemediationResult | undefined;\n runSqliteWriteTransaction((db) => {\n db.prepare(`UPDATE memory_trace_events SET feedback_json = ? WHERE trace_id = ?`)\n .run(JSON.stringify(feedback), input.traceId);\n remediation = reconcileUserUnderstandingFeedback(db, existing, feedback, nowMs);\n });\n return {\n ...memoryTraceRowToPayload({ ...existing, feedback_json: JSON.stringify(feedback) }),\n ...(remediation ? { remediation } : {}),\n };\n}\n\nfunction reconcileUserUnderstandingFeedback(\n db: ReturnType<typeof getSqliteDatabase>,\n trace: MemoryTraceRow,\n feedback: MemoryTraceFeedback,\n nowMs: number,\n): MemoryFeedbackRemediationResult | undefined {\n if (trace.phase !== 'inject' || feedback.outcome !== 'not_helpful') return undefined;\n const explicitCorrection = feedback.source === 'system'\n && feedback.reason === 'detected_explicit_user_correction';\n const evaluatedRecordIds: string[] = [];\n const needsReviewRecordIds: string[] = [];\n const actions: Array<Record<string, unknown>> = [];\n\n for (const recordId of new Set(parseStringArray(trace.selected_record_ids_json))) {\n const record = db.prepare(\n `SELECT * FROM memory_records\n WHERE record_id = ?\n AND status = 'active'\n AND tags_json LIKE '%\\\"user-understanding\\\"%'`,\n ).get(recordId) as MemoryRecordRow | undefined;\n if (!record) continue;\n evaluatedRecordIds.push(recordId);\n const feedbackRows = db.prepare(\n `SELECT trace.feedback_json\n FROM memory_trace_events AS trace\n JOIN json_each(trace.selected_record_ids_json) AS selected\n ON selected.value = ?\n WHERE trace.phase = 'inject'`,\n ).all(recordId) as Array<{ feedback_json: string }>;\n let helpful = 0;\n let notHelpful = 0;\n for (const row of feedbackRows) {\n const recordFeedback = parseMemoryTraceFeedback(row.feedback_json);\n if (recordFeedback?.outcome === 'helpful') helpful += 1;\n if (recordFeedback?.outcome === 'not_helpful') notHelpful += 1;\n }\n if (!explicitCorrection && (\n notHelpful < USER_UNDERSTANDING_REMEDIATION_POLICY.minNotHelpful\n || notHelpful <= helpful\n )) {\n continue;\n }\n const nextConfidence = record.confidence == null\n ? null\n : Math.round(Math.max(0.1, record.confidence - USER_UNDERSTANDING_REMEDIATION_POLICY.confidencePenalty) * 1000) / 1000;\n const update = db.prepare(\n `UPDATE memory_records\n SET status = 'needs_review', confidence = ?, review_after = ?, updated_at = ?\n WHERE record_id = ? AND status = 'active'`,\n ).run(nextConfidence, nowMs, nowMs, recordId);\n if (update.changes === 0) continue;\n needsReviewRecordIds.push(recordId);\n actions.push({\n recordId,\n previousStatus: record.status,\n nextStatus: 'needs_review',\n previousConfidence: record.confidence,\n nextConfidence,\n helpful,\n notHelpful,\n });\n }\n\n const result: MemoryFeedbackRemediationResult = {\n triggerTraceId: trace.trace_id,\n evaluatedRecordIds,\n needsReviewRecordIds,\n };\n if (needsReviewRecordIds.length > 0) {\n db.prepare(\n `INSERT INTO memory_trace_events (\n trace_id, session_key, turn_id, phase, provider_id, request_json,\n result_count, selected_record_ids_json, skipped_reason, error,\n feedback_json, duration_ms, created_at\n ) VALUES (?, ?, ?, 'remediation', 'user-understanding', ?, ?, ?, NULL, NULL, '{}', 0, ?)`,\n ).run(\n randomUUID(),\n trace.session_key,\n trace.turn_id,\n JSON.stringify({\n triggerTraceId: trace.trace_id,\n reason: explicitCorrection\n ? 'explicit_user_correction'\n : 'repeated_not_helpful_feedback',\n policy: USER_UNDERSTANDING_REMEDIATION_POLICY,\n actions,\n }),\n needsReviewRecordIds.length,\n JSON.stringify(needsReviewRecordIds),\n nowMs,\n );\n }\n return result;\n}\n\nexport function findLatestMemoryInjectTrace(\n input: FindLatestMemoryInjectTraceInput,\n): MemoryTraceEventPayload | null {\n const where = [\n `session_key = ?`,\n `phase = 'inject'`,\n `created_at <= ?`,\n ];\n const row = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n WHERE ${where.join(' AND ')}\n ORDER BY created_at DESC\n LIMIT 1`,\n )\n .get(input.sessionKey, input.beforeMs ?? Date.now()) as MemoryTraceRow | undefined;\n if (!row) return null;\n const trace = memoryTraceRowToPayload(row);\n if (input.requireSelectedRecords && trace.selectedRecordIds.length === 0) return null;\n return trace;\n}\n\nexport function setLatestMemoryInjectFeedback(\n input: SetLatestMemoryInjectFeedbackInput,\n): MemoryTraceEventPayload | null {\n const row = findLatestMemoryInjectTrace(input);\n if (!row) return null;\n return setMemoryTraceFeedback({\n traceId: row.traceId,\n feedback: input.feedback,\n nowMs: input.nowMs,\n });\n}\n\nexport function summarizeMemoryRecallFeedback(options: {\n recordId?: string;\n providerId?: string;\n sessionKey?: string;\n limit?: number;\n} = {}): MemoryRecallFeedbackSummary[] {\n const where = ['phase IN (?, ?)'];\n const params: Array<string | number> = ['search', 'inject'];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n const limit = Math.max(1, Math.min(5000, options.limit ?? 1000));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n WHERE ${where.join(' AND ')}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n\n const summaries = new Map<string, MemoryRecallFeedbackSummary & { scoreTotal: number; scoreCount: number }>();\n for (const row of rows) {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n if (!feedback) continue;\n const recordIds = parseStringArray(row.selected_record_ids_json);\n for (const recordId of recordIds) {\n if (options.recordId && recordId !== options.recordId) continue;\n const current = summaries.get(recordId) ?? {\n recordId,\n helpful: 0,\n notHelpful: 0,\n mixed: 0,\n irrelevant: 0,\n total: 0,\n averageScore: null,\n scoreTotal: 0,\n scoreCount: 0,\n };\n if (feedback.outcome === 'helpful') current.helpful += 1;\n if (feedback.outcome === 'not_helpful') current.notHelpful += 1;\n if (feedback.outcome === 'mixed') current.mixed += 1;\n if (feedback.outcome === 'irrelevant') current.irrelevant += 1;\n current.total += 1;\n if (typeof feedback.score === 'number') {\n current.scoreTotal += feedback.score;\n current.scoreCount += 1;\n current.averageScore = current.scoreTotal / current.scoreCount;\n }\n current.lastFeedbackAt ??= feedback.updatedAt ?? feedback.createdAt;\n summaries.set(recordId, current);\n }\n }\n\n return [...summaries.values()]\n .map(({ scoreTotal: _scoreTotal, scoreCount: _scoreCount, ...summary }) => summary)\n .sort((a, b) => b.total - a.total);\n}\n\nfunction boundedMetricCount(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value)\n ? Math.max(0, Math.floor(value))\n : 0;\n}\n\nfunction metricRate(numerator: number, denominator: number): number | null {\n return denominator > 0 ? Math.round((numerator / denominator) * 10_000) / 10_000 : null;\n}\n\nexport function summarizeUserUnderstandingQuality(options: {\n agentId?: string;\n windowDays?: number;\n agingCandidateDays?: number;\n nowMs?: number;\n} = {}): UserUnderstandingQualityMetrics {\n const nowMs = options.nowMs ?? Date.now();\n const windowDays = Math.max(1, Math.min(365, Math.floor(options.windowDays ?? 30)));\n const sinceMs = nowMs - windowDays * 24 * 60 * 60 * 1000;\n const agingCandidateDays = Math.max(1, Math.min(windowDays, Math.floor(options.agingCandidateDays ?? 7)));\n const agingCutoffMs = nowMs - agingCandidateDays * 24 * 60 * 60 * 1000;\n const db = getSqliteDatabase();\n const agentWhere = options.agentId ? 'AND agent_id = ?' : '';\n const recordRows = db.prepare(\n `SELECT record_id, status, explicitness, confidence, created_at, updated_at\n FROM memory_records\n WHERE tags_json LIKE '%\"user-understanding\"%'\n ${agentWhere}`,\n ).all(...(options.agentId ? [options.agentId] : [])) as Array<{\n record_id: string;\n status: string;\n explicitness: string;\n confidence: number | null;\n created_at: number;\n updated_at: number;\n }>;\n\n const records: UserUnderstandingQualityMetrics['records'] = {\n total: recordRows.length,\n candidate: 0,\n active: 0,\n rejected: 0,\n needsReview: 0,\n stale: 0,\n archived: 0,\n agingCandidates: 0,\n explicit: 0,\n inferred: 0,\n averageConfidence: null,\n };\n let confidenceTotal = 0;\n let confidenceCount = 0;\n const understandingRecordIds = new Set<string>();\n for (const row of recordRows) {\n understandingRecordIds.add(row.record_id);\n if (row.status === 'candidate') records.candidate += 1;\n if (row.status === 'active') records.active += 1;\n if (row.status === 'rejected') records.rejected += 1;\n if (row.status === 'needs_review') records.needsReview += 1;\n if (row.status === 'stale') records.stale += 1;\n if (row.status === 'archived') records.archived += 1;\n if (row.status === 'candidate' && row.created_at <= agingCutoffMs) records.agingCandidates += 1;\n if (row.explicitness === 'explicit') records.explicit += 1;\n if (row.explicitness === 'inferred') records.inferred += 1;\n if (typeof row.confidence === 'number') {\n confidenceTotal += row.confidence;\n confidenceCount += 1;\n }\n }\n records.averageConfidence = confidenceCount > 0\n ? Math.round((confidenceTotal / confidenceCount) * 10_000) / 10_000\n : null;\n\n const attempts: UserUnderstandingQualityMetrics['attempts'] = { total: 0, turn: 0, background: 0 };\n const candidates: UserUnderstandingQualityMetrics['candidates'] = {\n proposed: 0,\n created: 0,\n deduplicated: 0,\n rejectedByPolicy: 0,\n };\n const understandingTraces = db.prepare(\n `SELECT request_json FROM memory_trace_events\n WHERE phase = 'understanding' AND created_at >= ?`,\n ).all(sinceMs) as Array<{ request_json: string }>;\n for (const row of understandingTraces) {\n const parsed = parseJsonValue(row.request_json, {});\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) continue;\n const request = parsed as Record<string, unknown>;\n if (options.agentId && request.agentId !== options.agentId) continue;\n attempts.total += 1;\n if (request.source === 'turn') attempts.turn += 1;\n if (request.source === 'background') attempts.background += 1;\n candidates.proposed += boundedMetricCount(request.proposed);\n candidates.created += boundedMetricCount(request.created);\n candidates.deduplicated += boundedMetricCount(request.deduplicated);\n candidates.rejectedByPolicy += boundedMetricCount(request.rejected);\n }\n\n const recall: UserUnderstandingQualityMetrics['recall'] = {\n total: 0,\n helpful: 0,\n notHelpful: 0,\n mixed: 0,\n irrelevant: 0,\n helpfulRate: null,\n };\n if (understandingRecordIds.size > 0) {\n const recallRows = db.prepare(\n `SELECT selected_record_ids_json, feedback_json FROM memory_trace_events\n WHERE phase IN ('search', 'inject') AND created_at >= ?`,\n ).all(sinceMs) as Array<{ selected_record_ids_json: string; feedback_json: string }>;\n for (const row of recallRows) {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n if (!feedback) continue;\n const selected = parseStringArray(row.selected_record_ids_json);\n if (!selected.some((recordId) => understandingRecordIds.has(recordId))) continue;\n recall.total += 1;\n if (feedback.outcome === 'helpful') recall.helpful += 1;\n if (feedback.outcome === 'not_helpful') recall.notHelpful += 1;\n if (feedback.outcome === 'mixed') recall.mixed += 1;\n if (feedback.outcome === 'irrelevant') recall.irrelevant += 1;\n }\n }\n recall.helpfulRate = metricRate(recall.helpful, recall.total);\n const recentDecisions = recordRows.filter(\n (row) => (row.status === 'active' || row.status === 'rejected') && row.updated_at >= sinceMs,\n );\n const acceptedDecisions = recentDecisions.filter((row) => row.status === 'active').length;\n const decisionTotal = recentDecisions.length;\n\n return {\n ...(options.agentId ? { agentId: options.agentId } : {}),\n windowDays,\n since: new Date(sinceMs).toISOString(),\n attempts,\n candidates,\n records,\n decisions: {\n total: decisionTotal,\n acceptanceRate: metricRate(acceptedDecisions, decisionTotal),\n },\n recall,\n };\n}\n\nfunction parseJsonValue(json: string, fallback: unknown): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"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"}