Skip to content

chore: reconcile main into v4-spike ahead of the squash-merge - #2664

Open
miguelg719 wants to merge 6 commits into
v4-spikefrom
chore/reconcile-main-into-v4-spike
Open

chore: reconcile main into v4-spike ahead of the squash-merge#2664
miguelg719 wants to merge 6 commits into
v4-spikefrom
chore/reconcile-main-into-v4-spike

Conversation

@miguelg719

@miguelg719 miguelg719 commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Merges the 4 commits main gained since v4-spike's last restack (browse@0.9.6 release, daemon-error fix, Model Router docs, touch-tap contrib #2385) so the upcoming v4-spike → main squash PR shows a clean, accurate diff.

⚠️ Merge this PR with a merge commit, not squash — the point is to get main's commits into v4-spike's ancestry; squashing would leave the divergence in place. Repo settings currently only allow squash; temporarily enable merge commits (gh api -X PATCH repos/browserbase/stagehand -f allow_merge_commit=true), merge, then flip back.

Resolution notes:

  • All 19 modify/delete conflicts (cli/core/server-v3 files that v4 removed) resolved as deleted; new-on-main test files under those dead packages dropped; the touch-tap changeset dropped (it names @browserbasehq/stagehand and would trigger a spurious 4.x bump).
  • Rename detection tried to carry the touch-tap primitives from Contrib/2384 #2385 into packages/extensiondeliberately reverted to the v4-spike versions. Porting tap to v4 is a separate follow-up PR (Linear ticket to come), not a side effect of the reconcile.
  • Net content diff vs v4-spike is docs-only: packages/docs/v3 Model Router updates.

Verified locally: pnpm check green (fmt/lint/typecheck), check-changesets green.

miguelg719 and others added 4 commits July 28, 2026 09:54
# why

`model: "auto"` shipped in #2328 but is undocumented. This adds a
**Model Router** section to `/v3/configuration/models`, nested under
**Model Gateway** right after **Setup**, plus a launch callout at the
top of the page.

# what changed

`packages/docs/v3/configuration/models.mdx` only — no code, so no
changeset.

- **`(NEW) Model Router` callout** at the top of the page, above the
Model Gateway one, linking to `#model-router`. Dropped `(NEW)` from the
Model Gateway callout so only one feature is flagged as new.
- **`### Model Router`** subsection: what it does, basic usage, Model
Gateway billing (market-price tokens on your Browserbase key), and the
30–40% cost reduction vs. pinning one frontier model.
- **`#### Requirements`** table covering the four API-only constraints
the constructor enforces (`env: "BROWSERBASE"`, `disableAPI: false`,
`experimental: false`, no `llmClient`), plus a warning that `"auto"` has
no local fallback if the API is unavailable at init.
- **`#### Per-call routing`**: `{ model: "auto" }` as a per-primitive
override on top of a concrete default, including the object form (`{
modelName: "auto", temperature: 0.5 }`) and the note that overrides
don't inherit the session provider/API key.
- Agent support: works in default `dom`/`hybrid`, **not** with `mode:
"cua"` (`"auto"` isn't in `AVAILABLE_CUA_MODELS`, so it throws
`CuaModelRequiredError`).
- Caching: local replay is skipped for `"auto"` sessions; the API's
server-side cache handles it.
- Troubleshooting accordion for both auto-specific errors, and an
env-var table row.

Behavior claims were taken from `modelUtils.ts`, `v3.ts`, `api.ts`,
`AgentCache.ts`, and `tests/unit/auto-model.test.ts`. The routing
heuristic itself is server-side and not in this repo, so the copy
deliberately stays general about how a model gets picked — nothing here
goes stale when the router changes.

# open question

Should omitting `model` entirely also route through Model Router?

Today it doesn't — `resolveModelConfiguration()` falls back to
`DEFAULT_MODEL_NAME = "openai/gpt-4.1-mini"`
(`packages/core/lib/v3/v3.ts:101,115`), so an omitted `model` pins
gpt-4.1-mini (run through Model Gateway if only a Browserbase key is
set). That's a fixed model, not per-call routing. I left the omit path
out of the docs for now. If the default should become `"auto"`, that's a
core change and the docs can follow alongside it.

# test plan

- `mintlify broken-links` — no new broken links (the 5 reported are
pre-existing and in other files)
- JSX components balanced, code fences even, heading nesting verified,
`#model-router` anchor resolves

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
## Summary

- translate daemon socket `ECONNREFUSED` and `ENOENT` failures into a
human-readable error
- print the exact `browse open` command that restarts the requested
session
- document that API keys are forwarded to an already-running daemon and
that `browse stop` is idempotent
- preserve regression coverage for late environment variables and
exit-code-zero cleanup

## Root cause

The daemon client passed raw Unix socket errors through to users when
the daemon disappeared between the readiness check and the request.
Agents received `ECONNREFUSED` without a recovery command.

## Impact

Agents now get an actionable `daemon_not_running` failure with the exact
command needed to restart the session. Recovery command arguments are
shell-quoted, and a daemon disappearing between status and stop is
treated as an already-stopped session. Cleanup synchronizes with daemon
startup so it preserves a replacement daemon that starts during the stop
race. The bundled SKILL.md also makes the already-fixed env timing and
stop behavior explicit.

## E2E Test Matrix

| Command / flow | Observed output | Confidence / sufficiency |
| --- | --- | --- |
| `pnpm --filter browse build` | TypeScript compilation and oclif
manifest generation completed successfully. | Proves the exact local CLI
code under review builds; does not exercise a live browser. |
| `pnpm --filter browse test:cli` | 25 test files passed; 366/366 tests
passed. This includes deterministic daemon disappearance/restart races,
adversarial recovery-command shell quoting, malformed CDP log payloads,
and the complete CLI contract suite. | Proves the full CLI suite passes
against the completed local build on macOS; GitHub CI provides the
Ubuntu/Windows matrix. |
| `BROWSE_DAEMON_DIR=<temp dir> node packages/cli/bin/run.js stop
--session no-daemon-smoke` | Exited `0` and printed `{ "stopped": false,
"session": "no-daemon-smoke" }`. | Exercises the built CLI's real
absent-daemon stop path and confirms its documented successful no-op
behavior. |
| `pnpm --filter browse lint` | Full-package Prettier, ESLint, and
TypeScript checks completed successfully. | Reproduces the CI lint
pipeline locally and verifies the daemon changes, log reducer, tests,
and inherited CLI lint baseline. |

Linear:
[GRO-1908](https://linear.app/browserbase/issue/GRO-1908/cli-namespace-2027-dev-suggested-docs-updates)

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Replaces raw socket errors with a clear `daemon_not_running` message and
prints the exact, shell-quoted `browse open` recovery command. `browse
stop` now treats a missing daemon as already stopped, validates
ownership before cleanup, and avoids tearing down a daemon that restarts
mid-race. Addresses Linear:
https://linear.app/browserbase/issue/GRO-1908/cli-namespace-2027-dev-suggested-docs-updates.

- **Bug Fixes**
- Map `ECONNREFUSED`/`ENOENT` to `daemon_not_running` and show the
precise, session-aware recovery command.
- Make `browse stop` idempotent and safe: if the daemon vanished (no
`--force`), return `{ stopped: false }`; acquire a lock and verify
daemon ownership before removing pid/socket/lock; preserve a replacement
daemon started during the stop race (handles PID reuse).
- Harden CDP log reduction: stricter parsing, ignore malformed payloads,
and require numeric response statuses.
- Docs: clarify `BROWSERBASE_API_KEY` is forwarded on every command and
`browse stop` is idempotent; add troubleshooting for the new error.
- Tests: cover the error message and shell-quoted recovery command
(round-tripped through `/bin/sh`), stop race cleanup and restart
preservation, PID reuse, and reduce-logs edge cases.

<sup>Written for commit 030c02a.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/browserbase/stagehand/pull/2356?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Shrey Pandya <shrey@browserbase.com>
Prepare the next browse release by versioning the package on `main`.

What this PR does:
- bumps `packages/cli/package.json` to `0.9.6`
- updates the browse changelog
- consumes the pending browse changesets

After this PR merges, the `Release` workflow on `main` will publish
`browse@0.9.6` from that exact commit using `pnpm pack` + `npm publish
--provenance`.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
# why

The CUA and hybrid agents dispatch every pointer action as mouse input.
Mobile layouts commonly gate their handlers on touch/pointer events, so
a synthesized mouse click never registers — e.g. on `adidas.co.il`
(Browserbase `os: "mobile"`) a size selector highlights but keeps
reporting "please choose a size", blocking add-to-cart. A trusted touch
(`Input.dispatchTouchEvent`) works.

Originates from #2384 by @alonle.

# what changed

- New `useTouch` option (explicit opt-in, default `false`). Forwarded to
the server on the API execution path.
- `page.tap(x, y)` and `locator.tap()`: trusted touch taps mirroring
their click counterparts.
- When `useTouch` is set: CUA routes single left clicks to tap
(right/middle/multi-click, hover, and drag stay on mouse); hybrid
`click`/`type`/`fillFormVision` tap for coordinate focus/activation.
- Replay: taps record as `tap` steps and replay as touch. `tap` is not
exposed to the LLM during live inference.

# test plan

- Unit: `touch-actuation` (7), `touch-tool-routing` (9),
`touch-cua-routing` (7) — resolution, tool routing, recording.
- E2E: `perform-understudy-method` (8) — asserts
`pointerdown:touch`/`touchstart`/`touchend` delivery for both tap paths
(event-level, since Chromium synthesizes a click from a tap and
activation-only assertions can't tell touch from mouse).
- Server: `start.test.ts` covers `useTouch` on `/sessions/start`.
- Manual: with `useTouch: true` on a Browserbase `os: "mobile"` session,
the agent completes the adidas.co.il size + add-to-cart flow.

---------

Co-authored-by: alonl <alonl@wix.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@miguelg719
miguelg719 requested a review from a team as a code owner August 9, 2026 22:33
@changeset-bot

changeset-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1f3d91a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/docs/v3/references/stagehand.mdx Outdated
Comment thread packages/docs/v3/configuration/models.mdx Outdated
Comment thread packages/extension/understudy/locator.ts Outdated
Comment thread packages/docs/v3/references/stagehand.mdx Outdated
Comment thread packages/docs/v3/configuration/models.mdx Outdated
…into-v4-spike

# Conflicts:
#	packages/cli/CHANGELOG.md
#	packages/cli/package.json
#	packages/cli/skills/browse/SKILL.md
#	packages/cli/src/lib/cloud/reduce-logs.ts
#	packages/cli/src/lib/driver/daemon/client.ts
#	packages/cli/tests/driver-foundation.test.ts
#	packages/core/lib/v3/agent/tools/click.ts
#	packages/core/lib/v3/agent/tools/fillFormVision.ts
#	packages/core/lib/v3/agent/tools/type.ts
#	packages/core/lib/v3/api.ts
#	packages/core/lib/v3/handlers/v3CuaAgentHandler.ts
#	packages/core/lib/v3/types/public/api.ts
#	packages/core/lib/v3/types/public/options.ts
#	packages/core/lib/v3/v3.ts
#	packages/core/tests/integration/perform-understudy-method.spec.ts
#	packages/server-v3/src/lib/InMemorySessionStore.ts
#	packages/server-v3/src/lib/SessionStore.ts
#	packages/server-v3/src/routes/v1/sessions/start.ts
#	packages/server-v3/tests/integration/v3/start.test.ts
@miguelg719
miguelg719 force-pushed the chore/reconcile-main-into-v4-spike branch from 027eb0c to 7903814 Compare August 9, 2026 23:00
Comment thread packages/docs/v3/references/stagehand.mdx Outdated
…active voice

useTouch documents an option no shipped surface consumes here — the
touch-tap port to v4 is a deliberate follow-up, so the v3 reference
page reverts to the v4-spike version. Model Router prose recast per
the docs prose guide (active voice).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants