agents 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -9
- package/dist/abortable-C1SpfVoi.js +21 -0
- package/dist/abortable-C1SpfVoi.js.map +1 -0
- package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-QDcchcQP.d.ts} +16 -16
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/ai-ahruGw7e.d.ts +239 -0
- package/dist/ai-sdk-Bdsf6mSA.js +2444 -0
- package/dist/ai-sdk-Bdsf6mSA.js.map +1 -0
- package/dist/apply-chunks-1FheRb9W.js +99 -0
- package/dist/apply-chunks-1FheRb9W.js.map +1 -0
- package/dist/broadcast-state-CEyI4uAK.js +69 -0
- package/dist/broadcast-state-CEyI4uAK.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} +6 -5
- 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-DE3d-RLk.d.ts → browser-D30VlpcA.d.ts} +63 -37
- package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-4iomavs_.js} +198 -62
- package/dist/browser-tool-4iomavs_.js.map +1 -0
- package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-vtrPOV8e.d.ts} +25 -6
- package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
- package/dist/capability-DBAKc6UZ.js.map +1 -0
- package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-BiVUtjqC.d.ts} +9 -7
- package/dist/channel-Bak_6zDP.d.ts +333 -0
- package/dist/chat/index.d.ts +11 -9
- package/dist/chat/index.js +5 -194
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +2 -4
- package/dist/chat/react.js +3 -1
- package/dist/chat/react.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +144 -0
- package/dist/{client-je3koD9Z.d.ts → client-BGIQKJhX.d.ts} +2 -2
- package/dist/{client-fyQrLGkD.js → client-BnYbNT3z.js} +29 -5
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +1 -1
- package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
- package/dist/connector-CtZylXdk.js.map +1 -0
- package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
- package/dist/conversations-FjHDRZyD.d.ts +192 -0
- package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/daemon-core-Buubj-y1.js +481 -0
- package/dist/daemon-core-Buubj-y1.js.map +1 -0
- package/dist/daemon-core-CbohVPAu.d.ts +132 -0
- package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
- package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
- package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
- package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
- package/dist/experimental/channels/email/index.js.map +1 -0
- package/dist/experimental/channels/index.d.ts +270 -0
- package/dist/experimental/channels/index.js +1186 -0
- package/dist/experimental/channels/index.js.map +1 -0
- package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
- package/dist/experimental/channels/slack/index.js +267 -0
- package/dist/experimental/channels/slack/index.js.map +1 -0
- package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
- package/dist/experimental/channels/telegram/index.js +198 -0
- package/dist/experimental/channels/telegram/index.js.map +1 -0
- package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
- package/dist/experimental/channels/web/ai-sdk.js +266 -0
- package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
- package/dist/experimental/channels/web/client.d.ts +97 -0
- package/dist/experimental/channels/web/client.js +349 -0
- package/dist/experimental/channels/web/client.js.map +1 -0
- package/dist/experimental/channels/web/index.d.ts +189 -0
- package/dist/experimental/channels/web/index.js +332 -0
- package/dist/experimental/channels/web/index.js.map +1 -0
- package/dist/gateway-BFO6vRDn.d.ts +100 -0
- package/dist/handle-zAzh0UW2.d.ts +460 -0
- package/dist/harness/ai-sdk/index.d.ts +175 -0
- package/dist/harness/ai-sdk/index.js +605 -0
- package/dist/harness/ai-sdk/index.js.map +1 -0
- package/dist/harness/container/daemon/index.d.ts +76 -0
- package/dist/harness/container/daemon/index.js +3 -0
- package/dist/harness/container/index.d.ts +740 -0
- package/dist/harness/container/index.js +2152 -0
- package/dist/harness/container/index.js.map +1 -0
- package/dist/harness/container/runtime/index.d.ts +144 -0
- package/dist/harness/container/runtime/index.js +1082 -0
- package/dist/harness/container/runtime/index.js.map +1 -0
- package/dist/harness/opencode/index.d.ts +369 -0
- package/dist/harness/opencode/index.js +1072 -0
- package/dist/harness/opencode/index.js.map +1 -0
- package/dist/harness/pi/index.d.ts +3 -2
- package/dist/harness/pi/index.js +3 -3
- package/dist/harness/store/index.d.ts +24 -0
- package/dist/harness/store/index.js +2 -0
- package/dist/harness/think/index.d.ts +821 -0
- package/dist/harness/think/index.js +2721 -0
- package/dist/harness/think/index.js.map +1 -0
- package/dist/harness-B6B9S3rb.d.ts +203 -0
- package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
- package/dist/images-Ce9SCu3X.js.map +1 -0
- package/dist/{index-BreL0YrQ.d.ts → index-BEL3ZV-s.d.ts} +2 -6
- package/dist/index-CBt8oRJt.d.ts +198 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/ingress-EFbrS547.js +9 -0
- package/dist/ingress-EFbrS547.js.map +1 -0
- package/dist/input-schema-BQykTEp_.js +20 -0
- package/dist/input-schema-BQykTEp_.js.map +1 -0
- package/dist/input-schema-D2QAtHZH.js +23 -0
- package/dist/input-schema-D2QAtHZH.js.map +1 -0
- package/dist/internal-kmw70xwR.js +46 -0
- package/dist/internal-kmw70xwR.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/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js +9 -0
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.d.ts +35 -4
- package/dist/mcp/client/x402.js +24 -3
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/models/ai-sdk/index.d.ts +16 -14
- package/dist/models/ai-sdk/index.js +1 -2442
- package/dist/models/opencode/index.d.ts +65 -0
- package/dist/models/opencode/index.js +285 -0
- package/dist/models/opencode/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +9 -7
- package/dist/models/pi-ai/index.js +2 -1
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/options-CiIsJHXR.d.ts +130 -0
- package/dist/protocol-BEgrJYC5.d.ts +331 -0
- package/dist/protocol-CukuI73M.d.ts +386 -0
- package/dist/protocol-cOklVBBD.js +227 -0
- package/dist/protocol-cOklVBBD.js.map +1 -0
- package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
- package/dist/protocol-eXeJxhgu.js.map +1 -0
- package/dist/protocol-y2sSY584.js +148 -0
- package/dist/protocol-y2sSY584.js.map +1 -0
- 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-RdACNXDP.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 +11 -434
- package/dist/sessions/index.js +1 -2271
- package/dist/sessions-_vN5BEZX.js +2272 -0
- package/dist/sessions-_vN5BEZX.js.map +1 -0
- package/dist/settings-C45hDliX.js +253 -0
- package/dist/settings-C45hDliX.js.map +1 -0
- package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
- package/dist/{src-BZeu-SCD.js → src-CQxJFv4l.js} +8 -8
- package/dist/src-CQxJFv4l.js.map +1 -0
- package/dist/stall-watchdog-BpRF2uwG.js +195 -0
- package/dist/stall-watchdog-BpRF2uwG.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-BKM4Xm9M.d.ts +332 -0
- package/dist/store-CslVzfN7.js +458 -0
- 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-DW-UCOUc.js → streams-lsHMJhRW.js} +17 -4
- package/dist/streams-lsHMJhRW.js.map +1 -0
- package/dist/{streams-Cmkj9QfW.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-68DESxf0.js → tasks-BN_5AWqI.js} +3 -2
- package/dist/tasks-BN_5AWqI.js.map +1 -0
- package/dist/{tasks-9YxYtByh.d.ts → tasks-E89KdwkS.d.ts} +2 -2
- package/dist/tool-CTp72Jb_.d.ts +278 -0
- 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-cQRkwSZZ.js +410 -0
- package/dist/tool-cQRkwSZZ.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/transport-k2mFrtL8.d.ts +200 -0
- package/dist/turns-DCV3ycDl.js +317 -0
- package/dist/turns-DCV3ycDl.js.map +1 -0
- package/dist/voice/client.js +1 -1
- package/dist/voice/index.d.ts +2 -2
- package/dist/voice/index.js +1 -1
- 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/web/search/index.d.ts +58 -0
- package/dist/web/search/index.js +2 -0
- package/dist/web/search/tools/ai-sdk.d.ts +77 -0
- package/dist/web/search/tools/ai-sdk.js +46 -0
- package/dist/web/search/tools/ai-sdk.js.map +1 -0
- package/dist/web/search/tools/pi.d.ts +82 -0
- package/dist/web/search/tools/pi.js +89 -0
- package/dist/web/search/tools/pi.js.map +1 -0
- package/dist/web/search/tools/tanstack-ai.d.ts +71 -0
- package/dist/web/search/tools/tanstack-ai.js +46 -0
- package/dist/web/search/tools/tanstack-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +12 -296
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-Ci-LZFHH.js → websockets-C3zy8YR0.js} +20 -8
- package/dist/websockets-C3zy8YR0.js.map +1 -0
- package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
- 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 +29 -1
- package/docs/fetch-the-web.md +276 -0
- package/docs/harnesses/pi.md +25 -0
- package/docs/harnesses/think.md +215 -0
- package/docs/index.md +99 -75
- package/docs/lifecycle.md +42 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +135 -0
- package/package.json +148 -44
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/browser/ai-sdk.js.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/tanstack-ai.js.map +0 -1
- package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
- package/dist/capability-B4WbF81e.js.map +0 -1
- package/dist/channel-Bnm4S7T2.d.ts +0 -491
- package/dist/channels/ai-sdk.d.ts +0 -46
- package/dist/channels/ai-sdk.js +0 -120
- package/dist/channels/ai-sdk.js.map +0 -1
- package/dist/channels/email.js.map +0 -1
- package/dist/channels/index.d.ts +0 -233
- package/dist/channels/index.js +0 -608
- package/dist/channels/index.js.map +0 -1
- package/dist/channels/slack.js +0 -614
- package/dist/channels/slack.js.map +0 -1
- package/dist/channels/tanstack-ai.d.ts +0 -39
- package/dist/channels/tanstack-ai.js +0 -17
- package/dist/channels/tanstack-ai.js.map +0 -1
- package/dist/channels/telegram.js +0 -427
- package/dist/channels/telegram.js.map +0 -1
- package/dist/channels/voice.d.ts +0 -45
- package/dist/channels/voice.js +0 -122
- package/dist/channels/voice.js.map +0 -1
- package/dist/client-fyQrLGkD.js.map +0 -1
- package/dist/connector-58XDGvc3.js.map +0 -1
- package/dist/images-iiTDSyRu.js.map +0 -1
- package/dist/index-BB0kqhIz.d.ts +0 -101
- package/dist/ingress-BfetZbMO.js +0 -83
- package/dist/ingress-BfetZbMO.js.map +0 -1
- package/dist/internal-CYlgHl1l.js +0 -59
- package/dist/internal-CYlgHl1l.js.map +0 -1
- package/dist/lifecycle-CFu6OV03.js.map +0 -1
- package/dist/models/ai-sdk/index.js.map +0 -1
- package/dist/protocol-kHsr-f0X.js.map +0 -1
- package/dist/scheduler-DZ3xQfeK.js.map +0 -1
- package/dist/sessions/index.js.map +0 -1
- package/dist/src-BZeu-SCD.js.map +0 -1
- package/dist/streams-DW-UCOUc.js.map +0 -1
- package/dist/surface-bZZJqBka.js +0 -17
- package/dist/surface-bZZJqBka.js.map +0 -1
- package/dist/tasks-68DESxf0.js.map +0 -1
- package/dist/tool-schema-CBjGPrsQ.js +0 -31
- package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
- package/dist/websockets-Ci-LZFHH.js.map +0 -1
- package/docs/channels.md +0 -323
package/docs/index.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# Agents Documentation
|
|
2
2
|
|
|
3
|
-
Build stateful AI agents on Cloudflare Workers.
|
|
3
|
+
Build stateful AI agents on Cloudflare Workers. An agent is a Durable Object: an addressable actor with its own SQLite database, alarms, and WebSockets. You can run one durable agent per user, account, task, or conversation, and pay close to nothing while it is idle.
|
|
4
|
+
|
|
5
|
+
Every agent starts the same way. Extend `DurableObject`, install a [Lifecycle](./lifecycle.md), and add the capabilities you need:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { DurableObject } from "cloudflare:workers";
|
|
9
|
+
import { Lifecycle } from "agents/lifecycle";
|
|
10
|
+
import { MCPClientManager } from "agents/mcp/client";
|
|
11
|
+
import { Scheduler } from "agents/schedules";
|
|
12
|
+
|
|
13
|
+
export class Assistant extends DurableObject<Env> {
|
|
14
|
+
readonly mcp = new MCPClientManager("assistant", "1.0.0");
|
|
15
|
+
readonly scheduler = new Scheduler({ callbacks: {} });
|
|
16
|
+
readonly lifecycle = Lifecycle.install(this)
|
|
17
|
+
.use(this.mcp)
|
|
18
|
+
.use(this.scheduler);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The Lifecycle runs startup, routes requests to capabilities, and owns the object's durable job queue and its single alarm. Capabilities are independent pieces that share it.
|
|
4
23
|
|
|
5
24
|
## Related package documentation
|
|
6
25
|
|
|
@@ -9,86 +28,95 @@ Build stateful AI agents on Cloudflare Workers. Every agent is a Durable Object
|
|
|
9
28
|
|
|
10
29
|
## Choose your path
|
|
11
30
|
|
|
12
|
-
|
|
31
|
+
| You are building... | Use |
|
|
32
|
+
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
33
|
+
| An agent that runs a model loop with tools and recovery | [Pi harness](./harnesses/pi.md) on a Durable Object |
|
|
34
|
+
| Your own agent loop | [Sessions](./sessions.md), [Streams](./streams.md), and [Tasks](./tasks.md) on a Durable Object |
|
|
35
|
+
| A chat or reasoning agent with every default built in | [`Think`](https://github.com/cloudflare/agents/blob/main/docs/think/index.md) |
|
|
36
|
+
| A chat UI that owns the loop and the stream | [`AIChatAgent`](./chat-agents.md), built on the `Agent` class |
|
|
37
|
+
| Real-time state sync, `@callable` methods, email, voice | The [`Agent` class](./agent-class.md), which installs a preset of capabilities for you |
|
|
38
|
+
| Durable multi-step processes (not chat) | [Workflows](./workflows.md) |
|
|
39
|
+
|
|
40
|
+
## Getting started
|
|
13
41
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| Stateful backend logic, real-time sync, custom protocols | [`Agent`](./agent-class.md) | The core class: state, WebSockets, scheduling, SQL, and sub-agents. No opinions about chat or LLMs. |
|
|
17
|
-
| A chat UI where you own the loop, the stream, and the response | [`AIChatAgent`](./chat-agents.md) | A thin chat-protocol adapter for `useAgentChat`. Bring your own agentic loop and custom streaming. |
|
|
18
|
-
| A durable, general-purpose reasoning agent | [`Think`](https://github.com/cloudflare/agents/blob/main/docs/think/index.md) | Opinionated runtime: agentic loop, sessions, tools, memory, compaction, recovery, and multi-channel delivery built in. |
|
|
19
|
-
| A voice agent (speech in, speech out) | [Voice mixins](./voice.md) | `withVoice` adds real-time STT/TTS, interruption and barge-in, and conversation persistence to an agent. |
|
|
20
|
-
| Durable multi-step processes (not chat) | [Workflows](./workflows.md) | Long-running, retryable step orchestration with Cloudflare Workflows. |
|
|
42
|
+
- [Getting Started](./getting-started.md) - Quick start guide for new users
|
|
43
|
+
- [Adding to an Existing Project](./adding-to-existing-project.md) - Integrate agents into your app
|
|
21
44
|
|
|
22
|
-
|
|
45
|
+
## Lifecycle
|
|
23
46
|
|
|
24
|
-
|
|
47
|
+
- [Durable Object Lifecycle](./lifecycle.md) - Install a Lifecycle on a Durable Object, write capabilities, and use the job queue
|
|
48
|
+
- [getCurrentAgent()](./get-current-agent.md) - Accessing the current object, request, and connection across async calls
|
|
25
49
|
|
|
26
|
-
|
|
50
|
+
## Harnesses
|
|
27
51
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- **Durable submissions** — webhooks and RPC callers submit a turn with an idempotency key and check status later, instead of holding a request open. See [Programmatic Submissions](https://github.com/cloudflare/agents/blob/main/docs/think/programmatic-submissions.md).
|
|
32
|
-
- **Human-in-the-loop without hangs** — a turn can pause for approval and resume later. A human wait is a first-class state, not a stuck request. See [Human in the Loop](./human-in-the-loop.md).
|
|
52
|
+
- [Pi harness (Beta)](./harnesses/pi.md) - Host pi-durable sessions in a Durable Object with durable storage and lifecycle wakeups
|
|
53
|
+
- [Think harness (Experimental)](./harnesses/think.md) - Run Think's agent loop as a Lifecycle capability, with transcripts in Sessions, output in Streams, and turns that survive eviction
|
|
54
|
+
- [Think (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/think/index.md) - Opinionated chat agent with built-in memory, tools, and streaming. Extends `Think`, which builds on `Agent`.
|
|
33
55
|
|
|
34
|
-
##
|
|
56
|
+
## Capabilities
|
|
35
57
|
|
|
36
|
-
|
|
37
|
-
- [Adding to an Existing Project](./adding-to-existing-project.md) - Integrate agents into your app
|
|
38
|
-
- [Understanding the Agent Class](./agent-class.md) - Deep dive into the Agent class architecture
|
|
58
|
+
Install each capability with `lifecycle.use()`. Capabilities marked experimental may change between releases.
|
|
39
59
|
|
|
40
|
-
|
|
60
|
+
| Capability | Import | Status | Docs |
|
|
61
|
+
| ------------------ | ------------------- | ------------ | --------------------------------------------------------------- |
|
|
62
|
+
| `PiHarness` | `agents/harness/pi` | Beta | [Pi harness](./harnesses/pi.md) |
|
|
63
|
+
| `MCPClientManager` | `agents/mcp/client` | Stable | [MCP client](./mcp-client.md) |
|
|
64
|
+
| `Scheduler` | `agents/schedules` | Stable | [Scheduling](./scheduling.md) |
|
|
65
|
+
| `State` | `agents/state` | Stable | [Lifecycle](./lifecycle.md#websockets-are-an-opt-in-capability) |
|
|
66
|
+
| `WebSockets` | `agents/websockets` | Stable | [Lifecycle](./lifecycle.md#websockets-are-an-opt-in-capability) |
|
|
67
|
+
| `Queue` | `agents/queue` | Experimental | [Queue](./queue.md) |
|
|
68
|
+
| `RoutedAgents` | `agents/routing` | Experimental | [Routing](./routing.md) |
|
|
69
|
+
| `Browser` | `agents/browser` | Experimental | [Browse the Web](./browse-the-web.md) |
|
|
70
|
+
| `Sessions` | `agents/sessions` | Experimental | [Sessions](./sessions.md) |
|
|
71
|
+
| `Streams` | `agents/streams` | Experimental | [Streams](./streams.md) |
|
|
72
|
+
| `Tasks` | `agents/tasks` | Experimental | [Tasks](./tasks.md) |
|
|
41
73
|
|
|
42
|
-
|
|
74
|
+
Building your own harness? Sessions stores the conversation, Streams holds durable incremental output, and Tasks runs replayable background work. [Models](./models.md) and [Models for pi-ai](./models-pi-ai.md) give you one provider for Workers AI and third-party models. [Context](./context.md) and [Workspace](https://github.com/cloudflare/agents/blob/main/docs/shell/index.md) are also available.
|
|
75
|
+
|
|
76
|
+
## Agent class
|
|
77
|
+
|
|
78
|
+
`Agent` extends `DurableObject`, installs a Lifecycle, and adds `Scheduler`, `Queue`, `MCPClientManager`, `State`, `WebSockets`, `Tasks`, and dynamic agents for you. Its methods (`this.schedule()`, `this.queue()`, `this.setState()`) delegate to those capabilities. Features below are documented for `Agent` and its subclasses.
|
|
79
|
+
|
|
80
|
+
### Core
|
|
81
|
+
|
|
82
|
+
- [Understanding the Agent Class](./agent-class.md) - How the Agent class is built on the Lifecycle
|
|
83
|
+
- [State Management](./state.md) - `setState()`, `initialState`, and `onStateChanged()`
|
|
43
84
|
- [Routing](./routing.md) - How `routeAgentRequest()` and agent naming works, plus `RoutedAgents` for a hub that routes to many independent Agents
|
|
44
85
|
- [Dynamic agents](./sub-agents.md) - Facet-backed child agents for code the parent supervises (dynamic/generated code, per-run tool agents, sandboxes) — not the recommended primitive for many independent peers like chats
|
|
45
86
|
- [HTTP & WebSockets](./http-websockets.md) - Request handling and real-time connections
|
|
46
87
|
- [Callable Methods](./callable-methods.md) - The `@callable` decorator and client-server method calls
|
|
47
88
|
- [Readonly Connections](./readonly-connections.md) - Restricting which connections can modify state
|
|
48
|
-
- [
|
|
89
|
+
- [Client SDK](./client-sdk.md) - Connecting from React (`useAgent`) and vanilla JS (`AgentClient`), state sync, and RPC calls
|
|
49
90
|
|
|
50
|
-
|
|
91
|
+
### Background processing
|
|
51
92
|
|
|
52
|
-
- [
|
|
93
|
+
- [Queue](./queue.md) - Durable background task execution
|
|
94
|
+
- [Scheduling](./scheduling.md) - Delayed, scheduled, and cron-based tasks
|
|
95
|
+
- [Retries](./retries.md) - Automatic retries with exponential backoff and jitter
|
|
96
|
+
- [Durable Execution](./durable-execution.md) - `runFiber()`, `startFiber()`, `stash()`, and crash recovery for long tasks
|
|
97
|
+
- [Workflows](./workflows.md) - Durable multi-step processing with Cloudflare Workflows
|
|
98
|
+
- [Human in the Loop](./human-in-the-loop.md) - Approval flows and manual intervention
|
|
53
99
|
|
|
54
|
-
|
|
100
|
+
### Communication channels
|
|
55
101
|
|
|
56
102
|
- [Email Service](./email.md) - Sending, receiving, and replying to emails
|
|
57
103
|
- [Webhooks](./webhooks.md) - Receiving and sending webhook events
|
|
58
104
|
- [Push Notifications](./push-notifications.md) - Browser push notifications via Web Push API and scheduled delivery
|
|
59
105
|
- TODO: [SMS](./sms.md) - Text message integration (Twilio, etc.)
|
|
60
106
|
- [Voice Agents](./voice.md) - Build voice agents with real-time speech-to-text, text-to-speech, and conversation persistence
|
|
61
|
-
- [Channels](./channels.md) - Send and receive messages through Slack, Telegram, email, browser voice, or custom adapters
|
|
62
107
|
- [Chat SDK State](./chat-sdk.md) - Store Chat SDK subscriptions, locks, queues, and history in Agents sub-agents
|
|
63
108
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- [Queue](./queue.md) - Durable background task execution
|
|
67
|
-
- [Scheduling](./scheduling.md) - Delayed, scheduled, and cron-based tasks
|
|
68
|
-
- [Retries](./retries.md) - Automatic retries with exponential backoff and jitter
|
|
69
|
-
- [Durable Execution](./durable-execution.md) - `runFiber()`, `startFiber()`, `stash()`, and crash recovery for long tasks
|
|
70
|
-
- [Workflows](./workflows.md) - Durable multi-step processing with Cloudflare Workflows
|
|
71
|
-
- [Human in the Loop](./human-in-the-loop.md) - Approval flows and manual intervention
|
|
72
|
-
|
|
73
|
-
## AI Integration
|
|
109
|
+
### Chat and AI
|
|
74
110
|
|
|
75
|
-
- TODO: [AI SDK Integration](./ai-sdk.md) - Using Vercel AI SDK with agents
|
|
76
|
-
- TODO: [TanStack Integration](./tanstack.md) - Using TanStack AI with agents
|
|
77
111
|
- [Chat Agents](./chat-agents.md) - `AIChatAgent` class and `useAgentChat` React hook
|
|
78
112
|
- [Chat & Fiber Recovery](./chat-agents.md#stream-recovery) - Recover LLM turns after Durable Object eviction
|
|
79
113
|
- [Agent Tools](./agent-tools.md) - Run chat-capable sub-agents as tools with streaming child timelines
|
|
80
114
|
- [Server-Driven Messages](./server-driven-messages.md) - Autonomous agent workflows: scheduled follow-ups, queue processing, webhooks, chained reasoning
|
|
81
|
-
- TODO: [Using AI Models](./using-ai-models.md) - OpenAI, Anthropic, Workers AI, and other providers
|
|
82
|
-
- [Models (Experimental)](./models.md) - `createAI` — one AI SDK provider for Workers AI and third-party catalog models, same string space
|
|
83
|
-
- [Models for pi-ai (Beta)](./models-pi-ai.md) - `createAI` for pi-ai: Workers AI ids and third-party models through AI Gateway, as a pi-ai provider
|
|
84
|
-
- [Pi harness (Beta)](./harnesses/pi.md) - Host pi-durable sessions in a Durable Object with durable storage and lifecycle wakeups
|
|
85
|
-
- TODO: [RAG (Retrieval Augmented Generation)](./rag.md) - Vector search with Vectorize
|
|
86
|
-
- [Sessions (Experimental)](./sessions.md) - Durable message trees, streamed history, compaction, search, and lossless attachment offload
|
|
87
|
-
- [Context (Experimental)](./context.md) - System-prompt blocks, frozen prompts, writable/searchable/loadable providers, and their tools
|
|
88
|
-
- [Workspace (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/shell/index.md) - Durable virtual filesystem backed by SQLite + R2
|
|
89
|
-
- [Codemode (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/agents/codemode.md) - LLM-generated executable code for tool orchestration
|
|
90
115
|
- [Client Tools Continuation](./client-tools-continuation.md) - Handling tool calls across client/server
|
|
91
116
|
- [Resumable Streaming](./resumable-streaming.md) - Automatic stream resumption on client disconnect
|
|
117
|
+
- [Long-Running Agents](./long-running-agents.md) - Building agents that persist for weeks or months: lifecycle, recovery, async operations, and planning
|
|
118
|
+
- TODO: [SQL API](./sql.md) - Using `this.sql` for direct database queries
|
|
119
|
+
- TODO: [Memory & Persistence](./memory.md) - Long-term storage patterns
|
|
92
120
|
|
|
93
121
|
## Think (Experimental)
|
|
94
122
|
|
|
@@ -103,50 +131,46 @@ The differentiator is not "we have durable state" — it is what happens when a
|
|
|
103
131
|
- [Sub-agents and Programmatic Turns](https://github.com/cloudflare/agents/blob/main/docs/think/sub-agents.md) - RPC streaming, `saveMessages`, recovery
|
|
104
132
|
- [Programmatic Submissions](https://github.com/cloudflare/agents/blob/main/docs/think/programmatic-submissions.md) - Durable Think turn admission for webhooks and RPC callers
|
|
105
133
|
|
|
134
|
+
## Models and tools
|
|
135
|
+
|
|
136
|
+
- TODO: [AI SDK Integration](./ai-sdk.md) - Using Vercel AI SDK with agents
|
|
137
|
+
- TODO: [TanStack Integration](./tanstack.md) - Using TanStack AI with agents
|
|
138
|
+
- TODO: [Using AI Models](./using-ai-models.md) - OpenAI, Anthropic, Workers AI, and other providers
|
|
139
|
+
- [Models (Experimental)](./models.md) - `createAI` — one AI SDK provider for Workers AI and third-party catalog models, same string space
|
|
140
|
+
- [Models for pi-ai (Beta)](./models-pi-ai.md) - `createAI` for pi-ai: Workers AI ids and third-party models through AI Gateway, as a pi-ai provider
|
|
141
|
+
- [Context (Experimental)](./context.md) - System-prompt blocks, frozen prompts, writable/searchable/loadable providers, and their tools
|
|
142
|
+
- [Workspace (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/shell/index.md) - Durable virtual filesystem backed by SQLite + R2
|
|
143
|
+
- [Codemode (Experimental)](./codemode.md) - LLM-generated executable code for tool orchestration
|
|
144
|
+
- [Browse the Web (Experimental)](./browse-the-web.md) - Full CDP access for web inspection, scraping, and debugging
|
|
145
|
+
- [Search the Web (Beta)](./search-the-web.md) - A `websearch` tool over Cloudflare's Web Search API for the pi harness, the AI SDK, and TanStack AI
|
|
146
|
+
- [Fetch the Web (Beta)](./fetch-the-web.md) - A `web_fetch` tool that reads a URL as Markdown, JSON, or text, with a host-controlled URL policy, for the pi harness, the AI SDK, TanStack AI, and Think
|
|
147
|
+
- TODO: [Cloudflare Sandboxes](./sandboxes.md) - Isolated environments for coding agents, ffmpeg, and heavy compute
|
|
148
|
+
- TODO: [RAG (Retrieval Augmented Generation)](./rag.md) - Vector search with Vectorize
|
|
149
|
+
|
|
106
150
|
## MCP (Model Context Protocol)
|
|
107
151
|
|
|
108
152
|
- [Creating MCP Servers](./mcp-servers.md) - Build MCP servers with `McpAgent`
|
|
109
153
|
- [Securing MCP Servers](./securing-mcp-servers.md) - OAuth and authentication for MCP
|
|
110
|
-
- [Connecting to MCP Servers](./mcp-client.md) - `addMcpServer()`
|
|
154
|
+
- [Connecting to MCP Servers](./mcp-client.md) - `MCPClientManager` on a Durable Object, or `addMcpServer()` on an Agent
|
|
111
155
|
- [MCP Transports](./mcp-transports.md) - Transport options: Streamable HTTP, SSE, and RPC
|
|
112
156
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
- TODO: [Securing your Agents](./securing-agents.md) - Authentication, authorization, and access control
|
|
116
|
-
- [Cross-Domain Authentication](./cross-domain-authentication.md) - Auth across different domains
|
|
117
|
-
|
|
118
|
-
## Observability & Debugging
|
|
157
|
+
## Operations
|
|
119
158
|
|
|
159
|
+
- [Configuration](./configuration.md) - wrangler.jsonc setup, types, secrets, and deployment
|
|
120
160
|
- [Observability](./observability.md) - Monitoring and tracing agent activity
|
|
161
|
+
- [Cross-Domain Authentication](./cross-domain-authentication.md) - Auth across different domains
|
|
162
|
+
- TODO: [Securing your Agents](./securing-agents.md) - Authentication, authorization, and access control
|
|
121
163
|
- TODO: [Testing](./testing.md) - Unit tests, integration tests, mocking agents
|
|
122
164
|
- TODO: [Evals](./evals.md) - Evaluating AI agent quality and behavior
|
|
123
|
-
|
|
124
|
-
## Agent Studio
|
|
125
|
-
|
|
126
165
|
- TODO: [Agent Studio](./agent-studio.md) - Local dev tool for inspecting and interacting with agent instances
|
|
127
166
|
|
|
128
|
-
##
|
|
129
|
-
|
|
130
|
-
- [Browse the Web (Experimental)](./browse-the-web.md) - Full CDP access for web inspection, scraping, and debugging
|
|
131
|
-
- TODO: [Cloudflare Sandboxes](./sandboxes.md) - Isolated environments for coding agents, ffmpeg, and heavy compute
|
|
132
|
-
|
|
133
|
-
## Advanced Topics
|
|
134
|
-
|
|
135
|
-
- [Long-Running Agents](./long-running-agents.md) - Building agents that persist for weeks or months: lifecycle, recovery, async operations, and planning
|
|
136
|
-
- TODO: [SQL API](./sql.md) - Using `this.sql` for direct database queries
|
|
137
|
-
- TODO: [Memory & Persistence](./memory.md) - Long-term storage patterns
|
|
138
|
-
- [Configuration](./configuration.md) - wrangler.jsonc setup, types, secrets, and deployment
|
|
139
|
-
|
|
140
|
-
## Migration Guides
|
|
167
|
+
## Migration guides
|
|
141
168
|
|
|
142
169
|
- [Migration to AI SDK v5](./migration-to-ai-sdk-v5.md)
|
|
143
170
|
- [Migration to AI SDK v6](./migration-to-ai-sdk-v6.md)
|
|
144
171
|
|
|
145
172
|
## Reference
|
|
146
173
|
|
|
147
|
-
- [Durable Object Lifecycle](./lifecycle.md) - Compose reusable durable components outside the Agent base class
|
|
148
|
-
- [Tasks](./tasks.md) - Durable, replayable background work with journaled steps and durable sleeps (experimental)
|
|
149
|
-
- [Streams](./streams.md) - Durable incremental output: chunk log, cursor, replay-then-tail reads (experimental)
|
|
150
174
|
- TODO: [API Reference](./api-reference.md) - Complete API documentation
|
|
151
175
|
- TODO: [FAQ / How is this different from Durable Objects?](./faq.md)
|
|
152
176
|
- TODO: [Resources & Further Reading](./resources.md)
|
package/docs/lifecycle.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Durable Object lifecycle
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
> releases while the composition surface stabilizes.
|
|
3
|
+
`agents/lifecycle` is stable. Most capabilities built on it are still
|
|
4
|
+
experimental; each capability's page says which.
|
|
6
5
|
|
|
7
6
|
`agents/lifecycle` lets reusable durable capabilities work in both `Agent` and a
|
|
8
7
|
plain Cloudflare Durable Object. It uses composition: your class extends the
|
|
@@ -156,6 +155,46 @@ Host-specific bindings, authentication, and protocol adapters remain explicit
|
|
|
156
155
|
constructor dependencies. Lifecycle never grants a capability the complete
|
|
157
156
|
host implicitly.
|
|
158
157
|
|
|
158
|
+
A capability's public operations can run before startup, because
|
|
159
|
+
[native RPC](#native-rpc) bypasses the automatic startup on fetch, alarm and
|
|
160
|
+
WebSocket events. If an operation starts work that `onStart` also awaits, such
|
|
161
|
+
as lazily opening a store, it must call `await this.lifecycle.ready()` first:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
class Store extends LifecycleCapability {
|
|
165
|
+
#opening: Promise<Database> | undefined;
|
|
166
|
+
|
|
167
|
+
constructor() {
|
|
168
|
+
super("store");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async onStart(): Promise<void> {
|
|
172
|
+
await this.#open();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async get(key: string): Promise<string | undefined> {
|
|
176
|
+
const db = await this.#open();
|
|
177
|
+
return db.get(key);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async #open(): Promise<Database> {
|
|
181
|
+
// Without this, an RPC that calls get() before startup begins the open
|
|
182
|
+
// outside startup, and onStart then waits on it behind a closed gate.
|
|
183
|
+
await this.lifecycle.ready();
|
|
184
|
+
this.#opening ??= openDatabase(this.lifecycle.storage);
|
|
185
|
+
return this.#opening;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Startup holds the input gate (`blockConcurrencyWhile`) while `onStart` runs, so
|
|
191
|
+
work begun outside startup has its timers and I/O held back and never finishes.
|
|
192
|
+
`onStart` waits on it until startup times out after 30 seconds and the object
|
|
193
|
+
is reset. Whether it happens depends on whether the RPC arrives first, so it
|
|
194
|
+
shows up as an intermittent timeout. `ready()` resolves immediately inside
|
|
195
|
+
startup, so `onStart` can call the same guarded method. `Tasks`, `Streams`,
|
|
196
|
+
`Scheduler`, `Queue` and `PiHarness` guard their operations this way.
|
|
197
|
+
|
|
159
198
|
Capability hooks run outside host context, but user callbacks run through
|
|
160
199
|
`this.lifecycle.runInHostContext(fn)` inside the host invocation context.
|
|
161
200
|
Scheduler and Queue dispatch their registered callbacks through this
|
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
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Search the Web (Beta)
|
|
2
|
+
|
|
3
|
+
`agents/websearch` gives a model a `web_search` tool over Cloudflare's [Web Search API](https://developers.cloudflare.com/web-search/), called through the `AI` binding and billed by the account's AI Gateway. The same tool is available for the pi harness, the AI SDK, and TanStack AI.
|
|
4
|
+
|
|
5
|
+
This page covers what the SDK adds on top of the API. For the binding, the providers, pricing, payment, and the error codes, see the [Web Search API docs](https://developers.cloudflare.com/web-search/).
|
|
6
|
+
|
|
7
|
+
> **Beta** — this feature may have breaking changes in future releases.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
You need:
|
|
12
|
+
|
|
13
|
+
- An `AI` binding: `"ai": { "binding": "AI" }` in `wrangler.jsonc`.
|
|
14
|
+
- workerd 1.20260924.1 or later, which is where `env.AI.websearch()` arrived. It ships with wrangler 4.141.0 and `@cloudflare/vite-plugin` 1.60.2.
|
|
15
|
+
- AI Gateway credits or a provider key on the gateway, in the account the Worker runs in. That account pays for every search. The `AI` binding always calls Cloudflare, so under `wrangler dev` searches run against, and bill, the account you are logged in to.
|
|
16
|
+
|
|
17
|
+
Then add the tool to your harness. Every adapter takes the same options; the TanStack AI adapter also takes `name`, because TanStack AI tools carry their name in the definition.
|
|
18
|
+
|
|
19
|
+
Pi harness:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { webSearchTool } from "agents/websearch/pi";
|
|
23
|
+
|
|
24
|
+
this.registry.install({
|
|
25
|
+
name: "tools",
|
|
26
|
+
tools: [webSearchTool({ binding: this.env.AI, provider: "exa" })]
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
AI SDK:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { webSearchTool } from "agents/websearch/ai-sdk";
|
|
34
|
+
|
|
35
|
+
const result = streamText({
|
|
36
|
+
model,
|
|
37
|
+
tools: { web_search: webSearchTool({ binding: this.env.AI }) },
|
|
38
|
+
messages
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If you convert UI messages yourself, pass the same tools to `convertToModelMessages(messages, { tools })`. Without them, the AI SDK sends earlier search results back to the model as the full JSON response instead of the trimmed text. `AiSdkHarness` does this for you.
|
|
43
|
+
|
|
44
|
+
TanStack AI:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { webSearchTool } from "agents/websearch/tanstack-ai";
|
|
48
|
+
|
|
49
|
+
const tools = [webSearchTool({ binding: this.env.AI })];
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Options
|
|
53
|
+
|
|
54
|
+
The model's input is `{ query, limit? }` and nothing else. The host fixes everything that affects cost or data handling. An invalid `limit`, `maxDescriptionChars`, `timeoutMs`, or `byokAlias` throws a `RangeError` when the tool is created:
|
|
55
|
+
|
|
56
|
+
| Option | Default | Notes |
|
|
57
|
+
| --------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `binding` | — | The `AI` binding. Or pass `source` instead (see [Other sources](#other-sources)). |
|
|
59
|
+
| `gateway` | `"default"` | AI Gateway id. |
|
|
60
|
+
| `provider` | platform default | `"ceramic"`, `"exa"`, or `"linkup"`. The model cannot choose or change it. |
|
|
61
|
+
| `byokAlias` | — | Bill a provider key stored on the gateway. Passed through as the API defines it. |
|
|
62
|
+
| `limit` | `5` | Results per search when the model does not ask for a count, and the most it gets when it asks for more. The tool description tells the model this number. |
|
|
63
|
+
| `maxDescriptionChars` | `600` | Per-result description length in the model's view. `Infinity` passes descriptions through whole. |
|
|
64
|
+
| `description` | built-in description | Replaces the tool description the model sees. |
|
|
65
|
+
| `timeoutMs` | `30000` | Give up on a search after this long, as a retryable `web_search_timeout` failure. |
|
|
66
|
+
|
|
67
|
+
## Model Interface
|
|
68
|
+
|
|
69
|
+
The model gets text: a numbered list of title, URL, and description, with descriptions trimmed to `maxDescriptionChars`. Some providers return descriptions of several thousand characters per result, so the default keeps a five-result search to a few kilobytes of context.
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
3 results for "cloudflare web search api":
|
|
73
|
+
|
|
74
|
+
1. Introducing the Web Search API
|
|
75
|
+
https://blog.cloudflare.com/introducing-web-search-api/
|
|
76
|
+
Today we are launching the Web Search API in open beta…
|
|
77
|
+
|
|
78
|
+
2. …
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The host gets the full API response, without trimming, as `WebSearchToolOutput`: `items` with their whole descriptions and every documented field, `metadata` with `requestId` and `latencyMs`, plus `provider`. Items without a URL are dropped, a missing title falls back to the URL, and fields the API does not document are left out:
|
|
82
|
+
|
|
83
|
+
- **Pi**: in the tool result's `details`, as `{ ok: true, output }`. The tool is `replay: "safe"`: if a search is interrupted mid-call, for example by an eviction, pi runs it again when the session recovers, and that is a second billed search. Completed results are stored and not searched again.
|
|
84
|
+
- **AI SDK**: as the return value of `execute`, so `onFinish`, UI message parts, and logs see the full response. `toModelOutput` renders the text for the model.
|
|
85
|
+
- **TanStack AI**: the server tool returns the rendered text, so the host gets the same text the model does.
|
|
86
|
+
|
|
87
|
+
`renderWebSearchResults(output, { maxDescriptionChars })` from `agents/websearch` is the renderer, if you want the same text elsewhere.
|
|
88
|
+
|
|
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
|
+
|
|
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
|
+
|
|
93
|
+
## Failures
|
|
94
|
+
|
|
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`.
|
|
96
|
+
|
|
97
|
+
The error's `message` is written for you, and can say to top up credits or configure a key. The model gets different text that tells it what to do next: fix the query, retry once, or carry on without search.
|
|
98
|
+
|
|
99
|
+
- **Pi**: the tool returns an error result with the model's text, and `details` is `{ ok: false, message, status, code, retryable, requestId }`.
|
|
100
|
+
- **AI SDK** and **TanStack AI**: the tool throws a `WebSearchError`, which is how those frameworks report tool errors. Its `message` is the model's text, and its `cause` is the original error with the API's detail.
|
|
101
|
+
|
|
102
|
+
Every adapter entry point re-exports `WebSearchError`, so `instanceof` checks do not need a second import.
|
|
103
|
+
|
|
104
|
+
If the harness cancels the call, the search is aborted and the abort propagates instead of becoming a failed result.
|
|
105
|
+
|
|
106
|
+
## Other sources
|
|
107
|
+
|
|
108
|
+
`createAIWebSearch` and `createHTTPWebSearch` from `agents/websearch` return a `WebSearchSource`: an object whose `search({ query, limit? }, { signal? })` returns the API response (`limit` defaults to 5), with no model involved. Use them from scheduled jobs, or outside Workers:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { createHTTPWebSearch } from "agents/websearch";
|
|
112
|
+
|
|
113
|
+
const search = createHTTPWebSearch({
|
|
114
|
+
accountId: env.CF_ACCOUNT_ID,
|
|
115
|
+
apiToken: env.CF_API_TOKEN,
|
|
116
|
+
provider: "linkup"
|
|
117
|
+
});
|
|
118
|
+
const { items } = await search.search({
|
|
119
|
+
query: "cloudflare agents sdk",
|
|
120
|
+
limit: 3
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Any `WebSearchSource` can be passed to a tool as `source` instead of `binding`. That is how tests substitute a fake, and how you wrap a source with caching or logging. Spread the source you wrap so its `provider` is kept:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
webSearchTool({
|
|
128
|
+
source: {
|
|
129
|
+
search: async ({ query }) => ({
|
|
130
|
+
items: [{ url: "https://example.com", title: query }],
|
|
131
|
+
metadata: { query, requestId: "test", latencyMs: 0 }
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
```
|