plazbot-cli 0.2.26 → 0.3.1

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.
Files changed (178) hide show
  1. package/CLAUDE.md +34 -5
  2. package/README.md +21 -0
  3. package/dist/cli.js +32 -20
  4. package/dist/commands/agent/ai-config.js +98 -50
  5. package/dist/commands/agent/chat.js +80 -74
  6. package/dist/commands/agent/copy.js +23 -21
  7. package/dist/commands/agent/create.js +42 -72
  8. package/dist/commands/agent/delete.js +29 -30
  9. package/dist/commands/agent/enable-widget.js +30 -26
  10. package/dist/commands/agent/export.js +90 -77
  11. package/dist/commands/agent/files.js +68 -60
  12. package/dist/commands/agent/get.js +101 -87
  13. package/dist/commands/agent/index.js +53 -39
  14. package/dist/commands/agent/list.js +26 -24
  15. package/dist/commands/agent/monitor.js +91 -86
  16. package/dist/commands/agent/on-message.js +40 -37
  17. package/dist/commands/agent/set.js +62 -59
  18. package/dist/commands/agent/templates.js +109 -108
  19. package/dist/commands/agent/tools.js +64 -65
  20. package/dist/commands/agent/update.js +28 -27
  21. package/dist/commands/agent/validate.js +127 -0
  22. package/dist/commands/agent/wizard.js +152 -159
  23. package/dist/commands/auth/index.js +7 -10
  24. package/dist/commands/auth/login.js +50 -37
  25. package/dist/commands/auth/logout.js +16 -14
  26. package/dist/commands/auth/status.js +19 -16
  27. package/dist/commands/portal/add-agent.js +26 -24
  28. package/dist/commands/portal/add-link.js +21 -17
  29. package/dist/commands/portal/clear-links.js +17 -15
  30. package/dist/commands/portal/create.js +25 -21
  31. package/dist/commands/portal/delete.js +31 -30
  32. package/dist/commands/portal/get.js +33 -31
  33. package/dist/commands/portal/index.js +30 -22
  34. package/dist/commands/portal/list.js +34 -30
  35. package/dist/commands/portal/update.js +41 -33
  36. package/dist/commands/whatsapp/broadcast.js +40 -37
  37. package/dist/commands/whatsapp/channels.js +40 -34
  38. package/dist/commands/whatsapp/chat.js +33 -32
  39. package/dist/commands/whatsapp/connect.js +53 -52
  40. package/dist/commands/whatsapp/delete-webhook.js +19 -17
  41. package/dist/commands/whatsapp/index.js +35 -25
  42. package/dist/commands/whatsapp/register-webhook.js +21 -19
  43. package/dist/commands/whatsapp/send-template.js +39 -31
  44. package/dist/commands/whatsapp/send.js +27 -23
  45. package/dist/commands/whatsapp/widget.js +35 -31
  46. package/dist/commands/workers/deploy.js +49 -44
  47. package/dist/commands/workers/index.js +28 -18
  48. package/dist/commands/workers/list.js +43 -35
  49. package/dist/commands/workers/logs.js +38 -32
  50. package/dist/commands/workers/remove.js +38 -37
  51. package/dist/commands/workers/secret.js +63 -58
  52. package/dist/commands/workers/test.js +44 -36
  53. package/dist/schemas/agent.config.schema.json +569 -0
  54. package/dist/studio/api/sseClient.js +97 -0
  55. package/dist/studio/api/studioApi.js +25 -0
  56. package/dist/studio/api/types.js +16 -0
  57. package/dist/studio/components/AgentPanel.js +35 -0
  58. package/dist/studio/components/App.js +214 -0
  59. package/dist/studio/components/ChatLog.js +59 -0
  60. package/dist/studio/components/Footer.js +11 -0
  61. package/dist/studio/components/Header.js +8 -0
  62. package/dist/studio/components/Input.js +15 -0
  63. package/dist/studio/components/Message.js +56 -0
  64. package/dist/studio/components/Suggestions.js +11 -0
  65. package/dist/studio/components/ToolCall.js +33 -0
  66. package/dist/studio/components/WhatsappConnectCard.js +57 -0
  67. package/dist/studio/index.js +42 -0
  68. package/dist/studio/render/json.js +16 -0
  69. package/dist/studio/render/markdown.js +32 -0
  70. package/dist/studio/render/steps.js +58 -0
  71. package/dist/studio/runOneShot.js +96 -0
  72. package/dist/studio/runRepl.js +52 -0
  73. package/dist/studio/slash/handlers.js +199 -0
  74. package/dist/studio/slash/parser.js +46 -0
  75. package/dist/studio/slash/registry.js +16 -0
  76. package/dist/studio/state/store.js +181 -0
  77. package/dist/studio/whatsapp/api.js +63 -0
  78. package/dist/studio/whatsapp/polling.js +77 -0
  79. package/dist/studio/whatsapp/types.js +31 -0
  80. package/dist/types/agent.js +1 -2
  81. package/dist/types/auth.js +1 -2
  82. package/dist/types/common.js +1 -2
  83. package/dist/types/message.js +1 -2
  84. package/dist/types/portal.js +1 -2
  85. package/dist/types/workers.js +1 -2
  86. package/dist/utils/agent-errors.js +46 -0
  87. package/dist/utils/api.js +8 -9
  88. package/dist/utils/banner.js +33 -34
  89. package/dist/utils/credentials.js +12 -20
  90. package/dist/utils/help.js +44 -0
  91. package/dist/utils/logger.js +13 -19
  92. package/dist/utils/ui.js +35 -49
  93. package/package.json +21 -10
  94. package/src/cli.ts +24 -8
  95. package/src/commands/agent/ai-config.ts +89 -34
  96. package/src/commands/agent/chat.ts +49 -37
  97. package/src/commands/agent/copy.ts +19 -13
  98. package/src/commands/agent/create.ts +32 -22
  99. package/src/commands/agent/delete.ts +24 -18
  100. package/src/commands/agent/enable-widget.ts +31 -23
  101. package/src/commands/agent/export.ts +72 -51
  102. package/src/commands/agent/files.ts +51 -39
  103. package/src/commands/agent/get.ts +86 -66
  104. package/src/commands/agent/index.ts +36 -18
  105. package/src/commands/agent/list.ts +22 -16
  106. package/src/commands/agent/monitor.ts +67 -56
  107. package/src/commands/agent/on-message.ts +36 -27
  108. package/src/commands/agent/set.ts +47 -37
  109. package/src/commands/agent/templates.ts +90 -82
  110. package/src/commands/agent/tools.ts +53 -47
  111. package/src/commands/agent/update.ts +28 -20
  112. package/src/commands/agent/validate.ts +135 -0
  113. package/src/commands/agent/wizard.ts +114 -114
  114. package/src/commands/auth/index.ts +3 -3
  115. package/src/commands/auth/login.ts +44 -29
  116. package/src/commands/auth/logout.ts +16 -10
  117. package/src/commands/auth/status.ts +14 -8
  118. package/src/commands/portal/add-agent.ts +23 -17
  119. package/src/commands/portal/add-link.ts +17 -9
  120. package/src/commands/portal/clear-links.ts +13 -7
  121. package/src/commands/portal/create.ts +20 -12
  122. package/src/commands/portal/delete.ts +28 -20
  123. package/src/commands/portal/get.ts +25 -19
  124. package/src/commands/portal/index.ts +22 -10
  125. package/src/commands/portal/list.ts +27 -19
  126. package/src/commands/portal/update.ts +38 -26
  127. package/src/commands/whatsapp/broadcast.ts +28 -18
  128. package/src/commands/whatsapp/channels.ts +31 -20
  129. package/src/commands/whatsapp/chat.ts +20 -12
  130. package/src/commands/whatsapp/connect.ts +39 -31
  131. package/src/commands/whatsapp/delete-webhook.ts +15 -9
  132. package/src/commands/whatsapp/index.ts +24 -10
  133. package/src/commands/whatsapp/register-webhook.ts +16 -10
  134. package/src/commands/whatsapp/send-template.ts +33 -21
  135. package/src/commands/whatsapp/send.ts +23 -15
  136. package/src/commands/whatsapp/widget.ts +25 -17
  137. package/src/commands/workers/deploy.ts +34 -22
  138. package/src/commands/workers/index.ts +21 -7
  139. package/src/commands/workers/list.ts +31 -19
  140. package/src/commands/workers/logs.ts +30 -20
  141. package/src/commands/workers/remove.ts +30 -22
  142. package/src/commands/workers/secret.ts +46 -34
  143. package/src/commands/workers/test.ts +34 -22
  144. package/src/schemas/agent.config.schema.json +569 -0
  145. package/src/studio/api/sseClient.ts +91 -0
  146. package/src/studio/api/studioApi.ts +27 -0
  147. package/src/studio/api/types.ts +96 -0
  148. package/src/studio/components/App.tsx +266 -0
  149. package/src/studio/components/ChatLog.tsx +95 -0
  150. package/src/studio/components/Footer.tsx +38 -0
  151. package/src/studio/components/Header.tsx +39 -0
  152. package/src/studio/components/Input.tsx +32 -0
  153. package/src/studio/components/Message.tsx +87 -0
  154. package/src/studio/components/Suggestions.tsx +26 -0
  155. package/src/studio/components/ToolCall.tsx +58 -0
  156. package/src/studio/components/WhatsappConnectCard.tsx +139 -0
  157. package/src/studio/index.ts +58 -0
  158. package/src/studio/render/markdown.ts +32 -0
  159. package/src/studio/render/steps.ts +57 -0
  160. package/src/studio/runOneShot.ts +114 -0
  161. package/src/studio/runRepl.tsx +76 -0
  162. package/src/studio/slash/handlers.ts +226 -0
  163. package/src/studio/slash/parser.ts +41 -0
  164. package/src/studio/slash/registry.ts +54 -0
  165. package/src/studio/state/store.ts +273 -0
  166. package/src/studio/whatsapp/api.ts +96 -0
  167. package/src/studio/whatsapp/polling.ts +93 -0
  168. package/src/studio/whatsapp/types.ts +80 -0
  169. package/src/types/agent.ts +1 -1
  170. package/src/types/auth.ts +4 -3
  171. package/src/types/portal.ts +1 -1
  172. package/src/types/workers.ts +1 -1
  173. package/src/utils/agent-errors.ts +67 -0
  174. package/src/utils/api.ts +6 -0
  175. package/src/utils/banner.ts +14 -9
  176. package/src/utils/credentials.ts +6 -5
  177. package/src/utils/help.ts +51 -0
  178. package/tsconfig.json +9 -6
package/dist/utils/ui.js CHANGED
@@ -1,44 +1,30 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.theme = void 0;
7
- exports.createSpinner = createSpinner;
8
- exports.createTable = createTable;
9
- exports.box = box;
10
- exports.formatDate = formatDate;
11
- exports.statusBadge = statusBadge;
12
- exports.kvPair = kvPair;
13
- exports.section = section;
14
- exports.progressBar = progressBar;
15
- const chalk_1 = __importDefault(require("chalk"));
16
- const ora_1 = __importDefault(require("ora"));
17
- const cli_table3_1 = __importDefault(require("cli-table3"));
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import Table from 'cli-table3';
18
4
  // Colores del tema Plazbot
19
- exports.theme = {
20
- primary: chalk_1.default.hex('#4CAF50'),
21
- secondary: chalk_1.default.hex('#2196F3'),
22
- accent: chalk_1.default.hex('#FFA726'),
23
- success: chalk_1.default.hex('#66BB6A'),
24
- error: chalk_1.default.hex('#EF5350'),
25
- warning: chalk_1.default.hex('#FFA726'),
26
- muted: chalk_1.default.gray,
27
- bold: chalk_1.default.bold,
28
- dim: chalk_1.default.dim,
5
+ export const theme = {
6
+ primary: chalk.hex('#4CAF50'),
7
+ secondary: chalk.hex('#2196F3'),
8
+ accent: chalk.hex('#FFA726'),
9
+ success: chalk.hex('#66BB6A'),
10
+ error: chalk.hex('#EF5350'),
11
+ warning: chalk.hex('#FFA726'),
12
+ muted: chalk.gray,
13
+ bold: chalk.bold,
14
+ dim: chalk.dim,
29
15
  };
30
16
  // Spinner
31
- function createSpinner(text) {
32
- return (0, ora_1.default)({
33
- text: exports.theme.muted(text),
17
+ export function createSpinner(text) {
18
+ return ora({
19
+ text: theme.muted(text),
34
20
  spinner: 'dots',
35
21
  color: 'green',
36
22
  });
37
23
  }
38
24
  // Tabla formateada
39
- function createTable(headers, rows) {
40
- const table = new cli_table3_1.default({
41
- head: headers.map(h => exports.theme.bold.hex('#4CAF50')(h)),
25
+ export function createTable(headers, rows) {
26
+ const table = new Table({
27
+ head: headers.map(h => theme.bold.hex('#4CAF50')(h)),
42
28
  style: {
43
29
  head: [],
44
30
  border: ['gray'],
@@ -54,22 +40,22 @@ function createTable(headers, rows) {
54
40
  return table.toString();
55
41
  }
56
42
  // Box simple
57
- function box(content, title) {
43
+ export function box(content, title) {
58
44
  const lines = content.split('\n');
59
45
  const maxLen = Math.max(...lines.map(l => stripAnsi(l).length), title ? stripAnsi(title).length + 4 : 0);
60
46
  const width = maxLen + 4;
61
47
  let result = '';
62
48
  if (title) {
63
- result += exports.theme.muted(' ┌─ ') + exports.theme.primary(title) + exports.theme.muted(' ' + '─'.repeat(Math.max(0, width - stripAnsi(title).length - 5))) + exports.theme.muted('┐') + '\n';
49
+ result += theme.muted(' ┌─ ') + theme.primary(title) + theme.muted(' ' + '─'.repeat(Math.max(0, width - stripAnsi(title).length - 5))) + theme.muted('┐') + '\n';
64
50
  }
65
51
  else {
66
- result += exports.theme.muted(' ┌' + '─'.repeat(width) + '┐') + '\n';
52
+ result += theme.muted(' ┌' + '─'.repeat(width) + '┐') + '\n';
67
53
  }
68
54
  for (const line of lines) {
69
55
  const pad = ' '.repeat(Math.max(0, maxLen - stripAnsi(line).length));
70
- result += exports.theme.muted(' │') + ' ' + line + pad + ' ' + exports.theme.muted('│') + '\n';
56
+ result += theme.muted(' │') + ' ' + line + pad + ' ' + theme.muted('│') + '\n';
71
57
  }
72
- result += exports.theme.muted(' └' + '─'.repeat(width) + '┘');
58
+ result += theme.muted(' └' + '─'.repeat(width) + '┘');
73
59
  return result;
74
60
  }
75
61
  // Strip ANSI codes para calcular longitud real
@@ -77,7 +63,7 @@ function stripAnsi(str) {
77
63
  return str.replace(/\x1b\[[0-9;]*m/g, '');
78
64
  }
79
65
  // Formato de fecha legible
80
- function formatDate(date) {
66
+ export function formatDate(date) {
81
67
  const d = new Date(date);
82
68
  return d.toLocaleDateString('es-ES', {
83
69
  year: 'numeric',
@@ -88,24 +74,24 @@ function formatDate(date) {
88
74
  });
89
75
  }
90
76
  // Status badge
91
- function statusBadge(enabled) {
77
+ export function statusBadge(enabled) {
92
78
  return enabled
93
- ? exports.theme.success('● activo')
94
- : exports.theme.error('○ inactivo');
79
+ ? theme.success('● activo')
80
+ : theme.error('○ inactivo');
95
81
  }
96
82
  // Key-value pair formateado
97
- function kvPair(key, value) {
98
- return ` ${exports.theme.muted(key + ':')} ${value}`;
83
+ export function kvPair(key, value) {
84
+ return ` ${theme.muted(key + ':')} ${value}`;
99
85
  }
100
86
  // Sección con título
101
- function section(title) {
102
- return '\n' + exports.theme.bold.hex('#4CAF50')(` ${title}`) + '\n' + exports.theme.muted(' ' + '─'.repeat(40));
87
+ export function section(title) {
88
+ return '\n' + theme.bold.hex('#4CAF50')(` ${title}`) + '\n' + theme.muted(' ' + '─'.repeat(40));
103
89
  }
104
90
  // Progress bar simple
105
- function progressBar(current, total, width = 30) {
91
+ export function progressBar(current, total, width = 30) {
106
92
  const percent = Math.round((current / total) * 100);
107
93
  const filled = Math.round((current / total) * width);
108
94
  const empty = width - filled;
109
- const bar = exports.theme.success('█'.repeat(filled)) + exports.theme.muted('░'.repeat(empty));
110
- return `${bar} ${exports.theme.bold(percent + '%')} (${current}/${total})`;
95
+ const bar = theme.success('█'.repeat(filled)) + theme.muted('░'.repeat(empty));
96
+ return `${bar} ${theme.bold(percent + '%')} (${current}/${total})`;
111
97
  }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "plazbot-cli",
3
- "version": "0.2.26",
3
+ "version": "0.3.1",
4
4
  "description": "CLI para Plazbot SDK",
5
+ "type": "module",
5
6
  "main": "dist/cli.js",
6
7
  "bin": {
7
8
  "plazbot": "dist/cli.js"
8
9
  },
9
10
  "scripts": {
10
- "build": "tsc",
11
+ "build": "tsc && mkdir -p dist/schemas && cp src/schemas/*.json dist/schemas/ && chmod +x dist/cli.js",
11
12
  "start": "node dist/cli.js",
12
13
  "dev": "tsc -w",
14
+ "typecheck": "tsc --noEmit",
13
15
  "prepare:dev": "npm uninstall plazbot && npm install file:../Plazbot-SDK-v2.0",
14
16
  "prepare:prod": "npm uninstall plazbot && npm install plazbot@latest",
15
17
  "prepublishOnly": "npm run prepare:prod && npm run build",
@@ -32,25 +34,34 @@
32
34
  "license": "MIT",
33
35
  "dependencies": {
34
36
  "@microsoft/signalr": "^10.0.0",
35
- "@types/inquirer": "^9.0.8",
37
+ "ajv": "^8.20.0",
38
+ "ajv-formats": "^3.0.1",
36
39
  "axios": "^1.6.0",
37
- "boxen": "^5.1.2",
38
- "chalk": "^4.1.2",
40
+ "boxen": "^7.1.1",
41
+ "chalk": "^5.3.0",
39
42
  "cli-table3": "^0.6.5",
40
43
  "commander": "^12.0.0",
41
- "figures": "^3.2.0",
42
- "gradient-string": "^2.0.2",
44
+ "figures": "^6.1.0",
45
+ "gradient-string": "^3.0.0",
46
+ "ink": "^5.0.1",
47
+ "ink-spinner": "^5.0.0",
48
+ "ink-syntax-highlight": "^2.0.2",
49
+ "ink-text-input": "^6.0.0",
43
50
  "inquirer": "^12.6.3",
44
51
  "marked": "^12.0.2",
45
52
  "marked-terminal": "^7.2.1",
46
- "ora": "^5.4.1",
47
- "plazbot": "^2.1.4"
53
+ "ora": "^8.0.1",
54
+ "plazbot": "^2.1.4",
55
+ "react": "^18.3.1",
56
+ "zustand": "^4.5.4"
48
57
  },
49
58
  "devDependencies": {
59
+ "@types/inquirer": "^9.0.8",
50
60
  "@types/node": "^20.0.0",
61
+ "@types/react": "^18.3.3",
51
62
  "typescript": "^5.0.0"
52
63
  },
53
64
  "engines": {
54
- "node": ">=16.0.0"
65
+ "node": ">=18.17.0"
55
66
  }
56
67
  }
package/src/cli.ts CHANGED
@@ -1,19 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
- import { portalCommands } from './commands/portal';
4
- import { authCommands } from './commands/auth';
5
- import { agentCommands } from './commands/agent';
6
- import { whatsappCommands } from './commands/whatsapp';
7
- import { workersCommands } from './commands/workers';
8
- import { showBanner } from './utils/banner';
3
+ import { readFileSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ import { portalCommands } from './commands/portal/index.js';
7
+ import { authCommands } from './commands/auth/index.js';
8
+ import { agentCommands } from './commands/agent/index.js';
9
+ import { whatsappCommands } from './commands/whatsapp/index.js';
10
+ import { workersCommands } from './commands/workers/index.js';
11
+ import { studioCommand } from './studio/index.js';
12
+ import { showBanner } from './utils/banner.js';
13
+
14
+ // Guard de runtime: Plazbot CLI v0.3+ requiere Node 18.17+
15
+ const [major, minor] = process.versions.node.split('.').map(Number);
16
+ if (major < 18 || (major === 18 && minor < 17)) {
17
+ console.error(`Plazbot CLI v0.3+ requires Node.js >=18.17.0. Current version: ${process.versions.node}`);
18
+ process.exit(1);
19
+ }
9
20
 
10
21
  // Leer version desde package.json
11
- const { version } = require('../package.json');
22
+ const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ const pkgPath = join(__dirname, '..', 'package.json');
24
+ const { version } = JSON.parse(readFileSync(pkgPath, 'utf-8'));
12
25
 
13
26
  // Configuracion basica del CLI
14
27
  program
15
28
  .name('plazbot')
16
- .description('CLI oficial de Plazbot - Agentes de IA para WhatsApp, portales y desarrolladores')
29
+ .description('Official Plazbot CLI - AI agents for WhatsApp, portals and developers')
17
30
  .version(version);
18
31
 
19
32
  // Registrar todos los comandos de autenticacion
@@ -31,6 +44,9 @@ program.addCommand(whatsappCommands);
31
44
  // Registrar todos los comandos de Workers
32
45
  program.addCommand(workersCommands);
33
46
 
47
+ // Registrar el comando Studio (REPL interactivo)
48
+ program.addCommand(studioCommand);
49
+
34
50
  // Si no se pasan argumentos, mostrar banner
35
51
  if (process.argv.length <= 2) {
36
52
  showBanner().then(() => {
@@ -1,21 +1,64 @@
1
1
  import { Command } from 'commander';
2
2
  import { Agent } from 'plazbot';
3
3
  import inquirer from 'inquirer';
4
- import { getStoredCredentials } from '../../utils/credentials';
5
- import { logger } from '../../utils/logger';
6
- import { createSpinner, theme, section, kvPair } from '../../utils/ui';
7
- import { AgentCommandOptions } from '../../types/agent';
4
+ import { getStoredCredentials } from '../../utils/credentials.js';
5
+ import { logger } from '../../utils/logger.js';
6
+ import { addExamples } from '../../utils/help.js';
7
+ import { describeAgentLoadError } from '../../utils/agent-errors.js';
8
+ import { createSpinner, theme, section, kvPair } from '../../utils/ui.js';
9
+ import { AgentCommandOptions } from '../../types/agent.js';
8
10
 
11
+ // Catalogo de modelos sincronizado con el front (AIModelSection.tsx).
12
+ // Si se actualiza el dropdown del front, actualizar aqui tambien.
9
13
  const MODELS: Record<string, string[]> = {
10
- openai: ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo', 'o1-preview', 'o1-mini'],
11
- claude: ['claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'],
12
- gemini: ['gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
14
+ openai: [
15
+ // GPT-5.4 (flagship actual)
16
+ 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano',
17
+ // GPT-5.2
18
+ 'gpt-5.2',
19
+ // GPT-5.1
20
+ 'gpt-5.1', 'gpt-5.1-codex', 'gpt-5.1-codex-mini',
21
+ // GPT-5
22
+ 'gpt-5', 'gpt-5-mini', 'gpt-5-nano',
23
+ // GPT-4.1
24
+ 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4.1-nano',
25
+ // GPT-4o
26
+ 'gpt-4o', 'gpt-4o-mini',
27
+ // Razonamiento (o-series)
28
+ 'o4-mini', 'o3', 'o3-mini', 'o1-2024-12-17',
29
+ // Legacy
30
+ 'gpt-4-turbo', 'gpt-3.5-turbo',
31
+ ],
32
+ claude: [
33
+ // Mythos-class (flagship)
34
+ 'claude-fable-5',
35
+ // Claude 4.6
36
+ 'claude-opus-4-6', 'claude-sonnet-4-6',
37
+ // Claude 4.5
38
+ 'claude-opus-4-5-20251101', 'claude-sonnet-4-5-20250929', 'claude-haiku-4-5-20251001',
39
+ // Claude 4.x
40
+ 'claude-opus-4-1-20250805', 'claude-opus-4-20250514', 'claude-sonnet-4-20250514',
41
+ ],
42
+ gemini: [
43
+ // Gemini 3.1 (flagship actual)
44
+ 'gemini-3.1-pro-preview', 'gemini-3.1-flash-lite-preview',
45
+ // Gemini 2.5
46
+ 'gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.5-flash-lite',
47
+ // Gemini 2.0
48
+ 'gemini-2.0-flash',
49
+ ],
50
+ };
51
+
52
+ const DEFAULT_MODEL: Record<string, string> = {
53
+ openai: 'gpt-4o',
54
+ claude: 'claude-sonnet-4-6',
55
+ gemini: 'gemini-2.5-pro',
13
56
  };
14
57
 
15
58
  export const aiConfigCommand = new Command('ai-config')
16
- .description('Configurar proveedor de IA del agente')
17
- .argument('<agentId>', 'ID del agente')
18
- .option('--dev', 'Usar ambiente de desarrollo', false)
59
+ .description('Configure the agent AI provider')
60
+ .argument('<agentId>', 'Agent ID')
61
+ .option('--dev', 'Use development environment', false)
19
62
  .action(async (agentId: string, options: AgentCommandOptions) => {
20
63
  try {
21
64
  const credentials = await getStoredCredentials();
@@ -26,36 +69,43 @@ export const aiConfigCommand = new Command('ai-config')
26
69
  ...(options.dev && { customUrl: "http://localhost:5090" })
27
70
  });
28
71
 
29
- const spinner = createSpinner('Cargando agente...');
72
+ const spinner = createSpinner('Loading agent...');
30
73
  spinner.start();
31
- const _res: any = await agent.getAgentById({ id: agentId });
32
- const agentData = _res.agent || _res.data || _res;
33
- spinner.stop();
74
+ let agentData: any;
75
+ try {
76
+ const _res: any = await agent.getAgentById({ id: agentId });
77
+ agentData = _res.agent || _res.data || _res;
78
+ spinner.stop();
79
+ } catch (loadErr) {
80
+ spinner.stop();
81
+ logger.error(describeAgentLoadError(loadErr, agentId, credentials, { dev: options.dev }));
82
+ process.exit(1);
83
+ }
34
84
 
35
- console.log(section('Configuracion de IA - ' + (agentData.name || agentId)));
85
+ console.log(section('AI Configuration - ' + (agentData.name || agentId)));
36
86
 
37
87
  const currentProviders = agentData.aiProviders || [];
38
88
  if (currentProviders.length > 0 && agentData.customAIConfig) {
39
- console.log(theme.bold('\n Configuracion actual:'));
89
+ console.log(theme.bold('\n Current configuration:'));
40
90
  currentProviders.forEach((p: any) => {
41
- console.log(kvPair(' Proveedor', p.provider));
42
- console.log(kvPair(' Modelo', p.model));
43
- console.log(kvPair(' Temperatura', String(p.temperature)));
91
+ console.log(kvPair(' Provider', p.provider));
92
+ console.log(kvPair(' Model', p.model));
93
+ console.log(kvPair(' Temperature', String(p.temperature)));
44
94
  console.log(kvPair(' Max Tokens', String(p.maxTokens)));
45
- console.log(kvPair(' Default', p.isDefault ? 'Si' : 'No'));
95
+ console.log(kvPair(' Default', p.isDefault ? 'Yes' : 'No'));
46
96
  });
47
97
  } else {
48
- console.log(theme.muted('\n Usando configuracion de IA por defecto (Plazbot)'));
98
+ console.log(theme.muted('\n Using default AI configuration (Plazbot)'));
49
99
  }
50
100
 
51
101
  const { action } = await (inquirer as any).prompt([{
52
102
  type: 'list',
53
103
  name: 'action',
54
- message: 'Que deseas hacer?',
104
+ message: 'What would you like to do?',
55
105
  choices: [
56
- { name: 'Configurar nuevo proveedor', value: 'set' },
57
- { name: 'Usar configuracion por defecto', value: 'reset' },
58
- { name: 'Salir', value: 'exit' },
106
+ { name: 'Configure new provider', value: 'set' },
107
+ { name: 'Use default configuration', value: 'reset' },
108
+ { name: 'Exit', value: 'exit' },
59
109
  ],
60
110
  }]);
61
111
 
@@ -63,24 +113,24 @@ export const aiConfigCommand = new Command('ai-config')
63
113
 
64
114
  if (action === 'reset') {
65
115
  const { id, _id, ...resetConfig } = { ...agentData, customAIConfig: false, aiProviders: [] };
66
- const resetSpinner = createSpinner('Reseteando configuracion...');
116
+ const resetSpinner = createSpinner('Resetting configuration...');
67
117
  resetSpinner.start();
68
118
  await agent.updateAgent(agentId, resetConfig);
69
- resetSpinner.succeed('Usando configuracion por defecto');
119
+ resetSpinner.succeed('Using default configuration');
70
120
  return;
71
121
  }
72
122
 
73
123
  // Configurar nuevo proveedor
74
124
  const ai = await (inquirer as any).prompt([
75
- { type: 'list', name: 'provider', message: 'Proveedor:', choices: ['openai', 'claude', 'gemini'] },
125
+ { type: 'list', name: 'provider', message: 'Provider:', choices: ['openai', 'claude', 'gemini'] },
76
126
  ]);
77
127
 
78
128
  const models = MODELS[ai.provider] || MODELS.openai;
79
129
 
80
130
  const config = await (inquirer as any).prompt([
81
- { type: 'list', name: 'model', message: 'Modelo:', choices: models },
82
- { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Requerido' },
83
- { type: 'number', name: 'temperature', message: 'Temperatura (0-2):', default: 0.7 },
131
+ { type: 'list', name: 'model', message: 'Model:', choices: models, default: DEFAULT_MODEL[ai.provider] },
132
+ { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Required' },
133
+ { type: 'number', name: 'temperature', message: 'Temperature (0-2):', default: 0.7 },
84
134
  { type: 'number', name: 'maxTokens', message: 'Max tokens (1024-16384):', default: 4096 },
85
135
  ]);
86
136
 
@@ -96,14 +146,19 @@ export const aiConfigCommand = new Command('ai-config')
96
146
  isDefault: true,
97
147
  }],
98
148
  };
99
- const updateSpinner = createSpinner('Guardando configuracion...');
149
+ const updateSpinner = createSpinner('Saving configuration...');
100
150
  updateSpinner.start();
101
151
  await agent.updateAgent(agentId, updatedConfig);
102
- updateSpinner.succeed(`Proveedor configurado: ${ai.provider} / ${config.model}`);
152
+ updateSpinner.succeed(`Provider configured: ${ai.provider} / ${config.model}`);
103
153
 
104
154
  } catch (error) {
105
- const message = error instanceof Error ? error.message : 'Error desconocido';
155
+ const message = error instanceof Error ? error.message : 'Unknown error';
106
156
  logger.error(message);
107
157
  process.exit(1);
108
158
  }
109
159
  });
160
+
161
+ addExamples(aiConfigCommand, [
162
+ { description: 'Pick provider/model/API key for the agent interactively',
163
+ command: 'plazbot agent ai-config agt_AbcDef123' },
164
+ ]);
@@ -1,30 +1,31 @@
1
1
  import { Command } from 'commander';
2
2
  import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { AgentCommandOptions, AgentResponse, AgentSource } from '../../types/agent';
6
- import { theme, section } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { describeAgentLoadError } from '../../utils/agent-errors.js';
7
+ import { AgentCommandOptions, AgentResponse, AgentSource } from '../../types/agent.js';
8
+ import { theme, section } from '../../utils/ui.js';
7
9
  import crypto from 'crypto';
8
10
  import readline from 'readline';
9
11
  import chalk from 'chalk';
10
12
 
11
13
  const COMMANDS_HELP = `
12
- ${chalk.bold('Comandos disponibles:')}
13
- ${chalk.hex('#4CAF50')('/exit')} Terminar conversacion
14
- ${chalk.hex('#4CAF50')('/clear')} Limpiar pantalla
15
- ${chalk.hex('#4CAF50')('/info')} Informacion de la sesion
16
- ${chalk.hex('#4CAF50')('/sources')} Mostrar/ocultar fuentes
17
- ${chalk.hex('#4CAF50')('/help')} Mostrar estos comandos
14
+ ${chalk.bold('Available commands:')}
15
+ ${chalk.hex('#4CAF50')('/exit')} End conversation
16
+ ${chalk.hex('#4CAF50')('/clear')} Clear screen
17
+ ${chalk.hex('#4CAF50')('/info')} Session information
18
+ ${chalk.hex('#4CAF50')('/sources')} Toggle sources
19
+ ${chalk.hex('#4CAF50')('/help')} Show these commands
18
20
  `;
19
21
 
20
22
  export const chatCommand = new Command('chat')
21
- .description('Inicia una sesion de chat interactiva con un agente')
22
- .requiredOption('-a, --agent-id <id>', 'ID del agente')
23
- .option('-s, --session-id <id>', 'ID de sesion (opcional)')
24
- .option('-m, --multiple-answers', 'Permitir multiples respuestas', false)
25
- .option('--dev', 'Usar ambiente de desarrollo', false)
26
- .action(async (options: AgentCommandOptions & {
27
- agentId: string;
23
+ .description('Start an interactive chat session with an agent')
24
+ .argument('<agentId>', 'Agent ID')
25
+ .option('-s, --session-id <id>', 'Session ID (optional)')
26
+ .option('-m, --multiple-answers', 'Allow multiple answers', false)
27
+ .option('--dev', 'Use development environment', false)
28
+ .action(async (agentId: string, options: AgentCommandOptions & {
28
29
  sessionId?: string;
29
30
  multipleAnswers?: boolean;
30
31
  }) => {
@@ -44,12 +45,14 @@ export const chatCommand = new Command('chat')
44
45
  // Cargar info del agente
45
46
  let agentInfo: any = null;
46
47
  try {
47
- process.stdout.write(chalk.gray(' Conectando con agente...'));
48
- const _res: any = await agent.getAgentById({ id: options.agentId });
48
+ process.stdout.write(chalk.gray(' Connecting to agent...'));
49
+ const _res: any = await agent.getAgentById({ id: agentId });
49
50
  agentInfo = _res.agent || _res.data || _res;
50
51
  process.stdout.write('\r' + ' '.repeat(40) + '\r');
51
- } catch {
52
+ } catch (loadErr) {
52
53
  process.stdout.write('\r' + ' '.repeat(40) + '\r');
54
+ logger.error(describeAgentLoadError(loadErr, agentId, credentials, { dev: options.dev }));
55
+ process.exit(1);
53
56
  }
54
57
 
55
58
  const rl = readline.createInterface({
@@ -59,27 +62,27 @@ export const chatCommand = new Command('chat')
59
62
 
60
63
  // Pantalla de chat
61
64
  console.clear();
62
- const agentName = agentInfo?.name || 'Agente';
65
+ const agentName = agentInfo?.name || 'Agent';
63
66
  const toolCalling = agentInfo?.useToolCalling ? chalk.hex('#4CAF50')(' [Tool Calling]') : '';
64
67
 
65
68
  console.log();
66
69
  console.log(chalk.hex('#4CAF50')(' ┌' + '─'.repeat(58) + '┐'));
67
70
  console.log(chalk.hex('#4CAF50')(' │') + chalk.bold(` ${agentName}${toolCalling}`).padEnd(68) + chalk.hex('#4CAF50')('│'));
68
71
  console.log(chalk.hex('#4CAF50')(' │') + chalk.gray(` Session: ${sessionId.substring(0, 8)}...`).padEnd(68) + chalk.hex('#4CAF50')('│'));
69
- console.log(chalk.hex('#4CAF50')(' │') + chalk.gray(' /help para ver comandos').padEnd(68) + chalk.hex('#4CAF50')('│'));
72
+ console.log(chalk.hex('#4CAF50')(' │') + chalk.gray(' /help to see commands').padEnd(68) + chalk.hex('#4CAF50')('│'));
70
73
  console.log(chalk.hex('#4CAF50')(' └' + '─'.repeat(58) + '┘'));
71
74
  console.log();
72
75
 
73
76
  // Saludo del agente
74
77
  if (agentInfo?.instructions?.greeting) {
75
- const timestamp = new Date().toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' });
78
+ const timestamp = new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
76
79
  console.log(chalk.hex('#4CAF50')(` ${agentName}`) + chalk.gray(` ${timestamp}`));
77
80
  console.log(chalk.white(` ${agentInfo.instructions.greeting}`));
78
81
  console.log();
79
82
  }
80
83
 
81
84
  const askQuestion = () => {
82
- rl.question(chalk.hex('#2196F3')(' Tu > '), async (question) => {
85
+ rl.question(chalk.hex('#2196F3')(' You > '), async (question) => {
83
86
  if (!question.trim()) {
84
87
  askQuestion();
85
88
  return;
@@ -87,7 +90,7 @@ export const chatCommand = new Command('chat')
87
90
 
88
91
  // Comandos especiales
89
92
  if (question.toLowerCase() === '/exit') {
90
- console.log(chalk.gray('\n Sesion terminada.\n'));
93
+ console.log(chalk.gray('\n Session ended.\n'));
91
94
  rl.close();
92
95
  return;
93
96
  }
@@ -105,11 +108,11 @@ export const chatCommand = new Command('chat')
105
108
  }
106
109
 
107
110
  if (question.toLowerCase() === '/info') {
108
- console.log(section('Informacion de sesion'));
109
- logger.label('Agent ID', options.agentId);
111
+ console.log(section('Session information'));
112
+ logger.label('Agent ID', agentId);
110
113
  logger.label('Session ID', sessionId);
111
- logger.label('Agente', agentName);
112
- logger.label('Tool Calling', agentInfo?.useToolCalling ? 'Activado' : 'Desactivado');
114
+ logger.label('Agent', agentName);
115
+ logger.label('Tool Calling', agentInfo?.useToolCalling ? 'Enabled' : 'Disabled');
113
116
  logger.label('AI Provider', agentInfo?.customAIConfig ? (agentInfo.aiProviders?.[0]?.provider || 'Custom') : 'Default');
114
117
  console.log();
115
118
  askQuestion();
@@ -118,23 +121,23 @@ export const chatCommand = new Command('chat')
118
121
 
119
122
  if (question.toLowerCase() === '/sources') {
120
123
  showSources = !showSources;
121
- console.log(chalk.gray(` Fuentes: ${showSources ? 'activadas' : 'desactivadas'}`));
124
+ console.log(chalk.gray(` Sources: ${showSources ? 'on' : 'off'}`));
122
125
  console.log();
123
126
  askQuestion();
124
127
  return;
125
128
  }
126
129
 
127
130
  try {
128
- process.stdout.write(chalk.gray(' ...pensando\n'));
131
+ process.stdout.write(chalk.gray(' ...thinking\n'));
129
132
 
130
133
  const response = await agent.onMessage({
131
- agentId: options.agentId,
134
+ agentId: agentId,
132
135
  question,
133
136
  sessionId,
134
137
  multipleAnswers: options.multipleAnswers
135
138
  }) as AgentResponse & { actionsExecuted?: any[] };
136
139
 
137
- const timestamp = new Date().toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' });
140
+ const timestamp = new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
138
141
 
139
142
  // Mostrar tool calls si hay
140
143
  if (response.actionsExecuted && response.actionsExecuted.length > 0) {
@@ -154,9 +157,9 @@ export const chatCommand = new Command('chat')
154
157
 
155
158
  // Fuentes
156
159
  if (showSources && response.sources && response.sources.length > 0) {
157
- console.log(chalk.gray(' Fuentes:'));
160
+ console.log(chalk.gray(' Sources:'));
158
161
  response.sources.forEach((source: AgentSource) => {
159
- console.log(chalk.gray(` - ${source.title || 'Sin titulo'}`));
162
+ console.log(chalk.gray(` - ${source.title || 'Untitled'}`));
160
163
  if (source.url) console.log(chalk.gray(` ${source.url}`));
161
164
  });
162
165
  console.log();
@@ -164,7 +167,7 @@ export const chatCommand = new Command('chat')
164
167
 
165
168
  askQuestion();
166
169
  } catch (error) {
167
- const message = error instanceof Error ? error.message : 'Error desconocido';
170
+ const message = error instanceof Error ? error.message : 'Unknown error';
168
171
  console.log(chalk.hex('#EF5350')(`\n ✖ Error: ${message}\n`));
169
172
  askQuestion();
170
173
  }
@@ -174,12 +177,21 @@ export const chatCommand = new Command('chat')
174
177
  askQuestion();
175
178
 
176
179
  } catch (error) {
177
- const message = error instanceof Error ? error.message : 'Error desconocido';
180
+ const message = error instanceof Error ? error.message : 'Unknown error';
178
181
  logger.error(message);
179
182
  process.exit(1);
180
183
  }
181
184
  });
182
185
 
186
+ addExamples(chatCommand, [
187
+ { description: 'Open an interactive chat with the agent',
188
+ command: 'plazbot agent chat agt_AbcDef123' },
189
+ { description: 'Reuse a previous session ID to continue the conversation',
190
+ command: 'plazbot agent chat agt_AbcDef123 -s sess_AbcDef123' },
191
+ { description: 'Allow the agent to send multiple answers per turn',
192
+ command: 'plazbot agent chat agt_AbcDef123 -m' },
193
+ ]);
194
+
183
195
  function formatResponse(text: string): string {
184
196
  if (!text) return '';
185
197