前端架构
RTC Agent 的前端是一个基于 Lit Web Components 构建的组件库。对外只暴露一个 <rtc-agent> 组件,内部包含 57 个子组件,使用 23 个 Controller 管理状态,通过 @lit/context 向子组件分发数据。

文件浏览器:左侧为虚拟文件系统目录树(functions/、scenarios/、scripts/),右侧为编辑器 + 实时预览。所有文件数据存储在浏览器 IndexedDB 中。

设置界面:支持主题切换、语言选择、字体大小调整等个性化配置。
新增组件一览
Section titled “新增组件一览”| 组件 | 用途 | 替换关系 |
|---|---|---|
rtc-chat-layout | 两栏聊天布局(会话树 + 内容区) | 替代旧版 rtc-content-wrapper |
rtc-session-tree | VS Code 风格会话树侧栏 | 新增 |
rtc-session-tree-item | 树节点(递归渲染) | 新增 |
rtc-session-tab-bar | 浏览器风格标签栏 | 新增 |
rtc-session-tab | 单个标签页 | 新增 |
rtc-settings-panel | 设置侧抽屉面板 | 新增 |
rtc-settings-layout | 设置两栏布局 | 新增 |
rtc-settings-nav | 设置分类导航 | 新增 |
rtc-file-preview-area | 附件预览区(水平滚动缩略图列表) | 新增 |
rtc-file-thumbnail | 文件缩略图(上传进度、删除、预览) | 新增 |
rtc-file-preview-modal | 文件全屏预览弹窗(图片/文本) | 新增 |
宿主应用只需引入一个组件即可使用全部功能:
| 属性 | 说明 | 示例 |
|---|---|---|
theme | 主题切换 | light / dark / system |
lang | 界面语言 | zh-CN / en-US |
app-label | 标题栏文字 + 气泡 tooltip | "RTC 助手" |
database-name | IndexedDB 名称前缀 | "my-app-rtc" |
server-url | 服务端地址 | "https://rtc.example.com" |
redirect-uri | OAuth 回调地址 | "/auth/callback.html" |
bubble-icon | 最小化气泡内的 SVG/HTML | 自定义图标 |
logo | 自定义品牌 Logo(light/dark 两套) | { light: '<svg>...', dark: '<svg>...' } |
worker-url | SharedWorker 文件 URL | "/rtc-agent/shared-worker.js" |
scenarios-url | 场景文档 URL | "https://..." |
agentConfig | 声明式函数注册(推荐) | JSON 配置对象 |
详细 API 说明见 Component API。
新增 Controller
Section titled “新增 Controller”| Controller | Context | 说明 |
|---|---|---|
SessionTreeController | SessionTreeContext | 管理会话树结构、展开/折叠状态 |
NotificationController | NotificationContext | 管理通知状态、音效、焦点检测 |
SettingsController | SettingsContext | 管理全局设置、localStorage 持久化 |
此外,还有以下辅助模块:
| 模块 | 说明 |
|---|---|
LocaleController / i18n | 国际化支持,运行时语言切换 |
SessionTabController | 管理标签页状态(SessionTabContext) |
ToastController | 管理 Toast 通知展示 |
| 原则 | 说明 |
|---|---|
| Controller 不互相引用 | 每个 Controller 独立管理自己的状态切片 |
| 根组件编排 | <rtc-agent> 作为中枢,协调跨 Controller 通信 |
| Context 分发 | 通过 @lit/context 向子组件分发状态,避免 prop drilling |
| 数据层隔离 | Persistence Controller 统一管理 IndexedDB 读写 |
💡 为什么不用全局状态? Web Components 运行在宿主应用的页面中,可能有多个实例。例如一个页面同时嵌入”客服助手”和”数据分析助手”两个
<rtc-agent>,它们需要各自独立的会话、消息、认证状态。Controller + Context 保证每个实例的状态完全隔离,互不干扰。
文件存储(FileStorage)
Section titled “文件存储(FileStorage)”RTC Agent 内置了离线优先的文件存储系统,通过 FileStorageContext 向子组件分发 FileStorage 实例。所有文件操作都先写入本地 IndexedDB 缓存,再后台同步到 S3,保证离线场景下的可用性。
FileStorage 核心 API:
| 方法 | 说明 |
|---|---|
cacheFileForUpload(file) | 缓存文件到本地 IndexedDB,计算 MD5,返回 FileInfo(含 md5、ext、size) |
upload(options) | 上传文件到 S3,支持 onProgress 回调,返回 FileInfo(含 syncStatus) |
download(md5, ext, options?) | 下载文件,优先从本地缓存读取,缓存未命中时从 S3 下载 |
getThumbnailUrl(identifier) | 获取图片缩略图 URL(返回 blob URL,需调用 releaseThumbnailUrl() 释放) |
getPresignedUrl(identifier, expires) | 获取 S3 预签名 URL(用于降级场景) |
list(filter?) | 列出文件,支持分页和过滤 |
delete(identifier) | 删除文件(同时删除本地缓存和 S3) |
getCacheStats() | 获取缓存统计信息(文件数、占用空间) |
离线优先特性:
- 文件上传先写入本地缓存(
syncStatus: 'pending'),缩略图立即可显示 - 网络恢复后,后台自动同步到 S3(
syncStatus: 'synced') - 下载优先读取本地缓存,缓存未命中时才请求 S3
- 支持中断恢复:
resumeInterruptedUploads()恢复未完成的上传任务
| 交互 | 实现 |
|---|---|
| 拖拽 | title-bar 作为拖拽手柄 |
| 缩放 | 四角 + 四边共 8 个缩放手柄 |
| 键盘 | 方向键移动,Shift 加速 |
| 视口约束 | 始终保持在可视区域内 |
| 层级 | 内容 | 自定义方式 |
|---|---|---|
| Design Tokens | 间距、字体、圆角、阴影、过渡、z-index | 覆盖 CSS 变量 |
| 颜色主题 | light / dark 两套配色 | theme 属性切换 |
| CSS 变量 | 窗口尺寸、气泡大小 | --rtc-* 前缀变量 |
文件上传流程:
- 触发方式:点击附件按钮打开文件选择器,或使用
Ctrl+V/Cmd+V粘贴剪贴板中的文件 - 本地缓存:文件先写入本地 IndexedDB 缓存(
FileStorage.cacheFileForUpload()),生成真实的fileid(md5.ext格式) - 即时预览:缩略图立即显示(
rtc-file-thumbnail从 FileStorage 缓存加载),无需等待 S3 上传 - 后台上传:后台调用
FileStorage.upload()上传到 S3,实时显示上传进度(0-100%) - 状态管理:每个文件有三种状态 ——
loading(上传中)、loaded(成功)、error(失败) - 重试机制:上传失败的文件显示重试按钮,点击后重新上传
- 发送条件:所有文件上传完成后,发送按钮才可用;发送时文件列表随消息一起提交
| 特性 | 行为 |
|---|---|
| 自动滚动 | 新消息到达时自动滚动到底部 |
| 智能暂停 | 用户手动上滑时暂停自动滚动 |
| 新消息提示 | 用户离开底部时显示”新消息”按钮 |
| 渲染 | Markdown 渲染 + 代码高亮 |
工具确认弹窗
Section titled “工具确认弹窗”用户输入 / 开头的文本时,触发命令输入模式:
| 命令 | 类型 | 功能 |
|---|---|---|
/compact | RPC | 手动触发上下文压缩 |
/loop | 本地 + RPC | 循环执行任务(定时 / 动态) |
/goal | Prompt | 目标驱动,AI 设置完成条件,Judge 模型检查 |
详见 命令系统。
测试与质量保障
Section titled “测试与质量保障”前端工程采用多层测试策略,覆盖单元测试、集成测试与端到端测试,确保组件行为正确、跨模块协作稳定。
测试基础设施
Section titled “测试基础设施”| 工具 | 用途 | 配置位置 |
|---|---|---|
| Vitest | 单元测试 & 集成测试 | packages/*/vitest.config.ts |
| Playwright | 端到端测试 (E2E) | packages/component/playwright.config.ts |
| jsdom | 浏览器 API 模拟(Vitest 环境) | test-setup.ts 中 polyfill IndexedDB、matchMedia、ResizeObserver 等 |
| fake-indexeddb | IndexedDB 纯 JS 实现,供 Dexie 在测试中使用 | test-setup.ts 自动导入 |
| 包 | 单元测试文件数 | 说明 |
|---|---|---|
@rtc-agent/component | 62 | 覆盖所有 Controller、组件、工厂函数、事件系统、认证流程 |
@rtc-agent/persistence | 12 | 覆盖 IndexedDB 操作、实体仓库、事务、偏移管理器、脚本引擎 |
@rtc-agent/client | 1 | 覆盖 WebSocket 客户端、偏移同步、gap-fill 逻辑 |
@rtc-agent/worker | 1 | 覆盖 SharedWorker 核心消息路由 |
| E2E (Playwright) | 6 | 覆盖调试 API、业务流程、高级交互、文档协调、脚本执行 |
当前共计 835+ 单元测试用例,全部通过。
# 运行所有单元测试(在 web-components 根目录)pnpm test
# 仅运行 component 包的单元测试pnpm --filter @rtc-agent/component test
# 运行 E2E 测试(需要 Vite 开发服务器)pnpm --filter @rtc-agent/component test:e2e
# 运行特定测试文件npx vitest run packages/component/src/controllers/auth.controller.test.ts
# 监听模式(开发时推荐)npx vitest测试辅助工具
Section titled “测试辅助工具”packages/component/src/test-helpers.ts 提供测试基础设施:
| 工具 | 说明 |
|---|---|
fixture(template, options?) | 创建 Lit 组件测试夹具,自动等待更新周期完成 |
nextFrame() | 等待一帧,确保 Lit 完成渲染 |
cleanupFixtures() | 清理所有已创建的测试夹具,防止测试间污染 |
provideContext() | 在 setup 阶段注入 @lit/context,确保组件首次更新前上下文就绪 |
E2E 测试调试 API
Section titled “E2E 测试调试 API”E2E 测试依赖调试页面 (/debug/index.html) 暴露的 window.rtcAgentDebug API。该 API 在开发模式下自动安装,提供以下能力:
| 方法 | 说明 |
|---|---|
waitForReady(timeout?) | 等待 <rtc-agent> 组件就绪 |
sendMessage(text) | 发送消息 |
getSessionController() | 获取会话控制器 |
getActions(controller) | 获取指定控制器的 actions |
CI 流水线
Section titled “CI 流水线”GitHub Actions CI 在每次 push/PR 时自动执行:
pnpm install → pnpm build → pnpm typecheck → pnpm testNode.js 版本:24。测试在 ubuntu-latest 环境运行。
性能与无障碍
Section titled “性能与无障碍”| 场景 | 策略 |
|---|---|
| 大消息列表 | 消息分页加载(cursor pagination),首次加载最近 50 条 |
| 长对话滚动 | 虚拟滚动优化(未来版本) |
| Markdown 渲染 | 按需渲染,代码高亮延迟加载 |
| IndexedDB 读写 | Persistence Controller 统一管理,批量操作减少 IO |
| 特性 | 实现 |
|---|---|
| 键盘导航 | Tab 键切换焦点,Enter 激活,Esc 关闭弹窗 |
| ARIA 标签 | 所有交互元素添加 aria-label |
| 屏幕阅读器 | 消息列表使用 role="log",新消息自动播报 |
| 高对比度 | 支持系统高对比度模式 |
- 后端架构 — 了解 Go 服务端的分层设计
- 架构总览 — 返回架构全景
- Remote Tool Calling — 了解前端工具调用的核心协议
- 虚拟文件系统 — 了解前端 IndexedDB 文件系统
- 命令系统 — 了解完整的命令系统