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.
Files changed (329) hide show
  1. package/README.md +302 -116
  2. package/SKILL.md +193 -0
  3. package/dist/agents/index.d.ts +3 -0
  4. package/dist/agents/index.d.ts.map +1 -0
  5. package/dist/agents/index.js +5 -0
  6. package/dist/agents/index.js.map +1 -0
  7. package/dist/agents/mock-provider.d.ts +23 -0
  8. package/dist/agents/mock-provider.d.ts.map +1 -0
  9. package/dist/agents/mock-provider.js +71 -0
  10. package/dist/agents/mock-provider.js.map +1 -0
  11. package/dist/agents/types.d.ts +98 -0
  12. package/dist/agents/types.d.ts.map +1 -0
  13. package/dist/agents/types.js +44 -0
  14. package/dist/agents/types.js.map +1 -0
  15. package/dist/atlas.d.ts +196 -0
  16. package/dist/atlas.d.ts.map +1 -0
  17. package/dist/atlas.js +373 -0
  18. package/dist/atlas.js.map +1 -0
  19. package/dist/bin/cognitive-core.d.ts +18 -0
  20. package/dist/bin/cognitive-core.d.ts.map +1 -0
  21. package/dist/bin/cognitive-core.js +419 -0
  22. package/dist/bin/cognitive-core.js.map +1 -0
  23. package/dist/embeddings/bm25.d.ts +104 -0
  24. package/dist/embeddings/bm25.d.ts.map +1 -0
  25. package/dist/embeddings/bm25.js +264 -0
  26. package/dist/embeddings/bm25.js.map +1 -0
  27. package/dist/embeddings/index.d.ts +12 -0
  28. package/dist/embeddings/index.d.ts.map +1 -0
  29. package/dist/embeddings/index.js +16 -0
  30. package/dist/embeddings/index.js.map +1 -0
  31. package/dist/embeddings/manager.d.ts +112 -0
  32. package/dist/embeddings/manager.d.ts.map +1 -0
  33. package/dist/embeddings/manager.js +215 -0
  34. package/dist/embeddings/manager.js.map +1 -0
  35. package/dist/embeddings/provider.d.ts +101 -0
  36. package/dist/embeddings/provider.d.ts.map +1 -0
  37. package/dist/embeddings/provider.js +232 -0
  38. package/dist/embeddings/provider.js.map +1 -0
  39. package/dist/embeddings/vector-store.d.ts +101 -0
  40. package/dist/embeddings/vector-store.d.ts.map +1 -0
  41. package/dist/embeddings/vector-store.js +256 -0
  42. package/dist/embeddings/vector-store.js.map +1 -0
  43. package/dist/factory.d.ts +193 -0
  44. package/dist/factory.d.ts.map +1 -0
  45. package/dist/factory.js +109 -0
  46. package/dist/factory.js.map +1 -0
  47. package/dist/index.d.ts +30 -453
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +84 -509
  50. package/dist/index.js.map +1 -0
  51. package/dist/learning/analyzer.d.ts +110 -0
  52. package/dist/learning/analyzer.d.ts.map +1 -0
  53. package/dist/learning/analyzer.js +213 -0
  54. package/dist/learning/analyzer.js.map +1 -0
  55. package/dist/learning/effectiveness.d.ts +158 -0
  56. package/dist/learning/effectiveness.d.ts.map +1 -0
  57. package/dist/learning/effectiveness.js +251 -0
  58. package/dist/learning/effectiveness.js.map +1 -0
  59. package/dist/learning/index.d.ts +8 -0
  60. package/dist/learning/index.d.ts.map +1 -0
  61. package/dist/learning/index.js +11 -0
  62. package/dist/learning/index.js.map +1 -0
  63. package/dist/learning/llm-extractor.d.ts +88 -0
  64. package/dist/learning/llm-extractor.d.ts.map +1 -0
  65. package/dist/learning/llm-extractor.js +372 -0
  66. package/dist/learning/llm-extractor.js.map +1 -0
  67. package/dist/learning/meta-learner.d.ts +80 -0
  68. package/dist/learning/meta-learner.d.ts.map +1 -0
  69. package/dist/learning/meta-learner.js +355 -0
  70. package/dist/learning/meta-learner.js.map +1 -0
  71. package/dist/learning/pipeline.d.ts +65 -0
  72. package/dist/learning/pipeline.d.ts.map +1 -0
  73. package/dist/learning/pipeline.js +170 -0
  74. package/dist/learning/pipeline.js.map +1 -0
  75. package/dist/learning/playbook-extractor.d.ts +113 -0
  76. package/dist/learning/playbook-extractor.d.ts.map +1 -0
  77. package/dist/learning/playbook-extractor.js +523 -0
  78. package/dist/learning/playbook-extractor.js.map +1 -0
  79. package/dist/learning/usage-inference.d.ts +82 -0
  80. package/dist/learning/usage-inference.d.ts.map +1 -0
  81. package/dist/learning/usage-inference.js +261 -0
  82. package/dist/learning/usage-inference.js.map +1 -0
  83. package/dist/mcp/index.d.ts +6 -0
  84. package/dist/mcp/index.d.ts.map +1 -0
  85. package/dist/mcp/index.js +6 -0
  86. package/dist/mcp/index.js.map +1 -0
  87. package/dist/mcp/playbook-server.d.ts +120 -0
  88. package/dist/mcp/playbook-server.d.ts.map +1 -0
  89. package/dist/mcp/playbook-server.js +427 -0
  90. package/dist/mcp/playbook-server.js.map +1 -0
  91. package/dist/memory/curated-loader.d.ts +62 -0
  92. package/dist/memory/curated-loader.d.ts.map +1 -0
  93. package/dist/memory/curated-loader.js +106 -0
  94. package/dist/memory/curated-loader.js.map +1 -0
  95. package/dist/memory/experience.d.ts +122 -0
  96. package/dist/memory/experience.d.ts.map +1 -0
  97. package/dist/memory/experience.js +392 -0
  98. package/dist/memory/experience.js.map +1 -0
  99. package/dist/memory/index.d.ts +6 -0
  100. package/dist/memory/index.d.ts.map +1 -0
  101. package/dist/memory/index.js +9 -0
  102. package/dist/memory/index.js.map +1 -0
  103. package/dist/memory/meta.d.ts +90 -0
  104. package/dist/memory/meta.d.ts.map +1 -0
  105. package/dist/memory/meta.js +362 -0
  106. package/dist/memory/meta.js.map +1 -0
  107. package/dist/memory/playbook.d.ts +133 -0
  108. package/dist/memory/playbook.d.ts.map +1 -0
  109. package/dist/memory/playbook.js +357 -0
  110. package/dist/memory/playbook.js.map +1 -0
  111. package/dist/memory/system.d.ts +167 -0
  112. package/dist/memory/system.d.ts.map +1 -0
  113. package/dist/memory/system.js +383 -0
  114. package/dist/memory/system.js.map +1 -0
  115. package/dist/runtime/backends/acp.d.ts +67 -0
  116. package/dist/runtime/backends/acp.d.ts.map +1 -0
  117. package/dist/runtime/backends/acp.js +290 -0
  118. package/dist/runtime/backends/acp.js.map +1 -0
  119. package/dist/runtime/backends/index.d.ts +5 -0
  120. package/dist/runtime/backends/index.d.ts.map +1 -0
  121. package/dist/runtime/backends/index.js +6 -0
  122. package/dist/runtime/backends/index.js.map +1 -0
  123. package/dist/runtime/backends/mock.d.ts +67 -0
  124. package/dist/runtime/backends/mock.d.ts.map +1 -0
  125. package/dist/runtime/backends/mock.js +153 -0
  126. package/dist/runtime/backends/mock.js.map +1 -0
  127. package/dist/runtime/backends/subprocess.d.ts +56 -0
  128. package/dist/runtime/backends/subprocess.d.ts.map +1 -0
  129. package/dist/runtime/backends/subprocess.js +260 -0
  130. package/dist/runtime/backends/subprocess.js.map +1 -0
  131. package/dist/runtime/flows/learning.d.ts +73 -0
  132. package/dist/runtime/flows/learning.d.ts.map +1 -0
  133. package/dist/runtime/flows/learning.js +116 -0
  134. package/dist/runtime/flows/learning.js.map +1 -0
  135. package/dist/runtime/flows/validation.d.ts +122 -0
  136. package/dist/runtime/flows/validation.d.ts.map +1 -0
  137. package/dist/runtime/flows/validation.js +223 -0
  138. package/dist/runtime/flows/validation.js.map +1 -0
  139. package/dist/runtime/index.d.ts +6 -0
  140. package/dist/runtime/index.d.ts.map +1 -0
  141. package/dist/runtime/index.js +8 -0
  142. package/dist/runtime/index.js.map +1 -0
  143. package/dist/runtime/manager.d.ts +116 -0
  144. package/dist/runtime/manager.d.ts.map +1 -0
  145. package/dist/runtime/manager.js +416 -0
  146. package/dist/runtime/manager.js.map +1 -0
  147. package/dist/runtime/types.d.ts +138 -0
  148. package/dist/runtime/types.d.ts.map +1 -0
  149. package/dist/runtime/types.js +2 -0
  150. package/dist/runtime/types.js.map +1 -0
  151. package/dist/search/evaluator.d.ts +102 -0
  152. package/dist/search/evaluator.d.ts.map +1 -0
  153. package/dist/search/evaluator.js +352 -0
  154. package/dist/search/evaluator.js.map +1 -0
  155. package/dist/search/index.d.ts +7 -0
  156. package/dist/search/index.d.ts.map +1 -0
  157. package/dist/search/index.js +11 -0
  158. package/dist/search/index.js.map +1 -0
  159. package/dist/search/refinement-loop.d.ts +73 -0
  160. package/dist/search/refinement-loop.d.ts.map +1 -0
  161. package/dist/search/refinement-loop.js +245 -0
  162. package/dist/search/refinement-loop.js.map +1 -0
  163. package/dist/search/refinement-types.d.ts +154 -0
  164. package/dist/search/refinement-types.d.ts.map +1 -0
  165. package/dist/search/refinement-types.js +99 -0
  166. package/dist/search/refinement-types.js.map +1 -0
  167. package/dist/search/router.d.ts +61 -0
  168. package/dist/search/router.d.ts.map +1 -0
  169. package/dist/search/router.js +197 -0
  170. package/dist/search/router.js.map +1 -0
  171. package/dist/search/solver.d.ts +75 -0
  172. package/dist/search/solver.d.ts.map +1 -0
  173. package/dist/search/solver.js +216 -0
  174. package/dist/search/solver.js.map +1 -0
  175. package/dist/search/verification-runner.d.ts +125 -0
  176. package/dist/search/verification-runner.d.ts.map +1 -0
  177. package/dist/search/verification-runner.js +440 -0
  178. package/dist/search/verification-runner.js.map +1 -0
  179. package/dist/surfacing/index.d.ts +2 -0
  180. package/dist/surfacing/index.d.ts.map +1 -0
  181. package/dist/surfacing/index.js +2 -0
  182. package/dist/surfacing/index.js.map +1 -0
  183. package/dist/surfacing/skill-library.d.ts +158 -0
  184. package/dist/surfacing/skill-library.d.ts.map +1 -0
  185. package/dist/surfacing/skill-library.js +429 -0
  186. package/dist/surfacing/skill-library.js.map +1 -0
  187. package/dist/types/config.d.ts +1113 -0
  188. package/dist/types/config.d.ts.map +1 -0
  189. package/dist/types/config.js +274 -0
  190. package/dist/types/config.js.map +1 -0
  191. package/dist/types/index.d.ts +9 -0
  192. package/dist/types/index.d.ts.map +1 -0
  193. package/dist/types/index.js +14 -0
  194. package/dist/types/index.js.map +1 -0
  195. package/dist/types/memory.d.ts +339 -0
  196. package/dist/types/memory.d.ts.map +1 -0
  197. package/dist/types/memory.js +207 -0
  198. package/dist/types/memory.js.map +1 -0
  199. package/dist/types/meta.d.ts +146 -0
  200. package/dist/types/meta.d.ts.map +1 -0
  201. package/dist/types/meta.js +51 -0
  202. package/dist/types/meta.js.map +1 -0
  203. package/dist/types/outcome.d.ts +42 -0
  204. package/dist/types/outcome.d.ts.map +1 -0
  205. package/dist/types/outcome.js +50 -0
  206. package/dist/types/outcome.js.map +1 -0
  207. package/dist/types/playbook.d.ts +119 -0
  208. package/dist/types/playbook.d.ts.map +1 -0
  209. package/dist/types/playbook.js +71 -0
  210. package/dist/types/playbook.js.map +1 -0
  211. package/dist/types/step.d.ts +44 -0
  212. package/dist/types/step.d.ts.map +1 -0
  213. package/dist/types/step.js +32 -0
  214. package/dist/types/step.js.map +1 -0
  215. package/dist/types/task.d.ts +91 -0
  216. package/dist/types/task.d.ts.map +1 -0
  217. package/dist/types/task.js +39 -0
  218. package/dist/types/task.js.map +1 -0
  219. package/dist/types/trajectory.d.ts +221 -0
  220. package/dist/types/trajectory.d.ts.map +1 -0
  221. package/dist/types/trajectory.js +60 -0
  222. package/dist/types/trajectory.js.map +1 -0
  223. package/dist/utils/index.d.ts +4 -0
  224. package/dist/utils/index.d.ts.map +1 -0
  225. package/dist/utils/index.js +4 -0
  226. package/dist/utils/index.js.map +1 -0
  227. package/dist/utils/similarity.d.ts +31 -0
  228. package/dist/utils/similarity.d.ts.map +1 -0
  229. package/dist/utils/similarity.js +107 -0
  230. package/dist/utils/similarity.js.map +1 -0
  231. package/dist/utils/storage.d.ts +106 -0
  232. package/dist/utils/storage.d.ts.map +1 -0
  233. package/dist/utils/storage.js +203 -0
  234. package/dist/utils/storage.js.map +1 -0
  235. package/dist/utils/validation.d.ts +129 -0
  236. package/dist/utils/validation.d.ts.map +1 -0
  237. package/dist/utils/validation.js +171 -0
  238. package/dist/utils/validation.js.map +1 -0
  239. package/package.json +50 -34
  240. package/scripts/migrate-to-playbooks.ts +307 -0
  241. package/src/agents/index.ts +14 -0
  242. package/src/agents/mock-provider.ts +93 -0
  243. package/src/agents/types.ts +137 -0
  244. package/src/atlas.ts +560 -0
  245. package/src/bin/cognitive-core.ts +470 -0
  246. package/src/embeddings/bm25.ts +337 -0
  247. package/src/embeddings/index.ts +39 -0
  248. package/src/embeddings/manager.ts +288 -0
  249. package/src/embeddings/provider.ts +311 -0
  250. package/src/embeddings/vector-store.ts +353 -0
  251. package/src/factory.ts +263 -0
  252. package/src/index.ts +246 -0
  253. package/src/learning/analyzer.ts +335 -0
  254. package/src/learning/effectiveness.ts +428 -0
  255. package/src/learning/index.ts +58 -0
  256. package/src/learning/llm-extractor.ts +542 -0
  257. package/src/learning/meta-learner.ts +516 -0
  258. package/src/learning/pipeline.ts +244 -0
  259. package/src/learning/playbook-extractor.ts +702 -0
  260. package/src/learning/usage-inference.ts +372 -0
  261. package/src/mcp/index.ts +12 -0
  262. package/src/mcp/playbook-server.ts +565 -0
  263. package/src/memory/curated-loader.ts +160 -0
  264. package/src/memory/experience.ts +515 -0
  265. package/src/memory/index.ts +27 -0
  266. package/src/memory/meta.ts +506 -0
  267. package/src/memory/playbook.ts +493 -0
  268. package/src/memory/system.ts +551 -0
  269. package/src/runtime/backends/acp.ts +378 -0
  270. package/src/runtime/backends/index.ts +24 -0
  271. package/src/runtime/backends/mock.ts +218 -0
  272. package/src/runtime/backends/subprocess.ts +356 -0
  273. package/src/runtime/flows/learning.ts +183 -0
  274. package/src/runtime/flows/validation.ts +381 -0
  275. package/src/runtime/index.ts +53 -0
  276. package/src/runtime/manager.ts +541 -0
  277. package/src/runtime/types.ts +157 -0
  278. package/src/search/evaluator.ts +474 -0
  279. package/src/search/index.ts +59 -0
  280. package/src/search/refinement-loop.ts +363 -0
  281. package/src/search/refinement-types.ts +159 -0
  282. package/src/search/router.ts +261 -0
  283. package/src/search/solver.ts +303 -0
  284. package/src/search/verification-runner.ts +570 -0
  285. package/src/surfacing/index.ts +6 -0
  286. package/src/surfacing/skill-library.ts +594 -0
  287. package/src/types/config.ts +333 -0
  288. package/src/types/index.ts +130 -0
  289. package/src/types/memory.ts +270 -0
  290. package/src/types/meta.ts +218 -0
  291. package/src/types/outcome.ts +66 -0
  292. package/src/types/playbook.ts +196 -0
  293. package/src/types/step.ts +40 -0
  294. package/src/types/task.ts +52 -0
  295. package/src/types/trajectory.ts +80 -0
  296. package/src/utils/index.ts +38 -0
  297. package/src/utils/similarity.ts +139 -0
  298. package/src/utils/storage.ts +249 -0
  299. package/src/utils/validation.ts +286 -0
  300. package/tests/embeddings/bm25.test.ts +130 -0
  301. package/tests/embeddings/manager.test.ts +205 -0
  302. package/tests/integration/atlas.test.ts +266 -0
  303. package/tests/integration/e2e.test.ts +929 -0
  304. package/tests/learning/analyzer.test.ts +426 -0
  305. package/tests/learning/effectiveness.test.ts +542 -0
  306. package/tests/learning/pipeline.test.ts +176 -0
  307. package/tests/learning/playbook-extractor-provenance.test.ts +114 -0
  308. package/tests/learning/usage-inference.test.ts +254 -0
  309. package/tests/mcp/playbook-server.test.ts +252 -0
  310. package/tests/memory/experience.test.ts +198 -0
  311. package/tests/memory/playbook.test.ts +338 -0
  312. package/tests/memory/provenance.test.ts +639 -0
  313. package/tests/memory/system.test.ts +325 -0
  314. package/tests/runtime/agent-manager.test.ts +512 -0
  315. package/tests/runtime/mock-backend.test.ts +248 -0
  316. package/tests/search/refinement-loop.test.ts +468 -0
  317. package/tests/search/refinement.test.ts +267 -0
  318. package/tests/search/router.test.ts +427 -0
  319. package/tests/surfacing/skill-library.test.ts +292 -0
  320. package/tests/types/outcome.test.ts +147 -0
  321. package/tests/types/step.test.ts +133 -0
  322. package/tests/types/task.test.ts +158 -0
  323. package/tests/types/trajectory.test.ts +253 -0
  324. package/tests/utils/similarity.test.ts +188 -0
  325. package/tests/utils/validation.test.ts +252 -0
  326. package/tsconfig.json +25 -0
  327. package/vitest.config.ts +22 -0
  328. package/dist/index.d.mts +0 -466
  329. package/dist/index.mjs +0 -478
@@ -0,0 +1,292 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { SkillLibrary, createSkillLibrary } from '../../src/surfacing/skill-library.js';
3
+ import { PlaybookLibrary, createPlaybookLibrary } from '../../src/memory/playbook.js';
4
+ import type { Playbook } from '../../src/types/playbook.js';
5
+ import type { Task } from '../../src/types/task.js';
6
+ import { mkdtemp, rm } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { tmpdir } from 'node:os';
9
+
10
+ describe('SkillLibrary', () => {
11
+ let tempDir: string;
12
+ let playbooks: PlaybookLibrary;
13
+ let skillLibrary: SkillLibrary;
14
+
15
+ beforeEach(async () => {
16
+ tempDir = await mkdtemp(join(tmpdir(), 'atlas-test-'));
17
+ playbooks = createPlaybookLibrary(tempDir);
18
+ await playbooks.init();
19
+ skillLibrary = createSkillLibrary(playbooks, {
20
+ promotion: {
21
+ minConfidence: 0.85,
22
+ minSuccessCount: 3,
23
+ minSuccessRate: 0.8,
24
+ },
25
+ limits: {
26
+ maxCoreSkills: 5,
27
+ maxDomainSkills: 3,
28
+ maxContextualPlaybooks: 2,
29
+ },
30
+ });
31
+ });
32
+
33
+ afterEach(async () => {
34
+ await playbooks.close();
35
+ await rm(tempDir, { recursive: true, force: true });
36
+ });
37
+
38
+ function createSamplePlaybook(overrides?: Partial<Playbook>): Playbook {
39
+ return {
40
+ id: `playbook-${Date.now()}-${Math.random().toString(36).slice(2)}`,
41
+ name: 'sample-playbook',
42
+ applicability: {
43
+ situations: ['General coding task'],
44
+ triggers: [],
45
+ antiPatterns: [],
46
+ domains: ['code'],
47
+ },
48
+ guidance: {
49
+ strategy: 'Follow best practices',
50
+ tactics: ['Read code', 'Understand context', 'Make changes'],
51
+ },
52
+ verification: {
53
+ successIndicators: ['Tests pass'],
54
+ failureIndicators: ['Tests fail'],
55
+ },
56
+ evolution: {
57
+ version: '1.0.0',
58
+ createdFrom: [],
59
+ failures: [],
60
+ refinements: [],
61
+ successCount: 0,
62
+ failureCount: 0,
63
+ },
64
+ confidence: 0.5,
65
+ complexity: 'moderate',
66
+ estimatedEffort: 3,
67
+ createdAt: new Date(),
68
+ updatedAt: new Date(),
69
+ ...overrides,
70
+ };
71
+ }
72
+
73
+ function createSampleTask(overrides?: Partial<Task>): Task {
74
+ return {
75
+ id: `task-${Date.now()}`,
76
+ description: 'Fix the bug in the code',
77
+ domain: 'code',
78
+ context: {},
79
+ metadata: {},
80
+ createdAt: new Date(),
81
+ ...overrides,
82
+ };
83
+ }
84
+
85
+ describe('refreshTiers', () => {
86
+ it('should promote high-confidence playbooks to core', async () => {
87
+ // Create a playbook that meets promotion criteria
88
+ const coreCandidate = createSamplePlaybook({
89
+ name: 'core-skill',
90
+ confidence: 0.9,
91
+ evolution: {
92
+ version: '1.0.0',
93
+ createdFrom: [],
94
+ failures: [],
95
+ refinements: [],
96
+ successCount: 10,
97
+ failureCount: 1,
98
+ },
99
+ });
100
+ await playbooks.add(coreCandidate);
101
+
102
+ // Create a low-confidence playbook
103
+ const lowConf = createSamplePlaybook({
104
+ name: 'low-conf',
105
+ confidence: 0.3,
106
+ });
107
+ await playbooks.add(lowConf);
108
+
109
+ const result = await skillLibrary.refreshTiers();
110
+
111
+ expect(result.promoted).toContain(coreCandidate.id);
112
+ expect(result.coreCount).toBeGreaterThanOrEqual(1);
113
+ });
114
+
115
+ it('should respect maxCoreSkills limit', async () => {
116
+ // Add more than maxCoreSkills (5) high-confidence playbooks
117
+ for (let i = 0; i < 7; i++) {
118
+ await playbooks.add(createSamplePlaybook({
119
+ name: `core-${i}`,
120
+ confidence: 0.9 + (i * 0.01),
121
+ evolution: {
122
+ version: '1.0.0',
123
+ createdFrom: [],
124
+ failures: [],
125
+ refinements: [],
126
+ successCount: 10,
127
+ failureCount: 0,
128
+ },
129
+ }));
130
+ }
131
+
132
+ const result = await skillLibrary.refreshTiers();
133
+
134
+ expect(result.coreCount).toBeLessThanOrEqual(5);
135
+ });
136
+ });
137
+
138
+ describe('getSkillsForAgent', () => {
139
+ it('should return skills for a task', async () => {
140
+ // Add a high-confidence playbook
141
+ await playbooks.add(createSamplePlaybook({
142
+ name: 'core-skill',
143
+ confidence: 0.9,
144
+ evolution: {
145
+ version: '1.0.0',
146
+ createdFrom: [],
147
+ failures: [],
148
+ refinements: [],
149
+ successCount: 10,
150
+ failureCount: 1,
151
+ },
152
+ }));
153
+
154
+ // Add a domain-specific playbook
155
+ await playbooks.add(createSamplePlaybook({
156
+ name: 'typescript-skill',
157
+ confidence: 0.7,
158
+ applicability: {
159
+ situations: ['TypeScript debugging'],
160
+ triggers: ['TS2322'],
161
+ antiPatterns: [],
162
+ domains: ['typescript'],
163
+ },
164
+ }));
165
+
166
+ await skillLibrary.refreshTiers();
167
+
168
+ const task = createSampleTask({
169
+ description: 'Fix TypeScript type error',
170
+ domain: 'typescript',
171
+ });
172
+
173
+ const skills = await skillLibrary.getSkillsForAgent(task);
174
+
175
+ expect(skills).toBeDefined();
176
+ expect(skills.totalTokenEstimate).toBeGreaterThan(0);
177
+ });
178
+
179
+ it('should respect includeCore option', async () => {
180
+ await playbooks.add(createSamplePlaybook({
181
+ name: 'core-skill',
182
+ confidence: 0.95,
183
+ evolution: {
184
+ version: '1.0.0',
185
+ createdFrom: [],
186
+ failures: [],
187
+ refinements: [],
188
+ successCount: 10,
189
+ failureCount: 0,
190
+ },
191
+ }));
192
+
193
+ await skillLibrary.refreshTiers();
194
+
195
+ const task = createSampleTask();
196
+
197
+ const withCore = await skillLibrary.getSkillsForAgent(task, { includeCore: true });
198
+ const withoutCore = await skillLibrary.getSkillsForAgent(task, { includeCore: false });
199
+
200
+ expect(withCore.core.length).toBeGreaterThanOrEqual(withoutCore.core.length);
201
+ });
202
+ });
203
+
204
+ describe('formatForSystemPrompt', () => {
205
+ it('should format skills as markdown', async () => {
206
+ await playbooks.add(createSamplePlaybook({
207
+ name: 'test-skill',
208
+ confidence: 0.9,
209
+ guidance: {
210
+ strategy: 'Test strategy',
211
+ tactics: ['Tactic 1', 'Tactic 2'],
212
+ },
213
+ evolution: {
214
+ version: '1.0.0',
215
+ createdFrom: [],
216
+ failures: [],
217
+ refinements: [],
218
+ successCount: 10,
219
+ failureCount: 0,
220
+ },
221
+ }));
222
+
223
+ await skillLibrary.refreshTiers();
224
+
225
+ const skills = await skillLibrary.getSkillsForAgent(createSampleTask());
226
+ const formatted = skillLibrary.formatForSystemPrompt(skills);
227
+
228
+ expect(formatted).toContain('Skills');
229
+ expect(typeof formatted).toBe('string');
230
+ });
231
+ });
232
+
233
+ describe('recordOutcome', () => {
234
+ it('should record playbook usage outcome', async () => {
235
+ const playbook = createSamplePlaybook({ name: 'tracked-playbook' });
236
+ await playbooks.add(playbook);
237
+
238
+ await skillLibrary.recordOutcome(playbook.id, 'traj-1', true);
239
+ await skillLibrary.recordOutcome(playbook.id, 'traj-2', true);
240
+ await skillLibrary.recordOutcome(playbook.id, 'traj-3', false);
241
+
242
+ const updated = await playbooks.get(playbook.id);
243
+ expect(updated?.evolution.successCount).toBe(2);
244
+ expect(updated?.evolution.failureCount).toBe(1);
245
+ });
246
+ });
247
+
248
+ describe('getPromotionCandidates and getDemotionCandidates', () => {
249
+ it('should return playbooks eligible for promotion', async () => {
250
+ // High performer not yet promoted
251
+ await playbooks.add(createSamplePlaybook({
252
+ name: 'promotion-candidate',
253
+ confidence: 0.86,
254
+ evolution: {
255
+ version: '1.0.0',
256
+ createdFrom: [],
257
+ failures: [],
258
+ refinements: [],
259
+ successCount: 5,
260
+ failureCount: 0,
261
+ },
262
+ }));
263
+
264
+ const candidates = await skillLibrary.getPromotionCandidates();
265
+ expect(candidates.length).toBeGreaterThanOrEqual(1);
266
+ });
267
+ });
268
+
269
+ describe('getStats', () => {
270
+ it('should return library statistics', async () => {
271
+ await playbooks.add(createSamplePlaybook({
272
+ name: 'core-1',
273
+ confidence: 0.95,
274
+ evolution: {
275
+ version: '1.0.0',
276
+ createdFrom: [],
277
+ failures: [],
278
+ refinements: [],
279
+ successCount: 10,
280
+ failureCount: 0,
281
+ },
282
+ }));
283
+
284
+ await skillLibrary.refreshTiers();
285
+
286
+ const stats = skillLibrary.getStats();
287
+ expect(stats).toHaveProperty('coreSkillCount');
288
+ expect(stats).toHaveProperty('domainSkillCounts');
289
+ expect(typeof stats.coreSkillCount).toBe('number');
290
+ });
291
+ });
292
+ });
@@ -0,0 +1,147 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ OutcomeSchema,
4
+ successOutcome,
5
+ failureOutcome,
6
+ partialOutcome,
7
+ type Outcome,
8
+ } from '../../src/types/outcome.js';
9
+
10
+ describe('Outcome', () => {
11
+ it('should validate a successful outcome', () => {
12
+ const outcome: Outcome = {
13
+ success: true,
14
+ partialScore: 1.0,
15
+ solution: { result: 42 },
16
+ verificationDetails: { method: 'exact_match' },
17
+ };
18
+ const result = OutcomeSchema.parse(outcome);
19
+ expect(result.success).toBe(true);
20
+ expect(result.partialScore).toBe(1.0);
21
+ expect(result.solution).toEqual({ result: 42 });
22
+ });
23
+
24
+ it('should validate a failed outcome with error', () => {
25
+ const outcome: Outcome = {
26
+ success: false,
27
+ partialScore: 0,
28
+ errorInfo: 'Timeout exceeded',
29
+ verificationDetails: {},
30
+ };
31
+ const result = OutcomeSchema.parse(outcome);
32
+ expect(result.success).toBe(false);
33
+ expect(result.errorInfo).toBe('Timeout exceeded');
34
+ });
35
+
36
+ it('should apply defaults', () => {
37
+ const outcome = OutcomeSchema.parse({
38
+ success: true,
39
+ });
40
+ expect(outcome.partialScore).toBe(0);
41
+ expect(outcome.verificationDetails).toEqual({});
42
+ });
43
+
44
+ it('should validate partialScore bounds', () => {
45
+ // Valid scores
46
+ expect(OutcomeSchema.parse({ success: false, partialScore: 0 }).partialScore).toBe(0);
47
+ expect(OutcomeSchema.parse({ success: false, partialScore: 0.5 }).partialScore).toBe(0.5);
48
+ expect(OutcomeSchema.parse({ success: true, partialScore: 1 }).partialScore).toBe(1);
49
+ });
50
+
51
+ it('should reject partialScore out of bounds', () => {
52
+ expect(() =>
53
+ OutcomeSchema.parse({ success: false, partialScore: -0.1 })
54
+ ).toThrow();
55
+
56
+ expect(() =>
57
+ OutcomeSchema.parse({ success: true, partialScore: 1.5 })
58
+ ).toThrow();
59
+ });
60
+
61
+ it('should allow various solution types', () => {
62
+ // String solution
63
+ expect(
64
+ OutcomeSchema.parse({ success: true, solution: 'answer' }).solution
65
+ ).toBe('answer');
66
+
67
+ // Number solution
68
+ expect(
69
+ OutcomeSchema.parse({ success: true, solution: 42 }).solution
70
+ ).toBe(42);
71
+
72
+ // Array solution
73
+ expect(
74
+ OutcomeSchema.parse({ success: true, solution: [1, 2, 3] }).solution
75
+ ).toEqual([1, 2, 3]);
76
+
77
+ // Object solution
78
+ expect(
79
+ OutcomeSchema.parse({ success: true, solution: { a: 1 } }).solution
80
+ ).toEqual({ a: 1 });
81
+ });
82
+ });
83
+
84
+ describe('successOutcome', () => {
85
+ it('should create a successful outcome with solution', () => {
86
+ const outcome = successOutcome('correct answer');
87
+ expect(outcome.success).toBe(true);
88
+ expect(outcome.partialScore).toBe(1.0);
89
+ expect(outcome.solution).toBe('correct answer');
90
+ expect(outcome.errorInfo).toBeUndefined();
91
+ });
92
+
93
+ it('should create a successful outcome with details', () => {
94
+ const outcome = successOutcome(42, { checked: true, time_ms: 100 });
95
+ expect(outcome.solution).toBe(42);
96
+ expect(outcome.verificationDetails.checked).toBe(true);
97
+ expect(outcome.verificationDetails.time_ms).toBe(100);
98
+ });
99
+
100
+ it('should accept complex solutions', () => {
101
+ const solution = {
102
+ grid: [[1, 2], [3, 4]],
103
+ metadata: { transformed: true },
104
+ };
105
+ const outcome = successOutcome(solution);
106
+ expect(outcome.solution).toEqual(solution);
107
+ });
108
+ });
109
+
110
+ describe('failureOutcome', () => {
111
+ it('should create a failed outcome with error', () => {
112
+ const outcome = failureOutcome('Test failed: assertion error');
113
+ expect(outcome.success).toBe(false);
114
+ expect(outcome.partialScore).toBe(0);
115
+ expect(outcome.errorInfo).toBe('Test failed: assertion error');
116
+ expect(outcome.solution).toBeUndefined();
117
+ });
118
+
119
+ it('should create a failed outcome with partial score', () => {
120
+ const outcome = failureOutcome('Incomplete solution', 0.4);
121
+ expect(outcome.success).toBe(false);
122
+ expect(outcome.partialScore).toBe(0.4);
123
+ expect(outcome.errorInfo).toBe('Incomplete solution');
124
+ });
125
+
126
+ it('should create a failed outcome with details', () => {
127
+ const outcome = failureOutcome('Error', 0.2, { attempts: 3 });
128
+ expect(outcome.verificationDetails.attempts).toBe(3);
129
+ });
130
+ });
131
+
132
+ describe('partialOutcome', () => {
133
+ it('should create a partial outcome', () => {
134
+ const outcome = partialOutcome(0.7, 'almost correct');
135
+ expect(outcome.success).toBe(false);
136
+ expect(outcome.partialScore).toBe(0.7);
137
+ expect(outcome.solution).toBe('almost correct');
138
+ expect(outcome.errorInfo).toBeUndefined();
139
+ });
140
+
141
+ it('should create a partial outcome with details', () => {
142
+ const outcome = partialOutcome(0.5, [1, 2, 3], { matched: 2, total: 4 });
143
+ expect(outcome.partialScore).toBe(0.5);
144
+ expect(outcome.solution).toEqual([1, 2, 3]);
145
+ expect(outcome.verificationDetails.matched).toBe(2);
146
+ });
147
+ });
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { StepSchema, createStep, type Step } from '../../src/types/step.js';
3
+
4
+ describe('Step', () => {
5
+ it('should validate a complete step', () => {
6
+ const step: Step = {
7
+ thought: 'I need to read the file first',
8
+ action: 'read_file("main.ts")',
9
+ observation: 'File contents: export function main() {}',
10
+ timestamp: new Date(),
11
+ metadata: { tool: 'read_file' },
12
+ attributionScore: 0.8,
13
+ };
14
+ const result = StepSchema.parse(step);
15
+ expect(result.thought).toBe('I need to read the file first');
16
+ expect(result.action).toBe('read_file("main.ts")');
17
+ expect(result.observation).toBe('File contents: export function main() {}');
18
+ expect(result.attributionScore).toBe(0.8);
19
+ });
20
+
21
+ it('should validate a step without thought', () => {
22
+ const step = StepSchema.parse({
23
+ action: 'run_command("npm test")',
24
+ observation: 'All tests passed',
25
+ });
26
+ expect(step.thought).toBeUndefined();
27
+ expect(step.action).toBe('run_command("npm test")');
28
+ });
29
+
30
+ it('should apply defaults for optional fields', () => {
31
+ const step = StepSchema.parse({
32
+ action: 'search("pattern")',
33
+ observation: 'Found 3 matches',
34
+ });
35
+ expect(step.metadata).toEqual({});
36
+ expect(step.timestamp).toBeInstanceOf(Date);
37
+ expect(step.attributionScore).toBeUndefined();
38
+ });
39
+
40
+ it('should validate attribution score bounds', () => {
41
+ // Valid score
42
+ const validStep = StepSchema.parse({
43
+ action: 'test',
44
+ observation: 'result',
45
+ attributionScore: 0.5,
46
+ });
47
+ expect(validStep.attributionScore).toBe(0.5);
48
+
49
+ // Score at minimum
50
+ const minStep = StepSchema.parse({
51
+ action: 'test',
52
+ observation: 'result',
53
+ attributionScore: 0,
54
+ });
55
+ expect(minStep.attributionScore).toBe(0);
56
+
57
+ // Score at maximum
58
+ const maxStep = StepSchema.parse({
59
+ action: 'test',
60
+ observation: 'result',
61
+ attributionScore: 1,
62
+ });
63
+ expect(maxStep.attributionScore).toBe(1);
64
+ });
65
+
66
+ it('should reject attribution scores out of bounds', () => {
67
+ expect(() =>
68
+ StepSchema.parse({
69
+ action: 'test',
70
+ observation: 'result',
71
+ attributionScore: -0.1,
72
+ })
73
+ ).toThrow();
74
+
75
+ expect(() =>
76
+ StepSchema.parse({
77
+ action: 'test',
78
+ observation: 'result',
79
+ attributionScore: 1.1,
80
+ })
81
+ ).toThrow();
82
+ });
83
+ });
84
+
85
+ describe('createStep', () => {
86
+ it('should create a step with required fields', () => {
87
+ const step = createStep({
88
+ action: 'write_file("output.txt", "data")',
89
+ observation: 'File written successfully',
90
+ });
91
+ expect(step.action).toBe('write_file("output.txt", "data")');
92
+ expect(step.observation).toBe('File written successfully');
93
+ expect(step.timestamp).toBeInstanceOf(Date);
94
+ });
95
+
96
+ it('should create a step with thought', () => {
97
+ const step = createStep({
98
+ thought: 'First, I should analyze the error message',
99
+ action: 'analyze_error()',
100
+ observation: 'Error: undefined variable x',
101
+ });
102
+ expect(step.thought).toBe('First, I should analyze the error message');
103
+ });
104
+
105
+ it('should create a step with metadata', () => {
106
+ const step = createStep({
107
+ action: 'api_call()',
108
+ observation: 'Response: 200 OK',
109
+ metadata: { duration_ms: 150, cached: false },
110
+ });
111
+ expect(step.metadata.duration_ms).toBe(150);
112
+ expect(step.metadata.cached).toBe(false);
113
+ });
114
+
115
+ it('should set timestamp to current time', () => {
116
+ const before = new Date();
117
+ const step = createStep({
118
+ action: 'test_action',
119
+ observation: 'test_observation',
120
+ });
121
+ const after = new Date();
122
+ expect(step.timestamp.getTime()).toBeGreaterThanOrEqual(before.getTime());
123
+ expect(step.timestamp.getTime()).toBeLessThanOrEqual(after.getTime());
124
+ });
125
+
126
+ it('should not set attributionScore by default', () => {
127
+ const step = createStep({
128
+ action: 'action',
129
+ observation: 'observation',
130
+ });
131
+ expect(step.attributionScore).toBeUndefined();
132
+ });
133
+ });