agents 0.25.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 (238) 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/{harnesses → harness}/pi/index.d.ts +85 -88
  85. package/dist/{harnesses → harness}/pi/index.js +196 -77
  86. package/dist/harness/pi/index.js.map +1 -0
  87. package/dist/harness/store/index.d.ts +24 -0
  88. package/dist/harness/store/index.js +2 -0
  89. package/dist/harness/think/index.d.ts +821 -0
  90. package/dist/harness/think/index.js +2529 -0
  91. package/dist/harness/think/index.js.map +1 -0
  92. package/dist/harness-B6B9S3rb.d.ts +203 -0
  93. package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
  94. package/dist/images-Ce9SCu3X.js.map +1 -0
  95. package/dist/{index-BreL0YrQ.d.ts → index-D0A5tbWu.d.ts} +2 -2
  96. package/dist/index-Ib_4dwOo.d.ts +200 -0
  97. package/dist/index.d.ts +5 -5
  98. package/dist/index.js +2 -2
  99. package/dist/ingress-EFbrS547.js +9 -0
  100. package/dist/ingress-EFbrS547.js.map +1 -0
  101. package/dist/input-schema-DNrpTu49.js +23 -0
  102. package/dist/input-schema-DNrpTu49.js.map +1 -0
  103. package/dist/internal-kmw70xwR.js +46 -0
  104. package/dist/internal-kmw70xwR.js.map +1 -0
  105. package/dist/internal_context.d.ts +1 -1
  106. package/dist/lifecycle/index.d.ts +3 -3
  107. package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
  108. package/dist/mcp/client/do-oauth-client-provider.js +9 -0
  109. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
  110. package/dist/mcp/client/index.d.ts +1 -1
  111. package/dist/mcp/client/index.js +1 -1
  112. package/dist/mcp/client/x402.d.ts +35 -4
  113. package/dist/mcp/client/x402.js +24 -3
  114. package/dist/mcp/client/x402.js.map +1 -1
  115. package/dist/mcp/index.d.ts +1 -1
  116. package/dist/mcp/index.js +2 -2
  117. package/dist/models/ai-sdk/index.d.ts +16 -14
  118. package/dist/models/ai-sdk/index.js +1 -2442
  119. package/dist/models/opencode/index.d.ts +65 -0
  120. package/dist/models/opencode/index.js +285 -0
  121. package/dist/models/opencode/index.js.map +1 -0
  122. package/dist/models/pi-ai/index.d.ts +23 -21
  123. package/dist/models/pi-ai/index.js +7 -6
  124. package/dist/models/pi-ai/index.js.map +1 -1
  125. package/dist/options-pwTNq9z6.d.ts +134 -0
  126. package/dist/protocol-BEgrJYC5.d.ts +331 -0
  127. package/dist/protocol-CukuI73M.d.ts +386 -0
  128. package/dist/protocol-cOklVBBD.js +227 -0
  129. package/dist/protocol-cOklVBBD.js.map +1 -0
  130. package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
  131. package/dist/protocol-eXeJxhgu.js.map +1 -0
  132. package/dist/protocol-y2sSY584.js +148 -0
  133. package/dist/protocol-y2sSY584.js.map +1 -0
  134. package/dist/queue/index.d.ts +1 -1
  135. package/dist/react.d.ts +2 -2
  136. package/dist/routing/index.d.ts +2 -2
  137. package/dist/{scheduler-RdACNXDP.d.ts → scheduler-CrFCnv_J.d.ts} +2 -2
  138. package/dist/schedules/index.d.ts +1 -1
  139. package/dist/serializable.d.ts +1 -1
  140. package/dist/sessions/index.d.ts +11 -434
  141. package/dist/sessions/index.js +1 -2271
  142. package/dist/sessions-B9pNuxdT.js +2272 -0
  143. package/dist/sessions-B9pNuxdT.js.map +1 -0
  144. package/dist/settings-C45hDliX.js +253 -0
  145. package/dist/settings-C45hDliX.js.map +1 -0
  146. package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
  147. package/dist/{src-BZeu-SCD.js → src-DgCbZtIR.js} +4 -4
  148. package/dist/{src-BZeu-SCD.js.map → src-DgCbZtIR.js.map} +1 -1
  149. package/dist/stall-watchdog-BpRF2uwG.js +195 -0
  150. package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
  151. package/dist/state/index.d.ts +1 -1
  152. package/dist/store-DLeqKuj3.d.ts +310 -0
  153. package/dist/store-vgcPYo8K.js +432 -0
  154. package/dist/store-vgcPYo8K.js.map +1 -0
  155. package/dist/streams/index.d.ts +1 -1
  156. package/dist/streams/index.js +1 -1
  157. package/dist/{streams-DW-UCOUc.js → streams-CITClVer.js} +16 -3
  158. package/dist/streams-CITClVer.js.map +1 -0
  159. package/dist/{streams-Cmkj9QfW.d.ts → streams-fbG61qM8.d.ts} +2 -2
  160. package/dist/sub-routing.d.ts +1 -1
  161. package/dist/tasks/index.d.ts +1 -1
  162. package/dist/tasks/index.js +1 -1
  163. package/dist/{tasks-68DESxf0.js → tasks-CkTZNaV1.js} +2 -1
  164. package/dist/tasks-CkTZNaV1.js.map +1 -0
  165. package/dist/{tasks-9YxYtByh.d.ts → tasks-PtlB4Uyn.d.ts} +2 -2
  166. package/dist/tool-3PA8xjB_.js +421 -0
  167. package/dist/tool-3PA8xjB_.js.map +1 -0
  168. package/dist/tool-BPJEbwaX.d.ts +278 -0
  169. package/dist/transport-k2mFrtL8.d.ts +200 -0
  170. package/dist/turns-DCV3ycDl.js +317 -0
  171. package/dist/turns-DCV3ycDl.js.map +1 -0
  172. package/dist/voice/client.js +1 -1
  173. package/dist/voice/index.d.ts +2 -2
  174. package/dist/voice/index.js +1 -1
  175. package/dist/websearch/index.d.ts +58 -0
  176. package/dist/websearch/index.js +2 -0
  177. package/dist/websearch/tools/ai-sdk.d.ts +77 -0
  178. package/dist/websearch/tools/ai-sdk.js +46 -0
  179. package/dist/websearch/tools/ai-sdk.js.map +1 -0
  180. package/dist/websearch/tools/pi.d.ts +82 -0
  181. package/dist/websearch/tools/pi.js +89 -0
  182. package/dist/websearch/tools/pi.js.map +1 -0
  183. package/dist/websearch/tools/tanstack-ai.d.ts +71 -0
  184. package/dist/websearch/tools/tanstack-ai.js +46 -0
  185. package/dist/websearch/tools/tanstack-ai.js.map +1 -0
  186. package/dist/websockets/index.d.ts +12 -296
  187. package/dist/websockets/index.js +1 -1
  188. package/dist/{websockets-Ci-LZFHH.js → websockets-CmENGb-Z.js} +18 -4
  189. package/dist/websockets-CmENGb-Z.js.map +1 -0
  190. package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
  191. package/dist/workflow-types.d.ts +1 -1
  192. package/dist/workflows.d.ts +1 -1
  193. package/dist/workflows.js +1 -1
  194. package/docs/browse-the-web.md +3 -0
  195. package/docs/harnesses/pi.md +114 -32
  196. package/docs/harnesses/think.md +215 -0
  197. package/docs/index.md +4 -3
  198. package/docs/lifecycle.md +40 -0
  199. package/docs/models-pi-ai.md +5 -5
  200. package/docs/search-the-web.md +133 -0
  201. package/package.json +126 -47
  202. package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
  203. package/dist/channel-Bnm4S7T2.d.ts +0 -491
  204. package/dist/channels/ai-sdk.d.ts +0 -46
  205. package/dist/channels/ai-sdk.js +0 -120
  206. package/dist/channels/ai-sdk.js.map +0 -1
  207. package/dist/channels/email.js.map +0 -1
  208. package/dist/channels/index.d.ts +0 -233
  209. package/dist/channels/index.js +0 -608
  210. package/dist/channels/index.js.map +0 -1
  211. package/dist/channels/slack.js +0 -614
  212. package/dist/channels/slack.js.map +0 -1
  213. package/dist/channels/tanstack-ai.d.ts +0 -39
  214. package/dist/channels/tanstack-ai.js +0 -17
  215. package/dist/channels/tanstack-ai.js.map +0 -1
  216. package/dist/channels/telegram.js +0 -427
  217. package/dist/channels/telegram.js.map +0 -1
  218. package/dist/channels/voice.d.ts +0 -45
  219. package/dist/channels/voice.js +0 -122
  220. package/dist/channels/voice.js.map +0 -1
  221. package/dist/harnesses/pi/index.js.map +0 -1
  222. package/dist/images-iiTDSyRu.js.map +0 -1
  223. package/dist/index-BB0kqhIz.d.ts +0 -101
  224. package/dist/ingress-BfetZbMO.js +0 -83
  225. package/dist/ingress-BfetZbMO.js.map +0 -1
  226. package/dist/internal-CYlgHl1l.js +0 -59
  227. package/dist/internal-CYlgHl1l.js.map +0 -1
  228. package/dist/models/ai-sdk/index.js.map +0 -1
  229. package/dist/protocol-kHsr-f0X.js.map +0 -1
  230. package/dist/sessions/index.js.map +0 -1
  231. package/dist/streams-DW-UCOUc.js.map +0 -1
  232. package/dist/surface-bZZJqBka.js +0 -17
  233. package/dist/surface-bZZJqBka.js.map +0 -1
  234. package/dist/tasks-68DESxf0.js.map +0 -1
  235. package/dist/tool-schema-CBjGPrsQ.js +0 -31
  236. package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
  237. package/dist/websockets-Ci-LZFHH.js.map +0 -1
  238. package/docs/channels.md +0 -323
@@ -0,0 +1,195 @@
1
+ import { t as CHAT_MESSAGE_TYPES } from "./protocol-eXeJxhgu.js";
2
+ import { jsonSchema, tool } from "ai";
3
+ //#region src/chat/client-tools.ts
4
+ /**
5
+ * Converts client tool schemas to AI SDK tool format.
6
+ *
7
+ * By default these tools have no `execute` function — when the AI model calls
8
+ * them, the tool call is sent back to the client for execution.
9
+ *
10
+ * When `options.execute` is provided, each tool is built WITH an `execute` that
11
+ * delegates to it. This is used by the RPC path (e.g. a parent agent driving a
12
+ * Think sub-agent) so the model's client-tool call is resolved inline within
13
+ * the same turn.
14
+ *
15
+ * @param clientTools - Array of tool schemas from the client
16
+ * @param options - Optional `execute` delegate to run the tools inline
17
+ * @returns Record of AI SDK tools that can be spread into your tools object
18
+ */
19
+ function createToolsFromClientSchemas(clientTools, options) {
20
+ if (!clientTools || clientTools.length === 0) return {};
21
+ const seenNames = /* @__PURE__ */ new Set();
22
+ for (const t of clientTools) {
23
+ if (seenNames.has(t.name)) console.warn(`[createToolsFromClientSchemas] Duplicate tool name "${t.name}" found. Later definitions will override earlier ones.`);
24
+ seenNames.add(t.name);
25
+ }
26
+ const execute = options?.execute;
27
+ const createTool = tool;
28
+ return Object.fromEntries(clientTools.map((t) => [t.name, createTool({
29
+ description: typeof t.description === "function" ? "" : t.description ?? "",
30
+ inputSchema: jsonSchema(t.parameters ?? { type: "object" }),
31
+ ...execute ? { execute: (input, executeOptions) => execute({
32
+ toolName: t.name,
33
+ input,
34
+ toolCallId: executeOptions?.toolCallId ?? ""
35
+ }) } : {}
36
+ })]));
37
+ }
38
+ //#endregion
39
+ //#region src/chat/parse-protocol.ts
40
+ /**
41
+ * Protocol Message Parser — typed parsing of cf_agent_chat_* WebSocket messages.
42
+ *
43
+ * Parses raw WebSocket messages into a discriminated union of protocol events.
44
+ * Both AIChatAgent and Think can use this instead of manual JSON.parse + type checking.
45
+ */
46
+ /**
47
+ * Parse a raw WebSocket message string into a typed protocol event.
48
+ *
49
+ * Returns `null` if the message is not valid JSON or not a recognized
50
+ * protocol message type. Callers should fall through to the user's
51
+ * `onMessage` handler when `null` is returned.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const event = parseProtocolMessage(rawMessage);
56
+ * if (!event) return userOnMessage(connection, rawMessage);
57
+ *
58
+ * switch (event.type) {
59
+ * case "chat-request": { ... }
60
+ * case "clear": { ... }
61
+ * case "tool-result": { ... }
62
+ * }
63
+ * ```
64
+ */
65
+ function parseProtocolMessage(raw) {
66
+ let data;
67
+ try {
68
+ data = JSON.parse(raw);
69
+ } catch {
70
+ return null;
71
+ }
72
+ const wireType = data.type;
73
+ if (!wireType) return null;
74
+ switch (wireType) {
75
+ case CHAT_MESSAGE_TYPES.USE_CHAT_REQUEST: return {
76
+ type: "chat-request",
77
+ id: data.id,
78
+ init: data.init ?? {}
79
+ };
80
+ case CHAT_MESSAGE_TYPES.CHAT_CLEAR: return { type: "clear" };
81
+ case CHAT_MESSAGE_TYPES.CHAT_REQUEST_CANCEL: return {
82
+ type: "cancel",
83
+ id: data.id
84
+ };
85
+ case CHAT_MESSAGE_TYPES.TOOL_RESULT: return {
86
+ type: "tool-result",
87
+ toolCallId: data.toolCallId,
88
+ toolName: data.toolName ?? "",
89
+ output: data.output,
90
+ state: data.state,
91
+ errorText: data.errorText,
92
+ autoContinue: data.autoContinue,
93
+ clientTools: data.clientTools
94
+ };
95
+ case CHAT_MESSAGE_TYPES.TOOL_APPROVAL: return {
96
+ type: "tool-approval",
97
+ toolCallId: data.toolCallId,
98
+ approved: data.approved,
99
+ autoContinue: data.autoContinue
100
+ };
101
+ case CHAT_MESSAGE_TYPES.STREAM_RESUME_REQUEST: return {
102
+ type: "stream-resume-request",
103
+ ...typeof data.probeId === "string" ? { probeId: data.probeId } : {}
104
+ };
105
+ case CHAT_MESSAGE_TYPES.STREAM_RESUME_ACK: return {
106
+ type: "stream-resume-ack",
107
+ id: data.id
108
+ };
109
+ case CHAT_MESSAGE_TYPES.CHAT_MESSAGES: return {
110
+ type: "messages",
111
+ messages: data.messages ?? []
112
+ };
113
+ default: return null;
114
+ }
115
+ }
116
+ //#endregion
117
+ //#region src/chat/stall-watchdog.ts
118
+ /**
119
+ * Shared inactivity watchdog for UI-message streams.
120
+ *
121
+ * A model/transport stream can park indefinitely without ever throwing (a hung
122
+ * provider, a wedged transport). Left unguarded, the consumer read-loop waits
123
+ * forever. {@link iterateWithStallWatchdog} wraps such a stream so that a gap of
124
+ * `timeoutMs` between chunks aborts the upstream and throws
125
+ * {@link ChatStreamStalledError}, letting the consumer route the stall into
126
+ * bounded recovery (#1626) — a transient hang is retried within the existing
127
+ * recovery budget — while genuine in-band errors stay terminal.
128
+ *
129
+ * @internal Sibling-package support for `@cloudflare/ai-chat` and
130
+ * `@cloudflare/think`, not a public API. See
131
+ * `design/rfc-chat-recovery-foundation.md`.
132
+ */
133
+ /**
134
+ * Thrown by {@link iterateWithStallWatchdog} when the inactivity watchdog fires
135
+ * (a model/transport stream that parks without ever throwing). Distinct from
136
+ * in-band model/stream errors so the read-loop catch can route a stall into
137
+ * bounded recovery (#1626) — a transient hang is retried within the existing
138
+ * recovery budget — while genuine errors stay terminal.
139
+ */
140
+ var ChatStreamStalledError = class extends Error {
141
+ constructor(message) {
142
+ super(message);
143
+ this.isChatStreamStall = true;
144
+ this.name = "ChatStreamStalledError";
145
+ }
146
+ };
147
+ /**
148
+ * Wrap a UI-message stream with an inactivity watchdog. If no chunk arrives
149
+ * within `timeoutMs`, `onStall` runs (aborting the upstream model stream) and
150
+ * the iterator throws, so the consumer loop exits with a terminal error
151
+ * instead of parking forever on a hung provider/transport. `timeoutMs <= 0`
152
+ * passes the source through untouched.
153
+ */
154
+ async function* iterateWithStallWatchdog(source, timeoutMs, onStall) {
155
+ if (!(timeoutMs > 0)) {
156
+ yield* source;
157
+ return;
158
+ }
159
+ const iterator = source[Symbol.asyncIterator]();
160
+ let selfAborted = false;
161
+ try {
162
+ while (true) {
163
+ let timer;
164
+ let stalled = false;
165
+ const stall = new Promise((_, reject) => {
166
+ timer = setTimeout(() => {
167
+ stalled = true;
168
+ reject(new ChatStreamStalledError(`Chat stream stalled: no activity for ${timeoutMs}ms; the turn was aborted by the stall watchdog.`));
169
+ }, timeoutMs);
170
+ });
171
+ const nextPromise = iterator.next();
172
+ nextPromise.catch(() => {});
173
+ let next;
174
+ try {
175
+ next = await Promise.race([nextPromise, stall]);
176
+ } catch (err) {
177
+ if (stalled) {
178
+ selfAborted = true;
179
+ onStall();
180
+ }
181
+ throw err;
182
+ } finally {
183
+ if (timer !== void 0) clearTimeout(timer);
184
+ }
185
+ if (next.done) return;
186
+ yield next.value;
187
+ }
188
+ } finally {
189
+ if (!selfAborted) await iterator.return?.(void 0).catch(() => {});
190
+ }
191
+ }
192
+ //#endregion
193
+ export { createToolsFromClientSchemas as i, iterateWithStallWatchdog as n, parseProtocolMessage as r, ChatStreamStalledError as t };
194
+
195
+ //# sourceMappingURL=stall-watchdog-BpRF2uwG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stall-watchdog-BpRF2uwG.js","names":[],"sources":["../src/chat/client-tools.ts","../src/chat/parse-protocol.ts","../src/chat/stall-watchdog.ts"],"sourcesContent":["/**\n * Client tool schema handling for the cf_agent_chat protocol.\n *\n * Converts client-provided tool schemas (JSON wire format) into AI SDK\n * tool definitions. By default these tools have no `execute` function —\n * when the model calls them, the tool call is sent back to the client.\n *\n * When an `execute` delegate is supplied (e.g. a parent agent that drives a\n * Think sub-agent over RPC and can run the client tools itself), the tools are\n * built WITH an `execute` so the model's call is resolved inline within the\n * same turn instead of being surfaced as a dangling tool call.\n *\n * Used by both @cloudflare/ai-chat and @cloudflare/think.\n */\n\nimport type { JSONSchema7, Tool, ToolSet } from \"ai\";\nimport { tool, jsonSchema } from \"ai\";\n\n/**\n * Wire-format tool schema sent from the client.\n * Uses `parameters` (JSONSchema7) rather than AI SDK's `inputSchema`\n * because Zod schemas cannot be serialized over the wire.\n */\nexport type ClientToolSchema = {\n /** Unique name for the tool */\n name: string;\n /** Human-readable description of what the tool does */\n description?: Tool[\"description\"];\n /** JSON Schema defining the tool's input parameters */\n parameters?: JSONSchema7;\n};\n\n/**\n * Executes a client-defined tool and returns its output.\n *\n * Used for the RPC path (e.g. a parent agent delegating to a Think sub-agent)\n * where the caller can run the client tools itself, rather than the\n * browser/WebSocket path where results are sent back asynchronously.\n */\nexport type ClientToolExecutor = (call: {\n /** The name of the client tool the model called. */\n toolName: string;\n /** The model-generated input for the tool call. */\n input: unknown;\n /** The AI SDK tool-call id for the invocation. */\n toolCallId: string;\n}) => unknown | Promise<unknown>;\n\n/**\n * Converts client tool schemas to AI SDK tool format.\n *\n * By default these tools have no `execute` function — when the AI model calls\n * them, the tool call is sent back to the client for execution.\n *\n * When `options.execute` is provided, each tool is built WITH an `execute` that\n * delegates to it. This is used by the RPC path (e.g. a parent agent driving a\n * Think sub-agent) so the model's client-tool call is resolved inline within\n * the same turn.\n *\n * @param clientTools - Array of tool schemas from the client\n * @param options - Optional `execute` delegate to run the tools inline\n * @returns Record of AI SDK tools that can be spread into your tools object\n */\nexport function createToolsFromClientSchemas(\n clientTools?: ClientToolSchema[],\n options?: { execute?: ClientToolExecutor }\n): ToolSet {\n if (!clientTools || clientTools.length === 0) {\n return {};\n }\n\n const seenNames = new Set<string>();\n for (const t of clientTools) {\n if (seenNames.has(t.name)) {\n console.warn(\n `[createToolsFromClientSchemas] Duplicate tool name \"${t.name}\" found. Later definitions will override earlier ones.`\n );\n }\n seenNames.add(t.name);\n }\n\n const execute = options?.execute;\n // The AI SDK's `tool()` overloads infer the input type as `never` when an\n // `execute` is combined with a runtime `jsonSchema(...)`. Cast to a\n // permissive signature (same approach as `agentTool()`), since the wire\n // schema is untyped JSON.\n const createTool = tool as unknown as (config: {\n description: string | ((options: unknown) => string);\n inputSchema: ReturnType<typeof jsonSchema>;\n execute?: (\n input: unknown,\n executeOptions?: { toolCallId?: string }\n ) => unknown | Promise<unknown>;\n }) => Tool;\n\n return Object.fromEntries(\n clientTools.map((t) => [\n t.name,\n createTool({\n description:\n typeof t.description === \"function\" ? \"\" : (t.description ?? \"\"),\n inputSchema: jsonSchema(t.parameters ?? { type: \"object\" }),\n ...(execute\n ? {\n execute: (\n input: unknown,\n executeOptions?: { toolCallId?: string }\n ) =>\n execute({\n toolName: t.name,\n input,\n toolCallId: executeOptions?.toolCallId ?? \"\"\n })\n }\n : {})\n })\n ])\n );\n}\n","/**\n * Protocol Message Parser — typed parsing of cf_agent_chat_* WebSocket messages.\n *\n * Parses raw WebSocket messages into a discriminated union of protocol events.\n * Both AIChatAgent and Think can use this instead of manual JSON.parse + type checking.\n */\n\nimport { CHAT_MESSAGE_TYPES } from \"./protocol\";\n\n/**\n * Discriminated union of all incoming chat protocol events.\n *\n * Each agent handles the events it cares about and ignores the rest.\n * Returns `null` for non-JSON messages or unrecognized types.\n */\nexport type ChatProtocolEvent =\n | {\n type: \"chat-request\";\n id: string;\n init: { method?: string; body?: string; [key: string]: unknown };\n }\n | { type: \"clear\" }\n | { type: \"cancel\"; id: string }\n | {\n type: \"tool-result\";\n toolCallId: string;\n toolName: string;\n output: unknown;\n state?: string;\n errorText?: string;\n autoContinue?: boolean;\n clientTools?: Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>;\n }\n | {\n type: \"tool-approval\";\n toolCallId: string;\n approved: boolean;\n autoContinue?: boolean;\n }\n | { type: \"stream-resume-request\"; probeId?: string }\n | { type: \"stream-resume-ack\"; id: string }\n | { type: \"messages\"; messages: unknown[] };\n\n/**\n * Parse a raw WebSocket message string into a typed protocol event.\n *\n * Returns `null` if the message is not valid JSON or not a recognized\n * protocol message type. Callers should fall through to the user's\n * `onMessage` handler when `null` is returned.\n *\n * @example\n * ```typescript\n * const event = parseProtocolMessage(rawMessage);\n * if (!event) return userOnMessage(connection, rawMessage);\n *\n * switch (event.type) {\n * case \"chat-request\": { ... }\n * case \"clear\": { ... }\n * case \"tool-result\": { ... }\n * }\n * ```\n */\nexport function parseProtocolMessage(raw: string): ChatProtocolEvent | null {\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n\n const wireType = data.type as string | undefined;\n if (!wireType) return null;\n\n switch (wireType) {\n case CHAT_MESSAGE_TYPES.USE_CHAT_REQUEST:\n return {\n type: \"chat-request\",\n id: data.id as string,\n init: (data.init as { method?: string; body?: string }) ?? {}\n };\n\n case CHAT_MESSAGE_TYPES.CHAT_CLEAR:\n return { type: \"clear\" };\n\n case CHAT_MESSAGE_TYPES.CHAT_REQUEST_CANCEL:\n return { type: \"cancel\", id: data.id as string };\n\n case CHAT_MESSAGE_TYPES.TOOL_RESULT:\n return {\n type: \"tool-result\",\n toolCallId: data.toolCallId as string,\n toolName: (data.toolName as string) ?? \"\",\n output: data.output,\n state: data.state as string | undefined,\n errorText: data.errorText as string | undefined,\n autoContinue: data.autoContinue as boolean | undefined,\n clientTools: data.clientTools as\n | Array<{\n name: string;\n description?: string;\n parameters?: unknown;\n }>\n | undefined\n };\n\n case CHAT_MESSAGE_TYPES.TOOL_APPROVAL:\n return {\n type: \"tool-approval\",\n toolCallId: data.toolCallId as string,\n approved: data.approved as boolean,\n autoContinue: data.autoContinue as boolean | undefined\n };\n\n case CHAT_MESSAGE_TYPES.STREAM_RESUME_REQUEST:\n return {\n type: \"stream-resume-request\",\n ...(typeof data.probeId === \"string\" ? { probeId: data.probeId } : {})\n };\n\n case CHAT_MESSAGE_TYPES.STREAM_RESUME_ACK:\n return {\n type: \"stream-resume-ack\",\n id: data.id as string\n };\n\n case CHAT_MESSAGE_TYPES.CHAT_MESSAGES:\n return {\n type: \"messages\",\n messages: (data.messages as unknown[]) ?? []\n };\n\n default:\n return null;\n }\n}\n","/**\n * Shared inactivity watchdog for UI-message streams.\n *\n * A model/transport stream can park indefinitely without ever throwing (a hung\n * provider, a wedged transport). Left unguarded, the consumer read-loop waits\n * forever. {@link iterateWithStallWatchdog} wraps such a stream so that a gap of\n * `timeoutMs` between chunks aborts the upstream and throws\n * {@link ChatStreamStalledError}, letting the consumer route the stall into\n * bounded recovery (#1626) — a transient hang is retried within the existing\n * recovery budget — while genuine in-band errors stay terminal.\n *\n * @internal Sibling-package support for `@cloudflare/ai-chat` and\n * `@cloudflare/think`, not a public API. See\n * `design/rfc-chat-recovery-foundation.md`.\n */\n\n/**\n * Thrown by {@link iterateWithStallWatchdog} when the inactivity watchdog fires\n * (a model/transport stream that parks without ever throwing). Distinct from\n * in-band model/stream errors so the read-loop catch can route a stall into\n * bounded recovery (#1626) — a transient hang is retried within the existing\n * recovery budget — while genuine errors stay terminal.\n */\nexport class ChatStreamStalledError extends Error {\n readonly isChatStreamStall = true;\n constructor(message: string) {\n super(message);\n this.name = \"ChatStreamStalledError\";\n }\n}\n\n/**\n * Wrap a UI-message stream with an inactivity watchdog. If no chunk arrives\n * within `timeoutMs`, `onStall` runs (aborting the upstream model stream) and\n * the iterator throws, so the consumer loop exits with a terminal error\n * instead of parking forever on a hung provider/transport. `timeoutMs <= 0`\n * passes the source through untouched.\n */\nexport async function* iterateWithStallWatchdog<T>(\n source: AsyncIterable<T>,\n timeoutMs: number,\n onStall: () => void\n): AsyncGenerator<T> {\n if (!(timeoutMs > 0)) {\n yield* source;\n return;\n }\n const iterator = source[Symbol.asyncIterator]();\n // Tracks whether the watchdog itself aborted the upstream. In that case we\n // must NOT also `iterator.return()` it: cancelling the readable after the\n // abort makes the AI SDK pipeline write to an already-cancelled readable\n // (\"readable side is no longer readable\"). Letting the abort error the\n // stream is the clean path.\n let selfAborted = false;\n try {\n while (true) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let stalled = false;\n const stall = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n stalled = true;\n reject(\n new ChatStreamStalledError(\n `Chat stream stalled: no activity for ${timeoutMs}ms; the turn was aborted by the stall watchdog.`\n )\n );\n }, timeoutMs);\n });\n const nextPromise = iterator.next();\n // If the watchdog wins the race we abandon this read; aborting the\n // upstream stream makes it reject later, so pre-attach a no-op catch to\n // keep that abandoned rejection from surfacing as an unhandled rejection.\n nextPromise.catch(() => {});\n let next: IteratorResult<T>;\n try {\n next = await Promise.race([nextPromise, stall]);\n } catch (err) {\n if (stalled) {\n selfAborted = true;\n onStall();\n }\n throw err;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n if (next.done) return;\n yield next.value;\n }\n } finally {\n // Forward early termination (consumer `break`/`throw`, e.g. an in-band\n // stream error where the abort signal is NOT set) to the source so its\n // reader is cancelled — otherwise the wrapped source would leak when the\n // consumer stops reading mid-stream. Skipped after a watchdog stall, which\n // already aborted the upstream (see `selfAborted` above).\n if (!selfAborted) {\n await iterator.return?.(undefined as never).catch(() => {});\n }\n }\n}\n"],"mappings":"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"}
@@ -2,5 +2,5 @@ import {
2
2
  n as StateChangeSource,
3
3
  r as StateOptions,
4
4
  t as State
5
- } from "../index-BreL0YrQ.js";
5
+ } from "../index-D0A5tbWu.js";
6
6
  export { State, StateChangeSource, StateOptions };
@@ -0,0 +1,310 @@
1
+ //#region src/harness/store/store.d.ts
2
+ /**
3
+ * A session store for harnesses, on a Durable Object's SQLite database.
4
+ *
5
+ * Any harness that runs its agent somewhere other than the object (a
6
+ * container, a sandbox, a remote process) needs the same few things kept
7
+ * durably next to it: which sessions exist, which operations were submitted
8
+ * and how each one ended, and the session's history in whatever format the
9
+ * harness speaks. This store keeps those and nothing more. It knows no
10
+ * message format, no event vocabulary and no runtime: inputs, results,
11
+ * session state and log entries are opaque JSON that the harness parses.
12
+ *
13
+ * Three record kinds:
14
+ *
15
+ * - **Sessions**: an id, an optional parent (a fork), and one JSON state
16
+ * value the harness owns (model, cursors, resume handles).
17
+ * - **Operations**: one row per submitted operation, keyed by an
18
+ * idempotency id within its session, moving `queued` → `running` →
19
+ * `done` | `unanswered`. Transitions are guarded in SQL, so a duplicate or
20
+ * late transition is a no-op rather than a regression.
21
+ * - **Logs**: named, append-ordered streams of JSON entries per session
22
+ * (`"messages"`, `"engine"`, …). An entry may carry an id, and an entry
23
+ * written again under the same id replaces the old one in place. Entries
24
+ * larger than one SQLite row are split across continuation rows.
25
+ *
26
+ * The store is synchronous, like the SQL API under it, so a harness can
27
+ * group several writes in `transaction()` without awaiting.
28
+ *
29
+ * @experimental The API may change before it stabilizes.
30
+ */
31
+ /** A JSON value, as the store keeps it. */
32
+ type JsonValue =
33
+ | string
34
+ | number
35
+ | boolean
36
+ | null
37
+ | readonly JsonValue[]
38
+ | {
39
+ readonly [key: string]: JsonValue;
40
+ };
41
+ /** Where an operation is in its life. */
42
+ type OperationStatus = "queued" | "running" | "done" | "unanswered";
43
+ /** A session, as stored. */
44
+ type SessionRecord = {
45
+ readonly id: string /** The session this one was forked from. */;
46
+ readonly parent:
47
+ | string
48
+ | undefined /** Harness-owned state. `null` until the harness writes some. */;
49
+ readonly state: JsonValue;
50
+ readonly createdAt: number;
51
+ readonly updatedAt: number;
52
+ };
53
+ /** One operation, as stored. */
54
+ type OperationRecord = {
55
+ readonly session: string /** The idempotency key, unique within the session. */;
56
+ readonly id: string /** Submission order within the whole store. */;
57
+ readonly seq: number;
58
+ readonly status: OperationStatus /** What was submitted, in the harness's format. */;
59
+ readonly input: JsonValue /** Harness-owned submission options and bookkeeping. */;
60
+ readonly meta: JsonValue /** The harness's result for a `done` operation, else `null`. */;
61
+ readonly result: JsonValue /** Why an `unanswered` operation ended. */;
62
+ readonly reason: string | undefined;
63
+ readonly createdAt: number;
64
+ readonly settledAt: number | undefined;
65
+ };
66
+ /** One log entry, as stored. */
67
+ type LogEntry = {
68
+ /** Position in the log. Stable when the entry is replaced by id. */ readonly seq: number;
69
+ readonly id: string | undefined;
70
+ readonly data: JsonValue;
71
+ readonly createdAt: number;
72
+ };
73
+ /** One entry to append. */
74
+ type LogAppend = {
75
+ /** Replace an existing entry with this id in place, instead of appending. */ readonly id?: string;
76
+ readonly data: JsonValue;
77
+ };
78
+ /** How an operation ended. */
79
+ type OperationOutcome =
80
+ | {
81
+ readonly status: "done";
82
+ readonly result: JsonValue;
83
+ }
84
+ | {
85
+ readonly status: "unanswered";
86
+ readonly reason: string;
87
+ };
88
+ /** `openHarnessStore`'s options. */
89
+ type HarnessStoreOptions = {
90
+ /**
91
+ * Prefix for the store's tables. Two harnesses in one object use two
92
+ * prefixes. Must not start with `_cf_`, which Durable Objects reserve.
93
+ * Default `harness_`.
94
+ */
95
+ readonly prefix?: string;
96
+ };
97
+ /**
98
+ * Open the store over this object's SQLite database, creating its tables on
99
+ * first use. Cheap: call it once per isolate and keep the result.
100
+ *
101
+ * @param storage - The Durable Object's storage.
102
+ * @param options - Table prefix.
103
+ * @returns The store.
104
+ */
105
+ declare function openHarnessStore(
106
+ storage: DurableObjectStorage,
107
+ options?: HarnessStoreOptions
108
+ ): HarnessStore;
109
+ /**
110
+ * The store. Construct it with `openHarnessStore`.
111
+ *
112
+ * @experimental The API may change before it stabilizes.
113
+ */
114
+ declare class HarnessStore {
115
+ #private;
116
+ /**
117
+ * @param storage - The Durable Object's storage.
118
+ * @param options - Table prefix.
119
+ */
120
+ constructor(storage: DurableObjectStorage, options: HarnessStoreOptions);
121
+ /**
122
+ * Run `fn` in one storage transaction. Writes inside it commit together or
123
+ * not at all.
124
+ *
125
+ * @template T - What `fn` returns.
126
+ * @param fn - Synchronous work against this store.
127
+ * @returns What `fn` returned.
128
+ */
129
+ transaction<T>(fn: () => T): T;
130
+ /**
131
+ * Create a session, or return the existing one with this id unchanged.
132
+ *
133
+ * @param input - The id, an optional parent, and the initial state.
134
+ * @returns The stored session.
135
+ */
136
+ createSession(input: {
137
+ readonly id: string;
138
+ readonly parent?: string;
139
+ readonly state?: JsonValue;
140
+ }): SessionRecord;
141
+ /**
142
+ * Read one session.
143
+ *
144
+ * @param id - The session id.
145
+ * @returns The session, or `undefined` when there is none.
146
+ */
147
+ session(id: string): SessionRecord | undefined;
148
+ /**
149
+ * Every session, oldest first.
150
+ *
151
+ * @returns The sessions.
152
+ */
153
+ sessions(): SessionRecord[];
154
+ /**
155
+ * Replace a session's harness-owned state.
156
+ *
157
+ * @param id - The session id.
158
+ * @param state - The new state.
159
+ * @returns False when there is no such session.
160
+ */
161
+ setSessionState(id: string, state: JsonValue): boolean;
162
+ /**
163
+ * Delete a session with its operations and logs.
164
+ *
165
+ * @param id - The session id.
166
+ * @returns False when there was no such session.
167
+ */
168
+ deleteSession(id: string): boolean;
169
+ /**
170
+ * Durably queue an operation. Idempotent on `(session, id)`: a second
171
+ * enqueue with the same id stores nothing and returns the first record.
172
+ *
173
+ * @param input - The session, the idempotency id, the input and options.
174
+ * @returns The stored record, and whether this call created it.
175
+ */
176
+ enqueue(input: {
177
+ readonly session: string;
178
+ readonly id: string;
179
+ readonly input: JsonValue;
180
+ readonly meta?: JsonValue;
181
+ }): {
182
+ readonly record: OperationRecord;
183
+ readonly accepted: boolean;
184
+ };
185
+ /**
186
+ * Read one operation.
187
+ *
188
+ * @param session - The session id.
189
+ * @param id - The operation id.
190
+ * @returns The operation, or `undefined` when there is none.
191
+ */
192
+ operation(session: string, id: string): OperationRecord | undefined;
193
+ /**
194
+ * Operations in submission order, optionally narrowed to one session and
195
+ * to some statuses.
196
+ *
197
+ * @param filter - The session and statuses to keep. Default: all.
198
+ * @returns The matching operations, oldest first.
199
+ */
200
+ operations(filter?: {
201
+ readonly session?: string;
202
+ readonly status?: readonly OperationStatus[];
203
+ }): OperationRecord[];
204
+ /**
205
+ * Move a queued operation to `running`.
206
+ *
207
+ * @param session - The session id.
208
+ * @param id - The operation id.
209
+ * @returns False when it was not queued.
210
+ */
211
+ start(session: string, id: string): boolean;
212
+ /**
213
+ * Move a running operation back to `queued`, to run it again.
214
+ *
215
+ * @param session - The session id.
216
+ * @param id - The operation id.
217
+ * @returns False when it was not running.
218
+ */
219
+ requeue(session: string, id: string): boolean;
220
+ /**
221
+ * Settle a queued or running operation.
222
+ *
223
+ * @param session - The session id.
224
+ * @param id - The operation id.
225
+ * @param outcome - How it ended.
226
+ * @returns False when it had already settled or does not exist.
227
+ */
228
+ settle(session: string, id: string, outcome: OperationOutcome): boolean;
229
+ /**
230
+ * Replace an operation's harness-owned bookkeeping.
231
+ *
232
+ * @param session - The session id.
233
+ * @param id - The operation id.
234
+ * @param meta - The new value.
235
+ * @returns False when there is no such operation.
236
+ */
237
+ setOperationMeta(session: string, id: string, meta: JsonValue): boolean;
238
+ /**
239
+ * Append entries to a session's log. An entry with an id that is already
240
+ * in the log replaces that entry in place, keeping its position.
241
+ *
242
+ * @param session - The session id.
243
+ * @param log - The log's name, such as `"messages"`.
244
+ * @param entries - The entries, in order.
245
+ * @returns The position of the last entry written, or of the log's end.
246
+ */
247
+ append(session: string, log: string, entries: readonly LogAppend[]): number;
248
+ /**
249
+ * Read a session's log in order.
250
+ *
251
+ * @param session - The session id.
252
+ * @param log - The log's name.
253
+ * @param range - Entries after position `after` (exclusive), at most `limit`.
254
+ * @returns The entries.
255
+ */
256
+ read(
257
+ session: string,
258
+ log: string,
259
+ range?: {
260
+ readonly after?: number;
261
+ readonly limit?: number;
262
+ }
263
+ ): LogEntry[];
264
+ /**
265
+ * One entry by id.
266
+ *
267
+ * @param session - The session id.
268
+ * @param log - The log's name.
269
+ * @param id - The entry id.
270
+ * @returns The entry, or `undefined`.
271
+ */
272
+ entry(session: string, log: string, id: string): LogEntry | undefined;
273
+ /**
274
+ * The position of a log's last entry.
275
+ *
276
+ * @param session - The session id.
277
+ * @param log - The log's name.
278
+ * @returns The position, or 0 for an empty log.
279
+ */
280
+ end(session: string, log: string): number;
281
+ /**
282
+ * Empty a session's log.
283
+ *
284
+ * @param session - The session id.
285
+ * @param log - The log's name.
286
+ */
287
+ clear(session: string, log: string): void;
288
+ /**
289
+ * Copy one session's log onto the end of another's, keeping entry ids.
290
+ *
291
+ * @param from - The source session.
292
+ * @param to - The target session.
293
+ * @param log - The log's name.
294
+ */
295
+ copy(from: string, to: string, log: string): void;
296
+ }
297
+ //#endregion
298
+ export {
299
+ LogEntry as a,
300
+ OperationStatus as c,
301
+ LogAppend as i,
302
+ SessionRecord as l,
303
+ HarnessStoreOptions as n,
304
+ OperationOutcome as o,
305
+ JsonValue as r,
306
+ OperationRecord as s,
307
+ HarnessStore as t,
308
+ openHarnessStore as u
309
+ };
310
+ //# sourceMappingURL=store-DLeqKuj3.d.ts.map