hippo-memory 1.60.0 → 1.61.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 (585) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1262
  53. package/dist/api.js +25 -2727
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +6 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +2 -2
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +71 -120
  123. package/dist/cli.js +170 -8469
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +6 -4
  126. package/dist/connectors/github/backfill.js +94 -87
  127. package/dist/connectors/github/cli-impl.js +4 -3
  128. package/dist/connectors/github/dlq.js +67 -54
  129. package/dist/connectors/github/ingest.js +34 -35
  130. package/dist/connectors/github/tenant-routing.js +3 -2
  131. package/dist/connectors/github/webhook.js +135 -216
  132. package/dist/connectors/slack/dlq.js +49 -61
  133. package/dist/connectors/slack/ingest.js +55 -48
  134. package/dist/connectors/slack/tenant-routing.js +4 -3
  135. package/dist/connectors/slack/webhook.js +72 -74
  136. package/dist/consolidate/conflicts.d.ts +10 -0
  137. package/dist/consolidate/conflicts.js +178 -0
  138. package/dist/consolidate/decay.d.ts +12 -0
  139. package/dist/consolidate/decay.js +145 -0
  140. package/dist/consolidate/llm-passes.d.ts +3 -0
  141. package/dist/consolidate/llm-passes.js +141 -0
  142. package/dist/consolidate/merge.d.ts +7 -0
  143. package/dist/consolidate/merge.js +251 -0
  144. package/dist/consolidate/physics-pass.d.ts +3 -0
  145. package/dist/consolidate/physics-pass.js +60 -0
  146. package/dist/consolidate/run.d.ts +69 -0
  147. package/dist/consolidate/run.js +76 -0
  148. package/dist/consolidate/sleep.d.ts +18 -0
  149. package/dist/consolidate/sleep.js +209 -0
  150. package/dist/consolidate/traces.d.ts +4 -0
  151. package/dist/consolidate/traces.js +178 -0
  152. package/dist/context-auto.js +7 -11
  153. package/dist/context-render.d.ts +1 -1
  154. package/dist/context-render.js +1 -1
  155. package/dist/customer-notes.d.ts +3 -0
  156. package/dist/customer-notes.js +6 -4
  157. package/dist/dag.js +6 -5
  158. package/dist/dashboard-actions.d.ts +20 -0
  159. package/dist/dashboard-actions.js +88 -0
  160. package/dist/dashboard-params.d.ts +45 -0
  161. package/dist/dashboard-params.js +127 -0
  162. package/dist/dashboard-queries.d.ts +15 -0
  163. package/dist/dashboard-queries.js +355 -0
  164. package/dist/dashboard-snapshot.d.ts +138 -0
  165. package/dist/dashboard-snapshot.js +308 -0
  166. package/dist/dashboard-types.d.ts +163 -0
  167. package/dist/dashboard-types.js +3 -0
  168. package/dist/dashboard.d.ts +6 -7
  169. package/dist/dashboard.js +228 -202
  170. package/dist/db/busy.d.ts +5 -0
  171. package/dist/db/busy.js +24 -0
  172. package/dist/db/continuity.d.ts +5 -0
  173. package/dist/db/continuity.js +145 -0
  174. package/dist/db/meta.d.ts +8 -0
  175. package/dist/db/meta.js +35 -0
  176. package/dist/db/migrate.d.ts +9 -0
  177. package/dist/db/migrate.js +138 -0
  178. package/dist/db/migrations/index.d.ts +5 -0
  179. package/dist/db/migrations/index.js +109 -0
  180. package/dist/db/migrations/types.d.ts +14 -0
  181. package/dist/db/migrations/types.js +2 -0
  182. package/dist/db/migrations/v01.d.ts +3 -0
  183. package/dist/db/migrations/v01.js +38 -0
  184. package/dist/db/migrations/v02.d.ts +3 -0
  185. package/dist/db/migrations/v02.js +21 -0
  186. package/dist/db/migrations/v03.d.ts +3 -0
  187. package/dist/db/migrations/v03.js +22 -0
  188. package/dist/db/migrations/v04.d.ts +3 -0
  189. package/dist/db/migrations/v04.js +28 -0
  190. package/dist/db/migrations/v05.d.ts +3 -0
  191. package/dist/db/migrations/v05.js +21 -0
  192. package/dist/db/migrations/v06.d.ts +3 -0
  193. package/dist/db/migrations/v06.js +25 -0
  194. package/dist/db/migrations/v07.d.ts +3 -0
  195. package/dist/db/migrations/v07.js +13 -0
  196. package/dist/db/migrations/v08.d.ts +3 -0
  197. package/dist/db/migrations/v08.js +8 -0
  198. package/dist/db/migrations/v09.d.ts +3 -0
  199. package/dist/db/migrations/v09.js +13 -0
  200. package/dist/db/migrations/v10.d.ts +3 -0
  201. package/dist/db/migrations/v10.js +17 -0
  202. package/dist/db/migrations/v11.d.ts +3 -0
  203. package/dist/db/migrations/v11.js +15 -0
  204. package/dist/db/migrations/v12.d.ts +3 -0
  205. package/dist/db/migrations/v12.js +11 -0
  206. package/dist/db/migrations/v13.d.ts +3 -0
  207. package/dist/db/migrations/v13.js +15 -0
  208. package/dist/db/migrations/v14.d.ts +3 -0
  209. package/dist/db/migrations/v14.js +66 -0
  210. package/dist/db/migrations/v15.d.ts +3 -0
  211. package/dist/db/migrations/v15.js +42 -0
  212. package/dist/db/migrations/v16.d.ts +3 -0
  213. package/dist/db/migrations/v16.js +61 -0
  214. package/dist/db/migrations/v17.d.ts +3 -0
  215. package/dist/db/migrations/v17.js +46 -0
  216. package/dist/db/migrations/v18.d.ts +3 -0
  217. package/dist/db/migrations/v18.js +60 -0
  218. package/dist/db/migrations/v19.d.ts +3 -0
  219. package/dist/db/migrations/v19.js +28 -0
  220. package/dist/db/migrations/v20.d.ts +3 -0
  221. package/dist/db/migrations/v20.js +42 -0
  222. package/dist/db/migrations/v21.d.ts +3 -0
  223. package/dist/db/migrations/v21.js +16 -0
  224. package/dist/db/migrations/v22.d.ts +3 -0
  225. package/dist/db/migrations/v22.js +82 -0
  226. package/dist/db/migrations/v23.d.ts +3 -0
  227. package/dist/db/migrations/v23.js +48 -0
  228. package/dist/db/migrations/v24.d.ts +3 -0
  229. package/dist/db/migrations/v24.js +72 -0
  230. package/dist/db/migrations/v25.d.ts +3 -0
  231. package/dist/db/migrations/v25.js +46 -0
  232. package/dist/db/migrations/v26.d.ts +3 -0
  233. package/dist/db/migrations/v26.js +23 -0
  234. package/dist/db/migrations/v27.d.ts +3 -0
  235. package/dist/db/migrations/v27.js +57 -0
  236. package/dist/db/migrations/v28.d.ts +3 -0
  237. package/dist/db/migrations/v28.js +38 -0
  238. package/dist/db/migrations/v29.d.ts +3 -0
  239. package/dist/db/migrations/v29.js +78 -0
  240. package/dist/db/migrations/v30.d.ts +3 -0
  241. package/dist/db/migrations/v30.js +92 -0
  242. package/dist/db/migrations/v31.d.ts +3 -0
  243. package/dist/db/migrations/v31.js +74 -0
  244. package/dist/db/migrations/v32.d.ts +3 -0
  245. package/dist/db/migrations/v32.js +102 -0
  246. package/dist/db/migrations/v33.d.ts +3 -0
  247. package/dist/db/migrations/v33.js +104 -0
  248. package/dist/db/migrations/v34.d.ts +3 -0
  249. package/dist/db/migrations/v34.js +93 -0
  250. package/dist/db/migrations/v35.d.ts +3 -0
  251. package/dist/db/migrations/v35.js +98 -0
  252. package/dist/db/migrations/v36.d.ts +3 -0
  253. package/dist/db/migrations/v36.js +98 -0
  254. package/dist/db/migrations/v37.d.ts +3 -0
  255. package/dist/db/migrations/v37.js +219 -0
  256. package/dist/db/migrations/v38.d.ts +3 -0
  257. package/dist/db/migrations/v38.js +277 -0
  258. package/dist/db/migrations/v39.d.ts +3 -0
  259. package/dist/db/migrations/v39.js +59 -0
  260. package/dist/db/migrations/v40.d.ts +3 -0
  261. package/dist/db/migrations/v40.js +74 -0
  262. package/dist/db/migrations/v41.d.ts +3 -0
  263. package/dist/db/migrations/v41.js +43 -0
  264. package/dist/db/migrations/v42.d.ts +3 -0
  265. package/dist/db/migrations/v42.js +41 -0
  266. package/dist/db/migrations/v43.d.ts +3 -0
  267. package/dist/db/migrations/v43.js +67 -0
  268. package/dist/db/migrations/v44.d.ts +3 -0
  269. package/dist/db/migrations/v44.js +28 -0
  270. package/dist/db/migrations/v45.d.ts +3 -0
  271. package/dist/db/migrations/v45.js +30 -0
  272. package/dist/db/migrations/v46.d.ts +3 -0
  273. package/dist/db/migrations/v46.js +25 -0
  274. package/dist/db/migrations/v47.d.ts +3 -0
  275. package/dist/db/migrations/v47.js +17 -0
  276. package/dist/db/migrations/v48.d.ts +3 -0
  277. package/dist/db/migrations/v48.js +10 -0
  278. package/dist/db/migrations/v49.d.ts +3 -0
  279. package/dist/db/migrations/v49.js +31 -0
  280. package/dist/db/migrations/v50.d.ts +3 -0
  281. package/dist/db/migrations/v50.js +67 -0
  282. package/dist/db/migrations/v51.d.ts +3 -0
  283. package/dist/db/migrations/v51.js +14 -0
  284. package/dist/db/migrations/v52.d.ts +3 -0
  285. package/dist/db/migrations/v52.js +7 -0
  286. package/dist/db/open.d.ts +23 -0
  287. package/dist/db/open.js +146 -0
  288. package/dist/db/sqlite.d.ts +21 -0
  289. package/dist/db/sqlite.js +8 -0
  290. package/dist/db/tables.d.ts +7 -0
  291. package/dist/db/tables.js +38 -0
  292. package/dist/db.d.ts +6 -46
  293. package/dist/db.js +5 -3049
  294. package/dist/decisions.d.ts +4 -1
  295. package/dist/decisions.js +9 -7
  296. package/dist/dedupe.js +3 -2
  297. package/dist/delivery-recorder.js +4 -1
  298. package/dist/doctor.js +3 -3
  299. package/dist/embedding-provider.d.ts +1 -1
  300. package/dist/embedding-provider.js +4 -3
  301. package/dist/embeddings.d.ts +9 -52
  302. package/dist/embeddings.js +43 -297
  303. package/dist/env.d.ts +75 -0
  304. package/dist/env.js +119 -0
  305. package/dist/eval-suite.js +1 -1
  306. package/dist/eval.js +2 -2
  307. package/dist/extract.js +1 -1
  308. package/dist/gated-write.js +3 -1
  309. package/dist/goals.d.ts +3 -1
  310. package/dist/goals.js +18 -0
  311. package/dist/graph/read.d.ts +73 -0
  312. package/dist/graph/read.js +325 -0
  313. package/dist/graph/rows.d.ts +45 -0
  314. package/dist/graph/rows.js +51 -0
  315. package/dist/graph/types.d.ts +83 -0
  316. package/dist/graph/types.js +11 -0
  317. package/dist/graph/write.d.ts +93 -0
  318. package/dist/{graph.js → graph/write.js} +6 -384
  319. package/dist/graph-extract.js +2 -1
  320. package/dist/graph-recall.d.ts +1 -1
  321. package/dist/graph-recall.js +2 -2
  322. package/dist/graph-stream.js +1 -1
  323. package/dist/graph-view.d.ts +1 -1
  324. package/dist/graph-view.js +1 -1
  325. package/dist/half-life-migration.d.ts +1 -1
  326. package/dist/half-life-migration.js +2 -1
  327. package/dist/hooks/codex-session.d.ts +8 -0
  328. package/dist/hooks/codex-session.js +76 -0
  329. package/dist/hooks/codex-wrapper.d.ts +55 -0
  330. package/dist/hooks/codex-wrapper.js +288 -0
  331. package/dist/hooks/json-hooks.d.ts +63 -0
  332. package/dist/hooks/json-hooks.js +356 -0
  333. package/dist/hooks/opencode.d.ts +50 -0
  334. package/dist/hooks/opencode.js +202 -0
  335. package/dist/hooks/shared.d.ts +54 -0
  336. package/dist/hooks/shared.js +77 -0
  337. package/dist/http-retry.d.ts +2 -0
  338. package/dist/http-retry.js +4 -3
  339. package/dist/http-util.d.ts +3 -0
  340. package/dist/http-util.js +10 -0
  341. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  342. package/dist/importers/core.js +141 -0
  343. package/dist/importers/markdown-parse.d.ts +41 -0
  344. package/dist/importers/markdown-parse.js +132 -0
  345. package/dist/importers/markdown.d.ts +3 -0
  346. package/dist/importers/markdown.js +92 -0
  347. package/dist/importers/sources.d.ts +7 -0
  348. package/dist/importers/sources.js +229 -0
  349. package/dist/importers/vault.d.ts +11 -0
  350. package/dist/importers/vault.js +352 -0
  351. package/dist/incidents.d.ts +3 -0
  352. package/dist/incidents.js +7 -5
  353. package/dist/index.d.ts +25 -6
  354. package/dist/index.js +23 -6
  355. package/dist/invalidation.js +2 -1
  356. package/dist/judgment.js +2 -1
  357. package/dist/keyset.d.ts +13 -0
  358. package/dist/keyset.js +8 -0
  359. package/dist/local-embedding.d.ts +13 -0
  360. package/dist/local-embedding.js +165 -0
  361. package/dist/log.d.ts +7 -0
  362. package/dist/log.js +19 -1
  363. package/dist/mcp/admin-tools.d.ts +8 -0
  364. package/dist/mcp/admin-tools.js +116 -0
  365. package/dist/mcp/format.d.ts +27 -0
  366. package/dist/mcp/format.js +135 -0
  367. package/dist/mcp/memory-tools.d.ts +5 -0
  368. package/dist/mcp/memory-tools.js +83 -0
  369. package/dist/mcp/protocol.d.ts +83 -0
  370. package/dist/mcp/protocol.js +55 -0
  371. package/dist/mcp/recall-tools.d.ts +6 -0
  372. package/dist/mcp/recall-tools.js +320 -0
  373. package/dist/mcp/request.d.ts +10 -0
  374. package/dist/mcp/request.js +163 -0
  375. package/dist/mcp/server.d.ts +4 -75
  376. package/dist/mcp/server.js +7 -1190
  377. package/dist/mcp/session-state.d.ts +11 -0
  378. package/dist/mcp/session-state.js +28 -0
  379. package/dist/mcp/stdio.d.ts +8 -0
  380. package/dist/mcp/stdio.js +79 -0
  381. package/dist/mcp/tools.d.ts +11 -0
  382. package/dist/mcp/tools.js +247 -0
  383. package/dist/memory.d.ts +3 -0
  384. package/dist/memory.js +27 -1
  385. package/dist/multihop.d.ts +1 -1
  386. package/dist/multihop.js +2 -1
  387. package/dist/owner-validation.js +2 -1
  388. package/dist/physics-state.js +10 -7
  389. package/dist/policies.d.ts +3 -0
  390. package/dist/policies.js +8 -6
  391. package/dist/postinstall.js +3 -2
  392. package/dist/predictions/planning-fallacy.d.ts +100 -0
  393. package/dist/predictions/planning-fallacy.js +190 -0
  394. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  395. package/dist/predictions/store.js +434 -0
  396. package/dist/processes.d.ts +3 -0
  397. package/dist/processes.js +7 -5
  398. package/dist/project-briefs.d.ts +3 -0
  399. package/dist/project-briefs.js +7 -5
  400. package/dist/project-identity.js +3 -2
  401. package/dist/project-merge.js +3 -1
  402. package/dist/quarantine.d.ts +2 -1
  403. package/dist/quarantine.js +8 -5
  404. package/dist/raw-archive.js +1 -1
  405. package/dist/recall-history.js +3 -2
  406. package/dist/recall-pipeline.d.ts +2 -2
  407. package/dist/recall-pipeline.js +16 -8
  408. package/dist/recall-scope.js +1 -1
  409. package/dist/recall-trace.d.ts +1 -1
  410. package/dist/refine-llm.js +2 -1
  411. package/dist/reject-flow.js +6 -1
  412. package/dist/rerankers/clef.js +6 -5
  413. package/dist/rerankers/jev.d.ts +1 -1
  414. package/dist/rerankers/jev.js +4 -4
  415. package/dist/rerankers/llm.d.ts +4 -2
  416. package/dist/rerankers/llm.js +58 -38
  417. package/dist/rerankers/types.d.ts +1 -1
  418. package/dist/salience.js +1 -1
  419. package/dist/scheduler.d.ts +1 -0
  420. package/dist/scheduler.js +26 -4
  421. package/dist/scope.js +4 -3
  422. package/dist/search/as-of.d.ts +10 -0
  423. package/dist/search/as-of.js +22 -0
  424. package/dist/search/bm25-search.d.ts +14 -0
  425. package/dist/search/bm25-search.js +43 -0
  426. package/dist/search/bm25.d.ts +15 -0
  427. package/dist/search/bm25.js +54 -0
  428. package/dist/search/boosts.d.ts +54 -0
  429. package/dist/search/boosts.js +94 -0
  430. package/dist/search/breakdown.d.ts +7 -0
  431. package/dist/search/breakdown.js +20 -0
  432. package/dist/search/explain.d.ts +25 -0
  433. package/dist/search/explain.js +31 -0
  434. package/dist/search/finalize.d.ts +8 -0
  435. package/dist/search/finalize.js +52 -0
  436. package/dist/search/fusion.d.ts +27 -0
  437. package/dist/search/fusion.js +42 -0
  438. package/dist/search/hybrid-score.d.ts +20 -0
  439. package/dist/search/hybrid-score.js +73 -0
  440. package/dist/search/hybrid.d.ts +46 -0
  441. package/dist/search/hybrid.js +64 -0
  442. package/dist/search/physics-search.d.ts +29 -0
  443. package/dist/search/physics-search.js +162 -0
  444. package/dist/search/rerank.d.ts +10 -0
  445. package/dist/search/rerank.js +72 -0
  446. package/dist/search/temporal.d.ts +15 -0
  447. package/dist/search/temporal.js +45 -0
  448. package/dist/search/types.d.ts +91 -0
  449. package/dist/search/types.js +2 -0
  450. package/dist/search/vector.d.ts +30 -0
  451. package/dist/search/vector.js +71 -0
  452. package/dist/secret-detect.d.ts +2 -0
  453. package/dist/secret-detect.js +2 -1
  454. package/dist/server/auth.d.ts +52 -0
  455. package/dist/server/auth.js +221 -0
  456. package/dist/server/client-ip.d.ts +25 -0
  457. package/dist/server/client-ip.js +92 -0
  458. package/dist/server/cursor.d.ts +23 -0
  459. package/dist/server/cursor.js +58 -0
  460. package/dist/server/lifecycle.d.ts +7 -0
  461. package/dist/server/lifecycle.js +29 -0
  462. package/dist/server/mcp-http.d.ts +5 -0
  463. package/dist/server/mcp-http.js +199 -0
  464. package/dist/server/request.d.ts +33 -0
  465. package/dist/server/request.js +103 -0
  466. package/dist/server/routes/admin.d.ts +9 -0
  467. package/dist/server/routes/admin.js +158 -0
  468. package/dist/server/routes/customer-notes.d.ts +7 -0
  469. package/dist/server/routes/customer-notes.js +112 -0
  470. package/dist/server/routes/decisions.d.ts +7 -0
  471. package/dist/server/routes/decisions.js +133 -0
  472. package/dist/server/routes/incidents.d.ts +7 -0
  473. package/dist/server/routes/incidents.js +126 -0
  474. package/dist/server/routes/memories.d.ts +10 -0
  475. package/dist/server/routes/memories.js +179 -0
  476. package/dist/server/routes/policies.d.ts +8 -0
  477. package/dist/server/routes/policies.js +151 -0
  478. package/dist/server/routes/predictions.d.ts +7 -0
  479. package/dist/server/routes/predictions.js +164 -0
  480. package/dist/server/routes/processes.d.ts +7 -0
  481. package/dist/server/routes/processes.js +161 -0
  482. package/dist/server/routes/project-briefs.d.ts +8 -0
  483. package/dist/server/routes/project-briefs.js +136 -0
  484. package/dist/server/routes/recall.d.ts +8 -0
  485. package/dist/server/routes/recall.js +340 -0
  486. package/dist/server/routes/skills.d.ts +8 -0
  487. package/dist/server/routes/skills.js +150 -0
  488. package/dist/server/types.d.ts +56 -0
  489. package/dist/server/types.js +2 -0
  490. package/dist/server/validation.d.ts +14 -0
  491. package/dist/server/validation.js +91 -0
  492. package/dist/server.d.ts +7 -61
  493. package/dist/server.js +69 -2362
  494. package/dist/session-digest.d.ts +1 -1
  495. package/dist/session-digest.js +9 -2
  496. package/dist/shared.d.ts +3 -1
  497. package/dist/shared.js +26 -22
  498. package/dist/skills.d.ts +3 -0
  499. package/dist/skills.js +7 -5
  500. package/dist/stdin.js +2 -2
  501. package/dist/store/audit-event.d.ts +19 -0
  502. package/dist/store/audit-event.js +33 -0
  503. package/dist/store/candidates.d.ts +42 -0
  504. package/dist/store/candidates.js +152 -0
  505. package/dist/store/conflicts.d.ts +44 -0
  506. package/dist/store/conflicts.js +444 -0
  507. package/dist/store/delete-and-batch.d.ts +63 -0
  508. package/dist/store/delete-and-batch.js +310 -0
  509. package/dist/store/entry-reads.d.ts +92 -0
  510. package/dist/store/entry-reads.js +255 -0
  511. package/dist/store/entry-row.d.ts +67 -0
  512. package/dist/store/entry-row.js +208 -0
  513. package/dist/store/entry-writes.d.ts +46 -0
  514. package/dist/store/entry-writes.js +148 -0
  515. package/dist/store/handoffs.d.ts +26 -0
  516. package/dist/store/handoffs.js +184 -0
  517. package/dist/store/index-and-stats.d.ts +52 -0
  518. package/dist/store/index-and-stats.js +214 -0
  519. package/dist/store/markdown.d.ts +10 -0
  520. package/dist/store/markdown.js +108 -0
  521. package/dist/store/mirrors.d.ts +49 -0
  522. package/dist/store/mirrors.js +312 -0
  523. package/dist/store/open.d.ts +15 -0
  524. package/dist/store/open.js +223 -0
  525. package/dist/store/rows.d.ts +178 -0
  526. package/dist/store/rows.js +158 -0
  527. package/dist/store/search-rows.d.ts +86 -0
  528. package/dist/store/search-rows.js +254 -0
  529. package/dist/store/sessions.d.ts +83 -0
  530. package/dist/store/sessions.js +272 -0
  531. package/dist/store/summaries.d.ts +94 -0
  532. package/dist/store/summaries.js +377 -0
  533. package/dist/store/tenant-lookup.d.ts +12 -0
  534. package/dist/store/tenant-lookup.js +16 -0
  535. package/dist/store-cards.js +2 -1
  536. package/dist/summary-dirty.d.ts +4 -0
  537. package/dist/summary-dirty.js +32 -0
  538. package/dist/support-bundle.js +4 -3
  539. package/dist/tenant.js +2 -2
  540. package/dist/tokenize.d.ts +2 -0
  541. package/dist/tokenize.js +16 -0
  542. package/dist/transcript-tail.d.ts +7 -0
  543. package/dist/transcript-tail.js +48 -0
  544. package/dist/vector-store.d.ts +27 -0
  545. package/dist/vector-store.js +210 -0
  546. package/dist/version.d.ts +2 -2
  547. package/dist/version.js +2 -2
  548. package/dist/working-memory.js +1 -1
  549. package/dist/yaml.js +36 -11
  550. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  551. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  552. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  553. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  554. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  555. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  556. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  557. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  558. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  559. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  560. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  562. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  563. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  564. package/dist-ui/index.html +3 -25
  565. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  566. package/extensions/openclaw-plugin/package.json +1 -1
  567. package/openclaw.plugin.json +1 -1
  568. package/package.json +1 -1
  569. package/dist/capture.d.ts +0 -155
  570. package/dist/capture.js +0 -1295
  571. package/dist/consolidate.d.ts +0 -58
  572. package/dist/consolidate.js +0 -1124
  573. package/dist/graph.d.ts +0 -245
  574. package/dist/hooks.d.ts +0 -208
  575. package/dist/hooks.js +0 -1076
  576. package/dist/importers.js +0 -900
  577. package/dist/predictions.js +0 -620
  578. package/dist/search.d.ts +0 -320
  579. package/dist/search.js +0 -970
  580. package/dist/store.d.ts +0 -776
  581. package/dist/store.js +0 -3473
  582. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  583. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  584. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  585. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -3,26 +3,20 @@
3
3
  * Uses @huggingface/transformers (local, zero API keys, ~22MB model).
4
4
  * Falls back silently if the library is not installed.
5
5
  */
6
+ import { envByName } from './env.js';
6
7
  import * as fs from 'fs';
7
8
  import * as path from 'path';
8
9
  import { randomUUID } from 'crypto';
9
- import { createRequire } from 'module';
10
- import { loadAllEntries } from './store.js';
10
+ import { loadAllEntries } from './store/entry-reads.js';
11
11
  import { openHippoDb, closeHippoDb, getMeta, setMeta } from './db.js';
12
+ import { EMBEDDING_MODEL_META_KEY, deleteOrphanVectors, hasStoredVectors, loadVectors, replaceAllVectors, storedVectorIds, upsertVectors, } from './vector-store.js';
12
13
  import { initializeParticle, savePhysicsState, loadPhysicsState, resetAllPhysicsState } from './physics-state.js';
13
14
  import { loadConfig } from './config.js';
14
15
  import { resolveEmbeddingProvider } from './embedding-provider.js';
16
+ import { DEFAULT_EMBEDDING_MODEL } from './local-embedding.js';
15
17
  import { redactSecretsStrict } from './secret-detect.js';
16
18
  import { log } from './log.js';
17
- // Use createRequire for synchronous module resolution check in ESM
18
- const _require = createRequire(import.meta.url);
19
- // Cached availability check
20
- let _embeddingAvailable = null;
21
- // Lazy-loaded pipeline (expensive to initialize)
22
- const _pipelineInstances = new Map();
23
- const _pipelineLoading = new Map();
24
- export const DEFAULT_EMBEDDING_MODEL = 'Xenova/all-MiniLM-L6-v2';
25
- export const EMBEDDING_MODEL_META_KEY = 'embedding_model';
19
+ export { EMBEDDING_MODEL_META_KEY };
26
20
  /**
27
21
  * Bump whenever `embeddingInputText`'s composition changes in a way that
28
22
  * changes the resulting vectors for existing entries. Folded into the stored
@@ -75,150 +69,6 @@ export function embeddingInputText(entry) {
75
69
  const tags = entry.tags.filter((t) => !t.startsWith('path:'));
76
70
  return `${entry.content} ${tags.join(' ')}`.trim();
77
71
  }
78
- /**
79
- * Per-model pooling dispatch for Transformers.js's feature-extraction
80
- * pipeline. BGE family models were trained with CLS pooling (per BAAI's
81
- * official inference code in `FlagEmbedding`); MiniLM and most sentence-
82
- * transformers models use mean pooling. Unknown model ids default to mean
83
- * — that is the safe choice because most third-party models adopt the
84
- * sentence-transformers convention, and the alternative ('cls') silently
85
- * degrades vector quality for mean-pooling models.
86
- */
87
- export function poolingFor(model) {
88
- return /\bbge\b/i.test(model) ? 'cls' : 'mean';
89
- }
90
- export function prefixFor(model, role) {
91
- if (!role)
92
- return '';
93
- if (/\be5\b/i.test(model)) {
94
- return role === 'query' ? 'query: ' : 'passage: ';
95
- }
96
- return '';
97
- }
98
- // Use Function constructor to bypass TypeScript static module resolution
99
- // for optional peer dependencies that may not be installed.
100
- // SAFETY: `import(s)` always resolves to a module namespace object (or rejects);
101
- // Promise<object> names that honestly without claiming a specific module shape.
102
- const _dynImport = new Function('s', 'return import(s)');
103
- /**
104
- * Check (synchronously) if @xenova/transformers or @huggingface/transformers is installed.
105
- */
106
- export function isEmbeddingAvailable() {
107
- if (_embeddingAvailable !== null)
108
- return _embeddingAvailable;
109
- try {
110
- _require.resolve('@xenova/transformers');
111
- _embeddingAvailable = true;
112
- return true;
113
- }
114
- catch {
115
- // fall through
116
- }
117
- try {
118
- _require.resolve('@huggingface/transformers');
119
- _embeddingAvailable = true;
120
- return true;
121
- }
122
- catch {
123
- // fall through
124
- }
125
- _embeddingAvailable = false;
126
- return false;
127
- }
128
- /**
129
- * Pick exactly one Transformers.js implementation before importing either.
130
- *
131
- * Importing both packages in one process loads incompatible native
132
- * onnxruntime-node versions (Xenova v2 uses ORT 1.14; Hugging Face v4 uses a
133
- * current ORT). Their finalizers can double-free an InferenceSession on exit.
134
- * Prefer the maintained package shipped by Hippo, with Xenova retained only as
135
- * a compatibility fallback for users who installed it themselves.
136
- */
137
- function resolveTransformersPackage() {
138
- try {
139
- _require.resolve('@huggingface/transformers');
140
- return '@huggingface/transformers';
141
- }
142
- catch {
143
- // fall through
144
- }
145
- try {
146
- _require.resolve('@xenova/transformers');
147
- return '@xenova/transformers';
148
- }
149
- catch {
150
- return null; // neither optional package is installed; callers fall back to no local embeddings
151
- }
152
- }
153
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
154
- async function loadPipeline(model) {
155
- if (_pipelineInstances.has(model))
156
- return _pipelineInstances.get(model);
157
- if (_pipelineLoading.has(model))
158
- return _pipelineLoading.get(model);
159
- const loading = (async () => {
160
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
161
- const pkg = resolveTransformersPackage();
162
- if (!pkg)
163
- return null;
164
- let pipelineFn = null;
165
- try {
166
- // SAFETY: the resolved module's shape is untyped by design (optional peer
167
- // dependency); pipelineFn/mod.env are read defensively below and any
168
- // failure to find a usable pipeline falls through to `return null`.
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
- const mod = await _dynImport(pkg);
171
- if (process.env.HIPPO_MODEL_CACHE) {
172
- if (mod.env) {
173
- mod.env.cacheDir = process.env.HIPPO_MODEL_CACHE;
174
- mod.env.localModelPath = process.env.HIPPO_MODEL_CACHE;
175
- mod.env.allowRemoteModels = false;
176
- }
177
- }
178
- pipelineFn = mod.pipeline ?? mod.default?.pipeline;
179
- }
180
- catch (err) {
181
- log.debug(`transformers import failed (${pkg}): ${err instanceof Error ? err.message : String(err)}`);
182
- return null;
183
- }
184
- if (!pipelineFn)
185
- return null;
186
- // The Qdrant-vendored bundle (used in egress-restricted sandboxes) ships
187
- // only `onnx/model.onnx` (FP32). The HF default ships `model_quantized.onnx`
188
- // too. When pointing at a local cache, pick the variant that's on disk.
189
- const cacheRoot = process.env.HIPPO_MODEL_CACHE?.trim();
190
- const quantized = !cacheRoot
191
- || fs.existsSync(path.join(cacheRoot, model, 'onnx', 'model_quantized.onnx'));
192
- try {
193
- const instance = await pipelineFn('feature-extraction', model, { quantized });
194
- _pipelineInstances.set(model, instance);
195
- return instance;
196
- }
197
- catch (err) {
198
- log.debug(`embedding pipeline load failed (${model}): ${err instanceof Error ? err.message : String(err)}`);
199
- return null;
200
- }
201
- finally {
202
- _pipelineLoading.delete(model);
203
- }
204
- })();
205
- _pipelineLoading.set(model, loading);
206
- return loading;
207
- }
208
- export function resolveEmbeddingModel(hippoRoot, explicitModel) {
209
- const direct = explicitModel?.trim();
210
- if (direct)
211
- return direct;
212
- try {
213
- const configured = loadConfig(hippoRoot).embeddings.model?.trim();
214
- if (configured)
215
- return configured;
216
- }
217
- catch {
218
- // Fall back to the default model when config cannot be read.
219
- }
220
- return DEFAULT_EMBEDDING_MODEL;
221
- }
222
72
  function loadStoredEmbeddingModel(hippoRoot) {
223
73
  try {
224
74
  const db = openHippoDb(hippoRoot);
@@ -254,7 +104,8 @@ export function resolveIndexedEmbeddingModel(hippoRoot, index) {
254
104
  const stored = loadStoredEmbeddingModel(hippoRoot);
255
105
  if (stored)
256
106
  return stored;
257
- return Object.keys(index ?? loadEmbeddingIndex(hippoRoot)).length > 0 ? DEFAULT_EMBEDDING_MODEL : null;
107
+ const hasVectors = index ? Object.keys(index).length > 0 : withVectorDb(hippoRoot, hasStoredVectors);
108
+ return hasVectors ? DEFAULT_EMBEDDING_MODEL : null;
258
109
  }
259
110
  export function embeddingModelRequiresReindex(hippoRoot, model, index) {
260
111
  const stored = resolveIndexedEmbeddingModel(hippoRoot, index);
@@ -299,39 +150,6 @@ function resetPhysicsFromIndex(hippoRoot, entries, index) {
299
150
  function noteSkippedEmbedding(id) {
300
151
  log.warn('memory not embedded; the next embed run retries it', { id });
301
152
  }
302
- /**
303
- * Get an embedding vector for a piece of text.
304
- * Returns an empty array if transformers is not available or fails.
305
- *
306
- * Pass `role: 'query'` / `'passage'` to engage asymmetric prefixing for
307
- * model families that require it (currently intfloat/e5-*). Omitting `role`
308
- * keeps the legacy symmetric behavior (no prefix), so BGE / MiniLM callers
309
- * don't need to change.
310
- */
311
- export async function getEmbedding(text, model = DEFAULT_EMBEDDING_MODEL, role) {
312
- if (!isEmbeddingAvailable())
313
- return [];
314
- try {
315
- const pipe = await loadPipeline(model);
316
- if (!pipe)
317
- return [];
318
- const prefix = prefixFor(model, role);
319
- const input = prefix ? `${prefix}${text}` : text;
320
- // SAFETY: pipe() is a Transformers.js feature-extraction pipeline call;
321
- // its untyped output is read defensively below (only `.data`, cast on
322
- // the return line to the documented Float32Array tensor shape).
323
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
324
- const output = await pipe(input, { pooling: poolingFor(model), normalize: true });
325
- // SAFETY: output.data is a Float32Array per the feature-extraction
326
- // pipeline's documented tensor output shape.
327
- return Array.from(output.data);
328
- }
329
- catch (err) {
330
- // The caller sees `[]` and names the memory; the reason only shows at debug.
331
- log.debug(`local embedding failed: ${err instanceof Error ? err.message : String(err)}`);
332
- return [];
333
- }
334
- }
335
153
  /**
336
154
  * Cosine similarity between two vectors. Handles unnormalized vectors.
337
155
  * Returns 0 for empty or mismatched vectors.
@@ -353,85 +171,30 @@ export function cosineSimilarity(a, b) {
353
171
  // Clamp to [-1, 1] to handle floating point drift
354
172
  return Math.min(1, Math.max(-1, dot / denom));
355
173
  }
356
- const EMBEDDINGS_FILE = 'embeddings.json';
357
- // Never equal to a real index identity, so the next embed run treats it as a model change and rebuilds every vector.
358
- const QUARANTINED_INDEX_IDENTITY = 'quarantined-corrupt-index';
359
- function isErrnoCode(err, code) {
360
- return err instanceof Error && 'code' in err && err.code === code;
361
- }
362
- function parseEmbeddingIndex(raw) {
363
- try {
364
- const parsed = JSON.parse(raw);
365
- // SAFETY: saveEmbeddingIndex is the only writer and always writes this shape; anything that is not an object is corrupt.
366
- return parsed instanceof Object && !Array.isArray(parsed) ? parsed : null;
367
- }
368
- catch {
369
- return null; // the caller quarantines the corrupt file and logs it
370
- }
371
- }
372
- /** Move a corrupt index aside and flag a full rebuild, so no later save can write over the only copy of those bytes. */
373
- function quarantineCorruptIndex(hippoRoot, fp) {
374
- const aside = `${fp}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}-${process.pid}`;
375
- try {
376
- fs.renameSync(fp, aside);
377
- }
378
- catch (err) {
379
- if (isErrnoCode(err, 'ENOENT'))
380
- return;
381
- // A rename blocked by an open handle (Windows) still gets a copy kept; if the copy fails too, the throw stops the save.
382
- fs.copyFileSync(fp, aside, fs.constants.COPYFILE_EXCL);
383
- }
384
- log.error(`${EMBEDDINGS_FILE} could not be parsed; kept it as ${path.basename(aside)} and the next embed rebuilds the index`, { hippoRoot });
174
+ function withVectorDb(hippoRoot, fn) {
175
+ const db = openHippoDb(hippoRoot);
385
176
  try {
386
- const db = openHippoDb(hippoRoot);
387
- try {
388
- setMeta(db, EMBEDDING_MODEL_META_KEY, QUARANTINED_INDEX_IDENTITY);
389
- }
390
- finally {
391
- closeHippoDb(db);
392
- }
177
+ return fn(db);
393
178
  }
394
- catch (err) {
395
- log.warn(`could not flag the embedding index for rebuild; run 'hippo embed' to restore vectors (${err instanceof Error ? err.message : String(err)})`, { hippoRoot });
179
+ finally {
180
+ closeHippoDb(db);
396
181
  }
397
182
  }
398
- /**
399
- * Load the cached embedding index; `{}` when the file is missing. A corrupt file is moved aside and rebuilt on the next embed; any other read error throws, so nothing saves over an index it could not read.
400
- */
183
+ /** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
401
184
  export function loadEmbeddingIndex(hippoRoot) {
402
- const fp = path.join(hippoRoot, EMBEDDINGS_FILE);
403
- let raw;
404
- try {
405
- raw = fs.readFileSync(fp, 'utf8');
406
- }
407
- catch (err) {
408
- if (isErrnoCode(err, 'ENOENT'))
409
- return {};
410
- throw err;
411
- }
412
- const index = parseEmbeddingIndex(raw);
413
- if (index)
414
- return index;
415
- quarantineCorruptIndex(hippoRoot, fp);
416
- return {};
185
+ return Object.fromEntries(withVectorDb(hippoRoot, (db) => loadVectors(db)));
417
186
  }
418
- /**
419
- * Save the embedding index to disk.
420
- */
421
- export function saveEmbeddingIndex(hippoRoot, index) {
422
- const fp = path.join(hippoRoot, EMBEDDINGS_FILE);
423
- const tmp = fp + '.tmp';
424
- fs.writeFileSync(tmp, JSON.stringify(index), 'utf8');
425
- try {
426
- fs.renameSync(tmp, fp);
427
- }
428
- catch (err) {
429
- try {
430
- fs.unlinkSync(tmp);
431
- }
432
- catch { /* best-effort cleanup */ }
433
- throw err;
434
- }
187
+ /** Stored vectors for `ids` only. */
188
+ export function loadStoredVectors(hippoRoot, ids) {
189
+ return ids.length === 0 ? new Map() : withVectorDb(hippoRoot, (db) => loadVectors(db, ids));
190
+ }
191
+ /** Whether the store holds any vector at all. */
192
+ export function hasEmbeddings(hippoRoot) {
193
+ return withVectorDb(hippoRoot, hasStoredVectors);
194
+ }
195
+ /** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
196
+ export function saveEmbeddingIndex(hippoRoot, index, model) {
197
+ withVectorDb(hippoRoot, (db) => replaceAllVectors(db, index, model ?? getMeta(db, EMBEDDING_MODEL_META_KEY, '')));
435
198
  }
436
199
  const EMBED_LOCK_FILE = 'embeddings.lock';
437
200
  const EMBED_LOCK_WAIT_MS = 10_000;
@@ -495,7 +258,7 @@ async function acquireEmbedFileLock(hippoRoot) {
495
258
  continue;
496
259
  }
497
260
  if (Date.now() >= deadline)
498
- throw new Error(`embeddings.json is busy: another hippo process holds ${lockPath}`);
261
+ throw new Error(`the embedding index is busy: another hippo process holds ${lockPath}`);
499
262
  await new Promise((r) => setTimeout(r, 50));
500
263
  }
501
264
  }
@@ -550,15 +313,14 @@ export async function embedMemory(hippoRoot, entry, model) {
550
313
  // where failures surface. On any failure we leave the existing index as-is.
551
314
  try {
552
315
  const identity = provider.id;
553
- const existingIndex = loadEmbeddingIndex(hippoRoot);
554
- if (embeddingModelRequiresReindex(hippoRoot, identity, existingIndex)) {
316
+ if (embeddingModelRequiresReindex(hippoRoot, identity)) {
555
317
  // L9: host-wide rebuild. The embedding index is keyed by entry.id
556
318
  // (which is tenant-scoped) but the index itself is one per hippoRoot.
557
319
  // Cross-tenant content equivalence is visible at the vector level.
558
320
  // Per-tenant indices would be a larger architecture change.
559
321
  const entries = loadAllEntries(hippoRoot);
560
322
  const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
561
- saveEmbeddingIndex(hippoRoot, rebuiltIndex);
323
+ saveEmbeddingIndex(hippoRoot, rebuiltIndex, embeddingIndexIdentity(identity));
562
324
  saveStoredEmbeddingModel(hippoRoot, identity);
563
325
  resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
564
326
  return;
@@ -567,9 +329,7 @@ export async function embedMemory(hippoRoot, entry, model) {
567
329
  const [vector] = await provider.embed([text], 'passage');
568
330
  if (!vector || vector.length === 0)
569
331
  return;
570
- const index = existingIndex;
571
- index[entry.id] = vector;
572
- saveEmbeddingIndex(hippoRoot, index);
332
+ withVectorDb(hippoRoot, (db) => upsertVectors(db, [[entry.id, vector]], embeddingIndexIdentity(identity)));
573
333
  saveStoredEmbeddingModel(hippoRoot, identity);
574
334
  // Initialize physics state for this memory
575
335
  try {
@@ -612,7 +372,7 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
612
372
  if (provider.kind !== 'local' &&
613
373
  cfg.enabled !== false &&
614
374
  provider.keyEnv &&
615
- !process.env[provider.keyEnv]?.trim()) {
375
+ !envByName(provider.keyEnv)?.trim()) {
616
376
  throw new Error(`Embedding provider '${provider.kind}' is configured but ${provider.keyEnv} is not set.`);
617
377
  }
618
378
  return 0;
@@ -623,30 +383,25 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
623
383
  // entries into the per-host embedding index. Per-tenant filtering would
624
384
  // produce partial indices and break recall.
625
385
  const entries = loadAllEntries(hippoRoot);
626
- const index = loadEmbeddingIndex(hippoRoot);
627
- if (embeddingModelRequiresReindex(hippoRoot, identity, index)) {
386
+ const model = embeddingIndexIdentity(identity);
387
+ if (embeddingModelRequiresReindex(hippoRoot, identity)) {
628
388
  const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
629
- saveEmbeddingIndex(hippoRoot, rebuiltIndex);
389
+ saveEmbeddingIndex(hippoRoot, rebuiltIndex, model);
630
390
  saveStoredEmbeddingModel(hippoRoot, identity);
631
391
  resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
632
392
  return Object.keys(rebuiltIndex).length;
633
393
  }
634
- let dirty = false;
635
- // Prune orphaned embeddings for deleted memories
636
- const activeIds = new Set(entries.map((e) => e.id));
637
- for (const id of Object.keys(index)) {
638
- if (!activeIds.has(id)) {
639
- delete index[id];
640
- dirty = true;
641
- }
642
- }
394
+ const embedded = withVectorDb(hippoRoot, (db) => {
395
+ deleteOrphanVectors(db);
396
+ return storedVectorIds(db);
397
+ });
643
398
  // Embed entries without a cached vector in save-checkpointed chunks.
644
399
  // provider.embed batches internally (one HTTP request per batchSize for API
645
400
  // providers; sequential for local). A `[]` row means that single item could
646
401
  // not be embedded and is left for a later run (resumable). On a hard provider
647
402
  // failure mid-backfill we persist the chunks already embedded this run rather
648
403
  // than discarding paid progress, then stop and resume on the next run.
649
- const pending = entries.filter((e) => !index[e.id]);
404
+ const pending = entries.filter((e) => !embedded.has(e.id));
650
405
  let count = 0;
651
406
  // Initialized to `undefined` (not a known-evidence literal like `null`) so
652
407
  // it stays a plain `unknown` binding for the arbitrary caught value below;
@@ -665,24 +420,15 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
665
420
  backfillError = err;
666
421
  break;
667
422
  }
668
- let chunkDirty = false;
423
+ const rows = [];
669
424
  for (let j = 0; j < chunk.length; j++) {
670
425
  const vec = vectors[j];
671
- if (vec && vec.length > 0) {
672
- index[chunk[j].id] = vec;
673
- count++;
674
- dirty = true;
675
- chunkDirty = true;
676
- }
677
- else {
426
+ if (vec && vec.length > 0)
427
+ rows.push([chunk[j].id, vec]);
428
+ else
678
429
  noteSkippedEmbedding(chunk[j].id);
679
- }
680
430
  }
681
- if (chunkDirty)
682
- saveEmbeddingIndex(hippoRoot, index);
683
- }
684
- if (dirty) {
685
- saveEmbeddingIndex(hippoRoot, index);
431
+ count += withVectorDb(hippoRoot, (db) => upsertVectors(db, rows, model));
686
432
  }
687
433
  saveStoredEmbeddingModel(hippoRoot, identity);
688
434
  // Partial progress is now persisted; surface a hard backfill failure so the
package/dist/env.d.ts ADDED
@@ -0,0 +1,75 @@
1
+ /** The whole environment, for code that takes it as an injectable map (agent-memory machines, owner checks, support bundles). */
2
+ export declare function processEnv(): NodeJS.ProcessEnv;
3
+ /** A variable whose name comes from configuration, such as an embedding provider's key variable. */
4
+ export declare function envByName(name: string): string | undefined;
5
+ export declare function envAblateDecay(): boolean;
6
+ export declare function envAblateRecallBoost(): boolean;
7
+ export declare function envAblateOutcome(): boolean;
8
+ export declare function envAblateOutcomeSlow(): boolean;
9
+ export declare function envAblateOutcomeFast(): boolean;
10
+ export declare function envAblateRecency(): boolean;
11
+ /** HIPPO_EVAL_RECENCY_DAYS when it is a positive number, else null. */
12
+ export declare function envEvalRecencyDays(): number | null;
13
+ /** HIPPO_FAKE_NOW as epoch millis, or null unless it is byte-identical to Date.toISOString output. */
14
+ export declare function envFakeNowMs(): number | null;
15
+ export declare function envTestDeliveryFault(): string;
16
+ export declare function envForceLikePath(): boolean;
17
+ export declare function envLossAversionRatio(): string | undefined;
18
+ export declare function envSummaryDeboost(): string | undefined;
19
+ export declare function envAutodebiasOff(): boolean;
20
+ export declare function envAnchoringOff(): boolean;
21
+ export declare function envAvailabilityOff(): boolean;
22
+ export declare function envDagRebuildCap(): number | undefined;
23
+ export declare function envHippoHome(): string | undefined;
24
+ export declare function envXdgDataHome(): string | undefined;
25
+ export declare function envHomeDir(): string | undefined;
26
+ export declare function envPath(): string | undefined;
27
+ export declare function envModelCache(): string | undefined;
28
+ export declare function envHippoSessionId(): string | undefined;
29
+ export declare function envClaudeCodeSessionId(): string | undefined;
30
+ export declare function envScope(): string | undefined;
31
+ export declare function envGstackSkill(): string | undefined;
32
+ export declare function envOpenclawSkill(): string | undefined;
33
+ /** HIPPO_TENANT trimmed; empty or whitespace-only falls through to 'default'. */
34
+ export declare function envTenant(): string;
35
+ export declare function envSkipAutoIntegrations(): boolean;
36
+ export declare function envSkipPostinstall(): boolean;
37
+ export declare function envMcpStdio(): boolean;
38
+ /** Any non-empty value counts, unlike the `=1` switches. */
39
+ export declare function envRequireServer(): boolean;
40
+ export declare function envRequireSessionScopedFreshTail(): boolean;
41
+ export declare function envStdinWaitMs(): number | undefined;
42
+ export declare function envLogLevel(): string;
43
+ export declare function envPort(): string | undefined;
44
+ export declare function envRequireAuth(): boolean;
45
+ export declare function envV1Rps(): string | undefined;
46
+ export declare function envApiKey(): string | undefined;
47
+ export declare function envClientIpHeader(): string | undefined;
48
+ export declare function envTrustedProxies(): string | undefined;
49
+ export declare function envMcpSseMaxStreams(): number | undefined;
50
+ export declare function envMcpSseHeartbeatMs(): number | undefined;
51
+ export declare function envMcpSseMaxAgeSec(): number | undefined;
52
+ export declare function envAnthropicApiKey(): string | undefined;
53
+ export declare function envLlmTimeoutMs(): number | undefined;
54
+ export declare function envTypesafeApiKey(): string | undefined;
55
+ export declare function envJevTimeoutMs(): number | undefined;
56
+ export declare function envJevModel(): string | undefined;
57
+ export declare function envLlmRerankerUrl(): string | undefined;
58
+ export declare function envLlmRerankerKey(): string | undefined;
59
+ export declare function envLlmRerankerModel(): string | undefined;
60
+ export declare function envLlmRerankerTimeoutMs(): number | undefined;
61
+ export declare function envClefEndpoint(): string | undefined;
62
+ export declare function envClefEndpointToken(): string | undefined;
63
+ export declare function envClefTimeoutMs(): string | undefined;
64
+ export declare function envCloudflareAccountId(): string;
65
+ export declare function envCloudflareApiToken(): string;
66
+ export declare function envSlackBotToken(): string | undefined;
67
+ export declare function envSlackTeamId(): string | undefined;
68
+ export declare function envSlackSigningSecret(): string | undefined;
69
+ export declare function envSlackSigningSecretPrevious(): string | undefined;
70
+ export declare function envSlackAllowUnknownTeamFallback(): boolean;
71
+ export declare function envGithubToken(): string | undefined;
72
+ export declare function envGithubWebhookSecret(): string | undefined;
73
+ export declare function envGithubWebhookSecretPrevious(): string | undefined;
74
+ export declare function envGithubAllowUnknownInstallationFallback(): boolean;
75
+ //# sourceMappingURL=env.d.ts.map
package/dist/env.js ADDED
@@ -0,0 +1,119 @@
1
+ // The one module in src/ that reads process.env; scripts/check-env-reads.mjs fails CI on any other read.
2
+ // Accessors read at call time, so a test that sets a variable between cases, or a HIPPO_HOME switch mid-process, still holds.
3
+ function raw(name) {
4
+ return process.env[name];
5
+ }
6
+ function isOne(name) {
7
+ return raw(name) === '1';
8
+ }
9
+ function isOneOrTrue(name) {
10
+ const value = raw(name);
11
+ return value === '1' || value === 'true';
12
+ }
13
+ /** parseInt, kept only when above zero; the caller supplies its own default. */
14
+ function positiveInt(name) {
15
+ const parsed = Number.parseInt(raw(name) ?? '', 10);
16
+ return parsed > 0 ? parsed : undefined;
17
+ }
18
+ /** parseInt, kept when nonzero: these sites have always used `|| default`, so a negative value passes through. */
19
+ function nonZeroInt(name) {
20
+ return Number.parseInt(raw(name) ?? '', 10) || undefined;
21
+ }
22
+ /** The whole environment, for code that takes it as an injectable map (agent-memory machines, owner checks, support bundles). */
23
+ export function processEnv() {
24
+ return process.env;
25
+ }
26
+ /** A variable whose name comes from configuration, such as an embedding provider's key variable. */
27
+ export function envByName(name) {
28
+ return raw(name);
29
+ }
30
+ // Eval-only lifecycle switches; ablation.ts caches them per process.
31
+ export function envAblateDecay() { return isOneOrTrue('HIPPO_ABLATE_DECAY'); }
32
+ export function envAblateRecallBoost() { return isOneOrTrue('HIPPO_ABLATE_RECALL_BOOST'); }
33
+ export function envAblateOutcome() { return isOneOrTrue('HIPPO_ABLATE_OUTCOME'); }
34
+ export function envAblateOutcomeSlow() { return isOneOrTrue('HIPPO_ABLATE_OUTCOME_SLOW'); }
35
+ export function envAblateOutcomeFast() { return isOneOrTrue('HIPPO_ABLATE_OUTCOME_FAST'); }
36
+ export function envAblateRecency() { return isOneOrTrue('HIPPO_ABLATE_RECENCY'); }
37
+ /** HIPPO_EVAL_RECENCY_DAYS when it is a positive number, else null. */
38
+ export function envEvalRecencyDays() {
39
+ const days = Number(raw('HIPPO_EVAL_RECENCY_DAYS'));
40
+ return Number.isFinite(days) && days > 0 ? days : null;
41
+ }
42
+ /** HIPPO_FAKE_NOW as epoch millis, or null unless it is byte-identical to Date.toISOString output. */
43
+ export function envFakeNowMs() {
44
+ const value = raw('HIPPO_FAKE_NOW');
45
+ if (value === undefined || value === '')
46
+ return null;
47
+ // Round-trip, not a regex: Date.parse accepts junk and locale dates, and a regex admits rolled-over days like 02-31.
48
+ const parsed = Date.parse(value);
49
+ return Number.isFinite(parsed) && new Date(parsed).toISOString() === value ? parsed : null;
50
+ }
51
+ export function envTestDeliveryFault() { return raw('HIPPO_TEST_DELIVERY_FAULT') ?? ''; }
52
+ export function envForceLikePath() { return isOne('HIPPO_FORCE_LIKE_PATH'); }
53
+ export function envLossAversionRatio() { return raw('HIPPO_LOSS_AVERSION_RATIO'); }
54
+ export function envSummaryDeboost() { return raw('HIPPO_SUMMARY_DEBOOST'); }
55
+ export function envAutodebiasOff() { return raw('HIPPO_AUTODEBIAS') === 'off'; }
56
+ export function envAnchoringOff() { return raw('HIPPO_ANCHORING') === 'off'; }
57
+ export function envAvailabilityOff() { return raw('HIPPO_AVAILABILITY') === 'off'; }
58
+ export function envDagRebuildCap() { return positiveInt('HIPPO_DAG_REBUILD_CAP'); }
59
+ // Paths. HIPPO_HOME and XDG_DATA_HOME come back trimmed, possibly empty.
60
+ export function envHippoHome() { return raw('HIPPO_HOME')?.trim(); }
61
+ export function envXdgDataHome() { return raw('XDG_DATA_HOME')?.trim(); }
62
+ export function envHomeDir() { return raw('HOME') || raw('USERPROFILE'); }
63
+ export function envPath() { return raw('PATH'); }
64
+ export function envModelCache() { return raw('HIPPO_MODEL_CACHE'); }
65
+ // Session, scope and tenant.
66
+ export function envHippoSessionId() { return raw('HIPPO_SESSION_ID'); }
67
+ export function envClaudeCodeSessionId() { return raw('CLAUDE_CODE_SESSION_ID'); }
68
+ export function envScope() { return raw('HIPPO_SCOPE'); }
69
+ export function envGstackSkill() { return raw('GSTACK_SKILL'); }
70
+ export function envOpenclawSkill() { return raw('OPENCLAW_SKILL'); }
71
+ /** HIPPO_TENANT trimmed; empty or whitespace-only falls through to 'default'. */
72
+ export function envTenant() {
73
+ return raw('HIPPO_TENANT')?.trim() || 'default';
74
+ }
75
+ // Install and CLI switches.
76
+ export function envSkipAutoIntegrations() { return isOne('HIPPO_SKIP_AUTO_INTEGRATIONS'); }
77
+ export function envSkipPostinstall() { return isOne('HIPPO_SKIP_POSTINSTALL'); }
78
+ export function envMcpStdio() { return isOne('HIPPO_MCP_STDIO'); }
79
+ /** Any non-empty value counts, unlike the `=1` switches. */
80
+ export function envRequireServer() { return Boolean(raw('HIPPO_REQUIRE_SERVER')); }
81
+ export function envRequireSessionScopedFreshTail() { return isOne('HIPPO_REQUIRE_SESSION_SCOPED_FRESH_TAIL'); }
82
+ export function envStdinWaitMs() { return positiveInt('HIPPO_STDIN_WAIT_MS'); }
83
+ export function envLogLevel() { return raw('HIPPO_LOG')?.trim().toLowerCase() ?? ''; }
84
+ // Server.
85
+ export function envPort() { return raw('HIPPO_PORT'); }
86
+ export function envRequireAuth() { return isOne('HIPPO_REQUIRE_AUTH'); }
87
+ export function envV1Rps() { return raw('HIPPO_V1_RPS'); }
88
+ export function envApiKey() { return raw('HIPPO_API_KEY'); }
89
+ export function envClientIpHeader() { return raw('HIPPO_CLIENT_IP_HEADER')?.trim().toLowerCase(); }
90
+ export function envTrustedProxies() { return raw('HIPPO_TRUSTED_PROXIES'); }
91
+ export function envMcpSseMaxStreams() { return positiveInt('MCP_SSE_MAX_STREAMS'); }
92
+ export function envMcpSseHeartbeatMs() { return nonZeroInt('MCP_SSE_HEARTBEAT_MS'); }
93
+ export function envMcpSseMaxAgeSec() { return nonZeroInt('MCP_SSE_MAX_AGE_SEC'); }
94
+ // LLM and reranker credentials and knobs.
95
+ export function envAnthropicApiKey() { return raw('ANTHROPIC_API_KEY'); }
96
+ export function envLlmTimeoutMs() { return positiveInt('HIPPO_LLM_TIMEOUT_MS'); }
97
+ export function envTypesafeApiKey() { return raw('TYPESAFE_API_KEY'); }
98
+ export function envJevTimeoutMs() { return positiveInt('HIPPO_JEV_TIMEOUT_MS'); }
99
+ export function envJevModel() { return raw('HIPPO_JEV_MODEL'); }
100
+ export function envLlmRerankerUrl() { return raw('HIPPO_LLM_RERANKER_URL'); }
101
+ export function envLlmRerankerKey() { return raw('HIPPO_LLM_RERANKER_KEY'); }
102
+ export function envLlmRerankerModel() { return raw('HIPPO_LLM_RERANKER_MODEL'); }
103
+ export function envLlmRerankerTimeoutMs() { return nonZeroInt('HIPPO_LLM_RERANKER_TIMEOUT_MS'); }
104
+ export function envClefEndpoint() { return raw('HIPPO_CLEF_ENDPOINT')?.trim(); }
105
+ export function envClefEndpointToken() { return raw('HIPPO_CLEF_ENDPOINT_TOKEN')?.trim() || undefined; }
106
+ export function envClefTimeoutMs() { return raw('HIPPO_CLEF_TIMEOUT_MS'); }
107
+ export function envCloudflareAccountId() { return raw('CLOUDFLARE_ACCOUNT_ID')?.trim() ?? ''; }
108
+ export function envCloudflareApiToken() { return raw('CLOUDFLARE_API_TOKEN')?.trim() ?? ''; }
109
+ // Connectors.
110
+ export function envSlackBotToken() { return raw('SLACK_BOT_TOKEN'); }
111
+ export function envSlackTeamId() { return raw('SLACK_TEAM_ID'); }
112
+ export function envSlackSigningSecret() { return raw('SLACK_SIGNING_SECRET'); }
113
+ export function envSlackSigningSecretPrevious() { return raw('SLACK_SIGNING_SECRET_PREVIOUS'); }
114
+ export function envSlackAllowUnknownTeamFallback() { return isOne('SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK'); }
115
+ export function envGithubToken() { return raw('GITHUB_TOKEN'); }
116
+ export function envGithubWebhookSecret() { return raw('GITHUB_WEBHOOK_SECRET'); }
117
+ export function envGithubWebhookSecretPrevious() { return raw('GITHUB_WEBHOOK_SECRET_PREVIOUS'); }
118
+ export function envGithubAllowUnknownInstallationFallback() { return isOne('GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK'); }
119
+ //# sourceMappingURL=env.js.map
@@ -12,7 +12,7 @@
12
12
  * - Per-feature breakdown so you see exactly what a change helped/hurt
13
13
  */
14
14
  import { createMemory, Layer } from './memory.js';
15
- import { search } from './search.js';
15
+ import { search } from './search/bm25-search.js';
16
16
  import { multihopSearch } from './multihop.js';
17
17
  import { mrr, recallAtK, ndcgAtK } from './eval.js';
18
18
  // ---------------------------------------------------------------------------