@weave_protocol/domere 1.0.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/PLANNING.md +231 -0
- package/README.md +50 -0
- package/dist/anchoring/ethereum.d.ts +135 -0
- package/dist/anchoring/ethereum.d.ts.map +1 -0
- package/dist/anchoring/ethereum.js +474 -0
- package/dist/anchoring/ethereum.js.map +1 -0
- package/dist/anchoring/index.d.ts +93 -0
- package/dist/anchoring/index.d.ts.map +1 -0
- package/dist/anchoring/index.js +184 -0
- package/dist/anchoring/index.js.map +1 -0
- package/dist/anchoring/merkle.d.ts +91 -0
- package/dist/anchoring/merkle.d.ts.map +1 -0
- package/dist/anchoring/merkle.js +203 -0
- package/dist/anchoring/merkle.js.map +1 -0
- package/dist/anchoring/solana.d.ts +85 -0
- package/dist/anchoring/solana.d.ts.map +1 -0
- package/dist/anchoring/solana.js +301 -0
- package/dist/anchoring/solana.js.map +1 -0
- package/dist/constants.d.ts +130 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +536 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/language/code-analyzer.d.ts +80 -0
- package/dist/language/code-analyzer.d.ts.map +1 -0
- package/dist/language/code-analyzer.js +489 -0
- package/dist/language/code-analyzer.js.map +1 -0
- package/dist/language/detector.d.ts +53 -0
- package/dist/language/detector.d.ts.map +1 -0
- package/dist/language/detector.js +248 -0
- package/dist/language/detector.js.map +1 -0
- package/dist/language/index.d.ts +61 -0
- package/dist/language/index.d.ts.map +1 -0
- package/dist/language/index.js +109 -0
- package/dist/language/index.js.map +1 -0
- package/dist/language/nl-analyzer.d.ts +59 -0
- package/dist/language/nl-analyzer.d.ts.map +1 -0
- package/dist/language/nl-analyzer.js +350 -0
- package/dist/language/nl-analyzer.js.map +1 -0
- package/dist/language/semantic.d.ts +48 -0
- package/dist/language/semantic.d.ts.map +1 -0
- package/dist/language/semantic.js +329 -0
- package/dist/language/semantic.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +6 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory.d.ts +48 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +211 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/thread/drift.d.ts +43 -0
- package/dist/thread/drift.d.ts.map +1 -0
- package/dist/thread/drift.js +248 -0
- package/dist/thread/drift.js.map +1 -0
- package/dist/thread/index.d.ts +9 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/thread/index.js +9 -0
- package/dist/thread/index.js.map +1 -0
- package/dist/thread/intent.d.ts +68 -0
- package/dist/thread/intent.d.ts.map +1 -0
- package/dist/thread/intent.js +333 -0
- package/dist/thread/intent.js.map +1 -0
- package/dist/thread/manager.d.ts +85 -0
- package/dist/thread/manager.d.ts.map +1 -0
- package/dist/thread/manager.js +305 -0
- package/dist/thread/manager.js.map +1 -0
- package/dist/thread/weave.d.ts +61 -0
- package/dist/thread/weave.d.ts.map +1 -0
- package/dist/thread/weave.js +158 -0
- package/dist/thread/weave.js.map +1 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +102 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +466 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/package.json +24 -0
- package/src/anchoring/ethereum.ts +568 -0
- package/src/anchoring/index.ts +236 -0
- package/src/anchoring/merkle.ts +256 -0
- package/src/anchoring/solana.ts +370 -0
- package/src/constants.ts +566 -0
- package/src/index.ts +43 -0
- package/src/language/code-analyzer.ts +564 -0
- package/src/language/detector.ts +297 -0
- package/src/language/index.ts +129 -0
- package/src/language/nl-analyzer.ts +411 -0
- package/src/language/semantic.ts +385 -0
- package/src/storage/index.ts +6 -0
- package/src/storage/memory.ts +271 -0
- package/src/thread/drift.ts +319 -0
- package/src/thread/index.ts +9 -0
- package/src/thread/intent.ts +409 -0
- package/src/thread/manager.ts +414 -0
- package/src/thread/weave.ts +205 -0
- package/src/tools/index.ts +107 -0
- package/src/types.ts +736 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dōmere - The Judge Protocol
|
|
3
|
+
* Intent Drift Detection
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DriftAnalysis, DriftMetrics } from '../types.js';
|
|
7
|
+
import { DEFAULT_CONFIG } from '../constants.js';
|
|
8
|
+
import { IntentAnalyzer } from './intent.js';
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Drift Detector
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export class DriftDetector {
|
|
15
|
+
private intentAnalyzer: IntentAnalyzer;
|
|
16
|
+
private maxDrift: number;
|
|
17
|
+
private warnThreshold: number;
|
|
18
|
+
|
|
19
|
+
constructor(config?: { maxDrift?: number; warnThreshold?: number }) {
|
|
20
|
+
this.intentAnalyzer = new IntentAnalyzer();
|
|
21
|
+
this.maxDrift = config?.maxDrift || DEFAULT_CONFIG.drift.max_acceptable_drift;
|
|
22
|
+
this.warnThreshold = config?.warnThreshold || DEFAULT_CONFIG.drift.warn_threshold;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Analyze drift between original and current intent
|
|
27
|
+
*/
|
|
28
|
+
analyze(config: {
|
|
29
|
+
original_intent: string;
|
|
30
|
+
previous_intent: string;
|
|
31
|
+
current_intent: string;
|
|
32
|
+
constraints: string[];
|
|
33
|
+
hop_number: number;
|
|
34
|
+
}): DriftAnalysis {
|
|
35
|
+
const metrics = this.calculateMetrics(
|
|
36
|
+
config.original_intent,
|
|
37
|
+
config.current_intent,
|
|
38
|
+
config.constraints
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const hopDrift = this.calculateHopDrift(
|
|
42
|
+
config.previous_intent,
|
|
43
|
+
config.current_intent
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const cumulativeDrift = this.calculateCumulativeDrift(metrics, config.hop_number);
|
|
47
|
+
|
|
48
|
+
const constraintViolations = this.checkConstraintViolations(
|
|
49
|
+
config.current_intent,
|
|
50
|
+
config.constraints
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const verdict = this.determineVerdict(
|
|
54
|
+
cumulativeDrift,
|
|
55
|
+
hopDrift,
|
|
56
|
+
constraintViolations
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
original_intent: config.original_intent,
|
|
61
|
+
current_interpretation: config.current_intent,
|
|
62
|
+
metrics,
|
|
63
|
+
cumulative_drift: cumulativeDrift,
|
|
64
|
+
hop_drift: hopDrift,
|
|
65
|
+
max_acceptable_drift: this.maxDrift,
|
|
66
|
+
verdict,
|
|
67
|
+
explanation: this.generateExplanation(verdict, metrics, constraintViolations),
|
|
68
|
+
constraint_violations: constraintViolations,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Calculate drift metrics
|
|
74
|
+
*/
|
|
75
|
+
calculateMetrics(
|
|
76
|
+
originalIntent: string,
|
|
77
|
+
currentIntent: string,
|
|
78
|
+
constraints: string[]
|
|
79
|
+
): DriftMetrics {
|
|
80
|
+
return {
|
|
81
|
+
semantic_similarity: this.calculateSemanticSimilarity(originalIntent, currentIntent),
|
|
82
|
+
action_alignment: this.calculateActionAlignment(originalIntent, currentIntent),
|
|
83
|
+
scope_creep: this.calculateScopeCreep(originalIntent, currentIntent),
|
|
84
|
+
entity_preservation: this.calculateEntityPreservation(originalIntent, currentIntent),
|
|
85
|
+
constraint_adherence: this.calculateConstraintAdherence(currentIntent, constraints),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private calculateSemanticSimilarity(intent1: string, intent2: string): number {
|
|
90
|
+
const norm1 = this.intentAnalyzer.normalize(intent1);
|
|
91
|
+
const norm2 = this.intentAnalyzer.normalize(intent2);
|
|
92
|
+
|
|
93
|
+
const words1 = new Set(norm1.split(' ').filter(w => w.length > 2));
|
|
94
|
+
const words2 = new Set(norm2.split(' ').filter(w => w.length > 2));
|
|
95
|
+
|
|
96
|
+
if (words1.size === 0 && words2.size === 0) return 1;
|
|
97
|
+
if (words1.size === 0 || words2.size === 0) return 0;
|
|
98
|
+
|
|
99
|
+
const intersection = new Set([...words1].filter(w => words2.has(w)));
|
|
100
|
+
const union = new Set([...words1, ...words2]);
|
|
101
|
+
|
|
102
|
+
const jaccardSimilarity = intersection.size / union.size;
|
|
103
|
+
|
|
104
|
+
const bigrams1 = this.getBigrams(norm1);
|
|
105
|
+
const bigrams2 = this.getBigrams(norm2);
|
|
106
|
+
|
|
107
|
+
const bigramIntersection = new Set([...bigrams1].filter(b => bigrams2.has(b)));
|
|
108
|
+
const bigramUnion = new Set([...bigrams1, ...bigrams2]);
|
|
109
|
+
|
|
110
|
+
const bigramSimilarity = bigramUnion.size > 0
|
|
111
|
+
? bigramIntersection.size / bigramUnion.size
|
|
112
|
+
: 0;
|
|
113
|
+
|
|
114
|
+
return jaccardSimilarity * 0.6 + bigramSimilarity * 0.4;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private calculateActionAlignment(originalIntent: string, currentIntent: string): number {
|
|
118
|
+
const original = this.intentAnalyzer.analyze(originalIntent);
|
|
119
|
+
const current = this.intentAnalyzer.analyze(currentIntent);
|
|
120
|
+
|
|
121
|
+
let alignment = 0;
|
|
122
|
+
|
|
123
|
+
if (original.classification === current.classification) {
|
|
124
|
+
alignment += 0.4;
|
|
125
|
+
} else if (this.areRelatedClassifications(original.classification, current.classification)) {
|
|
126
|
+
alignment += 0.2;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (original.action_verb && current.action_verb) {
|
|
130
|
+
if (original.action_verb === current.action_verb) {
|
|
131
|
+
alignment += 0.3;
|
|
132
|
+
} else if (this.areSynonymVerbs(original.action_verb, current.action_verb)) {
|
|
133
|
+
alignment += 0.2;
|
|
134
|
+
}
|
|
135
|
+
} else if (!original.action_verb && !current.action_verb) {
|
|
136
|
+
alignment += 0.3;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (original.target_object && current.target_object) {
|
|
140
|
+
const targetSimilarity = this.calculateWordSimilarity(
|
|
141
|
+
original.target_object,
|
|
142
|
+
current.target_object
|
|
143
|
+
);
|
|
144
|
+
alignment += targetSimilarity * 0.3;
|
|
145
|
+
} else if (!original.target_object && !current.target_object) {
|
|
146
|
+
alignment += 0.3;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return Math.min(1, alignment);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private calculateScopeCreep(originalIntent: string, currentIntent: string): number {
|
|
153
|
+
const original = this.intentAnalyzer.analyze(originalIntent);
|
|
154
|
+
const current = this.intentAnalyzer.analyze(currentIntent);
|
|
155
|
+
|
|
156
|
+
const scopeValues: Record<string, number> = {
|
|
157
|
+
'narrow': -1,
|
|
158
|
+
'medium': 0,
|
|
159
|
+
'broad': 1,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const originalScope = scopeValues[original.scope];
|
|
163
|
+
const currentScope = scopeValues[current.scope];
|
|
164
|
+
|
|
165
|
+
return 0.5 + (currentScope - originalScope) * 0.25;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private calculateEntityPreservation(originalIntent: string, currentIntent: string): number {
|
|
169
|
+
const original = this.intentAnalyzer.analyze(originalIntent);
|
|
170
|
+
const current = this.intentAnalyzer.analyze(currentIntent);
|
|
171
|
+
|
|
172
|
+
if (original.entities.length === 0) return 1;
|
|
173
|
+
|
|
174
|
+
const originalValues = new Set(original.entities.map(e => e.value.toLowerCase()));
|
|
175
|
+
const currentLower = currentIntent.toLowerCase();
|
|
176
|
+
|
|
177
|
+
let preserved = 0;
|
|
178
|
+
for (const value of originalValues) {
|
|
179
|
+
if (currentLower.includes(value)) {
|
|
180
|
+
preserved++;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return preserved / originalValues.size;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private calculateConstraintAdherence(currentIntent: string, constraints: string[]): number {
|
|
188
|
+
if (constraints.length === 0) return 1;
|
|
189
|
+
|
|
190
|
+
const violations = this.checkConstraintViolations(currentIntent, constraints);
|
|
191
|
+
|
|
192
|
+
return 1 - (violations.length / constraints.length);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private checkConstraintViolations(currentIntent: string, constraints: string[]): string[] {
|
|
196
|
+
const violations: string[] = [];
|
|
197
|
+
const currentLower = currentIntent.toLowerCase();
|
|
198
|
+
|
|
199
|
+
for (const constraint of constraints) {
|
|
200
|
+
if (constraint.startsWith('NOT:')) {
|
|
201
|
+
const forbidden = constraint.slice(5).toLowerCase().trim();
|
|
202
|
+
if (currentLower.includes(forbidden)) {
|
|
203
|
+
violations.push(constraint);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return violations;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private calculateHopDrift(previousIntent: string, currentIntent: string): number {
|
|
212
|
+
const similarity = this.calculateSemanticSimilarity(previousIntent, currentIntent);
|
|
213
|
+
return 1 - similarity;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private calculateCumulativeDrift(metrics: DriftMetrics, hopNumber: number): number {
|
|
217
|
+
const baseDrift =
|
|
218
|
+
(1 - metrics.semantic_similarity) * 0.3 +
|
|
219
|
+
(1 - metrics.action_alignment) * 0.25 +
|
|
220
|
+
Math.abs(metrics.scope_creep - 0.5) * 0.15 +
|
|
221
|
+
(1 - metrics.entity_preservation) * 0.15 +
|
|
222
|
+
(1 - metrics.constraint_adherence) * 0.15;
|
|
223
|
+
|
|
224
|
+
const hopFactor = 1 + (hopNumber - 1) * 0.1;
|
|
225
|
+
|
|
226
|
+
return Math.min(1, baseDrift * hopFactor);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private determineVerdict(
|
|
230
|
+
cumulativeDrift: number,
|
|
231
|
+
hopDrift: number,
|
|
232
|
+
constraintViolations: string[]
|
|
233
|
+
): 'aligned' | 'minor_drift' | 'significant_drift' | 'violated' {
|
|
234
|
+
if (constraintViolations.length > 0) return 'violated';
|
|
235
|
+
if (cumulativeDrift > this.maxDrift) return 'violated';
|
|
236
|
+
if (cumulativeDrift > this.warnThreshold || hopDrift > this.warnThreshold * 1.5) return 'significant_drift';
|
|
237
|
+
if (cumulativeDrift > this.warnThreshold * 0.5 || hopDrift > this.warnThreshold) return 'minor_drift';
|
|
238
|
+
return 'aligned';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private generateExplanation(
|
|
242
|
+
verdict: string,
|
|
243
|
+
metrics: DriftMetrics,
|
|
244
|
+
constraintViolations: string[]
|
|
245
|
+
): string {
|
|
246
|
+
const parts: string[] = [];
|
|
247
|
+
|
|
248
|
+
if (verdict === 'aligned') {
|
|
249
|
+
parts.push('Intent preserved through this hop.');
|
|
250
|
+
} else if (verdict === 'violated') {
|
|
251
|
+
if (constraintViolations.length > 0) {
|
|
252
|
+
parts.push(`Constraint violations: ${constraintViolations.join(', ')}`);
|
|
253
|
+
} else {
|
|
254
|
+
parts.push('Intent has drifted beyond acceptable threshold.');
|
|
255
|
+
}
|
|
256
|
+
} else if (verdict === 'significant_drift') {
|
|
257
|
+
parts.push('Significant drift detected.');
|
|
258
|
+
} else {
|
|
259
|
+
parts.push('Minor drift detected.');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (metrics.semantic_similarity < 0.5) parts.push('Low semantic similarity.');
|
|
263
|
+
if (metrics.action_alignment < 0.5) parts.push('Action type changed.');
|
|
264
|
+
if (metrics.scope_creep > 0.7) parts.push('Scope expanded.');
|
|
265
|
+
if (metrics.entity_preservation < 0.5) parts.push('Entities not preserved.');
|
|
266
|
+
|
|
267
|
+
return parts.join(' ');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private getBigrams(text: string): Set<string> {
|
|
271
|
+
const words = text.split(' ');
|
|
272
|
+
const bigrams = new Set<string>();
|
|
273
|
+
for (let i = 0; i < words.length - 1; i++) {
|
|
274
|
+
bigrams.add(`${words[i]} ${words[i + 1]}`);
|
|
275
|
+
}
|
|
276
|
+
return bigrams;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private areRelatedClassifications(c1: string, c2: string): boolean {
|
|
280
|
+
const related: Record<string, string[]> = {
|
|
281
|
+
'query': ['analysis'],
|
|
282
|
+
'analysis': ['query', 'generation'],
|
|
283
|
+
'mutation': ['execution'],
|
|
284
|
+
'execution': ['mutation'],
|
|
285
|
+
'generation': ['analysis', 'communication'],
|
|
286
|
+
'communication': ['generation'],
|
|
287
|
+
};
|
|
288
|
+
return related[c1]?.includes(c2) || related[c2]?.includes(c1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private areSynonymVerbs(v1: string, v2: string): boolean {
|
|
292
|
+
const synonymGroups = [
|
|
293
|
+
['get', 'fetch', 'retrieve', 'find', 'search', 'lookup'],
|
|
294
|
+
['create', 'make', 'generate', 'build', 'add'],
|
|
295
|
+
['update', 'change', 'modify', 'edit', 'set'],
|
|
296
|
+
['delete', 'remove', 'drop', 'clear', 'erase'],
|
|
297
|
+
['send', 'email', 'message', 'notify'],
|
|
298
|
+
['analyze', 'examine', 'review', 'assess'],
|
|
299
|
+
];
|
|
300
|
+
|
|
301
|
+
for (const group of synonymGroups) {
|
|
302
|
+
if (group.includes(v1) && group.includes(v2)) return true;
|
|
303
|
+
}
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private calculateWordSimilarity(word1: string, word2: string): number {
|
|
308
|
+
if (word1 === word2) return 1;
|
|
309
|
+
if (word1.includes(word2) || word2.includes(word1)) return 0.8;
|
|
310
|
+
|
|
311
|
+
const chars1 = new Set(word1.toLowerCase().split(''));
|
|
312
|
+
const chars2 = new Set(word2.toLowerCase().split(''));
|
|
313
|
+
|
|
314
|
+
const intersection = new Set([...chars1].filter(c => chars2.has(c)));
|
|
315
|
+
const union = new Set([...chars1, ...chars2]);
|
|
316
|
+
|
|
317
|
+
return intersection.size / union.size;
|
|
318
|
+
}
|
|
319
|
+
}
|