/** * El nodo de Airtable como AI toolkit: sus ocho operaciones como herramientas * que un AI Node, un servidor MCP o un agente de voz pueden llamar. * * ## Qué pidió Ariel (2026-09-26) * * «Ahora quiero que hagas el AI Toolkit de … Airtable», con el mismo criterio * que los anteriores: como si fuera single operation, con TODOS los campos de * cada operación (`AIRTABLE_OPERATION_SPECS`). Y dos decisiones suyas: * * - `delete_record` nace BLOQUEADA: por API no hay papelera. * - El alcance nace en la BASE del nodo (y en su tabla, si la tiene), y el * dueño lo puede abrir a todas sus bases (`toolkitScope: 'any'`). Como el * actor de Apify: cerrado de fábrica, abrible a propósito. * * ## Decide el LLM (2026-09-27) * * El mismo criterio que RSS, Firecrawl y Apify: «que le diga al LLM lo que * quiere y el LLM resuelva». Hasta ese día el límite de la single operation * del nodo era el TOPE de lo que el modelo podía pedir; ahora el tope es fijo * ({@link AIRTABLE_TOOLKIT_TOPES}) y lo guardado en single operation no cuenta en modo toolkit * para eso. Lo que el dueño sigue decidiendo es el QUÉ: la base y la tabla donde trabaja, las herramientas bloqueadas y los caracteres que vuelven. * * ## Los valores * * Los campos se escriben POR NOMBRE, como los ve el usuario en Airtable, en un * objeto JSON: `{"Name": "Ana", "Status": "Done"}`. `get_base_schema` le dice * al modelo qué campos hay y qué opciones admite cada select, y `typecast` * (activado por defecto, como en single operation) convierte «Done» en la * opción del select aunque no exista. */ import type { CampoDeToolkit } from './argumentos-de-toolkit.js'; export type AirtableToolkitOperation = 'listRecords' | 'getRecord' | 'createRecord' | 'updateRecord' | 'upsertRecord' | 'deleteRecord' | 'listBases' | 'getBaseSchema'; export interface AirtableToolkitParameter { name: string; type: 'string' | 'number' | 'boolean'; description: string; required: boolean; } export interface AirtableToolkitSpec { operation: AirtableToolkitOperation; label: string; toolName: string; description: string; parameters: AirtableToolkitParameter[]; destructive?: boolean; /** Nace bloqueada en el nodo; el dueño la desbloquea. Ver `toolkits.ts`. */ bloqueadaPorDefecto?: boolean; } /** Los parámetros que el nodo puede traer configurados: el modelo los omite * y se usan la base y la tabla del nodo. */ export declare const AIRTABLE_TOOLKIT_DEFAULTABLE: readonly ["base_id", "table_id"]; /** Cuántos records devuelve `list_records` si el modelo no dice otra cosa: * cada uno entra en su contexto. */ export declare const AIRTABLE_TOOLKIT_REGISTROS_POR_DEFECTO = 50; /** * Lo más que puede pedir el modelo. Fijo desde el 2026-09-27 (antes, el * `maxRecords` de la single operation del nodo, si lo tenía). 200: cada record * entra en el contexto, y con el tope de caracteres de fábrica (20.000) no * caben muchos más; para más, se filtra o se pide menos campos. */ export declare const AIRTABLE_TOOLKIT_TOPES: Readonly>; /** Hasta dónde llega el modelo. `node` (el de fábrica): la base del nodo, y * su tabla si la tiene. `any`: cualquier base de la credencial. */ export declare const AIRTABLE_TOOLKIT_ALCANCES: readonly ["node", "any"]; export type AirtableToolkitAlcance = (typeof AIRTABLE_TOOLKIT_ALCANCES)[number]; export declare const AIRTABLE_TOOLKIT_SPECS: AirtableToolkitSpec[]; export declare const AIRTABLE_TOOLKIT_SPECS_BY_TOOL_NAME: Readonly>; export declare const AIRTABLE_TOOLKIT_CAMPOS: Readonly>>>;