Pular para o conteúdo

React para Agente AG-UI

O Nx Plugin for AWS fornece um gerador para conectar um website React a um Strands Agent que expõe o protocolo AG-UI. Ele configura o CopilotKit com um HttpAgent @ag-ui/client no seu website, com suporte para autenticação AWS IAM e Cognito.

Antes de usar este gerador, certifique-se de ter:

  1. Um website React (gerado usando o gerador ts#react-website)
  2. Um Python Strands Agent com protocol=AG-UI (gerado usando o gerador py#strands-agent)
  3. Para agentes implantados, Cognito Auth adicionado via o gerador ts#react-website-auth
  1. Instale o Nx Console VSCode Plugin se ainda não o fez
  2. Abra o console Nx no VSCode
  3. Clique em Generate (UI) na seção "Common Nx Commands"
  4. Procure por @aws/nx-plugin - connection
  5. Preencha os parâmetros obrigatórios
    • Clique em Generate

    Você será solicitado a selecionar seu website React como o projeto de origem e o projeto contendo seu AG-UI Strands Agent como o projeto de destino. Se seu projeto de destino contiver múltiplos componentes (como múltiplos agentes ou outros tipos de componentes), você será solicitado a especificar um targetComponent para desambiguar.

    Parâmetro Tipo Padrão Descrição
    sourceProject Obrigatório string - O projeto de origem
    targetProject Obrigatório string - O projeto de destino para conectar
    sourceComponent string - O componente de origem para conectar (nome do componente, caminho relativo à raiz do projeto de origem, ou id do gerador). Use '.' para selecionar explicitamente o projeto como origem.
    targetComponent string - O componente de destino para conectar (nome do componente, caminho relativo à raiz do projeto de destino, ou id do gerador). Use '.' para selecionar explicitamente o projeto como destino.

    O gerador cria um componente AguiProvider único compartilhado, um hook por agente conectado e um wrapper temático para os componentes de chat do CopilotKit:

    • Directorysrc
      • Directorycomponents
        • AguiProvider.tsx CopilotKitProvider único para cada agente AG-UI. Criado na primeira execução de connection e atualizado em execuções subsequentes para registrar cada novo agente.
        • Directorycopilot
          • index.tsx Re-exporta CopilotChat, CopilotSidebar e CopilotPopup com padrões de slot que correspondem ao uxProvider do seu website (Cloudscape, Shadcn, ou nenhum tema).
          • ThemeComponents .tsx Componentes de tema por slot (ex: CloudscapeAssistantMessage.tsx, ShadcnChatInput.tsx). Apenas fornecidos quando uxProvider é Cloudscape ou Shadcn.
      • Directoryhooks
        • useAgui<AgentName>.tsx Registra um agente AG-UI. Um arquivo por execução de connection.
        • useSigV4.tsx Assinatura SigV4 (somente IAM)

    Executar connection uma segunda vez para um agente diferente adiciona um novo hook useAgui<AgentName>.tsx e atualiza AguiProvider.tsx para registrar ambos os hooks — quaisquer edições personalizadas que você tenha feito no provider são preservadas. main.tsx mantém seu único wrapper <AguiProvider> — você nunca acaba com providers aninhados.

    As seguintes dependências são adicionadas ao package.json raiz:

    • @copilotkit/react-core — fornece CopilotKitProvider e componentes de chat (CopilotChat, CopilotSidebar, CopilotPopup)
    • @ag-ui/clientHttpAgent usado pelos hooks gerados
    • aws4fetch, oidc-client-ts, react-oidc-context, @aws-sdk/credential-providers — somente autenticação IAM
    • react-oidc-context — autenticação Cognito

    Cada hook useAgui<AgentName> lê o valor de runtime do seu agente da Configuração de Runtime e instancia um HttpAgent @ag-ui/client:

    • Implantado: o valor de runtime é um Bedrock AgentCore Runtime ARN, que é convertido para o endpoint HTTPS do AgentCore: https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT
    • Desenvolvimento local: serve-local substitui o valor para a URL local do agente (ex: http://localhost:8081)

    O AguiProvider compartilhado chama cada hook gerado e distribui cada um em selfManagedAgents em um único CopilotKitProvider, que os expõe todos aos componentes CopilotKit.

    CopilotKit é o cliente React de referência de primeira parte para o protocolo AG-UI e fornece componentes de chat prontos:

    • <CopilotChat /> — interface de chat completa
    • <CopilotSidebar /> — chat em painel lateral fixo
    • <CopilotPopup /> — popup de chat flutuante

    Coloque qualquer um destes em qualquer lugar dentro do wrapper <AguiProvider> (já configurado em main.tsx para você).

    O código gerado lida com a autenticação dependendo da configuração do seu agente:

    • IAM (padrão): usa requisições HTTP assinadas com AWS SigV4. As credenciais são obtidas do Cognito Identity Pool configurado com a autenticação do seu website.
    • Cognito: incorpora o token de acesso JWT no cabeçalho Authorization como um token Bearer.

    Se o seu agente usa autenticação IAM, a função autenticada do Cognito Identity Pool deve receber permissão para invocar o agente.

    packages/infra/src/stacks/application-stack.ts
    const identity = new UserIdentity(this, 'Identity');
    const myAgent = new MyAgent(this, 'MyAgent');
    // Grant the authenticated Cognito role permission to invoke the agent
    myAgent.grantInvokeAccess(identity.identityPool.authenticatedRole);

    grantInvokeAccess conecta todas as ações de invocação do AgentCore (InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream) no ARN de runtime do agente.

    Se o seu agente usa autenticação Cognito, você não precisa definir nenhuma infraestrutura adicional para conectar seu website ao seu agente.

    Instancie componentes CopilotKit com agentId para selecionar qual agente usar. O id é o nome do agente — o mesmo que você escolheu quando executou o gerador py#strands-agent — e você também pode encontrá-lo no arquivo de hook gerado (ex: a chave retornada de packages/web/src/hooks/useAgui<AgentName>.tsx).

    Importe os componentes de chat do módulo gerado ./components/copilot para que o tema que corresponde ao uxProvider do seu website seja aplicado automaticamente:

    import { CopilotChat } from './components/copilot';
    function ChatPage() {
    return (
    <CopilotChat
    agentId="agent"
    labels={{
    welcomeMessageText: 'How can I help you today?',
    chatInputPlaceholder: 'Ask me anything...',
    }}
    />
    );
    }

    Execute o gerador connection uma vez por agente. Todos os agentes registrados via o AguiProvider compartilhado são visíveis de qualquer lugar no aplicativo — instancie um componente CopilotKit com um agentId diferente para rotear cada chat para o agente desejado:

    import { CopilotChat } from './components/copilot';
    <CopilotChat agentId="story" /> {/* conversa com StoryAgent */}
    <CopilotChat agentId="research" /> {/* conversa com ResearchAgent */}

    <CopilotChat /> (e <CopilotSidebar />, <CopilotPopup />) usam um sistema de slots recursivo — você pode substituir qualquer sub-componente com uma string de classe Tailwind, um objeto de prop ou um componente React personalizado. Veja o guia de slots do CopilotKit para a árvore completa de slots.

    O gerador lê metadata.uxProvider do seu projeto de website React e fornece um módulo wrapper temático em src/components/copilot/index.tsx para que os componentes de chat correspondam ao resto da sua UI sem nenhuma configuração extra:

    uxProviderEstilização aplicada a CopilotChat / CopilotSidebar / CopilotPopup
    CloudscapeMensagens são renderizadas dentro de ChatBubbles do Cloudscape com Avatars gen-AI (correspondendo ao padrão de chat de IA generativa do Cloudscape); o indicador de digitação se torna uma LoadingBar e o input é um PromptInput. Construído a partir de @cloudscape-design/components e @cloudscape-design/chat-components.
    ShadcnMensagens do assistente são renderizadas em uma bolha bg-muted com um avatar Sparkles; mensagens do usuário são renderizadas alinhadas à direita em uma bolha bg-primary com um avatar User. O input é um Textarea arredondado + Button de enviar/parar em formato de pílula (Enter envia, Shift+Enter insere nova linha). Usa primitivos shadcn do pacote compartilhado common-shadcn.
    None (ou qualquer outro)Nenhum tema — o módulo apenas re-exporta os componentes padrão do CopilotKit.

    Importe os componentes temáticos do módulo de tema local (não diretamente de @copilotkit/react-core/v2) para que o tema seja aplicado automaticamente:

    import { CopilotChat } from './components/copilot';
    <CopilotChat agentId="agent" />

    O tema é aplicado como padrões de slot, então qualquer slot que você passar explicitamente ainda prevalece — você mantém controle total sempre que precisar de uma substituição pontual.

    O tema gerado vive inteiramente dentro do seu projeto:

    • src/components/copilot/index.tsx — exporta os CopilotChat / CopilotSidebar / CopilotPopup temáticos e os objetos cloudscapeCopilotTheme / shadcnCopilotTheme. Edite este arquivo para alterar a configuração padrão de slot para cada chat no seu aplicativo.
    • src/components/copilot/<ThemeComponent>.tsx — componentes de tema por slot (ex: CloudscapeAssistantMessage, ShadcnChatInput). Edite estes para ajustar a aparência de um único slot sem reconfigurar o tema.

    Por exemplo, para inserir seu próprio renderizador de mensagem do usuário mantendo o resto do tema, edite o arquivo relevante em src/components/copilot/ e re-exporte-o de index.tsx.

    Substituições por chat ainda funcionam junto com o tema — qualquer coisa que você passe como prop de slot substitui o padrão temático:

    <CopilotChat
    agentId="agent"
    // estiliza o input e seus filhos
    input={{
    textArea: 'text-blue-600',
    sendButton: 'bg-blue-600 hover:bg-blue-700',
    }}
    // estiliza slots de mensagem aninhados
    messageView={{
    assistantMessage: 'bg-blue-50 rounded-xl p-2',
    userMessage: 'bg-blue-100 rounded-xl',
    }}
    />

    Substituindo um slot com um componente personalizado

    Seção intitulada “Substituindo um slot com um componente personalizado”

    Qualquer slot pode receber um componente React ao invés de um className, então você pode substituir o padrão completamente:

    import { CopilotChat } from './components/copilot';
    const MySendButton: React.FC<{ onClick: () => void }> = ({ onClick }) => (
    <button onClick={onClick} className="my-send-btn">
    Send
    </button>
    );
    <CopilotChat
    agentId="agent"
    input={{ sendButton: MySendButton }}
    />;

    Substituições mais profundas seguem a mesma forma — ex: substitua apenas o botão de copiar nas mensagens do assistente:

    <CopilotChat
    agentId="agent"
    messageView={{
    assistantMessage: {
    copyButton: ({ onClick }) => <button onClick={onClick}>Copy</button>,
    },
    }}
    />

    O gerador de conexão configura automaticamente a integração serve-local:

    1. Executar nx serve-local <website> também iniciará o servidor local do agente
    2. A configuração de runtime é substituída para apontar para a URL AG-UI local (ex: http://localhost:8081)
    3. Tanto o website quanto o agente recarregam automaticamente juntos
    Terminal window
    pnpm nx serve-local <WebsiteProject>