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,94 +1,89 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const ui_1 = require("../../utils/ui");
|
|
13
|
-
exports.toolsCommand = new commander_1.Command('tools')
|
|
14
|
-
.description('Gestionar herramientas de Tool Calling del agente')
|
|
15
|
-
.argument('<agentId>', 'ID del agente')
|
|
16
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Agent } from 'plazbot';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
import { addExamples } from '../../utils/help.js';
|
|
7
|
+
import { createSpinner, createTable, theme, section, kvPair, statusBadge } from '../../utils/ui.js';
|
|
8
|
+
export const toolsCommand = new Command('tools')
|
|
9
|
+
.description('Manage agent Tool Calling tools')
|
|
10
|
+
.argument('<agentId>', 'Agent ID')
|
|
11
|
+
.option('--dev', 'Use development environment', false)
|
|
17
12
|
.action(async (agentId, options) => {
|
|
18
13
|
try {
|
|
19
|
-
const credentials = await
|
|
20
|
-
const agent = new
|
|
14
|
+
const credentials = await getStoredCredentials();
|
|
15
|
+
const agent = new Agent({
|
|
21
16
|
workspaceId: credentials.workspace,
|
|
22
17
|
apiKey: credentials.apiKey,
|
|
23
18
|
zone: credentials.zone,
|
|
24
19
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
25
20
|
});
|
|
26
|
-
const spinner =
|
|
21
|
+
const spinner = createSpinner('Loading agent...');
|
|
27
22
|
spinner.start();
|
|
28
23
|
const _res = await agent.getAgentById({ id: agentId });
|
|
29
24
|
const agentData = _res.agent || _res.data || _res;
|
|
30
25
|
spinner.stop();
|
|
31
|
-
console.log(
|
|
32
|
-
console.log(
|
|
26
|
+
console.log(section('Tool Calling - ' + (agentData.name || agentId)));
|
|
27
|
+
console.log(kvPair('Status', agentData.useToolCalling ? theme.success('Enabled') : theme.error('Disabled')));
|
|
33
28
|
// Servicios
|
|
34
29
|
const services = agentData.services || [];
|
|
35
30
|
if (services.length > 0) {
|
|
36
|
-
console.log(
|
|
31
|
+
console.log(section('Services (API calls)'));
|
|
37
32
|
const rows = services.map((s) => [
|
|
38
33
|
s.intent,
|
|
39
34
|
s.method || 'POST',
|
|
40
35
|
s.endpoint ? s.endpoint.substring(0, 40) + '...' : 'N/A',
|
|
41
|
-
|
|
36
|
+
statusBadge(s.enabled !== false),
|
|
42
37
|
]);
|
|
43
|
-
console.log(
|
|
38
|
+
console.log(createTable(['Intent', 'Method', 'Endpoint', 'Status'], rows));
|
|
44
39
|
}
|
|
45
40
|
else {
|
|
46
|
-
console.log(
|
|
41
|
+
console.log(theme.muted('\n No services configured'));
|
|
47
42
|
}
|
|
48
43
|
// Acciones
|
|
49
44
|
const actions = agentData.actions || [];
|
|
50
45
|
if (actions.length > 0) {
|
|
51
|
-
console.log(
|
|
46
|
+
console.log(section('Actions'));
|
|
52
47
|
const rows = actions.map((a) => [
|
|
53
48
|
a.intent,
|
|
54
49
|
(a.action || []).map((ac) => ac.type).join(', '),
|
|
55
|
-
|
|
50
|
+
statusBadge(a.enabled !== false),
|
|
56
51
|
]);
|
|
57
|
-
console.log(
|
|
52
|
+
console.log(createTable(['Intent', 'Type', 'Status'], rows));
|
|
58
53
|
}
|
|
59
54
|
else {
|
|
60
|
-
console.log(
|
|
55
|
+
console.log(theme.muted('\n No actions configured'));
|
|
61
56
|
}
|
|
62
57
|
// Menu de opciones
|
|
63
58
|
console.log();
|
|
64
|
-
const { action } = await
|
|
59
|
+
const { action } = await inquirer.prompt([{
|
|
65
60
|
type: 'list',
|
|
66
61
|
name: 'action',
|
|
67
|
-
message: '
|
|
62
|
+
message: 'What would you like to do?',
|
|
68
63
|
choices: [
|
|
69
|
-
{ name: '
|
|
70
|
-
{ name: '
|
|
71
|
-
{ name: agentData.useToolCalling ? '
|
|
72
|
-
{ name: '
|
|
64
|
+
{ name: 'Add service (API call)', value: 'add-service' },
|
|
65
|
+
{ name: 'Add action', value: 'add-action' },
|
|
66
|
+
{ name: agentData.useToolCalling ? 'Disable Tool Calling' : 'Enable Tool Calling', value: 'toggle' },
|
|
67
|
+
{ name: 'Exit', value: 'exit' },
|
|
73
68
|
],
|
|
74
69
|
}]);
|
|
75
70
|
if (action === 'exit')
|
|
76
71
|
return;
|
|
77
72
|
if (action === 'toggle') {
|
|
78
|
-
const toggleSpinner =
|
|
73
|
+
const toggleSpinner = createSpinner('Updating...');
|
|
79
74
|
toggleSpinner.start();
|
|
80
75
|
const { id: _i1, _id: _o1, ...updatedConfig } = { ...agentData, useToolCalling: !agentData.useToolCalling };
|
|
81
76
|
await agent.updateAgent(agentId, updatedConfig);
|
|
82
|
-
toggleSpinner.succeed(`Tool Calling ${!agentData.useToolCalling ? '
|
|
77
|
+
toggleSpinner.succeed(`Tool Calling ${!agentData.useToolCalling ? 'enabled' : 'disabled'}`);
|
|
83
78
|
return;
|
|
84
79
|
}
|
|
85
80
|
if (action === 'add-service') {
|
|
86
|
-
const svc = await
|
|
87
|
-
{ type: 'input', name: 'intent', message: '
|
|
88
|
-
{ type: 'input', name: 'reference', message: '
|
|
89
|
-
{ type: 'list', name: 'method', message: '
|
|
90
|
-
{ type: 'input', name: 'endpoint', message: 'URL
|
|
91
|
-
{ type: 'input', name: 'responseMessage', message: '
|
|
81
|
+
const svc = await inquirer.prompt([
|
|
82
|
+
{ type: 'input', name: 'intent', message: 'Service name/intent:', validate: (v) => v.length > 0 || 'Required' },
|
|
83
|
+
{ type: 'input', name: 'reference', message: 'Keywords:', default: '' },
|
|
84
|
+
{ type: 'list', name: 'method', message: 'HTTP method:', choices: ['GET', 'POST'] },
|
|
85
|
+
{ type: 'input', name: 'endpoint', message: 'Endpoint URL:', validate: (v) => v.length > 0 || 'Required' },
|
|
86
|
+
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
92
87
|
]);
|
|
93
88
|
const newService = {
|
|
94
89
|
intent: svc.intent,
|
|
@@ -105,32 +100,32 @@ exports.toolsCommand = new commander_1.Command('tools')
|
|
|
105
100
|
};
|
|
106
101
|
const updatedServices = [...services, newService];
|
|
107
102
|
const { id: _i2, _id: _o2, ...updatedConfig } = { ...agentData, services: updatedServices, useToolCalling: true };
|
|
108
|
-
const updateSpinner =
|
|
103
|
+
const updateSpinner = createSpinner('Saving service...');
|
|
109
104
|
updateSpinner.start();
|
|
110
105
|
await agent.updateAgent(agentId, updatedConfig);
|
|
111
|
-
updateSpinner.succeed(`
|
|
106
|
+
updateSpinner.succeed(`Service "${svc.intent}" added`);
|
|
112
107
|
}
|
|
113
108
|
if (action === 'add-action') {
|
|
114
|
-
const act = await
|
|
115
|
-
{ type: 'input', name: 'intent', message: '
|
|
116
|
-
{ type: 'input', name: 'reference', message: '
|
|
109
|
+
const act = await inquirer.prompt([
|
|
110
|
+
{ type: 'input', name: 'intent', message: 'Action name/intent:', validate: (v) => v.length > 0 || 'Required' },
|
|
111
|
+
{ type: 'input', name: 'reference', message: 'Keywords:', default: '' },
|
|
117
112
|
{
|
|
118
|
-
type: 'list', name: 'actionType', message: '
|
|
113
|
+
type: 'list', name: 'actionType', message: 'Action type:',
|
|
119
114
|
choices: [
|
|
120
|
-
{ name: '
|
|
121
|
-
{ name: '
|
|
122
|
-
{ name: '
|
|
123
|
-
{ name: '
|
|
124
|
-
{ name: '
|
|
125
|
-
{ name: '
|
|
126
|
-
{ name: '
|
|
127
|
-
{ name: '
|
|
128
|
-
{ name: '
|
|
129
|
-
{ name: '
|
|
115
|
+
{ name: 'Schedule event', value: 'action.event.add' },
|
|
116
|
+
{ name: 'Update event (reschedule)', value: 'action.event.update' },
|
|
117
|
+
{ name: 'List events', value: 'action.event.list' },
|
|
118
|
+
{ name: 'Delete event (cancel)', value: 'action.event.delete' },
|
|
119
|
+
{ name: 'Add tag', value: 'action.tag' },
|
|
120
|
+
{ name: 'Change stage', value: 'action.stage' },
|
|
121
|
+
{ name: 'Hand off to human agent', value: 'action.agentShutDown' },
|
|
122
|
+
{ name: 'Mark as resolved', value: 'action.solved' },
|
|
123
|
+
{ name: 'Assign agent', value: 'action.asign' },
|
|
124
|
+
{ name: 'Segmentation', value: 'action.segmentation' },
|
|
130
125
|
],
|
|
131
126
|
},
|
|
132
|
-
{ type: 'input', name: 'actionValue', message: '
|
|
133
|
-
{ type: 'input', name: 'responseMessage', message: '
|
|
127
|
+
{ type: 'input', name: 'actionValue', message: 'Value (optional):', default: '' },
|
|
128
|
+
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
134
129
|
]);
|
|
135
130
|
const newAction = {
|
|
136
131
|
intent: act.intent,
|
|
@@ -142,15 +137,19 @@ exports.toolsCommand = new commander_1.Command('tools')
|
|
|
142
137
|
};
|
|
143
138
|
const updatedActions = [...actions, newAction];
|
|
144
139
|
const { id: _i3, _id: _o3, ...updatedConfig } = { ...agentData, actions: updatedActions, useToolCalling: true };
|
|
145
|
-
const updateSpinner =
|
|
140
|
+
const updateSpinner = createSpinner('Saving action...');
|
|
146
141
|
updateSpinner.start();
|
|
147
142
|
await agent.updateAgent(agentId, updatedConfig);
|
|
148
|
-
updateSpinner.succeed(`
|
|
143
|
+
updateSpinner.succeed(`Action "${act.intent}" added`);
|
|
149
144
|
}
|
|
150
145
|
}
|
|
151
146
|
catch (error) {
|
|
152
|
-
const message = error instanceof Error ? error.message : '
|
|
153
|
-
|
|
147
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
148
|
+
logger.error(message);
|
|
154
149
|
process.exit(1);
|
|
155
150
|
}
|
|
156
151
|
});
|
|
152
|
+
addExamples(toolsCommand, [
|
|
153
|
+
{ description: 'View services/actions and add new ones interactively',
|
|
154
|
+
command: 'plazbot agent tools agt_AbcDef123' },
|
|
155
|
+
]);
|
|
@@ -1,52 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports.updateCommand = new commander_1.Command('update')
|
|
13
|
-
.description('Actualiza un agente existente en Plazbot')
|
|
14
|
-
.argument('<agentId>', 'ID del agente a actualizar')
|
|
15
|
-
.argument('<configPath>', 'Ruta al archivo de configuración JSON del agente')
|
|
16
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Agent } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
export const updateCommand = new Command('update')
|
|
8
|
+
.description('Update an existing agent in Plazbot')
|
|
9
|
+
.argument('<agentId>', 'Agent ID to update')
|
|
10
|
+
.argument('<configPath>', 'Path to the agent JSON configuration file')
|
|
11
|
+
.option('--dev', 'Use development environment', false)
|
|
17
12
|
.action(async (agentId, configPath, options) => {
|
|
18
13
|
try {
|
|
19
14
|
// Obtener credenciales guardadas
|
|
20
|
-
const credentials = await
|
|
15
|
+
const credentials = await getStoredCredentials();
|
|
21
16
|
// Leer archivo de configuración del agente
|
|
22
17
|
let agentConfig;
|
|
23
18
|
try {
|
|
24
|
-
const fileContent = await
|
|
19
|
+
const fileContent = await fs.readFile(configPath, 'utf-8');
|
|
25
20
|
agentConfig = JSON.parse(fileContent);
|
|
26
21
|
}
|
|
27
22
|
catch (error) {
|
|
28
|
-
const errorMessage = error instanceof Error ? error.message : '
|
|
29
|
-
throw new Error(`Error
|
|
23
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
24
|
+
throw new Error(`Error reading configuration file: ${errorMessage}`);
|
|
30
25
|
}
|
|
31
26
|
// Crear instancia del agente con las credenciales guardadas
|
|
32
|
-
const agent = new
|
|
27
|
+
const agent = new Agent({
|
|
33
28
|
workspaceId: credentials.workspace,
|
|
34
29
|
apiKey: credentials.apiKey,
|
|
35
30
|
zone: credentials.zone,
|
|
36
31
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
37
32
|
});
|
|
38
|
-
|
|
33
|
+
logger.dim('Updating agent...');
|
|
39
34
|
// Actualizar el agente
|
|
40
35
|
const result = await agent.updateAgent(agentId, agentConfig);
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
logger.success('Agent updated successfully');
|
|
37
|
+
logger.info(`Message: ${result.message}`);
|
|
43
38
|
if (options.dev) {
|
|
44
|
-
|
|
39
|
+
logger.warning('Environment: development');
|
|
45
40
|
}
|
|
46
41
|
}
|
|
47
42
|
catch (error) {
|
|
48
|
-
const message = error instanceof Error ? error.message : '
|
|
49
|
-
|
|
43
|
+
const message = error instanceof Error ? error.message : 'Unknown error while updating the agent';
|
|
44
|
+
logger.error(message);
|
|
50
45
|
process.exit(1);
|
|
51
46
|
}
|
|
52
47
|
});
|
|
48
|
+
addExamples(updateCommand, [
|
|
49
|
+
{ description: 'Push a new configuration to the agent',
|
|
50
|
+
command: 'plazbot agent update agt_AbcDef123 ./agent.json' },
|
|
51
|
+
{ description: 'Tip: export → edit → update workflow',
|
|
52
|
+
command: 'plazbot agent export agt_AbcDef123 -o agent.json && plazbot agent update agt_AbcDef123 ./agent.json' },
|
|
53
|
+
]);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import { resolve, dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import Ajv from 'ajv';
|
|
6
|
+
import addFormats from 'ajv-formats';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { logger } from '../../utils/logger.js';
|
|
9
|
+
import { addExamples } from '../../utils/help.js';
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
// El schema se copia a dist/schemas durante el build.
|
|
13
|
+
// Buscar primero en dist/schemas (produccion) y luego en src/schemas (dev/ts-node).
|
|
14
|
+
function loadSchema() {
|
|
15
|
+
const candidates = [
|
|
16
|
+
join(__dirname, '..', '..', 'schemas', 'agent.config.schema.json'), // dist/commands/agent -> dist/schemas
|
|
17
|
+
join(__dirname, '..', '..', '..', 'src', 'schemas', 'agent.config.schema.json'), // fallback dev
|
|
18
|
+
];
|
|
19
|
+
for (const candidate of candidates) {
|
|
20
|
+
if (existsSync(candidate)) {
|
|
21
|
+
return JSON.parse(readFileSync(candidate, 'utf-8'));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error('No se encontro el schema agent.config.schema.json. Reinstala el CLI.');
|
|
25
|
+
}
|
|
26
|
+
// Traduce una ruta de AJV (e.g. "/actions/0/action/2") en migas legibles
|
|
27
|
+
// estilo "acciones -> 0 -> action -> 2".
|
|
28
|
+
function humanizePath(instancePath) {
|
|
29
|
+
if (!instancePath || instancePath === '')
|
|
30
|
+
return '(raiz)';
|
|
31
|
+
return instancePath
|
|
32
|
+
.replace(/^\//, '')
|
|
33
|
+
.split('/')
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.join(' -> ');
|
|
36
|
+
}
|
|
37
|
+
function formatError(err) {
|
|
38
|
+
const path = humanizePath(err.instancePath);
|
|
39
|
+
const keyword = err.keyword;
|
|
40
|
+
let detail = err.message || 'error de validacion';
|
|
41
|
+
if (keyword === 'required' && err.params && err.params.missingProperty) {
|
|
42
|
+
detail = `debe tener la propiedad requerida '${err.params.missingProperty}'`;
|
|
43
|
+
}
|
|
44
|
+
else if (keyword === 'enum' && err.params && err.params.allowedValues) {
|
|
45
|
+
const allowed = err.params.allowedValues;
|
|
46
|
+
detail = `debe ser uno de: ${allowed.join(', ')}`;
|
|
47
|
+
}
|
|
48
|
+
else if (keyword === 'type' && err.params && err.params.type) {
|
|
49
|
+
detail = `debe ser de tipo ${err.params.type}`;
|
|
50
|
+
}
|
|
51
|
+
else if (keyword === 'minLength') {
|
|
52
|
+
detail = 'no puede estar vacio';
|
|
53
|
+
}
|
|
54
|
+
else if (keyword === 'pattern') {
|
|
55
|
+
detail = `no cumple el patron ${err.params.pattern}`;
|
|
56
|
+
}
|
|
57
|
+
return `${path}: ${detail}`;
|
|
58
|
+
}
|
|
59
|
+
export const validateCommand = new Command('validate')
|
|
60
|
+
.description('Validate an agent JSON file against the official schema')
|
|
61
|
+
.argument('<file>', 'Path to the agent JSON file')
|
|
62
|
+
.option('--strict', 'Fail on additional unknown properties', false)
|
|
63
|
+
.option('--raw', 'Print raw AJV errors as JSON', false)
|
|
64
|
+
.action(async (file, options) => {
|
|
65
|
+
try {
|
|
66
|
+
const filePath = resolve(process.cwd(), file);
|
|
67
|
+
if (!existsSync(filePath)) {
|
|
68
|
+
logger.error(`No existe el archivo: ${filePath}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
let data;
|
|
72
|
+
try {
|
|
73
|
+
data = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
74
|
+
}
|
|
75
|
+
catch (parseErr) {
|
|
76
|
+
const msg = parseErr instanceof Error ? parseErr.message : 'JSON invalido';
|
|
77
|
+
logger.error(`JSON con sintaxis invalida: ${msg}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const schema = loadSchema();
|
|
81
|
+
const ajv = new Ajv({
|
|
82
|
+
allErrors: true,
|
|
83
|
+
strict: false,
|
|
84
|
+
strictTypes: false,
|
|
85
|
+
});
|
|
86
|
+
addFormats(ajv);
|
|
87
|
+
const validate = ajv.compile(schema);
|
|
88
|
+
const ok = validate(data);
|
|
89
|
+
if (ok) {
|
|
90
|
+
console.log();
|
|
91
|
+
console.log(chalk.hex('#66BB6A')(' Schema valido'));
|
|
92
|
+
const name = data?.name ? ` (${data.name})` : '';
|
|
93
|
+
console.log(chalk.gray(` El agente${name} cumple con el schema oficial.`));
|
|
94
|
+
console.log();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Filtrar errores AJV redundantes generados por allOf/if-then:
|
|
98
|
+
// "must match 'then' schema" siempre acompana a un error real con misma path.
|
|
99
|
+
const rawErrors = validate.errors || [];
|
|
100
|
+
const errors = rawErrors.filter(e => e.keyword !== 'if' && !/match "then" schema/.test(e.message || ''));
|
|
101
|
+
if (options.raw) {
|
|
102
|
+
console.log(JSON.stringify(errors, null, 2));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
console.log();
|
|
106
|
+
console.log(chalk.hex('#EF5350')(` Schema invalido (${errors.length} ${errors.length === 1 ? 'error' : 'errores'}):`));
|
|
107
|
+
console.log();
|
|
108
|
+
errors.forEach((err, i) => {
|
|
109
|
+
console.log(chalk.hex('#EF5350')(` ${i + 1}. ${formatError(err)}`));
|
|
110
|
+
});
|
|
111
|
+
console.log();
|
|
112
|
+
console.log(chalk.gray(' Sugerencia: usa --raw para inspeccionar los errores AJV en JSON.'));
|
|
113
|
+
console.log();
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const message = error instanceof Error ? error.message : 'Error desconocido';
|
|
118
|
+
logger.error(message);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
addExamples(validateCommand, [
|
|
123
|
+
{ description: 'Validate an exported agent file against the schema',
|
|
124
|
+
command: 'plazbot agent validate ./agent.json' },
|
|
125
|
+
{ description: 'Print raw AJV errors as JSON for tooling',
|
|
126
|
+
command: 'plazbot agent validate ./agent.json --raw' },
|
|
127
|
+
]);
|