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,702 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playbook Extractor
|
|
3
|
+
* Extracts playbooks from successful trajectories
|
|
4
|
+
* Replaces the old TextPatternExtractor with more intelligent extraction
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
Playbook,
|
|
9
|
+
Trajectory,
|
|
10
|
+
Refinement,
|
|
11
|
+
} from '../types/index.js';
|
|
12
|
+
import { createPlaybook } from '../types/index.js';
|
|
13
|
+
import type { AnalysisResult } from './analyzer.js';
|
|
14
|
+
import { textSimilarity } from '../utils/similarity.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Result of playbook extraction
|
|
18
|
+
*/
|
|
19
|
+
export interface ExtractedPlaybooks {
|
|
20
|
+
/** Entirely new playbooks */
|
|
21
|
+
new: Playbook[];
|
|
22
|
+
/** Updates to existing playbooks */
|
|
23
|
+
updates: PlaybookUpdate[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Update to an existing playbook
|
|
28
|
+
*/
|
|
29
|
+
export interface PlaybookUpdate {
|
|
30
|
+
id: string;
|
|
31
|
+
refinement?: Refinement;
|
|
32
|
+
newTrigger?: string;
|
|
33
|
+
newAntiPattern?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for playbook extraction
|
|
38
|
+
*/
|
|
39
|
+
export interface PlaybookExtractorConfig {
|
|
40
|
+
/** Minimum trajectories needed to create a playbook */
|
|
41
|
+
minTrajectories: number;
|
|
42
|
+
/** Similarity threshold for merging playbooks */
|
|
43
|
+
mergeThreshold: number;
|
|
44
|
+
/** Minimum success rate for extraction */
|
|
45
|
+
minSuccessRate: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const DEFAULT_CONFIG: PlaybookExtractorConfig = {
|
|
49
|
+
minTrajectories: 2,
|
|
50
|
+
mergeThreshold: 0.85,
|
|
51
|
+
minSuccessRate: 0.6,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Playbook Extractor
|
|
56
|
+
* Intelligent extraction of playbooks from trajectories
|
|
57
|
+
*/
|
|
58
|
+
export class PlaybookExtractor {
|
|
59
|
+
private config: PlaybookExtractorConfig;
|
|
60
|
+
|
|
61
|
+
constructor(config?: Partial<PlaybookExtractorConfig>) {
|
|
62
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Extract playbooks from successful trajectories
|
|
67
|
+
*/
|
|
68
|
+
async extract(
|
|
69
|
+
trajectories: Trajectory[],
|
|
70
|
+
analyses: AnalysisResult[],
|
|
71
|
+
existingPlaybooks: Playbook[] = []
|
|
72
|
+
): Promise<ExtractedPlaybooks> {
|
|
73
|
+
const result: ExtractedPlaybooks = {
|
|
74
|
+
new: [],
|
|
75
|
+
updates: [],
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Filter to successful, abstractable trajectories
|
|
79
|
+
const candidates = trajectories.filter((_t, i) => {
|
|
80
|
+
const analysis = analyses[i];
|
|
81
|
+
return analysis?.success && analysis.abstractable;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (candidates.length < this.config.minTrajectories) {
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Group by domain
|
|
89
|
+
const byDomain = this.groupByDomain(candidates);
|
|
90
|
+
|
|
91
|
+
for (const [domain, domainTrajectories] of byDomain) {
|
|
92
|
+
// Extract playbooks from this domain
|
|
93
|
+
const extracted = await this.extractFromDomain(
|
|
94
|
+
domain,
|
|
95
|
+
domainTrajectories,
|
|
96
|
+
analyses,
|
|
97
|
+
existingPlaybooks
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
result.new.push(...extracted.new);
|
|
101
|
+
result.updates.push(...extracted.updates);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Consolidate similar playbooks
|
|
105
|
+
result.new = await this.consolidate(result.new);
|
|
106
|
+
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Extract playbooks from a single domain's trajectories
|
|
112
|
+
*/
|
|
113
|
+
private async extractFromDomain(
|
|
114
|
+
domain: string,
|
|
115
|
+
trajectories: Trajectory[],
|
|
116
|
+
analyses: AnalysisResult[],
|
|
117
|
+
existingPlaybooks: Playbook[]
|
|
118
|
+
): Promise<ExtractedPlaybooks> {
|
|
119
|
+
const result: ExtractedPlaybooks = {
|
|
120
|
+
new: [],
|
|
121
|
+
updates: [],
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Find common patterns across trajectories
|
|
125
|
+
const patterns = this.findCommonPatterns(trajectories, analyses);
|
|
126
|
+
|
|
127
|
+
for (const pattern of patterns) {
|
|
128
|
+
// Check if similar playbook exists
|
|
129
|
+
const existing = this.findSimilarPlaybook(pattern, existingPlaybooks);
|
|
130
|
+
|
|
131
|
+
if (existing) {
|
|
132
|
+
// Generate update
|
|
133
|
+
const update = this.generateUpdate(existing, pattern, trajectories);
|
|
134
|
+
if (update) {
|
|
135
|
+
result.updates.push(update);
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
// Create new playbook
|
|
139
|
+
const playbook = this.createPlaybookFromPattern(pattern, domain);
|
|
140
|
+
result.new.push(playbook);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Find common patterns across trajectories
|
|
149
|
+
*/
|
|
150
|
+
private findCommonPatterns(
|
|
151
|
+
trajectories: Trajectory[],
|
|
152
|
+
analyses: AnalysisResult[]
|
|
153
|
+
): ExtractedPattern[] {
|
|
154
|
+
const patterns: ExtractedPattern[] = [];
|
|
155
|
+
|
|
156
|
+
// Extract action sequences from key steps
|
|
157
|
+
const actionSequences: Array<{
|
|
158
|
+
actions: string[];
|
|
159
|
+
thought: string;
|
|
160
|
+
trajectoryId: string;
|
|
161
|
+
}> = [];
|
|
162
|
+
|
|
163
|
+
for (let i = 0; i < trajectories.length; i++) {
|
|
164
|
+
const trajectory = trajectories[i];
|
|
165
|
+
// Use index-based matching since TrainingExample doesn't have trajectoryId
|
|
166
|
+
const analysis = analyses[i];
|
|
167
|
+
|
|
168
|
+
if (!analysis) continue;
|
|
169
|
+
|
|
170
|
+
// Get key steps
|
|
171
|
+
const keySteps = analysis.keySteps
|
|
172
|
+
.map((idx) => trajectory.steps[idx])
|
|
173
|
+
.filter(Boolean);
|
|
174
|
+
|
|
175
|
+
if (keySteps.length > 0) {
|
|
176
|
+
actionSequences.push({
|
|
177
|
+
actions: keySteps.map((s) => s.action),
|
|
178
|
+
thought: keySteps[0]?.thought ?? trajectory.task.description,
|
|
179
|
+
trajectoryId: trajectory.id,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Find repeated patterns
|
|
185
|
+
const patternCounts = new Map<string, ExtractedPattern>();
|
|
186
|
+
|
|
187
|
+
for (const seq of actionSequences) {
|
|
188
|
+
// Normalize actions
|
|
189
|
+
const normalized = seq.actions.map((a) => this.normalizeAction(a));
|
|
190
|
+
const key = normalized.join('|');
|
|
191
|
+
|
|
192
|
+
if (patternCounts.has(key)) {
|
|
193
|
+
const existing = patternCounts.get(key)!;
|
|
194
|
+
existing.frequency++;
|
|
195
|
+
existing.trajectoryIds.push(seq.trajectoryId);
|
|
196
|
+
} else {
|
|
197
|
+
patternCounts.set(key, {
|
|
198
|
+
actions: seq.actions,
|
|
199
|
+
normalizedActions: normalized,
|
|
200
|
+
thought: seq.thought,
|
|
201
|
+
frequency: 1,
|
|
202
|
+
trajectoryIds: [seq.trajectoryId],
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Filter to patterns that occur multiple times
|
|
208
|
+
for (const pattern of patternCounts.values()) {
|
|
209
|
+
if (pattern.frequency >= this.config.minTrajectories) {
|
|
210
|
+
patterns.push(pattern);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Also extract error-recovery patterns
|
|
215
|
+
const errorPatterns = this.extractErrorPatterns(trajectories, analyses);
|
|
216
|
+
patterns.push(...errorPatterns);
|
|
217
|
+
|
|
218
|
+
return patterns;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Extract error-recovery patterns
|
|
223
|
+
*/
|
|
224
|
+
private extractErrorPatterns(
|
|
225
|
+
trajectories: Trajectory[],
|
|
226
|
+
analyses: AnalysisResult[]
|
|
227
|
+
): ExtractedPattern[] {
|
|
228
|
+
const patterns: ExtractedPattern[] = [];
|
|
229
|
+
const errorRecoveries = new Map<string, ExtractedPattern>();
|
|
230
|
+
|
|
231
|
+
for (let i = 0; i < trajectories.length; i++) {
|
|
232
|
+
const trajectory = trajectories[i];
|
|
233
|
+
const analysis = analyses[i];
|
|
234
|
+
|
|
235
|
+
if (!analysis?.errorPatterns) continue;
|
|
236
|
+
|
|
237
|
+
for (const errorPattern of analysis.errorPatterns) {
|
|
238
|
+
const key = errorPattern.signature;
|
|
239
|
+
|
|
240
|
+
// Find recovery actions (steps after the error)
|
|
241
|
+
const errorStepIdx = trajectory.steps.findIndex((s: { observation?: string }) =>
|
|
242
|
+
s.observation?.includes(errorPattern.signature)
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
if (errorStepIdx >= 0 && errorStepIdx < trajectory.steps.length - 1) {
|
|
246
|
+
const recoverySteps = trajectory.steps.slice(
|
|
247
|
+
errorStepIdx + 1,
|
|
248
|
+
errorStepIdx + 4
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
if (errorRecoveries.has(key)) {
|
|
252
|
+
const existing = errorRecoveries.get(key)!;
|
|
253
|
+
existing.frequency++;
|
|
254
|
+
existing.trajectoryIds.push(trajectory.id);
|
|
255
|
+
} else {
|
|
256
|
+
errorRecoveries.set(key, {
|
|
257
|
+
actions: recoverySteps.map((s: { action: string }) => s.action),
|
|
258
|
+
normalizedActions: recoverySteps.map((s: { action: string }) =>
|
|
259
|
+
this.normalizeAction(s.action)
|
|
260
|
+
),
|
|
261
|
+
thought: `When encountering: ${errorPattern.signature}`,
|
|
262
|
+
frequency: 1,
|
|
263
|
+
trajectoryIds: [trajectory.id],
|
|
264
|
+
errorTrigger: errorPattern.signature,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
for (const pattern of errorRecoveries.values()) {
|
|
272
|
+
if (pattern.frequency >= this.config.minTrajectories) {
|
|
273
|
+
patterns.push(pattern);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return patterns;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Normalize an action for pattern matching
|
|
282
|
+
*/
|
|
283
|
+
private normalizeAction(action: string): string {
|
|
284
|
+
const lower = action.toLowerCase();
|
|
285
|
+
|
|
286
|
+
// Map to action categories
|
|
287
|
+
const categories: Record<string, string[]> = {
|
|
288
|
+
read: ['read', 'view', 'show', 'display', 'cat', 'less', 'get'],
|
|
289
|
+
write: ['write', 'create', 'add', 'insert', 'save'],
|
|
290
|
+
edit: ['edit', 'modify', 'change', 'update', 'replace'],
|
|
291
|
+
delete: ['delete', 'remove', 'drop', 'clear'],
|
|
292
|
+
search: ['search', 'find', 'grep', 'locate', 'query'],
|
|
293
|
+
run: ['run', 'execute', 'call', 'invoke', 'start'],
|
|
294
|
+
test: ['test', 'verify', 'check', 'validate', 'assert'],
|
|
295
|
+
build: ['build', 'compile', 'bundle', 'package'],
|
|
296
|
+
install: ['install', 'add', 'npm', 'yarn', 'pip'],
|
|
297
|
+
debug: ['debug', 'trace', 'log', 'inspect', 'breakpoint'],
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
for (const [category, keywords] of Object.entries(categories)) {
|
|
301
|
+
if (keywords.some((kw) => lower.includes(kw))) {
|
|
302
|
+
return category;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Return first word as fallback
|
|
307
|
+
return lower.split(/\s+/)[0] ?? 'action';
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Find similar existing playbook
|
|
312
|
+
*/
|
|
313
|
+
private findSimilarPlaybook(
|
|
314
|
+
pattern: ExtractedPattern,
|
|
315
|
+
playbooks: Playbook[]
|
|
316
|
+
): Playbook | undefined {
|
|
317
|
+
for (const playbook of playbooks) {
|
|
318
|
+
// Check situation similarity
|
|
319
|
+
const situationMatch = playbook.applicability.situations.some(
|
|
320
|
+
(s) => textSimilarity(pattern.thought, s) > this.config.mergeThreshold
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
if (situationMatch) return playbook;
|
|
324
|
+
|
|
325
|
+
// Check trigger match for error patterns
|
|
326
|
+
if (pattern.errorTrigger) {
|
|
327
|
+
const triggerMatch = playbook.applicability.triggers.some(
|
|
328
|
+
(t) =>
|
|
329
|
+
textSimilarity(pattern.errorTrigger!, t) > this.config.mergeThreshold
|
|
330
|
+
);
|
|
331
|
+
if (triggerMatch) return playbook;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Generate update for existing playbook
|
|
340
|
+
*/
|
|
341
|
+
private generateUpdate(
|
|
342
|
+
playbook: Playbook,
|
|
343
|
+
pattern: ExtractedPattern,
|
|
344
|
+
trajectories: Trajectory[]
|
|
345
|
+
): PlaybookUpdate | undefined {
|
|
346
|
+
const update: PlaybookUpdate = { id: playbook.id };
|
|
347
|
+
let hasUpdate = false;
|
|
348
|
+
|
|
349
|
+
// Check for new trigger
|
|
350
|
+
if (
|
|
351
|
+
pattern.errorTrigger &&
|
|
352
|
+
!playbook.applicability.triggers.includes(pattern.errorTrigger)
|
|
353
|
+
) {
|
|
354
|
+
update.newTrigger = pattern.errorTrigger;
|
|
355
|
+
hasUpdate = true;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Check for context-specific refinement
|
|
359
|
+
const contexts = trajectories
|
|
360
|
+
.filter((t) => pattern.trajectoryIds.includes(t.id))
|
|
361
|
+
.map((t) => this.extractContext(t));
|
|
362
|
+
|
|
363
|
+
const uniqueContext = contexts.find(
|
|
364
|
+
(c) =>
|
|
365
|
+
!playbook.evolution.refinements.some(
|
|
366
|
+
(r) => textSimilarity(r.context, c) > 0.8
|
|
367
|
+
)
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
if (uniqueContext && pattern.actions.length > 0) {
|
|
371
|
+
update.refinement = {
|
|
372
|
+
context: uniqueContext,
|
|
373
|
+
addition: `Also: ${pattern.actions.slice(0, 2).join(', ')}`,
|
|
374
|
+
source: 'success',
|
|
375
|
+
addedAt: new Date(),
|
|
376
|
+
};
|
|
377
|
+
hasUpdate = true;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return hasUpdate ? update : undefined;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Create a playbook from an extracted pattern
|
|
385
|
+
*/
|
|
386
|
+
private createPlaybookFromPattern(
|
|
387
|
+
pattern: ExtractedPattern,
|
|
388
|
+
domain: string
|
|
389
|
+
): Playbook {
|
|
390
|
+
const name = this.generatePlaybookName(pattern);
|
|
391
|
+
|
|
392
|
+
return createPlaybook({
|
|
393
|
+
name,
|
|
394
|
+
applicability: {
|
|
395
|
+
situations: [pattern.thought],
|
|
396
|
+
triggers: pattern.errorTrigger ? [pattern.errorTrigger] : [],
|
|
397
|
+
antiPatterns: [],
|
|
398
|
+
domains: [domain],
|
|
399
|
+
},
|
|
400
|
+
guidance: {
|
|
401
|
+
strategy: pattern.thought,
|
|
402
|
+
tactics: pattern.actions.slice(0, 5),
|
|
403
|
+
steps: pattern.actions,
|
|
404
|
+
},
|
|
405
|
+
verification: {
|
|
406
|
+
successIndicators: ['Task completes successfully'],
|
|
407
|
+
failureIndicators: ['Same error persists', 'New errors introduced'],
|
|
408
|
+
},
|
|
409
|
+
evolution: {
|
|
410
|
+
version: '1.0.0',
|
|
411
|
+
createdFrom: pattern.trajectoryIds,
|
|
412
|
+
failures: [],
|
|
413
|
+
refinements: [],
|
|
414
|
+
successCount: pattern.frequency,
|
|
415
|
+
failureCount: 0,
|
|
416
|
+
},
|
|
417
|
+
provenance: {
|
|
418
|
+
origin: 'extracted',
|
|
419
|
+
recordedAt: new Date(),
|
|
420
|
+
},
|
|
421
|
+
confidence: Math.min(0.5, 0.2 + pattern.frequency * 0.1),
|
|
422
|
+
complexity:
|
|
423
|
+
pattern.actions.length <= 3
|
|
424
|
+
? 'simple'
|
|
425
|
+
: pattern.actions.length <= 6
|
|
426
|
+
? 'moderate'
|
|
427
|
+
: 'complex',
|
|
428
|
+
estimatedEffort: Math.ceil(pattern.actions.length * 0.5),
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Generate a kebab-case playbook name
|
|
434
|
+
*/
|
|
435
|
+
private generatePlaybookName(pattern: ExtractedPattern): string {
|
|
436
|
+
const words = pattern.thought
|
|
437
|
+
.toLowerCase()
|
|
438
|
+
.replace(/[^\w\s]/g, '')
|
|
439
|
+
.split(/\s+/)
|
|
440
|
+
.filter((w) => w.length > 2 && !this.isStopWord(w))
|
|
441
|
+
.slice(0, 4);
|
|
442
|
+
|
|
443
|
+
if (words.length === 0) {
|
|
444
|
+
return `playbook-${Date.now()}`;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return words.join('-');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Check if word is a stop word
|
|
452
|
+
*/
|
|
453
|
+
private isStopWord(word: string): boolean {
|
|
454
|
+
const stopWords = new Set([
|
|
455
|
+
'the',
|
|
456
|
+
'a',
|
|
457
|
+
'an',
|
|
458
|
+
'and',
|
|
459
|
+
'or',
|
|
460
|
+
'but',
|
|
461
|
+
'is',
|
|
462
|
+
'are',
|
|
463
|
+
'was',
|
|
464
|
+
'were',
|
|
465
|
+
'be',
|
|
466
|
+
'been',
|
|
467
|
+
'being',
|
|
468
|
+
'have',
|
|
469
|
+
'has',
|
|
470
|
+
'had',
|
|
471
|
+
'do',
|
|
472
|
+
'does',
|
|
473
|
+
'did',
|
|
474
|
+
'will',
|
|
475
|
+
'would',
|
|
476
|
+
'could',
|
|
477
|
+
'should',
|
|
478
|
+
'may',
|
|
479
|
+
'might',
|
|
480
|
+
'must',
|
|
481
|
+
'shall',
|
|
482
|
+
'can',
|
|
483
|
+
'to',
|
|
484
|
+
'of',
|
|
485
|
+
'in',
|
|
486
|
+
'for',
|
|
487
|
+
'on',
|
|
488
|
+
'with',
|
|
489
|
+
'at',
|
|
490
|
+
'by',
|
|
491
|
+
'from',
|
|
492
|
+
'as',
|
|
493
|
+
'into',
|
|
494
|
+
'through',
|
|
495
|
+
'during',
|
|
496
|
+
'before',
|
|
497
|
+
'after',
|
|
498
|
+
'above',
|
|
499
|
+
'below',
|
|
500
|
+
'between',
|
|
501
|
+
'under',
|
|
502
|
+
'again',
|
|
503
|
+
'further',
|
|
504
|
+
'then',
|
|
505
|
+
'once',
|
|
506
|
+
'here',
|
|
507
|
+
'there',
|
|
508
|
+
'when',
|
|
509
|
+
'where',
|
|
510
|
+
'why',
|
|
511
|
+
'how',
|
|
512
|
+
'all',
|
|
513
|
+
'each',
|
|
514
|
+
'few',
|
|
515
|
+
'more',
|
|
516
|
+
'most',
|
|
517
|
+
'other',
|
|
518
|
+
'some',
|
|
519
|
+
'such',
|
|
520
|
+
'no',
|
|
521
|
+
'not',
|
|
522
|
+
'only',
|
|
523
|
+
'own',
|
|
524
|
+
'same',
|
|
525
|
+
'so',
|
|
526
|
+
'than',
|
|
527
|
+
'too',
|
|
528
|
+
'very',
|
|
529
|
+
'just',
|
|
530
|
+
]);
|
|
531
|
+
return stopWords.has(word);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Extract context from a trajectory
|
|
536
|
+
*/
|
|
537
|
+
private extractContext(trajectory: Trajectory): string {
|
|
538
|
+
// Try to extract meaningful context
|
|
539
|
+
const metadata = trajectory.task.metadata ?? {};
|
|
540
|
+
|
|
541
|
+
if (metadata.fileType) return `${metadata.fileType} files`;
|
|
542
|
+
if (metadata.framework) return `${metadata.framework} projects`;
|
|
543
|
+
if (metadata.language) return `${metadata.language} code`;
|
|
544
|
+
|
|
545
|
+
// Fall back to domain
|
|
546
|
+
return trajectory.task.domain;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Group trajectories by domain
|
|
551
|
+
*/
|
|
552
|
+
private groupByDomain(
|
|
553
|
+
trajectories: Trajectory[]
|
|
554
|
+
): Map<string, Trajectory[]> {
|
|
555
|
+
const groups = new Map<string, Trajectory[]>();
|
|
556
|
+
|
|
557
|
+
for (const trajectory of trajectories) {
|
|
558
|
+
const domain = trajectory.task.domain;
|
|
559
|
+
const existing = groups.get(domain) ?? [];
|
|
560
|
+
existing.push(trajectory);
|
|
561
|
+
groups.set(domain, existing);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return groups;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Consolidate similar playbooks
|
|
569
|
+
*/
|
|
570
|
+
async consolidate(playbooks: Playbook[]): Promise<Playbook[]> {
|
|
571
|
+
if (playbooks.length <= 1) return playbooks;
|
|
572
|
+
|
|
573
|
+
const consolidated: Playbook[] = [];
|
|
574
|
+
const merged = new Set<string>();
|
|
575
|
+
|
|
576
|
+
for (let i = 0; i < playbooks.length; i++) {
|
|
577
|
+
if (merged.has(playbooks[i].id)) continue;
|
|
578
|
+
|
|
579
|
+
let current = playbooks[i];
|
|
580
|
+
|
|
581
|
+
for (let j = i + 1; j < playbooks.length; j++) {
|
|
582
|
+
if (merged.has(playbooks[j].id)) continue;
|
|
583
|
+
|
|
584
|
+
const other = playbooks[j];
|
|
585
|
+
const similarity = this.calculatePlaybookSimilarity(current, other);
|
|
586
|
+
|
|
587
|
+
if (similarity > this.config.mergeThreshold) {
|
|
588
|
+
current = this.mergePlaybooks(current, other);
|
|
589
|
+
merged.add(other.id);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
consolidated.push(current);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
return consolidated;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Calculate similarity between two playbooks
|
|
601
|
+
*/
|
|
602
|
+
private calculatePlaybookSimilarity(a: Playbook, b: Playbook): number {
|
|
603
|
+
// Compare situations
|
|
604
|
+
let maxSituationSim = 0;
|
|
605
|
+
for (const sA of a.applicability.situations) {
|
|
606
|
+
for (const sB of b.applicability.situations) {
|
|
607
|
+
maxSituationSim = Math.max(maxSituationSim, textSimilarity(sA, sB));
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Compare guidance
|
|
612
|
+
const strategySim = textSimilarity(a.guidance.strategy, b.guidance.strategy);
|
|
613
|
+
|
|
614
|
+
// Combined score
|
|
615
|
+
return maxSituationSim * 0.6 + strategySim * 0.4;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Merge two similar playbooks
|
|
620
|
+
*/
|
|
621
|
+
private mergePlaybooks(a: Playbook, b: Playbook): Playbook {
|
|
622
|
+
return createPlaybook({
|
|
623
|
+
id: a.id,
|
|
624
|
+
name: a.name,
|
|
625
|
+
applicability: {
|
|
626
|
+
situations: [...new Set([...a.applicability.situations, ...b.applicability.situations])],
|
|
627
|
+
triggers: [...new Set([...a.applicability.triggers, ...b.applicability.triggers])],
|
|
628
|
+
antiPatterns: [...new Set([...a.applicability.antiPatterns, ...b.applicability.antiPatterns])],
|
|
629
|
+
domains: [...new Set([...a.applicability.domains, ...b.applicability.domains])],
|
|
630
|
+
},
|
|
631
|
+
guidance: {
|
|
632
|
+
strategy: a.guidance.strategy, // Keep first
|
|
633
|
+
tactics: [...new Set([...a.guidance.tactics, ...b.guidance.tactics])],
|
|
634
|
+
steps: a.guidance.steps ?? b.guidance.steps,
|
|
635
|
+
codeExample: a.guidance.codeExample ?? b.guidance.codeExample,
|
|
636
|
+
},
|
|
637
|
+
verification: {
|
|
638
|
+
successIndicators: [...new Set([...a.verification.successIndicators, ...b.verification.successIndicators])],
|
|
639
|
+
failureIndicators: [...new Set([...a.verification.failureIndicators, ...b.verification.failureIndicators])],
|
|
640
|
+
rollbackStrategy: a.verification.rollbackStrategy ?? b.verification.rollbackStrategy,
|
|
641
|
+
},
|
|
642
|
+
evolution: {
|
|
643
|
+
version: a.evolution.version,
|
|
644
|
+
createdFrom: [...new Set([...a.evolution.createdFrom, ...b.evolution.createdFrom])],
|
|
645
|
+
failures: [...a.evolution.failures, ...b.evolution.failures],
|
|
646
|
+
refinements: [...a.evolution.refinements, ...b.evolution.refinements],
|
|
647
|
+
successCount: a.evolution.successCount + b.evolution.successCount,
|
|
648
|
+
failureCount: a.evolution.failureCount + b.evolution.failureCount,
|
|
649
|
+
},
|
|
650
|
+
provenance: a.provenance, // Preserve provenance from primary playbook
|
|
651
|
+
confidence: Math.max(a.confidence, b.confidence),
|
|
652
|
+
complexity: a.complexity,
|
|
653
|
+
estimatedEffort: Math.min(a.estimatedEffort, b.estimatedEffort),
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Generate refinement from a failure
|
|
659
|
+
*/
|
|
660
|
+
async generateRefinement(
|
|
661
|
+
_playbook: Playbook,
|
|
662
|
+
failedTrajectory: Trajectory,
|
|
663
|
+
failureContext: string
|
|
664
|
+
): Promise<Refinement> {
|
|
665
|
+
// Analyze what was different in this failure
|
|
666
|
+
const context = this.extractContext(failedTrajectory);
|
|
667
|
+
|
|
668
|
+
// Try to identify what additional steps might help
|
|
669
|
+
const lastSteps = failedTrajectory.steps.slice(-3);
|
|
670
|
+
const suggestion = lastSteps.length > 0
|
|
671
|
+
? `Consider checking: ${lastSteps.map((s: { action: string }) => s.action).join(', ')}`
|
|
672
|
+
: `Review the approach for ${failureContext}`;
|
|
673
|
+
|
|
674
|
+
return {
|
|
675
|
+
context,
|
|
676
|
+
addition: suggestion,
|
|
677
|
+
source: 'failure',
|
|
678
|
+
addedAt: new Date(),
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Internal type for extracted patterns
|
|
685
|
+
*/
|
|
686
|
+
interface ExtractedPattern {
|
|
687
|
+
actions: string[];
|
|
688
|
+
normalizedActions: string[];
|
|
689
|
+
thought: string;
|
|
690
|
+
frequency: number;
|
|
691
|
+
trajectoryIds: string[];
|
|
692
|
+
errorTrigger?: string;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Create a playbook extractor
|
|
697
|
+
*/
|
|
698
|
+
export function createPlaybookExtractor(
|
|
699
|
+
config?: Partial<PlaybookExtractorConfig>
|
|
700
|
+
): PlaybookExtractor {
|
|
701
|
+
return new PlaybookExtractor(config);
|
|
702
|
+
}
|