lynkr 8.0.0 → 8.0.1

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.
Files changed (102) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/api/openai-router.js +34 -2
  4. package/src/clients/standard-tools.js +23 -0
  5. package/src/config/index.js +20 -0
  6. package/src/orchestrator/index.js +2 -2
  7. package/src/server.js +2 -12
  8. package/src/tools/index.js +4 -0
  9. package/src/tools/lazy-loader.js +7 -0
  10. package/src/tools/tinyfish.js +358 -0
  11. package/src/tools/truncate.js +1 -0
  12. package/.github/FUNDING.yml +0 -15
  13. package/.github/workflows/README.md +0 -215
  14. package/.github/workflows/ci.yml +0 -69
  15. package/.github/workflows/index.yml +0 -62
  16. package/.github/workflows/web-tools-tests.yml +0 -56
  17. package/CITATIONS.bib +0 -6
  18. package/DEPLOYMENT.md +0 -1001
  19. package/LYNKR-TUI-PLAN.md +0 -984
  20. package/PERFORMANCE-REPORT.md +0 -866
  21. package/PLAN-per-client-model-routing.md +0 -252
  22. package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
  23. package/docs/BingSiteAuth.xml +0 -4
  24. package/docs/docs-style.css +0 -478
  25. package/docs/docs.html +0 -198
  26. package/docs/google5be250e608e6da39.html +0 -1
  27. package/docs/index.html +0 -577
  28. package/docs/index.md +0 -584
  29. package/docs/robots.txt +0 -4
  30. package/docs/sitemap.xml +0 -44
  31. package/docs/style.css +0 -1223
  32. package/docs/toon-integration-spec.md +0 -130
  33. package/documentation/README.md +0 -101
  34. package/documentation/api.md +0 -806
  35. package/documentation/claude-code-cli.md +0 -679
  36. package/documentation/codex-cli.md +0 -397
  37. package/documentation/contributing.md +0 -571
  38. package/documentation/cursor-integration.md +0 -734
  39. package/documentation/docker.md +0 -874
  40. package/documentation/embeddings.md +0 -762
  41. package/documentation/faq.md +0 -713
  42. package/documentation/features.md +0 -403
  43. package/documentation/headroom.md +0 -519
  44. package/documentation/installation.md +0 -758
  45. package/documentation/memory-system.md +0 -476
  46. package/documentation/production.md +0 -636
  47. package/documentation/providers.md +0 -1009
  48. package/documentation/routing.md +0 -476
  49. package/documentation/testing.md +0 -629
  50. package/documentation/token-optimization.md +0 -325
  51. package/documentation/tools.md +0 -697
  52. package/documentation/troubleshooting.md +0 -969
  53. package/final-test.js +0 -33
  54. package/headroom-sidecar/config.py +0 -93
  55. package/headroom-sidecar/requirements.txt +0 -14
  56. package/headroom-sidecar/server.py +0 -451
  57. package/monitor-agents.sh +0 -31
  58. package/scripts/audit-log-reader.js +0 -399
  59. package/scripts/compact-dictionary.js +0 -204
  60. package/scripts/test-deduplication.js +0 -448
  61. package/src/db/database.sqlite +0 -0
  62. package/te +0 -11622
  63. package/test/README.md +0 -212
  64. package/test/azure-openai-config.test.js +0 -213
  65. package/test/azure-openai-error-resilience.test.js +0 -238
  66. package/test/azure-openai-format-conversion.test.js +0 -354
  67. package/test/azure-openai-integration.test.js +0 -287
  68. package/test/azure-openai-routing.test.js +0 -175
  69. package/test/azure-openai-streaming.test.js +0 -171
  70. package/test/bedrock-integration.test.js +0 -457
  71. package/test/comprehensive-test-suite.js +0 -928
  72. package/test/config-validation.test.js +0 -207
  73. package/test/cursor-integration.test.js +0 -484
  74. package/test/format-conversion.test.js +0 -578
  75. package/test/hybrid-routing-integration.test.js +0 -269
  76. package/test/hybrid-routing-performance.test.js +0 -428
  77. package/test/llamacpp-integration.test.js +0 -882
  78. package/test/lmstudio-integration.test.js +0 -347
  79. package/test/memory/extractor.test.js +0 -398
  80. package/test/memory/retriever.test.js +0 -613
  81. package/test/memory/retriever.test.js.bak +0 -585
  82. package/test/memory/search.test.js +0 -537
  83. package/test/memory/search.test.js.bak +0 -389
  84. package/test/memory/store.test.js +0 -344
  85. package/test/memory/store.test.js.bak +0 -312
  86. package/test/memory/surprise.test.js +0 -300
  87. package/test/memory-performance.test.js +0 -472
  88. package/test/openai-integration.test.js +0 -683
  89. package/test/openrouter-error-resilience.test.js +0 -418
  90. package/test/passthrough-mode.test.js +0 -385
  91. package/test/performance-benchmark.js +0 -351
  92. package/test/performance-tests.js +0 -528
  93. package/test/routing.test.js +0 -225
  94. package/test/toon-compression.test.js +0 -131
  95. package/test/web-tools.test.js +0 -329
  96. package/test-agents-simple.js +0 -43
  97. package/test-cli-connection.sh +0 -33
  98. package/test-learning-unit.js +0 -126
  99. package/test-learning.js +0 -112
  100. package/test-parallel-agents.sh +0 -124
  101. package/test-parallel-direct.js +0 -155
  102. package/test-subagents.sh +0 -117
@@ -1,472 +0,0 @@
1
- /**
2
- * Performance Tests for Titans-Inspired Long-Term Memory System
3
- *
4
- * Performance Targets:
5
- * - Retrieval latency: <50ms for top 10 memories
6
- * - Extraction latency: <100ms (async, non-blocking)
7
- * - Memory overhead: <50MB for 10K memories
8
- * - Database size: ~100 bytes per memory
9
- */
10
-
11
- const assert = require("assert");
12
- const fs = require("fs");
13
- const path = require("path");
14
-
15
- // Test configuration
16
- const PERFORMANCE_TARGETS = {
17
- retrievalLatencyMs: 50,
18
- extractionLatencyMs: 100,
19
- storageLatencyMs: 10,
20
- searchLatencyMs: 50,
21
- memoryOverheadMb: 50,
22
- bytesPerMemory: 200, // Conservative estimate
23
- };
24
-
25
- const TEST_SIZES = {
26
- small: 100,
27
- medium: 1000,
28
- large: 10000,
29
- };
30
-
31
- console.log("=".repeat(80));
32
- console.log("Memory System Performance Tests");
33
- console.log("=".repeat(80));
34
- console.log();
35
-
36
- // Setup test environment
37
- const testDbPath = path.join(__dirname, `../data/perf-test-${Date.now()}.db`);
38
- process.env.DB_PATH = testDbPath;
39
- process.env.MEMORY_ENABLED = "true";
40
- process.env.MEMORY_SURPRISE_THRESHOLD = "0.3";
41
-
42
- // Clear module cache
43
- Object.keys(require.cache).forEach(key => {
44
- if (key.includes('/src/')) {
45
- delete require.cache[key];
46
- }
47
- });
48
-
49
- // Initialize modules
50
- const db = require("../src/db");
51
- const store = require("../src/memory/store");
52
- const search = require("../src/memory/search");
53
- const retriever = require("../src/memory/retriever");
54
- const surprise = require("../src/memory/surprise");
55
- const extractor = require("../src/memory/extractor");
56
-
57
- /**
58
- * Measure execution time
59
- */
60
- function measureTime(fn) {
61
- const start = process.hrtime.bigint();
62
- const result = fn();
63
- const end = process.hrtime.bigint();
64
- const durationMs = Number(end - start) / 1_000_000;
65
- return { result, durationMs };
66
- }
67
-
68
- /**
69
- * Measure async execution time
70
- */
71
- async function measureTimeAsync(fn) {
72
- const start = process.hrtime.bigint();
73
- const result = await fn();
74
- const end = process.hrtime.bigint();
75
- const durationMs = Number(end - start) / 1_000_000;
76
- return { result, durationMs };
77
- }
78
-
79
- /**
80
- * Create test memories
81
- */
82
- function createTestMemories(count) {
83
- const memories = [];
84
- const types = ['preference', 'decision', 'fact', 'entity', 'relationship'];
85
- const categories = ['user', 'code', 'project', 'general'];
86
-
87
- console.log(`Creating ${count} test memories...`);
88
- const start = Date.now();
89
-
90
- for (let i = 0; i < count; i++) {
91
- const type = types[i % types.length];
92
- const category = categories[i % categories.length];
93
-
94
- const memory = store.createMemory({
95
- content: `Test memory ${i}: This is about ${type} in ${category} with various keywords like Python JavaScript TypeScript React Express`,
96
- type,
97
- category,
98
- importance: Math.random(),
99
- surpriseScore: Math.random(),
100
- sessionId: null,
101
- });
102
-
103
- memories.push(memory);
104
-
105
- if ((i + 1) % 1000 === 0) {
106
- process.stdout.write(` Created ${i + 1}/${count}...\r`);
107
- }
108
- }
109
-
110
- const duration = Date.now() - start;
111
- console.log(` Created ${count} memories in ${duration}ms (${(duration/count).toFixed(2)}ms per memory)`);
112
- console.log();
113
-
114
- return memories;
115
- }
116
-
117
- /**
118
- * Test 1: Memory Creation Performance
119
- */
120
- function testCreationPerformance() {
121
- console.log("Test 1: Memory Creation Performance");
122
- console.log("-".repeat(60));
123
-
124
- const { durationMs } = measureTime(() => {
125
- return store.createMemory({
126
- content: "User prefers Python for data processing with pandas and numpy libraries",
127
- type: "preference",
128
- category: "user",
129
- importance: 0.8,
130
- surpriseScore: 0.6,
131
- });
132
- });
133
-
134
- console.log(` Single memory creation: ${durationMs.toFixed(2)}ms`);
135
-
136
- if (durationMs < PERFORMANCE_TARGETS.storageLatencyMs) {
137
- console.log(` ✓ PASS: Under ${PERFORMANCE_TARGETS.storageLatencyMs}ms target`);
138
- } else {
139
- console.log(` ✗ FAIL: Exceeds ${PERFORMANCE_TARGETS.storageLatencyMs}ms target`);
140
- }
141
-
142
- console.log();
143
- return durationMs < PERFORMANCE_TARGETS.storageLatencyMs;
144
- }
145
-
146
- /**
147
- * Test 2: Retrieval Performance at Scale
148
- */
149
- function testRetrievalPerformance(memoryCount) {
150
- console.log(`Test 2: Retrieval Performance (${memoryCount} memories)`);
151
- console.log("-".repeat(60));
152
-
153
- createTestMemories(memoryCount);
154
-
155
- // Test retrieval
156
- const queries = [
157
- "Python programming",
158
- "JavaScript framework",
159
- "database connection",
160
- "user authentication",
161
- "API endpoint",
162
- ];
163
-
164
- const results = [];
165
-
166
- for (const query of queries) {
167
- const { result, durationMs } = measureTime(() => {
168
- return retriever.retrieveRelevantMemories(query, { limit: 10 });
169
- });
170
-
171
- results.push({ query, durationMs, count: result.length });
172
- console.log(` "${query}": ${durationMs.toFixed(2)}ms (${result.length} results)`);
173
- }
174
-
175
- const avgDuration = results.reduce((sum, r) => sum + r.durationMs, 0) / results.length;
176
- console.log(` Average retrieval time: ${avgDuration.toFixed(2)}ms`);
177
-
178
- if (avgDuration < PERFORMANCE_TARGETS.retrievalLatencyMs) {
179
- console.log(` ✓ PASS: Under ${PERFORMANCE_TARGETS.retrievalLatencyMs}ms target`);
180
- } else {
181
- console.log(` ✗ FAIL: Exceeds ${PERFORMANCE_TARGETS.retrievalLatencyMs}ms target`);
182
- }
183
-
184
- console.log();
185
- return avgDuration < PERFORMANCE_TARGETS.retrievalLatencyMs;
186
- }
187
-
188
- /**
189
- * Test 3: FTS5 Search Performance
190
- */
191
- function testSearchPerformance(memoryCount) {
192
- console.log(`Test 3: FTS5 Search Performance (${memoryCount} memories)`);
193
- console.log("-".repeat(60));
194
-
195
- const queries = [
196
- "Python",
197
- "framework AND JavaScript",
198
- "database OR connection",
199
- "user authentication security",
200
- ];
201
-
202
- const results = [];
203
-
204
- for (const query of queries) {
205
- const { result, durationMs } = measureTime(() => {
206
- return search.searchMemories({ query, limit: 20 });
207
- });
208
-
209
- results.push({ query, durationMs, count: result.length });
210
- console.log(` "${query}": ${durationMs.toFixed(2)}ms (${result.length} results)`);
211
- }
212
-
213
- const avgDuration = results.reduce((sum, r) => sum + r.durationMs, 0) / results.length;
214
- console.log(` Average search time: ${avgDuration.toFixed(2)}ms`);
215
-
216
- if (avgDuration < PERFORMANCE_TARGETS.searchLatencyMs) {
217
- console.log(` ✓ PASS: Under ${PERFORMANCE_TARGETS.searchLatencyMs}ms target`);
218
- } else {
219
- console.log(` ✗ FAIL: Exceeds ${PERFORMANCE_TARGETS.searchLatencyMs}ms target`);
220
- }
221
-
222
- console.log();
223
- return avgDuration < PERFORMANCE_TARGETS.searchLatencyMs;
224
- }
225
-
226
- /**
227
- * Test 4: Surprise Calculation Performance
228
- */
229
- function testSurprisePerformance() {
230
- console.log("Test 4: Surprise Calculation Performance");
231
- console.log("-".repeat(60));
232
-
233
- const existingMemories = store.getRecentMemories({ limit: 100 });
234
-
235
- const testCases = [
236
- "User prefers Rust for systems programming with zero-cost abstractions",
237
- "This project uses GraphQL with Apollo Server and PostgreSQL database",
238
- "IMPORTANT: Always validate input to prevent SQL injection attacks",
239
- ];
240
-
241
- const results = [];
242
-
243
- for (const content of testCases) {
244
- const { result, durationMs } = measureTime(() => {
245
- return surprise.calculateSurprise(
246
- { content, type: "fact", category: "code" },
247
- existingMemories,
248
- { userContent: content }
249
- );
250
- });
251
-
252
- results.push({ durationMs, score: result });
253
- console.log(` Surprise calculation: ${durationMs.toFixed(2)}ms (score: ${result.toFixed(3)})`);
254
- }
255
-
256
- const avgDuration = results.reduce((sum, r) => sum + r.durationMs, 0) / results.length;
257
- console.log(` Average surprise calculation: ${avgDuration.toFixed(2)}ms`);
258
-
259
- // Surprise calculation should be fast (<10ms)
260
- const passThreshold = 10;
261
- if (avgDuration < passThreshold) {
262
- console.log(` ✓ PASS: Under ${passThreshold}ms target`);
263
- } else {
264
- console.log(` ✗ FAIL: Exceeds ${passThreshold}ms target`);
265
- }
266
-
267
- console.log();
268
- return avgDuration < passThreshold;
269
- }
270
-
271
- /**
272
- * Test 5: Memory Extraction Performance
273
- */
274
- async function testExtractionPerformance() {
275
- console.log("Test 5: Memory Extraction Performance");
276
- console.log("-".repeat(60));
277
-
278
- const testResponses = [
279
- {
280
- role: "assistant",
281
- content: "I understand that you prefer Python for data processing and always use pandas for DataFrame operations. We decided to implement the API using FastAPI framework with async/await patterns."
282
- },
283
- {
284
- role: "assistant",
285
- content: "This project uses TypeScript with strict mode, ESLint for linting, and Jest for testing. The database connection uses connection pooling with max 20 connections."
286
- },
287
- {
288
- role: "assistant",
289
- content: "IMPORTANT: User wants detailed error messages in development but minimal info in production. The authentication system must use JWT tokens with 1-hour expiration."
290
- },
291
- ];
292
-
293
- const results = [];
294
-
295
- for (const response of testResponses) {
296
- const { result, durationMs } = await measureTimeAsync(async () => {
297
- return await extractor.extractMemories(response, [], { sessionId: null });
298
- });
299
-
300
- results.push({ durationMs, count: result.length });
301
- console.log(` Extraction: ${durationMs.toFixed(2)}ms (${result.length} memories extracted)`);
302
- }
303
-
304
- const avgDuration = results.reduce((sum, r) => sum + r.durationMs, 0) / results.length;
305
- console.log(` Average extraction time: ${avgDuration.toFixed(2)}ms`);
306
-
307
- if (avgDuration < PERFORMANCE_TARGETS.extractionLatencyMs) {
308
- console.log(` ✓ PASS: Under ${PERFORMANCE_TARGETS.extractionLatencyMs}ms target`);
309
- } else {
310
- console.log(` ✗ FAIL: Exceeds ${PERFORMANCE_TARGETS.extractionLatencyMs}ms target`);
311
- }
312
-
313
- console.log();
314
- return avgDuration < PERFORMANCE_TARGETS.extractionLatencyMs;
315
- }
316
-
317
- /**
318
- * Test 6: Database Size and Memory Overhead
319
- */
320
- function testStorageEfficiency(memoryCount) {
321
- console.log(`Test 6: Storage Efficiency (${memoryCount} memories)`);
322
- console.log("-".repeat(60));
323
-
324
- // Get the actual database path used
325
- const actualDbPath = require("../src/config").dbPath;
326
-
327
- if (!fs.existsSync(actualDbPath)) {
328
- console.log(` ⚠ SKIP: Database file not found at ${actualDbPath}`);
329
- console.log();
330
- return true; // Skip, don't fail
331
- }
332
-
333
- const stats = fs.statSync(actualDbPath);
334
- const sizeMb = stats.size / (1024 * 1024);
335
- const bytesPerMemory = memoryCount > 0 ? stats.size / memoryCount : 0;
336
-
337
- console.log(` Database size: ${sizeMb.toFixed(2)} MB`);
338
- console.log(` Bytes per memory: ${bytesPerMemory.toFixed(0)} bytes`);
339
- console.log(` Total memories: ${memoryCount}`);
340
-
341
- if (bytesPerMemory < PERFORMANCE_TARGETS.bytesPerMemory) {
342
- console.log(` ✓ PASS: Under ${PERFORMANCE_TARGETS.bytesPerMemory} bytes per memory target`);
343
- } else {
344
- console.log(` ✗ FAIL: Exceeds ${PERFORMANCE_TARGETS.bytesPerMemory} bytes per memory target`);
345
- }
346
-
347
- console.log();
348
- return bytesPerMemory < PERFORMANCE_TARGETS.bytesPerMemory;
349
- }
350
-
351
- /**
352
- * Test 7: Concurrent Access Performance
353
- */
354
- function testConcurrentAccess() {
355
- console.log("Test 7: Concurrent Access Performance");
356
- console.log("-".repeat(60));
357
-
358
- const queries = Array.from({ length: 10 }, (_, i) => `query${i}`);
359
-
360
- const start = process.hrtime.bigint();
361
-
362
- const results = queries.map(query => {
363
- return retriever.retrieveRelevantMemories(query, { limit: 5 });
364
- });
365
-
366
- const end = process.hrtime.bigint();
367
- const durationMs = Number(end - start) / 1_000_000;
368
-
369
- console.log(` 10 concurrent retrievals: ${durationMs.toFixed(2)}ms`);
370
- console.log(` Average per retrieval: ${(durationMs / 10).toFixed(2)}ms`);
371
-
372
- const passThreshold = 100;
373
- if (durationMs < passThreshold) {
374
- console.log(` ✓ PASS: Under ${passThreshold}ms for 10 concurrent queries`);
375
- } else {
376
- console.log(` ✗ FAIL: Exceeds ${passThreshold}ms for 10 concurrent queries`);
377
- }
378
-
379
- console.log();
380
- return durationMs < passThreshold;
381
- }
382
-
383
- /**
384
- * Run all performance tests
385
- */
386
- async function runPerformanceTests() {
387
- console.log(`Starting at: ${new Date().toISOString()}`);
388
- console.log();
389
-
390
- const results = {
391
- creation: false,
392
- retrieval: false,
393
- search: false,
394
- surprise: false,
395
- extraction: false,
396
- storage: false,
397
- concurrent: false,
398
- };
399
-
400
- try {
401
- // Test 1: Creation
402
- results.creation = testCreationPerformance();
403
-
404
- // Test 2: Retrieval (with 1000 memories)
405
- results.retrieval = testRetrievalPerformance(TEST_SIZES.medium);
406
-
407
- // Test 3: Search
408
- results.search = testSearchPerformance(TEST_SIZES.medium);
409
-
410
- // Test 4: Surprise
411
- results.surprise = testSurprisePerformance();
412
-
413
- // Test 5: Extraction
414
- results.extraction = await testExtractionPerformance();
415
-
416
- // Test 6: Storage efficiency
417
- const totalMemories = store.countMemories();
418
- results.storage = testStorageEfficiency(totalMemories);
419
-
420
- // Test 7: Concurrent access
421
- results.concurrent = testConcurrentAccess();
422
-
423
- // Summary
424
- console.log("=".repeat(80));
425
- console.log("Performance Test Summary");
426
- console.log("=".repeat(80));
427
- console.log();
428
-
429
- const passCount = Object.values(results).filter(Boolean).length;
430
- const totalTests = Object.keys(results).length;
431
-
432
- Object.entries(results).forEach(([test, passed]) => {
433
- console.log(` ${passed ? '✓' : '✗'} ${test.padEnd(20)} ${passed ? 'PASS' : 'FAIL'}`);
434
- });
435
-
436
- console.log();
437
- console.log(`Total: ${passCount}/${totalTests} tests passed`);
438
- console.log();
439
-
440
- if (passCount === totalTests) {
441
- console.log("✓ All performance tests PASSED");
442
- return 0;
443
- } else {
444
- console.log(`✗ ${totalTests - passCount} performance tests FAILED`);
445
- return 1;
446
- }
447
-
448
- } catch (err) {
449
- console.error("Performance test error:", err);
450
- return 1;
451
- } finally {
452
- // Cleanup
453
- try {
454
- if (fs.existsSync(testDbPath)) {
455
- fs.unlinkSync(testDbPath);
456
- console.log(`Cleaned up test database: ${testDbPath}`);
457
- }
458
- } catch (err) {
459
- console.error("Cleanup error:", err);
460
- }
461
- }
462
- }
463
-
464
- // Run tests
465
- runPerformanceTests()
466
- .then(exitCode => {
467
- process.exit(exitCode);
468
- })
469
- .catch(err => {
470
- console.error("Fatal error:", err);
471
- process.exit(1);
472
- });