oh-my-second-brain 0.3.0 → 0.6.2

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 (110) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/ACKNOWLEDGMENTS.md +8 -0
  5. package/CHANGELOG-assets.md +10 -0
  6. package/CHANGELOG-cli.md +11 -0
  7. package/CHANGELOG-kernel.md +31 -0
  8. package/CHANGELOG-mcp.md +12 -0
  9. package/CHANGELOG-vendors.md +6 -0
  10. package/CHANGELOG.md +35 -0
  11. package/assets/hermes-manifest.json +1 -1
  12. package/assets/skills/doctor/SKILL.md +2 -2
  13. package/assets/skills/search/SKILL.md +17 -1
  14. package/dist/cli/args.d.ts +2 -0
  15. package/dist/cli/args.js +13 -0
  16. package/dist/cli/args.js.map +1 -1
  17. package/dist/cli/host-commands.js +2 -1
  18. package/dist/cli/host-commands.js.map +1 -1
  19. package/dist/cli/oms.d.ts +1 -1
  20. package/dist/cli/oms.js +26 -3
  21. package/dist/cli/oms.js.map +1 -1
  22. package/dist/cli/semantic-args.js +102 -3
  23. package/dist/cli/semantic-args.js.map +1 -1
  24. package/dist/cli/semantic.js +30 -6
  25. package/dist/cli/semantic.js.map +1 -1
  26. package/dist/cli/setup-command.d.ts +16 -0
  27. package/dist/cli/setup-command.js +50 -1
  28. package/dist/cli/setup-command.js.map +1 -1
  29. package/dist/kernel/contracts/index.d.ts +144 -0
  30. package/dist/kernel/contracts/index.js +401 -0
  31. package/dist/kernel/contracts/index.js.map +1 -0
  32. package/dist/kernel/conventions/note-exclude.d.ts +14 -0
  33. package/dist/kernel/conventions/note-exclude.js +95 -0
  34. package/dist/kernel/conventions/note-exclude.js.map +1 -0
  35. package/dist/kernel/engine/assemble.d.ts +22 -1
  36. package/dist/kernel/engine/assemble.js +202 -19
  37. package/dist/kernel/engine/assemble.js.map +1 -1
  38. package/dist/kernel/engine/axes/store.d.ts +90 -0
  39. package/dist/kernel/engine/axes/store.js +422 -0
  40. package/dist/kernel/engine/axes/store.js.map +1 -0
  41. package/dist/kernel/engine/conventions/vault-lint.d.ts +7 -2
  42. package/dist/kernel/engine/conventions/vault-lint.js +7 -21
  43. package/dist/kernel/engine/conventions/vault-lint.js.map +1 -1
  44. package/dist/kernel/engine/embed/identity.d.ts +14 -4
  45. package/dist/kernel/engine/embed/identity.js +33 -1
  46. package/dist/kernel/engine/embed/identity.js.map +1 -1
  47. package/dist/kernel/engine/embed/model.d.ts +134 -0
  48. package/dist/kernel/engine/embed/model.js +302 -0
  49. package/dist/kernel/engine/embed/model.js.map +1 -0
  50. package/dist/kernel/engine/embed/provider.d.ts +36 -5
  51. package/dist/kernel/engine/embed/provider.js +240 -103
  52. package/dist/kernel/engine/embed/provider.js.map +1 -1
  53. package/dist/kernel/engine/embed/store.d.ts +5 -1
  54. package/dist/kernel/engine/embed/store.js +136 -26
  55. package/dist/kernel/engine/embed/store.js.map +1 -1
  56. package/dist/kernel/engine/embed/sync.d.ts +53 -0
  57. package/dist/kernel/engine/embed/sync.js +489 -59
  58. package/dist/kernel/engine/embed/sync.js.map +1 -1
  59. package/dist/kernel/engine/graph/builder.d.ts +9 -5
  60. package/dist/kernel/engine/graph/builder.js +225 -82
  61. package/dist/kernel/engine/graph/builder.js.map +1 -1
  62. package/dist/kernel/engine/graph/node.d.ts +49 -1
  63. package/dist/kernel/engine/graph/node.js +205 -0
  64. package/dist/kernel/engine/graph/node.js.map +1 -1
  65. package/dist/kernel/engine/mcp/facade.d.ts +21 -1
  66. package/dist/kernel/engine/mcp/facade.js +523 -28
  67. package/dist/kernel/engine/mcp/facade.js.map +1 -1
  68. package/dist/kernel/engine/mcp/query-mapper.d.ts +27 -2
  69. package/dist/kernel/engine/mcp/query-mapper.js +157 -12
  70. package/dist/kernel/engine/mcp/query-mapper.js.map +1 -1
  71. package/dist/kernel/engine/mcp/types.d.ts +64 -2
  72. package/dist/kernel/engine/retrieval/dispatcher.d.ts +22 -0
  73. package/dist/kernel/engine/retrieval/dispatcher.js +84 -8
  74. package/dist/kernel/engine/retrieval/dispatcher.js.map +1 -1
  75. package/dist/kernel/engine/retrieval/index.d.ts +2 -1
  76. package/dist/kernel/engine/retrieval/index.js +1 -1
  77. package/dist/kernel/engine/retrieval/index.js.map +1 -1
  78. package/dist/kernel/engine/retrieval/reranker.d.ts +82 -4
  79. package/dist/kernel/engine/retrieval/reranker.js +178 -3
  80. package/dist/kernel/engine/retrieval/reranker.js.map +1 -1
  81. package/dist/kernel/engine/retrieval/rrf.d.ts +10 -2
  82. package/dist/kernel/engine/retrieval/rrf.js +39 -16
  83. package/dist/kernel/engine/retrieval/rrf.js.map +1 -1
  84. package/dist/kernel/engine/tracer.d.ts +13 -0
  85. package/dist/kernel/engine/tracer.js +63 -6
  86. package/dist/kernel/engine/tracer.js.map +1 -1
  87. package/dist/kernel/graph/cache.js +174 -23
  88. package/dist/kernel/graph/cache.js.map +1 -1
  89. package/dist/kernel/index.d.ts +2 -0
  90. package/dist/kernel/index.js +2 -0
  91. package/dist/kernel/index.js.map +1 -1
  92. package/dist/kernel/measurement/no-default-contract.d.ts +17 -0
  93. package/dist/kernel/measurement/no-default-contract.js +84 -0
  94. package/dist/kernel/measurement/no-default-contract.js.map +1 -0
  95. package/dist/kernel/searchbackend/engine-search-backend.js +93 -7
  96. package/dist/kernel/searchbackend/engine-search-backend.js.map +1 -1
  97. package/dist/kernel/searchbackend/search-backend.d.ts +11 -1
  98. package/dist/kernel/searchbackend/search-backend.js +66 -5
  99. package/dist/kernel/searchbackend/search-backend.js.map +1 -1
  100. package/dist/kernel/semantic/semantic-engine.js +31 -5
  101. package/dist/kernel/semantic/semantic-engine.js.map +1 -1
  102. package/dist/kernel/semantic/semantic-retrieve-args.d.ts +19 -2
  103. package/dist/kernel/semantic/semantic-retrieve-args.js +81 -7
  104. package/dist/kernel/semantic/semantic-retrieve-args.js.map +1 -1
  105. package/dist/kernel/update/update.d.ts +7 -0
  106. package/dist/kernel/update/update.js +106 -8
  107. package/dist/kernel/update/update.js.map +1 -1
  108. package/dist/mcp/server.js +84 -34
  109. package/dist/mcp/server.js.map +1 -1
  110. package/package.json +3 -2
@@ -11,6 +11,23 @@
11
11
  * every async step.
12
12
  */
13
13
  import { fuseRRF } from "./rrf.js";
14
+ function assertFiniteVector(vector, expectedDimensions) {
15
+ if (!(vector instanceof Float32Array)) {
16
+ throw new Error("Embedding provider returned a vector that is not a Float32Array.");
17
+ }
18
+ if (vector.length !== expectedDimensions) {
19
+ throw new Error(`Embedding provider returned ${vector.length} dimensions; expected ${expectedDimensions}.`);
20
+ }
21
+ for (let index = 0; index < vector.length; index += 1) {
22
+ if (!Number.isFinite(vector[index])) {
23
+ throw new Error(`Embedding provider returned a non-finite vector value at index ${index}.`);
24
+ }
25
+ }
26
+ }
27
+ async function embedQuery(provider, text) {
28
+ const queryProvider = provider;
29
+ return queryProvider.embedQuery?.(text) ?? provider.embed(text);
30
+ }
14
31
  /** Create a new mutable cancel token. */
15
32
  export function createCancelToken() {
16
33
  let cancelled = false;
@@ -59,6 +76,26 @@ const PROVENANCE_BOOST = {
59
76
  curated: 0.01, // deliberately imported / curated references
60
77
  "external-raw": 0, // raw external content — no boost
61
78
  };
79
+ /**
80
+ * Apply the provenance signal without putting it on a different scale from
81
+ * RRF. RRF scores are bounded by the number of lists and `rrfK` (roughly
82
+ * 0.016 for one rank-1 list with k=60), so adding a raw 0.02 would let a
83
+ * low-ranked authored hit leap over a stronger multi-list result. A
84
+ * multiplicative adjustment keeps the signal monotonic and proportional to
85
+ * the fused score.
86
+ */
87
+ export function applyProvenanceBoost(score, provenance) {
88
+ const boost = provenance === undefined ? 0 : PROVENANCE_BOOST[provenance];
89
+ return score * (1 + boost);
90
+ }
91
+ export const DISPATCHER_POLICIES = Object.freeze([
92
+ "boost-additive",
93
+ "boost-k-scale",
94
+ "boost-per-list",
95
+ "boost-zero",
96
+ ]);
97
+ export const PREREGISTERED_ARM_POLICIES = Object.freeze(["boost-k-scale", "boost-per-list", "boost-zero"]);
98
+ export const DEFAULT_DISPATCHER_POLICY = "boost-additive";
62
99
  // ---------------------------------------------------------------------------
63
100
  // Per-type dispatch
64
101
  // ---------------------------------------------------------------------------
@@ -70,13 +107,15 @@ async function dispatchOne(sub, deps, k, cancel, collection) {
70
107
  : deps.store.queryLex(sub.query, k, collection)), cancel);
71
108
  }
72
109
  case "vec": {
73
- const vec = await withRetry(() => deps.embed.embed(sub.query), cancel);
110
+ const vec = await withRetry(() => embedQuery(deps.embed, sub.query), cancel);
111
+ assertFiniteVector(vec, deps.embed.dimensions);
74
112
  return withRetry(() => Promise.resolve(collection === undefined ? deps.store.queryVec(vec, k) : deps.store.queryVec(vec, k, collection)), cancel);
75
113
  }
76
114
  case "hyde": {
77
115
  const generator = deps.hydeGenerator ?? defaultHydeGenerator;
78
116
  const hypoDoc = await withRetry(() => generator(sub.query), cancel);
79
- const vec = await withRetry(() => deps.embed.embed(hypoDoc), cancel);
117
+ const vec = await withRetry(() => embedQuery(deps.embed, hypoDoc), cancel);
118
+ assertFiniteVector(vec, deps.embed.dimensions);
80
119
  return withRetry(() => Promise.resolve(collection === undefined ? deps.store.queryVec(vec, k) : deps.store.queryVec(vec, k, collection)), cancel);
81
120
  }
82
121
  case "graph": {
@@ -91,6 +130,22 @@ async function dispatchOne(sub, deps, k, cancel, collection) {
91
130
  }
92
131
  }
93
132
  }
133
+ /**
134
+ * Apply the per-list policy before RRF ranking. RRF consumes rank positions,
135
+ * so the weighted score must be used to establish each list's order rather
136
+ * than applied after fusion (which would be the k-scale policy).
137
+ */
138
+ function rankListForPolicy(list, deps, policy) {
139
+ if (policy !== "boost-per-list")
140
+ return list;
141
+ return [...list].sort((left, right) => {
142
+ const leftScore = applyProvenanceBoost(left.score, deps.provenanceMap?.(left.docPath));
143
+ const rightScore = applyProvenanceBoost(right.score, deps.provenanceMap?.(right.docPath));
144
+ return rightScore - leftScore ||
145
+ left.docPath.localeCompare(right.docPath) ||
146
+ left.chunkOrdinal - right.chunkOrdinal;
147
+ });
148
+ }
94
149
  // ---------------------------------------------------------------------------
95
150
  // Public API
96
151
  // ---------------------------------------------------------------------------
@@ -106,16 +161,27 @@ async function dispatchOne(sub, deps, k, cancel, collection) {
106
161
  export async function dispatch(subQueries, deps, k = 10, cancel, collection) {
107
162
  const token = cancel ?? createCancelToken();
108
163
  const rrfK = deps.rrfK ?? 60;
164
+ const policy = deps.policy ?? DEFAULT_DISPATCHER_POLICY;
165
+ if (!Number.isSafeInteger(k) || k < 0) {
166
+ throw new Error("Retrieval candidate count k must be a non-negative safe integer.");
167
+ }
168
+ if (!Number.isFinite(rrfK) || rrfK < 0) {
169
+ throw new Error("RRF smoothing constant k must be a finite non-negative number.");
170
+ }
171
+ if (!DISPATCHER_POLICIES.includes(policy)) {
172
+ throw new Error(`Unknown dispatcher policy: ${String(policy)}`);
173
+ }
109
174
  if (subQueries.length === 0)
110
175
  return [];
111
176
  // Execute all sub-queries in parallel (each with its own retry envelope)
112
177
  const rankedLists = await Promise.all(subQueries.map((sub) => dispatchOne(sub, deps, k, token, collection)));
178
+ const policyLists = rankedLists.map((list) => rankListForPolicy(list, deps, policy));
113
179
  // Build per-type score index for the perTypeScores field
114
180
  // key = "docPath\0chunkOrdinal" → type → max raw score from that type
115
181
  const typeScores = new Map();
116
182
  for (let i = 0; i < subQueries.length; i++) {
117
183
  const type = subQueries[i].type;
118
- const list = rankedLists[i];
184
+ const list = policyLists[i];
119
185
  for (const hit of list) {
120
186
  const key = `${hit.docPath}\x00${hit.chunkOrdinal}`;
121
187
  const perType = typeScores.get(key) ?? new Map();
@@ -126,22 +192,32 @@ export async function dispatch(subQueries, deps, k = 10, cancel, collection) {
126
192
  }
127
193
  }
128
194
  // Fuse with RRF
129
- const fused = fuseRRF(rankedLists, rrfK);
130
- // Build final results with provenance boost and per-type breakdown
131
- return fused.map((hit) => {
195
+ const fused = fuseRRF(policyLists, rrfK, {
196
+ preserveInputOrder: policy === "boost-per-list",
197
+ });
198
+ // Build final results with provenance boost and per-type breakdown.
199
+ const results = fused.map((hit) => {
132
200
  const key = `${hit.docPath}\x00${hit.chunkOrdinal}`;
133
201
  const provenance = deps.provenanceMap?.(hit.docPath);
134
- const boost = provenance !== undefined ? PROVENANCE_BOOST[provenance] : 0;
202
+ const boost = provenance === undefined ? 0 : PROVENANCE_BOOST[provenance];
135
203
  const perTypeMap = typeScores.get(key);
136
204
  const perTypeScores = perTypeMap !== undefined && perTypeMap.size > 0
137
205
  ? Object.fromEntries(perTypeMap)
138
206
  : undefined;
139
207
  return {
140
208
  docPath: hit.docPath,
141
- score: hit.score + boost,
209
+ score: policy === "boost-additive"
210
+ ? hit.score + boost
211
+ : policy === "boost-k-scale"
212
+ ? applyProvenanceBoost(hit.score, provenance)
213
+ : hit.score,
142
214
  provenance,
143
215
  perTypeScores,
144
216
  };
145
217
  });
218
+ if (policy === "boost-additive")
219
+ return results;
220
+ return results.sort((a, b) => b.score - a.score ||
221
+ a.docPath.localeCompare(b.docPath));
146
222
  }
147
223
  //# sourceMappingURL=dispatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,8 @@
11
11
  */
12
12
  export { fuseRRF } from "./rrf.js";
13
13
  export type { Reranker } from "./reranker.js";
14
- export { PassthroughReranker, passthroughReranker } from "./reranker.js";
14
+ export { createLlamaReranker, DEFAULT_RERANKER_CANDIDATE_CAP, LlamaReranker, PassthroughReranker, passthroughReranker, } from "./reranker.js";
15
+ export type { LlamaModelLoader, LlamaRerankerOptions, RankingContext, RankingModel, } from "./reranker.js";
15
16
  export { dispatch, createCancelToken, } from "./dispatcher.js";
16
17
  export type { CancelToken, DispatcherDeps, HydeGenerator } from "./dispatcher.js";
17
18
  import type { RetrievalResult } from "../types.js";
@@ -10,7 +10,7 @@
10
10
  * - DispatcherDeps — dependency-injection bag for backends
11
11
  */
12
12
  export { fuseRRF } from "./rrf.js";
13
- export { PassthroughReranker, passthroughReranker } from "./reranker.js";
13
+ export { createLlamaReranker, DEFAULT_RERANKER_CANDIDATE_CAP, LlamaReranker, PassthroughReranker, passthroughReranker, } from "./reranker.js";
14
14
  export { dispatch, createCancelToken, } from "./dispatcher.js";
15
15
  import { dispatch } from "./dispatcher.js";
16
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EACL,QAAQ,EACR,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAkC3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAqB;IAClD,qDAAqD;IACrD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAEjG,2CAA2C;IAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC;IAEnC,2EAA2E;IAC3E,MAAM,IAAI,GAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,YAAY,EAAE,CAAC;QACf,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE9D,wEAAwE;IACxE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzC,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAA4B,CAAC;IACjE,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,EACL,mBAAmB,EACnB,8BAA8B,EAC9B,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAOvB,OAAO,EACL,QAAQ,EACR,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAkC3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAqB;IAClD,qDAAqD;IACrD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAEjG,2CAA2C;IAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC;IAEnC,2EAA2E;IAC3E,MAAM,IAAI,GAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,YAAY,EAAE,CAAC;QACf,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE9D,wEAAwE;IACxE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzC,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAA4B,CAAC;IACjE,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;AAC1D,CAAC"}
@@ -2,8 +2,10 @@
2
2
  * Cross-encoder reranker hook.
3
3
  *
4
4
  * This module defines the Reranker interface and ships a passthrough (no-op)
5
- * default so the precision-mode pipeline is wired end-to-end in M1 without
6
- * requiring a loaded reranker model.
5
+ * default so the precision-mode pipeline is wired end-to-end without
6
+ * requiring a loaded reranker model. The node-llama-cpp implementation below
7
+ * is explicitly opt-in and lazy: constructing it never loads a model or
8
+ * creates a ranking context.
7
9
  *
8
10
  * Intended production implementations (inject at the integrate phase):
9
11
  * - bge-reranker-v2-m3 (BAAI, Apache-2.0) — strong multilingual reranker,
@@ -13,6 +15,7 @@
13
15
  *
14
16
  * Wire a real impl by passing it to retrieve() as `opts.reranker`.
15
17
  */
18
+ import type { LlamaRankingContextOptions } from "node-llama-cpp";
16
19
  import type { ScoredHit } from "../types.js";
17
20
  /**
18
21
  * Opt-in cross-encoder reranker hook.
@@ -31,8 +34,81 @@ export interface Reranker {
31
34
  * @returns A new list sorted descending by the reranker's cross-encoder score.
32
35
  * The returned list may be shorter than `hits` (e.g. top-k precision cut).
33
36
  */
34
- rerank(query: string, hits: ScoredHit[]): Promise<ScoredHit[]>;
37
+ rerank(query: string, hits: ScoredHit[], cancel?: {
38
+ readonly cancelled: boolean;
39
+ }): Promise<ScoredHit[]>;
35
40
  }
41
+ /**
42
+ * Narrow seam around node-llama-cpp used by the lazy implementation.
43
+ *
44
+ * Keeping the seam injectable makes the lifecycle contract testable without
45
+ * downloading or loading a model. Production uses the default dynamic loader.
46
+ */
47
+ export interface RankingContext {
48
+ rankAll(query: string, documents: string[]): Promise<readonly number[]>;
49
+ dispose(): Promise<void>;
50
+ }
51
+ export interface RankingModel {
52
+ createRankingContext(options?: LlamaRankingContextOptions): Promise<RankingContext>;
53
+ dispose(): Promise<void>;
54
+ }
55
+ export type LlamaModelLoader = (modelPath: string) => Promise<RankingModel>;
56
+ /** Conservative candidate budget; reranking is opt-in and default-off. */
57
+ export declare const DEFAULT_RERANKER_CANDIDATE_CAP = 50;
58
+ /**
59
+ * Options for {@link createLlamaReranker}.
60
+ *
61
+ * `idleUnloadMs` is disabled by default (`0`). Enabling it is useful for
62
+ * memory-constrained hosts, but the model is otherwise retained after its
63
+ * first requested rerank so repeated opt-in calls do not reload native state.
64
+ */
65
+ export interface LlamaRerankerOptions {
66
+ readonly modelPath: string;
67
+ readonly candidateCap?: number;
68
+ readonly idleUnloadMs?: number;
69
+ readonly contextOptions?: LlamaRankingContextOptions;
70
+ /** Test seam; production callers should omit this. */
71
+ readonly loadModel?: LlamaModelLoader;
72
+ }
73
+ /**
74
+ * A lazy node-llama-cpp cross-encoder reranker.
75
+ *
76
+ * The model and `LlamaRankingContext` are created only by the first
77
+ * `rerank()` call. Only the first `candidateCap` fused hits are sent to the
78
+ * cross-encoder; hits beyond that safety budget are intentionally omitted.
79
+ * Scores are replaced with the cross-encoder scores and returned descending.
80
+ */
81
+ export declare class LlamaReranker implements Reranker {
82
+ private readonly modelPath;
83
+ private readonly candidateCap;
84
+ private readonly idleUnloadMs;
85
+ private readonly contextOptions;
86
+ private readonly loadModel;
87
+ private model;
88
+ private context;
89
+ private loadPromise;
90
+ private idleTimer;
91
+ private activeCalls;
92
+ private activeDone;
93
+ private resolveActiveDone;
94
+ private disposed;
95
+ private disposePromise;
96
+ constructor(options: LlamaRerankerOptions);
97
+ private clearIdleTimer;
98
+ private scheduleIdleUnload;
99
+ private ensureContext;
100
+ private unload;
101
+ /** Release model/context resources; safe before the first rerank call. */
102
+ dispose(): Promise<void>;
103
+ rerank(query: string, hits: ScoredHit[], cancel?: {
104
+ readonly cancelled: boolean;
105
+ }): Promise<ScoredHit[]>;
106
+ }
107
+ /**
108
+ * Construct a lazy reranker. No model import, native load, or context
109
+ * creation occurs until the returned reranker's `rerank()` is requested.
110
+ */
111
+ export declare function createLlamaReranker(options: LlamaRerankerOptions): LlamaReranker;
36
112
  /**
37
113
  * Passthrough (no-op) reranker — returns hits unchanged.
38
114
  *
@@ -40,7 +116,9 @@ export interface Reranker {
40
116
  * is available or when reranking overhead is not desired.
41
117
  */
42
118
  export declare class PassthroughReranker implements Reranker {
43
- rerank(_query: string, hits: ScoredHit[]): Promise<ScoredHit[]>;
119
+ rerank(_query: string, hits: ScoredHit[], cancel?: {
120
+ readonly cancelled: boolean;
121
+ }): Promise<ScoredHit[]>;
44
122
  }
45
123
  /** Shared singleton passthrough instance — safe to reuse across calls. */
46
124
  export declare const passthroughReranker: Reranker;
@@ -2,8 +2,10 @@
2
2
  * Cross-encoder reranker hook.
3
3
  *
4
4
  * This module defines the Reranker interface and ships a passthrough (no-op)
5
- * default so the precision-mode pipeline is wired end-to-end in M1 without
6
- * requiring a loaded reranker model.
5
+ * default so the precision-mode pipeline is wired end-to-end without
6
+ * requiring a loaded reranker model. The node-llama-cpp implementation below
7
+ * is explicitly opt-in and lazy: constructing it never loads a model or
8
+ * creates a ranking context.
7
9
  *
8
10
  * Intended production implementations (inject at the integrate phase):
9
11
  * - bge-reranker-v2-m3 (BAAI, Apache-2.0) — strong multilingual reranker,
@@ -13,6 +15,177 @@
13
15
  *
14
16
  * Wire a real impl by passing it to retrieve() as `opts.reranker`.
15
17
  */
18
+ /** Conservative candidate budget; reranking is opt-in and default-off. */
19
+ export const DEFAULT_RERANKER_CANDIDATE_CAP = 50;
20
+ async function loadLlamaModel(modelPath) {
21
+ const { getLlama } = await import("node-llama-cpp");
22
+ const llama = await getLlama();
23
+ return llama.loadModel({ modelPath });
24
+ }
25
+ /**
26
+ * A lazy node-llama-cpp cross-encoder reranker.
27
+ *
28
+ * The model and `LlamaRankingContext` are created only by the first
29
+ * `rerank()` call. Only the first `candidateCap` fused hits are sent to the
30
+ * cross-encoder; hits beyond that safety budget are intentionally omitted.
31
+ * Scores are replaced with the cross-encoder scores and returned descending.
32
+ */
33
+ export class LlamaReranker {
34
+ modelPath;
35
+ candidateCap;
36
+ idleUnloadMs;
37
+ contextOptions;
38
+ loadModel;
39
+ model = null;
40
+ context = null;
41
+ loadPromise = null;
42
+ idleTimer = null;
43
+ activeCalls = 0;
44
+ activeDone = null;
45
+ resolveActiveDone = null;
46
+ disposed = false;
47
+ disposePromise = null;
48
+ constructor(options) {
49
+ const candidateCap = options.candidateCap ?? DEFAULT_RERANKER_CANDIDATE_CAP;
50
+ if (!Number.isSafeInteger(candidateCap) || candidateCap < 1) {
51
+ throw new Error("reranker candidateCap must be a positive safe integer.");
52
+ }
53
+ const idleUnloadMs = options.idleUnloadMs ?? 0;
54
+ if (!Number.isFinite(idleUnloadMs) || idleUnloadMs < 0) {
55
+ throw new Error("reranker idleUnloadMs must be a non-negative number.");
56
+ }
57
+ if (options.modelPath.trim().length === 0) {
58
+ throw new Error("reranker modelPath must be non-empty.");
59
+ }
60
+ this.modelPath = options.modelPath;
61
+ this.candidateCap = candidateCap;
62
+ this.idleUnloadMs = idleUnloadMs;
63
+ this.contextOptions = options.contextOptions;
64
+ this.loadModel = options.loadModel ?? loadLlamaModel;
65
+ }
66
+ clearIdleTimer() {
67
+ if (this.idleTimer !== null) {
68
+ clearTimeout(this.idleTimer);
69
+ this.idleTimer = null;
70
+ }
71
+ }
72
+ scheduleIdleUnload() {
73
+ this.clearIdleTimer();
74
+ if (this.disposed || this.idleUnloadMs <= 0 || this.context === null)
75
+ return;
76
+ this.idleTimer = setTimeout(() => {
77
+ this.idleTimer = null;
78
+ if (this.activeCalls > 0) {
79
+ this.scheduleIdleUnload();
80
+ return;
81
+ }
82
+ void this.unload().catch(() => undefined);
83
+ }, this.idleUnloadMs);
84
+ }
85
+ async ensureContext() {
86
+ if (this.disposed)
87
+ throw new Error("Reranker has been disposed.");
88
+ if (this.context !== null)
89
+ return this.context;
90
+ if (this.loadPromise !== null)
91
+ return this.loadPromise;
92
+ this.loadPromise = (async () => {
93
+ const model = await this.loadModel(this.modelPath);
94
+ this.model = model;
95
+ try {
96
+ const context = await model.createRankingContext(this.contextOptions);
97
+ this.context = context;
98
+ return context;
99
+ }
100
+ catch (error) {
101
+ this.model = null;
102
+ await model.dispose().catch(() => undefined);
103
+ throw error;
104
+ }
105
+ })().finally(() => {
106
+ this.loadPromise = null;
107
+ });
108
+ return this.loadPromise;
109
+ }
110
+ async unload() {
111
+ this.clearIdleTimer();
112
+ const context = this.context;
113
+ const model = this.model;
114
+ this.context = null;
115
+ this.model = null;
116
+ if (context !== null)
117
+ await context.dispose().catch(() => undefined);
118
+ if (model !== null)
119
+ await model.dispose().catch(() => undefined);
120
+ }
121
+ /** Release model/context resources; safe before the first rerank call. */
122
+ async dispose() {
123
+ if (this.disposePromise !== null) {
124
+ return this.disposePromise;
125
+ }
126
+ this.disposed = true;
127
+ this.clearIdleTimer();
128
+ this.disposePromise = (async () => {
129
+ if (this.loadPromise !== null) {
130
+ await this.loadPromise.catch(() => undefined);
131
+ }
132
+ // Context disposal must never race a native rankAll() call. Calls
133
+ // already admitted before dispose() drain before unloading resources.
134
+ if (this.activeDone !== null)
135
+ await this.activeDone;
136
+ await this.unload();
137
+ })();
138
+ return this.disposePromise;
139
+ }
140
+ async rerank(query, hits, cancel) {
141
+ if (hits.length === 0)
142
+ return [];
143
+ if (this.disposed)
144
+ throw new Error("Reranker has been disposed.");
145
+ if (cancel?.cancelled)
146
+ throw new Error("Retrieval cancelled");
147
+ const candidates = hits.slice(0, this.candidateCap);
148
+ this.activeCalls += 1;
149
+ if (this.activeCalls === 1) {
150
+ this.activeDone = new Promise((resolve) => {
151
+ this.resolveActiveDone = resolve;
152
+ });
153
+ }
154
+ try {
155
+ const context = await this.ensureContext();
156
+ if (cancel?.cancelled)
157
+ throw new Error("Retrieval cancelled");
158
+ const scores = await context.rankAll(query, candidates.map((hit) => hit.docPath));
159
+ if (cancel?.cancelled)
160
+ throw new Error("Retrieval cancelled");
161
+ if (scores.length !== candidates.length) {
162
+ throw new Error(`reranker returned ${scores.length} scores for ${candidates.length} candidates.`);
163
+ }
164
+ if (scores.some((score) => !Number.isFinite(score))) {
165
+ throw new Error("reranker returned a non-finite score.");
166
+ }
167
+ return candidates
168
+ .map((hit, index) => ({ ...hit, score: scores[index] }))
169
+ .sort((left, right) => right.score - left.score);
170
+ }
171
+ finally {
172
+ this.activeCalls -= 1;
173
+ if (this.activeCalls === 0) {
174
+ this.resolveActiveDone?.();
175
+ this.resolveActiveDone = null;
176
+ this.activeDone = null;
177
+ }
178
+ this.scheduleIdleUnload();
179
+ }
180
+ }
181
+ }
182
+ /**
183
+ * Construct a lazy reranker. No model import, native load, or context
184
+ * creation occurs until the returned reranker's `rerank()` is requested.
185
+ */
186
+ export function createLlamaReranker(options) {
187
+ return new LlamaReranker(options);
188
+ }
16
189
  /**
17
190
  * Passthrough (no-op) reranker — returns hits unchanged.
18
191
  *
@@ -20,7 +193,9 @@
20
193
  * is available or when reranking overhead is not desired.
21
194
  */
22
195
  export class PassthroughReranker {
23
- async rerank(_query, hits) {
196
+ async rerank(_query, hits, cancel) {
197
+ if (cancel?.cancelled)
198
+ throw new Error("Retrieval cancelled");
24
199
  return hits;
25
200
  }
26
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/reranker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAwBH;;;;;GAKG;AACH,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,IAAiB;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAa,IAAI,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../../../src/kernel/engine/retrieval/reranker.ts"],"names":[],"mappings":"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"}
@@ -14,10 +14,18 @@ import type { ScoredHit } from "../types.js";
14
14
  * Fuse multiple ranked lists into a single list using Reciprocal Rank Fusion.
15
15
  *
16
16
  * @param rankedLists - Per-modality ranked hit lists. Each inner list need not be
17
- * pre-sorted; fuseRRF sorts each list descending by score before ranking.
17
+ * pre-sorted unless `preserveInputOrder` is enabled.
18
18
  * @param k - RRF smoothing constant (default 60). Higher values reduce the impact
19
19
  * of rank position; typical range is 50–70.
20
+ * @param options - Ranking behavior for each input list.
20
21
  * @returns Fused list sorted descending by RRF score. Ties are broken
21
22
  * lexicographically by the composite key `"docPath\0chunkOrdinal"`.
22
23
  */
23
- export declare function fuseRRF(rankedLists: ScoredHit[][], k?: number): ScoredHit[];
24
+ export interface FuseRRFOptions {
25
+ /**
26
+ * Treat each list as already ranked and use its supplied order. This is
27
+ * required when a caller has established rank with a non-score policy.
28
+ */
29
+ preserveInputOrder?: boolean;
30
+ }
31
+ export declare function fuseRRF(rankedLists: ScoredHit[][], k?: number, options?: FuseRRFOptions): ScoredHit[];
@@ -9,17 +9,38 @@
9
9
  * where rank_i(d) is the 1-based position of document d in list i.
10
10
  * Documents absent from a list contribute 0 for that list.
11
11
  */
12
- /**
13
- * Fuse multiple ranked lists into a single list using Reciprocal Rank Fusion.
14
- *
15
- * @param rankedLists - Per-modality ranked hit lists. Each inner list need not be
16
- * pre-sorted; fuseRRF sorts each list descending by score before ranking.
17
- * @param k - RRF smoothing constant (default 60). Higher values reduce the impact
18
- * of rank position; typical range is 50–70.
19
- * @returns Fused list sorted descending by RRF score. Ties are broken
20
- * lexicographically by the composite key `"docPath\0chunkOrdinal"`.
21
- */
22
- export function fuseRRF(rankedLists, k = 60) {
12
+ function validateRrfInputs(rankedLists, k, options) {
13
+ if (!Array.isArray(rankedLists)) {
14
+ throw new Error("RRF ranked lists must be an array.");
15
+ }
16
+ if (options === null || typeof options !== "object" || Array.isArray(options)) {
17
+ throw new Error("RRF options must be an object.");
18
+ }
19
+ if (!Number.isFinite(k) || k < 0) {
20
+ throw new Error("RRF smoothing constant k must be a finite non-negative number.");
21
+ }
22
+ if (typeof options.preserveInputOrder !== "undefined" && typeof options.preserveInputOrder !== "boolean") {
23
+ throw new Error("RRF preserveInputOrder must be a boolean.");
24
+ }
25
+ for (const list of rankedLists) {
26
+ if (!Array.isArray(list)) {
27
+ throw new Error("RRF ranked lists must be arrays of scored hits.");
28
+ }
29
+ for (const hit of list) {
30
+ if (hit === null ||
31
+ typeof hit !== "object" ||
32
+ typeof hit.docPath !== "string" ||
33
+ hit.docPath.trim().length === 0 ||
34
+ !Number.isSafeInteger(hit.chunkOrdinal) ||
35
+ hit.chunkOrdinal < 0 ||
36
+ !Number.isFinite(hit.score)) {
37
+ throw new Error("RRF scored hits must have a non-empty path, non-negative ordinal, and finite score.");
38
+ }
39
+ }
40
+ }
41
+ }
42
+ export function fuseRRF(rankedLists, k = 60, options = {}) {
43
+ validateRrfInputs(rankedLists, k, options);
23
44
  if (rankedLists.length === 0)
24
45
  return [];
25
46
  // key → { accumulated RRF score, original hit metadata }
@@ -27,11 +48,13 @@ export function fuseRRF(rankedLists, k = 60) {
27
48
  for (const list of rankedLists) {
28
49
  if (list.length === 0)
29
50
  continue;
30
- // Sort descending by score; secondary lex sort ensures deterministic ranking
31
- // when two hits in the same list have the same score.
32
- const sorted = [...list].sort((a, b) => b.score - a.score ||
33
- a.docPath.localeCompare(b.docPath) ||
34
- a.chunkOrdinal - b.chunkOrdinal);
51
+ // Dispatch policies may establish rank independently of raw score. In that
52
+ // case, preserve the caller's order rather than replacing it here.
53
+ const sorted = options.preserveInputOrder
54
+ ? list
55
+ : [...list].sort((a, b) => b.score - a.score ||
56
+ a.docPath.localeCompare(b.docPath) ||
57
+ a.chunkOrdinal - b.chunkOrdinal);
35
58
  for (let idx = 0; idx < sorted.length; idx++) {
36
59
  const hit = sorted[idx];
37
60
  const key = `${hit.docPath}\x00${hit.chunkOrdinal}`;