콘텐츠로 이동

React에서 AG-UI 에이전트로

Nx Plugin for AWS는 AG-UI 프로토콜을 노출하는 Strands Agent에 React 웹사이트를 연결하는 생성기를 제공합니다. 이는 AWS IAM 및 Cognito 인증 지원과 함께 웹사이트의 @ag-ui/client HttpAgentCopilotKit을 연결합니다.

이 생성기를 사용하기 전에 다음을 준비해야 합니다:

  1. React 웹사이트 (ts#react-website 생성기를 사용하여 생성)
  2. protocol=AG-UI를 사용하는 Python Strands Agent (py#strands-agent 생성기를 사용하여 생성)
  3. 배포된 에이전트의 경우, ts#react-website-auth 생성기를 통해 추가된 Cognito Auth
  1. 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
  2. VSCode에서 Nx 콘솔 열기
  3. 클릭 Generate (UI) "Common Nx Commands" 섹션에서
  4. 검색 @aws/nx-plugin - connection
  5. 필수 매개변수 입력
    • 클릭 Generate

    소스 프로젝트로 React 웹사이트를, 타겟 프로젝트로 AG-UI Strands Agent가 포함된 프로젝트를 선택하라는 메시지가 표시됩니다. 타겟 프로젝트에 여러 컴포넌트(여러 에이전트 또는 다른 컴포넌트 유형 등)가 포함된 경우, 명확히 구분하기 위해 targetComponent를 지정하라는 메시지가 표시됩니다.

    매개변수 타입 기본값 설명
    sourceProject 필수 string - 소스 프로젝트
    targetProject 필수 string - 연결할 대상 프로젝트
    sourceComponent string - 연결을 시작할 소스 컴포넌트 (컴포넌트 이름, 소스 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 소스로 명시적으로 선택하려면 '.'을 사용하세요.
    targetComponent string - 연결할 대상 컴포넌트 (컴포넌트 이름, 대상 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 대상으로 명시적으로 선택하려면 '.'을 사용하세요.

    생성기는 단일 공유 AguiProvider 컴포넌트, 연결된 에이전트당 하나의 훅, 그리고 CopilotKit 채팅 컴포넌트를 위한 테마가 적용된 래퍼를 생성합니다:

    • 디렉터리src
      • 디렉터리components
        • AguiProvider.tsx 모든 AG-UI 에이전트를 위한 단일 CopilotKitProvider. 첫 번째 connection 실행 시 생성되고 후속 실행 시 각 새 에이전트를 등록하도록 업데이트됩니다.
        • 디렉터리copilot
          • index.tsx 웹사이트의 uxProvider(Cloudscape, Shadcn 또는 테마 없음)와 일치하는 슬롯 기본값으로 CopilotChat, CopilotSidebar, CopilotPopup을 재내보냅니다.
          • ThemeComponents .tsx 슬롯별 테마 컴포넌트(예: CloudscapeAssistantMessage.tsx, ShadcnChatInput.tsx). uxProviderCloudscape 또는 Shadcn일 때만 제공됩니다.
      • 디렉터리hooks
        • useAgui<AgentName>.tsx 하나의 AG-UI 에이전트를 등록합니다. connection 실행당 하나의 파일.
        • useSigV4.tsx SigV4 서명 (IAM 전용)

    다른 에이전트에 대해 connection을 두 번째로 실행하면 새로운 useAgui<AgentName>.tsx 훅이 추가되고 AguiProvider.tsx가 두 훅을 모두 등록하도록 업데이트됩니다 — 프로바이더에 대한 사용자 정의 편집 내용은 보존됩니다. main.tsx는 단일 <AguiProvider> 래퍼를 유지하므로 중첩된 프로바이더가 생기지 않습니다.

    다음 종속성이 루트 package.json에 추가됩니다:

    • @copilotkit/react-coreCopilotKitProvider와 채팅 컴포넌트(CopilotChat, CopilotSidebar, CopilotPopup)를 제공합니다
    • @ag-ui/client — 생성된 훅에서 사용하는 HttpAgent
    • aws4fetch, oidc-client-ts, react-oidc-context, @aws-sdk/credential-providers — IAM 인증 전용
    • react-oidc-context — Cognito 인증

    useAgui<AgentName> 훅은 런타임 구성에서 에이전트의 런타임 값을 읽고 @ag-ui/client HttpAgent를 인스턴스화합니다:

    • 배포됨: 런타임 값은 Bedrock AgentCore Runtime ARN이며, AgentCore HTTPS 엔드포인트로 변환됩니다: https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT
    • 로컬 개발: serve-local이 값을 에이전트의 로컬 URL(예: http://localhost:8081)로 재정의합니다

    공유 AguiProvider는 생성된 모든 훅을 호출하고 각각을 단일 CopilotKitProviderselfManagedAgents에 전개하여 모든 에이전트를 CopilotKit 컴포넌트에 노출합니다.

    CopilotKit은 AG-UI 프로토콜을 위한 1차 참조 React 클라이언트이며 즉시 사용 가능한 채팅 컴포넌트를 제공합니다:

    • <CopilotChat /> — 전체 채팅 인터페이스
    • <CopilotSidebar /> — 고정 사이드 패널 채팅
    • <CopilotPopup /> — 플로팅 채팅 팝업

    이들 중 하나를 <AguiProvider> 래퍼 내부 어디에나 배치하세요(이미 main.tsx에 연결되어 있습니다).

    생성된 코드는 에이전트의 구성에 따라 인증을 처리합니다:

    • IAM (기본값): AWS SigV4 서명된 HTTP 요청을 사용합니다. 자격 증명은 웹사이트의 인증과 함께 구성된 Cognito Identity Pool에서 가져옵니다.
    • Cognito: JWT 액세스 토큰을 Bearer 토큰으로 Authorization 헤더에 포함합니다.

    에이전트가 IAM 인증을 사용하는 경우, Cognito Identity Pool의 인증된 역할에 에이전트를 호출할 수 있는 권한을 부여해야 합니다.

    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는 에이전트의 런타임 ARN에 대한 모든 AgentCore 호출 작업(InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream)을 연결합니다.

    에이전트가 Cognito 인증을 사용하는 경우, 웹사이트를 에이전트에 연결하기 위해 추가 인프라를 정의할 필요가 없습니다.

    agentId와 함께 CopilotKit 컴포넌트를 인스턴스화하여 사용할 에이전트를 선택합니다. id는 에이전트의 이름입니다 — py#strands-agent 생성기를 실행할 때 선택한 것과 동일하며 — 생성된 훅 파일에서도 찾을 수 있습니다(예: packages/web/src/hooks/useAgui<AgentName>.tsx에서 반환된 키).

    웹사이트의 uxProvider와 일치하는 테마가 자동으로 적용되도록 생성된 ./components/copilot 모듈에서 채팅 컴포넌트를 임포트합니다:

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

    에이전트당 한 번씩 connection 생성기를 실행합니다. 공유 AguiProvider를 통해 등록된 모든 에이전트는 앱의 어디에서나 볼 수 있습니다 — 다른 agentId로 CopilotKit 컴포넌트를 인스턴스화하여 각 채팅을 원하는 에이전트로 라우팅합니다:

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

    <CopilotChat /> (그리고 <CopilotSidebar />, <CopilotPopup />)는 재귀적 슬롯 시스템을 사용합니다 — Tailwind 클래스 문자열, prop 객체 또는 사용자 정의 React 컴포넌트로 하위 컴포넌트를 재정의할 수 있습니다. 전체 슬롯 트리는 CopilotKit 슬롯 가이드를 참조하세요.

    생성기는 React 웹사이트 프로젝트에서 metadata.uxProvider를 읽고 src/components/copilot/index.tsx에 테마가 적용된 래퍼 모듈을 제공하여 추가 구성 없이 채팅 컴포넌트가 나머지 UI와 일치하도록 합니다:

    uxProviderCopilotChat / CopilotSidebar / CopilotPopup에 적용되는 스타일
    Cloudscape메시지가 gen-AI Avatar를 포함한 Cloudscape ChatBubble 내부에 렌더링됩니다(Cloudscape 생성형 AI 채팅 패턴과 일치); 타이핑 인디케이터는 LoadingBar가 되고 입력은 PromptInput입니다. @cloudscape-design/components@cloudscape-design/chat-components로 구축됩니다.
    Shadcn어시스턴트 메시지는 Sparkles 아바타와 함께 bg-muted 버블로 렌더링되고, 사용자 메시지는 User 아바타와 함께 bg-primary 버블에 오른쪽 정렬로 렌더링됩니다. 입력은 둥근 Textarea + 알약 모양의 전송/중지 Button입니다(Enter는 제출, Shift+Enter는 줄바꿈). 공유 common-shadcn 패키지의 shadcn 프리미티브를 사용합니다.
    None (또는 기타)테마 없음 — 모듈은 단순히 기본 CopilotKit 컴포넌트를 재내보냅니다.

    테마가 자동으로 적용되도록 로컬 테마 모듈에서 테마가 적용된 컴포넌트를 임포트합니다(@copilotkit/react-core/v2에서 직접 임포트하지 않음):

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

    테마는 슬롯 기본값으로 적용되므로 명시적으로 전달하는 슬롯은 여전히 우선합니다 — 일회성 재정의가 필요할 때마다 완전한 제어권을 유지합니다.

    생성된 테마는 완전히 프로젝트 내부에 있습니다:

    • src/components/copilot/index.tsx — 테마가 적용된 CopilotChat / CopilotSidebar / CopilotPopupcloudscapeCopilotTheme / shadcnCopilotTheme 객체를 내보냅니다. 이 파일을 편집하여 앱의 모든 채팅에 대한 기본 슬롯 연결을 변경합니다.
    • src/components/copilot/<ThemeComponent>.tsx — 슬롯별 테마 컴포넌트(예: CloudscapeAssistantMessage, ShadcnChatInput). 이들을 편집하여 테마를 재연결하지 않고 단일 슬롯의 모양을 조정합니다.

    예를 들어, 나머지 테마를 유지하면서 자체 사용자 메시지 렌더러를 삽입하려면 src/components/copilot/의 관련 파일을 편집하고 index.tsx에서 재내보냅니다.

    채팅별 재정의는 테마와 함께 여전히 작동합니다 — 슬롯 prop으로 전달하는 모든 것이 테마 기본값을 재정의합니다:

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

    사용자 정의 컴포넌트로 슬롯 교체

    섹션 제목: “사용자 정의 컴포넌트로 슬롯 교체”

    모든 슬롯은 className 대신 React 컴포넌트를 받을 수 있으므로 기본값을 완전히 교체할 수 있습니다:

    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 }}
    />;

    더 깊은 재정의도 동일한 형태를 따릅니다 — 예를 들어 어시스턴트 메시지의 복사 버튼만 교체:

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

    연결 생성기는 자동으로 serve-local 통합을 구성합니다:

    1. nx serve-local <website>를 실행하면 에이전트의 로컬 서버도 시작됩니다
    2. 런타임 구성이 로컬 AG-UI URL(예: http://localhost:8081)을 가리키도록 재정의됩니다
    3. 웹사이트와 에이전트가 함께 핫 리로드됩니다
    Terminal window
    pnpm nx serve-local <WebsiteProject>