plazbot-cli 0.2.9 → 0.2.11
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/commands/agent/ai-config.js +2 -1
- package/dist/commands/agent/chat.js +2 -1
- package/dist/commands/agent/delete.js +5 -4
- package/dist/commands/agent/enable-widget.js +2 -1
- package/dist/commands/agent/files.js +2 -1
- package/dist/commands/agent/monitor.js +2 -1
- package/dist/commands/agent/set.js +4 -2
- package/dist/commands/agent/tools.js +2 -1
- package/dist/commands/agent/wizard.js +148 -141
- package/package.json +1 -1
- package/src/commands/agent/ai-config.ts +2 -1
- package/src/commands/agent/chat.ts +2 -1
- package/src/commands/agent/delete.ts +6 -5
- package/src/commands/agent/enable-widget.ts +3 -2
- package/src/commands/agent/files.ts +2 -1
- package/src/commands/agent/monitor.ts +2 -1
- package/src/commands/agent/set.ts +4 -2
- package/src/commands/agent/tools.ts +2 -1
- package/src/commands/agent/wizard.ts +158 -151
|
@@ -30,7 +30,8 @@ exports.aiConfigCommand = new commander_1.Command('ai-config')
|
|
|
30
30
|
});
|
|
31
31
|
const spinner = (0, ui_1.createSpinner)('Cargando agente...');
|
|
32
32
|
spinner.start();
|
|
33
|
-
const
|
|
33
|
+
const _res = await agent.getAgentById({ id: agentId });
|
|
34
|
+
const agentData = _res.agent || _res.data || _res;
|
|
34
35
|
spinner.stop();
|
|
35
36
|
console.log((0, ui_1.section)('Configuracion de IA - ' + (agentData.name || agentId)));
|
|
36
37
|
const currentProviders = agentData.aiProviders || [];
|
|
@@ -41,7 +41,8 @@ exports.chatCommand = new commander_1.Command('chat')
|
|
|
41
41
|
let agentInfo = null;
|
|
42
42
|
try {
|
|
43
43
|
process.stdout.write(chalk_1.default.gray(' Conectando con agente...'));
|
|
44
|
-
|
|
44
|
+
const _res = await agent.getAgentById({ id: options.agentId });
|
|
45
|
+
agentInfo = _res.agent || _res.data || _res;
|
|
45
46
|
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
46
47
|
}
|
|
47
48
|
catch {
|
|
@@ -24,12 +24,13 @@ exports.deleteCommand = new commander_1.Command('delete')
|
|
|
24
24
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
25
25
|
});
|
|
26
26
|
// Obtener detalles del agente para mostrar información
|
|
27
|
-
const
|
|
27
|
+
const response = await agent.getAgentById({ id: agentId });
|
|
28
|
+
const agentDetails = response.agent || response.data || response;
|
|
28
29
|
logger_1.logger.warning('\nVas a eliminar el siguiente agente:');
|
|
29
30
|
logger_1.logger.divider();
|
|
30
|
-
logger_1.logger.info(`ID: ${agentDetails.id}`);
|
|
31
|
-
logger_1.logger.info(`Nombre: ${agentDetails.name}`);
|
|
32
|
-
logger_1.logger.info(`
|
|
31
|
+
logger_1.logger.info(`ID: ${agentDetails.id || agentId}`);
|
|
32
|
+
logger_1.logger.info(`Nombre: ${agentDetails.name || '—'}`);
|
|
33
|
+
logger_1.logger.info(`Descripcion: ${agentDetails.description || '—'}`);
|
|
33
34
|
logger_1.logger.divider();
|
|
34
35
|
// Crear interfaz para confirmación
|
|
35
36
|
const rl = readline_1.default.createInterface({
|
|
@@ -21,7 +21,8 @@ exports.enableCommand = new commander_1.Command('enable-widget')
|
|
|
21
21
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
22
22
|
});
|
|
23
23
|
// Obtener estado actual del agente
|
|
24
|
-
const
|
|
24
|
+
const _res = await agent.getAgentById({ id: agentId });
|
|
25
|
+
const agentDetails = _res.agent || _res.data || _res;
|
|
25
26
|
logger_1.logger.title('Estado actual del widget');
|
|
26
27
|
logger_1.logger.label('Agente', agentDetails.name);
|
|
27
28
|
// Cambiar estado
|
|
@@ -24,7 +24,8 @@ filesGroup.command('list')
|
|
|
24
24
|
});
|
|
25
25
|
const spinner = (0, ui_1.createSpinner)('Cargando archivos...');
|
|
26
26
|
spinner.start();
|
|
27
|
-
const
|
|
27
|
+
const _res = await agent.getAgentById({ id: agentId });
|
|
28
|
+
const agentData = _res.agent || _res.data || _res;
|
|
28
29
|
spinner.stop();
|
|
29
30
|
const files = agentData.files || [];
|
|
30
31
|
console.log((0, ui_1.section)('Archivos - ' + (agentData.name || agentId)));
|
|
@@ -145,7 +145,8 @@ exports.monitorCommand = new commander_1.Command('monitor')
|
|
|
145
145
|
zone: effectiveZone,
|
|
146
146
|
...(options.dev && { customUrl: 'http://localhost:5090' }),
|
|
147
147
|
});
|
|
148
|
-
const
|
|
148
|
+
const _res = await agent.getAgentById({ id: options.agentId });
|
|
149
|
+
const info = _res.agent || _res.data || _res;
|
|
149
150
|
if (info?.name)
|
|
150
151
|
agentName = info.name;
|
|
151
152
|
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
@@ -56,7 +56,8 @@ setGroup.command('instructions')
|
|
|
56
56
|
// Cargar instrucciones actuales
|
|
57
57
|
const loadSpinner = (0, ui_1.createSpinner)('Cargando...');
|
|
58
58
|
loadSpinner.start();
|
|
59
|
-
const
|
|
59
|
+
const _res1 = await agent.getAgentById({ id: agentId });
|
|
60
|
+
const agentData = _res1.agent || _res1.data || _res1;
|
|
60
61
|
loadSpinner.stop();
|
|
61
62
|
const current = agentData.instructions || {};
|
|
62
63
|
console.log((0, ui_1.section)('Instrucciones - ' + (agentData.name || agentId)));
|
|
@@ -104,7 +105,8 @@ setGroup.command('persona')
|
|
|
104
105
|
});
|
|
105
106
|
const loadSpinner = (0, ui_1.createSpinner)('Cargando...');
|
|
106
107
|
loadSpinner.start();
|
|
107
|
-
const
|
|
108
|
+
const _res2 = await agent.getAgentById({ id: agentId });
|
|
109
|
+
const agentData = _res2.agent || _res2.data || _res2;
|
|
108
110
|
loadSpinner.stop();
|
|
109
111
|
const current = agentData.person || {};
|
|
110
112
|
console.log((0, ui_1.section)('Persona - ' + (agentData.name || agentId)));
|
|
@@ -25,7 +25,8 @@ exports.toolsCommand = new commander_1.Command('tools')
|
|
|
25
25
|
});
|
|
26
26
|
const spinner = (0, ui_1.createSpinner)('Cargando agente...');
|
|
27
27
|
spinner.start();
|
|
28
|
-
const
|
|
28
|
+
const _res = await agent.getAgentById({ id: agentId });
|
|
29
|
+
const agentData = _res.agent || _res.data || _res;
|
|
29
30
|
spinner.stop();
|
|
30
31
|
console.log((0, ui_1.section)('Tool Calling - ' + (agentData.name || agentId)));
|
|
31
32
|
console.log((0, ui_1.kvPair)('Estado', agentData.useToolCalling ? ui_1.theme.success('Activado') : ui_1.theme.error('Desactivado')));
|
|
@@ -32,6 +32,24 @@ const CHANNEL_AGENT_MAP = {
|
|
|
32
32
|
instagram: 'instagram',
|
|
33
33
|
facebook: 'facebook',
|
|
34
34
|
};
|
|
35
|
+
function getIntegrationLabel(ig) {
|
|
36
|
+
if (ig.type === 'whatsapp') {
|
|
37
|
+
return ig.aliasName
|
|
38
|
+
? `${ig.aliasName} (${ig.cellphoneNumberFormat || ig.cellphoneNumber || ''})`
|
|
39
|
+
: ig.cellphoneNumberFormat || ig.cellphoneNumber || ig.id;
|
|
40
|
+
}
|
|
41
|
+
return ig.aliasName || ig.srcName || ig.id;
|
|
42
|
+
}
|
|
43
|
+
async function fetchWorkspaceIntegrations(baseUrl, workspaceId, headers) {
|
|
44
|
+
try {
|
|
45
|
+
const wkRes = await axios_1.default.get(`${baseUrl}/api/workspace/${workspaceId}`, { headers });
|
|
46
|
+
const wsData = Array.isArray(wkRes.data) ? wkRes.data[0] : wkRes.data;
|
|
47
|
+
return wsData?.integrations || [];
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
35
53
|
async function connectChannelFlow(ctx) {
|
|
36
54
|
const channels = [];
|
|
37
55
|
const baseUrl = getBaseUrl(ctx.zone, ctx.dev);
|
|
@@ -49,156 +67,145 @@ async function connectChannelFlow(ctx) {
|
|
|
49
67
|
choices: CHANNEL_CHOICES,
|
|
50
68
|
}]);
|
|
51
69
|
const channelLabel = CHANNEL_CHOICES.find(c => c.value === channelType)?.name || channelType;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
const targetType = channelType === 'whatsapp_business' ? 'whatsapp' : channelType;
|
|
71
|
+
// Cargar integraciones existentes del tipo seleccionado
|
|
72
|
+
const loadSpinner = (0, ora_1.default)({ text: chalk_1.default.gray('Cargando integraciones...'), spinner: 'dots', color: 'green' }).start();
|
|
73
|
+
const allIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
|
|
74
|
+
const existing = allIntegrations.filter((ig) => ig.type === targetType);
|
|
75
|
+
loadSpinner.stop();
|
|
76
|
+
let selectedIntegration = null;
|
|
77
|
+
if (existing.length > 0) {
|
|
78
|
+
// Mostrar integraciones existentes + opcion de agregar nueva
|
|
79
|
+
const choices = existing.map((ig) => ({
|
|
80
|
+
name: `${getIntegrationLabel(ig)}`,
|
|
81
|
+
value: ig.id,
|
|
82
|
+
}));
|
|
83
|
+
choices.push(new inquirer_1.default.Separator());
|
|
84
|
+
choices.push({ name: chalk_1.default.hex('#4ade80')('+ Agregar uno nuevo (generar link)'), value: '__new__' });
|
|
85
|
+
const { selected } = await inquirer_1.default.prompt([{
|
|
86
|
+
type: 'list',
|
|
87
|
+
name: 'selected',
|
|
88
|
+
message: `Integraciones de ${channelLabel} disponibles:`,
|
|
89
|
+
choices,
|
|
90
|
+
}]);
|
|
91
|
+
if (selected !== '__new__') {
|
|
92
|
+
// Selecciono una existente
|
|
93
|
+
selectedIntegration = existing.find((ig) => ig.id === selected);
|
|
94
|
+
const label = getIntegrationLabel(selectedIntegration);
|
|
95
|
+
channels.push({
|
|
96
|
+
channel: CHANNEL_AGENT_MAP[channelType],
|
|
97
|
+
key: selectedIntegration.id,
|
|
98
|
+
multianswer: false,
|
|
99
|
+
});
|
|
100
|
+
console.log(chalk_1.default.hex('#4ade80')(` Canal asociado: ${label}`));
|
|
71
101
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
console.log(chalk_1.default.hex('#4CAF50')(' ─'.repeat(32)));
|
|
77
|
-
console.log(chalk_1.default.bold(` Envia este link para conectar ${channelLabel}:`));
|
|
78
|
-
console.log();
|
|
79
|
-
console.log(' ' + chalk_1.default.hex('#22d3ee')(shortUrl));
|
|
80
|
-
console.log();
|
|
81
|
-
console.log(chalk_1.default.hex('#4CAF50')(' ─'.repeat(32)));
|
|
82
|
-
console.log();
|
|
83
|
-
// Snapshot de integraciones actuales
|
|
84
|
-
let prevIntegrationIds = new Set();
|
|
102
|
+
}
|
|
103
|
+
// Si no hay existentes o eligio "Agregar nuevo" → generar link de onboarding
|
|
104
|
+
if (!selectedIntegration) {
|
|
105
|
+
const spinner = (0, ora_1.default)({ text: chalk_1.default.gray('Generando link de conexion...'), spinner: 'dots', color: 'green' }).start();
|
|
85
106
|
try {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
107
|
+
const linkRes = await axios_1.default.post(`${baseUrl}/api/workspace/${ctx.workspaceId}/onboarding-link`, { type: channelType }, { headers });
|
|
108
|
+
if (!linkRes.data?.success) {
|
|
109
|
+
spinner.fail(chalk_1.default.hex('#EF5350')(`Error: ${linkRes.data?.message || 'No se pudo generar el link'}`));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const shortUrl = linkRes.data.data?.shortUrl || '';
|
|
113
|
+
spinner.stop();
|
|
114
|
+
// Mostrar link
|
|
115
|
+
console.log();
|
|
116
|
+
console.log(chalk_1.default.hex('#4CAF50')(' ─'.repeat(32)));
|
|
117
|
+
console.log(chalk_1.default.bold(` Envia este link para conectar ${channelLabel}:`));
|
|
118
|
+
console.log();
|
|
119
|
+
console.log(' ' + chalk_1.default.hex('#22d3ee')(shortUrl));
|
|
120
|
+
console.log();
|
|
121
|
+
console.log(chalk_1.default.hex('#4CAF50')(' ─'.repeat(32)));
|
|
122
|
+
console.log();
|
|
123
|
+
// Guardar IDs actuales para detectar nuevos
|
|
124
|
+
const prevIds = new Set(allIntegrations.map((i) => i.id));
|
|
125
|
+
// Polling para detectar nueva integracion (Enter para saltar)
|
|
126
|
+
const pollSpinner = (0, ora_1.default)({ text: chalk_1.default.gray('Esperando conexion... (Enter para saltar)'), spinner: 'dots', color: 'cyan' }).start();
|
|
127
|
+
const POLL_INTERVAL = 5000;
|
|
128
|
+
const MAX_POLLS = 60;
|
|
129
|
+
let detected = null;
|
|
130
|
+
let skipped = false;
|
|
131
|
+
// Escuchar Enter para saltar
|
|
132
|
+
const skipPromise = new Promise(resolve => {
|
|
133
|
+
const onData = (data) => {
|
|
134
|
+
if (data.toString().includes('\n') || data.toString().includes('\r')) {
|
|
135
|
+
skipped = true;
|
|
136
|
+
process.stdin.removeListener('data', onData);
|
|
137
|
+
if (wasRaw)
|
|
138
|
+
process.stdin.setRawMode(false);
|
|
139
|
+
resolve();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const wasRaw = process.stdin.isRaw;
|
|
143
|
+
if (process.stdin.isTTY)
|
|
144
|
+
process.stdin.setRawMode(true);
|
|
145
|
+
process.stdin.resume();
|
|
146
|
+
process.stdin.on('data', onData);
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
process.stdin.removeListener('data', onData);
|
|
149
|
+
if (process.stdin.isTTY && wasRaw !== undefined) {
|
|
150
|
+
try {
|
|
151
|
+
process.stdin.setRawMode(wasRaw);
|
|
152
|
+
}
|
|
153
|
+
catch { }
|
|
154
|
+
}
|
|
155
|
+
resolve();
|
|
156
|
+
}, POLL_INTERVAL * MAX_POLLS + 1000);
|
|
157
|
+
});
|
|
158
|
+
for (let i = 0; i < MAX_POLLS; i++) {
|
|
159
|
+
await Promise.race([
|
|
160
|
+
new Promise(r => setTimeout(r, POLL_INTERVAL)),
|
|
161
|
+
skipPromise,
|
|
162
|
+
]);
|
|
163
|
+
if (skipped)
|
|
164
|
+
break;
|
|
121
165
|
try {
|
|
122
|
-
|
|
166
|
+
const freshIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
|
|
167
|
+
const newOnes = freshIntegrations.filter((ig) => !prevIds.has(ig.id));
|
|
168
|
+
if (newOnes.length > 0) {
|
|
169
|
+
const match = newOnes.find((ig) => ig.type === targetType);
|
|
170
|
+
detected = match || newOnes[0];
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
123
173
|
}
|
|
124
174
|
catch { }
|
|
175
|
+
const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
|
|
176
|
+
pollSpinner.text = chalk_1.default.gray(`Esperando conexion... ${elapsed}s (Enter para saltar)`);
|
|
125
177
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
178
|
+
if (detected) {
|
|
179
|
+
const detectedName = getIntegrationLabel(detected);
|
|
180
|
+
pollSpinner.succeed(chalk_1.default.hex('#4ade80')(`Conexion detectada: ${detectedName}`));
|
|
181
|
+
channels.push({
|
|
182
|
+
channel: CHANNEL_AGENT_MAP[channelType],
|
|
183
|
+
key: detected.id,
|
|
184
|
+
multianswer: false,
|
|
185
|
+
});
|
|
186
|
+
console.log(chalk_1.default.hex('#4ade80')(' Canal asociado correctamente.'));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
pollSpinner.warn(chalk_1.default.hex('#FFA726')(skipped ? 'Omitido.' : 'Timeout: no se detecto conexion.'));
|
|
190
|
+
const { action } = await inquirer_1.default.prompt([{
|
|
191
|
+
type: 'list', name: 'action',
|
|
192
|
+
message: 'Que deseas hacer?',
|
|
193
|
+
choices: [
|
|
194
|
+
{ name: 'Ingresar ID manualmente', value: 'manual' },
|
|
195
|
+
{ name: 'Saltar', value: 'skip' },
|
|
196
|
+
],
|
|
197
|
+
}]);
|
|
198
|
+
if (action === 'manual') {
|
|
199
|
+
const { key } = await inquirer_1.default.prompt([
|
|
200
|
+
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v) => v.length > 0 || 'Requerido' },
|
|
201
|
+
]);
|
|
202
|
+
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
203
|
+
}
|
|
149
204
|
}
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
// Ignorar errores de poll individual
|
|
153
|
-
}
|
|
154
|
-
const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
|
|
155
|
-
pollSpinner.text = chalk_1.default.gray(`Esperando conexion... ${elapsed}s (Enter para saltar)`);
|
|
156
|
-
}
|
|
157
|
-
if (detected) {
|
|
158
|
-
const detectedName = detected.aliasName || detected.cellphoneNumberFormat || detected.cellphoneNumber || detected.srcName || detected.id;
|
|
159
|
-
pollSpinner.succeed(chalk_1.default.hex('#4ade80')(`Conexion detectada: ${detectedName} (${channelLabel})`));
|
|
160
|
-
const { associate } = await inquirer_1.default.prompt([{
|
|
161
|
-
type: 'confirm', name: 'associate',
|
|
162
|
-
message: 'Deseas asociar este canal al agente?', default: true,
|
|
163
|
-
}]);
|
|
164
|
-
if (associate) {
|
|
165
|
-
channels.push({
|
|
166
|
-
channel: CHANNEL_AGENT_MAP[channelType],
|
|
167
|
-
key: detected.id,
|
|
168
|
-
multianswer: false,
|
|
169
|
-
});
|
|
170
|
-
console.log(chalk_1.default.hex('#4ade80')(' Canal asociado correctamente.'));
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
pollSpinner.warn(chalk_1.default.hex('#FFA726')(skipped ? 'Polling omitido.' : 'Timeout: no se detecto una conexion.'));
|
|
175
|
-
const { action } = await inquirer_1.default.prompt([{
|
|
176
|
-
type: 'list', name: 'action',
|
|
177
|
-
message: 'Que deseas hacer?',
|
|
178
|
-
choices: [
|
|
179
|
-
{ name: 'Ingresar numero/ID manualmente', value: 'manual' },
|
|
180
|
-
{ name: 'Saltar este paso', value: 'skip' },
|
|
181
|
-
],
|
|
182
|
-
}]);
|
|
183
|
-
if (action === 'manual') {
|
|
184
|
-
const { key } = await inquirer_1.default.prompt([
|
|
185
|
-
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v) => v.length > 0 || 'Requerido' },
|
|
186
|
-
]);
|
|
187
|
-
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
188
205
|
}
|
|
189
206
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
spinner.fail(chalk_1.default.hex('#EF5350')(`Error al generar link: ${err instanceof Error ? err.message : err}`));
|
|
193
|
-
const { tryManual } = await inquirer_1.default.prompt([{
|
|
194
|
-
type: 'confirm', name: 'tryManual',
|
|
195
|
-
message: 'Deseas ingresar el numero manualmente?', default: false,
|
|
196
|
-
}]);
|
|
197
|
-
if (tryManual) {
|
|
198
|
-
const { key } = await inquirer_1.default.prompt([
|
|
199
|
-
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v) => v.length > 0 || 'Requerido' },
|
|
200
|
-
]);
|
|
201
|
-
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
207
|
+
catch (err) {
|
|
208
|
+
spinner.fail(chalk_1.default.hex('#EF5350')(`Error: ${err instanceof Error ? err.message : err}`));
|
|
202
209
|
}
|
|
203
210
|
}
|
|
204
211
|
const { more } = await inquirer_1.default.prompt([{ type: 'confirm', name: 'more', message: 'Conectar otro canal?', default: false }]);
|
package/package.json
CHANGED
|
@@ -28,7 +28,8 @@ export const aiConfigCommand = new Command('ai-config')
|
|
|
28
28
|
|
|
29
29
|
const spinner = createSpinner('Cargando agente...');
|
|
30
30
|
spinner.start();
|
|
31
|
-
const
|
|
31
|
+
const _res: any = await agent.getAgentById({ id: agentId });
|
|
32
|
+
const agentData = _res.agent || _res.data || _res;
|
|
32
33
|
spinner.stop();
|
|
33
34
|
|
|
34
35
|
console.log(section('Configuracion de IA - ' + (agentData.name || agentId)));
|
|
@@ -45,7 +45,8 @@ export const chatCommand = new Command('chat')
|
|
|
45
45
|
let agentInfo: any = null;
|
|
46
46
|
try {
|
|
47
47
|
process.stdout.write(chalk.gray(' Conectando con agente...'));
|
|
48
|
-
|
|
48
|
+
const _res: any = await agent.getAgentById({ id: options.agentId });
|
|
49
|
+
agentInfo = _res.agent || _res.data || _res;
|
|
49
50
|
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
50
51
|
} catch {
|
|
51
52
|
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
@@ -22,13 +22,14 @@ export const deleteCommand = new Command('delete')
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
// Obtener detalles del agente para mostrar información
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
const response: any = await agent.getAgentById({ id: agentId });
|
|
26
|
+
const agentDetails = response.agent || response.data || response;
|
|
27
|
+
|
|
27
28
|
logger.warning('\nVas a eliminar el siguiente agente:');
|
|
28
29
|
logger.divider();
|
|
29
|
-
logger.info(`ID: ${agentDetails.id}`);
|
|
30
|
-
logger.info(`Nombre: ${agentDetails.name}`);
|
|
31
|
-
logger.info(`
|
|
30
|
+
logger.info(`ID: ${agentDetails.id || agentId}`);
|
|
31
|
+
logger.info(`Nombre: ${agentDetails.name || '—'}`);
|
|
32
|
+
logger.info(`Descripcion: ${agentDetails.description || '—'}`);
|
|
32
33
|
logger.divider();
|
|
33
34
|
|
|
34
35
|
// Crear interfaz para confirmación
|
|
@@ -22,8 +22,9 @@ export const enableCommand = new Command('enable-widget')
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
// Obtener estado actual del agente
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
const _res: any = await agent.getAgentById({ id: agentId });
|
|
26
|
+
const agentDetails = _res.agent || _res.data || _res;
|
|
27
|
+
|
|
27
28
|
logger.title('Estado actual del widget');
|
|
28
29
|
logger.label('Agente', agentDetails.name);
|
|
29
30
|
|
|
@@ -25,7 +25,8 @@ filesGroup.command('list')
|
|
|
25
25
|
|
|
26
26
|
const spinner = createSpinner('Cargando archivos...');
|
|
27
27
|
spinner.start();
|
|
28
|
-
const
|
|
28
|
+
const _res: any = await agent.getAgentById({ id: agentId });
|
|
29
|
+
const agentData = _res.agent || _res.data || _res;
|
|
29
30
|
spinner.stop();
|
|
30
31
|
|
|
31
32
|
const files = (agentData as any).files || [];
|
|
@@ -193,7 +193,8 @@ export const monitorCommand = new Command('monitor')
|
|
|
193
193
|
zone: effectiveZone,
|
|
194
194
|
...(options.dev && { customUrl: 'http://localhost:5090' }),
|
|
195
195
|
});
|
|
196
|
-
const
|
|
196
|
+
const _res: any = await agent.getAgentById({ id: options.agentId });
|
|
197
|
+
const info = _res.agent || _res.data || _res;
|
|
197
198
|
if (info?.name) agentName = info.name;
|
|
198
199
|
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
199
200
|
} catch {
|
|
@@ -56,7 +56,8 @@ setGroup.command('instructions')
|
|
|
56
56
|
// Cargar instrucciones actuales
|
|
57
57
|
const loadSpinner = createSpinner('Cargando...');
|
|
58
58
|
loadSpinner.start();
|
|
59
|
-
const
|
|
59
|
+
const _res1: any = await agent.getAgentById({ id: agentId });
|
|
60
|
+
const agentData = _res1.agent || _res1.data || _res1;
|
|
60
61
|
loadSpinner.stop();
|
|
61
62
|
|
|
62
63
|
const current = agentData.instructions || {};
|
|
@@ -110,7 +111,8 @@ setGroup.command('persona')
|
|
|
110
111
|
|
|
111
112
|
const loadSpinner = createSpinner('Cargando...');
|
|
112
113
|
loadSpinner.start();
|
|
113
|
-
const
|
|
114
|
+
const _res2: any = await agent.getAgentById({ id: agentId });
|
|
115
|
+
const agentData = _res2.agent || _res2.data || _res2;
|
|
114
116
|
loadSpinner.stop();
|
|
115
117
|
|
|
116
118
|
const current = agentData.person || {};
|
|
@@ -22,7 +22,8 @@ export const toolsCommand = new Command('tools')
|
|
|
22
22
|
|
|
23
23
|
const spinner = createSpinner('Cargando agente...');
|
|
24
24
|
spinner.start();
|
|
25
|
-
const
|
|
25
|
+
const _res: any = await agent.getAgentById({ id: agentId });
|
|
26
|
+
const agentData = _res.agent || _res.data || _res;
|
|
26
27
|
spinner.stop();
|
|
27
28
|
|
|
28
29
|
console.log(section('Tool Calling - ' + (agentData.name || agentId)));
|
|
@@ -122,6 +122,25 @@ const CHANNEL_AGENT_MAP: Record<string, string> = {
|
|
|
122
122
|
facebook: 'facebook',
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
+
function getIntegrationLabel(ig: any): string {
|
|
126
|
+
if (ig.type === 'whatsapp') {
|
|
127
|
+
return ig.aliasName
|
|
128
|
+
? `${ig.aliasName} (${ig.cellphoneNumberFormat || ig.cellphoneNumber || ''})`
|
|
129
|
+
: ig.cellphoneNumberFormat || ig.cellphoneNumber || ig.id;
|
|
130
|
+
}
|
|
131
|
+
return ig.aliasName || ig.srcName || ig.id;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function fetchWorkspaceIntegrations(baseUrl: string, workspaceId: string, headers: any): Promise<any[]> {
|
|
135
|
+
try {
|
|
136
|
+
const wkRes = await axios.get(`${baseUrl}/api/workspace/${workspaceId}`, { headers });
|
|
137
|
+
const wsData = Array.isArray(wkRes.data) ? wkRes.data[0] : wkRes.data;
|
|
138
|
+
return wsData?.integrations || [];
|
|
139
|
+
} catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
125
144
|
async function connectChannelFlow(ctx: WizardContext): Promise<AgentChannel[]> {
|
|
126
145
|
const channels: AgentChannel[] = [];
|
|
127
146
|
const baseUrl = getBaseUrl(ctx.zone, ctx.dev);
|
|
@@ -141,165 +160,153 @@ async function connectChannelFlow(ctx: WizardContext): Promise<AgentChannel[]> {
|
|
|
141
160
|
}]);
|
|
142
161
|
|
|
143
162
|
const channelLabel = CHANNEL_CHOICES.find(c => c.value === channelType)?.name || channelType;
|
|
163
|
+
const targetType = channelType === 'whatsapp_business' ? 'whatsapp' : channelType;
|
|
164
|
+
|
|
165
|
+
// Cargar integraciones existentes del tipo seleccionado
|
|
166
|
+
const loadSpinner = ora({ text: chalk.gray('Cargando integraciones...'), spinner: 'dots', color: 'green' }).start();
|
|
167
|
+
const allIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
|
|
168
|
+
const existing = allIntegrations.filter((ig: any) => ig.type === targetType);
|
|
169
|
+
loadSpinner.stop();
|
|
170
|
+
|
|
171
|
+
let selectedIntegration: any = null;
|
|
172
|
+
|
|
173
|
+
if (existing.length > 0) {
|
|
174
|
+
// Mostrar integraciones existentes + opcion de agregar nueva
|
|
175
|
+
const choices = existing.map((ig: any) => ({
|
|
176
|
+
name: `${getIntegrationLabel(ig)}`,
|
|
177
|
+
value: ig.id,
|
|
178
|
+
}));
|
|
179
|
+
choices.push(new (inquirer as any).Separator());
|
|
180
|
+
choices.push({ name: chalk.hex('#4ade80')('+ Agregar uno nuevo (generar link)'), value: '__new__' });
|
|
181
|
+
|
|
182
|
+
const { selected } = await (inquirer as any).prompt([{
|
|
183
|
+
type: 'list',
|
|
184
|
+
name: 'selected',
|
|
185
|
+
message: `Integraciones de ${channelLabel} disponibles:`,
|
|
186
|
+
choices,
|
|
187
|
+
}]);
|
|
144
188
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (!linkRes.data?.success) {
|
|
156
|
-
spinner.fail(chalk.hex('#EF5350')(`Error: ${linkRes.data?.message || 'No se pudo generar el link'}`));
|
|
157
|
-
const { tryManual } = await (inquirer as any).prompt([{
|
|
158
|
-
type: 'confirm', name: 'tryManual',
|
|
159
|
-
message: 'Deseas ingresar el numero manualmente?', default: false,
|
|
160
|
-
}]);
|
|
161
|
-
if (tryManual) {
|
|
162
|
-
const { key } = await (inquirer as any).prompt([
|
|
163
|
-
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
164
|
-
]);
|
|
165
|
-
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
166
|
-
}
|
|
167
|
-
const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Conectar otro canal?', default: false }]);
|
|
168
|
-
addMore = more;
|
|
169
|
-
continue;
|
|
189
|
+
if (selected !== '__new__') {
|
|
190
|
+
// Selecciono una existente
|
|
191
|
+
selectedIntegration = existing.find((ig: any) => ig.id === selected);
|
|
192
|
+
const label = getIntegrationLabel(selectedIntegration);
|
|
193
|
+
channels.push({
|
|
194
|
+
channel: CHANNEL_AGENT_MAP[channelType],
|
|
195
|
+
key: selectedIntegration.id,
|
|
196
|
+
multianswer: false,
|
|
197
|
+
});
|
|
198
|
+
console.log(chalk.hex('#4ade80')(` Canal asociado: ${label}`));
|
|
170
199
|
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Si no hay existentes o eligio "Agregar nuevo" → generar link de onboarding
|
|
203
|
+
if (!selectedIntegration) {
|
|
204
|
+
const spinner = ora({ text: chalk.gray('Generando link de conexion...'), spinner: 'dots', color: 'green' }).start();
|
|
171
205
|
|
|
172
|
-
const shortUrl = linkRes.data.data?.shortUrl || '';
|
|
173
|
-
spinner.stop();
|
|
174
|
-
|
|
175
|
-
// Mostrar link
|
|
176
|
-
console.log();
|
|
177
|
-
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
178
|
-
console.log(chalk.bold(` Envia este link para conectar ${channelLabel}:`));
|
|
179
|
-
console.log();
|
|
180
|
-
console.log(' ' + chalk.hex('#22d3ee')(shortUrl));
|
|
181
|
-
console.log();
|
|
182
|
-
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
183
|
-
console.log();
|
|
184
|
-
|
|
185
|
-
// Snapshot de integraciones actuales
|
|
186
|
-
let prevIntegrationIds: Set<string> = new Set();
|
|
187
206
|
try {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
207
|
+
const linkRes = await axios.post(
|
|
208
|
+
`${baseUrl}/api/workspace/${ctx.workspaceId}/onboarding-link`,
|
|
209
|
+
{ type: channelType },
|
|
210
|
+
{ headers }
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
if (!linkRes.data?.success) {
|
|
214
|
+
spinner.fail(chalk.hex('#EF5350')(`Error: ${linkRes.data?.message || 'No se pudo generar el link'}`));
|
|
215
|
+
} else {
|
|
216
|
+
const shortUrl = linkRes.data.data?.shortUrl || '';
|
|
217
|
+
spinner.stop();
|
|
218
|
+
|
|
219
|
+
// Mostrar link
|
|
220
|
+
console.log();
|
|
221
|
+
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
222
|
+
console.log(chalk.bold(` Envia este link para conectar ${channelLabel}:`));
|
|
223
|
+
console.log();
|
|
224
|
+
console.log(' ' + chalk.hex('#22d3ee')(shortUrl));
|
|
225
|
+
console.log();
|
|
226
|
+
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
227
|
+
console.log();
|
|
228
|
+
|
|
229
|
+
// Guardar IDs actuales para detectar nuevos
|
|
230
|
+
const prevIds = new Set(allIntegrations.map((i: any) => i.id));
|
|
231
|
+
|
|
232
|
+
// Polling para detectar nueva integracion (Enter para saltar)
|
|
233
|
+
const pollSpinner = ora({ text: chalk.gray('Esperando conexion... (Enter para saltar)'), spinner: 'dots', color: 'cyan' }).start();
|
|
234
|
+
const POLL_INTERVAL = 5000;
|
|
235
|
+
const MAX_POLLS = 60;
|
|
236
|
+
let detected: any = null;
|
|
237
|
+
let skipped = false;
|
|
238
|
+
|
|
239
|
+
// Escuchar Enter para saltar
|
|
240
|
+
const skipPromise = new Promise<void>(resolve => {
|
|
241
|
+
const onData = (data: Buffer) => {
|
|
242
|
+
if (data.toString().includes('\n') || data.toString().includes('\r')) {
|
|
243
|
+
skipped = true;
|
|
244
|
+
process.stdin.removeListener('data', onData);
|
|
245
|
+
if (wasRaw) process.stdin.setRawMode(false);
|
|
246
|
+
resolve();
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
const wasRaw = process.stdin.isRaw;
|
|
250
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(true);
|
|
251
|
+
process.stdin.resume();
|
|
252
|
+
process.stdin.on('data', onData);
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
process.stdin.removeListener('data', onData);
|
|
255
|
+
if (process.stdin.isTTY && wasRaw !== undefined) {
|
|
256
|
+
try { process.stdin.setRawMode(wasRaw); } catch {}
|
|
257
|
+
}
|
|
258
|
+
resolve();
|
|
259
|
+
}, POLL_INTERVAL * MAX_POLLS + 1000);
|
|
260
|
+
});
|
|
196
261
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const wasRaw = process.stdin.isRaw;
|
|
215
|
-
if (process.stdin.isTTY) process.stdin.setRawMode(true);
|
|
216
|
-
process.stdin.resume();
|
|
217
|
-
process.stdin.on('data', onData);
|
|
218
|
-
// Limpiar si termina el polling naturalmente
|
|
219
|
-
setTimeout(() => {
|
|
220
|
-
process.stdin.removeListener('data', onData);
|
|
221
|
-
if (process.stdin.isTTY && wasRaw !== undefined) {
|
|
222
|
-
try { process.stdin.setRawMode(wasRaw); } catch {}
|
|
223
|
-
}
|
|
224
|
-
resolve();
|
|
225
|
-
}, POLL_INTERVAL * MAX_POLLS + 1000);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
for (let i = 0; i < MAX_POLLS; i++) {
|
|
229
|
-
await Promise.race([
|
|
230
|
-
new Promise(r => setTimeout(r, POLL_INTERVAL)),
|
|
231
|
-
skipPromise,
|
|
232
|
-
]);
|
|
233
|
-
if (skipped) break;
|
|
234
|
-
try {
|
|
235
|
-
const wkRes = await axios.get(`${baseUrl}/api/workspace/${ctx.workspaceId}`, { headers });
|
|
236
|
-
// La API retorna un array [{ integrations: [...] }]
|
|
237
|
-
const wsData = Array.isArray(wkRes.data) ? wkRes.data[0] : wkRes.data;
|
|
238
|
-
const integrations = wsData?.integrations || [];
|
|
239
|
-
|
|
240
|
-
// Buscar integraciones nuevas (cualquier ID que no existia antes)
|
|
241
|
-
const newOnes = integrations.filter((ig: any) => !prevIntegrationIds.has(ig.id));
|
|
242
|
-
|
|
243
|
-
if (newOnes.length > 0) {
|
|
244
|
-
// Preferir la que coincida con el tipo solicitado
|
|
245
|
-
const targetType = channelType === 'whatsapp_business' ? 'whatsapp' : channelType;
|
|
246
|
-
const matchingNew = newOnes.find((ig: any) => ig.type === targetType);
|
|
247
|
-
detected = matchingNew || newOnes[0];
|
|
248
|
-
break;
|
|
262
|
+
for (let i = 0; i < MAX_POLLS; i++) {
|
|
263
|
+
await Promise.race([
|
|
264
|
+
new Promise(r => setTimeout(r, POLL_INTERVAL)),
|
|
265
|
+
skipPromise,
|
|
266
|
+
]);
|
|
267
|
+
if (skipped) break;
|
|
268
|
+
try {
|
|
269
|
+
const freshIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
|
|
270
|
+
const newOnes = freshIntegrations.filter((ig: any) => !prevIds.has(ig.id));
|
|
271
|
+
if (newOnes.length > 0) {
|
|
272
|
+
const match = newOnes.find((ig: any) => ig.type === targetType);
|
|
273
|
+
detected = match || newOnes[0];
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
} catch {}
|
|
277
|
+
const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
|
|
278
|
+
pollSpinner.text = chalk.gray(`Esperando conexion... ${elapsed}s (Enter para saltar)`);
|
|
249
279
|
}
|
|
250
|
-
} catch {
|
|
251
|
-
// Ignorar errores de poll individual
|
|
252
|
-
}
|
|
253
|
-
const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
|
|
254
|
-
pollSpinner.text = chalk.gray(`Esperando conexion... ${elapsed}s (Enter para saltar)`);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (detected) {
|
|
258
|
-
const detectedName = detected.aliasName || detected.cellphoneNumberFormat || detected.cellphoneNumber || detected.srcName || detected.id;
|
|
259
|
-
pollSpinner.succeed(chalk.hex('#4ade80')(`Conexion detectada: ${detectedName} (${channelLabel})`));
|
|
260
|
-
|
|
261
|
-
const { associate } = await (inquirer as any).prompt([{
|
|
262
|
-
type: 'confirm', name: 'associate',
|
|
263
|
-
message: 'Deseas asociar este canal al agente?', default: true,
|
|
264
|
-
}]);
|
|
265
280
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
281
|
+
if (detected) {
|
|
282
|
+
const detectedName = getIntegrationLabel(detected);
|
|
283
|
+
pollSpinner.succeed(chalk.hex('#4ade80')(`Conexion detectada: ${detectedName}`));
|
|
284
|
+
channels.push({
|
|
285
|
+
channel: CHANNEL_AGENT_MAP[channelType],
|
|
286
|
+
key: detected.id,
|
|
287
|
+
multianswer: false,
|
|
288
|
+
});
|
|
289
|
+
console.log(chalk.hex('#4ade80')(' Canal asociado correctamente.'));
|
|
290
|
+
} else {
|
|
291
|
+
pollSpinner.warn(chalk.hex('#FFA726')(skipped ? 'Omitido.' : 'Timeout: no se detecto conexion.'));
|
|
292
|
+
const { action } = await (inquirer as any).prompt([{
|
|
293
|
+
type: 'list', name: 'action',
|
|
294
|
+
message: 'Que deseas hacer?',
|
|
295
|
+
choices: [
|
|
296
|
+
{ name: 'Ingresar ID manualmente', value: 'manual' },
|
|
297
|
+
{ name: 'Saltar', value: 'skip' },
|
|
298
|
+
],
|
|
299
|
+
}]);
|
|
300
|
+
if (action === 'manual') {
|
|
301
|
+
const { key } = await (inquirer as any).prompt([
|
|
302
|
+
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
303
|
+
]);
|
|
304
|
+
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
305
|
+
}
|
|
306
|
+
}
|
|
289
307
|
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
} catch (err) {
|
|
293
|
-
spinner.fail(chalk.hex('#EF5350')(`Error al generar link: ${err instanceof Error ? err.message : err}`));
|
|
294
|
-
const { tryManual } = await (inquirer as any).prompt([{
|
|
295
|
-
type: 'confirm', name: 'tryManual',
|
|
296
|
-
message: 'Deseas ingresar el numero manualmente?', default: false,
|
|
297
|
-
}]);
|
|
298
|
-
if (tryManual) {
|
|
299
|
-
const { key } = await (inquirer as any).prompt([
|
|
300
|
-
{ type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
301
|
-
]);
|
|
302
|
-
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
308
|
+
} catch (err) {
|
|
309
|
+
spinner.fail(chalk.hex('#EF5350')(`Error: ${err instanceof Error ? err.message : err}`));
|
|
303
310
|
}
|
|
304
311
|
}
|
|
305
312
|
|