deepfish-ai 2.0.9 → 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 +354 -147
- package/dist/serve/pm2-server.js +59 -46
- 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/dist/serve/pm2-server.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 fs22 = (0, node_1.default)();
|
|
8407
8407
|
const handler = (err, buffer) => {
|
|
8408
8408
|
if (fd) {
|
|
8409
|
-
|
|
8409
|
+
fs22.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 = fs22.openSync(filepath, "r");
|
|
8422
8422
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
8423
|
-
|
|
8423
|
+
fs22.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
|
+
fs22.readFile(filepath, handler);
|
|
8436
8436
|
});
|
|
8437
8437
|
exports2.detectFile = detectFile;
|
|
8438
8438
|
var detectFileSync = (filepath, opts = {}) => {
|
|
8439
|
-
const
|
|
8439
|
+
const fs22 = (0, node_1.default)();
|
|
8440
8440
|
if (opts && opts.sampleSize) {
|
|
8441
|
-
const fd =
|
|
8441
|
+
const fd = fs22.openSync(filepath, "r");
|
|
8442
8442
|
let sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
8443
|
-
const bytesRead =
|
|
8443
|
+
const bytesRead = fs22.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
|
+
fs22.closeSync(fd);
|
|
8448
8448
|
return (0, exports2.detect)(sample);
|
|
8449
8449
|
}
|
|
8450
|
-
return (0, exports2.detect)(
|
|
8450
|
+
return (0, exports2.detect)(fs22.readFileSync(filepath));
|
|
8451
8451
|
};
|
|
8452
8452
|
exports2.detectFileSync = detectFileSync;
|
|
8453
8453
|
exports2.default = {
|
|
@@ -8542,6 +8542,13 @@ var ADD_MODEL_Config = {
|
|
|
8542
8542
|
// src/cli/cli-utils/getGlobalPath.ts
|
|
8543
8543
|
var import_path2 = __toESM(require("path"));
|
|
8544
8544
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
8545
|
+
|
|
8546
|
+
// src/cli/cli-utils/node-root.ts
|
|
8547
|
+
var { execSync } = require("child_process");
|
|
8548
|
+
var path2 = require("path");
|
|
8549
|
+
var fs = require("fs");
|
|
8550
|
+
|
|
8551
|
+
// src/cli/cli-utils/getGlobalPath.ts
|
|
8545
8552
|
var getDirname = () => __dirname;
|
|
8546
8553
|
function getCodePath() {
|
|
8547
8554
|
let dir = getDirname();
|
|
@@ -9516,10 +9523,10 @@ function mergeDefs(...defs) {
|
|
|
9516
9523
|
function cloneDef(schema) {
|
|
9517
9524
|
return mergeDefs(schema._zod.def);
|
|
9518
9525
|
}
|
|
9519
|
-
function getElementAtPath(obj,
|
|
9520
|
-
if (!
|
|
9526
|
+
function getElementAtPath(obj, path16) {
|
|
9527
|
+
if (!path16)
|
|
9521
9528
|
return obj;
|
|
9522
|
-
return
|
|
9529
|
+
return path16.reduce((acc, key) => acc?.[key], obj);
|
|
9523
9530
|
}
|
|
9524
9531
|
function promiseAllObject(promisesObj) {
|
|
9525
9532
|
const keys = Object.keys(promisesObj);
|
|
@@ -9928,11 +9935,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
9928
9935
|
}
|
|
9929
9936
|
return false;
|
|
9930
9937
|
}
|
|
9931
|
-
function prefixIssues(
|
|
9938
|
+
function prefixIssues(path16, issues) {
|
|
9932
9939
|
return issues.map((iss) => {
|
|
9933
9940
|
var _a3;
|
|
9934
9941
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
9935
|
-
iss.path.unshift(
|
|
9942
|
+
iss.path.unshift(path16);
|
|
9936
9943
|
return iss;
|
|
9937
9944
|
});
|
|
9938
9945
|
}
|
|
@@ -10079,16 +10086,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
10079
10086
|
}
|
|
10080
10087
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
10081
10088
|
const fieldErrors = { _errors: [] };
|
|
10082
|
-
const processError = (error52,
|
|
10089
|
+
const processError = (error52, path16 = []) => {
|
|
10083
10090
|
for (const issue2 of error52.issues) {
|
|
10084
10091
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
10085
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
10092
|
+
issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
|
|
10086
10093
|
} else if (issue2.code === "invalid_key") {
|
|
10087
|
-
processError({ issues: issue2.issues }, [...
|
|
10094
|
+
processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
|
|
10088
10095
|
} else if (issue2.code === "invalid_element") {
|
|
10089
|
-
processError({ issues: issue2.issues }, [...
|
|
10096
|
+
processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
|
|
10090
10097
|
} else {
|
|
10091
|
-
const fullpath = [...
|
|
10098
|
+
const fullpath = [...path16, ...issue2.path];
|
|
10092
10099
|
if (fullpath.length === 0) {
|
|
10093
10100
|
fieldErrors._errors.push(mapper(issue2));
|
|
10094
10101
|
} else {
|
|
@@ -10115,17 +10122,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
10115
10122
|
}
|
|
10116
10123
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
10117
10124
|
const result = { errors: [] };
|
|
10118
|
-
const processError = (error52,
|
|
10125
|
+
const processError = (error52, path16 = []) => {
|
|
10119
10126
|
var _a3, _b;
|
|
10120
10127
|
for (const issue2 of error52.issues) {
|
|
10121
10128
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
10122
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
10129
|
+
issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
|
|
10123
10130
|
} else if (issue2.code === "invalid_key") {
|
|
10124
|
-
processError({ issues: issue2.issues }, [...
|
|
10131
|
+
processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
|
|
10125
10132
|
} else if (issue2.code === "invalid_element") {
|
|
10126
|
-
processError({ issues: issue2.issues }, [...
|
|
10133
|
+
processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
|
|
10127
10134
|
} else {
|
|
10128
|
-
const fullpath = [...
|
|
10135
|
+
const fullpath = [...path16, ...issue2.path];
|
|
10129
10136
|
if (fullpath.length === 0) {
|
|
10130
10137
|
result.errors.push(mapper(issue2));
|
|
10131
10138
|
continue;
|
|
@@ -10157,8 +10164,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
10157
10164
|
}
|
|
10158
10165
|
function toDotPath(_path) {
|
|
10159
10166
|
const segs = [];
|
|
10160
|
-
const
|
|
10161
|
-
for (const seg of
|
|
10167
|
+
const path16 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
10168
|
+
for (const seg of path16) {
|
|
10162
10169
|
if (typeof seg === "number")
|
|
10163
10170
|
segs.push(`[${seg}]`);
|
|
10164
10171
|
else if (typeof seg === "symbol")
|
|
@@ -22850,13 +22857,13 @@ function resolveRef(ref, ctx) {
|
|
|
22850
22857
|
if (!ref.startsWith("#")) {
|
|
22851
22858
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
22852
22859
|
}
|
|
22853
|
-
const
|
|
22854
|
-
if (
|
|
22860
|
+
const path16 = ref.slice(1).split("/").filter(Boolean);
|
|
22861
|
+
if (path16.length === 0) {
|
|
22855
22862
|
return ctx.rootSchema;
|
|
22856
22863
|
}
|
|
22857
22864
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
22858
|
-
if (
|
|
22859
|
-
const key =
|
|
22865
|
+
if (path16[0] === defsKey) {
|
|
22866
|
+
const key = path16[1];
|
|
22860
22867
|
if (!key || !ctx.defs[key]) {
|
|
22861
22868
|
throw new Error(`Reference not found: ${ref}`);
|
|
22862
22869
|
}
|
|
@@ -23272,8 +23279,8 @@ var import_langchain = require("langchain");
|
|
|
23272
23279
|
var import_messages = require("@langchain/core/messages");
|
|
23273
23280
|
|
|
23274
23281
|
// src/agent/AIAgent/utils/skill-parser.ts
|
|
23275
|
-
var
|
|
23276
|
-
var
|
|
23282
|
+
var fs6 = require("fs-extra");
|
|
23283
|
+
var path6 = require("path");
|
|
23277
23284
|
var yaml = require_js_yaml();
|
|
23278
23285
|
|
|
23279
23286
|
// src/agent/AIAgent/system-prompt.ts
|
|
@@ -23503,20 +23510,17 @@ var import_fs_extra7 = __toESM(require("fs-extra"));
|
|
|
23503
23510
|
|
|
23504
23511
|
// src/agent/tools/subAgent.ts
|
|
23505
23512
|
var import_langchain4 = require("langchain");
|
|
23506
|
-
async function subAgentExec(prompt, runtime) {
|
|
23513
|
+
async function subAgentExec(systemPrompt, prompt, runtime) {
|
|
23507
23514
|
const curAgent = runtime.context?.curAgent;
|
|
23508
|
-
|
|
23509
|
-
throw new Error("\u5F53\u524D\u8FD0\u884C\u4E0A\u4E0B\u6587\u4E0D\u652F\u6301\u521B\u5EFA\u5B50 agent");
|
|
23510
|
-
}
|
|
23511
|
-
const subAgent = await curAgent.createSubAgent();
|
|
23512
|
-
return subAgent.execute(prompt);
|
|
23515
|
+
return curAgent && curAgent.subExecute(systemPrompt, prompt);
|
|
23513
23516
|
}
|
|
23514
23517
|
var subAgentTool = (0, import_langchain4.tool)(
|
|
23515
|
-
async ({ prompt }, runtime) => safeTool(() => subAgentExec(prompt, runtime)),
|
|
23518
|
+
async ({ systemPrompt, prompt }, runtime) => safeTool(() => subAgentExec(systemPrompt, prompt, runtime)),
|
|
23516
23519
|
{
|
|
23517
23520
|
name: "subAgent_exec",
|
|
23518
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",
|
|
23519
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"),
|
|
23520
23524
|
prompt: external_exports.string().min(1).describe("\u4EA4\u7ED9\u901A\u7528\u5B50 agent \u6267\u884C\u7684\u5B8C\u6574\u4EFB\u52A1\u63CF\u8FF0")
|
|
23521
23525
|
})
|
|
23522
23526
|
}
|
|
@@ -23597,7 +23601,7 @@ var installPackageTool = (0, import_langchain5.tool)(
|
|
|
23597
23601
|
);
|
|
23598
23602
|
var executeJSCodeTool = (0, import_langchain5.tool)(async ({ code }, runtime) => safeTool(() => executeJSCode(code, runtime)), {
|
|
23599
23603
|
name: "execute_js_code",
|
|
23600
|
-
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
|
|
23601
23605
|
\u53EF\u7528\u5185\u7F6E\u51FD\u6570\uFF1A
|
|
23602
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
|
|
23603
23607
|
\u793A\u4F8B\u4EE3\u7801\uFF1A
|
|
@@ -24211,7 +24215,10 @@ Commands:
|
|
|
24211
24215
|
ai skills generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u6280\u80FD\u6A21\u677F
|
|
24212
24216
|
|
|
24213
24217
|
# Tools commands
|
|
24218
|
+
ai tools ls \u67E5\u770B\u5DF2\u5B89\u88C5\u6216\u5DF2\u914D\u7F6E\u7684\u5DE5\u5177\u5217\u8868
|
|
24214
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
|
|
24215
24222
|
ai tools generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u5DE5\u5177\u6A21\u677F
|
|
24216
24223
|
|
|
24217
24224
|
# Session commands
|
|
@@ -24223,9 +24230,15 @@ Commands:
|
|
|
24223
24230
|
ai task add <task> \u5411\u4EFB\u52A1\u961F\u5217\u6DFB\u52A0\u4E00\u4E2A\u540E\u7EED\u4EFB\u52A1
|
|
24224
24231
|
ai task del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u4EFB\u52A1
|
|
24225
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
|
|
24226
24236
|
|
|
24227
24237
|
# MCP commands
|
|
24228
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
|
|
24229
24242
|
|
|
24230
24243
|
# Serve commands
|
|
24231
24244
|
ai serve \u542F\u52A8\u670D\u52A1\u6216\u8FDB\u5165\u670D\u52A1\u7BA1\u7406\u5165\u53E3
|
|
@@ -24538,14 +24551,14 @@ function startAgentRoomServer(opts = {}) {
|
|
|
24538
24551
|
logWarning("[agent-room] Service already running");
|
|
24539
24552
|
return wss;
|
|
24540
24553
|
}
|
|
24541
|
-
const
|
|
24554
|
+
const path16 = opts.path ?? "/agent-room";
|
|
24542
24555
|
if (opts.httpServer) {
|
|
24543
|
-
wss = new import_ws2.WebSocketServer({ server: opts.httpServer, path:
|
|
24544
|
-
logSuccess(`[agent-room] started, path=${
|
|
24556
|
+
wss = new import_ws2.WebSocketServer({ server: opts.httpServer, path: path16 });
|
|
24557
|
+
logSuccess(`[agent-room] started, path=${path16}`);
|
|
24545
24558
|
} else {
|
|
24546
24559
|
const port = opts.port ?? PORT2;
|
|
24547
|
-
wss = new import_ws2.WebSocketServer({ port, path:
|
|
24548
|
-
logSuccess(`[agent-room] started: ws://localhost:${port}${
|
|
24560
|
+
wss = new import_ws2.WebSocketServer({ port, path: path16 });
|
|
24561
|
+
logSuccess(`[agent-room] started: ws://localhost:${port}${path16}`);
|
|
24549
24562
|
}
|
|
24550
24563
|
wss.on("connection", handleConnection);
|
|
24551
24564
|
return wss;
|
|
@@ -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
|