agent-resource-management 1.4.0 → 1.5.0
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/dist/main.js +735 -5
- package/package.json +1 -1
- package/src/cmd/agent.ts +331 -2
- package/src/cmd/knowledge.ts +95 -2
- package/src/cmd/skill.ts +115 -2
- package/src/lib/client.ts +87 -0
- package/src/lib/output.ts +35 -0
- package/src/lib/storage.ts +1 -0
- package/src/main.ts +176 -1
- package/test-regression.sh +1 -1
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/AGENT.md +0 -18
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260Loki/346/227/245/345/277/227/346/216/222/346/237/245/346/226/271/346/263/225.md +0 -27
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/344/273/273/345/212/241/350/247/246/345/217/221/345/220/270/346/224/266/345/231/250/344/270/216/345/215/240/344/275/215/350/247/246/345/217/221/345/220/270/346/224/266/345/231/250/344/275/277/347/224/250/345/234/272/346/231/257.md +0 -18
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/345/220/216/347/253/257Swagger/346/216/245/345/217/243/346/226/207/346/241/243.md +0 -22
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/345/275/223/345/211/215/350/277/220/350/241/214/345/256/236/344/276/213/345/217/212/345/256/236/344/276/213/350/277/220/350/241/214/346/227/245/345/277/227/346/216/222/346/237/245.md +0 -39
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/346/216/245/345/217/243/346/216/222/346/237/245/350/203/214/346/231/257/347/237/245/350/257/206.md +0 -49
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/350/264/247/350/275/275/347/224/237/345/221/275/345/221/250/346/234/237/346/237/245/350/257/242/346/265/201/347/250/213.md +0 -165
- package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//345/244/251/350/275/246/350/260/203/345/272/246/347/263/273/347/273/237/351/207/215/347/273/204/346/216/245/345/217/243/350/260/203/347/224/250/344/270/216/346/227/245/345/277/227/345/210/206/346/236/220/346/226/271/346/263/225.md +0 -137
package/package.json
CHANGED
package/src/cmd/agent.ts
CHANGED
|
@@ -1,14 +1,289 @@
|
|
|
1
1
|
import { ApiClient } from '../lib/client';
|
|
2
2
|
import { loadConfig } from '../lib/storage';
|
|
3
3
|
import { formatAgent, formatAgentDetail, success, error, info } from '../lib/formatter';
|
|
4
|
+
import { shouldOutputJson, outputJson } from '../lib/output';
|
|
4
5
|
import { writeFileSync, existsSync } from 'fs';
|
|
5
6
|
import { join } from 'path';
|
|
6
7
|
import { execSync } from 'child_process';
|
|
7
8
|
import { mkdtempSync, rmSync } from 'fs';
|
|
8
9
|
|
|
10
|
+
function getAgentIdentifier(identifier: string): { id: string; name: string } {
|
|
11
|
+
if (identifier.includes('-')) {
|
|
12
|
+
return { id: identifier, name: identifier };
|
|
13
|
+
}
|
|
14
|
+
return { id: identifier, name: identifier };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function createAgent(
|
|
18
|
+
name: string,
|
|
19
|
+
options: {
|
|
20
|
+
description?: string;
|
|
21
|
+
prompt?: string;
|
|
22
|
+
avatar?: string;
|
|
23
|
+
skills?: string[];
|
|
24
|
+
knowledges?: string[];
|
|
25
|
+
skillConfigs?: string[];
|
|
26
|
+
knowledgeConfigs?: string[];
|
|
27
|
+
} = {}
|
|
28
|
+
): Promise<void> {
|
|
29
|
+
const config = loadConfig();
|
|
30
|
+
if (!config?.token) {
|
|
31
|
+
if (shouldOutputJson()) {
|
|
32
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
error('未登录,请先运行 arm login');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const client = new ApiClient(config.serverUrl, config.token);
|
|
40
|
+
try {
|
|
41
|
+
const skills = options.skills?.map((skillId, index) => ({
|
|
42
|
+
skillId,
|
|
43
|
+
config: options.skillConfigs?.[index] ? JSON.parse(options.skillConfigs[index]) : undefined,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
const knowledges = options.knowledges?.map((knowledgeId, index) => ({
|
|
47
|
+
knowledgeId,
|
|
48
|
+
retrievalConfig: options.knowledgeConfigs?.[index] ? JSON.parse(options.knowledgeConfigs[index]) : undefined,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
const result = await client.createAgent({
|
|
52
|
+
name,
|
|
53
|
+
description: options.description,
|
|
54
|
+
prompt: options.prompt,
|
|
55
|
+
avatar: options.avatar,
|
|
56
|
+
skills,
|
|
57
|
+
knowledges,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (shouldOutputJson()) {
|
|
61
|
+
outputJson({ success: true, data: result });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
success(`Agent "${name}" 创建成功 (ID: ${result.id})`);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (shouldOutputJson()) {
|
|
67
|
+
outputJson({ success: false, error: { code: 'CREATE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
error(`创建失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function updateAgent(
|
|
76
|
+
id: string,
|
|
77
|
+
options: {
|
|
78
|
+
name?: string;
|
|
79
|
+
description?: string;
|
|
80
|
+
prompt?: string;
|
|
81
|
+
avatar?: string;
|
|
82
|
+
status?: 'active' | 'draft';
|
|
83
|
+
} = {}
|
|
84
|
+
): Promise<void> {
|
|
85
|
+
const config = loadConfig();
|
|
86
|
+
if (!config?.token) {
|
|
87
|
+
if (shouldOutputJson()) {
|
|
88
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
error('未登录,请先运行 arm login');
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const client = new ApiClient(config.serverUrl, config.token);
|
|
96
|
+
try {
|
|
97
|
+
const updateData: Partial<{
|
|
98
|
+
name: string;
|
|
99
|
+
description: string;
|
|
100
|
+
prompt: string;
|
|
101
|
+
avatar: string;
|
|
102
|
+
status: 'active' | 'draft';
|
|
103
|
+
}> = {};
|
|
104
|
+
|
|
105
|
+
if (options.name !== undefined) updateData.name = options.name;
|
|
106
|
+
if (options.description !== undefined) updateData.description = options.description;
|
|
107
|
+
if (options.prompt !== undefined) updateData.prompt = options.prompt;
|
|
108
|
+
if (options.avatar !== undefined) updateData.avatar = options.avatar;
|
|
109
|
+
if (options.status !== undefined) updateData.status = options.status;
|
|
110
|
+
|
|
111
|
+
const result = await client.updateAgent(id, updateData);
|
|
112
|
+
|
|
113
|
+
if (shouldOutputJson()) {
|
|
114
|
+
outputJson({ success: true, data: result });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
success(`Agent "${id}" 更新成功`);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (shouldOutputJson()) {
|
|
120
|
+
outputJson({ success: false, error: { code: 'UPDATE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
error(`更新失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function deleteAgent(id: string): Promise<void> {
|
|
129
|
+
const config = loadConfig();
|
|
130
|
+
if (!config?.token) {
|
|
131
|
+
if (shouldOutputJson()) {
|
|
132
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
error('未登录,请先运行 arm login');
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const client = new ApiClient(config.serverUrl, config.token);
|
|
140
|
+
try {
|
|
141
|
+
await client.deleteAgent(id);
|
|
142
|
+
|
|
143
|
+
if (shouldOutputJson()) {
|
|
144
|
+
outputJson({ success: true, data: { id } });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
success(`Agent "${id}" 删除成功`);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
if (shouldOutputJson()) {
|
|
150
|
+
outputJson({ success: false, error: { code: 'DELETE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
error(`删除失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export async function bindSkill(id: string, skillId: string, config?: string): Promise<void> {
|
|
159
|
+
const configStore = loadConfig();
|
|
160
|
+
if (!configStore?.token) {
|
|
161
|
+
if (shouldOutputJson()) {
|
|
162
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
error('未登录,请先运行 arm login');
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const client = new ApiClient(configStore.serverUrl, configStore.token);
|
|
170
|
+
try {
|
|
171
|
+
const parsedConfig = config ? JSON.parse(config) : undefined;
|
|
172
|
+
await client.bindSkillToAgent(id, skillId, parsedConfig);
|
|
173
|
+
|
|
174
|
+
if (shouldOutputJson()) {
|
|
175
|
+
outputJson({ success: true, data: { agentId: id, skillId, config: parsedConfig } });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
success(`Skill "${skillId}" 已绑定到 Agent "${id}"`);
|
|
179
|
+
} catch (err) {
|
|
180
|
+
if (shouldOutputJson()) {
|
|
181
|
+
outputJson({ success: false, error: { code: 'BIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
error(`绑定失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function unbindSkill(id: string, skillId: string): Promise<void> {
|
|
190
|
+
const config = loadConfig();
|
|
191
|
+
if (!config?.token) {
|
|
192
|
+
if (shouldOutputJson()) {
|
|
193
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
error('未登录,请先运行 arm login');
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const client = new ApiClient(config.serverUrl, config.token);
|
|
201
|
+
try {
|
|
202
|
+
await client.unbindSkillFromAgent(id, skillId);
|
|
203
|
+
|
|
204
|
+
if (shouldOutputJson()) {
|
|
205
|
+
outputJson({ success: true, data: { agentId: id, skillId } });
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
success(`Skill "${skillId}" 已从 Agent "${id}" 解绑`);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
if (shouldOutputJson()) {
|
|
211
|
+
outputJson({ success: false, error: { code: 'UNBIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
error(`解绑失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export async function bindKnowledge(id: string, knowledgeId: string, retrievalConfig?: string): Promise<void> {
|
|
220
|
+
const configStore = loadConfig();
|
|
221
|
+
if (!configStore?.token) {
|
|
222
|
+
if (shouldOutputJson()) {
|
|
223
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
error('未登录,请先运行 arm login');
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const client = new ApiClient(configStore.serverUrl, configStore.token);
|
|
231
|
+
try {
|
|
232
|
+
const parsedConfig = retrievalConfig ? JSON.parse(retrievalConfig) : undefined;
|
|
233
|
+
await client.bindKnowledgeToAgent(id, knowledgeId, parsedConfig);
|
|
234
|
+
|
|
235
|
+
if (shouldOutputJson()) {
|
|
236
|
+
outputJson({ success: true, data: { agentId: id, knowledgeId, retrievalConfig: parsedConfig } });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
success(`Knowledge "${knowledgeId}" 已绑定到 Agent "${id}"`);
|
|
240
|
+
} catch (err) {
|
|
241
|
+
if (shouldOutputJson()) {
|
|
242
|
+
outputJson({ success: false, error: { code: 'BIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
error(`绑定失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export async function unbindKnowledge(id: string, knowledgeId: string): Promise<void> {
|
|
251
|
+
const config = loadConfig();
|
|
252
|
+
if (!config?.token) {
|
|
253
|
+
if (shouldOutputJson()) {
|
|
254
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
error('未登录,请先运行 arm login');
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const client = new ApiClient(config.serverUrl, config.token);
|
|
262
|
+
try {
|
|
263
|
+
await client.unbindKnowledgeFromAgent(id, knowledgeId);
|
|
264
|
+
|
|
265
|
+
if (shouldOutputJson()) {
|
|
266
|
+
outputJson({ success: true, data: { agentId: id, knowledgeId } });
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
success(`Knowledge "${knowledgeId}" 已从 Agent "${id}" 解绑`);
|
|
270
|
+
} catch (err) {
|
|
271
|
+
if (shouldOutputJson()) {
|
|
272
|
+
outputJson({ success: false, error: { code: 'UNBIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
error(`解绑失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
9
280
|
export async function listAgents(): Promise<void> {
|
|
10
281
|
const config = loadConfig();
|
|
11
282
|
if (!config?.token) {
|
|
283
|
+
if (shouldOutputJson()) {
|
|
284
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
12
287
|
error('未登录,请先运行 arm login');
|
|
13
288
|
process.exit(1);
|
|
14
289
|
}
|
|
@@ -16,6 +291,10 @@ export async function listAgents(): Promise<void> {
|
|
|
16
291
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
17
292
|
try {
|
|
18
293
|
const result = await client.listAgents();
|
|
294
|
+
if (shouldOutputJson()) {
|
|
295
|
+
outputJson({ success: true, data: result });
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
19
298
|
if (result.agents.length === 0) {
|
|
20
299
|
info('暂无 Agent');
|
|
21
300
|
return;
|
|
@@ -26,6 +305,10 @@ export async function listAgents(): Promise<void> {
|
|
|
26
305
|
console.log('');
|
|
27
306
|
}
|
|
28
307
|
} catch (err) {
|
|
308
|
+
if (shouldOutputJson()) {
|
|
309
|
+
outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
29
312
|
error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
30
313
|
process.exit(1);
|
|
31
314
|
}
|
|
@@ -34,6 +317,10 @@ export async function listAgents(): Promise<void> {
|
|
|
34
317
|
export async function searchAgents(keyword: string): Promise<void> {
|
|
35
318
|
const config = loadConfig();
|
|
36
319
|
if (!config?.token) {
|
|
320
|
+
if (shouldOutputJson()) {
|
|
321
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
322
|
+
process.exit(1);
|
|
323
|
+
}
|
|
37
324
|
error('未登录,请先运行 arm login');
|
|
38
325
|
process.exit(1);
|
|
39
326
|
}
|
|
@@ -41,6 +328,10 @@ export async function searchAgents(keyword: string): Promise<void> {
|
|
|
41
328
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
42
329
|
try {
|
|
43
330
|
const result = await client.listAgents(keyword);
|
|
331
|
+
if (shouldOutputJson()) {
|
|
332
|
+
outputJson({ success: true, data: result });
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
44
335
|
if (result.agents.length === 0) {
|
|
45
336
|
info(`没有找到包含 "${keyword}" 的 Agent`);
|
|
46
337
|
return;
|
|
@@ -51,6 +342,10 @@ export async function searchAgents(keyword: string): Promise<void> {
|
|
|
51
342
|
console.log('');
|
|
52
343
|
}
|
|
53
344
|
} catch (err) {
|
|
345
|
+
if (shouldOutputJson()) {
|
|
346
|
+
outputJson({ success: false, error: { code: 'SEARCH_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
54
349
|
error(`搜索失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
55
350
|
process.exit(1);
|
|
56
351
|
}
|
|
@@ -59,6 +354,10 @@ export async function searchAgents(keyword: string): Promise<void> {
|
|
|
59
354
|
export async function infoAgent(name: string): Promise<void> {
|
|
60
355
|
const config = loadConfig();
|
|
61
356
|
if (!config?.token) {
|
|
357
|
+
if (shouldOutputJson()) {
|
|
358
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
62
361
|
error('未登录,请先运行 arm login');
|
|
63
362
|
process.exit(1);
|
|
64
363
|
}
|
|
@@ -68,6 +367,10 @@ export async function infoAgent(name: string): Promise<void> {
|
|
|
68
367
|
const result = await client.listAgents(name);
|
|
69
368
|
const agent = result.agents.find((a) => a.name === name);
|
|
70
369
|
if (!agent) {
|
|
370
|
+
if (shouldOutputJson()) {
|
|
371
|
+
outputJson({ success: false, error: { code: 'NOT_FOUND', message: `Agent "${name}" 不存在` } });
|
|
372
|
+
process.exit(1);
|
|
373
|
+
}
|
|
71
374
|
error(`Agent "${name}" 不存在`);
|
|
72
375
|
process.exit(1);
|
|
73
376
|
}
|
|
@@ -86,8 +389,16 @@ export async function infoAgent(name: string): Promise<void> {
|
|
|
86
389
|
fullAgent.knowledges = await Promise.all(knowledgeNamePromises);
|
|
87
390
|
}
|
|
88
391
|
|
|
392
|
+
if (shouldOutputJson()) {
|
|
393
|
+
outputJson({ success: true, data: fullAgent });
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
89
396
|
console.log(formatAgentDetail(fullAgent));
|
|
90
397
|
} catch (err) {
|
|
398
|
+
if (shouldOutputJson()) {
|
|
399
|
+
outputJson({ success: false, error: { code: 'INFO_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
91
402
|
error(`获取详情失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
92
403
|
process.exit(1);
|
|
93
404
|
}
|
|
@@ -96,6 +407,10 @@ export async function infoAgent(name: string): Promise<void> {
|
|
|
96
407
|
export async function downloadAgent(name: string, outputDir?: string): Promise<void> {
|
|
97
408
|
const config = loadConfig();
|
|
98
409
|
if (!config?.token) {
|
|
410
|
+
if (shouldOutputJson()) {
|
|
411
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
99
414
|
error('未登录,请先运行 arm login');
|
|
100
415
|
process.exit(1);
|
|
101
416
|
}
|
|
@@ -105,11 +420,17 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
|
|
|
105
420
|
const result = await client.listAgents(name);
|
|
106
421
|
const agent = result.agents.find((a) => a.name === name);
|
|
107
422
|
if (!agent) {
|
|
423
|
+
if (shouldOutputJson()) {
|
|
424
|
+
outputJson({ success: false, error: { code: 'NOT_FOUND', message: `Agent "${name}" 不存在` } });
|
|
425
|
+
process.exit(1);
|
|
426
|
+
}
|
|
108
427
|
error(`Agent "${name}" 不存在`);
|
|
109
428
|
process.exit(1);
|
|
110
429
|
}
|
|
111
430
|
|
|
112
|
-
|
|
431
|
+
if (shouldOutputJson()) {
|
|
432
|
+
info(`正在下载 ${name}...`);
|
|
433
|
+
}
|
|
113
434
|
const { buffer, version } = await client.downloadAgent(agent.id);
|
|
114
435
|
|
|
115
436
|
const tempDir = mkdtempSync('/tmp/agent-download-');
|
|
@@ -119,7 +440,7 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
|
|
|
119
440
|
const targetDir = join(outputDir || '.', name);
|
|
120
441
|
execSync(`mkdir -p "${targetDir}"`, { stdio: 'pipe' });
|
|
121
442
|
execSync(`unzip -q "${zipPath}" -d "${tempDir}"`, { stdio: 'pipe' });
|
|
122
|
-
|
|
443
|
+
|
|
123
444
|
const contentDir = join(tempDir, 'agent-content');
|
|
124
445
|
if (existsSync(contentDir)) {
|
|
125
446
|
execSync(`cp -r "${contentDir}"/* "${targetDir}/"`, { stdio: 'pipe' });
|
|
@@ -129,8 +450,16 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
|
|
|
129
450
|
|
|
130
451
|
rmSync(tempDir, { recursive: true, force: true });
|
|
131
452
|
|
|
453
|
+
if (shouldOutputJson()) {
|
|
454
|
+
outputJson({ success: true, data: { path: targetDir, version } });
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
132
457
|
success(`已下载到 ${targetDir} (版本: ${version})`);
|
|
133
458
|
} catch (err) {
|
|
459
|
+
if (shouldOutputJson()) {
|
|
460
|
+
outputJson({ success: false, error: { code: 'DOWNLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
461
|
+
process.exit(1);
|
|
462
|
+
}
|
|
134
463
|
error(`下载失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
135
464
|
process.exit(1);
|
|
136
465
|
}
|
package/src/cmd/knowledge.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ApiClient } from '../lib/client';
|
|
2
2
|
import { loadConfig } from '../lib/storage';
|
|
3
3
|
import { formatKnowledge, formatKnowledgeDetail, success, error, info } from '../lib/formatter';
|
|
4
|
+
import { shouldOutputJson, outputJson } from '../lib/output';
|
|
4
5
|
import { writeFileSync, existsSync, statSync } from 'fs';
|
|
5
6
|
import { join, basename, dirname } from 'path';
|
|
6
7
|
import { execSync } from 'child_process';
|
|
@@ -9,6 +10,10 @@ import { mkdtempSync, rmSync } from 'fs';
|
|
|
9
10
|
export async function listKnowledge(): Promise<void> {
|
|
10
11
|
const config = loadConfig();
|
|
11
12
|
if (!config?.token) {
|
|
13
|
+
if (shouldOutputJson()) {
|
|
14
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
12
17
|
error('未登录,请先运行 arm login');
|
|
13
18
|
process.exit(1);
|
|
14
19
|
}
|
|
@@ -16,6 +21,10 @@ export async function listKnowledge(): Promise<void> {
|
|
|
16
21
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
17
22
|
try {
|
|
18
23
|
const result = await client.listKnowledge();
|
|
24
|
+
if (shouldOutputJson()) {
|
|
25
|
+
outputJson({ success: true, data: result });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
19
28
|
if (result.knowledges.length === 0) {
|
|
20
29
|
info('暂无 Knowledge');
|
|
21
30
|
return;
|
|
@@ -26,6 +35,10 @@ export async function listKnowledge(): Promise<void> {
|
|
|
26
35
|
console.log('');
|
|
27
36
|
}
|
|
28
37
|
} catch (err) {
|
|
38
|
+
if (shouldOutputJson()) {
|
|
39
|
+
outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
29
42
|
error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
30
43
|
process.exit(1);
|
|
31
44
|
}
|
|
@@ -34,6 +47,10 @@ export async function listKnowledge(): Promise<void> {
|
|
|
34
47
|
export async function searchKnowledge(keyword: string): Promise<void> {
|
|
35
48
|
const config = loadConfig();
|
|
36
49
|
if (!config?.token) {
|
|
50
|
+
if (shouldOutputJson()) {
|
|
51
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
37
54
|
error('未登录,请先运行 arm login');
|
|
38
55
|
process.exit(1);
|
|
39
56
|
}
|
|
@@ -41,6 +58,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
|
|
|
41
58
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
42
59
|
try {
|
|
43
60
|
const result = await client.listKnowledge(keyword);
|
|
61
|
+
if (shouldOutputJson()) {
|
|
62
|
+
outputJson({ success: true, data: result });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
44
65
|
if (result.knowledges.length === 0) {
|
|
45
66
|
info(`没有找到包含 "${keyword}" 的 Knowledge`);
|
|
46
67
|
return;
|
|
@@ -51,6 +72,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
|
|
|
51
72
|
console.log('');
|
|
52
73
|
}
|
|
53
74
|
} catch (err) {
|
|
75
|
+
if (shouldOutputJson()) {
|
|
76
|
+
outputJson({ success: false, error: { code: 'SEARCH_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
54
79
|
error(`搜索失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
55
80
|
process.exit(1);
|
|
56
81
|
}
|
|
@@ -59,6 +84,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
|
|
|
59
84
|
export async function infoKnowledge(name: string): Promise<void> {
|
|
60
85
|
const config = loadConfig();
|
|
61
86
|
if (!config?.token) {
|
|
87
|
+
if (shouldOutputJson()) {
|
|
88
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
62
91
|
error('未登录,请先运行 arm login');
|
|
63
92
|
process.exit(1);
|
|
64
93
|
}
|
|
@@ -66,8 +95,16 @@ export async function infoKnowledge(name: string): Promise<void> {
|
|
|
66
95
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
67
96
|
try {
|
|
68
97
|
const knowledge = await client.getKnowledge(name);
|
|
98
|
+
if (shouldOutputJson()) {
|
|
99
|
+
outputJson({ success: true, data: knowledge });
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
69
102
|
console.log(formatKnowledgeDetail(knowledge));
|
|
70
103
|
} catch (err) {
|
|
104
|
+
if (shouldOutputJson()) {
|
|
105
|
+
outputJson({ success: false, error: { code: 'INFO_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
71
108
|
error(`获取详情失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
72
109
|
process.exit(1);
|
|
73
110
|
}
|
|
@@ -76,18 +113,32 @@ export async function infoKnowledge(name: string): Promise<void> {
|
|
|
76
113
|
export async function downloadKnowledge(name: string, outputDir?: string): Promise<void> {
|
|
77
114
|
const config = loadConfig();
|
|
78
115
|
if (!config?.token) {
|
|
116
|
+
if (shouldOutputJson()) {
|
|
117
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
79
120
|
error('未登录,请先运行 arm login');
|
|
80
121
|
process.exit(1);
|
|
81
122
|
}
|
|
82
123
|
|
|
83
124
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
84
125
|
try {
|
|
85
|
-
|
|
126
|
+
if (shouldOutputJson()) {
|
|
127
|
+
info(`正在下载 ${name}...`);
|
|
128
|
+
}
|
|
86
129
|
const buffer = await client.downloadKnowledge(name);
|
|
87
130
|
const outputPath = join(outputDir || '.', `${name}.zip`);
|
|
88
131
|
writeFileSync(outputPath, Buffer.from(buffer));
|
|
132
|
+
if (shouldOutputJson()) {
|
|
133
|
+
outputJson({ success: true, data: { path: outputPath } });
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
89
136
|
success(`已下载到 ${outputPath}`);
|
|
90
137
|
} catch (err) {
|
|
138
|
+
if (shouldOutputJson()) {
|
|
139
|
+
outputJson({ success: false, error: { code: 'DOWNLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
91
142
|
error(`下载失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
92
143
|
process.exit(1);
|
|
93
144
|
}
|
|
@@ -96,11 +147,19 @@ export async function downloadKnowledge(name: string, outputDir?: string): Promi
|
|
|
96
147
|
export async function uploadKnowledge(filePath: string): Promise<void> {
|
|
97
148
|
const config = loadConfig();
|
|
98
149
|
if (!config?.token) {
|
|
150
|
+
if (shouldOutputJson()) {
|
|
151
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
99
154
|
error('未登录,请先运行 arm login');
|
|
100
155
|
process.exit(1);
|
|
101
156
|
}
|
|
102
157
|
|
|
103
158
|
if (!existsSync(filePath)) {
|
|
159
|
+
if (shouldOutputJson()) {
|
|
160
|
+
outputJson({ success: false, error: { code: 'FILE_NOT_FOUND', message: `上传失败: 目录不存在: ${filePath}` } });
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
104
163
|
error(`上传失败: 目录不存在: ${filePath}`);
|
|
105
164
|
process.exit(1);
|
|
106
165
|
}
|
|
@@ -117,10 +176,20 @@ export async function uploadKnowledge(filePath: string): Promise<void> {
|
|
|
117
176
|
}
|
|
118
177
|
|
|
119
178
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
120
|
-
|
|
179
|
+
if (shouldOutputJson()) {
|
|
180
|
+
info(`正在上传 ${filePath}...`);
|
|
181
|
+
}
|
|
121
182
|
const knowledge = await client.uploadKnowledge(zipPath);
|
|
183
|
+
if (shouldOutputJson()) {
|
|
184
|
+
outputJson({ success: true, data: knowledge });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
122
187
|
success(`上传成功! Knowledge: ${knowledge.name}`);
|
|
123
188
|
} catch (err) {
|
|
189
|
+
if (shouldOutputJson()) {
|
|
190
|
+
outputJson({ success: false, error: { code: 'UPLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
124
193
|
error(`上传失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
125
194
|
process.exit(1);
|
|
126
195
|
} finally {
|
|
@@ -131,6 +200,10 @@ export async function uploadKnowledge(filePath: string): Promise<void> {
|
|
|
131
200
|
export async function myKnowledge(): Promise<void> {
|
|
132
201
|
const config = loadConfig();
|
|
133
202
|
if (!config?.token) {
|
|
203
|
+
if (shouldOutputJson()) {
|
|
204
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
134
207
|
error('未登录,请先运行 arm login');
|
|
135
208
|
process.exit(1);
|
|
136
209
|
}
|
|
@@ -138,6 +211,10 @@ export async function myKnowledge(): Promise<void> {
|
|
|
138
211
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
139
212
|
try {
|
|
140
213
|
const knowledges = await client.getMyKnowledge();
|
|
214
|
+
if (shouldOutputJson()) {
|
|
215
|
+
outputJson({ success: true, data: knowledges });
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
141
218
|
if (knowledges.length === 0) {
|
|
142
219
|
info('您还没有发布任何 Knowledge');
|
|
143
220
|
return;
|
|
@@ -148,6 +225,10 @@ export async function myKnowledge(): Promise<void> {
|
|
|
148
225
|
console.log('');
|
|
149
226
|
}
|
|
150
227
|
} catch (err) {
|
|
228
|
+
if (shouldOutputJson()) {
|
|
229
|
+
outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
151
232
|
error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
152
233
|
process.exit(1);
|
|
153
234
|
}
|
|
@@ -156,6 +237,10 @@ export async function myKnowledge(): Promise<void> {
|
|
|
156
237
|
export async function deleteKnowledge(name: string): Promise<void> {
|
|
157
238
|
const config = loadConfig();
|
|
158
239
|
if (!config?.token) {
|
|
240
|
+
if (shouldOutputJson()) {
|
|
241
|
+
outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
159
244
|
error('未登录,请先运行 arm login');
|
|
160
245
|
process.exit(1);
|
|
161
246
|
}
|
|
@@ -163,8 +248,16 @@ export async function deleteKnowledge(name: string): Promise<void> {
|
|
|
163
248
|
const client = new ApiClient(config.serverUrl, config.token);
|
|
164
249
|
try {
|
|
165
250
|
await client.deleteKnowledge(name);
|
|
251
|
+
if (shouldOutputJson()) {
|
|
252
|
+
outputJson({ success: true, data: { name } });
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
166
255
|
success(`已删除 ${name}`);
|
|
167
256
|
} catch (err) {
|
|
257
|
+
if (shouldOutputJson()) {
|
|
258
|
+
outputJson({ success: false, error: { code: 'DELETE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
168
261
|
error(`删除失败: ${err instanceof Error ? err.message : '未知错误'}`);
|
|
169
262
|
process.exit(1);
|
|
170
263
|
}
|