@memograph/cli 0.1.4
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/LICENSE +21 -0
- package/README.md +402 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +97 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/detect.d.ts +30 -0
- package/dist/core/detect.d.ts.map +1 -0
- package/dist/core/detect.js +212 -0
- package/dist/core/detect.js.map +1 -0
- package/dist/core/extract.d.ts +6 -0
- package/dist/core/extract.d.ts.map +1 -0
- package/dist/core/extract.js +104 -0
- package/dist/core/extract.js.map +1 -0
- package/dist/core/inspect.d.ts +7 -0
- package/dist/core/inspect.d.ts.map +1 -0
- package/dist/core/inspect.js +98 -0
- package/dist/core/inspect.js.map +1 -0
- package/dist/core/llm/client.d.ts +55 -0
- package/dist/core/llm/client.d.ts.map +1 -0
- package/dist/core/llm/client.js +199 -0
- package/dist/core/llm/client.js.map +1 -0
- package/dist/core/llm/detect-llm.d.ts +28 -0
- package/dist/core/llm/detect-llm.d.ts.map +1 -0
- package/dist/core/llm/detect-llm.js +212 -0
- package/dist/core/llm/detect-llm.js.map +1 -0
- package/dist/core/llm/extract-llm.d.ts +27 -0
- package/dist/core/llm/extract-llm.d.ts.map +1 -0
- package/dist/core/llm/extract-llm.js +151 -0
- package/dist/core/llm/extract-llm.js.map +1 -0
- package/dist/core/llm/prompts.d.ts +28 -0
- package/dist/core/llm/prompts.d.ts.map +1 -0
- package/dist/core/llm/prompts.js +172 -0
- package/dist/core/llm/prompts.js.map +1 -0
- package/dist/core/llm/providers.d.ts +34 -0
- package/dist/core/llm/providers.d.ts.map +1 -0
- package/dist/core/llm/providers.js +169 -0
- package/dist/core/llm/providers.js.map +1 -0
- package/dist/core/load.d.ts +10 -0
- package/dist/core/load.d.ts.map +1 -0
- package/dist/core/load.js +106 -0
- package/dist/core/load.js.map +1 -0
- package/dist/core/normalize.d.ts +30 -0
- package/dist/core/normalize.d.ts.map +1 -0
- package/dist/core/normalize.js +63 -0
- package/dist/core/normalize.js.map +1 -0
- package/dist/core/render.d.ts +10 -0
- package/dist/core/render.d.ts.map +1 -0
- package/dist/core/render.js +60 -0
- package/dist/core/render.js.map +1 -0
- package/dist/core/score.d.ts +27 -0
- package/dist/core/score.d.ts.map +1 -0
- package/dist/core/score.js +59 -0
- package/dist/core/score.js.map +1 -0
- package/dist/core/types.d.ts +162 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/interactive/index.d.ts +67 -0
- package/dist/interactive/index.d.ts.map +1 -0
- package/dist/interactive/index.js +794 -0
- package/dist/interactive/index.js.map +1 -0
- package/dist/interactive/settings.d.ts +36 -0
- package/dist/interactive/settings.d.ts.map +1 -0
- package/dist/interactive/settings.js +174 -0
- package/dist/interactive/settings.js.map +1 -0
- package/dist/interactive/wizard.d.ts +10 -0
- package/dist/interactive/wizard.d.ts.map +1 -0
- package/dist/interactive/wizard.js +249 -0
- package/dist/interactive/wizard.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectRepetitionClusters = detectRepetitionClusters;
|
|
4
|
+
exports.detectSessionReset = detectSessionReset;
|
|
5
|
+
exports.detectPreferenceForgotten = detectPreferenceForgotten;
|
|
6
|
+
exports.detectContradictions = detectContradictions;
|
|
7
|
+
const normalize_js_1 = require("./normalize.js");
|
|
8
|
+
/**
|
|
9
|
+
* Detect repetition clusters in user messages
|
|
10
|
+
*/
|
|
11
|
+
function detectRepetitionClusters(messages, similarityThreshold = 0.65) {
|
|
12
|
+
const start = performance.now();
|
|
13
|
+
const userMessages = messages.filter(m => m.role === 'user');
|
|
14
|
+
if (userMessages.length < 2) {
|
|
15
|
+
return { events: [], timing_ms: performance.now() - start };
|
|
16
|
+
}
|
|
17
|
+
// Bucket messages by signature for O(n) complexity
|
|
18
|
+
const buckets = new Map();
|
|
19
|
+
for (const msg of userMessages) {
|
|
20
|
+
const normalized = (0, normalize_js_1.normalizeText)(msg.content);
|
|
21
|
+
const tokens = (0, normalize_js_1.tokenize)(normalized);
|
|
22
|
+
const signature = (0, normalize_js_1.makeSignature)(tokens);
|
|
23
|
+
if (!buckets.has(signature)) {
|
|
24
|
+
buckets.set(signature, []);
|
|
25
|
+
}
|
|
26
|
+
buckets.get(signature).push({ msg, tokens });
|
|
27
|
+
}
|
|
28
|
+
// Find clusters within each bucket
|
|
29
|
+
const clusters = [];
|
|
30
|
+
for (const bucket of buckets.values()) {
|
|
31
|
+
if (bucket.length < 2) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
// Find similar messages within bucket
|
|
35
|
+
const visited = new Set();
|
|
36
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
37
|
+
if (visited.has(i))
|
|
38
|
+
continue;
|
|
39
|
+
const cluster = [bucket[i]];
|
|
40
|
+
visited.add(i);
|
|
41
|
+
for (let j = i + 1; j < bucket.length; j++) {
|
|
42
|
+
if (visited.has(j))
|
|
43
|
+
continue;
|
|
44
|
+
const sim = (0, normalize_js_1.jaccardSimilarity)(new Set(bucket[i].tokens), new Set(bucket[j].tokens));
|
|
45
|
+
if (sim >= similarityThreshold) {
|
|
46
|
+
cluster.push(bucket[j]);
|
|
47
|
+
visited.add(j);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (cluster.length >= 2) {
|
|
51
|
+
// Create event for this cluster
|
|
52
|
+
const msgIndices = cluster.map(c => c.msg.idx);
|
|
53
|
+
const snippets = cluster.map(c => c.msg.content.substring(0, 50));
|
|
54
|
+
const avgSimilarity = calculateAverageSimilarity(cluster.map(c => c.tokens));
|
|
55
|
+
clusters.push({
|
|
56
|
+
type: 'repetition_cluster',
|
|
57
|
+
severity: Math.min(cluster.length - 1, 5),
|
|
58
|
+
confidence: avgSimilarity,
|
|
59
|
+
cluster_size: cluster.length,
|
|
60
|
+
evidence: {
|
|
61
|
+
msg_idxs: msgIndices,
|
|
62
|
+
snippets,
|
|
63
|
+
},
|
|
64
|
+
summary: `User repeated a similar request ${cluster.length} times.`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Sort by cluster size (largest first)
|
|
70
|
+
clusters.sort((a, b) => b.cluster_size - a.cluster_size);
|
|
71
|
+
const timing_ms = performance.now() - start;
|
|
72
|
+
return { events: clusters, timing_ms };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Calculate average pairwise similarity in a cluster
|
|
76
|
+
*/
|
|
77
|
+
function calculateAverageSimilarity(tokenSets) {
|
|
78
|
+
if (tokenSets.length < 2)
|
|
79
|
+
return 1.0;
|
|
80
|
+
let totalSim = 0;
|
|
81
|
+
let count = 0;
|
|
82
|
+
for (let i = 0; i < tokenSets.length; i++) {
|
|
83
|
+
for (let j = i + 1; j < tokenSets.length; j++) {
|
|
84
|
+
totalSim += (0, normalize_js_1.jaccardSimilarity)(new Set(tokenSets[i]), new Set(tokenSets[j]));
|
|
85
|
+
count++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return count > 0 ? totalSim / count : 1.0;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Detect session reset signals in assistant messages
|
|
92
|
+
*/
|
|
93
|
+
function detectSessionReset(messages) {
|
|
94
|
+
const start = performance.now();
|
|
95
|
+
const resetPatterns = [
|
|
96
|
+
'new chat',
|
|
97
|
+
'start over',
|
|
98
|
+
"let's start over",
|
|
99
|
+
'from scratch',
|
|
100
|
+
'forget everything',
|
|
101
|
+
'reset',
|
|
102
|
+
'beginning again',
|
|
103
|
+
];
|
|
104
|
+
const events = [];
|
|
105
|
+
const assistantMessages = messages.filter(m => m.role === 'assistant');
|
|
106
|
+
for (const msg of assistantMessages) {
|
|
107
|
+
const content = msg.content.toLowerCase();
|
|
108
|
+
for (const pattern of resetPatterns) {
|
|
109
|
+
if (content.includes(pattern)) {
|
|
110
|
+
events.push({
|
|
111
|
+
type: 'session_reset',
|
|
112
|
+
severity: 5,
|
|
113
|
+
confidence: 0.9,
|
|
114
|
+
reset_phrase: pattern,
|
|
115
|
+
evidence: {
|
|
116
|
+
msg_idxs: [msg.idx],
|
|
117
|
+
snippets: [msg.content.substring(0, 100)],
|
|
118
|
+
},
|
|
119
|
+
summary: `Assistant indicated session reset: "${pattern}"`,
|
|
120
|
+
});
|
|
121
|
+
break; // Only one event per message
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const timing_ms = performance.now() - start;
|
|
126
|
+
return { events, timing_ms };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Detect when user restates preferences (suggesting they were forgotten)
|
|
130
|
+
*/
|
|
131
|
+
function detectPreferenceForgotten(messages, facts, gapThreshold = 5) {
|
|
132
|
+
const start = performance.now();
|
|
133
|
+
// Group preference facts by (key, value)
|
|
134
|
+
const prefGroups = new Map();
|
|
135
|
+
for (const fact of facts) {
|
|
136
|
+
// Only look at preference facts
|
|
137
|
+
if (!fact.fact_key.startsWith('pref:')) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const key = `${fact.fact_key}:${fact.fact_value}`;
|
|
141
|
+
if (!prefGroups.has(key)) {
|
|
142
|
+
prefGroups.set(key, []);
|
|
143
|
+
}
|
|
144
|
+
prefGroups.get(key).push(fact);
|
|
145
|
+
}
|
|
146
|
+
const events = [];
|
|
147
|
+
// Check each preference group
|
|
148
|
+
for (const [key, group] of prefGroups.entries()) {
|
|
149
|
+
if (group.length < 2) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Sort by message index
|
|
153
|
+
group.sort((a, b) => a.msg_idx - b.msg_idx);
|
|
154
|
+
// Check gap between first and last occurrence
|
|
155
|
+
const firstIdx = group[0].msg_idx;
|
|
156
|
+
const lastIdx = group[group.length - 1].msg_idx;
|
|
157
|
+
const gap = lastIdx - firstIdx;
|
|
158
|
+
if (gap >= gapThreshold) {
|
|
159
|
+
// User had to restate the preference
|
|
160
|
+
const [factKey, factValue] = key.split(':').slice(0, 2);
|
|
161
|
+
events.push({
|
|
162
|
+
type: 'preference_forgotten',
|
|
163
|
+
severity: 4,
|
|
164
|
+
confidence: 0.65,
|
|
165
|
+
preference_key: factKey,
|
|
166
|
+
preference_value: factValue,
|
|
167
|
+
evidence: {
|
|
168
|
+
msg_idxs: group.map(f => f.msg_idx),
|
|
169
|
+
snippets: group.map(f => messages[f.msg_idx]?.content.substring(0, 50) || ''),
|
|
170
|
+
fact_key: group[0].fact_key,
|
|
171
|
+
},
|
|
172
|
+
summary: `User restated ${factKey}=${factValue} later, suggesting the assistant didn't retain it.`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const timing_ms = performance.now() - start;
|
|
177
|
+
return { events, timing_ms };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Detect contradictions in extracted facts
|
|
181
|
+
*/
|
|
182
|
+
function detectContradictions(facts) {
|
|
183
|
+
const start = performance.now();
|
|
184
|
+
// Track last seen value for each fact key
|
|
185
|
+
const lastSeen = new Map();
|
|
186
|
+
const events = [];
|
|
187
|
+
// Sort facts by message index
|
|
188
|
+
const sortedFacts = [...facts].sort((a, b) => a.msg_idx - b.msg_idx);
|
|
189
|
+
for (const fact of sortedFacts) {
|
|
190
|
+
const previous = lastSeen.get(fact.fact_key);
|
|
191
|
+
if (previous && previous.fact_value !== fact.fact_value) {
|
|
192
|
+
// Contradiction detected
|
|
193
|
+
events.push({
|
|
194
|
+
type: 'contradiction',
|
|
195
|
+
severity: 3,
|
|
196
|
+
confidence: Math.min(previous.confidence, fact.confidence),
|
|
197
|
+
old_value: previous.fact_value,
|
|
198
|
+
new_value: fact.fact_value,
|
|
199
|
+
evidence: {
|
|
200
|
+
msg_idxs: [previous.msg_idx, fact.msg_idx],
|
|
201
|
+
snippets: [`Old: ${previous.fact_value}`, `New: ${fact.fact_value}`],
|
|
202
|
+
fact_key: fact.fact_key,
|
|
203
|
+
},
|
|
204
|
+
summary: `${fact.fact_key} changed from "${previous.fact_value}" to "${fact.fact_value}"`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
lastSeen.set(fact.fact_key, fact);
|
|
208
|
+
}
|
|
209
|
+
const timing_ms = performance.now() - start;
|
|
210
|
+
return { events, timing_ms };
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/core/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/core/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAgB3E"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractFacts = extractFacts;
|
|
4
|
+
/**
|
|
5
|
+
* Extract facts from transcript messages
|
|
6
|
+
*/
|
|
7
|
+
function extractFacts(messages) {
|
|
8
|
+
const facts = [];
|
|
9
|
+
for (const msg of messages) {
|
|
10
|
+
// Only extract from user messages
|
|
11
|
+
if (msg.role !== 'user') {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
// Apply all extraction rules
|
|
15
|
+
facts.push(...extractIdentityFacts(msg));
|
|
16
|
+
facts.push(...extractLanguagePreference(msg));
|
|
17
|
+
facts.push(...extractTonePreference(msg));
|
|
18
|
+
}
|
|
19
|
+
return facts;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extract identity facts (name, etc.)
|
|
23
|
+
*/
|
|
24
|
+
function extractIdentityFacts(msg) {
|
|
25
|
+
const facts = [];
|
|
26
|
+
const content = msg.content.toLowerCase();
|
|
27
|
+
// Pattern: "my name is X"
|
|
28
|
+
const namePattern1 = /my\s+name\s+is\s+([a-z]+)/i;
|
|
29
|
+
const match1 = msg.content.match(namePattern1);
|
|
30
|
+
if (match1) {
|
|
31
|
+
facts.push({
|
|
32
|
+
fact_key: 'identity:name',
|
|
33
|
+
fact_value: match1[1].toLowerCase(),
|
|
34
|
+
msg_idx: msg.idx,
|
|
35
|
+
confidence: 0.9,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// Pattern: "I'm X" or "I am X" (simple single-word name)
|
|
39
|
+
const namePattern2 = /\b(?:i'?m|i\s+am)\s+([a-z]+)\b/i;
|
|
40
|
+
const match2 = msg.content.match(namePattern2);
|
|
41
|
+
if (match2 && !facts.some(f => f.fact_key === 'identity:name')) {
|
|
42
|
+
// Only add if not already found (prioritize "my name is")
|
|
43
|
+
facts.push({
|
|
44
|
+
fact_key: 'identity:name',
|
|
45
|
+
fact_value: match2[1].toLowerCase(),
|
|
46
|
+
msg_idx: msg.idx,
|
|
47
|
+
confidence: 0.85,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return facts;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract language preference
|
|
54
|
+
*/
|
|
55
|
+
function extractLanguagePreference(msg) {
|
|
56
|
+
const facts = [];
|
|
57
|
+
// Patterns for language preference
|
|
58
|
+
const patterns = [
|
|
59
|
+
/reply\s+in\s+([a-z]+)/i,
|
|
60
|
+
/use\s+([a-z]+)\s+language/i,
|
|
61
|
+
/please\s+use\s+([a-z]+)/i,
|
|
62
|
+
/speak\s+in\s+([a-z]+)/i,
|
|
63
|
+
/respond\s+in\s+([a-z]+)/i,
|
|
64
|
+
];
|
|
65
|
+
for (const pattern of patterns) {
|
|
66
|
+
const match = msg.content.match(pattern);
|
|
67
|
+
if (match) {
|
|
68
|
+
facts.push({
|
|
69
|
+
fact_key: 'pref:language',
|
|
70
|
+
fact_value: match[1].toLowerCase(),
|
|
71
|
+
msg_idx: msg.idx,
|
|
72
|
+
confidence: 0.7,
|
|
73
|
+
});
|
|
74
|
+
break; // Only extract once per message
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return facts;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Extract tone/style preference
|
|
81
|
+
*/
|
|
82
|
+
function extractTonePreference(msg) {
|
|
83
|
+
const facts = [];
|
|
84
|
+
const content = msg.content.toLowerCase();
|
|
85
|
+
// Tone indicators
|
|
86
|
+
const tonePatterns = [
|
|
87
|
+
{ pattern: /\b(?:be|use)\s+(formal|casual|professional|friendly)\b/i, conf: 0.7 },
|
|
88
|
+
{ pattern: /\b(formal|casual|professional|friendly)\s+tone/i, conf: 0.75 },
|
|
89
|
+
];
|
|
90
|
+
for (const { pattern, conf } of tonePatterns) {
|
|
91
|
+
const match = msg.content.match(pattern);
|
|
92
|
+
if (match) {
|
|
93
|
+
facts.push({
|
|
94
|
+
fact_key: 'pref:tone',
|
|
95
|
+
fact_value: match[1].toLowerCase(),
|
|
96
|
+
msg_idx: msg.idx,
|
|
97
|
+
confidence: conf,
|
|
98
|
+
});
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return facts;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/core/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Transcript, InspectResult, InspectConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Main inspection pipeline (LLM-based)
|
|
4
|
+
* Uses AI models for semantic understanding of drift patterns
|
|
5
|
+
*/
|
|
6
|
+
export declare function inspectTranscript(transcript: Transcript, config?: InspectConfig): Promise<InspectResult>;
|
|
7
|
+
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/core/inspect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAW,MAAM,YAAY,CAAC;AAM/E;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,UAAU,EACtB,MAAM,GAAE,aAAkB,GACzB,OAAO,CAAC,aAAa,CAAC,CA+FxB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inspectTranscript = inspectTranscript;
|
|
4
|
+
const score_js_1 = require("./score.js");
|
|
5
|
+
const client_js_1 = require("./llm/client.js");
|
|
6
|
+
const extract_llm_js_1 = require("./llm/extract-llm.js");
|
|
7
|
+
const detect_llm_js_1 = require("./llm/detect-llm.js");
|
|
8
|
+
/**
|
|
9
|
+
* Main inspection pipeline (LLM-based)
|
|
10
|
+
* Uses AI models for semantic understanding of drift patterns
|
|
11
|
+
*/
|
|
12
|
+
async function inspectTranscript(transcript, config = {}) {
|
|
13
|
+
const { messages } = transcript;
|
|
14
|
+
const rawText = transcript.raw_text;
|
|
15
|
+
// Cap messages if configured
|
|
16
|
+
const cappedMessages = config.max_messages
|
|
17
|
+
? messages.slice(0, config.max_messages)
|
|
18
|
+
: messages;
|
|
19
|
+
// Create LLM client
|
|
20
|
+
const llmConfig = config.llm || {};
|
|
21
|
+
const llmClient = (0, client_js_1.createLLMClient)(llmConfig);
|
|
22
|
+
// Phase 1: Extract facts using LLM
|
|
23
|
+
const factStart = performance.now();
|
|
24
|
+
let extractResult;
|
|
25
|
+
// Use batching for large transcripts
|
|
26
|
+
if (rawText) {
|
|
27
|
+
extractResult = await (0, extract_llm_js_1.extractFactsLLMFromRaw)(rawText, llmClient);
|
|
28
|
+
}
|
|
29
|
+
else if (cappedMessages.length > 50) {
|
|
30
|
+
extractResult = await (0, extract_llm_js_1.extractFactsLLMBatched)(cappedMessages, llmClient);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
extractResult = await (0, extract_llm_js_1.extractFactsLLM)(cappedMessages, llmClient);
|
|
34
|
+
}
|
|
35
|
+
const facts = extractResult.facts;
|
|
36
|
+
const extractTiming = performance.now() - factStart;
|
|
37
|
+
// Phase 2: Detect drift using LLM
|
|
38
|
+
const driftStart = performance.now();
|
|
39
|
+
let driftResult;
|
|
40
|
+
// Use batching for large transcripts
|
|
41
|
+
if (rawText) {
|
|
42
|
+
driftResult = await (0, detect_llm_js_1.detectDriftLLMFromRaw)(rawText, facts, llmClient);
|
|
43
|
+
}
|
|
44
|
+
else if (cappedMessages.length > 100) {
|
|
45
|
+
driftResult = await (0, detect_llm_js_1.detectDriftLLMBatched)(cappedMessages, facts, llmClient);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
driftResult = await (0, detect_llm_js_1.detectDriftLLM)(cappedMessages, facts, llmClient);
|
|
49
|
+
}
|
|
50
|
+
const events = driftResult.events;
|
|
51
|
+
const driftTiming = performance.now() - driftStart;
|
|
52
|
+
// Sort events by severity (descending), then by confidence (descending)
|
|
53
|
+
events.sort((a, b) => {
|
|
54
|
+
if (a.severity !== b.severity) {
|
|
55
|
+
return b.severity - a.severity;
|
|
56
|
+
}
|
|
57
|
+
return b.confidence - a.confidence;
|
|
58
|
+
});
|
|
59
|
+
// Phase 3: Calculate scores
|
|
60
|
+
// Prefer LLM-provided drift score, fallback to calculated score
|
|
61
|
+
let drift_score;
|
|
62
|
+
let raw_score;
|
|
63
|
+
if (driftResult.drift_score !== undefined) {
|
|
64
|
+
// Use LLM's assessment
|
|
65
|
+
drift_score = Math.round(driftResult.drift_score);
|
|
66
|
+
raw_score = driftResult.drift_score;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Fallback to calculated score from events
|
|
70
|
+
const calculated = (0, score_js_1.calculateDriftScore)(events);
|
|
71
|
+
drift_score = calculated.drift_score;
|
|
72
|
+
raw_score = calculated.raw_score;
|
|
73
|
+
}
|
|
74
|
+
const token_waste_pct = rawText ? 0 : (0, score_js_1.calculateTokenWaste)(cappedMessages, events);
|
|
75
|
+
// Prepare "should have been memory" facts (top by confidence)
|
|
76
|
+
const should_have_been_memory = [...facts]
|
|
77
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
78
|
+
.slice(0, 10); // Top 10 facts
|
|
79
|
+
// Collect timings
|
|
80
|
+
// Note: LLM handles all drift detection types together, so we don't have per-type timings
|
|
81
|
+
const timings_ms = {
|
|
82
|
+
extract_facts: Number(extractTiming.toFixed(2)),
|
|
83
|
+
repetition: 0, // LLM handles all detection together
|
|
84
|
+
session_reset: 0,
|
|
85
|
+
contradictions: 0,
|
|
86
|
+
pref_forgotten: 0, // All drift detection combined
|
|
87
|
+
drift_detection: Number(driftTiming.toFixed(2)), // Total LLM drift detection time
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
drift_score,
|
|
91
|
+
raw_score,
|
|
92
|
+
token_waste_pct: Number(token_waste_pct.toFixed(1)),
|
|
93
|
+
events,
|
|
94
|
+
should_have_been_memory,
|
|
95
|
+
timings_ms,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/core/inspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Client - Unified interface for multiple LLM providers
|
|
3
|
+
*/
|
|
4
|
+
import type { LLMProvider } from './providers.js';
|
|
5
|
+
export interface LLMConfig {
|
|
6
|
+
provider: LLMProvider;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
temperature?: number;
|
|
10
|
+
maxTokens?: number;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface LLMResponse {
|
|
14
|
+
content: string;
|
|
15
|
+
model: string;
|
|
16
|
+
usage?: {
|
|
17
|
+
promptTokens: number;
|
|
18
|
+
completionTokens: number;
|
|
19
|
+
totalTokens: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Unified LLM client supporting multiple providers
|
|
24
|
+
*/
|
|
25
|
+
export declare class LLMClient {
|
|
26
|
+
private openaiClient?;
|
|
27
|
+
private anthropicClient?;
|
|
28
|
+
private config;
|
|
29
|
+
constructor(config: LLMConfig);
|
|
30
|
+
/**
|
|
31
|
+
* Generate a completion from the LLM
|
|
32
|
+
*/
|
|
33
|
+
complete(prompt: string, systemPrompt?: string): Promise<LLMResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* OpenAI completion
|
|
36
|
+
*/
|
|
37
|
+
private completeOpenAI;
|
|
38
|
+
/**
|
|
39
|
+
* Anthropic completion
|
|
40
|
+
*/
|
|
41
|
+
private completeAnthropic;
|
|
42
|
+
/**
|
|
43
|
+
* Get default model for each provider
|
|
44
|
+
*/
|
|
45
|
+
private getDefaultModel;
|
|
46
|
+
/**
|
|
47
|
+
* Test the connection
|
|
48
|
+
*/
|
|
49
|
+
test(): Promise<boolean>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create LLM client from environment or explicit config
|
|
53
|
+
*/
|
|
54
|
+
export declare function createLLMClient(config?: Partial<LLMConfig>): LLMClient;
|
|
55
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/llm/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAC,CAAY;IACpC,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IA8C7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAY3E;;OAEG;YACW,cAAc;IAoC5B;;OAEG;YACW,iBAAiB;IAiC/B;;OAEG;IACH,OAAO,CAAC,eAAe;IA8BvB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAS/B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAgBtE"}
|