@sparkleideas/testing 3.0.0-alpha.7
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/README.md +547 -0
- package/__tests__/framework.test.ts +21 -0
- package/package.json +61 -0
- package/src/fixtures/agent-fixtures.ts +793 -0
- package/src/fixtures/agents.ts +212 -0
- package/src/fixtures/configurations.ts +491 -0
- package/src/fixtures/index.ts +21 -0
- package/src/fixtures/mcp-fixtures.ts +1030 -0
- package/src/fixtures/memory-entries.ts +328 -0
- package/src/fixtures/memory-fixtures.ts +750 -0
- package/src/fixtures/swarm-fixtures.ts +837 -0
- package/src/fixtures/tasks.ts +309 -0
- package/src/helpers/assertion-helpers.ts +616 -0
- package/src/helpers/assertions.ts +286 -0
- package/src/helpers/create-mock.ts +200 -0
- package/src/helpers/index.ts +182 -0
- package/src/helpers/mock-factory.ts +711 -0
- package/src/helpers/setup-teardown.ts +678 -0
- package/src/helpers/swarm-instance.ts +326 -0
- package/src/helpers/test-application.ts +310 -0
- package/src/helpers/test-utils.ts +670 -0
- package/src/index.ts +232 -0
- package/src/mocks/index.ts +29 -0
- package/src/mocks/mock-mcp-client.ts +723 -0
- package/src/mocks/mock-services.ts +793 -0
- package/src/regression/api-contract.ts +473 -0
- package/src/regression/index.ts +46 -0
- package/src/regression/integration-regression.ts +416 -0
- package/src/regression/performance-baseline.ts +356 -0
- package/src/regression/regression-runner.ts +339 -0
- package/src/regression/security-regression.ts +331 -0
- package/src/setup.ts +127 -0
- package/src/v2-compat/api-compat.test.ts +590 -0
- package/src/v2-compat/cli-compat.test.ts +484 -0
- package/src/v2-compat/compatibility-validator.ts +1072 -0
- package/src/v2-compat/hooks-compat.test.ts +602 -0
- package/src/v2-compat/index.ts +58 -0
- package/src/v2-compat/mcp-compat.test.ts +557 -0
- package/src/v2-compat/report-generator.ts +441 -0
- package/tmp.json +0 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sparkleideas/testing - Memory Fixtures
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive mock memory entries and backend configurations for testing.
|
|
5
|
+
* Supports AgentDB, HNSW indexing, vector search, and ReasoningBank patterns.
|
|
6
|
+
*
|
|
7
|
+
* Based on ADR-006 (Unified Memory Service) and ADR-009 (Hybrid Memory Backend).
|
|
8
|
+
*/
|
|
9
|
+
import { vi, type Mock } from 'vitest';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Memory entry types
|
|
13
|
+
*/
|
|
14
|
+
export type MemoryType = 'short-term' | 'long-term' | 'semantic' | 'episodic' | 'procedural';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Memory backend types
|
|
18
|
+
*/
|
|
19
|
+
export type MemoryBackendType = 'sqlite' | '@sparkleideas/agentdb' | 'hybrid' | 'redis' | 'memory';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Memory entry interface
|
|
23
|
+
*/
|
|
24
|
+
export interface MemoryEntry {
|
|
25
|
+
key: string;
|
|
26
|
+
value: unknown;
|
|
27
|
+
metadata: MemoryMetadata;
|
|
28
|
+
embedding?: number[];
|
|
29
|
+
createdAt: Date;
|
|
30
|
+
updatedAt: Date;
|
|
31
|
+
expiresAt?: Date;
|
|
32
|
+
accessCount?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Memory metadata interface
|
|
37
|
+
*/
|
|
38
|
+
export interface MemoryMetadata {
|
|
39
|
+
type: MemoryType;
|
|
40
|
+
tags: string[];
|
|
41
|
+
source?: string;
|
|
42
|
+
confidence?: number;
|
|
43
|
+
ttl?: number;
|
|
44
|
+
agentId?: string;
|
|
45
|
+
sessionId?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Vector query interface
|
|
50
|
+
*/
|
|
51
|
+
export interface VectorQuery {
|
|
52
|
+
embedding: number[];
|
|
53
|
+
topK: number;
|
|
54
|
+
threshold?: number;
|
|
55
|
+
filters?: Record<string, unknown>;
|
|
56
|
+
includeMetadata?: boolean;
|
|
57
|
+
rerank?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Search result interface
|
|
62
|
+
*/
|
|
63
|
+
export interface SearchResult {
|
|
64
|
+
key: string;
|
|
65
|
+
value: unknown;
|
|
66
|
+
score: number;
|
|
67
|
+
metadata: MemoryMetadata;
|
|
68
|
+
distance?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* HNSW index configuration
|
|
73
|
+
*/
|
|
74
|
+
export interface HNSWConfig {
|
|
75
|
+
M: number;
|
|
76
|
+
efConstruction: number;
|
|
77
|
+
efSearch: number;
|
|
78
|
+
dimensions: number;
|
|
79
|
+
metric: 'cosine' | 'euclidean' | 'dot';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Quantization configuration
|
|
84
|
+
*/
|
|
85
|
+
export interface QuantizationConfig {
|
|
86
|
+
enabled: boolean;
|
|
87
|
+
bits: 4 | 8 | 16;
|
|
88
|
+
type: 'scalar' | 'product';
|
|
89
|
+
compressionRatio?: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Memory backend configuration
|
|
94
|
+
*/
|
|
95
|
+
export interface MemoryBackendConfig {
|
|
96
|
+
type: MemoryBackendType;
|
|
97
|
+
path?: string;
|
|
98
|
+
maxSize?: number;
|
|
99
|
+
ttlMs?: number;
|
|
100
|
+
vectorDimensions?: number;
|
|
101
|
+
hnswConfig?: HNSWConfig;
|
|
102
|
+
quantization?: QuantizationConfig;
|
|
103
|
+
caching?: {
|
|
104
|
+
enabled: boolean;
|
|
105
|
+
maxSize: number;
|
|
106
|
+
ttl: number;
|
|
107
|
+
strategy: 'lru' | 'lfu' | 'arc';
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Learned pattern interface (for ReasoningBank)
|
|
113
|
+
*/
|
|
114
|
+
export interface LearnedPattern {
|
|
115
|
+
id: string;
|
|
116
|
+
sessionId: string;
|
|
117
|
+
task: string;
|
|
118
|
+
input: string;
|
|
119
|
+
output: string;
|
|
120
|
+
reward: number;
|
|
121
|
+
success: boolean;
|
|
122
|
+
critique?: string;
|
|
123
|
+
tokensUsed?: number;
|
|
124
|
+
latencyMs?: number;
|
|
125
|
+
createdAt: Date;
|
|
126
|
+
embedding?: number[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Generate deterministic mock embedding vector
|
|
131
|
+
*/
|
|
132
|
+
export function generateMockEmbedding(dimensions: number, seed: string): number[] {
|
|
133
|
+
const seedHash = hashString(seed);
|
|
134
|
+
return Array.from({ length: dimensions }, (_, i) => {
|
|
135
|
+
const value = Math.sin(seedHash + i * 0.1) * 0.5 + 0.5;
|
|
136
|
+
return Math.round(value * 10000) / 10000;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Simple string hash function for deterministic embeddings
|
|
142
|
+
*/
|
|
143
|
+
function hashString(str: string): number {
|
|
144
|
+
let hash = 0;
|
|
145
|
+
for (let i = 0; i < str.length; i++) {
|
|
146
|
+
hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
|
|
147
|
+
}
|
|
148
|
+
return hash;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Pre-defined memory entries for testing
|
|
153
|
+
*/
|
|
154
|
+
export const memoryEntries: Record<string, MemoryEntry> = {
|
|
155
|
+
agentPattern: {
|
|
156
|
+
key: 'pattern:agent:queen-coordinator',
|
|
157
|
+
value: {
|
|
158
|
+
pattern: 'orchestration',
|
|
159
|
+
successRate: 0.95,
|
|
160
|
+
avgDuration: 150,
|
|
161
|
+
commonTasks: ['task-distribution', 'conflict-resolution', 'priority-scheduling'],
|
|
162
|
+
},
|
|
163
|
+
metadata: {
|
|
164
|
+
type: 'semantic',
|
|
165
|
+
tags: ['agent', 'pattern', 'queen', 'coordination'],
|
|
166
|
+
source: 'learning-module',
|
|
167
|
+
confidence: 0.92,
|
|
168
|
+
agentId: 'queen-coordinator-001',
|
|
169
|
+
},
|
|
170
|
+
embedding: generateMockEmbedding(384, 'orchestration'),
|
|
171
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
172
|
+
updatedAt: new Date('2024-01-15T12:00:00Z'),
|
|
173
|
+
accessCount: 150,
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
securityRule: {
|
|
177
|
+
key: 'rule:security:path-traversal',
|
|
178
|
+
value: {
|
|
179
|
+
rule: 'block-path-traversal',
|
|
180
|
+
patterns: ['../', '~/', '/etc/', '/tmp/', '/var/'],
|
|
181
|
+
severity: 'critical',
|
|
182
|
+
action: 'reject',
|
|
183
|
+
},
|
|
184
|
+
metadata: {
|
|
185
|
+
type: 'long-term',
|
|
186
|
+
tags: ['security', 'rule', 'validation', 'path'],
|
|
187
|
+
source: 'security-module',
|
|
188
|
+
confidence: 1.0,
|
|
189
|
+
},
|
|
190
|
+
embedding: generateMockEmbedding(384, 'security-path-traversal'),
|
|
191
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
192
|
+
updatedAt: new Date('2024-01-01T00:00:00Z'),
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
taskMemory: {
|
|
196
|
+
key: 'task:memory:impl-001',
|
|
197
|
+
value: {
|
|
198
|
+
taskId: 'impl-001',
|
|
199
|
+
context: 'implementing security module',
|
|
200
|
+
decisions: ['use argon2 for hashing', 'implement path validation', 'add input sanitization'],
|
|
201
|
+
progress: 0.75,
|
|
202
|
+
},
|
|
203
|
+
metadata: {
|
|
204
|
+
type: 'episodic',
|
|
205
|
+
tags: ['task', 'implementation', 'security'],
|
|
206
|
+
ttl: 86400000, // 24 hours
|
|
207
|
+
sessionId: 'session-001',
|
|
208
|
+
},
|
|
209
|
+
embedding: generateMockEmbedding(384, 'implementation-security'),
|
|
210
|
+
createdAt: new Date('2024-01-15T10:00:00Z'),
|
|
211
|
+
updatedAt: new Date('2024-01-15T10:00:00Z'),
|
|
212
|
+
expiresAt: new Date('2024-01-16T10:00:00Z'),
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
sessionContext: {
|
|
216
|
+
key: 'session:context:session-001',
|
|
217
|
+
value: {
|
|
218
|
+
sessionId: 'session-001',
|
|
219
|
+
user: 'developer',
|
|
220
|
+
activeAgents: ['queen-coordinator', 'coder', 'tester'],
|
|
221
|
+
currentTask: 'security-implementation',
|
|
222
|
+
startedAt: new Date('2024-01-15T14:00:00Z'),
|
|
223
|
+
},
|
|
224
|
+
metadata: {
|
|
225
|
+
type: 'short-term',
|
|
226
|
+
tags: ['session', 'context', 'active'],
|
|
227
|
+
ttl: 3600000, // 1 hour
|
|
228
|
+
},
|
|
229
|
+
createdAt: new Date('2024-01-15T14:00:00Z'),
|
|
230
|
+
updatedAt: new Date('2024-01-15T14:30:00Z'),
|
|
231
|
+
expiresAt: new Date('2024-01-15T15:30:00Z'),
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
learningTrajectory: {
|
|
235
|
+
key: 'learning:trajectory:traj-001',
|
|
236
|
+
value: {
|
|
237
|
+
trajectoryId: 'traj-001',
|
|
238
|
+
steps: [
|
|
239
|
+
{ action: 'analyze', result: 'success', reward: 0.8, duration: 100 },
|
|
240
|
+
{ action: 'implement', result: 'success', reward: 0.9, duration: 500 },
|
|
241
|
+
{ action: 'test', result: 'success', reward: 1.0, duration: 200 },
|
|
242
|
+
],
|
|
243
|
+
totalReward: 2.7,
|
|
244
|
+
convergenceRate: 0.85,
|
|
245
|
+
},
|
|
246
|
+
metadata: {
|
|
247
|
+
type: 'long-term',
|
|
248
|
+
tags: ['learning', 'trajectory', 'reinforcement', 'reasoningbank'],
|
|
249
|
+
source: 'reasoningbank',
|
|
250
|
+
confidence: 0.88,
|
|
251
|
+
},
|
|
252
|
+
embedding: generateMockEmbedding(384, 'learning-trajectory'),
|
|
253
|
+
createdAt: new Date('2024-01-10T00:00:00Z'),
|
|
254
|
+
updatedAt: new Date('2024-01-15T00:00:00Z'),
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
vectorIndex: {
|
|
258
|
+
key: 'index:hnsw:agents',
|
|
259
|
+
value: {
|
|
260
|
+
indexId: 'hnsw-agents',
|
|
261
|
+
dimensions: 384,
|
|
262
|
+
vectorCount: 10000,
|
|
263
|
+
M: 16,
|
|
264
|
+
efConstruction: 200,
|
|
265
|
+
efSearch: 50,
|
|
266
|
+
},
|
|
267
|
+
metadata: {
|
|
268
|
+
type: 'procedural',
|
|
269
|
+
tags: ['index', 'hnsw', 'vector', 'search'],
|
|
270
|
+
source: '@sparkleideas/agentdb',
|
|
271
|
+
},
|
|
272
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
273
|
+
updatedAt: new Date('2024-01-15T00:00:00Z'),
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
cacheEntry: {
|
|
277
|
+
key: 'cache:search:security-patterns',
|
|
278
|
+
value: {
|
|
279
|
+
query: 'security input validation',
|
|
280
|
+
results: ['pattern-001', 'pattern-002', 'pattern-003'],
|
|
281
|
+
hitCount: 45,
|
|
282
|
+
},
|
|
283
|
+
metadata: {
|
|
284
|
+
type: 'short-term',
|
|
285
|
+
tags: ['cache', 'search', 'security'],
|
|
286
|
+
ttl: 300000, // 5 minutes
|
|
287
|
+
},
|
|
288
|
+
createdAt: new Date('2024-01-15T14:00:00Z'),
|
|
289
|
+
updatedAt: new Date('2024-01-15T14:00:00Z'),
|
|
290
|
+
expiresAt: new Date('2024-01-15T14:05:00Z'),
|
|
291
|
+
accessCount: 45,
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Pre-defined search results for testing
|
|
297
|
+
*/
|
|
298
|
+
export const searchResults: Record<string, SearchResult[]> = {
|
|
299
|
+
securityPatterns: [
|
|
300
|
+
{
|
|
301
|
+
key: 'pattern:security:input-validation',
|
|
302
|
+
value: { pattern: 'validate all inputs', effectiveness: 0.99, applicability: 'universal' },
|
|
303
|
+
score: 0.95,
|
|
304
|
+
metadata: { type: 'semantic', tags: ['security', 'pattern', 'input'] },
|
|
305
|
+
distance: 0.05,
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: 'pattern:security:output-encoding',
|
|
309
|
+
value: { pattern: 'encode all outputs', effectiveness: 0.97, applicability: 'web' },
|
|
310
|
+
score: 0.88,
|
|
311
|
+
metadata: { type: 'semantic', tags: ['security', 'pattern', 'output'] },
|
|
312
|
+
distance: 0.12,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
key: 'pattern:security:least-privilege',
|
|
316
|
+
value: { pattern: 'minimal permissions', effectiveness: 0.95, applicability: 'universal' },
|
|
317
|
+
score: 0.82,
|
|
318
|
+
metadata: { type: 'semantic', tags: ['security', 'pattern', 'permissions'] },
|
|
319
|
+
distance: 0.18,
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
|
|
323
|
+
agentPatterns: [
|
|
324
|
+
{
|
|
325
|
+
key: 'pattern:agent:coordination',
|
|
326
|
+
value: { pattern: 'hierarchical coordination', successRate: 0.92, topology: 'hierarchical-mesh' },
|
|
327
|
+
score: 0.91,
|
|
328
|
+
metadata: { type: 'semantic', tags: ['agent', 'pattern', 'coordination'] },
|
|
329
|
+
distance: 0.09,
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
key: 'pattern:agent:communication',
|
|
333
|
+
value: { pattern: 'async messaging', successRate: 0.89, protocol: 'quic' },
|
|
334
|
+
score: 0.85,
|
|
335
|
+
metadata: { type: 'semantic', tags: ['agent', 'pattern', 'communication'] },
|
|
336
|
+
distance: 0.15,
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
|
|
340
|
+
memoryOptimization: [
|
|
341
|
+
{
|
|
342
|
+
key: 'pattern:memory:hnsw-tuning',
|
|
343
|
+
value: { M: 16, efConstruction: 200, speedup: '150x' },
|
|
344
|
+
score: 0.94,
|
|
345
|
+
metadata: { type: 'procedural', tags: ['memory', 'optimization', 'hnsw'] },
|
|
346
|
+
distance: 0.06,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
key: 'pattern:memory:quantization',
|
|
350
|
+
value: { bits: 8, compression: '4x', qualityLoss: 0.02 },
|
|
351
|
+
score: 0.89,
|
|
352
|
+
metadata: { type: 'procedural', tags: ['memory', 'optimization', 'quantization'] },
|
|
353
|
+
distance: 0.11,
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
|
|
357
|
+
emptyResults: [],
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Pre-defined learned patterns for ReasoningBank testing
|
|
362
|
+
*/
|
|
363
|
+
export const learnedPatterns: Record<string, LearnedPattern> = {
|
|
364
|
+
successfulImplementation: {
|
|
365
|
+
id: 'pattern-impl-001',
|
|
366
|
+
sessionId: 'session-001',
|
|
367
|
+
task: 'Implement input validation',
|
|
368
|
+
input: 'Create secure input validation for user data',
|
|
369
|
+
output: 'Implemented regex-based validation with sanitization',
|
|
370
|
+
reward: 0.95,
|
|
371
|
+
success: true,
|
|
372
|
+
critique: 'Good coverage of edge cases, could add more specific error messages',
|
|
373
|
+
tokensUsed: 1500,
|
|
374
|
+
latencyMs: 2500,
|
|
375
|
+
createdAt: new Date('2024-01-15T10:00:00Z'),
|
|
376
|
+
embedding: generateMockEmbedding(384, 'input-validation'),
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
failedImplementation: {
|
|
380
|
+
id: 'pattern-impl-002',
|
|
381
|
+
sessionId: 'session-001',
|
|
382
|
+
task: 'Implement path validation',
|
|
383
|
+
input: 'Create path traversal protection',
|
|
384
|
+
output: 'Initial implementation had security gaps',
|
|
385
|
+
reward: 0.3,
|
|
386
|
+
success: false,
|
|
387
|
+
critique: 'Did not handle URL-encoded path traversal attempts',
|
|
388
|
+
tokensUsed: 2000,
|
|
389
|
+
latencyMs: 3500,
|
|
390
|
+
createdAt: new Date('2024-01-15T11:00:00Z'),
|
|
391
|
+
embedding: generateMockEmbedding(384, 'path-validation-failed'),
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
optimizationPattern: {
|
|
395
|
+
id: 'pattern-opt-001',
|
|
396
|
+
sessionId: 'session-002',
|
|
397
|
+
task: 'Optimize vector search',
|
|
398
|
+
input: 'Improve HNSW search performance',
|
|
399
|
+
output: 'Tuned M=16, efConstruction=200 for 150x speedup',
|
|
400
|
+
reward: 0.98,
|
|
401
|
+
success: true,
|
|
402
|
+
critique: 'Excellent parameter tuning, validated with benchmarks',
|
|
403
|
+
tokensUsed: 800,
|
|
404
|
+
latencyMs: 1200,
|
|
405
|
+
createdAt: new Date('2024-01-14T08:00:00Z'),
|
|
406
|
+
embedding: generateMockEmbedding(384, 'vector-optimization'),
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Pre-defined HNSW configurations
|
|
412
|
+
*/
|
|
413
|
+
export const hnswConfigs: Record<string, HNSWConfig> = {
|
|
414
|
+
default: {
|
|
415
|
+
M: 16,
|
|
416
|
+
efConstruction: 200,
|
|
417
|
+
efSearch: 50,
|
|
418
|
+
dimensions: 384,
|
|
419
|
+
metric: 'cosine',
|
|
420
|
+
},
|
|
421
|
+
|
|
422
|
+
highPerformance: {
|
|
423
|
+
M: 32,
|
|
424
|
+
efConstruction: 400,
|
|
425
|
+
efSearch: 100,
|
|
426
|
+
dimensions: 384,
|
|
427
|
+
metric: 'cosine',
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
lowMemory: {
|
|
431
|
+
M: 8,
|
|
432
|
+
efConstruction: 100,
|
|
433
|
+
efSearch: 25,
|
|
434
|
+
dimensions: 384,
|
|
435
|
+
metric: 'dot',
|
|
436
|
+
},
|
|
437
|
+
|
|
438
|
+
highDimension: {
|
|
439
|
+
M: 24,
|
|
440
|
+
efConstruction: 300,
|
|
441
|
+
efSearch: 75,
|
|
442
|
+
dimensions: 1536,
|
|
443
|
+
metric: 'euclidean',
|
|
444
|
+
},
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Pre-defined quantization configurations
|
|
449
|
+
*/
|
|
450
|
+
export const quantizationConfigs: Record<string, QuantizationConfig> = {
|
|
451
|
+
scalar4bit: {
|
|
452
|
+
enabled: true,
|
|
453
|
+
bits: 4,
|
|
454
|
+
type: 'scalar',
|
|
455
|
+
compressionRatio: 8,
|
|
456
|
+
},
|
|
457
|
+
|
|
458
|
+
scalar8bit: {
|
|
459
|
+
enabled: true,
|
|
460
|
+
bits: 8,
|
|
461
|
+
type: 'scalar',
|
|
462
|
+
compressionRatio: 4,
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
product: {
|
|
466
|
+
enabled: true,
|
|
467
|
+
bits: 8,
|
|
468
|
+
type: 'product',
|
|
469
|
+
compressionRatio: 32,
|
|
470
|
+
},
|
|
471
|
+
|
|
472
|
+
disabled: {
|
|
473
|
+
enabled: false,
|
|
474
|
+
bits: 16,
|
|
475
|
+
type: 'scalar',
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Pre-defined memory backend configurations
|
|
481
|
+
*/
|
|
482
|
+
export const memoryBackendConfigs: Record<string, MemoryBackendConfig> = {
|
|
483
|
+
agentDB: {
|
|
484
|
+
type: '@sparkleideas/agentdb',
|
|
485
|
+
vectorDimensions: 384,
|
|
486
|
+
hnswConfig: hnswConfigs.default,
|
|
487
|
+
quantization: quantizationConfigs.scalar8bit,
|
|
488
|
+
caching: {
|
|
489
|
+
enabled: true,
|
|
490
|
+
maxSize: 1000,
|
|
491
|
+
ttl: 3600000,
|
|
492
|
+
strategy: 'lru',
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
hybrid: {
|
|
497
|
+
type: 'hybrid',
|
|
498
|
+
path: './data',
|
|
499
|
+
vectorDimensions: 384,
|
|
500
|
+
hnswConfig: hnswConfigs.highPerformance,
|
|
501
|
+
quantization: quantizationConfigs.scalar4bit,
|
|
502
|
+
caching: {
|
|
503
|
+
enabled: true,
|
|
504
|
+
maxSize: 5000,
|
|
505
|
+
ttl: 7200000,
|
|
506
|
+
strategy: 'arc',
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
inMemory: {
|
|
511
|
+
type: 'memory',
|
|
512
|
+
maxSize: 10000,
|
|
513
|
+
vectorDimensions: 384,
|
|
514
|
+
hnswConfig: hnswConfigs.lowMemory,
|
|
515
|
+
caching: {
|
|
516
|
+
enabled: false,
|
|
517
|
+
maxSize: 0,
|
|
518
|
+
ttl: 0,
|
|
519
|
+
strategy: 'lru',
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
|
|
523
|
+
sqlite: {
|
|
524
|
+
type: 'sqlite',
|
|
525
|
+
path: './test.db',
|
|
526
|
+
maxSize: 100000,
|
|
527
|
+
caching: {
|
|
528
|
+
enabled: true,
|
|
529
|
+
maxSize: 2000,
|
|
530
|
+
ttl: 1800000,
|
|
531
|
+
strategy: 'lfu',
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Performance targets from V3 specifications
|
|
538
|
+
*/
|
|
539
|
+
export const performanceTargets = {
|
|
540
|
+
searchSpeedupMin: 150,
|
|
541
|
+
searchSpeedupMax: 12500,
|
|
542
|
+
memoryReduction: 0.50,
|
|
543
|
+
insertionTime: 1, // ms
|
|
544
|
+
searchTime: 0.1, // ms for 1M vectors
|
|
545
|
+
flashAttentionSpeedup: [2.49, 7.47],
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Factory function to create memory entry with overrides
|
|
550
|
+
*/
|
|
551
|
+
export function createMemoryEntry(
|
|
552
|
+
base: keyof typeof memoryEntries,
|
|
553
|
+
overrides?: Partial<MemoryEntry>
|
|
554
|
+
): MemoryEntry {
|
|
555
|
+
return {
|
|
556
|
+
...memoryEntries[base],
|
|
557
|
+
...overrides,
|
|
558
|
+
key: overrides?.key ?? memoryEntries[base].key,
|
|
559
|
+
createdAt: overrides?.createdAt ?? new Date(),
|
|
560
|
+
updatedAt: overrides?.updatedAt ?? new Date(),
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Factory function to create vector query
|
|
566
|
+
*/
|
|
567
|
+
export function createVectorQuery(overrides?: Partial<VectorQuery>): VectorQuery {
|
|
568
|
+
return {
|
|
569
|
+
embedding: overrides?.embedding ?? generateMockEmbedding(384, 'query'),
|
|
570
|
+
topK: overrides?.topK ?? 10,
|
|
571
|
+
threshold: overrides?.threshold ?? 0.7,
|
|
572
|
+
filters: overrides?.filters,
|
|
573
|
+
includeMetadata: overrides?.includeMetadata ?? true,
|
|
574
|
+
rerank: overrides?.rerank ?? false,
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Factory function to create learned pattern
|
|
580
|
+
*/
|
|
581
|
+
export function createLearnedPattern(
|
|
582
|
+
base: keyof typeof learnedPatterns,
|
|
583
|
+
overrides?: Partial<LearnedPattern>
|
|
584
|
+
): LearnedPattern {
|
|
585
|
+
return {
|
|
586
|
+
...learnedPatterns[base],
|
|
587
|
+
...overrides,
|
|
588
|
+
id: overrides?.id ?? `pattern-${Date.now()}`,
|
|
589
|
+
createdAt: overrides?.createdAt ?? new Date(),
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Factory function to create HNSW config
|
|
595
|
+
*/
|
|
596
|
+
export function createHNSWConfig(
|
|
597
|
+
base: keyof typeof hnswConfigs = 'default',
|
|
598
|
+
overrides?: Partial<HNSWConfig>
|
|
599
|
+
): HNSWConfig {
|
|
600
|
+
return {
|
|
601
|
+
...hnswConfigs[base],
|
|
602
|
+
...overrides,
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Factory function to create memory backend config
|
|
608
|
+
*/
|
|
609
|
+
export function createMemoryBackendConfig(
|
|
610
|
+
base: keyof typeof memoryBackendConfigs = 'agentDB',
|
|
611
|
+
overrides?: Partial<MemoryBackendConfig>
|
|
612
|
+
): MemoryBackendConfig {
|
|
613
|
+
return {
|
|
614
|
+
...memoryBackendConfigs[base],
|
|
615
|
+
...overrides,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Create batch of memory entries for performance testing
|
|
621
|
+
*/
|
|
622
|
+
export function createMemoryBatch(
|
|
623
|
+
count: number,
|
|
624
|
+
type: MemoryType = 'semantic',
|
|
625
|
+
dimensions: number = 384
|
|
626
|
+
): MemoryEntry[] {
|
|
627
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
628
|
+
key: `batch:entry:${i}`,
|
|
629
|
+
value: { index: i, data: `test data ${i}` },
|
|
630
|
+
metadata: {
|
|
631
|
+
type,
|
|
632
|
+
tags: ['batch', `entry-${i % 10}`],
|
|
633
|
+
},
|
|
634
|
+
embedding: generateMockEmbedding(dimensions, `batch-${i}`),
|
|
635
|
+
createdAt: new Date(),
|
|
636
|
+
updatedAt: new Date(),
|
|
637
|
+
}));
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Create embeddings batch for vector index testing
|
|
642
|
+
*/
|
|
643
|
+
export function createEmbeddingsBatch(
|
|
644
|
+
count: number,
|
|
645
|
+
dimensions: number = 384
|
|
646
|
+
): { id: string; embedding: number[] }[] {
|
|
647
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
648
|
+
id: `embedding-${i}`,
|
|
649
|
+
embedding: generateMockEmbedding(dimensions, `embedding-${i}`),
|
|
650
|
+
}));
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Invalid memory entries for error testing
|
|
655
|
+
*/
|
|
656
|
+
export const invalidMemoryEntries = {
|
|
657
|
+
emptyKey: {
|
|
658
|
+
key: '',
|
|
659
|
+
value: { data: 'test' },
|
|
660
|
+
metadata: { type: 'short-term' as const, tags: [] },
|
|
661
|
+
createdAt: new Date(),
|
|
662
|
+
updatedAt: new Date(),
|
|
663
|
+
},
|
|
664
|
+
|
|
665
|
+
nullValue: {
|
|
666
|
+
key: 'valid-key',
|
|
667
|
+
value: null,
|
|
668
|
+
metadata: { type: 'short-term' as const, tags: [] },
|
|
669
|
+
createdAt: new Date(),
|
|
670
|
+
updatedAt: new Date(),
|
|
671
|
+
},
|
|
672
|
+
|
|
673
|
+
invalidEmbeddingDimension: {
|
|
674
|
+
key: 'valid-key',
|
|
675
|
+
value: { data: 'test' },
|
|
676
|
+
metadata: { type: 'semantic' as const, tags: [] },
|
|
677
|
+
embedding: [0.1, 0.2], // Wrong dimension
|
|
678
|
+
createdAt: new Date(),
|
|
679
|
+
updatedAt: new Date(),
|
|
680
|
+
},
|
|
681
|
+
|
|
682
|
+
expiredEntry: {
|
|
683
|
+
key: 'expired-key',
|
|
684
|
+
value: { data: 'expired' },
|
|
685
|
+
metadata: { type: 'short-term' as const, tags: [], ttl: -1000 },
|
|
686
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
687
|
+
updatedAt: new Date('2024-01-01T00:00:00Z'),
|
|
688
|
+
expiresAt: new Date('2024-01-01T00:01:00Z'),
|
|
689
|
+
},
|
|
690
|
+
|
|
691
|
+
invalidTags: {
|
|
692
|
+
key: 'invalid-tags',
|
|
693
|
+
value: { data: 'test' },
|
|
694
|
+
metadata: { type: 'short-term' as const, tags: null as unknown as string[] },
|
|
695
|
+
createdAt: new Date(),
|
|
696
|
+
updatedAt: new Date(),
|
|
697
|
+
},
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Mock memory service interface
|
|
702
|
+
*/
|
|
703
|
+
export interface MockMemoryService {
|
|
704
|
+
store: Mock<(key: string, value: unknown, metadata?: MemoryMetadata) => Promise<void>>;
|
|
705
|
+
retrieve: Mock<(key: string) => Promise<unknown>>;
|
|
706
|
+
search: Mock<(query: VectorQuery) => Promise<SearchResult[]>>;
|
|
707
|
+
delete: Mock<(key: string) => Promise<void>>;
|
|
708
|
+
clear: Mock<() => Promise<void>>;
|
|
709
|
+
getStats: Mock<() => Promise<{ totalEntries: number; sizeBytes: number }>>;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Create a mock memory service
|
|
714
|
+
*/
|
|
715
|
+
export function createMockMemoryService(): MockMemoryService {
|
|
716
|
+
return {
|
|
717
|
+
store: vi.fn().mockResolvedValue(undefined),
|
|
718
|
+
retrieve: vi.fn().mockResolvedValue(null),
|
|
719
|
+
search: vi.fn().mockResolvedValue([]),
|
|
720
|
+
delete: vi.fn().mockResolvedValue(undefined),
|
|
721
|
+
clear: vi.fn().mockResolvedValue(undefined),
|
|
722
|
+
getStats: vi.fn().mockResolvedValue({ totalEntries: 0, sizeBytes: 0 }),
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Mock AgentDB interface
|
|
728
|
+
*/
|
|
729
|
+
export interface MockAgentDB {
|
|
730
|
+
insert: Mock<(id: string, embedding: number[], metadata?: unknown) => Promise<void>>;
|
|
731
|
+
search: Mock<(embedding: number[], k: number) => Promise<SearchResult[]>>;
|
|
732
|
+
delete: Mock<(id: string) => Promise<void>>;
|
|
733
|
+
update: Mock<(id: string, embedding: number[], metadata?: unknown) => Promise<void>>;
|
|
734
|
+
getStats: Mock<() => Promise<{ vectorCount: number; indexSize: number }>>;
|
|
735
|
+
rebuildIndex: Mock<() => Promise<void>>;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Create a mock AgentDB instance
|
|
740
|
+
*/
|
|
741
|
+
export function createMockAgentDB(): MockAgentDB {
|
|
742
|
+
return {
|
|
743
|
+
insert: vi.fn().mockResolvedValue(undefined),
|
|
744
|
+
search: vi.fn().mockResolvedValue([]),
|
|
745
|
+
delete: vi.fn().mockResolvedValue(undefined),
|
|
746
|
+
update: vi.fn().mockResolvedValue(undefined),
|
|
747
|
+
getStats: vi.fn().mockResolvedValue({ vectorCount: 0, indexSize: 0 }),
|
|
748
|
+
rebuildIndex: vi.fn().mockResolvedValue(undefined),
|
|
749
|
+
};
|
|
750
|
+
}
|