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,189 @@
1
+ import {
2
+ d as ChannelUpgradeMatch,
3
+ m as ParticipantResult,
4
+ n as Channel,
5
+ t as Awaitable
6
+ } from "../../../channel-Bak_6zDP.js";
7
+ import {
8
+ _ as TranscriptMessage,
9
+ c as InboundEvent,
10
+ i as ConversationSnapshot,
11
+ m as ResponseChunk,
12
+ n as ConversationInfo,
13
+ p as Participant,
14
+ r as ConversationOperation,
15
+ y as TurnStatus
16
+ } from "../../../protocol-CukuI73M.js";
17
+ import { i as WebSockets } from "../../../index-Ib_4dwOo.js";
18
+ import {
19
+ a as ConversationChannel,
20
+ o as ConversationUpdate,
21
+ r as ChannelsHost
22
+ } from "../../../conversations-DH0ut_8n.js";
23
+
24
+ //#region src/experimental/channels/web/channel.d.ts
25
+ type WebChannelOptions = {
26
+ /**
27
+ * The connections to serve conversations on, for an agent sharing its own.
28
+ * Default: the WebSockets Channels shares, created on first use.
29
+ */
30
+ websockets?: WebSockets;
31
+ };
32
+ /**
33
+ * Serves conversations over the agent's WebSockets connections, to clients
34
+ * the gateway has resolved. Frames are
35
+ * namespaced `channels:`, so a connection can carry other protocols too.
36
+ */
37
+ declare class WebChannel implements ConversationChannel {
38
+ #private;
39
+ constructor(options?: WebChannelOptions);
40
+ mount(host: ChannelsHost): void;
41
+ publish(conversationId: string, update: ConversationUpdate): void;
42
+ }
43
+ //#endregion
44
+ //#region src/experimental/channels/web/ingress.d.ts
45
+ /** How the gateway takes the Web Channel's WebSocket upgrades. */
46
+ type WebIngressOptions = {
47
+ /**
48
+ * Who is connecting, from request data you can verify, such as a session
49
+ * cookie or an Access JWT. Return null to refuse the upgrade.
50
+ */
51
+ participant(request: Request): Awaitable<ParticipantResult>;
52
+ /**
53
+ * The agent object the participant reaches, or null to refuse them. That
54
+ * object is the authorization boundary: whoever reaches it may use every
55
+ * conversation in it. Default: an agent object of the participant's own.
56
+ */
57
+ route?(request: Request, participant: Participant): Awaitable<string | null>;
58
+ /**
59
+ * Which upgrades are for the Web Channel, and the conversation each
60
+ * follows. Return undefined for one that is not. Default: `/channels`,
61
+ * or `/channels/<conversation>`.
62
+ */
63
+ match?(request: Request): ChannelUpgradeMatch | undefined;
64
+ };
65
+ /**
66
+ * The Web Channel's side in the gateway: it resolves each WebSocket upgrade
67
+ * and forwards it to the agent, whose `WebChannel` serves the connection.
68
+ *
69
+ * ```ts
70
+ * new ChannelGateway({
71
+ * agent: (route) => env.SupportAgent.getByName(route),
72
+ * channels: {
73
+ * web: web({
74
+ * participant: async (request) =>
75
+ * (await verifySession(request, env))?.id ?? null
76
+ * })
77
+ * }
78
+ * });
79
+ * ```
80
+ */
81
+ declare function web(options: WebIngressOptions): Channel;
82
+ //#endregion
83
+ //#region src/experimental/channels/web/protocol.d.ts
84
+ /** Who a connection is: set by the gateway, read by the Web Channel. */
85
+ type WebIdentity = {
86
+ /** The route that picked the agent. */ route: string /** The conversation to follow. Default: the agent's default for the route. */;
87
+ conversationId?: string;
88
+ participant: Participant;
89
+ };
90
+ /**
91
+ * The header carrying a connection's WebIdentity from the gateway to the
92
+ * agent. The gateway always sets it, so a client cannot supply its own; an
93
+ * agent must not take WebSocket upgrades from any other route.
94
+ */
95
+ declare const WEB_IDENTITY_HEADER = "x-channels-identity";
96
+ type ClientFrame =
97
+ | {
98
+ type: "channels:event";
99
+ event: InboundEvent;
100
+ }
101
+ | {
102
+ type: "channels:subscribe";
103
+ responseId: string;
104
+ from?: number;
105
+ } /** Ask for the agent's conversations; answered by `channels:conversations`. */
106
+ | {
107
+ type: "channels:list-conversations";
108
+ requestId: string;
109
+ };
110
+ type ServerFrame = {
111
+ conversationId: string;
112
+ } &
113
+ /**
114
+ * On connect, after a reset (empty), and when the connection follows
115
+ * another conversation. `you` is this connection's participant;
116
+ * `operations` are the conversation operations it may send.
117
+ */
118
+ (
119
+ | ({
120
+ type: "channels:snapshot";
121
+ you: Participant;
122
+ operations: ConversationOperation[];
123
+ } & ConversationSnapshot)
124
+ | {
125
+ type: "channels:turn";
126
+ turn: TurnStatus;
127
+ } /** Upserts by id; an unknown id appends. */
128
+ | {
129
+ type: "channels:messages";
130
+ messages: TranscriptMessage[];
131
+ }
132
+ | {
133
+ type: "channels:chunks";
134
+ responseId: string /** Seq of the first chunk. */;
135
+ from: number;
136
+ chunks: ResponseChunk[];
137
+ } /** Everything before this was replay; what follows is live. */
138
+ | {
139
+ type: "channels:caught-up";
140
+ responseId: string;
141
+ cursor: number;
142
+ }
143
+ | {
144
+ type: "channels:end";
145
+ responseId: string;
146
+ state: "ended" | "interrupted" | "not-found";
147
+ }
148
+ /**
149
+ * The agent's conversations: the answer to a list request, carrying its
150
+ * `requestId`, or pushed when one is created or forked.
151
+ */
152
+ | {
153
+ type: "channels:conversations";
154
+ requestId?: string;
155
+ conversations?: ConversationInfo[];
156
+ error?: string;
157
+ } /** `conversationId` is the one a create or fork started, when it did. */
158
+ | {
159
+ type: "channels:ack";
160
+ eventId: string;
161
+ error?: string;
162
+ }
163
+ );
164
+ /** A frame that names a Channels type but is malformed. */
165
+ type InvalidClientFrame = {
166
+ invalid: string;
167
+ eventId?: string;
168
+ };
169
+ /**
170
+ * Parse a text frame. Returns undefined for anything that is not a Channels
171
+ * frame, so the socket's other protocols keep working.
172
+ */
173
+ declare function parseClientFrame(
174
+ text: string
175
+ ): ClientFrame | InvalidClientFrame | undefined;
176
+ //#endregion
177
+ export {
178
+ ClientFrame,
179
+ InvalidClientFrame,
180
+ ServerFrame,
181
+ WEB_IDENTITY_HEADER,
182
+ WebChannel,
183
+ WebChannelOptions,
184
+ WebIdentity,
185
+ WebIngressOptions,
186
+ parseClientFrame,
187
+ web
188
+ };
189
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,332 @@
1
+ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../../../classPrivateFieldGet2-DZBYAB34.js";
2
+ import { t as _classPrivateMethodInitSpec } from "../../../classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
+ import { a as getConnectionFlag, l as registerInternalConnectionKeys, t as WebSockets, u as setConnectionFlag } from "../../../websockets-CmENGb-Z.js";
4
+ import { i as participantRoute } from "../../../internal-kmw70xwR.js";
5
+ import { n as parseClientFrame, t as WEB_IDENTITY_HEADER } from "../../../protocol-y2sSY584.js";
6
+ //#region src/experimental/channels/web/channel.ts
7
+ /** Where a Channels connection's identity lives in its connection state. */
8
+ const IDENTITY_KEY = "_cf_channels";
9
+ registerInternalConnectionKeys(IDENTITY_KEY);
10
+ var _options = /* @__PURE__ */ new WeakMap();
11
+ var _websockets = /* @__PURE__ */ new WeakMap();
12
+ var _host = /* @__PURE__ */ new WeakMap();
13
+ var _pending = /* @__PURE__ */ new WeakMap();
14
+ var _reads = /* @__PURE__ */ new WeakMap();
15
+ var _WebChannel_brand = /* @__PURE__ */ new WeakSet();
16
+ /**
17
+ * Serves conversations over the agent's WebSockets connections, to clients
18
+ * the gateway has resolved. Frames are
19
+ * namespaced `channels:`, so a connection can carry other protocols too.
20
+ */
21
+ var WebChannel = class {
22
+ constructor(options = {}) {
23
+ _classPrivateMethodInitSpec(this, _WebChannel_brand);
24
+ _classPrivateFieldInitSpec(this, _options, void 0);
25
+ _classPrivateFieldInitSpec(this, _websockets, void 0);
26
+ _classPrivateFieldInitSpec(this, _host, void 0);
27
+ _classPrivateFieldInitSpec(this, _pending, /* @__PURE__ */ new Map());
28
+ _classPrivateFieldInitSpec(this, _reads, /* @__PURE__ */ new Map());
29
+ _classPrivateFieldSet2(_options, this, options);
30
+ }
31
+ mount(host) {
32
+ if (_classPrivateFieldGet2(_host, this)) throw new Error("A WebChannel can be mounted only once");
33
+ _classPrivateFieldSet2(_host, this, host);
34
+ _classPrivateFieldSet2(_websockets, this, _classPrivateFieldGet2(_options, this).websockets ?? host.websockets(() => new WebSockets()));
35
+ _classPrivateFieldGet2(_websockets, this).use({
36
+ onConnect: (connection, ctx) => _assertClassBrand(_WebChannel_brand, this, _connect).call(this, connection, ctx),
37
+ onMessage: (connection, message) => _assertClassBrand(_WebChannel_brand, this, _message).call(this, connection, message),
38
+ onClose: (connection) => _assertClassBrand(_WebChannel_brand, this, _close).call(this, connection)
39
+ });
40
+ }
41
+ publish(conversationId, update) {
42
+ for (const [connection, identity] of _assertClassBrand(_WebChannel_brand, this, _connections).call(this)) {
43
+ if (identity.conversationId !== conversationId) continue;
44
+ if (update.type === "messages" && _assertClassBrand(_WebChannel_brand, this, _sentBy).call(this, update, connection)) continue;
45
+ if (update.type === "reset") _assertClassBrand(_WebChannel_brand, this, _stopReads).call(this, connection.id);
46
+ const frame = toFrame(update, conversationId, identity.participant, _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).operations);
47
+ const pending = _classPrivateFieldGet2(_pending, this).get(connection.id);
48
+ if (pending) pending.push(frame);
49
+ else send(connection, frame);
50
+ }
51
+ }
52
+ };
53
+ async function _connect(connection, { request }) {
54
+ const header = request.headers.get(WEB_IDENTITY_HEADER);
55
+ if (header === null) return;
56
+ const resolved = JSON.parse(header);
57
+ const host = _assertClassBrand(_WebChannel_brand, this, _mounted).call(this);
58
+ const identity = {
59
+ ...resolved,
60
+ conversationId: resolved.conversationId ?? host.defaultConversation(),
61
+ channelKey: host.channelKey
62
+ };
63
+ setConnectionFlag(connection, IDENTITY_KEY, identity);
64
+ _classPrivateFieldGet2(_pending, this).set(connection.id, []);
65
+ await _assertClassBrand(_WebChannel_brand, this, _sendSnapshot).call(this, connection, identity);
66
+ }
67
+ async function _message(connection, message) {
68
+ const identity = _assertClassBrand(_WebChannel_brand, this, _identityOf).call(this, connection);
69
+ if (!identity || typeof message !== "string") return false;
70
+ const frame = parseClientFrame(message);
71
+ if (!frame) return false;
72
+ if ("invalid" in frame) {
73
+ send(connection, {
74
+ type: "channels:ack",
75
+ conversationId: identity.conversationId,
76
+ eventId: frame.eventId ?? "",
77
+ error: `Invalid frame: ${frame.invalid}`
78
+ });
79
+ return true;
80
+ }
81
+ if (frame.type === "channels:list-conversations") {
82
+ await _assertClassBrand(_WebChannel_brand, this, _list).call(this, connection, identity, frame.requestId);
83
+ return true;
84
+ }
85
+ if (frame.type === "channels:subscribe") {
86
+ _assertClassBrand(_WebChannel_brand, this, _subscribe).call(this, connection, identity, frame.responseId, frame.from);
87
+ return true;
88
+ }
89
+ const { eventId } = frame.event;
90
+ let result;
91
+ try {
92
+ result = await _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).dispatch(frame.event, origin(identity, connection.id));
93
+ } catch {
94
+ send(connection, {
95
+ type: "channels:ack",
96
+ conversationId: identity.conversationId,
97
+ eventId,
98
+ error: "Event rejected"
99
+ });
100
+ return true;
101
+ }
102
+ const followed = result.conversationId;
103
+ send(connection, {
104
+ type: "channels:ack",
105
+ conversationId: followed ?? identity.conversationId,
106
+ eventId
107
+ });
108
+ if (followed !== void 0 && followed !== identity.conversationId) await _assertClassBrand(_WebChannel_brand, this, _follow).call(this, connection, {
109
+ ...identity,
110
+ conversationId: followed
111
+ });
112
+ if (followed !== void 0) await _assertClassBrand(_WebChannel_brand, this, _pushConversations).call(this);
113
+ return true;
114
+ }
115
+ async function _list(connection, identity, requestId) {
116
+ const frame = {
117
+ type: "channels:conversations",
118
+ conversationId: identity.conversationId,
119
+ requestId
120
+ };
121
+ try {
122
+ const conversations = await _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).listConversations();
123
+ send(connection, {
124
+ ...frame,
125
+ conversations
126
+ });
127
+ } catch (error) {
128
+ console.error("Failed to list conversations", error);
129
+ send(connection, {
130
+ ...frame,
131
+ error: "Failed to list conversations"
132
+ });
133
+ }
134
+ }
135
+ /** Tell every connection the agent's conversations changed. */
136
+ async function _pushConversations() {
137
+ let conversations;
138
+ try {
139
+ conversations = await _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).listConversations();
140
+ } catch (error) {
141
+ console.error("Failed to list conversations", error);
142
+ return;
143
+ }
144
+ for (const [connection, identity] of _assertClassBrand(_WebChannel_brand, this, _connections).call(this)) {
145
+ const frame = {
146
+ type: "channels:conversations",
147
+ conversationId: identity.conversationId,
148
+ conversations
149
+ };
150
+ const pending = _classPrivateFieldGet2(_pending, this).get(connection.id);
151
+ if (pending) pending.push(frame);
152
+ else send(connection, frame);
153
+ }
154
+ }
155
+ /** Move a connection to another conversation, starting from its snapshot. */
156
+ async function _follow(connection, identity) {
157
+ _assertClassBrand(_WebChannel_brand, this, _stopReads).call(this, connection.id);
158
+ setConnectionFlag(connection, IDENTITY_KEY, identity);
159
+ _classPrivateFieldGet2(_pending, this).set(connection.id, []);
160
+ await _assertClassBrand(_WebChannel_brand, this, _sendSnapshot).call(this, connection, identity);
161
+ }
162
+ function _close(connection) {
163
+ _assertClassBrand(_WebChannel_brand, this, _stopReads).call(this, connection.id);
164
+ _classPrivateFieldGet2(_pending, this).delete(connection.id);
165
+ }
166
+ function _sentBy(update, connection) {
167
+ const surface = update.origin?.surface;
168
+ return surface !== void 0 && surface.channelKey === _classPrivateFieldGet2(_host, this)?.channelKey && connectionIdOf(surface.address) === connection.id;
169
+ }
170
+ async function _sendSnapshot(connection, identity) {
171
+ try {
172
+ const snapshot = await _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).snapshot(identity.conversationId);
173
+ send(connection, {
174
+ type: "channels:snapshot",
175
+ conversationId: identity.conversationId,
176
+ you: identity.participant,
177
+ operations: [..._assertClassBrand(_WebChannel_brand, this, _mounted).call(this).operations],
178
+ ...snapshot
179
+ });
180
+ for (const frame of _classPrivateFieldGet2(_pending, this).get(connection.id) ?? []) send(connection, frame);
181
+ _classPrivateFieldGet2(_pending, this).delete(connection.id);
182
+ } catch (error) {
183
+ console.error("Failed to read the conversation snapshot", error);
184
+ _classPrivateFieldGet2(_pending, this).delete(connection.id);
185
+ connection.close(1011, "Snapshot failed");
186
+ }
187
+ }
188
+ /** One read per response per connection; a repeated subscribe joins it. */
189
+ function _subscribe(connection, identity, responseId, from) {
190
+ let reads = _classPrivateFieldGet2(_reads, this).get(connection.id);
191
+ if (!reads) _classPrivateFieldGet2(_reads, this).set(connection.id, reads = /* @__PURE__ */ new Map());
192
+ if (reads.has(responseId)) return;
193
+ const controller = new AbortController();
194
+ reads.set(responseId, controller);
195
+ const { conversationId } = identity;
196
+ _assertClassBrand(_WebChannel_brand, this, _mounted).call(this).readResponse(conversationId, responseId, {
197
+ from,
198
+ signal: controller.signal,
199
+ onChunks: (first, chunks) => send(connection, {
200
+ type: "channels:chunks",
201
+ conversationId,
202
+ responseId,
203
+ from: first,
204
+ chunks
205
+ }),
206
+ onCaughtUp: (cursor) => send(connection, {
207
+ type: "channels:caught-up",
208
+ conversationId,
209
+ responseId,
210
+ cursor
211
+ })
212
+ }).then((ending) => send(connection, {
213
+ type: "channels:end",
214
+ conversationId,
215
+ responseId,
216
+ state: ending
217
+ }), (error) => {
218
+ if (controller.signal.aborted) return;
219
+ console.error(`Failed to read response "${responseId}"`, error);
220
+ send(connection, {
221
+ type: "channels:end",
222
+ conversationId,
223
+ responseId,
224
+ state: "interrupted"
225
+ });
226
+ }).finally(() => reads.delete(responseId));
227
+ }
228
+ function _stopReads(connectionId) {
229
+ for (const controller of _classPrivateFieldGet2(_reads, this).get(connectionId)?.values() ?? []) controller.abort();
230
+ _classPrivateFieldGet2(_reads, this).delete(connectionId);
231
+ }
232
+ function* _connections() {
233
+ for (const connection of _classPrivateFieldGet2(_websockets, this)?.getConnections() ?? []) {
234
+ const identity = _assertClassBrand(_WebChannel_brand, this, _identityOf).call(this, connection);
235
+ if (identity) yield [connection, identity];
236
+ }
237
+ }
238
+ function _identityOf(connection) {
239
+ const identity = getConnectionFlag(connection, IDENTITY_KEY);
240
+ return identity?.channelKey === _classPrivateFieldGet2(_host, this)?.channelKey ? identity : void 0;
241
+ }
242
+ function _mounted() {
243
+ if (!_classPrivateFieldGet2(_host, this)) throw new Error("WebChannel is not mounted");
244
+ return _classPrivateFieldGet2(_host, this);
245
+ }
246
+ function origin(identity, connectionId) {
247
+ return {
248
+ conversationId: identity.conversationId,
249
+ participant: identity.participant,
250
+ surface: {
251
+ channelKey: identity.channelKey,
252
+ version: 1,
253
+ address: {
254
+ conversationId: identity.conversationId,
255
+ connectionId
256
+ },
257
+ label: "Web"
258
+ }
259
+ };
260
+ }
261
+ function connectionIdOf(address) {
262
+ return typeof address === "object" && address !== null && "connectionId" in address && typeof address.connectionId === "string" ? address.connectionId : void 0;
263
+ }
264
+ function toFrame(update, conversationId, you, operations) {
265
+ switch (update.type) {
266
+ case "turn": return {
267
+ type: "channels:turn",
268
+ conversationId,
269
+ turn: update.turn
270
+ };
271
+ case "messages": return {
272
+ type: "channels:messages",
273
+ conversationId,
274
+ messages: update.messages
275
+ };
276
+ case "reset": return {
277
+ type: "channels:snapshot",
278
+ conversationId,
279
+ you,
280
+ operations: [...operations],
281
+ messages: [],
282
+ turns: []
283
+ };
284
+ case "response-end": return {
285
+ type: "channels:end",
286
+ conversationId,
287
+ responseId: update.responseId,
288
+ state: update.ending
289
+ };
290
+ }
291
+ }
292
+ /** A failed send to one stale socket must not stop delivery to the rest. */
293
+ function send(connection, frame) {
294
+ try {
295
+ connection.send(JSON.stringify(frame));
296
+ } catch {}
297
+ }
298
+ //#endregion
299
+ //#region src/experimental/channels/web/ingress.ts
300
+ /**
301
+ * The Web Channel's side in the gateway: it resolves each WebSocket upgrade
302
+ * and forwards it to the agent, whose `WebChannel` serves the connection.
303
+ *
304
+ * ```ts
305
+ * new ChannelGateway({
306
+ * agent: (route) => env.SupportAgent.getByName(route),
307
+ * channels: {
308
+ * web: web({
309
+ * participant: async (request) =>
310
+ * (await verifySession(request, env))?.id ?? null
311
+ * })
312
+ * }
313
+ * });
314
+ * ```
315
+ */
316
+ function web(options) {
317
+ const route = options.route;
318
+ return { upgrade: {
319
+ match: options.match ?? matchChannelsPath,
320
+ participant: (request) => options.participant(request),
321
+ route: (request, participant) => route ? route(request, participant) : participantRoute(participant)
322
+ } };
323
+ }
324
+ function matchChannelsPath(request) {
325
+ const match = /^\/channels(?:\/([^/]+))?$/.exec(new URL(request.url).pathname);
326
+ if (!match) return void 0;
327
+ return match[1] === void 0 ? {} : { conversationId: decodeURIComponent(match[1]) };
328
+ }
329
+ //#endregion
330
+ export { WEB_IDENTITY_HEADER, WebChannel, parseClientFrame, web };
331
+
332
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/experimental/channels/web/channel.ts","../../../../src/experimental/channels/web/ingress.ts"],"sourcesContent":["import type {\n Connection,\n ConnectionContext,\n WSMessage\n} from \"../../../lifecycle\";\nimport {\n getConnectionFlag,\n registerInternalConnectionKeys,\n setConnectionFlag\n} from \"../../../websockets/connection-flags\";\nimport { WebSockets } from \"../../../websockets\";\nimport type {\n ChannelsHost,\n ConversationChannel,\n ConversationUpdate\n} from \"../conversations\";\nimport type {\n ConversationOperation,\n EventOrigin,\n Participant\n} from \"../protocol\";\nimport {\n parseClientFrame,\n WEB_IDENTITY_HEADER,\n type ServerFrame,\n type WebIdentity\n} from \"./protocol\";\n\n/** Where a Channels connection's identity lives in its connection state. */\nconst IDENTITY_KEY = \"_cf_channels\";\nregisterInternalConnectionKeys(IDENTITY_KEY);\n\nexport type WebChannelOptions = {\n /**\n * The connections to serve conversations on, for an agent sharing its own.\n * Default: the WebSockets Channels shares, created on first use.\n */\n websockets?: WebSockets;\n};\n\ntype Identity = Omit<WebIdentity, \"conversationId\"> & {\n conversationId: string;\n channelKey: string;\n};\n\n/**\n * Serves conversations over the agent's WebSockets connections, to clients\n * the gateway has resolved. Frames are\n * namespaced `channels:`, so a connection can carry other protocols too.\n */\nexport class WebChannel implements ConversationChannel {\n readonly #options: WebChannelOptions;\n #websockets: WebSockets | undefined;\n #host: ChannelsHost | undefined;\n /** Frames held back until a connection has its snapshot. */\n readonly #pending = new Map<string, ServerFrame[]>();\n /** Active response reads, by connection, then response. */\n readonly #reads = new Map<string, Map<string, AbortController>>();\n\n constructor(options: WebChannelOptions = {}) {\n this.#options = options;\n }\n\n mount(host: ChannelsHost): void {\n if (this.#host) throw new Error(\"A WebChannel can be mounted only once\");\n this.#host = host;\n this.#websockets =\n this.#options.websockets ?? host.websockets(() => new WebSockets());\n this.#websockets.use({\n onConnect: (connection, ctx) => this.#connect(connection, ctx),\n onMessage: (connection, message) => this.#message(connection, message),\n onClose: (connection) => this.#close(connection)\n });\n }\n\n publish(conversationId: string, update: ConversationUpdate): void {\n for (const [connection, identity] of this.#connections()) {\n if (identity.conversationId !== conversationId) continue;\n // The sender adds its own message once the agent accepts it.\n if (update.type === \"messages\" && this.#sentBy(update, connection)) {\n continue;\n }\n if (update.type === \"reset\") this.#stopReads(connection.id);\n const frame = toFrame(\n update,\n conversationId,\n identity.participant,\n this.#mounted().operations\n );\n const pending = this.#pending.get(connection.id);\n if (pending) pending.push(frame);\n else send(connection, frame);\n }\n }\n\n async #connect(\n connection: Connection,\n { request }: ConnectionContext\n ): Promise<void> {\n const header = request.headers.get(WEB_IDENTITY_HEADER);\n if (header === null) return;\n // The gateway is the trust boundary: it resolves who is connecting and\n // sets this header. The agent must only be reachable through the\n // gateway, or a caller could forge the header and join as anyone.\n // There is no further authorization here: the agent object is the\n // boundary, so a connection may use every conversation in it.\n // SAFETY: only the gateway sets this header, with a WebIdentity.\n const resolved = JSON.parse(header) as WebIdentity;\n const host = this.#mounted();\n const identity: Identity = {\n ...resolved,\n conversationId: resolved.conversationId ?? host.defaultConversation(),\n channelKey: host.channelKey\n };\n setConnectionFlag(connection, IDENTITY_KEY, identity);\n // Listen for pushes before reading the snapshot, so none are lost.\n this.#pending.set(connection.id, []);\n await this.#sendSnapshot(connection, identity);\n }\n\n async #message(connection: Connection, message: WSMessage): Promise<boolean> {\n const identity = this.#identityOf(connection);\n if (!identity || typeof message !== \"string\") return false;\n const frame = parseClientFrame(message);\n if (!frame) return false;\n\n if (\"invalid\" in frame) {\n send(connection, {\n type: \"channels:ack\",\n conversationId: identity.conversationId,\n eventId: frame.eventId ?? \"\",\n error: `Invalid frame: ${frame.invalid}`\n });\n return true;\n }\n if (frame.type === \"channels:list-conversations\") {\n await this.#list(connection, identity, frame.requestId);\n return true;\n }\n if (frame.type === \"channels:subscribe\") {\n this.#subscribe(connection, identity, frame.responseId, frame.from);\n return true;\n }\n\n const { eventId } = frame.event;\n let result;\n try {\n result = await this.#mounted().dispatch(\n frame.event,\n origin(identity, connection.id)\n );\n } catch {\n send(connection, {\n type: \"channels:ack\",\n conversationId: identity.conversationId,\n eventId,\n error: \"Event rejected\"\n });\n return true;\n }\n // The sender follows a conversation it created or forked; other\n // connections stay where they are. Acknowledge first: a client resends\n // unacknowledged events on every snapshot, and the new conversation's\n // snapshot would otherwise carry the create or fork into it again.\n const followed = result.conversationId;\n send(connection, {\n type: \"channels:ack\",\n conversationId: followed ?? identity.conversationId,\n eventId\n });\n if (followed !== undefined && followed !== identity.conversationId) {\n await this.#follow(connection, { ...identity, conversationId: followed });\n }\n if (followed !== undefined) await this.#pushConversations();\n return true;\n }\n\n async #list(\n connection: Connection,\n identity: Identity,\n requestId: string\n ): Promise<void> {\n // The agent object is the authorization boundary, so every connection\n // may list every conversation in it.\n const frame = {\n type: \"channels:conversations\" as const,\n conversationId: identity.conversationId,\n requestId\n };\n try {\n const conversations = await this.#mounted().listConversations();\n send(connection, { ...frame, conversations });\n } catch (error) {\n console.error(\"Failed to list conversations\", error);\n send(connection, { ...frame, error: \"Failed to list conversations\" });\n }\n }\n\n /** Tell every connection the agent's conversations changed. */\n async #pushConversations(): Promise<void> {\n let conversations;\n try {\n conversations = await this.#mounted().listConversations();\n } catch (error) {\n console.error(\"Failed to list conversations\", error);\n return;\n }\n for (const [connection, identity] of this.#connections()) {\n const frame: ServerFrame = {\n type: \"channels:conversations\",\n conversationId: identity.conversationId,\n conversations\n };\n const pending = this.#pending.get(connection.id);\n if (pending) pending.push(frame);\n else send(connection, frame);\n }\n }\n\n /** Move a connection to another conversation, starting from its snapshot. */\n async #follow(connection: Connection, identity: Identity): Promise<void> {\n this.#stopReads(connection.id);\n setConnectionFlag(connection, IDENTITY_KEY, identity);\n this.#pending.set(connection.id, []);\n await this.#sendSnapshot(connection, identity);\n }\n\n #close(connection: Connection): void {\n this.#stopReads(connection.id);\n this.#pending.delete(connection.id);\n }\n\n #sentBy(\n update: Extract<ConversationUpdate, { type: \"messages\" }>,\n connection: Connection\n ): boolean {\n const surface = update.origin?.surface;\n return (\n surface !== undefined &&\n surface.channelKey === this.#host?.channelKey &&\n connectionIdOf(surface.address) === connection.id\n );\n }\n\n async #sendSnapshot(\n connection: Connection,\n identity: Identity\n ): Promise<void> {\n try {\n const snapshot = await this.#mounted().snapshot(identity.conversationId);\n send(connection, {\n type: \"channels:snapshot\",\n conversationId: identity.conversationId,\n you: identity.participant,\n operations: [...this.#mounted().operations],\n ...snapshot\n });\n for (const frame of this.#pending.get(connection.id) ?? []) {\n send(connection, frame);\n }\n this.#pending.delete(connection.id);\n } catch (error) {\n console.error(\"Failed to read the conversation snapshot\", error);\n this.#pending.delete(connection.id);\n connection.close(1011, \"Snapshot failed\");\n }\n }\n\n /** One read per response per connection; a repeated subscribe joins it. */\n #subscribe(\n connection: Connection,\n identity: Identity,\n responseId: string,\n from: number | undefined\n ): void {\n let reads = this.#reads.get(connection.id);\n if (!reads) this.#reads.set(connection.id, (reads = new Map()));\n if (reads.has(responseId)) return;\n const controller = new AbortController();\n reads.set(responseId, controller);\n\n const { conversationId } = identity;\n this.#mounted()\n .readResponse(conversationId, responseId, {\n from,\n signal: controller.signal,\n onChunks: (first, chunks) =>\n send(connection, {\n type: \"channels:chunks\",\n conversationId,\n responseId,\n from: first,\n chunks\n }),\n onCaughtUp: (cursor) =>\n send(connection, {\n type: \"channels:caught-up\",\n conversationId,\n responseId,\n cursor\n })\n })\n .then(\n (ending) =>\n send(connection, {\n type: \"channels:end\",\n conversationId,\n responseId,\n state: ending\n }),\n (error) => {\n if (controller.signal.aborted) return;\n console.error(`Failed to read response \"${responseId}\"`, error);\n // Tell the client the read is over, so it does not wait forever.\n send(connection, {\n type: \"channels:end\",\n conversationId,\n responseId,\n state: \"interrupted\"\n });\n }\n )\n .finally(() => reads.delete(responseId));\n }\n\n #stopReads(connectionId: string): void {\n for (const controller of this.#reads.get(connectionId)?.values() ?? []) {\n controller.abort();\n }\n this.#reads.delete(connectionId);\n }\n\n *#connections(): Iterable<[Connection, Identity]> {\n for (const connection of this.#websockets?.getConnections() ?? []) {\n const identity = this.#identityOf(connection);\n if (identity) yield [connection, identity];\n }\n }\n\n #identityOf(connection: Connection): Identity | undefined {\n // SAFETY: only #connect writes this key, with an Identity.\n const identity = getConnectionFlag(connection, IDENTITY_KEY) as\n | Identity\n | undefined;\n return identity?.channelKey === this.#host?.channelKey\n ? identity\n : undefined;\n }\n\n #mounted(): ChannelsHost {\n if (!this.#host) throw new Error(\"WebChannel is not mounted\");\n return this.#host;\n }\n}\n\nfunction origin(identity: Identity, connectionId: string): EventOrigin {\n return {\n conversationId: identity.conversationId,\n participant: identity.participant,\n surface: {\n channelKey: identity.channelKey,\n version: 1,\n address: { conversationId: identity.conversationId, connectionId },\n label: \"Web\"\n }\n };\n}\n\nfunction connectionIdOf(address: unknown): string | undefined {\n return typeof address === \"object\" &&\n address !== null &&\n \"connectionId\" in address &&\n typeof address.connectionId === \"string\"\n ? address.connectionId\n : undefined;\n}\n\nfunction toFrame(\n update: ConversationUpdate,\n conversationId: string,\n you: Participant,\n operations: readonly ConversationOperation[]\n): ServerFrame {\n switch (update.type) {\n case \"turn\":\n return { type: \"channels:turn\", conversationId, turn: update.turn };\n case \"messages\":\n return {\n type: \"channels:messages\",\n conversationId,\n messages: update.messages\n };\n case \"reset\":\n return {\n type: \"channels:snapshot\",\n conversationId,\n you,\n operations: [...operations],\n messages: [],\n turns: []\n };\n case \"response-end\":\n return {\n type: \"channels:end\",\n conversationId,\n responseId: update.responseId,\n state: update.ending\n };\n }\n}\n\n/** A failed send to one stale socket must not stop delivery to the rest. */\nfunction send(connection: Connection, frame: ServerFrame): void {\n try {\n connection.send(JSON.stringify(frame));\n } catch {\n // The socket is closing; its close handler cleans up.\n }\n}\n","import type {\n Awaitable,\n Channel,\n ChannelUpgradeMatch,\n ParticipantResult\n} from \"../channel\";\nimport { participantRoute } from \"../internal\";\nimport type { Participant } from \"../protocol\";\n\n/** How the gateway takes the Web Channel's WebSocket upgrades. */\nexport type WebIngressOptions = {\n /**\n * Who is connecting, from request data you can verify, such as a session\n * cookie or an Access JWT. Return null to refuse the upgrade.\n */\n participant(request: Request): Awaitable<ParticipantResult>;\n /**\n * The agent object the participant reaches, or null to refuse them. That\n * object is the authorization boundary: whoever reaches it may use every\n * conversation in it. Default: an agent object of the participant's own.\n */\n route?(request: Request, participant: Participant): Awaitable<string | null>;\n /**\n * Which upgrades are for the Web Channel, and the conversation each\n * follows. Return undefined for one that is not. Default: `/channels`,\n * or `/channels/<conversation>`.\n */\n match?(request: Request): ChannelUpgradeMatch | undefined;\n};\n\n/**\n * The Web Channel's side in the gateway: it resolves each WebSocket upgrade\n * and forwards it to the agent, whose `WebChannel` serves the connection.\n *\n * ```ts\n * new ChannelGateway({\n * agent: (route) => env.SupportAgent.getByName(route),\n * channels: {\n * web: web({\n * participant: async (request) =>\n * (await verifySession(request, env))?.id ?? null\n * })\n * }\n * });\n * ```\n */\nexport function web(options: WebIngressOptions): Channel {\n const route = options.route;\n return {\n upgrade: {\n match: options.match ?? matchChannelsPath,\n participant: (request) => options.participant(request),\n route: (request, participant) =>\n route ? route(request, participant) : participantRoute(participant)\n }\n };\n}\n\nfunction matchChannelsPath(request: Request): ChannelUpgradeMatch | undefined {\n const match = /^\\/channels(?:\\/([^/]+))?$/.exec(\n new URL(request.url).pathname\n );\n if (!match) return undefined;\n return match[1] === undefined\n ? {}\n : { conversationId: decodeURIComponent(match[1]) };\n}\n"],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import {
2
+ N as ChannelIdentity,
3
+ S as ChannelEmailInput,
4
+ a as ChannelDeliveryOptions,
5
+ k as ChannelIngressEvent,
6
+ l as ChannelStreamOptions,
7
+ n as Channel,
8
+ o as ChannelMessage,
9
+ p as DeliveryResult,
10
+ r as ChannelChunkSource
11
+ } from "./channel-Bak_6zDP.js";
12
+ import {
13
+ b as ChannelMessageSurface,
14
+ p as Participant,
15
+ s as GatewayOrigin
16
+ } from "./protocol-CukuI73M.js";
17
+ import { c as GatewayEvent } from "./conversations-DH0ut_8n.js";
18
+
19
+ //#region src/experimental/channels/gateway.d.ts
20
+ type ChannelRouteEvent = {
21
+ channelKey: string;
22
+ event: ChannelIngressEvent /** Who the Channel resolved the sender as; null when it refused them. */;
23
+ participant: Participant | null /** The agent object the event reaches; null when it is ignored or refused. */;
24
+ route:
25
+ | string
26
+ | null /** Stable identity derived only from the configured Channel and eventId. */;
27
+ dispatchId: string;
28
+ };
29
+ /** The agent object a route names, as the gateway reaches it. */
30
+ type GatewayAgent = {
31
+ /** Hand the agent an inbound event; Channels' `receive` serves it. */ receive(
32
+ event: GatewayEvent,
33
+ origin: GatewayOrigin
34
+ ): Promise<unknown>;
35
+ fetch(request: Request): Promise<Response>;
36
+ };
37
+ type ChannelGatewayOptions = {
38
+ /**
39
+ * The Channels this Worker serves. Each one that takes ingress says who
40
+ * its senders are (`participant`) and which agent object they reach
41
+ * (`route`).
42
+ */
43
+ channels: Record<string, Channel> /** The agent object a route names. */;
44
+ agent(
45
+ route: string
46
+ ): GatewayAgent /** Observes every valid route outcome before it is sent to the agent. */;
47
+ onRoute?(event: ChannelRouteEvent): void | Promise<void>;
48
+ };
49
+ /**
50
+ * The Worker's entry point for Channels. Authenticates and normalizes
51
+ * webhooks, resolves WebSocket upgrades, routes each to the agent object
52
+ * its route names, and sends to surfaces.
53
+ *
54
+ * The gateway is the trust boundary. It alone decides who a sender is and
55
+ * tells the agent, so an agent serving Channels must be reachable only
56
+ * through it: an app that forwards an upgrade to the agent some other way
57
+ * (another fetch handler, `routeAgentRequest`, RPC) lets the caller pick
58
+ * its own participant and conversation.
59
+ *
60
+ * The agent object is the authorization boundary. Whoever a Channel routes
61
+ * to an object may list, join, create, fork and reset every conversation in
62
+ * it. To keep people apart, route them to different objects; by default
63
+ * each participant gets an object of their own.
64
+ */
65
+ declare class ChannelGateway {
66
+ #private;
67
+ constructor(options: ChannelGatewayOptions);
68
+ /** Serve a request if it is for Channels, or return undefined. */
69
+ fetch(request: Request): Promise<Response | undefined>;
70
+ handleEmail(email: ChannelEmailInput): Promise<boolean>;
71
+ /** Deliver through the configured Channel named by the surface. */
72
+ deliver(
73
+ surface: ChannelMessageSurface,
74
+ message: ChannelMessage,
75
+ options?: ChannelDeliveryOptions
76
+ ): Promise<DeliveryResult>;
77
+ /**
78
+ * Deliver a progressively generated answer to the Channel
79
+ * named by the surface.
80
+ *
81
+ * A Channel that can stream consumes the stream itself. A Channel that
82
+ * cannot never learns it was a stream, because the Host collects the answer
83
+ * and calls `deliver` once.
84
+ */
85
+ stream(
86
+ surface: ChannelMessageSurface,
87
+ chunks: ChannelChunkSource,
88
+ options?: ChannelStreamOptions
89
+ ): Promise<DeliveryResult>;
90
+ /** Return the identity's configured Channel destination, when supported. */
91
+ contactSurface(identity: ChannelIdentity): ChannelMessageSurface | null;
92
+ }
93
+ //#endregion
94
+ export {
95
+ GatewayAgent as i,
96
+ ChannelGatewayOptions as n,
97
+ ChannelRouteEvent as r,
98
+ ChannelGateway as t
99
+ };
100
+ //# sourceMappingURL=gateway-BDC07gYO.d.ts.map