fix(extension): avoid work for suppressed CDP logs
why
Addresses the logging-overhead portion of #3239. This does not close the whole issue: Runtime/DOM setup caching and element-handle reuse are intentionally out of scope.
Suppressed records currently reach schema validation, payload serialization and log-span creation. CDP calls and unsolicited events also serialize their debug payloads before the logger can filter them.
what changed
- Add an inexpensive
StagehandLogger.isEnabled()check and filter suppressed records before validation/serialization/span creation. Keep the final emission check so a data getter or span processor changing the level tooffstill prevents emission. - Guard expensive CDP debug payload construction for root calls, session calls and events. Custom
{ debug, error }loggers without a level query retain concrete-object payloads and their previous behavior. - Keep required wire serialization, enabled log data/context, response errors, and normal operation/request spans. Serialize the wire payload before registering inflight work so cyclic, BigInt or throwing-
toJSONinputs do not introduce retained pending requests. - Add deterministic regression tests, update tests that previously expected filtered log spans, and include extension/TypeScript/Python patch changesets.
test plan
Passed locally on Node 24.22.1:
- Focused logger/CDP/RPC tests: 43 passed. The first regression run against unmodified production code had 9 failures / 16 passes; the original focused suite passed before adding regressions.
- Complete extension unit suite: 1,074 passed, 9 todo across 68 files. Before publication, the patch applied cleanly to latest
main(59346d0); the extension suite again passed 1,074 tests, with extension build/typecheck and release-metadata checks passing. The compatibility run used two test workers after a parallel artifact-comparison timeout. - Independent adversarial harness: 28/28 passed, including dynamic levels, throwing getters, cyclic/BigInt/throwing-
toJSONpayloads, legacy custom loggers, scoped context, error rejection and operation-span preservation. - Extension build/typecheck,
just fmt, targeted formatting/lint, release metadata checks, Python generated-code drift/lock/ruff/type checks, andgit diff --check. - Workspace formatting/lint/typecheck excluding the docs validator: 42/42 tasks passed, using concurrency 2.
- Python suite: 1,052 passed, 5 skipped. The sandbox's SOCKS proxy required installing
socksiointo the local test environment only; no dependency manifests were changed. - SDK package-install contract passed with writable cache directories.
A deterministic 100-call mixed root/session harness measured parameter serialization 200 → 100, log spans 200 → 0, wire messages 100 → 100, and operation spans 1 → 1. These are work counts, not browser timing or end-to-end performance claims.
The full repository gates are not green in this sandbox. The docs validator cannot enumerate network interfaces; a root release test requires a blocked local tsx IPC socket; an eval-doctor test detects the sandbox's read-only Codex home; browser suites cannot launch Chromium (socket() EPERM) and a cross-version test cannot resolve the package registry. No unrelated code was changed to work around these restrictions. The broad test run completed with 37/42 tasks passing; its temporary SDK package-install failure passed separately after correcting cache locations.
Developed with AI assistance and independently reviewed by a separate AI agent. This is a draft for human review; the submitting contributor remains responsible for the change. No maintainer approval is claimed. External-contributor CI still requires the repository's normal team approval; this PR does not bypass that process.