@axiom-lattice/core 1.0.1
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/.eslintrc.json +22 -0
- package/.turbo/turbo-build.log +21 -0
- package/README.md +47 -0
- package/dist/index.d.mts +356 -0
- package/dist/index.d.ts +356 -0
- package/dist/index.js +2191 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2159 -0
- package/dist/index.mjs.map +1 -0
- package/jest.config.js +21 -0
- package/package.json +63 -0
- package/src/__tests__/AgentManager.test.ts +202 -0
- package/src/__tests__/setup.ts +5 -0
- package/src/agent_lattice/AgentLatticeManager.ts +216 -0
- package/src/agent_lattice/builders/AgentBuilder.ts +79 -0
- package/src/agent_lattice/builders/AgentGraphBuilder.ts +22 -0
- package/src/agent_lattice/builders/AgentGraphBuilderFactory.ts +70 -0
- package/src/agent_lattice/builders/AgentParamsBuilder.ts +86 -0
- package/src/agent_lattice/builders/DeepAgentGraphBuilder.ts +46 -0
- package/src/agent_lattice/builders/PlanExecuteAgentGraphBuilder.ts +46 -0
- package/src/agent_lattice/builders/ReActAgentGraphBuilder.ts +42 -0
- package/src/agent_lattice/builders/index.ts +14 -0
- package/src/agent_lattice/index.ts +27 -0
- package/src/agent_lattice/types.ts +42 -0
- package/src/base/BaseLatticeManager.ts +145 -0
- package/src/base/index.ts +1 -0
- package/src/createPlanExecuteAgent.ts +475 -0
- package/src/deep_agent/graph.ts +106 -0
- package/src/deep_agent/index.ts +25 -0
- package/src/deep_agent/prompts.ts +284 -0
- package/src/deep_agent/state.ts +63 -0
- package/src/deep_agent/subAgent.ts +185 -0
- package/src/deep_agent/tools.ts +273 -0
- package/src/deep_agent/types.ts +71 -0
- package/src/index.ts +9 -0
- package/src/logger/Logger.ts +186 -0
- package/src/memory_lattice/DefaultMemorySaver.ts +4 -0
- package/src/memory_lattice/MemoryLatticeManager.ts +105 -0
- package/src/memory_lattice/index.ts +9 -0
- package/src/model_lattice/ModelLattice.ts +208 -0
- package/src/model_lattice/ModelLatticeManager.ts +125 -0
- package/src/model_lattice/index.ts +1 -0
- package/src/tool_lattice/ToolLatticeManager.ts +221 -0
- package/src/tool_lattice/get_current_date_time/index.ts +14 -0
- package/src/tool_lattice/index.ts +2 -0
- package/src/tool_lattice/internet_search/index.ts +66 -0
- package/src/types.ts +28 -0
- package/src/util/PGMemory.ts +16 -0
- package/src/util/genUICard.ts +3 -0
- package/src/util/genUIMarkdown.ts +3 -0
- package/src/util/getLastHumanMessageData.ts +41 -0
- package/src/util/returnAIResponse.ts +30 -0
- package/src/util/returnErrorResponse.ts +26 -0
- package/src/util/returnFeedbackResponse.ts +25 -0
- package/src/util/returnToolResponse.ts +32 -0
- package/src/util/withAgentName.ts +220 -0
- package/src/util/zod-to-prompt.ts +50 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseLatticeManager - 抽象基类,为各种Lattice管理器提供通用功能
|
|
3
|
+
* 使用统一的Lattice注册表,不同类型的Lattice通过前缀区分
|
|
4
|
+
* @template TItem - 管理的项目类型
|
|
5
|
+
*/
|
|
6
|
+
export abstract class BaseLatticeManager<TItem = any> {
|
|
7
|
+
// 全局统一的Lattice注册表
|
|
8
|
+
protected static registry: Map<string, any> = new Map();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 受保护的构造函数,防止外部直接实例化
|
|
12
|
+
*/
|
|
13
|
+
protected constructor() {
|
|
14
|
+
// 空实现
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 获取管理器实例(由子类实现)
|
|
19
|
+
*/
|
|
20
|
+
public static getInstance(): BaseLatticeManager<any> {
|
|
21
|
+
throw new Error("必须由子类实现");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 获取Lattice类型,用于构造键前缀
|
|
26
|
+
* 子类必须重写此方法以提供唯一的类型标识符
|
|
27
|
+
*/
|
|
28
|
+
protected abstract getLatticeType(): string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 构造完整的键名,包含类型前缀
|
|
32
|
+
* @param key 原始键名
|
|
33
|
+
*/
|
|
34
|
+
protected getFullKey(key: string): string {
|
|
35
|
+
return `${this.getLatticeType()}.${key}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 注册项目
|
|
40
|
+
* @param key 项目键名(不含前缀)
|
|
41
|
+
* @param item 项目实例
|
|
42
|
+
*/
|
|
43
|
+
public register(key: string, item: TItem): void {
|
|
44
|
+
const fullKey = this.getFullKey(key);
|
|
45
|
+
if (BaseLatticeManager.registry.has(fullKey)) {
|
|
46
|
+
throw new Error(`项目 "${fullKey}" 已经存在,无法重复注册`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
BaseLatticeManager.registry.set(fullKey, item);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 获取指定项目
|
|
54
|
+
* @param key 项目键名(不含前缀)
|
|
55
|
+
*/
|
|
56
|
+
public get(key: string): TItem | undefined {
|
|
57
|
+
const fullKey = this.getFullKey(key);
|
|
58
|
+
return BaseLatticeManager.registry.get(fullKey) as TItem | undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 获取所有当前类型的项目
|
|
63
|
+
*/
|
|
64
|
+
public getAll(): TItem[] {
|
|
65
|
+
const prefix = `${this.getLatticeType()}.`;
|
|
66
|
+
const result: TItem[] = [];
|
|
67
|
+
|
|
68
|
+
for (const [key, value] of BaseLatticeManager.registry.entries()) {
|
|
69
|
+
if (key.startsWith(prefix)) {
|
|
70
|
+
result.push(value as TItem);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 检查项目是否存在
|
|
79
|
+
* @param key 项目键名(不含前缀)
|
|
80
|
+
*/
|
|
81
|
+
public has(key: string): boolean {
|
|
82
|
+
const fullKey = this.getFullKey(key);
|
|
83
|
+
return BaseLatticeManager.registry.has(fullKey);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 移除项目
|
|
88
|
+
* @param key 项目键名(不含前缀)
|
|
89
|
+
*/
|
|
90
|
+
public remove(key: string): boolean {
|
|
91
|
+
const fullKey = this.getFullKey(key);
|
|
92
|
+
return BaseLatticeManager.registry.delete(fullKey);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 清空当前类型的所有项目
|
|
97
|
+
*/
|
|
98
|
+
public clear(): void {
|
|
99
|
+
const prefix = `${this.getLatticeType()}.`;
|
|
100
|
+
const keysToDelete: string[] = [];
|
|
101
|
+
|
|
102
|
+
for (const key of BaseLatticeManager.registry.keys()) {
|
|
103
|
+
if (key.startsWith(prefix)) {
|
|
104
|
+
keysToDelete.push(key);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (const key of keysToDelete) {
|
|
109
|
+
BaseLatticeManager.registry.delete(key);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 获取当前类型的项目数量
|
|
115
|
+
*/
|
|
116
|
+
public count(): number {
|
|
117
|
+
const prefix = `${this.getLatticeType()}.`;
|
|
118
|
+
let count = 0;
|
|
119
|
+
|
|
120
|
+
for (const key of BaseLatticeManager.registry.keys()) {
|
|
121
|
+
if (key.startsWith(prefix)) {
|
|
122
|
+
count++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return count;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 获取当前类型的项目键名列表(不含前缀)
|
|
131
|
+
*/
|
|
132
|
+
public keys(): string[] {
|
|
133
|
+
const prefix = `${this.getLatticeType()}.`;
|
|
134
|
+
const prefixLength = prefix.length;
|
|
135
|
+
const result: string[] = [];
|
|
136
|
+
|
|
137
|
+
for (const key of BaseLatticeManager.registry.keys()) {
|
|
138
|
+
if (key.startsWith(prefix)) {
|
|
139
|
+
result.push(key.substring(prefixLength));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./BaseLatticeManager";
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Annotation,
|
|
3
|
+
BaseCheckpointSaver,
|
|
4
|
+
END,
|
|
5
|
+
GraphInterrupt,
|
|
6
|
+
LangGraphRunnableConfig,
|
|
7
|
+
START,
|
|
8
|
+
StateGraph,
|
|
9
|
+
messagesStateReducer,
|
|
10
|
+
} from "@langchain/langgraph";
|
|
11
|
+
import {
|
|
12
|
+
BaseMessage,
|
|
13
|
+
HumanMessage,
|
|
14
|
+
mergeMessageRuns,
|
|
15
|
+
} from "@langchain/core/messages";
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { ModelLattice } from "./model_lattice/ModelLattice";
|
|
18
|
+
import { Logger } from "@logger/Logger";
|
|
19
|
+
import { StateBaseType } from "./types";
|
|
20
|
+
import { returnToolResponse } from "./util/returnToolResponse";
|
|
21
|
+
import { returnAIResponse } from "./util/returnAIResponse";
|
|
22
|
+
import { getLastHumanMessageData } from "./util/getLastHumanMessageData";
|
|
23
|
+
import { tool } from "@langchain/core/tools";
|
|
24
|
+
import { MemoryManager } from "./util/PGMemory";
|
|
25
|
+
import { getModelLattice } from "./model_lattice/ModelLatticeManager";
|
|
26
|
+
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Plan-and-Execute Agent 状态定义
|
|
30
|
+
*/
|
|
31
|
+
export const PlanExecuteState = Annotation.Root({
|
|
32
|
+
// 输入
|
|
33
|
+
input: Annotation<string>({
|
|
34
|
+
reducer: (x, y) => y ?? x ?? "",
|
|
35
|
+
}),
|
|
36
|
+
// 计划步骤列表
|
|
37
|
+
plan: Annotation<string[]>({
|
|
38
|
+
reducer: (x, y) => y ?? x ?? [],
|
|
39
|
+
}),
|
|
40
|
+
// 已执行的步骤 [步骤名称, 执行结果]
|
|
41
|
+
pastSteps: Annotation<[string, string][]>({
|
|
42
|
+
reducer: (x, y) => x.concat(y),
|
|
43
|
+
default: () => [],
|
|
44
|
+
}),
|
|
45
|
+
// 最终响应
|
|
46
|
+
response: Annotation<string | undefined>({
|
|
47
|
+
reducer: (x, y) => y ?? x,
|
|
48
|
+
}),
|
|
49
|
+
// 错误信息
|
|
50
|
+
error: Annotation<string | undefined>({
|
|
51
|
+
reducer: (x, y) => y ?? x,
|
|
52
|
+
}),
|
|
53
|
+
// 继承基础状态
|
|
54
|
+
"x-tenant-id": Annotation<number>(),
|
|
55
|
+
messages: Annotation<BaseMessage[]>({
|
|
56
|
+
reducer: messagesStateReducer,
|
|
57
|
+
default: () => [],
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 计划工具的结构化输出模式
|
|
63
|
+
*/
|
|
64
|
+
const planSchema = z.object({
|
|
65
|
+
steps: z.array(z.string()).describe("需要执行的步骤列表,应按照执行顺序排序"),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 响应工具的结构化输出模式
|
|
70
|
+
*/
|
|
71
|
+
const responseSchema = z.object({
|
|
72
|
+
response: z
|
|
73
|
+
.string()
|
|
74
|
+
.describe("给用户的最终响应,如果不需要执行步骤,则返回这个字段"),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Plan-and-Execute Agent 配置接口
|
|
79
|
+
*/
|
|
80
|
+
export interface PlanExecuteAgentConfig {
|
|
81
|
+
name: string;
|
|
82
|
+
description: string;
|
|
83
|
+
tools?: any[]; // 执行器可使用的工具
|
|
84
|
+
checkpointer?: false | BaseCheckpointSaver<number>;
|
|
85
|
+
llmManager?: ModelLattice;
|
|
86
|
+
logger?: Logger;
|
|
87
|
+
maxSteps?: number; // 最大步骤数限制
|
|
88
|
+
prompt?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 创建 Plan-and-Execute Agent
|
|
93
|
+
*
|
|
94
|
+
* 这是一个规划-执行风格的代理,首先制定多步骤计划,然后逐一执行。
|
|
95
|
+
* 在完成每个任务后,会重新评估计划并根据需要进行修改。
|
|
96
|
+
*
|
|
97
|
+
* 相比传统的ReAct风格代理的优势:
|
|
98
|
+
* 1. 明确的长期规划能力
|
|
99
|
+
* 2. 可以在执行步骤使用较小的模型,只在规划步骤使用大模型
|
|
100
|
+
* 3. 更好的任务分解和执行追踪
|
|
101
|
+
*/
|
|
102
|
+
export function createPlanExecuteAgent(config: PlanExecuteAgentConfig) {
|
|
103
|
+
const {
|
|
104
|
+
name,
|
|
105
|
+
description,
|
|
106
|
+
tools: executorTools = [],
|
|
107
|
+
checkpointer,
|
|
108
|
+
llmManager,
|
|
109
|
+
logger,
|
|
110
|
+
maxSteps = 10,
|
|
111
|
+
prompt,
|
|
112
|
+
} = config;
|
|
113
|
+
|
|
114
|
+
const agentLogger =
|
|
115
|
+
logger || new Logger({ name: `PlanExecuteAgent:${name}` });
|
|
116
|
+
const llm = llmManager || getModelLattice("default")?.client;
|
|
117
|
+
|
|
118
|
+
if (!llm) {
|
|
119
|
+
throw new Error("LLM not found");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
agentLogger.info(`初始化Plan-Execute代理: ${name}`, {
|
|
123
|
+
description,
|
|
124
|
+
maxSteps,
|
|
125
|
+
toolsCount: executorTools.length,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const agentExecutor = createReactAgent({
|
|
129
|
+
tools: executorTools,
|
|
130
|
+
llm: llm,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 规划步骤:创建初始计划
|
|
135
|
+
*/
|
|
136
|
+
async function planStep(
|
|
137
|
+
state: typeof PlanExecuteState.State,
|
|
138
|
+
config: LangGraphRunnableConfig
|
|
139
|
+
): Promise<Partial<typeof PlanExecuteState.State>> {
|
|
140
|
+
const input =
|
|
141
|
+
state.input || getLastHumanMessageData(state.messages)?.content;
|
|
142
|
+
|
|
143
|
+
const plannerPrompt = `${
|
|
144
|
+
prompt || ""
|
|
145
|
+
}\n针对给定的目标,制定一个简单的分步计划。
|
|
146
|
+
这个计划应该包含独立的任务,如果正确执行将会得到正确的答案。不要添加多余的步骤。
|
|
147
|
+
最后一步的结果应该是最终答案。确保每一步都有所需的所有信息 - 不要跳过步骤。
|
|
148
|
+
|
|
149
|
+
可以使用的工具如下:
|
|
150
|
+
${executorTools.map((tool) => tool.name).join("\n")}
|
|
151
|
+
|
|
152
|
+
目标: ${input}`;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const planResult = (await llm.invokeWithStructuredOutput(
|
|
156
|
+
[new HumanMessage(plannerPrompt)],
|
|
157
|
+
planSchema
|
|
158
|
+
)) as { steps: string[] };
|
|
159
|
+
|
|
160
|
+
const { messages } = await returnToolResponse(config, {
|
|
161
|
+
title: "我的计划",
|
|
162
|
+
content: planResult.steps.map((step: string) => step).join("\n\n"),
|
|
163
|
+
status: "success",
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
agentLogger.info("计划制定完成", { plan: planResult.steps });
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
input: input as string,
|
|
170
|
+
plan: planResult.steps,
|
|
171
|
+
error: undefined,
|
|
172
|
+
messages,
|
|
173
|
+
};
|
|
174
|
+
} catch (error) {
|
|
175
|
+
const errorMsg = `计划制定失败: ${
|
|
176
|
+
error instanceof Error ? error.message : "未知错误"
|
|
177
|
+
}`;
|
|
178
|
+
agentLogger.error(errorMsg, { error });
|
|
179
|
+
return {
|
|
180
|
+
error: errorMsg,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 执行步骤:执行计划中的第一个任务
|
|
187
|
+
*/
|
|
188
|
+
async function executeStep(
|
|
189
|
+
state: typeof PlanExecuteState.State,
|
|
190
|
+
config: LangGraphRunnableConfig
|
|
191
|
+
): Promise<Partial<typeof PlanExecuteState.State>> {
|
|
192
|
+
if (!state.plan || state.plan.length === 0) {
|
|
193
|
+
agentLogger.warn("没有可执行的任务");
|
|
194
|
+
return { error: "没有可执行的任务" };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const currentTask = state.plan[0];
|
|
198
|
+
agentLogger.info("开始执行任务", { task: currentTask });
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
// 这里可以集成真实的工具执行器
|
|
202
|
+
// 目前使用LLM来模拟执行
|
|
203
|
+
const executorPrompt = `执行以下任务并提供结果:
|
|
204
|
+
|
|
205
|
+
任务: ${currentTask}
|
|
206
|
+
|
|
207
|
+
上下文信息:
|
|
208
|
+
- 原始目标: ${state.input}
|
|
209
|
+
- 已完成的步骤: ${state.pastSteps
|
|
210
|
+
.map(([step, result]) => `${step}: ${result}`)
|
|
211
|
+
.join("\n")}
|
|
212
|
+
|
|
213
|
+
请提供执行此任务的详细结果。`;
|
|
214
|
+
|
|
215
|
+
const executionResult = await agentExecutor.invoke({
|
|
216
|
+
messages: [new HumanMessage(executorPrompt)],
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const resultContent =
|
|
220
|
+
executionResult.messages[executionResult.messages.length - 1].content;
|
|
221
|
+
|
|
222
|
+
// 生成工具响应消息
|
|
223
|
+
// const { messages } = await returnToolResponse(config, {
|
|
224
|
+
// title: `执行任务: ${currentTask}`,
|
|
225
|
+
// content: resultContent as string,
|
|
226
|
+
// status: "success",
|
|
227
|
+
// });
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
pastSteps: [[currentTask, resultContent]] as [string, string][],
|
|
231
|
+
plan: state.plan.slice(1), // 移除已执行的任务
|
|
232
|
+
//messages,
|
|
233
|
+
error: undefined,
|
|
234
|
+
};
|
|
235
|
+
} catch (error) {
|
|
236
|
+
if (error instanceof GraphInterrupt) {
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
const errorMsg = `任务执行失败: ${
|
|
240
|
+
error instanceof Error ? error.message : "未知错误"
|
|
241
|
+
}`;
|
|
242
|
+
agentLogger.error(errorMsg, { task: currentTask, error });
|
|
243
|
+
|
|
244
|
+
// const { messages } = await returnToolResponse(config, {
|
|
245
|
+
// title: `执行任务失败: ${currentTask}`,
|
|
246
|
+
// content: errorMsg,
|
|
247
|
+
// status: "error",
|
|
248
|
+
// });
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
error: errorMsg,
|
|
252
|
+
//messages,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const responseTool = tool(
|
|
258
|
+
({ response }: { response: string }) => {
|
|
259
|
+
return response;
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "response",
|
|
263
|
+
description: "Respond to the user.",
|
|
264
|
+
schema: responseSchema,
|
|
265
|
+
returnDirect: true,
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const planTool = tool(
|
|
270
|
+
({ steps }: { steps: string[] }) => {
|
|
271
|
+
return steps.join("\n\n");
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: "plan",
|
|
275
|
+
description: "This tool is used to plan the steps to follow.",
|
|
276
|
+
schema: planSchema,
|
|
277
|
+
returnDirect: true,
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
const replanAgent = createReactAgent({
|
|
282
|
+
tools: [responseTool, planTool],
|
|
283
|
+
llm: llm,
|
|
284
|
+
});
|
|
285
|
+
/**
|
|
286
|
+
* 重新规划步骤:根据执行结果调整计划
|
|
287
|
+
*/
|
|
288
|
+
async function replanStep(
|
|
289
|
+
state: typeof PlanExecuteState.State,
|
|
290
|
+
config: LangGraphRunnableConfig
|
|
291
|
+
): Promise<Partial<typeof PlanExecuteState.State>> {
|
|
292
|
+
agentLogger.info("开始重新规划");
|
|
293
|
+
|
|
294
|
+
const replannerPrompt = `${
|
|
295
|
+
prompt || ""
|
|
296
|
+
}\n针对给定的目标,根据已执行的步骤来更新计划。
|
|
297
|
+
这个计划应该包含独立的任务,如果正确执行将会得到正确的答案。不要添加多余的步骤。
|
|
298
|
+
最后一步的结果应该是最终答案。确保每一步都有所需的所有信息 - 不要跳过步骤。
|
|
299
|
+
|
|
300
|
+
你的目标是:
|
|
301
|
+
${state.input}
|
|
302
|
+
|
|
303
|
+
你的原始计划是:
|
|
304
|
+
${state.plan.join("\n")}
|
|
305
|
+
|
|
306
|
+
你目前已经完成了以下步骤:
|
|
307
|
+
${state.pastSteps.map(([step, result]) => `${step}: ${result}`).join("\n")}
|
|
308
|
+
|
|
309
|
+
Update your plan accordingly. If no more steps are needed and you can return to the user, then respond with that and use the 'response' function.
|
|
310
|
+
Otherwise, fill out the plan.
|
|
311
|
+
Only add steps to the plan that still NEED to be done. Do not return previously done steps as part of the plan.`;
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
// 首先尝试获取最终响应
|
|
315
|
+
const responseResult = await replanAgent.invoke({
|
|
316
|
+
messages: [new HumanMessage(replannerPrompt)],
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const toolCall =
|
|
320
|
+
responseResult.messages[responseResult.messages.length - 1];
|
|
321
|
+
|
|
322
|
+
if (toolCall?.name == "response") {
|
|
323
|
+
agentLogger.info("任务完成,提供最终响应");
|
|
324
|
+
|
|
325
|
+
const { messages } = await returnAIResponse(
|
|
326
|
+
config,
|
|
327
|
+
toolCall.content as string
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
response: toolCall.content as string,
|
|
332
|
+
messages,
|
|
333
|
+
error: undefined,
|
|
334
|
+
};
|
|
335
|
+
} else if (toolCall?.name == "plan") {
|
|
336
|
+
let messages: any[] = [];
|
|
337
|
+
if (toolCall.content?.length > 0) {
|
|
338
|
+
messages = await returnToolResponse(config, {
|
|
339
|
+
title: "新的计划",
|
|
340
|
+
content: toolCall.content as string,
|
|
341
|
+
status: "success",
|
|
342
|
+
}).messages;
|
|
343
|
+
}
|
|
344
|
+
agentLogger.info("计划更新完成", { newPlan: toolCall.content });
|
|
345
|
+
return {
|
|
346
|
+
messages,
|
|
347
|
+
plan: (toolCall.content as string).split("\n\n"),
|
|
348
|
+
error: undefined,
|
|
349
|
+
};
|
|
350
|
+
} else {
|
|
351
|
+
return {
|
|
352
|
+
error: "重新规划失败",
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
} catch (error) {
|
|
356
|
+
if (error instanceof GraphInterrupt) {
|
|
357
|
+
throw error;
|
|
358
|
+
}
|
|
359
|
+
const errorMsg = `重新规划失败: ${
|
|
360
|
+
error instanceof Error ? error.message : "未知错误"
|
|
361
|
+
}`;
|
|
362
|
+
agentLogger.error(errorMsg, { error });
|
|
363
|
+
return {
|
|
364
|
+
error: errorMsg,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* 判断是否应该结束执行
|
|
371
|
+
*/
|
|
372
|
+
function shouldEnd(state: typeof PlanExecuteState.State): "end" | "continue" {
|
|
373
|
+
if (state.error) {
|
|
374
|
+
agentLogger.warn("因错误结束执行", { error: state.error });
|
|
375
|
+
return "end";
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (state.response) {
|
|
379
|
+
agentLogger.info("任务完成,结束执行");
|
|
380
|
+
return "end";
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (state.pastSteps.length >= maxSteps) {
|
|
384
|
+
agentLogger.warn("达到最大步骤数限制,结束执行", {
|
|
385
|
+
maxSteps,
|
|
386
|
+
currentSteps: state.pastSteps.length,
|
|
387
|
+
});
|
|
388
|
+
return "end";
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (!state.plan || state.plan.length === 0) {
|
|
392
|
+
agentLogger.info("计划为空,结束执行");
|
|
393
|
+
return "end";
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return "continue";
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// 构建状态图
|
|
400
|
+
const workflow = new StateGraph(PlanExecuteState)
|
|
401
|
+
.addNode("planner", planStep)
|
|
402
|
+
.addNode("executor", executeStep)
|
|
403
|
+
.addNode("replanner", replanStep)
|
|
404
|
+
.addEdge(START, "planner")
|
|
405
|
+
.addEdge("planner", "executor")
|
|
406
|
+
.addEdge("executor", "replanner")
|
|
407
|
+
.addConditionalEdges("replanner", shouldEnd, {
|
|
408
|
+
end: END,
|
|
409
|
+
continue: "executor",
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// 编译图
|
|
413
|
+
//const memory = MemoryManager.getInstance();
|
|
414
|
+
const compiledGraph = workflow.compile({
|
|
415
|
+
checkpointer: checkpointer || MemoryManager.getInstance(),
|
|
416
|
+
name: `PlanExecuteAgent:${name}`,
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
agentLogger.info(`Plan-Execute代理编译完成: ${name}`);
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
/**
|
|
423
|
+
* 执行代理
|
|
424
|
+
*/
|
|
425
|
+
invoke: async (
|
|
426
|
+
input: { input: string; "x-tenant-id": number },
|
|
427
|
+
config?: LangGraphRunnableConfig
|
|
428
|
+
) => {
|
|
429
|
+
agentLogger.info(`开始执行Plan-Execute代理: ${name}`, {
|
|
430
|
+
input: input.input,
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
try {
|
|
434
|
+
const result = await compiledGraph.invoke(input, config);
|
|
435
|
+
agentLogger.info(`代理执行完成: ${name}`);
|
|
436
|
+
return result;
|
|
437
|
+
} catch (error) {
|
|
438
|
+
agentLogger.error(
|
|
439
|
+
`代理执行失败: ${name}`,
|
|
440
|
+
error instanceof Error ? error : { error }
|
|
441
|
+
);
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* 流式执行代理
|
|
448
|
+
*/
|
|
449
|
+
stream: async (
|
|
450
|
+
input: { input: string; "x-tenant-id": number },
|
|
451
|
+
config?: LangGraphRunnableConfig
|
|
452
|
+
) => {
|
|
453
|
+
agentLogger.info(`开始流式执行Plan-Execute代理: ${name}`, {
|
|
454
|
+
input: input.input,
|
|
455
|
+
});
|
|
456
|
+
return compiledGraph.stream(input, config);
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* 获取代理信息
|
|
461
|
+
*/
|
|
462
|
+
getInfo: () => ({
|
|
463
|
+
name,
|
|
464
|
+
description,
|
|
465
|
+
type: "PlanExecuteAgent",
|
|
466
|
+
toolsCount: executorTools.length,
|
|
467
|
+
maxSteps,
|
|
468
|
+
}),
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* 获取编译后的图
|
|
472
|
+
*/
|
|
473
|
+
getCompiledGraph: () => compiledGraph,
|
|
474
|
+
};
|
|
475
|
+
}
|