Mastra BrowserViewer 实战用 Playwright 托管 Chrome、CDP URL 与屏幕直播驱动 CLI 浏览器工具【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastramastra/browser-viewer是 Mastra 浏览器体系中的 CLI 型浏览器 Provider它用 Playwright 启动并全权管理一个 Chrome 实例对外暴露 Chrome DevTools ProtocolCDPWebSocket 地址供agent-browser、browser-use、browse等命令行工具作为次级客户端连接同时提供屏幕直播screencast、输入注入和线程级浏览器隔离能力。本文基于该包的 README、完整源码与仓库内参考文档展开读完后你可以独立配置一个 BrowserViewer 接入 Workspace、理解 CDP URL 的发现与注入机制并掌握thread/shared两种作用域、外部浏览器连接与直播流的实现细节。一、定位CLI 驱动的浏览器自动化在 Mastra 中Agent 驱动浏览器有两条路线通过 SDK 对象编程如AgentBrowser、Stagehand或通过命令行工具操作。BrowserViewer属于后者。源码顶部的注释直接说明了它的设计目标browser/browser-viewer.ts#L1-L12直接建立页面级 CDP 会话修复 screencast 的 sessionId 问题完整的浏览器生命周期控制可预测的 CDP URL便于注入到 CLI 命令线程Thread作用域的浏览器隔离。类定义在 browser/browser-viewer.ts#L49关键只读属性揭示了它的身份browser/browser-viewer.ts#L50-L59属性值 / 说明id构造时生成为browser-viewer-{timestamp}name固定为BrowserViewerprovider固定为browser-viewerproviderType固定为cli用于区别于 SDK 型 Providercli当前配置使用的 CLICLIProvider类型与 SDK 型 Provider 的一个本质区别是getTools()直接返回空对象browser/browser-viewer.ts#L406-L414。CLI Agent 不需要 SDK 工具它通过workspace_execute_command配合 skills 来驱动 CLI 命令Mastra 只负责浏览器侧的直播、输入注入与生命周期。完整的集成指南Workspace 快速上手、CLI 安装方式见仓库内文档 browser-viewer 集成文档API 级参考见 BrowserViewer 参考文档。二、安装与基础用法安装方式见 browser/browser-viewer/README.mdnpm install mastra/browser-viewer包元信息browser/browser-viewer/package.json当前版本0.2.3依赖playwright-core^1.61.1与typed-emitter对mastra/core的 peer 要求为1.26.0-0 2.0.0-0zod兼容^3.25.0 || ^4.0.0要求 Node.js22.13.0。README 给出的最简用法——独立启动浏览器并获取 CDP URLimport { BrowserViewer } from mastra/browser-viewer; const viewer new BrowserViewer({ cli: agent-browser, // Agent 将使用的 CLI headless: false, // 显示浏览器窗口 }); // 启动浏览器 await viewer.launch(); // 获取供 CLI 连接的 CDP URL const cdpUrl viewer.getCdpUrl(); console.log(cdpUrl); // ws://127.0.0.1:9222/devtools/browser/...典型的生产用法则是把BrowserViewer交给Workspace再挂到 Agent 上示例整理自 browser-viewer.ts#L36-L47 的 JSDoc 与仓库内集成文档import { Workspace, LocalSandbox } from mastra/core/workspace; import { BrowserViewer } from mastra/browser-viewer; const workspace new Workspace({ sandbox: new LocalSandbox({ workingDirectory: ./workspace }), browser: new BrowserViewer({ cli: browser-use, headless: false, }), });当 Agent 通过workspace_execute_command执行浏览器 CLI 命令时Mastra 会自动检测 CLI 命令 → 若浏览器未运行则通过 Playwright 启动 Chrome → 把 CDP URL 以正确的标志注入命令 → 开始向 Studio 推流 screencast。三、配置参数详解BrowserViewerConfig继承自 core 包的BrowserConfigBase再附加两个 CLI 专属字段browser-viewer/types.ts#L15-L29参数类型默认值说明cliagent-browser \| browser-use \| browse \| browse-cli必填Agent 使用的 CLICLI 通过 CDP URL 连接 ChromecdpPortnumber0自动分配可用端口Chrome 远程调试端口仅在自行启动 Chrome 时生效headlessbooleantrue是否无头运行测试 browser-viewer.test.ts#L46-L49 验证了默认值scopethread \| sharedthread提供cdpUrl时默认shared浏览器实例作用域详见第五节cdpUrlstring \| (() string \| Promisestring)-连接已存在的浏览器而非新启动一个viewport{ width, height } \| window{ width: 1280, height: 720 }视口尺寸window表示不做视口模拟、跟随真实窗口executablePathstringPlaywright 自带 Chromium自定义 Chrome 可执行文件路径timeoutnumber10000浏览器操作默认超时毫秒onLaunch/onClose生命周期回调-浏览器就绪 / 关闭前触发screencastScreencastOptions-直播流参数格式、质量、尺寸基础字段的定义与约束在 packages/core/src/browser/browser.ts#L233-L307。其中两个值得注意的约束cdpUrl与scope: thread互斥——线程隔离需要为每个线程启动独立浏览器进程连接已有浏览器时做不到。构造器中的处理逻辑印证了这一点browser-viewer.ts#L64-L76// 提供 cdpUrl 时 scope 默认 shared否则默认 thread const effectiveScope config.cdpUrl ? (config.scope ?? shared) : (config.scope ?? thread);构造时 CLI 专属字段cli、cdpPort会被剔除后再传入基类browser-viewer.ts#L71因为基类BrowserConfig是判别联合不识别这些字段。四、核心机制Playwright 托管 Chrome 与 CDP URL 发现真正的启动逻辑在 thread-manager.ts 的launchBrowser中thread-manager.ts#L182-L290调用链如下chromium.launchServer(...)以--remote-debugging-port${cdpPort}、--no-first-run、--no-default-browser-check参数启动 Chrome 进程。端口默认0由操作系统自动分配discoverCdpUrl(browserServer)从 Chrome 的DevToolsActivePort文件中发现真实的 CDP WebSocket 地址thread-manager.ts#L433-L484。该文件第一行是端口号、第二行是/devtools/browser/guid路径拼出形如ws://127.0.0.1:52481/devtools/browser/abc...的 URL 供外部 CLI 连接。由于 Chrome 启动初期可能仍在写文件这里做了最长 1500ms 的重试轮询chromium.connect(browserServer.wsEndpoint())Playwright 自身也连接该浏览器用于 screencast 与会话管理browser.newContext(...)创建上下文并打开初始页面。注意视口处理thread-manager.ts#L217-L222viewport: window时传null给 Playwright语义正是“禁用模拟、跟随真实窗口”context.newCDPSession(page)为活动页面建立 CDP 会话供 screencast 和输入注入使用。此外还有一个可靠性增强通过browser.newBrowserCDPSession()打开Target.setDiscoverTargets监听Target.targetDestroyedthread-manager.ts#L249-L280。当页面级 CDP 看不到全局事件时CLI 会自己创建页面浏览器级会话能观察到所有 target 的销毁一旦剩余页面 target 归零即判定浏览器已关闭。五、作用域模型thread与sharedBrowserViewerThreadManager支持两种会话组织方式thread-manager.ts#L48-L64thread默认每个线程一个独立 Chrome 进程。threadSessions是一个threadId - BrowserViewerSession的 Map懒创建——线程首次调用ensureReady()/launch(threadId)时才启动browser-viewer.ts#L157-L199。适合并行 Agent 需要互相隔离的浏览器状态shared所有线程共享单个 Chrome。doLaunch()中走createSharedSession()一次性启动browser-viewer.ts#L122-L135。getCdpUrl(threadId?)按作用域路由到对应会话的cdpUrlbrowser-viewer.ts#L114-L116。线程隔离的会话状态查询、活动页解析resolveActivePage取最近打开的页面与断连清理逻辑均在该 thread-manager 中实现关闭入口为closeAll()thread-manager.ts#L655-L665。六、连接已有浏览器cdpUrl与connectToExternalCdpBrowserViewer 有两种“不自己启动浏览器”的路径构造时提供cdpUrl可以是字符串或异步函数。doLaunch()解析 URL 后走connectToExisting→createSharedSessionFromCdpbrowser-viewer.ts#L126-L130内部用chromium.connectOverCDP(cdpUrl)建立连接thread-manager.ts#L568-L594。此时会话的browserServer为null表示进程不归本包所有清理时不会杀掉外部浏览器运行时调用connectToExternalCdp(cdpUrl, threadId?)browser-viewer.ts#L210-L225适用于 Agent 使用自己的外部浏览器端点例如云端浏览器服务Mastra 仅连接以启用 screencast不管理其生命周期。实现上它会先关闭该线程的既有会话避免泄漏浏览器进程thread-manager.ts#L551-L562。用法示例// 连接本地已开启远程调试的 Chrome const viewer new BrowserViewer({ cli: browser-use, cdpUrl: ws://127.0.0.1:9222/devtools/browser/abc123, }); // 或运行中接入外部端点 await viewer.connectToExternalCdp(wss://cloud.example.com/session, thread-123);七、屏幕直播与输入注入startScreencaststartScreencast(options?)browser-viewer.ts#L279-L382返回一个ScreencastStream。默认直播参数写死在源码中format: jpeg、quality: 80、maxWidth: 1280、maxHeight: 720、everyNthFrame: 1。其设计要点是CDP 会话按需提供且不缓存CdpSessionProvider.getCdpSession每次调用都通过createFreshCdpSession(threadId)为当前活动页面新建 CDP 会话browser-viewer.ts#L282-L306。源码注释解释原因——CDP 会话是页面作用域的tab 切换后必须重新附着到当前页面而不是启动时的初始页面。配套的 tab 切换处理会监听 context 的page事件与每个页面的close/framenavigated事件在 100ms 延迟后自动stream.reconnect()并在流停止时统一解绑监听器browser-viewer.ts#L317-L378。injectMouseEvent / injectKeyboardEventStudio 的实时交互通过 CDP 的Input.dispatchMouseEvent/Input.dispatchKeyEvent实现browser-viewer.ts#L388-L404await viewer.injectMouseEvent({ type: mousePressed, x: 100, y: 200, button: left }); await viewer.injectKeyboardEvent({ type: keyDown, key: Enter, code: Enter });底层getCdpSessionForThread带了一个按pageUrl判定的缓存thread-manager.ts#L329-L370同一活动页复用会话页面 URL 变化或页面关闭则重建若创建会话失败页面已在获取与创建之间关闭会触发断连清理流程。八、支持的 CLI 与 CDP 注入方式CLIProvider类型定义支持四种取值browser-viewer/types.ts#L10。各 CLI 需在 workspace 环境中单独安装并各自发布一个 skill 教会 Agent 其命令与工作流。根据仓库内集成/参考文档集成文档、参考文档cli取值安装CDP 注入方式agent-browsernpm install -g agent-browsernpx skills add vercel-labs/agent-browser--cdp标志browser-usepip install browser-usenpx skills add browser-use/browser-use --skill browser-use直接 stdin 调用browser-use/browseruse/browser/bu时设置BU_CDP_WS与线程隔离的BU_NAME环境变量遗留子命令保留--cdp-url与--session注入browse/browse-clinpm install -g browsebrowse skills install--ws标志当 CLI 命令经workspace_execute_command执行时Mastra 按cli配置自动选择正确的注入方式无需 Agent 手写连接参数。仓库内的 browser/agent-browser 包则是 SDK 型 Provider供对比二者分工明确BrowserViewer管 Chrome 与 CDPCLI 工具执行具体的浏览操作。九、行为验证从测试用例看契约包内测试browser-viewer/src/tests/browser-viewer.test.ts覆盖了几个关键契约无浏览器运行时getBrowserState()与getCurrentUrl()均返回null而非抛错getBrowserState(thread-1)会透传线程 ID 给底层的按线程状态查询headless默认true显式传false时生效对应 README 中headless: false显示浏览器窗口的用法cli同时支持现值browse与遗留值browse-cli。getBrowserStateForThread返回{ tabs, activeTabIndex }其中activeTabIndex取最后一个页面最近打开者与 thread-manager 中resolveActivePage的取页策略保持一致browser-viewer.ts#L235-L254。十、仓库文件索引路径内容browser/browser-viewer/README.md包 README本文主文档browser/browser-viewer/src/browser-viewer.tsBrowserViewer主类生命周期、CDP、screencast、输入注入browser/browser-viewer/src/thread-manager.ts线程会话管理、Chrome 启动与 CDP URL 发现browser/browser-viewer/src/types.tsCLIProvider与BrowserViewerConfig类型browser/browser-viewer/src/tests/browser-viewer.test.ts行为测试browser/browser-viewer/package.json版本、依赖与引擎要求docs/src/content/en/integrations/browsers/browser-viewer.mdx集成指南Quickstart、CLI 安装docs/src/content/en/reference/browser/browser-viewer.mdx完整 API 参考参数表、方法签名packages/core/src/browser/browser.ts基类BrowserConfigBase配置约束【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考