@agentforge/patterns 0.16.40 → 0.16.41
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 +102 -102
- package/dist/index.d.cts +3 -20
- package/dist/index.d.ts +3 -20
- package/dist/index.js +102 -102
- package/package.json +3 -3
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/
|
|
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
|
-
|
|
1806
|
-
|
|
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
|
|
1827
|
+
const response = await model.invoke([
|
|
1814
1828
|
new import_messages4.SystemMessage(systemPrompt),
|
|
1815
1829
|
new import_messages4.HumanMessage(userPrompt)
|
|
1816
|
-
];
|
|
1817
|
-
const
|
|
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
|
-
|
|
1863
|
-
const
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1967
|
-
new
|
|
1968
|
-
new
|
|
1969
|
-
];
|
|
1970
|
-
const
|
|
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: [
|
|
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
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
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
|
|
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
|
|
2530
|
-
new
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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/
|
|
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
|
-
|
|
1708
|
-
|
|
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
|
|
1729
|
+
const response = await model.invoke([
|
|
1716
1730
|
new SystemMessage4(systemPrompt),
|
|
1717
1731
|
new HumanMessage4(userPrompt)
|
|
1718
|
-
];
|
|
1719
|
-
const
|
|
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
|
-
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1869
|
-
new
|
|
1870
|
-
new
|
|
1871
|
-
];
|
|
1872
|
-
const
|
|
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: [
|
|
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
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
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
|
|
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
|
|
2432
|
-
new
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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.
|
|
3
|
+
"version": "0.16.41",
|
|
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.
|
|
44
|
+
"@agentforge/core": "0.16.41",
|
|
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.
|
|
50
|
+
"@agentforge/testing": "0.16.41",
|
|
51
51
|
"@eslint/js": "^9.17.0",
|
|
52
52
|
"@types/node": "^22.10.2",
|
|
53
53
|
"eslint": "^9.17.0",
|