fayzfayz sdk

Seu app como camada de dados para IA

Todo app gerado pela Fayz nasce pronto para agentes. Não é um recurso que você liga depois: o mesmo manifesto que descreve telas, rotas e dados também descreve, em contrato tipado, o que uma IA pode ler e fazer naquele app. Um agente que entende esse contrato consulta a agenda, resume o financeiro ou ajusta o estoque — sem que você escreva um endpoint de IA do zero.

Esta página explica o contrato aiTools, o que já vem de graça, como a shell de chat se conecta a um LLM e como um plugin próprio entra nessa camada.

O contrato aiTools

Todo plugin pode declarar um campo aiTools no seu manifesto (PluginManifest.aiTools?: PluginAITool[], em @fayz-ai/core). Cada ferramenta é uma função que um agente pode chamar, descrita num formato que LLMs entendem nativamente — o mesmo shape de function calling que a OpenAI e a Anthropic usam:

type PluginAITool = {
  id: string            // 'agenda.create-appointment'
  name: string          // 'createAppointment' — o nome que o LLM chama
  description: string    // o que a ferramenta faz, em linguagem natural
  mode: 'read' | 'persist'   // só lê dados, ou grava/muda estado?
  parameters?: {         // JSON Schema: type:'object', properties, required
    type: 'object'
    properties: Record<string, { type: string; description?: string }>
    required?: string[]
  }
  permission?: { feature: string; action: 'read' | 'create' | ... }
  suggestions?: { label: string }[]   // chips de sugestão no chat
  category?: string
}

Dois detalhes importam:

  • mode separa leitura de escrita. read consulta; persist cria ou muda estado. A shell usa isso para filtrar e para você poder pedir confirmação antes de qualquer persist.
  • permission prende a ferramenta ao controle de acesso. A mesma feature/permissão que protege a tela protege a ferramenta. Um agente rodando com o papel de um usuário só enxerga as ferramentas que aquele usuário poderia usar.

14 dos 22 plugins já declaram aiTools hoje — agenda, conversations, crm, dashboard, financial, forms, inventory, marketing, menu, orders, shop, tables, tasks e admin. Ligou o plugin, ganhou as ferramentas dele no contrato.

Exemplos reais do SDK

Estas são ferramentas que existem no código dos plugins hoje — não exemplos inventados:

PluginFerramentamodeO que faz
agendalistAppointmentsreadLista agendamentos de uma data ou período, com filtro por profissional.
agendacreateAppointmentpersistCria um agendamento para um cliente com profissional e serviço.
agendacheckAvailabilityreadVerifica horários livres de um profissional numa data.
menutoggleMenuItemAvailabilitypersistMarca um item do cardápio como disponível/esgotado.
financialgetRevenuereadDevolve o faturamento de um período.
orderscreateOrderpersistAbre um novo pedido.
inventorygetLowStockreadLista itens abaixo do ponto de reposição.
conversationssendMessagepersistEnvia uma mensagem numa conversa.
dashboardgetKpiSummaryreadResume os KPIs do negócio.

O que já vem de graça: ferramentas de core + registries

Além do que cada plugin declara, a shell da Fayz (@fayz-ai/saas) injeta três ferramentas de core sempre presentes, definidas em core-ai-tools.ts:

  • getBusinessSummary (read) — o panorama do negócio.
  • getTeamMembers (read) — quem está na equipe.
  • navigateTo (read) — leva o usuário a uma tela.

E há um multiplicador: cada registry (entidade) não-readonly do seu app vira uma ferramenta list<Entidade> automaticamente. Registrou products, ganhou listProducts sem escrever nada — o comentário no código é literal: "Each registry gets a basic 'list' tool so plugins get AI capabilities for free." Suas entidades viram consultáveis por um agente só por existirem.

A shell de chat — e a fronteira honesta

A shell já traz a UI: um FAB de chat e um painel (ChatFab, ChatPanel), com chips de sugestão vindos das aiTools e filtragem por permissão e vertical via o hook useAITools. O usuário vê as ferramentas certas e sugestões prontas.

Mas o useChat é traga-seu-endpoint (BYO endpoint). Ele faz POST do histórico da conversa para um apiEndpoint no formato OpenAI que você configura. Sem endpoint, a resposta é um mock de demonstração.

O SDK não executa ferramentas. PluginAITool não tem handler — ele é um schema, não uma implementação. Quem recebe o tool_call do LLM, roda a ação contra o Supabase (respeitando RLS) e devolve o resultado é o backend do dono do app. O SDK entrega o contrato e a UI; o loop de execução é seu. Nunca presuma que a Fayz "roda o agente" por você.

A arquitetura-alvo, honesta sobre o que existe:

┌─────────────┐  histórico (tools ficam no seu backend)  ┌──────────────────┐
│  ChatPanel   │ ─────────────────────────────────────▶ │  seu apiEndpoint  │
│  (shell UI)  │                        │  (seu backend)     │
│  useAITools  │ ◀───────────────────── │  + LLM (Claude/…)  │
└─────────────┘   resposta / tool_call  └────────┬─────────┘
       ▲                                          │ executa a tool
       │ schemas de aiTools                        ▼
       │ (do manifesto)                   ┌──────────────────┐
       └───────────────────────────────── │ Supabase + RLS    │
                                          │ (dados do tenant)  │
                                          └──────────────────┘

A shell fornece os schemas (o que existe) e a UI. Seu endpoint fornece o LLM e a execução. O RLS garante que o agente só toca os dados do tenant certo.

Cenários práticos

Escritos como arquitetura-alvo sobre o que já existe — os schemas estão prontos; falta você plugar o endpoint:

  • Assistente que consulta a agenda e marca. O LLM recebe listAppointments, checkAvailability e createAppointment. "Encaixa a Sarah amanhã de manhã?" → ele chama checkAvailability, escolhe o horário e propõe createAppointment (que é persist — você pede confirmação).
  • Resumo financeiro por chat. getRevenue + getKpiSummary alimentam "como foi a semana?" com números reais do tenant, não estimativa.
  • Agente de estoque. getLowStock acha o que está acabando; um persist de reposição (quando você o declarar) fecha o ciclo.

Um aiTool de verdade, em JSON

O schema que o seu endpoint entrega ao LLM — adaptado do createAppointment real do plugin-agenda:

{
  "name": "createAppointment",
  "description": "Creates a new appointment for a client with a specific professional and service.",
  "parameters": {
    "type": "object",
    "properties": {
      "client":       { "type": "string", "description": "Client name" },
      "professional": { "type": "string", "description": "Professional name" },
      "service":      { "type": "string", "description": "Service name" },
      "date":         { "type": "string", "description": "Date (YYYY-MM-DD)" },
      "time":         { "type": "string", "description": "Time (HH:MM)" }
    },
    "required": ["client", "professional", "service", "date", "time"]
  }
}

O mode: 'persist' e o permission ficam no manifesto (não vão ao LLM) — são o que a shell e o seu backend usam para gate e confirmação.

Como um plugin próprio entra nessa camada

Simples: declare aiTools no manifesto. O fayz create plugin já emite o array (vazio) — é só preencher. Uma ferramenta bem feita:

  1. Tem name verbo-substantivo claro (listLeads, createOrder).
  2. Declara mode honesto — persist para tudo que muda estado.
  3. Descreve parameters com description em cada campo (o LLM lê isso).
  4. Amarra permission à mesma feature da tela.

Feito isso, seu plugin aparece no chat, nas sugestões e no contrato que o agente lê. Para os campos completos, veja o Manifesto do plugin — referência. Para conectar o agente a este Dev Center, veja Conecte seu agente.