agents 0.23.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.
- package/dist/{agent-routing-DE5zmCQ8.d.ts → agent-routing-0DR0Tk2v.d.ts} +270 -190
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-routing.js.map +1 -1
- package/dist/agent-tool-types.d.ts +13 -7
- package/dist/agent-tool-types.js +23 -1
- package/dist/agent-tool-types.js.map +1 -1
- package/dist/{agent-tools-y7zLfw4Q.js → agent-tools-CdJC-8Dc.js} +72 -9
- package/dist/agent-tools-CdJC-8Dc.js.map +1 -0
- package/dist/{agent-tools-DtXMTDGM.d.ts → agent-tools-YrATZJu2.d.ts} +29 -15
- package/dist/agent-tools.d.ts +6 -4
- package/dist/agent-tools.js.map +1 -1
- package/dist/ai-fm7xx1BK.js +312 -0
- package/dist/ai-fm7xx1BK.js.map +1 -0
- package/dist/base64-redaction-C1Uu29t5.js +59 -0
- package/dist/base64-redaction-C1Uu29t5.js.map +1 -0
- package/dist/browser/ai-sdk.d.ts +90 -0
- package/dist/browser/ai-sdk.js +51 -0
- package/dist/browser/ai-sdk.js.map +1 -0
- package/dist/browser/ai.d.ts +4 -4
- package/dist/browser/ai.js +1 -347
- package/dist/browser/index.d.ts +81 -79
- package/dist/browser/index.js +361 -2
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/tanstack-ai.d.ts +96 -1
- package/dist/browser/tanstack-ai.js +62 -2
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/browser-DE3d-RLk.d.ts +275 -0
- package/dist/browser-tool-CQ10e6Kj.js +480 -0
- package/dist/browser-tool-CQ10e6Kj.js.map +1 -0
- package/dist/browser-tool-DuNdlwZ9.d.ts +73 -0
- package/dist/{capability-BjSKYpzg.js → capability-B4WbF81e.js} +2 -1
- package/dist/capability-B4WbF81e.js.map +1 -0
- package/dist/{capability-runner-Be_-PLR1.d.ts → capability-runner-DBAnGr6L.d.ts} +45 -15
- package/dist/chat/index.d.ts +341 -232
- package/dist/chat/index.js +602 -72
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +42 -2
- package/dist/chat/react.js +191 -35
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.d.ts +1 -1
- package/dist/chat/transport.js +1 -1
- package/dist/chat-sdk/index.d.ts +17 -3
- package/dist/chat-sdk/index.js +28 -2
- package/dist/chat-sdk/index.js.map +1 -1
- package/dist/client-4OlMIJx-.js +591 -0
- package/dist/client-4OlMIJx-.js.map +1 -0
- package/dist/{client-jagG8a9_.js → client-fyQrLGkD.js} +2 -2
- package/dist/{client-jagG8a9_.js.map → client-fyQrLGkD.js.map} +1 -1
- package/dist/client-je3koD9Z.d.ts +446 -0
- package/dist/client.d.ts +29 -283
- package/dist/client.js +2 -274
- package/dist/{connector-CptFKzRh.js → connector-58XDGvc3.js} +251 -120
- package/dist/connector-58XDGvc3.js.map +1 -0
- package/dist/{connector-CkQD4MK3.d.ts → connector-Cl-VqPmA.d.ts} +244 -146
- package/dist/context/index.d.ts +29 -0
- package/dist/context/index.js +64 -17
- package/dist/context/index.js.map +1 -1
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/current-agent-vAk_5JMt.d.ts +93 -0
- package/dist/{current-agent-Da_C9a3b.d.ts → durable-object-lifecycle-HhgOMWq9.d.ts} +26 -127
- package/dist/harnesses/pi/index.d.ts +348 -0
- package/dist/harnesses/pi/index.js +754 -0
- package/dist/harnesses/pi/index.js.map +1 -0
- package/dist/images-iiTDSyRu.js +1631 -0
- package/dist/images-iiTDSyRu.js.map +1 -0
- package/dist/index-BreL0YrQ.d.ts +78 -0
- package/dist/index-kbSUIer3.d.ts +343 -0
- package/dist/index.d.ts +43 -41
- package/dist/index.js +2 -2
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +19 -17
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CMRGjZdw.js → lifecycle-CFu6OV03.js} +73 -29
- package/dist/lifecycle-CFu6OV03.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.js +21 -19
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +2 -2
- package/dist/{message-builder-BymO4N_D.js → message-builder-DAl9AhHH.js} +89 -4
- package/dist/message-builder-DAl9AhHH.js.map +1 -0
- package/dist/models/ai-sdk/index.d.ts +353 -0
- package/dist/models/ai-sdk/index.js +2443 -0
- package/dist/models/ai-sdk/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +313 -0
- package/dist/models/pi-ai/index.js +1795 -0
- package/dist/models/pi-ai/index.js.map +1 -0
- package/dist/observability/ai/index.js +20 -4
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/{protocol-B0nh6KNf.js → protocol-kHsr-f0X.js} +26 -12
- package/dist/{protocol-B0nh6KNf.js.map → protocol-kHsr-f0X.js.map} +1 -1
- package/dist/queue/index.d.ts +123 -0
- package/dist/queue/index.js +2 -0
- package/dist/queue-BB-zfIYF.js +406 -0
- package/dist/queue-BB-zfIYF.js.map +1 -0
- package/dist/react.d.ts +31 -13
- package/dist/react.js +190 -71
- package/dist/react.js.map +1 -1
- package/dist/{retries-D9Ds-1lz.d.ts → retries-CV6AkXmQ.d.ts} +23 -8
- package/dist/retries.d.ts +12 -8
- package/dist/retries.js +19 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-DD9NdYbF.js → scheduler-DZ3xQfeK.js} +4 -11
- package/dist/scheduler-DZ3xQfeK.js.map +1 -0
- package/dist/{scheduler-Dwh85ZGl.d.ts → scheduler-RdACNXDP.d.ts} +6 -6
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +70 -3
- package/dist/sessions/index.js +276 -67
- package/dist/sessions/index.js.map +1 -1
- package/dist/skills/index.d.ts +29 -314
- package/dist/socket-address.d.ts +16 -0
- package/dist/socket-address.js +19 -0
- package/dist/socket-address.js.map +1 -0
- package/dist/{src-DlSHshb2.js → src-BZeu-SCD.js} +541 -500
- package/dist/src-BZeu-SCD.js.map +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/index.js +137 -0
- package/dist/state/index.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-D6tJ0NN9.d.ts → streams-Cmkj9QfW.d.ts} +4 -2
- package/dist/{streams-DZKgAj9b.js → streams-DW-UCOUc.js} +9 -2
- package/dist/streams-DW-UCOUc.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-ylZgBjhj.js → tasks-68DESxf0.js} +3 -3
- package/dist/{tasks-ylZgBjhj.js.map → tasks-68DESxf0.js.map} +1 -1
- package/dist/{tasks-BRJ5zgya.d.ts → tasks-9YxYtByh.d.ts} +5 -5
- package/dist/transport-PfFnt-Ld.d.ts +525 -0
- package/dist/transport-protocol-BxyngQ_R.js +25 -0
- package/dist/transport-protocol-BxyngQ_R.js.map +1 -0
- package/dist/transport-protocol-ZTew5Wso.d.ts +27 -0
- package/dist/types-BA4anrjI.d.ts +70 -0
- package/dist/voice/index.d.ts +2 -2
- package/dist/websockets/index.d.ts +195 -69
- package/dist/websockets/index.js +3 -2
- package/dist/websockets-Ci-LZFHH.js +1030 -0
- package/dist/websockets-Ci-LZFHH.js.map +1 -0
- package/dist/wire-types-CnMt6_HR.js.map +1 -1
- package/dist/wire-types-CrjKvDyi.d.ts +300 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/dist/{ws-chat-transport-UNRIS2xl.d.ts → ws-chat-transport-BbT1A5Lc.d.ts} +51 -2
- package/dist/{ws-chat-transport-rWwta645.js → ws-chat-transport-cqMKq3IY.js} +143 -16
- package/dist/ws-chat-transport-cqMKq3IY.js.map +1 -0
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +29 -4
- package/docs/browse-the-web.md +87 -5
- package/docs/chat-agents.md +124 -16
- package/docs/client-sdk.md +30 -0
- package/docs/context.md +27 -0
- package/docs/durable-execution.md +2 -0
- package/docs/harnesses/pi.md +91 -0
- package/docs/human-in-the-loop.md +4 -0
- package/docs/index.md +4 -1
- package/docs/lifecycle.md +114 -23
- package/docs/models-pi-ai.md +325 -0
- package/docs/models.md +504 -0
- package/docs/queue.md +135 -241
- package/docs/resumable-streaming.md +2 -0
- package/docs/retries.md +1 -1
- package/docs/routing.md +13 -13
- package/docs/sessions.md +36 -1
- package/docs/state.md +1 -0
- package/docs/sub-agents.md +12 -3
- package/package.json +51 -3
- package/dist/agent-tools-y7zLfw4Q.js.map +0 -1
- package/dist/browser/ai.js.map +0 -1
- package/dist/capability-BjSKYpzg.js.map +0 -1
- package/dist/client-tools-aIBO0Fk7.d.ts +0 -53
- package/dist/client.js.map +0 -1
- package/dist/connector-CptFKzRh.js.map +0 -1
- package/dist/lifecycle-CMRGjZdw.js.map +0 -1
- package/dist/message-builder-BymO4N_D.js.map +0 -1
- package/dist/scheduler-DD9NdYbF.js.map +0 -1
- package/dist/src-DlSHshb2.js.map +0 -1
- package/dist/streams-DZKgAj9b.js.map +0 -1
- package/dist/websockets-DUfRHPRq.js +0 -502
- package/dist/websockets-DUfRHPRq.js.map +0 -1
- 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-
|
|
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
|
-
*
|
|
24
|
-
* timeouts,
|
|
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
|
|
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
|
-
|
|
35
|
-
|
|
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<
|
|
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
|
-
|
|
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<
|
|
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<
|
|
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
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
runQuickAction as
|
|
630
|
-
|
|
631
|
-
|
|
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
|
-
|
|
634
|
-
|
|
726
|
+
createBrowserSession as J,
|
|
727
|
+
connectBrowser as K,
|
|
635
728
|
BrowserRecording as L,
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
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
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
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
|
-
|
|
664
|
-
|
|
665
|
-
|
|
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
|
-
|
|
763
|
+
connectUrl as rt,
|
|
764
|
+
QuickAction as s,
|
|
668
765
|
BrowserConnector as t,
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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-
|
|
774
|
+
//# sourceMappingURL=connector-Cl-VqPmA.d.ts.map
|
package/dist/context/index.d.ts
CHANGED
|
@@ -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
|
*
|
package/dist/context/index.js
CHANGED
|
@@ -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
|
|
266
|
-
|
|
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:
|