agents 0.27.0 → 0.28.1
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-BMvWTFEp.d.ts} +21 -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-ohoewW-B.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-C2iTAwUd.js} +44 -18
- package/dist/ai-sdk-C2iTAwUd.js.map +1 -0
- 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-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/{client-DS3Dz9l0.d.ts → client-Bp-JwL3p.d.ts} +2 -2
- 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/{handler-stateless-VvrWSAVA.js → handler-stateless-Bly_nSH3.js} +12 -3
- package/dist/handler-stateless-Bly_nSH3.js.map +1 -0
- 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 +183 -7
- package/dist/harness/opencode/index.js +355 -24
- package/dist/harness/opencode/index.js.map +1 -1
- 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/{images-Ce9SCu3X.js → images-C4hiIexM.js} +46 -4
- package/dist/images-C4hiIexM.js.map +1 -0
- 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-xBofjBKC.js} +3 -3
- package/dist/input-schema-xBofjBKC.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 +18 -4
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server/index.js +1 -1
- package/dist/models/ai-sdk/index.d.ts +45 -17
- package/dist/models/ai-sdk/index.js +1 -1
- package/dist/models/opencode/index.d.ts +2 -2
- package/dist/models/opencode/index.js +1 -1
- package/dist/models/pi-ai/index.d.ts +8 -3
- package/dist/models/pi-ai/index.js +6 -6
- package/dist/models/pi-ai/index.js.map +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/{settings-C45hDliX.js → settings-BjAiPd6Z.js} +7 -4
- package/dist/settings-BjAiPd6Z.js.map +1 -0
- package/dist/{settings-NgGwF7Qt.d.ts → settings-DnD__xuE.d.ts} +22 -4
- 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-VF0qiO7q.js} +7 -18
- package/dist/tool-VF0qiO7q.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/{transport-k2mFrtL8.d.ts → transport-DCyarnwm.d.ts} +2 -2
- 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/mcp-client.md +1 -1
- package/docs/mcp-servers.md +1 -1
- package/docs/models-pi-ai.md +11 -0
- package/docs/models.md +45 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +2 -0
- package/package.json +52 -27
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/ai-sdk-OoGkFy3s.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/handler-stateless-VvrWSAVA.js.map +0 -1
- package/dist/images-Ce9SCu3X.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/settings-C45hDliX.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
package/docs/models.md
CHANGED
|
@@ -20,9 +20,11 @@ we hand its request to AI Gateway and hand the answer straight back to it.
|
|
|
20
20
|
|
|
21
21
|
## The canon, in five lines
|
|
22
22
|
|
|
23
|
-
1. **`ai(string)` is
|
|
24
|
-
from `@cloudflare/workers-types
|
|
25
|
-
|
|
23
|
+
1. **`ai(string)` is Cloudflare's.** A Workers AI id, `@cf/<author>/<model>`,
|
|
24
|
+
autocompleted from `@cloudflare/workers-types`, or a
|
|
25
|
+
[dynamic route](#dynamic-routes) on your gateway, `dynamic/<route>`. Any
|
|
26
|
+
other string is a `TypeError` that tells you which provider package to
|
|
27
|
+
install.
|
|
26
28
|
2. **`ai(model)` is any AI SDK v4 model**, routed through AI Gateway. Its
|
|
27
29
|
provider builds the request, parses the response, and handles its own
|
|
28
30
|
errors; only the transport is ours.
|
|
@@ -215,9 +217,47 @@ this package's:
|
|
|
215
217
|
and that error is surfaced to you exactly as Google wrote it, because Google's
|
|
216
218
|
provider is the one that knows how to read it.
|
|
217
219
|
|
|
220
|
+
`zdr` turns Zero Data Retention on (`true`) or off (`false`) for one request,
|
|
221
|
+
whatever the gateway's own setting. It applies to a routed model on unified
|
|
222
|
+
billing and is sent as `cf-aig-zdr`.
|
|
223
|
+
|
|
224
|
+
To use a key you hold yourself rather than one stored on the gateway, give it
|
|
225
|
+
to the vendor's provider and set `vendorKey: "request"`, which forwards the
|
|
226
|
+
credential header instead of stripping it:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
const anthropic = createAnthropic({ apiKey: env.ANTHROPIC_API_KEY });
|
|
230
|
+
const model = ai(anthropic("claude-opus-4-8"), { vendorKey: "request" });
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`vendorKey` belongs to the model it is set on (`ai(model, …)` or
|
|
234
|
+
`ai.routed(model, …)`). A fallback leg does not inherit it, so a chain can mix
|
|
235
|
+
a model on your key with one on unified billing.
|
|
236
|
+
|
|
218
237
|
Only the gateway's _own_ failures — no such gateway, an unpaid account — become
|
|
219
238
|
a `CloudflareAIError`. A vendor error stays the vendor's.
|
|
220
239
|
|
|
240
|
+
## Dynamic routes
|
|
241
|
+
|
|
242
|
+
An [AI Gateway dynamic route](https://developers.cloudflare.com/ai-gateway/features/dynamic-routing/)
|
|
243
|
+
is called by name, as `dynamic/<route>`. The route configured on the gateway
|
|
244
|
+
picks the model (conditions, percentages, rate and budget limits, its own
|
|
245
|
+
fallbacks), and the call goes through `env.AI.run` like a Workers AI model:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const ai = createAI({ binding: env.AI, id: "prod" });
|
|
249
|
+
|
|
250
|
+
await generateText({ model: ai("dynamic/support"), prompt: "Hi" });
|
|
251
|
+
ai("@cf/zai-org/glm-4.7-flash", { fallback: ["dynamic/support"] });
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
The route belongs to a gateway, so set the gateway `id` it was created on. It
|
|
255
|
+
answers in the OpenAI chat-completions shape whatever model served it, so the
|
|
256
|
+
request is built as strict OpenAI: `chatTemplateKwargs` is dropped with a
|
|
257
|
+
warning, because the route may not land on Workers AI. A dynamic route is a
|
|
258
|
+
language model only, and the modality methods refuse it, including as a
|
|
259
|
+
fallback leg.
|
|
260
|
+
|
|
221
261
|
## Other modalities
|
|
222
262
|
|
|
223
263
|
Images, speech, transcription and reranking come off the same provider, the
|
|
@@ -326,6 +366,8 @@ await generateText({
|
|
|
326
366
|
| `eventId` | `string` | Correlates several requests into one gateway event. |
|
|
327
367
|
| `requestTimeoutMs` | `number` | Upstream request timeout. |
|
|
328
368
|
| `retries` | `{ maxAttempts, retryDelayMs, backoff }` | Server-side retry policy for the upstream provider call. |
|
|
369
|
+
| `zdr` | `boolean` | Routed models only: Zero Data Retention on or off (unified billing). |
|
|
370
|
+
| `vendorKey` | `"gateway" \| "request"` | Routed models only: forward the vendor key on the request. Per model. |
|
|
329
371
|
| `fallback` | `(WorkersAIModelId \| LanguageModelV4)[]` | Models to try, in order, if the primary fails before producing output. |
|
|
330
372
|
| `headers` | `Record<string, string>` | Extra request headers, merged last. |
|
|
331
373
|
| `sessionAffinity` | `string` | Pin same-key requests to one replica for prefix-cache hits. |
|
package/docs/queue.md
CHANGED
|
@@ -7,9 +7,8 @@ survives the object leaving memory.
|
|
|
7
7
|
|
|
8
8
|
## Queue Lifecycle capability
|
|
9
9
|
|
|
10
|
-
> **Experimental.** The `Queue` capability
|
|
11
|
-
>
|
|
12
|
-
> (`this.queue()` and friends) are stable.
|
|
10
|
+
> **Experimental.** The `Queue` capability may change between releases.
|
|
11
|
+
> Agent's queue methods (`this.queue()` and friends) are stable.
|
|
13
12
|
|
|
14
13
|
`Queue` is a reusable Lifecycle capability. A plain Lifecycle Object can
|
|
15
14
|
install it without extending `Agent`:
|
package/docs/scheduling.md
CHANGED
|
@@ -17,10 +17,6 @@ Under the hood, scheduling uses [Durable Object alarms](https://developers.cloud
|
|
|
17
17
|
|
|
18
18
|
## Scheduler Lifecycle primitive
|
|
19
19
|
|
|
20
|
-
> **Experimental.** The `Scheduler` primitive and the `agents/lifecycle`
|
|
21
|
-
> surface it builds on may change between releases. Agent's established
|
|
22
|
-
> scheduling methods (`this.schedule()` and friends) are stable.
|
|
23
|
-
|
|
24
20
|
`Scheduler` is a reusable Lifecycle capability. A plain Lifecycle Object can
|
|
25
21
|
install it without extending `Agent`:
|
|
26
22
|
|
|
@@ -836,8 +832,8 @@ When using this schema with OpenAI models via the AI SDK, you must pass `provide
|
|
|
836
832
|
|
|
837
833
|
## API Reference
|
|
838
834
|
|
|
839
|
-
Two surfaces share these semantics: the
|
|
840
|
-
(`agents/schedules`, methods on the scheduler instance) and the
|
|
835
|
+
Two surfaces share these semantics: the `Scheduler` capability
|
|
836
|
+
(`agents/schedules`, methods on the scheduler instance) and the `Agent`
|
|
841
837
|
methods (on the Agent class, delegating to `this.scheduler`).
|
|
842
838
|
|
|
843
839
|
### Scheduler primitive
|
package/docs/search-the-web.md
CHANGED
|
@@ -88,6 +88,8 @@ The host gets the full API response, without trimming, as `WebSearchToolOutput`:
|
|
|
88
88
|
|
|
89
89
|
The API has no pagination. The tool description tells the model to search again with a rephrased query when it wants more or different results.
|
|
90
90
|
|
|
91
|
+
Results are for discovery. To let the model read the pages it finds, add the [`web_fetch` tool](./fetch-the-web.md) beside `web_search`; the `web_search` description tells the model to fetch result URLs with `web_fetch` when it is available.
|
|
92
|
+
|
|
91
93
|
## Failures
|
|
92
94
|
|
|
93
95
|
A failed search becomes a `WebSearchError` with `status`, `code`, `retryable`, and `requestId` (AI Gateway's id for the request, for the gateway log). Every error has a `code`: the API's own when it sends one, for example `web_search_payment_required`, otherwise one derived from the HTTP status, such as `web_search_rate_limited` or `web_search_unavailable`. On a runtime older than the one above, the binding has no `websearch()` and the search fails with code `web_search_unsupported_runtime`.
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"bin": {
|
|
13
13
|
"agents": "./dist/cli.js"
|
|
14
14
|
},
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.28.1",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
|
18
18
|
"directory": "packages/agents",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"@ai-sdk/provider": "^4.0.0",
|
|
43
43
|
"@ai-sdk/react": "^4.0.0",
|
|
44
44
|
"@ai-sdk/valibot": "3.0.6",
|
|
45
|
-
"@cloudflare/codemode": "^0.5.
|
|
45
|
+
"@cloudflare/codemode": "^0.5.4",
|
|
46
46
|
"@earendil-works/pi-ai": "^1.0.0",
|
|
47
47
|
"@earendil-works/pi-durable": "^1.0.0",
|
|
48
48
|
"@earendil-works/pi-tui": "1.0.0",
|
|
49
|
-
"@modelcontextprotocol/client": "2.
|
|
50
|
-
"@modelcontextprotocol/conformance-v2": "npm:@modelcontextprotocol/conformance@0.2.0-alpha.
|
|
51
|
-
"@modelcontextprotocol/sdk": "1.
|
|
52
|
-
"@modelcontextprotocol/server": "2.
|
|
49
|
+
"@modelcontextprotocol/client": "2.3.1",
|
|
50
|
+
"@modelcontextprotocol/conformance-v2": "npm:@modelcontextprotocol/conformance@0.2.0-alpha.12",
|
|
51
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
52
|
+
"@modelcontextprotocol/server": "2.3.1",
|
|
53
53
|
"@opencode/plugin": "2.0.24",
|
|
54
54
|
"@opencode/sdk": "2.0.24",
|
|
55
55
|
"@tanstack/ai": "0.38.0",
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"@cloudflare/codemode": ">=0.5.0",
|
|
74
74
|
"@earendil-works/pi-ai": "^1.0.0",
|
|
75
75
|
"@earendil-works/pi-durable": "^1.0.0",
|
|
76
|
-
"@modelcontextprotocol/client": "2.
|
|
77
|
-
"@modelcontextprotocol/sdk": "1.
|
|
78
|
-
"@modelcontextprotocol/server": "2.
|
|
76
|
+
"@modelcontextprotocol/client": "2.3.1",
|
|
77
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
78
|
+
"@modelcontextprotocol/server": "2.3.1",
|
|
79
79
|
"@opencode/plugin": "^2.0.24",
|
|
80
80
|
"@opencode/sdk": "^2.0.24",
|
|
81
81
|
"@tanstack/ai": ">=0.10.2 <1.0.0",
|
|
@@ -383,34 +383,59 @@
|
|
|
383
383
|
"require": "./dist/browser/ai.js"
|
|
384
384
|
},
|
|
385
385
|
"./browser/ai-sdk": {
|
|
386
|
-
"types": "./dist/browser/ai-sdk.d.ts",
|
|
387
|
-
"import": "./dist/browser/ai-sdk.js",
|
|
388
|
-
"require": "./dist/browser/ai-sdk.js"
|
|
386
|
+
"types": "./dist/browser/tools/ai-sdk.d.ts",
|
|
387
|
+
"import": "./dist/browser/tools/ai-sdk.js",
|
|
388
|
+
"require": "./dist/browser/tools/ai-sdk.js"
|
|
389
389
|
},
|
|
390
390
|
"./browser/tanstack-ai": {
|
|
391
|
-
"types": "./dist/browser/tanstack-ai.d.ts",
|
|
392
|
-
"import": "./dist/browser/tanstack-ai.js",
|
|
393
|
-
"require": "./dist/browser/tanstack-ai.js"
|
|
391
|
+
"types": "./dist/browser/tools/tanstack-ai.d.ts",
|
|
392
|
+
"import": "./dist/browser/tools/tanstack-ai.js",
|
|
393
|
+
"require": "./dist/browser/tools/tanstack-ai.js"
|
|
394
394
|
},
|
|
395
395
|
"./websearch": {
|
|
396
|
-
"types": "./dist/
|
|
397
|
-
"import": "./dist/
|
|
398
|
-
"require": "./dist/
|
|
396
|
+
"types": "./dist/web/search/index.d.ts",
|
|
397
|
+
"import": "./dist/web/search/index.js",
|
|
398
|
+
"require": "./dist/web/search/index.js"
|
|
399
399
|
},
|
|
400
400
|
"./websearch/pi": {
|
|
401
|
-
"types": "./dist/
|
|
402
|
-
"import": "./dist/
|
|
403
|
-
"require": "./dist/
|
|
401
|
+
"types": "./dist/web/search/tools/pi.d.ts",
|
|
402
|
+
"import": "./dist/web/search/tools/pi.js",
|
|
403
|
+
"require": "./dist/web/search/tools/pi.js"
|
|
404
404
|
},
|
|
405
405
|
"./websearch/ai-sdk": {
|
|
406
|
-
"types": "./dist/
|
|
407
|
-
"import": "./dist/
|
|
408
|
-
"require": "./dist/
|
|
406
|
+
"types": "./dist/web/search/tools/ai-sdk.d.ts",
|
|
407
|
+
"import": "./dist/web/search/tools/ai-sdk.js",
|
|
408
|
+
"require": "./dist/web/search/tools/ai-sdk.js"
|
|
409
409
|
},
|
|
410
410
|
"./websearch/tanstack-ai": {
|
|
411
|
-
"types": "./dist/
|
|
412
|
-
"import": "./dist/
|
|
413
|
-
"require": "./dist/
|
|
411
|
+
"types": "./dist/web/search/tools/tanstack-ai.d.ts",
|
|
412
|
+
"import": "./dist/web/search/tools/tanstack-ai.js",
|
|
413
|
+
"require": "./dist/web/search/tools/tanstack-ai.js"
|
|
414
|
+
},
|
|
415
|
+
"./browser/pi": {
|
|
416
|
+
"types": "./dist/browser/tools/pi.d.ts",
|
|
417
|
+
"import": "./dist/browser/tools/pi.js",
|
|
418
|
+
"require": "./dist/browser/tools/pi.js"
|
|
419
|
+
},
|
|
420
|
+
"./webfetch": {
|
|
421
|
+
"types": "./dist/web/fetch/index.d.ts",
|
|
422
|
+
"import": "./dist/web/fetch/index.js",
|
|
423
|
+
"require": "./dist/web/fetch/index.js"
|
|
424
|
+
},
|
|
425
|
+
"./webfetch/pi": {
|
|
426
|
+
"types": "./dist/web/fetch/tools/pi.d.ts",
|
|
427
|
+
"import": "./dist/web/fetch/tools/pi.js",
|
|
428
|
+
"require": "./dist/web/fetch/tools/pi.js"
|
|
429
|
+
},
|
|
430
|
+
"./webfetch/ai-sdk": {
|
|
431
|
+
"types": "./dist/web/fetch/tools/ai-sdk.d.ts",
|
|
432
|
+
"import": "./dist/web/fetch/tools/ai-sdk.js",
|
|
433
|
+
"require": "./dist/web/fetch/tools/ai-sdk.js"
|
|
434
|
+
},
|
|
435
|
+
"./webfetch/tanstack-ai": {
|
|
436
|
+
"types": "./dist/web/fetch/tools/tanstack-ai.d.ts",
|
|
437
|
+
"import": "./dist/web/fetch/tools/tanstack-ai.js",
|
|
438
|
+
"require": "./dist/web/fetch/tools/tanstack-ai.js"
|
|
414
439
|
},
|
|
415
440
|
"./voice": {
|
|
416
441
|
"types": "./dist/voice/index.d.ts",
|
package/dist/ai-fm7xx1BK.js
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
import { t as __DO_NOT_USE_WILL_BREAK__agentContext } from "./current-agent-DhoDkSnH.js";
|
|
2
|
-
import "./internal_context.js";
|
|
3
|
-
import { c as browserExtract, f as browserScrape, i as DurableBrowserSessionStore, l as browserLinks, s as browserContent, t as BrowserConnector, u as browserMarkdown } from "./connector-58XDGvc3.js";
|
|
4
|
-
import { t as redactBase64Payloads } from "./base64-redaction-C1Uu29t5.js";
|
|
5
|
-
import { tool } from "ai";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
import { DynamicWorkerExecutor, createCodemodeRuntime, truncateResult } from "@cloudflare/codemode";
|
|
8
|
-
//#region src/browser/tool-helpers.ts
|
|
9
|
-
function browserScreenshotOutput(value) {
|
|
10
|
-
const outer = typeof value === "object" && value !== null ? value : null;
|
|
11
|
-
const result = outer && typeof outer.result === "object" && outer.result !== null ? outer.result : outer;
|
|
12
|
-
if (result?.type !== "browser_screenshot" || typeof result.mediaType !== "string" || typeof result.data !== "string") return null;
|
|
13
|
-
return result;
|
|
14
|
-
}
|
|
15
|
-
function transformBrowserResult(value) {
|
|
16
|
-
return browserScreenshotOutput(value) ? value : truncateResult(redactBase64Payloads(value));
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* @param notes Sentences appended when a screenshot collapses the output to
|
|
20
|
-
* text, so notices on the output aren't lost with it.
|
|
21
|
-
*/
|
|
22
|
-
function browserExecuteModelOutput(output, notes = []) {
|
|
23
|
-
const screenshot = browserScreenshotOutput(output);
|
|
24
|
-
if (screenshot) {
|
|
25
|
-
const approximateBytes = Math.floor(screenshot.data.length * 3 / 4);
|
|
26
|
-
return {
|
|
27
|
-
type: "text",
|
|
28
|
-
value: [`Screenshot captured successfully (${screenshot.mediaType}, approximately ${approximateBytes.toLocaleString()} bytes); the image is kept for the UI and omitted here.`, ...notes].join(" ")
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
const redacted = redactBase64Payloads(typeof output === "object" && output !== null && !Array.isArray(output) ? (({ calls: _calls, ...rest }) => ({
|
|
32
|
-
...rest,
|
|
33
|
-
...Array.isArray(rest.logs) ? { logs: truncateResult(rest.logs) } : {}
|
|
34
|
-
}))(output) : output);
|
|
35
|
-
try {
|
|
36
|
-
const serialized = JSON.stringify(redacted);
|
|
37
|
-
return {
|
|
38
|
-
type: "json",
|
|
39
|
-
value: serialized === void 0 ? null : JSON.parse(serialized)
|
|
40
|
-
};
|
|
41
|
-
} catch {
|
|
42
|
-
return {
|
|
43
|
-
type: "text",
|
|
44
|
-
value: "Browser execution completed, but its result could not be serialized for model context."
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* The Durable Object state to build the runtime in: the explicit `ctx` if
|
|
50
|
-
* given, otherwise the current Agent's `ctx` (via `getCurrentAgent()`), so
|
|
51
|
-
* `createBrowserRuntime` can be called from an Agent method without threading
|
|
52
|
-
* `this.ctx` through.
|
|
53
|
-
*/
|
|
54
|
-
function resolveCtx(options) {
|
|
55
|
-
if (options.ctx) return options.ctx;
|
|
56
|
-
return (__DO_NOT_USE_WILL_BREAK__agentContext.getStore()?.agent)?.ctx;
|
|
57
|
-
}
|
|
58
|
-
//#endregion
|
|
59
|
-
//#region src/browser/ai.ts
|
|
60
|
-
let didWarnExperimental = false;
|
|
61
|
-
let didDebugQuickActionSkip = false;
|
|
62
|
-
function connectorOptions(options, ctx) {
|
|
63
|
-
if (options.cdpUrl) return {
|
|
64
|
-
cdpUrl: options.cdpUrl,
|
|
65
|
-
cdpHeaders: options.cdpHeaders,
|
|
66
|
-
timeout: options.timeout
|
|
67
|
-
};
|
|
68
|
-
if (!options.browser) throw new Error("Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided");
|
|
69
|
-
return {
|
|
70
|
-
browser: options.browser,
|
|
71
|
-
store: options.store ?? new DurableBrowserSessionStore(ctx.storage),
|
|
72
|
-
session: options.session,
|
|
73
|
-
timeout: options.timeout
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Create the browser codemode runtime: the `browser_execute` tool plus the
|
|
78
|
-
* runtime handle and connector for host-side wiring (approvals, session info,
|
|
79
|
-
* sweeps).
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```ts
|
|
83
|
-
* export class MyAgent extends Agent<Env> {
|
|
84
|
-
* get browser() {
|
|
85
|
-
* return createBrowserRuntime({
|
|
86
|
-
* ctx: this.ctx,
|
|
87
|
-
* browser: this.env.BROWSER,
|
|
88
|
-
* loader: this.env.LOADER,
|
|
89
|
-
* session: { mode: "dynamic" }
|
|
90
|
-
* });
|
|
91
|
-
* }
|
|
92
|
-
*
|
|
93
|
-
* @callable()
|
|
94
|
-
* async closeBrowserSession() {
|
|
95
|
-
* await this.browser.connector.closeSession();
|
|
96
|
-
* }
|
|
97
|
-
* }
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
function createBrowserRuntime(options) {
|
|
101
|
-
if (!didWarnExperimental) {
|
|
102
|
-
didWarnExperimental = true;
|
|
103
|
-
console.warn("[agents/browser] Browser tools are experimental and may change in a future release.");
|
|
104
|
-
}
|
|
105
|
-
const ctx = resolveCtx(options);
|
|
106
|
-
if (!ctx) throw new Error("createBrowserRuntime requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()");
|
|
107
|
-
const connector = new BrowserConnector(ctx, connectorOptions(options, ctx));
|
|
108
|
-
const runtime = createCodemodeRuntime({
|
|
109
|
-
ctx,
|
|
110
|
-
executor: new DynamicWorkerExecutor({
|
|
111
|
-
loader: options.loader,
|
|
112
|
-
timeout: options.timeout
|
|
113
|
-
}),
|
|
114
|
-
connectors: [connector],
|
|
115
|
-
name: options.name ?? "browser",
|
|
116
|
-
transformResult: transformBrowserResult
|
|
117
|
-
});
|
|
118
|
-
const isKitesurf = !options.cdpUrl && options.session?.browser === "kitesurf";
|
|
119
|
-
const tools = { browser_execute: {
|
|
120
|
-
...runtime.tool({ connectorHints: { cdp: isKitesurf ? "Kitesurf one-shot Browser CDP. Call codemode.describe(\"cdp\") for connector types and Kitesurf execution rules. codemode.search indexes connector methods and snippets, not underlying CDP commands. Complete the task in one execution and do not pause. Return screenshots as { type: \"browser_screenshot\", mediaType: \"image/png\", data: screenshot.data }." : "Browser CDP. Return screenshots as { type: 'browser_screenshot', mediaType: 'image/png', data: screenshot.data }; the UI keeps the image while the model receives a compact summary." } }),
|
|
121
|
-
toModelOutput: ({ output }) => browserExecuteModelOutput(output)
|
|
122
|
-
} };
|
|
123
|
-
if (options.quickActions !== false && (!isKitesurf || options.quickActions !== void 0)) {
|
|
124
|
-
const qa = typeof options.quickActions === "object" ? options.quickActions : {};
|
|
125
|
-
const quickActionBrowser = qa.browser ?? options.browser;
|
|
126
|
-
if (quickActionBrowser) Object.assign(tools, createQuickActionTools({
|
|
127
|
-
browser: quickActionBrowser,
|
|
128
|
-
actions: qa.actions,
|
|
129
|
-
maxChars: qa.maxChars,
|
|
130
|
-
options: qa.options
|
|
131
|
-
}));
|
|
132
|
-
else if (options.quickActions) throw new Error("quickActions requires a Browser Run binding — set 'browser' (env.BROWSER) or 'quickActions.browser'");
|
|
133
|
-
else if (!didDebugQuickActionSkip) {
|
|
134
|
-
didDebugQuickActionSkip = true;
|
|
135
|
-
console.debug("[agents/browser] Quick Action tools skipped — no Browser Run binding (only 'cdpUrl' is set). Pass 'browser' or 'quickActions.browser' to enable them.");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
runtime,
|
|
140
|
-
connector,
|
|
141
|
-
tools
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Create AI SDK tools for browser automation via CDP code mode.
|
|
146
|
-
*
|
|
147
|
-
* Returns a `ToolSet` with a single durable `browser_execute` tool backed by
|
|
148
|
-
* a codemode runtime: the model writes TypeScript against the `cdp` connector
|
|
149
|
-
* (`cdp.send`, `cdp.attachToTarget`, `cdp.spec`, …), executions are recorded
|
|
150
|
-
* for abort-and-replay, and browser sessions survive pauses.
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```ts
|
|
154
|
-
* import { createBrowserTools } from "agents/browser/ai";
|
|
155
|
-
* import { generateText } from "ai";
|
|
156
|
-
*
|
|
157
|
-
* // inside a Durable Object / Agent:
|
|
158
|
-
* const browserTools = createBrowserTools({
|
|
159
|
-
* ctx: this.ctx,
|
|
160
|
-
* browser: this.env.BROWSER,
|
|
161
|
-
* loader: this.env.LOADER,
|
|
162
|
-
* });
|
|
163
|
-
*
|
|
164
|
-
* const result = await generateText({
|
|
165
|
-
* model,
|
|
166
|
-
* tools: { ...browserTools, ...otherTools },
|
|
167
|
-
* messages,
|
|
168
|
-
* });
|
|
169
|
-
* ```
|
|
170
|
-
*/
|
|
171
|
-
function createBrowserTools(options) {
|
|
172
|
-
return createBrowserRuntime(options).tools;
|
|
173
|
-
}
|
|
174
|
-
const DEFAULT_QUICK_ACTION_TOOLS = [
|
|
175
|
-
"markdown",
|
|
176
|
-
"extract",
|
|
177
|
-
"links",
|
|
178
|
-
"scrape"
|
|
179
|
-
];
|
|
180
|
-
const DEFAULT_QUICK_ACTION_MAX_CHARS = 5e4;
|
|
181
|
-
const pageInputSchema = z.object({
|
|
182
|
-
url: z.string().url().optional().describe("URL of the page to load"),
|
|
183
|
-
html: z.string().optional().describe("Raw HTML to render instead of loading a URL")
|
|
184
|
-
}).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" });
|
|
185
|
-
function toPage(input, options) {
|
|
186
|
-
const page = input.url ? { url: input.url } : { html: input.html };
|
|
187
|
-
return {
|
|
188
|
-
...options,
|
|
189
|
-
...page
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
function truncate(text, maxChars) {
|
|
193
|
-
if (maxChars <= 0 || text.length <= maxChars) return text;
|
|
194
|
-
return `${text.slice(0, maxChars)}\n\n[truncated ${text.length - maxChars} characters]`;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Keep a tool result within a rough character budget so a single browse cannot
|
|
198
|
-
* blow the model's context window — while preserving the result's shape so the
|
|
199
|
-
* model sees a consistent type across calls:
|
|
200
|
-
*
|
|
201
|
-
* - strings (markdown/content) are truncated to a string;
|
|
202
|
-
* - arrays (links/scrape) are trimmed from the end but stay arrays;
|
|
203
|
-
* - only an opaque oversized object (e.g. a sprawling `extract`) degrades to a
|
|
204
|
-
* `{ truncated, note, preview }` summary, since it cannot be trimmed safely.
|
|
205
|
-
*/
|
|
206
|
-
function boundResult(value, maxChars) {
|
|
207
|
-
if (maxChars <= 0) return value;
|
|
208
|
-
if (typeof value === "string") return truncate(value, maxChars);
|
|
209
|
-
let json;
|
|
210
|
-
try {
|
|
211
|
-
json = JSON.stringify(value);
|
|
212
|
-
} catch {
|
|
213
|
-
return value;
|
|
214
|
-
}
|
|
215
|
-
if (json.length <= maxChars) return value;
|
|
216
|
-
if (Array.isArray(value)) {
|
|
217
|
-
const trimmed = boundArray(value, maxChars);
|
|
218
|
-
if (trimmed.length > 0) return trimmed;
|
|
219
|
-
}
|
|
220
|
-
return {
|
|
221
|
-
truncated: true,
|
|
222
|
-
note: `Result is too large (${json.length} characters); narrow the request.`,
|
|
223
|
-
preview: `${json.slice(0, maxChars)}…`
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Take as many leading items as fit within `maxChars` (measured against their
|
|
228
|
-
* JSON length), returning a trimmed array of the same element type. Silent by
|
|
229
|
-
* design: the model gets fewer, valid items rather than a reshaped result.
|
|
230
|
-
*/
|
|
231
|
-
function boundArray(value, maxChars) {
|
|
232
|
-
const out = [];
|
|
233
|
-
let size = 2;
|
|
234
|
-
for (const item of value) {
|
|
235
|
-
const itemSize = JSON.stringify(item).length + 1;
|
|
236
|
-
if (size + itemSize > maxChars) break;
|
|
237
|
-
out.push(item);
|
|
238
|
-
size += itemSize;
|
|
239
|
-
}
|
|
240
|
-
return out;
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Create AI SDK tools for Browser Run [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/):
|
|
244
|
-
* stateless one-shot browsing (read a page as Markdown, extract structured
|
|
245
|
-
* data with AI, list links, scrape elements). Unlike `createBrowserTools`,
|
|
246
|
-
* these need only the `browser` binding — no Durable Object, loader, or
|
|
247
|
-
* sandbox — so they work from any Worker.
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* ```ts
|
|
251
|
-
* import { createQuickActionTools } from "agents/browser/ai";
|
|
252
|
-
*
|
|
253
|
-
* const tools = createQuickActionTools({ browser: this.env.BROWSER });
|
|
254
|
-
* const result = await generateText({ model, tools, messages });
|
|
255
|
-
* ```
|
|
256
|
-
*/
|
|
257
|
-
function createQuickActionTools(options) {
|
|
258
|
-
const { browser } = options;
|
|
259
|
-
const requestOptions = options.options;
|
|
260
|
-
const enabled = new Set(options.actions ?? DEFAULT_QUICK_ACTION_TOOLS);
|
|
261
|
-
const maxChars = options.maxChars ?? DEFAULT_QUICK_ACTION_MAX_CHARS;
|
|
262
|
-
const tools = {};
|
|
263
|
-
if (enabled.has("markdown")) tools.browser_markdown = tool({
|
|
264
|
-
description: "Load a web page (or render raw HTML) and return its content as Markdown. Best for reading articles, docs, or any page as text.",
|
|
265
|
-
inputSchema: pageInputSchema,
|
|
266
|
-
execute: async (input) => boundResult(await browserMarkdown(browser, toPage(input, requestOptions)), maxChars)
|
|
267
|
-
});
|
|
268
|
-
if (enabled.has("extract")) tools.browser_extract = tool({
|
|
269
|
-
description: "Extract structured data from a web page using AI. Describe what you want in 'prompt'. Passing a JSON Schema in 'schema' is strongly recommended — without one the extractor often fails to produce JSON.",
|
|
270
|
-
inputSchema: z.object({
|
|
271
|
-
url: z.string().url().optional().describe("URL of the page to load"),
|
|
272
|
-
html: z.string().optional().describe("Raw HTML to render instead of loading a URL"),
|
|
273
|
-
prompt: z.string().optional().describe("What to extract, in natural language"),
|
|
274
|
-
schema: z.record(z.string(), z.unknown(), { error: "Schema must be a JSON object" }).optional().describe("Optional JSON Schema describing the desired output")
|
|
275
|
-
}).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" }).refine((value) => Boolean(value.prompt) || Boolean(value.schema), { message: "Provide either 'prompt' or 'schema'" }),
|
|
276
|
-
execute: async (input) => boundResult(await browserExtract(browser, {
|
|
277
|
-
...toPage(input, requestOptions),
|
|
278
|
-
prompt: input.prompt,
|
|
279
|
-
response_format: input.schema ? {
|
|
280
|
-
type: "json_schema",
|
|
281
|
-
json_schema: input.schema
|
|
282
|
-
} : void 0
|
|
283
|
-
}), maxChars)
|
|
284
|
-
});
|
|
285
|
-
if (enabled.has("links")) tools.browser_links = tool({
|
|
286
|
-
description: "Return every link found on a web page (including ones not visible). Useful for discovering pages to follow.",
|
|
287
|
-
inputSchema: pageInputSchema,
|
|
288
|
-
execute: async (input) => boundResult(await browserLinks(browser, toPage(input, requestOptions)), maxChars)
|
|
289
|
-
});
|
|
290
|
-
if (enabled.has("scrape")) tools.browser_scrape = tool({
|
|
291
|
-
description: "Scrape specific elements from a web page by CSS selector. Returns the matched elements' text, HTML, and attributes.",
|
|
292
|
-
inputSchema: z.object({
|
|
293
|
-
url: z.string().url().optional().describe("URL of the page to load"),
|
|
294
|
-
html: z.string().optional().describe("Raw HTML to render instead of loading a URL"),
|
|
295
|
-
selectors: z.array(z.string()).min(1).describe("CSS selectors to extract")
|
|
296
|
-
}).refine((value) => Boolean(value.url) || Boolean(value.html), { message: "Provide either 'url' or 'html'" }),
|
|
297
|
-
execute: async (input) => boundResult(await browserScrape(browser, {
|
|
298
|
-
...toPage(input, requestOptions),
|
|
299
|
-
elements: input.selectors.map((selector) => ({ selector }))
|
|
300
|
-
}), maxChars)
|
|
301
|
-
});
|
|
302
|
-
if (enabled.has("content")) tools.browser_content = tool({
|
|
303
|
-
description: "Load a web page and return its fully rendered HTML (after JavaScript runs). Prefer 'browser_markdown' unless you need the raw HTML.",
|
|
304
|
-
inputSchema: pageInputSchema,
|
|
305
|
-
execute: async (input) => boundResult(await browserContent(browser, toPage(input, requestOptions)), maxChars)
|
|
306
|
-
});
|
|
307
|
-
return tools;
|
|
308
|
-
}
|
|
309
|
-
//#endregion
|
|
310
|
-
export { browserScreenshotOutput as a, browserExecuteModelOutput as i, createBrowserTools as n, resolveCtx as o, createQuickActionTools as r, transformBrowserResult as s, createBrowserRuntime as t };
|
|
311
|
-
|
|
312
|
-
//# sourceMappingURL=ai-fm7xx1BK.js.map
|
package/dist/ai-fm7xx1BK.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai-fm7xx1BK.js","names":["agentContext"],"sources":["../src/browser/tool-helpers.ts","../src/browser/ai.ts"],"sourcesContent":["/**\n * Helpers shared by the browser tools: `createBrowserTools` in `ai.ts`, and\n * `browserTool` in `ai-sdk.ts` and `tanstack-ai.ts`. Internal — not an entry\n * point.\n */\nimport type { JSONValue } from \"ai\";\nimport { truncateResult } from \"@cloudflare/codemode\";\nimport { redactBase64Payloads } from \"../core/base64-redaction\";\nimport { __DO_NOT_USE_WILL_BREAK__agentContext as agentContext } from \"../internal_context\";\n\ninterface BrowserScreenshotOutput {\n type: \"browser_screenshot\";\n mediaType: string;\n data: string;\n}\n\nexport function browserScreenshotOutput(\n value: unknown\n): BrowserScreenshotOutput | null {\n const outer =\n typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : null;\n const result =\n outer && typeof outer.result === \"object\" && outer.result !== null\n ? (outer.result as Record<string, unknown>)\n : outer;\n if (\n result?.type !== \"browser_screenshot\" ||\n typeof result.mediaType !== \"string\" ||\n typeof result.data !== \"string\"\n ) {\n return null;\n }\n return result as unknown as BrowserScreenshotOutput;\n}\n\nexport function transformBrowserResult(value: unknown): unknown {\n // Keep canonical screenshot output intact for UIMessage persistence and the\n // chat renderer. Other results are redacted before truncation so a nested\n // binary payload cannot become a large serialized preview.\n return browserScreenshotOutput(value)\n ? value\n : truncateResult(redactBase64Payloads(value));\n}\n\n/** What the model sees in place of a browser tool's output. */\nexport type BrowserModelOutput =\n | { type: \"text\"; value: string }\n | { type: \"json\"; value: JSONValue };\n\n/**\n * @param notes Sentences appended when a screenshot collapses the output to\n * text, so notices on the output aren't lost with it.\n */\nexport function browserExecuteModelOutput(\n output: unknown,\n notes: string[] = []\n): BrowserModelOutput {\n const screenshot = browserScreenshotOutput(output);\n if (screenshot) {\n const approximateBytes = Math.floor((screenshot.data.length * 3) / 4);\n return {\n type: \"text\",\n value: [\n `Screenshot captured successfully (${screenshot.mediaType}, approximately ${approximateBytes.toLocaleString()} bytes); the image is kept for the UI and omitted here.`,\n ...notes\n ].join(\" \")\n };\n }\n\n // `calls` is the durable audit log; like the codemode tool's own projection,\n // it stays on the persisted part and never enters the model's context, and\n // the sandbox `logs` are bounded like a result.\n const modelFacing =\n typeof output === \"object\" && output !== null && !Array.isArray(output)\n ? (({ calls: _calls, ...rest }: { calls?: unknown; logs?: unknown }) => ({\n ...rest,\n ...(Array.isArray(rest.logs)\n ? { logs: truncateResult(rest.logs) }\n : {})\n }))(output)\n : output;\n const redacted = redactBase64Payloads(modelFacing);\n try {\n const serialized = JSON.stringify(redacted);\n return {\n type: \"json\",\n value:\n serialized === undefined ? null : (JSON.parse(serialized) as JSONValue)\n };\n } catch {\n return {\n type: \"text\",\n value:\n \"Browser execution completed, but its result could not be serialized for model context.\"\n };\n }\n}\n\n/**\n * The Durable Object state to build the runtime in: the explicit `ctx` if\n * given, otherwise the current Agent's `ctx` (via `getCurrentAgent()`), so\n * `createBrowserRuntime` can be called from an Agent method without threading\n * `this.ctx` through.\n */\nexport function resolveCtx(options: {\n ctx?: DurableObjectState;\n}): DurableObjectState | undefined {\n if (options.ctx) return options.ctx;\n const agent = agentContext.getStore()?.agent as\n | { ctx?: DurableObjectState }\n | undefined;\n return agent?.ctx;\n}\n","import { tool, type ToolSet } from \"ai\";\nimport { z } from \"zod\";\nimport {\n createCodemodeRuntime,\n DynamicWorkerExecutor,\n type CodemodeRuntimeHandle\n} from \"@cloudflare/codemode\";\nimport type { BrowserBinding } from \"./browser-run\";\nimport {\n browserContent,\n browserExtract,\n browserLinks,\n browserMarkdown,\n browserScrape,\n type QuickActionBinding,\n type QuickActionCommonOptions,\n type QuickActionPage\n} from \"./quick-actions\";\nimport {\n BrowserConnector,\n type BrowserConnectorOptions,\n type BrowserConnectorSessionOptions\n} from \"./connector\";\nimport {\n DurableBrowserSessionStore,\n type BrowserSessionStore\n} from \"./session-store\";\nimport {\n browserExecuteModelOutput,\n resolveCtx,\n transformBrowserResult\n} from \"./tool-helpers\";\n\nexport interface CreateBrowserToolsOptions {\n /**\n * Durable Object state. The codemode runtime that backs the browser tool\n * lives in a facet of this DO, and browser session ids are stored in its\n * storage — so the tool must be created from inside a Durable Object\n * (e.g. an Agent).\n *\n * Optional: when omitted, it is resolved from the current Agent via\n * `getCurrentAgent()`, so inside an Agent method you can just pass `browser`\n * and `loader`. Pass it explicitly outside an Agent context.\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 * WorkerLoader binding for sandboxed code execution.\n *\n * Requires `\"worker_loaders\": [{ \"binding\": \"LOADER\" }]` in wrangler.jsonc.\n */\n loader: WorkerLoader;\n\n /**\n * Browser Rendering binding (Fetcher).\n *\n * This is the primary way to connect — works both locally in\n * `wrangler dev` and when deployed to Cloudflare Workers.\n *\n * Requires `\"browser\": { \"binding\": \"BROWSER\" }` in wrangler.jsonc.\n */\n browser?: BrowserBinding;\n\n /**\n * Optional CDP base URL override (e.g. `http://localhost:9222`).\n *\n * Use when connecting to a manually managed Chrome instance or\n * a remote CDP endpoint behind a tunnel.\n */\n cdpUrl?: string;\n\n /**\n * Headers to send with CDP URL discovery requests.\n * Useful when the CDP endpoint requires authentication\n * (e.g. Cloudflare Access headers).\n */\n cdpHeaders?: Record<string, string>;\n\n /**\n * Browser session lifecycle (binding-backed only). Defaults to one fresh\n * session per codemode execution (`one-shot`).\n */\n session?: BrowserConnectorSessionOptions;\n\n /**\n * Durable store for Browser Run session ids. Defaults to a\n * {@link DurableBrowserSessionStore} over `ctx.storage`.\n */\n store?: BrowserSessionStore;\n\n /**\n * Sandbox execution timeout in milliseconds. Defaults to 30000 (30s).\n * Also used as the per-CDP-command timeout.\n */\n timeout?: number;\n\n /**\n * Codemode runtime name — the durable identity of the tool's executions\n * and snippets. Defaults to `\"browser\"`.\n */\n name?: string;\n\n /**\n * Also expose stateless {@link createQuickActionTools | Quick Action} tools\n * (`browser_markdown`, `browser_extract`, …) alongside the durable\n * `browser_execute` tool.\n *\n * Enabled by default whenever a Browser Run `browser` binding is available\n * (they share it), except when `session.browser` selects Kitesurf because\n * the binding RPC cannot select that engine. Pass `true` or an object to\n * explicitly add Chromium Quick Actions alongside Kitesurf, or `false` to\n * disable them. The Quick Action binding defaults to `browser`; override it via\n * `quickActions.browser`. When only `cdpUrl` is set (no binding), the\n * defaults are skipped silently — pass `quickActions: { browser }` to force\n * them.\n */\n quickActions?:\n | boolean\n | {\n browser?: QuickActionBinding;\n actions?: QuickActionToolName[];\n maxChars?: number;\n options?: QuickActionCommonOptions;\n };\n}\n\n/**\n * The browser tool's moving parts, for hosts that need more than the tools:\n *\n * - `runtime` — the codemode runtime handle (approve/reject paused runs,\n * `expirePaused`, audit via `executions()`, snippets).\n * - `connector` — host-side session helpers: `sessionInfo()`,\n * `closeSession()`, and `sweep()` for a recurring cleanup task.\n * - `tools` — what `createBrowserTools` returns.\n */\nexport interface BrowserRuntime {\n runtime: CodemodeRuntimeHandle;\n connector: BrowserConnector;\n tools: ToolSet;\n}\n\nlet didWarnExperimental = false;\nlet didDebugQuickActionSkip = false;\n\nfunction connectorOptions(\n options: CreateBrowserToolsOptions,\n ctx: DurableObjectState\n): BrowserConnectorOptions {\n if (options.cdpUrl) {\n return {\n cdpUrl: options.cdpUrl,\n cdpHeaders: options.cdpHeaders,\n timeout: options.timeout\n };\n }\n if (!options.browser) {\n throw new Error(\n \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\"\n );\n }\n return {\n browser: options.browser,\n store: options.store ?? new DurableBrowserSessionStore(ctx.storage),\n session: options.session,\n timeout: options.timeout\n };\n}\n\n/**\n * Create the browser codemode runtime: the `browser_execute` tool plus the\n * runtime handle and connector for host-side wiring (approvals, session info,\n * sweeps).\n *\n * @example\n * ```ts\n * export class MyAgent extends Agent<Env> {\n * get browser() {\n * return createBrowserRuntime({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * session: { mode: \"dynamic\" }\n * });\n * }\n *\n * @callable()\n * async closeBrowserSession() {\n * await this.browser.connector.closeSession();\n * }\n * }\n * ```\n */\nexport function createBrowserRuntime(\n options: CreateBrowserToolsOptions\n): BrowserRuntime {\n if (!didWarnExperimental) {\n didWarnExperimental = true;\n console.warn(\n \"[agents/browser] Browser tools are experimental and may change in a future release.\"\n );\n }\n\n const ctx = resolveCtx(options);\n if (!ctx) {\n throw new Error(\n \"createBrowserRuntime 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 BrowserConnector(ctx, connectorOptions(options, ctx));\n const runtime = createCodemodeRuntime({\n ctx,\n executor: new DynamicWorkerExecutor({\n loader: options.loader,\n timeout: options.timeout\n }),\n connectors: [connector],\n name: options.name ?? \"browser\",\n transformResult: transformBrowserResult\n });\n\n // `connectorOptions` drops `session` when a custom endpoint is used, so the\n // connector is plain Chromium there whatever the session options say.\n const isKitesurf = !options.cdpUrl && options.session?.browser === \"kitesurf\";\n const browserExecute = runtime.tool({\n connectorHints: {\n cdp: isKitesurf\n ? 'Kitesurf one-shot Browser CDP. Call codemode.describe(\"cdp\") for connector types and Kitesurf execution rules. codemode.search indexes connector methods and snippets, not underlying CDP commands. Complete the task in one execution and do not pause. Return screenshots as { type: \"browser_screenshot\", mediaType: \"image/png\", data: screenshot.data }.'\n : \"Browser CDP. Return screenshots as { type: 'browser_screenshot', mediaType: 'image/png', data: screenshot.data }; the UI keeps the image while the model receives a compact summary.\"\n }\n });\n const tools: ToolSet = {\n browser_execute: {\n ...browserExecute,\n toModelOutput: ({ output }: { output: unknown }) =>\n browserExecuteModelOutput(output)\n }\n };\n\n // Quick Actions ride the same `browser` binding, so they are on by default\n // for Chromium. The binding RPC cannot select Kitesurf, so selecting\n // Kitesurf disables the defaults rather than silently adding Chromium tools.\n // Callers can still request a mixed-engine toolset explicitly.\n const enableQuickActions =\n options.quickActions !== false &&\n (!isKitesurf || options.quickActions !== undefined);\n // `env.BROWSER` satisfies both the CDP `BrowserBinding` (fetch) and the\n // `QuickActionBinding` (quickAction) surfaces; our narrower option type only\n // sees the former, so reuse it here unless an explicit binding wins.\n if (enableQuickActions) {\n const qa =\n typeof options.quickActions === \"object\" ? options.quickActions : {};\n const quickActionBrowser =\n qa.browser ??\n (options.browser as unknown as QuickActionBinding | undefined);\n if (quickActionBrowser) {\n Object.assign(\n tools,\n createQuickActionTools({\n browser: quickActionBrowser,\n actions: qa.actions,\n maxChars: qa.maxChars,\n options: qa.options\n })\n );\n } else if (options.quickActions) {\n // Explicitly requested but no binding to back them.\n throw new Error(\n \"quickActions requires a Browser Run binding — set 'browser' (env.BROWSER) or 'quickActions.browser'\"\n );\n } else if (!didDebugQuickActionSkip) {\n // Defaulted on, but only `cdpUrl` is set: there is no binding to call\n // Quick Actions through, so they are skipped. Surface it once so a user\n // expecting `browser_markdown` et al. isn't left wondering.\n didDebugQuickActionSkip = true;\n console.debug(\n \"[agents/browser] Quick Action tools skipped — no Browser Run binding (only 'cdpUrl' is set). Pass 'browser' or 'quickActions.browser' to enable them.\"\n );\n }\n }\n\n return { runtime, connector, tools };\n}\n\n/**\n * Create AI SDK tools for browser automation via CDP code mode.\n *\n * Returns a `ToolSet` with a single durable `browser_execute` tool backed by\n * a codemode runtime: the model writes TypeScript against the `cdp` connector\n * (`cdp.send`, `cdp.attachToTarget`, `cdp.spec`, …), executions are recorded\n * for abort-and-replay, and browser sessions survive pauses.\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/ai\";\n * import { generateText } from \"ai\";\n *\n * // inside a Durable Object / Agent:\n * const browserTools = createBrowserTools({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * });\n *\n * const result = await generateText({\n * model,\n * tools: { ...browserTools, ...otherTools },\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(\n options: CreateBrowserToolsOptions\n): ToolSet {\n return createBrowserRuntime(options).tools;\n}\n\n/** A Quick Action exposed as an AI SDK tool. */\nexport type QuickActionToolName =\n | \"markdown\"\n | \"extract\"\n | \"links\"\n | \"scrape\"\n | \"content\";\n\nexport interface CreateQuickActionToolsOptions {\n /**\n * Browser Run binding with Quick Actions support (`env.BROWSER`). Requires a\n * Worker `compatibility_date` of `2026-03-24`+ and `remote: true` for local\n * `wrangler dev`.\n */\n browser: QuickActionBinding;\n\n /**\n * Which tools to expose. Defaults to the text-returning, model-friendly set\n * (`markdown`, `extract`, `links`, `scrape`). `content` (raw HTML) is opt-in\n * since it is large and rarely what a model wants.\n */\n actions?: QuickActionToolName[];\n\n /**\n * Bound every result to roughly this many characters before returning it to\n * the model, to protect the context window, preserving each result's shape:\n * text (markdown/content) is truncated to a string, oversized arrays\n * (links/scrape) are trimmed but stay arrays, and only an opaque oversized\n * object degrades to a truncated-preview summary. Set to `0` to disable.\n * Defaults to 50000.\n */\n maxChars?: number;\n\n /**\n * Common Browser Run options merged into every request — e.g. `cookies`,\n * `authenticate`, or `setExtraHTTPHeaders` for authenticated pages, and\n * `gotoOptions` / `viewport` for JavaScript-heavy pages. The model only ever\n * supplies the page (`url`/`html`) and action-specific fields; these\n * host-supplied options are never exposed to it.\n */\n options?: QuickActionCommonOptions;\n}\n\nconst DEFAULT_QUICK_ACTION_TOOLS: QuickActionToolName[] = [\n \"markdown\",\n \"extract\",\n \"links\",\n \"scrape\"\n];\n\nconst DEFAULT_QUICK_ACTION_MAX_CHARS = 50_000;\n\nconst pageInputSchema = z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n });\n\nfunction toPage(\n input: { url?: string; html?: string },\n options?: QuickActionCommonOptions\n): QuickActionPage {\n const page = input.url ? { url: input.url } : { html: input.html as string };\n return { ...options, ...page } as QuickActionPage;\n}\n\nfunction truncate(text: string, maxChars: number): string {\n if (maxChars <= 0 || text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}\\n\\n[truncated ${text.length - maxChars} characters]`;\n}\n\n/**\n * Keep a tool result within a rough character budget so a single browse cannot\n * blow the model's context window — while preserving the result's shape so the\n * model sees a consistent type across calls:\n *\n * - strings (markdown/content) are truncated to a string;\n * - arrays (links/scrape) are trimmed from the end but stay arrays;\n * - only an opaque oversized object (e.g. a sprawling `extract`) degrades to a\n * `{ truncated, note, preview }` summary, since it cannot be trimmed safely.\n */\nfunction boundResult(value: unknown, maxChars: number): unknown {\n if (maxChars <= 0) return value;\n if (typeof value === \"string\") return truncate(value, maxChars);\n let json: string;\n try {\n json = JSON.stringify(value);\n } catch {\n return value;\n }\n if (json.length <= maxChars) return value;\n if (Array.isArray(value)) {\n const trimmed = boundArray(value, maxChars);\n // If even the first element overflows the budget, `trimmed` is empty —\n // returning `[]` would read as \"no results\" rather than \"too large\", so\n // fall through to the explicit truncated-preview summary instead.\n if (trimmed.length > 0) return trimmed;\n }\n return {\n truncated: true,\n note: `Result is too large (${json.length} characters); narrow the request.`,\n preview: `${json.slice(0, maxChars)}…`\n };\n}\n\n/**\n * Take as many leading items as fit within `maxChars` (measured against their\n * JSON length), returning a trimmed array of the same element type. Silent by\n * design: the model gets fewer, valid items rather than a reshaped result.\n */\nfunction boundArray(value: unknown[], maxChars: number): unknown[] {\n const out: unknown[] = [];\n let size = 2; // the enclosing \"[]\"\n for (const item of value) {\n const itemSize = JSON.stringify(item).length + 1; // + a separating comma\n if (size + itemSize > maxChars) break;\n out.push(item);\n size += itemSize;\n }\n return out;\n}\n\n/**\n * Create AI SDK tools for Browser Run [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/):\n * stateless one-shot browsing (read a page as Markdown, extract structured\n * data with AI, list links, scrape elements). Unlike `createBrowserTools`,\n * these need only the `browser` binding — no Durable Object, loader, or\n * sandbox — so they work from any Worker.\n *\n * @example\n * ```ts\n * import { createQuickActionTools } from \"agents/browser/ai\";\n *\n * const tools = createQuickActionTools({ browser: this.env.BROWSER });\n * const result = await generateText({ model, tools, messages });\n * ```\n */\nexport function createQuickActionTools(\n options: CreateQuickActionToolsOptions\n): ToolSet {\n const { browser } = options;\n const requestOptions = options.options;\n const enabled = new Set(options.actions ?? DEFAULT_QUICK_ACTION_TOOLS);\n const maxChars = options.maxChars ?? DEFAULT_QUICK_ACTION_MAX_CHARS;\n const tools: ToolSet = {};\n\n if (enabled.has(\"markdown\")) {\n tools.browser_markdown = tool({\n description:\n \"Load a web page (or render raw HTML) and return its content as Markdown. Best for reading articles, docs, or any page as text.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserMarkdown(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"extract\")) {\n tools.browser_extract = tool({\n description:\n \"Extract structured data from a web page using AI. Describe what you want in 'prompt'. Passing a JSON Schema in 'schema' is strongly recommended — without one the extractor often fails to produce JSON.\",\n inputSchema: z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\"),\n prompt: z\n .string()\n .optional()\n .describe(\"What to extract, in natural language\"),\n schema: z\n .record(z.string(), z.unknown(), {\n error: \"Schema must be a JSON object\"\n })\n .optional()\n .describe(\"Optional JSON Schema describing the desired output\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n })\n .refine((value) => Boolean(value.prompt) || Boolean(value.schema), {\n message: \"Provide either 'prompt' or 'schema'\"\n }),\n execute: async (input) =>\n boundResult(\n await browserExtract(browser, {\n ...toPage(input, requestOptions),\n prompt: input.prompt,\n response_format: input.schema\n ? { type: \"json_schema\", json_schema: input.schema }\n : undefined\n }),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"links\")) {\n tools.browser_links = tool({\n description:\n \"Return every link found on a web page (including ones not visible). Useful for discovering pages to follow.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserLinks(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"scrape\")) {\n tools.browser_scrape = tool({\n description:\n \"Scrape specific elements from a web page by CSS selector. Returns the matched elements' text, HTML, and attributes.\",\n inputSchema: z\n .object({\n url: z.string().url().optional().describe(\"URL of the page to load\"),\n html: z\n .string()\n .optional()\n .describe(\"Raw HTML to render instead of loading a URL\"),\n selectors: z\n .array(z.string())\n .min(1)\n .describe(\"CSS selectors to extract\")\n })\n .refine((value) => Boolean(value.url) || Boolean(value.html), {\n message: \"Provide either 'url' or 'html'\"\n }),\n execute: async (input) =>\n boundResult(\n await browserScrape(browser, {\n ...toPage(input, requestOptions),\n elements: input.selectors.map((selector) => ({ selector }))\n }),\n maxChars\n )\n });\n }\n\n if (enabled.has(\"content\")) {\n tools.browser_content = tool({\n description:\n \"Load a web page and return its fully rendered HTML (after JavaScript runs). Prefer 'browser_markdown' unless you need the raw HTML.\",\n inputSchema: pageInputSchema,\n execute: async (input) =>\n boundResult(\n await browserContent(browser, toPage(input, requestOptions)),\n maxChars\n )\n });\n }\n\n return tools;\n}\n"],"mappings":"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"}
|