@hostwebhook/node-types 1.86.0 → 1.87.0

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 (55) hide show
  1. package/dist/calendar-toolkit.d.ts +3 -0
  2. package/dist/calendar-toolkit.js +3 -2
  3. package/dist/clase-de-herramienta.d.ts +61 -0
  4. package/dist/clase-de-herramienta.js +153 -0
  5. package/dist/discord-toolkit.d.ts +2 -3
  6. package/dist/discord-toolkit.js +3 -6
  7. package/dist/docs-toolkit.d.ts +2 -1
  8. package/dist/docs-toolkit.js +3 -6
  9. package/dist/drive-toolkit.d.ts +9 -4
  10. package/dist/drive-toolkit.js +3 -4
  11. package/dist/esm/calendar-toolkit.d.ts +3 -0
  12. package/dist/esm/calendar-toolkit.js +3 -2
  13. package/dist/esm/clase-de-herramienta.d.ts +61 -0
  14. package/dist/esm/clase-de-herramienta.js +148 -0
  15. package/dist/esm/discord-toolkit.d.ts +2 -3
  16. package/dist/esm/discord-toolkit.js +3 -6
  17. package/dist/esm/docs-toolkit.d.ts +2 -1
  18. package/dist/esm/docs-toolkit.js +3 -6
  19. package/dist/esm/drive-toolkit.d.ts +9 -4
  20. package/dist/esm/drive-toolkit.js +3 -4
  21. package/dist/esm/gmail-operations.d.ts +2 -0
  22. package/dist/esm/gmail-operations.js +7 -6
  23. package/dist/esm/index.d.ts +8 -0
  24. package/dist/esm/index.js +5 -0
  25. package/dist/esm/mongo-toolkit.d.ts +47 -0
  26. package/dist/esm/mongo-toolkit.js +98 -0
  27. package/dist/esm/postgres-toolkit.d.ts +52 -0
  28. package/dist/esm/postgres-toolkit.js +85 -0
  29. package/dist/esm/registry.js +10 -0
  30. package/dist/esm/sheets-toolkit.d.ts +2 -1
  31. package/dist/esm/sheets-toolkit.js +3 -6
  32. package/dist/esm/slack-toolkit.d.ts +2 -3
  33. package/dist/esm/slack-toolkit.js +3 -4
  34. package/dist/esm/telegram-toolkit.d.ts +3 -0
  35. package/dist/esm/telegram-toolkit.js +3 -2
  36. package/dist/esm/toolkits.d.ts +47 -0
  37. package/dist/esm/toolkits.js +74 -0
  38. package/dist/gmail-operations.d.ts +2 -0
  39. package/dist/gmail-operations.js +11 -10
  40. package/dist/index.d.ts +8 -0
  41. package/dist/index.js +16 -1
  42. package/dist/mongo-toolkit.d.ts +47 -0
  43. package/dist/mongo-toolkit.js +101 -0
  44. package/dist/postgres-toolkit.d.ts +52 -0
  45. package/dist/postgres-toolkit.js +88 -0
  46. package/dist/registry.js +10 -0
  47. package/dist/sheets-toolkit.d.ts +2 -1
  48. package/dist/sheets-toolkit.js +3 -6
  49. package/dist/slack-toolkit.d.ts +2 -3
  50. package/dist/slack-toolkit.js +3 -4
  51. package/dist/telegram-toolkit.d.ts +3 -0
  52. package/dist/telegram-toolkit.js +3 -2
  53. package/dist/toolkits.d.ts +47 -0
  54. package/dist/toolkits.js +79 -0
  55. package/package.json +1 -1
@@ -38,9 +38,8 @@ export interface SlackToolkitSpec {
38
38
  /** Descripción (más reglas de uso) que ve el LLM. */
39
39
  description: string;
40
40
  parameters: SlackToolkitParameter[];
41
- /** Operaciones irreversibles o que cambian privilegios. La capa MCP las
42
- * bloquea cuando el nodo de IA lleva `requireConfirmationForDestructive`,
43
- * salvo que la llamada traiga confirmación explícita. */
41
+ /** Pisa o borra. Lo pone `marcarDestructivas` leyendo el verbo del
42
+ * nombre (ver `clase-de-herramienta.ts`), no se escribe a mano. */
44
43
  destructive?: boolean;
45
44
  }
46
45
  export declare const SLACK_TOOLKIT_SPECS: SlackToolkitSpec[];
@@ -23,8 +23,9 @@
23
23
  * y quien mire la lista de herramientas del servidor MCP.
24
24
  */
25
25
  import { camposDeSlackNoDisponibles, operacionesDeSlackPara, } from './slack-operations.js';
26
+ import { marcarDestructivas } from './clase-de-herramienta.js';
26
27
  const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
27
- export const SLACK_TOOLKIT_SPECS = [
28
+ export const SLACK_TOOLKIT_SPECS = marcarDestructivas([
28
29
  // ── Messages ─────────────────────────────────────────────────────
29
30
  {
30
31
  operation: 'sendMessage',
@@ -63,7 +64,6 @@ export const SLACK_TOOLKIT_SPECS = [
63
64
  p('channel', 'Channel where the message lives.'),
64
65
  p('ts', 'Timestamp of the message to delete.'),
65
66
  ],
66
- destructive: true,
67
67
  },
68
68
  {
69
69
  operation: 'sendEphemeral',
@@ -142,7 +142,6 @@ export const SLACK_TOOLKIT_SPECS = [
142
142
  p('name', 'Channel name — lowercase, no spaces, max 80 chars.'),
143
143
  p('isPrivate', 'Create a private channel instead of public. Default false.', false, 'boolean'),
144
144
  ],
145
- destructive: true,
146
145
  },
147
146
  {
148
147
  operation: 'inviteToChannel',
@@ -212,7 +211,7 @@ export const SLACK_TOOLKIT_SPECS = [
212
211
  p('threadTs', 'Thread to attach the file to.', false),
213
212
  ],
214
213
  },
215
- ];
214
+ ]);
216
215
  export const SLACK_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(SLACK_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
217
216
  /**
218
217
  * Las herramientas que ofrecerle al modelo con ESTA credencial.
@@ -39,6 +39,9 @@ export interface TelegramToolkitSpec {
39
39
  /** Descripción (más reglas de uso) que ve el LLM. */
40
40
  description: string;
41
41
  parameters: TelegramToolkitParameter[];
42
+ /** Pisa o borra. Lo pone `marcarDestructivas` leyendo el verbo del
43
+ * nombre (ver `clase-de-herramienta.ts`), no se escribe a mano. */
44
+ destructive?: boolean;
42
45
  /**
43
46
  * Encabezado de grupo para la lista de la página de detalle. Las filas
44
47
  * consecutivas que comparten grupo se pintan bajo un único título, así que el
@@ -19,6 +19,7 @@
19
19
  * usarse sin adaptador. Los textos van en inglés porque los lee el modelo y
20
20
  * quien mire la lista de herramientas del servidor MCP.
21
21
  */
22
+ import { marcarDestructivas } from './clase-de-herramienta.js';
22
23
  const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
23
24
  /*
24
25
  * `sendAndWaitForResponse` NO está aquí, y es una decisión, no un olvido: la op
@@ -33,7 +34,7 @@ const p = (name, description, required = true, type = 'string') => ({ name, type
33
34
  * campo en ninguna de las dos capas, y añadirlo cambiaría cuándo el AI Node pide
34
35
  * confirmación. Eso es otra decisión, no parte de mudar el esquema de sitio.
35
36
  */
36
- export const TELEGRAM_TOOLKIT_SPECS = [
37
+ export const TELEGRAM_TOOLKIT_SPECS = marcarDestructivas([
37
38
  {
38
39
  operation: 'sendMessage',
39
40
  label: 'Send message',
@@ -178,6 +179,6 @@ export const TELEGRAM_TOOLKIT_SPECS = [
178
179
  p('showAlert', 'Optional. true = modal alert; false (default) = toast notification.', false, 'boolean'),
179
180
  ],
180
181
  },
181
- ];
182
+ ]);
182
183
  /** Las herramientas por nombre, para despachar una llamada del modelo. */
183
184
  export const TELEGRAM_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(TELEGRAM_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Los toolkits por tipo de nodo: qué herramientas expone cada nodo en modo
3
+ * AI toolkit, en un solo sitio.
4
+ *
5
+ * ## Para qué (2026-09-24)
6
+ *
7
+ * Para que el gate «Block destructive tool calls» del AI Node pueda preguntar
8
+ * por la OPERACIÓN y no sólo por el nombre. Hasta hoy sólo miraba el nombre
9
+ * contra unos patrones (`delete_*`, `drop_*`…), así que `update_row` de Sheets
10
+ * —que pisa una fila— pasaba con el gate encendido. Con esto, la herramienta
11
+ * que el AI Node guardó al conectar (`nodeRefType` + `operationOverride`) se
12
+ * resuelve aquí a su operación, y su `destructive` —que sale del verbo, ver
13
+ * `clase-de-herramienta.ts`— decide.
14
+ *
15
+ * ## Lo que falta aquí, a propósito
16
+ *
17
+ * WhatsApp y Contacts siguen con sus specs escritos a mano en la api y en el
18
+ * dashboard, no en este paquete. Hasta que se muden, quien consulte este
19
+ * registro tiene que componerlos por su lado — {@link esOperacionDestructiva}
20
+ * devuelve `null` para ellos, que significa «no lo sé», no «no es
21
+ * destructiva».
22
+ */
23
+ /** Lo mínimo de una herramienta de toolkit que hace falta para decidir. */
24
+ export interface OperacionDeToolkit {
25
+ operation: string;
26
+ toolName: string;
27
+ label: string;
28
+ destructive?: boolean;
29
+ }
30
+ export declare const TOOLKITS_POR_TIPO: Readonly<Record<string, readonly OperacionDeToolkit[]>>;
31
+ /**
32
+ * La operación de un toolkit, buscada por su nombre interno (`updateRow`) O
33
+ * por el nombre de su herramienta (`update_row`).
34
+ *
35
+ * Las dos formas porque las dos llegan: el AI Node guarda `operationOverride`
36
+ * con el nombre interno, y el servidor MCP recibe el nombre de la herramienta.
37
+ */
38
+ export declare function operacionDeToolkit(nodeType: string | undefined | null, operacionONombre: string | undefined | null): OperacionDeToolkit | null;
39
+ /**
40
+ * ¿Es destructiva esta operación de toolkit?
41
+ *
42
+ * `null` cuando no se sabe —el tipo no es un toolkit de este paquete, o la
43
+ * operación no existe en él—. Quien llama decide qué hace con el «no sé»; el
44
+ * gate del AI Node lo combina con los patrones de nombre, que siguen ahí para
45
+ * las herramientas que no son de toolkit (MCP, HTTP…).
46
+ */
47
+ export declare function esOperacionDestructiva(nodeType: string | undefined | null, operacionONombre: string | undefined | null): boolean | null;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Los toolkits por tipo de nodo: qué herramientas expone cada nodo en modo
3
+ * AI toolkit, en un solo sitio.
4
+ *
5
+ * ## Para qué (2026-09-24)
6
+ *
7
+ * Para que el gate «Block destructive tool calls» del AI Node pueda preguntar
8
+ * por la OPERACIÓN y no sólo por el nombre. Hasta hoy sólo miraba el nombre
9
+ * contra unos patrones (`delete_*`, `drop_*`…), así que `update_row` de Sheets
10
+ * —que pisa una fila— pasaba con el gate encendido. Con esto, la herramienta
11
+ * que el AI Node guardó al conectar (`nodeRefType` + `operationOverride`) se
12
+ * resuelve aquí a su operación, y su `destructive` —que sale del verbo, ver
13
+ * `clase-de-herramienta.ts`— decide.
14
+ *
15
+ * ## Lo que falta aquí, a propósito
16
+ *
17
+ * WhatsApp y Contacts siguen con sus specs escritos a mano en la api y en el
18
+ * dashboard, no en este paquete. Hasta que se muden, quien consulte este
19
+ * registro tiene que componerlos por su lado — {@link esOperacionDestructiva}
20
+ * devuelve `null` para ellos, que significa «no lo sé», no «no es
21
+ * destructiva».
22
+ */
23
+ import { GMAIL_ALL_TOOLKIT_SPECS, NATIVE_EMAIL_TOOLKIT_SPECS } from './gmail-operations.js';
24
+ import { GOOGLE_CALENDAR_TOOLKIT_SPECS } from './calendar-toolkit.js';
25
+ import { DRIVE_TOOLKIT_SPECS } from './drive-toolkit.js';
26
+ import { TELEGRAM_TOOLKIT_SPECS } from './telegram-toolkit.js';
27
+ import { DISCORD_TOOLKIT_SPECS } from './discord-toolkit.js';
28
+ import { SLACK_TOOLKIT_SPECS } from './slack-toolkit.js';
29
+ import { SHEETS_TOOLKIT_SPECS } from './sheets-toolkit.js';
30
+ import { DOCS_TOOLKIT_SPECS } from './docs-toolkit.js';
31
+ import { MONGO_TOOLKIT_SPECS } from './mongo-toolkit.js';
32
+ import { POSTGRES_TOOLKIT_SPECS } from './postgres-toolkit.js';
33
+ export const TOOLKITS_POR_TIPO = Object.freeze({
34
+ gmailAction: GMAIL_ALL_TOOLKIT_SPECS,
35
+ emailAction: NATIVE_EMAIL_TOOLKIT_SPECS,
36
+ calendarAction: GOOGLE_CALENDAR_TOOLKIT_SPECS,
37
+ driveAction: DRIVE_TOOLKIT_SPECS,
38
+ telegramAction: TELEGRAM_TOOLKIT_SPECS,
39
+ discordAction: DISCORD_TOOLKIT_SPECS,
40
+ slackAction: SLACK_TOOLKIT_SPECS,
41
+ sheetsAction: SHEETS_TOOLKIT_SPECS,
42
+ docsAction: DOCS_TOOLKIT_SPECS,
43
+ mongoAction: MONGO_TOOLKIT_SPECS,
44
+ postgresAction: POSTGRES_TOOLKIT_SPECS,
45
+ });
46
+ /**
47
+ * La operación de un toolkit, buscada por su nombre interno (`updateRow`) O
48
+ * por el nombre de su herramienta (`update_row`).
49
+ *
50
+ * Las dos formas porque las dos llegan: el AI Node guarda `operationOverride`
51
+ * con el nombre interno, y el servidor MCP recibe el nombre de la herramienta.
52
+ */
53
+ export function operacionDeToolkit(nodeType, operacionONombre) {
54
+ if (!nodeType || !operacionONombre)
55
+ return null;
56
+ const toolkit = TOOLKITS_POR_TIPO[nodeType];
57
+ if (!toolkit)
58
+ return null;
59
+ return (toolkit.find((s) => s.operation === operacionONombre) ??
60
+ toolkit.find((s) => s.toolName === operacionONombre) ??
61
+ null);
62
+ }
63
+ /**
64
+ * ¿Es destructiva esta operación de toolkit?
65
+ *
66
+ * `null` cuando no se sabe —el tipo no es un toolkit de este paquete, o la
67
+ * operación no existe en él—. Quien llama decide qué hace con el «no sé»; el
68
+ * gate del AI Node lo combina con los patrones de nombre, que siguen ahí para
69
+ * las herramientas que no son de toolkit (MCP, HTTP…).
70
+ */
71
+ export function esOperacionDestructiva(nodeType, operacionONombre) {
72
+ const op = operacionDeToolkit(nodeType, operacionONombre);
73
+ return op ? op.destructive === true : null;
74
+ }
@@ -151,6 +151,8 @@ export interface GmailToolkitSpec {
151
151
  toolName: string;
152
152
  description: string;
153
153
  parameters: GmailToolkitParameter[];
154
+ /** Pisa o borra. Lo pone `marcarDestructivas` leyendo el verbo del
155
+ * nombre (ver `clase-de-herramienta.ts`), no se escribe a mano. */
154
156
  destructive?: boolean;
155
157
  }
156
158
  export declare const GMAIL_TOOLKIT_SPECS: GmailToolkitSpec[];
@@ -1,8 +1,4 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GMAIL_SEND_LEGACY_FIELDS = exports.NATIVE_EMAIL_TOOLKIT_BY_TOOL_NAME = exports.GMAIL_TOOLKIT_BY_TOOL_NAME = exports.NATIVE_EMAIL_TOOLKIT_SPECS = exports.GMAIL_ALL_TOOLKIT_SPECS = exports.GMAIL_SEND_AND_WAIT_TOOL_SPEC = exports.GMAIL_TOOLKIT_SPECS = exports.GMAIL_TOOLKIT_OPERATIONS = exports.GMAIL_DROPDOWN_OPERATIONS = exports.GMAIL_OPERATION_SPECS = exports.GMAIL_OPERATION_GROUPS = exports.GMAIL_OPERATIONS = void 0;
4
- exports.isGmailOperation = isGmailOperation;
5
- exports.resolveGmailSendFields = resolveGmailSendFields;
6
2
  /**
7
3
  * Gmail operation enum — single source of truth across the API, Dashboard,
8
4
  * and Message Broker. Used by:
@@ -17,6 +13,11 @@ exports.resolveGmailSendFields = resolveGmailSendFields;
17
13
  * dashboard owns the UI form schema, the api owns the dispatch logic),
18
14
  * but the canonical list of valid operation strings lives here.
19
15
  */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.GMAIL_SEND_LEGACY_FIELDS = exports.NATIVE_EMAIL_TOOLKIT_BY_TOOL_NAME = exports.GMAIL_TOOLKIT_BY_TOOL_NAME = exports.NATIVE_EMAIL_TOOLKIT_SPECS = exports.GMAIL_ALL_TOOLKIT_SPECS = exports.GMAIL_SEND_AND_WAIT_TOOL_SPEC = exports.GMAIL_TOOLKIT_SPECS = exports.GMAIL_TOOLKIT_OPERATIONS = exports.GMAIL_DROPDOWN_OPERATIONS = exports.GMAIL_OPERATION_SPECS = exports.GMAIL_OPERATION_GROUPS = exports.GMAIL_OPERATIONS = void 0;
18
+ exports.isGmailOperation = isGmailOperation;
19
+ exports.resolveGmailSendFields = resolveGmailSendFields;
20
+ const clase_de_herramienta_js_1 = require("./clase-de-herramienta.js");
20
21
  exports.GMAIL_OPERATIONS = [
21
22
  'send',
22
23
  // Pause-the-pipeline op — sends an email with Approve / (optional)
@@ -301,7 +302,7 @@ const p = (name, description, required = true, type = 'string') => ({ name, type
301
302
  const ADJUNTOS = p('attachments', 'Optional. Files to attach, taken from the payload: pass the `_file` reference object(s) ' +
302
303
  'exactly as they appear (a single `_file`, or the `_files` / `files` array), as a JSON ' +
303
304
  'string. Never invent one. Up to 5 files, 25 MB in total.', false);
304
- exports.GMAIL_TOOLKIT_SPECS = [
305
+ exports.GMAIL_TOOLKIT_SPECS = (0, clase_de_herramienta_js_1.marcarDestructivas)([
305
306
  {
306
307
  operation: 'send',
307
308
  label: 'Send message',
@@ -510,7 +511,7 @@ exports.GMAIL_TOOLKIT_SPECS = [
510
511
  p('threadId', 'Gmail thread id.'),
511
512
  ],
512
513
  },
513
- ];
514
+ ]);
514
515
  /**
515
516
  * La op que espera, **fuera** del toolkit y aparte a propósito. Sigue haciendo
516
517
  * falta para dos cosas que no son el toolkit: reconocer la operación de una
@@ -540,12 +541,12 @@ exports.GMAIL_SEND_AND_WAIT_TOOL_SPEC = {
540
541
  ],
541
542
  };
542
543
  /** Todo lo que el nodo sabe ejecutar, se ofrezca o no como herramienta. */
543
- exports.GMAIL_ALL_TOOLKIT_SPECS = [
544
+ exports.GMAIL_ALL_TOOLKIT_SPECS = (0, clase_de_herramienta_js_1.marcarDestructivas)([
544
545
  ...exports.GMAIL_TOOLKIT_SPECS,
545
546
  exports.GMAIL_SEND_AND_WAIT_TOOL_SPEC,
546
- ];
547
+ ]);
547
548
  /** El toolkit del proveedor nativo (Resend): una sola herramienta. */
548
- exports.NATIVE_EMAIL_TOOLKIT_SPECS = [
549
+ exports.NATIVE_EMAIL_TOOLKIT_SPECS = (0, clase_de_herramienta_js_1.marcarDestructivas)([
549
550
  {
550
551
  operation: 'send',
551
552
  label: 'Send email',
@@ -564,7 +565,7 @@ exports.NATIVE_EMAIL_TOOLKIT_SPECS = [
564
565
  p('attachment_file_ids', 'Optional. Comma-separated list of file IDs from `_file.id` refs in the upstream payload (e.g., a File Transform output or a webhook multipart upload). Max 5 files, 30MB total. Do NOT invent IDs — only use values actually present in the current payload.', false),
565
566
  ],
566
567
  },
567
- ];
568
+ ]);
568
569
  exports.GMAIL_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.GMAIL_ALL_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
569
570
  exports.NATIVE_EMAIL_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.NATIVE_EMAIL_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
570
571
  /** Los tres campos que un día vivieron en la raíz. */
package/dist/index.d.ts CHANGED
@@ -70,6 +70,14 @@ export { DOCS_OPERATIONS, DOCS_OPERATION_SPECS, isDocsOperation, } from './docs-
70
70
  export type { DocsOperation, DocsParamType, DocsParamSlot, DocsParamSpec, DocsOperationSpec, } from './docs-operations.js';
71
71
  export { DOCS_TOOLKIT_SPECS, DOCS_TOOLKIT_BY_TOOL_NAME, DOCS_TOOLKIT_DEFAULTABLE, } from './docs-toolkit.js';
72
72
  export type { DocsToolkitSpec, DocsToolkitParameter, } from './docs-toolkit.js';
73
+ export { MONGO_TOOLKIT_SPECS, MONGO_TOOLKIT_BY_TOOL_NAME, } from './mongo-toolkit.js';
74
+ export type { MongoToolkitSpec, MongoToolkitParameter, } from './mongo-toolkit.js';
75
+ export { POSTGRES_TOOLKIT_SPECS, POSTGRES_TOOLKIT_BY_TOOL_NAME, } from './postgres-toolkit.js';
76
+ export type { PostgresToolkitSpec, PostgresToolkitParameter, } from './postgres-toolkit.js';
77
+ export { claseDeHerramienta, esHerramientaDestructiva, marcarDestructivas, } from './clase-de-herramienta.js';
78
+ export type { ClaseDeHerramienta } from './clase-de-herramienta.js';
79
+ export { TOOLKITS_POR_TIPO, operacionDeToolkit, esOperacionDestructiva, } from './toolkits.js';
80
+ export type { OperacionDeToolkit } from './toolkits.js';
73
81
  export type { LlmProvider, LlmProviderOption, LlmModelOption, } from './llm-models.js';
74
82
  export { LLM_PROVIDERS, LLM_MODELS, MODEL_CONTEXT_WINDOWS, getModelsFor, getDefaultModel, getModelLabel, } from './llm-models.js';
75
83
  export type { ModeloDeOpenRouter, PrecioDeOpenRouter, RespuestaDeModelosDeOpenRouter, } from './openrouter.js';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GMAIL_SEND_LEGACY_FIELDS = exports.NATIVE_EMAIL_TOOLKIT_BY_TOOL_NAME = exports.GMAIL_TOOLKIT_BY_TOOL_NAME = exports.NATIVE_EMAIL_TOOLKIT_SPECS = exports.GMAIL_SEND_AND_WAIT_TOOL_SPEC = exports.GMAIL_ALL_TOOLKIT_SPECS = exports.GMAIL_TOOLKIT_SPECS = exports.GMAIL_TOOLKIT_OPERATIONS = exports.GMAIL_DROPDOWN_OPERATIONS = exports.GMAIL_OPERATION_GROUPS = exports.GMAIL_OPERATION_SPECS = exports.GMAIL_OPERATIONS = exports.versionCatalogErrors = exports.fieldsLost = exports.fieldsLostBetween = exports.currentVersion = exports.versionSpec = exports.versionsOf = exports.isVersioned = exports.NODE_TYPE_TO_PREFIX = exports.PREFIX_TO_NODE_TYPE = exports.NODE_STATE_KEYS = exports.NODE_COLORS = exports.NODE_DETAIL_PATHS = exports.getNodeRegistryEntry = exports.NODE_REGISTRY = exports.pasaLoQueRecibe = exports.getNodeDispatchConfig = exports.getAllNodeCollections = exports.NODE_DISPATCH = exports.todosLosOutputGroups = exports.outputGroupsFor = exports.esEtiquetaDeSentimiento = exports.SENTIMENT_PORT_SUMMARY = exports.SENTIMENT_PORT_LABEL = exports.SENTIMENT_PORTS = exports.SENTIMENT_UNCLEAR = exports.SENTIMENT_LABELS = exports.resolveNodeId = exports.PREFIX_TO_TYPE = exports.NODE_UI = exports.ALL_NODE_TYPES = exports.isNodeType = exports.isTerminal = exports.canSendToNodes = exports.canReceiveFromNodes = exports.canReceiveFrom = exports.NODE_CONNECTIONS = exports.iterableMeta = exports.singleMeta = void 0;
4
4
  exports.isGithubOperation = exports.GITHUB_ITERABLE_OPERATIONS = exports.GITHUB_DROPDOWN_OPERATIONS = exports.GITHUB_OPERATION_SPECS = exports.GITHUB_OPERATIONS = exports.scopesQueFaltanEnShopify = exports.isShopifyOperation = exports.SHOPIFY_PRODUCT_STATUSES = exports.SHOPIFY_CANCEL_REASONS = exports.SHOPIFY_SEARCHABLE_RESOURCES = exports.SHOPIFY_TAGGABLE_RESOURCES = exports.SHOPIFY_OPERATION_SCOPES = exports.SHOPIFY_OPERATION_SPECS = exports.SHOPIFY_OPERATIONS = exports.isMailchimpOperation = exports.MAILCHIMP_CONTACT_STATUSES = exports.MAILCHIMP_OPERATION_SPECS = exports.MAILCHIMP_OPERATIONS = exports.herramientasDeDiscordPara = exports.DISCORD_TOOLKIT_BY_TOOL_NAME = exports.DISCORD_TOOLKIT_SPECS = exports.isDiscordOperation = exports.camposDeDiscordNoDisponibles = exports.discordPuedeEjecutar = exports.operacionesDeDiscordPara = exports.DISCORD_CAPACIDADES_POR_CREDENCIAL = exports.DISCORD_OPERATION_SPECS = exports.DISCORD_OPERATIONS = exports.camposNoDisponiblesPara = exports.puedeEjecutar = exports.operacionesPara = exports.isWhatsAppOperation = exports.WHATSAPP_OPERATIONS = exports.TELEGRAM_TOOLKIT_BY_TOOL_NAME = exports.TELEGRAM_TOOLKIT_SPECS = exports.isTelegramOperation = exports.TELEGRAM_OPERATION_SPECS = exports.TELEGRAM_OPERATIONS = exports.DRIVE_TOOLKIT_BY_TOOL_NAME = exports.DRIVE_TOOLKIT_SPECS = exports.isDriveOperation = exports.DRIVE_OPERATION_SPECS = exports.DRIVE_OPERATIONS = exports.GOOGLE_CALENDAR_TOOLKIT_BY_TOOL_NAME = exports.GOOGLE_CALENDAR_TOOLKIT_SPECS = exports.isGoogleCalendarOperation = exports.GOOGLE_CALENDAR_OPERATION_SPECS = exports.GOOGLE_CALENDAR_OPERATIONS = exports.isGmailOperation = exports.resolveGmailSendFields = void 0;
5
5
  exports.NOTION_OPERATION_SPECS = exports.NOTION_OPERATIONS = exports.isGoogleAnalyticsOperation = exports.GOOGLE_ANALYTICS_DROPDOWN_OPERATIONS = exports.GOOGLE_ANALYTICS_OPERATION_SPECS = exports.GOOGLE_ANALYTICS_OPERATIONS = exports.isGoogleContactsOperation = exports.GOOGLE_CONTACTS_DEFAULT_PERSON_FIELDS = exports.GOOGLE_CONTACTS_OPERATION_GROUPS = exports.GOOGLE_CONTACTS_OPERATION_SPECS = exports.GOOGLE_CONTACTS_OPERATIONS_V2 = exports.GOOGLE_CONTACTS_OPERATIONS_V1 = exports.GOOGLE_CONTACTS_OPERATIONS = exports.SHEETS_TOOLKIT_DEFAULTABLE = exports.SHEETS_TOOLKIT_BY_TOOL_NAME = exports.SHEETS_TOOLKIT_SPECS = exports.isSheetsOperation = exports.SHEETS_OPERATION_SPECS = exports.SHEETS_OPERATIONS = exports.herramientasDeSlackPara = exports.SLACK_TOOLKIT_BY_TOOL_NAME = exports.SLACK_TOOLKIT_SPECS = exports.isSlackOperation = exports.camposDeSlackNoDisponibles = exports.slackPuedeEjecutar = exports.operacionesDeSlackPara = exports.SLACK_CAPACIDADES_POR_CREDENCIAL = exports.SLACK_OPERATION_SPECS = exports.SLACK_OPERATIONS = exports.isAirtableOperation = exports.AIRTABLE_ITERABLE_OPERATIONS = exports.AIRTABLE_OPERATION_SPECS = exports.AIRTABLE_OPERATIONS = exports.isCalendlyOperation = exports.CALENDLY_ITERABLE_OPERATIONS = exports.CALENDLY_OPERATION_SPECS = exports.CALENDLY_OPERATIONS = exports.isApifyOperation = exports.APIFY_ITERABLE_OPERATIONS = exports.APIFY_OPERATION_SPECS = exports.APIFY_OPERATIONS = exports.isBucketOperation = exports.BUCKET_ITERABLE_OPERATIONS = exports.BUCKET_OPERATION_SPECS = exports.BUCKET_OPERATIONS = exports.isJiraOperation = exports.JIRA_ITERABLE_OPERATIONS = exports.JIRA_DROPDOWN_OPERATIONS = exports.JIRA_OPERATION_SPECS = exports.JIRA_OPERATIONS = void 0;
6
- exports.armarRespuestaDelSync = exports.RESPUESTA_DEL_SYNC_POR_DEFECTO = exports.TOPE_DE_ESPERA_DEL_SYNC = exports.TOPES_DE_ESTADO = exports.SOBRES_DE_RESPUESTA = exports.MODOS_DE_PAYLOAD = exports.NIVELES_DE_DETALLE = exports.RESULTADOS_DEL_VALIDADOR = exports.contestaEnSync = exports.NODOS_QUE_CONTESTAN_EN_SYNC = exports.isCredentialType = exports.getCredentialType = exports.credentialTypeValues = exports.CREDENTIAL_TYPE_VALUES = exports.CREDENTIAL_TYPES = exports.ventanaDeContextoDeOpenRouter = exports.opcionesDeModelosDeOpenRouter = exports.URL_DE_MODELOS_DE_OPENROUTER = exports.getModelLabel = exports.getDefaultModel = exports.getModelsFor = exports.MODEL_CONTEXT_WINDOWS = exports.LLM_MODELS = exports.LLM_PROVIDERS = exports.DOCS_TOOLKIT_DEFAULTABLE = exports.DOCS_TOOLKIT_BY_TOOL_NAME = exports.DOCS_TOOLKIT_SPECS = exports.isDocsOperation = exports.DOCS_OPERATION_SPECS = exports.DOCS_OPERATIONS = exports.isMongoOperation = exports.MONGO_OPERATION_SPECS = exports.MONGO_OPERATIONS = exports.isPostgresOperation = exports.POSTGRES_OPERATION_SPECS = exports.POSTGRES_MODES = exports.POSTGRES_OPERATIONS = exports.isNotionOperation = exports.NOTION_DROPDOWN_OPERATIONS = void 0;
6
+ exports.armarRespuestaDelSync = exports.RESPUESTA_DEL_SYNC_POR_DEFECTO = exports.TOPE_DE_ESPERA_DEL_SYNC = exports.TOPES_DE_ESTADO = exports.SOBRES_DE_RESPUESTA = exports.MODOS_DE_PAYLOAD = exports.NIVELES_DE_DETALLE = exports.RESULTADOS_DEL_VALIDADOR = exports.contestaEnSync = exports.NODOS_QUE_CONTESTAN_EN_SYNC = exports.isCredentialType = exports.getCredentialType = exports.credentialTypeValues = exports.CREDENTIAL_TYPE_VALUES = exports.CREDENTIAL_TYPES = exports.ventanaDeContextoDeOpenRouter = exports.opcionesDeModelosDeOpenRouter = exports.URL_DE_MODELOS_DE_OPENROUTER = exports.getModelLabel = exports.getDefaultModel = exports.getModelsFor = exports.MODEL_CONTEXT_WINDOWS = exports.LLM_MODELS = exports.LLM_PROVIDERS = exports.esOperacionDestructiva = exports.operacionDeToolkit = exports.TOOLKITS_POR_TIPO = exports.marcarDestructivas = exports.esHerramientaDestructiva = exports.claseDeHerramienta = exports.POSTGRES_TOOLKIT_BY_TOOL_NAME = exports.POSTGRES_TOOLKIT_SPECS = exports.MONGO_TOOLKIT_BY_TOOL_NAME = exports.MONGO_TOOLKIT_SPECS = exports.DOCS_TOOLKIT_DEFAULTABLE = exports.DOCS_TOOLKIT_BY_TOOL_NAME = exports.DOCS_TOOLKIT_SPECS = exports.isDocsOperation = exports.DOCS_OPERATION_SPECS = exports.DOCS_OPERATIONS = exports.isMongoOperation = exports.MONGO_OPERATION_SPECS = exports.MONGO_OPERATIONS = exports.isPostgresOperation = exports.POSTGRES_OPERATION_SPECS = exports.POSTGRES_MODES = exports.POSTGRES_OPERATIONS = exports.isNotionOperation = exports.NOTION_DROPDOWN_OPERATIONS = void 0;
7
7
  var types_js_1 = require("./types.js");
8
8
  Object.defineProperty(exports, "singleMeta", { enumerable: true, get: function () { return types_js_1.singleMeta; } });
9
9
  Object.defineProperty(exports, "iterableMeta", { enumerable: true, get: function () { return types_js_1.iterableMeta; } });
@@ -224,6 +224,21 @@ var docs_toolkit_js_1 = require("./docs-toolkit.js");
224
224
  Object.defineProperty(exports, "DOCS_TOOLKIT_SPECS", { enumerable: true, get: function () { return docs_toolkit_js_1.DOCS_TOOLKIT_SPECS; } });
225
225
  Object.defineProperty(exports, "DOCS_TOOLKIT_BY_TOOL_NAME", { enumerable: true, get: function () { return docs_toolkit_js_1.DOCS_TOOLKIT_BY_TOOL_NAME; } });
226
226
  Object.defineProperty(exports, "DOCS_TOOLKIT_DEFAULTABLE", { enumerable: true, get: function () { return docs_toolkit_js_1.DOCS_TOOLKIT_DEFAULTABLE; } });
227
+ // ── Toolkits de bases de datos, y la clase de cada herramienta (2026-09-24) ──
228
+ var mongo_toolkit_js_1 = require("./mongo-toolkit.js");
229
+ Object.defineProperty(exports, "MONGO_TOOLKIT_SPECS", { enumerable: true, get: function () { return mongo_toolkit_js_1.MONGO_TOOLKIT_SPECS; } });
230
+ Object.defineProperty(exports, "MONGO_TOOLKIT_BY_TOOL_NAME", { enumerable: true, get: function () { return mongo_toolkit_js_1.MONGO_TOOLKIT_BY_TOOL_NAME; } });
231
+ var postgres_toolkit_js_1 = require("./postgres-toolkit.js");
232
+ Object.defineProperty(exports, "POSTGRES_TOOLKIT_SPECS", { enumerable: true, get: function () { return postgres_toolkit_js_1.POSTGRES_TOOLKIT_SPECS; } });
233
+ Object.defineProperty(exports, "POSTGRES_TOOLKIT_BY_TOOL_NAME", { enumerable: true, get: function () { return postgres_toolkit_js_1.POSTGRES_TOOLKIT_BY_TOOL_NAME; } });
234
+ var clase_de_herramienta_js_1 = require("./clase-de-herramienta.js");
235
+ Object.defineProperty(exports, "claseDeHerramienta", { enumerable: true, get: function () { return clase_de_herramienta_js_1.claseDeHerramienta; } });
236
+ Object.defineProperty(exports, "esHerramientaDestructiva", { enumerable: true, get: function () { return clase_de_herramienta_js_1.esHerramientaDestructiva; } });
237
+ Object.defineProperty(exports, "marcarDestructivas", { enumerable: true, get: function () { return clase_de_herramienta_js_1.marcarDestructivas; } });
238
+ var toolkits_js_1 = require("./toolkits.js");
239
+ Object.defineProperty(exports, "TOOLKITS_POR_TIPO", { enumerable: true, get: function () { return toolkits_js_1.TOOLKITS_POR_TIPO; } });
240
+ Object.defineProperty(exports, "operacionDeToolkit", { enumerable: true, get: function () { return toolkits_js_1.operacionDeToolkit; } });
241
+ Object.defineProperty(exports, "esOperacionDestructiva", { enumerable: true, get: function () { return toolkits_js_1.esOperacionDestructiva; } });
227
242
  var llm_models_js_1 = require("./llm-models.js");
228
243
  Object.defineProperty(exports, "LLM_PROVIDERS", { enumerable: true, get: function () { return llm_models_js_1.LLM_PROVIDERS; } });
229
244
  Object.defineProperty(exports, "LLM_MODELS", { enumerable: true, get: function () { return llm_models_js_1.LLM_MODELS; } });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * MongoDB AI Toolkit — las herramientas que un mongoAction expone cuando
3
+ * `aiEnabled` está encendido.
4
+ *
5
+ * ## Lo que el modelo NO elige (2026-09-24, decisiones de Ariel)
6
+ *
7
+ * - **La colección.** Es la del nodo y no hay parámetro para cambiarla: para
8
+ * tocar otra se conecta otro nodo. Una herramienta de base de datos que deja
9
+ * al modelo nombrar la colección le da acceso a todo lo que la credencial
10
+ * alcanza, y eso no se ve al mirar el lienzo.
11
+ * - **El JavaScript del servidor.** `$where`, `$function` y `$accumulator`
12
+ * ejecutan código dentro de Mongo; el handler los rechaza en cualquier
13
+ * filtro o pipeline que venga del modelo.
14
+ * - **Escribir desde una agregación.** `$out` y `$merge` son las dos etapas que
15
+ * escriben; `aggregate_documents` las rechaza, y por eso cuenta como lectura.
16
+ *
17
+ * ## Los nombres
18
+ *
19
+ * Cada nombre empieza por el verbo que dice lo que hace, porque el `destructive`
20
+ * de cada operación lo pone `marcarDestructivas` leyendo ese verbo (ver
21
+ * `clase-de-herramienta.ts`). Por eso `findOneAndUpdate` se ofrece como
22
+ * `update_and_return_document` y no como `find_and_update_document`: con el
23
+ * segundo nombre el verbo diría «lectura» de algo que pisa un documento.
24
+ *
25
+ * Los textos van en inglés porque los lee el modelo.
26
+ */
27
+ import type { MongoOperation } from './mongo-operations';
28
+ export interface MongoToolkitParameter {
29
+ name: string;
30
+ /** El esquema MCP sólo admite estos tres; lo estructurado viaja como JSON
31
+ * en un `string`, igual que las filas de Sheets. */
32
+ type: 'string' | 'number' | 'boolean';
33
+ description: string;
34
+ required: boolean;
35
+ }
36
+ export interface MongoToolkitSpec {
37
+ operation: MongoOperation;
38
+ label: string;
39
+ toolName: string;
40
+ description: string;
41
+ parameters: MongoToolkitParameter[];
42
+ /** Pisa o borra. Lo pone `marcarDestructivas`, no se escribe a mano. */
43
+ destructive?: boolean;
44
+ }
45
+ export declare const MONGO_TOOLKIT_SPECS: MongoToolkitSpec[];
46
+ /** Las herramientas por nombre, para despachar una llamada del modelo. */
47
+ export declare const MONGO_TOOLKIT_BY_TOOL_NAME: Record<string, MongoToolkitSpec>;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * MongoDB AI Toolkit — las herramientas que un mongoAction expone cuando
4
+ * `aiEnabled` está encendido.
5
+ *
6
+ * ## Lo que el modelo NO elige (2026-09-24, decisiones de Ariel)
7
+ *
8
+ * - **La colección.** Es la del nodo y no hay parámetro para cambiarla: para
9
+ * tocar otra se conecta otro nodo. Una herramienta de base de datos que deja
10
+ * al modelo nombrar la colección le da acceso a todo lo que la credencial
11
+ * alcanza, y eso no se ve al mirar el lienzo.
12
+ * - **El JavaScript del servidor.** `$where`, `$function` y `$accumulator`
13
+ * ejecutan código dentro de Mongo; el handler los rechaza en cualquier
14
+ * filtro o pipeline que venga del modelo.
15
+ * - **Escribir desde una agregación.** `$out` y `$merge` son las dos etapas que
16
+ * escriben; `aggregate_documents` las rechaza, y por eso cuenta como lectura.
17
+ *
18
+ * ## Los nombres
19
+ *
20
+ * Cada nombre empieza por el verbo que dice lo que hace, porque el `destructive`
21
+ * de cada operación lo pone `marcarDestructivas` leyendo ese verbo (ver
22
+ * `clase-de-herramienta.ts`). Por eso `findOneAndUpdate` se ofrece como
23
+ * `update_and_return_document` y no como `find_and_update_document`: con el
24
+ * segundo nombre el verbo diría «lectura» de algo que pisa un documento.
25
+ *
26
+ * Los textos van en inglés porque los lee el modelo.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.MONGO_TOOLKIT_BY_TOOL_NAME = exports.MONGO_TOOLKIT_SPECS = void 0;
30
+ const clase_de_herramienta_js_1 = require("./clase-de-herramienta.js");
31
+ const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
32
+ const filtro = (para, required = true) => p('filter', `JSON object with a MongoDB query filter that selects ${para}, e.g. {"email": "a@b.c"} or {"total": {"$gt": 100}}. Server-side JavaScript operators ($where, $function, $accumulator) are rejected.`, required);
33
+ const proyeccion = () => p('projection', 'Optional JSON object choosing the fields to return, e.g. {"name": 1, "email": 1}. Leave it out to return whole documents.', false);
34
+ exports.MONGO_TOOLKIT_SPECS = (0, clase_de_herramienta_js_1.marcarDestructivas)([
35
+ {
36
+ operation: 'findAll',
37
+ label: 'Find documents',
38
+ toolName: 'find_documents',
39
+ description: "Return the documents of this node's collection that match a filter. Returns at most `limit` documents — use a filter that narrows the result instead of reading the whole collection.",
40
+ parameters: [
41
+ filtro('the documents to return. {} matches every document', false),
42
+ proyeccion(),
43
+ p('sort', 'Optional JSON object with the sort order, e.g. {"createdAt": -1} for newest first.', false),
44
+ p('limit', 'Maximum number of documents to return (default 20, maximum 100).', false, 'number'),
45
+ ],
46
+ },
47
+ {
48
+ operation: 'findOne',
49
+ label: 'Find one document',
50
+ toolName: 'find_one_document',
51
+ description: "Return the first document of this node's collection that matches a filter, or nothing when none does.",
52
+ parameters: [filtro('the document'), proyeccion()],
53
+ },
54
+ {
55
+ operation: 'aggregate',
56
+ label: 'Aggregate documents',
57
+ toolName: 'aggregate_documents',
58
+ description: "Run an aggregation pipeline over this node's collection and return its result — for counts, sums, groupings and joins with $lookup. It only reads: the $out and $merge stages, which write, are rejected.",
59
+ parameters: [
60
+ p('pipeline', 'JSON array of aggregation stages, e.g. [{"$match": {"status": "paid"}}, {"$group": {"_id": "$customer", "total": {"$sum": "$amount"}}}].'),
61
+ ],
62
+ },
63
+ {
64
+ operation: 'insertOne',
65
+ label: 'Insert document',
66
+ toolName: 'insert_document',
67
+ description: "Insert one new document into this node's collection and return its _id. It does not check for duplicates — when the document might already exist, find it first.",
68
+ parameters: [
69
+ p('document', 'JSON object with the new document, e.g. {"name": "Ariel", "email": "a@b.c"}.'),
70
+ ],
71
+ },
72
+ {
73
+ operation: 'updateOne',
74
+ label: 'Update document',
75
+ toolName: 'update_document',
76
+ description: "Update the first document of this node's collection that matches a filter. It overwrites the fields you set. When nothing matches it changes nothing — it does not create a document.",
77
+ parameters: [
78
+ filtro('the document to update. It cannot be empty'),
79
+ p('update', 'JSON object with MongoDB update operators, e.g. {"$set": {"status": "shipped"}} or {"$inc": {"stock": -1}}. A plain object without operators is rejected, because it would replace the whole document.'),
80
+ ],
81
+ },
82
+ {
83
+ operation: 'findOneAndUpdate',
84
+ label: 'Update and return document',
85
+ toolName: 'update_and_return_document',
86
+ description: "Update the first document of this node's collection that matches a filter and return it as it is AFTER the update. Use it when you need the updated values in your reply; otherwise update_document is enough.",
87
+ parameters: [
88
+ filtro('the document to update. It cannot be empty'),
89
+ p('update', 'JSON object with MongoDB update operators, e.g. {"$set": {"status": "shipped"}}. A plain object without operators is rejected.'),
90
+ ],
91
+ },
92
+ {
93
+ operation: 'deleteOne',
94
+ label: 'Delete document',
95
+ toolName: 'delete_document',
96
+ description: "Delete the first document of this node's collection that matches a filter. This cannot be undone. When you are not sure which document the filter selects, call find_one_document first.",
97
+ parameters: [filtro('the document to delete. It cannot be empty')],
98
+ },
99
+ ]);
100
+ /** Las herramientas por nombre, para despachar una llamada del modelo. */
101
+ exports.MONGO_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.MONGO_TOOLKIT_SPECS.map((s) => [s.toolName, s]));
@@ -0,0 +1,52 @@
1
+ /**
2
+ * PostgreSQL AI Toolkit — las herramientas que un postgresAction expone cuando
3
+ * `aiEnabled` está encendido.
4
+ *
5
+ * ## Por qué las escrituras NO reciben SQL (2026-09-24, decisión de Ariel)
6
+ *
7
+ * El nodo, en modo de una operación, ejecuta el SQL que se le escribe: sus
8
+ * cinco operaciones son una etiqueta encima del mismo SQL crudo. Si el toolkit
9
+ * hiciera lo mismo, bloquear una herramienta no bloquearía nada — un
10
+ * `insert_rows` puede llevar un `DELETE` dentro de un `WITH`, y quien bloqueó
11
+ * `delete_rows` seguiría viendo desaparecer filas.
12
+ *
13
+ * Así que las tres escrituras reciben la tabla del nodo y JSON, y el SQL lo
14
+ * genera el handler, parametrizado y con los identificadores entrecomillados:
15
+ * el modelo no escribe SQL que se ejecute como escritura.
16
+ *
17
+ * ## Lo que queda con SQL, y cómo se contiene
18
+ *
19
+ * - `query_rows` recibe SQL, y corre dentro de una transacción **READ ONLY**:
20
+ * un `DELETE`, un `UPDATE` o un `CREATE` los rechaza el propio Postgres, no
21
+ * una expresión regular nuestra. Puede leer otras tablas —un JOIN hace
22
+ * falta a menudo—; el límite ahí lo pone el usuario de base de datos de la
23
+ * credencial.
24
+ * - `execute_sql` recibe SQL cualquiera, DDL incluido. Es la excepción
25
+ * consciente a «sólo la tabla del nodo»: SQL crudo no se puede vallar a una
26
+ * tabla. La contienen tres cosas: es siempre destructiva (el gate del AI
27
+ * Node la para si está encendido), se puede bloquear en el nodo, y el
28
+ * usuario de base de datos.
29
+ *
30
+ * Los textos van en inglés porque los lee el modelo.
31
+ */
32
+ import type { PostgresOperation } from './postgres-operations';
33
+ export interface PostgresToolkitParameter {
34
+ name: string;
35
+ /** El esquema MCP sólo admite estos tres; lo estructurado viaja como JSON
36
+ * en un `string`. */
37
+ type: 'string' | 'number' | 'boolean';
38
+ description: string;
39
+ required: boolean;
40
+ }
41
+ export interface PostgresToolkitSpec {
42
+ operation: PostgresOperation;
43
+ label: string;
44
+ toolName: string;
45
+ description: string;
46
+ parameters: PostgresToolkitParameter[];
47
+ /** Pisa o borra. Lo pone `marcarDestructivas`, no se escribe a mano. */
48
+ destructive?: boolean;
49
+ }
50
+ export declare const POSTGRES_TOOLKIT_SPECS: PostgresToolkitSpec[];
51
+ /** Las herramientas por nombre, para despachar una llamada del modelo. */
52
+ export declare const POSTGRES_TOOLKIT_BY_TOOL_NAME: Record<string, PostgresToolkitSpec>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * PostgreSQL AI Toolkit — las herramientas que un postgresAction expone cuando
4
+ * `aiEnabled` está encendido.
5
+ *
6
+ * ## Por qué las escrituras NO reciben SQL (2026-09-24, decisión de Ariel)
7
+ *
8
+ * El nodo, en modo de una operación, ejecuta el SQL que se le escribe: sus
9
+ * cinco operaciones son una etiqueta encima del mismo SQL crudo. Si el toolkit
10
+ * hiciera lo mismo, bloquear una herramienta no bloquearía nada — un
11
+ * `insert_rows` puede llevar un `DELETE` dentro de un `WITH`, y quien bloqueó
12
+ * `delete_rows` seguiría viendo desaparecer filas.
13
+ *
14
+ * Así que las tres escrituras reciben la tabla del nodo y JSON, y el SQL lo
15
+ * genera el handler, parametrizado y con los identificadores entrecomillados:
16
+ * el modelo no escribe SQL que se ejecute como escritura.
17
+ *
18
+ * ## Lo que queda con SQL, y cómo se contiene
19
+ *
20
+ * - `query_rows` recibe SQL, y corre dentro de una transacción **READ ONLY**:
21
+ * un `DELETE`, un `UPDATE` o un `CREATE` los rechaza el propio Postgres, no
22
+ * una expresión regular nuestra. Puede leer otras tablas —un JOIN hace
23
+ * falta a menudo—; el límite ahí lo pone el usuario de base de datos de la
24
+ * credencial.
25
+ * - `execute_sql` recibe SQL cualquiera, DDL incluido. Es la excepción
26
+ * consciente a «sólo la tabla del nodo»: SQL crudo no se puede vallar a una
27
+ * tabla. La contienen tres cosas: es siempre destructiva (el gate del AI
28
+ * Node la para si está encendido), se puede bloquear en el nodo, y el
29
+ * usuario de base de datos.
30
+ *
31
+ * Los textos van en inglés porque los lee el modelo.
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.POSTGRES_TOOLKIT_BY_TOOL_NAME = exports.POSTGRES_TOOLKIT_SPECS = void 0;
35
+ const clase_de_herramienta_js_1 = require("./clase-de-herramienta.js");
36
+ const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
37
+ const donde = (que) => p('where', `JSON object selecting the rows ${que}: each key is a column and each value the value it must equal, all of them at once, e.g. {"id": 42} or {"status": "pending", "customer_id": 7}. It cannot be empty — an empty condition would touch every row.`);
38
+ const parametros = () => p('params', 'Optional JSON array with the values for the $1, $2… placeholders in the SQL, e.g. ["paid", 100]. Always pass values this way instead of writing them into the SQL.', false);
39
+ exports.POSTGRES_TOOLKIT_SPECS = (0, clase_de_herramienta_js_1.marcarDestructivas)([
40
+ {
41
+ operation: 'query',
42
+ label: 'Query rows',
43
+ toolName: 'query_rows',
44
+ description: 'Run a read-only SQL query (SELECT, WITH … SELECT) and return its rows, at most 200. It runs inside a READ ONLY transaction: a statement that writes is rejected by the database. Use it for lookups, counts, sums and joins.',
45
+ parameters: [
46
+ p('sql', 'The SELECT statement, with $1, $2… placeholders for values, e.g. SELECT * FROM orders WHERE status = $1 LIMIT 20.'),
47
+ parametros(),
48
+ ],
49
+ },
50
+ {
51
+ operation: 'insertOne',
52
+ label: 'Insert rows',
53
+ toolName: 'insert_rows',
54
+ description: "Insert one or more rows into this node's table and return them as stored, with the values the database filled in (ids, defaults). It does not check for duplicates.",
55
+ parameters: [
56
+ p('rows', 'JSON object with one row, or a JSON array of rows. Keys are column names, e.g. {"name": "Ariel", "email": "a@b.c"}. A key that is not a column makes the call fail.'),
57
+ ],
58
+ },
59
+ {
60
+ operation: 'update',
61
+ label: 'Update rows',
62
+ toolName: 'update_rows',
63
+ description: "Update the rows of this node's table that match a condition, overwriting the columns you set, and return them after the update. When no row matches it changes nothing.",
64
+ parameters: [
65
+ p('set', 'JSON object with the columns to overwrite and their new values, e.g. {"status": "shipped"}.'),
66
+ donde('to update'),
67
+ ],
68
+ },
69
+ {
70
+ operation: 'delete',
71
+ label: 'Delete rows',
72
+ toolName: 'delete_rows',
73
+ description: "Delete the rows of this node's table that match a condition and return them as they were. This cannot be undone: when you are not sure which rows match, check with query_rows first.",
74
+ parameters: [donde('to delete')],
75
+ },
76
+ {
77
+ operation: 'execute',
78
+ label: 'Execute SQL',
79
+ toolName: 'execute_sql',
80
+ description: 'Run any SQL statement — including ones that change the schema (CREATE, ALTER, DROP) — and return what it produces. It is not limited to this node\'s table. Prefer query_rows, insert_rows, update_rows or delete_rows whenever one of them can do the job.',
81
+ parameters: [
82
+ p('sql', 'The SQL statement, with $1, $2… placeholders for values.'),
83
+ parametros(),
84
+ ],
85
+ },
86
+ ]);
87
+ /** Las herramientas por nombre, para despachar una llamada del modelo. */
88
+ exports.POSTGRES_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.POSTGRES_TOOLKIT_SPECS.map((s) => [s.toolName, s]));