@steno-ai/engine 0.1.19 → 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,
|
|
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,62 +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
|
-
//
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
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
|
+
];
|
|
85
84
|
const candidates = [];
|
|
86
|
-
|
|
87
|
-
for (const match of recentStructuredFacts) {
|
|
88
|
-
// Time guard — stop before we exceed the budget
|
|
85
|
+
for (let i = 0; i < sourceTypes.length && candidates.length < maxCandidates; i++) {
|
|
89
86
|
if (Date.now() - startTime > maxDurationMs) {
|
|
90
87
|
console.error(`[steno-structured-xlink] Time budget exhausted after ${candidates.length} candidates`);
|
|
91
88
|
break;
|
|
92
89
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
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,
|
|
100
96
|
tenantId,
|
|
101
97
|
scope,
|
|
102
98
|
scopeId,
|
|
103
|
-
limit:
|
|
104
|
-
minSimilarity:
|
|
99
|
+
limit: maxFacts,
|
|
100
|
+
minSimilarity: 0.3, // low threshold to find structured facts
|
|
105
101
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
+
}
|
|
125
128
|
if (candidates.length >= maxCandidates)
|
|
126
129
|
break;
|
|
127
130
|
}
|
|
128
|
-
if (candidates.length >= maxCandidates)
|
|
129
|
-
break;
|
|
130
131
|
}
|
|
131
132
|
return candidates;
|
|
132
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structured-cross-linker.js","sourceRoot":"","sources":["../../src/extraction/structured-cross-linker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAuB,EACvB,QAAgB,EAChB,YAAiC,EAAI,2BAA2B;AAChE,SAAiB;IAEjB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,IAAI,YAAY,EAAE,CAAC;QACrD,8DAA8D;QAC9D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAEvC,mEAAmE;QACnE,qEAAqE;QACrE,mFAAmF;QACnF,IAAI,CAAC;YACH,+DAA+D;YAC/D,8EAA8E;YAC9E,2EAA2E;YAC3E,gEAAgE;YAChE,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YACvF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YAErE,kFAAkF;YAClF,4EAA4E;YAC5E,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,kBAAyB,CAAC,CAAC;YAC/D,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,kBAAyB,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,kBAAyB,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,iBAAwB,CAAC,CAAC;YAE1D,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC3F,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;gBAC1B,4EAA4E;gBAC5E,MAAM,UAAU,GAAG,IAAI,aAAa,4CAA4C;oBAC9E,WAAW,IAAI,UAAU;oBACzB,QAAQ,IAAI,OAAO;oBACnB,QAAQ,IAAI,OAAO;oBACnB,OAAO,IAAI,OAAO;iBACnB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAE/B,OAAO,CAAC,KAAK,CAAC,oDAAoD,UAAU,EAAE,CAAC,CAAC;gBAChF,YAAY,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kDAAkD,aAAa,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9H,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAoBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAuB,EACvB,SAA2B,EAC3B,QAAgB,EAChB,KAAa,EACb,OAAe,EACf,OAAuG;IAEvG,MAAM,MAAM,GAAG,OAAO,EAAE,aAAa,IAAI,GAAG,CAAC;IAC7C,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC;IACnD,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;IACzC,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,KAAK,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,sEAAsE;IACtE,
|
|
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
|
@@ -113,65 +113,71 @@ export async function findPendingCrossLinks(
|
|
|
113
113
|
const maxDurationMs = options?.maxDurationMs ?? 20000;
|
|
114
114
|
const startTime = Date.now();
|
|
115
115
|
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
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
|
+
];
|
|
127
126
|
|
|
128
127
|
const candidates: PendingCrossLink[] = [];
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
for (const match of recentStructuredFacts) {
|
|
132
|
-
// Time guard — stop before we exceed the budget
|
|
129
|
+
for (let i = 0; i < sourceTypes.length && candidates.length < maxCandidates; i++) {
|
|
133
130
|
if (Date.now() - startTime > maxDurationMs) {
|
|
134
131
|
console.error(`[steno-structured-xlink] Time budget exhausted after ${candidates.length} candidates`);
|
|
135
132
|
break;
|
|
136
133
|
}
|
|
137
134
|
|
|
138
|
-
const
|
|
139
|
-
|
|
135
|
+
const sourceType = sourceTypes[i]!;
|
|
136
|
+
const queryText = queryTexts[i]!;
|
|
140
137
|
|
|
141
|
-
// Embed the
|
|
142
|
-
const
|
|
138
|
+
// Embed the query to find facts of this type
|
|
139
|
+
const queryEmbedding = await embedding.embed(queryText);
|
|
143
140
|
|
|
144
|
-
const
|
|
145
|
-
embedding:
|
|
141
|
+
const results = await storage.vectorSearch({
|
|
142
|
+
embedding: queryEmbedding,
|
|
146
143
|
tenantId,
|
|
147
144
|
scope,
|
|
148
145
|
scopeId,
|
|
149
|
-
limit:
|
|
150
|
-
minSimilarity:
|
|
146
|
+
limit: maxFacts,
|
|
147
|
+
minSimilarity: 0.3, // low threshold to find structured facts
|
|
151
148
|
});
|
|
152
149
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
entityName: '',
|
|
161
|
-
factId: fact.id,
|
|
162
|
-
factContent: fact.content,
|
|
163
|
-
sourceType: fact.sourceType,
|
|
164
|
-
candidateEntityId: '',
|
|
165
|
-
candidateEntityName: '',
|
|
166
|
-
candidateFactId: match.fact.id,
|
|
167
|
-
candidateFactContent: match.fact.content,
|
|
168
|
-
candidateSourceType: match.fact.sourceType,
|
|
169
|
-
similarity: match.similarity,
|
|
170
|
-
});
|
|
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
|
+
);
|
|
171
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
|
+
}
|
|
172
179
|
if (candidates.length >= maxCandidates) break;
|
|
173
180
|
}
|
|
174
|
-
if (candidates.length >= maxCandidates) break;
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
return candidates;
|