React から TypeScript Agent への接続
Nx Plugin for AWS は、TypeScript Agent を React ウェブサイトと素早く統合するためのジェネレーターを提供します。WebSocket 経由の tRPC を使用してエージェントに接続するために必要なすべての設定を行い、AWS IAM および Cognito 認証のサポートも含まれます。この統合により、フロントエンドとエージェントの tRPC ルーター間で完全なエンドツーエンドの型安全性が提供されます。
このジェネレーターを使用する前に、以下を確認してください:
- React ウェブサイト(
ts#websiteジェネレーターを使用して生成) - TypeScript Agent(
ts#agentジェネレーターを使用して生成) ts#website#authジェネレーターを介して追加された Cognito Auth
ジェネレーターの実行
Section titled “ジェネレーターの実行”pnpm nx g @aws/nx-plugin:connectionyarn nx g @aws/nx-plugin:connectionnpx nx g @aws/nx-plugin:connectionbunx nx g @aws/nx-plugin:connection- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - connection - 必須パラメータを入力
- クリック
Generate
React ウェブサイトをソースプロジェクトとして、Agent を含むプロジェクトをターゲットプロジェクトとして選択するよう求められます。ターゲットプロジェクトに複数のコンポーネント(複数のエージェントや他のコンポーネントタイプなど)が含まれている場合は、曖昧さを解消するために targetComponent を指定するよう求められます。
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
| sourceProject 必須 | string | - | ソース プロジェクト |
| targetProject 必須 | string | - | 接続先のターゲット プロジェクト |
| sourceComponent | string | - | 接続元のソース コンポーネント (コンポーネント名、ソース プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをソースとして明示的に選択するには '.' を使用します。 |
| targetComponent | string | - | 接続先のターゲット コンポーネント (コンポーネント名、ターゲット プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをターゲットとして明示的に選択するには '.' を使用します。 |
| preferInstallDependencies | boolean | true | ジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。 |
ジェネレーターの出力
Section titled “ジェネレーターの出力”ジェネレーターは、React アプリケーション内に以下の構造を作成します:
Directorysrc
Directorycomponents
- <AgentName>AgentClientProvider.tsx tRPC WebSocket クライアントとエージェントの tRPC ルーターへのバインディングを設定
- QueryClientProvider.tsx TanStack React Query クライアントプロバイダー
Directoryhooks
- useSigV4.tsx SigV4 でリクエストに署名するためのフック(IAM のみ)
- use<AgentName>Agent.tsx tRPC オプションプロキシとバニラ tRPC クライアントを返すフック
さらに、必要な依存関係がインストールされます:
@trpc/client@trpc/tanstack-react-query@tanstack/react-queryaws4fetch(IAM 認証を使用する場合)
WebSocket 接続
Section titled “WebSocket 接続”生成されたクライアントは、WebSocket 経由の tRPC を使用して Agent に接続します。エージェントは、WebSocket エンドポイント経由で tRPC ルーター(ストリーミングエージェントレスポンス用の invoke サブスクリプションを含む)を公開します。
- デプロイ時: エージェントランタイム ARN はランタイム設定から読み込まれます。この接続ジェネレーターを実行すると、エージェントの生成された CDK/Terraform コンストラクトにパッチが適用され、その ARN がウェブサイトの
runtime-config.json(connection名前空間の下)に公開されるため、明示的に接続したエージェントのみがフロントエンドに公開されます。ARN は、Bedrock AgentCore Runtime WebSocket プロトコルに従って WebSocket URL に変換されます:wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/ws - ローカル開発:
devで実行する場合、ランタイム設定のオーバーライドにより値がローカルのws://URL(例:ws://localhost:8081/ws)に設定され、クライアントは直接接続します
生成されたコードは、エージェントの設定に応じて認証を処理します:
- IAM(デフォルト): AWS SigV4 事前署名 URL を使用して WebSocket 接続を認証します。認証情報は、ウェブサイトの認証で設定された Cognito Identity Pool から取得されます。
devモードでは、runtime-config.jsonが存在しない場合、署名は自動的にスキップされます - Cognito: JWT アクセストークンを
Sec-WebSocket-Protocolヘッダーに base64url エンコードされたベアラートークンとして埋め込み、AgentCore WebSocket 認証プロトコルに従います
インフラストラクチャ
Section titled “インフラストラクチャ”エージェントが IAM 認証を使用する場合、Cognito Identity Pool の認証済みロールにエージェントを呼び出す権限を付与する必要があります。
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 は、エージェントのランタイム ARN 上のすべての AgentCore 呼び出しアクション(InvokeAgentRuntime、InvokeAgentRuntimeWithWebSocketStream)を接続します。
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}エージェントが Cognito 認証を使用する場合、ウェブサイトをエージェントに接続するための追加のインフラストラクチャを定義する必要はありません。
生成されたコードの使用
Section titled “生成されたコードの使用”TanStack Query の使用
Section titled “TanStack Query の使用”最も一般的な使用例は、use<AgentName>Agent フックを使用して invoke サブスクリプションでエージェントのレスポンスをストリーミングすることです。このフックは、TanStack Query で使用するための tRPC オプションプロキシを返します:
import { useSubscription } from '@trpc/tanstack-react-query';import { useMyAgentAgent } from './hooks/useMyAgentAgent';
function ChatComponent() { const trpc = useMyAgentAgent();
const subscription = useSubscription( trpc.invoke.subscriptionOptions( { prompt: 'What can you help me with?' }, { enabled: true, onStarted: () => { console.log('Agent started responding'); }, onData: (token) => { console.log('Received token:', token); }, onError: (error) => { console.error('Agent error:', error); }, }, ), );
return ( <div> <p>Status: {subscription.status}</p> {subscription.data && <p>Latest token: {subscription.data}</p>} {subscription.error && <p>Error: {subscription.error.message}</p>} </div> );}バニラ tRPC クライアントの使用
Section titled “バニラ tRPC クライアントの使用”use<AgentName>AgentClient フックは、サブスクリプションのライフサイクルをより細かく制御するための バニラ tRPC クライアントへのアクセスを提供します:
import { useState } from 'react';import { useMyAgentAgentClient } from './hooks/useMyAgentAgent';
function ChatComponent() { const client = useMyAgentAgentClient(); const [messages, setMessages] = useState<string[]>([]);
const sendMessage = (prompt: string) => { const subscription = client.invoke.subscribe( { prompt }, { onData: (token) => { setMessages((prev) => [...prev, token]); }, onComplete: () => { console.log('Agent finished'); }, onError: (error) => { console.error('Error:', error); }, }, );
// Clean up when done return () => subscription.unsubscribe(); };
return ( <div> <button onClick={() => sendMessage('Hello!')}>Send</button> <div> {messages.map((msg, i) => ( <span key={i}>{msg}</span> ))} </div> </div> );}ローカル開発
Section titled “ローカル開発”接続ジェネレーターは、React ウェブサイトの dev 統合を自動的に設定します:
nx dev <website>を実行すると、エージェントのローカルサーバーも起動します- ランタイム設定は、ローカルの WebSocket URL(例:
ws://localhost:8081/ws)を指すようにオーバーライドされます - 接続された API と同様に、
runtime-config.jsonが存在しない場合、devモードでは認証がスキップされます
この統合は、完全なエンドツーエンドの型安全性を提供します。IDE は、すべてのエージェントプロシージャ呼び出しに対して完全な自動補完と型チェックを提供します。型はエージェントの tRPC ルーター定義から自動的に推論されるため、エージェントの API への変更がフロントエンドコードに即座に反映されます。
詳細については、以下を参照してください: