基于 Midscene 的 AI UI 自动化——android_ui 与 web_ui 工具,通过 ctx.midscene seam 在真实 Android 设备或已运行的 Chrome 上完成点击、输入、查询与断言。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-plugin-midscene
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:ciky20171114/dsh-plugin-midscene
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
English | 中文
为 DeepSeek Harness(DSH)提供基于 Midscene 的 AI 驱动 UI 自动化。模型看得到屏幕、用自然语言描述定位元素、对真实目标执行操作——一台真实的 Android 设备或一个真实的 Chrome 浏览器。
一个能力 seam(ctx.midscene)、两个 Provider、两个工具:
| Provider 入口 | 工具 | 目标 | |
|---|---|---|---|
| Android | dsh-plugin-midscene/android |
android_ui |
一台 ADB 连接的设备 |
| Web | dsh-plugin-midscene/web |
web_ui |
一台已经在运行的 Chrome 的活动页面 |
每个工具都是带 action 参数的单工具(与 str_replace_editor 同风格):模型选择一个动作(tap / act / input / query / assert / boolean / back),工具在内部自行分发——不撑大工具面。
前置条件
- DSH(
dshCLI)及一个 profile - Android:
adb devices能看到设备 - Web:Chrome 以
--remote-debugging-port=9222 --user-data-dir=<目录>启动;Provider 只连接、绝不启动浏览器 - 一个 Midscene 兼容的视觉模型,通过环境变量配置(见模型配置)
安装
dsh plugin --profile mysetup add dsh-plugin-midscene
bundle 的默认层注册两个工具。工具以机会主义方式读取 ctx.midscene,所以即使还没配置 provider 工具也已出现——此时调用会以一条指明缺失 provider 行的错误失败。
然后向 profile 的 cordis.patch.yml(~/.dsh/profiles/mysetup/cordis.patch.yml)加恰好一个 provider 行(两个 provider 不能在同一个 context 里同时拥有 ctx.midscene):
Android
- insert:
- id: midscene-android
name: dsh-plugin-midscene/android
config:
deviceId: '' # 留空:选择 getConnectedDevices() 的第一台
aiActionContext: '' # 供 aiAct 规划使用的自由文本上下文,例如应用约定
Web
- insert:
- id: midscene-web
name: dsh-plugin-midscene/web
config:
browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser/<id>'
aiActionContext: ''
可直接粘贴的 provider 行见 examples/。
从 http://127.0.0.1:9222/json/version 的 webSocketDebuggerUrl 取端点。注意该 Chrome 每次重启后 id 都会变——更新此行并重启 dsh。
销毁时 provider 会销毁自己的 agent,然后对浏览器执行 disconnect() —— 绝不 close():Chrome 进程属于你的部署,继续运行。
启动:
dsh --profile mysetup # 若 3080 被占用,加 --port 3081
安装排错
dsh plugin add 报 ERR_PNPM_IGNORED_BUILDS,点名 sharp / @ffmpeg-installer/linux-x64:pnpm ≥ 10 会拦截这些传递依赖的安装脚本(来自 @midscene/*),直到显式声明。处理:打开 ~/.dsh/profiles/<name>/pnpm-workspace.yaml,把 pnpm 列在 allowBuilds 下的键设为 false(插件没有它们也能工作——仅当你要 sharp/ffmpeg 二进制做真机截图/录屏时才设 true),然后重新执行 add。每个 profile 只需一次。
工具参考
android_ui 与 web_ui 共享同一形状:
action |
其余参数 | 结果 |
|---|---|---|
tap |
prompt(元素描述) |
ack |
act |
prompt(目标描述) |
ack + agent 自身的结果文本(若有) |
input |
prompt(元素)+ value(要输入的文本) |
ack |
query |
demand(要提取什么) |
提取出的 JSON |
assert |
prompt(断言)+ 可选 msg |
pass/fail + 可选思考过程 |
boolean |
prompt(是/否问题) |
true/false |
back |
— | ack(Android:系统返回;Web:历史返回) |
schema 无法表达的跨字段规则(如 input 必须有 value、query 必须有 demand)在 execute 中以指名道姓的错误消息强制执行。断言失败是一次成功的 pass: false 结果——错误路径只留给基础设施故障(设备消失、websocket 拒绝)。
模型配置
Midscene 的视觉模型通过 @midscene/* 自身的约定配置——环境变量,而非 DSH 的 ctx.llm:
export MIDSCENE_MODEL_NAME=glm-4.6v
export MIDSCENE_MODEL_BASE_URL=https://open.bigmodel.cn/api/paas/v4/
export MIDSCENE_MODEL_API_KEY=<你的key>
export MIDSCENE_MODEL_FAMILY=glm-v
(任何 OpenAI 兼容的多模态端点都可以——设置对应变量即可。)
设计边界:不含策略、不含恢复
Provider 是刻意的薄传输层:无重试、无前置条件检查、无对意外 UI 状态的自动恢复(意外弹窗、非预期跳转、重新登录)。有这类需求的调用方在其上自行构建——例如每次写操作前检查应用状态的约束/harness 层。
已知限制
- 每个 provider 实例一个目标 —— 每个 context 一台设备或一台浏览器;扇出需要隔离的组合。
- 不重连 —— 会话中途断开表现为一次被拒绝的调用。
- 锁定 SDK 版本 ——
@midscene/android/@midscene/web精确锁定在1.11.0;升级是一次刻意的版本 bump。 puppeteer是 peer(web)—— 由部署方的 pnpm 解析;Chrome 本身由部署方提供,本插件绝不下载。
开发
git clone https://github.com/ciky20171114/dsh-plugin-midscene
cd dsh-plugin-midscene
pnpm install # 原生/浏览器安装脚本默认被拒绝;测试 mock 掉 SDK
pnpm test # 只测接线:mock 的 @midscene/*、puppeteer,真实工具注册表背后的 stub seam
pnpm build # tsc 输出到 lib/(git 安装时作为 `prepare` 运行)
目录结构:
src/service.ts MidsceneService 定义 —— ctx.midscene seam(7 个操作)
src/android.ts Android provider(AndroidDevice + AndroidAgent,ADB)
src/web.ts Web provider(puppeteer.connect + PuppeteerBrowserAgent,只连接)
src/tool.ts android_ui + web_ui 工具(一份共享定义,action 分支)
tests/ 31 个接线测试 —— 绝不碰真机或真浏览器
开发时把本地 checkout 装进 profile:
dsh plugin --profile dev add /path/to/dsh-plugin-midscene
社区与支持
欢迎通过 GitHub Discussions 提交反馈或 bug 报告。本仓库携带 dsh-plugin topic 以便被检索到。
许可证
MIT
链接
同类插件
Tencent/WeKnora#dsh-weknora★ 32192
把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己带引用的 RAG 或 ReAct agent 回答(含可续聊的 session id)。
superdesigndev/treg★ 4192
给 Agent 的工具目录:按「要做的事」检索约 2,600 个外部接口(SEO 与 SERP、外链、社交、人物与公司信息补全、广告库、抓取),查看参数与单次调用价格后直接调用,凭据由服务端注入。附带技能,MCP 行在未设置 TREG_TOKEN 前保持禁用。
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1133
把腾讯云 CloudBase 后端接入 DeepSeek Harness——在对话里搭好并部署全栈应用,查询结果渲染为表格卡片(分页、排序、导出 CSV),部署后可预览真实域名,并提供 CloudBase MCP 工具集(`mcp__cloudbase__*`),登录走 device-code 流程。
gitroomhq/postiz-agent#dsh-postiz★ 503
通过 MCP 将 DeepSeek Harness 连接到 Postiz:列出已连接的社交媒体渠道、获取各平台发帖规则,并向 X、LinkedIn、Instagram、Facebook、Threads、TikTok、YouTube、Reddit、Bluesky、Mastodon、Discord、Slack、Telegram 等平台排期、存草稿或发布帖子;附带 postiz 工作流技能。
EthanYoQ/Invoice-Downloader#dsh-invoice-downloader★ 491
面向 DeepSeek Harness 的本地 IMAP 发票下载、OCR 识别、归档与 Excel 报销汇总。
anysearch-team/anysearch-dsh★ 447
基于 AnySearch 的实时网页与垂直搜索插件,为 DeepSeek Harness 提供搜索工具。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。