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.
- package/README.md +20 -1
- package/dist/{agent-routing-CnkaHb-v.d.ts → agent-routing-DE5zmCQ8.d.ts} +1038 -394
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-C0XJqWzB.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
- package/dist/agent-tools.d.ts +21 -21
- package/dist/browser/ai.js +4 -1
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
- package/dist/callable-decorator.d.ts +18 -0
- package/dist/callable-decorator.js +71 -0
- package/dist/callable-decorator.js.map +1 -0
- package/dist/capability-BjSKYpzg.js.map +1 -1
- package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
- package/dist/channel-Bnm4S7T2.d.ts +491 -0
- package/dist/channels/ai-sdk.d.ts +46 -0
- package/dist/channels/ai-sdk.js +120 -0
- package/dist/channels/ai-sdk.js.map +1 -0
- package/dist/channels/email.d.ts +95 -0
- package/dist/channels/email.js +323 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/index.d.ts +233 -0
- package/dist/channels/index.js +608 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/slack.d.ts +140 -0
- package/dist/channels/slack.js +614 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/tanstack-ai.d.ts +39 -0
- package/dist/channels/tanstack-ai.js +17 -0
- package/dist/channels/tanstack-ai.js.map +1 -0
- package/dist/channels/telegram.d.ts +106 -0
- package/dist/channels/telegram.js +427 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/voice.d.ts +45 -0
- package/dist/channels/voice.js +122 -0
- package/dist/channels/voice.js.map +1 -0
- package/dist/chat/index.d.ts +2325 -2019
- package/dist/chat/index.js +888 -518
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +7 -7
- package/dist/chat-sdk/index.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/context/index.d.ts +216 -0
- package/dist/context/index.js +454 -0
- package/dist/context/index.js.map +1 -0
- package/dist/{current-agent-CuMErtly.d.ts → current-agent-Da_C9a3b.d.ts} +90 -107
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/{diagnostics-CaBjfz4J.js → diagnostics-BzvaX2UT.js} +5 -1
- package/dist/diagnostics-BzvaX2UT.js.map +1 -0
- package/dist/diagnostics-C4jcz3VK.js +360 -0
- package/dist/diagnostics-C4jcz3VK.js.map +1 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-XDkuQ7zm.d.ts +89 -0
- package/dist/{index-DcSAZKsB.d.ts → index-YSKgfgg9.d.ts} +3 -1
- package/dist/index.d.ts +91 -82
- package/dist/index.js +3 -2
- package/dist/ingress-BfetZbMO.js +83 -0
- package/dist/ingress-BfetZbMO.js.map +1 -0
- package/dist/internal-CYlgHl1l.js +59 -0
- package/dist/internal-CYlgHl1l.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +35 -17
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle-CMRGjZdw.js +1299 -0
- package/dist/lifecycle-CMRGjZdw.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
- package/dist/retries.d.ts +8 -6
- package/dist/retries.js +13 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +137 -0
- package/dist/routing/index.js +244 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/sanitize-D9TujEK8.js +79 -0
- package/dist/sanitize-D9TujEK8.js.map +1 -0
- package/dist/scheduler-DD9NdYbF.js +665 -0
- package/dist/scheduler-DD9NdYbF.js.map +1 -0
- package/dist/{scheduler-DQoTGoAW.d.ts → scheduler-Dwh85ZGl.d.ts} +21 -22
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +441 -0
- package/dist/sessions/index.js +2063 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/skills/index.d.ts +99 -0
- package/dist/skills/index.js +254 -5
- package/dist/skills/index.js.map +1 -1
- package/dist/{src-5W6JNKVb.js → src-DlSHshb2.js} +1460 -1110
- package/dist/src-DlSHshb2.js.map +1 -0
- package/dist/streams/index.d.ts +120 -0
- package/dist/streams/index.js +107 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams-D6tJ0NN9.d.ts +370 -0
- package/dist/streams-DZKgAj9b.js +709 -0
- package/dist/streams-DZKgAj9b.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/surface-bZZJqBka.js +17 -0
- package/dist/surface-bZZJqBka.js.map +1 -0
- package/dist/tasks/index.d.ts +64 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks-BRJ5zgya.d.ts +517 -0
- package/dist/tasks-ylZgBjhj.js +1656 -0
- package/dist/tasks-ylZgBjhj.js.map +1 -0
- package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
- package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
- package/dist/text-stream-CpdiKrJB.js +272 -0
- package/dist/text-stream-CpdiKrJB.js.map +1 -0
- package/dist/tokens-nHAKcN6M.js +52 -0
- package/dist/tokens-nHAKcN6M.js.map +1 -0
- package/dist/tool-schema-CBjGPrsQ.js +31 -0
- package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-_Faxb570.d.ts +439 -0
- package/dist/voice/client.d.ts +226 -0
- package/dist/voice/client.js +932 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/errors.d.ts +43 -0
- package/dist/voice/errors.js +41 -0
- package/dist/voice/errors.js.map +1 -0
- package/dist/voice/index.d.ts +271 -0
- package/dist/voice/index.js +1812 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/react.d.ts +167 -0
- package/dist/voice/react.js +234 -0
- package/dist/voice/react.js.map +1 -0
- package/dist/voice/sfu.d.ts +71 -0
- package/dist/voice/sfu.js +157 -0
- package/dist/voice/sfu.js.map +1 -0
- package/dist/voice/text.d.ts +6 -0
- package/dist/voice/text.js +2 -0
- package/dist/voice/types.d.ts +58 -0
- package/dist/voice/types.js +18 -0
- package/dist/voice/types.js.map +1 -0
- package/dist/voice/workers-ai.d.ts +136 -0
- package/dist/voice/workers-ai.js +568 -0
- package/dist/voice/workers-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +192 -0
- package/dist/websockets/index.js +2 -0
- package/dist/websockets-DUfRHPRq.js +502 -0
- package/dist/websockets-DUfRHPRq.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +6 -13
- package/docs/context.md +131 -0
- package/docs/index.md +15 -12
- package/docs/lifecycle.md +102 -55
- package/docs/long-running-agents.md +2 -2
- package/docs/mcp-servers.md +5 -1
- package/docs/resumable-streaming.md +1 -1
- package/docs/routing.md +105 -0
- package/docs/sessions.md +237 -871
- package/docs/streams.md +213 -0
- package/docs/sub-agents.md +184 -124
- package/docs/tasks.md +246 -0
- package/docs/voice.md +745 -0
- package/package.json +115 -13
- package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
- package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
- package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
- package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
- package/dist/diagnostics-CaBjfz4J.js.map +0 -1
- package/dist/durable-object-lifecycle-D6nNQJJd.js +0 -862
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +0 -1
- package/dist/experimental/memory/session/index.d.ts +0 -671
- package/dist/experimental/memory/session/index.js +0 -2379
- package/dist/experimental/memory/session/index.js.map +0 -1
- package/dist/experimental/memory/utils/index.d.ts +0 -96
- package/dist/experimental/memory/utils/index.js +0 -79
- package/dist/experimental/memory/utils/index.js.map +0 -1
- package/dist/scheduler-CR9RHGos.js +0 -857
- package/dist/scheduler-CR9RHGos.js.map +0 -1
- package/dist/src-5W6JNKVb.js.map +0 -1
- package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
- 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 };
|