@agentforge/patterns 0.10.5 → 0.10.7

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
@@ -108,6 +108,7 @@ var MessageSchema = import_zod.z.object({
108
108
  role: MessageRoleSchema,
109
109
  content: import_zod.z.string(),
110
110
  name: import_zod.z.string().optional(),
111
+ tool_call_id: import_zod.z.string().optional(),
111
112
  metadata: import_zod.z.record(import_zod.z.any()).optional()
112
113
  });
113
114
  var ThoughtSchema = import_zod.z.object({
@@ -343,6 +344,13 @@ function createReasoningNode(llm, tools, systemPrompt, maxIterations, verbose =
343
344
  if (msg.role === "user") return new import_messages.HumanMessage(msg.content);
344
345
  if (msg.role === "assistant") return new import_messages.AIMessage(msg.content);
345
346
  if (msg.role === "system") return new import_messages.SystemMessage(msg.content);
347
+ if (msg.role === "tool") {
348
+ return new import_messages.ToolMessage({
349
+ content: msg.content,
350
+ tool_call_id: msg.tool_call_id,
351
+ name: msg.name
352
+ });
353
+ }
346
354
  return new import_messages.HumanMessage(msg.content);
347
355
  })
348
356
  ];
@@ -379,7 +387,7 @@ ${scratchpadText}`));
379
387
  thoughts: thought ? [{ content: thought, timestamp: Date.now() }] : [],
380
388
  actions: toolCalls,
381
389
  iteration: 1,
382
- // Increment iteration
390
+ // Add 1 to iteration counter (uses additive reducer)
383
391
  shouldContinue,
384
392
  response: toolCalls.length === 0 ? thought : void 0
385
393
  // Final response if no tool calls
@@ -509,7 +517,7 @@ function createActionNode(tools, verbose = false, enableDeduplication = true) {
509
517
  };
510
518
  };
511
519
  }
512
- function createObservationNode(verbose = false) {
520
+ function createObservationNode(verbose = false, returnIntermediateSteps = false) {
513
521
  return async (state) => {
514
522
  const observations = state.observations || [];
515
523
  const thoughts = state.thoughts || [];
@@ -520,37 +528,36 @@ function createObservationNode(verbose = false) {
520
528
  iteration
521
529
  });
522
530
  const recentObservations = observations.slice(-10);
523
- const currentStep = state.iteration;
524
- const latestThought = thoughts[thoughts.length - 1]?.content || "";
525
531
  const latestActions = actions.slice(-10);
526
- const latestObservations = recentObservations;
527
- const scratchpadEntry = {
528
- step: currentStep,
529
- thought: latestThought,
532
+ const observationMessages = recentObservations.map((obs) => {
533
+ const content = obs.error ? `Error: ${obs.error}` : typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result, null, 2);
534
+ return {
535
+ role: "tool",
536
+ content,
537
+ name: latestActions.find((a) => a.id === obs.toolCallId)?.name,
538
+ tool_call_id: obs.toolCallId
539
+ // Include tool_call_id for proper ToolMessage construction
540
+ };
541
+ });
542
+ const scratchpadEntries = returnIntermediateSteps ? [{
543
+ step: state.iteration,
544
+ thought: thoughts[thoughts.length - 1]?.content || "",
530
545
  action: latestActions.map((a) => `${a.name}(${JSON.stringify(a.arguments)})`).join(", "),
531
- observation: latestObservations.map((obs) => {
546
+ observation: recentObservations.map((obs) => {
532
547
  if (obs.error) {
533
548
  return `Error: ${obs.error}`;
534
549
  }
535
550
  return typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result);
536
551
  }).join("; "),
537
552
  timestamp: Date.now()
538
- };
539
- const observationMessages = latestObservations.map((obs) => {
540
- const content = obs.error ? `Error: ${obs.error}` : typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result, null, 2);
541
- return {
542
- role: "tool",
543
- content,
544
- name: latestActions.find((a) => a.id === obs.toolCallId)?.name
545
- };
546
- });
553
+ }] : [];
547
554
  observationLogger.debug("Observation node complete", {
548
555
  iteration,
549
- scratchpadUpdated: true,
556
+ scratchpadUpdated: returnIntermediateSteps,
550
557
  messageCount: observationMessages.length
551
558
  });
552
559
  return {
553
- scratchpad: [scratchpadEntry],
560
+ scratchpad: scratchpadEntries,
554
561
  messages: observationMessages
555
562
  };
556
563
  };
@@ -587,7 +594,7 @@ function createReActAgent(config, options) {
587
594
  verbose
588
595
  );
589
596
  const actionNode = createActionNode(toolArray, verbose, enableDeduplication);
590
- const observationNode = createObservationNode(verbose);
597
+ const observationNode = createObservationNode(verbose, returnIntermediateSteps);
591
598
  const shouldContinue = (state) => {
592
599
  if (stopCondition && stopCondition(state)) {
593
600
  return import_langgraph.END;
@@ -2615,7 +2622,8 @@ function createSupervisorNode(config) {
2615
2622
  activeAssignments: assignments,
2616
2623
  // Multiple assignments for parallel execution!
2617
2624
  messages,
2618
- iteration: state.iteration + 1
2625
+ // Add 1 to iteration counter (uses additive reducer)
2626
+ iteration: 1
2619
2627
  };
2620
2628
  } catch (error) {
2621
2629
  logger2.error("Supervisor node error", {
package/dist/index.d.cts CHANGED
@@ -16,21 +16,28 @@ import { ToolRegistry, Tool, LogLevel } from '@agentforge/core';
16
16
 
17
17
  /**
18
18
  * Base message schema
19
+ *
20
+ * Note: tool_call_id is required for messages with role='tool' to properly
21
+ * construct ToolMessage instances in LangChain. It links tool results back
22
+ * to their corresponding tool calls.
19
23
  */
20
24
  declare const MessageSchema: z.ZodObject<{
21
25
  role: z.ZodEnum<["system", "user", "assistant", "tool"]>;
22
26
  content: z.ZodString;
23
27
  name: z.ZodOptional<z.ZodString>;
28
+ tool_call_id: z.ZodOptional<z.ZodString>;
24
29
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
25
30
  }, "strip", z.ZodTypeAny, {
26
31
  role: "system" | "user" | "assistant" | "tool";
27
32
  content: string;
28
33
  name?: string | undefined;
34
+ tool_call_id?: string | undefined;
29
35
  metadata?: Record<string, any> | undefined;
30
36
  }, {
31
37
  role: "system" | "user" | "assistant" | "tool";
32
38
  content: string;
33
39
  name?: string | undefined;
40
+ tool_call_id?: string | undefined;
34
41
  metadata?: Record<string, any> | undefined;
35
42
  }>;
36
43
  type Message = z.infer<typeof MessageSchema>;
@@ -2817,6 +2824,14 @@ declare function createWorkerNode(config: WorkerConfig): (state: MultiAgentState
2817
2824
  */
2818
2825
  declare function createAggregatorNode(config?: AggregatorConfig): (state: MultiAgentStateType) => Promise<Partial<MultiAgentStateType>>;
2819
2826
 
2827
+ /**
2828
+ * Multi-Agent System Factory
2829
+ *
2830
+ * This module provides the main factory function for creating multi-agent systems.
2831
+ *
2832
+ * @module patterns/multi-agent/agent
2833
+ */
2834
+
2820
2835
  /**
2821
2836
  * Create a multi-agent coordination system
2822
2837
  *
@@ -2901,11 +2916,7 @@ declare function createAggregatorNode(config?: AggregatorConfig): (state: MultiA
2901
2916
  * );
2902
2917
  * ```
2903
2918
  */
2904
- declare function createMultiAgentSystem(config: MultiAgentSystemConfig): CompiledStateGraph<{
2905
- [x: string]: unknown;
2906
- }, {
2907
- [x: string]: unknown;
2908
- }, "__start__", _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, unknown, unknown, unknown>;
2919
+ declare function createMultiAgentSystem(config: MultiAgentSystemConfig): MultiAgentSystemWithRegistry;
2909
2920
  /**
2910
2921
  * Multi-agent system builder for dynamic worker registration
2911
2922
  *
@@ -2956,16 +2967,12 @@ declare class MultiAgentSystemBuilder {
2956
2967
  *
2957
2968
  * @returns Compiled LangGraph workflow
2958
2969
  */
2959
- build(): CompiledStateGraph<{
2960
- [x: string]: unknown;
2961
- }, {
2962
- [x: string]: unknown;
2963
- }, "__start__", _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, unknown, unknown, unknown>;
2970
+ build(): MultiAgentSystemWithRegistry;
2964
2971
  }
2965
2972
  /**
2966
2973
  * Extended multi-agent system with worker registration support
2967
2974
  */
2968
- interface MultiAgentSystemWithRegistry extends CompiledStateGraph<MultiAgentStateType, Partial<MultiAgentStateType>, '__start__' | 'supervisor' | 'aggregator' | string> {
2975
+ interface MultiAgentSystemWithRegistry extends CompiledStateGraph<any, any, any> {
2969
2976
  _workerRegistry?: Record<string, WorkerCapabilities>;
2970
2977
  _originalInvoke?: typeof CompiledStateGraph.prototype.invoke;
2971
2978
  _originalStream?: typeof CompiledStateGraph.prototype.stream;
package/dist/index.d.ts CHANGED
@@ -16,21 +16,28 @@ import { ToolRegistry, Tool, LogLevel } from '@agentforge/core';
16
16
 
17
17
  /**
18
18
  * Base message schema
19
+ *
20
+ * Note: tool_call_id is required for messages with role='tool' to properly
21
+ * construct ToolMessage instances in LangChain. It links tool results back
22
+ * to their corresponding tool calls.
19
23
  */
20
24
  declare const MessageSchema: z.ZodObject<{
21
25
  role: z.ZodEnum<["system", "user", "assistant", "tool"]>;
22
26
  content: z.ZodString;
23
27
  name: z.ZodOptional<z.ZodString>;
28
+ tool_call_id: z.ZodOptional<z.ZodString>;
24
29
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
25
30
  }, "strip", z.ZodTypeAny, {
26
31
  role: "system" | "user" | "assistant" | "tool";
27
32
  content: string;
28
33
  name?: string | undefined;
34
+ tool_call_id?: string | undefined;
29
35
  metadata?: Record<string, any> | undefined;
30
36
  }, {
31
37
  role: "system" | "user" | "assistant" | "tool";
32
38
  content: string;
33
39
  name?: string | undefined;
40
+ tool_call_id?: string | undefined;
34
41
  metadata?: Record<string, any> | undefined;
35
42
  }>;
36
43
  type Message = z.infer<typeof MessageSchema>;
@@ -2817,6 +2824,14 @@ declare function createWorkerNode(config: WorkerConfig): (state: MultiAgentState
2817
2824
  */
2818
2825
  declare function createAggregatorNode(config?: AggregatorConfig): (state: MultiAgentStateType) => Promise<Partial<MultiAgentStateType>>;
2819
2826
 
2827
+ /**
2828
+ * Multi-Agent System Factory
2829
+ *
2830
+ * This module provides the main factory function for creating multi-agent systems.
2831
+ *
2832
+ * @module patterns/multi-agent/agent
2833
+ */
2834
+
2820
2835
  /**
2821
2836
  * Create a multi-agent coordination system
2822
2837
  *
@@ -2901,11 +2916,7 @@ declare function createAggregatorNode(config?: AggregatorConfig): (state: MultiA
2901
2916
  * );
2902
2917
  * ```
2903
2918
  */
2904
- declare function createMultiAgentSystem(config: MultiAgentSystemConfig): CompiledStateGraph<{
2905
- [x: string]: unknown;
2906
- }, {
2907
- [x: string]: unknown;
2908
- }, "__start__", _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, unknown, unknown, unknown>;
2919
+ declare function createMultiAgentSystem(config: MultiAgentSystemConfig): MultiAgentSystemWithRegistry;
2909
2920
  /**
2910
2921
  * Multi-agent system builder for dynamic worker registration
2911
2922
  *
@@ -2956,16 +2967,12 @@ declare class MultiAgentSystemBuilder {
2956
2967
  *
2957
2968
  * @returns Compiled LangGraph workflow
2958
2969
  */
2959
- build(): CompiledStateGraph<{
2960
- [x: string]: unknown;
2961
- }, {
2962
- [x: string]: unknown;
2963
- }, "__start__", _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, unknown, unknown, unknown>;
2970
+ build(): MultiAgentSystemWithRegistry;
2964
2971
  }
2965
2972
  /**
2966
2973
  * Extended multi-agent system with worker registration support
2967
2974
  */
2968
- interface MultiAgentSystemWithRegistry extends CompiledStateGraph<MultiAgentStateType, Partial<MultiAgentStateType>, '__start__' | 'supervisor' | 'aggregator' | string> {
2975
+ interface MultiAgentSystemWithRegistry extends CompiledStateGraph<any, any, any> {
2969
2976
  _workerRegistry?: Record<string, WorkerCapabilities>;
2970
2977
  _originalInvoke?: typeof CompiledStateGraph.prototype.invoke;
2971
2978
  _originalStream?: typeof CompiledStateGraph.prototype.stream;
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ var MessageSchema = z.object({
5
5
  role: MessageRoleSchema,
6
6
  content: z.string(),
7
7
  name: z.string().optional(),
8
+ tool_call_id: z.string().optional(),
8
9
  metadata: z.record(z.any()).optional()
9
10
  });
10
11
  var ThoughtSchema = z.object({
@@ -170,7 +171,7 @@ function formatScratchpad(scratchpad) {
170
171
  }
171
172
 
172
173
  // src/react/nodes.ts
173
- import { HumanMessage, AIMessage, SystemMessage } from "@langchain/core/messages";
174
+ import { HumanMessage, AIMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
174
175
  import { toLangChainTools } from "@agentforge/core";
175
176
 
176
177
  // src/shared/deduplication.ts
@@ -240,6 +241,13 @@ function createReasoningNode(llm, tools, systemPrompt, maxIterations, verbose =
240
241
  if (msg.role === "user") return new HumanMessage(msg.content);
241
242
  if (msg.role === "assistant") return new AIMessage(msg.content);
242
243
  if (msg.role === "system") return new SystemMessage(msg.content);
244
+ if (msg.role === "tool") {
245
+ return new ToolMessage({
246
+ content: msg.content,
247
+ tool_call_id: msg.tool_call_id,
248
+ name: msg.name
249
+ });
250
+ }
243
251
  return new HumanMessage(msg.content);
244
252
  })
245
253
  ];
@@ -276,7 +284,7 @@ ${scratchpadText}`));
276
284
  thoughts: thought ? [{ content: thought, timestamp: Date.now() }] : [],
277
285
  actions: toolCalls,
278
286
  iteration: 1,
279
- // Increment iteration
287
+ // Add 1 to iteration counter (uses additive reducer)
280
288
  shouldContinue,
281
289
  response: toolCalls.length === 0 ? thought : void 0
282
290
  // Final response if no tool calls
@@ -406,7 +414,7 @@ function createActionNode(tools, verbose = false, enableDeduplication = true) {
406
414
  };
407
415
  };
408
416
  }
409
- function createObservationNode(verbose = false) {
417
+ function createObservationNode(verbose = false, returnIntermediateSteps = false) {
410
418
  return async (state) => {
411
419
  const observations = state.observations || [];
412
420
  const thoughts = state.thoughts || [];
@@ -417,37 +425,36 @@ function createObservationNode(verbose = false) {
417
425
  iteration
418
426
  });
419
427
  const recentObservations = observations.slice(-10);
420
- const currentStep = state.iteration;
421
- const latestThought = thoughts[thoughts.length - 1]?.content || "";
422
428
  const latestActions = actions.slice(-10);
423
- const latestObservations = recentObservations;
424
- const scratchpadEntry = {
425
- step: currentStep,
426
- thought: latestThought,
429
+ const observationMessages = recentObservations.map((obs) => {
430
+ const content = obs.error ? `Error: ${obs.error}` : typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result, null, 2);
431
+ return {
432
+ role: "tool",
433
+ content,
434
+ name: latestActions.find((a) => a.id === obs.toolCallId)?.name,
435
+ tool_call_id: obs.toolCallId
436
+ // Include tool_call_id for proper ToolMessage construction
437
+ };
438
+ });
439
+ const scratchpadEntries = returnIntermediateSteps ? [{
440
+ step: state.iteration,
441
+ thought: thoughts[thoughts.length - 1]?.content || "",
427
442
  action: latestActions.map((a) => `${a.name}(${JSON.stringify(a.arguments)})`).join(", "),
428
- observation: latestObservations.map((obs) => {
443
+ observation: recentObservations.map((obs) => {
429
444
  if (obs.error) {
430
445
  return `Error: ${obs.error}`;
431
446
  }
432
447
  return typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result);
433
448
  }).join("; "),
434
449
  timestamp: Date.now()
435
- };
436
- const observationMessages = latestObservations.map((obs) => {
437
- const content = obs.error ? `Error: ${obs.error}` : typeof obs.result === "string" ? obs.result : JSON.stringify(obs.result, null, 2);
438
- return {
439
- role: "tool",
440
- content,
441
- name: latestActions.find((a) => a.id === obs.toolCallId)?.name
442
- };
443
- });
450
+ }] : [];
444
451
  observationLogger.debug("Observation node complete", {
445
452
  iteration,
446
- scratchpadUpdated: true,
453
+ scratchpadUpdated: returnIntermediateSteps,
447
454
  messageCount: observationMessages.length
448
455
  });
449
456
  return {
450
- scratchpad: [scratchpadEntry],
457
+ scratchpad: scratchpadEntries,
451
458
  messages: observationMessages
452
459
  };
453
460
  };
@@ -484,7 +491,7 @@ function createReActAgent(config, options) {
484
491
  verbose
485
492
  );
486
493
  const actionNode = createActionNode(toolArray, verbose, enableDeduplication);
487
- const observationNode = createObservationNode(verbose);
494
+ const observationNode = createObservationNode(verbose, returnIntermediateSteps);
488
495
  const shouldContinue = (state) => {
489
496
  if (stopCondition && stopCondition(state)) {
490
497
  return END;
@@ -2512,7 +2519,8 @@ function createSupervisorNode(config) {
2512
2519
  activeAssignments: assignments,
2513
2520
  // Multiple assignments for parallel execution!
2514
2521
  messages,
2515
- iteration: state.iteration + 1
2522
+ // Add 1 to iteration counter (uses additive reducer)
2523
+ iteration: 1
2516
2524
  };
2517
2525
  } catch (error) {
2518
2526
  logger2.error("Supervisor node error", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/patterns",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "Agent patterns (ReAct, Planner-Executor) for AgentForge framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",