# 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:

```ts
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.

{% callout type="tip" %}
**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.
{% /callout %}

## Exemplos reais do SDK

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

| Plugin | Ferramenta | `mode` | O que faz |
| --- | --- | --- | --- |
| `agenda` | `listAppointments` | `read` | Lista agendamentos de uma data ou período, com filtro por profissional. |
| `agenda` | `createAppointment` | `persist` | Cria um agendamento para um cliente com profissional e serviço. |
| `agenda` | `checkAvailability` | `read` | Verifica horários livres de um profissional numa data. |
| `menu` | `toggleMenuItemAvailability` | `persist` | Marca um item do cardápio como disponível/esgotado. |
| `financial` | `getRevenue` | `read` | Devolve o faturamento de um período. |
| `orders` | `createOrder` | `persist` | Abre um novo pedido. |
| `inventory` | `getLowStock` | `read` | Lista itens abaixo do ponto de reposição. |
| `conversations` | `sendMessage` | `persist` | Envia uma mensagem numa conversa. |
| `dashboard` | `getKpiSummary` | `read` | Resume 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.

{% callout type="warn" %}
**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ê.
{% /callout %}

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:

```json
{
  "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](/pt-BR/docs/referencia/plugin-manifest). Para conectar o agente a este Dev Center, veja [Conecte seu agente](/pt-BR/docs/ia/conecte-seu-agente).
