kugelaudio 0.4.0 → 0.6.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/CHANGELOG.md +17 -0
- package/README.md +36 -0
- package/dist/index.d.mts +221 -3
- package/dist/index.d.ts +221 -3
- package/dist/index.js +283 -3
- package/dist/index.mjs +280 -3
- package/package.json +1 -1
- package/src/client.test.ts +115 -0
- package/src/client.ts +110 -3
- package/src/dictionaries.test.ts +212 -0
- package/src/dictionaries.ts +278 -0
- package/src/errors.ts +24 -1
- package/src/index.ts +11 -0
- package/src/types.ts +95 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## [kugelaudio-v0.6.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.5.0...js-sdk-v0.6.0) (2026-06-01)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* streaming barge-in (cancelCurrent) across server + JS/Python/Java SDKs ([#1210](https://github.com/Kugelaudio/KugelAudio/issues/1210)) ([341e54f](https://github.com/Kugelaudio/KugelAudio/commit/341e54f169b4dd9242272b249fca30f005bfc3b8))
|
|
6
|
+
|
|
7
|
+
## [kugelaudio-v0.5.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.4.0...js-sdk-v0.5.0) (2026-05-21)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **ingress,sdks:** public API for custom word dictionaries (KUG-765) ([#875](https://github.com/Kugelaudio/KugelAudio/issues/875)) ([9988924](https://github.com/Kugelaudio/KugelAudio/commit/99889244997d1cb4dba9714e2633d84ace9852a3))
|
|
12
|
+
* **sdk:** add NotFoundError for unknown resources (KUG-423) ([#872](https://github.com/Kugelaudio/KugelAudio/issues/872)) ([d613b0f](https://github.com/Kugelaudio/KugelAudio/commit/d613b0fa1314c9e9e1f2af924652d94014626ddc))
|
|
13
|
+
|
|
14
|
+
### Reverts
|
|
15
|
+
|
|
16
|
+
* undo accidental merge of PR [#723](https://github.com/Kugelaudio/KugelAudio/issues/723) ([e8eff2e](https://github.com/Kugelaudio/KugelAudio/commit/e8eff2e86c76b893262782ff6ae763ed405396ce))
|
|
17
|
+
|
|
1
18
|
## [kugelaudio-v0.4.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.3.0...js-sdk-v0.4.0) (2026-05-14)
|
|
2
19
|
|
|
3
20
|
### Features
|
package/README.md
CHANGED
|
@@ -274,6 +274,39 @@ onChunk: (chunk) => {
|
|
|
274
274
|
}
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
+
## LLM Integration: Streaming Text Input
|
|
278
|
+
|
|
279
|
+
For real-time TTS when streaming text from an LLM (GPT-4, Claude, etc.),
|
|
280
|
+
use a `StreamingSession`. Forward LLM tokens directly to `session.send()`
|
|
281
|
+
**without** `flush=true` — the server accumulates them and starts
|
|
282
|
+
generation at natural sentence boundaries. `session.close()` triggers a
|
|
283
|
+
single final flush at the end of the assistant turn.
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
const session = client.tts.streamingSession(
|
|
287
|
+
{ voiceId: 123, modelId: 'kugel-1-turbo', language: 'en' },
|
|
288
|
+
{ onChunk: (chunk) => playAudio(chunk.audio) },
|
|
289
|
+
);
|
|
290
|
+
await session.connect();
|
|
291
|
+
|
|
292
|
+
// Forward every LLM token directly. No flush per token —
|
|
293
|
+
// the server's text buffer chunks at sentence boundaries.
|
|
294
|
+
for await (const token of llmTokenStream) {
|
|
295
|
+
session.send(token);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Triggers the server-side final flush of any trailing text,
|
|
299
|
+
// streams the resulting audio through onChunk, then closes the WS.
|
|
300
|
+
await session.close();
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
> ⚠️ **Do not call `session.send(text, true)` (`flush=true`) between
|
|
304
|
+
> sentences or words.** Each explicit flush is a separate TTS request
|
|
305
|
+
> that pays the full model time-to-first-audio (TTFA) again and produces
|
|
306
|
+
> an audible gap. See [Streaming best practices](https://docs.kugelaudio.com/streaming-best-practices)
|
|
307
|
+
> for the full rationale, chunk-size ordering, and ElevenLabs migration
|
|
308
|
+
> notes.
|
|
309
|
+
|
|
277
310
|
## Text Normalization
|
|
278
311
|
|
|
279
312
|
Text normalization converts numbers, dates, times, and other non-verbal text into spoken words. For example:
|
|
@@ -331,6 +364,7 @@ import {
|
|
|
331
364
|
RateLimitError,
|
|
332
365
|
InsufficientCreditsError,
|
|
333
366
|
ValidationError,
|
|
367
|
+
NotFoundError,
|
|
334
368
|
ConnectionError,
|
|
335
369
|
} from 'kugelaudio';
|
|
336
370
|
|
|
@@ -345,6 +379,8 @@ try {
|
|
|
345
379
|
console.error('Not enough credits, please top up');
|
|
346
380
|
} else if (error instanceof ValidationError) {
|
|
347
381
|
console.error(`Invalid request: ${error.message}`);
|
|
382
|
+
} else if (error instanceof NotFoundError) {
|
|
383
|
+
console.error(`Resource not found (e.g. unknown voiceId): ${error.message}`);
|
|
348
384
|
} else if (error instanceof ConnectionError) {
|
|
349
385
|
console.error('Failed to connect to server');
|
|
350
386
|
} else if (error instanceof KugelAudioError) {
|
package/dist/index.d.mts
CHANGED
|
@@ -54,6 +54,84 @@ interface VoiceListResponse {
|
|
|
54
54
|
* Voice quality levels.
|
|
55
55
|
*/
|
|
56
56
|
type VoiceQuality = 'low' | 'mid' | 'high';
|
|
57
|
+
/**
|
|
58
|
+
* A per-project pronunciation dictionary.
|
|
59
|
+
*/
|
|
60
|
+
interface Dictionary {
|
|
61
|
+
id: number;
|
|
62
|
+
projectId: number;
|
|
63
|
+
name: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
language?: string;
|
|
66
|
+
isActive: boolean;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A single word → replacement / IPA mapping within a dictionary.
|
|
72
|
+
*/
|
|
73
|
+
interface DictionaryEntry {
|
|
74
|
+
id: number;
|
|
75
|
+
dictionaryId: number;
|
|
76
|
+
word: string;
|
|
77
|
+
replacement: string;
|
|
78
|
+
ipa?: string;
|
|
79
|
+
caseSensitive: boolean;
|
|
80
|
+
createdAt: string;
|
|
81
|
+
updatedAt: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Paginated response from listing entries.
|
|
85
|
+
*/
|
|
86
|
+
interface DictionaryEntryListResponse {
|
|
87
|
+
entries: DictionaryEntry[];
|
|
88
|
+
total: number;
|
|
89
|
+
limit: number;
|
|
90
|
+
offset: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Counts returned by `entries.replaceAll`.
|
|
94
|
+
*/
|
|
95
|
+
interface BulkReplaceResult {
|
|
96
|
+
upserted: number;
|
|
97
|
+
deleted: number;
|
|
98
|
+
total: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Options for creating a dictionary.
|
|
102
|
+
*/
|
|
103
|
+
interface CreateDictionaryOptions {
|
|
104
|
+
name: string;
|
|
105
|
+
description?: string;
|
|
106
|
+
language?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Options for updating a dictionary. Only provided fields are changed.
|
|
110
|
+
*/
|
|
111
|
+
interface UpdateDictionaryOptions {
|
|
112
|
+
name?: string;
|
|
113
|
+
description?: string;
|
|
114
|
+
language?: string;
|
|
115
|
+
isActive?: boolean;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Payload for creating or replacing a single entry.
|
|
119
|
+
*/
|
|
120
|
+
interface DictionaryEntryInput {
|
|
121
|
+
word: string;
|
|
122
|
+
replacement: string;
|
|
123
|
+
ipa?: string;
|
|
124
|
+
caseSensitive?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Options for updating an entry.
|
|
128
|
+
*/
|
|
129
|
+
interface UpdateDictionaryEntryOptions {
|
|
130
|
+
word?: string;
|
|
131
|
+
replacement?: string;
|
|
132
|
+
ipa?: string;
|
|
133
|
+
caseSensitive?: boolean;
|
|
134
|
+
}
|
|
57
135
|
/**
|
|
58
136
|
* Extended voice information returned by voice management endpoints.
|
|
59
137
|
*/
|
|
@@ -305,6 +383,13 @@ interface StreamingSessionCallbacks {
|
|
|
305
383
|
onGenerationStarted?: (chunkId: number, text: string) => void;
|
|
306
384
|
/** Called when word-level timestamps arrive (requires `wordTimestamps: true`). */
|
|
307
385
|
onWordTimestamps?: (timestamps: WordTimestamp[]) => void;
|
|
386
|
+
/**
|
|
387
|
+
* Called when the server acknowledges a barge-in
|
|
388
|
+
* ({@link StreamingSession.cancelCurrent}). After this fires, no further
|
|
389
|
+
* audio chunks from the cancelled turn will arrive and the session is
|
|
390
|
+
* ready for the next `send()`.
|
|
391
|
+
*/
|
|
392
|
+
onInterrupted?: () => void;
|
|
308
393
|
/** Called on any error. */
|
|
309
394
|
onError?: (error: Error) => void;
|
|
310
395
|
}
|
|
@@ -482,6 +567,92 @@ interface MultiContextCallbacks {
|
|
|
482
567
|
onError?: (error: Error, contextId?: string) => void;
|
|
483
568
|
}
|
|
484
569
|
|
|
570
|
+
/**
|
|
571
|
+
* Resources for managing per-project custom word dictionaries.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* const dict = await client.dictionaries.create({ name: 'Brand names' });
|
|
576
|
+
* await client.dictionaries.entries.add(dict.id, {
|
|
577
|
+
* word: 'Postgres',
|
|
578
|
+
* replacement: 'post-gres',
|
|
579
|
+
* });
|
|
580
|
+
*
|
|
581
|
+
* // Sync from an external source — atomic, idempotent
|
|
582
|
+
* await client.dictionaries.entries.replaceAll(dict.id, [
|
|
583
|
+
* { word: 'Postgres', replacement: 'post-gres' },
|
|
584
|
+
* { word: 'Kubernetes', replacement: 'koo-ber-net-eez' },
|
|
585
|
+
* ]);
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Resource for entries within a single dictionary.
|
|
591
|
+
* Access via ``client.dictionaries.entries`` and pass ``dictionaryId``
|
|
592
|
+
* to each call.
|
|
593
|
+
*/
|
|
594
|
+
declare class DictionaryEntriesResource {
|
|
595
|
+
private client;
|
|
596
|
+
constructor(client: KugelAudio);
|
|
597
|
+
/** List entries with optional search + pagination. */
|
|
598
|
+
list(dictionaryId: number, options?: {
|
|
599
|
+
search?: string;
|
|
600
|
+
limit?: number;
|
|
601
|
+
offset?: number;
|
|
602
|
+
projectId?: number;
|
|
603
|
+
}): Promise<DictionaryEntryListResponse>;
|
|
604
|
+
/** Add a single entry to a dictionary. */
|
|
605
|
+
add(dictionaryId: number, entry: DictionaryEntryInput, options?: {
|
|
606
|
+
projectId?: number;
|
|
607
|
+
}): Promise<DictionaryEntry>;
|
|
608
|
+
/** Update an existing entry. */
|
|
609
|
+
update(dictionaryId: number, entryId: number, updates: UpdateDictionaryEntryOptions, options?: {
|
|
610
|
+
projectId?: number;
|
|
611
|
+
}): Promise<DictionaryEntry>;
|
|
612
|
+
/** Delete a single entry. */
|
|
613
|
+
delete(dictionaryId: number, entryId: number, options?: {
|
|
614
|
+
projectId?: number;
|
|
615
|
+
}): Promise<void>;
|
|
616
|
+
/**
|
|
617
|
+
* Replace every entry in the dictionary atomically.
|
|
618
|
+
*
|
|
619
|
+
* Each item must have ``word`` and ``replacement``; existing entries
|
|
620
|
+
* whose ``word`` is not in the supplied list are deleted. Idempotent.
|
|
621
|
+
*/
|
|
622
|
+
replaceAll(dictionaryId: number, entries: DictionaryEntryInput[], options?: {
|
|
623
|
+
projectId?: number;
|
|
624
|
+
}): Promise<BulkReplaceResult>;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Resource for managing per-project custom dictionaries.
|
|
628
|
+
*/
|
|
629
|
+
declare class DictionariesResource {
|
|
630
|
+
private client;
|
|
631
|
+
/** Per-entry operations within a dictionary. */
|
|
632
|
+
readonly entries: DictionaryEntriesResource;
|
|
633
|
+
constructor(client: KugelAudio);
|
|
634
|
+
/** List every dictionary in the caller's project. */
|
|
635
|
+
list(options?: {
|
|
636
|
+
projectId?: number;
|
|
637
|
+
}): Promise<Dictionary[]>;
|
|
638
|
+
/** Create a new dictionary scoped to the caller's project. */
|
|
639
|
+
create(body: CreateDictionaryOptions, options?: {
|
|
640
|
+
projectId?: number;
|
|
641
|
+
}): Promise<Dictionary>;
|
|
642
|
+
/** Fetch a single dictionary. */
|
|
643
|
+
get(dictionaryId: number, options?: {
|
|
644
|
+
projectId?: number;
|
|
645
|
+
}): Promise<Dictionary>;
|
|
646
|
+
/** Update name / description / language / isActive. */
|
|
647
|
+
update(dictionaryId: number, updates: UpdateDictionaryOptions, options?: {
|
|
648
|
+
projectId?: number;
|
|
649
|
+
}): Promise<Dictionary>;
|
|
650
|
+
/** Delete a dictionary (cascades to its entries). */
|
|
651
|
+
delete(dictionaryId: number, options?: {
|
|
652
|
+
projectId?: number;
|
|
653
|
+
}): Promise<void>;
|
|
654
|
+
}
|
|
655
|
+
|
|
485
656
|
/**
|
|
486
657
|
* Models resource for listing TTS models.
|
|
487
658
|
*/
|
|
@@ -774,8 +945,14 @@ declare class MultiContextSession {
|
|
|
774
945
|
flush(contextId: string): void;
|
|
775
946
|
/**
|
|
776
947
|
* Close a specific context.
|
|
948
|
+
*
|
|
949
|
+
* @param contextId - The context to close.
|
|
950
|
+
* @param immediate - When `true`, **barge-in**: the server cancels the
|
|
951
|
+
* context's in-flight generation immediately and discards any buffered or
|
|
952
|
+
* queued text instead of draining it. Use this when the end user speaks
|
|
953
|
+
* over the agent. When `false` (default), queued sentences finish first.
|
|
777
954
|
*/
|
|
778
|
-
closeContext(contextId: string): void;
|
|
955
|
+
closeContext(contextId: string, immediate?: boolean): void;
|
|
779
956
|
/**
|
|
780
957
|
* Send keep-alive to reset a context's inactivity timeout.
|
|
781
958
|
*/
|
|
@@ -852,6 +1029,34 @@ declare class StreamingSession {
|
|
|
852
1029
|
* handle chunking via `chunkLengthSchedule` / `autoMode` instead.
|
|
853
1030
|
*/
|
|
854
1031
|
send(text: string, flush?: boolean): void;
|
|
1032
|
+
/**
|
|
1033
|
+
* Interrupt (barge-in) the current generation without closing the socket.
|
|
1034
|
+
*
|
|
1035
|
+
* Use this when the end user starts speaking over the agent: it tells the
|
|
1036
|
+
* server to **stop generating audio for the current turn immediately** and
|
|
1037
|
+
* drop any text that was buffered or queued but not yet spoken. Unlike
|
|
1038
|
+
* {@link endSession}, no remaining text is flushed — the turn is abandoned.
|
|
1039
|
+
*
|
|
1040
|
+
* The WebSocket stays open and a fresh session is ready, so you can call
|
|
1041
|
+
* {@link send} for the next user turn right away (config is re-sent
|
|
1042
|
+
* automatically on that first `send`).
|
|
1043
|
+
*
|
|
1044
|
+
* The returned promise resolves once the server acknowledges with an
|
|
1045
|
+
* `interrupted` frame (which also fires
|
|
1046
|
+
* {@link StreamingSessionCallbacks.onInterrupted}), or after a 5 s **quiet**
|
|
1047
|
+
* timeout — i.e. 5 s elapse without any server message arriving. The timer
|
|
1048
|
+
* resets on every incoming frame, so a few in-flight audio chunks still
|
|
1049
|
+
* draining at the moment of cancellation do not trip it prematurely.
|
|
1050
|
+
*
|
|
1051
|
+
* @example
|
|
1052
|
+
* ```typescript
|
|
1053
|
+
* // VAD detected the user speaking over the agent:
|
|
1054
|
+
* await session.cancelCurrent();
|
|
1055
|
+
* // Socket is still open — start the next turn immediately:
|
|
1056
|
+
* session.send(nextLlmToken);
|
|
1057
|
+
* ```
|
|
1058
|
+
*/
|
|
1059
|
+
cancelCurrent(): Promise<void>;
|
|
855
1060
|
/**
|
|
856
1061
|
* End the current session but keep the WebSocket connection open.
|
|
857
1062
|
*
|
|
@@ -929,6 +1134,8 @@ declare class KugelAudio {
|
|
|
929
1134
|
readonly models: ModelsResource;
|
|
930
1135
|
/** Voices resource */
|
|
931
1136
|
readonly voices: VoicesResource;
|
|
1137
|
+
/** Custom dictionaries resource */
|
|
1138
|
+
readonly dictionaries: DictionariesResource;
|
|
932
1139
|
/** TTS resource */
|
|
933
1140
|
readonly tts: TTSResource;
|
|
934
1141
|
constructor(options: KugelAudioOptions);
|
|
@@ -1005,7 +1212,7 @@ declare class KugelAudio {
|
|
|
1005
1212
|
*
|
|
1006
1213
|
* All SDK errors inherit from {@link KugelAudioError}. Specific subclasses
|
|
1007
1214
|
* map to the server's `error_code` field (see the server-side `ErrorCode`
|
|
1008
|
-
* enum at `
|
|
1215
|
+
* enum at `engine/src/serving/deployments/errors.py`) so callers can
|
|
1009
1216
|
* `instanceof AuthenticationError` without matching on message text.
|
|
1010
1217
|
*/
|
|
1011
1218
|
declare const ErrorCodes: {
|
|
@@ -1073,6 +1280,17 @@ declare class ValidationError extends KugelAudioError {
|
|
|
1073
1280
|
declare class ConnectionError extends KugelAudioError {
|
|
1074
1281
|
constructor(message: string, options?: KugelAudioErrorOptions);
|
|
1075
1282
|
}
|
|
1283
|
+
/**
|
|
1284
|
+
* A referenced resource doesn't exist or isn't visible to the caller.
|
|
1285
|
+
*
|
|
1286
|
+
* Surfaced when the server returns HTTP 404 with `error_code = NOT_FOUND` —
|
|
1287
|
+
* e.g. an unknown `voiceId`, a voice that belongs to another org, or a
|
|
1288
|
+
* deleted resource. Distinct from {@link ValidationError} (malformed
|
|
1289
|
+
* request) so callers can show "not found" UX without parsing messages.
|
|
1290
|
+
*/
|
|
1291
|
+
declare class NotFoundError extends KugelAudioError {
|
|
1292
|
+
constructor(message?: string, options?: KugelAudioErrorOptions);
|
|
1293
|
+
}
|
|
1076
1294
|
interface HttpResponseLike {
|
|
1077
1295
|
status: number;
|
|
1078
1296
|
headers: {
|
|
@@ -1133,4 +1351,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
|
|
|
1133
1351
|
*/
|
|
1134
1352
|
declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
|
|
1135
1353
|
|
|
1136
|
-
export { type AudioChunk, type AudioResponse, AuthenticationError, ConnectionError, type ContextVoiceSettings, type CreateVoiceOptions, type ErrorCode, ErrorCodes, type GenerateOptions, type GenerationStats, InsufficientCreditsError, KugelAudio, KugelAudioError, type KugelAudioErrorOptions, type KugelAudioOptions, type Model, type MultiContextAudioChunk, type MultiContextCallbacks, type MultiContextConfig, RateLimitError, type Region, type StreamCallbacks, type StreamConfig, type StreamingSessionCallbacks, 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 };
|
|
1354
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,84 @@ interface VoiceListResponse {
|
|
|
54
54
|
* Voice quality levels.
|
|
55
55
|
*/
|
|
56
56
|
type VoiceQuality = 'low' | 'mid' | 'high';
|
|
57
|
+
/**
|
|
58
|
+
* A per-project pronunciation dictionary.
|
|
59
|
+
*/
|
|
60
|
+
interface Dictionary {
|
|
61
|
+
id: number;
|
|
62
|
+
projectId: number;
|
|
63
|
+
name: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
language?: string;
|
|
66
|
+
isActive: boolean;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A single word → replacement / IPA mapping within a dictionary.
|
|
72
|
+
*/
|
|
73
|
+
interface DictionaryEntry {
|
|
74
|
+
id: number;
|
|
75
|
+
dictionaryId: number;
|
|
76
|
+
word: string;
|
|
77
|
+
replacement: string;
|
|
78
|
+
ipa?: string;
|
|
79
|
+
caseSensitive: boolean;
|
|
80
|
+
createdAt: string;
|
|
81
|
+
updatedAt: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Paginated response from listing entries.
|
|
85
|
+
*/
|
|
86
|
+
interface DictionaryEntryListResponse {
|
|
87
|
+
entries: DictionaryEntry[];
|
|
88
|
+
total: number;
|
|
89
|
+
limit: number;
|
|
90
|
+
offset: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Counts returned by `entries.replaceAll`.
|
|
94
|
+
*/
|
|
95
|
+
interface BulkReplaceResult {
|
|
96
|
+
upserted: number;
|
|
97
|
+
deleted: number;
|
|
98
|
+
total: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Options for creating a dictionary.
|
|
102
|
+
*/
|
|
103
|
+
interface CreateDictionaryOptions {
|
|
104
|
+
name: string;
|
|
105
|
+
description?: string;
|
|
106
|
+
language?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Options for updating a dictionary. Only provided fields are changed.
|
|
110
|
+
*/
|
|
111
|
+
interface UpdateDictionaryOptions {
|
|
112
|
+
name?: string;
|
|
113
|
+
description?: string;
|
|
114
|
+
language?: string;
|
|
115
|
+
isActive?: boolean;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Payload for creating or replacing a single entry.
|
|
119
|
+
*/
|
|
120
|
+
interface DictionaryEntryInput {
|
|
121
|
+
word: string;
|
|
122
|
+
replacement: string;
|
|
123
|
+
ipa?: string;
|
|
124
|
+
caseSensitive?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Options for updating an entry.
|
|
128
|
+
*/
|
|
129
|
+
interface UpdateDictionaryEntryOptions {
|
|
130
|
+
word?: string;
|
|
131
|
+
replacement?: string;
|
|
132
|
+
ipa?: string;
|
|
133
|
+
caseSensitive?: boolean;
|
|
134
|
+
}
|
|
57
135
|
/**
|
|
58
136
|
* Extended voice information returned by voice management endpoints.
|
|
59
137
|
*/
|
|
@@ -305,6 +383,13 @@ interface StreamingSessionCallbacks {
|
|
|
305
383
|
onGenerationStarted?: (chunkId: number, text: string) => void;
|
|
306
384
|
/** Called when word-level timestamps arrive (requires `wordTimestamps: true`). */
|
|
307
385
|
onWordTimestamps?: (timestamps: WordTimestamp[]) => void;
|
|
386
|
+
/**
|
|
387
|
+
* Called when the server acknowledges a barge-in
|
|
388
|
+
* ({@link StreamingSession.cancelCurrent}). After this fires, no further
|
|
389
|
+
* audio chunks from the cancelled turn will arrive and the session is
|
|
390
|
+
* ready for the next `send()`.
|
|
391
|
+
*/
|
|
392
|
+
onInterrupted?: () => void;
|
|
308
393
|
/** Called on any error. */
|
|
309
394
|
onError?: (error: Error) => void;
|
|
310
395
|
}
|
|
@@ -482,6 +567,92 @@ interface MultiContextCallbacks {
|
|
|
482
567
|
onError?: (error: Error, contextId?: string) => void;
|
|
483
568
|
}
|
|
484
569
|
|
|
570
|
+
/**
|
|
571
|
+
* Resources for managing per-project custom word dictionaries.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* const dict = await client.dictionaries.create({ name: 'Brand names' });
|
|
576
|
+
* await client.dictionaries.entries.add(dict.id, {
|
|
577
|
+
* word: 'Postgres',
|
|
578
|
+
* replacement: 'post-gres',
|
|
579
|
+
* });
|
|
580
|
+
*
|
|
581
|
+
* // Sync from an external source — atomic, idempotent
|
|
582
|
+
* await client.dictionaries.entries.replaceAll(dict.id, [
|
|
583
|
+
* { word: 'Postgres', replacement: 'post-gres' },
|
|
584
|
+
* { word: 'Kubernetes', replacement: 'koo-ber-net-eez' },
|
|
585
|
+
* ]);
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Resource for entries within a single dictionary.
|
|
591
|
+
* Access via ``client.dictionaries.entries`` and pass ``dictionaryId``
|
|
592
|
+
* to each call.
|
|
593
|
+
*/
|
|
594
|
+
declare class DictionaryEntriesResource {
|
|
595
|
+
private client;
|
|
596
|
+
constructor(client: KugelAudio);
|
|
597
|
+
/** List entries with optional search + pagination. */
|
|
598
|
+
list(dictionaryId: number, options?: {
|
|
599
|
+
search?: string;
|
|
600
|
+
limit?: number;
|
|
601
|
+
offset?: number;
|
|
602
|
+
projectId?: number;
|
|
603
|
+
}): Promise<DictionaryEntryListResponse>;
|
|
604
|
+
/** Add a single entry to a dictionary. */
|
|
605
|
+
add(dictionaryId: number, entry: DictionaryEntryInput, options?: {
|
|
606
|
+
projectId?: number;
|
|
607
|
+
}): Promise<DictionaryEntry>;
|
|
608
|
+
/** Update an existing entry. */
|
|
609
|
+
update(dictionaryId: number, entryId: number, updates: UpdateDictionaryEntryOptions, options?: {
|
|
610
|
+
projectId?: number;
|
|
611
|
+
}): Promise<DictionaryEntry>;
|
|
612
|
+
/** Delete a single entry. */
|
|
613
|
+
delete(dictionaryId: number, entryId: number, options?: {
|
|
614
|
+
projectId?: number;
|
|
615
|
+
}): Promise<void>;
|
|
616
|
+
/**
|
|
617
|
+
* Replace every entry in the dictionary atomically.
|
|
618
|
+
*
|
|
619
|
+
* Each item must have ``word`` and ``replacement``; existing entries
|
|
620
|
+
* whose ``word`` is not in the supplied list are deleted. Idempotent.
|
|
621
|
+
*/
|
|
622
|
+
replaceAll(dictionaryId: number, entries: DictionaryEntryInput[], options?: {
|
|
623
|
+
projectId?: number;
|
|
624
|
+
}): Promise<BulkReplaceResult>;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Resource for managing per-project custom dictionaries.
|
|
628
|
+
*/
|
|
629
|
+
declare class DictionariesResource {
|
|
630
|
+
private client;
|
|
631
|
+
/** Per-entry operations within a dictionary. */
|
|
632
|
+
readonly entries: DictionaryEntriesResource;
|
|
633
|
+
constructor(client: KugelAudio);
|
|
634
|
+
/** List every dictionary in the caller's project. */
|
|
635
|
+
list(options?: {
|
|
636
|
+
projectId?: number;
|
|
637
|
+
}): Promise<Dictionary[]>;
|
|
638
|
+
/** Create a new dictionary scoped to the caller's project. */
|
|
639
|
+
create(body: CreateDictionaryOptions, options?: {
|
|
640
|
+
projectId?: number;
|
|
641
|
+
}): Promise<Dictionary>;
|
|
642
|
+
/** Fetch a single dictionary. */
|
|
643
|
+
get(dictionaryId: number, options?: {
|
|
644
|
+
projectId?: number;
|
|
645
|
+
}): Promise<Dictionary>;
|
|
646
|
+
/** Update name / description / language / isActive. */
|
|
647
|
+
update(dictionaryId: number, updates: UpdateDictionaryOptions, options?: {
|
|
648
|
+
projectId?: number;
|
|
649
|
+
}): Promise<Dictionary>;
|
|
650
|
+
/** Delete a dictionary (cascades to its entries). */
|
|
651
|
+
delete(dictionaryId: number, options?: {
|
|
652
|
+
projectId?: number;
|
|
653
|
+
}): Promise<void>;
|
|
654
|
+
}
|
|
655
|
+
|
|
485
656
|
/**
|
|
486
657
|
* Models resource for listing TTS models.
|
|
487
658
|
*/
|
|
@@ -774,8 +945,14 @@ declare class MultiContextSession {
|
|
|
774
945
|
flush(contextId: string): void;
|
|
775
946
|
/**
|
|
776
947
|
* Close a specific context.
|
|
948
|
+
*
|
|
949
|
+
* @param contextId - The context to close.
|
|
950
|
+
* @param immediate - When `true`, **barge-in**: the server cancels the
|
|
951
|
+
* context's in-flight generation immediately and discards any buffered or
|
|
952
|
+
* queued text instead of draining it. Use this when the end user speaks
|
|
953
|
+
* over the agent. When `false` (default), queued sentences finish first.
|
|
777
954
|
*/
|
|
778
|
-
closeContext(contextId: string): void;
|
|
955
|
+
closeContext(contextId: string, immediate?: boolean): void;
|
|
779
956
|
/**
|
|
780
957
|
* Send keep-alive to reset a context's inactivity timeout.
|
|
781
958
|
*/
|
|
@@ -852,6 +1029,34 @@ declare class StreamingSession {
|
|
|
852
1029
|
* handle chunking via `chunkLengthSchedule` / `autoMode` instead.
|
|
853
1030
|
*/
|
|
854
1031
|
send(text: string, flush?: boolean): void;
|
|
1032
|
+
/**
|
|
1033
|
+
* Interrupt (barge-in) the current generation without closing the socket.
|
|
1034
|
+
*
|
|
1035
|
+
* Use this when the end user starts speaking over the agent: it tells the
|
|
1036
|
+
* server to **stop generating audio for the current turn immediately** and
|
|
1037
|
+
* drop any text that was buffered or queued but not yet spoken. Unlike
|
|
1038
|
+
* {@link endSession}, no remaining text is flushed — the turn is abandoned.
|
|
1039
|
+
*
|
|
1040
|
+
* The WebSocket stays open and a fresh session is ready, so you can call
|
|
1041
|
+
* {@link send} for the next user turn right away (config is re-sent
|
|
1042
|
+
* automatically on that first `send`).
|
|
1043
|
+
*
|
|
1044
|
+
* The returned promise resolves once the server acknowledges with an
|
|
1045
|
+
* `interrupted` frame (which also fires
|
|
1046
|
+
* {@link StreamingSessionCallbacks.onInterrupted}), or after a 5 s **quiet**
|
|
1047
|
+
* timeout — i.e. 5 s elapse without any server message arriving. The timer
|
|
1048
|
+
* resets on every incoming frame, so a few in-flight audio chunks still
|
|
1049
|
+
* draining at the moment of cancellation do not trip it prematurely.
|
|
1050
|
+
*
|
|
1051
|
+
* @example
|
|
1052
|
+
* ```typescript
|
|
1053
|
+
* // VAD detected the user speaking over the agent:
|
|
1054
|
+
* await session.cancelCurrent();
|
|
1055
|
+
* // Socket is still open — start the next turn immediately:
|
|
1056
|
+
* session.send(nextLlmToken);
|
|
1057
|
+
* ```
|
|
1058
|
+
*/
|
|
1059
|
+
cancelCurrent(): Promise<void>;
|
|
855
1060
|
/**
|
|
856
1061
|
* End the current session but keep the WebSocket connection open.
|
|
857
1062
|
*
|
|
@@ -929,6 +1134,8 @@ declare class KugelAudio {
|
|
|
929
1134
|
readonly models: ModelsResource;
|
|
930
1135
|
/** Voices resource */
|
|
931
1136
|
readonly voices: VoicesResource;
|
|
1137
|
+
/** Custom dictionaries resource */
|
|
1138
|
+
readonly dictionaries: DictionariesResource;
|
|
932
1139
|
/** TTS resource */
|
|
933
1140
|
readonly tts: TTSResource;
|
|
934
1141
|
constructor(options: KugelAudioOptions);
|
|
@@ -1005,7 +1212,7 @@ declare class KugelAudio {
|
|
|
1005
1212
|
*
|
|
1006
1213
|
* All SDK errors inherit from {@link KugelAudioError}. Specific subclasses
|
|
1007
1214
|
* map to the server's `error_code` field (see the server-side `ErrorCode`
|
|
1008
|
-
* enum at `
|
|
1215
|
+
* enum at `engine/src/serving/deployments/errors.py`) so callers can
|
|
1009
1216
|
* `instanceof AuthenticationError` without matching on message text.
|
|
1010
1217
|
*/
|
|
1011
1218
|
declare const ErrorCodes: {
|
|
@@ -1073,6 +1280,17 @@ declare class ValidationError extends KugelAudioError {
|
|
|
1073
1280
|
declare class ConnectionError extends KugelAudioError {
|
|
1074
1281
|
constructor(message: string, options?: KugelAudioErrorOptions);
|
|
1075
1282
|
}
|
|
1283
|
+
/**
|
|
1284
|
+
* A referenced resource doesn't exist or isn't visible to the caller.
|
|
1285
|
+
*
|
|
1286
|
+
* Surfaced when the server returns HTTP 404 with `error_code = NOT_FOUND` —
|
|
1287
|
+
* e.g. an unknown `voiceId`, a voice that belongs to another org, or a
|
|
1288
|
+
* deleted resource. Distinct from {@link ValidationError} (malformed
|
|
1289
|
+
* request) so callers can show "not found" UX without parsing messages.
|
|
1290
|
+
*/
|
|
1291
|
+
declare class NotFoundError extends KugelAudioError {
|
|
1292
|
+
constructor(message?: string, options?: KugelAudioErrorOptions);
|
|
1293
|
+
}
|
|
1076
1294
|
interface HttpResponseLike {
|
|
1077
1295
|
status: number;
|
|
1078
1296
|
headers: {
|
|
@@ -1133,4 +1351,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
|
|
|
1133
1351
|
*/
|
|
1134
1352
|
declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
|
|
1135
1353
|
|
|
1136
|
-
export { type AudioChunk, type AudioResponse, AuthenticationError, ConnectionError, type ContextVoiceSettings, type CreateVoiceOptions, type ErrorCode, ErrorCodes, type GenerateOptions, type GenerationStats, InsufficientCreditsError, KugelAudio, KugelAudioError, type KugelAudioErrorOptions, type KugelAudioOptions, type Model, type MultiContextAudioChunk, type MultiContextCallbacks, type MultiContextConfig, RateLimitError, type Region, type StreamCallbacks, type StreamConfig, type StreamingSessionCallbacks, 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 };
|
|
1354
|
+
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 };
|