@tryhakim/voice 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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/dist/audio/speech-stream-ws.d.ts +40 -0
  4. package/dist/audio/speech-stream-ws.d.ts.map +1 -0
  5. package/dist/audio/speech-stream-ws.js +565 -0
  6. package/dist/audio/speech-stream-ws.js.map +1 -0
  7. package/dist/audio/speech.d.ts +46 -0
  8. package/dist/audio/speech.d.ts.map +1 -0
  9. package/dist/audio/speech.js +125 -0
  10. package/dist/audio/speech.js.map +1 -0
  11. package/dist/audio/stream.d.ts +38 -0
  12. package/dist/audio/stream.d.ts.map +1 -0
  13. package/dist/audio/stream.js +452 -0
  14. package/dist/audio/stream.js.map +1 -0
  15. package/dist/audio/to-blob.d.ts +10 -0
  16. package/dist/audio/to-blob.d.ts.map +1 -0
  17. package/dist/audio/to-blob.js +78 -0
  18. package/dist/audio/to-blob.js.map +1 -0
  19. package/dist/audio/transcriptions.d.ts +35 -0
  20. package/dist/audio/transcriptions.d.ts.map +1 -0
  21. package/dist/audio/transcriptions.js +105 -0
  22. package/dist/audio/transcriptions.js.map +1 -0
  23. package/dist/audio/translate-stream-ws.d.ts +37 -0
  24. package/dist/audio/translate-stream-ws.d.ts.map +1 -0
  25. package/dist/audio/translate-stream-ws.js +665 -0
  26. package/dist/audio/translate-stream-ws.js.map +1 -0
  27. package/dist/audio/translate.d.ts +36 -0
  28. package/dist/audio/translate.d.ts.map +1 -0
  29. package/dist/audio/translate.js +39 -0
  30. package/dist/audio/translate.js.map +1 -0
  31. package/dist/audio/voices.d.ts +47 -0
  32. package/dist/audio/voices.d.ts.map +1 -0
  33. package/dist/audio/voices.js +91 -0
  34. package/dist/audio/voices.js.map +1 -0
  35. package/dist/chat/completions.d.ts +76 -0
  36. package/dist/chat/completions.d.ts.map +1 -0
  37. package/dist/chat/completions.js +114 -0
  38. package/dist/chat/completions.js.map +1 -0
  39. package/dist/chat/index.d.ts +2 -0
  40. package/dist/chat/index.d.ts.map +1 -0
  41. package/dist/chat/index.js +2 -0
  42. package/dist/chat/index.js.map +1 -0
  43. package/dist/chat/sse.d.ts +12 -0
  44. package/dist/chat/sse.d.ts.map +1 -0
  45. package/dist/chat/sse.js +142 -0
  46. package/dist/chat/sse.js.map +1 -0
  47. package/dist/client.d.ts +63 -0
  48. package/dist/client.d.ts.map +1 -0
  49. package/dist/client.js +80 -0
  50. package/dist/client.js.map +1 -0
  51. package/dist/errors.d.ts +99 -0
  52. package/dist/errors.d.ts.map +1 -0
  53. package/dist/errors.js +158 -0
  54. package/dist/errors.js.map +1 -0
  55. package/dist/index.d.ts +27 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +25 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/jobs.d.ts +34 -0
  60. package/dist/jobs.d.ts.map +1 -0
  61. package/dist/jobs.js +62 -0
  62. package/dist/jobs.js.map +1 -0
  63. package/dist/observability.d.ts +28 -0
  64. package/dist/observability.d.ts.map +1 -0
  65. package/dist/observability.js +107 -0
  66. package/dist/observability.js.map +1 -0
  67. package/dist/settings.d.ts +49 -0
  68. package/dist/settings.d.ts.map +1 -0
  69. package/dist/settings.js +84 -0
  70. package/dist/settings.js.map +1 -0
  71. package/dist/transport.d.ts +82 -0
  72. package/dist/transport.d.ts.map +1 -0
  73. package/dist/transport.js +289 -0
  74. package/dist/transport.js.map +1 -0
  75. package/dist/types.d.ts +969 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +11 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/usage.d.ts +43 -0
  80. package/dist/usage.d.ts.map +1 -0
  81. package/dist/usage.js +85 -0
  82. package/dist/usage.js.map +1 -0
  83. package/dist/version.d.ts +13 -0
  84. package/dist/version.d.ts.map +1 -0
  85. package/dist/version.js +13 -0
  86. package/dist/version.js.map +1 -0
  87. package/dist/webhooks.d.ts +84 -0
  88. package/dist/webhooks.d.ts.map +1 -0
  89. package/dist/webhooks.js +157 -0
  90. package/dist/webhooks.js.map +1 -0
  91. package/package.json +57 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `audio.speech` — POST /v1/audio/speech.
3
+ *
4
+ * Two entry points:
5
+ *
6
+ * - `create(request)` — buffers the full audio into memory and
7
+ * returns it with decoded headers. Use for short outputs or when
8
+ * you need `usageCharacters` / `durationMs` immediately.
9
+ *
10
+ * - `stream(request)` — returns an AsyncIterable of `Uint8Array`
11
+ * chunks so the caller can start playback / uploading before the
12
+ * server finishes synthesis. `stream` forces `stream: true` on the
13
+ * request payload regardless of what the caller passed.
14
+ */
15
+ import { ConnectionError } from '../errors.js';
16
+ import { parseLimitsFromHeaders, parseUsageBlockFromHeaders } from '../observability.js';
17
+ import { openSpeechStream } from './speech-stream-ws.js';
18
+ export class SpeechAPI {
19
+ transport;
20
+ constructor(transport) {
21
+ this.transport = transport;
22
+ }
23
+ /** Realtime TTS over a WebSocket (`/v1/audio/speech/stream`).
24
+ *
25
+ * Trades the per-request TCP/TLS/HTTP-header setup of the HTTP
26
+ * path (~7 ms per call cross-region) for a long-lived socket that
27
+ * can serve many utterances back-to-back. The persistent surface
28
+ * is the right pick for LLM-→-TTS pipelines (synthesise the next
29
+ * sentence while the LLM is still generating tokens) and embed
30
+ * widgets that make many TTS calls per session.
31
+ *
32
+ * Returns a `SpeechStreamHandle` — call `sendSpeech({...})` to
33
+ * request an utterance, iterate `audio` (raw PCM-S16LE @ 24 kHz
34
+ * mono) or `events` (started / audio / done / usage / error), and
35
+ * `close()` when finished. */
36
+ streamWs(opts = {}) {
37
+ return openSpeechStream(this.transport, opts);
38
+ }
39
+ /** Non-streaming TTS. Returns the complete audio body as a Uint8Array. */
40
+ async create(request, opts = {}) {
41
+ const res = await this.transport.request({
42
+ method: 'POST',
43
+ path: '/v1/audio/speech',
44
+ json: { ...request, stream: false },
45
+ accept: 'audio/*',
46
+ headers: { accept: 'audio/*' },
47
+ ...(opts.idempotencyKey !== undefined ? { idempotencyKey: opts.idempotencyKey } : {}),
48
+ ...(opts.signal !== undefined ? { signal: opts.signal } : {}),
49
+ });
50
+ const buffer = await res.arrayBuffer();
51
+ return {
52
+ audio: new Uint8Array(buffer),
53
+ contentType: res.headers.get('content-type') ?? 'application/octet-stream',
54
+ usageCharacters: parsePositiveInt(res.headers.get('x-usage-characters')),
55
+ durationMs: parsePositiveInt(res.headers.get('x-duration-ms')),
56
+ usage: parseUsageBlockFromHeaders(res.headers),
57
+ limits: parseLimitsFromHeaders(res.headers),
58
+ meta: {
59
+ requestId: res.headers.get('x-request-id') ?? undefined,
60
+ status: res.status,
61
+ headers: res.headers,
62
+ },
63
+ };
64
+ }
65
+ /** Streaming TTS. Starts yielding chunks as soon as the server writes
66
+ * them, without buffering the whole response. */
67
+ async stream(request, opts = {}) {
68
+ const res = await this.transport.request({
69
+ method: 'POST',
70
+ path: '/v1/audio/speech',
71
+ json: { ...request, stream: true },
72
+ accept: 'audio/*',
73
+ headers: { accept: 'audio/*' },
74
+ stream: true,
75
+ ...(opts.idempotencyKey !== undefined ? { idempotencyKey: opts.idempotencyKey } : {}),
76
+ ...(opts.signal !== undefined ? { signal: opts.signal } : {}),
77
+ });
78
+ if (!res.body) {
79
+ throw new ConnectionError({
80
+ message: 'Hakim SDK: TTS streaming response has no body',
81
+ requestId: res.headers.get('x-request-id') ?? undefined,
82
+ });
83
+ }
84
+ return {
85
+ stream: iterateReader(res.body),
86
+ contentType: res.headers.get('content-type') ?? 'application/octet-stream',
87
+ usageCharacters: parsePositiveInt(res.headers.get('x-usage-characters')),
88
+ usage: parseUsageBlockFromHeaders(res.headers),
89
+ limits: parseLimitsFromHeaders(res.headers),
90
+ meta: {
91
+ requestId: res.headers.get('x-request-id') ?? undefined,
92
+ status: res.status,
93
+ headers: res.headers,
94
+ },
95
+ };
96
+ }
97
+ }
98
+ /** Convert a `ReadableStream<Uint8Array>` (returned by fetch on Node 18+)
99
+ * to an `AsyncIterable<Uint8Array>` so callers can `for await …`. */
100
+ async function* iterateReader(body) {
101
+ const reader = body.getReader();
102
+ try {
103
+ while (true) {
104
+ const { done, value } = await reader.read();
105
+ if (done)
106
+ return;
107
+ if (value)
108
+ yield value;
109
+ }
110
+ }
111
+ finally {
112
+ // Release the reader lock so the stream can be GC'd if the caller
113
+ // bailed out mid-iteration.
114
+ reader.releaseLock();
115
+ }
116
+ }
117
+ function parsePositiveInt(raw) {
118
+ if (!raw)
119
+ return undefined;
120
+ const n = Number(raw);
121
+ if (!Number.isFinite(n) || n < 0)
122
+ return undefined;
123
+ return Math.floor(n);
124
+ }
125
+ //# sourceMappingURL=speech.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech.js","sourceRoot":"","sources":["../../src/audio/speech.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Realtime STT over WebSocket (`WSS /v1/audio/transcriptions/stream`).
3
+ *
4
+ * The SDK translates the server's `session.created` / `transcription.delta`
5
+ * / `transcription.done` / `error` frames into friendly
6
+ * `TranscriptionStreamEvent`s and translates caller audio chunks into
7
+ * base64-encoded `input_audio_buffer.append` frames.
8
+ *
9
+ * The SDK stays dependency-free. We prefer `globalThis.WebSocket` when
10
+ * present (Node 22+, Bun, Deno, browsers). On Node 18/20 the global
11
+ * isn't there — we dynamically import `ws` at runtime. Consumers on
12
+ * those engines must install `ws` alongside `@tryhakim/voice`; we surface
13
+ * a helpful error if it's missing instead of blowing up with an
14
+ * opaque module-not-found trace.
15
+ *
16
+ * The handle is lazy: the WebSocket opens on the first call to
17
+ * `sendAudio` / `close` / the first consumer iteration of `events`.
18
+ * This keeps the hot path fast and avoids dangling connections when a
19
+ * caller creates a handle but bails before sending anything.
20
+ */
21
+ import type { Transport } from '../transport.js';
22
+ import type { TranscriptionStreamEvent, TranscriptionStreamHandle, TranscriptionStreamOptions } from '../types.js';
23
+ export declare function openTranscriptionStream(transport: Transport, opts: TranscriptionStreamOptions): TranscriptionStreamHandle;
24
+ declare function translateFrame(frame: unknown): TranscriptionStreamEvent | null;
25
+ declare function buildSessionUpdate(opts: TranscriptionStreamOptions): {
26
+ type: 'session.update';
27
+ session: Record<string, unknown>;
28
+ } | null;
29
+ declare function buildWsUrl(baseURL: string): string;
30
+ declare function estimateAudioMs(byteLength: number, sampleRate: number, format: 'pcm16'): number | undefined;
31
+ export declare const __internals: {
32
+ translateFrame: typeof translateFrame;
33
+ buildSessionUpdate: typeof buildSessionUpdate;
34
+ buildWsUrl: typeof buildWsUrl;
35
+ estimateAudioMs: typeof estimateAudioMs;
36
+ };
37
+ export {};
38
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/audio/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAGV,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAE3B,MAAM,aAAa,CAAC;AAerB,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,0BAA0B,GAC/B,yBAAyB,CAyN3B;AA6CD,iBAAS,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,GAAG,IAAI,CA+EvE;AAED,iBAAS,kBAAkB,CACzB,IAAI,EAAE,0BAA0B,GAC/B;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAQrE;AAED,iBAAS,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,iBAAS,eAAe,CACtB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,MAAM,GAAG,SAAS,CAKpB;AAgGD,eAAO,MAAM,WAAW;;;;;CAAsE,CAAC"}
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Realtime STT over WebSocket (`WSS /v1/audio/transcriptions/stream`).
3
+ *
4
+ * The SDK translates the server's `session.created` / `transcription.delta`
5
+ * / `transcription.done` / `error` frames into friendly
6
+ * `TranscriptionStreamEvent`s and translates caller audio chunks into
7
+ * base64-encoded `input_audio_buffer.append` frames.
8
+ *
9
+ * The SDK stays dependency-free. We prefer `globalThis.WebSocket` when
10
+ * present (Node 22+, Bun, Deno, browsers). On Node 18/20 the global
11
+ * isn't there — we dynamically import `ws` at runtime. Consumers on
12
+ * those engines must install `ws` alongside `@tryhakim/voice`; we surface
13
+ * a helpful error if it's missing instead of blowing up with an
14
+ * opaque module-not-found trace.
15
+ *
16
+ * The handle is lazy: the WebSocket opens on the first call to
17
+ * `sendAudio` / `close` / the first consumer iteration of `events`.
18
+ * This keeps the hot path fast and avoids dangling connections when a
19
+ * caller creates a handle but bails before sending anything.
20
+ */
21
+ import { ConnectionError, HakimError } from '../errors.js';
22
+ import { SDK_NAME, SDK_VERSION } from '../version.js';
23
+ export function openTranscriptionStream(transport, opts) {
24
+ const url = buildWsUrl(transport.baseURL);
25
+ const apiKey = transport.apiKey;
26
+ // Accumulated audio chunks / control frames queued before the socket
27
+ // is OPEN. Flushed in-order on open.
28
+ const pending = [];
29
+ let socket = null;
30
+ let openPromise = null;
31
+ const queue = [];
32
+ let waiter = null;
33
+ let streamClosed = false;
34
+ let closedResolve;
35
+ const closedPromise = new Promise((r) => {
36
+ closedResolve = r;
37
+ });
38
+ function emit(ev) {
39
+ if (streamClosed)
40
+ return;
41
+ if (waiter) {
42
+ const w = waiter;
43
+ waiter = null;
44
+ w({ value: ev, done: false });
45
+ }
46
+ else {
47
+ queue.push(ev);
48
+ }
49
+ }
50
+ function finishStream() {
51
+ if (streamClosed)
52
+ return;
53
+ streamClosed = true;
54
+ if (waiter) {
55
+ const w = waiter;
56
+ waiter = null;
57
+ w({ value: undefined, done: true });
58
+ }
59
+ closedResolve();
60
+ }
61
+ async function ensureOpen() {
62
+ if (socket)
63
+ return socket;
64
+ if (openPromise)
65
+ return openPromise;
66
+ openPromise = (async () => {
67
+ const Ctor = await resolveSocketCtor();
68
+ const headers = {
69
+ Authorization: `Bearer ${apiKey}`,
70
+ 'User-Agent': `${SDK_NAME}/${SDK_VERSION}`,
71
+ };
72
+ // `ws` on Node takes `{ headers }` as second arg; the browser
73
+ // `WebSocket` ignores extra args — in the browser the auth has
74
+ // to come from a subprotocol token. For the SDK-in-Node path we
75
+ // always have headers available; for custom browser usage, the
76
+ // caller should pre-construct a socket (future extension point).
77
+ const s = new Ctor(url, { headers });
78
+ await new Promise((resolve, reject) => {
79
+ const onOpen = () => {
80
+ detach();
81
+ resolve();
82
+ };
83
+ const onError = (err) => {
84
+ detach();
85
+ reject(new ConnectionError({
86
+ message: 'Hakim SDK: could not open WebSocket to ' +
87
+ `${url}. Is HAKIM_API_KEY valid and the network reachable?` +
88
+ (err instanceof Error ? ` Cause: ${err.message}` : ''),
89
+ requestId: undefined,
90
+ }));
91
+ };
92
+ const detach = () => {
93
+ removeListener(s, 'open', onOpen);
94
+ removeListener(s, 'error', onError);
95
+ };
96
+ addListener(s, 'open', onOpen);
97
+ addListener(s, 'error', onError);
98
+ });
99
+ attachSocketHandlers(s, emit, finishStream);
100
+ socket = s;
101
+ // Send the initial session.update using the caller's opts.
102
+ const sessionUpdate = buildSessionUpdate(opts);
103
+ if (sessionUpdate) {
104
+ s.send(JSON.stringify(sessionUpdate));
105
+ }
106
+ // Flush anything queued while we were connecting.
107
+ for (const frame of pending.splice(0)) {
108
+ s.send(frame);
109
+ }
110
+ return s;
111
+ })();
112
+ return openPromise;
113
+ }
114
+ function enqueueFrame(frame) {
115
+ if (socket && socket.readyState === 1 /* OPEN */) {
116
+ socket.send(frame);
117
+ }
118
+ else {
119
+ pending.push(frame);
120
+ // Fire-and-forget the open; errors surface on the iterator.
121
+ ensureOpen().catch((err) => {
122
+ if (err instanceof HakimError || err instanceof ConnectionError) {
123
+ emit({
124
+ type: 'error',
125
+ code: err.code ?? 'connection_error',
126
+ message: err.message,
127
+ });
128
+ }
129
+ finishStream();
130
+ });
131
+ }
132
+ }
133
+ function sendAudio(chunk) {
134
+ if (streamClosed) {
135
+ throw new HakimError({
136
+ type: 'invalid_request_error',
137
+ code: 'stream_closed',
138
+ message: 'Hakim SDK: cannot send audio; stream is closed.',
139
+ status: 400,
140
+ requestId: undefined,
141
+ });
142
+ }
143
+ const bytes = toUint8Array(chunk);
144
+ const frame = {
145
+ type: 'input_audio_buffer.append',
146
+ audio: bufferToBase64(bytes),
147
+ };
148
+ const durationMs = estimateAudioMs(bytes.byteLength, opts.sample_rate ?? 16000, opts.audio_format ?? 'pcm16');
149
+ if (durationMs !== undefined)
150
+ frame.audio_ms = durationMs;
151
+ enqueueFrame(JSON.stringify(frame));
152
+ }
153
+ async function close() {
154
+ if (streamClosed)
155
+ return;
156
+ // Commit any buffered audio, then ask the server to close.
157
+ enqueueFrame(JSON.stringify({ type: 'input_audio_buffer.commit' }));
158
+ enqueueFrame(JSON.stringify({ type: 'session.close' }));
159
+ // Wait for the server to emit `usage` + close the socket.
160
+ await closedPromise;
161
+ }
162
+ // Wire the caller-supplied AbortSignal to a clean close.
163
+ if (opts.signal) {
164
+ if (opts.signal.aborted) {
165
+ Promise.resolve()
166
+ .then(() => close())
167
+ .catch(() => undefined);
168
+ }
169
+ else {
170
+ opts.signal.addEventListener('abort', () => {
171
+ close().catch(() => undefined);
172
+ }, { once: true });
173
+ }
174
+ }
175
+ const events = {
176
+ [Symbol.asyncIterator]() {
177
+ return {
178
+ next() {
179
+ if (queue.length > 0) {
180
+ return Promise.resolve({ value: queue.shift(), done: false });
181
+ }
182
+ if (streamClosed) {
183
+ return Promise.resolve({
184
+ value: undefined,
185
+ done: true,
186
+ });
187
+ }
188
+ return new Promise((resolve) => {
189
+ waiter = resolve;
190
+ // Opening lazily: if the caller started by iterating
191
+ // events (without any sendAudio yet), kick the socket
192
+ // open so `session.created` / `error` can land.
193
+ if (!socket && !openPromise) {
194
+ ensureOpen().catch((err) => {
195
+ if (!streamClosed) {
196
+ emit({
197
+ type: 'error',
198
+ code: err?.code ?? 'connection_error',
199
+ message: err instanceof Error ? err.message : 'connection error',
200
+ });
201
+ finishStream();
202
+ }
203
+ });
204
+ }
205
+ });
206
+ },
207
+ return() {
208
+ close().catch(() => undefined);
209
+ return Promise.resolve({
210
+ value: undefined,
211
+ done: true,
212
+ });
213
+ },
214
+ };
215
+ },
216
+ };
217
+ return {
218
+ sendAudio,
219
+ events,
220
+ close,
221
+ closed: closedPromise,
222
+ };
223
+ }
224
+ function attachSocketHandlers(s, emit, finishStream) {
225
+ const onMessage = (raw) => {
226
+ // In `ws` Node, raw is a Buffer-like; in browsers, raw.data is a
227
+ // string. Normalise.
228
+ const text = extractMessageText(raw);
229
+ if (text === null)
230
+ return;
231
+ let parsed;
232
+ try {
233
+ parsed = JSON.parse(text);
234
+ }
235
+ catch {
236
+ return;
237
+ }
238
+ const translated = translateFrame(parsed);
239
+ if (translated)
240
+ emit(translated);
241
+ };
242
+ const onClose = () => {
243
+ finishStream();
244
+ };
245
+ addListener(s, 'message', onMessage);
246
+ addListener(s, 'close', onClose);
247
+ }
248
+ function extractMessageText(raw) {
249
+ if (typeof raw === 'string')
250
+ return raw;
251
+ // Browser MessageEvent: `{ data: string | ArrayBuffer | Blob }`.
252
+ if (raw && typeof raw === 'object' && 'data' in raw) {
253
+ const d = raw.data;
254
+ if (typeof d === 'string')
255
+ return d;
256
+ if (d instanceof ArrayBuffer)
257
+ return new TextDecoder().decode(d);
258
+ if (ArrayBuffer.isView(d)) {
259
+ return new TextDecoder().decode(new Uint8Array(d.buffer, d.byteOffset, d.byteLength));
260
+ }
261
+ return null;
262
+ }
263
+ // `ws` Node 'message' listener receives (data, isBinary) — Buffer.
264
+ if (raw instanceof Uint8Array)
265
+ return new TextDecoder().decode(raw);
266
+ return null;
267
+ }
268
+ function translateFrame(frame) {
269
+ if (!frame || typeof frame !== 'object')
270
+ return null;
271
+ const f = frame;
272
+ switch (f.type) {
273
+ case 'transcription.delta': {
274
+ const d = frame;
275
+ if (typeof d.text !== 'string')
276
+ return null;
277
+ const seq = typeof d.event_id === 'number' ? d.event_id : 0;
278
+ if (d.is_final === true) {
279
+ const ev = {
280
+ type: 'final',
281
+ text: d.text,
282
+ seq,
283
+ };
284
+ if (typeof d.start_ms === 'number')
285
+ ev.start = d.start_ms / 1000;
286
+ if (typeof d.end_ms === 'number')
287
+ ev.end = d.end_ms / 1000;
288
+ return ev;
289
+ }
290
+ const partial = {
291
+ type: 'partial',
292
+ text: d.text,
293
+ seq,
294
+ };
295
+ return partial;
296
+ }
297
+ case 'transcription.done': {
298
+ const d = frame;
299
+ // `transcription.done` carries the final stitched text; expose it
300
+ // as a `final` event so callers see a single committed snapshot
301
+ // per commit window.
302
+ if (typeof d.text === 'string') {
303
+ const ev = {
304
+ type: 'final',
305
+ text: d.text,
306
+ seq: typeof d.event_id === 'number' ? d.event_id : 0,
307
+ };
308
+ if (typeof d.language === 'string')
309
+ ev.language = d.language;
310
+ return ev;
311
+ }
312
+ return null;
313
+ }
314
+ case 'session.usage':
315
+ case 'usage': {
316
+ const d = frame;
317
+ const seconds = typeof d.seconds === 'number'
318
+ ? d.seconds
319
+ : typeof d.audio_ms === 'number'
320
+ ? d.audio_ms / 1000
321
+ : null;
322
+ if (seconds === null)
323
+ return null;
324
+ const ev = { type: 'usage', seconds };
325
+ return ev;
326
+ }
327
+ case 'error': {
328
+ const d = frame;
329
+ return {
330
+ type: 'error',
331
+ code: typeof d.code === 'string' ? d.code : 'unknown_error',
332
+ message: typeof d.message === 'string' ? d.message : 'unknown error',
333
+ };
334
+ }
335
+ case 'session.created':
336
+ // Informational — don't surface to callers.
337
+ return null;
338
+ default:
339
+ return null;
340
+ }
341
+ }
342
+ function buildSessionUpdate(opts) {
343
+ const session = {};
344
+ if (opts.model !== undefined)
345
+ session.model = opts.model;
346
+ if (opts.language !== undefined)
347
+ session.language = opts.language;
348
+ if (opts.sample_rate !== undefined)
349
+ session.input_sample_rate = opts.sample_rate;
350
+ if (opts.audio_format !== undefined)
351
+ session.input_audio_format = opts.audio_format;
352
+ if (Object.keys(session).length === 0)
353
+ return null;
354
+ return { type: 'session.update', session };
355
+ }
356
+ function buildWsUrl(baseURL) {
357
+ const u = new URL(baseURL);
358
+ u.protocol = u.protocol === 'https:' ? 'wss:' : 'ws:';
359
+ u.pathname = u.pathname.replace(/\/$/, '') + '/v1/audio/transcriptions/stream';
360
+ return u.toString();
361
+ }
362
+ function estimateAudioMs(byteLength, sampleRate, format) {
363
+ if (format === 'pcm16' && sampleRate > 0) {
364
+ return Math.round((byteLength / 2 / sampleRate) * 1000);
365
+ }
366
+ return undefined;
367
+ }
368
+ function toUint8Array(chunk) {
369
+ if (chunk instanceof Uint8Array)
370
+ return chunk;
371
+ if (chunk instanceof ArrayBuffer)
372
+ return new Uint8Array(chunk);
373
+ if (ArrayBuffer.isView(chunk)) {
374
+ return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
375
+ }
376
+ throw new HakimError({
377
+ type: 'invalid_request_error',
378
+ code: 'invalid_audio_chunk',
379
+ message: `Hakim SDK: unsupported audio chunk type (${typeof chunk}). Pass a Uint8Array, Buffer, ArrayBuffer, or ArrayBufferView.`,
380
+ status: 400,
381
+ requestId: undefined,
382
+ });
383
+ }
384
+ function bufferToBase64(bytes) {
385
+ // Node + Bun have Buffer; browsers have btoa. Handle both.
386
+ if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {
387
+ return Buffer.from(bytes).toString('base64');
388
+ }
389
+ let binary = '';
390
+ for (let i = 0; i < bytes.byteLength; i++) {
391
+ binary += String.fromCharCode(bytes[i]);
392
+ }
393
+ return btoa(binary);
394
+ }
395
+ function addListener(socket, type, listener) {
396
+ if (socket.addEventListener) {
397
+ socket.addEventListener(type, listener);
398
+ }
399
+ else if (socket.on) {
400
+ socket.on(type, listener);
401
+ }
402
+ }
403
+ function removeListener(socket, type, listener) {
404
+ // `ws` supports .off() on EventEmitter; browser WebSocket supports
405
+ // .removeEventListener(). Support both.
406
+ const s = socket;
407
+ if (s.removeEventListener)
408
+ s.removeEventListener(type, listener);
409
+ else if (s.off)
410
+ s.off(type, listener);
411
+ }
412
+ let _socketCtor = null;
413
+ let _socketCtorPromise = null;
414
+ async function resolveSocketCtor() {
415
+ if (_socketCtor)
416
+ return _socketCtor;
417
+ if (_socketCtorPromise)
418
+ return _socketCtorPromise;
419
+ const globalWs = globalThis.WebSocket;
420
+ if (globalWs) {
421
+ _socketCtor = globalWs;
422
+ return globalWs;
423
+ }
424
+ _socketCtorPromise = (async () => {
425
+ try {
426
+ // Dynamic import so a bundler building for the browser doesn't
427
+ // try to statically resolve `ws`.
428
+ // Dynamic import with a computed specifier so `tsc` doesn't
429
+ // try to resolve `ws`'s types at compile time (the SDK ships
430
+ // zero deps; `ws` is only resolved at runtime on older Node).
431
+ const mod = await new Function('s', 'return import(s)')('ws');
432
+ const Ctor = mod.default ?? mod.WebSocket;
433
+ if (!Ctor)
434
+ throw new Error('ws module did not export a WebSocket class');
435
+ _socketCtor = Ctor;
436
+ return Ctor;
437
+ }
438
+ catch (err) {
439
+ throw new HakimError({
440
+ type: 'invalid_request_error',
441
+ code: 'websocket_impl_missing',
442
+ message: 'Hakim SDK: realtime STT requires a WebSocket implementation. On Node 22+ / Bun / Deno / browsers it is built in. On Node 18 / 20, run `npm install ws` alongside @tryhakim/voice. ' +
443
+ (err instanceof Error ? `(cause: ${err.message})` : ''),
444
+ status: 0,
445
+ requestId: undefined,
446
+ });
447
+ }
448
+ })();
449
+ return _socketCtorPromise;
450
+ }
451
+ export const __internals = { translateFrame, buildSessionUpdate, buildWsUrl, estimateAudioMs };
452
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/audio/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared helper for multipart uploads. Normalizes the broad SDK
3
+ * `AudioInput` union into a single `Blob` suitable for
4
+ * `FormData.append`. Extracted so the transcriptions + voices (clone)
5
+ * endpoints use identical input-coercion rules — a future multipart
6
+ * endpoint can import this helper instead of re-rolling it.
7
+ */
8
+ import type { AudioInput } from '../types.js';
9
+ export declare function audioInputToBlob(input: AudioInput, filename: string): Promise<Blob>;
10
+ //# sourceMappingURL=to-blob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-blob.d.ts","sourceRoot":"","sources":["../../src/audio/to-blob.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CzF"}