@steno-ai/engine 0.1.14 → 0.1.16

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 (232) hide show
  1. package/dist/adapters/storage.d.ts +29 -2
  2. package/dist/adapters/storage.d.ts.map +1 -1
  3. package/dist/extraction/pipeline.d.ts.map +1 -1
  4. package/dist/extraction/pipeline.js +165 -0
  5. package/dist/extraction/pipeline.js.map +1 -1
  6. package/dist/extraction/types.d.ts +2 -0
  7. package/dist/extraction/types.d.ts.map +1 -1
  8. package/dist/identity/index.d.ts +2 -0
  9. package/dist/identity/index.d.ts.map +1 -0
  10. package/dist/identity/index.js +2 -0
  11. package/dist/identity/index.js.map +1 -0
  12. package/dist/identity/resolver.d.ts +31 -0
  13. package/dist/identity/resolver.d.ts.map +1 -0
  14. package/dist/identity/resolver.js +122 -0
  15. package/dist/identity/resolver.js.map +1 -0
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +1 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/models/entity.d.ts +32 -0
  21. package/dist/models/entity.d.ts.map +1 -1
  22. package/dist/models/entity.js +11 -0
  23. package/dist/models/entity.js.map +1 -1
  24. package/dist/retrieval/graph-traversal.d.ts +4 -1
  25. package/dist/retrieval/graph-traversal.d.ts.map +1 -1
  26. package/dist/retrieval/graph-traversal.js +6 -3
  27. package/dist/retrieval/graph-traversal.js.map +1 -1
  28. package/dist/retrieval/search.d.ts.map +1 -1
  29. package/dist/retrieval/search.js +56 -3
  30. package/dist/retrieval/search.js.map +1 -1
  31. package/dist/retrieval/types.d.ts +1 -0
  32. package/dist/retrieval/types.d.ts.map +1 -1
  33. package/dist/retrieval/types.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/adapters/storage.ts +35 -2
  36. package/src/extraction/pipeline.ts +213 -0
  37. package/src/extraction/types.ts +2 -0
  38. package/src/identity/index.ts +1 -0
  39. package/src/identity/resolver.ts +149 -0
  40. package/src/index.ts +1 -0
  41. package/src/models/entity.ts +13 -0
  42. package/src/retrieval/graph-traversal.ts +7 -4
  43. package/src/retrieval/search.ts +58 -3
  44. package/src/retrieval/types.ts +1 -0
  45. package/src/adapters/cache.d.ts +0 -9
  46. package/src/adapters/cache.d.ts.map +0 -1
  47. package/src/adapters/cache.js +0 -2
  48. package/src/adapters/cache.js.map +0 -1
  49. package/src/adapters/embedding.d.ts +0 -7
  50. package/src/adapters/embedding.d.ts.map +0 -1
  51. package/src/adapters/embedding.js +0 -2
  52. package/src/adapters/embedding.js.map +0 -1
  53. package/src/adapters/llm.d.ts +0 -19
  54. package/src/adapters/llm.d.ts.map +0 -1
  55. package/src/adapters/llm.js +0 -2
  56. package/src/adapters/llm.js.map +0 -1
  57. package/src/adapters/perplexity-embedding.d.ts +0 -24
  58. package/src/adapters/perplexity-embedding.d.ts.map +0 -1
  59. package/src/adapters/perplexity-embedding.js +0 -78
  60. package/src/adapters/perplexity-embedding.js.map +0 -1
  61. package/src/adapters/storage.d.ts +0 -173
  62. package/src/adapters/storage.d.ts.map +0 -1
  63. package/src/adapters/storage.js +0 -2
  64. package/src/adapters/storage.js.map +0 -1
  65. package/src/config.d.ts +0 -296
  66. package/src/config.d.ts.map +0 -1
  67. package/src/config.js +0 -92
  68. package/src/config.js.map +0 -1
  69. package/src/extraction/contradiction.d.ts +0 -15
  70. package/src/extraction/contradiction.d.ts.map +0 -1
  71. package/src/extraction/contradiction.js +0 -23
  72. package/src/extraction/contradiction.js.map +0 -1
  73. package/src/extraction/cross-linker.d.ts +0 -23
  74. package/src/extraction/cross-linker.d.ts.map +0 -1
  75. package/src/extraction/cross-linker.js +0 -146
  76. package/src/extraction/cross-linker.js.map +0 -1
  77. package/src/extraction/dedup.d.ts +0 -12
  78. package/src/extraction/dedup.d.ts.map +0 -1
  79. package/src/extraction/dedup.js +0 -93
  80. package/src/extraction/dedup.js.map +0 -1
  81. package/src/extraction/entity-extractor.d.ts +0 -30
  82. package/src/extraction/entity-extractor.d.ts.map +0 -1
  83. package/src/extraction/entity-extractor.js +0 -145
  84. package/src/extraction/entity-extractor.js.map +0 -1
  85. package/src/extraction/hasher.d.ts +0 -5
  86. package/src/extraction/hasher.d.ts.map +0 -1
  87. package/src/extraction/hasher.js +0 -8
  88. package/src/extraction/hasher.js.map +0 -1
  89. package/src/extraction/heuristic.d.ts +0 -3
  90. package/src/extraction/heuristic.d.ts.map +0 -1
  91. package/src/extraction/heuristic.js +0 -282
  92. package/src/extraction/heuristic.js.map +0 -1
  93. package/src/extraction/llm-extractor.d.ts +0 -23
  94. package/src/extraction/llm-extractor.d.ts.map +0 -1
  95. package/src/extraction/llm-extractor.js +0 -240
  96. package/src/extraction/llm-extractor.js.map +0 -1
  97. package/src/extraction/pipeline.d.ts +0 -30
  98. package/src/extraction/pipeline.d.ts.map +0 -1
  99. package/src/extraction/pipeline.js +0 -413
  100. package/src/extraction/pipeline.js.map +0 -1
  101. package/src/extraction/prompts.d.ts +0 -28
  102. package/src/extraction/prompts.d.ts.map +0 -1
  103. package/src/extraction/prompts.js +0 -205
  104. package/src/extraction/prompts.js.map +0 -1
  105. package/src/extraction/sliding-window.d.ts +0 -41
  106. package/src/extraction/sliding-window.d.ts.map +0 -1
  107. package/src/extraction/sliding-window.js +0 -84
  108. package/src/extraction/sliding-window.js.map +0 -1
  109. package/src/extraction/types.d.ts +0 -80
  110. package/src/extraction/types.d.ts.map +0 -1
  111. package/src/extraction/types.js +0 -2
  112. package/src/extraction/types.js.map +0 -1
  113. package/src/feedback/tracker.d.ts +0 -25
  114. package/src/feedback/tracker.d.ts.map +0 -1
  115. package/src/feedback/tracker.js +0 -90
  116. package/src/feedback/tracker.js.map +0 -1
  117. package/src/models/api-key.d.ts +0 -54
  118. package/src/models/api-key.d.ts.map +0 -1
  119. package/src/models/api-key.js +0 -21
  120. package/src/models/api-key.js.map +0 -1
  121. package/src/models/edge.d.ts +0 -78
  122. package/src/models/edge.d.ts.map +0 -1
  123. package/src/models/edge.js +0 -29
  124. package/src/models/edge.js.map +0 -1
  125. package/src/models/entity.d.ts +0 -60
  126. package/src/models/entity.d.ts.map +0 -1
  127. package/src/models/entity.js +0 -22
  128. package/src/models/entity.js.map +0 -1
  129. package/src/models/extraction.d.ts +0 -111
  130. package/src/models/extraction.d.ts.map +0 -1
  131. package/src/models/extraction.js +0 -40
  132. package/src/models/extraction.js.map +0 -1
  133. package/src/models/fact-entity.d.ts +0 -33
  134. package/src/models/fact-entity.d.ts.map +0 -1
  135. package/src/models/fact-entity.js +0 -14
  136. package/src/models/fact-entity.js.map +0 -1
  137. package/src/models/fact.d.ts +0 -191
  138. package/src/models/fact.d.ts.map +0 -1
  139. package/src/models/fact.js +0 -72
  140. package/src/models/fact.js.map +0 -1
  141. package/src/models/index.d.ts +0 -13
  142. package/src/models/index.d.ts.map +0 -1
  143. package/src/models/index.js +0 -13
  144. package/src/models/index.js.map +0 -1
  145. package/src/models/memory-access.d.ts +0 -89
  146. package/src/models/memory-access.d.ts.map +0 -1
  147. package/src/models/memory-access.js +0 -33
  148. package/src/models/memory-access.js.map +0 -1
  149. package/src/models/session.d.ts +0 -60
  150. package/src/models/session.d.ts.map +0 -1
  151. package/src/models/session.js +0 -23
  152. package/src/models/session.js.map +0 -1
  153. package/src/models/tenant.d.ts +0 -448
  154. package/src/models/tenant.d.ts.map +0 -1
  155. package/src/models/tenant.js +0 -23
  156. package/src/models/tenant.js.map +0 -1
  157. package/src/models/trigger.d.ts +0 -87
  158. package/src/models/trigger.d.ts.map +0 -1
  159. package/src/models/trigger.js +0 -41
  160. package/src/models/trigger.js.map +0 -1
  161. package/src/models/usage-record.d.ts +0 -37
  162. package/src/models/usage-record.d.ts.map +0 -1
  163. package/src/models/usage-record.js +0 -14
  164. package/src/models/usage-record.js.map +0 -1
  165. package/src/models/webhook.d.ts +0 -50
  166. package/src/models/webhook.d.ts.map +0 -1
  167. package/src/models/webhook.js +0 -25
  168. package/src/models/webhook.js.map +0 -1
  169. package/src/retrieval/compound-search.d.ts +0 -13
  170. package/src/retrieval/compound-search.d.ts.map +0 -1
  171. package/src/retrieval/compound-search.js +0 -87
  172. package/src/retrieval/compound-search.js.map +0 -1
  173. package/src/retrieval/contradiction-surfacer.d.ts +0 -18
  174. package/src/retrieval/contradiction-surfacer.d.ts.map +0 -1
  175. package/src/retrieval/contradiction-surfacer.js +0 -64
  176. package/src/retrieval/contradiction-surfacer.js.map +0 -1
  177. package/src/retrieval/embedding-cache.d.ts +0 -17
  178. package/src/retrieval/embedding-cache.d.ts.map +0 -1
  179. package/src/retrieval/embedding-cache.js +0 -56
  180. package/src/retrieval/embedding-cache.js.map +0 -1
  181. package/src/retrieval/fusion.d.ts +0 -27
  182. package/src/retrieval/fusion.d.ts.map +0 -1
  183. package/src/retrieval/fusion.js +0 -87
  184. package/src/retrieval/fusion.js.map +0 -1
  185. package/src/retrieval/graph-traversal.d.ts +0 -29
  186. package/src/retrieval/graph-traversal.d.ts.map +0 -1
  187. package/src/retrieval/graph-traversal.js +0 -208
  188. package/src/retrieval/graph-traversal.js.map +0 -1
  189. package/src/retrieval/query-expansion.d.ts +0 -20
  190. package/src/retrieval/query-expansion.d.ts.map +0 -1
  191. package/src/retrieval/query-expansion.js +0 -76
  192. package/src/retrieval/query-expansion.js.map +0 -1
  193. package/src/retrieval/reranker.d.ts +0 -15
  194. package/src/retrieval/reranker.d.ts.map +0 -1
  195. package/src/retrieval/reranker.js +0 -47
  196. package/src/retrieval/reranker.js.map +0 -1
  197. package/src/retrieval/salience-scorer.d.ts +0 -15
  198. package/src/retrieval/salience-scorer.d.ts.map +0 -1
  199. package/src/retrieval/salience-scorer.js +0 -41
  200. package/src/retrieval/salience-scorer.js.map +0 -1
  201. package/src/retrieval/search.d.ts +0 -21
  202. package/src/retrieval/search.d.ts.map +0 -1
  203. package/src/retrieval/search.js +0 -228
  204. package/src/retrieval/search.js.map +0 -1
  205. package/src/retrieval/temporal-scorer.d.ts +0 -18
  206. package/src/retrieval/temporal-scorer.d.ts.map +0 -1
  207. package/src/retrieval/temporal-scorer.js +0 -106
  208. package/src/retrieval/temporal-scorer.js.map +0 -1
  209. package/src/retrieval/trigger-matcher.d.ts +0 -18
  210. package/src/retrieval/trigger-matcher.d.ts.map +0 -1
  211. package/src/retrieval/trigger-matcher.js +0 -134
  212. package/src/retrieval/trigger-matcher.js.map +0 -1
  213. package/src/retrieval/types.d.ts +0 -70
  214. package/src/retrieval/types.d.ts.map +0 -1
  215. package/src/retrieval/types.js +0 -9
  216. package/src/retrieval/types.js.map +0 -1
  217. package/src/retrieval/vector-search.d.ts +0 -5
  218. package/src/retrieval/vector-search.d.ts.map +0 -1
  219. package/src/retrieval/vector-search.js +0 -24
  220. package/src/retrieval/vector-search.js.map +0 -1
  221. package/src/salience/decay.d.ts +0 -9
  222. package/src/salience/decay.d.ts.map +0 -1
  223. package/src/salience/decay.js +0 -15
  224. package/src/salience/decay.js.map +0 -1
  225. package/src/scratchpad/scratchpad.d.ts +0 -23
  226. package/src/scratchpad/scratchpad.d.ts.map +0 -1
  227. package/src/scratchpad/scratchpad.js +0 -137
  228. package/src/scratchpad/scratchpad.js.map +0 -1
  229. package/src/sessions/manager.d.ts +0 -11
  230. package/src/sessions/manager.d.ts.map +0 -1
  231. package/src/sessions/manager.js +0 -63
  232. package/src/sessions/manager.js.map +0 -1
@@ -0,0 +1,149 @@
1
+ export interface IdentityCandidate {
2
+ id: string;
3
+ canonicalName: string;
4
+ entityType: string;
5
+ properties: Record<string, unknown>;
6
+ }
7
+
8
+ export interface AliasCandidate {
9
+ primaryEntityId: string;
10
+ aliasEntityId: string;
11
+ confidence: number;
12
+ matchReason: 'email_match' | 'fuzzy_name' | 'temporal_cooccurrence' | 'manual';
13
+ }
14
+
15
+ /**
16
+ * Jaro-Winkler similarity algorithm.
17
+ * Returns a value between 0 (no similarity) and 1 (identical).
18
+ */
19
+ export function jaroWinkler(s1: string, s2: string): number {
20
+ if (s1 === s2) return 1.0;
21
+ if (s1.length === 0 || s2.length === 0) return 0.0;
22
+
23
+ const matchDistance = Math.floor(Math.max(s1.length, s2.length) / 2) - 1;
24
+
25
+ const s1Matches = new Array(s1.length).fill(false);
26
+ const s2Matches = new Array(s2.length).fill(false);
27
+
28
+ let matches = 0;
29
+ let transpositions = 0;
30
+
31
+ // Find matching characters
32
+ for (let i = 0; i < s1.length; i++) {
33
+ const start = Math.max(0, i - matchDistance);
34
+ const end = Math.min(i + matchDistance + 1, s2.length);
35
+
36
+ for (let j = start; j < end; j++) {
37
+ if (s2Matches[j] || s1[i] !== s2[j]) continue;
38
+ s1Matches[i] = true;
39
+ s2Matches[j] = true;
40
+ matches++;
41
+ break;
42
+ }
43
+ }
44
+
45
+ if (matches === 0) return 0.0;
46
+
47
+ // Count transpositions
48
+ let k = 0;
49
+ for (let i = 0; i < s1.length; i++) {
50
+ if (!s1Matches[i]) continue;
51
+ while (!s2Matches[k]) k++;
52
+ if (s1[i] !== s2[k]) transpositions++;
53
+ k++;
54
+ }
55
+
56
+ const jaro =
57
+ (matches / s1.length + matches / s2.length + (matches - transpositions / 2) / matches) / 3;
58
+
59
+ // Winkler prefix bonus (up to 4 common prefix chars)
60
+ let prefix = 0;
61
+ for (let i = 0; i < Math.min(4, Math.min(s1.length, s2.length)); i++) {
62
+ if (s1[i] === s2[i]) prefix++;
63
+ else break;
64
+ }
65
+
66
+ return jaro + prefix * 0.1 * (1 - jaro);
67
+ }
68
+
69
+ /**
70
+ * Normalize a name for fuzzy comparison:
71
+ * lowercase and strip separators (. _ - @).
72
+ */
73
+ export function normalizeName(name: string): string {
74
+ return name.toLowerCase().replace(/[._\-@]/g, '');
75
+ }
76
+
77
+ /**
78
+ * Resolve identities across a list of entity candidates using a three-tier strategy:
79
+ * 1. Exact email match (confidence 1.0)
80
+ * 2. Fuzzy canonical name match via Jaro-Winkler (confidence 0.6–0.8)
81
+ *
82
+ * Returns alias pairs without duplicates.
83
+ */
84
+ export function resolveIdentities(entities: IdentityCandidate[]): AliasCandidate[] {
85
+ const aliases: AliasCandidate[] = [];
86
+ const seen = new Set<string>();
87
+
88
+ const addAlias = (
89
+ primaryEntityId: string,
90
+ aliasEntityId: string,
91
+ confidence: number,
92
+ matchReason: AliasCandidate['matchReason'],
93
+ ): void => {
94
+ const key = [primaryEntityId, aliasEntityId].sort().join(':');
95
+ if (seen.has(key)) return;
96
+ seen.add(key);
97
+ aliases.push({ primaryEntityId, aliasEntityId, confidence, matchReason });
98
+ };
99
+
100
+ // Tier 1: Email match (confidence 1.0)
101
+ const emailGroups = new Map<string, IdentityCandidate[]>();
102
+ for (const entity of entities) {
103
+ const email = entity.properties['email'];
104
+ if (typeof email !== 'string' || email.trim() === '') continue;
105
+ const normalizedEmail = email.toLowerCase();
106
+ const group = emailGroups.get(normalizedEmail) ?? [];
107
+ group.push(entity);
108
+ emailGroups.set(normalizedEmail, group);
109
+ }
110
+
111
+ for (const group of emailGroups.values()) {
112
+ if (group.length < 2) continue;
113
+ const primary = group[0]!;
114
+ for (let i = 1; i < group.length; i++) {
115
+ addAlias(primary.id, group[i]!.id, 1.0, 'email_match');
116
+ }
117
+ }
118
+
119
+ // Tier 2: Fuzzy name match (confidence 0.6–0.8)
120
+ // Threshold: Jaro-Winkler >= 0.85, same entity type required
121
+ const JARO_WINKLER_THRESHOLD = 0.85;
122
+
123
+ for (let i = 0; i < entities.length; i++) {
124
+ for (let j = i + 1; j < entities.length; j++) {
125
+ const a = entities[i]!;
126
+ const b = entities[j]!;
127
+
128
+ // Must be same entity type
129
+ if (a.entityType !== b.entityType) continue;
130
+
131
+ // Skip if already aliased
132
+ const key = [a.id, b.id].sort().join(':');
133
+ if (seen.has(key)) continue;
134
+
135
+ const normA = normalizeName(a.canonicalName);
136
+ const normB = normalizeName(b.canonicalName);
137
+ const similarity = jaroWinkler(normA, normB);
138
+
139
+ if (similarity >= JARO_WINKLER_THRESHOLD) {
140
+ // Map similarity [0.85, 1.0] → confidence [0.6, 0.8]
141
+ const confidence = 0.6 + ((similarity - 0.85) / 0.15) * 0.2;
142
+ const clampedConfidence = Math.min(0.8, Math.max(0.6, confidence));
143
+ addAlias(a.id, b.id, clampedConfidence, 'fuzzy_name');
144
+ }
145
+ }
146
+ }
147
+
148
+ return aliases;
149
+ }
package/src/index.ts CHANGED
@@ -10,3 +10,4 @@ export * from './sessions/index.js';
10
10
  export * from './feedback/index.js';
11
11
  export * from './profiles/index.js';
12
12
  export * from './scratchpad/index.js';
13
+ export * from './identity/index.js';
@@ -16,6 +16,19 @@ export const EntitySchema = z.object({
16
16
 
17
17
  export type Entity = z.infer<typeof EntitySchema>;
18
18
 
19
+ export const AliasSchema = z.object({
20
+ id: z.string().uuid(),
21
+ tenantId: z.string().uuid(),
22
+ primaryEntityId: z.string().uuid(),
23
+ aliasEntityId: z.string().uuid(),
24
+ confidence: z.number().min(0).max(1),
25
+ matchReason: z.enum(['email_match', 'fuzzy_name', 'temporal_cooccurrence', 'manual']),
26
+ confirmedBy: z.string().nullable(),
27
+ confirmedAt: z.coerce.date().nullable(),
28
+ createdAt: z.coerce.date(),
29
+ });
30
+ export type Alias = z.infer<typeof AliasSchema>;
31
+
19
32
  export const CreateEntitySchema = z.object({
20
33
  tenantId: z.string().uuid(),
21
34
  name: z.string().min(1).max(500),
@@ -41,14 +41,17 @@ export function tokenizeQuery(query: string): string[] {
41
41
  * - 1-hop = 0.5
42
42
  * - 2-hop = 0.25
43
43
  * - 3-hop = 0.125
44
+ *
45
+ * Note: Entity lookups are tenant-scoped.
46
+ * Fact retrieval is scope-filtered to prevent cross-user data leakage.
44
47
  */
45
48
  export async function graphSearch(
46
49
  storage: StorageAdapter,
47
50
  embedding: EmbeddingAdapter,
48
51
  query: string,
49
52
  tenantId: string,
50
- _scope: string,
51
- _scopeId: string,
53
+ scope: string,
54
+ scopeId: string,
52
55
  limit: number,
53
56
  config?: Partial<GraphSearchConfig>,
54
57
  ): Promise<Candidate[]> {
@@ -183,7 +186,7 @@ export async function graphSearch(
183
186
  // Single query: get all facts linked to any of these entities
184
187
  try {
185
188
  const batchResult = await storage.getFactsForEntities(
186
- tenantId, entityIds, PER_ENTITY_LIMIT
189
+ tenantId, entityIds, PER_ENTITY_LIMIT, scope, scopeId
187
190
  );
188
191
 
189
192
  for (const { entityId, fact } of batchResult) {
@@ -214,7 +217,7 @@ export async function graphSearch(
214
217
  const hopDepth = entityHopMap.get(entity.id) ?? maxDepth;
215
218
  const graphScore = 1 / Math.pow(2, hopDepth);
216
219
  try {
217
- const factsResult = await storage.getFactsForEntity(tenantId, entity.id, { limit: 3 });
220
+ const factsResult = await storage.getFactsForEntity(tenantId, entity.id, { limit: 3 }, scope, scopeId);
218
221
  for (const fact of factsResult.data) {
219
222
  if (!candidateMap.has(fact.id)) {
220
223
  candidateMap.set(fact.id, {
@@ -55,19 +55,74 @@ export async function search(
55
55
  // 1. Run retrieval signals
56
56
  const t0 = Date.now();
57
57
 
58
+ // Determine whether to use multi-scope search
59
+ const useMultiScope = options.scopeIds && options.scopeIds.length > 0;
60
+
58
61
  const tCompound = Date.now();
59
- const compoundPromise = compoundSearchSignal(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId, limit * fetchMultiplier).catch(() => ({ vectorCandidates: [] as Candidate[], keywordCandidates: [] as Candidate[] }));
62
+ let compoundPromise: Promise<{ vectorCandidates: Candidate[]; keywordCandidates: Candidate[] }>;
63
+
64
+ if (useMultiScope) {
65
+ // Multi-scope path: run vectorSearchMultiScope + keywordSearchMultiScope in parallel
66
+ compoundPromise = (async () => {
67
+ const embedding = await effectiveEmbedding.embed(options.query);
68
+ const [vectorResults, keywordResults] = await Promise.all([
69
+ config.storage.vectorSearchMultiScope({
70
+ embedding,
71
+ tenantId: options.tenantId,
72
+ scope: options.scope,
73
+ scopeIds: options.scopeIds!,
74
+ limit: limit * fetchMultiplier,
75
+ asOf: options.temporalFilter?.asOf,
76
+ }).catch(() => [] as import('../adapters/storage.js').VectorSearchResult[]),
77
+ config.storage.keywordSearchMultiScope({
78
+ query: options.query,
79
+ tenantId: options.tenantId,
80
+ scope: options.scope,
81
+ scopeIds: options.scopeIds!,
82
+ limit: limit * fetchMultiplier,
83
+ asOf: options.temporalFilter?.asOf,
84
+ }).catch(() => [] as import('../adapters/storage.js').KeywordSearchResult[]),
85
+ ]);
86
+ const vectorCandidates: Candidate[] = vectorResults.map(r => ({
87
+ fact: r.fact,
88
+ vectorScore: r.similarity,
89
+ keywordScore: 0,
90
+ graphScore: 0,
91
+ recencyScore: 0,
92
+ salienceScore: 0,
93
+ temporalScore: 0,
94
+ source: 'vector' as const,
95
+ }));
96
+ const keywordCandidates: Candidate[] = keywordResults.map(r => ({
97
+ fact: r.fact,
98
+ vectorScore: 0,
99
+ keywordScore: r.rankScore,
100
+ graphScore: 0,
101
+ recencyScore: 0,
102
+ salienceScore: 0,
103
+ temporalScore: 0,
104
+ source: 'keyword' as const,
105
+ }));
106
+ return { vectorCandidates, keywordCandidates };
107
+ })().catch(() => ({ vectorCandidates: [] as Candidate[], keywordCandidates: [] as Candidate[] }));
108
+ } else {
109
+ // Single-scope path (original behavior)
110
+ compoundPromise = compoundSearchSignal(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId, limit * fetchMultiplier).catch(() => ({ vectorCandidates: [] as Candidate[], keywordCandidates: [] as Candidate[] }));
111
+ }
60
112
 
61
113
  let graphPromise: Promise<Candidate[]> | null = null;
62
114
  let triggerPromise: Promise<{ candidates: Candidate[]; triggersMatched: string[] }> | null = null;
63
115
 
116
+ // Graph and trigger searches use single scope (scopeId or first of scopeIds)
117
+ const effectiveScopeId = useMultiScope ? options.scopeIds![0]! : options.scopeId;
118
+
64
119
  if (!isFast) {
65
120
  const tGraph = Date.now();
66
- 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 })
121
+ graphPromise = graphSearch(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, effectiveScopeId, limit * fetchMultiplier, { maxDepth: config.graphMaxDepth, maxEntities: config.graphMaxEntities, asOf: options.temporalFilter?.asOf })
67
122
  .then(r => { console.error(`[steno-search] graph: ${Date.now() - tGraph}ms (${Array.isArray(r) ? r.length : 0} candidates)`); return r; })
68
123
  .catch(() => [] as Candidate[]);
69
124
  const tTrigger = Date.now();
70
- triggerPromise = matchTriggers(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, options.scopeId)
125
+ triggerPromise = matchTriggers(config.storage, effectiveEmbedding, options.query, options.tenantId, options.scope, effectiveScopeId)
71
126
  .then(r => { console.error(`[steno-search] trigger: ${Date.now() - tTrigger}ms`); return r; })
72
127
  .catch(() => ({ candidates: [] as Candidate[], triggersMatched: [] as string[] }));
73
128
  }
@@ -15,6 +15,7 @@ export interface SearchOptions {
15
15
  weights?: FusionWeights; // override default fusion weights
16
16
  tokenBudget?: number; // max estimated tokens for results (rough: chars/4). Trims lowest-scored results to fit.
17
17
  fast?: boolean; // skip graph traversal + reranking for <300ms latency
18
+ scopeIds?: string[]; // when present, query across multiple scopeIds instead of a single one
18
19
  }
19
20
 
20
21
  /** Configurable fusion weights (should sum to 1.0 — normalized if not) */
@@ -1,9 +0,0 @@
1
- export interface CacheAdapter {
2
- get<T>(key: string): Promise<T | null>;
3
- set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
4
- del(key: string): Promise<void>;
5
- incr(key: string): Promise<number>;
6
- expire(key: string, ttlSeconds: number): Promise<void>;
7
- ping(): Promise<boolean>;
8
- }
9
- //# sourceMappingURL=cache.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=cache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":""}
@@ -1,7 +0,0 @@
1
- export interface EmbeddingAdapter {
2
- embed(text: string): Promise<number[]>;
3
- embedBatch(texts: string[]): Promise<number[][]>;
4
- readonly model: string;
5
- readonly dimensions: number;
6
- }
7
- //# sourceMappingURL=embedding.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["embedding.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=embedding.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embedding.js","sourceRoot":"","sources":["embedding.ts"],"names":[],"mappings":""}
@@ -1,19 +0,0 @@
1
- export interface LLMMessage {
2
- role: 'system' | 'user' | 'assistant';
3
- content: string;
4
- }
5
- export interface LLMResponse {
6
- content: string;
7
- tokensInput: number;
8
- tokensOutput: number;
9
- model: string;
10
- }
11
- export interface LLMAdapter {
12
- complete(messages: LLMMessage[], options?: {
13
- temperature?: number;
14
- maxTokens?: number;
15
- responseFormat?: 'json';
16
- }): Promise<LLMResponse>;
17
- readonly model: string;
18
- }
19
- //# sourceMappingURL=llm.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["llm.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxI,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=llm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm.js","sourceRoot":"","sources":["llm.ts"],"names":[],"mappings":""}
@@ -1,24 +0,0 @@
1
- import type { EmbeddingAdapter } from './embedding.js';
2
- export interface PerplexityEmbeddingConfig {
3
- apiKey: string;
4
- model?: string;
5
- dimensions?: number;
6
- }
7
- /**
8
- * Perplexity embedding adapter using pplx-embed models.
9
- * SOTA quality at $0.03/1M tokens for pplx-embed-v1-4b.
10
- *
11
- * IMPORTANT: Perplexity returns base64-encoded int8 embeddings by default.
12
- * These are decoded to float32 and L2-normalized for cosine similarity compatibility
13
- * with pgvector and other vector DBs.
14
- */
15
- export declare class PerplexityEmbeddingAdapter implements EmbeddingAdapter {
16
- readonly model: string;
17
- readonly dimensions: number;
18
- private readonly apiKey;
19
- private readonly baseUrl;
20
- constructor(config: PerplexityEmbeddingConfig);
21
- embed(text: string): Promise<number[]>;
22
- embedBatch(texts: string[]): Promise<number[][]>;
23
- }
24
- //# sourceMappingURL=perplexity-embedding.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"perplexity-embedding.d.ts","sourceRoot":"","sources":["perplexity-embedding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,qBAAa,0BAA2B,YAAW,gBAAgB;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;gBAEzD,MAAM,EAAE,yBAAyB;IAMvC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKtC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CA+BvD"}
@@ -1,78 +0,0 @@
1
- /**
2
- * Perplexity embedding adapter using pplx-embed models.
3
- * SOTA quality at $0.03/1M tokens for pplx-embed-v1-4b.
4
- *
5
- * IMPORTANT: Perplexity returns base64-encoded int8 embeddings by default.
6
- * These are decoded to float32 and L2-normalized for cosine similarity compatibility
7
- * with pgvector and other vector DBs.
8
- */
9
- export class PerplexityEmbeddingAdapter {
10
- model;
11
- dimensions;
12
- apiKey;
13
- baseUrl = 'https://api.perplexity.ai/v1/embeddings';
14
- constructor(config) {
15
- this.apiKey = config.apiKey;
16
- this.model = config.model ?? 'pplx-embed-v1-4b';
17
- this.dimensions = config.dimensions ?? 2000;
18
- }
19
- async embed(text) {
20
- const results = await this.embedBatch([text]);
21
- return results[0];
22
- }
23
- async embedBatch(texts) {
24
- if (texts.length === 0)
25
- return [];
26
- const response = await fetch(this.baseUrl, {
27
- method: 'POST',
28
- headers: {
29
- 'Authorization': `Bearer ${this.apiKey}`,
30
- 'Content-Type': 'application/json',
31
- },
32
- body: JSON.stringify({
33
- input: texts,
34
- model: this.model,
35
- ...(this.dimensions !== 2560 ? { dimensions: this.dimensions } : {}),
36
- }),
37
- });
38
- if (!response.ok) {
39
- const error = await response.text();
40
- throw new Error(`Perplexity embedding failed (${response.status}): ${error}`);
41
- }
42
- const data = await response.json();
43
- // Sort by index to ensure correct order
44
- const sorted = data.data.sort((a, b) => a.index - b.index);
45
- // Decode base64 int8 → float32 → L2-normalize
46
- return sorted.map(d => decodeAndNormalize(d.embedding));
47
- }
48
- }
49
- /**
50
- * Decode a base64-encoded int8 embedding to a normalized float32 array.
51
- * Perplexity embeddings are unnormalized int8 — we must L2-normalize
52
- * for cosine similarity to work correctly with pgvector.
53
- */
54
- function decodeAndNormalize(b64String) {
55
- // Decode base64 using atob (works in both Node.js and browsers)
56
- const binaryStr = atob(b64String);
57
- const bytes = new Uint8Array(binaryStr.length);
58
- for (let i = 0; i < binaryStr.length; i++) {
59
- bytes[i] = binaryStr.charCodeAt(i);
60
- }
61
- const int8 = new Int8Array(bytes.buffer);
62
- const float32 = new Array(int8.length);
63
- // Convert int8 to float32 and compute norm
64
- let norm = 0;
65
- for (let i = 0; i < int8.length; i++) {
66
- float32[i] = int8[i];
67
- norm += float32[i] * float32[i];
68
- }
69
- // L2-normalize so cosine similarity == inner product in pgvector
70
- norm = Math.sqrt(norm);
71
- if (norm > 0) {
72
- for (let i = 0; i < float32.length; i++) {
73
- float32[i] = float32[i] / norm;
74
- }
75
- }
76
- return float32;
77
- }
78
- //# sourceMappingURL=perplexity-embedding.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"perplexity-embedding.js","sourceRoot":"","sources":["perplexity-embedding.ts"],"names":[],"mappings":"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"}
@@ -1,173 +0,0 @@
1
- import type { Fact, CreateFact, Entity, CreateEntity, Edge, CreateEdge, Trigger, CreateTrigger, MemoryAccess, CreateMemoryAccess, Extraction, CreateExtraction, Session, CreateSession, Tenant, CreateTenant, ApiKey, CreateApiKey, UsageRecord, Webhook, CreateWebhook } from '../models/index.js';
2
- export interface PaginationOptions {
3
- limit: number;
4
- cursor?: string;
5
- }
6
- export interface PaginatedResult<T> {
7
- data: T[];
8
- cursor: string | null;
9
- hasMore: boolean;
10
- }
11
- export interface VectorSearchOptions {
12
- embedding: number[];
13
- tenantId: string;
14
- scope: string;
15
- scopeId: string;
16
- limit: number;
17
- minSimilarity?: number;
18
- validOnly?: boolean;
19
- asOf?: Date;
20
- }
21
- export interface VectorSearchResult {
22
- fact: Fact;
23
- similarity: number;
24
- }
25
- export interface KeywordSearchOptions {
26
- query: string;
27
- tenantId: string;
28
- scope: string;
29
- scopeId: string;
30
- limit: number;
31
- validOnly?: boolean;
32
- asOf?: Date;
33
- }
34
- export interface KeywordSearchResult {
35
- fact: Fact;
36
- rankScore: number;
37
- }
38
- export interface CompoundSearchOptions {
39
- embedding: number[];
40
- query: string;
41
- tenantId: string;
42
- scope: string;
43
- scopeId: string;
44
- limit: number;
45
- minSimilarity?: number;
46
- }
47
- export interface CompoundSearchResult {
48
- source: 'vector' | 'keyword';
49
- fact: Fact;
50
- relevanceScore: number;
51
- }
52
- export interface GraphTraversalOptions {
53
- tenantId: string;
54
- entityIds: string[];
55
- maxDepth: number;
56
- maxEntities: number;
57
- validOnly?: boolean;
58
- asOf?: Date;
59
- }
60
- export interface GraphTraversalResult {
61
- entities: Entity[];
62
- edges: Edge[];
63
- }
64
- export interface StorageAdapter {
65
- createFact(fact: CreateFact & {
66
- id: string;
67
- lineageId: string;
68
- embeddingModel: string;
69
- embeddingDim: number;
70
- embedding?: number[];
71
- }): Promise<Fact>;
72
- getFact(tenantId: string, id: string): Promise<Fact | null>;
73
- getFactsByIds(tenantId: string, ids: string[]): Promise<Fact[]>;
74
- getFactsByLineage(tenantId: string, lineageId: string): Promise<Fact[]>;
75
- getFactsByScope(tenantId: string, scope: string, scopeId: string, options: PaginationOptions): Promise<PaginatedResult<Fact>>;
76
- invalidateFact(tenantId: string, id: string): Promise<void>;
77
- purgeFacts(tenantId: string, scope: string, scopeId: string): Promise<number>;
78
- updateDecayScores(tenantId: string, facts: Array<{
79
- id: string;
80
- decayScore: number;
81
- lastAccessed?: Date;
82
- frequency?: number;
83
- importance?: number;
84
- }>): Promise<void>;
85
- vectorSearch(options: VectorSearchOptions): Promise<VectorSearchResult[]>;
86
- keywordSearch(options: KeywordSearchOptions): Promise<KeywordSearchResult[]>;
87
- compoundSearch(options: CompoundSearchOptions): Promise<CompoundSearchResult[]>;
88
- createEntity(entity: CreateEntity & {
89
- id: string;
90
- embedding?: number[];
91
- embeddingModel?: string;
92
- embeddingDim?: number;
93
- }): Promise<Entity>;
94
- getEntity(tenantId: string, id: string): Promise<Entity | null>;
95
- findEntityByCanonicalName(tenantId: string, canonicalName: string, entityType: string): Promise<Entity | null>;
96
- findEntitiesByEmbedding(tenantId: string, embedding: number[], limit: number, minSimilarity?: number): Promise<Array<{
97
- entity: Entity;
98
- similarity: number;
99
- }>>;
100
- getEntitiesForTenant(tenantId: string, options: PaginationOptions): Promise<PaginatedResult<Entity>>;
101
- linkFactEntity(factId: string, entityId: string, role: string): Promise<void>;
102
- getEntitiesForFact(factId: string): Promise<Entity[]>;
103
- getFactsForEntity(tenantId: string, entityId: string, options: PaginationOptions): Promise<PaginatedResult<Fact>>;
104
- getFactsForEntities(tenantId: string, entityIds: string[], perEntityLimit: number): Promise<Array<{
105
- entityId: string;
106
- fact: Fact;
107
- }>>;
108
- createEdge(edge: CreateEdge & {
109
- id: string;
110
- }): Promise<Edge>;
111
- getEdgesForEntity(tenantId: string, entityId: string): Promise<Edge[]>;
112
- graphTraversal(options: GraphTraversalOptions): Promise<GraphTraversalResult>;
113
- createTrigger(trigger: CreateTrigger & {
114
- id: string;
115
- }): Promise<Trigger>;
116
- getTrigger(tenantId: string, id: string): Promise<Trigger | null>;
117
- getActiveTriggers(tenantId: string, scope: string, scopeId: string): Promise<Trigger[]>;
118
- updateTrigger(tenantId: string, id: string, updates: Partial<Trigger>): Promise<Trigger>;
119
- deleteTrigger(tenantId: string, id: string): Promise<void>;
120
- incrementTriggerFired(tenantId: string, id: string): Promise<void>;
121
- createMemoryAccess(access: CreateMemoryAccess & {
122
- id: string;
123
- }): Promise<MemoryAccess>;
124
- updateFeedback(tenantId: string, factId: string, feedback: {
125
- wasUseful: boolean;
126
- feedbackType: string;
127
- feedbackDetail?: string;
128
- wasCorrected?: boolean;
129
- }): Promise<void>;
130
- createExtraction(extraction: CreateExtraction & {
131
- id: string;
132
- }): Promise<Extraction>;
133
- getExtraction(tenantId: string, id: string): Promise<Extraction | null>;
134
- updateExtraction(tenantId: string, id: string, updates: Partial<Extraction>): Promise<Extraction>;
135
- getExtractionByHash(tenantId: string, inputHash: string): Promise<Extraction | null>;
136
- deleteExtraction(tenantId: string, id: string): Promise<void>;
137
- getExtractionsByTenant(tenantId: string, options: PaginationOptions): Promise<PaginatedResult<Extraction>>;
138
- createSession(session: CreateSession & {
139
- id: string;
140
- }): Promise<Session>;
141
- getSession(tenantId: string, id: string): Promise<Session | null>;
142
- endSession(tenantId: string, id: string, summary?: string, topics?: string[]): Promise<Session>;
143
- getSessionsByScope(tenantId: string, scope: string, scopeId: string, options: PaginationOptions): Promise<PaginatedResult<Session>>;
144
- createTenant(tenant: CreateTenant & {
145
- id: string;
146
- }): Promise<Tenant>;
147
- getTenant(id: string): Promise<Tenant | null>;
148
- getTenantBySlug(slug: string): Promise<Tenant | null>;
149
- updateTenant(id: string, updates: Partial<Tenant>): Promise<Tenant>;
150
- createApiKey(apiKey: CreateApiKey & {
151
- id: string;
152
- keyHash: string;
153
- keyPrefix: string;
154
- }): Promise<ApiKey>;
155
- getApiKeyByPrefix(prefix: string): Promise<ApiKey | null>;
156
- getApiKeysForTenant(tenantId: string): Promise<ApiKey[]>;
157
- revokeApiKey(tenantId: string, id: string): Promise<void>;
158
- updateApiKeyLastUsed(id: string): Promise<void>;
159
- incrementUsage(tenantId: string, tokens: number, queries: number, extractions: number, costUsd: number): Promise<void>;
160
- getUsage(tenantId: string, periodStart: Date): Promise<UsageRecord | null>;
161
- getCurrentUsage(tenantId: string): Promise<UsageRecord | null>;
162
- createWebhook(webhook: CreateWebhook & {
163
- id: string;
164
- secretHash: string;
165
- signingKey: string;
166
- }): Promise<Webhook>;
167
- getWebhook(tenantId: string, id: string): Promise<Webhook | null>;
168
- getWebhooksForTenant(tenantId: string): Promise<Webhook[]>;
169
- getWebhooksByEvent(tenantId: string, event: string): Promise<Webhook[]>;
170
- deleteWebhook(tenantId: string, id: string): Promise<void>;
171
- ping(): Promise<boolean>;
172
- }
173
- //# sourceMappingURL=storage.d.ts.map