deepfish-ai 2.0.5 → 2.0.7

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/dist/index.js CHANGED
@@ -8936,7 +8936,7 @@ function registerModelsCommands(program) {
8936
8936
  }
8937
8937
 
8938
8938
  // src/cli/cli-core/skills.ts
8939
- var import_crypto5 = require("crypto");
8939
+ var import_crypto6 = require("crypto");
8940
8940
  var import_inquirer3 = __toESM(require("inquirer"));
8941
8941
  var import_fs_extra19 = __toESM(require("fs-extra"));
8942
8942
  var import_path19 = __toESM(require("path"));
@@ -8998,11 +8998,11 @@ function getConfig() {
8998
8998
  // src/cli/cli-utils/init-agent.ts
8999
8999
  var import_fs_extra18 = __toESM(require("fs-extra"));
9000
9000
  var import_path18 = __toESM(require("path"));
9001
- var import_crypto4 = require("crypto");
9001
+ var import_crypto5 = require("crypto");
9002
9002
 
9003
9003
  // src/agent/AIAgent/index.ts
9004
- var import_langchain16 = require("langchain");
9005
- var import_deepagents = require("deepagents");
9004
+ var import_langchain18 = require("langchain");
9005
+ var import_deepagents2 = require("deepagents");
9006
9006
 
9007
9007
  // src/agent/AIAgent/utils/langgraph-checkpoint-filesystem/filesystem-saver.ts
9008
9008
  var import_path5 = require("path");
@@ -9363,11 +9363,11 @@ var StorePathResolver = class {
9363
9363
  splitWithSplitter(str) {
9364
9364
  return str.split(this.splitter).map(decodeFilename);
9365
9365
  }
9366
- getThreadPath(threadId) {
9367
- return (0, import_path4.join)(this.rootFolder, this.joinWithSplitter(threadId));
9366
+ getThreadPath(_threadId) {
9367
+ return (0, import_path4.join)(this.rootFolder, _threadId);
9368
9368
  }
9369
9369
  getCheckpointNsPath(_threadId, _checkpointNs) {
9370
- return (0, import_path4.join)(this.rootFolder);
9370
+ return (0, import_path4.join)(this.rootFolder, _threadId, _checkpointNs || this.defaultCheckpointNs);
9371
9371
  }
9372
9372
  getCheckpointFolderPath(threadId, checkpointNs, checkpointId) {
9373
9373
  return (0, import_path4.join)(this.getCheckpointNsPath(threadId, checkpointNs), checkpointId);
@@ -9450,6 +9450,35 @@ var FileSystemSaver = class extends BaseCheckpointSaver {
9450
9450
  super(serde);
9451
9451
  this.pathResolver = new StorePathResolver(rootFolder, splitter);
9452
9452
  }
9453
+ // 还原到最后一次会话结束时的检查点
9454
+ async init(agentId, agent) {
9455
+ const { lastCheckPointId, allCheckPointId } = await this.getLastCheckPointId(agentId, agent);
9456
+ if (lastCheckPointId && allCheckPointId.includes(lastCheckPointId)) {
9457
+ for (const checkpointId of allCheckPointId) {
9458
+ if (checkpointId !== lastCheckPointId) {
9459
+ const checkpointPath = this.pathResolver.getCheckpointFolderPath(agentId, this.pathResolver.defaultCheckpointNs, checkpointId);
9460
+ await safeDeleteFile(checkpointPath);
9461
+ } else {
9462
+ break;
9463
+ }
9464
+ }
9465
+ }
9466
+ }
9467
+ async getLastCheckPointId(agentId, agent) {
9468
+ const threadConfig = { configurable: { thread_id: agentId } };
9469
+ const history = [];
9470
+ const compiledGraph = agent.graph;
9471
+ const checkPointIds = [];
9472
+ for await (const state of compiledGraph.getStateHistory(threadConfig)) {
9473
+ history.push(state);
9474
+ checkPointIds.push(state.config.configurable?.["checkpoint_id"]);
9475
+ }
9476
+ const finishSnap = history.find((s) => s.next.length === 0);
9477
+ return {
9478
+ lastCheckPointId: finishSnap?.config.configurable?.["checkpoint_id"],
9479
+ allCheckPointId: checkPointIds
9480
+ };
9481
+ }
9453
9482
  async *list(config2, options) {
9454
9483
  const { before, limit, filter } = options ?? {};
9455
9484
  const threadIds = config2.configurable?.["thread_id"] ? [config2.configurable["thread_id"]] : await listDirs(this.pathResolver.rootFolder);
@@ -9514,11 +9543,7 @@ var FileSystemSaver = class extends BaseCheckpointSaver {
9514
9543
  const extraPath = (0, import_path5.join)(checkpointsPath, "extra.json");
9515
9544
  const metadataPath = (0, import_path5.join)(checkpointsPath, "metadata");
9516
9545
  const checkpointPath = (0, import_path5.join)(checkpointsPath, "checkpoint");
9517
- const [extraJson, metadata, checkpoint] = await Promise.all([
9518
- readJSON(extraPath),
9519
- readBinary(metadataPath),
9520
- readBinary(checkpointPath)
9521
- ]);
9546
+ const [extraJson, metadata, checkpoint] = await Promise.all([readJSON(extraPath), readBinary(metadataPath), readBinary(checkpointPath)]);
9522
9547
  const [deserializedMetadata, deserializedCheckpoint] = await Promise.all([
9523
9548
  this.serde.loadsTyped("json", metadata),
9524
9549
  this.serde.loadsTyped("json", checkpoint)
@@ -9565,11 +9590,7 @@ var FileSystemSaver = class extends BaseCheckpointSaver {
9565
9590
  const extraPath = (0, import_path5.join)(checkpointsPath, "extra.json");
9566
9591
  const metadataPath = (0, import_path5.join)(checkpointsPath, "metadata");
9567
9592
  const checkpointPath = (0, import_path5.join)(checkpointsPath, "checkpoint");
9568
- const [extraJson, metadata, checkpoint] = await Promise.all([
9569
- readJSON(extraPath),
9570
- readBinary(metadataPath),
9571
- readBinary(checkpointPath)
9572
- ]);
9593
+ const [extraJson, metadata, checkpoint] = await Promise.all([readJSON(extraPath), readBinary(metadataPath), readBinary(checkpointPath)]);
9573
9594
  const [deserializedMetadata, deserializedCheckpoint] = await Promise.all([
9574
9595
  this.serde.loadsTyped("json", metadata),
9575
9596
  this.serde.loadsTyped("json", checkpoint)
@@ -9618,9 +9639,7 @@ var FileSystemSaver = class extends BaseCheckpointSaver {
9618
9639
  const parentCheckpointId = config2.configurable?.["checkpoint_id"];
9619
9640
  const checkpointId = checkpoint.id;
9620
9641
  if (threadId === void 0) {
9621
- throw new Error(
9622
- `Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`
9623
- );
9642
+ throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`);
9624
9643
  }
9625
9644
  const checkpointsPath = this.pathResolver.getCheckpointsPath(threadId, checkpointNs, checkpointId);
9626
9645
  await checkOrCreateFolder(checkpointsPath);
@@ -9644,14 +9663,10 @@ var FileSystemSaver = class extends BaseCheckpointSaver {
9644
9663
  const checkpointId = config2.configurable?.["checkpoint_id"];
9645
9664
  const checkpointNs = config2.configurable?.["checkpoint_ns"];
9646
9665
  if (threadId === void 0) {
9647
- throw new Error(
9648
- `Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`
9649
- );
9666
+ throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`);
9650
9667
  }
9651
9668
  if (checkpointId === void 0) {
9652
- throw new Error(
9653
- `Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`
9654
- );
9669
+ throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`);
9655
9670
  }
9656
9671
  const writesPath = this.pathResolver.getWritesPath(threadId, checkpointNs, checkpointId);
9657
9672
  await checkOrCreateFolder(writesPath);
@@ -24228,7 +24243,7 @@ function date4(params) {
24228
24243
  config(en_default());
24229
24244
 
24230
24245
  // src/agent/AIAgent/index.ts
24231
- var import_eventemitter_super = require("eventemitter-super");
24246
+ var import_eventemitter_super2 = require("eventemitter-super");
24232
24247
 
24233
24248
  // src/agent/AIAgent/middleware/eventEmitMiddleware.ts
24234
24249
  var import_langchain = require("langchain");
@@ -24329,15 +24344,15 @@ function parseSkillMetadataYaml(skillPath) {
24329
24344
 
24330
24345
  // src/agent/AIAgent/system-prompt.ts
24331
24346
  var import_fs_extra5 = __toESM(require("fs-extra"));
24332
- function getSkillPrompt(skills) {
24347
+ function getSkillPrompt(skills, excludeSkills) {
24333
24348
  const parsedSkills = skills.map((skill) => {
24334
24349
  return parseSkillMetadataYaml(skill);
24335
- });
24350
+ }).filter((skill) => skill !== null && !excludeSkills.includes(skill.name));
24336
24351
  let skillPrompt = "";
24337
24352
  if (parsedSkills.length > 0) {
24338
24353
  const skillTable = parsedSkills.map((s) => `| ${s.name} | ${s.description} | ${s.location} | ${s.skillFilePath} |`).join("\n");
24339
24354
  skillPrompt = `
24340
- ### \u53EF\u4EE5\u4F7F\u7528\u7684Skills
24355
+ # \u53EF\u4EE5\u4F7F\u7528\u7684Skills
24341
24356
  \u53EF\u4EE5\u8C03\u7528\u4EE5\u4E0BSkill\u6765\u5B8C\u6210\u7528\u6237\u4EFB\u52A1\u76EE\u6807,Skill\u7684\u8C03\u7528\u65B9\u5F0F:
24342
24357
  - \u4F7F\u7528\u7528\u6237\u8BF7\u6C42\u5339\u914D skill description,
24343
24358
  - \u4E00\u6B21\u53EA\u52A0\u8F7D\u4E00\u4E2ASkill,\u4F18\u5148\u5339\u914D\u6700\u5177\u4F53\u7684Skill
@@ -24360,8 +24375,10 @@ function getUserMemoryPrompt(memoryFilePath) {
24360
24375
  if (import_fs_extra5.default.existsSync(memoryFilePath)) {
24361
24376
  const content = import_fs_extra5.default.readFileSync(memoryFilePath, "utf-8");
24362
24377
  return `
24363
- ### \u7528\u6237\u4FE1\u606F
24378
+ # \u7528\u6237\u4FE1\u606F
24379
+ \`\`\`
24364
24380
  ${content}
24381
+ \`\`\`
24365
24382
  `;
24366
24383
  }
24367
24384
  return "";
@@ -24372,34 +24389,34 @@ function getAgentRulesPrompt(agentRulesPath) {
24372
24389
  }
24373
24390
  if (import_fs_extra5.default.existsSync(agentRulesPath)) {
24374
24391
  const content = import_fs_extra5.default.readFileSync(agentRulesPath, "utf-8");
24375
- return `### \u4EE5\u4E0B\u662FAgent\u884C\u4E3A\u89C4\u8303\uFF0C\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF1A
24392
+ return `# \u4EE5\u4E0B\u662FAgent\u884C\u4E3A\u89C4\u8303\uFF0C\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF1A
24376
24393
  ${content}
24377
24394
  `;
24378
24395
  }
24379
24396
  }
24380
- var systemPrompt = (workspace, osType, skills, memoryFilePath, agentRulesPath) => {
24381
- const skillPrompt = getSkillPrompt(skills);
24382
- const memoryPrompt = getUserMemoryPrompt(memoryFilePath);
24383
- const agentRulesPrompt = getAgentRulesPrompt(agentRulesPath);
24397
+ var getSystemPrompt = (params) => {
24398
+ const skillPrompt = getSkillPrompt(params.skills, params.excludeSkills);
24399
+ const memoryPrompt = getUserMemoryPrompt(params.memoryFilePath);
24400
+ const agentRulesPrompt = getAgentRulesPrompt(params.agentRulesPath);
24384
24401
  return `
24385
- \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
24386
- ### \u57FA\u7840\u73AF\u5883\u4FE1\u606F
24387
- \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${workspace}
24388
- \u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${osType}
24389
- \u8BED\u8A00\u7C7B\u578B: \u4E0E\u7528\u6237\u8F93\u5165\u8BED\u8A00\u4E00\u81F4
24390
-
24391
- \u6CE8\u610F:
24402
+ ${params.systemPrompt || `\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
24403
+ # \u6CE8\u610F\u6CE8\u610F\u4E8B\u9879:
24392
24404
  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
24393
24405
  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
24394
- 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1
24406
+ 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1`}
24407
+
24408
+ # \u57FA\u7840\u73AF\u5883\u4FE1\u606F
24409
+ \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${params.workspace}
24410
+ \u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${params.osType}
24411
+ \u8BED\u8A00\u7C7B\u578B: \u4E0E\u7528\u6237\u8F93\u5165\u8BED\u8A00\u4E00\u81F4
24395
24412
 
24396
24413
  ${skillPrompt}
24397
24414
  ${memoryPrompt}
24398
24415
  ${agentRulesPrompt}
24399
24416
  `;
24400
24417
  };
24401
- var subSystemPrompt = (workspace, osType, skills) => {
24402
- let skillPrompt = getSkillPrompt(skills);
24418
+ var subSystemPrompt = (workspace, osType, skills, excludeSkills) => {
24419
+ let skillPrompt = getSkillPrompt(skills, excludeSkills);
24403
24420
  return `
24404
24421
  \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
24405
24422
  ### \u57FA\u7840\u73AF\u5883\u4FE1\u606F
@@ -24625,9 +24642,16 @@ function toLangChainTool(func, description) {
24625
24642
  zodProperties[key] = zodType;
24626
24643
  }
24627
24644
  const schema = external_exports.object(zodProperties);
24628
- const wrappedFunc = async (args) => {
24645
+ const wrappedFunc = async (args, runtime) => {
24629
24646
  try {
24630
- const result = await func(...Object.values(args));
24647
+ const boundFunc = func.bind({
24648
+ createSubAgent: async (prompt) => {
24649
+ const subAgent = await runtime.context.curAgent.createSubAgent();
24650
+ return subAgent.execute(prompt);
24651
+ },
24652
+ curAgent: runtime.context.curAgent
24653
+ });
24654
+ const result = await boundFunc(...Object.values(args));
24631
24655
  if (typeof result === "object" && result !== null && "success" in result) {
24632
24656
  return serializeToolResult(result);
24633
24657
  }
@@ -24642,7 +24666,7 @@ function toLangChainTool(func, description) {
24642
24666
  schema
24643
24667
  });
24644
24668
  }
24645
- function scanUserTools() {
24669
+ function scanUserTools(excludeTools) {
24646
24670
  const tools = [];
24647
24671
  const scanPaths = getScanDirPaths();
24648
24672
  scanPaths.forEach((scanPath) => {
@@ -24653,24 +24677,24 @@ function scanUserTools() {
24653
24677
  if (import_fs_extra8.default.statSync(import_path8.default.resolve(toolsDir, file2)).isDirectory()) {
24654
24678
  const subDirPath = import_path8.default.resolve(toolsDir, file2);
24655
24679
  const subFiles = import_fs_extra8.default.readdirSync(subDirPath);
24656
- const indexFile = subFiles.find((f) => f === "index" || f === "index.cjs");
24680
+ const indexFile = subFiles.find((f) => f === "index.js" || f === "index.cjs");
24657
24681
  if (indexFile) {
24658
24682
  const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, indexFile), indexFile);
24659
24683
  if (filePath) {
24660
- _loadToolsFromFile(filePath, tools);
24684
+ _loadToolsFromFile(filePath, tools, excludeTools);
24661
24685
  }
24662
24686
  } else {
24663
24687
  subFiles.forEach((subFile) => {
24664
24688
  const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, subFile), subFile);
24665
24689
  if (filePath) {
24666
- _loadToolsFromFile(filePath, tools);
24690
+ _loadToolsFromFile(filePath, tools, excludeTools);
24667
24691
  }
24668
24692
  });
24669
24693
  }
24670
24694
  } else {
24671
24695
  const filePath = _scanDeepFishJsFile(toolsDir, file2);
24672
24696
  if (filePath) {
24673
- _loadToolsFromFile(filePath, tools);
24697
+ _loadToolsFromFile(filePath, tools, excludeTools);
24674
24698
  }
24675
24699
  }
24676
24700
  });
@@ -24687,16 +24711,36 @@ function _scanDeepFishJsFile(filePath, fileName) {
24687
24711
  }
24688
24712
  return null;
24689
24713
  }
24690
- function _loadToolsFromFile(filePath, tools) {
24691
- const toolModule = require(filePath);
24692
- const { functions, descriptions } = toolModule;
24693
- descriptions.forEach((desc) => {
24694
- const func = functions[desc.function.name];
24695
- if (func) {
24714
+ function _loadToolsFromFile(filePath, tools, excludeTools) {
24715
+ try {
24716
+ const toolModule = require(filePath);
24717
+ const { functions, descriptions } = toolModule;
24718
+ if (!functions || typeof functions !== "object" || !Array.isArray(descriptions)) {
24719
+ logWarning(`Skip invalid tool file: ${filePath}`);
24720
+ return;
24721
+ }
24722
+ descriptions.forEach((desc) => {
24723
+ if (!desc.type) {
24724
+ desc = {
24725
+ type: "function",
24726
+ function: desc
24727
+ };
24728
+ }
24729
+ if (excludeTools.includes(desc.function.name)) {
24730
+ return;
24731
+ }
24732
+ const func = functions[desc.function.name];
24733
+ if (typeof func !== "function") {
24734
+ logWarning(`Skip tool "${desc.function.name}": implementation not found in ${filePath}`);
24735
+ return;
24736
+ }
24696
24737
  const langChainTool = toLangChainTool(func, desc);
24697
24738
  tools.push(langChainTool);
24698
- }
24699
- });
24739
+ });
24740
+ } catch (error51) {
24741
+ const message = error51 instanceof Error ? error51.message : String(error51);
24742
+ logWarning(`Failed to load tool file: ${filePath}. ${message}`);
24743
+ }
24700
24744
  }
24701
24745
 
24702
24746
  // src/agent/tools/executeCommand.ts
@@ -24753,11 +24797,33 @@ var executeCommandTool = (0, import_langchain3.tool)(({ command, timeout }) => s
24753
24797
  });
24754
24798
 
24755
24799
  // src/agent/tools/executeJSCode.ts
24756
- var import_langchain4 = require("langchain");
24800
+ var import_langchain5 = require("langchain");
24757
24801
  var import_path9 = __toESM(require("path"));
24758
24802
  var import_fs_extra9 = __toESM(require("fs-extra"));
24759
- var _require = require;
24760
- async function executeJSCode(code) {
24803
+
24804
+ // src/agent/tools/subAgent.ts
24805
+ var import_langchain4 = require("langchain");
24806
+ async function subAgentExec(prompt, runtime) {
24807
+ const curAgent = runtime.context?.curAgent;
24808
+ if (!curAgent || typeof curAgent.createSubAgent !== "function") {
24809
+ throw new Error("\u5F53\u524D\u8FD0\u884C\u4E0A\u4E0B\u6587\u4E0D\u652F\u6301\u521B\u5EFA\u5B50 agent");
24810
+ }
24811
+ const subAgent = await curAgent.createSubAgent();
24812
+ return subAgent.execute(prompt);
24813
+ }
24814
+ var subAgentTool = (0, import_langchain4.tool)(
24815
+ async ({ prompt }, runtime) => safeTool(() => subAgentExec(prompt, runtime)),
24816
+ {
24817
+ name: "subAgent_exec",
24818
+ 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",
24819
+ schema: external_exports.object({
24820
+ prompt: external_exports.string().min(1).describe("\u4EA4\u7ED9\u901A\u7528\u5B50 agent \u6267\u884C\u7684\u5B8C\u6574\u4EFB\u52A1\u63CF\u8FF0")
24821
+ })
24822
+ }
24823
+ );
24824
+
24825
+ // src/agent/tools/executeJSCode.ts
24826
+ async function executeJSCode(code, runtime) {
24761
24827
  logInfo("Executing JavaScript code: ");
24762
24828
  logInfo(code);
24763
24829
  try {
@@ -24766,15 +24832,26 @@ async function executeJSCode(code) {
24766
24832
  const result = await __main()
24767
24833
  return result || "Code executed successfully, but __main() did not return anything."
24768
24834
  })()`;
24769
- const fn = new Function("require", wrapped);
24770
- const result = await fn(_require);
24835
+ const fn = new Function("require", "agentExec", wrapped);
24836
+ const _require = require;
24837
+ const newRequire = (modulePath) => {
24838
+ if (modulePath.startsWith("./")) {
24839
+ const resolvedPath = import_path9.default.resolve(process.cwd(), modulePath);
24840
+ return _require(resolvedPath);
24841
+ }
24842
+ return _require(modulePath);
24843
+ };
24844
+ const agentExec = async (prompt) => {
24845
+ return subAgentExec(prompt, runtime);
24846
+ };
24847
+ const result = await fn(newRequire, agentExec);
24771
24848
  return result;
24772
24849
  } catch (error51) {
24773
24850
  logError(`Error executing code: ${error51.stack}`);
24774
24851
  throw error51;
24775
24852
  }
24776
24853
  }
24777
- var getInstalledPackagesTool = (0, import_langchain4.tool)(
24854
+ var getInstalledPackagesTool = (0, import_langchain5.tool)(
24778
24855
  async () => safeTool(() => {
24779
24856
  const packageJson = import_path9.default.join(getCodePath(), "./package.json");
24780
24857
  const pkg = import_fs_extra9.default.readJsonSync(packageJson);
@@ -24786,7 +24863,7 @@ var getInstalledPackagesTool = (0, import_langchain4.tool)(
24786
24863
  schema: external_exports.object({})
24787
24864
  }
24788
24865
  );
24789
- var checkPackageInstalledTool = (0, import_langchain4.tool)(
24866
+ var checkPackageInstalledTool = (0, import_langchain5.tool)(
24790
24867
  async ({ packageName }) => safeTool(() => {
24791
24868
  const packageJson = import_path9.default.join(getCodePath(), "./package.json");
24792
24869
  const pkg = import_fs_extra9.default.readJsonSync(packageJson);
@@ -24801,7 +24878,7 @@ var checkPackageInstalledTool = (0, import_langchain4.tool)(
24801
24878
  })
24802
24879
  }
24803
24880
  );
24804
- var installPackageTool = (0, import_langchain4.tool)(
24881
+ var installPackageTool = (0, import_langchain5.tool)(
24805
24882
  async ({ packageName }) => safeTool(() => {
24806
24883
  const packageJson = import_path9.default.join(getCodePath(), "./package.json");
24807
24884
  const pkg = import_fs_extra9.default.readJsonSync(packageJson);
@@ -24818,12 +24895,16 @@ var installPackageTool = (0, import_langchain4.tool)(
24818
24895
  })
24819
24896
  }
24820
24897
  );
24821
- var executeJSCodeTool = (0, import_langchain4.tool)(async ({ code }) => safeTool(() => executeJSCode(code)), {
24898
+ var executeJSCodeTool = (0, import_langchain5.tool)(async ({ code }, runtime) => safeTool(() => executeJSCode(code, runtime)), {
24822
24899
  name: "execute_js_code",
24823
- description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A\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\u793A\u4F8B\u4EE3\u7801\uFF1A
24900
+ description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A\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
24901
+ \u53EF\u7528\u5185\u7F6E\u51FD\u6570\uFF1A
24902
+ - 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
24903
+ \u793A\u4F8B\u4EE3\u7801\uFF1A
24824
24904
  async function __main() {
24825
24905
  const data = await fs.readFile("data.txt", "utf-8")
24826
- return data
24906
+ const analysis = await agentExec("\u8BF7\u5206\u6790\u8FD9\u6BB5\u6587\u4EF6\u5185\u5BB9\u5E76\u603B\u7ED3\u91CD\u70B9\uFF1A" + data)
24907
+ return analysis
24827
24908
  }
24828
24909
  `,
24829
24910
  schema: external_exports.object({
@@ -24919,9 +25000,9 @@ var UserCache = class {
24919
25000
  };
24920
25001
 
24921
25002
  // src/agent/tools/learn-self.ts
24922
- var import_langchain5 = require("langchain");
25003
+ var import_langchain6 = require("langchain");
24923
25004
  var userCache = new UserCache();
24924
- var learnSelfTool = (0, import_langchain5.tool)(
25005
+ var learnSelfTool = (0, import_langchain6.tool)(
24925
25006
  ({ description, content }) => safeTool(() => {
24926
25007
  userCache.add(description, content);
24927
25008
  return `\u5DF2\u7F13\u5B58\u89E3\u51B3\u65B9\u6848: ${description}`;
@@ -24935,7 +25016,7 @@ var learnSelfTool = (0, import_langchain5.tool)(
24935
25016
  })
24936
25017
  }
24937
25018
  );
24938
- var getLearnedDetailTool = (0, import_langchain5.tool)(
25019
+ var getLearnedDetailTool = (0, import_langchain6.tool)(
24939
25020
  ({ indexOrId }) => safeTool(() => {
24940
25021
  const index = Number(indexOrId);
24941
25022
  let item;
@@ -24964,7 +25045,7 @@ ${detail.content}`;
24964
25045
  })
24965
25046
  }
24966
25047
  );
24967
- var updateLearnContentTool = (0, import_langchain5.tool)(
25048
+ var updateLearnContentTool = (0, import_langchain6.tool)(
24968
25049
  ({ id, content }) => safeTool(() => {
24969
25050
  const success2 = userCache.update(id, content);
24970
25051
  if (!success2) {
@@ -24981,7 +25062,7 @@ var updateLearnContentTool = (0, import_langchain5.tool)(
24981
25062
  })
24982
25063
  }
24983
25064
  );
24984
- var getCatalogFilePathTool = (0, import_langchain5.tool)(() => safeTool(() => userCache.getCatalogFilePath()), {
25065
+ var getCatalogFilePathTool = (0, import_langchain6.tool)(() => safeTool(() => userCache.getCatalogFilePath()), {
24985
25066
  name: "get_catalog_file_path",
24986
25067
  description: "\u83B7\u53D6\u7F13\u5B58\u7D22\u5F15\u6587\u4EF6 catalog.json \u7684\u7EDD\u5BF9\u8DEF\u5F84\u3002\u8BE5\u6587\u4EF6\u5305\u542B\u6240\u6709\u5DF2\u7F13\u5B58\u65B9\u6848\u7684 id \u548C description \u5217\u8868\u3002\u83B7\u53D6\u8DEF\u5F84\u540E\uFF0C\u4F7F\u7528 read_file \u5DE5\u5177\u8BFB\u53D6\u8BE5\u6587\u4EF6\u5373\u53EF\u67E5\u770B\u6240\u6709\u7F13\u5B58\u9879\u3002",
24987
25068
  schema: external_exports.object({})
@@ -24991,7 +25072,7 @@ var learnTools = [learnSelfTool, getLearnedDetailTool, updateLearnContentTool, g
24991
25072
  // src/agent/tools/mcp.ts
24992
25073
  var import_mcp_adapters = require("@langchain/mcp-adapters");
24993
25074
  var import_fs_extra11 = __toESM(require("fs-extra"));
24994
- var import_langchain6 = require("langchain");
25075
+ var import_langchain7 = require("langchain");
24995
25076
  var import_path11 = __toESM(require("path"));
24996
25077
  function normalizeMcpToolResult(result) {
24997
25078
  if (Array.isArray(result)) {
@@ -25003,7 +25084,7 @@ function normalizeMcpToolResult(result) {
25003
25084
  return result;
25004
25085
  }
25005
25086
  function wrapMcpTool(mcpTool) {
25006
- const wrapped = (0, import_langchain6.tool)(
25087
+ const wrapped = (0, import_langchain7.tool)(
25007
25088
  async (input, runtime) => {
25008
25089
  try {
25009
25090
  const result = await mcpTool.invoke(input, runtime);
@@ -25020,15 +25101,19 @@ function wrapMcpTool(mcpTool) {
25020
25101
  );
25021
25102
  return wrapped;
25022
25103
  }
25023
- async function loadMcpToolsFromConfigPath(mcpFilePath) {
25104
+ async function loadMcpToolsFromConfigPath(mcpFilePath, excludeMCP) {
25024
25105
  const jsonContent = import_fs_extra11.default.readJSONSync(mcpFilePath);
25025
- const { mcpServers } = jsonContent;
25106
+ let mcpServers = jsonContent.mcpServers;
25026
25107
  if (!mcpServers || Object.keys(mcpServers).length === 0) {
25027
25108
  return [];
25028
25109
  }
25029
25110
  try {
25030
25111
  for (const key of Object.keys(mcpServers)) {
25031
25112
  const server = mcpServers[key];
25113
+ if (server.disabled || excludeMCP.includes(key)) {
25114
+ delete mcpServers[key];
25115
+ continue;
25116
+ }
25032
25117
  if (!server.transport) {
25033
25118
  if (server.url) {
25034
25119
  if (server.url.startsWith("ws://") || server.url.startsWith("wss://")) {
@@ -25045,6 +25130,9 @@ async function loadMcpToolsFromConfigPath(mcpFilePath) {
25045
25130
  delete mcpServers[key];
25046
25131
  }
25047
25132
  }
25133
+ if (Object.keys(mcpServers).length === 0) {
25134
+ return [];
25135
+ }
25048
25136
  logInfo(`Loading MCP tools from config path: ${mcpFilePath}`);
25049
25137
  const client = new import_mcp_adapters.MultiServerMCPClient(jsonContent.mcpServers);
25050
25138
  const tools = await client.getTools();
@@ -25055,13 +25143,13 @@ async function loadMcpToolsFromConfigPath(mcpFilePath) {
25055
25143
  return [];
25056
25144
  }
25057
25145
  }
25058
- async function scanUserMcp() {
25146
+ async function scanUserMcp(excludeMCP) {
25059
25147
  const tools = [];
25060
25148
  const scanPaths = getScanDirPaths();
25061
25149
  for (const scanPath of scanPaths) {
25062
25150
  const mcpFilePath = import_path11.default.join(scanPath, "mcp.json");
25063
25151
  if (import_fs_extra11.default.existsSync(mcpFilePath)) {
25064
- const mcpTools = await loadMcpToolsFromConfigPath(mcpFilePath);
25152
+ const mcpTools = await loadMcpToolsFromConfigPath(mcpFilePath, excludeMCP);
25065
25153
  tools.push(...mcpTools);
25066
25154
  }
25067
25155
  }
@@ -25070,7 +25158,7 @@ async function scanUserMcp() {
25070
25158
 
25071
25159
  // src/agent/tools/edit.ts
25072
25160
  var import_fs_extra12 = __toESM(require("fs-extra"));
25073
- var import_langchain7 = require("langchain");
25161
+ var import_langchain8 = require("langchain");
25074
25162
  async function editFileByReplace(filePath, oldString, newString, replaceAll = false) {
25075
25163
  const absPath = resolveWorkspacePath(filePath);
25076
25164
  if (!await import_fs_extra12.default.pathExists(absPath)) {
@@ -25091,7 +25179,7 @@ async function editFileByReplace(filePath, oldString, newString, replaceAll = fa
25091
25179
  await import_fs_extra12.default.writeFile(absPath, nextContent, "utf-8");
25092
25180
  return `\u5DF2\u7F16\u8F91\u6587\u4EF6: ${absPath}\uFF0C\u66FF\u6362 ${replaceAll ? matches : 1} \u5904`;
25093
25181
  }
25094
- var editFileTool = (0, import_langchain7.tool)(
25182
+ var editFileTool = (0, import_langchain8.tool)(
25095
25183
  async ({ filePath, oldString, newString, replaceAll }) => safeTool(() => editFileByReplace(filePath, oldString, newString, replaceAll)),
25096
25184
  {
25097
25185
  name: "edit_file",
@@ -25107,7 +25195,7 @@ var editFileTool = (0, import_langchain7.tool)(
25107
25195
 
25108
25196
  // src/agent/tools/glob.ts
25109
25197
  var import_path12 = __toESM(require("path"));
25110
- var import_langchain8 = require("langchain");
25198
+ var import_langchain9 = require("langchain");
25111
25199
  async function globFiles(pattern, cwd, maxResults = 200, includeHidden = false) {
25112
25200
  const rootDir = resolveWorkspacePath(cwd || ".");
25113
25201
  const allFiles = await walkFiles(rootDir, { includeHidden, maxFiles: Math.max(maxResults * 20, 1e3) });
@@ -25115,7 +25203,7 @@ async function globFiles(pattern, cwd, maxResults = 200, includeHidden = false)
25115
25203
  const matches = allFiles.map((file2) => normalizePathForMatch(import_path12.default.relative(rootDir, file2))).filter((relativePath) => matchesGlob(relativePath, normalizedPattern)).slice(0, maxResults);
25116
25204
  return truncateOutput(formatJson({ cwd: rootDir, pattern, count: matches.length, files: matches }));
25117
25205
  }
25118
- var globTool = (0, import_langchain8.tool)(
25206
+ var globTool = (0, import_langchain9.tool)(
25119
25207
  async ({ pattern, cwd, maxResults, includeHidden }) => safeTool(() => globFiles(pattern, cwd, maxResults, includeHidden)),
25120
25208
  {
25121
25209
  name: "glob_files",
@@ -25132,7 +25220,7 @@ var globTool = (0, import_langchain8.tool)(
25132
25220
  // src/agent/tools/grep.ts
25133
25221
  var import_fs_extra13 = __toESM(require("fs-extra"));
25134
25222
  var import_path13 = __toESM(require("path"));
25135
- var import_langchain9 = require("langchain");
25223
+ var import_langchain10 = require("langchain");
25136
25224
  async function grepFiles(query, cwd, includePattern = "**/*", isRegexp = false, maxResults = 100, includeHidden = false) {
25137
25225
  const rootDir = resolveWorkspacePath(cwd || ".");
25138
25226
  const matcher = isRegexp ? new RegExp(query, "i") : null;
@@ -25157,7 +25245,7 @@ async function grepFiles(query, cwd, includePattern = "**/*", isRegexp = false,
25157
25245
  }
25158
25246
  return truncateOutput(formatJson({ cwd: rootDir, query, includePattern, count: matches.length, matches }));
25159
25247
  }
25160
- var grepTool = (0, import_langchain9.tool)(
25248
+ var grepTool = (0, import_langchain10.tool)(
25161
25249
  async ({ query, pattern, cwd, includePattern, isRegexp, maxResults, includeHidden }) => safeTool(() => {
25162
25250
  const searchQuery = query || pattern;
25163
25251
  if (!searchQuery) {
@@ -25185,7 +25273,7 @@ var grepTool = (0, import_langchain9.tool)(
25185
25273
 
25186
25274
  // src/agent/tools/question.ts
25187
25275
  var import_inquirer2 = __toESM(require("inquirer"));
25188
- var import_langchain10 = require("langchain");
25276
+ var import_langchain11 = require("langchain");
25189
25277
  async function askQuestion(question, type = "input", choices = []) {
25190
25278
  const promptType = type === "select" ? "list" : type;
25191
25279
  const answer = await import_inquirer2.default.prompt([
@@ -25199,7 +25287,7 @@ async function askQuestion(question, type = "input", choices = []) {
25199
25287
  const value = answer["value"];
25200
25288
  return typeof value === "string" ? value : JSON.stringify(value);
25201
25289
  }
25202
- var questionTool = (0, import_langchain10.tool)(async ({ question, type, choices }) => safeTool(() => askQuestion(question, type, choices)), {
25290
+ var questionTool = (0, import_langchain11.tool)(async ({ question, type, choices }) => safeTool(() => askQuestion(question, type, choices)), {
25203
25291
  name: "ask_question",
25204
25292
  description: "\u5F53\u7EE7\u7EED\u4EFB\u52A1\u5FC5\u987B\u83B7\u53D6\u7528\u6237\u6F84\u6E05\u3001\u786E\u8BA4\u6216\u9009\u62E9\u65F6\uFF0C\u5411\u7528\u6237\u53D1\u8D77\u547D\u4EE4\u884C\u63D0\u95EE\u5E76\u8FD4\u56DE\u7B54\u6848\u3002\u4E0D\u8981\u8BE2\u95EE\u5BC6\u7801\u3001\u5BC6\u94A5\u7B49\u654F\u611F\u4FE1\u606F\u3002",
25205
25293
  schema: external_exports.object({
@@ -25212,7 +25300,7 @@ var questionTool = (0, import_langchain10.tool)(async ({ question, type, choices
25212
25300
  // src/agent/tools/read.ts
25213
25301
  var import_fs_extra14 = __toESM(require("fs-extra"));
25214
25302
  var import_iconv_lite2 = __toESM(require("iconv-lite"));
25215
- var import_langchain11 = require("langchain");
25303
+ var import_langchain12 = require("langchain");
25216
25304
  async function readFile2(filePath, startLine = 1, endLine = -1, encoding) {
25217
25305
  const absPath = resolveWorkspacePath(filePath);
25218
25306
  if (!await import_fs_extra14.default.pathExists(absPath)) {
@@ -25234,7 +25322,7 @@ async function readFile2(filePath, startLine = 1, endLine = -1, encoding) {
25234
25322
  const selected = lines.slice(safeStart - 1, safeEnd).map((line, index) => `${safeStart + index}: ${line}`).join("\n");
25235
25323
  return truncateOutput(formatJson({ filePath: absPath, totalLines: lines.length, startLine: safeStart, endLine: safeEnd, content: selected }));
25236
25324
  }
25237
- var readFileTool = (0, import_langchain11.tool)(
25325
+ var readFileTool = (0, import_langchain12.tool)(
25238
25326
  async ({ filePath, startLine, endLine, encoding }) => safeTool(() => readFile2(filePath, startLine, endLine, encoding)),
25239
25327
  {
25240
25328
  name: "read_file",
@@ -25251,7 +25339,7 @@ var readFileTool = (0, import_langchain11.tool)(
25251
25339
  // src/agent/tools/semanticMemory.ts
25252
25340
  var import_fs_extra15 = __toESM(require("fs-extra"));
25253
25341
  var import_path14 = __toESM(require("path"));
25254
- var import_langchain12 = require("langchain");
25342
+ var import_langchain13 = require("langchain");
25255
25343
  var DEFAULT_MEMORY_MARKDOWN = `# \u7528\u6237\u8BED\u4E49\u8BB0\u5FC6
25256
25344
 
25257
25345
  > \u8BE5\u6587\u4EF6\u7531\u8BED\u4E49\u8BB0\u5FC6\u5DE5\u5177\u7EF4\u62A4\u3002\u4EC5\u8BB0\u5F55\u53EF\u957F\u671F\u590D\u7528\u7684\u7528\u6237\u4FE1\u606F\u3001\u4E60\u60EF\u548C\u504F\u597D\uFF1B\u4E0D\u8981\u8BB0\u5F55\u5BC6\u7801\u3001\u5BC6\u94A5\u3001\u4EE4\u724C\u7B49\u654F\u611F\u4FE1\u606F\u3002
@@ -25287,7 +25375,7 @@ async function updateSemanticMemory(memoryFilePath, content) {
25287
25375
  `, "utf-8");
25288
25376
  return `\u5DF2\u66F4\u65B0\u7528\u6237\u8BED\u4E49\u8BB0\u5FC6: ${memoryFilePath}`;
25289
25377
  }
25290
- var readSemanticMemoryTool = (0, import_langchain12.tool)(
25378
+ var readSemanticMemoryTool = (0, import_langchain13.tool)(
25291
25379
  async (_input, runtime) => safeTool(() => readSemanticMemory(getMemoryFilePath(runtime.context?.memoryFilePath))),
25292
25380
  {
25293
25381
  name: "read_user_semantic_memory",
@@ -25295,7 +25383,7 @@ var readSemanticMemoryTool = (0, import_langchain12.tool)(
25295
25383
  schema: external_exports.object({})
25296
25384
  }
25297
25385
  );
25298
- var updateSemanticMemoryTool = (0, import_langchain12.tool)(
25386
+ var updateSemanticMemoryTool = (0, import_langchain13.tool)(
25299
25387
  async ({ content }, runtime) => safeTool(() => updateSemanticMemory(getMemoryFilePath(runtime.context?.memoryFilePath), content)),
25300
25388
  {
25301
25389
  name: "update_user_semantic_memory",
@@ -25355,7 +25443,7 @@ var TaskQueue = class {
25355
25443
  };
25356
25444
 
25357
25445
  // src/agent/tools/task.ts
25358
- var import_langchain13 = require("langchain");
25446
+ var import_langchain14 = require("langchain");
25359
25447
  function getCurrentTaskQueue(agentId) {
25360
25448
  return agentId ? new TaskQueue(agentId) : null;
25361
25449
  }
@@ -25387,7 +25475,7 @@ function manageTaskQueue(agentId, action, task, index) {
25387
25475
  queue.clearTasks();
25388
25476
  return "\u5DF2\u6E05\u7A7A\u4EFB\u52A1\u961F\u5217";
25389
25477
  }
25390
- var taskTool = (0, import_langchain13.tool)(
25478
+ var taskTool = (0, import_langchain14.tool)(
25391
25479
  async ({ action, task, index }, runtime) => safeTool(() => {
25392
25480
  const agentId = runtime.context?.agentId || getAgentId();
25393
25481
  return manageTaskQueue(agentId, action, task, index);
@@ -25404,7 +25492,7 @@ var taskTool = (0, import_langchain13.tool)(
25404
25492
  );
25405
25493
 
25406
25494
  // src/agent/tools/webfetch.ts
25407
- var import_langchain14 = require("langchain");
25495
+ var import_langchain15 = require("langchain");
25408
25496
  async function webFetch(url2, timeout = 3e4, maxLength = 6e4) {
25409
25497
  const controller = new AbortController();
25410
25498
  const timer = setTimeout(() => controller.abort(), timeout);
@@ -25437,7 +25525,7 @@ async function webFetch(url2, timeout = 3e4, maxLength = 6e4) {
25437
25525
  clearTimeout(timer);
25438
25526
  }
25439
25527
  }
25440
- var webFetchTool = (0, import_langchain14.tool)(async ({ url: url2, timeout, maxLength }) => safeTool(() => webFetch(url2, timeout, maxLength)), {
25528
+ var webFetchTool = (0, import_langchain15.tool)(async ({ url: url2, timeout, maxLength }) => safeTool(() => webFetch(url2, timeout, maxLength)), {
25441
25529
  name: "web_fetch",
25442
25530
  description: "\u901A\u8FC7 HTTP GET \u83B7\u53D6\u7F51\u9875\u3001\u63A5\u53E3\u6216\u8FDC\u7A0B\u6587\u672C\u5185\u5BB9\uFF0C\u5E76\u8FD4\u56DE\u72B6\u6001\u7801\u3001content-type \u548C\u54CD\u5E94\u6B63\u6587\u3002",
25443
25531
  schema: external_exports.object({
@@ -25450,7 +25538,7 @@ var webFetchTool = (0, import_langchain14.tool)(async ({ url: url2, timeout, max
25450
25538
  // src/agent/tools/write.ts
25451
25539
  var import_fs_extra17 = __toESM(require("fs-extra"));
25452
25540
  var import_path15 = __toESM(require("path"));
25453
- var import_langchain15 = require("langchain");
25541
+ var import_langchain16 = require("langchain");
25454
25542
  async function writeFile2(filePath, content, mode = "overwrite") {
25455
25543
  const absPath = resolveWorkspacePath(filePath);
25456
25544
  const exists = await import_fs_extra17.default.pathExists(absPath);
@@ -25465,7 +25553,7 @@ async function writeFile2(filePath, content, mode = "overwrite") {
25465
25553
  await import_fs_extra17.default.writeFile(absPath, content, "utf-8");
25466
25554
  return `${exists ? "\u5DF2\u8986\u76D6\u5199\u5165\u6587\u4EF6" : "\u5DF2\u521B\u5EFA\u6587\u4EF6"}: ${absPath}`;
25467
25555
  }
25468
- var writeFileTool = (0, import_langchain15.tool)(async ({ filePath, content, mode }) => safeTool(() => writeFile2(filePath, content, mode)), {
25556
+ var writeFileTool = (0, import_langchain16.tool)(async ({ filePath, content, mode }) => safeTool(() => writeFile2(filePath, content, mode)), {
25469
25557
  name: "write_file",
25470
25558
  description: "\u5411\u672C\u5730\u6587\u4EF6\u5199\u5165\u6587\u672C\u5185\u5BB9\u3002\u53EF\u521B\u5EFA\u65B0\u6587\u4EF6\u3001\u8986\u76D6\u5DF2\u6709\u6587\u4EF6\u6216\u8FFD\u52A0\u5185\u5BB9\uFF0C\u4F1A\u81EA\u52A8\u521B\u5EFA\u7236\u76EE\u5F55\u3002",
25471
25559
  schema: external_exports.object({
@@ -25478,6 +25566,7 @@ var writeFileTool = (0, import_langchain15.tool)(async ({ filePath, content, mod
25478
25566
  // src/agent/tools/index.ts
25479
25567
  var builtinTools = [
25480
25568
  taskTool,
25569
+ subAgentTool,
25481
25570
  executeCommandTool,
25482
25571
  readFileTool,
25483
25572
  editFileTool,
@@ -25490,8 +25579,8 @@ var builtinTools = [
25490
25579
  ...semanticMemoryTools,
25491
25580
  ...learnTools
25492
25581
  ];
25493
- async function getTools() {
25494
- return [...builtinTools, ...await scanUserTools(), ...await scanUserMcp()];
25582
+ async function getTools(excludeTools, excludeMCP) {
25583
+ return [...builtinTools, ...await scanUserTools(excludeTools), ...await scanUserMcp(excludeMCP)];
25495
25584
  }
25496
25585
 
25497
25586
  // src/agent/skills/index.ts
@@ -25501,15 +25590,217 @@ function getSkills() {
25501
25590
  }
25502
25591
 
25503
25592
  // src/agent/AIAgent/index.ts
25593
+ var import_os4 = __toESM(require("os"));
25594
+
25595
+ // src/agent/AIAgent/SubAgents/SubAIAgent.ts
25596
+ var import_langchain17 = require("langchain");
25597
+ var import_deepagents = require("deepagents");
25598
+ var import_eventemitter_super = require("eventemitter-super");
25504
25599
  var import_os3 = __toESM(require("os"));
25505
- var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25600
+ var import_crypto4 = require("crypto");
25601
+ var import_lodash = require("lodash");
25602
+ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitterSuper {
25603
+ id = "";
25604
+ opt = {};
25605
+ tools = [];
25606
+ dynamicTools = [];
25607
+ skills = [];
25608
+ mcp = [];
25609
+ subLevel = 1;
25610
+ agent = {};
25611
+ messages = [];
25612
+ basespace = "";
25613
+ workspace = "";
25614
+ memoryFilePath = "";
25615
+ sessionDirPath = "";
25616
+ userStorePath = "";
25617
+ agentRulesPath = "";
25618
+ isPrintThinking = true;
25619
+ maxSubAgentCount = 2;
25620
+ excludeTools = [];
25621
+ excludeSkills = [];
25622
+ excludeMCP = [];
25623
+ systemPrompt = "";
25624
+ constructor(opt) {
25625
+ super();
25626
+ this.opt = (0, import_lodash.cloneDeep)(opt);
25627
+ this.id = opt.id || `agent-${(0, import_crypto4.randomUUID)()}`;
25628
+ this.basespace = opt.basespace;
25629
+ this.workspace = opt.workspace;
25630
+ this.memoryFilePath = opt.memoryFilePath;
25631
+ this.sessionDirPath = opt.sessionDirPath;
25632
+ this.userStorePath = opt.userStorePath;
25633
+ this.agentRulesPath = opt.agentRulesPath;
25634
+ this.isPrintThinking = opt.isPrintThinking;
25635
+ this.excludeTools = opt.excludeTools || [];
25636
+ this.excludeSkills = opt.excludeSkills || [];
25637
+ this.excludeMCP = opt.excludeMCP || [];
25638
+ this.systemPrompt = opt.systemPrompt || "";
25639
+ this.subLevel = opt.subLevel || 1;
25640
+ this.maxSubAgentCount = opt.maxSubAgentCount || 2;
25641
+ }
25642
+ async init() {
25643
+ if (this.subLevel > 2) {
25644
+ this.excludeTools.push("subAgent_exec");
25645
+ }
25646
+ this.tools = await getTools(this.excludeTools, this.excludeMCP);
25647
+ this.skills = [...getSkills(), ...this.opt.skills || []];
25648
+ const model = getModel(this.opt.modelOpt);
25649
+ const checkpointer = new FileSystemSaver({
25650
+ rootFolder: this.sessionDirPath
25651
+ });
25652
+ const contextSchema = external_exports.object({
25653
+ agent_name: external_exports.string(),
25654
+ encoding: external_exports.string(),
25655
+ skills: external_exports.array(external_exports.string()).optional(),
25656
+ memoryFilePath: external_exports.string().optional(),
25657
+ agentId: external_exports.string().optional(),
25658
+ curAgent: external_exports.object().optional()
25659
+ });
25660
+ const systemPrompt = this.subLevel > 2 ? getSystemPrompt({
25661
+ systemPrompt: this.systemPrompt,
25662
+ workspace: this.workspace,
25663
+ osType: import_os3.default.platform(),
25664
+ skills: this.skills,
25665
+ memoryFilePath: this.memoryFilePath,
25666
+ agentRulesPath: this.agentRulesPath,
25667
+ excludeSkills: this.excludeSkills
25668
+ }) : subSystemPrompt(this.workspace, import_os3.default.platform(), this.skills, this.excludeSkills);
25669
+ const agent = (0, import_langchain17.createAgent)({
25670
+ model,
25671
+ checkpointer,
25672
+ tools: this.tools,
25673
+ contextSchema,
25674
+ middleware: [
25675
+ createAgentEventMiddleware(this),
25676
+ (0, import_langchain17.summarizationMiddleware)({
25677
+ model,
25678
+ trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
25679
+ keep: { messages: 50 }
25680
+ }),
25681
+ (0, import_langchain17.humanInTheLoopMiddleware)({
25682
+ interruptOn: {
25683
+ install_package: {
25684
+ allowedDecisions: ["approve", "reject"]
25685
+ },
25686
+ readEmailTool: false
25687
+ }
25688
+ }),
25689
+ (0, import_langchain17.todoListMiddleware)(),
25690
+ (0, import_deepagents.createPatchToolCallsMiddleware)()
25691
+ ],
25692
+ systemPrompt
25693
+ });
25694
+ await checkpointer.init(this.id, agent);
25695
+ this.agent = agent;
25696
+ this.initEvents();
25697
+ }
25698
+ async execute(input) {
25699
+ const humanMessage = new import_langchain17.HumanMessage(input);
25700
+ this.messages.push(humanMessage);
25701
+ const stream = await this.agent.stream(
25702
+ { messages: this.messages },
25703
+ {
25704
+ streamMode: ["messages"],
25705
+ recursionLimit: 2e3,
25706
+ subgraphs: true,
25707
+ configurable: { thread_id: this.id },
25708
+ context: {
25709
+ agent_name: "deepfish",
25710
+ encoding: this.opt.encoding,
25711
+ skills: this.skills,
25712
+ memoryFilePath: this.memoryFilePath,
25713
+ agentId: this.id,
25714
+ curAgent: this
25715
+ }
25716
+ }
25717
+ );
25718
+ return new Promise(async (resolve) => {
25719
+ this.once("TASK_AFTER" /* TASK_AFTER */, (msg) => {
25720
+ resolve(msg);
25721
+ });
25722
+ for await (const [_namespace, mode, data] of stream) {
25723
+ if (mode === "messages") {
25724
+ const message = data[0].additional_kwargs.reasoning_content;
25725
+ this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, message);
25726
+ }
25727
+ }
25728
+ });
25729
+ }
25730
+ initEvents() {
25731
+ const thinking = new Thinking();
25732
+ this.on("TASK_BEFORE" /* TASK_BEFORE */, () => {
25733
+ });
25734
+ this.on("TASK_AFTER" /* TASK_AFTER */, (msg) => {
25735
+ logInfo(msg);
25736
+ });
25737
+ this.on("MODEL_BEFORE" /* MODEL_BEFORE */, () => {
25738
+ });
25739
+ this.on("MODEL_AFTER" /* MODEL_AFTER */, () => {
25740
+ if (this.isPrintThinking) {
25741
+ thinking.stop();
25742
+ }
25743
+ });
25744
+ this.on("MODEL_ERROR" /* MODEL_ERROR */, (error51) => {
25745
+ if (this.isPrintThinking) {
25746
+ thinking.stop();
25747
+ }
25748
+ logError(error51?.message + "\n" + error51?.stack);
25749
+ });
25750
+ this.on("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, (content) => {
25751
+ if (this.isPrintThinking) {
25752
+ if (content && typeof content === "string") {
25753
+ streamOutput(content, "#f2c97d");
25754
+ }
25755
+ } else {
25756
+ if (content && typeof content === "string") {
25757
+ thinking.start();
25758
+ } else {
25759
+ thinking.stop();
25760
+ }
25761
+ }
25762
+ });
25763
+ this.on("COMPRESS_MESSAGES_BEFORE" /* COMPRESS_MESSAGES_BEFORE */, (_currentLength) => {
25764
+ });
25765
+ this.on("COMPRESS_MESSAGES_AFTER" /* COMPRESS_MESSAGES_AFTER */, (_currentLength) => {
25766
+ });
25767
+ this.on("NEW_MESSAGE" /* NEW_MESSAGE */, (_msg) => {
25768
+ });
25769
+ this.on("USE_TOOL_BEFORE" /* USE_TOOL_BEFORE */, (_toolId, funcName, _funcArgs) => {
25770
+ log(`[Tool Call] ${funcName}`, "#c2a654");
25771
+ });
25772
+ this.on("USE_TOOL_RETURN" /* USE_TOOL_RETURN */, (_toolId, _funcName, _toolContent) => {
25773
+ logInfo(`[Tool Return] ${_funcName} returned: ${_toolContent}`);
25774
+ });
25775
+ this.on("USE_TOOL_ERROR" /* USE_TOOL_ERROR */, (_toolId, _funcName, _error) => {
25776
+ logError(`Error in tool ${_funcName}: ${_error instanceof Error ? _error.message : String(_error)}`);
25777
+ });
25778
+ this.on("USE_TOOL_AFTER" /* USE_TOOL_AFTER */, (_toolId, _funcName, _funcArgs) => {
25779
+ });
25780
+ }
25781
+ async createSubAgent() {
25782
+ const subAgent = new _SubAIAgent(this.opt);
25783
+ subAgent.subLevel = this.subLevel + 1;
25784
+ await subAgent.init();
25785
+ return subAgent;
25786
+ }
25787
+ destory() {
25788
+ this.removeAllListeners();
25789
+ }
25790
+ };
25791
+
25792
+ // src/agent/AIAgent/index.ts
25793
+ var import_lodash2 = require("lodash");
25794
+ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
25506
25795
  id = "";
25796
+ threadId = "main_session_records";
25507
25797
  opt = {};
25508
25798
  tools = [];
25509
25799
  dynamicTools = [];
25510
25800
  skills = [];
25511
25801
  mcp = [];
25512
25802
  subLevel = 0;
25803
+ maxSubAgentCount = 2;
25513
25804
  agent = {};
25514
25805
  messages = [];
25515
25806
  basespace = "";
@@ -25521,8 +25812,13 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25521
25812
  roomClient = null;
25522
25813
  taskQueue = {};
25523
25814
  isPrintThinking = true;
25815
+ excludeTools = [];
25816
+ excludeSkills = [];
25817
+ excludeMCP = [];
25818
+ systemPrompt = "";
25524
25819
  constructor(opt) {
25525
25820
  super();
25821
+ this.opt = (0, import_lodash2.cloneDeep)(opt);
25526
25822
  this.id = opt.id || `agent-${Date.now()}`;
25527
25823
  this.basespace = opt.basespace;
25528
25824
  this.workspace = opt.workspace;
@@ -25531,10 +25827,15 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25531
25827
  this.userStorePath = opt.userStorePath;
25532
25828
  this.agentRulesPath = opt.agentRulesPath;
25533
25829
  this.isPrintThinking = opt.isPrintThinking;
25534
- this.opt = opt;
25830
+ this.excludeTools = opt.excludeTools || [];
25831
+ this.excludeSkills = opt.excludeSkills || [];
25832
+ this.excludeMCP = opt.excludeMCP || [];
25833
+ this.systemPrompt = opt.systemPrompt || "";
25834
+ this.subLevel = 0;
25835
+ this.maxSubAgentCount = opt.maxSubAgentCount || 2;
25535
25836
  }
25536
25837
  async init() {
25537
- this.tools = await getTools();
25838
+ this.tools = await getTools(this.excludeTools, this.excludeMCP);
25538
25839
  this.skills = [...getSkills(), ...this.opt.skills || []];
25539
25840
  const model = getModel(this.opt.modelOpt);
25540
25841
  const checkpointer = new FileSystemSaver({
@@ -25545,21 +25846,22 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25545
25846
  encoding: external_exports.string(),
25546
25847
  skills: external_exports.array(external_exports.string()).optional(),
25547
25848
  memoryFilePath: external_exports.string().optional(),
25548
- agentId: external_exports.string().optional()
25849
+ agentId: external_exports.string().optional(),
25850
+ curAgent: external_exports.object().optional()
25549
25851
  });
25550
- const agent = (0, import_langchain16.createAgent)({
25852
+ const agent = (0, import_langchain18.createAgent)({
25551
25853
  model,
25552
25854
  checkpointer,
25553
25855
  tools: this.tools,
25554
25856
  contextSchema,
25555
25857
  middleware: [
25556
25858
  createAgentEventMiddleware(this),
25557
- (0, import_langchain16.summarizationMiddleware)({
25859
+ (0, import_langchain18.summarizationMiddleware)({
25558
25860
  model,
25559
25861
  trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
25560
25862
  keep: { messages: 50 }
25561
25863
  }),
25562
- (0, import_langchain16.humanInTheLoopMiddleware)({
25864
+ (0, import_langchain18.humanInTheLoopMiddleware)({
25563
25865
  interruptOn: {
25564
25866
  install_package: {
25565
25867
  allowedDecisions: ["approve", "reject"]
@@ -25567,30 +25869,26 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25567
25869
  readEmailTool: false
25568
25870
  }
25569
25871
  }),
25570
- (0, import_langchain16.todoListMiddleware)(),
25571
- (0, import_deepagents.createPatchToolCallsMiddleware)(),
25572
- (0, import_deepagents.createSubAgentMiddleware)({
25573
- defaultModel: model,
25574
- subagents: [
25575
- {
25576
- name: "subagent",
25577
- description: "This subagent can execute sub tasks.",
25578
- systemPrompt: subSystemPrompt(this.workspace, import_os3.default.platform(), this.skills),
25579
- tools: this.tools,
25580
- model,
25581
- middleware: []
25582
- }
25583
- ]
25584
- })
25872
+ (0, import_langchain18.todoListMiddleware)(),
25873
+ (0, import_deepagents2.createPatchToolCallsMiddleware)()
25585
25874
  ],
25586
- systemPrompt: systemPrompt(this.workspace, import_os3.default.platform(), this.skills, this.memoryFilePath, this.agentRulesPath)
25875
+ systemPrompt: getSystemPrompt({
25876
+ systemPrompt: this.systemPrompt,
25877
+ workspace: this.workspace,
25878
+ osType: import_os4.default.platform(),
25879
+ skills: this.skills,
25880
+ memoryFilePath: this.memoryFilePath,
25881
+ agentRulesPath: this.agentRulesPath,
25882
+ excludeSkills: this.excludeSkills
25883
+ })
25587
25884
  });
25885
+ await checkpointer.init(this.threadId, agent);
25588
25886
  this.agent = agent;
25589
25887
  this.taskQueue = new TaskQueue(this.id);
25590
25888
  this.initEvents();
25591
25889
  }
25592
25890
  async execute(input) {
25593
- const humanMessage = new import_langchain16.HumanMessage(input);
25891
+ const humanMessage = new import_langchain18.HumanMessage(input);
25594
25892
  this.messages.push(humanMessage);
25595
25893
  const stream = await this.agent.stream(
25596
25894
  { messages: this.messages },
@@ -25598,14 +25896,23 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25598
25896
  streamMode: ["messages"],
25599
25897
  recursionLimit: 2e3,
25600
25898
  subgraphs: true,
25601
- configurable: { thread_id: this.id },
25602
- context: { agent_name: "deepfish", encoding: this.opt.encoding, skills: this.skills, memoryFilePath: this.memoryFilePath, agentId: this.id }
25899
+ configurable: { thread_id: this.threadId },
25900
+ context: {
25901
+ agent_name: "deepfish",
25902
+ encoding: this.opt.encoding,
25903
+ skills: this.skills,
25904
+ memoryFilePath: this.memoryFilePath,
25905
+ agentId: this.id,
25906
+ curAgent: this
25907
+ }
25603
25908
  }
25604
25909
  );
25605
25910
  for await (const [_namespace, mode, data] of stream) {
25606
25911
  if (mode === "messages") {
25607
- const message = data[0].additional_kwargs.reasoning_content;
25608
- this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, message);
25912
+ const message = data?.[0];
25913
+ const reasoning_content = message?.additional_kwargs?.reasoning_content;
25914
+ const toolcall_content = message?.tool_call_chunks?.[0]?.args;
25915
+ this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, reasoning_content || toolcall_content || "");
25609
25916
  }
25610
25917
  }
25611
25918
  const newTask = this.taskQueue.getTask();
@@ -25618,8 +25925,8 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25618
25925
  const thinking = new Thinking();
25619
25926
  this.on("TASK_BEFORE" /* TASK_BEFORE */, () => {
25620
25927
  });
25621
- this.on("TASK_AFTER" /* TASK_AFTER */, (msg) => {
25622
- logInfo(msg);
25928
+ this.on("TASK_AFTER" /* TASK_AFTER */, (_msg) => {
25929
+ logSuccess(_msg);
25623
25930
  });
25624
25931
  this.on("MODEL_BEFORE" /* MODEL_BEFORE */, () => {
25625
25932
  });
@@ -25627,6 +25934,7 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25627
25934
  if (this.isPrintThinking) {
25628
25935
  thinking.stop();
25629
25936
  }
25937
+ streamOutput("\n");
25630
25938
  });
25631
25939
  this.on("MODEL_ERROR" /* MODEL_ERROR */, (error51) => {
25632
25940
  if (this.isPrintThinking) {
@@ -25656,13 +25964,20 @@ var AIAgent = class extends import_eventemitter_super.EventEmitterSuper {
25656
25964
  this.on("USE_TOOL_BEFORE" /* USE_TOOL_BEFORE */, (_toolId, funcName, _funcArgs) => {
25657
25965
  log(`[Tool Call] ${funcName}`, "#c2a654");
25658
25966
  });
25659
- this.on("USE_TOOL_RETURN" /* USE_TOOL_RETURN */, (_toolId, _funcName, _toolContent) => {
25967
+ this.on("USE_TOOL_RETURN" /* USE_TOOL_RETURN */, (_toolId, _funcName, _toolContent = "") => {
25968
+ logInfo(`[Tool Return] ${_funcName} returned: ${_toolContent.length > 50 ? _toolContent.slice(0, 50) + "..." : _toolContent}`);
25660
25969
  });
25661
25970
  this.on("USE_TOOL_ERROR" /* USE_TOOL_ERROR */, (_toolId, _funcName, _error) => {
25971
+ logError(`Error in tool ${_funcName}: ${_error instanceof Error ? _error.message : String(_error)}`);
25662
25972
  });
25663
25973
  this.on("USE_TOOL_AFTER" /* USE_TOOL_AFTER */, (_toolId, _funcName, _funcArgs) => {
25664
25974
  });
25665
25975
  }
25976
+ async createSubAgent() {
25977
+ const subAgent = new SubAIAgent(this.opt);
25978
+ await subAgent.init();
25979
+ return subAgent;
25980
+ }
25666
25981
  destory() {
25667
25982
  this.removeAllListeners();
25668
25983
  }
@@ -26053,7 +26368,7 @@ function initSession() {
26053
26368
  initSessionDir(existingSession.id);
26054
26369
  return existingSession;
26055
26370
  }
26056
- const agentId = (0, import_crypto4.randomUUID)();
26371
+ const agentId = (0, import_crypto5.randomUUID)();
26057
26372
  const newSession = {
26058
26373
  id: agentId,
26059
26374
  name: import_path18.default.basename(workspace),
@@ -26106,15 +26421,15 @@ function getAgentId() {
26106
26421
  // src/cli/cli-core/skills.ts
26107
26422
  function handleSkillsLs() {
26108
26423
  const skills = _getAllSkills();
26109
- console.log("=".repeat(50));
26424
+ logInfo("=".repeat(50));
26110
26425
  if (skills.length === 0) {
26111
26426
  logInfo("No skills registered yet");
26112
26427
  } else {
26113
26428
  skills.forEach((skill, index) => {
26114
- console.log(`[${index}] ${skill.name} (${skill.isEnabled ? "enabled" : "disabled"})`);
26429
+ logInfo(`[${index}] ${skill.name} (${skill.isEnabled ? "enabled" : "disabled"})`);
26115
26430
  });
26116
26431
  }
26117
- console.log("=".repeat(50));
26432
+ logInfo("=".repeat(50));
26118
26433
  }
26119
26434
  async function handleSkillsAdd(name) {
26120
26435
  logInfo(`Adding skill: ${name}`);
@@ -26126,7 +26441,7 @@ async function handleSkillsAdd(name) {
26126
26441
  }
26127
26442
  const { scope } = await import_inquirer3.default.prompt([
26128
26443
  {
26129
- type: "list",
26444
+ type: "select",
26130
26445
  name: "scope",
26131
26446
  message: "Select skill scope:",
26132
26447
  choices: [
@@ -26292,7 +26607,7 @@ function _updateRegister(skillsDir) {
26292
26607
  const existItem = register.find((item) => item.skillPath === skillPath);
26293
26608
  if (!existItem) {
26294
26609
  newRegister.push({
26295
- id: (0, import_crypto5.randomUUID)(),
26610
+ id: (0, import_crypto6.randomUUID)(),
26296
26611
  name: skillName,
26297
26612
  isEnabled: true,
26298
26613
  skillPath
@@ -26375,7 +26690,7 @@ async function handleToolsAdd(name) {
26375
26690
  }
26376
26691
  const { scope } = await import_inquirer4.default.prompt([
26377
26692
  {
26378
- type: "list",
26693
+ type: "select",
26379
26694
  name: "scope",
26380
26695
  message: "Select tool scope:",
26381
26696
  choices: [
@@ -26720,7 +27035,7 @@ function handleCacheList() {
26720
27035
  }
26721
27036
  catalog.forEach((item, index) => {
26722
27037
  const desc = item.description.length > 20 ? item.description.slice(0, 20) + "..." : item.description;
26723
- console.log(`[${index}] ${item.id} ${desc}`);
27038
+ logInfo(`${index}. ${item.id} - ${desc}`);
26724
27039
  });
26725
27040
  }
26726
27041
  function handleCacheEdit(input) {