deepfish-ai 1.0.28 → 2.0.2
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 +126 -368
- package/dist/index.js +23320 -0
- package/dist/serve/client/assets/index-DUHYC91l.js +1 -0
- package/dist/serve/client/assets/index-zcrdNLZs.css +1 -0
- package/dist/serve/client/index.html +14 -0
- package/dist/serve/pm2-server.js +21015 -0
- package/dist/serve/server/entry-server.mjs +224 -0
- package/package.json +50 -70
- package/LICENSE +0 -21
- package/README_CN.md +0 -460
- package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +0 -88
- package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +0 -45
- package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +0 -45
- package/src/AgentRobot/AgentRobotFactory/index.js +0 -48
- package/src/AgentRobot/BaseAgentRobot/Brain.js +0 -210
- package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +0 -17
- package/src/AgentRobot/BaseAgentRobot/Hand.js +0 -119
- package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
- package/src/AgentRobot/BaseAgentRobot/Logger.js +0 -114
- package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +0 -49
- package/src/AgentRobot/BaseAgentRobot/index.js +0 -266
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/AliBailian.js +0 -997
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/doc-transform.js +0 -204
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +0 -1286
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +0 -765
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +0 -736
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +0 -567
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/video.js +0 -36
- package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +0 -611
- package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +0 -13
- package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +0 -158
- package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +0 -768
- package/src/AgentRobot/BaseAgentRobot/tools/GenerateTools.js +0 -441
- package/src/AgentRobot/BaseAgentRobot/tools/InquirerTools.js +0 -244
- package/src/AgentRobot/BaseAgentRobot/tools/SystemTools.js +0 -263
- package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +0 -211
- package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +0 -100
- package/src/AgentRobot/BaseAgentRobot/tools/UserTool.js +0 -87
- package/src/AgentRobot/BaseAgentRobot/tools/WebTools.js +0 -257
- package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +0 -297
- package/src/AgentRobot/BaseAgentRobot/utils/AIToolManager.js +0 -131
- package/src/AgentRobot/BaseAgentRobot/utils/AgentTree.js +0 -66
- package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +0 -235
- package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +0 -236
- package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +0 -74
- package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +0 -78
- package/src/AgentRobot/BaseAgentRobot/utils/analyzeReturn.test.js +0 -104
- package/src/AgentRobot/BaseAgentRobot/utils/copilot.js +0 -117
- package/src/AgentRobot/BaseAgentRobot/utils/node-root.js +0 -138
- package/src/AgentRobot/BaseAgentRobot/utils/normal.js +0 -399
- package/src/cli/ConfigManager.js +0 -283
- package/src/cli/DefaultConfig.js +0 -98
- package/src/cli/GlobalVariable.js +0 -8
- package/src/cli/MemoryManager.js +0 -53
- package/src/cli/SkillConfigManager.js +0 -343
- package/src/cli/SkillParser.js +0 -58
- package/src/cli/ai-auth.js +0 -231
- package/src/cli/ai-config.js +0 -225
- package/src/cli/ai-memory.js +0 -22
- package/src/cli/ai-skill.js +0 -65
- package/src/cli/index.js +0 -77
- package/src/index.js +0 -54
package/README_CN.md
DELETED
|
@@ -1,460 +0,0 @@
|
|
|
1
|
-
<div align="center" style="display:flex;align-items: center;justify-content: center;">
|
|
2
|
-
<img src="./images/title-img.png" alt="DeepFish" width="300" />
|
|
3
|
-
</div>
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
<div align="center" style="line-height: 1">
|
|
8
|
-
<img alt="QQ" src="https://img.shields.io/badge/QQ-306863030-green.svg" />
|
|
9
|
-
<img
|
|
10
|
-
alt="WeChat"
|
|
11
|
-
src="https://img.shields.io/badge/WeChat-MrRoman_123-green.svg"
|
|
12
|
-
/>
|
|
13
|
-
<a href="https://github.com/qq306863030/deepfish-ai">
|
|
14
|
-
<img
|
|
15
|
-
alt="GitHub"
|
|
16
|
-
src="https://img.shields.io/badge/GitHub-DeepFish AI-blue.svg"
|
|
17
|
-
/></a>
|
|
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
|
-
/></a>
|
|
21
|
-
<img
|
|
22
|
-
alt="Code License"
|
|
23
|
-
src="https://img.shields.io/badge/Code_License-MIT-blue"
|
|
24
|
-
/>
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<img src="./images/banner.png" alt="banner" style="width:100%;text-align:center;" />
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- [English](README.md) | [中文](README_CN.md)
|
|
33
|
-
|
|
34
|
-
## 目录
|
|
35
|
-
|
|
36
|
-
- [目录](#目录)
|
|
37
|
-
- [1. 介绍](#1-介绍)
|
|
38
|
-
- [2. 安装](#2-安装)
|
|
39
|
-
- [前置要求](#前置要求)
|
|
40
|
-
- [通过npm安装](#通过npm安装)
|
|
41
|
-
- [从源码安装](#从源码安装)
|
|
42
|
-
- [3. 快速使用](#3-快速使用)
|
|
43
|
-
- [4. 配置](#4-配置)
|
|
44
|
-
- [初始设置](#初始设置)
|
|
45
|
-
- [配置命令](#配置命令)
|
|
46
|
-
- [配置文件结构](#配置文件结构)
|
|
47
|
-
- [目录结构说明](#目录结构说明)
|
|
48
|
-
- [5. 使用方法](#5-使用方法)
|
|
49
|
-
- [交互模式](#交互模式)
|
|
50
|
-
- [直接命令模式](#直接命令模式)
|
|
51
|
-
- [使用示例](#使用示例)
|
|
52
|
-
- [6. 扩展开发](#6-扩展开发)
|
|
53
|
-
- [创建扩展](#创建扩展)
|
|
54
|
-
- [注册扩展](#注册扩展)
|
|
55
|
-
- [7. 建议](#7-建议)
|
|
56
|
-
- [AI服务选择](#ai服务选择)
|
|
57
|
-
- [8. 使用说明](#8-使用说明)
|
|
58
|
-
- [使用相对路径](#使用相对路径)
|
|
59
|
-
- [对话历史](#对话历史)
|
|
60
|
-
- [9. 故障排除](#9-故障排除)
|
|
61
|
-
- [配置问题](#配置问题)
|
|
62
|
-
- [AI服务连接](#ai服务连接)
|
|
63
|
-
- [扩展未加载](#扩展未加载)
|
|
64
|
-
- [10. 贡献](#10-贡献)
|
|
65
|
-
- [11. 许可证](#11-许可证)
|
|
66
|
-
- [12. 支持](#12-支持)
|
|
67
|
-
|
|
68
|
-
## 1. 介绍
|
|
69
|
-
|
|
70
|
-
一款高效便捷的AI驱动命令行工具,致力于打破自然语言与操作系统指令、文件操作指令之间的壁垒,让非专业开发者也能通过简单的自然语言描述,快速生成可直接执行的操作指令,大幅提升终端操作效率。
|
|
71
|
-
核心特性:
|
|
72
|
-
|
|
73
|
-
- 多模型兼容:无缝支持DeepSeek、Ollama,以及所有遵循OpenAI API规范的AI模型,可根据需求灵活切换,适配不同场景下的指令生成需求。
|
|
74
|
-
|
|
75
|
-
- OpenClaw Skill 兼容:支持适配 OpenClaw 的 Skill 生态,可通过现有 Skill 命令进行安装、启用与管理,快速扩展工作流能力。
|
|
76
|
-
|
|
77
|
-
- 自然语言转指令:精准解析自然语言需求,自动转换为对应的操作系统命令(如Linux、Windows、macOS终端指令)和文件操作指令(如创建、删除、修改文件/目录),无需手动编写复杂命令。
|
|
78
|
-
|
|
79
|
-
- 高度可扩展:支持通过扩展机制拓展功能边界,除基础的终端、文件操作外,可轻松实现翻译、小说创作、文件格式转换、数据处理等复杂任务,满足多样化使用需求。
|
|
80
|
-
|
|
81
|
-
- AI自动生成扩展:无需手动开发复杂扩展工具,可通过AI直接生成自定义扩展,降低扩展开发门槛,让功能拓展更高效、更灵活。[扩展示例](https://github.com/qq306863030/deepfish-extensions)
|
|
82
|
-
|
|
83
|
-
适用于开发者、运维人员、日常终端使用者等各类人群,无论是快速执行终端操作、批量处理文件,还是通过扩展实现个性化需求,都能通过该工具简化操作流程,提升工作效率,让AI赋能每一次终端操作。
|
|
84
|
-
|
|
85
|
-
## 2. 安装
|
|
86
|
-
|
|
87
|
-
### 前置要求
|
|
88
|
-
|
|
89
|
-
- Node.js(v22.14.0或更高版本)
|
|
90
|
-
- npm或yarn
|
|
91
|
-
|
|
92
|
-
### 通过npm安装
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
npm install -g deepfish-ai
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 从源码安装
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
git clone https://github.com/qq306863030/deepfish-ai.git
|
|
102
|
-
cd deepfish
|
|
103
|
-
npm install
|
|
104
|
-
npm link
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## 3. 快速使用
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
ai config add # 输入名称, 然后选择deepseek,并输入你的deepseek api key
|
|
111
|
-
ai config use 你输入的名称
|
|
112
|
-
ai ”帮我在当前目录写一篇关于未来科技的文章,用markdown格式输出“
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## 4. 配置
|
|
116
|
-
|
|
117
|
-
### 初始设置
|
|
118
|
-
|
|
119
|
-
运行配置向导来设置您的AI服务:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
ai config add
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
这将提示你配置以下内容:
|
|
126
|
-
|
|
127
|
-
- **AI服务类型**:选择DeepSeek、MiniMax、Qwen、Ollama或OpenAI
|
|
128
|
-
- **API基础URL**:为每个服务提供默认URL
|
|
129
|
-
- **模型名称**:选择要使用的AI模型
|
|
130
|
-
- **API密钥**:DeepSeek和OpenAI需要
|
|
131
|
-
- **Temperature**:控制响应随机性(0-2)
|
|
132
|
-
- **Max Tokens**:最大响应长度
|
|
133
|
-
- **Streaming Output**:启用/禁用流式响应
|
|
134
|
-
|
|
135
|
-
### 配置命令
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# 配置命令
|
|
139
|
-
ai config add # 添加新的AI配置
|
|
140
|
-
ai config ls # 列出所有AI配置
|
|
141
|
-
ai config use <name> # 设置指定的AI配置为当前配置
|
|
142
|
-
ai config del <name> # 删除指定的AI配置
|
|
143
|
-
ai config view [name] # 查看指定AI配置的详细信息
|
|
144
|
-
ai config edit # 编辑配置文件手动编辑配置文件
|
|
145
|
-
ai config dir # 打开配置文件所在目录
|
|
146
|
-
ai config reset # 重置配置
|
|
147
|
-
|
|
148
|
-
# Skill 命令
|
|
149
|
-
ai skill ls # 列出所有已注册的 skill
|
|
150
|
-
ai skill add <name> # 从当前目录添加本地 skill 目录或 zip 文件
|
|
151
|
-
ai skill del <name|index> # 通过名称或索引删除 skill, exp: ai skill del 1
|
|
152
|
-
ai skill install <url> # 从 ClawHub 安装 skill,exp: ai skill install https://clawhub.ai/TheSethRose/agent-browser
|
|
153
|
-
ai skill enable <name|index> # 通过名称或索引启用 skill, exp: ai skill enable 1
|
|
154
|
-
ai skill disable <name|index> # 通过名称或索引禁用 skill, exp: ai skill disable 1
|
|
155
|
-
ai skill dir # 打开 skill 目录
|
|
156
|
-
|
|
157
|
-
# 记忆命令
|
|
158
|
-
ai memory clear # 清除当前目录的对话历史
|
|
159
|
-
ai memory dir # 打开记忆目录
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### 配置文件结构
|
|
163
|
-
|
|
164
|
-
配置文件 (`~/.deepfish-ai/config.js`) 具有以下结构:
|
|
165
|
-
|
|
166
|
-
```javascript
|
|
167
|
-
export default {
|
|
168
|
-
ai: [
|
|
169
|
-
{
|
|
170
|
-
name: "default", // AI配置名称
|
|
171
|
-
type: "deepseek", // AI服务类型:"ollama"、"deepseek"或"openai"
|
|
172
|
-
baseUrl: "https://api.deepseek.com", // API基础URL
|
|
173
|
-
model: "deepseek-reasoner", // AI模型名称
|
|
174
|
-
apiKey: "", // API密钥(DeepSeek和OpenAI需要)
|
|
175
|
-
temperature: 0.7, // 响应随机性(0-2)
|
|
176
|
-
maxTokens: 8, // 最大响应长度(KB)
|
|
177
|
-
maxContextLength: 64, // 最大上下文长度(KB)
|
|
178
|
-
stream: true, // 启用/禁用流式输出
|
|
179
|
-
}
|
|
180
|
-
],
|
|
181
|
-
currentAi: "default", // 当前活动的AI配置名称
|
|
182
|
-
maxIterations: -1, // ai完成工作流的最大迭代次数,-1表示无限制
|
|
183
|
-
maxMemoryExpireTime: 30, // 整个会话的最大过期时间,单位天,-1表示无限制,0表示不记录
|
|
184
|
-
maxLogExpireTime: 3, // 日志过期时间,单位天,-1表示无限制,0表示不记录
|
|
185
|
-
maxBlockFileSize: 20, // 最大分块文件大小,单位KB;超过该大小的文件需要分块处理
|
|
186
|
-
isThinkPrint: true, // 是否打印思考过程
|
|
187
|
-
encoding: "auto", // 命令行编码格式,可设置为utf-8、gbk等,也可以设置成auto或空值自动判断
|
|
188
|
-
EMBEDDING_API: "", // 向量化接口地址
|
|
189
|
-
EMBEDDING_API_KEY: "", // 向量化接口密钥
|
|
190
|
-
};
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### 目录结构说明
|
|
194
|
-
|
|
195
|
-
DeepFish 默认工作目录为 `.deepfish-ai`,可通过以下命令直接打开:
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
ai config dir
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
默认路径:
|
|
202
|
-
|
|
203
|
-
- Windows: `C:/Users/<用户名>/.deepfish-ai`
|
|
204
|
-
- macOS/Linux: `~/.deepfish-ai`
|
|
205
|
-
|
|
206
|
-
参考 DevPlan 的目录结构示例如下:
|
|
207
|
-
|
|
208
|
-
```text
|
|
209
|
-
.deepfish-ai/
|
|
210
|
-
├─ config.js # 全局配置
|
|
211
|
-
├─ user-info/
|
|
212
|
-
│ └─ user.md # 用户信息
|
|
213
|
-
├─ clawSkills/
|
|
214
|
-
│ ├─ clawSkills.json # OpenClaw 技能索引
|
|
215
|
-
│ └─ <skill>/
|
|
216
|
-
│ └─ SKILL.md # 单个技能说明
|
|
217
|
-
└─ memery/
|
|
218
|
-
├─ agentRecord.json # 工作目录与主 agent 映射
|
|
219
|
-
└─ <主agent编号>/
|
|
220
|
-
├─ memery.json # 主 agent 记忆
|
|
221
|
-
├─ memery-<子agent编号>.json # 子 agent 记忆
|
|
222
|
-
├─ agentTree.json # agent 组织结构
|
|
223
|
-
├─ bakup/
|
|
224
|
-
│ └─ <时间戳>/
|
|
225
|
-
│ ├─ record.json # 备份记录
|
|
226
|
-
│ └─ <uuid>.* # 备份文件
|
|
227
|
-
└─ logs/
|
|
228
|
-
└─ log-{YYYY-MM-DD HH}.txt # 按小时滚动日志
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## 5. 使用方法
|
|
232
|
-
|
|
233
|
-
### 交互模式
|
|
234
|
-
|
|
235
|
-
启动交互式会话(多轮对话):
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
ai
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
或显式指定:
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
ai -i 或 ai -interactive
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### 直接命令模式
|
|
248
|
-
|
|
249
|
-
执行单个命令:
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
ai "创建一个名为hello.txt的文件,内容为'Hello World'"
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### 使用示例
|
|
256
|
-
|
|
257
|
-
**文件操作:**
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
ai "创建10个文本文档,分别输入100个随机文本"
|
|
261
|
-
ai "清空当前目录"
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
**代码生成:**
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
ai "创建一个带有/hello端点的简单Express服务器"
|
|
268
|
-
ai "创建一个基于浏览器的飞机大战游戏"
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**系统命令:**
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
ai "列出当前目录中所有文件及其大小"
|
|
275
|
-
ai "检查当前目录的磁盘使用情况"
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
**扩展工具生成:**
|
|
279
|
-
|
|
280
|
-
```bash
|
|
281
|
-
ai "创建一个用于查询天气的扩展工具weather.js"
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**Skill 管理:**
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
ai skill install https://clawhub.ai/TheSethRose/agent-browser
|
|
288
|
-
ai skill install https://clawhub.ai/steipete/weather
|
|
289
|
-
ai skill ls
|
|
290
|
-
ai skill enable 1
|
|
291
|
-
ai skill disable 0
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**OpenClaw Skill 生成:**
|
|
295
|
-
|
|
296
|
-
```bash
|
|
297
|
-
ai "创建一个查询天气的skill"
|
|
298
|
-
ai skill add weather-query
|
|
299
|
-
ai skill enable weather-query
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
**媒体处理:**
|
|
303
|
-
|
|
304
|
-
```bash
|
|
305
|
-
ai "我的系统上安装了ffmpeg5,帮我将目录中的所有MP4文件转换为AVI格式"
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**文件组织:**
|
|
309
|
-
|
|
310
|
-
```bash
|
|
311
|
-
ai "将model目录下的所有文件按月份分类到model2目录中,日期格式为YYYY-MM"
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
**任务列表执行:**
|
|
315
|
-
|
|
316
|
-
```bash
|
|
317
|
-
ai "创建一个任务列表,1.xxxx;2.xxxx;..."
|
|
318
|
-
ai "执行任务列表" # 开始执行
|
|
319
|
-
|
|
320
|
-
ai "我要实现一个用于长篇小说创作的扩展工具,支持大篇幅写作,保持上下文逻辑连贯,避免AI上下文爆炸问题。这个扩展工具实现起来可能有点复杂,你需要先仔细阅读扩展工具生成规则,然后创建一个任务列表"
|
|
321
|
-
ai "执行任务列表" # 开始执行
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
## 6. 扩展开发
|
|
325
|
-
|
|
326
|
-
扩展允许您添加AI可以在其工作流中使用的自定义函数, 对于复杂的流程也可以自行开发或尝试使用本程序生成扩展,然后将扩展注册到程序中,在使用命令行来完成任务。
|
|
327
|
-
|
|
328
|
-
### 创建扩展
|
|
329
|
-
|
|
330
|
-
1. 扩展应导出包含 `descriptions`(工具描述数组)和 `functions`(函数对象)的对象。
|
|
331
|
-
2. 提示:可以通过AI生成扩展,例如"ai "创建一个用于查询天气的扩展工具weather.js"
|
|
332
|
-
3. 可查看[示例扩展](https://github.com/qq306863030/deepfish-extensions)。
|
|
333
|
-
|
|
334
|
-
```javascript
|
|
335
|
-
// 示例扩展:天气扩展
|
|
336
|
-
const axios = require('axios');
|
|
337
|
-
|
|
338
|
-
const descriptions = [
|
|
339
|
-
{
|
|
340
|
-
type: 'function',
|
|
341
|
-
function: {
|
|
342
|
-
name: 'getWeather',
|
|
343
|
-
description: '获取城市的当前天气信息',
|
|
344
|
-
parameters: {
|
|
345
|
-
type: 'object',
|
|
346
|
-
properties: {
|
|
347
|
-
city: { type: 'string' }
|
|
348
|
-
},
|
|
349
|
-
required: ['city']
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
];
|
|
354
|
-
|
|
355
|
-
const functions = {
|
|
356
|
-
async getWeather(city) {
|
|
357
|
-
// 实现天气API调用
|
|
358
|
-
const response = await axios.get(`https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q=${city}`);
|
|
359
|
-
return `${city}的天气:${response.data.current.temp_c}°C,${response.data.current.condition.text}`;
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
module.exports = {
|
|
364
|
-
descriptions,
|
|
365
|
-
functions
|
|
366
|
-
};
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
### 注册扩展
|
|
370
|
-
|
|
371
|
-
**方法1:手动配置**
|
|
372
|
-
|
|
373
|
-
1. ai config edit
|
|
374
|
-
2. 将其添加到您的配置中:
|
|
375
|
-
|
|
376
|
-
```javascript
|
|
377
|
-
export default {
|
|
378
|
-
// ... 其他配置
|
|
379
|
-
extensions: [
|
|
380
|
-
'/path/to/weather-extension.js'
|
|
381
|
-
],
|
|
382
|
-
};
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**方法2:自动扫描**
|
|
386
|
-
|
|
387
|
-
程序启动时自动扫描扩展模块的规则:
|
|
388
|
-
1. 扫描位置:
|
|
389
|
-
- 程序安装目录(deepfish-ai 程序所在目录)
|
|
390
|
-
- 当前工作目录的 node_modules 目录
|
|
391
|
-
- 当前工作目录
|
|
392
|
-
2. 扫描文件:
|
|
393
|
-
- 在以上目录中扫描 `@deepfish-ai/*` 作用域包
|
|
394
|
-
- 在以上目录中扫描 `deepfish-` 开头的包(排除 `deepfish-ai` 本体)
|
|
395
|
-
- 在当前工作目录额外扫描顶层 `.js` / `.mjs` 文件, 文件内容包含 `module.exports`、`descriptions`、`functions` 字符串时视为可自动加载扩展
|
|
396
|
-
|
|
397
|
-
## 7. 建议
|
|
398
|
-
|
|
399
|
-
### AI服务选择
|
|
400
|
-
|
|
401
|
-
**建议:使用在线AI服务(DeepSeek/OpenAI)以获得最佳效果**
|
|
402
|
-
|
|
403
|
-
虽然本地AI服务(如Ollama)提供隐私保护和离线能力,但它们可能存在以下限制:
|
|
404
|
-
|
|
405
|
-
- **响应准确性**:本地模型可能不如在线模型严谨和精确
|
|
406
|
-
- **代码质量**:生成的代码可能需要更多的人工审查和修正
|
|
407
|
-
- **复杂任务处理**:在多步骤或复杂操作上可能遇到困难
|
|
408
|
-
- **语言理解**:在线服务提供更好的语言模型
|
|
409
|
-
|
|
410
|
-
对于生产环境或复杂任务,我们建议使用DeepSeek或OpenAI服务,或Ollama中的云端服务,以获得更可靠和准确的结果。
|
|
411
|
-
|
|
412
|
-
## 8. 使用说明
|
|
413
|
-
|
|
414
|
-
### 使用相对路径
|
|
415
|
-
|
|
416
|
-
AI始终使用相对于当前工作目录的相对路径。
|
|
417
|
-
|
|
418
|
-
### 对话历史
|
|
419
|
-
|
|
420
|
-
对话历史是以程序执行目录为单位创建的,每个程序的执行目录会对应一个独立的 Agent 上下文。这意味着在不同目录下启动的对话是相互独立的。
|
|
421
|
-
|
|
422
|
-
> **⚠️ 重要提示:** AI上下文是以目录为单位的,一个目录对应一个上下文。**请不要在同一个目录下开启两个命令行对话框**,以免造成上下文冲突和意外行为。
|
|
423
|
-
|
|
424
|
-
对话历史会在一定时间内自动清除(通过配置文件中的 `maxMemoryExpireTime` 字段控制,默认为 30 天)。您也可以手动管理对话历史:
|
|
425
|
-
|
|
426
|
-
- `ai memory dir` — 打开记忆目录,查看已存储的对话上下文
|
|
427
|
-
- `ai memory clear` — 清除当前目录的对话历史
|
|
428
|
-
|
|
429
|
-
## 9. 故障排除
|
|
430
|
-
|
|
431
|
-
### 配置问题
|
|
432
|
-
|
|
433
|
-
如果遇到配置错误,请尝试重置:
|
|
434
|
-
|
|
435
|
-
```bash
|
|
436
|
-
ai config reset
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### AI服务连接
|
|
440
|
-
|
|
441
|
-
- **Ollama**:确保Ollama在本地11434端口上运行
|
|
442
|
-
- **DeepSeek/MiniMax/Qwen/OpenAI**:验证您的API密钥是否正确,并且您有足够的额度
|
|
443
|
-
|
|
444
|
-
### 扩展未加载
|
|
445
|
-
|
|
446
|
-
- 检查配置中的文件路径
|
|
447
|
-
- 确保文件导出正确的对象
|
|
448
|
-
- 验证文件没有语法错误
|
|
449
|
-
|
|
450
|
-
## 10. 贡献
|
|
451
|
-
|
|
452
|
-
欢迎贡献!请随时提交Pull Request。
|
|
453
|
-
|
|
454
|
-
## 11. 许可证
|
|
455
|
-
|
|
456
|
-
本项目采用MIT许可证 - 详见[LICENSE](LICENSE)文件。
|
|
457
|
-
|
|
458
|
-
## 12. 支持
|
|
459
|
-
|
|
460
|
-
如有问题和疑问,请在GitHub仓库上提交issue。
|
|
@@ -1,88 +0,0 @@
|
|
|
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
|
-
const AgentTree = require('../BaseAgentRobot/utils/AgentTree.js')
|
|
9
|
-
|
|
10
|
-
class MainAgentRobot extends BaseAgentRobot {
|
|
11
|
-
// toolCollection = null // 工具集合,包含所有工具函数
|
|
12
|
-
constructor(opt) {
|
|
13
|
-
super(opt)
|
|
14
|
-
this.type = 'main'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// 初始化文件
|
|
18
|
-
_initFiles(opt) {
|
|
19
|
-
this.logId = Date.now()
|
|
20
|
-
this.workspace = opt.workspace || process.cwd() // 工作空间,目录
|
|
21
|
-
this.basespace = opt.basespace || path.join(os.homedir(), '.deepfish-ai') // 记忆空间,目录
|
|
22
|
-
this.userspace = path.join(this.basespace, 'user-info') // 用户空间,目录
|
|
23
|
-
this.userInfoFilePath = path.join(this.userspace, 'user.md')
|
|
24
|
-
this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
|
|
25
|
-
this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
|
|
26
|
-
fs.ensureDirSync(this.memorySpace)
|
|
27
|
-
fs.ensureDirSync(this.userspace)
|
|
28
|
-
// 查看agentRecord.json文件是否存在,不存在则创建
|
|
29
|
-
if (!fs.pathExistsSync(this.agentRecordFilePath)) {
|
|
30
|
-
fs.writeJsonSync(this.agentRecordFilePath, [], { spaces: 2 })
|
|
31
|
-
}
|
|
32
|
-
// 判断是否已经存在workspace
|
|
33
|
-
let agentRecord = fs.readJsonSync(this.agentRecordFilePath)
|
|
34
|
-
const record = agentRecord.find(
|
|
35
|
-
(record) => record.workspace === this.workspace,
|
|
36
|
-
)
|
|
37
|
-
if (record) {
|
|
38
|
-
this.id = record.agentId
|
|
39
|
-
this.name = record.name
|
|
40
|
-
this.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
|
|
41
|
-
} else {
|
|
42
|
-
agentRecord.push({
|
|
43
|
-
agentId: this.id,
|
|
44
|
-
name: this.name,
|
|
45
|
-
workspace: this.workspace,
|
|
46
|
-
createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
47
|
-
updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
fs.writeJsonSync(this.agentRecordFilePath, agentRecord, { spaces: 2 })
|
|
51
|
-
this.agentSpace = path.join(this.memorySpace, this.id) // Agent空间,目录
|
|
52
|
-
fs.ensureDirSync(this.agentSpace)
|
|
53
|
-
this.agentTree = new AgentTree(this)
|
|
54
|
-
this.agentTree.init()
|
|
55
|
-
this.memoryFilePath = path.join(this.agentSpace, 'memory.json')
|
|
56
|
-
this.logDirPath = path.join(this.agentSpace, 'logs')
|
|
57
|
-
fs.ensureDirSync(this.logDirPath)
|
|
58
|
-
|
|
59
|
-
// 自动清除过期的记忆和日志
|
|
60
|
-
const currentDate = dayjs()
|
|
61
|
-
agentRecord = agentRecord.filter((record) => {
|
|
62
|
-
if (
|
|
63
|
-
currentDate.diff(dayjs(record.updateTime), 'day') >
|
|
64
|
-
opt.maxMemoryExpireTime
|
|
65
|
-
) {
|
|
66
|
-
// 删除Agent空间
|
|
67
|
-
fs.removeSync(path.join(this.memorySpace, record.agentId))
|
|
68
|
-
return false
|
|
69
|
-
}
|
|
70
|
-
return true
|
|
71
|
-
})
|
|
72
|
-
fs.writeJsonSync(this.agentRecordFilePath, agentRecord, { spaces: 2 })
|
|
73
|
-
this.logger = new Logger(this) // 初始化日志系统
|
|
74
|
-
this.logger.clearAllLogs()
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
_getDefaultSystemPrompt(opt) {
|
|
78
|
-
const systemPrompt = super._getDefaultSystemPrompt(opt)
|
|
79
|
-
return `
|
|
80
|
-
${systemPrompt}
|
|
81
|
-
### 工具调用
|
|
82
|
-
对于复杂的任务,先从可以使用的Skills中查找并使用合适的Skill,如果没有合适的Skill,再使用内置工具函数,使用时请严格按照工具函数的调用方式进行调用。
|
|
83
|
-
${AttachmentToolScanner.getAttachToolPrompt(this.toolManager.toolCollection, this.toolManager.clawSkillCollection)}
|
|
84
|
-
`
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
module.exports = MainAgentRobot
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const os = require('os')
|
|
3
|
-
const BaseAgentRobot = require('../BaseAgentRobot/index.js')
|
|
4
|
-
const Logger = require('../BaseAgentRobot/Logger.js')
|
|
5
|
-
const {AttachmentToolScanner} = require('../BaseAgentRobot/utils/AttachmentToolScanner.js')
|
|
6
|
-
const AgentTree = require('../BaseAgentRobot/utils/AgentTree.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.userspace = path.join(this.basespace, 'user-info') // 用户空间,目录
|
|
23
|
-
this.userInfoFilePath = path.join(this.userspace, 'user.md')
|
|
24
|
-
this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
|
|
25
|
-
this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
|
|
26
|
-
this.agentSpace = path.join(this.memorySpace, this.root.id) // Agent空间,目录
|
|
27
|
-
this.memoryFilePath = path.join(this.agentSpace, `memory-${this.id}.json`)
|
|
28
|
-
this.logDirPath = path.join(this.agentSpace, 'logs')
|
|
29
|
-
this.logger = new Logger(this) // 初始化日志系统
|
|
30
|
-
this.agentTree = new AgentTree(this)
|
|
31
|
-
this.agentTree.init()
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
_getDefaultSystemPrompt(opt) {
|
|
35
|
-
const systemPrompt = super._getDefaultSystemPrompt(opt)
|
|
36
|
-
return `
|
|
37
|
-
${systemPrompt}
|
|
38
|
-
### 工具调用
|
|
39
|
-
对于复杂的任务,先从可以使用的Skills中查找并使用合适的Skill,如果没有合适的Skill,再使用内置工具函数,使用时请严格按照工具函数的调用方式进行调用。
|
|
40
|
-
${AttachmentToolScanner.getAttachToolPrompt(this.toolManager.toolCollection, this.toolManager.clawSkillCollection)}
|
|
41
|
-
`
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
module.exports = SubAgentRobot
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const os = require('os')
|
|
3
|
-
const BaseAgentRobot = require('../BaseAgentRobot/index.js')
|
|
4
|
-
const Logger = require('../BaseAgentRobot/Logger.js')
|
|
5
|
-
const AgentTree = require('../BaseAgentRobot/utils/AgentTree.js')
|
|
6
|
-
const {
|
|
7
|
-
AttachmentToolScanner,
|
|
8
|
-
} = require('../BaseAgentRobot/utils/AttachmentToolScanner.js')
|
|
9
|
-
|
|
10
|
-
class SubSkillAgentRobot extends BaseAgentRobot {
|
|
11
|
-
// opt: { root, parent, ...MainAgentOpt }
|
|
12
|
-
constructor(opt) {
|
|
13
|
-
super(opt)
|
|
14
|
-
this.type = 'sub-skill'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
_initFiles(opt) {
|
|
18
|
-
this.root = opt.root
|
|
19
|
-
this.parent = opt.parent
|
|
20
|
-
this.attachTools = opt.attachTools || []
|
|
21
|
-
this.workspace = opt.workspace || process.cwd() // 工作空间,目录
|
|
22
|
-
this.basespace = opt.basespace || path.join(os.homedir(), '.deepfish-ai') // 记忆空间,目录
|
|
23
|
-
this.userspace = path.join(this.basespace, 'user-info') // 用户空间,目录
|
|
24
|
-
this.userInfoFilePath = path.join(this.userspace, 'user.md')
|
|
25
|
-
this.memorySpace = path.join(this.basespace, 'memory') // 记忆空间,目录
|
|
26
|
-
this.agentRecordFilePath = path.join(this.memorySpace, 'agentRecord.json')
|
|
27
|
-
this.agentSpace = path.join(this.memorySpace, this.root.id) // Agent空间,目录
|
|
28
|
-
this.agentTreeFilePath = path.join(this.agentSpace, 'agentTree.json')
|
|
29
|
-
this.memoryFilePath = path.join(this.agentSpace, `memory-${this.id}.json`)
|
|
30
|
-
this.logDirPath = path.join(this.agentSpace, 'logs')
|
|
31
|
-
this.logger = new Logger(this) // 初始化日志系统
|
|
32
|
-
this.agentTree = new AgentTree(this)
|
|
33
|
-
this.agentTree.init()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
_getDefaultSystemPrompt(opt) {
|
|
37
|
-
const clawSkills = opt.clawSkills || []
|
|
38
|
-
let systemPrompt = super._getDefaultSystemPrompt(opt)
|
|
39
|
-
systemPrompt =
|
|
40
|
-
systemPrompt + '\n' + AttachmentToolScanner.getClawSkillPrompt(clawSkills, this.toolManager.toolCollection, this.toolManager.clawSkillCollection)
|
|
41
|
-
return systemPrompt
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
module.exports = SubSkillAgentRobot
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const { AttachmentToolType, AttachmentToolScanner } = 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
|
-
// 创建子技能Agent
|
|
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
|
-
clawSkills: clawSkill
|
|
29
|
-
})
|
|
30
|
-
parent.children.push(subAgent)
|
|
31
|
-
return subAgent
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 创建子Agent
|
|
35
|
-
createSubAgent(parent, id) {
|
|
36
|
-
const subAgent = new SubAgentRobot({
|
|
37
|
-
...parent.opt,
|
|
38
|
-
id,
|
|
39
|
-
name: `SubAgent-${id}`,
|
|
40
|
-
parent: parent,
|
|
41
|
-
root: parent.root || parent,
|
|
42
|
-
})
|
|
43
|
-
parent.children.push(subAgent)
|
|
44
|
-
return subAgent
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = AgentRobotFactory
|