deepfish-ai 1.0.29 → 2.0.3
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 +195 -344
- package/dist/generate-skill.md +104 -0
- package/dist/generate-tool.md +88 -0
- package/dist/index.js +26831 -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 +24405 -0
- package/dist/serve/server/entry-server.mjs +224 -0
- package/dist/view-learn-cache.md +65 -0
- package/package.json +77 -83
- 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 -424
- 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 -354
- 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/src/cli/ai-auth.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
const axios = require('axios')
|
|
2
|
-
const { program } = require('commander')
|
|
3
|
-
const aiInquirer = require('../AgentRobot/BaseAgentRobot/utils/aiInquirer.js')
|
|
4
|
-
const aiConsole = require('../AgentRobot/BaseAgentRobot/utils/aiConsole.js')
|
|
5
|
-
const ConfigManager = require('./ConfigManager.js')
|
|
6
|
-
const { GlobalVariable } = require('./GlobalVariable.js')
|
|
7
|
-
|
|
8
|
-
function sleep(ms) {
|
|
9
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function secondsToISO(seconds) {
|
|
13
|
-
if (!seconds || Number(seconds) <= 0) {
|
|
14
|
-
return ''
|
|
15
|
-
}
|
|
16
|
-
return new Date(Date.now() + Number(seconds) * 1000).toISOString()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getConfigManager() {
|
|
20
|
-
return GlobalVariable.configManager || new ConfigManager()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function githubDeviceLogin({
|
|
24
|
-
configManager,
|
|
25
|
-
targetName,
|
|
26
|
-
currentAuth = {},
|
|
27
|
-
saveToConfig = true,
|
|
28
|
-
} = {}) {
|
|
29
|
-
const manager = configManager || getConfigManager()
|
|
30
|
-
let aiConfig = null
|
|
31
|
-
|
|
32
|
-
if (saveToConfig) {
|
|
33
|
-
if (!targetName) {
|
|
34
|
-
aiConsole.logError('No target AI configuration. Please pass a config name or set current AI first.')
|
|
35
|
-
return null
|
|
36
|
-
}
|
|
37
|
-
aiConfig = manager.getAiConfig(targetName)
|
|
38
|
-
if (!aiConfig) {
|
|
39
|
-
aiConsole.logError(`Configuration with name "${targetName}" not found.`)
|
|
40
|
-
return null
|
|
41
|
-
}
|
|
42
|
-
if (aiConfig.type !== 'copilot') {
|
|
43
|
-
aiConsole.logError(
|
|
44
|
-
`Configuration "${targetName}" is type "${aiConfig.type}". GitHub login only supports "copilot" type.`,
|
|
45
|
-
)
|
|
46
|
-
return null
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const authSeed = saveToConfig ? (aiConfig.githubAuth || {}) : (currentAuth || {})
|
|
51
|
-
const questions = [
|
|
52
|
-
{
|
|
53
|
-
type: 'input',
|
|
54
|
-
name: 'clientId',
|
|
55
|
-
message: 'Enter GitHub OAuth App Client ID:',
|
|
56
|
-
default: authSeed.clientId || process.env.GITHUB_OAUTH_CLIENT_ID || '',
|
|
57
|
-
validate: (value) => !!String(value || '').trim() || 'Client ID is required',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
type: 'password',
|
|
61
|
-
name: 'clientSecret',
|
|
62
|
-
message: 'Enter GitHub OAuth App Client Secret (optional, needed for refresh in some OAuth app settings):',
|
|
63
|
-
mask: '*',
|
|
64
|
-
default: authSeed.clientSecret || process.env.GITHUB_OAUTH_CLIENT_SECRET || '',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: 'input',
|
|
68
|
-
name: 'scope',
|
|
69
|
-
message: 'Enter OAuth scope:',
|
|
70
|
-
default: authSeed.scope || 'models:read',
|
|
71
|
-
},
|
|
72
|
-
]
|
|
73
|
-
|
|
74
|
-
const answers = await aiInquirer.askAny(questions)
|
|
75
|
-
const clientId = String(answers.clientId || '').trim()
|
|
76
|
-
const clientSecret = String(answers.clientSecret || '').trim()
|
|
77
|
-
const scope = String(answers.scope || 'models:read').trim()
|
|
78
|
-
|
|
79
|
-
let deviceCodeResponse
|
|
80
|
-
try {
|
|
81
|
-
const form = new URLSearchParams()
|
|
82
|
-
form.set('client_id', clientId)
|
|
83
|
-
form.set('scope', scope)
|
|
84
|
-
|
|
85
|
-
const res = await axios.post(
|
|
86
|
-
'https://github.com/login/device/code',
|
|
87
|
-
form.toString(),
|
|
88
|
-
{
|
|
89
|
-
headers: {
|
|
90
|
-
Accept: 'application/json',
|
|
91
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
92
|
-
},
|
|
93
|
-
timeout: 20000,
|
|
94
|
-
},
|
|
95
|
-
)
|
|
96
|
-
deviceCodeResponse = res.data
|
|
97
|
-
} catch (error) {
|
|
98
|
-
const message = error?.response?.data?.error_description || error.message
|
|
99
|
-
aiConsole.logError(`Failed to request GitHub device code: ${message}`)
|
|
100
|
-
return null
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const deviceCode = deviceCodeResponse.device_code
|
|
104
|
-
const userCode = deviceCodeResponse.user_code
|
|
105
|
-
const verificationUri = deviceCodeResponse.verification_uri || 'https://github.com/login/device'
|
|
106
|
-
const expiresIn = Number(deviceCodeResponse.expires_in || 900)
|
|
107
|
-
let intervalSec = Number(deviceCodeResponse.interval || 5)
|
|
108
|
-
|
|
109
|
-
aiConsole.logSuccess('Please complete GitHub login in browser:')
|
|
110
|
-
aiConsole.logInfo(`URL: ${verificationUri}`)
|
|
111
|
-
aiConsole.logInfo(`Code: ${userCode}`)
|
|
112
|
-
|
|
113
|
-
const deadline = Date.now() + expiresIn * 1000
|
|
114
|
-
|
|
115
|
-
while (Date.now() < deadline) {
|
|
116
|
-
await sleep(intervalSec * 1000)
|
|
117
|
-
try {
|
|
118
|
-
const form = new URLSearchParams()
|
|
119
|
-
form.set('client_id', clientId)
|
|
120
|
-
form.set('device_code', deviceCode)
|
|
121
|
-
form.set('grant_type', 'urn:ietf:params:oauth:grant-type:device_code')
|
|
122
|
-
|
|
123
|
-
const res = await axios.post(
|
|
124
|
-
'https://github.com/login/oauth/access_token',
|
|
125
|
-
form.toString(),
|
|
126
|
-
{
|
|
127
|
-
headers: {
|
|
128
|
-
Accept: 'application/json',
|
|
129
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
130
|
-
},
|
|
131
|
-
timeout: 20000,
|
|
132
|
-
},
|
|
133
|
-
)
|
|
134
|
-
const tokenData = res.data || {}
|
|
135
|
-
|
|
136
|
-
if (tokenData.error) {
|
|
137
|
-
if (tokenData.error === 'authorization_pending') {
|
|
138
|
-
continue
|
|
139
|
-
}
|
|
140
|
-
if (tokenData.error === 'slow_down') {
|
|
141
|
-
intervalSec = Number(tokenData.interval || intervalSec + 5)
|
|
142
|
-
continue
|
|
143
|
-
}
|
|
144
|
-
if (tokenData.error === 'expired_token') {
|
|
145
|
-
aiConsole.logError('Device code expired. Please run the login command again.')
|
|
146
|
-
return null
|
|
147
|
-
}
|
|
148
|
-
if (tokenData.error === 'access_denied') {
|
|
149
|
-
aiConsole.logError('GitHub authorization denied by user.')
|
|
150
|
-
return null
|
|
151
|
-
}
|
|
152
|
-
aiConsole.logError(tokenData.error_description || tokenData.error)
|
|
153
|
-
return null
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!tokenData.access_token) {
|
|
157
|
-
aiConsole.logError('GitHub login failed: no access_token returned.')
|
|
158
|
-
return null
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const githubAuthPatch = {
|
|
162
|
-
provider: 'github-oauth-device',
|
|
163
|
-
clientId,
|
|
164
|
-
clientSecret,
|
|
165
|
-
scope,
|
|
166
|
-
tokenType: tokenData.token_type || 'bearer',
|
|
167
|
-
accessTokenExpiresAt: secondsToISO(tokenData.expires_in),
|
|
168
|
-
refreshToken: tokenData.refresh_token || '',
|
|
169
|
-
refreshTokenExpiresAt: secondsToISO(tokenData.refresh_token_expires_in),
|
|
170
|
-
lastUpdatedAt: new Date().toISOString(),
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (saveToConfig) {
|
|
174
|
-
manager.updateAiConfigByName(targetName, (current) => {
|
|
175
|
-
return {
|
|
176
|
-
...current,
|
|
177
|
-
apiKey: tokenData.access_token,
|
|
178
|
-
githubAuth: {
|
|
179
|
-
...(current.githubAuth || {}),
|
|
180
|
-
...githubAuthPatch,
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
})
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
aiConsole.logSuccess('GitHub login success.')
|
|
187
|
-
if (githubAuthPatch.accessTokenExpiresAt) {
|
|
188
|
-
aiConsole.logInfo(`Access token expires at: ${githubAuthPatch.accessTokenExpiresAt}`)
|
|
189
|
-
}
|
|
190
|
-
if (!githubAuthPatch.refreshToken) {
|
|
191
|
-
aiConsole.logInfo('No refresh token returned. Re-login may be required after access token expires.')
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
accessToken: tokenData.access_token,
|
|
196
|
-
githubAuth: githubAuthPatch,
|
|
197
|
-
}
|
|
198
|
-
} catch (error) {
|
|
199
|
-
const message = error?.response?.data?.error_description || error.message
|
|
200
|
-
aiConsole.logError(`Polling GitHub token failed: ${message}`)
|
|
201
|
-
return null
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
aiConsole.logError('GitHub login timeout. Please run the command again.')
|
|
206
|
-
return null
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const authCommand = program
|
|
210
|
-
.command('auth')
|
|
211
|
-
.description('Authenticate third-party model providers')
|
|
212
|
-
|
|
213
|
-
authCommand
|
|
214
|
-
.command('github-login [name]')
|
|
215
|
-
.description('Login with GitHub account (Device Flow) and store short-lived token into a copilot config')
|
|
216
|
-
.action(async (name) => {
|
|
217
|
-
const configManager = getConfigManager()
|
|
218
|
-
const targetName = name || configManager.getCurrentAi()
|
|
219
|
-
const res = await githubDeviceLogin({
|
|
220
|
-
configManager,
|
|
221
|
-
targetName,
|
|
222
|
-
saveToConfig: true,
|
|
223
|
-
})
|
|
224
|
-
if (res) {
|
|
225
|
-
aiConsole.logSuccess(`Token has been saved to AI config "${targetName}".`)
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
module.exports = {
|
|
230
|
-
githubDeviceLogin,
|
|
231
|
-
}
|
package/src/cli/ai-config.js
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @Author: Roman 306863030@qq.com
|
|
3
|
-
* @Date: 2026-03-19 11:45:10
|
|
4
|
-
* @LastEditors: Roman 306863030@qq.com
|
|
5
|
-
* @LastEditTime: 2026-04-07 15:15:43
|
|
6
|
-
* @FilePath: \deepfish\src\cli\ai-config.js
|
|
7
|
-
* @Description: ai config 相关命令
|
|
8
|
-
* @
|
|
9
|
-
*/
|
|
10
|
-
const { program } = require('commander')
|
|
11
|
-
const { aiCliConfig } = require('./DefaultConfig.js')
|
|
12
|
-
const ConfigManager = require('./ConfigManager.js')
|
|
13
|
-
const aiInquirer = require('../AgentRobot/BaseAgentRobot/utils/aiInquirer.js')
|
|
14
|
-
const aiConsole = require('../AgentRobot/BaseAgentRobot/utils/aiConsole.js')
|
|
15
|
-
const { githubDeviceLogin } = require('./ai-auth.js')
|
|
16
|
-
|
|
17
|
-
const configManager = new ConfigManager()
|
|
18
|
-
const configCommand = program
|
|
19
|
-
.command('config')
|
|
20
|
-
.description('Configure AI service settings')
|
|
21
|
-
|
|
22
|
-
configCommand
|
|
23
|
-
.command('edit')
|
|
24
|
-
.description('Edit configuration file with default editor')
|
|
25
|
-
.action(() => {
|
|
26
|
-
configManager.edit()
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
configCommand
|
|
30
|
-
.command('dir')
|
|
31
|
-
.description('Open configuration directory')
|
|
32
|
-
.action(() => {
|
|
33
|
-
configManager.dir()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
configCommand
|
|
37
|
-
.command('reset')
|
|
38
|
-
.description('Reset configuration file')
|
|
39
|
-
.action(async () => {
|
|
40
|
-
const isReset = await aiInquirer.askConfirm(
|
|
41
|
-
'isReset',
|
|
42
|
-
'Are you sure you want to reset the configuration file?',
|
|
43
|
-
false,
|
|
44
|
-
)
|
|
45
|
-
if (isReset) {
|
|
46
|
-
configManager.resetConfig()
|
|
47
|
-
} else {
|
|
48
|
-
console.log('Operation cancelled')
|
|
49
|
-
process.exit(0)
|
|
50
|
-
}
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
configCommand
|
|
54
|
-
.command('add')
|
|
55
|
-
.description('Add a new AI configuration')
|
|
56
|
-
.action(async () => {
|
|
57
|
-
console.log('AI Service Configuration')
|
|
58
|
-
console.log('='.repeat(50))
|
|
59
|
-
const questions = [
|
|
60
|
-
{
|
|
61
|
-
type: 'input',
|
|
62
|
-
name: 'name',
|
|
63
|
-
message: 'Enter AI configuration name:',
|
|
64
|
-
validate: (value) => {
|
|
65
|
-
if (value.trim() === '') {
|
|
66
|
-
return 'Configuration name cannot be empty'
|
|
67
|
-
}
|
|
68
|
-
const hasName = configManager.checkName(value.trim())
|
|
69
|
-
if (hasName) {
|
|
70
|
-
setTimeout(() => {
|
|
71
|
-
// 结束会话
|
|
72
|
-
process.exit(0)
|
|
73
|
-
})
|
|
74
|
-
return 'Configuration with this name already exists. Please enter a different name.'
|
|
75
|
-
}
|
|
76
|
-
return true
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
type: 'list',
|
|
81
|
-
name: 'Type',
|
|
82
|
-
message: 'Select AI service type:',
|
|
83
|
-
choices: Object.keys(aiCliConfig).map((key) => {
|
|
84
|
-
return { name: key, value: key }
|
|
85
|
-
}),
|
|
86
|
-
default: 'deepseek',
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
type: 'input',
|
|
90
|
-
name: 'baseUrl',
|
|
91
|
-
message: 'Enter API base URL:',
|
|
92
|
-
when: (answers) => answers.Type !== 'Copilot',
|
|
93
|
-
default: (answers) => {
|
|
94
|
-
return aiCliConfig[answers.Type].baseUrl
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: 'list',
|
|
99
|
-
name: 'model',
|
|
100
|
-
message: 'Select DeepSeek model:',
|
|
101
|
-
when: (answers) => answers.Type === 'DeepSeek',
|
|
102
|
-
choices: aiCliConfig['DeepSeek'].model.list.map((item) => {
|
|
103
|
-
return { name: item, value: item }
|
|
104
|
-
}),
|
|
105
|
-
default: 'deepseek-reasoner',
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
type: 'input',
|
|
109
|
-
name: 'model',
|
|
110
|
-
message: 'Enter model name:',
|
|
111
|
-
when: (answers) => answers.Type !== 'DeepSeek',
|
|
112
|
-
default: (answers) => {
|
|
113
|
-
return aiCliConfig[answers.Type].model.defaultValue
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
type: 'input',
|
|
118
|
-
name: 'deepseekOtherModel',
|
|
119
|
-
message: 'Enter DeepSeek model name:',
|
|
120
|
-
when: (answers) =>
|
|
121
|
-
answers.Type === 'DeepSeek' && answers.model === 'other',
|
|
122
|
-
default: 'deepseek-reasoner',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
type: 'input',
|
|
126
|
-
name: 'apiKey',
|
|
127
|
-
message: 'Enter API key:',
|
|
128
|
-
when: (answers) => answers.Type !== 'Copilot',
|
|
129
|
-
default: (answers) => {
|
|
130
|
-
return aiCliConfig[answers.Type].apiKey
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
type: 'number',
|
|
135
|
-
name: 'temperature',
|
|
136
|
-
message: 'Enter temperature (0-2):',
|
|
137
|
-
default: (answers) => {
|
|
138
|
-
return aiCliConfig[answers.Type].temperature
|
|
139
|
-
},
|
|
140
|
-
validate: (value) =>
|
|
141
|
-
(value >= 0 && value <= 2) || 'Temperature must be between 0 and 2',
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
type: 'number',
|
|
145
|
-
name: 'maxTokens',
|
|
146
|
-
message: 'Enter max tokens (KB):',
|
|
147
|
-
default: (answers) => {
|
|
148
|
-
return aiCliConfig[answers.Type].maxTokens
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
type: 'number',
|
|
153
|
-
name: 'maxContextLength',
|
|
154
|
-
message: 'Enter max context length (KB):',
|
|
155
|
-
default: (answers) => {
|
|
156
|
-
return aiCliConfig[answers.Type].maxContextLength
|
|
157
|
-
},
|
|
158
|
-
validate: (value) => value > 0 || 'Max context length must be greater than 0',
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
type: 'confirm',
|
|
162
|
-
name: 'stream',
|
|
163
|
-
message: 'Enable streaming output:',
|
|
164
|
-
default: (answers) => {
|
|
165
|
-
return aiCliConfig[answers.Type].stream
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
]
|
|
169
|
-
const answers = await aiInquirer.askAny(questions)
|
|
170
|
-
const aiConfig = {
|
|
171
|
-
name: answers.name,
|
|
172
|
-
type: aiCliConfig[answers.Type].type,
|
|
173
|
-
baseUrl: answers.baseUrl || aiCliConfig[answers.Type].baseUrl,
|
|
174
|
-
model: answers.model,
|
|
175
|
-
apiKey: answers.apiKey || aiCliConfig[answers.Type].apiKey,
|
|
176
|
-
temperature: answers.temperature,
|
|
177
|
-
maxTokens: answers.maxTokens,
|
|
178
|
-
maxContextLength: answers.maxContextLength,
|
|
179
|
-
stream: answers.stream,
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (answers.Type === 'Copilot') {
|
|
183
|
-
const loginRes = await githubDeviceLogin({
|
|
184
|
-
configManager,
|
|
185
|
-
targetName: answers.name,
|
|
186
|
-
saveToConfig: false,
|
|
187
|
-
})
|
|
188
|
-
if (!loginRes) {
|
|
189
|
-
aiConsole.logError('Copilot login failed. Configuration was not added.')
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
aiConfig.apiKey = loginRes.accessToken
|
|
193
|
-
aiConfig.githubAuth = loginRes.githubAuth
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return configManager.addAiConfig(aiConfig)
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
configCommand
|
|
200
|
-
.command('ls')
|
|
201
|
-
.description('List all AI configurations')
|
|
202
|
-
.action(async () => {
|
|
203
|
-
configManager.getAiList()
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
configCommand
|
|
207
|
-
.command('use <name>')
|
|
208
|
-
.description('Set the specified AI configuration as current')
|
|
209
|
-
.action((name) => {
|
|
210
|
-
configManager.setCurrentAi(name)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
configCommand
|
|
214
|
-
.command('del <name>')
|
|
215
|
-
.description('Delete the specified AI configuration')
|
|
216
|
-
.action((name) => {
|
|
217
|
-
configManager.delAiConfig(name)
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
configCommand
|
|
221
|
-
.command('view [name]')
|
|
222
|
-
.description('View details of the specified AI configuration')
|
|
223
|
-
.action((name) => {
|
|
224
|
-
configManager.viewAiConfigDetail(name)
|
|
225
|
-
})
|
package/src/cli/ai-memory.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const { program } = require('commander')
|
|
2
|
-
const MemoryManager = require('./MemoryManager.js')
|
|
3
|
-
|
|
4
|
-
const memoryManager = new MemoryManager()
|
|
5
|
-
const extCommand = program
|
|
6
|
-
.command('memory')
|
|
7
|
-
.description('Memory management commands')
|
|
8
|
-
|
|
9
|
-
extCommand
|
|
10
|
-
.command('clear')
|
|
11
|
-
.description('Clear the memory messages for the current directory')
|
|
12
|
-
.action(() => {
|
|
13
|
-
memoryManager.clearMessage()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
extCommand
|
|
17
|
-
.command('dir')
|
|
18
|
-
.description('Open the memory directory')
|
|
19
|
-
.action(() => {
|
|
20
|
-
memoryManager.openDirectory()
|
|
21
|
-
})
|
|
22
|
-
|
package/src/cli/ai-skill.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @Author: Roman 306863030@qq.com
|
|
3
|
-
* @Date: 2026-03-23 15:07:51
|
|
4
|
-
* @LastEditors: Roman 306863030@qq.com
|
|
5
|
-
* @LastEditTime: 2026-04-07 15:21:20
|
|
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.js')
|
|
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 skill 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
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { program } = require('commander')
|
|
3
|
-
const { DeepFishAI } = require('../index.js')
|
|
4
|
-
const { GlobalVariable } = require('./GlobalVariable.js')
|
|
5
|
-
require('./ai-config.js')
|
|
6
|
-
require('./ai-skill.js')
|
|
7
|
-
require('./ai-memory.js')
|
|
8
|
-
require('./ai-auth.js')
|
|
9
|
-
const aiConsole = require('../AgentRobot/BaseAgentRobot/utils/aiConsole.js')
|
|
10
|
-
program
|
|
11
|
-
.version('1.0.0')
|
|
12
|
-
.description(
|
|
13
|
-
'A command-line tool that uses AI to execute commands and manipulate files',
|
|
14
|
-
)
|
|
15
|
-
.option('-p, --prompt <prompt>', 'The prompt to send to the AI')
|
|
16
|
-
.option('-i, --interactive', 'Start interactive mode')
|
|
17
|
-
.arguments('[prompt...]')
|
|
18
|
-
.action((prompt) => {
|
|
19
|
-
program.prompt = Array.isArray(prompt) ? prompt.join(' ') : prompt || ''
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
async function main() {
|
|
23
|
-
try {
|
|
24
|
-
if (
|
|
25
|
-
(program.args &&
|
|
26
|
-
(program.args[0] === 'config' ||
|
|
27
|
-
program.args[0] === 'skill' ||
|
|
28
|
-
program.args[0] === 'auth')) ||
|
|
29
|
-
program.args[0] === 'memory'
|
|
30
|
-
) {
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
const options = program.opts()
|
|
34
|
-
let prompt
|
|
35
|
-
|
|
36
|
-
if (program.prompt) {
|
|
37
|
-
prompt = program.prompt
|
|
38
|
-
} else if (options.prompt) {
|
|
39
|
-
prompt = options.prompt
|
|
40
|
-
} else if (!program.args || program.args.length === 0) {
|
|
41
|
-
options.interactive = true
|
|
42
|
-
} else {
|
|
43
|
-
prompt = program.args.join(' ')
|
|
44
|
-
}
|
|
45
|
-
const configManager = GlobalVariable.configManager
|
|
46
|
-
// 判断当前列表是否为空
|
|
47
|
-
if (configManager.isAiListEmpty()) {
|
|
48
|
-
aiConsole.logError('No AI configurations found.')
|
|
49
|
-
aiConsole.logError("Please use 'ai config add' to add a new AI configuration.")
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
const currentAi = configManager.getCurrentAi()
|
|
53
|
-
// 判断当前是否有设置当前配置
|
|
54
|
-
if (!currentAi || currentAi.trim() === '') {
|
|
55
|
-
aiConsole.logError('No current AI configuration set.')
|
|
56
|
-
aiConsole.logError(
|
|
57
|
-
"Please use 'ai config use <name>' to set a current configuration.",
|
|
58
|
-
)
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
const cli = new DeepFishAI(configManager.getAppConfig())
|
|
62
|
-
if (options.interactive) {
|
|
63
|
-
cli.startInteractive()
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (prompt) {
|
|
68
|
-
cli.run(prompt)
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
aiConsole.logError(error.stack)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
program.parse(process.argv)
|
|
76
|
-
|
|
77
|
-
main()
|
package/src/index.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const MainAgentRobot = require('./AgentRobot/AgentRobotFactory/MainAgentRobot.js')
|
|
2
|
-
const SubAgentRobot = require('./AgentRobot/AgentRobotFactory/SubAgentRobot.js')
|
|
3
|
-
const SubSkillAgentRobot = require('./AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js')
|
|
4
|
-
const readline = require('readline')
|
|
5
|
-
|
|
6
|
-
class DeepFishAI {
|
|
7
|
-
constructor(config) {
|
|
8
|
-
// 启动一个Agent
|
|
9
|
-
this.agentRobot = new MainAgentRobot(config)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 单轮对话
|
|
13
|
-
async run(userPrompt) {
|
|
14
|
-
await this.agentRobot.executeTask(userPrompt)
|
|
15
|
-
}
|
|
16
|
-
// 多轮对话
|
|
17
|
-
startInteractive() {
|
|
18
|
-
const rl = readline.createInterface({
|
|
19
|
-
input: process.stdin,
|
|
20
|
-
output: process.stdout,
|
|
21
|
-
prompt: '> ',
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
console.log('AI CLI Assistant')
|
|
25
|
-
console.log('Type your question or command. Type "exit" to quit.')
|
|
26
|
-
console.log('='.repeat(50))
|
|
27
|
-
rl.prompt()
|
|
28
|
-
|
|
29
|
-
rl.on('line', async (line) => {
|
|
30
|
-
const input = line.trim()
|
|
31
|
-
|
|
32
|
-
if (input.toLowerCase() === 'exit') {
|
|
33
|
-
rl.close()
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
await this.run(input)
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error('Error:', error.message)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log('='.repeat(50))
|
|
44
|
-
rl.prompt()
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
rl.on('close', () => {
|
|
48
|
-
console.log('Goodbye!')
|
|
49
|
-
process.exit(0)
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = { DeepFishAI, MainAgentRobot, SubAgentRobot, SubSkillAgentRobot }
|