/** * El nodo de Shopify como AI toolkit: sus operaciones como herramientas que un * AI Node, un servidor MCP o un agente de voz pueden llamar. * * ## Qué pidió Ariel (2026-09-28) * * Como con Mailchimp, primero lo probó como cliente —en la tienda de * desarrollo `hw-tests`— y después el toolkit. Sus decisiones: * * - **Las 10 + lecturas.** Las diez operaciones, más buscar productos (con * sus variantes, precio, SKU y stock), buscar pedidos, buscar clientes, * ver un pedido y listar las sedes. Sin las lecturas el modelo no sabe * qué `variantId` poner en un borrador ni qué artículo de inventario * mover. * - **Nacen bloqueadas** cancelar un pedido, completar un borrador y * cumplir un pedido: las tres mueven dinero, stock o un envío, y ninguna * se deshace repitiéndola. El dueño las desbloquea en el nodo. * - **Lo decide el dueño, no el modelo**: los correos al cliente (al * cumplir y al cancelar), reponer el stock al cancelar, el estado de un * producto nuevo (DRAFT salvo que el dueño elija ACTIVE) y el * consentimiento de marketing, que el modelo no escribe nunca. * * Hasta ese día Shopify tenía `aiEnabled` pero exponía el nodo como UNA * herramienta sin operación, como RSS y Mailchimp antes de rehacerse. * * ## Quince herramientas para doce operaciones * * Al revés que Mailchimp, aquí la herramienta NO es la operación: * * - `findRecords` son TRES búsquedas (productos, pedidos, clientes). Una * sola con un `resource` obligaba al modelo a acertar un enum para algo * que ya dice el nombre. * - `setTags` son DOS: añadir y quitar. Shopify no hace las dos cosas en la * misma llamada, y un `remove: true` que el modelo olvida es añadir lo que * quería quitar. Además quitar pisa y añadir no: son clases distintas. * * {@link SHOPIFY_TOOLKIT_OPERACION} dice qué operación corre cada una y con qué * valores fijos; el resto va por el mismo `despachar` que single operation. * * ## El esquema * * Sólo `string`, `number` y `boolean` (lo que admite MCP): las líneas de un * borrador y la dirección van como JSON en un `string`; las etiquetas, como * se escriben en la caja: «vip, mx». */ import type { CampoDeToolkit } from './argumentos-de-toolkit.js'; import type { ShopifyOperation } from './shopify-operations.js'; export type ShopifyToolkitOperation = 'searchProducts' | 'searchOrders' | 'searchCustomers' | 'getOrder' | 'listLocations' | 'upsertCustomer' | 'addTags' | 'removeTags' | 'adjustInventory' | 'createDraftOrder' | 'completeDraftOrder' | 'fulfillOrder' | 'cancelOrder' | 'setMetafield' | 'createProduct'; export interface ShopifyToolkitParameter { name: string; type: 'string' | 'number' | 'boolean'; description: string; required: boolean; } export interface ShopifyToolkitSpec { operation: ShopifyToolkitOperation; label: string; toolName: string; description: string; parameters: ShopifyToolkitParameter[]; destructive?: boolean; /** Nace bloqueada en el nodo; el dueño la desbloquea. Ver `toolkits.ts`. */ bloqueadaPorDefecto?: boolean; } /** Cuántos registros trae una búsqueda como mucho. Productos, menos: cada uno * viene con sus variantes, y Shopify corta una consulta que pase de 1.000 * puntos de coste. */ export declare const SHOPIFY_TOOLKIT_MAXIMO: { readonly products: 25; readonly orders: 50; readonly customers: 50; }; /** Cuántos trae si el modelo no dice nada. */ export declare const SHOPIFY_TOOLKIT_POR_DEFECTO = 10; /** El estado de un producto nuevo que puede elegir el dueño. ARCHIVED no: un * producto recién creado y archivado no tiene sentido. */ export declare const SHOPIFY_TOOLKIT_ESTADOS_DE_PRODUCTO: readonly ["DRAFT", "ACTIVE"]; export type ShopifyToolkitEstadoDeProducto = (typeof SHOPIFY_TOOLKIT_ESTADOS_DE_PRODUCTO)[number]; export declare const SHOPIFY_TOOLKIT_SPECS: ShopifyToolkitSpec[]; export declare const SHOPIFY_TOOLKIT_SPECS_BY_TOOL_NAME: Readonly>; /** * Qué operación de single operation corre cada herramienta, y con qué campos * FIJOS — los que la herramienta decide por su nombre y el modelo no manda. */ export declare const SHOPIFY_TOOLKIT_OPERACION: Readonly>; }>>; /** Qué campo de `operationConfig` rellena cada parámetro. */ export declare const SHOPIFY_TOOLKIT_CAMPOS: Readonly>>>; /** * Los campos de single operation que el toolkit NO expone, y por qué. El test * de paridad los salta con nombre, no en silencio. Los fijos de * {@link SHOPIFY_TOOLKIT_OPERACION} tampoco se exponen, pero ésos los decide * la herramienta, no el dueño. */ export declare const SHOPIFY_TOOLKIT_FUERA: Readonly>;