kugelaudio 0.7.0 → 0.9.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/dist/index.d.ts CHANGED
@@ -34,6 +34,7 @@ interface Voice {
34
34
  category?: VoiceCategory;
35
35
  sex?: VoiceSex;
36
36
  age?: VoiceAge;
37
+ quality?: string;
37
38
  supportedLanguages: string[];
38
39
  sampleText?: string;
39
40
  avatarUrl?: string;
@@ -221,7 +222,7 @@ interface GenerateOptions {
221
222
  modelId?: string;
222
223
  /** Voice ID to use */
223
224
  voiceId?: number;
224
- /** CFG scale for generation (default: 2.0) */
225
+ /** Classifier-free guidance scale. Clamped to [1.2, 2.5] (default: 2.0). */
225
226
  cfgScale?: number;
226
227
  /**
227
228
  * Sampling variance. Range [0.0, 1.0]. 0 = most stable (near-greedy),
@@ -235,6 +236,12 @@ interface GenerateOptions {
235
236
  maxNewTokens?: number;
236
237
  /** Output sample rate (default: 24000) */
237
238
  sampleRate?: number;
239
+ /**
240
+ * Combined codec+rate token, e.g. 'ulaw_8000' / 'alaw_8000' / 'pcm_8000'.
241
+ * Opt-in; when set it is authoritative and must not contradict sampleRate.
242
+ * Absent ⇒ legacy PCM16 at sampleRate.
243
+ */
244
+ outputFormat?: string;
238
245
  /**
239
246
  * Enable text normalization (converts numbers, dates, etc. to spoken words).
240
247
  * When true, text will be normalized before TTS generation.
@@ -263,8 +270,9 @@ interface GenerateOptions {
263
270
  /**
264
271
  * Playback speed multiplier (0.8 = slower, 1.0 = normal, 1.2 = faster).
265
272
  *
266
- * Uses pitch-preserving time-stretching (WSOLA). Inline `<prosody rate="...">` tags
267
- * can also be used for per-segment speed control.
273
+ * Uses pitch-preserving time-stretching (WSOLA); applies to the whole
274
+ * request. Wrap text in `<prosody rate="slow|medium|fast|0.8-1.2">` to
275
+ * override the rate for a span (the span rate wins inside the span).
268
276
  * Range: [0.8, 1.2]. Default: 1.0.
269
277
  */
270
278
  speed?: number;
@@ -275,6 +283,14 @@ interface GenerateOptions {
275
283
  * server treats the value as trusted once received.
276
284
  */
277
285
  projectId?: number;
286
+ /**
287
+ * Per-request dictionary selection. Omit for the default behavior (all
288
+ * active dictionaries of the project apply, filtered by language). An
289
+ * empty array disables dictionaries for this request. A list of
290
+ * dictionary IDs applies exactly those dictionaries — including
291
+ * inactive ones — bypassing the language filter.
292
+ */
293
+ dictionaryIds?: number[];
278
294
  }
279
295
  /**
280
296
  * Streaming session configuration for `/ws/tts/stream`.
@@ -298,7 +314,7 @@ interface StreamConfig {
298
314
  voiceId?: number;
299
315
  /** Model ID. Default: 'kugel-3'. Legacy ids still accepted; they alias to kugel-3 server-side. */
300
316
  modelId?: string;
301
- /** CFG scale for generation */
317
+ /** Classifier-free guidance scale. Clamped to [1.2, 2.5] (default: 2.0). */
302
318
  cfgScale?: number;
303
319
  /**
304
320
  * Sampling variance. Range [0.0, 1.0]. 0 = most stable, 1 = most variance.
@@ -309,6 +325,8 @@ interface StreamConfig {
309
325
  maxNewTokens?: number;
310
326
  /** Output sample rate */
311
327
  sampleRate?: number;
328
+ /** Combined codec+rate token (e.g. 'ulaw_8000'); opt-in, set-once per session. */
329
+ outputFormat?: string;
312
330
  /** Auto-flush timeout in milliseconds */
313
331
  flushTimeoutMs?: number;
314
332
  /** Maximum buffer length */
@@ -353,11 +371,55 @@ interface StreamConfig {
353
371
  /**
354
372
  * Playback speed multiplier (0.8 = slower, 1.0 = normal, 1.2 = faster).
355
373
  *
356
- * Uses pitch-preserving time-stretching (WSOLA). Inline `<prosody rate="...">` tags
357
- * can also be used for per-segment speed control.
374
+ * Uses pitch-preserving time-stretching (WSOLA); applies to the whole
375
+ * request. Wrap text in `<prosody rate="slow|medium|fast|0.8-1.2">` to
376
+ * override the rate for a span (the span rate wins inside the span).
358
377
  * Range: [0.8, 1.2]. Default: 1.0.
359
378
  */
360
379
  speed?: number;
380
+ /**
381
+ * Per-request dictionary selection. Omit for the default behavior (all
382
+ * active dictionaries of the project apply, filtered by language). An
383
+ * empty array disables dictionaries for this request. A list of
384
+ * dictionary IDs applies exactly those dictionaries — including
385
+ * inactive ones — bypassing the language filter.
386
+ */
387
+ dictionaryIds?: number[];
388
+ }
389
+ /**
390
+ * Generation parameters changeable mid-connection via
391
+ * {@link StreamingSession.updateSettings} / {@link MultiContextSession.updateSettings}
392
+ * (KUG-1166). Every field is optional; an update changes only the fields it
393
+ * carries. Identity / audio-format fields (`voiceId`, `modelId`, `sampleRate`,
394
+ * `outputFormat`, `dictionaryIds`) are NOT here — they are fixed for the
395
+ * connection's lifetime and the server rejects them in an update.
396
+ */
397
+ interface SettingsUpdate {
398
+ /** Classifier-free guidance scale (0.0–10.0). */
399
+ cfgScale?: number;
400
+ /** Sampling variance (0.0–1.0). */
401
+ temperature?: number;
402
+ /** Playback speed multiplier (0.8–1.2). */
403
+ speed?: number;
404
+ /** Maximum tokens per generation (1–8192). */
405
+ maxNewTokens?: number;
406
+ /** Language code for normalization (e.g. `'de'`). */
407
+ language?: string;
408
+ /** Enable text normalization. */
409
+ normalize?: boolean;
410
+ }
411
+ /**
412
+ * The generation parameters in effect after an
413
+ * {@link StreamingSession.updateSettings} call — the server's echo. Fields the
414
+ * session never set come back `null` (e.g. `temperature`, `language`).
415
+ */
416
+ interface EffectiveSettings {
417
+ cfgScale?: number;
418
+ temperature?: number | null;
419
+ speed?: number;
420
+ maxNewTokens?: number;
421
+ language?: string | null;
422
+ normalize?: boolean;
361
423
  }
362
424
  /**
363
425
  * Event callbacks for a streaming session (`/ws/tts/stream`).
@@ -374,9 +436,18 @@ interface StreamingSessionCallbacks {
374
436
  * Carries the segment index, total audio duration, and generation time.
375
437
  */
376
438
  onChunkComplete?: (chunkId: number, audioSeconds: number, genMs: number) => void;
439
+ /**
440
+ * Called when the server marks the end of a turn's audio
441
+ * (`{"final": true, ...}` — sent after the last audio frame of every
442
+ * gracefully completed turn, right before `session_closed`). The
443
+ * ElevenLabs `isFinal` equivalent: once this fires, no further audio
444
+ * for the turn will arrive. Not fired on a barge-in cancel — that
445
+ * path fires {@link onInterrupted} instead.
446
+ */
447
+ onFinal?: (totalAudioSeconds: number, totalTextChunks: number, totalAudioChunks: number) => void;
377
448
  /**
378
449
  * Called when the session is fully closed (after `session.close()`).
379
- * Equivalent to `onFinal` on the one-shot endpoint.
450
+ * Fires right after {@link onFinal} and additionally carries usage.
380
451
  */
381
452
  onSessionClosed?: (totalAudioSeconds: number, totalTextChunks: number, totalAudioChunks: number) => void;
382
453
  /** Called when the server begins generating audio for a text segment. */
@@ -393,14 +464,45 @@ interface StreamingSessionCallbacks {
393
464
  /** Called on any error. */
394
465
  onError?: (error: Error) => void;
395
466
  }
467
+ /**
468
+ * Per-session usage reported in the `session_closed` frame (KUG-1192).
469
+ *
470
+ * Lets you bill your own customers per conversation. `costCents` is the
471
+ * actual amount charged in **EUR cents**. When the charge could not be
472
+ * determined at session end (e.g. a transient billing error) `costCents` is
473
+ * `null` and `costAvailable` is `false` — never a misleading `0`.
474
+ * `audioSeconds` is always reported. On `/ws/tts/multi` usage is reported per
475
+ * context (per conversation) on each `context_closed` frame, not aggregated
476
+ * across contexts.
477
+ */
478
+ interface SessionUsage {
479
+ /** Total audio generated this session, in seconds (the unit we bill on). */
480
+ audioSeconds: number;
481
+ /** Actual amount charged in EUR cents, or `null` if undetermined. */
482
+ costCents: number | null;
483
+ /** Currency of `costCents` (`"eur"`); present only when `costCents` is set. */
484
+ currency?: string;
485
+ /** Total input characters submitted this session, if reported. */
486
+ characters?: number;
487
+ /** Model that produced the audio, if reported. */
488
+ modelId?: string;
489
+ /** `true` when an authoritative charge was returned for this session. */
490
+ costAvailable: boolean;
491
+ }
492
+ /**
493
+ * Parse the raw `usage` object (or a legacy `session_closed` payload without
494
+ * one) into a typed {@link SessionUsage}. Returns `null` when no usage info
495
+ * is present.
496
+ */
497
+ declare function parseSessionUsage(data: Record<string, unknown>): SessionUsage | null;
396
498
  /**
397
499
  * Audio chunk from streaming TTS.
398
500
  */
399
501
  interface AudioChunk {
400
502
  /** Raw PCM16 audio as base64 */
401
503
  audio: string;
402
- /** Encoding format */
403
- encoding: 'pcm_s16le';
504
+ /** Encoding format. 'mulaw' / 'alaw' only when output_format requested G.711. */
505
+ encoding: 'pcm_s16le' | 'mulaw' | 'alaw';
404
506
  /** Chunk index */
405
507
  index: number;
406
508
  /** Sample rate */
@@ -426,6 +528,12 @@ interface GenerationStats {
426
528
  rtf: number;
427
529
  /** Error message if any */
428
530
  error?: string;
531
+ /**
532
+ * Per-request usage (audio time + amount charged), for billing your own
533
+ * customers. Undefined when the server reports no usage. See
534
+ * {@link SessionUsage}.
535
+ */
536
+ usage?: SessionUsage;
429
537
  }
430
538
  /**
431
539
  * Complete audio response from TTS generation.
@@ -505,7 +613,9 @@ interface MultiContextConfig {
505
613
  defaultVoiceId?: number;
506
614
  /** Output sample rate (default: 24000) */
507
615
  sampleRate?: number;
508
- /** CFG scale for generation (default: 2.0) */
616
+ /** Combined codec+rate token (e.g. 'ulaw_8000'); opt-in, set-once per context. */
617
+ outputFormat?: string;
618
+ /** Classifier-free guidance scale. Clamped to [1.2, 2.5] (default: 2.0). */
509
619
  cfgScale?: number;
510
620
  /**
511
621
  * Sampling variance. Range [0.0, 1.0]. 0 = most stable, 1 = most variance.
@@ -522,6 +632,14 @@ interface MultiContextConfig {
522
632
  * the language, which adds ~60-150ms to time-to-first-audio.
523
633
  */
524
634
  language?: string;
635
+ /**
636
+ * Per-request dictionary selection. Omit for the default behavior (all
637
+ * active dictionaries of the project apply, filtered by language). An
638
+ * empty array disables dictionaries for this request. A list of
639
+ * dictionary IDs applies exactly those dictionaries — including
640
+ * inactive ones — bypassing the language filter.
641
+ */
642
+ dictionaryIds?: number[];
525
643
  /** Seconds before context auto-closes (default: 20.0) */
526
644
  inactivityTimeout?: number;
527
645
  }
@@ -557,8 +675,20 @@ interface MultiContextCallbacks {
557
675
  onContextCreated?: (contextId: string) => void;
558
676
  /** Called when an audio chunk is received */
559
677
  onChunk?: (chunk: MultiContextAudioChunk) => void;
560
- /** Called when a context is closed */
561
- onContextClosed?: (contextId: string) => void;
678
+ /**
679
+ * Called when all audio admitted before a `{flush: true}` has been
680
+ * delivered for a context (`{"final": true, "context_id": ...}`), and
681
+ * once more before {@link onContextClosed} on a graceful close. The
682
+ * ElevenLabs multi-context `is_final` equivalent. Not fired on an
683
+ * immediate (barge-in) close.
684
+ */
685
+ onFinal?: (contextId: string) => void;
686
+ /**
687
+ * Called when a context is closed (terminal). `usage` carries this
688
+ * conversation's audio time + amount charged (undefined if not reported).
689
+ * See {@link SessionUsage}.
690
+ */
691
+ onContextClosed?: (contextId: string, usage?: SessionUsage) => void;
562
692
  /** Called when a context times out */
563
693
  onContextTimeout?: (contextId: string) => void;
564
694
  /** Called when session is closed */
@@ -912,13 +1042,25 @@ declare class MultiContextSession {
912
1042
  private config;
913
1043
  private callbacks;
914
1044
  private contexts;
1045
+ /** Contexts a create message has been sent for (not yet necessarily
1046
+ * confirmed by the server via context_created). */
1047
+ private requestedContexts;
915
1048
  private _sessionId;
1049
+ private _contextUsage;
916
1050
  private isStarted;
917
1051
  constructor(client: KugelAudio, config?: MultiContextConfig);
918
1052
  /**
919
1053
  * Get the current session ID, or null if not connected.
920
1054
  */
921
1055
  get sessionId(): string | null;
1056
+ /**
1057
+ * Per-context usage (audio time + amount charged) for a closed context, or
1058
+ * null if that context hasn't closed yet. Each context is its own
1059
+ * conversation — use this to bill per conversation. See {@link SessionUsage}.
1060
+ */
1061
+ usageFor(contextId: string): SessionUsage | null;
1062
+ /** Map of context_id → per-context usage for all closed contexts. */
1063
+ get contextUsage(): Map<string, SessionUsage>;
922
1064
  /**
923
1065
  * Connect to the multi-context WebSocket endpoint.
924
1066
  *
@@ -957,6 +1099,22 @@ declare class MultiContextSession {
957
1099
  * Send keep-alive to reset a context's inactivity timeout.
958
1100
  */
959
1101
  keepAlive(contextId: string): void;
1102
+ /**
1103
+ * Change the session's generation parameters mid-connection (KUG-1166).
1104
+ *
1105
+ * Session-scoped (there is no `contextId`): the update applies to contexts
1106
+ * started **after** it — a context already streaming keeps the settings it
1107
+ * began with, since generation parameters are bound when a context's engine
1108
+ * session opens. With the common one-context-per-turn pattern that means it
1109
+ * takes effect on the next turn. Per-context `cfgScale` / `maxNewTokens`
1110
+ * passed to {@link createContext} still win for that context.
1111
+ *
1112
+ * Resolves with the generation parameters now in effect (the server's echo).
1113
+ *
1114
+ * @throws {KugelAudioError} if no field is provided, the socket is not open,
1115
+ * or the server rejects the update.
1116
+ */
1117
+ updateSettings(settings: SettingsUpdate): Promise<EffectiveSettings>;
960
1118
  /**
961
1119
  * Close the session and all contexts.
962
1120
  */
@@ -1005,7 +1163,14 @@ declare class StreamingSession {
1005
1163
  private callbacks;
1006
1164
  private client;
1007
1165
  private configSent;
1166
+ private _lastUsage;
1008
1167
  constructor(client: KugelAudio, config: StreamConfig, callbacks: StreamingSessionCallbacks);
1168
+ /**
1169
+ * Per-session usage from the most recently closed session, or null before
1170
+ * the first session closes. Use this to bill your own customers per
1171
+ * conversation. See {@link SessionUsage}.
1172
+ */
1173
+ get lastUsage(): SessionUsage | null;
1009
1174
  /**
1010
1175
  * Open the WebSocket connection and authenticate.
1011
1176
  *
@@ -1079,6 +1244,28 @@ declare class StreamingSession {
1079
1244
  * to change voice, model, language, or other settings.
1080
1245
  */
1081
1246
  updateConfig(config: Partial<StreamConfig>): void;
1247
+ /**
1248
+ * Change generation parameters mid-connection without reconnecting (KUG-1166).
1249
+ *
1250
+ * Sends an `update_settings` message and resolves with the generation
1251
+ * parameters now in effect (the server's echo). Only the six fields of
1252
+ * {@link SettingsUpdate} are updatable; identity / audio-format fields
1253
+ * (`voiceId`, `modelId`, `sampleRate`, `outputFormat`, `dictionaryIds`) are
1254
+ * fixed for the connection — change those with {@link updateConfig} after
1255
+ * {@link endSession} instead.
1256
+ *
1257
+ * The change applies to the **next turn**: a turn already streaming keeps the
1258
+ * settings it started with, so call this between turns.
1259
+ *
1260
+ * @example
1261
+ * ```typescript
1262
+ * const effective = await session.updateSettings({ cfgScale: 1.5, speed: 1.1 });
1263
+ * ```
1264
+ *
1265
+ * @throws {KugelAudioError} if no field is provided, the socket is not open,
1266
+ * or the server rejects the update (e.g. a value out of range).
1267
+ */
1268
+ updateSettings(settings: SettingsUpdate): Promise<EffectiveSettings>;
1082
1269
  /**
1083
1270
  * Close the session and the WebSocket connection.
1084
1271
  *
@@ -1334,9 +1521,6 @@ declare function classifyWsClose(code: number | undefined, reason?: string): Kug
1334
1521
  */
1335
1522
  declare function classifyWsHandshakeError(err: unknown): KugelAudioError | null;
1336
1523
 
1337
- /**
1338
- * Utility functions for KugelAudio SDK.
1339
- */
1340
1524
  /**
1341
1525
  * Decode base64 string to ArrayBuffer.
1342
1526
  */
@@ -1354,4 +1538,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
1354
1538
  */
1355
1539
  declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
1356
1540
 
1357
- export { type AudioChunk, type AudioResponse, AuthenticationError, type BulkReplaceResult, ConnectionError, type ContextVoiceSettings, type CreateDictionaryOptions, type CreateVoiceOptions, DictionariesResource, type Dictionary, DictionaryEntriesResource, type DictionaryEntry, type DictionaryEntryInput, type DictionaryEntryListResponse, type ErrorCode, ErrorCodes, type GenerateOptions, type GenerationStats, InsufficientCreditsError, KugelAudio, KugelAudioError, type KugelAudioErrorOptions, type KugelAudioOptions, type Model, type MultiContextAudioChunk, type MultiContextCallbacks, type MultiContextConfig, NotFoundError, RateLimitError, type Region, type StreamCallbacks, type StreamConfig, type StreamingSessionCallbacks, type UpdateDictionaryEntryOptions, type UpdateDictionaryOptions, type UpdateVoiceOptions, ValidationError, type Voice, type VoiceAge, type VoiceCategory, type VoiceDetail, type VoiceListResponse, type VoiceQuality, type VoiceReference, type VoiceSex, type WordTimestamp, WsCloseCodes, base64ToArrayBuffer, classifyHttpError, classifyWsClose, classifyWsFrame, classifyWsHandshakeError, createWavBlob, createWavFile, decodePCM16 };
1541
+ export { type AudioChunk, type AudioResponse, AuthenticationError, type BulkReplaceResult, ConnectionError, type ContextVoiceSettings, type CreateDictionaryOptions, type CreateVoiceOptions, DictionariesResource, type Dictionary, DictionaryEntriesResource, type DictionaryEntry, type DictionaryEntryInput, type DictionaryEntryListResponse, type EffectiveSettings, type ErrorCode, ErrorCodes, type GenerateOptions, type GenerationStats, InsufficientCreditsError, KugelAudio, KugelAudioError, type KugelAudioErrorOptions, type KugelAudioOptions, type Model, type MultiContextAudioChunk, type MultiContextCallbacks, type MultiContextConfig, NotFoundError, RateLimitError, type Region, type SessionUsage, type SettingsUpdate, type StreamCallbacks, type StreamConfig, type StreamingSessionCallbacks, type UpdateDictionaryEntryOptions, type UpdateDictionaryOptions, type UpdateVoiceOptions, ValidationError, type Voice, type VoiceAge, type VoiceCategory, type VoiceDetail, type VoiceListResponse, type VoiceQuality, type VoiceReference, type VoiceSex, type WordTimestamp, WsCloseCodes, base64ToArrayBuffer, classifyHttpError, classifyWsClose, classifyWsFrame, classifyWsHandshakeError, createWavBlob, createWavFile, decodePCM16, parseSessionUsage };