@agentforge/patterns 0.16.40 → 0.16.42

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
@@ -1783,16 +1783,33 @@ Suggestions: {suggestions}`;
1783
1783
  var REVISION_ENTRY_TEMPLATE = `Iteration {iteration}:
1784
1784
  {content}`;
1785
1785
 
1786
- // src/reflection/nodes.ts
1786
+ // src/reflection/generator-node.ts
1787
1787
  var import_messages4 = require("@langchain/core/messages");
1788
+
1789
+ // src/reflection/node-shared.ts
1788
1790
  var generatorLogger = createPatternLogger("agentforge:patterns:reflection:generator");
1789
1791
  var reflectorLogger = createPatternLogger("agentforge:patterns:reflection:reflector");
1790
1792
  var reviserLogger = createPatternLogger("agentforge:patterns:reflection:reviser");
1793
+ function serializeModelContent(content) {
1794
+ return typeof content === "string" ? content : JSON.stringify(content);
1795
+ }
1796
+ function buildRevisionHistorySection(revisions, heading) {
1797
+ if (revisions.length === 0) {
1798
+ return "";
1799
+ }
1800
+ const revisionsText = revisions.map(
1801
+ (revision) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", revision.iteration.toString()).replace("{content}", `${revision.content.substring(0, 200)}...`)
1802
+ ).join("\n\n");
1803
+ return `
1804
+ ${heading}:
1805
+ ${revisionsText}`;
1806
+ }
1807
+
1808
+ // src/reflection/generator-node.ts
1791
1809
  function createGeneratorNode(config) {
1792
1810
  const {
1793
1811
  model,
1794
- systemPrompt = DEFAULT_GENERATOR_SYSTEM_PROMPT,
1795
- verbose = false
1812
+ systemPrompt = DEFAULT_GENERATOR_SYSTEM_PROMPT
1796
1813
  } = config;
1797
1814
  return async (state) => {
1798
1815
  const startTime = Date.now();
@@ -1802,20 +1819,16 @@ function createGeneratorNode(config) {
1802
1819
  hasFeedback: state.reflections.length > 0,
1803
1820
  hasExistingResponse: !!state.currentResponse
1804
1821
  });
1805
- let context = "";
1806
- if (state.iteration > 0 && state.reflections.length > 0) {
1807
- const lastReflection = state.reflections[state.reflections.length - 1];
1808
- context = `
1822
+ const lastReflection = state.reflections[state.reflections.length - 1];
1823
+ const context = state.iteration > 0 && lastReflection ? `
1809
1824
  Previous feedback to consider:
1810
- ${lastReflection.critique}`;
1811
- }
1825
+ ${lastReflection.critique}` : "";
1812
1826
  const userPrompt = GENERATION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{context}", context);
1813
- const messages = [
1827
+ const response = await model.invoke([
1814
1828
  new import_messages4.SystemMessage(systemPrompt),
1815
1829
  new import_messages4.HumanMessage(userPrompt)
1816
- ];
1817
- const response = await model.invoke(messages);
1818
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1830
+ ]);
1831
+ const content = serializeModelContent(response.content);
1819
1832
  generatorLogger.info("Response generated", {
1820
1833
  attempt: state.iteration + 1,
1821
1834
  responseLength: content.length,
@@ -1841,12 +1854,47 @@ ${lastReflection.critique}`;
1841
1854
  }
1842
1855
  };
1843
1856
  }
1857
+
1858
+ // src/reflection/reflector-node.ts
1859
+ var import_messages5 = require("@langchain/core/messages");
1860
+ function buildCriteriaSection(config, state) {
1861
+ const criteria = config.qualityCriteria || state.qualityCriteria;
1862
+ if (!criteria) {
1863
+ return "";
1864
+ }
1865
+ const criteriaList = criteria.criteria?.join("\n- ") || "";
1866
+ return QUALITY_CRITERIA_TEMPLATE.replace("{criteria}", criteriaList ? `- ${criteriaList}` : "General quality standards").replace("{minScore}", criteria.minScore?.toString() || "7").replace("{requireAll}", criteria.requireAll ? "All criteria must be met." : "Meet as many criteria as possible.");
1867
+ }
1868
+ function buildHistorySection(state) {
1869
+ if (state.reflections.length === 0 && state.revisions.length === 0) {
1870
+ return "";
1871
+ }
1872
+ const reflectionsText = state.reflections.map(
1873
+ (reflection, idx) => REFLECTION_ENTRY_TEMPLATE.replace("{iteration}", (idx + 1).toString()).replace("{critique}", reflection.critique).replace("{score}", reflection.score?.toString() || "N/A").replace("{issues}", reflection.issues.join(", ")).replace("{suggestions}", reflection.suggestions.join(", "))
1874
+ ).join("\n\n");
1875
+ const revisionsText = buildRevisionHistorySection(state.revisions, "Previous Revisions").replace("\nPrevious Revisions:\n", "");
1876
+ return REFLECTION_HISTORY_TEMPLATE.replace("{reflections}", reflectionsText || "None").replace("{revisions}", revisionsText || "None");
1877
+ }
1878
+ function parseReflection(content) {
1879
+ try {
1880
+ const jsonMatch = content.match(/\{[\s\S]*\}/);
1881
+ if (jsonMatch) {
1882
+ return JSON.parse(jsonMatch[0]);
1883
+ }
1884
+ } catch {
1885
+ }
1886
+ return {
1887
+ critique: content,
1888
+ issues: [],
1889
+ suggestions: [],
1890
+ score: 5,
1891
+ meetsStandards: false
1892
+ };
1893
+ }
1844
1894
  function createReflectorNode(config) {
1845
1895
  const {
1846
1896
  model,
1847
- systemPrompt = DEFAULT_REFLECTOR_SYSTEM_PROMPT,
1848
- qualityCriteria,
1849
- verbose = false
1897
+ systemPrompt = DEFAULT_REFLECTOR_SYSTEM_PROMPT
1850
1898
  } = config;
1851
1899
  return async (state) => {
1852
1900
  const startTime = Date.now();
@@ -1854,57 +1902,17 @@ function createReflectorNode(config) {
1854
1902
  reflectorLogger.debug("Reflecting on response", {
1855
1903
  attempt: state.iteration,
1856
1904
  responseLength: state.currentResponse?.length || 0,
1857
- hasCriteria: !!(qualityCriteria || state.qualityCriteria)
1905
+ hasCriteria: !!(config.qualityCriteria || state.qualityCriteria)
1858
1906
  });
1859
1907
  if (!state.currentResponse) {
1860
1908
  throw new Error("No current response to reflect on");
1861
1909
  }
1862
- let criteriaSection = "";
1863
- const criteria = qualityCriteria || state.qualityCriteria;
1864
- if (criteria) {
1865
- const criteriaList = criteria.criteria?.join("\n- ") || "";
1866
- criteriaSection = QUALITY_CRITERIA_TEMPLATE.replace("{criteria}", criteriaList ? `- ${criteriaList}` : "General quality standards").replace("{minScore}", criteria.minScore?.toString() || "7").replace("{requireAll}", criteria.requireAll ? "All criteria must be met." : "Meet as many criteria as possible.");
1867
- }
1868
- let historySection = "";
1869
- if (state.reflections.length > 0 || state.revisions.length > 0) {
1870
- const reflectionsText = state.reflections.map(
1871
- (r, idx) => REFLECTION_ENTRY_TEMPLATE.replace("{iteration}", (idx + 1).toString()).replace("{critique}", r.critique).replace("{score}", r.score?.toString() || "N/A").replace("{issues}", r.issues.join(", ")).replace("{suggestions}", r.suggestions.join(", "))
1872
- ).join("\n\n");
1873
- const revisionsText = state.revisions.map(
1874
- (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1875
- ).join("\n\n");
1876
- historySection = REFLECTION_HISTORY_TEMPLATE.replace("{reflections}", reflectionsText || "None").replace("{revisions}", revisionsText || "None");
1877
- }
1878
- const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", criteriaSection).replace("{history}", historySection);
1879
- const messages = [
1880
- new import_messages4.SystemMessage(systemPrompt),
1881
- new import_messages4.HumanMessage(userPrompt)
1882
- ];
1883
- const response = await model.invoke(messages);
1884
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1885
- let reflection;
1886
- try {
1887
- const jsonMatch = content.match(/\{[\s\S]*\}/);
1888
- if (jsonMatch) {
1889
- reflection = JSON.parse(jsonMatch[0]);
1890
- } else {
1891
- reflection = {
1892
- critique: content,
1893
- issues: [],
1894
- suggestions: [],
1895
- score: 5,
1896
- meetsStandards: false
1897
- };
1898
- }
1899
- } catch (parseError) {
1900
- reflection = {
1901
- critique: content,
1902
- issues: [],
1903
- suggestions: [],
1904
- score: 5,
1905
- meetsStandards: false
1906
- };
1907
- }
1910
+ const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", buildCriteriaSection(config, state)).replace("{history}", buildHistorySection(state));
1911
+ const response = await model.invoke([
1912
+ new import_messages5.SystemMessage(systemPrompt),
1913
+ new import_messages5.HumanMessage(userPrompt)
1914
+ ]);
1915
+ const reflection = parseReflection(serializeModelContent(response.content));
1908
1916
  reflectorLogger.info("Reflection complete", {
1909
1917
  attempt: state.iteration,
1910
1918
  ...reflection.score !== void 0 ? { score: reflection.score } : {},
@@ -1931,11 +1939,13 @@ function createReflectorNode(config) {
1931
1939
  }
1932
1940
  };
1933
1941
  }
1942
+
1943
+ // src/reflection/reviser-node.ts
1944
+ var import_messages6 = require("@langchain/core/messages");
1934
1945
  function createReviserNode(config) {
1935
1946
  const {
1936
1947
  model,
1937
- systemPrompt = DEFAULT_REVISER_SYSTEM_PROMPT,
1938
- verbose = false
1948
+ systemPrompt = DEFAULT_REVISER_SYSTEM_PROMPT
1939
1949
  } = config;
1940
1950
  return async (state) => {
1941
1951
  const startTime = Date.now();
@@ -1943,37 +1953,23 @@ function createReviserNode(config) {
1943
1953
  if (!state.currentResponse) {
1944
1954
  throw new Error("No current response to revise");
1945
1955
  }
1946
- if (state.reflections.length === 0) {
1956
+ const lastReflection = state.reflections[state.reflections.length - 1];
1957
+ if (!lastReflection) {
1947
1958
  throw new Error("No reflections to base revision on");
1948
1959
  }
1949
- const lastReflection = state.reflections[state.reflections.length - 1];
1950
1960
  reviserLogger.debug("Revising response", {
1951
1961
  attempt: state.iteration,
1952
1962
  ...lastReflection.score !== void 0 ? { previousScore: lastReflection.score } : {},
1953
1963
  issueCount: lastReflection.issues.length,
1954
1964
  suggestionCount: lastReflection.suggestions.length
1955
1965
  });
1956
- let historySection = "";
1957
- if (state.revisions.length > 0) {
1958
- const revisionsText = state.revisions.map(
1959
- (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1960
- ).join("\n\n");
1961
- historySection = `
1962
- Previous Revisions:
1963
- ${revisionsText}`;
1964
- }
1966
+ const historySection = buildRevisionHistorySection(state.revisions, "Previous Revisions");
1965
1967
  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);
1966
- const messages = [
1967
- new import_messages4.SystemMessage(systemPrompt),
1968
- new import_messages4.HumanMessage(userPrompt)
1969
- ];
1970
- const response = await model.invoke(messages);
1971
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1972
- const revision = {
1973
- content,
1974
- iteration: state.iteration,
1975
- basedOn: lastReflection
1976
- };
1968
+ const response = await model.invoke([
1969
+ new import_messages6.SystemMessage(systemPrompt),
1970
+ new import_messages6.HumanMessage(userPrompt)
1971
+ ]);
1972
+ const content = serializeModelContent(response.content);
1977
1973
  reviserLogger.info("Revision complete", {
1978
1974
  attempt: state.iteration,
1979
1975
  revisionLength: content.length,
@@ -1982,7 +1978,11 @@ ${revisionsText}`;
1982
1978
  });
1983
1979
  return {
1984
1980
  currentResponse: content,
1985
- revisions: [revision],
1981
+ revisions: [{
1982
+ content,
1983
+ iteration: state.iteration,
1984
+ basedOn: lastReflection
1985
+ }],
1986
1986
  status: "reflecting",
1987
1987
  iteration: 1
1988
1988
  };
@@ -2000,13 +2000,13 @@ ${revisionsText}`;
2000
2000
  }
2001
2001
  };
2002
2002
  }
2003
+
2004
+ // src/reflection/finisher-node.ts
2003
2005
  function createFinisherNode2() {
2004
- return async (state) => {
2005
- return {
2006
- status: "completed",
2007
- response: state.currentResponse
2008
- };
2009
- };
2006
+ return async (state) => ({
2007
+ status: "completed",
2008
+ response: state.currentResponse
2009
+ });
2010
2010
  }
2011
2011
 
2012
2012
  // src/reflection/agent.ts
@@ -2392,7 +2392,7 @@ var MultiAgentStateConfig = {
2392
2392
  var MultiAgentState = (0, import_core7.createStateAnnotation)(MultiAgentStateConfig);
2393
2393
 
2394
2394
  // src/multi-agent/routing-internal/llm-routing.ts
2395
- var import_messages5 = require("@langchain/core/messages");
2395
+ var import_messages7 = require("@langchain/core/messages");
2396
2396
  var logger = createPatternLogger("agentforge:patterns:multi-agent:routing");
2397
2397
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2398
2398
 
@@ -2526,8 +2526,8 @@ ${workerInfo}
2526
2526
 
2527
2527
  Select the best worker(s) for this task and explain your reasoning.`;
2528
2528
  const messages = [
2529
- new import_messages5.SystemMessage(systemPrompt),
2530
- new import_messages5.HumanMessage(userPrompt)
2529
+ new import_messages7.SystemMessage(systemPrompt),
2530
+ new import_messages7.HumanMessage(userPrompt)
2531
2531
  ];
2532
2532
  return invokeRoutingDecision(config.model, messages);
2533
2533
  }
@@ -2845,7 +2845,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2845
2845
  }
2846
2846
 
2847
2847
  // src/multi-agent/nodes/shared.ts
2848
- var import_messages6 = require("@langchain/core/messages");
2848
+ var import_messages8 = require("@langchain/core/messages");
2849
2849
  var import_core8 = require("@agentforge/core");
2850
2850
  var logger3 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2851
2851
  function createGeneratedId(prefix) {
@@ -2889,7 +2889,7 @@ function convertWorkerToolsForLangChain(tools) {
2889
2889
  const safeTools = tools ?? [];
2890
2890
  return (0, import_core8.toLangChainTools)(safeTools);
2891
2891
  }
2892
- function serializeModelContent(content) {
2892
+ function serializeModelContent2(content) {
2893
2893
  if (typeof content === "string") {
2894
2894
  return content;
2895
2895
  }
@@ -2916,7 +2916,7 @@ function serializeModelContent(content) {
2916
2916
  }
2917
2917
  }
2918
2918
  function createPromptMessages(systemPrompt, task) {
2919
- return [new import_messages6.SystemMessage(systemPrompt), new import_messages6.HumanMessage(task)];
2919
+ return [new import_messages8.SystemMessage(systemPrompt), new import_messages8.HumanMessage(task)];
2920
2920
  }
2921
2921
 
2922
2922
  // src/multi-agent/nodes/aggregator.ts
@@ -2992,7 +2992,7 @@ function createAggregatorNode(config = {}) {
2992
2992
  const messages = createPromptMessages(systemPrompt, createAggregationPrompt(state));
2993
2993
  logger3.debug("Invoking aggregation LLM");
2994
2994
  const response = await model.invoke(messages);
2995
- const aggregatedResponse = serializeModelContent(response.content);
2995
+ const aggregatedResponse = serializeModelContent2(response.content);
2996
2996
  logger3.info("Aggregation complete", {
2997
2997
  responseLength: aggregatedResponse.length
2998
2998
  });
@@ -3186,7 +3186,7 @@ async function invokeWorkerModel(model, config, assignment) {
3186
3186
  }
3187
3187
  logger3.debug("Invoking LLM", { workerId: config.id });
3188
3188
  const response = await modelToUse.invoke(messages);
3189
- const result = serializeModelContent(response.content);
3189
+ const result = serializeModelContent2(response.content);
3190
3190
  logger3.info("Worker task completed", {
3191
3191
  workerId: config.id,
3192
3192
  assignmentId: assignment.id,
package/dist/index.d.cts CHANGED
@@ -2132,29 +2132,12 @@ declare const REFLECTION_ENTRY_TEMPLATE = "Iteration {iteration}:\nCritique: {cr
2132
2132
  */
2133
2133
  declare const REVISION_ENTRY_TEMPLATE = "Iteration {iteration}:\n{content}";
2134
2134
 
2135
- /**
2136
- * Node Implementations for Reflection Pattern
2137
- *
2138
- * This module implements the core nodes for the Reflection agent pattern.
2139
- *
2140
- * @module patterns/reflection/nodes
2141
- */
2142
-
2143
- /**
2144
- * Create a generator node that creates initial responses
2145
- */
2146
2135
  declare function createGeneratorNode(config: GeneratorConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2147
- /**
2148
- * Create a reflector node that critiques responses
2149
- */
2136
+
2150
2137
  declare function createReflectorNode(config: ReflectorConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2151
- /**
2152
- * Create a reviser node that improves responses based on critiques
2153
- */
2138
+
2154
2139
  declare function createReviserNode(config: ReviserConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2155
- /**
2156
- * Create a finisher node that marks the reflection as complete
2157
- */
2140
+
2158
2141
  declare function createFinisherNode(): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2159
2142
 
2160
2143
  /**
package/dist/index.d.ts CHANGED
@@ -2132,29 +2132,12 @@ declare const REFLECTION_ENTRY_TEMPLATE = "Iteration {iteration}:\nCritique: {cr
2132
2132
  */
2133
2133
  declare const REVISION_ENTRY_TEMPLATE = "Iteration {iteration}:\n{content}";
2134
2134
 
2135
- /**
2136
- * Node Implementations for Reflection Pattern
2137
- *
2138
- * This module implements the core nodes for the Reflection agent pattern.
2139
- *
2140
- * @module patterns/reflection/nodes
2141
- */
2142
-
2143
- /**
2144
- * Create a generator node that creates initial responses
2145
- */
2146
2135
  declare function createGeneratorNode(config: GeneratorConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2147
- /**
2148
- * Create a reflector node that critiques responses
2149
- */
2136
+
2150
2137
  declare function createReflectorNode(config: ReflectorConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2151
- /**
2152
- * Create a reviser node that improves responses based on critiques
2153
- */
2138
+
2154
2139
  declare function createReviserNode(config: ReviserConfig): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2155
- /**
2156
- * Create a finisher node that marks the reflection as complete
2157
- */
2140
+
2158
2141
  declare function createFinisherNode(): (state: ReflectionStateType) => Promise<Partial<ReflectionStateType>>;
2159
2142
 
2160
2143
  /**
package/dist/index.js CHANGED
@@ -1685,16 +1685,33 @@ Suggestions: {suggestions}`;
1685
1685
  var REVISION_ENTRY_TEMPLATE = `Iteration {iteration}:
1686
1686
  {content}`;
1687
1687
 
1688
- // src/reflection/nodes.ts
1688
+ // src/reflection/generator-node.ts
1689
1689
  import { HumanMessage as HumanMessage4, SystemMessage as SystemMessage4 } from "@langchain/core/messages";
1690
+
1691
+ // src/reflection/node-shared.ts
1690
1692
  var generatorLogger = createPatternLogger("agentforge:patterns:reflection:generator");
1691
1693
  var reflectorLogger = createPatternLogger("agentforge:patterns:reflection:reflector");
1692
1694
  var reviserLogger = createPatternLogger("agentforge:patterns:reflection:reviser");
1695
+ function serializeModelContent(content) {
1696
+ return typeof content === "string" ? content : JSON.stringify(content);
1697
+ }
1698
+ function buildRevisionHistorySection(revisions, heading) {
1699
+ if (revisions.length === 0) {
1700
+ return "";
1701
+ }
1702
+ const revisionsText = revisions.map(
1703
+ (revision) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", revision.iteration.toString()).replace("{content}", `${revision.content.substring(0, 200)}...`)
1704
+ ).join("\n\n");
1705
+ return `
1706
+ ${heading}:
1707
+ ${revisionsText}`;
1708
+ }
1709
+
1710
+ // src/reflection/generator-node.ts
1693
1711
  function createGeneratorNode(config) {
1694
1712
  const {
1695
1713
  model,
1696
- systemPrompt = DEFAULT_GENERATOR_SYSTEM_PROMPT,
1697
- verbose = false
1714
+ systemPrompt = DEFAULT_GENERATOR_SYSTEM_PROMPT
1698
1715
  } = config;
1699
1716
  return async (state) => {
1700
1717
  const startTime = Date.now();
@@ -1704,20 +1721,16 @@ function createGeneratorNode(config) {
1704
1721
  hasFeedback: state.reflections.length > 0,
1705
1722
  hasExistingResponse: !!state.currentResponse
1706
1723
  });
1707
- let context = "";
1708
- if (state.iteration > 0 && state.reflections.length > 0) {
1709
- const lastReflection = state.reflections[state.reflections.length - 1];
1710
- context = `
1724
+ const lastReflection = state.reflections[state.reflections.length - 1];
1725
+ const context = state.iteration > 0 && lastReflection ? `
1711
1726
  Previous feedback to consider:
1712
- ${lastReflection.critique}`;
1713
- }
1727
+ ${lastReflection.critique}` : "";
1714
1728
  const userPrompt = GENERATION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{context}", context);
1715
- const messages = [
1729
+ const response = await model.invoke([
1716
1730
  new SystemMessage4(systemPrompt),
1717
1731
  new HumanMessage4(userPrompt)
1718
- ];
1719
- const response = await model.invoke(messages);
1720
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1732
+ ]);
1733
+ const content = serializeModelContent(response.content);
1721
1734
  generatorLogger.info("Response generated", {
1722
1735
  attempt: state.iteration + 1,
1723
1736
  responseLength: content.length,
@@ -1743,12 +1756,47 @@ ${lastReflection.critique}`;
1743
1756
  }
1744
1757
  };
1745
1758
  }
1759
+
1760
+ // src/reflection/reflector-node.ts
1761
+ import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
1762
+ function buildCriteriaSection(config, state) {
1763
+ const criteria = config.qualityCriteria || state.qualityCriteria;
1764
+ if (!criteria) {
1765
+ return "";
1766
+ }
1767
+ const criteriaList = criteria.criteria?.join("\n- ") || "";
1768
+ return QUALITY_CRITERIA_TEMPLATE.replace("{criteria}", criteriaList ? `- ${criteriaList}` : "General quality standards").replace("{minScore}", criteria.minScore?.toString() || "7").replace("{requireAll}", criteria.requireAll ? "All criteria must be met." : "Meet as many criteria as possible.");
1769
+ }
1770
+ function buildHistorySection(state) {
1771
+ if (state.reflections.length === 0 && state.revisions.length === 0) {
1772
+ return "";
1773
+ }
1774
+ const reflectionsText = state.reflections.map(
1775
+ (reflection, idx) => REFLECTION_ENTRY_TEMPLATE.replace("{iteration}", (idx + 1).toString()).replace("{critique}", reflection.critique).replace("{score}", reflection.score?.toString() || "N/A").replace("{issues}", reflection.issues.join(", ")).replace("{suggestions}", reflection.suggestions.join(", "))
1776
+ ).join("\n\n");
1777
+ const revisionsText = buildRevisionHistorySection(state.revisions, "Previous Revisions").replace("\nPrevious Revisions:\n", "");
1778
+ return REFLECTION_HISTORY_TEMPLATE.replace("{reflections}", reflectionsText || "None").replace("{revisions}", revisionsText || "None");
1779
+ }
1780
+ function parseReflection(content) {
1781
+ try {
1782
+ const jsonMatch = content.match(/\{[\s\S]*\}/);
1783
+ if (jsonMatch) {
1784
+ return JSON.parse(jsonMatch[0]);
1785
+ }
1786
+ } catch {
1787
+ }
1788
+ return {
1789
+ critique: content,
1790
+ issues: [],
1791
+ suggestions: [],
1792
+ score: 5,
1793
+ meetsStandards: false
1794
+ };
1795
+ }
1746
1796
  function createReflectorNode(config) {
1747
1797
  const {
1748
1798
  model,
1749
- systemPrompt = DEFAULT_REFLECTOR_SYSTEM_PROMPT,
1750
- qualityCriteria,
1751
- verbose = false
1799
+ systemPrompt = DEFAULT_REFLECTOR_SYSTEM_PROMPT
1752
1800
  } = config;
1753
1801
  return async (state) => {
1754
1802
  const startTime = Date.now();
@@ -1756,57 +1804,17 @@ function createReflectorNode(config) {
1756
1804
  reflectorLogger.debug("Reflecting on response", {
1757
1805
  attempt: state.iteration,
1758
1806
  responseLength: state.currentResponse?.length || 0,
1759
- hasCriteria: !!(qualityCriteria || state.qualityCriteria)
1807
+ hasCriteria: !!(config.qualityCriteria || state.qualityCriteria)
1760
1808
  });
1761
1809
  if (!state.currentResponse) {
1762
1810
  throw new Error("No current response to reflect on");
1763
1811
  }
1764
- let criteriaSection = "";
1765
- const criteria = qualityCriteria || state.qualityCriteria;
1766
- if (criteria) {
1767
- const criteriaList = criteria.criteria?.join("\n- ") || "";
1768
- criteriaSection = QUALITY_CRITERIA_TEMPLATE.replace("{criteria}", criteriaList ? `- ${criteriaList}` : "General quality standards").replace("{minScore}", criteria.minScore?.toString() || "7").replace("{requireAll}", criteria.requireAll ? "All criteria must be met." : "Meet as many criteria as possible.");
1769
- }
1770
- let historySection = "";
1771
- if (state.reflections.length > 0 || state.revisions.length > 0) {
1772
- const reflectionsText = state.reflections.map(
1773
- (r, idx) => REFLECTION_ENTRY_TEMPLATE.replace("{iteration}", (idx + 1).toString()).replace("{critique}", r.critique).replace("{score}", r.score?.toString() || "N/A").replace("{issues}", r.issues.join(", ")).replace("{suggestions}", r.suggestions.join(", "))
1774
- ).join("\n\n");
1775
- const revisionsText = state.revisions.map(
1776
- (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1777
- ).join("\n\n");
1778
- historySection = REFLECTION_HISTORY_TEMPLATE.replace("{reflections}", reflectionsText || "None").replace("{revisions}", revisionsText || "None");
1779
- }
1780
- const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", criteriaSection).replace("{history}", historySection);
1781
- const messages = [
1782
- new SystemMessage4(systemPrompt),
1783
- new HumanMessage4(userPrompt)
1784
- ];
1785
- const response = await model.invoke(messages);
1786
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1787
- let reflection;
1788
- try {
1789
- const jsonMatch = content.match(/\{[\s\S]*\}/);
1790
- if (jsonMatch) {
1791
- reflection = JSON.parse(jsonMatch[0]);
1792
- } else {
1793
- reflection = {
1794
- critique: content,
1795
- issues: [],
1796
- suggestions: [],
1797
- score: 5,
1798
- meetsStandards: false
1799
- };
1800
- }
1801
- } catch (parseError) {
1802
- reflection = {
1803
- critique: content,
1804
- issues: [],
1805
- suggestions: [],
1806
- score: 5,
1807
- meetsStandards: false
1808
- };
1809
- }
1812
+ const userPrompt = REFLECTION_PROMPT_TEMPLATE.replace("{input}", state.input || "").replace("{currentResponse}", state.currentResponse).replace("{criteria}", buildCriteriaSection(config, state)).replace("{history}", buildHistorySection(state));
1813
+ const response = await model.invoke([
1814
+ new SystemMessage5(systemPrompt),
1815
+ new HumanMessage5(userPrompt)
1816
+ ]);
1817
+ const reflection = parseReflection(serializeModelContent(response.content));
1810
1818
  reflectorLogger.info("Reflection complete", {
1811
1819
  attempt: state.iteration,
1812
1820
  ...reflection.score !== void 0 ? { score: reflection.score } : {},
@@ -1833,11 +1841,13 @@ function createReflectorNode(config) {
1833
1841
  }
1834
1842
  };
1835
1843
  }
1844
+
1845
+ // src/reflection/reviser-node.ts
1846
+ import { HumanMessage as HumanMessage6, SystemMessage as SystemMessage6 } from "@langchain/core/messages";
1836
1847
  function createReviserNode(config) {
1837
1848
  const {
1838
1849
  model,
1839
- systemPrompt = DEFAULT_REVISER_SYSTEM_PROMPT,
1840
- verbose = false
1850
+ systemPrompt = DEFAULT_REVISER_SYSTEM_PROMPT
1841
1851
  } = config;
1842
1852
  return async (state) => {
1843
1853
  const startTime = Date.now();
@@ -1845,37 +1855,23 @@ function createReviserNode(config) {
1845
1855
  if (!state.currentResponse) {
1846
1856
  throw new Error("No current response to revise");
1847
1857
  }
1848
- if (state.reflections.length === 0) {
1858
+ const lastReflection = state.reflections[state.reflections.length - 1];
1859
+ if (!lastReflection) {
1849
1860
  throw new Error("No reflections to base revision on");
1850
1861
  }
1851
- const lastReflection = state.reflections[state.reflections.length - 1];
1852
1862
  reviserLogger.debug("Revising response", {
1853
1863
  attempt: state.iteration,
1854
1864
  ...lastReflection.score !== void 0 ? { previousScore: lastReflection.score } : {},
1855
1865
  issueCount: lastReflection.issues.length,
1856
1866
  suggestionCount: lastReflection.suggestions.length
1857
1867
  });
1858
- let historySection = "";
1859
- if (state.revisions.length > 0) {
1860
- const revisionsText = state.revisions.map(
1861
- (r) => REVISION_ENTRY_TEMPLATE.replace("{iteration}", r.iteration.toString()).replace("{content}", r.content.substring(0, 200) + "...")
1862
- ).join("\n\n");
1863
- historySection = `
1864
- Previous Revisions:
1865
- ${revisionsText}`;
1866
- }
1868
+ const historySection = buildRevisionHistorySection(state.revisions, "Previous Revisions");
1867
1869
  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);
1868
- const messages = [
1869
- new SystemMessage4(systemPrompt),
1870
- new HumanMessage4(userPrompt)
1871
- ];
1872
- const response = await model.invoke(messages);
1873
- const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
1874
- const revision = {
1875
- content,
1876
- iteration: state.iteration,
1877
- basedOn: lastReflection
1878
- };
1870
+ const response = await model.invoke([
1871
+ new SystemMessage6(systemPrompt),
1872
+ new HumanMessage6(userPrompt)
1873
+ ]);
1874
+ const content = serializeModelContent(response.content);
1879
1875
  reviserLogger.info("Revision complete", {
1880
1876
  attempt: state.iteration,
1881
1877
  revisionLength: content.length,
@@ -1884,7 +1880,11 @@ ${revisionsText}`;
1884
1880
  });
1885
1881
  return {
1886
1882
  currentResponse: content,
1887
- revisions: [revision],
1883
+ revisions: [{
1884
+ content,
1885
+ iteration: state.iteration,
1886
+ basedOn: lastReflection
1887
+ }],
1888
1888
  status: "reflecting",
1889
1889
  iteration: 1
1890
1890
  };
@@ -1902,13 +1902,13 @@ ${revisionsText}`;
1902
1902
  }
1903
1903
  };
1904
1904
  }
1905
+
1906
+ // src/reflection/finisher-node.ts
1905
1907
  function createFinisherNode2() {
1906
- return async (state) => {
1907
- return {
1908
- status: "completed",
1909
- response: state.currentResponse
1910
- };
1911
- };
1908
+ return async (state) => ({
1909
+ status: "completed",
1910
+ response: state.currentResponse
1911
+ });
1912
1912
  }
1913
1913
 
1914
1914
  // src/reflection/agent.ts
@@ -2294,7 +2294,7 @@ var MultiAgentStateConfig = {
2294
2294
  var MultiAgentState = createStateAnnotation4(MultiAgentStateConfig);
2295
2295
 
2296
2296
  // src/multi-agent/routing-internal/llm-routing.ts
2297
- import { HumanMessage as HumanMessage5, SystemMessage as SystemMessage5 } from "@langchain/core/messages";
2297
+ import { HumanMessage as HumanMessage7, SystemMessage as SystemMessage7 } from "@langchain/core/messages";
2298
2298
  var logger = createPatternLogger("agentforge:patterns:multi-agent:routing");
2299
2299
  var DEFAULT_SUPERVISOR_SYSTEM_PROMPT = `You are a supervisor agent responsible for routing tasks to specialized worker agents.
2300
2300
 
@@ -2428,8 +2428,8 @@ ${workerInfo}
2428
2428
 
2429
2429
  Select the best worker(s) for this task and explain your reasoning.`;
2430
2430
  const messages = [
2431
- new SystemMessage5(systemPrompt),
2432
- new HumanMessage5(userPrompt)
2431
+ new SystemMessage7(systemPrompt),
2432
+ new HumanMessage7(userPrompt)
2433
2433
  ];
2434
2434
  return invokeRoutingDecision(config.model, messages);
2435
2435
  }
@@ -2747,7 +2747,7 @@ function wrapReActAgent(workerId, agent, verbose = false) {
2747
2747
  }
2748
2748
 
2749
2749
  // src/multi-agent/nodes/shared.ts
2750
- import { HumanMessage as HumanMessage6, SystemMessage as SystemMessage6 } from "@langchain/core/messages";
2750
+ import { HumanMessage as HumanMessage8, SystemMessage as SystemMessage8 } from "@langchain/core/messages";
2751
2751
  import { toLangChainTools as toLangChainTools2 } from "@agentforge/core";
2752
2752
  var logger3 = createPatternLogger("agentforge:patterns:multi-agent:nodes");
2753
2753
  function createGeneratedId(prefix) {
@@ -2791,7 +2791,7 @@ function convertWorkerToolsForLangChain(tools) {
2791
2791
  const safeTools = tools ?? [];
2792
2792
  return toLangChainTools2(safeTools);
2793
2793
  }
2794
- function serializeModelContent(content) {
2794
+ function serializeModelContent2(content) {
2795
2795
  if (typeof content === "string") {
2796
2796
  return content;
2797
2797
  }
@@ -2818,7 +2818,7 @@ function serializeModelContent(content) {
2818
2818
  }
2819
2819
  }
2820
2820
  function createPromptMessages(systemPrompt, task) {
2821
- return [new SystemMessage6(systemPrompt), new HumanMessage6(task)];
2821
+ return [new SystemMessage8(systemPrompt), new HumanMessage8(task)];
2822
2822
  }
2823
2823
 
2824
2824
  // src/multi-agent/nodes/aggregator.ts
@@ -2894,7 +2894,7 @@ function createAggregatorNode(config = {}) {
2894
2894
  const messages = createPromptMessages(systemPrompt, createAggregationPrompt(state));
2895
2895
  logger3.debug("Invoking aggregation LLM");
2896
2896
  const response = await model.invoke(messages);
2897
- const aggregatedResponse = serializeModelContent(response.content);
2897
+ const aggregatedResponse = serializeModelContent2(response.content);
2898
2898
  logger3.info("Aggregation complete", {
2899
2899
  responseLength: aggregatedResponse.length
2900
2900
  });
@@ -3088,7 +3088,7 @@ async function invokeWorkerModel(model, config, assignment) {
3088
3088
  }
3089
3089
  logger3.debug("Invoking LLM", { workerId: config.id });
3090
3090
  const response = await modelToUse.invoke(messages);
3091
- const result = serializeModelContent(response.content);
3091
+ const result = serializeModelContent2(response.content);
3092
3092
  logger3.info("Worker task completed", {
3093
3093
  workerId: config.id,
3094
3094
  assignmentId: assignment.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/patterns",
3
- "version": "0.16.40",
3
+ "version": "0.16.42",
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.40",
44
+ "@agentforge/core": "0.16.42",
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.40",
50
+ "@agentforge/testing": "0.16.42",
51
51
  "@eslint/js": "^9.17.0",
52
52
  "@types/node": "^22.10.2",
53
53
  "eslint": "^9.17.0",