Tools & Capabilities
dsh-browser-use-native
AythyaCrispus/dsh-browser-use-native · ★ 1
DSH browser plugin: 17 Playwright browser tools running in the Host process.
Manifest details
安装
dsh plugin --profile web add 'github:AythyaCrispus/dsh-browser-use-native#7975253a4f5606f8df48afc9569eff4e87694c39'GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
English | 简体中文
@local/browser-use-native is a Host-side plugin for DSH (DeepSeek Harness). It drives a real
Chromium through Playwright inside the Host process and exposes 17 browser_* tools to the
model. Tools are registered via ctx.tools; the config only carries browser options, and
Playwright is responsible for discovering a usable Chromium.
It targets agents that actually operate web pages: instead of dumping HTML, it renders a
prunable accessibility-tree snapshot, assigns each actionable node a uid that stays stable
across snapshots, and then clicks, fills, drags and downloads by uid.
The package keeps the
@local/scope on purpose: it is installed as a locallink:bundle and is not published to npm.private: truealso prevents accidental publishing.
Features
- 17 tools: navigation, prunable snapshots, click, fill, hover, drag, key presses, file upload, native downloads, script evaluation, multiple pages, console, network and dialogs.
- One browser per live agent: started lazily on the first browser tool call; calls from the same agent run serially; the browser is closed when the agent is disposed.
- a11y snapshots: reads the Chrome Accessibility Tree per frame and gives actionable nodes
stable uids. Supports
selector/uidscoping plus character, line and depth caps. - Stable uids: uids are keyed by DOM backend node id and reused across snapshots; page navigation clears them, while iframe navigation clears only that frame. Stale uids produce a clear error instead of clicking some other element.
- Action fallbacks: when a plain click fails, it tries hit testing, a forced click, an associated label click and finally a scripted click, reporting which fallback was used.
- Native downloads:
downloadfetches throughcontext.request(shared cookies) and falls back to an in-pagefetch;uidmode captures Playwright'sdownloadevent and otherwise uses the link href. - Screenshots: either written to disk or returned to the model as an attachment.
- No hard-coded paths: relative paths resolve against the current session working directory,
and
~expands to the home directory.
Install
Requirements: DSH with Host bundle plugin support, Node.js >= 20, and Chrome or Edge installed.
git clone https://github.com/AythyaCrispus/dsh-browser-use-native.git
cd dsh-browser-use-native
npm install --omit=dev
Then install that directory through the plugin manager in a DSH session:
plugin_manager action=install_bundle target=<cloned directory>
The plugin is registered as a link: dependency, so it uses its own node_modules.
Updating
- Config in
cordis.patch.yml: HMR re-configures the plugin and the change takes effect. index.js/lib/*.js: the Host has already imported the module. Restart DSH, or disable and re-enable the plugin (set_plugin enabled=false/true) to re-import it.- After installing or updating, trust the
applicationreturned byplugin_manager.
Configuration
Every tunable lives in the patch config; values are validated on activation, and an invalid
value fails that row with an explanation.
| Field | Default | Description |
|---|---|---|
headless |
true |
false shows the browser window |
channel |
chrome |
Playwright browser channel, e.g. chrome / msedge; empty means auto-detect |
executablePath |
'' |
Optional Chromium executable; empty means auto-detect |
slowMo |
0 |
Delay per action (ms) |
viewportWidth |
1280 |
Viewport width |
viewportHeight |
800 |
Viewport height |
actionTimeoutMs |
5000 |
Timeout for click / fill / hover and similar steps |
navigationTimeoutMs |
30000 |
Navigation timeout |
dialogPolicy |
manual |
manual / auto-dismiss / auto-accept |
dialogTimeoutMs |
5000 |
Watchdog timeout for pending dialogs in manual mode |
Discovery order: executablePath → channel → chrome → msedge → Playwright-managed
Chromium. If everything fails, the tools return a summary of each attempt and suggest installing
Chrome/Edge or setting channel / executablePath. No machine-specific paths in the patch.
Runtime behaviour
- One browser per agent: lazily started on the first browser tool call; tool calls for the same agent run serially; its context/browser is closed when the agent is disposed and all of them are closed when the plugin unloads.
- Snapshots: calls
Accessibility.getFullAXTreeper frame, renders it as text and assigns uids to actionable nodes. uids are written todata-ba-uidover CDP and registered inwindow.__baUidLookup(soevaluate_scriptcan reach elements inside shadow DOM). Same-process iframes use page-level CDP with aframeId; OOPIFs get their own CDP session. - Pruning:
selectordrops a temporary marker inside the frame, resolves it to a backend node id over CDP DOM, and renders only that AX subtree;uidreuses an existing backend node id. Defaults: 20000 chars / 1200 lines, withmaxDepth,maxChars,maxLinesandincludeFrames; truncation is reported at the end. - Waiting:
wait_forpolls text, selectors and JS predicates across all frames and supportstextGoneplusvisible/hidden/attached/detachedstates. - Observation: console and network entries are collected from Playwright events; on main-frame navigation they are archived into a preserved buffer, and default listings show only entries since the last navigation.
- Dialogs:
dialogevents are kept forhandle_dialog; inmanualmode a timeout watchdog dismisses them so a serial client never hangs. - Screenshots: with
filePaththey are written to disk; otherwise they are stored throughctx.attachments.saveImagesand returned as an image content block. Without an attachment service the tool asks for an explicitfilePath. - System prompt: browser instructions are injected only when
take_snapshotis visible to the current agent.
Tools
17 tools: click, download, fill, hover, drag, press_key, upload_file,
evaluate_script, navigate_page, take_snapshot, take_screenshot, wait_for, list_pages,
select_page, list_console_messages, list_network_requests, handle_dialog. They are exposed
to the model as browser_<name>.
Self-test
node selftest.mjs
The self-test does not need DSH: it starts a local HTTP server and headless Chrome and covers
navigate, snapshot, selector/uid-scoped snapshots, stable uids, fill (input / select / hidden
checkbox), hover, overlay click fallbacks, click, wait_for (text / textGone / selector / predicate /
iframe), native downloads (URL and uid click), evaluate_script, upload_file, iframe, drag,
press_key, screenshots (page / element / file), console, network, multiple pages, dialogs, stale-uid
rejection, and the presence of all 17 tool methods — 49 checks in total. Artifacts go to
artifacts/.
Files
| File | Purpose |
|---|---|
package.json |
Bundle manifest, dsh.bundle.patch, playwright-core dependency, locale/icon exports |
cordis.patch.yml |
Inserts the browser-use-native row; carries only tunables |
index.js |
Host plugin entry: 17 tool definitions, per-agent session management, attachments, system prompt |
lib/browser.js |
BrowserSession / BrowserTools: Chromium lifecycle, pages, logs, dialogs, actions |
lib/snapshot.js |
AX-tree rendering, uid assignment, data-ba-uid CDP injection |
selftest.mjs |
End-to-end self-test without DSH (local HTTP pages + a real Chromium) |
locale/en.json / locale/zh.json |
Title and description shown in the plugin manager |
icon.svg |
Plugin icon |
Troubleshooting
| Symptom | Fix |
|---|---|
playwright-core is not installed |
Run npm install --omit=dev in the repo directory |
Could not launch a Chromium browser |
Install Chrome/Edge, or set channel / executablePath in the patch |
No browser_* tools listed |
Make sure the plugin is installed and enabled; after JS changes disable/enable it or restart DSH |
| Screenshot returns no image | The current model route does not accept images, or no attachment service is available; pass filePath |
| Code changes have no effect | Restart DSH or disable/enable the plugin to re-import the linked package |
Security
This is an in-process Host plugin with the Host's process privileges; the Chromium it launches is
not constrained by the workspace file sandbox. Only install plugin code you trust: the browser
visits pages and runs JavaScript from evaluate_script on the model's instructions.