hippo-memory 1.59.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 (596) 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 -1260
  53. package/dist/api.js +25 -2711
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +7 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +7 -4
  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 +319 -13
  123. package/dist/cli.js +436 -8580
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +12 -9
  126. package/dist/config.js +12 -11
  127. package/dist/connectors/github/backfill.js +94 -87
  128. package/dist/connectors/github/cli-impl.js +5 -3
  129. package/dist/connectors/github/dlq.js +67 -54
  130. package/dist/connectors/github/ingest.js +34 -35
  131. package/dist/connectors/github/tenant-routing.js +3 -2
  132. package/dist/connectors/github/webhook.js +135 -216
  133. package/dist/connectors/slack/dlq.js +49 -61
  134. package/dist/connectors/slack/ingest.js +55 -48
  135. package/dist/connectors/slack/tenant-routing.js +4 -3
  136. package/dist/connectors/slack/webhook.js +72 -74
  137. package/dist/consolidate/conflicts.d.ts +10 -0
  138. package/dist/consolidate/conflicts.js +178 -0
  139. package/dist/consolidate/decay.d.ts +12 -0
  140. package/dist/consolidate/decay.js +145 -0
  141. package/dist/consolidate/llm-passes.d.ts +3 -0
  142. package/dist/consolidate/llm-passes.js +141 -0
  143. package/dist/consolidate/merge.d.ts +7 -0
  144. package/dist/consolidate/merge.js +251 -0
  145. package/dist/consolidate/physics-pass.d.ts +3 -0
  146. package/dist/consolidate/physics-pass.js +60 -0
  147. package/dist/consolidate/run.d.ts +69 -0
  148. package/dist/consolidate/run.js +76 -0
  149. package/dist/consolidate/sleep.d.ts +18 -0
  150. package/dist/consolidate/sleep.js +209 -0
  151. package/dist/consolidate/traces.d.ts +4 -0
  152. package/dist/consolidate/traces.js +178 -0
  153. package/dist/context-auto.js +7 -11
  154. package/dist/context-render.d.ts +1 -1
  155. package/dist/context-render.js +1 -1
  156. package/dist/customer-notes.d.ts +3 -0
  157. package/dist/customer-notes.js +6 -4
  158. package/dist/dag.js +13 -12
  159. package/dist/dashboard-actions.d.ts +20 -0
  160. package/dist/dashboard-actions.js +88 -0
  161. package/dist/dashboard-params.d.ts +45 -0
  162. package/dist/dashboard-params.js +127 -0
  163. package/dist/dashboard-queries.d.ts +15 -0
  164. package/dist/dashboard-queries.js +355 -0
  165. package/dist/dashboard-snapshot.d.ts +138 -0
  166. package/dist/dashboard-snapshot.js +308 -0
  167. package/dist/dashboard-types.d.ts +163 -0
  168. package/dist/dashboard-types.js +3 -0
  169. package/dist/dashboard.d.ts +6 -7
  170. package/dist/dashboard.js +231 -203
  171. package/dist/db/busy.d.ts +5 -0
  172. package/dist/db/busy.js +24 -0
  173. package/dist/db/continuity.d.ts +5 -0
  174. package/dist/db/continuity.js +145 -0
  175. package/dist/db/meta.d.ts +8 -0
  176. package/dist/db/meta.js +35 -0
  177. package/dist/db/migrate.d.ts +9 -0
  178. package/dist/db/migrate.js +138 -0
  179. package/dist/db/migrations/index.d.ts +5 -0
  180. package/dist/db/migrations/index.js +109 -0
  181. package/dist/db/migrations/types.d.ts +14 -0
  182. package/dist/db/migrations/types.js +2 -0
  183. package/dist/db/migrations/v01.d.ts +3 -0
  184. package/dist/db/migrations/v01.js +38 -0
  185. package/dist/db/migrations/v02.d.ts +3 -0
  186. package/dist/db/migrations/v02.js +21 -0
  187. package/dist/db/migrations/v03.d.ts +3 -0
  188. package/dist/db/migrations/v03.js +22 -0
  189. package/dist/db/migrations/v04.d.ts +3 -0
  190. package/dist/db/migrations/v04.js +28 -0
  191. package/dist/db/migrations/v05.d.ts +3 -0
  192. package/dist/db/migrations/v05.js +21 -0
  193. package/dist/db/migrations/v06.d.ts +3 -0
  194. package/dist/db/migrations/v06.js +25 -0
  195. package/dist/db/migrations/v07.d.ts +3 -0
  196. package/dist/db/migrations/v07.js +13 -0
  197. package/dist/db/migrations/v08.d.ts +3 -0
  198. package/dist/db/migrations/v08.js +8 -0
  199. package/dist/db/migrations/v09.d.ts +3 -0
  200. package/dist/db/migrations/v09.js +13 -0
  201. package/dist/db/migrations/v10.d.ts +3 -0
  202. package/dist/db/migrations/v10.js +17 -0
  203. package/dist/db/migrations/v11.d.ts +3 -0
  204. package/dist/db/migrations/v11.js +15 -0
  205. package/dist/db/migrations/v12.d.ts +3 -0
  206. package/dist/db/migrations/v12.js +11 -0
  207. package/dist/db/migrations/v13.d.ts +3 -0
  208. package/dist/db/migrations/v13.js +15 -0
  209. package/dist/db/migrations/v14.d.ts +3 -0
  210. package/dist/db/migrations/v14.js +66 -0
  211. package/dist/db/migrations/v15.d.ts +3 -0
  212. package/dist/db/migrations/v15.js +42 -0
  213. package/dist/db/migrations/v16.d.ts +3 -0
  214. package/dist/db/migrations/v16.js +61 -0
  215. package/dist/db/migrations/v17.d.ts +3 -0
  216. package/dist/db/migrations/v17.js +46 -0
  217. package/dist/db/migrations/v18.d.ts +3 -0
  218. package/dist/db/migrations/v18.js +60 -0
  219. package/dist/db/migrations/v19.d.ts +3 -0
  220. package/dist/db/migrations/v19.js +28 -0
  221. package/dist/db/migrations/v20.d.ts +3 -0
  222. package/dist/db/migrations/v20.js +42 -0
  223. package/dist/db/migrations/v21.d.ts +3 -0
  224. package/dist/db/migrations/v21.js +16 -0
  225. package/dist/db/migrations/v22.d.ts +3 -0
  226. package/dist/db/migrations/v22.js +82 -0
  227. package/dist/db/migrations/v23.d.ts +3 -0
  228. package/dist/db/migrations/v23.js +48 -0
  229. package/dist/db/migrations/v24.d.ts +3 -0
  230. package/dist/db/migrations/v24.js +72 -0
  231. package/dist/db/migrations/v25.d.ts +3 -0
  232. package/dist/db/migrations/v25.js +46 -0
  233. package/dist/db/migrations/v26.d.ts +3 -0
  234. package/dist/db/migrations/v26.js +23 -0
  235. package/dist/db/migrations/v27.d.ts +3 -0
  236. package/dist/db/migrations/v27.js +57 -0
  237. package/dist/db/migrations/v28.d.ts +3 -0
  238. package/dist/db/migrations/v28.js +38 -0
  239. package/dist/db/migrations/v29.d.ts +3 -0
  240. package/dist/db/migrations/v29.js +78 -0
  241. package/dist/db/migrations/v30.d.ts +3 -0
  242. package/dist/db/migrations/v30.js +92 -0
  243. package/dist/db/migrations/v31.d.ts +3 -0
  244. package/dist/db/migrations/v31.js +74 -0
  245. package/dist/db/migrations/v32.d.ts +3 -0
  246. package/dist/db/migrations/v32.js +102 -0
  247. package/dist/db/migrations/v33.d.ts +3 -0
  248. package/dist/db/migrations/v33.js +104 -0
  249. package/dist/db/migrations/v34.d.ts +3 -0
  250. package/dist/db/migrations/v34.js +93 -0
  251. package/dist/db/migrations/v35.d.ts +3 -0
  252. package/dist/db/migrations/v35.js +98 -0
  253. package/dist/db/migrations/v36.d.ts +3 -0
  254. package/dist/db/migrations/v36.js +98 -0
  255. package/dist/db/migrations/v37.d.ts +3 -0
  256. package/dist/db/migrations/v37.js +219 -0
  257. package/dist/db/migrations/v38.d.ts +3 -0
  258. package/dist/db/migrations/v38.js +277 -0
  259. package/dist/db/migrations/v39.d.ts +3 -0
  260. package/dist/db/migrations/v39.js +59 -0
  261. package/dist/db/migrations/v40.d.ts +3 -0
  262. package/dist/db/migrations/v40.js +74 -0
  263. package/dist/db/migrations/v41.d.ts +3 -0
  264. package/dist/db/migrations/v41.js +43 -0
  265. package/dist/db/migrations/v42.d.ts +3 -0
  266. package/dist/db/migrations/v42.js +41 -0
  267. package/dist/db/migrations/v43.d.ts +3 -0
  268. package/dist/db/migrations/v43.js +67 -0
  269. package/dist/db/migrations/v44.d.ts +3 -0
  270. package/dist/db/migrations/v44.js +28 -0
  271. package/dist/db/migrations/v45.d.ts +3 -0
  272. package/dist/db/migrations/v45.js +30 -0
  273. package/dist/db/migrations/v46.d.ts +3 -0
  274. package/dist/db/migrations/v46.js +25 -0
  275. package/dist/db/migrations/v47.d.ts +3 -0
  276. package/dist/db/migrations/v47.js +17 -0
  277. package/dist/db/migrations/v48.d.ts +3 -0
  278. package/dist/db/migrations/v48.js +10 -0
  279. package/dist/db/migrations/v49.d.ts +3 -0
  280. package/dist/db/migrations/v49.js +31 -0
  281. package/dist/db/migrations/v50.d.ts +3 -0
  282. package/dist/db/migrations/v50.js +67 -0
  283. package/dist/db/migrations/v51.d.ts +3 -0
  284. package/dist/db/migrations/v51.js +14 -0
  285. package/dist/db/migrations/v52.d.ts +3 -0
  286. package/dist/db/migrations/v52.js +7 -0
  287. package/dist/db/open.d.ts +23 -0
  288. package/dist/db/open.js +146 -0
  289. package/dist/db/sqlite.d.ts +21 -0
  290. package/dist/db/sqlite.js +8 -0
  291. package/dist/db/tables.d.ts +7 -0
  292. package/dist/db/tables.js +38 -0
  293. package/dist/db.d.ts +6 -46
  294. package/dist/db.js +5 -3036
  295. package/dist/decisions.d.ts +4 -1
  296. package/dist/decisions.js +9 -7
  297. package/dist/dedupe.js +3 -2
  298. package/dist/delivery-recorder.js +5 -1
  299. package/dist/doctor.js +4 -3
  300. package/dist/dormant.js +1 -0
  301. package/dist/embedding-provider.d.ts +1 -1
  302. package/dist/embedding-provider.js +7 -5
  303. package/dist/embeddings.d.ts +9 -52
  304. package/dist/embeddings.js +47 -298
  305. package/dist/env.d.ts +75 -0
  306. package/dist/env.js +119 -0
  307. package/dist/eval-suite.js +1 -1
  308. package/dist/eval.js +2 -2
  309. package/dist/extract.js +5 -4
  310. package/dist/gated-write.js +3 -1
  311. package/dist/goals.d.ts +3 -1
  312. package/dist/goals.js +18 -0
  313. package/dist/graph/read.d.ts +73 -0
  314. package/dist/graph/read.js +325 -0
  315. package/dist/graph/rows.d.ts +45 -0
  316. package/dist/graph/rows.js +51 -0
  317. package/dist/graph/types.d.ts +83 -0
  318. package/dist/graph/types.js +11 -0
  319. package/dist/graph/write.d.ts +93 -0
  320. package/dist/{graph.js → graph/write.js} +8 -391
  321. package/dist/graph-extract.js +2 -1
  322. package/dist/graph-recall.d.ts +1 -1
  323. package/dist/graph-recall.js +2 -2
  324. package/dist/graph-stream.js +1 -1
  325. package/dist/graph-view.d.ts +1 -1
  326. package/dist/graph-view.js +1 -1
  327. package/dist/half-life-migration.d.ts +1 -1
  328. package/dist/half-life-migration.js +2 -1
  329. package/dist/handoff.js +3 -0
  330. package/dist/hooks/codex-session.d.ts +8 -0
  331. package/dist/hooks/codex-session.js +76 -0
  332. package/dist/hooks/codex-wrapper.d.ts +55 -0
  333. package/dist/hooks/codex-wrapper.js +288 -0
  334. package/dist/hooks/json-hooks.d.ts +63 -0
  335. package/dist/hooks/json-hooks.js +356 -0
  336. package/dist/hooks/opencode.d.ts +50 -0
  337. package/dist/hooks/opencode.js +202 -0
  338. package/dist/hooks/shared.d.ts +54 -0
  339. package/dist/hooks/shared.js +77 -0
  340. package/dist/http-retry.d.ts +2 -0
  341. package/dist/http-retry.js +4 -3
  342. package/dist/http-util.d.ts +3 -0
  343. package/dist/http-util.js +10 -0
  344. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  345. package/dist/importers/core.js +141 -0
  346. package/dist/importers/markdown-parse.d.ts +41 -0
  347. package/dist/importers/markdown-parse.js +132 -0
  348. package/dist/importers/markdown.d.ts +3 -0
  349. package/dist/importers/markdown.js +92 -0
  350. package/dist/importers/sources.d.ts +7 -0
  351. package/dist/importers/sources.js +229 -0
  352. package/dist/importers/vault.d.ts +11 -0
  353. package/dist/importers/vault.js +352 -0
  354. package/dist/incidents.d.ts +3 -0
  355. package/dist/incidents.js +8 -5
  356. package/dist/index.d.ts +25 -6
  357. package/dist/index.js +23 -6
  358. package/dist/invalidation.js +2 -1
  359. package/dist/judgment.js +7 -3
  360. package/dist/keyset.d.ts +13 -0
  361. package/dist/keyset.js +8 -0
  362. package/dist/local-embedding.d.ts +13 -0
  363. package/dist/local-embedding.js +165 -0
  364. package/dist/log.d.ts +7 -0
  365. package/dist/log.js +19 -1
  366. package/dist/mcp/admin-tools.d.ts +8 -0
  367. package/dist/mcp/admin-tools.js +116 -0
  368. package/dist/mcp/format.d.ts +27 -0
  369. package/dist/mcp/format.js +135 -0
  370. package/dist/mcp/memory-tools.d.ts +5 -0
  371. package/dist/mcp/memory-tools.js +83 -0
  372. package/dist/mcp/protocol.d.ts +83 -0
  373. package/dist/mcp/protocol.js +55 -0
  374. package/dist/mcp/recall-tools.d.ts +6 -0
  375. package/dist/mcp/recall-tools.js +320 -0
  376. package/dist/mcp/request.d.ts +10 -0
  377. package/dist/mcp/request.js +163 -0
  378. package/dist/mcp/server.d.ts +4 -70
  379. package/dist/mcp/server.js +8 -1172
  380. package/dist/mcp/session-state.d.ts +11 -0
  381. package/dist/mcp/session-state.js +28 -0
  382. package/dist/mcp/stdio.d.ts +8 -0
  383. package/dist/mcp/stdio.js +79 -0
  384. package/dist/mcp/tools.d.ts +11 -0
  385. package/dist/mcp/tools.js +247 -0
  386. package/dist/memory.d.ts +8 -3
  387. package/dist/memory.js +27 -1
  388. package/dist/multihop.d.ts +1 -1
  389. package/dist/multihop.js +2 -1
  390. package/dist/owner-validation.js +2 -1
  391. package/dist/physics-state.js +10 -7
  392. package/dist/policies.d.ts +3 -0
  393. package/dist/policies.js +8 -6
  394. package/dist/postinstall.js +3 -2
  395. package/dist/predictions/planning-fallacy.d.ts +100 -0
  396. package/dist/predictions/planning-fallacy.js +190 -0
  397. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  398. package/dist/predictions/store.js +434 -0
  399. package/dist/processes.d.ts +3 -0
  400. package/dist/processes.js +8 -5
  401. package/dist/project-briefs.d.ts +3 -0
  402. package/dist/project-briefs.js +7 -5
  403. package/dist/project-identity.d.ts +1 -1
  404. package/dist/project-identity.js +12 -6
  405. package/dist/project-merge.js +3 -1
  406. package/dist/quarantine.d.ts +2 -1
  407. package/dist/quarantine.js +8 -5
  408. package/dist/raw-archive-mirror-cleanup.js +2 -1
  409. package/dist/raw-archive.js +1 -1
  410. package/dist/recall-history.js +3 -2
  411. package/dist/recall-pipeline.d.ts +2 -2
  412. package/dist/recall-pipeline.js +16 -8
  413. package/dist/recall-scope.js +1 -1
  414. package/dist/recall-trace.d.ts +3 -3
  415. package/dist/recall-trace.js +10 -14
  416. package/dist/refine-llm.js +20 -11
  417. package/dist/reject-flow.js +6 -1
  418. package/dist/rerankers/clef.d.ts +2 -2
  419. package/dist/rerankers/clef.js +72 -30
  420. package/dist/rerankers/cross-encoder.js +6 -4
  421. package/dist/rerankers/jev.d.ts +4 -2
  422. package/dist/rerankers/jev.js +24 -19
  423. package/dist/rerankers/llm.d.ts +4 -2
  424. package/dist/rerankers/llm.js +61 -41
  425. package/dist/rerankers/types.d.ts +1 -1
  426. package/dist/salience.js +1 -1
  427. package/dist/same-text.d.ts +2 -0
  428. package/dist/same-text.js +4 -0
  429. package/dist/scheduler.d.ts +1 -0
  430. package/dist/scheduler.js +26 -3
  431. package/dist/scope.js +4 -3
  432. package/dist/search/as-of.d.ts +10 -0
  433. package/dist/search/as-of.js +22 -0
  434. package/dist/search/bm25-search.d.ts +14 -0
  435. package/dist/search/bm25-search.js +43 -0
  436. package/dist/search/bm25.d.ts +15 -0
  437. package/dist/search/bm25.js +54 -0
  438. package/dist/search/boosts.d.ts +54 -0
  439. package/dist/search/boosts.js +94 -0
  440. package/dist/search/breakdown.d.ts +7 -0
  441. package/dist/search/breakdown.js +20 -0
  442. package/dist/search/explain.d.ts +25 -0
  443. package/dist/search/explain.js +31 -0
  444. package/dist/search/finalize.d.ts +8 -0
  445. package/dist/search/finalize.js +52 -0
  446. package/dist/search/fusion.d.ts +27 -0
  447. package/dist/search/fusion.js +42 -0
  448. package/dist/search/hybrid-score.d.ts +20 -0
  449. package/dist/search/hybrid-score.js +73 -0
  450. package/dist/search/hybrid.d.ts +46 -0
  451. package/dist/search/hybrid.js +64 -0
  452. package/dist/search/physics-search.d.ts +29 -0
  453. package/dist/search/physics-search.js +162 -0
  454. package/dist/search/rerank.d.ts +10 -0
  455. package/dist/search/rerank.js +72 -0
  456. package/dist/search/temporal.d.ts +15 -0
  457. package/dist/search/temporal.js +45 -0
  458. package/dist/search/types.d.ts +91 -0
  459. package/dist/search/types.js +2 -0
  460. package/dist/search/vector.d.ts +30 -0
  461. package/dist/search/vector.js +71 -0
  462. package/dist/secret-detect.d.ts +2 -0
  463. package/dist/secret-detect.js +3 -1
  464. package/dist/server/auth.d.ts +52 -0
  465. package/dist/server/auth.js +221 -0
  466. package/dist/server/client-ip.d.ts +25 -0
  467. package/dist/server/client-ip.js +92 -0
  468. package/dist/server/cursor.d.ts +23 -0
  469. package/dist/server/cursor.js +58 -0
  470. package/dist/server/lifecycle.d.ts +7 -0
  471. package/dist/server/lifecycle.js +29 -0
  472. package/dist/server/mcp-http.d.ts +5 -0
  473. package/dist/server/mcp-http.js +199 -0
  474. package/dist/server/request.d.ts +33 -0
  475. package/dist/server/request.js +103 -0
  476. package/dist/server/routes/admin.d.ts +9 -0
  477. package/dist/server/routes/admin.js +158 -0
  478. package/dist/server/routes/customer-notes.d.ts +7 -0
  479. package/dist/server/routes/customer-notes.js +112 -0
  480. package/dist/server/routes/decisions.d.ts +7 -0
  481. package/dist/server/routes/decisions.js +133 -0
  482. package/dist/server/routes/incidents.d.ts +7 -0
  483. package/dist/server/routes/incidents.js +126 -0
  484. package/dist/server/routes/memories.d.ts +10 -0
  485. package/dist/server/routes/memories.js +179 -0
  486. package/dist/server/routes/policies.d.ts +8 -0
  487. package/dist/server/routes/policies.js +151 -0
  488. package/dist/server/routes/predictions.d.ts +7 -0
  489. package/dist/server/routes/predictions.js +164 -0
  490. package/dist/server/routes/processes.d.ts +7 -0
  491. package/dist/server/routes/processes.js +161 -0
  492. package/dist/server/routes/project-briefs.d.ts +8 -0
  493. package/dist/server/routes/project-briefs.js +136 -0
  494. package/dist/server/routes/recall.d.ts +8 -0
  495. package/dist/server/routes/recall.js +340 -0
  496. package/dist/server/routes/skills.d.ts +8 -0
  497. package/dist/server/routes/skills.js +150 -0
  498. package/dist/server/types.d.ts +56 -0
  499. package/dist/server/types.js +2 -0
  500. package/dist/server/validation.d.ts +14 -0
  501. package/dist/server/validation.js +91 -0
  502. package/dist/server.d.ts +7 -61
  503. package/dist/server.js +92 -2368
  504. package/dist/session-digest.d.ts +1 -1
  505. package/dist/session-digest.js +9 -2
  506. package/dist/shared.d.ts +3 -1
  507. package/dist/shared.js +46 -40
  508. package/dist/skills.d.ts +3 -0
  509. package/dist/skills.js +7 -5
  510. package/dist/stdin.js +3 -2
  511. package/dist/store/audit-event.d.ts +19 -0
  512. package/dist/store/audit-event.js +33 -0
  513. package/dist/store/candidates.d.ts +42 -0
  514. package/dist/store/candidates.js +152 -0
  515. package/dist/store/conflicts.d.ts +44 -0
  516. package/dist/store/conflicts.js +444 -0
  517. package/dist/store/delete-and-batch.d.ts +63 -0
  518. package/dist/store/delete-and-batch.js +310 -0
  519. package/dist/store/entry-reads.d.ts +92 -0
  520. package/dist/store/entry-reads.js +255 -0
  521. package/dist/store/entry-row.d.ts +67 -0
  522. package/dist/store/entry-row.js +208 -0
  523. package/dist/store/entry-writes.d.ts +46 -0
  524. package/dist/store/entry-writes.js +148 -0
  525. package/dist/store/handoffs.d.ts +26 -0
  526. package/dist/store/handoffs.js +184 -0
  527. package/dist/store/index-and-stats.d.ts +52 -0
  528. package/dist/store/index-and-stats.js +214 -0
  529. package/dist/store/markdown.d.ts +10 -0
  530. package/dist/store/markdown.js +108 -0
  531. package/dist/store/mirrors.d.ts +49 -0
  532. package/dist/store/mirrors.js +312 -0
  533. package/dist/store/open.d.ts +15 -0
  534. package/dist/store/open.js +223 -0
  535. package/dist/store/rows.d.ts +178 -0
  536. package/dist/store/rows.js +158 -0
  537. package/dist/store/search-rows.d.ts +86 -0
  538. package/dist/store/search-rows.js +254 -0
  539. package/dist/store/sessions.d.ts +83 -0
  540. package/dist/store/sessions.js +272 -0
  541. package/dist/store/summaries.d.ts +94 -0
  542. package/dist/store/summaries.js +377 -0
  543. package/dist/store/tenant-lookup.d.ts +12 -0
  544. package/dist/store/tenant-lookup.js +16 -0
  545. package/dist/store-cards.js +2 -1
  546. package/dist/summary-dirty.d.ts +4 -0
  547. package/dist/summary-dirty.js +32 -0
  548. package/dist/support-bundle.js +4 -3
  549. package/dist/tenant.js +2 -2
  550. package/dist/token-ledger.js +1 -0
  551. package/dist/tokenize.d.ts +2 -0
  552. package/dist/tokenize.js +16 -0
  553. package/dist/transcript-tail.d.ts +7 -0
  554. package/dist/transcript-tail.js +48 -0
  555. package/dist/vector-store.d.ts +27 -0
  556. package/dist/vector-store.js +210 -0
  557. package/dist/version.d.ts +2 -2
  558. package/dist/version.js +2 -2
  559. package/dist/working-memory.js +1 -1
  560. package/dist/yaml.js +36 -11
  561. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  562. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  563. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  564. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  565. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  566. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  567. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  568. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  569. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  570. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  571. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  572. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  573. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  574. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  575. package/dist-ui/index.html +3 -25
  576. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  577. package/extensions/openclaw-plugin/package.json +1 -1
  578. package/openclaw.plugin.json +1 -1
  579. package/package.json +2 -1
  580. package/dist/capture.d.ts +0 -155
  581. package/dist/capture.js +0 -1293
  582. package/dist/consolidate.d.ts +0 -58
  583. package/dist/consolidate.js +0 -1123
  584. package/dist/graph.d.ts +0 -245
  585. package/dist/hooks.d.ts +0 -208
  586. package/dist/hooks.js +0 -1073
  587. package/dist/importers.js +0 -897
  588. package/dist/predictions.js +0 -620
  589. package/dist/search.d.ts +0 -320
  590. package/dist/search.js +0 -968
  591. package/dist/store.d.ts +0 -744
  592. package/dist/store.js +0 -3372
  593. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  594. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  595. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  596. 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,148 +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;
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 {
181
- return null;
182
- }
183
- if (!pipelineFn)
184
- return null;
185
- // The Qdrant-vendored bundle (used in egress-restricted sandboxes) ships
186
- // only `onnx/model.onnx` (FP32). The HF default ships `model_quantized.onnx`
187
- // too. When pointing at a local cache, pick the variant that's on disk.
188
- const cacheRoot = process.env.HIPPO_MODEL_CACHE?.trim();
189
- const quantized = !cacheRoot
190
- || fs.existsSync(path.join(cacheRoot, model, 'onnx', 'model_quantized.onnx'));
191
- try {
192
- const instance = await pipelineFn('feature-extraction', model, { quantized });
193
- _pipelineInstances.set(model, instance);
194
- return instance;
195
- }
196
- catch {
197
- return null;
198
- }
199
- finally {
200
- _pipelineLoading.delete(model);
201
- }
202
- })();
203
- _pipelineLoading.set(model, loading);
204
- return loading;
205
- }
206
- export function resolveEmbeddingModel(hippoRoot, explicitModel) {
207
- const direct = explicitModel?.trim();
208
- if (direct)
209
- return direct;
210
- try {
211
- const configured = loadConfig(hippoRoot).embeddings.model?.trim();
212
- if (configured)
213
- return configured;
214
- }
215
- catch {
216
- // Fall back to the default model when config cannot be read.
217
- }
218
- return DEFAULT_EMBEDDING_MODEL;
219
- }
220
72
  function loadStoredEmbeddingModel(hippoRoot) {
221
73
  try {
222
74
  const db = openHippoDb(hippoRoot);
@@ -228,7 +80,8 @@ function loadStoredEmbeddingModel(hippoRoot) {
228
80
  closeHippoDb(db);
229
81
  }
230
82
  }
231
- catch {
83
+ catch (err) {
84
+ log.debug(`stored embedding model unreadable: ${err instanceof Error ? err.message : String(err)}`);
232
85
  return null;
233
86
  }
234
87
  }
@@ -251,7 +104,8 @@ export function resolveIndexedEmbeddingModel(hippoRoot, index) {
251
104
  const stored = loadStoredEmbeddingModel(hippoRoot);
252
105
  if (stored)
253
106
  return stored;
254
- 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;
255
109
  }
256
110
  export function embeddingModelRequiresReindex(hippoRoot, model, index) {
257
111
  const stored = resolveIndexedEmbeddingModel(hippoRoot, index);
@@ -296,39 +150,6 @@ function resetPhysicsFromIndex(hippoRoot, entries, index) {
296
150
  function noteSkippedEmbedding(id) {
297
151
  log.warn('memory not embedded; the next embed run retries it', { id });
298
152
  }
299
- /**
300
- * Get an embedding vector for a piece of text.
301
- * Returns an empty array if transformers is not available or fails.
302
- *
303
- * Pass `role: 'query'` / `'passage'` to engage asymmetric prefixing for
304
- * model families that require it (currently intfloat/e5-*). Omitting `role`
305
- * keeps the legacy symmetric behavior (no prefix), so BGE / MiniLM callers
306
- * don't need to change.
307
- */
308
- export async function getEmbedding(text, model = DEFAULT_EMBEDDING_MODEL, role) {
309
- if (!isEmbeddingAvailable())
310
- return [];
311
- try {
312
- const pipe = await loadPipeline(model);
313
- if (!pipe)
314
- return [];
315
- const prefix = prefixFor(model, role);
316
- const input = prefix ? `${prefix}${text}` : text;
317
- // SAFETY: pipe() is a Transformers.js feature-extraction pipeline call;
318
- // its untyped output is read defensively below (only `.data`, cast on
319
- // the return line to the documented Float32Array tensor shape).
320
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
321
- const output = await pipe(input, { pooling: poolingFor(model), normalize: true });
322
- // SAFETY: output.data is a Float32Array per the feature-extraction
323
- // pipeline's documented tensor output shape.
324
- return Array.from(output.data);
325
- }
326
- catch (err) {
327
- // The caller sees `[]` and names the memory; the reason only shows at debug.
328
- log.debug(`local embedding failed: ${err instanceof Error ? err.message : String(err)}`);
329
- return [];
330
- }
331
- }
332
153
  /**
333
154
  * Cosine similarity between two vectors. Handles unnormalized vectors.
334
155
  * Returns 0 for empty or mismatched vectors.
@@ -350,85 +171,30 @@ export function cosineSimilarity(a, b) {
350
171
  // Clamp to [-1, 1] to handle floating point drift
351
172
  return Math.min(1, Math.max(-1, dot / denom));
352
173
  }
353
- const EMBEDDINGS_FILE = 'embeddings.json';
354
- // Never equal to a real index identity, so the next embed run treats it as a model change and rebuilds every vector.
355
- const QUARANTINED_INDEX_IDENTITY = 'quarantined-corrupt-index';
356
- function isErrnoCode(err, code) {
357
- return err instanceof Error && 'code' in err && err.code === code;
358
- }
359
- function parseEmbeddingIndex(raw) {
360
- try {
361
- const parsed = JSON.parse(raw);
362
- // SAFETY: saveEmbeddingIndex is the only writer and always writes this shape; anything that is not an object is corrupt.
363
- return parsed instanceof Object && !Array.isArray(parsed) ? parsed : null;
364
- }
365
- catch {
366
- return null;
367
- }
368
- }
369
- /** Move a corrupt index aside and flag a full rebuild, so no later save can write over the only copy of those bytes. */
370
- function quarantineCorruptIndex(hippoRoot, fp) {
371
- const aside = `${fp}.corrupt-${new Date().toISOString().replace(/[:.]/g, '-')}-${process.pid}`;
372
- try {
373
- fs.renameSync(fp, aside);
374
- }
375
- catch (err) {
376
- if (isErrnoCode(err, 'ENOENT'))
377
- return;
378
- // A rename blocked by an open handle (Windows) still gets a copy kept; if the copy fails too, the throw stops the save.
379
- fs.copyFileSync(fp, aside, fs.constants.COPYFILE_EXCL);
380
- }
381
- 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);
382
176
  try {
383
- const db = openHippoDb(hippoRoot);
384
- try {
385
- setMeta(db, EMBEDDING_MODEL_META_KEY, QUARANTINED_INDEX_IDENTITY);
386
- }
387
- finally {
388
- closeHippoDb(db);
389
- }
177
+ return fn(db);
390
178
  }
391
- catch (err) {
392
- 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);
393
181
  }
394
182
  }
395
- /**
396
- * 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.
397
- */
183
+ /** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
398
184
  export function loadEmbeddingIndex(hippoRoot) {
399
- const fp = path.join(hippoRoot, EMBEDDINGS_FILE);
400
- let raw;
401
- try {
402
- raw = fs.readFileSync(fp, 'utf8');
403
- }
404
- catch (err) {
405
- if (isErrnoCode(err, 'ENOENT'))
406
- return {};
407
- throw err;
408
- }
409
- const index = parseEmbeddingIndex(raw);
410
- if (index)
411
- return index;
412
- quarantineCorruptIndex(hippoRoot, fp);
413
- return {};
185
+ return Object.fromEntries(withVectorDb(hippoRoot, (db) => loadVectors(db)));
414
186
  }
415
- /**
416
- * Save the embedding index to disk.
417
- */
418
- export function saveEmbeddingIndex(hippoRoot, index) {
419
- const fp = path.join(hippoRoot, EMBEDDINGS_FILE);
420
- const tmp = fp + '.tmp';
421
- fs.writeFileSync(tmp, JSON.stringify(index), 'utf8');
422
- try {
423
- fs.renameSync(tmp, fp);
424
- }
425
- catch (err) {
426
- try {
427
- fs.unlinkSync(tmp);
428
- }
429
- catch { /* best-effort cleanup */ }
430
- throw err;
431
- }
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, '')));
432
198
  }
433
199
  const EMBED_LOCK_FILE = 'embeddings.lock';
434
200
  const EMBED_LOCK_WAIT_MS = 10_000;
@@ -492,7 +258,7 @@ async function acquireEmbedFileLock(hippoRoot) {
492
258
  continue;
493
259
  }
494
260
  if (Date.now() >= deadline)
495
- 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}`);
496
262
  await new Promise((r) => setTimeout(r, 50));
497
263
  }
498
264
  }
@@ -523,7 +289,7 @@ function warnEmbedFailureOnce(source, rawMessage) {
523
289
  _embedFailureWarned = true;
524
290
  // Strict scrub: this line can land in a hook log file, and an API may echo the key back in its error body.
525
291
  const message = redactSecretsStrict(rawMessage).replace(/\s+/g, ' ').replace(/\.+$/, '');
526
- console.error(`hippo: embedding failed (${source}): ${message}. Memories are stored without embeddings until this is fixed.`);
292
+ log.warn(`embedding failed (${source}): ${message}. Memories are stored without embeddings until this is fixed.`);
527
293
  }
528
294
  /**
529
295
  * Embed a single memory entry and cache the result in the embedding index.
@@ -547,15 +313,14 @@ export async function embedMemory(hippoRoot, entry, model) {
547
313
  // where failures surface. On any failure we leave the existing index as-is.
548
314
  try {
549
315
  const identity = provider.id;
550
- const existingIndex = loadEmbeddingIndex(hippoRoot);
551
- if (embeddingModelRequiresReindex(hippoRoot, identity, existingIndex)) {
316
+ if (embeddingModelRequiresReindex(hippoRoot, identity)) {
552
317
  // L9: host-wide rebuild. The embedding index is keyed by entry.id
553
318
  // (which is tenant-scoped) but the index itself is one per hippoRoot.
554
319
  // Cross-tenant content equivalence is visible at the vector level.
555
320
  // Per-tenant indices would be a larger architecture change.
556
321
  const entries = loadAllEntries(hippoRoot);
557
322
  const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
558
- saveEmbeddingIndex(hippoRoot, rebuiltIndex);
323
+ saveEmbeddingIndex(hippoRoot, rebuiltIndex, embeddingIndexIdentity(identity));
559
324
  saveStoredEmbeddingModel(hippoRoot, identity);
560
325
  resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
561
326
  return;
@@ -564,9 +329,7 @@ export async function embedMemory(hippoRoot, entry, model) {
564
329
  const [vector] = await provider.embed([text], 'passage');
565
330
  if (!vector || vector.length === 0)
566
331
  return;
567
- const index = existingIndex;
568
- index[entry.id] = vector;
569
- saveEmbeddingIndex(hippoRoot, index);
332
+ withVectorDb(hippoRoot, (db) => upsertVectors(db, [[entry.id, vector]], embeddingIndexIdentity(identity)));
570
333
  saveStoredEmbeddingModel(hippoRoot, identity);
571
334
  // Initialize physics state for this memory
572
335
  try {
@@ -591,7 +354,7 @@ export async function embedMemory(hippoRoot, entry, model) {
591
354
  warnEmbedFailureOnce(provider.kind, err instanceof Error ? err.message : String(err));
592
355
  }
593
356
  }).catch((err) => {
594
- console.error(`hippo: skipped embedding ${entry.id} (${err instanceof Error ? err.message : String(err)}); run 'hippo embed' to backfill`);
357
+ log.warn(`skipped embedding ${entry.id} (${err instanceof Error ? err.message : String(err)}); run 'hippo embed' to backfill`);
595
358
  });
596
359
  }
597
360
  /**
@@ -609,7 +372,7 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
609
372
  if (provider.kind !== 'local' &&
610
373
  cfg.enabled !== false &&
611
374
  provider.keyEnv &&
612
- !process.env[provider.keyEnv]?.trim()) {
375
+ !envByName(provider.keyEnv)?.trim()) {
613
376
  throw new Error(`Embedding provider '${provider.kind}' is configured but ${provider.keyEnv} is not set.`);
614
377
  }
615
378
  return 0;
@@ -620,30 +383,25 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
620
383
  // entries into the per-host embedding index. Per-tenant filtering would
621
384
  // produce partial indices and break recall.
622
385
  const entries = loadAllEntries(hippoRoot);
623
- const index = loadEmbeddingIndex(hippoRoot);
624
- if (embeddingModelRequiresReindex(hippoRoot, identity, index)) {
386
+ const model = embeddingIndexIdentity(identity);
387
+ if (embeddingModelRequiresReindex(hippoRoot, identity)) {
625
388
  const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
626
- saveEmbeddingIndex(hippoRoot, rebuiltIndex);
389
+ saveEmbeddingIndex(hippoRoot, rebuiltIndex, model);
627
390
  saveStoredEmbeddingModel(hippoRoot, identity);
628
391
  resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
629
392
  return Object.keys(rebuiltIndex).length;
630
393
  }
631
- let dirty = false;
632
- // Prune orphaned embeddings for deleted memories
633
- const activeIds = new Set(entries.map((e) => e.id));
634
- for (const id of Object.keys(index)) {
635
- if (!activeIds.has(id)) {
636
- delete index[id];
637
- dirty = true;
638
- }
639
- }
394
+ const embedded = withVectorDb(hippoRoot, (db) => {
395
+ deleteOrphanVectors(db);
396
+ return storedVectorIds(db);
397
+ });
640
398
  // Embed entries without a cached vector in save-checkpointed chunks.
641
399
  // provider.embed batches internally (one HTTP request per batchSize for API
642
400
  // providers; sequential for local). A `[]` row means that single item could
643
401
  // not be embedded and is left for a later run (resumable). On a hard provider
644
402
  // failure mid-backfill we persist the chunks already embedded this run rather
645
403
  // than discarding paid progress, then stop and resume on the next run.
646
- const pending = entries.filter((e) => !index[e.id]);
404
+ const pending = entries.filter((e) => !embedded.has(e.id));
647
405
  let count = 0;
648
406
  // Initialized to `undefined` (not a known-evidence literal like `null`) so
649
407
  // it stays a plain `unknown` binding for the arbitrary caught value below;
@@ -662,24 +420,15 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
662
420
  backfillError = err;
663
421
  break;
664
422
  }
665
- let chunkDirty = false;
423
+ const rows = [];
666
424
  for (let j = 0; j < chunk.length; j++) {
667
425
  const vec = vectors[j];
668
- if (vec && vec.length > 0) {
669
- index[chunk[j].id] = vec;
670
- count++;
671
- dirty = true;
672
- chunkDirty = true;
673
- }
674
- else {
426
+ if (vec && vec.length > 0)
427
+ rows.push([chunk[j].id, vec]);
428
+ else
675
429
  noteSkippedEmbedding(chunk[j].id);
676
- }
677
430
  }
678
- if (chunkDirty)
679
- saveEmbeddingIndex(hippoRoot, index);
680
- }
681
- if (dirty) {
682
- saveEmbeddingIndex(hippoRoot, index);
431
+ count += withVectorDb(hippoRoot, (db) => upsertVectors(db, rows, model));
683
432
  }
684
433
  saveStoredEmbeddingModel(hippoRoot, identity);
685
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