Skip to content

React to AG-UI Agent

Nx Plugin for AWS provides a generator to connect a React website to a Strands Agent that exposes the AG-UI protocol. It wires up CopilotKit with an @ag-ui/client HttpAgent on your website, with AWS IAM and Cognito authentication support.

Before using this generator, ensure you have:

  1. A React website (generated using the ts#react-website generator)
  2. A Python Strands Agent with protocol=AG-UI (generated using the py#strands-agent generator)
  3. For deployed agents, Cognito Auth added via the ts#react-website-auth generator
  1. Install the Nx Console VSCode Plugin if you haven't already
  2. Open the Nx Console in VSCode
  3. Click Generate (UI) in the "Common Nx Commands" section
  4. Search for @aws/nx-plugin - connection
  5. Fill in the required parameters
    • Click Generate

    You will be prompted to select your React website as the source project and the project containing your AG-UI Strands Agent as the target project. If your target project contains multiple components (such as multiple agents or other component types), you will be prompted to specify a targetComponent to disambiguate.

    Parameter Type Default Description
    sourceProject Required string - The source project
    targetProject Required string - The target project to connect to
    sourceComponent string - The source component to connect from (component name, path relative to source project root, or generator id). Use '.' to explicitly select the project as the source.
    targetComponent string - The target component to connect to (component name, path relative to target project root, or generator id). Use '.' to explicitly select the project as the target.

    The generator creates a single shared AguiProvider component and one hook per connected agent:

    • Directorysrc
      • Directorycomponents
        • AguiProvider.tsx Single CopilotKitProvider for every AG-UI agent. Created on the first connection run and updated on subsequent runs to register each new agent.
      • Directoryhooks
        • useAgui<AgentName>.tsx Registers one AG-UI agent. One file per connection run.
        • useSigV4.tsx SigV4 signing (IAM only)

    Running connection a second time for a different agent adds a new useAgui<AgentName>.tsx hook and updates AguiProvider.tsx to register both hooks — any custom edits you’ve made to the provider are preserved. main.tsx keeps its single <AguiProvider> wrapper — you never end up with nested providers.

    The following dependencies are added to the root package.json:

    • @copilotkit/react-core — ships CopilotKitProvider and chat components (CopilotChat, CopilotSidebar, CopilotPopup)
    • @ag-ui/clientHttpAgent used by the generated hooks
    • aws4fetch, oidc-client-ts, react-oidc-context, @aws-sdk/credential-providers — IAM auth only
    • react-oidc-context — Cognito auth

    Each useAgui<AgentName> hook reads its agent’s runtime value from Runtime Configuration and instantiates an @ag-ui/client HttpAgent:

    • Deployed: the runtime value is a Bedrock AgentCore Runtime ARN, which is converted to the AgentCore HTTPS endpoint: https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT
    • Local development: serve-local overrides the value to the agent’s local URL (e.g. http://localhost:8081)

    The shared AguiProvider calls every generated hook and spreads each one into selfManagedAgents on a single CopilotKitProvider, which exposes them all to CopilotKit components.

    CopilotKit is the 1st-party reference React client for the AG-UI protocol and ships ready-made chat components:

    • <CopilotChat /> — full chat interface
    • <CopilotSidebar /> — fixed side panel chat
    • <CopilotPopup /> — floating chat popup

    Place any of these anywhere inside the <AguiProvider> wrapper (already wired into main.tsx for you).

    The generated code handles authentication depending on your agent’s configuration:

    • IAM (default): uses AWS SigV4-signed HTTP requests. Credentials are obtained from the Cognito Identity Pool configured with your website’s auth.
    • Cognito: embeds the JWT access token in the Authorization header as a Bearer token.

    If your agent uses IAM auth, the Cognito Identity Pool’s authenticated role must be granted permission to invoke the agent.

    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 wires up all AgentCore invoke actions (InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream) on the agent’s runtime ARN.

    If your agent uses Cognito auth, you do not need to define any additional infrastructure to connect your website to your agent.

    Instantiate CopilotKit components with agentId to select which agent to use. The id is the agent’s name — the same one you chose when you ran the py#strands-agent generator — and you can also find it in the generated hook file (e.g. the key returned from packages/web/src/hooks/useAgui<AgentName>.tsx):

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

    Run the connection generator once per agent. Every agent registered via the shared AguiProvider is visible from anywhere in the app — instantiate a CopilotKit component with a different agentId to route each chat to the agent you want:

    <CopilotChat agentId="story" /> {/* talks to StoryAgent */}
    <CopilotChat agentId="research" /> {/* talks to ResearchAgent */}

    <CopilotChat /> (and <CopilotSidebar />, <CopilotPopup />) use a recursive slot system — you can override any sub-component with either a Tailwind class string, a prop object, or a custom React component. See the CopilotKit slots guide for the full slot tree.

    <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',
    }}
    />

    Any slot can take a React component instead of a className, so you can replace the default entirely:

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

    Deeper overrides follow the same shape — e.g. replace just the copy button on assistant messages:

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

    The connection generator automatically configures serve-local integration:

    1. Running nx serve-local <website> will also start the agent’s local server
    2. The runtime config is overridden to point to the local AG-UI URL (e.g. http://localhost:8081)
    3. Both the website and the agent hot-reload together
    Terminal window
    pnpm nx serve-local <WebsiteProject>