plazbot-cli 0.1.2 → 0.1.4
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/.claude/settings.local.json +14 -0
- package/CLAUDE.md +92 -0
- package/README.md +102 -0
- package/dist/cli.js +14 -5
- package/dist/commands/agent/ai-config.js +107 -0
- package/dist/commands/agent/chat.js +130 -34
- package/dist/commands/agent/copy.js +37 -0
- package/dist/commands/agent/create.js +80 -17
- package/dist/commands/agent/files.js +142 -0
- package/dist/commands/agent/index.js +14 -2
- package/dist/commands/agent/set.js +127 -0
- package/dist/commands/agent/templates.js +240 -0
- package/dist/commands/agent/tools.js +161 -0
- package/dist/commands/agent/wizard.js +369 -0
- package/dist/commands/whatsapp/broadcast.js +97 -0
- package/dist/commands/whatsapp/channels.js +86 -0
- package/dist/commands/whatsapp/chat.js +74 -0
- package/dist/commands/whatsapp/index.js +11 -2
- package/dist/commands/whatsapp/send-template.js +51 -14
- package/dist/commands/whatsapp/send.js +10 -10
- package/dist/commands/whatsapp/widget.js +64 -0
- package/dist/utils/banner.js +87 -0
- package/dist/utils/logger.js +27 -6
- package/dist/utils/ui.js +111 -0
- package/package.json +10 -2
- package/src/cli.ts +13 -5
- package/src/commands/agent/ai-config.ts +112 -0
- package/src/commands/agent/chat.ts +149 -40
- package/src/commands/agent/copy.ts +40 -0
- package/src/commands/agent/create.ts +58 -23
- package/src/commands/agent/files.ts +158 -0
- package/src/commands/agent/index.ts +14 -2
- package/src/commands/agent/set.ts +137 -0
- package/src/commands/agent/templates.ts +249 -0
- package/src/commands/agent/tools.ts +167 -0
- package/src/commands/agent/wizard.ts +475 -0
- package/src/commands/whatsapp/broadcast.ts +100 -0
- package/src/commands/whatsapp/channels.ts +98 -0
- package/src/commands/whatsapp/chat.ts +77 -0
- package/src/commands/whatsapp/index.ts +11 -2
- package/src/commands/whatsapp/send-template.ts +57 -19
- package/src/commands/whatsapp/send.ts +15 -14
- package/src/commands/whatsapp/widget.ts +67 -0
- package/src/utils/banner.ts +94 -0
- package/src/utils/logger.ts +26 -7
- package/src/utils/ui.ts +109 -0
- package/dist/commands/message/delete-webhook.js +0 -39
- package/dist/commands/message/index.js +0 -14
- package/dist/commands/message/register-webhook.js +0 -42
- package/dist/commands/message/send-template.js +0 -42
- package/dist/commands/message/send.js +0 -42
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Agent } from 'plazbot';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { getStoredCredentials } from '../../utils/credentials';
|
|
5
|
+
import { logger } from '../../utils/logger';
|
|
6
|
+
import { createSpinner, createTable, theme, section, kvPair, statusBadge } from '../../utils/ui';
|
|
7
|
+
import { AgentCommandOptions } from '../../types/agent';
|
|
8
|
+
|
|
9
|
+
export const toolsCommand = new Command('tools')
|
|
10
|
+
.description('Gestionar herramientas de Tool Calling del agente')
|
|
11
|
+
.argument('<agentId>', 'ID del agente')
|
|
12
|
+
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
13
|
+
.action(async (agentId: string, options: AgentCommandOptions) => {
|
|
14
|
+
try {
|
|
15
|
+
const credentials = await getStoredCredentials();
|
|
16
|
+
const agent = new Agent({
|
|
17
|
+
workspaceId: credentials.workspace,
|
|
18
|
+
apiKey: credentials.apiKey,
|
|
19
|
+
zone: credentials.zone,
|
|
20
|
+
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const spinner = createSpinner('Cargando agente...');
|
|
24
|
+
spinner.start();
|
|
25
|
+
const agentData = await agent.getAgentById({ id: agentId });
|
|
26
|
+
spinner.stop();
|
|
27
|
+
|
|
28
|
+
console.log(section('Tool Calling - ' + (agentData.name || agentId)));
|
|
29
|
+
console.log(kvPair('Estado', agentData.useToolCalling ? theme.success('Activado') : theme.error('Desactivado')));
|
|
30
|
+
|
|
31
|
+
// Servicios
|
|
32
|
+
const services = agentData.services || [];
|
|
33
|
+
if (services.length > 0) {
|
|
34
|
+
console.log(section('Servicios (API calls)'));
|
|
35
|
+
const rows = services.map((s: any) => [
|
|
36
|
+
s.intent,
|
|
37
|
+
s.method || 'POST',
|
|
38
|
+
s.endpoint ? s.endpoint.substring(0, 40) + '...' : 'N/A',
|
|
39
|
+
statusBadge(s.enabled !== false),
|
|
40
|
+
]);
|
|
41
|
+
console.log(createTable(['Intent', 'Method', 'Endpoint', 'Estado'], rows));
|
|
42
|
+
} else {
|
|
43
|
+
console.log(theme.muted('\n No hay servicios configurados'));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Acciones
|
|
47
|
+
const actions = agentData.actions || [];
|
|
48
|
+
if (actions.length > 0) {
|
|
49
|
+
console.log(section('Acciones'));
|
|
50
|
+
const rows = actions.map((a: any) => [
|
|
51
|
+
a.intent,
|
|
52
|
+
(a.action || []).map((ac: any) => ac.type).join(', '),
|
|
53
|
+
statusBadge(a.enabled !== false),
|
|
54
|
+
]);
|
|
55
|
+
console.log(createTable(['Intent', 'Tipo', 'Estado'], rows));
|
|
56
|
+
} else {
|
|
57
|
+
console.log(theme.muted('\n No hay acciones configuradas'));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Menu de opciones
|
|
61
|
+
console.log();
|
|
62
|
+
const { action } = await (inquirer as any).prompt([{
|
|
63
|
+
type: 'list',
|
|
64
|
+
name: 'action',
|
|
65
|
+
message: 'Que deseas hacer?',
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: 'Agregar servicio (API call)', value: 'add-service' },
|
|
68
|
+
{ name: 'Agregar accion', value: 'add-action' },
|
|
69
|
+
{ name: agentData.useToolCalling ? 'Desactivar Tool Calling' : 'Activar Tool Calling', value: 'toggle' },
|
|
70
|
+
{ name: 'Salir', value: 'exit' },
|
|
71
|
+
],
|
|
72
|
+
}]);
|
|
73
|
+
|
|
74
|
+
if (action === 'exit') return;
|
|
75
|
+
|
|
76
|
+
if (action === 'toggle') {
|
|
77
|
+
const toggleSpinner = createSpinner('Actualizando...');
|
|
78
|
+
toggleSpinner.start();
|
|
79
|
+
const updatedConfig = { ...agentData, useToolCalling: !agentData.useToolCalling };
|
|
80
|
+
delete updatedConfig.id;
|
|
81
|
+
delete updatedConfig._id;
|
|
82
|
+
await agent.updateAgent(agentId, updatedConfig);
|
|
83
|
+
toggleSpinner.succeed(`Tool Calling ${!agentData.useToolCalling ? 'activado' : 'desactivado'}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (action === 'add-service') {
|
|
88
|
+
const svc = await (inquirer as any).prompt([
|
|
89
|
+
{ type: 'input', name: 'intent', message: 'Nombre/intent del servicio:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
90
|
+
{ type: 'input', name: 'reference', message: 'Palabras clave:', default: '' },
|
|
91
|
+
{ type: 'list', name: 'method', message: 'Metodo HTTP:', choices: ['GET', 'POST'] },
|
|
92
|
+
{ type: 'input', name: 'endpoint', message: 'URL del endpoint:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
93
|
+
{ type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
const newService = {
|
|
97
|
+
intent: svc.intent,
|
|
98
|
+
reference: svc.reference,
|
|
99
|
+
enabled: true,
|
|
100
|
+
method: svc.method,
|
|
101
|
+
endpoint: svc.endpoint,
|
|
102
|
+
requiredFields: [],
|
|
103
|
+
headers: {},
|
|
104
|
+
bodyTemplate: {},
|
|
105
|
+
responseMapping: {},
|
|
106
|
+
responseMessage: svc.responseMessage,
|
|
107
|
+
responseConditions: [],
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const updatedServices = [...services, newService];
|
|
111
|
+
const updatedConfig = { ...agentData, services: updatedServices, useToolCalling: true };
|
|
112
|
+
delete updatedConfig.id;
|
|
113
|
+
delete updatedConfig._id;
|
|
114
|
+
const updateSpinner = createSpinner('Guardando servicio...');
|
|
115
|
+
updateSpinner.start();
|
|
116
|
+
await agent.updateAgent(agentId, updatedConfig);
|
|
117
|
+
updateSpinner.succeed(`Servicio "${svc.intent}" agregado`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (action === 'add-action') {
|
|
121
|
+
const act = await (inquirer as any).prompt([
|
|
122
|
+
{ type: 'input', name: 'intent', message: 'Nombre/intent de la accion:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
123
|
+
{ type: 'input', name: 'reference', message: 'Palabras clave:', default: '' },
|
|
124
|
+
{
|
|
125
|
+
type: 'list', name: 'actionType', message: 'Tipo de accion:',
|
|
126
|
+
choices: [
|
|
127
|
+
{ name: 'Agendar evento', value: 'action.event.add' },
|
|
128
|
+
{ name: 'Actualizar evento (reagendar)', value: 'action.event.update' },
|
|
129
|
+
{ name: 'Listar eventos', value: 'action.event.list' },
|
|
130
|
+
{ name: 'Eliminar evento (cancelar)', value: 'action.event.delete' },
|
|
131
|
+
{ name: 'Agregar tag', value: 'action.tag' },
|
|
132
|
+
{ name: 'Cambiar stage', value: 'action.stage' },
|
|
133
|
+
{ name: 'Derivar a agente humano', value: 'action.agentShutDown' },
|
|
134
|
+
{ name: 'Marcar como resuelto', value: 'action.solved' },
|
|
135
|
+
{ name: 'Asignar agente', value: 'action.asign' },
|
|
136
|
+
{ name: 'Segmentacion', value: 'action.segmentation' },
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
{ type: 'input', name: 'actionValue', message: 'Valor (opcional):', default: '' },
|
|
140
|
+
{ type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
|
|
141
|
+
]);
|
|
142
|
+
|
|
143
|
+
const newAction = {
|
|
144
|
+
intent: act.intent,
|
|
145
|
+
reference: act.reference,
|
|
146
|
+
enabled: true,
|
|
147
|
+
requiredFields: [],
|
|
148
|
+
responseMessage: act.responseMessage,
|
|
149
|
+
action: [{ type: act.actionType, value: act.actionValue }],
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const updatedActions = [...actions, newAction];
|
|
153
|
+
const updatedConfig = { ...agentData, actions: updatedActions, useToolCalling: true };
|
|
154
|
+
delete updatedConfig.id;
|
|
155
|
+
delete updatedConfig._id;
|
|
156
|
+
const updateSpinner = createSpinner('Guardando accion...');
|
|
157
|
+
updateSpinner.start();
|
|
158
|
+
await agent.updateAgent(agentId, updatedConfig);
|
|
159
|
+
updateSpinner.succeed(`Accion "${act.intent}" agregada`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const message = error instanceof Error ? error.message : 'Error desconocido';
|
|
164
|
+
logger.error(message);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { theme, section, kvPair } from '../../utils/ui';
|
|
4
|
+
|
|
5
|
+
interface AgentConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
prompt: string;
|
|
9
|
+
buffer: number;
|
|
10
|
+
zone: string;
|
|
11
|
+
color: string;
|
|
12
|
+
useToolCalling: boolean;
|
|
13
|
+
customAIConfig: boolean;
|
|
14
|
+
aiProviders: AIProvider[];
|
|
15
|
+
instructions: AgentInstructions;
|
|
16
|
+
person: AgentPerson;
|
|
17
|
+
fallbacks: AgentFallbacks;
|
|
18
|
+
services: AgentService[];
|
|
19
|
+
actions: AgentAction[];
|
|
20
|
+
channels: AgentChannel[];
|
|
21
|
+
examples: AgentExample[];
|
|
22
|
+
tags: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface AIProvider {
|
|
26
|
+
provider: string;
|
|
27
|
+
model: string;
|
|
28
|
+
apiToken: string;
|
|
29
|
+
temperature: number;
|
|
30
|
+
maxTokens: number;
|
|
31
|
+
isDefault: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface AgentInstructions {
|
|
35
|
+
tone: string;
|
|
36
|
+
style: string;
|
|
37
|
+
personality: string;
|
|
38
|
+
objective: string;
|
|
39
|
+
language: string;
|
|
40
|
+
emojis: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface AgentPerson {
|
|
44
|
+
name: string;
|
|
45
|
+
role: string;
|
|
46
|
+
speaksInFirstPerson: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface AgentFallbacks {
|
|
50
|
+
noAnswer: string;
|
|
51
|
+
serviceError: string;
|
|
52
|
+
doNotUnderstand: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface AgentService {
|
|
56
|
+
intent: string;
|
|
57
|
+
reference: string;
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
method: string;
|
|
60
|
+
endpoint: string;
|
|
61
|
+
requiredFields: { name: string; type: string; description: string; promptHint: string }[];
|
|
62
|
+
headers: Record<string, string>;
|
|
63
|
+
bodyTemplate: Record<string, string>;
|
|
64
|
+
responseMapping: Record<string, string>;
|
|
65
|
+
responseMessage: string;
|
|
66
|
+
responseConditions: { condition: string; message: string }[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface AgentAction {
|
|
70
|
+
intent: string;
|
|
71
|
+
reference: string;
|
|
72
|
+
enabled: boolean;
|
|
73
|
+
requiredFields: { name: string; type: string; description: string; promptHint: string }[];
|
|
74
|
+
responseMessage: string;
|
|
75
|
+
action: { type: string; value: string }[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface AgentChannel {
|
|
79
|
+
channel: string;
|
|
80
|
+
key: string;
|
|
81
|
+
multianswer: boolean;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface AgentExample {
|
|
85
|
+
value: string;
|
|
86
|
+
color: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const MODELS: Record<string, string[]> = {
|
|
90
|
+
openai: ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo', 'o1-preview', 'o1-mini'],
|
|
91
|
+
claude: ['claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'],
|
|
92
|
+
gemini: ['gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const COLORS = ['blue', 'green', 'orange', 'gray', 'white'];
|
|
96
|
+
|
|
97
|
+
export async function runAgentWizard(zone: string): Promise<AgentConfig> {
|
|
98
|
+
console.log(section('Crear nuevo agente de IA'));
|
|
99
|
+
console.log(theme.muted(' Responde las siguientes preguntas para configurar tu agente.\n'));
|
|
100
|
+
|
|
101
|
+
// Paso 1: Informacion basica
|
|
102
|
+
console.log(theme.bold('\n Paso 1/8: Informacion basica'));
|
|
103
|
+
const basic = await (inquirer as any).prompt([
|
|
104
|
+
{
|
|
105
|
+
type: 'input',
|
|
106
|
+
name: 'name',
|
|
107
|
+
message: 'Nombre del agente:',
|
|
108
|
+
validate: (v: string) => v.length > 0 || 'El nombre es requerido',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
type: 'input',
|
|
112
|
+
name: 'description',
|
|
113
|
+
message: 'Descripcion breve:',
|
|
114
|
+
default: '',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'input',
|
|
118
|
+
name: 'prompt',
|
|
119
|
+
message: 'Prompt del sistema (instrucciones principales):',
|
|
120
|
+
default: 'Eres un asistente virtual amigable y profesional.',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
type: 'number',
|
|
124
|
+
name: 'buffer',
|
|
125
|
+
message: 'Buffer de conversacion (3-20 mensajes):',
|
|
126
|
+
default: 5,
|
|
127
|
+
validate: (v: number) => (v >= 3 && v <= 20) || 'Debe ser entre 3 y 20',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: 'list',
|
|
131
|
+
name: 'color',
|
|
132
|
+
message: 'Color del agente:',
|
|
133
|
+
choices: COLORS,
|
|
134
|
+
default: 'blue',
|
|
135
|
+
},
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
// Paso 2: Personalidad
|
|
139
|
+
console.log(theme.bold('\n Paso 2/8: Personalidad e instrucciones'));
|
|
140
|
+
const personality = await (inquirer as any).prompt([
|
|
141
|
+
{
|
|
142
|
+
type: 'list',
|
|
143
|
+
name: 'tone',
|
|
144
|
+
message: 'Tono de comunicacion:',
|
|
145
|
+
choices: ['profesional', 'amigable', 'formal', 'casual', 'tecnico', 'empatico'],
|
|
146
|
+
default: 'profesional',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'list',
|
|
150
|
+
name: 'style',
|
|
151
|
+
message: 'Estilo de respuesta:',
|
|
152
|
+
choices: ['conciso', 'detallado', 'conversacional', 'directo'],
|
|
153
|
+
default: 'conciso',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: 'input',
|
|
157
|
+
name: 'personality',
|
|
158
|
+
message: 'Personalidad en una frase:',
|
|
159
|
+
default: 'Servicial y conocedor',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: 'input',
|
|
163
|
+
name: 'objective',
|
|
164
|
+
message: 'Objetivo principal del agente:',
|
|
165
|
+
default: 'Ayudar a los usuarios con sus consultas',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: 'list',
|
|
169
|
+
name: 'language',
|
|
170
|
+
message: 'Idioma principal:',
|
|
171
|
+
choices: ['Espanol', 'English', 'Portugues', 'Frances'],
|
|
172
|
+
default: 'Espanol',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'confirm',
|
|
176
|
+
name: 'useEmojis',
|
|
177
|
+
message: 'Usar emojis en respuestas?',
|
|
178
|
+
default: true,
|
|
179
|
+
},
|
|
180
|
+
]);
|
|
181
|
+
|
|
182
|
+
// Paso 3: Persona
|
|
183
|
+
console.log(theme.bold('\n Paso 3/8: Identidad del agente'));
|
|
184
|
+
const person = await (inquirer as any).prompt([
|
|
185
|
+
{
|
|
186
|
+
type: 'input',
|
|
187
|
+
name: 'name',
|
|
188
|
+
message: 'Nombre del personaje (como se presenta):',
|
|
189
|
+
default: basic.name,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
type: 'input',
|
|
193
|
+
name: 'role',
|
|
194
|
+
message: 'Rol (ej: Asistente de ventas, Soporte tecnico):',
|
|
195
|
+
default: 'Asistente virtual',
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
type: 'confirm',
|
|
199
|
+
name: 'firstPerson',
|
|
200
|
+
message: 'Hablar en primera persona?',
|
|
201
|
+
default: true,
|
|
202
|
+
},
|
|
203
|
+
]);
|
|
204
|
+
|
|
205
|
+
// Paso 4: Fallbacks
|
|
206
|
+
console.log(theme.bold('\n Paso 4/8: Mensajes de fallback'));
|
|
207
|
+
const fallbacks = await (inquirer as any).prompt([
|
|
208
|
+
{
|
|
209
|
+
type: 'input',
|
|
210
|
+
name: 'noAnswer',
|
|
211
|
+
message: 'Cuando no tiene respuesta:',
|
|
212
|
+
default: 'Lo siento, no tengo informacion sobre eso. Puedo ayudarte con otra consulta?',
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'input',
|
|
216
|
+
name: 'serviceError',
|
|
217
|
+
message: 'Cuando hay error de servicio:',
|
|
218
|
+
default: 'Disculpa, estamos experimentando dificultades tecnicas. Intenta de nuevo en unos momentos.',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
type: 'input',
|
|
222
|
+
name: 'misunderstanding',
|
|
223
|
+
message: 'Cuando no entiende la pregunta:',
|
|
224
|
+
default: 'No estoy seguro de entender tu consulta. Podrias reformularla?',
|
|
225
|
+
},
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
// Paso 5: Tool Calling
|
|
229
|
+
console.log(theme.bold('\n Paso 5/8: Tool Calling'));
|
|
230
|
+
console.log(theme.muted(' Tool Calling permite al agente ejecutar acciones automaticas\n'));
|
|
231
|
+
const { useToolCalling } = await (inquirer as any).prompt([
|
|
232
|
+
{
|
|
233
|
+
type: 'confirm',
|
|
234
|
+
name: 'useToolCalling',
|
|
235
|
+
message: 'Activar Tool Calling?',
|
|
236
|
+
default: true,
|
|
237
|
+
},
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
// Servicios (API calls)
|
|
241
|
+
const services: AgentService[] = [];
|
|
242
|
+
if (useToolCalling) {
|
|
243
|
+
const { addServices } = await (inquirer as any).prompt([{
|
|
244
|
+
type: 'confirm',
|
|
245
|
+
name: 'addServices',
|
|
246
|
+
message: 'Agregar servicios externos (API calls)?',
|
|
247
|
+
default: false,
|
|
248
|
+
}]);
|
|
249
|
+
|
|
250
|
+
if (addServices) {
|
|
251
|
+
let addMore = true;
|
|
252
|
+
while (addMore) {
|
|
253
|
+
console.log(theme.muted('\n Nuevo servicio:'));
|
|
254
|
+
const svc = await (inquirer as any).prompt([
|
|
255
|
+
{ type: 'input', name: 'intent', message: 'Nombre/intent del servicio:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
256
|
+
{ type: 'input', name: 'reference', message: 'Palabras clave de referencia:', default: '' },
|
|
257
|
+
{ type: 'list', name: 'method', message: 'Metodo HTTP:', choices: ['GET', 'POST'] },
|
|
258
|
+
{ type: 'input', name: 'endpoint', message: 'URL del endpoint:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
259
|
+
{ type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
|
|
260
|
+
]);
|
|
261
|
+
|
|
262
|
+
// Required fields
|
|
263
|
+
const fields: AgentService['requiredFields'] = [];
|
|
264
|
+
const { addFields } = await (inquirer as any).prompt([{
|
|
265
|
+
type: 'confirm', name: 'addFields',
|
|
266
|
+
message: 'Agregar campos requeridos?', default: false,
|
|
267
|
+
}]);
|
|
268
|
+
if (addFields) {
|
|
269
|
+
let moreFields = true;
|
|
270
|
+
while (moreFields) {
|
|
271
|
+
const field = await (inquirer as any).prompt([
|
|
272
|
+
{ type: 'input', name: 'name', message: 'Nombre del campo:' },
|
|
273
|
+
{ type: 'list', name: 'type', message: 'Tipo:', choices: ['string', 'number', 'boolean', 'date'] },
|
|
274
|
+
{ type: 'input', name: 'description', message: 'Descripcion:' },
|
|
275
|
+
{ type: 'input', name: 'promptHint', message: 'Hint para el LLM:' },
|
|
276
|
+
]);
|
|
277
|
+
fields.push(field);
|
|
278
|
+
const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro campo?', default: false }]);
|
|
279
|
+
moreFields = more;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
services.push({
|
|
284
|
+
intent: svc.intent,
|
|
285
|
+
reference: svc.reference,
|
|
286
|
+
enabled: true,
|
|
287
|
+
method: svc.method,
|
|
288
|
+
endpoint: svc.endpoint,
|
|
289
|
+
requiredFields: fields,
|
|
290
|
+
headers: {},
|
|
291
|
+
bodyTemplate: {},
|
|
292
|
+
responseMapping: {},
|
|
293
|
+
responseMessage: svc.responseMessage,
|
|
294
|
+
responseConditions: [],
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro servicio?', default: false }]);
|
|
298
|
+
addMore = more;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Acciones
|
|
304
|
+
const actions: AgentAction[] = [];
|
|
305
|
+
if (useToolCalling) {
|
|
306
|
+
const { addActions } = await (inquirer as any).prompt([{
|
|
307
|
+
type: 'confirm',
|
|
308
|
+
name: 'addActions',
|
|
309
|
+
message: 'Agregar acciones (tag, stage, asignar agente)?',
|
|
310
|
+
default: false,
|
|
311
|
+
}]);
|
|
312
|
+
|
|
313
|
+
if (addActions) {
|
|
314
|
+
let addMore = true;
|
|
315
|
+
while (addMore) {
|
|
316
|
+
console.log(theme.muted('\n Nueva accion:'));
|
|
317
|
+
const act = await (inquirer as any).prompt([
|
|
318
|
+
{ type: 'input', name: 'intent', message: 'Nombre/intent de la accion:', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
319
|
+
{ type: 'input', name: 'reference', message: 'Palabras clave de referencia:', default: '' },
|
|
320
|
+
{
|
|
321
|
+
type: 'list', name: 'actionType', message: 'Tipo de accion:',
|
|
322
|
+
choices: [
|
|
323
|
+
{ name: 'Agendar evento', value: 'action.event.add' },
|
|
324
|
+
{ name: 'Actualizar evento (reagendar)', value: 'action.event.update' },
|
|
325
|
+
{ name: 'Listar eventos', value: 'action.event.list' },
|
|
326
|
+
{ name: 'Eliminar evento (cancelar)', value: 'action.event.delete' },
|
|
327
|
+
{ name: 'Agregar tag', value: 'action.tag' },
|
|
328
|
+
{ name: 'Cambiar stage', value: 'action.stage' },
|
|
329
|
+
{ name: 'Derivar a agente humano', value: 'action.agentShutDown' },
|
|
330
|
+
{ name: 'Marcar como resuelto', value: 'action.solved' },
|
|
331
|
+
{ name: 'Asignar agente', value: 'action.asign' },
|
|
332
|
+
{ name: 'Segmentacion', value: 'action.segmentation' },
|
|
333
|
+
],
|
|
334
|
+
},
|
|
335
|
+
{ type: 'input', name: 'actionValue', message: 'Valor de la accion:', default: '' },
|
|
336
|
+
{ type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
|
|
337
|
+
]);
|
|
338
|
+
|
|
339
|
+
actions.push({
|
|
340
|
+
intent: act.intent,
|
|
341
|
+
reference: act.reference,
|
|
342
|
+
enabled: true,
|
|
343
|
+
requiredFields: [],
|
|
344
|
+
responseMessage: act.responseMessage,
|
|
345
|
+
action: [{ type: act.actionType, value: act.actionValue }],
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otra accion?', default: false }]);
|
|
349
|
+
addMore = more;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Paso 6: AI Provider
|
|
355
|
+
console.log(theme.bold('\n Paso 6/8: Proveedor de IA'));
|
|
356
|
+
const { configureAI } = await (inquirer as any).prompt([{
|
|
357
|
+
type: 'confirm',
|
|
358
|
+
name: 'configureAI',
|
|
359
|
+
message: 'Configurar proveedor de IA personalizado?',
|
|
360
|
+
default: false,
|
|
361
|
+
}]);
|
|
362
|
+
|
|
363
|
+
const aiProviders: AIProvider[] = [];
|
|
364
|
+
if (configureAI) {
|
|
365
|
+
const ai = await (inquirer as any).prompt([
|
|
366
|
+
{ type: 'list', name: 'provider', message: 'Proveedor:', choices: ['openai', 'claude', 'gemini'] },
|
|
367
|
+
]);
|
|
368
|
+
const models = MODELS[ai.provider] || MODELS.openai;
|
|
369
|
+
const aiConfig = await (inquirer as any).prompt([
|
|
370
|
+
{ type: 'list', name: 'model', message: 'Modelo:', choices: models },
|
|
371
|
+
{ type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
372
|
+
{ type: 'number', name: 'temperature', message: 'Temperatura (0-2):', default: 0.7 },
|
|
373
|
+
{ type: 'number', name: 'maxTokens', message: 'Max tokens (1024-16384):', default: 4096 },
|
|
374
|
+
]);
|
|
375
|
+
|
|
376
|
+
aiProviders.push({
|
|
377
|
+
provider: ai.provider,
|
|
378
|
+
model: aiConfig.model,
|
|
379
|
+
apiToken: aiConfig.apiToken,
|
|
380
|
+
temperature: aiConfig.temperature,
|
|
381
|
+
maxTokens: aiConfig.maxTokens,
|
|
382
|
+
isDefault: true,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Paso 7: Canal WhatsApp
|
|
387
|
+
console.log(theme.bold('\n Paso 7/8: Canal WhatsApp'));
|
|
388
|
+
const channels: AgentChannel[] = [];
|
|
389
|
+
const { addWhatsApp } = await (inquirer as any).prompt([{
|
|
390
|
+
type: 'confirm',
|
|
391
|
+
name: 'addWhatsApp',
|
|
392
|
+
message: 'Conectar a un numero de WhatsApp?',
|
|
393
|
+
default: false,
|
|
394
|
+
}]);
|
|
395
|
+
|
|
396
|
+
if (addWhatsApp) {
|
|
397
|
+
const wa = await (inquirer as any).prompt([
|
|
398
|
+
{ type: 'input', name: 'key', message: 'Numero de WhatsApp (con codigo de pais):', validate: (v: string) => v.length > 0 || 'Requerido' },
|
|
399
|
+
{ type: 'confirm', name: 'multianswer', message: 'Permitir multiples respuestas?', default: false },
|
|
400
|
+
]);
|
|
401
|
+
channels.push({ channel: 'whatsapp', key: wa.key, multianswer: wa.multianswer });
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Paso 8: Ejemplos
|
|
405
|
+
console.log(theme.bold('\n Paso 8/8: Ejemplos de conversacion'));
|
|
406
|
+
const examples: AgentExample[] = [];
|
|
407
|
+
const { addExamples } = await (inquirer as any).prompt([{
|
|
408
|
+
type: 'confirm',
|
|
409
|
+
name: 'addExamples',
|
|
410
|
+
message: 'Agregar ejemplos de conversacion?',
|
|
411
|
+
default: false,
|
|
412
|
+
}]);
|
|
413
|
+
|
|
414
|
+
if (addExamples) {
|
|
415
|
+
let addMore = true;
|
|
416
|
+
while (addMore) {
|
|
417
|
+
const ex = await (inquirer as any).prompt([
|
|
418
|
+
{ type: 'input', name: 'user', message: 'Mensaje del usuario:' },
|
|
419
|
+
{ type: 'input', name: 'agent', message: 'Respuesta del agente:' },
|
|
420
|
+
]);
|
|
421
|
+
examples.push({ value: `Usuario: ${ex.user}\nAgente: ${ex.agent}`, color: 'blue' });
|
|
422
|
+
const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro ejemplo?', default: false }]);
|
|
423
|
+
addMore = more;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Armar config final (alineado con agent.config.schema.json del backend)
|
|
428
|
+
const config: AgentConfig = {
|
|
429
|
+
name: basic.name,
|
|
430
|
+
description: basic.description || '',
|
|
431
|
+
prompt: basic.prompt,
|
|
432
|
+
buffer: basic.buffer,
|
|
433
|
+
zone,
|
|
434
|
+
color: basic.color,
|
|
435
|
+
useToolCalling,
|
|
436
|
+
customAIConfig: configureAI,
|
|
437
|
+
aiProviders,
|
|
438
|
+
instructions: {
|
|
439
|
+
tone: personality.tone,
|
|
440
|
+
style: personality.style,
|
|
441
|
+
personality: personality.personality,
|
|
442
|
+
objective: personality.objective,
|
|
443
|
+
language: personality.language,
|
|
444
|
+
emojis: personality.useEmojis,
|
|
445
|
+
},
|
|
446
|
+
person: {
|
|
447
|
+
name: person.name,
|
|
448
|
+
role: person.role,
|
|
449
|
+
speaksInFirstPerson: person.firstPerson,
|
|
450
|
+
},
|
|
451
|
+
fallbacks: {
|
|
452
|
+
noAnswer: fallbacks.noAnswer,
|
|
453
|
+
serviceError: fallbacks.serviceError,
|
|
454
|
+
doNotUnderstand: fallbacks.misunderstanding,
|
|
455
|
+
},
|
|
456
|
+
services,
|
|
457
|
+
actions,
|
|
458
|
+
channels,
|
|
459
|
+
examples,
|
|
460
|
+
tags: [],
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// Preview
|
|
464
|
+
console.log(section('Vista previa de la configuracion'));
|
|
465
|
+
console.log(kvPair('Nombre', config.name));
|
|
466
|
+
console.log(kvPair('Prompt', config.prompt.substring(0, 80) + '...'));
|
|
467
|
+
console.log(kvPair('Tool Calling', config.useToolCalling ? 'Activado' : 'Desactivado'));
|
|
468
|
+
console.log(kvPair('Servicios', String(config.services.length)));
|
|
469
|
+
console.log(kvPair('Acciones', String(config.actions.length)));
|
|
470
|
+
console.log(kvPair('AI Provider', config.customAIConfig ? config.aiProviders[0]?.provider + ' / ' + config.aiProviders[0]?.model : 'Default (Plazbot)'));
|
|
471
|
+
console.log(kvPair('Canal WhatsApp', config.channels.length > 0 ? config.channels[0].key : 'No configurado'));
|
|
472
|
+
console.log();
|
|
473
|
+
|
|
474
|
+
return config;
|
|
475
|
+
}
|