plazbot-cli 0.2.26 → 0.3.2
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.md +34 -5
- package/README.md +21 -0
- package/dist/cli.js +32 -20
- package/dist/commands/agent/ai-config.js +98 -50
- package/dist/commands/agent/chat.js +80 -74
- package/dist/commands/agent/copy.js +23 -21
- package/dist/commands/agent/create.js +42 -72
- package/dist/commands/agent/delete.js +29 -30
- package/dist/commands/agent/enable-widget.js +30 -26
- package/dist/commands/agent/export.js +90 -77
- package/dist/commands/agent/files.js +68 -60
- package/dist/commands/agent/get.js +101 -87
- package/dist/commands/agent/index.js +53 -39
- package/dist/commands/agent/list.js +26 -24
- package/dist/commands/agent/monitor.js +91 -86
- package/dist/commands/agent/on-message.js +40 -37
- package/dist/commands/agent/set.js +62 -59
- package/dist/commands/agent/templates.js +109 -108
- package/dist/commands/agent/tools.js +64 -65
- package/dist/commands/agent/update.js +28 -27
- package/dist/commands/agent/validate.js +127 -0
- package/dist/commands/agent/wizard.js +152 -159
- package/dist/commands/auth/index.js +7 -10
- package/dist/commands/auth/login.js +50 -37
- package/dist/commands/auth/logout.js +16 -14
- package/dist/commands/auth/status.js +19 -16
- package/dist/commands/portal/add-agent.js +26 -24
- package/dist/commands/portal/add-link.js +21 -17
- package/dist/commands/portal/clear-links.js +17 -15
- package/dist/commands/portal/create.js +25 -21
- package/dist/commands/portal/delete.js +31 -30
- package/dist/commands/portal/get.js +33 -31
- package/dist/commands/portal/index.js +30 -22
- package/dist/commands/portal/list.js +34 -30
- package/dist/commands/portal/update.js +41 -33
- package/dist/commands/whatsapp/broadcast.js +40 -37
- package/dist/commands/whatsapp/channels.js +40 -34
- package/dist/commands/whatsapp/chat.js +33 -32
- package/dist/commands/whatsapp/connect.js +53 -52
- package/dist/commands/whatsapp/delete-webhook.js +19 -17
- package/dist/commands/whatsapp/index.js +35 -25
- package/dist/commands/whatsapp/register-webhook.js +21 -19
- package/dist/commands/whatsapp/send-template.js +39 -31
- package/dist/commands/whatsapp/send.js +27 -23
- package/dist/commands/whatsapp/widget.js +35 -31
- package/dist/commands/workers/deploy.js +49 -44
- package/dist/commands/workers/index.js +28 -18
- package/dist/commands/workers/list.js +43 -35
- package/dist/commands/workers/logs.js +38 -32
- package/dist/commands/workers/remove.js +38 -37
- package/dist/commands/workers/secret.js +63 -58
- package/dist/commands/workers/test.js +44 -36
- package/dist/schemas/agent.config.schema.json +569 -0
- package/dist/studio/api/sseClient.js +97 -0
- package/dist/studio/api/studioApi.js +25 -0
- package/dist/studio/api/types.js +16 -0
- package/dist/studio/components/AgentPanel.js +35 -0
- package/dist/studio/components/App.js +214 -0
- package/dist/studio/components/ChatLog.js +59 -0
- package/dist/studio/components/Footer.js +11 -0
- package/dist/studio/components/Header.js +8 -0
- package/dist/studio/components/Input.js +15 -0
- package/dist/studio/components/Message.js +56 -0
- package/dist/studio/components/Suggestions.js +11 -0
- package/dist/studio/components/ToolCall.js +33 -0
- package/dist/studio/components/WhatsappConnectCard.js +57 -0
- package/dist/studio/index.js +42 -0
- package/dist/studio/render/json.js +16 -0
- package/dist/studio/render/markdown.js +86 -0
- package/dist/studio/render/steps.js +58 -0
- package/dist/studio/runOneShot.js +96 -0
- package/dist/studio/runRepl.js +52 -0
- package/dist/studio/slash/handlers.js +199 -0
- package/dist/studio/slash/parser.js +46 -0
- package/dist/studio/slash/registry.js +16 -0
- package/dist/studio/state/store.js +181 -0
- package/dist/studio/whatsapp/api.js +63 -0
- package/dist/studio/whatsapp/polling.js +77 -0
- package/dist/studio/whatsapp/types.js +31 -0
- package/dist/types/agent.js +1 -2
- package/dist/types/auth.js +1 -2
- package/dist/types/common.js +1 -2
- package/dist/types/message.js +1 -2
- package/dist/types/portal.js +1 -2
- package/dist/types/workers.js +1 -2
- package/dist/utils/agent-errors.js +46 -0
- package/dist/utils/api.js +8 -9
- package/dist/utils/banner.js +33 -34
- package/dist/utils/credentials.js +12 -20
- package/dist/utils/help.js +44 -0
- package/dist/utils/logger.js +13 -19
- package/dist/utils/ui.js +35 -49
- package/package.json +22 -10
- package/src/cli.ts +24 -8
- package/src/commands/agent/ai-config.ts +89 -34
- package/src/commands/agent/chat.ts +49 -37
- package/src/commands/agent/copy.ts +19 -13
- package/src/commands/agent/create.ts +32 -22
- package/src/commands/agent/delete.ts +24 -18
- package/src/commands/agent/enable-widget.ts +31 -23
- package/src/commands/agent/export.ts +72 -51
- package/src/commands/agent/files.ts +51 -39
- package/src/commands/agent/get.ts +86 -66
- package/src/commands/agent/index.ts +36 -18
- package/src/commands/agent/list.ts +22 -16
- package/src/commands/agent/monitor.ts +67 -56
- package/src/commands/agent/on-message.ts +36 -27
- package/src/commands/agent/set.ts +47 -37
- package/src/commands/agent/templates.ts +90 -82
- package/src/commands/agent/tools.ts +53 -47
- package/src/commands/agent/update.ts +28 -20
- package/src/commands/agent/validate.ts +135 -0
- package/src/commands/agent/wizard.ts +114 -114
- package/src/commands/auth/index.ts +3 -3
- package/src/commands/auth/login.ts +44 -29
- package/src/commands/auth/logout.ts +16 -10
- package/src/commands/auth/status.ts +14 -8
- package/src/commands/portal/add-agent.ts +23 -17
- package/src/commands/portal/add-link.ts +17 -9
- package/src/commands/portal/clear-links.ts +13 -7
- package/src/commands/portal/create.ts +20 -12
- package/src/commands/portal/delete.ts +28 -20
- package/src/commands/portal/get.ts +25 -19
- package/src/commands/portal/index.ts +22 -10
- package/src/commands/portal/list.ts +27 -19
- package/src/commands/portal/update.ts +38 -26
- package/src/commands/whatsapp/broadcast.ts +28 -18
- package/src/commands/whatsapp/channels.ts +31 -20
- package/src/commands/whatsapp/chat.ts +20 -12
- package/src/commands/whatsapp/connect.ts +39 -31
- package/src/commands/whatsapp/delete-webhook.ts +15 -9
- package/src/commands/whatsapp/index.ts +24 -10
- package/src/commands/whatsapp/register-webhook.ts +16 -10
- package/src/commands/whatsapp/send-template.ts +33 -21
- package/src/commands/whatsapp/send.ts +23 -15
- package/src/commands/whatsapp/widget.ts +25 -17
- package/src/commands/workers/deploy.ts +34 -22
- package/src/commands/workers/index.ts +21 -7
- package/src/commands/workers/list.ts +31 -19
- package/src/commands/workers/logs.ts +30 -20
- package/src/commands/workers/remove.ts +30 -22
- package/src/commands/workers/secret.ts +46 -34
- package/src/commands/workers/test.ts +34 -22
- package/src/schemas/agent.config.schema.json +569 -0
- package/src/studio/api/sseClient.ts +91 -0
- package/src/studio/api/studioApi.ts +27 -0
- package/src/studio/api/types.ts +96 -0
- package/src/studio/components/App.tsx +266 -0
- package/src/studio/components/ChatLog.tsx +95 -0
- package/src/studio/components/Footer.tsx +38 -0
- package/src/studio/components/Header.tsx +39 -0
- package/src/studio/components/Input.tsx +32 -0
- package/src/studio/components/Message.tsx +87 -0
- package/src/studio/components/Suggestions.tsx +26 -0
- package/src/studio/components/ToolCall.tsx +58 -0
- package/src/studio/components/WhatsappConnectCard.tsx +139 -0
- package/src/studio/index.ts +58 -0
- package/src/studio/render/markdown.ts +93 -0
- package/src/studio/render/steps.ts +57 -0
- package/src/studio/runOneShot.ts +114 -0
- package/src/studio/runRepl.tsx +76 -0
- package/src/studio/slash/handlers.ts +226 -0
- package/src/studio/slash/parser.ts +41 -0
- package/src/studio/slash/registry.ts +54 -0
- package/src/studio/state/store.ts +273 -0
- package/src/studio/whatsapp/api.ts +96 -0
- package/src/studio/whatsapp/polling.ts +93 -0
- package/src/studio/whatsapp/types.ts +80 -0
- package/src/types/agent.ts +1 -1
- package/src/types/auth.ts +4 -3
- package/src/types/portal.ts +1 -1
- package/src/types/workers.ts +1 -1
- package/src/utils/agent-errors.ts +67 -0
- package/src/utils/api.ts +6 -0
- package/src/utils/banner.ts +14 -9
- package/src/utils/credentials.ts +6 -5
- package/src/utils/help.ts +51 -0
- package/tsconfig.json +9 -6
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.connectChannelFlow = connectChannelFlow;
|
|
7
|
-
exports.runAgentWizard = runAgentWizard;
|
|
8
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const axios_1 = __importDefault(require("axios"));
|
|
11
|
-
const ora_1 = __importDefault(require("ora"));
|
|
12
|
-
const ui_1 = require("../../utils/ui");
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import { theme, section, kvPair } from '../../utils/ui.js';
|
|
13
6
|
const MODELS = {
|
|
14
7
|
openai: ['gpt-4o', 'gpt-4o-mini', 'gpt-4', 'gpt-3.5-turbo', 'o1-preview', 'o1-mini'],
|
|
15
8
|
claude: ['claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'],
|
|
@@ -48,7 +41,7 @@ function getIntegrationKey(ig) {
|
|
|
48
41
|
}
|
|
49
42
|
async function fetchWorkspaceIntegrations(baseUrl, workspaceId, headers) {
|
|
50
43
|
try {
|
|
51
|
-
const wkRes = await
|
|
44
|
+
const wkRes = await axios.get(`${baseUrl}/api/workspace/${workspaceId}`, { headers });
|
|
52
45
|
const wsData = Array.isArray(wkRes.data) ? wkRes.data[0] : wkRes.data;
|
|
53
46
|
return wsData?.integrations || [];
|
|
54
47
|
}
|
|
@@ -58,14 +51,14 @@ async function fetchWorkspaceIntegrations(baseUrl, workspaceId, headers) {
|
|
|
58
51
|
}
|
|
59
52
|
async function activateIntegration(baseUrl, workspaceId, integrationId, headers) {
|
|
60
53
|
try {
|
|
61
|
-
const res = await
|
|
54
|
+
const res = await axios.post(`${baseUrl}/api/workspace/${workspaceId}/integrations/${integrationId}/activate`, { isActive: true }, { headers });
|
|
62
55
|
return res.data?.success === true;
|
|
63
56
|
}
|
|
64
57
|
catch {
|
|
65
58
|
return false;
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
|
-
async function connectChannelFlow(ctx) {
|
|
61
|
+
export async function connectChannelFlow(ctx) {
|
|
69
62
|
const channels = [];
|
|
70
63
|
const baseUrl = getBaseUrl(ctx.zone, ctx.dev);
|
|
71
64
|
const headers = {
|
|
@@ -75,16 +68,16 @@ async function connectChannelFlow(ctx) {
|
|
|
75
68
|
};
|
|
76
69
|
let addMore = true;
|
|
77
70
|
while (addMore) {
|
|
78
|
-
const { channelType } = await
|
|
71
|
+
const { channelType } = await inquirer.prompt([{
|
|
79
72
|
type: 'list',
|
|
80
73
|
name: 'channelType',
|
|
81
|
-
message: '
|
|
74
|
+
message: 'Which channel do you want to connect?',
|
|
82
75
|
choices: CHANNEL_CHOICES,
|
|
83
76
|
}]);
|
|
84
77
|
const channelLabel = CHANNEL_CHOICES.find(c => c.value === channelType)?.name || channelType;
|
|
85
78
|
const targetType = channelType === 'whatsapp_business' ? 'whatsapp' : channelType;
|
|
86
79
|
// Cargar integraciones existentes del tipo seleccionado
|
|
87
|
-
const loadSpinner = (
|
|
80
|
+
const loadSpinner = ora({ text: chalk.gray('Loading integrations...'), spinner: 'dots', color: 'green' }).start();
|
|
88
81
|
const allIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
|
|
89
82
|
const existing = allIntegrations.filter((ig) => ig.type === targetType);
|
|
90
83
|
loadSpinner.stop();
|
|
@@ -95,12 +88,12 @@ async function connectChannelFlow(ctx) {
|
|
|
95
88
|
name: `${getIntegrationLabel(ig)}`,
|
|
96
89
|
value: ig.id,
|
|
97
90
|
}));
|
|
98
|
-
choices.push(new
|
|
99
|
-
choices.push({ name:
|
|
100
|
-
const { selected } = await
|
|
91
|
+
choices.push(new inquirer.Separator());
|
|
92
|
+
choices.push({ name: chalk.hex('#4ade80')('+ Add a new one (generate link)'), value: '__new__' });
|
|
93
|
+
const { selected } = await inquirer.prompt([{
|
|
101
94
|
type: 'list',
|
|
102
95
|
name: 'selected',
|
|
103
|
-
message: `
|
|
96
|
+
message: `Available ${channelLabel} integrations:`,
|
|
104
97
|
choices,
|
|
105
98
|
}]);
|
|
106
99
|
if (selected !== '__new__') {
|
|
@@ -109,13 +102,13 @@ async function connectChannelFlow(ctx) {
|
|
|
109
102
|
const label = getIntegrationLabel(selectedIntegration);
|
|
110
103
|
// Activar la integracion si no esta activa
|
|
111
104
|
if (!selectedIntegration.isActive) {
|
|
112
|
-
const actSpinner = (
|
|
105
|
+
const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
|
|
113
106
|
const activated = await activateIntegration(baseUrl, ctx.workspaceId, selectedIntegration.id, headers);
|
|
114
107
|
if (activated) {
|
|
115
|
-
actSpinner.succeed(
|
|
108
|
+
actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
|
|
116
109
|
}
|
|
117
110
|
else {
|
|
118
|
-
actSpinner.warn(
|
|
111
|
+
actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
|
|
119
112
|
}
|
|
120
113
|
}
|
|
121
114
|
channels.push({
|
|
@@ -123,33 +116,33 @@ async function connectChannelFlow(ctx) {
|
|
|
123
116
|
key: getIntegrationKey(selectedIntegration),
|
|
124
117
|
multianswer: false,
|
|
125
118
|
});
|
|
126
|
-
console.log(
|
|
119
|
+
console.log(chalk.hex('#4ade80')(` Channel linked: ${label}`));
|
|
127
120
|
}
|
|
128
121
|
}
|
|
129
122
|
// Si no hay existentes o eligio "Agregar nuevo" → generar link de onboarding
|
|
130
123
|
if (!selectedIntegration) {
|
|
131
|
-
const spinner = (
|
|
124
|
+
const spinner = ora({ text: chalk.gray('Generating connection link...'), spinner: 'dots', color: 'green' }).start();
|
|
132
125
|
try {
|
|
133
|
-
const linkRes = await
|
|
126
|
+
const linkRes = await axios.post(`${baseUrl}/api/workspace/${ctx.workspaceId}/onboarding-link`, { type: channelType }, { headers });
|
|
134
127
|
if (!linkRes.data?.success) {
|
|
135
|
-
spinner.fail(
|
|
128
|
+
spinner.fail(chalk.hex('#EF5350')(`Error: ${linkRes.data?.message || 'Could not generate the link'}`));
|
|
136
129
|
}
|
|
137
130
|
else {
|
|
138
131
|
const shortUrl = linkRes.data.data?.shortUrl || '';
|
|
139
132
|
spinner.stop();
|
|
140
133
|
// Mostrar link
|
|
141
134
|
console.log();
|
|
142
|
-
console.log(
|
|
143
|
-
console.log(
|
|
135
|
+
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
136
|
+
console.log(chalk.bold(` Send this link to connect ${channelLabel}:`));
|
|
144
137
|
console.log();
|
|
145
|
-
console.log(' ' +
|
|
138
|
+
console.log(' ' + chalk.hex('#22d3ee')(shortUrl));
|
|
146
139
|
console.log();
|
|
147
|
-
console.log(
|
|
140
|
+
console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
|
|
148
141
|
console.log();
|
|
149
142
|
// Guardar IDs actuales para detectar nuevos
|
|
150
143
|
const prevIds = new Set(allIntegrations.map((i) => i.id));
|
|
151
144
|
// Polling para detectar nueva integracion (Enter para saltar)
|
|
152
|
-
const pollSpinner = (
|
|
145
|
+
const pollSpinner = ora({ text: chalk.gray('Waiting for connection... (Enter to skip)'), spinner: 'dots', color: 'cyan' }).start();
|
|
153
146
|
const POLL_INTERVAL = 5000;
|
|
154
147
|
const MAX_POLLS = 60;
|
|
155
148
|
let detected = null;
|
|
@@ -199,49 +192,49 @@ async function connectChannelFlow(ctx) {
|
|
|
199
192
|
}
|
|
200
193
|
catch { }
|
|
201
194
|
const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
|
|
202
|
-
pollSpinner.text =
|
|
195
|
+
pollSpinner.text = chalk.gray(`Waiting for connection... ${elapsed}s (Enter to skip)`);
|
|
203
196
|
}
|
|
204
197
|
if (detected) {
|
|
205
198
|
const detectedName = getIntegrationLabel(detected);
|
|
206
|
-
pollSpinner.succeed(
|
|
199
|
+
pollSpinner.succeed(chalk.hex('#4ade80')(`Connection detected: ${detectedName}`));
|
|
207
200
|
// Activar la integracion detectada
|
|
208
|
-
const actSpinner = (
|
|
201
|
+
const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
|
|
209
202
|
const activated = await activateIntegration(baseUrl, ctx.workspaceId, detected.id, headers);
|
|
210
203
|
if (activated) {
|
|
211
|
-
actSpinner.succeed(
|
|
204
|
+
actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
|
|
212
205
|
}
|
|
213
206
|
else {
|
|
214
|
-
actSpinner.warn(
|
|
207
|
+
actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
|
|
215
208
|
}
|
|
216
209
|
channels.push({
|
|
217
210
|
channel: CHANNEL_AGENT_MAP[channelType],
|
|
218
211
|
key: getIntegrationKey(detected),
|
|
219
212
|
multianswer: false,
|
|
220
213
|
});
|
|
221
|
-
console.log(
|
|
214
|
+
console.log(chalk.hex('#4ade80')(' Channel linked successfully.'));
|
|
222
215
|
}
|
|
223
216
|
else {
|
|
224
|
-
pollSpinner.warn(
|
|
225
|
-
const { action } = await
|
|
217
|
+
pollSpinner.warn(chalk.hex('#FFA726')(skipped ? 'Skipped.' : 'Timeout: no connection detected.'));
|
|
218
|
+
const { action } = await inquirer.prompt([{
|
|
226
219
|
type: 'list', name: 'action',
|
|
227
|
-
message: '
|
|
220
|
+
message: 'What would you like to do?',
|
|
228
221
|
choices: [
|
|
229
|
-
{ name: '
|
|
230
|
-
{ name: '
|
|
222
|
+
{ name: 'Enter ID manually', value: 'manual' },
|
|
223
|
+
{ name: 'Skip', value: 'skip' },
|
|
231
224
|
],
|
|
232
225
|
}]);
|
|
233
226
|
if (action === 'manual') {
|
|
234
|
-
const { key } = await
|
|
235
|
-
{ type: 'input', name: 'key', message:
|
|
227
|
+
const { key } = await inquirer.prompt([
|
|
228
|
+
{ type: 'input', name: 'key', message: `${channelLabel} channel ID/number:`, validate: (v) => v.length > 0 || 'Required' },
|
|
236
229
|
]);
|
|
237
230
|
// Activar la integracion ingresada manualmente
|
|
238
|
-
const actSpinner = (
|
|
231
|
+
const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
|
|
239
232
|
const activated = await activateIntegration(baseUrl, ctx.workspaceId, key, headers);
|
|
240
233
|
if (activated) {
|
|
241
|
-
actSpinner.succeed(
|
|
234
|
+
actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
|
|
242
235
|
}
|
|
243
236
|
else {
|
|
244
|
-
actSpinner.warn(
|
|
237
|
+
actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
|
|
245
238
|
}
|
|
246
239
|
channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
|
|
247
240
|
}
|
|
@@ -249,188 +242,188 @@ async function connectChannelFlow(ctx) {
|
|
|
249
242
|
}
|
|
250
243
|
}
|
|
251
244
|
catch (err) {
|
|
252
|
-
spinner.fail(
|
|
245
|
+
spinner.fail(chalk.hex('#EF5350')(`Error: ${err instanceof Error ? err.message : err}`));
|
|
253
246
|
}
|
|
254
247
|
}
|
|
255
|
-
const { more } = await
|
|
248
|
+
const { more } = await inquirer.prompt([{ type: 'confirm', name: 'more', message: 'Connect another channel?', default: false }]);
|
|
256
249
|
addMore = more;
|
|
257
250
|
}
|
|
258
251
|
return channels;
|
|
259
252
|
}
|
|
260
|
-
async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
261
|
-
console.log(
|
|
262
|
-
console.log(
|
|
253
|
+
export async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
254
|
+
console.log(section('Create new AI agent'));
|
|
255
|
+
console.log(theme.muted(' Answer the following questions to configure your agent.\n'));
|
|
263
256
|
// Paso 1: Informacion basica
|
|
264
|
-
console.log(
|
|
265
|
-
const basic = await
|
|
257
|
+
console.log(theme.bold('\n Step 1/8: Basic information'));
|
|
258
|
+
const basic = await inquirer.prompt([
|
|
266
259
|
{
|
|
267
260
|
type: 'input',
|
|
268
261
|
name: 'name',
|
|
269
|
-
message: '
|
|
270
|
-
validate: (v) => v.length > 0 || '
|
|
262
|
+
message: 'Agent name:',
|
|
263
|
+
validate: (v) => v.length > 0 || 'Name is required',
|
|
271
264
|
},
|
|
272
265
|
{
|
|
273
266
|
type: 'input',
|
|
274
267
|
name: 'description',
|
|
275
|
-
message: '
|
|
268
|
+
message: 'Short description:',
|
|
276
269
|
default: '',
|
|
277
270
|
},
|
|
278
271
|
{
|
|
279
272
|
type: 'input',
|
|
280
273
|
name: 'prompt',
|
|
281
|
-
message: '
|
|
282
|
-
default: '
|
|
274
|
+
message: 'System prompt (main instructions):',
|
|
275
|
+
default: 'You are a friendly and professional virtual assistant.',
|
|
283
276
|
},
|
|
284
277
|
{
|
|
285
278
|
type: 'number',
|
|
286
279
|
name: 'buffer',
|
|
287
|
-
message: '
|
|
280
|
+
message: 'Conversation buffer (3-20 messages):',
|
|
288
281
|
default: 5,
|
|
289
|
-
validate: (v) => (v >= 3 && v <= 20) || '
|
|
282
|
+
validate: (v) => (v >= 3 && v <= 20) || 'Must be between 3 and 20',
|
|
290
283
|
},
|
|
291
284
|
{
|
|
292
285
|
type: 'list',
|
|
293
286
|
name: 'color',
|
|
294
|
-
message: '
|
|
287
|
+
message: 'Agent color:',
|
|
295
288
|
choices: COLORS,
|
|
296
289
|
default: 'blue',
|
|
297
290
|
},
|
|
298
291
|
]);
|
|
299
292
|
// Paso 2: Personalidad
|
|
300
|
-
console.log(
|
|
301
|
-
const personality = await
|
|
293
|
+
console.log(theme.bold('\n Step 2/8: Personality and instructions'));
|
|
294
|
+
const personality = await inquirer.prompt([
|
|
302
295
|
{
|
|
303
296
|
type: 'list',
|
|
304
297
|
name: 'tone',
|
|
305
|
-
message: '
|
|
298
|
+
message: 'Communication tone:',
|
|
306
299
|
choices: ['profesional', 'amigable', 'formal', 'casual', 'tecnico', 'empatico'],
|
|
307
300
|
default: 'profesional',
|
|
308
301
|
},
|
|
309
302
|
{
|
|
310
303
|
type: 'list',
|
|
311
304
|
name: 'style',
|
|
312
|
-
message: '
|
|
305
|
+
message: 'Response style:',
|
|
313
306
|
choices: ['conciso', 'detallado', 'conversacional', 'directo'],
|
|
314
307
|
default: 'conciso',
|
|
315
308
|
},
|
|
316
309
|
{
|
|
317
310
|
type: 'input',
|
|
318
311
|
name: 'personality',
|
|
319
|
-
message: '
|
|
320
|
-
default: '
|
|
312
|
+
message: 'Personality in one sentence:',
|
|
313
|
+
default: 'Helpful and knowledgeable',
|
|
321
314
|
},
|
|
322
315
|
{
|
|
323
316
|
type: 'input',
|
|
324
317
|
name: 'objective',
|
|
325
|
-
message: '
|
|
326
|
-
default: '
|
|
318
|
+
message: 'Main objective of the agent:',
|
|
319
|
+
default: 'Help users with their queries',
|
|
327
320
|
},
|
|
328
321
|
{
|
|
329
322
|
type: 'list',
|
|
330
323
|
name: 'language',
|
|
331
|
-
message: '
|
|
324
|
+
message: 'Primary language:',
|
|
332
325
|
choices: ['Espanol', 'English', 'Portugues', 'Frances'],
|
|
333
326
|
default: 'Espanol',
|
|
334
327
|
},
|
|
335
328
|
{
|
|
336
329
|
type: 'confirm',
|
|
337
330
|
name: 'useEmojis',
|
|
338
|
-
message: '
|
|
331
|
+
message: 'Use emojis in responses?',
|
|
339
332
|
default: true,
|
|
340
333
|
},
|
|
341
334
|
]);
|
|
342
335
|
// Paso 3: Persona
|
|
343
|
-
console.log(
|
|
344
|
-
const person = await
|
|
336
|
+
console.log(theme.bold('\n Step 3/8: Agent identity'));
|
|
337
|
+
const person = await inquirer.prompt([
|
|
345
338
|
{
|
|
346
339
|
type: 'input',
|
|
347
340
|
name: 'name',
|
|
348
|
-
message: '
|
|
341
|
+
message: 'Character name (how it introduces itself):',
|
|
349
342
|
default: basic.name,
|
|
350
343
|
},
|
|
351
344
|
{
|
|
352
345
|
type: 'input',
|
|
353
346
|
name: 'role',
|
|
354
|
-
message: '
|
|
355
|
-
default: '
|
|
347
|
+
message: 'Role (e.g. Sales assistant, Tech support):',
|
|
348
|
+
default: 'Virtual assistant',
|
|
356
349
|
},
|
|
357
350
|
{
|
|
358
351
|
type: 'confirm',
|
|
359
352
|
name: 'firstPerson',
|
|
360
|
-
message: '
|
|
353
|
+
message: 'Speak in first person?',
|
|
361
354
|
default: true,
|
|
362
355
|
},
|
|
363
356
|
]);
|
|
364
357
|
// Paso 4: Fallbacks
|
|
365
|
-
console.log(
|
|
366
|
-
const fallbacks = await
|
|
358
|
+
console.log(theme.bold('\n Step 4/8: Fallback messages'));
|
|
359
|
+
const fallbacks = await inquirer.prompt([
|
|
367
360
|
{
|
|
368
361
|
type: 'input',
|
|
369
362
|
name: 'noAnswer',
|
|
370
|
-
message: '
|
|
363
|
+
message: 'When it has no answer:',
|
|
371
364
|
default: 'Lo siento, no tengo informacion sobre eso. Puedo ayudarte con otra consulta?',
|
|
372
365
|
},
|
|
373
366
|
{
|
|
374
367
|
type: 'input',
|
|
375
368
|
name: 'serviceError',
|
|
376
|
-
message: '
|
|
369
|
+
message: 'When there is a service error:',
|
|
377
370
|
default: 'Disculpa, estamos experimentando dificultades tecnicas. Intenta de nuevo en unos momentos.',
|
|
378
371
|
},
|
|
379
372
|
{
|
|
380
373
|
type: 'input',
|
|
381
374
|
name: 'misunderstanding',
|
|
382
|
-
message: '
|
|
375
|
+
message: 'When it does not understand the question:',
|
|
383
376
|
default: 'No estoy seguro de entender tu consulta. Podrias reformularla?',
|
|
384
377
|
},
|
|
385
378
|
]);
|
|
386
379
|
// Paso 5: Tool Calling
|
|
387
|
-
console.log(
|
|
388
|
-
console.log(
|
|
389
|
-
const { useToolCalling } = await
|
|
380
|
+
console.log(theme.bold('\n Step 5/8: Tool Calling'));
|
|
381
|
+
console.log(theme.muted(' Tool Calling lets the agent execute automatic actions\n'));
|
|
382
|
+
const { useToolCalling } = await inquirer.prompt([
|
|
390
383
|
{
|
|
391
384
|
type: 'confirm',
|
|
392
385
|
name: 'useToolCalling',
|
|
393
|
-
message: '
|
|
386
|
+
message: 'Enable Tool Calling?',
|
|
394
387
|
default: true,
|
|
395
388
|
},
|
|
396
389
|
]);
|
|
397
390
|
// Servicios (API calls)
|
|
398
391
|
const services = [];
|
|
399
392
|
if (useToolCalling) {
|
|
400
|
-
const { addServices } = await
|
|
393
|
+
const { addServices } = await inquirer.prompt([{
|
|
401
394
|
type: 'confirm',
|
|
402
395
|
name: 'addServices',
|
|
403
|
-
message: '
|
|
396
|
+
message: 'Add external services (API calls)?',
|
|
404
397
|
default: false,
|
|
405
398
|
}]);
|
|
406
399
|
if (addServices) {
|
|
407
400
|
let addMore = true;
|
|
408
401
|
while (addMore) {
|
|
409
|
-
console.log(
|
|
410
|
-
const svc = await
|
|
411
|
-
{ type: 'input', name: 'intent', message: '
|
|
412
|
-
{ type: 'input', name: 'reference', message: '
|
|
413
|
-
{ type: 'list', name: 'method', message: '
|
|
414
|
-
{ type: 'input', name: 'endpoint', message: 'URL
|
|
415
|
-
{ type: 'input', name: 'responseMessage', message: '
|
|
402
|
+
console.log(theme.muted('\n New service:'));
|
|
403
|
+
const svc = await inquirer.prompt([
|
|
404
|
+
{ type: 'input', name: 'intent', message: 'Service name/intent:', validate: (v) => v.length > 0 || 'Required' },
|
|
405
|
+
{ type: 'input', name: 'reference', message: 'Reference keywords:', default: '' },
|
|
406
|
+
{ type: 'list', name: 'method', message: 'HTTP method:', choices: ['GET', 'POST'] },
|
|
407
|
+
{ type: 'input', name: 'endpoint', message: 'Endpoint URL:', validate: (v) => v.length > 0 || 'Required' },
|
|
408
|
+
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
416
409
|
]);
|
|
417
410
|
// Required fields
|
|
418
411
|
const fields = [];
|
|
419
|
-
const { addFields } = await
|
|
412
|
+
const { addFields } = await inquirer.prompt([{
|
|
420
413
|
type: 'confirm', name: 'addFields',
|
|
421
|
-
message: '
|
|
414
|
+
message: 'Add required fields?', default: false,
|
|
422
415
|
}]);
|
|
423
416
|
if (addFields) {
|
|
424
417
|
let moreFields = true;
|
|
425
418
|
while (moreFields) {
|
|
426
|
-
const field = await
|
|
427
|
-
{ type: 'input', name: 'name', message: '
|
|
428
|
-
{ type: 'list', name: 'type', message: '
|
|
429
|
-
{ type: 'input', name: 'description', message: '
|
|
430
|
-
{ type: 'input', name: 'promptHint', message: 'Hint
|
|
419
|
+
const field = await inquirer.prompt([
|
|
420
|
+
{ type: 'input', name: 'name', message: 'Field name:' },
|
|
421
|
+
{ type: 'list', name: 'type', message: 'Type:', choices: ['string', 'number', 'boolean', 'date'] },
|
|
422
|
+
{ type: 'input', name: 'description', message: 'Description:' },
|
|
423
|
+
{ type: 'input', name: 'promptHint', message: 'Hint for the LLM:' },
|
|
431
424
|
]);
|
|
432
425
|
fields.push(field);
|
|
433
|
-
const { more } = await
|
|
426
|
+
const { more } = await inquirer.prompt([{ type: 'confirm', name: 'more', message: 'Add another field?', default: false }]);
|
|
434
427
|
moreFields = more;
|
|
435
428
|
}
|
|
436
429
|
}
|
|
@@ -447,7 +440,7 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
447
440
|
responseMessage: svc.responseMessage,
|
|
448
441
|
responseConditions: [],
|
|
449
442
|
});
|
|
450
|
-
const { more } = await
|
|
443
|
+
const { more } = await inquirer.prompt([{ type: 'confirm', name: 'more', message: 'Add another service?', default: false }]);
|
|
451
444
|
addMore = more;
|
|
452
445
|
}
|
|
453
446
|
}
|
|
@@ -455,36 +448,36 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
455
448
|
// Acciones
|
|
456
449
|
const actions = [];
|
|
457
450
|
if (useToolCalling) {
|
|
458
|
-
const { addActions } = await
|
|
451
|
+
const { addActions } = await inquirer.prompt([{
|
|
459
452
|
type: 'confirm',
|
|
460
453
|
name: 'addActions',
|
|
461
|
-
message: '
|
|
454
|
+
message: 'Add actions (tag, stage, assign agent)?',
|
|
462
455
|
default: false,
|
|
463
456
|
}]);
|
|
464
457
|
if (addActions) {
|
|
465
458
|
let addMore = true;
|
|
466
459
|
while (addMore) {
|
|
467
|
-
console.log(
|
|
468
|
-
const act = await
|
|
469
|
-
{ type: 'input', name: 'intent', message: '
|
|
470
|
-
{ type: 'input', name: 'reference', message: '
|
|
460
|
+
console.log(theme.muted('\n New action:'));
|
|
461
|
+
const act = await inquirer.prompt([
|
|
462
|
+
{ type: 'input', name: 'intent', message: 'Action name/intent:', validate: (v) => v.length > 0 || 'Required' },
|
|
463
|
+
{ type: 'input', name: 'reference', message: 'Reference keywords:', default: '' },
|
|
471
464
|
{
|
|
472
|
-
type: 'list', name: 'actionType', message: '
|
|
465
|
+
type: 'list', name: 'actionType', message: 'Action type:',
|
|
473
466
|
choices: [
|
|
474
|
-
{ name: '
|
|
475
|
-
{ name: '
|
|
476
|
-
{ name: '
|
|
477
|
-
{ name: '
|
|
478
|
-
{ name: '
|
|
479
|
-
{ name: '
|
|
480
|
-
{ name: '
|
|
481
|
-
{ name: '
|
|
482
|
-
{ name: '
|
|
483
|
-
{ name: '
|
|
467
|
+
{ name: 'Schedule event', value: 'action.event.add' },
|
|
468
|
+
{ name: 'Update event (reschedule)', value: 'action.event.update' },
|
|
469
|
+
{ name: 'List events', value: 'action.event.list' },
|
|
470
|
+
{ name: 'Delete event (cancel)', value: 'action.event.delete' },
|
|
471
|
+
{ name: 'Add tag', value: 'action.tag' },
|
|
472
|
+
{ name: 'Change stage', value: 'action.stage' },
|
|
473
|
+
{ name: 'Hand off to human agent', value: 'action.agentShutDown' },
|
|
474
|
+
{ name: 'Mark as resolved', value: 'action.solved' },
|
|
475
|
+
{ name: 'Assign agent', value: 'action.asign' },
|
|
476
|
+
{ name: 'Segmentation', value: 'action.segmentation' },
|
|
484
477
|
],
|
|
485
478
|
},
|
|
486
|
-
{ type: 'input', name: 'actionValue', message: '
|
|
487
|
-
{ type: 'input', name: 'responseMessage', message: '
|
|
479
|
+
{ type: 'input', name: 'actionValue', message: 'Action value:', default: '' },
|
|
480
|
+
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
488
481
|
]);
|
|
489
482
|
actions.push({
|
|
490
483
|
intent: act.intent,
|
|
@@ -494,28 +487,28 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
494
487
|
responseMessage: act.responseMessage,
|
|
495
488
|
action: [{ type: act.actionType, value: act.actionValue }],
|
|
496
489
|
});
|
|
497
|
-
const { more } = await
|
|
490
|
+
const { more } = await inquirer.prompt([{ type: 'confirm', name: 'more', message: 'Add another action?', default: false }]);
|
|
498
491
|
addMore = more;
|
|
499
492
|
}
|
|
500
493
|
}
|
|
501
494
|
}
|
|
502
495
|
// Paso 6: AI Provider
|
|
503
|
-
console.log(
|
|
504
|
-
const { configureAI } = await
|
|
496
|
+
console.log(theme.bold('\n Step 6/8: AI provider'));
|
|
497
|
+
const { configureAI } = await inquirer.prompt([{
|
|
505
498
|
type: 'confirm',
|
|
506
499
|
name: 'configureAI',
|
|
507
|
-
message: '
|
|
500
|
+
message: 'Configure a custom AI provider?',
|
|
508
501
|
default: false,
|
|
509
502
|
}]);
|
|
510
503
|
const aiProviders = [];
|
|
511
504
|
if (configureAI) {
|
|
512
|
-
const ai = await
|
|
513
|
-
{ type: 'list', name: 'provider', message: '
|
|
505
|
+
const ai = await inquirer.prompt([
|
|
506
|
+
{ type: 'list', name: 'provider', message: 'Provider:', choices: ['openai', 'claude', 'gemini'] },
|
|
514
507
|
]);
|
|
515
508
|
const models = MODELS[ai.provider] || MODELS.openai;
|
|
516
|
-
const aiConfig = await
|
|
517
|
-
{ type: 'list', name: 'model', message: '
|
|
518
|
-
{ type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v) => v.length > 0 || '
|
|
509
|
+
const aiConfig = await inquirer.prompt([
|
|
510
|
+
{ type: 'list', name: 'model', message: 'Model:', choices: models },
|
|
511
|
+
{ type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v) => v.length > 0 || 'Required' },
|
|
519
512
|
]);
|
|
520
513
|
aiProviders.push({
|
|
521
514
|
provider: ai.provider,
|
|
@@ -527,12 +520,12 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
527
520
|
});
|
|
528
521
|
}
|
|
529
522
|
// Paso 7: Conectar canal
|
|
530
|
-
console.log(
|
|
523
|
+
console.log(theme.bold('\n Step 7/8: Connect channel'));
|
|
531
524
|
let channels = [];
|
|
532
|
-
const { addChannel } = await
|
|
525
|
+
const { addChannel } = await inquirer.prompt([{
|
|
533
526
|
type: 'confirm',
|
|
534
527
|
name: 'addChannel',
|
|
535
|
-
message: '
|
|
528
|
+
message: 'Connect a channel (WhatsApp, Instagram, Messenger)?',
|
|
536
529
|
default: false,
|
|
537
530
|
}]);
|
|
538
531
|
if (addChannel && workspaceId && apiKey) {
|
|
@@ -540,30 +533,30 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
540
533
|
}
|
|
541
534
|
else if (addChannel) {
|
|
542
535
|
// Fallback manual si no hay credenciales para API
|
|
543
|
-
const wa = await
|
|
544
|
-
{ type: 'input', name: 'key', message: '
|
|
545
|
-
{ type: 'confirm', name: 'multianswer', message: '
|
|
536
|
+
const wa = await inquirer.prompt([
|
|
537
|
+
{ type: 'input', name: 'key', message: 'WhatsApp number (with country code):', validate: (v) => v.length > 0 || 'Required' },
|
|
538
|
+
{ type: 'confirm', name: 'multianswer', message: 'Allow multiple answers?', default: false },
|
|
546
539
|
]);
|
|
547
540
|
channels.push({ channel: 'whatsapp', key: wa.key, multianswer: wa.multianswer });
|
|
548
541
|
}
|
|
549
542
|
// Paso 8: Ejemplos
|
|
550
|
-
console.log(
|
|
543
|
+
console.log(theme.bold('\n Step 8/8: Conversation examples'));
|
|
551
544
|
const examples = [];
|
|
552
|
-
const { addExamples } = await
|
|
545
|
+
const { addExamples } = await inquirer.prompt([{
|
|
553
546
|
type: 'confirm',
|
|
554
547
|
name: 'addExamples',
|
|
555
|
-
message: '
|
|
548
|
+
message: 'Add conversation examples?',
|
|
556
549
|
default: false,
|
|
557
550
|
}]);
|
|
558
551
|
if (addExamples) {
|
|
559
552
|
let addMore = true;
|
|
560
553
|
while (addMore) {
|
|
561
|
-
const ex = await
|
|
562
|
-
{ type: 'input', name: 'user', message: '
|
|
563
|
-
{ type: 'input', name: 'agent', message: '
|
|
554
|
+
const ex = await inquirer.prompt([
|
|
555
|
+
{ type: 'input', name: 'user', message: 'User message:' },
|
|
556
|
+
{ type: 'input', name: 'agent', message: 'Agent response:' },
|
|
564
557
|
]);
|
|
565
|
-
examples.push({ value: `
|
|
566
|
-
const { more } = await
|
|
558
|
+
examples.push({ value: `User: ${ex.user}\nAgent: ${ex.agent}`, color: 'blue' });
|
|
559
|
+
const { more } = await inquirer.prompt([{ type: 'confirm', name: 'more', message: 'Add another example?', default: false }]);
|
|
567
560
|
addMore = more;
|
|
568
561
|
}
|
|
569
562
|
}
|
|
@@ -603,20 +596,20 @@ async function runAgentWizard(zone, workspaceId, apiKey, dev) {
|
|
|
603
596
|
tags: [],
|
|
604
597
|
};
|
|
605
598
|
// Preview
|
|
606
|
-
console.log(
|
|
607
|
-
console.log(
|
|
608
|
-
console.log(
|
|
609
|
-
console.log(
|
|
610
|
-
console.log(
|
|
611
|
-
console.log(
|
|
612
|
-
console.log(
|
|
599
|
+
console.log(section('Configuration preview'));
|
|
600
|
+
console.log(kvPair('Name', config.name));
|
|
601
|
+
console.log(kvPair('Prompt', config.prompt.substring(0, 80) + '...'));
|
|
602
|
+
console.log(kvPair('Tool Calling', config.useToolCalling ? 'Enabled' : 'Disabled'));
|
|
603
|
+
console.log(kvPair('Services', String(config.services.length)));
|
|
604
|
+
console.log(kvPair('Actions', String(config.actions.length)));
|
|
605
|
+
console.log(kvPair('AI Provider', config.customAIConfig ? config.aiProviders[0]?.provider + ' / ' + config.aiProviders[0]?.model : 'Default (Plazbot)'));
|
|
613
606
|
if (config.channels.length > 0) {
|
|
614
607
|
config.channels.forEach((ch, i) => {
|
|
615
|
-
console.log(
|
|
608
|
+
console.log(kvPair(`Channel ${i + 1} (${ch.channel})`, ch.key));
|
|
616
609
|
});
|
|
617
610
|
}
|
|
618
611
|
else {
|
|
619
|
-
console.log(
|
|
612
|
+
console.log(kvPair('Channels', 'Not configured'));
|
|
620
613
|
}
|
|
621
614
|
console.log();
|
|
622
615
|
return config;
|