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,356 @@
1
+ import { spawn, type ChildProcess } from 'child_process';
2
+ import { EventEmitter } from 'events';
3
+ import type {
4
+ AgentBackend,
5
+ AgentSpawnConfig,
6
+ AgentSession,
7
+ AgentMessage,
8
+ ToolCall,
9
+ } from '../types.js';
10
+
11
+ /**
12
+ * Configuration for subprocess-based agents
13
+ */
14
+ export interface SubprocessAgentConfig {
15
+ /** Command to run the agent */
16
+ command: string;
17
+ /** Arguments for the command */
18
+ args?: string[];
19
+ /** How to pass the task to the agent */
20
+ taskPassingMode: 'stdin' | 'arg' | 'env' | 'file';
21
+ /** Environment variable name for task (if taskPassingMode is 'env') */
22
+ taskEnvVar?: string;
23
+ /** How to pass knowledge injection */
24
+ knowledgePassingMode: 'stdin' | 'env' | 'file' | 'system-prompt';
25
+ /** Environment variable name for knowledge (if knowledgePassingMode is 'env') */
26
+ knowledgeEnvVar?: string;
27
+ /** Parser for agent output to extract tool calls */
28
+ outputParser?: (output: string) => {
29
+ messages: AgentMessage[];
30
+ toolCalls: ToolCall[];
31
+ result?: unknown;
32
+ isComplete: boolean;
33
+ };
34
+ }
35
+
36
+ /**
37
+ * Running subprocess session
38
+ */
39
+ interface SubprocessSession {
40
+ session: AgentSession;
41
+ process: ChildProcess;
42
+ outputBuffer: string;
43
+ emitter: EventEmitter;
44
+ }
45
+
46
+ /**
47
+ * Subprocess-based agent backend
48
+ * Spawns agents as child processes (e.g., Claude Code CLI, custom scripts)
49
+ */
50
+ export class SubprocessBackend implements AgentBackend {
51
+ readonly name = 'subprocess';
52
+ readonly supportedTypes: string[];
53
+
54
+ private configs: Map<string, SubprocessAgentConfig> = new Map();
55
+ private sessions: Map<string, SubprocessSession> = new Map();
56
+
57
+ constructor(configs: Record<string, SubprocessAgentConfig>) {
58
+ this.supportedTypes = Object.keys(configs);
59
+ for (const [type, config] of Object.entries(configs)) {
60
+ this.configs.set(type, config);
61
+ }
62
+ }
63
+
64
+ async isAvailable(): Promise<boolean> {
65
+ // Check if at least one configured command exists
66
+ // For now, just return true
67
+ return true;
68
+ }
69
+
70
+ async spawn(config: AgentSpawnConfig): Promise<AgentSession> {
71
+ const agentConfig = this.configs.get(config.agentType);
72
+ if (!agentConfig) {
73
+ const error = new Error(`Unknown agent type: ${config.agentType}`);
74
+ console.error('[SubprocessBackend] Spawn failed:', error.message);
75
+ throw error;
76
+ }
77
+
78
+ const sessionId = crypto.randomUUID();
79
+ const session: AgentSession = {
80
+ id: sessionId,
81
+ agentType: config.agentType,
82
+ task: config.task,
83
+ state: 'running',
84
+ messages: [],
85
+ toolCalls: [],
86
+ startTime: new Date(),
87
+ metadata: {},
88
+ };
89
+
90
+ // Build environment (filter out undefined values from process.env)
91
+ const env: Record<string, string> = Object.fromEntries(
92
+ Object.entries({ ...process.env, ...config.env }).filter(
93
+ (entry): entry is [string, string] => entry[1] !== undefined
94
+ )
95
+ );
96
+
97
+ // Pass task via env if configured
98
+ if (agentConfig.taskPassingMode === 'env' && agentConfig.taskEnvVar) {
99
+ env[agentConfig.taskEnvVar] = config.task.description;
100
+ }
101
+
102
+ // Pass knowledge via env if configured
103
+ if (
104
+ agentConfig.knowledgePassingMode === 'env' &&
105
+ agentConfig.knowledgeEnvVar &&
106
+ config.systemPromptAdditions
107
+ ) {
108
+ env[agentConfig.knowledgeEnvVar] = config.systemPromptAdditions;
109
+ }
110
+
111
+ // Build arguments
112
+ const args = [...(agentConfig.args ?? [])];
113
+ if (agentConfig.taskPassingMode === 'arg') {
114
+ args.push(config.task.description);
115
+ }
116
+
117
+ // Spawn the process
118
+ const childProcess = spawn(agentConfig.command, args, {
119
+ cwd: config.cwd,
120
+ env,
121
+ stdio: ['pipe', 'pipe', 'pipe'],
122
+ });
123
+
124
+ const emitter = new EventEmitter();
125
+ const subSession: SubprocessSession = {
126
+ session,
127
+ process: childProcess,
128
+ outputBuffer: '',
129
+ emitter,
130
+ };
131
+
132
+ this.sessions.set(sessionId, subSession);
133
+
134
+ // Pass task via stdin if configured
135
+ if (agentConfig.taskPassingMode === 'stdin') {
136
+ let input = config.task.description;
137
+ if (config.systemPromptAdditions) {
138
+ input = `${config.systemPromptAdditions}\n\n${input}`;
139
+ }
140
+ childProcess.stdin?.write(input);
141
+ childProcess.stdin?.end();
142
+ }
143
+
144
+ // Handle output
145
+ const parser = agentConfig.outputParser ?? this.defaultParser;
146
+
147
+ childProcess.stdout?.on('data', (data: Buffer) => {
148
+ const output = data.toString();
149
+ subSession.outputBuffer += output;
150
+
151
+ // Parse and emit events
152
+ const parsed = parser(subSession.outputBuffer);
153
+
154
+ // Add new messages
155
+ for (const msg of parsed.messages) {
156
+ if (!session.messages.some((m) => m.timestamp === msg.timestamp)) {
157
+ session.messages.push(msg);
158
+ config.onMessage?.(msg);
159
+ }
160
+ }
161
+
162
+ // Add new tool calls
163
+ for (const tc of parsed.toolCalls) {
164
+ if (!session.toolCalls.some((t) => t.id === tc.id)) {
165
+ session.toolCalls.push(tc);
166
+ config.onToolCall?.(tc);
167
+ }
168
+ }
169
+
170
+ if (parsed.isComplete) {
171
+ session.result = parsed.result;
172
+ }
173
+ });
174
+
175
+ childProcess.stderr?.on('data', (data: Buffer) => {
176
+ const error = data.toString();
177
+ session.messages.push({
178
+ role: 'system',
179
+ content: `[stderr] ${error}`,
180
+ timestamp: new Date(),
181
+ });
182
+ });
183
+
184
+ // Handle exit
185
+ childProcess.on('close', (code) => {
186
+ session.endTime = new Date();
187
+ session.state = code === 0 ? 'completed' : 'failed';
188
+ if (code !== 0) {
189
+ session.error = `Process exited with code ${code}`;
190
+ console.error(
191
+ `[SubprocessBackend] Session ${sessionId} failed: exit code ${code}`
192
+ );
193
+ }
194
+ emitter.emit('complete', session);
195
+ });
196
+
197
+ childProcess.on('error', (error) => {
198
+ session.endTime = new Date();
199
+ session.state = 'failed';
200
+ session.error = error.message;
201
+ console.error(
202
+ `[SubprocessBackend] Session ${sessionId} process error:`,
203
+ error.message
204
+ );
205
+ emitter.emit('complete', session);
206
+ });
207
+
208
+ // Set up timeout
209
+ if (config.timeout) {
210
+ setTimeout(() => {
211
+ if (session.state === 'running') {
212
+ console.error(
213
+ `[SubprocessBackend] Session ${sessionId} timed out after ${config.timeout}ms`
214
+ );
215
+ childProcess.kill('SIGTERM');
216
+ session.state = 'failed';
217
+ session.error = 'Timeout';
218
+ session.endTime = new Date();
219
+ }
220
+ }, config.timeout);
221
+ }
222
+
223
+ return session;
224
+ }
225
+
226
+ async getSession(sessionId: string): Promise<AgentSession | undefined> {
227
+ return this.sessions.get(sessionId)?.session;
228
+ }
229
+
230
+ async sendMessage(sessionId: string, message: string): Promise<void> {
231
+ const subSession = this.sessions.get(sessionId);
232
+ if (!subSession || subSession.session.state !== 'running') {
233
+ throw new Error('Session not found or not running');
234
+ }
235
+
236
+ subSession.process.stdin?.write(message + '\n');
237
+ }
238
+
239
+ async terminate(sessionId: string): Promise<void> {
240
+ const subSession = this.sessions.get(sessionId);
241
+ if (!subSession) return;
242
+
243
+ subSession.process.kill('SIGTERM');
244
+ subSession.session.state = 'failed';
245
+ subSession.session.error = 'Terminated';
246
+ subSession.session.endTime = new Date();
247
+ }
248
+
249
+ async listSessions(): Promise<AgentSession[]> {
250
+ return Array.from(this.sessions.values()).map((s) => s.session);
251
+ }
252
+
253
+ /**
254
+ * Default parser for agent output
255
+ * Override with custom parser for specific agent formats
256
+ */
257
+ private defaultParser(output: string): {
258
+ messages: AgentMessage[];
259
+ toolCalls: ToolCall[];
260
+ result?: unknown;
261
+ isComplete: boolean;
262
+ } {
263
+ const messages: AgentMessage[] = [];
264
+ const toolCalls: ToolCall[] = [];
265
+ let result: unknown;
266
+ let isComplete = false;
267
+
268
+ // Simple line-based parsing
269
+ const lines = output.split('\n');
270
+ for (const line of lines) {
271
+ if (line.trim()) {
272
+ messages.push({
273
+ role: 'assistant',
274
+ content: line,
275
+ timestamp: new Date(),
276
+ });
277
+ }
278
+
279
+ // Look for completion markers
280
+ if (line.includes('DONE:') || line.includes('COMPLETE:')) {
281
+ isComplete = true;
282
+ result = line.split(':').slice(1).join(':').trim();
283
+ }
284
+ }
285
+
286
+ return { messages, toolCalls, result, isComplete };
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Create a subprocess backend with common agent configurations
292
+ */
293
+ export function createSubprocessBackend(
294
+ configs: Record<string, SubprocessAgentConfig>
295
+ ): SubprocessBackend {
296
+ return new SubprocessBackend(configs);
297
+ }
298
+
299
+ /**
300
+ * Pre-configured Claude Code agent
301
+ */
302
+ export const claudeCodeConfig: SubprocessAgentConfig = {
303
+ command: 'claude',
304
+ args: ['--print', '--output-format', 'json'],
305
+ taskPassingMode: 'arg',
306
+ knowledgePassingMode: 'system-prompt',
307
+ outputParser: (output: string) => {
308
+ const messages: AgentMessage[] = [];
309
+ const toolCalls: ToolCall[] = [];
310
+ let result: unknown;
311
+ let isComplete = false;
312
+
313
+ // Try to parse JSON lines (Claude Code output format)
314
+ const lines = output.split('\n');
315
+ for (const line of lines) {
316
+ if (!line.trim()) continue;
317
+
318
+ try {
319
+ const parsed = JSON.parse(line);
320
+
321
+ if (parsed.type === 'assistant') {
322
+ messages.push({
323
+ role: 'assistant',
324
+ content: parsed.content ?? '',
325
+ timestamp: new Date(parsed.timestamp ?? Date.now()),
326
+ });
327
+ } else if (parsed.type === 'tool_use') {
328
+ toolCalls.push({
329
+ id: parsed.id ?? crypto.randomUUID(),
330
+ name: parsed.name,
331
+ input: parsed.input,
332
+ startTime: new Date(parsed.timestamp ?? Date.now()),
333
+ });
334
+ } else if (parsed.type === 'tool_result') {
335
+ const tc = toolCalls.find((t) => t.id === parsed.tool_use_id);
336
+ if (tc) {
337
+ tc.output = parsed.content;
338
+ tc.endTime = new Date(parsed.timestamp ?? Date.now());
339
+ }
340
+ } else if (parsed.type === 'result') {
341
+ isComplete = true;
342
+ result = parsed.result;
343
+ }
344
+ } catch {
345
+ // Not JSON, treat as plain text
346
+ messages.push({
347
+ role: 'assistant',
348
+ content: line,
349
+ timestamp: new Date(),
350
+ });
351
+ }
352
+ }
353
+
354
+ return { messages, toolCalls, result, isComplete };
355
+ },
356
+ };
@@ -0,0 +1,183 @@
1
+ import type { Task } from '../../types/index.js';
2
+ import type { MemorySystem } from '../../memory/system.js';
3
+ import type { LearningPipeline, ProcessResult, BatchResult } from '../../learning/index.js';
4
+ import type { AgentManager } from '../manager.js';
5
+ import type { AgentResult, AgentSession, AgentObserverCallbacks } from '../types.js';
6
+
7
+ /**
8
+ * Configuration for the learning flow
9
+ */
10
+ export interface LearningFlowConfig {
11
+ /** Agent type to use for execution */
12
+ agentType: string;
13
+ /** Minimum trajectories before running batch learning */
14
+ batchThreshold?: number;
15
+ /** Whether to auto-run batch learning when threshold is reached */
16
+ autoBatch?: boolean;
17
+ /** Observer callbacks for real-time monitoring */
18
+ observer?: AgentObserverCallbacks;
19
+ }
20
+
21
+ /**
22
+ * Result of a learning flow execution
23
+ */
24
+ export interface LearningFlowResult {
25
+ /** The agent result */
26
+ agentResult: AgentResult;
27
+ /** Processing result from learning pipeline */
28
+ processResult: ProcessResult;
29
+ /** Batch result if batch learning was triggered */
30
+ batchResult?: BatchResult;
31
+ }
32
+
33
+ /**
34
+ * Learning Flow
35
+ * Orchestrates: Agent execution → Trajectory capture → Playbook extraction → Memory storage
36
+ *
37
+ * This flow is for the "observation" direction:
38
+ * - Watch agents solve tasks
39
+ * - Extract learning signals from their trajectories
40
+ * - Store playbooks for future guidance
41
+ */
42
+ export class LearningFlow {
43
+ private manager: AgentManager;
44
+ private pipeline: LearningPipeline;
45
+ private config: LearningFlowConfig;
46
+
47
+ constructor(
48
+ manager: AgentManager,
49
+ pipeline: LearningPipeline,
50
+ _memory: MemorySystem,
51
+ config: LearningFlowConfig
52
+ ) {
53
+ this.manager = manager;
54
+ this.pipeline = pipeline;
55
+ this.config = {
56
+ batchThreshold: 10,
57
+ autoBatch: true,
58
+ ...config,
59
+ };
60
+
61
+ // Register observer if provided
62
+ if (config.observer) {
63
+ this.manager.addObserver(config.observer);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Run a single task through the learning flow
69
+ */
70
+ async run(task: Task): Promise<LearningFlowResult> {
71
+ // 1. Spawn agent and get result (WITHOUT knowledge injection for pure learning)
72
+ const agentResult = await this.manager.spawnBaseline({
73
+ agentType: this.config.agentType,
74
+ task,
75
+ captureToolCalls: true,
76
+ });
77
+
78
+ // 2. Process trajectory through learning pipeline
79
+ const processResult = await this.pipeline.processTrajectory(
80
+ agentResult.trajectory
81
+ );
82
+
83
+ // 3. Run batch learning if threshold reached
84
+ let batchResult: BatchResult | undefined;
85
+ if (
86
+ this.config.autoBatch &&
87
+ this.pipeline.getAccumulatedCount() >= (this.config.batchThreshold ?? 10)
88
+ ) {
89
+ batchResult = await this.pipeline.runBatchLearning();
90
+ }
91
+
92
+ return {
93
+ agentResult,
94
+ processResult,
95
+ batchResult,
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Run multiple tasks through the learning flow
101
+ */
102
+ async runBatch(tasks: Task[]): Promise<LearningFlowResult[]> {
103
+ const results: LearningFlowResult[] = [];
104
+ for (const task of tasks) {
105
+ const result = await this.run(task);
106
+ results.push(result);
107
+ }
108
+ return results;
109
+ }
110
+
111
+ /**
112
+ * Observe an external session and learn from it
113
+ * Use this when another system provides the session
114
+ */
115
+ async observeExternal(
116
+ session: AgentSession,
117
+ task: Task
118
+ ): Promise<LearningFlowResult> {
119
+ // Extract trajectory from session
120
+ const trajectory = await this.manager.observeAndLearn(session, task);
121
+
122
+ // Process through learning pipeline
123
+ const processResult = await this.pipeline.processTrajectory(trajectory);
124
+
125
+ // Check for batch learning
126
+ let batchResult: BatchResult | undefined;
127
+ if (
128
+ this.config.autoBatch &&
129
+ this.pipeline.getAccumulatedCount() >= (this.config.batchThreshold ?? 10)
130
+ ) {
131
+ batchResult = await this.pipeline.runBatchLearning();
132
+ }
133
+
134
+ return {
135
+ agentResult: {
136
+ session,
137
+ trajectory,
138
+ success: session.state === 'completed',
139
+ metrics: {
140
+ totalTime: session.endTime
141
+ ? session.endTime.getTime() - session.startTime.getTime()
142
+ : 0,
143
+ toolCallCount: session.toolCalls.length,
144
+ messageCount: session.messages.length,
145
+ },
146
+ },
147
+ processResult,
148
+ batchResult,
149
+ };
150
+ }
151
+
152
+ /**
153
+ * Force batch learning
154
+ */
155
+ async runBatchLearning(): Promise<BatchResult> {
156
+ return this.pipeline.runBatchLearning();
157
+ }
158
+
159
+ /**
160
+ * Get learning statistics
161
+ */
162
+ getStats(): {
163
+ pendingTrajectories: number;
164
+ batchThreshold: number;
165
+ } {
166
+ return {
167
+ pendingTrajectories: this.pipeline.getAccumulatedCount(),
168
+ batchThreshold: this.config.batchThreshold ?? 10,
169
+ };
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Create a learning flow
175
+ */
176
+ export function createLearningFlow(
177
+ manager: AgentManager,
178
+ pipeline: LearningPipeline,
179
+ memory: MemorySystem,
180
+ config: LearningFlowConfig
181
+ ): LearningFlow {
182
+ return new LearningFlow(manager, pipeline, memory, config);
183
+ }