@steno-ai/engine 0.1.20 → 0.1.21

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.
@@ -1 +1 @@
1
- {"version":3,"file":"structured-cross-linker.d.ts","sourceRoot":"","sources":["../../src/extraction/structured-cross-linker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOrD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAI,2BAA2B;AAChE,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkE7B;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,gBAAgB,EAC3B,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA8EtD"}
1
+ {"version":3,"file":"structured-cross-linker.d.ts","sourceRoot":"","sources":["../../src/extraction/structured-cross-linker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOrD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAI,2BAA2B;AAChE,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA2E7B;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,gBAAgB,EAC3B,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA8EtD"}
@@ -71,58 +71,63 @@ export async function findPendingCrossLinks(storage, embedding, tenantId, scope,
71
71
  const maxFacts = options?.maxFacts ?? 10;
72
72
  const maxDurationMs = options?.maxDurationMs ?? 20000;
73
73
  const startTime = Date.now();
74
- // Find structured facts by querying scope and filtering by sourceType
75
- // Keyword search doesn't work on encrypted content, so we use getFactsByScope
76
- const allFacts = await storage.getFactsByScope(tenantId, scope, scopeId, { limit: 100 });
77
- const structuredFacts = (allFacts.data ?? [])
78
- .filter(f => f.sourceType?.startsWith('structured_'))
79
- .slice(0, maxFacts);
80
- const recentStructuredFacts = structuredFacts.map(f => ({ fact: f, similarity: 1.0 }));
81
- if (recentStructuredFacts.length === 0)
82
- return [];
74
+ // Use cross-source vector search: embed a synthetic query per structured source type
75
+ // and find similar facts from OTHER source types. This avoids needing to read
76
+ // individual fact embeddings (which are stripped from the Fact type).
77
+ const sourceTypes = ['structured_task', 'structured_event', 'structured_vault', 'structured_email'];
78
+ const queryTexts = [
79
+ 'user task todo priority deadline',
80
+ 'calendar event meeting appointment schedule',
81
+ 'saved bookmark vault article job link',
82
+ 'email message inbox reply draft',
83
+ ];
83
84
  const candidates = [];
84
- // For each structured fact, find semantically similar facts from different source types
85
- for (const match of recentStructuredFacts) {
86
- // Time guard — stop before we exceed the budget
85
+ for (let i = 0; i < sourceTypes.length && candidates.length < maxCandidates; i++) {
87
86
  if (Date.now() - startTime > maxDurationMs) {
88
87
  console.error(`[steno-structured-xlink] Time budget exhausted after ${candidates.length} candidates`);
89
88
  break;
90
89
  }
91
- const fact = match.fact;
92
- // Embed the fact content to find similar facts
93
- const factEmbedding = await embedding.embed(fact.content);
94
- const similar = await storage.vectorSearch({
95
- embedding: factEmbedding,
90
+ const sourceType = sourceTypes[i];
91
+ const queryText = queryTexts[i];
92
+ // Embed the query to find facts of this type
93
+ const queryEmbedding = await embedding.embed(queryText);
94
+ const results = await storage.vectorSearch({
95
+ embedding: queryEmbedding,
96
96
  tenantId,
97
97
  scope,
98
98
  scopeId,
99
- limit: 5,
100
- minSimilarity: minSim,
99
+ limit: maxFacts,
100
+ minSimilarity: 0.3, // low threshold to find structured facts
101
101
  });
102
- for (const match of similar) {
103
- // Skip self-matches and same-source matches
104
- if (match.fact.id === fact.id)
105
- continue;
106
- if (match.fact.sourceType === fact.sourceType)
107
- continue;
108
- candidates.push({
109
- entityId: '',
110
- entityName: '',
111
- factId: fact.id,
112
- factContent: fact.content,
113
- sourceType: fact.sourceType,
114
- candidateEntityId: '',
115
- candidateEntityName: '',
116
- candidateFactId: match.fact.id,
117
- candidateFactContent: match.fact.content,
118
- candidateSourceType: match.fact.sourceType,
119
- similarity: match.similarity,
120
- });
102
+ // Find structured facts of THIS type
103
+ const sourceFacts = results.filter(r => r.fact.sourceType === sourceType);
104
+ // Find facts of OTHER structured types that might be cross-linked
105
+ const otherFacts = results.filter(r => r.fact.sourceType?.startsWith('structured_') &&
106
+ r.fact.sourceType !== sourceType);
107
+ // Create candidate pairs
108
+ for (const src of sourceFacts) {
109
+ for (const other of otherFacts) {
110
+ if (src.fact.id === other.fact.id)
111
+ continue;
112
+ candidates.push({
113
+ entityId: '',
114
+ entityName: '',
115
+ factId: src.fact.id,
116
+ factContent: src.fact.content,
117
+ sourceType: src.fact.sourceType,
118
+ candidateEntityId: '',
119
+ candidateEntityName: '',
120
+ candidateFactId: other.fact.id,
121
+ candidateFactContent: other.fact.content,
122
+ candidateSourceType: other.fact.sourceType,
123
+ similarity: Math.min(src.similarity, other.similarity),
124
+ });
125
+ if (candidates.length >= maxCandidates)
126
+ break;
127
+ }
121
128
  if (candidates.length >= maxCandidates)
122
129
  break;
123
130
  }
124
- if (candidates.length >= maxCandidates)
125
- break;
126
131
  }
127
132
  return candidates;
128
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"structured-cross-linker.js","sourceRoot":"","sources":["../../src/extraction/structured-cross-linker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"structured-cross-linker.js","sourceRoot":"","sources":["../../src/extraction/structured-cross-linker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steno-ai/engine",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Core memory engine — extraction, retrieval, knowledge graph",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -113,62 +113,71 @@ export async function findPendingCrossLinks(
113
113
  const maxDurationMs = options?.maxDurationMs ?? 20000;
114
114
  const startTime = Date.now();
115
115
 
116
- // Find structured facts by querying scope and filtering by sourceType
117
- // Keyword search doesn't work on encrypted content, so we use getFactsByScope
118
- const allFacts = await storage.getFactsByScope(tenantId, scope, scopeId, { limit: 100 });
119
- const structuredFacts = (allFacts.data ?? [])
120
- .filter(f => f.sourceType?.startsWith('structured_'))
121
- .slice(0, maxFacts);
122
- const recentStructuredFacts = structuredFacts.map(f => ({ fact: f, similarity: 1.0 }));
123
-
124
- if (recentStructuredFacts.length === 0) return [];
116
+ // Use cross-source vector search: embed a synthetic query per structured source type
117
+ // and find similar facts from OTHER source types. This avoids needing to read
118
+ // individual fact embeddings (which are stripped from the Fact type).
119
+ const sourceTypes = ['structured_task', 'structured_event', 'structured_vault', 'structured_email'];
120
+ const queryTexts = [
121
+ 'user task todo priority deadline',
122
+ 'calendar event meeting appointment schedule',
123
+ 'saved bookmark vault article job link',
124
+ 'email message inbox reply draft',
125
+ ];
125
126
 
126
127
  const candidates: PendingCrossLink[] = [];
127
128
 
128
- // For each structured fact, find semantically similar facts from different source types
129
- for (const match of recentStructuredFacts) {
130
- // Time guard — stop before we exceed the budget
129
+ for (let i = 0; i < sourceTypes.length && candidates.length < maxCandidates; i++) {
131
130
  if (Date.now() - startTime > maxDurationMs) {
132
131
  console.error(`[steno-structured-xlink] Time budget exhausted after ${candidates.length} candidates`);
133
132
  break;
134
133
  }
135
134
 
136
- const fact = match.fact;
135
+ const sourceType = sourceTypes[i]!;
136
+ const queryText = queryTexts[i]!;
137
137
 
138
- // Embed the fact content to find similar facts
139
- const factEmbedding = await embedding.embed(fact.content);
138
+ // Embed the query to find facts of this type
139
+ const queryEmbedding = await embedding.embed(queryText);
140
140
 
141
- const similar = await storage.vectorSearch({
142
- embedding: factEmbedding,
141
+ const results = await storage.vectorSearch({
142
+ embedding: queryEmbedding,
143
143
  tenantId,
144
144
  scope,
145
145
  scopeId,
146
- limit: 5,
147
- minSimilarity: minSim,
146
+ limit: maxFacts,
147
+ minSimilarity: 0.3, // low threshold to find structured facts
148
148
  });
149
149
 
150
- for (const match of similar) {
151
- // Skip self-matches and same-source matches
152
- if (match.fact.id === fact.id) continue;
153
- if (match.fact.sourceType === fact.sourceType) continue;
154
-
155
- candidates.push({
156
- entityId: '',
157
- entityName: '',
158
- factId: fact.id,
159
- factContent: fact.content,
160
- sourceType: fact.sourceType,
161
- candidateEntityId: '',
162
- candidateEntityName: '',
163
- candidateFactId: match.fact.id,
164
- candidateFactContent: match.fact.content,
165
- candidateSourceType: match.fact.sourceType,
166
- similarity: match.similarity,
167
- });
150
+ // Find structured facts of THIS type
151
+ const sourceFacts = results.filter(r => r.fact.sourceType === sourceType);
152
+ // Find facts of OTHER structured types that might be cross-linked
153
+ const otherFacts = results.filter(r =>
154
+ r.fact.sourceType?.startsWith('structured_') &&
155
+ r.fact.sourceType !== sourceType
156
+ );
168
157
 
158
+ // Create candidate pairs
159
+ for (const src of sourceFacts) {
160
+ for (const other of otherFacts) {
161
+ if (src.fact.id === other.fact.id) continue;
162
+
163
+ candidates.push({
164
+ entityId: '',
165
+ entityName: '',
166
+ factId: src.fact.id,
167
+ factContent: src.fact.content,
168
+ sourceType: src.fact.sourceType,
169
+ candidateEntityId: '',
170
+ candidateEntityName: '',
171
+ candidateFactId: other.fact.id,
172
+ candidateFactContent: other.fact.content,
173
+ candidateSourceType: other.fact.sourceType,
174
+ similarity: Math.min(src.similarity, other.similarity),
175
+ });
176
+
177
+ if (candidates.length >= maxCandidates) break;
178
+ }
169
179
  if (candidates.length >= maxCandidates) break;
170
180
  }
171
- if (candidates.length >= maxCandidates) break;
172
181
  }
173
182
 
174
183
  return candidates;