WU / DOCSMICROFRONTENDS UNIVERSAIS
PT

Ações IA e MCP executáveis

Registre e execute ações WU sem provedor; conecte um relay MCP real e verifique schema, permissões, autenticação, cancelamento e limpeza.

Uma ação não precisa de um provedor LLM

wu.ai.execute invoca um handler registrado. Você pode usá-lo a partir de sua própria interface, de um agente externo ou de um teste sem configurar provider, criar prompts nem inserir uma API key. Os provedores são necessários para operações que conversam com modelos; o registro e a execução direta de ações funcionam separadamente.

A receita examples/ai/local-actions.mjs executa uma soma real e verifica rejeições antes que o handler faça seu cálculo.

Baixe o projeto de receitas, extraia o ZIP e execute npm install para obter as dependências. Inclui as mesmas ações usadas pelos exemplos Node e MCP, junto com seus testes.

node examples/ai/local-actions.mjs
node scripts/verify-server-examples.mjs

Registrar, habilitar e executar

import wu from 'wu-framework';

const ai = await wu.aiReady();
ai.init({ permissions: {
  executeActions: true,
  readStore: false,
  writeStore: false,
  emitEvents: false,
  readDOM: false,
  modifyDOM: false,
  readDiagnostics: false,
  navigate: false,
  network: false,
} });

ai.action('sum_local', {
  description: 'Suma dos números sin efectos externos',
  parameters: {
    type: 'object',
    properties: { a: { type: 'number' }, b: { type: 'number' } },
    required: ['a', 'b'],
  },
  handler({ a, b }) {
    if (!Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(a + b)) {
      throw new Error('Se requieren números y resultado finitos');
    }
    return { sum: a + b };
  },
});

const outcome = await ai.execute('sum_local', { a: 2, b: 3 });
// { success: true, result: { sum: 5 } }

Aguarde aiReady() antes de operações que retornam dados. action retorna o objeto IA para encadear registros. execute retorna uma promessa com { success, result? , reason? }; uma falha de permissão ou validação normalmente é representada por success: false, não pelo lançamento de uma exceção para o chamador.

ai.tools() expõe schemas do catálogo para clientes externos. O fato de uma ferramenta aparecer nessa lista não concede permissão para executá-la.

Schema, permissão e regras de domínio

A validação de parâmetros do WU é deliberadamente pequena: verifica campos obrigatórios, tipos de propriedades de primeiro nível — incluindo integer — e enum. Não é um validador completo de JSON Schema. Regras como limites numéricos, additionalProperties, formatos e validação recursiva exigem validação do produto antes do efeito.

A receita testa um campo ausente, uma string onde se esperava um número e um valor não finito. O primeiro e o segundo caso são rejeitados pelo WU; o terceiro é rejeitado pelo handler com uma regra explícita. Um contador demonstra que apenas o caso permitido chegou ao cálculo.

ai.permissions.configure({ executeActions: false });
const result = await ai.execute('sum_local', { a: 2, b: 3 });
// { success: false, reason: 'Permission denied: executeActions' }

Uma ação pode declarar permissions: ['readStore'] ou permissionsWhen(params). As flags exigidas são verificadas antes da validação e do handler. A API fornecida como segundo argumento oferece apenas as operações declaradas e habilitadas, por exemplo getState, setState, emit ou fetch.

Mantenha estes controles separados:

Controle Decide
Capabilities da app WU Acesso técnico a store, eventos e RPC por meio de sua facade
Flags IA Se o subsistema pode executar ações, ler DOM, gravar estado ou usar a rede
Autorização de domínio Qual operação de negócio o servidor permite ao ator autenticado
Capacidade do executor Se o backend ou runner implementa cancelamento, transação ou outra operação

Os handlers são código confiável do host. Uma closure pode acessar objetos globais fora da API fornecida; o registro não é um sandbox para JavaScript hostil. Para ações com efeitos no backend, use um serviço que revalide identidade, schema, escopo e autorização. Estas receitas mantêm cálculos puros e não acessam drivers privilegiados.

Confirmação e cleanup

const stop = wu.on('ai:tool:confirm', event => {
  // La receta de rechazo no concede ninguna aprobación.
  ai.rejectTool(event.data.callId);
});

try {
  const result = await ai.execute('sum_with_confirmation', { a: 2, b: 3 });
  // success: false; reason: 'User denied action'
} finally {
  stop();
  ai.destroy();
  await wu.destroy();
}

A ação sum_with_confirmation está registrada em examples/ai/register-actions.mjs com confirm: true. Uma UI que obtenha uma decisão afirmativa usa confirmTool(callId); rejectTool resolve a recusa. Sem uma decisão, a confirmação expira após 30 segundos e nega a execução.

Resolva ou rejeite as confirmações pendentes antes de destruir o subsistema e remova as inscrições instaladas pela integração. destroy limpa os recursos de IA; não cancela arbitrariamente promessas ou efeitos capturados por handlers próprios. Também não transforma o histórico em memória em uma auditoria durável.

MCP: do cliente ao navegador ativo

O servidor MCP do pacote é um relay. O cliente fala MCP/JSON-RPC por stdio; o relay envia comandos por WebSocket à ponte de uma página com WU carregado. A ação é executada nessa página, com suas permissões IA.

Cliente MCP → stdio → wu-mcp-server → WebSocket → wu.mcp → wu.ai.execute

Execute a receita completa:

node examples/mcp/local-relay.mjs
node scripts/verify-server-examples.mjs --mcp

A receita inicia o servidor empacotado por meio do export wu-framework/mcp-server, serve o bundle UMD instalado a partir de um listener local e abre Chromium headless. No Windows, usa Edge; em outros sistemas, usa o Chromium do Playwright. Se o navegador do Playwright estiver ausente, instale seus binários com npx playwright install chromium. Você pode escolher um canal instalado por meio de WU_BROWSER_CHANNEL.

Não precisa de um cliente MCP externo instalado: examples/mcp/stdio-client.mjs implementa apenas as operações JSON-RPC necessárias para inicializar, listar ferramentas, invocar e cancelar uma espera. Para uma integração geral, use um cliente MCP que gerencie o protocolo completo.

Conectar seu próprio cliente

O pacote instala o executável wu-mcp-server. Configure seu ambiente a partir do host que inicia esse processo. Não coloque o token em uma URL nem o publique no código do frontend.

Variável Comportamento
WU_MCP_TOKEN Obrigatório, exceto com adesão ao modo inseguro; entre 16 e 4096 bytes
WU_MCP_HOST 127.0.0.1 por padrão
WU_MCP_PORT 19100; aceita 1–65535
WU_MCP_ORIGINS Origens HTTP(S) exatas separadas por vírgulas; sem caminhos
WU_MCP_TIMEOUT Espera pela resposta da ponte: 30000 ms por padrão, intervalo 50–300000
WU_MCP_AUTH_TIMEOUT Espera pela autenticação: 5000 ms por padrão, intervalo 50–60000
WU_MCP_MAX_PAYLOAD 1048576 bytes por padrão, intervalo 1024–16777216
WU_MCP_INSECURE Apenas 1 permite omitir o token; a receita mantém a autenticação obrigatória

Sem WU_MCP_ORIGINS, são aceitas páginas HTTP(S) de loopback; um cliente WebSocket sem Origin não passa por essa verificação. A receita restringe o relay à origem exata do servidor que acabou de criar.

Na página, uma integração confiável entrega o token efêmero à ponte:

await wu.mcp.connect(relayUrl, { token: sessionToken });

A promessa carrega o módulo e inicia a conexão; não garante que o handshake já tenha terminado. Verifique wu.mcp.isConnected() e consulte wu_conexion a partir do cliente MCP para observar as duas pontas. O relay aceita uma ponte autenticada ativa por vez.

Ferramentas e leitura de resultados

Ferramenta Argumentos principais
wu_conexion {}; estado do relay mesmo sem uma página conectada
wu_list_actions {}; catálogo de ações da página
wu_execute_action { action, params? }
wu_get_state { path? }; exige readStore
wu_set_state { path, value }; exige writeStore
wu_emit_event { event, data? }; rejeita namespaces wu:, system: e app:

O relay também registra ferramentas de estado do WU, apps, eventos, navegação, DOM, diagnóstico e montagem. tools/list retorna o catálogo exato da versão instalada. Suas permissões continuam sendo aplicadas dentro da página.

Há dois níveis de resultado: o envelope MCP e o resultado da ação. Uma ação negada pode viajar em um envelope isError: false e conter success: false no JSON de content[0].text. Verifique ambos:

const response = await client.callTool('wu_execute_action', {
  action: 'sum_local', params: { a: 2, b: 3 },
});
if (response.isError) throw new Error(response.content[0].text);
const outcome = JSON.parse(response.content[0].text);
if (!outcome.success) throw new Error(outcome.reason);
console.log(outcome.result);

Esse trecho usa o cliente mínimo da receita. A assinatura de callTool em outro SDK pode ser diferente.

Cancelamento que você pode observar

A receita envia notifications/cancelled quando cancela a espera por uma solicitação MCP. Depois verifica que o handler bounded_sum, já iniciado no navegador, termina seu atraso fixo e seu cálculo. O relay não transmite um AbortSignal para wu.ai.execute.

Portanto, cancelar uma espera não demonstra que o trabalho parou. Para operações longas com efeitos, projete um serviço com identificador de operação, autorização de status/cancel e cancelamento cooperativo do executor. WASM/WASI pode hospedar lógica portátil, mas o host ainda precisa implementar esses contratos e o transporte de rede. O serviço conectado com WU mostra um caso diferente: conecta o signal RPC à terminação efetiva de seu Worker.

Ao terminar, chame wu.mcp.disconnect() para interromper reconexões e liberar seus interceptadores. O teste verifica que fetch e console.log recuperam suas referências anteriores, que o relay já não vê uma app conectada e que os processos criados são fechados. Consulte extensões e IA e segurança para conhecer os limites do runtime.

CONSTRUA O WU CONOSCO

Encontrou um bug? Tem uma ideia?

Sua experiência melhora o WU. Conte o que falhou ou ajude a manter seu desenvolvimento.