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,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM-Based Playbook Extractor
|
|
3
|
+
*
|
|
4
|
+
* Uses language models to generate higher-quality playbooks
|
|
5
|
+
* from trajectories. Complements the pattern-based extractor
|
|
6
|
+
* with deeper semantic analysis.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
Playbook,
|
|
11
|
+
Trajectory,
|
|
12
|
+
Refinement,
|
|
13
|
+
} from '../types/index.js';
|
|
14
|
+
import { createPlaybook } from '../types/index.js';
|
|
15
|
+
import type { AnalysisResult } from './analyzer.js';
|
|
16
|
+
import type { LLMProvider } from '../agents/types.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for LLM-based extraction
|
|
20
|
+
*/
|
|
21
|
+
export interface LLMExtractorConfig {
|
|
22
|
+
/** Temperature for LLM calls (default: 0.2 for determinism) */
|
|
23
|
+
temperature: number;
|
|
24
|
+
/** Maximum tokens for response */
|
|
25
|
+
maxTokens: number;
|
|
26
|
+
/** Whether to extract from single trajectories (vs only batches) */
|
|
27
|
+
extractFromSingle: boolean;
|
|
28
|
+
/** Minimum complexity for LLM extraction */
|
|
29
|
+
minComplexity: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const DEFAULT_CONFIG: LLMExtractorConfig = {
|
|
33
|
+
temperature: 0.2,
|
|
34
|
+
maxTokens: 2000,
|
|
35
|
+
extractFromSingle: true,
|
|
36
|
+
minComplexity: 3, // Minimum steps to warrant LLM extraction
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Result from LLM extraction
|
|
41
|
+
*/
|
|
42
|
+
export interface LLMExtractionResult {
|
|
43
|
+
playbooks: Playbook[];
|
|
44
|
+
refinements: Array<{
|
|
45
|
+
playbookId: string;
|
|
46
|
+
refinement: Refinement;
|
|
47
|
+
}>;
|
|
48
|
+
/** Raw LLM response for debugging */
|
|
49
|
+
rawResponse?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* LLM-Based Playbook Extractor
|
|
54
|
+
*/
|
|
55
|
+
export class LLMPlaybookExtractor {
|
|
56
|
+
private provider: LLMProvider;
|
|
57
|
+
private config: LLMExtractorConfig;
|
|
58
|
+
|
|
59
|
+
constructor(provider: LLMProvider, config?: Partial<LLMExtractorConfig>) {
|
|
60
|
+
this.provider = provider;
|
|
61
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extract playbooks from trajectories using LLM
|
|
66
|
+
*/
|
|
67
|
+
async extract(
|
|
68
|
+
trajectories: Trajectory[],
|
|
69
|
+
analyses: AnalysisResult[],
|
|
70
|
+
existingPlaybooks: Playbook[] = []
|
|
71
|
+
): Promise<LLMExtractionResult> {
|
|
72
|
+
// Filter to successful, complex enough trajectories
|
|
73
|
+
const candidates = trajectories.filter((t, i) => {
|
|
74
|
+
const analysis = analyses[i];
|
|
75
|
+
return (
|
|
76
|
+
analysis?.success &&
|
|
77
|
+
analysis.abstractable &&
|
|
78
|
+
t.steps.length >= this.config.minComplexity
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (candidates.length === 0) {
|
|
83
|
+
return { playbooks: [], refinements: [] };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Extract playbooks from each candidate
|
|
87
|
+
const allResults: LLMExtractionResult = {
|
|
88
|
+
playbooks: [],
|
|
89
|
+
refinements: [],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Process individually for better quality
|
|
93
|
+
if (this.config.extractFromSingle) {
|
|
94
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
95
|
+
const trajectory = candidates[i];
|
|
96
|
+
const analysis = analyses.find(
|
|
97
|
+
(_, idx) => trajectories[idx] === trajectory
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (!analysis) continue;
|
|
101
|
+
|
|
102
|
+
const result = await this.extractFromSingleTrajectory(
|
|
103
|
+
trajectory,
|
|
104
|
+
analysis,
|
|
105
|
+
existingPlaybooks
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
allResults.playbooks.push(...result.playbooks);
|
|
109
|
+
allResults.refinements.push(...result.refinements);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Also do batch extraction if we have multiple
|
|
114
|
+
if (candidates.length >= 2) {
|
|
115
|
+
const batchResult = await this.extractFromBatch(
|
|
116
|
+
candidates,
|
|
117
|
+
analyses.filter((_, i) => candidates.includes(trajectories[i])),
|
|
118
|
+
existingPlaybooks
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Merge with individual results (avoid duplicates)
|
|
122
|
+
for (const playbook of batchResult.playbooks) {
|
|
123
|
+
const isDuplicate = allResults.playbooks.some(
|
|
124
|
+
(p) => this.isSimilarPlaybook(p, playbook)
|
|
125
|
+
);
|
|
126
|
+
if (!isDuplicate) {
|
|
127
|
+
allResults.playbooks.push(playbook);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
allResults.refinements.push(...batchResult.refinements);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return allResults;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Extract a playbook from a single trajectory
|
|
139
|
+
*/
|
|
140
|
+
private async extractFromSingleTrajectory(
|
|
141
|
+
trajectory: Trajectory,
|
|
142
|
+
analysis: AnalysisResult,
|
|
143
|
+
existingPlaybooks: Playbook[]
|
|
144
|
+
): Promise<LLMExtractionResult> {
|
|
145
|
+
const prompt = this.buildSingleExtractionPrompt(
|
|
146
|
+
trajectory,
|
|
147
|
+
analysis,
|
|
148
|
+
existingPlaybooks
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const response = await this.provider.complete(
|
|
152
|
+
[{ role: 'user', content: prompt }],
|
|
153
|
+
{
|
|
154
|
+
temperature: this.config.temperature,
|
|
155
|
+
maxTokens: this.config.maxTokens,
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
return this.parseExtractionResponse(response, trajectory);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Extract playbooks from a batch of trajectories
|
|
164
|
+
*/
|
|
165
|
+
private async extractFromBatch(
|
|
166
|
+
trajectories: Trajectory[],
|
|
167
|
+
analyses: AnalysisResult[],
|
|
168
|
+
existingPlaybooks: Playbook[]
|
|
169
|
+
): Promise<LLMExtractionResult> {
|
|
170
|
+
const prompt = this.buildBatchExtractionPrompt(
|
|
171
|
+
trajectories,
|
|
172
|
+
analyses,
|
|
173
|
+
existingPlaybooks
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const response = await this.provider.complete(
|
|
177
|
+
[{ role: 'user', content: prompt }],
|
|
178
|
+
{
|
|
179
|
+
temperature: this.config.temperature,
|
|
180
|
+
maxTokens: this.config.maxTokens * 2,
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
return this.parseExtractionResponse(response);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Build prompt for single trajectory extraction
|
|
189
|
+
*/
|
|
190
|
+
private buildSingleExtractionPrompt(
|
|
191
|
+
trajectory: Trajectory,
|
|
192
|
+
analysis: AnalysisResult,
|
|
193
|
+
existingPlaybooks: Playbook[]
|
|
194
|
+
): string {
|
|
195
|
+
const keyStepsDesc = analysis.keySteps
|
|
196
|
+
.map((idx) => {
|
|
197
|
+
const step = trajectory.steps[idx];
|
|
198
|
+
return step
|
|
199
|
+
? ` - Step ${idx + 1}: ${step.action}${step.thought ? ` (reasoning: ${step.thought})` : ''}`
|
|
200
|
+
: '';
|
|
201
|
+
})
|
|
202
|
+
.filter(Boolean)
|
|
203
|
+
.join('\n');
|
|
204
|
+
|
|
205
|
+
const existingPlaybookNames = existingPlaybooks
|
|
206
|
+
.map((p) => `- ${p.name}: ${p.guidance.strategy.slice(0, 100)}`)
|
|
207
|
+
.slice(0, 5)
|
|
208
|
+
.join('\n');
|
|
209
|
+
|
|
210
|
+
return `Analyze this successful problem-solving trajectory and extract a reusable playbook.
|
|
211
|
+
|
|
212
|
+
## Task
|
|
213
|
+
${trajectory.task.description}
|
|
214
|
+
Domain: ${trajectory.task.domain}
|
|
215
|
+
|
|
216
|
+
## Solution Steps
|
|
217
|
+
${trajectory.steps.map((s, i) => `${i + 1}. ${s.action}${s.observation ? `\n Observation: ${s.observation.slice(0, 100)}` : ''}`).join('\n')}
|
|
218
|
+
|
|
219
|
+
## Key Steps (most important for success)
|
|
220
|
+
${keyStepsDesc}
|
|
221
|
+
|
|
222
|
+
## Outcome
|
|
223
|
+
${trajectory.outcome.success ? 'SUCCESS' : 'FAILURE'}: ${trajectory.outcome.solution ?? trajectory.outcome.errorInfo ?? 'No details'}
|
|
224
|
+
|
|
225
|
+
${existingPlaybooks.length > 0 ? `## Existing Playbooks (avoid duplicates)
|
|
226
|
+
${existingPlaybookNames}` : ''}
|
|
227
|
+
|
|
228
|
+
## Instructions
|
|
229
|
+
Extract a reusable playbook that captures the essential approach. Focus on:
|
|
230
|
+
1. What situations trigger this approach
|
|
231
|
+
2. The core strategy/pattern used
|
|
232
|
+
3. Key tactical steps
|
|
233
|
+
4. Success/failure indicators
|
|
234
|
+
|
|
235
|
+
Respond in JSON format:
|
|
236
|
+
{
|
|
237
|
+
"playbook": {
|
|
238
|
+
"name": "kebab-case-name",
|
|
239
|
+
"situations": ["when X happens", "for Y type problems"],
|
|
240
|
+
"triggers": ["error messages", "signals that trigger this"],
|
|
241
|
+
"antiPatterns": ["when NOT to use this"],
|
|
242
|
+
"strategy": "High-level approach description",
|
|
243
|
+
"tactics": ["specific technique 1", "specific technique 2"],
|
|
244
|
+
"steps": ["step 1", "step 2", "step 3"],
|
|
245
|
+
"successIndicators": ["how to know it worked"],
|
|
246
|
+
"failureIndicators": ["how to know it failed"],
|
|
247
|
+
"complexity": "simple|moderate|complex",
|
|
248
|
+
"estimatedEffort": 5
|
|
249
|
+
},
|
|
250
|
+
"isRefinementOf": null
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
If this is better suited as a refinement to an existing playbook, set isRefinementOf to the playbook name and include only the refinement details.`;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Build prompt for batch extraction
|
|
258
|
+
*/
|
|
259
|
+
private buildBatchExtractionPrompt(
|
|
260
|
+
trajectories: Trajectory[],
|
|
261
|
+
analyses: AnalysisResult[],
|
|
262
|
+
existingPlaybooks: Playbook[]
|
|
263
|
+
): string {
|
|
264
|
+
const trajectorySummaries = trajectories
|
|
265
|
+
.map((t, i) => {
|
|
266
|
+
const analysis = analyses[i];
|
|
267
|
+
const keySteps = analysis?.keySteps ?? [];
|
|
268
|
+
return `### Trajectory ${i + 1}
|
|
269
|
+
Task: ${t.task.description}
|
|
270
|
+
Domain: ${t.task.domain}
|
|
271
|
+
Steps: ${t.steps.length}
|
|
272
|
+
Key steps: ${keySteps.map((idx) => t.steps[idx]?.action ?? '').join(' → ')}
|
|
273
|
+
Outcome: ${t.outcome.success ? 'SUCCESS' : 'FAILURE'}`;
|
|
274
|
+
})
|
|
275
|
+
.join('\n\n');
|
|
276
|
+
|
|
277
|
+
const existingPlaybookNames = existingPlaybooks
|
|
278
|
+
.map((p) => `- ${p.name}`)
|
|
279
|
+
.slice(0, 10)
|
|
280
|
+
.join('\n');
|
|
281
|
+
|
|
282
|
+
return `Analyze these successful trajectories and identify common patterns that can be extracted as reusable playbooks.
|
|
283
|
+
|
|
284
|
+
## Trajectories
|
|
285
|
+
${trajectorySummaries}
|
|
286
|
+
|
|
287
|
+
${existingPlaybooks.length > 0 ? `## Existing Playbooks (avoid duplicates)
|
|
288
|
+
${existingPlaybookNames}` : ''}
|
|
289
|
+
|
|
290
|
+
## Instructions
|
|
291
|
+
Identify patterns that appear across multiple trajectories and extract them as playbooks.
|
|
292
|
+
Focus on generalizable approaches, not task-specific details.
|
|
293
|
+
|
|
294
|
+
Respond in JSON format:
|
|
295
|
+
{
|
|
296
|
+
"playbooks": [
|
|
297
|
+
{
|
|
298
|
+
"name": "kebab-case-name",
|
|
299
|
+
"situations": ["when X happens"],
|
|
300
|
+
"triggers": [],
|
|
301
|
+
"antiPatterns": [],
|
|
302
|
+
"strategy": "Description",
|
|
303
|
+
"tactics": ["technique 1"],
|
|
304
|
+
"steps": ["step 1", "step 2"],
|
|
305
|
+
"successIndicators": ["indicator"],
|
|
306
|
+
"failureIndicators": ["indicator"],
|
|
307
|
+
"complexity": "simple|moderate|complex",
|
|
308
|
+
"estimatedEffort": 5,
|
|
309
|
+
"sourceTrajectories": [1, 2]
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
}`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Parse LLM response into extraction result
|
|
317
|
+
*/
|
|
318
|
+
private parseExtractionResponse(
|
|
319
|
+
response: string,
|
|
320
|
+
sourceTrajectory?: Trajectory
|
|
321
|
+
): LLMExtractionResult {
|
|
322
|
+
const result: LLMExtractionResult = {
|
|
323
|
+
playbooks: [],
|
|
324
|
+
refinements: [],
|
|
325
|
+
rawResponse: response,
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
// Extract JSON from response
|
|
330
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
331
|
+
if (!jsonMatch) {
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const parsed = JSON.parse(jsonMatch[0]) as {
|
|
336
|
+
playbook?: LLMPlaybookData;
|
|
337
|
+
playbooks?: LLMPlaybookData[];
|
|
338
|
+
isRefinementOf?: string | null;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
// Handle single playbook response
|
|
342
|
+
if (parsed.playbook && !parsed.isRefinementOf) {
|
|
343
|
+
const playbook = this.createPlaybookFromLLMData(
|
|
344
|
+
parsed.playbook,
|
|
345
|
+
sourceTrajectory
|
|
346
|
+
);
|
|
347
|
+
result.playbooks.push(playbook);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Handle refinement response
|
|
351
|
+
if (parsed.playbook && parsed.isRefinementOf) {
|
|
352
|
+
result.refinements.push({
|
|
353
|
+
playbookId: parsed.isRefinementOf,
|
|
354
|
+
refinement: {
|
|
355
|
+
context: parsed.playbook.situations?.[0] ?? 'General refinement',
|
|
356
|
+
addition: parsed.playbook.strategy ?? '',
|
|
357
|
+
source: 'success',
|
|
358
|
+
addedAt: new Date(),
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Handle batch response
|
|
364
|
+
if (parsed.playbooks && Array.isArray(parsed.playbooks)) {
|
|
365
|
+
for (const pbData of parsed.playbooks) {
|
|
366
|
+
const playbook = this.createPlaybookFromLLMData(pbData);
|
|
367
|
+
result.playbooks.push(playbook);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
} catch (error) {
|
|
371
|
+
// JSON parsing failed, return empty result
|
|
372
|
+
console.warn(
|
|
373
|
+
'Failed to parse LLM extraction response:',
|
|
374
|
+
error instanceof Error ? error.message : error
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Create a Playbook from LLM-extracted data
|
|
383
|
+
*/
|
|
384
|
+
private createPlaybookFromLLMData(
|
|
385
|
+
data: LLMPlaybookData,
|
|
386
|
+
sourceTrajectory?: Trajectory
|
|
387
|
+
): Playbook {
|
|
388
|
+
const domain = sourceTrajectory?.task.domain ?? 'general';
|
|
389
|
+
const sourceIds = sourceTrajectory ? [sourceTrajectory.id] : [];
|
|
390
|
+
|
|
391
|
+
return createPlaybook({
|
|
392
|
+
name: data.name ?? `llm-extracted-${Date.now()}`,
|
|
393
|
+
applicability: {
|
|
394
|
+
situations: data.situations ?? [],
|
|
395
|
+
triggers: data.triggers ?? [],
|
|
396
|
+
antiPatterns: data.antiPatterns ?? [],
|
|
397
|
+
domains: [domain],
|
|
398
|
+
},
|
|
399
|
+
guidance: {
|
|
400
|
+
strategy: data.strategy ?? '',
|
|
401
|
+
tactics: data.tactics ?? [],
|
|
402
|
+
steps: data.steps ?? [],
|
|
403
|
+
},
|
|
404
|
+
verification: {
|
|
405
|
+
successIndicators: data.successIndicators ?? [],
|
|
406
|
+
failureIndicators: data.failureIndicators ?? [],
|
|
407
|
+
},
|
|
408
|
+
evolution: {
|
|
409
|
+
version: '1.0.0',
|
|
410
|
+
createdFrom: sourceIds,
|
|
411
|
+
failures: [],
|
|
412
|
+
refinements: [],
|
|
413
|
+
successCount: 1,
|
|
414
|
+
failureCount: 0,
|
|
415
|
+
},
|
|
416
|
+
confidence: 0.6, // Start with moderate confidence for LLM-extracted
|
|
417
|
+
complexity: this.parseComplexity(data.complexity),
|
|
418
|
+
estimatedEffort: data.estimatedEffort ?? 5,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Parse complexity string
|
|
424
|
+
*/
|
|
425
|
+
private parseComplexity(
|
|
426
|
+
complexity?: string
|
|
427
|
+
): 'simple' | 'moderate' | 'complex' {
|
|
428
|
+
const normalized = complexity?.toLowerCase();
|
|
429
|
+
if (normalized === 'simple') return 'simple';
|
|
430
|
+
if (normalized === 'complex') return 'complex';
|
|
431
|
+
return 'moderate';
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Check if two playbooks are similar
|
|
436
|
+
*/
|
|
437
|
+
private isSimilarPlaybook(a: Playbook, b: Playbook): boolean {
|
|
438
|
+
// Simple name-based check
|
|
439
|
+
if (a.name === b.name) return true;
|
|
440
|
+
|
|
441
|
+
// Check situation overlap
|
|
442
|
+
const aSituations = new Set(a.applicability.situations);
|
|
443
|
+
const bSituations = b.applicability.situations;
|
|
444
|
+
const overlap = bSituations.filter((s) => aSituations.has(s)).length;
|
|
445
|
+
|
|
446
|
+
return overlap >= Math.min(aSituations.size, bSituations.length) * 0.8;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Generate a refinement for an existing playbook based on a new trajectory
|
|
451
|
+
*/
|
|
452
|
+
async generateRefinement(
|
|
453
|
+
playbook: Playbook,
|
|
454
|
+
trajectory: Trajectory,
|
|
455
|
+
context: string
|
|
456
|
+
): Promise<Refinement> {
|
|
457
|
+
const prompt = `Given this existing playbook and a new trajectory, generate a refinement.
|
|
458
|
+
|
|
459
|
+
## Existing Playbook: ${playbook.name}
|
|
460
|
+
Strategy: ${playbook.guidance.strategy}
|
|
461
|
+
Steps: ${playbook.guidance.steps?.join(' → ') ?? 'None'}
|
|
462
|
+
|
|
463
|
+
## New Trajectory
|
|
464
|
+
Task: ${trajectory.task.description}
|
|
465
|
+
Steps taken: ${trajectory.steps.map((s) => s.action).join(' → ')}
|
|
466
|
+
Outcome: ${trajectory.outcome.success ? 'SUCCESS' : 'FAILURE'}
|
|
467
|
+
|
|
468
|
+
## Context
|
|
469
|
+
${context}
|
|
470
|
+
|
|
471
|
+
## Instructions
|
|
472
|
+
Generate a refinement that captures what's new or different in this trajectory.
|
|
473
|
+
|
|
474
|
+
Respond in JSON:
|
|
475
|
+
{
|
|
476
|
+
"context": "when/where this refinement applies",
|
|
477
|
+
"addition": "what to add/change in the approach"
|
|
478
|
+
}`;
|
|
479
|
+
|
|
480
|
+
const response = await this.provider.complete(
|
|
481
|
+
[{ role: 'user', content: prompt }],
|
|
482
|
+
{
|
|
483
|
+
temperature: this.config.temperature,
|
|
484
|
+
maxTokens: 500,
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
try {
|
|
489
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
490
|
+
if (jsonMatch) {
|
|
491
|
+
const parsed = JSON.parse(jsonMatch[0]) as {
|
|
492
|
+
context?: string;
|
|
493
|
+
addition?: string;
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
return {
|
|
497
|
+
context: parsed.context ?? context,
|
|
498
|
+
addition: parsed.addition ?? '',
|
|
499
|
+
source: trajectory.outcome.success ? 'success' : 'failure',
|
|
500
|
+
addedAt: new Date(),
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
} catch {
|
|
504
|
+
// Fall back to simple refinement
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return {
|
|
508
|
+
context,
|
|
509
|
+
addition: `Additional approach from trajectory: ${trajectory.steps[0]?.action ?? ''}`,
|
|
510
|
+
source: trajectory.outcome.success ? 'success' : 'failure',
|
|
511
|
+
addedAt: new Date(),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Internal type for LLM-extracted playbook data
|
|
518
|
+
*/
|
|
519
|
+
interface LLMPlaybookData {
|
|
520
|
+
name?: string;
|
|
521
|
+
situations?: string[];
|
|
522
|
+
triggers?: string[];
|
|
523
|
+
antiPatterns?: string[];
|
|
524
|
+
strategy?: string;
|
|
525
|
+
tactics?: string[];
|
|
526
|
+
steps?: string[];
|
|
527
|
+
successIndicators?: string[];
|
|
528
|
+
failureIndicators?: string[];
|
|
529
|
+
complexity?: string;
|
|
530
|
+
estimatedEffort?: number;
|
|
531
|
+
sourceTrajectories?: number[];
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Create an LLM-based playbook extractor
|
|
536
|
+
*/
|
|
537
|
+
export function createLLMExtractor(
|
|
538
|
+
provider: LLMProvider,
|
|
539
|
+
config?: Partial<LLMExtractorConfig>
|
|
540
|
+
): LLMPlaybookExtractor {
|
|
541
|
+
return new LLMPlaybookExtractor(provider, config);
|
|
542
|
+
}
|