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.
- package/dist/{agent-routing-B2XLNMxq.d.ts → agent-routing-0DR0Tk2v.d.ts} +205 -132
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-routing.js.map +1 -1
- package/dist/agent-tool-types.d.ts +28 -22
- 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-Dj5Mzlw7.d.ts → agent-tools-YrATZJu2.d.ts} +34 -20
- package/dist/agent-tools.d.ts +20 -18
- 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-B4WbF81e.js.map +1 -1
- package/dist/{capability-runner-BUBa6Ake.d.ts → capability-runner-DBAnGr6L.d.ts} +7 -2
- package/dist/chat/index.d.ts +340 -234
- package/dist/chat/index.js +592 -66
- 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-C9DAjZIY.js → client-4OlMIJx-.js} +102 -29
- package/dist/client-4OlMIJx-.js.map +1 -0
- package/dist/{client-BxdkCuVy.d.ts → client-je3koD9Z.d.ts} +45 -10
- package/dist/client.d.ts +7 -5
- package/dist/client.js +2 -2
- 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-C4w86kcN.d.ts → current-agent-vAk_5JMt.d.ts} +4 -4
- package/dist/{durable-object-lifecycle-ei7M7lqB.d.ts → durable-object-lifecycle-HhgOMWq9.d.ts} +15 -7
- package/dist/harness/pi/index.d.ts +344 -0
- package/dist/harness/pi/index.js +873 -0
- package/dist/harness/pi/index.js.map +1 -0
- package/dist/images-iiTDSyRu.js +1631 -0
- package/dist/images-iiTDSyRu.js.map +1 -0
- package/dist/{index-Dlgtd3Mj.d.ts → index-BreL0YrQ.d.ts} +2 -2
- package/dist/index-kbSUIer3.d.ts +343 -0
- package/dist/index.d.ts +46 -44
- package/dist/index.js +1 -1
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +3 -3
- package/dist/lifecycle/index.js +1 -1
- package/dist/{lifecycle-Mm_jQh7r.js → lifecycle-CFu6OV03.js} +39 -10
- package/dist/{lifecycle-Mm_jQh7r.js.map → lifecycle-CFu6OV03.js.map} +1 -1
- package/dist/mcp/client/index.d.ts +20 -20
- 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 +1 -1
- 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 +3 -3
- package/dist/queue/index.js +1 -1
- package/dist/{queue-BC9F5cUo.js → queue-BB-zfIYF.js} +2 -2
- package/dist/{queue-BC9F5cUo.js.map → queue-BB-zfIYF.js.map} +1 -1
- package/dist/react.d.ts +6 -6
- package/dist/react.js +160 -64
- package/dist/react.js.map +1 -1
- package/dist/{retries-D9B2UCq3.d.ts → retries-CV6AkXmQ.d.ts} +18 -9
- package/dist/retries.d.ts +11 -9
- package/dist/retries.js +11 -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-D_KHqxBa.js → scheduler-DZ3xQfeK.js} +2 -2
- package/dist/{scheduler-D_KHqxBa.js.map → scheduler-DZ3xQfeK.js.map} +1 -1
- package/dist/{scheduler-BGq6M5Kd.d.ts → scheduler-RdACNXDP.d.ts} +3 -3
- 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-BNU3ZiJM.js → src-BZeu-SCD.js} +423 -115
- package/dist/src-BZeu-SCD.js.map +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-BcE8JP2X.d.ts → streams-Cmkj9QfW.d.ts} +4 -2
- package/dist/{streams-CCPRV6dt.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-D4nLqVSI.js → tasks-68DESxf0.js} +2 -2
- package/dist/{tasks-D4nLqVSI.js.map → tasks-68DESxf0.js.map} +1 -1
- package/dist/{tasks-V2lCT8ZV.d.ts → tasks-9YxYtByh.d.ts} +2 -2
- package/dist/transport-PfFnt-Ld.d.ts +525 -0
- package/dist/{types-DCD6BNZH.d.ts → types-BA4anrjI.d.ts} +2 -2
- package/dist/voice/index.d.ts +2 -2
- package/dist/websockets/index.d.ts +23 -6
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-D7IzWbZb.js → websockets-Ci-LZFHH.js} +45 -20
- package/dist/{websockets-D7IzWbZb.js.map → websockets-Ci-LZFHH.js.map} +1 -1
- 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-tools.md +29 -4
- package/docs/browse-the-web.md +87 -5
- package/docs/chat-agents.md +124 -16
- package/docs/context.md +27 -0
- package/docs/durable-execution.md +2 -0
- package/docs/harnesses/pi.md +173 -0
- package/docs/human-in-the-loop.md +4 -0
- package/docs/index.md +3 -0
- package/docs/lifecycle.md +20 -4
- package/docs/models-pi-ai.md +325 -0
- package/docs/models.md +504 -0
- package/docs/resumable-streaming.md +2 -0
- package/docs/routing.md +13 -13
- package/docs/sessions.md +36 -1
- package/docs/state.md +1 -0
- package/docs/sub-agents.md +9 -0
- package/package.json +40 -2
- package/dist/agent-tools-y7zLfw4Q.js.map +0 -1
- package/dist/browser/ai.js.map +0 -1
- package/dist/client-C9DAjZIY.js.map +0 -1
- package/dist/client-tools-aIBO0Fk7.d.ts +0 -53
- package/dist/connector-CptFKzRh.js.map +0 -1
- package/dist/message-builder-BymO4N_D.js.map +0 -1
- package/dist/src-BNU3ZiJM.js.map +0 -1
- package/dist/streams-CCPRV6dt.js.map +0 -1
- package/dist/ws-chat-transport-rWwta645.js.map +0 -1
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
|
+
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
+
import { E as CdpProtocolError, k as validateConnectorArgs } from "./connector-58XDGvc3.js";
|
|
4
|
+
import { o as resolveCtx, s as transformBrowserResult } from "./ai-fm7xx1BK.js";
|
|
5
|
+
import { CodemodeConnector, DynamicWorkerExecutor, createCodemodeRuntime } from "@cloudflare/codemode";
|
|
6
|
+
/**
|
|
7
|
+
* `cdp.attachToTarget` returns `{ sessionId: "target:<targetId>" }` — a
|
|
8
|
+
* stable handle rather than a connection-scoped CDP session id, so replayed
|
|
9
|
+
* code computes identical arguments. `send` resolves it on the live socket.
|
|
10
|
+
*/
|
|
11
|
+
const ATTACH_HANDLE_PREFIX = "target:";
|
|
12
|
+
/** Chrome's JSON-RPC code for a CDP session id it doesn't know. */
|
|
13
|
+
const CDP_SESSION_NOT_FOUND = -32001;
|
|
14
|
+
/** {@link BrowserSessionConnector} `#liveParams`: nothing to detach. */
|
|
15
|
+
const DETACHED = Symbol("detached");
|
|
16
|
+
/** Reports awaiting their tool call; bounded in case a caller never reads. */
|
|
17
|
+
const MAX_PENDING_REPORTS = 100;
|
|
18
|
+
/**
|
|
19
|
+
* Commands that would end the browser. The host owns its lifetime, so the
|
|
20
|
+
* model can't close it out from under the agent (and lose its logins).
|
|
21
|
+
*/
|
|
22
|
+
const BROWSER_LIFETIME_COMMANDS = /* @__PURE__ */ new Set([
|
|
23
|
+
"Browser.close",
|
|
24
|
+
"Browser.crash",
|
|
25
|
+
"Browser.crashGpuProcess"
|
|
26
|
+
]);
|
|
27
|
+
const INSTRUCTIONS = [
|
|
28
|
+
"This browser persists between executions: tabs, cookies, and logins you leave behind are still there next time. It is managed for you — there is nothing to start, close, or reset.",
|
|
29
|
+
"The browser can still be replaced between runs (idle timeout, crash) — even between the passes of a run that paused for approval. The tool result then says restarted: true, and earlier tabs, cookies, and logins are gone. Don't assume a page from an earlier run is still there: check where you are before an action that matters (submitting a form, making a purchase).",
|
|
30
|
+
"Page-scoped commands (Page.*, Runtime.*, DOM.*, Input.*, Network.*, Emulation.*) need sessionId: \"active\" — the tab you are working in, which stays the same across executions. Example: await cdp.send({ method: \"Page.navigate\", params: { url }, sessionId: \"active\" }).",
|
|
31
|
+
"Browser- and Target-scoped commands (Target.getTargets, Target.createTarget, Browser.getVersion) take no sessionId.",
|
|
32
|
+
"Opening a tab with Target.createTarget makes it the active tab. To switch to another open tab, call cdp.attachToTarget({ targetId }): it becomes active, and the returned sessionId works like \"active\" for that tab, in this run and later ones. A raw Target.attachToTarget sent through cdp.send returns Chrome's own sessionId, which only lasts for the current run.",
|
|
33
|
+
"Tabs a page opens on its own (popups, target=_blank links) do not become active; the tool result lists them as newTabs.",
|
|
34
|
+
"cdp.send returns the CDP method result directly, not the JSON-RPC envelope: Target.createTarget returns { targetId }, Runtime.evaluate returns { result: { value } }, Page.captureScreenshot returns { data }.",
|
|
35
|
+
"Issue CDP calls sequentially — never in parallel (no Promise.all): call order is recorded for durable replay.",
|
|
36
|
+
"Page.navigate resolves before the page finishes loading. Poll Runtime.evaluate of document.readyState until it is 'complete' before reading the page.",
|
|
37
|
+
"Use cdp.spec() to discover commands, events, and types when unsure. If a command fails or times out, check cdp.getDebugLog() for recent protocol traffic.",
|
|
38
|
+
"Return small results. Write large page dumps to a file or workspace and pass references around."
|
|
39
|
+
].join("\n");
|
|
40
|
+
var _browser = /* @__PURE__ */ new WeakMap();
|
|
41
|
+
var _states = /* @__PURE__ */ new WeakMap();
|
|
42
|
+
var _connecting = /* @__PURE__ */ new WeakMap();
|
|
43
|
+
var _reports = /* @__PURE__ */ new WeakMap();
|
|
44
|
+
var _BrowserSessionConnector_brand = /* @__PURE__ */ new WeakSet();
|
|
45
|
+
/**
|
|
46
|
+
* Codemode connector exposing one host-named, persistent browser over the
|
|
47
|
+
* Chrome DevTools Protocol as the `cdp` global.
|
|
48
|
+
*
|
|
49
|
+
* The model never manages sessions: every execution reattaches to the
|
|
50
|
+
* browser (or gets a replacement, reported as `restarted`), and
|
|
51
|
+
* `sessionId: "active"` addresses the tab it last worked in. The active tab
|
|
52
|
+
* is stored on the browser's record, so it survives between executions for as
|
|
53
|
+
* long as the tab does.
|
|
54
|
+
*
|
|
55
|
+
* The CDP socket is per pass: opened on the first call, closed when the pass
|
|
56
|
+
* ends. The browser itself outlives the execution.
|
|
57
|
+
*/
|
|
58
|
+
var BrowserSessionConnector = class extends CodemodeConnector {
|
|
59
|
+
constructor(ctx, options) {
|
|
60
|
+
super(ctx, {});
|
|
61
|
+
_classPrivateMethodInitSpec(this, _BrowserSessionConnector_brand);
|
|
62
|
+
_classPrivateFieldInitSpec(this, _browser, void 0);
|
|
63
|
+
_classPrivateFieldInitSpec(this, _states, /* @__PURE__ */ new Map());
|
|
64
|
+
_classPrivateFieldInitSpec(this, _connecting, /* @__PURE__ */ new Map());
|
|
65
|
+
_classPrivateFieldInitSpec(this, _reports, /* @__PURE__ */ new Map());
|
|
66
|
+
_classPrivateFieldSet2(_browser, this, options.browser);
|
|
67
|
+
}
|
|
68
|
+
name() {
|
|
69
|
+
return "cdp";
|
|
70
|
+
}
|
|
71
|
+
instructions() {
|
|
72
|
+
return INSTRUCTIONS;
|
|
73
|
+
}
|
|
74
|
+
tool(name, tool) {
|
|
75
|
+
return validateConnectorArgs(this.name(), name, tool);
|
|
76
|
+
}
|
|
77
|
+
tools() {
|
|
78
|
+
return {
|
|
79
|
+
send: {
|
|
80
|
+
description: "Send a CDP command and return its method result directly. Pass sessionId: \"active\" for page-scoped commands; omit it for Browser/Target commands.",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
method: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "CDP method, e.g. \"Page.navigate\""
|
|
87
|
+
},
|
|
88
|
+
params: {
|
|
89
|
+
type: "object",
|
|
90
|
+
description: "CDP command parameters"
|
|
91
|
+
},
|
|
92
|
+
sessionId: {
|
|
93
|
+
type: "string",
|
|
94
|
+
description: "\"active\" for the current tab, or a handle from attachToTarget. Omit for Browser/Target commands."
|
|
95
|
+
},
|
|
96
|
+
timeoutMs: {
|
|
97
|
+
type: "number",
|
|
98
|
+
description: "Per-command timeout override in milliseconds"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
required: ["method"]
|
|
102
|
+
},
|
|
103
|
+
execute: async (args, ctx) => {
|
|
104
|
+
const { method, params, sessionId, timeoutMs } = args;
|
|
105
|
+
if (BROWSER_LIFETIME_COMMANDS.has(method)) throw new Error(`${method} is not available: this browser is managed for you and persists between runs. To close a tab, send Target.closeTarget with its targetId.`);
|
|
106
|
+
const state = await _assertClassBrand(_BrowserSessionConnector_brand, this, _state).call(this, _assertClassBrand(_BrowserSessionConnector_brand, this, _executionId).call(this, ctx));
|
|
107
|
+
const live = await _assertClassBrand(_BrowserSessionConnector_brand, this, _resolveSessionId).call(this, state, sessionId);
|
|
108
|
+
const liveParams = _assertClassBrand(_BrowserSessionConnector_brand, this, _liveParams).call(this, state, method, params);
|
|
109
|
+
if (liveParams === DETACHED) return {};
|
|
110
|
+
let result;
|
|
111
|
+
try {
|
|
112
|
+
result = await state.connected.cdp.send(method, liveParams, {
|
|
113
|
+
sessionId: live,
|
|
114
|
+
timeoutMs
|
|
115
|
+
});
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw await _assertClassBrand(_BrowserSessionConnector_brand, this, _teach).call(this, state, error, method, sessionId);
|
|
118
|
+
}
|
|
119
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _observe).call(this, state, method, liveParams, result);
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
attachToTarget: {
|
|
124
|
+
description: "Switch to an open tab: make it the active tab and return { sessionId } — a handle you can pass to page-scoped send calls for that tab.",
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
targetId: {
|
|
129
|
+
type: "string",
|
|
130
|
+
description: "Target id from Target.getTargets/createTarget"
|
|
131
|
+
},
|
|
132
|
+
timeoutMs: { type: "number" }
|
|
133
|
+
},
|
|
134
|
+
required: ["targetId"]
|
|
135
|
+
},
|
|
136
|
+
outputSchema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: { sessionId: {
|
|
139
|
+
type: "string",
|
|
140
|
+
description: "Session handle for page-scoped send calls"
|
|
141
|
+
} },
|
|
142
|
+
required: ["sessionId"]
|
|
143
|
+
},
|
|
144
|
+
execute: async (args, ctx) => {
|
|
145
|
+
const { targetId, timeoutMs } = args;
|
|
146
|
+
const state = await _assertClassBrand(_BrowserSessionConnector_brand, this, _state).call(this, _assertClassBrand(_BrowserSessionConnector_brand, this, _executionId).call(this, ctx));
|
|
147
|
+
await _assertClassBrand(_BrowserSessionConnector_brand, this, _attach).call(this, state, targetId, timeoutMs);
|
|
148
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, targetId);
|
|
149
|
+
return { sessionId: attachHandle(targetId) };
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
spec: {
|
|
153
|
+
description: "Return the searchable Chrome DevTools Protocol spec: domains with their commands, events, and types.",
|
|
154
|
+
replay: "reexecute",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {}
|
|
158
|
+
},
|
|
159
|
+
execute: async (_args, ctx) => {
|
|
160
|
+
return (await _assertClassBrand(_BrowserSessionConnector_brand, this, _state).call(this, _assertClassBrand(_BrowserSessionConnector_brand, this, _executionId).call(this, ctx))).connected.spec();
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
getDebugLog: {
|
|
164
|
+
description: "Return recent CDP protocol traffic (sends, receives, warnings) for this execution — useful to diagnose failures and timeouts.",
|
|
165
|
+
replay: "reexecute",
|
|
166
|
+
inputSchema: {
|
|
167
|
+
type: "object",
|
|
168
|
+
properties: { limit: {
|
|
169
|
+
type: "number",
|
|
170
|
+
minimum: 1,
|
|
171
|
+
description: "Max entries to return, newest last (default 50; only the last 400 are kept)"
|
|
172
|
+
} }
|
|
173
|
+
},
|
|
174
|
+
execute: async (args, ctx) => {
|
|
175
|
+
const { limit } = args ?? {};
|
|
176
|
+
return (await _assertClassBrand(_BrowserSessionConnector_brand, this, _state).call(this, _assertClassBrand(_BrowserSessionConnector_brand, this, _executionId).call(this, ctx))).connected.cdp.getDebugLog(limit);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
clearDebugLog: {
|
|
180
|
+
description: "Clear the CDP debug log for this execution.",
|
|
181
|
+
inputSchema: {
|
|
182
|
+
type: "object",
|
|
183
|
+
properties: {}
|
|
184
|
+
},
|
|
185
|
+
execute: async (_args, ctx) => {
|
|
186
|
+
(await _assertClassBrand(_BrowserSessionConnector_brand, this, _state).call(this, _assertClassBrand(_BrowserSessionConnector_brand, this, _executionId).call(this, ctx))).connected.cdp.clearDebugLog();
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* The pass is over: note tabs the page opened, save the active tab on the
|
|
194
|
+
* browser's record, and drop the socket. The browser stays alive.
|
|
195
|
+
*/
|
|
196
|
+
async onPassEnd(executionId) {
|
|
197
|
+
const state = _classPrivateFieldGet2(_states, this).get(executionId);
|
|
198
|
+
if (!state) return;
|
|
199
|
+
_classPrivateFieldGet2(_states, this).delete(executionId);
|
|
200
|
+
try {
|
|
201
|
+
const open = await _assertClassBrand(_BrowserSessionConnector_brand, this, _recordNewTabs).call(this, executionId, state);
|
|
202
|
+
await _assertClassBrand(_BrowserSessionConnector_brand, this, _saveActiveTarget).call(this, state, open);
|
|
203
|
+
} finally {
|
|
204
|
+
state.connected.cdp.disconnect();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/** Nothing per execution outlives the pass; the named browser persists. */
|
|
208
|
+
async disposeExecution(executionId) {
|
|
209
|
+
const state = _classPrivateFieldGet2(_states, this).get(executionId);
|
|
210
|
+
if (!state) return;
|
|
211
|
+
_classPrivateFieldGet2(_states, this).delete(executionId);
|
|
212
|
+
state.connected.cdp.disconnect();
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Take (and forget) what happened to the browser during an execution.
|
|
216
|
+
* `undefined` when the execution never touched the browser. Covers the
|
|
217
|
+
* passes this instance ran; see the note on `#reports`.
|
|
218
|
+
*/
|
|
219
|
+
takeReport(executionId) {
|
|
220
|
+
const report = _classPrivateFieldGet2(_reports, this).get(executionId);
|
|
221
|
+
_classPrivateFieldGet2(_reports, this).delete(executionId);
|
|
222
|
+
return report;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
function _executionId(ctx) {
|
|
226
|
+
if (!ctx?.executionId) throw new Error("Browser tools must run inside a codemode execution");
|
|
227
|
+
return ctx.executionId;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Connect once per pass. Concurrent first calls (model code that uses
|
|
231
|
+
* Promise.all despite the instructions) share one connect.
|
|
232
|
+
*/
|
|
233
|
+
function _state(executionId) {
|
|
234
|
+
const existing = _classPrivateFieldGet2(_states, this).get(executionId);
|
|
235
|
+
if (existing) return Promise.resolve(existing);
|
|
236
|
+
const inFlight = _classPrivateFieldGet2(_connecting, this).get(executionId);
|
|
237
|
+
if (inFlight) return inFlight;
|
|
238
|
+
const promise = _assertClassBrand(_BrowserSessionConnector_brand, this, _connect).call(this, executionId).finally(() => {
|
|
239
|
+
_classPrivateFieldGet2(_connecting, this).delete(executionId);
|
|
240
|
+
});
|
|
241
|
+
_classPrivateFieldGet2(_connecting, this).set(executionId, promise);
|
|
242
|
+
return promise;
|
|
243
|
+
}
|
|
244
|
+
async function _connect(executionId) {
|
|
245
|
+
const connected = await _classPrivateFieldGet2(_browser, this).connect();
|
|
246
|
+
let initialPages;
|
|
247
|
+
try {
|
|
248
|
+
initialPages = await _assertClassBrand(_BrowserSessionConnector_brand, this, _pages).call(this, connected.cdp);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
connected.cdp.disconnect();
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
const state = {
|
|
254
|
+
connected,
|
|
255
|
+
attached: /* @__PURE__ */ new Map(),
|
|
256
|
+
initialPages: new Set(initialPages.map((page) => page.targetId)),
|
|
257
|
+
activeResolved: false
|
|
258
|
+
};
|
|
259
|
+
_classPrivateFieldGet2(_states, this).set(executionId, state);
|
|
260
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, executionId, connected.restarted);
|
|
261
|
+
return state;
|
|
262
|
+
}
|
|
263
|
+
function _report(executionId, restarted) {
|
|
264
|
+
let report = _classPrivateFieldGet2(_reports, this).get(executionId);
|
|
265
|
+
if (!report) {
|
|
266
|
+
report = {
|
|
267
|
+
restarted,
|
|
268
|
+
newTabs: []
|
|
269
|
+
};
|
|
270
|
+
_classPrivateFieldGet2(_reports, this).set(executionId, report);
|
|
271
|
+
if (_classPrivateFieldGet2(_reports, this).size > MAX_PENDING_REPORTS) {
|
|
272
|
+
const oldest = _classPrivateFieldGet2(_reports, this).keys().next().value;
|
|
273
|
+
if (oldest !== void 0) _classPrivateFieldGet2(_reports, this).delete(oldest);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
report.restarted ||= restarted;
|
|
277
|
+
return report;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Add tabs the page opened this pass to the execution's report, and drop
|
|
281
|
+
* earlier ones that have since closed: `newTabs` lists page-opened tabs
|
|
282
|
+
* still open when the execution ends, across every pass. Returns the open
|
|
283
|
+
* tabs, or `undefined` when the browser couldn't be asked.
|
|
284
|
+
*/
|
|
285
|
+
async function _recordNewTabs(executionId, state) {
|
|
286
|
+
let pages;
|
|
287
|
+
try {
|
|
288
|
+
pages = await _assertClassBrand(_BrowserSessionConnector_brand, this, _pages).call(this, state.connected.cdp);
|
|
289
|
+
} catch (error) {
|
|
290
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _warn).call(this, "list the open tabs", error);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const report = _assertClassBrand(_BrowserSessionConnector_brand, this, _report).call(this, executionId, state.connected.restarted);
|
|
294
|
+
const opened = new Set(report.newTabs.map((tab) => tab.targetId));
|
|
295
|
+
for (const page of pages) if (!state.initialPages.has(page.targetId) && page.openerId) opened.add(page.targetId);
|
|
296
|
+
report.newTabs = pages.filter((page) => opened.has(page.targetId)).map(({ targetId, url, title }) => ({
|
|
297
|
+
targetId,
|
|
298
|
+
url,
|
|
299
|
+
title
|
|
300
|
+
}));
|
|
301
|
+
return new Set(pages.map((page) => page.targetId));
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Save the tab this pass settled on, forgetting one that has since closed.
|
|
305
|
+
* Without the list of open tabs, save the choice unchecked: the next
|
|
306
|
+
* execution checks the stored tab is still open before using it.
|
|
307
|
+
*/
|
|
308
|
+
async function _saveActiveTarget(state, open) {
|
|
309
|
+
const stored = state.connected.activeTargetId;
|
|
310
|
+
const candidate = state.activeResolved ? state.activeTargetId : stored;
|
|
311
|
+
const active = candidate && (!open || open.has(candidate)) ? candidate : void 0;
|
|
312
|
+
if (active === stored) return;
|
|
313
|
+
try {
|
|
314
|
+
await state.connected.setActiveTarget(active);
|
|
315
|
+
} catch (error) {
|
|
316
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _warn).call(this, "save the active tab", error);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function _warn(action, error) {
|
|
320
|
+
console.warn(`[agents/browser] Failed to ${action} for browser "${_classPrivateFieldGet2(_browser, this).name}"`, error);
|
|
321
|
+
}
|
|
322
|
+
async function _pages(cdp) {
|
|
323
|
+
return ((await cdp.send("Target.getTargets"))?.targetInfos ?? []).filter((info) => info.type === "page");
|
|
324
|
+
}
|
|
325
|
+
async function _resolveSessionId(state, sessionId) {
|
|
326
|
+
if (sessionId === "active") return _assertClassBrand(_BrowserSessionConnector_brand, this, _attach).call(this, state, await _assertClassBrand(_BrowserSessionConnector_brand, this, _activeTarget).call(this, state));
|
|
327
|
+
if (isAttachHandle(sessionId)) return _assertClassBrand(_BrowserSessionConnector_brand, this, _attach).call(this, state, targetOfHandle(sessionId));
|
|
328
|
+
return sessionId;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Decide which tab `"active"` means, once per pass: the stored tab if it
|
|
332
|
+
* is still open, else the only open tab, else a new blank tab when none
|
|
333
|
+
* are open, else the first listed tab.
|
|
334
|
+
*/
|
|
335
|
+
async function _activeTarget(state) {
|
|
336
|
+
if (state.activeTargetId) return state.activeTargetId;
|
|
337
|
+
const pages = await _assertClassBrand(_BrowserSessionConnector_brand, this, _pages).call(this, state.connected.cdp);
|
|
338
|
+
const stored = state.connected.activeTargetId;
|
|
339
|
+
let targetId = pages.find((page) => page.targetId === stored)?.targetId;
|
|
340
|
+
if (!targetId && pages.length === 0) targetId = (await state.connected.cdp.send("Target.createTarget", { url: "about:blank" })).targetId;
|
|
341
|
+
targetId ??= pages[0].targetId;
|
|
342
|
+
_assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, targetId);
|
|
343
|
+
return targetId;
|
|
344
|
+
}
|
|
345
|
+
function _setActive(state, targetId) {
|
|
346
|
+
state.activeTargetId = targetId;
|
|
347
|
+
state.activeResolved = true;
|
|
348
|
+
}
|
|
349
|
+
async function _attach(state, targetId, timeoutMs) {
|
|
350
|
+
const existing = state.attached.get(targetId);
|
|
351
|
+
if (existing) return existing;
|
|
352
|
+
const live = await state.connected.cdp.attachToTarget(targetId, { timeoutMs });
|
|
353
|
+
state.attached.set(targetId, live);
|
|
354
|
+
return live;
|
|
355
|
+
}
|
|
356
|
+
/** Track tab changes the model makes through raw Target commands. */
|
|
357
|
+
function _observe(state, method, params, result) {
|
|
358
|
+
const targetId = typeof params?.targetId === "string" ? params.targetId : void 0;
|
|
359
|
+
if (method === "Target.createTarget") {
|
|
360
|
+
const created = result?.targetId;
|
|
361
|
+
if (typeof created === "string") _assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, created);
|
|
362
|
+
} else if (method === "Target.attachToTarget" && targetId) _assertClassBrand(_BrowserSessionConnector_brand, this, _setActive).call(this, state, targetId);
|
|
363
|
+
else if (method === "Target.closeTarget" && targetId) {
|
|
364
|
+
state.attached.delete(targetId);
|
|
365
|
+
if (state.activeTargetId === targetId) state.activeTargetId = void 0;
|
|
366
|
+
} else if (method === "Target.detachFromTarget") {
|
|
367
|
+
for (const [target, live] of state.attached) if (target === targetId || live === params?.sessionId) state.attached.delete(target);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Swap a handle in `Target.detachFromTarget`'s `sessionId` param for the
|
|
372
|
+
* live CDP session id. Returns {@link DETACHED} when the handle's tab isn't
|
|
373
|
+
* attached on this socket, so there is nothing to detach.
|
|
374
|
+
*/
|
|
375
|
+
function _liveParams(state, method, params) {
|
|
376
|
+
const handle = params?.sessionId;
|
|
377
|
+
if (method !== "Target.detachFromTarget" || typeof handle !== "string") return params;
|
|
378
|
+
if (!isAttachHandle(handle)) return params;
|
|
379
|
+
const live = state.attached.get(targetOfHandle(handle));
|
|
380
|
+
return live ? {
|
|
381
|
+
...params,
|
|
382
|
+
sessionId: live
|
|
383
|
+
} : DETACHED;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Turn the common protocol mistakes into instructions: sending an
|
|
387
|
+
* event as a command, and a page-scoped command without a session.
|
|
388
|
+
*/
|
|
389
|
+
async function _teach(state, error, method, sessionId) {
|
|
390
|
+
if (!(error instanceof CdpProtocolError)) return error;
|
|
391
|
+
if (error.code === CDP_SESSION_NOT_FOUND && sessionId && sessionId !== "active" && !isAttachHandle(sessionId)) return /* @__PURE__ */ new Error(`${error.message}. CDP session ids don't carry over between runs. Use sessionId: "active" for the current tab, or the handle from cdp.attachToTarget({ targetId }) for another tab.`);
|
|
392
|
+
if (error.code !== -32601) return error;
|
|
393
|
+
if (await _assertClassBrand(_BrowserSessionConnector_brand, this, _isEvent).call(this, state, method)) return /* @__PURE__ */ new Error(`${error.message}. '${method}' is a CDP *event*, not a command — it cannot be sent. To wait for page state, poll instead (e.g. Runtime.evaluate of document.readyState until "complete").`);
|
|
394
|
+
if (!sessionId) return /* @__PURE__ */ new Error(`${error.message}. '${method}' is page-scoped: pass sessionId: "active" to run it in the current tab — cdp.send({ method: "${method}", params, sessionId: "active" }).`);
|
|
395
|
+
return error;
|
|
396
|
+
}
|
|
397
|
+
async function _isEvent(state, method) {
|
|
398
|
+
try {
|
|
399
|
+
const spec = await state.connected.spec();
|
|
400
|
+
const domain = method.split(".")[0];
|
|
401
|
+
return spec.domains.some((d) => d.name === domain && d.events.some((e) => e.event === method));
|
|
402
|
+
} catch {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function attachHandle(targetId) {
|
|
407
|
+
return `${ATTACH_HANDLE_PREFIX}${targetId}`;
|
|
408
|
+
}
|
|
409
|
+
function isAttachHandle(sessionId) {
|
|
410
|
+
return sessionId?.startsWith(ATTACH_HANDLE_PREFIX) ?? false;
|
|
411
|
+
}
|
|
412
|
+
function targetOfHandle(handle) {
|
|
413
|
+
return handle.slice(7);
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
416
|
+
//#region src/browser/browser-tool.ts
|
|
417
|
+
/**
|
|
418
|
+
* The harness-neutral core of `browserTool`, shared by the AI SDK
|
|
419
|
+
* (`agents/browser/ai-sdk`) and TanStack AI (`agents/browser/tanstack-ai`)
|
|
420
|
+
* adapters. Internal — not an entry point.
|
|
421
|
+
*/
|
|
422
|
+
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.";
|
|
423
|
+
/**
|
|
424
|
+
* A codemode runtime name per browser. Browser names are host-chosen and
|
|
425
|
+
* unrestricted; runtime names allow only `[a-zA-Z0-9_.-]`, so anything else
|
|
426
|
+
* (including `.`, the escape) is hex-escaped.
|
|
427
|
+
*/
|
|
428
|
+
function browserRuntimeName(name) {
|
|
429
|
+
return `browser-tool_${name.replace(/[^a-zA-Z0-9_-]/g, (char) => `.${char.codePointAt(0)?.toString(16)}.`)}`;
|
|
430
|
+
}
|
|
431
|
+
/** Add what happened to the browser to the codemode result. */
|
|
432
|
+
function withBrowserReport(output, report) {
|
|
433
|
+
if (!report) return output;
|
|
434
|
+
return {
|
|
435
|
+
...output,
|
|
436
|
+
...report.restarted ? {
|
|
437
|
+
restarted: true,
|
|
438
|
+
notice: RESTARTED_NOTICE
|
|
439
|
+
} : {},
|
|
440
|
+
...report.newTabs.length > 0 ? { newTabs: report.newTabs } : {}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
/** Report sentences that must survive a screenshot's text summary. */
|
|
444
|
+
function browserReportNotes(output) {
|
|
445
|
+
const notes = [];
|
|
446
|
+
if (output.notice) notes.push(output.notice);
|
|
447
|
+
if (output.newTabs?.length) notes.push(`New tabs opened by the page: ${JSON.stringify(output.newTabs)}`);
|
|
448
|
+
return notes;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Build the codemode runtime and connector for one `browserTool`, and wrap
|
|
452
|
+
* `execute` so each result carries the browser report.
|
|
453
|
+
*/
|
|
454
|
+
function createBrowserToolCore(options, adapter) {
|
|
455
|
+
const ctx = resolveCtx(options);
|
|
456
|
+
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()");
|
|
457
|
+
const connector = new BrowserSessionConnector(ctx, { browser: options.browser });
|
|
458
|
+
const codemodeTool = createCodemodeRuntime({
|
|
459
|
+
ctx,
|
|
460
|
+
executor: new DynamicWorkerExecutor({
|
|
461
|
+
loader: options.loader,
|
|
462
|
+
timeout: options.timeoutMs
|
|
463
|
+
}),
|
|
464
|
+
connectors: [connector],
|
|
465
|
+
name: browserRuntimeName(options.browser.name),
|
|
466
|
+
transformResult: transformBrowserResult
|
|
467
|
+
}).tool({ connectorHints: { cdp: `A persistent browser over CDP — tabs and logins carry over between runs. Use sessionId: "active" for page commands. ${adapter.screenshotHint}` } });
|
|
468
|
+
return {
|
|
469
|
+
description: codemodeTool.description,
|
|
470
|
+
inputSchema: codemodeTool.inputSchema,
|
|
471
|
+
execute: async (input, executeOptions) => {
|
|
472
|
+
const output = await codemodeTool.execute(input, executeOptions);
|
|
473
|
+
return withBrowserReport(output, connector.takeReport(output.executionId));
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
//#endregion
|
|
478
|
+
export { createBrowserToolCore as n, browserReportNotes as t };
|
|
479
|
+
|
|
480
|
+
//# sourceMappingURL=browser-tool-CQ10e6Kj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-tool-CQ10e6Kj.js","names":[],"sources":["../src/browser/session-connector.ts","../src/browser/browser-tool.ts"],"sourcesContent":["import {\n CodemodeConnector,\n type ConnectorTool,\n type ConnectorTools,\n type ToolExecuteContext\n} from \"@cloudflare/codemode\";\nimport { validateConnectorArgs } from \"./connector-validation\";\nimport {\n CDP_METHOD_NOT_FOUND,\n CdpProtocolError,\n type CdpConnection\n} from \"./cdp-connection\";\nimport type { BrowserConnection } from \"./browser\";\nimport type { SearchableCdpSpec } from \"./spec\";\n\n/**\n * Where a {@link BrowserSessionConnector} gets its browser. Usually a\n * `Browser` installed on the host's Lifecycle.\n */\nexport interface BrowserSource {\n /** The browser's name, for log messages. */\n readonly name: string;\n /** Reattach to the browser (or replace it) and open a CDP connection. */\n connect(): Promise<BrowserConnection>;\n}\n\nexport interface BrowserSessionConnectorOptions {\n /** The persistent browser this connector drives. */\n browser: BrowserSource;\n}\n\n/** A tab a page opened on its own during an execution. */\nexport interface BrowserNewTab {\n targetId: string;\n url?: string;\n title?: string;\n}\n\n/**\n * What happened to the browser during one execution, beyond the code's own\n * result — read by the tool after the run via\n * {@link BrowserSessionConnector.takeReport}.\n */\nexport interface BrowserExecutionReport {\n /** The browser was replaced before this run; earlier page state is gone. */\n restarted: boolean;\n /** Tabs the page opened itself (popups, `target=_blank`). */\n newTabs: BrowserNewTab[];\n}\n\n/** `sessionId` value that addresses the tab the agent is working in. */\nexport const ACTIVE_PAGE_SESSION = \"active\";\n\n/**\n * `cdp.attachToTarget` returns `{ sessionId: \"target:<targetId>\" }` — a\n * stable handle rather than a connection-scoped CDP session id, so replayed\n * code computes identical arguments. `send` resolves it on the live socket.\n */\nconst ATTACH_HANDLE_PREFIX = \"target:\";\n\n/** Chrome's JSON-RPC code for a CDP session id it doesn't know. */\nconst CDP_SESSION_NOT_FOUND = -32001;\n\n/** {@link BrowserSessionConnector} `#liveParams`: nothing to detach. */\nconst DETACHED = Symbol(\"detached\");\n\n/** Reports awaiting their tool call; bounded in case a caller never reads. */\nconst MAX_PENDING_REPORTS = 100;\n\n/**\n * Commands that would end the browser. The host owns its lifetime, so the\n * model can't close it out from under the agent (and lose its logins).\n */\nconst BROWSER_LIFETIME_COMMANDS = new Set([\n \"Browser.close\",\n \"Browser.crash\",\n \"Browser.crashGpuProcess\"\n]);\n\n/** A CDP target id — for this connector, a tab. */\ntype TargetId = string & { readonly __brand: \"TargetId\" };\n\n/** A CDP session id from `Target.attachToTarget`, valid on one socket only. */\ntype LiveSessionId = string & { readonly __brand: \"LiveSessionId\" };\n\n/** The stable `sessionId` handle `cdp.attachToTarget` gives the model. */\ntype AttachHandle = `${typeof ATTACH_HANDLE_PREFIX}${string}`;\n\ninterface TargetInfo {\n targetId: TargetId;\n type: string;\n url?: string;\n title?: string;\n /** The tab that opened this one (popups, `target=_blank` links). */\n openerId?: TargetId;\n}\n\n/** Per-execution state for one pass. Dropped when the pass ends. */\ninterface ExecutionState {\n connected: BrowserConnection;\n /** Live CDP session per target, valid on this socket only. */\n attached: Map<TargetId, LiveSessionId>;\n /** Page targets open when the pass connected. */\n initialPages: Set<TargetId>;\n /** The tab `\"active\"` resolves to — decided lazily on first use. */\n activeTargetId?: TargetId;\n /** Whether {@link activeTargetId} was decided (vs. never needed). */\n activeResolved: boolean;\n}\n\nconst INSTRUCTIONS = [\n \"This browser persists between executions: tabs, cookies, and logins you leave behind are still there next time. It is managed for you — there is nothing to start, close, or reset.\",\n \"The browser can still be replaced between runs (idle timeout, crash) — even between the passes of a run that paused for approval. The tool result then says restarted: true, and earlier tabs, cookies, and logins are gone. Don't assume a page from an earlier run is still there: check where you are before an action that matters (submitting a form, making a purchase).\",\n 'Page-scoped commands (Page.*, Runtime.*, DOM.*, Input.*, Network.*, Emulation.*) need sessionId: \"active\" — the tab you are working in, which stays the same across executions. Example: await cdp.send({ method: \"Page.navigate\", params: { url }, sessionId: \"active\" }).',\n \"Browser- and Target-scoped commands (Target.getTargets, Target.createTarget, Browser.getVersion) take no sessionId.\",\n 'Opening a tab with Target.createTarget makes it the active tab. To switch to another open tab, call cdp.attachToTarget({ targetId }): it becomes active, and the returned sessionId works like \"active\" for that tab, in this run and later ones. A raw Target.attachToTarget sent through cdp.send returns Chrome\\'s own sessionId, which only lasts for the current run.',\n \"Tabs a page opens on its own (popups, target=_blank links) do not become active; the tool result lists them as newTabs.\",\n \"cdp.send returns the CDP method result directly, not the JSON-RPC envelope: Target.createTarget returns { targetId }, Runtime.evaluate returns { result: { value } }, Page.captureScreenshot returns { data }.\",\n \"Issue CDP calls sequentially — never in parallel (no Promise.all): call order is recorded for durable replay.\",\n \"Page.navigate resolves before the page finishes loading. Poll Runtime.evaluate of document.readyState until it is 'complete' before reading the page.\",\n \"Use cdp.spec() to discover commands, events, and types when unsure. If a command fails or times out, check cdp.getDebugLog() for recent protocol traffic.\",\n \"Return small results. Write large page dumps to a file or workspace and pass references around.\"\n].join(\"\\n\");\n\n/**\n * Codemode connector exposing one host-named, persistent browser over the\n * Chrome DevTools Protocol as the `cdp` global.\n *\n * The model never manages sessions: every execution reattaches to the\n * browser (or gets a replacement, reported as `restarted`), and\n * `sessionId: \"active\"` addresses the tab it last worked in. The active tab\n * is stored on the browser's record, so it survives between executions for as\n * long as the tab does.\n *\n * The CDP socket is per pass: opened on the first call, closed when the pass\n * ends. The browser itself outlives the execution.\n */\nexport class BrowserSessionConnector extends CodemodeConnector {\n readonly #browser: BrowserSource;\n #states = new Map<string, ExecutionState>();\n #connecting = new Map<string, Promise<ExecutionState>>();\n /**\n * In memory, on this instance. An execution resumed after an approval\n * pause may run on a fresh connector, whose report starts over. Nothing\n * pauses today — the browser tool wires no approval tools — so reporting\n * across a resume is left for when approvals are added.\n *\n * The same goes for raw CDP session ids from `Target.attachToTarget` sent\n * through `send`: they belong to one pass's socket, so a replay after a\n * pause would reuse a dead id. The stable handles from `attachToTarget`\n * are the replay-safe path.\n */\n #reports = new Map<string, BrowserExecutionReport>();\n\n constructor(\n ctx: DurableObjectState | ExecutionContext,\n options: BrowserSessionConnectorOptions\n ) {\n super(ctx, {});\n this.#browser = options.browser;\n }\n\n name(): string {\n return \"cdp\";\n }\n\n protected instructions(): string {\n return INSTRUCTIONS;\n }\n\n protected override tool(name: string, tool: ConnectorTool): ConnectorTool {\n return validateConnectorArgs(this.name(), name, tool);\n }\n\n protected tools(): ConnectorTools {\n return {\n send: {\n description:\n 'Send a CDP command and return its method result directly. Pass sessionId: \"active\" for page-scoped commands; omit it for Browser/Target commands.',\n inputSchema: {\n type: \"object\",\n properties: {\n method: {\n type: \"string\",\n description: 'CDP method, e.g. \"Page.navigate\"'\n },\n params: {\n type: \"object\",\n description: \"CDP command parameters\"\n },\n sessionId: {\n type: \"string\",\n description:\n '\"active\" for the current tab, or a handle from attachToTarget. Omit for Browser/Target commands.'\n },\n timeoutMs: {\n type: \"number\",\n description: \"Per-command timeout override in milliseconds\"\n }\n },\n required: [\"method\"]\n },\n execute: async (args, ctx) => {\n const { method, params, sessionId, timeoutMs } = args as {\n method: string;\n params?: Record<string, unknown>;\n sessionId?: string;\n timeoutMs?: number;\n };\n if (BROWSER_LIFETIME_COMMANDS.has(method)) {\n throw new Error(\n `${method} is not available: this browser is managed for you ` +\n `and persists between runs. To close a tab, send ` +\n `Target.closeTarget with its targetId.`\n );\n }\n const state = await this.#state(this.#executionId(ctx));\n const live = await this.#resolveSessionId(state, sessionId);\n const liveParams = this.#liveParams(state, method, params);\n if (liveParams === DETACHED) return {};\n let result: unknown;\n try {\n result = await state.connected.cdp.send(method, liveParams, {\n sessionId: live,\n timeoutMs\n });\n } catch (error) {\n throw await this.#teach(state, error, method, sessionId);\n }\n this.#observe(state, method, liveParams, result);\n return result;\n }\n },\n\n attachToTarget: {\n description:\n \"Switch to an open tab: make it the active tab and return { sessionId } — a handle you can pass to page-scoped send calls for that tab.\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetId: {\n type: \"string\",\n description: \"Target id from Target.getTargets/createTarget\"\n },\n timeoutMs: { type: \"number\" }\n },\n required: [\"targetId\"]\n },\n outputSchema: {\n type: \"object\",\n properties: {\n sessionId: {\n type: \"string\",\n description: \"Session handle for page-scoped send calls\"\n }\n },\n required: [\"sessionId\"]\n },\n execute: async (args, ctx) => {\n const { targetId, timeoutMs } = args as {\n targetId: TargetId;\n timeoutMs?: number;\n };\n const state = await this.#state(this.#executionId(ctx));\n await this.#attach(state, targetId, timeoutMs);\n this.#setActive(state, targetId);\n return { sessionId: attachHandle(targetId) };\n }\n },\n\n spec: {\n description:\n \"Return the searchable Chrome DevTools Protocol spec: domains with their commands, events, and types.\",\n replay: \"reexecute\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx): Promise<SearchableCdpSpec> => {\n const state = await this.#state(this.#executionId(ctx));\n return state.connected.spec();\n }\n },\n\n getDebugLog: {\n description:\n \"Return recent CDP protocol traffic (sends, receives, warnings) for this execution — useful to diagnose failures and timeouts.\",\n replay: \"reexecute\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: {\n type: \"number\",\n minimum: 1,\n description:\n \"Max entries to return, newest last (default 50; only the last 400 are kept)\"\n }\n }\n },\n execute: async (args, ctx) => {\n const { limit } = (args ?? {}) as { limit?: number };\n const state = await this.#state(this.#executionId(ctx));\n return state.connected.cdp.getDebugLog(limit);\n }\n },\n\n clearDebugLog: {\n description: \"Clear the CDP debug log for this execution.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) => {\n const state = await this.#state(this.#executionId(ctx));\n state.connected.cdp.clearDebugLog();\n return null;\n }\n }\n };\n }\n\n // ── Codemode execution hooks ─────────────────────────────────────────────\n\n /**\n * The pass is over: note tabs the page opened, save the active tab on the\n * browser's record, and drop the socket. The browser stays alive.\n */\n override async onPassEnd(executionId: string): Promise<void> {\n const state = this.#states.get(executionId);\n if (!state) return;\n this.#states.delete(executionId);\n try {\n const open = await this.#recordNewTabs(executionId, state);\n await this.#saveActiveTarget(state, open);\n } finally {\n state.connected.cdp.disconnect();\n }\n }\n\n /** Nothing per execution outlives the pass; the named browser persists. */\n override async disposeExecution(executionId: string): Promise<void> {\n const state = this.#states.get(executionId);\n if (!state) return;\n this.#states.delete(executionId);\n state.connected.cdp.disconnect();\n }\n\n /**\n * Take (and forget) what happened to the browser during an execution.\n * `undefined` when the execution never touched the browser. Covers the\n * passes this instance ran; see the note on `#reports`.\n */\n takeReport(executionId: string): BrowserExecutionReport | undefined {\n const report = this.#reports.get(executionId);\n this.#reports.delete(executionId);\n return report;\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n #executionId(ctx: ToolExecuteContext | undefined): string {\n if (!ctx?.executionId) {\n throw new Error(\"Browser tools must run inside a codemode execution\");\n }\n return ctx.executionId;\n }\n\n /**\n * Connect once per pass. Concurrent first calls (model code that uses\n * Promise.all despite the instructions) share one connect.\n */\n #state(executionId: string): Promise<ExecutionState> {\n const existing = this.#states.get(executionId);\n if (existing) return Promise.resolve(existing);\n const inFlight = this.#connecting.get(executionId);\n if (inFlight) return inFlight;\n const promise = this.#connect(executionId).finally(() => {\n this.#connecting.delete(executionId);\n });\n this.#connecting.set(executionId, promise);\n return promise;\n }\n\n async #connect(executionId: string): Promise<ExecutionState> {\n const connected = await this.#browser.connect();\n let initialPages: TargetInfo[];\n try {\n initialPages = await this.#pages(connected.cdp);\n } catch (error) {\n connected.cdp.disconnect();\n throw error;\n }\n const state: ExecutionState = {\n connected,\n attached: new Map(),\n initialPages: new Set(initialPages.map((page) => page.targetId)),\n activeResolved: false\n };\n this.#states.set(executionId, state);\n this.#report(executionId, connected.restarted);\n return state;\n }\n\n #report(executionId: string, restarted: boolean): BrowserExecutionReport {\n let report = this.#reports.get(executionId);\n if (!report) {\n report = { restarted, newTabs: [] };\n this.#reports.set(executionId, report);\n if (this.#reports.size > MAX_PENDING_REPORTS) {\n const oldest = this.#reports.keys().next().value;\n if (oldest !== undefined) this.#reports.delete(oldest);\n }\n }\n // A replacement on any pass means earlier page state is gone.\n report.restarted ||= restarted;\n return report;\n }\n\n /**\n * Add tabs the page opened this pass to the execution's report, and drop\n * earlier ones that have since closed: `newTabs` lists page-opened tabs\n * still open when the execution ends, across every pass. Returns the open\n * tabs, or `undefined` when the browser couldn't be asked.\n */\n async #recordNewTabs(\n executionId: string,\n state: ExecutionState\n ): Promise<Set<TargetId> | undefined> {\n let pages: TargetInfo[];\n try {\n pages = await this.#pages(state.connected.cdp);\n } catch (error) {\n this.#warn(\"list the open tabs\", error);\n return undefined;\n }\n const report = this.#report(executionId, state.connected.restarted);\n const opened = new Set<string>(report.newTabs.map((tab) => tab.targetId));\n for (const page of pages) {\n // Chrome sets openerId only on tabs a page opened, never on\n // Target.createTarget tabs — including ones another execution sharing\n // this browser created meanwhile.\n if (!state.initialPages.has(page.targetId) && page.openerId) {\n opened.add(page.targetId);\n }\n }\n report.newTabs = pages\n .filter((page) => opened.has(page.targetId))\n .map(({ targetId, url, title }) => ({ targetId, url, title }));\n return new Set(pages.map((page) => page.targetId));\n }\n\n /**\n * Save the tab this pass settled on, forgetting one that has since closed.\n * Without the list of open tabs, save the choice unchecked: the next\n * execution checks the stored tab is still open before using it.\n */\n async #saveActiveTarget(\n state: ExecutionState,\n open: Set<TargetId> | undefined\n ): Promise<void> {\n const stored = state.connected.activeTargetId as TargetId | undefined;\n const candidate = state.activeResolved ? state.activeTargetId : stored;\n const active =\n candidate && (!open || open.has(candidate)) ? candidate : undefined;\n if (active === stored) return;\n try {\n await state.connected.setActiveTarget(active);\n } catch (error) {\n this.#warn(\"save the active tab\", error);\n }\n }\n\n #warn(action: string, error: unknown): void {\n console.warn(\n `[agents/browser] Failed to ${action} for browser \"${this.#browser.name}\"`,\n error\n );\n }\n\n async #pages(cdp: CdpConnection): Promise<TargetInfo[]> {\n const result = (await cdp.send(\"Target.getTargets\")) as {\n targetInfos?: TargetInfo[];\n };\n return (result?.targetInfos ?? []).filter((info) => info.type === \"page\");\n }\n\n async #resolveSessionId(\n state: ExecutionState,\n sessionId: string | undefined\n ): Promise<LiveSessionId | undefined> {\n if (sessionId === ACTIVE_PAGE_SESSION) {\n return this.#attach(state, await this.#activeTarget(state));\n }\n if (isAttachHandle(sessionId)) {\n return this.#attach(state, targetOfHandle(sessionId));\n }\n // Omitted, or a raw CDP session id the model got from send().\n return sessionId as LiveSessionId | undefined;\n }\n\n /**\n * Decide which tab `\"active\"` means, once per pass: the stored tab if it\n * is still open, else the only open tab, else a new blank tab when none\n * are open, else the first listed tab.\n */\n async #activeTarget(state: ExecutionState): Promise<TargetId> {\n if (state.activeTargetId) return state.activeTargetId;\n const pages = await this.#pages(state.connected.cdp);\n const stored = state.connected.activeTargetId;\n let targetId = pages.find((page) => page.targetId === stored)?.targetId;\n if (!targetId && pages.length === 0) {\n const created = (await state.connected.cdp.send(\"Target.createTarget\", {\n url: \"about:blank\"\n })) as { targetId: TargetId };\n targetId = created.targetId;\n }\n targetId ??= pages[0].targetId;\n this.#setActive(state, targetId);\n return targetId;\n }\n\n #setActive(state: ExecutionState, targetId: TargetId | undefined): void {\n state.activeTargetId = targetId;\n state.activeResolved = true;\n }\n\n async #attach(\n state: ExecutionState,\n targetId: TargetId,\n timeoutMs?: number\n ): Promise<LiveSessionId> {\n const existing = state.attached.get(targetId);\n if (existing) return existing;\n const live = (await state.connected.cdp.attachToTarget(targetId, {\n timeoutMs\n })) as LiveSessionId;\n state.attached.set(targetId, live);\n return live;\n }\n\n /** Track tab changes the model makes through raw Target commands. */\n #observe(\n state: ExecutionState,\n method: string,\n params: Record<string, unknown> | undefined,\n result: unknown\n ): void {\n const targetId =\n typeof params?.targetId === \"string\"\n ? (params.targetId as TargetId)\n : undefined;\n if (method === \"Target.createTarget\") {\n const created = (result as { targetId?: unknown } | undefined)?.targetId;\n if (typeof created === \"string\") {\n this.#setActive(state, created as TargetId);\n }\n } else if (method === \"Target.attachToTarget\" && targetId) {\n this.#setActive(state, targetId);\n } else if (method === \"Target.closeTarget\" && targetId) {\n state.attached.delete(targetId);\n // The next \"active\" use picks a tab afresh.\n if (state.activeTargetId === targetId) state.activeTargetId = undefined;\n } else if (method === \"Target.detachFromTarget\") {\n // Forget a session the model detached, so the next use reattaches.\n for (const [target, live] of state.attached) {\n if (target === targetId || live === params?.sessionId) {\n state.attached.delete(target);\n }\n }\n }\n }\n\n /**\n * Swap a handle in `Target.detachFromTarget`'s `sessionId` param for the\n * live CDP session id. Returns {@link DETACHED} when the handle's tab isn't\n * attached on this socket, so there is nothing to detach.\n */\n #liveParams(\n state: ExecutionState,\n method: string,\n params: Record<string, unknown> | undefined\n ): Record<string, unknown> | undefined | typeof DETACHED {\n const handle = params?.sessionId;\n if (method !== \"Target.detachFromTarget\" || typeof handle !== \"string\") {\n return params;\n }\n if (!isAttachHandle(handle)) return params;\n const live = state.attached.get(targetOfHandle(handle));\n return live ? { ...params, sessionId: live } : DETACHED;\n }\n\n /**\n * Turn the common protocol mistakes into instructions: sending an\n * event as a command, and a page-scoped command without a session.\n */\n async #teach(\n state: ExecutionState,\n error: unknown,\n method: string,\n sessionId: string | undefined\n ): Promise<unknown> {\n if (!(error instanceof CdpProtocolError)) return error;\n if (\n error.code === CDP_SESSION_NOT_FOUND &&\n sessionId &&\n sessionId !== ACTIVE_PAGE_SESSION &&\n !isAttachHandle(sessionId)\n ) {\n return new Error(\n `${error.message}. CDP session ids don't carry over between runs. ` +\n `Use sessionId: \"active\" for the current tab, or the handle from ` +\n `cdp.attachToTarget({ targetId }) for another tab.`\n );\n }\n if (error.code !== CDP_METHOD_NOT_FOUND) return error;\n if (await this.#isEvent(state, method)) {\n return new Error(\n `${error.message}. '${method}' is a CDP *event*, not a command — it ` +\n `cannot be sent. To wait for page state, poll instead (e.g. ` +\n `Runtime.evaluate of document.readyState until \"complete\").`\n );\n }\n if (!sessionId) {\n return new Error(\n `${error.message}. '${method}' is page-scoped: pass sessionId: ` +\n `\"active\" to run it in the current tab — ` +\n `cdp.send({ method: \"${method}\", params, sessionId: \"active\" }).`\n );\n }\n return error;\n }\n\n async #isEvent(state: ExecutionState, method: string): Promise<boolean> {\n try {\n const spec = await state.connected.spec();\n const domain = method.split(\".\")[0];\n return spec.domains.some(\n (d) => d.name === domain && d.events.some((e) => e.event === method)\n );\n } catch {\n return false;\n }\n }\n}\n\nfunction attachHandle(targetId: TargetId): AttachHandle {\n return `${ATTACH_HANDLE_PREFIX}${targetId}`;\n}\n\nfunction isAttachHandle(\n sessionId: string | undefined\n): sessionId is AttachHandle {\n return sessionId?.startsWith(ATTACH_HANDLE_PREFIX) ?? false;\n}\n\nfunction targetOfHandle(handle: AttachHandle): TargetId {\n return handle.slice(ATTACH_HANDLE_PREFIX.length) as TargetId;\n}\n","/**\n * The harness-neutral core of `browserTool`, shared by the AI SDK\n * (`agents/browser/ai-sdk`) and TanStack AI (`agents/browser/tanstack-ai`)\n * adapters. Internal — not an entry point.\n */\nimport {\n createCodemodeRuntime,\n DynamicWorkerExecutor,\n type ProxyToolOutput\n} from \"@cloudflare/codemode\";\nimport {\n BrowserSessionConnector,\n type BrowserExecutionReport,\n type BrowserNewTab,\n type BrowserSource\n} from \"./session-connector\";\nimport { resolveCtx, transformBrowserResult } from \"./tool-helpers\";\n\nexport interface BrowserToolOptions {\n /**\n * The browser the tool drives — usually a `Browser` installed on the\n * host's Lifecycle. Tools built from the same `Browser` share it.\n */\n browser: BrowserSource;\n\n /**\n * WorkerLoader binding for sandboxed code execution.\n *\n * Requires `\"worker_loaders\": [{ \"binding\": \"LOADER\" }]` in wrangler.jsonc.\n */\n loader: WorkerLoader;\n\n /** Sandbox execution timeout in milliseconds. Defaults to 30000 (30s). */\n timeoutMs?: number;\n\n /**\n * Durable Object state for the codemode runtime facet. Optional inside an\n * Agent (resolved via `getCurrentAgent()`); pass it explicitly elsewhere.\n *\n * The worker must export the `CodemodeRuntime` class (the\n * `@cloudflare/codemode/vite` plugin does this automatically, or add\n * `export { CodemodeRuntime } from \"@cloudflare/codemode\"` to your entry).\n */\n ctx?: DurableObjectState;\n}\n\n/** The model's input to `browserTool`: JavaScript to run. */\nexport interface BrowserToolInput {\n code: string;\n}\n\n/**\n * The result of one `browserTool` run: the codemode execution result,\n * plus what happened to the browser.\n */\nexport type BrowserToolOutput = ProxyToolOutput & {\n /** The browser was replaced before this run; earlier tabs are gone. */\n restarted?: true;\n /** A sentence telling the model what `restarted` means for it. */\n notice?: string;\n /** Tabs the page opened itself (popups, `target=_blank` links). */\n newTabs?: BrowserNewTab[];\n};\n\nconst RESTARTED_NOTICE =\n \"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.\";\n\n/**\n * A codemode runtime name per browser. Browser names are host-chosen and\n * unrestricted; runtime names allow only `[a-zA-Z0-9_.-]`, so anything else\n * (including `.`, the escape) is hex-escaped.\n */\nfunction browserRuntimeName(name: string): string {\n const escaped = name.replace(\n /[^a-zA-Z0-9_-]/g,\n (char) => `.${char.codePointAt(0)?.toString(16)}.`\n );\n return `browser-tool_${escaped}`;\n}\n\n/** Add what happened to the browser to the codemode result. */\nfunction withBrowserReport(\n output: ProxyToolOutput,\n report: BrowserExecutionReport | undefined\n): BrowserToolOutput {\n if (!report) return output;\n return {\n ...output,\n ...(report.restarted\n ? { restarted: true as const, notice: RESTARTED_NOTICE }\n : {}),\n ...(report.newTabs.length > 0 ? { newTabs: report.newTabs } : {})\n };\n}\n\n/** Report sentences that must survive a screenshot's text summary. */\nexport function browserReportNotes(output: BrowserToolOutput): string[] {\n const notes: string[] = [];\n if (output.notice) notes.push(output.notice);\n if (output.newTabs?.length) {\n notes.push(\n `New tabs opened by the page: ${JSON.stringify(output.newTabs)}`\n );\n }\n return notes;\n}\n\n/**\n * Build the codemode runtime and connector for one `browserTool`, and wrap\n * `execute` so each result carries the browser report.\n */\nexport function createBrowserToolCore(\n options: BrowserToolOptions,\n adapter: {\n /** What the adapter does with screenshots, told to the model. */\n screenshotHint: string;\n }\n) {\n const ctx = resolveCtx(options);\n if (!ctx) {\n throw new Error(\n \"browserTool requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()\"\n );\n }\n\n const connector = new BrowserSessionConnector(ctx, {\n browser: options.browser\n });\n const runtime = createCodemodeRuntime({\n ctx,\n executor: new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeoutMs\n }),\n connectors: [connector],\n name: browserRuntimeName(options.browser.name),\n transformResult: transformBrowserResult\n });\n\n const codemodeTool = runtime.tool({\n connectorHints: {\n cdp: `A persistent browser over CDP — tabs and logins carry over between runs. Use sessionId: \"active\" for page commands. ${adapter.screenshotHint}`\n }\n });\n\n return {\n description: codemodeTool.description,\n inputSchema: codemodeTool.inputSchema,\n execute: async (\n input: BrowserToolInput,\n executeOptions?: unknown\n ): Promise<BrowserToolOutput> => {\n const output = await codemodeTool.execute(input, executeOptions);\n return withBrowserReport(\n output,\n connector.takeReport(output.executionId)\n );\n }\n };\n}\n"],"mappings":";;;;;;;;;;AA0DA,MAAM,uBAAuB;;AAG7B,MAAM,wBAAwB;;AAG9B,MAAM,WAAW,OAAO,UAAU;;AAGlC,MAAM,sBAAsB;;;;;AAM5B,MAAM,4CAA4B,IAAI,IAAI;CACxC;CACA;CACA;AACF,CAAC;AAiCD,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;AAeX,IAAa,0BAAb,cAA6C,kBAAkB;CAiB7D,YACE,KACA,SACA;EACA,MAAM,KAAK,CAAC,CAAC;;;4DAnBL,IAAI,IAA4B,CAAA;gEAC5B,IAAI,IAAqC,CAAA;6DAY5C,IAAI,IAAoC,CAAA;EAOjD,uBAAA,UAAA,MAAgB,QAAQ,OAAA;CAC1B;CAEA,OAAe;EACb,OAAO;CACT;CAEA,eAAiC;EAC/B,OAAO;CACT;CAEA,KAAwB,MAAc,MAAoC;EACxE,OAAO,sBAAsB,KAAK,KAAK,GAAG,MAAM,IAAI;CACtD;CAEA,QAAkC;EAChC,OAAO;GACL,MAAM;IACJ,aACE;IACF,aAAa;KACX,MAAM;KACN,YAAY;MACV,QAAQ;OACN,MAAM;OACN,aAAa;MACf;MACA,QAAQ;OACN,MAAM;OACN,aAAa;MACf;MACA,WAAW;OACT,MAAM;OACN,aACE;MACJ;MACA,WAAW;OACT,MAAM;OACN,aAAa;MACf;KACF;KACA,UAAU,CAAC,QAAQ;IACrB;IACA,SAAS,OAAO,MAAM,QAAQ;KAC5B,MAAM,EAAE,QAAQ,QAAQ,WAAW,cAAc;KAMjD,IAAI,0BAA0B,IAAI,MAAM,GACtC,MAAM,IAAI,MACR,GAAG,OAAO,yIAGZ;KAEF,MAAM,QAAQ,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAA,kBAAA,gCAAY,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,GAAG,CAAC;KACtD,MAAM,OAAO,MAAA,kBAAA,gCAAM,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAuB,OAAO,SAAS;KAC1D,MAAM,aAAA,kBAAA,gCAAa,MAAA,WAAA,CAAA,CAAA,KAAA,MAAiB,OAAO,QAAQ,MAAM;KACzD,IAAI,eAAe,UAAU,OAAO,CAAC;KACrC,IAAI;KACJ,IAAI;MACF,SAAS,MAAM,MAAM,UAAU,IAAI,KAAK,QAAQ,YAAY;OAC1D,WAAW;OACX;MACF,CAAC;KACH,SAAS,OAAO;MACd,MAAM,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAY,OAAO,OAAO,QAAQ,SAAS;KACzD;KACA,kBAAA,gCAAA,MAAA,QAAA,CAAA,CAAA,KAAA,MAAc,OAAO,QAAQ,YAAY,MAAM;KAC/C,OAAO;IACT;GACF;GAEA,gBAAgB;IACd,aACE;IACF,aAAa;KACX,MAAM;KACN,YAAY;MACV,UAAU;OACR,MAAM;OACN,aAAa;MACf;MACA,WAAW,EAAE,MAAM,SAAS;KAC9B;KACA,UAAU,CAAC,UAAU;IACvB;IACA,cAAc;KACZ,MAAM;KACN,YAAY,EACV,WAAW;MACT,MAAM;MACN,aAAa;KACf,EACF;KACA,UAAU,CAAC,WAAW;IACxB;IACA,SAAS,OAAO,MAAM,QAAQ;KAC5B,MAAM,EAAE,UAAU,cAAc;KAIhC,MAAM,QAAQ,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAA,kBAAA,gCAAY,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,GAAG,CAAC;KACtD,MAAA,kBAAA,gCAAM,MAAA,OAAA,CAAA,CAAA,KAAA,MAAa,OAAO,UAAU,SAAS;KAC7C,kBAAA,gCAAA,MAAA,UAAA,CAAA,CAAA,KAAA,MAAgB,OAAO,QAAQ;KAC/B,OAAO,EAAE,WAAW,aAAa,QAAQ,EAAE;IAC7C;GACF;GAEA,MAAM;IACJ,aACE;IACF,QAAQ;IACR,aAAa;KAAE,MAAM;KAAU,YAAY,CAAC;IAAE;IAC9C,SAAS,OAAO,OAAO,QAAoC;KAEzD,QAAO,MAAA,kBAAA,gCADa,MAAA,MAAA,CAAA,CAAA,KAAA,MAAA,kBAAA,gCAAY,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,GAAG,CAAC,EAAA,CACzC,UAAU,KAAK;IAC9B;GACF;GAEA,aAAa;IACX,aACE;IACF,QAAQ;IACR,aAAa;KACX,MAAM;KACN,YAAY,EACV,OAAO;MACL,MAAM;MACN,SAAS;MACT,aACE;KACJ,EACF;IACF;IACA,SAAS,OAAO,MAAM,QAAQ;KAC5B,MAAM,EAAE,UAAW,QAAQ,CAAC;KAE5B,QAAO,MAAA,kBAAA,gCADa,MAAA,MAAA,CAAA,CAAA,KAAA,MAAA,kBAAA,gCAAY,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,GAAG,CAAC,EAAA,CACzC,UAAU,IAAI,YAAY,KAAK;IAC9C;GACF;GAEA,eAAe;IACb,aAAa;IACb,aAAa;KAAE,MAAM;KAAU,YAAY,CAAC;IAAE;IAC9C,SAAS,OAAO,OAAO,QAAQ;KAE7B,CAAA,MAAA,kBAAA,gCADoB,MAAA,MAAA,CAAA,CAAA,KAAA,MAAA,kBAAA,gCAAY,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,GAAG,CAAC,EAAA,CAChD,UAAU,IAAI,cAAc;KAClC,OAAO;IACT;GACF;EACF;CACF;;;;;CAQA,MAAe,UAAU,aAAoC;EAC3D,MAAM,QAAA,uBAAA,SAAQ,IAAA,CAAA,CAAa,IAAI,WAAW;EAC1C,IAAI,CAAC,OAAO;EACZ,uBAAA,SAAA,IAAA,CAAA,CAAa,OAAO,WAAW;EAC/B,IAAI;GACF,MAAM,OAAO,MAAA,kBAAA,gCAAM,MAAA,cAAA,CAAA,CAAA,KAAA,MAAoB,aAAa,KAAK;GACzD,MAAA,kBAAA,gCAAM,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAuB,OAAO,IAAI;EAC1C,UAAU;GACR,MAAM,UAAU,IAAI,WAAW;EACjC;CACF;;CAGA,MAAe,iBAAiB,aAAoC;EAClE,MAAM,QAAA,uBAAA,SAAQ,IAAA,CAAA,CAAa,IAAI,WAAW;EAC1C,IAAI,CAAC,OAAO;EACZ,uBAAA,SAAA,IAAA,CAAA,CAAa,OAAO,WAAW;EAC/B,MAAM,UAAU,IAAI,WAAW;CACjC;;;;;;CAOA,WAAW,aAAyD;EAClE,MAAM,SAAA,uBAAA,UAAS,IAAA,CAAA,CAAc,IAAI,WAAW;EAC5C,uBAAA,UAAA,IAAA,CAAA,CAAc,OAAO,WAAW;EAChC,OAAO;CACT;AA+RF;AA3RE,SAAA,aAAa,KAA6C;CACxD,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MAAM,oDAAoD;CAEtE,OAAO,IAAI;AACb;;;;;AAMA,SAAA,OAAO,aAA8C;CACnD,MAAM,WAAA,uBAAA,SAAW,IAAA,CAAA,CAAa,IAAI,WAAW;CAC7C,IAAI,UAAU,OAAO,QAAQ,QAAQ,QAAQ;CAC7C,MAAM,WAAA,uBAAA,aAAW,IAAA,CAAA,CAAiB,IAAI,WAAW;CACjD,IAAI,UAAU,OAAO;CACrB,MAAM,UAAA,kBAAA,gCAAU,MAAA,QAAA,CAAA,CAAA,KAAA,MAAc,WAAW,CAAC,CAAC,cAAc;EACvD,uBAAA,aAAA,IAAA,CAAA,CAAiB,OAAO,WAAW;CACrC,CAAC;CACD,uBAAA,aAAA,IAAA,CAAA,CAAiB,IAAI,aAAa,OAAO;CACzC,OAAO;AACT;AAEA,eAAA,SAAe,aAA8C;CAC3D,MAAM,YAAY,MAAA,uBAAA,UAAM,IAAA,CAAA,CAAc,QAAQ;CAC9C,IAAI;CACJ,IAAI;EACF,eAAe,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAY,UAAU,GAAG;CAChD,SAAS,OAAO;EACd,UAAU,IAAI,WAAW;EACzB,MAAM;CACR;CACA,MAAM,QAAwB;EAC5B;EACA,0BAAU,IAAI,IAAI;EAClB,cAAc,IAAI,IAAI,aAAa,KAAK,SAAS,KAAK,QAAQ,CAAC;EAC/D,gBAAgB;CAClB;CACA,uBAAA,SAAA,IAAA,CAAA,CAAa,IAAI,aAAa,KAAK;CACnC,kBAAA,gCAAA,MAAA,OAAA,CAAA,CAAA,KAAA,MAAa,aAAa,UAAU,SAAS;CAC7C,OAAO;AACT;AAEA,SAAA,QAAQ,aAAqB,WAA4C;CACvE,IAAI,SAAA,uBAAA,UAAS,IAAA,CAAA,CAAc,IAAI,WAAW;CAC1C,IAAI,CAAC,QAAQ;EACX,SAAS;GAAE;GAAW,SAAS,CAAC;EAAE;EAClC,uBAAA,UAAA,IAAA,CAAA,CAAc,IAAI,aAAa,MAAM;EACrC,IAAA,uBAAA,UAAI,IAAA,CAAA,CAAc,OAAO,qBAAqB;GAC5C,MAAM,SAAA,uBAAA,UAAS,IAAA,CAAA,CAAc,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GAC3C,IAAI,WAAW,KAAA,GAAW,uBAAA,UAAA,IAAA,CAAA,CAAc,OAAO,MAAM;EACvD;CACF;CAEA,OAAO,cAAc;CACrB,OAAO;AACT;;;;;;;AAQA,eAAA,eACE,aACA,OACoC;CACpC,IAAI;CACJ,IAAI;EACF,QAAQ,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAY,MAAM,UAAU,GAAG;CAC/C,SAAS,OAAO;EACd,kBAAA,gCAAA,MAAA,KAAA,CAAA,CAAA,KAAA,MAAW,sBAAsB,KAAK;EACtC;CACF;CACA,MAAM,SAAA,kBAAA,gCAAS,MAAA,OAAA,CAAA,CAAA,KAAA,MAAa,aAAa,MAAM,UAAU,SAAS;CAClE,MAAM,SAAS,IAAI,IAAY,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC;CACxE,KAAK,MAAM,QAAQ,OAIjB,IAAI,CAAC,MAAM,aAAa,IAAI,KAAK,QAAQ,KAAK,KAAK,UACjD,OAAO,IAAI,KAAK,QAAQ;CAG5B,OAAO,UAAU,MACd,QAAQ,SAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAC3C,KAAK,EAAE,UAAU,KAAK,aAAa;EAAE;EAAU;EAAK;CAAM,EAAE;CAC/D,OAAO,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,QAAQ,CAAC;AACnD;;;;;;AAOA,eAAA,kBACE,OACA,MACe;CACf,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,YAAY,MAAM,iBAAiB,MAAM,iBAAiB;CAChE,MAAM,SACJ,cAAc,CAAC,QAAQ,KAAK,IAAI,SAAS,KAAK,YAAY,KAAA;CAC5D,IAAI,WAAW,QAAQ;CACvB,IAAI;EACF,MAAM,MAAM,UAAU,gBAAgB,MAAM;CAC9C,SAAS,OAAO;EACd,kBAAA,gCAAA,MAAA,KAAA,CAAA,CAAA,KAAA,MAAW,uBAAuB,KAAK;CACzC;AACF;AAEA,SAAA,MAAM,QAAgB,OAAsB;CAC1C,QAAQ,KACN,8BAA8B,OAAO,gBAAA,uBAAA,UAAgB,IAAA,CAAA,CAAc,KAAK,IACxE,KACF;AACF;AAEA,eAAA,OAAa,KAA2C;CAItD,SAAQ,MAHc,IAAI,KAAK,mBAAmB,EAAA,EAGlC,eAAe,CAAC,EAAA,CAAG,QAAQ,SAAS,KAAK,SAAS,MAAM;AAC1E;AAEA,eAAA,kBACE,OACA,WACoC;CACpC,IAAI,cAAA,UACF,OAAA,kBAAA,gCAAO,MAAA,OAAA,CAAA,CAAA,KAAA,MAAa,OAAO,MAAA,kBAAA,gCAAM,MAAA,aAAA,CAAA,CAAA,KAAA,MAAmB,KAAK,CAAC;CAE5D,IAAI,eAAe,SAAS,GAC1B,OAAA,kBAAA,gCAAO,MAAA,OAAA,CAAA,CAAA,KAAA,MAAa,OAAO,eAAe,SAAS,CAAC;CAGtD,OAAO;AACT;;;;;;AAOA,eAAA,cAAoB,OAA0C;CAC5D,IAAI,MAAM,gBAAgB,OAAO,MAAM;CACvC,MAAM,QAAQ,MAAA,kBAAA,gCAAM,MAAA,MAAA,CAAA,CAAA,KAAA,MAAY,MAAM,UAAU,GAAG;CACnD,MAAM,SAAS,MAAM,UAAU;CAC/B,IAAI,WAAW,MAAM,MAAM,SAAS,KAAK,aAAa,MAAM,CAAC,EAAE;CAC/D,IAAI,CAAC,YAAY,MAAM,WAAW,GAIhC,YAAW,MAHY,MAAM,UAAU,IAAI,KAAK,uBAAuB,EACrE,KAAK,cACP,CAAC,EAAA,CACkB;CAErB,aAAa,MAAM,EAAE,CAAC;CACtB,kBAAA,gCAAA,MAAA,UAAA,CAAA,CAAA,KAAA,MAAgB,OAAO,QAAQ;CAC/B,OAAO;AACT;AAEA,SAAA,WAAW,OAAuB,UAAsC;CACtE,MAAM,iBAAiB;CACvB,MAAM,iBAAiB;AACzB;AAEA,eAAA,QACE,OACA,UACA,WACwB;CACxB,MAAM,WAAW,MAAM,SAAS,IAAI,QAAQ;CAC5C,IAAI,UAAU,OAAO;CACrB,MAAM,OAAQ,MAAM,MAAM,UAAU,IAAI,eAAe,UAAU,EAC/D,UACF,CAAC;CACD,MAAM,SAAS,IAAI,UAAU,IAAI;CACjC,OAAO;AACT;;AAGA,SAAA,SACE,OACA,QACA,QACA,QACM;CACN,MAAM,WACJ,OAAO,QAAQ,aAAa,WACvB,OAAO,WACR,KAAA;CACN,IAAI,WAAW,uBAAuB;EACpC,MAAM,UAAW,QAA+C;EAChE,IAAI,OAAO,YAAY,UACrB,kBAAA,gCAAA,MAAA,UAAA,CAAA,CAAA,KAAA,MAAgB,OAAO,OAAmB;CAE9C,OAAO,IAAI,WAAW,2BAA2B,UAC/C,kBAAA,gCAAA,MAAA,UAAA,CAAA,CAAA,KAAA,MAAgB,OAAO,QAAQ;MAC1B,IAAI,WAAW,wBAAwB,UAAU;EACtD,MAAM,SAAS,OAAO,QAAQ;EAE9B,IAAI,MAAM,mBAAmB,UAAU,MAAM,iBAAiB,KAAA;CAChE,OAAO,IAAI,WAAW;OAEf,MAAM,CAAC,QAAQ,SAAS,MAAM,UACjC,IAAI,WAAW,YAAY,SAAS,QAAQ,WAC1C,MAAM,SAAS,OAAO,MAAM;CAAA;AAIpC;;;;;;AAOA,SAAA,YACE,OACA,QACA,QACuD;CACvD,MAAM,SAAS,QAAQ;CACvB,IAAI,WAAW,6BAA6B,OAAO,WAAW,UAC5D,OAAO;CAET,IAAI,CAAC,eAAe,MAAM,GAAG,OAAO;CACpC,MAAM,OAAO,MAAM,SAAS,IAAI,eAAe,MAAM,CAAC;CACtD,OAAO,OAAO;EAAE,GAAG;EAAQ,WAAW;CAAK,IAAI;AACjD;;;;;AAMA,eAAA,OACE,OACA,OACA,QACA,WACkB;CAClB,IAAI,EAAE,iBAAiB,mBAAmB,OAAO;CACjD,IACE,MAAM,SAAS,yBACf,aACA,cAAA,YACA,CAAC,eAAe,SAAS,GAEzB,uBAAO,IAAI,MACT,GAAG,MAAM,QAAQ,mKAGnB;CAEF,IAAI,MAAM,SAAA,QAA+B,OAAO;CAChD,IAAI,MAAA,kBAAA,gCAAM,MAAA,QAAA,CAAA,CAAA,KAAA,MAAc,OAAO,MAAM,GACnC,uBAAO,IAAI,MACT,GAAG,MAAM,QAAQ,KAAK,OAAO,6JAG/B;CAEF,IAAI,CAAC,WACH,uBAAO,IAAI,MACT,GAAG,MAAM,QAAQ,KAAK,OAAO,gGAEJ,OAAO,mCAClC;CAEF,OAAO;AACT;AAEA,eAAA,SAAe,OAAuB,QAAkC;CACtE,IAAI;EACF,MAAM,OAAO,MAAM,MAAM,UAAU,KAAK;EACxC,MAAM,SAAS,OAAO,MAAM,GAAG,CAAC,CAAC;EACjC,OAAO,KAAK,QAAQ,MACjB,MAAM,EAAE,SAAS,UAAU,EAAE,OAAO,MAAM,MAAM,EAAE,UAAU,MAAM,CACrE;CACF,QAAQ;EACN,OAAO;CACT;AACF;AAGF,SAAS,aAAa,UAAkC;CACtD,OAAO,GAAG,uBAAuB;AACnC;AAEA,SAAS,eACP,WAC2B;CAC3B,OAAO,WAAW,WAAW,oBAAoB,KAAK;AACxD;AAEA,SAAS,eAAe,QAAgC;CACtD,OAAO,OAAO,MAAM,CAA2B;AACjD;;;;;;;;AC3kBA,MAAM,mBACJ;;;;;;AAOF,SAAS,mBAAmB,MAAsB;CAKhD,OAAO,gBAJS,KAAK,QACnB,oBACC,SAAS,IAAI,KAAK,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAErB;AAC/B;;AAGA,SAAS,kBACP,QACA,QACmB;CACnB,IAAI,CAAC,QAAQ,OAAO;CACpB,OAAO;EACL,GAAG;EACH,GAAI,OAAO,YACP;GAAE,WAAW;GAAe,QAAQ;EAAiB,IACrD,CAAC;EACL,GAAI,OAAO,QAAQ,SAAS,IAAI,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;CACjE;AACF;;AAGA,SAAgB,mBAAmB,QAAqC;CACtE,MAAM,QAAkB,CAAC;CACzB,IAAI,OAAO,QAAQ,MAAM,KAAK,OAAO,MAAM;CAC3C,IAAI,OAAO,SAAS,QAClB,MAAM,KACJ,gCAAgC,KAAK,UAAU,OAAO,OAAO,GAC/D;CAEF,OAAO;AACT;;;;;AAMA,SAAgB,sBACd,SACA,SAIA;CACA,MAAM,MAAM,WAAW,OAAO;CAC9B,IAAI,CAAC,KACH,MAAM,IAAI,MACR,4IACF;CAGF,MAAM,YAAY,IAAI,wBAAwB,KAAK,EACjD,SAAS,QAAQ,QACnB,CAAC;CAYD,MAAM,eAXU,sBAAsB;EACpC;EACA,UAAU,IAAI,sBAAsB;GAClC,QAAQ,QAAQ;GAChB,SAAS,QAAQ;EACnB,CAAC;EACD,YAAY,CAAC,SAAS;EACtB,MAAM,mBAAmB,QAAQ,QAAQ,IAAI;EAC7C,iBAAiB;CACnB,CAE2B,CAAC,CAAC,KAAK,EAChC,gBAAgB,EACd,KAAK,uHAAuH,QAAQ,iBACtI,EACF,CAAC;CAED,OAAO;EACL,aAAa,aAAa;EAC1B,aAAa,aAAa;EAC1B,SAAS,OACP,OACA,mBAC+B;GAC/B,MAAM,SAAS,MAAM,aAAa,QAAQ,OAAO,cAAc;GAC/D,OAAO,kBACL,QACA,UAAU,WAAW,OAAO,WAAW,CACzC;EACF;CACF;AACF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { n as BrowserConnection } from "./browser-DE3d-RLk.js";
|
|
2
|
+
import {
|
|
3
|
+
CodemodeConnector,
|
|
4
|
+
ConnectorTool,
|
|
5
|
+
ConnectorTools,
|
|
6
|
+
ProxyToolOutput
|
|
7
|
+
} from "@cloudflare/codemode";
|
|
8
|
+
|
|
9
|
+
//#region src/browser/session-connector.d.ts
|
|
10
|
+
/**
|
|
11
|
+
* Where a {@link BrowserSessionConnector} gets its browser. Usually a
|
|
12
|
+
* `Browser` installed on the host's Lifecycle.
|
|
13
|
+
*/
|
|
14
|
+
interface BrowserSource {
|
|
15
|
+
/** The browser's name, for log messages. */
|
|
16
|
+
readonly name: string;
|
|
17
|
+
/** Reattach to the browser (or replace it) and open a CDP connection. */
|
|
18
|
+
connect(): Promise<BrowserConnection>;
|
|
19
|
+
}
|
|
20
|
+
/** A tab a page opened on its own during an execution. */
|
|
21
|
+
interface BrowserNewTab {
|
|
22
|
+
targetId: string;
|
|
23
|
+
url?: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/browser/browser-tool.d.ts
|
|
28
|
+
interface BrowserToolOptions {
|
|
29
|
+
/**
|
|
30
|
+
* The browser the tool drives — usually a `Browser` installed on the
|
|
31
|
+
* host's Lifecycle. Tools built from the same `Browser` share it.
|
|
32
|
+
*/
|
|
33
|
+
browser: BrowserSource;
|
|
34
|
+
/**
|
|
35
|
+
* WorkerLoader binding for sandboxed code execution.
|
|
36
|
+
*
|
|
37
|
+
* Requires `"worker_loaders": [{ "binding": "LOADER" }]` in wrangler.jsonc.
|
|
38
|
+
*/
|
|
39
|
+
loader: WorkerLoader;
|
|
40
|
+
/** Sandbox execution timeout in milliseconds. Defaults to 30000 (30s). */
|
|
41
|
+
timeoutMs?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Durable Object state for the codemode runtime facet. Optional inside an
|
|
44
|
+
* Agent (resolved via `getCurrentAgent()`); pass it explicitly elsewhere.
|
|
45
|
+
*
|
|
46
|
+
* The worker must export the `CodemodeRuntime` class (the
|
|
47
|
+
* `@cloudflare/codemode/vite` plugin does this automatically, or add
|
|
48
|
+
* `export { CodemodeRuntime } from "@cloudflare/codemode"` to your entry).
|
|
49
|
+
*/
|
|
50
|
+
ctx?: DurableObjectState;
|
|
51
|
+
}
|
|
52
|
+
/** The model's input to `browserTool`: JavaScript to run. */
|
|
53
|
+
interface BrowserToolInput {
|
|
54
|
+
code: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The result of one `browserTool` run: the codemode execution result,
|
|
58
|
+
* plus what happened to the browser.
|
|
59
|
+
*/
|
|
60
|
+
type BrowserToolOutput = ProxyToolOutput & {
|
|
61
|
+
/** The browser was replaced before this run; earlier tabs are gone. */ restarted?: true /** A sentence telling the model what `restarted` means for it. */;
|
|
62
|
+
notice?: string /** Tabs the page opened itself (popups, `target=_blank` links). */;
|
|
63
|
+
newTabs?: BrowserNewTab[];
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export {
|
|
67
|
+
BrowserSource as a,
|
|
68
|
+
BrowserNewTab as i,
|
|
69
|
+
BrowserToolOptions as n,
|
|
70
|
+
BrowserToolOutput as r,
|
|
71
|
+
BrowserToolInput as t
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=browser-tool-DuNdlwZ9.d.ts.map
|