agents 0.27.0 → 0.28.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 (193) hide show
  1. package/dist/abortable-C1SpfVoi.js +21 -0
  2. package/dist/abortable-C1SpfVoi.js.map +1 -0
  3. package/dist/{agent-routing-Bhdbvf7s.d.ts → agent-routing-QDcchcQP.d.ts} +10 -15
  4. package/dist/agent-routing.d.ts +1 -1
  5. package/dist/agent-tool-types.d.ts +1 -1
  6. package/dist/{agent-tools-bJZwBMfq.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
  7. package/dist/agent-tools.d.ts +1 -1
  8. package/dist/ai-ahruGw7e.d.ts +239 -0
  9. package/dist/{ai-sdk-OoGkFy3s.js → ai-sdk-Bdsf6mSA.js} +2 -2
  10. package/dist/{ai-sdk-OoGkFy3s.js.map → ai-sdk-Bdsf6mSA.js.map} +1 -1
  11. package/dist/browser/ai.d.ts +8 -227
  12. package/dist/browser/ai.js +259 -1
  13. package/dist/browser/ai.js.map +1 -0
  14. package/dist/browser/index.d.ts +56 -46
  15. package/dist/browser/index.js +4 -361
  16. package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
  17. package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +5 -4
  18. package/dist/browser/tools/ai-sdk.js.map +1 -0
  19. package/dist/browser/tools/pi.d.ts +111 -0
  20. package/dist/browser/tools/pi.js +119 -0
  21. package/dist/browser/tools/pi.js.map +1 -0
  22. package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
  23. package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
  24. package/dist/browser/tools/tanstack-ai.js.map +1 -0
  25. package/dist/browser-CEdNlsaD.js +481 -0
  26. package/dist/browser-CEdNlsaD.js.map +1 -0
  27. package/dist/{browser-tmkcAAI3.d.ts → browser-D30VlpcA.d.ts} +63 -37
  28. package/dist/{browser-tool-CBqs6hqa.js → browser-tool-4iomavs_.js} +145 -49
  29. package/dist/browser-tool-4iomavs_.js.map +1 -0
  30. package/dist/{browser-tool-Bn-nzJQI.d.ts → browser-tool-vtrPOV8e.d.ts} +24 -5
  31. package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
  32. package/dist/capability-DBAKc6UZ.js.map +1 -0
  33. package/dist/{capability-runner-O5VbQzqg.d.ts → capability-runner-BiVUtjqC.d.ts} +1 -7
  34. package/dist/chat/index.d.ts +4 -4
  35. package/dist/chat/index.js +1 -1
  36. package/dist/chat-sdk/index.d.ts +1 -1
  37. package/dist/chat-sdk/index.js +1 -1
  38. package/dist/{client-DS3Dz9l0.d.ts → client-BGIQKJhX.d.ts} +2 -2
  39. package/dist/{client-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
  40. package/dist/client-BnYbNT3z.js.map +1 -0
  41. package/dist/client.d.ts +1 -1
  42. package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
  43. package/dist/connector-CtZylXdk.js.map +1 -0
  44. package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
  45. package/dist/{conversations-DH0ut_8n.d.ts → conversations-FjHDRZyD.d.ts} +4 -4
  46. package/dist/{current-agent-C07C5o5Y.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
  47. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  48. package/dist/{durable-object-lifecycle-DRqp475_.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
  49. package/dist/experimental/channels/index.d.ts +2 -2
  50. package/dist/experimental/channels/index.js +2 -2
  51. package/dist/experimental/channels/web/index.d.ts +2 -2
  52. package/dist/experimental/channels/web/index.js +1 -1
  53. package/dist/{gateway-BDC07gYO.d.ts → gateway-BFO6vRDn.d.ts} +2 -2
  54. package/dist/harness/ai-sdk/index.d.ts +2 -2
  55. package/dist/harness/ai-sdk/index.js +1 -1
  56. package/dist/harness/container/index.d.ts +2 -2
  57. package/dist/harness/container/index.js +3 -3
  58. package/dist/harness/opencode/index.d.ts +1 -1
  59. package/dist/harness/opencode/index.js +2 -2
  60. package/dist/harness/pi/index.d.ts +2 -2
  61. package/dist/harness/pi/index.js +3 -3
  62. package/dist/harness/store/index.d.ts +1 -1
  63. package/dist/harness/store/index.js +1 -1
  64. package/dist/harness/think/index.d.ts +2 -2
  65. package/dist/harness/think/index.js +363 -171
  66. package/dist/harness/think/index.js.map +1 -1
  67. package/dist/{index-D0A5tbWu.d.ts → index-BEL3ZV-s.d.ts} +2 -6
  68. package/dist/{index-Ib_4dwOo.d.ts → index-CBt8oRJt.d.ts} +3 -5
  69. package/dist/index.d.ts +4 -4
  70. package/dist/index.js +2 -2
  71. package/dist/input-schema-BQykTEp_.js +20 -0
  72. package/dist/input-schema-BQykTEp_.js.map +1 -0
  73. package/dist/{input-schema-DNrpTu49.js → input-schema-D2QAtHZH.js} +3 -3
  74. package/dist/input-schema-D2QAtHZH.js.map +1 -0
  75. package/dist/internal_context.d.ts +1 -1
  76. package/dist/lifecycle/index.d.ts +3 -3
  77. package/dist/lifecycle/index.js +2 -2
  78. package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
  79. package/dist/lifecycle-DGorpAmA.js.map +1 -0
  80. package/dist/mcp/client/index.d.ts +1 -1
  81. package/dist/mcp/client/index.js +1 -1
  82. package/dist/mcp/index.d.ts +1 -1
  83. package/dist/mcp/index.js +2 -2
  84. package/dist/models/ai-sdk/index.js +1 -1
  85. package/dist/models/opencode/index.js +1 -1
  86. package/dist/models/pi-ai/index.js +1 -1
  87. package/dist/{options-pwTNq9z6.d.ts → options-CiIsJHXR.d.ts} +2 -6
  88. package/dist/queue/index.d.ts +1 -1
  89. package/dist/queue/index.js +1 -1
  90. package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
  91. package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
  92. package/dist/react.d.ts +2 -2
  93. package/dist/routing/index.d.ts +2 -2
  94. package/dist/routing/index.js +1 -1
  95. package/dist/{scheduler-CrFCnv_J.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
  96. package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
  97. package/dist/scheduler-FIHv2-kJ.js.map +1 -0
  98. package/dist/schedules/index.d.ts +1 -1
  99. package/dist/schedules/index.js +1 -1
  100. package/dist/serializable.d.ts +1 -1
  101. package/dist/session-store-Do4xkDcf.js +606 -0
  102. package/dist/session-store-Do4xkDcf.js.map +1 -0
  103. package/dist/session-store-DoPY12xM.d.ts +383 -0
  104. package/dist/sessions/index.d.ts +1 -1
  105. package/dist/sessions/index.js +1 -1
  106. package/dist/{sessions-B9pNuxdT.js → sessions-_vN5BEZX.js} +2 -2
  107. package/dist/{sessions-B9pNuxdT.js.map → sessions-_vN5BEZX.js.map} +1 -1
  108. package/dist/{src-DgCbZtIR.js → src-CQxJFv4l.js} +8 -8
  109. package/dist/src-CQxJFv4l.js.map +1 -0
  110. package/dist/state/index.d.ts +1 -1
  111. package/dist/state/index.js +1 -3
  112. package/dist/state/index.js.map +1 -1
  113. package/dist/{store-DLeqKuj3.d.ts → store-BKM4Xm9M.d.ts} +23 -1
  114. package/dist/{store-vgcPYo8K.js → store-CslVzfN7.js} +28 -2
  115. package/dist/store-CslVzfN7.js.map +1 -0
  116. package/dist/streams/index.d.ts +1 -1
  117. package/dist/streams/index.js +1 -1
  118. package/dist/{streams-CITClVer.js → streams-lsHMJhRW.js} +2 -2
  119. package/dist/{streams-CITClVer.js.map → streams-lsHMJhRW.js.map} +1 -1
  120. package/dist/{streams-fbG61qM8.d.ts → streams-vrCtbUIn.d.ts} +2 -2
  121. package/dist/sub-routing.d.ts +1 -1
  122. package/dist/tasks/index.d.ts +1 -1
  123. package/dist/tasks/index.js +1 -1
  124. package/dist/{tasks-CkTZNaV1.js → tasks-BN_5AWqI.js} +2 -2
  125. package/dist/{tasks-CkTZNaV1.js.map → tasks-BN_5AWqI.js.map} +1 -1
  126. package/dist/{tasks-PtlB4Uyn.d.ts → tasks-E89KdwkS.d.ts} +2 -2
  127. package/dist/{tool-BPJEbwaX.d.ts → tool-CTp72Jb_.d.ts} +4 -4
  128. package/dist/tool-CxKsvxjm.js +1126 -0
  129. package/dist/tool-CxKsvxjm.js.map +1 -0
  130. package/dist/tool-DoVberpN.d.ts +301 -0
  131. package/dist/{tool-3PA8xjB_.js → tool-cQRkwSZZ.js} +6 -17
  132. package/dist/tool-cQRkwSZZ.js.map +1 -0
  133. package/dist/tool-helpers-O5BDVEAY.js +58 -0
  134. package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
  135. package/dist/voice/index.d.ts +2 -2
  136. package/dist/web/fetch/index.d.ts +89 -0
  137. package/dist/web/fetch/index.js +20 -0
  138. package/dist/web/fetch/index.js.map +1 -0
  139. package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
  140. package/dist/web/fetch/tools/ai-sdk.js +47 -0
  141. package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
  142. package/dist/web/fetch/tools/pi.d.ts +84 -0
  143. package/dist/web/fetch/tools/pi.js +88 -0
  144. package/dist/web/fetch/tools/pi.js.map +1 -0
  145. package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
  146. package/dist/web/fetch/tools/tanstack-ai.js +45 -0
  147. package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
  148. package/dist/{websearch → web/search}/index.d.ts +1 -1
  149. package/dist/{websearch → web/search}/index.js +1 -1
  150. package/dist/{websearch → web/search}/tools/ai-sdk.d.ts +2 -2
  151. package/dist/{websearch → web/search}/tools/ai-sdk.js +3 -3
  152. package/dist/web/search/tools/ai-sdk.js.map +1 -0
  153. package/dist/{websearch → web/search}/tools/pi.d.ts +3 -3
  154. package/dist/{websearch → web/search}/tools/pi.js +2 -2
  155. package/dist/web/search/tools/pi.js.map +1 -0
  156. package/dist/{websearch → web/search}/tools/tanstack-ai.d.ts +2 -2
  157. package/dist/{websearch → web/search}/tools/tanstack-ai.js +3 -3
  158. package/dist/web/search/tools/tanstack-ai.js.map +1 -0
  159. package/dist/websockets/index.d.ts +2 -2
  160. package/dist/websockets/index.js +1 -1
  161. package/dist/{websockets-CmENGb-Z.js → websockets-C3zy8YR0.js} +3 -5
  162. package/dist/websockets-C3zy8YR0.js.map +1 -0
  163. package/dist/workflow-types.d.ts +1 -1
  164. package/dist/workflows.d.ts +1 -1
  165. package/dist/workflows.js +1 -1
  166. package/docs/browse-the-web.md +26 -1
  167. package/docs/fetch-the-web.md +276 -0
  168. package/docs/harnesses/pi.md +25 -0
  169. package/docs/index.md +99 -76
  170. package/docs/lifecycle.md +2 -3
  171. package/docs/queue.md +2 -3
  172. package/docs/scheduling.md +2 -6
  173. package/docs/search-the-web.md +2 -0
  174. package/package.json +44 -19
  175. package/dist/ai-fm7xx1BK.js +0 -312
  176. package/dist/ai-fm7xx1BK.js.map +0 -1
  177. package/dist/browser/ai-sdk.js.map +0 -1
  178. package/dist/browser/index.js.map +0 -1
  179. package/dist/browser/tanstack-ai.js.map +0 -1
  180. package/dist/browser-tool-CBqs6hqa.js.map +0 -1
  181. package/dist/capability-B4WbF81e.js.map +0 -1
  182. package/dist/client-1tEQ1Oqz.js.map +0 -1
  183. package/dist/connector-58XDGvc3.js.map +0 -1
  184. package/dist/input-schema-DNrpTu49.js.map +0 -1
  185. package/dist/lifecycle-CFu6OV03.js.map +0 -1
  186. package/dist/scheduler-DZ3xQfeK.js.map +0 -1
  187. package/dist/src-DgCbZtIR.js.map +0 -1
  188. package/dist/store-vgcPYo8K.js.map +0 -1
  189. package/dist/tool-3PA8xjB_.js.map +0 -1
  190. package/dist/websearch/tools/ai-sdk.js.map +0 -1
  191. package/dist/websearch/tools/pi.js.map +0 -1
  192. package/dist/websearch/tools/tanstack-ai.js.map +0 -1
  193. package/dist/websockets-CmENGb-Z.js.map +0 -1
@@ -0,0 +1,606 @@
1
+ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
2
+ import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
+ import { Validator } from "@cfworker/json-schema";
4
+ //#region src/browser/cdp-connection.ts
5
+ const DEFAULT_TIMEOUT_MS = 1e4;
6
+ /** JSON-RPC's "method not found" code, which Chrome also uses for CDP. */
7
+ const CDP_METHOD_NOT_FOUND = -32601;
8
+ /** The browser answered a command with a JSON-RPC error. */
9
+ var CdpProtocolError = class extends Error {
10
+ constructor(method, code, message) {
11
+ super(`CDP error ${code ?? "unknown"}: ${message} for ${method}`);
12
+ this.name = "CdpProtocolError";
13
+ this.code = code;
14
+ this.method = method;
15
+ }
16
+ };
17
+ const MAX_DEBUG_ENTRIES = 400;
18
+ var _socket = /* @__PURE__ */ new WeakMap();
19
+ var _nextId = /* @__PURE__ */ new WeakMap();
20
+ var _pending = /* @__PURE__ */ new WeakMap();
21
+ var _debugLog = /* @__PURE__ */ new WeakMap();
22
+ var _defaultTimeoutMs = /* @__PURE__ */ new WeakMap();
23
+ var _dispose = /* @__PURE__ */ new WeakMap();
24
+ var _disposed = /* @__PURE__ */ new WeakMap();
25
+ var _onActivity = /* @__PURE__ */ new WeakMap();
26
+ var _CdpConnection_brand = /* @__PURE__ */ new WeakSet();
27
+ /**
28
+ * One Chrome DevTools Protocol connection over an open WebSocket. Manages
29
+ * command correlation, timeouts, per-tab CDP sessions, and a debug event
30
+ * ring buffer.
31
+ *
32
+ * Used host-side (not in the sandbox) — the sandbox calls into this
33
+ * via DynamicWorkerExecutor's ToolDispatcher RPC.
34
+ */
35
+ var CdpConnection = class {
36
+ constructor(socket, optionsOrTimeoutMs, onClose, sessionId) {
37
+ _classPrivateMethodInitSpec(this, _CdpConnection_brand);
38
+ _classPrivateFieldInitSpec(this, _socket, void 0);
39
+ _classPrivateFieldInitSpec(this, _nextId, 1);
40
+ _classPrivateFieldInitSpec(this, _pending, /* @__PURE__ */ new Map());
41
+ _classPrivateFieldInitSpec(this, _debugLog, []);
42
+ _classPrivateFieldInitSpec(this, _defaultTimeoutMs, void 0);
43
+ _classPrivateFieldInitSpec(this, _dispose, void 0);
44
+ _classPrivateFieldInitSpec(this, _disposed, false);
45
+ _classPrivateFieldInitSpec(this, _onActivity, void 0);
46
+ const options = typeof optionsOrTimeoutMs === "object" ? optionsOrTimeoutMs : {
47
+ timeoutMs: optionsOrTimeoutMs,
48
+ onClose,
49
+ sessionId
50
+ };
51
+ _classPrivateFieldSet2(_socket, this, socket);
52
+ _classPrivateFieldSet2(_defaultTimeoutMs, this, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
53
+ _classPrivateFieldSet2(_dispose, this, options.onClose);
54
+ this.sessionId = options.sessionId;
55
+ _classPrivateFieldSet2(_onActivity, this, options.onActivity);
56
+ socket.addEventListener("message", (event) => _assertClassBrand(_CdpConnection_brand, this, _handleMessage).call(this, event));
57
+ socket.addEventListener("error", () => {
58
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP socket error"));
59
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
60
+ });
61
+ socket.addEventListener("close", () => {
62
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP connection closed"));
63
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
64
+ });
65
+ }
66
+ send(method, params, options = {}) {
67
+ var _this$nextId, _this$nextId2;
68
+ _classPrivateFieldGet2(_onActivity, this)?.call(this);
69
+ const id = (_classPrivateFieldSet2(_nextId, this, (_this$nextId = _classPrivateFieldGet2(_nextId, this), _this$nextId2 = _this$nextId++, _this$nextId)), _this$nextId2);
70
+ const timeoutMs = options.timeoutMs ?? _classPrivateFieldGet2(_defaultTimeoutMs, this);
71
+ const sessionId = typeof options.sessionId === "string" && options.sessionId.length > 0 ? options.sessionId : void 0;
72
+ const domain = typeof method === "string" ? method.split(".")[0] : "";
73
+ if (!sessionId && domain && !["Browser", "Target"].includes(domain)) _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "warning", {
74
+ id,
75
+ method,
76
+ reason: "target-scoped method sent without sessionId"
77
+ });
78
+ const result = new Promise((resolve, reject) => {
79
+ const startedAt = performance.now();
80
+ const timeoutId = setTimeout(() => {
81
+ _classPrivateFieldGet2(_pending, this).delete(id);
82
+ reject(/* @__PURE__ */ new Error(`CDP command timed out after ${timeoutMs}ms: ${method}`));
83
+ }, timeoutMs);
84
+ _classPrivateFieldGet2(_pending, this).set(id, {
85
+ resolve,
86
+ reject,
87
+ timeoutId,
88
+ method,
89
+ sessionId,
90
+ startedAt
91
+ });
92
+ });
93
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "send", {
94
+ id,
95
+ method,
96
+ sessionId,
97
+ timeoutMs
98
+ });
99
+ try {
100
+ _classPrivateFieldGet2(_socket, this).send(JSON.stringify({
101
+ id,
102
+ method,
103
+ params,
104
+ sessionId
105
+ }));
106
+ } catch (error) {
107
+ const pending = _classPrivateFieldGet2(_pending, this).get(id);
108
+ if (pending) {
109
+ clearTimeout(pending.timeoutId);
110
+ _classPrivateFieldGet2(_pending, this).delete(id);
111
+ pending.reject(error instanceof Error ? error : new Error(String(error)));
112
+ }
113
+ }
114
+ return result;
115
+ }
116
+ async attachToTarget(targetId, options = {}) {
117
+ if (typeof targetId !== "string" || !targetId) throw new Error("attachToTarget requires a targetId — list open tabs with send('Target.getTargets') or create one with send('Target.createTarget', { url })");
118
+ const sessionId = (await this.send("Target.attachToTarget", {
119
+ targetId,
120
+ flatten: true
121
+ }, { timeoutMs: options.timeoutMs }))?.sessionId ?? "";
122
+ if (!sessionId) throw new Error(`Target.attachToTarget did not return a sessionId for target ${targetId}`);
123
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "attach", {
124
+ targetId,
125
+ sessionId
126
+ });
127
+ return sessionId;
128
+ }
129
+ getDebugLog(limit = 50) {
130
+ const normalized = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 50;
131
+ return _classPrivateFieldGet2(_debugLog, this).slice(-normalized);
132
+ }
133
+ clearDebugLog() {
134
+ _classPrivateFieldSet2(_debugLog, this, []);
135
+ }
136
+ disconnect() {
137
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP session disconnected"));
138
+ try {
139
+ _classPrivateFieldGet2(_socket, this).close(1e3, "Done");
140
+ } catch {}
141
+ }
142
+ close() {
143
+ this.disconnect();
144
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
145
+ }
146
+ };
147
+ /**
148
+ * Run the dispose callback exactly once, on the first terminal event —
149
+ * an explicit {@link close}, peer closure, or a socket error.
150
+ */
151
+ function _runDispose() {
152
+ if (_classPrivateFieldGet2(_disposed, this)) return;
153
+ _classPrivateFieldSet2(_disposed, this, true);
154
+ _classPrivateFieldGet2(_dispose, this)?.call(this);
155
+ }
156
+ function _rejectAll(error) {
157
+ for (const [id, pending] of _classPrivateFieldGet2(_pending, this).entries()) {
158
+ clearTimeout(pending.timeoutId);
159
+ _classPrivateFieldGet2(_pending, this).delete(id);
160
+ pending.reject(error);
161
+ }
162
+ }
163
+ function _handleMessage(event) {
164
+ if (typeof event.data !== "string") return;
165
+ let payload;
166
+ try {
167
+ payload = JSON.parse(event.data);
168
+ } catch {
169
+ return;
170
+ }
171
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "receive", {
172
+ id: payload.id,
173
+ method: payload.method,
174
+ sessionId: payload.sessionId,
175
+ hasError: !!payload.error
176
+ });
177
+ if (typeof payload.id !== "number") return;
178
+ const pending = _classPrivateFieldGet2(_pending, this).get(payload.id);
179
+ if (!pending) return;
180
+ clearTimeout(pending.timeoutId);
181
+ _classPrivateFieldGet2(_pending, this).delete(payload.id);
182
+ if (payload.error) {
183
+ const err = payload.error;
184
+ pending.reject(new CdpProtocolError(pending.method, typeof err.code === "number" ? err.code : void 0, err.message ?? "CDP error"));
185
+ return;
186
+ }
187
+ pending.resolve(payload.result);
188
+ }
189
+ function _recordDebug(type, data) {
190
+ _classPrivateFieldGet2(_debugLog, this).push({
191
+ at: (/* @__PURE__ */ new Date()).toISOString(),
192
+ type,
193
+ ...data
194
+ });
195
+ if (_classPrivateFieldGet2(_debugLog, this).length > MAX_DEBUG_ENTRIES) _classPrivateFieldGet2(_debugLog, this).splice(0, _classPrivateFieldGet2(_debugLog, this).length - MAX_DEBUG_ENTRIES);
196
+ }
197
+ const LOCALHOST_HOSTS = /* @__PURE__ */ new Set([
198
+ "localhost",
199
+ "127.0.0.1",
200
+ "0.0.0.0",
201
+ "::1",
202
+ "[::1]"
203
+ ]);
204
+ /**
205
+ * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).
206
+ * Discovers the WebSocket debugger URL via /json/version,
207
+ * rewrites localhost URLs to the base URL host, and opens the WebSocket.
208
+ *
209
+ * Useful for local development with `chrome --remote-debugging-port=9222`
210
+ * or when connecting through a tunnel.
211
+ */
212
+ async function connectUrl(baseUrl, options) {
213
+ const endpoint = new URL("/json/version", baseUrl).toString();
214
+ const response = await fetch(endpoint, { headers: options?.headers });
215
+ if (!response.ok) throw new Error(`Failed to discover CDP endpoint at ${endpoint}: ${response.status}`);
216
+ const payload = await response.json();
217
+ if (!payload.webSocketDebuggerUrl) throw new Error("CDP /json/version did not include webSocketDebuggerUrl");
218
+ let wsUrl = payload.webSocketDebuggerUrl;
219
+ const parsed = new URL(wsUrl);
220
+ if (LOCALHOST_HOSTS.has(parsed.hostname)) {
221
+ const base = new URL(baseUrl);
222
+ parsed.hostname = base.hostname;
223
+ parsed.port = base.port;
224
+ parsed.protocol = base.protocol;
225
+ } else parsed.protocol = parsed.protocol === "wss:" ? "https:" : "http:";
226
+ const fetchUrl = parsed.toString();
227
+ const wsResponse = await fetch(fetchUrl, { headers: {
228
+ ...options?.headers,
229
+ Upgrade: "websocket"
230
+ } });
231
+ const ws = wsResponse.webSocket;
232
+ if (!ws) throw new Error(`Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`);
233
+ ws.accept();
234
+ return new CdpConnection(ws, { timeoutMs: options?.timeoutMs });
235
+ }
236
+ /** @deprecated Renamed to {@link CdpConnection}. */
237
+ const CdpSession = CdpConnection;
238
+ //#endregion
239
+ //#region src/browser/browser-run.ts
240
+ var BrowserRenderingError = class extends Error {
241
+ constructor(message, status) {
242
+ super(message);
243
+ this.status = status;
244
+ this.name = "BrowserRenderingError";
245
+ }
246
+ };
247
+ /**
248
+ * Whether an error means the platform session is gone: Browser Run uses 404
249
+ * for unknown ids and 410 after `keep_alive` expiry.
250
+ */
251
+ function isMissingBrowserSession(error) {
252
+ return error instanceof BrowserRenderingError && (error.status === 404 || error.status === 410);
253
+ }
254
+ function browserSessionEndpoint(sessionId, options) {
255
+ const path = sessionId ? `/v1/devtools/browser/${sessionId}` : "/v1/devtools/browser";
256
+ const url = new URL(`https://localhost${path}`);
257
+ if (options?.keepAliveMs !== void 0) url.searchParams.set("keep_alive", String(options.keepAliveMs));
258
+ if (options?.includeTargets) url.searchParams.set("targets", "true");
259
+ if (options?.recording) url.searchParams.set("recording", "true");
260
+ if (options?.browser) url.searchParams.set("browser", options.browser);
261
+ return url.toString();
262
+ }
263
+ async function parseBrowserSessionInfo(response) {
264
+ const payload = await response.json();
265
+ const sessionId = typeof payload.sessionId === "string" ? payload.sessionId : "";
266
+ if (!sessionId) throw new Error("Browser Rendering response did not include a sessionId");
267
+ return {
268
+ sessionId,
269
+ targets: Array.isArray(payload.targets) ? payload.targets : void 0,
270
+ webSocketDebuggerUrl: typeof payload.webSocketDebuggerUrl === "string" ? payload.webSocketDebuggerUrl : void 0
271
+ };
272
+ }
273
+ async function createBrowserSession(browser, options) {
274
+ const response = await browser.fetch(browserSessionEndpoint(void 0, options), {
275
+ method: "POST",
276
+ headers: { "Content-Type": "application/json" },
277
+ body: JSON.stringify(options?.guardrails ? { guardrails: options.guardrails } : {})
278
+ });
279
+ if (!response.ok) throw new BrowserRenderingError(`Failed to create Browser Rendering session: ${response.status}`, response.status);
280
+ return parseBrowserSessionInfo(response);
281
+ }
282
+ async function listBrowserTargets(browser, sessionId) {
283
+ const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/list`);
284
+ if (!response.ok) throw new BrowserRenderingError(`Failed to list Browser Rendering targets for ${sessionId}: ${response.status}`, response.status);
285
+ const payload = await response.json();
286
+ return Array.isArray(payload) ? payload : [];
287
+ }
288
+ async function deleteBrowserSession(browser, sessionId) {
289
+ const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, { method: "DELETE" });
290
+ if (!response.ok && response.status !== 404) throw new BrowserRenderingError(`Failed to delete Browser Rendering session ${sessionId}: ${response.status}`, response.status);
291
+ }
292
+ /**
293
+ * Connect to a Browser Rendering session and delete it when closed.
294
+ */
295
+ async function connectBrowser(browser, options) {
296
+ const normalizedOptions = typeof options === "number" ? { timeoutMs: options } : options ?? {};
297
+ if (normalizedOptions.browser === "kitesurf") {
298
+ const smuggled = normalizedOptions;
299
+ if (smuggled.keepAliveMs || smuggled.includeTargets || smuggled.recording) throw new Error("Kitesurf does not support keepAliveMs, includeTargets, or recording");
300
+ }
301
+ const response = await browser.fetch(browserSessionEndpoint(void 0, normalizedOptions.browser === "kitesurf" ? { browser: "kitesurf" } : {
302
+ keepAliveMs: normalizedOptions.keepAliveMs,
303
+ includeTargets: normalizedOptions.includeTargets,
304
+ recording: normalizedOptions.recording
305
+ }), { headers: { Upgrade: "websocket" } });
306
+ const ws = response.webSocket;
307
+ if (!ws) throw new Error("Browser Rendering binding did not return a WebSocket. Ensure the 'browser' binding is configured in wrangler.jsonc.");
308
+ if (normalizedOptions.browser === "kitesurf") {
309
+ ws.accept();
310
+ return new CdpConnection(ws, { timeoutMs: normalizedOptions.timeoutMs });
311
+ }
312
+ const sessionId = response.headers.get("cf-browser-session-id");
313
+ if (!sessionId) throw new Error("Browser Rendering binding did not include a session ID when opening the CDP WebSocket");
314
+ ws.accept();
315
+ return new CdpConnection(ws, {
316
+ timeoutMs: normalizedOptions.timeoutMs,
317
+ onClose: () => {
318
+ deleteBrowserSession(browser, sessionId).catch((error) => {
319
+ console.warn(`[agents/browser] Failed to delete one-shot Browser Run session ${sessionId}`, error);
320
+ });
321
+ },
322
+ sessionId
323
+ });
324
+ }
325
+ /**
326
+ * Fetch a Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/)
327
+ * by session id, via the Browser Rendering REST API.
328
+ *
329
+ * A recording is only available **after** the session closes (explicit
330
+ * `closeSession()`, idle `keep_alive` expiry, or sweep) and is retained for 30
331
+ * days. Capture the session id while the session is alive — e.g. from
332
+ * `connector.liveView()`/`sessionInfo()` — then call this once it has ended.
333
+ *
334
+ * Unlike the binding-based helpers, this hits `api.cloudflare.com` directly, so
335
+ * it needs an account id and an API token with `Browser Rendering` read access
336
+ * (the Workers Browser Run binding cannot read recordings).
337
+ */
338
+ async function getBrowserRecording(options) {
339
+ const { accountId, apiToken, sessionId } = options;
340
+ const response = await (options.fetchImpl ?? fetch)(`https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/recording/${sessionId}`, { headers: { Authorization: `Bearer ${apiToken}` } });
341
+ if (!response.ok) throw new BrowserRenderingError(`Failed to fetch Browser Run recording for ${sessionId}: ${response.status}`, response.status);
342
+ const payload = await response.json();
343
+ return "result" in payload && payload.result ? payload.result : payload;
344
+ }
345
+ async function connectBrowserSession(browser, sessionId, options) {
346
+ const normalized = typeof options === "number" ? { timeoutMs: options } : options ?? {};
347
+ const response = await browser.fetch(browserSessionEndpoint(sessionId), { headers: { Upgrade: "websocket" } });
348
+ const ws = response.webSocket;
349
+ if (!ws) throw new BrowserRenderingError(`Browser Rendering binding did not return a WebSocket for session ${sessionId} (${response.status})`, response.status);
350
+ ws.accept();
351
+ return new CdpConnection(ws, {
352
+ timeoutMs: normalized.timeoutMs,
353
+ onClose: normalized.onClose,
354
+ sessionId,
355
+ onActivity: normalized.onActivity
356
+ });
357
+ }
358
+ //#endregion
359
+ //#region src/browser/connector-validation.ts
360
+ function formatToolValidationError(connector, tool, errors) {
361
+ const specific = errors.filter((error) => error.keyword !== "properties");
362
+ return `Invalid arguments for ${connector}.${tool}${(specific.length > 0 ? specific : errors).map((error) => {
363
+ const location = error.instanceLocation.replace(/^#\/?/, "").replaceAll("~1", "/").replaceAll("~0", "~").replaceAll("/", ".");
364
+ return `${location ? ` at ${location}` : ""}: ${error.error}`;
365
+ }).join(";")}`;
366
+ }
367
+ /**
368
+ * Validate a connector tool's arguments against its input schema before it
369
+ * runs, so the model gets a precise error instead of a failure deep inside
370
+ * browser work. An omitted argument counts as `{}`: argumentless tools are
371
+ * documented as `cdp.spec()`.
372
+ */
373
+ function validateConnectorArgs(connector, name, tool) {
374
+ if (!tool.inputSchema) return tool;
375
+ const schema = tool.inputSchema;
376
+ const validator = new Validator(schema, "7", false);
377
+ return {
378
+ ...tool,
379
+ execute: async (args, ctx) => {
380
+ const input = args === void 0 ? {} : args;
381
+ const result = validator.validate(input);
382
+ if (!result.valid) throw new Error(formatToolValidationError(connector, name, result.errors));
383
+ return await tool.execute(input, ctx);
384
+ }
385
+ };
386
+ }
387
+ //#endregion
388
+ //#region src/browser/live-view.ts
389
+ /**
390
+ * Browser Run mints `devtoolsFrontendUrl`s (the Live View links) that are
391
+ * valid for ~5 minutes. We surface the window so callers can decide how long
392
+ * a shared link is good for before re-listing targets.
393
+ */
394
+ const LIVE_VIEW_URL_TTL_MS = 300 * 1e3;
395
+ /**
396
+ * Rewrite the hosted Live View UI's `mode` query param (`tab` | `devtools`).
397
+ * The raw `devtoolsFrontendUrl` is returned unchanged when no mode is asked
398
+ * for or the URL can't be parsed.
399
+ */
400
+ function applyLiveViewMode(rawUrl, mode) {
401
+ if (!mode) return rawUrl;
402
+ try {
403
+ const url = new URL(rawUrl);
404
+ url.searchParams.set("mode", mode === "devtools" ? "devtools" : "tab");
405
+ return url.toString();
406
+ } catch {
407
+ return rawUrl;
408
+ }
409
+ }
410
+ /**
411
+ * Project a fresh target listing into Live View links — one per tab that has
412
+ * a `devtoolsFrontendUrl`. Pure; the caller supplies just-listed targets.
413
+ */
414
+ function createLiveView(sessionId, targets, mode) {
415
+ return {
416
+ sessionId,
417
+ targets: targets.filter((target) => target.devtoolsFrontendUrl).map((target) => ({
418
+ targetId: target.id,
419
+ url: applyLiveViewMode(target.devtoolsFrontendUrl, mode),
420
+ pageUrl: target.url,
421
+ title: target.title,
422
+ type: target.type
423
+ })),
424
+ expiresInMs: LIVE_VIEW_URL_TTL_MS
425
+ };
426
+ }
427
+ //#endregion
428
+ //#region src/browser/spec.ts
429
+ const MISSING_BROWSER_CONFIG = "Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided";
430
+ const urlSpecCache = /* @__PURE__ */ new Map();
431
+ const bindingSpecCache = /* @__PURE__ */ new WeakMap();
432
+ const CACHE_TTL_MS = 300 * 1e3;
433
+ /** Qualify a same-domain `$ref` (`"FrameId"` → `"Page.FrameId"`). */
434
+ function qualifyRef(domain, ref) {
435
+ if (ref === void 0) return void 0;
436
+ return ref.includes(".") ? ref : `${domain}.${ref}`;
437
+ }
438
+ function normalizeItems(domain, items) {
439
+ if (!items) return void 0;
440
+ return {
441
+ type: items.type,
442
+ $ref: qualifyRef(domain, items.$ref),
443
+ enum: items.enum
444
+ };
445
+ }
446
+ function normalizeFields(domain, fields) {
447
+ return (fields ?? []).map((field) => ({
448
+ name: field.name,
449
+ description: field.description,
450
+ optional: field.optional,
451
+ experimental: field.experimental,
452
+ deprecated: field.deprecated,
453
+ type: field.type,
454
+ $ref: qualifyRef(domain, field.$ref),
455
+ enum: field.enum,
456
+ items: normalizeItems(domain, field.items)
457
+ }));
458
+ }
459
+ function normalizeCdpSpec(spec) {
460
+ return { domains: (spec.domains ?? []).map(({ domain, ...raw }) => ({
461
+ name: domain,
462
+ description: raw.description,
463
+ experimental: raw.experimental,
464
+ deprecated: raw.deprecated,
465
+ commands: (raw.commands ?? []).map((command) => ({
466
+ name: command.name,
467
+ method: `${domain}.${command.name}`,
468
+ description: command.description,
469
+ experimental: command.experimental,
470
+ deprecated: command.deprecated,
471
+ parameters: normalizeFields(domain, command.parameters),
472
+ returns: normalizeFields(domain, command.returns)
473
+ })),
474
+ events: (raw.events ?? []).map((event) => ({
475
+ name: event.name,
476
+ event: `${domain}.${event.name}`,
477
+ description: event.description,
478
+ experimental: event.experimental,
479
+ deprecated: event.deprecated,
480
+ parameters: normalizeFields(domain, event.parameters)
481
+ })),
482
+ types: (raw.types ?? []).map((type) => ({
483
+ id: type.id,
484
+ name: `${domain}.${type.id}`,
485
+ description: type.description,
486
+ experimental: type.experimental,
487
+ deprecated: type.deprecated,
488
+ type: type.type,
489
+ enum: type.enum,
490
+ properties: normalizeFields(domain, type.properties),
491
+ items: normalizeItems(domain, type.items)
492
+ }))
493
+ })) };
494
+ }
495
+ function getSpecCacheKey(source, headers) {
496
+ const headerEntries = Object.entries(headers ?? {}).sort(([a], [b]) => a.localeCompare(b));
497
+ return `${source}:${JSON.stringify(headerEntries)}`;
498
+ }
499
+ async function getCachedSpec(cache, key, load) {
500
+ const cached = cache.get(key);
501
+ if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) return cached.spec;
502
+ const spec = normalizeCdpSpec(await load());
503
+ cache.set(key, {
504
+ spec,
505
+ cachedAt: Date.now()
506
+ });
507
+ return spec;
508
+ }
509
+ async function fetchCdpSpecFromUrl(cdpBaseUrl, headers) {
510
+ const endpoint = new URL("/json/protocol", cdpBaseUrl).toString();
511
+ return getCachedSpec(urlSpecCache, getSpecCacheKey(endpoint, headers), async () => {
512
+ const response = await fetch(endpoint, { headers });
513
+ if (!response.ok) throw new Error(`Failed to fetch CDP spec from ${endpoint}: ${response.status}`);
514
+ return await response.json();
515
+ });
516
+ }
517
+ async function fetchCdpSpecFromSession(browser, sessionId) {
518
+ return getCachedSpec(bindingSpecCache, browser, async () => {
519
+ const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/protocol`);
520
+ if (!response.ok) throw new Error(`Failed to fetch CDP spec from Browser Rendering: ${response.status}`);
521
+ return await response.json();
522
+ });
523
+ }
524
+ async function fetchCdpSpecFromBrowser(browser) {
525
+ return getCachedSpec(bindingSpecCache, browser, async () => {
526
+ const createResponse = await browser.fetch("https://localhost/v1/devtools/browser", { method: "POST" });
527
+ if (!createResponse.ok) throw new Error(`Failed to create Browser Rendering session for protocol fetch: ${createResponse.status}`);
528
+ const sessionId = (await createResponse.json()).sessionId;
529
+ if (!sessionId) throw new Error("Browser Rendering session response did not include a sessionId");
530
+ try {
531
+ const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/protocol`);
532
+ if (!response.ok) throw new Error(`Failed to fetch CDP spec from Browser Rendering: ${response.status}`);
533
+ return await response.json();
534
+ } finally {
535
+ try {
536
+ await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, { method: "DELETE" });
537
+ } catch {}
538
+ }
539
+ });
540
+ }
541
+ /** Load the (cached) searchable CDP spec for a browser source. */
542
+ async function loadCdpSpec(source) {
543
+ if (source.cdpUrl) return fetchCdpSpecFromUrl(source.cdpUrl, source.cdpHeaders);
544
+ if (source.browser && source.sessionId) return fetchCdpSpecFromSession(source.browser, source.sessionId);
545
+ if (source.browser) return fetchCdpSpecFromBrowser(source.browser);
546
+ throw new Error(MISSING_BROWSER_CONFIG);
547
+ }
548
+ //#endregion
549
+ //#region src/browser/session-store.ts
550
+ var _DurableBrowserSessionStore_brand = /* @__PURE__ */ new WeakSet();
551
+ var DurableBrowserSessionStore = class {
552
+ constructor(storage) {
553
+ this.storage = storage;
554
+ _classPrivateMethodInitSpec(this, _DurableBrowserSessionStore_brand);
555
+ }
556
+ async acquireLock(key) {
557
+ let queues = _queues._.get(this.storage);
558
+ if (!queues) {
559
+ queues = /* @__PURE__ */ new Map();
560
+ _queues._.set(this.storage, queues);
561
+ }
562
+ const previous = queues.get(key) ?? Promise.resolve();
563
+ let releaseQueue = () => void 0;
564
+ const current = previous.then(() => new Promise((resolve) => {
565
+ releaseQueue = resolve;
566
+ }));
567
+ queues.set(key, current);
568
+ await previous;
569
+ let released = false;
570
+ return { release: () => {
571
+ if (released) return;
572
+ released = true;
573
+ if (queues.get(key) === current) queues.delete(key);
574
+ releaseQueue();
575
+ } };
576
+ }
577
+ async get(key) {
578
+ return this.storage.get(_assertClassBrand(_DurableBrowserSessionStore_brand, this, _storageKey).call(this, key));
579
+ }
580
+ async set(key, session) {
581
+ await this.storage.put(_assertClassBrand(_DurableBrowserSessionStore_brand, this, _storageKey).call(this, key), session);
582
+ }
583
+ async delete(key) {
584
+ await this.storage.delete(_assertClassBrand(_DurableBrowserSessionStore_brand, this, _storageKey).call(this, key));
585
+ }
586
+ async list(prefix) {
587
+ const storagePrefix = _assertClassBrand(_DurableBrowserSessionStore_brand, this, _storageKey).call(this, prefix);
588
+ const entries = await this.storage.list({ prefix: storagePrefix });
589
+ const result = /* @__PURE__ */ new Map();
590
+ for (const [storageKey, value] of entries) result.set(storageKey.slice(16), value);
591
+ return result;
592
+ }
593
+ };
594
+ function _storageKey(key) {
595
+ return `browser-session:${key}`;
596
+ }
597
+ var _queues = { _: /* @__PURE__ */ new WeakMap() };
598
+ /**
599
+ * Default idle window used by {@link BrowserConnector.sweep} for the shared
600
+ * (reuse/promoted) session entry.
601
+ */
602
+ const DEFAULT_SWEEP_IDLE_MS = 600 * 1e3;
603
+ //#endregion
604
+ export { CdpConnection as _, applyLiveViewMode as a, connectUrl as b, BrowserRenderingError as c, createBrowserSession as d, deleteBrowserSession as f, CDP_METHOD_NOT_FOUND as g, listBrowserTargets as h, LIVE_VIEW_URL_TTL_MS as i, connectBrowser as l, isMissingBrowserSession as m, DurableBrowserSessionStore as n, createLiveView as o, getBrowserRecording as p, loadCdpSpec as r, validateConnectorArgs as s, DEFAULT_SWEEP_IDLE_MS as t, connectBrowserSession as u, CdpProtocolError as v, CdpSession as y };
605
+
606
+ //# sourceMappingURL=session-store-Do4xkDcf.js.map