@agentforge/patterns 0.16.14 → 0.16.16

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
@@ -1012,7 +1012,7 @@ var PlanExecuteStateConfig = {
1012
1012
  };
1013
1013
  var PlanExecuteState = (0, import_core5.createStateAnnotation)(PlanExecuteStateConfig);
1014
1014
 
1015
- // src/plan-execute/nodes.ts
1015
+ // src/plan-execute/planner-node.ts
1016
1016
  var import_messages2 = require("@langchain/core/messages");
1017
1017
 
1018
1018
  // src/plan-execute/prompts.ts
@@ -1074,13 +1074,61 @@ Status: {status}`;
1074
1074
  var REMAINING_STEP_TEMPLATE = `Step {stepNumber}: {description}
1075
1075
  {dependencies}`;
1076
1076
 
1077
- // src/plan-execute/nodes.ts
1077
+ // src/plan-execute/node-loggers.ts
1078
1078
  var plannerLogger = createPatternLogger("agentforge:patterns:plan-execute:planner");
1079
1079
  var executorLogger = createPatternLogger("agentforge:patterns:plan-execute:executor");
1080
1080
  var replannerLogger = createPatternLogger("agentforge:patterns:plan-execute:replanner");
1081
- function invokePlanExecuteTool(tool, args) {
1082
- return tool.invoke.call(tool, args);
1081
+
1082
+ // src/plan-execute/serialization.ts
1083
+ function hasTextContentPart(value) {
1084
+ return typeof value === "object" && value !== null && "text" in value && typeof value.text === "string";
1085
+ }
1086
+ function stringifyWithFallback(value, fallbackLabel) {
1087
+ try {
1088
+ const serialized = JSON.stringify(value);
1089
+ if (serialized === void 0) {
1090
+ return "undefined";
1091
+ }
1092
+ return serialized;
1093
+ } catch (error) {
1094
+ const reason = error instanceof Error ? error.message : String(error);
1095
+ return `[${fallbackLabel}: ${reason}]`;
1096
+ }
1083
1097
  }
1098
+ function toJsonSafeValue(value) {
1099
+ try {
1100
+ const serialized = JSON.stringify(value);
1101
+ if (serialized === void 0) {
1102
+ return void 0;
1103
+ }
1104
+ return JSON.parse(serialized);
1105
+ } catch (error) {
1106
+ const reason = error instanceof Error ? error.message : String(error);
1107
+ return `[Unserializable step result: ${reason}]`;
1108
+ }
1109
+ }
1110
+ function normalizeModelContent(content) {
1111
+ if (typeof content === "string") {
1112
+ return content;
1113
+ }
1114
+ if (Array.isArray(content)) {
1115
+ const textParts = [];
1116
+ for (const part of content) {
1117
+ if (hasTextContentPart(part) && part.text.length > 0) {
1118
+ textParts.push(part.text);
1119
+ }
1120
+ }
1121
+ if (textParts.length > 0) {
1122
+ return textParts.join("\n");
1123
+ }
1124
+ }
1125
+ return stringifyWithFallback(content, "Unserializable model content");
1126
+ }
1127
+ function serializePlanExecuteResult(result) {
1128
+ return stringifyWithFallback(result, "Unserializable step result");
1129
+ }
1130
+
1131
+ // src/plan-execute/planner-node.ts
1084
1132
  function createPlannerNode(config) {
1085
1133
  const {
1086
1134
  model,
@@ -1106,13 +1154,12 @@ function createPlannerNode(config) {
1106
1154
  new import_messages2.HumanMessage(userPrompt)
1107
1155
  ];
1108
1156
  const response = await model.invoke(messages);
1109
- const content = response.content.toString();
1157
+ const content = normalizeModelContent(response.content);
1110
1158
  let plan;
1111
1159
  try {
1112
1160
  const parsed = JSON.parse(content);
1113
1161
  plan = {
1114
1162
  steps: parsed.steps.slice(0, maxSteps),
1115
- // Limit to maxSteps
1116
1163
  goal: parsed.goal || state.input || "",
1117
1164
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1118
1165
  confidence: parsed.confidence
@@ -1144,6 +1191,11 @@ function createPlannerNode(config) {
1144
1191
  }
1145
1192
  };
1146
1193
  }
1194
+
1195
+ // src/plan-execute/executor-node.ts
1196
+ function invokePlanExecuteTool(tool, args) {
1197
+ return tool.invoke.call(tool, args);
1198
+ }
1147
1199
  function createExecutorNode(config) {
1148
1200
  const {
1149
1201
  tools,
@@ -1170,14 +1222,10 @@ function createExecutorNode(config) {
1170
1222
  deduplicationEnabled: enableDeduplication
1171
1223
  });
1172
1224
  if (!plan || !plan.steps || plan.steps.length === 0) {
1173
- return {
1174
- status: "completed"
1175
- };
1225
+ return { status: "completed" };
1176
1226
  }
1177
1227
  if (currentStepIndex >= plan.steps.length) {
1178
- return {
1179
- status: "completed"
1180
- };
1228
+ return { status: "completed" };
1181
1229
  }
1182
1230
  const currentStep = plan.steps[currentStepIndex];
1183
1231
  if (currentStep.dependencies && currentStep.dependencies.length > 0) {
@@ -1231,7 +1279,7 @@ function createExecutorNode(config) {
1231
1279
  }
1232
1280
  }
1233
1281
  if (!isDuplicate) {
1234
- const tool = tools.find((t) => t.metadata.name === currentStep.tool);
1282
+ const tool = tools.find((candidate) => candidate.metadata.name === currentStep.tool);
1235
1283
  if (!tool) {
1236
1284
  throw new Error(`Tool not found: ${currentStep.tool}`);
1237
1285
  }
@@ -1292,6 +1340,9 @@ function createExecutorNode(config) {
1292
1340
  currentStepIndex: currentStepIndex + 1
1293
1341
  };
1294
1342
  } catch (error) {
1343
+ if (isGraphInterrupt(error)) {
1344
+ throw error;
1345
+ }
1295
1346
  executorLogger.error("Executor node failed", {
1296
1347
  error: error instanceof Error ? error.message : "Unknown error",
1297
1348
  iteration
@@ -1303,6 +1354,9 @@ function createExecutorNode(config) {
1303
1354
  }
1304
1355
  };
1305
1356
  }
1357
+
1358
+ // src/plan-execute/replanner-node.ts
1359
+ var import_messages3 = require("@langchain/core/messages");
1306
1360
  function createReplannerNode(config) {
1307
1361
  const {
1308
1362
  model,
@@ -1328,19 +1382,19 @@ function createReplannerNode(config) {
1328
1382
  failedSteps: pastSteps.filter((ps) => !ps.success).length
1329
1383
  });
1330
1384
  const completedStepsText = pastSteps.map(
1331
- (ps, idx) => COMPLETED_STEP_TEMPLATE.replace("{stepNumber}", String(idx + 1)).replace("{description}", ps.step.description).replace("{result}", JSON.stringify(ps.result)).replace("{status}", ps.success ? "Success" : `Failed: ${ps.error}`)
1385
+ (ps, idx) => COMPLETED_STEP_TEMPLATE.replace("{stepNumber}", String(idx + 1)).replace("{description}", ps.step.description).replace("{result}", serializePlanExecuteResult(ps.result)).replace("{status}", ps.success ? "Success" : `Failed: ${ps.error}`)
1332
1386
  ).join("\n\n");
1333
1387
  const remainingSteps = plan.steps.slice(currentStepIndex);
1334
1388
  const remainingStepsText = remainingSteps.map(
1335
- (step, idx) => REMAINING_STEP_TEMPLATE.replace("{stepNumber}", String(currentStepIndex + idx + 1)).replace("{description}", step.description).replace("{dependencies}", step.dependencies ? `Dependencies: ${step.dependencies.join(", ")}` : "")
1389
+ (step, idx) => REMAINING_STEP_TEMPLATE.replace("{stepNumber}", String(currentStepIndex + idx + 1)).replace("{description}", step.description).replace("{dependencies}", step.dependencies?.length ? `Dependencies: ${step.dependencies.join(", ")}` : "")
1336
1390
  ).join("\n\n");
1337
1391
  const userPrompt = REPLANNING_PROMPT_TEMPLATE.replace("{goal}", plan.goal).replace("{completedSteps}", completedStepsText || "None").replace("{remainingSteps}", remainingStepsText || "None");
1338
1392
  const messages = [
1339
- new import_messages2.SystemMessage(systemPrompt),
1340
- new import_messages2.HumanMessage(userPrompt)
1393
+ new import_messages3.SystemMessage(systemPrompt),
1394
+ new import_messages3.HumanMessage(userPrompt)
1341
1395
  ];
1342
1396
  const response = await model.invoke(messages);
1343
- const content = response.content.toString();
1397
+ const content = normalizeModelContent(response.content);
1344
1398
  let decision;
1345
1399
  try {
1346
1400
  decision = JSON.parse(content);
@@ -1358,15 +1412,14 @@ function createReplannerNode(config) {
1358
1412
  input: decision.newGoal || plan.goal,
1359
1413
  iteration: 1
1360
1414
  };
1361
- } else {
1362
- replannerLogger.info("Continuing with current plan", {
1363
- reason: decision.reason,
1364
- duration: Date.now() - startTime
1365
- });
1366
- return {
1367
- status: "executing"
1368
- };
1369
1415
  }
1416
+ replannerLogger.info("Continuing with current plan", {
1417
+ reason: decision.reason,
1418
+ duration: Date.now() - startTime
1419
+ });
1420
+ return {
1421
+ status: "executing"
1422
+ };
1370
1423
  } catch (error) {
1371
1424
  replannerLogger.error("Replanning evaluation failed", {
1372
1425
  error: error instanceof Error ? error.message : String(error),
@@ -1379,11 +1432,13 @@ function createReplannerNode(config) {
1379
1432
  }
1380
1433
  };
1381
1434
  }
1435
+
1436
+ // src/plan-execute/finisher-node.ts
1382
1437
  function createFinisherNode() {
1383
1438
  return async (state) => {
1384
1439
  const results = state.pastSteps?.map((ps) => ({
1385
1440
  step: ps.step.description,
1386
- result: ps.result,
1441
+ result: toJsonSafeValue(ps.result),
1387
1442
  success: ps.success
1388
1443
  })) || [];
1389
1444
  const response = JSON.stringify({
@@ -1729,7 +1784,7 @@ var REVISION_ENTRY_TEMPLATE = `Iteration {iteration}:
1729
1784
  {content}`;
1730
1785
 
1731
1786
  // src/reflection/nodes.ts
1732
- var import_messages3 = require("@langchain/core/messages");
1787
+ var import_messages4 = require("@langchain/core/messages");
1733
1788
  var generatorLogger = createPatternLogger("agentforge:patterns:reflection:generator");
1734
1789
  var reflectorLogger = createPatternLogger("agentforge:patterns:reflection:reflector");
1735
1790
  var reviserLogger = createPatternLogger("agentforge:patterns:reflection:reviser");
@@ -1756,8 +1811,8 @@ ${lastReflection.critique}`;
1756
1811
  }
1757
1812
  const userPrompt = GENERATION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{context}", context);
1758
1813
  const messages = [
1759
- new import_messages3.SystemMessage(systemPrompt),
1760
- new import_messages3.HumanMessage(userPrompt)
1814
+ new import_messages4.SystemMessage(systemPrompt),
1815
+ new import_messages4.HumanMessage(userPrompt)
1761
1816
  ];
1762
1817
  const response = await model.invoke(messages);
1763
1818
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -1822,8 +1877,8 @@ function createReflectorNode(config) {
1822
1877
  }
1823
1878
  const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", criteriaSection).replace("{history}", historySection);
1824
1879
  const messages = [
1825
- new import_messages3.SystemMessage(systemPrompt),
1826
- new import_messages3.HumanMessage(userPrompt)
1880
+ new import_messages4.SystemMessage(systemPrompt),
1881
+ new import_messages4.HumanMessage(userPrompt)
1827
1882
  ];
1828
1883
  const response = await model.invoke(messages);
1829
1884
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -1909,8 +1964,8 @@ ${revisionsText}`;
1909
1964
  }
1910
1965
  const userPrompt = REVISION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{critique}", lastReflection.critique).replace("{issues}", lastReflection.issues.join("\n- ")).replace("{suggestions}", lastReflection.suggestions.join("\n- ")).replace("{history}", historySection);
1911
1966
  const messages = [
1912
- new import_messages3.SystemMessage(systemPrompt),
1913
- new import_messages3.HumanMessage(userPrompt)
1967
+ new import_messages4.SystemMessage(systemPrompt),
1968
+ new import_messages4.HumanMessage(userPrompt)
1914
1969
  ];
1915
1970
  const response = await model.invoke(messages);
1916
1971
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -2337,7 +2392,7 @@ var MultiAgentStateConfig = {
2337
2392
  var MultiAgentState = (0, import_core7.createStateAnnotation)(MultiAgentStateConfig);
2338
2393
 
2339
2394
  // src/multi-agent/routing.ts
2340
- var import_messages4 = require("@langchain/core/messages");
2395
+ var import_messages5 = require("@langchain/core/messages");
2341
2396
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2342
2397
 
2343
2398
  Your job is to:
@@ -2392,8 +2447,8 @@ ${workerInfo}
2392
2447
 
2393
2448
  Select the best worker(s) for this task and explain your reasoning.`;
2394
2449
  const messages = [
2395
- new import_messages4.SystemMessage(systemPrompt),
2396
- new import_messages4.HumanMessage(userPrompt)
2450
+ new import_messages5.SystemMessage(systemPrompt),
2451
+ new import_messages5.HumanMessage(userPrompt)
2397
2452
  ];
2398
2453
  const decision = await config.model.invoke(messages);
2399
2454
  return {
@@ -2686,7 +2741,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2686
2741
  }
2687
2742
 
2688
2743
  // src/multi-agent/nodes/shared.ts
2689
- var import_messages5 = require("@langchain/core/messages");
2744
+ var import_messages6 = require("@langchain/core/messages");
2690
2745
  var import_core8 = require("@agentforge/core");
2691
2746
  var logger2 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2692
2747
  function createGeneratedId(prefix) {
@@ -2757,7 +2812,7 @@ function serializeModelContent(content) {
2757
2812
  }
2758
2813
  }
2759
2814
  function createPromptMessages(systemPrompt, task) {
2760
- return [new import_messages5.SystemMessage(systemPrompt), new import_messages5.HumanMessage(task)];
2815
+ return [new import_messages6.SystemMessage(systemPrompt), new import_messages6.HumanMessage(task)];
2761
2816
  }
2762
2817
 
2763
2818
  // src/multi-agent/nodes/aggregator.ts
package/dist/index.d.cts CHANGED
@@ -1426,29 +1426,12 @@ declare function createPlanExecuteAgent<TTool extends PlanExecuteTool = PlanExec
1426
1426
  replanner: Partial<PlanExecuteStateType>;
1427
1427
  }, unknown, unknown>;
1428
1428
 
1429
- /**
1430
- * Node Implementations for Plan-and-Execute Pattern
1431
- *
1432
- * This module implements the core nodes for the Plan-and-Execute agent pattern.
1433
- *
1434
- * @module patterns/plan-execute/nodes
1435
- */
1436
-
1437
- /**
1438
- * Create a planner node that generates a multi-step plan
1439
- */
1440
1429
  declare function createPlannerNode(config: PlannerConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1441
- /**
1442
- * Create an executor node that executes plan steps
1443
- */
1430
+
1444
1431
  declare function createExecutorNode(config: ExecutorConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1445
- /**
1446
- * Create a replanner node that decides whether to replan
1447
- */
1432
+
1448
1433
  declare function createReplannerNode(config: ReplannerConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1449
- /**
1450
- * Create a finisher node that sets the final status and response
1451
- */
1434
+
1452
1435
  declare function createFinisherNode$1(): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1453
1436
 
1454
1437
  /**
package/dist/index.d.ts CHANGED
@@ -1426,29 +1426,12 @@ declare function createPlanExecuteAgent<TTool extends PlanExecuteTool = PlanExec
1426
1426
  replanner: Partial<PlanExecuteStateType>;
1427
1427
  }, unknown, unknown>;
1428
1428
 
1429
- /**
1430
- * Node Implementations for Plan-and-Execute Pattern
1431
- *
1432
- * This module implements the core nodes for the Plan-and-Execute agent pattern.
1433
- *
1434
- * @module patterns/plan-execute/nodes
1435
- */
1436
-
1437
- /**
1438
- * Create a planner node that generates a multi-step plan
1439
- */
1440
1429
  declare function createPlannerNode(config: PlannerConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1441
- /**
1442
- * Create an executor node that executes plan steps
1443
- */
1430
+
1444
1431
  declare function createExecutorNode(config: ExecutorConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1445
- /**
1446
- * Create a replanner node that decides whether to replan
1447
- */
1432
+
1448
1433
  declare function createReplannerNode(config: ReplannerConfig): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1449
- /**
1450
- * Create a finisher node that sets the final status and response
1451
- */
1434
+
1452
1435
  declare function createFinisherNode$1(): (state: PlanExecuteStateType) => Promise<Partial<PlanExecuteStateType>>;
1453
1436
 
1454
1437
  /**
package/dist/index.js CHANGED
@@ -914,7 +914,7 @@ var PlanExecuteStateConfig = {
914
914
  };
915
915
  var PlanExecuteState = createStateAnnotation2(PlanExecuteStateConfig);
916
916
 
917
- // src/plan-execute/nodes.ts
917
+ // src/plan-execute/planner-node.ts
918
918
  import { HumanMessage as HumanMessage2, SystemMessage as SystemMessage2 } from "@langchain/core/messages";
919
919
 
920
920
  // src/plan-execute/prompts.ts
@@ -976,13 +976,61 @@ Status: {status}`;
976
976
  var REMAINING_STEP_TEMPLATE = `Step {stepNumber}: {description}
977
977
  {dependencies}`;
978
978
 
979
- // src/plan-execute/nodes.ts
979
+ // src/plan-execute/node-loggers.ts
980
980
  var plannerLogger = createPatternLogger("agentforge:patterns:plan-execute:planner");
981
981
  var executorLogger = createPatternLogger("agentforge:patterns:plan-execute:executor");
982
982
  var replannerLogger = createPatternLogger("agentforge:patterns:plan-execute:replanner");
983
- function invokePlanExecuteTool(tool, args) {
984
- return tool.invoke.call(tool, args);
983
+
984
+ // src/plan-execute/serialization.ts
985
+ function hasTextContentPart(value) {
986
+ return typeof value === "object" && value !== null && "text" in value && typeof value.text === "string";
987
+ }
988
+ function stringifyWithFallback(value, fallbackLabel) {
989
+ try {
990
+ const serialized = JSON.stringify(value);
991
+ if (serialized === void 0) {
992
+ return "undefined";
993
+ }
994
+ return serialized;
995
+ } catch (error) {
996
+ const reason = error instanceof Error ? error.message : String(error);
997
+ return `[${fallbackLabel}: ${reason}]`;
998
+ }
985
999
  }
1000
+ function toJsonSafeValue(value) {
1001
+ try {
1002
+ const serialized = JSON.stringify(value);
1003
+ if (serialized === void 0) {
1004
+ return void 0;
1005
+ }
1006
+ return JSON.parse(serialized);
1007
+ } catch (error) {
1008
+ const reason = error instanceof Error ? error.message : String(error);
1009
+ return `[Unserializable step result: ${reason}]`;
1010
+ }
1011
+ }
1012
+ function normalizeModelContent(content) {
1013
+ if (typeof content === "string") {
1014
+ return content;
1015
+ }
1016
+ if (Array.isArray(content)) {
1017
+ const textParts = [];
1018
+ for (const part of content) {
1019
+ if (hasTextContentPart(part) && part.text.length > 0) {
1020
+ textParts.push(part.text);
1021
+ }
1022
+ }
1023
+ if (textParts.length > 0) {
1024
+ return textParts.join("\n");
1025
+ }
1026
+ }
1027
+ return stringifyWithFallback(content, "Unserializable model content");
1028
+ }
1029
+ function serializePlanExecuteResult(result) {
1030
+ return stringifyWithFallback(result, "Unserializable step result");
1031
+ }
1032
+
1033
+ // src/plan-execute/planner-node.ts
986
1034
  function createPlannerNode(config) {
987
1035
  const {
988
1036
  model,
@@ -1008,13 +1056,12 @@ function createPlannerNode(config) {
1008
1056
  new HumanMessage2(userPrompt)
1009
1057
  ];
1010
1058
  const response = await model.invoke(messages);
1011
- const content = response.content.toString();
1059
+ const content = normalizeModelContent(response.content);
1012
1060
  let plan;
1013
1061
  try {
1014
1062
  const parsed = JSON.parse(content);
1015
1063
  plan = {
1016
1064
  steps: parsed.steps.slice(0, maxSteps),
1017
- // Limit to maxSteps
1018
1065
  goal: parsed.goal || state.input || "",
1019
1066
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1020
1067
  confidence: parsed.confidence
@@ -1046,6 +1093,11 @@ function createPlannerNode(config) {
1046
1093
  }
1047
1094
  };
1048
1095
  }
1096
+
1097
+ // src/plan-execute/executor-node.ts
1098
+ function invokePlanExecuteTool(tool, args) {
1099
+ return tool.invoke.call(tool, args);
1100
+ }
1049
1101
  function createExecutorNode(config) {
1050
1102
  const {
1051
1103
  tools,
@@ -1072,14 +1124,10 @@ function createExecutorNode(config) {
1072
1124
  deduplicationEnabled: enableDeduplication
1073
1125
  });
1074
1126
  if (!plan || !plan.steps || plan.steps.length === 0) {
1075
- return {
1076
- status: "completed"
1077
- };
1127
+ return { status: "completed" };
1078
1128
  }
1079
1129
  if (currentStepIndex >= plan.steps.length) {
1080
- return {
1081
- status: "completed"
1082
- };
1130
+ return { status: "completed" };
1083
1131
  }
1084
1132
  const currentStep = plan.steps[currentStepIndex];
1085
1133
  if (currentStep.dependencies && currentStep.dependencies.length > 0) {
@@ -1133,7 +1181,7 @@ function createExecutorNode(config) {
1133
1181
  }
1134
1182
  }
1135
1183
  if (!isDuplicate) {
1136
- const tool = tools.find((t) => t.metadata.name === currentStep.tool);
1184
+ const tool = tools.find((candidate) => candidate.metadata.name === currentStep.tool);
1137
1185
  if (!tool) {
1138
1186
  throw new Error(`Tool not found: ${currentStep.tool}`);
1139
1187
  }
@@ -1194,6 +1242,9 @@ function createExecutorNode(config) {
1194
1242
  currentStepIndex: currentStepIndex + 1
1195
1243
  };
1196
1244
  } catch (error) {
1245
+ if (isGraphInterrupt(error)) {
1246
+ throw error;
1247
+ }
1197
1248
  executorLogger.error("Executor node failed", {
1198
1249
  error: error instanceof Error ? error.message : "Unknown error",
1199
1250
  iteration
@@ -1205,6 +1256,9 @@ function createExecutorNode(config) {
1205
1256
  }
1206
1257
  };
1207
1258
  }
1259
+
1260
+ // src/plan-execute/replanner-node.ts
1261
+ import { HumanMessage as HumanMessage3, SystemMessage as SystemMessage3 } from "@langchain/core/messages";
1208
1262
  function createReplannerNode(config) {
1209
1263
  const {
1210
1264
  model,
@@ -1230,19 +1284,19 @@ function createReplannerNode(config) {
1230
1284
  failedSteps: pastSteps.filter((ps) => !ps.success).length
1231
1285
  });
1232
1286
  const completedStepsText = pastSteps.map(
1233
- (ps, idx) => COMPLETED_STEP_TEMPLATE.replace("{stepNumber}", String(idx + 1)).replace("{description}", ps.step.description).replace("{result}", JSON.stringify(ps.result)).replace("{status}", ps.success ? "Success" : `Failed: ${ps.error}`)
1287
+ (ps, idx) => COMPLETED_STEP_TEMPLATE.replace("{stepNumber}", String(idx + 1)).replace("{description}", ps.step.description).replace("{result}", serializePlanExecuteResult(ps.result)).replace("{status}", ps.success ? "Success" : `Failed: ${ps.error}`)
1234
1288
  ).join("\n\n");
1235
1289
  const remainingSteps = plan.steps.slice(currentStepIndex);
1236
1290
  const remainingStepsText = remainingSteps.map(
1237
- (step, idx) => REMAINING_STEP_TEMPLATE.replace("{stepNumber}", String(currentStepIndex + idx + 1)).replace("{description}", step.description).replace("{dependencies}", step.dependencies ? `Dependencies: ${step.dependencies.join(", ")}` : "")
1291
+ (step, idx) => REMAINING_STEP_TEMPLATE.replace("{stepNumber}", String(currentStepIndex + idx + 1)).replace("{description}", step.description).replace("{dependencies}", step.dependencies?.length ? `Dependencies: ${step.dependencies.join(", ")}` : "")
1238
1292
  ).join("\n\n");
1239
1293
  const userPrompt = REPLANNING_PROMPT_TEMPLATE.replace("{goal}", plan.goal).replace("{completedSteps}", completedStepsText || "None").replace("{remainingSteps}", remainingStepsText || "None");
1240
1294
  const messages = [
1241
- new SystemMessage2(systemPrompt),
1242
- new HumanMessage2(userPrompt)
1295
+ new SystemMessage3(systemPrompt),
1296
+ new HumanMessage3(userPrompt)
1243
1297
  ];
1244
1298
  const response = await model.invoke(messages);
1245
- const content = response.content.toString();
1299
+ const content = normalizeModelContent(response.content);
1246
1300
  let decision;
1247
1301
  try {
1248
1302
  decision = JSON.parse(content);
@@ -1260,15 +1314,14 @@ function createReplannerNode(config) {
1260
1314
  input: decision.newGoal || plan.goal,
1261
1315
  iteration: 1
1262
1316
  };
1263
- } else {
1264
- replannerLogger.info("Continuing with current plan", {
1265
- reason: decision.reason,
1266
- duration: Date.now() - startTime
1267
- });
1268
- return {
1269
- status: "executing"
1270
- };
1271
1317
  }
1318
+ replannerLogger.info("Continuing with current plan", {
1319
+ reason: decision.reason,
1320
+ duration: Date.now() - startTime
1321
+ });
1322
+ return {
1323
+ status: "executing"
1324
+ };
1272
1325
  } catch (error) {
1273
1326
  replannerLogger.error("Replanning evaluation failed", {
1274
1327
  error: error instanceof Error ? error.message : String(error),
@@ -1281,11 +1334,13 @@ function createReplannerNode(config) {
1281
1334
  }
1282
1335
  };
1283
1336
  }
1337
+
1338
+ // src/plan-execute/finisher-node.ts
1284
1339
  function createFinisherNode() {
1285
1340
  return async (state) => {
1286
1341
  const results = state.pastSteps?.map((ps) => ({
1287
1342
  step: ps.step.description,
1288
- result: ps.result,
1343
+ result: toJsonSafeValue(ps.result),
1289
1344
  success: ps.success
1290
1345
  })) || [];
1291
1346
  const response = JSON.stringify({
@@ -1631,7 +1686,7 @@ var REVISION_ENTRY_TEMPLATE = `Iteration {iteration}:
1631
1686
  {content}`;
1632
1687
 
1633
1688
  // src/reflection/nodes.ts
1634
- import { HumanMessage as HumanMessage3, SystemMessage as SystemMessage3 } from "@langchain/core/messages";
1689
+ import { HumanMessage as HumanMessage4, SystemMessage as SystemMessage4 } from "@langchain/core/messages";
1635
1690
  var generatorLogger = createPatternLogger("agentforge:patterns:reflection:generator");
1636
1691
  var reflectorLogger = createPatternLogger("agentforge:patterns:reflection:reflector");
1637
1692
  var reviserLogger = createPatternLogger("agentforge:patterns:reflection:reviser");
@@ -1658,8 +1713,8 @@ ${lastReflection.critique}`;
1658
1713
  }
1659
1714
  const userPrompt = GENERATION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{context}", context);
1660
1715
  const messages = [
1661
- new SystemMessage3(systemPrompt),
1662
- new HumanMessage3(userPrompt)
1716
+ new SystemMessage4(systemPrompt),
1717
+ new HumanMessage4(userPrompt)
1663
1718
  ];
1664
1719
  const response = await model.invoke(messages);
1665
1720
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -1724,8 +1779,8 @@ function createReflectorNode(config) {
1724
1779
  }
1725
1780
  const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", criteriaSection).replace("{history}", historySection);
1726
1781
  const messages = [
1727
- new SystemMessage3(systemPrompt),
1728
- new HumanMessage3(userPrompt)
1782
+ new SystemMessage4(systemPrompt),
1783
+ new HumanMessage4(userPrompt)
1729
1784
  ];
1730
1785
  const response = await model.invoke(messages);
1731
1786
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -1811,8 +1866,8 @@ ${revisionsText}`;
1811
1866
  }
1812
1867
  const userPrompt = REVISION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{critique}", lastReflection.critique).replace("{issues}", lastReflection.issues.join("\n- ")).replace("{suggestions}", lastReflection.suggestions.join("\n- ")).replace("{history}", historySection);
1813
1868
  const messages = [
1814
- new SystemMessage3(systemPrompt),
1815
- new HumanMessage3(userPrompt)
1869
+ new SystemMessage4(systemPrompt),
1870
+ new HumanMessage4(userPrompt)
1816
1871
  ];
1817
1872
  const response = await model.invoke(messages);
1818
1873
  const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
@@ -2239,7 +2294,7 @@ var MultiAgentStateConfig = {
2239
2294
  var MultiAgentState = createStateAnnotation4(MultiAgentStateConfig);
2240
2295
 
2241
2296
  // src/multi-agent/routing.ts
2242
- import { HumanMessage as HumanMessage4, SystemMessage as SystemMessage4 } from "@langchain/core/messages";
2297
+ import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
2243
2298
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2244
2299
 
2245
2300
  Your job is to:
@@ -2294,8 +2349,8 @@ ${workerInfo}
2294
2349
 
2295
2350
  Select the best worker(s) for this task and explain your reasoning.`;
2296
2351
  const messages = [
2297
- new SystemMessage4(systemPrompt),
2298
- new HumanMessage4(userPrompt)
2352
+ new SystemMessage5(systemPrompt),
2353
+ new HumanMessage5(userPrompt)
2299
2354
  ];
2300
2355
  const decision = await config.model.invoke(messages);
2301
2356
  return {
@@ -2588,7 +2643,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2588
2643
  }
2589
2644
 
2590
2645
  // src/multi-agent/nodes/shared.ts
2591
- import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
2646
+ import { HumanMessage as HumanMessage6, SystemMessage as SystemMessage6 } from "@langchain/core/messages";
2592
2647
  import { toLangChainTools as toLangChainTools2 } from "@agentforge/core";
2593
2648
  var logger2 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2594
2649
  function createGeneratedId(prefix) {
@@ -2659,7 +2714,7 @@ function serializeModelContent(content) {
2659
2714
  }
2660
2715
  }
2661
2716
  function createPromptMessages(systemPrompt, task) {
2662
- return [new SystemMessage5(systemPrompt), new HumanMessage5(task)];
2717
+ return [new SystemMessage6(systemPrompt), new HumanMessage6(task)];
2663
2718
  }
2664
2719
 
2665
2720
  // src/multi-agent/nodes/aggregator.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/patterns",
3
- "version": "0.16.14",
3
+ "version": "0.16.16",
4
4
  "description": "Production-ready agent workflow patterns for TypeScript including ReAct and Planner-Executor, built on LangGraph.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -41,13 +41,13 @@
41
41
  "url": "https://github.com/TVScoundrel/agentforge/issues"
42
42
  },
43
43
  "dependencies": {
44
- "@agentforge/core": "0.16.14",
44
+ "@agentforge/core": "0.16.16",
45
45
  "@langchain/core": "^1.1.17",
46
46
  "@langchain/langgraph": "^1.1.2",
47
47
  "zod": "^3.23.8"
48
48
  },
49
49
  "devDependencies": {
50
- "@agentforge/testing": "0.16.14",
50
+ "@agentforge/testing": "0.16.16",
51
51
  "@eslint/js": "^9.17.0",
52
52
  "@types/node": "^22.10.2",
53
53
  "eslint": "^9.17.0",