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,594 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Library
|
|
3
|
+
* Tiered surfacing of playbooks for agent consumption
|
|
4
|
+
*
|
|
5
|
+
* Tiers:
|
|
6
|
+
* 1. Core Skills - Always in system prompt (highest confidence)
|
|
7
|
+
* 2. Domain Skills - Loaded when domain matches
|
|
8
|
+
* 3. Contextual - Injected based on task query
|
|
9
|
+
* 4. On-Demand - Available via MCP tool
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
Task,
|
|
14
|
+
Playbook,
|
|
15
|
+
SkillLibraryConfig,
|
|
16
|
+
} from '../types/index.js';
|
|
17
|
+
import type { PlaybookLibrary } from '../memory/playbook.js';
|
|
18
|
+
import { getPlaybookSuccessRate } from '../types/playbook.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Skills organized for agent context
|
|
22
|
+
*/
|
|
23
|
+
export interface AgentSkills {
|
|
24
|
+
/** Core skills - always included */
|
|
25
|
+
core: Playbook[];
|
|
26
|
+
/** Domain-specific skills */
|
|
27
|
+
domain: Playbook[];
|
|
28
|
+
/** Task-specific contextual playbooks */
|
|
29
|
+
contextual: Playbook[];
|
|
30
|
+
/** Estimated token count */
|
|
31
|
+
totalTokenEstimate: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Result of refreshing skill tiers
|
|
36
|
+
*/
|
|
37
|
+
export interface TierRefreshResult {
|
|
38
|
+
/** Playbook IDs promoted to core */
|
|
39
|
+
promoted: string[];
|
|
40
|
+
/** Playbook IDs demoted from core */
|
|
41
|
+
demoted: string[];
|
|
42
|
+
/** Current core skill count */
|
|
43
|
+
coreCount: number;
|
|
44
|
+
/** Domain skill counts */
|
|
45
|
+
domainCounts: Record<string, number>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Default configuration
|
|
50
|
+
*/
|
|
51
|
+
const DEFAULT_CONFIG: SkillLibraryConfig = {
|
|
52
|
+
promotion: {
|
|
53
|
+
minConfidence: 0.85,
|
|
54
|
+
minSuccessCount: 5,
|
|
55
|
+
minSuccessRate: 0.8,
|
|
56
|
+
},
|
|
57
|
+
limits: {
|
|
58
|
+
maxCoreSkills: 10,
|
|
59
|
+
maxDomainSkills: 5,
|
|
60
|
+
maxContextualPlaybooks: 3,
|
|
61
|
+
},
|
|
62
|
+
context: {
|
|
63
|
+
maxTokensForSkills: 2000,
|
|
64
|
+
includeRefinements: true,
|
|
65
|
+
includeExamples: false,
|
|
66
|
+
cacheRefreshInterval: 5 * 60 * 1000, // 5 minutes
|
|
67
|
+
},
|
|
68
|
+
demotion: {
|
|
69
|
+
failureThreshold: 3,
|
|
70
|
+
minConfidenceToRetain: 0.6,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Skill Library
|
|
76
|
+
* Manages tiered access to playbooks for agent consumption
|
|
77
|
+
*/
|
|
78
|
+
export class SkillLibrary {
|
|
79
|
+
private playbooks: PlaybookLibrary;
|
|
80
|
+
private config: SkillLibraryConfig;
|
|
81
|
+
|
|
82
|
+
// Cached promoted skills (refreshed periodically)
|
|
83
|
+
private coreSkills: Playbook[] = [];
|
|
84
|
+
private domainSkills: Map<string, Playbook[]> = new Map();
|
|
85
|
+
private lastRefresh: Date | null = null;
|
|
86
|
+
private consecutiveFailures: Map<string, number> = new Map();
|
|
87
|
+
|
|
88
|
+
constructor(
|
|
89
|
+
playbooks: PlaybookLibrary,
|
|
90
|
+
config?: Partial<SkillLibraryConfig>
|
|
91
|
+
) {
|
|
92
|
+
this.playbooks = playbooks;
|
|
93
|
+
this.config = this.mergeConfig(DEFAULT_CONFIG, config);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Merge configuration with defaults
|
|
98
|
+
*/
|
|
99
|
+
private mergeConfig(
|
|
100
|
+
defaults: SkillLibraryConfig,
|
|
101
|
+
overrides?: Partial<SkillLibraryConfig>
|
|
102
|
+
): SkillLibraryConfig {
|
|
103
|
+
if (!overrides) return defaults;
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
promotion: { ...defaults.promotion, ...overrides.promotion },
|
|
107
|
+
limits: { ...defaults.limits, ...overrides.limits },
|
|
108
|
+
context: { ...defaults.context, ...overrides.context },
|
|
109
|
+
demotion: { ...defaults.demotion, ...overrides.demotion },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// === TIER MANAGEMENT ===
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Refresh skill tiers based on current playbook state
|
|
117
|
+
* Called periodically or after significant learning
|
|
118
|
+
*/
|
|
119
|
+
async refreshTiers(): Promise<TierRefreshResult> {
|
|
120
|
+
const allPlaybooks = await this.playbooks.getAll();
|
|
121
|
+
const previousCoreIds = new Set(this.coreSkills.map((p) => p.id));
|
|
122
|
+
|
|
123
|
+
// Find playbooks that meet promotion criteria
|
|
124
|
+
const promotionCandidates = allPlaybooks
|
|
125
|
+
.filter((p) => this.meetsPromotionCriteria(p))
|
|
126
|
+
.sort((a, b) => {
|
|
127
|
+
// Sort by confidence * success rate
|
|
128
|
+
const scoreA = a.confidence * getPlaybookSuccessRate(a);
|
|
129
|
+
const scoreB = b.confidence * getPlaybookSuccessRate(b);
|
|
130
|
+
return scoreB - scoreA;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Check for demotions
|
|
134
|
+
const demotions: string[] = [];
|
|
135
|
+
for (const playbook of this.coreSkills) {
|
|
136
|
+
if (this.meetsDemotionCriteria(playbook)) {
|
|
137
|
+
demotions.push(playbook.id);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Update core skills (respecting max limit)
|
|
142
|
+
this.coreSkills = promotionCandidates
|
|
143
|
+
.filter((p) => !demotions.includes(p.id))
|
|
144
|
+
.slice(0, this.config.limits.maxCoreSkills);
|
|
145
|
+
|
|
146
|
+
const newCoreIds = new Set(this.coreSkills.map((p) => p.id));
|
|
147
|
+
|
|
148
|
+
// Calculate promotions and demotions
|
|
149
|
+
const promoted = [...newCoreIds].filter((id) => !previousCoreIds.has(id));
|
|
150
|
+
const demoted = [...previousCoreIds].filter((id) => !newCoreIds.has(id));
|
|
151
|
+
|
|
152
|
+
// Update domain skills
|
|
153
|
+
this.domainSkills.clear();
|
|
154
|
+
for (const playbook of allPlaybooks) {
|
|
155
|
+
if (newCoreIds.has(playbook.id)) continue; // Skip core skills
|
|
156
|
+
|
|
157
|
+
for (const domain of playbook.applicability.domains) {
|
|
158
|
+
const domainList = this.domainSkills.get(domain) ?? [];
|
|
159
|
+
|
|
160
|
+
if (domainList.length < this.config.limits.maxDomainSkills) {
|
|
161
|
+
domainList.push(playbook);
|
|
162
|
+
this.domainSkills.set(domain, domainList);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Sort domain skills by confidence
|
|
168
|
+
for (const [domain, skills] of this.domainSkills) {
|
|
169
|
+
this.domainSkills.set(
|
|
170
|
+
domain,
|
|
171
|
+
skills.sort((a, b) => b.confidence - a.confidence)
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this.lastRefresh = new Date();
|
|
176
|
+
|
|
177
|
+
// Build domain counts
|
|
178
|
+
const domainCounts: Record<string, number> = {};
|
|
179
|
+
for (const [domain, skills] of this.domainSkills) {
|
|
180
|
+
domainCounts[domain] = skills.length;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
promoted,
|
|
185
|
+
demoted,
|
|
186
|
+
coreCount: this.coreSkills.length,
|
|
187
|
+
domainCounts,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check if a playbook qualifies for core skill status
|
|
193
|
+
*/
|
|
194
|
+
private meetsPromotionCriteria(playbook: Playbook): boolean {
|
|
195
|
+
const { minConfidence, minSuccessCount, minSuccessRate } =
|
|
196
|
+
this.config.promotion;
|
|
197
|
+
const { successCount, failureCount } = playbook.evolution;
|
|
198
|
+
const totalUses = successCount + failureCount;
|
|
199
|
+
const actualSuccessRate = totalUses > 0 ? successCount / totalUses : 0;
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
playbook.confidence >= minConfidence &&
|
|
203
|
+
successCount >= minSuccessCount &&
|
|
204
|
+
actualSuccessRate >= minSuccessRate
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Check if a core skill should be demoted
|
|
210
|
+
*/
|
|
211
|
+
private meetsDemotionCriteria(playbook: Playbook): boolean {
|
|
212
|
+
const { failureThreshold, minConfidenceToRetain } = this.config.demotion;
|
|
213
|
+
const recentFailures = this.consecutiveFailures.get(playbook.id) ?? 0;
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
recentFailures >= failureThreshold ||
|
|
217
|
+
playbook.confidence < minConfidenceToRetain
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// === RETRIEVAL FOR AGENT CONTEXT ===
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get skills for agent system prompt
|
|
225
|
+
* Returns tiered skills based on task context
|
|
226
|
+
*/
|
|
227
|
+
async getSkillsForAgent(
|
|
228
|
+
task: Task,
|
|
229
|
+
options?: {
|
|
230
|
+
includeCore?: boolean;
|
|
231
|
+
includeDomain?: boolean;
|
|
232
|
+
includeContextual?: boolean;
|
|
233
|
+
}
|
|
234
|
+
): Promise<AgentSkills> {
|
|
235
|
+
const includeCore = options?.includeCore ?? true;
|
|
236
|
+
const includeDomain = options?.includeDomain ?? true;
|
|
237
|
+
const includeContextual = options?.includeContextual ?? true;
|
|
238
|
+
|
|
239
|
+
// Ensure tiers are fresh (refresh if older than cache interval)
|
|
240
|
+
if (
|
|
241
|
+
!this.lastRefresh ||
|
|
242
|
+
Date.now() - this.lastRefresh.getTime() > this.config.context.cacheRefreshInterval
|
|
243
|
+
) {
|
|
244
|
+
await this.refreshTiers();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const result: AgentSkills = {
|
|
248
|
+
core: [],
|
|
249
|
+
domain: [],
|
|
250
|
+
contextual: [],
|
|
251
|
+
totalTokenEstimate: 0,
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// Add core skills
|
|
255
|
+
if (includeCore) {
|
|
256
|
+
result.core = [...this.coreSkills];
|
|
257
|
+
result.totalTokenEstimate += this.estimateTokens(result.core);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Add domain skills
|
|
261
|
+
if (includeDomain && task.domain) {
|
|
262
|
+
const domainSkills = this.domainSkills.get(task.domain) ?? [];
|
|
263
|
+
result.domain = domainSkills.filter(
|
|
264
|
+
(p) => !result.core.some((c) => c.id === p.id)
|
|
265
|
+
);
|
|
266
|
+
result.totalTokenEstimate += this.estimateTokens(result.domain);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Add contextual playbooks (from query)
|
|
270
|
+
if (includeContextual) {
|
|
271
|
+
const matches = await this.playbooks.findMatching(task.description, {
|
|
272
|
+
k: this.config.limits.maxContextualPlaybooks,
|
|
273
|
+
domains: task.domain ? [task.domain] : undefined,
|
|
274
|
+
excludeAntiPatterns: true,
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
result.contextual = matches
|
|
278
|
+
.map((m) => m.playbook)
|
|
279
|
+
.filter(
|
|
280
|
+
(p) =>
|
|
281
|
+
!result.core.some((c) => c.id === p.id) &&
|
|
282
|
+
!result.domain.some((d) => d.id === p.id)
|
|
283
|
+
);
|
|
284
|
+
result.totalTokenEstimate += this.estimateTokens(result.contextual);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Trim if over token budget
|
|
288
|
+
while (
|
|
289
|
+
result.totalTokenEstimate > this.config.context.maxTokensForSkills &&
|
|
290
|
+
result.contextual.length > 0
|
|
291
|
+
) {
|
|
292
|
+
result.contextual.pop();
|
|
293
|
+
result.totalTokenEstimate = this.estimateTokens([
|
|
294
|
+
...result.core,
|
|
295
|
+
...result.domain,
|
|
296
|
+
...result.contextual,
|
|
297
|
+
]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Estimate token count for playbooks
|
|
305
|
+
*/
|
|
306
|
+
private estimateTokens(playbooks: Playbook[]): number {
|
|
307
|
+
let tokens = 0;
|
|
308
|
+
|
|
309
|
+
for (const playbook of playbooks) {
|
|
310
|
+
// Rough estimate: 4 characters per token
|
|
311
|
+
tokens += playbook.name.length / 4;
|
|
312
|
+
tokens += playbook.guidance.strategy.length / 4;
|
|
313
|
+
tokens += playbook.guidance.tactics.join(' ').length / 4;
|
|
314
|
+
|
|
315
|
+
if (this.config.context.includeRefinements) {
|
|
316
|
+
tokens +=
|
|
317
|
+
playbook.evolution.refinements
|
|
318
|
+
.map((r) => `${r.context}: ${r.addition}`)
|
|
319
|
+
.join(' ').length / 4;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (playbook.guidance.steps) {
|
|
323
|
+
tokens += playbook.guidance.steps.join(' ').length / 4;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return Math.ceil(tokens);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Format skills for system prompt injection
|
|
332
|
+
*/
|
|
333
|
+
formatForSystemPrompt(skills: AgentSkills): string {
|
|
334
|
+
const sections: string[] = [];
|
|
335
|
+
|
|
336
|
+
// Format core skills
|
|
337
|
+
if (skills.core.length > 0) {
|
|
338
|
+
sections.push('## Core Skills\n');
|
|
339
|
+
sections.push('These are proven approaches you should follow:\n');
|
|
340
|
+
for (const playbook of skills.core) {
|
|
341
|
+
sections.push(this.formatPlaybookForPrompt(playbook, 'core'));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Format domain skills
|
|
346
|
+
if (skills.domain.length > 0) {
|
|
347
|
+
sections.push('## Domain Skills\n');
|
|
348
|
+
for (const playbook of skills.domain) {
|
|
349
|
+
sections.push(this.formatPlaybookForPrompt(playbook, 'domain'));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Format contextual playbooks
|
|
354
|
+
if (skills.contextual.length > 0) {
|
|
355
|
+
sections.push('## Relevant Playbooks\n');
|
|
356
|
+
for (const playbook of skills.contextual) {
|
|
357
|
+
sections.push(this.formatPlaybookForPrompt(playbook, 'contextual'));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return sections.join('\n');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Format a single playbook for prompt
|
|
366
|
+
*/
|
|
367
|
+
private formatPlaybookForPrompt(
|
|
368
|
+
playbook: Playbook,
|
|
369
|
+
_tier: 'core' | 'domain' | 'contextual'
|
|
370
|
+
): string {
|
|
371
|
+
const lines: string[] = [];
|
|
372
|
+
const confidencePercent = Math.round(playbook.confidence * 100);
|
|
373
|
+
|
|
374
|
+
lines.push(`### ${playbook.name} (${confidencePercent}% confidence)`);
|
|
375
|
+
lines.push(`**When**: ${playbook.applicability.situations[0] ?? 'General use'}`);
|
|
376
|
+
lines.push(`**Strategy**: ${playbook.guidance.strategy}`);
|
|
377
|
+
|
|
378
|
+
if (playbook.guidance.tactics.length > 0) {
|
|
379
|
+
lines.push('**Tactics**:');
|
|
380
|
+
for (const tactic of playbook.guidance.tactics.slice(0, 5)) {
|
|
381
|
+
lines.push(` - ${tactic}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (
|
|
386
|
+
this.config.context.includeRefinements &&
|
|
387
|
+
playbook.evolution.refinements.length > 0
|
|
388
|
+
) {
|
|
389
|
+
lines.push('**Notes**:');
|
|
390
|
+
for (const ref of playbook.evolution.refinements.slice(0, 2)) {
|
|
391
|
+
lines.push(` - In ${ref.context}: ${ref.addition}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
lines.push('');
|
|
396
|
+
return lines.join('\n');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// === LIFECYCLE INTEGRATION ===
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Record playbook usage outcome (inferred from trajectory)
|
|
403
|
+
* Called by learning pipeline after trajectory analysis
|
|
404
|
+
*/
|
|
405
|
+
async recordOutcome(
|
|
406
|
+
playbookId: string,
|
|
407
|
+
trajectoryId: string,
|
|
408
|
+
success: boolean,
|
|
409
|
+
context?: string
|
|
410
|
+
): Promise<void> {
|
|
411
|
+
if (success) {
|
|
412
|
+
// Reset consecutive failures
|
|
413
|
+
this.consecutiveFailures.set(playbookId, 0);
|
|
414
|
+
await this.playbooks.recordSuccess(playbookId, trajectoryId);
|
|
415
|
+
} else {
|
|
416
|
+
// Increment consecutive failures
|
|
417
|
+
const currentFailures = this.consecutiveFailures.get(playbookId) ?? 0;
|
|
418
|
+
this.consecutiveFailures.set(playbookId, currentFailures + 1);
|
|
419
|
+
await this.playbooks.recordFailure(
|
|
420
|
+
playbookId,
|
|
421
|
+
trajectoryId,
|
|
422
|
+
context ?? 'Unknown',
|
|
423
|
+
'Task failed'
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Get promotion candidates
|
|
430
|
+
*/
|
|
431
|
+
async getPromotionCandidates(): Promise<Playbook[]> {
|
|
432
|
+
const allPlaybooks = await this.playbooks.getAll();
|
|
433
|
+
const coreIds = new Set(this.coreSkills.map((p) => p.id));
|
|
434
|
+
|
|
435
|
+
return allPlaybooks.filter(
|
|
436
|
+
(p) => !coreIds.has(p.id) && this.meetsPromotionCriteria(p)
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Get demotion candidates
|
|
442
|
+
*/
|
|
443
|
+
async getDemotionCandidates(): Promise<Playbook[]> {
|
|
444
|
+
return this.coreSkills.filter((p) => this.meetsDemotionCriteria(p));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Get current core skills
|
|
449
|
+
*/
|
|
450
|
+
getCoreSkills(): Playbook[] {
|
|
451
|
+
return [...this.coreSkills];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Get domain skills
|
|
456
|
+
*/
|
|
457
|
+
getDomainSkills(domain: string): Playbook[] {
|
|
458
|
+
return [...(this.domainSkills.get(domain) ?? [])];
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Get all domains with skills
|
|
463
|
+
*/
|
|
464
|
+
getDomains(): string[] {
|
|
465
|
+
return Array.from(this.domainSkills.keys());
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Get statistics
|
|
470
|
+
*/
|
|
471
|
+
getStats(): {
|
|
472
|
+
coreSkillCount: number;
|
|
473
|
+
domainSkillCounts: Record<string, number>;
|
|
474
|
+
lastRefresh: Date | null;
|
|
475
|
+
consecutiveFailures: Record<string, number>;
|
|
476
|
+
} {
|
|
477
|
+
const domainSkillCounts: Record<string, number> = {};
|
|
478
|
+
for (const [domain, skills] of this.domainSkills) {
|
|
479
|
+
domainSkillCounts[domain] = skills.length;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Convert consecutive failures map to record
|
|
483
|
+
const failureRecord: Record<string, number> = {};
|
|
484
|
+
for (const [id, count] of this.consecutiveFailures) {
|
|
485
|
+
if (count > 0) {
|
|
486
|
+
failureRecord[id] = count;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return {
|
|
491
|
+
coreSkillCount: this.coreSkills.length,
|
|
492
|
+
domainSkillCounts,
|
|
493
|
+
lastRefresh: this.lastRefresh,
|
|
494
|
+
consecutiveFailures: failureRecord,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Get consecutive failure count for a playbook
|
|
500
|
+
*/
|
|
501
|
+
getConsecutiveFailures(playbookId: string): number {
|
|
502
|
+
return this.consecutiveFailures.get(playbookId) ?? 0;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Reset consecutive failures for a playbook
|
|
507
|
+
*/
|
|
508
|
+
resetConsecutiveFailures(playbookId: string): void {
|
|
509
|
+
this.consecutiveFailures.delete(playbookId);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Get all playbooks at risk of demotion
|
|
514
|
+
*/
|
|
515
|
+
getAtRiskPlaybooks(): Array<{
|
|
516
|
+
playbook: Playbook;
|
|
517
|
+
consecutiveFailures: number;
|
|
518
|
+
failuresUntilDemotion: number;
|
|
519
|
+
}> {
|
|
520
|
+
const atRisk: Array<{
|
|
521
|
+
playbook: Playbook;
|
|
522
|
+
consecutiveFailures: number;
|
|
523
|
+
failuresUntilDemotion: number;
|
|
524
|
+
}> = [];
|
|
525
|
+
|
|
526
|
+
for (const playbook of this.coreSkills) {
|
|
527
|
+
const failures = this.consecutiveFailures.get(playbook.id) ?? 0;
|
|
528
|
+
const threshold = this.config.demotion.failureThreshold;
|
|
529
|
+
|
|
530
|
+
if (failures > 0) {
|
|
531
|
+
atRisk.push({
|
|
532
|
+
playbook,
|
|
533
|
+
consecutiveFailures: failures,
|
|
534
|
+
failuresUntilDemotion: Math.max(0, threshold - failures),
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return atRisk.sort(
|
|
540
|
+
(a, b) => a.failuresUntilDemotion - b.failuresUntilDemotion
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Apply time-based decay to consecutive failures
|
|
546
|
+
* Reduces failure counts for playbooks that haven't been used recently
|
|
547
|
+
* @param decayAmount Amount to reduce failure count by (default: 1)
|
|
548
|
+
*/
|
|
549
|
+
applyFailureDecay(decayAmount = 1): void {
|
|
550
|
+
for (const [playbookId, count] of this.consecutiveFailures) {
|
|
551
|
+
const newCount = Math.max(0, count - decayAmount);
|
|
552
|
+
if (newCount === 0) {
|
|
553
|
+
this.consecutiveFailures.delete(playbookId);
|
|
554
|
+
} else {
|
|
555
|
+
this.consecutiveFailures.set(playbookId, newCount);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Export consecutive failure state for persistence
|
|
562
|
+
*/
|
|
563
|
+
exportFailureState(): Record<string, number> {
|
|
564
|
+
const state: Record<string, number> = {};
|
|
565
|
+
for (const [id, count] of this.consecutiveFailures) {
|
|
566
|
+
if (count > 0) {
|
|
567
|
+
state[id] = count;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return state;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Import consecutive failure state from persistence
|
|
575
|
+
*/
|
|
576
|
+
importFailureState(state: Record<string, number>): void {
|
|
577
|
+
this.consecutiveFailures.clear();
|
|
578
|
+
for (const [id, count] of Object.entries(state)) {
|
|
579
|
+
if (count > 0) {
|
|
580
|
+
this.consecutiveFailures.set(id, count);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Create a skill library
|
|
588
|
+
*/
|
|
589
|
+
export function createSkillLibrary(
|
|
590
|
+
playbooks: PlaybookLibrary,
|
|
591
|
+
config?: Partial<SkillLibraryConfig>
|
|
592
|
+
): SkillLibrary {
|
|
593
|
+
return new SkillLibrary(playbooks, config);
|
|
594
|
+
}
|