plazbot-cli 0.3.6 → 0.4.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.
Files changed (117) hide show
  1. package/README.md +38 -2
  2. package/dist/commands/agent/export.js +25 -2
  3. package/dist/commands/auth/browser-login.js +121 -0
  4. package/dist/commands/auth/index.js +5 -1
  5. package/dist/commands/auth/login.js +1 -3
  6. package/dist/commands/auth/logout.js +4 -3
  7. package/dist/commands/auth/status.js +8 -5
  8. package/dist/commands/auth/workspace.js +73 -0
  9. package/dist/commands/whatsapp/connect-flow.js +137 -0
  10. package/dist/commands/whatsapp/connect.js +26 -160
  11. package/dist/commands/whatsapp/index.js +4 -0
  12. package/dist/commands/whatsapp/setup.js +242 -0
  13. package/dist/studio/components/App.js +1 -1
  14. package/dist/studio/runOneShot.js +2 -2
  15. package/dist/studio/runRepl.js +1 -1
  16. package/dist/utils/agent-errors.js +2 -2
  17. package/dist/utils/banner.js +10 -9
  18. package/dist/utils/credentials.js +31 -3
  19. package/dist/utils/open-browser.js +17 -0
  20. package/package.json +14 -6
  21. package/.claude/settings.local.json +0 -15
  22. package/CLAUDE.md +0 -121
  23. package/agent.config.json +0 -21
  24. package/dist/studio/components/AgentPanel.js +0 -35
  25. package/dist/studio/render/json.js +0 -16
  26. package/dist/studio/whatsapp/api.js +0 -63
  27. package/dist/studio/whatsapp/polling.js +0 -77
  28. package/dist/studio/whatsapp/types.js +0 -31
  29. package/src/cli.ts +0 -57
  30. package/src/commands/agent/ai-config.ts +0 -164
  31. package/src/commands/agent/chat.ts +0 -225
  32. package/src/commands/agent/copy.ts +0 -46
  33. package/src/commands/agent/create.ts +0 -103
  34. package/src/commands/agent/delete.ts +0 -71
  35. package/src/commands/agent/enable-widget.ts +0 -67
  36. package/src/commands/agent/export.ts +0 -408
  37. package/src/commands/agent/files.ts +0 -171
  38. package/src/commands/agent/get.ts +0 -233
  39. package/src/commands/agent/index.ts +0 -55
  40. package/src/commands/agent/list.ts +0 -58
  41. package/src/commands/agent/monitor.ts +0 -375
  42. package/src/commands/agent/on-message.ts +0 -82
  43. package/src/commands/agent/set.ts +0 -149
  44. package/src/commands/agent/templates.ts +0 -892
  45. package/src/commands/agent/tools.ts +0 -168
  46. package/src/commands/agent/update.ts +0 -61
  47. package/src/commands/agent/validate.ts +0 -135
  48. package/src/commands/agent/wizard.ts +0 -756
  49. package/src/commands/auth/index.ts +0 -10
  50. package/src/commands/auth/login.ts +0 -72
  51. package/src/commands/auth/logout.ts +0 -28
  52. package/src/commands/auth/status.ts +0 -28
  53. package/src/commands/portal/add-agent.ts +0 -66
  54. package/src/commands/portal/add-link.ts +0 -47
  55. package/src/commands/portal/clear-links.ts +0 -33
  56. package/src/commands/portal/create.ts +0 -58
  57. package/src/commands/portal/delete.ts +0 -70
  58. package/src/commands/portal/get.ts +0 -77
  59. package/src/commands/portal/index.ts +0 -32
  60. package/src/commands/portal/list.ts +0 -79
  61. package/src/commands/portal/update.ts +0 -93
  62. package/src/commands/whatsapp/broadcast.ts +0 -110
  63. package/src/commands/whatsapp/channels.ts +0 -109
  64. package/src/commands/whatsapp/chat.ts +0 -85
  65. package/src/commands/whatsapp/connect.ts +0 -220
  66. package/src/commands/whatsapp/delete-webhook.ts +0 -43
  67. package/src/commands/whatsapp/index.ts +0 -37
  68. package/src/commands/whatsapp/register-webhook.ts +0 -47
  69. package/src/commands/whatsapp/send-template.ts +0 -94
  70. package/src/commands/whatsapp/send.ts +0 -55
  71. package/src/commands/whatsapp/widget.ts +0 -75
  72. package/src/commands/workers/deploy.ts +0 -156
  73. package/src/commands/workers/index.ts +0 -30
  74. package/src/commands/workers/list.ts +0 -105
  75. package/src/commands/workers/logs.ts +0 -99
  76. package/src/commands/workers/remove.ts +0 -103
  77. package/src/commands/workers/secret.ts +0 -191
  78. package/src/commands/workers/test.ts +0 -145
  79. package/src/schemas/agent.config.schema.json +0 -569
  80. package/src/studio/api/sseClient.ts +0 -91
  81. package/src/studio/api/studioApi.ts +0 -27
  82. package/src/studio/api/types.ts +0 -96
  83. package/src/studio/components/App.tsx +0 -274
  84. package/src/studio/components/ChatLog.tsx +0 -121
  85. package/src/studio/components/ConnectCard.tsx +0 -171
  86. package/src/studio/components/Footer.tsx +0 -38
  87. package/src/studio/components/Header.tsx +0 -39
  88. package/src/studio/components/Input.tsx +0 -176
  89. package/src/studio/components/Message.tsx +0 -87
  90. package/src/studio/components/Suggestions.tsx +0 -26
  91. package/src/studio/components/ToolCall.tsx +0 -58
  92. package/src/studio/connect/api.ts +0 -98
  93. package/src/studio/connect/polling.ts +0 -94
  94. package/src/studio/connect/types.ts +0 -141
  95. package/src/studio/index.ts +0 -58
  96. package/src/studio/render/markdown.ts +0 -93
  97. package/src/studio/render/steps.ts +0 -57
  98. package/src/studio/runOneShot.ts +0 -114
  99. package/src/studio/runRepl.tsx +0 -82
  100. package/src/studio/slash/handlers.ts +0 -226
  101. package/src/studio/slash/parser.ts +0 -41
  102. package/src/studio/slash/registry.ts +0 -54
  103. package/src/studio/state/store.ts +0 -279
  104. package/src/types/agent.ts +0 -63
  105. package/src/types/auth.ts +0 -9
  106. package/src/types/common.ts +0 -10
  107. package/src/types/message.ts +0 -34
  108. package/src/types/portal.ts +0 -56
  109. package/src/types/workers.ts +0 -86
  110. package/src/utils/agent-errors.ts +0 -67
  111. package/src/utils/api.ts +0 -35
  112. package/src/utils/banner.ts +0 -99
  113. package/src/utils/credentials.ts +0 -38
  114. package/src/utils/help.ts +0 -51
  115. package/src/utils/logger.ts +0 -40
  116. package/src/utils/ui.ts +0 -109
  117. package/tsconfig.json +0 -18
@@ -1,408 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { createSpinner } from '../../utils/ui.js';
7
- import chalk from 'chalk';
8
- import fs from 'fs';
9
- import path from 'path';
10
- import inquirer from 'inquirer';
11
-
12
- // Campos validos segun el schema de agentValidation.ts (additionalProperties: false)
13
- const VALID_AGENT_FIELDS = new Set([
14
- 'name', 'description', 'prompt', 'zone', 'timezone', 'buffer',
15
- 'color', 'question', 'enable', 'tags', 'showInChat',
16
- 'instructions', 'person', 'fallbacks', 'rules',
17
- 'examples', 'channels', 'services', 'actions',
18
- 'useToolCalling', 'customAIConfig', 'aiProviders',
19
- 'responseMode', 'batchWaitSeconds',
20
- 'enableWidget', 'enableWhatsappWidget', 'urlWhatsappWidget',
21
- 'formWidget', 'darkWidget', 'nameWidget', 'initialShowWidget',
22
- 'fUseAutomationFlowWidget', 'iconWidget',
23
- 'enableAvatarWidget', 'avatarGender', 'avatarVoiceId', 'avatarLanguage',
24
- ]);
25
-
26
- // Campos que el schema espera como string (no pueden ser null)
27
- const STRING_FIELDS = new Set([
28
- 'name', 'description', 'prompt', 'zone', 'timezone', 'color',
29
- 'question', 'responseMode', 'iconWidget', 'avatarGender',
30
- 'avatarVoiceId', 'avatarLanguage', 'urlWhatsappWidget', 'nameWidget',
31
- ]);
32
-
33
- // Campos que el schema espera como array (no pueden ser null)
34
- const ARRAY_FIELDS = new Set([
35
- 'tags', 'examples', 'channels', 'services', 'actions', 'aiProviders',
36
- ]);
37
-
38
- function cleanRequiredFields(fields: any): any[] {
39
- if (!fields || !Array.isArray(fields)) return [];
40
- return fields.map((f: any) => {
41
- const clean: any = {};
42
- if (f.name) clean.name = f.name;
43
- if (f.description) clean.description = f.description;
44
- if (f.promptHint) clean.promptHint = f.promptHint;
45
- if (f.type) clean.type = f.type;
46
- // properties debe ser array o no existir
47
- if (f.properties && Array.isArray(f.properties)) {
48
- clean.properties = f.properties.map((p: any) => ({
49
- name: p.name || '',
50
- type: p.type || 'string',
51
- }));
52
- }
53
- // Si properties es null o no es array, no incluirlo
54
- return clean;
55
- });
56
- }
57
-
58
- function cleanServices(services: any): any[] {
59
- if (!services || !Array.isArray(services)) return [];
60
- return services.map((svc: any) => {
61
- const clean: any = {
62
- intent: svc.intent || '',
63
- reference: svc.reference || '',
64
- enabled: svc.enabled ?? true,
65
- method: svc.method || 'GET',
66
- endpoint: svc.endpoint || '',
67
- requiredFields: cleanRequiredFields(svc.requiredFields),
68
- };
69
- if (svc.tags && Array.isArray(svc.tags)) clean.tags = svc.tags;
70
- if (svc.headers && typeof svc.headers === 'object') clean.headers = svc.headers;
71
- if (svc.bodyTemplate && typeof svc.bodyTemplate === 'object') clean.bodyTemplate = svc.bodyTemplate;
72
- if (svc.bodySchema && typeof svc.bodySchema === 'object') clean.bodySchema = svc.bodySchema;
73
- if (svc.responseMapping && typeof svc.responseMapping === 'object') clean.responseMapping = svc.responseMapping;
74
- if (typeof svc.responseMessage === 'string') clean.responseMessage = svc.responseMessage;
75
- if (svc.responseConditions && Array.isArray(svc.responseConditions)) {
76
- clean.responseConditions = svc.responseConditions.map((rc: any) => {
77
- const c: any = { condition: rc.condition || '' };
78
- if (typeof rc.message === 'string') c.message = rc.message;
79
- if (typeof rc.nextService === 'string') c.nextService = rc.nextService;
80
- return c;
81
- });
82
- }
83
- if (typeof svc.action === 'string') clean.action = svc.action;
84
- return clean;
85
- });
86
- }
87
-
88
- function cleanActions(actions: any): any[] {
89
- if (!actions || !Array.isArray(actions)) return [];
90
- return actions.map((act: any) => {
91
- const clean: any = {
92
- intent: act.intent || '',
93
- reference: act.reference || '',
94
- enabled: act.enabled ?? true,
95
- action: Array.isArray(act.action) ? act.action.map((a: any) => ({
96
- type: a.type || '',
97
- value: a.value ?? '',
98
- })) : [],
99
- };
100
- if (act.tags && Array.isArray(act.tags)) clean.tags = act.tags;
101
- clean.requiredFields = cleanRequiredFields(act.requiredFields);
102
- if (typeof act.responseMessage === 'string') clean.responseMessage = act.responseMessage;
103
- if (typeof act.responseJson === 'boolean') clean.responseJson = act.responseJson;
104
- return clean;
105
- });
106
- }
107
-
108
- function cleanAgentForExport(agentData: any): any {
109
- const cleaned: any = {};
110
-
111
- for (const key of Object.keys(agentData)) {
112
- if (!VALID_AGENT_FIELDS.has(key)) continue;
113
-
114
- const value = agentData[key];
115
-
116
- // Eliminar campos null en campos string
117
- if (STRING_FIELDS.has(key)) {
118
- if (value !== null && value !== undefined) {
119
- cleaned[key] = String(value);
120
- }
121
- continue;
122
- }
123
-
124
- // Asegurar que campos array sean arrays
125
- if (ARRAY_FIELDS.has(key)) {
126
- if (key === 'services') {
127
- cleaned[key] = cleanServices(value);
128
- } else if (key === 'actions') {
129
- cleaned[key] = cleanActions(value);
130
- } else if (Array.isArray(value)) {
131
- cleaned[key] = value;
132
- } else {
133
- cleaned[key] = [];
134
- }
135
- continue;
136
- }
137
-
138
- // Eliminar nulls genericos
139
- if (value !== null && value !== undefined) {
140
- cleaned[key] = value;
141
- }
142
- }
143
-
144
- // Limpiar channels
145
- if (cleaned.channels && Array.isArray(cleaned.channels)) {
146
- cleaned.channels = cleaned.channels.map((ch: any) => ({
147
- channel: ch.channel || '',
148
- key: ch.key || '',
149
- multianswer: ch.multianswer || false,
150
- }));
151
- }
152
-
153
- // Limpiar aiProviders
154
- if (cleaned.aiProviders && Array.isArray(cleaned.aiProviders)) {
155
- cleaned.aiProviders = cleaned.aiProviders.map((ai: any) => ({
156
- provider: ai.provider,
157
- model: ai.model,
158
- apiToken: ai.apiToken || '',
159
- temperature: ai.temperature,
160
- maxTokens: ai.maxTokens,
161
- isDefault: ai.isDefault,
162
- }));
163
- }
164
-
165
- // Limpiar examples
166
- if (cleaned.examples && Array.isArray(cleaned.examples)) {
167
- cleaned.examples = cleaned.examples.map((ex: any) => ({
168
- value: ex.value || '',
169
- color: ex.color || 'blue',
170
- }));
171
- }
172
-
173
- return cleaned;
174
- }
175
-
176
- export const exportCommand = new Command('export')
177
- .description('Export a clean agent configuration (compatible with import)')
178
- .argument('<agentId>', 'Agent ID to export')
179
- .option('-w, --workspace <id>', 'Source workspace ID (overrides local config)')
180
- .option('-z, --zone <zone>', 'Zone LA or EU (overrides local config)')
181
- .option('-o, --output <path>', 'Output file path (.json)')
182
- .option('--no-channels', 'Exclude channels from export')
183
- .option('--no-ai', 'Exclude custom AI configuration')
184
- .option('--dev', 'Use development environment', false)
185
- .action(async (agentId: string, options: {
186
- workspace?: string;
187
- zone?: string;
188
- output?: string;
189
- channels: boolean;
190
- ai: boolean;
191
- dev: boolean;
192
- }) => {
193
- try {
194
- const credentials = await getStoredCredentials();
195
-
196
- const effectiveWorkspace = options.workspace || credentials.workspace;
197
- const effectiveZone = (options.zone?.toUpperCase() === 'EU' ? 'EU' : options.zone?.toUpperCase() === 'LA' ? 'LA' : credentials.zone) as 'LA' | 'EU';
198
-
199
- if (options.workspace || options.zone) {
200
- console.log(chalk.hex('#FFA726')(`\n Support mode: workspace=${effectiveWorkspace} zone=${effectiveZone}`));
201
- }
202
-
203
- const agent = new Agent({
204
- workspaceId: effectiveWorkspace,
205
- apiKey: credentials.apiKey,
206
- zone: effectiveZone,
207
- ...(options.dev && { customUrl: 'http://localhost:5090' }),
208
- });
209
-
210
- const spinner = createSpinner('Fetching agent...');
211
- spinner.start();
212
-
213
- const response: any = await agent.getAgentById({ id: agentId });
214
- const agentData = response.agent || response.data || response;
215
-
216
- spinner.succeed('Agent fetched');
217
-
218
- // Limpiar para exportacion
219
- const cleaned = cleanAgentForExport(agentData);
220
-
221
- // Aplicar opciones de exclusion
222
- if (!options.channels) {
223
- delete cleaned.channels;
224
- }
225
-
226
- if (!options.ai) {
227
- cleaned.customAIConfig = false;
228
- delete cleaned.aiProviders;
229
- }
230
-
231
- const jsonOutput = JSON.stringify(cleaned, null, 2);
232
-
233
- // Guardar en archivo o mostrar en consola
234
- if (options.output) {
235
- const outputPath = path.resolve(options.output);
236
- fs.writeFileSync(outputPath, jsonOutput, 'utf-8');
237
- console.log(chalk.hex('#4ade80')(`\n Exported to: ${outputPath}`));
238
- } else {
239
- console.log();
240
- console.log(jsonOutput);
241
- }
242
-
243
- console.log();
244
- console.log(chalk.gray(' This JSON is compatible with:'));
245
- console.log(chalk.gray(' - plazbot agent create <file.json>'));
246
- console.log(chalk.gray(' - Importing JSON in the platform (AgentTraining)'));
247
- console.log();
248
-
249
- } catch (error) {
250
- const message = error instanceof Error ? error.message : 'Unknown error';
251
- logger.error(message);
252
- process.exit(1);
253
- }
254
- });
255
-
256
- addExamples(exportCommand, [
257
- { description: 'Print the cleaned JSON to stdout',
258
- command: 'plazbot agent export agt_AbcDef123' },
259
- { description: 'Write the cleaned JSON to a file',
260
- command: 'plazbot agent export agt_AbcDef123 -o ./agent.json' },
261
- { description: 'Export without channels nor AI credentials (portable JSON)',
262
- command: 'plazbot agent export agt_AbcDef123 -o ./agent.json --no-channels --no-ai' },
263
- { description: 'Export from a different workspace (support mode)',
264
- command: 'plazbot agent export agt_AbcDef123 -w wok_Other123 -z LA -o ./agent.json' },
265
- ]);
266
-
267
- export const crossCopyCommand = new Command('cross-copy')
268
- .description('Copy an agent from one workspace to another')
269
- .argument('<agentId>', 'Agent ID to copy')
270
- .requiredOption('--from-workspace <id>', 'Source workspace ID')
271
- .requiredOption('--to-workspace <id>', 'Target workspace ID')
272
- .option('--from-zone <zone>', 'Source workspace zone (LA or EU)', 'LA')
273
- .option('--to-zone <zone>', 'Target workspace zone (LA or EU)', 'LA')
274
- .option('--no-channels', 'Do not copy channels (recommended)')
275
- .option('--no-ai', 'Do not copy custom AI configuration')
276
- .option('--dev', 'Use development environment', false)
277
- .action(async (agentId: string, options: {
278
- fromWorkspace: string;
279
- toWorkspace: string;
280
- fromZone: string;
281
- toZone: string;
282
- channels: boolean;
283
- ai: boolean;
284
- dev: boolean;
285
- }) => {
286
- try {
287
- const credentials = await getStoredCredentials();
288
- const fromZone = (options.fromZone.toUpperCase() === 'EU' ? 'EU' : 'LA') as 'LA' | 'EU';
289
- const toZone = (options.toZone.toUpperCase() === 'EU' ? 'EU' : 'LA') as 'LA' | 'EU';
290
-
291
- console.log();
292
- console.log(chalk.hex('#4CAF50')(' ┌' + '─'.repeat(58) + '┐'));
293
- console.log(chalk.hex('#4CAF50')(' │') + chalk.bold(' Copy agent between workspaces').padEnd(68) + chalk.hex('#4CAF50')('│'));
294
- console.log(chalk.hex('#4CAF50')(' └' + '─'.repeat(58) + '┘'));
295
- console.log();
296
- console.log(chalk.gray(` Source: ${options.fromWorkspace} (${fromZone})`));
297
- console.log(chalk.gray(` Target: ${options.toWorkspace} (${toZone})`));
298
- console.log(chalk.gray(` Agent: ${agentId}`));
299
- console.log();
300
-
301
- // 1. Obtener agente del workspace origen
302
- const spinnerGet = createSpinner('Fetching agent from source workspace...');
303
- spinnerGet.start();
304
-
305
- const sourceAgent = new Agent({
306
- workspaceId: options.fromWorkspace,
307
- apiKey: credentials.apiKey,
308
- zone: fromZone,
309
- ...(options.dev && { customUrl: 'http://localhost:5090' }),
310
- });
311
-
312
- const response: any = await sourceAgent.getAgentById({ id: agentId });
313
- const agentData = response.agent || response.data || response;
314
-
315
- if (!agentData || !agentData.name) {
316
- spinnerGet.fail('Agent not found in source workspace');
317
- process.exit(1);
318
- }
319
-
320
- spinnerGet.succeed(`Agent fetched: ${agentData.name}`);
321
-
322
- // 2. Limpiar JSON
323
- const cleaned = cleanAgentForExport(agentData);
324
-
325
- // Ajustar zona al destino
326
- cleaned.zone = toZone;
327
-
328
- // Limpiar canales (los canales son especificos del workspace)
329
- if (!options.channels) {
330
- cleaned.channels = [];
331
- }
332
-
333
- // Limpiar AI config si se solicita
334
- if (!options.ai) {
335
- cleaned.customAIConfig = false;
336
- delete cleaned.aiProviders;
337
- }
338
-
339
- // Desactivar widget (seguridad)
340
- cleaned.enableWidget = false;
341
-
342
- // 3. Mostrar resumen
343
- console.log();
344
- console.log(chalk.bold(' Configuration to copy:'));
345
- console.log(chalk.gray(` Name: ${cleaned.name}`));
346
- console.log(chalk.gray(` Target zone: ${cleaned.zone}`));
347
- console.log(chalk.gray(` Channels: ${cleaned.channels?.length || 0}`));
348
- console.log(chalk.gray(` Services: ${cleaned.services?.length || 0}`));
349
- console.log(chalk.gray(` Actions: ${cleaned.actions?.length || 0}`));
350
- console.log(chalk.gray(` Custom AI: ${cleaned.customAIConfig ? 'Yes' : 'No'}`));
351
- console.log();
352
-
353
- const { confirm } = await (inquirer as any).prompt([{
354
- type: 'confirm',
355
- name: 'confirm',
356
- message: 'Create this agent in the target workspace?',
357
- default: true,
358
- }]);
359
-
360
- if (!confirm) {
361
- console.log(chalk.gray(' Operation cancelled.'));
362
- return;
363
- }
364
-
365
- // 4. Crear en workspace destino
366
- const spinnerCreate = createSpinner('Creating agent in target workspace...');
367
- spinnerCreate.start();
368
-
369
- const targetAgent = new Agent({
370
- workspaceId: options.toWorkspace,
371
- apiKey: credentials.apiKey,
372
- zone: toZone,
373
- ...(options.dev && { customUrl: 'http://localhost:5090' }),
374
- });
375
-
376
- const result: any = await targetAgent.addAgent(cleaned);
377
-
378
- if (result?.success === false) {
379
- spinnerCreate.fail(`Error: ${result.message || 'Could not create the agent'}`);
380
- process.exit(1);
381
- }
382
-
383
- const newId = result?.agentId || result?.id || result?.data?.agentId;
384
- spinnerCreate.succeed('Agent created successfully');
385
-
386
- console.log();
387
- if (newId) {
388
- console.log(chalk.hex('#4ade80')(` New ID: ${newId}`));
389
- }
390
- console.log(chalk.gray(' Widget disabled by default.'));
391
- console.log(chalk.gray(' Channels must be configured manually in the target workspace.'));
392
- console.log();
393
-
394
- } catch (error) {
395
- const message = error instanceof Error ? error.message : 'Unknown error';
396
- logger.error(message);
397
- process.exit(1);
398
- }
399
- });
400
-
401
- addExamples(crossCopyCommand, [
402
- { description: 'Copy an agent between two LA workspaces (skip channels)',
403
- command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --to-workspace wok_Target456' },
404
- { description: 'Copy across zones (LA → EU)',
405
- command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --from-zone LA --to-workspace wok_Target456 --to-zone EU' },
406
- { description: 'Copy preserving channels and AI providers',
407
- command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --to-workspace wok_Target456 --channels --ai' },
408
- ]);
@@ -1,171 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { createSpinner, createTable, theme, section, statusBadge } from '../../utils/ui.js';
7
- import { AgentCommandOptions } from '../../types/agent.js';
8
-
9
- const filesGroup = new Command('files')
10
- .description('Manage files in the agent knowledge base');
11
-
12
- addExamples(filesGroup, [
13
- { description: 'List the knowledge-base files of an agent',
14
- command: 'plazbot agent files list agt_AbcDef123' },
15
- { description: 'Add a remote PDF/DOC to the knowledge base',
16
- command: 'plazbot agent files add agt_AbcDef123 -u https://files.example.com/manual.pdf -r manual -t docs,onboarding' },
17
- { description: 'Check whether a file finished processing',
18
- command: 'plazbot agent files status file_AbcDef123' },
19
- { description: 'Remove a file from the knowledge base',
20
- command: 'plazbot agent files delete agt_AbcDef123 file_AbcDef123' },
21
- ]);
22
-
23
- // Listar archivos
24
- filesGroup.command('list')
25
- .description('List agent files')
26
- .argument('<agentId>', 'Agent ID')
27
- .option('--dev', 'Use development environment', false)
28
- .action(async (agentId: string, options: AgentCommandOptions) => {
29
- try {
30
- const credentials = await getStoredCredentials();
31
- const agent = new Agent({
32
- workspaceId: credentials.workspace,
33
- apiKey: credentials.apiKey,
34
- zone: credentials.zone,
35
- ...(options.dev && { customUrl: "http://localhost:5090" })
36
- });
37
-
38
- const spinner = createSpinner('Loading files...');
39
- spinner.start();
40
- const _res: any = await agent.getAgentById({ id: agentId });
41
- const agentData = _res.agent || _res.data || _res;
42
- spinner.stop();
43
-
44
- const files = (agentData as any).files || [];
45
- console.log(section('Files - ' + (agentData.name || agentId)));
46
-
47
- if (files.length === 0) {
48
- console.log(theme.muted('\n No files in the knowledge base'));
49
- console.log(theme.muted(' Use: plazbot agent files add <agentId> --url <url>\n'));
50
- return;
51
- }
52
-
53
- const rows = files.map((f: any) => [
54
- f.fileId || f.id || 'N/A',
55
- f.name || f.reference || 'Untitled',
56
- (f.tags || []).join(', ') || '-',
57
- ]);
58
-
59
- console.log(createTable(['ID', 'Name', 'Tags'], rows));
60
-
61
- } catch (error) {
62
- const message = error instanceof Error ? error.message : 'Unknown error';
63
- logger.error(message);
64
- process.exit(1);
65
- }
66
- });
67
-
68
- // Agregar archivo
69
- filesGroup.command('add')
70
- .description('Add a file to the knowledge base')
71
- .argument('<agentId>', 'Agent ID')
72
- .requiredOption('-u, --url <url>', 'File URL (PDF, DOC, DOCX)')
73
- .option('-r, --reference <name>', 'Reference name', 'documento')
74
- .option('-t, --tags <tags>', 'Comma-separated tags', '')
75
- .option('--dev', 'Use development environment', false)
76
- .action(async (agentId: string, options: any) => {
77
- try {
78
- const credentials = await getStoredCredentials();
79
- const agent = new Agent({
80
- workspaceId: credentials.workspace,
81
- apiKey: credentials.apiKey,
82
- zone: credentials.zone,
83
- ...(options.dev && { customUrl: "http://localhost:5090" })
84
- });
85
-
86
- const spinner = createSpinner('Uploading file...');
87
- spinner.start();
88
-
89
- const tags = options.tags ? options.tags.split(',').map((t: string) => t.trim()) : [];
90
- const result = await agent.addFile({
91
- fileUrl: options.url,
92
- reference: options.reference,
93
- agentId,
94
- tags,
95
- });
96
-
97
- spinner.succeed('File added');
98
-
99
- if (result?.fileId) {
100
- logger.label('File ID', result.fileId);
101
- logger.dim('The file is being processed. Check status with:');
102
- logger.dim(`plazbot agent files status ${result.fileId}`);
103
- }
104
-
105
- } catch (error) {
106
- const message = error instanceof Error ? error.message : 'Unknown error';
107
- logger.error(message);
108
- process.exit(1);
109
- }
110
- });
111
-
112
- // Verificar estado
113
- filesGroup.command('status')
114
- .description('Check the processing status of a file')
115
- .argument('<fileId>', 'File ID')
116
- .option('--dev', 'Use development environment', false)
117
- .action(async (fileId: string, options: AgentCommandOptions) => {
118
- try {
119
- const credentials = await getStoredCredentials();
120
- const agent = new Agent({
121
- workspaceId: credentials.workspace,
122
- apiKey: credentials.apiKey,
123
- zone: credentials.zone,
124
- ...(options.dev && { customUrl: "http://localhost:5090" })
125
- });
126
-
127
- const spinner = createSpinner('Checking...');
128
- spinner.start();
129
- const result = await agent.validateFile({ fileId });
130
- spinner.stop();
131
-
132
- logger.title('File status');
133
- logger.label('File ID', fileId);
134
- logger.label('Status', result?.status ? 'Completed' : 'Processing');
135
-
136
- } catch (error) {
137
- const message = error instanceof Error ? error.message : 'Unknown error';
138
- logger.error(message);
139
- process.exit(1);
140
- }
141
- });
142
-
143
- // Eliminar archivo
144
- filesGroup.command('delete')
145
- .description('Delete a file from the knowledge base')
146
- .argument('<agentId>', 'Agent ID')
147
- .argument('<fileId>', 'File ID')
148
- .option('--dev', 'Use development environment', false)
149
- .action(async (agentId: string, fileId: string, options: AgentCommandOptions) => {
150
- try {
151
- const credentials = await getStoredCredentials();
152
- const agent = new Agent({
153
- workspaceId: credentials.workspace,
154
- apiKey: credentials.apiKey,
155
- zone: credentials.zone,
156
- ...(options.dev && { customUrl: "http://localhost:5090" })
157
- });
158
-
159
- const spinner = createSpinner('Deleting file...');
160
- spinner.start();
161
- await agent.deleteFile({ fileId, agentId });
162
- spinner.succeed('File deleted');
163
-
164
- } catch (error) {
165
- const message = error instanceof Error ? error.message : 'Unknown error';
166
- logger.error(message);
167
- process.exit(1);
168
- }
169
- });
170
-
171
- export const filesCommand = filesGroup;