deepfish-ai 2.0.11 → 2.0.12
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 +13 -3
- package/dist/index.js +256 -128
- package/dist/serve/pm2-server.js +14 -8
- package/dist/{generate-skill.md → skills/generate-skill.md} +1 -1
- package/dist/{generate-tool.md → skills/generate-tool.md} +1 -1
- package/dist/skills/planning-do.md +90 -0
- package/package.json +2 -2
- /package/dist/{view-learn-cache.md → skills/view-learn-cache.md} +0 -0
package/README.md
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
- [工具管理](#工具管理)
|
|
46
46
|
- [会话管理](#会话管理)
|
|
47
47
|
- [任务管理](#任务管理)
|
|
48
|
+
- [长任务规划](#长任务规划)
|
|
48
49
|
- [MCP 管理](#mcp-管理)
|
|
49
50
|
- [服务管理](#服务管理)
|
|
50
51
|
- [缓存管理(AI自我学习的缓存)](#缓存管理ai自我学习的缓存)
|
|
@@ -183,11 +184,20 @@ ai "我刚问了一个什么问题"
|
|
|
183
184
|
| `ai tasks del <index>` | 删除指定任务 |
|
|
184
185
|
| `ai tasks clear` | 清除所有任务 |
|
|
185
186
|
|
|
187
|
+
### 长任务规划
|
|
188
|
+
|
|
189
|
+
| 命令 | 说明 |
|
|
190
|
+
| ------------------------- | ------------------------------------------ |
|
|
191
|
+
| `ai plan-do <任务描述>` | 将复杂任务拆解为子任务并逐步执行完成 |
|
|
192
|
+
|
|
186
193
|
### MCP 管理
|
|
187
194
|
|
|
188
|
-
| 命令
|
|
189
|
-
|
|
|
190
|
-
| `ai mcp
|
|
195
|
+
| 命令 | 说明 |
|
|
196
|
+
| --------------------------------- | ---------------- |
|
|
197
|
+
| `ai mcp ls` | 列出所有 MCP 服务器 |
|
|
198
|
+
| `ai mcp edit` | 编辑 MCP 配置 |
|
|
199
|
+
| `ai mcp enable <name\|index>` | 启用 MCP 服务器 |
|
|
200
|
+
| `ai mcp disable <name\|index>` | 禁用 MCP 服务器 |
|
|
191
201
|
|
|
192
202
|
### 服务管理
|
|
193
203
|
|
package/dist/index.js
CHANGED
|
@@ -8403,10 +8403,10 @@ var require_lib = __commonJS({
|
|
|
8403
8403
|
exports2.analyse = analyse;
|
|
8404
8404
|
var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
|
|
8405
8405
|
let fd;
|
|
8406
|
-
const
|
|
8406
|
+
const fs26 = (0, node_1.default)();
|
|
8407
8407
|
const handler = (err, buffer) => {
|
|
8408
8408
|
if (fd) {
|
|
8409
|
-
|
|
8409
|
+
fs26.closeSync(fd);
|
|
8410
8410
|
}
|
|
8411
8411
|
if (err) {
|
|
8412
8412
|
reject(err);
|
|
@@ -8418,9 +8418,9 @@ var require_lib = __commonJS({
|
|
|
8418
8418
|
};
|
|
8419
8419
|
const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
|
|
8420
8420
|
if (sampleSize > 0) {
|
|
8421
|
-
fd =
|
|
8421
|
+
fd = fs26.openSync(filepath, "r");
|
|
8422
8422
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
8423
|
-
|
|
8423
|
+
fs26.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
|
|
8424
8424
|
if (err) {
|
|
8425
8425
|
handler(err, null);
|
|
8426
8426
|
} else {
|
|
@@ -8432,22 +8432,22 @@ var require_lib = __commonJS({
|
|
|
8432
8432
|
});
|
|
8433
8433
|
return;
|
|
8434
8434
|
}
|
|
8435
|
-
|
|
8435
|
+
fs26.readFile(filepath, handler);
|
|
8436
8436
|
});
|
|
8437
8437
|
exports2.detectFile = detectFile;
|
|
8438
8438
|
var detectFileSync = (filepath, opts = {}) => {
|
|
8439
|
-
const
|
|
8439
|
+
const fs26 = (0, node_1.default)();
|
|
8440
8440
|
if (opts && opts.sampleSize) {
|
|
8441
|
-
const fd =
|
|
8441
|
+
const fd = fs26.openSync(filepath, "r");
|
|
8442
8442
|
let sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
8443
|
-
const bytesRead =
|
|
8443
|
+
const bytesRead = fs26.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
|
|
8444
8444
|
if (bytesRead < opts.sampleSize) {
|
|
8445
8445
|
sample = sample.subarray(0, bytesRead);
|
|
8446
8446
|
}
|
|
8447
|
-
|
|
8447
|
+
fs26.closeSync(fd);
|
|
8448
8448
|
return (0, exports2.detect)(sample);
|
|
8449
8449
|
}
|
|
8450
|
-
return (0, exports2.detect)(
|
|
8450
|
+
return (0, exports2.detect)(fs26.readFileSync(filepath));
|
|
8451
8451
|
};
|
|
8452
8452
|
exports2.detectFileSync = detectFileSync;
|
|
8453
8453
|
exports2.default = {
|
|
@@ -10564,10 +10564,10 @@ function mergeDefs(...defs) {
|
|
|
10564
10564
|
function cloneDef(schema) {
|
|
10565
10565
|
return mergeDefs(schema._zod.def);
|
|
10566
10566
|
}
|
|
10567
|
-
function getElementAtPath(obj,
|
|
10568
|
-
if (!
|
|
10567
|
+
function getElementAtPath(obj, path24) {
|
|
10568
|
+
if (!path24)
|
|
10569
10569
|
return obj;
|
|
10570
|
-
return
|
|
10570
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
10571
10571
|
}
|
|
10572
10572
|
function promiseAllObject(promisesObj) {
|
|
10573
10573
|
const keys = Object.keys(promisesObj);
|
|
@@ -10976,11 +10976,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
10976
10976
|
}
|
|
10977
10977
|
return false;
|
|
10978
10978
|
}
|
|
10979
|
-
function prefixIssues(
|
|
10979
|
+
function prefixIssues(path24, issues) {
|
|
10980
10980
|
return issues.map((iss) => {
|
|
10981
10981
|
var _a3;
|
|
10982
10982
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
10983
|
-
iss.path.unshift(
|
|
10983
|
+
iss.path.unshift(path24);
|
|
10984
10984
|
return iss;
|
|
10985
10985
|
});
|
|
10986
10986
|
}
|
|
@@ -11127,16 +11127,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
11127
11127
|
}
|
|
11128
11128
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
11129
11129
|
const fieldErrors = { _errors: [] };
|
|
11130
|
-
const processError = (error52,
|
|
11130
|
+
const processError = (error52, path24 = []) => {
|
|
11131
11131
|
for (const issue2 of error52.issues) {
|
|
11132
11132
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
11133
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
11133
|
+
issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
|
|
11134
11134
|
} else if (issue2.code === "invalid_key") {
|
|
11135
|
-
processError({ issues: issue2.issues }, [...
|
|
11135
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
11136
11136
|
} else if (issue2.code === "invalid_element") {
|
|
11137
|
-
processError({ issues: issue2.issues }, [...
|
|
11137
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
11138
11138
|
} else {
|
|
11139
|
-
const fullpath = [...
|
|
11139
|
+
const fullpath = [...path24, ...issue2.path];
|
|
11140
11140
|
if (fullpath.length === 0) {
|
|
11141
11141
|
fieldErrors._errors.push(mapper(issue2));
|
|
11142
11142
|
} else {
|
|
@@ -11163,17 +11163,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
11163
11163
|
}
|
|
11164
11164
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
11165
11165
|
const result = { errors: [] };
|
|
11166
|
-
const processError = (error52,
|
|
11166
|
+
const processError = (error52, path24 = []) => {
|
|
11167
11167
|
var _a3, _b;
|
|
11168
11168
|
for (const issue2 of error52.issues) {
|
|
11169
11169
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
11170
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
11170
|
+
issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
|
|
11171
11171
|
} else if (issue2.code === "invalid_key") {
|
|
11172
|
-
processError({ issues: issue2.issues }, [...
|
|
11172
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
11173
11173
|
} else if (issue2.code === "invalid_element") {
|
|
11174
|
-
processError({ issues: issue2.issues }, [...
|
|
11174
|
+
processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
|
|
11175
11175
|
} else {
|
|
11176
|
-
const fullpath = [...
|
|
11176
|
+
const fullpath = [...path24, ...issue2.path];
|
|
11177
11177
|
if (fullpath.length === 0) {
|
|
11178
11178
|
result.errors.push(mapper(issue2));
|
|
11179
11179
|
continue;
|
|
@@ -11205,8 +11205,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
11205
11205
|
}
|
|
11206
11206
|
function toDotPath(_path) {
|
|
11207
11207
|
const segs = [];
|
|
11208
|
-
const
|
|
11209
|
-
for (const seg of
|
|
11208
|
+
const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
11209
|
+
for (const seg of path24) {
|
|
11210
11210
|
if (typeof seg === "number")
|
|
11211
11211
|
segs.push(`[${seg}]`);
|
|
11212
11212
|
else if (typeof seg === "symbol")
|
|
@@ -23898,13 +23898,13 @@ function resolveRef(ref, ctx) {
|
|
|
23898
23898
|
if (!ref.startsWith("#")) {
|
|
23899
23899
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
23900
23900
|
}
|
|
23901
|
-
const
|
|
23902
|
-
if (
|
|
23901
|
+
const path24 = ref.slice(1).split("/").filter(Boolean);
|
|
23902
|
+
if (path24.length === 0) {
|
|
23903
23903
|
return ctx.rootSchema;
|
|
23904
23904
|
}
|
|
23905
23905
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
23906
|
-
if (
|
|
23907
|
-
const key =
|
|
23906
|
+
if (path24[0] === defsKey) {
|
|
23907
|
+
const key = path24[1];
|
|
23908
23908
|
if (!key || !ctx.defs[key]) {
|
|
23909
23909
|
throw new Error(`Reference not found: ${ref}`);
|
|
23910
23910
|
}
|
|
@@ -24470,11 +24470,12 @@ var getSystemPrompt = (params) => {
|
|
|
24470
24470
|
const memoryPrompt = getUserMemoryPrompt(params.memoryFilePath);
|
|
24471
24471
|
const agentRulesPrompt = getAgentRulesPrompt(params.agentRulesPath);
|
|
24472
24472
|
return `
|
|
24473
|
-
${params.systemPrompt
|
|
24473
|
+
${params.systemPrompt + `
|
|
24474
|
+
\u8FD9\u662FDeepfish Cli\u7CFB\u7EDF,\u4F60\u662F\u7CFB\u7EDF\u4E2D\u4E25\u683C\u6309\u89C4\u5219\u6267\u884C\u4EFB\u52A1\u7684\u667A\u80FD\u4F53,\u4E0D\u80FD\u8FDD\u53CD\u4EFB\u4F55\u7CFB\u7EDF\u9650\u5236\u3002
|
|
24474
24475
|
# \u6CE8\u610F\u6CE8\u610F\u4E8B\u9879:
|
|
24475
24476
|
1.\u5982\u679C\u4EFB\u52A1\u6BD4\u8F83\u590D\u6742\uFF0C\u5E94\u8BE5\u5148\u8FDB\u884C\u62C6\u5206\uFF0C\u5206\u89E3\u6210\u591A\u4E2A\u6B65\u9AA4\uFF0C\u521B\u5EFA\u5B50\u667A\u80FD\u4F53\u6765\u9010\u6B65\u5B8C\u6210\u3002
|
|
24476
24477
|
2.\u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4F7F\u7528"tmp_"\u4F5C\u4E3A\u524D\u7F00\u547D\u540D\uFF0C\u5E76\u5728\u4EFB\u52A1\u7ED3\u675F\u540E\u5220\u9664\uFF0C\u4E0D\u80FD\u5728\u5DE5\u4F5C\u76EE\u5F55\u4E2D\u7559\u4E0B\u4EFB\u4F55\u4E34\u65F6\u6587\u4EF6\u3002
|
|
24477
|
-
3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1
|
|
24478
|
+
3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u7ED3\u5408Nodejs\u4EE3\u7801\u5B8C\u6210\u4EFB\u52A1
|
|
24478
24479
|
4.\u786C\u6027\u89C4\u5219\uFF1A\u65E0\u8BBA\u6846\u67B6\u5185\u7F6E\u82F1\u6587\u6A21\u677F\uFF0C\u4F60\u7684\u6BCF\u4E00\u6B65\u601D\u8003\uFF08Thought\uFF09\u3001\u89C2\u5BDF\u5206\u6790\u3001\u7ED3\u8BBA\u56DE\u7B54\uFF0C**\u4E25\u683C\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587**\uFF0C\u7981\u6B62\u82F1\u6587\u3002`}
|
|
24479
24480
|
|
|
24480
24481
|
# \u57FA\u7840\u73AF\u5883\u4FE1\u606F
|
|
@@ -24486,21 +24487,24 @@ ${memoryPrompt}
|
|
|
24486
24487
|
${agentRulesPrompt}
|
|
24487
24488
|
`;
|
|
24488
24489
|
};
|
|
24489
|
-
var subSystemPrompt = (
|
|
24490
|
-
|
|
24491
|
-
|
|
24490
|
+
var subSystemPrompt = (params) => {
|
|
24491
|
+
const skillPrompt = getSkillPrompt(params.skills, params.excludeSkills);
|
|
24492
|
+
const basePrompt = `
|
|
24492
24493
|
\u8FD9\u662FDeepfish Cli\u7CFB\u7EDF,\u4F60\u662F\u7CFB\u7EDF\u4E2D\u4E25\u683C\u6309\u89C4\u5219\u6267\u884C\u4EFB\u52A1\u7684\u5B50\u667A\u80FD\u4F53,\u4E0D\u80FD\u8FDD\u53CD\u4EFB\u4F55\u7CFB\u7EDF\u9650\u5236\u3002
|
|
24493
24494
|
### \u57FA\u7840\u73AF\u5883\u4FE1\u606F
|
|
24494
|
-
\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${workspace}
|
|
24495
|
-
\u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${osType}
|
|
24495
|
+
\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${params.workspace}
|
|
24496
|
+
\u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${params.osType}
|
|
24496
24497
|
|
|
24497
24498
|
\u6CE8\u610F:
|
|
24498
24499
|
1.\u5B50\u667A\u80FD\u4F53\u53EA\u80FD\u5B8C\u6210\u5355\u4E2A\u4EFB\u52A1,\u4E0D\u80FD\u521B\u5EFA\u65B0\u7684\u5B50\u667A\u80FD\u4F53\u3002
|
|
24499
24500
|
2.\u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4F7F\u7528"tmp_"\u4F5C\u4E3A\u524D\u7F00\u547D\u540D\uFF0C\u5E76\u5728\u4EFB\u52A1\u7ED3\u675F\u540E\u5220\u9664\uFF0C\u4E0D\u80FD\u5728\u5DE5\u4F5C\u76EE\u5F55\u4E2D\u7559\u4E0B\u4EFB\u4F55\u4E34\u65F6\u6587\u4EF6\u3002
|
|
24500
|
-
3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1
|
|
24501
|
+
3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u7ED3\u5408Nodejs\u4EE3\u7801\u5B8C\u6210\u4EFB\u52A1
|
|
24501
24502
|
4.\u786C\u6027\u89C4\u5219\uFF1A\u65E0\u8BBA\u6846\u67B6\u5185\u7F6E\u82F1\u6587\u6A21\u677F\uFF0C\u4F60\u7684\u6BCF\u4E00\u6B65\u601D\u8003\uFF08Thought\uFF09\u3001\u89C2\u5BDF\u5206\u6790\u3001\u7ED3\u8BBA\u56DE\u7B54\uFF0C**\u4E25\u683C\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587**\uFF0C\u7981\u6B62\u82F1\u6587\u3002
|
|
24502
24503
|
|
|
24503
24504
|
${skillPrompt}
|
|
24505
|
+
`;
|
|
24506
|
+
return `
|
|
24507
|
+
${params.systemPrompt + basePrompt}
|
|
24504
24508
|
`;
|
|
24505
24509
|
};
|
|
24506
24510
|
|
|
@@ -24737,9 +24741,8 @@ function toLangChainTool(func, description) {
|
|
|
24737
24741
|
const wrappedFunc = async (args, runtime) => {
|
|
24738
24742
|
try {
|
|
24739
24743
|
const boundFunc = func.bind({
|
|
24740
|
-
createSubAgent: async (prompt) => {
|
|
24741
|
-
|
|
24742
|
-
return subAgent.execute(prompt);
|
|
24744
|
+
createSubAgent: async (systemPrompt, prompt) => {
|
|
24745
|
+
return runtime.context.curAgent.subExecute(systemPrompt, prompt);
|
|
24743
24746
|
},
|
|
24744
24747
|
curAgent: runtime.context.curAgent
|
|
24745
24748
|
});
|
|
@@ -24758,10 +24761,11 @@ function toLangChainTool(func, description) {
|
|
|
24758
24761
|
schema
|
|
24759
24762
|
});
|
|
24760
24763
|
}
|
|
24761
|
-
function scanUserTools(excludeTools) {
|
|
24762
|
-
const
|
|
24764
|
+
function scanUserTools(excludeTools, externalTools) {
|
|
24765
|
+
const files1 = _scanUserToolsFile();
|
|
24766
|
+
const files2 = _scanExternalToolsFile(externalTools);
|
|
24763
24767
|
const tools = [];
|
|
24764
|
-
|
|
24768
|
+
[...files1, ...files2].forEach((toolFile) => {
|
|
24765
24769
|
_loadToolsFromFile(toolFile.filePath, tools, excludeTools);
|
|
24766
24770
|
});
|
|
24767
24771
|
return tools;
|
|
@@ -24792,6 +24796,52 @@ function getUserToolList() {
|
|
|
24792
24796
|
});
|
|
24793
24797
|
return toolOpts;
|
|
24794
24798
|
}
|
|
24799
|
+
function _scanToolsFile(filePath) {
|
|
24800
|
+
let toolFile = null;
|
|
24801
|
+
if (import_fs_extra8.default.statSync(filePath).isDirectory()) {
|
|
24802
|
+
const subDirPath = import_path8.default.resolve(filePath);
|
|
24803
|
+
const subFiles = import_fs_extra8.default.readdirSync(subDirPath);
|
|
24804
|
+
const indexFile = subFiles.find((f) => f === "index.js" || f === "index.cjs");
|
|
24805
|
+
if (indexFile) {
|
|
24806
|
+
const filePath2 = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, indexFile));
|
|
24807
|
+
if (filePath2) {
|
|
24808
|
+
toolFile = {
|
|
24809
|
+
filePath: filePath2,
|
|
24810
|
+
dir: subDirPath
|
|
24811
|
+
};
|
|
24812
|
+
}
|
|
24813
|
+
} else {
|
|
24814
|
+
subFiles.forEach((subFile) => {
|
|
24815
|
+
const filePath2 = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, subFile));
|
|
24816
|
+
if (filePath2) {
|
|
24817
|
+
toolFile = {
|
|
24818
|
+
filePath: filePath2,
|
|
24819
|
+
dir: subDirPath
|
|
24820
|
+
};
|
|
24821
|
+
}
|
|
24822
|
+
});
|
|
24823
|
+
}
|
|
24824
|
+
} else {
|
|
24825
|
+
const toolfilePath = _scanDeepFishJsFile(filePath);
|
|
24826
|
+
if (toolfilePath) {
|
|
24827
|
+
toolFile = {
|
|
24828
|
+
filePath: toolfilePath,
|
|
24829
|
+
dir: null
|
|
24830
|
+
};
|
|
24831
|
+
}
|
|
24832
|
+
}
|
|
24833
|
+
return toolFile;
|
|
24834
|
+
}
|
|
24835
|
+
function _scanExternalToolsFile(externalTools) {
|
|
24836
|
+
const toolFiles = [];
|
|
24837
|
+
externalTools.forEach((filePath) => {
|
|
24838
|
+
const toolFile = _scanToolsFile(filePath);
|
|
24839
|
+
if (toolFile) {
|
|
24840
|
+
toolFiles.push(toolFile);
|
|
24841
|
+
}
|
|
24842
|
+
});
|
|
24843
|
+
return toolFiles;
|
|
24844
|
+
}
|
|
24795
24845
|
function _scanUserToolsFile() {
|
|
24796
24846
|
const toolFiles = [];
|
|
24797
24847
|
const scanPaths = getScanDirPaths();
|
|
@@ -24803,45 +24853,18 @@ function _scanUserToolsFile() {
|
|
|
24803
24853
|
if (import_fs_extra8.default.pathExistsSync(toolsDir)) {
|
|
24804
24854
|
const files = import_fs_extra8.default.readdirSync(toolsDir);
|
|
24805
24855
|
files.forEach((file2) => {
|
|
24806
|
-
|
|
24807
|
-
|
|
24808
|
-
|
|
24809
|
-
|
|
24810
|
-
if (indexFile) {
|
|
24811
|
-
const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, indexFile), indexFile);
|
|
24812
|
-
if (filePath) {
|
|
24813
|
-
toolFiles.push({
|
|
24814
|
-
filePath,
|
|
24815
|
-
dir: subDirPath
|
|
24816
|
-
});
|
|
24817
|
-
}
|
|
24818
|
-
} else {
|
|
24819
|
-
subFiles.forEach((subFile) => {
|
|
24820
|
-
const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, subFile), subFile);
|
|
24821
|
-
if (filePath) {
|
|
24822
|
-
toolFiles.push({
|
|
24823
|
-
filePath,
|
|
24824
|
-
dir: subDirPath
|
|
24825
|
-
});
|
|
24826
|
-
}
|
|
24827
|
-
});
|
|
24828
|
-
}
|
|
24829
|
-
} else {
|
|
24830
|
-
const filePath = _scanDeepFishJsFile(toolsDir, file2);
|
|
24831
|
-
if (filePath) {
|
|
24832
|
-
toolFiles.push({
|
|
24833
|
-
filePath,
|
|
24834
|
-
dir: null
|
|
24835
|
-
});
|
|
24836
|
-
}
|
|
24856
|
+
const filePath = import_path8.default.resolve(toolsDir, file2);
|
|
24857
|
+
const toolFile = _scanToolsFile(filePath);
|
|
24858
|
+
if (toolFile) {
|
|
24859
|
+
toolFiles.push(toolFile);
|
|
24837
24860
|
}
|
|
24838
24861
|
});
|
|
24839
24862
|
}
|
|
24840
24863
|
});
|
|
24841
24864
|
return toolFiles;
|
|
24842
24865
|
}
|
|
24843
|
-
function _scanDeepFishJsFile(filePath
|
|
24844
|
-
if (
|
|
24866
|
+
function _scanDeepFishJsFile(filePath) {
|
|
24867
|
+
if (filePath.endsWith(".js") || filePath.endsWith(".cjs")) {
|
|
24845
24868
|
const fileContent = import_fs_extra8.default.readFileSync(filePath, "utf-8");
|
|
24846
24869
|
if (fileContent.includes("module.exports") && fileContent.includes("descriptions") && fileContent.includes("functions")) {
|
|
24847
24870
|
return filePath;
|
|
@@ -24941,20 +24964,17 @@ var import_fs_extra9 = __toESM(require("fs-extra"));
|
|
|
24941
24964
|
|
|
24942
24965
|
// src/agent/tools/subAgent.ts
|
|
24943
24966
|
var import_langchain4 = require("langchain");
|
|
24944
|
-
async function subAgentExec(prompt, runtime) {
|
|
24967
|
+
async function subAgentExec(systemPrompt, prompt, runtime) {
|
|
24945
24968
|
const curAgent = runtime.context?.curAgent;
|
|
24946
|
-
|
|
24947
|
-
throw new Error("\u5F53\u524D\u8FD0\u884C\u4E0A\u4E0B\u6587\u4E0D\u652F\u6301\u521B\u5EFA\u5B50 agent");
|
|
24948
|
-
}
|
|
24949
|
-
const subAgent = await curAgent.createSubAgent();
|
|
24950
|
-
return subAgent.execute(prompt);
|
|
24969
|
+
return curAgent && curAgent.subExecute(systemPrompt, prompt);
|
|
24951
24970
|
}
|
|
24952
24971
|
var subAgentTool = (0, import_langchain4.tool)(
|
|
24953
|
-
async ({ prompt }, runtime) => safeTool(() => subAgentExec(prompt, runtime)),
|
|
24972
|
+
async ({ systemPrompt, prompt }, runtime) => safeTool(() => subAgentExec(systemPrompt, prompt, runtime)),
|
|
24954
24973
|
{
|
|
24955
24974
|
name: "subAgent_exec",
|
|
24956
24975
|
description: "\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6765\u6267\u884C\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u5E76\u8FD4\u56DE\u5B50 agent \u7684\u6267\u884C\u7ED3\u679C\u3002\u9002\u5408\u62C6\u5206\u590D\u6742\u4EFB\u52A1\u3001\u5E76\u884C\u8C03\u7814\u6216\u59D4\u6D3E\u5B50\u4EFB\u52A1\u3002",
|
|
24957
24976
|
schema: external_exports.object({
|
|
24977
|
+
systemPrompt: external_exports.string().min(1).describe("\u5B50 agent \u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF0C\u5B9A\u4E49\u5176\u89D2\u8272\u548C\u884C\u4E3A\u89C4\u8303"),
|
|
24958
24978
|
prompt: external_exports.string().min(1).describe("\u4EA4\u7ED9\u901A\u7528\u5B50 agent \u6267\u884C\u7684\u5B8C\u6574\u4EFB\u52A1\u63CF\u8FF0")
|
|
24959
24979
|
})
|
|
24960
24980
|
}
|
|
@@ -25035,7 +25055,7 @@ var installPackageTool = (0, import_langchain5.tool)(
|
|
|
25035
25055
|
);
|
|
25036
25056
|
var executeJSCodeTool = (0, import_langchain5.tool)(async ({ code }, runtime) => safeTool(() => executeJSCode(code, runtime)), {
|
|
25037
25057
|
name: "execute_js_code",
|
|
25038
|
-
description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\
|
|
25058
|
+
description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A1.\u5982\u679C\u4EE3\u7801\u4E2D\u4F7F\u7528\u7B2C\u4E09\u65B9\u4F9D\u8D56\u5FC5\u987B\u5148\u4F7F\u7528check_package_installed\u5DE5\u5177\u68C0\u67E5\u5305\u662F\u5426\u5B89\u88C5\uFF0C\u5982\u679C\u672A\u5B89\u88C5\u9700\u8981\u6267\u884Cinstall_package\u5DE5\u5177\u5B89\u88C5\u6307\u5B9A\u7684npm\u5305;2.\u4EE3\u7801\u5FC5\u987B\u5305\u542B\u4E00\u4E2A__main()\u51FD\u6570\u4F5C\u4E3A\u6267\u884C\u5165\u53E3\uFF0C__main()\u51FD\u6570\u5185\u5FC5\u987B\u662F\u4E00\u4E2A\u4F7F\u7528async\u524D\u7F00\u7684\u51FD\u6570\u3002
|
|
25039
25059
|
\u53EF\u7528\u5185\u7F6E\u51FD\u6570\uFF1A
|
|
25040
25060
|
- agentExec(prompt: string): Promise<string>\uFF0C\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6267\u884C\u6307\u5B9A\u4EFB\u52A1\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF0C\u9002\u5408\u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u5206\u7ED9\u5B50 agent \u5B8C\u6210\u3002
|
|
25041
25061
|
\u793A\u4F8B\u4EE3\u7801\uFF1A
|
|
@@ -25731,7 +25751,10 @@ Commands:
|
|
|
25731
25751
|
ai skills generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u6280\u80FD\u6A21\u677F
|
|
25732
25752
|
|
|
25733
25753
|
# Tools commands
|
|
25754
|
+
ai tools ls \u67E5\u770B\u5DF2\u5B89\u88C5\u6216\u5DF2\u914D\u7F6E\u7684\u5DE5\u5177\u5217\u8868
|
|
25734
25755
|
ai tools dir \u6253\u5F00\u6216\u8F93\u51FA\u7528\u6237\u81EA\u5B9A\u4E49\u5DE5\u5177\u76EE\u5F55
|
|
25756
|
+
ai tools add <name> \u6DFB\u52A0\u6307\u5B9A\u540D\u79F0\u7684\u5DE5\u5177
|
|
25757
|
+
ai tools del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u81EA\u5B9A\u4E49\u5DE5\u5177
|
|
25735
25758
|
ai tools generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u5DE5\u5177\u6A21\u677F
|
|
25736
25759
|
|
|
25737
25760
|
# Session commands
|
|
@@ -25743,9 +25766,15 @@ Commands:
|
|
|
25743
25766
|
ai task add <task> \u5411\u4EFB\u52A1\u961F\u5217\u6DFB\u52A0\u4E00\u4E2A\u540E\u7EED\u4EFB\u52A1
|
|
25744
25767
|
ai task del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u4EFB\u52A1
|
|
25745
25768
|
ai task clear \u6E05\u7A7A\u5F53\u524D\u4EFB\u52A1\u961F\u5217
|
|
25769
|
+
|
|
25770
|
+
# Plan commands
|
|
25771
|
+
ai plan-do <\u4EFB\u52A1\u63CF\u8FF0> \u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u89E3\u4E3A\u5B50\u4EFB\u52A1\u5E76\u9010\u6B65\u6267\u884C\u5B8C\u6210
|
|
25746
25772
|
|
|
25747
25773
|
# MCP commands
|
|
25748
25774
|
ai mcp edit \u6253\u5F00 MCP \u914D\u7F6E\u6587\u4EF6\u8FDB\u884C\u7F16\u8F91
|
|
25775
|
+
ai mcp ls \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u5668\u5217\u8868
|
|
25776
|
+
ai mcp enable <name|index> \u542F\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
25777
|
+
ai mcp disable <name|index> \u7981\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
25749
25778
|
|
|
25750
25779
|
# Serve commands
|
|
25751
25780
|
ai serve \u542F\u52A8\u670D\u52A1\u6216\u8FDB\u5165\u670D\u52A1\u7BA1\u7406\u5165\u53E3
|
|
@@ -25833,14 +25862,14 @@ var builtinTools = [
|
|
|
25833
25862
|
...learnTools,
|
|
25834
25863
|
...fishInfoTools
|
|
25835
25864
|
];
|
|
25836
|
-
async function getTools(excludeTools, excludeMCP) {
|
|
25837
|
-
return [...builtinTools, ...await scanUserTools(excludeTools), ...await scanUserMcp(excludeMCP)];
|
|
25865
|
+
async function getTools(excludeTools, excludeMCP, externalTools = []) {
|
|
25866
|
+
return [...builtinTools, ...await scanUserTools(excludeTools, externalTools), ...await scanUserMcp(excludeMCP)];
|
|
25838
25867
|
}
|
|
25839
25868
|
|
|
25840
25869
|
// src/agent/skills/index.ts
|
|
25841
25870
|
var import_path17 = __toESM(require("path"));
|
|
25842
25871
|
function getSkills() {
|
|
25843
|
-
return [...getRegisteredSkills(), import_path17.default.join(__dirname, "./view-learn-cache.md")];
|
|
25872
|
+
return [...getRegisteredSkills(), import_path17.default.join(__dirname, "./skills/view-learn-cache.md"), import_path17.default.join(__dirname, "./skills/generate-skill.md"), import_path17.default.join(__dirname, "./skills/generate-tool.md")];
|
|
25844
25873
|
}
|
|
25845
25874
|
|
|
25846
25875
|
// src/agent/AIAgent/index.ts
|
|
@@ -25897,8 +25926,8 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25897
25926
|
if (this.subLevel > 2) {
|
|
25898
25927
|
this.excludeTools.push("subAgent_exec");
|
|
25899
25928
|
}
|
|
25900
|
-
this.tools = await getTools(this.excludeTools, this.excludeMCP);
|
|
25901
|
-
this.skills = [...getSkills(), ...this.opt.
|
|
25929
|
+
this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
|
|
25930
|
+
this.skills = [...getSkills(), ...this.opt.externalSkills || []];
|
|
25902
25931
|
const model = getModel(this.opt.modelOpt);
|
|
25903
25932
|
const checkpointer = new FileSystemSaver({
|
|
25904
25933
|
rootFolder: this.sessionDirPath
|
|
@@ -25919,7 +25948,13 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25919
25948
|
memoryFilePath: this.memoryFilePath,
|
|
25920
25949
|
agentRulesPath: this.agentRulesPath,
|
|
25921
25950
|
excludeSkills: this.excludeSkills
|
|
25922
|
-
}) : subSystemPrompt(
|
|
25951
|
+
}) : subSystemPrompt({
|
|
25952
|
+
systemPrompt: this.systemPrompt,
|
|
25953
|
+
workspace: this.workspace,
|
|
25954
|
+
osType: import_os3.default.platform(),
|
|
25955
|
+
skills: this.skills,
|
|
25956
|
+
excludeSkills: this.excludeSkills
|
|
25957
|
+
});
|
|
25923
25958
|
const agent = (0, import_langchain18.createAgent)({
|
|
25924
25959
|
model,
|
|
25925
25960
|
checkpointer,
|
|
@@ -25932,14 +25967,6 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25932
25967
|
trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
|
|
25933
25968
|
keep: { messages: 50 }
|
|
25934
25969
|
}),
|
|
25935
|
-
(0, import_langchain18.humanInTheLoopMiddleware)({
|
|
25936
|
-
interruptOn: {
|
|
25937
|
-
install_package: {
|
|
25938
|
-
allowedDecisions: ["approve", "reject"]
|
|
25939
|
-
},
|
|
25940
|
-
readEmailTool: false
|
|
25941
|
-
}
|
|
25942
|
-
}),
|
|
25943
25970
|
(0, import_langchain18.todoListMiddleware)(),
|
|
25944
25971
|
(0, import_deepagents.createPatchToolCallsMiddleware)()
|
|
25945
25972
|
],
|
|
@@ -25974,6 +26001,9 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25974
26001
|
resolve(msg);
|
|
25975
26002
|
});
|
|
25976
26003
|
for await (const [_namespace, mode, data] of stream) {
|
|
26004
|
+
if (Array.isArray(_namespace) && _namespace.length > 0) {
|
|
26005
|
+
continue;
|
|
26006
|
+
}
|
|
25977
26007
|
if (mode === "messages") {
|
|
25978
26008
|
const message = data[0].additional_kwargs.reasoning_content;
|
|
25979
26009
|
this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, message);
|
|
@@ -26089,8 +26119,8 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26089
26119
|
this.maxSubAgentCount = opt.maxSubAgentCount || 2;
|
|
26090
26120
|
}
|
|
26091
26121
|
async init() {
|
|
26092
|
-
this.tools = await getTools(this.excludeTools, this.excludeMCP);
|
|
26093
|
-
this.skills = [...getSkills(), ...this.opt.
|
|
26122
|
+
this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
|
|
26123
|
+
this.skills = [...getSkills(), ...this.opt.externalSkills || []];
|
|
26094
26124
|
const model = getModel(this.opt.modelOpt);
|
|
26095
26125
|
const checkpointer = new FileSystemSaver({
|
|
26096
26126
|
rootFolder: this.sessionDirPath
|
|
@@ -26115,14 +26145,6 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26115
26145
|
trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
|
|
26116
26146
|
keep: { messages: 50 }
|
|
26117
26147
|
}),
|
|
26118
|
-
(0, import_langchain19.humanInTheLoopMiddleware)({
|
|
26119
|
-
interruptOn: {
|
|
26120
|
-
install_package: {
|
|
26121
|
-
allowedDecisions: ["approve", "reject"]
|
|
26122
|
-
},
|
|
26123
|
-
readEmailTool: false
|
|
26124
|
-
}
|
|
26125
|
-
}),
|
|
26126
26148
|
(0, import_langchain19.todoListMiddleware)(),
|
|
26127
26149
|
(0, import_deepagents2.createPatchToolCallsMiddleware)()
|
|
26128
26150
|
],
|
|
@@ -26162,6 +26184,9 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26162
26184
|
}
|
|
26163
26185
|
);
|
|
26164
26186
|
for await (const [_namespace, mode, data] of stream) {
|
|
26187
|
+
if (Array.isArray(_namespace) && _namespace.length > 0) {
|
|
26188
|
+
continue;
|
|
26189
|
+
}
|
|
26165
26190
|
if (mode === "messages") {
|
|
26166
26191
|
const message = data?.[0];
|
|
26167
26192
|
const reasoning_content = message?.additional_kwargs?.reasoning_content;
|
|
@@ -26227,11 +26252,16 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26227
26252
|
this.on("USE_TOOL_AFTER" /* USE_TOOL_AFTER */, (_toolId, _funcName, _funcArgs) => {
|
|
26228
26253
|
});
|
|
26229
26254
|
}
|
|
26230
|
-
async createSubAgent() {
|
|
26255
|
+
async createSubAgent(systemPrompt) {
|
|
26231
26256
|
const subAgent = new SubAIAgent(this.opt);
|
|
26257
|
+
systemPrompt && (subAgent.systemPrompt = systemPrompt);
|
|
26232
26258
|
await subAgent.init();
|
|
26233
26259
|
return subAgent;
|
|
26234
26260
|
}
|
|
26261
|
+
async subExecute(systemPrompt, prompt) {
|
|
26262
|
+
const subAgent = await this.createSubAgent(systemPrompt);
|
|
26263
|
+
return subAgent.execute(prompt);
|
|
26264
|
+
}
|
|
26235
26265
|
destory() {
|
|
26236
26266
|
this.removeAllListeners();
|
|
26237
26267
|
}
|
|
@@ -26484,7 +26514,7 @@ async function initAgent(config2, skills) {
|
|
|
26484
26514
|
// CLI encoding format, can be set to utf-8, gbk, etc., or left empty for auto-detection
|
|
26485
26515
|
maxSubAgentCount: config2.maxSubAgentCount,
|
|
26486
26516
|
// Maximum parallel sub-agent execution count, -1 means unlimited
|
|
26487
|
-
skills,
|
|
26517
|
+
externalSkills: skills,
|
|
26488
26518
|
isPrintThinking: config2.isPrintThinking
|
|
26489
26519
|
// Whether to print intermediate information during AI thinking, default is true
|
|
26490
26520
|
});
|
|
@@ -26680,7 +26710,11 @@ function handleSkillsLs() {
|
|
|
26680
26710
|
logInfo("No skills registered yet");
|
|
26681
26711
|
} else {
|
|
26682
26712
|
skills.forEach((skill, index) => {
|
|
26683
|
-
|
|
26713
|
+
if (skill.isEnabled) {
|
|
26714
|
+
logSuccess(`[${index}] ${skill.name} [\u221A]`);
|
|
26715
|
+
} else {
|
|
26716
|
+
logInfo(`[${index}] ${skill.name} [\xD7]`);
|
|
26717
|
+
}
|
|
26684
26718
|
});
|
|
26685
26719
|
}
|
|
26686
26720
|
logInfo("=".repeat(50));
|
|
@@ -26814,7 +26848,7 @@ async function handleSkillsGenerate(target) {
|
|
|
26814
26848
|
logError("Failed to start service, please check config or port availability");
|
|
26815
26849
|
return;
|
|
26816
26850
|
}
|
|
26817
|
-
const generateSkillPath = import_path20.default.join(__dirname, "./generate-skill.md");
|
|
26851
|
+
const generateSkillPath = import_path20.default.join(__dirname, "./skills/generate-skill.md");
|
|
26818
26852
|
const agent = await initAgent(config2, [generateSkillPath]);
|
|
26819
26853
|
const prompt = `\u8BF7\u6839\u636E\u4EE5\u4E0B\u9700\u6C42\u751F\u6210\u4E00\u4E2ASkill\u6A21\u5757\uFF1A${target}
|
|
26820
26854
|
|
|
@@ -26848,11 +26882,13 @@ function _scanSkills(skillsDir) {
|
|
|
26848
26882
|
}
|
|
26849
26883
|
function _updateRegister(skillsDir) {
|
|
26850
26884
|
const registerPath = _getRegisterPath(skillsDir);
|
|
26851
|
-
if (import_fs_extra20.default.existsSync(skillsDir)
|
|
26852
|
-
import_fs_extra20.default.writeJSONSync(registerPath, [], { spaces: 2 });
|
|
26853
|
-
} else if (!import_fs_extra20.default.existsSync(skillsDir)) {
|
|
26885
|
+
if (!import_fs_extra20.default.existsSync(skillsDir)) {
|
|
26854
26886
|
return;
|
|
26855
26887
|
}
|
|
26888
|
+
if (!import_fs_extra20.default.existsSync(registerPath)) {
|
|
26889
|
+
import_fs_extra20.default.ensureDirSync(import_path20.default.dirname(registerPath));
|
|
26890
|
+
import_fs_extra20.default.writeJSONSync(registerPath, [], { spaces: 2 });
|
|
26891
|
+
}
|
|
26856
26892
|
const skills = _scanSkills(skillsDir);
|
|
26857
26893
|
let register = import_fs_extra20.default.readJSONSync(registerPath);
|
|
26858
26894
|
const newRegister = [];
|
|
@@ -26913,10 +26949,12 @@ function _getAllSkills() {
|
|
|
26913
26949
|
return allSkills;
|
|
26914
26950
|
}
|
|
26915
26951
|
function _getRegisterPath(skillsDir) {
|
|
26916
|
-
|
|
26917
|
-
|
|
26952
|
+
const normalizedDir = import_path20.default.normalize(skillsDir);
|
|
26953
|
+
const baseName = import_path20.default.basename(normalizedDir).toLowerCase();
|
|
26954
|
+
if (baseName === "@deepfish-ai" || baseName === "skills") {
|
|
26955
|
+
return import_path20.default.join(normalizedDir, "register.json");
|
|
26918
26956
|
}
|
|
26919
|
-
return import_path20.default.join(
|
|
26957
|
+
return import_path20.default.join(normalizedDir, "skills", "register.json");
|
|
26920
26958
|
}
|
|
26921
26959
|
|
|
26922
26960
|
// src/cli/cli-skills.ts
|
|
@@ -27034,7 +27072,7 @@ async function handleToolsGenerate(target) {
|
|
|
27034
27072
|
logError("Failed to start service, please check config or port availability");
|
|
27035
27073
|
return;
|
|
27036
27074
|
}
|
|
27037
|
-
const generateSkillPath = import_path21.default.join(__dirname, "./generate-tool.md");
|
|
27075
|
+
const generateSkillPath = import_path21.default.join(__dirname, "./skills/generate-tool.md");
|
|
27038
27076
|
const agent = await initAgent(config2, [generateSkillPath]);
|
|
27039
27077
|
const prompt = `Please use the "generate-tool" SKILL to generate a tool module according to the following requirements: ${target}
|
|
27040
27078
|
|
|
@@ -27170,21 +27208,92 @@ function registerTaskCommands(program) {
|
|
|
27170
27208
|
}
|
|
27171
27209
|
|
|
27172
27210
|
// src/cli/cli-core/mcp.ts
|
|
27211
|
+
var import_fs_extra22 = __toESM(require("fs-extra"));
|
|
27173
27212
|
function handleMcpEdit() {
|
|
27174
27213
|
const mcpPath = getMCPFilePath();
|
|
27175
27214
|
editFile(mcpPath);
|
|
27176
27215
|
}
|
|
27216
|
+
function readMcpConfig() {
|
|
27217
|
+
const mcpPath = getMCPFilePath();
|
|
27218
|
+
return import_fs_extra22.default.readJSONSync(mcpPath);
|
|
27219
|
+
}
|
|
27220
|
+
function writeMcpConfig(data) {
|
|
27221
|
+
const mcpPath = getMCPFilePath();
|
|
27222
|
+
import_fs_extra22.default.writeJSONSync(mcpPath, data, { spaces: 2 });
|
|
27223
|
+
}
|
|
27224
|
+
function handleMcpLs() {
|
|
27225
|
+
const config2 = readMcpConfig();
|
|
27226
|
+
const servers = config2.mcpServers || {};
|
|
27227
|
+
const entries = Object.entries(servers);
|
|
27228
|
+
if (entries.length === 0) {
|
|
27229
|
+
logWarning("No MCP servers configured yet");
|
|
27230
|
+
return;
|
|
27231
|
+
}
|
|
27232
|
+
logInfo("=".repeat(50));
|
|
27233
|
+
entries.forEach(([name, server], index) => {
|
|
27234
|
+
const disabled = server.disabled === true;
|
|
27235
|
+
if (disabled) {
|
|
27236
|
+
logInfo(`[${index}] ${name} [\xD7]`);
|
|
27237
|
+
} else {
|
|
27238
|
+
logSuccess(`[${index}] ${name} [\u221A]`);
|
|
27239
|
+
}
|
|
27240
|
+
});
|
|
27241
|
+
logInfo("=".repeat(50));
|
|
27242
|
+
}
|
|
27243
|
+
function handleMcpEnable(nameOrIndex) {
|
|
27244
|
+
const config2 = readMcpConfig();
|
|
27245
|
+
const servers = config2.mcpServers || {};
|
|
27246
|
+
const entries = Object.keys(servers);
|
|
27247
|
+
let targetIndex = -1;
|
|
27248
|
+
const index = parseInt(nameOrIndex, 10);
|
|
27249
|
+
if (!isNaN(index) && index >= 0 && index < entries.length) {
|
|
27250
|
+
targetIndex = index;
|
|
27251
|
+
} else {
|
|
27252
|
+
targetIndex = entries.findIndex((name) => name === nameOrIndex);
|
|
27253
|
+
}
|
|
27254
|
+
if (targetIndex === -1) {
|
|
27255
|
+
logError(`MCP server not found: ${nameOrIndex}`);
|
|
27256
|
+
return;
|
|
27257
|
+
}
|
|
27258
|
+
const serverName = entries[targetIndex];
|
|
27259
|
+
servers[serverName].disabled = false;
|
|
27260
|
+
writeMcpConfig(config2);
|
|
27261
|
+
logSuccess(`MCP server "${serverName}" enabled`);
|
|
27262
|
+
}
|
|
27263
|
+
function handleMcpDisable(nameOrIndex) {
|
|
27264
|
+
const config2 = readMcpConfig();
|
|
27265
|
+
const servers = config2.mcpServers || {};
|
|
27266
|
+
const entries = Object.keys(servers);
|
|
27267
|
+
let targetIndex = -1;
|
|
27268
|
+
const index = parseInt(nameOrIndex, 10);
|
|
27269
|
+
if (!isNaN(index) && index >= 0 && index < entries.length) {
|
|
27270
|
+
targetIndex = index;
|
|
27271
|
+
} else {
|
|
27272
|
+
targetIndex = entries.findIndex((name) => name === nameOrIndex);
|
|
27273
|
+
}
|
|
27274
|
+
if (targetIndex === -1) {
|
|
27275
|
+
logError(`MCP server not found: ${nameOrIndex}`);
|
|
27276
|
+
return;
|
|
27277
|
+
}
|
|
27278
|
+
const serverName = entries[targetIndex];
|
|
27279
|
+
servers[serverName].disabled = true;
|
|
27280
|
+
writeMcpConfig(config2);
|
|
27281
|
+
logSuccess(`MCP server "${serverName}" disabled`);
|
|
27282
|
+
}
|
|
27177
27283
|
|
|
27178
27284
|
// src/cli/cli-mcp.ts
|
|
27179
27285
|
function registerMcpCommands(program) {
|
|
27180
27286
|
const mcp = program.command("mcp");
|
|
27181
27287
|
mcp.command("edit").description("\u7F16\u8F91 MCP \u914D\u7F6E\u6587\u4EF6").action(handleMcpEdit);
|
|
27288
|
+
mcp.command("ls").description("\u5217\u51FA\u6240\u6709 MCP \u670D\u52A1\u5668").action(handleMcpLs);
|
|
27289
|
+
mcp.command("enable <nameOrIndex>").description("\u542F\u7528 MCP \u670D\u52A1\u5668").action(handleMcpEnable);
|
|
27290
|
+
mcp.command("disable <nameOrIndex>").description("\u7981\u7528 MCP \u670D\u52A1\u5668").action(handleMcpDisable);
|
|
27182
27291
|
}
|
|
27183
27292
|
|
|
27184
27293
|
// src/cli/cli-core/input.ts
|
|
27185
|
-
var
|
|
27294
|
+
var import_fs_extra23 = __toESM(require("fs-extra"));
|
|
27186
27295
|
var readline = __toESM(require("readline"));
|
|
27187
|
-
async function handleInput(args) {
|
|
27296
|
+
async function handleInput(args, skills) {
|
|
27188
27297
|
const input = args.join(" ");
|
|
27189
27298
|
if (!input.trim()) {
|
|
27190
27299
|
logError("Please enter content");
|
|
@@ -27192,7 +27301,7 @@ async function handleInput(args) {
|
|
|
27192
27301
|
}
|
|
27193
27302
|
try {
|
|
27194
27303
|
const configPath = getConfigPath();
|
|
27195
|
-
if (!
|
|
27304
|
+
if (!import_fs_extra23.default.pathExistsSync(configPath)) {
|
|
27196
27305
|
logError("Config file not found, please run init first");
|
|
27197
27306
|
return;
|
|
27198
27307
|
}
|
|
@@ -27207,7 +27316,7 @@ async function handleInput(args) {
|
|
|
27207
27316
|
logError("Failed to start service, please check config or port availability");
|
|
27208
27317
|
return;
|
|
27209
27318
|
}
|
|
27210
|
-
const agent = await initAgent(config2);
|
|
27319
|
+
const agent = await initAgent(config2, skills);
|
|
27211
27320
|
const connResult = await connectAgentRoom(agent);
|
|
27212
27321
|
if (!connResult.ok) {
|
|
27213
27322
|
if (connResult.reason === "duplicate-id") {
|
|
@@ -27229,7 +27338,7 @@ async function handleInput(args) {
|
|
|
27229
27338
|
async function multiInput() {
|
|
27230
27339
|
try {
|
|
27231
27340
|
const configPath = getConfigPath();
|
|
27232
|
-
if (!
|
|
27341
|
+
if (!import_fs_extra23.default.pathExistsSync(configPath)) {
|
|
27233
27342
|
logError("Config file not found, please run init first");
|
|
27234
27343
|
return;
|
|
27235
27344
|
}
|
|
@@ -27286,6 +27395,24 @@ async function multiInput() {
|
|
|
27286
27395
|
}
|
|
27287
27396
|
}
|
|
27288
27397
|
|
|
27398
|
+
// src/cli/cli-core/plan.ts
|
|
27399
|
+
var import_path22 = __toESM(require("path"));
|
|
27400
|
+
async function handlePlan(args) {
|
|
27401
|
+
const input = args.join(" ");
|
|
27402
|
+
if (!input.trim()) {
|
|
27403
|
+
logError("Please enter content");
|
|
27404
|
+
return;
|
|
27405
|
+
}
|
|
27406
|
+
const skillPrompt = `\u4F7F\u7528SKILL-"planning-do"\u5C06\u7528\u6237\u4EFB\u52A1\u5206\u89E3\u5E76\u5B8C\u6210\uFF0C\u4EE5\u4E0B\u662F\u7528\u6237\u76EE\u6807\uFF1A${input}`;
|
|
27407
|
+
const skillPath = import_path22.default.join(__dirname, "./skills/planning-do.md");
|
|
27408
|
+
await handleInput([skillPrompt], [skillPath]);
|
|
27409
|
+
}
|
|
27410
|
+
|
|
27411
|
+
// src/cli/cli-plan.ts
|
|
27412
|
+
function registerPlanCommands(program) {
|
|
27413
|
+
program.command("plan-do").description("\u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u89E3\u4E3A\u5B50\u4EFB\u52A1\u5E76\u9010\u6B65\u6267\u884C\u5B8C\u6210").argument("[input...]", "\u4EFB\u52A1\u63CF\u8FF0").action((input) => handlePlan(input));
|
|
27414
|
+
}
|
|
27415
|
+
|
|
27289
27416
|
// src/cli/cli-input.ts
|
|
27290
27417
|
function registerInputCommand(program) {
|
|
27291
27418
|
program.argument("[inputs...]", "Natural language instruction or enter interactive mode").action(async (inputs) => {
|
|
@@ -27299,7 +27426,7 @@ function registerInputCommand(program) {
|
|
|
27299
27426
|
}
|
|
27300
27427
|
|
|
27301
27428
|
// src/cli/cli-core/cache.ts
|
|
27302
|
-
var
|
|
27429
|
+
var import_path23 = __toESM(require("path"));
|
|
27303
27430
|
var userCache2 = new UserCache();
|
|
27304
27431
|
function resolveId(input) {
|
|
27305
27432
|
const index = Number(input);
|
|
@@ -27333,7 +27460,7 @@ function handleCacheList() {
|
|
|
27333
27460
|
function handleCacheEdit(input) {
|
|
27334
27461
|
const id = resolveId(input);
|
|
27335
27462
|
if (!id) return;
|
|
27336
|
-
const filePath =
|
|
27463
|
+
const filePath = import_path23.default.join(getUserStorePath(), `${id}.md`);
|
|
27337
27464
|
editFile(filePath);
|
|
27338
27465
|
}
|
|
27339
27466
|
function handleCacheDel(input) {
|
|
@@ -27378,6 +27505,7 @@ function main() {
|
|
|
27378
27505
|
registerTaskCommands(program);
|
|
27379
27506
|
registerCommonFlags(program);
|
|
27380
27507
|
registerMcpCommands(program);
|
|
27508
|
+
registerPlanCommands(program);
|
|
27381
27509
|
registerCacheCommands(program);
|
|
27382
27510
|
registerHelpCommand(program);
|
|
27383
27511
|
registerInputCommand(program);
|
package/dist/serve/pm2-server.js
CHANGED
|
@@ -23510,20 +23510,17 @@ var import_fs_extra7 = __toESM(require("fs-extra"));
|
|
|
23510
23510
|
|
|
23511
23511
|
// src/agent/tools/subAgent.ts
|
|
23512
23512
|
var import_langchain4 = require("langchain");
|
|
23513
|
-
async function subAgentExec(prompt, runtime) {
|
|
23513
|
+
async function subAgentExec(systemPrompt, prompt, runtime) {
|
|
23514
23514
|
const curAgent = runtime.context?.curAgent;
|
|
23515
|
-
|
|
23516
|
-
throw new Error("\u5F53\u524D\u8FD0\u884C\u4E0A\u4E0B\u6587\u4E0D\u652F\u6301\u521B\u5EFA\u5B50 agent");
|
|
23517
|
-
}
|
|
23518
|
-
const subAgent = await curAgent.createSubAgent();
|
|
23519
|
-
return subAgent.execute(prompt);
|
|
23515
|
+
return curAgent && curAgent.subExecute(systemPrompt, prompt);
|
|
23520
23516
|
}
|
|
23521
23517
|
var subAgentTool = (0, import_langchain4.tool)(
|
|
23522
|
-
async ({ prompt }, runtime) => safeTool(() => subAgentExec(prompt, runtime)),
|
|
23518
|
+
async ({ systemPrompt, prompt }, runtime) => safeTool(() => subAgentExec(systemPrompt, prompt, runtime)),
|
|
23523
23519
|
{
|
|
23524
23520
|
name: "subAgent_exec",
|
|
23525
23521
|
description: "\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6765\u6267\u884C\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u5E76\u8FD4\u56DE\u5B50 agent \u7684\u6267\u884C\u7ED3\u679C\u3002\u9002\u5408\u62C6\u5206\u590D\u6742\u4EFB\u52A1\u3001\u5E76\u884C\u8C03\u7814\u6216\u59D4\u6D3E\u5B50\u4EFB\u52A1\u3002",
|
|
23526
23522
|
schema: external_exports.object({
|
|
23523
|
+
systemPrompt: external_exports.string().min(1).describe("\u5B50 agent \u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF0C\u5B9A\u4E49\u5176\u89D2\u8272\u548C\u884C\u4E3A\u89C4\u8303"),
|
|
23527
23524
|
prompt: external_exports.string().min(1).describe("\u4EA4\u7ED9\u901A\u7528\u5B50 agent \u6267\u884C\u7684\u5B8C\u6574\u4EFB\u52A1\u63CF\u8FF0")
|
|
23528
23525
|
})
|
|
23529
23526
|
}
|
|
@@ -23604,7 +23601,7 @@ var installPackageTool = (0, import_langchain5.tool)(
|
|
|
23604
23601
|
);
|
|
23605
23602
|
var executeJSCodeTool = (0, import_langchain5.tool)(async ({ code }, runtime) => safeTool(() => executeJSCode(code, runtime)), {
|
|
23606
23603
|
name: "execute_js_code",
|
|
23607
|
-
description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\
|
|
23604
|
+
description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A1.\u5982\u679C\u4EE3\u7801\u4E2D\u4F7F\u7528\u7B2C\u4E09\u65B9\u4F9D\u8D56\u5FC5\u987B\u5148\u4F7F\u7528check_package_installed\u5DE5\u5177\u68C0\u67E5\u5305\u662F\u5426\u5B89\u88C5\uFF0C\u5982\u679C\u672A\u5B89\u88C5\u9700\u8981\u6267\u884Cinstall_package\u5DE5\u5177\u5B89\u88C5\u6307\u5B9A\u7684npm\u5305;2.\u4EE3\u7801\u5FC5\u987B\u5305\u542B\u4E00\u4E2A__main()\u51FD\u6570\u4F5C\u4E3A\u6267\u884C\u5165\u53E3\uFF0C__main()\u51FD\u6570\u5185\u5FC5\u987B\u662F\u4E00\u4E2A\u4F7F\u7528async\u524D\u7F00\u7684\u51FD\u6570\u3002
|
|
23608
23605
|
\u53EF\u7528\u5185\u7F6E\u51FD\u6570\uFF1A
|
|
23609
23606
|
- agentExec(prompt: string): Promise<string>\uFF0C\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6267\u884C\u6307\u5B9A\u4EFB\u52A1\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF0C\u9002\u5408\u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u5206\u7ED9\u5B50 agent \u5B8C\u6210\u3002
|
|
23610
23607
|
\u793A\u4F8B\u4EE3\u7801\uFF1A
|
|
@@ -24218,7 +24215,10 @@ Commands:
|
|
|
24218
24215
|
ai skills generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u6280\u80FD\u6A21\u677F
|
|
24219
24216
|
|
|
24220
24217
|
# Tools commands
|
|
24218
|
+
ai tools ls \u67E5\u770B\u5DF2\u5B89\u88C5\u6216\u5DF2\u914D\u7F6E\u7684\u5DE5\u5177\u5217\u8868
|
|
24221
24219
|
ai tools dir \u6253\u5F00\u6216\u8F93\u51FA\u7528\u6237\u81EA\u5B9A\u4E49\u5DE5\u5177\u76EE\u5F55
|
|
24220
|
+
ai tools add <name> \u6DFB\u52A0\u6307\u5B9A\u540D\u79F0\u7684\u5DE5\u5177
|
|
24221
|
+
ai tools del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u81EA\u5B9A\u4E49\u5DE5\u5177
|
|
24222
24222
|
ai tools generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u5DE5\u5177\u6A21\u677F
|
|
24223
24223
|
|
|
24224
24224
|
# Session commands
|
|
@@ -24230,9 +24230,15 @@ Commands:
|
|
|
24230
24230
|
ai task add <task> \u5411\u4EFB\u52A1\u961F\u5217\u6DFB\u52A0\u4E00\u4E2A\u540E\u7EED\u4EFB\u52A1
|
|
24231
24231
|
ai task del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u4EFB\u52A1
|
|
24232
24232
|
ai task clear \u6E05\u7A7A\u5F53\u524D\u4EFB\u52A1\u961F\u5217
|
|
24233
|
+
|
|
24234
|
+
# Plan commands
|
|
24235
|
+
ai plan-do <\u4EFB\u52A1\u63CF\u8FF0> \u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u89E3\u4E3A\u5B50\u4EFB\u52A1\u5E76\u9010\u6B65\u6267\u884C\u5B8C\u6210
|
|
24233
24236
|
|
|
24234
24237
|
# MCP commands
|
|
24235
24238
|
ai mcp edit \u6253\u5F00 MCP \u914D\u7F6E\u6587\u4EF6\u8FDB\u884C\u7F16\u8F91
|
|
24239
|
+
ai mcp ls \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u5668\u5217\u8868
|
|
24240
|
+
ai mcp enable <name|index> \u542F\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
24241
|
+
ai mcp disable <name|index> \u7981\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
24236
24242
|
|
|
24237
24243
|
# Serve commands
|
|
24238
24244
|
ai serve \u542F\u52A8\u670D\u52A1\u6216\u8FDB\u5165\u670D\u52A1\u7BA1\u7406\u5165\u53E3
|
|
@@ -18,7 +18,7 @@ homepage: ''
|
|
|
18
18
|
|
|
19
19
|
1. **目录创建**:在当前工作目录下新建一个子目录,目录名称应简洁明了地反映 Skill 功能(如 `web-scraper`、`code-reviewer`、`image-optimizer` 等)
|
|
20
20
|
2. **核心文件**:目录中必须包含 `SKILL.md` 文件(文件名大小写敏感,必须为 `SKILL.md`)
|
|
21
|
-
3. **辅助文件**:如果 Skill 涉及复杂逻辑,可在目录中创建辅助脚本文件(如 `.js`、`.sh`、`.py` 等),并在 `SKILL.md` 中说明其用途和调用方式;如果是 js 文件,可以在函数中通过 `this.Tools` 调用内置函数,如直接使用 `this.Tools.createSubAgent(workGoal)`
|
|
21
|
+
3. **辅助文件**:如果 Skill 涉及复杂逻辑,可在目录中创建辅助脚本文件(如 `.js`、`.sh`、`.py` 等),并在 `SKILL.md` 中说明其用途和调用方式;如果是 js 文件,可以在函数中通过 `this.Tools` 调用内置函数,如直接使用 `this.Tools.createSubAgent(systemPrompt:string, workGoal:string)`
|
|
22
22
|
|
|
23
23
|
#### 标准目录结构
|
|
24
24
|
|
|
@@ -85,7 +85,7 @@ module.exports = { functions, descriptions };
|
|
|
85
85
|
1. 理解用户要生成的工具功能
|
|
86
86
|
2. 在当前工作目录下创建 `deepfish-tool-{功能名}/` 目录
|
|
87
87
|
3. 编写 `index.js`,导出 `functions` 和 `descriptions`
|
|
88
|
-
4. 对于需要Agent参与的复杂任务,可以直接使用 `this.createSubAgent(prompt: string)` 创建子 Agent 执行任务,并将任务说明作为 `prompt` 传入
|
|
88
|
+
4. 对于需要Agent参与的复杂任务,可以直接使用 `this.createSubAgent(systemPrompt: string, prompt: string)` 创建子 Agent 执行任务,并将任务说明作为 `prompt` 传入
|
|
89
89
|
5. 需要引入第三方模块时,需要将该tool创建成NodeJs项目,在tool中引入模块
|
|
90
90
|
|
|
91
91
|
## 生成说明文档
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 'planning-do'
|
|
3
|
+
description: '将复杂长任务拆分为子任务,通过子 Agent 逐步执行完成'
|
|
4
|
+
homepage: ''
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 长任务规划执行 Skill
|
|
8
|
+
|
|
9
|
+
当你收到一个复杂的长任务时,使用本 Skill 将其拆分为可执行的子任务,并通过子 Agent 逐步执行完成。
|
|
10
|
+
|
|
11
|
+
## 工作流程
|
|
12
|
+
|
|
13
|
+
整个流程分为两个阶段,**必须按顺序执行**:
|
|
14
|
+
|
|
15
|
+
### 阶段一:创建任务列表
|
|
16
|
+
|
|
17
|
+
创建一个子 Agent,传入以下系统提示词,让子 Agent 负责将用户目标拆解为子任务:
|
|
18
|
+
|
|
19
|
+
**子 Agent 系统提示词:**
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
你是任务分析专家,负责将用户的目标拆解为可执行的子任务。
|
|
23
|
+
|
|
24
|
+
工作流程:
|
|
25
|
+
1. 分析用户的任务描述,判断是否足够清晰具体;
|
|
26
|
+
2. 如果用户描述模糊、缺少关键信息或存在多种可能性,**必须与用户交互来收敛需求**:
|
|
27
|
+
- 使用选择题方式让用户选择(如:"项目类型是 A. 前端项目 B. 后端项目 C. 全栈项目?")
|
|
28
|
+
- 结合输入框让用户补充具体信息(如:"请描述项目的核心功能")
|
|
29
|
+
- 一次最多问8个问题,避免一次性问太多
|
|
30
|
+
- 持续交互直到需求足够清晰,能够拆解为具体的子任务
|
|
31
|
+
3. 将收敛后的完整需求作为用户的原始任务描述;
|
|
32
|
+
4. 在当前目录创建 tmp_task_goal.md,记录收敛后的完整需求描述;
|
|
33
|
+
5. 创建 tmp_tasklist.json,包含拆解后的子任务列表。
|
|
34
|
+
|
|
35
|
+
tmp_tasklist.json 格式要求:
|
|
36
|
+
- 必须是合法的 JSON 数组
|
|
37
|
+
- 每个任务对象包含以下字段:
|
|
38
|
+
- id: 任务唯一标识(字符串或数字)
|
|
39
|
+
- name: 任务名称(简洁明了)
|
|
40
|
+
- description: 任务详细说明
|
|
41
|
+
- status: 任务状态,初始为 "todo"
|
|
42
|
+
- createdAt: 创建时间(ISO 字符串)
|
|
43
|
+
- finishedAt: 完成时间(未完成时为 null)
|
|
44
|
+
- note: 备注(可为空字符串)
|
|
45
|
+
|
|
46
|
+
拆分原则:
|
|
47
|
+
- 任务尽量原子化,每个任务只做一件事
|
|
48
|
+
- 任务之间尽量独立,减少依赖
|
|
49
|
+
- 按执行顺序排列
|
|
50
|
+
|
|
51
|
+
输出要求:仅输出合法 JSON,不要输出解释文字。
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**子 Agent 的用户提示词:** 用户的原始任务描述。
|
|
55
|
+
|
|
56
|
+
### 阶段二:执行任务列表
|
|
57
|
+
|
|
58
|
+
创建一个子 Agent,传入以下系统提示词,让子 Agent 负责按顺序执行子任务:
|
|
59
|
+
|
|
60
|
+
**子 Agent 系统提示词:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
你负责按顺序执行 tmp_tasklist.json 中的子任务,完成 tmp_task_goal.md 描述的整体目标。
|
|
64
|
+
|
|
65
|
+
执行规则:
|
|
66
|
+
1. 先读取 tmp_task_goal.md 了解整体目标;
|
|
67
|
+
2. 读取 tmp_tasklist.json,仅处理 status 为 "todo" 或 "doing" 的任务;
|
|
68
|
+
3. 每次只执行一个子任务,按列表顺序依次执行;
|
|
69
|
+
4. 执行前将当前任务 status 更新为 "doing" 并写回文件;
|
|
70
|
+
5. 执行成功后更新 status 为 "done",并记录 finishedAt(ISO 时间);
|
|
71
|
+
6. 执行失败时保留为 "doing" 或回退为 "todo",在 note 中记录失败原因;
|
|
72
|
+
7. 每完成一个子任务必须立即写回 tmp_tasklist.json;
|
|
73
|
+
8. 尽量将具体执行工作交给子 agent 完成,主流程只负责调度和状态管理;
|
|
74
|
+
9. 告知子 agent 任务列表的文件名为 tmp_tasklist.json;
|
|
75
|
+
10. 全部任务完成后,删除 tmp_tasklist.json 和 tmp_task_goal.md。
|
|
76
|
+
|
|
77
|
+
输出要求:
|
|
78
|
+
- 输出当前执行的任务 id、名称、结果状态和下一步计划;
|
|
79
|
+
- 不要跳过状态更新和文件写入步骤。
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**子 Agent 的用户提示词:** 用户的原始任务描述。
|
|
83
|
+
|
|
84
|
+
## 注意事项
|
|
85
|
+
|
|
86
|
+
1. **必须分两个阶段执行**:先创建任务列表,再执行任务列表,不能合并
|
|
87
|
+
2. **子 Agent 只做一件事**:阶段一只负责拆解任务,阶段二只负责按顺序执行
|
|
88
|
+
3. **文件持久化**:任务状态通过 `tmp_tasklist.json` 文件持久化,子 Agent 崩溃后可以重新读取继续执行
|
|
89
|
+
4. **清理临时文件**:全部任务完成后必须删除 `tmp_tasklist.json` 和 `tmp_task_goal.md`
|
|
90
|
+
5. **原子化执行**:每个子任务只做一件事,执行完立即更新状态并写回文件
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepfish-ai",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "An efficient AI-driven command-line tool designed to bridge the gap between natural language and operating system commands, file operations, and more. It enables non-developers to quickly generate executable instructions through simple natural language descriptions, significantly improving terminal operation efficiency.",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dist/"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "tsup && npm run build:ui",
|
|
30
|
+
"build": "tsup && node -e \"const fs=require('fs-extra'),p=require('path');const src=p.join(process.cwd(),'src/agent/skills'),dst=p.join(process.cwd(),'dist/skills');fs.ensureDirSync(dst);fs.readdirSync(src).filter(f=>f.endsWith('.md')).forEach(f=>fs.copySync(p.join(src,f),p.join(dst,f)))\" && npm run build:ui",
|
|
31
31
|
"build:ui": "vite build && vite build --config vite.server.config.ts",
|
|
32
32
|
"dev": "tsx src/cli/index.ts",
|
|
33
33
|
"format": "prettier --write \"src/**/*.{ts,js,json,css,md}\"",
|
|
File without changes
|