openmatrix 0.1.56 → 0.1.58
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/README.md +24 -0
- package/dist/agents/impl/researcher-agent.d.ts +10 -1
- package/dist/agents/impl/researcher-agent.js +163 -41
- package/dist/cli/commands/brainstorm.js +47 -3
- package/dist/cli/commands/complete.js +26 -1
- package/dist/cli/commands/research.d.ts +2 -0
- package/dist/cli/commands/research.js +270 -0
- package/dist/cli/commands/start.js +5 -1
- package/dist/cli/index.js +2 -0
- package/dist/orchestrator/phase-executor.js +14 -0
- package/dist/storage/state-manager.d.ts +16 -0
- package/dist/storage/state-manager.js +58 -6
- package/dist/types/index.d.ts +36 -0
- package/package.json +1 -1
- package/skills/brainstorm.md +86 -20
- package/skills/om.md +47 -101
- package/skills/openmatrix.md +97 -190
- package/skills/research.md +258 -0
- package/skills/start.md +33 -9
package/README.md
CHANGED
|
@@ -386,6 +386,27 @@ Accept 阶段由 Reviewer Agent 执行:
|
|
|
386
386
|
}
|
|
387
387
|
```
|
|
388
388
|
|
|
389
|
+
## 状态存储
|
|
390
|
+
|
|
391
|
+
任务状态持久化在 `.openmatrix/` 目录:
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
.openmatrix/
|
|
395
|
+
├── state.json # 全局状态 (runId, status, config, statistics)
|
|
396
|
+
├── plan.md # AI 生成的执行计划
|
|
397
|
+
├── tasks-input.json # 任务输入 (goals, constraints, deliverables)
|
|
398
|
+
├── tasks/
|
|
399
|
+
│ └── TASK-001/
|
|
400
|
+
│ ├── task.json # 任务定义 + 状态 + 阶段信息
|
|
401
|
+
│ ├── context.md # Agent 上下文 (供后续 Agent 读取)
|
|
402
|
+
│ ├── develop.json # 开发阶段结果
|
|
403
|
+
│ ├── verify.json # 验证阶段结果 (质量门禁)
|
|
404
|
+
│ ├── accept.json # 验收阶段结果
|
|
405
|
+
│ └── artifacts/ # 产出文件 (result.md, quality-report.json 等)
|
|
406
|
+
├── approvals/ # 审批记录
|
|
407
|
+
└── meetings/ # Meeting 记录
|
|
408
|
+
```
|
|
409
|
+
|
|
389
410
|
---
|
|
390
411
|
|
|
391
412
|
## 多语言支持
|
|
@@ -465,6 +486,9 @@ cd openmatrix && npm install && npm run build && npm test
|
|
|
465
486
|
- [x] `/om:brainstorm` 头脑风暴模式
|
|
466
487
|
- [x] 多语言支持 (Python/Go/Java/TypeScript 等)
|
|
467
488
|
- [x] E2E 测试支持 (Web/Mobile/GUI)
|
|
489
|
+
- [x] Agent 上下文共享 (Agent Memory)
|
|
490
|
+
- [x] Task 子目录结构 + Phase 结果持久化
|
|
491
|
+
- [x] 执行循环持久化 (`openmatrix step`/`complete` 防上下文压缩丢失)
|
|
468
492
|
- [ ] VSCode 扩展
|
|
469
493
|
- [ ] CI/CD 集成
|
|
470
494
|
|
|
@@ -7,11 +7,20 @@ import type { Task, AgentType, AgentResult } from '../../types/index.js';
|
|
|
7
7
|
* - 分析技术方案
|
|
8
8
|
* - 总结最佳实践
|
|
9
9
|
* - 提供决策建议
|
|
10
|
+
*
|
|
11
|
+
* 支持动态领域感知,根据任务描述自动适配研究方向
|
|
10
12
|
*/
|
|
11
13
|
export declare class ResearcherAgent {
|
|
12
14
|
readonly type: AgentType;
|
|
13
15
|
readonly capabilities: string[];
|
|
14
16
|
execute(task: Task): Promise<AgentResult>;
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* 构建动态领域感知的研究 Prompt
|
|
19
|
+
*/
|
|
20
|
+
private buildDynamicResearchPrompt;
|
|
21
|
+
/**
|
|
22
|
+
* 从任务描述中提取研究上下文
|
|
23
|
+
*/
|
|
24
|
+
private extractResearchContext;
|
|
16
25
|
private generateRunId;
|
|
17
26
|
}
|
|
@@ -9,6 +9,8 @@ exports.ResearcherAgent = void 0;
|
|
|
9
9
|
* - 分析技术方案
|
|
10
10
|
* - 总结最佳实践
|
|
11
11
|
* - 提供决策建议
|
|
12
|
+
*
|
|
13
|
+
* 支持动态领域感知,根据任务描述自动适配研究方向
|
|
12
14
|
*/
|
|
13
15
|
class ResearcherAgent {
|
|
14
16
|
type = 'researcher';
|
|
@@ -16,7 +18,7 @@ class ResearcherAgent {
|
|
|
16
18
|
async execute(task) {
|
|
17
19
|
const startTime = Date.now();
|
|
18
20
|
try {
|
|
19
|
-
const prompt = this.
|
|
21
|
+
const prompt = this.buildDynamicResearchPrompt(task);
|
|
20
22
|
return {
|
|
21
23
|
runId: this.generateRunId(),
|
|
22
24
|
taskId: task.id,
|
|
@@ -44,88 +46,208 @@ class ResearcherAgent {
|
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* 构建动态领域感知的研究 Prompt
|
|
51
|
+
*/
|
|
52
|
+
buildDynamicResearchPrompt(task) {
|
|
53
|
+
// 从任务描述中提取领域和角色信息
|
|
54
|
+
const { domain, role, focus } = this.extractResearchContext(task.description);
|
|
48
55
|
return `
|
|
49
56
|
# 调研任务
|
|
50
57
|
|
|
51
|
-
##
|
|
58
|
+
## 研究领域
|
|
59
|
+
${domain}
|
|
60
|
+
|
|
61
|
+
## 角色定位
|
|
62
|
+
${role}
|
|
63
|
+
|
|
64
|
+
## 研究方向
|
|
65
|
+
${focus}
|
|
52
66
|
|
|
67
|
+
## 原始任务描述
|
|
53
68
|
${task.description}
|
|
54
69
|
|
|
55
70
|
## 调研步骤
|
|
56
71
|
|
|
57
72
|
1. **搜索资料**
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
73
|
+
- 使用 WebSearch 搜索领域核心概念
|
|
74
|
+
- 搜索行业标准、最佳实践
|
|
75
|
+
- 搜索主流技术方案和开源项目
|
|
76
|
+
- 搜索常见挑战和解决方案
|
|
62
77
|
|
|
63
|
-
2.
|
|
78
|
+
2. **分析整理**
|
|
64
79
|
- 功能对比
|
|
65
|
-
-
|
|
66
|
-
-
|
|
80
|
+
- 性能特点
|
|
81
|
+
- 社区生态
|
|
67
82
|
- 学习曲线
|
|
83
|
+
- 适用场景
|
|
68
84
|
|
|
69
85
|
3. **总结发现**
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
86
|
+
- 关键信息提炼
|
|
87
|
+
- 优缺点分析
|
|
88
|
+
- 决策建议
|
|
73
89
|
|
|
74
90
|
## 输出格式
|
|
75
91
|
|
|
76
92
|
\`\`\`markdown
|
|
77
|
-
# 调研报告
|
|
93
|
+
# ${domain} 调研报告
|
|
78
94
|
|
|
79
|
-
##
|
|
80
|
-
[调研的核心问题]
|
|
95
|
+
## 核心发现
|
|
81
96
|
|
|
82
|
-
|
|
83
|
-
- 搜索关键词: ...
|
|
84
|
-
- 参考来源: ...
|
|
97
|
+
[3-5 个关键发现,每个用一句话概括]
|
|
85
98
|
|
|
86
|
-
|
|
99
|
+
1. ...
|
|
100
|
+
2. ...
|
|
101
|
+
3. ...
|
|
87
102
|
|
|
88
|
-
|
|
89
|
-
- 描述: ...
|
|
90
|
-
- 优点:
|
|
91
|
-
- ...
|
|
92
|
-
- 缺点:
|
|
93
|
-
- ...
|
|
94
|
-
- 适用场景: ...
|
|
103
|
+
## 详细分析
|
|
95
104
|
|
|
96
|
-
###
|
|
97
|
-
-
|
|
98
|
-
-
|
|
105
|
+
### 发现 1: [标题]
|
|
106
|
+
- **描述**: ...
|
|
107
|
+
- **关键点**:
|
|
99
108
|
- ...
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
- **注意事项**: ...
|
|
110
|
+
|
|
111
|
+
### 发现 2: [标题]
|
|
112
|
+
...
|
|
103
113
|
|
|
104
|
-
##
|
|
114
|
+
## 行业最佳实践
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
1. ...
|
|
117
|
+
2. ...
|
|
118
|
+
3. ...
|
|
119
|
+
|
|
120
|
+
## 关键决策点
|
|
121
|
+
|
|
122
|
+
[用户需要做出的关键决策]
|
|
123
|
+
|
|
124
|
+
1. **决策 1**: [决策描述]
|
|
125
|
+
- 选项 A: ... (适用场景)
|
|
126
|
+
- 选项 B: ... (适用场景)
|
|
127
|
+
- 建议: ...
|
|
128
|
+
|
|
129
|
+
2. **决策 2**: ...
|
|
111
130
|
|
|
112
|
-
##
|
|
131
|
+
## 推荐方案
|
|
113
132
|
|
|
114
|
-
|
|
133
|
+
**首选方案**: ...
|
|
115
134
|
|
|
116
135
|
**理由**:
|
|
117
136
|
1. ...
|
|
118
137
|
2. ...
|
|
119
138
|
|
|
139
|
+
**备选方案**: ...
|
|
140
|
+
|
|
120
141
|
## 参考资料
|
|
142
|
+
|
|
121
143
|
1. [标题](链接)
|
|
144
|
+
2. [标题](链接)
|
|
122
145
|
\`\`\`
|
|
123
146
|
|
|
124
147
|
## 开始调研
|
|
125
148
|
|
|
126
149
|
请使用 WebSearch 和 WebFetch 工具搜索相关信息。
|
|
150
|
+
至少搜索 5 个相关关键词,覆盖官方文档、社区讨论、技术博客等维度。
|
|
127
151
|
`;
|
|
128
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* 从任务描述中提取研究上下文
|
|
155
|
+
*/
|
|
156
|
+
extractResearchContext(description) {
|
|
157
|
+
const lower = description.toLowerCase();
|
|
158
|
+
// 领域关键词映射
|
|
159
|
+
const domainMap = [
|
|
160
|
+
{
|
|
161
|
+
keywords: ['游戏', 'game', 'gamedev', 'unity', 'unreal'],
|
|
162
|
+
domain: '游戏开发',
|
|
163
|
+
aspects: ['游戏类型', '目标平台', '技术架构', '美术风格', '盈利模式']
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
keywords: ['网站', 'website', 'web app', '门户'],
|
|
167
|
+
domain: 'Web 网站开发',
|
|
168
|
+
aspects: ['功能需求', '用户体验', '技术栈', 'SEO', '性能优化']
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
keywords: ['app', '移动应用', 'ios', 'android', 'flutter'],
|
|
172
|
+
domain: '移动应用开发',
|
|
173
|
+
aspects: ['平台选择', '用户界面', '性能优化', '发布流程', '用户增长']
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
keywords: ['支付', 'payment', 'stripe', '支付宝'],
|
|
177
|
+
domain: '支付系统',
|
|
178
|
+
aspects: ['支付方式', '安全合规', '风控策略', '对账结算', '国际化']
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
keywords: ['电商', 'ecommerce', 'shop', '商城'],
|
|
182
|
+
domain: '电商系统',
|
|
183
|
+
aspects: ['商品管理', '购物流程', '库存物流', '营销工具', '数据分析']
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
keywords: ['社交', 'social', 'community', '论坛'],
|
|
187
|
+
domain: '社交平台',
|
|
188
|
+
aspects: ['用户关系', '内容互动', '实时通讯', '内容审核', '推荐算法']
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
keywords: ['安全', 'security', 'auth', '认证', '加密'],
|
|
192
|
+
domain: '安全领域',
|
|
193
|
+
aspects: ['威胁模型', '认证授权', '数据保护', '审计监控', '合规要求']
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
keywords: ['后台', 'admin', 'dashboard', 'cms', '管理'],
|
|
197
|
+
domain: '后台管理系统',
|
|
198
|
+
aspects: ['权限模型', '数据看板', '工作流程', 'API 设计', '多租户']
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
keywords: ['ai', '人工智能', 'ml', '机器学习', '大模型', 'llm'],
|
|
202
|
+
domain: 'AI/机器学习',
|
|
203
|
+
aspects: ['模型选择', '数据处理', '训练部署', '性能优化', '伦理合规']
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
keywords: ['区块链', 'blockchain', 'web3', 'defi', 'nft'],
|
|
207
|
+
domain: '区块链',
|
|
208
|
+
aspects: ['链选择', '智能合约', '安全审计', '性能扩展', '合规监管']
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
keywords: ['音视频', 'streaming', '直播', 'rtc', 'webrtc'],
|
|
212
|
+
domain: '音视频',
|
|
213
|
+
aspects: ['编解码', '传输协议', '延迟优化', '存储分发', '实时互动']
|
|
214
|
+
}
|
|
215
|
+
];
|
|
216
|
+
// 查找匹配的领域
|
|
217
|
+
for (const { keywords, domain, aspects } of domainMap) {
|
|
218
|
+
if (keywords.some(kw => lower.includes(kw))) {
|
|
219
|
+
return {
|
|
220
|
+
domain,
|
|
221
|
+
role: `${domain}专家`,
|
|
222
|
+
focus: `请重点调研以下方面: ${aspects.join('、')}`
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// 通用领域:尝试从"做X"模式提取
|
|
227
|
+
const actionPatterns = [
|
|
228
|
+
/做(一个|个)(.+?)(的|app|网站|系统|平台|工具|应用|$)/,
|
|
229
|
+
/开发(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
|
|
230
|
+
/构建(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
|
|
231
|
+
/build (a |an )?(.+?)(app|website|system|tool|platform|$)/i,
|
|
232
|
+
];
|
|
233
|
+
for (const pattern of actionPatterns) {
|
|
234
|
+
const match = description.match(pattern);
|
|
235
|
+
if (match && match[2]) {
|
|
236
|
+
const extracted = match[2].trim();
|
|
237
|
+
return {
|
|
238
|
+
domain: extracted,
|
|
239
|
+
role: `${extracted}领域专家`,
|
|
240
|
+
focus: `请调研 ${extracted} 的核心概念、技术方案、最佳实践、常见挑战`
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// 默认:使用原始描述
|
|
245
|
+
return {
|
|
246
|
+
domain: '项目开发',
|
|
247
|
+
role: '技术顾问',
|
|
248
|
+
focus: '请调研相关技术方案、最佳实践、实现路径'
|
|
249
|
+
};
|
|
250
|
+
}
|
|
129
251
|
generateRunId() {
|
|
130
252
|
return `researcher-${Date.now().toString(36)}`;
|
|
131
253
|
}
|
|
@@ -177,6 +177,8 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
|
|
|
177
177
|
}
|
|
178
178
|
// 生成头脑风暴问题
|
|
179
179
|
const questions = generateBrainstormQuestions(taskContent, taskTitle);
|
|
180
|
+
// 检测是否涉及垂直领域
|
|
181
|
+
const domainDetection = detectVerticalDomain(taskContent);
|
|
180
182
|
// 创建会话
|
|
181
183
|
const session = {
|
|
182
184
|
status: 'brainstorming',
|
|
@@ -185,12 +187,13 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
|
|
|
185
187
|
questions,
|
|
186
188
|
answers: {},
|
|
187
189
|
insights: [],
|
|
188
|
-
designNotes: []
|
|
190
|
+
designNotes: [],
|
|
191
|
+
suggestResearch: domainDetection.isVertical ? domainDetection.domain : undefined
|
|
189
192
|
};
|
|
190
193
|
await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
|
|
191
194
|
if (options.json) {
|
|
192
195
|
// JSON 输出供 Skill 解析
|
|
193
|
-
|
|
196
|
+
const output = {
|
|
194
197
|
status: 'brainstorming',
|
|
195
198
|
message: '开始头脑风暴',
|
|
196
199
|
taskTitle,
|
|
@@ -202,11 +205,21 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
|
|
|
202
205
|
multiSelect: q.multiSelect
|
|
203
206
|
})),
|
|
204
207
|
hint: '请逐一回答问题,完成后再调用 --complete'
|
|
205
|
-
}
|
|
208
|
+
};
|
|
209
|
+
// 如果检测到垂直领域,添加建议
|
|
210
|
+
if (domainDetection.isVertical) {
|
|
211
|
+
output.suggestResearch = domainDetection.domain;
|
|
212
|
+
output.researchHint = `检测到垂直领域「${domainDetection.domain}」,建议先进行领域调研`;
|
|
213
|
+
}
|
|
214
|
+
console.log(JSON.stringify(output));
|
|
206
215
|
}
|
|
207
216
|
else {
|
|
208
217
|
console.log('\n🧠 开始头脑风暴...\n');
|
|
209
218
|
console.log(`📋 任务: ${taskTitle}\n`);
|
|
219
|
+
if (domainDetection.isVertical) {
|
|
220
|
+
console.log(`🔍 检测到垂直领域: ${domainDetection.domain}`);
|
|
221
|
+
console.log(' 建议使用 /om:research 进行领域调研\n');
|
|
222
|
+
}
|
|
210
223
|
console.log('需要探索以下问题:');
|
|
211
224
|
questions.forEach((q, i) => {
|
|
212
225
|
console.log(` ${i + 1}. ${q.question}`);
|
|
@@ -214,6 +227,37 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
|
|
|
214
227
|
console.log('\n💡 使用 /om:brainstorm 技能进行交互式问答');
|
|
215
228
|
}
|
|
216
229
|
});
|
|
230
|
+
/**
|
|
231
|
+
* 检测是否可能需要领域调研
|
|
232
|
+
* 不硬编码领域,只判断是否像垂直领域任务
|
|
233
|
+
*/
|
|
234
|
+
function detectVerticalDomain(taskContent) {
|
|
235
|
+
const lower = taskContent.toLowerCase();
|
|
236
|
+
// 检测"做X"模式 - 这是垂直领域任务的典型特征
|
|
237
|
+
const actionPatterns = [
|
|
238
|
+
/做(一个|个)(.+?)(的|app|网站|系统|平台|工具|应用|游戏|$)/,
|
|
239
|
+
/开发(一个|个)?(.+?)(系统|应用|平台|工具|游戏|$)/,
|
|
240
|
+
/构建(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
|
|
241
|
+
/build (a |an )?(.+?)(app|website|system|tool|platform|game|$)/i,
|
|
242
|
+
/create (a |an )?(.+?)(app|website|system|tool|platform|game|$)/i,
|
|
243
|
+
];
|
|
244
|
+
for (const pattern of actionPatterns) {
|
|
245
|
+
const match = taskContent.match(pattern);
|
|
246
|
+
if (match && match[2]) {
|
|
247
|
+
const extracted = match[2].trim();
|
|
248
|
+
// 如果提取的内容有意义,认为是垂直领域任务
|
|
249
|
+
if (extracted.length > 1) {
|
|
250
|
+
return { isVertical: true, domain: extracted };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// 检测是否包含"系统"、"平台"、"应用"等大词
|
|
255
|
+
const systemKeywords = ['系统', '平台', '应用', 'system', 'platform', 'app'];
|
|
256
|
+
if (systemKeywords.some(kw => lower.includes(kw))) {
|
|
257
|
+
return { isVertical: true, domain: '待分析' };
|
|
258
|
+
}
|
|
259
|
+
return { isVertical: false, domain: '' };
|
|
260
|
+
}
|
|
217
261
|
/**
|
|
218
262
|
* 根据任务内容生成头脑风暴问题
|
|
219
263
|
*/
|
|
@@ -37,6 +37,7 @@ exports.completeCommand = void 0;
|
|
|
37
37
|
// src/cli/commands/complete.ts
|
|
38
38
|
const commander_1 = require("commander");
|
|
39
39
|
const state_manager_js_1 = require("../../storage/state-manager.js");
|
|
40
|
+
const git_commit_manager_js_1 = require("../../orchestrator/git-commit-manager.js");
|
|
40
41
|
const path = __importStar(require("path"));
|
|
41
42
|
exports.completeCommand = new commander_1.Command('complete')
|
|
42
43
|
.description('标记任务完成并更新全局统计')
|
|
@@ -93,7 +94,31 @@ exports.completeCommand = new commander_1.Command('complete')
|
|
|
93
94
|
currentPhase: allDone ? 'completed' : 'execution',
|
|
94
95
|
...(allDone ? { completedAt: now } : {})
|
|
95
96
|
});
|
|
96
|
-
// 5.
|
|
97
|
+
// 5. Git 自动提交
|
|
98
|
+
if (isSuccess) {
|
|
99
|
+
const state = await stateManager.getState();
|
|
100
|
+
const gitManager = new git_commit_manager_js_1.GitCommitManager(basePath);
|
|
101
|
+
try {
|
|
102
|
+
const commitResult = await gitManager.commit({
|
|
103
|
+
taskId,
|
|
104
|
+
taskTitle: task.title,
|
|
105
|
+
runId: state.runId,
|
|
106
|
+
phase: 'develop',
|
|
107
|
+
changes: [],
|
|
108
|
+
impactScope: []
|
|
109
|
+
});
|
|
110
|
+
if (commitResult.success) {
|
|
111
|
+
console.error(`✅ Git 提交成功: ${commitResult.commitHash}`);
|
|
112
|
+
}
|
|
113
|
+
else if (commitResult.message !== 'No changes to commit') {
|
|
114
|
+
console.error(`⚠️ Git 提交跳过: ${commitResult.message || commitResult.error}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error(`⚠️ Git 提交失败: ${error}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 6. 输出结果
|
|
97
122
|
const result = {
|
|
98
123
|
taskId,
|
|
99
124
|
status: isSuccess ? 'completed' : 'failed',
|