React para Agente AG-UI
Nx Plugin for AWS fornece um gerador para conectar um site React a um Agente que expõe o protocolo AG-UI. Ele configura o CopilotKit com um HttpAgent @ag-ui/client no seu site, 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 site React (gerado usando o gerador
ts#website) - Um Agente TypeScript ou Python com
protocol=ag-ui(gerado usando o geradorts#agentoupy#agent) - Para agentes implantados, Cognito Auth adicionado via gerador
ts#website#auth
Executar o Gerador
Seção intitulada “Executar o Gerador”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-run- 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
Você será solicitado a selecionar seu site React como o projeto de origem e o projeto contendo seu Agente AG-UI como o projeto de destino. Se o 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. |
| preferInstallDependencies | boolean | true | Se deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que os geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final. |
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 aouxdo seu site (Cloudscape, Shadcn, ou nenhum tema). - ThemeComponents .tsx Componentes de tema por slot (por exemplo,
CloudscapeAssistantMessage.tsx,ShadcnChatInput.tsx). Fornecidos apenas quandouxé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 (apenas 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— apenas 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 ARN do Bedrock AgentCore Runtime, que é convertido para o endpoint HTTPS do AgentCore:
https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT - Desenvolvimento local:
devsubstitui o valor pela URL local do agente (por exemplo,http://localhost:8081)
O AguiProvider compartilhado chama cada hook gerado e espalha 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 vem com 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á conectado em main.tsx para você).
Autenticação
Seção intitulada “Autenticação”O código gerado lida com 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 site.
- Cognito: incorpora o token de acesso JWT no cabeçalho
Authorizationcomo um Bearer token.
Sessões e Threads
Seção intitulada “Sessões e Threads”AG-UI e AgentCore Runtime identificam uma conversa de maneira diferente, e o hook gerado os conecta:
threadId— o identificador de conversa AG-UI, enviado no corpo da requisição. CopilotKit gera um UUID aleatório por chat, a menos que você passe umthreadIdexplícito.- Session ID — a sessão do AgentCore Runtime, enviada no cabeçalho
X-Amzn-Bedrock-AgentCore-Runtime-Session-Id. Ele seleciona a microVM que atende a requisição, e é o que osession.ts/session.pydo seu agente usa como chave para o estado da conversa.
O hook deriva o session ID do thread ID, preenchendo-o à direita até os 33 caracteres que o AgentCore Runtime requer:
function agentCoreSessionId(input: RunAgentInput): string { return (input.threadId ?? '').padEnd(33, '0');}Deixar threadId não definido é mais simples — o UUID gerado pelo CopilotKit já tem 36 caracteres. Se você passar um explicitamente, faça com que tenha pelo menos 33 caracteres, pois o preenchimento mapeia thread IDs que diferem apenas em caracteres finais para a mesma sessão.
Tanto o Session ID quanto o Thread ID são fornecidos pelo navegador. Para restringir cada usuário às suas próprias conversas, consulte o guia py#agent ou ts#agent.
Infraestrutura
Seção intitulada “Infraestrutura”Se o seu agent usa autenticação IAM, a função autenticada do Cognito Identity Pool deve receber permissão para invocar o agent.
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 agent.
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 agent usa autenticação Cognito, você não precisa definir nenhuma infraestrutura adicional para conectar seu website ao seu agent.
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 ts#agent ou py#agent — e você também pode encontrá-lo no arquivo de hook gerado (por exemplo, a chave retornada de packages/web/src/hooks/useAgui<AgentName>.tsx).
Importe os componentes de chat do módulo ./components/copilot gerado para que o tema que corresponde ao ux do seu site 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. Cada agente registrado via AguiProvider compartilhado é visível de qualquer lugar no aplicativo — instancie um componente CopilotKit com um agentId diferente para rotear cada chat para o agente que você deseja:
import { CopilotChat } from './components/copilot';
<CopilotChat agentId="story" /> {/* talks to StoryAgent */}<CopilotChat agentId="research" /> {/* talks to 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 subcomponente com uma string de classe Tailwind, um objeto de props 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.ux do seu projeto de site 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:
ux | Estilo aplicado a CopilotChat / CopilotSidebar / CopilotPopup |
|---|---|
cloudscape | Mensagens renderizadas dentro de ChatBubbles Cloudscape com Avatars gen-AI (correspondendo ao padrão de chat de IA generativa Cloudscape); o indicador de digitação se torna uma LoadingBar e a entrada é um PromptInput. Construído a partir de @cloudscape-design/components e @cloudscape-design/chat-components. |
shadcn | Mensagens do assistente renderizadas em uma bolha bg-muted com um avatar Sparkles; mensagens do usuário renderizadas alinhadas à direita em uma bolha bg-primary com um avatar User. A entrada é um Textarea arredondado + Button de enviar/parar em forma de pílula (Enter envia, Shift+Enter nova linha). Usa primitivos shadcn do pacote compartilhado common-shadcn. |
none (ou qualquer outra coisa) | Sem 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 conexão de slot padrão para cada chat no seu aplicativo.src/components/copilot/<ThemeComponent>.tsx— componentes de tema por slot (por exemplo,CloudscapeAssistantMessage,ShadcnChatInput). Edite estes para ajustar a aparência de um único slot sem reconectar o tema.
Por exemplo, para inserir seu próprio renderizador de mensagem de 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ê passar como prop de slot substitui o padrão temático:
<CopilotChat agentId="agent" // style the input and its children input={{ textArea: 'text-blue-600', sendButton: 'bg-blue-600 hover:bg-blue-700', }} // style nested message slots 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 em vez de um className, então você pode substituir o padrão inteiramente:
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 — por exemplo, 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 dev:
- Executar
nx dev <website>também iniciará o servidor local do agente - A configuração de runtime é substituída para apontar para a URL AG-UI local (por exemplo,
http://localhost:8081) - Tanto o site quanto o agente recarregam automaticamente juntos
pnpm nx dev <WebsiteProject>yarn nx dev <WebsiteProject>npx nx dev <WebsiteProject>bunx nx dev <WebsiteProject>