pi-agent-browser-native 0.2.39 → 0.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.40 - 2026-06-02
6
+
7
+ ### Added
8
+
9
+ - Added Pi-scoped `pi-agent-browser-native` package config at `~/.pi/config/pi-agent-browser-native/config.json`, `.pi/config/pi-agent-browser-native/config.json`, and the `PI_AGENT_BROWSER_CONFIG` override, including the `pi-agent-browser-config` helper for redacted setup/status and conservative browser profile hints.
10
+ - Added the optional Brave-backed `agent_browser_web_search` companion tool, registered only when a usable Brave credential source is configured or resolvable, with compact normalized results for current/live web information.
11
+
12
+ ### Changed
13
+
14
+ - Documented optional web-search setup, config precedence, credential safety, and browser profile guidance across the README, command reference, tool contract, architecture notes, and support matrix.
15
+
16
+ ### Fixed
17
+
18
+ - Hardened Brave credential handling so project-local config only accepts exact inert `$ENV_VAR` or `${ENV_VAR}` references, rejects plaintext/malformed/interpolation-literal/command-backed secrets, and keeps raw or entity-encoded API keys out of tool output and errors.
19
+ - Cleaned Brave result text by decoding common HTML entities while stripping decoded HTML tags safely and preserving placeholder text such as `<version>`.
20
+
5
21
  ## 0.2.39 - 2026-06-02
6
22
 
7
23
  ### Added
package/README.md CHANGED
@@ -146,6 +146,48 @@ The doctor checks:
146
146
 
147
147
  It does **not** edit Pi settings and does **not** run upstream `agent-browser doctor --fix`.
148
148
 
149
+ ## Optional package config and web search
150
+
151
+ `pi-agent-browser-native` also reads package-owned config under Pi-scoped paths:
152
+
153
+ - global user config: `~/.pi/config/pi-agent-browser-native/config.json`
154
+ - project config: `.pi/config/pi-agent-browser-native/config.json`
155
+ - explicit override: `PI_AGENT_BROWSER_CONFIG=/path/to/config.json`
156
+
157
+ Use the setup helper to inspect or write config:
158
+
159
+ ```bash
160
+ pi-agent-browser-config paths
161
+ pi-agent-browser-config show
162
+ ```
163
+
164
+ The optional `agent_browser_web_search` companion tool is Brave-only today and is registered only when a usable Brave Search credential source is configured or resolvable. It is not an `agent_browser` input mode and does not launch a browser; agents may use it whenever current/live external web information helps, then use `agent_browser` when they need page interaction, screenshots, authenticated/profile content, or DOM inspection.
165
+
166
+ Get a Brave Search API key from the [Brave Search API dashboard](https://api-dashboard.search.brave.com/). Brave currently advertises free monthly credits for Search API usage, which is usually ample for light personal agent/dogfood use; confirm current pricing and limits on Brave's dashboard before relying on it for heavier workflows.
167
+
168
+ Supported setup examples:
169
+
170
+ ```bash
171
+ # Store a plaintext key in global Pi-scoped user config; output stays redacted.
172
+ printf '%s' "$BRAVE_API_KEY" | pi-agent-browser-config web-search set-key --stdin
173
+
174
+ # Store an env-var reference, useful for project config.
175
+ pi-agent-browser-config web-search set-env BRAVE_API_KEY --project
176
+
177
+ # Store a global secret-manager command source.
178
+ pi-agent-browser-config web-search set-command "op read 'op://Private/Brave Search/API Key'" --global
179
+ ```
180
+
181
+ Project-local plaintext, interpolation-literal, malformed, and command-backed Brave keys are refused; use an exact environment reference such as `$BRAVE_API_KEY` or `${BRAVE_API_KEY}` for `.pi/config/pi-agent-browser-native/config.json`. The tool content, details, status output, and docs examples must not expose the resolved key.
182
+
183
+ The same config file can record conservative browser defaults such as a profile hint:
184
+
185
+ ```bash
186
+ pi-agent-browser-config browser profile set Default --policy authenticated-only
187
+ ```
188
+
189
+ This adds agent guidance for signed-in/account-specific tasks; current releases do not auto-inject `--profile` for every launch.
190
+
149
191
  ## Common agent calls
150
192
 
151
193
  You usually prompt the agent in natural language. These JSON snippets show the exact native tool shape the agent should use.
@@ -15,17 +15,22 @@ The package install path is the primary product path. Local checkout development
15
15
 
16
16
  ## Chosen shape
17
17
 
18
- ### One primary tool
18
+ ### One primary tool plus optional companion search
19
19
 
20
- V1 should expose one native tool:
20
+ V1 exposes one native browser tool:
21
21
 
22
22
  - `agent_browser`
23
23
 
24
+ It may also expose one optional companion tool:
25
+
26
+ - `agent_browser_web_search`, registered only when a Brave Search credential source is configured or resolvable
27
+
24
28
  Why:
25
- - lowest maintenance cost
26
- - lowest drift risk as upstream changes
27
- - preserves full upstream power
28
- - avoids overengineering
29
+ - keeps browser automation centered on `agent_browser`
30
+ - avoids colliding with generic `web_search`
31
+ - keeps live search separate from browser state, screenshots, refs, and session lifecycle
32
+ - preserves full upstream power without adding a generic provider abstraction
33
+ - keeps optional search invisible when it cannot run
29
34
 
30
35
  ### Direct subprocess execution
31
36
 
@@ -53,6 +58,20 @@ That means:
53
58
  - no manual user orchestration as the main workflow
54
59
  - any future slash commands should be minimal and secondary
55
60
 
61
+ ### Package-owned config
62
+
63
+ Pi docs use `settings.json` for package/resource loading and filtering, not arbitrary extension secrets. For user-tunable package behavior, this package owns Pi-scoped config files instead:
64
+
65
+ - global: `~/.pi/config/pi-agent-browser-native/config.json`
66
+ - project-local: `.pi/config/pi-agent-browser-native/config.json`
67
+ - explicit override: `PI_AGENT_BROWSER_CONFIG=/path/to/config.json`
68
+
69
+ Config layers merge in that order: global, project, override. The config reader accepts v1 fields for `webSearch.braveApiKey` and conservative browser defaults such as `browser.defaultProfile`. `webSearch.braveApiKey` follows Pi model/provider-style value resolution for trusted global/override config: literal values, `$ENV_VAR` / `${ENV_VAR}` interpolation, escapes (`$$`, `$!`), and leading `!command` resolved at request time. Project-local plaintext, interpolation-literal, malformed, and command-backed Brave keys are rejected because project config can be copied, committed, or supplied by a repository; project config should use inert exact `$ENV_VAR` or `${ENV_VAR}` sources only.
70
+
71
+ `agent_browser_web_search` registration is conditional. Literal and env-backed sources must resolve at startup; command-backed sources are considered configured without running the command until tool execution, so secret managers do not slow startup or prompt unexpectedly. The tool resolves the key lazily, calls Brave Search, and returns compact result details without exposing the key.
72
+
73
+ Browser default profile config is intentionally conservative. It can add prompt guidance for signed-in/account-specific tasks, but current releases do not auto-inject `--profile` into every launch. Automatic launch-default mutation would affect privacy and browser state, so it needs a separate explicit design and test pass.
74
+
56
75
  ### Prompt guidance budget
57
76
 
58
77
  Runtime `promptGuidelines` are a Tier A budget, not a full manual. They stay short enough to load on every `agent_browser`-aware turn and carry only high-impact rules: input-mode choice, the open → snapshot → ref loop, launch-scoped session handling, artifact verification, structured `nextActions`, extraction basics, and hard safety boundaries such as “stop before order/post/purchase/submit.”
@@ -663,6 +663,48 @@ Long-running or lifecycle commands should be explicitly paired with cleanup call
663
663
 
664
664
  When these commands are invoked through the native `agent_browser` tool, structured diagnostic/status outputs are rendered as compact summaries. Local inspection/setup calls (`auth save/list/show/delete/remove`, `dashboard start/stop`, `device list`, `doctor`, `install`, `upgrade`, `profiles`, `session list`, `state list/show/rename`, `state clean --older-than <days>`, `state clear --all`, `state clear -a`, and `state clear <session-name>`) are sessionless unless you explicitly pass `--session`; context-dependent calls such as root `session`, untargeted `state clear`, `auth login`, `chat`, and `state save/load` keep normal session behavior. List-like outputs such as sessions, Chrome profiles, auth profiles, network requests, console messages, and page errors include counts and key fields; large outputs are previewed with a `Full output path:` spill file instead of dumping the entire payload into context. For `network requests`, the wrapper shows a failed-request summary split into actionable versus benign low-impact rows, then status, method, URL, resource/mime type, request id, and, when the installed upstream output includes body-like fields, bounded redacted payload, response, and failure/error snippets. Safe request IDs also produce `details.nextActions` for exact request details, actionable failed-request source lookup candidates, filtered request lists, or starting HAR capture before a repro. `network request <requestId>` can expose upstream full-detail body fields such as response bodies using the same bounded model-facing preview; its request URL stays diagnostic-only and does not overwrite `details.sessionTabTarget` for later ref guards. Header, cookie, auth, token, and other secret-like fields are not expanded in model-facing text or `details.data`; command echoes also redact `--body`, `--headers`, `--password`, proxy credentials, auth-bearing URLs, cookie/storage values, and bearer/basic credential text in positional arguments. Use upstream HAR or full raw details only when complete data is required.
665
665
 
666
+ ## Optional package config and companion web search
667
+
668
+ `pi-agent-browser-native` has package-owned config under Pi-scoped paths. This is separate from upstream `agent-browser` config and from Pi package settings:
669
+
670
+ - global: `~/.pi/config/pi-agent-browser-native/config.json`
671
+ - project-local: `.pi/config/pi-agent-browser-native/config.json`
672
+ - explicit override: `PI_AGENT_BROWSER_CONFIG=/path/to/config.json`
673
+
674
+ Get a Brave Search API key from the [Brave Search API dashboard](https://api-dashboard.search.brave.com/). Brave currently advertises free monthly credits for Search API usage, which is usually ample for light personal agent/dogfood use; confirm current pricing and limits on Brave's dashboard before relying on it for heavier workflows.
675
+
676
+ Inspect and write config with the package helper:
677
+
678
+ ```bash
679
+ pi-agent-browser-config paths
680
+ pi-agent-browser-config show
681
+ pi-agent-browser-config web-search set-env BRAVE_API_KEY --project
682
+ pi-agent-browser-config web-search set-command "op read 'op://Private/Brave Search/API Key'" --global
683
+ printf '%s' "$BRAVE_API_KEY" | pi-agent-browser-config web-search set-key --stdin
684
+ pi-agent-browser-config browser profile set Default --policy authenticated-only
685
+ ```
686
+
687
+ The optional `agent_browser_web_search` tool is registered only when a Brave Search credential source is configured or resolvable. It is a separate custom tool, not an `agent_browser` input mode, and does not launch a browser. Use it when current/live external web information would help; use `agent_browser` for browser interaction, screenshots, authenticated/profile pages, and DOM inspection. Project-local plaintext, interpolation-literal, malformed, and command-backed Brave keys are refused; use exact `$ENV_VAR` or `${ENV_VAR}` sources there.
688
+
689
+ Example config:
690
+
691
+ ```json
692
+ {
693
+ "version": 1,
694
+ "webSearch": {
695
+ "braveApiKey": "$BRAVE_API_KEY"
696
+ },
697
+ "browser": {
698
+ "defaultProfile": {
699
+ "name": "Default",
700
+ "policy": "authenticated-only"
701
+ }
702
+ }
703
+ }
704
+ ```
705
+
706
+ Browser default profile config is conservative: it adds agent guidance for signed-in/account-specific tasks; current releases do not auto-inject `--profile` for every launch.
707
+
666
708
  ## Important global flags, config, and environment
667
709
 
668
710
  ### Authentication and session flags
package/docs/RELEASE.md CHANGED
@@ -57,7 +57,7 @@ npm run smoke:platform:all
57
57
 
58
58
  This mode uses the extension harness and the real `agent-browser` on `PATH` against a deterministic local file fixture, then verifies top-level `qa`, `semanticAction`, constrained `job`, screenshot artifact verification, and session close. Use `npm run verify -- dogfood --keep-artifacts` or `--artifact-dir <path>` only while debugging, then delete retained screenshots. This smoke complements, but does not replace, human-readable interactive transcript evidence.
59
59
 
60
- Every release also requires interactive `tmux`-driven Pi dogfood with the native `agent_browser` tool against real sites. For extension-focused release smokes, use `pi --no-extensions --no-skills -e .` from the checkout before publish so auto-loaded dogfood/QA skills cannot replace the bounded smoke workflow; run separate skill-enabled dogfood only when validating skill routing or report-generation behavior. Drive prompts with `tmux send-keys`, exercise at least one simple static site and one real documentation/product site, include the higher-level `qa` or `job`/`batch` surfaces when they changed, close every opened browser session, remove screenshots/temp artifacts, and record the outcome in the release notes or support-matrix evidence. Automated localhost, fake-upstream, and deterministic dogfood gates do not replace this human-readable live-site transcript evidence. When `electron.*` surfaces, attached-session diagnostics, or `qa.attached` changed, add a local Electron pass: `electron.list` → `electron.launch` (expect isolated profile behavior) → `snapshot -i` or `electron.probe` / `qa.attached` → `electron.cleanup` with the returned `launchId`, verifying status/mismatch guidance if you simulate a dead renderer or stale refs. For dense-dashboard stress coverage, use the [public Grafana stress checklist](#public-grafana-stress-checklist) below; it is a maintainer workflow, not bundled product skill or recipe runtime.
60
+ Every release also requires interactive `tmux`-driven Pi dogfood with the native `agent_browser` tool against real sites. For extension-focused release smokes, use `pi --no-extensions --no-skills -e .` from the checkout before publish so auto-loaded dogfood/QA skills cannot replace the bounded smoke workflow; run separate skill-enabled dogfood only when validating skill routing or report-generation behavior. Drive prompts with `tmux send-keys`, exercise at least one simple static site and one real documentation/product site, include the higher-level `qa` or `job`/`batch` surfaces when they changed, close every opened browser session, remove screenshots/temp artifacts, and record the outcome in the release notes or support-matrix evidence. Automated localhost, fake-upstream, and deterministic dogfood gates do not replace this human-readable live-site transcript evidence. When `agent_browser_web_search` or package config changed, add one key-free smoke proving the optional tool is absent without config, one fake/unit-backed smoke in the default suite, and one opt-in live Brave Search check with a real key while confirming the key does not appear in transcripts, stdout/stderr, config status, PR text, or artifacts. When `electron.*` surfaces, attached-session diagnostics, or `qa.attached` changed, add a local Electron pass: `electron.list` → `electron.launch` (expect isolated profile behavior) → `snapshot -i` or `electron.probe` / `qa.attached` → `electron.cleanup` with the returned `launchId`, verifying status/mismatch guidance if you simulate a dead renderer or stale refs. For dense-dashboard stress coverage, use the [public Grafana stress checklist](#public-grafana-stress-checklist) below; it is a maintainer workflow, not bundled product skill or recipe runtime.
61
61
 
62
62
  When reviewing saved session JSONL after a failed smoke or a `qa` preset that reclassified an upstream-successful batch, expect `agent_browser` tool rows to carry `isError: true` whenever `details.resultCategory` is `failure`. For normal prose output, model-visible text should end with a `Pi tool isError: true` category line; for caller-requested `--json` output, the hook preserves parseable JSON and only patches `isError`. The extension applies that patch on the `tool_result` path so Pi’s transcript matches the wrapper contract ([`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details)). Preserve a normal Pi session directory for those checks; avoiding `--no-session` keeps this evidence intact ([`AGENTS.md`](../AGENTS.md) preferred validation workflow).
63
63
 
@@ -157,7 +157,8 @@ Maintainer constraints for evolving scenarios and version bumps are summarized u
157
157
  `npm run verify -- package-pi` runs the same package-content checks and additionally confirms that:
158
158
 
159
159
  - the packed package can be loaded through Pi SDK resource loading with the same isolation principle as `pi --no-extensions -e <package-source>`
160
- - exactly one `agent_browser` tool is registered
160
+ - `agent_browser` is registered without requiring optional Brave config
161
+ - any optional companion tools remain governed by their own configuration gates
161
162
  - the registered `agent_browser` source resolves inside the extracted packed package path, not the working checkout
162
163
  - the packaged `agent_browser` tool can be executed through Pi's loaded native tool definition with a deterministic fake upstream `agent-browser --version` binary
163
164
 
@@ -30,7 +30,7 @@ When upstream ships a new `agent-browser` or the inventory changes:
30
30
  - Source of truth: `CAPABILITY_BASELINE.inventorySections` in the same file (stable `id` keys: `skills`, `core-commands`, `state-tabs-frames-dialogs`, `network-storage-artifacts-diagnostics`, `batch-auth-setup-ai`, `options-and-env`).
31
31
  - Status: supported for the current wrapper contract after the 2026-05-26 all-command audit.
32
32
  - High-priority support gaps: 2026-05-26 audit found sessionless local commands and command-scoped value flags needed sharper wrapper handling; runtime/tests/docs now cover those paths. Remaining upstream-owned caveat: `agent-browser 0.27.1` help mentions `wait <selector> --state hidden`, but source parsing does not implement that distinct wait mode, so wrapper docs steer agents to `wait --fn` predicates.
33
- - Post-`v0.2.29` review state: commits `eb55320` through `86abbfb` add browser guidance/smoke coverage plus `RQ-0086` click-probe reduction, `RQ-0087` same-snapshot form fill batching, `RQ-0088` current-ref fallback on locator misses, `RQ-0089` direct-upstream click mutation investigation, and `RQ-0090` stop-boundary/artifact-path guidance. Verification gates below were rerun on 2026-05-18 after those tasks landed. Constrained `job` (`RQ-0064`), the lightweight `qa` preset (`RQ-0065`), the experimental `sourceLookup` helper (`RQ-0066`), and the experimental `networkSourceLookup` helper (`RQ-0067`) are implemented; see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#job), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#qa), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sourcelookup), and [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#networksourcelookup). Reusable browser recipes (`RQ-0068`) are intentionally not adopted as a runtime surface; see [`ARCHITECTURE.md`](ARCHITECTURE.md#no-reusable-recipe-layer-yet).
33
+ - Post-`v0.2.29` review state: commits `eb55320` through `86abbfb` add browser guidance/smoke coverage plus `RQ-0086` click-probe reduction, `RQ-0087` same-snapshot form fill batching, `RQ-0088` current-ref fallback on locator misses, `RQ-0089` direct-upstream click mutation investigation, and `RQ-0090` stop-boundary/artifact-path guidance. Verification gates below were rerun on 2026-05-18 after those tasks landed. Constrained `job` (`RQ-0064`), the lightweight `qa` preset (`RQ-0065`), the experimental `sourceLookup` helper (`RQ-0066`), the experimental `networkSourceLookup` helper (`RQ-0067`), and optional Brave-backed `agent_browser_web_search` with Pi-scoped package config (`RQ-0121`) are implemented; see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#job), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#qa), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sourcelookup), [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#networksourcelookup), and [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#optional-companion-web-search). Reusable browser recipes (`RQ-0068`) are intentionally not adopted as a runtime surface; see [`ARCHITECTURE.md`](ARCHITECTURE.md#no-reusable-recipe-layer-yet).
34
34
 
35
35
  ## Open UX/reliability follow-ups from 2026-05-29 agent feedback
36
36
 
@@ -60,7 +60,7 @@ Re-run the gates below before each release; this table records what the closure
60
60
  | --- | --- | --- |
61
61
  | Default local gate | `npm run verify` checks generated playbook drift, `tsc --noEmit`, unit/fake tests, generated command-reference blocks, and live command-reference sampling. | Pass on 2026-06-02 as part of `npm run verify -- release` (`agent-browser 0.27.1` on `PATH`). |
62
62
  | Real upstream contract | `npm run verify -- real-upstream` runs the localhost fixture matrix against the real installed `agent-browser` matching the baseline. | Pass on 2026-06-02 (`npm run verify -- real-upstream`, `agent-browser 0.27.1` on `PATH`; updated Web Vitals shape assertions for upstream 0.27.1 structured output). |
63
- | Packaged Pi smoke | `npm run verify -- package-pi` validates package contents, loads exactly one packaged `agent_browser` tool, and executes fake-upstream `--version`. | Pass on 2026-05-29 (`npm run verify -- package-pi`). |
63
+ | Packaged Pi smoke | `npm run verify -- package-pi` validates package contents, loads the packaged `agent_browser` tool without requiring optional Brave config, and executes fake-upstream `--version`. | Pass on 2026-05-29 (`npm run verify -- package-pi`). |
64
64
  | Deterministic dogfood smoke | `npm run verify -- dogfood` (`scripts/verify-agent-browser-dogfood.ts`) drives the native wrapper against a local file fixture through top-level `qa`, `semanticAction`, constrained `job`, screenshot artifact verification, and session close with the real `agent-browser` on `PATH`. | Pass on 2026-06-02 (`npm run verify -- dogfood`, `agent-browser 0.27.1`; artifacts cleaned by the harness). |
65
65
  | Efficiency benchmark | `npm run verify -- benchmark` runs deterministic browser workflow accounting plus focused benchmark tests, including JSONL sampling fixtures and job/qa/sourceLookup/networkSourceLookup/Electron scenario coverage. | Pass on 2026-05-29 (`npm run verify -- benchmark`). |
66
66
  | Crabbox platform smoke | `npm run check:platform-smoke` syntax-checks the harness and cheap invariants. `npm run smoke:platform:all` runs doctor first, then fast target-local `platform-build` (`npm run verify -- platform-target`, pack, clean Pi install) plus `browser-dogfood-smoke` on Crabbox `macos`, `ubuntu`, and `windows-native`; see [`platform-smoke.md`](platform-smoke.md). | Pass on 2026-06-02 (`npm run check:platform-smoke`, `npm run smoke:platform:ubuntu-image`, and `npm run smoke:platform:all`; artifacts cleaned after evidence capture). |
@@ -77,11 +77,13 @@ Re-run the gates below before each release; this table records what the closure
77
77
  | Sessions, state, tabs, frames, dialogs, and windows | 20 canonical tokens from baseline section `state-tabs-frames-dialogs`; see [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs) and generated [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#session-state-frames-dialogs-windows-and-inspection-commands). | [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#session-state-frames-dialogs-windows-and-inspection-commands), stateful workflow notes, [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details). | Stateful summaries/redaction, state artifact handling, sessionless local command planning, managed-session restore, tab target pinning, and close alias cleanup. | Extension-validation stateful matrix, runtime session/resume tests, presentation redaction tests, lifecycle harness. | Supported. External profile/auth state remains operator-owned. |
78
78
  | Network, storage, artifacts, diagnostics, and performance | 42 canonical tokens from baseline section `network-storage-artifacts-diagnostics`; see [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs) and generated [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#page-state-finding-mouse-settings-network-and-storage). | [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#page-state-finding-mouse-settings-network-and-storage), diagnostic sections, [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details). | Thin passthrough plus compact diagnostics, artifact metadata, missing-ffmpeg warnings, sensitive-data redaction, timeout bounds, and cleanup-pair guidance. | Fake non-core matrix and safe real-upstream coverage for network/HAR, diff, trace/profiler, console/errors/highlight, stream, vitals, and React missing-renderer. | Supported. Environment-sensitive operations need suitable local/browser state. |
79
79
  | Batch, auth, confirmations, setup, dashboard, devices, and AI commands | 24 canonical tokens from baseline section `batch-auth-setup-ai`; see [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs) and generated [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#batch-auth-confirmations-sessions-chat-dashboard-devices-and-setup). | [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#batch-auth-confirmations-sessions-chat-dashboard-devices-and-setup), README security notes, release docs. | Native-tool batch stdin, generated `job`/`qa`/lookup batch plans, auth/confirmation redaction, sessionless local auth/setup/dashboard/doctor planning, timeout/cleanup guidance. | Unit/fake batch/auth/confirmation/dashboard/chat/doctor tests; extension-validation for structured input modes; efficiency benchmark scenarios. | Supported. Interactive side-effecting setup/auth/chat remains upstream-owned. |
80
- | Global flags, config, providers, policy, and environment | 117 canonical tokens from baseline section `options-and-env`; see [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs) and generated [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#important-global-flags-config-and-environment). | [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#important-global-flags-config-and-environment), README provider/setup notes, [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sessionmode), architecture/runtime docs. | Runtime handles command discovery, value-flag prevalidation, launch-scoped flags, redacted echoes, fresh-session recovery hints, explicit sessions, provider/device launch-scoping, curated env forwarding, and subprocess completion. | Runtime tests for flags/planning/redaction/session behavior; process tests for env and stdio-linger completion; fake provider/specialized-skill matrix; package doctor. | Supported. Provider clouds, iOS/Appium, proxies, profiles, and credentials require external setup. |
80
+ | Global flags, config, providers, policy, and environment | 117 canonical tokens from baseline section `options-and-env`; see [`scripts/agent-browser-capability-baseline.mjs`](../scripts/agent-browser-capability-baseline.mjs) and generated [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#important-global-flags-config-and-environment). | [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#important-global-flags-config-and-environment), README provider/setup notes, [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sessionmode), architecture/runtime docs. | Runtime handles command discovery, value-flag prevalidation, launch-scoped flags, redacted echoes, fresh-session recovery hints, explicit sessions, provider/device launch-scoping, curated env forwarding, subprocess completion, and package-owned Pi-scoped config for optional companion features. | Runtime tests for flags/planning/redaction/session behavior; process tests for env and stdio-linger completion; config/web-search/CLI tests; fake provider/specialized-skill matrix; package doctor. | Supported. Provider clouds, iOS/Appium, proxies, profiles, and credentials require external setup. |
81
81
 
82
82
  ## Follow-up decision after closure
83
83
 
84
- Native `job`, `qa`, experimental `sourceLookup`, experimental `networkSourceLookup`, and first-class Electron lifecycle/probe support are shipped.
84
+ Native `job`, `qa`, experimental `sourceLookup`, experimental `networkSourceLookup`, first-class Electron lifecycle/probe support, and optional Brave-backed companion web search are shipped.
85
+
86
+ `RQ-0121` adds Pi-scoped package config plus optional Brave web search without turning search into an `agent_browser` input mode. Config lives at `~/.pi/config/pi-agent-browser-native/config.json`, `.pi/config/pi-agent-browser-native/config.json`, or an explicit `PI_AGENT_BROWSER_CONFIG` override, with global → project → override merge order and `BRAVE_API_KEY` as a fallback only when no config credential source exists. `webSearch.braveApiKey` supports Pi model/provider-style literal, `$ENV_VAR` / `${ENV_VAR}`, escape, and `!command` values in trusted global/override config; project-local config rejects plaintext, interpolation-literal, malformed, and command-backed keys and allows inert exact env references only. `agent_browser_web_search` registers only when a usable credential source is available, resolves command secrets lazily at execution, calls Brave Search, returns compact normalized result details, and never exposes the key. Browser default profile config records conservative prompt guidance only; it does not auto-inject launch args. Contract: [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#optional-companion-web-search); human workflow: README optional package config and [`COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#optional-package-config-and-companion-web-search); implementation: `extensions/agent-browser/lib/config.ts`, `extensions/agent-browser/lib/web-search.ts`, `scripts/config.mjs`, and conditional registration in `extensions/agent-browser/index.ts`; fake coverage: `test/agent-browser.config.test.ts`, `test/agent-browser.web-search.test.ts`, and `test/agent-browser.config-cli.test.ts`.
85
87
 
86
88
  `RQ-0066` shipped as the bounded evidence model in [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#sourcelookup): it compiles to upstream `batch` steps (`is visible`, `get html`, `react inspect`, `react tree` as applicable), merges `details.sourceLookup` into the tool `details` alongside batch presentation, and never reclassifies an upstream-successful batch to failed solely because no candidates were found (unlike `qa` diagnostic reclassification). Wrapper-tracked packaged Electron no-candidate results now add bounded `workspaceRoot` / `electronContext` when available, limitations that the scan only covers the Pi cwd and does not unpack installed app resources or `app.asar`, and live Electron `snapshot` / `probe` / `tab list` next actions. Fake coverage: `agentBrowserExtension explains packaged Electron sourceLookup no-candidate boundaries` in [`test/agent-browser.extension-validation.test.ts`](../test/agent-browser.extension-validation.test.ts).
87
89
 
@@ -10,9 +10,10 @@ Related docs:
10
10
 
11
11
  ## V1 tool
12
12
 
13
- V1 should expose one primary native tool:
13
+ V1 exposes one primary native browser tool and one optional companion search tool:
14
14
 
15
15
  - `agent_browser`
16
+ - `agent_browser_web_search` when a Brave Search credential source is configured or resolvable
16
17
 
17
18
  ## Why this tool shape
18
19
 
@@ -33,6 +34,49 @@ The native command reference in `docs/COMMAND_REFERENCE.md` is driven by the sam
33
34
 
34
35
  Agent-facing efficiency claims are measured with `npm run benchmark:agent-browser` or `npm run verify -- benchmark`. The benchmark is deterministic and does not launch a browser; it tracks representative workflow success, tool calls, model-visible output size, stale-ref failures and recoveries, artifact success, failure-category coverage, and elapsed-time estimates so future abstractions can prove they reduce agent work before replacing raw tool use.
35
36
 
37
+ ## Optional companion web search
38
+
39
+ `agent_browser_web_search` is a separate custom tool, not an `agent_browser` input mode. It is registered only when the extension can see a configured Brave Search credential source from `~/.pi/config/pi-agent-browser-native/config.json`, `.pi/config/pi-agent-browser-native/config.json`, `PI_AGENT_BROWSER_CONFIG`, or the `BRAVE_API_KEY` environment fallback. Command credential sources such as `"!op read 'op://Private/Brave Search/API Key'"` are allowed only from trusted global or explicit-override config; they make the tool available without running the command at startup, and the key is resolved when the tool executes. Project-local config may use inert exact `$ENV_VAR` / `${ENV_VAR}` references only; interpolation literals and malformed `$` values are rejected.
40
+
41
+ Use it when live/current external web information would help answer a task, find current docs/news, or discover candidate URLs. Use `agent_browser` when the task needs browser interaction, screenshots, authenticated/profile content, page inspection, or DOM work. The search tool is Brave-only today, namespaced to avoid colliding with generic `web_search`, and must not expose the resolved API key in content, details, errors, status output, docs examples, logs, or PR artifacts.
42
+
43
+ Schema:
44
+
45
+ ```json
46
+ {
47
+ "query": "search text",
48
+ "count": 5,
49
+ "offset": 0,
50
+ "country": "US",
51
+ "searchLang": "en-US",
52
+ "safesearch": "moderate",
53
+ "freshness": "pw"
54
+ }
55
+ ```
56
+
57
+ Result details:
58
+
59
+ ```json
60
+ {
61
+ "provider": "brave",
62
+ "query": "search text",
63
+ "returnedQuery": "search text",
64
+ "count": 5,
65
+ "offset": 0,
66
+ "fetchedAt": "2026-06-02T00:00:00.000Z",
67
+ "results": [
68
+ {
69
+ "title": "Result title",
70
+ "url": "https://example.com/",
71
+ "description": "Compact summary",
72
+ "source": "Example",
73
+ "age": "1 day ago",
74
+ "language": "en"
75
+ }
76
+ ]
77
+ }
78
+ ```
79
+
36
80
  ## Input mode chooser
37
81
 
38
82
  Use exactly one top-level input per call:
@@ -41,7 +41,6 @@ import {
41
41
  getImplicitSessionCloseTimeoutMs,
42
42
  getImplicitSessionIdleTimeoutMs,
43
43
  hasLaunchScopedTabCorrectionFlag,
44
- hasUsableBraveApiKey,
45
44
  extractExplicitSessionName,
46
45
  redactInvocationArgs,
47
46
  restoreManagedSessionStateFromBranch,
@@ -118,6 +117,8 @@ import {
118
117
  type VisibleRefFallbackDiagnostic,
119
118
  } from "./lib/results/selector-recovery.js";
120
119
  import { withOptionalSessionArgs } from "./lib/results/next-actions.js";
120
+ import { canRegisterWebSearchTool, loadAgentBrowserConfigSync } from "./lib/config.js";
121
+ import { createAgentBrowserWebSearchTool } from "./lib/web-search.js";
121
122
 
122
123
  const DEFAULT_SESSION_MODE = "auto" as const;
123
124
  const DIRECT_AGENT_BROWSER_BASH_BYPASS_ENV = "PI_AGENT_BROWSER_ALLOW_DIRECT_BASH";
@@ -947,8 +948,13 @@ function getInstalledDocsPaths(): { readmePath: string; commandReferencePath: st
947
948
 
948
949
  export default function agentBrowserExtension(pi: ExtensionAPI) {
949
950
  const ephemeralSessionSeed = createEphemeralSessionSeed();
950
- const hasBraveApiKey = hasUsableBraveApiKey();
951
- const toolPromptGuidelines = buildToolPromptGuidelines({ includeBraveSearch: hasBraveApiKey, docs: getInstalledDocsPaths() });
951
+ const agentBrowserConfig = loadAgentBrowserConfigSync({ cwd: process.cwd() });
952
+ const webSearchToolAvailable = canRegisterWebSearchTool(agentBrowserConfig);
953
+ const toolPromptGuidelines = buildToolPromptGuidelines({
954
+ browserDefaultProfile: agentBrowserConfig.browserDefaultProfile,
955
+ includeBraveSearch: webSearchToolAvailable,
956
+ docs: getInstalledDocsPaths(),
957
+ });
952
958
  const implicitSessionIdleTimeoutMs = String(getImplicitSessionIdleTimeoutMs());
953
959
  const implicitSessionCloseTimeoutMs = getImplicitSessionCloseTimeoutMs();
954
960
  let managedSessionActive = false;
@@ -1267,4 +1273,8 @@ export default function agentBrowserExtension(pi: ExtensionAPI) {
1267
1273
  : runBrowserCommand();
1268
1274
  },
1269
1275
  });
1276
+
1277
+ if (webSearchToolAvailable) {
1278
+ pi.registerTool(createAgentBrowserWebSearchTool(agentBrowserConfig));
1279
+ }
1270
1280
  }