@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.cjs CHANGED
@@ -138,15 +138,46 @@ var ScratchpadEntrySchema = import_zod.z.object({
138
138
  });
139
139
 
140
140
  // src/react/state.ts
141
- var import_zod2 = require("zod");
141
+ var import_zod3 = require("zod");
142
142
  var import_core = require("@agentforge/core");
143
+
144
+ // src/shared/state-fields.ts
145
+ var import_zod2 = require("zod");
146
+ var iterationField = {
147
+ schema: import_zod2.z.number().int().nonnegative(),
148
+ reducer: (left, right) => left + right,
149
+ default: () => 0,
150
+ description: "Current iteration number"
151
+ };
152
+ function maxIterationsField(defaultValue) {
153
+ return {
154
+ schema: import_zod2.z.number().int().positive(),
155
+ default: () => defaultValue,
156
+ description: "Maximum number of iterations allowed"
157
+ };
158
+ }
159
+ var errorField = {
160
+ schema: import_zod2.z.string().optional(),
161
+ description: "Error message if execution failed"
162
+ };
163
+ var responseField = {
164
+ schema: import_zod2.z.string().optional(),
165
+ description: "Final response after completion"
166
+ };
167
+ var inputField = {
168
+ schema: import_zod2.z.string(),
169
+ default: () => "",
170
+ description: "Original user input or query"
171
+ };
172
+
173
+ // src/react/state.ts
143
174
  var ReActStateConfig = {
144
175
  /**
145
176
  * Conversation messages
146
177
  * Accumulates all messages in the conversation
147
178
  */
148
179
  messages: {
149
- schema: import_zod2.z.array(MessageSchema),
180
+ schema: import_zod3.z.array(MessageSchema),
150
181
  reducer: (left, right) => [...left, ...right],
151
182
  default: () => [],
152
183
  description: "Conversation message history"
@@ -156,7 +187,7 @@ var ReActStateConfig = {
156
187
  * Accumulates all reasoning steps the agent takes
157
188
  */
158
189
  thoughts: {
159
- schema: import_zod2.z.array(ThoughtSchema),
190
+ schema: import_zod3.z.array(ThoughtSchema),
160
191
  reducer: (left, right) => [...left, ...right],
161
192
  default: () => [],
162
193
  description: "Agent reasoning steps"
@@ -166,7 +197,7 @@ var ReActStateConfig = {
166
197
  * Accumulates all tool calls made by the agent
167
198
  */
168
199
  actions: {
169
- schema: import_zod2.z.array(ToolCallSchema),
200
+ schema: import_zod3.z.array(ToolCallSchema),
170
201
  reducer: (left, right) => [...left, ...right],
171
202
  default: () => [],
172
203
  description: "Tool calls made by the agent"
@@ -176,7 +207,7 @@ var ReActStateConfig = {
176
207
  * Accumulates all observations from tool executions
177
208
  */
178
209
  observations: {
179
- schema: import_zod2.z.array(ToolResultSchema),
210
+ schema: import_zod3.z.array(ToolResultSchema),
180
211
  reducer: (left, right) => [...left, ...right],
181
212
  default: () => [],
182
213
  description: "Results from tool executions"
@@ -186,7 +217,7 @@ var ReActStateConfig = {
186
217
  * Accumulates step-by-step reasoning process
187
218
  */
188
219
  scratchpad: {
189
- schema: import_zod2.z.array(ScratchpadEntrySchema),
220
+ schema: import_zod3.z.array(ScratchpadEntrySchema),
190
221
  reducer: (left, right) => [...left, ...right],
191
222
  default: () => [],
192
223
  description: "Intermediate reasoning scratchpad"
@@ -195,27 +226,19 @@ var ReActStateConfig = {
195
226
  * Current iteration count
196
227
  * Tracks how many thought-action-observation loops have been executed
197
228
  */
198
- iteration: {
199
- schema: import_zod2.z.number(),
200
- reducer: (left, right) => left + right,
201
- default: () => 0,
202
- description: "Current iteration count"
203
- },
229
+ iteration: iterationField,
204
230
  /**
205
231
  * Whether the agent should continue iterating
206
232
  */
207
233
  shouldContinue: {
208
- schema: import_zod2.z.boolean().optional(),
234
+ schema: import_zod3.z.boolean().optional(),
209
235
  default: () => true,
210
236
  description: "Whether to continue the ReAct loop"
211
237
  },
212
238
  /**
213
239
  * Final response (if any)
214
240
  */
215
- response: {
216
- schema: import_zod2.z.string().optional(),
217
- description: "Final response from the agent"
218
- }
241
+ response: responseField
219
242
  };
220
243
  var ReActState = (0, import_core.createStateAnnotation)(ReActStateConfig);
221
244
 
@@ -260,8 +283,8 @@ function generateToolCallCacheKey(toolName, args) {
260
283
  return `${toolName}:${sortedArgs}`;
261
284
  }
262
285
  function createPatternLogger(name, defaultLevel = "info") {
263
- const logLevel5 = process.env.LOG_LEVEL?.toLowerCase() || defaultLevel;
264
- return (0, import_core2.createLogger)(name, { level: logLevel5 });
286
+ const logLevel4 = process.env.LOG_LEVEL?.toLowerCase() || defaultLevel;
287
+ return (0, import_core2.createLogger)(name, { level: logLevel4 });
265
288
  }
266
289
  function calculateDeduplicationSavings(duplicatesSkipped, toolsExecuted) {
267
290
  if (duplicatesSkipped === 0) {
@@ -279,6 +302,24 @@ function buildDeduplicationMetrics(toolsExecuted, duplicatesSkipped, totalObserv
279
302
  };
280
303
  }
281
304
 
305
+ // src/shared/error-handling.ts
306
+ function isGraphInterrupt(error) {
307
+ return error !== null && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt";
308
+ }
309
+ function handleNodeError(error, context, verbose = false) {
310
+ if (isGraphInterrupt(error)) {
311
+ throw error;
312
+ }
313
+ const errorMessage = error instanceof Error ? error.message : String(error);
314
+ if (verbose) {
315
+ console.error(`[${context}] Error:`, errorMessage);
316
+ if (error instanceof Error && error.stack) {
317
+ console.error(`[${context}] Stack:`, error.stack);
318
+ }
319
+ }
320
+ return errorMessage;
321
+ }
322
+
282
323
  // src/react/nodes.ts
283
324
  var reasoningLogger = createPatternLogger("agentforge:patterns:react:reasoning");
284
325
  var actionLogger = createPatternLogger("agentforge:patterns:react:action");
@@ -441,10 +482,7 @@ function createActionNode(tools, verbose = false, enableDeduplication = true) {
441
482
  executionCache.set(cacheKey, observation);
442
483
  }
443
484
  } catch (error) {
444
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
445
- throw error;
446
- }
447
- const errorMessage = error instanceof Error ? error.message : String(error);
485
+ const errorMessage = handleNodeError(error, `action:${action.name}`, false);
448
486
  actionLogger.error("Tool execution failed", {
449
487
  toolName: action.name,
450
488
  error: errorMessage,
@@ -683,34 +721,34 @@ function createReActAgentBuilder() {
683
721
  var import_langgraph2 = require("@langchain/langgraph");
684
722
 
685
723
  // src/plan-execute/state.ts
686
- var import_zod4 = require("zod");
724
+ var import_zod5 = require("zod");
687
725
  var import_core5 = require("@agentforge/core");
688
726
 
689
727
  // src/plan-execute/schemas.ts
690
- var import_zod3 = require("zod");
691
- var PlanStepSchema = import_zod3.z.object({
728
+ var import_zod4 = require("zod");
729
+ var PlanStepSchema = import_zod4.z.object({
692
730
  /**
693
731
  * Unique identifier for the step
694
732
  */
695
- id: import_zod3.z.string().describe("Unique identifier for the step"),
733
+ id: import_zod4.z.string().describe("Unique identifier for the step"),
696
734
  /**
697
735
  * Description of what this step should accomplish
698
736
  */
699
- description: import_zod3.z.string().describe("Description of what this step should accomplish"),
737
+ description: import_zod4.z.string().describe("Description of what this step should accomplish"),
700
738
  /**
701
739
  * Optional dependencies on other steps (by ID)
702
740
  */
703
- dependencies: import_zod3.z.array(import_zod3.z.string()).optional().describe("IDs of steps that must complete before this one"),
741
+ dependencies: import_zod4.z.array(import_zod4.z.string()).optional().describe("IDs of steps that must complete before this one"),
704
742
  /**
705
743
  * Optional tool to use for this step
706
744
  */
707
- tool: import_zod3.z.string().optional().describe("Name of the tool to use for this step"),
745
+ tool: import_zod4.z.string().optional().describe("Name of the tool to use for this step"),
708
746
  /**
709
747
  * Optional arguments for the tool
710
748
  */
711
- args: import_zod3.z.record(import_zod3.z.any()).optional().describe("Arguments to pass to the tool")
749
+ args: import_zod4.z.record(import_zod4.z.any()).optional().describe("Arguments to pass to the tool")
712
750
  });
713
- var CompletedStepSchema = import_zod3.z.object({
751
+ var CompletedStepSchema = import_zod4.z.object({
714
752
  /**
715
753
  * The step that was executed
716
754
  */
@@ -718,53 +756,53 @@ var CompletedStepSchema = import_zod3.z.object({
718
756
  /**
719
757
  * The result of executing the step
720
758
  */
721
- result: import_zod3.z.any().describe("The result of executing the step"),
759
+ result: import_zod4.z.any().describe("The result of executing the step"),
722
760
  /**
723
761
  * Whether the step succeeded
724
762
  */
725
- success: import_zod3.z.boolean().describe("Whether the step succeeded"),
763
+ success: import_zod4.z.boolean().describe("Whether the step succeeded"),
726
764
  /**
727
765
  * Optional error message if the step failed
728
766
  */
729
- error: import_zod3.z.string().optional().describe("Error message if the step failed"),
767
+ error: import_zod4.z.string().optional().describe("Error message if the step failed"),
730
768
  /**
731
769
  * Timestamp when the step was completed
732
770
  */
733
- timestamp: import_zod3.z.string().datetime().describe("ISO timestamp when the step was completed")
771
+ timestamp: import_zod4.z.string().datetime().describe("ISO timestamp when the step was completed")
734
772
  });
735
- var PlanSchema = import_zod3.z.object({
773
+ var PlanSchema = import_zod4.z.object({
736
774
  /**
737
775
  * List of steps in the plan
738
776
  */
739
- steps: import_zod3.z.array(PlanStepSchema).describe("List of steps in the plan"),
777
+ steps: import_zod4.z.array(PlanStepSchema).describe("List of steps in the plan"),
740
778
  /**
741
779
  * Overall goal of the plan
742
780
  */
743
- goal: import_zod3.z.string().describe("Overall goal of the plan"),
781
+ goal: import_zod4.z.string().describe("Overall goal of the plan"),
744
782
  /**
745
783
  * Timestamp when the plan was created
746
784
  */
747
- createdAt: import_zod3.z.string().datetime().describe("ISO timestamp when the plan was created"),
785
+ createdAt: import_zod4.z.string().datetime().describe("ISO timestamp when the plan was created"),
748
786
  /**
749
787
  * Optional confidence score (0-1)
750
788
  */
751
- confidence: import_zod3.z.number().min(0).max(1).optional().describe("Confidence score for the plan (0-1)")
789
+ confidence: import_zod4.z.number().min(0).max(1).optional().describe("Confidence score for the plan (0-1)")
752
790
  });
753
- var ReplanDecisionSchema = import_zod3.z.object({
791
+ var ReplanDecisionSchema = import_zod4.z.object({
754
792
  /**
755
793
  * Whether to replan
756
794
  */
757
- shouldReplan: import_zod3.z.boolean().describe("Whether to replan based on current results"),
795
+ shouldReplan: import_zod4.z.boolean().describe("Whether to replan based on current results"),
758
796
  /**
759
797
  * Reason for the decision
760
798
  */
761
- reason: import_zod3.z.string().describe("Reason for the replan decision"),
799
+ reason: import_zod4.z.string().describe("Reason for the replan decision"),
762
800
  /**
763
801
  * Optional new goal if replanning
764
802
  */
765
- newGoal: import_zod3.z.string().optional().describe("Updated goal if replanning")
803
+ newGoal: import_zod4.z.string().optional().describe("Updated goal if replanning")
766
804
  });
767
- var ExecutionStatusSchema = import_zod3.z.enum([
805
+ var ExecutionStatusSchema = import_zod4.z.enum([
768
806
  "planning",
769
807
  "executing",
770
808
  "replanning",
@@ -777,11 +815,7 @@ var PlanExecuteStateConfig = {
777
815
  /**
778
816
  * Original user input/query
779
817
  */
780
- input: {
781
- schema: import_zod4.z.string(),
782
- default: () => "",
783
- description: "Original user input or query"
784
- },
818
+ input: inputField,
785
819
  /**
786
820
  * The current plan
787
821
  */
@@ -794,7 +828,7 @@ var PlanExecuteStateConfig = {
794
828
  * Accumulates all completed steps
795
829
  */
796
830
  pastSteps: {
797
- schema: import_zod4.z.array(CompletedStepSchema),
831
+ schema: import_zod5.z.array(CompletedStepSchema),
798
832
  reducer: (left, right) => [...left, ...right],
799
833
  default: () => [],
800
834
  description: "Completed steps with their results"
@@ -803,7 +837,7 @@ var PlanExecuteStateConfig = {
803
837
  * Index of the current step being executed
804
838
  */
805
839
  currentStepIndex: {
806
- schema: import_zod4.z.number().int().nonnegative().optional(),
840
+ schema: import_zod5.z.number().int().nonnegative().optional(),
807
841
  description: "Index of the current step being executed"
808
842
  },
809
843
  /**
@@ -817,34 +851,19 @@ var PlanExecuteStateConfig = {
817
851
  /**
818
852
  * Final response
819
853
  */
820
- response: {
821
- schema: import_zod4.z.string().optional(),
822
- description: "Final response after plan execution"
823
- },
854
+ response: responseField,
824
855
  /**
825
856
  * Error message if execution failed
826
857
  */
827
- error: {
828
- schema: import_zod4.z.string().optional(),
829
- description: "Error message if execution failed"
830
- },
858
+ error: errorField,
831
859
  /**
832
860
  * Iteration counter for replanning
833
861
  */
834
- iteration: {
835
- schema: import_zod4.z.number().int().nonnegative(),
836
- reducer: (left, right) => left + right,
837
- default: () => 0,
838
- description: "Number of planning iterations"
839
- },
862
+ iteration: iterationField,
840
863
  /**
841
864
  * Maximum iterations allowed
842
865
  */
843
- maxIterations: {
844
- schema: import_zod4.z.number().int().positive(),
845
- default: () => 5,
846
- description: "Maximum number of planning iterations allowed"
847
- }
866
+ maxIterations: maxIterationsField(5)
848
867
  };
849
868
  var PlanExecuteState = (0, import_core5.createStateAnnotation)(PlanExecuteStateConfig);
850
869
 
@@ -1077,11 +1096,8 @@ function createExecutorNode(config) {
1077
1096
  result = { message: "Step completed without tool execution" };
1078
1097
  }
1079
1098
  } catch (execError) {
1080
- if (execError && typeof execError === "object" && "constructor" in execError && execError.constructor.name === "GraphInterrupt") {
1081
- throw execError;
1082
- }
1099
+ error = handleNodeError(execError, `executor:${currentStep.description}`, false);
1083
1100
  success = false;
1084
- error = execError instanceof Error ? execError.message : "Unknown execution error";
1085
1101
  result = null;
1086
1102
  executorLogger.warn("Step execution failed", {
1087
1103
  stepId: currentStep.id,
@@ -1284,46 +1300,46 @@ function createPlanExecuteAgent(config) {
1284
1300
  }
1285
1301
 
1286
1302
  // src/reflection/state.ts
1287
- var import_zod6 = require("zod");
1303
+ var import_zod7 = require("zod");
1288
1304
  var import_core6 = require("@agentforge/core");
1289
1305
 
1290
1306
  // src/reflection/schemas.ts
1291
- var import_zod5 = require("zod");
1292
- var ReflectionSchema = import_zod5.z.object({
1307
+ var import_zod6 = require("zod");
1308
+ var ReflectionSchema = import_zod6.z.object({
1293
1309
  /**
1294
1310
  * The critique or feedback on the current response
1295
1311
  */
1296
- critique: import_zod5.z.string().describe("Critique or feedback on the current response"),
1312
+ critique: import_zod6.z.string().describe("Critique or feedback on the current response"),
1297
1313
  /**
1298
1314
  * Specific issues identified
1299
1315
  */
1300
- issues: import_zod5.z.array(import_zod5.z.string()).describe("Specific issues or problems identified"),
1316
+ issues: import_zod6.z.array(import_zod6.z.string()).describe("Specific issues or problems identified"),
1301
1317
  /**
1302
1318
  * Suggestions for improvement
1303
1319
  */
1304
- suggestions: import_zod5.z.array(import_zod5.z.string()).describe("Suggestions for improving the response"),
1320
+ suggestions: import_zod6.z.array(import_zod6.z.string()).describe("Suggestions for improving the response"),
1305
1321
  /**
1306
1322
  * Quality score (0-10)
1307
1323
  */
1308
- score: import_zod5.z.number().min(0).max(10).optional().describe("Quality score from 0 to 10"),
1324
+ score: import_zod6.z.number().min(0).max(10).optional().describe("Quality score from 0 to 10"),
1309
1325
  /**
1310
1326
  * Whether the response meets quality standards
1311
1327
  */
1312
- meetsStandards: import_zod5.z.boolean().describe("Whether the response meets quality standards"),
1328
+ meetsStandards: import_zod6.z.boolean().describe("Whether the response meets quality standards"),
1313
1329
  /**
1314
1330
  * Timestamp of the reflection
1315
1331
  */
1316
- timestamp: import_zod5.z.date().optional().describe("When this reflection was created")
1332
+ timestamp: import_zod6.z.date().optional().describe("When this reflection was created")
1317
1333
  });
1318
- var RevisionSchema = import_zod5.z.object({
1334
+ var RevisionSchema = import_zod6.z.object({
1319
1335
  /**
1320
1336
  * The revised content
1321
1337
  */
1322
- content: import_zod5.z.string().describe("The revised content"),
1338
+ content: import_zod6.z.string().describe("The revised content"),
1323
1339
  /**
1324
1340
  * Which iteration this revision is from
1325
1341
  */
1326
- iteration: import_zod5.z.number().int().nonnegative().describe("Iteration number"),
1342
+ iteration: import_zod6.z.number().int().nonnegative().describe("Iteration number"),
1327
1343
  /**
1328
1344
  * The reflection that prompted this revision
1329
1345
  */
@@ -1331,9 +1347,9 @@ var RevisionSchema = import_zod5.z.object({
1331
1347
  /**
1332
1348
  * Timestamp of the revision
1333
1349
  */
1334
- timestamp: import_zod5.z.date().optional().describe("When this revision was created")
1350
+ timestamp: import_zod6.z.date().optional().describe("When this revision was created")
1335
1351
  });
1336
- var ReflectionStatusSchema = import_zod5.z.enum([
1352
+ var ReflectionStatusSchema = import_zod6.z.enum([
1337
1353
  "generating",
1338
1354
  // Initial generation
1339
1355
  "reflecting",
@@ -1345,25 +1361,25 @@ var ReflectionStatusSchema = import_zod5.z.enum([
1345
1361
  "failed"
1346
1362
  // Max iterations reached without meeting standards
1347
1363
  ]);
1348
- var QualityCriteriaSchema = import_zod5.z.object({
1364
+ var QualityCriteriaSchema = import_zod6.z.object({
1349
1365
  /**
1350
1366
  * Minimum quality score required (0-10)
1351
1367
  */
1352
- minScore: import_zod5.z.number().min(0).max(10).default(7).describe("Minimum quality score required"),
1368
+ minScore: import_zod6.z.number().min(0).max(10).default(7).describe("Minimum quality score required"),
1353
1369
  /**
1354
1370
  * Specific criteria to evaluate
1355
1371
  */
1356
- criteria: import_zod5.z.array(import_zod5.z.string()).optional().describe("Specific criteria to evaluate"),
1372
+ criteria: import_zod6.z.array(import_zod6.z.string()).optional().describe("Specific criteria to evaluate"),
1357
1373
  /**
1358
1374
  * Whether all criteria must be met
1359
1375
  */
1360
- requireAll: import_zod5.z.boolean().default(true).describe("Whether all criteria must be met")
1376
+ requireAll: import_zod6.z.boolean().default(true).describe("Whether all criteria must be met")
1361
1377
  });
1362
- var ReflectionConfigSchema = import_zod5.z.object({
1378
+ var ReflectionConfigSchema = import_zod6.z.object({
1363
1379
  /**
1364
1380
  * Maximum number of reflection iterations
1365
1381
  */
1366
- maxIterations: import_zod5.z.number().int().positive().default(3).describe("Maximum reflection iterations"),
1382
+ maxIterations: import_zod6.z.number().int().positive().default(3).describe("Maximum reflection iterations"),
1367
1383
  /**
1368
1384
  * Quality criteria for completion
1369
1385
  */
@@ -1371,7 +1387,7 @@ var ReflectionConfigSchema = import_zod5.z.object({
1371
1387
  /**
1372
1388
  * Whether to include previous reflections in context
1373
1389
  */
1374
- includeHistory: import_zod5.z.boolean().default(true).describe("Include previous reflections in context")
1390
+ includeHistory: import_zod6.z.boolean().default(true).describe("Include previous reflections in context")
1375
1391
  });
1376
1392
 
1377
1393
  // src/reflection/state.ts
@@ -1379,16 +1395,12 @@ var ReflectionStateConfig = {
1379
1395
  /**
1380
1396
  * Original user input/task
1381
1397
  */
1382
- input: {
1383
- schema: import_zod6.z.string(),
1384
- default: () => "",
1385
- description: "Original user input or task"
1386
- },
1398
+ input: inputField,
1387
1399
  /**
1388
1400
  * Current response/output
1389
1401
  */
1390
1402
  currentResponse: {
1391
- schema: import_zod6.z.string().optional(),
1403
+ schema: import_zod7.z.string().optional(),
1392
1404
  description: "Current response or output"
1393
1405
  },
1394
1406
  /**
@@ -1396,7 +1408,7 @@ var ReflectionStateConfig = {
1396
1408
  * Accumulates all reflections
1397
1409
  */
1398
1410
  reflections: {
1399
- schema: import_zod6.z.array(ReflectionSchema),
1411
+ schema: import_zod7.z.array(ReflectionSchema),
1400
1412
  reducer: (left, right) => [...left, ...right],
1401
1413
  default: () => [],
1402
1414
  description: "History of all reflections and critiques"
@@ -1406,7 +1418,7 @@ var ReflectionStateConfig = {
1406
1418
  * Accumulates all revisions
1407
1419
  */
1408
1420
  revisions: {
1409
- schema: import_zod6.z.array(RevisionSchema),
1421
+ schema: import_zod7.z.array(RevisionSchema),
1410
1422
  reducer: (left, right) => [...left, ...right],
1411
1423
  default: () => [],
1412
1424
  description: "History of all revisions"
@@ -1414,12 +1426,7 @@ var ReflectionStateConfig = {
1414
1426
  /**
1415
1427
  * Current iteration number
1416
1428
  */
1417
- iteration: {
1418
- schema: import_zod6.z.number().int().nonnegative(),
1419
- reducer: (left, right) => left + right,
1420
- default: () => 0,
1421
- description: "Current iteration number"
1422
- },
1429
+ iteration: iterationField,
1423
1430
  /**
1424
1431
  * Current status
1425
1432
  */
@@ -1438,25 +1445,15 @@ var ReflectionStateConfig = {
1438
1445
  /**
1439
1446
  * Maximum iterations allowed
1440
1447
  */
1441
- maxIterations: {
1442
- schema: import_zod6.z.number().int().positive(),
1443
- default: () => 3,
1444
- description: "Maximum number of reflection iterations allowed"
1445
- },
1448
+ maxIterations: maxIterationsField(3),
1446
1449
  /**
1447
1450
  * Final response (when completed)
1448
1451
  */
1449
- response: {
1450
- schema: import_zod6.z.string().optional(),
1451
- description: "Final response after reflection process"
1452
- },
1452
+ response: responseField,
1453
1453
  /**
1454
1454
  * Error message if failed
1455
1455
  */
1456
- error: {
1457
- schema: import_zod6.z.string().optional(),
1458
- description: "Error message if reflection failed"
1459
- }
1456
+ error: errorField
1460
1457
  };
1461
1458
  var ReflectionState = (0, import_core6.createStateAnnotation)(ReflectionStateConfig);
1462
1459
 
@@ -1605,14 +1602,15 @@ ${lastReflection.critique}`;
1605
1602
  iteration: 1
1606
1603
  };
1607
1604
  } catch (error) {
1605
+ const errorMessage = handleNodeError(error, "generator", false);
1608
1606
  generatorLogger.error("Response generation failed", {
1609
1607
  attempt: state.iteration + 1,
1610
- error: error instanceof Error ? error.message : String(error),
1608
+ error: errorMessage,
1611
1609
  duration: Date.now() - startTime
1612
1610
  });
1613
1611
  return {
1614
1612
  status: "failed",
1615
- error: error instanceof Error ? error.message : "Unknown error in generator"
1613
+ error: errorMessage
1616
1614
  };
1617
1615
  }
1618
1616
  };
@@ -1694,14 +1692,15 @@ function createReflectorNode(config) {
1694
1692
  status: reflection.meetsStandards ? "completed" : "revising"
1695
1693
  };
1696
1694
  } catch (error) {
1695
+ const errorMessage = handleNodeError(error, "reflector", false);
1697
1696
  reflectorLogger.error("Reflection failed", {
1698
1697
  attempt: state.iteration,
1699
- error: error instanceof Error ? error.message : String(error),
1698
+ error: errorMessage,
1700
1699
  duration: Date.now() - startTime
1701
1700
  });
1702
1701
  return {
1703
1702
  status: "failed",
1704
- error: error instanceof Error ? error.message : "Unknown error in reflector"
1703
+ error: errorMessage
1705
1704
  };
1706
1705
  }
1707
1706
  };
@@ -1762,14 +1761,15 @@ ${revisionsText}`;
1762
1761
  iteration: 1
1763
1762
  };
1764
1763
  } catch (error) {
1764
+ const errorMessage = handleNodeError(error, "reviser", false);
1765
1765
  reviserLogger.error("Revision failed", {
1766
1766
  attempt: state.iteration,
1767
- error: error instanceof Error ? error.message : String(error),
1767
+ error: errorMessage,
1768
1768
  duration: Date.now() - startTime
1769
1769
  });
1770
1770
  return {
1771
1771
  status: "failed",
1772
- error: error instanceof Error ? error.message : "Unknown error in reviser"
1772
+ error: errorMessage
1773
1773
  };
1774
1774
  }
1775
1775
  };
@@ -1855,13 +1855,13 @@ function createReflectionAgent(config) {
1855
1855
  }
1856
1856
 
1857
1857
  // src/multi-agent/state.ts
1858
- var import_zod8 = require("zod");
1858
+ var import_zod9 = require("zod");
1859
1859
  var import_core7 = require("@agentforge/core");
1860
1860
 
1861
1861
  // src/multi-agent/schemas.ts
1862
- var import_zod7 = require("zod");
1863
- var AgentRoleSchema = import_zod7.z.enum(["supervisor", "worker"]);
1864
- var MessageTypeSchema = import_zod7.z.enum([
1862
+ var import_zod8 = require("zod");
1863
+ var AgentRoleSchema = import_zod8.z.enum(["supervisor", "worker"]);
1864
+ var MessageTypeSchema = import_zod8.z.enum([
1865
1865
  "user_input",
1866
1866
  // Initial user message
1867
1867
  "task_assignment",
@@ -1875,11 +1875,11 @@ var MessageTypeSchema = import_zod7.z.enum([
1875
1875
  "completion"
1876
1876
  // Final completion message
1877
1877
  ]);
1878
- var AgentMessageSchema = import_zod7.z.object({
1878
+ var AgentMessageSchema = import_zod8.z.object({
1879
1879
  /**
1880
1880
  * Unique identifier for the message
1881
1881
  */
1882
- id: import_zod7.z.string().describe("Unique message identifier"),
1882
+ id: import_zod8.z.string().describe("Unique message identifier"),
1883
1883
  /**
1884
1884
  * Type of message
1885
1885
  */
@@ -1887,25 +1887,25 @@ var AgentMessageSchema = import_zod7.z.object({
1887
1887
  /**
1888
1888
  * Agent that sent the message
1889
1889
  */
1890
- from: import_zod7.z.string().describe("Agent identifier that sent the message"),
1890
+ from: import_zod8.z.string().describe("Agent identifier that sent the message"),
1891
1891
  /**
1892
1892
  * Agent(s) that should receive the message
1893
1893
  */
1894
- to: import_zod7.z.union([import_zod7.z.string(), import_zod7.z.array(import_zod7.z.string())]).describe("Target agent(s)"),
1894
+ to: import_zod8.z.union([import_zod8.z.string(), import_zod8.z.array(import_zod8.z.string())]).describe("Target agent(s)"),
1895
1895
  /**
1896
1896
  * Message content
1897
1897
  */
1898
- content: import_zod7.z.string().describe("Message content"),
1898
+ content: import_zod8.z.string().describe("Message content"),
1899
1899
  /**
1900
1900
  * Optional metadata
1901
1901
  */
1902
- metadata: import_zod7.z.record(import_zod7.z.any()).optional().describe("Additional message metadata"),
1902
+ metadata: import_zod8.z.record(import_zod8.z.any()).optional().describe("Additional message metadata"),
1903
1903
  /**
1904
1904
  * Timestamp when message was created
1905
1905
  */
1906
- timestamp: import_zod7.z.number().describe("Timestamp when message was created")
1906
+ timestamp: import_zod8.z.number().describe("Timestamp when message was created")
1907
1907
  });
1908
- var RoutingStrategySchema = import_zod7.z.enum([
1908
+ var RoutingStrategySchema = import_zod8.z.enum([
1909
1909
  "llm-based",
1910
1910
  // LLM decides which agent to route to
1911
1911
  "rule-based",
@@ -1917,25 +1917,25 @@ var RoutingStrategySchema = import_zod7.z.enum([
1917
1917
  "load-balanced"
1918
1918
  // Route based on agent workload
1919
1919
  ]);
1920
- var RoutingDecisionSchema = import_zod7.z.object({
1920
+ var RoutingDecisionSchema = import_zod8.z.object({
1921
1921
  /**
1922
1922
  * Target agent to route to (single agent routing)
1923
1923
  * @deprecated Use targetAgents for parallel routing support
1924
1924
  */
1925
- targetAgent: import_zod7.z.string().nullable().default(null).describe("Agent to route the task to (single routing)"),
1925
+ targetAgent: import_zod8.z.string().nullable().default(null).describe("Agent to route the task to (single routing)"),
1926
1926
  /**
1927
1927
  * Target agents to route to (parallel routing)
1928
1928
  * When multiple agents are specified, they execute in parallel
1929
1929
  */
1930
- targetAgents: import_zod7.z.array(import_zod7.z.string()).nullable().default(null).describe("Agents to route the task to (parallel routing)"),
1930
+ targetAgents: import_zod8.z.array(import_zod8.z.string()).nullable().default(null).describe("Agents to route the task to (parallel routing)"),
1931
1931
  /**
1932
1932
  * Reasoning for the routing decision
1933
1933
  */
1934
- reasoning: import_zod7.z.string().default("").describe("Explanation for routing decision"),
1934
+ reasoning: import_zod8.z.string().default("").describe("Explanation for routing decision"),
1935
1935
  /**
1936
1936
  * Confidence in the routing decision (0-1)
1937
1937
  */
1938
- confidence: import_zod7.z.number().min(0).max(1).default(0.8).describe("Confidence score"),
1938
+ confidence: import_zod8.z.number().min(0).max(1).default(0.8).describe("Confidence score"),
1939
1939
  /**
1940
1940
  * Strategy used for routing
1941
1941
  */
@@ -1943,86 +1943,86 @@ var RoutingDecisionSchema = import_zod7.z.object({
1943
1943
  /**
1944
1944
  * Timestamp of the routing decision
1945
1945
  */
1946
- timestamp: import_zod7.z.number().default(() => Date.now()).describe("Timestamp of the decision")
1946
+ timestamp: import_zod8.z.number().default(() => Date.now()).describe("Timestamp of the decision")
1947
1947
  }).refine(
1948
1948
  (data) => data.targetAgent || data.targetAgents && data.targetAgents.length > 0,
1949
1949
  { message: "Either targetAgent or targetAgents must be provided" }
1950
1950
  );
1951
- var WorkerCapabilitiesSchema = import_zod7.z.object({
1951
+ var WorkerCapabilitiesSchema = import_zod8.z.object({
1952
1952
  /**
1953
1953
  * Skills/capabilities the agent has
1954
1954
  */
1955
- skills: import_zod7.z.array(import_zod7.z.string()).describe("List of agent skills"),
1955
+ skills: import_zod8.z.array(import_zod8.z.string()).describe("List of agent skills"),
1956
1956
  /**
1957
1957
  * Tools available to the agent
1958
1958
  */
1959
- tools: import_zod7.z.array(import_zod7.z.string()).describe("List of tool names available to agent"),
1959
+ tools: import_zod8.z.array(import_zod8.z.string()).describe("List of tool names available to agent"),
1960
1960
  /**
1961
1961
  * Whether the agent is currently available
1962
1962
  */
1963
- available: import_zod7.z.boolean().default(true).describe("Whether agent is available"),
1963
+ available: import_zod8.z.boolean().default(true).describe("Whether agent is available"),
1964
1964
  /**
1965
1965
  * Current workload (number of active tasks)
1966
1966
  */
1967
- currentWorkload: import_zod7.z.number().int().nonnegative().default(0).describe("Current number of active tasks")
1967
+ currentWorkload: import_zod8.z.number().int().nonnegative().default(0).describe("Current number of active tasks")
1968
1968
  });
1969
- var TaskAssignmentSchema = import_zod7.z.object({
1969
+ var TaskAssignmentSchema = import_zod8.z.object({
1970
1970
  /**
1971
1971
  * Unique assignment identifier
1972
1972
  */
1973
- id: import_zod7.z.string().describe("Unique assignment identifier"),
1973
+ id: import_zod8.z.string().describe("Unique assignment identifier"),
1974
1974
  /**
1975
1975
  * Worker ID assigned to the task
1976
1976
  */
1977
- workerId: import_zod7.z.string().describe("Worker identifier assigned to task"),
1977
+ workerId: import_zod8.z.string().describe("Worker identifier assigned to task"),
1978
1978
  /**
1979
1979
  * Task description
1980
1980
  */
1981
- task: import_zod7.z.string().describe("Description of the task"),
1981
+ task: import_zod8.z.string().describe("Description of the task"),
1982
1982
  /**
1983
1983
  * Task priority (1-10, higher is more urgent)
1984
1984
  */
1985
- priority: import_zod7.z.number().int().min(1).max(10).default(5).describe("Task priority"),
1985
+ priority: import_zod8.z.number().int().min(1).max(10).default(5).describe("Task priority"),
1986
1986
  /**
1987
1987
  * Timestamp when task was assigned
1988
1988
  */
1989
- assignedAt: import_zod7.z.number().describe("Timestamp when task was assigned"),
1989
+ assignedAt: import_zod8.z.number().describe("Timestamp when task was assigned"),
1990
1990
  /**
1991
1991
  * Optional deadline for task completion
1992
1992
  */
1993
- deadline: import_zod7.z.number().optional().describe("Optional task deadline timestamp")
1993
+ deadline: import_zod8.z.number().optional().describe("Optional task deadline timestamp")
1994
1994
  });
1995
- var TaskResultSchema = import_zod7.z.object({
1995
+ var TaskResultSchema = import_zod8.z.object({
1996
1996
  /**
1997
1997
  * Assignment identifier
1998
1998
  */
1999
- assignmentId: import_zod7.z.string().describe("Assignment identifier"),
1999
+ assignmentId: import_zod8.z.string().describe("Assignment identifier"),
2000
2000
  /**
2001
2001
  * Worker that completed the task
2002
2002
  */
2003
- workerId: import_zod7.z.string().describe("Worker that completed the task"),
2003
+ workerId: import_zod8.z.string().describe("Worker that completed the task"),
2004
2004
  /**
2005
2005
  * Whether the task succeeded
2006
2006
  */
2007
- success: import_zod7.z.boolean().describe("Whether the task succeeded"),
2007
+ success: import_zod8.z.boolean().describe("Whether the task succeeded"),
2008
2008
  /**
2009
2009
  * Task result/output
2010
2010
  */
2011
- result: import_zod7.z.string().describe("Task result or output"),
2011
+ result: import_zod8.z.string().describe("Task result or output"),
2012
2012
  /**
2013
2013
  * Optional error message if task failed
2014
2014
  */
2015
- error: import_zod7.z.string().optional().describe("Error message if task failed"),
2015
+ error: import_zod8.z.string().optional().describe("Error message if task failed"),
2016
2016
  /**
2017
2017
  * Timestamp when task was completed
2018
2018
  */
2019
- completedAt: import_zod7.z.number().describe("Timestamp when task was completed"),
2019
+ completedAt: import_zod8.z.number().describe("Timestamp when task was completed"),
2020
2020
  /**
2021
2021
  * Optional metadata about execution
2022
2022
  */
2023
- metadata: import_zod7.z.record(import_zod7.z.any()).optional().describe("Execution metadata")
2023
+ metadata: import_zod8.z.record(import_zod8.z.any()).optional().describe("Execution metadata")
2024
2024
  });
2025
- var MultiAgentStatusSchema = import_zod7.z.enum([
2025
+ var MultiAgentStatusSchema = import_zod8.z.enum([
2026
2026
  "initializing",
2027
2027
  // System is initializing
2028
2028
  "routing",
@@ -2038,27 +2038,27 @@ var MultiAgentStatusSchema = import_zod7.z.enum([
2038
2038
  "failed"
2039
2039
  // Task failed
2040
2040
  ]);
2041
- var HandoffRequestSchema = import_zod7.z.object({
2041
+ var HandoffRequestSchema = import_zod8.z.object({
2042
2042
  /**
2043
2043
  * Agent requesting the handoff
2044
2044
  */
2045
- from: import_zod7.z.string().describe("Agent requesting handoff"),
2045
+ from: import_zod8.z.string().describe("Agent requesting handoff"),
2046
2046
  /**
2047
2047
  * Target agent for handoff
2048
2048
  */
2049
- to: import_zod7.z.string().describe("Target agent for handoff"),
2049
+ to: import_zod8.z.string().describe("Target agent for handoff"),
2050
2050
  /**
2051
2051
  * Reason for handoff
2052
2052
  */
2053
- reason: import_zod7.z.string().describe("Reason for requesting handoff"),
2053
+ reason: import_zod8.z.string().describe("Reason for requesting handoff"),
2054
2054
  /**
2055
2055
  * Context to pass to next agent
2056
2056
  */
2057
- context: import_zod7.z.any().describe("Context to pass to next agent"),
2057
+ context: import_zod8.z.any().describe("Context to pass to next agent"),
2058
2058
  /**
2059
2059
  * Timestamp of handoff request
2060
2060
  */
2061
- timestamp: import_zod7.z.string().datetime().describe("ISO timestamp of handoff request")
2061
+ timestamp: import_zod8.z.string().datetime().describe("ISO timestamp of handoff request")
2062
2062
  });
2063
2063
 
2064
2064
  // src/multi-agent/state.ts
@@ -2066,17 +2066,13 @@ var MultiAgentStateConfig = {
2066
2066
  /**
2067
2067
  * Original user input/query
2068
2068
  */
2069
- input: {
2070
- schema: import_zod8.z.string(),
2071
- default: () => "",
2072
- description: "Original user input or query"
2073
- },
2069
+ input: inputField,
2074
2070
  /**
2075
2071
  * All messages in the multi-agent conversation
2076
2072
  * Accumulates all messages between agents
2077
2073
  */
2078
2074
  messages: {
2079
- schema: import_zod8.z.array(AgentMessageSchema),
2075
+ schema: import_zod9.z.array(AgentMessageSchema),
2080
2076
  reducer: (left, right) => [...left, ...right],
2081
2077
  default: () => [],
2082
2078
  description: "All messages in the multi-agent conversation"
@@ -2085,7 +2081,7 @@ var MultiAgentStateConfig = {
2085
2081
  * Available worker agents and their capabilities
2086
2082
  */
2087
2083
  workers: {
2088
- schema: import_zod8.z.record(import_zod8.z.string(), WorkerCapabilitiesSchema),
2084
+ schema: import_zod9.z.record(import_zod9.z.string(), WorkerCapabilitiesSchema),
2089
2085
  reducer: (left, right) => ({
2090
2086
  ...left,
2091
2087
  ...right
@@ -2097,7 +2093,7 @@ var MultiAgentStateConfig = {
2097
2093
  * Current active agent
2098
2094
  */
2099
2095
  currentAgent: {
2100
- schema: import_zod8.z.string().optional(),
2096
+ schema: import_zod9.z.string().optional(),
2101
2097
  description: "Identifier of the currently active agent"
2102
2098
  },
2103
2099
  /**
@@ -2105,7 +2101,7 @@ var MultiAgentStateConfig = {
2105
2101
  * Accumulates all routing decisions
2106
2102
  */
2107
2103
  routingHistory: {
2108
- schema: import_zod8.z.array(RoutingDecisionSchema),
2104
+ schema: import_zod9.z.array(RoutingDecisionSchema),
2109
2105
  reducer: (left, right) => [...left, ...right],
2110
2106
  default: () => [],
2111
2107
  description: "History of routing decisions"
@@ -2114,7 +2110,7 @@ var MultiAgentStateConfig = {
2114
2110
  * Active task assignments
2115
2111
  */
2116
2112
  activeAssignments: {
2117
- schema: import_zod8.z.array(TaskAssignmentSchema),
2113
+ schema: import_zod9.z.array(TaskAssignmentSchema),
2118
2114
  reducer: (left, right) => [...left, ...right],
2119
2115
  default: () => [],
2120
2116
  description: "Currently active task assignments"
@@ -2124,7 +2120,7 @@ var MultiAgentStateConfig = {
2124
2120
  * Accumulates all completed tasks
2125
2121
  */
2126
2122
  completedTasks: {
2127
- schema: import_zod8.z.array(TaskResultSchema),
2123
+ schema: import_zod9.z.array(TaskResultSchema),
2128
2124
  reducer: (left, right) => [...left, ...right],
2129
2125
  default: () => [],
2130
2126
  description: "Completed task results"
@@ -2134,7 +2130,7 @@ var MultiAgentStateConfig = {
2134
2130
  * Accumulates all handoff requests
2135
2131
  */
2136
2132
  handoffs: {
2137
- schema: import_zod8.z.array(HandoffRequestSchema),
2133
+ schema: import_zod9.z.array(HandoffRequestSchema),
2138
2134
  reducer: (left, right) => [...left, ...right],
2139
2135
  default: () => [],
2140
2136
  description: "Handoff requests between agents"
@@ -2150,99 +2146,24 @@ var MultiAgentStateConfig = {
2150
2146
  /**
2151
2147
  * Iteration counter
2152
2148
  */
2153
- iteration: {
2154
- schema: import_zod8.z.number().int().nonnegative(),
2155
- reducer: (left, right) => left + right,
2156
- default: () => 0,
2157
- description: "Current iteration number"
2158
- },
2149
+ iteration: iterationField,
2159
2150
  /**
2160
2151
  * Maximum iterations allowed
2161
2152
  */
2162
- maxIterations: {
2163
- schema: import_zod8.z.number().int().positive(),
2164
- default: () => 10,
2165
- description: "Maximum number of iterations allowed"
2166
- },
2153
+ maxIterations: maxIterationsField(10),
2167
2154
  /**
2168
2155
  * Final aggregated response
2169
2156
  */
2170
- response: {
2171
- schema: import_zod8.z.string().optional(),
2172
- description: "Final aggregated response"
2173
- },
2157
+ response: responseField,
2174
2158
  /**
2175
2159
  * Error message if execution failed
2176
2160
  */
2177
- error: {
2178
- schema: import_zod8.z.string().optional(),
2179
- description: "Error message if execution failed"
2180
- }
2161
+ error: errorField
2181
2162
  };
2182
2163
  var MultiAgentState = (0, import_core7.createStateAnnotation)(MultiAgentStateConfig);
2183
2164
 
2184
2165
  // src/multi-agent/routing.ts
2185
2166
  var import_messages4 = require("@langchain/core/messages");
2186
- var import_core8 = require("@agentforge/core");
2187
- var logLevel = process.env.LOG_LEVEL?.toLowerCase() || import_core8.LogLevel.INFO;
2188
- var logger = (0, import_core8.createLogger)("multi-agent:routing", { level: logLevel });
2189
- async function executeTools(toolCalls, tools) {
2190
- const results = [];
2191
- logger.debug("Executing tools", {
2192
- toolCallCount: toolCalls.length,
2193
- toolNames: toolCalls.map((tc) => tc.name)
2194
- });
2195
- for (const toolCall of toolCalls) {
2196
- const tool = tools.find((t) => t.metadata.name === toolCall.name);
2197
- if (!tool) {
2198
- logger.warn("Tool not found", {
2199
- toolName: toolCall.name,
2200
- availableTools: tools.map((t) => t.metadata.name)
2201
- });
2202
- results.push(new import_messages4.ToolMessage({
2203
- content: `Error: Tool '${toolCall.name}' not found`,
2204
- tool_call_id: toolCall.id
2205
- }));
2206
- continue;
2207
- }
2208
- try {
2209
- logger.debug("Executing tool", {
2210
- toolName: toolCall.name,
2211
- args: toolCall.args
2212
- });
2213
- const result = await tool.execute(toolCall.args);
2214
- const content = typeof result === "string" ? result : JSON.stringify(result);
2215
- logger.debug("Tool execution successful", {
2216
- toolName: toolCall.name,
2217
- resultLength: content.length
2218
- });
2219
- results.push(new import_messages4.ToolMessage({
2220
- content,
2221
- tool_call_id: toolCall.id
2222
- }));
2223
- } catch (error) {
2224
- logger.error("Tool execution failed", {
2225
- toolName: toolCall.name,
2226
- error: error.message
2227
- });
2228
- results.push(new import_messages4.ToolMessage({
2229
- content: `Error executing tool: ${error.message}`,
2230
- tool_call_id: toolCall.id
2231
- }));
2232
- }
2233
- }
2234
- logger.debug("Tool execution complete", {
2235
- successCount: results.filter((r) => {
2236
- const content = typeof r.content === "string" ? r.content : JSON.stringify(r.content);
2237
- return !content.startsWith("Error");
2238
- }).length,
2239
- errorCount: results.filter((r) => {
2240
- const content = typeof r.content === "string" ? r.content : JSON.stringify(r.content);
2241
- return content.startsWith("Error");
2242
- }).length
2243
- });
2244
- return results;
2245
- }
2246
2167
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2247
2168
 
2248
2169
  Your job is to:
@@ -2278,151 +2199,48 @@ Choose parallel routing when the task benefits from multiple perspectives or dat
2278
2199
  var llmBasedRouting = {
2279
2200
  name: "llm-based",
2280
2201
  async route(state, config) {
2281
- logger.info("Starting LLM-based routing", {
2282
- iteration: state.iteration,
2283
- availableWorkers: Object.keys(state.workers).length
2284
- });
2285
2202
  if (!config.model) {
2286
2203
  throw new Error("LLM-based routing requires a model to be configured");
2287
2204
  }
2288
2205
  const systemPrompt = config.systemPrompt || DEFAULT_SUPERVISOR_SYSTEM_PROMPT;
2289
- const maxRetries = config.maxToolRetries || 3;
2290
- const tools = config.tools || [];
2291
2206
  const workerInfo = Object.entries(state.workers).map(([id, caps]) => {
2292
2207
  const skills = caps.skills.join(", ");
2293
- const tools2 = caps.tools.join(", ");
2208
+ const tools = caps.tools.join(", ");
2294
2209
  const available = caps.available ? "available" : "busy";
2295
- return `- ${id}: Skills: [${skills}], Tools: [${tools2}], Status: ${available}, Workload: ${caps.currentWorkload}`;
2210
+ return `- ${id}: Skills: [${skills}], Tools: [${tools}], Status: ${available}, Workload: ${caps.currentWorkload}`;
2296
2211
  }).join("\n");
2297
- logger.debug("Worker capabilities", {
2298
- workers: Object.entries(state.workers).map(([id, caps]) => ({
2299
- id,
2300
- skills: caps.skills,
2301
- available: caps.available,
2302
- workload: caps.currentWorkload
2303
- }))
2304
- });
2305
2212
  const lastMessage = state.messages[state.messages.length - 1];
2306
2213
  const taskContext = lastMessage?.content || state.input;
2307
- logger.debug("Task context", {
2308
- taskLength: taskContext.length,
2309
- taskPreview: taskContext.substring(0, 100)
2310
- });
2311
2214
  const userPrompt = `Current task: ${taskContext}
2312
2215
 
2313
2216
  Available workers:
2314
2217
  ${workerInfo}
2315
2218
 
2316
2219
  Select the best worker(s) for this task and explain your reasoning.`;
2317
- const conversationHistory = [];
2318
- let attempt = 0;
2319
- while (attempt < maxRetries) {
2320
- logger.debug("LLM routing attempt", {
2321
- attempt: attempt + 1,
2322
- maxRetries,
2323
- conversationHistoryLength: conversationHistory.length
2324
- });
2325
- const messages = [
2326
- new import_messages4.SystemMessage(systemPrompt),
2327
- new import_messages4.HumanMessage(userPrompt),
2328
- ...conversationHistory
2329
- ];
2330
- const response = await config.model.invoke(messages);
2331
- if (response.tool_calls && response.tool_calls.length > 0) {
2332
- logger.info("LLM requested tool calls", {
2333
- toolCount: response.tool_calls.length,
2334
- toolNames: response.tool_calls.map((tc) => tc.name)
2335
- });
2336
- if (tools.length === 0) {
2337
- throw new Error("LLM requested tool calls but no tools are configured");
2338
- }
2339
- const toolResults = await executeTools(response.tool_calls, tools);
2340
- conversationHistory.push(
2341
- new import_messages4.AIMessage({ content: response.content || "", tool_calls: response.tool_calls }),
2342
- ...toolResults
2343
- );
2344
- attempt++;
2345
- logger.debug("Retrying routing with tool results", { attempt });
2346
- continue;
2347
- }
2348
- logger.debug("Parsing routing decision from LLM response");
2349
- let decision;
2350
- if (response && typeof response === "object" && ("targetAgent" in response || "targetAgents" in response)) {
2351
- logger.debug("Response is structured output", {
2352
- hasTargetAgent: "targetAgent" in response,
2353
- hasTargetAgents: "targetAgents" in response
2354
- });
2355
- decision = response;
2356
- } else if (response.content) {
2357
- if (typeof response.content === "string") {
2358
- try {
2359
- decision = JSON.parse(response.content);
2360
- logger.debug("Parsed JSON from string response");
2361
- } catch (error) {
2362
- logger.error("Failed to parse routing decision", {
2363
- content: response.content,
2364
- error: error instanceof Error ? error.message : String(error)
2365
- });
2366
- throw new Error(`Failed to parse routing decision from LLM. Expected JSON but got: ${response.content}`);
2367
- }
2368
- } else if (typeof response.content === "object") {
2369
- logger.debug("Response content is already an object");
2370
- decision = response.content;
2371
- } else {
2372
- logger.error("Unexpected response content type", {
2373
- type: typeof response.content
2374
- });
2375
- throw new Error(`Unexpected response content type: ${typeof response.content}`);
2376
- }
2377
- } else {
2378
- logger.error("Unexpected response format", {
2379
- response: JSON.stringify(response)
2380
- });
2381
- throw new Error(`Unexpected response format: ${JSON.stringify(response)}`);
2382
- }
2383
- const result = {
2384
- targetAgent: decision.targetAgent,
2385
- targetAgents: decision.targetAgents,
2386
- reasoning: decision.reasoning,
2387
- confidence: decision.confidence,
2388
- strategy: "llm-based",
2389
- timestamp: Date.now()
2390
- };
2391
- logger.info("LLM routing decision made", {
2392
- targetAgent: result.targetAgent,
2393
- targetAgents: result.targetAgents,
2394
- isParallel: result.targetAgents && result.targetAgents.length > 1,
2395
- confidence: result.confidence,
2396
- reasoning: result.reasoning
2397
- });
2398
- return result;
2399
- }
2400
- logger.error("Max tool retries exceeded", { maxRetries });
2401
- throw new Error(`Max tool retries (${maxRetries}) exceeded without routing decision`);
2220
+ const messages = [
2221
+ new import_messages4.SystemMessage(systemPrompt),
2222
+ new import_messages4.HumanMessage(userPrompt)
2223
+ ];
2224
+ const decision = await config.model.invoke(messages);
2225
+ return {
2226
+ targetAgent: decision.targetAgent,
2227
+ targetAgents: decision.targetAgents,
2228
+ reasoning: decision.reasoning,
2229
+ confidence: decision.confidence,
2230
+ strategy: "llm-based",
2231
+ timestamp: Date.now()
2232
+ };
2402
2233
  }
2403
2234
  };
2404
2235
  var roundRobinRouting = {
2405
2236
  name: "round-robin",
2406
2237
  async route(state, config) {
2407
- logger.info("Starting round-robin routing", {
2408
- iteration: state.iteration
2409
- });
2410
2238
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id]) => id);
2411
- logger.debug("Available workers for round-robin", {
2412
- count: availableWorkers.length,
2413
- workers: availableWorkers
2414
- });
2415
2239
  if (availableWorkers.length === 0) {
2416
- logger.error("No available workers for round-robin routing");
2417
2240
  throw new Error("No available workers for round-robin routing");
2418
2241
  }
2419
2242
  const lastRoutingIndex = state.routingHistory.length % availableWorkers.length;
2420
2243
  const targetAgent = availableWorkers[lastRoutingIndex];
2421
- logger.info("Round-robin routing decision", {
2422
- targetAgent,
2423
- index: lastRoutingIndex + 1,
2424
- totalWorkers: availableWorkers.length
2425
- });
2426
2244
  return {
2427
2245
  targetAgent,
2428
2246
  targetAgents: null,
@@ -2436,15 +2254,8 @@ var roundRobinRouting = {
2436
2254
  var skillBasedRouting = {
2437
2255
  name: "skill-based",
2438
2256
  async route(state, config) {
2439
- logger.info("Starting skill-based routing", {
2440
- iteration: state.iteration
2441
- });
2442
2257
  const lastMessage = state.messages[state.messages.length - 1];
2443
2258
  const taskContent = (lastMessage?.content || state.input).toLowerCase();
2444
- logger.debug("Task content for skill matching", {
2445
- taskLength: taskContent.length,
2446
- taskPreview: taskContent.substring(0, 100)
2447
- });
2448
2259
  const workerScores = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => {
2449
2260
  const skillMatches = caps.skills.filter(
2450
2261
  (skill) => taskContent.includes(skill.toLowerCase())
@@ -2455,20 +2266,11 @@ var skillBasedRouting = {
2455
2266
  const score = skillMatches * 2 + toolMatches;
2456
2267
  return { id, score, skills: caps.skills, tools: caps.tools };
2457
2268
  }).filter((w) => w.score > 0).sort((a, b) => b.score - a.score);
2458
- logger.debug("Worker skill scores", {
2459
- scoredWorkers: workerScores.map((w) => ({ id: w.id, score: w.score }))
2460
- });
2461
2269
  if (workerScores.length === 0) {
2462
- logger.warn("No skill matches found, using fallback");
2463
2270
  const firstAvailable = Object.entries(state.workers).find(([_, caps]) => caps.available);
2464
2271
  if (!firstAvailable) {
2465
- logger.error("No available workers for skill-based routing");
2466
2272
  throw new Error("No available workers for skill-based routing");
2467
2273
  }
2468
- logger.info("Skill-based routing fallback decision", {
2469
- targetAgent: firstAvailable[0],
2470
- confidence: 0.5
2471
- });
2472
2274
  return {
2473
2275
  targetAgent: firstAvailable[0],
2474
2276
  targetAgents: null,
@@ -2480,12 +2282,6 @@ var skillBasedRouting = {
2480
2282
  }
2481
2283
  const best = workerScores[0];
2482
2284
  const confidence = Math.min(best.score / 5, 1);
2483
- logger.info("Skill-based routing decision", {
2484
- targetAgent: best.id,
2485
- score: best.score,
2486
- confidence,
2487
- matchedSkills: best.skills
2488
- });
2489
2285
  return {
2490
2286
  targetAgent: best.id,
2491
2287
  targetAgents: null,
@@ -2499,26 +2295,13 @@ var skillBasedRouting = {
2499
2295
  var loadBalancedRouting = {
2500
2296
  name: "load-balanced",
2501
2297
  async route(state, config) {
2502
- logger.info("Starting load-balanced routing", {
2503
- iteration: state.iteration
2504
- });
2505
2298
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => ({ id, workload: caps.currentWorkload })).sort((a, b) => a.workload - b.workload);
2506
- logger.debug("Worker workloads", {
2507
- workers: availableWorkers.map((w) => ({ id: w.id, workload: w.workload }))
2508
- });
2509
2299
  if (availableWorkers.length === 0) {
2510
- logger.error("No available workers for load-balanced routing");
2511
2300
  throw new Error("No available workers for load-balanced routing");
2512
2301
  }
2513
2302
  const targetWorker = availableWorkers[0];
2514
2303
  const avgWorkload = availableWorkers.reduce((sum, w) => sum + w.workload, 0) / availableWorkers.length;
2515
2304
  const confidence = targetWorker.workload === 0 ? 1 : Math.max(0.5, 1 - targetWorker.workload / (avgWorkload * 2));
2516
- logger.info("Load-balanced routing decision", {
2517
- targetAgent: targetWorker.id,
2518
- workload: targetWorker.workload,
2519
- avgWorkload: avgWorkload.toFixed(1),
2520
- confidence
2521
- });
2522
2305
  return {
2523
2306
  targetAgent: targetWorker.id,
2524
2307
  targetAgents: null,
@@ -2532,24 +2315,13 @@ var loadBalancedRouting = {
2532
2315
  var ruleBasedRouting = {
2533
2316
  name: "rule-based",
2534
2317
  async route(state, config) {
2535
- logger.info("Starting rule-based routing", {
2536
- iteration: state.iteration
2537
- });
2538
2318
  if (!config.routingFn) {
2539
- logger.error("Rule-based routing requires a custom routing function");
2540
2319
  throw new Error("Rule-based routing requires a custom routing function");
2541
2320
  }
2542
- const decision = await config.routingFn(state);
2543
- logger.info("Rule-based routing decision", {
2544
- targetAgent: decision.targetAgent,
2545
- targetAgents: decision.targetAgents,
2546
- confidence: decision.confidence
2547
- });
2548
- return decision;
2321
+ return await config.routingFn(state);
2549
2322
  }
2550
2323
  };
2551
2324
  function getRoutingStrategy(name) {
2552
- logger.debug("Getting routing strategy", { name });
2553
2325
  switch (name) {
2554
2326
  case "llm-based":
2555
2327
  return llmBasedRouting;
@@ -2562,15 +2334,14 @@ function getRoutingStrategy(name) {
2562
2334
  case "rule-based":
2563
2335
  return ruleBasedRouting;
2564
2336
  default:
2565
- logger.error("Unknown routing strategy", { name });
2566
2337
  throw new Error(`Unknown routing strategy: ${name}`);
2567
2338
  }
2568
2339
  }
2569
2340
 
2570
2341
  // src/multi-agent/utils.ts
2571
- var import_core9 = require("@agentforge/core");
2572
- var logLevel2 = process.env.LOG_LEVEL?.toLowerCase() || import_core9.LogLevel.INFO;
2573
- var logger2 = (0, import_core9.createLogger)("multi-agent", { level: logLevel2 });
2342
+ var import_core8 = require("@agentforge/core");
2343
+ var logLevel = process.env.LOG_LEVEL?.toLowerCase() || import_core8.LogLevel.INFO;
2344
+ var logger = (0, import_core8.createLogger)("multi-agent", { level: logLevel });
2574
2345
  function isReActAgent(obj) {
2575
2346
  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
2576
2347
  (obj.constructor?.name === "CompiledGraph" || obj.constructor?.name === "CompiledStateGraph");
@@ -2578,9 +2349,9 @@ function isReActAgent(obj) {
2578
2349
  function wrapReActAgent(workerId, agent, verbose = false) {
2579
2350
  return async (state, config) => {
2580
2351
  try {
2581
- logger2.debug("Wrapping ReAct agent execution", { workerId });
2352
+ logger.debug("Wrapping ReAct agent execution", { workerId });
2582
2353
  const task = state.messages[state.messages.length - 1]?.content || state.input;
2583
- logger2.debug("Extracted task", {
2354
+ logger.debug("Extracted task", {
2584
2355
  workerId,
2585
2356
  taskPreview: task.substring(0, 100) + (task.length > 100 ? "..." : "")
2586
2357
  });
@@ -2588,7 +2359,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2588
2359
  (assignment) => assignment.workerId === workerId && !state.completedTasks.some((task2) => task2.assignmentId === assignment.id)
2589
2360
  );
2590
2361
  if (!currentAssignment) {
2591
- logger2.debug("No active assignment found", { workerId });
2362
+ logger.debug("No active assignment found", { workerId });
2592
2363
  return {};
2593
2364
  }
2594
2365
  const result = await agent.invoke(
@@ -2599,14 +2370,14 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2599
2370
  // Pass through the config for checkpointing and interrupt support
2600
2371
  );
2601
2372
  const response = result.messages?.[result.messages.length - 1]?.content || "No response";
2602
- logger2.debug("Received response from ReAct agent", {
2373
+ logger.debug("Received response from ReAct agent", {
2603
2374
  workerId,
2604
2375
  responsePreview: response.substring(0, 100) + (response.length > 100 ? "..." : "")
2605
2376
  });
2606
2377
  const toolsUsed = result.actions?.map((action) => action.name).filter(Boolean) || [];
2607
2378
  const uniqueTools = [...new Set(toolsUsed)];
2608
2379
  if (uniqueTools.length > 0) {
2609
- logger2.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2380
+ logger.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2610
2381
  }
2611
2382
  const taskResult = {
2612
2383
  assignmentId: currentAssignment.id,
@@ -2624,14 +2395,10 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2624
2395
  completedTasks: [taskResult]
2625
2396
  };
2626
2397
  } catch (error) {
2627
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
2628
- logger2.debug("GraphInterrupt detected - re-throwing", { workerId });
2629
- throw error;
2630
- }
2631
- logger2.error("Error in ReAct agent execution", {
2398
+ const errorMessage = handleNodeError(error, `react-agent:${workerId}`, false);
2399
+ logger.error("Error in ReAct agent execution", {
2632
2400
  workerId,
2633
- error: error instanceof Error ? error.message : String(error),
2634
- stack: error instanceof Error ? error.stack : void 0
2401
+ error: errorMessage
2635
2402
  });
2636
2403
  const currentAssignment = state.activeAssignments.find(
2637
2404
  (assignment) => assignment.workerId === workerId
@@ -2642,7 +2409,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2642
2409
  workerId,
2643
2410
  success: false,
2644
2411
  result: "",
2645
- error: error instanceof Error ? error.message : "Unknown error in ReAct agent",
2412
+ error: errorMessage,
2646
2413
  completedAt: Date.now()
2647
2414
  };
2648
2415
  return {
@@ -2653,7 +2420,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2653
2420
  }
2654
2421
  return {
2655
2422
  status: "failed",
2656
- error: error instanceof Error ? error.message : `Unknown error in ReAct wrapper for ${workerId}`
2423
+ error: errorMessage
2657
2424
  };
2658
2425
  }
2659
2426
  };
@@ -2661,9 +2428,9 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2661
2428
 
2662
2429
  // src/multi-agent/nodes.ts
2663
2430
  var import_messages5 = require("@langchain/core/messages");
2664
- var import_core10 = require("@agentforge/core");
2665
- var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || import_core10.LogLevel.INFO;
2666
- var logger3 = (0, import_core10.createLogger)("multi-agent:nodes", { level: logLevel3 });
2431
+ var import_core9 = require("@agentforge/core");
2432
+ var logLevel2 = process.env.LOG_LEVEL?.toLowerCase() || import_core9.LogLevel.INFO;
2433
+ var logger2 = (0, import_core9.createLogger)("multi-agent:nodes", { level: logLevel2 });
2667
2434
  var DEFAULT_AGGREGATOR_SYSTEM_PROMPT = `You are an aggregator agent responsible for combining results from multiple worker agents.
2668
2435
 
2669
2436
  Your job is to:
@@ -2681,19 +2448,19 @@ function createSupervisorNode(config) {
2681
2448
  } = config;
2682
2449
  return async (state) => {
2683
2450
  try {
2684
- logger3.info("Supervisor node executing", {
2451
+ logger2.info("Supervisor node executing", {
2685
2452
  iteration: state.iteration,
2686
2453
  maxIterations,
2687
2454
  activeAssignments: state.activeAssignments.length,
2688
2455
  completedTasks: state.completedTasks.length
2689
2456
  });
2690
- logger3.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2457
+ logger2.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2691
2458
  if (state.iteration >= maxIterations) {
2692
- logger3.warn("Max iterations reached", {
2459
+ logger2.warn("Max iterations reached", {
2693
2460
  iteration: state.iteration,
2694
2461
  maxIterations
2695
2462
  });
2696
- logger3.debug("Max iterations reached, moving to aggregation");
2463
+ logger2.debug("Max iterations reached, moving to aggregation");
2697
2464
  return {
2698
2465
  status: "aggregating",
2699
2466
  currentAgent: "aggregator"
@@ -2702,26 +2469,26 @@ function createSupervisorNode(config) {
2702
2469
  const allCompleted = state.activeAssignments.every(
2703
2470
  (assignment) => state.completedTasks.some((task2) => task2.assignmentId === assignment.id)
2704
2471
  );
2705
- logger3.debug("Checking task completion", {
2472
+ logger2.debug("Checking task completion", {
2706
2473
  activeAssignments: state.activeAssignments.length,
2707
2474
  completedTasks: state.completedTasks.length,
2708
2475
  allCompleted
2709
2476
  });
2710
2477
  if (allCompleted && state.activeAssignments.length > 0) {
2711
- logger3.info("All tasks completed, moving to aggregation", {
2478
+ logger2.info("All tasks completed, moving to aggregation", {
2712
2479
  completedCount: state.completedTasks.length
2713
2480
  });
2714
- logger3.debug("All tasks completed, moving to aggregation");
2481
+ logger2.debug("All tasks completed, moving to aggregation");
2715
2482
  return {
2716
2483
  status: "aggregating",
2717
2484
  currentAgent: "aggregator"
2718
2485
  };
2719
2486
  }
2720
- logger3.debug("Getting routing strategy", { strategy });
2487
+ logger2.debug("Getting routing strategy", { strategy });
2721
2488
  const routingImpl = getRoutingStrategy(strategy);
2722
2489
  const decision = await routingImpl.route(state, config);
2723
2490
  const targetAgents = decision.targetAgents && decision.targetAgents.length > 0 ? decision.targetAgents : decision.targetAgent ? [decision.targetAgent] : [];
2724
- logger3.debug("Target agents determined", {
2491
+ logger2.debug("Target agents determined", {
2725
2492
  targetAgents,
2726
2493
  isParallel: targetAgents.length > 1,
2727
2494
  decision: {
@@ -2730,17 +2497,17 @@ function createSupervisorNode(config) {
2730
2497
  }
2731
2498
  });
2732
2499
  if (targetAgents.length === 0) {
2733
- logger3.error("No target agents specified in routing decision");
2500
+ logger2.error("No target agents specified in routing decision");
2734
2501
  throw new Error("Routing decision must specify at least one target agent");
2735
2502
  }
2736
2503
  if (targetAgents.length === 1) {
2737
- logger3.info("Routing to single agent", {
2504
+ logger2.info("Routing to single agent", {
2738
2505
  targetAgent: targetAgents[0],
2739
2506
  reasoning: decision.reasoning,
2740
2507
  confidence: decision.confidence
2741
2508
  });
2742
2509
  } else {
2743
- logger3.info("Routing to multiple agents in parallel", {
2510
+ logger2.info("Routing to multiple agents in parallel", {
2744
2511
  targetAgents,
2745
2512
  count: targetAgents.length,
2746
2513
  reasoning: decision.reasoning,
@@ -2748,9 +2515,9 @@ function createSupervisorNode(config) {
2748
2515
  });
2749
2516
  }
2750
2517
  if (targetAgents.length === 1) {
2751
- logger3.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2518
+ logger2.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2752
2519
  } else {
2753
- logger3.debug(`Routing to ${targetAgents.length} agents in parallel [${targetAgents.join(", ")}]: ${decision.reasoning}`);
2520
+ logger2.debug(`Routing to ${targetAgents.length} agents in parallel [${targetAgents.join(", ")}]: ${decision.reasoning}`);
2754
2521
  }
2755
2522
  const task = state.messages[state.messages.length - 1]?.content || state.input;
2756
2523
  const assignments = targetAgents.map((workerId) => ({
@@ -2760,7 +2527,7 @@ function createSupervisorNode(config) {
2760
2527
  priority: 5,
2761
2528
  assignedAt: Date.now()
2762
2529
  }));
2763
- logger3.debug("Created task assignments", {
2530
+ logger2.debug("Created task assignments", {
2764
2531
  assignmentCount: assignments.length,
2765
2532
  assignments: assignments.map((a) => ({
2766
2533
  id: a.id,
@@ -2780,7 +2547,7 @@ function createSupervisorNode(config) {
2780
2547
  priority: assignment.priority
2781
2548
  }
2782
2549
  }));
2783
- logger3.info("Supervisor routing complete", {
2550
+ logger2.info("Supervisor routing complete", {
2784
2551
  currentAgent: targetAgents.join(","),
2785
2552
  status: "executing",
2786
2553
  assignmentCount: assignments.length,
@@ -2797,7 +2564,7 @@ function createSupervisorNode(config) {
2797
2564
  iteration: state.iteration + 1
2798
2565
  };
2799
2566
  } catch (error) {
2800
- logger3.error("Supervisor node error", {
2567
+ logger2.error("Supervisor node error", {
2801
2568
  error: error instanceof Error ? error.message : String(error),
2802
2569
  stack: error instanceof Error ? error.stack : void 0,
2803
2570
  iteration: state.iteration
@@ -2822,7 +2589,7 @@ function createWorkerNode(config) {
2822
2589
  } = config;
2823
2590
  return async (state, runConfig) => {
2824
2591
  try {
2825
- logger3.info("Worker node executing", {
2592
+ logger2.info("Worker node executing", {
2826
2593
  workerId: id,
2827
2594
  iteration: state.iteration,
2828
2595
  activeAssignments: state.activeAssignments.length
@@ -2831,39 +2598,39 @@ function createWorkerNode(config) {
2831
2598
  (assignment) => assignment.workerId === id && !state.completedTasks.some((task) => task.assignmentId === assignment.id)
2832
2599
  );
2833
2600
  if (!currentAssignment) {
2834
- logger3.debug("No active assignment found for worker", {
2601
+ logger2.debug("No active assignment found for worker", {
2835
2602
  workerId: id,
2836
2603
  totalActiveAssignments: state.activeAssignments.length,
2837
2604
  completedTasks: state.completedTasks.length
2838
2605
  });
2839
2606
  return {};
2840
2607
  }
2841
- logger3.info("Worker processing assignment", {
2608
+ logger2.info("Worker processing assignment", {
2842
2609
  workerId: id,
2843
2610
  assignmentId: currentAssignment.id,
2844
2611
  taskLength: currentAssignment.task.length,
2845
2612
  taskPreview: currentAssignment.task.substring(0, 100)
2846
2613
  });
2847
2614
  if (executeFn) {
2848
- logger3.debug("Using custom execution function", { workerId: id });
2615
+ logger2.debug("Using custom execution function", { workerId: id });
2849
2616
  return await executeFn(state, runConfig);
2850
2617
  }
2851
2618
  if (agent) {
2852
2619
  if (isReActAgent(agent)) {
2853
- logger3.debug("Using ReAct agent", { workerId: id });
2620
+ logger2.debug("Using ReAct agent", { workerId: id });
2854
2621
  const wrappedFn = wrapReActAgent(id, agent, verbose);
2855
2622
  return await wrappedFn(state, runConfig);
2856
2623
  } else {
2857
- logger3.warn("Agent provided but not a ReAct agent, falling back", { workerId: id });
2624
+ logger2.warn("Agent provided but not a ReAct agent, falling back", { workerId: id });
2858
2625
  }
2859
2626
  }
2860
2627
  if (!model) {
2861
- logger3.error("Worker missing required configuration", { workerId: id });
2628
+ logger2.error("Worker missing required configuration", { workerId: id });
2862
2629
  throw new Error(
2863
2630
  `Worker ${id} requires either a model, an agent, or a custom execution function. Provide one of: config.model, config.agent, or config.executeFn`
2864
2631
  );
2865
2632
  }
2866
- logger3.debug("Using default LLM execution", {
2633
+ logger2.debug("Using default LLM execution", {
2867
2634
  workerId: id,
2868
2635
  hasTools: tools.length > 0,
2869
2636
  toolCount: tools.length
@@ -2879,18 +2646,18 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2879
2646
  ];
2880
2647
  let modelToUse = model;
2881
2648
  if (tools.length > 0 && model.bindTools) {
2882
- logger3.debug("Binding tools to model", {
2649
+ logger2.debug("Binding tools to model", {
2883
2650
  workerId: id,
2884
2651
  toolCount: tools.length,
2885
2652
  toolNames: tools.map((t) => t.metadata.name)
2886
2653
  });
2887
- const langchainTools = (0, import_core10.toLangChainTools)(tools);
2654
+ const langchainTools = (0, import_core9.toLangChainTools)(tools);
2888
2655
  modelToUse = model.bindTools(langchainTools);
2889
2656
  }
2890
- logger3.debug("Invoking LLM", { workerId: id });
2657
+ logger2.debug("Invoking LLM", { workerId: id });
2891
2658
  const response = await modelToUse.invoke(messages);
2892
2659
  const result = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
2893
- logger3.info("Worker task completed", {
2660
+ logger2.info("Worker task completed", {
2894
2661
  workerId: id,
2895
2662
  assignmentId: currentAssignment.id,
2896
2663
  resultLength: result.length,
@@ -2925,7 +2692,7 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2925
2692
  currentWorkload: Math.max(0, capabilities.currentWorkload - 1)
2926
2693
  }
2927
2694
  };
2928
- logger3.debug("Worker state update", {
2695
+ logger2.debug("Worker state update", {
2929
2696
  workerId: id,
2930
2697
  newWorkload: updatedWorkers[id].currentWorkload
2931
2698
  });
@@ -2935,20 +2702,16 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2935
2702
  workers: updatedWorkers
2936
2703
  };
2937
2704
  } catch (error) {
2938
- if (error && typeof error === "object" && "constructor" in error && error.constructor.name === "GraphInterrupt") {
2939
- logger3.info("GraphInterrupt detected, re-throwing", { workerId: id });
2940
- throw error;
2941
- }
2942
- logger3.error("Worker node error", {
2705
+ const errorMessage = handleNodeError(error, `worker:${id}`, false);
2706
+ logger2.error("Worker node error", {
2943
2707
  workerId: id,
2944
- error: error instanceof Error ? error.message : String(error),
2945
- stack: error instanceof Error ? error.stack : void 0
2708
+ error: errorMessage
2946
2709
  });
2947
2710
  const currentAssignment = state.activeAssignments.find(
2948
2711
  (assignment) => assignment.workerId === id
2949
2712
  );
2950
2713
  if (currentAssignment) {
2951
- logger3.warn("Creating error result for assignment", {
2714
+ logger2.warn("Creating error result for assignment", {
2952
2715
  workerId: id,
2953
2716
  assignmentId: currentAssignment.id
2954
2717
  });
@@ -2957,7 +2720,7 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2957
2720
  workerId: id,
2958
2721
  success: false,
2959
2722
  result: "",
2960
- error: error instanceof Error ? error.message : "Unknown error",
2723
+ error: errorMessage,
2961
2724
  completedAt: Date.now()
2962
2725
  };
2963
2726
  return {
@@ -2966,10 +2729,10 @@ Execute the assigned task using your skills and tools. Provide a clear, actionab
2966
2729
  status: "routing"
2967
2730
  };
2968
2731
  }
2969
- logger3.error("No assignment found for error handling", { workerId: id });
2732
+ logger2.error("No assignment found for error handling", { workerId: id });
2970
2733
  return {
2971
2734
  status: "failed",
2972
- error: error instanceof Error ? error.message : `Unknown error in worker ${id}`
2735
+ error: errorMessage
2973
2736
  };
2974
2737
  }
2975
2738
  };
@@ -2983,16 +2746,16 @@ function createAggregatorNode(config = {}) {
2983
2746
  } = config;
2984
2747
  return async (state) => {
2985
2748
  try {
2986
- logger3.info("Aggregator node executing", {
2749
+ logger2.info("Aggregator node executing", {
2987
2750
  completedTasks: state.completedTasks.length,
2988
2751
  successfulTasks: state.completedTasks.filter((t) => t.success).length,
2989
2752
  failedTasks: state.completedTasks.filter((t) => !t.success).length
2990
2753
  });
2991
- logger3.debug("Combining results from workers");
2754
+ logger2.debug("Combining results from workers");
2992
2755
  if (aggregateFn) {
2993
- logger3.debug("Using custom aggregation function");
2756
+ logger2.debug("Using custom aggregation function");
2994
2757
  const response2 = await aggregateFn(state);
2995
- logger3.info("Custom aggregation complete", {
2758
+ logger2.info("Custom aggregation complete", {
2996
2759
  responseLength: response2.length
2997
2760
  });
2998
2761
  return {
@@ -3001,16 +2764,16 @@ function createAggregatorNode(config = {}) {
3001
2764
  };
3002
2765
  }
3003
2766
  if (state.completedTasks.length === 0) {
3004
- logger3.warn("No completed tasks to aggregate");
2767
+ logger2.warn("No completed tasks to aggregate");
3005
2768
  return {
3006
2769
  response: "No tasks were completed.",
3007
2770
  status: "completed"
3008
2771
  };
3009
2772
  }
3010
2773
  if (!model) {
3011
- logger3.debug("No model provided, concatenating results");
2774
+ logger2.debug("No model provided, concatenating results");
3012
2775
  const combinedResults = state.completedTasks.filter((task) => task.success).map((task) => task.result).join("\n\n");
3013
- logger3.info("Simple concatenation complete", {
2776
+ logger2.info("Simple concatenation complete", {
3014
2777
  resultLength: combinedResults.length
3015
2778
  });
3016
2779
  return {
@@ -3018,7 +2781,7 @@ function createAggregatorNode(config = {}) {
3018
2781
  status: "completed"
3019
2782
  };
3020
2783
  }
3021
- logger3.debug("Using LLM for intelligent aggregation", {
2784
+ logger2.debug("Using LLM for intelligent aggregation", {
3022
2785
  taskCount: state.completedTasks.length
3023
2786
  });
3024
2787
  const taskResults = state.completedTasks.map((task, idx) => {
@@ -3037,20 +2800,20 @@ Please synthesize these results into a comprehensive response that addresses the
3037
2800
  new import_messages5.SystemMessage(systemPrompt),
3038
2801
  new import_messages5.HumanMessage(userPrompt)
3039
2802
  ];
3040
- logger3.debug("Invoking aggregation LLM");
2803
+ logger2.debug("Invoking aggregation LLM");
3041
2804
  const response = await model.invoke(messages);
3042
2805
  const aggregatedResponse = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
3043
- logger3.info("Aggregation complete", {
2806
+ logger2.info("Aggregation complete", {
3044
2807
  responseLength: aggregatedResponse.length,
3045
2808
  responsePreview: aggregatedResponse.substring(0, 100)
3046
2809
  });
3047
- logger3.debug("Aggregation complete");
2810
+ logger2.debug("Aggregation complete");
3048
2811
  return {
3049
2812
  response: aggregatedResponse,
3050
2813
  status: "completed"
3051
2814
  };
3052
2815
  } catch (error) {
3053
- logger3.error("Aggregator node error", {
2816
+ logger2.error("Aggregator node error", {
3054
2817
  error: error instanceof Error ? error.message : String(error),
3055
2818
  stack: error instanceof Error ? error.stack : void 0,
3056
2819
  completedTasks: state.completedTasks.length
@@ -3065,9 +2828,9 @@ Please synthesize these results into a comprehensive response that addresses the
3065
2828
 
3066
2829
  // src/multi-agent/agent.ts
3067
2830
  var import_langgraph4 = require("@langchain/langgraph");
3068
- var import_core11 = require("@agentforge/core");
3069
- var logLevel4 = process.env.LOG_LEVEL?.toLowerCase() || import_core11.LogLevel.INFO;
3070
- var logger4 = (0, import_core11.createLogger)("multi-agent:system", { level: logLevel4 });
2831
+ var import_core10 = require("@agentforge/core");
2832
+ var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || import_core10.LogLevel.INFO;
2833
+ var logger3 = (0, import_core10.createLogger)("multi-agent:system", { level: logLevel3 });
3071
2834
  function createMultiAgentSystem(config) {
3072
2835
  const {
3073
2836
  supervisor,
@@ -3084,10 +2847,6 @@ function createMultiAgentSystem(config) {
3084
2847
  if (supervisor.strategy === "llm-based") {
3085
2848
  configuredModel = configuredModel.withStructuredOutput(RoutingDecisionSchema);
3086
2849
  }
3087
- if (supervisor.tools && supervisor.tools.length > 0) {
3088
- const langchainTools = (0, import_core11.toLangChainTools)(supervisor.tools);
3089
- configuredModel = configuredModel.bindTools(langchainTools);
3090
- }
3091
2850
  supervisorConfig.model = configuredModel;
3092
2851
  }
3093
2852
  const supervisorNode = createSupervisorNode(supervisorConfig);
@@ -3109,46 +2868,46 @@ function createMultiAgentSystem(config) {
3109
2868
  });
3110
2869
  workflow.addNode("aggregator", aggregatorNode);
3111
2870
  const supervisorRouter = (state) => {
3112
- logger4.debug("Supervisor router executing", {
2871
+ logger3.debug("Supervisor router executing", {
3113
2872
  status: state.status,
3114
2873
  currentAgent: state.currentAgent,
3115
2874
  iteration: state.iteration
3116
2875
  });
3117
2876
  if (state.status === "completed" || state.status === "failed") {
3118
- logger4.info("Supervisor router: ending workflow", { status: state.status });
2877
+ logger3.info("Supervisor router: ending workflow", { status: state.status });
3119
2878
  return import_langgraph4.END;
3120
2879
  }
3121
2880
  if (state.status === "aggregating") {
3122
- logger4.info("Supervisor router: routing to aggregator");
2881
+ logger3.info("Supervisor router: routing to aggregator");
3123
2882
  return "aggregator";
3124
2883
  }
3125
2884
  if (state.currentAgent && state.currentAgent !== "supervisor") {
3126
2885
  if (state.currentAgent.includes(",")) {
3127
2886
  const agents = state.currentAgent.split(",").map((a) => a.trim());
3128
- logger4.info("Supervisor router: parallel routing", {
2887
+ logger3.info("Supervisor router: parallel routing", {
3129
2888
  agents,
3130
2889
  count: agents.length
3131
2890
  });
3132
2891
  return agents;
3133
2892
  }
3134
- logger4.info("Supervisor router: single agent routing", {
2893
+ logger3.info("Supervisor router: single agent routing", {
3135
2894
  targetAgent: state.currentAgent
3136
2895
  });
3137
2896
  return state.currentAgent;
3138
2897
  }
3139
- logger4.debug("Supervisor router: staying at supervisor");
2898
+ logger3.debug("Supervisor router: staying at supervisor");
3140
2899
  return "supervisor";
3141
2900
  };
3142
2901
  const workerRouter = (state) => {
3143
- logger4.debug("Worker router executing", {
2902
+ logger3.debug("Worker router executing", {
3144
2903
  iteration: state.iteration,
3145
2904
  completedTasks: state.completedTasks.length
3146
2905
  });
3147
- logger4.debug("Worker router: returning to supervisor");
2906
+ logger3.debug("Worker router: returning to supervisor");
3148
2907
  return "supervisor";
3149
2908
  };
3150
2909
  const aggregatorRouter = (state) => {
3151
- logger4.info("Aggregator router: ending workflow", {
2910
+ logger3.info("Aggregator router: ending workflow", {
3152
2911
  completedTasks: state.completedTasks.length,
3153
2912
  status: state.status
3154
2913
  });