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