@dialgem/client 0.0.0-stage → 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/emitter.ts","../src/protocol.ts","../src/player.ts","../src/worklet.ts","../src/call.ts","../src/version.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/** A minimal typed event emitter. A handler that throws never stops the others or the call. */\nexport class Emitter<Events extends Record<string, unknown>> {\n private handlers = new Map<keyof Events, Set<(payload: never) => void>>()\n\n on<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void): () => void {\n let set = this.handlers.get(event)\n if (!set) this.handlers.set(event, (set = new Set()))\n set.add(handler as (payload: never) => void)\n return () => this.off(event, handler)\n }\n\n off<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void): void {\n this.handlers.get(event)?.delete(handler as (payload: never) => void)\n }\n\n protected emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n for (const handler of [...(this.handlers.get(event) ?? [])]) {\n try {\n ;(handler as (payload: Events[K]) => void)(payload)\n } catch (error) {\n // Report it without breaking the call: a page's rendering bug is not a reason to drop the audio.\n if (typeof reportError === \"function\") reportError(error)\n else console.error(error)\n }\n }\n }\n}\n","/**\n * What the call WebSocket speaks. Everything here is pure, so it is tested without a browser.\n *\n * Client to server: one JSON text frame to open the call, then binary frames of 16 kHz mono signed\n * 16-bit little-endian PCM, and the text frame `hangup` to end it.\n * Server to client: JSON text frames (events) and binary frames of 16 kHz mono signed 16-bit PCM\n * (the agent's voice), each sentence beginning with a 44-byte RIFF header.\n */\n\n/** The only address the SDK talks to unless a self-hosted deployment says otherwise. */\nexport const DEFAULT_BASE_URL = \"wss://api.dialgem.com\"\n\n/** Both directions of the call's audio. */\nexport const SAMPLE_RATE = 16_000\n\n/** Microphone audio is sent in chunks of this many samples: 40 ms, small enough not to delay speech detection. */\nexport const CAPTURE_CHUNK_SAMPLES = 640\n\nexport class UrlError extends Error {}\n\n/**\n * The WebSocket address for a call. The token rides in the query string because browsers cannot set\n * headers on a WebSocket; it is single-use and lives 60 seconds, which is what makes that acceptable.\n *\n * Plain `ws:` is refused except for a local address: a token sent in the clear can be replayed by\n * whoever reads it before the real page connects.\n */\nexport function buildCallUrl(baseURL: string, accessToken: string): string {\n let url: URL\n try {\n url = new URL(baseURL)\n } catch {\n throw new UrlError(`baseURL is not a URL: ${baseURL}`)\n }\n if (url.protocol === \"https:\") url.protocol = \"wss:\"\n if (url.protocol === \"http:\") url.protocol = \"ws:\"\n if (url.protocol !== \"wss:\" && url.protocol !== \"ws:\") throw new UrlError(\"baseURL must be a wss:// or ws:// address\")\n const local = url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === \"[::1]\"\n if (url.protocol === \"ws:\" && !local) throw new UrlError(\"baseURL must use wss:// except for localhost\")\n if (!accessToken) throw new UrlError(\"accessToken is empty\")\n // An organization API key (`zk_...`) grants full access to the account. A page that is handed one has\n // already leaked it to every visitor, so refuse before it is put in a URL that gets logged.\n if (/^zk_/i.test(accessToken.trim())) {\n throw new UrlError(\n \"That is an organization API key, not a call token. Never put an API key in a web page: create the call on your server with webCalls.create() and give the page its access_token.\",\n )\n }\n const base = url.toString().replace(/\\/+$/, \"\")\n const query = new URLSearchParams({ web_token: accessToken, live_transcript: \"1\" })\n return `${base}/v1/agent/call?${query.toString()}`\n}\n\n/** The first frame. The server decides the agent and its configuration from the token and ignores this body. */\nexport const INIT_FRAME = JSON.stringify({ agent_config: {} })\n\nexport type ServerFrame =\n | { type: \"session_started\"; sessionId: string }\n | { type: \"transcript\"; role: \"user\" | \"agent\"; text: string }\n | { type: \"transcript_partial\"; text: string }\n | { type: \"agent_interrupted\" }\n | { type: \"call_ended\" }\n | { type: \"error\"; reason: string }\n | { type: \"ignored\" }\n\n/** One text frame from the server. Anything unrecognized (including malformed JSON) is `ignored`, never an exception. */\nexport function parseServerFrame(text: string): ServerFrame {\n let msg: unknown\n try {\n msg = JSON.parse(text)\n } catch {\n return { type: \"ignored\" }\n }\n if (typeof msg !== \"object\" || msg === null) return { type: \"ignored\" }\n const m = msg as Record<string, unknown>\n if (typeof m[\"error\"] === \"string\") {\n return { type: \"error\", reason: typeof m[\"disconnection_reason\"] === \"string\" ? m[\"disconnection_reason\"] : m[\"error\"] }\n }\n switch (m[\"type\"]) {\n case \"session_started\":\n return { type: \"session_started\", sessionId: typeof m[\"session_id\"] === \"string\" ? m[\"session_id\"] : \"\" }\n case \"transcript\":\n if ((m[\"role\"] === \"user\" || m[\"role\"] === \"agent\") && typeof m[\"text\"] === \"string\") {\n return { type: \"transcript\", role: m[\"role\"], text: m[\"text\"] }\n }\n return { type: \"ignored\" }\n case \"transcript_partial\":\n return m[\"role\"] === \"user\" && typeof m[\"text\"] === \"string\" ? { type: \"transcript_partial\", text: m[\"text\"] } : { type: \"ignored\" }\n case \"agent_interrupted\":\n return { type: \"agent_interrupted\" }\n case \"call_ended\":\n return { type: \"call_ended\" }\n default:\n return { type: \"ignored\" }\n }\n}\n\n/**\n * Strips the 44-byte RIFF header the server puts at the start of each sentence. A header-only frame\n * yields nothing. Audio that does not start with one is returned as is.\n */\nexport function stripRiffHeader(chunk: ArrayBuffer): ArrayBuffer | null {\n if (chunk.byteLength >= 4) {\n const magic = new Uint8Array(chunk, 0, 4)\n if (magic[0] === 0x52 && magic[1] === 0x49 && magic[2] === 0x46 && magic[3] === 0x46) {\n return chunk.byteLength <= 44 ? null : chunk.slice(44)\n }\n }\n return chunk\n}\n\n/**\n * What the server said when it turned the call away. Browsers cannot see the close code of a socket refused before\n * it is accepted, so the server accepts a refused call, sends this reason in one frame and then closes it.\n */\nexport function describeRefusal(reason: string): {\n code: \"refused\" | \"busy\" | \"server_error\" | \"call_refused\"\n message: string\n} {\n switch (reason) {\n case \"origin_not_allowed\":\n return { code: \"refused\", message: \"This page's origin is not allowed to start calls. Add it under Web calls in your Dialgem settings.\" }\n case \"token_expired\":\n return { code: \"refused\", message: \"The access token expired before the call connected. Request a new one and start again.\" }\n case \"token_already_used\":\n return { code: \"refused\", message: \"The access token was already used. Each call needs its own token from your backend.\" }\n case \"token_invalid\":\n case \"bad_request\":\n return { code: \"refused\", message: \"The access token is not valid for a call.\" }\n case \"concurrency_limit_reached\":\n return { code: \"busy\", message: \"Too many calls are running right now. Try again in a moment.\" }\n case \"web_calls_unavailable\":\n return { code: \"server_error\", message: \"Browser calls are not available right now.\" }\n default:\n return { code: \"call_refused\", message: `The call was declined: ${reason}.` }\n }\n}\n\n/** What a closed socket means, from its close code. */\nexport function describeClose(code: number): { code: \"refused\" | \"busy\" | \"server_error\" | \"connection_failed\"; message: string } {\n switch (code) {\n case 1008:\n return {\n code: \"refused\",\n message:\n \"The call was refused. The access token was invalid, expired or already used, or this page's origin is not allowed to start calls.\",\n }\n case 1013:\n return { code: \"busy\", message: \"Too many calls are running right now. Try again in a moment.\" }\n case 1011:\n case 1002:\n return { code: \"server_error\", message: \"The call could not start because of a problem on Dialgem's side.\" }\n default:\n return { code: \"connection_failed\", message: \"Could not connect to the call.\" }\n }\n}\n\n/** Float samples in [-1, 1] as little-endian 16-bit PCM. */\nexport function floatToPcm16(samples: Float32Array): ArrayBuffer {\n const out = new Int16Array(samples.length)\n for (let i = 0; i < samples.length; i++) {\n const s = Math.max(-1, Math.min(1, samples[i] ?? 0))\n out[i] = s < 0 ? s * 32768 : s * 32767\n }\n return out.buffer\n}\n","import { SAMPLE_RATE, stripRiffHeader } from \"./protocol.js\"\n\n/** The part of `AudioContext` the player uses, so a test can stand in for it. */\nexport interface PlaybackContext {\n readonly currentTime: number\n readonly destination: AudioNode\n createBuffer(channels: number, length: number, sampleRate: number): AudioBuffer\n createBufferSource(): AudioBufferSourceNode\n}\n\n/**\n * Plays the agent's voice as it arrives.\n *\n * Each binary frame is scheduled onto the audio clock right after the previous one, so speech starts within\n * a few milliseconds of the first frame instead of after a whole sentence has been buffered, and consecutive\n * frames join without a gap. The buffers are 16 kHz; the browser resamples them to whatever the output device\n * runs at.\n *\n * Network delivery is faster than playback, so the last byte of a sentence arrives while the speaker still has\n * a second of it to say. `remainingMs` is how much is still queued, which is what lets a call that ends\n * with a goodbye let the goodbye finish.\n */\nexport class PcmPlayer {\n private nextTime = 0\n private sources: AudioBufferSourceNode[] = []\n /** A trailing odd byte: frames are not guaranteed to end on a sample boundary. */\n private carry: Uint8Array | null = null\n\n constructor(private readonly ctx: PlaybackContext) {}\n\n feed(chunk: ArrayBuffer): void {\n let data = stripRiffHeader(chunk)\n if (data === null) return\n if (this.carry) {\n const joined = new Uint8Array(this.carry.length + data.byteLength)\n joined.set(this.carry, 0)\n joined.set(new Uint8Array(data), this.carry.length)\n data = joined.buffer\n this.carry = null\n }\n const usable = data.byteLength - (data.byteLength % 2)\n if (usable !== data.byteLength) this.carry = new Uint8Array(data.slice(usable))\n const samples = usable / 2\n if (samples < 1) return\n\n const pcm = new Int16Array(data.slice(0, usable))\n const floats = new Float32Array(samples)\n for (let i = 0; i < samples; i++) floats[i] = (pcm[i] ?? 0) / 32768\n\n const buffer = this.ctx.createBuffer(1, samples, SAMPLE_RATE)\n buffer.copyToChannel(floats, 0)\n const source = this.ctx.createBufferSource()\n source.buffer = buffer\n source.connect(this.ctx.destination)\n source.onended = () => {\n const i = this.sources.indexOf(source)\n if (i !== -1) this.sources.splice(i, 1)\n }\n\n const now = this.ctx.currentTime\n // Behind (the first frame, or after an interruption): start a hair ahead of now so the first sample is not clipped.\n if (this.nextTime < now) this.nextTime = now + 0.02\n source.start(this.nextTime)\n this.sources.push(source)\n this.nextTime += buffer.duration\n }\n\n /** Stop everything queued, immediately: the caller started talking over the agent. */\n interrupt(): void {\n for (const s of this.sources) {\n try {\n s.stop(0)\n } catch {\n // already finished\n }\n }\n this.sources = []\n this.nextTime = 0\n this.carry = null\n }\n\n /** Whether anything is queued or playing. */\n active(): boolean {\n return this.sources.length > 0\n }\n\n /** Milliseconds of audio still queued ahead of the audio clock. */\n remainingMs(): number {\n return Math.max(0, (this.nextTime - this.ctx.currentTime) * 1000)\n }\n}\n","import { CAPTURE_CHUNK_SAMPLES, SAMPLE_RATE } from \"./protocol.js\"\n\nexport const WORKLET_NAME = \"dialgem-capture\"\n\n/**\n * The microphone capture processor, as source text.\n *\n * It runs in the audio thread at the device's own sample rate (44.1 or 48 kHz, whatever the hardware\n * does) and turns that into the 16 kHz mono 16-bit PCM the call needs, 640 samples at a time. Capturing at\n * the device rate and converting here, rather than asking the browser for a 16 kHz context, is what\n * keeps this working in Firefox, which refuses to connect a microphone to a context at another rate.\n *\n * Each output sample is the mean of the input samples that fall in its slot. That is a box filter: crude, but\n * it removes most of what would otherwise fold into the speech band, and speech recognition does not need more.\n * A rate that is not a whole multiple of 16 kHz (44.1 kHz) is handled by a fractional boundary, not by rounding.\n *\n * It is text, not an imported function, because `audioWorklet.addModule` takes a URL; the SDK serves it from a\n * Blob. The tests run this exact text, so what ships is what is tested.\n */\nexport const WORKLET_SOURCE = `\nclass DialgemCapture extends AudioWorkletProcessor {\n constructor(options) {\n super()\n const o = (options && options.processorOptions) || {}\n this.chunk = o.chunkSamples || ${CAPTURE_CHUNK_SAMPLES}\n this.ratio = sampleRate / (o.targetRate || ${SAMPLE_RATE})\n this.pos = 0\n this.boundary = this.ratio\n this.sum = 0\n this.count = 0\n this.last = 0\n this.out = new Int16Array(this.chunk)\n this.n = 0\n this.peak = 0\n }\n\n emit(v) {\n const a = v < 0 ? -v : v\n if (a > this.peak) this.peak = a\n const s = v > 1 ? 1 : v < -1 ? -1 : v\n this.out[this.n++] = s < 0 ? s * 32768 : s * 32767\n if (this.n === this.chunk) {\n const pcm = this.out.buffer\n this.port.postMessage({ pcm: pcm, peak: this.peak }, [pcm])\n this.out = new Int16Array(this.chunk)\n this.n = 0\n this.peak = 0\n }\n }\n\n process(inputs) {\n const input = inputs[0] && inputs[0][0]\n if (!input) return true\n for (let i = 0; i < input.length; i++) {\n this.sum += input[i]\n this.count++\n this.pos++\n while (this.pos >= this.boundary) {\n const v = this.count > 0 ? this.sum / this.count : this.last\n this.last = v\n this.sum = 0\n this.count = 0\n this.boundary += this.ratio\n this.emit(v)\n }\n }\n return true\n }\n}\nregisterProcessor(${JSON.stringify(WORKLET_NAME)}, DialgemCapture)\n`\n","import { Emitter } from \"./emitter.js\"\nimport { PcmPlayer } from \"./player.js\"\nimport {\n CAPTURE_CHUNK_SAMPLES,\n DEFAULT_BASE_URL,\n INIT_FRAME,\n SAMPLE_RATE,\n UrlError,\n buildCallUrl,\n describeClose,\n describeRefusal,\n parseServerFrame,\n} from \"./protocol.js\"\nimport { WORKLET_NAME, WORKLET_SOURCE } from \"./worklet.js\"\n\nexport type CallState = \"idle\" | \"connecting\" | \"active\" | \"ended\" | \"error\"\n\n/** How a call that started came to an end. */\nexport type EndReason =\n /** `stop()` was called. */\n | \"hangup\"\n /** The agent ended the call, or a call limit (maximum length, silence) did. */\n | \"agent_ended\"\n /** The connection dropped. The call cannot be resumed: start a new one. */\n | \"connection_lost\"\n\nexport type ErrorCode =\n /** The browser lacks something the call needs (WebSocket, Web Audio, AudioWorklet, a microphone API). */\n | \"unsupported\"\n /** The visitor refused microphone access, or it is blocked for this page. */\n | \"mic_denied\"\n /** No microphone, or it could not be opened. */\n | \"mic_unavailable\"\n /** `accessToken` was a function and it threw or returned nothing. */\n | \"token_unavailable\"\n /** The token was invalid, expired or already used, or this page's origin is not allowed. */\n | \"refused\"\n /** The organization has too many calls running. */\n | \"busy\"\n /** The server declined the call; `reason` says why (for example `insufficient_credit`). */\n | \"call_refused\"\n | \"server_error\"\n | \"connection_failed\"\n\nexport interface CallError {\n code: ErrorCode\n message: string\n /** For `call_refused`: the server's reason. */\n reason?: string | undefined\n}\n\nexport interface TranscriptEvent {\n role: \"user\" | \"agent\"\n text: string\n /** False while the caller is still speaking (the words so far); true once the line is settled. */\n final: boolean\n}\n\nexport interface CallEvents extends Record<string, unknown> {\n state: CallState\n started: { callId: string }\n transcript: TranscriptEvent\n agent_speaking: { speaking: boolean }\n /** The caller talked over the agent and its speech was cut off. */\n interrupted: Record<string, never>\n /** Microphone level, 0 to 1, about ten times a second. Not emitted while muted. */\n level: { level: number }\n ended: { reason: EndReason }\n error: CallError\n}\n\nexport interface MicrophoneOptions {\n deviceId?: string | undefined\n /** Default true: without it the agent's own voice comes back through the microphone and it answers itself. */\n echoCancellation?: boolean | undefined\n noiseSuppression?: boolean | undefined\n autoGainControl?: boolean | undefined\n}\n\nexport interface DialgemCallOptions {\n /**\n * The access token from your backend's `POST /v1/calls/web`, or a function that returns it. A function\n * is called **after** the visitor has allowed the microphone, because the token only lives 60 seconds and\n * the permission prompt can take longer than that.\n */\n accessToken: string | (() => string | Promise<string>)\n /** Only for a self-hosted deployment. Default `wss://api.dialgem.com`. */\n baseURL?: string | undefined\n microphone?: MicrophoneOptions | undefined\n /** @internal Stand-ins for the browser, for tests. */\n platform?: Partial<Platform> | undefined\n}\n\n/** What the call needs from the browser. */\nexport interface Platform {\n WebSocket: typeof WebSocket\n AudioContext: typeof AudioContext\n AudioWorkletNode: typeof AudioWorkletNode\n getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream>\n createObjectURL(blob: Blob): string\n revokeObjectURL(url: string): void\n Blob: typeof Blob\n}\n\nconst LEVEL_INTERVAL_MS = 100\n/** A closing line is let finish playing, but never for longer than this. */\nconst MAX_DRAIN_MS = 10_000\n\nfunction browser(): Partial<Platform> {\n const g = globalThis as unknown as Record<string, unknown>\n const nav = g[\"navigator\"] as Navigator | undefined\n const url = g[\"URL\"] as typeof URL | undefined\n const out: Partial<Platform> = {}\n if (g[\"WebSocket\"]) out.WebSocket = g[\"WebSocket\"] as Platform[\"WebSocket\"]\n const audio = g[\"AudioContext\"] ?? g[\"webkitAudioContext\"]\n if (audio) out.AudioContext = audio as Platform[\"AudioContext\"]\n if (g[\"AudioWorkletNode\"]) out.AudioWorkletNode = g[\"AudioWorkletNode\"] as Platform[\"AudioWorkletNode\"]\n if (g[\"Blob\"]) out.Blob = g[\"Blob\"] as Platform[\"Blob\"]\n if (nav?.mediaDevices?.getUserMedia) out.getUserMedia = (c) => nav.mediaDevices.getUserMedia(c)\n if (url?.createObjectURL) out.createObjectURL = (b) => url.createObjectURL(b)\n if (url?.revokeObjectURL) out.revokeObjectURL = (u) => url.revokeObjectURL(u)\n return out\n}\n\n/**\n * One conversation with one agent.\n *\n * const call = new DialgemCall({ accessToken: () => fetch(\"/api/start-call\").then((r) => r.text()) })\n * call.on(\"transcript\", (t) => ...)\n * await call.start() // from a click: browsers only let a page open the microphone and play sound after one\n * ...\n * call.stop()\n *\n * A call object is used once. Its token is single-use, so a second call needs a new object (and a new token).\n * There is no reconnecting: the conversation lives on the server for as long as the socket does, and a call\n * that drops has ended.\n */\nexport class DialgemCall extends Emitter<CallEvents> {\n private _state: CallState = \"idle\"\n private _muted = false\n private _callId: string | null = null\n private readonly platform: Platform\n\n private ctx: AudioContext | null = null\n private stream: MediaStream | null = null\n private ws: WebSocket | null = null\n private player: PcmPlayer | null = null\n private source: MediaStreamAudioSourceNode | null = null\n private node: AudioWorkletNode | null = null\n private sink: GainNode | null = null\n private moduleUrl: string | null = null\n private speakingTimer: ReturnType<typeof setTimeout> | null = null\n private drainTimer: ReturnType<typeof setTimeout> | null = null\n private ending = false\n private pendingRefusal: string | null = null\n private failure: CallError | null = null\n private lastLevelAt = 0\n private speaking = false\n\n constructor(private readonly options: DialgemCallOptions) {\n super()\n this.platform = { ...browser(), ...(options.platform ?? {}) } as Platform\n }\n\n get state(): CallState {\n return this._state\n }\n\n /** Set once the call has started. */\n get callId(): string | null {\n return this._callId\n }\n\n get muted(): boolean {\n return this._muted\n }\n\n /**\n * Opens the microphone and the call. Call it directly from a click or tap: the browser decides whether the page\n * may play sound at the moment this runs, and a call started from a timer or after other awaits can be silent.\n * Resolves when the connection is open; the call has started when `started` fires. A failure is reported as an\n * `error` event and also rejects.\n */\n async start(): Promise<void> {\n if (this._state !== \"idle\") throw new Error(\"A call object can only be started once. Create a new DialgemCall for each call.\")\n this.setState(\"connecting\")\n const p = this.platform\n if (!p.WebSocket || !p.AudioContext || !p.AudioWorkletNode || !p.getUserMedia || !p.createObjectURL || !p.Blob) {\n throw this.fail({ code: \"unsupported\", message: \"This browser cannot run voice calls (it needs WebSocket, Web Audio with AudioWorklet, and a microphone API).\" })\n }\n\n // Synchronously, before any await: this is what a browser counts as \"started by the visitor\".\n try {\n this.ctx = new p.AudioContext()\n void this.ctx.resume()\n } catch {\n throw this.fail({ code: \"unsupported\", message: \"This browser could not start audio.\" })\n }\n this.player = new PcmPlayer(this.ctx)\n\n const mic = this.options.microphone ?? {}\n try {\n this.stream = await p.getUserMedia({\n audio: {\n channelCount: 1,\n echoCancellation: mic.echoCancellation ?? true,\n noiseSuppression: mic.noiseSuppression ?? true,\n autoGainControl: mic.autoGainControl ?? true,\n ...(mic.deviceId ? { deviceId: { exact: mic.deviceId } } : {}),\n },\n })\n } catch (error) {\n const name = (error as { name?: string } | null)?.name ?? \"\"\n throw this.fail(\n name === \"NotAllowedError\" || name === \"SecurityError\"\n ? { code: \"mic_denied\", message: \"Microphone access was denied. Allow the microphone for this page and try again.\" }\n : { code: \"mic_unavailable\", message: \"The microphone could not be opened. Check that one is connected and not in use by another app.\" },\n )\n }\n if (this.dead()) return this.cleanup()\n\n try {\n this.moduleUrl = p.createObjectURL(new p.Blob([WORKLET_SOURCE], { type: \"application/javascript\" }))\n await this.ctx.audioWorklet.addModule(this.moduleUrl)\n } catch {\n throw this.fail({\n code: \"unsupported\",\n message: \"The audio processor could not be loaded. If this page sets a Content-Security-Policy, allow blob: in script-src.\",\n })\n }\n if (this.dead()) return this.cleanup()\n\n // The token is fetched last: it has 60 seconds, and everything above can take a visitor longer than that.\n let token: string\n try {\n const t = this.options.accessToken\n token = typeof t === \"function\" ? await t() : t\n if (!token) throw new Error(\"empty token\")\n } catch {\n throw this.fail({ code: \"token_unavailable\", message: \"Could not get an access token for the call.\" })\n }\n if (this.dead()) return this.cleanup()\n\n let url: string\n try {\n url = buildCallUrl(this.options.baseURL ?? DEFAULT_BASE_URL, token)\n } catch (error) {\n throw this.fail({ code: \"connection_failed\", message: error instanceof UrlError ? error.message : \"Invalid call address.\" })\n }\n\n await new Promise<void>((resolve) => {\n const ws = new p.WebSocket(url)\n ws.binaryType = \"arraybuffer\"\n this.ws = ws\n ws.onopen = () => {\n ws.send(INIT_FRAME)\n resolve()\n }\n ws.onmessage = (event) => this.onMessage(event.data)\n ws.onerror = () => resolve()\n ws.onclose = (event) => {\n resolve()\n this.onClose(event.code)\n }\n })\n if (this.failure) throw this.fail(this.failure)\n }\n\n /** Ends the call. Safe to call at any time, any number of times. */\n stop(): void {\n if (this._state === \"idle\") {\n this.setState(\"ended\")\n this.emit(\"ended\", { reason: \"hangup\" })\n return\n }\n if (this._state !== \"active\" && this._state !== \"connecting\") return\n try {\n if (this.ws?.readyState === 1) this.ws.send(\"hangup\")\n } catch {\n // closing anyway\n }\n this.finish(\"hangup\")\n }\n\n /** While muted the agent hears silence. The call stays open. */\n setMuted(muted: boolean): void {\n this._muted = muted\n if (muted) this.emit(\"level\", { level: 0 })\n }\n\n // ── server to client ──────────────────────────────────────────────────────────\n\n private onMessage(data: unknown): void {\n if (typeof data !== \"string\") {\n if (data instanceof ArrayBuffer) this.onAudio(data)\n return\n }\n const frame = parseServerFrame(data)\n switch (frame.type) {\n case \"session_started\":\n this.onStarted(frame.sessionId)\n break\n case \"transcript\":\n this.emit(\"transcript\", { role: frame.role, text: frame.text, final: true })\n break\n case \"transcript_partial\":\n this.emit(\"transcript\", { role: \"user\", text: frame.text, final: false })\n break\n case \"agent_interrupted\":\n this.player?.interrupt()\n this.setSpeaking(false)\n this.emit(\"interrupted\", {})\n break\n case \"call_ended\":\n this.onCallEnded()\n break\n case \"error\":\n // The close that follows carries the code; this carries the reason.\n this.pendingRefusal = frame.reason\n break\n case \"ignored\":\n break\n }\n }\n\n private onStarted(sessionId: string): void {\n if (this._state !== \"connecting\" || !this.ctx || !this.stream) return\n this._callId = sessionId || null\n this.setState(\"active\")\n\n const ctx = this.ctx\n this.source = ctx.createMediaStreamSource(this.stream)\n this.node = new this.platform.AudioWorkletNode(ctx, WORKLET_NAME, {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n processorOptions: { targetRate: SAMPLE_RATE, chunkSamples: CAPTURE_CHUNK_SAMPLES },\n })\n // Muted to the speakers: the node only needs to be pulled by the graph.\n this.sink = ctx.createGain()\n this.sink.gain.value = 0\n this.source.connect(this.node)\n this.node.connect(this.sink)\n this.sink.connect(ctx.destination)\n this.node.port.onmessage = (event: MessageEvent<{ pcm: ArrayBuffer; peak: number }>) => this.onCaptured(event.data)\n\n this.emit(\"started\", { callId: this._callId ?? \"\" })\n }\n\n private onCaptured(frame: { pcm: ArrayBuffer; peak: number }): void {\n const ws = this.ws\n if (!ws || ws.readyState !== 1 || this.ending) return\n // Muted: silence of the same length, so the server's speech detection keeps its rhythm instead of seeing a gap.\n ws.send(this._muted ? new ArrayBuffer(frame.pcm.byteLength) : frame.pcm)\n const now = Date.now()\n if (!this._muted && now - this.lastLevelAt >= LEVEL_INTERVAL_MS) {\n this.lastLevelAt = now\n this.emit(\"level\", { level: Math.min(1, frame.peak) })\n }\n }\n\n private onAudio(data: ArrayBuffer): void {\n if (this._state !== \"active\" || !this.player) return\n this.player.feed(data)\n this.setSpeaking(true)\n // Speaking until the queued audio has played out, not for a fixed time after the last frame.\n if (this.speakingTimer) clearTimeout(this.speakingTimer)\n this.speakingTimer = setTimeout(() => this.setSpeaking(false), this.player.remainingMs() + 50)\n }\n\n private setSpeaking(speaking: boolean): void {\n if (speaking === this.speaking) return\n this.speaking = speaking\n if (!speaking && this.speakingTimer) {\n clearTimeout(this.speakingTimer)\n this.speakingTimer = null\n }\n this.emit(\"agent_speaking\", { speaking })\n }\n\n private onCallEnded(): void {\n if (this.ending || this.dead()) return\n // Everything has been sent, but a goodbye can still be mid-sentence in the speaker: let it finish.\n this.ending = true\n const wait = Math.min(MAX_DRAIN_MS, (this.player?.remainingMs() ?? 0) + 50)\n this.drainTimer = setTimeout(() => this.finish(\"agent_ended\"), wait)\n }\n\n private onClose(code: number): void {\n if (this.dead()) return\n if (this._state === \"active\") {\n // A graceful end already has its own timer; a close during it must not cut the goodbye short.\n if (!this.ending) this.finish(\"connection_lost\")\n return\n }\n if (this.pendingRefusal) {\n this.fail({ ...describeRefusal(this.pendingRefusal), reason: this.pendingRefusal })\n return\n }\n this.fail(describeClose(code))\n }\n\n // ── ending ────────────────────────────────────────────────────────────────────\n\n private dead(): boolean {\n return this._state === \"ended\" || this._state === \"error\"\n }\n\n /** Ends the call as failed and reports it once. Returns the error, for `start()` to throw. */\n private fail(error: CallError): Error {\n if (!this.dead()) {\n this.failure = error\n this.cleanup()\n this.setState(\"error\")\n this.emit(\"error\", error)\n }\n const shown = this.failure ?? error\n return Object.assign(new Error(shown.message), { code: shown.code, reason: shown.reason })\n }\n\n private finish(reason: EndReason): void {\n if (this.dead()) return\n this.cleanup()\n this.setState(\"ended\")\n this.emit(\"ended\", { reason })\n }\n\n private setState(state: CallState): void {\n this._state = state\n this.emit(\"state\", state)\n }\n\n private cleanup(): void {\n this.ending = true\n for (const t of [this.speakingTimer, this.drainTimer]) if (t) clearTimeout(t)\n this.speakingTimer = this.drainTimer = null\n if (this.speaking) {\n this.speaking = false\n this.emit(\"agent_speaking\", { speaking: false })\n }\n this.player?.interrupt()\n if (this.node) {\n this.node.port.onmessage = null\n try {\n this.node.disconnect()\n } catch {\n // already disconnected\n }\n }\n try {\n this.source?.disconnect()\n this.sink?.disconnect()\n } catch {\n // already disconnected\n }\n this.stream?.getTracks().forEach((t) => t.stop())\n if (this.ws) {\n this.ws.onmessage = this.ws.onerror = this.ws.onopen = null\n try {\n this.ws.close()\n } catch {\n // already closed\n }\n }\n if (this.moduleUrl) this.platform.revokeObjectURL?.(this.moduleUrl)\n void this.ctx?.close().catch(() => undefined)\n this.node = this.source = this.sink = this.stream = this.ctx = this.player = null\n this.moduleUrl = null\n }\n}\n","/** Kept equal to package.json's version by a test. */\nexport const VERSION = \"1.0.0\"\n"]}
@@ -0,0 +1,19 @@
1
+ export { C as CallError, a as CallEvents, b as CallState, D as DialgemCall, c as DialgemCallOptions, E as EndReason, d as ErrorCode, M as MicrophoneOptions, T as TranscriptEvent } from './call-Cv2GrNfJ.cjs';
2
+
3
+ /**
4
+ * What the call WebSocket speaks. Everything here is pure, so it is tested without a browser.
5
+ *
6
+ * Client to server: one JSON text frame to open the call, then binary frames of 16 kHz mono signed
7
+ * 16-bit little-endian PCM, and the text frame `hangup` to end it.
8
+ * Server to client: JSON text frames (events) and binary frames of 16 kHz mono signed 16-bit PCM
9
+ * (the agent's voice), each sentence beginning with a 44-byte RIFF header.
10
+ */
11
+ /** The only address the SDK talks to unless a self-hosted deployment says otherwise. */
12
+ declare const DEFAULT_BASE_URL = "wss://api.dialgem.com";
13
+ /** Both directions of the call's audio. */
14
+ declare const SAMPLE_RATE = 16000;
15
+
16
+ /** Kept equal to package.json's version by a test. */
17
+ declare const VERSION = "1.0.0";
18
+
19
+ export { DEFAULT_BASE_URL, SAMPLE_RATE, VERSION };
@@ -0,0 +1,19 @@
1
+ export { C as CallError, a as CallEvents, b as CallState, D as DialgemCall, c as DialgemCallOptions, E as EndReason, d as ErrorCode, M as MicrophoneOptions, T as TranscriptEvent } from './call-Cv2GrNfJ.js';
2
+
3
+ /**
4
+ * What the call WebSocket speaks. Everything here is pure, so it is tested without a browser.
5
+ *
6
+ * Client to server: one JSON text frame to open the call, then binary frames of 16 kHz mono signed
7
+ * 16-bit little-endian PCM, and the text frame `hangup` to end it.
8
+ * Server to client: JSON text frames (events) and binary frames of 16 kHz mono signed 16-bit PCM
9
+ * (the agent's voice), each sentence beginning with a 44-byte RIFF header.
10
+ */
11
+ /** The only address the SDK talks to unless a self-hosted deployment says otherwise. */
12
+ declare const DEFAULT_BASE_URL = "wss://api.dialgem.com";
13
+ /** Both directions of the call's audio. */
14
+ declare const SAMPLE_RATE = 16000;
15
+
16
+ /** Kept equal to package.json's version by a test. */
17
+ declare const VERSION = "1.0.0";
18
+
19
+ export { DEFAULT_BASE_URL, SAMPLE_RATE, VERSION };