agents 0.24.0 → 0.26.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/harness/pi/index.d.ts +344 -0
  59. package/dist/harness/pi/index.js +873 -0
  60. package/dist/harness/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 +173 -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
@@ -6,7 +6,7 @@ import {
6
6
  PassEndStatus
7
7
  } from "@cloudflare/codemode";
8
8
 
9
- //#region src/browser/cdp-session.d.ts
9
+ //#region src/browser/cdp-connection.d.ts
10
10
  interface DebugEntry {
11
11
  at: string;
12
12
  type: string;
@@ -19,20 +19,41 @@ interface CdpSendOptions {
19
19
  interface CdpAttachOptions {
20
20
  timeoutMs?: number;
21
21
  }
22
+ /** Construction options for {@link CdpConnection}. */
23
+ interface CdpConnectionOptions {
24
+ /** Default per-command timeout. Defaults to 10 seconds. */
25
+ timeoutMs?: number;
26
+ /**
27
+ * Invoked exactly once when the session reaches a terminal state — an
28
+ * explicit `close()`, peer closure, or a socket error.
29
+ */
30
+ onClose?: () => void;
31
+ /** Browser Run session id, when connected to a session-scoped browser. */
32
+ sessionId?: string;
33
+ /** Invoked on every CDP command sent — an activity signal for idle tracking. */
34
+ onActivity?: () => void;
35
+ }
22
36
  /**
23
- * A CDP session over an open WebSocket. Manages command correlation,
24
- * timeouts, target sessions, and a debug event ring buffer.
37
+ * One Chrome DevTools Protocol connection over an open WebSocket. Manages
38
+ * command correlation, timeouts, per-tab CDP sessions, and a debug event
39
+ * ring buffer.
25
40
  *
26
41
  * Used host-side (not in the sandbox) — the sandbox calls into this
27
42
  * via DynamicWorkerExecutor's ToolDispatcher RPC.
28
43
  */
29
- declare class CdpSession {
44
+ declare class CdpConnection {
30
45
  #private;
31
46
  readonly sessionId?: string;
47
+ constructor(socket: WebSocket, options?: CdpConnectionOptions);
48
+ /**
49
+ * @deprecated Pass a {@link CdpConnectionOptions} object instead —
50
+ * `new CdpConnection(socket, { timeoutMs, onClose, sessionId })`. The
51
+ * positional form will be removed.
52
+ */
32
53
  constructor(
33
54
  socket: WebSocket,
34
- defaultTimeoutMs?: number,
35
- dispose?: () => void,
55
+ timeoutMs?: number,
56
+ onClose?: () => void,
36
57
  sessionId?: string
37
58
  );
38
59
  send(
@@ -60,7 +81,11 @@ declare function connectUrl(
60
81
  timeoutMs?: number;
61
82
  headers?: Record<string, string>;
62
83
  }
63
- ): Promise<CdpSession>;
84
+ ): Promise<CdpConnection>;
85
+ /** @deprecated Renamed to {@link CdpConnection}. */
86
+ declare const CdpSession: typeof CdpConnection;
87
+ /** @deprecated Renamed to {@link CdpConnection}. */
88
+ type CdpSession = CdpConnection;
64
89
  //#endregion
65
90
  //#region src/browser/browser-run.d.ts
66
91
  /**
@@ -71,6 +96,23 @@ declare function connectUrl(
71
96
  interface BrowserBinding {
72
97
  fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
73
98
  }
99
+ /**
100
+ * Browser Run [hostname guardrails](https://developers.cloudflare.com/browser-run/features/guardrails/):
101
+ * restrict which hostnames the session's HTTP/HTTPS requests may reach. Fixed
102
+ * at session launch for every connection to the session, including Live View.
103
+ * Omitted entirely, the platform default applies: all hostnames are allowed.
104
+ * Not supported by Kitesurf.
105
+ */
106
+ interface BrowserSessionGuardrails {
107
+ /**
108
+ * Hostname patterns the browser may request — bare hostnames only (no
109
+ * protocol, port, or path). `*.example.com` matches subdomains; add
110
+ * `example.com` separately to allow the apex.
111
+ */
112
+ allowedDomains?: string[];
113
+ /** Named Cloudflare-maintained domain sets, e.g. `"common-cdns"`. */
114
+ allowedDomainSets?: string[];
115
+ }
74
116
  interface BrowserTargetInfo {
75
117
  id: string;
76
118
  type?: string;
@@ -85,7 +127,10 @@ interface BrowserSessionInfo {
85
127
  targets?: BrowserTargetInfo[];
86
128
  webSocketDebuggerUrl?: string;
87
129
  }
88
- interface ConnectBrowserOptions {
130
+ /** {@link connectBrowser} options for the default Chromium engine. */
131
+ interface ConnectChromiumBrowserOptions {
132
+ /** Select the browser engine. Defaults to Chromium. */
133
+ browser?: "chromium";
89
134
  timeoutMs?: number;
90
135
  keepAliveMs?: number;
91
136
  includeTargets?: boolean;
@@ -96,12 +141,24 @@ interface ConnectBrowserOptions {
96
141
  * {@link getBrowserRecording}.
97
142
  */
98
143
  recording?: boolean;
99
- /**
100
- * Select the browser engine. Defaults to Chromium. Use `"kitesurf"` for
101
- * Cloudflare's connection-scoped, agent-first browser engine.
102
- */
103
- browser?: "kitesurf";
104
144
  }
145
+ /**
146
+ * {@link connectBrowser} options for Kitesurf, Cloudflare's connection-scoped,
147
+ * agent-first browser engine. A Kitesurf browser lives and dies with its
148
+ * WebSocket, so the Chromium-only options (`keepAliveMs`, `includeTargets`,
149
+ * `recording`) do not exist on this arm.
150
+ */
151
+ interface ConnectKitesurfBrowserOptions {
152
+ browser: "kitesurf";
153
+ timeoutMs?: number;
154
+ }
155
+ /**
156
+ * Engine-discriminated {@link connectBrowser} options: selecting
157
+ * `browser: "kitesurf"` removes the Chromium-only options at the type level.
158
+ */
159
+ type ConnectBrowserOptions =
160
+ | ConnectChromiumBrowserOptions
161
+ | ConnectKitesurfBrowserOptions;
105
162
  /** An rrweb session recording for a closed Browser Run session. */
106
163
  interface BrowserRecording {
107
164
  sessionId: string;
@@ -123,6 +180,7 @@ declare function createBrowserSession(
123
180
  keepAliveMs?: number;
124
181
  includeTargets?: boolean;
125
182
  recording?: boolean;
183
+ guardrails?: BrowserSessionGuardrails;
126
184
  }
127
185
  ): Promise<BrowserSessionInfo>;
128
186
  declare function listBrowserTargets(
@@ -139,7 +197,7 @@ declare function deleteBrowserSession(
139
197
  declare function connectBrowser(
140
198
  browser: BrowserBinding,
141
199
  options?: number | ConnectBrowserOptions
142
- ): Promise<CdpSession>;
200
+ ): Promise<CdpConnection>;
143
201
  /**
144
202
  * Fetch a Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/)
145
203
  * by session id, via the Browser Rendering REST API.
@@ -159,14 +217,135 @@ declare function getBrowserRecording(options: {
159
217
  sessionId: string /** Override for testing; defaults to the global `fetch`. */;
160
218
  fetchImpl?: typeof fetch;
161
219
  }): Promise<BrowserRecording>;
220
+ interface ConnectBrowserSessionOptions {
221
+ timeoutMs?: number;
222
+ /**
223
+ * Invoked once when the returned {@link CdpConnection} reaches a terminal
224
+ * state — an explicit `close()`, peer closure, or a socket error. The
225
+ * session itself is never deleted on close — pass an `onClose` that
226
+ * deletes it for one-shot (create-and-close) semantics.
227
+ */
228
+ onClose?: () => void;
229
+ /**
230
+ * Invoked on every CDP command sent over the returned {@link CdpConnection} —
231
+ * an activity signal for idle tracking. Keep it cheap and synchronous;
232
+ * throttle any I/O it triggers.
233
+ */
234
+ onActivity?: () => void;
235
+ }
162
236
  /**
163
237
  * Connect to an existing Browser Rendering session without deleting it on close.
164
238
  */
239
+ declare function connectBrowserSession(
240
+ browser: BrowserBinding,
241
+ sessionId: string,
242
+ options?: ConnectBrowserSessionOptions
243
+ ): Promise<CdpConnection>;
244
+ /**
245
+ * @deprecated Pass `{ timeoutMs }` instead of a bare number — the numeric
246
+ * form will be removed.
247
+ */
165
248
  declare function connectBrowserSession(
166
249
  browser: BrowserBinding,
167
250
  sessionId: string,
168
251
  timeoutMs?: number
169
- ): Promise<CdpSession>;
252
+ ): Promise<CdpConnection>;
253
+ //#endregion
254
+ //#region src/browser/live-view.d.ts
255
+ /**
256
+ * Live View rendering mode (the `mode` query param the hosted UI at
257
+ * `live.browser.run` understands):
258
+ *
259
+ * - `"tab"` — a standalone, interactive page view (best for handing control
260
+ * to a human).
261
+ * - `"devtools"` — the full DevTools inspector panel (Elements, Console,
262
+ * Network, …).
263
+ *
264
+ * Omit it to use whatever mode the binding's `devtoolsFrontendUrl` defaults
265
+ * to.
266
+ */
267
+ type LiveViewMode = "tab" | "devtools";
268
+ /** A single tab's Live View URL. */
269
+ interface BrowserLiveViewUrl {
270
+ /** Open this in a browser to watch/control the tab in real time. */
271
+ url: string;
272
+ /** CDP target (tab) id the URL points at. */
273
+ targetId: string;
274
+ /** Milliseconds the URL stays valid from when it was generated (~5 min). */
275
+ expiresInMs: number;
276
+ }
277
+ interface BrowserLiveViewTarget {
278
+ targetId: string;
279
+ /** Embeddable Live View URL (the `devtoolsFrontendUrl`) for this tab. */
280
+ url: string;
281
+ /** The page the tab is currently showing (e.g. `https://example.com`). */
282
+ pageUrl?: string;
283
+ title?: string;
284
+ type?: string;
285
+ }
286
+ /** Live View URLs for every tab in a session. */
287
+ interface BrowserLiveView {
288
+ sessionId: string;
289
+ targets: BrowserLiveViewTarget[];
290
+ /** Milliseconds the URLs stay valid from when they were generated (~5 min). */
291
+ expiresInMs: number;
292
+ }
293
+ //#endregion
294
+ //#region src/browser/session-store.d.ts
295
+ type MaybePromise<T> = T | Promise<T>;
296
+ interface StoredBrowserSession {
297
+ sessionId: string;
298
+ createdAt: number;
299
+ updatedAt: number;
300
+ /**
301
+ * Set when a sweep closed this entry's Browser Run session but kept the
302
+ * entry as a tombstone, so a later resume of the owning execution fails
303
+ * loudly instead of silently continuing in a fresh browser.
304
+ */
305
+ closedAt?: number;
306
+ /**
307
+ * Named browsers only: the tab (CDP `targetId`) the agent last worked in,
308
+ * so `sessionId: "active"` in a later execution lands on the same page.
309
+ * CDP session ids die with each connection; target ids live as long as
310
+ * the tab.
311
+ */
312
+ activeTargetId?: string;
313
+ }
314
+ interface BrowserSessionLock {
315
+ release(): MaybePromise<void>;
316
+ }
317
+ interface BrowserSessionStore {
318
+ /**
319
+ * Acquire an exclusive lock for this session key. The lock must serialize
320
+ * all holders using the same key. Held only around storage reads/writes —
321
+ * never across Browser Rendering network calls.
322
+ */
323
+ acquireLock(key: string): MaybePromise<BrowserSessionLock>;
324
+ get(key: string): MaybePromise<StoredBrowserSession | undefined>;
325
+ set(key: string, session: StoredBrowserSession): MaybePromise<void>;
326
+ delete(key: string): MaybePromise<void>;
327
+ /**
328
+ * List stored sessions by key prefix. Optional — used by sweeps to find
329
+ * orphaned per-execution sessions; without it only the shared session key
330
+ * is swept.
331
+ */
332
+ list?(prefix: string): MaybePromise<Map<string, StoredBrowserSession>>;
333
+ }
334
+ declare class DurableBrowserSessionStore implements BrowserSessionStore {
335
+ #private;
336
+ private readonly storage;
337
+ constructor(storage: DurableObjectStorage);
338
+ acquireLock(key: string): Promise<BrowserSessionLock>;
339
+ get(key: string): Promise<StoredBrowserSession | undefined>;
340
+ set(key: string, session: StoredBrowserSession): Promise<void>;
341
+ delete(key: string): Promise<void>;
342
+ list(prefix: string): Promise<Map<string, StoredBrowserSession>>;
343
+ }
344
+ /**
345
+ * Default idle window used by {@link BrowserConnector.sweep} for the shared
346
+ * (reuse/promoted) session entry.
347
+ */
348
+ declare const DEFAULT_SWEEP_IDLE_MS: number;
170
349
  //#endregion
171
350
  //#region src/browser/quick-actions.d.ts
172
351
  /**
@@ -365,55 +544,6 @@ declare function browserPdf(
365
544
  input: QuickActionPage
366
545
  ): Promise<QuickActionBinary>;
367
546
  //#endregion
368
- //#region src/browser/session-manager.d.ts
369
- type MaybePromise<T> = T | Promise<T>;
370
- interface StoredBrowserSession {
371
- sessionId: string;
372
- createdAt: number;
373
- updatedAt: number;
374
- /**
375
- * Set when a sweep closed this entry's Browser Run session but kept the
376
- * entry as a tombstone, so a later resume of the owning execution fails
377
- * loudly instead of silently continuing in a fresh browser.
378
- */
379
- closedAt?: number;
380
- }
381
- interface BrowserSessionLock {
382
- release(): MaybePromise<void>;
383
- }
384
- interface BrowserSessionStore {
385
- /**
386
- * Acquire an exclusive lock for this session key. The lock must serialize
387
- * all holders using the same key. Held only around storage reads/writes —
388
- * never across Browser Rendering network calls.
389
- */
390
- acquireLock(key: string): MaybePromise<BrowserSessionLock>;
391
- get(key: string): MaybePromise<StoredBrowserSession | undefined>;
392
- set(key: string, session: StoredBrowserSession): MaybePromise<void>;
393
- delete(key: string): MaybePromise<void>;
394
- /**
395
- * List stored sessions by key prefix. Optional — used by sweeps to find
396
- * orphaned per-execution sessions; without it only the shared session key
397
- * is swept.
398
- */
399
- list?(prefix: string): MaybePromise<Map<string, StoredBrowserSession>>;
400
- }
401
- declare class DurableBrowserSessionStore implements BrowserSessionStore {
402
- #private;
403
- private readonly storage;
404
- constructor(storage: DurableObjectStorage);
405
- acquireLock(key: string): Promise<BrowserSessionLock>;
406
- get(key: string): Promise<StoredBrowserSession | undefined>;
407
- set(key: string, session: StoredBrowserSession): Promise<void>;
408
- delete(key: string): Promise<void>;
409
- list(prefix: string): Promise<Map<string, StoredBrowserSession>>;
410
- }
411
- /**
412
- * Default idle window used by {@link BrowserConnector.sweep} for the shared
413
- * (reuse/promoted) session entry.
414
- */
415
- declare const DEFAULT_SWEEP_IDLE_MS: number;
416
- //#endregion
417
547
  //#region src/browser/connector.d.ts
418
548
  /** Browser session lifecycle for the connector (binding-backed only). */
419
549
  interface BrowserConnectorSessionOptions {
@@ -496,44 +626,6 @@ interface BrowserConnectorSweepResult {
496
626
  sessionId: string;
497
627
  }>;
498
628
  }
499
- /**
500
- * Live View rendering mode (the `mode` query param the hosted UI at
501
- * `live.browser.run` understands):
502
- *
503
- * - `"tab"` — a standalone, interactive page view (best for handing control
504
- * to a human).
505
- * - `"devtools"` — the full DevTools inspector panel (Elements, Console,
506
- * Network, …).
507
- *
508
- * Omit it to use whatever mode the binding's `devtoolsFrontendUrl` defaults
509
- * to.
510
- */
511
- type LiveViewMode = "tab" | "devtools";
512
- /** A single tab's Live View URL. */
513
- interface BrowserLiveViewUrl {
514
- /** Open this in a browser to watch/control the tab in real time. */
515
- url: string;
516
- /** CDP target (tab) id the URL points at. */
517
- targetId: string;
518
- /** Milliseconds the URL stays valid from when it was generated (~5 min). */
519
- expiresInMs: number;
520
- }
521
- interface BrowserLiveViewTarget {
522
- targetId: string;
523
- /** Embeddable Live View URL (the `devtoolsFrontendUrl`) for this tab. */
524
- url: string;
525
- /** The page the tab is currently showing (e.g. `https://example.com`). */
526
- pageUrl?: string;
527
- title?: string;
528
- type?: string;
529
- }
530
- /** Live View URLs for every tab in a (shared) session. */
531
- interface BrowserLiveView {
532
- sessionId: string;
533
- targets: BrowserLiveViewTarget[];
534
- /** Milliseconds the URLs stay valid from when they were generated (~5 min). */
535
- expiresInMs: number;
536
- }
537
629
  /**
538
630
  * Default idle window before {@link BrowserConnector.sweep} reclaims a
539
631
  * per-execution session. Matches the codemode runtime's default paused TTL
@@ -621,56 +713,62 @@ declare class BrowserConnector extends CodemodeConnector {
621
713
  }
622
714
  //#endregion
623
715
  export {
624
- browserMarkdown as A,
625
- BrowserTargetInfo as B,
626
- QuickActionScrapeInput as C,
627
- browserContent as D,
628
- QuickActionSnapshot as E,
629
- runQuickAction as F,
630
- deleteBrowserSession as G,
631
- connectBrowser as H,
716
+ CdpConnection as $,
717
+ DurableBrowserSessionStore as A,
718
+ BrowserSessionInfo as B,
719
+ browserScrape as C,
720
+ BrowserSessionLock as D,
721
+ runQuickAction as E,
722
+ LiveViewMode as F,
723
+ ConnectKitesurfBrowserOptions as G,
724
+ ConnectBrowserOptions as H,
632
725
  BrowserBinding as I,
633
- CdpAttachOptions as J,
634
- getBrowserRecording as K,
726
+ createBrowserSession as J,
727
+ connectBrowser as K,
635
728
  BrowserRecording as L,
636
- browserScrape as M,
637
- browserScreenshot as N,
638
- browserExtract as O,
639
- browserSnapshot as P,
729
+ BrowserLiveView as M,
730
+ BrowserLiveViewTarget as N,
731
+ BrowserSessionStore as O,
732
+ BrowserLiveViewUrl as P,
733
+ CdpAttachOptions as Q,
640
734
  BrowserRenderingError as R,
641
- QuickActionPage as S,
642
- QuickActionScreenshotInput as T,
643
- connectBrowserSession as U,
644
- ConnectBrowserOptions as V,
645
- createBrowserSession as W,
646
- CdpSession as X,
647
- CdpSendOptions as Y,
648
- connectUrl as Z,
649
- QuickActionBinary as _,
735
+ browserPdf as S,
736
+ browserSnapshot as T,
737
+ ConnectBrowserSessionOptions as U,
738
+ BrowserTargetInfo as V,
739
+ ConnectChromiumBrowserOptions as W,
740
+ getBrowserRecording as X,
741
+ deleteBrowserSession as Y,
742
+ listBrowserTargets as Z,
743
+ QuickActionSnapshot as _,
650
744
  BrowserConnectorSweepResult as a,
651
- QuickActionExtractInput as b,
652
- BrowserLiveViewUrl as c,
653
- BrowserSessionLock as d,
654
- BrowserSessionStore as f,
655
- QuickAction as g,
656
- StoredBrowserSession as h,
745
+ browserLinks as b,
746
+ QuickActionBinary as c,
747
+ QuickActionExtractInput as d,
748
+ CdpConnectionOptions as et,
749
+ QuickActionInput as f,
750
+ QuickActionScreenshotInput as g,
751
+ QuickActionScrapeResult as h,
657
752
  BrowserConnectorSweepOptions as i,
658
- browserPdf as j,
659
- browserLinks as k,
660
- DEFAULT_EXEC_SWEEP_IDLE_MS as l,
661
- DurableBrowserSessionStore as m,
753
+ StoredBrowserSession as j,
754
+ DEFAULT_SWEEP_IDLE_MS as k,
755
+ QuickActionBinding as l,
756
+ QuickActionScrapeInput as m,
662
757
  BrowserConnectorOptions as n,
663
- BrowserLiveView as o,
664
- DEFAULT_SWEEP_IDLE_MS as p,
665
- listBrowserTargets as q,
758
+ CdpSession as nt,
759
+ DEFAULT_EXEC_SWEEP_IDLE_MS as o,
760
+ QuickActionPage as p,
761
+ connectBrowserSession as q,
666
762
  BrowserConnectorSessionOptions as r,
667
- BrowserLiveViewTarget as s,
763
+ connectUrl as rt,
764
+ QuickAction as s,
668
765
  BrowserConnector as t,
669
- LiveViewMode as u,
670
- QuickActionBinding as v,
671
- QuickActionScrapeResult as w,
672
- QuickActionInput as x,
673
- QuickActionCommonOptions as y,
674
- BrowserSessionInfo as z
766
+ CdpSendOptions as tt,
767
+ QuickActionCommonOptions as u,
768
+ browserContent as v,
769
+ browserScreenshot as w,
770
+ browserMarkdown as x,
771
+ browserExtract as y,
772
+ BrowserSessionGuardrails as z
675
773
  };
676
- //# sourceMappingURL=connector-CkQD4MK3.d.ts.map
774
+ //# sourceMappingURL=connector-Cl-VqPmA.d.ts.map
@@ -94,6 +94,22 @@ interface ContextConfig {
94
94
  * - SearchProvider (get+search+set?) → searchable via search_context
95
95
  * If omitted, auto-wired to writable SQLite when using builder. */
96
96
  provider?: ContextProvider | WritableContextProvider | SearchProvider;
97
+ /**
98
+ * What the model sees when this block's value moves on after the system
99
+ * prompt was frozen.
100
+ *
101
+ * - `"wait"` (default): nothing, until `refreshSystemPrompt()` rebuilds
102
+ * the prompt.
103
+ * - `"remind"`: `reminder()` re-reads the block and, while it differs from
104
+ * the frozen prompt, returns its current value for the host to send
105
+ * after the cached prefix. The frozen prompt, and the provider's prefix
106
+ * cache, stay intact until `refreshSystemPrompt()` promotes the value.
107
+ * The block renders in the prompt even when empty.
108
+ *
109
+ * A change is any difference in what the provider returns, so return only
110
+ * what should count: a date rather than a timestamp.
111
+ */
112
+ whenChanged?: "wait" | "remind";
97
113
  }
98
114
  /**
99
115
  * A loaded context block with computed token count.
@@ -140,6 +156,7 @@ declare class ContextBlocks {
140
156
  load(): Promise<void>;
141
157
  /** Initialize a block's provider and read its current content. */
142
158
  private loadBlock;
159
+ private readBlock;
143
160
  /**
144
161
  * Dynamically register a new context block after initialization.
145
162
  * Used by extensions to contribute context at runtime.
@@ -192,6 +209,18 @@ declare class ContextBlocks {
192
209
  * persist it. Use this after block content has changed.
193
210
  */
194
211
  refreshSystemPrompt(): Promise<string>;
212
+ /**
213
+ * Current values of the `whenChanged: "remind"` blocks that no longer
214
+ * match the frozen prompt, rendered for the host to send after the cached
215
+ * prefix: at the end of the conversation, not in the system prompt. `null`
216
+ * when nothing has changed or nothing is frozen yet.
217
+ *
218
+ * Each call re-reads those blocks from their providers. The comparison is
219
+ * against the frozen prompt itself, so it holds across restarts, and a
220
+ * reminder keeps appearing on every call until `refreshSystemPrompt()`
221
+ * folds the value in.
222
+ */
223
+ reminder(): Promise<string | null>;
195
224
  /**
196
225
  * AI tools for context blocks.
197
226
  *
@@ -104,6 +104,39 @@ function contextEntryKey(metadataTitle, content) {
104
104
  if (metadataTitle?.trim()) return slugify(metadataTitle) || `entry-${stableHash(metadataTitle)}`;
105
105
  return `${slugify(content) || "entry"}-${stableHash(content)}`;
106
106
  }
107
+ const SECTION_RULE = "═".repeat(46);
108
+ const REMINDER_PREAMBLE = "These context blocks changed after the system prompt was written. Their current values below replace the ones in the system prompt.";
109
+ /**
110
+ * Empty readonly blocks are left out of the prompt. Writable and searchable
111
+ * blocks always render so the model knows which tools can address them.
112
+ * Remind blocks always render so `promptRendersBlock` can match them exactly:
113
+ * an absent section cannot be told apart from another label's by prefix.
114
+ */
115
+ function rendersInPrompt(block, remind) {
116
+ return !!block.content || block.writable || block.isSearchable || remind;
117
+ }
118
+ function renderSection(block) {
119
+ let header = block.label.toUpperCase();
120
+ if (block.description) header += ` (${block.description})`;
121
+ if (block.maxTokens) {
122
+ const pct = Math.round(block.tokens / block.maxTokens * 100);
123
+ header += ` [${pct}% — ${block.tokens}/${block.maxTokens} tokens]`;
124
+ }
125
+ if (block.isSearchable) header += " [searchable]";
126
+ else if (!block.writable) header += " [readonly]";
127
+ else header += " [writable]";
128
+ return `${SECTION_RULE}\n${header}\n${SECTION_RULE}\n${block.content}`;
129
+ }
130
+ /**
131
+ * Whether `prompt` renders `block` exactly as it stands now. Sections are
132
+ * joined by a blank line and each opens with a rule, so padding the prompt
133
+ * with a blank line in front and a rule behind lets one containment test
134
+ * pin both ends of a section: content that only grew or shrank at the
135
+ * edges does not pass for unchanged.
136
+ */
137
+ function promptRendersBlock(prompt, block) {
138
+ return `\n\n${prompt}\n\n${SECTION_RULE}\n`.includes(`\n\n${renderSection(block)}\n\n${SECTION_RULE}\n`);
139
+ }
107
140
  /**
108
141
  * Check if a provider is writable (has a `set` method).
109
142
  */
@@ -148,8 +181,11 @@ var ContextBlocks = class {
148
181
  }
149
182
  /** Initialize a block's provider and read its current content. */
150
183
  async loadBlock(config) {
184
+ config.provider?.init?.(config.label);
185
+ return this.readBlock(config);
186
+ }
187
+ async readBlock(config) {
151
188
  const provider = config.provider;
152
- provider?.init?.(config.label);
153
189
  const content = provider ? await provider.get() ?? "" : "";
154
190
  const searchable = isSearchProvider(provider);
155
191
  return {
@@ -262,22 +298,8 @@ var ContextBlocks = class {
262
298
  return this.setBlock(label, existing.content + (needsSep ? "\n" : "") + content);
263
299
  }
264
300
  renderPrompt() {
265
- const parts = [];
266
- const sep = "═".repeat(46);
267
- for (const block of this.blocks.values()) {
268
- if (!block.content && !block.writable && !block.isSearchable) continue;
269
- let header = block.label.toUpperCase();
270
- if (block.description) header += ` (${block.description})`;
271
- if (block.maxTokens) {
272
- const pct = Math.round(block.tokens / block.maxTokens * 100);
273
- header += ` [${pct}% — ${block.tokens}/${block.maxTokens} tokens]`;
274
- }
275
- if (block.isSearchable) header += " [searchable]";
276
- else if (!block.writable) header += " [readonly]";
277
- else header += " [writable]";
278
- parts.push(`${sep}\n${header}\n${sep}\n${block.content}`);
279
- }
280
- return parts.join("\n\n");
301
+ const remind = new Set(this.configs.filter((config) => config.whenChanged === "remind").map((config) => config.label));
302
+ return Array.from(this.blocks.values()).filter((block) => rendersInPrompt(block, remind.has(block.label))).map(renderSection).join("\n\n");
281
303
  }
282
304
  /**
283
305
  * The frozen system prompt. The first call renders the blocks and stores
@@ -308,6 +330,31 @@ var ContextBlocks = class {
308
330
  return this.snapshot;
309
331
  }
310
332
  /**
333
+ * Current values of the `whenChanged: "remind"` blocks that no longer
334
+ * match the frozen prompt, rendered for the host to send after the cached
335
+ * prefix: at the end of the conversation, not in the system prompt. `null`
336
+ * when nothing has changed or nothing is frozen yet.
337
+ *
338
+ * Each call re-reads those blocks from their providers. The comparison is
339
+ * against the frozen prompt itself, so it holds across restarts, and a
340
+ * reminder keeps appearing on every call until `refreshSystemPrompt()`
341
+ * folds the value in.
342
+ */
343
+ async reminder() {
344
+ if (!this.loaded) await this.load();
345
+ const frozen = this.promptStore ? await this.promptStore.get() ?? this.snapshot : this.snapshot;
346
+ if (frozen === null) return null;
347
+ const sections = [];
348
+ for (const config of this.configs) {
349
+ if (config.whenChanged !== "remind") continue;
350
+ const block = await this.readBlock(config);
351
+ this.blocks.set(config.label, block);
352
+ if (!promptRendersBlock(frozen, block)) sections.push(renderSection(block));
353
+ }
354
+ if (sections.length === 0) return null;
355
+ return [REMINDER_PREAMBLE, ...sections].join("\n\n");
356
+ }
357
+ /**
311
358
  * AI tools for context blocks.
312
359
  *
313
360
  * Auto-wired based on provider capabilities: