@agentforge/patterns 0.16.31 → 0.16.32

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
@@ -313,9 +313,9 @@ function stringifyActionArguments(arguments_) {
313
313
  function getLatestThought(thoughts) {
314
314
  return thoughts[thoughts.length - 1]?.content ?? "";
315
315
  }
316
- function debugIfVerbose(logger4, verbose, message, data) {
316
+ function debugIfVerbose(logger5, verbose, message, data) {
317
317
  if (verbose) {
318
- logger4.debug(message, data);
318
+ logger5.debug(message, data);
319
319
  }
320
320
  }
321
321
 
@@ -2295,6 +2295,82 @@ var MultiAgentState = createStateAnnotation4(MultiAgentStateConfig);
2295
2295
 
2296
2296
  // src/multi-agent/routing.ts
2297
2297
  import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
2298
+ var logger = createPatternLogger("agentforge:patterns:multi-agent:routing");
2299
+ function hasStructuredOutput(model) {
2300
+ return typeof model.withStructuredOutput === "function";
2301
+ }
2302
+ function isRecord(value) {
2303
+ return typeof value === "object" && value !== null;
2304
+ }
2305
+ function isContentCarrier(value) {
2306
+ return isRecord(value) && "content" in value;
2307
+ }
2308
+ function serializeRoutingContent(content) {
2309
+ if (typeof content === "string") {
2310
+ return content;
2311
+ }
2312
+ if (Array.isArray(content)) {
2313
+ const textParts = content.flatMap((part) => {
2314
+ if (typeof part === "string") {
2315
+ return [part];
2316
+ }
2317
+ if (isRecord(part) && typeof part.text === "string") {
2318
+ return [part.text];
2319
+ }
2320
+ return [];
2321
+ });
2322
+ if (textParts.length > 0) {
2323
+ return textParts.join("\n");
2324
+ }
2325
+ return JSON.stringify(content);
2326
+ }
2327
+ return JSON.stringify(content);
2328
+ }
2329
+ function normalizeRoutingDecisionInput(decision) {
2330
+ if (isContentCarrier(decision)) {
2331
+ return JSON.parse(serializeRoutingContent(decision.content));
2332
+ }
2333
+ return decision;
2334
+ }
2335
+ function parseRoutingDecision(decision) {
2336
+ try {
2337
+ return RoutingDecisionSchema.parse(normalizeRoutingDecisionInput(decision));
2338
+ } catch (error) {
2339
+ const message = error instanceof Error ? error.message : String(error);
2340
+ throw new Error(`Invalid LLM routing decision: ${message}`);
2341
+ }
2342
+ }
2343
+ function finalizeLlmRoutingDecision(decision) {
2344
+ const parsed = parseRoutingDecision(decision);
2345
+ return {
2346
+ targetAgent: parsed.targetAgent,
2347
+ targetAgents: parsed.targetAgents,
2348
+ reasoning: parsed.reasoning,
2349
+ confidence: parsed.confidence,
2350
+ strategy: "llm-based",
2351
+ timestamp: Date.now()
2352
+ };
2353
+ }
2354
+ async function invokeRoutingDecision(model, messages) {
2355
+ if (hasStructuredOutput(model)) {
2356
+ let structuredModel;
2357
+ try {
2358
+ structuredModel = model.withStructuredOutput(RoutingDecisionSchema);
2359
+ } catch (error) {
2360
+ logger.warn("Structured output unavailable, using direct routing fallback", {
2361
+ strategy: "llm-based",
2362
+ fallback: "direct-model-invoke",
2363
+ error: error instanceof Error ? error.message : String(error)
2364
+ });
2365
+ const decision3 = await model.invoke(messages);
2366
+ return finalizeLlmRoutingDecision(decision3);
2367
+ }
2368
+ const decision2 = await structuredModel.invoke(messages);
2369
+ return finalizeLlmRoutingDecision(decision2);
2370
+ }
2371
+ const decision = await model.invoke(messages);
2372
+ return finalizeLlmRoutingDecision(decision);
2373
+ }
2298
2374
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2299
2375
 
2300
2376
  Your job is to:
@@ -2352,20 +2428,12 @@ Select the best worker(s) for this task and explain your reasoning.`;
2352
2428
  new SystemMessage5(systemPrompt),
2353
2429
  new HumanMessage5(userPrompt)
2354
2430
  ];
2355
- const decision = await config.model.invoke(messages);
2356
- return {
2357
- targetAgent: decision.targetAgent,
2358
- targetAgents: decision.targetAgents,
2359
- reasoning: decision.reasoning,
2360
- confidence: decision.confidence,
2361
- strategy: "llm-based",
2362
- timestamp: Date.now()
2363
- };
2431
+ return await invokeRoutingDecision(config.model, messages);
2364
2432
  }
2365
2433
  };
2366
2434
  var roundRobinRouting = {
2367
2435
  name: "round-robin",
2368
- async route(state, config) {
2436
+ async route(state, _config) {
2369
2437
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id]) => id);
2370
2438
  if (availableWorkers.length === 0) {
2371
2439
  throw new Error("No available workers for round-robin routing");
@@ -2384,7 +2452,7 @@ var roundRobinRouting = {
2384
2452
  };
2385
2453
  var skillBasedRouting = {
2386
2454
  name: "skill-based",
2387
- async route(state, config) {
2455
+ async route(state, _config) {
2388
2456
  const lastMessage = state.messages[state.messages.length - 1];
2389
2457
  const taskContent = (lastMessage?.content || state.input).toLowerCase();
2390
2458
  const workerScores = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => {
@@ -2425,7 +2493,7 @@ var skillBasedRouting = {
2425
2493
  };
2426
2494
  var loadBalancedRouting = {
2427
2495
  name: "load-balanced",
2428
- async route(state, config) {
2496
+ async route(state, _config) {
2429
2497
  const availableWorkers = Object.entries(state.workers).filter(([_, caps]) => caps.available).map(([id, caps]) => ({ id, workload: caps.currentWorkload })).sort((a, b) => a.workload - b.workload);
2430
2498
  if (availableWorkers.length === 0) {
2431
2499
  throw new Error("No available workers for load-balanced routing");
@@ -2470,22 +2538,22 @@ function getRoutingStrategy(name) {
2470
2538
  }
2471
2539
 
2472
2540
  // src/multi-agent/utils.ts
2473
- var logger = createPatternLogger("agentforge:patterns:multi-agent:utils");
2474
- function isRecord(value) {
2541
+ var logger2 = createPatternLogger("agentforge:patterns:multi-agent:utils");
2542
+ function isRecord2(value) {
2475
2543
  return typeof value === "object" && value !== null && !Array.isArray(value);
2476
2544
  }
2477
2545
  function toRunnableConfig(config) {
2478
- if (!isRecord(config)) {
2546
+ if (!isRecord2(config)) {
2479
2547
  return void 0;
2480
2548
  }
2481
2549
  return config;
2482
2550
  }
2483
2551
  function getReActResultShape(value) {
2484
- if (!isRecord(value)) {
2552
+ if (!isRecord2(value)) {
2485
2553
  return {};
2486
2554
  }
2487
- const messages = Array.isArray(value.messages) ? value.messages.filter((message) => isRecord(message)) : void 0;
2488
- const actions = Array.isArray(value.actions) ? value.actions.filter((action) => isRecord(action)) : void 0;
2555
+ const messages = Array.isArray(value.messages) ? value.messages.filter((message) => isRecord2(message)) : void 0;
2556
+ const actions = Array.isArray(value.actions) ? value.actions.filter((action) => isRecord2(action)) : void 0;
2489
2557
  return {
2490
2558
  messages,
2491
2559
  actions,
@@ -2504,7 +2572,7 @@ function safeSerializeContent(content) {
2504
2572
  if (typeof part === "string") {
2505
2573
  return part;
2506
2574
  }
2507
- if (isRecord(part) && typeof part.text === "string" && part.text.length > 0) {
2575
+ if (isRecord2(part) && typeof part.text === "string" && part.text.length > 0) {
2508
2576
  return part.text;
2509
2577
  }
2510
2578
  try {
@@ -2549,17 +2617,17 @@ function isReActAgent(obj) {
2549
2617
  function wrapReActAgent(workerId, agent, verbose = false) {
2550
2618
  return async (state, config) => {
2551
2619
  try {
2552
- logger.debug("Wrapping ReAct agent execution", { workerId });
2620
+ logger2.debug("Wrapping ReAct agent execution", { workerId });
2553
2621
  const runnableConfig = toRunnableConfig(config);
2554
2622
  const currentAssignment = state.activeAssignments.find(
2555
2623
  (assignment) => assignment.workerId === workerId && !state.completedTasks.some((task2) => task2.assignmentId === assignment.id)
2556
2624
  );
2557
2625
  if (!currentAssignment) {
2558
- logger.debug("No active assignment found", { workerId });
2626
+ logger2.debug("No active assignment found", { workerId });
2559
2627
  return {};
2560
2628
  }
2561
2629
  const task = currentAssignment.task;
2562
- logger.debug("Extracted task from assignment", {
2630
+ logger2.debug("Extracted task from assignment", {
2563
2631
  workerId,
2564
2632
  assignmentId: currentAssignment.id,
2565
2633
  taskPreview: task.substring(0, 100) + (task.length > 100 ? "..." : "")
@@ -2572,7 +2640,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2572
2640
  thread_id: workerThreadId
2573
2641
  }
2574
2642
  } : runnableConfig;
2575
- logger.debug("Invoking ReAct agent with worker-specific config", {
2643
+ logger2.debug("Invoking ReAct agent with worker-specific config", {
2576
2644
  workerId,
2577
2645
  ...runnableConfig?.configurable?.thread_id !== void 0 ? { parentThreadId: String(runnableConfig.configurable.thread_id) } : {},
2578
2646
  ...workerThreadId ? { workerThreadId } : {},
@@ -2587,13 +2655,13 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2587
2655
  );
2588
2656
  const resultShape = getReActResultShape(result);
2589
2657
  const response = extractResponse(resultShape);
2590
- logger.debug("Received response from ReAct agent", {
2658
+ logger2.debug("Received response from ReAct agent", {
2591
2659
  workerId,
2592
2660
  responsePreview: response.substring(0, 100) + (response.length > 100 ? "..." : "")
2593
2661
  });
2594
2662
  const uniqueTools = extractToolsUsed(resultShape);
2595
2663
  if (uniqueTools.length > 0) {
2596
- logger.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2664
+ logger2.debug("Tools used by ReAct agent", { workerId, tools: uniqueTools });
2597
2665
  }
2598
2666
  const taskResult = {
2599
2667
  assignmentId: currentAssignment.id,
@@ -2612,7 +2680,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2612
2680
  };
2613
2681
  } catch (error) {
2614
2682
  const errorMessage = handleNodeError(error, `react-agent:${workerId}`, verbose);
2615
- logger.error("Error in ReAct agent execution", {
2683
+ logger2.error("Error in ReAct agent execution", {
2616
2684
  workerId,
2617
2685
  error: errorMessage
2618
2686
  });
@@ -2645,7 +2713,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2645
2713
  // src/multi-agent/nodes/shared.ts
2646
2714
  import { HumanMessage as HumanMessage6, SystemMessage as SystemMessage6 } from "@langchain/core/messages";
2647
2715
  import { toLangChainTools as toLangChainTools2 } from "@agentforge/core";
2648
- var logger2 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2716
+ var logger3 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2649
2717
  function createGeneratedId(prefix) {
2650
2718
  return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
2651
2719
  }
@@ -2697,7 +2765,7 @@ function serializeModelContent(content) {
2697
2765
  const error = new Error(
2698
2766
  "Failed to serialize model content: JSON.stringify returned undefined"
2699
2767
  );
2700
- logger2.error("Model content serialization failed", {
2768
+ logger3.error("Model content serialization failed", {
2701
2769
  errorMessage: error.message,
2702
2770
  contentType: content === null ? "null" : typeof content
2703
2771
  });
@@ -2706,7 +2774,7 @@ function serializeModelContent(content) {
2706
2774
  return serialized;
2707
2775
  } catch (error) {
2708
2776
  const normalizedError = error instanceof Error ? error : new Error("Unknown error during model content serialization");
2709
- logger2.error("Model content serialization threw an error", {
2777
+ logger3.error("Model content serialization threw an error", {
2710
2778
  errorMessage: normalizedError.message,
2711
2779
  contentType: content === null ? "null" : typeof content
2712
2780
  });
@@ -2749,16 +2817,16 @@ function createAggregatorNode(config = {}) {
2749
2817
  } = config;
2750
2818
  return async (state) => {
2751
2819
  try {
2752
- logger2.info("Aggregator node executing", {
2820
+ logger3.info("Aggregator node executing", {
2753
2821
  completedTasks: state.completedTasks.length,
2754
2822
  successfulTasks: state.completedTasks.filter((task) => task.success).length,
2755
2823
  failedTasks: state.completedTasks.filter((task) => !task.success).length
2756
2824
  });
2757
- logger2.debug("Combining results from workers");
2825
+ logger3.debug("Combining results from workers");
2758
2826
  if (aggregateFn) {
2759
- logger2.debug("Using custom aggregation function");
2827
+ logger3.debug("Using custom aggregation function");
2760
2828
  const response2 = await aggregateFn(state);
2761
- logger2.info("Custom aggregation complete", {
2829
+ logger3.info("Custom aggregation complete", {
2762
2830
  responseLength: response2.length
2763
2831
  });
2764
2832
  return {
@@ -2767,16 +2835,16 @@ function createAggregatorNode(config = {}) {
2767
2835
  };
2768
2836
  }
2769
2837
  if (state.completedTasks.length === 0) {
2770
- logger2.warn("No completed tasks to aggregate");
2838
+ logger3.warn("No completed tasks to aggregate");
2771
2839
  return {
2772
2840
  response: "No tasks were completed.",
2773
2841
  status: "completed"
2774
2842
  };
2775
2843
  }
2776
2844
  if (!model) {
2777
- logger2.debug("No model provided, concatenating results");
2845
+ logger3.debug("No model provided, concatenating results");
2778
2846
  const combinedResults = state.completedTasks.filter((task) => task.success).map((task) => task.result).join("\n\n");
2779
- logger2.info("Simple concatenation complete", {
2847
+ logger3.info("Simple concatenation complete", {
2780
2848
  resultLength: combinedResults.length
2781
2849
  });
2782
2850
  return {
@@ -2784,27 +2852,27 @@ function createAggregatorNode(config = {}) {
2784
2852
  status: "completed"
2785
2853
  };
2786
2854
  }
2787
- logger2.debug("Using LLM for intelligent aggregation", {
2855
+ logger3.debug("Using LLM for intelligent aggregation", {
2788
2856
  taskCount: state.completedTasks.length
2789
2857
  });
2790
2858
  const messages = createPromptMessages(systemPrompt, createAggregationPrompt(state));
2791
- logger2.debug("Invoking aggregation LLM");
2859
+ logger3.debug("Invoking aggregation LLM");
2792
2860
  const response = await model.invoke(messages);
2793
2861
  const aggregatedResponse = serializeModelContent(response.content);
2794
- logger2.info("Aggregation complete", {
2862
+ logger3.info("Aggregation complete", {
2795
2863
  responseLength: aggregatedResponse.length
2796
2864
  });
2797
- logger2.debug("Aggregation response details", {
2865
+ logger3.debug("Aggregation response details", {
2798
2866
  responseLength: aggregatedResponse.length
2799
2867
  });
2800
- logger2.debug("Aggregation complete");
2868
+ logger3.debug("Aggregation complete");
2801
2869
  return {
2802
2870
  response: aggregatedResponse,
2803
2871
  status: "completed"
2804
2872
  };
2805
2873
  } catch (error) {
2806
2874
  const errorMessage = handleNodeError(error, "aggregator", false);
2807
- logger2.error("Aggregator node error", {
2875
+ logger3.error("Aggregator node error", {
2808
2876
  error: errorMessage,
2809
2877
  ...error instanceof Error && error.stack ? { stack: error.stack } : {},
2810
2878
  completedTasks: state.completedTasks.length
@@ -2828,7 +2896,7 @@ function incrementAssignedWorkerLoads(state, assignments) {
2828
2896
  for (const assignment of assignments) {
2829
2897
  const worker = updatedWorkers[assignment.workerId];
2830
2898
  if (!worker) {
2831
- logger2.error("Worker not found in state", {
2899
+ logger3.error("Worker not found in state", {
2832
2900
  workerId: assignment.workerId,
2833
2901
  availableWorkers: Object.keys(updatedWorkers)
2834
2902
  });
@@ -2847,45 +2915,45 @@ function createSupervisorNode(config) {
2847
2915
  const { strategy, maxIterations = 10 } = config;
2848
2916
  return async (state) => {
2849
2917
  try {
2850
- logger2.info("Supervisor node executing", {
2918
+ logger3.info("Supervisor node executing", {
2851
2919
  iteration: state.iteration,
2852
2920
  maxIterations,
2853
2921
  activeAssignments: state.activeAssignments.length,
2854
2922
  completedTasks: state.completedTasks.length
2855
2923
  });
2856
- logger2.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2924
+ logger3.debug(`Routing iteration ${state.iteration}/${maxIterations}`);
2857
2925
  if (state.iteration >= maxIterations) {
2858
- logger2.warn("Max iterations reached", {
2926
+ logger3.warn("Max iterations reached", {
2859
2927
  iteration: state.iteration,
2860
2928
  maxIterations
2861
2929
  });
2862
- logger2.debug("Max iterations reached, moving to aggregation");
2930
+ logger3.debug("Max iterations reached, moving to aggregation");
2863
2931
  return {
2864
2932
  status: "aggregating",
2865
2933
  currentAgent: "aggregator"
2866
2934
  };
2867
2935
  }
2868
2936
  const allCompleted = allAssignmentsCompleted(state);
2869
- logger2.debug("Checking task completion", {
2937
+ logger3.debug("Checking task completion", {
2870
2938
  activeAssignments: state.activeAssignments.length,
2871
2939
  completedTasks: state.completedTasks.length,
2872
2940
  allCompleted
2873
2941
  });
2874
2942
  if (allCompleted && state.activeAssignments.length > 0) {
2875
- logger2.info("All tasks completed, moving to aggregation", {
2943
+ logger3.info("All tasks completed, moving to aggregation", {
2876
2944
  completedCount: state.completedTasks.length
2877
2945
  });
2878
- logger2.debug("All tasks completed, moving to aggregation");
2946
+ logger3.debug("All tasks completed, moving to aggregation");
2879
2947
  return {
2880
2948
  status: "aggregating",
2881
2949
  currentAgent: "aggregator"
2882
2950
  };
2883
2951
  }
2884
- logger2.debug("Getting routing strategy", { strategy });
2952
+ logger3.debug("Getting routing strategy", { strategy });
2885
2953
  const routingImpl = getRoutingStrategy(strategy);
2886
2954
  const decision = await routingImpl.route(state, config);
2887
2955
  const targetAgents = decision.targetAgents && decision.targetAgents.length > 0 ? decision.targetAgents : decision.targetAgent ? [decision.targetAgent] : [];
2888
- logger2.debug("Target agents determined", {
2956
+ logger3.debug("Target agents determined", {
2889
2957
  targetAgents,
2890
2958
  isParallel: targetAgents.length > 1,
2891
2959
  decision: {
@@ -2894,30 +2962,30 @@ function createSupervisorNode(config) {
2894
2962
  }
2895
2963
  });
2896
2964
  if (targetAgents.length === 0) {
2897
- logger2.error("No target agents specified in routing decision");
2965
+ logger3.error("No target agents specified in routing decision");
2898
2966
  throw new Error("Routing decision must specify at least one target agent");
2899
2967
  }
2900
2968
  if (targetAgents.length === 1) {
2901
- logger2.info("Routing to single agent", {
2969
+ logger3.info("Routing to single agent", {
2902
2970
  targetAgent: targetAgents[0],
2903
2971
  reasoning: decision.reasoning,
2904
2972
  confidence: decision.confidence
2905
2973
  });
2906
- logger2.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2974
+ logger3.debug(`Routing to ${targetAgents[0]}: ${decision.reasoning}`);
2907
2975
  } else {
2908
- logger2.info("Routing to multiple agents in parallel", {
2976
+ logger3.info("Routing to multiple agents in parallel", {
2909
2977
  targetAgents,
2910
2978
  count: targetAgents.length,
2911
2979
  reasoning: decision.reasoning,
2912
2980
  confidence: decision.confidence
2913
2981
  });
2914
- logger2.debug(
2982
+ logger3.debug(
2915
2983
  `Routing to ${targetAgents.length} agents in parallel [${targetAgents.join(", ")}]: ${decision.reasoning}`
2916
2984
  );
2917
2985
  }
2918
2986
  const task = getLatestTaskContent(state);
2919
2987
  const assignments = createTaskAssignments(targetAgents, task);
2920
- logger2.debug("Created task assignments", {
2988
+ logger3.debug("Created task assignments", {
2921
2989
  assignmentCount: assignments.length,
2922
2990
  assignments: assignments.map((assignment) => ({
2923
2991
  id: assignment.id,
@@ -2927,7 +2995,7 @@ function createSupervisorNode(config) {
2927
2995
  });
2928
2996
  const messages = createAssignmentMessages(assignments);
2929
2997
  const updatedWorkers = incrementAssignedWorkerLoads(state, assignments);
2930
- logger2.info("Supervisor routing complete", {
2998
+ logger3.info("Supervisor routing complete", {
2931
2999
  currentAgent: targetAgents.join(","),
2932
3000
  status: "executing",
2933
3001
  assignmentCount: assignments.length,
@@ -2945,7 +3013,7 @@ function createSupervisorNode(config) {
2945
3013
  };
2946
3014
  } catch (error) {
2947
3015
  const errorMessage = handleNodeError(error, "supervisor", false);
2948
- logger2.error("Supervisor node error", {
3016
+ logger3.error("Supervisor node error", {
2949
3017
  error: errorMessage,
2950
3018
  ...error instanceof Error && error.stack ? { stack: error.stack } : {},
2951
3019
  iteration: state.iteration
@@ -2973,7 +3041,7 @@ async function invokeWorkerModel(model, config, assignment) {
2973
3041
  );
2974
3042
  let modelToUse = model;
2975
3043
  if (config.tools && config.tools.length > 0 && model.bindTools) {
2976
- logger2.debug("Binding tools to model", {
3044
+ logger3.debug("Binding tools to model", {
2977
3045
  workerId: config.id,
2978
3046
  toolCount: config.tools.length,
2979
3047
  toolNames: config.tools.map((tool) => tool.metadata.name)
@@ -2982,15 +3050,15 @@ async function invokeWorkerModel(model, config, assignment) {
2982
3050
  convertWorkerToolsForLangChain(config.tools)
2983
3051
  );
2984
3052
  }
2985
- logger2.debug("Invoking LLM", { workerId: config.id });
3053
+ logger3.debug("Invoking LLM", { workerId: config.id });
2986
3054
  const response = await modelToUse.invoke(messages);
2987
3055
  const result = serializeModelContent(response.content);
2988
- logger2.info("Worker task completed", {
3056
+ logger3.info("Worker task completed", {
2989
3057
  workerId: config.id,
2990
3058
  assignmentId: assignment.id,
2991
3059
  resultLength: result.length
2992
3060
  });
2993
- logger2.debug("Worker result details", {
3061
+ logger3.debug("Worker result details", {
2994
3062
  workerId: config.id,
2995
3063
  assignmentId: assignment.id,
2996
3064
  resultLength: result.length
@@ -3025,7 +3093,7 @@ async function invokeWorkerModel(model, config, assignment) {
3025
3093
  function getStateWorkerOrThrow(state, workerId) {
3026
3094
  const currentWorker = state.workers[workerId];
3027
3095
  if (!currentWorker) {
3028
- logger2.error("Attempted to decrement workload for unknown worker", {
3096
+ logger3.error("Attempted to decrement workload for unknown worker", {
3029
3097
  workerId,
3030
3098
  availableWorkers: Object.keys(state.workers)
3031
3099
  });
@@ -3041,7 +3109,7 @@ function resolvePreviousWorkload(workerId, currentWorker, workerFromExecution) {
3041
3109
  if (typeof currentWorker.currentWorkload === "number" && Number.isFinite(currentWorker.currentWorkload)) {
3042
3110
  return currentWorker.currentWorkload;
3043
3111
  }
3044
- logger2.error("Worker workload is not a valid number; cannot decrement", {
3112
+ logger3.error("Worker workload is not a valid number; cannot decrement", {
3045
3113
  workerId,
3046
3114
  workloadFromState: currentWorker.currentWorkload,
3047
3115
  ...typeof workloadFromWorker === "number" ? { workloadFromWorker } : {}
@@ -3076,7 +3144,7 @@ function mergeWorkersWithDecrement(state, workerId, executionResult) {
3076
3144
  ...baseWorkers,
3077
3145
  [workerId]: updatedWorker
3078
3146
  };
3079
- logger2.debug("Worker workload decremented", {
3147
+ logger3.debug("Worker workload decremented", {
3080
3148
  workerId,
3081
3149
  previousWorkload,
3082
3150
  newWorkload: updatedWorkers[workerId].currentWorkload,
@@ -3094,7 +3162,7 @@ function decrementWorkerOnError(state, workerId) {
3094
3162
  currentWorkload: Math.max(0, previousWorkload - 1)
3095
3163
  }
3096
3164
  };
3097
- logger2.debug("Worker workload decremented (error path)", {
3165
+ logger3.debug("Worker workload decremented (error path)", {
3098
3166
  workerId,
3099
3167
  previousWorkload,
3100
3168
  newWorkload: updatedWorkers[workerId].currentWorkload
@@ -3102,7 +3170,7 @@ function decrementWorkerOnError(state, workerId) {
3102
3170
  return updatedWorkers;
3103
3171
  }
3104
3172
  function createErrorTaskResult(assignment, workerId, errorMessage) {
3105
- logger2.warn("Creating error result for assignment", {
3173
+ logger3.warn("Creating error result for assignment", {
3106
3174
  workerId,
3107
3175
  assignmentId: assignment.id
3108
3176
  });
@@ -3119,47 +3187,47 @@ function createWorkerNode(config) {
3119
3187
  const { id, model, executeFn, agent } = config;
3120
3188
  return async (state, runConfig) => {
3121
3189
  try {
3122
- logger2.info("Worker node executing", {
3190
+ logger3.info("Worker node executing", {
3123
3191
  workerId: id,
3124
3192
  iteration: state.iteration,
3125
3193
  activeAssignments: state.activeAssignments.length
3126
3194
  });
3127
3195
  const currentAssignment = findCurrentAssignment(state, id);
3128
3196
  if (!currentAssignment) {
3129
- logger2.debug("No active assignment found for worker", {
3197
+ logger3.debug("No active assignment found for worker", {
3130
3198
  workerId: id,
3131
3199
  totalActiveAssignments: state.activeAssignments.length,
3132
3200
  completedTasks: state.completedTasks.length
3133
3201
  });
3134
3202
  return {};
3135
3203
  }
3136
- logger2.info("Worker processing assignment", {
3204
+ logger3.info("Worker processing assignment", {
3137
3205
  workerId: id,
3138
3206
  assignmentId: currentAssignment.id,
3139
3207
  taskLength: currentAssignment.task.length
3140
3208
  });
3141
- logger2.debug("Worker assignment details", {
3209
+ logger3.debug("Worker assignment details", {
3142
3210
  workerId: id,
3143
3211
  assignmentId: currentAssignment.id,
3144
3212
  taskLength: currentAssignment.task.length
3145
3213
  });
3146
3214
  let executionResult;
3147
3215
  if (executeFn) {
3148
- logger2.debug("Using custom execution function", { workerId: id });
3216
+ logger3.debug("Using custom execution function", { workerId: id });
3149
3217
  executionResult = await executeFn(state, runConfig);
3150
3218
  } else if (agent && isReActAgent(agent)) {
3151
- logger2.debug("Using ReAct agent", { workerId: id });
3219
+ logger3.debug("Using ReAct agent", { workerId: id });
3152
3220
  const wrappedFn = wrapReActAgent(id, agent, config.verbose ?? false);
3153
3221
  executionResult = await wrappedFn(state, runConfig);
3154
3222
  } else if (model) {
3155
- logger2.debug("Using default LLM execution", {
3223
+ logger3.debug("Using default LLM execution", {
3156
3224
  workerId: id,
3157
3225
  hasTools: (config.tools ?? []).length > 0,
3158
3226
  toolCount: (config.tools ?? []).length
3159
3227
  });
3160
3228
  executionResult = await invokeWorkerModel(model, config, currentAssignment);
3161
3229
  } else {
3162
- logger2.error("Worker missing required configuration", { workerId: id });
3230
+ logger3.error("Worker missing required configuration", { workerId: id });
3163
3231
  throw new Error(
3164
3232
  `Worker ${id} requires either a model, an agent, or a custom execution function. Provide one of: config.model, config.agent, or config.executeFn`
3165
3233
  );
@@ -3171,7 +3239,7 @@ function createWorkerNode(config) {
3171
3239
  };
3172
3240
  } catch (error) {
3173
3241
  const errorMessage = handleNodeError(error, `worker:${id}`, false);
3174
- logger2.error("Worker node error", {
3242
+ logger3.error("Worker node error", {
3175
3243
  workerId: id,
3176
3244
  error: errorMessage
3177
3245
  });
@@ -3180,7 +3248,7 @@ function createWorkerNode(config) {
3180
3248
  updatedWorkers = decrementWorkerOnError(state, id);
3181
3249
  } catch (workloadError) {
3182
3250
  const workloadErrorMessage = workloadError instanceof Error ? workloadError.message : String(workloadError);
3183
- logger2.error("Worker error handling failed", {
3251
+ logger3.error("Worker error handling failed", {
3184
3252
  workerId: id,
3185
3253
  error: workloadErrorMessage
3186
3254
  });
@@ -3200,7 +3268,7 @@ function createWorkerNode(config) {
3200
3268
  workers: updatedWorkers
3201
3269
  };
3202
3270
  }
3203
- logger2.error("No assignment found for error handling", { workerId: id });
3271
+ logger3.error("No assignment found for error handling", { workerId: id });
3204
3272
  return {
3205
3273
  status: "failed",
3206
3274
  error: errorMessage,
@@ -3212,7 +3280,7 @@ function createWorkerNode(config) {
3212
3280
 
3213
3281
  // src/multi-agent/agent.ts
3214
3282
  import { StateGraph as StateGraph4, END as END4 } from "@langchain/langgraph";
3215
- var logger3 = createPatternLogger("agentforge:patterns:multi-agent:system");
3283
+ var logger4 = createPatternLogger("agentforge:patterns:multi-agent:system");
3216
3284
  function getToolName(tool) {
3217
3285
  if (!tool || typeof tool !== "object") {
3218
3286
  return "unknown";
@@ -3237,13 +3305,6 @@ function createMultiAgentSystem(config) {
3237
3305
  } = config;
3238
3306
  const workflow = new StateGraph4(MultiAgentState);
3239
3307
  const supervisorConfig = { ...supervisor, maxIterations, verbose };
3240
- if (supervisor.model) {
3241
- let configuredModel = supervisor.model;
3242
- if (supervisor.strategy === "llm-based") {
3243
- configuredModel = configuredModel.withStructuredOutput(RoutingDecisionSchema);
3244
- }
3245
- supervisorConfig.model = configuredModel;
3246
- }
3247
3308
  const supervisorNode = createSupervisorNode(supervisorConfig);
3248
3309
  workflow.addNode("supervisor", supervisorNode);
3249
3310
  const workerIds = [];
@@ -3263,46 +3324,46 @@ function createMultiAgentSystem(config) {
3263
3324
  });
3264
3325
  workflow.addNode("aggregator", aggregatorNode);
3265
3326
  const supervisorRouter = (state) => {
3266
- logger3.debug("Supervisor router executing", {
3327
+ logger4.debug("Supervisor router executing", {
3267
3328
  status: state.status,
3268
3329
  ...state.currentAgent ? { currentAgent: state.currentAgent } : {},
3269
3330
  iteration: state.iteration
3270
3331
  });
3271
3332
  if (state.status === "completed" || state.status === "failed") {
3272
- logger3.info("Supervisor router: ending workflow", { status: state.status });
3333
+ logger4.info("Supervisor router: ending workflow", { status: state.status });
3273
3334
  return END4;
3274
3335
  }
3275
3336
  if (state.status === "aggregating") {
3276
- logger3.info("Supervisor router: routing to aggregator");
3337
+ logger4.info("Supervisor router: routing to aggregator");
3277
3338
  return "aggregator";
3278
3339
  }
3279
3340
  if (state.currentAgent && state.currentAgent !== "supervisor") {
3280
3341
  if (state.currentAgent.includes(",")) {
3281
3342
  const agents = state.currentAgent.split(",").map((a) => a.trim());
3282
- logger3.info("Supervisor router: parallel routing", {
3343
+ logger4.info("Supervisor router: parallel routing", {
3283
3344
  agents,
3284
3345
  count: agents.length
3285
3346
  });
3286
3347
  return agents;
3287
3348
  }
3288
- logger3.info("Supervisor router: single agent routing", {
3349
+ logger4.info("Supervisor router: single agent routing", {
3289
3350
  targetAgent: state.currentAgent
3290
3351
  });
3291
3352
  return state.currentAgent;
3292
3353
  }
3293
- logger3.debug("Supervisor router: staying at supervisor");
3354
+ logger4.debug("Supervisor router: staying at supervisor");
3294
3355
  return "supervisor";
3295
3356
  };
3296
3357
  const workerRouter = (state) => {
3297
- logger3.debug("Worker router executing", {
3358
+ logger4.debug("Worker router executing", {
3298
3359
  iteration: state.iteration,
3299
3360
  completedTasks: state.completedTasks.length
3300
3361
  });
3301
- logger3.debug("Worker router: returning to supervisor");
3362
+ logger4.debug("Worker router: returning to supervisor");
3302
3363
  return "supervisor";
3303
3364
  };
3304
3365
  const aggregatorRouter = (state) => {
3305
- logger3.info("Aggregator router: ending workflow", {
3366
+ logger4.info("Aggregator router: ending workflow", {
3306
3367
  completedTasks: state.completedTasks.length,
3307
3368
  status: state.status
3308
3369
  });