Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
400 commits
Select commit Hold shift + click to select a range
47d2b7a
feat(harness): run custom actions as commands
Oct 10, 2026
477620b
test(harness): cover custom actions as commands
Oct 10, 2026
75f96f4
fix(harness): show and record the observation a driver stale ref carries
Oct 10, 2026
7289bfc
test(harness): cover the observation a driver stale ref carries
Oct 10, 2026
f933600
fix(harness): count a read that answered as executed
Oct 10, 2026
a5954f1
test(harness): cover reads that answered without sending a command
Oct 10, 2026
2b0a577
fix(harness): remove staged MCP upload copies when the driver stops
Oct 10, 2026
6cc8c01
test(harness): cover removing staged MCP upload copies on stop
Oct 10, 2026
7757fbd
fix(harness): treat a browser-use browser that went away as lost
Oct 10, 2026
e717600
test(harness): cover a dead browser under browser-use
Oct 10, 2026
819cc0b
docs(harness): describe the batch tool and custom actions as commands
Oct 10, 2026
2aa4ac2
refactor(harness): drop the controller's Playwright script actions
Oct 11, 2026
61c91a0
test(harness): cover the controller without its script actions
Oct 11, 2026
d02a6f5
feat(harness): run the browser agent on the driver session
Oct 11, 2026
ff21e9d
test(harness): cover the browser agent on the driver session
Oct 11, 2026
789037b
fix(harness): type a batch value at once on a driver without slow typing
Oct 11, 2026
a231503
test(harness): cover the batch typing fallback
Oct 11, 2026
bd76e38
docs(harness): describe the browser agent on the driver session
Oct 11, 2026
35af21e
feat(harness): surface factory with instance, settings, worker flag
Oct 11, 2026
7c6b546
test(harness): cover the surface factory arguments and the worker flag
Oct 11, 2026
fb189da
feat(harness): stop and restart the driver session between tasks
Oct 11, 2026
5107720
test(harness): cover session stop, start and health
Oct 11, 2026
53a81e5
feat(harness): run the worker and the runner facade on the session
Oct 11, 2026
aa8460e
test(harness): cover the worker and the runner facade on the session
Oct 11, 2026
0a64d58
docs(harness): describe the worker and the runner facade on the session
Oct 11, 2026
2aae31a
refactor(harness): give the record rails the old rail names
Oct 11, 2026
ab3ce49
test(harness): cover the renamed rails and drop the old rail tests
Oct 11, 2026
e83579f
refactor(harness): rename the record rail tests to the rail names
Oct 11, 2026
ea8df3b
refactor(harness): drop the assembly's duplicate surface settings
Oct 11, 2026
2e6b10f
test(harness): build assemblies without the duplicate surface settings
Oct 11, 2026
e4f8848
feat(harness): key the context processors and status log by effect
Oct 11, 2026
b640e8c
test(harness): feed the processors and status log effects and records
Oct 11, 2026
89e21d1
refactor(harness): drop the client patch call and heartbeat ownership
Oct 11, 2026
afd20cb
test(harness): drop the client patch and heartbeat ownership tests
Oct 11, 2026
64f4248
fix(harness): keep a given MCP server env as the old injection did
Oct 11, 2026
8eaa1be
test(harness): cover a given MCP server env keeping its browser
Oct 11, 2026
729d727
test(harness): compare the agent's browser-use views with the golden
Oct 11, 2026
0e6d1a9
fix(harness): merge a given MCP env without env-name lookups
Oct 11, 2026
f0349c1
docs(harness): describe processors, rails and dead code after the switch
Oct 11, 2026
f696da8
feat(harness): send browser_snapshot depth and target to the MCP server
Oct 11, 2026
d808725
test(harness): cover scoped snapshots on the dialect, driver and page…
Oct 11, 2026
af2d2a2
docs(harness): describe scoped observations in S_20 and F_07
Oct 11, 2026
47625f8
fix(harness): let the MCP server judge the refs the model sends
Oct 11, 2026
505efa4
test(harness): cover MCP targets the page state no longer pre-refuses
Oct 11, 2026
2e62355
docs(harness): say who owns ref staleness in S_20 and F_07
Oct 11, 2026
6876d30
fix(harness): keep a failing status logger inside the rail
Oct 11, 2026
867f29c
test(harness): cover a status logger failure staying inside the rail
Oct 11, 2026
cd958db
docs(harness): start the switch verification baseline in F_07
Oct 11, 2026
4b1e0b4
fix(harness): write the runner's Direct agent to the process log
Oct 11, 2026
d1045df
refactor(harness): name the topology, not a driver, in the runner ent…
Oct 11, 2026
f3af327
test(harness): cover the Direct agent running outside the browser log…
Oct 11, 2026
7141481
docs(harness): say where the Direct agent's log lines go in S_20 and …
Oct 11, 2026
1d3dcb7
test(harness): give the stable-wait batch test an answer for every po…
Oct 11, 2026
d1343e8
fix(harness): start the repeat guard at the first model call of a dee…
Oct 11, 2026
5935cf4
test(harness): cover the repeat guard when before_invoke fired on ano…
Oct 11, 2026
d64110d
docs(harness): describe the repeat guard's start on a deep agent in S…
Oct 11, 2026
b8bc28a
test(harness): run the core rails and the worker live on both drivers
Oct 11, 2026
cf3afdb
fix(harness): normalise arguments only for the dialect that addresses…
Oct 11, 2026
557288a
test(harness): cover a browser-dialect click passing the rail untouched
Oct 11, 2026
f07a372
docs(harness): record the normalisation gate fix in F_07
Oct 11, 2026
3c93011
docs(harness): record the switch verification baseline in F_07
Oct 11, 2026
bd5caa9
fix(harness): fail the invoke when the driver session cannot start
Oct 11, 2026
9f35819
test(harness): cover a driver session that cannot start
Oct 11, 2026
755e79f
fix(harness): build the runner's Direct agent in the worker's language
Oct 11, 2026
6f96f15
test(harness): cover the Direct agent speaking the worker's language
Oct 11, 2026
50ca5b0
docs(harness): record the start-failure and worker-language rules in …
Oct 11, 2026
d062c31
refactor(harness): run the browser agents on the driver contract
Oct 11, 2026
6855133
feat(harness): read the topology from BROWSER_TOPOLOGY with a per-dri…
Oct 11, 2026
8db981c
test(harness): cover the topology setting, its registry default and t…
Oct 11, 2026
89b6399
docs(harness): record the topology setting in S_20 and F_07
Oct 11, 2026
f821301
feat(harness): open the session and build the worker through the comp…
Oct 11, 2026
f7d188b
test(harness): cover open_session's retry, core_rails, the live polic…
Oct 11, 2026
b495e5a
docs(harness): record the assembly pieces, the first-open retry and b…
Oct 11, 2026
51b1c40
feat(harness): run the facade's entry points through a topology strat…
Oct 11, 2026
ce5f666
test(harness): cover the topology strategies, the facade's rails at c…
Oct 11, 2026
b3bd452
docs(harness): record the topology strategies and the rails at constr…
Oct 11, 2026
49a32a4
test(harness): finish one task per driver in both topologies through …
Oct 11, 2026
cb3e906
docs(harness): record the Phase 6 verification baseline in F_07
Oct 11, 2026
d797406
refactor(harness): delete the MCP client patch and the runtime-server…
Oct 11, 2026
6efba62
refactor(harness): delete the compressor config builder and the three…
Oct 11, 2026
bc1cef2
refactor(harness): move the Playwright MCP launch defaults into the b…
Oct 11, 2026
ca6f9b3
refactor(harness): name no driver in the core's docstrings, comments …
Oct 11, 2026
a136388
test(harness): count no driver name inside another identifier and reg…
Oct 11, 2026
50616b0
refactor(harness): name the session's driver in the worker card and n…
Oct 11, 2026
aacf0f6
test(harness): cover the worker card naming the session's driver
Oct 11, 2026
322a4f4
docs(harness): record Phase 7 in S_20 and F_07
Oct 11, 2026
2ae0de9
refactor(harness): rename playwright_runtime to runtime and nest cont…
Oct 11, 2026
5d1069d
feat(harness): keep playwright_runtime as a deprecated alias of runtime
Oct 11, 2026
3b67126
test(harness): cover the playwright_runtime alias
Oct 11, 2026
a632b30
docs(harness): record Phase 8 in S_20 and F_07
Oct 11, 2026
f9a06f6
refactor(harness): move the browser modules under surfaces/browser an…
Oct 12, 2026
22e9f46
fix(harness): import the runtime server absolutely and drop the bare …
Oct 12, 2026
83fcaaa
test(harness): cover the server entry, the alias map and the surfaces…
Oct 12, 2026
f369804
fix(harness): build the MCP capability names when the server config i…
Oct 12, 2026
36e5215
test(harness): assert the --caps names playwright_mcp_config builds
Oct 12, 2026
6069390
test(harness): count no browser word inside an import statement
Oct 12, 2026
a1d8d35
refactor(harness): export CAPABILITY_TOOLS and CAPABILITY_CATALOG fro…
Oct 12, 2026
26cc701
docs(harness): record Phase 9 PR a in S_20 and F_07
Oct 12, 2026
7c182cd
refactor(harness): rename runtime.py to session.py
Oct 12, 2026
149b6ed
refactor(harness): move BrowserRuntimeRail to surfaces/browser/rails …
Oct 12, 2026
bdc7fae
refactor(harness): move the prompt sections and the worker prompt to …
Oct 12, 2026
d14df30
docs(harness): record Phase 9 PR b in S_20 and F_07
Oct 12, 2026
965aa20
refactor(harness): drop the service progress wrappers nobody calls
Oct 12, 2026
a8aa8aa
test(harness): drop the mocks of the deleted progress wrappers
Oct 12, 2026
6be6f93
refactor(harness): move the worker loop and the progress state to run…
Oct 12, 2026
66137ec
refactor(harness): split the probe JS builders into one module each
Oct 12, 2026
bbe2ca7
refactor(harness): move the browser action specs and the upload listi…
Oct 12, 2026
c78641e
docs(harness): record Phase 9 PR c in S_20 and F_07
Oct 12, 2026
6c2b253
refactor(harness): reword the browser words left in the core that are…
Oct 12, 2026
6d0fa7d
test(harness): hold the registries to the composition root and state …
Oct 12, 2026
76464c7
docs(harness): record Phase 9 PR d in S_20 and F_07
Oct 12, 2026
95bbfbf
feat(harness): hand the hooks, the worker prompt and the capability c…
Oct 12, 2026
ca8a8da
test(harness): cover the profile fields the core reads and fill the f…
Oct 12, 2026
b2ed775
test(harness): give the facades test's surface factory the registry s…
Oct 12, 2026
700dbe2
docs(harness): record Phase 9 PR e in S_20 and F_07
Oct 12, 2026
f7ea776
fix(harness): keep browser-use offload paths legal for any session id
Oct 12, 2026
7d7c3ad
test(harness): offload and recall with a session id that contains colons
Oct 12, 2026
35d51c8
docs(harness): record the offload path fix in S_20 and F_07
Oct 12, 2026
fa375eb
fix(harness): deny paste chords and clipboard reads on the browser su…
Oct 12, 2026
130185e
test(harness): paste chords and clipboard reads are denied on both di…
Oct 12, 2026
98fb4e1
docs(harness): record the clipboard policy rules in S_20 and F_07
Oct 12, 2026
fe4f016
fix(harness): recover a prose answer as JSON without re-auditing it
Oct 12, 2026
1925cc6
test(harness): the recovery request keeps the tools and restates prose
Oct 12, 2026
841e4bf
docs(harness): record the final-answer recovery change in S_20 and F_07
Oct 12, 2026
e27700b
fix(harness): charge browser-use phase budgets on what each command did
Oct 12, 2026
452696e
test(harness): phase budgets on command records and menu-free card pr…
Oct 12, 2026
6bc571c
docs(harness): record the phase-budget accounting in S_20 and F_07
Oct 12, 2026
7c3064f
fix(harness): close three browser-use driver gaps from the Phase 10 runs
Oct 12, 2026
a4e0f91
test(harness): browser-use evaluate, hung-page and selector gaps
Oct 12, 2026
844f2e6
docs(harness): record the browser-use driver gap fixes in S_20 and F_07
Oct 12, 2026
29c509b
feat(harness): give both browser agents today's date and the task rules
Oct 12, 2026
67b363e
test(harness): the task rules block, its date, and where both agents …
Oct 12, 2026
12c3328
docs(harness): record the task rules block and the open screenshot step
Oct 12, 2026
689eb57
fix(harness): resolve image input from the outer agent and probe it f…
Oct 12, 2026
204b860
test(harness): image support from the outer agent and the awaited probe
Oct 12, 2026
e1ee258
docs(harness): record image support resolution and the awaited probe
Oct 12, 2026
4187a44
fix(harness): offer browser_take_screenshot through the core capability
Oct 12, 2026
b7ff7cc
test(harness): the screenshot in core, offered only with image support
Oct 12, 2026
109f6fc
docs(harness): record browser_take_screenshot in the core capability
Oct 12, 2026
859f32a
fix(harness): probe images at the first run, not at start; no worker …
Oct 12, 2026
daaa99d
test(harness): no model call in start, the probe before the run, no w…
Oct 12, 2026
98dd9ce
docs(harness): record the probe at the first run and the worker witho…
Oct 12, 2026
b2841ac
fix(harness): refund an extraction read that adds evidence
Oct 12, 2026
e8f1a94
test(harness): replay the extraction budget failures of the browser-u…
Oct 12, 2026
77091ac
docs(harness): record the extraction refund for reads that add evidence
Oct 12, 2026
2a1a4ee
refactor(harness): move ProvisionedDevice to the contract
Oct 12, 2026
3b9b59a
refactor(harness): move masked() and the sensitive-field walk to the …
Oct 12, 2026
ef545cd
refactor(harness): move the Playwright MCP server config into the dri…
Oct 12, 2026
a682e42
refactor(harness): drivers log through core logging and take the side…
Oct 12, 2026
72b42de
refactor(harness): type the managed browser provisioner input with it…
Oct 12, 2026
7dcc139
refactor(harness): move offload_recall.py from the package root to su…
Oct 12, 2026
3d26ee5
refactor(harness): keep browser_move.offload_recall importable as a d…
Oct 12, 2026
9071c5e
fix(harness): report only transport failures of the MCP client as a l…
Oct 12, 2026
a4eb348
test(harness): lock the dependency direction and the narrowed MCP con…
Oct 12, 2026
353febd
docs(harness): record the dependency direction and the narrowed MCP c…
Oct 12, 2026
6087352
refactor(harness): move upload path resolution into the browser-use d…
Oct 12, 2026
b4acea9
docs(harness): record upload path resolution as a browser-use driver …
Oct 12, 2026
41d1658
fix(harness): let BROWSER_DRIVER name any registered driver
Oct 12, 2026
6ce532e
test(harness): select a registered driver by BROWSER_DRIVER and fail …
Oct 12, 2026
b3ecf0b
docs(harness): record that BROWSER_DRIVER names any registered driver
Oct 12, 2026
224f530
fix(harness): offer an extra tool only when the driver handles the co…
Oct 12, 2026
c0d408c
test(harness): extra tools follow the commands the driver handles
Oct 12, 2026
2b5c106
docs(harness): record that extra tools declare the commands they need
Oct 12, 2026
439f4f7
fix(harness): run the facade and the worker on a surface without the …
Oct 12, 2026
caf85bf
test(harness): the facade and the worker run on a profile without the…
Oct 12, 2026
9d81e17
docs(harness): record the optional surface hooks and the facade's bro…
Oct 12, 2026
60792b0
docs(harness): record the surface-neutral service as out of scope for…
Oct 12, 2026
10e50f0
refactor(harness): split the page state into a core registry and the …
Oct 12, 2026
6c225b1
fix(harness): detect a moved context by the surface context's identity
Oct 12, 2026
d1c6dc2
test(harness): the core page state moves by the surface context's ide…
Oct 12, 2026
6acc5a2
docs(harness): record the surface-neutral page state and the context …
Oct 12, 2026
f2f91e4
fix(harness): confine upload and drop paths to the upload root and th…
Oct 12, 2026
556866d
test(harness): upload and drop paths stay inside the upload root and …
Oct 12, 2026
17bb18b
docs(harness): record the upload confinement rule
Oct 12, 2026
c636786
test(harness): keep agent workspaces and the agent log out of the tes…
Oct 12, 2026
c390da2
fix(harness): serve the browser modules moved to surfaces/browser und…
Oct 12, 2026
3c3fa04
test(harness): each old playwright_runtime path of a moved browser mo…
Oct 12, 2026
429a62b
docs(harness): record the clean test tree and the old alias paths of …
Oct 12, 2026
963f183
fix(harness): never hand on a screenshot that is not an image; worker…
Oct 12, 2026
77291ff
test(harness): answer screenshots are images or nothing; the worker's…
Oct 12, 2026
ad9437d
fix(harness): a worker rebuilt for images leaves out the tools the ca…
Oct 12, 2026
659c08f
test(harness): the image rebuild keeps the runner's helper removal
Oct 12, 2026
3937652
docs(harness): record the cause of the rejected screenshots and the w…
Oct 12, 2026
e64f0db
fix(harness): let the core tool timeout cap the surface's per-effect …
Oct 12, 2026
8ccafb3
test(harness): the smaller of the profile and the core tool timeout b…
Oct 12, 2026
90a8167
docs(harness): record that the core tool timeout caps the driver stack
Oct 12, 2026
e164be1
refactor(harness): sort the imports of three moved modules and drop p…
Oct 12, 2026
867fe99
fix(harness): keep the browser-use stderr drain task and cancel it on…
Oct 12, 2026
963f21b
test(harness): the transport keeps the stderr drain while the sidecar…
Oct 12, 2026
4fc8b92
docs(harness): drop the S_20 draft banner and record the phase's hygiene
Oct 12, 2026
9c00105
docs(harness): record the Phase 11 live gate and the remaining ruff f…
Oct 12, 2026
3d523c0
fix(harness): judge a relative upload name only under the root it is …
Oct 13, 2026
587e6ac
test(harness): a relative upload may not climb out of the root it is …
Oct 13, 2026
8deb58b
docs(harness): record the per-root check of relative upload names
Oct 13, 2026
c2b0bea
test(harness): catch core imports that reach a surface through an out…
Oct 13, 2026
5e49488
docs(harness): record the rule for core imports through outside modules
Oct 13, 2026
ab44d76
refactor(harness): remove the playwright_runtime and offload_recall a…
Oct 13, 2026
36fd408
test(harness): pin the runner's new import paths and drop the alias t…
Oct 13, 2026
38b4b15
docs(harness): record the removal of the old import paths
Oct 13, 2026
d055476
refactor(harness): apply ruff format to browser_move
Oct 13, 2026
7b01418
test(harness): apply ruff format to the browser_move tests
Oct 13, 2026
ca02694
refactor(harness): drop comments and cut docstrings to one line in br…
Oct 13, 2026
808c7f6
test(harness): drop comments and long docstrings in the browser_move …
Oct 13, 2026
352aba3
refactor(harness): remove the deprecated ManagedBrowserDriver alias
Oct 14, 2026
75df407
test(harness): drop the alias tests and the process references in the…
Oct 14, 2026
0146a41
docs(harness): record the alias removal and drop a process reference …
Oct 14, 2026
1849046
fix(harness): type the masking helper so mypy accepts it
Oct 15, 2026
a87aa33
refactor(harness): move the custom-action tools and controller into t…
Oct 15, 2026
5f11384
refactor(harness): move the browser agent log into the browser runner…
Oct 15, 2026
b220bcb
refactor(harness): move the browser-only settings, the server config …
Oct 15, 2026
9c4983e
feat(harness): split the runner into a neutral core runtime and the b…
Oct 15, 2026
df11305
test(harness): cover the neutral runtime, the facade's answer and the…
Oct 15, 2026
b968c68
docs(harness): record the neutral core runtime and the browser facade
Oct 15, 2026
de7846a
feat(harness): build the main agent through the surface profile
Oct 15, 2026
5457edb
test(harness): pin the main-agent hook and the parts-built agent
Oct 15, 2026
0162818
docs(harness): record the main-agent hook of the surface profile
Oct 15, 2026
f949af3
fix(harness): take the browser words out of the core rails, the worke…
Oct 15, 2026
8d71de7
test(harness): pin the reworded rail and worker texts and shrink the …
Oct 15, 2026
2998a3b
docs(harness): record the browser words left in the core and why
Oct 15, 2026
1d8e83b
test(harness): run the fake surface through the core runtime on both …
Oct 15, 2026
5abfdad
docs(harness): record the fake surface's run through the core runtime
Oct 15, 2026
ec42d62
docs(harness): record the live gate of the surface-neutral runner
Oct 15, 2026
6510ec8
docs(harness): record the decision to keep the worker loop's browser …
Oct 15, 2026
7d31e80
fix(harness): resolve upload paths with one rule in the command module
Oct 15, 2026
9a577c3
test(harness): cover the upload path rule on the rail and both drivers
Oct 15, 2026
550f8f6
docs(harness): record the one upload path rule in S_20 and F_07
Oct 15, 2026
525b9b8
fix(core): reload offloaded messages from the old session folder too
Oct 15, 2026
4421434
test(core): cover the legacy offload folder lookup
Oct 15, 2026
6ff9cc3
docs(harness): record the legacy offload folder lookup in S_20 and F_07
Oct 15, 2026
e072be0
test(harness): skip the Windows user-data-dir test outside Windows
Oct 15, 2026
25ffc47
docs(harness): state the provisioning default and its one implied ove…
Oct 15, 2026
8239a48
fix(harness): enforce the clipboard rule in the page on both drivers
Oct 15, 2026
c863080
test(harness): cover the clipboard guard on both drivers and in the page
Oct 15, 2026
d4491f0
docs(harness): record the in-page clipboard guard in S_20 and F_07
Oct 15, 2026
961df59
fix(harness): type slowly on browser-use one character at a time
Oct 15, 2026
6f8031e
test(harness): cover slow typing on browser-use and in the live suites
Oct 15, 2026
bbb4595
docs(harness): record slow typing on browser-use in S_20 and F_07
Oct 15, 2026
bebdf42
fix(harness): keep the clipboard guard one expression for the sidecar
Oct 15, 2026
4a14b7f
docs(harness): record the live runs of the clipboard guard in F_07
Oct 15, 2026
b34f958
fix(harness): let the recall tool read the literal session folder too
Oct 15, 2026
febd31e
test(harness): recall an artifact stored under the literal session fo…
Oct 15, 2026
4237bb9
refactor(harness): the sidecar takes absolute upload paths only
Oct 15, 2026
b5fde00
test(harness): drop the sidecar's environment read from the allowlist
Oct 15, 2026
eb5454b
docs(harness): record the recall tool's legacy folder and the sidecar…
Oct 15, 2026
f01e939
feat(harness): make delegated_worker the browser-use default topology
Oct 15, 2026
ed7c792
test(harness): pin the browser-use runner views under the worker default
Oct 15, 2026
e1c9002
docs(harness): record the browser-use default topology measurement
Oct 15, 2026
e640f0c
fix(harness): end the task when the driver session is lost for good
Oct 15, 2026
9c668cd
test(harness): cover the end of a task after a final connection loss
Oct 15, 2026
343b919
docs(harness): record the lost-connection stop in S_20 and F_07
Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ The tools available to the sub-agent — both the Playwright MCP primitives and
| [Capability allowlist](#browser-capabilities) | Playwright tools are grouped into named capabilities (`core`, `pdf`, `vision`, `devtools`, `config`, `network`, `storage`, `testing`). The caller selects capabilities per task; only the expanded tool allowlist is exposed to the model. |
| [Runtime helper tools](../tools/browser_tools.md#runtime-helper-tools) | Page probes, batch interaction, custom actions, cancellation, and health checks, injected alongside the Playwright primitives. |
| [Browser options](#browser-options) | Headless vs. headed operation, browser engine choice, session persistence, viewport/device emulation, proxies, and output directories. |
| [Browser instance isolation](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserinstanceconfig) | `BrowserInstanceConfig` gives each agent its own browser (own MCP server, Chrome profile, and CDP port); agents sharing a key intentionally share one browser. |
| [Browser instance isolation](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigbrowserinstanceconfig) | `BrowserInstanceConfig` gives each agent its own browser (own MCP server, Chrome profile, and CDP port); agents sharing a key intentionally share one browser. |
| [Driver modes](#driver-modes) | `managed` (launch a dedicated local Chrome), `remote` (attach to an existing CDP endpoint), or `extension` (drive a running browser through the Playwright MCP extension bridge). |
| [Progress and resumability](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeruntimebrowserruntimerail) | `BrowserRuntimeRail` persists task progress into the session, injects it back as continuation context on the next invocation, and converts incomplete runs into structured failure summaries. |
| [Guardrails](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserrunguardrails) | Step, failure, and timeout limits with automatic retry and optional resume after a max-iterations stop. |
| [Progress and resumability](#class-openjiuwenharnesstoolsbrowser_moveruntimeruntimebrowserruntimerail) | `BrowserRuntimeRail` persists task progress into the session, injects it back as continuation context on the next invocation, and converts incomplete runs into structured failure summaries. |
| [Guardrails](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigrunguardrails) | Step, failure, and timeout limits with automatic retry and optional resume after a max-iterations stop. |
| [Observability](#observability) | A dedicated `logs/browser_agent.log` file and redacted structured status telemetry (`[BROWSER_SUBAGENT]` records). |

---
Expand Down Expand Up @@ -53,9 +53,9 @@ create_browser_agent(
Create the browser sub-agent. On top of a plain deep agent, this factory:

1. Resolves the requested `browser_capabilities` against the trusted capability catalog (unknown names raise `ValueError` listing the available capabilities).
2. Builds a [`BrowserAgentRuntime`](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeruntimebrowseragentruntime) from `settings` (or from the model's client config / environment when `settings` is omitted).
2. Builds a [`BrowserAgentRuntime`](#class-openjiuwenharnesstoolsbrowser_moveruntimeruntimebrowseragentruntime) from `settings` (or from the model's client config / environment when `settings` is omitted).
3. Appends the [runtime helper tools](../tools/browser_tools.md#runtime-helper-tools) to any caller-provided `tools`.
4. Appends a [`BrowserRuntimeRail`](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeruntimebrowserruntimerail) to any caller-provided `rails`.
4. Appends a [`BrowserRuntimeRail`](#class-openjiuwenharnesstoolsbrowser_moveruntimeruntimebrowserruntimerail) to any caller-provided `rails`.

The default system prompt (locale-specific, `cn`/`en`) instructs the agent to prefer compact probes over snapshots, to use `browser_run_code` only with a known selector, and to claim completion only when the outcome is evidenced on the page.

Expand All @@ -76,9 +76,9 @@ The default system prompt (locale-specific, `cn`/`en`) instructs the agent to pr
- **sys_operation** (SysOperation, optional): System operation. Default: `None`.
- **language** (str, optional): `"cn"` or `"en"`; anything else falls back to `"cn"`. Default: `None`.
- **prompt_mode** (str, optional): Prompt mode. Default: `None`.
- **settings** ([RuntimeSettings](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigruntimesettings), optional): Full browser runtime override (provider, API key/base, model, MCP config, guardrails, instance). Default: resolved from `model` or environment variables.
- **settings** ([RuntimeSettings](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigruntimesettings), optional): Full browser runtime override (provider, API key/base, model, MCP config, guardrails, instance). Default: resolved from `model` or environment variables.
- **browser_key** (str, optional): Shorthand for `browser_instance=BrowserInstanceConfig(key=...)`. Default: `None`.
- **browser_instance** ([BrowserInstanceConfig](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserinstanceconfig) | dict, optional): Per-instance browser identity. A plain dict is accepted so the identity can travel as serializable `factory_kwargs`. Default: `None` (legacy shared, environment-driven browser).
- **browser_instance** ([BrowserInstanceConfig](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigbrowserinstanceconfig) | dict, optional): Per-instance browser identity. A plain dict is accepted so the identity can travel as serializable `factory_kwargs`. Default: `None` (legacy shared, environment-driven browser).
- **browser_capabilities** (list[str], optional): Task-scoped capability names from the [capability catalog](#browser-capabilities). `core` is always included. `None` means no allowlist restriction. Default: `None`.
- ****config_kwargs**: Additional configuration arguments forwarded to `create_deep_agent`.

Expand Down Expand Up @@ -169,7 +169,7 @@ The sub-session ID for `browser_agent` is deterministic (`{parent_session}_sub_b

## Browser Capabilities

Module: `openjiuwen.harness.tools.browser_move.playwright_runtime.browser_capabilities`
Module: `openjiuwen.harness.tools.browser_move.surfaces.browser.capabilities`

Playwright MCP tools are grouped into a trusted, explicit catalog of capabilities. Matching is by exact tool name — never by prefix — so a newly introduced Playwright tool is not exposed before its policy is reviewed. The main agent selects capability names per task; the resolver performs no task interpretation of its own.

Expand Down Expand Up @@ -249,7 +249,7 @@ Headed operation is the safer default for sites with bot detection and for debug
### Timeouts

- **Per tool call**: `PLAYWRIGHT_MCP_TIMEOUT_S` / `BROWSER_TIMEOUT_S` (default `180`) bounds each MCP tool invocation.
- **Per task attempt**: `BrowserRunGuardrails.timeout_s` (default `180`) bounds a whole delegated browser task; see [Guardrails](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserrunguardrails).
- **Per task attempt**: `RunGuardrails.timeout_s` (default `180`) bounds a whole delegated browser task; see [Guardrails](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigrunguardrails).
- **Per batch step**: `browser_batch_interact` clamps step timeouts to 250–30000 ms with a global batch cap of 90 s.

### Output directories
Expand All @@ -258,7 +258,7 @@ The runtime resolves a working directory (`PLAYWRIGHT_RUNTIME_MCP_CWD`, default:

---

## class openjiuwen.harness.tools.browser_move.playwright_runtime.config.BrowserInstanceConfig
## class openjiuwen.harness.tools.browser_move.surfaces.browser.runner.settings.BrowserInstanceConfig

```python
@dataclass(frozen=True)
Expand All @@ -276,6 +276,7 @@ Per-instance browser identity, used to isolate one browser per agent. All fields
- **profile_name** (str): Managed profile name. Empty falls back to the key, then `BROWSER_PROFILE_NAME`.
- **cdp_url** (str): Explicit CDP endpoint for remote mode; wins over the shared environment endpoint.
- **browser_binary** (str): Optional Chrome binary path override.
- **launch_args** (str): Playwright MCP launch arguments in the `PLAYWRIGHT_MCP_ARGS` format (a shell-style string or a JSON list). Empty defers to `PLAYWRIGHT_MCP_ARGS`, then the default; a caller that decides headless or isolated mode per run sets this instead of the environment.

### Driver Modes

Expand All @@ -285,7 +286,7 @@ Per-instance browser identity, used to isolate one browser per agent. All fields

---

## class openjiuwen.harness.tools.browser_move.playwright_runtime.config.RuntimeSettings
## class openjiuwen.harness.tools.browser_move.surfaces.browser.runner.settings.RuntimeSettings

```python
@dataclass(frozen=True)
Expand All @@ -301,18 +302,18 @@ Resolved browser runtime settings, stored in `SubAgentConfig.factory_kwargs` and
- **api_base** (str): Model API base URL.
- **model_name** (str): Model name for the nested browser worker.
- **mcp_cfg** (McpServerConfig): Playwright MCP server configuration (stdio; command defaults to `npx -y @playwright/mcp@0.0.78` with the full capability list enabled via `--caps=`).
- **guardrails** ([BrowserRunGuardrails](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserrunguardrails)): Run guardrails.
- **instance** ([BrowserInstanceConfig](#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeconfigbrowserinstanceconfig), optional): Per-instance browser identity.
- **guardrails** ([RunGuardrails](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigrunguardrails)): Run guardrails.
- **instance** ([BrowserInstanceConfig](#class-openjiuwenharnesstoolsbrowser_moveruntimeconfigbrowserinstanceconfig), optional): Per-instance browser identity.

Use `build_runtime_settings(instance)` to resolve everything from environment variables, or let `create_browser_agent` derive provider/key/base/model from the `Model` object's client config.

---

## class openjiuwen.harness.tools.browser_move.playwright_runtime.config.BrowserRunGuardrails
## class openjiuwen.harness.tools.browser_move.runtime.config.RunGuardrails

```python
@dataclass
class BrowserRunGuardrails
class RunGuardrails
```

Limits applied to browser task runs. Built from environment variables by `build_browser_guardrails()`.
Expand All @@ -329,7 +330,7 @@ Retryable transport failures (detached frame, target closed, page crash, `net::E

---

## class openjiuwen.harness.tools.browser_move.playwright_runtime.runtime.BrowserAgentRuntime
## class openjiuwen.harness.tools.browser_move.surfaces.browser.runner.facade.BrowserAgentRuntime

```python
class BrowserAgentRuntime(
Expand All @@ -338,7 +339,7 @@ class BrowserAgentRuntime(
api_base: str,
model_name: str,
mcp_cfg: McpServerConfig,
guardrails: BrowserRunGuardrails,
guardrails: RunGuardrails,
instance: BrowserInstanceConfig | None = None,
allowed_tool_names: Iterable[str] | None = None,
)
Expand All @@ -359,7 +360,7 @@ Runtime kernel shared by all browser helper tools. Owns the underlying `BrowserS

---

## class openjiuwen.harness.tools.browser_move.playwright_runtime.runtime.BrowserRuntimeRail
## class openjiuwen.harness.tools.browser_move.surfaces.browser.rails.runtime_rail.BrowserRuntimeRail

```python
class BrowserRuntimeRail(runtime: BrowserAgentRuntime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ Session-state access — cookies, localStorage, sessionStorage, and Playwright s

## Runtime Helper Tools

Module: `openjiuwen.harness.tools.browser_move.playwright_runtime.runtime_tools`
Module: `openjiuwen.harness.tools.browser_move.surfaces.browser.runner.tools`

Deterministic helpers backed by the shared [`BrowserAgentRuntime`](../subagents/browser_agent.md#class-openjiuwenharnesstoolsbrowser_moveplaywright_runtimeruntimebrowseragentruntime). They are always injected, regardless of the capability selection.
Deterministic helpers backed by the shared [`BrowserAgentRuntime`](../subagents/browser_agent.md#class-openjiuwenharnesstoolsbrowser_moveruntimeruntimebrowseragentruntime). They are always injected, regardless of the capability selection.

| Tool | Description |
|---|---|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
| [浏览器实例隔离](#class-browserinstanceconfig) | `BrowserInstanceConfig` 为每个智能体分配独立浏览器(独立 MCP 服务器、Chrome 配置目录和 CDP 端口);使用相同 key 的智能体有意共享同一个浏览器。 |
| [驱动模式](#驱动模式) | `managed`(启动专属本地 Chrome)、`remote`(连接已有 CDP 端点)、`extension`(通过 Playwright MCP 扩展桥驱动正在运行的浏览器)。 |
| [进度与可恢复性](#class-browserruntimerail) | `BrowserRuntimeRail` 将任务进度持久化到会话中,在下次调用时作为延续上下文注入,并将未完成的运行转换为结构化失败摘要。 |
| [Guardrails](#class-browserrunguardrails) | 步数、失败次数和超时限制,支持自动重试,以及在达到最大迭代后可选的恢复执行。 |
| [Guardrails](#class-runguardrails) | 步数、失败次数和超时限制,支持自动重试,以及在达到最大迭代后可选的恢复执行。 |
| [可观测性](#可观测性) | 专用日志文件 `logs/browser_agent.log` 和经过脱敏的结构化状态遥测(`[BROWSER_SUBAGENT]` 记录)。 |

---
Expand Down Expand Up @@ -167,7 +167,7 @@ main_agent = create_deep_agent(model=model, subagents=[browser_cfg])

## 浏览器能力(Capabilities)

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.browser_capabilities`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.capabilities`

Playwright MCP 工具按可信的显式能力目录分组。匹配按工具名精确进行 —— 从不使用前缀匹配 —— 因此新引入的 Playwright 工具在其策略审查之前不会被暴露。主智能体按任务选择能力名称;解析器本身不做任何任务语义解释。

Expand Down Expand Up @@ -245,7 +245,7 @@ Managed 模式注意事项:重连时,运行时会拒绝复用启动参数与
### 超时

- **单次工具调用**:`PLAYWRIGHT_MCP_TIMEOUT_S` / `BROWSER_TIMEOUT_S`(默认 `180`)限制每次 MCP 工具调用。
- **单次任务尝试**:`BrowserRunGuardrails.timeout_s`(默认 `180`)限制一次完整的委派浏览器任务;参见 [Guardrails](#class-browserrunguardrails)。
- **单次任务尝试**:`RunGuardrails.timeout_s`(默认 `180`)限制一次完整的委派浏览器任务;参见 [Guardrails](#class-runguardrails)。
- **批量步骤**:`browser_batch_interact` 将单步超时钳制在 250–30000 ms,整批上限 90 s。

### 输出目录
Expand All @@ -256,7 +256,7 @@ Managed 模式注意事项:重连时,运行时会拒绝复用启动参数与

## class BrowserInstanceConfig

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.config`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.runner.settings`

```python
@dataclass(frozen=True)
Expand All @@ -276,6 +276,7 @@ class BrowserInstanceConfig
| `profile_name` | `str` | Managed profile 名。为空时回退到 key,再回退到 `BROWSER_PROFILE_NAME` |
| `cdp_url` | `str` | Remote 模式的显式 CDP 端点;优先于共享环境端点 |
| `browser_binary` | `str` | 可选的 Chrome 可执行文件路径覆盖 |
| `launch_args` | `str` | Playwright MCP 启动参数,格式同 `PLAYWRIGHT_MCP_ARGS`(shell 风格字符串或 JSON 列表)。为空时遵循 `PLAYWRIGHT_MCP_ARGS`,再回退到默认值;按运行决定 headless 或 isolated 的调用方在此设置,而不写环境变量 |

### 驱动模式

Expand All @@ -287,7 +288,7 @@ class BrowserInstanceConfig

## class RuntimeSettings

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.config`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.runner.settings`

```python
@dataclass(frozen=True)
Expand All @@ -305,20 +306,20 @@ class RuntimeSettings
| `api_base` | `str` | 模型 API base URL |
| `model_name` | `str` | 嵌套 browser worker 使用的模型名 |
| `mcp_cfg` | `McpServerConfig` | Playwright MCP 服务器配置(stdio;命令默认 `npx -y @playwright/mcp@0.0.78`,通过 `--caps=` 启用完整能力列表) |
| `guardrails` | `BrowserRunGuardrails` | 运行 guardrails |
| `guardrails` | `RunGuardrails` | 运行 guardrails |
| `instance` | `Optional[BrowserInstanceConfig]` | 每实例浏览器身份 |

使用 `build_runtime_settings(instance)` 从环境变量解析全部字段,或让 `create_browser_agent` 从 `Model` 对象的客户端配置推导 provider/key/base/model。

---

## class BrowserRunGuardrails
## class RunGuardrails

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.config`
模块:`openjiuwen.harness.tools.browser_move.runtime.config`

```python
@dataclass
class BrowserRunGuardrails
class RunGuardrails
```

浏览器任务运行的限制。由 `build_browser_guardrails()` 从环境变量构建。
Expand All @@ -339,7 +340,7 @@ class BrowserRunGuardrails

## class BrowserAgentRuntime

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.runtime`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.runner.facade`

```python
class BrowserAgentRuntime(
Expand All @@ -348,7 +349,7 @@ class BrowserAgentRuntime(
api_base: str,
model_name: str,
mcp_cfg: McpServerConfig,
guardrails: BrowserRunGuardrails,
guardrails: RunGuardrails,
instance: BrowserInstanceConfig | None = None,
allowed_tool_names: Iterable[str] | None = None,
)
Expand All @@ -371,7 +372,7 @@ class BrowserAgentRuntime(

## class BrowserRuntimeRail

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.runtime`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.rails.runtime_rail`

```python
class BrowserRuntimeRail(runtime: BrowserAgentRuntime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@

## 运行时辅助工具

模块:`openjiuwen.harness.tools.browser_move.playwright_runtime.runtime_tools`
模块:`openjiuwen.harness.tools.browser_move.surfaces.browser.runner.tools`

由共享的 [`BrowserAgentRuntime`](../subagents/浏览器子智能体.md#class-browseragentruntime) 支撑的确定性辅助工具。无论能力如何选择,它们始终被注入。

Expand Down
24 changes: 24 additions & 0 deletions openjiuwen/core/common/logging/tool_call.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# coding: utf-8
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.

from __future__ import annotations

from typing import Any, Callable, Optional

ToolNameMatcher = Callable[[str], bool]
ToolCallLog = Callable[..., Any]

# Process-wide like the loggers it routes to: agents are built by callers that never see the registrant.
_TOOL_CALL_LOGGERS: dict[ToolNameMatcher, ToolCallLog] = {}


def register_tool_call_logger(matches: ToolNameMatcher, log: ToolCallLog) -> None:
"""Send the tool-call lines of tools whose name ``matches`` to ``log(message, *args)``."""
_TOOL_CALL_LOGGERS[matches] = log


def tool_call_logger(tool_name: str) -> Optional[ToolCallLog]:
for matches, log in _TOOL_CALL_LOGGERS.items():
if matches(tool_name):
return log
return None
Loading