@agentlensai/server 0.2.0 → 0.5.0
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/db/embedding-store.d.ts +74 -0
- package/dist/db/embedding-store.d.ts.map +1 -0
- package/dist/db/embedding-store.js +177 -0
- package/dist/db/embedding-store.js.map +1 -0
- package/dist/db/lesson-store.d.ts +57 -0
- package/dist/db/lesson-store.d.ts.map +1 -0
- package/dist/db/lesson-store.js +217 -0
- package/dist/db/lesson-store.js.map +1 -0
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +250 -4
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.sqlite.d.ts +881 -55
- package/dist/db/schema.sqlite.d.ts.map +1 -1
- package/dist/db/schema.sqlite.js +82 -4
- package/dist/db/schema.sqlite.js.map +1 -1
- package/dist/db/session-summary-store.d.ts +45 -0
- package/dist/db/session-summary-store.d.ts.map +1 -0
- package/dist/db/session-summary-store.js +112 -0
- package/dist/db/session-summary-store.js.map +1 -0
- package/dist/db/sqlite-store.d.ts +25 -13
- package/dist/db/sqlite-store.d.ts.map +1 -1
- package/dist/db/sqlite-store.js +224 -47
- package/dist/db/sqlite-store.js.map +1 -1
- package/dist/db/tenant-scoped-store.d.ts +61 -0
- package/dist/db/tenant-scoped-store.d.ts.map +1 -0
- package/dist/db/tenant-scoped-store.js +94 -0
- package/dist/db/tenant-scoped-store.js.map +1 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/alert-engine.d.ts +72 -0
- package/dist/lib/alert-engine.d.ts.map +1 -0
- package/dist/lib/alert-engine.js +318 -0
- package/dist/lib/alert-engine.js.map +1 -0
- package/dist/lib/analysis/cost-analysis.d.ts +20 -0
- package/dist/lib/analysis/cost-analysis.d.ts.map +1 -0
- package/dist/lib/analysis/cost-analysis.js +158 -0
- package/dist/lib/analysis/cost-analysis.js.map +1 -0
- package/dist/lib/analysis/error-patterns.d.ts +26 -0
- package/dist/lib/analysis/error-patterns.d.ts.map +1 -0
- package/dist/lib/analysis/error-patterns.js +155 -0
- package/dist/lib/analysis/error-patterns.js.map +1 -0
- package/dist/lib/analysis/index.d.ts +23 -0
- package/dist/lib/analysis/index.d.ts.map +1 -0
- package/dist/lib/analysis/index.js +144 -0
- package/dist/lib/analysis/index.js.map +1 -0
- package/dist/lib/analysis/performance-trends.d.ts +19 -0
- package/dist/lib/analysis/performance-trends.d.ts.map +1 -0
- package/dist/lib/analysis/performance-trends.js +118 -0
- package/dist/lib/analysis/performance-trends.js.map +1 -0
- package/dist/lib/analysis/tool-sequences.d.ts +19 -0
- package/dist/lib/analysis/tool-sequences.d.ts.map +1 -0
- package/dist/lib/analysis/tool-sequences.js +145 -0
- package/dist/lib/analysis/tool-sequences.js.map +1 -0
- package/dist/lib/context/index.d.ts +5 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/index.js +5 -0
- package/dist/lib/context/index.js.map +1 -0
- package/dist/lib/context/retrieval.d.ts +56 -0
- package/dist/lib/context/retrieval.d.ts.map +1 -0
- package/dist/lib/context/retrieval.js +229 -0
- package/dist/lib/context/retrieval.js.map +1 -0
- package/dist/lib/embeddings/index.d.ts +31 -0
- package/dist/lib/embeddings/index.d.ts.map +1 -0
- package/dist/lib/embeddings/index.js +31 -0
- package/dist/lib/embeddings/index.js.map +1 -0
- package/dist/lib/embeddings/local.d.ts +15 -0
- package/dist/lib/embeddings/local.d.ts.map +1 -0
- package/dist/lib/embeddings/local.js +65 -0
- package/dist/lib/embeddings/local.js.map +1 -0
- package/dist/lib/embeddings/math.d.ts +13 -0
- package/dist/lib/embeddings/math.d.ts.map +1 -0
- package/dist/lib/embeddings/math.js +35 -0
- package/dist/lib/embeddings/math.js.map +1 -0
- package/dist/lib/embeddings/openai.d.ts +15 -0
- package/dist/lib/embeddings/openai.d.ts.map +1 -0
- package/dist/lib/embeddings/openai.js +58 -0
- package/dist/lib/embeddings/openai.js.map +1 -0
- package/dist/lib/embeddings/summarizer.d.ts +26 -0
- package/dist/lib/embeddings/summarizer.d.ts.map +1 -0
- package/dist/lib/embeddings/summarizer.js +181 -0
- package/dist/lib/embeddings/summarizer.js.map +1 -0
- package/dist/lib/embeddings/types.d.ts +17 -0
- package/dist/lib/embeddings/types.d.ts.map +1 -0
- package/dist/lib/embeddings/types.js +5 -0
- package/dist/lib/embeddings/types.js.map +1 -0
- package/dist/lib/embeddings/worker.d.ts +56 -0
- package/dist/lib/embeddings/worker.d.ts.map +1 -0
- package/dist/lib/embeddings/worker.js +109 -0
- package/dist/lib/embeddings/worker.js.map +1 -0
- package/dist/lib/event-bus.d.ts +48 -0
- package/dist/lib/event-bus.d.ts.map +1 -0
- package/dist/lib/event-bus.js +34 -0
- package/dist/lib/event-bus.js.map +1 -0
- package/dist/lib/retention.d.ts +1 -1
- package/dist/lib/retention.d.ts.map +1 -1
- package/dist/lib/sse.d.ts +22 -0
- package/dist/lib/sse.d.ts.map +1 -0
- package/dist/lib/sse.js +121 -0
- package/dist/lib/sse.js.map +1 -0
- package/dist/middleware/auth.d.ts +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +2 -1
- package/dist/middleware/auth.js.map +1 -1
- package/dist/routes/agents.d.ts +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +6 -3
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/alerts.d.ts +17 -0
- package/dist/routes/alerts.d.ts.map +1 -0
- package/dist/routes/alerts.js +141 -0
- package/dist/routes/alerts.js.map +1 -0
- package/dist/routes/analytics.d.ts +16 -0
- package/dist/routes/analytics.d.ts.map +1 -0
- package/dist/routes/analytics.js +307 -0
- package/dist/routes/analytics.js.map +1 -0
- package/dist/routes/api-keys.d.ts.map +1 -1
- package/dist/routes/api-keys.js +30 -5
- package/dist/routes/api-keys.js.map +1 -1
- package/dist/routes/config.d.ts +5 -0
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +27 -7
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/context.d.ts +23 -0
- package/dist/routes/context.d.ts.map +1 -0
- package/dist/routes/context.js +52 -0
- package/dist/routes/context.js.map +1 -0
- package/dist/routes/events.d.ts +7 -2
- package/dist/routes/events.d.ts.map +1 -1
- package/dist/routes/events.js +76 -8
- package/dist/routes/events.js.map +1 -1
- package/dist/routes/ingest.d.ts +36 -0
- package/dist/routes/ingest.d.ts.map +1 -0
- package/dist/routes/ingest.js +280 -0
- package/dist/routes/ingest.js.map +1 -0
- package/dist/routes/lessons.d.ts +19 -0
- package/dist/routes/lessons.d.ts.map +1 -0
- package/dist/routes/lessons.js +164 -0
- package/dist/routes/lessons.js.map +1 -0
- package/dist/routes/recall.d.ts +20 -0
- package/dist/routes/recall.d.ts.map +1 -0
- package/dist/routes/recall.js +71 -0
- package/dist/routes/recall.js.map +1 -0
- package/dist/routes/reflect.d.ts +15 -0
- package/dist/routes/reflect.d.ts.map +1 -0
- package/dist/routes/reflect.js +55 -0
- package/dist/routes/reflect.js.map +1 -0
- package/dist/routes/sessions.d.ts +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +9 -7
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/stats.d.ts +1 -1
- package/dist/routes/stats.d.ts.map +1 -1
- package/dist/routes/stats.js +3 -1
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/stream.d.ts +23 -0
- package/dist/routes/stream.d.ts.map +1 -0
- package/dist/routes/stream.js +94 -0
- package/dist/routes/stream.js.map +1 -0
- package/dist/routes/tenant-helper.d.ts +20 -0
- package/dist/routes/tenant-helper.d.ts.map +1 -0
- package/dist/routes/tenant-helper.js +23 -0
- package/dist/routes/tenant-helper.js.map +1 -0
- package/package.json +11 -11
- package/LICENSE +0 -21
- package/dist/__tests__/agents-stats.test.d.ts +0 -5
- package/dist/__tests__/agents-stats.test.d.ts.map +0 -1
- package/dist/__tests__/agents-stats.test.js +0 -134
- package/dist/__tests__/agents-stats.test.js.map +0 -1
- package/dist/__tests__/api-keys.test.d.ts +0 -5
- package/dist/__tests__/api-keys.test.d.ts.map +0 -1
- package/dist/__tests__/api-keys.test.js +0 -118
- package/dist/__tests__/api-keys.test.js.map +0 -1
- package/dist/__tests__/auth-no-db.test.d.ts +0 -2
- package/dist/__tests__/auth-no-db.test.d.ts.map +0 -1
- package/dist/__tests__/auth-no-db.test.js +0 -43
- package/dist/__tests__/auth-no-db.test.js.map +0 -1
- package/dist/__tests__/auth.test.d.ts +0 -5
- package/dist/__tests__/auth.test.d.ts.map +0 -1
- package/dist/__tests__/auth.test.js +0 -86
- package/dist/__tests__/auth.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -2
- package/dist/__tests__/config.test.d.ts.map +0 -1
- package/dist/__tests__/config.test.js +0 -37
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/events-ingest.test.d.ts +0 -5
- package/dist/__tests__/events-ingest.test.d.ts.map +0 -1
- package/dist/__tests__/events-ingest.test.js +0 -248
- package/dist/__tests__/events-ingest.test.js.map +0 -1
- package/dist/__tests__/events-query.test.d.ts +0 -5
- package/dist/__tests__/events-query.test.d.ts.map +0 -1
- package/dist/__tests__/events-query.test.js +0 -205
- package/dist/__tests__/events-query.test.js.map +0 -1
- package/dist/__tests__/health.test.d.ts +0 -5
- package/dist/__tests__/health.test.d.ts.map +0 -1
- package/dist/__tests__/health.test.js +0 -40
- package/dist/__tests__/health.test.js.map +0 -1
- package/dist/__tests__/sessions.test.d.ts +0 -5
- package/dist/__tests__/sessions.test.d.ts.map +0 -1
- package/dist/__tests__/sessions.test.js +0 -176
- package/dist/__tests__/sessions.test.js.map +0 -1
- package/dist/__tests__/test-helpers.d.ts +0 -24
- package/dist/__tests__/test-helpers.d.ts.map +0 -1
- package/dist/__tests__/test-helpers.js +0 -45
- package/dist/__tests__/test-helpers.js.map +0 -1
- package/dist/db/__tests__/init.test.d.ts +0 -2
- package/dist/db/__tests__/init.test.d.ts.map +0 -1
- package/dist/db/__tests__/init.test.js +0 -73
- package/dist/db/__tests__/init.test.js.map +0 -1
- package/dist/db/__tests__/sqlite-store-read.test.d.ts +0 -2
- package/dist/db/__tests__/sqlite-store-read.test.d.ts.map +0 -1
- package/dist/db/__tests__/sqlite-store-read.test.js +0 -749
- package/dist/db/__tests__/sqlite-store-read.test.js.map +0 -1
- package/dist/db/__tests__/sqlite-store-write.test.d.ts +0 -2
- package/dist/db/__tests__/sqlite-store-write.test.d.ts.map +0 -1
- package/dist/db/__tests__/sqlite-store-write.test.js +0 -418
- package/dist/db/__tests__/sqlite-store-write.test.js.map +0 -1
- package/dist/lib/__tests__/retention.test.d.ts +0 -2
- package/dist/lib/__tests__/retention.test.d.ts.map +0 -1
- package/dist/lib/__tests__/retention.test.js +0 -238
- package/dist/lib/__tests__/retention.test.js.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Sequence Analysis (Story 4.2)
|
|
3
|
+
*
|
|
4
|
+
* Analyzes tool_call events to extract N-grams (2-grams and 3-grams)
|
|
5
|
+
* of tool sequences per session, and identifies error-prone sequences.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Analyze tool usage sequences across sessions.
|
|
9
|
+
*/
|
|
10
|
+
export async function analyzeToolSequences(store, opts = {}) {
|
|
11
|
+
const limit = opts.limit ?? 20;
|
|
12
|
+
// Query tool_call events
|
|
13
|
+
const toolCallResult = await store.queryEvents({
|
|
14
|
+
agentId: opts.agentId,
|
|
15
|
+
from: opts.from,
|
|
16
|
+
to: opts.to,
|
|
17
|
+
eventType: 'tool_call',
|
|
18
|
+
limit: 500,
|
|
19
|
+
order: 'asc',
|
|
20
|
+
});
|
|
21
|
+
// Also query tool_error events to identify error-prone sequences
|
|
22
|
+
const toolErrorResult = await store.queryEvents({
|
|
23
|
+
agentId: opts.agentId,
|
|
24
|
+
from: opts.from,
|
|
25
|
+
to: opts.to,
|
|
26
|
+
eventType: 'tool_error',
|
|
27
|
+
limit: 500,
|
|
28
|
+
order: 'asc',
|
|
29
|
+
});
|
|
30
|
+
const allToolCalls = toolCallResult.events;
|
|
31
|
+
const allToolErrors = toolErrorResult.events;
|
|
32
|
+
const eventsAnalyzed = allToolCalls.length + allToolErrors.length;
|
|
33
|
+
const timeRange = {
|
|
34
|
+
from: allToolCalls.length > 0 ? allToolCalls[0].timestamp : (opts.from ?? ''),
|
|
35
|
+
to: allToolCalls.length > 0 ? allToolCalls[allToolCalls.length - 1].timestamp : (opts.to ?? ''),
|
|
36
|
+
};
|
|
37
|
+
// Group tool_call events by session
|
|
38
|
+
const sessionToolCalls = new Map();
|
|
39
|
+
for (const event of allToolCalls) {
|
|
40
|
+
const list = sessionToolCalls.get(event.sessionId) ?? [];
|
|
41
|
+
list.push(event);
|
|
42
|
+
sessionToolCalls.set(event.sessionId, list);
|
|
43
|
+
}
|
|
44
|
+
// Group tool_error events by session for error-prone detection
|
|
45
|
+
const sessionErrors = new Map();
|
|
46
|
+
for (const event of allToolErrors) {
|
|
47
|
+
const list = sessionErrors.get(event.sessionId) ?? [];
|
|
48
|
+
list.push(event);
|
|
49
|
+
sessionErrors.set(event.sessionId, list);
|
|
50
|
+
}
|
|
51
|
+
// Extract tool names per session (ordered by timestamp)
|
|
52
|
+
const uniqueToolsSet = new Set();
|
|
53
|
+
let totalCalls = 0;
|
|
54
|
+
const sessionToolNames = new Map();
|
|
55
|
+
for (const [sessionId, calls] of sessionToolCalls) {
|
|
56
|
+
const names = calls.map((e) => {
|
|
57
|
+
const p = e.payload;
|
|
58
|
+
const name = String(p.toolName ?? 'unknown');
|
|
59
|
+
uniqueToolsSet.add(name);
|
|
60
|
+
return name;
|
|
61
|
+
});
|
|
62
|
+
sessionToolNames.set(sessionId, names);
|
|
63
|
+
totalCalls += names.length;
|
|
64
|
+
}
|
|
65
|
+
// Extract N-grams and count frequencies
|
|
66
|
+
// key = tools joined by "→", value = { frequency across sessions, set of sessions, errorFollowed count }
|
|
67
|
+
const ngramMap = new Map();
|
|
68
|
+
for (const [sessionId, toolNames] of sessionToolNames) {
|
|
69
|
+
const sessionErrorEvents = sessionErrors.get(sessionId) ?? [];
|
|
70
|
+
// Get the full session timeline for error-proximity checks
|
|
71
|
+
const sessionCalls = sessionToolCalls.get(sessionId) ?? [];
|
|
72
|
+
// Extract 2-grams and 3-grams
|
|
73
|
+
const seenInSession = new Set(); // Avoid counting same ngram twice per session
|
|
74
|
+
for (const n of [2, 3]) {
|
|
75
|
+
for (let i = 0; i <= toolNames.length - n; i++) {
|
|
76
|
+
const ngram = toolNames.slice(i, i + n);
|
|
77
|
+
const key = ngram.join('→');
|
|
78
|
+
if (!seenInSession.has(key)) {
|
|
79
|
+
seenInSession.add(key);
|
|
80
|
+
let entry = ngramMap.get(key);
|
|
81
|
+
if (!entry) {
|
|
82
|
+
entry = { tools: ngram, frequency: 0, sessions: new Set(), errorFollowed: 0 };
|
|
83
|
+
ngramMap.set(key, entry);
|
|
84
|
+
}
|
|
85
|
+
entry.frequency++;
|
|
86
|
+
entry.sessions.add(sessionId);
|
|
87
|
+
}
|
|
88
|
+
// Check if this ngram is followed by an error within 2 events
|
|
89
|
+
// The last event of the ngram is at index i + n - 1 in sessionCalls
|
|
90
|
+
const lastCallInNgram = sessionCalls[i + n - 1];
|
|
91
|
+
if (lastCallInNgram) {
|
|
92
|
+
const isErrorFollowed = sessionErrorEvents.some((errEvt) => {
|
|
93
|
+
// Error must be after the last tool call in ngram
|
|
94
|
+
// and within 2 "event positions" (by timestamp)
|
|
95
|
+
if (errEvt.timestamp < lastCallInNgram.timestamp)
|
|
96
|
+
return false;
|
|
97
|
+
// Count how many tool_call events are between the last ngram call and the error
|
|
98
|
+
const callsAfter = sessionCalls.filter((c) => c.timestamp > lastCallInNgram.timestamp && c.timestamp <= errEvt.timestamp);
|
|
99
|
+
return callsAfter.length <= 2;
|
|
100
|
+
});
|
|
101
|
+
if (isErrorFollowed) {
|
|
102
|
+
// We only count this once per session per ngram for error rate calculation
|
|
103
|
+
// But we need to track total occurrences vs error-followed
|
|
104
|
+
let entry = ngramMap.get(key);
|
|
105
|
+
// Track on first occurrence in session
|
|
106
|
+
if (seenInSession.has(`${key}:error-checked`))
|
|
107
|
+
continue;
|
|
108
|
+
seenInSession.add(`${key}:error-checked`);
|
|
109
|
+
entry.errorFollowed++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Calculate stats
|
|
116
|
+
const sessionLengths = Array.from(sessionToolNames.values()).map((n) => n.length);
|
|
117
|
+
const avgSequenceLength = sessionLengths.length > 0
|
|
118
|
+
? sessionLengths.reduce((a, b) => a + b, 0) / sessionLengths.length
|
|
119
|
+
: 0;
|
|
120
|
+
// Build sorted results
|
|
121
|
+
const sequences = Array.from(ngramMap.values())
|
|
122
|
+
.map((entry) => ({
|
|
123
|
+
tools: entry.tools,
|
|
124
|
+
frequency: entry.frequency,
|
|
125
|
+
sessions: entry.sessions.size,
|
|
126
|
+
errorRate: entry.sessions.size > 0
|
|
127
|
+
? entry.errorFollowed / entry.sessions.size
|
|
128
|
+
: 0,
|
|
129
|
+
}))
|
|
130
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
131
|
+
.slice(0, limit);
|
|
132
|
+
return {
|
|
133
|
+
sequences,
|
|
134
|
+
stats: {
|
|
135
|
+
avgSequenceLength: Math.round(avgSequenceLength * 100) / 100,
|
|
136
|
+
uniqueTools: uniqueToolsSet.size,
|
|
137
|
+
totalCalls,
|
|
138
|
+
},
|
|
139
|
+
metadata: {
|
|
140
|
+
eventsAnalyzed,
|
|
141
|
+
timeRange,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=tool-sequences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-sequences.js","sourceRoot":"","sources":["../../../src/lib/analysis/tool-sequences.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/context/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/context/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Retriever (Story 5.2)
|
|
3
|
+
*
|
|
4
|
+
* Combines semantic search over session summaries, lesson search,
|
|
5
|
+
* and key event retrieval to build cross-session context.
|
|
6
|
+
*
|
|
7
|
+
* Falls back to text search when embeddings are unavailable.
|
|
8
|
+
*/
|
|
9
|
+
import type { ContextQuery, ContextResult } from '@agentlensai/core';
|
|
10
|
+
import type { EmbeddingStore } from '../../db/embedding-store.js';
|
|
11
|
+
import type { EmbeddingService } from '../embeddings/index.js';
|
|
12
|
+
import type { SessionSummaryStore } from '../../db/session-summary-store.js';
|
|
13
|
+
import type { LessonStore } from '../../db/lesson-store.js';
|
|
14
|
+
import type { IEventStore } from '@agentlensai/core';
|
|
15
|
+
export declare class ContextRetriever {
|
|
16
|
+
private readonly embeddingStore;
|
|
17
|
+
private readonly embeddingService;
|
|
18
|
+
private readonly sessionSummaryStore;
|
|
19
|
+
private readonly lessonStore;
|
|
20
|
+
private readonly eventStore;
|
|
21
|
+
constructor(embeddingStore: EmbeddingStore | null, embeddingService: EmbeddingService | null, sessionSummaryStore: SessionSummaryStore, lessonStore: LessonStore, eventStore: IEventStore);
|
|
22
|
+
/**
|
|
23
|
+
* Retrieve cross-session context by combining:
|
|
24
|
+
* 1. Semantic search over session summary embeddings
|
|
25
|
+
* 2. Lesson search (semantic or text-based)
|
|
26
|
+
* 3. Key events for matching sessions
|
|
27
|
+
* 4. Ranking by relevance + recency
|
|
28
|
+
*/
|
|
29
|
+
retrieve(tenantId: string, query: ContextQuery): Promise<ContextResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Find relevant sessions using semantic search (with text search fallback).
|
|
32
|
+
*/
|
|
33
|
+
private findRelevantSessions;
|
|
34
|
+
/**
|
|
35
|
+
* Filter semantic search results by agentId/userId and rank by relevance + recency.
|
|
36
|
+
*/
|
|
37
|
+
private filterAndRankSessions;
|
|
38
|
+
/**
|
|
39
|
+
* Text search fallback when embeddings are unavailable.
|
|
40
|
+
*/
|
|
41
|
+
private textSearchSessions;
|
|
42
|
+
/**
|
|
43
|
+
* Find relevant lessons using semantic search (with text search fallback).
|
|
44
|
+
*/
|
|
45
|
+
private findRelevantLessons;
|
|
46
|
+
/**
|
|
47
|
+
* Enrich a session result with key events from the timeline.
|
|
48
|
+
*/
|
|
49
|
+
private enrichSessionWithEvents;
|
|
50
|
+
/**
|
|
51
|
+
* Compute a recency boost (0-1) based on how recent the content is.
|
|
52
|
+
* Items from the last 24h get ~1.0, items from 30+ days ago get ~0.0.
|
|
53
|
+
*/
|
|
54
|
+
private computeRecencyBoost;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=retrieval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../../src/lib/context/retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAkD,MAAM,mBAAmB,CAAC;AACrH,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,mCAAmC,CAAC;AACnG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAJV,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,EACzC,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,WAAW;IAG1C;;;;;;OAMG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAsB7E;;OAEG;YACW,oBAAoB;IA6BlC;;OAEG;YACW,qBAAqB;IAwCnC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;YACW,mBAAmB;IAwDjC;;OAEG;YACW,uBAAuB;IA+CrC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;CAU5B"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Retriever (Story 5.2)
|
|
3
|
+
*
|
|
4
|
+
* Combines semantic search over session summaries, lesson search,
|
|
5
|
+
* and key event retrieval to build cross-session context.
|
|
6
|
+
*
|
|
7
|
+
* Falls back to text search when embeddings are unavailable.
|
|
8
|
+
*/
|
|
9
|
+
import { summarizeEvent } from '../embeddings/summarizer.js';
|
|
10
|
+
/** Default maximum results */
|
|
11
|
+
const DEFAULT_LIMIT = 10;
|
|
12
|
+
/** Maximum key events per session in results */
|
|
13
|
+
const MAX_KEY_EVENTS = 5;
|
|
14
|
+
export class ContextRetriever {
|
|
15
|
+
embeddingStore;
|
|
16
|
+
embeddingService;
|
|
17
|
+
sessionSummaryStore;
|
|
18
|
+
lessonStore;
|
|
19
|
+
eventStore;
|
|
20
|
+
constructor(embeddingStore, embeddingService, sessionSummaryStore, lessonStore, eventStore) {
|
|
21
|
+
this.embeddingStore = embeddingStore;
|
|
22
|
+
this.embeddingService = embeddingService;
|
|
23
|
+
this.sessionSummaryStore = sessionSummaryStore;
|
|
24
|
+
this.lessonStore = lessonStore;
|
|
25
|
+
this.eventStore = eventStore;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Retrieve cross-session context by combining:
|
|
29
|
+
* 1. Semantic search over session summary embeddings
|
|
30
|
+
* 2. Lesson search (semantic or text-based)
|
|
31
|
+
* 3. Key events for matching sessions
|
|
32
|
+
* 4. Ranking by relevance + recency
|
|
33
|
+
*/
|
|
34
|
+
async retrieve(tenantId, query) {
|
|
35
|
+
const limit = query.limit ?? DEFAULT_LIMIT;
|
|
36
|
+
// Step 1: Find relevant sessions
|
|
37
|
+
const sessionResults = await this.findRelevantSessions(tenantId, query, limit);
|
|
38
|
+
// Step 2: Find relevant lessons
|
|
39
|
+
const lessonResults = await this.findRelevantLessons(tenantId, query, limit);
|
|
40
|
+
// Step 3: For each matching session, get key events
|
|
41
|
+
const sessionsWithEvents = await Promise.all(sessionResults.map((s) => this.enrichSessionWithEvents(tenantId, s)));
|
|
42
|
+
return {
|
|
43
|
+
topic: query.topic,
|
|
44
|
+
sessions: sessionsWithEvents,
|
|
45
|
+
lessons: lessonResults,
|
|
46
|
+
totalSessions: sessionsWithEvents.length,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find relevant sessions using semantic search (with text search fallback).
|
|
51
|
+
*/
|
|
52
|
+
async findRelevantSessions(tenantId, query, limit) {
|
|
53
|
+
// Try semantic search first
|
|
54
|
+
if (this.embeddingService && this.embeddingStore) {
|
|
55
|
+
try {
|
|
56
|
+
const queryVector = await this.embeddingService.embed(query.topic);
|
|
57
|
+
const results = this.embeddingStore.similaritySearch(tenantId, queryVector, {
|
|
58
|
+
sourceType: 'session',
|
|
59
|
+
from: query.from,
|
|
60
|
+
to: query.to,
|
|
61
|
+
limit: limit * 2, // over-fetch for post-filtering
|
|
62
|
+
minScore: 0.3,
|
|
63
|
+
});
|
|
64
|
+
if (results.length > 0) {
|
|
65
|
+
return this.filterAndRankSessions(tenantId, results, query, limit);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Fall through to text search
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Fallback: text search on session summaries
|
|
73
|
+
return this.textSearchSessions(tenantId, query, limit);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Filter semantic search results by agentId/userId and rank by relevance + recency.
|
|
77
|
+
*/
|
|
78
|
+
async filterAndRankSessions(tenantId, results, query, limit) {
|
|
79
|
+
const sessions = [];
|
|
80
|
+
for (const result of results) {
|
|
81
|
+
// sourceId is the sessionId for session-scope embeddings
|
|
82
|
+
const sessionId = result.sourceId;
|
|
83
|
+
// Filter by agentId if provided
|
|
84
|
+
if (query.agentId) {
|
|
85
|
+
const session = await this.eventStore.getSession(sessionId);
|
|
86
|
+
if (!session || session.agentId !== query.agentId)
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
// Get the summary text from the store (richer than embedding text)
|
|
90
|
+
const summaryRecord = this.sessionSummaryStore.get(tenantId, sessionId);
|
|
91
|
+
const summary = summaryRecord?.summary ?? result.text;
|
|
92
|
+
// Recency boost: more recent sessions score slightly higher
|
|
93
|
+
const recencyBoost = this.computeRecencyBoost(result.createdAt);
|
|
94
|
+
const adjustedScore = result.score * 0.85 + recencyBoost * 0.15;
|
|
95
|
+
sessions.push({
|
|
96
|
+
sessionId,
|
|
97
|
+
summary,
|
|
98
|
+
relevanceScore: Math.round(adjustedScore * 10000) / 10000,
|
|
99
|
+
});
|
|
100
|
+
if (sessions.length >= limit)
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
// Sort by adjusted score descending
|
|
104
|
+
sessions.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
105
|
+
return sessions.slice(0, limit);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Text search fallback when embeddings are unavailable.
|
|
109
|
+
*/
|
|
110
|
+
textSearchSessions(tenantId, query, limit) {
|
|
111
|
+
const results = this.sessionSummaryStore.search(tenantId, query.topic, limit * 2);
|
|
112
|
+
let filtered = results;
|
|
113
|
+
// If agentId filter is needed, we need to cross-reference sessions
|
|
114
|
+
// For text search, we can't easily filter by agentId synchronously here,
|
|
115
|
+
// so we'll skip that filter for the text fallback (best effort)
|
|
116
|
+
return filtered.slice(0, limit).map((r, index) => ({
|
|
117
|
+
sessionId: r.sessionId,
|
|
118
|
+
summary: r.summary,
|
|
119
|
+
// Assign a decreasing relevance score for text search results (1.0 → 0.5)
|
|
120
|
+
relevanceScore: Math.round((1.0 - index * (0.5 / Math.max(limit, 1))) * 10000) / 10000,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Find relevant lessons using semantic search (with text search fallback).
|
|
125
|
+
*/
|
|
126
|
+
async findRelevantLessons(tenantId, query, limit) {
|
|
127
|
+
// Try semantic search first
|
|
128
|
+
if (this.embeddingService && this.embeddingStore) {
|
|
129
|
+
try {
|
|
130
|
+
const queryVector = await this.embeddingService.embed(query.topic);
|
|
131
|
+
const results = this.embeddingStore.similaritySearch(tenantId, queryVector, {
|
|
132
|
+
sourceType: 'lesson',
|
|
133
|
+
limit,
|
|
134
|
+
minScore: 0.3,
|
|
135
|
+
});
|
|
136
|
+
if (results.length > 0) {
|
|
137
|
+
const lessons = [];
|
|
138
|
+
for (const result of results) {
|
|
139
|
+
const lesson = this.lessonStore.get(tenantId, result.sourceId);
|
|
140
|
+
if (lesson) {
|
|
141
|
+
lessons.push({
|
|
142
|
+
id: lesson.id,
|
|
143
|
+
title: lesson.title,
|
|
144
|
+
content: lesson.content,
|
|
145
|
+
category: lesson.category,
|
|
146
|
+
importance: lesson.importance,
|
|
147
|
+
relevanceScore: Math.round(result.score * 10000) / 10000,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return lessons;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Fall through to text search
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Fallback: text search on lessons
|
|
159
|
+
const textResults = this.lessonStore.list(tenantId, {
|
|
160
|
+
search: query.topic,
|
|
161
|
+
limit,
|
|
162
|
+
});
|
|
163
|
+
return textResults.map((lesson, index) => ({
|
|
164
|
+
id: lesson.id,
|
|
165
|
+
title: lesson.title,
|
|
166
|
+
content: lesson.content,
|
|
167
|
+
category: lesson.category,
|
|
168
|
+
importance: lesson.importance,
|
|
169
|
+
// Assign decreasing scores for text search results
|
|
170
|
+
relevanceScore: Math.round((1.0 - index * (0.5 / Math.max(limit, 1))) * 10000) / 10000,
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Enrich a session result with key events from the timeline.
|
|
175
|
+
*/
|
|
176
|
+
async enrichSessionWithEvents(tenantId, session) {
|
|
177
|
+
// Get session metadata for startedAt/endedAt/agentId
|
|
178
|
+
const sessionRecord = await this.eventStore.getSession(session.sessionId);
|
|
179
|
+
// Get timeline events for key event extraction
|
|
180
|
+
let keyEvents = [];
|
|
181
|
+
try {
|
|
182
|
+
const timeline = await this.eventStore.getSessionTimeline(session.sessionId);
|
|
183
|
+
// Extract key events: errors, tool calls, session boundaries
|
|
184
|
+
const significant = timeline.filter((e) => e.eventType === 'tool_error' ||
|
|
185
|
+
e.eventType === 'tool_call' ||
|
|
186
|
+
e.eventType === 'session_started' ||
|
|
187
|
+
e.eventType === 'session_ended' ||
|
|
188
|
+
e.severity === 'error' ||
|
|
189
|
+
e.severity === 'critical');
|
|
190
|
+
keyEvents = significant.slice(0, MAX_KEY_EVENTS).map((e) => {
|
|
191
|
+
const eventSummary = summarizeEvent(e) ?? `${e.eventType}`;
|
|
192
|
+
return {
|
|
193
|
+
id: e.id,
|
|
194
|
+
eventType: e.eventType,
|
|
195
|
+
summary: eventSummary,
|
|
196
|
+
timestamp: e.timestamp,
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Non-critical — return session without events
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
sessionId: session.sessionId,
|
|
205
|
+
agentId: sessionRecord?.agentId ?? '',
|
|
206
|
+
summary: session.summary,
|
|
207
|
+
relevanceScore: session.relevanceScore,
|
|
208
|
+
startedAt: sessionRecord?.startedAt ?? '',
|
|
209
|
+
endedAt: sessionRecord?.endedAt,
|
|
210
|
+
keyEvents,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Compute a recency boost (0-1) based on how recent the content is.
|
|
215
|
+
* Items from the last 24h get ~1.0, items from 30+ days ago get ~0.0.
|
|
216
|
+
*/
|
|
217
|
+
computeRecencyBoost(createdAt) {
|
|
218
|
+
const now = Date.now();
|
|
219
|
+
const created = new Date(createdAt).getTime();
|
|
220
|
+
const ageMs = now - created;
|
|
221
|
+
const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;
|
|
222
|
+
if (ageMs <= 0)
|
|
223
|
+
return 1.0;
|
|
224
|
+
if (ageMs >= thirtyDaysMs)
|
|
225
|
+
return 0.0;
|
|
226
|
+
return 1.0 - ageMs / thirtyDaysMs;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=retrieval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.js","sourceRoot":"","sources":["../../../src/lib/context/retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Service — interface and factory (Story 2.1)
|
|
3
|
+
*
|
|
4
|
+
* Supports local (Xenova/transformers.js ONNX) and OpenAI backends.
|
|
5
|
+
*/
|
|
6
|
+
import type { EmbeddingServiceConfig } from './types.js';
|
|
7
|
+
export type { EmbeddingVector, EmbeddingBackend, EmbeddingServiceConfig } from './types.js';
|
|
8
|
+
export { cosineSimilarity } from './math.js';
|
|
9
|
+
/**
|
|
10
|
+
* Embedding service interface — embed text into vector space.
|
|
11
|
+
*/
|
|
12
|
+
export interface EmbeddingService {
|
|
13
|
+
/** Embed a single text string */
|
|
14
|
+
embed(text: string): Promise<Float32Array>;
|
|
15
|
+
/** Embed a batch of texts */
|
|
16
|
+
embedBatch(texts: string[]): Promise<Float32Array[]>;
|
|
17
|
+
/** Dimensionality of the output vectors */
|
|
18
|
+
readonly dimensions: number;
|
|
19
|
+
/** Name of the model used */
|
|
20
|
+
readonly modelName: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create an embedding service from config or environment variables.
|
|
24
|
+
*
|
|
25
|
+
* Environment variables:
|
|
26
|
+
* - AGENTLENS_EMBEDDING_BACKEND: 'local' | 'openai' (default: 'local')
|
|
27
|
+
* - AGENTLENS_EMBEDDING_MODEL: model name override
|
|
28
|
+
* - OPENAI_API_KEY: required for 'openai' backend
|
|
29
|
+
*/
|
|
30
|
+
export declare function createEmbeddingService(config?: Partial<EmbeddingServiceConfig>): EmbeddingService;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/embeddings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAIzD,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAE3C,6BAA6B;IAC7B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAErD,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,gBAAgB,CAgBjG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Service — interface and factory (Story 2.1)
|
|
3
|
+
*
|
|
4
|
+
* Supports local (Xenova/transformers.js ONNX) and OpenAI backends.
|
|
5
|
+
*/
|
|
6
|
+
import { createLocalEmbeddingService } from './local.js';
|
|
7
|
+
import { createOpenAIEmbeddingService } from './openai.js';
|
|
8
|
+
export { cosineSimilarity } from './math.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create an embedding service from config or environment variables.
|
|
11
|
+
*
|
|
12
|
+
* Environment variables:
|
|
13
|
+
* - AGENTLENS_EMBEDDING_BACKEND: 'local' | 'openai' (default: 'local')
|
|
14
|
+
* - AGENTLENS_EMBEDDING_MODEL: model name override
|
|
15
|
+
* - OPENAI_API_KEY: required for 'openai' backend
|
|
16
|
+
*/
|
|
17
|
+
export function createEmbeddingService(config) {
|
|
18
|
+
const backend = config?.backend ??
|
|
19
|
+
process.env['AGENTLENS_EMBEDDING_BACKEND'] ??
|
|
20
|
+
'local';
|
|
21
|
+
const modelName = config?.modelName ?? process.env['AGENTLENS_EMBEDDING_MODEL'];
|
|
22
|
+
switch (backend) {
|
|
23
|
+
case 'local':
|
|
24
|
+
return createLocalEmbeddingService(modelName);
|
|
25
|
+
case 'openai':
|
|
26
|
+
return createOpenAIEmbeddingService(config?.openaiApiKey, modelName);
|
|
27
|
+
default:
|
|
28
|
+
throw new Error(`Unknown embedding backend: ${backend}. Use 'local' or 'openai'.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/embeddings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAmB7C;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAwC;IAC7E,MAAM,OAAO,GACX,MAAM,EAAE,OAAO;QACd,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAoC;QAC9E,OAAO,CAAC;IAEV,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEhF,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,2BAA2B,CAAC,SAAS,CAAC,CAAC;QAChD,KAAK,QAAQ;YACX,OAAO,4BAA4B,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QACvE;YACE,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAiB,4BAA4B,CAAC,CAAC;IACjG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local embedding service using @xenova/transformers (ONNX) (Story 2.1)
|
|
3
|
+
*
|
|
4
|
+
* Uses all-MiniLM-L6-v2 model (384 dimensions) by default.
|
|
5
|
+
* Model is loaded once and cached for subsequent calls.
|
|
6
|
+
*/
|
|
7
|
+
import type { EmbeddingService } from './index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a local embedding service backed by @xenova/transformers.
|
|
10
|
+
*
|
|
11
|
+
* The @xenova/transformers package is dynamically imported, so it's
|
|
12
|
+
* not a hard dependency. If not installed, a clear error is thrown.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createLocalEmbeddingService(modelName?: string): EmbeddingService;
|
|
15
|
+
//# sourceMappingURL=local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/lib/embeddings/local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKnD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAwDhF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local embedding service using @xenova/transformers (ONNX) (Story 2.1)
|
|
3
|
+
*
|
|
4
|
+
* Uses all-MiniLM-L6-v2 model (384 dimensions) by default.
|
|
5
|
+
* Model is loaded once and cached for subsequent calls.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_MODEL = 'Xenova/all-MiniLM-L6-v2';
|
|
8
|
+
const DEFAULT_DIMENSIONS = 384;
|
|
9
|
+
/**
|
|
10
|
+
* Create a local embedding service backed by @xenova/transformers.
|
|
11
|
+
*
|
|
12
|
+
* The @xenova/transformers package is dynamically imported, so it's
|
|
13
|
+
* not a hard dependency. If not installed, a clear error is thrown.
|
|
14
|
+
*/
|
|
15
|
+
export function createLocalEmbeddingService(modelName) {
|
|
16
|
+
const model = modelName ?? DEFAULT_MODEL;
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
let pipelinePromise = null;
|
|
19
|
+
async function getPipeline() {
|
|
20
|
+
if (!pipelinePromise) {
|
|
21
|
+
pipelinePromise = (async () => {
|
|
22
|
+
try {
|
|
23
|
+
// Dynamic import — @xenova/transformers may not be installed
|
|
24
|
+
// Use a variable to prevent TypeScript from resolving the module at compile time
|
|
25
|
+
const moduleName = '@xenova/transformers';
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
const mod = await Function('m', 'return import(m)')(moduleName);
|
|
28
|
+
const { pipeline } = mod;
|
|
29
|
+
return await pipeline('feature-extraction', model);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
pipelinePromise = null; // Reset so user can retry after install
|
|
33
|
+
if (err instanceof Error &&
|
|
34
|
+
(err.message.includes('Cannot find module') ||
|
|
35
|
+
err.message.includes('Cannot find package') ||
|
|
36
|
+
err.message.includes('ERR_MODULE_NOT_FOUND'))) {
|
|
37
|
+
throw new Error('Local embedding backend requires @xenova/transformers. ' +
|
|
38
|
+
'Install it with: pnpm add @xenova/transformers');
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
})();
|
|
43
|
+
}
|
|
44
|
+
return pipelinePromise;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
dimensions: DEFAULT_DIMENSIONS,
|
|
48
|
+
modelName: model,
|
|
49
|
+
async embed(text) {
|
|
50
|
+
const pipe = await getPipeline();
|
|
51
|
+
const output = await pipe(text, { pooling: 'mean', normalize: true });
|
|
52
|
+
return new Float32Array(output.data);
|
|
53
|
+
},
|
|
54
|
+
async embedBatch(texts) {
|
|
55
|
+
const pipe = await getPipeline();
|
|
56
|
+
const results = [];
|
|
57
|
+
for (const text of texts) {
|
|
58
|
+
const output = await pipe(text, { pooling: 'mean', normalize: true });
|
|
59
|
+
results.push(new Float32Array(output.data));
|
|
60
|
+
}
|
|
61
|
+
return results;
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../src/lib/embeddings/local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAAkB;IAC5D,MAAM,KAAK,GAAG,SAAS,IAAI,aAAa,CAAC;IACzC,8DAA8D;IAC9D,IAAI,eAAe,GAAwB,IAAI,CAAC;IAEhD,KAAK,UAAU,WAAW;QACxB,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,eAAe,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC5B,IAAI,CAAC;oBACH,6DAA6D;oBAC7D,iFAAiF;oBACjF,MAAM,UAAU,GAAG,sBAAsB,CAAC;oBAC1C,8DAA8D;oBAC9D,MAAM,GAAG,GAAG,MAAO,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAiC,CAAC,UAAU,CAAC,CAAC;oBACjG,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;oBACzB,OAAO,MAAM,QAAQ,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;gBACrD,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACtB,eAAe,GAAG,IAAI,CAAC,CAAC,wCAAwC;oBAChE,IACE,GAAG,YAAY,KAAK;wBACpB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;4BACzC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;4BAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,EAC/C,CAAC;wBACD,MAAM,IAAI,KAAK,CACb,yDAAyD;4BACvD,gDAAgD,CACnD,CAAC;oBACJ,CAAC;oBACD,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO;QACL,UAAU,EAAE,kBAAkB;QAC9B,SAAS,EAAE,KAAK;QAEhB,KAAK,CAAC,KAAK,CAAC,IAAY;YACtB,MAAM,IAAI,GAAG,MAAM,WAAW,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtE,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,KAAe;YAC9B,MAAM,IAAI,GAAG,MAAM,WAAW,EAAE,CAAC;YACjC,MAAM,OAAO,GAAmB,EAAE,CAAC;YACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtE,OAAO,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
|