agents 0.22.0 → 0.24.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-B2XLNMxq.d.ts} +1094 -443
- 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-Dj5Mzlw7.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 → capability-B4WbF81e.js} +2 -1
- package/dist/capability-B4WbF81e.js.map +1 -0
- package/dist/capability-runner-BUBa6Ake.d.ts +484 -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 +2319 -2010
- package/dist/chat/index.js +892 -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-BxdkCuVy.d.ts +411 -0
- package/dist/client-C9DAjZIY.js +518 -0
- package/dist/client-C9DAjZIY.js.map +1 -0
- package/dist/{client-jagG8a9_.js → client-fyQrLGkD.js} +2 -2
- package/dist/{client-jagG8a9_.js.map → client-fyQrLGkD.js.map} +1 -1
- package/dist/client.d.ts +27 -283
- package/dist/client.js +2 -274
- 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-C4w86kcN.d.ts +93 -0
- 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/durable-object-lifecycle-ei7M7lqB.d.ts +157 -0
- package/dist/index-BB0kqhIz.d.ts +101 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-Dlgtd3Mj.d.ts +78 -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 +92 -83
- package/dist/index.js +4 -3
- 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 +39 -19
- package/dist/lifecycle/index.js +2 -2
- package/dist/lifecycle-Mm_jQh7r.js +1314 -0
- package/dist/lifecycle-Mm_jQh7r.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +2 -2
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/queue/index.d.ts +123 -0
- package/dist/queue/index.js +2 -0
- package/dist/queue-BC9F5cUo.js +406 -0
- package/dist/queue-BC9F5cUo.js.map +1 -0
- package/dist/react.d.ts +34 -16
- package/dist/react.js +31 -8
- package/dist/react.js.map +1 -1
- package/dist/{retries-CAvxtG9d.d.ts → retries-D9B2UCq3.d.ts} +23 -6
- package/dist/retries.d.ts +10 -6
- package/dist/retries.js +21 -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-DQoTGoAW.d.ts → scheduler-BGq6M5Kd.d.ts} +20 -21
- package/dist/scheduler-D_KHqxBa.js +658 -0
- package/dist/scheduler-D_KHqxBa.js.map +1 -0
- 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-BNU3ZiJM.js} +1524 -1441
- package/dist/src-BNU3ZiJM.js.map +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/index.js +137 -0
- package/dist/state/index.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-BcE8JP2X.d.ts +370 -0
- package/dist/streams-CCPRV6dt.js +709 -0
- package/dist/streams-CCPRV6dt.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-D4nLqVSI.js +1656 -0
- package/dist/tasks-D4nLqVSI.js.map +1 -0
- package/dist/tasks-V2lCT8ZV.d.ts +517 -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/transport-protocol-BxyngQ_R.js +25 -0
- package/dist/transport-protocol-BxyngQ_R.js.map +1 -0
- package/dist/transport-protocol-ZTew5Wso.d.ts +27 -0
- package/dist/types-B7LojTe4.d.ts +202 -0
- package/dist/types-DCD6BNZH.d.ts +70 -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 +301 -0
- package/dist/websockets/index.js +3 -0
- package/dist/websockets-D7IzWbZb.js +1005 -0
- package/dist/websockets-D7IzWbZb.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 +4 -4
- package/docs/agent-tools.md +2 -1
- package/docs/channels.md +323 -0
- package/docs/chat-agents.md +6 -13
- package/docs/client-sdk.md +30 -0
- package/docs/context.md +131 -0
- package/docs/index.md +16 -13
- package/docs/lifecycle.md +179 -57
- package/docs/long-running-agents.md +2 -2
- package/docs/mcp-servers.md +5 -1
- package/docs/queue.md +135 -241
- package/docs/resumable-streaming.md +1 -1
- package/docs/retries.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 +126 -14
- package/dist/capability-BjSKYpzg.js.map +0 -1
- package/dist/capability-runner-CvHGZqUu.d.ts +0 -150
- package/dist/client.js.map +0 -1
- 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/current-agent-CuMErtly.d.ts +0 -283
- 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":";;;;;;;;;;;;;;;;;;;;;;;;AA8CA,IAAa,eAAb,MAAiD;CAK/C,YAAY,IAAY,SAA+B;;;;EACrD,uBAAA,KAAA,MAAW,EAAA;EACX,uBAAA,QAAA,MAAc,SAAS,SAAS,qBAAA;EAChC,uBAAA,UAAA,MAAgB,SAAS,WAAW,SAAA;CACtC;CAEA,MAAM,WACJ,MACA,QAC6B;EAC7B,MAAM,WAAY,MAAA,uBAAA,KAAM,IAAA,CAAA,CAAS,IAAA,uBAAA,QAC/B,IAAA,GACA;GAAE;GAAM,SAAA,uBAAA,UAAS,IAAA;EAAc,GAC/B;GAAE,mBAAmB;GAAM,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAAG,CAC3D;EAIA,IAAI,CAAC,SAAS,IAAI;GAChB,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT,OAAO,IAAI,mBAAmB,iCAAiC,EAC7D,QAAQ,SAAS,OACnB,CAAC;GACH,CAAC;GACD,OAAO;EACT;EAEA,OAAO,MAAM,SAAS,YAAY;CACpC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAa,mBAAb,MAAqD;CAQnD,YAAY,IAAY,SAAmC;;;;;;;EACzD,uBAAA,MAAA,MAAW,EAAA;EACX,uBAAA,aAAA,MAAmB,SAAS,cAAc,IAAA;EAC1C,uBAAA,eAAA,MAAqB,SAAS,YAAA;EAC9B,uBAAA,oBAAA,MAA0B,SAAS,iBAAA;EACnC,uBAAA,eAAA,MAAqB,SAAS,YAAA;EAC9B,uBAAA,WAAA,MAAiB,SAAS,QAAA;CAC5B;CAEA,cAAc,SAAyD;EACrE,OAAO,IAAI,YAAA,uBAAA,MACT,IAAA,GACA;GACE,YAAA,uBAAA,aAAY,IAAA;GACZ,cAAA,uBAAA,eAAc,IAAA;GACd,mBAAA,uBAAA,oBAAmB,IAAA;GACnB,cAAA,uBAAA,eAAc,IAAA;GACd,UAAA,uBAAA,WAAU,IAAA;EACZ,GACA,OACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAM,cAAN,MAAgD;CAkB9C,YACE,IACA,QACA,SACA;;;;;;wCAhBsB,IAAA;+CACX,KAAA;4CACH,KAAA;mDACO,KAAA;mDAEe,CAAC,CAAA;uDACZ,EAAA;;kDAGgB,IAAA;iDACc,IAAA;EAOjD,uBAAA,YAAA,MAAkB,SAAS,SAAA;EAC3B,uBAAA,gBAAA,MAAsB,SAAS,aAAA;EAC/B,uBAAA,cAAA,MAAoB,SAAS,WAAA;EAC7B,uBAAA,eAAA,MAAqB,SAAS,YAAA;EAC9B,uBAAA,QAAA,MAAc,IAAI,SAAe,SAAS,WAAW;GACnD,uBAAA,eAAA,MAAqB,OAAA;GACrB,uBAAA,cAAA,MAAoB,MAAA;EACtB,CAAC,CAAA;EACD,uBAAA,QAAA,IAAA,CAAA,CAAY,YAAY,CAAC,CAAC;EAC1B,kBAAA,oBAAA,MAAA,QAAA,CAAA,CAAA,KAAA,MAAc,IAAI,MAAM;CAC1B;CAEA,iBAAgC;EAC9B,OAAA,uBAAA,QAAO,IAAA;CACT;CAqGA,KAAK,OAA0B;EAC7B,IAAA,uBAAA,SAAI,IAAA,GAAc;EAElB,IAAA,uBAAA,YAAI,IAAA,KAAA,uBAAA,KAAmB,IAAA,GACrB,uBAAA,KAAA,IAAA,CAAA,CAAS,KAAK,KAAK;OAEnB,uBAAA,gBAAA,IAAA,CAAA,CAAoB,KAAK,KAAK;CAElC;CAEA,QAAc;EACZ,IAAA,uBAAA,SAAI,IAAA,GAAc;EAClB,uBAAA,SAAA,MAAe,IAAA;EACf,uBAAA,gBAAA,MAAsB,CAAC,CAAA;EACvB,IAAA,uBAAA,KAAI,IAAA,GAAU;GACZ,IAAI;IACF,uBAAA,KAAA,IAAA,CAAA,CAAS,MAAM;GACjB,QAAQ,CAER;GACA,uBAAA,KAAA,MAAW,IAAA;EACb;EACA,uBAAA,YAAA,MAAkB,KAAA;EAClB,kBAAA,oBAAA,MAAA,iBAAA,CAAA,CAAA,KAAA,IAAuB;CACzB;AA+EF;AA1ME,eAAA,SAAe,IAAY,QAA0C;CACnE,IAAI;EACF,MAAM,QAAiC;GACrC,UAAU;GACV,aAAa,OAAO,OAAO,UAAU;EACvC;EACA,IAAI,OAAO,gBAAgB,MACzB,MAAM,gBAAgB,OAAO,OAAO,YAAY;EAClD,IAAI,OAAO,qBAAqB,MAC9B,MAAM,sBAAsB,OAAO,OAAO,iBAAiB;EAC7D,IAAI,OAAO,gBAAgB,MACzB,MAAM,iBAAiB,OAAO,OAAO,YAAY;EACnD,IAAI,OAAO,UAAU,QAAQ,MAAM,UAAU,OAAO;EAEpD,MAAM,OAAO,MAAM,GAAG,IAAI,qBAAqB,OAAO,EACpD,WAAW,KACb,CAAC;EAED,IAAA,uBAAA,SAAI,IAAA,GAAc;GAChB,MAAM,KAAM,KAAmC;GAC/C,IAAI,IAAI;IACN,GAAG,OAAO;IACV,GAAG,MAAM;GACX;GACA,kBAAA,oBAAA,MAAA,iBAAA,CAAA,CAAA,KAAA,IAAuB;GACvB;EACF;EAEA,MAAM,KAAM,KAAmC;EAC/C,IAAI,CAAC,IAAI;GACP,MAAM,wBAAQ,IAAI,MAChB,gDACF;GACA,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,kBAAA,oBAAA,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;GACvB,kBAAA,oBAAA,MAAA,gBAAA,CAAA,CAAA,KAAA,MAAsB,KAAK;GAC3B;EACF;EAEA,GAAG,OAAO;EACV,uBAAA,KAAA,MAAW,EAAA;EACX,uBAAA,YAAA,MAAkB,IAAA;EAElB,GAAG,iBAAiB,YAAY,UAAwB;GACtD,kBAAA,oBAAA,MAAA,cAAA,CAAA,CAAA,KAAA,MAAoB,KAAK;EAC3B,CAAC;EAED,GAAG,iBAAiB,eAAe;GACjC,uBAAA,YAAA,MAAkB,KAAA;GAClB,IAAA,uBAAA,SAAI,IAAA,GAAc;GAClB,MAAM,wBAAQ,IAAI,MAChB,mDACF;GACA,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,kBAAA,oBAAA,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;EACzB,CAAC;EAED,GAAG,iBAAiB,UAAU,UAAiB;GAC7C,MAAM,QAAQ,IAAI,MAAM,uCAAuC,EAC7D,OAAO,MACT,CAAC;GACD,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,uBAAA,YAAA,MAAkB,KAAA;GAClB,kBAAA,oBAAA,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;EACzB,CAAC;EAED,KAAK,MAAM,SAAA,uBAAA,gBAAS,IAAA,GAClB,GAAG,KAAK,KAAK;EAEf,uBAAA,gBAAA,MAAsB,CAAC,CAAA;EACvB,kBAAA,oBAAA,MAAA,iBAAA,CAAA,CAAA,KAAA,IAAuB;CACzB,SAAS,OAAO;EACd,MAAM,aAAa,aAAa,OAAO,4BAA4B;EACnE,cAAc;GACZ,WAAW;GACX,OAAO;GACP,SAAS;GACT,OAAO;EACT,CAAC;EACD,kBAAA,oBAAA,MAAA,YAAA,CAAA,CAAA,KAAA,MAAkB,UAAU;EAC5B,kBAAA,oBAAA,MAAA,gBAAA,CAAA,CAAA,KAAA,MAAsB,UAAU;CAClC;AACF;AA4BA,SAAA,oBAA0B;CACxB,MAAM,UAAA,uBAAA,eAAU,IAAA;CAChB,IAAI,CAAC,SAAS;CACd,uBAAA,eAAA,MAAqB,IAAA;CACrB,uBAAA,cAAA,MAAoB,IAAA;CACpB,QAAQ;AACV;AAEA,SAAA,iBAAiB,QAAuB;CACtC,MAAM,SAAA,uBAAA,cAAS,IAAA;CACf,IAAI,CAAC,QAAQ;CACb,uBAAA,eAAA,MAAqB,IAAA;CACrB,uBAAA,cAAA,MAAoB,IAAA;CACpB,OAAO,MAAM;AACf;AAEA,SAAA,aAAa,OAAoB;CAC/B,IAAA,uBAAA,SAAI,IAAA,KAAA,uBAAA,gBAAgB,IAAA,GAAqB;CACzC,uBAAA,gBAAA,MAAsB,IAAA;CACtB,uBAAA,eAAA,IAAA,CAAA,EAAA,KAAA,MAAqB,KAAK;AAC5B;AAEA,SAAA,eAAe,OAA2B;CACxC,IAAA,uBAAA,SAAI,IAAA,GAAc;CAElB,IAAI;EACF,MAAM,OACJ,OAAO,MAAM,SAAS,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI;EAE5D,IAAI,CAAC,QAAQ,CAAC,KAAK,OAAO;EAE1B,MAAM,aAAa,KAAK,cAAc;EAEtC,QAAQ,KAAK,OAAb;GACE,KAAK;IACH,uBAAA,oBAAA,MAA0B,EAAA;IAC1B,uBAAA,gBAAA,IAAA,CAAA,EAAA,KAAA,MAAsB,cAAc,KAAA,CAAS;IAC7C,IAAI,YAAY;KACd,uBAAA,oBAAA,MAA0B,UAAA;KAC1B,uBAAA,YAAA,IAAA,CAAA,EAAA,KAAA,MAAkB,UAAU;IAC9B;IACA;GAEF,KAAK;IACH,IAAI,YAAY;KACd,uBAAA,oBAAA,MAA0B,UAAA;KAC1B,uBAAA,YAAA,IAAA,CAAA,EAAA,KAAA,MAAkB,UAAU;IAC9B;IACA;GAEF,KAAK,aAAa;IAChB,MAAM,kBAAkB,cAAA,uBAAA,oBAAc,IAAA;IACtC,uBAAA,oBAAA,MAA0B,EAAA;IAC1B,IAAI,iBACF,uBAAA,cAAA,IAAA,CAAA,EAAA,KAAA,MAAoB,eAAe;IAErC;GACF;GAEA,KAAK;IACH,IAAI,YAAY;KACd,uBAAA,oBAAA,MAA0B,UAAA;KAC1B,uBAAA,YAAA,IAAA,CAAA,EAAA,KAAA,MAAkB,UAAU;IAC9B;IACA;GAEF,KAAK;IACH,uBAAA,oBAAA,MAA0B,UAAA;IAC1B,IAAI,YACF,uBAAA,YAAA,IAAA,CAAA,EAAA,KAAA,MAAkB,UAAU;IAE9B;EACJ;CACF,QAAQ,CAER;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CF,IAAa,oBAAb,MAAsD;CAUpD,YAAY,IAAY,SAAoC;;;;;;;;;EAC1D,uBAAA,MAAA,MAAW,EAAA;EACX,uBAAA,cAAA,MAAmB,SAAS,cAAc,IAAA;EAC1C,uBAAA,WAAA,MAAiB,SAAS,YAAY,IAAA;EACtC,uBAAA,gBAAA,MAAsB,SAAS,iBAAiB,GAAA;EAChD,uBAAA,iBAAA,MAAuB,SAAS,kBAAkB,GAAA;EAClD,uBAAA,cAAA,MAAoB,SAAS,eAAe,IAAA;EAC5C,uBAAA,YAAA,MAAkB,SAAS,aAAa,IAAA;EACxC,uBAAA,YAAA,MAAiB,SAAS,QAAA;CAC5B;CAEA,cAAc,SAAyD;EACrE,OAAO,IAAI,aAAA,uBAAA,MACT,IAAA,GACA;GACE,YAAA,uBAAA,cAAY,IAAA;GACZ,UAAA,uBAAA,WAAU,IAAA;GACV,eAAA,uBAAA,gBAAe,IAAA;GACf,gBAAA,uBAAA,iBAAgB,IAAA;GAChB,aAAA,uBAAA,cAAa,IAAA;GACb,WAAA,uBAAA,YAAW,IAAA;GACX,UAAA,uBAAA,YAAU,IAAA;EACZ,GACA,OACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,eAAN,MAAiD;CAiB/C,YACE,IACA,QACA,SACA;;;;;yCAhBsB,IAAA;gDACX,KAAA;6CACH,KAAA;oDACO,KAAA;oDAEe,CAAC,CAAA;;mDAEI,IAAA;kDACc,IAAA;uDAEpB,CAAC,CAAA;EAO9B,uBAAA,aAAA,MAAkB,SAAS,SAAA;EAC3B,uBAAA,eAAA,MAAoB,SAAS,WAAA;EAC7B,uBAAA,gBAAA,MAAqB,SAAS,YAAA;EAC9B,uBAAA,SAAA,MAAc,IAAI,SAAe,SAAS,WAAW;GACnD,uBAAA,gBAAA,MAAqB,OAAA;GACrB,uBAAA,eAAA,MAAoB,MAAA;EACtB,CAAC,CAAA;EACD,uBAAA,SAAA,IAAA,CAAA,CAAY,YAAY,CAAC,CAAC;EAC1B,kBAAA,qBAAA,MAAA,SAAA,CAAA,CAAA,KAAA,MAAc,IAAI,MAAM;CAC1B;CAEA,iBAAgC;EAC9B,OAAA,uBAAA,SAAO,IAAA;CACT;CAsGA,KAAK,OAA0B;EAC7B,IAAA,uBAAA,UAAI,IAAA,GAAc;EAElB,IAAA,uBAAA,aAAI,IAAA,KAAA,uBAAA,MAAmB,IAAA,GACrB,uBAAA,MAAA,IAAA,CAAA,CAAS,KAAK,KAAK;OAEnB,uBAAA,iBAAA,IAAA,CAAA,CAAoB,KAAK,KAAK;CAElC;CAEA,QAAc;EACZ,IAAA,uBAAA,UAAI,IAAA,GAAc;EAClB,uBAAA,UAAA,MAAe,IAAA;EACf,uBAAA,iBAAA,MAAsB,CAAC,CAAA;EACvB,IAAA,uBAAA,MAAI,IAAA,GAAU;GACZ,IAAI;IACF,uBAAA,MAAA,IAAA,CAAA,CAAS,MAAM;GACjB,QAAQ,CAER;GACA,uBAAA,MAAA,MAAW,IAAA;EACb;EACA,uBAAA,aAAA,MAAkB,KAAA;EAClB,kBAAA,qBAAA,MAAA,kBAAA,CAAA,CAAA,KAAA,IAAuB;CACzB;AA0DF;AAtLE,eAAA,UAAe,IAAY,QAA2C;CACpE,IAAI;EACF,MAAM,QAAiC;GACrC,UAAU;GACV,aAAa,OAAO,OAAO,UAAU;GACrC,UAAU,OAAO;GACjB,iBAAiB;GACjB,YAAY;GACZ,aAAa,OAAO,OAAO,aAAa;GACxC,kBAAkB,OAAO,OAAO,cAAc;GAC9C,cAAc,OAAO,OAAO,WAAW;GACvC,WAAW,OAAO,OAAO,SAAS;EACpC;EACA,IAAI,OAAO,UAAU,QAAQ,MAAM,UAAU,OAAO;EAEpD,MAAM,OAAO,MAAM,GAAG,IAAI,uBAAuB,OAAO,EACtD,WAAW,KACb,CAAC;EAED,IAAA,uBAAA,UAAI,IAAA,GAAc;GAChB,MAAM,KAAM,KAAmC;GAC/C,IAAI,IAAI;IACN,GAAG,OAAO;IACV,GAAG,MAAM;GACX;GACA,kBAAA,qBAAA,MAAA,kBAAA,CAAA,CAAA,KAAA,IAAuB;GACvB;EACF;EAEA,MAAM,KAAM,KAAmC;EAC/C,IAAI,CAAC,IAAI;GACP,MAAM,wBAAQ,IAAI,MAChB,kDACF;GACA,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,kBAAA,qBAAA,MAAA,aAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;GACvB,kBAAA,qBAAA,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAsB,KAAK;GAC3B;EACF;EAEA,GAAG,OAAO;EACV,uBAAA,MAAA,MAAW,EAAA;EACX,uBAAA,aAAA,MAAkB,IAAA;EAElB,GAAG,iBAAiB,YAAY,UAAwB;GACtD,kBAAA,qBAAA,MAAA,eAAA,CAAA,CAAA,KAAA,MAAoB,KAAK;EAC3B,CAAC;EAED,GAAG,iBAAiB,eAAe;GACjC,uBAAA,aAAA,MAAkB,KAAA;GAClB,IAAA,uBAAA,UAAI,IAAA,GAAc;GAClB,MAAM,wBAAQ,IAAI,MAChB,qDACF;GACA,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,kBAAA,qBAAA,MAAA,aAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;EACzB,CAAC;EAED,GAAG,iBAAiB,UAAU,UAAiB;GAC7C,MAAM,QAAQ,IAAI,MAAM,yCAAyC,EAC/D,OAAO,MACT,CAAC;GACD,cAAc;IACZ,WAAW;IACX,OAAO;IACP,SAAS;IACT;GACF,CAAC;GACD,uBAAA,aAAA,MAAkB,KAAA;GAClB,kBAAA,qBAAA,MAAA,aAAA,CAAA,CAAA,KAAA,MAAkB,KAAK;EACzB,CAAC;EAED,KAAK,MAAM,SAAA,uBAAA,iBAAS,IAAA,GAClB,GAAG,KAAK,KAAK;EAEf,uBAAA,iBAAA,MAAsB,CAAC,CAAA;EACvB,kBAAA,qBAAA,MAAA,kBAAA,CAAA,CAAA,KAAA,IAAuB;CACzB,SAAS,OAAO;EACd,MAAM,aAAa,aAAa,OAAO,8BAA8B;EACrE,cAAc;GACZ,WAAW;GACX,OAAO;GACP,SAAS;GACT,OAAO;EACT,CAAC;EACD,kBAAA,qBAAA,MAAA,aAAA,CAAA,CAAA,KAAA,MAAkB,UAAU;EAC5B,kBAAA,qBAAA,MAAA,iBAAA,CAAA,CAAA,KAAA,MAAsB,UAAU;CAClC;AACF;AA4BA,SAAA,qBAA0B;CACxB,MAAM,UAAA,uBAAA,gBAAU,IAAA;CAChB,IAAI,CAAC,SAAS;CACd,uBAAA,gBAAA,MAAqB,IAAA;CACrB,uBAAA,eAAA,MAAoB,IAAA;CACpB,QAAQ;AACV;AAEA,SAAA,kBAAiB,QAAuB;CACtC,MAAM,SAAA,uBAAA,eAAS,IAAA;CACf,IAAI,CAAC,QAAQ;CACb,uBAAA,gBAAA,MAAqB,IAAA;CACrB,uBAAA,eAAA,MAAoB,IAAA;CACpB,OAAO,MAAM;AACf;AAEA,SAAA,cAAa,OAAoB;CAC/B,IAAA,uBAAA,UAAI,IAAA,KAAA,uBAAA,iBAAgB,IAAA,GAAqB;CACzC,uBAAA,iBAAA,MAAsB,IAAA;CACtB,uBAAA,gBAAA,IAAA,CAAA,EAAA,KAAA,MAAqB,KAAK;AAC5B;AAEA,SAAA,gBAAe,OAA2B;CACxC,IAAA,uBAAA,UAAI,IAAA,GAAc;CAElB,IAAI;EACF,MAAM,OACJ,OAAO,MAAM,SAAS,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI;EAE5D,IAAI,CAAC,MAAM;EAEX,IAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,aAAa,KAAK,SAAS,eAAe,EAAE,EAAE,cAAc;GAElE,IAAI,KAAK,YAAY,YACnB,uBAAA,oBAAA,IAAA,CAAA,CAAwB,KAAK,UAAU;GAGzC,IAAI,KAAK,cAAc;IACrB,MAAM,iBAAA,uBAAA,oBAAiB,IAAA,CAAA,CAAwB,KAAK,GAAG,CAAC,CAAC,KAAK;IAC9D,uBAAA,oBAAA,MAA0B,CAAC,CAAA;IAC3B,IAAI,gBACF,uBAAA,eAAA,IAAA,CAAA,EAAA,KAAA,MAAoB,cAAc;GAEtC,OAAO,IAAI,CAAC,KAAK,YAAY,YAAY;IACvC,MAAM,UAAA,uBAAA,oBACJ,IAAA,CAAA,CAAwB,SAAS,IAAA,uBAAA,oBAC7B,IAAA,CAAA,CAAwB,KAAK,GAAG,IAAI,MAAM,aAC1C;IACN,uBAAA,aAAA,IAAA,CAAA,EAAA,KAAA,MAAkB,OAAO;GAC3B;EACF;CACF,QAAQ,CAER;AACF"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import {
|
|
2
|
+
S as ConnectionContext,
|
|
3
|
+
T as WSMessage,
|
|
4
|
+
r as CapabilityWebSocketUpgradeContext,
|
|
5
|
+
s as LifecycleCapability,
|
|
6
|
+
x as Connection
|
|
7
|
+
} from "../capability-runner-BUBa6Ake.js";
|
|
8
|
+
import {
|
|
9
|
+
a as capnWebTransportUrl,
|
|
10
|
+
n as CAPNWEB_TRANSPORT_QUERY,
|
|
11
|
+
o as isCapnWebTransportUpgrade,
|
|
12
|
+
r as CAPNWEB_TRANSPORT_VALUE,
|
|
13
|
+
t as AgentTransport
|
|
14
|
+
} from "../transport-protocol-ZTew5Wso.js";
|
|
15
|
+
import { RpcTarget } from "cloudflare:workers";
|
|
16
|
+
|
|
17
|
+
//#region src/websockets/options.d.ts
|
|
18
|
+
/**
|
|
19
|
+
* The part of a `State` capability the WebSockets capability uses. A
|
|
20
|
+
* structural port, so any `State<T>` fits without a cast and the
|
|
21
|
+
* capability never depends on the class itself.
|
|
22
|
+
*/
|
|
23
|
+
type SyncedState = {
|
|
24
|
+
/** Current state, or `undefined` when nothing is stored. */ get(): unknown /** Validate and persist a change; throws when the host rejects it. */;
|
|
25
|
+
set(nextState: never, source: Connection): void;
|
|
26
|
+
};
|
|
27
|
+
/** A frame delivered on a capability-owned WebSocket connection. */
|
|
28
|
+
type WebSocketMessage = WSMessage;
|
|
29
|
+
/**
|
|
30
|
+
* Connection handlers for the WebSockets capability. Handlers run inside
|
|
31
|
+
* the host invocation boundary with the live connection in ambient
|
|
32
|
+
* context (`getCurrentAgent().connection`).
|
|
33
|
+
*
|
|
34
|
+
* @experimental The API surface may change before stabilizing.
|
|
35
|
+
*/
|
|
36
|
+
type WebSocketHandlers = {
|
|
37
|
+
/** Handle a newly accepted hibernating WebSocket connection. */ onConnect?(
|
|
38
|
+
connection: Connection,
|
|
39
|
+
ctx: ConnectionContext
|
|
40
|
+
): void | Promise<void> /** Handle a message from a hibernating WebSocket connection. */;
|
|
41
|
+
onMessage?(
|
|
42
|
+
connection: Connection,
|
|
43
|
+
message: WebSocketMessage
|
|
44
|
+
): void | Promise<void> /** Handle a closing hibernating WebSocket connection. */;
|
|
45
|
+
onClose?(
|
|
46
|
+
connection: Connection,
|
|
47
|
+
code: number,
|
|
48
|
+
reason: string,
|
|
49
|
+
wasClean: boolean
|
|
50
|
+
): void | Promise<void> /** Handle a mid-connection WebSocket error. */;
|
|
51
|
+
onError?(connection: Connection, error: unknown): void | Promise<void>;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Configuration for the WebSockets capability.
|
|
55
|
+
*
|
|
56
|
+
* @experimental The API surface may change before stabilizing.
|
|
57
|
+
*/
|
|
58
|
+
interface WebSocketsOptions {
|
|
59
|
+
/**
|
|
60
|
+
* Connection handlers for WebSocket clients. The capability accepts and
|
|
61
|
+
* tracks every WebSocket upgrade either way; handlers add behavior on
|
|
62
|
+
* connect, message, close and error.
|
|
63
|
+
*/
|
|
64
|
+
readonly handlers?: WebSocketHandlers;
|
|
65
|
+
/**
|
|
66
|
+
* An `RpcTarget` whose prototype methods are the host's complete remote
|
|
67
|
+
* interface, reached through `useAgent().call` and `.stub`. On the
|
|
68
|
+
* `cf-websocket` wire they are answered as JSON `rpc` frames. On the
|
|
69
|
+
* `capnweb` wire they are native Cap'n Web methods on the session root:
|
|
70
|
+
* an `RpcTarget` result becomes a live stub, a `ReadableStream` streams,
|
|
71
|
+
* and calls pipeline. Methods run through the host invocation boundary
|
|
72
|
+
* with the calling connection in scope. `Agent` answers its own
|
|
73
|
+
* decorated methods on the JSON wire and does not set this.
|
|
74
|
+
*/
|
|
75
|
+
readonly callables?: RpcTarget;
|
|
76
|
+
/**
|
|
77
|
+
* Whether a new connection gets the connect-time protocol frames —
|
|
78
|
+
* identity (`cf_agent_identity`), then the current state when `state`
|
|
79
|
+
* is set — and whether protocol frames reach it at all.
|
|
80
|
+
*
|
|
81
|
+
* - `true` (default): every connection.
|
|
82
|
+
* - a function: decided per connection at accept time. `false` marks
|
|
83
|
+
* the connection no-protocol: it gets no protocol text frames, on
|
|
84
|
+
* connect or via `broadcastState()`, but can still send and receive
|
|
85
|
+
* ordinary messages and use callables. For binary-only clients.
|
|
86
|
+
* - `false`: the host drives the connect sequence itself with
|
|
87
|
+
* `sendIdentity()` and `sendState()`, and applies client state frames
|
|
88
|
+
* with `applyStateFrame()` — `Agent` does this, since it must decide
|
|
89
|
+
* whether a connection belongs to a facet before any frame is sent.
|
|
90
|
+
*/
|
|
91
|
+
readonly protocol?:
|
|
92
|
+
| boolean
|
|
93
|
+
| ((connection: Connection, ctx: ConnectionContext) => boolean);
|
|
94
|
+
/**
|
|
95
|
+
* Decide at accept time whether a connection is readonly. A readonly
|
|
96
|
+
* connection's `cf_agent_state` frames are refused with
|
|
97
|
+
* `cf_agent_state_error`; everything else works. Also settable later
|
|
98
|
+
* with `setReadonly()`.
|
|
99
|
+
*/
|
|
100
|
+
readonly readonly?: (
|
|
101
|
+
connection: Connection,
|
|
102
|
+
ctx: ConnectionContext
|
|
103
|
+
) => boolean;
|
|
104
|
+
/**
|
|
105
|
+
* A {@link SyncedState} — normally a `State` capability — to sync over
|
|
106
|
+
* connections. The capability pushes the current value to each new
|
|
107
|
+
* connection after identity and applies `cf_agent_state` frames a
|
|
108
|
+
* client sends: a readonly connection is refused, and a change the
|
|
109
|
+
* host's validator rejects is answered with `cf_agent_state_error`.
|
|
110
|
+
* Broadcasting a change is the state owner's call — wire the `State`'s
|
|
111
|
+
* `onChanged` to `broadcastState(source)`. Install the same instance on
|
|
112
|
+
* the lifecycle so it owns storage and validation; without this option
|
|
113
|
+
* state is never sent or accepted over connections.
|
|
114
|
+
*/
|
|
115
|
+
readonly state?: SyncedState;
|
|
116
|
+
/**
|
|
117
|
+
* Tags attached to each accepted connection, queryable through
|
|
118
|
+
* `getConnections(tag)`. The connection id is always the first tag.
|
|
119
|
+
*/
|
|
120
|
+
readonly getConnectionTags?: (
|
|
121
|
+
connection: Connection,
|
|
122
|
+
ctx: ConnectionContext
|
|
123
|
+
) => string[] | Promise<string[]>;
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/websockets/websockets.d.ts
|
|
127
|
+
/**
|
|
128
|
+
* Opt-in WebSocket support for Lifecycle Objects.
|
|
129
|
+
*
|
|
130
|
+
* Lifecycle itself does not model WebSockets — hosts that want them
|
|
131
|
+
* install this capability, which owns the connection subsystem end to
|
|
132
|
+
* end: it claims upgrades, dispatches `onConnect`/`onMessage`/`onClose`
|
|
133
|
+
* inside the host invocation boundary, reciprocates close handshakes,
|
|
134
|
+
* and answers `getConnections()`/`getConnection()`.
|
|
135
|
+
*
|
|
136
|
+
* ```ts
|
|
137
|
+
* class Room extends DurableObject<Env> {
|
|
138
|
+
* readonly webSockets = new WebSockets({
|
|
139
|
+
* handlers: {
|
|
140
|
+
* onConnect: (connection) => connection.send("welcome"),
|
|
141
|
+
* onMessage: (connection, message) => { ... }
|
|
142
|
+
* },
|
|
143
|
+
* callables: new RoomCallables()
|
|
144
|
+
* });
|
|
145
|
+
* readonly lifecycle = Lifecycle.install(this).use(this.webSockets);
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* Connections arrive on one of two wires, chosen by the client:
|
|
150
|
+
*
|
|
151
|
+
* - **cf-websocket** (default): accepted with the Hibernation API. Idle
|
|
152
|
+
* clients stay connected while the Durable Object leaves memory.
|
|
153
|
+
* - **capnweb** (`?__agents_transport=capnweb`): protocol frames through
|
|
154
|
+
* one pipe method on a Cap'n Web session whose root also carries the
|
|
155
|
+
* host's callables natively. Non-hibernating — the object stays pinned
|
|
156
|
+
* while the connection is open.
|
|
157
|
+
*
|
|
158
|
+
* Both wires dispatch the same handlers and appear in `getConnections()`.
|
|
159
|
+
* On both, the capability speaks the Agent protocol a plain host needs
|
|
160
|
+
* for `useAgent` and `AgentClient`: it sends the identity frame on
|
|
161
|
+
* connect, and it serves `callables` — as `rpc` JSON frames on the
|
|
162
|
+
* WebSocket wire, and natively on the Cap'n Web session root, where an
|
|
163
|
+
* `RpcTarget` result becomes a live stub and calls pipeline. `call()`
|
|
164
|
+
* and `stub` work against a plain Durable Object exactly as against an
|
|
165
|
+
* `Agent`. Pass a `State` capability as `state` and the hook's
|
|
166
|
+
* `state`/`setState` work too: the current value is pushed on connect
|
|
167
|
+
* and client updates are validated and applied; the state owner
|
|
168
|
+
* broadcasts changes with `broadcastState()`. Per-connection readonly
|
|
169
|
+
* and no-protocol flags live here as well, for every host.
|
|
170
|
+
*
|
|
171
|
+
* @experimental The API surface may change before stabilizing.
|
|
172
|
+
*/
|
|
173
|
+
declare class WebSockets extends LifecycleCapability {
|
|
174
|
+
#private;
|
|
175
|
+
/** Claims every upgrade, so Lifecycle dispatches it after all others. */
|
|
176
|
+
readonly claims = "catch-all";
|
|
177
|
+
constructor(options?: WebSocketsOptions);
|
|
178
|
+
/**
|
|
179
|
+
* Claim every upgrade, never declining: a Cap'n Web transport upgrade
|
|
180
|
+
* becomes a session, everything else a tracked hibernating connection,
|
|
181
|
+
* whether or not handlers or callables are configured. Handlers only add
|
|
182
|
+
* behavior on connect, message, close, and error.
|
|
183
|
+
*/
|
|
184
|
+
onWebSocketUpgrade({
|
|
185
|
+
request
|
|
186
|
+
}: CapabilityWebSocketUpgradeContext): Promise<Response>;
|
|
187
|
+
/** Dispatch a platform message wake for a capability-owned socket. */
|
|
188
|
+
onWebSocketMessage(
|
|
189
|
+
ws: WebSocket,
|
|
190
|
+
message: WebSocketMessage
|
|
191
|
+
): Promise<boolean>;
|
|
192
|
+
/** Dispatch and reciprocate a close wake for an owned socket. */
|
|
193
|
+
onWebSocketClose(
|
|
194
|
+
ws: WebSocket,
|
|
195
|
+
code: number,
|
|
196
|
+
reason: string,
|
|
197
|
+
wasClean: boolean
|
|
198
|
+
): Promise<boolean>;
|
|
199
|
+
/** Dispatch an error wake for an owned socket. */
|
|
200
|
+
onWebSocketError(ws: WebSocket, error: unknown): Promise<boolean>;
|
|
201
|
+
/**
|
|
202
|
+
* Close every owned connection during explicit host destruction. The
|
|
203
|
+
* capability owns its sockets' lifetimes, so it also owns tearing
|
|
204
|
+
* them down.
|
|
205
|
+
*/
|
|
206
|
+
dispose(): void;
|
|
207
|
+
/** Open connections on either wire, optionally by tag. */
|
|
208
|
+
getConnections<TState = unknown>(
|
|
209
|
+
tag?: string
|
|
210
|
+
): IterableIterator<Connection<TState>>;
|
|
211
|
+
/** One connection on either wire, by id. */
|
|
212
|
+
getConnection<TState = unknown>(id: string): Connection<TState> | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Send the identity frame, unless the connection is no-protocol. The
|
|
215
|
+
* defaults are the Durable Object's routed name and host class; a host
|
|
216
|
+
* whose public identity differs — an `Agent` facet, whose routed name
|
|
217
|
+
* is an internal encoding of its logical name — passes its own.
|
|
218
|
+
*/
|
|
219
|
+
sendIdentity(
|
|
220
|
+
connection: Connection,
|
|
221
|
+
identity?: {
|
|
222
|
+
name: string;
|
|
223
|
+
agent: string;
|
|
224
|
+
}
|
|
225
|
+
): void;
|
|
226
|
+
/**
|
|
227
|
+
* Send the current state to one connection, unless nothing is stored
|
|
228
|
+
* or the connection is no-protocol. Reading the state may seed the
|
|
229
|
+
* initial value; see `#connecting`.
|
|
230
|
+
*/
|
|
231
|
+
sendState(connection: Connection): void;
|
|
232
|
+
/**
|
|
233
|
+
* Apply a parsed `cf_agent_state` frame from a client. A readonly
|
|
234
|
+
* connection is refused; a change the host's validator rejects is
|
|
235
|
+
* logged in full server-side and answered with a generic
|
|
236
|
+
* `cf_agent_state_error`. Broadcasting the accepted change is the state
|
|
237
|
+
* owner's call, through its `onChanged` hook. Callers that drive the
|
|
238
|
+
* protocol themselves call this inside their own invocation context;
|
|
239
|
+
* the capability's automatic path does so via `runInHostContext`.
|
|
240
|
+
*
|
|
241
|
+
* @returns Whether the frame was a state frame (handled either way).
|
|
242
|
+
*/
|
|
243
|
+
applyStateFrame(connection: Connection, frame: unknown): boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Push the current state to every protocol-enabled connection except
|
|
246
|
+
* the one a change came from, which already has the value it sent.
|
|
247
|
+
* Wire a `State`'s `onChanged` to this.
|
|
248
|
+
*/
|
|
249
|
+
broadcastState(except?: Connection | "server"): void;
|
|
250
|
+
/** Whether the connection may update host state over the wire. */
|
|
251
|
+
isReadonly(connection: Connection): boolean;
|
|
252
|
+
/** Mark a connection readonly, or writable again. */
|
|
253
|
+
setReadonly(connection: Connection, readonly?: boolean): void;
|
|
254
|
+
/** Whether protocol text frames reach the connection. */
|
|
255
|
+
isProtocolEnabled(connection: Connection): boolean;
|
|
256
|
+
/** Enable or suppress protocol text frames for a connection. */
|
|
257
|
+
setProtocolEnabled(connection: Connection, enabled: boolean): void;
|
|
258
|
+
}
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/websockets/connection-flags.d.ts
|
|
261
|
+
/**
|
|
262
|
+
* Internal per-connection flags, stored inside the connection's own state
|
|
263
|
+
* under `_cf_`-prefixed keys so they ride the hibernation attachment (or a
|
|
264
|
+
* bridged connection's synced state) and survive a wake. The state wrapper
|
|
265
|
+
* installed by {@link ensureConnectionWrapped} hides them from
|
|
266
|
+
* `connection.state` and preserves them across user `setState` calls.
|
|
267
|
+
*
|
|
268
|
+
* Owned by the WebSockets capability; `Agent` and framework mixins reach it
|
|
269
|
+
* through the capability or, for their own keys, through
|
|
270
|
+
* {@link registerInternalConnectionKeys}.
|
|
271
|
+
*/
|
|
272
|
+
/** A readonly connection may not update host state. */
|
|
273
|
+
declare const CF_READONLY_KEY = "_cf_readonly";
|
|
274
|
+
/**
|
|
275
|
+
* A no-protocol connection receives no protocol text frames (identity,
|
|
276
|
+
* state sync, MCP servers) — neither on connect nor via broadcasts.
|
|
277
|
+
*/
|
|
278
|
+
declare const CF_NO_PROTOCOL_KEY = "_cf_no_protocol";
|
|
279
|
+
/**
|
|
280
|
+
* Register additional `_cf_`-prefixed keys a host or mixin stores in
|
|
281
|
+
* connection state, so they are hidden from `connection.state` and kept
|
|
282
|
+
* across user `setState` calls like the capability's own flags.
|
|
283
|
+
*/
|
|
284
|
+
declare function registerInternalConnectionKeys(...keys: string[]): void;
|
|
285
|
+
//#endregion
|
|
286
|
+
export {
|
|
287
|
+
type AgentTransport,
|
|
288
|
+
CAPNWEB_TRANSPORT_QUERY,
|
|
289
|
+
CAPNWEB_TRANSPORT_VALUE,
|
|
290
|
+
CF_NO_PROTOCOL_KEY,
|
|
291
|
+
CF_READONLY_KEY,
|
|
292
|
+
type SyncedState,
|
|
293
|
+
type WebSocketHandlers,
|
|
294
|
+
type WebSocketMessage,
|
|
295
|
+
WebSockets,
|
|
296
|
+
type WebSocketsOptions,
|
|
297
|
+
capnWebTransportUrl,
|
|
298
|
+
isCapnWebTransportUpgrade,
|
|
299
|
+
registerInternalConnectionKeys
|
|
300
|
+
};
|
|
301
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as isCapnWebTransportUpgrade, i as capnWebTransportUrl, r as CAPNWEB_TRANSPORT_VALUE, t as CAPNWEB_TRANSPORT_QUERY } from "../transport-protocol-BxyngQ_R.js";
|
|
2
|
+
import { l as registerInternalConnectionKeys, n as CF_NO_PROTOCOL_KEY, r as CF_READONLY_KEY, t as WebSockets } from "../websockets-D7IzWbZb.js";
|
|
3
|
+
export { CAPNWEB_TRANSPORT_QUERY, CAPNWEB_TRANSPORT_VALUE, CF_NO_PROTOCOL_KEY, CF_READONLY_KEY, WebSockets, capnWebTransportUrl, isCapnWebTransportUpgrade, registerInternalConnectionKeys };
|