deepfish-ai 2.0.11 → 2.0.13
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 +14 -3
- package/dist/index.js +296 -132
- package/dist/serve/pm2-server.js +15 -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 +94 -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,21 @@ ai "我刚问了一个什么问题"
|
|
|
183
184
|
| `ai tasks del <index>` | 删除指定任务 |
|
|
184
185
|
| `ai tasks clear` | 清除所有任务 |
|
|
185
186
|
|
|
187
|
+
### 长任务规划
|
|
188
|
+
|
|
189
|
+
| 命令 | 说明 |
|
|
190
|
+
| ------------------------- | ------------------------------------------ |
|
|
191
|
+
| `ai plan-do <任务描述>` | 将复杂任务拆解为子任务并逐步执行完成 |
|
|
192
|
+
| `ai plan-continue` | 继续执行被中断的 plan-do 任务 |
|
|
193
|
+
|
|
186
194
|
### MCP 管理
|
|
187
195
|
|
|
188
|
-
| 命令
|
|
189
|
-
|
|
|
190
|
-
| `ai mcp
|
|
196
|
+
| 命令 | 说明 |
|
|
197
|
+
| --------------------------------- | ---------------- |
|
|
198
|
+
| `ai mcp ls` | 列出所有 MCP 服务器 |
|
|
199
|
+
| `ai mcp edit` | 编辑 MCP 配置 |
|
|
200
|
+
| `ai mcp enable <name\|index>` | 启用 MCP 服务器 |
|
|
201
|
+
| `ai mcp disable <name\|index>` | 禁用 MCP 服务器 |
|
|
191
202
|
|
|
192
203
|
### 服务管理
|
|
193
204
|
|
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,16 @@ 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
|
|
25772
|
+
ai plan-continue \u7EE7\u7EED\u6267\u884C\u88AB\u4E2D\u65AD\u7684 plan-do \u4EFB\u52A1
|
|
25746
25773
|
|
|
25747
25774
|
# MCP commands
|
|
25748
25775
|
ai mcp edit \u6253\u5F00 MCP \u914D\u7F6E\u6587\u4EF6\u8FDB\u884C\u7F16\u8F91
|
|
25776
|
+
ai mcp ls \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u5668\u5217\u8868
|
|
25777
|
+
ai mcp enable <name|index> \u542F\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
25778
|
+
ai mcp disable <name|index> \u7981\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
25749
25779
|
|
|
25750
25780
|
# Serve commands
|
|
25751
25781
|
ai serve \u542F\u52A8\u670D\u52A1\u6216\u8FDB\u5165\u670D\u52A1\u7BA1\u7406\u5165\u53E3
|
|
@@ -25833,14 +25863,14 @@ var builtinTools = [
|
|
|
25833
25863
|
...learnTools,
|
|
25834
25864
|
...fishInfoTools
|
|
25835
25865
|
];
|
|
25836
|
-
async function getTools(excludeTools, excludeMCP) {
|
|
25837
|
-
return [...builtinTools, ...await scanUserTools(excludeTools), ...await scanUserMcp(excludeMCP)];
|
|
25866
|
+
async function getTools(excludeTools, excludeMCP, externalTools = []) {
|
|
25867
|
+
return [...builtinTools, ...await scanUserTools(excludeTools, externalTools), ...await scanUserMcp(excludeMCP)];
|
|
25838
25868
|
}
|
|
25839
25869
|
|
|
25840
25870
|
// src/agent/skills/index.ts
|
|
25841
25871
|
var import_path17 = __toESM(require("path"));
|
|
25842
25872
|
function getSkills() {
|
|
25843
|
-
return [...getRegisteredSkills(), import_path17.default.join(__dirname, "./view-learn-cache.md")];
|
|
25873
|
+
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
25874
|
}
|
|
25845
25875
|
|
|
25846
25876
|
// src/agent/AIAgent/index.ts
|
|
@@ -25897,8 +25927,8 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25897
25927
|
if (this.subLevel > 2) {
|
|
25898
25928
|
this.excludeTools.push("subAgent_exec");
|
|
25899
25929
|
}
|
|
25900
|
-
this.tools = await getTools(this.excludeTools, this.excludeMCP);
|
|
25901
|
-
this.skills = [...getSkills(), ...this.opt.
|
|
25930
|
+
this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
|
|
25931
|
+
this.skills = [...getSkills(), ...this.opt.externalSkills || []];
|
|
25902
25932
|
const model = getModel(this.opt.modelOpt);
|
|
25903
25933
|
const checkpointer = new FileSystemSaver({
|
|
25904
25934
|
rootFolder: this.sessionDirPath
|
|
@@ -25919,7 +25949,13 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25919
25949
|
memoryFilePath: this.memoryFilePath,
|
|
25920
25950
|
agentRulesPath: this.agentRulesPath,
|
|
25921
25951
|
excludeSkills: this.excludeSkills
|
|
25922
|
-
}) : subSystemPrompt(
|
|
25952
|
+
}) : subSystemPrompt({
|
|
25953
|
+
systemPrompt: this.systemPrompt,
|
|
25954
|
+
workspace: this.workspace,
|
|
25955
|
+
osType: import_os3.default.platform(),
|
|
25956
|
+
skills: this.skills,
|
|
25957
|
+
excludeSkills: this.excludeSkills
|
|
25958
|
+
});
|
|
25923
25959
|
const agent = (0, import_langchain18.createAgent)({
|
|
25924
25960
|
model,
|
|
25925
25961
|
checkpointer,
|
|
@@ -25932,14 +25968,6 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25932
25968
|
trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
|
|
25933
25969
|
keep: { messages: 50 }
|
|
25934
25970
|
}),
|
|
25935
|
-
(0, import_langchain18.humanInTheLoopMiddleware)({
|
|
25936
|
-
interruptOn: {
|
|
25937
|
-
install_package: {
|
|
25938
|
-
allowedDecisions: ["approve", "reject"]
|
|
25939
|
-
},
|
|
25940
|
-
readEmailTool: false
|
|
25941
|
-
}
|
|
25942
|
-
}),
|
|
25943
25971
|
(0, import_langchain18.todoListMiddleware)(),
|
|
25944
25972
|
(0, import_deepagents.createPatchToolCallsMiddleware)()
|
|
25945
25973
|
],
|
|
@@ -25974,6 +26002,9 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
|
|
|
25974
26002
|
resolve(msg);
|
|
25975
26003
|
});
|
|
25976
26004
|
for await (const [_namespace, mode, data] of stream) {
|
|
26005
|
+
if (Array.isArray(_namespace) && _namespace.length > 0) {
|
|
26006
|
+
continue;
|
|
26007
|
+
}
|
|
25977
26008
|
if (mode === "messages") {
|
|
25978
26009
|
const message = data[0].additional_kwargs.reasoning_content;
|
|
25979
26010
|
this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, message);
|
|
@@ -26089,8 +26120,8 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26089
26120
|
this.maxSubAgentCount = opt.maxSubAgentCount || 2;
|
|
26090
26121
|
}
|
|
26091
26122
|
async init() {
|
|
26092
|
-
this.tools = await getTools(this.excludeTools, this.excludeMCP);
|
|
26093
|
-
this.skills = [...getSkills(), ...this.opt.
|
|
26123
|
+
this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
|
|
26124
|
+
this.skills = [...getSkills(), ...this.opt.externalSkills || []];
|
|
26094
26125
|
const model = getModel(this.opt.modelOpt);
|
|
26095
26126
|
const checkpointer = new FileSystemSaver({
|
|
26096
26127
|
rootFolder: this.sessionDirPath
|
|
@@ -26115,14 +26146,6 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26115
26146
|
trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
|
|
26116
26147
|
keep: { messages: 50 }
|
|
26117
26148
|
}),
|
|
26118
|
-
(0, import_langchain19.humanInTheLoopMiddleware)({
|
|
26119
|
-
interruptOn: {
|
|
26120
|
-
install_package: {
|
|
26121
|
-
allowedDecisions: ["approve", "reject"]
|
|
26122
|
-
},
|
|
26123
|
-
readEmailTool: false
|
|
26124
|
-
}
|
|
26125
|
-
}),
|
|
26126
26149
|
(0, import_langchain19.todoListMiddleware)(),
|
|
26127
26150
|
(0, import_deepagents2.createPatchToolCallsMiddleware)()
|
|
26128
26151
|
],
|
|
@@ -26162,6 +26185,9 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26162
26185
|
}
|
|
26163
26186
|
);
|
|
26164
26187
|
for await (const [_namespace, mode, data] of stream) {
|
|
26188
|
+
if (Array.isArray(_namespace) && _namespace.length > 0) {
|
|
26189
|
+
continue;
|
|
26190
|
+
}
|
|
26165
26191
|
if (mode === "messages") {
|
|
26166
26192
|
const message = data?.[0];
|
|
26167
26193
|
const reasoning_content = message?.additional_kwargs?.reasoning_content;
|
|
@@ -26227,11 +26253,16 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
|
|
|
26227
26253
|
this.on("USE_TOOL_AFTER" /* USE_TOOL_AFTER */, (_toolId, _funcName, _funcArgs) => {
|
|
26228
26254
|
});
|
|
26229
26255
|
}
|
|
26230
|
-
async createSubAgent() {
|
|
26256
|
+
async createSubAgent(systemPrompt) {
|
|
26231
26257
|
const subAgent = new SubAIAgent(this.opt);
|
|
26258
|
+
systemPrompt && (subAgent.systemPrompt = systemPrompt);
|
|
26232
26259
|
await subAgent.init();
|
|
26233
26260
|
return subAgent;
|
|
26234
26261
|
}
|
|
26262
|
+
async subExecute(systemPrompt, prompt) {
|
|
26263
|
+
const subAgent = await this.createSubAgent(systemPrompt);
|
|
26264
|
+
return subAgent.execute(prompt);
|
|
26265
|
+
}
|
|
26235
26266
|
destory() {
|
|
26236
26267
|
this.removeAllListeners();
|
|
26237
26268
|
}
|
|
@@ -26484,7 +26515,7 @@ async function initAgent(config2, skills) {
|
|
|
26484
26515
|
// CLI encoding format, can be set to utf-8, gbk, etc., or left empty for auto-detection
|
|
26485
26516
|
maxSubAgentCount: config2.maxSubAgentCount,
|
|
26486
26517
|
// Maximum parallel sub-agent execution count, -1 means unlimited
|
|
26487
|
-
skills,
|
|
26518
|
+
externalSkills: skills,
|
|
26488
26519
|
isPrintThinking: config2.isPrintThinking
|
|
26489
26520
|
// Whether to print intermediate information during AI thinking, default is true
|
|
26490
26521
|
});
|
|
@@ -26680,7 +26711,11 @@ function handleSkillsLs() {
|
|
|
26680
26711
|
logInfo("No skills registered yet");
|
|
26681
26712
|
} else {
|
|
26682
26713
|
skills.forEach((skill, index) => {
|
|
26683
|
-
|
|
26714
|
+
if (skill.isEnabled) {
|
|
26715
|
+
logSuccess(`[${index}] ${skill.name} [\u221A]`);
|
|
26716
|
+
} else {
|
|
26717
|
+
logInfo(`[${index}] ${skill.name} [\xD7]`);
|
|
26718
|
+
}
|
|
26684
26719
|
});
|
|
26685
26720
|
}
|
|
26686
26721
|
logInfo("=".repeat(50));
|
|
@@ -26814,7 +26849,7 @@ async function handleSkillsGenerate(target) {
|
|
|
26814
26849
|
logError("Failed to start service, please check config or port availability");
|
|
26815
26850
|
return;
|
|
26816
26851
|
}
|
|
26817
|
-
const generateSkillPath = import_path20.default.join(__dirname, "./generate-skill.md");
|
|
26852
|
+
const generateSkillPath = import_path20.default.join(__dirname, "./skills/generate-skill.md");
|
|
26818
26853
|
const agent = await initAgent(config2, [generateSkillPath]);
|
|
26819
26854
|
const prompt = `\u8BF7\u6839\u636E\u4EE5\u4E0B\u9700\u6C42\u751F\u6210\u4E00\u4E2ASkill\u6A21\u5757\uFF1A${target}
|
|
26820
26855
|
|
|
@@ -26848,11 +26883,13 @@ function _scanSkills(skillsDir) {
|
|
|
26848
26883
|
}
|
|
26849
26884
|
function _updateRegister(skillsDir) {
|
|
26850
26885
|
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)) {
|
|
26886
|
+
if (!import_fs_extra20.default.existsSync(skillsDir)) {
|
|
26854
26887
|
return;
|
|
26855
26888
|
}
|
|
26889
|
+
if (!import_fs_extra20.default.existsSync(registerPath)) {
|
|
26890
|
+
import_fs_extra20.default.ensureDirSync(import_path20.default.dirname(registerPath));
|
|
26891
|
+
import_fs_extra20.default.writeJSONSync(registerPath, [], { spaces: 2 });
|
|
26892
|
+
}
|
|
26856
26893
|
const skills = _scanSkills(skillsDir);
|
|
26857
26894
|
let register = import_fs_extra20.default.readJSONSync(registerPath);
|
|
26858
26895
|
const newRegister = [];
|
|
@@ -26860,11 +26897,15 @@ function _updateRegister(skillsDir) {
|
|
|
26860
26897
|
const skillName = import_path20.default.basename(skillPath);
|
|
26861
26898
|
const existItem = register.find((item) => item.skillPath === skillPath);
|
|
26862
26899
|
if (!existItem) {
|
|
26900
|
+
let skillFilePath = skillPath;
|
|
26901
|
+
if (import_fs_extra20.default.statSync(skillPath).isDirectory()) {
|
|
26902
|
+
skillFilePath = import_path20.default.join(skillFilePath, "SKILL.md");
|
|
26903
|
+
}
|
|
26863
26904
|
newRegister.push({
|
|
26864
26905
|
id: (0, import_crypto6.randomUUID)(),
|
|
26865
26906
|
name: skillName,
|
|
26866
26907
|
isEnabled: true,
|
|
26867
|
-
skillPath
|
|
26908
|
+
skillPath: skillFilePath
|
|
26868
26909
|
});
|
|
26869
26910
|
}
|
|
26870
26911
|
});
|
|
@@ -26876,8 +26917,9 @@ function getRegisteredSkills() {
|
|
|
26876
26917
|
const scanPaths = getScanDirPaths();
|
|
26877
26918
|
const skills = [];
|
|
26878
26919
|
scanPaths.forEach((scanPath) => {
|
|
26879
|
-
|
|
26880
|
-
|
|
26920
|
+
const scanDir = import_path20.default.join(scanPath, "skills");
|
|
26921
|
+
_updateRegister(scanDir);
|
|
26922
|
+
const registerPath = _getRegisterPath(scanDir);
|
|
26881
26923
|
if (import_fs_extra20.default.existsSync(registerPath)) {
|
|
26882
26924
|
const register = import_fs_extra20.default.readJSONSync(registerPath);
|
|
26883
26925
|
register.forEach((item) => {
|
|
@@ -26903,7 +26945,8 @@ function _getAllSkills() {
|
|
|
26903
26945
|
const scanPaths = getScanDirPaths();
|
|
26904
26946
|
let allSkills = [];
|
|
26905
26947
|
scanPaths.forEach((scanPath) => {
|
|
26906
|
-
const
|
|
26948
|
+
const scanDir = import_path20.default.join(scanPath, "skills");
|
|
26949
|
+
const skills = _getSkillList(scanDir);
|
|
26907
26950
|
skills.map((item) => {
|
|
26908
26951
|
item.skillDir = scanPath;
|
|
26909
26952
|
return item;
|
|
@@ -26913,10 +26956,12 @@ function _getAllSkills() {
|
|
|
26913
26956
|
return allSkills;
|
|
26914
26957
|
}
|
|
26915
26958
|
function _getRegisterPath(skillsDir) {
|
|
26916
|
-
|
|
26917
|
-
|
|
26959
|
+
const normalizedDir = import_path20.default.normalize(skillsDir);
|
|
26960
|
+
const baseName = import_path20.default.basename(normalizedDir).toLowerCase();
|
|
26961
|
+
if (baseName === "@deepfish-ai" || baseName === "skills") {
|
|
26962
|
+
return import_path20.default.join(normalizedDir, "register.json");
|
|
26918
26963
|
}
|
|
26919
|
-
return import_path20.default.join(
|
|
26964
|
+
return import_path20.default.join(normalizedDir, "skills", "register.json");
|
|
26920
26965
|
}
|
|
26921
26966
|
|
|
26922
26967
|
// src/cli/cli-skills.ts
|
|
@@ -27034,7 +27079,7 @@ async function handleToolsGenerate(target) {
|
|
|
27034
27079
|
logError("Failed to start service, please check config or port availability");
|
|
27035
27080
|
return;
|
|
27036
27081
|
}
|
|
27037
|
-
const generateSkillPath = import_path21.default.join(__dirname, "./generate-tool.md");
|
|
27082
|
+
const generateSkillPath = import_path21.default.join(__dirname, "./skills/generate-tool.md");
|
|
27038
27083
|
const agent = await initAgent(config2, [generateSkillPath]);
|
|
27039
27084
|
const prompt = `Please use the "generate-tool" SKILL to generate a tool module according to the following requirements: ${target}
|
|
27040
27085
|
|
|
@@ -27170,21 +27215,92 @@ function registerTaskCommands(program) {
|
|
|
27170
27215
|
}
|
|
27171
27216
|
|
|
27172
27217
|
// src/cli/cli-core/mcp.ts
|
|
27218
|
+
var import_fs_extra22 = __toESM(require("fs-extra"));
|
|
27173
27219
|
function handleMcpEdit() {
|
|
27174
27220
|
const mcpPath = getMCPFilePath();
|
|
27175
27221
|
editFile(mcpPath);
|
|
27176
27222
|
}
|
|
27223
|
+
function readMcpConfig() {
|
|
27224
|
+
const mcpPath = getMCPFilePath();
|
|
27225
|
+
return import_fs_extra22.default.readJSONSync(mcpPath);
|
|
27226
|
+
}
|
|
27227
|
+
function writeMcpConfig(data) {
|
|
27228
|
+
const mcpPath = getMCPFilePath();
|
|
27229
|
+
import_fs_extra22.default.writeJSONSync(mcpPath, data, { spaces: 2 });
|
|
27230
|
+
}
|
|
27231
|
+
function handleMcpLs() {
|
|
27232
|
+
const config2 = readMcpConfig();
|
|
27233
|
+
const servers = config2.mcpServers || {};
|
|
27234
|
+
const entries = Object.entries(servers);
|
|
27235
|
+
if (entries.length === 0) {
|
|
27236
|
+
logWarning("No MCP servers configured yet");
|
|
27237
|
+
return;
|
|
27238
|
+
}
|
|
27239
|
+
logInfo("=".repeat(50));
|
|
27240
|
+
entries.forEach(([name, server], index) => {
|
|
27241
|
+
const disabled = server.disabled === true;
|
|
27242
|
+
if (disabled) {
|
|
27243
|
+
logInfo(`[${index}] ${name} [\xD7]`);
|
|
27244
|
+
} else {
|
|
27245
|
+
logSuccess(`[${index}] ${name} [\u221A]`);
|
|
27246
|
+
}
|
|
27247
|
+
});
|
|
27248
|
+
logInfo("=".repeat(50));
|
|
27249
|
+
}
|
|
27250
|
+
function handleMcpEnable(nameOrIndex) {
|
|
27251
|
+
const config2 = readMcpConfig();
|
|
27252
|
+
const servers = config2.mcpServers || {};
|
|
27253
|
+
const entries = Object.keys(servers);
|
|
27254
|
+
let targetIndex = -1;
|
|
27255
|
+
const index = parseInt(nameOrIndex, 10);
|
|
27256
|
+
if (!isNaN(index) && index >= 0 && index < entries.length) {
|
|
27257
|
+
targetIndex = index;
|
|
27258
|
+
} else {
|
|
27259
|
+
targetIndex = entries.findIndex((name) => name === nameOrIndex);
|
|
27260
|
+
}
|
|
27261
|
+
if (targetIndex === -1) {
|
|
27262
|
+
logError(`MCP server not found: ${nameOrIndex}`);
|
|
27263
|
+
return;
|
|
27264
|
+
}
|
|
27265
|
+
const serverName = entries[targetIndex];
|
|
27266
|
+
servers[serverName].disabled = false;
|
|
27267
|
+
writeMcpConfig(config2);
|
|
27268
|
+
logSuccess(`MCP server "${serverName}" enabled`);
|
|
27269
|
+
}
|
|
27270
|
+
function handleMcpDisable(nameOrIndex) {
|
|
27271
|
+
const config2 = readMcpConfig();
|
|
27272
|
+
const servers = config2.mcpServers || {};
|
|
27273
|
+
const entries = Object.keys(servers);
|
|
27274
|
+
let targetIndex = -1;
|
|
27275
|
+
const index = parseInt(nameOrIndex, 10);
|
|
27276
|
+
if (!isNaN(index) && index >= 0 && index < entries.length) {
|
|
27277
|
+
targetIndex = index;
|
|
27278
|
+
} else {
|
|
27279
|
+
targetIndex = entries.findIndex((name) => name === nameOrIndex);
|
|
27280
|
+
}
|
|
27281
|
+
if (targetIndex === -1) {
|
|
27282
|
+
logError(`MCP server not found: ${nameOrIndex}`);
|
|
27283
|
+
return;
|
|
27284
|
+
}
|
|
27285
|
+
const serverName = entries[targetIndex];
|
|
27286
|
+
servers[serverName].disabled = true;
|
|
27287
|
+
writeMcpConfig(config2);
|
|
27288
|
+
logSuccess(`MCP server "${serverName}" disabled`);
|
|
27289
|
+
}
|
|
27177
27290
|
|
|
27178
27291
|
// src/cli/cli-mcp.ts
|
|
27179
27292
|
function registerMcpCommands(program) {
|
|
27180
27293
|
const mcp = program.command("mcp");
|
|
27181
27294
|
mcp.command("edit").description("\u7F16\u8F91 MCP \u914D\u7F6E\u6587\u4EF6").action(handleMcpEdit);
|
|
27295
|
+
mcp.command("ls").description("\u5217\u51FA\u6240\u6709 MCP \u670D\u52A1\u5668").action(handleMcpLs);
|
|
27296
|
+
mcp.command("enable <nameOrIndex>").description("\u542F\u7528 MCP \u670D\u52A1\u5668").action(handleMcpEnable);
|
|
27297
|
+
mcp.command("disable <nameOrIndex>").description("\u7981\u7528 MCP \u670D\u52A1\u5668").action(handleMcpDisable);
|
|
27182
27298
|
}
|
|
27183
27299
|
|
|
27184
27300
|
// src/cli/cli-core/input.ts
|
|
27185
|
-
var
|
|
27301
|
+
var import_fs_extra23 = __toESM(require("fs-extra"));
|
|
27186
27302
|
var readline = __toESM(require("readline"));
|
|
27187
|
-
async function handleInput(args) {
|
|
27303
|
+
async function handleInput(args, skills) {
|
|
27188
27304
|
const input = args.join(" ");
|
|
27189
27305
|
if (!input.trim()) {
|
|
27190
27306
|
logError("Please enter content");
|
|
@@ -27192,7 +27308,7 @@ async function handleInput(args) {
|
|
|
27192
27308
|
}
|
|
27193
27309
|
try {
|
|
27194
27310
|
const configPath = getConfigPath();
|
|
27195
|
-
if (!
|
|
27311
|
+
if (!import_fs_extra23.default.pathExistsSync(configPath)) {
|
|
27196
27312
|
logError("Config file not found, please run init first");
|
|
27197
27313
|
return;
|
|
27198
27314
|
}
|
|
@@ -27207,7 +27323,7 @@ async function handleInput(args) {
|
|
|
27207
27323
|
logError("Failed to start service, please check config or port availability");
|
|
27208
27324
|
return;
|
|
27209
27325
|
}
|
|
27210
|
-
const agent = await initAgent(config2);
|
|
27326
|
+
const agent = await initAgent(config2, skills);
|
|
27211
27327
|
const connResult = await connectAgentRoom(agent);
|
|
27212
27328
|
if (!connResult.ok) {
|
|
27213
27329
|
if (connResult.reason === "duplicate-id") {
|
|
@@ -27229,7 +27345,7 @@ async function handleInput(args) {
|
|
|
27229
27345
|
async function multiInput() {
|
|
27230
27346
|
try {
|
|
27231
27347
|
const configPath = getConfigPath();
|
|
27232
|
-
if (!
|
|
27348
|
+
if (!import_fs_extra23.default.pathExistsSync(configPath)) {
|
|
27233
27349
|
logError("Config file not found, please run init first");
|
|
27234
27350
|
return;
|
|
27235
27351
|
}
|
|
@@ -27286,6 +27402,53 @@ async function multiInput() {
|
|
|
27286
27402
|
}
|
|
27287
27403
|
}
|
|
27288
27404
|
|
|
27405
|
+
// src/cli/cli-core/plan.ts
|
|
27406
|
+
var import_path22 = __toESM(require("path"));
|
|
27407
|
+
async function handlePlan(args) {
|
|
27408
|
+
const input = args.join(" ");
|
|
27409
|
+
if (!input.trim()) {
|
|
27410
|
+
logError("Please enter content");
|
|
27411
|
+
return;
|
|
27412
|
+
}
|
|
27413
|
+
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}`;
|
|
27414
|
+
const skillPath = import_path22.default.join(__dirname, "./skills/planning-do.md");
|
|
27415
|
+
await handleInput([skillPrompt], [skillPath]);
|
|
27416
|
+
}
|
|
27417
|
+
async function handlePlanContinue() {
|
|
27418
|
+
const skillPrompt = `
|
|
27419
|
+
\u76EE\u524D\u4EFB\u52A1\u6267\u884C\u4E86\u4E00\u90E8\u5206\uFF0C\u9700\u8981\u7EE7\u7EED\u6267\u884C\u3002\u4F60\u8D1F\u8D23\u6309\u987A\u5E8F\u8C03\u5EA6\u6267\u884C tmp_tasklist.json \u4E2D\u7684\u5B50\u4EFB\u52A1\uFF0C\u5B8C\u6210 tmp_task_goal.md \u63CF\u8FF0\u7684\u6574\u4F53\u76EE\u6807\u3002
|
|
27420
|
+
|
|
27421
|
+
\u6267\u884C\u89C4\u5219\uFF1A
|
|
27422
|
+
1. \u5148\u8BFB\u53D6 tmp_task_goal.md \u4E86\u89E3\u6574\u4F53\u76EE\u6807\uFF1B
|
|
27423
|
+
2. \u8BFB\u53D6 tmp_tasklist.json\uFF0C\u4EC5\u5904\u7406 status \u4E3A "todo" \u6216 "doing" \u7684\u4EFB\u52A1\uFF1B
|
|
27424
|
+
3. \u6BCF\u6B21\u901A\u8FC7\u521B\u5EFA\u5B50Agent\u53EA\u8C03\u5EA6\u4E00\u4E2A\u5B50\u4EFB\u52A1\uFF0C\u6309\u5217\u8868\u987A\u5E8F\u4F9D\u6B21\u6267\u884C\uFF1B
|
|
27425
|
+
4. \u8C03\u5EA6\u524D\u5C06\u5F53\u524D\u4EFB\u52A1 status \u66F4\u65B0\u4E3A "doing" \u5E76\u5199\u56DE\u6587\u4EF6\uFF1B
|
|
27426
|
+
5. \u5BF9\u6BCF\u4E2A\u5B50\u4EFB\u52A1\uFF0C\u5FC5\u987B\u521B\u5EFA\u4E00\u4E2A\u72EC\u7ACB\u7684\u5B50 Agent \u6765\u6267\u884C\uFF0C\u4E0D\u8981\u5728\u4E3B\u6D41\u7A0B\u4E2D\u76F4\u63A5\u5B8C\u6210\u5177\u4F53\u4EFB\u52A1\uFF1B
|
|
27427
|
+
6. \u521B\u5EFA\u5B50 Agent \u65F6\uFF0C\u5C06\u6574\u4F53\u76EE\u6807\u3001\u5F53\u524D\u5B50\u4EFB\u52A1 id/name/description\u3001tmp_tasklist.json \u6587\u4EF6\u540D\u548C\u6267\u884C\u8981\u6C42\u4E00\u5E76\u4F20\u5165\uFF1B
|
|
27428
|
+
7. \u5B50 Agent \u6267\u884C\u6210\u529F\u540E\uFF0C\u5C06\u5F53\u524D\u4EFB\u52A1 status \u66F4\u65B0\u4E3A "done"\uFF0C\u5E76\u8BB0\u5F55 finishedAt\uFF08ISO \u65F6\u95F4\uFF09\uFF1B
|
|
27429
|
+
8. \u5B50 Agent \u6267\u884C\u5931\u8D25\u65F6\uFF0C\u5C06\u5F53\u524D\u4EFB\u52A1\u4FDD\u7559\u4E3A "doing" \u6216\u56DE\u9000\u4E3A "todo"\uFF0C\u5E76\u5728 note \u4E2D\u8BB0\u5F55\u5931\u8D25\u539F\u56E0\uFF1B
|
|
27430
|
+
9. \u6BCF\u5B8C\u6210\u6216\u5931\u8D25\u4E00\u4E2A\u5B50\u4EFB\u52A1\uFF0C\u90FD\u5FC5\u987B\u7ACB\u5373\u5199\u56DE tmp_tasklist.json\uFF1B
|
|
27431
|
+
10. \u5168\u90E8\u4EFB\u52A1\u5B8C\u6210\u540E\uFF0C\u5220\u9664 tmp_tasklist.json \u548C tmp_task_goal.md\u3002
|
|
27432
|
+
|
|
27433
|
+
\u5B50 Agent \u6267\u884C\u8981\u6C42\uFF1A
|
|
27434
|
+
- \u53EA\u6267\u884C\u5F53\u524D\u88AB\u5206\u914D\u7684\u4E00\u4E2A\u5B50\u4EFB\u52A1\uFF0C\u4E0D\u8981\u4FEE\u6539\u5176\u4ED6\u4EFB\u52A1\u72B6\u6001\uFF1B
|
|
27435
|
+
- \u6267\u884C\u524D\u9605\u8BFB tmp_task_goal.md\uFF0C\u7406\u89E3\u6574\u4F53\u76EE\u6807\uFF1B
|
|
27436
|
+
- \u5FC5\u8981\u65F6\u9605\u8BFB tmp_tasklist.json\uFF0C\u4E86\u89E3\u4E0A\u4E0B\u6587\u548C\u4EFB\u52A1\u4F9D\u8D56\uFF1B
|
|
27437
|
+
- \u5B8C\u6210\u540E\u5411\u4E3B Agent \u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3001\u4FEE\u6539\u7684\u6587\u4EF6\u3001\u5931\u8D25\u539F\u56E0\u6216\u540E\u7EED\u5EFA\u8BAE\u3002
|
|
27438
|
+
|
|
27439
|
+
\u8F93\u51FA\u8981\u6C42\uFF1A
|
|
27440
|
+
- \u8F93\u51FA\u5F53\u524D\u8C03\u5EA6\u7684\u4EFB\u52A1 id\u3001\u540D\u79F0\u3001\u6267\u884C\u7ED3\u679C\u72B6\u6001\u548C\u4E0B\u4E00\u6B65\u8BA1\u5212\uFF1B
|
|
27441
|
+
- \u4E0D\u8981\u8DF3\u8FC7\u72B6\u6001\u66F4\u65B0\u548C\u6587\u4EF6\u5199\u5165\u6B65\u9AA4\u3002
|
|
27442
|
+
`;
|
|
27443
|
+
await handleInput([skillPrompt]);
|
|
27444
|
+
}
|
|
27445
|
+
|
|
27446
|
+
// src/cli/cli-plan.ts
|
|
27447
|
+
function registerPlanCommands(program) {
|
|
27448
|
+
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));
|
|
27449
|
+
program.command("plan-continue").description("\u7EE7\u7EED\u6267\u884C\u88AB\u4E2D\u65AD\u7684 plan-do \u4EFB\u52A1").action(() => handlePlanContinue());
|
|
27450
|
+
}
|
|
27451
|
+
|
|
27289
27452
|
// src/cli/cli-input.ts
|
|
27290
27453
|
function registerInputCommand(program) {
|
|
27291
27454
|
program.argument("[inputs...]", "Natural language instruction or enter interactive mode").action(async (inputs) => {
|
|
@@ -27299,7 +27462,7 @@ function registerInputCommand(program) {
|
|
|
27299
27462
|
}
|
|
27300
27463
|
|
|
27301
27464
|
// src/cli/cli-core/cache.ts
|
|
27302
|
-
var
|
|
27465
|
+
var import_path23 = __toESM(require("path"));
|
|
27303
27466
|
var userCache2 = new UserCache();
|
|
27304
27467
|
function resolveId(input) {
|
|
27305
27468
|
const index = Number(input);
|
|
@@ -27333,7 +27496,7 @@ function handleCacheList() {
|
|
|
27333
27496
|
function handleCacheEdit(input) {
|
|
27334
27497
|
const id = resolveId(input);
|
|
27335
27498
|
if (!id) return;
|
|
27336
|
-
const filePath =
|
|
27499
|
+
const filePath = import_path23.default.join(getUserStorePath(), `${id}.md`);
|
|
27337
27500
|
editFile(filePath);
|
|
27338
27501
|
}
|
|
27339
27502
|
function handleCacheDel(input) {
|
|
@@ -27378,6 +27541,7 @@ function main() {
|
|
|
27378
27541
|
registerTaskCommands(program);
|
|
27379
27542
|
registerCommonFlags(program);
|
|
27380
27543
|
registerMcpCommands(program);
|
|
27544
|
+
registerPlanCommands(program);
|
|
27381
27545
|
registerCacheCommands(program);
|
|
27382
27546
|
registerHelpCommand(program);
|
|
27383
27547
|
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,16 @@ 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
|
|
24236
|
+
ai plan-continue \u7EE7\u7EED\u6267\u884C\u88AB\u4E2D\u65AD\u7684 plan-do \u4EFB\u52A1
|
|
24233
24237
|
|
|
24234
24238
|
# MCP commands
|
|
24235
24239
|
ai mcp edit \u6253\u5F00 MCP \u914D\u7F6E\u6587\u4EF6\u8FDB\u884C\u7F16\u8F91
|
|
24240
|
+
ai mcp ls \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u5668\u5217\u8868
|
|
24241
|
+
ai mcp enable <name|index> \u542F\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
24242
|
+
ai mcp disable <name|index> \u7981\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
|
|
24236
24243
|
|
|
24237
24244
|
# Serve commands
|
|
24238
24245
|
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,94 @@
|
|
|
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读取任务列表并负责调度。执行每个子任务时,必须为该子任务再创建一个独立的子 Agent,由子 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. 每次通过创建子Agent只调度一个子任务,按列表顺序依次执行;
|
|
69
|
+
4. 调度前将当前任务 status 更新为 "doing" 并写回文件;
|
|
70
|
+
5. 对每个子任务,必须创建一个独立的子 Agent 来执行,不要在主流程中直接完成具体任务;
|
|
71
|
+
6. 创建子 Agent 时,将整体目标、当前子任务 id/name/description、tmp_tasklist.json 文件名和执行要求一并传入;
|
|
72
|
+
7. 子 Agent 执行成功后,将当前任务 status 更新为 "done",并记录 finishedAt(ISO 时间);
|
|
73
|
+
8. 子 Agent 执行失败时,将当前任务保留为 "doing" 或回退为 "todo",并在 note 中记录失败原因;
|
|
74
|
+
9. 每完成或失败一个子任务,都必须立即写回 tmp_tasklist.json;
|
|
75
|
+
10. 全部任务完成后,删除 tmp_tasklist.json 和 tmp_task_goal.md。
|
|
76
|
+
|
|
77
|
+
子 Agent 执行要求:
|
|
78
|
+
- 只执行当前被分配的一个子任务,不要修改其他任务状态;
|
|
79
|
+
- 执行前阅读 tmp_task_goal.md,理解整体目标;
|
|
80
|
+
- 必要时阅读 tmp_tasklist.json,了解上下文和任务依赖;
|
|
81
|
+
- 完成后向主 Agent 返回执行结果、修改的文件、失败原因或后续建议。
|
|
82
|
+
|
|
83
|
+
输出要求:
|
|
84
|
+
- 输出当前调度的任务 id、名称、执行结果状态和下一步计划;
|
|
85
|
+
- 不要跳过状态更新和文件写入步骤。
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 注意事项
|
|
89
|
+
|
|
90
|
+
1. **必须分两个阶段执行**:先创建任务列表,再执行任务列表,不能合并
|
|
91
|
+
2. **子 Agent 只做一件事**:阶段一只负责拆解任务,阶段二只负责按顺序执行
|
|
92
|
+
3. **文件持久化**:任务状态通过 `tmp_tasklist.json` 文件持久化,子 Agent 崩溃后可以重新读取继续执行
|
|
93
|
+
4. **清理临时文件**:全部任务完成后必须删除 `tmp_tasklist.json` 和 `tmp_task_goal.md`
|
|
94
|
+
5. **原子化执行**:每个子任务只做一件事,执行完立即更新状态并写回文件
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepfish-ai",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.13",
|
|
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
|