Skip to content

feat(#175): network response + dump commands for API flow capture#464

Open
giulio-leone wants to merge 4 commits intovercel-labs:mainfrom
giulio-leone:feat/175-network-response
Open

feat(#175): network response + dump commands for API flow capture#464
giulio-leone wants to merge 4 commits intovercel-labs:mainfrom
giulio-leone:feat/175-network-response

Conversation

@giulio-leone
Copy link
Contributor

@giulio-leone giulio-leone commented Feb 13, 2026

Closes #175

New Commands

network response <url> [--timeout <ms>]

Wait for and capture a response matching a URL pattern. Returns status code, headers, and parsed body.

network dump --out <path> [--filter <url>] [--host <domain>] [--type <types>] [--redact]

Export all tracked requests as structured JSON.

Enhanced network requests Filters

  • --host <domain> — Filter by hostname (substring match)
  • --type xhr,fetch — Filter by resource type (comma-separated)
  • --redact — Mask sensitive headers (Authorization, Cookie, Set-Cookie, X-Api-Key, X-Auth-Token)
  • --filter <url> — Existing URL substring filter (unchanged)

Implementation Details

  • Enhanced TrackedRequest with auto-increment IDs, status codes, response headers
  • WeakMap-based response matching (Playwright Request identity, not URL)
  • Idempotent tracking guard (isTrackingRequests)
  • Multi-page support: new pages auto-attach request listeners via setupPageTracking
  • Monotonically increasing IDs (never reset, even on clear)
  • Header redaction creates copies (never mutates original data)

Example Usage

# Track with filters
agent-browser network requests --host api.example.com --type xhr,fetch

# View specific response
agent-browser network response api.example.com/endpoint

# Export with redaction
agent-browser network dump --out ./flows.json --redact --host api.example.com

@vercel
Copy link
Contributor

vercel bot commented Feb 13, 2026

@g97iulio1609 is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Add networkdump command with host/type filters, header redaction,
idempotent tracking, WeakMap response matching, and monotonic IDs.

Refs: vercel-labs#175
@giulio-leone giulio-leone force-pushed the feat/175-network-response branch from 72f46f1 to 0c38cfb Compare March 1, 2026 03:42
Copilot AI review requested due to automatic review settings March 1, 2026 03:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds network inspection and export capabilities to the agent-browser CLI/protocol so users can capture API flows (requests + responses) during a browsing session, including new “network response” and “network dump” commands and enhanced request filtering/redaction.

Changes:

  • Extend request tracking to include monotonically increasing request IDs plus response status/headers, with multi-page listener attachment.
  • Add new protocol/types for networkdump and extend requests command options (host, type, redact).
  • Update CLI parsing to support network response and network dump, plus new network requests filters.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/types.ts Adds new command type (NetworkDumpCommand) and extends RequestsCommand options.
src/protocol.ts Adds Zod schema for networkdump and extends requests schema with new filters.
src/browser.ts Implements request IDs, response metadata capture, multi-page tracking, filtering, and redaction in getRequests.
src/actions.ts Wires the new networkdump action into dispatch and implements file export handler.
cli/src/commands.rs Adds CLI subcommands network response and network dump and extends network requests flags.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +494 to +499
getRequests(options?: {
filter?: string;
host?: string;
type?: string;
redact?: boolean;
}): TrackedRequest[] {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

getRequests was changed to accept an options object, but there are still call sites passing a plain string (e.g. the requests action handler). Without an overload/backwards-compat shim this will fail TypeScript compilation. Either keep a string overload (delegating to { filter }) or update all callers to the new { filter, host, type, redact } shape.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the latest commit. See the push for details.

Comment on lines 479 to 486
page.on('response', (response) => {
const reqId = requestMap.get(response.request());
if (reqId !== undefined) {
const tracked = this.trackedRequests.find((r) => r.id === reqId);
if (tracked) {
tracked.statusCode = response.status();
tracked.responseHeaders = response.headers();
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

In the response listener, updating the tracked entry uses this.trackedRequests.find(...), which makes response processing O(n) per response and can become noticeably slow on pages with lots of requests. Consider storing a direct reference (e.g., WeakMap<Request, TrackedRequest> or Map<number, TrackedRequest>) so the update is O(1).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the latest commit. See the push for details.

Comment on lines +573 to +574
case 'networkdump':
return await handleNetworkDump(command, browser);
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

New networkdump action will be categorized as unknown by the action policy system unless it’s added to ACTION_CATEGORIES (likely under 'network'). With a default-deny policy (or confirmation rules), this command may be unexpectedly blocked or treated differently than other network actions.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the latest commit. See the push for details.

Comment on lines +1982 to +1993
Some("response") => {
let url = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
context: "network response".to_string(),
usage: "network response <url> [--timeout <ms>]",
})?;
let timeout_idx = rest.iter().position(|&s| s == "--timeout");
let timeout = timeout_idx.and_then(|i| rest.get(i + 1).and_then(|s| s.parse::<u64>().ok()));
let mut cmd = json!({ "id": id, "action": "responsebody", "url": url });
if let Some(t) = timeout {
cmd["timeout"] = json!(t);
}
Ok(cmd)
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

network response is wired to the existing responsebody action, which currently returns { url, status, body } but not response headers. This doesn’t match the PR description/CLI docs that say headers are returned; either include headers in the responsebody response or adjust the command description/output expectations accordingly.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the latest commit. See the push for details.

- Use Map<number, TrackedRequest> for O(1) response matching instead of find()
- Add networkdump and responsebody to ACTION_CATEGORIES under network
- Include response headers in responsebody action output
Fixes TS2345: command.filter (string) is not assignable to the options
object parameter. Spread all RequestsCommand filter fields properly.
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.

Feature request: CLI command to capture & summarize API flows

2 participants