agents 0.22.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 (186) hide show
  1. package/README.md +20 -1
  2. package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
  3. package/dist/agent-routing.d.ts +1 -1
  4. package/dist/agent-tool-types.d.ts +26 -26
  5. package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
  6. package/dist/agent-tools.d.ts +21 -21
  7. package/dist/browser/ai.js +4 -1
  8. package/dist/browser/ai.js.map +1 -1
  9. package/dist/browser/tanstack-ai.js.map +1 -1
  10. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  11. package/dist/callable-decorator.d.ts +18 -0
  12. package/dist/callable-decorator.js +71 -0
  13. package/dist/callable-decorator.js.map +1 -0
  14. package/dist/capability-BjSKYpzg.js.map +1 -1
  15. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  16. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  17. package/dist/channels/ai-sdk.d.ts +46 -0
  18. package/dist/channels/ai-sdk.js +120 -0
  19. package/dist/channels/ai-sdk.js.map +1 -0
  20. package/dist/channels/email.d.ts +95 -0
  21. package/dist/channels/email.js +323 -0
  22. package/dist/channels/email.js.map +1 -0
  23. package/dist/channels/index.d.ts +233 -0
  24. package/dist/channels/index.js +608 -0
  25. package/dist/channels/index.js.map +1 -0
  26. package/dist/channels/slack.d.ts +140 -0
  27. package/dist/channels/slack.js +614 -0
  28. package/dist/channels/slack.js.map +1 -0
  29. package/dist/channels/tanstack-ai.d.ts +39 -0
  30. package/dist/channels/tanstack-ai.js +17 -0
  31. package/dist/channels/tanstack-ai.js.map +1 -0
  32. package/dist/channels/telegram.d.ts +106 -0
  33. package/dist/channels/telegram.js +427 -0
  34. package/dist/channels/telegram.js.map +1 -0
  35. package/dist/channels/voice.d.ts +45 -0
  36. package/dist/channels/voice.js +122 -0
  37. package/dist/channels/voice.js.map +1 -0
  38. package/dist/chat/index.d.ts +2325 -2019
  39. package/dist/chat/index.js +888 -518
  40. package/dist/chat/index.js.map +1 -1
  41. package/dist/chat-sdk/index.d.ts +7 -7
  42. package/dist/chat-sdk/index.js +1 -1
  43. package/dist/client.d.ts +1 -1
  44. package/dist/context/index.d.ts +216 -0
  45. package/dist/context/index.js +454 -0
  46. package/dist/context/index.js.map +1 -0
  47. package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
  48. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  49. package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
  50. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  51. package/dist/diagnostics-C4jcz3VK.js +360 -0
  52. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  53. package/dist/index-BB0kqhIz.d.ts +101 -0
  54. package/dist/index-BVVgDSdq.d.ts +1 -0
  55. package/dist/index-XDkuQ7zm.d.ts +89 -0
  56. package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
  57. package/dist/index.d.ts +91 -82
  58. package/dist/index.js +3 -2
  59. package/dist/ingress-BfetZbMO.js +83 -0
  60. package/dist/ingress-BfetZbMO.js.map +1 -0
  61. package/dist/internal-CYlgHl1l.js +59 -0
  62. package/dist/internal-CYlgHl1l.js.map +1 -0
  63. package/dist/internal_context.d.ts +1 -1
  64. package/dist/lifecycle/index.d.ts +35 -17
  65. package/dist/lifecycle/index.js +1 -1
  66. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  67. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  68. package/dist/mcp/client/index.d.ts +20 -20
  69. package/dist/mcp/index.d.ts +35 -35
  70. package/dist/mcp/index.js +1 -1
  71. package/dist/observability/index.d.ts +1 -1
  72. package/dist/observability/index.js +1 -1
  73. package/dist/react.d.ts +4 -4
  74. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  75. package/dist/retries.d.ts +8 -6
  76. package/dist/retries.js +13 -1
  77. package/dist/retries.js.map +1 -1
  78. package/dist/routing/index.d.ts +137 -0
  79. package/dist/routing/index.js +244 -0
  80. package/dist/routing/index.js.map +1 -0
  81. package/dist/sanitize-D9TujEK8.js +79 -0
  82. package/dist/sanitize-D9TujEK8.js.map +1 -0
  83. package/dist/scheduler-DD9NdYbF.js +665 -0
  84. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  85. package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
  86. package/dist/schedules/index.d.ts +1 -1
  87. package/dist/schedules/index.js +1 -1
  88. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  89. package/dist/serializable.d.ts +1 -1
  90. package/dist/sessions/index.d.ts +441 -0
  91. package/dist/sessions/index.js +2063 -0
  92. package/dist/sessions/index.js.map +1 -0
  93. package/dist/skills/index.d.ts +99 -0
  94. package/dist/skills/index.js +254 -5
  95. package/dist/skills/index.js.map +1 -1
  96. package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
  97. package/dist/src-DlSHshb2.js.map +1 -0
  98. package/dist/streams/index.d.ts +120 -0
  99. package/dist/streams/index.js +107 -0
  100. package/dist/streams/index.js.map +1 -0
  101. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  102. package/dist/streams-DZKgAj9b.js +709 -0
  103. package/dist/streams-DZKgAj9b.js.map +1 -0
  104. package/dist/sub-routing.d.ts +12 -12
  105. package/dist/surface-bZZJqBka.js +17 -0
  106. package/dist/surface-bZZJqBka.js.map +1 -0
  107. package/dist/tasks/index.d.ts +64 -0
  108. package/dist/tasks/index.js +2 -0
  109. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  110. package/dist/tasks-ylZgBjhj.js +1656 -0
  111. package/dist/tasks-ylZgBjhj.js.map +1 -0
  112. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  113. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  114. package/dist/text-stream-CpdiKrJB.js +272 -0
  115. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  116. package/dist/tokens-nHAKcN6M.js +52 -0
  117. package/dist/tokens-nHAKcN6M.js.map +1 -0
  118. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  119. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  120. package/dist/types-B7LojTe4.d.ts +202 -0
  121. package/dist/types-_Faxb570.d.ts +439 -0
  122. package/dist/voice/client.d.ts +226 -0
  123. package/dist/voice/client.js +932 -0
  124. package/dist/voice/client.js.map +1 -0
  125. package/dist/voice/errors.d.ts +43 -0
  126. package/dist/voice/errors.js +41 -0
  127. package/dist/voice/errors.js.map +1 -0
  128. package/dist/voice/index.d.ts +271 -0
  129. package/dist/voice/index.js +1812 -0
  130. package/dist/voice/index.js.map +1 -0
  131. package/dist/voice/react.d.ts +167 -0
  132. package/dist/voice/react.js +234 -0
  133. package/dist/voice/react.js.map +1 -0
  134. package/dist/voice/sfu.d.ts +71 -0
  135. package/dist/voice/sfu.js +157 -0
  136. package/dist/voice/sfu.js.map +1 -0
  137. package/dist/voice/text.d.ts +6 -0
  138. package/dist/voice/text.js +2 -0
  139. package/dist/voice/types.d.ts +58 -0
  140. package/dist/voice/types.js +18 -0
  141. package/dist/voice/types.js.map +1 -0
  142. package/dist/voice/workers-ai.d.ts +136 -0
  143. package/dist/voice/workers-ai.js +568 -0
  144. package/dist/voice/workers-ai.js.map +1 -0
  145. package/dist/websockets/index.d.ts +192 -0
  146. package/dist/websockets/index.js +2 -0
  147. package/dist/websockets-DUfRHPRq.js +502 -0
  148. package/dist/websockets-DUfRHPRq.js.map +1 -0
  149. package/dist/workflow-types.d.ts +25 -25
  150. package/dist/workflows.d.ts +21 -21
  151. package/dist/workflows.js +1 -1
  152. package/docs/agent-class.md +2 -2
  153. package/docs/agent-tools.md +2 -1
  154. package/docs/channels.md +323 -0
  155. package/docs/chat-agents.md +6 -13
  156. package/docs/context.md +131 -0
  157. package/docs/index.md +15 -12
  158. package/docs/lifecycle.md +102 -55
  159. package/docs/long-running-agents.md +2 -2
  160. package/docs/mcp-servers.md +5 -1
  161. package/docs/resumable-streaming.md +1 -1
  162. package/docs/routing.md +105 -0
  163. package/docs/sessions.md +237 -871
  164. package/docs/streams.md +213 -0
  165. package/docs/sub-agents.md +184 -124
  166. package/docs/tasks.md +246 -0
  167. package/docs/voice.md +745 -0
  168. package/package.json +115 -13
  169. package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
  170. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  171. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  172. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  173. package/dist/diagnostics-CaBjfz4J.js.map +0 -1
  174. package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
  175. package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
  176. package/dist/experimental/memory/session/index.d.ts +0 -671
  177. package/dist/experimental/memory/session/index.js +0 -2379
  178. package/dist/experimental/memory/session/index.js.map +0 -1
  179. package/dist/experimental/memory/utils/index.d.ts +0 -96
  180. package/dist/experimental/memory/utils/index.js +0 -79
  181. package/dist/experimental/memory/utils/index.js.map +0 -1
  182. package/dist/scheduler-CR9RHGos.js +0 -857
  183. package/dist/scheduler-CR9RHGos.js.map +0 -1
  184. package/dist/src-5W6JNKVb.js.map +0 -1
  185. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  186. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workers-ai.js","names":[],"sources":["../../src/voice/workers-ai.ts"],"sourcesContent":["/**\n * Workers AI provider implementations for the voice pipeline.\n *\n * These are convenience classes that wrap the Workers AI binding\n * (env.AI) for STT and TTS. They are not required — any object\n * satisfying the provider interfaces works.\n */\n\nimport { logVoiceError, toVoiceError, VoiceProviderError } from \"./errors\";\nimport type {\n TTSProvider,\n Transcriber,\n TranscriberSession,\n TranscriberSessionOptions\n} from \"./types\";\n\n// --- Loose AI binding type ---\n\n/** Loose type for the Workers AI binding — avoids hard dependency on @cloudflare/workers-types. */\ninterface AiLike {\n run(\n model: string,\n input: Record<string, unknown>,\n options?: Record<string, unknown>\n ): Promise<unknown>;\n}\n\n// --- TTS ---\n\nexport interface WorkersAITTSOptions {\n /** TTS model name. @default \"@cf/deepgram/aura-1\" */\n model?: string;\n /** TTS speaker voice. @default \"asteria\" */\n speaker?: string;\n}\n\n/**\n * Workers AI text-to-speech provider.\n *\n * @example\n * ```ts\n * class MyAgent extends VoiceAgent<Env> {\n * tts = new WorkersAITTS(this.env.AI);\n * }\n * ```\n */\nexport class WorkersAITTS implements TTSProvider {\n #ai: AiLike;\n #model: string;\n #speaker: string;\n\n constructor(ai: AiLike, options?: WorkersAITTSOptions) {\n this.#ai = ai;\n this.#model = options?.model ?? \"@cf/deepgram/aura-1\";\n this.#speaker = options?.speaker ?? \"asteria\";\n }\n\n async synthesize(\n text: string,\n signal?: AbortSignal\n ): Promise<ArrayBuffer | null> {\n const response = (await this.#ai.run(\n this.#model,\n { text, speaker: this.#speaker },\n { returnRawResponse: true, ...(signal ? { signal } : {}) }\n )) as Response;\n\n // Without this check an error body (e.g. a 429 quota JSON) would be\n // forwarded to the client as audio bytes and fail to decode silently.\n if (!response.ok) {\n logVoiceError({\n component: \"WorkersAITTS\",\n stage: \"synthesize\",\n message: \"Workers AI TTS request failed\",\n error: new VoiceProviderError(\"Workers AI TTS request failed\", {\n status: response.status\n })\n });\n return null;\n }\n\n return await response.arrayBuffer();\n }\n}\n\n// --- Flux continuous STT ---\n\nexport interface WorkersAIFluxSTTOptions {\n /** End-of-turn confidence threshold (0.5-0.9). @default 0.7 */\n eotThreshold?: number;\n /**\n * Eager end-of-turn threshold (0.3-0.9). When set, enables\n * EagerEndOfTurn and TurnResumed events for speculative processing.\n */\n eagerEotThreshold?: number;\n /** EOT timeout in milliseconds. @default 5000 */\n eotTimeoutMs?: number;\n /** Keyterms to boost recognition of specialized terminology. */\n keyterms?: string[];\n /** Sample rate in Hz. @default 16000 */\n sampleRate?: number;\n}\n\n/**\n * Workers AI continuous speech-to-text provider using the Flux model.\n *\n * Flux is a conversational STT model with built-in end-of-turn detection.\n * A single session is created per call and receives all audio continuously.\n * The model detects speech boundaries and fires `onUtterance` when a\n * turn is complete — no client-side silence detection needed for STT.\n *\n * Recommended for `withVoice` (conversational voice agents).\n *\n * @example\n * ```ts\n * import { Agent } from \"agents\";\n * import { withVoice, WorkersAIFluxSTT, WorkersAITTS } from \"agents/voice\";\n *\n * const VoiceAgent = withVoice(Agent);\n *\n * class MyAgent extends VoiceAgent<Env> {\n * transcriber = new WorkersAIFluxSTT(this.env.AI);\n * tts = new WorkersAITTS(this.env.AI);\n *\n * async onTurn(transcript, context) { ... }\n * }\n * ```\n */\nexport class WorkersAIFluxSTT implements Transcriber {\n #ai: AiLike;\n #sampleRate: number;\n #eotThreshold: number | undefined;\n #eagerEotThreshold: number | undefined;\n #eotTimeoutMs: number | undefined;\n #keyterms: string[] | undefined;\n\n constructor(ai: AiLike, options?: WorkersAIFluxSTTOptions) {\n this.#ai = ai;\n this.#sampleRate = options?.sampleRate ?? 16000;\n this.#eotThreshold = options?.eotThreshold;\n this.#eagerEotThreshold = options?.eagerEotThreshold;\n this.#eotTimeoutMs = options?.eotTimeoutMs;\n this.#keyterms = options?.keyterms;\n }\n\n createSession(options?: TranscriberSessionOptions): TranscriberSession {\n return new FluxSession(\n this.#ai,\n {\n sampleRate: this.#sampleRate,\n eotThreshold: this.#eotThreshold,\n eagerEotThreshold: this.#eagerEotThreshold,\n eotTimeoutMs: this.#eotTimeoutMs,\n keyterms: this.#keyterms\n },\n options\n );\n }\n}\n\ninterface FluxSessionConfig {\n sampleRate: number;\n eotThreshold?: number;\n eagerEotThreshold?: number;\n eotTimeoutMs?: number;\n keyterms?: string[];\n}\n\ninterface FluxEvent {\n event:\n | \"Update\"\n | \"StartOfTurn\"\n | \"EagerEndOfTurn\"\n | \"TurnResumed\"\n | \"EndOfTurn\";\n sequence_id?: number;\n transcript?: string;\n}\n\n/**\n * Per-call Flux transcription session. Lives for the entire call.\n *\n * Handles multi-turn conversations: on EndOfTurn, fires onUtterance\n * and resets transcript state for the next turn. On StartOfTurn,\n * clears accumulated text. The session stays alive across turns\n * and is only closed on end_call or disconnect.\n */\nclass FluxSession implements TranscriberSession {\n #onInterim: TranscriberSessionOptions[\"onInterim\"];\n #onSpeechStart: TranscriberSessionOptions[\"onSpeechStart\"];\n #onUtterance: TranscriberSessionOptions[\"onUtterance\"];\n #onFatalError: TranscriberSessionOptions[\"onFatalError\"];\n\n #ws: WebSocket | null = null;\n #connected = false;\n #closed = false;\n #fatalReported = false;\n\n #pendingChunks: ArrayBuffer[] = [];\n #currentTranscript = \"\";\n\n #ready: Promise<void>;\n #resolveReady: (() => void) | null = null;\n #rejectReady: ((reason: unknown) => void) | null = null;\n\n constructor(\n ai: AiLike,\n config: FluxSessionConfig,\n options?: TranscriberSessionOptions\n ) {\n this.#onInterim = options?.onInterim;\n this.#onSpeechStart = options?.onSpeechStart;\n this.#onUtterance = options?.onUtterance;\n this.#onFatalError = options?.onFatalError;\n this.#ready = new Promise<void>((resolve, reject) => {\n this.#resolveReady = resolve;\n this.#rejectReady = reject;\n });\n this.#ready.catch(() => {});\n this.#connect(ai, config);\n }\n\n waitUntilReady(): Promise<void> {\n return this.#ready;\n }\n\n async #connect(ai: AiLike, config: FluxSessionConfig): Promise<void> {\n try {\n const input: Record<string, unknown> = {\n encoding: \"linear16\",\n sample_rate: String(config.sampleRate)\n };\n if (config.eotThreshold != null)\n input.eot_threshold = String(config.eotThreshold);\n if (config.eagerEotThreshold != null)\n input.eager_eot_threshold = String(config.eagerEotThreshold);\n if (config.eotTimeoutMs != null)\n input.eot_timeout_ms = String(config.eotTimeoutMs);\n if (config.keyterms?.length) input.keyterm = config.keyterms;\n\n const resp = await ai.run(\"@cf/deepgram/flux\", input, {\n websocket: true\n });\n\n if (this.#closed) {\n const ws = (resp as { webSocket?: WebSocket }).webSocket;\n if (ws) {\n ws.accept();\n ws.close();\n }\n this.#resolveReadiness();\n return;\n }\n\n const ws = (resp as { webSocket?: WebSocket }).webSocket;\n if (!ws) {\n const error = new Error(\n \"Workers AI Flux STT did not return a WebSocket\"\n );\n logVoiceError({\n component: \"FluxSTT\",\n stage: \"connection\",\n message: \"Flux STT WebSocket upgrade failed\",\n error\n });\n this.#reportFatal(error);\n this.#rejectReadiness(error);\n return;\n }\n\n ws.accept();\n this.#ws = ws;\n this.#connected = true;\n\n ws.addEventListener(\"message\", (event: MessageEvent) => {\n this.#handleMessage(event);\n });\n\n ws.addEventListener(\"close\", () => {\n this.#connected = false;\n if (this.#closed) return;\n const error = new Error(\n \"Workers AI Flux STT WebSocket closed unexpectedly\"\n );\n logVoiceError({\n component: \"FluxSTT\",\n stage: \"websocket_close\",\n message: \"Flux STT WebSocket closed unexpectedly\",\n error\n });\n this.#reportFatal(error);\n });\n\n ws.addEventListener(\"error\", (event: Event) => {\n const error = new Error(\"Workers AI Flux STT WebSocket error\", {\n cause: event\n });\n logVoiceError({\n component: \"FluxSTT\",\n stage: \"websocket\",\n message: \"Flux STT WebSocket error\",\n error\n });\n this.#connected = false;\n this.#reportFatal(error);\n });\n\n for (const chunk of this.#pendingChunks) {\n ws.send(chunk);\n }\n this.#pendingChunks = [];\n this.#resolveReadiness();\n } catch (error) {\n const voiceError = toVoiceError(error, \"Flux STT connection failed\");\n logVoiceError({\n component: \"FluxSTT\",\n stage: \"connection\",\n message: \"Flux STT connection failed\",\n error: voiceError\n });\n this.#reportFatal(voiceError);\n this.#rejectReadiness(voiceError);\n }\n }\n\n feed(chunk: ArrayBuffer): void {\n if (this.#closed) return;\n\n if (this.#connected && this.#ws) {\n this.#ws.send(chunk);\n } else {\n this.#pendingChunks.push(chunk);\n }\n }\n\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n this.#pendingChunks = [];\n if (this.#ws) {\n try {\n this.#ws.close();\n } catch {\n // ignore close errors\n }\n this.#ws = null;\n }\n this.#connected = false;\n this.#resolveReadiness();\n }\n\n #resolveReadiness(): void {\n const resolve = this.#resolveReady;\n if (!resolve) return;\n this.#resolveReady = null;\n this.#rejectReady = null;\n resolve();\n }\n\n #rejectReadiness(reason: unknown): void {\n const reject = this.#rejectReady;\n if (!reject) return;\n this.#resolveReady = null;\n this.#rejectReady = null;\n reject(reason);\n }\n\n #reportFatal(error: Error): void {\n if (this.#closed || this.#fatalReported) return;\n this.#fatalReported = true;\n this.#onFatalError?.(error);\n }\n\n #handleMessage(event: MessageEvent): void {\n if (this.#closed) return;\n\n try {\n const data: FluxEvent =\n typeof event.data === \"string\" ? JSON.parse(event.data) : null;\n\n if (!data || !data.event) return;\n\n const transcript = data.transcript ?? \"\";\n\n switch (data.event) {\n case \"StartOfTurn\":\n this.#currentTranscript = \"\";\n this.#onSpeechStart?.(transcript || undefined);\n if (transcript) {\n this.#currentTranscript = transcript;\n this.#onInterim?.(transcript);\n }\n break;\n\n case \"Update\":\n if (transcript) {\n this.#currentTranscript = transcript;\n this.#onInterim?.(transcript);\n }\n break;\n\n case \"EndOfTurn\": {\n const finalTranscript = transcript || this.#currentTranscript;\n this.#currentTranscript = \"\";\n if (finalTranscript) {\n this.#onUtterance?.(finalTranscript);\n }\n break;\n }\n\n case \"EagerEndOfTurn\":\n if (transcript) {\n this.#currentTranscript = transcript;\n this.#onInterim?.(transcript);\n }\n break;\n\n case \"TurnResumed\":\n this.#currentTranscript = transcript;\n if (transcript) {\n this.#onInterim?.(transcript);\n }\n break;\n }\n } catch {\n // Ignore non-JSON or malformed messages\n }\n }\n}\n\n// --- Nova 3 continuous STT ---\n\nexport interface WorkersAINova3STTOptions {\n /** Language code. @default \"en\" */\n language?: string;\n /** Endpointing silence duration in ms. @default 300 */\n endpointingMs?: number;\n /** Utterance end detection timeout in ms. @default 1000 */\n utteranceEndMs?: number;\n /** Enable smart formatting (numbers, dates, etc.). @default true */\n smartFormat?: boolean;\n /** Enable punctuation. @default true */\n punctuate?: boolean;\n /** Keyterms to boost recognition of specialized terminology. */\n keyterms?: string[];\n /** Sample rate in Hz. @default 16000 */\n sampleRate?: number;\n}\n\n/**\n * Workers AI continuous speech-to-text provider using Nova 3.\n *\n * Nova 3 is a high-accuracy STT model with streaming WebSocket support.\n * A single session is created per call and receives all audio continuously.\n * Server-side VAD events and endpointing handle speech boundary detection.\n *\n * Recommended for `withVoiceInput` (dictation / voice input UIs).\n *\n * @example\n * ```ts\n * import { Agent } from \"agents\";\n * import { withVoiceInput, WorkersAINova3STT } from \"agents/voice\";\n *\n * const InputAgent = withVoiceInput(Agent);\n *\n * class MyAgent extends InputAgent<Env> {\n * transcriber = new WorkersAINova3STT(this.env.AI);\n *\n * onTranscript(text, connection) { ... }\n * }\n * ```\n */\nexport class WorkersAINova3STT implements Transcriber {\n #ai: AiLike;\n #sampleRate: number;\n #language: string;\n #endpointingMs: number;\n #utteranceEndMs: number;\n #smartFormat: boolean;\n #punctuate: boolean;\n #keyterms: string[] | undefined;\n\n constructor(ai: AiLike, options?: WorkersAINova3STTOptions) {\n this.#ai = ai;\n this.#sampleRate = options?.sampleRate ?? 16000;\n this.#language = options?.language ?? \"en\";\n this.#endpointingMs = options?.endpointingMs ?? 300;\n this.#utteranceEndMs = options?.utteranceEndMs ?? 1000;\n this.#smartFormat = options?.smartFormat ?? true;\n this.#punctuate = options?.punctuate ?? true;\n this.#keyterms = options?.keyterms;\n }\n\n createSession(options?: TranscriberSessionOptions): TranscriberSession {\n return new Nova3Session(\n this.#ai,\n {\n sampleRate: this.#sampleRate,\n language: this.#language,\n endpointingMs: this.#endpointingMs,\n utteranceEndMs: this.#utteranceEndMs,\n smartFormat: this.#smartFormat,\n punctuate: this.#punctuate,\n keyterms: this.#keyterms\n },\n options\n );\n }\n}\n\ninterface Nova3SessionConfig {\n sampleRate: number;\n language: string;\n endpointingMs: number;\n utteranceEndMs: number;\n smartFormat: boolean;\n punctuate: boolean;\n keyterms?: string[];\n}\n\ninterface Nova3Result {\n type: string;\n channel?: {\n alternatives?: Array<{\n transcript?: string;\n }>;\n };\n is_final?: boolean;\n speech_final?: boolean;\n}\n\n/**\n * Per-call Nova 3 transcription session. Lives for the entire call.\n *\n * Uses Nova 3's endpointing and VAD events to detect utterance\n * boundaries. When a result arrives with `speech_final: true`,\n * the accumulated finalized segments are emitted as an utterance.\n */\nclass Nova3Session implements TranscriberSession {\n #onInterim: ((text: string) => void) | undefined;\n #onUtterance: ((text: string) => void) | undefined;\n #onFatalError: TranscriberSessionOptions[\"onFatalError\"];\n\n #ws: WebSocket | null = null;\n #connected = false;\n #closed = false;\n #fatalReported = false;\n\n #pendingChunks: ArrayBuffer[] = [];\n #ready: Promise<void>;\n #resolveReady: (() => void) | null = null;\n #rejectReady: ((reason: unknown) => void) | null = null;\n\n #finalizedSegments: string[] = [];\n\n constructor(\n ai: AiLike,\n config: Nova3SessionConfig,\n options?: TranscriberSessionOptions\n ) {\n this.#onInterim = options?.onInterim;\n this.#onUtterance = options?.onUtterance;\n this.#onFatalError = options?.onFatalError;\n this.#ready = new Promise<void>((resolve, reject) => {\n this.#resolveReady = resolve;\n this.#rejectReady = reject;\n });\n this.#ready.catch(() => {});\n this.#connect(ai, config);\n }\n\n waitUntilReady(): Promise<void> {\n return this.#ready;\n }\n\n async #connect(ai: AiLike, config: Nova3SessionConfig): Promise<void> {\n try {\n const input: Record<string, unknown> = {\n encoding: \"linear16\",\n sample_rate: String(config.sampleRate),\n language: config.language,\n interim_results: \"true\",\n vad_events: \"true\",\n endpointing: String(config.endpointingMs),\n utterance_end_ms: String(config.utteranceEndMs),\n smart_format: String(config.smartFormat),\n punctuate: String(config.punctuate)\n };\n if (config.keyterms?.length) input.keyterm = config.keyterms;\n\n const resp = await ai.run(\"@cf/deepgram/nova-3\", input, {\n websocket: true\n });\n\n if (this.#closed) {\n const ws = (resp as { webSocket?: WebSocket }).webSocket;\n if (ws) {\n ws.accept();\n ws.close();\n }\n this.#resolveReadiness();\n return;\n }\n\n const ws = (resp as { webSocket?: WebSocket }).webSocket;\n if (!ws) {\n const error = new Error(\n \"Workers AI Nova-3 STT did not return a WebSocket\"\n );\n logVoiceError({\n component: \"Nova3STT\",\n stage: \"connection\",\n message: \"Nova-3 STT WebSocket upgrade failed\",\n error\n });\n this.#reportFatal(error);\n this.#rejectReadiness(error);\n return;\n }\n\n ws.accept();\n this.#ws = ws;\n this.#connected = true;\n\n ws.addEventListener(\"message\", (event: MessageEvent) => {\n this.#handleMessage(event);\n });\n\n ws.addEventListener(\"close\", () => {\n this.#connected = false;\n if (this.#closed) return;\n const error = new Error(\n \"Workers AI Nova-3 STT WebSocket closed unexpectedly\"\n );\n logVoiceError({\n component: \"Nova3STT\",\n stage: \"websocket_close\",\n message: \"Nova-3 STT WebSocket closed unexpectedly\",\n error\n });\n this.#reportFatal(error);\n });\n\n ws.addEventListener(\"error\", (event: Event) => {\n const error = new Error(\"Workers AI Nova-3 STT WebSocket error\", {\n cause: event\n });\n logVoiceError({\n component: \"Nova3STT\",\n stage: \"websocket\",\n message: \"Nova-3 STT WebSocket error\",\n error\n });\n this.#connected = false;\n this.#reportFatal(error);\n });\n\n for (const chunk of this.#pendingChunks) {\n ws.send(chunk);\n }\n this.#pendingChunks = [];\n this.#resolveReadiness();\n } catch (error) {\n const voiceError = toVoiceError(error, \"Nova-3 STT connection failed\");\n logVoiceError({\n component: \"Nova3STT\",\n stage: \"connection\",\n message: \"Nova-3 STT connection failed\",\n error: voiceError\n });\n this.#reportFatal(voiceError);\n this.#rejectReadiness(voiceError);\n }\n }\n\n feed(chunk: ArrayBuffer): void {\n if (this.#closed) return;\n\n if (this.#connected && this.#ws) {\n this.#ws.send(chunk);\n } else {\n this.#pendingChunks.push(chunk);\n }\n }\n\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n this.#pendingChunks = [];\n if (this.#ws) {\n try {\n this.#ws.close();\n } catch {\n // ignore close errors\n }\n this.#ws = null;\n }\n this.#connected = false;\n this.#resolveReadiness();\n }\n\n #resolveReadiness(): void {\n const resolve = this.#resolveReady;\n if (!resolve) return;\n this.#resolveReady = null;\n this.#rejectReady = null;\n resolve();\n }\n\n #rejectReadiness(reason: unknown): void {\n const reject = this.#rejectReady;\n if (!reject) return;\n this.#resolveReady = null;\n this.#rejectReady = null;\n reject(reason);\n }\n\n #reportFatal(error: Error): void {\n if (this.#closed || this.#fatalReported) return;\n this.#fatalReported = true;\n this.#onFatalError?.(error);\n }\n\n #handleMessage(event: MessageEvent): void {\n if (this.#closed) return;\n\n try {\n const data: Nova3Result =\n typeof event.data === \"string\" ? JSON.parse(event.data) : null;\n\n if (!data) return;\n\n if (data.type === \"Results\") {\n const transcript = data.channel?.alternatives?.[0]?.transcript ?? \"\";\n\n if (data.is_final && transcript) {\n this.#finalizedSegments.push(transcript);\n }\n\n if (data.speech_final) {\n const fullTranscript = this.#finalizedSegments.join(\" \").trim();\n this.#finalizedSegments = [];\n if (fullTranscript) {\n this.#onUtterance?.(fullTranscript);\n }\n } else if (!data.is_final && transcript) {\n const display =\n this.#finalizedSegments.length > 0\n ? this.#finalizedSegments.join(\" \") + \" \" + transcript\n : transcript;\n this.#onInterim?.(display);\n }\n }\n } catch {\n // Ignore non-JSON or malformed messages\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ import {
2
+ b as Connection,
3
+ r as CapabilityWebSocketUpgradeContext,
4
+ s as LifecycleCapability,
5
+ w as WSMessage,
6
+ x as ConnectionContext
7
+ } from "../capability-runner-Be_-PLR1.js";
8
+ import { RpcTarget } from "cloudflare:workers";
9
+
10
+ //#region src/websockets/options.d.ts
11
+ /** A frame delivered on a capability-owned WebSocket connection. */
12
+ type WebSocketMessage = WSMessage;
13
+ /**
14
+ * Connection handlers for the WebSockets capability. Handlers run inside
15
+ * the host invocation boundary with the live connection in ambient
16
+ * context (`getCurrentAgent().connection`).
17
+ *
18
+ * @experimental The API surface may change before stabilizing.
19
+ */
20
+ type WebSocketHandlers = {
21
+ /** Handle a newly accepted hibernating WebSocket connection. */ onConnect?(
22
+ connection: Connection,
23
+ ctx: ConnectionContext
24
+ ): void | Promise<void> /** Handle a message from a hibernating WebSocket connection. */;
25
+ onMessage?(
26
+ connection: Connection,
27
+ message: WebSocketMessage
28
+ ): void | Promise<void> /** Handle a closing hibernating WebSocket connection. */;
29
+ onClose?(
30
+ connection: Connection,
31
+ code: number,
32
+ reason: string,
33
+ wasClean: boolean
34
+ ): void | Promise<void> /** Handle a mid-connection WebSocket error. */;
35
+ onError?(connection: Connection, error: unknown): void | Promise<void>;
36
+ };
37
+ /**
38
+ * Configuration for the WebSockets capability.
39
+ *
40
+ * @experimental The API surface may change before stabilizing.
41
+ */
42
+ interface WebSocketsOptions {
43
+ /**
44
+ * Connection handlers for WebSocket clients. When present, the
45
+ * capability claims WebSocket upgrades and owns those connections end
46
+ * to end. When absent, upgrades are declined.
47
+ */
48
+ readonly handlers?: WebSocketHandlers;
49
+ /**
50
+ * An `RpcTarget` whose methods are exposed to remote callers over a
51
+ * Cap'n Web session (`?__agents_rpc=capnweb`). The target's prototype
52
+ * methods are the complete remote interface. Methods run through the
53
+ * host invocation boundary and may return a `ReadableStream` to
54
+ * stream results.
55
+ */
56
+ readonly callables?: RpcTarget;
57
+ /**
58
+ * Tags attached to each accepted connection, queryable through
59
+ * `getConnections(tag)`. The connection id is always the first tag.
60
+ */
61
+ readonly getConnectionTags?: (
62
+ connection: Connection,
63
+ ctx: ConnectionContext
64
+ ) => string[] | Promise<string[]>;
65
+ }
66
+ //#endregion
67
+ //#region src/websockets/websockets.d.ts
68
+ /**
69
+ * Opt-in WebSocket support for Lifecycle Objects.
70
+ *
71
+ * Lifecycle itself does not model WebSockets — hosts that want them
72
+ * install this capability, which owns the connection subsystem end to
73
+ * end: it claims upgrades, accepts hibernating sockets, dispatches
74
+ * `onConnect`/`onMessage`/`onClose` inside the host invocation
75
+ * boundary, reciprocates close handshakes, and answers
76
+ * `getConnections()`/`getConnection()`.
77
+ *
78
+ * ```ts
79
+ * class Room extends DurableObject<Env> {
80
+ * readonly webSockets = new WebSockets({
81
+ * handlers: {
82
+ * onConnect: (connection) => connection.send("welcome"),
83
+ * onMessage: (connection, message) => { ... },
84
+ * onClose: (connection, code) => { ... }
85
+ * },
86
+ * callables: new RoomCallables()
87
+ * });
88
+ * readonly lifecycle = Lifecycle.install(this).use(this.webSockets);
89
+ * }
90
+ * ```
91
+ *
92
+ * `callables` exposes an `RpcTarget`'s prototype methods to remote
93
+ * callers over a Cap'n Web session claimed from `?__agents_rpc=capnweb`
94
+ * upgrades. Methods run through the host invocation boundary, may
95
+ * return a `ReadableStream` to stream results, and emit
96
+ * `rpc`/`rpc:error` capability events. Callable sessions are
97
+ * non-hibernating: while a client holds one open, the Durable Object
98
+ * stays pinned in memory.
99
+ *
100
+ * There is no separate browser client: against an `Agent`, the
101
+ * `useAgent` hook's `stub`/`call` reach the same interface over the
102
+ * protocol socket. A plain host's endpoint is reached with capnweb
103
+ * directly — `newWebSocketRpcSession(new WebSocket(callablesRpcUrl(url)))`.
104
+ *
105
+ * @experimental The API surface may change before stabilizing.
106
+ */
107
+ declare class WebSockets extends LifecycleCapability {
108
+ #private;
109
+ constructor(options?: WebSocketsOptions);
110
+ /** Claim callables RPC upgrades and, with handlers, plain upgrades. */
111
+ onWebSocketUpgrade({
112
+ request
113
+ }: CapabilityWebSocketUpgradeContext):
114
+ | Promise<Response>
115
+ | Response
116
+ | undefined;
117
+ /** Dispatch a platform message wake for a capability-owned socket. */
118
+ onWebSocketMessage(
119
+ ws: WebSocket,
120
+ message: WebSocketMessage
121
+ ): Promise<boolean>;
122
+ /** Dispatch and reciprocate a close wake for an owned socket. */
123
+ onWebSocketClose(
124
+ ws: WebSocket,
125
+ code: number,
126
+ reason: string,
127
+ wasClean: boolean
128
+ ): Promise<boolean>;
129
+ /** Dispatch an error wake for an owned socket. */
130
+ onWebSocketError(ws: WebSocket, error: unknown): Promise<boolean>;
131
+ /**
132
+ * Close every owned connection during explicit host destruction. The
133
+ * capability owns its sockets' lifetimes, so it also owns tearing
134
+ * them down.
135
+ */
136
+ dispose(): void;
137
+ /** Open connections accepted by this capability, optionally by tag. */
138
+ getConnections<TState = unknown>(
139
+ tag?: string
140
+ ): IterableIterator<Connection<TState>>;
141
+ /** One connection accepted by this capability, by id. */
142
+ getConnection<TState = unknown>(id: string): Connection<TState> | undefined;
143
+ }
144
+ //#endregion
145
+ //#region src/websockets/callables-target.d.ts
146
+ /**
147
+ * Build a callables target from a host's `@callable()`-decorated
148
+ * methods — the fallback interface source when no `RpcTarget` is
149
+ * configured (an explicit target is preferred and wins).
150
+ *
151
+ * Methods are resolved on the host at call time, so framework wrapping
152
+ * applied after construction (e.g. Agent's context auto-wrapping) is
153
+ * honored. Methods registered with `streaming: true` expect the legacy
154
+ * Agent RPC protocol's injected `StreamingResponse` and are not exposed
155
+ * here — return a `ReadableStream` from an `RpcTarget` method instead.
156
+ *
157
+ * @param host - The object whose decorated methods form the interface.
158
+ * @returns A target exposing the decorated methods, or `undefined`
159
+ * when the host has none.
160
+ */
161
+ declare function callablesFromDecorated(host: object): RpcTarget | undefined;
162
+ //#endregion
163
+ //#region src/websockets/protocol.d.ts
164
+ /**
165
+ * Isomorphic pieces of the callables RPC wire contract.
166
+ *
167
+ * Imported from browser bundles (via the client) and from the Worker
168
+ * runtime, so it must not import `cloudflare:workers`.
169
+ */
170
+ /** Query parameter selecting the callables Cap'n Web RPC endpoint. */
171
+ declare const CALLABLES_RPC_QUERY = "__agents_rpc";
172
+ declare const CALLABLES_RPC_VALUE = "capnweb";
173
+ /** Whether a request is a WebSocket upgrade addressed to callables RPC. */
174
+ declare function isCallablesRpcUpgrade(request: Request): boolean;
175
+ /**
176
+ * Derive the callables RPC socket URL from a host route. Accepts http(s)
177
+ * or ws(s) URLs and returns a ws(s) URL with the RPC query parameter set.
178
+ */
179
+ declare function callablesRpcUrl(url: string | URL): string;
180
+ //#endregion
181
+ export {
182
+ CALLABLES_RPC_QUERY,
183
+ CALLABLES_RPC_VALUE,
184
+ type WebSocketHandlers,
185
+ type WebSocketMessage,
186
+ WebSockets,
187
+ type WebSocketsOptions,
188
+ callablesFromDecorated,
189
+ callablesRpcUrl,
190
+ isCallablesRpcUpgrade
191
+ };
192
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ import { a as isCallablesRpcUpgrade, i as callablesRpcUrl, n as CALLABLES_RPC_QUERY, o as callablesFromDecorated, r as CALLABLES_RPC_VALUE, t as WebSockets } from "../websockets-DUfRHPRq.js";
2
+ export { CALLABLES_RPC_QUERY, CALLABLES_RPC_VALUE, WebSockets, callablesFromDecorated, callablesRpcUrl, isCallablesRpcUpgrade };