hippo-memory 1.71.0 → 1.72.0

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 (555) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/apply.d.ts +0 -11
  3. package/dist/agent-memories/apply.js +6 -21
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/copilot.d.ts +1 -3
  7. package/dist/agent-memories/copilot.js +1 -17
  8. package/dist/agent-memories/project-folds.d.ts +10 -0
  9. package/dist/agent-memories/project-folds.js +34 -0
  10. package/dist/agent-memories/sync.js +8 -6
  11. package/dist/api/assemble.js +1 -1
  12. package/dist/api/audit.d.ts +29 -1
  13. package/dist/api/audit.js +44 -5
  14. package/dist/api/auth.d.ts +7 -4
  15. package/dist/api/auth.js +12 -8
  16. package/dist/api/auto-sleep.d.ts +5 -2
  17. package/dist/api/auto-sleep.js +7 -3
  18. package/dist/api/availability.js +2 -3
  19. package/dist/api/cards.d.ts +42 -0
  20. package/dist/api/cards.js +52 -0
  21. package/dist/api/conflicts.d.ts +28 -0
  22. package/dist/api/conflicts.js +61 -0
  23. package/dist/api/context-render.js +4 -3
  24. package/dist/api/context-select.js +9 -11
  25. package/dist/api/context.js +17 -8
  26. package/dist/api/continuity.d.ts +47 -0
  27. package/dist/api/continuity.js +66 -0
  28. package/dist/api/dormant.js +4 -2
  29. package/dist/api/drill-down.js +1 -1
  30. package/dist/api/embeddings.d.ts +17 -0
  31. package/dist/api/embeddings.js +28 -0
  32. package/dist/api/error-reply.d.ts +8 -0
  33. package/dist/api/error-reply.js +21 -0
  34. package/dist/api/forget.d.ts +6 -2
  35. package/dist/api/forget.js +18 -7
  36. package/dist/api/goals.d.ts +1 -1
  37. package/dist/api/goals.js +5 -9
  38. package/dist/api/index.d.ts +4 -2
  39. package/dist/api/index.js +4 -2
  40. package/dist/api/instruction-detect.js +5 -1
  41. package/dist/api/learn.d.ts +4 -0
  42. package/dist/api/learn.js +53 -27
  43. package/dist/api/ledger-db.d.ts +2 -6
  44. package/dist/api/ledger-db.js +4 -36
  45. package/dist/api/memories.d.ts +19 -1
  46. package/dist/api/memories.js +39 -0
  47. package/dist/api/objects.d.ts +1 -1
  48. package/dist/api/outcome.js +1 -1
  49. package/dist/api/pilot-arm.d.ts +1 -11
  50. package/dist/api/pilot-arm.js +5 -45
  51. package/dist/api/predictions.d.ts +3 -1
  52. package/dist/api/predictions.js +6 -0
  53. package/dist/api/projects.d.ts +21 -0
  54. package/dist/api/projects.js +24 -0
  55. package/dist/api/promote.js +1 -1
  56. package/dist/api/prompt-hook.d.ts +15 -2
  57. package/dist/api/prompt-hook.js +44 -4
  58. package/dist/api/recall-cli.d.ts +3 -0
  59. package/dist/api/recall-cli.js +13 -4
  60. package/dist/api/recall-core.js +3 -3
  61. package/dist/api/recall-pipeline.js +6 -7
  62. package/dist/api/recall-request.js +1 -1
  63. package/dist/api/recall.d.ts +0 -3
  64. package/dist/api/recall.js +19 -44
  65. package/dist/api/remember-local.js +1 -1
  66. package/dist/api/remember.d.ts +2 -1
  67. package/dist/api/remember.js +3 -2
  68. package/dist/api/session-end.d.ts +22 -0
  69. package/dist/api/session-end.js +101 -0
  70. package/dist/api/sleep-run.d.ts +1 -1
  71. package/dist/api/sleep-run.js +13 -9
  72. package/dist/api/status.d.ts +24 -0
  73. package/dist/api/status.js +40 -0
  74. package/dist/api/store-init.d.ts +4 -0
  75. package/dist/api/store-init.js +9 -0
  76. package/dist/api/tokens.js +1 -1
  77. package/dist/api/types.d.ts +2 -0
  78. package/dist/api/types.js +6 -1
  79. package/dist/capture/caller-session.d.ts +0 -3
  80. package/dist/capture/caller-session.js +1 -12
  81. package/dist/capture/capture-error.d.ts +2 -2
  82. package/dist/capture/capture-error.js +23 -18
  83. package/dist/capture/codex-patch.js +3 -1
  84. package/dist/capture/command.js +36 -95
  85. package/dist/capture/compact.js +10 -5
  86. package/dist/capture/compaction-items-caller.js +11 -20
  87. package/dist/capture/compaction-record.d.ts +7 -93
  88. package/dist/capture/compaction-record.js +29 -426
  89. package/dist/capture/compaction-spool.d.ts +4 -2
  90. package/dist/capture/compaction-spool.js +20 -6
  91. package/dist/capture/copilot-transcript.d.ts +2 -1
  92. package/dist/capture/copilot-transcript.js +2 -1
  93. package/dist/capture/extract.d.ts +5 -2
  94. package/dist/capture/extract.js +4 -3
  95. package/dist/capture/failure-caller.d.ts +1 -1
  96. package/dist/capture/failure-caller.js +21 -16
  97. package/dist/capture/failure-reading.d.ts +2 -1
  98. package/dist/capture/failure-reading.js +7 -9
  99. package/dist/capture/pre-compact-caller.js +5 -4
  100. package/dist/capture/session-digest.js +4 -3
  101. package/dist/capture/session-end-caller.js +2 -1
  102. package/dist/capture/session-worker.js +3 -4
  103. package/dist/capture/transcript.d.ts +2 -1
  104. package/dist/capture/transcript.js +6 -3
  105. package/dist/capture/working-state.d.ts +4 -2
  106. package/dist/capture/working-state.js +4 -2
  107. package/dist/cli/audit-prune.d.ts +0 -25
  108. package/dist/cli/audit-prune.js +1 -27
  109. package/dist/cli/audit.js +13 -13
  110. package/dist/cli/auth.d.ts +1 -1
  111. package/dist/cli/auth.js +12 -13
  112. package/dist/cli/briefs.d.ts +1 -4
  113. package/dist/cli/briefs.js +37 -292
  114. package/dist/cli/card.js +41 -33
  115. package/dist/cli/client.d.ts +5 -0
  116. package/dist/cli/client.js +24 -8
  117. package/dist/cli/compact-resume-payload.js +1 -1
  118. package/dist/cli/context.d.ts +1 -1
  119. package/dist/cli/context.js +12 -12
  120. package/dist/cli/continuity.d.ts +1 -1
  121. package/dist/cli/continuity.js +36 -39
  122. package/dist/cli/curate.d.ts +1 -1
  123. package/dist/cli/curate.js +23 -27
  124. package/dist/cli/dag.d.ts +1 -1
  125. package/dist/cli/dag.js +23 -8
  126. package/dist/cli/decisions.d.ts +0 -2
  127. package/dist/cli/decisions.js +4 -281
  128. package/dist/cli/eval.d.ts +1 -1
  129. package/dist/cli/eval.js +12 -13
  130. package/dist/cli/explain.d.ts +1 -1
  131. package/dist/cli/explain.js +21 -25
  132. package/dist/cli/flag-values.js +16 -6
  133. package/dist/cli/flags.d.ts +0 -289
  134. package/dist/cli/flags.js +3 -138
  135. package/dist/cli/graph.d.ts +3 -0
  136. package/dist/cli/graph.js +83 -0
  137. package/dist/cli/hook-runtime.d.ts +3 -5
  138. package/dist/cli/hook-runtime.js +7 -34
  139. package/dist/cli/incidents.d.ts +3 -0
  140. package/dist/cli/incidents.js +112 -0
  141. package/dist/cli/init.d.ts +1 -1
  142. package/dist/cli/init.js +28 -19
  143. package/dist/cli/install-steps.d.ts +2 -1
  144. package/dist/cli/install-steps.js +11 -3
  145. package/dist/cli/last-sleep.js +1 -1
  146. package/dist/cli/lenient-id.d.ts +2 -0
  147. package/dist/cli/lenient-id.js +13 -0
  148. package/dist/cli/maintenance.d.ts +3 -3
  149. package/dist/cli/maintenance.js +29 -30
  150. package/dist/cli/notes.d.ts +2 -0
  151. package/dist/cli/notes.js +41 -0
  152. package/dist/cli/open-browser.d.ts +14 -0
  153. package/dist/cli/open-browser.js +26 -0
  154. package/dist/cli/playbooks.d.ts +3 -4
  155. package/dist/cli/playbooks.js +126 -290
  156. package/dist/cli/predictions.d.ts +3 -0
  157. package/dist/cli/predictions.js +175 -0
  158. package/dist/cli/print.js +2 -1
  159. package/dist/cli/projects.js +30 -22
  160. package/dist/cli/quality-repair-once.d.ts +1 -1
  161. package/dist/cli/quality-repair-once.js +6 -5
  162. package/dist/cli/recall.js +13 -7
  163. package/dist/cli/refine-llm.js +17 -17
  164. package/dist/cli/remember.js +12 -12
  165. package/dist/cli/scheduler.js +2 -1
  166. package/dist/cli/serve.js +3 -3
  167. package/dist/cli/session-hooks.d.ts +1 -1
  168. package/dist/cli/session-hooks.js +45 -115
  169. package/dist/cli/setup.d.ts +1 -1
  170. package/dist/cli/setup.js +17 -10
  171. package/dist/cli/shared.d.ts +2 -6
  172. package/dist/cli/shared.js +9 -29
  173. package/dist/cli/sleep-render.js +6 -3
  174. package/dist/cli/sleep.js +6 -37
  175. package/dist/cli/status.d.ts +3 -3
  176. package/dist/cli/status.js +32 -35
  177. package/dist/cli/transfer.d.ts +1 -1
  178. package/dist/cli/transfer.js +33 -31
  179. package/dist/cli/usage.d.ts +0 -79
  180. package/dist/cli/usage.js +1 -695
  181. package/dist/cli/verb-row.d.ts +32 -0
  182. package/dist/cli/verb-row.js +6 -0
  183. package/dist/cli/verbs/health.d.ts +27 -0
  184. package/dist/cli/verbs/health.js +232 -0
  185. package/dist/cli/verbs/memory.d.ts +16 -0
  186. package/dist/cli/verbs/memory.js +244 -0
  187. package/dist/cli/verbs/objects.d.ts +20 -0
  188. package/dist/cli/verbs/objects.js +254 -0
  189. package/dist/cli/verbs/sessions.d.ts +31 -0
  190. package/dist/cli/verbs/sessions.js +312 -0
  191. package/dist/cli/verbs.d.ts +81 -0
  192. package/dist/cli/verbs.js +7 -0
  193. package/dist/cli/versioned-verbs.d.ts +51 -0
  194. package/dist/cli/versioned-verbs.js +79 -0
  195. package/dist/cli.d.ts +1 -272
  196. package/dist/cli.js +23 -313
  197. package/dist/connectors/dlq.d.ts +39 -3
  198. package/dist/connectors/dlq.js +37 -3
  199. package/dist/connectors/github/backfill.js +12 -3
  200. package/dist/connectors/github/dlq.js +31 -73
  201. package/dist/connectors/github/ingest.d.ts +2 -6
  202. package/dist/connectors/github/ingest.js +3 -28
  203. package/dist/connectors/github/webhook.d.ts +2 -1
  204. package/dist/connectors/github/webhook.js +33 -2
  205. package/dist/connectors/ingest.d.ts +10 -0
  206. package/dist/connectors/ingest.js +28 -0
  207. package/dist/connectors/slack/dlq.js +49 -71
  208. package/dist/connectors/slack/ingest.d.ts +2 -6
  209. package/dist/connectors/slack/ingest.js +2 -27
  210. package/dist/connectors/slack/webhook.d.ts +2 -1
  211. package/dist/connectors/slack/webhook.js +2 -1
  212. package/dist/consolidate/conflicts.js +1 -1
  213. package/dist/consolidate/dag.js +15 -9
  214. package/dist/consolidate/dedupe.d.ts +7 -0
  215. package/dist/consolidate/dedupe.js +5 -3
  216. package/dist/consolidate/llm-passes.js +45 -19
  217. package/dist/consolidate/memory-value.js +2 -1
  218. package/dist/consolidate/merge.js +2 -2
  219. package/dist/consolidate/physics-pass.d.ts +6 -1
  220. package/dist/consolidate/physics-pass.js +26 -6
  221. package/dist/consolidate/replay.js +11 -4
  222. package/dist/consolidate/sleep.js +8 -5
  223. package/dist/consolidate/traces.js +3 -3
  224. package/dist/core/ablation.d.ts +10 -0
  225. package/dist/core/ablation.js +12 -0
  226. package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
  227. package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
  228. package/dist/core/ambient.d.ts +4 -0
  229. package/dist/core/ambient.js +39 -18
  230. package/dist/core/api-errors.d.ts +16 -0
  231. package/dist/core/api-errors.js +20 -0
  232. package/dist/core/card.js +3 -1
  233. package/dist/core/compaction-timing.d.ts +7 -0
  234. package/dist/core/compaction-timing.js +9 -0
  235. package/dist/core/config.d.ts +1 -1
  236. package/dist/core/config.js +7 -2
  237. package/dist/core/cosine.d.ts +3 -0
  238. package/dist/core/cosine.js +19 -0
  239. package/dist/{store → core}/markdown.d.ts +1 -1
  240. package/dist/{store → core}/markdown.js +2 -2
  241. package/dist/core/memory-audit.d.ts +17 -0
  242. package/dist/core/memory-audit.js +54 -0
  243. package/dist/core/memory.d.ts +10 -4
  244. package/dist/core/memory.js +25 -18
  245. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  246. package/dist/{consolidate → core}/merged-row.js +1 -1
  247. package/dist/core/physics.js +6 -16
  248. package/dist/core/prediction.d.ts +3 -0
  249. package/dist/core/prediction.js +6 -0
  250. package/dist/core/project-identity.d.ts +3 -0
  251. package/dist/core/project-identity.js +10 -1
  252. package/dist/{store → core}/recall-scope.d.ts +1 -10
  253. package/dist/{store → core}/recall-scope.js +2 -19
  254. package/dist/db/busy.d.ts +2 -7
  255. package/dist/db/busy.js +21 -26
  256. package/dist/db/connect.d.ts +0 -1
  257. package/dist/db/connect.js +5 -6
  258. package/dist/db/index.d.ts +3 -3
  259. package/dist/db/index.js +3 -3
  260. package/dist/db/migrations/index.d.ts +1 -1
  261. package/dist/db/migrations/index.js +3 -1
  262. package/dist/db/migrations/v55.d.ts +3 -0
  263. package/dist/db/migrations/v55.js +17 -0
  264. package/dist/db/open.d.ts +0 -2
  265. package/dist/db/open.js +6 -10
  266. package/dist/db/physics-state.js +3 -3
  267. package/dist/db/tables.d.ts +2 -0
  268. package/dist/db/tables.js +6 -2
  269. package/dist/db/vector-store.js +17 -4
  270. package/dist/db/wal-checkpointer.js +2 -1
  271. package/dist/doctor.js +11 -8
  272. package/dist/embeddings/local.d.ts +62 -0
  273. package/dist/embeddings/local.js +146 -0
  274. package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
  275. package/dist/{store/embeddings → embeddings}/provider.js +18 -15
  276. package/dist/embeddings/transformers.d.ts +26 -0
  277. package/dist/embeddings/transformers.js +89 -0
  278. package/dist/entry/session-text.d.ts +1 -1
  279. package/dist/entry/session-text.js +1 -1
  280. package/dist/eval/eval-suite.js +17 -11
  281. package/dist/eval/eval.js +1 -1
  282. package/dist/eval/judgment.js +11 -4
  283. package/dist/graph/extract.js +3 -3
  284. package/dist/graph/recall.js +1 -1
  285. package/dist/graph/view.js +13 -5
  286. package/dist/graph/write.d.ts +1 -1
  287. package/dist/graph/write.js +9 -9
  288. package/dist/hooks/codex-session.js +3 -2
  289. package/dist/hooks/codex-wrapper.js +2 -1
  290. package/dist/hooks/json-hooks.js +4 -2
  291. package/dist/hooks/opencode.js +8 -5
  292. package/dist/hooks/shared.d.ts +0 -6
  293. package/dist/hooks/shared.js +4 -15
  294. package/dist/importers/core.js +1 -1
  295. package/dist/importers/sources.js +5 -4
  296. package/dist/importers/vault.js +7 -5
  297. package/dist/index.d.ts +3 -2
  298. package/dist/index.js +3 -2
  299. package/dist/learn/autolearn.d.ts +10 -2
  300. package/dist/learn/autolearn.js +32 -12
  301. package/dist/learn/churn-git.js +13 -4
  302. package/dist/learn/extract.d.ts +3 -2
  303. package/dist/learn/extract.js +6 -4
  304. package/dist/learn/forward-claim-detector.js +4 -2
  305. package/dist/learn/invalidation.js +10 -6
  306. package/dist/mcp/admin-tools.d.ts +2 -2
  307. package/dist/mcp/admin-tools.js +27 -48
  308. package/dist/mcp/format.js +3 -2
  309. package/dist/mcp/framing.d.ts +1 -0
  310. package/dist/mcp/framing.js +1 -1
  311. package/dist/mcp/memory-tools.js +3 -1
  312. package/dist/mcp/protocol.d.ts +11 -7
  313. package/dist/mcp/protocol.js +25 -12
  314. package/dist/mcp/recall-tools.js +12 -9
  315. package/dist/mcp/request.js +2 -1
  316. package/dist/mcp/stdio.js +24 -8
  317. package/dist/mcp/tool-args.js +2 -1
  318. package/dist/mcp/tools.js +44 -21
  319. package/dist/objects/customer-notes.d.ts +2 -2
  320. package/dist/objects/decisions.d.ts +2 -2
  321. package/dist/objects/descriptor.d.ts +1 -1
  322. package/dist/objects/incidents.d.ts +2 -2
  323. package/dist/objects/lifecycle.d.ts +1 -1
  324. package/dist/objects/lifecycle.js +2 -1
  325. package/dist/objects/policies.d.ts +2 -2
  326. package/dist/objects/policies.js +2 -1
  327. package/dist/objects/processes.d.ts +2 -2
  328. package/dist/objects/project-briefs.d.ts +2 -2
  329. package/dist/objects/project-briefs.js +2 -3
  330. package/dist/objects/skills.d.ts +2 -2
  331. package/dist/postinstall.js +1 -1
  332. package/dist/rerankers/clef.js +3 -6
  333. package/dist/rerankers/cross-encoder.d.ts +31 -2
  334. package/dist/rerankers/cross-encoder.js +63 -97
  335. package/dist/rerankers/index.js +5 -4
  336. package/dist/rerankers/jev.js +2 -4
  337. package/dist/rerankers/outage-warning.d.ts +3 -1
  338. package/dist/rerankers/outage-warning.js +5 -3
  339. package/dist/search/bm25-search.js +1 -1
  340. package/dist/search/boosts.js +1 -1
  341. package/dist/search/embed-memories.d.ts +9 -0
  342. package/dist/search/embed-memories.js +377 -0
  343. package/dist/search/goal-boost.d.ts +1 -1
  344. package/dist/search/goal-boost.js +6 -3
  345. package/dist/search/hybrid.d.ts +9 -2
  346. package/dist/search/hybrid.js +9 -4
  347. package/dist/search/physics-search.d.ts +6 -3
  348. package/dist/search/physics-search.js +22 -15
  349. package/dist/search/rerank.js +1 -1
  350. package/dist/search/vector.d.ts +8 -6
  351. package/dist/search/vector.js +10 -13
  352. package/dist/server/auth.d.ts +2 -0
  353. package/dist/server/auth.js +17 -7
  354. package/dist/server/boot.js +7 -66
  355. package/dist/server/client-ip.d.ts +0 -2
  356. package/dist/server/client-ip.js +3 -2
  357. package/dist/server/deadline.d.ts +0 -2
  358. package/dist/server/deadline.js +1 -7
  359. package/dist/server/defaults.d.ts +1 -0
  360. package/dist/server/defaults.js +1 -0
  361. package/dist/server/mcp-http.js +16 -11
  362. package/dist/server/request.js +7 -2
  363. package/dist/server/route-checks.d.ts +7 -0
  364. package/dist/server/route-checks.js +42 -0
  365. package/dist/server/route-table.d.ts +9 -8
  366. package/dist/server/route-table.js +127 -132
  367. package/dist/server/routes/admin.d.ts +8 -8
  368. package/dist/server/routes/admin.js +13 -21
  369. package/dist/server/routes/customer-notes.d.ts +6 -6
  370. package/dist/server/routes/customer-notes.js +1 -2
  371. package/dist/server/routes/decisions.d.ts +6 -6
  372. package/dist/server/routes/decisions.js +2 -4
  373. package/dist/server/routes/incidents.d.ts +6 -6
  374. package/dist/server/routes/incidents.js +2 -5
  375. package/dist/server/routes/memories.d.ts +9 -9
  376. package/dist/server/routes/memories.js +15 -38
  377. package/dist/server/routes/object-routes.d.ts +6 -6
  378. package/dist/server/routes/object-routes.js +4 -7
  379. package/dist/server/routes/policies.d.ts +7 -7
  380. package/dist/server/routes/policies.js +2 -4
  381. package/dist/server/routes/predictions.d.ts +6 -6
  382. package/dist/server/routes/predictions.js +9 -13
  383. package/dist/server/routes/processes.d.ts +6 -6
  384. package/dist/server/routes/processes.js +1 -2
  385. package/dist/server/routes/project-briefs.d.ts +7 -7
  386. package/dist/server/routes/project-briefs.js +2 -4
  387. package/dist/server/routes/recall.d.ts +5 -5
  388. package/dist/server/routes/recall.js +6 -10
  389. package/dist/server/routes/skills.d.ts +7 -7
  390. package/dist/server/routes/skills.js +2 -4
  391. package/dist/server/server-detect.d.ts +7 -1
  392. package/dist/server/server-detect.js +36 -11
  393. package/dist/server/sleep-child.js +26 -7
  394. package/dist/server/sleep-offload.d.ts +11 -5
  395. package/dist/server/sleep-offload.js +17 -11
  396. package/dist/server/types.d.ts +22 -10
  397. package/dist/server/validation.d.ts +1 -2
  398. package/dist/server/validation.js +6 -11
  399. package/dist/server.d.ts +5 -4
  400. package/dist/server.js +5 -4
  401. package/dist/sharing/global-store.js +2 -2
  402. package/dist/sharing/global-sync.js +38 -45
  403. package/dist/sharing/project-merge.d.ts +7 -14
  404. package/dist/sharing/project-merge.js +57 -121
  405. package/dist/sharing/search-both.js +1 -1
  406. package/dist/sharing/share.d.ts +2 -0
  407. package/dist/sharing/share.js +37 -34
  408. package/dist/store/ambient.js +5 -6
  409. package/dist/store/audit-event.d.ts +1 -1
  410. package/dist/store/audit.d.ts +0 -16
  411. package/dist/store/audit.js +4 -55
  412. package/dist/store/auth.d.ts +4 -2
  413. package/dist/store/auth.js +7 -3
  414. package/dist/store/candidates.d.ts +3 -2
  415. package/dist/store/candidates.js +42 -23
  416. package/dist/store/capture-write.d.ts +17 -0
  417. package/dist/store/capture-write.js +35 -0
  418. package/dist/store/cards.js +1 -1
  419. package/dist/store/compaction-caller.d.ts +18 -0
  420. package/dist/store/compaction-caller.js +29 -0
  421. package/dist/store/compactions-record.d.ts +115 -0
  422. package/dist/store/compactions-record.js +417 -0
  423. package/dist/store/compactions.js +6 -4
  424. package/dist/store/conflicts.js +7 -4
  425. package/dist/store/connectors/dlq.d.ts +10 -0
  426. package/dist/store/connectors/dlq.js +32 -0
  427. package/dist/store/connectors/github.d.ts +7 -9
  428. package/dist/store/connectors/github.js +30 -53
  429. package/dist/store/connectors/slack.d.ts +2 -11
  430. package/dist/store/connectors/slack.js +18 -47
  431. package/dist/store/dashboard-reads.js +7 -6
  432. package/dist/store/delete-and-batch.d.ts +6 -0
  433. package/dist/store/delete-and-batch.js +36 -3
  434. package/dist/store/delivery-recorder.d.ts +10 -3
  435. package/dist/store/delivery-recorder.js +12 -5
  436. package/dist/store/descendant-page.js +6 -3
  437. package/dist/store/dormant.d.ts +1 -1
  438. package/dist/store/dormant.js +3 -1
  439. package/dist/store/embeddings/index.d.ts +2 -12
  440. package/dist/store/embeddings/index.js +5 -374
  441. package/dist/store/entry-reads.d.ts +13 -4
  442. package/dist/store/entry-reads.js +47 -11
  443. package/dist/store/entry-writes.d.ts +5 -5
  444. package/dist/store/entry-writes.js +32 -12
  445. package/dist/store/failure-log-at.d.ts +8 -0
  446. package/dist/store/failure-log-at.js +16 -0
  447. package/dist/store/failure-log.d.ts +2 -2
  448. package/dist/store/failure-log.js +5 -3
  449. package/dist/{trust → store}/gated-write.d.ts +3 -1
  450. package/dist/{trust → store}/gated-write.js +7 -5
  451. package/dist/store/goals.js +20 -18
  452. package/dist/store/graph-reads.js +4 -2
  453. package/dist/store/graph-writes.d.ts +6 -6
  454. package/dist/store/graph-writes.js +48 -71
  455. package/dist/store/handoffs.d.ts +1 -1
  456. package/dist/store/handoffs.js +6 -6
  457. package/dist/store/index-and-stats.js +2 -2
  458. package/dist/store/key-writes.js +1 -1
  459. package/dist/store/ledger-turn.d.ts +9 -0
  460. package/dist/store/ledger-turn.js +38 -0
  461. package/dist/store/mirrors.js +10 -6
  462. package/dist/store/open.d.ts +0 -4
  463. package/dist/store/open.js +40 -53
  464. package/dist/store/pilot-arm.d.ts +12 -0
  465. package/dist/store/pilot-arm.js +42 -0
  466. package/dist/store/port.d.ts +9 -3
  467. package/dist/store/port.js +8 -0
  468. package/dist/store/predictions.d.ts +1 -2
  469. package/dist/store/predictions.js +3 -6
  470. package/dist/store/project-tags.d.ts +62 -0
  471. package/dist/store/project-tags.js +67 -0
  472. package/dist/store/quarantine.js +2 -1
  473. package/dist/store/recall-trace.d.ts +2 -0
  474. package/dist/store/recall-trace.js +18 -2
  475. package/dist/store/rejected-values.js +2 -1
  476. package/dist/store/rejection-probe.d.ts +4 -0
  477. package/dist/store/rejection-probe.js +19 -0
  478. package/dist/store/rejection.d.ts +0 -17
  479. package/dist/store/rejection.js +1 -21
  480. package/dist/store/rule-sql.d.ts +9 -0
  481. package/dist/store/rule-sql.js +21 -2
  482. package/dist/store/search-rows.js +9 -4
  483. package/dist/store/sessions.js +4 -2
  484. package/dist/store/set-aside.d.ts +14 -0
  485. package/dist/store/set-aside.js +23 -0
  486. package/dist/store/sqlite/busy.d.ts +3 -0
  487. package/dist/store/sqlite/busy.js +8 -0
  488. package/dist/store/sqlite/connector-events-group.js +4 -7
  489. package/dist/store/sqlite/connector-writes-group.js +3 -3
  490. package/dist/store/sqlite/entry-writes-group.js +2 -2
  491. package/dist/store/sqlite/error-codec.js +4 -3
  492. package/dist/store/sqlite/executor.js +10 -4
  493. package/dist/store/sqlite/graph-reads-group.js +1 -1
  494. package/dist/store/sqlite/held-connection.d.ts +9 -0
  495. package/dist/store/sqlite/held-connection.js +41 -0
  496. package/dist/store/sqlite/object-rows.d.ts +1 -1
  497. package/dist/store/sqlite/objects-group.d.ts +1 -1
  498. package/dist/store/sqlite/objects-group.js +1 -1
  499. package/dist/store/sqlite/store.js +14 -12
  500. package/dist/store/summaries.d.ts +3 -3
  501. package/dist/store/summaries.js +5 -4
  502. package/dist/store/token-ledger.d.ts +0 -7
  503. package/dist/store/token-ledger.js +0 -35
  504. package/dist/store/vector-index.js +3 -2
  505. package/dist/support-bundle.js +2 -3
  506. package/dist/trust/reject-flow.js +2 -2
  507. package/dist/util/agent-homes.d.ts +15 -0
  508. package/dist/util/agent-homes.js +34 -0
  509. package/dist/util/anthropic-messages.d.ts +3 -0
  510. package/dist/util/anthropic-messages.js +22 -5
  511. package/dist/util/chunked.d.ts +3 -0
  512. package/dist/util/chunked.js +10 -0
  513. package/dist/util/ellipsize.d.ts +3 -0
  514. package/dist/util/ellipsize.js +5 -0
  515. package/dist/util/env.d.ts +2 -1
  516. package/dist/util/env.js +2 -1
  517. package/dist/util/format.d.ts +3 -0
  518. package/dist/util/format.js +6 -0
  519. package/dist/util/hook-payload.d.ts +8 -0
  520. package/dist/util/hook-payload.js +37 -0
  521. package/dist/util/http-retry.d.ts +6 -0
  522. package/dist/util/http-retry.js +43 -5
  523. package/dist/util/http-util.d.ts +0 -8
  524. package/dist/util/http-util.js +10 -21
  525. package/dist/util/limits.d.ts +7 -0
  526. package/dist/util/limits.js +14 -0
  527. package/dist/util/log.d.ts +4 -0
  528. package/dist/util/log.js +9 -0
  529. package/dist/util/request-scope.d.ts +3 -1
  530. package/dist/util/request-scope.js +11 -6
  531. package/dist/util/secret-detect.js +6 -1
  532. package/dist/util/sqlite-blocked.d.ts +2 -0
  533. package/dist/util/sqlite-blocked.js +5 -0
  534. package/dist/util/stream-tee.d.ts +3 -0
  535. package/dist/util/stream-tee.js +35 -0
  536. package/dist/util/time.d.ts +4 -0
  537. package/dist/util/time.js +4 -0
  538. package/dist/util/version.d.ts +1 -1
  539. package/dist/util/version.js +1 -1
  540. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  541. package/extensions/openclaw-plugin/package.json +1 -1
  542. package/openclaw.plugin.json +1 -1
  543. package/package.json +2 -2
  544. package/dist/store/embeddings/local.d.ts +0 -15
  545. package/dist/store/embeddings/local.js +0 -175
  546. /package/dist/{cli → api}/correction-latency.d.ts +0 -0
  547. /package/dist/{cli → api}/correction-latency.js +0 -0
  548. /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
  549. /package/dist/{cli → api}/provenance-coverage.js +0 -0
  550. /package/dist/{store → core}/object-types.d.ts +0 -0
  551. /package/dist/{store → core}/object-types.js +0 -0
  552. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  553. /package/dist/{capture → util}/compaction-items.js +0 -0
  554. /package/dist/{store → util}/yaml.d.ts +0 -0
  555. /package/dist/{store → util}/yaml.js +0 -0
@@ -2,31 +2,31 @@
2
2
  import { withWriteScope } from '../../db/index.js';
3
3
  import { archiveRawMemory } from '../raw-archive.js';
4
4
  import { onHandle } from '../open.js';
5
- export function eventSeenAt(db, idempotencyKey) {
5
+ import { getDlqRow, insertDlqRow, listDlqRows, markDlqRetried } from './dlq.js';
6
+ export function githubEventSeenAt(db, idempotencyKey) {
6
7
  const row = db.prepare(`SELECT 1 FROM github_event_log WHERE idempotency_key = ?`).get(idempotencyKey);
7
8
  return !!row;
8
9
  }
9
- export function eventMemoryAt(db, idempotencyKey) {
10
+ export function githubEventMemoryAt(db, idempotencyKey) {
10
11
  // SAFETY: the SELECT projects exactly the memory_id column of github_event_log.
11
12
  const row = db.prepare(`SELECT memory_id FROM github_event_log WHERE idempotency_key = ?`).get(idempotencyKey);
12
13
  return row?.memory_id ?? null;
13
14
  }
14
15
  /** False when the key was already logged, so a caller inside a write scope can roll its own row back. */
15
- export function logEventAt(db, entry) {
16
+ export function markGitHubEventSeenAt(db, entry) {
16
17
  const inserted = db.prepare(`INSERT OR IGNORE INTO github_event_log (idempotency_key, delivery_id, event_name, ingested_at, memory_id) VALUES (?, ?, ?, ?, ?)`).run(entry.idempotencyKey, entry.deliveryId, entry.eventName, new Date().toISOString(), entry.memoryId);
17
18
  return Number(inserted.changes ?? 0) !== 0;
18
19
  }
19
- /** The memory an already-seen key points at, or null when the key is new. */
20
- export function seenEvent(hippoRoot, idempotencyKey) {
21
- return onHandle(hippoRoot, (db) => eventSeenAt(db, idempotencyKey) ? { memoryId: eventMemoryAt(db, idempotencyKey) } : null);
20
+ export function githubEventRecord(hippoRoot, idempotencyKey) {
21
+ return onHandle(hippoRoot, (db) => githubEventSeenAt(db, idempotencyKey) ? { seen: true, memoryId: githubEventMemoryAt(db, idempotencyKey) } : { seen: false });
22
22
  }
23
- export function logEvent(hippoRoot, entry) {
24
- onHandle(hippoRoot, (db) => { logEventAt(db, entry); });
23
+ export function markGitHubEventSeen(hippoRoot, entry) {
24
+ onHandle(hippoRoot, (db) => { markGitHubEventSeenAt(db, entry); });
25
25
  }
26
26
  /** Archives every active raw row of one tenant's artifact and logs the delete event; a failed archive rolls back the batch and the log row. */
27
27
  export function archiveDeletedArtifact(hippoRoot, del) {
28
28
  return onHandle(hippoRoot, (db) => {
29
- if (eventSeenAt(db, del.idempotencyKey))
29
+ if (githubEventSeenAt(db, del.idempotencyKey))
30
30
  return { duplicate: true, archived: 0 };
31
31
  const logged = { idempotencyKey: del.idempotencyKey, deliveryId: del.deliveryId, eventName: del.eventName };
32
32
  // SAFETY: the SELECT projects only the `id` column.
@@ -36,29 +36,17 @@ export function archiveDeletedArtifact(hippoRoot, del) {
36
36
  const memoryIds = rows.map((r) => r.id);
37
37
  if (memoryIds.length === 0) {
38
38
  // Still logged, so a retry of the same delete answers 'duplicate'.
39
- logEventAt(db, { ...logged, memoryId: null });
39
+ markGitHubEventSeenAt(db, { ...logged, memoryId: null });
40
40
  return { duplicate: false, archived: 0 };
41
41
  }
42
42
  withWriteScope(db, 'github_delete_all', () => {
43
43
  for (const id of memoryIds)
44
44
  archiveRawMemory(db, id, { reason: del.reason, who: del.who });
45
- logEventAt(db, { ...logged, memoryId: memoryIds[0] });
45
+ markGitHubEventSeenAt(db, { ...logged, memoryId: memoryIds[0] });
46
46
  });
47
47
  return { duplicate: false, archived: memoryIds.length };
48
48
  });
49
49
  }
50
- function insertGitHubDlqAt(db, row) {
51
- const result = db
52
- .prepare(`INSERT INTO github_dlq
53
- (tenant_id, raw_payload, error, event_name, delivery_id, signature,
54
- installation_id, repo_full_name, received_at, bucket)
55
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
56
- .run(row.tenantId, row.rawPayload, row.error, row.eventName ?? null, row.deliveryId ?? null, row.signature, row.installationId ?? null, row.repoFullName ?? null, new Date().toISOString(), row.bucket);
57
- return Number(result.lastInsertRowid);
58
- }
59
- export function insertGitHubDlq(hippoRoot, row) {
60
- return onHandle(hippoRoot, (db) => insertGitHubDlqAt(db, row));
61
- }
62
50
  const SELECT_COLUMNS = `id, tenant_id, raw_payload, error, event_name, delivery_id,
63
51
  signature, installation_id, repo_full_name, retry_count,
64
52
  received_at, retried_at, bucket`;
@@ -79,42 +67,31 @@ function rowToItem(r) {
79
67
  bucket: r.bucket == null ? 'parse_error' : String(r.bucket),
80
68
  };
81
69
  }
82
- function listGitHubDlqAt(db, tenantId, limit) {
83
- // SAFETY: SELECT_COLUMNS projects exactly DlqRawRow's fields.
84
- const rows = db
85
- .prepare(`SELECT ${SELECT_COLUMNS}
86
- FROM github_dlq
87
- WHERE tenant_id = ?
88
- ORDER BY received_at ASC
89
- LIMIT ?`)
90
- .all(tenantId, limit);
91
- return rows.map(rowToItem);
70
+ export function insertGitHubDlq(hippoRoot, row) {
71
+ return onHandle(hippoRoot, (db) => insertDlqRow(db, 'github_dlq', [
72
+ ['tenant_id', row.tenantId],
73
+ ['raw_payload', row.rawPayload],
74
+ ['error', row.error],
75
+ ['event_name', row.eventName ?? null],
76
+ ['delivery_id', row.deliveryId ?? null],
77
+ ['signature', row.signature],
78
+ ['installation_id', row.installationId ?? null],
79
+ ['repo_full_name', row.repoFullName ?? null],
80
+ ['bucket', row.bucket],
81
+ ]));
92
82
  }
93
83
  export function listGitHubDlq(hippoRoot, tenantId, limit) {
94
- return onHandle(hippoRoot, (db) => listGitHubDlqAt(db, tenantId, limit));
95
- }
96
- function githubDlqEntryAt(db, id) {
97
- // SAFETY: SELECT_COLUMNS projects exactly DlqRawRow's fields.
98
- const row = db
99
- .prepare(`SELECT ${SELECT_COLUMNS}
100
- FROM github_dlq
101
- WHERE id = ?`)
102
- .get(id);
103
- if (!row)
104
- return null;
105
- return rowToItem(row);
84
+ return onHandle(hippoRoot, (db) => listDlqRows(db, 'github_dlq', SELECT_COLUMNS, tenantId, limit).map(rowToItem));
106
85
  }
107
86
  export function githubDlqEntry(hippoRoot, id) {
108
- return onHandle(hippoRoot, (db) => githubDlqEntryAt(db, id));
109
- }
110
- export function bumpGitHubDlqRetryCount(hippoRoot, id) {
111
- onHandle(hippoRoot, (db) => {
112
- db.prepare(`UPDATE github_dlq
113
- SET retry_count = retry_count + 1,
114
- retried_at = ?
115
- WHERE id = ?`).run(new Date().toISOString(), id);
87
+ return onHandle(hippoRoot, (db) => {
88
+ const row = getDlqRow(db, 'github_dlq', SELECT_COLUMNS, id);
89
+ return row ? rowToItem(row) : null;
116
90
  });
117
91
  }
92
+ export function markGitHubDlqRetried(hippoRoot, id) {
93
+ onHandle(hippoRoot, (db) => markDlqRetried(db, 'github_dlq', id));
94
+ }
118
95
  export function githubRouting(hippoRoot, args) {
119
96
  return onHandle(hippoRoot, (db) => {
120
97
  // SAFETY: the SELECT projects exactly one column, `c`, as a COUNT(*).
@@ -1,4 +1,5 @@
1
1
  import type { DatabaseSyncLike } from '../../db/index.js';
2
+ import type { ConnectorEventRecord } from '../port.js';
2
3
  export declare function slackCursorAt(db: DatabaseSyncLike, tenantId: string, channelId: string): string | null;
3
4
  export declare function saveSlackCursorAt(db: DatabaseSyncLike, tenantId: string, channelId: string, latestTs: string): void;
4
5
  export declare function slackCursor(hippoRoot: string, tenantId: string, channelId: string): string | null;
@@ -7,14 +8,7 @@ export declare function slackEventSeenAt(db: DatabaseSyncLike, eventId: string):
7
8
  /** Records the event unless a row already holds its id; false means another writer got there first. */
8
9
  export declare function markSlackEventSeenAt(db: DatabaseSyncLike, eventId: string, memoryId: string | null): boolean;
9
10
  export declare function slackEventMemoryAt(db: DatabaseSyncLike, eventId: string): string | null;
10
- /** What the event log holds for one event id; `memoryId` is null for an event seen without a memory. */
11
- export type SlackEventRecord = {
12
- seen: false;
13
- } | {
14
- seen: true;
15
- memoryId: string | null;
16
- };
17
- export declare function slackEventRecord(hippoRoot: string, eventId: string): SlackEventRecord;
11
+ export declare function slackEventRecord(hippoRoot: string, eventId: string): ConnectorEventRecord;
18
12
  export declare function markSlackEventSeen(hippoRoot: string, eventId: string, memoryId: string | null): void;
19
13
  /** The raw memory a Slack message became. The tenant filter keeps one tenant's deletion from reaching another's row with the same ref. */
20
14
  export declare function rawMemoryIdForArtifactAt(db: DatabaseSyncLike, artifactRef: string, tenantId: string): string | null;
@@ -42,13 +36,10 @@ export interface SlackDlqInsert {
42
36
  signature: string | null;
43
37
  slackTimestamp?: string | null;
44
38
  }
45
- /** Counts a failed replay and leaves `retried_at` alone, so the row still reads as never drained. */
46
- export declare function bumpSlackDlqRetryCountAt(db: DatabaseSyncLike, id: number): void;
47
39
  export declare function insertSlackDlq(hippoRoot: string, row: SlackDlqInsert): number;
48
40
  export declare function listSlackDlq(hippoRoot: string, tenantId: string, limit: number): DlqItem[];
49
41
  export declare function slackDlqEntry(hippoRoot: string, id: number): DlqItem | null;
50
42
  export declare function markSlackDlqRetried(hippoRoot: string, id: number): void;
51
- export declare function bumpSlackDlqRetryCount(hippoRoot: string, id: number): void;
52
43
  /** The tenant a team maps to, or how many workspaces are registered when it maps to none. */
53
44
  export type SlackTeamRoute = {
54
45
  tenantId: string;
@@ -1,6 +1,7 @@
1
1
  // Every statement the Slack connector runs on hippo.db: backfill cursors, the event log, the dead-letter queue and workspace routing.
2
2
  // `xAt(db, ...)` runs on the caller's handle; the same name without `At` opens hippo.db for that one call.
3
3
  import { onHandle } from '../open.js';
4
+ import { getDlqRow, insertDlqRow, listDlqRows, markDlqRetried } from './dlq.js';
4
5
  // Backfill cursors
5
6
  export function slackCursorAt(db, tenantId, channelId) {
6
7
  // SAFETY: the SELECT names the single `latest_ts` column; sqlite returns undefined when no row matches.
@@ -51,6 +52,8 @@ export function rawMemoryIdForArtifactAt(db, artifactRef, tenantId) {
51
52
  .get(artifactRef, tenantId);
52
53
  return row?.id ?? null;
53
54
  }
55
+ const SELECT_COLUMNS = `id, tenant_id, team_id, raw_payload, error, received_at, retried_at,
56
+ bucket, retry_count, signature, slack_timestamp`;
54
57
  function rowToItem(r) {
55
58
  return {
56
59
  id: Number(r.id),
@@ -66,60 +69,28 @@ function rowToItem(r) {
66
69
  slackTimestamp: r.slack_timestamp == null ? null : String(r.slack_timestamp),
67
70
  };
68
71
  }
69
- function insertSlackDlqAt(db, row) {
70
- const result = db
71
- .prepare(`INSERT INTO slack_dlq
72
- (tenant_id, team_id, raw_payload, error, received_at, bucket, signature, slack_timestamp)
73
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
74
- .run(row.tenantId, row.teamId ?? null, row.rawPayload, row.error, new Date().toISOString(), row.bucket, row.signature, row.slackTimestamp ?? null);
75
- return Number(result.lastInsertRowid);
76
- }
77
- function listSlackDlqAt(db, tenantId, limit) {
78
- // SAFETY: row shape matches the columns named in the SELECT below.
79
- const rows = db
80
- .prepare(`SELECT id, tenant_id, team_id, raw_payload, error, received_at, retried_at,
81
- bucket, retry_count, signature, slack_timestamp
82
- FROM slack_dlq
83
- WHERE tenant_id = ?
84
- ORDER BY received_at ASC
85
- LIMIT ?`)
86
- .all(tenantId, limit);
87
- return rows.map(rowToItem);
88
- }
89
- function slackDlqEntryAt(db, id) {
90
- // SAFETY: row shape matches the columns named in the SELECT below.
91
- const row = db
92
- .prepare(`SELECT id, tenant_id, team_id, raw_payload, error, received_at, retried_at,
93
- bucket, retry_count, signature, slack_timestamp
94
- FROM slack_dlq
95
- WHERE id = ?`)
96
- .get(id);
97
- if (!row)
98
- return null;
99
- return rowToItem(row);
100
- }
101
- function markSlackDlqRetriedAt(db, id) {
102
- db.prepare(`UPDATE slack_dlq SET retried_at = ?, retry_count = retry_count + 1 WHERE id = ?`)
103
- .run(new Date().toISOString(), id);
104
- }
105
- /** Counts a failed replay and leaves `retried_at` alone, so the row still reads as never drained. */
106
- export function bumpSlackDlqRetryCountAt(db, id) {
107
- db.prepare(`UPDATE slack_dlq SET retry_count = retry_count + 1 WHERE id = ?`).run(id);
108
- }
109
72
  export function insertSlackDlq(hippoRoot, row) {
110
- return onHandle(hippoRoot, (db) => insertSlackDlqAt(db, row));
73
+ return onHandle(hippoRoot, (db) => insertDlqRow(db, 'slack_dlq', [
74
+ ['tenant_id', row.tenantId],
75
+ ['team_id', row.teamId ?? null],
76
+ ['raw_payload', row.rawPayload],
77
+ ['error', row.error],
78
+ ['bucket', row.bucket],
79
+ ['signature', row.signature],
80
+ ['slack_timestamp', row.slackTimestamp ?? null],
81
+ ]));
111
82
  }
112
83
  export function listSlackDlq(hippoRoot, tenantId, limit) {
113
- return onHandle(hippoRoot, (db) => listSlackDlqAt(db, tenantId, limit));
84
+ return onHandle(hippoRoot, (db) => listDlqRows(db, 'slack_dlq', SELECT_COLUMNS, tenantId, limit).map(rowToItem));
114
85
  }
115
86
  export function slackDlqEntry(hippoRoot, id) {
116
- return onHandle(hippoRoot, (db) => slackDlqEntryAt(db, id));
87
+ return onHandle(hippoRoot, (db) => {
88
+ const row = getDlqRow(db, 'slack_dlq', SELECT_COLUMNS, id);
89
+ return row ? rowToItem(row) : null;
90
+ });
117
91
  }
118
92
  export function markSlackDlqRetried(hippoRoot, id) {
119
- onHandle(hippoRoot, (db) => markSlackDlqRetriedAt(db, id));
120
- }
121
- export function bumpSlackDlqRetryCount(hippoRoot, id) {
122
- onHandle(hippoRoot, (db) => bumpSlackDlqRetryCountAt(db, id));
93
+ onHandle(hippoRoot, (db) => markDlqRetried(db, 'slack_dlq', id));
123
94
  }
124
95
  export function slackTeamRouteAt(db, teamId) {
125
96
  // SAFETY: the SELECT names only `tenant_id`; .get() returns undefined when no row matches.
@@ -8,7 +8,8 @@ import { storedVectorIds } from '../db/vector-store.js';
8
8
  import { onHandle, openStore } from './open.js';
9
9
  import { QUARANTINE_SCOPE_PREFIX } from './quarantine.js';
10
10
  import { parseJsonArray } from './rows.js';
11
- const LIVE_COLUMNS = 'id, created, last_retrieved, retrieval_count, half_life_days, layer, tags_json, emotional_valence, outcome_positive, outcome_negative, pinned, confidence, content, superseded_by, kind, scope, origin_project';
11
+ const LIVE_COLUMNS = 'id, created, last_retrieved, retrieval_count, half_life_days, layer, tags_json, emotional_valence, outcome_positive, ' +
12
+ 'outcome_negative, pinned, confidence, content, superseded_by, kind, scope, origin_project';
12
13
  // SQL twins of isQuarantineScope and of the two halves of isLiveMemory; substr compares bytes, as startsWith does, where LIKE would fold case.
13
14
  const QUARANTINED = `(scope IS NOT NULL AND substr(scope, 1, ${QUARANTINE_SCOPE_PREFIX.length}) = '${QUARANTINE_SCOPE_PREFIX}')`;
14
15
  const SUPERSEDED_BY = `(superseded_by IS NOT NULL AND superseded_by <> '')`;
@@ -44,11 +45,11 @@ export function loadDashboardRows(hippoRoot, tenantId) {
44
45
  // SAFETY: the SELECT names exactly LiveRow's columns.
45
46
  const live = db.prepare(`SELECT ${LIVE_COLUMNS} FROM memories WHERE tenant_id = ? AND ${LIVE} ORDER BY created ASC, id ASC`).all(tenantId);
46
47
  // SAFETY: the SELECT names exactly these two fields, and `why` is one of the three CASE arms or NULL.
47
- const counts = db.prepare(`
48
- SELECT CASE WHEN ${QUARANTINED} THEN 'quarantined' WHEN ${SUPERSEDED_BY} OR ${KIND} = 'superseded' THEN 'superseded' WHEN ${KIND} = 'archived' THEN 'archived' END AS why,
49
- COUNT(*) AS n
50
- FROM memories WHERE tenant_id = ? AND NOT (${LIVE}) GROUP BY why
51
- `).all(tenantId);
48
+ const counts = db.prepare(`\n SELECT CASE WHEN ${QUARANTINED} THEN 'quarantined' ` +
49
+ `WHEN ${SUPERSEDED_BY} OR ${KIND} = 'superseded' THEN 'superseded' ` +
50
+ `WHEN ${KIND} = 'archived' THEN 'archived' END AS why,\n` +
51
+ ` COUNT(*) AS n\n` +
52
+ ` FROM memories WHERE tenant_id = ? AND NOT (${LIVE}) GROUP BY why\n `).all(tenantId);
52
53
  const excluded = { superseded: 0, archived: 0, quarantined: 0 };
53
54
  for (const { why, n } of counts)
54
55
  if (why !== null)
@@ -26,6 +26,12 @@ export declare function deleteEntry(hippoRoot: string, id: string, opts?: {
26
26
  reason?: string;
27
27
  automatic?: boolean;
28
28
  }): boolean;
29
+ /** deleteEntry with `automatic` for each removal and its own forget row and reason, all in one transaction after one read of the id set.
30
+ * Returns the ids deleted, in `removals` order; a missing, repeated, pinned, raw or object-backing id is left out. */
31
+ export declare function deleteEntriesAutomatically(hippoRoot: string, removals: readonly {
32
+ id: string;
33
+ reason: string;
34
+ }[], actor: string): string[];
29
35
  /** Each row as the caller loaded it, by id; a `ReadonlyMap` fits. */
30
36
  export type LoadedRows = Pick<ReadonlyMap<string, MemoryEntry>, 'get'>;
31
37
  /** Writes, deletes and dormant moves in one transaction. With `snapshot`, a write keeps only the fields the caller changed and never resurrects a gone row.
@@ -2,7 +2,8 @@ import { DEFAULT_TENANT_ID } from '../util/env.js';
2
2
  import { RawAppendOnlyError } from '../core/raw-append-only.js';
3
3
  import { AUTO_DELETABLE_SQL } from './rule-sql.js';
4
4
  import { closeHippoDb, withWriteScope } from '../db/index.js';
5
- import { checkRejectionGuard, RejectedValueError } from './rejection.js';
5
+ import { checkRejectionGuard } from './rejection.js';
6
+ import { RejectedValueError } from '../core/api-errors.js';
6
7
  import { markSummaryDirtyInTx } from './summary-dirty.js';
7
8
  import { insertDormantRow } from './dormant.js';
8
9
  import { log } from '../util/log.js';
@@ -12,6 +13,7 @@ import { deleteFtsRow, replaceFtsRows, stampOriginProject, upsertMemoryRow } fro
12
13
  import { purgeMirrorBestEffort, mirrorBestEffort, writeMarkdownMirror } from './mirrors.js';
13
14
  import { onHandle, openStore } from './open.js';
14
15
  import { clock } from '../util/write-budget.js';
16
+ import { chunked } from '../util/chunked.js';
15
17
  /** Tables whose rows keep a first-class object's backing memory in `memory_id` (ON DELETE SET NULL); tests/dormant-memories.test.ts pins it to the schema. */
16
18
  export const MEMORY_BACKED_TABLES = ['predictions', 'decisions', 'incidents', 'processes', 'policies', 'skills', 'project_briefs', 'customer_notes'];
17
19
  /** Deleting a memory that backs an object nulls the object's link, and no restore can repair it, so no automatic pass may. */
@@ -61,8 +63,10 @@ export function deleteEntryCore(db, id, opts) {
61
63
  const row = db
62
64
  .prepare(`SELECT id, tenant_id, dag_parent_id FROM memories WHERE id = ?`)
63
65
  .get(id);
64
- if (!row?.id)
65
- return null;
66
+ return row?.id ? deleteTargetRow(db, row, opts) : null;
67
+ }
68
+ function deleteTargetRow(db, row, opts) {
69
+ const { id } = row;
66
70
  const guard = opts?.automatic ? ` AND ${AUTOMATIC_DELETE_SQL}` : '';
67
71
  if (deleteMemoryRow(db, `DELETE FROM memories WHERE id = ?${guard}`, id) === 0)
68
72
  return null;
@@ -92,6 +96,35 @@ function deleteEntryOn(db, hippoRoot, id, opts) {
92
96
  purgeMirrorBestEffort(hippoRoot, id, false, 'deleteEntry');
93
97
  return true;
94
98
  }
99
+ /** deleteEntry with `automatic` for each removal and its own forget row and reason, all in one transaction after one read of the id set.
100
+ * Returns the ids deleted, in `removals` order; a missing, repeated, pinned, raw or object-backing id is left out. */
101
+ export function deleteEntriesAutomatically(hippoRoot, removals, actor) {
102
+ if (removals.length === 0)
103
+ return [];
104
+ const deleted = onHandle(hippoRoot, (db) => withWriteScope(db, 'delete_entries_automatically', () => {
105
+ const rows = selectDeleteTargets(db, removals.map((removal) => removal.id));
106
+ return removals
107
+ .filter(({ id, reason }) => {
108
+ const row = rows.get(id);
109
+ return row !== undefined && deleteTargetRow(db, row, { actor, reason, automatic: true }) !== null;
110
+ })
111
+ .map((removal) => removal.id);
112
+ }), openStore);
113
+ for (const id of deleted)
114
+ purgeMirrorBestEffort(hippoRoot, id, false, 'deleteEntry');
115
+ return deleted;
116
+ }
117
+ function selectDeleteTargets(db, ids) {
118
+ const rows = new Map();
119
+ for (const chunk of chunked([...new Set(ids)])) {
120
+ // SAFETY: rows' shape matches the three columns named in the SELECT.
121
+ const found = db.prepare(`SELECT id, tenant_id, dag_parent_id FROM memories WHERE id IN (${chunk.map(() => '?').join(',')})`)
122
+ .all(...chunk);
123
+ for (const row of found)
124
+ rows.set(row.id, row);
125
+ }
126
+ return rows;
127
+ }
95
128
  // The child fields a level-2/3 summary is built from (loadChildrenOfSummary, generateDagSummary).
96
129
  const SUMMARY_INPUTS = ['content', 'created', 'dag_parent_id', 'kind'];
97
130
  function mergeOwnChanges(base, ours, live) {
@@ -1,7 +1,7 @@
1
1
  import type { MemoryEntry } from '../core/memory.js';
2
2
  import { type PromptRecallGate } from '../core/prompt-recall.js';
3
3
  export type DeliveryRuntime = 'claude-code' | 'codex' | 'copilot' | 'unknown';
4
- export type DeliveryEventType = 'prompt-submit' | 'pinned-manual' | 'pre-compact' | 'compact-resume' | 'session-end' | 'context';
4
+ export type DeliveryEventType = 'prompt-submit' | 'pinned-manual' | 'pre-compact' | 'compact-resume' | 'session-end' | 'context' | 'tool-failure';
5
5
  /** True for the boundary types: a compaction's two hooks and the end of a session. */
6
6
  export declare const isBoundaryEvent: (type: DeliveryEventType) => boolean;
7
7
  export type DeliverySurface = 'hook' | 'context';
@@ -12,8 +12,9 @@ export type DeliveryPool = 'pin' | 'recent' | 'prompt-recall' | 'strength' | 'se
12
12
  export type DeliveryStage = 'load' | 'eligible' | 'gate' | 'budget' | 'limit' | 'final';
13
13
  export type DeliveryOutcome = 'emitted' | 'reused' | 'rejected';
14
14
  export type DeliveryRejectReason = 'budget' | 'gate-below-threshold' | 'gate-max-items' | 'duplicate' | 'scope' | 'quality' | 'limit';
15
- /** Row format version in `delivery_events.ledger_version`: 3 = written by a binary that can write session-end and context rows, so `event_type` has six values. */
16
- export declare const DELIVERY_LEDGER_VERSION = 3;
15
+ /** Row format version in `delivery_events.ledger_version`: 4 = written by a binary that can write `tool-failure` rows and hashes the
16
+ * store's resolved root. */
17
+ export declare const DELIVERY_LEDGER_VERSION = 4;
17
18
  /** Rejected candidate rows kept per event; the rest only add to `rejected_unlisted`. */
18
19
  export declare const DELIVERY_REJECTED_ROW_CAP = 16;
19
20
  export interface DeliveryCandidateInput {
@@ -61,6 +62,10 @@ export interface DeliveryEventInput {
61
62
  recallHash: string | null;
62
63
  emittedHash: string | null;
63
64
  elapsedMs: number;
65
+ /** The host's id for the tool call; set on `tool-failure` rows only. */
66
+ toolUseId?: string | null;
67
+ /** The `failure_log` row the failure was logged as; set on `tool-failure` rows only. */
68
+ failureId?: number | null;
64
69
  candidates: readonly DeliveryCandidateInput[];
65
70
  }
66
71
  export interface DeliveryFacts {
@@ -116,6 +121,8 @@ export interface DeliveryOutcomeInput {
116
121
  export interface DeliveryRecorder extends DeliveryObserver {
117
122
  readonly root: string;
118
123
  delivered(outcome: DeliveryOutcomeInput): void;
124
+ /** The failure log row id a `tool-failure` event links to; null when the log write threw. */
125
+ logged(failureId: number | null): void;
119
126
  /** Builds the event and hands it to `write` once per call; throws on an injected fault, and writes nothing once broken. */
120
127
  flush(write: (input: DeliveryEventInput) => number | null): void;
121
128
  }
@@ -1,14 +1,15 @@
1
1
  import { evalNow } from '../core/ablation.js';
2
2
  import { scoreOverlap } from '../core/prompt-recall.js';
3
- import { hookPayloadSessionId, hookPayloadString, isSubagentPayload } from './token-ledger.js';
3
+ import { hookPayloadSessionId, hookPayloadString, isSubagentPayload } from '../util/hook-payload.js';
4
4
  import { blockHash, estimateTokens } from '../util/token-text.js';
5
5
  import { errorMessage, log } from '../util/log.js';
6
6
  /** True for the boundary types: a compaction's two hooks and the end of a session. */
7
7
  export const isBoundaryEvent = (type) => type === 'pre-compact' || type === 'compact-resume' || type === 'session-end';
8
8
  /** Only the per-prompt calls keep prompt facts; a boundary or a `hippo context` run is not a prompt. */
9
9
  const carriesPrompt = (type) => type === 'prompt-submit' || type === 'pinned-manual';
10
- /** Row format version in `delivery_events.ledger_version`: 3 = written by a binary that can write session-end and context rows, so `event_type` has six values. */
11
- export const DELIVERY_LEDGER_VERSION = 3;
10
+ /** Row format version in `delivery_events.ledger_version`: 4 = written by a binary that can write `tool-failure` rows and hashes the
11
+ * store's resolved root. */
12
+ export const DELIVERY_LEDGER_VERSION = 4;
12
13
  /** Rejected candidate rows kept per event; the rest only add to `rejected_unlisted`. */
13
14
  export const DELIVERY_REJECTED_ROW_CAP = 16;
14
15
  // Deeper stages were closer to being sent, so the row cap keeps them first.
@@ -35,10 +36,13 @@ function readPayload(init) {
35
36
  const rawTurnId = hookPayloadString(init.stdinText, 'turn_id');
36
37
  const hostTurnId = rawTurnId !== null && rawTurnId.trim() !== '' ? rawTurnId : null;
37
38
  const hookEvent = hookPayloadString(init.stdinText, 'hook_event_name');
39
+ const rawToolUseId = hookPayloadString(init.stdinText, 'tool_use_id')?.trim() ?? '';
40
+ // Cut as failure_log cuts its payload fields: the payload is not trusted to be short.
41
+ const toolUseId = rawToolUseId !== '' ? rawToolUseId.slice(0, 128) : null;
38
42
  const sessionState = subagent
39
43
  ? 'subagent'
40
44
  : payloadSession !== null ? 'payload' : envSession !== null ? 'env' : 'missing';
41
- return { payloadSession, envSession, prompt, hostTurnId, hookEvent, sessionState };
45
+ return { payloadSession, envSession, prompt, hostTurnId, hookEvent, toolUseId, sessionState };
42
46
  }
43
47
  function rejectId(state, id, rejection) {
44
48
  const { stage, reason, score, tokens } = rejection;
@@ -136,6 +140,8 @@ function buildEvent(init, payload, state, ts, startedMs) {
136
140
  recallHash: outcome.recallHash ?? null,
137
141
  emittedHash: emitted !== null ? blockHash(emitted) : null,
138
142
  elapsedMs: Math.max(0, Date.now() - startedMs),
143
+ toolUseId: eventType === 'tool-failure' ? payload.toolUseId : null,
144
+ failureId: eventType === 'tool-failure' ? state.failureId : null,
139
145
  candidates: rows,
140
146
  };
141
147
  }
@@ -205,7 +211,7 @@ export function createDeliveryRecorder(init) {
205
211
  const payload = readPayload(init);
206
212
  const state = {
207
213
  candidates: new Map(), picked: new Map(), filtered: new Set(), facts: null, shown: 0, dropped: 0,
208
- disabledSeen: false, outcome: { state: 'empty' }, queryHash: null, recallTraceId: null, broken: null, flushed: false,
214
+ disabledSeen: false, outcome: { state: 'empty' }, queryHash: null, recallTraceId: null, failureId: null, broken: null, flushed: false,
209
215
  };
210
216
  const guard = guardFor(state, fault);
211
217
  const { qualityDropped, offer, reject, dropMissing, gated, selected } = candidateMethods(state, guard);
@@ -229,6 +235,7 @@ export function createDeliveryRecorder(init) {
229
235
  queried: (query) => guard(() => { state.queryHash = blockHash(query); }),
230
236
  traced: (traceId) => guard(() => { state.recallTraceId = traceId; }),
231
237
  delivered: (o) => guard(() => { state.outcome = { ...o }; }),
238
+ logged: (failureId) => guard(() => { state.failureId = failureId; }),
232
239
  flush: (write) => {
233
240
  if (state.flushed)
234
241
  return;
@@ -1,4 +1,5 @@
1
- import { chunked, selectEntriesByIds, TENANT_IS } from './entry-reads.js';
1
+ import { selectEntriesByIds, TENANT_IS } from './entry-reads.js';
2
+ import { chunked } from '../util/chunked.js';
2
3
  import { MEMORY_SELECT_COLUMNS, rowToEntry } from './rows.js';
3
4
  const marks = (ids) => ids.map(() => '?').join(',');
4
5
  /** The walk `summaryWithDescendants` documents, with `levels` cut to the first `page.rows` rows and each level's full count in `sizes`. */
@@ -53,7 +54,8 @@ function countedLevel(db, walk, parents, room) {
53
54
  const perParent = new Map();
54
55
  for (const chunk of chunked([...parents])) {
55
56
  // SAFETY: the SELECT names exactly ChildGroup's four fields, and the WHERE keeps dag_parent_id a string.
56
- const groups = db.prepare(`SELECT dag_parent_id, scope, origin_project, COUNT(*) AS n FROM memories WHERE dag_parent_id IN (${marks(chunk)}) AND ${TENANT_IS} AND id <> ? GROUP BY dag_parent_id, scope, origin_project`).all(...chunk, walk.tenantId, walk.summary.id);
57
+ const groups = db.prepare(`SELECT dag_parent_id, scope, origin_project, COUNT(*) AS n FROM memories ` +
58
+ `WHERE dag_parent_id IN (${marks(chunk)}) AND ${TENANT_IS} AND id <> ? GROUP BY dag_parent_id, scope, origin_project`).all(...chunk, walk.tenantId, walk.summary.id);
57
59
  for (const group of groups) {
58
60
  if (!walk.page.admit(group))
59
61
  return null;
@@ -85,7 +87,8 @@ function childrenInOrder(db, walk, parents, limit) {
85
87
  const byParent = new Map();
86
88
  for (const chunk of chunked([...parents])) {
87
89
  // SAFETY: selects exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
88
- const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE dag_parent_id IN (${marks(chunk)}) AND ${TENANT_IS} AND id <> ? ORDER BY created ASC, id ASC LIMIT ?`).all(...chunk, walk.tenantId, walk.summary.id, limit);
90
+ const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE dag_parent_id IN (${marks(chunk)}) AND ${TENANT_IS} AND id <> ? ` +
91
+ `ORDER BY created ASC, id ASC LIMIT ?`).all(...chunk, walk.tenantId, walk.summary.id, limit);
89
92
  for (const row of rows) {
90
93
  const bucket = byParent.get(row.dag_parent_id ?? '');
91
94
  if (bucket)
@@ -3,7 +3,7 @@
3
3
  * Not the raw archive (`raw_archive`, `archiveRawMemory`), which keeps metadata only. db-taking helpers leave the handle and transaction to the caller. */
4
4
  import { type DatabaseSyncLike } from '../db/index.js';
5
5
  import type { MemoryEntry } from '../core/memory.js';
6
- import type { SqlFragment } from './recall-scope.js';
6
+ import type { SqlFragment } from './rule-sql.js';
7
7
  import type { WriteBudget } from '../util/write-budget.js';
8
8
  /** Why a memory went dormant: sleep's decay pass, an imported agent memory whose note was deleted, `hippo projects repair`
9
9
  * splitting a two-project merge, or `hippo audit repair` setting aside an automatic memory with a certain defect. */
@@ -3,7 +3,8 @@
3
3
  * Not the raw archive (`raw_archive`, `archiveRawMemory`), which keeps metadata only. db-taking helpers leave the handle and transaction to the caller. */
4
4
  import { closeHippoDb, openHippoDb, withWriteScope, withWriteScopeOr } from '../db/index.js';
5
5
  import { onHandle } from './open.js';
6
- import { RejectedValueError, rejectionDigest } from './rejection.js';
6
+ import { rejectionDigest } from './rejection.js';
7
+ import { RejectedValueError } from '../core/api-errors.js';
7
8
  import { escapeLike } from '../util/escape.js';
8
9
  import { warnDamagedColumn } from '../util/stored-json.js';
9
10
  import { DAY_MS } from '../util/time.js';
@@ -32,6 +33,7 @@ function parseSnapshot(row) {
32
33
  // the id / tenant / content checks below reject a row edited out of shape.
33
34
  const entry = JSON.parse(row.entry_json);
34
35
  if (entry.id !== row.id || entry.tenantId !== row.tenant_id || entry.content !== row.content) {
36
+ warnDamagedColumn({ table: 'dormant_memories', id: row.id, column: 'entry_json' }, 'wrong shape');
35
37
  return null;
36
38
  }
37
39
  return entry;
@@ -1,9 +1,6 @@
1
- /** Optional embedding-based semantic search for Hippo.
2
- * Uses @huggingface/transformers (local, no API keys, ~22MB model); falls back silently if not installed. */
3
- import { MemoryEntry } from '../../core/memory.js';
1
+ /** The stored vector index's identity: which model and text format built it, and when a provider change means a rebuild.
2
+ * Picking a provider and computing vectors sit in src/search/embed-memories.ts; this module only reads and writes what is stored. */
4
3
  import { EMBEDDING_MODEL_META_KEY } from '../../db/vector-store.js';
5
- import { type EmbeddingProvider } from './provider.js';
6
- import type { HippoStore } from '../index.js';
7
4
  export { EMBEDDING_MODEL_META_KEY };
8
5
  /** Bump when `embeddingInputText` changes existing vectors; folded into the stored index identity (`embeddingIndexIdentity`) so it reindexes like a model
9
6
  * change. Format 2 = `path:*` tags excluded; format 1 (implicit, no suffix) included them. */
@@ -26,11 +23,4 @@ export declare function resolveIndexedEmbeddingModel(hippoRoot: string, index?:
26
23
  export declare function embeddingModelRequiresReindex(hippoRoot: string, model: string, index?: Record<string, number[]>): boolean;
27
24
  /** Cosine similarity; handles unnormalized vectors, returns 0 for empty or mismatched vectors. */
28
25
  export declare function cosineSimilarity(a: number[], b: number[]): number;
29
- /** `cosineSimilarity` over any indexable vectors; a Float32 view reads the same doubles as its number[] copy, so the score is the same. */
30
- export declare function cosineOf(a: ArrayLike<number>, b: ArrayLike<number>): number;
31
- /** Embed a single memory entry and cache the result in the embedding index; with `store`, through its vectorWrites, never opening hippo.db. */
32
- export declare function embedMemory(hippoRoot: string, entry: MemoryEntry, model?: string, store?: HippoStore): Promise<void>;
33
- /** Embeds every entry with no cached vector, prunes vectors of deleted memories, and returns how many it embedded; `provider` defaults to the
34
- * configured one. With `store`, every tenant's memories with no vector for the provider's model go through its `vectorWrites`, never hippo.db. */
35
- export declare function embedAll(hippoRoot: string, model?: string, provider?: EmbeddingProvider, store?: HippoStore): Promise<number>;
36
26
  //# sourceMappingURL=index.d.ts.map