Skip to content

feat(stagehand): expose typed network capture events - #2832

Draft
shrey150 wants to merge 2 commits into
mainfrom
agent/browse-v4-2-network-capture
Draft

feat(stagehand): expose typed network capture events#2832
shrey150 wants to merge 2 commits into
mainfrom
agent/browse-v4-2-network-capture

Conversation

@shrey150

@shrey150 shrey150 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Expose a public, typed page-scoped network stream for Browse and other Stagehand V4 clients.

  • page.on("network", listener) emits request, completion, and failure events.
  • Completion events include response metadata, duration, and best-effort response bodies.
  • Request keys include the CDP session ID, so identical request IDs in OOPIFs cannot collide.
  • Capture follows current and future page-owned OOPIF sessions.
  • Unsubscribe removes only this observer; it deliberately does not call Network.disable, because Stagehand navigation and networkidle share that domain.

Landing status

This public network-event API draft is intentionally not part of the Browse V4 landing stack. It remains open because it has already been shared for framework/API design review.

The Browse CLI restores its V3 network command through a CLI-private CDP sidecar in #2849, without depending on this PR or committing Stagehand to these schemas.

Landing stack: #2833#2834#2849#2835#2838#2839#2701

Review boundary

This is an independent core Stagehand API-design draft. No PR in the Browse V4 landing stack consumes it. The proposal extends the existing NetworkManager; TypeScript exports a discriminated PageNetworkEvent union, while Python and Go receive compatible generated additions. Review it on the merits of that long-lived public contract, not as migration plumbing.

Usage proven by E2E

The following standalone Stagehand script was typechecked and rerun against real Chromium on the cursor-free rewritten head c0de0a14c:

import {
  localBrowser,
  Stagehand,
  type PageNetworkEvent,
} from "@browserbasehq/stagehand";

const browser = await localBrowser.launch({ headless: true });
const stagehand = await Stagehand.create({ browser });
const pages = await stagehand.browser.context.pages();
const page = pages[0] ?? (await stagehand.browser.context.newPage());

const events: PageNetworkEvent[] = [];
const subscription = await page.on("network", (event) => {
  events.push(event);

  if (event.method === "Network.requestWillBeSent") {
    console.log(event.params.httpMethod, event.params.url, event.params.body);
  }
  if (event.method === "Network.loadingFinished") {
    console.log(event.params.status, event.params.mimeType, event.params.body);
  }
  if (event.method === "Network.loadingFailed") {
    console.error(event.params.errorText);
  }
});

await page.goto("https://example.com");
await subscription.unsubscribe();
await stagehand.close();
await browser.close();

E2E Test Matrix

Command / flow Observed output Confidence / sufficiency
Build the extension and TypeScript SDK, then typecheck and run the script above against real Chromium NETWORK_STREAM_PASS; document title Network E2E Proves the public SDK API is executable, not only mocked
Page load plus POST /api/data 3 Network.requestWillBeSent and 3 Network.loadingFinished events Proves the page-level stream exposes the network firehose used by Browse
Inspect the captured POST Method POST, path /api/data, body {"probe":"network-firehose"} Proves request bodies are available
Inspect the captured response Status 200, MIME application/json, body {"value":"network-body-ok"}, base64Encoded: false Proves response metadata and best-effort bodies are available
Call subscription.unsubscribe(), then issue more traffic No further delivery to the listener Proves observer cleanup without disrupting the shared Network domain
Protocol, extension, SDK, Python, and Go checks Unit/type/build/generator-drift checks passed, including OOPIF request-ID collision coverage Covers cross-language shape and OOPIF bookkeeping beyond the main-frame browser smoke
Exact cursor-free rewritten head 4 files / 135 network, protocol, extension, and SDK tests passed Proves removing the unrelated cursor API did not disturb the network event contract

The real-browser smoke covers a local main page. OOPIF collision handling, redirects/failures, and cross-language generation are covered by automated tests rather than a second live-browser fixture.

@changeset-bot

changeset-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c0de0a1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@browserbasehq/stagehand-protocol Patch
@browserbasehq/stagehand-python Patch
@browserbasehq/stagehand-extension Patch
@browserbasehq/stagehand-go Patch
@browserbasehq/stagehand Patch
@browserbasehq/stagehand-integrations Patch
@browserbasehq/stagehand-integrations-example-eve-facade Patch
@browserbasehq/stagehand-integrations-example-pi-facade Patch
@browserbasehq/stagehand-integrations-example-claude-code-facade Patch
@browserbasehq/stagehand-integrations-example-codex-facade Patch
@browserbasehq/stagehand-integrations-example-mastra-facade Patch
@browserbasehq/stagehand-integrations-example-vercel-ai-facade Patch

Not sure what this means? Click here to learn what changesets are.

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

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.

1 participant