@louloulinx/metagpt 0.1.3
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 +23 -0
- package/.prettierrc +7 -0
- package/LICENSE +21 -0
- package/README-CN.md +754 -0
- package/README.md +238 -0
- package/bun.lock +1023 -0
- package/doc/TutorialAssistant.md +114 -0
- package/doc/VercelLLMProvider.md +164 -0
- package/eslint.config.js +55 -0
- package/examples/data-interpreter-example.ts +173 -0
- package/examples/qwen-direct-example.ts +60 -0
- package/examples/qwen-example.ts +62 -0
- package/examples/tutorial-assistant-example.ts +97 -0
- package/jest.config.ts +22 -0
- package/output/tutorials/Go/350/257/255/350/250/200/347/274/226/347/250/213/346/225/231/347/250/213_2025-02-25T09-35-15-436Z.md +2208 -0
- package/output/tutorials/Rust/346/225/231/347/250/213_2025-02-25T08-27-27-632Z.md +1967 -0
- package/output/tutorials//345/246/202/344/275/225/344/275/277/347/224/250TypeScript/345/274/200/345/217/221Node.js/345/272/224/347/224/250_2025-02-25T08-14-39-605Z.md +1721 -0
- package/output/tutorials//346/225/260/345/255/227/347/273/217/346/265/216/345/255/246/346/225/231/347/250/213_2025-02-25T10-45-03-605Z.md +902 -0
- package/output/tutorials//346/232/250/345/215/227/345/244/247/345/255/246/346/225/260/345/255/227/347/273/217/346/265/216/345/255/246/345/244/215/350/257/225/350/265/204/346/226/231_2025-02-25T11-16-59-133Z.md +719 -0
- package/package.json +58 -0
- package/plan-cn.md +321 -0
- package/plan.md +154 -0
- package/src/actions/analyze-task.ts +65 -0
- package/src/actions/base-action.ts +103 -0
- package/src/actions/di/execute-nb-code.ts +247 -0
- package/src/actions/di/write-analysis-code.ts +234 -0
- package/src/actions/write-tutorial.ts +232 -0
- package/src/config/browser.ts +33 -0
- package/src/config/config.ts +345 -0
- package/src/config/embedding.ts +26 -0
- package/src/config/llm.ts +36 -0
- package/src/config/mermaid.ts +37 -0
- package/src/config/omniparse.ts +25 -0
- package/src/config/redis.ts +34 -0
- package/src/config/s3.ts +33 -0
- package/src/config/search.ts +30 -0
- package/src/config/workspace.ts +20 -0
- package/src/index.ts +40 -0
- package/src/management/team.ts +168 -0
- package/src/memory/longterm.ts +218 -0
- package/src/memory/manager.ts +160 -0
- package/src/memory/types.ts +100 -0
- package/src/memory/working.ts +154 -0
- package/src/monitoring/system.ts +413 -0
- package/src/monitoring/types.ts +230 -0
- package/src/plugin/manager.ts +79 -0
- package/src/plugin/types.ts +114 -0
- package/src/provider/vercel-llm.ts +314 -0
- package/src/rag/base-rag.ts +194 -0
- package/src/rag/document-qa.ts +102 -0
- package/src/roles/base-role.ts +155 -0
- package/src/roles/data-interpreter.ts +360 -0
- package/src/roles/engineer.ts +1 -0
- package/src/roles/tutorial-assistant.ts +217 -0
- package/src/skills/base-skill.ts +144 -0
- package/src/skills/code-review.ts +120 -0
- package/src/tools/base-tool.ts +155 -0
- package/src/tools/file-system.ts +204 -0
- package/src/tools/tool-recommend.d.ts +14 -0
- package/src/tools/tool-recommend.ts +31 -0
- package/src/types/action.ts +38 -0
- package/src/types/config.ts +129 -0
- package/src/types/document.ts +354 -0
- package/src/types/llm.ts +64 -0
- package/src/types/memory.ts +36 -0
- package/src/types/message.ts +193 -0
- package/src/types/rag.ts +86 -0
- package/src/types/role.ts +67 -0
- package/src/types/skill.ts +71 -0
- package/src/types/task.ts +32 -0
- package/src/types/team.ts +55 -0
- package/src/types/tool.ts +77 -0
- package/src/types/workflow.ts +133 -0
- package/src/utils/common.ts +73 -0
- package/src/utils/yaml.ts +67 -0
- package/src/websocket/browser-client.ts +187 -0
- package/src/websocket/client.ts +186 -0
- package/src/websocket/server.ts +169 -0
- package/src/websocket/types.ts +125 -0
- package/src/workflow/executor.ts +193 -0
- package/src/workflow/executors/action-executor.ts +72 -0
- package/src/workflow/executors/condition-executor.ts +118 -0
- package/src/workflow/executors/parallel-executor.ts +201 -0
- package/src/workflow/executors/role-executor.ts +76 -0
- package/src/workflow/executors/sequence-executor.ts +196 -0
- package/tests/actions.test.ts +105 -0
- package/tests/benchmark/performance.test.ts +147 -0
- package/tests/config/config.test.ts +115 -0
- package/tests/config.test.ts +106 -0
- package/tests/e2e/setup.ts +74 -0
- package/tests/e2e/workflow.test.ts +88 -0
- package/tests/llm.test.ts +84 -0
- package/tests/memory/memory.test.ts +164 -0
- package/tests/memory.test.ts +63 -0
- package/tests/monitoring/monitoring.test.ts +225 -0
- package/tests/plugin/plugin.test.ts +183 -0
- package/tests/provider/bailian-llm.test.ts +98 -0
- package/tests/rag.test.ts +162 -0
- package/tests/roles.test.ts +88 -0
- package/tests/skills.test.ts +166 -0
- package/tests/team.test.ts +143 -0
- package/tests/tools.test.ts +170 -0
- package/tests/types/document.test.ts +181 -0
- package/tests/types/message.test.ts +122 -0
- package/tests/utils/yaml.test.ts +110 -0
- package/tests/utils.test.ts +74 -0
- package/tests/websocket/browser-client.test.ts +1 -0
- package/tests/websocket/websocket.test.ts +42 -0
- package/tests/workflow/parallel-executor.test.ts +224 -0
- package/tests/workflow/sequence-executor.test.ts +207 -0
- package/tests/workflow.test.ts +290 -0
- package/tsconfig.json +27 -0
- package/typedoc.json +25 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
import { interpret, createActor } from 'xstate';
|
2
|
+
import { Subject } from 'rxjs';
|
3
|
+
import type { Role, RoleContext } from '../types/role';
|
4
|
+
import type { Message } from '../types/message';
|
5
|
+
import type { Action } from '../types/action';
|
6
|
+
import { roleStateMachine } from '../types/role';
|
7
|
+
import { ArrayMemory } from '../types/memory';
|
8
|
+
import { generateId } from '../utils/common';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* 角色基类
|
12
|
+
* 实现了基本的角色行为和状态管理
|
13
|
+
*/
|
14
|
+
export abstract class BaseRole implements Role {
|
15
|
+
name: string;
|
16
|
+
profile: string;
|
17
|
+
goal: string;
|
18
|
+
constraints: string;
|
19
|
+
actions: Action[] = [];
|
20
|
+
state = -1;
|
21
|
+
context: RoleContext;
|
22
|
+
|
23
|
+
// 消息流
|
24
|
+
private messageSubject = new Subject<Message>();
|
25
|
+
|
26
|
+
// 状态机
|
27
|
+
private stateMachine = createActor(roleStateMachine).start();
|
28
|
+
|
29
|
+
constructor(
|
30
|
+
name: string,
|
31
|
+
profile: string,
|
32
|
+
goal: string,
|
33
|
+
constraints: string = '',
|
34
|
+
actions: Action[] = []
|
35
|
+
) {
|
36
|
+
this.name = name;
|
37
|
+
this.profile = profile;
|
38
|
+
this.goal = goal;
|
39
|
+
this.constraints = constraints;
|
40
|
+
this.actions = actions;
|
41
|
+
|
42
|
+
// 初始化上下文
|
43
|
+
this.context = {
|
44
|
+
memory: new ArrayMemory(),
|
45
|
+
workingMemory: new ArrayMemory(),
|
46
|
+
state: -1,
|
47
|
+
todo: null,
|
48
|
+
watch: new Set<string>(),
|
49
|
+
reactMode: 'react',
|
50
|
+
};
|
51
|
+
|
52
|
+
// 订阅状态变化
|
53
|
+
this.stateMachine.subscribe((state) => {
|
54
|
+
this.state = this.stateToNumber(state.value as string);
|
55
|
+
});
|
56
|
+
|
57
|
+
// 订阅消息
|
58
|
+
this.messageSubject.subscribe((message) => {
|
59
|
+
this.context.memory.add(message);
|
60
|
+
});
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* 观察环境,获取下一个状态
|
65
|
+
*/
|
66
|
+
async observe(): Promise<number> {
|
67
|
+
this.stateMachine.send({ type: 'OBSERVE' });
|
68
|
+
const messages = await this.context.memory.get();
|
69
|
+
// 子类需要实现具体的观察逻辑
|
70
|
+
return this.state;
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* 思考下一步行动
|
75
|
+
*/
|
76
|
+
async think(): Promise<boolean> {
|
77
|
+
this.stateMachine.send({ type: 'THINK' });
|
78
|
+
// 子类需要实现具体的思考逻辑
|
79
|
+
return true;
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* 执行行动
|
84
|
+
*/
|
85
|
+
async act(): Promise<Message> {
|
86
|
+
this.stateMachine.send({ type: 'ACT' });
|
87
|
+
if (!this.context.todo) {
|
88
|
+
throw new Error('No action to execute');
|
89
|
+
}
|
90
|
+
|
91
|
+
try {
|
92
|
+
const output = await this.context.todo.run();
|
93
|
+
const message: Message = {
|
94
|
+
id: generateId(),
|
95
|
+
content: output.content,
|
96
|
+
role: this.name,
|
97
|
+
causedBy: this.context.todo.name,
|
98
|
+
sentFrom: this.name,
|
99
|
+
sendTo: new Set(['*']),
|
100
|
+
instructContent: output.instruct_content,
|
101
|
+
};
|
102
|
+
|
103
|
+
this.messageSubject.next(message);
|
104
|
+
return message;
|
105
|
+
} catch (error) {
|
106
|
+
await this.context.todo.handleException(error as Error);
|
107
|
+
throw error;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* 角色对消息的响应
|
113
|
+
*/
|
114
|
+
async react(message?: Message): Promise<Message> {
|
115
|
+
console.log(`[BaseRole] react method called in ${this.name} with${message ? '' : 'out'} message`);
|
116
|
+
this.stateMachine.send({ type: 'REACT' });
|
117
|
+
// 子类需要实现具体的响应逻辑
|
118
|
+
return this.act();
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* 将状态字符串转换为数字
|
123
|
+
*/
|
124
|
+
private stateToNumber(state: string): number {
|
125
|
+
const stateMap: Record<string, number> = {
|
126
|
+
idle: -1,
|
127
|
+
observing: 0,
|
128
|
+
thinking: 1,
|
129
|
+
acting: 2,
|
130
|
+
reacting: 3,
|
131
|
+
};
|
132
|
+
return stateMap[state] ?? -1;
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* 设置要执行的动作
|
137
|
+
*/
|
138
|
+
protected setTodo(action: Action | null): void {
|
139
|
+
this.context.todo = action;
|
140
|
+
}
|
141
|
+
|
142
|
+
/**
|
143
|
+
* 获取记忆中的重要消息
|
144
|
+
*/
|
145
|
+
protected getImportantMemory(): Message[] {
|
146
|
+
return this.context.memory.getByActions(this.context.watch);
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* 发送消息
|
151
|
+
*/
|
152
|
+
protected sendMessage(message: Message): void {
|
153
|
+
this.messageSubject.next(message);
|
154
|
+
}
|
155
|
+
}
|
@@ -0,0 +1,360 @@
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
2
|
+
import { BaseRole } from './base-role';
|
3
|
+
import { ExecuteNbCode } from '../actions/di/execute-nb-code';
|
4
|
+
import { WriteAnalysisCode, CheckData } from '../actions/di/write-analysis-code';
|
5
|
+
import type { ActionConfig } from '../actions/di/write-analysis-code';
|
6
|
+
import type { Message } from '../types/message';
|
7
|
+
import type { LLMProvider } from '../types/llm';
|
8
|
+
import type { Action } from '../types/action';
|
9
|
+
import { BM25ToolRecommender } from '../tools/tool-recommend';
|
10
|
+
import type { ToolRecommender } from '../tools/tool-recommend';
|
11
|
+
import { ArrayMemory } from '../types/memory';
|
12
|
+
import type { Task, TaskResult } from '../types/task';
|
13
|
+
|
14
|
+
/**
|
15
|
+
* 思考提示词
|
16
|
+
*/
|
17
|
+
const REACT_THINK_PROMPT = `
|
18
|
+
# User Requirement
|
19
|
+
{user_requirement}
|
20
|
+
# Context
|
21
|
+
{context}
|
22
|
+
|
23
|
+
Output a json following the format:
|
24
|
+
\`\`\`json
|
25
|
+
{
|
26
|
+
"thoughts": str = "Thoughts on current situation, reflect on how you should proceed to fulfill the user requirement",
|
27
|
+
"state": bool = "Decide whether you need to take more actions to complete the user requirement. Return true if you think so. Return false if you think the requirement has been completely fulfilled."
|
28
|
+
}
|
29
|
+
\`\`\`
|
30
|
+
`;
|
31
|
+
|
32
|
+
/**
|
33
|
+
* 数据解释器配置接口
|
34
|
+
*/
|
35
|
+
export interface DataInterpreterConfig {
|
36
|
+
llm: LLMProvider;
|
37
|
+
auto_run?: boolean;
|
38
|
+
use_plan?: boolean;
|
39
|
+
use_reflection?: boolean;
|
40
|
+
tools?: string[];
|
41
|
+
react_mode?: 'plan_and_act' | 'react';
|
42
|
+
max_react_loop?: number;
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* 数据解释器角色,用于数据分析和可视化
|
47
|
+
*/
|
48
|
+
export class DataInterpreter extends BaseRole {
|
49
|
+
llm: LLMProvider;
|
50
|
+
auto_run: boolean;
|
51
|
+
use_plan: boolean;
|
52
|
+
use_reflection: boolean;
|
53
|
+
execute_code: ExecuteNbCode;
|
54
|
+
tools: string[] = [];
|
55
|
+
tool_recommender: any = null;
|
56
|
+
react_mode: 'plan_and_act' | 'react';
|
57
|
+
max_react_loop: number;
|
58
|
+
planner: any = null; // This would be replaced with actual Planner type
|
59
|
+
|
60
|
+
/**
|
61
|
+
* 构造函数
|
62
|
+
*/
|
63
|
+
constructor(config: DataInterpreterConfig) {
|
64
|
+
super(
|
65
|
+
'David',
|
66
|
+
'DataInterpreter',
|
67
|
+
'Analyze data and provide insights through code generation and execution',
|
68
|
+
'Write clean, efficient, and well-documented code for data analysis',
|
69
|
+
[]
|
70
|
+
);
|
71
|
+
|
72
|
+
console.log('[DataInterpreter] Initializing with config:', {
|
73
|
+
auto_run: config.auto_run ?? true,
|
74
|
+
use_plan: config.use_plan ?? true,
|
75
|
+
use_reflection: config.use_reflection ?? false,
|
76
|
+
react_mode: config.react_mode ?? 'plan_and_act',
|
77
|
+
max_react_loop: config.max_react_loop ?? 10,
|
78
|
+
tools: config.tools?.length ?? 0,
|
79
|
+
});
|
80
|
+
|
81
|
+
this.llm = config.llm;
|
82
|
+
this.auto_run = config.auto_run ?? true;
|
83
|
+
this.use_plan = config.use_plan ?? true;
|
84
|
+
this.use_reflection = config.use_reflection ?? false;
|
85
|
+
this.execute_code = new ExecuteNbCode(this.llm);
|
86
|
+
this.tools = config.tools ?? [];
|
87
|
+
this.react_mode = config.react_mode ?? 'plan_and_act';
|
88
|
+
this.max_react_loop = config.max_react_loop ?? 10;
|
89
|
+
|
90
|
+
// Initialize tool recommender if tools are provided
|
91
|
+
if (this.tools.length > 0) {
|
92
|
+
this.tool_recommender = new BM25ToolRecommender(this.tools);
|
93
|
+
}
|
94
|
+
|
95
|
+
// Initialize actions
|
96
|
+
this.initialize();
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* 初始化角色
|
101
|
+
*/
|
102
|
+
private initialize(): void {
|
103
|
+
console.log('[DataInterpreter] Initializing role');
|
104
|
+
|
105
|
+
// Set react mode and working memory
|
106
|
+
this.setReactMode(this.react_mode, this.max_react_loop, this.auto_run);
|
107
|
+
|
108
|
+
// Override use_plan based on react_mode for consistency
|
109
|
+
this.use_plan = this.react_mode === 'plan_and_act';
|
110
|
+
|
111
|
+
// Set initial action
|
112
|
+
this.actions = [new WriteAnalysisCode({ llm: this.llm })];
|
113
|
+
|
114
|
+
// Set initial state
|
115
|
+
this.context.state = 0;
|
116
|
+
this.setTodo(this.actions[0]);
|
117
|
+
|
118
|
+
console.log('[DataInterpreter] Initialization complete');
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* 设置反应模式
|
123
|
+
*/
|
124
|
+
private setReactMode(mode: 'plan_and_act' | 'react', maxLoop: number, autoRun: boolean): void {
|
125
|
+
this.react_mode = mode;
|
126
|
+
|
127
|
+
if (mode === 'react') {
|
128
|
+
this.context.reactMode = 'react';
|
129
|
+
this.max_react_loop = maxLoop;
|
130
|
+
} else {
|
131
|
+
this.context.reactMode = 'plan_and_act';
|
132
|
+
// Initialize planner here (simplified)
|
133
|
+
// In a full implementation, we would instantiate a proper Planner class
|
134
|
+
this.planner = {
|
135
|
+
plan: {
|
136
|
+
tasks: [],
|
137
|
+
get_finished_tasks: () => [],
|
138
|
+
current_task: null,
|
139
|
+
get_plan_status: () => ""
|
140
|
+
},
|
141
|
+
ask_review: async () => ["", false],
|
142
|
+
set_working_memory: (wm: any) => {}
|
143
|
+
};
|
144
|
+
|
145
|
+
if (!this.context.workingMemory) {
|
146
|
+
this.context.workingMemory = new ArrayMemory();
|
147
|
+
}
|
148
|
+
|
149
|
+
// Connect planner with working memory
|
150
|
+
if (this.planner && this.planner.set_working_memory) {
|
151
|
+
this.planner.set_working_memory(this.context.workingMemory);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* 获取工作记忆
|
158
|
+
*/
|
159
|
+
get working_memory(): ArrayMemory {
|
160
|
+
return this.context.workingMemory;
|
161
|
+
}
|
162
|
+
|
163
|
+
/**
|
164
|
+
* 思考下一步行动(React 模式下使用)
|
165
|
+
*/
|
166
|
+
async think(): Promise<boolean> {
|
167
|
+
console.log('[DataInterpreter] Starting think method');
|
168
|
+
|
169
|
+
// Get user requirement and context
|
170
|
+
const memories = await this.context.memory.get();
|
171
|
+
if (!memories || memories.length === 0) {
|
172
|
+
console.warn('[DataInterpreter] No memories available');
|
173
|
+
return false;
|
174
|
+
}
|
175
|
+
|
176
|
+
const user_requirement = memories[0].content;
|
177
|
+
const context = this.working_memory ? await this.working_memory.get() : [];
|
178
|
+
|
179
|
+
if (!context || context.length === 0) {
|
180
|
+
// Just started the run, we need action certainly
|
181
|
+
console.log('[DataInterpreter] No context available, adding user requirement to working memory');
|
182
|
+
if (this.working_memory) {
|
183
|
+
this.working_memory.add(memories[0]);
|
184
|
+
}
|
185
|
+
this.context.state = 0;
|
186
|
+
this.setTodo(this.actions[0]);
|
187
|
+
return true;
|
188
|
+
}
|
189
|
+
|
190
|
+
// Format context for prompt
|
191
|
+
const contextText = context.map(msg => `${msg.role}: ${msg.content}`).join('\n\n');
|
192
|
+
|
193
|
+
// Create thinking prompt
|
194
|
+
const prompt = REACT_THINK_PROMPT
|
195
|
+
.replace('{user_requirement}', user_requirement)
|
196
|
+
.replace('{context}', contextText);
|
197
|
+
|
198
|
+
console.log('[DataInterpreter] Sending think prompt to LLM');
|
199
|
+
|
200
|
+
// Get LLM response
|
201
|
+
const response = await this.llm.generate(prompt);
|
202
|
+
console.log(`[DataInterpreter] Received LLM response: ${response.substring(0, 100)}...`);
|
203
|
+
|
204
|
+
// Parse JSON response
|
205
|
+
try {
|
206
|
+
const jsonStr = response.replace(/```json|```/g, '').trim();
|
207
|
+
const responseObj = JSON.parse(jsonStr);
|
208
|
+
|
209
|
+
// Add thoughts to working memory
|
210
|
+
if (this.working_memory) {
|
211
|
+
this.working_memory.add({
|
212
|
+
id: uuidv4(),
|
213
|
+
content: responseObj.thoughts,
|
214
|
+
role: 'assistant',
|
215
|
+
causedBy: 'think',
|
216
|
+
sentFrom: this.name,
|
217
|
+
sendTo: new Set(['*']),
|
218
|
+
instructContent: null
|
219
|
+
});
|
220
|
+
}
|
221
|
+
|
222
|
+
// Set state based on whether more action is needed
|
223
|
+
const needAction = responseObj.state;
|
224
|
+
this.context.state = needAction ? 0 : -1;
|
225
|
+
if (needAction) {
|
226
|
+
this.setTodo(this.actions[0]);
|
227
|
+
} else {
|
228
|
+
this.setTodo(null);
|
229
|
+
}
|
230
|
+
|
231
|
+
console.log(`[DataInterpreter] Think result: need further action = ${needAction}`);
|
232
|
+
return needAction;
|
233
|
+
} catch (error) {
|
234
|
+
console.error('[DataInterpreter] Error parsing LLM response:', error);
|
235
|
+
// Default to taking action if parsing fails
|
236
|
+
this.context.state = 0;
|
237
|
+
this.setTodo(this.actions[0]);
|
238
|
+
return true;
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
* 执行行动(React 模式下使用)
|
244
|
+
*/
|
245
|
+
async act(): Promise<Message> {
|
246
|
+
console.log('[DataInterpreter] Starting act method');
|
247
|
+
|
248
|
+
const [code, result, isSuccess] = await this.writeAndExecCode();
|
249
|
+
|
250
|
+
const message: Message = {
|
251
|
+
id: uuidv4(),
|
252
|
+
content: code,
|
253
|
+
role: 'assistant',
|
254
|
+
causedBy: 'WriteAnalysisCode',
|
255
|
+
sentFrom: this.name,
|
256
|
+
sendTo: new Set(['*']),
|
257
|
+
instructContent: null
|
258
|
+
};
|
259
|
+
|
260
|
+
console.log('[DataInterpreter] Act completed, returning message');
|
261
|
+
return message;
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* 基于计划执行行动(plan_and_act 模式下使用)
|
266
|
+
*/
|
267
|
+
async planAndAct(): Promise<Message> {
|
268
|
+
console.log('[DataInterpreter] Starting planAndAct method');
|
269
|
+
|
270
|
+
try {
|
271
|
+
// This would be replaced with actual implementation
|
272
|
+
// that interacts with a proper Planner class
|
273
|
+
const message = await this.act();
|
274
|
+
await this.execute_code.terminate();
|
275
|
+
return message;
|
276
|
+
} catch (error) {
|
277
|
+
console.error('[DataInterpreter] Error in planAndAct:', error);
|
278
|
+
await this.execute_code.terminate();
|
279
|
+
throw error;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* 执行特定任务(plan_and_act 模式下使用)
|
285
|
+
*/
|
286
|
+
async actOnTask(task: Task): Promise<TaskResult> {
|
287
|
+
console.log(`[DataInterpreter] Starting actOnTask with task: ${task.title}`);
|
288
|
+
|
289
|
+
const [code, result, isSuccess] = await this.writeAndExecCode();
|
290
|
+
|
291
|
+
const taskResult: TaskResult = {
|
292
|
+
code: code,
|
293
|
+
result: result,
|
294
|
+
isSuccess: isSuccess
|
295
|
+
};
|
296
|
+
|
297
|
+
console.log(`[DataInterpreter] Task completed with success: ${isSuccess}`);
|
298
|
+
return taskResult;
|
299
|
+
}
|
300
|
+
|
301
|
+
/**
|
302
|
+
* 编写并执行代码
|
303
|
+
*/
|
304
|
+
private async writeAndExecCode(maxRetry: number = 3): Promise<[string, string, boolean]> {
|
305
|
+
console.log(`[DataInterpreter] Starting writeAndExecCode with max retries: ${maxRetry}`);
|
306
|
+
|
307
|
+
let counter = 0;
|
308
|
+
let success = false;
|
309
|
+
let code = '';
|
310
|
+
let result = '';
|
311
|
+
|
312
|
+
// Prepare plan status
|
313
|
+
const planStatus = this.use_plan && this.planner ? this.planner.get_plan_status() : '';
|
314
|
+
|
315
|
+
// Prepare tool info
|
316
|
+
let toolInfo = '';
|
317
|
+
if (this.tool_recommender) {
|
318
|
+
const context = this.working_memory && this.working_memory.get().length > 0
|
319
|
+
? this.working_memory.get()[this.working_memory.get().length - 1].content
|
320
|
+
: '';
|
321
|
+
const plan = this.use_plan && this.planner ? this.planner.plan : null;
|
322
|
+
|
323
|
+
toolInfo = await this.tool_recommender.getRecommendedToolInfo(context, plan);
|
324
|
+
}
|
325
|
+
|
326
|
+
// Check data (in a full implementation, this would interact with actual data)
|
327
|
+
await this.checkData();
|
328
|
+
|
329
|
+
// Try to write and execute code, with retries
|
330
|
+
while (!success && counter < maxRetry) {
|
331
|
+
console.log(`[DataInterpreter] Code execution attempt ${counter + 1} of ${maxRetry}`);
|
332
|
+
|
333
|
+
// Write code
|
334
|
+
[code] = await this.writeCode(counter, planStatus, toolInfo);
|
335
|
+
|
336
|
+
// Add code to working memory
|
337
|
+
if (this.working_memory) {
|
338
|
+
this.working_memory.add({
|
339
|
+
id: uuidv4(),
|
340
|
+
content: code,
|
341
|
+
role: 'assistant',
|
342
|
+
causedBy: 'WriteAnalysisCode',
|
343
|
+
sentFrom: this.name,
|
344
|
+
sendTo: new Set(['*']),
|
345
|
+
instructContent: null
|
346
|
+
});
|
347
|
+
}
|
348
|
+
|
349
|
+
// Execute code
|
350
|
+
[result, success] = await this.execute_code.run(code);
|
351
|
+
console.log(`Execution result: ${success ? 'Success' : 'Failed'}`);
|
352
|
+
|
353
|
+
if (!success) {
|
354
|
+
console.log(`[DataInterpreter] Code execution failed, retrying...`);
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
return [code, result, success];
|
359
|
+
}
|
360
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
|