cognitive-core 0.0.2 → 0.1.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/README.md +302 -116
- package/SKILL.md +193 -0
- package/dist/agents/index.d.ts +3 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/mock-provider.d.ts +23 -0
- package/dist/agents/mock-provider.d.ts.map +1 -0
- package/dist/agents/mock-provider.js +71 -0
- package/dist/agents/mock-provider.js.map +1 -0
- package/dist/agents/types.d.ts +98 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +44 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/atlas.d.ts +196 -0
- package/dist/atlas.d.ts.map +1 -0
- package/dist/atlas.js +373 -0
- package/dist/atlas.js.map +1 -0
- package/dist/bin/cognitive-core.d.ts +18 -0
- package/dist/bin/cognitive-core.d.ts.map +1 -0
- package/dist/bin/cognitive-core.js +419 -0
- package/dist/bin/cognitive-core.js.map +1 -0
- package/dist/embeddings/bm25.d.ts +104 -0
- package/dist/embeddings/bm25.d.ts.map +1 -0
- package/dist/embeddings/bm25.js +264 -0
- package/dist/embeddings/bm25.js.map +1 -0
- package/dist/embeddings/index.d.ts +12 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +16 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/manager.d.ts +112 -0
- package/dist/embeddings/manager.d.ts.map +1 -0
- package/dist/embeddings/manager.js +215 -0
- package/dist/embeddings/manager.js.map +1 -0
- package/dist/embeddings/provider.d.ts +101 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +232 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/embeddings/vector-store.d.ts +101 -0
- package/dist/embeddings/vector-store.d.ts.map +1 -0
- package/dist/embeddings/vector-store.js +256 -0
- package/dist/embeddings/vector-store.js.map +1 -0
- package/dist/factory.d.ts +193 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +109 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +30 -453
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -509
- package/dist/index.js.map +1 -0
- package/dist/learning/analyzer.d.ts +110 -0
- package/dist/learning/analyzer.d.ts.map +1 -0
- package/dist/learning/analyzer.js +213 -0
- package/dist/learning/analyzer.js.map +1 -0
- package/dist/learning/effectiveness.d.ts +158 -0
- package/dist/learning/effectiveness.d.ts.map +1 -0
- package/dist/learning/effectiveness.js +251 -0
- package/dist/learning/effectiveness.js.map +1 -0
- package/dist/learning/index.d.ts +8 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +11 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/llm-extractor.d.ts +88 -0
- package/dist/learning/llm-extractor.d.ts.map +1 -0
- package/dist/learning/llm-extractor.js +372 -0
- package/dist/learning/llm-extractor.js.map +1 -0
- package/dist/learning/meta-learner.d.ts +80 -0
- package/dist/learning/meta-learner.d.ts.map +1 -0
- package/dist/learning/meta-learner.js +355 -0
- package/dist/learning/meta-learner.js.map +1 -0
- package/dist/learning/pipeline.d.ts +65 -0
- package/dist/learning/pipeline.d.ts.map +1 -0
- package/dist/learning/pipeline.js +170 -0
- package/dist/learning/pipeline.js.map +1 -0
- package/dist/learning/playbook-extractor.d.ts +113 -0
- package/dist/learning/playbook-extractor.d.ts.map +1 -0
- package/dist/learning/playbook-extractor.js +523 -0
- package/dist/learning/playbook-extractor.js.map +1 -0
- package/dist/learning/usage-inference.d.ts +82 -0
- package/dist/learning/usage-inference.d.ts.map +1 -0
- package/dist/learning/usage-inference.js +261 -0
- package/dist/learning/usage-inference.js.map +1 -0
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +6 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/playbook-server.d.ts +120 -0
- package/dist/mcp/playbook-server.d.ts.map +1 -0
- package/dist/mcp/playbook-server.js +427 -0
- package/dist/mcp/playbook-server.js.map +1 -0
- package/dist/memory/curated-loader.d.ts +62 -0
- package/dist/memory/curated-loader.d.ts.map +1 -0
- package/dist/memory/curated-loader.js +106 -0
- package/dist/memory/curated-loader.js.map +1 -0
- package/dist/memory/experience.d.ts +122 -0
- package/dist/memory/experience.d.ts.map +1 -0
- package/dist/memory/experience.js +392 -0
- package/dist/memory/experience.js.map +1 -0
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +9 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/meta.d.ts +90 -0
- package/dist/memory/meta.d.ts.map +1 -0
- package/dist/memory/meta.js +362 -0
- package/dist/memory/meta.js.map +1 -0
- package/dist/memory/playbook.d.ts +133 -0
- package/dist/memory/playbook.d.ts.map +1 -0
- package/dist/memory/playbook.js +357 -0
- package/dist/memory/playbook.js.map +1 -0
- package/dist/memory/system.d.ts +167 -0
- package/dist/memory/system.d.ts.map +1 -0
- package/dist/memory/system.js +383 -0
- package/dist/memory/system.js.map +1 -0
- package/dist/runtime/backends/acp.d.ts +67 -0
- package/dist/runtime/backends/acp.d.ts.map +1 -0
- package/dist/runtime/backends/acp.js +290 -0
- package/dist/runtime/backends/acp.js.map +1 -0
- package/dist/runtime/backends/index.d.ts +5 -0
- package/dist/runtime/backends/index.d.ts.map +1 -0
- package/dist/runtime/backends/index.js +6 -0
- package/dist/runtime/backends/index.js.map +1 -0
- package/dist/runtime/backends/mock.d.ts +67 -0
- package/dist/runtime/backends/mock.d.ts.map +1 -0
- package/dist/runtime/backends/mock.js +153 -0
- package/dist/runtime/backends/mock.js.map +1 -0
- package/dist/runtime/backends/subprocess.d.ts +56 -0
- package/dist/runtime/backends/subprocess.d.ts.map +1 -0
- package/dist/runtime/backends/subprocess.js +260 -0
- package/dist/runtime/backends/subprocess.js.map +1 -0
- package/dist/runtime/flows/learning.d.ts +73 -0
- package/dist/runtime/flows/learning.d.ts.map +1 -0
- package/dist/runtime/flows/learning.js +116 -0
- package/dist/runtime/flows/learning.js.map +1 -0
- package/dist/runtime/flows/validation.d.ts +122 -0
- package/dist/runtime/flows/validation.d.ts.map +1 -0
- package/dist/runtime/flows/validation.js +223 -0
- package/dist/runtime/flows/validation.js.map +1 -0
- package/dist/runtime/index.d.ts +6 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/manager.d.ts +116 -0
- package/dist/runtime/manager.d.ts.map +1 -0
- package/dist/runtime/manager.js +416 -0
- package/dist/runtime/manager.js.map +1 -0
- package/dist/runtime/types.d.ts +138 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/search/evaluator.d.ts +102 -0
- package/dist/search/evaluator.d.ts.map +1 -0
- package/dist/search/evaluator.js +352 -0
- package/dist/search/evaluator.js.map +1 -0
- package/dist/search/index.d.ts +7 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +11 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/refinement-loop.d.ts +73 -0
- package/dist/search/refinement-loop.d.ts.map +1 -0
- package/dist/search/refinement-loop.js +245 -0
- package/dist/search/refinement-loop.js.map +1 -0
- package/dist/search/refinement-types.d.ts +154 -0
- package/dist/search/refinement-types.d.ts.map +1 -0
- package/dist/search/refinement-types.js +99 -0
- package/dist/search/refinement-types.js.map +1 -0
- package/dist/search/router.d.ts +61 -0
- package/dist/search/router.d.ts.map +1 -0
- package/dist/search/router.js +197 -0
- package/dist/search/router.js.map +1 -0
- package/dist/search/solver.d.ts +75 -0
- package/dist/search/solver.d.ts.map +1 -0
- package/dist/search/solver.js +216 -0
- package/dist/search/solver.js.map +1 -0
- package/dist/search/verification-runner.d.ts +125 -0
- package/dist/search/verification-runner.d.ts.map +1 -0
- package/dist/search/verification-runner.js +440 -0
- package/dist/search/verification-runner.js.map +1 -0
- package/dist/surfacing/index.d.ts +2 -0
- package/dist/surfacing/index.d.ts.map +1 -0
- package/dist/surfacing/index.js +2 -0
- package/dist/surfacing/index.js.map +1 -0
- package/dist/surfacing/skill-library.d.ts +158 -0
- package/dist/surfacing/skill-library.d.ts.map +1 -0
- package/dist/surfacing/skill-library.js +429 -0
- package/dist/surfacing/skill-library.js.map +1 -0
- package/dist/types/config.d.ts +1113 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +274 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/memory.d.ts +339 -0
- package/dist/types/memory.d.ts.map +1 -0
- package/dist/types/memory.js +207 -0
- package/dist/types/memory.js.map +1 -0
- package/dist/types/meta.d.ts +146 -0
- package/dist/types/meta.d.ts.map +1 -0
- package/dist/types/meta.js +51 -0
- package/dist/types/meta.js.map +1 -0
- package/dist/types/outcome.d.ts +42 -0
- package/dist/types/outcome.d.ts.map +1 -0
- package/dist/types/outcome.js +50 -0
- package/dist/types/outcome.js.map +1 -0
- package/dist/types/playbook.d.ts +119 -0
- package/dist/types/playbook.d.ts.map +1 -0
- package/dist/types/playbook.js +71 -0
- package/dist/types/playbook.js.map +1 -0
- package/dist/types/step.d.ts +44 -0
- package/dist/types/step.d.ts.map +1 -0
- package/dist/types/step.js +32 -0
- package/dist/types/step.js.map +1 -0
- package/dist/types/task.d.ts +91 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +39 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/trajectory.d.ts +221 -0
- package/dist/types/trajectory.d.ts.map +1 -0
- package/dist/types/trajectory.js +60 -0
- package/dist/types/trajectory.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/similarity.d.ts +31 -0
- package/dist/utils/similarity.d.ts.map +1 -0
- package/dist/utils/similarity.js +107 -0
- package/dist/utils/similarity.js.map +1 -0
- package/dist/utils/storage.d.ts +106 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/storage.js +203 -0
- package/dist/utils/storage.js.map +1 -0
- package/dist/utils/validation.d.ts +129 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +171 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +50 -34
- package/scripts/migrate-to-playbooks.ts +307 -0
- package/src/agents/index.ts +14 -0
- package/src/agents/mock-provider.ts +93 -0
- package/src/agents/types.ts +137 -0
- package/src/atlas.ts +560 -0
- package/src/bin/cognitive-core.ts +470 -0
- package/src/embeddings/bm25.ts +337 -0
- package/src/embeddings/index.ts +39 -0
- package/src/embeddings/manager.ts +288 -0
- package/src/embeddings/provider.ts +311 -0
- package/src/embeddings/vector-store.ts +353 -0
- package/src/factory.ts +263 -0
- package/src/index.ts +246 -0
- package/src/learning/analyzer.ts +335 -0
- package/src/learning/effectiveness.ts +428 -0
- package/src/learning/index.ts +58 -0
- package/src/learning/llm-extractor.ts +542 -0
- package/src/learning/meta-learner.ts +516 -0
- package/src/learning/pipeline.ts +244 -0
- package/src/learning/playbook-extractor.ts +702 -0
- package/src/learning/usage-inference.ts +372 -0
- package/src/mcp/index.ts +12 -0
- package/src/mcp/playbook-server.ts +565 -0
- package/src/memory/curated-loader.ts +160 -0
- package/src/memory/experience.ts +515 -0
- package/src/memory/index.ts +27 -0
- package/src/memory/meta.ts +506 -0
- package/src/memory/playbook.ts +493 -0
- package/src/memory/system.ts +551 -0
- package/src/runtime/backends/acp.ts +378 -0
- package/src/runtime/backends/index.ts +24 -0
- package/src/runtime/backends/mock.ts +218 -0
- package/src/runtime/backends/subprocess.ts +356 -0
- package/src/runtime/flows/learning.ts +183 -0
- package/src/runtime/flows/validation.ts +381 -0
- package/src/runtime/index.ts +53 -0
- package/src/runtime/manager.ts +541 -0
- package/src/runtime/types.ts +157 -0
- package/src/search/evaluator.ts +474 -0
- package/src/search/index.ts +59 -0
- package/src/search/refinement-loop.ts +363 -0
- package/src/search/refinement-types.ts +159 -0
- package/src/search/router.ts +261 -0
- package/src/search/solver.ts +303 -0
- package/src/search/verification-runner.ts +570 -0
- package/src/surfacing/index.ts +6 -0
- package/src/surfacing/skill-library.ts +594 -0
- package/src/types/config.ts +333 -0
- package/src/types/index.ts +130 -0
- package/src/types/memory.ts +270 -0
- package/src/types/meta.ts +218 -0
- package/src/types/outcome.ts +66 -0
- package/src/types/playbook.ts +196 -0
- package/src/types/step.ts +40 -0
- package/src/types/task.ts +52 -0
- package/src/types/trajectory.ts +80 -0
- package/src/utils/index.ts +38 -0
- package/src/utils/similarity.ts +139 -0
- package/src/utils/storage.ts +249 -0
- package/src/utils/validation.ts +286 -0
- package/tests/embeddings/bm25.test.ts +130 -0
- package/tests/embeddings/manager.test.ts +205 -0
- package/tests/integration/atlas.test.ts +266 -0
- package/tests/integration/e2e.test.ts +929 -0
- package/tests/learning/analyzer.test.ts +426 -0
- package/tests/learning/effectiveness.test.ts +542 -0
- package/tests/learning/pipeline.test.ts +176 -0
- package/tests/learning/playbook-extractor-provenance.test.ts +114 -0
- package/tests/learning/usage-inference.test.ts +254 -0
- package/tests/mcp/playbook-server.test.ts +252 -0
- package/tests/memory/experience.test.ts +198 -0
- package/tests/memory/playbook.test.ts +338 -0
- package/tests/memory/provenance.test.ts +639 -0
- package/tests/memory/system.test.ts +325 -0
- package/tests/runtime/agent-manager.test.ts +512 -0
- package/tests/runtime/mock-backend.test.ts +248 -0
- package/tests/search/refinement-loop.test.ts +468 -0
- package/tests/search/refinement.test.ts +267 -0
- package/tests/search/router.test.ts +427 -0
- package/tests/surfacing/skill-library.test.ts +292 -0
- package/tests/types/outcome.test.ts +147 -0
- package/tests/types/step.test.ts +133 -0
- package/tests/types/task.test.ts +158 -0
- package/tests/types/trajectory.test.ts +253 -0
- package/tests/utils/similarity.test.ts +188 -0
- package/tests/utils/validation.test.ts +252 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +22 -0
- package/dist/index.d.mts +0 -466
- package/dist/index.mjs +0 -478
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { EmbeddingManager, createEmbeddingManager } from '../../src/embeddings/manager.js';
|
|
3
|
+
import type { EmbeddingProvider } from '../../src/embeddings/provider.js';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
|
|
7
|
+
// Mock embedding provider for testing
|
|
8
|
+
class MockEmbeddingProvider implements EmbeddingProvider {
|
|
9
|
+
readonly name = 'mock';
|
|
10
|
+
readonly dimension = 3;
|
|
11
|
+
private callCount = 0;
|
|
12
|
+
|
|
13
|
+
async embed(text: string): Promise<number[]> {
|
|
14
|
+
this.callCount++;
|
|
15
|
+
// Simple hash-based embedding for deterministic testing
|
|
16
|
+
const hash = text.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
17
|
+
return [
|
|
18
|
+
Math.sin(hash * 0.1),
|
|
19
|
+
Math.cos(hash * 0.2),
|
|
20
|
+
Math.sin(hash * 0.3),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async embedBatch(texts: string[]): Promise<number[][]> {
|
|
25
|
+
return Promise.all(texts.map(t => this.embed(t)));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getCallCount(): number {
|
|
29
|
+
return this.callCount;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('EmbeddingManager', () => {
|
|
34
|
+
const testDbPath = '/tmp/test-embeddings.db';
|
|
35
|
+
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
// Clean up test database
|
|
38
|
+
try {
|
|
39
|
+
fs.unlinkSync(testDbPath);
|
|
40
|
+
} catch {
|
|
41
|
+
// Ignore if file doesn't exist
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('BM25-only mode (no provider)', () => {
|
|
46
|
+
let manager: EmbeddingManager;
|
|
47
|
+
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
manager = createEmbeddingManager({});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(() => {
|
|
53
|
+
manager.close();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should work without embedding provider', async () => {
|
|
57
|
+
await manager.store('id1', 'machine learning algorithms', 'experience');
|
|
58
|
+
await manager.store('id2', 'database optimization', 'strategy');
|
|
59
|
+
|
|
60
|
+
const results = await manager.search('machine learning');
|
|
61
|
+
expect(results.length).toBeGreaterThan(0);
|
|
62
|
+
expect(results[0].id).toBe('id1');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should report no vector search available', () => {
|
|
66
|
+
expect(manager.hasVectorSearch).toBe(false);
|
|
67
|
+
expect(manager.dimension).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should return undefined embeddings when storing', async () => {
|
|
71
|
+
const embedding = await manager.store('id1', 'test content', 'experience');
|
|
72
|
+
expect(embedding).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should return null when trying to embed directly', async () => {
|
|
76
|
+
const embedding = await manager.embed('test');
|
|
77
|
+
expect(embedding).toBeNull();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('with mock embedding provider (no vector store)', () => {
|
|
82
|
+
let manager: EmbeddingManager;
|
|
83
|
+
let provider: MockEmbeddingProvider;
|
|
84
|
+
|
|
85
|
+
beforeEach(() => {
|
|
86
|
+
provider = new MockEmbeddingProvider();
|
|
87
|
+
// No vectorStorePath, so vector store won't be created
|
|
88
|
+
manager = createEmbeddingManager({
|
|
89
|
+
provider,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
afterEach(() => {
|
|
94
|
+
manager.close();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should fall back to BM25 without vector store path', async () => {
|
|
98
|
+
await manager.store('id1', 'test content', 'experience');
|
|
99
|
+
|
|
100
|
+
// Should use BM25 for search since no vector store
|
|
101
|
+
const results = await manager.search('test');
|
|
102
|
+
expect(results.length).toBe(1);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('statistics', () => {
|
|
107
|
+
let manager: EmbeddingManager;
|
|
108
|
+
|
|
109
|
+
beforeEach(() => {
|
|
110
|
+
manager = createEmbeddingManager({});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
afterEach(() => {
|
|
114
|
+
manager.close();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should report correct stats', async () => {
|
|
118
|
+
await manager.store('id1', 'content 1', 'experience');
|
|
119
|
+
await manager.store('id2', 'content 2', 'strategy');
|
|
120
|
+
|
|
121
|
+
const stats = manager.getStats();
|
|
122
|
+
expect(stats.bm25Count).toBe(2);
|
|
123
|
+
expect(stats.hasVectorSearch).toBe(false);
|
|
124
|
+
expect(stats.providerName).toBeNull();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('batch operations', () => {
|
|
129
|
+
let manager: EmbeddingManager;
|
|
130
|
+
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
manager = createEmbeddingManager({});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
afterEach(() => {
|
|
136
|
+
manager.close();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should store batch items', async () => {
|
|
140
|
+
const items = [
|
|
141
|
+
{ id: 'id1', content: 'content 1', type: 'experience' as const },
|
|
142
|
+
{ id: 'id2', content: 'content 2', type: 'strategy' as const },
|
|
143
|
+
{ id: 'id3', content: 'content 3', type: 'concept' as const },
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const results = await manager.storeBatch(items);
|
|
147
|
+
|
|
148
|
+
expect(results.size).toBe(3);
|
|
149
|
+
expect(manager.has('id1')).toBe(true);
|
|
150
|
+
expect(manager.has('id2')).toBe(true);
|
|
151
|
+
expect(manager.has('id3')).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('remove operation', () => {
|
|
156
|
+
let manager: EmbeddingManager;
|
|
157
|
+
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
manager = createEmbeddingManager({});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
afterEach(() => {
|
|
163
|
+
manager.close();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should remove items from index', async () => {
|
|
167
|
+
await manager.store('id1', 'test content', 'experience');
|
|
168
|
+
expect(manager.has('id1')).toBe(true);
|
|
169
|
+
|
|
170
|
+
manager.remove('id1');
|
|
171
|
+
expect(manager.has('id1')).toBe(false);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('search with options', () => {
|
|
176
|
+
let manager: EmbeddingManager;
|
|
177
|
+
|
|
178
|
+
beforeEach(async () => {
|
|
179
|
+
manager = createEmbeddingManager({});
|
|
180
|
+
await manager.store('exp1', 'machine learning experience', 'experience');
|
|
181
|
+
await manager.store('str1', 'machine learning strategy', 'strategy');
|
|
182
|
+
await manager.store('con1', 'deep learning concept', 'concept');
|
|
183
|
+
await manager.store('skl1', 'learning skill', 'skill');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
afterEach(() => {
|
|
187
|
+
manager.close();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should filter by type', async () => {
|
|
191
|
+
const results = await manager.search('learning', { type: 'experience' });
|
|
192
|
+
expect(results.every(r => r.id.startsWith('exp'))).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should limit results with k', async () => {
|
|
196
|
+
const results = await manager.search('learning', { k: 2 });
|
|
197
|
+
expect(results.length).toBeLessThanOrEqual(2);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should apply threshold', async () => {
|
|
201
|
+
const results = await manager.search('learning', { threshold: 0.5 });
|
|
202
|
+
expect(results.every(r => r.score >= 0.5)).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
});
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { Atlas, createAtlas } from '../../src/atlas.js';
|
|
3
|
+
import { createTask } from '../../src/types/task.js';
|
|
4
|
+
import { createTrajectory } from '../../src/types/trajectory.js';
|
|
5
|
+
import { createStep } from '../../src/types/step.js';
|
|
6
|
+
import { successOutcome, failureOutcome } from '../../src/types/outcome.js';
|
|
7
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { tmpdir } from 'node:os';
|
|
10
|
+
|
|
11
|
+
describe('Atlas', () => {
|
|
12
|
+
let tempDir: string;
|
|
13
|
+
let atlas: Atlas;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
tempDir = await mkdtemp(join(tmpdir(), 'atlas-test-'));
|
|
17
|
+
atlas = createAtlas({
|
|
18
|
+
storage: { baseDir: tempDir },
|
|
19
|
+
learning: { batchSize: 3 },
|
|
20
|
+
});
|
|
21
|
+
await atlas.init();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(async () => {
|
|
25
|
+
await atlas.close();
|
|
26
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('initialization', () => {
|
|
30
|
+
it('should initialize with default config', async () => {
|
|
31
|
+
const stats = await atlas.getStats();
|
|
32
|
+
expect(stats.memory.experienceCount).toBe(0);
|
|
33
|
+
expect(stats.memory.playbookCount).toBe(0);
|
|
34
|
+
expect(stats.memory.metaObservationCount).toBe(0);
|
|
35
|
+
expect(stats.learning.trajectoriesProcessed).toBe(0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should expose memory and learning systems', () => {
|
|
39
|
+
expect(atlas.getMemory()).toBeDefined();
|
|
40
|
+
expect(atlas.getLearning()).toBeDefined();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('processTrajectory', () => {
|
|
45
|
+
it('should process a trajectory and update stats', async () => {
|
|
46
|
+
const trajectory = createTrajectory({
|
|
47
|
+
task: createTask({ domain: 'code', description: 'Test task' }),
|
|
48
|
+
steps: [
|
|
49
|
+
createStep({ action: 'read', observation: 'content' }),
|
|
50
|
+
createStep({ action: 'write', observation: 'done' }),
|
|
51
|
+
],
|
|
52
|
+
outcome: successOutcome('Completed'),
|
|
53
|
+
agentId: 'test-agent',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const result = await atlas.processTrajectory(trajectory);
|
|
57
|
+
|
|
58
|
+
expect(result).toBeDefined();
|
|
59
|
+
const stats = await atlas.getStats();
|
|
60
|
+
expect(stats.learning.trajectoriesProcessed).toBe(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should accumulate trajectories for batch learning', async () => {
|
|
64
|
+
const createTraj = (id: string) =>
|
|
65
|
+
createTrajectory({
|
|
66
|
+
id,
|
|
67
|
+
task: createTask({ domain: 'code', description: `Task ${id}` }),
|
|
68
|
+
steps: [createStep({ action: 'a', observation: 'o' })],
|
|
69
|
+
outcome: successOutcome('done'),
|
|
70
|
+
agentId: 'agent',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await atlas.processTrajectory(createTraj('1'));
|
|
74
|
+
await atlas.processTrajectory(createTraj('2'));
|
|
75
|
+
|
|
76
|
+
const stats = await atlas.getStats();
|
|
77
|
+
expect(stats.learning.trajectoriesProcessed).toBe(2);
|
|
78
|
+
expect(stats.learning.pendingTrajectories).toBeGreaterThan(0);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('queryMemory', () => {
|
|
83
|
+
it('should query memory with default options', async () => {
|
|
84
|
+
// First add some data
|
|
85
|
+
const memory = atlas.getMemory();
|
|
86
|
+
await memory.experiences.add({
|
|
87
|
+
id: 'exp-1',
|
|
88
|
+
taskInput: 'Write a function to add numbers',
|
|
89
|
+
solutionOutput: 'function add(a, b) { return a + b; }',
|
|
90
|
+
feedback: 'Correct',
|
|
91
|
+
success: true,
|
|
92
|
+
domain: 'code',
|
|
93
|
+
trajectoryId: 'traj-1',
|
|
94
|
+
usageCount: 0,
|
|
95
|
+
createdAt: new Date(),
|
|
96
|
+
metadata: {},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const results = await atlas.queryMemory('add numbers');
|
|
100
|
+
expect(results).toBeDefined();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should filter by domain', async () => {
|
|
104
|
+
const memory = atlas.getMemory();
|
|
105
|
+
await memory.experiences.add({
|
|
106
|
+
id: 'exp-code',
|
|
107
|
+
taskInput: 'Code task',
|
|
108
|
+
solutionOutput: 'solution',
|
|
109
|
+
feedback: 'ok',
|
|
110
|
+
success: true,
|
|
111
|
+
domain: 'code',
|
|
112
|
+
trajectoryId: 't1',
|
|
113
|
+
usageCount: 0,
|
|
114
|
+
createdAt: new Date(),
|
|
115
|
+
metadata: {},
|
|
116
|
+
});
|
|
117
|
+
await memory.experiences.add({
|
|
118
|
+
id: 'exp-math',
|
|
119
|
+
taskInput: 'Math task',
|
|
120
|
+
solutionOutput: 'solution',
|
|
121
|
+
feedback: 'ok',
|
|
122
|
+
success: true,
|
|
123
|
+
domain: 'math',
|
|
124
|
+
trajectoryId: 't2',
|
|
125
|
+
usageCount: 0,
|
|
126
|
+
createdAt: new Date(),
|
|
127
|
+
metadata: {},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const results = await atlas.queryMemory('task', { domains: ['code'] });
|
|
131
|
+
// Should only return code domain results
|
|
132
|
+
expect(results.experiences.every(e => e.experience.domain === 'code')).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('updateConfig', () => {
|
|
137
|
+
it('should update learning config', () => {
|
|
138
|
+
atlas.updateConfig({
|
|
139
|
+
learning: { batchSize: 10 },
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Config is updated internally - we can verify through behavior
|
|
143
|
+
// Batch learning won't trigger until 10 trajectories
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('runBatchLearning', () => {
|
|
148
|
+
it('should run batch learning explicitly', async () => {
|
|
149
|
+
// Add some trajectories
|
|
150
|
+
const trajectory = createTrajectory({
|
|
151
|
+
task: createTask({ domain: 'code', description: 'Test' }),
|
|
152
|
+
steps: [createStep({ action: 'a', observation: 'o' })],
|
|
153
|
+
outcome: successOutcome('done'),
|
|
154
|
+
agentId: 'agent',
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
await atlas.processTrajectory(trajectory);
|
|
158
|
+
|
|
159
|
+
const result = await atlas.runBatchLearning();
|
|
160
|
+
expect(result).toBeDefined();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('solve', () => {
|
|
165
|
+
it('should throw if no provider is set', async () => {
|
|
166
|
+
const task = createTask({
|
|
167
|
+
domain: 'code',
|
|
168
|
+
description: 'Solve this',
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
await expect(atlas.solve(task)).rejects.toThrow('No execution method available');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Note: Testing with actual provider requires mocking
|
|
175
|
+
// The solve functionality integrates with LLMProvider
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Note: extractPatterns was removed - LLM-based extraction is now handled
|
|
179
|
+
// through the LLMPlaybookExtractor directly
|
|
180
|
+
|
|
181
|
+
describe('persistence', () => {
|
|
182
|
+
it('should persist data across restarts', async () => {
|
|
183
|
+
// Add data
|
|
184
|
+
const memory = atlas.getMemory();
|
|
185
|
+
await memory.experiences.add({
|
|
186
|
+
id: 'persist-exp',
|
|
187
|
+
taskInput: 'Persistent task',
|
|
188
|
+
solutionOutput: 'solution',
|
|
189
|
+
feedback: 'ok',
|
|
190
|
+
success: true,
|
|
191
|
+
domain: 'code',
|
|
192
|
+
trajectoryId: 'traj-persist',
|
|
193
|
+
usageCount: 0,
|
|
194
|
+
createdAt: new Date(),
|
|
195
|
+
metadata: {},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Close and reopen
|
|
199
|
+
await atlas.close();
|
|
200
|
+
|
|
201
|
+
const atlas2 = createAtlas({
|
|
202
|
+
storage: { baseDir: tempDir },
|
|
203
|
+
});
|
|
204
|
+
await atlas2.init();
|
|
205
|
+
|
|
206
|
+
const stats = await atlas2.getStats();
|
|
207
|
+
expect(stats.memory.experienceCount).toBe(1);
|
|
208
|
+
|
|
209
|
+
// Query should find the data
|
|
210
|
+
const experience = await atlas2.getMemory().experiences.get('persist-exp');
|
|
211
|
+
expect(experience?.taskInput).toBe('Persistent task');
|
|
212
|
+
|
|
213
|
+
await atlas2.close();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('batch learning trigger', () => {
|
|
218
|
+
it('should trigger batch learning when threshold is reached', async () => {
|
|
219
|
+
// Create atlas with batch size of 2
|
|
220
|
+
const testAtlas = createAtlas({
|
|
221
|
+
storage: { baseDir: tempDir },
|
|
222
|
+
learning: { batchSize: 2 },
|
|
223
|
+
});
|
|
224
|
+
await testAtlas.init();
|
|
225
|
+
|
|
226
|
+
const createTraj = (id: string) =>
|
|
227
|
+
createTrajectory({
|
|
228
|
+
id,
|
|
229
|
+
task: createTask({ domain: 'code', description: `Task ${id}` }),
|
|
230
|
+
steps: [
|
|
231
|
+
createStep({ thought: 'thinking', action: 'action', observation: 'result' }),
|
|
232
|
+
createStep({ action: 'action2', observation: 'result2' }),
|
|
233
|
+
],
|
|
234
|
+
outcome: successOutcome({ result: 'done' }),
|
|
235
|
+
agentId: 'agent',
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
await testAtlas.processTrajectory(createTraj('1'));
|
|
239
|
+
let stats = await testAtlas.getStats();
|
|
240
|
+
expect(stats.learning.pendingTrajectories).toBe(1);
|
|
241
|
+
|
|
242
|
+
await testAtlas.processTrajectory(createTraj('2'));
|
|
243
|
+
// Batch learning should have been triggered
|
|
244
|
+
stats = await testAtlas.getStats();
|
|
245
|
+
// After batch learning, pending should be 0 or experiences should be added
|
|
246
|
+
expect(stats.learning.trajectoriesProcessed).toBe(2);
|
|
247
|
+
|
|
248
|
+
await testAtlas.close();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
describe('createAtlas', () => {
|
|
254
|
+
it('should create an Atlas instance with defaults', () => {
|
|
255
|
+
const atlas = createAtlas();
|
|
256
|
+
expect(atlas).toBeInstanceOf(Atlas);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should accept custom config', () => {
|
|
260
|
+
const atlas = createAtlas({
|
|
261
|
+
storage: { baseDir: '/tmp/custom' },
|
|
262
|
+
learning: { batchSize: 20 },
|
|
263
|
+
});
|
|
264
|
+
expect(atlas).toBeInstanceOf(Atlas);
|
|
265
|
+
});
|
|
266
|
+
});
|