agents 0.24.0 → 0.25.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 (170) hide show
  1. package/dist/{agent-routing-B2XLNMxq.d.ts → agent-routing-0DR0Tk2v.d.ts} +205 -132
  2. package/dist/agent-routing.d.ts +1 -1
  3. package/dist/agent-routing.js.map +1 -1
  4. package/dist/agent-tool-types.d.ts +28 -22
  5. package/dist/agent-tool-types.js +23 -1
  6. package/dist/agent-tool-types.js.map +1 -1
  7. package/dist/{agent-tools-y7zLfw4Q.js → agent-tools-CdJC-8Dc.js} +72 -9
  8. package/dist/agent-tools-CdJC-8Dc.js.map +1 -0
  9. package/dist/{agent-tools-Dj5Mzlw7.d.ts → agent-tools-YrATZJu2.d.ts} +34 -20
  10. package/dist/agent-tools.d.ts +20 -18
  11. package/dist/agent-tools.js.map +1 -1
  12. package/dist/ai-fm7xx1BK.js +312 -0
  13. package/dist/ai-fm7xx1BK.js.map +1 -0
  14. package/dist/base64-redaction-C1Uu29t5.js +59 -0
  15. package/dist/base64-redaction-C1Uu29t5.js.map +1 -0
  16. package/dist/browser/ai-sdk.d.ts +90 -0
  17. package/dist/browser/ai-sdk.js +51 -0
  18. package/dist/browser/ai-sdk.js.map +1 -0
  19. package/dist/browser/ai.d.ts +4 -4
  20. package/dist/browser/ai.js +1 -347
  21. package/dist/browser/index.d.ts +81 -79
  22. package/dist/browser/index.js +361 -2
  23. package/dist/browser/index.js.map +1 -0
  24. package/dist/browser/tanstack-ai.d.ts +96 -1
  25. package/dist/browser/tanstack-ai.js +62 -2
  26. package/dist/browser/tanstack-ai.js.map +1 -1
  27. package/dist/browser-DE3d-RLk.d.ts +275 -0
  28. package/dist/browser-tool-CQ10e6Kj.js +480 -0
  29. package/dist/browser-tool-CQ10e6Kj.js.map +1 -0
  30. package/dist/browser-tool-DuNdlwZ9.d.ts +73 -0
  31. package/dist/capability-B4WbF81e.js.map +1 -1
  32. package/dist/{capability-runner-BUBa6Ake.d.ts → capability-runner-DBAnGr6L.d.ts} +7 -2
  33. package/dist/chat/index.d.ts +340 -234
  34. package/dist/chat/index.js +592 -66
  35. package/dist/chat/index.js.map +1 -1
  36. package/dist/chat/react.d.ts +42 -2
  37. package/dist/chat/react.js +191 -35
  38. package/dist/chat/react.js.map +1 -1
  39. package/dist/chat/transport.d.ts +1 -1
  40. package/dist/chat/transport.js +1 -1
  41. package/dist/chat-sdk/index.d.ts +17 -3
  42. package/dist/chat-sdk/index.js +28 -2
  43. package/dist/chat-sdk/index.js.map +1 -1
  44. package/dist/{client-C9DAjZIY.js → client-4OlMIJx-.js} +102 -29
  45. package/dist/client-4OlMIJx-.js.map +1 -0
  46. package/dist/{client-BxdkCuVy.d.ts → client-je3koD9Z.d.ts} +45 -10
  47. package/dist/client.d.ts +7 -5
  48. package/dist/client.js +2 -2
  49. package/dist/{connector-CptFKzRh.js → connector-58XDGvc3.js} +251 -120
  50. package/dist/connector-58XDGvc3.js.map +1 -0
  51. package/dist/{connector-CkQD4MK3.d.ts → connector-Cl-VqPmA.d.ts} +244 -146
  52. package/dist/context/index.d.ts +29 -0
  53. package/dist/context/index.js +64 -17
  54. package/dist/context/index.js.map +1 -1
  55. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  56. package/dist/{current-agent-C4w86kcN.d.ts → current-agent-vAk_5JMt.d.ts} +4 -4
  57. package/dist/{durable-object-lifecycle-ei7M7lqB.d.ts → durable-object-lifecycle-HhgOMWq9.d.ts} +15 -7
  58. package/dist/harnesses/pi/index.d.ts +348 -0
  59. package/dist/harnesses/pi/index.js +754 -0
  60. package/dist/harnesses/pi/index.js.map +1 -0
  61. package/dist/images-iiTDSyRu.js +1631 -0
  62. package/dist/images-iiTDSyRu.js.map +1 -0
  63. package/dist/{index-Dlgtd3Mj.d.ts → index-BreL0YrQ.d.ts} +2 -2
  64. package/dist/index-kbSUIer3.d.ts +343 -0
  65. package/dist/index.d.ts +46 -44
  66. package/dist/index.js +1 -1
  67. package/dist/internal_context.d.ts +1 -1
  68. package/dist/lifecycle/index.d.ts +3 -3
  69. package/dist/lifecycle/index.js +1 -1
  70. package/dist/{lifecycle-Mm_jQh7r.js → lifecycle-CFu6OV03.js} +39 -10
  71. package/dist/{lifecycle-Mm_jQh7r.js.map → lifecycle-CFu6OV03.js.map} +1 -1
  72. package/dist/mcp/client/index.d.ts +20 -20
  73. package/dist/mcp/client/x402.js +21 -19
  74. package/dist/mcp/client/x402.js.map +1 -1
  75. package/dist/mcp/index.d.ts +35 -35
  76. package/dist/mcp/index.js +1 -1
  77. package/dist/{message-builder-BymO4N_D.js → message-builder-DAl9AhHH.js} +89 -4
  78. package/dist/message-builder-DAl9AhHH.js.map +1 -0
  79. package/dist/models/ai-sdk/index.d.ts +353 -0
  80. package/dist/models/ai-sdk/index.js +2443 -0
  81. package/dist/models/ai-sdk/index.js.map +1 -0
  82. package/dist/models/pi-ai/index.d.ts +313 -0
  83. package/dist/models/pi-ai/index.js +1795 -0
  84. package/dist/models/pi-ai/index.js.map +1 -0
  85. package/dist/observability/ai/index.js +20 -4
  86. package/dist/observability/ai/index.js.map +1 -1
  87. package/dist/{protocol-B0nh6KNf.js → protocol-kHsr-f0X.js} +26 -12
  88. package/dist/{protocol-B0nh6KNf.js.map → protocol-kHsr-f0X.js.map} +1 -1
  89. package/dist/queue/index.d.ts +3 -3
  90. package/dist/queue/index.js +1 -1
  91. package/dist/{queue-BC9F5cUo.js → queue-BB-zfIYF.js} +2 -2
  92. package/dist/{queue-BC9F5cUo.js.map → queue-BB-zfIYF.js.map} +1 -1
  93. package/dist/react.d.ts +6 -6
  94. package/dist/react.js +160 -64
  95. package/dist/react.js.map +1 -1
  96. package/dist/{retries-D9B2UCq3.d.ts → retries-CV6AkXmQ.d.ts} +18 -9
  97. package/dist/retries.d.ts +11 -9
  98. package/dist/retries.js +11 -1
  99. package/dist/retries.js.map +1 -1
  100. package/dist/routing/index.d.ts +2 -2
  101. package/dist/routing/index.js +1 -1
  102. package/dist/{scheduler-D_KHqxBa.js → scheduler-DZ3xQfeK.js} +2 -2
  103. package/dist/{scheduler-D_KHqxBa.js.map → scheduler-DZ3xQfeK.js.map} +1 -1
  104. package/dist/{scheduler-BGq6M5Kd.d.ts → scheduler-RdACNXDP.d.ts} +3 -3
  105. package/dist/schedules/index.d.ts +1 -1
  106. package/dist/schedules/index.js +1 -1
  107. package/dist/serializable.d.ts +1 -1
  108. package/dist/sessions/index.d.ts +70 -3
  109. package/dist/sessions/index.js +276 -67
  110. package/dist/sessions/index.js.map +1 -1
  111. package/dist/skills/index.d.ts +29 -314
  112. package/dist/socket-address.d.ts +16 -0
  113. package/dist/socket-address.js +19 -0
  114. package/dist/socket-address.js.map +1 -0
  115. package/dist/{src-BNU3ZiJM.js → src-BZeu-SCD.js} +423 -115
  116. package/dist/src-BZeu-SCD.js.map +1 -0
  117. package/dist/state/index.d.ts +1 -1
  118. package/dist/state/index.js +1 -1
  119. package/dist/streams/index.d.ts +1 -1
  120. package/dist/streams/index.js +1 -1
  121. package/dist/{streams-BcE8JP2X.d.ts → streams-Cmkj9QfW.d.ts} +4 -2
  122. package/dist/{streams-CCPRV6dt.js → streams-DW-UCOUc.js} +9 -2
  123. package/dist/streams-DW-UCOUc.js.map +1 -0
  124. package/dist/sub-routing.d.ts +12 -12
  125. package/dist/tasks/index.d.ts +1 -1
  126. package/dist/tasks/index.js +1 -1
  127. package/dist/{tasks-D4nLqVSI.js → tasks-68DESxf0.js} +2 -2
  128. package/dist/{tasks-D4nLqVSI.js.map → tasks-68DESxf0.js.map} +1 -1
  129. package/dist/{tasks-V2lCT8ZV.d.ts → tasks-9YxYtByh.d.ts} +2 -2
  130. package/dist/transport-PfFnt-Ld.d.ts +525 -0
  131. package/dist/{types-DCD6BNZH.d.ts → types-BA4anrjI.d.ts} +2 -2
  132. package/dist/voice/index.d.ts +2 -2
  133. package/dist/websockets/index.d.ts +23 -6
  134. package/dist/websockets/index.js +1 -1
  135. package/dist/{websockets-D7IzWbZb.js → websockets-Ci-LZFHH.js} +45 -20
  136. package/dist/{websockets-D7IzWbZb.js.map → websockets-Ci-LZFHH.js.map} +1 -1
  137. package/dist/wire-types-CnMt6_HR.js.map +1 -1
  138. package/dist/wire-types-CrjKvDyi.d.ts +300 -0
  139. package/dist/workflow-types.d.ts +25 -25
  140. package/dist/workflows.d.ts +21 -21
  141. package/dist/workflows.js +1 -1
  142. package/dist/{ws-chat-transport-UNRIS2xl.d.ts → ws-chat-transport-BbT1A5Lc.d.ts} +51 -2
  143. package/dist/{ws-chat-transport-rWwta645.js → ws-chat-transport-cqMKq3IY.js} +143 -16
  144. package/dist/ws-chat-transport-cqMKq3IY.js.map +1 -0
  145. package/docs/agent-tools.md +29 -4
  146. package/docs/browse-the-web.md +87 -5
  147. package/docs/chat-agents.md +124 -16
  148. package/docs/context.md +27 -0
  149. package/docs/durable-execution.md +2 -0
  150. package/docs/harnesses/pi.md +91 -0
  151. package/docs/human-in-the-loop.md +4 -0
  152. package/docs/index.md +3 -0
  153. package/docs/lifecycle.md +20 -4
  154. package/docs/models-pi-ai.md +325 -0
  155. package/docs/models.md +504 -0
  156. package/docs/resumable-streaming.md +2 -0
  157. package/docs/routing.md +13 -13
  158. package/docs/sessions.md +36 -1
  159. package/docs/state.md +1 -0
  160. package/docs/sub-agents.md +9 -0
  161. package/package.json +40 -2
  162. package/dist/agent-tools-y7zLfw4Q.js.map +0 -1
  163. package/dist/browser/ai.js.map +0 -1
  164. package/dist/client-C9DAjZIY.js.map +0 -1
  165. package/dist/client-tools-aIBO0Fk7.d.ts +0 -53
  166. package/dist/connector-CptFKzRh.js.map +0 -1
  167. package/dist/message-builder-BymO4N_D.js.map +0 -1
  168. package/dist/src-BNU3ZiJM.js.map +0 -1
  169. package/dist/streams-CCPRV6dt.js.map +0 -1
  170. package/dist/ws-chat-transport-rWwta645.js.map +0 -1
@@ -2,8 +2,48 @@ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _ass
2
2
  import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
3
  import { CodemodeConnector } from "@cloudflare/codemode";
4
4
  import { Validator } from "@cfworker/json-schema";
5
- //#region src/browser/cdp-session.ts
5
+ //#region src/browser/connector-validation.ts
6
+ function formatToolValidationError(connector, tool, errors) {
7
+ const specific = errors.filter((error) => error.keyword !== "properties");
8
+ return `Invalid arguments for ${connector}.${tool}${(specific.length > 0 ? specific : errors).map((error) => {
9
+ const location = error.instanceLocation.replace(/^#\/?/, "").replaceAll("~1", "/").replaceAll("~0", "~").replaceAll("/", ".");
10
+ return `${location ? ` at ${location}` : ""}: ${error.error}`;
11
+ }).join(";")}`;
12
+ }
13
+ /**
14
+ * Validate a connector tool's arguments against its input schema before it
15
+ * runs, so the model gets a precise error instead of a failure deep inside
16
+ * browser work. An omitted argument counts as `{}`: argumentless tools are
17
+ * documented as `cdp.spec()`.
18
+ */
19
+ function validateConnectorArgs(connector, name, tool) {
20
+ if (!tool.inputSchema) return tool;
21
+ const schema = tool.inputSchema;
22
+ const validator = new Validator(schema, "7", false);
23
+ return {
24
+ ...tool,
25
+ execute: async (args, ctx) => {
26
+ const input = args === void 0 ? {} : args;
27
+ const result = validator.validate(input);
28
+ if (!result.valid) throw new Error(formatToolValidationError(connector, name, result.errors));
29
+ return await tool.execute(input, ctx);
30
+ }
31
+ };
32
+ }
33
+ //#endregion
34
+ //#region src/browser/cdp-connection.ts
6
35
  const DEFAULT_TIMEOUT_MS = 1e4;
36
+ /** JSON-RPC's "method not found" code, which Chrome also uses for CDP. */
37
+ const CDP_METHOD_NOT_FOUND = -32601;
38
+ /** The browser answered a command with a JSON-RPC error. */
39
+ var CdpProtocolError = class extends Error {
40
+ constructor(method, code, message) {
41
+ super(`CDP error ${code ?? "unknown"}: ${message} for ${method}`);
42
+ this.name = "CdpProtocolError";
43
+ this.code = code;
44
+ this.method = method;
45
+ }
46
+ };
7
47
  const MAX_DEBUG_ENTRIES = 400;
8
48
  var _socket$1 = /* @__PURE__ */ new WeakMap();
9
49
  var _nextId = /* @__PURE__ */ new WeakMap();
@@ -11,42 +51,56 @@ var _pending = /* @__PURE__ */ new WeakMap();
11
51
  var _debugLog = /* @__PURE__ */ new WeakMap();
12
52
  var _defaultTimeoutMs = /* @__PURE__ */ new WeakMap();
13
53
  var _dispose = /* @__PURE__ */ new WeakMap();
14
- var _CdpSession_brand = /* @__PURE__ */ new WeakSet();
54
+ var _disposed = /* @__PURE__ */ new WeakMap();
55
+ var _onActivity = /* @__PURE__ */ new WeakMap();
56
+ var _CdpConnection_brand = /* @__PURE__ */ new WeakSet();
15
57
  /**
16
- * A CDP session over an open WebSocket. Manages command correlation,
17
- * timeouts, target sessions, and a debug event ring buffer.
58
+ * One Chrome DevTools Protocol connection over an open WebSocket. Manages
59
+ * command correlation, timeouts, per-tab CDP sessions, and a debug event
60
+ * ring buffer.
18
61
  *
19
62
  * Used host-side (not in the sandbox) — the sandbox calls into this
20
63
  * via DynamicWorkerExecutor's ToolDispatcher RPC.
21
64
  */
22
- var CdpSession = class {
23
- constructor(socket, defaultTimeoutMs = DEFAULT_TIMEOUT_MS, dispose, sessionId) {
24
- _classPrivateMethodInitSpec(this, _CdpSession_brand);
65
+ var CdpConnection = class {
66
+ constructor(socket, optionsOrTimeoutMs, onClose, sessionId) {
67
+ _classPrivateMethodInitSpec(this, _CdpConnection_brand);
25
68
  _classPrivateFieldInitSpec(this, _socket$1, void 0);
26
69
  _classPrivateFieldInitSpec(this, _nextId, 1);
27
70
  _classPrivateFieldInitSpec(this, _pending, /* @__PURE__ */ new Map());
28
71
  _classPrivateFieldInitSpec(this, _debugLog, []);
29
72
  _classPrivateFieldInitSpec(this, _defaultTimeoutMs, void 0);
30
73
  _classPrivateFieldInitSpec(this, _dispose, void 0);
74
+ _classPrivateFieldInitSpec(this, _disposed, false);
75
+ _classPrivateFieldInitSpec(this, _onActivity, void 0);
76
+ const options = typeof optionsOrTimeoutMs === "object" ? optionsOrTimeoutMs : {
77
+ timeoutMs: optionsOrTimeoutMs,
78
+ onClose,
79
+ sessionId
80
+ };
31
81
  _classPrivateFieldSet2(_socket$1, this, socket);
32
- _classPrivateFieldSet2(_defaultTimeoutMs, this, defaultTimeoutMs);
33
- _classPrivateFieldSet2(_dispose, this, dispose);
34
- this.sessionId = sessionId;
35
- socket.addEventListener("message", (event) => _assertClassBrand(_CdpSession_brand, this, _handleMessage).call(this, event));
82
+ _classPrivateFieldSet2(_defaultTimeoutMs, this, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
83
+ _classPrivateFieldSet2(_dispose, this, options.onClose);
84
+ this.sessionId = options.sessionId;
85
+ _classPrivateFieldSet2(_onActivity, this, options.onActivity);
86
+ socket.addEventListener("message", (event) => _assertClassBrand(_CdpConnection_brand, this, _handleMessage).call(this, event));
36
87
  socket.addEventListener("error", () => {
37
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP socket error"));
88
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP socket error"));
89
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
38
90
  });
39
91
  socket.addEventListener("close", () => {
40
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP connection closed"));
92
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP connection closed"));
93
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
41
94
  });
42
95
  }
43
96
  send(method, params, options = {}) {
44
97
  var _this$nextId, _this$nextId2;
98
+ _classPrivateFieldGet2(_onActivity, this)?.call(this);
45
99
  const id = (_classPrivateFieldSet2(_nextId, this, (_this$nextId = _classPrivateFieldGet2(_nextId, this), _this$nextId2 = _this$nextId++, _this$nextId)), _this$nextId2);
46
100
  const timeoutMs = options.timeoutMs ?? _classPrivateFieldGet2(_defaultTimeoutMs, this);
47
101
  const sessionId = typeof options.sessionId === "string" && options.sessionId.length > 0 ? options.sessionId : void 0;
48
102
  const domain = typeof method === "string" ? method.split(".")[0] : "";
49
- if (!sessionId && domain && !["Browser", "Target"].includes(domain)) _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "warning", {
103
+ if (!sessionId && domain && !["Browser", "Target"].includes(domain)) _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "warning", {
50
104
  id,
51
105
  method,
52
106
  reason: "target-scoped method sent without sessionId"
@@ -66,18 +120,27 @@ var CdpSession = class {
66
120
  startedAt
67
121
  });
68
122
  });
69
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "send", {
123
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "send", {
70
124
  id,
71
125
  method,
72
126
  sessionId,
73
127
  timeoutMs
74
128
  });
75
- _classPrivateFieldGet2(_socket$1, this).send(JSON.stringify({
76
- id,
77
- method,
78
- params,
79
- sessionId
80
- }));
129
+ try {
130
+ _classPrivateFieldGet2(_socket$1, this).send(JSON.stringify({
131
+ id,
132
+ method,
133
+ params,
134
+ sessionId
135
+ }));
136
+ } catch (error) {
137
+ const pending = _classPrivateFieldGet2(_pending, this).get(id);
138
+ if (pending) {
139
+ clearTimeout(pending.timeoutId);
140
+ _classPrivateFieldGet2(_pending, this).delete(id);
141
+ pending.reject(error instanceof Error ? error : new Error(String(error)));
142
+ }
143
+ }
81
144
  return result;
82
145
  }
83
146
  async attachToTarget(targetId, options = {}) {
@@ -87,7 +150,7 @@ var CdpSession = class {
87
150
  flatten: true
88
151
  }, { timeoutMs: options.timeoutMs }))?.sessionId ?? "";
89
152
  if (!sessionId) throw new Error(`Target.attachToTarget did not return a sessionId for target ${targetId}`);
90
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "attach", {
153
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "attach", {
91
154
  targetId,
92
155
  sessionId
93
156
  });
@@ -101,16 +164,25 @@ var CdpSession = class {
101
164
  _classPrivateFieldSet2(_debugLog, this, []);
102
165
  }
103
166
  disconnect() {
104
- _assertClassBrand(_CdpSession_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP session disconnected"));
167
+ _assertClassBrand(_CdpConnection_brand, this, _rejectAll).call(this, /* @__PURE__ */ new Error("CDP session disconnected"));
105
168
  try {
106
169
  _classPrivateFieldGet2(_socket$1, this).close(1e3, "Done");
107
170
  } catch {}
108
171
  }
109
172
  close() {
110
173
  this.disconnect();
111
- _classPrivateFieldGet2(_dispose, this)?.call(this);
174
+ _assertClassBrand(_CdpConnection_brand, this, _runDispose).call(this);
112
175
  }
113
176
  };
177
+ /**
178
+ * Run the dispose callback exactly once, on the first terminal event —
179
+ * an explicit {@link close}, peer closure, or a socket error.
180
+ */
181
+ function _runDispose() {
182
+ if (_classPrivateFieldGet2(_disposed, this)) return;
183
+ _classPrivateFieldSet2(_disposed, this, true);
184
+ _classPrivateFieldGet2(_dispose, this)?.call(this);
185
+ }
114
186
  function _rejectAll(error) {
115
187
  for (const [id, pending] of _classPrivateFieldGet2(_pending, this).entries()) {
116
188
  clearTimeout(pending.timeoutId);
@@ -126,7 +198,7 @@ function _handleMessage(event) {
126
198
  } catch {
127
199
  return;
128
200
  }
129
- _assertClassBrand(_CdpSession_brand, this, _recordDebug).call(this, "receive", {
201
+ _assertClassBrand(_CdpConnection_brand, this, _recordDebug).call(this, "receive", {
130
202
  id: payload.id,
131
203
  method: payload.method,
132
204
  sessionId: payload.sessionId,
@@ -139,9 +211,7 @@ function _handleMessage(event) {
139
211
  _classPrivateFieldGet2(_pending, this).delete(payload.id);
140
212
  if (payload.error) {
141
213
  const err = payload.error;
142
- const code = err.code ?? "unknown";
143
- const message = err.message ?? "CDP error";
144
- pending.reject(/* @__PURE__ */ new Error(`CDP error ${code}: ${message} for ${pending.method}`));
214
+ pending.reject(new CdpProtocolError(pending.method, typeof err.code === "number" ? err.code : void 0, err.message ?? "CDP error"));
145
215
  return;
146
216
  }
147
217
  pending.resolve(payload.result);
@@ -191,8 +261,10 @@ async function connectUrl(baseUrl, options) {
191
261
  const ws = wsResponse.webSocket;
192
262
  if (!ws) throw new Error(`Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`);
193
263
  ws.accept();
194
- return new CdpSession(ws, options?.timeoutMs);
264
+ return new CdpConnection(ws, { timeoutMs: options?.timeoutMs });
195
265
  }
266
+ /** @deprecated Renamed to {@link CdpConnection}. */
267
+ const CdpSession = CdpConnection;
196
268
  //#endregion
197
269
  //#region src/browser/browser-run.ts
198
270
  var BrowserRenderingError = class extends Error {
@@ -202,6 +274,13 @@ var BrowserRenderingError = class extends Error {
202
274
  this.name = "BrowserRenderingError";
203
275
  }
204
276
  };
277
+ /**
278
+ * Whether an error means the platform session is gone: Browser Run uses 404
279
+ * for unknown ids and 410 after `keep_alive` expiry.
280
+ */
281
+ function isMissingBrowserSession$1(error) {
282
+ return error instanceof BrowserRenderingError && (error.status === 404 || error.status === 410);
283
+ }
205
284
  function browserSessionEndpoint(sessionId, options) {
206
285
  const path = sessionId ? `/v1/devtools/browser/${sessionId}` : "/v1/devtools/browser";
207
286
  const url = new URL(`https://localhost${path}`);
@@ -222,7 +301,11 @@ async function parseBrowserSessionInfo(response) {
222
301
  };
223
302
  }
224
303
  async function createBrowserSession(browser, options) {
225
- const response = await browser.fetch(browserSessionEndpoint(void 0, options), { method: "POST" });
304
+ const response = await browser.fetch(browserSessionEndpoint(void 0, options), {
305
+ method: "POST",
306
+ headers: { "Content-Type": "application/json" },
307
+ body: JSON.stringify(options?.guardrails ? { guardrails: options.guardrails } : {})
308
+ });
226
309
  if (!response.ok) throw new BrowserRenderingError(`Failed to create Browser Rendering session: ${response.status}`, response.status);
227
310
  return parseBrowserSessionInfo(response);
228
311
  }
@@ -241,28 +324,33 @@ async function deleteBrowserSession(browser, sessionId) {
241
324
  */
242
325
  async function connectBrowser(browser, options) {
243
326
  const normalizedOptions = typeof options === "number" ? { timeoutMs: options } : options ?? {};
244
- const isKitesurf = normalizedOptions.browser === "kitesurf";
245
- if (isKitesurf && (normalizedOptions.keepAliveMs || normalizedOptions.includeTargets || normalizedOptions.recording)) throw new Error("Kitesurf does not support keepAliveMs, includeTargets, or recording");
246
- const response = await browser.fetch(browserSessionEndpoint(void 0, {
247
- keepAliveMs: isKitesurf ? void 0 : normalizedOptions.keepAliveMs,
327
+ if (normalizedOptions.browser === "kitesurf") {
328
+ const smuggled = normalizedOptions;
329
+ if (smuggled.keepAliveMs || smuggled.includeTargets || smuggled.recording) throw new Error("Kitesurf does not support keepAliveMs, includeTargets, or recording");
330
+ }
331
+ const response = await browser.fetch(browserSessionEndpoint(void 0, normalizedOptions.browser === "kitesurf" ? { browser: "kitesurf" } : {
332
+ keepAliveMs: normalizedOptions.keepAliveMs,
248
333
  includeTargets: normalizedOptions.includeTargets,
249
- recording: normalizedOptions.recording,
250
- browser: normalizedOptions.browser
334
+ recording: normalizedOptions.recording
251
335
  }), { headers: { Upgrade: "websocket" } });
252
336
  const ws = response.webSocket;
253
337
  if (!ws) throw new Error("Browser Rendering binding did not return a WebSocket. Ensure the 'browser' binding is configured in wrangler.jsonc.");
254
338
  if (normalizedOptions.browser === "kitesurf") {
255
339
  ws.accept();
256
- return new CdpSession(ws, normalizedOptions.timeoutMs);
340
+ return new CdpConnection(ws, { timeoutMs: normalizedOptions.timeoutMs });
257
341
  }
258
342
  const sessionId = response.headers.get("cf-browser-session-id");
259
343
  if (!sessionId) throw new Error("Browser Rendering binding did not include a session ID when opening the CDP WebSocket");
260
344
  ws.accept();
261
- return new CdpSession(ws, normalizedOptions.timeoutMs, () => {
262
- deleteBrowserSession(browser, sessionId).catch((error) => {
263
- console.warn(`[agents/browser] Failed to delete one-shot Browser Run session ${sessionId}`, error);
264
- });
265
- }, sessionId);
345
+ return new CdpConnection(ws, {
346
+ timeoutMs: normalizedOptions.timeoutMs,
347
+ onClose: () => {
348
+ deleteBrowserSession(browser, sessionId).catch((error) => {
349
+ console.warn(`[agents/browser] Failed to delete one-shot Browser Run session ${sessionId}`, error);
350
+ });
351
+ },
352
+ sessionId
353
+ });
266
354
  }
267
355
  /**
268
356
  * Fetch a Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/)
@@ -284,14 +372,18 @@ async function getBrowserRecording(options) {
284
372
  const payload = await response.json();
285
373
  return "result" in payload && payload.result ? payload.result : payload;
286
374
  }
287
- /**
288
- * Connect to an existing Browser Rendering session without deleting it on close.
289
- */
290
- async function connectBrowserSession(browser, sessionId, timeoutMs) {
291
- const ws = (await browser.fetch(browserSessionEndpoint(sessionId), { headers: { Upgrade: "websocket" } })).webSocket;
292
- if (!ws) throw new Error(`Browser Rendering binding did not return a WebSocket for session ${sessionId}`);
375
+ async function connectBrowserSession(browser, sessionId, options) {
376
+ const normalized = typeof options === "number" ? { timeoutMs: options } : options ?? {};
377
+ const response = await browser.fetch(browserSessionEndpoint(sessionId), { headers: { Upgrade: "websocket" } });
378
+ const ws = response.webSocket;
379
+ if (!ws) throw new BrowserRenderingError(`Browser Rendering binding did not return a WebSocket for session ${sessionId} (${response.status})`, response.status);
293
380
  ws.accept();
294
- return new CdpSession(ws, timeoutMs, void 0, sessionId);
381
+ return new CdpConnection(ws, {
382
+ timeoutMs: normalized.timeoutMs,
383
+ onClose: normalized.onClose,
384
+ sessionId,
385
+ onActivity: normalized.onActivity
386
+ });
295
387
  }
296
388
  //#endregion
297
389
  //#region src/browser/quick-actions.ts
@@ -375,29 +467,110 @@ function browserPdf(browser, input) {
375
467
  return quickActionBinary(browser, "pdf", input);
376
468
  }
377
469
  //#endregion
470
+ //#region src/browser/live-view.ts
471
+ /**
472
+ * Browser Run mints `devtoolsFrontendUrl`s (the Live View links) that are
473
+ * valid for ~5 minutes. We surface the window so callers can decide how long
474
+ * a shared link is good for before re-listing targets.
475
+ */
476
+ const LIVE_VIEW_URL_TTL_MS = 300 * 1e3;
477
+ /**
478
+ * Rewrite the hosted Live View UI's `mode` query param (`tab` | `devtools`).
479
+ * The raw `devtoolsFrontendUrl` is returned unchanged when no mode is asked
480
+ * for or the URL can't be parsed.
481
+ */
482
+ function applyLiveViewMode(rawUrl, mode) {
483
+ if (!mode) return rawUrl;
484
+ try {
485
+ const url = new URL(rawUrl);
486
+ url.searchParams.set("mode", mode === "devtools" ? "devtools" : "tab");
487
+ return url.toString();
488
+ } catch {
489
+ return rawUrl;
490
+ }
491
+ }
492
+ /**
493
+ * Project a fresh target listing into Live View links — one per tab that has
494
+ * a `devtoolsFrontendUrl`. Pure; the caller supplies just-listed targets.
495
+ */
496
+ function createLiveView(sessionId, targets, mode) {
497
+ return {
498
+ sessionId,
499
+ targets: targets.filter((target) => target.devtoolsFrontendUrl).map((target) => ({
500
+ targetId: target.id,
501
+ url: applyLiveViewMode(target.devtoolsFrontendUrl, mode),
502
+ pageUrl: target.url,
503
+ title: target.title,
504
+ type: target.type
505
+ })),
506
+ expiresInMs: LIVE_VIEW_URL_TTL_MS
507
+ };
508
+ }
509
+ //#endregion
378
510
  //#region src/browser/spec.ts
379
511
  const MISSING_BROWSER_CONFIG = "Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided";
380
512
  const urlSpecCache = /* @__PURE__ */ new Map();
381
513
  const bindingSpecCache = /* @__PURE__ */ new WeakMap();
382
514
  const CACHE_TTL_MS = 300 * 1e3;
515
+ /** Qualify a same-domain `$ref` (`"FrameId"` → `"Page.FrameId"`). */
516
+ function qualifyRef(domain, ref) {
517
+ if (ref === void 0) return void 0;
518
+ return ref.includes(".") ? ref : `${domain}.${ref}`;
519
+ }
520
+ function normalizeItems(domain, items) {
521
+ if (!items) return void 0;
522
+ return {
523
+ type: items.type,
524
+ $ref: qualifyRef(domain, items.$ref),
525
+ enum: items.enum
526
+ };
527
+ }
528
+ function normalizeFields(domain, fields) {
529
+ return (fields ?? []).map((field) => ({
530
+ name: field.name,
531
+ description: field.description,
532
+ optional: field.optional,
533
+ experimental: field.experimental,
534
+ deprecated: field.deprecated,
535
+ type: field.type,
536
+ $ref: qualifyRef(domain, field.$ref),
537
+ enum: field.enum,
538
+ items: normalizeItems(domain, field.items)
539
+ }));
540
+ }
383
541
  function normalizeCdpSpec(spec) {
384
- return { domains: (spec.domains ?? []).map((domain) => ({
385
- name: domain.domain,
386
- description: domain.description,
387
- commands: (domain.commands ?? []).map((command) => ({
542
+ return { domains: (spec.domains ?? []).map(({ domain, ...raw }) => ({
543
+ name: domain,
544
+ description: raw.description,
545
+ experimental: raw.experimental,
546
+ deprecated: raw.deprecated,
547
+ commands: (raw.commands ?? []).map((command) => ({
388
548
  name: command.name,
389
- method: `${domain.domain}.${command.name}`,
390
- description: command.description
549
+ method: `${domain}.${command.name}`,
550
+ description: command.description,
551
+ experimental: command.experimental,
552
+ deprecated: command.deprecated,
553
+ parameters: normalizeFields(domain, command.parameters),
554
+ returns: normalizeFields(domain, command.returns)
391
555
  })),
392
- events: (domain.events ?? []).map((event) => ({
556
+ events: (raw.events ?? []).map((event) => ({
393
557
  name: event.name,
394
- event: `${domain.domain}.${event.name}`,
395
- description: event.description
558
+ event: `${domain}.${event.name}`,
559
+ description: event.description,
560
+ experimental: event.experimental,
561
+ deprecated: event.deprecated,
562
+ parameters: normalizeFields(domain, event.parameters)
396
563
  })),
397
- types: (domain.types ?? []).map((type) => ({
564
+ types: (raw.types ?? []).map((type) => ({
398
565
  id: type.id,
399
- name: `${domain.domain}.${type.id}`,
400
- description: type.description
566
+ name: `${domain}.${type.id}`,
567
+ description: type.description,
568
+ experimental: type.experimental,
569
+ deprecated: type.deprecated,
570
+ type: type.type,
571
+ enum: type.enum,
572
+ properties: normalizeFields(domain, type.properties),
573
+ items: normalizeItems(domain, type.items)
401
574
  }))
402
575
  })) };
403
576
  }
@@ -423,6 +596,13 @@ async function fetchCdpSpecFromUrl(cdpBaseUrl, headers) {
423
596
  return await response.json();
424
597
  });
425
598
  }
599
+ async function fetchCdpSpecFromSession(browser, sessionId) {
600
+ return getCachedSpec(bindingSpecCache, browser, async () => {
601
+ const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/protocol`);
602
+ if (!response.ok) throw new Error(`Failed to fetch CDP spec from Browser Rendering: ${response.status}`);
603
+ return await response.json();
604
+ });
605
+ }
426
606
  async function fetchCdpSpecFromBrowser(browser) {
427
607
  return getCachedSpec(bindingSpecCache, browser, async () => {
428
608
  const createResponse = await browser.fetch("https://localhost/v1/devtools/browser", { method: "POST" });
@@ -443,11 +623,12 @@ async function fetchCdpSpecFromBrowser(browser) {
443
623
  /** Load the (cached) searchable CDP spec for a browser source. */
444
624
  async function loadCdpSpec(source) {
445
625
  if (source.cdpUrl) return fetchCdpSpecFromUrl(source.cdpUrl, source.cdpHeaders);
626
+ if (source.browser && source.sessionId) return fetchCdpSpecFromSession(source.browser, source.sessionId);
446
627
  if (source.browser) return fetchCdpSpecFromBrowser(source.browser);
447
628
  throw new Error(MISSING_BROWSER_CONFIG);
448
629
  }
449
630
  //#endregion
450
- //#region src/browser/session-manager.ts
631
+ //#region src/browser/session-store.ts
451
632
  var _DurableBrowserSessionStore_brand = /* @__PURE__ */ new WeakSet();
452
633
  var DurableBrowserSessionStore = class {
453
634
  constructor(storage) {
@@ -524,37 +705,9 @@ const DEFAULT_EXEC_SWEEP_IDLE_MS = 1440 * 60 * 1e3;
524
705
  * keep an active or recently-resumed execution out of sweep range.
525
706
  */
526
707
  const EXEC_TOUCH_INTERVAL_MS = 60 * 1e3;
527
- /**
528
- * Browser Run mints `devtoolsFrontendUrl`s (the Live View links) that are
529
- * valid for ~5 minutes. We surface the window so callers can decide how long
530
- * a shared link is good for before re-listing targets.
531
- */
532
- const LIVE_VIEW_URL_TTL_MS = 300 * 1e3;
533
708
  function isMissingBrowserSession(error) {
534
709
  return error instanceof BrowserRenderingError && (error.status === 404 || error.status === 410);
535
710
  }
536
- function formatToolValidationError(connector, tool, errors) {
537
- const specific = errors.filter((error) => error.keyword !== "properties");
538
- return `Invalid arguments for ${connector}.${tool}${(specific.length > 0 ? specific : errors).map((error) => {
539
- const location = error.instanceLocation.replace(/^#\/?/, "").replaceAll("~1", "/").replaceAll("~0", "~").replaceAll("/", ".");
540
- return `${location ? ` at ${location}` : ""}: ${error.error}`;
541
- }).join(";")}`;
542
- }
543
- /**
544
- * Rewrite the hosted Live View UI's `mode` query param (`tab` | `devtools`).
545
- * The raw `devtoolsFrontendUrl` is returned unchanged when no mode is asked
546
- * for or the URL can't be parsed.
547
- */
548
- function applyLiveViewMode(rawUrl, mode) {
549
- if (!mode) return rawUrl;
550
- try {
551
- const url = new URL(rawUrl);
552
- url.searchParams.set("mode", mode === "devtools" ? "devtools" : "tab");
553
- return url.toString();
554
- } catch {
555
- return rawUrl;
556
- }
557
- }
558
711
  /**
559
712
  * `cdp.attachToTarget` returns `{ sessionId: "target:<targetId>" }` — a stable
560
713
  * handle instead of the raw CDP session id. (The object shape mirrors the real
@@ -617,25 +770,14 @@ var BrowserConnector = class extends CodemodeConnector {
617
770
  "If a command fails or times out, check cdp.getDebugLog() for recent protocol traffic."
618
771
  ];
619
772
  if (_assertClassBrand(_BrowserConnector_brand, this, _isKitesurf).call(this)) lines.push("Kitesurf implements a subset of CDP and does not expose protocol discovery.", "Kitesurf is scoped to this connection. Complete the whole browser task in one execution and do not pause for approval: the browser cannot reconnect when execution resumes.", "Kitesurf Page.navigate may resolve before layout and paint. Before a screenshot: call Page.enable; navigate; poll Runtime.evaluate with returnByValue: true until result.value reports document.readyState === 'complete' and non-empty body text; then wait 1000ms before Page.captureScreenshot. Do not capture if readiness fails.");
620
- else lines.push("Use cdp.spec() to discover commands, events, and types when unsure.", "When a step needs a human (login, MFA, CAPTCHA, sensitive input), call cdp.getLiveViewUrl() to get a link they can open to control the browser live — surface it, then make an approval-gated call so the run pauses until they're done.");
773
+ else lines.push("Use cdp.spec() to look up commands, their parameters, events, and types when unsure.", "When a step needs a human (login, MFA, CAPTCHA, sensitive input), call cdp.getLiveViewUrl() to get a link they can open to control the browser live — surface it, then make an approval-gated call so the run pauses until they're done.");
621
774
  if (mode === "one-shot") lines.push("The browser session lasts for this execution only and is closed when it ends.");
622
775
  else if (mode === "reuse") lines.push("The browser session is shared and persists across executions — tabs and state you leave behind will still be there next time.");
623
776
  else lines.push("The browser session is one-shot by default. If browser state must persist after this execution (e.g. a logged-in page), call cdp.startSession() to keep it alive for later executions.");
624
777
  return lines.join("\n");
625
778
  }
626
779
  tool(name, tool) {
627
- if (!tool.inputSchema) return tool;
628
- const schema = tool.inputSchema;
629
- const validator = new Validator(schema, "7", false);
630
- return {
631
- ...tool,
632
- execute: async (args, ctx) => {
633
- const input = args === void 0 ? {} : args;
634
- const result = validator.validate(input);
635
- if (!result.valid) throw new Error(formatToolValidationError(this.name(), name, result.errors));
636
- return await tool.execute(input, ctx);
637
- }
638
- };
780
+ return validateConnectorArgs(this.name(), name, tool);
639
781
  }
640
782
  tools() {
641
783
  const tools = {
@@ -674,7 +816,7 @@ var BrowserConnector = class extends CodemodeConnector {
674
816
  timeoutMs
675
817
  });
676
818
  } catch (err) {
677
- if (err instanceof Error && /-32601|wasn't found/.test(err.message)) {
819
+ if (err instanceof CdpProtocolError && err.code === -32601) {
678
820
  if (await _assertClassBrand(_BrowserConnector_brand, this, _isSpecEvent).call(this, method)) throw new Error(`${err.message}. '${method}' is a CDP *event*, not a command — it cannot be called via cdp.send. To wait for page state, poll instead (e.g. Runtime.evaluate of document.readyState until "complete").`);
679
821
  if (!sessionId) throw new Error(`${err.message}. Page-scoped commands need a sessionId: const { sessionId } = await cdp.attachToTarget({ targetId }); then pass sessionId to cdp.send.`);
680
822
  }
@@ -711,7 +853,7 @@ var BrowserConnector = class extends CodemodeConnector {
711
853
  }
712
854
  },
713
855
  spec: {
714
- description: "Return the searchable Chrome DevTools Protocol spec: domains with their commands, events, and types. Use it to discover method names and capabilities.",
856
+ description: "Return the searchable Chrome DevTools Protocol spec: domains with their commands (parameters and returns), events, and types. Use it to find a method and exactly how to call it.",
715
857
  replay: "reexecute",
716
858
  inputSchema: {
717
859
  type: "object",
@@ -919,18 +1061,7 @@ var BrowserConnector = class extends CodemodeConnector {
919
1061
  async liveView(options) {
920
1062
  const info = await this.sessionInfo();
921
1063
  if (!info) return void 0;
922
- const targets = (info.targets ?? []).filter((target) => target.devtoolsFrontendUrl).map((target) => ({
923
- targetId: target.id,
924
- url: applyLiveViewMode(target.devtoolsFrontendUrl, options?.mode),
925
- pageUrl: target.url,
926
- title: target.title,
927
- type: target.type
928
- }));
929
- return {
930
- sessionId: info.sessionId,
931
- targets,
932
- expiresInMs: LIVE_VIEW_URL_TTL_MS
933
- };
1064
+ return createLiveView(info.sessionId, info.targets ?? [], options?.mode);
934
1065
  }
935
1066
  /** Close the shared (reuse/promoted) session, if one exists. */
936
1067
  async closeSession() {
@@ -1158,7 +1289,7 @@ async function _socketInner(executionId) {
1158
1289
  const cached = _classPrivateFieldGet2(_sockets, this).get(executionId);
1159
1290
  if (cached?.browserSessionId === stored.sessionId) return cached.session;
1160
1291
  if (cached) _assertClassBrand(_BrowserConnector_brand, this, _dropSocket).call(this, executionId);
1161
- const session = await connectBrowserSession(browser, stored.sessionId, _classPrivateFieldGet2(_options, this).timeout);
1292
+ const session = await connectBrowserSession(browser, stored.sessionId, { timeoutMs: _classPrivateFieldGet2(_options, this).timeout });
1162
1293
  _classPrivateFieldGet2(_sockets, this).set(executionId, {
1163
1294
  session,
1164
1295
  browserSessionId: stored.sessionId,
@@ -1404,6 +1535,6 @@ async function _closeStoredSession(key) {
1404
1535
  if (stored) await deleteBrowserSession(browser, stored.sessionId);
1405
1536
  }
1406
1537
  //#endregion
1407
- export { connectUrl as C, CdpSession as S, connectBrowserSession as _, loadCdpSpec as a, getBrowserRecording as b, browserLinks as c, browserScrape as d, browserScreenshot as f, connectBrowser as g, BrowserRenderingError as h, DurableBrowserSessionStore as i, browserMarkdown as l, runQuickAction as m, DEFAULT_EXEC_SWEEP_IDLE_MS as n, browserContent as o, browserSnapshot as p, DEFAULT_SWEEP_IDLE_MS as r, browserExtract as s, BrowserConnector as t, browserPdf as u, createBrowserSession as v, listBrowserTargets as x, deleteBrowserSession as y };
1538
+ export { listBrowserTargets as C, CdpSession as D, CdpProtocolError as E, connectUrl as O, isMissingBrowserSession$1 as S, CdpConnection as T, connectBrowser as _, loadCdpSpec as a, deleteBrowserSession as b, browserExtract as c, browserPdf as d, browserScrape as f, BrowserRenderingError as g, runQuickAction as h, DurableBrowserSessionStore as i, validateConnectorArgs as k, browserLinks as l, browserSnapshot as m, DEFAULT_EXEC_SWEEP_IDLE_MS as n, createLiveView as o, browserScreenshot as p, DEFAULT_SWEEP_IDLE_MS as r, browserContent as s, BrowserConnector as t, browserMarkdown as u, connectBrowserSession as v, CDP_METHOD_NOT_FOUND as w, getBrowserRecording as x, createBrowserSession as y };
1408
1539
 
1409
- //# sourceMappingURL=connector-CptFKzRh.js.map
1540
+ //# sourceMappingURL=connector-58XDGvc3.js.map