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.
Pré-requisitos
Seção intitulada “Pré-requisitos”Antes de usar este gerador, certifique-se de ter:
- Um website React (gerado usando o gerador
ts#react-website) - Um Python Strands Agent com
protocol=AG-UI(gerado usando o geradorpy#strands-agent) - Para agentes implantados, Cognito Auth adicionado via o gerador
ts#react-website-auth
Executar o Gerador
Seção intitulada “Executar o Gerador”- Instale o Nx Console VSCode Plugin se ainda não o fez
- Abra o console Nx no VSCode
- Clique em
Generate (UI)na seção "Common Nx Commands" - Procure por
@aws/nx-plugin - connection - Preencha os parâmetros obrigatórios
- Clique em
Generate
pnpm nx g @aws/nx-plugin:connectionyarn nx g @aws/nx-plugin:connectionnpx nx g @aws/nx-plugin:connectionbunx nx g @aws/nx-plugin:connectionVocê também pode realizar uma execução simulada para ver quais arquivos seriam alterados
pnpm nx g @aws/nx-plugin:connection --dry-runyarn nx g @aws/nx-plugin:connection --dry-runnpx nx g @aws/nx-plugin:connection --dry-runbunx nx g @aws/nx-plugin:connection --dry-runVocê 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. |
Saída do Gerador
Seção intitulada “Saída do Gerador”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 deconnectione atualizado em execuções subsequentes para registrar cada novo agente. Directorycopilot
- index.tsx Re-exporta
CopilotChat,CopilotSidebareCopilotPopupcom padrões de slot que correspondem aouxProviderdo seu website (Cloudscape, Shadcn, ou nenhum tema). - ThemeComponents .tsx Componentes de tema por slot (ex:
CloudscapeAssistantMessage.tsx,ShadcnChatInput.tsx). Apenas fornecidos quandouxProvideréCloudscapeouShadcn.
- index.tsx Re-exporta
- AguiProvider.tsx
Directoryhooks
- useAgui<AgentName>.tsx Registra um agente AG-UI. Um arquivo por execução de
connection. - useSigV4.tsx Assinatura SigV4 (somente IAM)
- useAgui<AgentName>.tsx Registra um agente AG-UI. Um arquivo por execução de
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— forneceCopilotKitProvidere componentes de chat (CopilotChat,CopilotSidebar,CopilotPopup)@ag-ui/client—HttpAgentusado pelos hooks geradosaws4fetch,oidc-client-ts,react-oidc-context,@aws-sdk/credential-providers— somente autenticação IAMreact-oidc-context— autenticação Cognito
Como Funciona
Seção intitulada “Como Funciona”Conexão AG-UI
Seção intitulada “Conexão AG-UI”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-localsubstitui 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.
Integração CopilotKit
Seção intitulada “Integração 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ê).
Autenticação
Seção intitulada “Autenticação”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
Authorizationcomo um token Bearer.
Infraestrutura
Seção intitulada “Infraestrutura”Se o seu agente usa autenticação IAM, a função autenticada do Cognito Identity Pool deve receber permissão para invocar o agente.
const identity = new UserIdentity(this, 'Identity');const myAgent = new MyAgent(this, 'MyAgent');
// Grant the authenticated Cognito role permission to invoke the agentmyAgent.grantInvokeAccess(identity.identityPool.authenticatedRole);grantInvokeAccess conecta todas as ações de invocação do AgentCore (InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream) no ARN de runtime do agente.
module "identity" { source = "../../common/terraform/src/core/user-identity"}
module "my_agent" { source = "../../common/terraform/src/app/agents/my-agent"
appconfig_application_id = module.runtime_config_appconfig.application_id appconfig_application_arn = module.runtime_config_appconfig.application_arn}
# Grant the authenticated Cognito role permission to invoke the agentresource "aws_iam_policy" "invoke_my_agent" { name = "InvokeMyAgentPolicy" policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = [ "bedrock-agentcore:InvokeAgentRuntime", "bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream", ] Resource = [ module.my_agent.agent_core_runtime_arn, "${module.my_agent.agent_core_runtime_arn}/*", ] }] })}
resource "aws_iam_role_policy_attachment" "invoke_my_agent" { role = module.identity.authenticated_role_name policy_arn = aws_iam_policy.invoke_my_agent.arn}Se o seu agente usa autenticação Cognito, você não precisa definir nenhuma infraestrutura adicional para conectar seu website ao seu agente.
Usando o Código Gerado
Seção intitulada “Usando o Código Gerado”Adicionando uma Interface de Chat
Seção intitulada “Adicionando uma Interface de Chat”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...', }} /> );}Conectando Múltiplos Agentes AG-UI
Seção intitulada “Conectando Múltiplos Agentes AG-UI”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 */}Personalizando a Aparência
Seção intitulada “Personalizando a Aparência”<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.
Temas Integrados
Seção intitulada “Temas Integrados”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:
uxProvider | Estilização aplicada a CopilotChat / CopilotSidebar / CopilotPopup |
|---|---|
Cloudscape | Mensagens 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. |
Shadcn | Mensagens 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.
Personalizando o Tema
Seção intitulada “Personalizando o Tema”O tema gerado vive inteiramente dentro do seu projeto:
src/components/copilot/index.tsx— exporta osCopilotChat/CopilotSidebar/CopilotPopuptemáticos e os objetoscloudscapeCopilotTheme/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.
Estilização Tailwind via slots
Seção intitulada “Estilização Tailwind via slots”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>, }, }}/>Desenvolvimento Local
Seção intitulada “Desenvolvimento Local”O gerador de conexão configura automaticamente a integração serve-local:
- Executar
nx serve-local <website>também iniciará o servidor local do agente - A configuração de runtime é substituída para apontar para a URL AG-UI local (ex:
http://localhost:8081) - Tanto o website quanto o agente recarregam automaticamente juntos
pnpm nx serve-local <WebsiteProject>yarn nx serve-local <WebsiteProject>npx nx serve-local <WebsiteProject>bunx nx serve-local <WebsiteProject>