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.
- package/README.md +38 -2
- package/dist/commands/agent/export.js +25 -2
- package/dist/commands/auth/browser-login.js +121 -0
- package/dist/commands/auth/index.js +5 -1
- package/dist/commands/auth/login.js +1 -3
- package/dist/commands/auth/logout.js +4 -3
- package/dist/commands/auth/status.js +8 -5
- package/dist/commands/auth/workspace.js +73 -0
- package/dist/commands/whatsapp/connect-flow.js +137 -0
- package/dist/commands/whatsapp/connect.js +26 -160
- package/dist/commands/whatsapp/index.js +4 -0
- package/dist/commands/whatsapp/setup.js +242 -0
- package/dist/studio/components/App.js +1 -1
- package/dist/studio/runOneShot.js +2 -2
- package/dist/studio/runRepl.js +1 -1
- package/dist/utils/agent-errors.js +2 -2
- package/dist/utils/banner.js +10 -9
- package/dist/utils/credentials.js +31 -3
- package/dist/utils/open-browser.js +17 -0
- package/package.json +14 -6
- package/.claude/settings.local.json +0 -15
- package/CLAUDE.md +0 -121
- package/agent.config.json +0 -21
- package/dist/studio/components/AgentPanel.js +0 -35
- package/dist/studio/render/json.js +0 -16
- package/dist/studio/whatsapp/api.js +0 -63
- package/dist/studio/whatsapp/polling.js +0 -77
- package/dist/studio/whatsapp/types.js +0 -31
- package/src/cli.ts +0 -57
- package/src/commands/agent/ai-config.ts +0 -164
- package/src/commands/agent/chat.ts +0 -225
- package/src/commands/agent/copy.ts +0 -46
- package/src/commands/agent/create.ts +0 -103
- package/src/commands/agent/delete.ts +0 -71
- package/src/commands/agent/enable-widget.ts +0 -67
- package/src/commands/agent/export.ts +0 -408
- package/src/commands/agent/files.ts +0 -171
- package/src/commands/agent/get.ts +0 -233
- package/src/commands/agent/index.ts +0 -55
- package/src/commands/agent/list.ts +0 -58
- package/src/commands/agent/monitor.ts +0 -375
- package/src/commands/agent/on-message.ts +0 -82
- package/src/commands/agent/set.ts +0 -149
- package/src/commands/agent/templates.ts +0 -892
- package/src/commands/agent/tools.ts +0 -168
- package/src/commands/agent/update.ts +0 -61
- package/src/commands/agent/validate.ts +0 -135
- package/src/commands/agent/wizard.ts +0 -756
- package/src/commands/auth/index.ts +0 -10
- package/src/commands/auth/login.ts +0 -72
- package/src/commands/auth/logout.ts +0 -28
- package/src/commands/auth/status.ts +0 -28
- package/src/commands/portal/add-agent.ts +0 -66
- package/src/commands/portal/add-link.ts +0 -47
- package/src/commands/portal/clear-links.ts +0 -33
- package/src/commands/portal/create.ts +0 -58
- package/src/commands/portal/delete.ts +0 -70
- package/src/commands/portal/get.ts +0 -77
- package/src/commands/portal/index.ts +0 -32
- package/src/commands/portal/list.ts +0 -79
- package/src/commands/portal/update.ts +0 -93
- package/src/commands/whatsapp/broadcast.ts +0 -110
- package/src/commands/whatsapp/channels.ts +0 -109
- package/src/commands/whatsapp/chat.ts +0 -85
- package/src/commands/whatsapp/connect.ts +0 -220
- package/src/commands/whatsapp/delete-webhook.ts +0 -43
- package/src/commands/whatsapp/index.ts +0 -37
- package/src/commands/whatsapp/register-webhook.ts +0 -47
- package/src/commands/whatsapp/send-template.ts +0 -94
- package/src/commands/whatsapp/send.ts +0 -55
- package/src/commands/whatsapp/widget.ts +0 -75
- package/src/commands/workers/deploy.ts +0 -156
- package/src/commands/workers/index.ts +0 -30
- package/src/commands/workers/list.ts +0 -105
- package/src/commands/workers/logs.ts +0 -99
- package/src/commands/workers/remove.ts +0 -103
- package/src/commands/workers/secret.ts +0 -191
- package/src/commands/workers/test.ts +0 -145
- package/src/schemas/agent.config.schema.json +0 -569
- package/src/studio/api/sseClient.ts +0 -91
- package/src/studio/api/studioApi.ts +0 -27
- package/src/studio/api/types.ts +0 -96
- package/src/studio/components/App.tsx +0 -274
- package/src/studio/components/ChatLog.tsx +0 -121
- package/src/studio/components/ConnectCard.tsx +0 -171
- package/src/studio/components/Footer.tsx +0 -38
- package/src/studio/components/Header.tsx +0 -39
- package/src/studio/components/Input.tsx +0 -176
- package/src/studio/components/Message.tsx +0 -87
- package/src/studio/components/Suggestions.tsx +0 -26
- package/src/studio/components/ToolCall.tsx +0 -58
- package/src/studio/connect/api.ts +0 -98
- package/src/studio/connect/polling.ts +0 -94
- package/src/studio/connect/types.ts +0 -141
- package/src/studio/index.ts +0 -58
- package/src/studio/render/markdown.ts +0 -93
- package/src/studio/render/steps.ts +0 -57
- package/src/studio/runOneShot.ts +0 -114
- package/src/studio/runRepl.tsx +0 -82
- package/src/studio/slash/handlers.ts +0 -226
- package/src/studio/slash/parser.ts +0 -41
- package/src/studio/slash/registry.ts +0 -54
- package/src/studio/state/store.ts +0 -279
- package/src/types/agent.ts +0 -63
- package/src/types/auth.ts +0 -9
- package/src/types/common.ts +0 -10
- package/src/types/message.ts +0 -34
- package/src/types/portal.ts +0 -56
- package/src/types/workers.ts +0 -86
- package/src/utils/agent-errors.ts +0 -67
- package/src/utils/api.ts +0 -35
- package/src/utils/banner.ts +0 -99
- package/src/utils/credentials.ts +0 -38
- package/src/utils/help.ts +0 -51
- package/src/utils/logger.ts +0 -40
- package/src/utils/ui.ts +0 -109
- 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;
|