agents 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abortable-C1SpfVoi.js +21 -0
- package/dist/abortable-C1SpfVoi.js.map +1 -0
- package/dist/{agent-routing-Bhdbvf7s.d.ts → agent-routing-QDcchcQP.d.ts} +10 -15
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-bJZwBMfq.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/ai-ahruGw7e.d.ts +239 -0
- package/dist/{ai-sdk-OoGkFy3s.js → ai-sdk-Bdsf6mSA.js} +2 -2
- package/dist/{ai-sdk-OoGkFy3s.js.map → ai-sdk-Bdsf6mSA.js.map} +1 -1
- package/dist/browser/ai.d.ts +8 -227
- package/dist/browser/ai.js +259 -1
- package/dist/browser/ai.js.map +1 -0
- package/dist/browser/index.d.ts +56 -46
- package/dist/browser/index.js +4 -361
- package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
- package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +5 -4
- package/dist/browser/tools/ai-sdk.js.map +1 -0
- package/dist/browser/tools/pi.d.ts +111 -0
- package/dist/browser/tools/pi.js +119 -0
- package/dist/browser/tools/pi.js.map +1 -0
- package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
- package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
- package/dist/browser/tools/tanstack-ai.js.map +1 -0
- package/dist/browser-CEdNlsaD.js +481 -0
- package/dist/browser-CEdNlsaD.js.map +1 -0
- package/dist/{browser-tmkcAAI3.d.ts → browser-D30VlpcA.d.ts} +63 -37
- package/dist/{browser-tool-CBqs6hqa.js → browser-tool-4iomavs_.js} +145 -49
- package/dist/browser-tool-4iomavs_.js.map +1 -0
- package/dist/{browser-tool-Bn-nzJQI.d.ts → browser-tool-vtrPOV8e.d.ts} +24 -5
- package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
- package/dist/capability-DBAKc6UZ.js.map +1 -0
- package/dist/{capability-runner-O5VbQzqg.d.ts → capability-runner-BiVUtjqC.d.ts} +1 -7
- package/dist/chat/index.d.ts +4 -4
- package/dist/chat/index.js +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/{client-DS3Dz9l0.d.ts → client-BGIQKJhX.d.ts} +2 -2
- package/dist/{client-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
- package/dist/connector-CtZylXdk.js.map +1 -0
- package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
- package/dist/{conversations-DH0ut_8n.d.ts → conversations-FjHDRZyD.d.ts} +4 -4
- package/dist/{current-agent-C07C5o5Y.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/{durable-object-lifecycle-DRqp475_.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
- package/dist/experimental/channels/index.d.ts +2 -2
- package/dist/experimental/channels/index.js +2 -2
- package/dist/experimental/channels/web/index.d.ts +2 -2
- package/dist/experimental/channels/web/index.js +1 -1
- package/dist/{gateway-BDC07gYO.d.ts → gateway-BFO6vRDn.d.ts} +2 -2
- package/dist/harness/ai-sdk/index.d.ts +2 -2
- package/dist/harness/ai-sdk/index.js +1 -1
- package/dist/harness/container/index.d.ts +2 -2
- package/dist/harness/container/index.js +3 -3
- package/dist/harness/opencode/index.d.ts +1 -1
- package/dist/harness/opencode/index.js +2 -2
- package/dist/harness/pi/index.d.ts +2 -2
- package/dist/harness/pi/index.js +3 -3
- package/dist/harness/store/index.d.ts +1 -1
- package/dist/harness/store/index.js +1 -1
- package/dist/harness/think/index.d.ts +2 -2
- package/dist/harness/think/index.js +363 -171
- package/dist/harness/think/index.js.map +1 -1
- package/dist/{index-D0A5tbWu.d.ts → index-BEL3ZV-s.d.ts} +2 -6
- package/dist/{index-Ib_4dwOo.d.ts → index-CBt8oRJt.d.ts} +3 -5
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/input-schema-BQykTEp_.js +20 -0
- package/dist/input-schema-BQykTEp_.js.map +1 -0
- package/dist/{input-schema-DNrpTu49.js → input-schema-D2QAtHZH.js} +3 -3
- package/dist/input-schema-D2QAtHZH.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +3 -3
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
- package/dist/lifecycle-DGorpAmA.js.map +1 -0
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/models/ai-sdk/index.js +1 -1
- package/dist/models/opencode/index.js +1 -1
- package/dist/models/pi-ai/index.js +1 -1
- package/dist/{options-pwTNq9z6.d.ts → options-CiIsJHXR.d.ts} +2 -6
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.js +1 -1
- package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
- package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-CrFCnv_J.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
- package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
- package/dist/scheduler-FIHv2-kJ.js.map +1 -0
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/session-store-Do4xkDcf.js +606 -0
- package/dist/session-store-Do4xkDcf.js.map +1 -0
- package/dist/session-store-DoPY12xM.d.ts +383 -0
- package/dist/sessions/index.d.ts +1 -1
- package/dist/sessions/index.js +1 -1
- package/dist/{sessions-B9pNuxdT.js → sessions-_vN5BEZX.js} +2 -2
- package/dist/{sessions-B9pNuxdT.js.map → sessions-_vN5BEZX.js.map} +1 -1
- package/dist/{src-DgCbZtIR.js → src-CQxJFv4l.js} +8 -8
- package/dist/src-CQxJFv4l.js.map +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -3
- package/dist/state/index.js.map +1 -1
- package/dist/{store-DLeqKuj3.d.ts → store-BKM4Xm9M.d.ts} +23 -1
- package/dist/{store-vgcPYo8K.js → store-CslVzfN7.js} +28 -2
- package/dist/store-CslVzfN7.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-CITClVer.js → streams-lsHMJhRW.js} +2 -2
- package/dist/{streams-CITClVer.js.map → streams-lsHMJhRW.js.map} +1 -1
- package/dist/{streams-fbG61qM8.d.ts → streams-vrCtbUIn.d.ts} +2 -2
- package/dist/sub-routing.d.ts +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-CkTZNaV1.js → tasks-BN_5AWqI.js} +2 -2
- package/dist/{tasks-CkTZNaV1.js.map → tasks-BN_5AWqI.js.map} +1 -1
- package/dist/{tasks-PtlB4Uyn.d.ts → tasks-E89KdwkS.d.ts} +2 -2
- package/dist/{tool-BPJEbwaX.d.ts → tool-CTp72Jb_.d.ts} +4 -4
- package/dist/tool-CxKsvxjm.js +1126 -0
- package/dist/tool-CxKsvxjm.js.map +1 -0
- package/dist/tool-DoVberpN.d.ts +301 -0
- package/dist/{tool-3PA8xjB_.js → tool-cQRkwSZZ.js} +6 -17
- package/dist/tool-cQRkwSZZ.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/voice/index.d.ts +2 -2
- package/dist/web/fetch/index.d.ts +89 -0
- package/dist/web/fetch/index.js +20 -0
- package/dist/web/fetch/index.js.map +1 -0
- package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
- package/dist/web/fetch/tools/ai-sdk.js +47 -0
- package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
- package/dist/web/fetch/tools/pi.d.ts +84 -0
- package/dist/web/fetch/tools/pi.js +88 -0
- package/dist/web/fetch/tools/pi.js.map +1 -0
- package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
- package/dist/web/fetch/tools/tanstack-ai.js +45 -0
- package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
- package/dist/{websearch → web/search}/index.d.ts +1 -1
- package/dist/{websearch → web/search}/index.js +1 -1
- package/dist/{websearch → web/search}/tools/ai-sdk.d.ts +2 -2
- package/dist/{websearch → web/search}/tools/ai-sdk.js +3 -3
- package/dist/web/search/tools/ai-sdk.js.map +1 -0
- package/dist/{websearch → web/search}/tools/pi.d.ts +3 -3
- package/dist/{websearch → web/search}/tools/pi.js +2 -2
- package/dist/web/search/tools/pi.js.map +1 -0
- package/dist/{websearch → web/search}/tools/tanstack-ai.d.ts +2 -2
- package/dist/{websearch → web/search}/tools/tanstack-ai.js +3 -3
- package/dist/web/search/tools/tanstack-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +2 -2
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-CmENGb-Z.js → websockets-C3zy8YR0.js} +3 -5
- package/dist/websockets-C3zy8YR0.js.map +1 -0
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +26 -1
- package/docs/fetch-the-web.md +276 -0
- package/docs/harnesses/pi.md +25 -0
- package/docs/index.md +99 -76
- package/docs/lifecycle.md +2 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +2 -0
- package/package.json +44 -19
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/browser/ai-sdk.js.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/tanstack-ai.js.map +0 -1
- package/dist/browser-tool-CBqs6hqa.js.map +0 -1
- package/dist/capability-B4WbF81e.js.map +0 -1
- package/dist/client-1tEQ1Oqz.js.map +0 -1
- package/dist/connector-58XDGvc3.js.map +0 -1
- package/dist/input-schema-DNrpTu49.js.map +0 -1
- package/dist/lifecycle-CFu6OV03.js.map +0 -1
- package/dist/scheduler-DZ3xQfeK.js.map +0 -1
- package/dist/src-DgCbZtIR.js.map +0 -1
- package/dist/store-vgcPYo8K.js.map +0 -1
- package/dist/tool-3PA8xjB_.js.map +0 -1
- package/dist/websearch/tools/ai-sdk.js.map +0 -1
- package/dist/websearch/tools/pi.js.map +0 -1
- package/dist/websearch/tools/tanstack-ai.js.map +0 -1
- package/dist/websockets-CmENGb-Z.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { s as LifecycleCapability } from "./capability-runner-
|
|
1
|
+
import { s as LifecycleCapability } from "./capability-runner-BiVUtjqC.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "./
|
|
3
|
+
O as CdpConnection,
|
|
4
|
+
a as ListableBrowserSessionStore,
|
|
5
|
+
d as BrowserBinding,
|
|
6
|
+
m as BrowserSessionGuardrails,
|
|
7
|
+
s as BrowserLiveView,
|
|
8
|
+
u as LiveViewMode
|
|
9
|
+
} from "./session-store-DoPY12xM.js";
|
|
10
10
|
|
|
11
11
|
//#region src/browser/spec.d.ts
|
|
12
12
|
/**
|
|
@@ -87,6 +87,16 @@ interface CdpSpecSource {
|
|
|
87
87
|
declare function loadCdpSpec(source: CdpSpecSource): Promise<SearchableCdpSpec>;
|
|
88
88
|
//#endregion
|
|
89
89
|
//#region src/browser/browser.d.ts
|
|
90
|
+
/**
|
|
91
|
+
* The scope used when a caller doesn't pick one: every caller that leaves
|
|
92
|
+
* `scope` out shares this one active tab. See {@link BrowserConnectOptions}.
|
|
93
|
+
*/
|
|
94
|
+
declare const DEFAULT_BROWSER_SCOPE = "shared";
|
|
95
|
+
/**
|
|
96
|
+
* Scope records kept per browser. Writing a new one past the cap deletes the
|
|
97
|
+
* least recently used; a scope that comes back afterwards starts fresh.
|
|
98
|
+
*/
|
|
99
|
+
declare const MAX_BROWSER_SCOPES = 100;
|
|
90
100
|
/**
|
|
91
101
|
* Browser Run settings applied every time a browser is created — including
|
|
92
102
|
* when a lost browser is replaced — so options like guardrails survive a
|
|
@@ -136,9 +146,9 @@ interface BrowserOptions {
|
|
|
136
146
|
* Where the browser's record lives. Defaults to a
|
|
137
147
|
* {@link DurableBrowserSessionStore} over the host object's storage, which
|
|
138
148
|
* requires installing the `Browser` with `Lifecycle.use()`. Passing a store
|
|
139
|
-
* lets the `Browser` work without Lifecycle.
|
|
149
|
+
* lets the `Browser` work without Lifecycle. It must implement `list`.
|
|
140
150
|
*/
|
|
141
|
-
store?:
|
|
151
|
+
store?: ListableBrowserSessionStore;
|
|
142
152
|
/** Default CDP command timeout for {@link Browser.connect}. */
|
|
143
153
|
timeoutMs?: number;
|
|
144
154
|
/**
|
|
@@ -163,32 +173,45 @@ interface ResolvedBrowser {
|
|
|
163
173
|
restarted: boolean;
|
|
164
174
|
createdAt: number;
|
|
165
175
|
updatedAt: number;
|
|
176
|
+
}
|
|
177
|
+
interface BrowserConnectOptions {
|
|
166
178
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
179
|
+
* Who is driving. Connections with the same scope share an active tab, and
|
|
180
|
+
* each scope keeps its own, so two conversations on one browser don't
|
|
181
|
+
* drive each other's page. Cookies, logins, and the tabs themselves are
|
|
182
|
+
* shared by every scope: a scope splits "which tab is mine", not the
|
|
183
|
+
* browser. Defaults to {@link DEFAULT_BROWSER_SCOPE}.
|
|
170
184
|
*/
|
|
171
|
-
|
|
185
|
+
scope?: string;
|
|
172
186
|
}
|
|
173
187
|
interface BrowserConnection {
|
|
174
188
|
name: string;
|
|
175
189
|
sessionId: string;
|
|
190
|
+
/** The scope this connection works in; see {@link BrowserConnectOptions}. */
|
|
191
|
+
scope: string;
|
|
176
192
|
/**
|
|
177
|
-
* `true` when
|
|
178
|
-
*
|
|
179
|
-
*
|
|
193
|
+
* `true` when this scope worked in an earlier browser that has since been
|
|
194
|
+
* replaced, whichever scope's connection replaced it. Its tabs and page
|
|
195
|
+
* state are gone; surface this loudly to the model. `false` on a scope's
|
|
196
|
+
* first connection, even one that replaced a lost browser: the scope had
|
|
197
|
+
* nothing to lose. This is per scope, not a browser-wide signal.
|
|
180
198
|
*/
|
|
181
199
|
restarted: boolean;
|
|
182
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* The tab this scope last worked in, when it recorded one in this
|
|
202
|
+
* browser.
|
|
203
|
+
*/
|
|
183
204
|
activeTargetId?: string;
|
|
184
205
|
/** Closing this connection does NOT close the browser. */
|
|
185
206
|
cdp: CdpConnection;
|
|
186
207
|
/**
|
|
187
|
-
* Record the tab
|
|
208
|
+
* Record the tab this scope is working in (or clear it with `undefined`).
|
|
188
209
|
* Never resurrects: returns `false` when the browser was closed or
|
|
189
210
|
* replaced since this connection resolved it.
|
|
190
211
|
*/
|
|
191
212
|
setActiveTarget(targetId: string | undefined): Promise<boolean>;
|
|
213
|
+
/** The tabs other scopes are working in, in this browser. */
|
|
214
|
+
targetsInOtherScopes(): Promise<Set<string>>;
|
|
192
215
|
/**
|
|
193
216
|
* The Chrome DevTools Protocol description this browser serves, read from
|
|
194
217
|
* the browser itself (cached per binding).
|
|
@@ -224,17 +247,17 @@ declare class Browser extends LifecycleCapability {
|
|
|
224
247
|
*/
|
|
225
248
|
resolve(): Promise<ResolvedBrowser>;
|
|
226
249
|
/**
|
|
227
|
-
* Resolve the browser and open a CDP connection to it
|
|
228
|
-
*
|
|
250
|
+
* Resolve the browser and open a CDP connection to it for one scope (see
|
|
251
|
+
* {@link BrowserConnectOptions.scope}). Commands sent over the connection
|
|
252
|
+
* refresh the record's `updatedAt` (throttled to
|
|
229
253
|
* {@link SESSION_TOUCH_INTERVAL_MS}), so hosts can tell an actively used
|
|
230
254
|
* browser from one the platform has likely reclaimed.
|
|
231
255
|
*
|
|
232
256
|
* If the browser expires between the liveness probe and the WebSocket
|
|
233
257
|
* upgrade, the record is retired and the browser resolved once more, so
|
|
234
|
-
* the caller gets a fresh browser
|
|
235
|
-
* error.
|
|
258
|
+
* the caller gets a fresh browser instead of an error.
|
|
236
259
|
*/
|
|
237
|
-
connect(): Promise<BrowserConnection>;
|
|
260
|
+
connect(options?: BrowserConnectOptions): Promise<BrowserConnection>;
|
|
238
261
|
/**
|
|
239
262
|
* Close the browser: retire the record (so the next resolve reports
|
|
240
263
|
* `restarted: true`) and delete its Browser Run session. Returns `false`
|
|
@@ -258,18 +281,21 @@ declare class Browser extends LifecycleCapability {
|
|
|
258
281
|
}
|
|
259
282
|
//#endregion
|
|
260
283
|
export {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
284
|
+
BrowserProvider as a,
|
|
285
|
+
DEFAULT_BROWSER_SCOPE as c,
|
|
286
|
+
browserRun as d,
|
|
287
|
+
CdpField as f,
|
|
288
|
+
loadCdpSpec as g,
|
|
289
|
+
SearchableCdpSpec as h,
|
|
290
|
+
BrowserOptions as i,
|
|
291
|
+
MAX_BROWSER_SCOPES as l,
|
|
292
|
+
CdpSpecSource as m,
|
|
293
|
+
BrowserConnectOptions as n,
|
|
294
|
+
BrowserRunOptions as o,
|
|
295
|
+
CdpItems as p,
|
|
296
|
+
BrowserConnection as r,
|
|
297
|
+
BrowserRunProvider as s,
|
|
272
298
|
Browser as t,
|
|
273
|
-
|
|
299
|
+
ResolvedBrowser as u
|
|
274
300
|
};
|
|
275
|
-
//# sourceMappingURL=browser-
|
|
301
|
+
//# sourceMappingURL=browser-D30VlpcA.d.ts.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
2
|
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { s as validateConnectorArgs, v as CdpProtocolError } from "./session-store-Do4xkDcf.js";
|
|
4
|
+
import { i as transformBrowserResult, r as resolveCtx } from "./tool-helpers-O5BDVEAY.js";
|
|
5
|
+
import "./browser-CEdNlsaD.js";
|
|
5
6
|
import { CodemodeConnector, DynamicWorkerExecutor, MAX_DURABLE_VALUE_BYTES, createCodemodeRuntime } from "@cloudflare/codemode";
|
|
6
7
|
/**
|
|
7
8
|
* `cdp.attachToTarget` returns `{ sessionId: "target:<targetId>" }` — a
|
|
@@ -45,7 +46,8 @@ const BROWSER_LIFETIME_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
45
46
|
const BROWSER_INSTRUCTIONS = [
|
|
46
47
|
"The browser persists between runs: tabs, cookies, and logins are still there next time. You never start or close it.",
|
|
47
48
|
"If the browser was replaced (idle timeout, crash), the result says restarted: true and earlier tabs and logins are gone. Before an action that matters (submitting a form, a purchase), check you're on the page you expect.",
|
|
48
|
-
"Page-scoped commands (Page.*, Runtime.*, DOM.*, Input.*, Network.*, Emulation.*) need sessionId: \"active\",
|
|
49
|
+
"Page-scoped commands (Page.*, Runtime.*, DOM.*, Input.*, Network.*, Emulation.*) need sessionId: \"active\", your tab, which is remembered between runs. Browser.* and Target.* commands take no sessionId.",
|
|
50
|
+
"Other open tabs (Target.getTargets) may belong to other conversations using this browser: don't close, navigate, or attach to a tab you didn't open unless the user asks.",
|
|
49
51
|
"Target.createTarget opens a tab and makes it active. To switch to another open tab, call cdp.attachToTarget({ targetId }); the sessionId it returns keeps working in later runs, while one from a raw Target.attachToTarget only works in the current run.",
|
|
50
52
|
"Tabs a page opens itself (popups, target=_blank links) don't become active; the result lists them as newTabs.",
|
|
51
53
|
"Runtime.evaluate: pass returnByValue: true, or objects come back as a remote reference with no value, and awaitPromise: true for async expressions. The value is at result.value. A thrown error doesn't reject: check exceptionDetails.",
|
|
@@ -53,6 +55,7 @@ const BROWSER_INSTRUCTIONS = [
|
|
|
53
55
|
"Pick out what you need inside Runtime.evaluate and return only that. Results over about 24,000 characters are cut short, and a single cdp.send result over 1 MB (a full-page screenshot, say) fails the run."
|
|
54
56
|
].join("\n");
|
|
55
57
|
var _browser = /* @__PURE__ */ new WeakMap();
|
|
58
|
+
var _scope = /* @__PURE__ */ new WeakMap();
|
|
56
59
|
var _states = /* @__PURE__ */ new WeakMap();
|
|
57
60
|
var _connecting = /* @__PURE__ */ new WeakMap();
|
|
58
61
|
var _reports = /* @__PURE__ */ new WeakMap();
|
|
@@ -64,8 +67,10 @@ var _BrowserSessionConnector_brand = /* @__PURE__ */ new WeakSet();
|
|
|
64
67
|
* The model never manages sessions: every execution reattaches to the
|
|
65
68
|
* browser (or gets a replacement, reported as `restarted`), and
|
|
66
69
|
* `sessionId: "active"` addresses the tab it last worked in. The active tab
|
|
67
|
-
* is stored
|
|
68
|
-
* long as the tab does
|
|
70
|
+
* is stored per scope (see {@link BrowserSessionConnectorOptions.scope}), so
|
|
71
|
+
* it survives between executions for as long as the tab does, and one
|
|
72
|
+
* scope's executions never land in another scope's tab unless the model
|
|
73
|
+
* attaches to it.
|
|
69
74
|
*
|
|
70
75
|
* The CDP socket is per pass: opened on the first call, closed when the pass
|
|
71
76
|
* ends. The browser itself outlives the execution.
|
|
@@ -75,10 +80,12 @@ var BrowserSessionConnector = class extends CodemodeConnector {
|
|
|
75
80
|
super(ctx, {});
|
|
76
81
|
_classPrivateMethodInitSpec(this, _BrowserSessionConnector_brand);
|
|
77
82
|
_classPrivateFieldInitSpec(this, _browser, void 0);
|
|
83
|
+
_classPrivateFieldInitSpec(this, _scope, void 0);
|
|
78
84
|
_classPrivateFieldInitSpec(this, _states, /* @__PURE__ */ new Map());
|
|
79
85
|
_classPrivateFieldInitSpec(this, _connecting, /* @__PURE__ */ new Map());
|
|
80
86
|
_classPrivateFieldInitSpec(this, _reports, /* @__PURE__ */ new Map());
|
|
81
87
|
_classPrivateFieldSet2(_browser, this, options.browser);
|
|
88
|
+
_classPrivateFieldSet2(_scope, this, options.scope);
|
|
82
89
|
}
|
|
83
90
|
name() {
|
|
84
91
|
return "cdp";
|
|
@@ -206,8 +213,9 @@ var BrowserSessionConnector = class extends CodemodeConnector {
|
|
|
206
213
|
};
|
|
207
214
|
}
|
|
208
215
|
/**
|
|
209
|
-
* The pass is over: note tabs the page opened, save the active
|
|
210
|
-
*
|
|
216
|
+
* The pass is over: note tabs the page opened, save the scope's active
|
|
217
|
+
* tab, note whether another scope shares it, and drop the socket. The
|
|
218
|
+
* browser stays alive.
|
|
211
219
|
*/
|
|
212
220
|
async onPassEnd(executionId) {
|
|
213
221
|
const state = _classPrivateFieldGet2(_states, this).get(executionId);
|
|
@@ -215,7 +223,8 @@ var BrowserSessionConnector = class extends CodemodeConnector {
|
|
|
215
223
|
_classPrivateFieldGet2(_states, this).delete(executionId);
|
|
216
224
|
try {
|
|
217
225
|
const open = await _assertClassBrand(_BrowserSessionConnector_brand, this, _recordNewTabs).call(this, executionId, state);
|
|
218
|
-
await _assertClassBrand(_BrowserSessionConnector_brand, this, _saveActiveTarget).call(this, state, open);
|
|
226
|
+
const active = await _assertClassBrand(_BrowserSessionConnector_brand, this, _saveActiveTarget).call(this, state, open);
|
|
227
|
+
if (active && state.activeResolved) await _assertClassBrand(_BrowserSessionConnector_brand, this, _recordSharedTab).call(this, state, active);
|
|
219
228
|
} finally {
|
|
220
229
|
state.connected.cdp.disconnect();
|
|
221
230
|
}
|
|
@@ -258,7 +267,7 @@ function _state(executionId) {
|
|
|
258
267
|
return promise;
|
|
259
268
|
}
|
|
260
269
|
async function _connect(executionId) {
|
|
261
|
-
const connected = await _classPrivateFieldGet2(_browser, this).connect();
|
|
270
|
+
const connected = await _classPrivateFieldGet2(_browser, this).connect(_classPrivateFieldGet2(_scope, this) === void 0 ? void 0 : { scope: _classPrivateFieldGet2(_scope, this) });
|
|
262
271
|
let initialPages;
|
|
263
272
|
try {
|
|
264
273
|
initialPages = await _assertClassBrand(_BrowserSessionConnector_brand, this, _pages).call(this, connected.cdp);
|
|
@@ -267,10 +276,13 @@ async function _connect(executionId) {
|
|
|
267
276
|
throw error;
|
|
268
277
|
}
|
|
269
278
|
const state = {
|
|
279
|
+
executionId,
|
|
270
280
|
connected,
|
|
271
281
|
attached: /* @__PURE__ */ new Map(),
|
|
282
|
+
workedIn: /* @__PURE__ */ new Set(),
|
|
272
283
|
initialPages: new Set(initialPages.map((page) => page.targetId)),
|
|
273
|
-
activeResolved: false
|
|
284
|
+
activeResolved: false,
|
|
285
|
+
closed: /* @__PURE__ */ new Set()
|
|
274
286
|
};
|
|
275
287
|
_classPrivateFieldGet2(_states, this).set(executionId, state);
|
|
276
288
|
_assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, executionId, connected.restarted);
|
|
@@ -281,7 +293,9 @@ function _report(executionId, restarted) {
|
|
|
281
293
|
if (!report) {
|
|
282
294
|
report = {
|
|
283
295
|
restarted,
|
|
284
|
-
newTabs: []
|
|
296
|
+
newTabs: [],
|
|
297
|
+
tabClosed: false,
|
|
298
|
+
tabShared: false
|
|
285
299
|
};
|
|
286
300
|
_classPrivateFieldGet2(_reports, this).set(executionId, report);
|
|
287
301
|
if (_classPrivateFieldGet2(_reports, this).size > MAX_PENDING_REPORTS) {
|
|
@@ -308,7 +322,18 @@ async function _recordNewTabs(executionId, state) {
|
|
|
308
322
|
}
|
|
309
323
|
const report = _assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, executionId, state.connected.restarted);
|
|
310
324
|
const opened = new Set(report.newTabs.map((tab) => tab.targetId));
|
|
311
|
-
|
|
325
|
+
let grew = true;
|
|
326
|
+
while (grew) {
|
|
327
|
+
grew = false;
|
|
328
|
+
for (const page of pages) {
|
|
329
|
+
const opener = page.openerId;
|
|
330
|
+
if (!opener || opened.has(page.targetId) || state.initialPages.has(page.targetId)) continue;
|
|
331
|
+
if (state.workedIn.has(opener) || opened.has(opener)) {
|
|
332
|
+
opened.add(page.targetId);
|
|
333
|
+
grew = true;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
312
337
|
report.newTabs = pages.filter((page) => opened.has(page.targetId)).map(({ targetId, url, title }) => ({
|
|
313
338
|
targetId,
|
|
314
339
|
url,
|
|
@@ -317,20 +342,31 @@ async function _recordNewTabs(executionId, state) {
|
|
|
317
342
|
return new Set(pages.map((page) => page.targetId));
|
|
318
343
|
}
|
|
319
344
|
/**
|
|
320
|
-
* Save the tab this pass settled on, forgetting one that has since closed
|
|
321
|
-
* Without the list of open tabs, save the choice
|
|
322
|
-
* execution checks the stored tab is still open
|
|
345
|
+
* Save the tab this pass settled on, forgetting one that has since closed,
|
|
346
|
+
* and return it. Without the list of open tabs, save the choice
|
|
347
|
+
* unchecked: the next execution checks the stored tab is still open
|
|
348
|
+
* before using it.
|
|
323
349
|
*/
|
|
324
350
|
async function _saveActiveTarget(state, open) {
|
|
325
351
|
const stored = state.connected.activeTargetId;
|
|
352
|
+
if (!state.activeResolved && stored && open && !open.has(stored) && !state.closed.has(stored)) _assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, state.executionId, state.connected.restarted).tabClosed = true;
|
|
326
353
|
const candidate = state.activeResolved ? state.activeTargetId : stored;
|
|
327
354
|
const active = candidate && (!open || open.has(candidate)) ? candidate : void 0;
|
|
328
|
-
if (active === stored) return;
|
|
355
|
+
if (active === stored) return active;
|
|
329
356
|
try {
|
|
330
357
|
await state.connected.setActiveTarget(active);
|
|
331
358
|
} catch (error) {
|
|
332
359
|
_assertClassBrand(_BrowserSessionConnector_brand, this, _warn).call(this, "save the active tab", error);
|
|
333
360
|
}
|
|
361
|
+
return active;
|
|
362
|
+
}
|
|
363
|
+
/** Report when another scope is working in this pass's tab too. */
|
|
364
|
+
async function _recordSharedTab(state, active) {
|
|
365
|
+
try {
|
|
366
|
+
if ((await state.connected.targetsInOtherScopes()).has(active)) _assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, state.executionId, state.connected.restarted).tabShared = true;
|
|
367
|
+
} catch (error) {
|
|
368
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _warn).call(this, "check whether the active tab is shared", error);
|
|
369
|
+
}
|
|
334
370
|
}
|
|
335
371
|
function _warn(action, error) {
|
|
336
372
|
console.warn(`[agents/browser] Failed to ${action} for browser "${_classPrivateFieldGet2(_browser, this).name}"`, error);
|
|
@@ -344,17 +380,18 @@ async function _resolveSessionId(state, sessionId) {
|
|
|
344
380
|
return sessionId;
|
|
345
381
|
}
|
|
346
382
|
/**
|
|
347
|
-
* Decide which tab `"active"` means, once per pass: the stored tab
|
|
348
|
-
* is still open, else
|
|
349
|
-
*
|
|
383
|
+
* Decide which tab `"active"` means, once per pass: the scope's stored tab
|
|
384
|
+
* if it is still open, else a new blank tab. Never a tab the scope didn't
|
|
385
|
+
* open, even a blank one: it may be another scope's, or a popup.
|
|
350
386
|
*/
|
|
351
387
|
async function _activeTarget(state) {
|
|
352
388
|
if (state.activeTargetId) return state.activeTargetId;
|
|
353
|
-
const
|
|
354
|
-
const
|
|
389
|
+
const { connected } = state;
|
|
390
|
+
const pages = await _assertClassBrand(_BrowserSessionConnector_brand, this, _pages).call(this, connected.cdp);
|
|
391
|
+
const stored = connected.activeTargetId;
|
|
355
392
|
let targetId = pages.find((page) => page.targetId === stored)?.targetId;
|
|
356
|
-
if (!targetId &&
|
|
357
|
-
targetId
|
|
393
|
+
if (!targetId && stored && !state.closed.has(stored)) _assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, state.executionId, connected.restarted).tabClosed = true;
|
|
394
|
+
if (!targetId) targetId = (await connected.cdp.send("Target.createTarget", { url: "about:blank" })).targetId;
|
|
358
395
|
_assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, targetId);
|
|
359
396
|
return targetId;
|
|
360
397
|
}
|
|
@@ -367,6 +404,7 @@ async function _attach(state, targetId, timeoutMs) {
|
|
|
367
404
|
if (existing) return existing;
|
|
368
405
|
const live = await state.connected.cdp.attachToTarget(targetId, { timeoutMs });
|
|
369
406
|
state.attached.set(targetId, live);
|
|
407
|
+
state.workedIn.add(targetId);
|
|
370
408
|
return live;
|
|
371
409
|
}
|
|
372
410
|
/** Track tab changes the model makes through raw Target commands. */
|
|
@@ -375,9 +413,12 @@ function _observe(state, method, params, result) {
|
|
|
375
413
|
if (method === "Target.createTarget") {
|
|
376
414
|
const created = result?.targetId;
|
|
377
415
|
if (typeof created === "string") _assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, created);
|
|
378
|
-
} else if (method === "Target.attachToTarget" && targetId)
|
|
379
|
-
|
|
416
|
+
} else if (method === "Target.attachToTarget" && targetId) {
|
|
417
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, targetId);
|
|
418
|
+
state.workedIn.add(targetId);
|
|
419
|
+
} else if (method === "Target.closeTarget" && targetId) {
|
|
380
420
|
state.attached.delete(targetId);
|
|
421
|
+
state.closed.add(targetId);
|
|
381
422
|
if (state.activeTargetId === targetId) state.activeTargetId = void 0;
|
|
382
423
|
} else if (method === "Target.detachFromTarget") {
|
|
383
424
|
for (const [target, live] of state.attached) if (target === targetId || live === params?.sessionId) state.attached.delete(target);
|
|
@@ -431,12 +472,17 @@ function targetOfHandle(handle) {
|
|
|
431
472
|
//#endregion
|
|
432
473
|
//#region src/browser/browser-tool.ts
|
|
433
474
|
/**
|
|
434
|
-
* The harness-neutral core of `browserTool`, shared by the
|
|
435
|
-
* (`agents/browser/ai-sdk
|
|
436
|
-
*
|
|
475
|
+
* The harness-neutral core of `browserTool`, shared by the adapters in
|
|
476
|
+
* `tools/` (`agents/browser/ai-sdk`, `agents/browser/tanstack-ai`,
|
|
477
|
+
* `agents/browser/pi`).
|
|
478
|
+
* Internal — not an entry point.
|
|
437
479
|
*/
|
|
438
480
|
const DEFAULT_TIMEOUT_MS = 6e4;
|
|
439
481
|
const RESTARTED_NOTICE = "The browser was restarted before this run (it expired or was closed): earlier tabs, logins, and page state are gone. Your code ran in a fresh browser — navigate again before relying on page state.";
|
|
482
|
+
const TAB_CLOSED_NOTICE = "The tab you were working in was closed (by another conversation using this browser, or a person). `sessionId: \"active\"` now opens a blank tab — navigate again before relying on page state.";
|
|
483
|
+
const TAB_SHARED_NOTICE = "Another conversation using this browser is also working in your tab, so its page may change between your runs. Open a tab of your own with Target.createTarget if you need one.";
|
|
484
|
+
/** Scopes whose runtime and connector stay built; older ones are rebuilt. */
|
|
485
|
+
const MAX_CACHED_SCOPES = 32;
|
|
440
486
|
/**
|
|
441
487
|
* A codemode runtime name per browser. Browser names are host-chosen and
|
|
442
488
|
* unrestricted; runtime names allow only `[a-zA-Z0-9_.-]`, so anything else
|
|
@@ -445,15 +491,35 @@ const RESTARTED_NOTICE = "The browser was restarted before this run (it expired
|
|
|
445
491
|
function browserRuntimeName(name) {
|
|
446
492
|
return `browser-tool_${name.replace(/[^a-zA-Z0-9_-]/g, (char) => `.${char.codePointAt(0)?.toString(16)}.`)}`;
|
|
447
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* The latest run queued per browser and scope, so runs in one scope go one
|
|
496
|
+
* at a time, even from tools built separately (one per turn, say). Per
|
|
497
|
+
* isolate, which is per Durable Object.
|
|
498
|
+
*/
|
|
499
|
+
const runQueues = /* @__PURE__ */ new WeakMap();
|
|
500
|
+
function queued(browser, scope, run) {
|
|
501
|
+
let queues = runQueues.get(browser);
|
|
502
|
+
if (!queues) runQueues.set(browser, queues = /* @__PURE__ */ new Map());
|
|
503
|
+
const next = (queues.get(scope) ?? Promise.resolve()).then(run, run);
|
|
504
|
+
const settled = next.catch(() => void 0);
|
|
505
|
+
queues.set(scope, settled);
|
|
506
|
+
settled.then(() => {
|
|
507
|
+
if (queues.get(scope) === settled) queues.delete(scope);
|
|
508
|
+
});
|
|
509
|
+
return next;
|
|
510
|
+
}
|
|
448
511
|
/** Add what happened to the browser to the codemode result. */
|
|
449
512
|
function withBrowserReport(output, report) {
|
|
450
513
|
if (!report) return output;
|
|
514
|
+
const notices = [
|
|
515
|
+
report.restarted && RESTARTED_NOTICE,
|
|
516
|
+
report.tabClosed && !report.restarted && TAB_CLOSED_NOTICE,
|
|
517
|
+
report.tabShared && TAB_SHARED_NOTICE
|
|
518
|
+
].filter((notice) => typeof notice === "string");
|
|
451
519
|
return {
|
|
452
520
|
...output,
|
|
453
|
-
...report.restarted ? {
|
|
454
|
-
|
|
455
|
-
notice: RESTARTED_NOTICE
|
|
456
|
-
} : {},
|
|
521
|
+
...report.restarted ? { restarted: true } : {},
|
|
522
|
+
...notices.length > 0 ? { notice: notices.join(" ") } : {},
|
|
457
523
|
...report.newTabs.length > 0 ? { newTabs: report.newTabs } : {}
|
|
458
524
|
};
|
|
459
525
|
}
|
|
@@ -467,21 +533,18 @@ function browserReportNotes(output) {
|
|
|
467
533
|
/**
|
|
468
534
|
* Build the codemode runtime and connector for one `browserTool`, and wrap
|
|
469
535
|
* `execute` so each result carries the browser report.
|
|
536
|
+
*
|
|
537
|
+
* Each scope gets its own connector (which knows its scope) on the same
|
|
538
|
+
* codemode runtime, built on first use. Runs in one scope wait for each
|
|
539
|
+
* other, since they drive one tab; runs in different scopes go in parallel.
|
|
470
540
|
*/
|
|
471
541
|
function createBrowserToolCore(options, adapter) {
|
|
472
542
|
const ctx = resolveCtx(options);
|
|
473
543
|
if (!ctx) throw new Error("browserTool requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()");
|
|
474
544
|
const timeout = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
executor: new DynamicWorkerExecutor({
|
|
479
|
-
loader: options.loader,
|
|
480
|
-
timeout
|
|
481
|
-
}),
|
|
482
|
-
connectors: [connector],
|
|
483
|
-
name: browserRuntimeName(options.browser.name),
|
|
484
|
-
transformResult: transformBrowserResult
|
|
545
|
+
const executor = new DynamicWorkerExecutor({
|
|
546
|
+
loader: options.loader,
|
|
547
|
+
timeout
|
|
485
548
|
});
|
|
486
549
|
const description = [
|
|
487
550
|
"Run JavaScript that drives a persistent Chrome browser over the Chrome DevTools Protocol (CDP).",
|
|
@@ -504,17 +567,50 @@ function createBrowserToolCore(options, adapter) {
|
|
|
504
567
|
].join("\n").split("\n").map((rule) => `- ${rule}`).join("\n"),
|
|
505
568
|
"- A `SyntaxError` from \"Failed to start Worker\" means your code didn't parse; its line number points into wrapper code, not yours. Check regex literals and escapes."
|
|
506
569
|
].join("\n");
|
|
507
|
-
const
|
|
570
|
+
const durableCtx = ctx;
|
|
571
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
572
|
+
function scoped(scope) {
|
|
573
|
+
const cached = scopes.get(scope);
|
|
574
|
+
if (cached) {
|
|
575
|
+
scopes.delete(scope);
|
|
576
|
+
scopes.set(scope, cached);
|
|
577
|
+
return cached;
|
|
578
|
+
}
|
|
579
|
+
const connector = new BrowserSessionConnector(durableCtx, {
|
|
580
|
+
browser: options.browser,
|
|
581
|
+
scope
|
|
582
|
+
});
|
|
583
|
+
const built = {
|
|
584
|
+
connector,
|
|
585
|
+
tool: createCodemodeRuntime({
|
|
586
|
+
ctx: durableCtx,
|
|
587
|
+
executor,
|
|
588
|
+
connectors: [connector],
|
|
589
|
+
name: browserRuntimeName(options.browser.name),
|
|
590
|
+
transformResult: transformBrowserResult
|
|
591
|
+
}).tool({ description })
|
|
592
|
+
};
|
|
593
|
+
scopes.set(scope, built);
|
|
594
|
+
if (scopes.size > MAX_CACHED_SCOPES) {
|
|
595
|
+
const oldest = scopes.keys().next().value;
|
|
596
|
+
if (oldest !== void 0) scopes.delete(oldest);
|
|
597
|
+
}
|
|
598
|
+
return built;
|
|
599
|
+
}
|
|
600
|
+
const defaultScope = options.scope ?? "shared";
|
|
601
|
+
const { inputSchema } = scoped(defaultScope).tool;
|
|
508
602
|
return {
|
|
509
|
-
description
|
|
510
|
-
inputSchema
|
|
511
|
-
|
|
512
|
-
|
|
603
|
+
description,
|
|
604
|
+
inputSchema,
|
|
605
|
+
/** Run `input` in `scope`, which defaults to the tool's `scope`. */
|
|
606
|
+
execute: (input, scope = defaultScope) => queued(options.browser, scope, async () => {
|
|
607
|
+
const { connector, tool } = scoped(scope);
|
|
608
|
+
const output = await tool.execute(input, void 0);
|
|
513
609
|
return withBrowserReport(output, connector.takeReport(output.executionId));
|
|
514
|
-
}
|
|
610
|
+
})
|
|
515
611
|
};
|
|
516
612
|
}
|
|
517
613
|
//#endregion
|
|
518
614
|
export { createBrowserToolCore as n, browserReportNotes as t };
|
|
519
615
|
|
|
520
|
-
//# sourceMappingURL=browser-tool-
|
|
616
|
+
//# sourceMappingURL=browser-tool-4iomavs_.js.map
|