deepfish-ai 1.0.28 → 2.0.2
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 +126 -368
- package/dist/index.js +23320 -0
- package/dist/serve/client/assets/index-DUHYC91l.js +1 -0
- package/dist/serve/client/assets/index-zcrdNLZs.css +1 -0
- package/dist/serve/client/index.html +14 -0
- package/dist/serve/pm2-server.js +21015 -0
- package/dist/serve/server/entry-server.mjs +224 -0
- package/package.json +50 -70
- package/LICENSE +0 -21
- package/README_CN.md +0 -460
- package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +0 -88
- package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +0 -45
- package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +0 -45
- package/src/AgentRobot/AgentRobotFactory/index.js +0 -48
- package/src/AgentRobot/BaseAgentRobot/Brain.js +0 -210
- package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +0 -17
- package/src/AgentRobot/BaseAgentRobot/Hand.js +0 -119
- package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
- package/src/AgentRobot/BaseAgentRobot/Logger.js +0 -114
- package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +0 -49
- package/src/AgentRobot/BaseAgentRobot/index.js +0 -266
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/AliBailian.js +0 -997
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/doc-transform.js +0 -204
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +0 -1286
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +0 -765
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +0 -736
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +0 -567
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/video.js +0 -36
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +0 -611
- package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +0 -13
- package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +0 -158
- package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +0 -768
- package/src/AgentRobot/BaseAgentRobot/tools/GenerateTools.js +0 -441
- package/src/AgentRobot/BaseAgentRobot/tools/InquirerTools.js +0 -244
- package/src/AgentRobot/BaseAgentRobot/tools/SystemTools.js +0 -263
- package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +0 -211
- package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +0 -100
- package/src/AgentRobot/BaseAgentRobot/tools/UserTool.js +0 -87
- package/src/AgentRobot/BaseAgentRobot/tools/WebTools.js +0 -257
- package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +0 -297
- package/src/AgentRobot/BaseAgentRobot/utils/AIToolManager.js +0 -131
- package/src/AgentRobot/BaseAgentRobot/utils/AgentTree.js +0 -66
- package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +0 -235
- package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +0 -236
- package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +0 -74
- package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +0 -78
- package/src/AgentRobot/BaseAgentRobot/utils/analyzeReturn.test.js +0 -104
- package/src/AgentRobot/BaseAgentRobot/utils/copilot.js +0 -117
- package/src/AgentRobot/BaseAgentRobot/utils/node-root.js +0 -138
- package/src/AgentRobot/BaseAgentRobot/utils/normal.js +0 -399
- package/src/cli/ConfigManager.js +0 -283
- package/src/cli/DefaultConfig.js +0 -98
- package/src/cli/GlobalVariable.js +0 -8
- package/src/cli/MemoryManager.js +0 -53
- package/src/cli/SkillConfigManager.js +0 -343
- package/src/cli/SkillParser.js +0 -58
- package/src/cli/ai-auth.js +0 -231
- package/src/cli/ai-config.js +0 -225
- package/src/cli/ai-memory.js +0 -22
- package/src/cli/ai-skill.js +0 -65
- package/src/cli/index.js +0 -77
- package/src/index.js +0 -54
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @Author: Roman 306863030@qq.com
|
|
3
|
-
* @Date: 2026-03-17 11:59:19
|
|
4
|
-
* @LastEditors: Roman 306863030@qq.com
|
|
5
|
-
* @LastEditTime: 2026-05-07 14:17:50
|
|
6
|
-
* @FilePath: \deepfish\src\AgentRobot\BaseAgentRobot\tools\SystemTools.js
|
|
7
|
-
* @Description: 默认扩展函数
|
|
8
|
-
* @
|
|
9
|
-
*/
|
|
10
|
-
const path = require('path')
|
|
11
|
-
const fs = require('fs-extra')
|
|
12
|
-
const dayjs = require('dayjs')
|
|
13
|
-
const iconv = require('iconv-lite')
|
|
14
|
-
const { spawnSync } = require('child_process')
|
|
15
|
-
const { detectEncoding, analyzeReturn } = require('../utils/normal.js')
|
|
16
|
-
const aiConsole = require('../utils/aiConsole.js')
|
|
17
|
-
|
|
18
|
-
// 执行系统命令
|
|
19
|
-
// 执行系统命令(全平台兼容:Windows/PowerShell/CentOS)
|
|
20
|
-
function executeCommand(command, timeout = -1) {
|
|
21
|
-
aiConsole.logSuccess(
|
|
22
|
-
`Executing system command: ${command}; ${timeout > 0 ? `Timeout: ${timeout}ms` : 'No timeout limit'}`,
|
|
23
|
-
)
|
|
24
|
-
try {
|
|
25
|
-
const result = spawnSync(command, {
|
|
26
|
-
cwd: process.cwd(),
|
|
27
|
-
stdio: 'pipe',
|
|
28
|
-
shell: true,
|
|
29
|
-
encoding: 'buffer',
|
|
30
|
-
windowsHide: true,
|
|
31
|
-
argv0: 'deepfish-shell',
|
|
32
|
-
timeout: timeout > 0 ? timeout : undefined,
|
|
33
|
-
})
|
|
34
|
-
let targetEncoding = this.agentRobot.config?.encoding
|
|
35
|
-
if (!targetEncoding || targetEncoding === 'auto') {
|
|
36
|
-
targetEncoding = detectEncoding(result.stdout || result.stderr)
|
|
37
|
-
}
|
|
38
|
-
const stdout = iconv.decode(result.stdout, targetEncoding)
|
|
39
|
-
const stderr = iconv.decode(result.stderr, targetEncoding)
|
|
40
|
-
const code = result.status
|
|
41
|
-
if (stderr && !stderr.trim().startsWith('WARNING')) {
|
|
42
|
-
const error = new Error(`Command failed (code ${code}): ${stderr.trim()}`)
|
|
43
|
-
aiConsole.logError(`Execute error: ${error.message}`)
|
|
44
|
-
return `Execute error: ${error.message}`
|
|
45
|
-
}
|
|
46
|
-
aiConsole.logSuccess(`${stdout}\nCommand executed successfully`)
|
|
47
|
-
return stdout || 'Command executed successfully'
|
|
48
|
-
} catch (decodeError) {
|
|
49
|
-
aiConsole.logError(`Encoding convert error: ${decodeError.message}`)
|
|
50
|
-
return `Failed to parse command output: ${decodeError.message}`
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 请求ai服务
|
|
55
|
-
async function requestAI(
|
|
56
|
-
systemDescription,
|
|
57
|
-
prompt,
|
|
58
|
-
temperature = this.agentRobot.opt.aiConfig.temperature,
|
|
59
|
-
) {
|
|
60
|
-
aiConsole.logSuccess(`Requesting AI`)
|
|
61
|
-
if (
|
|
62
|
-
typeof systemDescription === 'object' &&
|
|
63
|
-
systemDescription.systemDescription
|
|
64
|
-
) {
|
|
65
|
-
prompt = systemDescription.prompt || prompt || ''
|
|
66
|
-
systemDescription = systemDescription.systemDescription || ''
|
|
67
|
-
}
|
|
68
|
-
try {
|
|
69
|
-
const response = await this.agentRobot.brain.think(
|
|
70
|
-
systemDescription,
|
|
71
|
-
prompt,
|
|
72
|
-
temperature,
|
|
73
|
-
)
|
|
74
|
-
return response
|
|
75
|
-
} catch (error) {
|
|
76
|
-
aiConsole.logError(`Error executing AI function: ${error.message}`)
|
|
77
|
-
throw error
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// 执行js代码
|
|
82
|
-
async function executeJSCode(code) {
|
|
83
|
-
aiConsole.logSuccess('Executing JavaScript code: ')
|
|
84
|
-
aiConsole.logSuccess(code)
|
|
85
|
-
// 校验代码片段中是否存在顶层 return,避免仅按最后一行判断导致误判。
|
|
86
|
-
const { hasReturnValue } = analyzeReturn(code)
|
|
87
|
-
if (!hasReturnValue) {
|
|
88
|
-
const error = new Error('The code must contain a return value.')
|
|
89
|
-
throw error
|
|
90
|
-
}
|
|
91
|
-
try {
|
|
92
|
-
const functions = this.agentRobot.toolManager.functions
|
|
93
|
-
const Func = new Function(
|
|
94
|
-
'Tools',
|
|
95
|
-
'require',
|
|
96
|
-
`return (async () => {
|
|
97
|
-
this.logMessages = []
|
|
98
|
-
this.Tools = Tools
|
|
99
|
-
const originalLog = console.log
|
|
100
|
-
const newLog = function () {
|
|
101
|
-
originalLog.apply(console, arguments)
|
|
102
|
-
this.logMessages.push(Array.from(arguments).join(' '))
|
|
103
|
-
}
|
|
104
|
-
console.log = newLog.bind(this)
|
|
105
|
-
async function __main() {
|
|
106
|
-
${code}
|
|
107
|
-
}
|
|
108
|
-
const result = await __main()
|
|
109
|
-
console.log = originalLog
|
|
110
|
-
return result || this.logMessages.join('\\n')
|
|
111
|
-
})()`,
|
|
112
|
-
)
|
|
113
|
-
const originalRequire = require
|
|
114
|
-
const newRequire = (modulePath) => {
|
|
115
|
-
if (modulePath.startsWith('./')) {
|
|
116
|
-
const resolvedPath = path.resolve(process.cwd(), modulePath)
|
|
117
|
-
return originalRequire(resolvedPath)
|
|
118
|
-
}
|
|
119
|
-
return originalRequire(modulePath)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const result = await Func(functions, newRequire)
|
|
123
|
-
return result || ''
|
|
124
|
-
} catch (error) {
|
|
125
|
-
aiConsole.logError(`Error executing code: ${error.stack}`)
|
|
126
|
-
throw error
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// 获取当前系统时间
|
|
131
|
-
function getCurrentTime() {
|
|
132
|
-
const now = dayjs()
|
|
133
|
-
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'unknown'
|
|
134
|
-
return `Current system time: ${now.format('YYYY-MM-DD HH:mm:ss')} | ISO: ${now.toISOString()} | Timezone: ${timezone}`
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 了解自己
|
|
138
|
-
function getSelfInfo() {
|
|
139
|
-
// 返回自己的代码路径、package.json路径、readme路径等基本信息,供AI有选择的了解自己,回答用户的问题
|
|
140
|
-
const homeDir = path.resolve(__dirname, '../../../../')
|
|
141
|
-
const packageJson = fs.readJSONSync(path.resolve(homeDir, 'package.json'))
|
|
142
|
-
return {
|
|
143
|
-
config: {
|
|
144
|
-
description: 'DeepFish AI程序代码配置项',
|
|
145
|
-
value: this.agentRobot.config,
|
|
146
|
-
},
|
|
147
|
-
codePath: {
|
|
148
|
-
description: 'DeepFish AI程序代码路径',
|
|
149
|
-
value: homeDir,
|
|
150
|
-
},
|
|
151
|
-
packageJsonPath: {
|
|
152
|
-
description: 'DeepFish AI程序package.json文件路径',
|
|
153
|
-
value: path.resolve(homeDir, 'package.json'),
|
|
154
|
-
},
|
|
155
|
-
readmeCNPath: {
|
|
156
|
-
description: 'DeepFish AI程序中文文档路径',
|
|
157
|
-
value: path.resolve(homeDir, 'README_CN.md'),
|
|
158
|
-
},
|
|
159
|
-
readmeENPath: {
|
|
160
|
-
description: 'DeepFish AI程序英文文档路径',
|
|
161
|
-
value: path.resolve(homeDir, 'README.md'),
|
|
162
|
-
},
|
|
163
|
-
version: {
|
|
164
|
-
description: 'DeepFish AI程序版本',
|
|
165
|
-
value: 'v' + packageJson.version,
|
|
166
|
-
},
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const descriptions = [
|
|
171
|
-
{
|
|
172
|
-
type: 'function',
|
|
173
|
-
function: {
|
|
174
|
-
name: 'executeCommand',
|
|
175
|
-
description:
|
|
176
|
-
'执行系统命令,返回执行结果。适用于运行shell命令、系统工具等。command为需要执行的系统命令字符串,如"ls -l"; timeout为命令执行的超时时间,单位为毫秒,-1表示不限制超时时间, 默认值为-1。注意:如果执行多条命令,且需要保持会话,使用命令链的方式执行。命令执行失败时会抛出错误,成功时返回命令执行结果字符串或"System command executed successfully"。',
|
|
177
|
-
parameters: {
|
|
178
|
-
type: 'object',
|
|
179
|
-
properties: {
|
|
180
|
-
command: { type: 'string' },
|
|
181
|
-
timeout: { type: 'number' },
|
|
182
|
-
},
|
|
183
|
-
required: ['command'],
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
type: 'function',
|
|
189
|
-
function: {
|
|
190
|
-
name: 'requestAI',
|
|
191
|
-
description:
|
|
192
|
-
'请求AI服务处理简单任务,如随机生成一段话、翻译文本、数学计算、代码分析、知识检索等。通过systemDescription参数指定AI的行为和限制,prompt参数输入任务描述, temperature参数指定AI的温度(0-2之间的浮点数,默认为用户配置)。返回AI处理后的结果字符串,执行失败时会抛出错误。',
|
|
193
|
-
parameters: {
|
|
194
|
-
type: 'object',
|
|
195
|
-
properties: {
|
|
196
|
-
systemDescription: { type: 'string' },
|
|
197
|
-
prompt: { type: 'string' },
|
|
198
|
-
temperature: { type: 'number' },
|
|
199
|
-
},
|
|
200
|
-
required: ['systemDescription', 'prompt'],
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
type: 'function',
|
|
206
|
-
function: {
|
|
207
|
-
name: 'executeJSCode',
|
|
208
|
-
description:
|
|
209
|
-
'执行JavaScript代码,返回代码执行结果。代码中可通过Tools命名空间直接调用其他工具函数(如await Tools.createFile(),注意:不需要使用require引入),Tools中引入了一些常用库可直接调用(Tools.fs="fs-extra", Tools.dayjs="dayjs", Tools.axios="axios", Tools.lodash="lodash", Tools.echarts="echarts", Tools.canvas="canvas" Tools.cheerio="cheerio" Tools.puppeteer="puppeteer"),支持引入自定义模块(需使用绝对路径)。注意:1.代码中不要使用__dirname获取当前目录,请使用path.resolve(".")来获取当前目录。2.执行失败时会抛出错误,成功时返回代码执行结果或空字符串。3.使用require(module_path)函数引入自定义模块,module_path为模块路径字符串,支持相对路径(如"./myModule.js")和绝对路径,返回引入的模块内容。4.执行主函数必须使用return返回,如return main()',
|
|
210
|
-
parameters: {
|
|
211
|
-
type: 'object',
|
|
212
|
-
properties: {
|
|
213
|
-
code: { type: 'string' },
|
|
214
|
-
},
|
|
215
|
-
required: ['code'],
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
type: 'function',
|
|
221
|
-
function: {
|
|
222
|
-
name: 'getCurrentTime',
|
|
223
|
-
description:
|
|
224
|
-
'获取当前系统时间,返回本地时间、ISO时间和时区信息。适用于需要在任务中使用当前时间戳或进行时间记录的场景。',
|
|
225
|
-
parameters: {
|
|
226
|
-
type: 'object',
|
|
227
|
-
properties: {},
|
|
228
|
-
required: [],
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
type: 'function',
|
|
234
|
-
function: {
|
|
235
|
-
name: 'getSelfInfo',
|
|
236
|
-
description:
|
|
237
|
-
'获取DeepFish AI程序的基本信息、命令行等,供AI有选择的了解自己,回答用户的问题。',
|
|
238
|
-
parameters: {
|
|
239
|
-
type: 'object',
|
|
240
|
-
properties: {},
|
|
241
|
-
required: [],
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
]
|
|
246
|
-
const functions = {
|
|
247
|
-
executeCommand,
|
|
248
|
-
requestAI,
|
|
249
|
-
executeJSCode,
|
|
250
|
-
getCurrentTime,
|
|
251
|
-
getSelfInfo,
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const SystemTool = {
|
|
255
|
-
name: 'SystemTool',
|
|
256
|
-
description:
|
|
257
|
-
'提供系统命令执行、AI请求、JS代码执行、扩展文件生成规则、AI配置管理、Tool加载执行等核心系统功能',
|
|
258
|
-
descriptions,
|
|
259
|
-
functions,
|
|
260
|
-
isSystem: true
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
module.exports = SystemTool
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
|
|
4
|
-
// 生成/创建任务列表
|
|
5
|
-
function createTaskList(userPrompt = '') {
|
|
6
|
-
const prompt = `在当前目录创建一个任务列表文件 tmp_tasklist_${this.agentRobot.id}.json;创建一个记录用户任务目标的文件,tmp_task_goal_${this.agentRobot.id}.md。
|
|
7
|
-
tmp_tasklist_${this.agentRobot.id}.json文件创建规则:
|
|
8
|
-
1. 文件内容必须是 JSON 数组;
|
|
9
|
-
2. 每个数组元素是一个任务对象,字段至少包含:
|
|
10
|
-
- id: 任务唯一标识(字符串或数字)
|
|
11
|
-
- name: 任务名称
|
|
12
|
-
- description: 任务的详细说明
|
|
13
|
-
- status: 任务状态("todo" | "doing" | "done")
|
|
14
|
-
- createdAt: 创建时间(ISO 字符串)
|
|
15
|
-
- finishedAt: 完成时间(未完成可为 null)
|
|
16
|
-
- note: 备注(可为空字符串)
|
|
17
|
-
3. 任务需尽量原子化、可执行。
|
|
18
|
-
|
|
19
|
-
输出要求:
|
|
20
|
-
- 仅输出可写入的合法 JSON 内容,不要输出解释文字。
|
|
21
|
-
|
|
22
|
-
tmp_task_goal_${this.agentRobot.id}.md文件为以下内容:
|
|
23
|
-
${userPrompt}
|
|
24
|
-
`
|
|
25
|
-
return this.Tools.createSubAgent(prompt)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// 执行任务列表
|
|
29
|
-
function executeTaskList(userPrompt = '') {
|
|
30
|
-
const prompt = `你需要执行当前目录下的 tmp_tasklist_${this.agentRobot.id}.json。
|
|
31
|
-
|
|
32
|
-
执行规则:
|
|
33
|
-
1. 读取任务列表,仅处理 status 为 "todo" 或 "doing" 的任务;
|
|
34
|
-
2. 每次只执行一个子任务,按列表顺序执行;
|
|
35
|
-
3. 执行前将当前任务状态更新为 "doing" 并保存;
|
|
36
|
-
4. 执行前需要阅读 tmp_task_goal_${this.agentRobot.id}.md 文件,了解用户的整体需求;
|
|
37
|
-
5. 子任务执行成功后更新为 "done",并写入 finishedAt(ISO 时间);
|
|
38
|
-
6. 子任务失败时保留为 "doing" 或回退为 "todo",并在 note 记录失败原因摘要;
|
|
39
|
-
7. 每完成一个子任务都必须立刻写回 tmp_tasklist_${this.agentRobot.id}.json;
|
|
40
|
-
8. 当全部任务为 "done" 时,明确输出“任务列表执行完成”。
|
|
41
|
-
9. 尽量交给子任务完成,主任务流不要参与过多思考和执行细节。
|
|
42
|
-
10. 告诉子任务任务列表的文件名称 tmp_tasklist_${this.agentRobot.id}.json。
|
|
43
|
-
11. 任务全部执行完成后,删除 tmp_tasklist_${this.agentRobot.id}.json 文件和 tmp_task_goal_${this.agentRobot.id}.md 文件。
|
|
44
|
-
|
|
45
|
-
输出要求:
|
|
46
|
-
- 输出当前执行的任务 id/name、结果状态、下一步计划;
|
|
47
|
-
- 不要跳过状态更新与落盘步骤。
|
|
48
|
-
|
|
49
|
-
工具函数:
|
|
50
|
-
- readTaskList: 读取任务列表文件
|
|
51
|
-
- updateTaskList: 更新任务列表文件
|
|
52
|
-
- executeSubTaskFromTaskList: 执行单个子任务目标
|
|
53
|
-
|
|
54
|
-
以下是用户的原始需求:
|
|
55
|
-
${userPrompt}
|
|
56
|
-
`
|
|
57
|
-
return this.Tools.createSubAgent(prompt)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 读取任务列表
|
|
61
|
-
function readTaskList(taskListPath) {
|
|
62
|
-
return (
|
|
63
|
-
fs.readFileSync(
|
|
64
|
-
taskListPath ||
|
|
65
|
-
path.join(process.cwd(), `tmp_tasklist_${this.agentRobot.id}.json`),
|
|
66
|
-
{ encoding: 'utf-8' },
|
|
67
|
-
) || '[]'
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// 更新任务列表
|
|
72
|
-
function updateTaskList(taskListPath, list) {
|
|
73
|
-
try {
|
|
74
|
-
fs.writeFileSync(
|
|
75
|
-
taskListPath ||
|
|
76
|
-
path.join(process.cwd(), `tmp_tasklist_${this.agentRobot.id}.json`),
|
|
77
|
-
JSON.stringify(list, null, 2),
|
|
78
|
-
{ encoding: 'utf-8' },
|
|
79
|
-
)
|
|
80
|
-
return true
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return { error: error.message }
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// 从任务列表执行子任务
|
|
87
|
-
function executeSubTaskFromTaskList(subTaskGoalPrompt = '') {
|
|
88
|
-
return this.Tools.createSubAgent(subTaskGoalPrompt)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const descriptions = [
|
|
92
|
-
{
|
|
93
|
-
type: 'function',
|
|
94
|
-
function: {
|
|
95
|
-
name: 'createTaskList',
|
|
96
|
-
description:
|
|
97
|
-
'创建一个任务列表文件,根据用户的原始任务目标生成一个合法的任务列表。返回创建结果与状态信息。',
|
|
98
|
-
parameters: {
|
|
99
|
-
type: 'object',
|
|
100
|
-
properties: {
|
|
101
|
-
userPrompt: {
|
|
102
|
-
type: 'string',
|
|
103
|
-
description: '用户的原始任务目标,用于生成任务列表',
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
required: ['userPrompt'],
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
type: 'function',
|
|
112
|
-
function: {
|
|
113
|
-
name: 'executeTaskList',
|
|
114
|
-
description:
|
|
115
|
-
'根据任务列表文件执行任务,按照预定义的执行规则处理每个任务的状态更新与结果记录。返回执行结果与状态信息。',
|
|
116
|
-
parameters: {
|
|
117
|
-
type: 'object',
|
|
118
|
-
properties: {
|
|
119
|
-
userPrompt: {
|
|
120
|
-
type: 'string',
|
|
121
|
-
description: '用户的原始需求,用于约束和校验任务执行方向',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
required: ['userPrompt'],
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
type: 'function',
|
|
130
|
-
function: {
|
|
131
|
-
name: 'readTaskList',
|
|
132
|
-
description:
|
|
133
|
-
'读取任务列表并返回任务数组。读取以tmp_tasklist_开头的json文件,文件不存在或读取失败时返回空数组。',
|
|
134
|
-
parameters: {
|
|
135
|
-
type: 'object',
|
|
136
|
-
properties: {
|
|
137
|
-
taskListPath: {
|
|
138
|
-
type: 'string',
|
|
139
|
-
description:
|
|
140
|
-
'任务列表文件路径,以tmp_tasklist_开头的json文件',
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
required: ['taskListPath'],
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
type: 'function',
|
|
149
|
-
function: {
|
|
150
|
-
name: 'updateTaskList',
|
|
151
|
-
description:
|
|
152
|
-
'将完整任务数组写入任务列表文件。用于任务状态、备注、时间字段的持久化更新。返回true表示写入成功,写入失败会抛出错误。',
|
|
153
|
-
parameters: {
|
|
154
|
-
type: 'object',
|
|
155
|
-
properties: {
|
|
156
|
-
taskListPath: {
|
|
157
|
-
type: 'string',
|
|
158
|
-
description:
|
|
159
|
-
'任务列表文件路径,以tmp_tasklist_开头的json文件',
|
|
160
|
-
},
|
|
161
|
-
list: {
|
|
162
|
-
type: 'array',
|
|
163
|
-
description: '任务对象数组',
|
|
164
|
-
items: {
|
|
165
|
-
type: 'object',
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
required: ['taskListPath', 'list'],
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
type: 'function',
|
|
175
|
-
function: {
|
|
176
|
-
name: 'executeSubTaskFromTaskList',
|
|
177
|
-
description:
|
|
178
|
-
'启动子任务工作流执行单个子任务目标。subTaskGoalPrompt为子任务目标的提示词,传入“任务列表文件名称+当前进度+当前任务目标详细说明”。',
|
|
179
|
-
parameters: {
|
|
180
|
-
type: 'object',
|
|
181
|
-
properties: {
|
|
182
|
-
subTaskGoalPrompt: {
|
|
183
|
-
type: 'string',
|
|
184
|
-
description:
|
|
185
|
-
'子任务目标的详细描述,传入“任务列表文件名称+当前进度+当前任务目标详细说明”',
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
required: ['subTaskGoalPrompt'],
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
]
|
|
193
|
-
|
|
194
|
-
const functions = {
|
|
195
|
-
createTaskList,
|
|
196
|
-
executeTaskList,
|
|
197
|
-
readTaskList,
|
|
198
|
-
updateTaskList,
|
|
199
|
-
executeSubTaskFromTaskList,
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const TaskTools = {
|
|
203
|
-
name: 'TaskTools',
|
|
204
|
-
extensionDescription:
|
|
205
|
-
'提供任务列表创建规则、执行规则、任务读写与子任务执行能力,支持基于tasklist的可追踪拆分执行流程',
|
|
206
|
-
descriptions,
|
|
207
|
-
functions,
|
|
208
|
-
isSystem: true
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
module.exports = TaskTools
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// 执行测试任务
|
|
2
|
-
function executeTestTask(subGoalPrompt = "") {
|
|
3
|
-
// 调用子工作流完成目标
|
|
4
|
-
return this.Tools.createSubAgent(subGoalPrompt)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// 生成测试任务
|
|
8
|
-
function generateTestTaskRule(goal) {
|
|
9
|
-
return `
|
|
10
|
-
你是资深测试工程师。用户测试任务目标如下:${goal}
|
|
11
|
-
|
|
12
|
-
请在当前目录下生成一个 Markdown 格式的“程序功能测试说明文档”,并严格遵循以下要求:
|
|
13
|
-
1. 文档标题
|
|
14
|
-
- 一级标题固定格式:# xxx测试任务
|
|
15
|
-
- 其中“xxx”必须与用户提供的测试任务名称保持一致,不得改写。
|
|
16
|
-
2. 先分析再输出
|
|
17
|
-
- 在正文最前面先给出“测试范围与模块拆分”小节,明确:
|
|
18
|
-
- 待测功能模块
|
|
19
|
-
- 核心测试点
|
|
20
|
-
- 不在本轮测试范围的内容(如有)
|
|
21
|
-
- 然后再输出详细测试用例。
|
|
22
|
-
3. 测试用例组织方式
|
|
23
|
-
- 按“功能模块”分组(每个模块一个二级标题)。
|
|
24
|
-
- 模块内按优先级排序:P0 > P1 > P2。
|
|
25
|
-
- 每个用例必须有唯一编号,建议格式:TC-模块缩写-序号(如 TC-LOGIN-001)。
|
|
26
|
-
4. 每条测试用例必须包含以下字段(缺一不可)
|
|
27
|
-
- 用例编号
|
|
28
|
-
- 所属模块
|
|
29
|
-
- 优先级(P0/P1/P2)
|
|
30
|
-
- 测试场景
|
|
31
|
-
- 前置条件
|
|
32
|
-
- 测试数据
|
|
33
|
-
- 操作步骤(可逐条执行、无歧义、可落地)
|
|
34
|
-
- 预期结果(与步骤一一对应、可验证)
|
|
35
|
-
5. 覆盖性要求
|
|
36
|
-
- 必须覆盖:主流程、异常流程、边界场景。
|
|
37
|
-
- 不得遗漏核心功能,不得加入与目标无关的测试内容。
|
|
38
|
-
- 期望结果必须具体到可观察的页面状态、返回结果、数据变化或提示信息。
|
|
39
|
-
6. 输出格式要求
|
|
40
|
-
- 全文仅输出 Markdown 正文,不要输出解释性前言。
|
|
41
|
-
- 标题层级清晰:文档标题为一级、模块为二级、测试用例为三级(或有序列表)。
|
|
42
|
-
- 文档末尾增加“测试执行任务清单”章节,使用可勾选任务列表(- [ ])逐条列出所有测试用例,便于执行与追踪。
|
|
43
|
-
- 文档末尾增加“测试结果评估”章节,输出测试结果和未通过的测试用例,并评估评估测试结果的有效性、全面性、及时性。
|
|
44
|
-
|
|
45
|
-
请根据以上要求直接生成完整测试文档。
|
|
46
|
-
`}
|
|
47
|
-
|
|
48
|
-
const descriptions = [
|
|
49
|
-
{
|
|
50
|
-
type: "function",
|
|
51
|
-
function: {
|
|
52
|
-
name: "generateTestTaskRule",
|
|
53
|
-
description:
|
|
54
|
-
"根据用户提供的程序功能测试目标,生成一份标准化的Markdown格式功能测试说明文档的规则提示词。返回的提示词将指导AI生成包含完整测试用例(测试步骤、期望结果、用例编号)的测试文档。适用于用户需要对程序进行功能测试等场景。",
|
|
55
|
-
parameters: {
|
|
56
|
-
type: "object",
|
|
57
|
-
properties: {
|
|
58
|
-
goal: {
|
|
59
|
-
type: "string",
|
|
60
|
-
description: "程序功能测试目标描述,需明确待测试的功能模块、测试范围和测试重点",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
required: ["goal"],
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
type: "function",
|
|
69
|
-
function: {
|
|
70
|
-
name: "executeTestTask",
|
|
71
|
-
description:
|
|
72
|
-
"执行测试任务,启动一个专用的AI子工作流来完成指定的某一项测试目标。子工作流将根据测试任务描述,自动执行测试步骤并验证测试结果。适用于需要AI自动化执行功能测试的场景。",
|
|
73
|
-
parameters: {
|
|
74
|
-
type: "object",
|
|
75
|
-
properties: {
|
|
76
|
-
subGoalPrompt: {
|
|
77
|
-
type: "string",
|
|
78
|
-
description: "测试子工作流需要完成的目标描述,描述具体的测试任务内容",
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
required: ["subGoalPrompt"],
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
const functions = {
|
|
88
|
-
executeTestTask,
|
|
89
|
-
generateTestTaskRule,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const TestTools = {
|
|
93
|
-
name: 'TestTools',
|
|
94
|
-
extensionDescription: "提供程序功能测试任务的生成和执行功能,支持自动化测试工作流",
|
|
95
|
-
descriptions,
|
|
96
|
-
functions,
|
|
97
|
-
isSystem: true
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
module.exports = TestTools
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra')
|
|
2
|
-
|
|
3
|
-
function readUserInfo() {
|
|
4
|
-
const userInfoFilePath = this.agentRobot.userInfoFilePath
|
|
5
|
-
if (!fs.existsSync(userInfoFilePath)) {
|
|
6
|
-
return '暂无用户信息记录';
|
|
7
|
-
}
|
|
8
|
-
return fs.readFileSync(userInfoFilePath, 'utf-8') || '暂无用户信息记录'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async function writeUserInfo(info) {
|
|
12
|
-
const userInfoFilePath = this.agentRobot.userInfoFilePath
|
|
13
|
-
const oldUserInfo = this.Tools.readUserInfo()
|
|
14
|
-
const normalizedOldUserInfo = oldUserInfo === '暂无用户信息记录' ? '' : oldUserInfo
|
|
15
|
-
let mergedInfo = (info || '').trim()
|
|
16
|
-
|
|
17
|
-
const systemDescription = `你是用户信息整理助手。请将已有用户信息与新增用户信息合并为一份Markdown文本,只保留非敏感信息并去重,优先保留更新、更准确的信息。记录内容应简洁、可检索、可复用。`
|
|
18
|
-
const prompt = `请整合以下两部分用户信息,输出最终Markdown内容(仅输出正文,不要解释):\n\n【已有用户信息】\n${normalizedOldUserInfo || '(空)'}\n\n【新增用户信息】\n${mergedInfo || '(空)'}\n\n要求:\n1. 仅保留非敏感信息。\n2. 相同信息去重,冲突时以新增信息为准。\n3. 不确定内容标注“待确认”。\n4. 按“信息类型: 信息内容”格式整理。`
|
|
19
|
-
|
|
20
|
-
if (this.Tools.requestAI && mergedInfo) {
|
|
21
|
-
try {
|
|
22
|
-
const aiMerged = await this.Tools.requestAI(systemDescription, prompt, 0.2)
|
|
23
|
-
if (typeof aiMerged === 'string' && aiMerged.trim()) {
|
|
24
|
-
mergedInfo = aiMerged.trim()
|
|
25
|
-
}
|
|
26
|
-
} catch (error) {
|
|
27
|
-
// AI合并失败时回退为直接写入新增信息,保证写入流程可用
|
|
28
|
-
mergedInfo = normalizedOldUserInfo + '\n' + info
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
fs.writeFileSync(userInfoFilePath, mergedInfo, 'utf-8')
|
|
32
|
-
// 更新系统提示词中的用户信息区块
|
|
33
|
-
this.agentRobot.systemPrompt = this.agentRobot.systemPrompt.replace(
|
|
34
|
-
/----user info start----([\s\S]*?)----user info end----/,
|
|
35
|
-
`----user info start----\n${mergedInfo}\n----user info end----`
|
|
36
|
-
)
|
|
37
|
-
return true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const descriptions = [
|
|
41
|
-
{
|
|
42
|
-
type: 'function',
|
|
43
|
-
function: {
|
|
44
|
-
name: 'writeUserInfo',
|
|
45
|
-
description: '写入用户信息内容。记录规则:1. 仅记录非敏感信息:个人基础信息(如姓名、年龄、职业、兴趣、性格特征)、操作习惯、代码习惯、阅读习惯、常用目录、文档收藏夹目录等。2. 禁止记录敏感信息:密码、密钥、令牌、身份证号、银行卡号、详细住址、联系方式、精确定位、财务/医疗等个人隐私数据。3. 已有同类信息时优先更新,不重复堆叠;存在不确定信息时需标注“待确认”,不得臆测补全。4. 记录内容应简洁、可检索、可复用,避免写入一次性上下文和与任务无关的噪音信息。5. 无需询问,自动写入文件。6. 使用markdown文件格式记录,按照“信息类型: 信息内容”的格式进行记录,如“兴趣: 阅读、旅行、编程”。7. 只记录当前用户信息中没有的内容,避免重复记录相同信息。',
|
|
46
|
-
parameters: {
|
|
47
|
-
type: 'object',
|
|
48
|
-
properties: {
|
|
49
|
-
info: {
|
|
50
|
-
type: 'string',
|
|
51
|
-
description: '当前用户信息中没有的内容',
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
required: ['info'],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
type: 'function',
|
|
60
|
-
function: {
|
|
61
|
-
name: 'readUserInfo',
|
|
62
|
-
description: '读取已记录的用户信息内容。如果文件不存在,则返回 "暂无用户信息记录"。',
|
|
63
|
-
parameters: {
|
|
64
|
-
type: 'object',
|
|
65
|
-
properties: {},
|
|
66
|
-
required: [],
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
const functions = {
|
|
74
|
-
readUserInfo,
|
|
75
|
-
writeUserInfo,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const UserTool = {
|
|
79
|
-
name: 'UserTool',
|
|
80
|
-
description: '提供用户信息读写功能,用于维护用户偏好、习惯和常用目录信息',
|
|
81
|
-
platform: 'all',
|
|
82
|
-
descriptions,
|
|
83
|
-
functions,
|
|
84
|
-
isSystem: true
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
module.exports = UserTool
|