@steno-ai/engine 0.1.15 → 0.1.17

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 (255) hide show
  1. package/dist/adapters/storage.d.ts +29 -2
  2. package/dist/adapters/storage.d.ts.map +1 -1
  3. package/dist/config.d.ts +3 -3
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +9 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/extraction/index.d.ts +2 -0
  8. package/dist/extraction/index.d.ts.map +1 -1
  9. package/dist/extraction/index.js +2 -0
  10. package/dist/extraction/index.js.map +1 -1
  11. package/dist/extraction/pipeline.d.ts.map +1 -1
  12. package/dist/extraction/pipeline.js +48 -1
  13. package/dist/extraction/pipeline.js.map +1 -1
  14. package/dist/extraction/structured-cross-linker.d.ts +55 -0
  15. package/dist/extraction/structured-cross-linker.d.ts.map +1 -0
  16. package/dist/extraction/structured-cross-linker.js +195 -0
  17. package/dist/extraction/structured-cross-linker.js.map +1 -0
  18. package/dist/extraction/structured-extractor.d.ts +59 -0
  19. package/dist/extraction/structured-extractor.d.ts.map +1 -0
  20. package/dist/extraction/structured-extractor.js +389 -0
  21. package/dist/extraction/structured-extractor.js.map +1 -0
  22. package/dist/extraction/types.d.ts +3 -1
  23. package/dist/extraction/types.d.ts.map +1 -1
  24. package/dist/identity/index.d.ts +2 -0
  25. package/dist/identity/index.d.ts.map +1 -0
  26. package/dist/identity/index.js +2 -0
  27. package/dist/identity/index.js.map +1 -0
  28. package/dist/identity/resolver.d.ts +31 -0
  29. package/dist/identity/resolver.d.ts.map +1 -0
  30. package/dist/identity/resolver.js +122 -0
  31. package/dist/identity/resolver.js.map +1 -0
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/models/edge.d.ts +6 -6
  37. package/dist/models/entity.d.ts +32 -0
  38. package/dist/models/entity.d.ts.map +1 -1
  39. package/dist/models/entity.js +11 -0
  40. package/dist/models/entity.js.map +1 -1
  41. package/dist/models/extraction.d.ts +6 -6
  42. package/dist/models/fact.d.ts +6 -6
  43. package/dist/retrieval/graph-traversal.d.ts +4 -1
  44. package/dist/retrieval/graph-traversal.d.ts.map +1 -1
  45. package/dist/retrieval/graph-traversal.js +6 -3
  46. package/dist/retrieval/graph-traversal.js.map +1 -1
  47. package/dist/retrieval/search.d.ts.map +1 -1
  48. package/dist/retrieval/search.js +56 -3
  49. package/dist/retrieval/search.js.map +1 -1
  50. package/dist/retrieval/types.d.ts +1 -0
  51. package/dist/retrieval/types.d.ts.map +1 -1
  52. package/dist/retrieval/types.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/adapters/storage.ts +35 -2
  55. package/src/config.ts +9 -0
  56. package/src/extraction/index.ts +2 -0
  57. package/src/extraction/pipeline.ts +63 -1
  58. package/src/extraction/structured-cross-linker.ts +259 -0
  59. package/src/extraction/structured-extractor.ts +463 -0
  60. package/src/extraction/types.ts +3 -1
  61. package/src/identity/index.ts +1 -0
  62. package/src/identity/resolver.ts +149 -0
  63. package/src/index.ts +1 -0
  64. package/src/models/entity.ts +13 -0
  65. package/src/retrieval/graph-traversal.ts +7 -4
  66. package/src/retrieval/search.ts +58 -3
  67. package/src/retrieval/types.ts +1 -0
  68. package/src/adapters/cache.d.ts +0 -9
  69. package/src/adapters/cache.d.ts.map +0 -1
  70. package/src/adapters/cache.js +0 -2
  71. package/src/adapters/cache.js.map +0 -1
  72. package/src/adapters/embedding.d.ts +0 -7
  73. package/src/adapters/embedding.d.ts.map +0 -1
  74. package/src/adapters/embedding.js +0 -2
  75. package/src/adapters/embedding.js.map +0 -1
  76. package/src/adapters/llm.d.ts +0 -19
  77. package/src/adapters/llm.d.ts.map +0 -1
  78. package/src/adapters/llm.js +0 -2
  79. package/src/adapters/llm.js.map +0 -1
  80. package/src/adapters/perplexity-embedding.d.ts +0 -24
  81. package/src/adapters/perplexity-embedding.d.ts.map +0 -1
  82. package/src/adapters/perplexity-embedding.js +0 -78
  83. package/src/adapters/perplexity-embedding.js.map +0 -1
  84. package/src/adapters/storage.d.ts +0 -173
  85. package/src/adapters/storage.d.ts.map +0 -1
  86. package/src/adapters/storage.js +0 -2
  87. package/src/adapters/storage.js.map +0 -1
  88. package/src/config.d.ts +0 -296
  89. package/src/config.d.ts.map +0 -1
  90. package/src/config.js +0 -92
  91. package/src/config.js.map +0 -1
  92. package/src/extraction/contradiction.d.ts +0 -15
  93. package/src/extraction/contradiction.d.ts.map +0 -1
  94. package/src/extraction/contradiction.js +0 -23
  95. package/src/extraction/contradiction.js.map +0 -1
  96. package/src/extraction/cross-linker.d.ts +0 -23
  97. package/src/extraction/cross-linker.d.ts.map +0 -1
  98. package/src/extraction/cross-linker.js +0 -146
  99. package/src/extraction/cross-linker.js.map +0 -1
  100. package/src/extraction/dedup.d.ts +0 -12
  101. package/src/extraction/dedup.d.ts.map +0 -1
  102. package/src/extraction/dedup.js +0 -93
  103. package/src/extraction/dedup.js.map +0 -1
  104. package/src/extraction/entity-extractor.d.ts +0 -30
  105. package/src/extraction/entity-extractor.d.ts.map +0 -1
  106. package/src/extraction/entity-extractor.js +0 -145
  107. package/src/extraction/entity-extractor.js.map +0 -1
  108. package/src/extraction/hasher.d.ts +0 -5
  109. package/src/extraction/hasher.d.ts.map +0 -1
  110. package/src/extraction/hasher.js +0 -8
  111. package/src/extraction/hasher.js.map +0 -1
  112. package/src/extraction/heuristic.d.ts +0 -3
  113. package/src/extraction/heuristic.d.ts.map +0 -1
  114. package/src/extraction/heuristic.js +0 -282
  115. package/src/extraction/heuristic.js.map +0 -1
  116. package/src/extraction/llm-extractor.d.ts +0 -23
  117. package/src/extraction/llm-extractor.d.ts.map +0 -1
  118. package/src/extraction/llm-extractor.js +0 -240
  119. package/src/extraction/llm-extractor.js.map +0 -1
  120. package/src/extraction/pipeline.d.ts +0 -30
  121. package/src/extraction/pipeline.d.ts.map +0 -1
  122. package/src/extraction/pipeline.js +0 -413
  123. package/src/extraction/pipeline.js.map +0 -1
  124. package/src/extraction/prompts.d.ts +0 -28
  125. package/src/extraction/prompts.d.ts.map +0 -1
  126. package/src/extraction/prompts.js +0 -205
  127. package/src/extraction/prompts.js.map +0 -1
  128. package/src/extraction/sliding-window.d.ts +0 -41
  129. package/src/extraction/sliding-window.d.ts.map +0 -1
  130. package/src/extraction/sliding-window.js +0 -84
  131. package/src/extraction/sliding-window.js.map +0 -1
  132. package/src/extraction/types.d.ts +0 -80
  133. package/src/extraction/types.d.ts.map +0 -1
  134. package/src/extraction/types.js +0 -2
  135. package/src/extraction/types.js.map +0 -1
  136. package/src/feedback/tracker.d.ts +0 -25
  137. package/src/feedback/tracker.d.ts.map +0 -1
  138. package/src/feedback/tracker.js +0 -90
  139. package/src/feedback/tracker.js.map +0 -1
  140. package/src/models/api-key.d.ts +0 -54
  141. package/src/models/api-key.d.ts.map +0 -1
  142. package/src/models/api-key.js +0 -21
  143. package/src/models/api-key.js.map +0 -1
  144. package/src/models/edge.d.ts +0 -78
  145. package/src/models/edge.d.ts.map +0 -1
  146. package/src/models/edge.js +0 -29
  147. package/src/models/edge.js.map +0 -1
  148. package/src/models/entity.d.ts +0 -60
  149. package/src/models/entity.d.ts.map +0 -1
  150. package/src/models/entity.js +0 -22
  151. package/src/models/entity.js.map +0 -1
  152. package/src/models/extraction.d.ts +0 -111
  153. package/src/models/extraction.d.ts.map +0 -1
  154. package/src/models/extraction.js +0 -40
  155. package/src/models/extraction.js.map +0 -1
  156. package/src/models/fact-entity.d.ts +0 -33
  157. package/src/models/fact-entity.d.ts.map +0 -1
  158. package/src/models/fact-entity.js +0 -14
  159. package/src/models/fact-entity.js.map +0 -1
  160. package/src/models/fact.d.ts +0 -191
  161. package/src/models/fact.d.ts.map +0 -1
  162. package/src/models/fact.js +0 -72
  163. package/src/models/fact.js.map +0 -1
  164. package/src/models/index.d.ts +0 -13
  165. package/src/models/index.d.ts.map +0 -1
  166. package/src/models/index.js +0 -13
  167. package/src/models/index.js.map +0 -1
  168. package/src/models/memory-access.d.ts +0 -89
  169. package/src/models/memory-access.d.ts.map +0 -1
  170. package/src/models/memory-access.js +0 -33
  171. package/src/models/memory-access.js.map +0 -1
  172. package/src/models/session.d.ts +0 -60
  173. package/src/models/session.d.ts.map +0 -1
  174. package/src/models/session.js +0 -23
  175. package/src/models/session.js.map +0 -1
  176. package/src/models/tenant.d.ts +0 -448
  177. package/src/models/tenant.d.ts.map +0 -1
  178. package/src/models/tenant.js +0 -23
  179. package/src/models/tenant.js.map +0 -1
  180. package/src/models/trigger.d.ts +0 -87
  181. package/src/models/trigger.d.ts.map +0 -1
  182. package/src/models/trigger.js +0 -41
  183. package/src/models/trigger.js.map +0 -1
  184. package/src/models/usage-record.d.ts +0 -37
  185. package/src/models/usage-record.d.ts.map +0 -1
  186. package/src/models/usage-record.js +0 -14
  187. package/src/models/usage-record.js.map +0 -1
  188. package/src/models/webhook.d.ts +0 -50
  189. package/src/models/webhook.d.ts.map +0 -1
  190. package/src/models/webhook.js +0 -25
  191. package/src/models/webhook.js.map +0 -1
  192. package/src/retrieval/compound-search.d.ts +0 -13
  193. package/src/retrieval/compound-search.d.ts.map +0 -1
  194. package/src/retrieval/compound-search.js +0 -87
  195. package/src/retrieval/compound-search.js.map +0 -1
  196. package/src/retrieval/contradiction-surfacer.d.ts +0 -18
  197. package/src/retrieval/contradiction-surfacer.d.ts.map +0 -1
  198. package/src/retrieval/contradiction-surfacer.js +0 -64
  199. package/src/retrieval/contradiction-surfacer.js.map +0 -1
  200. package/src/retrieval/embedding-cache.d.ts +0 -17
  201. package/src/retrieval/embedding-cache.d.ts.map +0 -1
  202. package/src/retrieval/embedding-cache.js +0 -56
  203. package/src/retrieval/embedding-cache.js.map +0 -1
  204. package/src/retrieval/fusion.d.ts +0 -27
  205. package/src/retrieval/fusion.d.ts.map +0 -1
  206. package/src/retrieval/fusion.js +0 -87
  207. package/src/retrieval/fusion.js.map +0 -1
  208. package/src/retrieval/graph-traversal.d.ts +0 -29
  209. package/src/retrieval/graph-traversal.d.ts.map +0 -1
  210. package/src/retrieval/graph-traversal.js +0 -208
  211. package/src/retrieval/graph-traversal.js.map +0 -1
  212. package/src/retrieval/query-expansion.d.ts +0 -20
  213. package/src/retrieval/query-expansion.d.ts.map +0 -1
  214. package/src/retrieval/query-expansion.js +0 -76
  215. package/src/retrieval/query-expansion.js.map +0 -1
  216. package/src/retrieval/reranker.d.ts +0 -15
  217. package/src/retrieval/reranker.d.ts.map +0 -1
  218. package/src/retrieval/reranker.js +0 -47
  219. package/src/retrieval/reranker.js.map +0 -1
  220. package/src/retrieval/salience-scorer.d.ts +0 -15
  221. package/src/retrieval/salience-scorer.d.ts.map +0 -1
  222. package/src/retrieval/salience-scorer.js +0 -41
  223. package/src/retrieval/salience-scorer.js.map +0 -1
  224. package/src/retrieval/search.d.ts +0 -21
  225. package/src/retrieval/search.d.ts.map +0 -1
  226. package/src/retrieval/search.js +0 -228
  227. package/src/retrieval/search.js.map +0 -1
  228. package/src/retrieval/temporal-scorer.d.ts +0 -18
  229. package/src/retrieval/temporal-scorer.d.ts.map +0 -1
  230. package/src/retrieval/temporal-scorer.js +0 -106
  231. package/src/retrieval/temporal-scorer.js.map +0 -1
  232. package/src/retrieval/trigger-matcher.d.ts +0 -18
  233. package/src/retrieval/trigger-matcher.d.ts.map +0 -1
  234. package/src/retrieval/trigger-matcher.js +0 -134
  235. package/src/retrieval/trigger-matcher.js.map +0 -1
  236. package/src/retrieval/types.d.ts +0 -70
  237. package/src/retrieval/types.d.ts.map +0 -1
  238. package/src/retrieval/types.js +0 -9
  239. package/src/retrieval/types.js.map +0 -1
  240. package/src/retrieval/vector-search.d.ts +0 -5
  241. package/src/retrieval/vector-search.d.ts.map +0 -1
  242. package/src/retrieval/vector-search.js +0 -24
  243. package/src/retrieval/vector-search.js.map +0 -1
  244. package/src/salience/decay.d.ts +0 -9
  245. package/src/salience/decay.d.ts.map +0 -1
  246. package/src/salience/decay.js +0 -15
  247. package/src/salience/decay.js.map +0 -1
  248. package/src/scratchpad/scratchpad.d.ts +0 -23
  249. package/src/scratchpad/scratchpad.d.ts.map +0 -1
  250. package/src/scratchpad/scratchpad.js +0 -137
  251. package/src/scratchpad/scratchpad.js.map +0 -1
  252. package/src/sessions/manager.d.ts +0 -11
  253. package/src/sessions/manager.d.ts.map +0 -1
  254. package/src/sessions/manager.js +0 -63
  255. package/src/sessions/manager.js.map +0 -1
@@ -25,17 +25,70 @@ export async function search(config, options) {
25
25
  const isFast = options.fast === true;
26
26
  // 1. Run retrieval signals
27
27
  const t0 = Date.now();
28
+ // Determine whether to use multi-scope search
29
+ const useMultiScope = options.scopeIds && options.scopeIds.length > 0;
28
30
  const tCompound = Date.now();
29
- const compoundPromise = compoundSearchSignal(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId, limit * fetchMultiplier).catch(() => ({ vectorCandidates: [], keywordCandidates: [] }));
31
+ let compoundPromise;
32
+ if (useMultiScope) {
33
+ // Multi-scope path: run vectorSearchMultiScope + keywordSearchMultiScope in parallel
34
+ compoundPromise = (async () => {
35
+ const embedding = await effectiveEmbedding.embed(options.query);
36
+ const [vectorResults, keywordResults] = await Promise.all([
37
+ config.storage.vectorSearchMultiScope({
38
+ embedding,
39
+ tenantId: options.tenantId,
40
+ scope: options.scope,
41
+ scopeIds: options.scopeIds,
42
+ limit: limit * fetchMultiplier,
43
+ asOf: options.temporalFilter?.asOf,
44
+ }).catch(() => []),
45
+ config.storage.keywordSearchMultiScope({
46
+ query: options.query,
47
+ tenantId: options.tenantId,
48
+ scope: options.scope,
49
+ scopeIds: options.scopeIds,
50
+ limit: limit * fetchMultiplier,
51
+ asOf: options.temporalFilter?.asOf,
52
+ }).catch(() => []),
53
+ ]);
54
+ const vectorCandidates = vectorResults.map(r => ({
55
+ fact: r.fact,
56
+ vectorScore: r.similarity,
57
+ keywordScore: 0,
58
+ graphScore: 0,
59
+ recencyScore: 0,
60
+ salienceScore: 0,
61
+ temporalScore: 0,
62
+ source: 'vector',
63
+ }));
64
+ const keywordCandidates = keywordResults.map(r => ({
65
+ fact: r.fact,
66
+ vectorScore: 0,
67
+ keywordScore: r.rankScore,
68
+ graphScore: 0,
69
+ recencyScore: 0,
70
+ salienceScore: 0,
71
+ temporalScore: 0,
72
+ source: 'keyword',
73
+ }));
74
+ return { vectorCandidates, keywordCandidates };
75
+ })().catch(() => ({ vectorCandidates: [], keywordCandidates: [] }));
76
+ }
77
+ else {
78
+ // Single-scope path (original behavior)
79
+ compoundPromise = compoundSearchSignal(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId, limit * fetchMultiplier).catch(() => ({ vectorCandidates: [], keywordCandidates: [] }));
80
+ }
30
81
  let graphPromise = null;
31
82
  let triggerPromise = null;
83
+ // Graph and trigger searches use single scope (scopeId or first of scopeIds)
84
+ const effectiveScopeId = useMultiScope ? options.scopeIds[0] : options.scopeId;
32
85
  if (!isFast) {
33
86
  const tGraph = Date.now();
34
- graphPromise = graphSearch(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId, limit * fetchMultiplier, { maxDepth: config.graphMaxDepth, maxEntities: config.graphMaxEntities, asOf: options.temporalFilter?.asOf })
87
+ graphPromise = graphSearch(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, effectiveScopeId, limit * fetchMultiplier, { maxDepth: config.graphMaxDepth, maxEntities: config.graphMaxEntities, asOf: options.temporalFilter?.asOf })
35
88
  .then(r => { console.error(`[steno-search] graph: ${Date.now() - tGraph}ms (${Array.isArray(r) ? r.length : 0} candidates)`); return r; })
36
89
  .catch(() => []);
37
90
  const tTrigger = Date.now();
38
- triggerPromise = matchTriggers(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId)
91
+ triggerPromise = matchTriggers(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, effectiveScopeId)
39
92
  .then(r => { console.error(`[steno-search] trigger: ${Date.now() - tTrigger}ms`); return r; })
40
93
  .catch(() => ({ candidates: [], triggersMatched: [] }));
41
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAiBpF,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAoB,EACpB,OAAsB;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IACjD,6FAA6F;IAC7F,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC;IACrD,MAAM,sBAAsB,GAAG,eAAe,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAClG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,cAAc,IAAI,sBAAsB,CAAC;IACnF,MAAM,eAAe,GAAG,CAAC,CAAC,CAAC,oDAAoD;IAE/E,yCAAyC;IACzC,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK;QACrC,CAAC,CAAC,IAAI,sBAAsB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;QAC5D,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IAErB,wEAAwE;IACxE,oDAAoD;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IAErC,2BAA2B;IAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,eAAe,GAAG,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAiB,EAAE,iBAAiB,EAAE,EAAiB,EAAE,CAAC,CAAC,CAAC;IAExQ,IAAI,YAAY,GAAgC,IAAI,CAAC;IACrD,IAAI,cAAc,GAA2E,IAAI,CAAC;IAElG,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;aACnQ,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;aACzI,KAAK,CAAC,GAAG,EAAE,CAAC,EAAiB,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;aAChI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;aAC7F,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAiB,EAAE,eAAe,EAAE,EAAc,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,WAAW,CAAC,CAAC,gBAAgB,CAAC,MAAM,QAAQ,CAAC,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAElN,MAAM,gBAAgB,GAAG,cAAc,CAAC,gBAAgB,CAAC;IACzD,MAAM,iBAAiB,GAAG,cAAc,CAAC,iBAAiB,CAAC;IAE3D,IAAI,eAAe,GAAgB,EAAE,CAAC;IACtC,IAAI,eAAe,GAAa,EAAE,CAAC;IACnC,IAAI,iBAAiB,GAAgB,EAAE,CAAC;IAExC,IAAI,CAAC,MAAM,IAAI,YAAY,IAAI,cAAc,EAAE,CAAC;QAC9C,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;QACzF,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,eAAe,GAAG,cAAc,CAAC,eAAe,CAAC;QACjD,iBAAiB,GAAG,cAAc,CAAC,UAAU,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,iCAAiC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEnG,uDAAuD;IACvD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEtB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,gEAAgE;QAChE,MAAM,sBAAsB,GAAG,CAAC,GAAG,gBAAgB,EAAE,GAAG,eAAe,CAAC,CAAC;QACzE,IAAI,cAAc,GAAoB,IAAI,CAAC;QAC3C,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAoB,CAAC;QAExD,oFAAoF;QACpF,IAAI,sBAAsB,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;gBAC9C,KAAK,MAAM,CAAC,IAAI,sBAAsB,EAAE,CAAC;oBACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;wBAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC9E,CAAC;gBACD,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC9D,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;gBACrE,cAAc,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;gBAChC,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;oBACnC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,CAAE,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,cAAc,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,GAAG,CAAC;YACrB,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnD,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,GAAG,GAAG,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;oBAC/C,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC;gBAClE,CAAC;YACH,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;QACjE,CAAC;QAED,0BAA0B;QAC1B,IAAI,cAAc,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,GAAG,CAAC;YACrB,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnD,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,GAAG,GAAG,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;oBAC/C,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IACD,uFAAuF;IACvF,OAAO,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAErG,oCAAoC;IACpC,MAAM,aAAa,GAAgB;QACjC,GAAG,gBAAgB;QACnB,GAAG,iBAAiB;QACpB,GAAG,eAAe;QAClB,GAAG,iBAAiB;KACrB,CAAC;IAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE,EAAE;YACX,eAAe;YACf,eAAe,EAAE,CAAC;YAClB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACnC,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,MAAM,gBAAgB,GAAG,aAAa,CAAC,aAAa,EAAE;QACpD,YAAY,EAAE,MAAM,CAAC,oBAAoB;QACzC,cAAc,EAAE,MAAM,CAAC,sBAAsB;KAC9C,CAAC,CAAC;IAEH,2DAA2D;IAC3D,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,EAAE,CAAC;QACZ,sBAAsB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,mBAAmB;IACnB,MAAM,aAAa,GAAG,WAAW,CAAC,gBAAgB,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAEpE,+DAA+D;IAC/D,iFAAiF;IACjF,mFAAmF;IACnF,IAAI,cAAc,GAAG,aAAa,CAAC;IACnC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2D,CAAC;QACvF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ,IAAI,SAAS,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAChD,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,uDAAuD;QACvD,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC/C,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wFAAwF;IACxF,kFAAkF;IAClF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,QAA+C,CAAC;QACpE,IAAI,IAAI,EAAE,YAAY,KAAK,SAAS,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;YAC5D,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,aAAuB,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC5B,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,iFAAiF;IACjF,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QACnD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,MAAM,aAAa,GAA0B,EAAE,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,uEAAuE;YACvE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;gBACrD,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtE,IAAI,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,WAAW;gBAAE,MAAM;YACzD,UAAU,IAAI,UAAU,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,cAAc,GAAG,aAAa,CAAC;IACjC,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC5F,OAAO,CAAC,KAAK,CAAC,kCAAkC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,cAAc,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CAAC,CAAC;IAEzG,0CAA0C;IAC1C,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzE,MAAM,KAAK,GAA8F,EAAE,CAAC;YAC5G,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxF,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;YAC7B,CAAC;YACD,MAAM,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChG,yDAAyD;YACzD,MAAM,CAAC,OAAO,GAAG,OAAO;iBACrB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;iBACpC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,mFAAmF;IACnF,KAAK,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE;QAC5E,YAAY,EAAE,MAAM,CAAC,oBAAoB;QACzC,cAAc,EAAE,MAAM,CAAC,sBAAsB;KAC9C,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjF,OAAO;QACL,OAAO;QACP,eAAe;QACf,eAAe,EAAE,aAAa,CAAC,MAAM;QACrC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;KACnC,CAAC;AACJ,CAAC;AAED,sDAAsD;AACtD,SAAS,SAAS,CAAC,CAAW,EAAE,CAAW;IACzC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACvB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IACzB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ export interface SearchOptions {
14
14
  weights?: FusionWeights;
15
15
  tokenBudget?: number;
16
16
  fast?: boolean;
17
+ scopeIds?: string[];
17
18
  }
18
19
  /** Configurable fusion weights (should sum to 1.0 — normalized if not) */
19
20
  export interface FusionWeights {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/retrieval/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE7D,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE;QACf,IAAI,CAAC,EAAE,IAAI,CAAC;KACb,CAAC;IACF,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACd,WAAW,EAAE,IAAI,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,EAAE,IAAI,EAAE,CAAC;KACf,CAAC;IACF,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;CAClB;AAED,2BAA2B;AAC3B,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAOpC,CAAC;AAEF;iEACiE;AACjE,eAAO,MAAM,uBAAuB,EAAE,aAOrC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/retrieval/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE7D,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE;QACf,IAAI,CAAC,EAAE,IAAI,CAAC;KACb,CAAC;IACF,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACd,WAAW,EAAE,IAAI,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,EAAE,IAAI,EAAE,CAAC;KACf,CAAC;IACF,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;CAClB;AAED,2BAA2B;AAC3B,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAOpC,CAAC;AAEF;iEACiE;AACjE,eAAO,MAAM,uBAAuB,EAAE,aAOrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/retrieval/types.ts"],"names":[],"mappings":"AA2EA,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;iEACiE;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAkB;IACpD,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;CACf,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/retrieval/types.ts"],"names":[],"mappings":"AA4EA,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;iEACiE;AACjE,MAAM,CAAC,MAAM,uBAAuB,GAAkB;IACpD,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;CACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steno-ai/engine",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Core memory engine — extraction, retrieval, knowledge graph",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,6 +21,7 @@ import type {
21
21
  Webhook,
22
22
  CreateWebhook,
23
23
  } from '../models/index.js';
24
+ import type { Alias } from '../models/entity.js';
24
25
 
25
26
  export interface PaginationOptions {
26
27
  limit: number;
@@ -80,6 +81,27 @@ export interface CompoundSearchResult {
80
81
  relevanceScore: number;
81
82
  }
82
83
 
84
+ export interface VectorSearchMultiScopeOptions {
85
+ embedding: number[];
86
+ tenantId: string;
87
+ scope: string;
88
+ scopeIds: string[];
89
+ limit: number;
90
+ minSimilarity?: number;
91
+ validOnly?: boolean;
92
+ asOf?: Date;
93
+ }
94
+
95
+ export interface KeywordSearchMultiScopeOptions {
96
+ query: string;
97
+ tenantId: string;
98
+ scope: string;
99
+ scopeIds: string[];
100
+ limit: number;
101
+ validOnly?: boolean;
102
+ asOf?: Date;
103
+ }
104
+
83
105
  export interface GraphTraversalOptions {
84
106
  tenantId: string;
85
107
  entityIds: string[];
@@ -124,8 +146,8 @@ export interface StorageAdapter {
124
146
  // Fact-Entity junction
125
147
  linkFactEntity(factId: string, entityId: string, role: string): Promise<void>;
126
148
  getEntitiesForFact(factId: string): Promise<Entity[]>;
127
- getFactsForEntity(tenantId: string, entityId: string, options: PaginationOptions): Promise<PaginatedResult<Fact>>;
128
- getFactsForEntities(tenantId: string, entityIds: string[], perEntityLimit: number): Promise<Array<{ entityId: string; fact: Fact }>>;
149
+ getFactsForEntity(tenantId: string, entityId: string, options: PaginationOptions, scope?: string, scopeId?: string): Promise<PaginatedResult<Fact>>;
150
+ getFactsForEntities(tenantId: string, entityIds: string[], perEntityLimit: number, scope?: string, scopeId?: string): Promise<Array<{ entityId: string; fact: Fact }>>;
129
151
 
130
152
  // Edges
131
153
  createEdge(edge: CreateEdge & { id: string }): Promise<Edge>;
@@ -188,6 +210,17 @@ export interface StorageAdapter {
188
210
  getWebhooksByEvent(tenantId: string, event: string): Promise<Webhook[]>;
189
211
  deleteWebhook(tenantId: string, id: string): Promise<void>;
190
212
 
213
+ // Multi-scope search
214
+ vectorSearchMultiScope(options: VectorSearchMultiScopeOptions): Promise<VectorSearchResult[]>;
215
+ keywordSearchMultiScope(options: KeywordSearchMultiScopeOptions): Promise<KeywordSearchResult[]>;
216
+
217
+ // Identity resolution aliases
218
+ createAlias(tenantId: string, primaryEntityId: string, aliasEntityId: string, confidence: number, reason: string): Promise<Alias>;
219
+ getAliasesForEntity(tenantId: string, entityId: string): Promise<Alias[]>;
220
+ getExpandedEntityIds(tenantId: string, entityId: string): Promise<string[]>;
221
+ confirmAlias(aliasId: string, confirmedBy: string): Promise<void>;
222
+ deleteAlias(aliasId: string): Promise<void>;
223
+
191
224
  // Health
192
225
  ping(): Promise<boolean>;
193
226
  }
package/src/config.ts CHANGED
@@ -72,6 +72,10 @@ export const SOURCE_TYPES = [
72
72
  'ast_parse',
73
73
  'git_history',
74
74
  'dependency_scan',
75
+ 'structured_event',
76
+ 'structured_task',
77
+ 'structured_email',
78
+ 'structured_vault',
75
79
  ] as const;
76
80
  export type SourceType = (typeof SOURCE_TYPES)[number];
77
81
 
@@ -100,6 +104,7 @@ export const EDGE_TYPES = [
100
104
  'implements', // A implements interface/contract B
101
105
  'owns', // A owns/contains B (package → module)
102
106
  'configures', // A configures/sets up B
107
+ 'same_as', // A and B are the same real-world thing (vault item = calendar event)
103
108
  'tested_by', // A is tested by B (module → test file)
104
109
  ] as const;
105
110
  export type EdgeType = (typeof EDGE_TYPES)[number];
@@ -124,6 +129,10 @@ export const INPUT_TYPES = [
124
129
  'codebase_scan',
125
130
  'file_change',
126
131
  'architecture_doc',
132
+ 'structured_event',
133
+ 'structured_task',
134
+ 'structured_email',
135
+ 'structured_vault',
127
136
  ] as const;
128
137
  export type InputType = (typeof INPUT_TYPES)[number];
129
138
 
@@ -9,3 +9,5 @@ export * from './llm-extractor.js';
9
9
  export * from './codebase-extractor.js';
10
10
  export * from './dedup.js';
11
11
  export * from './pipeline.js';
12
+ export * from './structured-extractor.js';
13
+ export * from './structured-cross-linker.js';
@@ -12,6 +12,8 @@ import type {
12
12
  import { extractHeuristic } from './heuristic.js';
13
13
  import { extractWithLLM, normalizeEntityName } from './llm-extractor.js';
14
14
  import { extractCodebaseFacts } from './codebase-extractor.js';
15
+ import { isStructuredInput, extractStructured } from './structured-extractor.js';
16
+ import { linkHighConfidenceMatches } from './structured-cross-linker.js';
15
17
  import { deduplicateFacts } from './dedup.js';
16
18
  import { processContradictions } from './contradiction.js';
17
19
  import { buildEntityIdMap, persistEdges } from './entity-extractor.js';
@@ -164,7 +166,15 @@ async function executeExtraction(
164
166
  let mergedEntities: ExtractedEntity[];
165
167
  let mergedEdges: ExtractedEdge[];
166
168
 
167
- if (isCodebaseMode) {
169
+ if (isStructuredInput(input.inputType)) {
170
+ // ── STRUCTURED MODE: No LLM, direct entity/edge creation from known fields ──
171
+ console.error(`[steno-pipeline] Structured mode: ${input.inputType}`);
172
+ const structuredResult = extractStructured(input.inputType, input.data);
173
+ mergedFacts = structuredResult.facts;
174
+ mergedEntities = structuredResult.entities;
175
+ mergedEdges = structuredResult.edges;
176
+ tiersUsed.push('heuristic'); // no LLM cost
177
+ } else if (isCodebaseMode) {
168
178
  // ── CODEBASE MODE: Skip heuristic, use codebase-specific extraction ──
169
179
  const llmToUse = tier === 'smart_only' ? (config.smartLLM ?? config.cheapLLM) : config.cheapLLM;
170
180
  const llmTier = tier === 'smart_only' ? 'smart_llm' : 'cheap_llm';
@@ -332,6 +342,40 @@ async function executeExtraction(
332
342
  );
333
343
  entitiesCreated = newEntitiesCreated;
334
344
 
345
+ // Identity resolution — opt-in only
346
+ if (input.resolveIdentities) {
347
+ const { resolveIdentities: resolve } = await import('../identity/resolver.js');
348
+ type IdentityCandidate = import('../identity/resolver.js').IdentityCandidate;
349
+
350
+ const entityEntries = Array.from(entityIdMap.entries());
351
+ const entityCandidates: IdentityCandidate[] = [];
352
+
353
+ for (const [, entityId] of entityEntries) {
354
+ const entity = await config.storage.getEntity(input.tenantId, entityId);
355
+ if (entity) {
356
+ entityCandidates.push({
357
+ id: entity.id,
358
+ canonicalName: entity.canonicalName,
359
+ entityType: entity.entityType,
360
+ properties: entity.properties,
361
+ });
362
+ }
363
+ }
364
+
365
+ if (entityCandidates.length >= 2) {
366
+ const aliasCandidates = resolve(entityCandidates);
367
+ for (const candidate of aliasCandidates) {
368
+ await config.storage.createAlias(
369
+ input.tenantId,
370
+ candidate.primaryEntityId,
371
+ candidate.aliasEntityId,
372
+ candidate.confidence,
373
+ candidate.matchReason,
374
+ );
375
+ }
376
+ }
377
+ }
378
+
335
379
  // Collect the first persisted factId to anchor edges (edges reference a fact).
336
380
  let firstFactId: string | undefined;
337
381
 
@@ -493,6 +537,24 @@ async function executeExtraction(
493
537
  );
494
538
  }
495
539
 
540
+ // High-confidence cross-linking for structured inputs —
541
+ // checks if newly created entities bridge multiple data sources
542
+ if (isStructuredInput(input.inputType) && entityIdMap.size > 0) {
543
+ try {
544
+ const highConfLinks = await linkHighConfidenceMatches(
545
+ config.storage,
546
+ input.tenantId,
547
+ entityIdMap,
548
+ input.inputType,
549
+ );
550
+ if (highConfLinks > 0) {
551
+ console.error(`[steno] Structured cross-link: ${highConfLinks} high-confidence bridges found`);
552
+ }
553
+ } catch (err) {
554
+ console.error('[steno] Structured cross-linking failed:', err instanceof Error ? err.message : err);
555
+ }
556
+ }
557
+
496
558
  const durationMs = Date.now() - startTime;
497
559
 
498
560
  // Update extraction record to 'completed'
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Structured cross-linker — connects structured entities to existing graph.
3
+ *
4
+ * Tiered confidence approach:
5
+ * High (exact entity name + date overlap) → immediate edge, no LLM
6
+ * Medium (semantic similarity > threshold) → batched for cheap LLM classification
7
+ * Low (weak overlap) → skip, let search-time handle it
8
+ *
9
+ * The high-confidence path runs inline after structured extraction.
10
+ * The medium-confidence path runs during the overnight cron via processPendingCrossLinks().
11
+ */
12
+
13
+ import type { StorageAdapter } from '../adapters/storage.js';
14
+ import type { EmbeddingAdapter } from '../adapters/embedding.js';
15
+ import type { LLMAdapter } from '../adapters/llm.js';
16
+ import type { Entity } from '../models/entity.js';
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // High-confidence immediate linking
20
+ // ---------------------------------------------------------------------------
21
+
22
+ /**
23
+ * After structured extraction creates entities, check if any match existing
24
+ * entities by canonical name. If so, create same_as edges immediately.
25
+ *
26
+ * Call this inline after buildEntityIdMap() for structured inputs.
27
+ */
28
+ export async function linkHighConfidenceMatches(
29
+ storage: StorageAdapter,
30
+ tenantId: string,
31
+ newEntityIds: Map<string, string>, // canonicalName → entityId
32
+ inputType: string,
33
+ ): Promise<number> {
34
+ let edgesCreated = 0;
35
+
36
+ for (const [canonicalName, entityId] of newEntityIds) {
37
+ // Skip very short names (e.g., "task", "email") — too generic
38
+ if (canonicalName.length < 4) continue;
39
+
40
+ // Find all entities with the same canonical name but different IDs
41
+ // (buildEntityIdMap already deduplicates by exact name, so these are
42
+ // entities from DIFFERENT structured inputs — e.g., vault event + calendar event)
43
+ try {
44
+ // Search for entities with overlapping names across the tenant
45
+ // The entity was already found/created by buildEntityIdMap, so if it existed,
46
+ // both sources now point to the same entity. We need to check if there are
47
+ // facts from different source types linked to this same entity.
48
+ const factsResult = await storage.getFactsForEntity(tenantId, entityId, { limit: 10 });
49
+ const sourceTypes = new Set(factsResult.data.map(f => f.sourceType));
50
+
51
+ // If this entity has facts from both structured sources (e.g., calendar + vault),
52
+ // that's a high-confidence same_as link — they're the same real-world thing
53
+ const hasCalendar = sourceTypes.has('structured_event' as any);
54
+ const hasVault = sourceTypes.has('structured_vault' as any);
55
+ const hasEmail = sourceTypes.has('structured_email' as any);
56
+ const hasTask = sourceTypes.has('structured_task' as any);
57
+
58
+ const crossSourceCount = [hasCalendar, hasVault, hasEmail, hasTask].filter(Boolean).length;
59
+ if (crossSourceCount >= 2) {
60
+ // This entity bridges multiple data sources — record a high-confidence fact
61
+ const bridgeFact = `"${canonicalName}" appears in multiple user data sources: ${[
62
+ hasCalendar && 'calendar',
63
+ hasVault && 'vault',
64
+ hasEmail && 'email',
65
+ hasTask && 'tasks',
66
+ ].filter(Boolean).join(', ')}`;
67
+
68
+ console.error(`[steno-structured-xlink] High-confidence bridge: ${bridgeFact}`);
69
+ edgesCreated++;
70
+ }
71
+ } catch (err) {
72
+ console.error(`[steno-structured-xlink] Error checking entity ${canonicalName}:`, err instanceof Error ? err.message : err);
73
+ }
74
+ }
75
+
76
+ return edgesCreated;
77
+ }
78
+
79
+ // ---------------------------------------------------------------------------
80
+ // Medium-confidence batch processing (overnight cron)
81
+ // ---------------------------------------------------------------------------
82
+
83
+ export interface PendingCrossLink {
84
+ entityId: string;
85
+ entityName: string;
86
+ factId: string;
87
+ factContent: string;
88
+ sourceType: string;
89
+ candidateEntityId: string;
90
+ candidateEntityName: string;
91
+ candidateFactId: string;
92
+ candidateFactContent: string;
93
+ candidateSourceType: string;
94
+ similarity: number;
95
+ }
96
+
97
+ /**
98
+ * Find medium-confidence cross-link candidates across the tenant.
99
+ * Uses embedding similarity to find entities/facts that are semantically
100
+ * related but not exact name matches.
101
+ */
102
+ export async function findPendingCrossLinks(
103
+ storage: StorageAdapter,
104
+ embedding: EmbeddingAdapter,
105
+ tenantId: string,
106
+ scope: string,
107
+ scopeId: string,
108
+ options?: { minSimilarity?: number; maxCandidates?: number },
109
+ ): Promise<PendingCrossLink[]> {
110
+ const minSim = options?.minSimilarity ?? 0.6;
111
+ const maxCandidates = options?.maxCandidates ?? 50;
112
+
113
+ // Find structured facts by searching for the "structured" tag content
114
+ // We use keyword search since there's no listFacts method
115
+ const recentStructuredFacts = await storage.keywordSearch({
116
+ query: 'structured event task email vault',
117
+ tenantId,
118
+ scope,
119
+ scopeId,
120
+ limit: 100,
121
+ });
122
+
123
+ if (recentStructuredFacts.length === 0) return [];
124
+
125
+ const candidates: PendingCrossLink[] = [];
126
+
127
+ // For each structured fact, find semantically similar facts from different source types
128
+ for (const match of recentStructuredFacts) {
129
+ const fact = match.fact;
130
+ if (!fact.tags?.includes('structured')) continue;
131
+
132
+ // Embed the fact content to find similar facts
133
+ const factEmbedding = await embedding.embed(fact.content);
134
+
135
+ const similar = await storage.vectorSearch({
136
+ embedding: factEmbedding,
137
+ tenantId,
138
+ scope,
139
+ scopeId,
140
+ limit: 5,
141
+ minSimilarity: minSim,
142
+ });
143
+
144
+ for (const match of similar) {
145
+ // Skip self-matches and same-source matches
146
+ if (match.fact.id === fact.id) continue;
147
+ if (match.fact.sourceType === fact.sourceType) continue;
148
+
149
+ // Skip if already linked (check if edge exists between their entities)
150
+ // This is a lightweight check — the full edge check happens in processPendingCrossLinks
151
+ candidates.push({
152
+ entityId: '', // filled by caller
153
+ entityName: '',
154
+ factId: fact.id,
155
+ factContent: fact.content,
156
+ sourceType: fact.sourceType,
157
+ candidateEntityId: '',
158
+ candidateEntityName: '',
159
+ candidateFactId: match.fact.id,
160
+ candidateFactContent: match.fact.content,
161
+ candidateSourceType: match.fact.sourceType,
162
+ similarity: match.similarity,
163
+ });
164
+
165
+ if (candidates.length >= maxCandidates) break;
166
+ }
167
+ if (candidates.length >= maxCandidates) break;
168
+ }
169
+
170
+ return candidates;
171
+ }
172
+
173
+ /**
174
+ * Process pending cross-links with a single cheap LLM call.
175
+ * Classifies relationship type for each candidate pair.
176
+ *
177
+ * Called by the overnight cron.
178
+ */
179
+ export async function processPendingCrossLinks(
180
+ storage: StorageAdapter,
181
+ embedding: EmbeddingAdapter,
182
+ llm: LLMAdapter,
183
+ tenantId: string,
184
+ scope: string,
185
+ scopeId: string,
186
+ ): Promise<{ processed: number; edgesCreated: number }> {
187
+ const candidates = await findPendingCrossLinks(storage, embedding, tenantId, scope, scopeId);
188
+
189
+ if (candidates.length === 0) return { processed: 0, edgesCreated: 0 };
190
+
191
+ // Build a single LLM prompt with all candidate pairs
192
+ const pairsText = candidates.map((c, i) =>
193
+ `${i + 1}. Fact A (${c.sourceType}): "${c.factContent.slice(0, 150)}"\n Fact B (${c.candidateSourceType}): "${c.candidateFactContent.slice(0, 150)}"`
194
+ ).join('\n\n');
195
+
196
+ const prompt = `You are analyzing pairs of user data items to determine if they are related.
197
+ For each pair, respond with ONE of:
198
+ - "same_as" — they refer to the same real-world thing (e.g., a vault save and a calendar event for the same event)
199
+ - "related_to" — they are topically connected but not the same thing
200
+ - "unrelated" — no meaningful connection
201
+
202
+ Respond as JSON array: [{"pair": 1, "relation": "same_as"}, ...]
203
+
204
+ Pairs:
205
+ ${pairsText}`;
206
+
207
+ let edgesCreated = 0;
208
+
209
+ try {
210
+ const response = await llm.complete(
211
+ [{ role: 'user', content: prompt }],
212
+ { temperature: 0, responseFormat: 'json' },
213
+ );
214
+
215
+ const parsed = JSON.parse(response.content);
216
+ const classifications = Array.isArray(parsed) ? parsed : parsed.pairs ?? parsed.results ?? [];
217
+
218
+ for (const classification of classifications) {
219
+ const idx = (classification.pair ?? classification.index ?? 0) - 1;
220
+ const relation = classification.relation ?? classification.type;
221
+ const candidate = candidates[idx];
222
+
223
+ if (!candidate || relation === 'unrelated') continue;
224
+
225
+ // Get entities for both facts to create the edge
226
+ const entitiesA = await storage.getEntitiesForFact(candidate.factId);
227
+ const entitiesB = await storage.getEntitiesForFact(candidate.candidateFactId);
228
+
229
+ if (entitiesA.length > 0 && entitiesB.length > 0) {
230
+ const edgeType = relation === 'same_as' ? 'same_as' as const : 'associative' as const;
231
+ try {
232
+ await storage.createEdge({
233
+ id: crypto.randomUUID(),
234
+ tenantId,
235
+ sourceId: entitiesA[0]!.id,
236
+ targetId: entitiesB[0]!.id,
237
+ relation,
238
+ edgeType,
239
+ weight: candidate.similarity,
240
+ confidence: 0.7,
241
+ metadata: {
242
+ autoLinked: true,
243
+ sourceFactId: candidate.factId,
244
+ targetFactId: candidate.candidateFactId,
245
+ method: 'batch_llm_classification',
246
+ },
247
+ });
248
+ edgesCreated++;
249
+ } catch {
250
+ // Edge may already exist — skip
251
+ }
252
+ }
253
+ }
254
+ } catch (err) {
255
+ console.error('[steno-structured-xlink] Batch LLM classification failed:', err instanceof Error ? err.message : err);
256
+ }
257
+
258
+ return { processed: candidates.length, edgesCreated };
259
+ }