hippo-memory 1.70.0 → 1.71.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 (629) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/claude-code.d.ts +4 -2
  3. package/dist/agent-memories/claude-code.js +14 -5
  4. package/dist/agent-memories/files.js +23 -12
  5. package/dist/agent-memories/markdown.d.ts +1 -3
  6. package/dist/agent-memories/markdown.js +1 -3
  7. package/dist/agent-memories/report.js +2 -1
  8. package/dist/agent-memories/sync.d.ts +4 -2
  9. package/dist/agent-memories/sync.js +10 -5
  10. package/dist/api/assemble.d.ts +7 -44
  11. package/dist/api/assemble.js +2 -22
  12. package/dist/api/audit.d.ts +5 -1
  13. package/dist/api/audit.js +9 -1
  14. package/dist/api/auth.d.ts +13 -22
  15. package/dist/api/auth.js +34 -24
  16. package/dist/api/auto-sleep.js +2 -2
  17. package/dist/api/availability.d.ts +2 -15
  18. package/dist/api/availability.js +2 -15
  19. package/dist/api/context-select.js +3 -4
  20. package/dist/api/context-types.d.ts +10 -35
  21. package/dist/api/context.d.ts +5 -22
  22. package/dist/api/context.js +21 -38
  23. package/dist/api/dormant.d.ts +5 -21
  24. package/dist/api/dormant.js +7 -26
  25. package/dist/api/drill-down.d.ts +7 -46
  26. package/dist/api/drill-down.js +5 -26
  27. package/dist/api/forget.d.ts +5 -24
  28. package/dist/api/forget.js +5 -28
  29. package/dist/api/graph.d.ts +8 -0
  30. package/dist/api/graph.js +7 -0
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.js +2 -0
  33. package/dist/api/instruction-detect.js +16 -5
  34. package/dist/api/ledger-db.d.ts +2 -1
  35. package/dist/api/ledger-db.js +5 -3
  36. package/dist/api/memories.d.ts +5 -0
  37. package/dist/api/memories.js +7 -0
  38. package/dist/api/objects.d.ts +9 -0
  39. package/dist/api/objects.js +11 -0
  40. package/dist/api/on-store.js +5 -3
  41. package/dist/api/predictions.d.ts +9 -0
  42. package/dist/api/predictions.js +18 -0
  43. package/dist/api/promote.d.ts +13 -17
  44. package/dist/api/promote.js +11 -19
  45. package/dist/api/prompt-hook.d.ts +4 -4
  46. package/dist/api/prompt-hook.js +10 -9
  47. package/dist/api/recall-cli.d.ts +55 -0
  48. package/dist/api/recall-cli.js +94 -0
  49. package/dist/api/recall-core.js +14 -6
  50. package/dist/api/recall-finish.d.ts +53 -0
  51. package/dist/api/recall-finish.js +30 -0
  52. package/dist/api/recall-history.d.ts +17 -84
  53. package/dist/api/recall-history.js +15 -88
  54. package/dist/api/recall-pipeline.d.ts +2 -3
  55. package/dist/api/recall-pipeline.js +16 -9
  56. package/dist/api/recall-types.d.ts +64 -304
  57. package/dist/api/recall.d.ts +5 -33
  58. package/dist/api/recall.js +59 -60
  59. package/dist/api/refine.d.ts +7 -0
  60. package/dist/api/refine.js +10 -0
  61. package/dist/api/remember-local.d.ts +57 -0
  62. package/dist/api/remember-local.js +90 -0
  63. package/dist/api/remember.d.ts +18 -1
  64. package/dist/api/remember.js +13 -1
  65. package/dist/api/sleep-run.d.ts +1 -3
  66. package/dist/api/sleep-run.js +17 -21
  67. package/dist/api/sleep.d.ts +9 -28
  68. package/dist/api/tokens.d.ts +3 -10
  69. package/dist/api/tokens.js +3 -10
  70. package/dist/api/types.d.ts +6 -29
  71. package/dist/api/types.js +4 -22
  72. package/dist/capture/command.d.ts +4 -12
  73. package/dist/capture/command.js +6 -22
  74. package/dist/capture/compact.d.ts +4 -15
  75. package/dist/capture/compact.js +16 -25
  76. package/dist/capture/compaction-record.js +101 -69
  77. package/dist/capture/compaction-spool.d.ts +1 -1
  78. package/dist/capture/compaction-spool.js +1 -1
  79. package/dist/capture/session-digest.d.ts +1 -1
  80. package/dist/capture/session-digest.js +13 -7
  81. package/dist/capture/transcript.d.ts +2 -10
  82. package/dist/capture/transcript.js +4 -18
  83. package/dist/cli/api-context.d.ts +3 -0
  84. package/dist/cli/api-context.js +6 -0
  85. package/dist/cli/audit-prune.d.ts +6 -39
  86. package/dist/cli/audit-prune.js +6 -39
  87. package/dist/cli/audit.d.ts +1 -1
  88. package/dist/cli/audit.js +33 -34
  89. package/dist/cli/auth.d.ts +2 -2
  90. package/dist/cli/auth.js +57 -39
  91. package/dist/cli/briefs.d.ts +4 -4
  92. package/dist/cli/briefs.js +18 -22
  93. package/dist/cli/card.d.ts +2 -2
  94. package/dist/cli/card.js +31 -32
  95. package/dist/cli/client.d.ts +7 -27
  96. package/dist/cli/client.js +24 -43
  97. package/dist/cli/compact-resume-payload.js +3 -2
  98. package/dist/cli/context.d.ts +1 -2
  99. package/dist/cli/context.js +12 -8
  100. package/dist/cli/continuity.d.ts +6 -6
  101. package/dist/cli/continuity.js +62 -64
  102. package/dist/cli/correction-latency.d.ts +2 -14
  103. package/dist/cli/correction-latency.js +2 -14
  104. package/dist/cli/curate.d.ts +13 -17
  105. package/dist/cli/curate.js +68 -92
  106. package/dist/cli/dag.d.ts +4 -4
  107. package/dist/cli/dag.js +33 -27
  108. package/dist/cli/decisions.d.ts +4 -4
  109. package/dist/cli/decisions.js +33 -47
  110. package/dist/cli/eval.js +15 -13
  111. package/dist/cli/exit.d.ts +6 -0
  112. package/dist/cli/exit.js +11 -0
  113. package/dist/cli/explain.d.ts +1 -2
  114. package/dist/cli/explain.js +6 -4
  115. package/dist/cli/flag-values.d.ts +6 -1
  116. package/dist/cli/flag-values.js +27 -10
  117. package/dist/cli/flags.d.ts +1 -0
  118. package/dist/cli/flags.js +1 -1
  119. package/dist/cli/github.d.ts +14 -0
  120. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  121. package/dist/cli/goals.d.ts +2 -2
  122. package/dist/cli/goals.js +46 -50
  123. package/dist/cli/hook-runtime.d.ts +9 -27
  124. package/dist/cli/hook-runtime.js +15 -31
  125. package/dist/cli/init.d.ts +2 -2
  126. package/dist/cli/init.js +6 -12
  127. package/dist/cli/install-steps.js +3 -12
  128. package/dist/cli/last-sleep.d.ts +2 -1
  129. package/dist/cli/last-sleep.js +3 -0
  130. package/dist/cli/maintenance.d.ts +4 -4
  131. package/dist/cli/maintenance.js +14 -19
  132. package/dist/cli/object-verbs.js +4 -3
  133. package/dist/cli/owner-validation.d.ts +5 -28
  134. package/dist/cli/owner-validation.js +5 -28
  135. package/dist/cli/playbooks.d.ts +4 -4
  136. package/dist/cli/playbooks.js +23 -28
  137. package/dist/cli/print.d.ts +2 -5
  138. package/dist/cli/print.js +1 -4
  139. package/dist/cli/projects.d.ts +2 -2
  140. package/dist/cli/projects.js +1 -3
  141. package/dist/cli/provenance-coverage.d.ts +2 -6
  142. package/dist/cli/provenance-coverage.js +2 -6
  143. package/dist/cli/quality-repair-once.js +2 -2
  144. package/dist/cli/recall.d.ts +2 -4
  145. package/dist/cli/recall.js +55 -131
  146. package/dist/cli/refine-llm.d.ts +5 -31
  147. package/dist/cli/refine-llm.js +9 -36
  148. package/dist/cli/remember.d.ts +3 -3
  149. package/dist/cli/remember.js +122 -180
  150. package/dist/cli/scheduler.d.ts +2 -17
  151. package/dist/cli/scheduler.js +12 -18
  152. package/dist/cli/serve.js +21 -12
  153. package/dist/cli/session-hooks.d.ts +10 -18
  154. package/dist/cli/session-hooks.js +112 -113
  155. package/dist/cli/setup.d.ts +4 -4
  156. package/dist/cli/setup.js +19 -21
  157. package/dist/cli/shared.d.ts +9 -23
  158. package/dist/cli/shared.js +9 -32
  159. package/dist/cli/slack.d.ts +2 -2
  160. package/dist/cli/slack.js +19 -23
  161. package/dist/cli/sleep.d.ts +3 -2
  162. package/dist/cli/sleep.js +15 -16
  163. package/dist/cli/status.d.ts +9 -12
  164. package/dist/cli/status.js +55 -98
  165. package/dist/cli/stdin.d.ts +4 -6
  166. package/dist/cli/stdin.js +2 -3
  167. package/dist/cli/transfer.d.ts +9 -9
  168. package/dist/cli/transfer.js +66 -89
  169. package/dist/cli/usage.js +11 -5
  170. package/dist/cli.d.ts +66 -448
  171. package/dist/cli.js +87 -263
  172. package/dist/connectors/github/backfill.d.ts +5 -25
  173. package/dist/connectors/github/backfill.js +14 -49
  174. package/dist/connectors/github/deletion.d.ts +4 -18
  175. package/dist/connectors/github/deletion.js +2 -15
  176. package/dist/connectors/github/dlq.d.ts +8 -33
  177. package/dist/connectors/github/dlq.js +12 -29
  178. package/dist/connectors/github/ingest.d.ts +2 -6
  179. package/dist/connectors/github/ingest.js +4 -10
  180. package/dist/connectors/github/octokit-client.d.ts +4 -16
  181. package/dist/connectors/github/octokit-client.js +27 -24
  182. package/dist/connectors/github/ratelimit.d.ts +3 -14
  183. package/dist/connectors/github/ratelimit.js +3 -14
  184. package/dist/connectors/github/scope.d.ts +3 -5
  185. package/dist/connectors/github/scope.js +3 -5
  186. package/dist/connectors/github/signature.d.ts +4 -26
  187. package/dist/connectors/github/signature.js +4 -26
  188. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  189. package/dist/connectors/github/tenant-routing.js +4 -26
  190. package/dist/connectors/github/transform.js +2 -16
  191. package/dist/connectors/github/types.d.ts +3 -15
  192. package/dist/connectors/github/types.js +2 -9
  193. package/dist/connectors/github/webhook.d.ts +2 -16
  194. package/dist/connectors/github/webhook.js +6 -22
  195. package/dist/connectors/slack/backfill.d.ts +4 -17
  196. package/dist/connectors/slack/backfill.js +4 -13
  197. package/dist/connectors/slack/dlq.d.ts +2 -19
  198. package/dist/connectors/slack/dlq.js +2 -19
  199. package/dist/connectors/slack/ingest.d.ts +2 -3
  200. package/dist/connectors/slack/ingest.js +2 -3
  201. package/dist/connectors/slack/scope.d.ts +2 -8
  202. package/dist/connectors/slack/scope.js +2 -8
  203. package/dist/connectors/slack/signature.d.ts +1 -6
  204. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  205. package/dist/connectors/slack/tenant-routing.js +2 -21
  206. package/dist/connectors/slack/transform.d.ts +2 -18
  207. package/dist/connectors/slack/transform.js +2 -18
  208. package/dist/connectors/slack/types.d.ts +3 -9
  209. package/dist/connectors/slack/types.js +2 -4
  210. package/dist/connectors/slack/web-client.js +33 -27
  211. package/dist/connectors/slack/webhook.d.ts +2 -19
  212. package/dist/connectors/slack/webhook.js +5 -26
  213. package/dist/connectors/slack/workspaces.d.ts +4 -24
  214. package/dist/connectors/slack/workspaces.js +4 -24
  215. package/dist/consolidate/conflicts.js +6 -14
  216. package/dist/consolidate/dag-summary.d.ts +8 -0
  217. package/dist/consolidate/dag-summary.js +41 -0
  218. package/dist/consolidate/dag.d.ts +5 -28
  219. package/dist/consolidate/dag.js +14 -75
  220. package/dist/consolidate/decay.js +7 -19
  221. package/dist/consolidate/dedupe.d.ts +6 -52
  222. package/dist/consolidate/dedupe.js +13 -71
  223. package/dist/consolidate/flush-units.d.ts +3 -4
  224. package/dist/consolidate/flush-units.js +3 -3
  225. package/dist/consolidate/half-life-migration.d.ts +3 -26
  226. package/dist/consolidate/half-life-migration.js +11 -28
  227. package/dist/consolidate/llm-passes.js +4 -21
  228. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  229. package/dist/consolidate/memory-value-weights.js +2 -13
  230. package/dist/consolidate/memory-value.d.ts +11 -84
  231. package/dist/consolidate/memory-value.js +16 -104
  232. package/dist/consolidate/merge.js +10 -31
  233. package/dist/consolidate/merged-row.js +2 -1
  234. package/dist/consolidate/physics-pass.js +1 -3
  235. package/dist/consolidate/replay.d.ts +6 -38
  236. package/dist/consolidate/replay.js +14 -52
  237. package/dist/consolidate/run.js +1 -1
  238. package/dist/consolidate/sleep.d.ts +1 -8
  239. package/dist/consolidate/sleep.js +5 -17
  240. package/dist/consolidate/trace.d.ts +3 -18
  241. package/dist/consolidate/trace.js +3 -18
  242. package/dist/consolidate/traces.js +6 -22
  243. package/dist/core/ablation.d.ts +4 -91
  244. package/dist/core/ablation.js +4 -91
  245. package/dist/core/ambient.d.ts +1 -8
  246. package/dist/core/ambient.js +1 -8
  247. package/dist/core/capture-contract.d.ts +4 -2
  248. package/dist/core/capture-contract.js +4 -2
  249. package/dist/core/card.d.ts +4 -1
  250. package/dist/core/card.js +8 -0
  251. package/dist/core/compare.d.ts +11 -67
  252. package/dist/core/compare.js +9 -63
  253. package/dist/core/config.d.ts +10 -24
  254. package/dist/core/config.js +13 -14
  255. package/dist/core/handoff.d.ts +1 -7
  256. package/dist/core/handoff.js +1 -7
  257. package/dist/core/memory-quality.js +1 -1
  258. package/dist/core/memory.d.ts +41 -164
  259. package/dist/core/memory.js +51 -221
  260. package/dist/core/package-root.d.ts +3 -0
  261. package/dist/core/package-root.js +5 -0
  262. package/dist/core/physics-config.d.ts +1 -4
  263. package/dist/core/physics-config.js +3 -8
  264. package/dist/core/physics.d.ts +15 -61
  265. package/dist/core/physics.js +59 -122
  266. package/dist/core/project-identity.d.ts +17 -58
  267. package/dist/core/project-identity.js +17 -38
  268. package/dist/core/project-remote.js +13 -2
  269. package/dist/core/raw-append-only.d.ts +5 -0
  270. package/dist/core/raw-append-only.js +7 -0
  271. package/dist/core/salience.d.ts +1 -7
  272. package/dist/core/salience.js +1 -7
  273. package/dist/dashboard/dashboard-actions.js +2 -2
  274. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  275. package/dist/dashboard/dashboard-snapshot.js +11 -2
  276. package/dist/dashboard/dashboard-types.d.ts +2 -1
  277. package/dist/dashboard/dashboard.d.ts +1 -0
  278. package/dist/dashboard/dashboard.js +50 -4
  279. package/dist/db/busy.d.ts +1 -1
  280. package/dist/db/busy.js +17 -8
  281. package/dist/db/connect.d.ts +1 -0
  282. package/dist/db/connect.js +3 -3
  283. package/dist/db/migrate.js +3 -3
  284. package/dist/db/migrations/types.d.ts +2 -5
  285. package/dist/db/migrations/v14.js +2 -3
  286. package/dist/db/migrations/v15.js +2 -8
  287. package/dist/db/migrations/v16.js +2 -3
  288. package/dist/db/migrations/v17.js +2 -3
  289. package/dist/db/migrations/v19.js +2 -5
  290. package/dist/db/migrations/v20.js +2 -7
  291. package/dist/db/migrations/v22.js +4 -17
  292. package/dist/db/migrations/v23.js +3 -14
  293. package/dist/db/migrations/v24.js +2 -4
  294. package/dist/db/migrations/v25.js +3 -8
  295. package/dist/db/migrations/v26.js +2 -13
  296. package/dist/db/migrations/v27.js +3 -11
  297. package/dist/db/migrations/v28.js +2 -14
  298. package/dist/db/migrations/v29.js +4 -18
  299. package/dist/db/migrations/v30.js +4 -16
  300. package/dist/db/migrations/v31.js +2 -15
  301. package/dist/db/migrations/v32.js +4 -22
  302. package/dist/db/migrations/v33.js +2 -15
  303. package/dist/db/migrations/v34.js +2 -11
  304. package/dist/db/migrations/v35.js +2 -11
  305. package/dist/db/migrations/v36.js +2 -11
  306. package/dist/db/migrations/v37.js +8 -33
  307. package/dist/db/migrations/v38.js +5 -38
  308. package/dist/db/migrations/v39.js +9 -20
  309. package/dist/db/migrations/v40.js +2 -9
  310. package/dist/db/migrations/v41.js +2 -24
  311. package/dist/db/migrations/v43.js +1 -1
  312. package/dist/db/migrations/v44.js +2 -8
  313. package/dist/db/migrations/v45.js +2 -7
  314. package/dist/db/migrations/v47.js +2 -3
  315. package/dist/db/migrations/v51.js +1 -1
  316. package/dist/db/open.d.ts +2 -0
  317. package/dist/db/open.js +17 -1
  318. package/dist/db/physics-state.d.ts +6 -22
  319. package/dist/db/physics-state.js +25 -36
  320. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  321. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  322. package/dist/db/vector-store.d.ts +2 -0
  323. package/dist/db/vector-store.js +8 -1
  324. package/dist/doctor.js +74 -19
  325. package/dist/entry/session-text.js +2 -1
  326. package/dist/eval/eval-stats.d.ts +15 -53
  327. package/dist/eval/eval-stats.js +12 -42
  328. package/dist/eval/eval-suite.d.ts +2 -13
  329. package/dist/eval/eval-suite.js +74 -34
  330. package/dist/eval/eval.d.ts +6 -24
  331. package/dist/eval/eval.js +7 -34
  332. package/dist/eval/judgment.d.ts +0 -3
  333. package/dist/eval/judgment.js +19 -11
  334. package/dist/extensions/openclaw-plugin/index.js +1 -1
  335. package/dist/graph/extract.d.ts +5 -27
  336. package/dist/graph/extract.js +7 -33
  337. package/dist/graph/recall.d.ts +7 -20
  338. package/dist/graph/recall.js +14 -76
  339. package/dist/graph/stream.d.ts +7 -39
  340. package/dist/graph/stream.js +11 -34
  341. package/dist/graph/view.d.ts +9 -35
  342. package/dist/graph/view.js +11 -39
  343. package/dist/hooks/codex-wrapper.js +2 -2
  344. package/dist/hooks/copilot.js +2 -1
  345. package/dist/hooks/hook-blocks.d.ts +6 -2
  346. package/dist/hooks/hook-blocks.js +37 -124
  347. package/dist/hooks/json-hooks.d.ts +4 -36
  348. package/dist/hooks/json-hooks.js +18 -57
  349. package/dist/hooks/opencode.d.ts +0 -38
  350. package/dist/hooks/opencode.js +9 -76
  351. package/dist/hooks/shared.d.ts +8 -17
  352. package/dist/hooks/shared.js +29 -20
  353. package/dist/importers/core.d.ts +12 -37
  354. package/dist/importers/core.js +9 -27
  355. package/dist/importers/markdown-parse.d.ts +8 -22
  356. package/dist/importers/markdown-parse.js +8 -25
  357. package/dist/importers/markdown.js +3 -12
  358. package/dist/importers/sources.js +7 -35
  359. package/dist/importers/vault.d.ts +2 -8
  360. package/dist/importers/vault.js +25 -81
  361. package/dist/index.d.ts +6 -2
  362. package/dist/index.js +6 -2
  363. package/dist/learn/autolearn.d.ts +14 -41
  364. package/dist/learn/autolearn.js +14 -41
  365. package/dist/learn/extract.js +2 -4
  366. package/dist/learn/forward-claim-detector.d.ts +6 -30
  367. package/dist/learn/forward-claim-detector.js +14 -66
  368. package/dist/learn/invalidation.d.ts +6 -18
  369. package/dist/learn/invalidation.js +9 -26
  370. package/dist/mcp/admin-tools.js +3 -5
  371. package/dist/mcp/memory-tools.js +4 -9
  372. package/dist/mcp/protocol.d.ts +8 -26
  373. package/dist/mcp/protocol.js +3 -6
  374. package/dist/mcp/recall-tools.js +3 -3
  375. package/dist/mcp/request.d.ts +3 -11
  376. package/dist/mcp/request.js +10 -26
  377. package/dist/mcp/server.d.ts +3 -9
  378. package/dist/mcp/server.js +5 -16
  379. package/dist/mcp/session-state.d.ts +1 -1
  380. package/dist/mcp/session-state.js +5 -11
  381. package/dist/mcp/stdio.d.ts +2 -6
  382. package/dist/mcp/stdio.js +48 -12
  383. package/dist/mcp/tools.js +5 -3
  384. package/dist/objects/customer-notes.d.ts +7 -42
  385. package/dist/objects/customer-notes.js +7 -48
  386. package/dist/objects/decisions.d.ts +12 -50
  387. package/dist/objects/decisions.js +15 -53
  388. package/dist/objects/incidents.d.ts +7 -38
  389. package/dist/objects/incidents.js +7 -41
  390. package/dist/objects/policies.d.ts +11 -89
  391. package/dist/objects/policies.js +11 -98
  392. package/dist/objects/processes.d.ts +7 -52
  393. package/dist/objects/processes.js +7 -61
  394. package/dist/objects/project-briefs.d.ts +11 -55
  395. package/dist/objects/project-briefs.js +14 -75
  396. package/dist/objects/skills.d.ts +7 -42
  397. package/dist/objects/skills.js +8 -54
  398. package/dist/postinstall.js +6 -19
  399. package/dist/predictions/planning-fallacy.d.ts +11 -34
  400. package/dist/rerankers/clef.js +3 -31
  401. package/dist/rerankers/cross-encoder.js +4 -6
  402. package/dist/rerankers/jev.js +9 -6
  403. package/dist/rerankers/llm.d.ts +2 -11
  404. package/dist/rerankers/llm.js +14 -14
  405. package/dist/rerankers/outage-warning.d.ts +2 -1
  406. package/dist/rerankers/outage-warning.js +2 -1
  407. package/dist/rerankers/remote.d.ts +1 -0
  408. package/dist/rerankers/remote.js +2 -0
  409. package/dist/rerankers/types.d.ts +2 -14
  410. package/dist/search/boosts.d.ts +0 -2
  411. package/dist/search/boosts.js +2 -2
  412. package/dist/search/goal-boost.d.ts +23 -0
  413. package/dist/search/goal-boost.js +90 -0
  414. package/dist/search/hybrid.d.ts +2 -0
  415. package/dist/search/multihop.js +2 -3
  416. package/dist/search/path-context.d.ts +5 -18
  417. package/dist/search/path-context.js +5 -18
  418. package/dist/search/physics-search.js +11 -8
  419. package/dist/search/rrf.d.ts +7 -35
  420. package/dist/search/rrf.js +5 -30
  421. package/dist/search/vector.d.ts +7 -0
  422. package/dist/search/vector.js +35 -5
  423. package/dist/server/auth.d.ts +9 -28
  424. package/dist/server/auth.js +32 -25
  425. package/dist/server/boot.d.ts +2 -21
  426. package/dist/server/boot.js +63 -96
  427. package/dist/server/client-ip.d.ts +3 -19
  428. package/dist/server/client-ip.js +5 -28
  429. package/dist/server/defaults.d.ts +3 -0
  430. package/dist/server/defaults.js +4 -0
  431. package/dist/server/key-check-bounds.d.ts +2 -1
  432. package/dist/server/lifecycle.d.ts +5 -4
  433. package/dist/server/lifecycle.js +19 -4
  434. package/dist/server/mcp-http.js +10 -44
  435. package/dist/server/rate-limit.d.ts +5 -18
  436. package/dist/server/rate-limit.js +4 -13
  437. package/dist/server/request.d.ts +4 -8
  438. package/dist/server/request.js +9 -17
  439. package/dist/server/route-table.js +42 -49
  440. package/dist/server/routes/admin.js +22 -28
  441. package/dist/server/routes/customer-notes.js +7 -12
  442. package/dist/server/routes/decisions.js +10 -17
  443. package/dist/server/routes/incidents.js +12 -20
  444. package/dist/server/routes/memories.js +12 -32
  445. package/dist/server/routes/object-routes.d.ts +0 -5
  446. package/dist/server/routes/object-routes.js +7 -15
  447. package/dist/server/routes/policies.js +10 -18
  448. package/dist/server/routes/predictions.js +13 -25
  449. package/dist/server/routes/processes.js +16 -26
  450. package/dist/server/routes/project-briefs.js +9 -16
  451. package/dist/server/routes/recall.js +10 -35
  452. package/dist/server/routes/skills.js +8 -18
  453. package/dist/server/server-detect.d.ts +9 -53
  454. package/dist/server/server-detect.js +24 -90
  455. package/dist/server/sleep-offload.js +4 -1
  456. package/dist/server/types.d.ts +12 -10
  457. package/dist/server/validation.d.ts +3 -1
  458. package/dist/server/validation.js +10 -23
  459. package/dist/server.d.ts +2 -2
  460. package/dist/server.js +3 -2
  461. package/dist/sharing/global-store.d.ts +19 -0
  462. package/dist/sharing/global-store.js +75 -0
  463. package/dist/sharing/global-sync.d.ts +6 -0
  464. package/dist/sharing/global-sync.js +80 -0
  465. package/dist/sharing/project-merge.d.ts +4 -5
  466. package/dist/sharing/project-merge.js +9 -7
  467. package/dist/sharing/scope.d.ts +4 -11
  468. package/dist/sharing/scope.js +4 -11
  469. package/dist/sharing/search-both.d.ts +60 -0
  470. package/dist/sharing/search-both.js +138 -0
  471. package/dist/sharing/share.d.ts +38 -0
  472. package/dist/sharing/share.js +226 -0
  473. package/dist/store/ambient.js +4 -9
  474. package/dist/store/audit-event.d.ts +4 -12
  475. package/dist/store/audit-event.js +4 -12
  476. package/dist/store/audit.d.ts +2 -5
  477. package/dist/store/audit.js +4 -12
  478. package/dist/store/auth.d.ts +6 -6
  479. package/dist/store/auth.js +10 -9
  480. package/dist/store/candidates.d.ts +20 -3
  481. package/dist/store/candidates.js +77 -48
  482. package/dist/store/card-detail.d.ts +2 -1
  483. package/dist/store/card-detail.js +2 -1
  484. package/dist/store/cards.d.ts +14 -9
  485. package/dist/store/cards.js +72 -126
  486. package/dist/store/conflicts.d.ts +4 -21
  487. package/dist/store/conflicts.js +71 -150
  488. package/dist/store/connectors/github.d.ts +10 -10
  489. package/dist/store/connectors/github.js +10 -10
  490. package/dist/store/dashboard-reads.js +4 -8
  491. package/dist/store/delete-and-batch.d.ts +11 -31
  492. package/dist/store/delete-and-batch.js +48 -64
  493. package/dist/store/delivery-recorder.d.ts +8 -4
  494. package/dist/store/delivery-recorder.js +25 -15
  495. package/dist/store/diagnostics.js +6 -13
  496. package/dist/store/dormant.d.ts +7 -29
  497. package/dist/store/dormant.js +15 -56
  498. package/dist/store/embeddings/index.d.ts +11 -80
  499. package/dist/store/embeddings/index.js +71 -207
  500. package/dist/store/embeddings/local.js +15 -32
  501. package/dist/store/embeddings/provider.d.ts +16 -53
  502. package/dist/store/embeddings/provider.js +41 -69
  503. package/dist/store/entry-reads.d.ts +21 -57
  504. package/dist/store/entry-reads.js +65 -126
  505. package/dist/store/entry-row.d.ts +6 -35
  506. package/dist/store/entry-row.js +9 -37
  507. package/dist/store/entry-writes.d.ts +10 -16
  508. package/dist/store/entry-writes.js +17 -35
  509. package/dist/store/goals.d.ts +3 -40
  510. package/dist/store/goals.js +21 -160
  511. package/dist/store/graph-queue.d.ts +6 -22
  512. package/dist/store/graph-queue.js +14 -45
  513. package/dist/store/graph-reads.d.ts +11 -35
  514. package/dist/store/graph-reads.js +20 -58
  515. package/dist/store/graph-rows.d.ts +3 -6
  516. package/dist/store/graph-rows.js +6 -9
  517. package/dist/store/graph-view-rows.d.ts +2 -1
  518. package/dist/store/graph-view-rows.js +2 -1
  519. package/dist/store/graph-writes.d.ts +6 -31
  520. package/dist/store/graph-writes.js +13 -37
  521. package/dist/store/half-life.d.ts +2 -1
  522. package/dist/store/half-life.js +14 -16
  523. package/dist/store/handoffs.d.ts +5 -11
  524. package/dist/store/handoffs.js +16 -34
  525. package/dist/store/index-and-stats.d.ts +6 -19
  526. package/dist/store/index-and-stats.js +34 -82
  527. package/dist/store/markdown.d.ts +2 -6
  528. package/dist/store/markdown.js +21 -20
  529. package/dist/store/mirrors.d.ts +2 -6
  530. package/dist/store/mirrors.js +14 -23
  531. package/dist/store/open.js +6 -13
  532. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  533. package/dist/store/planning-fallacy-evidence.js +8 -37
  534. package/dist/store/port.d.ts +82 -79
  535. package/dist/store/predictions.d.ts +11 -51
  536. package/dist/store/predictions.js +38 -119
  537. package/dist/{cli → store}/quality-repair.js +15 -31
  538. package/dist/store/raw-archive.d.ts +4 -16
  539. package/dist/store/raw-archive.js +14 -29
  540. package/dist/store/recall-scope.d.ts +19 -79
  541. package/dist/store/recall-scope.js +21 -82
  542. package/dist/store/recall-trace.d.ts +10 -77
  543. package/dist/store/recall-trace.js +19 -95
  544. package/dist/store/rejected-values.js +7 -19
  545. package/dist/store/rejection.d.ts +12 -58
  546. package/dist/store/rejection.js +13 -65
  547. package/dist/store/report-reads.d.ts +6 -0
  548. package/dist/store/report-reads.js +29 -0
  549. package/dist/store/rows.d.ts +9 -19
  550. package/dist/store/rows.js +36 -34
  551. package/dist/store/rule-sql.d.ts +5 -0
  552. package/dist/store/rule-sql.js +37 -0
  553. package/dist/store/search-rows.d.ts +7 -38
  554. package/dist/store/search-rows.js +14 -50
  555. package/dist/store/sessions.d.ts +10 -47
  556. package/dist/store/sessions.js +17 -73
  557. package/dist/store/sqlite/connector-events-group.js +2 -2
  558. package/dist/store/sqlite/entry-writes-group.js +2 -2
  559. package/dist/store/sqlite/error-codec.js +4 -2
  560. package/dist/store/sqlite/executor.d.ts +2 -1
  561. package/dist/store/sqlite/executor.js +2 -1
  562. package/dist/store/sqlite/local.d.ts +3 -3
  563. package/dist/store/sqlite/local.js +1 -0
  564. package/dist/store/sqlite/object-rows.js +6 -3
  565. package/dist/store/sqlite/objects-group.js +4 -2
  566. package/dist/store/sqlite/quarantine-group.js +2 -2
  567. package/dist/store/sqlite/store.d.ts +1 -4
  568. package/dist/store/sqlite/store.js +2 -3
  569. package/dist/store/sqlite/vector-reads-group.js +2 -2
  570. package/dist/store/sqlite/worker-jobs.js +1 -1
  571. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  572. package/dist/store/sqlite/worker-ops.js +13 -2
  573. package/dist/store/sqlite/worker-store.js +5 -2
  574. package/dist/store/summaries.d.ts +10 -62
  575. package/dist/store/summaries.js +34 -146
  576. package/dist/store/summary-dirty.js +1 -1
  577. package/dist/store/tenant-lookup.d.ts +6 -1
  578. package/dist/store/tenant-lookup.js +7 -0
  579. package/dist/store/tenant.d.ts +2 -16
  580. package/dist/store/tenant.js +4 -19
  581. package/dist/store/token-ledger.d.ts +13 -43
  582. package/dist/store/token-ledger.js +19 -50
  583. package/dist/store/usage-reports.js +5 -13
  584. package/dist/store/vector-index.d.ts +46 -0
  585. package/dist/store/vector-index.js +170 -0
  586. package/dist/store/working-memory.d.ts +6 -25
  587. package/dist/store/working-memory.js +18 -52
  588. package/dist/store/yaml.d.ts +1 -5
  589. package/dist/store/yaml.js +2 -6
  590. package/dist/support-bundle.js +7 -5
  591. package/dist/trust/reject-flow.js +1 -3
  592. package/dist/util/anthropic-messages.js +14 -2
  593. package/dist/util/atomic-write.d.ts +2 -1
  594. package/dist/util/atomic-write.js +35 -4
  595. package/dist/util/capped-json.d.ts +6 -0
  596. package/dist/util/capped-json.js +46 -0
  597. package/dist/util/crash-handlers.d.ts +8 -1
  598. package/dist/util/crash-handlers.js +52 -10
  599. package/dist/util/env.d.ts +13 -6
  600. package/dist/util/env.js +14 -7
  601. package/dist/util/home-path.d.ts +2 -1
  602. package/dist/util/home-path.js +4 -2
  603. package/dist/util/http-retry.d.ts +3 -1
  604. package/dist/util/http-retry.js +26 -5
  605. package/dist/util/log.d.ts +3 -2
  606. package/dist/util/log.js +25 -9
  607. package/dist/util/request-scope.d.ts +2 -1
  608. package/dist/util/request-scope.js +2 -1
  609. package/dist/util/secret-detect.d.ts +5 -30
  610. package/dist/util/secret-detect.js +13 -39
  611. package/dist/util/stored-json.d.ts +1 -1
  612. package/dist/util/stored-json.js +1 -1
  613. package/dist/util/token-text.d.ts +1 -4
  614. package/dist/util/token-text.js +1 -4
  615. package/dist/util/transcript-tail.d.ts +2 -0
  616. package/dist/util/transcript-tail.js +24 -23
  617. package/dist/util/version.d.ts +5 -20
  618. package/dist/util/version.js +5 -20
  619. package/extensions/openclaw-plugin/index.ts +1 -1
  620. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  621. package/extensions/openclaw-plugin/package.json +1 -1
  622. package/openclaw.plugin.json +1 -1
  623. package/package.json +1 -1
  624. package/dist/connectors/github/cli-impl.d.ts +0 -25
  625. package/dist/sharing/shared.d.ts +0 -187
  626. package/dist/sharing/shared.js +0 -563
  627. package/dist/store/vector-writes.d.ts +0 -13
  628. package/dist/store/vector-writes.js +0 -89
  629. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
@@ -1,102 +1,33 @@
1
- /**
2
- * Optional embedding-based semantic search for Hippo.
3
- * Uses @huggingface/transformers (local, zero API keys, ~22MB model).
4
- * Falls back silently if the library is not installed.
5
- */
1
+ /** Optional embedding-based semantic search for Hippo.
2
+ * Uses @huggingface/transformers (local, no API keys, ~22MB model); falls back silently if not installed. */
6
3
  import { MemoryEntry } from '../../core/memory.js';
7
- import { type DatabaseSyncLike } from '../../db/index.js';
8
4
  import { EMBEDDING_MODEL_META_KEY } from '../../db/vector-store.js';
9
5
  import { type EmbeddingProvider } from './provider.js';
10
6
  import type { HippoStore } from '../index.js';
11
7
  export { EMBEDDING_MODEL_META_KEY };
12
- /**
13
- * Bump whenever `embeddingInputText`'s composition changes in a way that
14
- * changes the resulting vectors for existing entries. Folded into the stored
15
- * index identity (see `embeddingIndexIdentity`) so a text-format change is
16
- * treated exactly like an embedding-model change: the next embed-touching
17
- * operation detects the mismatch and reindexes automatically. Format 2 =
18
- * `path:*` tags excluded (see `embeddingInputText`); format 1 (implicit, no
19
- * suffix) = `${content} ${tags.join(' ')}` including path tags.
20
- */
8
+ /** Bump when `embeddingInputText` changes existing vectors; folded into the stored index identity (`embeddingIndexIdentity`) so it reindexes like a model
9
+ * change. Format 2 = `path:*` tags excluded; format 1 (implicit, no suffix) included them. */
21
10
  export declare const EMBED_TEXT_FORMAT = 2;
22
- /**
23
- * The stored-index identity for a given embedding provider id: folds
24
- * `EMBED_TEXT_FORMAT` into the provider id so index-identity comparisons
25
- * automatically invalidate on either a model change OR a text-format change.
26
- * This is the ONE choke point both `embeddingModelRequiresReindex` (compare
27
- * side) and `saveStoredEmbeddingModel` (save side) go through — they MUST
28
- * version identically, or every call reindexes in a loop (or none ever do).
29
- */
11
+ /** Stored-index identity for a provider id: folds `EMBED_TEXT_FORMAT` in so a model or text-format change invalidates the index. The ONE choke point for
12
+ * compare (`embeddingModelRequiresReindex`) and save (`saveStoredEmbeddingModel`); they MUST version identically or every call reindexes. */
30
13
  export declare function embeddingIndexIdentity(providerId: string): string;
31
- /**
32
- * Build the text embedded for a memory entry: content plus its tags, joined
33
- * by a space and trimmed — the same shape as the legacy
34
- * `` `${e.content} ${e.tags.join(' ')}`.trim() `` composition, minus `path:*`
35
- * tags.
36
- *
37
- * `path:*` tags are excluded because they are auto-derived from
38
- * `process.cwd()` (see `extractPathTags` in cli.ts) and carry every path
39
- * component of the store's location, INCLUDING the store directory name
40
- * itself. That means identical content embeds to a DIFFERENT vector
41
- * depending on WHERE the store happens to live — e.g. a fresh benchmark run
42
- * under `tempfile.mkdtemp()` gets a new directory name (hence new path
43
- * tokens, hence a new vector) every single run, even with byte-identical
44
- * content ingested in byte-identical order. This was diagnosed as the
45
- * DOMINANT root cause of cross-fresh-ingest recall-rank variance measured on
46
- * LoCoMo (mean evidence-recall@5 stdev 0.0175 across 4 fresh re-ingests of
47
- * identical data; see `benchmarks/LOCOMO_INVESTIGATION.md`, "Determinism
48
- * characterization"). It is a real product defect beyond benchmarks too:
49
- * retrieval semantics should not depend on a project directory's name.
50
- *
51
- * Only `path:*` is excluded. Other tags (`conv:`, `session:`, `speaker:`,
52
- * `dia:`, `error`, `scope:`, etc.) remain embedded — they carry semantic
53
- * meaning. Path relevance at recall time is already handled explicitly by
54
- * the v39 scope-isolation layer (`origin_project`, `pathOverlapScore`), so
55
- * embedding-level path tokens are redundant with a dedicated mechanism
56
- * rather than a feature.
57
- */
14
+ /** Text embedded for an entry: content plus tags, space-joined and trimmed, minus `path:*` tags.
15
+ * `path:*` tags derive from cwd, so identical content would embed differently per store location; path relevance is handled by `pathOverlapScore`. */
58
16
  export declare function embeddingInputText(entry: {
59
17
  content: string;
60
18
  tags: string[];
61
19
  }): string;
62
- /**
63
- * Persist the stored-index identity for `model` (see `embeddingIndexIdentity`).
64
- * Versioning happens INSIDE this function, not at call sites, so every caller
65
- * — current and future — gets the identity format for free. Must stay
66
- * consistent with the compare side in `embeddingModelRequiresReindex`.
67
- */
20
+ /** Persist the stored-index identity for `model` (see `embeddingIndexIdentity`); versioning happens here, not at call sites,
21
+ * and must stay consistent with the compare side in `embeddingModelRequiresReindex`. */
68
22
  export declare function saveStoredEmbeddingModel(hippoRoot: string, model: string): void;
69
- /** What a store's vector index was built by: the stored identity, and whether any vector exists. */
70
- export interface EmbeddingIndexState {
71
- readonly storedModel: string | null;
72
- readonly hasVectors: boolean;
73
- }
74
- /** The model the index was built by: the stored identity, else the default model when vectors exist. */
75
- export declare function indexedModel(state: EmbeddingIndexState): string | null;
76
23
  /** The one rebuild rule every store applies to its indexed model. */
77
24
  export declare function indexNeedsRebuild(indexed: string | null, providerId: string): boolean;
78
- /** Whether a vector write under the index identity `model` first drops the stored index, which another model built. */
79
- export declare function replacesIndex(state: EmbeddingIndexState, model: string): boolean;
80
25
  export declare function resolveIndexedEmbeddingModel(hippoRoot: string, index?: Record<string, number[]>): string | null;
81
26
  export declare function embeddingModelRequiresReindex(hippoRoot: string, model: string, index?: Record<string, number[]>): boolean;
82
- /** hippo.db's index state, the meta row and the EXISTS on one handle. */
83
- export declare function embeddingIndexStateAt(hippoRoot: string): EmbeddingIndexState;
84
- export declare function embeddingIndexStateOn(db: DatabaseSyncLike): EmbeddingIndexState;
85
- /**
86
- * Cosine similarity between two vectors. Handles unnormalized vectors.
87
- * Returns 0 for empty or mismatched vectors.
88
- */
27
+ /** Cosine similarity; handles unnormalized vectors, returns 0 for empty or mismatched vectors. */
89
28
  export declare function cosineSimilarity(a: number[], b: number[]): number;
90
29
  /** `cosineSimilarity` over any indexable vectors; a Float32 view reads the same doubles as its number[] copy, so the score is the same. */
91
30
  export declare function cosineOf(a: ArrayLike<number>, b: ArrayLike<number>): number;
92
- /** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
93
- export declare function loadEmbeddingIndex(hippoRoot: string): Record<string, number[]>;
94
- /** Stored vectors for `ids` only. */
95
- export declare function loadStoredVectors(hippoRoot: string, ids: readonly string[]): Map<string, number[]>;
96
- /** `loadStoredVectors` as Float32 views, for a caller that only scores them. */
97
- export declare function loadStoredVectorViews(hippoRoot: string, ids: readonly string[]): Map<string, Float32Array>;
98
- /** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
99
- export declare function saveEmbeddingIndex(hippoRoot: string, index: Record<string, number[]>, model?: string): void;
100
31
  /** Embed a single memory entry and cache the result in the embedding index; with `store`, through its vectorWrites, never opening hippo.db. */
101
32
  export declare function embedMemory(hippoRoot: string, entry: MemoryEntry, model?: string, store?: HippoStore): Promise<void>;
102
33
  /** Embeds every entry with no cached vector, prunes vectors of deleted memories, and returns how many it embedded; `provider` defaults to the
@@ -1,85 +1,37 @@
1
- /**
2
- * Optional embedding-based semantic search for Hippo.
3
- * Uses @huggingface/transformers (local, zero API keys, ~22MB model).
4
- * Falls back silently if the library is not installed.
5
- */
1
+ /** Optional embedding-based semantic search for Hippo.
2
+ * Uses @huggingface/transformers (local, no API keys, ~22MB model); falls back silently if not installed. */
6
3
  import { envByName } from '../../util/env.js';
7
4
  import * as fs from 'fs';
8
5
  import * as path from 'path';
9
6
  import { randomUUID } from 'crypto';
10
- import { loadAllEntries } from '../entry-reads.js';
11
- import { openHippoDb, closeHippoDb, getMeta, rethrowIfSqliteBlocked, setMeta } from '../../db/index.js';
12
- import { EMBEDDING_MODEL_META_KEY, deleteOrphanVectors, hasStoredVectors, loadVectors, loadVectorViews, replaceAllVectors, storedVectorIds, upsertVectors, } from '../../db/vector-store.js';
13
- import { initializeParticle, savePhysicsState, loadPhysicsState, resetAllPhysicsState } from '../../db/physics-state.js';
7
+ import { chunked, loadAllEntryIds, loadEntriesByIds } from '../entry-reads.js';
8
+ import { rethrowIfSqliteBlocked } from '../../db/index.js';
9
+ import { EMBEDDING_MODEL_META_KEY } from '../../db/vector-store.js';
10
+ import { initializeParticle } from '../../db/physics-state.js';
11
+ import { indexedModel, pruneStoredVectors, replacesIndex, resetStoredParticles, saveEmbeddingIndex, saveIndexIdentity, saveStoredVectors, seedStoredParticle, storedIndexState, } from '../vector-index.js';
14
12
  import { loadConfig } from '../../core/config.js';
15
13
  import { resolveEmbeddingProvider } from './provider.js';
16
- import { DEFAULT_EMBEDDING_MODEL } from './local.js';
17
14
  import { redactSecretsStrict } from '../../util/secret-detect.js';
18
15
  import { errorMessage, log } from '../../util/log.js';
19
16
  import { StoreNotPortedError } from '../../util/sqlite-blocked.js';
20
17
  export { EMBEDDING_MODEL_META_KEY };
21
- /**
22
- * Bump whenever `embeddingInputText`'s composition changes in a way that
23
- * changes the resulting vectors for existing entries. Folded into the stored
24
- * index identity (see `embeddingIndexIdentity`) so a text-format change is
25
- * treated exactly like an embedding-model change: the next embed-touching
26
- * operation detects the mismatch and reindexes automatically. Format 2 =
27
- * `path:*` tags excluded (see `embeddingInputText`); format 1 (implicit, no
28
- * suffix) = `${content} ${tags.join(' ')}` including path tags.
29
- */
18
+ /** Bump when `embeddingInputText` changes existing vectors; folded into the stored index identity (`embeddingIndexIdentity`) so it reindexes like a model
19
+ * change. Format 2 = `path:*` tags excluded; format 1 (implicit, no suffix) included them. */
30
20
  export const EMBED_TEXT_FORMAT = 2;
31
- /**
32
- * The stored-index identity for a given embedding provider id: folds
33
- * `EMBED_TEXT_FORMAT` into the provider id so index-identity comparisons
34
- * automatically invalidate on either a model change OR a text-format change.
35
- * This is the ONE choke point both `embeddingModelRequiresReindex` (compare
36
- * side) and `saveStoredEmbeddingModel` (save side) go through — they MUST
37
- * version identically, or every call reindexes in a loop (or none ever do).
38
- */
21
+ /** Stored-index identity for a provider id: folds `EMBED_TEXT_FORMAT` in so a model or text-format change invalidates the index. The ONE choke point for
22
+ * compare (`embeddingModelRequiresReindex`) and save (`saveStoredEmbeddingModel`); they MUST version identically or every call reindexes. */
39
23
  export function embeddingIndexIdentity(providerId) {
40
24
  return `${providerId}#t${EMBED_TEXT_FORMAT}`;
41
25
  }
42
- /**
43
- * Build the text embedded for a memory entry: content plus its tags, joined
44
- * by a space and trimmed — the same shape as the legacy
45
- * `` `${e.content} ${e.tags.join(' ')}`.trim() `` composition, minus `path:*`
46
- * tags.
47
- *
48
- * `path:*` tags are excluded because they are auto-derived from
49
- * `process.cwd()` (see `extractPathTags` in cli.ts) and carry every path
50
- * component of the store's location, INCLUDING the store directory name
51
- * itself. That means identical content embeds to a DIFFERENT vector
52
- * depending on WHERE the store happens to live — e.g. a fresh benchmark run
53
- * under `tempfile.mkdtemp()` gets a new directory name (hence new path
54
- * tokens, hence a new vector) every single run, even with byte-identical
55
- * content ingested in byte-identical order. This was diagnosed as the
56
- * DOMINANT root cause of cross-fresh-ingest recall-rank variance measured on
57
- * LoCoMo (mean evidence-recall@5 stdev 0.0175 across 4 fresh re-ingests of
58
- * identical data; see `benchmarks/LOCOMO_INVESTIGATION.md`, "Determinism
59
- * characterization"). It is a real product defect beyond benchmarks too:
60
- * retrieval semantics should not depend on a project directory's name.
61
- *
62
- * Only `path:*` is excluded. Other tags (`conv:`, `session:`, `speaker:`,
63
- * `dia:`, `error`, `scope:`, etc.) remain embedded — they carry semantic
64
- * meaning. Path relevance at recall time is already handled explicitly by
65
- * the v39 scope-isolation layer (`origin_project`, `pathOverlapScore`), so
66
- * embedding-level path tokens are redundant with a dedicated mechanism
67
- * rather than a feature.
68
- */
26
+ /** Text embedded for an entry: content plus tags, space-joined and trimmed, minus `path:*` tags.
27
+ * `path:*` tags derive from cwd, so identical content would embed differently per store location; path relevance is handled by `pathOverlapScore`. */
69
28
  export function embeddingInputText(entry) {
70
29
  const tags = entry.tags.filter((t) => !t.startsWith('path:'));
71
30
  return `${entry.content} ${tags.join(' ')}`.trim();
72
31
  }
73
32
  function loadStoredEmbeddingModel(hippoRoot) {
74
33
  try {
75
- const db = openHippoDb(hippoRoot);
76
- try {
77
- const model = getMeta(db, EMBEDDING_MODEL_META_KEY, '').trim();
78
- return model || null;
79
- }
80
- finally {
81
- closeHippoDb(db);
82
- }
34
+ return storedIndexState(hippoRoot).storedModel;
83
35
  }
84
36
  catch (err) {
85
37
  rethrowIfSqliteBlocked(err);
@@ -87,82 +39,55 @@ function loadStoredEmbeddingModel(hippoRoot) {
87
39
  return null;
88
40
  }
89
41
  }
90
- /**
91
- * Persist the stored-index identity for `model` (see `embeddingIndexIdentity`).
92
- * Versioning happens INSIDE this function, not at call sites, so every caller
93
- * — current and future — gets the identity format for free. Must stay
94
- * consistent with the compare side in `embeddingModelRequiresReindex`.
95
- */
42
+ /** Persist the stored-index identity for `model` (see `embeddingIndexIdentity`); versioning happens here, not at call sites,
43
+ * and must stay consistent with the compare side in `embeddingModelRequiresReindex`. */
96
44
  export function saveStoredEmbeddingModel(hippoRoot, model) {
97
- const db = openHippoDb(hippoRoot);
98
- try {
99
- setMeta(db, EMBEDDING_MODEL_META_KEY, embeddingIndexIdentity(model));
100
- }
101
- finally {
102
- closeHippoDb(db);
103
- }
104
- }
105
- /** The model the index was built by: the stored identity, else the default model when vectors exist. */
106
- export function indexedModel(state) {
107
- return state.storedModel ?? (state.hasVectors ? DEFAULT_EMBEDDING_MODEL : null);
45
+ saveIndexIdentity(hippoRoot, embeddingIndexIdentity(model));
108
46
  }
109
47
  /** The one rebuild rule every store applies to its indexed model. */
110
48
  export function indexNeedsRebuild(indexed, providerId) {
111
49
  return indexed !== null && indexed !== embeddingIndexIdentity(providerId);
112
50
  }
113
- /** Whether a vector write under the index identity `model` first drops the stored index, which another model built. */
114
- export function replacesIndex(state, model) {
115
- const indexed = indexedModel(state);
116
- return indexed !== null && indexed !== model;
117
- }
118
51
  export function resolveIndexedEmbeddingModel(hippoRoot, index) {
119
52
  const storedModel = loadStoredEmbeddingModel(hippoRoot);
120
53
  if (storedModel)
121
54
  return storedModel;
122
- return indexedModel({ storedModel, hasVectors: index ? Object.keys(index).length > 0 : withVectorDb(hippoRoot, hasStoredVectors) });
55
+ return indexedModel({ storedModel, hasVectors: index ? Object.keys(index).length > 0 : storedIndexState(hippoRoot).hasVectors });
123
56
  }
124
57
  export function embeddingModelRequiresReindex(hippoRoot, model, index) {
125
58
  return indexNeedsRebuild(resolveIndexedEmbeddingModel(hippoRoot, index), model);
126
59
  }
127
- /** hippo.db's index state, the meta row and the EXISTS on one handle. */
128
- export function embeddingIndexStateAt(hippoRoot) {
129
- return withVectorDb(hippoRoot, embeddingIndexStateOn);
130
- }
131
- export function embeddingIndexStateOn(db) {
132
- return {
133
- storedModel: getMeta(db, EMBEDDING_MODEL_META_KEY, '').trim() || null,
134
- hasVectors: hasStoredVectors(db),
135
- };
60
+ const STORE_PAGE = 64;
61
+ /** The rows for `ids`, a page at a time and in that order; an id deleted since it was listed is skipped. */
62
+ function* entryPages(hippoRoot, ids) {
63
+ for (const page of chunked(ids, STORE_PAGE)) {
64
+ const byId = new Map(loadEntriesByIds(hippoRoot, page).map((e) => [e.id, e]));
65
+ const entries = page.flatMap((id) => byId.get(id) ?? []);
66
+ if (entries.length > 0)
67
+ yield entries;
68
+ }
136
69
  }
137
- async function rebuildEmbeddingIndex(entries, provider) {
70
+ async function rebuildEmbeddingIndex(hippoRoot, ids, provider) {
138
71
  const rebuilt = {};
139
- if (entries.length === 0)
140
- return rebuilt;
141
- const texts = entries.map((e) => embeddingInputText(e));
142
- // provider.embed batches internally; on a hard transport/auth failure it
143
- // throws, so the caller aborts WITHOUT saving a partial index (atomic
144
- // reindex: the old index + stored identity are preserved).
145
- const vectors = await provider.embed(texts, 'passage');
146
- for (let i = 0; i < entries.length; i++) {
147
- const vec = vectors[i];
148
- if (vec && vec.length > 0) {
149
- rebuilt[entries[i].id] = vec;
150
- }
151
- else {
152
- noteSkippedEmbedding(entries[i].id);
72
+ for (const entries of entryPages(hippoRoot, ids)) {
73
+ // On a hard transport/auth failure provider.embed throws, so the caller aborts WITHOUT saving
74
+ // a partial index (atomic reindex: the old index + stored identity are preserved).
75
+ const vectors = await provider.embed(entries.map((e) => embeddingInputText(e)), 'passage');
76
+ for (let i = 0; i < entries.length; i++) {
77
+ const vec = vectors[i];
78
+ if (vec && vec.length > 0) {
79
+ rebuilt[entries[i].id] = vec;
80
+ }
81
+ else {
82
+ noteSkippedEmbedding(entries[i].id);
83
+ }
153
84
  }
154
85
  }
155
86
  return rebuilt;
156
87
  }
157
- function resetPhysicsFromIndex(hippoRoot, entries, index) {
88
+ function resetPhysicsFromIndex(hippoRoot, ids, index) {
158
89
  try {
159
- const db = openHippoDb(hippoRoot);
160
- try {
161
- resetAllPhysicsState(db, entries, index);
162
- }
163
- finally {
164
- closeHippoDb(db);
165
- }
90
+ resetStoredParticles(hippoRoot, ids, index);
166
91
  }
167
92
  catch (err) {
168
93
  // Best effort: retrieval still falls back without physics state.
@@ -173,10 +98,7 @@ function resetPhysicsFromIndex(hippoRoot, entries, index) {
173
98
  function noteSkippedEmbedding(id) {
174
99
  log.warn('memory not embedded; the next embed run retries it', { id });
175
100
  }
176
- /**
177
- * Cosine similarity between two vectors. Handles unnormalized vectors.
178
- * Returns 0 for empty or mismatched vectors.
179
- */
101
+ /** Cosine similarity; handles unnormalized vectors, returns 0 for empty or mismatched vectors. */
180
102
  export function cosineSimilarity(a, b) {
181
103
  return cosineOf(a, b);
182
104
  }
@@ -198,35 +120,11 @@ export function cosineOf(a, b) {
198
120
  // Clamp to [-1, 1] to handle floating point drift
199
121
  return Math.min(1, Math.max(-1, dot / denom));
200
122
  }
201
- function withVectorDb(hippoRoot, fn) {
202
- const db = openHippoDb(hippoRoot);
203
- try {
204
- return fn(db);
205
- }
206
- finally {
207
- closeHippoDb(db);
208
- }
209
- }
210
- /** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
211
- export function loadEmbeddingIndex(hippoRoot) {
212
- return Object.fromEntries(withVectorDb(hippoRoot, (db) => loadVectors(db)));
213
- }
214
- /** Stored vectors for `ids` only. */
215
- export function loadStoredVectors(hippoRoot, ids) {
216
- return ids.length === 0 ? new Map() : withVectorDb(hippoRoot, (db) => loadVectors(db, ids));
217
- }
218
- /** `loadStoredVectors` as Float32 views, for a caller that only scores them. */
219
- export function loadStoredVectorViews(hippoRoot, ids) {
220
- return ids.length === 0 ? new Map() : withVectorDb(hippoRoot, (db) => loadVectorViews(db, ids));
221
- }
222
- /** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
223
- export function saveEmbeddingIndex(hippoRoot, index, model) {
224
- withVectorDb(hippoRoot, (db) => replaceAllVectors(db, index, model ?? getMeta(db, EMBEDDING_MODEL_META_KEY, '')));
225
- }
226
123
  const EMBED_LOCK_FILE = 'embeddings.lock';
227
124
  const EMBED_LOCK_WAIT_MS = 10_000;
228
125
  const EMBED_LOCK_OWNER = `${process.pid}:${randomUUID()}`;
229
- // In-process mutex plus an O_EXCL "<pid>:<token>" lock file: our token is a lock we leaked; our PID with another token is a live worker thread, unless the lock predates this process (a reused PID).
126
+ // In-process mutex plus an O_EXCL "<pid>:<token>" lock file: our token is a lock we leaked; our PID
127
+ // with another token is a live worker thread, unless the lock predates this process (a reused PID).
230
128
  let _embedWriteLock = Promise.resolve();
231
129
  function embedLockHolderAlive(lockPath) {
232
130
  let raw;
@@ -324,7 +222,7 @@ function warnEmbedFailureOnce(source, rawMessage) {
324
222
  const message = redactSecretsStrict(rawMessage).replace(/\s+/g, ' ').replace(/\.+$/, '');
325
223
  log.warn(`embedding failed (${source}): ${message}. Memories are stored without embeddings until this is fixed.`);
326
224
  }
327
- // store-port.ts imports this module, so its requireGroup would close an import cycle.
225
+ // requireGroup (src/store/port.ts) would close an import cycle with this module.
328
226
  function vectorGroups(store) {
329
227
  if (store.vectors === undefined)
330
228
  throw new StoreNotPortedError(store.kind, 'vectors');
@@ -351,7 +249,6 @@ async function writeVectorPage(writes, write, page, vectors, withParticles) {
351
249
  }
352
250
  return { written, modelMismatch: false };
353
251
  }
354
- const STORE_PAGE = 64;
355
252
  const OTHER_MODEL_INDEX = "the vector index was built by another embedding model; run 'hippo embed' to rebuild it";
356
253
  /** Embeds every memory with no vector under `model`, page by page, so a provider failure keeps the pages written; a rebuild reseeds the particles it drops. */
357
254
  async function backfillInStore(writes, provider, model, rebuild) {
@@ -411,10 +308,8 @@ export async function embedMemory(hippoRoot, entry, model, store) {
411
308
  if (store)
412
309
  return embedMemoryInStore(store, provider, entry);
413
310
  return withEmbedLock(hippoRoot, async () => {
414
- // embedMemory is best-effort: an embedding failure (API down / bad key / 5xx)
415
- // must not reject the caller's write — `getEmbedding` historically swallowed
416
- // failures and returned []. The explicit `hippo embed` / `embedAll` path is
417
- // where failures surface. On any failure we leave the existing index as-is.
311
+ // Best-effort: an embedding failure (API down, bad key, 5xx) must not reject the caller's write; the existing index is left as-is.
312
+ // Failures surface on the explicit `hippo embed` / `embedAll` path.
418
313
  try {
419
314
  const identity = provider.id;
420
315
  if (embeddingModelRequiresReindex(hippoRoot, identity)) {
@@ -425,7 +320,7 @@ export async function embedMemory(hippoRoot, entry, model, store) {
425
320
  const [vector] = await provider.embed([text], 'passage');
426
321
  if (!vector || vector.length === 0)
427
322
  return;
428
- withVectorDb(hippoRoot, (db) => upsertVectors(db, [[entry.id, vector]], embeddingIndexIdentity(identity)));
323
+ saveStoredVectors(hippoRoot, [[entry.id, vector]], embeddingIndexIdentity(identity));
429
324
  saveStoredEmbeddingModel(hippoRoot, identity);
430
325
  // Initialize physics state for this memory
431
326
  initializePhysicsIfMissing(hippoRoot, entry, vector);
@@ -438,31 +333,21 @@ export async function embedMemory(hippoRoot, entry, model, store) {
438
333
  log.warn(`skipped embedding ${entry.id} (${errorMessage(err)}); run 'hippo embed' to backfill`);
439
334
  });
440
335
  }
336
+ // Every page is embedded before one transaction replaces the index, and the identity is saved only after that: a provider failure or a crash
337
+ // at any earlier point leaves the old identity, so embeddingModelRequiresReindex has the next run rebuild from the start.
441
338
  async function rebuildIndexForProvider(hippoRoot, provider) {
442
339
  const identity = provider.id;
443
- // Host-wide rebuild. The embedding index is keyed by entry.id
444
- // (which is tenant-scoped) but the index itself is one per hippoRoot.
445
- // Cross-tenant content equivalence is visible at the vector level.
446
- // Per-tenant indices would be a larger architecture change.
447
- const entries = loadAllEntries(hippoRoot);
448
- const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
340
+ // Host-wide rebuild: one embedding index per hippoRoot, keyed by tenant-scoped entry.id; per-tenant indices would be a larger architecture change.
341
+ const ids = loadAllEntryIds(hippoRoot);
342
+ const rebuiltIndex = await rebuildEmbeddingIndex(hippoRoot, ids, provider);
449
343
  saveEmbeddingIndex(hippoRoot, rebuiltIndex, embeddingIndexIdentity(identity));
450
344
  saveStoredEmbeddingModel(hippoRoot, identity);
451
- resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
345
+ resetPhysicsFromIndex(hippoRoot, ids, rebuiltIndex);
346
+ return Object.keys(rebuiltIndex).length;
452
347
  }
453
348
  function initializePhysicsIfMissing(hippoRoot, entry, vector) {
454
349
  try {
455
- const db = openHippoDb(hippoRoot);
456
- try {
457
- const existing = loadPhysicsState(db, [entry.id]);
458
- if (!existing.has(entry.id)) {
459
- const particle = initializeParticle(entry, vector);
460
- savePhysicsState(db, [particle]);
461
- }
462
- }
463
- finally {
464
- closeHippoDb(db);
465
- }
350
+ seedStoredParticle(hippoRoot, entry, vector);
466
351
  }
467
352
  catch (err) {
468
353
  // Physics init is best-effort and must not fail the embedding that just landed.
@@ -471,10 +356,8 @@ function initializePhysicsIfMissing(hippoRoot, entry, vector) {
471
356
  }
472
357
  /** Throws when an unavailable provider is a misconfiguration rather than an intentional no-op. */
473
358
  function throwIfProviderKeyMissing(hippoRoot, provider) {
474
- // A configured (non-disabled) API provider with a missing key is a
475
- // misconfiguration, not a no-op: surface it so programmatic callers of the
476
- // exported embedAll() learn nothing was written. Local-not-installed and an
477
- // explicit enabled=false stay silent no-ops (best-effort / intentional).
359
+ // A configured API provider with a missing key is a misconfiguration: surface it so callers of the exported embedAll() learn nothing was written.
360
+ // Local-not-installed and an explicit enabled=false stay silent no-ops.
478
361
  const cfg = loadConfig(hippoRoot).embeddings;
479
362
  if (provider.kind !== 'local' &&
480
363
  cfg.enabled !== false &&
@@ -483,21 +366,13 @@ function throwIfProviderKeyMissing(hippoRoot, provider) {
483
366
  throw new Error(`Embedding provider '${provider.kind}' is configured but ${provider.keyEnv} is not set.`);
484
367
  }
485
368
  }
486
- // Embed entries without a cached vector in save-checkpointed chunks.
487
- // provider.embed batches internally (one HTTP request per batchSize for API
488
- // providers; sequential for local). A `[]` row means that single item could
489
- // not be embedded and is left for a later run (resumable). On a hard provider
490
- // failure mid-backfill we persist the chunks already embedded this run rather
491
- // than discarding paid progress, then stop and resume on the next run.
369
+ // Embeds entries without a cached vector in save-checkpointed chunks; a `[]` row means that item could not be embedded and is retried next run.
370
+ // On a hard provider failure mid-backfill the chunks already embedded are persisted (paid progress), then it stops and resumes next run.
492
371
  async function backfillPending(hippoRoot, provider, pending, model) {
493
372
  let count = 0;
494
- // Initialized to `undefined` (not a known-evidence literal like `null`) so
495
- // it stays a plain `unknown` binding for the arbitrary caught value below;
496
- // falsy either way, so `if (backfillError)` behaves identically.
373
+ // Initialized to `undefined` so it stays a plain `unknown` binding for the arbitrary caught value; falsy either way.
497
374
  let backfillError = undefined;
498
- const SAVE_CHUNK = 64;
499
- for (let i = 0; i < pending.length; i += SAVE_CHUNK) {
500
- const chunk = pending.slice(i, i + SAVE_CHUNK);
375
+ for (const chunk of entryPages(hippoRoot, pending)) {
501
376
  let vectors;
502
377
  try {
503
378
  vectors = await provider.embed(chunk.map((e) => embeddingInputText(e)), 'passage');
@@ -516,7 +391,7 @@ async function backfillPending(hippoRoot, provider, pending, model) {
516
391
  else
517
392
  noteSkippedEmbedding(chunk[j].id);
518
393
  }
519
- count += withVectorDb(hippoRoot, (db) => upsertVectors(db, rows, model));
394
+ count += saveStoredVectors(hippoRoot, rows, model);
520
395
  }
521
396
  return { count, backfillError };
522
397
  }
@@ -531,24 +406,13 @@ export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProv
531
406
  return withProcessEmbedLock(() => embedAllInStore(store, provider));
532
407
  return withEmbedLock(hippoRoot, async () => {
533
408
  const identity = provider.id;
534
- // Host-wide by design. embedAll backfills vectors for all tenants'
535
- // entries into the per-host embedding index. Per-tenant filtering would
536
- // produce partial indices and break recall.
537
- const entries = loadAllEntries(hippoRoot);
538
- const model = embeddingIndexIdentity(identity);
539
- if (embeddingModelRequiresReindex(hippoRoot, identity)) {
540
- const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
541
- saveEmbeddingIndex(hippoRoot, rebuiltIndex, model);
542
- saveStoredEmbeddingModel(hippoRoot, identity);
543
- resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
544
- return Object.keys(rebuiltIndex).length;
545
- }
546
- const embedded = withVectorDb(hippoRoot, (db) => {
547
- deleteOrphanVectors(db);
548
- return storedVectorIds(db);
549
- });
550
- const pending = entries.filter((e) => !embedded.has(e.id));
551
- const { count, backfillError } = await backfillPending(hippoRoot, provider, pending, model);
409
+ if (embeddingModelRequiresReindex(hippoRoot, identity))
410
+ return rebuildIndexForProvider(hippoRoot, provider);
411
+ // Host-wide by design: embedAll backfills all tenants' entries into the per-host index; per-tenant filtering would produce partial indices and break
412
+ // recall.
413
+ const embedded = pruneStoredVectors(hippoRoot);
414
+ const pending = loadAllEntryIds(hippoRoot).filter((id) => !embedded.has(id));
415
+ const { count, backfillError } = await backfillPending(hippoRoot, provider, pending, embeddingIndexIdentity(identity));
552
416
  saveStoredEmbeddingModel(hippoRoot, identity);
553
417
  // Partial progress is now persisted; surface a hard backfill failure so the
554
418
  // explicit embed path reports it (best-effort callers go via embedMemory).
@@ -1,4 +1,4 @@
1
- // The local Transformers.js embedder, a leaf so embedding-provider.ts can wrap it without importing embeddings.ts.
1
+ // The local Transformers.js embedder, a leaf so provider.ts can wrap it without importing index.ts.
2
2
  import { envModelCache } from '../../util/env.js';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
@@ -25,11 +25,6 @@ export function prefixFor(model, role) {
25
25
  }
26
26
  return '';
27
27
  }
28
- // Use Function constructor to bypass TypeScript static module resolution
29
- // for optional peer dependencies that may not be installed.
30
- // SAFETY: `import(s)` always resolves to a module namespace object (or rejects);
31
- // Promise<object> names that honestly without claiming a specific module shape.
32
- const _dynImport = new Function('s', 'return import(s)');
33
28
  /** Check (synchronously) if @xenova/transformers or @huggingface/transformers is installed. */
34
29
  export function isEmbeddingAvailable() {
35
30
  if (_embeddingAvailable !== null)
@@ -71,20 +66,19 @@ function resolveTransformersPackage() {
71
66
  return null; // neither optional package is installed; callers fall back to no local embeddings
72
67
  }
73
68
  }
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
69
  async function loadPipeline(model) {
76
- if (_pipelineInstances.has(model))
77
- return _pipelineInstances.get(model);
78
- if (_pipelineLoading.has(model))
79
- return _pipelineLoading.get(model);
70
+ const loaded = _pipelineInstances.get(model);
71
+ if (loaded)
72
+ return loaded;
73
+ const inFlight = _pipelineLoading.get(model);
74
+ if (inFlight)
75
+ return inFlight;
80
76
  const loading = createPipeline(model);
81
77
  _pipelineLoading.set(model, loading);
82
78
  return loading;
83
79
  }
84
80
  /** The model's pipeline, or null with the reason recorded in `_pipelineErrors`. */
85
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
81
  async function createPipeline(model) {
87
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
82
  const pkg = resolveTransformersPackage();
89
83
  if (!pkg) {
90
84
  _pipelineErrors.set(model, 'no transformers package is installed');
@@ -113,23 +107,18 @@ async function createPipeline(model) {
113
107
  }
114
108
  }
115
109
  /** The package's `pipeline` function, or null with the reason recorded in `_pipelineErrors`. */
116
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
110
  async function importPipelineFactory(pkg, model) {
118
111
  let pipelineFn = null;
119
112
  try {
120
- // SAFETY: the resolved module's shape is untyped by design (optional peer
121
- // dependency); pipelineFn/mod.env are read defensively below and any
122
- // failure to find a usable pipeline falls through to `return null`.
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- const mod = await _dynImport(pkg);
125
- if (envModelCache()) {
126
- if (mod.env) {
127
- mod.env.cacheDir = envModelCache();
128
- mod.env.localModelPath = envModelCache();
129
- mod.env.allowRemoteModels = false;
130
- }
113
+ // The package is an optional peer, so the dynamic import is typed by what this file reads; a missing export falls to the null below.
114
+ const mod = await import(/* @vite-ignore */ pkg);
115
+ const cache = envModelCache();
116
+ if (cache && mod.env) {
117
+ mod.env.cacheDir = cache;
118
+ mod.env.localModelPath = cache;
119
+ mod.env.allowRemoteModels = false;
131
120
  }
132
- pipelineFn = mod.pipeline ?? mod.default?.pipeline;
121
+ pipelineFn = mod.pipeline ?? mod.default?.pipeline ?? null;
133
122
  }
134
123
  catch (err) {
135
124
  // String(err) keeps a Node error's [ERR_...] code, which callers match on.
@@ -174,13 +163,7 @@ export async function getEmbedding(text, model = DEFAULT_EMBEDDING_MODEL, role)
174
163
  return [];
175
164
  const prefix = prefixFor(model, role);
176
165
  const input = prefix ? `${prefix}${text}` : text;
177
- // SAFETY: pipe() is a Transformers.js feature-extraction pipeline call;
178
- // its untyped output is read defensively below (only `.data`, cast on
179
- // the return line to the documented Float32Array tensor shape).
180
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
181
166
  const output = await pipe(input, { pooling: poolingFor(model), normalize: true });
182
- // SAFETY: output.data is a Float32Array per the feature-extraction
183
- // pipeline's documented tensor output shape.
184
167
  return Array.from(output.data);
185
168
  }
186
169
  catch (err) {