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,317 @@
1
+ //#region src/harness/ai-sdk/turns.ts
2
+ function ownerOf(toolName, { tools, owner }) {
3
+ const tool = tools && Object.hasOwn(tools, toolName) ? tools[toolName] : void 0;
4
+ return tool && !tool.execute ? owner : void 0;
5
+ }
6
+ const json = (value) => value ?? null;
7
+ const object = (value) => typeof value === "object" && value !== null ? value : void 0;
8
+ function withMetadata(value, metadata) {
9
+ const providerMetadata = object(metadata);
10
+ return providerMetadata ? {
11
+ ...value,
12
+ providerMetadata
13
+ } : value;
14
+ }
15
+ let warned = false;
16
+ function warnSkipped(type) {
17
+ if (warned) return;
18
+ warned = true;
19
+ console.warn(`Channels skipped an AI SDK part it cannot carry: "${type}"`);
20
+ }
21
+ /**
22
+ * Convert an AI SDK UI message stream into response chunks.
23
+ *
24
+ * An `error` or `abort` chunk makes the iteration throw once the stream
25
+ * ends, so a failed or aborted generation never reads as a finished one, while the stream still
26
+ * runs to its end and its `onEnd` sees the partial message.
27
+ */
28
+ async function* toResponseChunks(stream, options = {}) {
29
+ let error;
30
+ for await (const chunk of stream) {
31
+ if (chunk.type === "error") error ??= new Error(chunk.errorText);
32
+ if (chunk.type === "abort") error ??= /* @__PURE__ */ new Error("The generation was aborted");
33
+ const converted = toResponseChunk(chunk, options);
34
+ if (converted) yield converted;
35
+ }
36
+ if (error) throw error;
37
+ }
38
+ /** Convert one AI SDK UI message chunk into a response chunk, if it has one. */
39
+ function toResponseChunk(chunk, options) {
40
+ switch (chunk.type) {
41
+ case "text-start":
42
+ case "text-end":
43
+ case "reasoning-start":
44
+ case "reasoning-end": return withMetadata({
45
+ type: chunk.type,
46
+ id: chunk.id
47
+ }, chunk.providerMetadata);
48
+ case "text-delta":
49
+ case "reasoning-delta": return {
50
+ type: chunk.type,
51
+ id: chunk.id,
52
+ delta: chunk.delta
53
+ };
54
+ case "tool-input-start": return tool(chunk, options, { type: "tool-input-start" });
55
+ case "tool-input-delta": return {
56
+ type: "tool-input-delta",
57
+ toolCallId: chunk.toolCallId,
58
+ delta: chunk.inputTextDelta
59
+ };
60
+ case "tool-input-available": return withMetadata(tool(chunk, options, {
61
+ type: "tool-input-available",
62
+ input: json(chunk.input)
63
+ }), chunk.providerMetadata);
64
+ case "tool-input-error": {
65
+ const { owner: _owner, ...call } = tool(chunk, {}, {});
66
+ return {
67
+ ...call,
68
+ type: "tool-input-error",
69
+ input: json(chunk.input),
70
+ errorText: chunk.errorText
71
+ };
72
+ }
73
+ case "tool-approval-request": return {
74
+ type: "tool-approval-request",
75
+ toolCallId: chunk.toolCallId,
76
+ approvalId: chunk.approvalId
77
+ };
78
+ case "tool-output-available": return {
79
+ type: "tool-output-available",
80
+ toolCallId: chunk.toolCallId,
81
+ output: json(chunk.output),
82
+ ...chunk.preliminary && { preliminary: true },
83
+ ...chunk.providerExecuted && { providerExecuted: true }
84
+ };
85
+ case "tool-output-error": return {
86
+ type: "tool-output-error",
87
+ toolCallId: chunk.toolCallId,
88
+ errorText: chunk.errorText,
89
+ ...chunk.providerExecuted && { providerExecuted: true }
90
+ };
91
+ case "tool-output-denied": return {
92
+ type: "tool-output-denied",
93
+ toolCallId: chunk.toolCallId
94
+ };
95
+ case "source-url":
96
+ case "source-document":
97
+ case "file": {
98
+ const { providerMetadata, ...part } = chunk;
99
+ return withMetadata(part, providerMetadata);
100
+ }
101
+ case "start":
102
+ case "finish": return chunk.messageMetadata === void 0 ? void 0 : metadata(chunk.messageMetadata);
103
+ case "message-metadata": return metadata(chunk.messageMetadata);
104
+ case "start-step":
105
+ case "finish-step":
106
+ case "tool-approval-response":
107
+ case "error":
108
+ case "abort": return;
109
+ default:
110
+ if (chunk.type.startsWith("data-") && "data" in chunk) return {
111
+ type: "data",
112
+ name: chunk.type.slice(5),
113
+ ...chunk.id !== void 0 && { id: chunk.id },
114
+ data: json(chunk.data),
115
+ ...chunk.transient && { transient: true }
116
+ };
117
+ warnSkipped(chunk.type);
118
+ return;
119
+ }
120
+ }
121
+ function tool(chunk, options, rest) {
122
+ const owner = ownerOf(chunk.toolName, options);
123
+ return {
124
+ toolCallId: chunk.toolCallId,
125
+ toolName: chunk.toolName,
126
+ ...owner !== void 0 && { owner },
127
+ ...chunk.providerExecuted && { providerExecuted: true },
128
+ ...chunk.dynamic && { dynamic: true },
129
+ ...chunk.title !== void 0 && { title: chunk.title },
130
+ ...rest
131
+ };
132
+ }
133
+ function metadata(value) {
134
+ const converted = object(value);
135
+ return converted ? {
136
+ type: "metadata",
137
+ metadata: converted
138
+ } : void 0;
139
+ }
140
+ /**
141
+ * Convert a response chunk into an AI SDK UI message chunk. Fields that only
142
+ * Channels has, such as a tool call's `owner`, are dropped.
143
+ */
144
+ function toUIMessageChunk(chunk) {
145
+ switch (chunk.type) {
146
+ case "tool-input-start":
147
+ case "tool-input-available": {
148
+ const { owner: _owner, ...rest } = chunk;
149
+ return rest;
150
+ }
151
+ case "tool-input-delta": return {
152
+ type: "tool-input-delta",
153
+ toolCallId: chunk.toolCallId,
154
+ inputTextDelta: chunk.delta
155
+ };
156
+ case "data": {
157
+ const { name, ...rest } = chunk;
158
+ return {
159
+ ...rest,
160
+ type: `data-${name}`
161
+ };
162
+ }
163
+ case "metadata": return {
164
+ type: "message-metadata",
165
+ messageMetadata: chunk.metadata
166
+ };
167
+ default: return chunk;
168
+ }
169
+ }
170
+ /** Convert a saved AI SDK UI message into a transcript message. */
171
+ function toTranscriptMessage(message, options = {}) {
172
+ const metadata = object(message.metadata);
173
+ return {
174
+ id: message.id,
175
+ role: message.role,
176
+ parts: message.parts.flatMap((part) => {
177
+ const converted = toMessagePart(part, options);
178
+ return converted ? [converted] : [];
179
+ }),
180
+ ...metadata && { metadata }
181
+ };
182
+ }
183
+ function toMessagePart(part, options) {
184
+ switch (part.type) {
185
+ case "text":
186
+ case "reasoning": return withMetadata({
187
+ type: part.type,
188
+ text: part.text
189
+ }, part.providerMetadata);
190
+ case "file":
191
+ case "source-url":
192
+ case "source-document": {
193
+ const { providerMetadata, ...rest } = part;
194
+ if ("providerReference" in rest) delete rest.providerReference;
195
+ return withMetadata(rest, providerMetadata);
196
+ }
197
+ case "step-start": return;
198
+ case "dynamic-tool": return toToolPart(part, part.toolName, true, options);
199
+ default:
200
+ if (part.type.startsWith("tool-") && "toolCallId" in part) return toToolPart(part, part.type.slice(5), false, options);
201
+ if (part.type.startsWith("data-") && "data" in part) return {
202
+ type: "data",
203
+ name: part.type.slice(5),
204
+ ...part.id !== void 0 && { id: part.id },
205
+ data: json(part.data)
206
+ };
207
+ warnSkipped(part.type);
208
+ return;
209
+ }
210
+ }
211
+ function toToolPart(part, toolName, dynamic, options) {
212
+ const owner = ownerOf(toolName, options);
213
+ return withMetadata({
214
+ type: "tool",
215
+ toolCallId: part.toolCallId,
216
+ toolName,
217
+ state: part.state,
218
+ ...part.input !== void 0 && { input: json(part.input) },
219
+ ...part.state === "output-available" && {
220
+ output: json(part.output),
221
+ ...part.preliminary && { preliminary: true }
222
+ },
223
+ ...part.state === "output-error" && { errorText: part.errorText },
224
+ ...part.approval && { approval: {
225
+ id: part.approval.id,
226
+ ...part.approval.approved !== void 0 && { approved: part.approval.approved },
227
+ ...part.approval.reason !== void 0 && { reason: part.approval.reason }
228
+ } },
229
+ ...owner !== void 0 && { owner },
230
+ ...part.providerExecuted && { providerExecuted: true },
231
+ ...dynamic && { dynamic: true },
232
+ ...part.title !== void 0 && { title: part.title }
233
+ }, part.callProviderMetadata);
234
+ }
235
+ /** Convert a transcript message into an AI SDK UI message. */
236
+ function toUIMessage(message) {
237
+ return {
238
+ id: message.id,
239
+ role: message.role,
240
+ parts: message.parts.map(toUIPart),
241
+ ...message.metadata && { metadata: message.metadata }
242
+ };
243
+ }
244
+ function toUIPart(part) {
245
+ switch (part.type) {
246
+ case "data": {
247
+ const { name, ...rest } = part;
248
+ return {
249
+ ...rest,
250
+ type: `data-${name}`
251
+ };
252
+ }
253
+ case "tool": {
254
+ const { type: _type, toolName, dynamic, owner: _owner, providerMetadata, ...rest } = part;
255
+ const call = {
256
+ ...rest,
257
+ ...providerMetadata && { callProviderMetadata: providerMetadata }
258
+ };
259
+ return dynamic ? {
260
+ ...call,
261
+ type: "dynamic-tool",
262
+ toolName
263
+ } : {
264
+ ...call,
265
+ type: `tool-${toolName}`
266
+ };
267
+ }
268
+ default: return part;
269
+ }
270
+ }
271
+ /** Whether the message has a tool call waiting for a result or an approval. */
272
+ function awaitsInput(message) {
273
+ return message.parts.some((part) => "toolCallId" in part && (part.state === "input-available" || part.state === "approval-requested"));
274
+ }
275
+ /**
276
+ * Record a tool result or approval response on the tool call it answers.
277
+ * Returns the updated message, or undefined when no call is waiting for it,
278
+ * so the first answer wins.
279
+ */
280
+ function answerToolCall(messages, event) {
281
+ for (const message of messages) {
282
+ const index = message.parts.findIndex((part) => answers(part, event));
283
+ if (index === -1) continue;
284
+ const parts = [...message.parts];
285
+ const part = parts[index];
286
+ parts[index] = event.type === "approval-response" ? {
287
+ ...part,
288
+ state: event.approved ? "approval-responded" : "output-denied",
289
+ approval: {
290
+ id: event.approvalId,
291
+ approved: event.approved,
292
+ ...event.reason !== void 0 && { reason: event.reason }
293
+ }
294
+ } : event.type === "tool-result" && event.result.ok ? {
295
+ ...part,
296
+ state: "output-available",
297
+ output: event.result.output
298
+ } : {
299
+ ...part,
300
+ state: "output-error",
301
+ errorText: event.type === "tool-result" && !event.result.ok ? event.result.errorText ?? "" : ""
302
+ };
303
+ return {
304
+ ...message,
305
+ parts
306
+ };
307
+ }
308
+ }
309
+ function answers(part, event) {
310
+ if (!("toolCallId" in part)) return false;
311
+ if (event.type === "tool-result") return part.toolCallId === event.toolCallId && (part.state === "input-available" || part.state === "approval-responded");
312
+ return event.type === "approval-response" && part.state === "approval-requested" && part.approval.id === event.approvalId;
313
+ }
314
+ //#endregion
315
+ export { toTranscriptMessage as a, toResponseChunks as i, awaitsInput as n, toUIMessage as o, toResponseChunk as r, toUIMessageChunk as s, answerToolCall as t };
316
+
317
+ //# sourceMappingURL=turns-DCV3ycDl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turns-DCV3ycDl.js","names":[],"sources":["../src/harness/ai-sdk/turns.ts"],"sourcesContent":["import type { ToolSet, UIMessage, UIMessageChunk } from \"ai\";\nimport type {\n InboundEvent,\n Json,\n JsonObject,\n MessagePart,\n ResponseChunk,\n ToolPart,\n TranscriptMessage\n} from \"../../experimental/channels/protocol\";\n\nexport type AiSdkConversionOptions = {\n /** The agent's tools. Those without `execute` run on a client. */\n tools?: ToolSet;\n /** Id of the participant whose client runs this message's client tools. */\n owner?: string;\n};\n\nfunction ownerOf(\n toolName: string,\n { tools, owner }: AiSdkConversionOptions\n): string | undefined {\n const tool =\n tools && Object.hasOwn(tools, toolName) ? tools[toolName] : undefined;\n return tool && !tool.execute ? owner : undefined;\n}\n\ntype UIPart = UIMessage[\"parts\"][number];\n\n// SAFETY: AI SDK values that reach these casts are JSON: tool inputs are\n// parsed JSON, and outputs, metadata and data are JSON-serializable by the\n// AI SDK's own contract for UI messages.\nconst json = (value: unknown): Json => (value ?? null) as Json;\nconst object = (value: unknown): JsonObject | undefined =>\n typeof value === \"object\" && value !== null\n ? (value as JsonObject)\n : undefined;\n\nfunction withMetadata<T extends object>(\n value: T,\n metadata: unknown\n): T & { providerMetadata?: JsonObject } {\n const providerMetadata = object(metadata);\n return providerMetadata ? { ...value, providerMetadata } : value;\n}\n\nlet warned = false;\nfunction warnSkipped(type: string): void {\n if (warned) return;\n warned = true;\n console.warn(`Channels skipped an AI SDK part it cannot carry: \"${type}\"`);\n}\n\n/**\n * Convert an AI SDK UI message stream into response chunks.\n *\n * An `error` or `abort` chunk makes the iteration throw once the stream\n * ends, so a failed or aborted generation never reads as a finished one, while the stream still\n * runs to its end and its `onEnd` sees the partial message.\n */\nexport async function* toResponseChunks(\n stream: AsyncIterable<UIMessageChunk>,\n options: AiSdkConversionOptions = {}\n): AsyncGenerator<ResponseChunk> {\n let error: Error | undefined;\n for await (const chunk of stream) {\n if (chunk.type === \"error\") error ??= new Error(chunk.errorText);\n if (chunk.type === \"abort\")\n error ??= new Error(\"The generation was aborted\");\n const converted = toResponseChunk(chunk, options);\n if (converted) yield converted;\n }\n if (error) throw error;\n}\n\n/** Convert one AI SDK UI message chunk into a response chunk, if it has one. */\nexport function toResponseChunk(\n chunk: UIMessageChunk,\n options: AiSdkConversionOptions\n): ResponseChunk | undefined {\n switch (chunk.type) {\n case \"text-start\":\n case \"text-end\":\n case \"reasoning-start\":\n case \"reasoning-end\":\n return withMetadata(\n { type: chunk.type, id: chunk.id },\n chunk.providerMetadata\n );\n case \"text-delta\":\n case \"reasoning-delta\":\n return { type: chunk.type, id: chunk.id, delta: chunk.delta };\n case \"tool-input-start\":\n return tool(chunk, options, { type: \"tool-input-start\" as const });\n case \"tool-input-delta\":\n return {\n type: \"tool-input-delta\",\n toolCallId: chunk.toolCallId,\n delta: chunk.inputTextDelta\n };\n case \"tool-input-available\":\n return withMetadata(\n tool(chunk, options, {\n type: \"tool-input-available\" as const,\n input: json(chunk.input)\n }),\n chunk.providerMetadata\n );\n case \"tool-input-error\": {\n const { owner: _owner, ...call } = tool(chunk, {}, {});\n return {\n ...call,\n type: \"tool-input-error\",\n input: json(chunk.input),\n errorText: chunk.errorText\n };\n }\n case \"tool-approval-request\":\n return {\n type: \"tool-approval-request\",\n toolCallId: chunk.toolCallId,\n approvalId: chunk.approvalId\n };\n case \"tool-output-available\":\n return {\n type: \"tool-output-available\",\n toolCallId: chunk.toolCallId,\n output: json(chunk.output),\n ...(chunk.preliminary && { preliminary: true }),\n ...(chunk.providerExecuted && { providerExecuted: true })\n };\n case \"tool-output-error\":\n return {\n type: \"tool-output-error\",\n toolCallId: chunk.toolCallId,\n errorText: chunk.errorText,\n ...(chunk.providerExecuted && { providerExecuted: true })\n };\n case \"tool-output-denied\":\n return { type: \"tool-output-denied\", toolCallId: chunk.toolCallId };\n case \"source-url\":\n case \"source-document\":\n case \"file\": {\n const { providerMetadata, ...part } = chunk;\n // SAFETY: these chunk shapes match the Channels parts field for field.\n return withMetadata(part, providerMetadata) as ResponseChunk;\n }\n case \"start\":\n case \"finish\":\n return chunk.messageMetadata === undefined\n ? undefined\n : metadata(chunk.messageMetadata);\n case \"message-metadata\":\n return metadata(chunk.messageMetadata);\n case \"start-step\":\n case \"finish-step\":\n case \"tool-approval-response\":\n case \"error\":\n case \"abort\":\n return undefined;\n default:\n if (chunk.type.startsWith(\"data-\") && \"data\" in chunk) {\n return {\n type: \"data\",\n name: chunk.type.slice(\"data-\".length),\n ...(chunk.id !== undefined && { id: chunk.id }),\n data: json(chunk.data),\n ...(chunk.transient && { transient: true })\n };\n }\n warnSkipped(chunk.type);\n return undefined;\n }\n}\n\nfunction tool<T extends object>(\n chunk: {\n toolCallId: string;\n toolName: string;\n providerExecuted?: boolean;\n dynamic?: boolean;\n title?: string;\n },\n options: AiSdkConversionOptions,\n rest: T\n) {\n const owner = ownerOf(chunk.toolName, options);\n return {\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n ...(owner !== undefined && { owner }),\n ...(chunk.providerExecuted && { providerExecuted: true }),\n ...(chunk.dynamic && { dynamic: true }),\n ...(chunk.title !== undefined && { title: chunk.title }),\n ...rest\n };\n}\n\nfunction metadata(value: unknown): ResponseChunk | undefined {\n const converted = object(value);\n return converted ? { type: \"metadata\", metadata: converted } : undefined;\n}\n\n/**\n * Convert a response chunk into an AI SDK UI message chunk. Fields that only\n * Channels has, such as a tool call's `owner`, are dropped.\n */\nexport function toUIMessageChunk(chunk: ResponseChunk): UIMessageChunk {\n switch (chunk.type) {\n case \"tool-input-start\":\n case \"tool-input-available\": {\n const { owner: _owner, ...rest } = chunk;\n // SAFETY: as below, once the Channels-only owner is gone.\n return rest as UIMessageChunk;\n }\n case \"tool-input-delta\":\n return {\n type: \"tool-input-delta\",\n toolCallId: chunk.toolCallId,\n inputTextDelta: chunk.delta\n };\n case \"data\": {\n const { name, ...rest } = chunk;\n return { ...rest, type: `data-${name}` };\n }\n case \"metadata\":\n return { type: \"message-metadata\", messageMetadata: chunk.metadata };\n default:\n // SAFETY: the remaining chunks match their AI SDK shapes field for\n // field.\n return chunk as UIMessageChunk;\n }\n}\n\n/** Convert a saved AI SDK UI message into a transcript message. */\nexport function toTranscriptMessage(\n message: UIMessage,\n options: AiSdkConversionOptions = {}\n): TranscriptMessage {\n const metadata = object(message.metadata);\n return {\n id: message.id,\n role: message.role,\n parts: message.parts.flatMap((part) => {\n const converted = toMessagePart(part, options);\n return converted ? [converted] : [];\n }),\n ...(metadata && { metadata })\n };\n}\n\nfunction toMessagePart(\n part: UIPart,\n options: AiSdkConversionOptions\n): MessagePart | undefined {\n switch (part.type) {\n case \"text\":\n case \"reasoning\":\n return withMetadata(\n { type: part.type, text: part.text },\n part.providerMetadata\n );\n case \"file\":\n case \"source-url\":\n case \"source-document\": {\n const { providerMetadata, ...rest } = part;\n if (\"providerReference\" in rest) delete rest.providerReference;\n // SAFETY: these part shapes match the Channels parts field for field.\n return withMetadata(rest, providerMetadata) as MessagePart;\n }\n case \"step-start\":\n return undefined;\n case \"dynamic-tool\":\n return toToolPart(part, part.toolName, true, options);\n default:\n if (part.type.startsWith(\"tool-\") && \"toolCallId\" in part) {\n return toToolPart(\n part,\n part.type.slice(\"tool-\".length),\n false,\n options\n );\n }\n if (part.type.startsWith(\"data-\") && \"data\" in part) {\n return {\n type: \"data\",\n name: part.type.slice(\"data-\".length),\n ...(part.id !== undefined && { id: part.id }),\n data: json(part.data)\n };\n }\n warnSkipped(part.type);\n return undefined;\n }\n}\n\ntype UIToolPart = Extract<UIPart, { toolCallId: string }>;\n\nfunction toToolPart(\n part: UIToolPart,\n toolName: string,\n dynamic: boolean,\n options: AiSdkConversionOptions\n): ToolPart {\n const owner = ownerOf(toolName, options);\n return withMetadata(\n {\n type: \"tool\",\n toolCallId: part.toolCallId,\n toolName,\n state: part.state,\n ...(part.input !== undefined && { input: json(part.input) }),\n ...(part.state === \"output-available\" && {\n output: json(part.output),\n ...(part.preliminary && { preliminary: true })\n }),\n ...(part.state === \"output-error\" && { errorText: part.errorText }),\n ...(part.approval && {\n approval: {\n id: part.approval.id,\n ...(part.approval.approved !== undefined && {\n approved: part.approval.approved\n }),\n ...(part.approval.reason !== undefined && {\n reason: part.approval.reason\n })\n }\n }),\n ...(owner !== undefined && { owner }),\n ...(part.providerExecuted && { providerExecuted: true }),\n ...(dynamic && { dynamic: true }),\n ...(part.title !== undefined && { title: part.title })\n } satisfies ToolPart,\n part.callProviderMetadata\n );\n}\n\n/** Convert a transcript message into an AI SDK UI message. */\nexport function toUIMessage(message: TranscriptMessage): UIMessage {\n return {\n id: message.id,\n role: message.role,\n parts: message.parts.map(toUIPart),\n ...(message.metadata && { metadata: message.metadata })\n };\n}\n\nfunction toUIPart(part: MessagePart): UIPart {\n switch (part.type) {\n case \"data\": {\n const { name, ...rest } = part;\n return { ...rest, type: `data-${name}` };\n }\n case \"tool\": {\n const {\n type: _type,\n toolName,\n dynamic,\n owner: _owner,\n providerMetadata,\n ...rest\n } = part;\n const call = {\n ...rest,\n ...(providerMetadata && { callProviderMetadata: providerMetadata })\n };\n // SAFETY: the state and its fields were produced together by\n // toToolPart, or by an agent following the same ToolState rules.\n return (\n dynamic\n ? { ...call, type: \"dynamic-tool\", toolName }\n : { ...call, type: `tool-${toolName}` }\n ) as UIPart;\n }\n default:\n // SAFETY: the remaining parts match their AI SDK shapes field for field.\n return part as UIPart;\n }\n}\n\n/** Whether the message has a tool call waiting for a result or an approval. */\nexport function awaitsInput(message: UIMessage): boolean {\n return message.parts.some(\n (part) =>\n \"toolCallId\" in part &&\n (part.state === \"input-available\" || part.state === \"approval-requested\")\n );\n}\n\n/** A tool result or approval response, as an inbound event carries it. */\nexport type ToolCallAnswer =\n | Pick<\n Extract<InboundEvent, { type: \"tool-result\" }>,\n \"type\" | \"toolCallId\" | \"result\"\n >\n | Pick<\n Extract<InboundEvent, { type: \"approval-response\" }>,\n \"type\" | \"approvalId\" | \"approved\" | \"reason\"\n >;\n\n/**\n * Record a tool result or approval response on the tool call it answers.\n * Returns the updated message, or undefined when no call is waiting for it,\n * so the first answer wins.\n */\nexport function answerToolCall(\n messages: readonly UIMessage[],\n event: ToolCallAnswer\n): UIMessage | undefined {\n for (const message of messages) {\n const index = message.parts.findIndex((part) => answers(part, event));\n if (index === -1) continue;\n const parts = [...message.parts];\n const part = parts[index] as UIToolPart;\n // SAFETY: the new state is set with exactly the fields it requires.\n parts[index] = (\n event.type === \"approval-response\"\n ? {\n ...part,\n // As the AI SDK records them: a rejection ends the call.\n state: event.approved ? \"approval-responded\" : \"output-denied\",\n approval: {\n id: event.approvalId,\n approved: event.approved,\n ...(event.reason !== undefined && { reason: event.reason })\n }\n }\n : event.type === \"tool-result\" && event.result.ok\n ? { ...part, state: \"output-available\", output: event.result.output }\n : {\n ...part,\n state: \"output-error\",\n errorText:\n event.type === \"tool-result\" && !event.result.ok\n ? (event.result.errorText ?? \"\")\n : \"\"\n }\n ) as UIPart;\n return { ...message, parts };\n }\n return undefined;\n}\n\nfunction answers(part: UIPart, event: ToolCallAnswer): boolean {\n if (!(\"toolCallId\" in part)) return false;\n if (event.type === \"tool-result\") {\n return (\n part.toolCallId === event.toolCallId &&\n // An approved client tool is answered after its approval.\n (part.state === \"input-available\" || part.state === \"approval-responded\")\n );\n }\n return (\n event.type === \"approval-response\" &&\n part.state === \"approval-requested\" &&\n part.approval.id === event.approvalId\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../classPrivateFieldGet2-DZBYAB34.js";
2
2
  import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
- import { VOICE_PROTOCOL_VERSION } from "./types.js";
4
3
  import { toVoiceError } from "./errors.js";
5
4
  import { t as ClientDiagnostics } from "../diagnostics-C4jcz3VK.js";
5
+ import { VOICE_PROTOCOL_VERSION } from "./types.js";
6
6
  import { PartySocket } from "partysocket";
7
7
  //#region src/voice/client.ts
8
8
  function camelCaseToKebabCase(str) {
@@ -1,5 +1,5 @@
1
- import { x as Connection } from "../capability-runner-DBAnGr6L.js";
2
- import { c as Agent } from "../agent-routing-0DR0Tk2v.js";
1
+ import { x as Connection } from "../capability-runner-O5VbQzqg.js";
2
+ import { c as Agent } from "../agent-routing-Bhdbvf7s.js";
3
3
  import {
4
4
  C as VoiceTransport,
5
5
  D as VoiceTurnSource,
@@ -1,8 +1,8 @@
1
1
  import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../classPrivateFieldGet2-DZBYAB34.js";
2
2
  import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
- import { VOICE_PROTOCOL_VERSION } from "./types.js";
4
3
  import { logVoiceError, toVoiceError, voiceErrorMessage } from "./errors.js";
5
4
  import { n as ServerDiagnostics } from "../diagnostics-C4jcz3VK.js";
5
+ import { VOICE_PROTOCOL_VERSION } from "./types.js";
6
6
  import { n as iterateTextEvents, r as SentenceChunker, t as iterateText } from "../text-stream-CpdiKrJB.js";
7
7
  import { addSFUTracks, createSFUSession, createSFUWebSocketAdapter, decodeVarint, downsample48kStereoTo16kMono, encodePayloadToProtobuf, encodeVarint, extractPayloadFromProtobuf, renegotiateSFUSession, sfuFetch, upsample16kMonoTo48kStereo } from "./sfu.js";
8
8
  import { WorkersAIFluxSTT, WorkersAINova3STT, WorkersAITTS } from "./workers-ai.js";
@@ -0,0 +1,58 @@
1
+ import {
2
+ C as WebSearchResponse,
3
+ D as renderWebSearchResults,
4
+ E as WebSearchToolOutput,
5
+ S as WEB_SEARCH_TOOL_NAME,
6
+ T as WebSearchToolInput,
7
+ _ as DEFAULT_WEB_SEARCH_LIMIT,
8
+ a as AIWebSearchOptions,
9
+ b as RenderWebSearchResultsOptions,
10
+ c as WebSearchError,
11
+ d as WebSearchProvider,
12
+ f as WebSearchRequest,
13
+ g as DEFAULT_WEB_SEARCH_DESCRIPTION_CHARS,
14
+ h as createHTTPWebSearch,
15
+ i as WebSearchToolSourceOptions,
16
+ l as WebSearchErrorCode,
17
+ m as createAIWebSearch,
18
+ n as WebSearchToolBindingOptions,
19
+ o as HTTPWebSearchOptions,
20
+ p as WebSearchSource,
21
+ r as WebSearchToolOptions,
22
+ s as WebSearchCallOptions,
23
+ t as DEFAULT_WEB_SEARCH_TIMEOUT_MS,
24
+ u as WebSearchGatewayOptions,
25
+ v as MAX_WEB_SEARCH_LIMIT,
26
+ w as WebSearchResult,
27
+ x as WEB_SEARCH_TOOL_DESCRIPTION,
28
+ y as MAX_WEB_SEARCH_QUERY_LENGTH
29
+ } from "../tool-BPJEbwaX.js";
30
+ export {
31
+ type AIWebSearchOptions,
32
+ DEFAULT_WEB_SEARCH_DESCRIPTION_CHARS,
33
+ DEFAULT_WEB_SEARCH_LIMIT,
34
+ DEFAULT_WEB_SEARCH_TIMEOUT_MS,
35
+ type HTTPWebSearchOptions,
36
+ MAX_WEB_SEARCH_LIMIT,
37
+ MAX_WEB_SEARCH_QUERY_LENGTH,
38
+ type RenderWebSearchResultsOptions,
39
+ WEB_SEARCH_TOOL_DESCRIPTION,
40
+ WEB_SEARCH_TOOL_NAME,
41
+ type WebSearchCallOptions,
42
+ WebSearchError,
43
+ type WebSearchErrorCode,
44
+ type WebSearchGatewayOptions,
45
+ type WebSearchProvider,
46
+ type WebSearchRequest,
47
+ type WebSearchResponse,
48
+ type WebSearchResult,
49
+ type WebSearchSource,
50
+ type WebSearchToolBindingOptions,
51
+ type WebSearchToolInput,
52
+ type WebSearchToolOptions,
53
+ type WebSearchToolOutput,
54
+ type WebSearchToolSourceOptions,
55
+ createAIWebSearch,
56
+ createHTTPWebSearch,
57
+ renderWebSearchResults
58
+ };
@@ -0,0 +1,2 @@
1
+ import { a as createAIWebSearch, c as DEFAULT_WEB_SEARCH_LIMIT, d as WEB_SEARCH_TOOL_DESCRIPTION, f as WEB_SEARCH_TOOL_NAME, i as WebSearchError, l as MAX_WEB_SEARCH_LIMIT, o as createHTTPWebSearch, p as renderWebSearchResults, s as DEFAULT_WEB_SEARCH_DESCRIPTION_CHARS, t as DEFAULT_WEB_SEARCH_TIMEOUT_MS, u as MAX_WEB_SEARCH_QUERY_LENGTH } from "../tool-3PA8xjB_.js";
2
+ export { DEFAULT_WEB_SEARCH_DESCRIPTION_CHARS, DEFAULT_WEB_SEARCH_LIMIT, DEFAULT_WEB_SEARCH_TIMEOUT_MS, MAX_WEB_SEARCH_LIMIT, MAX_WEB_SEARCH_QUERY_LENGTH, WEB_SEARCH_TOOL_DESCRIPTION, WEB_SEARCH_TOOL_NAME, WebSearchError, createAIWebSearch, createHTTPWebSearch, renderWebSearchResults };
@@ -0,0 +1,77 @@
1
+ import {
2
+ C as WebSearchResponse,
3
+ E as WebSearchToolOutput,
4
+ T as WebSearchToolInput,
5
+ c as WebSearchError,
6
+ d as WebSearchProvider,
7
+ l as WebSearchErrorCode,
8
+ p as WebSearchSource,
9
+ r as WebSearchToolOptions,
10
+ w as WebSearchResult
11
+ } from "../../tool-BPJEbwaX.js";
12
+ import { FlexibleSchema } from "ai";
13
+
14
+ //#region src/websearch/tools/ai-sdk.d.ts
15
+ /**
16
+ * The part of the AI SDK's tool execution options the tool reads. Spelled
17
+ * out rather than imported so it fits every supported `ai` major.
18
+ */
19
+ interface WebSearchToolExecuteOptions {
20
+ abortSignal?: AbortSignal;
21
+ }
22
+ /**
23
+ * The AI SDK tool {@link webSearchTool} returns. Assignable to the AI SDK's
24
+ * `Tool`; `execute` and `toModelOutput` are always present.
25
+ */
26
+ interface WebSearchTool {
27
+ description: string;
28
+ inputSchema: FlexibleSchema<WebSearchToolInput>;
29
+ execute(
30
+ input: WebSearchToolInput,
31
+ options: WebSearchToolExecuteOptions
32
+ ): Promise<WebSearchToolOutput>;
33
+ toModelOutput(options: { output: WebSearchToolOutput }): {
34
+ type: "text";
35
+ value: string;
36
+ };
37
+ }
38
+ /**
39
+ * Create an AI SDK tool that searches the web through Cloudflare's Web
40
+ * Search API. The host gets the full response as the tool's output (whole
41
+ * descriptions, provider metadata); the model gets a trimmed text rendering
42
+ * via `toModelOutput`. A failed search throws a `WebSearchError`, which the
43
+ * AI SDK reports to the model as a tool error: its `message` is written for
44
+ * the model, and its `cause` is the source's error with the API's detail.
45
+ *
46
+ * `toModelOutput` only applies to earlier turns when the tools are passed to
47
+ * `convertToModelMessages(messages, { tools })`; otherwise the AI SDK sends
48
+ * the full response back to the model as JSON. `AiSdkHarness` passes them.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { webSearchTool } from "agents/websearch/ai-sdk";
53
+ *
54
+ * const result = streamText({
55
+ * model,
56
+ * tools: { web_search: webSearchTool({ binding: env.AI }) },
57
+ * messages
58
+ * });
59
+ * ```
60
+ */
61
+ declare function webSearchTool(options: WebSearchToolOptions): WebSearchTool;
62
+ //#endregion
63
+ export {
64
+ WebSearchError,
65
+ type WebSearchErrorCode,
66
+ type WebSearchProvider,
67
+ type WebSearchResponse,
68
+ type WebSearchResult,
69
+ type WebSearchSource,
70
+ WebSearchTool,
71
+ WebSearchToolExecuteOptions,
72
+ type WebSearchToolInput,
73
+ type WebSearchToolOptions,
74
+ type WebSearchToolOutput,
75
+ webSearchTool
76
+ };
77
+ //# sourceMappingURL=ai-sdk.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
+ //#region src/websearch/tools/ai-sdk.ts
4
+ /**
5
+ * Create an AI SDK tool that searches the web through Cloudflare's Web
6
+ * Search API. The host gets the full response as the tool's output (whole
7
+ * descriptions, provider metadata); the model gets a trimmed text rendering
8
+ * via `toModelOutput`. A failed search throws a `WebSearchError`, which the
9
+ * AI SDK reports to the model as a tool error: its `message` is written for
10
+ * the model, and its `cause` is the source's error with the API's detail.
11
+ *
12
+ * `toModelOutput` only applies to earlier turns when the tools are passed to
13
+ * `convertToModelMessages(messages, { tools })`; otherwise the AI SDK sends
14
+ * the full response back to the model as JSON. `AiSdkHarness` passes them.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { webSearchTool } from "agents/websearch/ai-sdk";
19
+ *
20
+ * const result = streamText({
21
+ * model,
22
+ * tools: { web_search: webSearchTool({ binding: env.AI }) },
23
+ * messages
24
+ * });
25
+ * ```
26
+ */
27
+ function webSearchTool(options) {
28
+ const core = createWebSearchToolCore(options);
29
+ return {
30
+ description: core.description,
31
+ inputSchema: webSearchInputSchema(core.limit),
32
+ async execute(input, { abortSignal }) {
33
+ const run = await core.run(input, { signal: abortSignal });
34
+ if (!run.ok) throw toolFailure(run);
35
+ return run.output;
36
+ },
37
+ toModelOutput: ({ output }) => ({
38
+ type: "text",
39
+ value: core.render(output)
40
+ })
41
+ };
42
+ }
43
+ //#endregion
44
+ export { WebSearchError, webSearchTool };
45
+
46
+ //# sourceMappingURL=ai-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.js","names":[],"sources":["../../../src/websearch/tools/ai-sdk.ts"],"sourcesContent":["/**\n * `agents/websearch/ai-sdk` — the `web_search` tool for the AI SDK.\n *\n * @beta\n */\nimport type { FlexibleSchema } from \"ai\";\nimport type { WebSearchToolInput, WebSearchToolOutput } 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\n/**\n * The part of the AI SDK's tool execution options the tool reads. Spelled\n * out rather than imported so it fits every supported `ai` major.\n */\nexport interface WebSearchToolExecuteOptions {\n abortSignal?: AbortSignal;\n}\n\n/**\n * The AI SDK tool {@link webSearchTool} returns. Assignable to the AI SDK's\n * `Tool`; `execute` and `toModelOutput` are always present.\n */\nexport interface WebSearchTool {\n description: string;\n inputSchema: FlexibleSchema<WebSearchToolInput>;\n execute(\n input: WebSearchToolInput,\n options: WebSearchToolExecuteOptions\n ): Promise<WebSearchToolOutput>;\n toModelOutput(options: { output: WebSearchToolOutput }): {\n type: \"text\";\n value: string;\n };\n}\n\n/**\n * Create an AI SDK tool that searches the web through Cloudflare's Web\n * Search API. The host gets the full response as the tool's output (whole\n * descriptions, provider metadata); the model gets a trimmed text rendering\n * via `toModelOutput`. A failed search throws a `WebSearchError`, which the\n * AI SDK reports to the model as a tool error: its `message` is written for\n * the model, and its `cause` is the source's error with the API's detail.\n *\n * `toModelOutput` only applies to earlier turns when the tools are passed to\n * `convertToModelMessages(messages, { tools })`; otherwise the AI SDK sends\n * the full response back to the model as JSON. `AiSdkHarness` passes them.\n *\n * @example\n * ```ts\n * import { webSearchTool } from \"agents/websearch/ai-sdk\";\n *\n * const result = streamText({\n * model,\n * tools: { web_search: webSearchTool({ binding: env.AI }) },\n * messages\n * });\n * ```\n */\nexport function webSearchTool(options: WebSearchToolOptions): WebSearchTool {\n const core = createWebSearchToolCore(options);\n return {\n description: core.description,\n inputSchema: webSearchInputSchema(core.limit),\n async execute(input, { abortSignal }) {\n const run = await core.run(input, { signal: abortSignal });\n if (!run.ok) throw toolFailure(run);\n return run.output;\n },\n toModelOutput: ({ output }) => ({\n type: \"text\",\n value: core.render(output)\n })\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,SAAgB,cAAc,SAA8C;CAC1E,MAAM,OAAO,wBAAwB,OAAO;CAC5C,OAAO;EACL,aAAa,KAAK;EAClB,aAAa,qBAAqB,KAAK,KAAK;EAC5C,MAAM,QAAQ,OAAO,EAAE,eAAe;GACpC,MAAM,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,QAAQ,YAAY,CAAC;GACzD,IAAI,CAAC,IAAI,IAAI,MAAM,YAAY,GAAG;GAClC,OAAO,IAAI;EACb;EACA,gBAAgB,EAAE,cAAc;GAC9B,MAAM;GACN,OAAO,KAAK,OAAO,MAAM;EAC3B;CACF;AACF"}
@@ -0,0 +1,82 @@
1
+ import {
2
+ C as WebSearchResponse,
3
+ E as WebSearchToolOutput,
4
+ T as WebSearchToolInput,
5
+ c as WebSearchError,
6
+ d as WebSearchProvider,
7
+ l as WebSearchErrorCode,
8
+ p as WebSearchSource,
9
+ r as WebSearchToolOptions,
10
+ w as WebSearchResult
11
+ } from "../../tool-BPJEbwaX.js";
12
+ import { ToolRegistration } from "@earendil-works/pi-durable";
13
+ import { Type } from "@earendil-works/pi-ai";
14
+
15
+ //#region src/websearch/tools/pi.d.ts
16
+ /**
17
+ * The model's input schema. The description tells the model the host's
18
+ * `limit`; a larger value is not rejected (which would cost a validation
19
+ * round trip) but capped by the core. pi already coerces `"5"` to `5`.
20
+ */
21
+ declare function webSearchParameters(maxLimit: number): Type.TObject<{
22
+ query: Type.TString;
23
+ limit: Type.TOptional<Type.TInteger>;
24
+ }>;
25
+ type WebSearchParameters = ReturnType<typeof webSearchParameters>;
26
+ /**
27
+ * Host-side details pi stores with each `web_search` result: the full API
28
+ * response (untrimmed descriptions, provider metadata) or the failure.
29
+ */
30
+ type WebSearchToolDetails =
31
+ | {
32
+ ok: true;
33
+ output: WebSearchToolOutput;
34
+ }
35
+ | {
36
+ ok: false /** The source's error message, with the API's detail. */;
37
+ message: string;
38
+ status: number;
39
+ code: WebSearchErrorCode;
40
+ retryable: boolean;
41
+ requestId?: string;
42
+ };
43
+ /**
44
+ * Create a pi tool that searches the web through Cloudflare's Web Search
45
+ * API. Install it on a registry like any other pi tool.
46
+ *
47
+ * The model chooses the query and (within the host's `limit`) how many
48
+ * results; the host chooses the gateway, provider, and billing. The tool is
49
+ * `replay: "safe"`: a search interrupted mid-call (say, by an eviction) runs
50
+ * again when the session recovers, which is a second billed search.
51
+ * Completed results are stored and not searched again.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { createRegistry } from "@earendil-works/pi-durable";
56
+ * import { webSearchTool } from "agents/websearch/pi";
57
+ *
58
+ * const registry = createRegistry();
59
+ * registry.install({
60
+ * name: "tools",
61
+ * tools: [webSearchTool({ binding: env.AI, provider: "exa" })]
62
+ * });
63
+ * ```
64
+ */
65
+ declare function webSearchTool(
66
+ options: WebSearchToolOptions
67
+ ): ToolRegistration<WebSearchParameters, WebSearchToolDetails>;
68
+ //#endregion
69
+ export {
70
+ WebSearchError,
71
+ type WebSearchErrorCode,
72
+ type WebSearchProvider,
73
+ type WebSearchResponse,
74
+ type WebSearchResult,
75
+ type WebSearchSource,
76
+ WebSearchToolDetails,
77
+ type WebSearchToolInput,
78
+ type WebSearchToolOptions,
79
+ type WebSearchToolOutput,
80
+ webSearchTool
81
+ };
82
+ //# sourceMappingURL=pi.d.ts.map