React đến AG-UI Agent
Nx Plugin for AWS cung cấp một generator để kết nối một trang web React với Strands Agent sử dụng giao thức AG-UI. Nó kết nối CopilotKit với HttpAgent của @ag-ui/client trên trang web của bạn, hỗ trợ xác thực AWS IAM và Cognito.
Yêu cầu tiên quyết
Phần tiêu đề “Yêu cầu tiên quyết”Trước khi sử dụng generator này, hãy đảm bảo bạn có:
- Một trang web React (được tạo bằng generator
ts#react-website) - Một Python Strands Agent với
protocol=AG-UI(được tạo bằng generatorpy#strands-agent) - Đối với các agent đã triển khai, Cognito Auth được thêm vào thông qua generator
ts#react-website-auth
Cách sử dụng
Phần tiêu đề “Cách sử dụng”Chạy Generator
Phần tiêu đề “Chạy Generator”- Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
- Mở Nx Console trong VSCode
- Nhấp
Generate (UI)trong phần "Common Nx Commands" - Tìm kiếm
@aws/nx-plugin - connection - Điền các tham số bắt buộc
- Nhấp
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:connectionBạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
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-runBạn sẽ được nhắc chọn trang web React của mình làm dự án nguồn và dự án chứa AG-UI Strands Agent của bạn làm dự án đích. Nếu dự án đích của bạn chứa nhiều component (như nhiều agent hoặc các loại component khác), bạn sẽ được nhắc chỉ định targetComponent để phân biệt.
Tùy chọn
Phần tiêu đề “Tùy chọn”| Tham số | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
| sourceProject Bắt buộc | string | - | Dự án nguồn |
| targetProject Bắt buộc | string | - | Dự án đích để kết nối tới |
| sourceComponent | string | - | Component nguồn để kết nối từ đó (tên component, đường dẫn tương đối so với thư mục gốc của dự án nguồn, hoặc generator id). Sử dụng '.' để chọn rõ ràng dự án làm nguồn. |
| targetComponent | string | - | Component đích để kết nối tới (tên component, đường dẫn tương đối so với thư mục gốc của dự án đích, hoặc generator id). Sử dụng '.' để chọn rõ ràng dự án làm đích. |
Kết quả đầu ra của Generator
Phần tiêu đề “Kết quả đầu ra của Generator”Generator tạo ra một component AguiProvider được chia sẻ duy nhất, một hook cho mỗi agent được kết nối, và một wrapper có theme cho các component chat CopilotKit:
Thư mụcsrc
Thư mụccomponents
- AguiProvider.tsx
CopilotKitProviderduy nhất cho mọi AG-UI agent. Được tạo lần đầu tiên khi chạyconnectionvà được cập nhật trong các lần chạy tiếp theo để đăng ký mỗi agent mới. Thư mụccopilot
- index.tsx Re-export
CopilotChat,CopilotSidebarvàCopilotPopupvới các slot mặc định phù hợp vớiuxProvidercủa trang web (Cloudscape, Shadcn, hoặc không có theme). - ThemeComponents .tsx Các component theme cho từng slot (ví dụ:
CloudscapeAssistantMessage.tsx,ShadcnChatInput.tsx). Chỉ được cung cấp khiuxProviderlàCloudscapehoặcShadcn.
- index.tsx Re-export
- AguiProvider.tsx
Thư mụchooks
- useAgui<AgentName>.tsx Đăng ký một AG-UI agent. Một file cho mỗi lần chạy
connection. - useSigV4.tsx Ký SigV4 (chỉ IAM)
- useAgui<AgentName>.tsx Đăng ký một AG-UI agent. Một file cho mỗi lần chạy
Chạy connection lần thứ hai cho một agent khác sẽ thêm một hook useAgui<AgentName>.tsx mới và cập nhật AguiProvider.tsx để đăng ký cả hai hook — mọi chỉnh sửa tùy chỉnh bạn đã thực hiện đối với provider đều được bảo toàn. main.tsx giữ wrapper <AguiProvider> duy nhất của nó — bạn không bao giờ có các provider lồng nhau.
Các dependency sau được thêm vào package.json gốc:
@copilotkit/react-core— cung cấpCopilotKitProvidervà các component chat (CopilotChat,CopilotSidebar,CopilotPopup)@ag-ui/client—HttpAgentđược sử dụng bởi các hook được tạoaws4fetch,oidc-client-ts,react-oidc-context,@aws-sdk/credential-providers— chỉ xác thực IAMreact-oidc-context— xác thực Cognito
Cách hoạt động
Phần tiêu đề “Cách hoạt động”Kết nối AG-UI
Phần tiêu đề “Kết nối AG-UI”Mỗi hook useAgui<AgentName> đọc giá trị runtime của agent từ Runtime Configuration và khởi tạo một HttpAgent của @ag-ui/client:
- Đã triển khai: giá trị runtime là Bedrock AgentCore Runtime ARN, được chuyển đổi thành endpoint HTTPS của AgentCore:
https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT - Phát triển cục bộ:
serve-localghi đè giá trị thành URL cục bộ của agent (ví dụ:http://localhost:8081)
AguiProvider được chia sẻ gọi mọi hook được tạo và trải từng cái vào selfManagedAgents trên một CopilotKitProvider duy nhất, điều này hiển thị tất cả chúng cho các component CopilotKit.
Tích hợp CopilotKit
Phần tiêu đề “Tích hợp CopilotKit”CopilotKit là client React tham chiếu chính thức cho giao thức AG-UI và cung cấp sẵn các component chat:
<CopilotChat />— giao diện chat đầy đủ<CopilotSidebar />— chat bảng điều khiển bên cố định<CopilotPopup />— cửa sổ chat nổi
Đặt bất kỳ component nào trong số này ở bất kỳ đâu bên trong wrapper <AguiProvider> (đã được kết nối vào main.tsx cho bạn).
Xác thực
Phần tiêu đề “Xác thực”Mã được tạo xử lý xác thực tùy thuộc vào cấu hình agent của bạn:
- IAM (mặc định): sử dụng các yêu cầu HTTP được ký AWS SigV4. Thông tin xác thực được lấy từ Cognito Identity Pool được cấu hình với xác thực của trang web.
- Cognito: nhúng JWT access token vào header
Authorizationdưới dạng Bearer token.
Cơ sở hạ tầng
Phần tiêu đề “Cơ sở hạ tầng”Nếu agent của bạn sử dụng xác thực IAM, vai trò đã xác thực của Cognito Identity Pool phải được cấp quyền để gọi 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 kết nối tất cả các hành động gọi AgentCore (InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream) trên ARN runtime của 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}Nếu agent của bạn sử dụng xác thực Cognito, bạn không cần định nghĩa bất kỳ cơ sở hạ tầng bổ sung nào để kết nối trang web của bạn với agent.
Sử dụng mã được tạo
Phần tiêu đề “Sử dụng mã được tạo”Thêm giao diện Chat
Phần tiêu đề “Thêm giao diện Chat”Khởi tạo các component CopilotKit với agentId để chọn agent nào sẽ sử dụng. Id là tên của agent — tên mà bạn đã chọn khi chạy generator py#strands-agent — và bạn cũng có thể tìm thấy nó trong file hook được tạo (ví dụ: key được trả về từ packages/web/src/hooks/useAgui<AgentName>.tsx).
Import các component chat từ module ./components/copilot được tạo để theme phù hợp với uxProvider của trang web được áp dụng tự động:
import { CopilotChat } from './components/copilot';
function ChatPage() { return ( <CopilotChat agentId="agent" labels={{ welcomeMessageText: 'How can I help you today?', chatInputPlaceholder: 'Ask me anything...', }} /> );}Kết nối nhiều AG-UI Agent
Phần tiêu đề “Kết nối nhiều AG-UI Agent”Chạy generator connection một lần cho mỗi agent. Mọi agent được đăng ký thông qua AguiProvider được chia sẻ đều hiển thị từ bất kỳ đâu trong ứng dụng — khởi tạo một component CopilotKit với agentId khác nhau để định tuyến mỗi chat đến agent bạn muốn:
import { CopilotChat } from './components/copilot';
<CopilotChat agentId="story" /> {/* talks to StoryAgent */}<CopilotChat agentId="research" /> {/* talks to ResearchAgent */}Tùy chỉnh giao diện
Phần tiêu đề “Tùy chỉnh giao diện”<CopilotChat /> (và <CopilotSidebar />, <CopilotPopup />) sử dụng hệ thống slot đệ quy — bạn có thể ghi đè bất kỳ sub-component nào bằng chuỗi class Tailwind, đối tượng prop hoặc component React tùy chỉnh. Xem hướng dẫn slot CopilotKit để biết cây slot đầy đủ.
Theme tích hợp sẵn
Phần tiêu đề “Theme tích hợp sẵn”Generator đọc metadata.uxProvider từ dự án trang web React của bạn và cung cấp một module wrapper có theme tại src/components/copilot/index.tsx để các component chat phù hợp với phần còn lại của UI mà không cần cấu hình thêm:
uxProvider | Styling được áp dụng cho CopilotChat / CopilotSidebar / CopilotPopup |
|---|---|
Cloudscape | Tin nhắn được render bên trong các ChatBubble của Cloudscape với Avatar gen-AI (phù hợp với mẫu chat AI tạo sinh của Cloudscape); chỉ báo đang nhập trở thành LoadingBar và input là PromptInput. Được xây dựng từ @cloudscape-design/components và @cloudscape-design/chat-components. |
Shadcn | Tin nhắn trợ lý được render trong bong bóng bg-muted với avatar Sparkles; tin nhắn người dùng được render căn phải trong bong bóng bg-primary với avatar User. Input là Textarea bo tròn + Button gửi/dừng hình viên thuốc (Enter gửi, Shift+Enter xuống dòng). Sử dụng các primitive shadcn từ package common-shadcn được chia sẻ. |
None (hoặc bất kỳ giá trị nào khác) | Không có theme — module chỉ re-export các component CopilotKit mặc định. |
Import các component có theme từ module theme cục bộ (không phải trực tiếp từ @copilotkit/react-core/v2) để theme được áp dụng tự động:
import { CopilotChat } from './components/copilot';
<CopilotChat agentId="agent" />Theme được áp dụng dưới dạng các slot mặc định, vì vậy bất kỳ slot nào bạn truyền rõ ràng vẫn được ưu tiên — bạn vẫn giữ toàn quyền kiểm soát khi cần ghi đè một lần.
Tùy chỉnh Theme
Phần tiêu đề “Tùy chỉnh Theme”Theme được tạo nằm hoàn toàn bên trong dự án của bạn:
src/components/copilot/index.tsx— export cácCopilotChat/CopilotSidebar/CopilotPopupcó theme và các đối tượngcloudscapeCopilotTheme/shadcnCopilotTheme. Chỉnh sửa file này để thay đổi kết nối slot mặc định cho mọi chat trong ứng dụng.src/components/copilot/<ThemeComponent>.tsx— các component theme cho từng slot (ví dụ:CloudscapeAssistantMessage,ShadcnChatInput). Chỉnh sửa những file này để điều chỉnh giao diện của một slot đơn lẻ mà không cần kết nối lại theme.
Ví dụ, để thay thế renderer tin nhắn người dùng của riêng bạn trong khi giữ phần còn lại của theme, hãy chỉnh sửa file liên quan trong src/components/copilot/ và re-export nó từ index.tsx.
Tạo kiểu Tailwind thông qua slot
Phần tiêu đề “Tạo kiểu Tailwind thông qua slot”Các ghi đè cho từng chat vẫn hoạt động cùng với theme — bất cứ thứ gì bạn truyền dưới dạng slot prop sẽ ghi đè giá trị mặc định của theme:
<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', }}/>Thay thế slot bằng component tùy chỉnh
Phần tiêu đề “Thay thế slot bằng component tùy chỉnh”Bất kỳ slot nào cũng có thể nhận một component React thay vì className, vì vậy bạn có thể thay thế hoàn toàn mặc định:
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 }}/>;Ghi đè sâu hơn tuân theo cùng một hình dạng — ví dụ: chỉ thay thế nút sao chép trên tin nhắn trợ lý:
<CopilotChat agentId="agent" messageView={{ assistantMessage: { copyButton: ({ onClick }) => <button onClick={onClick}>Copy</button>, }, }}/>Phát triển cục bộ
Phần tiêu đề “Phát triển cục bộ”Generator kết nối tự động cấu hình tích hợp serve-local:
- Chạy
nx serve-local <website>cũng sẽ khởi động máy chủ cục bộ của agent - Cấu hình runtime được ghi đè để trỏ đến URL AG-UI cục bộ (ví dụ:
http://localhost:8081) - Cả trang web và agent đều hot-reload cùng nhau
pnpm nx serve-local <WebsiteProject>yarn nx serve-local <WebsiteProject>npx nx serve-local <WebsiteProject>bunx nx serve-local <WebsiteProject>