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
@@ -34,9 +34,8 @@ export function multihopSearch(query, entries, options = {}) {
34
34
  merged.set(r.entry.id, r);
35
35
  }
36
36
  }
37
- // PLAIN stable score sort on purpose -- pass1/pass2 inputs are
38
- // deterministically ordered (search() carries the content tail), stability
39
- // inherits that, and ties keep pass-1 results ahead of pass-2 follow-ups.
37
+ // PLAIN stable score sort on purpose: pass1/pass2 inputs are already deterministically ordered (search() carries the content tail),
38
+ // stability inherits that, and ties keep pass-1 results ahead of pass-2 follow-ups.
40
39
  return fit([...merged.values()].sort((a, b) => compareScoresDesc(a.score, b.score)));
41
40
  }
42
41
  //# sourceMappingURL=multihop.js.map
@@ -1,24 +1,11 @@
1
- /**
2
- * Extract meaningful path segments from a directory path.
3
- * Returns tags like ['path:src', 'path:api', 'path:my-project'].
4
- * Filters out noise (node_modules, .git, Users, home dirs, drive letters).
5
- */
1
+ /** Extracts meaningful path segments from a directory as tags like ['path:src', 'path:my-project']; filters noise (node_modules, .git, Users, home dirs,
2
+ * drive letters). */
6
3
  export declare function extractPathTags(dirPath: string): string[];
7
- /**
8
- * Compute path overlap score between two sets of path tags.
9
- * Returns 0..1 where 1 = perfect match.
10
- * Normalizes by the MORE SPECIFIC side (the larger of the two tag sets),
11
- * so a memory carrying only a bare/generic path tag can no longer score a
12
- * full 1.0 against a deeply-nested cwd just because its own tiny tag set
13
- * is fully contained in the query's — genericity is no longer rewarded.
14
- */
4
+ /** Path overlap score in 0..1 (1 = perfect match), normalized by the MORE SPECIFIC side (the larger tag set),
5
+ * so a bare/generic path tag cannot score 1.0 against a deeply nested cwd just because its tiny tag set is contained in the query's. */
15
6
  export declare function pathOverlapScore(memoryPathTags: string[], currentPathTags: string[]): number;
16
7
  /** Weight applied to path overlap score when computing the recall boost multiplier. */
17
8
  export declare const PATH_BOOST_WEIGHT = 0.3;
18
- /**
19
- * Multiplier applied to a composite recall score for path locality.
20
- * Filters the memory's tags to path:* itself so call sites cannot drift.
21
- * Returns 1.0..1.3.
22
- */
9
+ /** Multiplier (1.0..1.3) applied to a composite recall score for path locality; filters the memory's tags to path:* itself so call sites cannot drift. */
23
10
  export declare function pathBoostMultiplier(memoryTags: string[], currentPathTags: string[]): number;
24
11
  //# sourceMappingURL=path-context.d.ts.map
@@ -1,10 +1,7 @@
1
1
  // Keeps the last meaningful segments, the most specific ones.
2
2
  const PATH_SEGMENTS_KEPT = 4;
3
- /**
4
- * Extract meaningful path segments from a directory path.
5
- * Returns tags like ['path:src', 'path:api', 'path:my-project'].
6
- * Filters out noise (node_modules, .git, Users, home dirs, drive letters).
7
- */
3
+ /** Extracts meaningful path segments from a directory as tags like ['path:src', 'path:my-project']; filters noise (node_modules, .git, Users, home dirs,
4
+ * drive letters). */
8
5
  export function extractPathTags(dirPath) {
9
6
  const normalized = dirPath.replace(/\\/g, '/');
10
7
  const segments = normalized.split('/').filter(Boolean);
@@ -19,14 +16,8 @@ export function extractPathTags(dirPath) {
19
16
  .slice(-PATH_SEGMENTS_KEPT)
20
17
  .map(s => `path:${s.toLowerCase()}`);
21
18
  }
22
- /**
23
- * Compute path overlap score between two sets of path tags.
24
- * Returns 0..1 where 1 = perfect match.
25
- * Normalizes by the MORE SPECIFIC side (the larger of the two tag sets),
26
- * so a memory carrying only a bare/generic path tag can no longer score a
27
- * full 1.0 against a deeply-nested cwd just because its own tiny tag set
28
- * is fully contained in the query's — genericity is no longer rewarded.
29
- */
19
+ /** Path overlap score in 0..1 (1 = perfect match), normalized by the MORE SPECIFIC side (the larger tag set),
20
+ * so a bare/generic path tag cannot score 1.0 against a deeply nested cwd just because its tiny tag set is contained in the query's. */
30
21
  export function pathOverlapScore(memoryPathTags, currentPathTags) {
31
22
  if (memoryPathTags.length === 0 || currentPathTags.length === 0)
32
23
  return 0;
@@ -38,11 +29,7 @@ export function pathOverlapScore(memoryPathTags, currentPathTags) {
38
29
  }
39
30
  /** Weight applied to path overlap score when computing the recall boost multiplier. */
40
31
  export const PATH_BOOST_WEIGHT = 0.3;
41
- /**
42
- * Multiplier applied to a composite recall score for path locality.
43
- * Filters the memory's tags to path:* itself so call sites cannot drift.
44
- * Returns 1.0..1.3.
45
- */
32
+ /** Multiplier (1.0..1.3) applied to a composite recall score for path locality; filters the memory's tags to path:* itself so call sites cannot drift. */
46
33
  export function pathBoostMultiplier(memoryTags, currentPathTags) {
47
34
  const memPathTags = memoryTags.filter(t => t.startsWith('path:'));
48
35
  return 1.0 + pathOverlapScore(memPathTags, currentPathTags) * PATH_BOOST_WEIGHT;
@@ -1,7 +1,8 @@
1
1
  import { calculateStrength } from '../core/memory.js';
2
2
  import { estimateTokens } from '../util/token-text.js';
3
3
  import { evalNow, isRecallBoostAblated } from '../core/ablation.js';
4
- import { indexedModel, indexNeedsRebuild } from '../store/embeddings/index.js';
4
+ import { indexNeedsRebuild } from '../store/embeddings/index.js';
5
+ import { indexedModel } from '../store/vector-index.js';
5
6
  import { resolveEmbeddingProvider } from '../store/embeddings/provider.js';
6
7
  import { physicsScore as computePhysicsScores, computeMass } from '../core/physics.js';
7
8
  import { DEFAULT_PHYSICS_CONFIG } from '../core/physics-config.js';
@@ -14,7 +15,7 @@ import { addDagFields, ageInDays } from './breakdown.js';
14
15
  import { fitBudget } from './finalize.js';
15
16
  import { hybridSearch } from './hybrid.js';
16
17
  import { currentEntries } from './as-of.js';
17
- import { requireVectorReads, vectorCandidatesOutside } from './vector.js';
18
+ import { embedQueryBy, requireVectorReads, startQueryEmbedDeadline, vectorCandidatesOutside } from './vector.js';
18
19
  import { DEFAULT_RECALL_BUDGET } from '../core/search-types.js';
19
20
  /** Scores memories by gravity, momentum and cluster amplification; rows without physics state rank through hybridSearch. */
20
21
  export async function physicsSearch(query, entries, options = {}) {
@@ -28,27 +29,29 @@ export async function physicsSearch(query, entries, options = {}) {
28
29
  return hybridSearch(query, entries, options);
29
30
  const root = options.hippoRoot;
30
31
  const store = options.store ?? sqliteStore(root);
31
- const queryVector = await physicsQueryVector(query, root, store, options.queryEmbedding);
32
+ // Shared with every hybrid ranking below, so a provider that stalls here is not waited on a second time.
33
+ const queryEmbedDeadline = startQueryEmbedDeadline();
34
+ const queryVector = await physicsQueryVector(query, root, store, queryEmbedDeadline, options.queryEmbedding);
32
35
  if (!queryVector)
33
- return hybridSearch(query, entries, options);
36
+ return hybridSearch(query, entries, { ...options, queryEmbedDeadline });
34
37
  // Checked here too, since a caller's own query vector skips the check inside physicsQueryVector.
35
38
  const reads = requireVectorReads(store);
36
39
  const pool = currentEntries(await withVectorCandidates(reads, entries, queryVector, options.vectorCandidates), options);
37
40
  const physicsMap = await loadCandidateParticles(reads, pool);
38
41
  if (!physicsMap)
39
- return hybridSearch(query, pool, options);
42
+ return hybridSearch(query, pool, { ...options, queryEmbedDeadline });
40
43
  const pools = splitByParticle(pool, physicsMap, queryVector, now);
41
44
  const config = options.physicsConfig ?? DEFAULT_PHYSICS_CONFIG;
42
45
  const physicsResults = scorePhysicsPool(pools, queryVector, config, scoring);
43
46
  const classicResults = pools.classic.length > 0
44
- ? await hybridSearch(query, pools.classic, { ...options, vectorCandidates: undefined, budget: Infinity, explain })
47
+ ? await hybridSearch(query, pools.classic, { ...options, queryEmbedDeadline, vectorCandidates: undefined, budget: Infinity, explain })
45
48
  : [];
46
49
  const merged = mergeScorePools(physicsResults, classicResults);
47
50
  merged.sort(compareScoredResults);
48
51
  return fitBudget(merged, options.budget ?? DEFAULT_RECALL_BUDGET, options.minResults ?? 1, options.cost);
49
52
  }
50
53
  /** The caller's vector, else the provider's; null sends the caller to hybridSearch. */
51
- async function physicsQueryVector(query, root, store, given) {
54
+ async function physicsQueryVector(query, root, store, deadline, given) {
52
55
  if (given && given.length > 0)
53
56
  return given;
54
57
  // Physics scores against particle positions, not the stored vector index, so a pruned index must not block it.
@@ -58,7 +61,7 @@ async function physicsQueryVector(query, root, store, given) {
58
61
  return null;
59
62
  if (indexNeedsRebuild(indexedModel(await requireVectorReads(store).embeddingIndexState()), provider.id))
60
63
  return null;
61
- const [vec] = await provider.embed([query], 'query');
64
+ const vec = await embedQueryBy(deadline, provider, query);
62
65
  return vec && vec.length > 0 ? vec : null;
63
66
  }
64
67
  catch (err) {
@@ -1,43 +1,15 @@
1
- /**
2
- * Reciprocal Rank Fusion (Cormack, Clarke, and Buettcher 2009).
3
- *
4
- * Fuses N ranked candidate lists into a single ordering by summing
5
- * weighted 1/(k + rank) contributions per candidate. The constant K is
6
- * the canonical 60 from the original paper and the value already in use
7
- * across hippo's `hybridSearch`. Do NOT tune K without an
8
- * explicit cross-corpus eval — it is calibrated against IR benchmarks
9
- * and works robustly across BM25/dense/cross-encoder rank-list shapes.
10
- *
11
- * Generic over the candidate id type so this helper can be shared by
12
- * `src/search.ts::hybridSearch` (T = number, idx into MemoryEntry[]) and
13
- * the LongMemEval hybrid retrieve benchmark (T = string, session_id).
14
- *
15
- * Behaviour MUST stay byte-identical to the inline implementation that
16
- * lived in `src/search.ts:354-374` before extraction (commit ab6c5eb).
17
- * The `tests/rrf.test.ts` suite is the contract.
18
- */
1
+ /** Reciprocal Rank Fusion (Cormack, Clarke and Buettcher 2009): fuses N ranked lists by summing weighted 1/(k + rank) per candidate. K is the standard 60,
2
+ * the value hybridSearch already uses; do NOT tune it without a cross-corpus eval. Generic over the id type (hybridSearch uses number, the LongMemEval
3
+ * benchmark string). Behaviour MUST stay byte-identical to the inline hybridSearch code it replaced; tests/rrf.test.ts is the contract. */
19
4
  export declare const RRF_K = 60;
20
5
  export interface RrfFuseOptions {
21
6
  /** Smoothing constant. Default RRF_K = 60. */
22
7
  k?: number;
23
- /**
24
- * Rank assigned to candidates absent from a list. Default is
25
- * `max(rankedLists.map(l => l.length)) + 1` — the convention used in
26
- * the pre-extraction `hybridSearch` code (`entries.length + 1`).
27
- */
8
+ /** Rank assigned to candidates absent from a list; default `max(rankedLists.map(l => l.length)) + 1`, the convention hybridSearch used (`entries.length +
9
+ * 1`). */
28
10
  absentRank?: number;
29
11
  }
30
- /**
31
- * Fuse N ranked lists into a single Map of candidate id -> RRF score.
32
- *
33
- * @param rankedLists Each inner array is candidates in descending-score order.
34
- * Element at index 0 is rank 1; index 1 is rank 2; etc.
35
- * @param weights Per-list weights. weights.length === rankedLists.length.
36
- * Weights are summed without normalisation — pass {0.5, 0.5}
37
- * for symmetric fusion or {0.2, 0.8} for asymmetric.
38
- * @param options Optional k override + absentRank override.
39
- * @returns Map from candidate id to fused RRF score. Sort descending
40
- * by value to get the fused ordering.
41
- */
12
+ /** Fuses N ranked lists (each in descending-score order; index 0 is rank 1) into a Map of candidate id -> RRF score; sort by value descending for the fused
13
+ * order. `weights` has one entry per list and is summed without normalisation; `options` overrides k and absentRank. */
42
14
  export declare function rrfFuse<T>(rankedLists: ReadonlyArray<ReadonlyArray<T>>, weights: ReadonlyArray<number>, options?: RrfFuseOptions): Map<T, number>;
43
15
  //# sourceMappingURL=rrf.d.ts.map
@@ -1,34 +1,9 @@
1
- /**
2
- * Reciprocal Rank Fusion (Cormack, Clarke, and Buettcher 2009).
3
- *
4
- * Fuses N ranked candidate lists into a single ordering by summing
5
- * weighted 1/(k + rank) contributions per candidate. The constant K is
6
- * the canonical 60 from the original paper and the value already in use
7
- * across hippo's `hybridSearch`. Do NOT tune K without an
8
- * explicit cross-corpus eval — it is calibrated against IR benchmarks
9
- * and works robustly across BM25/dense/cross-encoder rank-list shapes.
10
- *
11
- * Generic over the candidate id type so this helper can be shared by
12
- * `src/search.ts::hybridSearch` (T = number, idx into MemoryEntry[]) and
13
- * the LongMemEval hybrid retrieve benchmark (T = string, session_id).
14
- *
15
- * Behaviour MUST stay byte-identical to the inline implementation that
16
- * lived in `src/search.ts:354-374` before extraction (commit ab6c5eb).
17
- * The `tests/rrf.test.ts` suite is the contract.
18
- */
1
+ /** Reciprocal Rank Fusion (Cormack, Clarke and Buettcher 2009): fuses N ranked lists by summing weighted 1/(k + rank) per candidate. K is the standard 60,
2
+ * the value hybridSearch already uses; do NOT tune it without a cross-corpus eval. Generic over the id type (hybridSearch uses number, the LongMemEval
3
+ * benchmark string). Behaviour MUST stay byte-identical to the inline hybridSearch code it replaced; tests/rrf.test.ts is the contract. */
19
4
  export const RRF_K = 60;
20
- /**
21
- * Fuse N ranked lists into a single Map of candidate id -> RRF score.
22
- *
23
- * @param rankedLists Each inner array is candidates in descending-score order.
24
- * Element at index 0 is rank 1; index 1 is rank 2; etc.
25
- * @param weights Per-list weights. weights.length === rankedLists.length.
26
- * Weights are summed without normalisation — pass {0.5, 0.5}
27
- * for symmetric fusion or {0.2, 0.8} for asymmetric.
28
- * @param options Optional k override + absentRank override.
29
- * @returns Map from candidate id to fused RRF score. Sort descending
30
- * by value to get the fused ordering.
31
- */
5
+ /** Fuses N ranked lists (each in descending-score order; index 0 is rank 1) into a Map of candidate id -> RRF score; sort by value descending for the fused
6
+ * order. `weights` has one entry per list and is summed without normalisation; `options` overrides k and absentRank. */
32
7
  export function rrfFuse(rankedLists, weights, options) {
33
8
  if (rankedLists.length !== weights.length) {
34
9
  throw new Error(`rrfFuse: rankedLists.length (${rankedLists.length}) must match weights.length (${weights.length})`);
@@ -1,5 +1,6 @@
1
1
  import type { MemoryEntry } from '../core/memory.js';
2
2
  import type { VectorCandidateSpec } from '../store/search-rows.js';
3
+ import { type EmbeddingProvider } from '../store/embeddings/provider.js';
3
4
  import { type HippoStore, type VectorReads } from '../store/index.js';
4
5
  import { type CurrentnessOptions } from './as-of.js';
5
6
  /** hybridSearch's vector arm: which rows it may add, plus the caller's JS admission rules (exact private regex, entry filters). */
@@ -19,7 +20,13 @@ export interface VectorArmOptions extends CurrentnessOptions {
19
20
  vectorCandidates?: HybridVectorCandidates;
20
21
  /** Where vectors are read; hippo.db under `hippoRoot` when unset. */
21
22
  store?: HippoStore;
23
+ /** The deadline a caller already started for this recall's query embedding; a fresh budget when unset. */
24
+ queryEmbedDeadline?: AbortSignal;
22
25
  }
26
+ /** One deadline for every query embedding a recall makes, so two stores or a physics fallback share the budget. */
27
+ export declare function startQueryEmbedDeadline(): AbortSignal;
28
+ /** The query's vector, or null when an API provider outlasts `deadline`; any other provider failure throws as before. */
29
+ export declare function embedQueryBy(deadline: AbortSignal, provider: EmbeddingProvider, query: string): Promise<number[] | null>;
23
30
  /** The store's vector reads; a store without them answers 501, as any unported path does. */
24
31
  export declare function requireVectorReads(store: HippoStore): VectorReads;
25
32
  /** The nearest admitted rows not already in `entries`. */
@@ -1,10 +1,36 @@
1
- import { cosineOf, indexedModel, indexNeedsRebuild } from '../store/embeddings/index.js';
1
+ import { cosineOf, indexNeedsRebuild } from '../store/embeddings/index.js';
2
+ import { indexedModel } from '../store/vector-index.js';
2
3
  import { resolveEmbeddingProvider } from '../store/embeddings/provider.js';
3
4
  import { rethrowIfSqliteBlocked } from '../db/index.js';
4
5
  import { errorMessage, log } from '../util/log.js';
6
+ import { envQueryEmbedTimeoutMs } from '../util/env.js';
5
7
  import { requireGroup, sqliteStore } from '../store/index.js';
6
8
  import { redactSecretsStrict } from '../util/secret-detect.js';
7
9
  import { currentEntries } from './as-of.js';
10
+ // Jev's default budget (rerankers/jev.ts): each is one off-box call that a recall waits on.
11
+ const QUERY_EMBED_BUDGET_MS = 5_000;
12
+ /** How long one recall waits for its query vector, retries included; HIPPO_QUERY_EMBED_TIMEOUT_MS overrides the default. */
13
+ function queryEmbedBudgetMs() {
14
+ return envQueryEmbedTimeoutMs() ?? QUERY_EMBED_BUDGET_MS;
15
+ }
16
+ /** One deadline for every query embedding a recall makes, so two stores or a physics fallback share the budget. */
17
+ export function startQueryEmbedDeadline() {
18
+ return AbortSignal.timeout(queryEmbedBudgetMs());
19
+ }
20
+ /** The query's vector, or null when an API provider outlasts `deadline`; any other provider failure throws as before. */
21
+ export async function embedQueryBy(deadline, provider, query) {
22
+ // No signal stops an in-process model, so the local provider is not held to the deadline.
23
+ if (provider.kind === 'local')
24
+ return (await provider.embed([query], 'query'))[0] ?? [];
25
+ try {
26
+ return (await provider.embed([query], 'query', { signal: deadline }))[0] ?? [];
27
+ }
28
+ catch (err) {
29
+ if (deadline.aborted)
30
+ return null;
31
+ throw err;
32
+ }
33
+ }
8
34
  // Search runs on every hook prompt, so one line per reason per process says why vectors went unused without flooding stderr.
9
35
  function warnBm25Fallback(reason, detail) {
10
36
  log.once(`search.bm25-fallback.${reason}`, 'warn', `hybrid search fell back to BM25 only: ${redactSecretsStrict(detail)}`);
@@ -61,8 +87,12 @@ async function fillVectorArm(arm, query, root, options) {
61
87
  // Only spend a (possibly paid, off-box) query embedding when there is a stored vector this search can use.
62
88
  if (vectors.size === 0 && !(spec !== undefined && index.hasVectors))
63
89
  return;
64
- const [vec] = await provider.embed([query], 'query');
65
- arm.queryVector = vec ?? [];
90
+ const vec = await embedQueryBy(options.queryEmbedDeadline ?? startQueryEmbedDeadline(), provider, query);
91
+ if (vec === null) {
92
+ warnBm25Fallback('query-embed-budget', `the ${provider.kind} embedding provider gave no query vector within ${queryEmbedBudgetMs()} ms`);
93
+ return;
94
+ }
95
+ arm.queryVector = vec;
66
96
  if (arm.queryVector.length === 0) {
67
97
  warnBm25Fallback('empty-query-vector', 'the embedding provider returned no vector for the query');
68
98
  return;
@@ -79,8 +109,8 @@ async function fillVectorArm(arm, query, root, options) {
79
109
  }
80
110
  export function denseScores(arm) {
81
111
  const n = arm.entries.length;
82
- const cosine = new Array(n).fill(0);
83
- const hadVec = new Array(n).fill(false);
112
+ const cosine = Array(n).fill(0);
113
+ const hadVec = Array(n).fill(false);
84
114
  if (!arm.useEmbeddings)
85
115
  return { cosine, hadVec };
86
116
  for (let i = 0; i < n; i++) {
@@ -1,23 +1,12 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
2
  import { type Context } from '../api/index.js';
3
3
  import type { ResolvedServeOpts } from './types.js';
4
- /**
5
- * Recognise loopback remote addresses. Node reports IPv6-mapped IPv4 as
6
- * '::ffff:127.0.0.1' on dual-stack sockets, so we accept that alongside
7
- * the bare v4 and v6 loopbacks. Anything else is treated as remote.
8
- */
4
+ /** Recognises loopback remote addresses, including the IPv6-mapped '::ffff:127.0.0.1' Node reports on dual-stack sockets; anything else is remote. */
9
5
  export declare function isLoopback(remoteAddress: string | undefined): boolean;
10
- /**
11
- * Read the Authorization header in a case-insensitive way and pull the
12
- * bearer token out. Returns:
13
- * - { kind: 'absent' } when no Authorization header is present
14
- * - { kind: 'malformed' } when the header is set but not 'Bearer <token>'
15
- * - { kind: 'bearer', token } when a non-empty bearer token is present
16
- *
17
- * The header NAME is case-insensitive (Node lowercases all header names on
18
- * IncomingMessage.headers); the SCHEME ('Bearer') is also matched
19
- * case-insensitively per RFC 6750.
20
- */
6
+ /** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the socket alone proves nothing. */
7
+ export declare function isLocalCaller(req: IncomingMessage): boolean;
8
+ /** Reads the Authorization header case-insensitively (name and RFC 6750 'Bearer' scheme): { kind: 'absent' }, { kind: 'malformed' } (set but not 'Bearer
9
+ * <token>'), or { kind: 'bearer', token } for a non-empty token. */
21
10
  type AuthHeader = {
22
11
  kind: 'absent';
23
12
  } | {
@@ -32,19 +21,11 @@ type AuthOpts = Pick<ResolvedServeOpts, 'hippoRoot' | 'authResolver' | 'authReso
32
21
  export declare function isReservedActor(subject: string): boolean;
33
22
  /** Key cap for every serve() bucket, shared by the warn map so it never tracks more callers than the buckets do. */
34
23
  export declare const LIMITER_MAX_KEYS = 10000;
35
- /**
36
- * Build a per-request Context from the Authorization header and remote
37
- * address. Throws HttpError(401) for invalid / missing credentials. Reads
38
- * the store only for an API-key-shaped Bearer token (or any Bearer token when no
39
- * auth resolver is registered), so loopback no-auth requests stay cheap.
40
- */
24
+ /** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401) for invalid or missing credentials.
25
+ * Reads the store only for an API-key-shaped Bearer (or any Bearer when no auth resolver is registered), so keyless local requests stay cheap. */
41
26
  export declare function buildContextWithAuth(req: IncomingMessage, opts: AuthOpts): Promise<Context>;
42
- /**
43
- * Auth check for routes that do not need a tenant Context (e.g. MCP transport,
44
- * which builds its own root resolution via findHippoRoot). Throws HttpError
45
- * 401 the same way buildContextWithAuth does, but skips building the Context
46
- * envelope. Loopback no-auth still passes.
47
- */
27
+ /** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws HttpError 401 like buildContextWithAuth.
28
+ * A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
48
29
  export declare function requireAuth(req: IncomingMessage, opts: AuthOpts): Promise<void>;
49
30
  /** Never rejects or charges a caller bucket: an outage (5xx) or a throttle (429) skips one tick; only a definite 4xx denial closes the stream. */
50
31
  export declare function heartbeatVerdict(req: IncomingMessage, opts: AuthOpts): Promise<'ok' | 'revoked' | 'unavailable'>;
@@ -1,5 +1,5 @@
1
1
  // Bearer and loopback auth for the HTTP server.
2
- import { envRequireAuth } from '../util/env.js';
2
+ import { envAllowKeylessLocal, envRequireAuth } from '../util/env.js';
3
3
  import { resolveTenantId } from '../store/tenant.js';
4
4
  import { log } from '../util/log.js';
5
5
  import { API_KEY_PREFIX, verifyApiKeyCached } from '../store/auth.js';
@@ -8,11 +8,7 @@ import { HttpError, isCrossSite, isHeaderString, LOOPBACK_HOST_HEADER, MAX_ID_LE
8
8
  import { clientLimitKey } from './client-ip.js';
9
9
  import { keyCheckBounds } from './key-check-bounds.js';
10
10
  import { isJsonString } from '../util/json.js';
11
- /**
12
- * Recognise loopback remote addresses. Node reports IPv6-mapped IPv4 as
13
- * '::ffff:127.0.0.1' on dual-stack sockets, so we accept that alongside
14
- * the bare v4 and v6 loopbacks. Anything else is treated as remote.
15
- */
11
+ /** Recognises loopback remote addresses, including the IPv6-mapped '::ffff:127.0.0.1' Node reports on dual-stack sockets; anything else is remote. */
16
12
  export function isLoopback(remoteAddress) {
17
13
  if (!remoteAddress)
18
14
  return false;
@@ -29,21 +25,36 @@ const PROXY_HEADERS = [
29
25
  'forwarded', 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-real-ip', 'cf-connecting-ip', 'true-client-ip',
30
26
  'fly-client-ip',
31
27
  ];
32
- // A browser on this machine is loopback too, so the no-key fallback also needs a local Host and a same-site caller.
28
+ function proxyHeaderOf(req) {
29
+ return PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
30
+ }
31
+ /** A page in a browser on this machine: another site's request, or a hostile name resolved to loopback (DNS rebinding). */
32
+ function isForeignPage(req) {
33
+ const host = req.headers.host;
34
+ return (host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req);
35
+ }
36
+ /** True only for a request made on this machine by its own user: a proxy and a browser page are loopback too, so the socket alone proves nothing. */
37
+ export function isLocalCaller(req) {
38
+ return isLoopback(req.socket.remoteAddress) && proxyHeaderOf(req) === undefined && !isForeignPage(req);
39
+ }
40
+ // The throwing twin of isLocalCaller, for the no-key fallback: each refusal has its own status, and a proxied one is logged.
33
41
  function assertLocalCaller(req) {
34
42
  if (!isLoopback(req.socket.remoteAddress))
35
43
  throw new HttpError(401, 'auth required');
36
- const proxyHeader = PROXY_HEADERS.find((name) => req.headers[name] !== undefined);
44
+ const proxyHeader = proxyHeaderOf(req);
37
45
  if (proxyHeader !== undefined) {
38
46
  log.warn(`proxied loopback request refused: it carries ${proxyHeader}, so the no-key local fallback does not apply. ` +
39
47
  'Send an API key (hippo auth create, then Authorization: Bearer hk_...).');
40
48
  throw new HttpError(401, 'auth required');
41
49
  }
42
- const host = req.headers.host;
43
- if ((host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req)) {
50
+ if (isForeignPage(req)) {
44
51
  throw new HttpError(403, 'cross-site or non-local request refused; send an API key');
45
52
  }
46
53
  }
54
+ /** The 401 a keyless request from this machine gets by default; it names both fixes, since an upgrade is where most people meet it. */
55
+ const KEY_REQUIRED_MESSAGE = 'auth required: this server takes no request without an API key. Mint one with `hippo auth create` and send it as ' +
56
+ '"Authorization: Bearer <key>" (the hippo CLI reads HIPPO_API_KEY), or start the server with HIPPO_ALLOW_KEYLESS_LOCAL=1 ' +
57
+ 'to let requests from this machine in without a key.';
47
58
  export function readAuthHeader(req) {
48
59
  const raw = req.headers['authorization'];
49
60
  if (raw === undefined)
@@ -167,7 +178,7 @@ async function resolveBearer(req, token, opts) {
167
178
  id.owner = key.ownerSubject;
168
179
  return id;
169
180
  }
170
- /** The auth check without a charge: the bearer's identity, or null for the loopback fallback. */
181
+ /** The auth check without a charge: the bearer's identity, or null for the keyless local fallback. */
171
182
  async function checkAuth(req, opts) {
172
183
  const auth = readAuthHeader(req);
173
184
  if (auth.kind === 'malformed') {
@@ -175,10 +186,14 @@ async function checkAuth(req, opts) {
175
186
  }
176
187
  if (auth.kind === 'bearer')
177
188
  return resolveBearer(req, auth.token, opts);
178
- // No Authorization header: the loopback fallback, unless HIPPO_REQUIRE_AUTH=1 forbids the local-CLI escape hatch.
189
+ // No Authorization header. HIPPO_REQUIRE_AUTH=1 is checked first, so a deployment that sets both stays closed.
179
190
  if (envRequireAuth()) {
180
191
  throw new HttpError(401, 'auth required');
181
192
  }
193
+ if (!envAllowKeylessLocal()) {
194
+ // Only this machine's own user is told how to switch the key off; a proxied caller or a page learns nothing.
195
+ throw new HttpError(401, isLocalCaller(req) ? KEY_REQUIRED_MESSAGE : 'auth required');
196
+ }
182
197
  assertLocalCaller(req);
183
198
  return null;
184
199
  }
@@ -224,12 +239,8 @@ function chargeCaller(tenantId, actor, opts) {
224
239
  warnCallerLimited(key, tenantId, person);
225
240
  throw new HttpError(429, 'rate limit exceeded for this caller', limiter.retryAfterSec);
226
241
  }
227
- /**
228
- * Build a per-request Context from the Authorization header and remote
229
- * address. Throws HttpError(401) for invalid / missing credentials. Reads
230
- * the store only for an API-key-shaped Bearer token (or any Bearer token when no
231
- * auth resolver is registered), so loopback no-auth requests stay cheap.
232
- */
242
+ /** Builds a per-request Context from the Authorization header and remote address; throws HttpError(401) for invalid or missing credentials.
243
+ * Reads the store only for an API-key-shaped Bearer (or any Bearer when no auth resolver is registered), so keyless local requests stay cheap. */
233
244
  export async function buildContextWithAuth(req, opts) {
234
245
  const id = await checkAuth(req, opts);
235
246
  if (id !== null) {
@@ -237,7 +248,7 @@ export async function buildContextWithAuth(req, opts) {
237
248
  chargeCaller(id.tenantId, actor, opts);
238
249
  return { hippoRoot: opts.hippoRoot, tenantId: id.tenantId, actor, store: opts.store };
239
250
  }
240
- // Loopback fallback is process-local, treat as admin.
251
+ // The keyless local fallback (HIPPO_ALLOW_KEYLESS_LOCAL=1) is this machine's own user, so it is host admin.
241
252
  return {
242
253
  hippoRoot: opts.hippoRoot,
243
254
  tenantId: resolveTenantId({}),
@@ -245,12 +256,8 @@ export async function buildContextWithAuth(req, opts) {
245
256
  store: opts.store,
246
257
  };
247
258
  }
248
- /**
249
- * Auth check for routes that do not need a tenant Context (e.g. MCP transport,
250
- * which builds its own root resolution via findHippoRoot). Throws HttpError
251
- * 401 the same way buildContextWithAuth does, but skips building the Context
252
- * envelope. Loopback no-auth still passes.
253
- */
259
+ /** Auth check for routes that need no tenant Context (e.g. the MCP transport, which resolves its own root): throws HttpError 401 like buildContextWithAuth.
260
+ * A keyless local request passes only under HIPPO_ALLOW_KEYLESS_LOCAL=1. */
254
261
  export async function requireAuth(req, opts) {
255
262
  const id = await checkAuth(req, opts);
256
263
  if (id !== null)
@@ -1,24 +1,5 @@
1
1
  import type { ServeOpts, ServerHandle } from './types.js';
2
- /**
3
- * Boot the HTTP daemon on host:port and write the pidfile under hippoRoot.
4
- *
5
- * Refuses non-loopback hosts at boot unless
6
- * HIPPO_REQUIRE_AUTH=1 is set. The auth middleware (buildContextWithAuth /
7
- * requireAuth) has shipped and every route checks it except GET /health
8
- * (public by design for platform health checks) and the two connector
9
- * webhooks in PUBLIC_ROUTES, which are HMAC-gated by their own signing
10
- * secrets and 404 when those secrets are unset, and any publicJson GET path. But the loopback
11
- * no-auth fallback inside buildContextWithAuth still admits unauthenticated
12
- * requests from a loopback remote address (unless they carry Forwarded,
13
- * X-Forwarded-For/-Host/-Proto, X-Real-IP, Cf-Connecting-Ip, True-Client-Ip or Fly-Client-Ip, which mark a same-host proxy and get
14
- * a 401 like any keyless remote request), so binding to a non-loopback host
15
- * is only safe once that fallback is disabled with HIPPO_REQUIRE_AUTH=1,
16
- * which forces every request (loopback or not) through Bearer-token
17
- * validation. Without that env var set, a non-loopback bind would expose the
18
- * DB to the network with no auth, so we fail fast instead.
19
- *
20
- * Use port: 0 in tests to bind to an ephemeral port and read the actual
21
- * port back via server.address() after listen.
22
- */
2
+ /** Boots the HTTP daemon on host:port and writes the pidfile under hippoRoot; refuses non-loopback hosts unless HIPPO_REQUIRE_AUTH=1.
3
+ * Use port: 0 in tests for an ephemeral port. See docs/ARCHITECTURE.md#srcserverbootts. */
23
4
  export declare function serve(opts: ServeOpts): Promise<ServerHandle>;
24
5
  //# sourceMappingURL=boot.d.ts.map