Skip to content

dsh-ego-browser

Verified

@dshworks/dsh-ego-browser · v0.1.0 · MIT

ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.

Install

dsh plugin add @dshworks/dsh-ego-browser

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Readme

    ___  __ _  ___
   / _ \/ _` |/ _ \    dsh-ego-browser
  |  __/ (_| | (_) |
   \___|\__, |\___/    ego lite for DeepSeek Harness,
        |___/          with a memory it keeps

给 dsh 浏览器 agent 的站点技能记忆。

7 个工具 · 用 ego lite 自己的 learnings/ 格式存 · 在 dsh 0.1.1-rc.2 上验证过 · 72 个测试,不需要浏览器 · 纯 host 插件 · MIT

CI MIT Node >= 20 verified against dsh 0.1.1-rc.2

它做什么 · 60 秒上手 · 凭据 · 什么时候别用 · 相关工作 · llms.txt · English


ego lite 是一个人和 agent 共用的浏览器:agent 在自己的 Space 里干活,复用你真实的登录态,你的标签页还是你的。这个插件把它接进 dsh —— 并补上 ego 自己 README 里仍标着「即将推出」的那一半。

*「Experience accumulation that makes your agent faster the more you use it (coming soon)」* —— ego lite README

读的那半边其实已经发布了:site.learnContextsite.runToolsite.runBrowserTool 会从 EGO_BROWSER_AGENT_WORKSPACE 指向的目录里加载 learnings/。缺的是的那半边。

  ego_recall  ──▶  ego_run  ──▶  ego_learn  ──▶  ego_site_run
   这个 agent      一次浏览器      把跑通的那       下次一次调用,
   已经学到的      任务写一段      一步固化         而不是重新摸
   关于该站点      脚本                             一遍页面
   的东西
                        │
                        └──▶  ego_handoff —— 页面需要真人时,
                              真的去问,然后再把控制权拿回来

闭环就成立了。第二次抓同一个后台时,agent 调的是它上周自己写的工具,而不是重新摸一遍页面。

它做什么

  • 动手前先回忆 —— ego_recall 直接从磁盘返回某个 hostname 的笔记与工具签名。不开浏览器、不加载页面、不花 token 重新摸索上个月已经跑通过的东西。
  • 一次任务一段脚本 —— ego_run 把整个浏览器任务交给 ego 运行时的一段脚本,这正是 ego 自己 benchmark 所依据的设计。
  • 把跑通的固化下来 —— ego_learn 把有效的一步变成真正的站点工具,用 ego 的格式存,并拒收那些活不到明天的。
  • 调用学过的东西 —— ego_site_run 按名字调用已存工具并计数,于是没人用的工具一眼可见。
  • 真的把键盘交给你 —— ego_handoff 弹出真正的 dsh Continue / Finish task 提示 —— 这正是 ego 自己的 hard-stop 文案在向 harness 要的东西 —— 你说继续,它才把控制权拿回来。
  • 告诉模型你装的是哪一代 ego —— ego_doctor 探测已安装的命令,而不是相信文档,因为同一个命令名后面有两套互不兼容的运行时。
  • 一开始就不是空的 —— 首次启动时,store 会继承你机器上已有 ego skill 的 learnings/

它怎么工作(30 秒)

  dsh agent
     │  ego_run / ego_site_run                    ego_recall / ego_learn
     ▼                                                      │
  ┌──────────────────────────────┐                          ▼
  │ dsh-ego-browser(host 半边) │              ┌──────────────────────────┐
  │  · argv 与 helper 表面探针   │              │ learnings/<site>/        │
  │  · 脚本包装与结果归类        │─────────────▶│   manifest.json          │
  │  · 晋升闸                    │    写入      │   notes/*.md             │
  └──────────────┬───────────────┘              │   tools/*.js             │
                 │ stdin heredoc                │   browser-tools/*.js     │
                 ▼                              └──────────┬───────────────┘
          `ego-browser`                                    │ EGO_BROWSER_
                 │                                         │ AGENT_WORKSPACE
                 ▼                                         ▼
          ego lite 应用  ◀────────── 同一份 store,ego 自己也读得回去
          (你的登录态,它自己的 Space)

唯一的那根线就是 ego lite 应用装的 ego-browser 命令。这里不内嵌、不打补丁、也不启动任何浏览器。

上手(60 秒)

需要运行 dsh 的机器上已安装并完成 ego lite 引导(lite.ego.app),使 ego-browser 在 PATH 上。

# 1. 安装 —— 构建产物已入库,不需要再构建
dsh plugin --profile web add -w github:dshworks/dsh-ego-browser

# 2. 重启 dsh

# 3. 确认装上了 —— 七个名字;如果是 [] 就是没装上
curl -s localhost:8090/dsh-ego-browser/memory | jq .tools

add 会顺手把 bundle 登记进 profile 花名册。然后让 agent 先跑一次 ego_doctor —— 它就是这样弄清楚该给你装的这一代 ego 写 cliLog() 还是 console.log() 的:

command: ego-browser   invoked as: ego-browser <<'JS'
ego runtime surface: facades (console.log / page / browser / taskSpaces); 7 helper names visible.
store: ~/.dsh/ego-browser/workspace (3 sites)
  github — github.com, *.github.com — 3 tool(s): search_repos (0x), get_open_issues (0x), get_repo_stats (0x)
  google — google.com, *.google.com, www.google.com — 2 tool(s): search_and_extract (0x), get_autocomplete_suggestions (0x)
  x-com — x.com, *.x.com, twitter.com, *.twitter.com — 3 tool(s): get_timeline_posts (0x), search_users (0x), post_from_active_element (0x)

agent 还没浏览任何东西,就已经有三个站点、八个工具 —— 这是 store 把 ego 自带的东西继承了过来。

凭据

在真实 dsh 上跑过(0.1.1-rc.2,把插件 link 进 profile 后启动):

声称 怎么验的
七个工具全部注册 GET /dsh-ego-browser/memory 会列出它们;tools 服务没到位时是 []
store 会自动继承 启动后带着 github(3 个工具)、google(2 个)、x-com(3 个),来自 ~/.claude/skills/ego-browser/learnings/
我们的校验器与 ego 的格式一致 对 ego 自带站点报出零问题 —— 这个方向的检查才有意义
路由有围栏 loopback 返回 200,Host 指向别处返回 403

对着真实构建出的 ego-browser bundle 和真实 subprocess 接缝:

声称 怎么验的
argv 探针能找到可用形状 在当前 CLI 上选中裸调用,在旧版上选中 nodejs;两种都失败时把两次输出都报出来
表面探针准确 对着真实 bundle 返回 facadepage, browser, taskSpaces, site, fetch, cdp, help —— 与其源码完全一致
出错也不丢输出 抛错不会吞掉抛错前打印的内容;顶层 return 依然产出判定
用户接管被识别为接管 而不是「结果丢了」—— 见一个命令名,两套运行时
晋升闸拦得住 快照 ref、错误 schema、缺失导出、无法解析的源码全部拒收,且不写入任何字节
npm install && npm test    # 72 个测试,不需要浏览器,约 2 秒

fixtures/ 里的 CLI 替身是从 ego 自己的源码逐条转写的 —— argv 处理来自 src/run.ts,输出 sink 来自 src/output-sink.ts,helper 表面来自 src/helpers.ts —— 每个文件头都写明了它跟的是上游哪个文件,因为比生产环境更弱的替身什么都测不出来。

没有验证的:所有需要真实浏览器的路径 —— 真的加载页面、真的任务空间、真的用户接管。ego lite 是 macOS 应用,而这份代码写在 Linux 容器里。通向它的那根线对着真实 CLI bundle 端到端跑过;线那头的东西没有。请先在真机上跑 ego_doctor,若与本页所写不符,请带上它的输出开 issue

让这份记忆值钱的那道闸

ego_learn 会拒绝含快照 ref 的代码:

this is not storable yet:
  - code contains a snapshot ref (@21 / ref=21). Those are rebuilt on every
    snapshotText() call and mean nothing on the next run — re-express the step
    with a stable locator (a CSS selector, or the loc=... value from the
    snapshot) before promoting it.

这就是「记忆」和「一堆死选择器」的全部差别。刚跑通的脚本里满是 @21,因为五秒前 agent 就是这么找到元素的。原样存下来等于什么都没存。这条规则是 ego 自己的 —— 它的校验器拒绝同一个模式 —— 在写入时就执行它,才能把「跑通过一次」变成「还能再跑」。

一个命令名,两套运行时

值得明说,因为任何人写 ego 集成都会碰上。

argv 形状不稳定。 已发布的 skill 写的是 ego-browser nodejs <<'EOF'citrolabs/ego-lite@main 里的 CLI 完全不接受 argv,多一个 nodejs 就打印用法并 exit 2;社区 Linux 移植则把 nodejs 当成空前缀吞掉。一个命令名,三种行为。

helper 表面同样不稳定。 一代装的是扁平全局量 —— cliLogsnapshotTextuseOrCreateTaskSpace;另一代装的是 Playwright 风格的 facade —— pagebrowsertaskSpacessite,并且用 console.log 取代了 cliLog。为其中一代写的脚本在另一代上直接 ReferenceError,而且靠文档解决不了:两份文档在各自的世界里都是对的。哪怕在 ego 自己仓库的 HEAD 上,SKILL.mdreferences/install.md 也互相矛盾。

所以这个插件不假设,它 —— 每次启动问一次,然后把答案交给模型。

还有:输出 sink 会吃掉你的结果。 用户把任务空间收回去时,ego 会标记 hard stop 并丢弃脚本打印的每一行,只留它自己的提示。任何从 stdout 里解析结果哨兵的集成,这时会什么都读不到,然后报一个「解析失败」。在这里,哨兵的缺席本身就是信号,这次运行会被正确归类:

hardStop: true —— 用户已接管该任务空间,ego 暂停了 agent。不要重试,也不要自行夺回控制权;
去问用户,等他们说继续之后用 ego_handoff 恢复。

什么时候用,什么时候别用

适合你,如果:你希望浏览器工作第二次做起来更便宜;你在 macOS 上装了 ego lite;你想让 agent 访问你已经登录的站点;或者你希望登录墙变成一个你能回答的提示框,而不是白白浪费一轮。

别用,如果:

  • 你想看着 agent 浏览。 这个插件没有观察窗。用 Fisfzy/dsh-ego-browser —— 可以直接点击操作的实时观察窗,外加一份 ego 运行时的 Linux 移植,没有 macOS 应用也能跑。
  • 你不在 macOS 上。 ego lite 目前只发 macOS。同样推荐上面那个。
  • 你想要细粒度的 click / fill / scroll 工具。 这是故意不做的:ego 自己的 benchmark 把速度归因于「一次任务一段脚本」,堆三十个小动词等于把这个优势花掉。如果你的模型 JavaScript 写得不好,细粒度设计更适合你。
  • 浏览器活儿你只做一次。 记忆才是重点。没有重复,它相对原版 ego-browser skill 只是额外开销。
  • 你要在 CI 里无头跑。 ego lite 是带真实 profile 的桌面应用。这时该用 Playwright 类插件。

七个工具

工具 作用
ego_run 在 ego 运行时里跑一段脚本。传 url 会先把该站点已学到的东西贴上来;传 taskSpace 会用正确的方言先开好任务空间。
ego_recall 某个 URL 的笔记与工具签名,直接读磁盘。
ego_site_run 按站点和名字调用已学会的工具,并记一次调用。
ego_learn 把跑通的一步固化成站点工具 —— 活不到明天的一律拒收。
ego_forget 删掉一个工具或整个站点。错的记忆比没有记忆更糟。
ego_handoff 交出浏览器,弹出真正的 Continue / Finish task,选 Continue 就把控制权拿回来。
ego_doctor 哪个 ego、哪种 argv、哪套 helper、store 在哪、里面有什么。
store 用的是 ego 的格式,不是我们的
<workspace>/learnings/<site-id>/manifest.json          id、name、domains、notes、tools
<workspace>/learnings/<site-id>/notes/*.md             agent 摸清楚的东西,用散文写
<workspace>/learnings/<site-id>/tools/*.js             node 工具:export async function f(ctx, args)
<workspace>/learnings/<site-id>/browser-tools/*.js     页面工具:在标签页里求值

这里学到的东西,在 dsh 之外的原版 ego-browser skill 里同样能加载,指向同一个 workspace 的其它 agent 也一样。没有私有格式,也没有需要迁出的东西。

首次启动时,如果找得到已有的 ego skill workspace,会把它的 learnings/ 继承过来一次。只继承一次;你删掉的站点不会自己回来。

一切都在写入前校验,被拒的晋升不会改动 store 分毫:manifest 形状、域名模式、参数与返回 schema、声明的导出,以及源码语法 —— 用 node --check进程外解析,绝不 import,因为那段代码是写给浏览器运行时的,没有理由在 harness 进程里执行。

随时读 store:

curl -s localhost:8090/dsh-ego-browser/memory | jq
配置

所有字段可选。

字段 默认 含义
bin ego-browser 命令。不在 PATH 上时填绝对路径。
workspace ~/.dsh/ego-browser/workspace 学到的站点存放处。指向已有的 ego skill 目录即可共用同一份 store。
seed true 首次启动时继承已有 ego workspace 的 learnings/
cwd harness cwd ego-browser 进程的工作目录。
extraArgs / env [] / {} 追加到每次调用。
timeoutMs 120000 单次脚本的时限。
probeTimeoutMs 20000 能力探针的时限。
maxOutputBytes 1048576 保留的脚本输出;超出保留尾部。
route true /dsh-ego-browser/memory 提供 store。
trustedHosts [] 除 loopback 外允许读该路由的 authority。

只有 subprocess 是硬依赖。toolswebServer 存在时才接管,所以 headless profile 也能干净加载,只是没有路由。

handoff 的完整流程

ego 自己的 hard-stop 文案,几乎是逐字在向 harness 要这个能力:

「Offer the user choices like "Continue" or "Finish task" if your harness supports it」

dsh 支持。ego_handoff 交出任务空间,弹出一个带这两个选项的真实 dsh 提问,选 Continue 后把控制权拿回来,下一次 ego_run 直接续上 —— 不用「你回一句 continue 我再试试」,也不会在用户还在输密码时把键盘抢走。

如果根本没人可问 —— headless、没有提问 UI,或者调用方是子 agent(harness 会用 DELEGATED_CALLER 拒绝而不是永远阻塞)—— 它会直说,而不是假装收到了答案。

相关工作

已经有两位先把 ego 接进了 dsh,两个都值得一看:

  • Fisfzy/dsh-ego-browser —— 32 个细粒度 ego_* 工具,外加一个可以直接点击操作的实时观察窗,并自带 ego 运行时的 Linux 移植,没有 macOS 应用也能跑。是真下了功夫的作品,对自身局限也很坦诚;如果你要的是看着 agent 浏览,选它。本插件不与之竞争,也不提供观察窗。
  • Da1dr1em/dsh-ego-browser —— 围绕 Windows 预览宿主的三个工具:run、help、status。能跑起来的最小诚实实现。

两者都没有往 learnings store 里写东西,也都没有把 ego 的 hard stop 变成真正的提示框。这个插件补的就是这块。

还有东西本身:ego liteCitroLabs 出品)才是这里的好点子 —— 人和 agent 共用一个浏览器,而不是用框架去驱动另一个。store 格式、临时 ref 规则、handoff 协议全是他们的;这个插件只是把它们填满。

贡献 · 安全 · 许可

CONTRIBUTING.md —— 哪些需要真实浏览器,哪些不需要。如果你手上有装了 ego lite 的 Mac,真机上的 ego_doctor 输出是你能提供的最有用的东西。

SECURITY.md —— agent 操作的是你真实的登录会话。安装前值得花两分钟看看。

MIT。ego lite 是独立发布的免费下载,遵循它自己的 MIT 许可;本仓库未内嵌其任何代码。与 DeepSeek、CitroLabs 均无关联。