agents 0.26.0 → 0.27.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.
Files changed (233) hide show
  1. package/README.md +8 -9
  2. package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-Bhdbvf7s.d.ts} +13 -8
  3. package/dist/agent-routing.d.ts +1 -1
  4. package/dist/agent-tool-types.d.ts +1 -1
  5. package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-bJZwBMfq.d.ts} +2 -2
  6. package/dist/agent-tools.d.ts +1 -1
  7. package/dist/ai-sdk-OoGkFy3s.js +2444 -0
  8. package/dist/ai-sdk-OoGkFy3s.js.map +1 -0
  9. package/dist/apply-chunks-1FheRb9W.js +99 -0
  10. package/dist/apply-chunks-1FheRb9W.js.map +1 -0
  11. package/dist/broadcast-state-CEyI4uAK.js +69 -0
  12. package/dist/broadcast-state-CEyI4uAK.js.map +1 -0
  13. package/dist/browser/ai-sdk.d.ts +1 -1
  14. package/dist/browser/ai-sdk.js +2 -2
  15. package/dist/browser/ai-sdk.js.map +1 -1
  16. package/dist/browser/index.d.ts +1 -1
  17. package/dist/browser/tanstack-ai.d.ts +1 -1
  18. package/dist/browser/tanstack-ai.js +1 -1
  19. package/dist/{browser-DE3d-RLk.d.ts → browser-tmkcAAI3.d.ts} +2 -2
  20. package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-Bn-nzJQI.d.ts} +3 -3
  21. package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-CBqs6hqa.js} +58 -18
  22. package/dist/browser-tool-CBqs6hqa.js.map +1 -0
  23. package/dist/capability-B4WbF81e.js.map +1 -1
  24. package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-O5VbQzqg.d.ts} +9 -1
  25. package/dist/channel-Bak_6zDP.d.ts +333 -0
  26. package/dist/chat/index.d.ts +11 -9
  27. package/dist/chat/index.js +5 -194
  28. package/dist/chat/index.js.map +1 -1
  29. package/dist/chat/react.d.ts +2 -4
  30. package/dist/chat/react.js +3 -1
  31. package/dist/chat/react.js.map +1 -1
  32. package/dist/chat-sdk/index.d.ts +1 -1
  33. package/dist/chat-sdk/index.js +1 -1
  34. package/dist/cli.js +144 -0
  35. package/dist/{client-fyQrLGkD.js → client-1tEQ1Oqz.js} +27 -2
  36. package/dist/{client-fyQrLGkD.js.map → client-1tEQ1Oqz.js.map} +1 -1
  37. package/dist/{client-je3koD9Z.d.ts → client-DS3Dz9l0.d.ts} +2 -2
  38. package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
  39. package/dist/client.d.ts +1 -1
  40. package/dist/conversations-DH0ut_8n.d.ts +192 -0
  41. package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-C07C5o5Y.d.ts} +3 -3
  42. package/dist/daemon-core-Buubj-y1.js +481 -0
  43. package/dist/daemon-core-Buubj-y1.js.map +1 -0
  44. package/dist/daemon-core-CbohVPAu.d.ts +132 -0
  45. package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
  46. package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DRqp475_.d.ts} +2 -2
  47. package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
  48. package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
  49. package/dist/experimental/channels/email/index.js.map +1 -0
  50. package/dist/experimental/channels/index.d.ts +270 -0
  51. package/dist/experimental/channels/index.js +1186 -0
  52. package/dist/experimental/channels/index.js.map +1 -0
  53. package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
  54. package/dist/experimental/channels/slack/index.js +267 -0
  55. package/dist/experimental/channels/slack/index.js.map +1 -0
  56. package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
  57. package/dist/experimental/channels/telegram/index.js +198 -0
  58. package/dist/experimental/channels/telegram/index.js.map +1 -0
  59. package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
  60. package/dist/experimental/channels/web/ai-sdk.js +266 -0
  61. package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
  62. package/dist/experimental/channels/web/client.d.ts +97 -0
  63. package/dist/experimental/channels/web/client.js +349 -0
  64. package/dist/experimental/channels/web/client.js.map +1 -0
  65. package/dist/experimental/channels/web/index.d.ts +189 -0
  66. package/dist/experimental/channels/web/index.js +332 -0
  67. package/dist/experimental/channels/web/index.js.map +1 -0
  68. package/dist/gateway-BDC07gYO.d.ts +100 -0
  69. package/dist/handle-zAzh0UW2.d.ts +460 -0
  70. package/dist/harness/ai-sdk/index.d.ts +175 -0
  71. package/dist/harness/ai-sdk/index.js +605 -0
  72. package/dist/harness/ai-sdk/index.js.map +1 -0
  73. package/dist/harness/container/daemon/index.d.ts +76 -0
  74. package/dist/harness/container/daemon/index.js +3 -0
  75. package/dist/harness/container/index.d.ts +740 -0
  76. package/dist/harness/container/index.js +2152 -0
  77. package/dist/harness/container/index.js.map +1 -0
  78. package/dist/harness/container/runtime/index.d.ts +144 -0
  79. package/dist/harness/container/runtime/index.js +1082 -0
  80. package/dist/harness/container/runtime/index.js.map +1 -0
  81. package/dist/harness/opencode/index.d.ts +369 -0
  82. package/dist/harness/opencode/index.js +1072 -0
  83. package/dist/harness/opencode/index.js.map +1 -0
  84. package/dist/harness/pi/index.d.ts +2 -1
  85. package/dist/harness/store/index.d.ts +24 -0
  86. package/dist/harness/store/index.js +2 -0
  87. package/dist/harness/think/index.d.ts +821 -0
  88. package/dist/harness/think/index.js +2529 -0
  89. package/dist/harness/think/index.js.map +1 -0
  90. package/dist/harness-B6B9S3rb.d.ts +203 -0
  91. package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
  92. package/dist/images-Ce9SCu3X.js.map +1 -0
  93. package/dist/{index-BreL0YrQ.d.ts → index-D0A5tbWu.d.ts} +2 -2
  94. package/dist/index-Ib_4dwOo.d.ts +200 -0
  95. package/dist/index.d.ts +5 -5
  96. package/dist/index.js +2 -2
  97. package/dist/ingress-EFbrS547.js +9 -0
  98. package/dist/ingress-EFbrS547.js.map +1 -0
  99. package/dist/input-schema-DNrpTu49.js +23 -0
  100. package/dist/input-schema-DNrpTu49.js.map +1 -0
  101. package/dist/internal-kmw70xwR.js +46 -0
  102. package/dist/internal-kmw70xwR.js.map +1 -0
  103. package/dist/internal_context.d.ts +1 -1
  104. package/dist/lifecycle/index.d.ts +3 -3
  105. package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
  106. package/dist/mcp/client/do-oauth-client-provider.js +9 -0
  107. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
  108. package/dist/mcp/client/index.d.ts +1 -1
  109. package/dist/mcp/client/index.js +1 -1
  110. package/dist/mcp/client/x402.d.ts +35 -4
  111. package/dist/mcp/client/x402.js +24 -3
  112. package/dist/mcp/client/x402.js.map +1 -1
  113. package/dist/mcp/index.d.ts +1 -1
  114. package/dist/mcp/index.js +2 -2
  115. package/dist/models/ai-sdk/index.d.ts +16 -14
  116. package/dist/models/ai-sdk/index.js +1 -2442
  117. package/dist/models/opencode/index.d.ts +65 -0
  118. package/dist/models/opencode/index.js +285 -0
  119. package/dist/models/opencode/index.js.map +1 -0
  120. package/dist/models/pi-ai/index.d.ts +9 -7
  121. package/dist/models/pi-ai/index.js +2 -1
  122. package/dist/models/pi-ai/index.js.map +1 -1
  123. package/dist/options-pwTNq9z6.d.ts +134 -0
  124. package/dist/protocol-BEgrJYC5.d.ts +331 -0
  125. package/dist/protocol-CukuI73M.d.ts +386 -0
  126. package/dist/protocol-cOklVBBD.js +227 -0
  127. package/dist/protocol-cOklVBBD.js.map +1 -0
  128. package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
  129. package/dist/protocol-eXeJxhgu.js.map +1 -0
  130. package/dist/protocol-y2sSY584.js +148 -0
  131. package/dist/protocol-y2sSY584.js.map +1 -0
  132. package/dist/queue/index.d.ts +1 -1
  133. package/dist/react.d.ts +2 -2
  134. package/dist/routing/index.d.ts +2 -2
  135. package/dist/{scheduler-RdACNXDP.d.ts → scheduler-CrFCnv_J.d.ts} +2 -2
  136. package/dist/schedules/index.d.ts +1 -1
  137. package/dist/serializable.d.ts +1 -1
  138. package/dist/sessions/index.d.ts +11 -434
  139. package/dist/sessions/index.js +1 -2271
  140. package/dist/sessions-B9pNuxdT.js +2272 -0
  141. package/dist/sessions-B9pNuxdT.js.map +1 -0
  142. package/dist/settings-C45hDliX.js +253 -0
  143. package/dist/settings-C45hDliX.js.map +1 -0
  144. package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
  145. package/dist/{src-BZeu-SCD.js → src-DgCbZtIR.js} +4 -4
  146. package/dist/{src-BZeu-SCD.js.map → src-DgCbZtIR.js.map} +1 -1
  147. package/dist/stall-watchdog-BpRF2uwG.js +195 -0
  148. package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
  149. package/dist/state/index.d.ts +1 -1
  150. package/dist/store-DLeqKuj3.d.ts +310 -0
  151. package/dist/store-vgcPYo8K.js +432 -0
  152. package/dist/store-vgcPYo8K.js.map +1 -0
  153. package/dist/streams/index.d.ts +1 -1
  154. package/dist/streams/index.js +1 -1
  155. package/dist/{streams-DW-UCOUc.js → streams-CITClVer.js} +16 -3
  156. package/dist/streams-CITClVer.js.map +1 -0
  157. package/dist/{streams-Cmkj9QfW.d.ts → streams-fbG61qM8.d.ts} +2 -2
  158. package/dist/sub-routing.d.ts +1 -1
  159. package/dist/tasks/index.d.ts +1 -1
  160. package/dist/tasks/index.js +1 -1
  161. package/dist/{tasks-68DESxf0.js → tasks-CkTZNaV1.js} +2 -1
  162. package/dist/tasks-CkTZNaV1.js.map +1 -0
  163. package/dist/{tasks-9YxYtByh.d.ts → tasks-PtlB4Uyn.d.ts} +2 -2
  164. package/dist/tool-3PA8xjB_.js +421 -0
  165. package/dist/tool-3PA8xjB_.js.map +1 -0
  166. package/dist/tool-BPJEbwaX.d.ts +278 -0
  167. package/dist/transport-k2mFrtL8.d.ts +200 -0
  168. package/dist/turns-DCV3ycDl.js +317 -0
  169. package/dist/turns-DCV3ycDl.js.map +1 -0
  170. package/dist/voice/client.js +1 -1
  171. package/dist/voice/index.d.ts +2 -2
  172. package/dist/voice/index.js +1 -1
  173. package/dist/websearch/index.d.ts +58 -0
  174. package/dist/websearch/index.js +2 -0
  175. package/dist/websearch/tools/ai-sdk.d.ts +77 -0
  176. package/dist/websearch/tools/ai-sdk.js +46 -0
  177. package/dist/websearch/tools/ai-sdk.js.map +1 -0
  178. package/dist/websearch/tools/pi.d.ts +82 -0
  179. package/dist/websearch/tools/pi.js +89 -0
  180. package/dist/websearch/tools/pi.js.map +1 -0
  181. package/dist/websearch/tools/tanstack-ai.d.ts +71 -0
  182. package/dist/websearch/tools/tanstack-ai.js +46 -0
  183. package/dist/websearch/tools/tanstack-ai.js.map +1 -0
  184. package/dist/websockets/index.d.ts +12 -296
  185. package/dist/websockets/index.js +1 -1
  186. package/dist/{websockets-Ci-LZFHH.js → websockets-CmENGb-Z.js} +18 -4
  187. package/dist/websockets-CmENGb-Z.js.map +1 -0
  188. package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
  189. package/dist/workflow-types.d.ts +1 -1
  190. package/dist/workflows.d.ts +1 -1
  191. package/dist/workflows.js +1 -1
  192. package/docs/browse-the-web.md +3 -0
  193. package/docs/harnesses/think.md +215 -0
  194. package/docs/index.md +2 -1
  195. package/docs/lifecycle.md +40 -0
  196. package/docs/search-the-web.md +133 -0
  197. package/package.json +117 -38
  198. package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
  199. package/dist/channel-Bnm4S7T2.d.ts +0 -491
  200. package/dist/channels/ai-sdk.d.ts +0 -46
  201. package/dist/channels/ai-sdk.js +0 -120
  202. package/dist/channels/ai-sdk.js.map +0 -1
  203. package/dist/channels/email.js.map +0 -1
  204. package/dist/channels/index.d.ts +0 -233
  205. package/dist/channels/index.js +0 -608
  206. package/dist/channels/index.js.map +0 -1
  207. package/dist/channels/slack.js +0 -614
  208. package/dist/channels/slack.js.map +0 -1
  209. package/dist/channels/tanstack-ai.d.ts +0 -39
  210. package/dist/channels/tanstack-ai.js +0 -17
  211. package/dist/channels/tanstack-ai.js.map +0 -1
  212. package/dist/channels/telegram.js +0 -427
  213. package/dist/channels/telegram.js.map +0 -1
  214. package/dist/channels/voice.d.ts +0 -45
  215. package/dist/channels/voice.js +0 -122
  216. package/dist/channels/voice.js.map +0 -1
  217. package/dist/images-iiTDSyRu.js.map +0 -1
  218. package/dist/index-BB0kqhIz.d.ts +0 -101
  219. package/dist/ingress-BfetZbMO.js +0 -83
  220. package/dist/ingress-BfetZbMO.js.map +0 -1
  221. package/dist/internal-CYlgHl1l.js +0 -59
  222. package/dist/internal-CYlgHl1l.js.map +0 -1
  223. package/dist/models/ai-sdk/index.js.map +0 -1
  224. package/dist/protocol-kHsr-f0X.js.map +0 -1
  225. package/dist/sessions/index.js.map +0 -1
  226. package/dist/streams-DW-UCOUc.js.map +0 -1
  227. package/dist/surface-bZZJqBka.js +0 -17
  228. package/dist/surface-bZZJqBka.js.map +0 -1
  229. package/dist/tasks-68DESxf0.js.map +0 -1
  230. package/dist/tool-schema-CBjGPrsQ.js +0 -31
  231. package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
  232. package/dist/websockets-Ci-LZFHH.js.map +0 -1
  233. package/docs/channels.md +0 -323
@@ -0,0 +1,89 @@
1
+ import { i as WebSearchError, n as createWebSearchToolCore, u as MAX_WEB_SEARCH_QUERY_LENGTH } from "../../tool-3PA8xjB_.js";
2
+ import { Type } from "@earendil-works/pi-ai";
3
+ //#region src/websearch/tools/pi.ts
4
+ /**
5
+ * `agents/websearch/pi` — the `web_search` tool for the pi harness.
6
+ *
7
+ * @beta
8
+ */
9
+ /**
10
+ * The model's input schema. The description tells the model the host's
11
+ * `limit`; a larger value is not rejected (which would cost a validation
12
+ * round trip) but capped by the core. pi already coerces `"5"` to `5`.
13
+ */
14
+ function webSearchParameters(maxLimit) {
15
+ return Type.Object({
16
+ query: Type.String({
17
+ minLength: 1,
18
+ maxLength: MAX_WEB_SEARCH_QUERY_LENGTH,
19
+ description: "What to search for."
20
+ }),
21
+ limit: Type.Optional(Type.Integer({
22
+ minimum: 1,
23
+ description: `How many results to return (at most ${maxLimit}).`
24
+ }))
25
+ });
26
+ }
27
+ /**
28
+ * Create a pi tool that searches the web through Cloudflare's Web Search
29
+ * API. Install it on a registry like any other pi tool.
30
+ *
31
+ * The model chooses the query and (within the host's `limit`) how many
32
+ * results; the host chooses the gateway, provider, and billing. The tool is
33
+ * `replay: "safe"`: a search interrupted mid-call (say, by an eviction) runs
34
+ * again when the session recovers, which is a second billed search.
35
+ * Completed results are stored and not searched again.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { createRegistry } from "@earendil-works/pi-durable";
40
+ * import { webSearchTool } from "agents/websearch/pi";
41
+ *
42
+ * const registry = createRegistry();
43
+ * registry.install({
44
+ * name: "tools",
45
+ * tools: [webSearchTool({ binding: env.AI, provider: "exa" })]
46
+ * });
47
+ * ```
48
+ */
49
+ function webSearchTool(options) {
50
+ const core = createWebSearchToolCore(options);
51
+ return {
52
+ name: core.name,
53
+ description: core.description,
54
+ parameters: webSearchParameters(core.limit),
55
+ replay: "safe",
56
+ async execute(input, _api, context) {
57
+ const run = await core.run(input, { signal: context.abortSignal });
58
+ if (run.ok) return {
59
+ content: [{
60
+ type: "text",
61
+ text: run.text
62
+ }],
63
+ details: {
64
+ ok: true,
65
+ output: run.output
66
+ }
67
+ };
68
+ return {
69
+ content: [{
70
+ type: "text",
71
+ text: run.text
72
+ }],
73
+ isError: true,
74
+ details: {
75
+ ok: false,
76
+ message: run.error.message,
77
+ status: run.error.status,
78
+ code: run.error.code,
79
+ retryable: run.error.retryable,
80
+ requestId: run.error.requestId
81
+ }
82
+ };
83
+ }
84
+ };
85
+ }
86
+ //#endregion
87
+ export { WebSearchError, webSearchTool };
88
+
89
+ //# sourceMappingURL=pi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.js","names":[],"sources":["../../../src/websearch/tools/pi.ts"],"sourcesContent":["/**\n * `agents/websearch/pi` — the `web_search` tool for the pi harness.\n *\n * @beta\n */\nimport { Type } from \"@earendil-works/pi-ai\";\nimport type { ToolRegistration } from \"@earendil-works/pi-durable\";\nimport {\n MAX_WEB_SEARCH_QUERY_LENGTH,\n type WebSearchToolOutput\n} from \"../contract\";\nimport type { WebSearchErrorCode } from \"../source\";\nimport { createWebSearchToolCore, type WebSearchToolOptions } from \"../tool\";\n\nexport type {\n WebSearchResponse,\n WebSearchResult,\n WebSearchToolInput,\n WebSearchToolOutput\n} from \"../contract\";\nexport {\n WebSearchError,\n type WebSearchErrorCode,\n type WebSearchProvider,\n type WebSearchSource\n} from \"../source\";\nexport type { WebSearchToolOptions } from \"../tool\";\n\n/**\n * The model's input schema. The description tells the model the host's\n * `limit`; a larger value is not rejected (which would cost a validation\n * round trip) but capped by the core. pi already coerces `\"5\"` to `5`.\n */\nfunction webSearchParameters(maxLimit: number) {\n return Type.Object({\n query: Type.String({\n minLength: 1,\n maxLength: MAX_WEB_SEARCH_QUERY_LENGTH,\n description: \"What to search for.\"\n }),\n limit: Type.Optional(\n Type.Integer({\n minimum: 1,\n description: `How many results to return (at most ${maxLimit}).`\n })\n )\n });\n}\n\ntype WebSearchParameters = ReturnType<typeof webSearchParameters>;\n\n/**\n * Host-side details pi stores with each `web_search` result: the full API\n * response (untrimmed descriptions, provider metadata) or the failure.\n */\nexport type WebSearchToolDetails =\n | { ok: true; output: WebSearchToolOutput }\n | {\n ok: false;\n /** The source's error message, with the API's detail. */\n message: string;\n status: number;\n code: WebSearchErrorCode;\n retryable: boolean;\n requestId?: string;\n };\n\n/**\n * Create a pi tool that searches the web through Cloudflare's Web Search\n * API. Install it on a registry like any other pi tool.\n *\n * The model chooses the query and (within the host's `limit`) how many\n * results; the host chooses the gateway, provider, and billing. The tool is\n * `replay: \"safe\"`: a search interrupted mid-call (say, by an eviction) runs\n * again when the session recovers, which is a second billed search.\n * Completed results are stored and not searched again.\n *\n * @example\n * ```ts\n * import { createRegistry } from \"@earendil-works/pi-durable\";\n * import { webSearchTool } from \"agents/websearch/pi\";\n *\n * const registry = createRegistry();\n * registry.install({\n * name: \"tools\",\n * tools: [webSearchTool({ binding: env.AI, provider: \"exa\" })]\n * });\n * ```\n */\nexport function webSearchTool(\n options: WebSearchToolOptions\n): ToolRegistration<WebSearchParameters, WebSearchToolDetails> {\n const core = createWebSearchToolCore(options);\n return {\n name: core.name,\n description: core.description,\n parameters: webSearchParameters(core.limit),\n replay: \"safe\",\n async execute(input, _api, context) {\n const run = await core.run(input, { signal: context.abortSignal });\n if (run.ok) {\n return {\n content: [{ type: \"text\", text: run.text }],\n details: { ok: true, output: run.output }\n };\n }\n return {\n content: [{ type: \"text\", text: run.text }],\n isError: true,\n details: {\n ok: false,\n message: run.error.message,\n status: run.error.status,\n code: run.error.code,\n retryable: run.error.retryable,\n requestId: run.error.requestId\n }\n };\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAiCA,SAAS,oBAAoB,UAAkB;CAC7C,OAAO,KAAK,OAAO;EACjB,OAAO,KAAK,OAAO;GACjB,WAAW;GACX,WAAW;GACX,aAAa;EACf,CAAC;EACD,OAAO,KAAK,SACV,KAAK,QAAQ;GACX,SAAS;GACT,aAAa,uCAAuC,SAAS;EAC/D,CAAC,CACH;CACF,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,cACd,SAC6D;CAC7D,MAAM,OAAO,wBAAwB,OAAO;CAC5C,OAAO;EACL,MAAM,KAAK;EACX,aAAa,KAAK;EAClB,YAAY,oBAAoB,KAAK,KAAK;EAC1C,QAAQ;EACR,MAAM,QAAQ,OAAO,MAAM,SAAS;GAClC,MAAM,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,QAAQ,QAAQ,YAAY,CAAC;GACjE,IAAI,IAAI,IACN,OAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,IAAI;IAAK,CAAC;IAC1C,SAAS;KAAE,IAAI;KAAM,QAAQ,IAAI;IAAO;GAC1C;GAEF,OAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,IAAI;IAAK,CAAC;IAC1C,SAAS;IACT,SAAS;KACP,IAAI;KACJ,SAAS,IAAI,MAAM;KACnB,QAAQ,IAAI,MAAM;KAClB,MAAM,IAAI,MAAM;KAChB,WAAW,IAAI,MAAM;KACrB,WAAW,IAAI,MAAM;IACvB;GACF;EACF;CACF;AACF"}
@@ -0,0 +1,71 @@
1
+ import {
2
+ C as WebSearchResponse,
3
+ E as WebSearchToolOutput,
4
+ S as WEB_SEARCH_TOOL_NAME,
5
+ T as WebSearchToolInput,
6
+ c as WebSearchError,
7
+ d as WebSearchProvider,
8
+ l as WebSearchErrorCode,
9
+ p as WebSearchSource,
10
+ r as WebSearchToolOptions,
11
+ w as WebSearchResult
12
+ } from "../../tool-BPJEbwaX.js";
13
+
14
+ //#region src/websearch/tools/tanstack-ai.d.ts
15
+ type TanStackWebSearchToolOptions<
16
+ TName extends string = typeof WEB_SEARCH_TOOL_NAME
17
+ > = WebSearchToolOptions & {
18
+ /** The tool's name. TanStack AI tools carry it in the definition. */ name?: TName;
19
+ };
20
+ /**
21
+ * Create a TanStack AI tool that searches the web through Cloudflare's Web
22
+ * Search API. TanStack AI has one return channel, so the model and the host
23
+ * both get the trimmed text rendering. A failed search throws a
24
+ * `WebSearchError`, which TanStack AI reports as an error result: its
25
+ * `message` is written for the model, and its `cause` is the source's error
26
+ * with the API's detail. The tool is named `web_search` unless you pass
27
+ * `name`.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { webSearchTool } from "agents/websearch/tanstack-ai";
32
+ * import { chat } from "@tanstack/ai";
33
+ *
34
+ * const stream = chat({
35
+ * adapter,
36
+ * tools: [webSearchTool({ binding: env.AI })],
37
+ * messages
38
+ * });
39
+ * ```
40
+ */
41
+ declare function webSearchTool<
42
+ TName extends string = typeof WEB_SEARCH_TOOL_NAME
43
+ >(
44
+ options: TanStackWebSearchToolOptions<TName>
45
+ ): import("@tanstack/ai").ServerTool<
46
+ import("zod").ZodObject<
47
+ {
48
+ query: import("zod").ZodString;
49
+ limit: import("zod").ZodOptional<import("zod").ZodNumber>;
50
+ },
51
+ import("zod/v4/core").$strip
52
+ >,
53
+ import("@tanstack/ai").SchemaInput,
54
+ TName,
55
+ unknown
56
+ >;
57
+ //#endregion
58
+ export {
59
+ TanStackWebSearchToolOptions,
60
+ WebSearchError,
61
+ type WebSearchErrorCode,
62
+ type WebSearchProvider,
63
+ type WebSearchResponse,
64
+ type WebSearchResult,
65
+ type WebSearchSource,
66
+ type WebSearchToolInput,
67
+ type WebSearchToolOptions,
68
+ type WebSearchToolOutput,
69
+ webSearchTool
70
+ };
71
+ //# sourceMappingURL=tanstack-ai.d.ts.map
@@ -0,0 +1,46 @@
1
+ import { i as WebSearchError, n as createWebSearchToolCore, r as toolFailure } from "../../tool-3PA8xjB_.js";
2
+ import { t as webSearchInputSchema } from "../../input-schema-DNrpTu49.js";
3
+ import { toolDefinition } from "@tanstack/ai";
4
+ //#region src/websearch/tools/tanstack-ai.ts
5
+ /**
6
+ * `agents/websearch/tanstack-ai` — the `web_search` tool for TanStack AI.
7
+ *
8
+ * @beta
9
+ */
10
+ /**
11
+ * Create a TanStack AI tool that searches the web through Cloudflare's Web
12
+ * Search API. TanStack AI has one return channel, so the model and the host
13
+ * both get the trimmed text rendering. A failed search throws a
14
+ * `WebSearchError`, which TanStack AI reports as an error result: its
15
+ * `message` is written for the model, and its `cause` is the source's error
16
+ * with the API's detail. The tool is named `web_search` unless you pass
17
+ * `name`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { webSearchTool } from "agents/websearch/tanstack-ai";
22
+ * import { chat } from "@tanstack/ai";
23
+ *
24
+ * const stream = chat({
25
+ * adapter,
26
+ * tools: [webSearchTool({ binding: env.AI })],
27
+ * messages
28
+ * });
29
+ * ```
30
+ */
31
+ function webSearchTool(options) {
32
+ const core = createWebSearchToolCore(options);
33
+ return toolDefinition({
34
+ name: options.name ?? core.name,
35
+ description: core.description,
36
+ inputSchema: webSearchInputSchema(core.limit)
37
+ }).server(async (input, context) => {
38
+ const run = await core.run(input, { signal: context?.abortSignal });
39
+ if (!run.ok) throw toolFailure(run);
40
+ return run.text;
41
+ });
42
+ }
43
+ //#endregion
44
+ export { WebSearchError, webSearchTool };
45
+
46
+ //# sourceMappingURL=tanstack-ai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tanstack-ai.js","names":[],"sources":["../../../src/websearch/tools/tanstack-ai.ts"],"sourcesContent":["/**\n * `agents/websearch/tanstack-ai` — the `web_search` tool for TanStack AI.\n *\n * @beta\n */\nimport { toolDefinition } from \"@tanstack/ai\";\nimport type { WEB_SEARCH_TOOL_NAME } from \"../contract\";\nimport {\n createWebSearchToolCore,\n toolFailure,\n type WebSearchToolOptions\n} from \"../tool\";\nimport { webSearchInputSchema } from \"./input-schema\";\n\nexport type {\n WebSearchResponse,\n WebSearchResult,\n WebSearchToolInput,\n WebSearchToolOutput\n} from \"../contract\";\nexport {\n WebSearchError,\n type WebSearchErrorCode,\n type WebSearchProvider,\n type WebSearchSource\n} from \"../source\";\nexport type { WebSearchToolOptions } from \"../tool\";\n\nexport type TanStackWebSearchToolOptions<\n TName extends string = typeof WEB_SEARCH_TOOL_NAME\n> = WebSearchToolOptions & {\n /** The tool's name. TanStack AI tools carry it in the definition. */\n name?: TName;\n};\n\n/**\n * Create a TanStack AI tool that searches the web through Cloudflare's Web\n * Search API. TanStack AI has one return channel, so the model and the host\n * both get the trimmed text rendering. A failed search throws a\n * `WebSearchError`, which TanStack AI reports as an error result: its\n * `message` is written for the model, and its `cause` is the source's error\n * with the API's detail. The tool is named `web_search` unless you pass\n * `name`.\n *\n * @example\n * ```ts\n * import { webSearchTool } from \"agents/websearch/tanstack-ai\";\n * import { chat } from \"@tanstack/ai\";\n *\n * const stream = chat({\n * adapter,\n * tools: [webSearchTool({ binding: env.AI })],\n * messages\n * });\n * ```\n */\nexport function webSearchTool<\n TName extends string = typeof WEB_SEARCH_TOOL_NAME\n>(options: TanStackWebSearchToolOptions<TName>) {\n const core = createWebSearchToolCore(options);\n return toolDefinition({\n name: options.name ?? (core.name as TName),\n description: core.description,\n inputSchema: webSearchInputSchema(core.limit)\n }).server(async (input, context) => {\n const run = await core.run(input, { signal: context?.abortSignal });\n if (!run.ok) throw toolFailure(run);\n return run.text;\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,SAAgB,cAEd,SAA8C;CAC9C,MAAM,OAAO,wBAAwB,OAAO;CAC5C,OAAO,eAAe;EACpB,MAAM,QAAQ,QAAS,KAAK;EAC5B,aAAa,KAAK;EAClB,aAAa,qBAAqB,KAAK,KAAK;CAC9C,CAAC,CAAC,CAAC,OAAO,OAAO,OAAO,YAAY;EAClC,MAAM,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,QAAQ,SAAS,YAAY,CAAC;EAClE,IAAI,CAAC,IAAI,IAAI,MAAM,YAAY,GAAG;EAClC,OAAO,IAAI;CACb,CAAC;AACH"}
@@ -1,10 +1,3 @@
1
- import {
2
- S as ConnectionContext,
3
- T as WSMessage,
4
- r as CapabilityWebSocketUpgradeContext,
5
- s as LifecycleCapability,
6
- x as Connection
7
- } from "../capability-runner-DBAnGr6L.js";
8
1
  import {
9
2
  a as capnWebTransportUrl,
10
3
  n as CAPNWEB_TRANSPORT_QUERY,
@@ -12,294 +5,18 @@ import {
12
5
  r as CAPNWEB_TRANSPORT_VALUE,
13
6
  t as AgentTransport
14
7
  } from "../transport-protocol-ZTew5Wso.js";
15
- import { RpcTarget } from "cloudflare:workers";
16
-
17
- //#region src/websockets/options.d.ts
18
- /**
19
- * The part of a `State` capability the WebSockets capability uses. A
20
- * structural port, so any `State<T>` fits without a cast and the
21
- * capability never depends on the class itself.
22
- */
23
- type SyncedState = {
24
- /** Current state, or `undefined` when nothing is stored. */ get(): unknown /** Validate and persist a change; throws when the host rejects it. */;
25
- set(nextState: never, source: Connection): void;
26
- };
27
- /** A frame delivered on a capability-owned WebSocket connection. */
28
- type WebSocketMessage = WSMessage;
29
- /**
30
- * Connection handlers for the WebSockets capability. Handlers run inside
31
- * the host invocation boundary with the live connection in ambient
32
- * context (`getCurrentAgent().connection`).
33
- *
34
- * @experimental The API surface may change before stabilizing.
35
- */
36
- type WebSocketHandlers = {
37
- /** Handle a newly accepted hibernating WebSocket connection. */ onConnect?(
38
- connection: Connection,
39
- ctx: ConnectionContext
40
- ): void | Promise<void> /** Handle a message from a hibernating WebSocket connection. */;
41
- onMessage?(
42
- connection: Connection,
43
- message: WebSocketMessage
44
- ): void | Promise<void> /** Handle a closing hibernating WebSocket connection. */;
45
- onClose?(
46
- connection: Connection,
47
- code: number,
48
- reason: string,
49
- wasClean: boolean
50
- ): void | Promise<void> /** Handle a mid-connection WebSocket error. */;
51
- onError?(connection: Connection, error: unknown): void | Promise<void>;
52
- };
53
- /**
54
- * Configuration for the WebSockets capability.
55
- *
56
- * @experimental The API surface may change before stabilizing.
57
- */
58
- interface WebSocketsOptions {
59
- /**
60
- * Connection handlers for WebSocket clients. The capability accepts and
61
- * tracks every WebSocket upgrade either way; handlers add behavior on
62
- * connect, message, close and error.
63
- */
64
- readonly handlers?: WebSocketHandlers;
65
- /**
66
- * An `RpcTarget` whose prototype methods are the host's complete remote
67
- * interface, reached through `useAgent().call` and `.stub`. On the
68
- * `cf-websocket` wire they are answered as JSON `rpc` frames. On the
69
- * `capnweb` wire they are native Cap'n Web methods on the session root:
70
- * an `RpcTarget` result becomes a live stub, a `ReadableStream` streams,
71
- * and calls pipeline. Methods run through the host invocation boundary
72
- * with the calling connection in scope. `Agent` answers its own
73
- * decorated methods on the JSON wire and does not set this.
74
- */
75
- readonly callables?: RpcTarget;
76
- /**
77
- * Whether a new connection gets the connect-time protocol frames —
78
- * identity (`cf_agent_identity`), then the current state when `state`
79
- * is set — and whether protocol frames reach it at all.
80
- *
81
- * - `true` (default): every connection.
82
- * - a function: decided per connection at accept time. `false` marks
83
- * the connection no-protocol: it gets no protocol text frames, on
84
- * connect or via `broadcastState()`, but can still send and receive
85
- * ordinary messages and use callables. For binary-only clients.
86
- * - `false`: the host drives the connect sequence itself with
87
- * `sendConnectFrames()` (or `sendIdentity()` and `sendState()`
88
- * separately), and applies client state frames
89
- * with `applyStateFrame()` — `Agent` does this, since it must decide
90
- * whether a connection belongs to a facet before any frame is sent.
91
- */
92
- readonly protocol?:
93
- | boolean
94
- | ((connection: Connection, ctx: ConnectionContext) => boolean);
95
- /**
96
- * Decide at accept time whether a connection is readonly. A readonly
97
- * connection's `cf_agent_state` frames are refused with
98
- * `cf_agent_state_error`; everything else works. Also settable later
99
- * with `setReadonly()`.
100
- */
101
- readonly readonly?: (
102
- connection: Connection,
103
- ctx: ConnectionContext
104
- ) => boolean;
105
- /**
106
- * A {@link SyncedState} — normally a `State` capability — to sync over
107
- * connections. The capability pushes the current value to each new
108
- * connection after identity and applies `cf_agent_state` frames a
109
- * client sends: a readonly connection is refused, and a change the
110
- * host's validator rejects is answered with `cf_agent_state_error`.
111
- * Broadcasting a change is the state owner's call — wire the `State`'s
112
- * `onChanged` to `broadcastState(source)`. Install the same instance on
113
- * the lifecycle so it owns storage and validation; without this option
114
- * state is never sent or accepted over connections.
115
- */
116
- readonly state?: SyncedState;
117
- /**
118
- * Tags attached to each accepted connection, queryable through
119
- * `getConnections(tag)`. The connection id is always the first tag.
120
- */
121
- readonly getConnectionTags?: (
122
- connection: Connection,
123
- ctx: ConnectionContext
124
- ) => string[] | Promise<string[]>;
125
- }
126
- //#endregion
127
- //#region src/websockets/websockets.d.ts
128
- /**
129
- * Opt-in WebSocket support for Lifecycle Objects.
130
- *
131
- * Lifecycle itself does not model WebSockets — hosts that want them
132
- * install this capability, which owns the connection subsystem end to
133
- * end: it claims upgrades, dispatches `onConnect`/`onMessage`/`onClose`
134
- * inside the host invocation boundary, reciprocates close handshakes,
135
- * and answers `getConnections()`/`getConnection()`.
136
- *
137
- * ```ts
138
- * class Room extends DurableObject<Env> {
139
- * readonly webSockets = new WebSockets({
140
- * handlers: {
141
- * onConnect: (connection) => connection.send("welcome"),
142
- * onMessage: (connection, message) => { ... }
143
- * },
144
- * callables: new RoomCallables()
145
- * });
146
- * readonly lifecycle = Lifecycle.install(this).use(this.webSockets);
147
- * }
148
- * ```
149
- *
150
- * Connections arrive on one of two wires, chosen by the client:
151
- *
152
- * - **cf-websocket** (default): accepted with the Hibernation API. Idle
153
- * clients stay connected while the Durable Object leaves memory.
154
- * - **capnweb** (`?__agents_transport=capnweb`): protocol frames through
155
- * one pipe method on a Cap'n Web session whose root also carries the
156
- * host's callables natively. Non-hibernating — the object stays pinned
157
- * while the connection is open.
158
- *
159
- * Both wires dispatch the same handlers and appear in `getConnections()`.
160
- * On both, the capability speaks the Agent protocol a plain host needs
161
- * for `useAgent` and `AgentClient`: it sends the identity frame on
162
- * connect, and it serves `callables` — as `rpc` JSON frames on the
163
- * WebSocket wire, and natively on the Cap'n Web session root, where an
164
- * `RpcTarget` result becomes a live stub and calls pipeline. `call()`
165
- * and `stub` work against a plain Durable Object exactly as against an
166
- * `Agent`. Pass a `State` capability as `state` and the hook's
167
- * `state`/`setState` work too: the current value is pushed on connect
168
- * and client updates are validated and applied; the state owner
169
- * broadcasts changes with `broadcastState()`. Per-connection readonly
170
- * and no-protocol flags live here as well, for every host.
171
- *
172
- * @experimental The API surface may change before stabilizing.
173
- */
174
- declare class WebSockets extends LifecycleCapability {
175
- #private;
176
- /** Claims every upgrade, so Lifecycle dispatches it after all others. */
177
- readonly claims = "catch-all";
178
- constructor(options?: WebSocketsOptions);
179
- /**
180
- * Claim every upgrade, never declining: a Cap'n Web transport upgrade
181
- * becomes a session, everything else a tracked hibernating connection,
182
- * whether or not handlers or callables are configured. Handlers only add
183
- * behavior on connect, message, close, and error.
184
- */
185
- onWebSocketUpgrade({
186
- request
187
- }: CapabilityWebSocketUpgradeContext): Promise<Response>;
188
- /** Dispatch a platform message wake for a capability-owned socket. */
189
- onWebSocketMessage(
190
- ws: WebSocket,
191
- message: WebSocketMessage
192
- ): Promise<boolean>;
193
- /** Dispatch and reciprocate a close wake for an owned socket. */
194
- onWebSocketClose(
195
- ws: WebSocket,
196
- code: number,
197
- reason: string,
198
- wasClean: boolean
199
- ): Promise<boolean>;
200
- /** Dispatch an error wake for an owned socket. */
201
- onWebSocketError(ws: WebSocket, error: unknown): Promise<boolean>;
202
- /**
203
- * Close every owned connection during explicit host destruction. The
204
- * capability owns its sockets' lifetimes, so it also owns tearing
205
- * them down.
206
- */
207
- dispose(): void;
208
- /** Open connections on either wire, optionally by tag. */
209
- getConnections<TState = unknown>(
210
- tag?: string
211
- ): IterableIterator<Connection<TState>>;
212
- /** One connection on either wire, by id. */
213
- getConnection<TState = unknown>(id: string): Connection<TState> | undefined;
214
- /**
215
- * Send the connect sequence: the identity frame, then the current state
216
- * when one is stored. The identity carries `stateFollows` in that case,
217
- * so clients resolve `ready` only once the state has landed. Nothing is
218
- * sent to a no-protocol connection. Identity defaults as for
219
- * `sendIdentity()`.
220
- */
221
- sendConnectFrames(
222
- connection: Connection,
223
- identity?: {
224
- name: string;
225
- agent: string;
226
- }
227
- ): void;
228
- /**
229
- * Send the identity frame alone, unless the connection is no-protocol.
230
- * Clients resolve `ready` on it, so a host that also pushes state on
231
- * connect should use `sendConnectFrames()`. The defaults are the Durable
232
- * Object's routed name and host class; a host whose public identity
233
- * differs — an `Agent` facet, whose routed name is an internal encoding
234
- * of its logical name — passes its own.
235
- */
236
- sendIdentity(
237
- connection: Connection,
238
- identity?: {
239
- name: string;
240
- agent: string;
241
- }
242
- ): void;
243
- /**
244
- * Send the current state to one connection, unless nothing is stored
245
- * or the connection is no-protocol. Reading the state may seed the
246
- * initial value; see `#connecting`.
247
- */
248
- sendState(connection: Connection): void;
249
- /**
250
- * Apply a parsed `cf_agent_state` frame from a client. A readonly
251
- * connection is refused; a change the host's validator rejects is
252
- * logged in full server-side and answered with a generic
253
- * `cf_agent_state_error`. Broadcasting the accepted change is the state
254
- * owner's call, through its `onChanged` hook. Callers that drive the
255
- * protocol themselves call this inside their own invocation context;
256
- * the capability's automatic path does so via `runInHostContext`.
257
- *
258
- * @returns Whether the frame was a state frame (handled either way).
259
- */
260
- applyStateFrame(connection: Connection, frame: unknown): boolean;
261
- /**
262
- * Push the current state to every protocol-enabled connection except
263
- * the one a change came from, which already has the value it sent.
264
- * Wire a `State`'s `onChanged` to this.
265
- */
266
- broadcastState(except?: Connection | "server"): void;
267
- /** Whether the connection may update host state over the wire. */
268
- isReadonly(connection: Connection): boolean;
269
- /** Mark a connection readonly, or writable again. */
270
- setReadonly(connection: Connection, readonly?: boolean): void;
271
- /** Whether protocol text frames reach the connection. */
272
- isProtocolEnabled(connection: Connection): boolean;
273
- /** Enable or suppress protocol text frames for a connection. */
274
- setProtocolEnabled(connection: Connection, enabled: boolean): void;
275
- }
276
- //#endregion
277
- //#region src/websockets/connection-flags.d.ts
278
- /**
279
- * Internal per-connection flags, stored inside the connection's own state
280
- * under `_cf_`-prefixed keys so they ride the hibernation attachment (or a
281
- * bridged connection's synced state) and survive a wake. The state wrapper
282
- * installed by {@link ensureConnectionWrapped} hides them from
283
- * `connection.state` and preserves them across user `setState` calls.
284
- *
285
- * Owned by the WebSockets capability; `Agent` and framework mixins reach it
286
- * through the capability or, for their own keys, through
287
- * {@link registerInternalConnectionKeys}.
288
- */
289
- /** A readonly connection may not update host state. */
290
- declare const CF_READONLY_KEY = "_cf_readonly";
291
- /**
292
- * A no-protocol connection receives no protocol text frames (identity,
293
- * state sync, MCP servers) — neither on connect nor via broadcasts.
294
- */
295
- declare const CF_NO_PROTOCOL_KEY = "_cf_no_protocol";
296
- /**
297
- * Register additional `_cf_`-prefixed keys a host or mixin stores in
298
- * connection state, so they are hidden from `connection.state` and kept
299
- * across user `setState` calls like the capability's own flags.
300
- */
301
- declare function registerInternalConnectionKeys(...keys: string[]): void;
302
- //#endregion
8
+ import {
9
+ i as WebSocketsOptions,
10
+ n as WebSocketHandlers,
11
+ r as WebSocketMessage,
12
+ t as SyncedState
13
+ } from "../options-pwTNq9z6.js";
14
+ import {
15
+ i as WebSockets,
16
+ n as CF_READONLY_KEY,
17
+ r as registerInternalConnectionKeys,
18
+ t as CF_NO_PROTOCOL_KEY
19
+ } from "../index-Ib_4dwOo.js";
303
20
  export {
304
21
  type AgentTransport,
305
22
  CAPNWEB_TRANSPORT_QUERY,
@@ -315,4 +32,3 @@ export {
315
32
  isCapnWebTransportUpgrade,
316
33
  registerInternalConnectionKeys
317
34
  };
318
- //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,3 @@
1
1
  import { a as isCapnWebTransportUpgrade, i as capnWebTransportUrl, r as CAPNWEB_TRANSPORT_VALUE, t as CAPNWEB_TRANSPORT_QUERY } from "../transport-protocol-BxyngQ_R.js";
2
- import { l as registerInternalConnectionKeys, n as CF_NO_PROTOCOL_KEY, r as CF_READONLY_KEY, t as WebSockets } from "../websockets-Ci-LZFHH.js";
2
+ import { l as registerInternalConnectionKeys, n as CF_NO_PROTOCOL_KEY, r as CF_READONLY_KEY, t as WebSockets } from "../websockets-CmENGb-Z.js";
3
3
  export { CAPNWEB_TRANSPORT_QUERY, CAPNWEB_TRANSPORT_VALUE, CF_NO_PROTOCOL_KEY, CF_READONLY_KEY, WebSockets, capnWebTransportUrl, isCapnWebTransportUpgrade, registerInternalConnectionKeys };
@@ -571,6 +571,7 @@ function isRpcRequest(value) {
571
571
  return frame.type === "rpc" && typeof frame.id === "string" && typeof frame.method === "string" && Array.isArray(frame.args);
572
572
  }
573
573
  var _handlers = /* @__PURE__ */ new WeakMap();
574
+ var _added = /* @__PURE__ */ new WeakMap();
574
575
  var _getConnectionTags = /* @__PURE__ */ new WeakMap();
575
576
  var _protocol = /* @__PURE__ */ new WeakMap();
576
577
  var _readonly = /* @__PURE__ */ new WeakMap();
@@ -632,6 +633,7 @@ var WebSockets = class extends LifecycleCapability {
632
633
  _classPrivateMethodInitSpec(this, _WebSockets_brand);
633
634
  this.claims = "catch-all";
634
635
  _classPrivateFieldInitSpec(this, _handlers, void 0);
636
+ _classPrivateFieldInitSpec(this, _added, []);
635
637
  _classPrivateFieldInitSpec(this, _getConnectionTags, void 0);
636
638
  _classPrivateFieldInitSpec(this, _protocol, void 0);
637
639
  _classPrivateFieldInitSpec(this, _readonly, void 0);
@@ -688,6 +690,14 @@ var WebSockets = class extends LifecycleCapability {
688
690
  connection.close(1001, "Durable Object destroyed");
689
691
  } catch {}
690
692
  }
693
+ /**
694
+ * Add handlers for another component sharing these connections, such as
695
+ * a protocol of its own. They run before the configured handlers, and
696
+ * their `onMessage` can claim a message by returning true.
697
+ */
698
+ use(handlers) {
699
+ _classPrivateFieldGet2(_added, this).push(handlers);
700
+ }
691
701
  /** Open connections on either wire, optionally by tag. */
692
702
  *getConnections(tag) {
693
703
  for (const { connection } of _classPrivateFieldGet2(_sessions, this).values()) {
@@ -836,7 +846,7 @@ async function _connect(connection, ctx) {
836
846
  if (_classPrivateFieldGet2(_readonly, this)?.call(this, connection, ctx)) setConnectionReadonly(connection, true);
837
847
  if (_classPrivateFieldGet2(_protocol, this) !== false) if (typeof _classPrivateFieldGet2(_protocol, this) === "function" ? _classPrivateFieldGet2(_protocol, this).call(this, connection, ctx) : true) this.sendConnectFrames(connection);
838
848
  else setConnectionProtocolEnabled(connection, false);
839
- await this.lifecycle.runInHostContext(() => _classPrivateFieldGet2(_handlers, this)?.onConnect?.(connection, ctx), {
849
+ for (const handlers of [..._classPrivateFieldGet2(_added, this), _classPrivateFieldGet2(_handlers, this)]) await this.lifecycle.runInHostContext(() => handlers?.onConnect?.(connection, ctx), {
840
850
  connection,
841
851
  request: ctx.request
842
852
  });
@@ -850,13 +860,17 @@ async function _message(connection, message) {
850
860
  }
851
861
  }
852
862
  if (_classPrivateFieldGet2(_callables, this).size > 0 && await _assertClassBrand(_WebSockets_brand, this, _answerRpc).call(this, connection, message)) return;
863
+ for (const handlers of _classPrivateFieldGet2(_added, this)) if (await this.lifecycle.runInHostContext(() => handlers.onMessage?.(connection, message), { connection }) === true) return;
853
864
  await this.lifecycle.runInHostContext(() => _classPrivateFieldGet2(_handlers, this)?.onMessage?.(connection, message), { connection });
854
865
  }
855
866
  function _close(connection, code, reason, wasClean) {
856
- return this.lifecycle.runInHostContext(() => _classPrivateFieldGet2(_handlers, this)?.onClose?.(connection, code, reason, wasClean), { connection });
867
+ return _assertClassBrand(_WebSockets_brand, this, _each).call(this, (handlers) => this.lifecycle.runInHostContext(() => handlers?.onClose?.(connection, code, reason, wasClean), { connection }));
857
868
  }
858
869
  function _error(connection, error) {
859
- return this.lifecycle.runInHostContext(() => _classPrivateFieldGet2(_handlers, this)?.onError?.(connection, error), { connection });
870
+ return _assertClassBrand(_WebSockets_brand, this, _each).call(this, (handlers) => this.lifecycle.runInHostContext(() => handlers?.onError?.(connection, error), { connection }));
871
+ }
872
+ async function _each(run) {
873
+ for (const handlers of [..._classPrivateFieldGet2(_added, this), _classPrivateFieldGet2(_handlers, this)]) await run(handlers);
860
874
  }
861
875
  async function _acceptConnection(request) {
862
876
  const { 0: clientWebSocket, 1: serverWebSocket } = new WebSocketPair();
@@ -1027,4 +1041,4 @@ async function _dispatchCallable(name, invoke, connection) {
1027
1041
  //#endregion
1028
1042
  export { getConnectionFlag as a, isConnectionReadonly as c, setConnectionProtocolEnabled as d, setConnectionReadonly as f, ensureConnectionWrapped as i, registerInternalConnectionKeys as l, CF_NO_PROTOCOL_KEY as n, getConnectionRawState as o, CF_READONLY_KEY as r, isConnectionProtocolEnabled as s, WebSockets as t, setConnectionFlag as u };
1029
1043
 
1030
- //# sourceMappingURL=websockets-Ci-LZFHH.js.map
1044
+ //# sourceMappingURL=websockets-CmENGb-Z.js.map