deepfish-ai 1.0.17 → 1.0.19

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.
Files changed (62) hide show
  1. package/README.md +31 -45
  2. package/README_CN.md +32 -46
  3. package/package.json +18 -2
  4. package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +105 -0
  5. package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +57 -0
  6. package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +45 -0
  7. package/src/AgentRobot/AgentRobotFactory/index.js +53 -0
  8. package/src/AgentRobot/BaseAgentRobot/Brain.js +203 -0
  9. package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +17 -0
  10. package/src/AgentRobot/BaseAgentRobot/Hand.js +119 -0
  11. package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
  12. package/src/AgentRobot/BaseAgentRobot/Logger.js +108 -0
  13. package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +49 -0
  14. package/src/AgentRobot/BaseAgentRobot/index.js +335 -0
  15. package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +708 -0
  16. package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +737 -0
  17. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +734 -0
  18. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +539 -0
  19. package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +586 -0
  20. package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +12 -0
  21. package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +125 -0
  22. package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +675 -0
  23. package/src/{core/extension/GenerateExtension.js → AgentRobot/BaseAgentRobot/tools/GenerateTools.js} +176 -82
  24. package/src/{core/extension/InquirerExtension.js → AgentRobot/BaseAgentRobot/tools/InquirerTools.js} +11 -9
  25. package/src/{core/extension/SystemExtension.js → AgentRobot/BaseAgentRobot/tools/SystemTools.js} +42 -108
  26. package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +210 -0
  27. package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +99 -0
  28. package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +241 -0
  29. package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +207 -0
  30. package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +236 -0
  31. package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +74 -0
  32. package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +78 -0
  33. package/src/{core → AgentRobot/BaseAgentRobot}/utils/node-root.js +32 -34
  34. package/src/{core → AgentRobot/BaseAgentRobot}/utils/normal.js +8 -4
  35. package/src/cli/ConfigManager.js +56 -38
  36. package/src/cli/DefaultConfig.js +50 -28
  37. package/src/{core → cli}/GlobalVariable.js +2 -4
  38. package/src/cli/MemoryManager.js +53 -0
  39. package/src/cli/SkillConfigManager.js +72 -60
  40. package/src/cli/SkillParser.js +4 -7
  41. package/src/cli/ai-config.js +17 -14
  42. package/src/cli/ai-memory.js +22 -0
  43. package/src/cli/ai-skill.js +33 -33
  44. package/src/cli/index.js +45 -39
  45. package/src/index.js +53 -6
  46. package/src/cli/ExtConfigManager.js +0 -90
  47. package/src/cli/HistoryManager.js +0 -293
  48. package/src/cli/ai-ext.js +0 -36
  49. package/src/cli/ai-history.js +0 -36
  50. package/src/core/AICLI.js +0 -98
  51. package/src/core/ai-services/AiWorker/AIMessageManager.js +0 -173
  52. package/src/core/ai-services/AiWorker/AiAgent.js +0 -150
  53. package/src/core/ai-services/AiWorker/AiPrompt.js +0 -135
  54. package/src/core/ai-services/AiWorker/AiTools.js +0 -368
  55. package/src/core/ai-services/AiWorker/index.js +0 -180
  56. package/src/core/ai-services/index.js +0 -39
  57. package/src/core/extension/BaseExtension.js +0 -9
  58. package/src/core/extension/ExtensionManager.js +0 -204
  59. package/src/core/extension/FileExtension.js +0 -439
  60. package/src/core/extension/TaskExtension.js +0 -169
  61. package/src/core/extension/TestExtension.js +0 -67
  62. package/src/core/utils/log.js +0 -157
package/README.md CHANGED
@@ -10,13 +10,13 @@
10
10
  alt="WeChat"
11
11
  src="https://img.shields.io/badge/WeChat-MrRoman_123-green.svg"
12
12
  />
13
- <a href="https://github.com/qq306863030/deepfish">
13
+ <a href="https://github.com/qq306863030/deepfish-ai">
14
14
  <img
15
15
  alt="GitHub"
16
- src="https://img.shields.io/badge/GitHub-DeepFish-blue.svg"
16
+ src="https://img.shields.io/badge/GitHub-DeepFish AI-blue.svg"
17
17
  /></a>
18
- <a href="https://www.npmjs.com/package/deepfish">
19
- <img alt="NPM" src="https://img.shields.io/badge/NPM-DeepFish-blue.svg"
18
+ <a href="https://www.npmjs.com/package/deepfish-ai">
19
+ <img alt="NPM" src="https://img.shields.io/badge/NPM-DeepFish AI-blue.svg"
20
20
  /></a>
21
21
  <img
22
22
  alt="Code License"
@@ -109,7 +109,7 @@ npm link
109
109
 
110
110
  ```bash
111
111
  ai config add # Enter a name, then select deepseek, and enter your DeepSeek API key
112
- ai use [the_name_you_entered]
112
+ ai config use [the_name_you_entered]
113
113
  ai "Help me write an article about future technology in the current directory, output in markdown format"
114
114
  ```
115
115
 
@@ -145,13 +145,6 @@ ai config view [name] # View details of the specified AI configuration
145
145
  ai config edit # Edit the configuration file manually
146
146
  ai config dir # Open the configuration file directory
147
147
  ai config reset # Reset configuration
148
- ai config clear # Delete the configuration file
149
-
150
- # Extension commands
151
- ai ext add <filename> # Add an extension tool
152
- ai ext del <filepath> # Remove an extension tool by file path
153
- ai ext del <index> # Remove an extension tool by index
154
- ai ext ls # List all extension tools
155
148
 
156
149
  # Skill commands
157
150
  ai skill ls # List all registered skills
@@ -162,11 +155,9 @@ ai skill enable <name|index> # Enable a skill by name or index, exp: ai skill en
162
155
  ai skill disable <name|index> # Disable a skill by name or index, exp: ai skill disable 1
163
156
  ai skill dir # Open the skill directory
164
157
 
165
- # History commands
166
- ai history clear # Clear the history messages for the current directory
167
- ai history output # Output the history messages to current directory
168
- ai history dir # Open the history directory
169
- ai history reset # Reset all history for all directories
158
+ # Memory commands
159
+ ai memery clear # Clear the history messages for the current directory
160
+ ai memery dir # Open the memory directory
170
161
  ```
171
162
 
172
163
  ### Configuration File Structure
@@ -174,7 +165,7 @@ ai history reset # Reset all history for all directories
174
165
  The configuration file (`~/.deepfish-ai/config.js`) has the following structure:
175
166
 
176
167
  ```javascript
177
- module.exports = {
168
+ export default {
178
169
  ai: [
179
170
  {
180
171
  name: "default", // AI configuration name
@@ -182,8 +173,9 @@ module.exports = {
182
173
  baseUrl: "https://api.deepseek.com", // API base URL
183
174
  model: "deepseek-reasoner", // AI model name
184
175
  apiKey: "", // API key (required for DeepSeek and OpenAI)
185
- temperature: 1, // Response randomness (0-2)
186
- maxTokens: 8192, // Maximum response length
176
+ temperature: 0.7, // Response randomness (0-2)
177
+ maxTokens: 8, // Maximum response length (KB)
178
+ maxContextLength: 64, // Maximum context length (KB)
187
179
  stream: true, // Enable/disable streaming output
188
180
  }
189
181
  ],
@@ -191,12 +183,11 @@ module.exports = {
191
183
  maxIterations: -1, // Maximum iterations for AI to complete the workflow, -1 for unlimited
192
184
  maxMessagesLength: 150000, // Maximum compression length, -1 for unlimited
193
185
  maxMessagesCount: 100, // Maximum compression count, -1 for unlimited
194
- maxHistoryExpireTime: 30, // Maximum session expiration time in days, -1 for unlimited, 0 to disable recording
186
+ maxMemoryExpireTime: 30, // Maximum session expiration time in days, -1 for unlimited, 0 to disable recording
195
187
  maxLogExpireTime: 3, // Log expiration time in days, -1 for unlimited, 0 to disable recording
196
188
  maxBlockFileSize: 20, // Maximum block file size in KB; files exceeding this size need to be processed in blocks
197
- extensions: [], // List of extension file paths
198
189
  skills: [], // List of skill configurations
199
- encoding: "utf-8", // Command line encoding format, can be set to utf-8, gbk, etc., or auto/empty for auto-detection
190
+ encoding: "auto", // Command line encoding format, can be set to utf-8, gbk, etc., or auto/empty for auto-detection
200
191
  };
201
192
  ```
202
193
 
@@ -251,7 +242,6 @@ ai "Check disk usage for the current directory"
251
242
 
252
243
  ```bash
253
244
  ai "Create a weather.js extension tool for querying weather"
254
- ai ext add weather.js
255
245
  ```
256
246
 
257
247
  **Skill Management:**
@@ -289,6 +279,9 @@ ai "Classify all files under the 'model' directory into the 'model2' directory b
289
279
  ```bash
290
280
  ai "Create a task list: 1.xxxx; 2.xxxx; ..."
291
281
  ai "Execute task list" # Start execution
282
+
283
+ ai "I want to implement an extension tool for long-form novel writing that supports large-scale writing, maintains contextual logic coherence, and avoids AI context explosion issues. This extension tool may be a bit complex to implement. You need to carefully read the extension tool generation rules first, then create a task list"
284
+ ai "Execute task list" # Start execution
292
285
  ```
293
286
 
294
287
  ## 6. Extension Development
@@ -338,20 +331,13 @@ module.exports = {
338
331
 
339
332
  ### Registering Extensions
340
333
 
341
- **Method 1: Using Command Line**
342
-
343
- ```bash
344
- ai ext add <filename> # ai ext add weather.js
345
- ai ext add . # Traverse the current directory, automatically scan and add extensions
346
- ```
347
-
348
- **Method 2: Manual Configuration**
334
+ **Method 1: Manual Configuration**
349
335
 
350
336
  1. ai config edit
351
337
  2. Add it to your configuration:
352
338
 
353
339
  ```javascript
354
- module.exports = {
340
+ export default {
355
341
  // ... other configurations
356
342
  extensions: [
357
343
  '/path/to/weather-extension.js'
@@ -359,19 +345,19 @@ module.exports = {
359
345
  };
360
346
  ```
361
347
 
362
- **Method 3: Automatic Scanning**
348
+ **Method 2: Automatic Scanning**
363
349
 
364
350
  Rules for automatic scanning of extension modules upon program startup:
365
351
 
366
352
  1. Scanning locations:
367
- - node_modules in the npm root directory
368
- - node_modules in the command execution directory
369
- - the command execution directory itself
353
+ - the DeepFish installation directory (where `deepfish-ai` is located)
354
+ - `node_modules` under the current working directory
355
+ - the current working directory itself
370
356
 
371
357
  2. Scanned files:
372
- - Extension packages under the @deepfish-ai directory
373
- - Extension packages starting with "deepfish-"
374
- - JavaScript extension files in the command execution directory, which are automatically loaded if they contain the strings 'module.exports', 'descriptions', and 'functions'
358
+ - scoped packages under `@deepfish-ai/*` in the locations above
359
+ - packages starting with `deepfish-` in the locations above (excluding `deepfish-ai` itself)
360
+ - top-level `.js` / `.mjs` files in the current working directory are scanned additionally; files containing `module.exports`, `descriptions`, and `functions` are treated as auto-loadable extensions
375
361
 
376
362
  ## 7. Recommendations
377
363
 
@@ -398,12 +384,12 @@ AI always uses paths relative to the current working directory.
398
384
 
399
385
  Conversation history is created on a per-directory basis — each execution directory corresponds to its own Agent context. This means that conversations started in different directories are independent of each other.
400
386
 
401
- Conversation history will be automatically cleared after a configurable period (controlled by the `maxHistoryExpireTime` field in the configuration file, default is 30 days). You can also manage it manually:
387
+ > **⚠️ Important Note:** AI context is directory-based each directory corresponds to one context. **Please do not open two command-line dialogs in the same directory**, as this may cause context conflicts and unexpected behavior.
388
+
389
+ Conversation history will be automatically cleared after a configurable period (controlled by the `maxMemoryExpireTime` field in the configuration file, default is 30 days). You can also manage it manually:
402
390
 
403
- - `ai history dir` — Open the history directory to view stored conversation contexts
404
- - `ai history clear` — Manually clear the conversation history for the current directory
405
- - `ai history output` — Export the conversation history to the current directory
406
- - `ai history reset` — Reset all conversation history for all directories
391
+ - `ai memery dir` — Open the memory directory to view stored conversation contexts
392
+ - `ai memery clear` — Manually clear the conversation history for the current directory
407
393
 
408
394
  ## 9. Troubleshooting
409
395
 
package/README_CN.md CHANGED
@@ -10,13 +10,13 @@
10
10
  alt="WeChat"
11
11
  src="https://img.shields.io/badge/WeChat-MrRoman_123-green.svg"
12
12
  />
13
- <a href="https://github.com/qq306863030/deepfish">
13
+ <a href="https://github.com/qq306863030/deepfish-ai">
14
14
  <img
15
15
  alt="GitHub"
16
- src="https://img.shields.io/badge/GitHub-DeepFish-blue.svg"
16
+ src="https://img.shields.io/badge/GitHub-DeepFish AI-blue.svg"
17
17
  /></a>
18
- <a href="https://www.npmjs.com/package/deepfish">
19
- <img alt="NPM" src="https://img.shields.io/badge/NPM-DeepFish-blue.svg"
18
+ <a href="https://www.npmjs.com/package/deepfish-ai">
19
+ <img alt="NPM" src="https://img.shields.io/badge/NPM-DeepFish AI-blue.svg"
20
20
  /></a>
21
21
  <img
22
22
  alt="Code License"
@@ -107,7 +107,7 @@ npm link
107
107
 
108
108
  ```bash
109
109
  ai config add # 输入名称, 然后选择deepseek,并输入你的deepseek api key
110
- ai use 你输入的名称
110
+ ai config use 你输入的名称
111
111
  ai ”帮我在当前目录写一篇关于未来科技的文章,用markdown格式输出“
112
112
  ```
113
113
 
@@ -143,13 +143,6 @@ ai config view [name] # 查看指定AI配置的详细信息
143
143
  ai config edit # 编辑配置文件手动编辑配置文件
144
144
  ai config dir # 打开配置文件所在目录
145
145
  ai config reset # 重置配置
146
- ai config clear # 删除配置文件
147
-
148
- # 扩展命令
149
- ai ext add <filename> # 添加扩展工具
150
- ai ext del <filepath> # 通过文件路径移除扩展工具
151
- ai ext del <index> # 通过索引移除扩展工具
152
- ai ext ls # 列出所有扩展工具
153
146
 
154
147
  # Skill 命令
155
148
  ai skill ls # 列出所有已注册的 skill
@@ -160,11 +153,9 @@ ai skill enable <name|index> # 通过名称或索引启用 skill, exp: ai skill
160
153
  ai skill disable <name|index> # 通过名称或索引禁用 skill, exp: ai skill disable 1
161
154
  ai skill dir # 打开 skill 目录
162
155
 
163
- # 历史记录命令
164
- ai history clear # 清除当前目录的对话历史
165
- ai history output # 将历史消息输出到当前目录
166
- ai history dir # 打开历史记录目录
167
- ai history reset # 清除所有目录的对话历史
156
+ # 记忆命令
157
+ ai memery clear # 清除当前目录的对话历史
158
+ ai memery dir # 打开记忆目录
168
159
  ```
169
160
 
170
161
  ### 配置文件结构
@@ -172,7 +163,7 @@ ai history reset # 清除所有目录的对话历史
172
163
  配置文件 (`~/.deepfish-ai/config.js`) 具有以下结构:
173
164
 
174
165
  ```javascript
175
- module.exports = {
166
+ export default {
176
167
  ai: [
177
168
  {
178
169
  name: "default", // AI配置名称
@@ -180,8 +171,9 @@ module.exports = {
180
171
  baseUrl: "https://api.deepseek.com", // API基础URL
181
172
  model: "deepseek-reasoner", // AI模型名称
182
173
  apiKey: "", // API密钥(DeepSeek和OpenAI需要)
183
- temperature: 1, // 响应随机性(0-2)
184
- maxTokens: 8192, // 最大响应长度
174
+ temperature: 0.7, // 响应随机性(0-2)
175
+ maxTokens: 8, // 最大响应长度(KB)
176
+ maxContextLength: 64, // 最大上下文长度(KB)
185
177
  stream: true, // 启用/禁用流式输出
186
178
  }
187
179
  ],
@@ -189,12 +181,11 @@ module.exports = {
189
181
  maxIterations: -1, // ai完成工作流的最大迭代次数,-1表示无限制
190
182
  maxMessagesLength: 150000, // 最大压缩长度,-1表示无限制
191
183
  maxMessagesCount: 100, // 最大压缩数量,-1表示无限制
192
- maxHistoryExpireTime: 30, // 整个会话的最大过期时间,单位天,-1表示无限制,0表示不记录
184
+ maxMemoryExpireTime: 30, // 整个会话的最大过期时间,单位天,-1表示无限制,0表示不记录
193
185
  maxLogExpireTime: 3, // 日志过期时间,单位天,-1表示无限制,0表示不记录
194
186
  maxBlockFileSize: 20, // 最大分块文件大小,单位KB;超过该大小的文件需要分块处理
195
- extensions: [], // 扩展文件路径列表
196
187
  skills: [], // 技能配置列表
197
- encoding: "utf-8", // 命令行编码格式,可设置为utf-8、gbk等,也可以设置成auto或空值自动判断
188
+ encoding: "auto", // 命令行编码格式,可设置为utf-8、gbk等,也可以设置成auto或空值自动判断
198
189
  };
199
190
  ```
200
191
 
@@ -249,7 +240,6 @@ ai "检查当前目录的磁盘使用情况"
249
240
 
250
241
  ```bash
251
242
  ai "创建一个用于查询天气的扩展工具weather.js"
252
- ai ext add weather.js
253
243
  ```
254
244
 
255
245
  **Skill 管理:**
@@ -287,6 +277,9 @@ ai "将model目录下的所有文件按月份分类到model2目录中,日期
287
277
  ```bash
288
278
  ai "创建一个任务列表,1.xxxx;2.xxxx;..."
289
279
  ai "执行任务列表" # 开始执行
280
+
281
+ ai "我要实现一个用于长篇小说创作的扩展工具,支持大篇幅写作,保持上下文逻辑连贯,避免AI上下文爆炸问题。这个扩展工具实现起来可能有点复杂,你需要先仔细阅读扩展工具生成规则,然后创建一个任务列表"
282
+ ai "执行任务列表" # 开始执行
290
283
  ```
291
284
 
292
285
  ## 6. 扩展开发
@@ -336,20 +329,13 @@ module.exports = {
336
329
 
337
330
  ### 注册扩展
338
331
 
339
- **方法1:使用命令行**
340
-
341
- ```bash
342
- ai ext add <filename> # ai ext add weather.js
343
- ai ext add . # 遍历当前目录,自动扫描并添加扩展
344
- ```
345
-
346
- **方法2:手动配置**
332
+ **方法1:手动配置**
347
333
 
348
334
  1. ai config edit
349
335
  2. 将其添加到您的配置中:
350
336
 
351
337
  ```javascript
352
- module.exports = {
338
+ export default {
353
339
  // ... 其他配置
354
340
  extensions: [
355
341
  '/path/to/weather-extension.js'
@@ -357,17 +343,17 @@ module.exports = {
357
343
  };
358
344
  ```
359
345
 
360
- **方法3:自动扫描**
346
+ **方法2:自动扫描**
361
347
 
362
348
  程序启动时自动扫描扩展模块的规则:
363
349
  1. 扫描位置:
364
- - npm根目录的node_modules
365
- - 命令执行目录的node_modules
366
- - 命令执行目录
350
+ - 程序安装目录(deepfish-ai 程序所在目录)
351
+ - 当前工作目录的 node_modules 目录
352
+ - 当前工作目录
367
353
  2. 扫描文件:
368
- - @deepfish-ai目录下的扩展包
369
- - deepfish-开头的扩展包
370
- - 命令执行目录的js扩展文件,js文件内包含'module.exports'、'descriptions'和'functions'字符串则视为扩展文件自动加载
354
+ - 在以上目录中扫描 `@deepfish-ai/*` 作用域包
355
+ - 在以上目录中扫描 `deepfish-` 开头的包(排除 `deepfish-ai` 本体)
356
+ - 在当前工作目录额外扫描顶层 `.js` / `.mjs` 文件, 文件内容包含 `module.exports`、`descriptions`、`functions` 字符串时视为可自动加载扩展
371
357
 
372
358
  ## 7. 建议
373
359
 
@@ -392,14 +378,14 @@ AI始终使用相对于当前工作目录的相对路径。
392
378
 
393
379
  ### 对话历史
394
380
 
395
- 对话历史是以程序执行目录为单位创建的,每个程序的执行目录会对应一个独立的 Agent 上下文。这意味着在不同目录下启动的对话是相互独立的。
381
+ 对话历史是以程序执行目录为单位创建的,每个程序的执行目录会对应一个独立的 Agent 上下文。这意味着在不同目录下启动的对话是相互独立的。
382
+
383
+ > **⚠️ 重要提示:** AI上下文是以目录为单位的,一个目录对应一个上下文。**请不要在同一个目录下开启两个命令行对话框**,以免造成上下文冲突和意外行为。
396
384
 
397
- 对话历史会在一定时间内自动清除(通过配置文件中的 `maxHistoryExpireTime` 字段控制,默认为 30 天)。您也可以手动管理对话历史:
385
+ 对话历史会在一定时间内自动清除(通过配置文件中的 `maxMemoryExpireTime` 字段控制,默认为 30 天)。您也可以手动管理对话历史:
398
386
 
399
- - `ai history dir` — 打开历史记录目录,查看已存储的对话上下文
400
- - `ai history clear` — 清除当前目录的对话历史
401
- - `ai history output` — 将对话历史导出到当前目录
402
- - `ai history reset` — 清除所有目录的对话历史
387
+ - `ai memery dir` — 打开记忆目录,查看已存储的对话上下文
388
+ - `ai memery clear` — 清除当前目录的对话历史
403
389
 
404
390
  ## 9. 故障排除
405
391
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "deepfish-ai",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "This is an AI-driven command-line tool built on Node.js, equipped with AI agent and workflow capabilities. It is compatible with a wide range of AI models, can convert natural language into cross-system terminal and file operation commands, and features high extensibility. It supports complex tasks such as translation, content creation, and format conversion, while allowing custom extensions to be automatically generated via AI.",
5
5
  "main": "src/index.js",
6
+ "type": "commonjs",
6
7
  "bin": {
7
8
  "ai": "src/cli/index.js"
8
9
  },
@@ -33,20 +34,35 @@
33
34
  },
34
35
  "homepage": "https://github.com/qq306863030/deepfish-ai#readme",
35
36
  "dependencies": {
37
+ "adm-zip": "^0.5.16",
36
38
  "axios": "^1.13.5",
39
+ "canvas": "^3.2.3",
37
40
  "chalk": "^4.1.0",
38
41
  "chardet": "^2.1.1",
39
42
  "cheerio": "^1.2.0",
40
43
  "commander": "^11.0.0",
41
44
  "dayjs": "^1.11.19",
45
+ "docx": "^9.6.1",
46
+ "docxtemplater": "^3.68.4",
47
+ "echarts": "^6.0.0",
48
+ "eventemitter-super": "^1.0.8",
42
49
  "extract-zip": "^2.0.1",
43
50
  "fs-extra": "^11.3.3",
44
51
  "iconv-lite": "^0.7.2",
45
52
  "inquirer": "^9.0.0",
46
53
  "js-yaml": "^4.1.1",
47
54
  "lodash": "^4.17.23",
55
+ "mammoth": "^1.12.0",
48
56
  "openai": "^6.18.0",
49
- "uuid": "^13.0.0"
57
+ "pdf-lib": "^1.17.1",
58
+ "pdf-parse": "^2.4.5",
59
+ "pdf-to-img": "^6.0.0",
60
+ "pdfkit": "^0.18.0",
61
+ "pizzip": "^3.2.0",
62
+ "pptxgenjs": "^4.0.1",
63
+ "sharp": "^0.34.5",
64
+ "uuid": "^13.0.0",
65
+ "xlsx": "^0.18.5"
50
66
  },
51
67
  "devDependencies": {
52
68
  "@eslint/js": "^10.0.1",
@@ -0,0 +1,105 @@
1
+ const path = require('path')
2
+ const os = require('os')
3
+ const fs = require('fs-extra')
4
+ const dayjs = require('dayjs')
5
+ const Logger = require('../BaseAgentRobot/Logger.js')
6
+ const BaseAgentRobot = require('../BaseAgentRobot/index.js')
7
+ const AttachmentToolScanner = require('../BaseAgentRobot/utils/AttachmentToolScanner.js')
8
+
9
+ class MainAgentRobot extends BaseAgentRobot {
10
+ // toolCollection = null // 工具集合,包含所有工具函数
11
+ constructor(opt) {
12
+ super(opt)
13
+ this.type = 'main'
14
+ }
15
+
16
+ // 初始化文件
17
+ _initFiles(opt) {
18
+ this.workspace = opt.workspace || process.cwd() // 工作空间,目录
19
+ this.basespace = opt.basespace || path.join(os.homedir(), '.deepfish-ai') // 记忆空间,目录
20
+ this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
21
+ this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
22
+ fs.ensureDirSync(this.memorySpace)
23
+ // 查看agentRecord.json文件是否存在,不存在则创建
24
+ if (!fs.pathExistsSync(this.agentRecordFilePath)) {
25
+ fs.writeJsonSync(this.agentRecordFilePath, [], { spaces: 2 })
26
+ }
27
+ // 判断是否已经存在workspace
28
+ let agentRecord = fs.readJsonSync(this.agentRecordFilePath)
29
+ const record = agentRecord.find(
30
+ (record) => record.workspace === this.workspace,
31
+ )
32
+ if (record) {
33
+ this.id = record.agentId
34
+ this.name = record.name
35
+ this.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
36
+ } else {
37
+ agentRecord.push({
38
+ agentId: this.id,
39
+ name: this.name,
40
+ workspace: this.workspace,
41
+ createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
42
+ updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
43
+ })
44
+ }
45
+ fs.writeJsonSync(this.agentRecordFilePath, agentRecord, { spaces: 2 })
46
+ this.agentSpace = path.join(this.memorySpace, this.id) // 机器人空间,目录
47
+ fs.ensureDirSync(this.agentSpace)
48
+ this.agentTreeFilePath = path.join(this.agentSpace, 'agentTree.json')
49
+ if (!fs.pathExistsSync(this.agentTreeFilePath)) {
50
+ fs.writeJsonSync(
51
+ this.agentTreeFilePath,
52
+ { agentId: this.id, children: [] },
53
+ { spaces: 2 },
54
+ )
55
+ } else {
56
+ const agentTree = fs.readJsonSync(this.agentTreeFilePath)
57
+ if (agentTree && agentTree.agentId === this.id) {
58
+ // 恢复子机器人
59
+ // this._parseAgentTree(this, agentTree)
60
+ } else {
61
+ agentTree.push({ agentId: this.id, children: [] })
62
+ fs.writeJsonSync(this.agentTreeFilePath, agentTree, { spaces: 2 })
63
+ }
64
+ }
65
+ this.agentTree = fs.readJsonSync(this.agentTreeFilePath)
66
+ this.memoryFilePath = path.join(this.agentSpace, 'memory.json')
67
+ this.logDirPath = path.join(this.agentSpace, 'logs')
68
+ fs.ensureDirSync(this.logDirPath)
69
+
70
+ // 自动清除过期的记忆和日志
71
+ const currentDate = dayjs()
72
+ agentRecord = agentRecord.filter((record) => {
73
+ if (
74
+ currentDate.diff(dayjs(record.updateTime), 'day') >
75
+ opt.maxMemoryExpireTime
76
+ ) {
77
+ // 删除机器人空间
78
+ fs.removeSync(path.join(this.memorySpace, record.agentId))
79
+ return false
80
+ }
81
+ return true
82
+ })
83
+ fs.writeJsonSync(this.agentRecordFilePath, agentRecord, { spaces: 2 })
84
+ this.logger = new Logger(this) // 初始化日志系统
85
+ this.logger.clearAllLogs()
86
+ this.toolCollection = AttachmentToolScanner.getToolCollection(
87
+ this.workspace,
88
+ ) // 加载工具集合
89
+ this.clawSkillCollection = AttachmentToolScanner.getClawSkillCollection(
90
+ this.basespace,
91
+ ) // 加载Claw技能集合
92
+ }
93
+
94
+ _getDefaultSystemPrompt(opt) {
95
+ const systemPrompt = super._getDefaultSystemPrompt(opt)
96
+ return `
97
+ ${systemPrompt}
98
+ ### 工具调用
99
+ 对于复杂的任务,先从可以使用的Skills中查找并使用合适的Skill,如果没有合适的Skill,再使用内置工具函数,使用时请严格按照工具函数的调用方式进行调用。
100
+ ${AttachmentToolScanner.getAttachToolPrompt(this.toolCollection, this.clawSkillCollection)}
101
+ `
102
+ }
103
+ }
104
+
105
+ module.exports = MainAgentRobot
@@ -0,0 +1,57 @@
1
+ const path = require('path')
2
+ const os = require('os')
3
+ const fs = require('fs-extra')
4
+ const BaseAgentRobot = require('../BaseAgentRobot/index.js')
5
+ const Logger = require('../BaseAgentRobot/Logger.js')
6
+ const AttachmentToolScanner = require('../BaseAgentRobot/utils/AttachmentToolScanner.js')
7
+
8
+ class SubAgentRobot extends BaseAgentRobot {
9
+ // opt: { root, parent, ...MainAgentOpt }
10
+ constructor(opt) {
11
+ super(opt)
12
+ this.type = 'sub'
13
+ this.parent = opt.parent
14
+ }
15
+
16
+ _initFiles(opt) {
17
+ this.root = opt.root
18
+ this.parent = opt.parent
19
+ this.attachTools = opt.attachTools || []
20
+ this.workspace = opt.workspace || process.cwd() // 工作空间,目录
21
+ this.basespace = opt.basespace || path.join(os.homedir(), '.deepfish-ai') // 记忆空间,目录
22
+ this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
23
+ this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
24
+ this.agentSpace = path.join(this.memorySpace, this.root.id) // 机器人空间,目录
25
+ this.agentTreeFilePath = path.join(this.agentSpace, 'agentTree.json')
26
+ this.memoryFilePath = path.join(this.agentSpace, `memory-${this.id}.json`)
27
+ this.logDirPath = path.join(this.agentSpace, 'logs')
28
+ this.logger = new Logger(this) // 初始化日志系统
29
+ const parentAgentTree = this.parent.agentTree
30
+ const rootAgentTree = this.root.agentTree
31
+ if (parentAgentTree && parentAgentTree.children) {
32
+ const currentNode = parentAgentTree.children.find((child) => child.agentId === this.id)
33
+ if (!currentNode) {
34
+ parentAgentTree.children.push({ agentId: this.id, children: [], type: 'sub' })
35
+ fs.writeJsonSync(this.agentTreeFilePath, rootAgentTree, { spaces: 2 })
36
+ }
37
+ }
38
+ this.toolCollection = AttachmentToolScanner.getToolCollection(
39
+ this.workspace,
40
+ ) // 加载工具集合
41
+ this.clawSkillCollection = AttachmentToolScanner.getClawSkillCollection(
42
+ this.basespace,
43
+ ) // 加载Claw技能集合
44
+ }
45
+
46
+ _getDefaultSystemPrompt(opt) {
47
+ const systemPrompt = super._getDefaultSystemPrompt(opt)
48
+ return `
49
+ ${systemPrompt}
50
+ ### 工具调用
51
+ 对于复杂的任务,先从可以使用的Skills中查找并使用合适的Skill,如果没有合适的Skill,再使用内置工具函数,使用时请严格按照工具函数的调用方式进行调用。
52
+ ${AttachmentToolScanner.getAttachToolPrompt(this.toolCollection, this.clawSkillCollection)}
53
+ `
54
+ }
55
+ }
56
+
57
+ module.exports = SubAgentRobot
@@ -0,0 +1,45 @@
1
+ const path = require('path')
2
+ const os = require('os')
3
+ const fs = require('fs-extra')
4
+ const BaseAgentRobot = require('../BaseAgentRobot/index.js')
5
+ const Logger = require('../BaseAgentRobot/Logger.js')
6
+
7
+ class SubSkillAgentRobot extends BaseAgentRobot {
8
+ // opt: { root, parent, ...MainAgentOpt }
9
+ constructor(opt) {
10
+ super(opt)
11
+ this.type = 'sub-skill'
12
+ }
13
+
14
+ _initFiles(opt) {
15
+ this.root = opt.root
16
+ this.parent = opt.parent
17
+ this.attachTools = opt.attachTools || []
18
+ this.workspace = opt.workspace || process.cwd() // 工作空间,目录
19
+ this.basespace = opt.basespace || path.join(os.homedir(), '.deepfish-ai') // 记忆空间,目录
20
+ this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
21
+ this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
22
+ this.agentSpace = path.join(this.memorySpace, this.root.id) // 机器人空间,目录
23
+ this.agentTreeFilePath = path.join(this.agentSpace, 'agentTree.json')
24
+ this.memoryFilePath = path.join(this.agentSpace, `memory-${this.id}.json`)
25
+ this.logDirPath = path.join(this.agentSpace, 'logs')
26
+ this.logger = new Logger(this) // 初始化日志系统
27
+ const parentAgentTree = this.parent.agentTree
28
+ const rootAgentTree = this.root.agentTree
29
+ if (parentAgentTree && parentAgentTree.children) {
30
+ const currentNode = parentAgentTree.children.find(
31
+ (child) => child.agentId === this.id,
32
+ )
33
+ if (!currentNode) {
34
+ parentAgentTree.children.push({
35
+ agentId: this.id,
36
+ children: [],
37
+ type: 'sub-skill',
38
+ })
39
+ fs.writeJsonSync(this.agentTreeFilePath, rootAgentTree, { spaces: 2 })
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ module.exports = SubSkillAgentRobot
@@ -0,0 +1,53 @@
1
+ const { AttachmentToolScanner, AttachmentToolType } = require('../BaseAgentRobot/utils/AttachmentToolScanner.js')
2
+ const MainAgentRobot = require('./MainAgentRobot.js')
3
+ const SubAgentRobot = require('./SubAgentRobot.js')
4
+ const SubSkillAgentRobot = require('./SubSkillAgentRobot.js')
5
+
6
+ class AgentRobotFactory {
7
+ createMainAgent(opt) {
8
+ return new MainAgentRobot(opt)
9
+ }
10
+ // 创建子技能机器人
11
+ createSubSkillAgent(parent, id, attachTools = []) {
12
+ const baseSkill = []
13
+ const clawSkill = []
14
+ for (const tool of attachTools) {
15
+ if (tool.type === AttachmentToolType.BASE_SKILL) {
16
+ baseSkill.push(tool)
17
+ } else if (tool.type === AttachmentToolType.CLAW_SKILL) {
18
+ clawSkill.push(tool)
19
+ }
20
+ }
21
+ const subAgent = new SubSkillAgentRobot({
22
+ ...parent.opt,
23
+ id,
24
+ name: `SubSkillAgent-${attachTools[0].name}`,
25
+ parent: parent,
26
+ root: parent.root || parent,
27
+ attachTools: baseSkill,
28
+ })
29
+ if (clawSkill.length > 0) {
30
+ parent.systemPrompt =
31
+ parent.systemPrompt +
32
+ '\n' +
33
+ AttachmentToolScanner.getClawSkillPrompt(clawSkill)
34
+ }
35
+ parent.children.push(subAgent)
36
+ return subAgent
37
+ }
38
+
39
+ // 创建子机器人
40
+ createSubAgent(parent, id) {
41
+ const subAgent = new SubAgentRobot({
42
+ ...parent.opt,
43
+ id,
44
+ name: `SubAgent-${id}`,
45
+ parent: parent,
46
+ root: parent.root || parent,
47
+ })
48
+ parent.children.push(subAgent)
49
+ return subAgent
50
+ }
51
+ }
52
+
53
+ module.exports = AgentRobotFactory