`src/native-host.ts`
进程入口。负责 stdio 分帧、日志文件、每个 port 一个的 Runner
实例,以及登出 / 登录辅助逻辑。
Browy 的后端是一个小型 Node.js 进程,以原生消息主机的形式注册到
Chrome / Edge / Brave 上,应用 id 是 com.browy.host。它运行在你的
机器上。
┌───────────────────┐ 原生消息 ┌───────────────────┐ 子进程 ┌───────────────────┐│ 浏览器扩展 │ ◄───────────► │ Browy 主机 │ ◄───────────► │ GitHub Copilot ││ (侧边栏, │ port │ (Node,本文 │ │ CLI / SDK ││ devtools 面板) │ │ 介绍) │ │ (LLM 桥) │└───────────────────┘ └───────────────────┘ └───────────────────┘ │ ▼ ┌───────────────────┐ │ CDP 走 │ │ chrome.debugger │ │ (回到扩展里执行) │ └───────────────────┘扩展和主机之间通过一条双向、长度前缀的 JSON 通道通信(Chrome 的
原生消息协议)。智能体决定调用的每一个工具都会作为 tool_call 消息
返回给扩展;扩展执行它(通常通过 chrome.debugger + CDP),然后
回发一个 tool_result。
`src/native-host.ts`
进程入口。负责 stdio 分帧、日志文件、每个 port 一个的 Runner
实例,以及登出 / 登录辅助逻辑。
`src/agent/loop.ts`
智能体循环。调用 Copilot SDK(createSession / resumeSession),
把 prompt 和工具清单喂给它,把助手文字和 tool_call 事件流式
回传到扩展,把工具结果路由回 SDK。
`src/agent/tools/browser.ts`
浏览器工具登记表:大模型可以调用的每一个工具(snapshot、
click、type、network_log 等)。每个工具直接和它的 JSON
schema 一起声明,加上一个薄的 handler,把调用通过 port 转发给扩展。
`src/runner.ts`
按 port 的生命周期。每个连上的 port 一个 Runner(每个侧边栏 /
DevTools 面板一个)。拥有自己的 session id、模型、未完成的工具调用。
`src/transports/`
Stdio 分帧(stdio.ts)和测试桥,让同一个主机能在不需要 Chrome
的情况下跑单元测试。
`src/cli-bin.ts`
独立入口:browy 二进制。当前是安装 / 注册 / 反注册的 CLI。
{type: 'user', text, sessionId}。Runner 调用 sdk.resumeSession(sessionId, ...)(首次
调用是 createSession),带上消息和配置好的工具列表。{type: 'delta'})
和工具调用({type: 'tool_call'})实时转发给扩展。snapshot → chrome.debugger → CDP
Accessibility.getFullAXTree 等),然后发出
{type: 'tool_result', id, result}。{type: 'turn_done'}。整个交换在模型那一侧是同步的;在用户这一侧是实时流式的。
Browy 把会话存储委托给 GitHub Copilot CLI 自己的会话机制(在
~/.copilot/)。主机在扩展端(不在主机端)的 chrome.storage.local
里维护一份 extensionChatId → copilotSessionId 的映射,这样恢复
某一段对话时能命中正确的 Copilot 会话。
智能体自己也有几个临时面:
~/.browy/data/files/:沙箱化的文件临时空间,save_file /
read_file 智能体工具操作的就是这个目录~/.browy/data/notes.json:跨对话的持久键值记忆~/.browy/host/host.log:单文件循环 5 MB 日志工具定义在 src/agent/tools/browser.ts。每一个工具声明:
name、description、JSON-schema parameters(SDK 会消费)handler(input, ctx):在主机里运行,通常把调用通过
ctx.port.send({type: 'tool_call', …}) 转发给扩展,等待匹配的
tool_result 回复也就是说,每个浏览器工具的执行发生在扩展里(页面所在的地方), 不在主机里。主机是调度者,是连接大模型的桥。
src/agent/loop.ts 在每次连接时构造交给 SDK 的工具清单。今天它是
完整的浏览器工具列表;v0.1.2 起会按用户的
设置 → 工具开关过滤。
src/native-host.ts 把 console.* 重定向到单文件
~/.browy/host/host.log。文件大小超过约 5 MB 时轮转(重命名为
host.log.1,重开一个)。一次只保留一份轮转;下一次轮转会覆盖旧的。
会话出问题时这是第一个要看的地方。它装的是主机的诊断输出,不是 对话记录。