@agentforge/patterns 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/dist/index.cjs ADDED
@@ -0,0 +1,2564 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AgentMessageSchema: () => AgentMessageSchema,
24
+ AgentRoleSchema: () => AgentRoleSchema,
25
+ CompletedStepSchema: () => CompletedStepSchema,
26
+ DEFAULT_AGGREGATOR_SYSTEM_PROMPT: () => DEFAULT_AGGREGATOR_SYSTEM_PROMPT,
27
+ DEFAULT_GENERATOR_SYSTEM_PROMPT: () => DEFAULT_GENERATOR_SYSTEM_PROMPT,
28
+ DEFAULT_PLANNER_SYSTEM_PROMPT: () => DEFAULT_PLANNER_SYSTEM_PROMPT,
29
+ DEFAULT_REACT_SYSTEM_PROMPT: () => DEFAULT_REACT_SYSTEM_PROMPT,
30
+ DEFAULT_REFLECTOR_SYSTEM_PROMPT: () => DEFAULT_REFLECTOR_SYSTEM_PROMPT,
31
+ DEFAULT_REPLANNER_SYSTEM_PROMPT: () => DEFAULT_REPLANNER_SYSTEM_PROMPT,
32
+ DEFAULT_REVISER_SYSTEM_PROMPT: () => DEFAULT_REVISER_SYSTEM_PROMPT,
33
+ DEFAULT_SUPERVISOR_SYSTEM_PROMPT: () => DEFAULT_SUPERVISOR_SYSTEM_PROMPT,
34
+ ExecutionStatusSchema: () => ExecutionStatusSchema,
35
+ GENERATION_PROMPT_TEMPLATE: () => GENERATION_PROMPT_TEMPLATE,
36
+ HandoffRequestSchema: () => HandoffRequestSchema,
37
+ MessageSchema: () => MessageSchema,
38
+ MessageTypeSchema: () => MessageTypeSchema,
39
+ MultiAgentState: () => MultiAgentState,
40
+ MultiAgentStateConfig: () => MultiAgentStateConfig,
41
+ MultiAgentStatusSchema: () => MultiAgentStatusSchema,
42
+ MultiAgentSystemBuilder: () => MultiAgentSystemBuilder,
43
+ PLANNING_PROMPT_TEMPLATE: () => PLANNING_PROMPT_TEMPLATE,
44
+ PlanExecuteState: () => PlanExecuteState,
45
+ PlanExecuteStateConfig: () => PlanExecuteStateConfig,
46
+ PlanSchema: () => PlanSchema,
47
+ PlanStepSchema: () => PlanStepSchema,
48
+ QUALITY_CRITERIA_TEMPLATE: () => QUALITY_CRITERIA_TEMPLATE,
49
+ QualityCriteriaSchema: () => QualityCriteriaSchema,
50
+ REFLECTION_ENTRY_TEMPLATE: () => REFLECTION_ENTRY_TEMPLATE,
51
+ REFLECTION_HISTORY_TEMPLATE: () => REFLECTION_HISTORY_TEMPLATE,
52
+ REFLECTION_PROMPT_TEMPLATE: () => REFLECTION_PROMPT_TEMPLATE,
53
+ REPLANNING_PROMPT_TEMPLATE: () => REPLANNING_PROMPT_TEMPLATE,
54
+ REVISION_ENTRY_TEMPLATE: () => REVISION_ENTRY_TEMPLATE,
55
+ REVISION_PROMPT_TEMPLATE: () => REVISION_PROMPT_TEMPLATE,
56
+ ReActAgentBuilder: () => ReActAgentBuilder,
57
+ ReActState: () => ReActState,
58
+ ReflectionConfigSchema: () => ReflectionConfigSchema,
59
+ ReflectionSchema: () => ReflectionSchema,
60
+ ReflectionState: () => ReflectionState,
61
+ ReflectionStateConfig: () => ReflectionStateConfig,
62
+ ReflectionStatusSchema: () => ReflectionStatusSchema,
63
+ ReplanDecisionSchema: () => ReplanDecisionSchema,
64
+ RevisionSchema: () => RevisionSchema,
65
+ RoutingDecisionSchema: () => RoutingDecisionSchema,
66
+ RoutingStrategySchema: () => RoutingStrategySchema,
67
+ ScratchpadEntrySchema: () => ScratchpadEntrySchema,
68
+ TaskAssignmentSchema: () => TaskAssignmentSchema,
69
+ TaskResultSchema: () => TaskResultSchema,
70
+ ThoughtSchema: () => ThoughtSchema,
71
+ ToolCallSchema: () => ToolCallSchema,
72
+ ToolResultSchema: () => ToolResultSchema,
73
+ WorkerCapabilitiesSchema: () => WorkerCapabilitiesSchema,
74
+ createAggregatorNode: () => createAggregatorNode,
75
+ createExecutorNode: () => createExecutorNode,
76
+ createFinisherNode: () => createFinisherNode,
77
+ createGeneratorNode: () => createGeneratorNode,
78
+ createMultiAgentSystem: () => createMultiAgentSystem,
79
+ createPlanExecuteAgent: () => createPlanExecuteAgent,
80
+ createPlannerNode: () => createPlannerNode,
81
+ createReActAgent: () => createReActAgent,
82
+ createReActAgentBuilder: () => createReActAgentBuilder,
83
+ createReflectionAgent: () => createReflectionAgent,
84
+ createReflectionFinisherNode: () => createFinisherNode2,
85
+ createReflectorNode: () => createReflectorNode,
86
+ createReplannerNode: () => createReplannerNode,
87
+ createReviserNode: () => createReviserNode,
88
+ createSupervisorNode: () => createSupervisorNode,
89
+ createWorkerNode: () => createWorkerNode,
90
+ getRoutingStrategy: () => getRoutingStrategy,
91
+ llmBasedRouting: () => llmBasedRouting,
92
+ loadBalancedRouting: () => loadBalancedRouting,
93
+ registerWorkers: () => registerWorkers,
94
+ roundRobinRouting: () => roundRobinRouting,
95
+ ruleBasedRouting: () => ruleBasedRouting,
96
+ skillBasedRouting: () => skillBasedRouting
97
+ });
98
+ module.exports = __toCommonJS(index_exports);
99
+
100
+ // src/react/schemas.ts
101
+ var import_zod = require("zod");
102
+ var MessageRoleSchema = import_zod.z.enum(["system", "user", "assistant", "tool"]);
103
+ var MessageSchema = import_zod.z.object({
104
+ role: MessageRoleSchema,
105
+ content: import_zod.z.string(),
106
+ name: import_zod.z.string().optional(),
107
+ metadata: import_zod.z.record(import_zod.z.any()).optional()
108
+ });
109
+ var ThoughtSchema = import_zod.z.object({
110
+ content: import_zod.z.string(),
111
+ timestamp: import_zod.z.number().optional(),
112
+ metadata: import_zod.z.record(import_zod.z.any()).optional()
113
+ });
114
+ var ToolCallSchema = import_zod.z.object({
115
+ id: import_zod.z.string(),
116
+ name: import_zod.z.string(),
117
+ arguments: import_zod.z.record(import_zod.z.any()),
118
+ timestamp: import_zod.z.number().optional()
119
+ });
120
+ var ToolResultSchema = import_zod.z.object({
121
+ toolCallId: import_zod.z.string(),
122
+ result: import_zod.z.any(),
123
+ error: import_zod.z.string().optional(),
124
+ timestamp: import_zod.z.number().optional()
125
+ });
126
+ var ScratchpadEntrySchema = import_zod.z.object({
127
+ step: import_zod.z.number(),
128
+ thought: import_zod.z.string().optional(),
129
+ action: import_zod.z.string().optional(),
130
+ observation: import_zod.z.string().optional(),
131
+ timestamp: import_zod.z.number().optional()
132
+ });
133
+
134
+ // src/react/state.ts
135
+ var import_zod2 = require("zod");
136
+ var import_core = require("@agentforge/core");
137
+ var ReActStateConfig = {
138
+ /**
139
+ * Conversation messages
140
+ * Accumulates all messages in the conversation
141
+ */
142
+ messages: {
143
+ schema: import_zod2.z.array(MessageSchema),
144
+ reducer: (left, right) => [...left, ...right],
145
+ default: () => [],
146
+ description: "Conversation message history"
147
+ },
148
+ /**
149
+ * Reasoning thoughts
150
+ * Accumulates all reasoning steps the agent takes
151
+ */
152
+ thoughts: {
153
+ schema: import_zod2.z.array(ThoughtSchema),
154
+ reducer: (left, right) => [...left, ...right],
155
+ default: () => [],
156
+ description: "Agent reasoning steps"
157
+ },
158
+ /**
159
+ * Tool calls (actions)
160
+ * Accumulates all tool calls made by the agent
161
+ */
162
+ actions: {
163
+ schema: import_zod2.z.array(ToolCallSchema),
164
+ reducer: (left, right) => [...left, ...right],
165
+ default: () => [],
166
+ description: "Tool calls made by the agent"
167
+ },
168
+ /**
169
+ * Tool results (observations)
170
+ * Accumulates all observations from tool executions
171
+ */
172
+ observations: {
173
+ schema: import_zod2.z.array(ToolResultSchema),
174
+ reducer: (left, right) => [...left, ...right],
175
+ default: () => [],
176
+ description: "Results from tool executions"
177
+ },
178
+ /**
179
+ * Scratchpad for intermediate reasoning
180
+ * Accumulates step-by-step reasoning process
181
+ */
182
+ scratchpad: {
183
+ schema: import_zod2.z.array(ScratchpadEntrySchema),
184
+ reducer: (left, right) => [...left, ...right],
185
+ default: () => [],
186
+ description: "Intermediate reasoning scratchpad"
187
+ },
188
+ /**
189
+ * Current iteration count
190
+ * Tracks how many thought-action-observation loops have been executed
191
+ */
192
+ iteration: {
193
+ schema: import_zod2.z.number(),
194
+ reducer: (left, right) => left + right,
195
+ default: () => 0,
196
+ description: "Current iteration count"
197
+ },
198
+ /**
199
+ * Whether the agent should continue iterating
200
+ */
201
+ shouldContinue: {
202
+ schema: import_zod2.z.boolean().optional(),
203
+ default: () => true,
204
+ description: "Whether to continue the ReAct loop"
205
+ },
206
+ /**
207
+ * Final response (if any)
208
+ */
209
+ response: {
210
+ schema: import_zod2.z.string().optional(),
211
+ description: "Final response from the agent"
212
+ }
213
+ };
214
+ var ReActState = (0, import_core.createStateAnnotation)(ReActStateConfig);
215
+
216
+ // src/react/prompts.ts
217
+ var DEFAULT_REACT_SYSTEM_PROMPT = `You are a helpful assistant that uses tools to solve problems.
218
+
219
+ You follow the ReAct (Reasoning and Action) pattern:
220
+ 1. THINK: Reason about what to do next
221
+ 2. ACT: Use a tool or provide a final answer
222
+ 3. OBSERVE: Examine the tool's result
223
+ 4. REPEAT: Continue until you can answer the user's question
224
+
225
+ When you need to use a tool:
226
+ - Think carefully about which tool to use
227
+ - Provide the correct arguments
228
+ - Wait for the observation before proceeding
229
+
230
+ When you have enough information:
231
+ - Provide a clear, complete answer
232
+ - Cite the tools you used if relevant`;
233
+ function formatScratchpad(scratchpad) {
234
+ if (scratchpad.length === 0) {
235
+ return "No previous steps.";
236
+ }
237
+ return scratchpad.map((entry) => {
238
+ const parts = [`Step ${entry.step}:`];
239
+ if (entry.thought) parts.push(` Thought: ${entry.thought}`);
240
+ if (entry.action) parts.push(` Action: ${entry.action}`);
241
+ if (entry.observation) parts.push(` Observation: ${entry.observation}`);
242
+ return parts.join("\n");
243
+ }).join("\n\n");
244
+ }
245
+
246
+ // src/react/nodes.ts
247
+ var import_messages = require("@langchain/core/messages");
248
+ var import_core2 = require("@agentforge/core");
249
+ function createReasoningNode(llm, tools, systemPrompt, maxIterations, verbose = false) {
250
+ const langchainTools = (0, import_core2.toLangChainTools)(tools);
251
+ const llmWithTools = llm.bindTools ? llm.bindTools(langchainTools) : llm;
252
+ return async (state) => {
253
+ if (verbose) {
254
+ console.log(`[reasoning] Iteration ${state.iteration + 1}/${maxIterations}`);
255
+ }
256
+ const stateMessages = state.messages || [];
257
+ const messages = [
258
+ new import_messages.SystemMessage(systemPrompt),
259
+ ...stateMessages.map((msg) => {
260
+ if (msg.role === "user") return new import_messages.HumanMessage(msg.content);
261
+ if (msg.role === "assistant") return new import_messages.AIMessage(msg.content);
262
+ if (msg.role === "system") return new import_messages.SystemMessage(msg.content);
263
+ return new import_messages.HumanMessage(msg.content);
264
+ })
265
+ ];
266
+ const scratchpad = state.scratchpad || [];
267
+ if (scratchpad.length > 0) {
268
+ const scratchpadText = formatScratchpad(scratchpad);
269
+ messages.push(new import_messages.SystemMessage(`Previous steps:
270
+ ${scratchpadText}`));
271
+ }
272
+ const response = await llmWithTools.invoke(messages);
273
+ const thought = typeof response.content === "string" ? response.content : "";
274
+ const toolCalls = [];
275
+ if (response.tool_calls && response.tool_calls.length > 0) {
276
+ for (const toolCall of response.tool_calls) {
277
+ toolCalls.push({
278
+ id: toolCall.id || `call_${Date.now()}_${Math.random()}`,
279
+ name: toolCall.name,
280
+ arguments: toolCall.args || {},
281
+ timestamp: Date.now()
282
+ });
283
+ }
284
+ }
285
+ const currentIteration = state.iteration || 0;
286
+ const shouldContinue = toolCalls.length > 0 && currentIteration + 1 < maxIterations;
287
+ return {
288
+ messages: [{ role: "assistant", content: thought }],
289
+ thoughts: thought ? [{ content: thought, timestamp: Date.now() }] : [],
290
+ actions: toolCalls,
291
+ iteration: 1,
292
+ // Increment iteration
293
+ shouldContinue,
294
+ response: toolCalls.length === 0 ? thought : void 0
295
+ // Final response if no tool calls
296
+ };
297
+ };
298
+ }
299
+ function createActionNode(tools, verbose = false) {
300
+ const toolMap = new Map(tools.map((tool) => [tool.metadata.name, tool]));
301
+ return async (state) => {
302
+ const actions = state.actions || [];
303
+ if (verbose) {
304
+ console.log(`[action] Executing ${actions.length} tool calls`);
305
+ }
306
+ const recentActions = actions.slice(-10);
307
+ const observations = [];
308
+ for (const action of recentActions) {
309
+ const tool = toolMap.get(action.name);
310
+ if (!tool) {
311
+ observations.push({
312
+ toolCallId: action.id,
313
+ result: null,
314
+ error: `Tool '${action.name}' not found`,
315
+ timestamp: Date.now()
316
+ });
317
+ continue;
318
+ }
319
+ try {
320
+ const result = await tool.execute(action.arguments);
321
+ observations.push({
322
+ toolCallId: action.id,
323
+ result,
324
+ timestamp: Date.now()
325
+ });
326
+ if (verbose) {
327
+ console.log(`[action] Tool '${action.name}' executed successfully`);
328
+ }
329
+ } catch (error) {
330
+ const errorMessage = error instanceof Error ? error.message : String(error);
331
+ observations.push({
332
+ toolCallId: action.id,
333
+ result: null,
334
+ error: errorMessage,
335
+ timestamp: Date.now()
336
+ });
337
+ if (verbose) {
338
+ console.error(`[action] Tool '${action.name}' failed:`, errorMessage);
339
+ }
340
+ }
341
+ }
342
+ return {
343
+ observations
344
+ };
345
+ };
346
+ }
347
+ function createObservationNode(verbose = false) {
348
+ return async (state) => {
349
+ const observations = state.observations || [];
350
+ const thoughts = state.thoughts || [];
351
+ const actions = state.actions || [];
352
+ if (verbose) {
353
+ console.log(`[observation] Processing ${observations.length} observations`);
354
+ }
355
+ const recentObservations = observations.slice(-10);
356
+ const currentStep = state.iteration;
357
+ const latestThought = thoughts[thoughts.length - 1]?.content || "";
358
+ const latestActions = actions.slice(-10);
359
+ const latestObservations = recentObservations;
360
+ const scratchpadEntry = {
361
+ step: currentStep,
362
+ thought: latestThought,
363
+ action: latestActions.map((a) => `${a.name}(${JSON.stringify(a.arguments)})`).join(", "),
364
+ observation: latestObservations.map((obs) => {
365
+ if (obs.error) {
366
+ return `Error: ${obs.error}`;
367
+ }
368
+ return typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result);
369
+ }).join("; "),
370
+ timestamp: Date.now()
371
+ };
372
+ const observationMessages = latestObservations.map((obs) => {
373
+ const content = obs.error ? `Error: ${obs.error}` : typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result, null, 2);
374
+ return {
375
+ role: "tool",
376
+ content,
377
+ name: latestActions.find((a) => a.id === obs.toolCallId)?.name
378
+ };
379
+ });
380
+ return {
381
+ scratchpad: [scratchpadEntry],
382
+ messages: observationMessages
383
+ };
384
+ };
385
+ }
386
+
387
+ // src/react/agent.ts
388
+ var import_langgraph = require("@langchain/langgraph");
389
+ var import_core3 = require("@agentforge/core");
390
+ function createReActAgent(config, options) {
391
+ const {
392
+ llm,
393
+ tools,
394
+ systemPrompt = DEFAULT_REACT_SYSTEM_PROMPT,
395
+ maxIterations = 10,
396
+ returnIntermediateSteps = false,
397
+ stopCondition
398
+ } = config;
399
+ const {
400
+ verbose = false,
401
+ nodeNames = {}
402
+ } = options || {};
403
+ const toolArray = tools instanceof import_core3.ToolRegistry ? tools.getAll() : tools;
404
+ const REASONING_NODE = nodeNames.reasoning || "reasoning";
405
+ const ACTION_NODE = nodeNames.action || "action";
406
+ const OBSERVATION_NODE = nodeNames.observation || "observation";
407
+ const reasoningNode = createReasoningNode(
408
+ llm,
409
+ toolArray,
410
+ systemPrompt,
411
+ maxIterations,
412
+ verbose
413
+ );
414
+ const actionNode = createActionNode(toolArray, verbose);
415
+ const observationNode = createObservationNode(verbose);
416
+ const shouldContinue = (state) => {
417
+ if (stopCondition && stopCondition(state)) {
418
+ return import_langgraph.END;
419
+ }
420
+ if (state.iteration >= maxIterations) {
421
+ return import_langgraph.END;
422
+ }
423
+ if (state.response) {
424
+ return import_langgraph.END;
425
+ }
426
+ if (state.shouldContinue === false) {
427
+ return import_langgraph.END;
428
+ }
429
+ return ACTION_NODE;
430
+ };
431
+ const workflow = new import_langgraph.StateGraph(ReActState).addNode(REASONING_NODE, reasoningNode).addNode(ACTION_NODE, actionNode).addNode(OBSERVATION_NODE, observationNode).addEdge("__start__", REASONING_NODE).addConditionalEdges(REASONING_NODE, shouldContinue).addEdge(ACTION_NODE, OBSERVATION_NODE).addEdge(OBSERVATION_NODE, REASONING_NODE);
432
+ return workflow.compile();
433
+ }
434
+
435
+ // src/react/builder.ts
436
+ var ReActAgentBuilder = class {
437
+ config = {};
438
+ options = {};
439
+ /**
440
+ * Set the language model (required)
441
+ *
442
+ * @param llm - LangChain chat model to use for reasoning
443
+ */
444
+ withLLM(llm) {
445
+ this.config.llm = llm;
446
+ return this;
447
+ }
448
+ /**
449
+ * Set the tools (required)
450
+ *
451
+ * @param tools - Tool registry or array of tools
452
+ */
453
+ withTools(tools) {
454
+ this.config.tools = tools;
455
+ return this;
456
+ }
457
+ /**
458
+ * Set the system prompt (optional)
459
+ *
460
+ * @param systemPrompt - System prompt for the agent
461
+ */
462
+ withSystemPrompt(systemPrompt) {
463
+ this.config.systemPrompt = systemPrompt;
464
+ return this;
465
+ }
466
+ /**
467
+ * Set the maximum iterations (optional, default: 10)
468
+ *
469
+ * @param maxIterations - Maximum number of thought-action loops
470
+ */
471
+ withMaxIterations(maxIterations) {
472
+ this.config.maxIterations = maxIterations;
473
+ return this;
474
+ }
475
+ /**
476
+ * Set whether to return intermediate steps (optional, default: false)
477
+ *
478
+ * @param returnIntermediateSteps - Whether to include reasoning steps in output
479
+ */
480
+ withReturnIntermediateSteps(returnIntermediateSteps) {
481
+ this.config.returnIntermediateSteps = returnIntermediateSteps;
482
+ return this;
483
+ }
484
+ /**
485
+ * Set a custom stop condition (optional)
486
+ *
487
+ * @param stopCondition - Function that determines when to stop the agent
488
+ */
489
+ withStopCondition(stopCondition) {
490
+ this.config.stopCondition = stopCondition;
491
+ return this;
492
+ }
493
+ /**
494
+ * Enable verbose logging (optional, default: false)
495
+ *
496
+ * @param verbose - Whether to enable verbose logging
497
+ */
498
+ withVerbose(verbose) {
499
+ this.options.verbose = verbose;
500
+ return this;
501
+ }
502
+ /**
503
+ * Set custom node names (optional)
504
+ *
505
+ * @param nodeNames - Custom names for nodes (for debugging/observability)
506
+ */
507
+ withNodeNames(nodeNames) {
508
+ this.options.nodeNames = nodeNames;
509
+ return this;
510
+ }
511
+ /**
512
+ * Build the ReAct agent
513
+ *
514
+ * @returns A compiled LangGraph StateGraph
515
+ * @throws Error if required configuration is missing
516
+ */
517
+ build() {
518
+ if (!this.config.llm) {
519
+ throw new Error("ReActAgentBuilder: llm is required. Use withLLM() to set it.");
520
+ }
521
+ if (!this.config.tools) {
522
+ throw new Error("ReActAgentBuilder: tools are required. Use withTools() to set them.");
523
+ }
524
+ const finalConfig = {
525
+ llm: this.config.llm,
526
+ tools: this.config.tools,
527
+ systemPrompt: this.config.systemPrompt || DEFAULT_REACT_SYSTEM_PROMPT,
528
+ maxIterations: this.config.maxIterations ?? 10,
529
+ returnIntermediateSteps: this.config.returnIntermediateSteps ?? false,
530
+ stopCondition: this.config.stopCondition
531
+ };
532
+ return createReActAgent(finalConfig, this.options);
533
+ }
534
+ };
535
+ function createReActAgentBuilder() {
536
+ return new ReActAgentBuilder();
537
+ }
538
+
539
+ // src/plan-execute/agent.ts
540
+ var import_langgraph2 = require("@langchain/langgraph");
541
+
542
+ // src/plan-execute/state.ts
543
+ var import_zod4 = require("zod");
544
+ var import_core4 = require("@agentforge/core");
545
+
546
+ // src/plan-execute/schemas.ts
547
+ var import_zod3 = require("zod");
548
+ var PlanStepSchema = import_zod3.z.object({
549
+ /**
550
+ * Unique identifier for the step
551
+ */
552
+ id: import_zod3.z.string().describe("Unique identifier for the step"),
553
+ /**
554
+ * Description of what this step should accomplish
555
+ */
556
+ description: import_zod3.z.string().describe("Description of what this step should accomplish"),
557
+ /**
558
+ * Optional dependencies on other steps (by ID)
559
+ */
560
+ dependencies: import_zod3.z.array(import_zod3.z.string()).optional().describe("IDs of steps that must complete before this one"),
561
+ /**
562
+ * Optional tool to use for this step
563
+ */
564
+ tool: import_zod3.z.string().optional().describe("Name of the tool to use for this step"),
565
+ /**
566
+ * Optional arguments for the tool
567
+ */
568
+ args: import_zod3.z.record(import_zod3.z.any()).optional().describe("Arguments to pass to the tool")
569
+ });
570
+ var CompletedStepSchema = import_zod3.z.object({
571
+ /**
572
+ * The step that was executed
573
+ */
574
+ step: PlanStepSchema.describe("The step that was executed"),
575
+ /**
576
+ * The result of executing the step
577
+ */
578
+ result: import_zod3.z.any().describe("The result of executing the step"),
579
+ /**
580
+ * Whether the step succeeded
581
+ */
582
+ success: import_zod3.z.boolean().describe("Whether the step succeeded"),
583
+ /**
584
+ * Optional error message if the step failed
585
+ */
586
+ error: import_zod3.z.string().optional().describe("Error message if the step failed"),
587
+ /**
588
+ * Timestamp when the step was completed
589
+ */
590
+ timestamp: import_zod3.z.string().datetime().describe("ISO timestamp when the step was completed")
591
+ });
592
+ var PlanSchema = import_zod3.z.object({
593
+ /**
594
+ * List of steps in the plan
595
+ */
596
+ steps: import_zod3.z.array(PlanStepSchema).describe("List of steps in the plan"),
597
+ /**
598
+ * Overall goal of the plan
599
+ */
600
+ goal: import_zod3.z.string().describe("Overall goal of the plan"),
601
+ /**
602
+ * Timestamp when the plan was created
603
+ */
604
+ createdAt: import_zod3.z.string().datetime().describe("ISO timestamp when the plan was created"),
605
+ /**
606
+ * Optional confidence score (0-1)
607
+ */
608
+ confidence: import_zod3.z.number().min(0).max(1).optional().describe("Confidence score for the plan (0-1)")
609
+ });
610
+ var ReplanDecisionSchema = import_zod3.z.object({
611
+ /**
612
+ * Whether to replan
613
+ */
614
+ shouldReplan: import_zod3.z.boolean().describe("Whether to replan based on current results"),
615
+ /**
616
+ * Reason for the decision
617
+ */
618
+ reason: import_zod3.z.string().describe("Reason for the replan decision"),
619
+ /**
620
+ * Optional new goal if replanning
621
+ */
622
+ newGoal: import_zod3.z.string().optional().describe("Updated goal if replanning")
623
+ });
624
+ var ExecutionStatusSchema = import_zod3.z.enum([
625
+ "planning",
626
+ "executing",
627
+ "replanning",
628
+ "completed",
629
+ "failed"
630
+ ]).describe("Current status of the plan execution");
631
+
632
+ // src/plan-execute/state.ts
633
+ var PlanExecuteStateConfig = {
634
+ /**
635
+ * Original user input/query
636
+ */
637
+ input: {
638
+ schema: import_zod4.z.string(),
639
+ default: () => "",
640
+ description: "Original user input or query"
641
+ },
642
+ /**
643
+ * The current plan
644
+ */
645
+ plan: {
646
+ schema: PlanSchema.optional(),
647
+ description: "The current execution plan"
648
+ },
649
+ /**
650
+ * Completed steps with their results
651
+ * Accumulates all completed steps
652
+ */
653
+ pastSteps: {
654
+ schema: import_zod4.z.array(CompletedStepSchema),
655
+ reducer: (left, right) => [...left, ...right],
656
+ default: () => [],
657
+ description: "Completed steps with their results"
658
+ },
659
+ /**
660
+ * Index of the current step being executed
661
+ */
662
+ currentStepIndex: {
663
+ schema: import_zod4.z.number().int().nonnegative().optional(),
664
+ description: "Index of the current step being executed"
665
+ },
666
+ /**
667
+ * Current execution status
668
+ */
669
+ status: {
670
+ schema: ExecutionStatusSchema,
671
+ default: () => "planning",
672
+ description: "Current execution status"
673
+ },
674
+ /**
675
+ * Final response
676
+ */
677
+ response: {
678
+ schema: import_zod4.z.string().optional(),
679
+ description: "Final response after plan execution"
680
+ },
681
+ /**
682
+ * Error message if execution failed
683
+ */
684
+ error: {
685
+ schema: import_zod4.z.string().optional(),
686
+ description: "Error message if execution failed"
687
+ },
688
+ /**
689
+ * Iteration counter for replanning
690
+ */
691
+ iteration: {
692
+ schema: import_zod4.z.number().int().nonnegative(),
693
+ reducer: (left, right) => left + right,
694
+ default: () => 0,
695
+ description: "Number of planning iterations"
696
+ },
697
+ /**
698
+ * Maximum iterations allowed
699
+ */
700
+ maxIterations: {
701
+ schema: import_zod4.z.number().int().positive(),
702
+ default: () => 5,
703
+ description: "Maximum number of planning iterations allowed"
704
+ }
705
+ };
706
+ var PlanExecuteState = (0, import_core4.createStateAnnotation)(PlanExecuteStateConfig);
707
+
708
+ // src/plan-execute/nodes.ts
709
+ var import_messages2 = require("@langchain/core/messages");
710
+
711
+ // src/plan-execute/prompts.ts
712
+ var DEFAULT_PLANNER_SYSTEM_PROMPT = `You are an expert planning assistant. Your job is to create a detailed, step-by-step plan to accomplish the user's goal.
713
+
714
+ Guidelines for creating plans:
715
+ 1. Break down complex tasks into clear, actionable steps
716
+ 2. Each step should have a specific, measurable outcome
717
+ 3. Identify dependencies between steps
718
+ 4. Consider which tools are needed for each step
719
+ 5. Keep the plan focused and efficient
720
+ 6. Aim for 3-7 steps for most tasks
721
+
722
+ Output your plan as a JSON object with the following structure:
723
+ {
724
+ "goal": "The overall goal",
725
+ "steps": [
726
+ {
727
+ "id": "step-1",
728
+ "description": "What this step accomplishes",
729
+ "tool": "tool_name (optional)",
730
+ "args": {"key": "value (optional)"},
731
+ "dependencies": ["step-id (optional)"]
732
+ }
733
+ ],
734
+ "confidence": 0.9
735
+ }`;
736
+ var DEFAULT_REPLANNER_SYSTEM_PROMPT = `You are an expert replanning assistant. Your job is to decide whether the current plan needs to be adjusted based on the results so far.
737
+
738
+ Consider:
739
+ 1. Have the completed steps achieved their intended outcomes?
740
+ 2. Are there any unexpected results that require plan changes?
741
+ 3. Is the original goal still achievable with the current plan?
742
+ 4. Would a different approach be more effective?
743
+
744
+ Output your decision as a JSON object:
745
+ {
746
+ "shouldReplan": true/false,
747
+ "reason": "Explanation for the decision",
748
+ "newGoal": "Updated goal if replanning (optional)"
749
+ }`;
750
+ var PLANNING_PROMPT_TEMPLATE = `User Goal: {input}
751
+
752
+ {toolDescriptions}
753
+
754
+ Create a step-by-step plan to accomplish this goal.`;
755
+ var REPLANNING_PROMPT_TEMPLATE = `Original Goal: {goal}
756
+
757
+ Completed Steps:
758
+ {completedSteps}
759
+
760
+ Current Plan:
761
+ {remainingSteps}
762
+
763
+ Based on the results so far, should we continue with the current plan or replan?`;
764
+ var COMPLETED_STEP_TEMPLATE = `Step {stepNumber}: {description}
765
+ Result: {result}
766
+ Status: {status}`;
767
+ var REMAINING_STEP_TEMPLATE = `Step {stepNumber}: {description}
768
+ {dependencies}`;
769
+
770
+ // src/plan-execute/nodes.ts
771
+ function createPlannerNode(config) {
772
+ const {
773
+ llm,
774
+ systemPrompt = DEFAULT_PLANNER_SYSTEM_PROMPT,
775
+ maxSteps = 7,
776
+ includeToolDescriptions = false
777
+ } = config;
778
+ return async (state) => {
779
+ try {
780
+ let toolDescriptions = "";
781
+ if (includeToolDescriptions) {
782
+ toolDescriptions = "";
783
+ }
784
+ const userPrompt = PLANNING_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{toolDescriptions}", toolDescriptions);
785
+ const messages = [
786
+ new import_messages2.SystemMessage(systemPrompt),
787
+ new import_messages2.HumanMessage(userPrompt)
788
+ ];
789
+ const response = await llm.invoke(messages);
790
+ const content = response.content.toString();
791
+ let plan;
792
+ try {
793
+ const parsed = JSON.parse(content);
794
+ plan = {
795
+ steps: parsed.steps.slice(0, maxSteps),
796
+ // Limit to maxSteps
797
+ goal: parsed.goal || state.input || "",
798
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
799
+ confidence: parsed.confidence
800
+ };
801
+ } catch (parseError) {
802
+ throw new Error(`Failed to parse plan from LLM response: ${parseError}`);
803
+ }
804
+ return {
805
+ plan,
806
+ status: "executing",
807
+ currentStepIndex: 0,
808
+ iteration: 1
809
+ };
810
+ } catch (error) {
811
+ return {
812
+ status: "failed",
813
+ error: error instanceof Error ? error.message : "Unknown error in planner"
814
+ };
815
+ }
816
+ };
817
+ }
818
+ function createExecutorNode(config) {
819
+ const {
820
+ tools,
821
+ llm,
822
+ parallel = false,
823
+ stepTimeout = 3e4
824
+ } = config;
825
+ return async (state) => {
826
+ try {
827
+ const { plan, currentStepIndex = 0, pastSteps = [] } = state;
828
+ if (!plan || !plan.steps || plan.steps.length === 0) {
829
+ return {
830
+ status: "completed"
831
+ };
832
+ }
833
+ if (currentStepIndex >= plan.steps.length) {
834
+ return {
835
+ status: "completed"
836
+ };
837
+ }
838
+ const currentStep = plan.steps[currentStepIndex];
839
+ if (currentStep.dependencies && currentStep.dependencies.length > 0) {
840
+ const completedStepIds = new Set(pastSteps.map((ps) => ps.step.id));
841
+ const unmetDependencies = currentStep.dependencies.filter((dep) => !completedStepIds.has(dep));
842
+ if (unmetDependencies.length > 0) {
843
+ throw new Error(`Unmet dependencies for step ${currentStep.id}: ${unmetDependencies.join(", ")}`);
844
+ }
845
+ }
846
+ let result;
847
+ let success = true;
848
+ let error;
849
+ try {
850
+ if (currentStep.tool) {
851
+ const tool = tools.find((t) => t.metadata.name === currentStep.tool);
852
+ if (!tool) {
853
+ throw new Error(`Tool not found: ${currentStep.tool}`);
854
+ }
855
+ const timeoutPromise = new Promise(
856
+ (_, reject) => setTimeout(() => reject(new Error("Step execution timeout")), stepTimeout)
857
+ );
858
+ result = await Promise.race([
859
+ tool.execute(currentStep.args || {}),
860
+ timeoutPromise
861
+ ]);
862
+ } else {
863
+ result = { message: "Step completed without tool execution" };
864
+ }
865
+ } catch (execError) {
866
+ success = false;
867
+ error = execError instanceof Error ? execError.message : "Unknown execution error";
868
+ result = null;
869
+ }
870
+ const completedStep = {
871
+ step: currentStep,
872
+ result,
873
+ success,
874
+ error,
875
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
876
+ };
877
+ return {
878
+ pastSteps: [completedStep],
879
+ currentStepIndex: currentStepIndex + 1
880
+ };
881
+ } catch (error) {
882
+ return {
883
+ status: "failed",
884
+ error: error instanceof Error ? error.message : "Unknown error in executor"
885
+ };
886
+ }
887
+ };
888
+ }
889
+ function createReplannerNode(config) {
890
+ const {
891
+ llm,
892
+ replanThreshold = 0.7,
893
+ systemPrompt = DEFAULT_REPLANNER_SYSTEM_PROMPT
894
+ } = config;
895
+ return async (state) => {
896
+ try {
897
+ const { plan, pastSteps = [], currentStepIndex = 0 } = state;
898
+ if (!plan) {
899
+ return { status: "failed", error: "No plan available for replanning" };
900
+ }
901
+ const completedStepsText = pastSteps.map(
902
+ (ps, idx) => COMPLETED_STEP_TEMPLATE.replace("{stepNumber}", String(idx + 1)).replace("{description}", ps.step.description).replace("{result}", JSON.stringify(ps.result)).replace("{status}", ps.success ? "Success" : `Failed: ${ps.error}`)
903
+ ).join("\n\n");
904
+ const remainingSteps = plan.steps.slice(currentStepIndex);
905
+ const remainingStepsText = remainingSteps.map(
906
+ (step, idx) => REMAINING_STEP_TEMPLATE.replace("{stepNumber}", String(currentStepIndex + idx + 1)).replace("{description}", step.description).replace("{dependencies}", step.dependencies ? `Dependencies: ${step.dependencies.join(", ")}` : "")
907
+ ).join("\n\n");
908
+ const userPrompt = REPLANNING_PROMPT_TEMPLATE.replace("{goal}", plan.goal).replace("{completedSteps}", completedStepsText || "None").replace("{remainingSteps}", remainingStepsText || "None");
909
+ const messages = [
910
+ new import_messages2.SystemMessage(systemPrompt),
911
+ new import_messages2.HumanMessage(userPrompt)
912
+ ];
913
+ const response = await llm.invoke(messages);
914
+ const content = response.content.toString();
915
+ let decision;
916
+ try {
917
+ decision = JSON.parse(content);
918
+ } catch (parseError) {
919
+ throw new Error(`Failed to parse replan decision from LLM response: ${parseError}`);
920
+ }
921
+ if (decision.shouldReplan) {
922
+ return {
923
+ status: "planning",
924
+ input: decision.newGoal || plan.goal,
925
+ iteration: 1
926
+ };
927
+ } else {
928
+ return {
929
+ status: "executing"
930
+ };
931
+ }
932
+ } catch (error) {
933
+ return {
934
+ status: "failed",
935
+ error: error instanceof Error ? error.message : "Unknown error in replanner"
936
+ };
937
+ }
938
+ };
939
+ }
940
+ function createFinisherNode() {
941
+ return async (state) => {
942
+ const results = state.pastSteps?.map((ps) => ({
943
+ step: ps.step.description,
944
+ result: ps.result,
945
+ success: ps.success
946
+ })) || [];
947
+ const response = JSON.stringify({
948
+ goal: state.plan?.goal || state.input,
949
+ results,
950
+ totalSteps: state.pastSteps?.length || 0,
951
+ successfulSteps: state.pastSteps?.filter((ps) => ps.success).length || 0
952
+ }, null, 2);
953
+ return {
954
+ status: "completed",
955
+ response
956
+ };
957
+ };
958
+ }
959
+
960
+ // src/plan-execute/agent.ts
961
+ function createPlanExecuteAgent(config) {
962
+ const {
963
+ planner,
964
+ executor,
965
+ replanner,
966
+ maxIterations = 5,
967
+ verbose = false
968
+ } = config;
969
+ const plannerNode = createPlannerNode(planner);
970
+ const executorNode = createExecutorNode(executor);
971
+ const finisherNode = createFinisherNode();
972
+ const replannerNode = replanner ? createReplannerNode(replanner) : async (state) => ({ status: "executing" });
973
+ const workflow = new import_langgraph2.StateGraph(PlanExecuteState).addNode("planner", plannerNode).addNode("executor", executorNode).addNode("finisher", finisherNode).addNode("replanner", replannerNode);
974
+ const routeAfterExecutor = (state) => {
975
+ if (state.status === "failed") {
976
+ return "error";
977
+ }
978
+ if (state.status === "completed") {
979
+ return "finish";
980
+ }
981
+ const allStepsCompleted = state.currentStepIndex !== void 0 && state.plan?.steps && state.currentStepIndex >= state.plan.steps.length;
982
+ if (allStepsCompleted) {
983
+ return "finish";
984
+ }
985
+ if (replanner && state.iteration < maxIterations) {
986
+ const recentSteps = state.pastSteps?.slice(-3) || [];
987
+ const hasFailures = recentSteps.some((step) => !step.success);
988
+ if (hasFailures) {
989
+ return "replan";
990
+ }
991
+ }
992
+ return "execute";
993
+ };
994
+ const routeAfterReplanner = (state) => {
995
+ if (state.status === "failed") {
996
+ return "error";
997
+ }
998
+ if (state.status === "planning") {
999
+ return "replan";
1000
+ }
1001
+ return "execute";
1002
+ };
1003
+ workflow.addEdge("__start__", "planner");
1004
+ workflow.addEdge("planner", "executor");
1005
+ workflow.addConditionalEdges(
1006
+ "executor",
1007
+ routeAfterExecutor,
1008
+ {
1009
+ execute: "executor",
1010
+ // Loop back to execute next step
1011
+ replan: "replanner",
1012
+ finish: "finisher",
1013
+ error: import_langgraph2.END
1014
+ }
1015
+ );
1016
+ workflow.addEdge("finisher", import_langgraph2.END);
1017
+ workflow.addConditionalEdges(
1018
+ "replanner",
1019
+ routeAfterReplanner,
1020
+ {
1021
+ replan: "planner",
1022
+ execute: "executor",
1023
+ error: import_langgraph2.END,
1024
+ finish: import_langgraph2.END
1025
+ }
1026
+ );
1027
+ return workflow.compile();
1028
+ }
1029
+
1030
+ // src/reflection/state.ts
1031
+ var import_zod6 = require("zod");
1032
+ var import_core5 = require("@agentforge/core");
1033
+
1034
+ // src/reflection/schemas.ts
1035
+ var import_zod5 = require("zod");
1036
+ var ReflectionSchema = import_zod5.z.object({
1037
+ /**
1038
+ * The critique or feedback on the current response
1039
+ */
1040
+ critique: import_zod5.z.string().describe("Critique or feedback on the current response"),
1041
+ /**
1042
+ * Specific issues identified
1043
+ */
1044
+ issues: import_zod5.z.array(import_zod5.z.string()).describe("Specific issues or problems identified"),
1045
+ /**
1046
+ * Suggestions for improvement
1047
+ */
1048
+ suggestions: import_zod5.z.array(import_zod5.z.string()).describe("Suggestions for improving the response"),
1049
+ /**
1050
+ * Quality score (0-10)
1051
+ */
1052
+ score: import_zod5.z.number().min(0).max(10).optional().describe("Quality score from 0 to 10"),
1053
+ /**
1054
+ * Whether the response meets quality standards
1055
+ */
1056
+ meetsStandards: import_zod5.z.boolean().describe("Whether the response meets quality standards"),
1057
+ /**
1058
+ * Timestamp of the reflection
1059
+ */
1060
+ timestamp: import_zod5.z.date().optional().describe("When this reflection was created")
1061
+ });
1062
+ var RevisionSchema = import_zod5.z.object({
1063
+ /**
1064
+ * The revised content
1065
+ */
1066
+ content: import_zod5.z.string().describe("The revised content"),
1067
+ /**
1068
+ * Which iteration this revision is from
1069
+ */
1070
+ iteration: import_zod5.z.number().int().nonnegative().describe("Iteration number"),
1071
+ /**
1072
+ * The reflection that prompted this revision
1073
+ */
1074
+ basedOn: ReflectionSchema.optional().describe("The reflection that prompted this revision"),
1075
+ /**
1076
+ * Timestamp of the revision
1077
+ */
1078
+ timestamp: import_zod5.z.date().optional().describe("When this revision was created")
1079
+ });
1080
+ var ReflectionStatusSchema = import_zod5.z.enum([
1081
+ "generating",
1082
+ // Initial generation
1083
+ "reflecting",
1084
+ // Critiquing current response
1085
+ "revising",
1086
+ // Improving based on critique
1087
+ "completed",
1088
+ // Quality threshold met
1089
+ "failed"
1090
+ // Max iterations reached without meeting standards
1091
+ ]);
1092
+ var QualityCriteriaSchema = import_zod5.z.object({
1093
+ /**
1094
+ * Minimum quality score required (0-10)
1095
+ */
1096
+ minScore: import_zod5.z.number().min(0).max(10).default(7).describe("Minimum quality score required"),
1097
+ /**
1098
+ * Specific criteria to evaluate
1099
+ */
1100
+ criteria: import_zod5.z.array(import_zod5.z.string()).optional().describe("Specific criteria to evaluate"),
1101
+ /**
1102
+ * Whether all criteria must be met
1103
+ */
1104
+ requireAll: import_zod5.z.boolean().default(true).describe("Whether all criteria must be met")
1105
+ });
1106
+ var ReflectionConfigSchema = import_zod5.z.object({
1107
+ /**
1108
+ * Maximum number of reflection iterations
1109
+ */
1110
+ maxIterations: import_zod5.z.number().int().positive().default(3).describe("Maximum reflection iterations"),
1111
+ /**
1112
+ * Quality criteria for completion
1113
+ */
1114
+ qualityCriteria: QualityCriteriaSchema.optional().describe("Quality criteria for completion"),
1115
+ /**
1116
+ * Whether to include previous reflections in context
1117
+ */
1118
+ includeHistory: import_zod5.z.boolean().default(true).describe("Include previous reflections in context")
1119
+ });
1120
+
1121
+ // src/reflection/state.ts
1122
+ var ReflectionStateConfig = {
1123
+ /**
1124
+ * Original user input/task
1125
+ */
1126
+ input: {
1127
+ schema: import_zod6.z.string(),
1128
+ default: () => "",
1129
+ description: "Original user input or task"
1130
+ },
1131
+ /**
1132
+ * Current response/output
1133
+ */
1134
+ currentResponse: {
1135
+ schema: import_zod6.z.string().optional(),
1136
+ description: "Current response or output"
1137
+ },
1138
+ /**
1139
+ * History of all reflections/critiques
1140
+ * Accumulates all reflections
1141
+ */
1142
+ reflections: {
1143
+ schema: import_zod6.z.array(ReflectionSchema),
1144
+ reducer: (left, right) => [...left, ...right],
1145
+ default: () => [],
1146
+ description: "History of all reflections and critiques"
1147
+ },
1148
+ /**
1149
+ * History of all revisions
1150
+ * Accumulates all revisions
1151
+ */
1152
+ revisions: {
1153
+ schema: import_zod6.z.array(RevisionSchema),
1154
+ reducer: (left, right) => [...left, ...right],
1155
+ default: () => [],
1156
+ description: "History of all revisions"
1157
+ },
1158
+ /**
1159
+ * Current iteration number
1160
+ */
1161
+ iteration: {
1162
+ schema: import_zod6.z.number().int().nonnegative(),
1163
+ reducer: (left, right) => left + right,
1164
+ default: () => 0,
1165
+ description: "Current iteration number"
1166
+ },
1167
+ /**
1168
+ * Current status
1169
+ */
1170
+ status: {
1171
+ schema: ReflectionStatusSchema,
1172
+ default: () => "generating",
1173
+ description: "Current reflection status"
1174
+ },
1175
+ /**
1176
+ * Quality criteria for completion
1177
+ */
1178
+ qualityCriteria: {
1179
+ schema: QualityCriteriaSchema.optional(),
1180
+ description: "Quality criteria for determining completion"
1181
+ },
1182
+ /**
1183
+ * Maximum iterations allowed
1184
+ */
1185
+ maxIterations: {
1186
+ schema: import_zod6.z.number().int().positive(),
1187
+ default: () => 3,
1188
+ description: "Maximum number of reflection iterations allowed"
1189
+ },
1190
+ /**
1191
+ * Final response (when completed)
1192
+ */
1193
+ response: {
1194
+ schema: import_zod6.z.string().optional(),
1195
+ description: "Final response after reflection process"
1196
+ },
1197
+ /**
1198
+ * Error message if failed
1199
+ */
1200
+ error: {
1201
+ schema: import_zod6.z.string().optional(),
1202
+ description: "Error message if reflection failed"
1203
+ }
1204
+ };
1205
+ var ReflectionState = (0, import_core5.createStateAnnotation)(ReflectionStateConfig);
1206
+
1207
+ // src/reflection/prompts.ts
1208
+ var DEFAULT_GENERATOR_SYSTEM_PROMPT = `You are an expert content generator. Your task is to create high-quality responses to user requests.
1209
+
1210
+ Focus on:
1211
+ - Clarity and coherence
1212
+ - Accuracy and correctness
1213
+ - Completeness and thoroughness
1214
+ - Appropriate tone and style
1215
+
1216
+ Generate the best possible response to the user's request.`;
1217
+ var DEFAULT_REFLECTOR_SYSTEM_PROMPT = `You are an expert critic and reviewer. Your task is to provide constructive feedback on responses.
1218
+
1219
+ Evaluate the response based on:
1220
+ - Clarity: Is it easy to understand?
1221
+ - Accuracy: Is the information correct?
1222
+ - Completeness: Does it fully address the request?
1223
+ - Quality: Is it well-written and professional?
1224
+
1225
+ Provide specific, actionable feedback for improvement.`;
1226
+ var DEFAULT_REVISER_SYSTEM_PROMPT = `You are an expert editor and reviser. Your task is to improve responses based on feedback.
1227
+
1228
+ Focus on:
1229
+ - Addressing all identified issues
1230
+ - Implementing suggested improvements
1231
+ - Maintaining the core message
1232
+ - Enhancing overall quality
1233
+
1234
+ Create an improved version that addresses the critique.`;
1235
+ var GENERATION_PROMPT_TEMPLATE = `Please generate a response to the following request:
1236
+
1237
+ {input}
1238
+
1239
+ {context}
1240
+
1241
+ Provide a high-quality, complete response.`;
1242
+ var REFLECTION_PROMPT_TEMPLATE = `Please review and critique the following response:
1243
+
1244
+ Original Request:
1245
+ {input}
1246
+
1247
+ Current Response:
1248
+ {currentResponse}
1249
+
1250
+ {criteria}
1251
+
1252
+ {history}
1253
+
1254
+ Provide a detailed critique including:
1255
+ 1. What works well
1256
+ 2. Specific issues or problems
1257
+ 3. Suggestions for improvement
1258
+ 4. A quality score (0-10)
1259
+ 5. Whether it meets quality standards
1260
+
1261
+ Format your response as JSON with the following structure:
1262
+ {
1263
+ "critique": "overall assessment",
1264
+ "issues": ["issue 1", "issue 2"],
1265
+ "suggestions": ["suggestion 1", "suggestion 2"],
1266
+ "score": 8,
1267
+ "meetsStandards": true
1268
+ }`;
1269
+ var REVISION_PROMPT_TEMPLATE = `Please revise the following response based on the critique:
1270
+
1271
+ Original Request:
1272
+ {input}
1273
+
1274
+ Current Response:
1275
+ {currentResponse}
1276
+
1277
+ Critique:
1278
+ {critique}
1279
+
1280
+ Issues to Address:
1281
+ {issues}
1282
+
1283
+ Suggestions:
1284
+ {suggestions}
1285
+
1286
+ {history}
1287
+
1288
+ Create an improved version that addresses all the feedback while maintaining the core message.`;
1289
+ var QUALITY_CRITERIA_TEMPLATE = `Evaluate against these specific criteria:
1290
+ {criteria}
1291
+
1292
+ Minimum required score: {minScore}/10
1293
+ {requireAll}`;
1294
+ var REFLECTION_HISTORY_TEMPLATE = `Previous Reflections:
1295
+ {reflections}
1296
+
1297
+ Previous Revisions:
1298
+ {revisions}`;
1299
+ var REFLECTION_ENTRY_TEMPLATE = `Iteration {iteration}:
1300
+ Critique: {critique}
1301
+ Score: {score}/10
1302
+ Issues: {issues}
1303
+ Suggestions: {suggestions}`;
1304
+ var REVISION_ENTRY_TEMPLATE = `Iteration {iteration}:
1305
+ {content}`;
1306
+
1307
+ // src/reflection/nodes.ts
1308
+ var import_messages3 = require("@langchain/core/messages");
1309
+ function createGeneratorNode(config) {
1310
+ const {
1311
+ llm,
1312
+ systemPrompt = DEFAULT_GENERATOR_SYSTEM_PROMPT,
1313
+ verbose = false
1314
+ } = config;
1315
+ return async (state) => {
1316
+ try {
1317
+ if (verbose) {
1318
+ console.log("[Generator] Generating initial response...");
1319
+ }
1320
+ let context = "";
1321
+ if (state.iteration > 0 && state.reflections.length > 0) {
1322
+ const lastReflection = state.reflections[state.reflections.length - 1];
1323
+ context = `
1324
+ Previous feedback to consider:
1325
+ ${lastReflection.critique}`;
1326
+ }
1327
+ const userPrompt = GENERATION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{context}", context);
1328
+ const messages = [
1329
+ new import_messages3.SystemMessage(systemPrompt),
1330
+ new import_messages3.HumanMessage(userPrompt)
1331
+ ];
1332
+ const response = await llm.invoke(messages);
1333
+ const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1334
+ if (verbose) {
1335
+ console.log("[Generator] Generated response:", content.substring(0, 100) + "...");
1336
+ }
1337
+ return {
1338
+ currentResponse: content,
1339
+ status: "reflecting",
1340
+ iteration: 1
1341
+ };
1342
+ } catch (error) {
1343
+ console.error("[Generator] Error:", error);
1344
+ return {
1345
+ status: "failed",
1346
+ error: error instanceof Error ? error.message : "Unknown error in generator"
1347
+ };
1348
+ }
1349
+ };
1350
+ }
1351
+ function createReflectorNode(config) {
1352
+ const {
1353
+ llm,
1354
+ systemPrompt = DEFAULT_REFLECTOR_SYSTEM_PROMPT,
1355
+ qualityCriteria,
1356
+ verbose = false
1357
+ } = config;
1358
+ return async (state) => {
1359
+ try {
1360
+ if (verbose) {
1361
+ console.log("[Reflector] Reflecting on response...");
1362
+ }
1363
+ if (!state.currentResponse) {
1364
+ throw new Error("No current response to reflect on");
1365
+ }
1366
+ let criteriaSection = "";
1367
+ const criteria = qualityCriteria || state.qualityCriteria;
1368
+ if (criteria) {
1369
+ const criteriaList = criteria.criteria?.join("\n- ") || "";
1370
+ criteriaSection = QUALITY_CRITERIA_TEMPLATE.replace("{criteria}", criteriaList ? `- ${criteriaList}` : "General quality standards").replace("{minScore}", criteria.minScore?.toString() || "7").replace("{requireAll}", criteria.requireAll ? "All criteria must be met." : "Meet as many criteria as possible.");
1371
+ }
1372
+ let historySection = "";
1373
+ if (state.reflections.length > 0 || state.revisions.length > 0) {
1374
+ const reflectionsText = state.reflections.map(
1375
+ (r, idx) => REFLECTION_ENTRY_TEMPLATE.replace("{iteration}", (idx + 1).toString()).replace("{critique}", r.critique).replace("{score}", r.score?.toString() || "N/A").replace("{issues}", r.issues.join(", ")).replace("{suggestions}", r.suggestions.join(", "))
1376
+ ).join("\n\n");
1377
+ const revisionsText = state.revisions.map(
1378
+ (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1379
+ ).join("\n\n");
1380
+ historySection = REFLECTION_HISTORY_TEMPLATE.replace("{reflections}", reflectionsText || "None").replace("{revisions}", revisionsText || "None");
1381
+ }
1382
+ const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", criteriaSection).replace("{history}", historySection);
1383
+ const messages = [
1384
+ new import_messages3.SystemMessage(systemPrompt),
1385
+ new import_messages3.HumanMessage(userPrompt)
1386
+ ];
1387
+ const response = await llm.invoke(messages);
1388
+ const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1389
+ let reflection;
1390
+ try {
1391
+ const jsonMatch = content.match(/\{[\s\S]*\}/);
1392
+ if (jsonMatch) {
1393
+ reflection = JSON.parse(jsonMatch[0]);
1394
+ } else {
1395
+ reflection = {
1396
+ critique: content,
1397
+ issues: [],
1398
+ suggestions: [],
1399
+ score: 5,
1400
+ meetsStandards: false
1401
+ };
1402
+ }
1403
+ } catch (parseError) {
1404
+ reflection = {
1405
+ critique: content,
1406
+ issues: [],
1407
+ suggestions: [],
1408
+ score: 5,
1409
+ meetsStandards: false
1410
+ };
1411
+ }
1412
+ if (verbose) {
1413
+ console.log("[Reflector] Reflection score:", reflection.score);
1414
+ console.log("[Reflector] Meets standards:", reflection.meetsStandards);
1415
+ }
1416
+ return {
1417
+ reflections: [reflection],
1418
+ status: reflection.meetsStandards ? "completed" : "revising"
1419
+ };
1420
+ } catch (error) {
1421
+ console.error("[Reflector] Error:", error);
1422
+ return {
1423
+ status: "failed",
1424
+ error: error instanceof Error ? error.message : "Unknown error in reflector"
1425
+ };
1426
+ }
1427
+ };
1428
+ }
1429
+ function createReviserNode(config) {
1430
+ const {
1431
+ llm,
1432
+ systemPrompt = DEFAULT_REVISER_SYSTEM_PROMPT,
1433
+ verbose = false
1434
+ } = config;
1435
+ return async (state) => {
1436
+ try {
1437
+ if (verbose) {
1438
+ console.log("[Reviser] Revising response...");
1439
+ }
1440
+ if (!state.currentResponse) {
1441
+ throw new Error("No current response to revise");
1442
+ }
1443
+ if (state.reflections.length === 0) {
1444
+ throw new Error("No reflections to base revision on");
1445
+ }
1446
+ const lastReflection = state.reflections[state.reflections.length - 1];
1447
+ let historySection = "";
1448
+ if (state.revisions.length > 0) {
1449
+ const revisionsText = state.revisions.map(
1450
+ (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1451
+ ).join("\n\n");
1452
+ historySection = `
1453
+ Previous Revisions:
1454
+ ${revisionsText}`;
1455
+ }
1456
+ const userPrompt = REVISION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{critique}", lastReflection.critique).replace("{issues}", lastReflection.issues.join("\n- ")).replace("{suggestions}", lastReflection.suggestions.join("\n- ")).replace("{history}", historySection);
1457
+ const messages = [
1458
+ new import_messages3.SystemMessage(systemPrompt),
1459
+ new import_messages3.HumanMessage(userPrompt)
1460
+ ];
1461
+ const response = await llm.invoke(messages);
1462
+ const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1463
+ if (verbose) {
1464
+ console.log("[Reviser] Created revision:", content.substring(0, 100) + "...");
1465
+ }
1466
+ const revision = {
1467
+ content,
1468
+ iteration: state.iteration,
1469
+ basedOn: lastReflection
1470
+ };
1471
+ return {
1472
+ currentResponse: content,
1473
+ revisions: [revision],
1474
+ status: "reflecting",
1475
+ iteration: 1
1476
+ };
1477
+ } catch (error) {
1478
+ console.error("[Reviser] Error:", error);
1479
+ return {
1480
+ status: "failed",
1481
+ error: error instanceof Error ? error.message : "Unknown error in reviser"
1482
+ };
1483
+ }
1484
+ };
1485
+ }
1486
+ function createFinisherNode2() {
1487
+ return async (state) => {
1488
+ return {
1489
+ status: "completed",
1490
+ response: state.currentResponse
1491
+ };
1492
+ };
1493
+ }
1494
+
1495
+ // src/reflection/agent.ts
1496
+ var import_langgraph3 = require("@langchain/langgraph");
1497
+ function createReflectionAgent(config) {
1498
+ const {
1499
+ generator,
1500
+ reflector,
1501
+ reviser,
1502
+ maxIterations = 3,
1503
+ qualityCriteria,
1504
+ verbose = false
1505
+ } = config;
1506
+ const generatorNode = createGeneratorNode({ ...generator, verbose });
1507
+ const reflectorNode = createReflectorNode({ ...reflector, qualityCriteria, verbose });
1508
+ const reviserNode = createReviserNode({ ...reviser, verbose });
1509
+ const finisherNode = createFinisherNode2();
1510
+ const routeAfterGenerator = (state) => {
1511
+ if (state.status === "failed") {
1512
+ return "error";
1513
+ }
1514
+ return "reflect";
1515
+ };
1516
+ const routeAfterReflector = (state) => {
1517
+ if (state.status === "failed") {
1518
+ return "error";
1519
+ }
1520
+ if (state.status === "completed") {
1521
+ return "finish";
1522
+ }
1523
+ if (state.iteration >= maxIterations) {
1524
+ return "finish";
1525
+ }
1526
+ return "revise";
1527
+ };
1528
+ const routeAfterReviser = (state) => {
1529
+ if (state.status === "failed") {
1530
+ return "error";
1531
+ }
1532
+ if (state.iteration >= maxIterations) {
1533
+ return "finish";
1534
+ }
1535
+ return "reflect";
1536
+ };
1537
+ const workflow = new import_langgraph3.StateGraph(ReflectionState).addNode("generator", generatorNode).addNode("reflector", reflectorNode).addNode("reviser", reviserNode).addNode("finisher", finisherNode);
1538
+ workflow.addEdge("__start__", "generator").addConditionalEdges(
1539
+ "generator",
1540
+ routeAfterGenerator,
1541
+ {
1542
+ reflect: "reflector",
1543
+ error: import_langgraph3.END
1544
+ }
1545
+ ).addConditionalEdges(
1546
+ "reflector",
1547
+ routeAfterReflector,
1548
+ {
1549
+ revise: "reviser",
1550
+ finish: "finisher",
1551
+ error: import_langgraph3.END
1552
+ }
1553
+ ).addConditionalEdges(
1554
+ "reviser",
1555
+ routeAfterReviser,
1556
+ {
1557
+ reflect: "reflector",
1558
+ finish: "finisher",
1559
+ error: import_langgraph3.END
1560
+ }
1561
+ ).addEdge("finisher", import_langgraph3.END);
1562
+ return workflow.compile();
1563
+ }
1564
+
1565
+ // src/multi-agent/state.ts
1566
+ var import_zod8 = require("zod");
1567
+ var import_core6 = require("@agentforge/core");
1568
+
1569
+ // src/multi-agent/schemas.ts
1570
+ var import_zod7 = require("zod");
1571
+ var AgentRoleSchema = import_zod7.z.enum(["supervisor", "worker"]);
1572
+ var MessageTypeSchema = import_zod7.z.enum([
1573
+ "user_input",
1574
+ // Initial user message
1575
+ "task_assignment",
1576
+ // Supervisor assigns task to worker
1577
+ "task_result",
1578
+ // Worker returns result to supervisor
1579
+ "handoff",
1580
+ // Worker hands off to another worker
1581
+ "error",
1582
+ // Error message
1583
+ "completion"
1584
+ // Final completion message
1585
+ ]);
1586
+ var AgentMessageSchema = import_zod7.z.object({
1587
+ /**
1588
+ * Unique identifier for the message
1589
+ */
1590
+ id: import_zod7.z.string().describe("Unique message identifier"),
1591
+ /**
1592
+ * Type of message
1593
+ */
1594
+ type: MessageTypeSchema.describe("Type of message"),
1595
+ /**
1596
+ * Agent that sent the message
1597
+ */
1598
+ from: import_zod7.z.string().describe("Agent identifier that sent the message"),
1599
+ /**
1600
+ * Agent(s) that should receive the message
1601
+ */
1602
+ to: import_zod7.z.union([import_zod7.z.string(), import_zod7.z.array(import_zod7.z.string())]).describe("Target agent(s)"),
1603
+ /**
1604
+ * Message content
1605
+ */
1606
+ content: import_zod7.z.string().describe("Message content"),
1607
+ /**
1608
+ * Optional metadata
1609
+ */
1610
+ metadata: import_zod7.z.record(import_zod7.z.any()).optional().describe("Additional message metadata"),
1611
+ /**
1612
+ * Timestamp when message was created
1613
+ */
1614
+ timestamp: import_zod7.z.number().describe("Timestamp when message was created")
1615
+ });
1616
+ var RoutingStrategySchema = import_zod7.z.enum([
1617
+ "llm-based",
1618
+ // LLM decides which agent to route to
1619
+ "rule-based",
1620
+ // Predefined rules determine routing
1621
+ "round-robin",
1622
+ // Distribute tasks evenly across agents
1623
+ "skill-based",
1624
+ // Route based on agent capabilities
1625
+ "load-balanced"
1626
+ // Route based on agent workload
1627
+ ]);
1628
+ var RoutingDecisionSchema = import_zod7.z.object({
1629
+ /**
1630
+ * Target agent to route to
1631
+ */
1632
+ targetAgent: import_zod7.z.string().describe("Agent to route the task to"),
1633
+ /**
1634
+ * Reasoning for the routing decision
1635
+ */
1636
+ reasoning: import_zod7.z.string().optional().describe("Explanation for routing decision"),
1637
+ /**
1638
+ * Confidence in the routing decision (0-1)
1639
+ */
1640
+ confidence: import_zod7.z.number().min(0).max(1).optional().describe("Confidence score"),
1641
+ /**
1642
+ * Strategy used for routing
1643
+ */
1644
+ strategy: RoutingStrategySchema.describe("Strategy used for this decision"),
1645
+ /**
1646
+ * Timestamp of the routing decision
1647
+ */
1648
+ timestamp: import_zod7.z.number().optional().describe("Timestamp of the decision")
1649
+ });
1650
+ var WorkerCapabilitiesSchema = import_zod7.z.object({
1651
+ /**
1652
+ * Skills/capabilities the agent has
1653
+ */
1654
+ skills: import_zod7.z.array(import_zod7.z.string()).describe("List of agent skills"),
1655
+ /**
1656
+ * Tools available to the agent
1657
+ */
1658
+ tools: import_zod7.z.array(import_zod7.z.string()).describe("List of tool names available to agent"),
1659
+ /**
1660
+ * Whether the agent is currently available
1661
+ */
1662
+ available: import_zod7.z.boolean().default(true).describe("Whether agent is available"),
1663
+ /**
1664
+ * Current workload (number of active tasks)
1665
+ */
1666
+ currentWorkload: import_zod7.z.number().int().nonnegative().default(0).describe("Current number of active tasks")
1667
+ });
1668
+ var TaskAssignmentSchema = import_zod7.z.object({
1669
+ /**
1670
+ * Unique assignment identifier
1671
+ */
1672
+ id: import_zod7.z.string().describe("Unique assignment identifier"),
1673
+ /**
1674
+ * Worker ID assigned to the task
1675
+ */
1676
+ workerId: import_zod7.z.string().describe("Worker identifier assigned to task"),
1677
+ /**
1678
+ * Task description
1679
+ */
1680
+ task: import_zod7.z.string().describe("Description of the task"),
1681
+ /**
1682
+ * Task priority (1-10, higher is more urgent)
1683
+ */
1684
+ priority: import_zod7.z.number().int().min(1).max(10).default(5).describe("Task priority"),
1685
+ /**
1686
+ * Timestamp when task was assigned
1687
+ */
1688
+ assignedAt: import_zod7.z.number().describe("Timestamp when task was assigned"),
1689
+ /**
1690
+ * Optional deadline for task completion
1691
+ */
1692
+ deadline: import_zod7.z.number().optional().describe("Optional task deadline timestamp")
1693
+ });
1694
+ var TaskResultSchema = import_zod7.z.object({
1695
+ /**
1696
+ * Assignment identifier
1697
+ */
1698
+ assignmentId: import_zod7.z.string().describe("Assignment identifier"),
1699
+ /**
1700
+ * Worker that completed the task
1701
+ */
1702
+ workerId: import_zod7.z.string().describe("Worker that completed the task"),
1703
+ /**
1704
+ * Whether the task succeeded
1705
+ */
1706
+ success: import_zod7.z.boolean().describe("Whether the task succeeded"),
1707
+ /**
1708
+ * Task result/output
1709
+ */
1710
+ result: import_zod7.z.string().describe("Task result or output"),
1711
+ /**
1712
+ * Optional error message if task failed
1713
+ */
1714
+ error: import_zod7.z.string().optional().describe("Error message if task failed"),
1715
+ /**
1716
+ * Timestamp when task was completed
1717
+ */
1718
+ completedAt: import_zod7.z.number().describe("Timestamp when task was completed"),
1719
+ /**
1720
+ * Optional metadata about execution
1721
+ */
1722
+ metadata: import_zod7.z.record(import_zod7.z.any()).optional().describe("Execution metadata")
1723
+ });
1724
+ var MultiAgentStatusSchema = import_zod7.z.enum([
1725
+ "initializing",
1726
+ // System is initializing
1727
+ "routing",
1728
+ // Supervisor is routing the task
1729
+ "executing",
1730
+ // Worker is executing the task
1731
+ "coordinating",
1732
+ // Multiple workers are coordinating
1733
+ "aggregating",
1734
+ // Results are being aggregated
1735
+ "completed",
1736
+ // Task is completed
1737
+ "failed"
1738
+ // Task failed
1739
+ ]);
1740
+ var HandoffRequestSchema = import_zod7.z.object({
1741
+ /**
1742
+ * Agent requesting the handoff
1743
+ */
1744
+ from: import_zod7.z.string().describe("Agent requesting handoff"),
1745
+ /**
1746
+ * Target agent for handoff
1747
+ */
1748
+ to: import_zod7.z.string().describe("Target agent for handoff"),
1749
+ /**
1750
+ * Reason for handoff
1751
+ */
1752
+ reason: import_zod7.z.string().describe("Reason for requesting handoff"),
1753
+ /**
1754
+ * Context to pass to next agent
1755
+ */
1756
+ context: import_zod7.z.any().describe("Context to pass to next agent"),
1757
+ /**
1758
+ * Timestamp of handoff request
1759
+ */
1760
+ timestamp: import_zod7.z.string().datetime().describe("ISO timestamp of handoff request")
1761
+ });
1762
+
1763
+ // src/multi-agent/state.ts
1764
+ var MultiAgentStateConfig = {
1765
+ /**
1766
+ * Original user input/query
1767
+ */
1768
+ input: {
1769
+ schema: import_zod8.z.string(),
1770
+ default: () => "",
1771
+ description: "Original user input or query"
1772
+ },
1773
+ /**
1774
+ * All messages in the multi-agent conversation
1775
+ * Accumulates all messages between agents
1776
+ */
1777
+ messages: {
1778
+ schema: import_zod8.z.array(AgentMessageSchema),
1779
+ reducer: (left, right) => [...left, ...right],
1780
+ default: () => [],
1781
+ description: "All messages in the multi-agent conversation"
1782
+ },
1783
+ /**
1784
+ * Available worker agents and their capabilities
1785
+ */
1786
+ workers: {
1787
+ schema: import_zod8.z.record(import_zod8.z.string(), WorkerCapabilitiesSchema),
1788
+ reducer: (left, right) => ({
1789
+ ...left,
1790
+ ...right
1791
+ }),
1792
+ default: () => ({}),
1793
+ description: "Available worker agents and their capabilities"
1794
+ },
1795
+ /**
1796
+ * Current active agent
1797
+ */
1798
+ currentAgent: {
1799
+ schema: import_zod8.z.string().optional(),
1800
+ description: "Identifier of the currently active agent"
1801
+ },
1802
+ /**
1803
+ * Routing decisions made by the supervisor
1804
+ * Accumulates all routing decisions
1805
+ */
1806
+ routingHistory: {
1807
+ schema: import_zod8.z.array(RoutingDecisionSchema),
1808
+ reducer: (left, right) => [...left, ...right],
1809
+ default: () => [],
1810
+ description: "History of routing decisions"
1811
+ },
1812
+ /**
1813
+ * Active task assignments
1814
+ */
1815
+ activeAssignments: {
1816
+ schema: import_zod8.z.array(TaskAssignmentSchema),
1817
+ reducer: (left, right) => [...left, ...right],
1818
+ default: () => [],
1819
+ description: "Currently active task assignments"
1820
+ },
1821
+ /**
1822
+ * Completed task results
1823
+ * Accumulates all completed tasks
1824
+ */
1825
+ completedTasks: {
1826
+ schema: import_zod8.z.array(TaskResultSchema),
1827
+ reducer: (left, right) => [...left, ...right],
1828
+ default: () => [],
1829
+ description: "Completed task results"
1830
+ },
1831
+ /**
1832
+ * Handoff requests between agents
1833
+ * Accumulates all handoff requests
1834
+ */
1835
+ handoffs: {
1836
+ schema: import_zod8.z.array(HandoffRequestSchema),
1837
+ reducer: (left, right) => [...left, ...right],
1838
+ default: () => [],
1839
+ description: "Handoff requests between agents"
1840
+ },
1841
+ /**
1842
+ * Current execution status
1843
+ */
1844
+ status: {
1845
+ schema: MultiAgentStatusSchema,
1846
+ default: () => "initializing",
1847
+ description: "Current multi-agent execution status"
1848
+ },
1849
+ /**
1850
+ * Iteration counter
1851
+ */
1852
+ iteration: {
1853
+ schema: import_zod8.z.number().int().nonnegative(),
1854
+ reducer: (left, right) => left + right,
1855
+ default: () => 0,
1856
+ description: "Current iteration number"
1857
+ },
1858
+ /**
1859
+ * Maximum iterations allowed
1860
+ */
1861
+ maxIterations: {
1862
+ schema: import_zod8.z.number().int().positive(),
1863
+ default: () => 10,
1864
+ description: "Maximum number of iterations allowed"
1865
+ },
1866
+ /**
1867
+ * Final aggregated response
1868
+ */
1869
+ response: {
1870
+ schema: import_zod8.z.string().optional(),
1871
+ description: "Final aggregated response"
1872
+ },
1873
+ /**
1874
+ * Error message if execution failed
1875
+ */
1876
+ error: {
1877
+ schema: import_zod8.z.string().optional(),
1878
+ description: "Error message if execution failed"
1879
+ }
1880
+ };
1881
+ var MultiAgentState = (0, import_core6.createStateAnnotation)(MultiAgentStateConfig);
1882
+
1883
+ // src/multi-agent/routing.ts
1884
+ var import_messages4 = require("@langchain/core/messages");
1885
+ var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
1886
+
1887
+ Your job is to:
1888
+ 1. Analyze the current task and context
1889
+ 2. Review available worker capabilities
1890
+ 3. Select the most appropriate worker for the task
1891
+ 4. Provide clear reasoning for your decision
1892
+
1893
+ Respond with a JSON object containing:
1894
+ {
1895
+ "targetAgent": "worker_id",
1896
+ "reasoning": "explanation of why this worker is best suited",
1897
+ "confidence": 0.0-1.0,
1898
+ "strategy": "llm-based"
1899
+ }`;
1900
+ var llmBasedRouting = {
1901
+ name: "llm-based",
1902
+ async route(state, config) {
1903
+ if (!config.llm) {
1904
+ throw new Error("LLM-based routing requires an LLM to be configured");
1905
+ }
1906
+ const systemPrompt = config.systemPrompt || DEFAULT_SUPERVISOR_SYSTEM_PROMPT;
1907
+ const workerInfo = Object.entries(state.workers).map(([id, caps]) => {
1908
+ const skills = caps.skills.join(", ");
1909
+ const tools = caps.tools.join(", ");
1910
+ const available = caps.available ? "available" : "busy";
1911
+ return `- ${id}: Skills: [${skills}], Tools: [${tools}], Status: ${available}, Workload: ${caps.currentWorkload}`;
1912
+ }).join("\n");
1913
+ const lastMessage = state.messages[state.messages.length - 1];
1914
+ const taskContext = lastMessage?.content || state.input;
1915
+ const userPrompt = `Current task: ${taskContext}
1916
+
1917
+ Available workers:
1918
+ ${workerInfo}
1919
+
1920
+ Select the best worker for this task and explain your reasoning.`;
1921
+ const messages = [
1922
+ new import_messages4.SystemMessage(systemPrompt),
1923
+ new import_messages4.HumanMessage(userPrompt)
1924
+ ];
1925
+ const response = await config.llm.invoke(messages);
1926
+ const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1927
+ try {
1928
+ const decision = JSON.parse(content);
1929
+ return {
1930
+ targetAgent: decision.targetAgent,
1931
+ reasoning: decision.reasoning,
1932
+ confidence: decision.confidence,
1933
+ strategy: "llm-based",
1934
+ timestamp: Date.now()
1935
+ };
1936
+ } catch (error) {
1937
+ throw new Error(`Failed to parse routing decision from LLM: ${error}`);
1938
+ }
1939
+ }
1940
+ };
1941
+ var roundRobinRouting = {
1942
+ name: "round-robin",
1943
+ async route(state, config) {
1944
+ const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id]) => id);
1945
+ if (availableWorkers.length === 0) {
1946
+ throw new Error("No available workers for round-robin routing");
1947
+ }
1948
+ const lastRoutingIndex = state.routingHistory.length % availableWorkers.length;
1949
+ const targetAgent = availableWorkers[lastRoutingIndex];
1950
+ return {
1951
+ targetAgent,
1952
+ reasoning: `Round-robin selection: worker ${lastRoutingIndex + 1} of ${availableWorkers.length}`,
1953
+ confidence: 1,
1954
+ strategy: "round-robin",
1955
+ timestamp: Date.now()
1956
+ };
1957
+ }
1958
+ };
1959
+ var skillBasedRouting = {
1960
+ name: "skill-based",
1961
+ async route(state, config) {
1962
+ const lastMessage = state.messages[state.messages.length - 1];
1963
+ const taskContent = (lastMessage?.content || state.input).toLowerCase();
1964
+ const workerScores = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => {
1965
+ const skillMatches = caps.skills.filter(
1966
+ (skill) => taskContent.includes(skill.toLowerCase())
1967
+ ).length;
1968
+ const toolMatches = caps.tools.filter(
1969
+ (tool) => taskContent.includes(tool.toLowerCase())
1970
+ ).length;
1971
+ const score = skillMatches * 2 + toolMatches;
1972
+ return { id, score, skills: caps.skills, tools: caps.tools };
1973
+ }).filter((w) => w.score > 0).sort((a, b) => b.score - a.score);
1974
+ if (workerScores.length === 0) {
1975
+ const firstAvailable = Object.entries(state.workers).find(([_, caps]) => caps.available);
1976
+ if (!firstAvailable) {
1977
+ throw new Error("No available workers for skill-based routing");
1978
+ }
1979
+ return {
1980
+ targetAgent: firstAvailable[0],
1981
+ reasoning: "No skill matches found, using first available worker",
1982
+ confidence: 0.5,
1983
+ strategy: "skill-based",
1984
+ timestamp: Date.now()
1985
+ };
1986
+ }
1987
+ const best = workerScores[0];
1988
+ const confidence = Math.min(best.score / 5, 1);
1989
+ return {
1990
+ targetAgent: best.id,
1991
+ reasoning: `Best skill match with score ${best.score} (skills: ${best.skills.join(", ")})`,
1992
+ confidence,
1993
+ strategy: "skill-based",
1994
+ timestamp: Date.now()
1995
+ };
1996
+ }
1997
+ };
1998
+ var loadBalancedRouting = {
1999
+ name: "load-balanced",
2000
+ async route(state, config) {
2001
+ const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => ({ id, workload: caps.currentWorkload })).sort((a, b) => a.workload - b.workload);
2002
+ if (availableWorkers.length === 0) {
2003
+ throw new Error("No available workers for load-balanced routing");
2004
+ }
2005
+ const targetWorker = availableWorkers[0];
2006
+ const avgWorkload = availableWorkers.reduce((sum, w) => sum + w.workload, 0) / availableWorkers.length;
2007
+ const confidence = targetWorker.workload === 0 ? 1 : Math.max(0.5, 1 - targetWorker.workload / (avgWorkload * 2));
2008
+ return {
2009
+ targetAgent: targetWorker.id,
2010
+ reasoning: `Lowest workload: ${targetWorker.workload} tasks (avg: ${avgWorkload.toFixed(1)})`,
2011
+ confidence,
2012
+ strategy: "load-balanced",
2013
+ timestamp: Date.now()
2014
+ };
2015
+ }
2016
+ };
2017
+ var ruleBasedRouting = {
2018
+ name: "rule-based",
2019
+ async route(state, config) {
2020
+ if (!config.routingFn) {
2021
+ throw new Error("Rule-based routing requires a custom routing function");
2022
+ }
2023
+ return await config.routingFn(state);
2024
+ }
2025
+ };
2026
+ function getRoutingStrategy(name) {
2027
+ switch (name) {
2028
+ case "llm-based":
2029
+ return llmBasedRouting;
2030
+ case "round-robin":
2031
+ return roundRobinRouting;
2032
+ case "skill-based":
2033
+ return skillBasedRouting;
2034
+ case "load-balanced":
2035
+ return loadBalancedRouting;
2036
+ case "rule-based":
2037
+ return ruleBasedRouting;
2038
+ default:
2039
+ throw new Error(`Unknown routing strategy: ${name}`);
2040
+ }
2041
+ }
2042
+
2043
+ // src/multi-agent/nodes.ts
2044
+ var import_messages5 = require("@langchain/core/messages");
2045
+ var import_core7 = require("@agentforge/core");
2046
+ var DEFAULT_AGGREGATOR_SYSTEM_PROMPT = `You are an aggregator agent responsible for combining results from multiple worker agents.
2047
+
2048
+ Your job is to:
2049
+ 1. Review all completed task results
2050
+ 2. Synthesize the information into a coherent response
2051
+ 3. Ensure all aspects of the original query are addressed
2052
+ 4. Provide a clear, comprehensive final answer
2053
+
2054
+ Be concise but thorough in your aggregation.`;
2055
+ function createSupervisorNode(config) {
2056
+ const {
2057
+ strategy,
2058
+ verbose = false,
2059
+ maxIterations = 10
2060
+ } = config;
2061
+ return async (state) => {
2062
+ try {
2063
+ if (verbose) {
2064
+ console.log(`[Supervisor] Routing iteration ${state.iteration}/${maxIterations}`);
2065
+ }
2066
+ if (state.iteration >= maxIterations) {
2067
+ if (verbose) {
2068
+ console.log("[Supervisor] Max iterations reached, moving to aggregation");
2069
+ }
2070
+ return {
2071
+ status: "aggregating",
2072
+ currentAgent: "aggregator"
2073
+ };
2074
+ }
2075
+ const allCompleted = state.activeAssignments.every(
2076
+ (assignment2) => state.completedTasks.some((task) => task.assignmentId === assignment2.id)
2077
+ );
2078
+ if (allCompleted && state.activeAssignments.length > 0) {
2079
+ if (verbose) {
2080
+ console.log("[Supervisor] All tasks completed, moving to aggregation");
2081
+ }
2082
+ return {
2083
+ status: "aggregating",
2084
+ currentAgent: "aggregator"
2085
+ };
2086
+ }
2087
+ const routingImpl = getRoutingStrategy(strategy);
2088
+ const decision = await routingImpl.route(state, config);
2089
+ if (verbose) {
2090
+ console.log(`[Supervisor] Routing to ${decision.targetAgent}: ${decision.reasoning}`);
2091
+ }
2092
+ const assignment = {
2093
+ id: `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
2094
+ workerId: decision.targetAgent,
2095
+ task: state.messages[state.messages.length - 1]?.content || state.input,
2096
+ priority: 5,
2097
+ assignedAt: Date.now()
2098
+ };
2099
+ const message = {
2100
+ id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
2101
+ from: "supervisor",
2102
+ to: [decision.targetAgent],
2103
+ type: "task_assignment",
2104
+ content: assignment.task,
2105
+ timestamp: Date.now(),
2106
+ metadata: {
2107
+ assignmentId: assignment.id,
2108
+ priority: assignment.priority
2109
+ }
2110
+ };
2111
+ return {
2112
+ currentAgent: decision.targetAgent,
2113
+ status: "executing",
2114
+ routingHistory: [decision],
2115
+ activeAssignments: [assignment],
2116
+ messages: [message],
2117
+ iteration: state.iteration + 1
2118
+ };
2119
+ } catch (error) {
2120
+ console.error("[Supervisor] Error:", error);
2121
+ return {
2122
+ status: "failed",
2123
+ error: error instanceof Error ? error.message : "Unknown error in supervisor"
2124
+ };
2125
+ }
2126
+ };
2127
+ }
2128
+ function createWorkerNode(config) {
2129
+ const {
2130
+ id,
2131
+ capabilities,
2132
+ llm,
2133
+ tools = [],
2134
+ systemPrompt,
2135
+ verbose = false,
2136
+ executeFn
2137
+ } = config;
2138
+ return async (state) => {
2139
+ try {
2140
+ if (verbose) {
2141
+ console.log(`[Worker:${id}] Executing task`);
2142
+ }
2143
+ const currentAssignment = state.activeAssignments.find(
2144
+ (assignment) => assignment.workerId === id && !state.completedTasks.some((task) => task.assignmentId === assignment.id)
2145
+ );
2146
+ if (!currentAssignment) {
2147
+ if (verbose) {
2148
+ console.log(`[Worker:${id}] No active assignment found`);
2149
+ }
2150
+ return {
2151
+ currentAgent: "supervisor",
2152
+ status: "routing"
2153
+ };
2154
+ }
2155
+ if (executeFn) {
2156
+ return await executeFn(state);
2157
+ }
2158
+ if (!llm) {
2159
+ throw new Error(`Worker ${id} requires either an LLM or custom execution function`);
2160
+ }
2161
+ const defaultSystemPrompt = `You are a specialized worker agent with the following capabilities:
2162
+ Skills: ${capabilities.skills.join(", ")}
2163
+ Tools: ${capabilities.tools.join(", ")}
2164
+
2165
+ Execute the assigned task using your skills and tools. Provide a clear, actionable result.`;
2166
+ const messages = [
2167
+ new import_messages5.SystemMessage(systemPrompt || defaultSystemPrompt),
2168
+ new import_messages5.HumanMessage(currentAssignment.task)
2169
+ ];
2170
+ let llmToUse = llm;
2171
+ if (tools.length > 0 && llm.bindTools) {
2172
+ const langchainTools = (0, import_core7.toLangChainTools)(tools);
2173
+ llmToUse = llm.bindTools(langchainTools);
2174
+ }
2175
+ const response = await llmToUse.invoke(messages);
2176
+ const result = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
2177
+ if (verbose) {
2178
+ console.log(`[Worker:${id}] Task completed:`, result.substring(0, 100) + "...");
2179
+ }
2180
+ const taskResult = {
2181
+ assignmentId: currentAssignment.id,
2182
+ workerId: id,
2183
+ success: true,
2184
+ result,
2185
+ completedAt: Date.now(),
2186
+ metadata: {
2187
+ skills_used: capabilities.skills
2188
+ }
2189
+ };
2190
+ const message = {
2191
+ id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
2192
+ from: id,
2193
+ to: ["supervisor"],
2194
+ type: "task_result",
2195
+ content: result,
2196
+ timestamp: Date.now(),
2197
+ metadata: {
2198
+ assignmentId: currentAssignment.id,
2199
+ success: true
2200
+ }
2201
+ };
2202
+ const updatedWorkers = {
2203
+ ...state.workers,
2204
+ [id]: {
2205
+ ...capabilities,
2206
+ currentWorkload: Math.max(0, capabilities.currentWorkload - 1)
2207
+ }
2208
+ };
2209
+ return {
2210
+ completedTasks: [taskResult],
2211
+ messages: [message],
2212
+ workers: updatedWorkers,
2213
+ currentAgent: "supervisor",
2214
+ status: "routing"
2215
+ };
2216
+ } catch (error) {
2217
+ console.error(`[Worker:${id}] Error:`, error);
2218
+ const currentAssignment = state.activeAssignments.find(
2219
+ (assignment) => assignment.workerId === id
2220
+ );
2221
+ if (currentAssignment) {
2222
+ const errorResult = {
2223
+ assignmentId: currentAssignment.id,
2224
+ workerId: id,
2225
+ success: false,
2226
+ result: "",
2227
+ error: error instanceof Error ? error.message : "Unknown error",
2228
+ completedAt: Date.now()
2229
+ };
2230
+ return {
2231
+ completedTasks: [errorResult],
2232
+ currentAgent: "supervisor",
2233
+ status: "routing"
2234
+ };
2235
+ }
2236
+ return {
2237
+ status: "failed",
2238
+ error: error instanceof Error ? error.message : `Unknown error in worker ${id}`
2239
+ };
2240
+ }
2241
+ };
2242
+ }
2243
+ function createAggregatorNode(config = {}) {
2244
+ const {
2245
+ llm,
2246
+ systemPrompt = DEFAULT_AGGREGATOR_SYSTEM_PROMPT,
2247
+ aggregateFn,
2248
+ verbose = false
2249
+ } = config;
2250
+ return async (state) => {
2251
+ try {
2252
+ if (verbose) {
2253
+ console.log("[Aggregator] Combining results from workers");
2254
+ }
2255
+ if (aggregateFn) {
2256
+ const response2 = await aggregateFn(state);
2257
+ return {
2258
+ response: response2,
2259
+ status: "completed"
2260
+ };
2261
+ }
2262
+ if (state.completedTasks.length === 0) {
2263
+ return {
2264
+ response: "No tasks were completed.",
2265
+ status: "completed"
2266
+ };
2267
+ }
2268
+ if (!llm) {
2269
+ const combinedResults = state.completedTasks.filter((task) => task.success).map((task) => task.result).join("\n\n");
2270
+ return {
2271
+ response: combinedResults || "No successful results to aggregate.",
2272
+ status: "completed"
2273
+ };
2274
+ }
2275
+ const taskResults = state.completedTasks.map((task, idx) => {
2276
+ const status = task.success ? "\u2713" : "\u2717";
2277
+ const result = task.success ? task.result : `Error: ${task.error}`;
2278
+ return `${idx + 1}. [${status}] Worker ${task.workerId}:
2279
+ ${result}`;
2280
+ }).join("\n\n");
2281
+ const userPrompt = `Original query: ${state.input}
2282
+
2283
+ Worker results:
2284
+ ${taskResults}
2285
+
2286
+ Please synthesize these results into a comprehensive response that addresses the original query.`;
2287
+ const messages = [
2288
+ new import_messages5.SystemMessage(systemPrompt),
2289
+ new import_messages5.HumanMessage(userPrompt)
2290
+ ];
2291
+ const response = await llm.invoke(messages);
2292
+ const aggregatedResponse = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
2293
+ if (verbose) {
2294
+ console.log("[Aggregator] Aggregation complete");
2295
+ }
2296
+ return {
2297
+ response: aggregatedResponse,
2298
+ status: "completed"
2299
+ };
2300
+ } catch (error) {
2301
+ console.error("[Aggregator] Error:", error);
2302
+ return {
2303
+ status: "failed",
2304
+ error: error instanceof Error ? error.message : "Unknown error in aggregator"
2305
+ };
2306
+ }
2307
+ };
2308
+ }
2309
+
2310
+ // src/multi-agent/agent.ts
2311
+ var import_langgraph4 = require("@langchain/langgraph");
2312
+ function createMultiAgentSystem(config) {
2313
+ const {
2314
+ supervisor,
2315
+ workers,
2316
+ aggregator,
2317
+ maxIterations = 10,
2318
+ verbose = false
2319
+ } = config;
2320
+ const workflow = new import_langgraph4.StateGraph(MultiAgentState);
2321
+ const supervisorNode = createSupervisorNode({
2322
+ ...supervisor,
2323
+ maxIterations,
2324
+ verbose
2325
+ });
2326
+ workflow.addNode("supervisor", supervisorNode);
2327
+ const workerIds = [];
2328
+ const workerCapabilities = {};
2329
+ for (const workerConfig of workers) {
2330
+ const workerNode = createWorkerNode({
2331
+ ...workerConfig,
2332
+ verbose
2333
+ });
2334
+ workflow.addNode(workerConfig.id, workerNode);
2335
+ workerIds.push(workerConfig.id);
2336
+ workerCapabilities[workerConfig.id] = workerConfig.capabilities;
2337
+ }
2338
+ const aggregatorNode = createAggregatorNode({
2339
+ ...aggregator,
2340
+ verbose
2341
+ });
2342
+ workflow.addNode("aggregator", aggregatorNode);
2343
+ const supervisorRouter = (state) => {
2344
+ if (state.status === "completed" || state.status === "failed") {
2345
+ return import_langgraph4.END;
2346
+ }
2347
+ if (state.status === "aggregating") {
2348
+ return "aggregator";
2349
+ }
2350
+ if (state.currentAgent && state.currentAgent !== "supervisor") {
2351
+ return state.currentAgent;
2352
+ }
2353
+ return "supervisor";
2354
+ };
2355
+ const workerRouter = (state) => {
2356
+ return "supervisor";
2357
+ };
2358
+ const aggregatorRouter = (state) => {
2359
+ return import_langgraph4.END;
2360
+ };
2361
+ workflow.setEntryPoint("supervisor");
2362
+ workflow.addConditionalEdges("supervisor", supervisorRouter, [
2363
+ "aggregator",
2364
+ import_langgraph4.END,
2365
+ ...workerIds
2366
+ ]);
2367
+ for (const workerId of workerIds) {
2368
+ workflow.addConditionalEdges(workerId, workerRouter, ["supervisor"]);
2369
+ }
2370
+ workflow.addConditionalEdges("aggregator", aggregatorRouter, [import_langgraph4.END]);
2371
+ const compiled = workflow.compile();
2372
+ const originalInvoke = compiled.invoke.bind(compiled);
2373
+ compiled.invoke = async function(input, config2) {
2374
+ const mergedInput = {
2375
+ ...input,
2376
+ workers: {
2377
+ ...workerCapabilities,
2378
+ ...input.workers || {}
2379
+ }
2380
+ };
2381
+ return originalInvoke(mergedInput, config2);
2382
+ };
2383
+ return compiled;
2384
+ }
2385
+ var MultiAgentSystemBuilder = class {
2386
+ config;
2387
+ additionalWorkers = [];
2388
+ compiled = false;
2389
+ constructor(config) {
2390
+ this.config = {
2391
+ ...config,
2392
+ workers: config.workers || []
2393
+ };
2394
+ }
2395
+ /**
2396
+ * Register workers with the system builder
2397
+ *
2398
+ * @param workers - Array of worker configurations
2399
+ * @returns this builder for chaining
2400
+ *
2401
+ * @example
2402
+ * ```typescript
2403
+ * const builder = new MultiAgentSystemBuilder({
2404
+ * supervisor: { llm, strategy: 'skill-based' },
2405
+ * aggregator: { llm },
2406
+ * });
2407
+ *
2408
+ * builder.registerWorkers([
2409
+ * {
2410
+ * name: 'math_worker',
2411
+ * capabilities: ['math', 'calculations'],
2412
+ * tools: [calculatorTool],
2413
+ * },
2414
+ * ]);
2415
+ *
2416
+ * const system = builder.build();
2417
+ * ```
2418
+ */
2419
+ registerWorkers(workers) {
2420
+ if (this.compiled) {
2421
+ throw new Error("Cannot register workers after the system has been compiled");
2422
+ }
2423
+ for (const worker of workers) {
2424
+ this.additionalWorkers.push({
2425
+ id: worker.name,
2426
+ capabilities: {
2427
+ skills: worker.capabilities,
2428
+ tools: worker.tools?.map((t) => t.name || "unknown") || [],
2429
+ available: true,
2430
+ currentWorkload: 0
2431
+ },
2432
+ llm: worker.llm || this.config.supervisor.llm,
2433
+ tools: worker.tools,
2434
+ systemPrompt: worker.systemPrompt
2435
+ });
2436
+ }
2437
+ return this;
2438
+ }
2439
+ /**
2440
+ * Build and compile the multi-agent system
2441
+ *
2442
+ * @returns Compiled LangGraph workflow
2443
+ */
2444
+ build() {
2445
+ if (this.compiled) {
2446
+ throw new Error("System has already been compiled");
2447
+ }
2448
+ const allWorkers = [...this.config.workers, ...this.additionalWorkers];
2449
+ if (allWorkers.length === 0) {
2450
+ throw new Error("At least one worker must be registered before building the system");
2451
+ }
2452
+ this.compiled = true;
2453
+ return createMultiAgentSystem({
2454
+ ...this.config,
2455
+ workers: allWorkers
2456
+ });
2457
+ }
2458
+ };
2459
+ function registerWorkers(system, workers) {
2460
+ console.warn(
2461
+ "[AgentForge] registerWorkers() on a compiled system only updates worker capabilities in state.\nIt does NOT add worker nodes to the graph. Use MultiAgentSystemBuilder for proper worker registration.\nSee: https://github.com/agentforge/agentforge/blob/main/packages/patterns/docs/multi-agent-pattern.md"
2462
+ );
2463
+ if (!system._workerRegistry) {
2464
+ system._workerRegistry = {};
2465
+ }
2466
+ for (const worker of workers) {
2467
+ system._workerRegistry[worker.name] = {
2468
+ skills: worker.capabilities,
2469
+ tools: worker.tools?.map((t) => t.name || "unknown") || [],
2470
+ available: true,
2471
+ currentWorkload: 0
2472
+ };
2473
+ }
2474
+ if (!system._originalInvoke) {
2475
+ system._originalInvoke = system.invoke.bind(system);
2476
+ system.invoke = async function(input, config) {
2477
+ const mergedInput = {
2478
+ ...input,
2479
+ workers: {
2480
+ ...system._workerRegistry || {},
2481
+ ...input.workers || {}
2482
+ }
2483
+ };
2484
+ return system._originalInvoke(mergedInput, config);
2485
+ };
2486
+ }
2487
+ }
2488
+ // Annotate the CommonJS export names for ESM import in node:
2489
+ 0 && (module.exports = {
2490
+ AgentMessageSchema,
2491
+ AgentRoleSchema,
2492
+ CompletedStepSchema,
2493
+ DEFAULT_AGGREGATOR_SYSTEM_PROMPT,
2494
+ DEFAULT_GENERATOR_SYSTEM_PROMPT,
2495
+ DEFAULT_PLANNER_SYSTEM_PROMPT,
2496
+ DEFAULT_REACT_SYSTEM_PROMPT,
2497
+ DEFAULT_REFLECTOR_SYSTEM_PROMPT,
2498
+ DEFAULT_REPLANNER_SYSTEM_PROMPT,
2499
+ DEFAULT_REVISER_SYSTEM_PROMPT,
2500
+ DEFAULT_SUPERVISOR_SYSTEM_PROMPT,
2501
+ ExecutionStatusSchema,
2502
+ GENERATION_PROMPT_TEMPLATE,
2503
+ HandoffRequestSchema,
2504
+ MessageSchema,
2505
+ MessageTypeSchema,
2506
+ MultiAgentState,
2507
+ MultiAgentStateConfig,
2508
+ MultiAgentStatusSchema,
2509
+ MultiAgentSystemBuilder,
2510
+ PLANNING_PROMPT_TEMPLATE,
2511
+ PlanExecuteState,
2512
+ PlanExecuteStateConfig,
2513
+ PlanSchema,
2514
+ PlanStepSchema,
2515
+ QUALITY_CRITERIA_TEMPLATE,
2516
+ QualityCriteriaSchema,
2517
+ REFLECTION_ENTRY_TEMPLATE,
2518
+ REFLECTION_HISTORY_TEMPLATE,
2519
+ REFLECTION_PROMPT_TEMPLATE,
2520
+ REPLANNING_PROMPT_TEMPLATE,
2521
+ REVISION_ENTRY_TEMPLATE,
2522
+ REVISION_PROMPT_TEMPLATE,
2523
+ ReActAgentBuilder,
2524
+ ReActState,
2525
+ ReflectionConfigSchema,
2526
+ ReflectionSchema,
2527
+ ReflectionState,
2528
+ ReflectionStateConfig,
2529
+ ReflectionStatusSchema,
2530
+ ReplanDecisionSchema,
2531
+ RevisionSchema,
2532
+ RoutingDecisionSchema,
2533
+ RoutingStrategySchema,
2534
+ ScratchpadEntrySchema,
2535
+ TaskAssignmentSchema,
2536
+ TaskResultSchema,
2537
+ ThoughtSchema,
2538
+ ToolCallSchema,
2539
+ ToolResultSchema,
2540
+ WorkerCapabilitiesSchema,
2541
+ createAggregatorNode,
2542
+ createExecutorNode,
2543
+ createFinisherNode,
2544
+ createGeneratorNode,
2545
+ createMultiAgentSystem,
2546
+ createPlanExecuteAgent,
2547
+ createPlannerNode,
2548
+ createReActAgent,
2549
+ createReActAgentBuilder,
2550
+ createReflectionAgent,
2551
+ createReflectionFinisherNode,
2552
+ createReflectorNode,
2553
+ createReplannerNode,
2554
+ createReviserNode,
2555
+ createSupervisorNode,
2556
+ createWorkerNode,
2557
+ getRoutingStrategy,
2558
+ llmBasedRouting,
2559
+ loadBalancedRouting,
2560
+ registerWorkers,
2561
+ roundRobinRouting,
2562
+ ruleBasedRouting,
2563
+ skillBasedRouting
2564
+ });