news 2026/9/14 11:58:05

CopilotKit 预构建弹窗(CopilotPopup)验收指南:以 LlamaIndex 集成为例的 QA 全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CopilotKit 预构建弹窗(CopilotPopup)验收指南:以 LlamaIndex 集成为例的 QA 全流程解析

CopilotKit 预构建弹窗(CopilotPopup)验收指南:以 LlamaIndex 集成为例的 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

本文以 CopilotKit 仓库中 LlamaIndex 集成示例的 QA 验证清单 showcase/integrations/llamaindex/qa/prebuilt-popup.md 为主线,结合对应的 demo 页面、Playwright 端到端测试与后端 AG-UI Agent 实现,完整讲解预构建弹窗组件<CopilotPopup />的接入方式、关键配置项与可自动化的验收方法。读完本文,你将掌握如何验证一个浮动弹窗聊天组件是否正确挂载、默认展开、与后端 Agent 正常对话,以及如何把这一系列人工 QA 步骤改写成可重复执行的自动化测试。

一、QA 清单在项目中的定位

prebuilt-popup.md是 CopilotKit showcase 体系中按功能维度拆分的 QA 检查清单之一。在showcase/integrations/llamaindex/qa/目录下还并存着prebuilt-sidebar.mdagentic-chat.mdtool-rendering.md等同构清单,它们共同覆盖了该集成(LlamaIndex)在 CopilotKit 上支持的全部功能特性。

该清单的 4 个验收点分别为:

  • 导航到/demos/prebuilt-popup路由;
  • 验证浮动<CopilotPopup />启动器(launcher)可见;
  • 验证弹窗默认处于打开状态;
  • 发送"Say hi from the popup!"并验证 Agent 正常响应。

其中"导航到指定路由"是前提,后三点则分别对应弹窗组件的三个核心行为:挂载与呈现默认展开状态消息收发链路。这三个行为也正是清单对应功能(manifest.yaml 中 features 列表里登记的prebuilt-popup)在 prebuilt-popup.spec.ts 端到端测试中被逐一验证的对象。

二、第一步:确认 Demo 路由与页面挂载

清单要求先导航到/demos/prebuilt-popup。该路由的入口组件位于 showcase/integrations/llamaindex/src/app/demos/prebuilt-popup/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 ( // @region[popup-basic-setup] <CopilotKit runtimeUrl="/api/copilotkit" agent="prebuilt-popup"> <MainContent /> <CopilotPopup agentId="prebuilt-popup" defaultOpen={true} labels={{ chatInputPlaceholder: "Ask the popup anything...", }} /> <Suggestions /> </CopilotKit> // @endregion[popup-basic-setup] ); }

这段代码同时展示了预构建弹窗的最小可用接入模式,其中三个要点直接决定了 QA 清单能否通过:

  1. <CopilotKit>根组件:通过runtimeUrl指向同仓库下的 Next.js API 路由/api/copilotkit,并通过agent指定默认 Agent。
  2. <CopilotPopup />浮层agentId与 Provider 的agent保持一致;defaultOpen={true}决定首屏是否展开;labels.chatInputPlaceholder覆盖默认的输入占位文案。
  3. 页面正文与弹窗解耦<MainContent />渲染的是普通页面内容(见 main-content.tsx),弹窗作为浮动层叠加其上——这正是"popup 浮在页面上方、原有布局保持不变"的产品形态。

页面正文在 e2e 测试中承担"路由已挂载"的断言锚点:page.getByRole("heading", { name: "Popup demo" })必须可见,其文案与 main-content.tsx 中的<h1>Popup demo</h1>逐字对应。这意味着验收第一步的核心是确认路由渲染出预期页面骨架,而非仅仅不报错。

三、第二步:验证浮动启动器(Launcher)可见

清单的第二项是验证<CopilotPopup />的浮动 launcher 气泡可见。启动器是弹窗关闭时留在页面角落的圆形悬浮按钮,用于再次唤起聊天面板。

在 prebuilt-popup.spec.ts 中,launcher 通过稳定的测试标识符定位:

await expect( page.locator('[data-testid="copilot-chat-toggle"]').first(), ).toBeVisible();

copilot-chat-toggle是 CopilotPopup 内部渲染的开关按钮的data-testid,它在本仓库的整个预构建组件体系中是一致约定的定位锚点(prebuilt-sidebar等其他 demo 的 e2e 测试也采用同样的 testid 模式)。从实现结构看,启动器与弹窗内容属于同一组件的两个渲染状态:关闭时仅渲染启动器,打开时渲染启动器加聊天面板。该断言因此既验证了组件已挂载,也隐含验证了组件具备"可再次唤起"的能力。

四、第三步:验证默认展开(defaultOpen)

清单第三项要求弹窗默认打开。这一行为由页面上的defaultOpen={true}属性直接驱动。defaultOpen<CopilotPopup />首屏初始状态开关:为true时组件在首次渲染即展开聊天面板,为false(默认值)时则收起为角落的 launcher 气泡。

e2e 测试对该行为的验证方式非常值得借鉴——它没有直接断言组件状态,而是断言自定义占位文案可见

// defaultOpen={true} means the popup window is open on first paint. The // demo sets a custom placeholder via labels.chatInputPlaceholder — we // assert on that literal string to prove the popup rendered AND its // labels override took effect. await expect( page.getByPlaceholder("Ask the popup anything..."), ).toBeVisible();

由于输入框只存在于展开的聊天面板内部,"Ask the popup anything..."这个占位符可见,就等价于"面板已展开"。同时,这个断言还顺带验证了labels.chatInputPlaceholder自定义项生效——一举两得。这也提醒我们:QA 时选择"只在目标状态出现的唯一文案"作为断言依据,比直接断言布尔状态更稳健

补充一点与关闭行为相关的实现细节:测试注释明确说明"关闭时 CopilotPopupView 会卸载其内容(由其内部isRendered状态跟踪)",因此弹窗关闭的可靠信号是data-testid="copilot-popup"从 DOM 中消失,而非被 CSS 隐藏。测试随后通过点击copilot-chat-toggle重新唤起弹窗并断言copilot-popup再次可见,同时验证 URL 保持不变(/demos/prebuilt-popup$),证明展开/收起是纯客户端状态切换。

五、第四步:发送消息并验证 Agent 响应

清单最后一项要求发送"Say hi from the popup!"并验证 Agent 回复。这条消息其实来自 Demo 页面上注册的"建议气泡"(suggestion pill),而非手动输入。

5.1 建议气泡的注册方式

建议由 suggestions.ts 通过useConfigureSuggestions钩子注册,并由 suggestions-mount.tsx 挂载到页面:

"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", }); }

suggestions数组中的每一项包含显示用的title与发送用的messageavailable: "always"表示这些建议气泡始终可用(不限定在空聊天等特定状态下)。QA 清单中的消息"Say hi from the popup!"正是第一条建议{ title: "Say hi", message: "Say hi from the popup!" }message字段——人工 QA 时点击气泡即可发出该消息。

e2e 测试对建议气泡的定位是data-testid="copilot-suggestion"且文本包含"Say hi"

const sayHiPill = page .locator('[data-testid="copilot-suggestion"]') .filter({ hasText: "Say hi" }) .first(); await expect(sayHiPill).toBeVisible({ timeout: 15000 }); await sayHiPill.click();

点击后,测试断言data-testid="copilot-assistant-message"的助手消息可见(超时 45 秒,为后端 LLM 往返预留余量)。该测试还覆盖了另一条手动输入路径:向输入框fill("Hello")后点击copilot-send-button,同样断言收到助手回复。

5.2 消息如何到达 LlamaIndex Agent

消息从弹窗发出的完整链路如下:

  1. 浏览器将消息发送到runtimeUrl指向的 Next.js API 路由 showcase/integrations/llamaindex/src/app/api/copilotkit/route.ts;
  2. 路由通过createCopilotRuntimeHandler+new CopilotRuntime({ agents })建立 CopilotKit Runtime,并以 AG-UI 协议将请求代理到独立进程中的 LlamaIndex Agent 服务(默认http://localhost:8000);
  3. prebuilt-popup属于该路由注册的sharedAgentNames之一,其请求由agents表中的createAgent()(即new HttpAgent({ url: "${AGENT_URL}/run" }))转发到 Agent 服务的默认/run端点;
  4. LlamaIndex 侧由 src/agents/agent.py 构建的FixedAGUIChatWorkflow(使用OpenAI(model="gpt-4.1"))处理对话,回复经同一链路流式返回弹窗。

从源码结构看,prebuilt-popup与多数共享 demo 共用同一后端 Agent——per-demo 的行为差异主要由前端驱动(如本 demo 的建议气泡、labels定制、弹窗布局),而非各自独立的系统提示词。这一点在路由文件的注释中也有明确说明:// Shared-router agents — every id here resolves to the same backend + same tool set. Per-demo behavior is driven by the frontend.

Agent 的系统提示词要求"保持回复简洁(1 到 2 句话)",因此对"Say hi from the popup!"这类寒暄,预期响应是简短的自然语言文本。这也解释了为什么 QA 只验证"收到回复"而非"收到特定回复"——后端是无工具(no tools)的中性对话,重点是端到端链路贯通

六、把人工 QA 升级为自动化测试

人工按清单逐项点击验证,是发布前的最低保障;但同样的 4 个验收点在 prebuilt-popup.spec.ts 中已被固化为 4 个 Playwright 测试用例,构成一个可重复执行的回归屏障:

QA 清单项对应测试用例关键断言
导航到/demos/prebuilt-popuppage loads with heading and the popup open by defaultheading: "Popup demo"可见
launcher 可见同上copilot-chat-toggle可见
弹窗默认打开同上占位符Ask the popup anything...可见(data-testid="copilot-popup"亦可见)
发送消息并收到回复"Say hi" suggestion pill...typing a message and clicking send...copilot-assistant-message可见
(额外)关闭/重开popup close button unmounts...关闭后copilot-popup隐藏,点击 toggle 后再次可见,URL 不变

测试代码中还沉淀了两条宝贵的实战经验,值得在编写类似测试时复用:

  • cpk-web-inspector叠加层会拦截指针事件:在 localhost 开发环境下自动启用的cpk-web-inspector会拦截 Playwright 的基于指针的click(),因此关闭按钮的点击需通过page.evaluate(() => document.querySelector(...).click())以 JS 层点击绕过(注释中说明这与共享工具_genuine-shared.ts:clickByJs是同一模式)。
  • 输入框回车提交不稳定:测试注释指出"textarea 上的 Enter 提交在该部署上偶发丢失",因此提交消息统一点击copilot-send-button按钮,这是每个聊天输入区都稳定存在的提交入口。

七、排查建议

当任一 QA 步骤失败时,可按如下顺序定位(均以本仓库实际结构为依据):

  • 路由 404:确认页面位于 src/app/demos/prebuilt-popup/ 目录下,Next.js App Router 会据此生成/demos/prebuilt-popup路由。
  • launcher 不可见:确认<CopilotPopup />位于<CopilotKit>之内,且未设置会导致其隐藏的自定义样式;启动器的 testid 为copilot-chat-toggle
  • 弹窗未默认展开:检查defaultOpen是否显式设为true(默认值为false,即收起状态)。
  • Agent 无响应:先访问/api/copilotkitGET健康探针(其返回 JSON 中包含agent_urlagent_status,可用于确认后端http://localhost:8000是否可达、OPENAI_API_KEY是否已配置);确认 Provider 的agentCopilotPopupagentId一致(本 demo 均为prebuilt-popup),且该名称在 route.ts 的sharedAgentNamesspecializedAgents中已注册。需要逐请求排障时,可设置环境变量SHOWCASE_ROUTE_DEBUG=1开启该路由的详细日志。

八、小结

一个只有四行的 QA 清单,背后实际上覆盖了预构建弹窗组件完整的三层链路:前端组件挂载与初始状态defaultOpenlabels)、交互入口(launcher 气泡与 suggestion pill)、以及端到端消息收发(Next.js Runtime 代理 → AG-UI → LlamaIndex Agent)。本文对应的实现文件均可直接在仓库中对照阅读:demo 页面、建议气泡注册、后端 Agent 工作流、运行时代理路由与端到端测试。照此流程,你可以把任何一个预构建组件 demo 的人工验收,快速升级为可长期回归的自动化测试。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 11:58:05

安卓与嵌入式低功耗开发全栈解析:从PMIC寄存器到PowerHAL契约

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 11:56:59

UART通信实操指南:从电平波形到寄存器配置

1. 这不是“讲义”&#xff0c;而是一份UART通信的实操手记你打开开发板手册&#xff0c;第一页就写着“支持UART通信”&#xff1b;调试时串口助手一闪而过几行乱码&#xff1b;Linux下dmesg | grep tty突然冒出个ttyUSB0却连不上&#xff1b;用FT232R芯片焊好电路&#xff0c…

作者头像 李华
网站建设 2026/9/14 11:54:39

AI编曲5大技巧:从清唱到专业级音乐制作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 11:52:54

Coze Studio 知识库向量化如何配置 Embedding 模型与向量维度

Coze Studio 知识库向量化如何配置 Embedding 模型与向量维度 【免费下载链接】coze-studio An AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation…

作者头像 李华