@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.
Files changed (113) hide show
  1. package/.eslintrc.json +23 -0
  2. package/.prettierrc +7 -0
  3. package/LICENSE +21 -0
  4. package/README-CN.md +754 -0
  5. package/README.md +238 -0
  6. package/bun.lock +1023 -0
  7. package/doc/TutorialAssistant.md +114 -0
  8. package/doc/VercelLLMProvider.md +164 -0
  9. package/eslint.config.js +55 -0
  10. package/examples/data-interpreter-example.ts +173 -0
  11. package/examples/qwen-direct-example.ts +60 -0
  12. package/examples/qwen-example.ts +62 -0
  13. package/examples/tutorial-assistant-example.ts +97 -0
  14. package/jest.config.ts +22 -0
  15. 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
  16. package/output/tutorials/Rust/346/225/231/347/250/213_2025-02-25T08-27-27-632Z.md +1967 -0
  17. 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
  18. 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
  19. 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
  20. package/package.json +58 -0
  21. package/plan-cn.md +321 -0
  22. package/plan.md +154 -0
  23. package/src/actions/analyze-task.ts +65 -0
  24. package/src/actions/base-action.ts +103 -0
  25. package/src/actions/di/execute-nb-code.ts +247 -0
  26. package/src/actions/di/write-analysis-code.ts +234 -0
  27. package/src/actions/write-tutorial.ts +232 -0
  28. package/src/config/browser.ts +33 -0
  29. package/src/config/config.ts +345 -0
  30. package/src/config/embedding.ts +26 -0
  31. package/src/config/llm.ts +36 -0
  32. package/src/config/mermaid.ts +37 -0
  33. package/src/config/omniparse.ts +25 -0
  34. package/src/config/redis.ts +34 -0
  35. package/src/config/s3.ts +33 -0
  36. package/src/config/search.ts +30 -0
  37. package/src/config/workspace.ts +20 -0
  38. package/src/index.ts +40 -0
  39. package/src/management/team.ts +168 -0
  40. package/src/memory/longterm.ts +218 -0
  41. package/src/memory/manager.ts +160 -0
  42. package/src/memory/types.ts +100 -0
  43. package/src/memory/working.ts +154 -0
  44. package/src/monitoring/system.ts +413 -0
  45. package/src/monitoring/types.ts +230 -0
  46. package/src/plugin/manager.ts +79 -0
  47. package/src/plugin/types.ts +114 -0
  48. package/src/provider/vercel-llm.ts +314 -0
  49. package/src/rag/base-rag.ts +194 -0
  50. package/src/rag/document-qa.ts +102 -0
  51. package/src/roles/base-role.ts +155 -0
  52. package/src/roles/data-interpreter.ts +360 -0
  53. package/src/roles/engineer.ts +1 -0
  54. package/src/roles/tutorial-assistant.ts +217 -0
  55. package/src/skills/base-skill.ts +144 -0
  56. package/src/skills/code-review.ts +120 -0
  57. package/src/tools/base-tool.ts +155 -0
  58. package/src/tools/file-system.ts +204 -0
  59. package/src/tools/tool-recommend.d.ts +14 -0
  60. package/src/tools/tool-recommend.ts +31 -0
  61. package/src/types/action.ts +38 -0
  62. package/src/types/config.ts +129 -0
  63. package/src/types/document.ts +354 -0
  64. package/src/types/llm.ts +64 -0
  65. package/src/types/memory.ts +36 -0
  66. package/src/types/message.ts +193 -0
  67. package/src/types/rag.ts +86 -0
  68. package/src/types/role.ts +67 -0
  69. package/src/types/skill.ts +71 -0
  70. package/src/types/task.ts +32 -0
  71. package/src/types/team.ts +55 -0
  72. package/src/types/tool.ts +77 -0
  73. package/src/types/workflow.ts +133 -0
  74. package/src/utils/common.ts +73 -0
  75. package/src/utils/yaml.ts +67 -0
  76. package/src/websocket/browser-client.ts +187 -0
  77. package/src/websocket/client.ts +186 -0
  78. package/src/websocket/server.ts +169 -0
  79. package/src/websocket/types.ts +125 -0
  80. package/src/workflow/executor.ts +193 -0
  81. package/src/workflow/executors/action-executor.ts +72 -0
  82. package/src/workflow/executors/condition-executor.ts +118 -0
  83. package/src/workflow/executors/parallel-executor.ts +201 -0
  84. package/src/workflow/executors/role-executor.ts +76 -0
  85. package/src/workflow/executors/sequence-executor.ts +196 -0
  86. package/tests/actions.test.ts +105 -0
  87. package/tests/benchmark/performance.test.ts +147 -0
  88. package/tests/config/config.test.ts +115 -0
  89. package/tests/config.test.ts +106 -0
  90. package/tests/e2e/setup.ts +74 -0
  91. package/tests/e2e/workflow.test.ts +88 -0
  92. package/tests/llm.test.ts +84 -0
  93. package/tests/memory/memory.test.ts +164 -0
  94. package/tests/memory.test.ts +63 -0
  95. package/tests/monitoring/monitoring.test.ts +225 -0
  96. package/tests/plugin/plugin.test.ts +183 -0
  97. package/tests/provider/bailian-llm.test.ts +98 -0
  98. package/tests/rag.test.ts +162 -0
  99. package/tests/roles.test.ts +88 -0
  100. package/tests/skills.test.ts +166 -0
  101. package/tests/team.test.ts +143 -0
  102. package/tests/tools.test.ts +170 -0
  103. package/tests/types/document.test.ts +181 -0
  104. package/tests/types/message.test.ts +122 -0
  105. package/tests/utils/yaml.test.ts +110 -0
  106. package/tests/utils.test.ts +74 -0
  107. package/tests/websocket/browser-client.test.ts +1 -0
  108. package/tests/websocket/websocket.test.ts +42 -0
  109. package/tests/workflow/parallel-executor.test.ts +224 -0
  110. package/tests/workflow/sequence-executor.test.ts +207 -0
  111. package/tests/workflow.test.ts +290 -0
  112. package/tsconfig.json +27 -0
  113. package/typedoc.json +25 -0
@@ -0,0 +1,193 @@
1
+ import { EventEmitter } from 'events';
2
+ import type {
3
+ WorkflowExecutor,
4
+ WorkflowConfig,
5
+ WorkflowState,
6
+ WorkflowNode,
7
+ NodeExecutor,
8
+ WorkflowEvent
9
+ } from '../types/workflow';
10
+ import {
11
+ WorkflowStateSchema,
12
+ WorkflowNodeSchema,
13
+ WorkflowEventSchema
14
+ } from '../types/workflow';
15
+ import { generateId } from '../utils/common';
16
+
17
+ /**
18
+ * 基础工作流执行器实现
19
+ */
20
+ export class BaseWorkflowExecutor extends EventEmitter implements WorkflowExecutor {
21
+ private config!: WorkflowConfig;
22
+ private state!: WorkflowState;
23
+ private nodeExecutors: Map<string, NodeExecutor>;
24
+ private isPaused: boolean = false;
25
+ private isStopped: boolean = false;
26
+
27
+ constructor() {
28
+ super();
29
+ this.nodeExecutors = new Map();
30
+ }
31
+
32
+ /**
33
+ * 注册节点执行器
34
+ * @param type 节点类型
35
+ * @param executor 执行器实例
36
+ */
37
+ public registerNodeExecutor(type: string, executor: NodeExecutor): void {
38
+ this.nodeExecutors.set(type, executor);
39
+ }
40
+
41
+ /**
42
+ * 执行工作流
43
+ * @param config 工作流配置
44
+ */
45
+ public async execute(config: WorkflowConfig): Promise<void> {
46
+ this.config = config;
47
+ this.state = WorkflowStateSchema.parse({
48
+ id: config.id,
49
+ status: 'running',
50
+ });
51
+
52
+ this.emit('workflow:start', this.createEvent('workflow:start'));
53
+
54
+ try {
55
+ await this.executeNode(this.findStartNode());
56
+
57
+ if (!this.isStopped) {
58
+ this.state.status = 'completed';
59
+ this.emit('workflow:complete', this.createEvent('workflow:complete'));
60
+ }
61
+ } catch (error) {
62
+ this.state.status = 'failed';
63
+ this.emit('workflow:fail', this.createEvent('workflow:fail', { error }));
64
+ throw error;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * 暂停工作流
70
+ */
71
+ public async pause(): Promise<void> {
72
+ this.isPaused = true;
73
+ }
74
+
75
+ /**
76
+ * 恢复工作流
77
+ */
78
+ public async resume(): Promise<void> {
79
+ this.isPaused = false;
80
+ if (this.state.currentNodeId) {
81
+ await this.executeNode(this.findNodeById(this.state.currentNodeId));
82
+ }
83
+ }
84
+
85
+ /**
86
+ * 停止工作流
87
+ */
88
+ public async stop(): Promise<void> {
89
+ this.isStopped = true;
90
+ }
91
+
92
+ /**
93
+ * 获取工作流状态
94
+ */
95
+ public getState(): WorkflowState {
96
+ return this.state;
97
+ }
98
+
99
+ /**
100
+ * 执行节点
101
+ * @param node 工作流节点
102
+ */
103
+ private async executeNode(node: WorkflowNode): Promise<void> {
104
+ if (this.isStopped) return;
105
+
106
+ while (this.isPaused) {
107
+ await new Promise(resolve => setTimeout(resolve, 100));
108
+ }
109
+
110
+ this.state.currentNodeId = node.id;
111
+ this.emit('node:start', this.createEvent('node:start', { nodeId: node.id }));
112
+
113
+ try {
114
+ const executor = this.nodeExecutors.get(node.type);
115
+ if (!executor) {
116
+ throw new Error(`No executor found for node type: ${node.type}`);
117
+ }
118
+
119
+ if (!executor.validate(node)) {
120
+ throw new Error(`Invalid node configuration: ${node.id}`);
121
+ }
122
+
123
+ const result = await executor.execute(node, {
124
+ workflow: this.config,
125
+ state: this.state,
126
+ });
127
+
128
+ node.status = 'completed';
129
+ node.result = result;
130
+ this.state.completedNodeIds.push(node.id);
131
+
132
+ this.emit('node:complete', this.createEvent('node:complete', {
133
+ nodeId: node.id,
134
+ data: result,
135
+ }));
136
+
137
+ // 执行子节点
138
+ for (const childId of node.childIds) {
139
+ await this.executeNode(this.findNodeById(childId));
140
+ }
141
+ } catch (error) {
142
+ node.status = 'failed';
143
+ this.state.failedNodeIds.push(node.id);
144
+
145
+ this.emit('node:fail', this.createEvent('node:fail', {
146
+ nodeId: node.id,
147
+ error,
148
+ }));
149
+
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ /**
155
+ * 查找起始节点
156
+ */
157
+ private findStartNode(): WorkflowNode {
158
+ const startNode = this.config.nodes.find(node => !node.parentId);
159
+ if (!startNode) {
160
+ throw new Error('No start node found in workflow');
161
+ }
162
+ return startNode;
163
+ }
164
+
165
+ /**
166
+ * 根据ID查找节点
167
+ * @param id 节点ID
168
+ */
169
+ private findNodeById(id: string): WorkflowNode {
170
+ const node = this.config.nodes.find(node => node.id === id);
171
+ if (!node) {
172
+ throw new Error(`Node not found: ${id}`);
173
+ }
174
+ return node;
175
+ }
176
+
177
+ /**
178
+ * 创建工作流事件
179
+ * @param type 事件类型
180
+ * @param data 事件数据
181
+ */
182
+ private createEvent(
183
+ type: WorkflowEvent['type'],
184
+ data: Partial<WorkflowEvent> = {}
185
+ ): WorkflowEvent {
186
+ return WorkflowEventSchema.parse({
187
+ type,
188
+ timestamp: Date.now(),
189
+ workflowId: this.config.id,
190
+ ...data,
191
+ });
192
+ }
193
+ }
@@ -0,0 +1,72 @@
1
+ import type { NodeExecutor, WorkflowNode } from '../../types/workflow';
2
+ import type { Action, ActionOutput } from '../../types/action';
3
+
4
+ /**
5
+ * 动作节点执行器
6
+ * 用于执行动作类型的工作流节点
7
+ */
8
+ export class ActionNodeExecutor implements NodeExecutor {
9
+ private status: string = 'pending';
10
+ private result: any = null;
11
+
12
+ /**
13
+ * 执行动作节点
14
+ * @param node 工作流节点
15
+ * @param context 执行上下文
16
+ */
17
+ async execute(node: WorkflowNode, context: any): Promise<ActionOutput> {
18
+ try {
19
+ this.status = 'running';
20
+
21
+ // 获取动作实例
22
+ const action = this.getAction(node);
23
+ if (!action) {
24
+ throw new Error(`Action not found in node: ${node.id}`);
25
+ }
26
+
27
+ // 执行动作
28
+ const result = await action.run();
29
+ this.result = result;
30
+ this.status = 'completed';
31
+
32
+ return result;
33
+ } catch (error) {
34
+ this.status = 'failed';
35
+ this.result = error;
36
+ throw error;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * 验证节点配置
42
+ * @param node 工作流节点
43
+ */
44
+ validate(node: WorkflowNode): boolean {
45
+ return (
46
+ node.type === 'action' &&
47
+ !!node.config?.action
48
+ );
49
+ }
50
+
51
+ /**
52
+ * 获取节点状态
53
+ */
54
+ getStatus(): string {
55
+ return this.status;
56
+ }
57
+
58
+ /**
59
+ * 获取执行结果
60
+ */
61
+ getResult(): any {
62
+ return this.result;
63
+ }
64
+
65
+ /**
66
+ * 从节点配置中获取动作实例
67
+ * @param node 工作流节点
68
+ */
69
+ private getAction(node: WorkflowNode): Action | undefined {
70
+ return node.config?.action as Action;
71
+ }
72
+ }
@@ -0,0 +1,118 @@
1
+ import type { NodeExecutor, WorkflowNode } from '../../types/workflow';
2
+
3
+ /**
4
+ * 条件节点配置
5
+ */
6
+ interface ConditionConfig {
7
+ /** 条件表达式 */
8
+ expression: string;
9
+ /** 条件参数 */
10
+ params?: Record<string, any>;
11
+ /** 条件处理函数 */
12
+ handler?: (params: Record<string, any>) => boolean | Promise<boolean>;
13
+ }
14
+
15
+ /**
16
+ * 条件节点执行器
17
+ * 用于执行条件类型的工作流节点
18
+ */
19
+ export class ConditionNodeExecutor implements NodeExecutor {
20
+ private status: string = 'pending';
21
+ private result: any = null;
22
+
23
+ /**
24
+ * 执行条件节点
25
+ * @param node 工作流节点
26
+ * @param context 执行上下文
27
+ */
28
+ async execute(node: WorkflowNode, context: any): Promise<boolean> {
29
+ try {
30
+ this.status = 'running';
31
+
32
+ // 获取条件配置
33
+ const config = this.getConditionConfig(node);
34
+ if (!config) {
35
+ throw new Error(`Condition config not found in node: ${node.id}`);
36
+ }
37
+
38
+ // 执行条件判断
39
+ const result = await this.evaluateCondition(config, context);
40
+ this.result = result;
41
+ this.status = 'completed';
42
+
43
+ return result;
44
+ } catch (error) {
45
+ this.status = 'failed';
46
+ this.result = error;
47
+ throw error;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * 验证节点配置
53
+ * @param node 工作流节点
54
+ */
55
+ validate(node: WorkflowNode): boolean {
56
+ const config = this.getConditionConfig(node);
57
+ return (
58
+ node.type === 'condition' &&
59
+ !!config &&
60
+ (!!config.expression || !!config.handler)
61
+ );
62
+ }
63
+
64
+ /**
65
+ * 获取节点状态
66
+ */
67
+ getStatus(): string {
68
+ return this.status;
69
+ }
70
+
71
+ /**
72
+ * 获取执行结果
73
+ */
74
+ getResult(): any {
75
+ return this.result;
76
+ }
77
+
78
+ /**
79
+ * 从节点配置中获取条件配置
80
+ * @param node 工作流节点
81
+ */
82
+ private getConditionConfig(node: WorkflowNode): ConditionConfig | undefined {
83
+ return node.config?.condition as ConditionConfig;
84
+ }
85
+
86
+ /**
87
+ * 执行条件判断
88
+ * @param config 条件配置
89
+ * @param context 执行上下文
90
+ */
91
+ private async evaluateCondition(
92
+ config: ConditionConfig,
93
+ context: any
94
+ ): Promise<boolean> {
95
+ try {
96
+ // 如果提供了处理函数,优先使用处理函数
97
+ if (config.handler) {
98
+ return await config.handler(config.params || {});
99
+ }
100
+
101
+ // 否则使用表达式求值
102
+ const params = {
103
+ ...config.params,
104
+ context,
105
+ };
106
+
107
+ // 使用 Function 构造函数创建表达式求值函数
108
+ const evaluator = new Function(
109
+ ...Object.keys(params),
110
+ `return ${config.expression};`
111
+ );
112
+
113
+ return evaluator(...Object.values(params));
114
+ } catch (error) {
115
+ throw new Error(`Failed to evaluate condition: ${error}`);
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,201 @@
1
+ import type { NodeExecutor, WorkflowNode } from '../../types/workflow';
2
+
3
+ /**
4
+ * 并行节点配置
5
+ */
6
+ interface ParallelConfig {
7
+ /** 最大并发数 */
8
+ maxConcurrency?: number;
9
+ /** 错误处理策略 */
10
+ errorStrategy?: 'fail-fast' | 'continue' | 'ignore';
11
+ /** 超时时间(ms) */
12
+ timeout?: number;
13
+ }
14
+
15
+ /**
16
+ * 并行节点执行器
17
+ * 用于并行执行多个子节点
18
+ */
19
+ export class ParallelNodeExecutor implements NodeExecutor {
20
+ private status: string = 'pending';
21
+ private result: any = null;
22
+
23
+ /**
24
+ * 执行并行节点
25
+ * @param node 工作流节点
26
+ * @param context 执行上下文
27
+ */
28
+ async execute(node: WorkflowNode, context: any): Promise<any[]> {
29
+ try {
30
+ this.status = 'running';
31
+
32
+ // 获取并行配置
33
+ const config = this.getParallelConfig(node);
34
+
35
+ // 获取子节点执行器
36
+ const childExecutors = this.getChildExecutors(node, context);
37
+ if (childExecutors.length === 0) {
38
+ throw new Error(`No child nodes found in parallel node: ${node.id}`);
39
+ }
40
+
41
+ // 执行子节点
42
+ const results = await this.executeParallel(childExecutors, config);
43
+ this.result = results;
44
+ this.status = 'completed';
45
+
46
+ return results;
47
+ } catch (error) {
48
+ this.status = 'failed';
49
+ this.result = error;
50
+ throw error;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * 验证节点配置
56
+ * @param node 工作流节点
57
+ */
58
+ validate(node: WorkflowNode): boolean {
59
+ return (
60
+ node.type === 'parallel' &&
61
+ Array.isArray(node.childIds) &&
62
+ node.childIds.length > 0
63
+ );
64
+ }
65
+
66
+ /**
67
+ * 获取节点状态
68
+ */
69
+ getStatus(): string {
70
+ return this.status;
71
+ }
72
+
73
+ /**
74
+ * 获取执行结果
75
+ */
76
+ getResult(): any {
77
+ return this.result;
78
+ }
79
+
80
+ /**
81
+ * 从节点配置中获取并行配置
82
+ * @param node 工作流节点
83
+ */
84
+ private getParallelConfig(node: WorkflowNode): ParallelConfig {
85
+ return {
86
+ maxConcurrency: Infinity,
87
+ errorStrategy: 'fail-fast',
88
+ timeout: 0,
89
+ ...(node.config?.parallel || {}),
90
+ };
91
+ }
92
+
93
+ /**
94
+ * 获取子节点执行器列表
95
+ * @param node 工作流节点
96
+ * @param context 执行上下文
97
+ */
98
+ private getChildExecutors(
99
+ node: WorkflowNode,
100
+ context: any
101
+ ): Array<() => Promise<any>> {
102
+ return node.childIds.map(childId => {
103
+ const childNode = context.workflow.nodes.find(
104
+ (n: WorkflowNode) => n.id === childId
105
+ );
106
+ if (!childNode) {
107
+ throw new Error(`Child node not found: ${childId}`);
108
+ }
109
+
110
+ const executor = context.workflow.nodeExecutors.get(childNode.type);
111
+ if (!executor) {
112
+ throw new Error(`No executor found for node type: ${childNode.type}`);
113
+ }
114
+
115
+ return () => executor.execute(childNode, context);
116
+ });
117
+ }
118
+
119
+ /**
120
+ * 并行执行子节点
121
+ * @param executors 执行器列表
122
+ * @param config 并行配置
123
+ */
124
+ private async executeParallel(
125
+ executors: Array<() => Promise<any>>,
126
+ config: ParallelConfig
127
+ ): Promise<any[]> {
128
+ const results: any[] = [];
129
+ const errors: Error[] = [];
130
+
131
+ // 创建执行队列
132
+ const queue = [...executors];
133
+ const running = new Set<Promise<void>>();
134
+
135
+ while (queue.length > 0 || running.size > 0) {
136
+ // 检查是否可以启动新的执行器
137
+ while (
138
+ queue.length > 0 &&
139
+ running.size < (config.maxConcurrency || Infinity)
140
+ ) {
141
+ const executor = queue.shift()!;
142
+ const promise = (async () => {
143
+ try {
144
+ const result = await this.executeWithTimeout(
145
+ executor(),
146
+ config.timeout
147
+ );
148
+ results.push(result);
149
+ } catch (error) {
150
+ errors.push(error as Error);
151
+ if (config.errorStrategy === 'fail-fast') {
152
+ queue.length = 0; // 清空队列
153
+ throw error;
154
+ }
155
+ }
156
+ })();
157
+
158
+ running.add(promise);
159
+ // 执行完成后从运行集合中移除
160
+ promise.finally(() => running.delete(promise));
161
+ }
162
+
163
+ // 等待任意一个执行器完成
164
+ if (running.size > 0) {
165
+ await Promise.race(running);
166
+ }
167
+ }
168
+
169
+ // 处理错误
170
+ if (errors.length > 0 && config.errorStrategy !== 'ignore') {
171
+ throw new AggregateError(
172
+ errors,
173
+ `${errors.length} parallel executions failed`
174
+ );
175
+ }
176
+
177
+ return results;
178
+ }
179
+
180
+ /**
181
+ * 带超时的执行
182
+ * @param promise Promise
183
+ * @param timeout 超时时间
184
+ */
185
+ private async executeWithTimeout<T>(
186
+ promise: Promise<T>,
187
+ timeout?: number
188
+ ): Promise<T> {
189
+ if (!timeout || timeout <= 0) {
190
+ return promise;
191
+ }
192
+
193
+ const timeoutPromise = new Promise<never>((_, reject) => {
194
+ setTimeout(() => {
195
+ reject(new Error(`Execution timed out after ${timeout}ms`));
196
+ }, timeout);
197
+ });
198
+
199
+ return Promise.race([promise, timeoutPromise]);
200
+ }
201
+ }
@@ -0,0 +1,76 @@
1
+ import type { NodeExecutor, WorkflowNode } from '../../types/workflow';
2
+ import type { Role } from '../../types/role';
3
+ import type { Message } from '../../types/message';
4
+
5
+ /**
6
+ * 角色节点执行器
7
+ * 用于执行角色类型的工作流节点
8
+ */
9
+ export class RoleNodeExecutor implements NodeExecutor {
10
+ private status: string = 'pending';
11
+ private result: any = null;
12
+
13
+ /**
14
+ * 执行角色节点
15
+ * @param node 工作流节点
16
+ * @param context 执行上下文
17
+ */
18
+ async execute(node: WorkflowNode, context: any): Promise<Message> {
19
+ try {
20
+ this.status = 'running';
21
+
22
+ // 获取角色实例
23
+ const role = this.getRole(node);
24
+ if (!role) {
25
+ throw new Error(`Role not found in node: ${node.id}`);
26
+ }
27
+
28
+ // 执行角色行为
29
+ await role.observe();
30
+ await role.think();
31
+ const result = await role.act();
32
+
33
+ this.result = result;
34
+ this.status = 'completed';
35
+
36
+ return result;
37
+ } catch (error) {
38
+ this.status = 'failed';
39
+ this.result = error;
40
+ throw error;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * 验证节点配置
46
+ * @param node 工作流节点
47
+ */
48
+ validate(node: WorkflowNode): boolean {
49
+ return (
50
+ node.type === 'role' &&
51
+ !!node.config?.role
52
+ );
53
+ }
54
+
55
+ /**
56
+ * 获取节点状态
57
+ */
58
+ getStatus(): string {
59
+ return this.status;
60
+ }
61
+
62
+ /**
63
+ * 获取执行结果
64
+ */
65
+ getResult(): any {
66
+ return this.result;
67
+ }
68
+
69
+ /**
70
+ * 从节点配置中获取角色实例
71
+ * @param node 工作流节点
72
+ */
73
+ private getRole(node: WorkflowNode): Role | undefined {
74
+ return node.config?.role as Role;
75
+ }
76
+ }