@agentforge/patterns 0.6.4 → 0.8.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.js CHANGED
@@ -35,15 +35,46 @@ var ScratchpadEntrySchema = z.object({
35
35
  });
36
36
 
37
37
  // src/react/state.ts
38
- import { z as z2 } from "zod";
38
+ import { z as z3 } from "zod";
39
39
  import { createStateAnnotation } from "@agentforge/core";
40
+
41
+ // src/shared/state-fields.ts
42
+ import { z as z2 } from "zod";
43
+ var iterationField = {
44
+ schema: z2.number().int().nonnegative(),
45
+ reducer: (left, right) => left + right,
46
+ default: () => 0,
47
+ description: "Current iteration number"
48
+ };
49
+ function maxIterationsField(defaultValue) {
50
+ return {
51
+ schema: z2.number().int().positive(),
52
+ default: () => defaultValue,
53
+ description: "Maximum number of iterations allowed"
54
+ };
55
+ }
56
+ var errorField = {
57
+ schema: z2.string().optional(),
58
+ description: "Error message if execution failed"
59
+ };
60
+ var responseField = {
61
+ schema: z2.string().optional(),
62
+ description: "Final response after completion"
63
+ };
64
+ var inputField = {
65
+ schema: z2.string(),
66
+ default: () => "",
67
+ description: "Original user input or query"
68
+ };
69
+
70
+ // src/react/state.ts
40
71
  var ReActStateConfig = {
41
72
  /**
42
73
  * Conversation messages
43
74
  * Accumulates all messages in the conversation
44
75
  */
45
76
  messages: {
46
- schema: z2.array(MessageSchema),
77
+ schema: z3.array(MessageSchema),
47
78
  reducer: (left, right) => [...left, ...right],
48
79
  default: () => [],
49
80
  description: "Conversation message history"
@@ -53,7 +84,7 @@ var ReActStateConfig = {
53
84
  * Accumulates all reasoning steps the agent takes
54
85
  */
55
86
  thoughts: {
56
- schema: z2.array(ThoughtSchema),
87
+ schema: z3.array(ThoughtSchema),
57
88
  reducer: (left, right) => [...left, ...right],
58
89
  default: () => [],
59
90
  description: "Agent reasoning steps"
@@ -63,7 +94,7 @@ var ReActStateConfig = {
63
94
  * Accumulates all tool calls made by the agent
64
95
  */
65
96
  actions: {
66
- schema: z2.array(ToolCallSchema),
97
+ schema: z3.array(ToolCallSchema),
67
98
  reducer: (left, right) => [...left, ...right],
68
99
  default: () => [],
69
100
  description: "Tool calls made by the agent"
@@ -73,7 +104,7 @@ var ReActStateConfig = {
73
104
  * Accumulates all observations from tool executions
74
105
  */
75
106
  observations: {
76
- schema: z2.array(ToolResultSchema),
107
+ schema: z3.array(ToolResultSchema),
77
108
  reducer: (left, right) => [...left, ...right],
78
109
  default: () => [],
79
110
  description: "Results from tool executions"
@@ -83,7 +114,7 @@ var ReActStateConfig = {
83
114
  * Accumulates step-by-step reasoning process
84
115
  */
85
116
  scratchpad: {
86
- schema: z2.array(ScratchpadEntrySchema),
117
+ schema: z3.array(ScratchpadEntrySchema),
87
118
  reducer: (left, right) => [...left, ...right],
88
119
  default: () => [],
89
120
  description: "Intermediate reasoning scratchpad"
@@ -92,27 +123,19 @@ var ReActStateConfig = {
92
123
  * Current iteration count
93
124
  * Tracks how many thought-action-observation loops have been executed
94
125
  */
95
- iteration: {
96
- schema: z2.number(),
97
- reducer: (left, right) => left + right,
98
- default: () => 0,
99
- description: "Current iteration count"
100
- },
126
+ iteration: iterationField,
101
127
  /**
102
128
  * Whether the agent should continue iterating
103
129
  */
104
130
  shouldContinue: {
105
- schema: z2.boolean().optional(),
131
+ schema: z3.boolean().optional(),
106
132
  default: () => true,
107
133
  description: "Whether to continue the ReAct loop"
108
134
  },
109
135
  /**
110
136
  * Final response (if any)
111
137
  */
112
- response: {
113
- schema: z2.string().optional(),
114
- description: "Final response from the agent"
115
- }
138
+ response: responseField
116
139
  };
117
140
  var ReActState = createStateAnnotation(ReActStateConfig);
118
141
 
@@ -157,8 +180,8 @@ function generateToolCallCacheKey(toolName, args) {
157
180
  return `${toolName}:${sortedArgs}`;
158
181
  }
159
182
  function createPatternLogger(name, defaultLevel = "info") {
160
- const logLevel5 = process.env.LOG_LEVEL?.toLowerCase() || defaultLevel;
161
- return createLogger(name, { level: logLevel5 });
183
+ const logLevel4 = process.env.LOG_LEVEL?.toLowerCase() || defaultLevel;
184
+ return createLogger(name, { level: logLevel4 });
162
185
  }
163
186
  function calculateDeduplicationSavings(duplicatesSkipped, toolsExecuted) {
164
187
  if (duplicatesSkipped === 0) {
@@ -176,6 +199,24 @@ function buildDeduplicationMetrics(toolsExecuted, duplicatesSkipped, totalObserv
176
199
  };
177
200
  }
178
201
 
202
+ // src/shared/error-handling.ts
203
+ function isGraphInterrupt(error) {
204
+ return error !== null && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt";
205
+ }
206
+ function handleNodeError(error, context, verbose = false) {
207
+ if (isGraphInterrupt(error)) {
208
+ throw error;
209
+ }
210
+ const errorMessage = error instanceof Error ? error.message : String(error);
211
+ if (verbose) {
212
+ console.error(`[${context}] Error:`, errorMessage);
213
+ if (error instanceof Error && error.stack) {
214
+ console.error(`[${context}] Stack:`, error.stack);
215
+ }
216
+ }
217
+ return errorMessage;
218
+ }
219
+
179
220
  // src/react/nodes.ts
180
221
  var reasoningLogger = createPatternLogger("agentforge:patterns:react:reasoning");
181
222
  var actionLogger = createPatternLogger("agentforge:patterns:react:action");
@@ -338,10 +379,7 @@ function createActionNode(tools, verbose = false, enableDeduplication = true) {
338
379
  executionCache.set(cacheKey, observation);
339
380
  }
340
381
  } catch (error) {
341
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
342
- throw error;
343
- }
344
- const errorMessage = error instanceof Error ? error.message : String(error);
382
+ const errorMessage = handleNodeError(error, `action:${action.name}`, false);
345
383
  actionLogger.error("Tool execution failed", {
346
384
  toolName: action.name,
347
385
  error: errorMessage,
@@ -580,34 +618,34 @@ function createReActAgentBuilder() {
580
618
  import { StateGraph as StateGraph2, END as END2 } from "@langchain/langgraph";
581
619
 
582
620
  // src/plan-execute/state.ts
583
- import { z as z4 } from "zod";
621
+ import { z as z5 } from "zod";
584
622
  import { createStateAnnotation as createStateAnnotation2 } from "@agentforge/core";
585
623
 
586
624
  // src/plan-execute/schemas.ts
587
- import { z as z3 } from "zod";
588
- var PlanStepSchema = z3.object({
625
+ import { z as z4 } from "zod";
626
+ var PlanStepSchema = z4.object({
589
627
  /**
590
628
  * Unique identifier for the step
591
629
  */
592
- id: z3.string().describe("Unique identifier for the step"),
630
+ id: z4.string().describe("Unique identifier for the step"),
593
631
  /**
594
632
  * Description of what this step should accomplish
595
633
  */
596
- description: z3.string().describe("Description of what this step should accomplish"),
634
+ description: z4.string().describe("Description of what this step should accomplish"),
597
635
  /**
598
636
  * Optional dependencies on other steps (by ID)
599
637
  */
600
- dependencies: z3.array(z3.string()).optional().describe("IDs of steps that must complete before this one"),
638
+ dependencies: z4.array(z4.string()).optional().describe("IDs of steps that must complete before this one"),
601
639
  /**
602
640
  * Optional tool to use for this step
603
641
  */
604
- tool: z3.string().optional().describe("Name of the tool to use for this step"),
642
+ tool: z4.string().optional().describe("Name of the tool to use for this step"),
605
643
  /**
606
644
  * Optional arguments for the tool
607
645
  */
608
- args: z3.record(z3.any()).optional().describe("Arguments to pass to the tool")
646
+ args: z4.record(z4.any()).optional().describe("Arguments to pass to the tool")
609
647
  });
610
- var CompletedStepSchema = z3.object({
648
+ var CompletedStepSchema = z4.object({
611
649
  /**
612
650
  * The step that was executed
613
651
  */
@@ -615,53 +653,53 @@ var CompletedStepSchema = z3.object({
615
653
  /**
616
654
  * The result of executing the step
617
655
  */
618
- result: z3.any().describe("The result of executing the step"),
656
+ result: z4.any().describe("The result of executing the step"),
619
657
  /**
620
658
  * Whether the step succeeded
621
659
  */
622
- success: z3.boolean().describe("Whether the step succeeded"),
660
+ success: z4.boolean().describe("Whether the step succeeded"),
623
661
  /**
624
662
  * Optional error message if the step failed
625
663
  */
626
- error: z3.string().optional().describe("Error message if the step failed"),
664
+ error: z4.string().optional().describe("Error message if the step failed"),
627
665
  /**
628
666
  * Timestamp when the step was completed
629
667
  */
630
- timestamp: z3.string().datetime().describe("ISO timestamp when the step was completed")
668
+ timestamp: z4.string().datetime().describe("ISO timestamp when the step was completed")
631
669
  });
632
- var PlanSchema = z3.object({
670
+ var PlanSchema = z4.object({
633
671
  /**
634
672
  * List of steps in the plan
635
673
  */
636
- steps: z3.array(PlanStepSchema).describe("List of steps in the plan"),
674
+ steps: z4.array(PlanStepSchema).describe("List of steps in the plan"),
637
675
  /**
638
676
  * Overall goal of the plan
639
677
  */
640
- goal: z3.string().describe("Overall goal of the plan"),
678
+ goal: z4.string().describe("Overall goal of the plan"),
641
679
  /**
642
680
  * Timestamp when the plan was created
643
681
  */
644
- createdAt: z3.string().datetime().describe("ISO timestamp when the plan was created"),
682
+ createdAt: z4.string().datetime().describe("ISO timestamp when the plan was created"),
645
683
  /**
646
684
  * Optional confidence score (0-1)
647
685
  */
648
- confidence: z3.number().min(0).max(1).optional().describe("Confidence score for the plan (0-1)")
686
+ confidence: z4.number().min(0).max(1).optional().describe("Confidence score for the plan (0-1)")
649
687
  });
650
- var ReplanDecisionSchema = z3.object({
688
+ var ReplanDecisionSchema = z4.object({
651
689
  /**
652
690
  * Whether to replan
653
691
  */
654
- shouldReplan: z3.boolean().describe("Whether to replan based on current results"),
692
+ shouldReplan: z4.boolean().describe("Whether to replan based on current results"),
655
693
  /**
656
694
  * Reason for the decision
657
695
  */
658
- reason: z3.string().describe("Reason for the replan decision"),
696
+ reason: z4.string().describe("Reason for the replan decision"),
659
697
  /**
660
698
  * Optional new goal if replanning
661
699
  */
662
- newGoal: z3.string().optional().describe("Updated goal if replanning")
700
+ newGoal: z4.string().optional().describe("Updated goal if replanning")
663
701
  });
664
- var ExecutionStatusSchema = z3.enum([
702
+ var ExecutionStatusSchema = z4.enum([
665
703
  "planning",
666
704
  "executing",
667
705
  "replanning",
@@ -674,11 +712,7 @@ var PlanExecuteStateConfig = {
674
712
  /**
675
713
  * Original user input/query
676
714
  */
677
- input: {
678
- schema: z4.string(),
679
- default: () => "",
680
- description: "Original user input or query"
681
- },
715
+ input: inputField,
682
716
  /**
683
717
  * The current plan
684
718
  */
@@ -691,7 +725,7 @@ var PlanExecuteStateConfig = {
691
725
  * Accumulates all completed steps
692
726
  */
693
727
  pastSteps: {
694
- schema: z4.array(CompletedStepSchema),
728
+ schema: z5.array(CompletedStepSchema),
695
729
  reducer: (left, right) => [...left, ...right],
696
730
  default: () => [],
697
731
  description: "Completed steps with their results"
@@ -700,7 +734,7 @@ var PlanExecuteStateConfig = {
700
734
  * Index of the current step being executed
701
735
  */
702
736
  currentStepIndex: {
703
- schema: z4.number().int().nonnegative().optional(),
737
+ schema: z5.number().int().nonnegative().optional(),
704
738
  description: "Index of the current step being executed"
705
739
  },
706
740
  /**
@@ -714,34 +748,19 @@ var PlanExecuteStateConfig = {
714
748
  /**
715
749
  * Final response
716
750
  */
717
- response: {
718
- schema: z4.string().optional(),
719
- description: "Final response after plan execution"
720
- },
751
+ response: responseField,
721
752
  /**
722
753
  * Error message if execution failed
723
754
  */
724
- error: {
725
- schema: z4.string().optional(),
726
- description: "Error message if execution failed"
727
- },
755
+ error: errorField,
728
756
  /**
729
757
  * Iteration counter for replanning
730
758
  */
731
- iteration: {
732
- schema: z4.number().int().nonnegative(),
733
- reducer: (left, right) => left + right,
734
- default: () => 0,
735
- description: "Number of planning iterations"
736
- },
759
+ iteration: iterationField,
737
760
  /**
738
761
  * Maximum iterations allowed
739
762
  */
740
- maxIterations: {
741
- schema: z4.number().int().positive(),
742
- default: () => 5,
743
- description: "Maximum number of planning iterations allowed"
744
- }
763
+ maxIterations: maxIterationsField(5)
745
764
  };
746
765
  var PlanExecuteState = createStateAnnotation2(PlanExecuteStateConfig);
747
766
 
@@ -974,11 +993,8 @@ function createExecutorNode(config) {
974
993
  result = { message: "Step completed without tool execution" };
975
994
  }
976
995
  } catch (execError) {
977
- if (execError && typeof execError === "object" && "constructor" in execError && execError.constructor.name === "GraphInterrupt") {
978
- throw execError;
979
- }
996
+ error = handleNodeError(execError, `executor:${currentStep.description}`, false);
980
997
  success = false;
981
- error = execError instanceof Error ? execError.message : "Unknown execution error";
982
998
  result = null;
983
999
  executorLogger.warn("Step execution failed", {
984
1000
  stepId: currentStep.id,
@@ -1181,46 +1197,46 @@ function createPlanExecuteAgent(config) {
1181
1197
  }
1182
1198
 
1183
1199
  // src/reflection/state.ts
1184
- import { z as z6 } from "zod";
1200
+ import { z as z7 } from "zod";
1185
1201
  import { createStateAnnotation as createStateAnnotation3 } from "@agentforge/core";
1186
1202
 
1187
1203
  // src/reflection/schemas.ts
1188
- import { z as z5 } from "zod";
1189
- var ReflectionSchema = z5.object({
1204
+ import { z as z6 } from "zod";
1205
+ var ReflectionSchema = z6.object({
1190
1206
  /**
1191
1207
  * The critique or feedback on the current response
1192
1208
  */
1193
- critique: z5.string().describe("Critique or feedback on the current response"),
1209
+ critique: z6.string().describe("Critique or feedback on the current response"),
1194
1210
  /**
1195
1211
  * Specific issues identified
1196
1212
  */
1197
- issues: z5.array(z5.string()).describe("Specific issues or problems identified"),
1213
+ issues: z6.array(z6.string()).describe("Specific issues or problems identified"),
1198
1214
  /**
1199
1215
  * Suggestions for improvement
1200
1216
  */
1201
- suggestions: z5.array(z5.string()).describe("Suggestions for improving the response"),
1217
+ suggestions: z6.array(z6.string()).describe("Suggestions for improving the response"),
1202
1218
  /**
1203
1219
  * Quality score (0-10)
1204
1220
  */
1205
- score: z5.number().min(0).max(10).optional().describe("Quality score from 0 to 10"),
1221
+ score: z6.number().min(0).max(10).optional().describe("Quality score from 0 to 10"),
1206
1222
  /**
1207
1223
  * Whether the response meets quality standards
1208
1224
  */
1209
- meetsStandards: z5.boolean().describe("Whether the response meets quality standards"),
1225
+ meetsStandards: z6.boolean().describe("Whether the response meets quality standards"),
1210
1226
  /**
1211
1227
  * Timestamp of the reflection
1212
1228
  */
1213
- timestamp: z5.date().optional().describe("When this reflection was created")
1229
+ timestamp: z6.date().optional().describe("When this reflection was created")
1214
1230
  });
1215
- var RevisionSchema = z5.object({
1231
+ var RevisionSchema = z6.object({
1216
1232
  /**
1217
1233
  * The revised content
1218
1234
  */
1219
- content: z5.string().describe("The revised content"),
1235
+ content: z6.string().describe("The revised content"),
1220
1236
  /**
1221
1237
  * Which iteration this revision is from
1222
1238
  */
1223
- iteration: z5.number().int().nonnegative().describe("Iteration number"),
1239
+ iteration: z6.number().int().nonnegative().describe("Iteration number"),
1224
1240
  /**
1225
1241
  * The reflection that prompted this revision
1226
1242
  */
@@ -1228,9 +1244,9 @@ var RevisionSchema = z5.object({
1228
1244
  /**
1229
1245
  * Timestamp of the revision
1230
1246
  */
1231
- timestamp: z5.date().optional().describe("When this revision was created")
1247
+ timestamp: z6.date().optional().describe("When this revision was created")
1232
1248
  });
1233
- var ReflectionStatusSchema = z5.enum([
1249
+ var ReflectionStatusSchema = z6.enum([
1234
1250
  "generating",
1235
1251
  // Initial generation
1236
1252
  "reflecting",
@@ -1242,25 +1258,25 @@ var ReflectionStatusSchema = z5.enum([
1242
1258
  "failed"
1243
1259
  // Max iterations reached without meeting standards
1244
1260
  ]);
1245
- var QualityCriteriaSchema = z5.object({
1261
+ var QualityCriteriaSchema = z6.object({
1246
1262
  /**
1247
1263
  * Minimum quality score required (0-10)
1248
1264
  */
1249
- minScore: z5.number().min(0).max(10).default(7).describe("Minimum quality score required"),
1265
+ minScore: z6.number().min(0).max(10).default(7).describe("Minimum quality score required"),
1250
1266
  /**
1251
1267
  * Specific criteria to evaluate
1252
1268
  */
1253
- criteria: z5.array(z5.string()).optional().describe("Specific criteria to evaluate"),
1269
+ criteria: z6.array(z6.string()).optional().describe("Specific criteria to evaluate"),
1254
1270
  /**
1255
1271
  * Whether all criteria must be met
1256
1272
  */
1257
- requireAll: z5.boolean().default(true).describe("Whether all criteria must be met")
1273
+ requireAll: z6.boolean().default(true).describe("Whether all criteria must be met")
1258
1274
  });
1259
- var ReflectionConfigSchema = z5.object({
1275
+ var ReflectionConfigSchema = z6.object({
1260
1276
  /**
1261
1277
  * Maximum number of reflection iterations
1262
1278
  */
1263
- maxIterations: z5.number().int().positive().default(3).describe("Maximum reflection iterations"),
1279
+ maxIterations: z6.number().int().positive().default(3).describe("Maximum reflection iterations"),
1264
1280
  /**
1265
1281
  * Quality criteria for completion
1266
1282
  */
@@ -1268,7 +1284,7 @@ var ReflectionConfigSchema = z5.object({
1268
1284
  /**
1269
1285
  * Whether to include previous reflections in context
1270
1286
  */
1271
- includeHistory: z5.boolean().default(true).describe("Include previous reflections in context")
1287
+ includeHistory: z6.boolean().default(true).describe("Include previous reflections in context")
1272
1288
  });
1273
1289
 
1274
1290
  // src/reflection/state.ts
@@ -1276,16 +1292,12 @@ var ReflectionStateConfig = {
1276
1292
  /**
1277
1293
  * Original user input/task
1278
1294
  */
1279
- input: {
1280
- schema: z6.string(),
1281
- default: () => "",
1282
- description: "Original user input or task"
1283
- },
1295
+ input: inputField,
1284
1296
  /**
1285
1297
  * Current response/output
1286
1298
  */
1287
1299
  currentResponse: {
1288
- schema: z6.string().optional(),
1300
+ schema: z7.string().optional(),
1289
1301
  description: "Current response or output"
1290
1302
  },
1291
1303
  /**
@@ -1293,7 +1305,7 @@ var ReflectionStateConfig = {
1293
1305
  * Accumulates all reflections
1294
1306
  */
1295
1307
  reflections: {
1296
- schema: z6.array(ReflectionSchema),
1308
+ schema: z7.array(ReflectionSchema),
1297
1309
  reducer: (left, right) => [...left, ...right],
1298
1310
  default: () => [],
1299
1311
  description: "History of all reflections and critiques"
@@ -1303,7 +1315,7 @@ var ReflectionStateConfig = {
1303
1315
  * Accumulates all revisions
1304
1316
  */
1305
1317
  revisions: {
1306
- schema: z6.array(RevisionSchema),
1318
+ schema: z7.array(RevisionSchema),
1307
1319
  reducer: (left, right) => [...left, ...right],
1308
1320
  default: () => [],
1309
1321
  description: "History of all revisions"
@@ -1311,12 +1323,7 @@ var ReflectionStateConfig = {
1311
1323
  /**
1312
1324
  * Current iteration number
1313
1325
  */
1314
- iteration: {
1315
- schema: z6.number().int().nonnegative(),
1316
- reducer: (left, right) => left + right,
1317
- default: () => 0,
1318
- description: "Current iteration number"
1319
- },
1326
+ iteration: iterationField,
1320
1327
  /**
1321
1328
  * Current status
1322
1329
  */
@@ -1335,25 +1342,15 @@ var ReflectionStateConfig = {
1335
1342
  /**
1336
1343
  * Maximum iterations allowed
1337
1344
  */
1338
- maxIterations: {
1339
- schema: z6.number().int().positive(),
1340
- default: () => 3,
1341
- description: "Maximum number of reflection iterations allowed"
1342
- },
1345
+ maxIterations: maxIterationsField(3),
1343
1346
  /**
1344
1347
  * Final response (when completed)
1345
1348
  */
1346
- response: {
1347
- schema: z6.string().optional(),
1348
- description: "Final response after reflection process"
1349
- },
1349
+ response: responseField,
1350
1350
  /**
1351
1351
  * Error message if failed
1352
1352
  */
1353
- error: {
1354
- schema: z6.string().optional(),
1355
- description: "Error message if reflection failed"
1356
- }
1353
+ error: errorField
1357
1354
  };
1358
1355
  var ReflectionState = createStateAnnotation3(ReflectionStateConfig);
1359
1356
 
@@ -1502,14 +1499,15 @@ ${lastReflection.critique}`;
1502
1499
  iteration: 1
1503
1500
  };
1504
1501
  } catch (error) {
1502
+ const errorMessage = handleNodeError(error, "generator", false);
1505
1503
  generatorLogger.error("Response generation failed", {
1506
1504
  attempt: state.iteration + 1,
1507
- error: error instanceof Error ? error.message : String(error),
1505
+ error: errorMessage,
1508
1506
  duration: Date.now() - startTime
1509
1507
  });
1510
1508
  return {
1511
1509
  status: "failed",
1512
- error: error instanceof Error ? error.message : "Unknown error in generator"
1510
+ error: errorMessage
1513
1511
  };
1514
1512
  }
1515
1513
  };
@@ -1591,14 +1589,15 @@ function createReflectorNode(config) {
1591
1589
  status: reflection.meetsStandards ? "completed" : "revising"
1592
1590
  };
1593
1591
  } catch (error) {
1592
+ const errorMessage = handleNodeError(error, "reflector", false);
1594
1593
  reflectorLogger.error("Reflection failed", {
1595
1594
  attempt: state.iteration,
1596
- error: error instanceof Error ? error.message : String(error),
1595
+ error: errorMessage,
1597
1596
  duration: Date.now() - startTime
1598
1597
  });
1599
1598
  return {
1600
1599
  status: "failed",
1601
- error: error instanceof Error ? error.message : "Unknown error in reflector"
1600
+ error: errorMessage
1602
1601
  };
1603
1602
  }
1604
1603
  };
@@ -1659,14 +1658,15 @@ ${revisionsText}`;
1659
1658
  iteration: 1
1660
1659
  };
1661
1660
  } catch (error) {
1661
+ const errorMessage = handleNodeError(error, "reviser", false);
1662
1662
  reviserLogger.error("Revision failed", {
1663
1663
  attempt: state.iteration,
1664
- error: error instanceof Error ? error.message : String(error),
1664
+ error: errorMessage,
1665
1665
  duration: Date.now() - startTime
1666
1666
  });
1667
1667
  return {
1668
1668
  status: "failed",
1669
- error: error instanceof Error ? error.message : "Unknown error in reviser"
1669
+ error: errorMessage
1670
1670
  };
1671
1671
  }
1672
1672
  };
@@ -1752,13 +1752,13 @@ function createReflectionAgent(config) {
1752
1752
  }
1753
1753
 
1754
1754
  // src/multi-agent/state.ts
1755
- import { z as z8 } from "zod";
1755
+ import { z as z9 } from "zod";
1756
1756
  import { createStateAnnotation as createStateAnnotation4 } from "@agentforge/core";
1757
1757
 
1758
1758
  // src/multi-agent/schemas.ts
1759
- import { z as z7 } from "zod";
1760
- var AgentRoleSchema = z7.enum(["supervisor", "worker"]);
1761
- var MessageTypeSchema = z7.enum([
1759
+ import { z as z8 } from "zod";
1760
+ var AgentRoleSchema = z8.enum(["supervisor", "worker"]);
1761
+ var MessageTypeSchema = z8.enum([
1762
1762
  "user_input",
1763
1763
  // Initial user message
1764
1764
  "task_assignment",
@@ -1772,11 +1772,11 @@ var MessageTypeSchema = z7.enum([
1772
1772
  "completion"
1773
1773
  // Final completion message
1774
1774
  ]);
1775
- var AgentMessageSchema = z7.object({
1775
+ var AgentMessageSchema = z8.object({
1776
1776
  /**
1777
1777
  * Unique identifier for the message
1778
1778
  */
1779
- id: z7.string().describe("Unique message identifier"),
1779
+ id: z8.string().describe("Unique message identifier"),
1780
1780
  /**
1781
1781
  * Type of message
1782
1782
  */
@@ -1784,25 +1784,25 @@ var AgentMessageSchema = z7.object({
1784
1784
  /**
1785
1785
  * Agent that sent the message
1786
1786
  */
1787
- from: z7.string().describe("Agent identifier that sent the message"),
1787
+ from: z8.string().describe("Agent identifier that sent the message"),
1788
1788
  /**
1789
1789
  * Agent(s) that should receive the message
1790
1790
  */
1791
- to: z7.union([z7.string(), z7.array(z7.string())]).describe("Target agent(s)"),
1791
+ to: z8.union([z8.string(), z8.array(z8.string())]).describe("Target agent(s)"),
1792
1792
  /**
1793
1793
  * Message content
1794
1794
  */
1795
- content: z7.string().describe("Message content"),
1795
+ content: z8.string().describe("Message content"),
1796
1796
  /**
1797
1797
  * Optional metadata
1798
1798
  */
1799
- metadata: z7.record(z7.any()).optional().describe("Additional message metadata"),
1799
+ metadata: z8.record(z8.any()).optional().describe("Additional message metadata"),
1800
1800
  /**
1801
1801
  * Timestamp when message was created
1802
1802
  */
1803
- timestamp: z7.number().describe("Timestamp when message was created")
1803
+ timestamp: z8.number().describe("Timestamp when message was created")
1804
1804
  });
1805
- var RoutingStrategySchema = z7.enum([
1805
+ var RoutingStrategySchema = z8.enum([
1806
1806
  "llm-based",
1807
1807
  // LLM decides which agent to route to
1808
1808
  "rule-based",
@@ -1814,25 +1814,25 @@ var RoutingStrategySchema = z7.enum([
1814
1814
  "load-balanced"
1815
1815
  // Route based on agent workload
1816
1816
  ]);
1817
- var RoutingDecisionSchema = z7.object({
1817
+ var RoutingDecisionSchema = z8.object({
1818
1818
  /**
1819
1819
  * Target agent to route to (single agent routing)
1820
1820
  * @deprecated Use targetAgents for parallel routing support
1821
1821
  */
1822
- targetAgent: z7.string().nullable().default(null).describe("Agent to route the task to (single routing)"),
1822
+ targetAgent: z8.string().nullable().default(null).describe("Agent to route the task to (single routing)"),
1823
1823
  /**
1824
1824
  * Target agents to route to (parallel routing)
1825
1825
  * When multiple agents are specified, they execute in parallel
1826
1826
  */
1827
- targetAgents: z7.array(z7.string()).nullable().default(null).describe("Agents to route the task to (parallel routing)"),
1827
+ targetAgents: z8.array(z8.string()).nullable().default(null).describe("Agents to route the task to (parallel routing)"),
1828
1828
  /**
1829
1829
  * Reasoning for the routing decision
1830
1830
  */
1831
- reasoning: z7.string().default("").describe("Explanation for routing decision"),
1831
+ reasoning: z8.string().default("").describe("Explanation for routing decision"),
1832
1832
  /**
1833
1833
  * Confidence in the routing decision (0-1)
1834
1834
  */
1835
- confidence: z7.number().min(0).max(1).default(0.8).describe("Confidence score"),
1835
+ confidence: z8.number().min(0).max(1).default(0.8).describe("Confidence score"),
1836
1836
  /**
1837
1837
  * Strategy used for routing
1838
1838
  */
@@ -1840,86 +1840,86 @@ var RoutingDecisionSchema = z7.object({
1840
1840
  /**
1841
1841
  * Timestamp of the routing decision
1842
1842
  */
1843
- timestamp: z7.number().default(() => Date.now()).describe("Timestamp of the decision")
1843
+ timestamp: z8.number().default(() => Date.now()).describe("Timestamp of the decision")
1844
1844
  }).refine(
1845
1845
  (data) => data.targetAgent || data.targetAgents && data.targetAgents.length > 0,
1846
1846
  { message: "Either targetAgent or targetAgents must be provided" }
1847
1847
  );
1848
- var WorkerCapabilitiesSchema = z7.object({
1848
+ var WorkerCapabilitiesSchema = z8.object({
1849
1849
  /**
1850
1850
  * Skills/capabilities the agent has
1851
1851
  */
1852
- skills: z7.array(z7.string()).describe("List of agent skills"),
1852
+ skills: z8.array(z8.string()).describe("List of agent skills"),
1853
1853
  /**
1854
1854
  * Tools available to the agent
1855
1855
  */
1856
- tools: z7.array(z7.string()).describe("List of tool names available to agent"),
1856
+ tools: z8.array(z8.string()).describe("List of tool names available to agent"),
1857
1857
  /**
1858
1858
  * Whether the agent is currently available
1859
1859
  */
1860
- available: z7.boolean().default(true).describe("Whether agent is available"),
1860
+ available: z8.boolean().default(true).describe("Whether agent is available"),
1861
1861
  /**
1862
1862
  * Current workload (number of active tasks)
1863
1863
  */
1864
- currentWorkload: z7.number().int().nonnegative().default(0).describe("Current number of active tasks")
1864
+ currentWorkload: z8.number().int().nonnegative().default(0).describe("Current number of active tasks")
1865
1865
  });
1866
- var TaskAssignmentSchema = z7.object({
1866
+ var TaskAssignmentSchema = z8.object({
1867
1867
  /**
1868
1868
  * Unique assignment identifier
1869
1869
  */
1870
- id: z7.string().describe("Unique assignment identifier"),
1870
+ id: z8.string().describe("Unique assignment identifier"),
1871
1871
  /**
1872
1872
  * Worker ID assigned to the task
1873
1873
  */
1874
- workerId: z7.string().describe("Worker identifier assigned to task"),
1874
+ workerId: z8.string().describe("Worker identifier assigned to task"),
1875
1875
  /**
1876
1876
  * Task description
1877
1877
  */
1878
- task: z7.string().describe("Description of the task"),
1878
+ task: z8.string().describe("Description of the task"),
1879
1879
  /**
1880
1880
  * Task priority (1-10, higher is more urgent)
1881
1881
  */
1882
- priority: z7.number().int().min(1).max(10).default(5).describe("Task priority"),
1882
+ priority: z8.number().int().min(1).max(10).default(5).describe("Task priority"),
1883
1883
  /**
1884
1884
  * Timestamp when task was assigned
1885
1885
  */
1886
- assignedAt: z7.number().describe("Timestamp when task was assigned"),
1886
+ assignedAt: z8.number().describe("Timestamp when task was assigned"),
1887
1887
  /**
1888
1888
  * Optional deadline for task completion
1889
1889
  */
1890
- deadline: z7.number().optional().describe("Optional task deadline timestamp")
1890
+ deadline: z8.number().optional().describe("Optional task deadline timestamp")
1891
1891
  });
1892
- var TaskResultSchema = z7.object({
1892
+ var TaskResultSchema = z8.object({
1893
1893
  /**
1894
1894
  * Assignment identifier
1895
1895
  */
1896
- assignmentId: z7.string().describe("Assignment identifier"),
1896
+ assignmentId: z8.string().describe("Assignment identifier"),
1897
1897
  /**
1898
1898
  * Worker that completed the task
1899
1899
  */
1900
- workerId: z7.string().describe("Worker that completed the task"),
1900
+ workerId: z8.string().describe("Worker that completed the task"),
1901
1901
  /**
1902
1902
  * Whether the task succeeded
1903
1903
  */
1904
- success: z7.boolean().describe("Whether the task succeeded"),
1904
+ success: z8.boolean().describe("Whether the task succeeded"),
1905
1905
  /**
1906
1906
  * Task result/output
1907
1907
  */
1908
- result: z7.string().describe("Task result or output"),
1908
+ result: z8.string().describe("Task result or output"),
1909
1909
  /**
1910
1910
  * Optional error message if task failed
1911
1911
  */
1912
- error: z7.string().optional().describe("Error message if task failed"),
1912
+ error: z8.string().optional().describe("Error message if task failed"),
1913
1913
  /**
1914
1914
  * Timestamp when task was completed
1915
1915
  */
1916
- completedAt: z7.number().describe("Timestamp when task was completed"),
1916
+ completedAt: z8.number().describe("Timestamp when task was completed"),
1917
1917
  /**
1918
1918
  * Optional metadata about execution
1919
1919
  */
1920
- metadata: z7.record(z7.any()).optional().describe("Execution metadata")
1920
+ metadata: z8.record(z8.any()).optional().describe("Execution metadata")
1921
1921
  });
1922
- var MultiAgentStatusSchema = z7.enum([
1922
+ var MultiAgentStatusSchema = z8.enum([
1923
1923
  "initializing",
1924
1924
  // System is initializing
1925
1925
  "routing",
@@ -1935,27 +1935,27 @@ var MultiAgentStatusSchema = z7.enum([
1935
1935
  "failed"
1936
1936
  // Task failed
1937
1937
  ]);
1938
- var HandoffRequestSchema = z7.object({
1938
+ var HandoffRequestSchema = z8.object({
1939
1939
  /**
1940
1940
  * Agent requesting the handoff
1941
1941
  */
1942
- from: z7.string().describe("Agent requesting handoff"),
1942
+ from: z8.string().describe("Agent requesting handoff"),
1943
1943
  /**
1944
1944
  * Target agent for handoff
1945
1945
  */
1946
- to: z7.string().describe("Target agent for handoff"),
1946
+ to: z8.string().describe("Target agent for handoff"),
1947
1947
  /**
1948
1948
  * Reason for handoff
1949
1949
  */
1950
- reason: z7.string().describe("Reason for requesting handoff"),
1950
+ reason: z8.string().describe("Reason for requesting handoff"),
1951
1951
  /**
1952
1952
  * Context to pass to next agent
1953
1953
  */
1954
- context: z7.any().describe("Context to pass to next agent"),
1954
+ context: z8.any().describe("Context to pass to next agent"),
1955
1955
  /**
1956
1956
  * Timestamp of handoff request
1957
1957
  */
1958
- timestamp: z7.string().datetime().describe("ISO timestamp of handoff request")
1958
+ timestamp: z8.string().datetime().describe("ISO timestamp of handoff request")
1959
1959
  });
1960
1960
 
1961
1961
  // src/multi-agent/state.ts
@@ -1963,17 +1963,13 @@ var MultiAgentStateConfig = {
1963
1963
  /**
1964
1964
  * Original user input/query
1965
1965
  */
1966
- input: {
1967
- schema: z8.string(),
1968
- default: () => "",
1969
- description: "Original user input or query"
1970
- },
1966
+ input: inputField,
1971
1967
  /**
1972
1968
  * All messages in the multi-agent conversation
1973
1969
  * Accumulates all messages between agents
1974
1970
  */
1975
1971
  messages: {
1976
- schema: z8.array(AgentMessageSchema),
1972
+ schema: z9.array(AgentMessageSchema),
1977
1973
  reducer: (left, right) => [...left, ...right],
1978
1974
  default: () => [],
1979
1975
  description: "All messages in the multi-agent conversation"
@@ -1982,7 +1978,7 @@ var MultiAgentStateConfig = {
1982
1978
  * Available worker agents and their capabilities
1983
1979
  */
1984
1980
  workers: {
1985
- schema: z8.record(z8.string(), WorkerCapabilitiesSchema),
1981
+ schema: z9.record(z9.string(), WorkerCapabilitiesSchema),
1986
1982
  reducer: (left, right) => ({
1987
1983
  ...left,
1988
1984
  ...right
@@ -1994,7 +1990,7 @@ var MultiAgentStateConfig = {
1994
1990
  * Current active agent
1995
1991
  */
1996
1992
  currentAgent: {
1997
- schema: z8.string().optional(),
1993
+ schema: z9.string().optional(),
1998
1994
  description: "Identifier of the currently active agent"
1999
1995
  },
2000
1996
  /**
@@ -2002,7 +1998,7 @@ var MultiAgentStateConfig = {
2002
1998
  * Accumulates all routing decisions
2003
1999
  */
2004
2000
  routingHistory: {
2005
- schema: z8.array(RoutingDecisionSchema),
2001
+ schema: z9.array(RoutingDecisionSchema),
2006
2002
  reducer: (left, right) => [...left, ...right],
2007
2003
  default: () => [],
2008
2004
  description: "History of routing decisions"
@@ -2011,7 +2007,7 @@ var MultiAgentStateConfig = {
2011
2007
  * Active task assignments
2012
2008
  */
2013
2009
  activeAssignments: {
2014
- schema: z8.array(TaskAssignmentSchema),
2010
+ schema: z9.array(TaskAssignmentSchema),
2015
2011
  reducer: (left, right) => [...left, ...right],
2016
2012
  default: () => [],
2017
2013
  description: "Currently active task assignments"
@@ -2021,7 +2017,7 @@ var MultiAgentStateConfig = {
2021
2017
  * Accumulates all completed tasks
2022
2018
  */
2023
2019
  completedTasks: {
2024
- schema: z8.array(TaskResultSchema),
2020
+ schema: z9.array(TaskResultSchema),
2025
2021
  reducer: (left, right) => [...left, ...right],
2026
2022
  default: () => [],
2027
2023
  description: "Completed task results"
@@ -2031,7 +2027,7 @@ var MultiAgentStateConfig = {
2031
2027
  * Accumulates all handoff requests
2032
2028
  */
2033
2029
  handoffs: {
2034
- schema: z8.array(HandoffRequestSchema),
2030
+ schema: z9.array(HandoffRequestSchema),
2035
2031
  reducer: (left, right) => [...left, ...right],
2036
2032
  default: () => [],
2037
2033
  description: "Handoff requests between agents"
@@ -2047,99 +2043,24 @@ var MultiAgentStateConfig = {
2047
2043
  /**
2048
2044
  * Iteration counter
2049
2045
  */
2050
- iteration: {
2051
- schema: z8.number().int().nonnegative(),
2052
- reducer: (left, right) => left + right,
2053
- default: () => 0,
2054
- description: "Current iteration number"
2055
- },
2046
+ iteration: iterationField,
2056
2047
  /**
2057
2048
  * Maximum iterations allowed
2058
2049
  */
2059
- maxIterations: {
2060
- schema: z8.number().int().positive(),
2061
- default: () => 10,
2062
- description: "Maximum number of iterations allowed"
2063
- },
2050
+ maxIterations: maxIterationsField(10),
2064
2051
  /**
2065
2052
  * Final aggregated response
2066
2053
  */
2067
- response: {
2068
- schema: z8.string().optional(),
2069
- description: "Final aggregated response"
2070
- },
2054
+ response: responseField,
2071
2055
  /**
2072
2056
  * Error message if execution failed
2073
2057
  */
2074
- error: {
2075
- schema: z8.string().optional(),
2076
- description: "Error message if execution failed"
2077
- }
2058
+ error: errorField
2078
2059
  };
2079
2060
  var MultiAgentState = createStateAnnotation4(MultiAgentStateConfig);
2080
2061
 
2081
2062
  // src/multi-agent/routing.ts
2082
- import { HumanMessage as HumanMessage4, SystemMessage as SystemMessage4, AIMessage as AIMessage2, ToolMessage as ToolMessage2 } from "@langchain/core/messages";
2083
- import { createLogger as createLogger2, LogLevel } from "@agentforge/core";
2084
- var logLevel = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
2085
- var logger = createLogger2("multi-agent:routing", { level: logLevel });
2086
- async function executeTools(toolCalls, tools) {
2087
- const results = [];
2088
- logger.debug("Executing tools", {
2089
- toolCallCount: toolCalls.length,
2090
- toolNames: toolCalls.map((tc) => tc.name)
2091
- });
2092
- for (const toolCall of toolCalls) {
2093
- const tool = tools.find((t) => t.metadata.name === toolCall.name);
2094
- if (!tool) {
2095
- logger.warn("Tool not found", {
2096
- toolName: toolCall.name,
2097
- availableTools: tools.map((t) => t.metadata.name)
2098
- });
2099
- results.push(new ToolMessage2({
2100
- content: `Error: Tool '${toolCall.name}' not found`,
2101
- tool_call_id: toolCall.id
2102
- }));
2103
- continue;
2104
- }
2105
- try {
2106
- logger.debug("Executing tool", {
2107
- toolName: toolCall.name,
2108
- args: toolCall.args
2109
- });
2110
- const result = await tool.execute(toolCall.args);
2111
- const content = typeof result === "string" ? result : JSON.stringify(result);
2112
- logger.debug("Tool execution successful", {
2113
- toolName: toolCall.name,
2114
- resultLength: content.length
2115
- });
2116
- results.push(new ToolMessage2({
2117
- content,
2118
- tool_call_id: toolCall.id
2119
- }));
2120
- } catch (error) {
2121
- logger.error("Tool execution failed", {
2122
- toolName: toolCall.name,
2123
- error: error.message
2124
- });
2125
- results.push(new ToolMessage2({
2126
- content: `Error executing tool: ${error.message}`,
2127
- tool_call_id: toolCall.id
2128
- }));
2129
- }
2130
- }
2131
- logger.debug("Tool execution complete", {
2132
- successCount: results.filter((r) => {
2133
- const content = typeof r.content === "string" ? r.content : JSON.stringify(r.content);
2134
- return !content.startsWith("Error");
2135
- }).length,
2136
- errorCount: results.filter((r) => {
2137
- const content = typeof r.content === "string" ? r.content : JSON.stringify(r.content);
2138
- return content.startsWith("Error");
2139
- }).length
2140
- });
2141
- return results;
2142
- }
2063
+ import { HumanMessage as HumanMessage4, SystemMessage as SystemMessage4 } from "@langchain/core/messages";
2143
2064
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2144
2065
 
2145
2066
  Your job is to:
@@ -2175,151 +2096,48 @@ Choose parallel routing when the task benefits from multiple perspectives or dat
2175
2096
  var llmBasedRouting = {
2176
2097
  name: "llm-based",
2177
2098
  async route(state, config) {
2178
- logger.info("Starting LLM-based routing", {
2179
- iteration: state.iteration,
2180
- availableWorkers: Object.keys(state.workers).length
2181
- });
2182
2099
  if (!config.model) {
2183
2100
  throw new Error("LLM-based routing requires a model to be configured");
2184
2101
  }
2185
2102
  const systemPrompt = config.systemPrompt || DEFAULT_SUPERVISOR_SYSTEM_PROMPT;
2186
- const maxRetries = config.maxToolRetries || 3;
2187
- const tools = config.tools || [];
2188
2103
  const workerInfo = Object.entries(state.workers).map(([id, caps]) => {
2189
2104
  const skills = caps.skills.join(", ");
2190
- const tools2 = caps.tools.join(", ");
2105
+ const tools = caps.tools.join(", ");
2191
2106
  const available = caps.available ? "available" : "busy";
2192
- return `- ${id}: Skills: [${skills}], Tools: [${tools2}], Status: ${available}, Workload: ${caps.currentWorkload}`;
2107
+ return `- ${id}: Skills: [${skills}], Tools: [${tools}], Status: ${available}, Workload: ${caps.currentWorkload}`;
2193
2108
  }).join("\n");
2194
- logger.debug("Worker capabilities", {
2195
- workers: Object.entries(state.workers).map(([id, caps]) => ({
2196
- id,
2197
- skills: caps.skills,
2198
- available: caps.available,
2199
- workload: caps.currentWorkload
2200
- }))
2201
- });
2202
2109
  const lastMessage = state.messages[state.messages.length - 1];
2203
2110
  const taskContext = lastMessage?.content || state.input;
2204
- logger.debug("Task context", {
2205
- taskLength: taskContext.length,
2206
- taskPreview: taskContext.substring(0, 100)
2207
- });
2208
2111
  const userPrompt = `Current task: ${taskContext}
2209
2112
 
2210
2113
  Available workers:
2211
2114
  ${workerInfo}
2212
2115
 
2213
2116
  Select the best worker(s) for this task and explain your reasoning.`;
2214
- const conversationHistory = [];
2215
- let attempt = 0;
2216
- while (attempt < maxRetries) {
2217
- logger.debug("LLM routing attempt", {
2218
- attempt: attempt + 1,
2219
- maxRetries,
2220
- conversationHistoryLength: conversationHistory.length
2221
- });
2222
- const messages = [
2223
- new SystemMessage4(systemPrompt),
2224
- new HumanMessage4(userPrompt),
2225
- ...conversationHistory
2226
- ];
2227
- const response = await config.model.invoke(messages);
2228
- if (response.tool_calls && response.tool_calls.length > 0) {
2229
- logger.info("LLM requested tool calls", {
2230
- toolCount: response.tool_calls.length,
2231
- toolNames: response.tool_calls.map((tc) => tc.name)
2232
- });
2233
- if (tools.length === 0) {
2234
- throw new Error("LLM requested tool calls but no tools are configured");
2235
- }
2236
- const toolResults = await executeTools(response.tool_calls, tools);
2237
- conversationHistory.push(
2238
- new AIMessage2({ content: response.content || "", tool_calls: response.tool_calls }),
2239
- ...toolResults
2240
- );
2241
- attempt++;
2242
- logger.debug("Retrying routing with tool results", { attempt });
2243
- continue;
2244
- }
2245
- logger.debug("Parsing routing decision from LLM response");
2246
- let decision;
2247
- if (response && typeof response === "object" && ("targetAgent" in response || "targetAgents" in response)) {
2248
- logger.debug("Response is structured output", {
2249
- hasTargetAgent: "targetAgent" in response,
2250
- hasTargetAgents: "targetAgents" in response
2251
- });
2252
- decision = response;
2253
- } else if (response.content) {
2254
- if (typeof response.content === "string") {
2255
- try {
2256
- decision = JSON.parse(response.content);
2257
- logger.debug("Parsed JSON from string response");
2258
- } catch (error) {
2259
- logger.error("Failed to parse routing decision", {
2260
- content: response.content,
2261
- error: error instanceof Error ? error.message : String(error)
2262
- });
2263
- throw new Error(`Failed to parse routing decision from LLM. Expected JSON but got: ${response.content}`);
2264
- }
2265
- } else if (typeof response.content === "object") {
2266
- logger.debug("Response content is already an object");
2267
- decision = response.content;
2268
- } else {
2269
- logger.error("Unexpected response content type", {
2270
- type: typeof response.content
2271
- });
2272
- throw new Error(`Unexpected response content type: ${typeof response.content}`);
2273
- }
2274
- } else {
2275
- logger.error("Unexpected response format", {
2276
- response: JSON.stringify(response)
2277
- });
2278
- throw new Error(`Unexpected response format: ${JSON.stringify(response)}`);
2279
- }
2280
- const result = {
2281
- targetAgent: decision.targetAgent,
2282
- targetAgents: decision.targetAgents,
2283
- reasoning: decision.reasoning,
2284
- confidence: decision.confidence,
2285
- strategy: "llm-based",
2286
- timestamp: Date.now()
2287
- };
2288
- logger.info("LLM routing decision made", {
2289
- targetAgent: result.targetAgent,
2290
- targetAgents: result.targetAgents,
2291
- isParallel: result.targetAgents && result.targetAgents.length > 1,
2292
- confidence: result.confidence,
2293
- reasoning: result.reasoning
2294
- });
2295
- return result;
2296
- }
2297
- logger.error("Max tool retries exceeded", { maxRetries });
2298
- throw new Error(`Max tool retries (${maxRetries}) exceeded without routing decision`);
2117
+ const messages = [
2118
+ new SystemMessage4(systemPrompt),
2119
+ new HumanMessage4(userPrompt)
2120
+ ];
2121
+ const decision = await config.model.invoke(messages);
2122
+ return {
2123
+ targetAgent: decision.targetAgent,
2124
+ targetAgents: decision.targetAgents,
2125
+ reasoning: decision.reasoning,
2126
+ confidence: decision.confidence,
2127
+ strategy: "llm-based",
2128
+ timestamp: Date.now()
2129
+ };
2299
2130
  }
2300
2131
  };
2301
2132
  var roundRobinRouting = {
2302
2133
  name: "round-robin",
2303
2134
  async route(state, config) {
2304
- logger.info("Starting round-robin routing", {
2305
- iteration: state.iteration
2306
- });
2307
2135
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id]) => id);
2308
- logger.debug("Available workers for round-robin", {
2309
- count: availableWorkers.length,
2310
- workers: availableWorkers
2311
- });
2312
2136
  if (availableWorkers.length === 0) {
2313
- logger.error("No available workers for round-robin routing");
2314
2137
  throw new Error("No available workers for round-robin routing");
2315
2138
  }
2316
2139
  const lastRoutingIndex = state.routingHistory.length % availableWorkers.length;
2317
2140
  const targetAgent = availableWorkers[lastRoutingIndex];
2318
- logger.info("Round-robin routing decision", {
2319
- targetAgent,
2320
- index: lastRoutingIndex + 1,
2321
- totalWorkers: availableWorkers.length
2322
- });
2323
2141
  return {
2324
2142
  targetAgent,
2325
2143
  targetAgents: null,
@@ -2333,15 +2151,8 @@ var roundRobinRouting = {
2333
2151
  var skillBasedRouting = {
2334
2152
  name: "skill-based",
2335
2153
  async route(state, config) {
2336
- logger.info("Starting skill-based routing", {
2337
- iteration: state.iteration
2338
- });
2339
2154
  const lastMessage = state.messages[state.messages.length - 1];
2340
2155
  const taskContent = (lastMessage?.content || state.input).toLowerCase();
2341
- logger.debug("Task content for skill matching", {
2342
- taskLength: taskContent.length,
2343
- taskPreview: taskContent.substring(0, 100)
2344
- });
2345
2156
  const workerScores = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => {
2346
2157
  const skillMatches = caps.skills.filter(
2347
2158
  (skill) => taskContent.includes(skill.toLowerCase())
@@ -2352,20 +2163,11 @@ var skillBasedRouting = {
2352
2163
  const score = skillMatches * 2 + toolMatches;
2353
2164
  return { id, score, skills: caps.skills, tools: caps.tools };
2354
2165
  }).filter((w) => w.score > 0).sort((a, b) => b.score - a.score);
2355
- logger.debug("Worker skill scores", {
2356
- scoredWorkers: workerScores.map((w) => ({ id: w.id, score: w.score }))
2357
- });
2358
2166
  if (workerScores.length === 0) {
2359
- logger.warn("No skill matches found, using fallback");
2360
2167
  const firstAvailable = Object.entries(state.workers).find(([_, caps]) => caps.available);
2361
2168
  if (!firstAvailable) {
2362
- logger.error("No available workers for skill-based routing");
2363
2169
  throw new Error("No available workers for skill-based routing");
2364
2170
  }
2365
- logger.info("Skill-based routing fallback decision", {
2366
- targetAgent: firstAvailable[0],
2367
- confidence: 0.5
2368
- });
2369
2171
  return {
2370
2172
  targetAgent: firstAvailable[0],
2371
2173
  targetAgents: null,
@@ -2377,12 +2179,6 @@ var skillBasedRouting = {
2377
2179
  }
2378
2180
  const best = workerScores[0];
2379
2181
  const confidence = Math.min(best.score / 5, 1);
2380
- logger.info("Skill-based routing decision", {
2381
- targetAgent: best.id,
2382
- score: best.score,
2383
- confidence,
2384
- matchedSkills: best.skills
2385
- });
2386
2182
  return {
2387
2183
  targetAgent: best.id,
2388
2184
  targetAgents: null,
@@ -2396,26 +2192,13 @@ var skillBasedRouting = {
2396
2192
  var loadBalancedRouting = {
2397
2193
  name: "load-balanced",
2398
2194
  async route(state, config) {
2399
- logger.info("Starting load-balanced routing", {
2400
- iteration: state.iteration
2401
- });
2402
2195
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => ({ id, workload: caps.currentWorkload })).sort((a, b) => a.workload - b.workload);
2403
- logger.debug("Worker workloads", {
2404
- workers: availableWorkers.map((w) => ({ id: w.id, workload: w.workload }))
2405
- });
2406
2196
  if (availableWorkers.length === 0) {
2407
- logger.error("No available workers for load-balanced routing");
2408
2197
  throw new Error("No available workers for load-balanced routing");
2409
2198
  }
2410
2199
  const targetWorker = availableWorkers[0];
2411
2200
  const avgWorkload = availableWorkers.reduce((sum, w) => sum + w.workload, 0) / availableWorkers.length;
2412
2201
  const confidence = targetWorker.workload === 0 ? 1 : Math.max(0.5, 1 - targetWorker.workload / (avgWorkload * 2));
2413
- logger.info("Load-balanced routing decision", {
2414
- targetAgent: targetWorker.id,
2415
- workload: targetWorker.workload,
2416
- avgWorkload: avgWorkload.toFixed(1),
2417
- confidence
2418
- });
2419
2202
  return {
2420
2203
  targetAgent: targetWorker.id,
2421
2204
  targetAgents: null,
@@ -2429,24 +2212,13 @@ var loadBalancedRouting = {
2429
2212
  var ruleBasedRouting = {
2430
2213
  name: "rule-based",
2431
2214
  async route(state, config) {
2432
- logger.info("Starting rule-based routing", {
2433
- iteration: state.iteration
2434
- });
2435
2215
  if (!config.routingFn) {
2436
- logger.error("Rule-based routing requires a custom routing function");
2437
2216
  throw new Error("Rule-based routing requires a custom routing function");
2438
2217
  }
2439
- const decision = await config.routingFn(state);
2440
- logger.info("Rule-based routing decision", {
2441
- targetAgent: decision.targetAgent,
2442
- targetAgents: decision.targetAgents,
2443
- confidence: decision.confidence
2444
- });
2445
- return decision;
2218
+ return await config.routingFn(state);
2446
2219
  }
2447
2220
  };
2448
2221
  function getRoutingStrategy(name) {
2449
- logger.debug("Getting routing strategy", { name });
2450
2222
  switch (name) {
2451
2223
  case "llm-based":
2452
2224
  return llmBasedRouting;
@@ -2459,15 +2231,14 @@ function getRoutingStrategy(name) {
2459
2231
  case "rule-based":
2460
2232
  return ruleBasedRouting;
2461
2233
  default:
2462
- logger.error("Unknown routing strategy", { name });
2463
2234
  throw new Error(`Unknown routing strategy: ${name}`);
2464
2235
  }
2465
2236
  }
2466
2237
 
2467
2238
  // src/multi-agent/utils.ts
2468
- import { createLogger as createLogger3, LogLevel as LogLevel2 } from "@agentforge/core";
2469
- var logLevel2 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel2.INFO;
2470
- var logger2 = createLogger3("multi-agent", { level: logLevel2 });
2239
+ import { createLogger as createLogger2, LogLevel } from "@agentforge/core";
2240
+ var logLevel = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
2241
+ var logger = createLogger2("multi-agent", { level: logLevel });
2471
2242
  function isReActAgent(obj) {
2472
2243
  return obj && typeof obj === "object" && typeof obj.invoke === "function" && typeof obj.stream === "function" && // Additional check to ensure it's not just any object with invoke/stream
2473
2244
  (obj.constructor?.name === "CompiledGraph" || obj.constructor?.name === "CompiledStateGraph");
@@ -2475,9 +2246,9 @@ function isReActAgent(obj) {
2475
2246
  function wrapReActAgent(workerId, agent, verbose = false) {
2476
2247
  return async (state, config) => {
2477
2248
  try {
2478
- logger2.debug("Wrapping ReAct agent execution", { workerId });
2249
+ logger.debug("Wrapping ReAct agent execution", { workerId });
2479
2250
  const task = state.messages[state.messages.length - 1]?.content || state.input;
2480
- logger2.debug("Extracted task", {
2251
+ logger.debug("Extracted task", {
2481
2252
  workerId,
2482
2253
  taskPreview: task.substring(0, 100) + (task.length > 100 ? "..." : "")
2483
2254
  });
@@ -2485,7 +2256,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2485
2256
  (assignment) => assignment.workerId === workerId && !state.completedTasks.some((task2) => task2.assignmentId === assignment.id)
2486
2257
  );
2487
2258
  if (!currentAssignment) {
2488
- logger2.debug("No active assignment found", { workerId });
2259
+ logger.debug("No active assignment found", { workerId });
2489
2260
  return {};
2490
2261
  }
2491
2262
  const result = await agent.invoke(
@@ -2496,14 +2267,14 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2496
2267
  // Pass through the config for checkpointing and interrupt support
2497
2268
  );
2498
2269
  const response = result.messages?.[result.messages.length - 1]?.content || "No response";
2499
- logger2.debug("Received response from ReAct agent", {
2270
+ logger.debug("Received response from ReAct agent", {
2500
2271
  workerId,
2501
2272
  responsePreview: response.substring(0, 100) + (response.length > 100 ? "..." : "")
2502
2273
  });
2503
2274
  const toolsUsed = result.actions?.map((action) => action.name).filter(Boolean) || [];
2504
2275
  const uniqueTools = [...new Set(toolsUsed)];
2505
2276
  if (uniqueTools.length > 0) {
2506
- logger2.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2277
+ logger.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2507
2278
  }
2508
2279
  const taskResult = {
2509
2280
  assignmentId: currentAssignment.id,
@@ -2521,14 +2292,10 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2521
2292
  completedTasks: [taskResult]
2522
2293
  };
2523
2294
  } catch (error) {
2524
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
2525
- logger2.debug("GraphInterrupt detected - re-throwing", { workerId });
2526
- throw error;
2527
- }
2528
- logger2.error("Error in ReAct agent execution", {
2295
+ const errorMessage = handleNodeError(error, `react-agent:${workerId}`, false);
2296
+ logger.error("Error in ReAct agent execution", {
2529
2297
  workerId,
2530
- error: error instanceof Error ? error.message : String(error),
2531
- stack: error instanceof Error ? error.stack : void 0
2298
+ error: errorMessage
2532
2299
  });
2533
2300
  const currentAssignment = state.activeAssignments.find(
2534
2301
  (assignment) => assignment.workerId === workerId
@@ -2539,7 +2306,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2539
2306
  workerId,
2540
2307
  success: false,
2541
2308
  result: "",
2542
- error: error instanceof Error ? error.message : "Unknown error in ReAct agent",
2309
+ error: errorMessage,
2543
2310
  completedAt: Date.now()
2544
2311
  };
2545
2312
  return {
@@ -2550,7 +2317,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2550
2317
  }
2551
2318
  return {
2552
2319
  status: "failed",
2553
- error: error instanceof Error ? error.message : `Unknown error in ReAct wrapper for ${workerId}`
2320
+ error: errorMessage
2554
2321
  };
2555
2322
  }
2556
2323
  };
@@ -2558,9 +2325,9 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2558
2325
 
2559
2326
  // src/multi-agent/nodes.ts
2560
2327
  import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
2561
- import { toLangChainTools as toLangChainTools2, createLogger as createLogger4, LogLevel as LogLevel3 } from "@agentforge/core";
2562
- var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel3.INFO;
2563
- var logger3 = createLogger4("multi-agent:nodes", { level: logLevel3 });
2328
+ import { toLangChainTools as toLangChainTools2, createLogger as createLogger3, LogLevel as LogLevel2 } from "@agentforge/core";
2329
+ var logLevel2 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel2.INFO;
2330
+ var logger2 = createLogger3("multi-agent:nodes", { level: logLevel2 });
2564
2331
  var DEFAULT_AGGREGATOR_SYSTEM_PROMPT = `You are an aggregator agent responsible for combining results from multiple worker agents.
2565
2332
 
2566
2333
  Your job is to:
@@ -2578,19 +2345,19 @@ function createSupervisorNode(config) {
2578
2345
  } = config;
2579
2346
  return async (state) => {
2580
2347
  try {
2581
- logger3.info("Supervisor node executing", {
2348
+ logger2.info("Supervisor node executing", {
2582
2349
  iteration: state.iteration,
2583
2350
  maxIterations,
2584
2351
  activeAssignments: state.activeAssignments.length,
2585
2352
  completedTasks: state.completedTasks.length
2586
2353
  });
2587
- logger3.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2354
+ logger2.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2588
2355
  if (state.iteration >= maxIterations) {
2589
- logger3.warn("Max iterations reached", {
2356
+ logger2.warn("Max iterations reached", {
2590
2357
  iteration: state.iteration,
2591
2358
  maxIterations
2592
2359
  });
2593
- logger3.debug("Max iterations reached, moving to aggregation");
2360
+ logger2.debug("Max iterations reached, moving to aggregation");
2594
2361
  return {
2595
2362
  status: "aggregating",
2596
2363
  currentAgent: "aggregator"
@@ -2599,26 +2366,26 @@ function createSupervisorNode(config) {
2599
2366
  const allCompleted = state.activeAssignments.every(
2600
2367
  (assignment) => state.completedTasks.some((task2) => task2.assignmentId === assignment.id)
2601
2368
  );
2602
- logger3.debug("Checking task completion", {
2369
+ logger2.debug("Checking task completion", {
2603
2370
  activeAssignments: state.activeAssignments.length,
2604
2371
  completedTasks: state.completedTasks.length,
2605
2372
  allCompleted
2606
2373
  });
2607
2374
  if (allCompleted && state.activeAssignments.length > 0) {
2608
- logger3.info("All tasks completed, moving to aggregation", {
2375
+ logger2.info("All tasks completed, moving to aggregation", {
2609
2376
  completedCount: state.completedTasks.length
2610
2377
  });
2611
- logger3.debug("All tasks completed, moving to aggregation");
2378
+ logger2.debug("All tasks completed, moving to aggregation");
2612
2379
  return {
2613
2380
  status: "aggregating",
2614
2381
  currentAgent: "aggregator"
2615
2382
  };
2616
2383
  }
2617
- logger3.debug("Getting routing strategy", { strategy });
2384
+ logger2.debug("Getting routing strategy", { strategy });
2618
2385
  const routingImpl = getRoutingStrategy(strategy);
2619
2386
  const decision = await routingImpl.route(state, config);
2620
2387
  const targetAgents = decision.targetAgents && decision.targetAgents.length > 0 ? decision.targetAgents : decision.targetAgent ? [decision.targetAgent] : [];
2621
- logger3.debug("Target agents determined", {
2388
+ logger2.debug("Target agents determined", {
2622
2389
  targetAgents,
2623
2390
  isParallel: targetAgents.length > 1,
2624
2391
  decision: {
@@ -2627,17 +2394,17 @@ function createSupervisorNode(config) {
2627
2394
  }
2628
2395
  });
2629
2396
  if (targetAgents.length === 0) {
2630
- logger3.error("No target agents specified in routing decision");
2397
+ logger2.error("No target agents specified in routing decision");
2631
2398
  throw new Error("Routing decision must specify at least one target agent");
2632
2399
  }
2633
2400
  if (targetAgents.length === 1) {
2634
- logger3.info("Routing to single agent", {
2401
+ logger2.info("Routing to single agent", {
2635
2402
  targetAgent: targetAgents[0],
2636
2403
  reasoning: decision.reasoning,
2637
2404
  confidence: decision.confidence
2638
2405
  });
2639
2406
  } else {
2640
- logger3.info("Routing to multiple agents in parallel", {
2407
+ logger2.info("Routing to multiple agents in parallel", {
2641
2408
  targetAgents,
2642
2409
  count: targetAgents.length,
2643
2410
  reasoning: decision.reasoning,
@@ -2645,9 +2412,9 @@ function createSupervisorNode(config) {
2645
2412
  });
2646
2413
  }
2647
2414
  if (targetAgents.length === 1) {
2648
- logger3.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2415
+ logger2.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2649
2416
  } else {
2650
- logger3.debug(`Routing to ${targetAgents.length} agents in parallel [${targetAgents.join(", ")}]: ${decision.reasoning}`);
2417
+ logger2.debug(`Routing to ${targetAgents.length} agents in parallel [${targetAgents.join(", ")}]: ${decision.reasoning}`);
2651
2418
  }
2652
2419
  const task = state.messages[state.messages.length - 1]?.content || state.input;
2653
2420
  const assignments = targetAgents.map((workerId) => ({
@@ -2657,7 +2424,7 @@ function createSupervisorNode(config) {
2657
2424
  priority: 5,
2658
2425
  assignedAt: Date.now()
2659
2426
  }));
2660
- logger3.debug("Created task assignments", {
2427
+ logger2.debug("Created task assignments", {
2661
2428
  assignmentCount: assignments.length,
2662
2429
  assignments: assignments.map((a) => ({
2663
2430
  id: a.id,
@@ -2677,7 +2444,7 @@ function createSupervisorNode(config) {
2677
2444
  priority: assignment.priority
2678
2445
  }
2679
2446
  }));
2680
- logger3.info("Supervisor routing complete", {
2447
+ logger2.info("Supervisor routing complete", {
2681
2448
  currentAgent: targetAgents.join(","),
2682
2449
  status: "executing",
2683
2450
  assignmentCount: assignments.length,
@@ -2694,7 +2461,7 @@ function createSupervisorNode(config) {
2694
2461
  iteration: state.iteration + 1
2695
2462
  };
2696
2463
  } catch (error) {
2697
- logger3.error("Supervisor node error", {
2464
+ logger2.error("Supervisor node error", {
2698
2465
  error: error instanceof Error ? error.message : String(error),
2699
2466
  stack: error instanceof Error ? error.stack : void 0,
2700
2467
  iteration: state.iteration
@@ -2719,7 +2486,7 @@ function createWorkerNode(config) {
2719
2486
  } = config;
2720
2487
  return async (state, runConfig) => {
2721
2488
  try {
2722
- logger3.info("Worker node executing", {
2489
+ logger2.info("Worker node executing", {
2723
2490
  workerId: id,
2724
2491
  iteration: state.iteration,
2725
2492
  activeAssignments: state.activeAssignments.length
@@ -2728,39 +2495,39 @@ function createWorkerNode(config) {
2728
2495
  (assignment) => assignment.workerId === id && !state.completedTasks.some((task) => task.assignmentId === assignment.id)
2729
2496
  );
2730
2497
  if (!currentAssignment) {
2731
- logger3.debug("No active assignment found for worker", {
2498
+ logger2.debug("No active assignment found for worker", {
2732
2499
  workerId: id,
2733
2500
  totalActiveAssignments: state.activeAssignments.length,
2734
2501
  completedTasks: state.completedTasks.length
2735
2502
  });
2736
2503
  return {};
2737
2504
  }
2738
- logger3.info("Worker processing assignment", {
2505
+ logger2.info("Worker processing assignment", {
2739
2506
  workerId: id,
2740
2507
  assignmentId: currentAssignment.id,
2741
2508
  taskLength: currentAssignment.task.length,
2742
2509
  taskPreview: currentAssignment.task.substring(0, 100)
2743
2510
  });
2744
2511
  if (executeFn) {
2745
- logger3.debug("Using custom execution function", { workerId: id });
2512
+ logger2.debug("Using custom execution function", { workerId: id });
2746
2513
  return await executeFn(state, runConfig);
2747
2514
  }
2748
2515
  if (agent) {
2749
2516
  if (isReActAgent(agent)) {
2750
- logger3.debug("Using ReAct agent", { workerId: id });
2517
+ logger2.debug("Using ReAct agent", { workerId: id });
2751
2518
  const wrappedFn = wrapReActAgent(id, agent, verbose);
2752
2519
  return await wrappedFn(state, runConfig);
2753
2520
  } else {
2754
- logger3.warn("Agent provided but not a ReAct agent, falling back", { workerId: id });
2521
+ logger2.warn("Agent provided but not a ReAct agent, falling back", { workerId: id });
2755
2522
  }
2756
2523
  }
2757
2524
  if (!model) {
2758
- logger3.error("Worker missing required configuration", { workerId: id });
2525
+ logger2.error("Worker missing required configuration", { workerId: id });
2759
2526
  throw new Error(
2760
2527
  `Worker ${id} requires either a model, an agent, or a custom execution function. Provide one of: config.model, config.agent, or config.executeFn`
2761
2528
  );
2762
2529
  }
2763
- logger3.debug("Using default LLM execution", {
2530
+ logger2.debug("Using default LLM execution", {
2764
2531
  workerId: id,
2765
2532
  hasTools: tools.length > 0,
2766
2533
  toolCount: tools.length
@@ -2776,7 +2543,7 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2776
2543
  ];
2777
2544
  let modelToUse = model;
2778
2545
  if (tools.length > 0 && model.bindTools) {
2779
- logger3.debug("Binding tools to model", {
2546
+ logger2.debug("Binding tools to model", {
2780
2547
  workerId: id,
2781
2548
  toolCount: tools.length,
2782
2549
  toolNames: tools.map((t) => t.metadata.name)
@@ -2784,10 +2551,10 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2784
2551
  const langchainTools = toLangChainTools2(tools);
2785
2552
  modelToUse = model.bindTools(langchainTools);
2786
2553
  }
2787
- logger3.debug("Invoking LLM", { workerId: id });
2554
+ logger2.debug("Invoking LLM", { workerId: id });
2788
2555
  const response = await modelToUse.invoke(messages);
2789
2556
  const result = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
2790
- logger3.info("Worker task completed", {
2557
+ logger2.info("Worker task completed", {
2791
2558
  workerId: id,
2792
2559
  assignmentId: currentAssignment.id,
2793
2560
  resultLength: result.length,
@@ -2822,7 +2589,7 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2822
2589
  currentWorkload: Math.max(0, capabilities.currentWorkload - 1)
2823
2590
  }
2824
2591
  };
2825
- logger3.debug("Worker state update", {
2592
+ logger2.debug("Worker state update", {
2826
2593
  workerId: id,
2827
2594
  newWorkload: updatedWorkers[id].currentWorkload
2828
2595
  });
@@ -2832,20 +2599,16 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2832
2599
  workers: updatedWorkers
2833
2600
  };
2834
2601
  } catch (error) {
2835
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
2836
- logger3.info("GraphInterrupt detected, re-throwing", { workerId: id });
2837
- throw error;
2838
- }
2839
- logger3.error("Worker node error", {
2602
+ const errorMessage = handleNodeError(error, `worker:${id}`, false);
2603
+ logger2.error("Worker node error", {
2840
2604
  workerId: id,
2841
- error: error instanceof Error ? error.message : String(error),
2842
- stack: error instanceof Error ? error.stack : void 0
2605
+ error: errorMessage
2843
2606
  });
2844
2607
  const currentAssignment = state.activeAssignments.find(
2845
2608
  (assignment) => assignment.workerId === id
2846
2609
  );
2847
2610
  if (currentAssignment) {
2848
- logger3.warn("Creating error result for assignment", {
2611
+ logger2.warn("Creating error result for assignment", {
2849
2612
  workerId: id,
2850
2613
  assignmentId: currentAssignment.id
2851
2614
  });
@@ -2854,7 +2617,7 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2854
2617
  workerId: id,
2855
2618
  success: false,
2856
2619
  result: "",
2857
- error: error instanceof Error ? error.message : "Unknown error",
2620
+ error: errorMessage,
2858
2621
  completedAt: Date.now()
2859
2622
  };
2860
2623
  return {
@@ -2863,10 +2626,10 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2863
2626
  status: "routing"
2864
2627
  };
2865
2628
  }
2866
- logger3.error("No assignment found for error handling", { workerId: id });
2629
+ logger2.error("No assignment found for error handling", { workerId: id });
2867
2630
  return {
2868
2631
  status: "failed",
2869
- error: error instanceof Error ? error.message : `Unknown error in worker ${id}`
2632
+ error: errorMessage
2870
2633
  };
2871
2634
  }
2872
2635
  };
@@ -2880,16 +2643,16 @@ function createAggregatorNode(config = {}) {
2880
2643
  } = config;
2881
2644
  return async (state) => {
2882
2645
  try {
2883
- logger3.info("Aggregator node executing", {
2646
+ logger2.info("Aggregator node executing", {
2884
2647
  completedTasks: state.completedTasks.length,
2885
2648
  successfulTasks: state.completedTasks.filter((t) => t.success).length,
2886
2649
  failedTasks: state.completedTasks.filter((t) => !t.success).length
2887
2650
  });
2888
- logger3.debug("Combining results from workers");
2651
+ logger2.debug("Combining results from workers");
2889
2652
  if (aggregateFn) {
2890
- logger3.debug("Using custom aggregation function");
2653
+ logger2.debug("Using custom aggregation function");
2891
2654
  const response2 = await aggregateFn(state);
2892
- logger3.info("Custom aggregation complete", {
2655
+ logger2.info("Custom aggregation complete", {
2893
2656
  responseLength: response2.length
2894
2657
  });
2895
2658
  return {
@@ -2898,16 +2661,16 @@ function createAggregatorNode(config = {}) {
2898
2661
  };
2899
2662
  }
2900
2663
  if (state.completedTasks.length === 0) {
2901
- logger3.warn("No completed tasks to aggregate");
2664
+ logger2.warn("No completed tasks to aggregate");
2902
2665
  return {
2903
2666
  response: "No tasks were completed.",
2904
2667
  status: "completed"
2905
2668
  };
2906
2669
  }
2907
2670
  if (!model) {
2908
- logger3.debug("No model provided, concatenating results");
2671
+ logger2.debug("No model provided, concatenating results");
2909
2672
  const combinedResults = state.completedTasks.filter((task) => task.success).map((task) => task.result).join("\n\n");
2910
- logger3.info("Simple concatenation complete", {
2673
+ logger2.info("Simple concatenation complete", {
2911
2674
  resultLength: combinedResults.length
2912
2675
  });
2913
2676
  return {
@@ -2915,7 +2678,7 @@ function createAggregatorNode(config = {}) {
2915
2678
  status: "completed"
2916
2679
  };
2917
2680
  }
2918
- logger3.debug("Using LLM for intelligent aggregation", {
2681
+ logger2.debug("Using LLM for intelligent aggregation", {
2919
2682
  taskCount: state.completedTasks.length
2920
2683
  });
2921
2684
  const taskResults = state.completedTasks.map((task, idx) => {
@@ -2934,20 +2697,20 @@ Please synthesize these results into a comprehensive response that addresses the
2934
2697
  new SystemMessage5(systemPrompt),
2935
2698
  new HumanMessage5(userPrompt)
2936
2699
  ];
2937
- logger3.debug("Invoking aggregation LLM");
2700
+ logger2.debug("Invoking aggregation LLM");
2938
2701
  const response = await model.invoke(messages);
2939
2702
  const aggregatedResponse = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
2940
- logger3.info("Aggregation complete", {
2703
+ logger2.info("Aggregation complete", {
2941
2704
  responseLength: aggregatedResponse.length,
2942
2705
  responsePreview: aggregatedResponse.substring(0, 100)
2943
2706
  });
2944
- logger3.debug("Aggregation complete");
2707
+ logger2.debug("Aggregation complete");
2945
2708
  return {
2946
2709
  response: aggregatedResponse,
2947
2710
  status: "completed"
2948
2711
  };
2949
2712
  } catch (error) {
2950
- logger3.error("Aggregator node error", {
2713
+ logger2.error("Aggregator node error", {
2951
2714
  error: error instanceof Error ? error.message : String(error),
2952
2715
  stack: error instanceof Error ? error.stack : void 0,
2953
2716
  completedTasks: state.completedTasks.length
@@ -2962,9 +2725,9 @@ Please synthesize these results into a comprehensive response that addresses the
2962
2725
 
2963
2726
  // src/multi-agent/agent.ts
2964
2727
  import { StateGraph as StateGraph4, END as END4 } from "@langchain/langgraph";
2965
- import { toLangChainTools as toLangChainTools3, createLogger as createLogger5, LogLevel as LogLevel4 } from "@agentforge/core";
2966
- var logLevel4 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel4.INFO;
2967
- var logger4 = createLogger5("multi-agent:system", { level: logLevel4 });
2728
+ import { createLogger as createLogger4, LogLevel as LogLevel3 } from "@agentforge/core";
2729
+ var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel3.INFO;
2730
+ var logger3 = createLogger4("multi-agent:system", { level: logLevel3 });
2968
2731
  function createMultiAgentSystem(config) {
2969
2732
  const {
2970
2733
  supervisor,
@@ -2981,10 +2744,6 @@ function createMultiAgentSystem(config) {
2981
2744
  if (supervisor.strategy === "llm-based") {
2982
2745
  configuredModel = configuredModel.withStructuredOutput(RoutingDecisionSchema);
2983
2746
  }
2984
- if (supervisor.tools && supervisor.tools.length > 0) {
2985
- const langchainTools = toLangChainTools3(supervisor.tools);
2986
- configuredModel = configuredModel.bindTools(langchainTools);
2987
- }
2988
2747
  supervisorConfig.model = configuredModel;
2989
2748
  }
2990
2749
  const supervisorNode = createSupervisorNode(supervisorConfig);
@@ -3006,46 +2765,46 @@ function createMultiAgentSystem(config) {
3006
2765
  });
3007
2766
  workflow.addNode("aggregator", aggregatorNode);
3008
2767
  const supervisorRouter = (state) => {
3009
- logger4.debug("Supervisor router executing", {
2768
+ logger3.debug("Supervisor router executing", {
3010
2769
  status: state.status,
3011
2770
  currentAgent: state.currentAgent,
3012
2771
  iteration: state.iteration
3013
2772
  });
3014
2773
  if (state.status === "completed" || state.status === "failed") {
3015
- logger4.info("Supervisor router: ending workflow", { status: state.status });
2774
+ logger3.info("Supervisor router: ending workflow", { status: state.status });
3016
2775
  return END4;
3017
2776
  }
3018
2777
  if (state.status === "aggregating") {
3019
- logger4.info("Supervisor router: routing to aggregator");
2778
+ logger3.info("Supervisor router: routing to aggregator");
3020
2779
  return "aggregator";
3021
2780
  }
3022
2781
  if (state.currentAgent && state.currentAgent !== "supervisor") {
3023
2782
  if (state.currentAgent.includes(",")) {
3024
2783
  const agents = state.currentAgent.split(",").map((a) => a.trim());
3025
- logger4.info("Supervisor router: parallel routing", {
2784
+ logger3.info("Supervisor router: parallel routing", {
3026
2785
  agents,
3027
2786
  count: agents.length
3028
2787
  });
3029
2788
  return agents;
3030
2789
  }
3031
- logger4.info("Supervisor router: single agent routing", {
2790
+ logger3.info("Supervisor router: single agent routing", {
3032
2791
  targetAgent: state.currentAgent
3033
2792
  });
3034
2793
  return state.currentAgent;
3035
2794
  }
3036
- logger4.debug("Supervisor router: staying at supervisor");
2795
+ logger3.debug("Supervisor router: staying at supervisor");
3037
2796
  return "supervisor";
3038
2797
  };
3039
2798
  const workerRouter = (state) => {
3040
- logger4.debug("Worker router executing", {
2799
+ logger3.debug("Worker router executing", {
3041
2800
  iteration: state.iteration,
3042
2801
  completedTasks: state.completedTasks.length
3043
2802
  });
3044
- logger4.debug("Worker router: returning to supervisor");
2803
+ logger3.debug("Worker router: returning to supervisor");
3045
2804
  return "supervisor";
3046
2805
  };
3047
2806
  const aggregatorRouter = (state) => {
3048
- logger4.info("Aggregator router: ending workflow", {
2807
+ logger3.info("Aggregator router: ending workflow", {
3049
2808
  completedTasks: state.completedTasks.length,
3050
2809
  status: state.status
3051
2810
  });