React vers Agent AG-UI
Nx Plugin for AWS fournit un générateur pour connecter un site web React à un Strands Agent qui expose le protocole AG-UI. Il configure CopilotKit avec un HttpAgent @ag-ui/client sur votre site web, avec prise en charge de l’authentification AWS IAM et Cognito.
Prérequis
Section intitulée « Prérequis »Avant d’utiliser ce générateur, assurez-vous d’avoir :
- Un site web React (généré avec le générateur
ts#react-website) - Un Python Strands Agent avec
protocol=AG-UI(généré avec le générateurpy#strands-agent) - Pour les agents déployés, Cognito Auth ajouté via le générateur
ts#react-website-auth
Utilisation
Section intitulée « Utilisation »Exécuter le générateur
Section intitulée « Exécuter le générateur »- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - connection - Remplissez les paramètres requis
- Cliquez sur
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:connectionVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
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-runVous serez invité à sélectionner votre site web React comme projet source et le projet contenant votre AG-UI Strands Agent comme projet cible. Si votre projet cible contient plusieurs composants (tels que plusieurs agents ou d’autres types de composants), vous serez invité à spécifier un targetComponent pour lever l’ambiguïté.
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| sourceProject Requis | string | - | Le projet source |
| targetProject Requis | string | - | Le projet cible auquel se connecter |
| sourceComponent | string | - | Le composant source depuis lequel se connecter (nom du composant, chemin relatif à la racine du projet source, ou identifiant du générateur). Utilisez '.' pour sélectionner explicitement le projet comme source. |
| targetComponent | string | - | Le composant cible auquel se connecter (nom du composant, chemin relatif à la racine du projet cible, ou identifiant du générateur). Utilisez '.' pour sélectionner explicitement le projet comme cible. |
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur crée un unique composant partagé AguiProvider, un hook par agent connecté, et un wrapper thématisé pour les composants de chat CopilotKit :
Répertoiresrc
Répertoirecomponents
- AguiProvider.tsx
CopilotKitProviderunique pour chaque agent AG-UI. Créé lors de la première exécution deconnectionet mis à jour lors des exécutions suivantes pour enregistrer chaque nouvel agent. Répertoirecopilot
- index.tsx Ré-exporte
CopilotChat,CopilotSidebaretCopilotPopupavec des valeurs par défaut de slots qui correspondent auuxProviderde votre site web (Cloudscape, Shadcn, ou aucun thème). - ThemeComponents .tsx Composants de thème par slot (par ex.
CloudscapeAssistantMessage.tsx,ShadcnChatInput.tsx). Fournis uniquement lorsqueuxProviderestCloudscapeouShadcn.
- index.tsx Ré-exporte
- AguiProvider.tsx
Répertoirehooks
- useAgui<AgentName>.tsx Enregistre un agent AG-UI. Un fichier par exécution de
connection. - useSigV4.tsx Signature SigV4 (IAM uniquement)
- useAgui<AgentName>.tsx Enregistre un agent AG-UI. Un fichier par exécution de
Exécuter connection une seconde fois pour un agent différent ajoute un nouveau hook useAgui<AgentName>.tsx et met à jour AguiProvider.tsx pour enregistrer les deux hooks — toutes les modifications personnalisées que vous avez apportées au provider sont préservées. main.tsx conserve son unique wrapper <AguiProvider> — vous ne vous retrouvez jamais avec des providers imbriqués.
Les dépendances suivantes sont ajoutées au package.json racine :
@copilotkit/react-core— fournitCopilotKitProvideret les composants de chat (CopilotChat,CopilotSidebar,CopilotPopup)@ag-ui/client—HttpAgentutilisé par les hooks générésaws4fetch,oidc-client-ts,react-oidc-context,@aws-sdk/credential-providers— authentification IAM uniquementreact-oidc-context— authentification Cognito
Fonctionnement
Section intitulée « Fonctionnement »Connexion AG-UI
Section intitulée « Connexion AG-UI »Chaque hook useAgui<AgentName> lit la valeur runtime de son agent depuis la Configuration Runtime et instancie un HttpAgent @ag-ui/client :
- Déployé : la valeur runtime est un ARN Bedrock AgentCore Runtime, qui est converti en point de terminaison HTTPS AgentCore :
https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT - Développement local :
serve-localremplace la valeur par l’URL locale de l’agent (par ex.http://localhost:8081)
Le AguiProvider partagé appelle chaque hook généré et les répartit dans selfManagedAgents sur un unique CopilotKitProvider, qui les expose tous aux composants CopilotKit.
Intégration CopilotKit
Section intitulée « Intégration CopilotKit »CopilotKit est le client React de référence officiel pour le protocole AG-UI et fournit des composants de chat prêts à l’emploi :
<CopilotChat />— interface de chat complète<CopilotSidebar />— panneau latéral de chat fixe<CopilotPopup />— popup de chat flottant
Placez n’importe lequel de ces composants n’importe où à l’intérieur du wrapper <AguiProvider> (déjà configuré dans main.tsx pour vous).
Authentification
Section intitulée « Authentification »Le code généré gère l’authentification en fonction de la configuration de votre agent :
- IAM (par défaut) : utilise des requêtes HTTP signées AWS SigV4. Les informations d’identification sont obtenues à partir du Cognito Identity Pool configuré avec l’authentification de votre site web.
- Cognito : intègre le jeton d’accès JWT dans l’en-tête
Authorizationen tant que jeton Bearer.
Infrastructure
Section intitulée « Infrastructure »Si votre agent utilise l’authentification IAM, le rôle authentifié du pool d’identités Cognito doit se voir accorder la permission d’invoquer l’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 configure toutes les actions d’invocation AgentCore (InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream) sur l’ARN d’exécution de l’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}Si votre agent utilise l’authentification Cognito, vous n’avez pas besoin de définir d’infrastructure supplémentaire pour connecter votre site web à votre agent.
Utilisation du code généré
Section intitulée « Utilisation du code généré »Ajout d’une interface de chat
Section intitulée « Ajout d’une interface de chat »Instanciez les composants CopilotKit avec agentId pour sélectionner l’agent à utiliser. L’id est le nom de l’agent — le même que celui que vous avez choisi lors de l’exécution du générateur py#strands-agent — et vous pouvez également le trouver dans le fichier hook généré (par ex. la clé retournée par packages/web/src/hooks/useAgui<AgentName>.tsx).
Importez les composants de chat depuis le module généré ./components/copilot afin que le thème correspondant au uxProvider de votre site web soit appliqué automatiquement :
import { CopilotChat } from './components/copilot';
function ChatPage() { return ( <CopilotChat agentId="agent" labels={{ welcomeMessageText: 'How can I help you today?', chatInputPlaceholder: 'Ask me anything...', }} /> );}Connexion de plusieurs agents AG-UI
Section intitulée « Connexion de plusieurs agents AG-UI »Exécutez le générateur connection une fois par agent. Tous les agents enregistrés via le AguiProvider partagé sont visibles depuis n’importe où dans l’application — instanciez un composant CopilotKit avec un agentId différent pour router chaque chat vers l’agent souhaité :
import { CopilotChat } from './components/copilot';
<CopilotChat agentId="story" /> {/* talks to StoryAgent */}<CopilotChat agentId="research" /> {/* talks to ResearchAgent */}Personnalisation de l’apparence
Section intitulée « Personnalisation de l’apparence »<CopilotChat /> (ainsi que <CopilotSidebar />, <CopilotPopup />) utilisent un système de slots récursif — vous pouvez remplacer n’importe quel sous-composant par une chaîne de classe Tailwind, un objet de propriétés ou un composant React personnalisé. Consultez le guide des slots CopilotKit pour l’arborescence complète des slots.
Thèmes intégrés
Section intitulée « Thèmes intégrés »Le générateur lit metadata.uxProvider depuis votre projet de site web React et fournit un module wrapper thématisé dans src/components/copilot/index.tsx afin que les composants de chat correspondent au reste de votre interface utilisateur sans configuration supplémentaire :
uxProvider | Style appliqué à CopilotChat / CopilotSidebar / CopilotPopup |
|---|---|
Cloudscape | Les messages s’affichent dans des ChatBubbles Cloudscape avec des Avatars gen-AI (correspondant au pattern de chat IA générative Cloudscape) ; l’indicateur de saisie devient une LoadingBar et l’entrée est un PromptInput. Construit à partir de @cloudscape-design/components et @cloudscape-design/chat-components. |
Shadcn | Les messages de l’assistant s’affichent dans une bulle bg-muted avec un avatar Sparkles ; les messages utilisateur s’affichent alignés à droite dans une bulle bg-primary avec un avatar User. L’entrée est un Textarea arrondi + un Button d’envoi/arrêt en forme de pilule (Entrée soumet, Maj+Entrée pour les sauts de ligne). Utilise les primitives shadcn du package partagé common-shadcn. |
None (ou autre) | Aucun thème — le module ré-exporte simplement les composants CopilotKit par défaut. |
Importez les composants thématisés depuis le module de thème local (et non directement depuis @copilotkit/react-core/v2) afin que le thème soit appliqué automatiquement :
import { CopilotChat } from './components/copilot';
<CopilotChat agentId="agent" />Le thème est appliqué en tant que valeurs par défaut des slots, donc tout slot que vous passez explicitement l’emporte — vous gardez le contrôle total lorsque vous avez besoin d’une modification ponctuelle.
Personnalisation du thème
Section intitulée « Personnalisation du thème »Le thème généré se trouve entièrement dans votre projet :
src/components/copilot/index.tsx— exporte lesCopilotChat/CopilotSidebar/CopilotPopupthématisés et les objetscloudscapeCopilotTheme/shadcnCopilotTheme. Modifiez ce fichier pour changer le câblage par défaut des slots pour tous les chats de votre application.src/components/copilot/<ThemeComponent>.tsx— composants de thème par slot (par ex.CloudscapeAssistantMessage,ShadcnChatInput). Modifiez-les pour ajuster l’apparence d’un seul slot sans recâbler le thème.
Par exemple, pour intégrer votre propre rendu de message utilisateur tout en conservant le reste du thème, modifiez le fichier correspondant dans src/components/copilot/ et ré-exportez-le depuis index.tsx.
Style Tailwind via les slots
Section intitulée « Style Tailwind via les slots »Les modifications par chat fonctionnent toujours parallèlement au thème — tout ce que vous passez en tant que propriété de slot remplace la valeur par défaut thématisée :
<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', }}/>Remplacement d’un slot par un composant personnalisé
Section intitulée « Remplacement d’un slot par un composant personnalisé »N’importe quel slot peut prendre un composant React au lieu d’un className, vous pouvez donc remplacer complètement le défaut :
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 }}/>;Les remplacements plus profonds suivent la même forme — par ex. remplacer uniquement le bouton de copie sur les messages de l’assistant :
<CopilotChat agentId="agent" messageView={{ assistantMessage: { copyButton: ({ onClick }) => <button onClick={onClick}>Copy</button>, }, }}/>Développement local
Section intitulée « Développement local »Le générateur de connexion configure automatiquement l’intégration serve-local :
- L’exécution de
nx serve-local <website>démarrera également le serveur local de l’agent - La configuration runtime est remplacée pour pointer vers l’URL AG-UI locale (par ex.
http://localhost:8081) - Le site web et l’agent se rechargent à chaud ensemble
pnpm nx serve-local <WebsiteProject>yarn nx serve-local <WebsiteProject>npx nx serve-local <WebsiteProject>bunx nx serve-local <WebsiteProject>