AG2 集成中的 CopilotKit 预构建弹窗(Pre-Built Popup)QA 验证指南与实现解析
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
导读
本文围绕 AG2 集成仓库中的prebuilt-popup质量验证(QA)检查清单,系统讲解 CopilotKit v2 预构建弹窗组件<CopilotPopup />的接入方式、配置要点与验收标准。你将掌握如何在 Next.js 应用中通过runtimeUrl+agentId挂载浮动弹窗聊天界面、如何用defaultOpen、labels控制其行为与文案,以及如何结合仓库自带的端到端(E2E)测试与 AG2 后端路由,完成从“页面可见”到“Agent 回复”的完整回归验证。
一、QA 清单在验证什么:从需求到验收
QA 文档 prebuilt-popup.md 定义的检查路径只有 5 步,却覆盖了弹窗组件三个核心行为维度:
- 路由可达性:
Navigate to /demos/prebuilt-popup——页面必须能正常挂载; - 默认打开态:
Popup opens by default——首次渲染即应展示弹窗内容,而非仅显示角落的启动气泡; - 消息往返:
Send "Say hi from the popup"并Verify agent responds——用户输入(或点击建议词)后,Agent 的回复必须出现在弹窗内部。
对应的 Expected Results 只有两条:Popup opens as overlay(以浮层形式打开)与Agent replies inside the popup window(回复渲染在弹窗窗口内)。这组最小验收标准的关键在于:弹窗是“叠加在既有布局之上”的浮层,页面本身的布局在其下层保持不变。
二、Demo 页面结构:三行核心代码挂载弹窗
该演示的前端实现位于 page.tsx,完整的页面组装如下:
"use client"; import React from "react"; import { CopilotKit, CopilotPopup } from "@copilotkit/react-core/v2"; import { MainContent } from "./main-content"; import { Suggestions } from "./suggestions-mount"; export default function PrebuiltPopupDemo() { return ( <CopilotKit runtimeUrl="/api/copilotkit" agent="prebuilt-popup"> <MainContent /> <CopilotPopup agentId="prebuilt-popup" defaultOpen={true} labels={{ chatInputPlaceholder: "Ask the popup anything...", }} /> <Suggestions /> </CopilotKit> ); }拆解这三层结构:
<CopilotKit>:顶层 Provider,runtimeUrl指向本仓库的运行时路由/api/copilotkit,agent指定默认 Agent 名称。所有子组件(弹窗、建议词)共享这一上下文;<CopilotPopup>:预构建弹窗组件。agentId="prebuilt-popup"与顶层agent对应,负责把弹窗会话绑定到同一个后端 Agent;defaultOpen={true}声明默认打开;labels用于覆写内置文案;<Suggestions>:建议词挂载点(详情见第四节)。
页面正文 main-content.tsx 只是一个普通的居中内容区(标题 “Popup demo” 与说明文字),没有任何弹窗相关的布局代码——这正是“预构建”的含义:浮动启动器(launcher bubble)与聊天浮层完全由CopilotPopup自行渲染在角落,既有页面布局保持原样。
三、组件实现级解析:defaultOpen、labels 与受控模式
CopilotPopup的源码位于 CopilotPopup.tsx,其完整 props 类型为:
| Props | 类型 | 作用 |
|---|---|---|
agentId | string | 会话绑定的 Agent 标识 |
defaultOpen | boolean | 非受控模式下弹窗的初始开关状态,true表示首次渲染即打开 |
open/onOpenChange | boolean / (open: boolean) => void | 受控模式。传入open后,弹窗完全由宿主决定开合,自身不再改状态,需配合onOpenChange响应开关请求 |
header | ReactNode | 自定义弹窗头部 |
toggleButton | ReactNode | 自定义角落启动气泡 |
width/height | string | number | 弹窗尺寸,默认由样式系统提供 |
clickOutsideToClose | boolean | 点击外部是否关闭 |
| 其余 | CopilotChatProps | 透传给内部CopilotChat的聊天配置,含labels、welcomeScreen等 |
三个值得注意的实现细节:
1. labels 覆写 placeholder。演示页传入labels.chatInputPlaceholder: "Ask the popup anything...",QA 与 E2E 测试正是用这个自定义占位文案来证明“弹窗确实渲染了、且文案覆写生效”的(测试断言见 prebuilt-popup.spec.ts)。
2. 弹窗外壳通过 Context 传递。源码中PopupViewOverride组件刻意保持“身份稳定”(stable identity):width/height 这类随拖拽变化的 props 通过PopupShellPropsContext下发,而不是直接作为覆盖组件的依赖。原因在源码注释中写得很清楚——若尺寸变化导致覆盖组件“换身份”,React 会卸载并重挂载整个聊天子树,使滚动位置归零并触发initial="smooth"的可见滚动动画(见 CopilotPopup.tsx)。
3. 许可证检查。组件内部通过checkFeature("popup")校验许可,未授权时渲染InlineFeatureWarning并在控制台输出警告(CopilotPopup.tsx),不影响功能调试,但部署前需确认许可配置。
四、建议词:useConfigureSuggestions 让 QA 用例可一键触发
QA 清单中的Send "Say hi from the popup"除了可以手动输入,也能通过建议词一键触发。建议词定义在 suggestions.ts:
"use client"; import { useConfigureSuggestions } from "@copilotkit/react-core/v2"; export function usePrebuiltPopupSuggestions() { useConfigureSuggestions({ suggestions: [ { title: "Say hi", message: "Say hi from the popup!" }, { title: "Limerick", message: "Write me a quick limerick." }, { title: "Is 17 prime?", message: "Walk me through whether 17 is prime." }, ], available: "always", }); }title是气泡上显示的文字,message是点击后实际发送给 Agent 的消息;available: "always"表示建议词在会话的任何阶段都可用;- 挂载组件 suggestions-mount.tsx 仅调用该 hook 并返回
null,是一个纯逻辑挂载点。
注意:点击 “Say hi” 发送的实际消息是"Say hi from the popup!",与 QA 清单的措辞略有出入,但语义一致,E2E 测试即按此实际消息断言(见下节)。
五、后端接线:共享 AG2 Agent 与运行时路由
弹窗本身不包含任何 AI 逻辑,它只是前端外壳,真正的对话能力来自后端。本仓库采用“前端变体复用共享后端”的模式,这在 PARITY_NOTES.md 中明确记录:prebuilt-popup属于 Batch 1 前端变体,复用同一个 agent.py 中的ConversableAgent(经AGUIStream包装),与prebuilt-sidebar、chat-slots等共享同一后端进程。
请求链路由 route.ts 承担:
const AGENT_URL = process.env.AGENT_URL || "http://localhost:8000"; function createAgent(path = "/") { return new HttpAgent({ url: `${AGENT_URL}${path}` }); } // 前端变体统一注册到共享 Agent const sharedAgentNames = [ "agentic_chat", // ... "prebuilt-sidebar", "prebuilt-popup", // ... ];关键事实:
- Agent 后端是独立进程(默认
http://localhost:8000,可用AGENT_URL环境变量覆写),本路由通过 AG-UI 协议的HttpAgent代理 CopilotKit 请求; prebuilt-popup被注册进sharedAgentNames,最终与defaultAgent 一样指向根路径/的同一个ConversableAgent;- 运行时以
single-route模式挂载在basePath: "/api/copilotkit",恰好与页面runtimeUrl对齐; - 调试开关
SHOWCASE_ROUTE_DEBUG=1可开启逐请求日志;GET /api/copilotkit提供健康探针,返回agent_url与agent_status,可用于排查“弹窗打开但 Agent 无回复”的问题。
此外,manifest.yaml 中登记了该演示的元信息(demo idprebuilt-popup、名称 “Pre-Built: Popup”、描述 “Floating popup chat via<CopilotPopup />”、路由/demos/prebuilt-popup),并标注高亮文件为src/agents/agent.py、page.tsx、route.ts,与本文分析路径一致。
六、从 QA 清单到自动化验收:E2E 测试逐条对应
QA 文档的 5 个步骤在 prebuilt-popup.spec.ts 中被完整固化为 4 个 Playwright 用例,可作为“QA 清单落地为自动化”的范例:
| QA 步骤 | E2E 断言 | 关键选择器 |
|---|---|---|
| 路由可达 | 标题 “Popup demo” 可见(L12-L14) | page.getByRole("heading") |
| 弹窗默认打开 | 自定义 placeholder 可见,证明弹窗已渲染且 labels 覆写生效(L20-L22) | data-testid="copilot-popup"、placeholder |
| 浮动启动器可见 | 切换按钮存在(L25-L27) | data-testid="copilot-chat-toggle" |
| 发送 “Say hi” 且 Agent 回复 | 点击建议词气泡后,助理消息可见(L34-L45) | data-testid="copilot-suggestion"/copilot-assistant-message |
| 手动输入发送 | 输入 “Hello” 并点击发送按钮后消息可见(L51-L63) | data-testid="copilot-send-button" |
| 关闭与重开 | 关闭后弹窗隐藏、点启动器重新挂载、URL 不变(L66-L92) | data-testid="copilot-close-button" |
测试注释中还有两条值得记录的工程经验:一是“Enter 键提交在此部署环境中偶发失效,发送按钮是稳定可靠的提交触发点”;二是本地开发时自动启用的<cpk-web-inspector>覆盖层会拦截 Playwright 的指针点击,因此关闭弹窗改用 JS 级.click()绕过覆盖层(见 L72-L83)。这意味着在本地跑 E2E 或手动 QA 时,若点击被覆盖层拦截,应优先检查 web-inspector 是否开启。
七、手动 QA 执行清单(可直接使用)
结合 QA 文档与仓库实现,完整的手动验收步骤为:
- 启动 AG2 后端(
http://localhost:8000,默认端口可用AGENT_URL调整)与 Next.js 前端; - 访问
/demos/prebuilt-popup,确认标题 “Popup demo” 正常渲染; - 确认页面角落出现浮动启动器气泡(QA 第 2 步),且弹窗已默认展开为浮层(QA 第 3 步,因
defaultOpen={true}),页面上层布局未被打乱; - 在输入框输入或点击 “Say hi” 建议词,实际发送消息
"Say hi from the popup!"; - 确认弹窗内部出现 Assistant 回复气泡(QA 第 5 步 + Expected Results 第 2 条);
- 可选回归项:点击关闭按钮,弹窗收起但启动器仍在;再次点击启动器,弹窗重新挂载,URL 保持
/demos/prebuilt-popup不变(纯客户端状态切换)。
若第 5 步 Agent 无回复,优先检查GET /api/copilotkit健康探针返回的agent_status是否为reachable,以及是否设置OPENAI_API_KEY(探针会返回env.OPENAI_API_KEY的 set/NOT SET 状态)。
八、小结
prebuilt-popup演示展示了 CopilotKit 预构建弹窗的完整闭环:<CopilotKit>+<CopilotPopup>两个组件即完成前端浮层接入,useConfigureSuggestions提供可一键触发的 QA 消息,运行时路由经 AG-UI 协议代理到共享的 AG2ConversableAgent。QA 文档的 5 步清单覆盖了“挂载、默认态、消息往返”三个验收维度,而仓库中的 E2E 测试与组件源码则进一步揭示了defaultOpen、labels、受控模式open/onOpenChange、Context 传递外壳 props 等实现级细节——理解这些,你便能在自己的 AG2 应用中快速复现同样的弹窗聊天体验,并建立可自动化的质量验收基线。
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考