@browserbasehq/orca 3.5.0-preview.1 → 3.5.1-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +7 -3
  2. package/dist/cjs/lib/utils.d.ts +2 -0
  3. package/dist/cjs/lib/utils.js +20 -0
  4. package/dist/cjs/lib/utils.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/AgentProvider.js +1 -0
  6. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  7. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +1 -0
  8. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  9. package/dist/cjs/lib/v3/api.js +28 -33
  10. package/dist/cjs/lib/v3/api.js.map +1 -1
  11. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.d.ts +24 -24
  12. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js +24 -24
  13. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
  14. package/dist/cjs/lib/v3/dom/locatorScripts/xpathResolver.js +79 -10
  15. package/dist/cjs/lib/v3/dom/locatorScripts/xpathResolver.js.map +1 -1
  16. package/dist/cjs/lib/v3/index.d.ts +2 -1
  17. package/dist/cjs/lib/v3/llm/LLMProvider.js +18 -2
  18. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  19. package/dist/cjs/lib/v3/types/public/agent.d.ts +2 -2
  20. package/dist/cjs/lib/v3/types/public/agent.js +1 -0
  21. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  22. package/dist/cjs/lib/v3/types/public/api.d.ts +538 -27
  23. package/dist/cjs/lib/v3/types/public/api.js +83 -7
  24. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  25. package/dist/cjs/lib/v3/types/public/clipboard.d.ts +15 -0
  26. package/dist/cjs/lib/v3/types/public/clipboard.js +3 -0
  27. package/dist/cjs/lib/v3/types/public/clipboard.js.map +1 -0
  28. package/dist/cjs/lib/v3/types/public/index.d.ts +1 -0
  29. package/dist/cjs/lib/v3/types/public/index.js +1 -0
  30. package/dist/cjs/lib/v3/types/public/index.js.map +1 -1
  31. package/dist/cjs/lib/v3/types/public/model.d.ts +18 -3
  32. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  33. package/dist/cjs/lib/v3/types/public/page.d.ts +29 -0
  34. package/dist/cjs/lib/v3/types/public/page.js.map +1 -1
  35. package/dist/cjs/lib/v3/types/public/sdkErrors.d.ts +3 -0
  36. package/dist/cjs/lib/v3/types/public/sdkErrors.js +8 -2
  37. package/dist/cjs/lib/v3/types/public/sdkErrors.js.map +1 -1
  38. package/dist/cjs/lib/v3/understudy/clipboard.d.ts +24 -0
  39. package/dist/cjs/lib/v3/understudy/clipboard.js +166 -0
  40. package/dist/cjs/lib/v3/understudy/clipboard.js.map +1 -0
  41. package/dist/cjs/lib/v3/understudy/context.d.ts +3 -0
  42. package/dist/cjs/lib/v3/understudy/context.js +15 -0
  43. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  44. package/dist/cjs/lib/v3/understudy/page.d.ts +23 -1
  45. package/dist/cjs/lib/v3/understudy/page.js +283 -0
  46. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  47. package/dist/cjs/lib/v3/v3.js +15 -6
  48. package/dist/cjs/lib/v3/v3.js.map +1 -1
  49. package/dist/cjs/lib/version.d.ts +1 -1
  50. package/dist/cjs/lib/version.js +1 -1
  51. package/dist/cjs/lib/version.js.map +1 -1
  52. package/dist/esm/lib/utils.d.ts +2 -0
  53. package/dist/esm/lib/utils.js +18 -0
  54. package/dist/esm/lib/utils.js.map +1 -1
  55. package/dist/esm/lib/v3/agent/AgentProvider.js +1 -0
  56. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  57. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +1 -0
  58. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  59. package/dist/esm/lib/v3/api.js +29 -34
  60. package/dist/esm/lib/v3/api.js.map +1 -1
  61. package/dist/esm/lib/v3/dom/build/locatorScripts.generated.d.ts +24 -24
  62. package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js +24 -24
  63. package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
  64. package/dist/esm/lib/v3/dom/locatorScripts/xpathResolver.js +79 -10
  65. package/dist/esm/lib/v3/dom/locatorScripts/xpathResolver.js.map +1 -1
  66. package/dist/esm/lib/v3/index.d.ts +2 -1
  67. package/dist/esm/lib/v3/llm/LLMProvider.js +18 -2
  68. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  69. package/dist/esm/lib/v3/types/public/agent.d.ts +2 -2
  70. package/dist/esm/lib/v3/types/public/agent.js +1 -0
  71. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  72. package/dist/esm/lib/v3/types/public/api.d.ts +538 -27
  73. package/dist/esm/lib/v3/types/public/api.js +81 -5
  74. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  75. package/dist/esm/lib/v3/types/public/clipboard.d.ts +15 -0
  76. package/dist/esm/lib/v3/types/public/clipboard.js +2 -0
  77. package/dist/esm/lib/v3/types/public/clipboard.js.map +1 -0
  78. package/dist/esm/lib/v3/types/public/index.d.ts +1 -0
  79. package/dist/esm/lib/v3/types/public/index.js +1 -0
  80. package/dist/esm/lib/v3/types/public/index.js.map +1 -1
  81. package/dist/esm/lib/v3/types/public/model.d.ts +18 -3
  82. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  83. package/dist/esm/lib/v3/types/public/page.d.ts +29 -0
  84. package/dist/esm/lib/v3/types/public/page.js.map +1 -1
  85. package/dist/esm/lib/v3/types/public/sdkErrors.d.ts +3 -0
  86. package/dist/esm/lib/v3/types/public/sdkErrors.js +5 -0
  87. package/dist/esm/lib/v3/types/public/sdkErrors.js.map +1 -1
  88. package/dist/esm/lib/v3/understudy/clipboard.d.ts +24 -0
  89. package/dist/esm/lib/v3/understudy/clipboard.js +163 -0
  90. package/dist/esm/lib/v3/understudy/clipboard.js.map +1 -0
  91. package/dist/esm/lib/v3/understudy/context.d.ts +3 -0
  92. package/dist/esm/lib/v3/understudy/context.js +15 -0
  93. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  94. package/dist/esm/lib/v3/understudy/page.d.ts +23 -1
  95. package/dist/esm/lib/v3/understudy/page.js +284 -1
  96. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  97. package/dist/esm/lib/v3/v3.js +16 -7
  98. package/dist/esm/lib/v3/v3.js.map +1 -1
  99. package/dist/esm/lib/version.d.ts +1 -1
  100. package/dist/esm/lib/version.js +1 -1
  101. package/dist/esm/lib/version.js.map +1 -1
  102. package/package.json +13 -7
@@ -73,8 +73,49 @@ const LIFECYCLE_NAME = {
73
73
  domcontentloaded: "DOMContentLoaded",
74
74
  networkidle: "networkIdle",
75
75
  };
76
+ const WEB_MCP_SUPPORT_MESSAGE = "Make sure you are using Chrome/Chromium newer than version 149 and that it is launched with --enable-features=WebMCPTesting,DevToolsWebMCPSupport.";
77
+ function createDeferred() {
78
+ let resolve;
79
+ let reject;
80
+ const promise = new Promise((res, rej) => {
81
+ resolve = res;
82
+ reject = rej;
83
+ });
84
+ return { promise, resolve, reject };
85
+ }
86
+ function stripWebMCPToolDebugFields(tool) {
87
+ const { name, description, inputSchema, annotations, frameId } = tool;
88
+ const publicAnnotations = annotations === undefined ? undefined : { ...annotations };
89
+ return {
90
+ name,
91
+ ...(description !== undefined && { description }),
92
+ ...(inputSchema !== undefined && { inputSchema }),
93
+ ...(publicAnnotations !== undefined && { annotations: publicAnnotations }),
94
+ frameId,
95
+ };
96
+ }
97
+ function webMCPResultFromEvent(invocationId, event) {
98
+ return {
99
+ invocationId,
100
+ status: event.status ?? "Error",
101
+ ...(event.output !== undefined && { output: event.output }),
102
+ ...(event.errorText !== undefined && { errorText: event.errorText }),
103
+ ...(event.exception !== undefined && { exception: event.exception }),
104
+ };
105
+ }
106
+ function isWebMCPUnsupportedBrowserError(error) {
107
+ if (error instanceof sdkErrors_js_1.StagehandUnsupportedBrowserFeatureError)
108
+ return true;
109
+ const code = error?.code;
110
+ if (code === -32601)
111
+ return true;
112
+ const message = error instanceof Error ? error.message : String(error);
113
+ return /method not found/i.test(message);
114
+ }
76
115
  let Page = (() => {
77
116
  let _instanceExtraInitializers = [];
117
+ let _listWebMCPTools_decorators;
118
+ let _invokeWebMCPTool_decorators;
78
119
  let _close_decorators;
79
120
  let _goto_decorators;
80
121
  let _reload_decorators;
@@ -94,6 +135,8 @@ let Page = (() => {
94
135
  return class Page {
95
136
  static {
96
137
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
138
+ _listWebMCPTools_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageListWebMCPTools" })];
139
+ _invokeWebMCPTool_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageInvokeWebMCPTool" })];
97
140
  _close_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageClose" })];
98
141
  _goto_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageGoto" })];
99
142
  _reload_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageReload" })];
@@ -120,6 +163,8 @@ let Page = (() => {
120
163
  _type_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageType" })];
121
164
  _keyPress_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageKeyPress" })];
122
165
  _snapshot_decorators = [FlowLogger_js_1.FlowLogger.wrapWithLogging({ eventType: "PageSnapshot" })];
166
+ __esDecorate(this, null, _listWebMCPTools_decorators, { kind: "method", name: "listWebMCPTools", static: false, private: false, access: { has: obj => "listWebMCPTools" in obj, get: obj => obj.listWebMCPTools }, metadata: _metadata }, null, _instanceExtraInitializers);
167
+ __esDecorate(this, null, _invokeWebMCPTool_decorators, { kind: "method", name: "invokeWebMCPTool", static: false, private: false, access: { has: obj => "invokeWebMCPTool" in obj, get: obj => obj.invokeWebMCPTool }, metadata: _metadata }, null, _instanceExtraInitializers);
123
168
  __esDecorate(this, null, _close_decorators, { kind: "method", name: "close", static: false, private: false, access: { has: obj => "close" in obj, get: obj => obj.close }, metadata: _metadata }, null, _instanceExtraInitializers);
124
169
  __esDecorate(this, null, _goto_decorators, { kind: "method", name: "goto", static: false, private: false, access: { has: obj => "goto" in obj, get: obj => obj.goto }, metadata: _metadata }, null, _instanceExtraInitializers);
125
170
  __esDecorate(this, null, _reload_decorators, { kind: "method", name: "reload", static: false, private: false, access: { has: obj => "reload" in obj, get: obj => obj.reload }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -164,6 +209,10 @@ let Page = (() => {
164
209
  apiClient = null;
165
210
  consoleListeners = new Set();
166
211
  consoleHandlers = new Map();
212
+ webMCPEnablePromise = null;
213
+ pendingWebMCPInvocations = new Map();
214
+ bufferedWebMCPResults = new Map();
215
+ pendingWebMCPInvokeToolResponses = 0;
167
216
  /** Document-start scripts installed across every session this page owns. */
168
217
  initScripts = [];
169
218
  extraHTTPHeaders;
@@ -517,6 +566,154 @@ let Page = (() => {
517
566
  }
518
567
  return this;
519
568
  }
569
+ onWebMCPToolResponded = (event) => {
570
+ if (!event.invocationId)
571
+ return;
572
+ const result = webMCPResultFromEvent(event.invocationId, event);
573
+ const pending = this.pendingWebMCPInvocations.get(event.invocationId);
574
+ if (!pending) {
575
+ /*
576
+ * WebMCP.invokeTool returns the invocationId, while WebMCP.toolResponded
577
+ * is a separate event. Very fast tools can emit the event before the
578
+ * invokeTool command response reaches us, so there is not yet a pending
579
+ * invocation entry to resolve. Buffer only during that command-response
580
+ * window; otherwise unmatched events are stale or unexpected.
581
+ */
582
+ if (this.pendingWebMCPInvokeToolResponses > 0) {
583
+ this.bufferedWebMCPResults.set(event.invocationId, result);
584
+ }
585
+ return;
586
+ }
587
+ clearTimeout(pending.timer);
588
+ this.pendingWebMCPInvocations.delete(event.invocationId);
589
+ pending.deferred.resolve(result);
590
+ };
591
+ async ensureWebMCPEnabled() {
592
+ if (this.webMCPEnablePromise) {
593
+ return this.webMCPEnablePromise;
594
+ }
595
+ this.mainSession.on("WebMCP.toolResponded", this.onWebMCPToolResponded);
596
+ this.webMCPEnablePromise = this.mainSession
597
+ .send("WebMCP.enable")
598
+ .then(() => undefined)
599
+ .catch((error) => {
600
+ this.teardownWebMCP();
601
+ const message = error instanceof Error ? error.message : String(error);
602
+ if (isWebMCPUnsupportedBrowserError(error)) {
603
+ throw new sdkErrors_js_1.StagehandUnsupportedBrowserFeatureError("WebMCP", `Unable to enable WebMCP. ${WEB_MCP_SUPPORT_MESSAGE} CDP error: ${message}`, error);
604
+ }
605
+ throw error;
606
+ });
607
+ return this.webMCPEnablePromise;
608
+ }
609
+ /**
610
+ * `WebMCP.enable` is the browser's source-of-truth snapshot trigger: CDP emits
611
+ * `WebMCP.toolsAdded` for all tools currently registered on the page. Keep
612
+ * this scoped to the list call so tools from old documents are not cached here.
613
+ */
614
+ async collectWebMCPToolsSnapshot(timeoutMs) {
615
+ const quietWindowMs = Math.min(100, Math.max(0, timeoutMs));
616
+ const tools = new Map();
617
+ let toolsVersion = 0;
618
+ let toolsLastUpdatedAt = null;
619
+ const toolKey = (tool) => `${tool.frameId}:${tool.name}`;
620
+ const onToolsAdded = (event) => {
621
+ if (!Array.isArray(event.tools))
622
+ return;
623
+ let changed = false;
624
+ for (const tool of event.tools) {
625
+ const normalized = stripWebMCPToolDebugFields(tool);
626
+ tools.set(toolKey(normalized), normalized);
627
+ changed = true;
628
+ }
629
+ if (!changed)
630
+ return;
631
+ toolsVersion += 1;
632
+ toolsLastUpdatedAt = Date.now();
633
+ schedule?.();
634
+ };
635
+ const onToolsRemoved = (event) => {
636
+ if (!Array.isArray(event.tools))
637
+ return;
638
+ let changed = false;
639
+ for (const tool of event.tools) {
640
+ changed = tools.delete(toolKey(tool)) || changed;
641
+ }
642
+ if (!changed)
643
+ return;
644
+ toolsVersion += 1;
645
+ toolsLastUpdatedAt = Date.now();
646
+ schedule?.();
647
+ };
648
+ const deadline = Date.now() + timeoutMs;
649
+ let schedule = null;
650
+ this.mainSession.on("WebMCP.toolsAdded", onToolsAdded);
651
+ this.mainSession.on("WebMCP.toolsRemoved", onToolsRemoved);
652
+ try {
653
+ await this.mainSession.send("WebMCP.enable");
654
+ if (quietWindowMs === 0)
655
+ return [...tools.values()];
656
+ await new Promise((resolve) => {
657
+ const startVersion = toolsVersion;
658
+ let quietTimer = null;
659
+ let timeoutTimer = null;
660
+ let done = false;
661
+ const cleanup = () => {
662
+ if (done)
663
+ return;
664
+ done = true;
665
+ if (quietTimer)
666
+ clearTimeout(quietTimer);
667
+ if (timeoutTimer)
668
+ clearTimeout(timeoutTimer);
669
+ resolve();
670
+ };
671
+ schedule = () => {
672
+ if (done)
673
+ return;
674
+ if (quietTimer) {
675
+ clearTimeout(quietTimer);
676
+ quietTimer = null;
677
+ }
678
+ const now = Date.now();
679
+ if (now >= deadline) {
680
+ cleanup();
681
+ return;
682
+ }
683
+ const sawToolsSinceStart = toolsVersion > startVersion;
684
+ const lastUpdate = toolsLastUpdatedAt;
685
+ const quietRemaining = sawToolsSinceStart && lastUpdate !== null
686
+ ? Math.max(0, quietWindowMs - (now - lastUpdate))
687
+ : quietWindowMs;
688
+ quietTimer = setTimeout(cleanup, Math.min(quietRemaining, deadline - now));
689
+ };
690
+ timeoutTimer = setTimeout(cleanup, timeoutMs);
691
+ schedule();
692
+ });
693
+ }
694
+ finally {
695
+ this.mainSession.off("WebMCP.toolsAdded", onToolsAdded);
696
+ this.mainSession.off("WebMCP.toolsRemoved", onToolsRemoved);
697
+ }
698
+ return [...tools.values()];
699
+ }
700
+ cleanupWebMCPInvocation(invocationId) {
701
+ const pending = this.pendingWebMCPInvocations.get(invocationId);
702
+ if (!pending)
703
+ return;
704
+ clearTimeout(pending.timer);
705
+ this.pendingWebMCPInvocations.delete(invocationId);
706
+ }
707
+ teardownWebMCP() {
708
+ this.mainSession.off("WebMCP.toolResponded", this.onWebMCPToolResponded);
709
+ for (const [invocationId, pending] of this.pendingWebMCPInvocations) {
710
+ clearTimeout(pending.timer);
711
+ pending.deferred.reject(new sdkErrors_js_1.StagehandInvalidArgumentError(`WebMCP invocation "${invocationId}" was disposed before it completed.`));
712
+ }
713
+ this.pendingWebMCPInvocations.clear();
714
+ this.bufferedWebMCPResults.clear();
715
+ this.webMCPEnablePromise = null;
716
+ }
520
717
  // ---------------- MAIN APIs ----------------
521
718
  targetId() {
522
719
  return this._targetId;
@@ -543,6 +740,90 @@ let Page = (() => {
543
740
  sendCDP(method, params) {
544
741
  return this.mainSession.send(method, params);
545
742
  }
743
+ /**
744
+ * List WebMCP tools registered by the current page.
745
+ * CDP emits WebMCP.toolsAdded for all currently registered tools each time
746
+ * WebMCP.enable is called, so this method treats the browser as the source of
747
+ * truth and collects that per-call snapshot instead of keeping a tool cache.
748
+ */
749
+ async listWebMCPTools(options) {
750
+ const timeoutMs = options?.timeoutMs ?? 1_000;
751
+ try {
752
+ return await this.collectWebMCPToolsSnapshot(timeoutMs);
753
+ }
754
+ catch (error) {
755
+ if (error instanceof sdkErrors_js_1.StagehandUnsupportedBrowserFeatureError)
756
+ throw error;
757
+ const message = error instanceof Error ? error.message : String(error);
758
+ if (isWebMCPUnsupportedBrowserError(error)) {
759
+ throw new sdkErrors_js_1.StagehandUnsupportedBrowserFeatureError("WebMCP", `Unable to list WebMCP tools. ${WEB_MCP_SUPPORT_MESSAGE} CDP error: ${message}`, error);
760
+ }
761
+ throw error;
762
+ }
763
+ }
764
+ async invokeWebMCPTool(toolName, input, options) {
765
+ const timeoutMs = options?.timeoutMs ?? 30_000;
766
+ let frameId = options?.frameId;
767
+ if (!frameId) {
768
+ const matchingTools = (await this.listWebMCPTools()).filter((tool) => tool.name === toolName);
769
+ if (matchingTools.length === 0) {
770
+ throw new sdkErrors_js_1.StagehandInvalidArgumentError(`Unable to invoke WebMCP tool "${toolName}" because it was not found on the current page.`);
771
+ }
772
+ if (matchingTools.length > 1) {
773
+ throw new sdkErrors_js_1.StagehandInvalidArgumentError(`Unable to invoke WebMCP tool "${toolName}" because multiple frames registered a tool with that name. Pass options.frameId to disambiguate.`);
774
+ }
775
+ frameId = matchingTools[0].frameId;
776
+ }
777
+ const deferred = createDeferred();
778
+ let invocationId;
779
+ await this.ensureWebMCPEnabled();
780
+ try {
781
+ this.pendingWebMCPInvokeToolResponses += 1;
782
+ const response = await this.mainSession
783
+ .send("WebMCP.invokeTool", {
784
+ frameId,
785
+ toolName,
786
+ input,
787
+ })
788
+ .finally(() => {
789
+ this.pendingWebMCPInvokeToolResponses -= 1;
790
+ });
791
+ invocationId = response.invocationId;
792
+ }
793
+ catch (error) {
794
+ const message = error instanceof Error ? error.message : String(error);
795
+ if (isWebMCPUnsupportedBrowserError(error)) {
796
+ throw new sdkErrors_js_1.StagehandUnsupportedBrowserFeatureError("WebMCP", `Unable to invoke WebMCP tool "${toolName}". ${WEB_MCP_SUPPORT_MESSAGE} CDP error: ${message}`, error);
797
+ }
798
+ throw error;
799
+ }
800
+ const bufferedResult = this.bufferedWebMCPResults.get(invocationId);
801
+ if (bufferedResult) {
802
+ this.bufferedWebMCPResults.delete(invocationId);
803
+ deferred.resolve(bufferedResult);
804
+ }
805
+ else {
806
+ const timer = setTimeout(() => {
807
+ this.cleanupWebMCPInvocation(invocationId);
808
+ deferred.reject(new sdkErrors_js_1.StagehandInvalidArgumentError(`Timed out waiting for WebMCP tool "${toolName}" invocation result after ${timeoutMs}ms.`));
809
+ }, timeoutMs);
810
+ this.pendingWebMCPInvocations.set(invocationId, {
811
+ deferred,
812
+ timer,
813
+ });
814
+ }
815
+ return {
816
+ invocationId,
817
+ toolName,
818
+ frameId,
819
+ result: deferred.promise,
820
+ cancel: async () => {
821
+ await this.mainSession.send("WebMCP.cancelInvocation", {
822
+ invocationId,
823
+ });
824
+ },
825
+ };
826
+ }
546
827
  /** Seed the cached URL before navigation events converge. */
547
828
  seedCurrentUrl(url) {
548
829
  if (!url)
@@ -579,6 +860,7 @@ let Page = (() => {
579
860
  const targets = await this.conn.getTargets();
580
861
  if (!targets.some((t) => t.targetId === this._targetId)) {
581
862
  this.networkManager.dispose();
863
+ this.teardownWebMCP();
582
864
  return;
583
865
  }
584
866
  }
@@ -588,6 +870,7 @@ let Page = (() => {
588
870
  await new Promise((r) => setTimeout(r, 25));
589
871
  }
590
872
  this.networkManager.dispose();
873
+ this.teardownWebMCP();
591
874
  this.removeAllConsoleTaps();
592
875
  this.consoleListeners.clear();
593
876
  }