deepfish-ai 1.0.13 → 1.0.16

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.
@@ -0,0 +1,362 @@
1
+ /**
2
+ * @Author: Roman 306863030@qq.com
3
+ * @Date: 2026-03-23 15:23:42
4
+ * @LastEditors: Roman 306863030@qq.com
5
+ * @LastEditTime: 2026-03-25 20:43:02
6
+ * @FilePath: \deepfish\src\cli\SkillConfigManager.js
7
+ * @Description: Skill configuration manager
8
+ */
9
+ const path = require('path')
10
+ const fs = require('fs-extra')
11
+ const axios = require('axios')
12
+ const cheerio = require('cheerio')
13
+ const { GlobalVariable } = require('../core/globalVariable')
14
+ const { logError, logSuccess } = require('../core/utils/log')
15
+ const extract = require('extract-zip')
16
+ const { parseSkillMetadataYaml } = require('./SkillParser')
17
+ const { openDirectory } = require('../core/utils/normal')
18
+
19
+ // skill的数据结构: {name: string, enable: boolean, description: string, baseDir: string, skillDirName: string, location: string, skillFilePath: string, homepage: string, metadata: object}
20
+ class SkillConfigManager {
21
+ constructor() {
22
+ this.configManager = GlobalVariable.configManager
23
+ // skill目录
24
+ this.skillDir = path.join(this.configManager.configDir, './skills')
25
+ // 自动创建skill目录
26
+ fs.ensureDirSync(this.skillDir)
27
+ this.init()
28
+ GlobalVariable.skillConfigManager = this
29
+ }
30
+
31
+ init() {
32
+ const userConfig = this.configManager.config
33
+ if (!userConfig.skills) {
34
+ userConfig.skills = []
35
+ this.configManager.writeConfig(userConfig)
36
+ }
37
+ this._check()
38
+ }
39
+
40
+ openDirectory() {
41
+ // 打开目录
42
+ openDirectory(this.skillDir)
43
+ }
44
+
45
+ // 预加载skills,拼接提示词
46
+ preLoadSkills() {
47
+ const skills = this.configManager.config.skills.filter((skill) => skill.enable)
48
+ if (skills.length === 0) {
49
+ return ''
50
+ }
51
+ const table = skills
52
+ .map((s) => `| ${s.name} | ${s.description} | ${s.location} | ${s.skillFilePath} |`)
53
+ .join('\n')
54
+ return (
55
+ `
56
+ ### 可以使用的Skill
57
+ 除了使用内置函数,还可以调用以下Skill来完成用户的请求,Skill的调用方式:当用户的请求匹配技能描述时,调用executeSkill函数加载对应Skill的SKILL.md说明文件,获取调用说明,通过仔细阅读说明文件学习Skill的使用方法,来完成任务。
58
+ ## Available Skills
59
+
60
+ | Skill | Description | Location | SkillFilePath |
61
+ |-------|-------------|----------|---------------|
62
+ ${table}
63
+
64
+ ## Skills Policy
65
+ - 当用户请求匹配 skill description 时,调用 executeSkill 函数加载对应 SKILL.md
66
+ - 一次只加载一个Skill,优先匹配最具体的Skill
67
+ - 当用户请求不匹配任何Skill描述时,不加载任何Skill
68
+ - Skill即你可以使用的技能`
69
+ )
70
+ }
71
+
72
+ // 调用skill,传入参数,返回结果
73
+ loadSkill(skillFilePath) {
74
+ // 读取skill的SKILL.md,获取调用说明
75
+ if (!fs.existsSync(skillFilePath)) {
76
+ logError(`Skill file "${skillFilePath}" does not exist.`)
77
+ return null
78
+ }
79
+ return fs.readFileSync(skillFilePath, 'utf-8')
80
+ }
81
+
82
+ // 解析skill文件,写入到json中,获取名称、版本、作者、元数据、描述等信息
83
+ _parseSkill(skillDirPath) {
84
+ const skillMdPath = ['SKILL.md', 'skill.md']
85
+ .map((name) => path.join(skillDirPath, name))
86
+ .find((filePath) => fs.existsSync(filePath))
87
+ if (!skillMdPath) {
88
+ return {}
89
+ }
90
+ const parsed = parseSkillMetadataYaml(skillMdPath)
91
+ return parsed
92
+ }
93
+
94
+ // 查看skills列表
95
+ viewList() {
96
+ const skills = this.configManager.config.skills
97
+ if (skills && Array.isArray(skills)) {
98
+ console.log('='.repeat(50))
99
+ // 打印扩展列表,并加上索引
100
+ if (skills.length === 0) {
101
+ console.log(`No skills in config.`)
102
+ } else {
103
+ console.log('Skills in config:')
104
+ skills.forEach((skill, index) => {
105
+ console.log(`[${index}] ${skill.name} (${skill.enable ? 'Enabled' : 'Disabled'})`)
106
+ })
107
+ }
108
+ console.log('='.repeat(50))
109
+ } else {
110
+ logError(`No skills in config.`)
111
+ }
112
+ }
113
+ _check() {
114
+ // 如果数组的数量与目录中的数量不一致,则自动同步
115
+ const userConfig = this.configManager.config
116
+ const skills = userConfig.skills
117
+ const skillDirs = fs.readdirSync(this.skillDir).filter((file) => {
118
+ return fs.statSync(path.join(this.skillDir, file)).isDirectory()
119
+ })
120
+ if (skills.length === skillDirs.length) {
121
+ return
122
+ }
123
+ if (skills.length !== skillDirs.length) {
124
+ // 查询未被注册的skill,自动注册
125
+ skillDirs.forEach((skillDir) => {
126
+ if (
127
+ !skills.some(
128
+ (skill) => skill.skillDirName === skillDir || skill.name === skillDir,
129
+ )
130
+ ) {
131
+ this._registerSkill(skillDir, false)
132
+ }
133
+ })
134
+ // 查询已注册但目录不存在的skill,自动从列表中删除
135
+ skills.forEach((skill) => {
136
+ if (!skillDirs.includes(skill.skillDirName)) {
137
+ this.remove(skill.name)
138
+ }
139
+ })
140
+ }
141
+ }
142
+
143
+ // 添加skills
144
+ async add(skillName) {
145
+ // 从当前目录process.pwd()查询是否存在同名的skill
146
+ // 如果存在则判断是否是目录=>1.如果是目录则拷贝到skills目录下,并添加到config中 2.如果是zip文件则解压到skills目录下,并添加到config中
147
+ // 如果不存在则提示从ClawHub中下载https://clawhub.ai/
148
+ const baseName = path.basename(skillName, '.zip')
149
+ const fileNames = fs.readdirSync(process.cwd())
150
+ const file = fileNames.find(
151
+ (name) => name === baseName || name === `${baseName}.zip`,
152
+ )
153
+ if (file) {
154
+ // 如果存在同名文件,则判断是否是目录
155
+ const baseDir = path.join(process.cwd(), file)
156
+ if (fs.statSync(baseDir).isDirectory()) {
157
+ // 如果是目录,则拷贝到skills目录下,并添加到config中
158
+ fs.copySync(baseDir, path.join(this.skillDir, file))
159
+ this._registerSkill(baseName)
160
+ } else if (path.extname(file) === '.zip') {
161
+ // 如果是zip文件,则解压到skills目录下,并添加到config中
162
+ const extractPath = path.join(this.skillDir, baseName)
163
+ await extract(baseDir, { dir: extractPath })
164
+ this._registerSkill(baseName)
165
+ } else {
166
+ logError(`File "${file}" is not a directory or a zip file.`)
167
+ }
168
+ } else {
169
+ logError(
170
+ `No skill named "${skillName}" found in current directory. Please download it from ClawHub (https://clawhub.ai/) and place it in the current directory.`,
171
+ )
172
+ }
173
+ }
174
+
175
+ // install('https://clawhub.ai/TheSethRose/agent-browser')
176
+ async install(skillUrl) {
177
+ // 从ClawHub下载zip并解压到skills目录下,并添加到config中
178
+ if (!skillUrl || typeof skillUrl !== 'string') {
179
+ logError('Invalid skill URL. Please provide a valid ClawHub URL.')
180
+ return
181
+ }
182
+
183
+ let parsedUrl
184
+ try {
185
+ parsedUrl = new URL(skillUrl)
186
+ } catch (error) {
187
+ logError('Invalid skill URL format.')
188
+ return
189
+ }
190
+
191
+ const host = parsedUrl.hostname.toLowerCase()
192
+ if (host !== 'clawhub.ai' && host !== 'www.clawhub.ai') {
193
+ logError(
194
+ 'Only ClawHub URLs are supported, e.g. https://clawhub.ai/author/skill-name',
195
+ )
196
+ return
197
+ }
198
+
199
+ const segments = parsedUrl.pathname.split('/').filter(Boolean)
200
+ if (segments.length < 2) {
201
+ logError(
202
+ 'Invalid ClawHub URL. Expected format: https://clawhub.ai/<author>/<skill-name>',
203
+ )
204
+ return
205
+ }
206
+
207
+ const skillName = path.basename(segments[1], '.zip')
208
+ const userConfig = this.configManager.config
209
+ if (userConfig.skills.some((skill) => skill.name === skillName)) {
210
+ logError(`Skill with name "${skillName}" already exists in config.`)
211
+ return
212
+ }
213
+ // 查看目录是否存在当前的skill
214
+ const skillPath = path.join(this.skillDir, skillName)
215
+ if (fs.existsSync(skillPath)) {
216
+ logError(`Skill "${skillName}" already exists in the skills directory.`)
217
+ return
218
+ }
219
+ const zipFilePath = path.join(this.skillDir, `${skillName}.zip`)
220
+ const extractPath = path.join(this.skillDir, skillName)
221
+
222
+ try {
223
+ // 自动获取download地址
224
+ const response = await axios({
225
+ method: 'get',
226
+ url: skillUrl,
227
+ responseType: 'text',
228
+ timeout: 30000,
229
+ maxRedirects: 5,
230
+ validateStatus: (status) => status >= 200 && status < 300,
231
+ })
232
+
233
+ // 解析HTML获取下载链接
234
+ const html = response.data
235
+ const $ = cheerio.load(html)
236
+ const downloadHref = $('.skill-hero-cta a').first().attr('href')
237
+
238
+ if (!downloadHref) {
239
+ logError(`No download link found for skill "${skillName}".`)
240
+ return
241
+ }
242
+
243
+ const downloadUrl = new URL(downloadHref, parsedUrl.origin).toString()
244
+ const zipResponse = await axios({
245
+ method: 'get',
246
+ url: downloadUrl,
247
+ responseType: 'arraybuffer',
248
+ timeout: 60000,
249
+ maxRedirects: 5,
250
+ validateStatus: (status) => status >= 200 && status < 300,
251
+ })
252
+ fs.writeFileSync(zipFilePath, Buffer.from(zipResponse.data))
253
+ await extract(zipFilePath, { dir: extractPath })
254
+ this._registerSkill(skillName)
255
+ logSuccess(`Skill "${skillName}" installed successfully!`)
256
+ } catch (error) {
257
+ logError(`Failed to install skill "${skillName}": ${error.message}`)
258
+ } finally {
259
+ fs.removeSync(zipFilePath)
260
+ }
261
+ }
262
+
263
+ // 根据名称或索引 删除skills
264
+ remove(skillName) {
265
+ const userConfig = this.configManager.config
266
+ const skillObj = this._getSkill(skillName)
267
+ if (!skillObj) {
268
+ return
269
+ }
270
+ const { skill, index } = skillObj
271
+ const skillPath = skill.location
272
+ userConfig.skills = userConfig.skills.filter((_, i) => i !== index)
273
+ this.configManager.writeConfig(userConfig)
274
+ if (fs.existsSync(skillPath)) {
275
+ fs.removeSync(skillPath)
276
+ }
277
+ logSuccess(`Skill "${skill.name}" removed successfully!`)
278
+ }
279
+
280
+ // 根据名称或索引 启用skill-限制最大启用100个
281
+ enable(skillName) {
282
+ const userConfig = this.configManager.config
283
+ const skills = userConfig.skills
284
+ const enabledCount = skills.filter((skill) => skill.enable).length
285
+ if (enabledCount >= 100) {
286
+ logError('Cannot enable more than 100 skills.')
287
+ return
288
+ }
289
+ const skillObj = this._getSkill(skillName)
290
+ if (!skillObj) {
291
+ return
292
+ }
293
+ const { skill } = skillObj
294
+ skill.enable = true
295
+ this.configManager.writeConfig(userConfig)
296
+ logSuccess(`Skill "${skill.name}" enabled successfully!`)
297
+ }
298
+
299
+ // 根据名称或索引 禁用skill
300
+ disable(skillName) {
301
+ const userConfig = this.configManager.config
302
+ const skillObj = this._getSkill(skillName)
303
+ if (!skillObj) {
304
+ return
305
+ }
306
+ const { skill } = skillObj
307
+ skill.enable = false
308
+ this.configManager.writeConfig(userConfig)
309
+ logSuccess(`Skill "${skill.name}" disabled successfully!`)
310
+ }
311
+
312
+ // 解析skill的描述文件,获取name、description
313
+ _registerSkill(skillDirName, enable = true) {
314
+ const userConfig = this.configManager.config
315
+ // 同名检测
316
+ if (userConfig.skills.some((skill) => skill.name === skillDirName)) {
317
+ throw new Error(
318
+ `Skill with name "${skillDirName}" already exists in config.`,
319
+ )
320
+ }
321
+ const skillDirPath = path.join(this.skillDir, skillDirName)
322
+ // 获取name、description
323
+ const skillInfo = this._parseSkill(skillDirPath)
324
+ const name = skillInfo.name || skillDirName
325
+ const description = skillInfo.description || ''
326
+ userConfig.skills.push({
327
+ name,
328
+ description,
329
+ enable,
330
+ baseDir: this.skillDir,
331
+ skillDirName: skillDirName,
332
+ ...skillInfo,
333
+ })
334
+ this.configManager.writeConfig(userConfig)
335
+ }
336
+
337
+ _getSkill(skillName) {
338
+ const userConfig = this.configManager.config
339
+ let index = parseInt(skillName, 10)
340
+ let skill = null
341
+ if (!isNaN(index)) {
342
+ if (index < 0 || index >= userConfig.skills.length) {
343
+ logError(`Skill index "${index}" is out of range.`)
344
+ } else {
345
+ skill = userConfig.skills[index]
346
+ }
347
+ } else {
348
+ index = userConfig.skills.findIndex((skill) => skill.name === skillName)
349
+ if (index === -1) {
350
+ logError(`Skill with name "${skillName}" not found in config.`)
351
+ return
352
+ }
353
+ skill = userConfig.skills[index]
354
+ }
355
+ return {
356
+ skill,
357
+ index,
358
+ }
359
+ }
360
+ }
361
+
362
+ module.exports = SkillConfigManager
@@ -0,0 +1,61 @@
1
+ const fs = require("fs-extra");
2
+ const path = require("path");
3
+ const yaml = require('js-yaml');
4
+
5
+ function parseSkillMetadata(skillPath) {
6
+ const content = fs.readFileSync(skillPath, 'utf-8');
7
+
8
+ // 提取 frontmatter (--- 之间的内容)
9
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
10
+ if (!frontmatterMatch) {
11
+ throw new Error(`No frontmatter found in ${skillPath}`);
12
+ }
13
+
14
+ const frontmatter = frontmatterMatch[1];
15
+ const metadata = {};
16
+
17
+ // 解析 key: value 或 key: "quoted value"
18
+ const lines = frontmatter.split('\n');
19
+ for (const line of lines) {
20
+ const match = line.match(/^(\w+):\s*(.+)$/);
21
+ if (match) {
22
+ const [, key, value] = match;
23
+ // 去除引号
24
+ metadata[key] = value.replace(/^["']|["']$/g, '');
25
+ }
26
+ }
27
+
28
+ return {
29
+ name: metadata.name,
30
+ description: metadata.description,
31
+ homepage: metadata.homepage,
32
+ location: path.dirname(skillPath),
33
+ skillFilePath: skillPath,
34
+ metadata: metadata.metadata || {}
35
+ };
36
+ }
37
+
38
+ function parseSkillMetadataYaml(skillPath) {
39
+ const content = fs.readFileSync(skillPath, 'utf-8');
40
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
41
+
42
+ if (!frontmatterMatch) {
43
+ throw new Error(`No frontmatter found in ${skillPath}`);
44
+ }
45
+
46
+ const frontmatter = yaml.load(frontmatterMatch[1]);
47
+
48
+ return {
49
+ name: frontmatter.name,
50
+ description: frontmatter.description,
51
+ homepage: frontmatter.homepage,
52
+ location: path.dirname(skillPath),
53
+ metadata: frontmatter.metadata || {},
54
+ skillFilePath: skillPath,
55
+ };
56
+ }
57
+
58
+ module.exports = {
59
+ parseSkillMetadata,
60
+ parseSkillMetadataYaml
61
+ }
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * @Author: Roman 306863030@qq.com
3
3
  * @Date: 2026-03-19 11:45:10
4
- * @LastEditors: roman_123 306863030@qq.com
5
- * @LastEditTime: 2026-03-20 23:54:34
4
+ * @LastEditors: Roman 306863030@qq.com
5
+ * @LastEditTime: 2026-03-25 18:40:12
6
6
  * @FilePath: \deepfish\src\cli\ai-config.js
7
7
  * @Description: ai config 相关命令
8
8
  * @
9
9
  */
10
10
  const { program } = require('commander')
11
- const { aiCliConfig } = require('./configTools')
11
+ const { aiCliConfig } = require('./DefaultConfig')
12
12
  const { askConfirm, askAny } = require('../core/utils/log')
13
13
  const ConfigManager = require('./ConfigManager')
14
14
 
@@ -24,6 +24,13 @@ configCommand
24
24
  configManager.edit()
25
25
  })
26
26
 
27
+ configCommand
28
+ .command('dir')
29
+ .description('Open configuration directory')
30
+ .action(() => {
31
+ configManager.dir()
32
+ })
33
+
27
34
  configCommand
28
35
  .command('reset')
29
36
  .description('Reset configuration file')
@@ -58,6 +65,10 @@ configCommand
58
65
  }
59
66
  const hasName = configManager.checkName(value.trim())
60
67
  if (hasName) {
68
+ setTimeout(() => {
69
+ // 结束会话
70
+ process.exit(0)
71
+ })
61
72
  return 'Configuration with this name already exists. Please enter a different name.'
62
73
  }
63
74
  return true
@@ -105,7 +116,7 @@ configCommand
105
116
  message: 'Enter DeepSeek model name:',
106
117
  when: (answers) =>
107
118
  answers.Type === 'DeepSeek' && answers.model === 'other',
108
- default: 'deepseek-chat',
119
+ default: 'deepseek-reasoner',
109
120
  },
110
121
  {
111
122
  type: 'input',
@@ -130,6 +141,13 @@ configCommand
130
141
  name: 'maxTokens',
131
142
  message: 'Enter max tokens:',
132
143
  default: (answers) => {
144
+ if (answers.Type === 'DeepSeek') {
145
+ if (answers.model === 'deepseek-chat') {
146
+ return 8192
147
+ } else if (answers.model === 'deepseek-reasoner') {
148
+ return 65536
149
+ }
150
+ }
133
151
  return aiCliConfig[answers.Type].maxTokens
134
152
  },
135
153
  validate: (value) => value > 0 || 'Max tokens must be greater than 0',
@@ -154,7 +172,7 @@ configCommand
154
172
  maxTokens: answers.maxTokens,
155
173
  stream: answers.stream,
156
174
  }
157
- configManager.addAiConfig(aiConfig)
175
+ return configManager.addAiConfig(aiConfig)
158
176
  })
159
177
 
160
178
  configCommand
@@ -0,0 +1,34 @@
1
+ const { program } = require("commander");
2
+ const HistoryManager = require("./HistoryManager");
3
+ const historyManager = new HistoryManager();
4
+ const extCommand = program
5
+ .command("history")
6
+ .description("History management commands");
7
+
8
+ extCommand
9
+ .command("clear")
10
+ .description("Clear the history messages for the current directory")
11
+ .action(() => {
12
+ historyManager.clearMessage();
13
+ });
14
+
15
+ extCommand
16
+ .command("output")
17
+ .description("Output the history messages to current directory")
18
+ .action(() => {
19
+ historyManager.outputMessage();
20
+ });
21
+
22
+ extCommand
23
+ .command("dir")
24
+ .description("Open the history directory")
25
+ .action(() => {
26
+ historyManager.openDirectory();
27
+ });
28
+
29
+ extCommand
30
+ .command("reset")
31
+ .description("Reset all history for all directories")
32
+ .action(() => {
33
+ historyManager.reset();
34
+ });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @Author: Roman 306863030@qq.com
3
+ * @Date: 2026-03-23 15:07:51
4
+ * @LastEditors: Roman 306863030@qq.com
5
+ * @LastEditTime: 2026-03-25 16:03:48
6
+ * @FilePath: \deepfish\src\cli\ai-skill.js
7
+ * @Description: AI skill management CLI
8
+ * @
9
+ */
10
+ const { program } = require("commander");
11
+ const SkillConfigManager = require("./SkillConfigManager");
12
+ const skillConfigManager = new SkillConfigManager()
13
+ // ai skill command
14
+ const skillCommand = program
15
+ .command("skill")
16
+ .description("Skill management commands");
17
+
18
+ skillCommand
19
+ .command("ls")
20
+ .description("List all skills in the configuration")
21
+ .action(() => {
22
+ skillConfigManager.viewList();
23
+ });
24
+
25
+ skillCommand
26
+ .command("add <name>")
27
+ .description("Add a local skill directory or zip file")
28
+ .action(async (name) => {
29
+ await skillConfigManager.add(name);
30
+ });
31
+
32
+ skillCommand
33
+ .command("del <name>")
34
+ .description("Remove a skill by name or index")
35
+ .action((name) => {
36
+ skillConfigManager.remove(name);
37
+ });
38
+
39
+ skillCommand
40
+ .command("dir")
41
+ .description("Open the history directory")
42
+ .action(() => {
43
+ skillConfigManager.openDirectory();
44
+ });
45
+
46
+ skillCommand
47
+ .command("install <url>")
48
+ .description("Install a skill from ClawHub")
49
+ .action(async (url) => {
50
+ await skillConfigManager.install(url);
51
+ });
52
+
53
+ skillCommand
54
+ .command("enable <name>")
55
+ .description("Enable a skill by name or index")
56
+ .action((name) => {
57
+ skillConfigManager.enable(name);
58
+ });
59
+
60
+ skillCommand
61
+ .command("disable <name>")
62
+ .description("Disable a skill by name or index")
63
+ .action((name) => {
64
+ skillConfigManager.disable(name);
65
+ });
package/src/cli/index.js CHANGED
@@ -1,12 +1,12 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  const { program } = require("commander");
3
3
  const AICLI = require("../core/AICLI");
4
4
  const { logError } = require("../core/utils/log");
5
5
  const { GlobalVariable } = require("../core/globalVariable.js");
6
- const ConfigManager = require("./ConfigManager.js");
7
6
  require("./ai-config.js");
8
7
  require("./ai-ext.js");
9
-
8
+ require("./ai-skill.js");
9
+ require("./ai-history.js");
10
10
  program
11
11
  .version("1.0.0")
12
12
  .description(
@@ -21,7 +21,7 @@ program
21
21
 
22
22
  async function main() {
23
23
  try {
24
- if (program.args && (program.args[0] === "config" || program.args[0] === "ext")) {
24
+ if (program.args && (program.args[0] === "config" || program.args[0] === "ext" || program.args[0] === "skill") || (program.args[0] === "history")) {
25
25
  return;
26
26
  }
27
27
  const options = program.opts();
@@ -50,9 +50,6 @@ async function main() {
50
50
  logError("Please use 'ai config use <name>' to set a current configuration.");
51
51
  return;
52
52
  }
53
- if (!GlobalVariable.configManager) {
54
- GlobalVariable.configManager = new ConfigManager();
55
- }
56
53
  const cli = new AICLI(configManager.config);
57
54
  if (options.interactive) {
58
55
  cli.startInteractive();
package/src/core/AICLI.js CHANGED
@@ -2,22 +2,20 @@ const ExtensionManager = require('./extension/ExtensionManager')
2
2
  const readline = require('readline')
3
3
  const { logError } = require('./utils/log')
4
4
  const { GlobalVariable } = require('./globalVariable')
5
- const AiRecorder = require('./ai-services/AiWorker/AiRecorder')
6
- const AIService = require('./ai-services/AIService')
5
+ const AIService = require('./ai-services')
7
6
 
8
7
  class AICLI {
9
8
  constructor(config) {
10
9
  this.config = config
11
10
  this.aiConfig = GlobalVariable.configManager.getCurrentAiConfig()
11
+ this.skillConfigManager = GlobalVariable.skillConfigManager
12
+ this.historyManager = GlobalVariable.historyManager
12
13
  // 初始化扩展
13
14
  this.extensionManager = new ExtensionManager(this)
14
15
  this.Tools = this.extensionManager.extensions.functions
15
- this.aiRecorder = new AiRecorder(this);
16
+
16
17
  this.aiService = new AIService(this.aiConfig.type, this)
17
18
  GlobalVariable.aiCli = this
18
- GlobalVariable.aiRecorder = this.aiRecorder
19
- GlobalVariable.isRecordHistory = this.config.isRecordHistory || false
20
- GlobalVariable.isLog = this.config.isLog || false
21
19
  }
22
20
 
23
21
  // 单轮对话
@@ -1,9 +1,8 @@
1
1
  const GlobalVariable = {
2
2
  aiCli: null,
3
- aiRecorder: null,
4
- isRecordHistory: false,
5
- isLog: false,
6
3
  configManager: null,
4
+ skillConfigManager: null,
5
+ historyManager: null,
7
6
  }
8
7
 
9
8
  module.exports = {