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.
- package/README.md +31 -45
- package/README_CN.md +32 -46
- package/package.json +18 -2
- package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +105 -0
- package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +57 -0
- package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +45 -0
- package/src/AgentRobot/AgentRobotFactory/index.js +53 -0
- package/src/AgentRobot/BaseAgentRobot/Brain.js +203 -0
- package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +17 -0
- package/src/AgentRobot/BaseAgentRobot/Hand.js +119 -0
- package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
- package/src/AgentRobot/BaseAgentRobot/Logger.js +108 -0
- package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +49 -0
- package/src/AgentRobot/BaseAgentRobot/index.js +335 -0
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +708 -0
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +737 -0
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +734 -0
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +539 -0
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +586 -0
- package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +12 -0
- package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +125 -0
- package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +675 -0
- package/src/{core/extension/GenerateExtension.js → AgentRobot/BaseAgentRobot/tools/GenerateTools.js} +176 -82
- package/src/{core/extension/InquirerExtension.js → AgentRobot/BaseAgentRobot/tools/InquirerTools.js} +11 -9
- package/src/{core/extension/SystemExtension.js → AgentRobot/BaseAgentRobot/tools/SystemTools.js} +42 -108
- package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +210 -0
- package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +99 -0
- package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +241 -0
- package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +207 -0
- package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +236 -0
- package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +74 -0
- package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +78 -0
- package/src/{core → AgentRobot/BaseAgentRobot}/utils/node-root.js +32 -34
- package/src/{core → AgentRobot/BaseAgentRobot}/utils/normal.js +8 -4
- package/src/cli/ConfigManager.js +56 -38
- package/src/cli/DefaultConfig.js +50 -28
- package/src/{core → cli}/GlobalVariable.js +2 -4
- package/src/cli/MemoryManager.js +53 -0
- package/src/cli/SkillConfigManager.js +72 -60
- package/src/cli/SkillParser.js +4 -7
- package/src/cli/ai-config.js +17 -14
- package/src/cli/ai-memory.js +22 -0
- package/src/cli/ai-skill.js +33 -33
- package/src/cli/index.js +45 -39
- package/src/index.js +53 -6
- package/src/cli/ExtConfigManager.js +0 -90
- package/src/cli/HistoryManager.js +0 -293
- package/src/cli/ai-ext.js +0 -36
- package/src/cli/ai-history.js +0 -36
- package/src/core/AICLI.js +0 -98
- package/src/core/ai-services/AiWorker/AIMessageManager.js +0 -173
- package/src/core/ai-services/AiWorker/AiAgent.js +0 -150
- package/src/core/ai-services/AiWorker/AiPrompt.js +0 -135
- package/src/core/ai-services/AiWorker/AiTools.js +0 -368
- package/src/core/ai-services/AiWorker/index.js +0 -180
- package/src/core/ai-services/index.js +0 -39
- package/src/core/extension/BaseExtension.js +0 -9
- package/src/core/extension/ExtensionManager.js +0 -204
- package/src/core/extension/FileExtension.js +0 -439
- package/src/core/extension/TaskExtension.js +0 -169
- package/src/core/extension/TestExtension.js +0 -67
- 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
|
-
#
|
|
166
|
-
ai
|
|
167
|
-
ai
|
|
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
|
-
|
|
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:
|
|
186
|
-
maxTokens:
|
|
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
|
-
|
|
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: "
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
-
|
|
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
|
|
404
|
-
- `ai
|
|
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
|
|
165
|
-
ai
|
|
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
|
-
|
|
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:
|
|
184
|
-
maxTokens:
|
|
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
|
-
|
|
184
|
+
maxMemoryExpireTime: 30, // 整个会话的最大过期时间,单位天,-1表示无限制,0表示不记录
|
|
193
185
|
maxLogExpireTime: 3, // 日志过期时间,单位天,-1表示无限制,0表示不记录
|
|
194
186
|
maxBlockFileSize: 20, // 最大分块文件大小,单位KB;超过该大小的文件需要分块处理
|
|
195
|
-
extensions: [], // 扩展文件路径列表
|
|
196
187
|
skills: [], // 技能配置列表
|
|
197
|
-
encoding: "
|
|
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
|
-
|
|
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
|
-
**方法
|
|
346
|
+
**方法2:自动扫描**
|
|
361
347
|
|
|
362
348
|
程序启动时自动扫描扩展模块的规则:
|
|
363
349
|
1. 扫描位置:
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
350
|
+
- 程序安装目录(deepfish-ai 程序所在目录)
|
|
351
|
+
- 当前工作目录的 node_modules 目录
|
|
352
|
+
- 当前工作目录
|
|
367
353
|
2. 扫描文件:
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
对话历史会在一定时间内自动清除(通过配置文件中的 `
|
|
385
|
+
对话历史会在一定时间内自动清除(通过配置文件中的 `maxMemoryExpireTime` 字段控制,默认为 30 天)。您也可以手动管理对话历史:
|
|
398
386
|
|
|
399
|
-
- `ai
|
|
400
|
-
- `ai
|
|
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.
|
|
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
|
-
"
|
|
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
|