agents 0.21.0 → 0.23.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 (258) hide show
  1. package/README.md +21 -1
  2. package/dist/{agent-tool-types-CzGGB-20.d.ts → agent-routing-DE5zmCQ8.d.ts} +1844 -1336
  3. package/dist/agent-routing.d.ts +14 -0
  4. package/dist/agent-routing.js +187 -0
  5. package/dist/agent-routing.js.map +1 -0
  6. package/dist/agent-tool-types.d.ts +26 -26
  7. package/dist/{agent-tools-zR2d5uij.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
  8. package/dist/agent-tools.d.ts +21 -21
  9. package/dist/agent-tools.js +2 -1
  10. package/dist/agent-tools.js.map +1 -1
  11. package/dist/browser/ai.js +6 -2
  12. package/dist/browser/ai.js.map +1 -1
  13. package/dist/browser/tanstack-ai.js.map +1 -1
  14. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  15. package/dist/callable-decorator.d.ts +18 -0
  16. package/dist/callable-decorator.js +71 -0
  17. package/dist/callable-decorator.js.map +1 -0
  18. package/dist/capability-BjSKYpzg.js +42 -0
  19. package/dist/capability-BjSKYpzg.js.map +1 -0
  20. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  21. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  22. package/dist/channels/ai-sdk.d.ts +46 -0
  23. package/dist/channels/ai-sdk.js +120 -0
  24. package/dist/channels/ai-sdk.js.map +1 -0
  25. package/dist/channels/email.d.ts +95 -0
  26. package/dist/channels/email.js +323 -0
  27. package/dist/channels/email.js.map +1 -0
  28. package/dist/channels/index.d.ts +233 -0
  29. package/dist/channels/index.js +608 -0
  30. package/dist/channels/index.js.map +1 -0
  31. package/dist/channels/slack.d.ts +140 -0
  32. package/dist/channels/slack.js +614 -0
  33. package/dist/channels/slack.js.map +1 -0
  34. package/dist/channels/tanstack-ai.d.ts +39 -0
  35. package/dist/channels/tanstack-ai.js +17 -0
  36. package/dist/channels/tanstack-ai.js.map +1 -0
  37. package/dist/channels/telegram.d.ts +106 -0
  38. package/dist/channels/telegram.js +427 -0
  39. package/dist/channels/telegram.js.map +1 -0
  40. package/dist/channels/voice.d.ts +45 -0
  41. package/dist/channels/voice.js +122 -0
  42. package/dist/channels/voice.js.map +1 -0
  43. package/dist/chat/index.d.ts +2328 -2015
  44. package/dist/chat/index.js +891 -521
  45. package/dist/chat/index.js.map +1 -1
  46. package/dist/chat/react.d.ts +14 -1
  47. package/dist/chat/react.js +82 -52
  48. package/dist/chat/react.js.map +1 -1
  49. package/dist/chat/transport.js +1 -1
  50. package/dist/chat-sdk/index.d.ts +7 -7
  51. package/dist/chat-sdk/index.js +1 -1
  52. package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
  53. package/dist/client-jagG8a9_.js.map +1 -0
  54. package/dist/client.d.ts +1 -1
  55. package/dist/client.js +1 -1
  56. package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
  57. package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
  58. package/dist/context/index.d.ts +216 -0
  59. package/dist/context/index.js +454 -0
  60. package/dist/context/index.js.map +1 -0
  61. package/dist/current-agent-Da_C9a3b.d.ts +266 -0
  62. package/dist/current-agent-DhoDkSnH.js +51 -0
  63. package/dist/current-agent-DhoDkSnH.js.map +1 -0
  64. package/dist/diagnostics-BzvaX2UT.js +45 -0
  65. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  66. package/dist/diagnostics-C4jcz3VK.js +360 -0
  67. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  68. package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
  69. package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
  70. package/dist/email-send.d.ts +15 -0
  71. package/dist/email-send.js +32 -0
  72. package/dist/email-send.js.map +1 -0
  73. package/dist/email.d.ts +14 -10
  74. package/dist/email.js.map +1 -1
  75. package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
  76. package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
  77. package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
  78. package/dist/index-BB0kqhIz.d.ts +101 -0
  79. package/dist/index-XDkuQ7zm.d.ts +89 -0
  80. package/dist/{index-BRnybD6X.d.ts → index-YSKgfgg9.d.ts} +21 -31
  81. package/dist/index.d.ts +113 -101
  82. package/dist/index.js +11 -7234
  83. package/dist/ingress-BfetZbMO.js +83 -0
  84. package/dist/ingress-BfetZbMO.js.map +1 -0
  85. package/dist/internal-CYlgHl1l.js +59 -0
  86. package/dist/internal-CYlgHl1l.js.map +1 -0
  87. package/dist/internal_context-BlxFEWfn.d.ts +19 -0
  88. package/dist/internal_context.d.ts +10 -4
  89. package/dist/internal_context.js +1 -10
  90. package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
  91. package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
  92. package/dist/invoker-CHMnoxIA.js.map +1 -0
  93. package/dist/lifecycle/index.d.ts +66 -0
  94. package/dist/lifecycle/index.js +4 -0
  95. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  96. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  97. package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
  98. package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
  99. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
  100. package/dist/mcp/client/index.d.ts +42 -0
  101. package/dist/mcp/{client.js → client/index.js} +1 -1
  102. package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
  103. package/dist/mcp/{x402.js → client/x402.js} +2 -2
  104. package/dist/mcp/client/x402.js.map +1 -0
  105. package/dist/mcp/index.d.ts +36 -36
  106. package/dist/mcp/index.js +14 -16
  107. package/dist/mcp/index.js.map +1 -1
  108. package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
  109. package/dist/mcp/{server.js → server/index.js} +1 -1
  110. package/dist/observability/ai/index.js +50 -35
  111. package/dist/observability/ai/index.js.map +1 -1
  112. package/dist/observability/index.d.ts +4 -4
  113. package/dist/observability/index.js +3 -50
  114. package/dist/observability/index.js.map +1 -1
  115. package/dist/{protocol-Dqc2MQxo.js → protocol-B0nh6KNf.js} +19 -21
  116. package/dist/protocol-B0nh6KNf.js.map +1 -0
  117. package/dist/react.d.ts +4 -4
  118. package/dist/react.js +1 -1
  119. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  120. package/dist/retries.d.ts +8 -6
  121. package/dist/retries.js +13 -1
  122. package/dist/retries.js.map +1 -1
  123. package/dist/routing/index.d.ts +137 -0
  124. package/dist/routing/index.js +244 -0
  125. package/dist/routing/index.js.map +1 -0
  126. package/dist/sanitize-D9TujEK8.js +79 -0
  127. package/dist/sanitize-D9TujEK8.js.map +1 -0
  128. package/dist/schedule.d.ts +25 -94
  129. package/dist/schedule.js +1 -98
  130. package/dist/schedule.js.map +1 -1
  131. package/dist/scheduler-DD9NdYbF.js +665 -0
  132. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  133. package/dist/scheduler-Dwh85ZGl.d.ts +223 -0
  134. package/dist/schedules/index.d.ts +22 -0
  135. package/dist/schedules/index.js +2 -0
  136. package/dist/schedules/parser.d.ts +79 -0
  137. package/dist/schedules/parser.js +103 -0
  138. package/dist/schedules/parser.js.map +1 -0
  139. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  140. package/dist/serializable.d.ts +1 -1
  141. package/dist/sessions/index.d.ts +441 -0
  142. package/dist/sessions/index.js +2063 -0
  143. package/dist/sessions/index.js.map +1 -0
  144. package/dist/skills/index.d.ts +99 -0
  145. package/dist/skills/index.js +254 -5
  146. package/dist/skills/index.js.map +1 -1
  147. package/dist/sql-error-CPY-GXyI.d.ts +12 -0
  148. package/dist/sql-error.d.ts +2 -0
  149. package/dist/sql-error.js +16 -0
  150. package/dist/sql-error.js.map +1 -0
  151. package/dist/src-DlSHshb2.js +6963 -0
  152. package/dist/src-DlSHshb2.js.map +1 -0
  153. package/dist/streams/index.d.ts +120 -0
  154. package/dist/streams/index.js +107 -0
  155. package/dist/streams/index.js.map +1 -0
  156. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  157. package/dist/streams-DZKgAj9b.js +709 -0
  158. package/dist/streams-DZKgAj9b.js.map +1 -0
  159. package/dist/sub-routing.d.ts +12 -12
  160. package/dist/surface-bZZJqBka.js +17 -0
  161. package/dist/surface-bZZJqBka.js.map +1 -0
  162. package/dist/tasks/index.d.ts +64 -0
  163. package/dist/tasks/index.js +2 -0
  164. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  165. package/dist/tasks-ylZgBjhj.js +1656 -0
  166. package/dist/tasks-ylZgBjhj.js.map +1 -0
  167. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  168. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  169. package/dist/text-stream-CpdiKrJB.js +272 -0
  170. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  171. package/dist/tokens-nHAKcN6M.js +52 -0
  172. package/dist/tokens-nHAKcN6M.js.map +1 -0
  173. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  174. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  175. package/dist/types-B7LojTe4.d.ts +202 -0
  176. package/dist/types-_Faxb570.d.ts +439 -0
  177. package/dist/voice/client.d.ts +226 -0
  178. package/dist/voice/client.js +932 -0
  179. package/dist/voice/client.js.map +1 -0
  180. package/dist/voice/errors.d.ts +43 -0
  181. package/dist/voice/errors.js +41 -0
  182. package/dist/voice/errors.js.map +1 -0
  183. package/dist/voice/index.d.ts +271 -0
  184. package/dist/voice/index.js +1812 -0
  185. package/dist/voice/index.js.map +1 -0
  186. package/dist/voice/react.d.ts +167 -0
  187. package/dist/voice/react.js +234 -0
  188. package/dist/voice/react.js.map +1 -0
  189. package/dist/voice/sfu.d.ts +71 -0
  190. package/dist/voice/sfu.js +157 -0
  191. package/dist/voice/sfu.js.map +1 -0
  192. package/dist/voice/text.d.ts +6 -0
  193. package/dist/voice/text.js +2 -0
  194. package/dist/voice/types.d.ts +58 -0
  195. package/dist/voice/types.js +18 -0
  196. package/dist/voice/types.js.map +1 -0
  197. package/dist/voice/workers-ai.d.ts +136 -0
  198. package/dist/voice/workers-ai.js +568 -0
  199. package/dist/voice/workers-ai.js.map +1 -0
  200. package/dist/websockets/index.d.ts +192 -0
  201. package/dist/websockets/index.js +2 -0
  202. package/dist/websockets-DUfRHPRq.js +502 -0
  203. package/dist/websockets-DUfRHPRq.js.map +1 -0
  204. package/dist/workflow-types.d.ts +25 -25
  205. package/dist/workflows.d.ts +22 -22
  206. package/dist/workflows.js +2 -1
  207. package/dist/workflows.js.map +1 -1
  208. package/dist/{ws-chat-transport-CIoOBbO7.js → ws-chat-transport-rWwta645.js} +152 -15
  209. package/dist/ws-chat-transport-rWwta645.js.map +1 -0
  210. package/docs/agent-class.md +29 -87
  211. package/docs/agent-tools.md +2 -1
  212. package/docs/channels.md +323 -0
  213. package/docs/chat-agents.md +19 -25
  214. package/docs/context.md +131 -0
  215. package/docs/durable-execution.md +1 -1
  216. package/docs/http-websockets.md +1 -11
  217. package/docs/human-in-the-loop.md +1 -1
  218. package/docs/index.md +16 -12
  219. package/docs/lifecycle.md +370 -0
  220. package/docs/long-running-agents.md +4 -6
  221. package/docs/mcp-client.md +55 -0
  222. package/docs/mcp-servers.md +5 -1
  223. package/docs/observability.md +11 -11
  224. package/docs/resumable-streaming.md +2 -2
  225. package/docs/routing.md +105 -0
  226. package/docs/scheduling.md +175 -15
  227. package/docs/server-driven-messages.md +1 -1
  228. package/docs/sessions.md +237 -871
  229. package/docs/streams.md +213 -0
  230. package/docs/sub-agents.md +185 -125
  231. package/docs/tasks.md +246 -0
  232. package/docs/voice.md +745 -0
  233. package/package.json +144 -33
  234. package/dist/cli/index.js +0 -26
  235. package/dist/cli/index.js.map +0 -1
  236. package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
  237. package/dist/client-zqKcsyFa.js.map +0 -1
  238. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  239. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  240. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  241. package/dist/experimental/memory/session/index.d.ts +0 -670
  242. package/dist/experimental/memory/session/index.js +0 -2374
  243. package/dist/experimental/memory/session/index.js.map +0 -1
  244. package/dist/experimental/memory/utils/index.d.ts +0 -96
  245. package/dist/experimental/memory/utils/index.js +0 -79
  246. package/dist/experimental/memory/utils/index.js.map +0 -1
  247. package/dist/handler-stateless-CIkKPETH.js.map +0 -1
  248. package/dist/index.js.map +0 -1
  249. package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
  250. package/dist/internal_context.js.map +0 -1
  251. package/dist/mcp/client.d.ts +0 -42
  252. package/dist/mcp/do-oauth-client-provider.js.map +0 -1
  253. package/dist/mcp/x402.js.map +0 -1
  254. package/dist/protocol-Dqc2MQxo.js.map +0 -1
  255. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  256. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
  257. package/dist/ws-chat-transport-CIoOBbO7.js.map +0 -1
  258. /package/dist/{cli/index.d.ts → index-BVVgDSdq.d.ts} +0 -0
@@ -0,0 +1,360 @@
1
+ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
2
+ import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
+ import { VoiceProviderError } from "./voice/errors.js";
4
+ //#region src/voice/diagnostics.ts
5
+ const MAX_STRING_LENGTH = 160;
6
+ const PRIVATE_KEY = /(^|_)(audio|body|contents?|exceptions?|messages?|prompts?|query|results?|stack|text|tokens?|tools?|transcripts?|arguments?)(_|$)/i;
7
+ function boundedString(value, maxLength = MAX_STRING_LENGTH) {
8
+ const normalized = value.replace(/\s+/g, " ").trim();
9
+ return normalized.length <= maxLength ? normalized : `${normalized.slice(0, maxLength - 1)}…`;
10
+ }
11
+ function diagnosticErrorData(error) {
12
+ const summary = {
13
+ name: boundedString(error.name || "Error"),
14
+ message: boundedString(error.message || "Unknown error")
15
+ };
16
+ if (error instanceof VoiceProviderError) {
17
+ if (error.code !== void 0) summary.code = error.code;
18
+ if (error.status !== void 0) summary.status = error.status;
19
+ if (error.closeCode !== void 0) summary.closeCode = error.closeCode;
20
+ if (error.closeReason !== void 0) summary.closeReason = boundedString(error.closeReason);
21
+ if (error.wasClean !== void 0) summary.wasClean = error.wasClean;
22
+ }
23
+ return summary;
24
+ }
25
+ /**
26
+ * Keep diagnostic metadata bounded and reject fields that could carry user or
27
+ * provider content. Instrumentation should still pass only known-safe values.
28
+ */
29
+ function sanitizeDiagnosticData(data) {
30
+ if (!data) return void 0;
31
+ const sanitized = {};
32
+ for (const [key, value] of Object.entries(data)) {
33
+ if (PRIVATE_KEY.test(key)) continue;
34
+ sanitized[key] = value instanceof Error ? diagnosticErrorData(value) : typeof value === "string" ? boundedString(value) : value;
35
+ }
36
+ return Object.keys(sanitized).length > 0 ? sanitized : void 0;
37
+ }
38
+ function createDiagnosticEvent(event, data, timestamp = Date.now()) {
39
+ const safeData = sanitizeDiagnosticData(data);
40
+ return {
41
+ event,
42
+ timestamp,
43
+ ...safeData ? { data: safeData } : {}
44
+ };
45
+ }
46
+ /** Server-only diagnostics. The sink is the reserved voice protocol message. */
47
+ var ServerDiagnostics = class {
48
+ constructor(browserConsole) {
49
+ this.browserConsole = browserConsole;
50
+ }
51
+ emit(connection, event, data) {
52
+ if (!this.browserConsole) return;
53
+ try {
54
+ connection.send(JSON.stringify({
55
+ type: "diagnostic",
56
+ ...createDiagnosticEvent(event, data)
57
+ }));
58
+ } catch {}
59
+ }
60
+ turn(connection, turnId, source = "speech", now = Date.now) {
61
+ return new TurnDiagnostics(this, connection, turnId, source, now);
62
+ }
63
+ };
64
+ function safeDuration(value) {
65
+ return Math.max(0, value);
66
+ }
67
+ var _turn = /* @__PURE__ */ new WeakMap();
68
+ var _startedAt = /* @__PURE__ */ new WeakMap();
69
+ /** One sentence attempt measured by its parent turn clock. */
70
+ var TtsSentenceTracker = class {
71
+ constructor(turn, startedAt) {
72
+ _classPrivateFieldInitSpec(this, _turn, void 0);
73
+ _classPrivateFieldInitSpec(this, _startedAt, void 0);
74
+ _classPrivateFieldSet2(_turn, this, turn);
75
+ _classPrivateFieldSet2(_startedAt, this, startedAt);
76
+ }
77
+ providerStarted() {
78
+ _classPrivateFieldGet2(_turn, this).recordTtsProviderStarted();
79
+ }
80
+ settle(outcome) {
81
+ return _classPrivateFieldGet2(_turn, this).recordTtsSentence(_classPrivateFieldGet2(_startedAt, this), outcome);
82
+ }
83
+ };
84
+ var _diagnostics = /* @__PURE__ */ new WeakMap();
85
+ var _connection = /* @__PURE__ */ new WeakMap();
86
+ var _now = /* @__PURE__ */ new WeakMap();
87
+ var _startedAt2 = /* @__PURE__ */ new WeakMap();
88
+ var _speechStartedAt = /* @__PURE__ */ new WeakMap();
89
+ var _firstInterimObserved = /* @__PURE__ */ new WeakMap();
90
+ var _finalInputAt = /* @__PURE__ */ new WeakMap();
91
+ var _firstTtsProviderAt = /* @__PURE__ */ new WeakMap();
92
+ var _firstAudioAt = /* @__PURE__ */ new WeakMap();
93
+ var _ttsFinished = /* @__PURE__ */ new WeakMap();
94
+ var _hasTtsFailures = /* @__PURE__ */ new WeakMap();
95
+ var _metrics = /* @__PURE__ */ new WeakMap();
96
+ /**
97
+ * One content-free turn lifecycle. Diagnostics and stable metrics are emitted
98
+ * from the same recorded landmarks; application metrics never parse event
99
+ * names or diagnostic metadata.
100
+ */
101
+ var TurnDiagnostics = class {
102
+ constructor(diagnostics, connection, turnId, source, now) {
103
+ _classPrivateFieldInitSpec(this, _diagnostics, void 0);
104
+ _classPrivateFieldInitSpec(this, _connection, void 0);
105
+ _classPrivateFieldInitSpec(this, _now, void 0);
106
+ _classPrivateFieldInitSpec(this, _startedAt2, void 0);
107
+ _classPrivateFieldInitSpec(this, _speechStartedAt, void 0);
108
+ _classPrivateFieldInitSpec(this, _firstInterimObserved, false);
109
+ _classPrivateFieldInitSpec(this, _finalInputAt, void 0);
110
+ _classPrivateFieldInitSpec(this, _firstTtsProviderAt, void 0);
111
+ _classPrivateFieldInitSpec(this, _firstAudioAt, void 0);
112
+ _classPrivateFieldInitSpec(this, _ttsFinished, false);
113
+ _classPrivateFieldInitSpec(this, _hasTtsFailures, false);
114
+ _classPrivateFieldInitSpec(this, _metrics, {});
115
+ _classPrivateFieldSet2(_diagnostics, this, diagnostics);
116
+ _classPrivateFieldSet2(_connection, this, connection);
117
+ _classPrivateFieldSet2(_now, this, now);
118
+ _classPrivateFieldSet2(_startedAt2, this, now());
119
+ this.turnId = turnId;
120
+ this.source = source;
121
+ }
122
+ get hasTtsFailures() {
123
+ return _classPrivateFieldGet2(_hasTtsFailures, this);
124
+ }
125
+ get ttsWorkMs() {
126
+ return _classPrivateFieldGet2(_metrics, this).ttsWorkMs ?? 0;
127
+ }
128
+ emit(event, data) {
129
+ const scopedData = {
130
+ ...data,
131
+ turn_id: this.turnId
132
+ };
133
+ _classPrivateFieldGet2(_diagnostics, this).emit(_classPrivateFieldGet2(_connection, this), event, scopedData);
134
+ }
135
+ startModel() {
136
+ return new ModelDiagnosticTracker(this, _classPrivateFieldGet2(_now, this));
137
+ }
138
+ markTextInput() {
139
+ _classPrivateFieldGet2(_finalInputAt, this) ?? _classPrivateFieldSet2(_finalInputAt, this, _classPrivateFieldGet2(_startedAt2, this));
140
+ }
141
+ speechStarted() {
142
+ _classPrivateFieldGet2(_speechStartedAt, this) ?? _classPrivateFieldSet2(_speechStartedAt, this, _classPrivateFieldGet2(_now, this).call(this));
143
+ this.emit("speech.started");
144
+ }
145
+ firstInterim(characters) {
146
+ if (_classPrivateFieldGet2(_firstInterimObserved, this)) return;
147
+ _classPrivateFieldSet2(_firstInterimObserved, this, true);
148
+ const elapsed = _classPrivateFieldGet2(_speechStartedAt, this) === void 0 ? void 0 : safeDuration(_classPrivateFieldGet2(_now, this).call(this) - _classPrivateFieldGet2(_speechStartedAt, this));
149
+ if (elapsed !== void 0) _classPrivateFieldGet2(_metrics, this).speechStartToFirstInterimMs = elapsed;
150
+ this.emit("stt.interim", {
151
+ ...characters === void 0 ? {} : { characters },
152
+ ...elapsed === void 0 ? {} : { speech_to_interim_ms: elapsed }
153
+ });
154
+ }
155
+ finalInput(characters) {
156
+ _classPrivateFieldSet2(_finalInputAt, this, _classPrivateFieldGet2(_now, this).call(this));
157
+ const elapsed = _classPrivateFieldGet2(_speechStartedAt, this) === void 0 ? void 0 : safeDuration(_classPrivateFieldGet2(_finalInputAt, this) - _classPrivateFieldGet2(_speechStartedAt, this));
158
+ if (elapsed !== void 0) _classPrivateFieldGet2(_metrics, this).speechStartToFinalMs = elapsed;
159
+ this.emit("stt.utterance", {
160
+ ...characters === void 0 ? {} : { characters },
161
+ ...elapsed === void 0 ? {} : { speech_to_final_ms: elapsed }
162
+ });
163
+ }
164
+ recordAfterTranscribe(durationMs, outcome, characters) {
165
+ _classPrivateFieldGet2(_metrics, this).afterTranscribeMs = safeDuration(durationMs);
166
+ this.emit("after_transcribe.completed", {
167
+ duration_ms: safeDuration(durationMs),
168
+ outcome,
169
+ characters
170
+ });
171
+ }
172
+ beginTtsSentence() {
173
+ _classPrivateFieldGet2(_metrics, this).ttsWorkMs ??= 0;
174
+ return new TtsSentenceTracker(this, _classPrivateFieldGet2(_now, this).call(this));
175
+ }
176
+ recordTtsProviderStarted() {
177
+ _classPrivateFieldGet2(_firstTtsProviderAt, this) ?? _classPrivateFieldSet2(_firstTtsProviderAt, this, _classPrivateFieldGet2(_now, this).call(this));
178
+ }
179
+ recordTtsSentence(startedAt, outcome) {
180
+ const duration = safeDuration(_classPrivateFieldGet2(_now, this).call(this) - startedAt);
181
+ _classPrivateFieldGet2(_metrics, this).ttsWorkMs = (_classPrivateFieldGet2(_metrics, this).ttsWorkMs ?? 0) + duration;
182
+ if (outcome === "failed") _classPrivateFieldSet2(_hasTtsFailures, this, true);
183
+ return duration;
184
+ }
185
+ finishTts() {
186
+ if (_classPrivateFieldGet2(_ttsFinished, this)) return;
187
+ _classPrivateFieldSet2(_ttsFinished, this, true);
188
+ if (_classPrivateFieldGet2(_firstTtsProviderAt, this) !== void 0) _classPrivateFieldGet2(_metrics, this).ttsWallMs = safeDuration(_classPrivateFieldGet2(_now, this).call(this) - _classPrivateFieldGet2(_firstTtsProviderAt, this));
189
+ }
190
+ audioSent() {
191
+ const now = _classPrivateFieldGet2(_now, this).call(this);
192
+ if (_classPrivateFieldGet2(_firstAudioAt, this) !== void 0) return;
193
+ _classPrivateFieldSet2(_firstAudioAt, this, now);
194
+ if (_classPrivateFieldGet2(_finalInputAt, this) !== void 0) _classPrivateFieldGet2(_metrics, this).finalInputToFirstAudioMs = safeDuration(now - _classPrivateFieldGet2(_finalInputAt, this));
195
+ if (_classPrivateFieldGet2(_firstTtsProviderAt, this) !== void 0) _classPrivateFieldGet2(_metrics, this).ttsToFirstAudioMs = safeDuration(now - _classPrivateFieldGet2(_firstTtsProviderAt, this));
196
+ }
197
+ recordModelFirstText(durationMs) {
198
+ _classPrivateFieldGet2(_metrics, this).modelToFirstTextMs = safeDuration(durationMs);
199
+ }
200
+ recordReasoning(durationMs) {
201
+ _classPrivateFieldGet2(_metrics, this).exposedReasoningMs = (_classPrivateFieldGet2(_metrics, this).exposedReasoningMs ?? 0) + safeDuration(durationMs);
202
+ }
203
+ recordModelTerminal(durationMs) {
204
+ _classPrivateFieldGet2(_metrics, this).modelStreamConsumptionMs = safeDuration(durationMs);
205
+ }
206
+ finish(outcome) {
207
+ this.finishTts();
208
+ const summary = {
209
+ turnId: this.turnId,
210
+ source: this.source,
211
+ outcome,
212
+ turnTotalMs: safeDuration(_classPrivateFieldGet2(_now, this).call(this) - _classPrivateFieldGet2(_startedAt2, this)),
213
+ ..._classPrivateFieldGet2(_metrics, this)
214
+ };
215
+ this.emit("turn.ended", {
216
+ outcome,
217
+ duration_ms: summary.turnTotalMs
218
+ });
219
+ try {
220
+ _classPrivateFieldGet2(_connection, this).send(JSON.stringify({
221
+ type: "turn_metrics",
222
+ ...summary
223
+ }));
224
+ } catch {}
225
+ return summary;
226
+ }
227
+ };
228
+ var _turn2 = /* @__PURE__ */ new WeakMap();
229
+ var _now2 = /* @__PURE__ */ new WeakMap();
230
+ var _startedAt3 = /* @__PURE__ */ new WeakMap();
231
+ var _firstTextObserved = /* @__PURE__ */ new WeakMap();
232
+ var _reasoningActive = /* @__PURE__ */ new WeakMap();
233
+ var _reasoningStartedAt = /* @__PURE__ */ new WeakMap();
234
+ var _characters = /* @__PURE__ */ new WeakMap();
235
+ var _terminal = /* @__PURE__ */ new WeakMap();
236
+ var _ModelDiagnosticTracker_brand = /* @__PURE__ */ new WeakSet();
237
+ /**
238
+ * Tracks one model stream without retaining model or reasoning content.
239
+ * Lifecycle methods are idempotent so stale turn cleanup cannot affect a
240
+ * successor tracker.
241
+ */
242
+ var ModelDiagnosticTracker = class {
243
+ constructor(turn, now) {
244
+ _classPrivateMethodInitSpec(this, _ModelDiagnosticTracker_brand);
245
+ _classPrivateFieldInitSpec(this, _turn2, void 0);
246
+ _classPrivateFieldInitSpec(this, _now2, void 0);
247
+ _classPrivateFieldInitSpec(this, _startedAt3, void 0);
248
+ _classPrivateFieldInitSpec(this, _firstTextObserved, false);
249
+ _classPrivateFieldInitSpec(this, _reasoningActive, false);
250
+ _classPrivateFieldInitSpec(this, _reasoningStartedAt, 0);
251
+ _classPrivateFieldInitSpec(this, _characters, 0);
252
+ _classPrivateFieldInitSpec(this, _terminal, false);
253
+ _classPrivateFieldSet2(_turn2, this, turn);
254
+ _classPrivateFieldSet2(_now2, this, now);
255
+ _classPrivateFieldSet2(_startedAt3, this, now());
256
+ _classPrivateFieldGet2(_turn2, this).emit("model.started");
257
+ }
258
+ observe(event) {
259
+ if (_classPrivateFieldGet2(_terminal, this)) return;
260
+ switch (event.type) {
261
+ case "text":
262
+ _classPrivateFieldSet2(_characters, this, _classPrivateFieldGet2(_characters, this) + event.text.length);
263
+ if (!_classPrivateFieldGet2(_firstTextObserved, this) && event.text.trim().length > 0) {
264
+ _classPrivateFieldSet2(_firstTextObserved, this, true);
265
+ const elapsed = safeDuration(_classPrivateFieldGet2(_now2, this).call(this) - _classPrivateFieldGet2(_startedAt3, this));
266
+ _classPrivateFieldGet2(_turn2, this).recordModelFirstText(elapsed);
267
+ _classPrivateFieldGet2(_turn2, this).emit("model.first_text", { elapsed_ms: elapsed });
268
+ }
269
+ break;
270
+ case "reasoning-start":
271
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _startReasoning).call(this);
272
+ break;
273
+ case "reasoning-end":
274
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _completeReasoning).call(this, "completed");
275
+ break;
276
+ case "finish":
277
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _completeReasoning).call(this, "stream_finished");
278
+ break;
279
+ case "error": break;
280
+ case "boundary": break;
281
+ }
282
+ }
283
+ complete(outcome, finishReason) {
284
+ if (_classPrivateFieldGet2(_terminal, this)) return;
285
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _completeReasoning).call(this, "stream_completed");
286
+ _classPrivateFieldSet2(_terminal, this, true);
287
+ const duration = this.elapsedMs();
288
+ _classPrivateFieldGet2(_turn2, this).recordModelTerminal(duration);
289
+ _classPrivateFieldGet2(_turn2, this).emit("model.completed", {
290
+ duration_ms: duration,
291
+ outcome,
292
+ characters: _classPrivateFieldGet2(_characters, this),
293
+ ...finishReason === void 0 ? {} : { finish_reason: finishReason }
294
+ });
295
+ }
296
+ fail(error) {
297
+ if (_classPrivateFieldGet2(_terminal, this)) return;
298
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _completeReasoning).call(this, "error");
299
+ _classPrivateFieldSet2(_terminal, this, true);
300
+ _classPrivateFieldGet2(_turn2, this).recordModelTerminal(this.elapsedMs());
301
+ _classPrivateFieldGet2(_turn2, this).emit("model.failed", { error });
302
+ }
303
+ abort() {
304
+ if (_classPrivateFieldGet2(_terminal, this)) return;
305
+ _assertClassBrand(_ModelDiagnosticTracker_brand, this, _completeReasoning).call(this, "aborted");
306
+ _classPrivateFieldSet2(_terminal, this, true);
307
+ _classPrivateFieldGet2(_turn2, this).recordModelTerminal(this.elapsedMs());
308
+ }
309
+ elapsedMs() {
310
+ return safeDuration(_classPrivateFieldGet2(_now2, this).call(this) - _classPrivateFieldGet2(_startedAt3, this));
311
+ }
312
+ };
313
+ function _startReasoning() {
314
+ if (_classPrivateFieldGet2(_reasoningActive, this)) return;
315
+ _classPrivateFieldSet2(_reasoningActive, this, true);
316
+ _classPrivateFieldSet2(_reasoningStartedAt, this, _classPrivateFieldGet2(_now2, this).call(this));
317
+ _classPrivateFieldGet2(_turn2, this).emit("model.reasoning_started");
318
+ }
319
+ function _completeReasoning(outcome) {
320
+ if (!_classPrivateFieldGet2(_reasoningActive, this)) return;
321
+ _classPrivateFieldSet2(_reasoningActive, this, false);
322
+ const duration = safeDuration(_classPrivateFieldGet2(_now2, this).call(this) - _classPrivateFieldGet2(_reasoningStartedAt, this));
323
+ _classPrivateFieldGet2(_turn2, this).recordReasoning(duration);
324
+ _classPrivateFieldGet2(_turn2, this).emit("model.reasoning_completed", {
325
+ duration_ms: duration,
326
+ outcome
327
+ });
328
+ }
329
+ var _enabled = /* @__PURE__ */ new WeakMap();
330
+ var _ClientDiagnostics_brand = /* @__PURE__ */ new WeakSet();
331
+ /** Browser-only diagnostics. Activation always comes from the server welcome. */
332
+ var ClientDiagnostics = class {
333
+ constructor() {
334
+ _classPrivateMethodInitSpec(this, _ClientDiagnostics_brand);
335
+ _classPrivateFieldInitSpec(this, _enabled, false);
336
+ }
337
+ setEnabled(enabled) {
338
+ _classPrivateFieldSet2(_enabled, this, enabled);
339
+ }
340
+ emit(event, data) {
341
+ if (!_classPrivateFieldGet2(_enabled, this)) return;
342
+ _assertClassBrand(_ClientDiagnostics_brand, this, _log).call(this, "client", createDiagnosticEvent(event, data));
343
+ }
344
+ receive(event) {
345
+ if (!_classPrivateFieldGet2(_enabled, this)) return;
346
+ _assertClassBrand(_ClientDiagnostics_brand, this, _log).call(this, "server", event);
347
+ }
348
+ };
349
+ function _log(origin, event) {
350
+ try {
351
+ console.info(`[voice:${origin}] ${event.event}`, {
352
+ timestamp: event.timestamp,
353
+ ...event.data ?? {}
354
+ });
355
+ } catch {}
356
+ }
357
+ //#endregion
358
+ export { ServerDiagnostics as n, ClientDiagnostics as t };
359
+
360
+ //# sourceMappingURL=diagnostics-C4jcz3VK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics-C4jcz3VK.js","names":[],"sources":["../src/voice/diagnostics.ts"],"sourcesContent":["import { VoiceProviderError } from \"./errors\";\nimport type { TextStreamEvent } from \"./text-stream\";\nimport type {\n VoiceDiagnosticEvent,\n VoiceModelFinishReason,\n VoiceTurnMetrics,\n VoiceTurnOutcome,\n VoiceTurnSource\n} from \"./types\";\n\nconst MAX_STRING_LENGTH = 160;\n\nconst PRIVATE_KEY =\n /(^|_)(audio|body|contents?|exceptions?|messages?|prompts?|query|results?|stack|text|tokens?|tools?|transcripts?|arguments?)(_|$)/i;\n\ntype DiagnosticValue = string | number | boolean | null | Error;\nexport type DiagnosticData = Record<string, DiagnosticValue>;\n\ntype DiagnosticConnection = {\n send(data: string | ArrayBuffer): void;\n};\n\nfunction boundedString(value: string, maxLength = MAX_STRING_LENGTH): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n return normalized.length <= maxLength\n ? normalized\n : `${normalized.slice(0, maxLength - 1)}…`;\n}\n\nfunction diagnosticErrorData(error: Error): Record<string, unknown> {\n const summary: Record<string, unknown> = {\n name: boundedString(error.name || \"Error\"),\n message: boundedString(error.message || \"Unknown error\")\n };\n\n if (error instanceof VoiceProviderError) {\n if (error.code !== undefined) summary.code = error.code;\n if (error.status !== undefined) summary.status = error.status;\n if (error.closeCode !== undefined) summary.closeCode = error.closeCode;\n if (error.closeReason !== undefined) {\n summary.closeReason = boundedString(error.closeReason);\n }\n if (error.wasClean !== undefined) summary.wasClean = error.wasClean;\n }\n\n return summary;\n}\n\n/**\n * Keep diagnostic metadata bounded and reject fields that could carry user or\n * provider content. Instrumentation should still pass only known-safe values.\n */\nexport function sanitizeDiagnosticData(\n data?: DiagnosticData\n): Record<string, unknown> | undefined {\n if (!data) return undefined;\n\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (PRIVATE_KEY.test(key)) continue;\n sanitized[key] =\n value instanceof Error\n ? diagnosticErrorData(value)\n : typeof value === \"string\"\n ? boundedString(value)\n : value;\n }\n\n return Object.keys(sanitized).length > 0 ? sanitized : undefined;\n}\n\nfunction createDiagnosticEvent(\n event: string,\n data?: DiagnosticData,\n timestamp = Date.now()\n): VoiceDiagnosticEvent {\n const safeData = sanitizeDiagnosticData(data);\n return {\n event,\n timestamp,\n ...(safeData ? { data: safeData } : {})\n };\n}\n\n/** Server-only diagnostics. The sink is the reserved voice protocol message. */\nexport class ServerDiagnostics {\n readonly browserConsole: boolean;\n\n constructor(browserConsole: boolean) {\n this.browserConsole = browserConsole;\n }\n\n emit(\n connection: DiagnosticConnection,\n event: string,\n data?: DiagnosticData\n ): void {\n if (!this.browserConsole) return;\n\n try {\n connection.send(\n JSON.stringify({\n type: \"diagnostic\",\n ...createDiagnosticEvent(event, data)\n })\n );\n } catch {\n // Diagnostics must never alter call behavior.\n }\n }\n\n turn(\n connection: DiagnosticConnection,\n turnId: string,\n source: VoiceTurnSource = \"speech\",\n now: () => number = Date.now\n ): TurnDiagnostics {\n return new TurnDiagnostics(this, connection, turnId, source, now);\n }\n}\n\nfunction safeDuration(value: number): number {\n return Math.max(0, value);\n}\n\nexport type TtsSentenceOutcome = \"completed\" | \"skipped\" | \"failed\";\n\n/** One sentence attempt measured by its parent turn clock. */\nexport class TtsSentenceTracker {\n #turn: TurnDiagnostics;\n #startedAt: number;\n\n constructor(turn: TurnDiagnostics, startedAt: number) {\n this.#turn = turn;\n this.#startedAt = startedAt;\n }\n\n providerStarted(): void {\n this.#turn.recordTtsProviderStarted();\n }\n\n settle(outcome: TtsSentenceOutcome): number {\n return this.#turn.recordTtsSentence(this.#startedAt, outcome);\n }\n}\n\n/**\n * One content-free turn lifecycle. Diagnostics and stable metrics are emitted\n * from the same recorded landmarks; application metrics never parse event\n * names or diagnostic metadata.\n */\nexport class TurnDiagnostics {\n readonly turnId: string;\n readonly source: VoiceTurnSource;\n #diagnostics: ServerDiagnostics;\n #connection: DiagnosticConnection;\n #now: () => number;\n #startedAt: number;\n #speechStartedAt: number | undefined;\n #firstInterimObserved = false;\n #finalInputAt: number | undefined;\n #firstTtsProviderAt: number | undefined;\n #firstAudioAt: number | undefined;\n #ttsFinished = false;\n #hasTtsFailures = false;\n #metrics: Partial<VoiceTurnMetrics> = {};\n\n constructor(\n diagnostics: ServerDiagnostics,\n connection: DiagnosticConnection,\n turnId: string,\n source: VoiceTurnSource,\n now: () => number\n ) {\n this.#diagnostics = diagnostics;\n this.#connection = connection;\n this.#now = now;\n this.#startedAt = now();\n this.turnId = turnId;\n this.source = source;\n }\n\n get hasTtsFailures(): boolean {\n return this.#hasTtsFailures;\n }\n\n get ttsWorkMs(): number {\n return this.#metrics.ttsWorkMs ?? 0;\n }\n\n emit(event: string, data?: DiagnosticData): void {\n const scopedData: DiagnosticData = {\n ...data,\n turn_id: this.turnId\n };\n this.#diagnostics.emit(this.#connection, event, scopedData);\n }\n\n startModel(): ModelDiagnosticTracker {\n return new ModelDiagnosticTracker(this, this.#now);\n }\n\n markTextInput(): void {\n this.#finalInputAt ??= this.#startedAt;\n }\n\n speechStarted(): void {\n this.#speechStartedAt ??= this.#now();\n this.emit(\"speech.started\");\n }\n\n firstInterim(characters?: number): void {\n if (this.#firstInterimObserved) return;\n this.#firstInterimObserved = true;\n const elapsed =\n this.#speechStartedAt === undefined\n ? undefined\n : safeDuration(this.#now() - this.#speechStartedAt);\n if (elapsed !== undefined) {\n this.#metrics.speechStartToFirstInterimMs = elapsed;\n }\n this.emit(\"stt.interim\", {\n ...(characters === undefined ? {} : { characters }),\n ...(elapsed === undefined ? {} : { speech_to_interim_ms: elapsed })\n });\n }\n\n finalInput(characters?: number): void {\n this.#finalInputAt = this.#now();\n const elapsed =\n this.#speechStartedAt === undefined\n ? undefined\n : safeDuration(this.#finalInputAt - this.#speechStartedAt);\n if (elapsed !== undefined) this.#metrics.speechStartToFinalMs = elapsed;\n this.emit(\"stt.utterance\", {\n ...(characters === undefined ? {} : { characters }),\n ...(elapsed === undefined ? {} : { speech_to_final_ms: elapsed })\n });\n }\n\n recordAfterTranscribe(\n durationMs: number,\n outcome: \"accepted\" | \"skipped\",\n characters: number\n ): void {\n this.#metrics.afterTranscribeMs = safeDuration(durationMs);\n this.emit(\"after_transcribe.completed\", {\n duration_ms: safeDuration(durationMs),\n outcome,\n characters\n });\n }\n\n beginTtsSentence(): TtsSentenceTracker {\n this.#metrics.ttsWorkMs ??= 0;\n return new TtsSentenceTracker(this, this.#now());\n }\n\n recordTtsProviderStarted(): void {\n this.#firstTtsProviderAt ??= this.#now();\n }\n\n recordTtsSentence(startedAt: number, outcome: TtsSentenceOutcome): number {\n const duration = safeDuration(this.#now() - startedAt);\n this.#metrics.ttsWorkMs = (this.#metrics.ttsWorkMs ?? 0) + duration;\n if (outcome === \"failed\") this.#hasTtsFailures = true;\n return duration;\n }\n\n finishTts(): void {\n if (this.#ttsFinished) return;\n this.#ttsFinished = true;\n if (this.#firstTtsProviderAt !== undefined) {\n this.#metrics.ttsWallMs = safeDuration(\n this.#now() - this.#firstTtsProviderAt\n );\n }\n }\n\n audioSent(): void {\n const now = this.#now();\n if (this.#firstAudioAt !== undefined) return;\n this.#firstAudioAt = now;\n if (this.#finalInputAt !== undefined) {\n this.#metrics.finalInputToFirstAudioMs = safeDuration(\n now - this.#finalInputAt\n );\n }\n if (this.#firstTtsProviderAt !== undefined) {\n this.#metrics.ttsToFirstAudioMs = safeDuration(\n now - this.#firstTtsProviderAt\n );\n }\n }\n\n recordModelFirstText(durationMs: number): void {\n this.#metrics.modelToFirstTextMs = safeDuration(durationMs);\n }\n\n recordReasoning(durationMs: number): void {\n this.#metrics.exposedReasoningMs =\n (this.#metrics.exposedReasoningMs ?? 0) + safeDuration(durationMs);\n }\n\n recordModelTerminal(durationMs: number): void {\n this.#metrics.modelStreamConsumptionMs = safeDuration(durationMs);\n }\n\n finish(outcome: VoiceTurnOutcome): VoiceTurnMetrics {\n this.finishTts();\n\n const summary: VoiceTurnMetrics = {\n turnId: this.turnId,\n source: this.source,\n outcome,\n turnTotalMs: safeDuration(this.#now() - this.#startedAt),\n ...this.#metrics\n };\n\n this.emit(\"turn.ended\", {\n outcome,\n duration_ms: summary.turnTotalMs\n });\n try {\n this.#connection.send(\n JSON.stringify({ type: \"turn_metrics\", ...summary })\n );\n } catch {\n // A closing connection can make the terminal summary undeliverable.\n }\n return summary;\n }\n}\n\n/**\n * Tracks one model stream without retaining model or reasoning content.\n * Lifecycle methods are idempotent so stale turn cleanup cannot affect a\n * successor tracker.\n */\nexport class ModelDiagnosticTracker {\n #turn: TurnDiagnostics;\n #now: () => number;\n #startedAt: number;\n #firstTextObserved = false;\n #reasoningActive = false;\n #reasoningStartedAt = 0;\n #characters = 0;\n #terminal = false;\n\n constructor(turn: TurnDiagnostics, now: () => number) {\n this.#turn = turn;\n this.#now = now;\n this.#startedAt = now();\n this.#turn.emit(\"model.started\");\n }\n\n observe(event: TextStreamEvent): void {\n if (this.#terminal) return;\n\n switch (event.type) {\n case \"text\":\n this.#characters += event.text.length;\n if (!this.#firstTextObserved && event.text.trim().length > 0) {\n this.#firstTextObserved = true;\n const elapsed = safeDuration(this.#now() - this.#startedAt);\n this.#turn.recordModelFirstText(elapsed);\n this.#turn.emit(\"model.first_text\", { elapsed_ms: elapsed });\n }\n break;\n case \"reasoning-start\":\n this.#startReasoning();\n break;\n case \"reasoning-end\":\n this.#completeReasoning(\"completed\");\n break;\n case \"finish\":\n this.#completeReasoning(\"stream_finished\");\n break;\n case \"error\":\n break;\n case \"boundary\":\n break;\n }\n }\n\n complete(\n outcome: \"output\" | \"no_output\",\n finishReason?: VoiceModelFinishReason\n ): void {\n if (this.#terminal) return;\n this.#completeReasoning(\"stream_completed\");\n this.#terminal = true;\n const duration = this.elapsedMs();\n this.#turn.recordModelTerminal(duration);\n this.#turn.emit(\"model.completed\", {\n duration_ms: duration,\n outcome,\n characters: this.#characters,\n ...(finishReason === undefined ? {} : { finish_reason: finishReason })\n });\n }\n\n fail(error: Error): void {\n if (this.#terminal) return;\n this.#completeReasoning(\"error\");\n this.#terminal = true;\n this.#turn.recordModelTerminal(this.elapsedMs());\n this.#turn.emit(\"model.failed\", { error });\n }\n\n abort(): void {\n if (this.#terminal) return;\n this.#completeReasoning(\"aborted\");\n this.#terminal = true;\n this.#turn.recordModelTerminal(this.elapsedMs());\n }\n\n elapsedMs(): number {\n return safeDuration(this.#now() - this.#startedAt);\n }\n\n #startReasoning(): void {\n if (this.#reasoningActive) return;\n this.#reasoningActive = true;\n this.#reasoningStartedAt = this.#now();\n this.#turn.emit(\"model.reasoning_started\");\n }\n\n #completeReasoning(outcome: string): void {\n if (!this.#reasoningActive) return;\n this.#reasoningActive = false;\n const duration = safeDuration(this.#now() - this.#reasoningStartedAt);\n this.#turn.recordReasoning(duration);\n this.#turn.emit(\"model.reasoning_completed\", {\n duration_ms: duration,\n outcome\n });\n }\n}\n\n/** Browser-only diagnostics. Activation always comes from the server welcome. */\nexport class ClientDiagnostics {\n #enabled = false;\n\n setEnabled(enabled: boolean): void {\n this.#enabled = enabled;\n }\n\n emit(event: string, data?: DiagnosticData): void {\n if (!this.#enabled) return;\n this.#log(\"client\", createDiagnosticEvent(event, data));\n }\n\n receive(event: VoiceDiagnosticEvent): void {\n if (!this.#enabled) return;\n this.#log(\"server\", event);\n }\n\n #log(origin: \"client\" | \"server\", event: VoiceDiagnosticEvent): void {\n try {\n console.info(`[voice:${origin}] ${event.event}`, {\n timestamp: event.timestamp,\n ...(event.data ?? {})\n });\n } catch {\n // Console replacements and test spies are allowed to throw.\n }\n }\n}\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import {
7
7
  StoredOAuthTokens
8
8
  } from "@modelcontextprotocol/client";
9
9
 
10
- //#region src/mcp/do-oauth-client-provider.d.ts
10
+ //#region src/mcp/client/do-oauth-client-provider.d.ts
11
11
  interface AgentMcpOAuthProvider extends OAuthClientProvider {
12
12
  authUrl: string | undefined;
13
13
  clientId: string | undefined;
@@ -107,4 +107,4 @@ export {
107
107
  DurableObjectOAuthClientProvider as r,
108
108
  AgentMcpOAuthProvider as t
109
109
  };
110
- //# sourceMappingURL=do-oauth-client-provider-VTZj2VtM.d.ts.map
110
+ //# sourceMappingURL=do-oauth-client-provider-Tmf1vgKz.d.ts.map
@@ -1,4 +1,31 @@
1
1
  //#region src/email.d.ts
2
+ /** Cloudflare Email Service binding. */
3
+ type EmailSendBinding = SendEmail;
4
+ /** Options for sending an outbound email from an Agent. */
5
+ type SendEmailOptions = {
6
+ binding: EmailSendBinding;
7
+ to: string | string[];
8
+ from:
9
+ | string
10
+ | {
11
+ email: string;
12
+ name?: string;
13
+ };
14
+ subject: string;
15
+ text?: string;
16
+ html?: string;
17
+ replyTo?:
18
+ | string
19
+ | {
20
+ email: string;
21
+ name?: string;
22
+ };
23
+ cc?: string | string[];
24
+ bcc?: string | string[];
25
+ inReplyTo?: string;
26
+ headers?: Record<string, string>;
27
+ secret?: string;
28
+ };
2
29
  /**
3
30
  * Header object as returned by postal-mime and similar email parsing libraries.
4
31
  * Each header has a lowercase key and a string value.
@@ -141,17 +168,19 @@ declare function createCatchAllEmailResolver<Env>(
141
168
  ): EmailResolver<Env>;
142
169
  //#endregion
143
170
  export {
144
- SecureReplyResolverOptions as a,
145
- createCatchAllEmailResolver as c,
146
- isAutoReplyEmail as d,
147
- signAgentHeaders as f,
171
+ EmailSendBinding as a,
172
+ SignatureFailureReason as c,
173
+ createHeaderBasedEmailResolver as d,
174
+ createSecureReplyEmailResolver as f,
148
175
  EmailResolverResult as i,
149
- createHeaderBasedEmailResolver as l,
176
+ createAddressBasedEmailResolver as l,
177
+ signAgentHeaders as m,
150
178
  EmailHeader as n,
151
- SignatureFailureReason as o,
179
+ SecureReplyResolverOptions as o,
180
+ isAutoReplyEmail as p,
152
181
  EmailResolver as r,
153
- createAddressBasedEmailResolver as s,
182
+ SendEmailOptions as s,
154
183
  DEFAULT_MAX_AGE_SECONDS as t,
155
- createSecureReplyEmailResolver as u
184
+ createCatchAllEmailResolver as u
156
185
  };
157
- //# sourceMappingURL=email-CL27preh.d.ts.map
186
+ //# sourceMappingURL=email-7TatiTnl.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { s as SendEmailOptions } from "./email-7TatiTnl.js";
2
+
3
+ //#region src/email-send.d.ts
4
+ type AgentEmailIdentity = {
5
+ agentName: string;
6
+ agentId: string;
7
+ };
8
+ /** Send with the routing and signing behavior used by `Agent.sendEmail()`. */
9
+ declare function sendAgentEmail(
10
+ options: SendEmailOptions,
11
+ identity: AgentEmailIdentity
12
+ ): Promise<EmailSendResult>;
13
+ //#endregion
14
+ export { sendAgentEmail };
15
+ //# sourceMappingURL=email-send.d.ts.map
@@ -0,0 +1,32 @@
1
+ import { signAgentHeaders } from "./email.js";
2
+ //#region src/email-send.ts
3
+ /** Send with the routing and signing behavior used by `Agent.sendEmail()`. */
4
+ async function sendAgentEmail(options, identity) {
5
+ if (!options.binding) throw new Error("binding is required. Pass your send_email binding, e.g. this.sendEmail({ binding: this.env.EMAIL, ... }).");
6
+ const headers = {
7
+ ...options.headers,
8
+ "X-Agent-Name": identity.agentName,
9
+ "X-Agent-ID": identity.agentId
10
+ };
11
+ if (options.inReplyTo) headers["In-Reply-To"] = options.inReplyTo;
12
+ if (typeof options.secret === "string") {
13
+ const signedHeaders = await signAgentHeaders(options.secret, identity.agentName, identity.agentId);
14
+ headers["X-Agent-Sig"] = signedHeaders["X-Agent-Sig"];
15
+ headers["X-Agent-Sig-Ts"] = signedHeaders["X-Agent-Sig-Ts"];
16
+ }
17
+ return options.binding.send({
18
+ from: options.from,
19
+ to: options.to,
20
+ subject: options.subject,
21
+ text: options.text,
22
+ html: options.html,
23
+ replyTo: options.replyTo,
24
+ cc: options.cc,
25
+ bcc: options.bcc,
26
+ headers
27
+ });
28
+ }
29
+ //#endregion
30
+ export { sendAgentEmail };
31
+
32
+ //# sourceMappingURL=email-send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-send.js","names":[],"sources":["../src/email-send.ts"],"sourcesContent":["import { signAgentHeaders, type SendEmailOptions } from \"./email\";\n\ntype AgentEmailIdentity = {\n agentName: string;\n agentId: string;\n};\n\n/** Send with the routing and signing behavior used by `Agent.sendEmail()`. */\nexport async function sendAgentEmail(\n options: SendEmailOptions,\n identity: AgentEmailIdentity\n): Promise<EmailSendResult> {\n if (!options.binding) {\n throw new Error(\n \"binding is required. Pass your send_email binding, \" +\n \"e.g. this.sendEmail({ binding: this.env.EMAIL, ... }).\"\n );\n }\n\n const headers: Record<string, string> = {\n ...options.headers,\n \"X-Agent-Name\": identity.agentName,\n \"X-Agent-ID\": identity.agentId\n };\n\n if (options.inReplyTo) {\n headers[\"In-Reply-To\"] = options.inReplyTo;\n }\n\n if (typeof options.secret === \"string\") {\n const signedHeaders = await signAgentHeaders(\n options.secret,\n identity.agentName,\n identity.agentId\n );\n headers[\"X-Agent-Sig\"] = signedHeaders[\"X-Agent-Sig\"];\n headers[\"X-Agent-Sig-Ts\"] = signedHeaders[\"X-Agent-Sig-Ts\"];\n }\n\n // Preserve Agent.sendEmail()'s existing optional display-name input while\n // delegating to the platform binding type, whose EmailAddress requires one.\n return options.binding.send({\n from: options.from,\n to: options.to,\n subject: options.subject,\n text: options.text,\n html: options.html,\n replyTo: options.replyTo,\n cc: options.cc,\n bcc: options.bcc,\n headers\n } as EmailMessageBuilder);\n}\n"],"mappings":";;;AAQA,eAAsB,eACpB,SACA,UAC0B;CAC1B,IAAI,CAAC,QAAQ,SACX,MAAM,IAAI,MACR,2GAEF;CAGF,MAAM,UAAkC;EACtC,GAAG,QAAQ;EACX,gBAAgB,SAAS;EACzB,cAAc,SAAS;CACzB;CAEA,IAAI,QAAQ,WACV,QAAQ,iBAAiB,QAAQ;CAGnC,IAAI,OAAO,QAAQ,WAAW,UAAU;EACtC,MAAM,gBAAgB,MAAM,iBAC1B,QAAQ,QACR,SAAS,WACT,SAAS,OACX;EACA,QAAQ,iBAAiB,cAAc;EACvC,QAAQ,oBAAoB,cAAc;CAC5C;CAIA,OAAO,QAAQ,QAAQ,KAAK;EAC1B,MAAM,QAAQ;EACd,IAAI,QAAQ;EACZ,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,MAAM,QAAQ;EACd,SAAS,QAAQ;EACjB,IAAI,QAAQ;EACZ,KAAK,QAAQ;EACb;CACF,CAAwB;AAC1B"}
package/dist/email.d.ts CHANGED
@@ -1,25 +1,29 @@
1
- import { n as AgentEmail } from "./internal_context-Dg4Cgjcu.js";
1
+ import { t as AgentEmail } from "./internal_context-BlxFEWfn.js";
2
2
  import {
3
- a as SecureReplyResolverOptions,
4
- c as createCatchAllEmailResolver,
5
- d as isAutoReplyEmail,
6
- f as signAgentHeaders,
3
+ a as EmailSendBinding,
4
+ c as SignatureFailureReason,
5
+ d as createHeaderBasedEmailResolver,
6
+ f as createSecureReplyEmailResolver,
7
7
  i as EmailResolverResult,
8
- l as createHeaderBasedEmailResolver,
8
+ l as createAddressBasedEmailResolver,
9
+ m as signAgentHeaders,
9
10
  n as EmailHeader,
10
- o as SignatureFailureReason,
11
+ o as SecureReplyResolverOptions,
12
+ p as isAutoReplyEmail,
11
13
  r as EmailResolver,
12
- s as createAddressBasedEmailResolver,
14
+ s as SendEmailOptions,
13
15
  t as DEFAULT_MAX_AGE_SECONDS,
14
- u as createSecureReplyEmailResolver
15
- } from "./email-CL27preh.js";
16
+ u as createCatchAllEmailResolver
17
+ } from "./email-7TatiTnl.js";
16
18
  export {
17
19
  type AgentEmail,
18
20
  DEFAULT_MAX_AGE_SECONDS,
19
21
  EmailHeader,
20
22
  EmailResolver,
21
23
  EmailResolverResult,
24
+ EmailSendBinding,
22
25
  SecureReplyResolverOptions,
26
+ SendEmailOptions,
23
27
  SignatureFailureReason,
24
28
  createAddressBasedEmailResolver,
25
29
  createCatchAllEmailResolver,