chore: reconcile main into v4-spike ahead of the squash-merge - #2664
Conversation
# 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>
|
There was a problem hiding this comment.
All reported issues were addressed across 5 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…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
027eb0c to
7903814
Compare
…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).
Co-authored-by: Miguel <36487034+miguelg719@users.noreply.github.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Confidence score: 4/5
- In
packages/docs/v3/configuration/models.mdx, the callout text uses an em dash instead of the required colon format, so the docs may fail prose-guide compliance and create avoidable follow-up churn in publishing or lint checks — replace**(NEW) Model Gateway** —style punctuation with**(NEW) Model Gateway:**to align with the Stagehand docs standard.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/docs/v3/configuration/models.mdx">
<violation number="1">
P2: Custom agent: **Stagehand docs prose guide**
The callout prose uses an em dash, which the Stagehand docs prose guide explicitly prohibits. Replace it with a colon to keep the copy compliant: `**(NEW) Model Gateway:** Use your...`</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
0184cf7 to
4b932e9
Compare
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) into v4-spike's ancestry so the upcoming
v4-spike → mainsquash PR shows a clean, accurate diff.Net content diff: v3 Model Router docs only (
packages/docs/v3/configuration/models.mdx). The section is accurate for the v3 SDK it documents (stringmodel,model: "auto",disableAPI,experimentalare all v3 API); prose recast to active voice per the docs guide + review suggestions applied. The v4 docs page already covers v4's auto-routing (omitmodel) via #2642 / STG-2795.Everything else from main was either already deleted in v4 or deliberately excluded:
@browserbasehq/stagehandand would trigger a spurious 4.x bump).gh api -X PATCH repos/browserbase/stagehand -f allow_merge_commit=true), merge, then flip back.Verified locally:
pnpm checkgreen,check-changesetsgreen.