@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.
- package/dist/adapters/storage.d.ts +29 -2
- package/dist/adapters/storage.d.ts.map +1 -1
- package/dist/extraction/pipeline.d.ts.map +1 -1
- package/dist/extraction/pipeline.js +165 -0
- package/dist/extraction/pipeline.js.map +1 -1
- package/dist/extraction/types.d.ts +2 -0
- package/dist/extraction/types.d.ts.map +1 -1
- package/dist/identity/index.d.ts +2 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +2 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/resolver.d.ts +31 -0
- package/dist/identity/resolver.d.ts.map +1 -0
- package/dist/identity/resolver.js +122 -0
- package/dist/identity/resolver.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/models/entity.d.ts +32 -0
- package/dist/models/entity.d.ts.map +1 -1
- package/dist/models/entity.js +11 -0
- package/dist/models/entity.js.map +1 -1
- package/dist/retrieval/graph-traversal.d.ts +4 -1
- package/dist/retrieval/graph-traversal.d.ts.map +1 -1
- package/dist/retrieval/graph-traversal.js +6 -3
- package/dist/retrieval/graph-traversal.js.map +1 -1
- package/dist/retrieval/search.d.ts.map +1 -1
- package/dist/retrieval/search.js +56 -3
- package/dist/retrieval/search.js.map +1 -1
- package/dist/retrieval/types.d.ts +1 -0
- package/dist/retrieval/types.d.ts.map +1 -1
- package/dist/retrieval/types.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/storage.ts +35 -2
- package/src/extraction/pipeline.ts +213 -0
- package/src/extraction/types.ts +2 -0
- package/src/identity/index.ts +1 -0
- package/src/identity/resolver.ts +149 -0
- package/src/index.ts +1 -0
- package/src/models/entity.ts +13 -0
- package/src/retrieval/graph-traversal.ts +7 -4
- package/src/retrieval/search.ts +58 -3
- package/src/retrieval/types.ts +1 -0
- package/src/adapters/cache.d.ts +0 -9
- package/src/adapters/cache.d.ts.map +0 -1
- package/src/adapters/cache.js +0 -2
- package/src/adapters/cache.js.map +0 -1
- package/src/adapters/embedding.d.ts +0 -7
- package/src/adapters/embedding.d.ts.map +0 -1
- package/src/adapters/embedding.js +0 -2
- package/src/adapters/embedding.js.map +0 -1
- package/src/adapters/llm.d.ts +0 -19
- package/src/adapters/llm.d.ts.map +0 -1
- package/src/adapters/llm.js +0 -2
- package/src/adapters/llm.js.map +0 -1
- package/src/adapters/perplexity-embedding.d.ts +0 -24
- package/src/adapters/perplexity-embedding.d.ts.map +0 -1
- package/src/adapters/perplexity-embedding.js +0 -78
- package/src/adapters/perplexity-embedding.js.map +0 -1
- package/src/adapters/storage.d.ts +0 -173
- package/src/adapters/storage.d.ts.map +0 -1
- package/src/adapters/storage.js +0 -2
- package/src/adapters/storage.js.map +0 -1
- package/src/config.d.ts +0 -296
- package/src/config.d.ts.map +0 -1
- package/src/config.js +0 -92
- package/src/config.js.map +0 -1
- package/src/extraction/contradiction.d.ts +0 -15
- package/src/extraction/contradiction.d.ts.map +0 -1
- package/src/extraction/contradiction.js +0 -23
- package/src/extraction/contradiction.js.map +0 -1
- package/src/extraction/cross-linker.d.ts +0 -23
- package/src/extraction/cross-linker.d.ts.map +0 -1
- package/src/extraction/cross-linker.js +0 -146
- package/src/extraction/cross-linker.js.map +0 -1
- package/src/extraction/dedup.d.ts +0 -12
- package/src/extraction/dedup.d.ts.map +0 -1
- package/src/extraction/dedup.js +0 -93
- package/src/extraction/dedup.js.map +0 -1
- package/src/extraction/entity-extractor.d.ts +0 -30
- package/src/extraction/entity-extractor.d.ts.map +0 -1
- package/src/extraction/entity-extractor.js +0 -145
- package/src/extraction/entity-extractor.js.map +0 -1
- package/src/extraction/hasher.d.ts +0 -5
- package/src/extraction/hasher.d.ts.map +0 -1
- package/src/extraction/hasher.js +0 -8
- package/src/extraction/hasher.js.map +0 -1
- package/src/extraction/heuristic.d.ts +0 -3
- package/src/extraction/heuristic.d.ts.map +0 -1
- package/src/extraction/heuristic.js +0 -282
- package/src/extraction/heuristic.js.map +0 -1
- package/src/extraction/llm-extractor.d.ts +0 -23
- package/src/extraction/llm-extractor.d.ts.map +0 -1
- package/src/extraction/llm-extractor.js +0 -240
- package/src/extraction/llm-extractor.js.map +0 -1
- package/src/extraction/pipeline.d.ts +0 -30
- package/src/extraction/pipeline.d.ts.map +0 -1
- package/src/extraction/pipeline.js +0 -413
- package/src/extraction/pipeline.js.map +0 -1
- package/src/extraction/prompts.d.ts +0 -28
- package/src/extraction/prompts.d.ts.map +0 -1
- package/src/extraction/prompts.js +0 -205
- package/src/extraction/prompts.js.map +0 -1
- package/src/extraction/sliding-window.d.ts +0 -41
- package/src/extraction/sliding-window.d.ts.map +0 -1
- package/src/extraction/sliding-window.js +0 -84
- package/src/extraction/sliding-window.js.map +0 -1
- package/src/extraction/types.d.ts +0 -80
- package/src/extraction/types.d.ts.map +0 -1
- package/src/extraction/types.js +0 -2
- package/src/extraction/types.js.map +0 -1
- package/src/feedback/tracker.d.ts +0 -25
- package/src/feedback/tracker.d.ts.map +0 -1
- package/src/feedback/tracker.js +0 -90
- package/src/feedback/tracker.js.map +0 -1
- package/src/models/api-key.d.ts +0 -54
- package/src/models/api-key.d.ts.map +0 -1
- package/src/models/api-key.js +0 -21
- package/src/models/api-key.js.map +0 -1
- package/src/models/edge.d.ts +0 -78
- package/src/models/edge.d.ts.map +0 -1
- package/src/models/edge.js +0 -29
- package/src/models/edge.js.map +0 -1
- package/src/models/entity.d.ts +0 -60
- package/src/models/entity.d.ts.map +0 -1
- package/src/models/entity.js +0 -22
- package/src/models/entity.js.map +0 -1
- package/src/models/extraction.d.ts +0 -111
- package/src/models/extraction.d.ts.map +0 -1
- package/src/models/extraction.js +0 -40
- package/src/models/extraction.js.map +0 -1
- package/src/models/fact-entity.d.ts +0 -33
- package/src/models/fact-entity.d.ts.map +0 -1
- package/src/models/fact-entity.js +0 -14
- package/src/models/fact-entity.js.map +0 -1
- package/src/models/fact.d.ts +0 -191
- package/src/models/fact.d.ts.map +0 -1
- package/src/models/fact.js +0 -72
- package/src/models/fact.js.map +0 -1
- package/src/models/index.d.ts +0 -13
- package/src/models/index.d.ts.map +0 -1
- package/src/models/index.js +0 -13
- package/src/models/index.js.map +0 -1
- package/src/models/memory-access.d.ts +0 -89
- package/src/models/memory-access.d.ts.map +0 -1
- package/src/models/memory-access.js +0 -33
- package/src/models/memory-access.js.map +0 -1
- package/src/models/session.d.ts +0 -60
- package/src/models/session.d.ts.map +0 -1
- package/src/models/session.js +0 -23
- package/src/models/session.js.map +0 -1
- package/src/models/tenant.d.ts +0 -448
- package/src/models/tenant.d.ts.map +0 -1
- package/src/models/tenant.js +0 -23
- package/src/models/tenant.js.map +0 -1
- package/src/models/trigger.d.ts +0 -87
- package/src/models/trigger.d.ts.map +0 -1
- package/src/models/trigger.js +0 -41
- package/src/models/trigger.js.map +0 -1
- package/src/models/usage-record.d.ts +0 -37
- package/src/models/usage-record.d.ts.map +0 -1
- package/src/models/usage-record.js +0 -14
- package/src/models/usage-record.js.map +0 -1
- package/src/models/webhook.d.ts +0 -50
- package/src/models/webhook.d.ts.map +0 -1
- package/src/models/webhook.js +0 -25
- package/src/models/webhook.js.map +0 -1
- package/src/retrieval/compound-search.d.ts +0 -13
- package/src/retrieval/compound-search.d.ts.map +0 -1
- package/src/retrieval/compound-search.js +0 -87
- package/src/retrieval/compound-search.js.map +0 -1
- package/src/retrieval/contradiction-surfacer.d.ts +0 -18
- package/src/retrieval/contradiction-surfacer.d.ts.map +0 -1
- package/src/retrieval/contradiction-surfacer.js +0 -64
- package/src/retrieval/contradiction-surfacer.js.map +0 -1
- package/src/retrieval/embedding-cache.d.ts +0 -17
- package/src/retrieval/embedding-cache.d.ts.map +0 -1
- package/src/retrieval/embedding-cache.js +0 -56
- package/src/retrieval/embedding-cache.js.map +0 -1
- package/src/retrieval/fusion.d.ts +0 -27
- package/src/retrieval/fusion.d.ts.map +0 -1
- package/src/retrieval/fusion.js +0 -87
- package/src/retrieval/fusion.js.map +0 -1
- package/src/retrieval/graph-traversal.d.ts +0 -29
- package/src/retrieval/graph-traversal.d.ts.map +0 -1
- package/src/retrieval/graph-traversal.js +0 -208
- package/src/retrieval/graph-traversal.js.map +0 -1
- package/src/retrieval/query-expansion.d.ts +0 -20
- package/src/retrieval/query-expansion.d.ts.map +0 -1
- package/src/retrieval/query-expansion.js +0 -76
- package/src/retrieval/query-expansion.js.map +0 -1
- package/src/retrieval/reranker.d.ts +0 -15
- package/src/retrieval/reranker.d.ts.map +0 -1
- package/src/retrieval/reranker.js +0 -47
- package/src/retrieval/reranker.js.map +0 -1
- package/src/retrieval/salience-scorer.d.ts +0 -15
- package/src/retrieval/salience-scorer.d.ts.map +0 -1
- package/src/retrieval/salience-scorer.js +0 -41
- package/src/retrieval/salience-scorer.js.map +0 -1
- package/src/retrieval/search.d.ts +0 -21
- package/src/retrieval/search.d.ts.map +0 -1
- package/src/retrieval/search.js +0 -228
- package/src/retrieval/search.js.map +0 -1
- package/src/retrieval/temporal-scorer.d.ts +0 -18
- package/src/retrieval/temporal-scorer.d.ts.map +0 -1
- package/src/retrieval/temporal-scorer.js +0 -106
- package/src/retrieval/temporal-scorer.js.map +0 -1
- package/src/retrieval/trigger-matcher.d.ts +0 -18
- package/src/retrieval/trigger-matcher.d.ts.map +0 -1
- package/src/retrieval/trigger-matcher.js +0 -134
- package/src/retrieval/trigger-matcher.js.map +0 -1
- package/src/retrieval/types.d.ts +0 -70
- package/src/retrieval/types.d.ts.map +0 -1
- package/src/retrieval/types.js +0 -9
- package/src/retrieval/types.js.map +0 -1
- package/src/retrieval/vector-search.d.ts +0 -5
- package/src/retrieval/vector-search.d.ts.map +0 -1
- package/src/retrieval/vector-search.js +0 -24
- package/src/retrieval/vector-search.js.map +0 -1
- package/src/salience/decay.d.ts +0 -9
- package/src/salience/decay.d.ts.map +0 -1
- package/src/salience/decay.js +0 -15
- package/src/salience/decay.js.map +0 -1
- package/src/scratchpad/scratchpad.d.ts +0 -23
- package/src/scratchpad/scratchpad.d.ts.map +0 -1
- package/src/scratchpad/scratchpad.js +0 -137
- package/src/scratchpad/scratchpad.js.map +0 -1
- package/src/sessions/manager.d.ts +0 -11
- package/src/sessions/manager.d.ts.map +0 -1
- package/src/sessions/manager.js +0 -63
- 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
package/src/models/entity.ts
CHANGED
|
@@ -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
|
-
|
|
51
|
-
|
|
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, {
|
package/src/retrieval/search.ts
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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,
|
|
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
|
}
|
package/src/retrieval/types.ts
CHANGED
|
@@ -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) */
|
package/src/adapters/cache.d.ts
DELETED
|
@@ -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"}
|
package/src/adapters/cache.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":""}
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["embedding.ts"],"names":[],"mappings":""}
|
package/src/adapters/llm.d.ts
DELETED
|
@@ -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"}
|
package/src/adapters/llm.js
DELETED
package/src/adapters/llm.js.map
DELETED
|
@@ -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
|