kugelaudio 0.3.0 → 0.5.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 +36 -0
- package/README.md +49 -16
- package/dist/index.d.mts +185 -8
- package/dist/index.d.ts +185 -8
- package/dist/index.js +212 -9
- package/dist/index.mjs +209 -9
- package/package.json +2 -2
- package/src/client.test.ts +10 -10
- package/src/client.ts +14 -10
- 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 +94 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [kugelaudio-v0.5.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.4.0...js-sdk-v0.5.0) (2026-05-21)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **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))
|
|
6
|
+
* **sdk:** add NotFoundError for unknown resources (KUG-423) ([#872](https://github.com/Kugelaudio/KugelAudio/issues/872)) ([d613b0f](https://github.com/Kugelaudio/KugelAudio/commit/d613b0fa1314c9e9e1f2af924652d94014626ddc))
|
|
7
|
+
|
|
8
|
+
### Reverts
|
|
9
|
+
|
|
10
|
+
* undo accidental merge of PR [#723](https://github.com/Kugelaudio/KugelAudio/issues/723) ([e8eff2e](https://github.com/Kugelaudio/KugelAudio/commit/e8eff2e86c76b893262782ff6ae763ed405396ce))
|
|
11
|
+
|
|
12
|
+
## [kugelaudio-v0.4.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.3.0...js-sdk-v0.4.0) (2026-05-14)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **web:** bump kugelaudio SDK to ^0.3.0 to enable per-project dictionary ([#640](https://github.com/Kugelaudio/KugelAudio/issues/640)) ([f503372](https://github.com/Kugelaudio/KugelAudio/commit/f5033728b2febb00cea6b021da5b5309c2c9097f))
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **python-sdk,js-sdk,java-sdk:** update regional endpoints ([#660](https://github.com/Kugelaudio/KugelAudio/issues/660)) ([b9a32c0](https://github.com/Kugelaudio/KugelAudio/commit/b9a32c09813c3e9de34a9d0a84ed0e024e1fe158))
|
|
21
|
+
|
|
1
22
|
# Changelog
|
|
2
23
|
|
|
3
24
|
All notable changes to the KugelAudio JavaScript/TypeScript SDK will be documented in this file.
|
|
@@ -5,6 +26,21 @@ All notable changes to the KugelAudio JavaScript/TypeScript SDK will be document
|
|
|
5
26
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
27
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
28
|
|
|
29
|
+
## [0.3.0](https://github.com/Kugelaudio/KugelAudio/compare/js-sdk-v0.2.3...js-sdk-v0.3.0) (2026-05-10)
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
* **temperature, projectId, speed** on `tts.stream` / `tts.generate` / multi-context. Required for per-project custom dictionary replacement on the website. ([#273](https://github.com/Kugelaudio/KugelAudio/pull/273))
|
|
34
|
+
* **error classification:** unify across SDKs with actionable messages ([#315](https://github.com/Kugelaudio/KugelAudio/pull/315))
|
|
35
|
+
* **multi-region routing** for all SDKs ([#227](https://github.com/Kugelaudio/KugelAudio/pull/227))
|
|
36
|
+
|
|
37
|
+
### Bug Fixes
|
|
38
|
+
|
|
39
|
+
* **streaming session close:** per-message-quiet timeout in `StreamingSession.close()` ([#528](https://github.com/Kugelaudio/KugelAudio/pull/528))
|
|
40
|
+
* **multi-context:** remove redundant `is_final` signal from protocol ([#279](https://github.com/Kugelaudio/KugelAudio/pull/279))
|
|
41
|
+
* **websocket:** keep alive across streaming sessions ([#253](https://github.com/Kugelaudio/KugelAudio/pull/253))
|
|
42
|
+
* **release pipeline:** fix stale repo URLs blocking semantic-release ([#637](https://github.com/Kugelaudio/KugelAudio/pull/637))
|
|
43
|
+
|
|
8
44
|
## [0.1.3] - 2024-12-25
|
|
9
45
|
|
|
10
46
|
### Fixed
|
package/README.md
CHANGED
|
@@ -59,30 +59,28 @@ const client = new KugelAudio({
|
|
|
59
59
|
|
|
60
60
|
### Region Selection
|
|
61
61
|
|
|
62
|
-
KugelAudio
|
|
62
|
+
By default, KugelAudio uses the canonical geo-routed API endpoint. You can
|
|
63
|
+
select the direct EU endpoint when you need to pin traffic to Europe.
|
|
63
64
|
|
|
64
|
-
| Region | Endpoint |
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
| `
|
|
68
|
-
| `global` | `global-api.kugelaudio.com` (geo-routed) |
|
|
65
|
+
| Region hint | Endpoint |
|
|
66
|
+
|-------------|----------|
|
|
67
|
+
| default | `api.kugelaudio.com` (geo-routed) |
|
|
68
|
+
| `eu` | `api.eu.kugelaudio.com` |
|
|
69
69
|
|
|
70
70
|
**Option 1 — API key prefix** (simplest, works with env vars):
|
|
71
71
|
|
|
72
72
|
```typescript
|
|
73
|
-
const client = new KugelAudio({ apiKey: '
|
|
74
|
-
const client = new KugelAudio({ apiKey: '
|
|
75
|
-
const client = new KugelAudio({ apiKey: 'eu-ka_your_api_key' }); // → EU (explicit)
|
|
76
|
-
const client = new KugelAudio({ apiKey: 'ka_your_api_key' }); // → EU (default)
|
|
73
|
+
const client = new KugelAudio({ apiKey: 'eu-ka_your_api_key' }); // → EU
|
|
74
|
+
const client = new KugelAudio({ apiKey: 'ka_your_api_key' }); // → canonical geo-routed API
|
|
77
75
|
```
|
|
78
76
|
|
|
79
77
|
**Option 2 — `region` parameter**:
|
|
80
78
|
|
|
81
79
|
```typescript
|
|
82
|
-
const client = new KugelAudio({ apiKey: 'ka_your_api_key', region: '
|
|
80
|
+
const client = new KugelAudio({ apiKey: 'ka_your_api_key', region: 'eu' });
|
|
83
81
|
```
|
|
84
82
|
|
|
85
|
-
The prefix is always stripped before authentication. Priority: `apiUrl` > `region` > key prefix > default
|
|
83
|
+
The prefix is always stripped before authentication. Priority: `apiUrl` > `region` > key prefix > default.
|
|
86
84
|
|
|
87
85
|
### Single URL Architecture
|
|
88
86
|
|
|
@@ -276,6 +274,39 @@ onChunk: (chunk) => {
|
|
|
276
274
|
}
|
|
277
275
|
```
|
|
278
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
|
+
|
|
279
310
|
## Text Normalization
|
|
280
311
|
|
|
281
312
|
Text normalization converts numbers, dates, times, and other non-verbal text into spoken words. For example:
|
|
@@ -333,6 +364,7 @@ import {
|
|
|
333
364
|
RateLimitError,
|
|
334
365
|
InsufficientCreditsError,
|
|
335
366
|
ValidationError,
|
|
367
|
+
NotFoundError,
|
|
336
368
|
ConnectionError,
|
|
337
369
|
} from 'kugelaudio';
|
|
338
370
|
|
|
@@ -347,6 +379,8 @@ try {
|
|
|
347
379
|
console.error('Not enough credits, please top up');
|
|
348
380
|
} else if (error instanceof ValidationError) {
|
|
349
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}`);
|
|
350
384
|
} else if (error instanceof ConnectionError) {
|
|
351
385
|
console.error('Failed to connect to server');
|
|
352
386
|
} else if (error instanceof KugelAudioError) {
|
|
@@ -361,9 +395,9 @@ try {
|
|
|
361
395
|
|
|
362
396
|
```typescript
|
|
363
397
|
interface KugelAudioOptions {
|
|
364
|
-
apiKey: string; // Required (can be prefixed with 'eu-'
|
|
365
|
-
region?: Region; // 'eu'
|
|
366
|
-
apiUrl?: string; // Default:
|
|
398
|
+
apiKey: string; // Required (can be prefixed with 'eu-' for EU)
|
|
399
|
+
region?: Region; // 'eu' selects the direct EU endpoint
|
|
400
|
+
apiUrl?: string; // Default: https://api.kugelaudio.com
|
|
367
401
|
ttsUrl?: string; // Default: same as apiUrl
|
|
368
402
|
timeout?: number; // Default: 60000 (ms)
|
|
369
403
|
}
|
|
@@ -571,4 +605,3 @@ The SDK works in modern browsers with WebSocket support. For Node.js, ensure you
|
|
|
571
605
|
## License
|
|
572
606
|
|
|
573
607
|
MIT
|
|
574
|
-
|
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
|
*/
|
|
@@ -379,17 +457,17 @@ interface StreamCallbacks {
|
|
|
379
457
|
onClose?: () => void;
|
|
380
458
|
}
|
|
381
459
|
/**
|
|
382
|
-
* Deployment region.
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
460
|
+
* Deployment region. Set `'eu'` to use the direct EU endpoint:
|
|
461
|
+
* `api.eu.kugelaudio.com`.
|
|
462
|
+
*
|
|
463
|
+
* If omitted, the SDK uses `api.kugelaudio.com`.
|
|
386
464
|
*/
|
|
387
465
|
type Region = 'eu' | 'us' | 'global';
|
|
388
466
|
/**
|
|
389
467
|
* KugelAudio client options.
|
|
390
468
|
*/
|
|
391
469
|
interface KugelAudioOptions {
|
|
392
|
-
/** Your KugelAudio API key or JWT token.
|
|
470
|
+
/** Your KugelAudio API key or JWT token. Prefix with `eu-` to select the direct EU endpoint (prefix is stripped before auth). */
|
|
393
471
|
apiKey: string;
|
|
394
472
|
/** Whether apiKey is a master key (for internal/server-side use). Master keys bypass billing. */
|
|
395
473
|
isMasterKey?: boolean;
|
|
@@ -397,7 +475,7 @@ interface KugelAudioOptions {
|
|
|
397
475
|
isToken?: boolean;
|
|
398
476
|
/** Organisation ID to bill usage against (required for token auth to enable usage recording). */
|
|
399
477
|
orgId?: number;
|
|
400
|
-
/** Deployment region. Takes precedence over API-key prefix but not over `apiUrl`. */
|
|
478
|
+
/** Deployment region. Set `eu` to select the direct EU endpoint. Takes precedence over API-key prefix but not over `apiUrl`. */
|
|
401
479
|
region?: Region;
|
|
402
480
|
/** API base URL (default: https://api.kugelaudio.com) */
|
|
403
481
|
apiUrl?: string;
|
|
@@ -482,6 +560,92 @@ interface MultiContextCallbacks {
|
|
|
482
560
|
onError?: (error: Error, contextId?: string) => void;
|
|
483
561
|
}
|
|
484
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Resources for managing per-project custom word dictionaries.
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* ```typescript
|
|
568
|
+
* const dict = await client.dictionaries.create({ name: 'Brand names' });
|
|
569
|
+
* await client.dictionaries.entries.add(dict.id, {
|
|
570
|
+
* word: 'Postgres',
|
|
571
|
+
* replacement: 'post-gres',
|
|
572
|
+
* });
|
|
573
|
+
*
|
|
574
|
+
* // Sync from an external source — atomic, idempotent
|
|
575
|
+
* await client.dictionaries.entries.replaceAll(dict.id, [
|
|
576
|
+
* { word: 'Postgres', replacement: 'post-gres' },
|
|
577
|
+
* { word: 'Kubernetes', replacement: 'koo-ber-net-eez' },
|
|
578
|
+
* ]);
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Resource for entries within a single dictionary.
|
|
584
|
+
* Access via ``client.dictionaries.entries`` and pass ``dictionaryId``
|
|
585
|
+
* to each call.
|
|
586
|
+
*/
|
|
587
|
+
declare class DictionaryEntriesResource {
|
|
588
|
+
private client;
|
|
589
|
+
constructor(client: KugelAudio);
|
|
590
|
+
/** List entries with optional search + pagination. */
|
|
591
|
+
list(dictionaryId: number, options?: {
|
|
592
|
+
search?: string;
|
|
593
|
+
limit?: number;
|
|
594
|
+
offset?: number;
|
|
595
|
+
projectId?: number;
|
|
596
|
+
}): Promise<DictionaryEntryListResponse>;
|
|
597
|
+
/** Add a single entry to a dictionary. */
|
|
598
|
+
add(dictionaryId: number, entry: DictionaryEntryInput, options?: {
|
|
599
|
+
projectId?: number;
|
|
600
|
+
}): Promise<DictionaryEntry>;
|
|
601
|
+
/** Update an existing entry. */
|
|
602
|
+
update(dictionaryId: number, entryId: number, updates: UpdateDictionaryEntryOptions, options?: {
|
|
603
|
+
projectId?: number;
|
|
604
|
+
}): Promise<DictionaryEntry>;
|
|
605
|
+
/** Delete a single entry. */
|
|
606
|
+
delete(dictionaryId: number, entryId: number, options?: {
|
|
607
|
+
projectId?: number;
|
|
608
|
+
}): Promise<void>;
|
|
609
|
+
/**
|
|
610
|
+
* Replace every entry in the dictionary atomically.
|
|
611
|
+
*
|
|
612
|
+
* Each item must have ``word`` and ``replacement``; existing entries
|
|
613
|
+
* whose ``word`` is not in the supplied list are deleted. Idempotent.
|
|
614
|
+
*/
|
|
615
|
+
replaceAll(dictionaryId: number, entries: DictionaryEntryInput[], options?: {
|
|
616
|
+
projectId?: number;
|
|
617
|
+
}): Promise<BulkReplaceResult>;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Resource for managing per-project custom dictionaries.
|
|
621
|
+
*/
|
|
622
|
+
declare class DictionariesResource {
|
|
623
|
+
private client;
|
|
624
|
+
/** Per-entry operations within a dictionary. */
|
|
625
|
+
readonly entries: DictionaryEntriesResource;
|
|
626
|
+
constructor(client: KugelAudio);
|
|
627
|
+
/** List every dictionary in the caller's project. */
|
|
628
|
+
list(options?: {
|
|
629
|
+
projectId?: number;
|
|
630
|
+
}): Promise<Dictionary[]>;
|
|
631
|
+
/** Create a new dictionary scoped to the caller's project. */
|
|
632
|
+
create(body: CreateDictionaryOptions, options?: {
|
|
633
|
+
projectId?: number;
|
|
634
|
+
}): Promise<Dictionary>;
|
|
635
|
+
/** Fetch a single dictionary. */
|
|
636
|
+
get(dictionaryId: number, options?: {
|
|
637
|
+
projectId?: number;
|
|
638
|
+
}): Promise<Dictionary>;
|
|
639
|
+
/** Update name / description / language / isActive. */
|
|
640
|
+
update(dictionaryId: number, updates: UpdateDictionaryOptions, options?: {
|
|
641
|
+
projectId?: number;
|
|
642
|
+
}): Promise<Dictionary>;
|
|
643
|
+
/** Delete a dictionary (cascades to its entries). */
|
|
644
|
+
delete(dictionaryId: number, options?: {
|
|
645
|
+
projectId?: number;
|
|
646
|
+
}): Promise<void>;
|
|
647
|
+
}
|
|
648
|
+
|
|
485
649
|
/**
|
|
486
650
|
* Models resource for listing TTS models.
|
|
487
651
|
*/
|
|
@@ -929,6 +1093,8 @@ declare class KugelAudio {
|
|
|
929
1093
|
readonly models: ModelsResource;
|
|
930
1094
|
/** Voices resource */
|
|
931
1095
|
readonly voices: VoicesResource;
|
|
1096
|
+
/** Custom dictionaries resource */
|
|
1097
|
+
readonly dictionaries: DictionariesResource;
|
|
932
1098
|
/** TTS resource */
|
|
933
1099
|
readonly tts: TTSResource;
|
|
934
1100
|
constructor(options: KugelAudioOptions);
|
|
@@ -1005,7 +1171,7 @@ declare class KugelAudio {
|
|
|
1005
1171
|
*
|
|
1006
1172
|
* All SDK errors inherit from {@link KugelAudioError}. Specific subclasses
|
|
1007
1173
|
* map to the server's `error_code` field (see the server-side `ErrorCode`
|
|
1008
|
-
* enum at `
|
|
1174
|
+
* enum at `engine/src/serving/deployments/errors.py`) so callers can
|
|
1009
1175
|
* `instanceof AuthenticationError` without matching on message text.
|
|
1010
1176
|
*/
|
|
1011
1177
|
declare const ErrorCodes: {
|
|
@@ -1073,6 +1239,17 @@ declare class ValidationError extends KugelAudioError {
|
|
|
1073
1239
|
declare class ConnectionError extends KugelAudioError {
|
|
1074
1240
|
constructor(message: string, options?: KugelAudioErrorOptions);
|
|
1075
1241
|
}
|
|
1242
|
+
/**
|
|
1243
|
+
* A referenced resource doesn't exist or isn't visible to the caller.
|
|
1244
|
+
*
|
|
1245
|
+
* Surfaced when the server returns HTTP 404 with `error_code = NOT_FOUND` —
|
|
1246
|
+
* e.g. an unknown `voiceId`, a voice that belongs to another org, or a
|
|
1247
|
+
* deleted resource. Distinct from {@link ValidationError} (malformed
|
|
1248
|
+
* request) so callers can show "not found" UX without parsing messages.
|
|
1249
|
+
*/
|
|
1250
|
+
declare class NotFoundError extends KugelAudioError {
|
|
1251
|
+
constructor(message?: string, options?: KugelAudioErrorOptions);
|
|
1252
|
+
}
|
|
1076
1253
|
interface HttpResponseLike {
|
|
1077
1254
|
status: number;
|
|
1078
1255
|
headers: {
|
|
@@ -1133,4 +1310,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
|
|
|
1133
1310
|
*/
|
|
1134
1311
|
declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
|
|
1135
1312
|
|
|
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 };
|
|
1313
|
+
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
|
*/
|
|
@@ -379,17 +457,17 @@ interface StreamCallbacks {
|
|
|
379
457
|
onClose?: () => void;
|
|
380
458
|
}
|
|
381
459
|
/**
|
|
382
|
-
* Deployment region.
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
460
|
+
* Deployment region. Set `'eu'` to use the direct EU endpoint:
|
|
461
|
+
* `api.eu.kugelaudio.com`.
|
|
462
|
+
*
|
|
463
|
+
* If omitted, the SDK uses `api.kugelaudio.com`.
|
|
386
464
|
*/
|
|
387
465
|
type Region = 'eu' | 'us' | 'global';
|
|
388
466
|
/**
|
|
389
467
|
* KugelAudio client options.
|
|
390
468
|
*/
|
|
391
469
|
interface KugelAudioOptions {
|
|
392
|
-
/** Your KugelAudio API key or JWT token.
|
|
470
|
+
/** Your KugelAudio API key or JWT token. Prefix with `eu-` to select the direct EU endpoint (prefix is stripped before auth). */
|
|
393
471
|
apiKey: string;
|
|
394
472
|
/** Whether apiKey is a master key (for internal/server-side use). Master keys bypass billing. */
|
|
395
473
|
isMasterKey?: boolean;
|
|
@@ -397,7 +475,7 @@ interface KugelAudioOptions {
|
|
|
397
475
|
isToken?: boolean;
|
|
398
476
|
/** Organisation ID to bill usage against (required for token auth to enable usage recording). */
|
|
399
477
|
orgId?: number;
|
|
400
|
-
/** Deployment region. Takes precedence over API-key prefix but not over `apiUrl`. */
|
|
478
|
+
/** Deployment region. Set `eu` to select the direct EU endpoint. Takes precedence over API-key prefix but not over `apiUrl`. */
|
|
401
479
|
region?: Region;
|
|
402
480
|
/** API base URL (default: https://api.kugelaudio.com) */
|
|
403
481
|
apiUrl?: string;
|
|
@@ -482,6 +560,92 @@ interface MultiContextCallbacks {
|
|
|
482
560
|
onError?: (error: Error, contextId?: string) => void;
|
|
483
561
|
}
|
|
484
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Resources for managing per-project custom word dictionaries.
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* ```typescript
|
|
568
|
+
* const dict = await client.dictionaries.create({ name: 'Brand names' });
|
|
569
|
+
* await client.dictionaries.entries.add(dict.id, {
|
|
570
|
+
* word: 'Postgres',
|
|
571
|
+
* replacement: 'post-gres',
|
|
572
|
+
* });
|
|
573
|
+
*
|
|
574
|
+
* // Sync from an external source — atomic, idempotent
|
|
575
|
+
* await client.dictionaries.entries.replaceAll(dict.id, [
|
|
576
|
+
* { word: 'Postgres', replacement: 'post-gres' },
|
|
577
|
+
* { word: 'Kubernetes', replacement: 'koo-ber-net-eez' },
|
|
578
|
+
* ]);
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Resource for entries within a single dictionary.
|
|
584
|
+
* Access via ``client.dictionaries.entries`` and pass ``dictionaryId``
|
|
585
|
+
* to each call.
|
|
586
|
+
*/
|
|
587
|
+
declare class DictionaryEntriesResource {
|
|
588
|
+
private client;
|
|
589
|
+
constructor(client: KugelAudio);
|
|
590
|
+
/** List entries with optional search + pagination. */
|
|
591
|
+
list(dictionaryId: number, options?: {
|
|
592
|
+
search?: string;
|
|
593
|
+
limit?: number;
|
|
594
|
+
offset?: number;
|
|
595
|
+
projectId?: number;
|
|
596
|
+
}): Promise<DictionaryEntryListResponse>;
|
|
597
|
+
/** Add a single entry to a dictionary. */
|
|
598
|
+
add(dictionaryId: number, entry: DictionaryEntryInput, options?: {
|
|
599
|
+
projectId?: number;
|
|
600
|
+
}): Promise<DictionaryEntry>;
|
|
601
|
+
/** Update an existing entry. */
|
|
602
|
+
update(dictionaryId: number, entryId: number, updates: UpdateDictionaryEntryOptions, options?: {
|
|
603
|
+
projectId?: number;
|
|
604
|
+
}): Promise<DictionaryEntry>;
|
|
605
|
+
/** Delete a single entry. */
|
|
606
|
+
delete(dictionaryId: number, entryId: number, options?: {
|
|
607
|
+
projectId?: number;
|
|
608
|
+
}): Promise<void>;
|
|
609
|
+
/**
|
|
610
|
+
* Replace every entry in the dictionary atomically.
|
|
611
|
+
*
|
|
612
|
+
* Each item must have ``word`` and ``replacement``; existing entries
|
|
613
|
+
* whose ``word`` is not in the supplied list are deleted. Idempotent.
|
|
614
|
+
*/
|
|
615
|
+
replaceAll(dictionaryId: number, entries: DictionaryEntryInput[], options?: {
|
|
616
|
+
projectId?: number;
|
|
617
|
+
}): Promise<BulkReplaceResult>;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Resource for managing per-project custom dictionaries.
|
|
621
|
+
*/
|
|
622
|
+
declare class DictionariesResource {
|
|
623
|
+
private client;
|
|
624
|
+
/** Per-entry operations within a dictionary. */
|
|
625
|
+
readonly entries: DictionaryEntriesResource;
|
|
626
|
+
constructor(client: KugelAudio);
|
|
627
|
+
/** List every dictionary in the caller's project. */
|
|
628
|
+
list(options?: {
|
|
629
|
+
projectId?: number;
|
|
630
|
+
}): Promise<Dictionary[]>;
|
|
631
|
+
/** Create a new dictionary scoped to the caller's project. */
|
|
632
|
+
create(body: CreateDictionaryOptions, options?: {
|
|
633
|
+
projectId?: number;
|
|
634
|
+
}): Promise<Dictionary>;
|
|
635
|
+
/** Fetch a single dictionary. */
|
|
636
|
+
get(dictionaryId: number, options?: {
|
|
637
|
+
projectId?: number;
|
|
638
|
+
}): Promise<Dictionary>;
|
|
639
|
+
/** Update name / description / language / isActive. */
|
|
640
|
+
update(dictionaryId: number, updates: UpdateDictionaryOptions, options?: {
|
|
641
|
+
projectId?: number;
|
|
642
|
+
}): Promise<Dictionary>;
|
|
643
|
+
/** Delete a dictionary (cascades to its entries). */
|
|
644
|
+
delete(dictionaryId: number, options?: {
|
|
645
|
+
projectId?: number;
|
|
646
|
+
}): Promise<void>;
|
|
647
|
+
}
|
|
648
|
+
|
|
485
649
|
/**
|
|
486
650
|
* Models resource for listing TTS models.
|
|
487
651
|
*/
|
|
@@ -929,6 +1093,8 @@ declare class KugelAudio {
|
|
|
929
1093
|
readonly models: ModelsResource;
|
|
930
1094
|
/** Voices resource */
|
|
931
1095
|
readonly voices: VoicesResource;
|
|
1096
|
+
/** Custom dictionaries resource */
|
|
1097
|
+
readonly dictionaries: DictionariesResource;
|
|
932
1098
|
/** TTS resource */
|
|
933
1099
|
readonly tts: TTSResource;
|
|
934
1100
|
constructor(options: KugelAudioOptions);
|
|
@@ -1005,7 +1171,7 @@ declare class KugelAudio {
|
|
|
1005
1171
|
*
|
|
1006
1172
|
* All SDK errors inherit from {@link KugelAudioError}. Specific subclasses
|
|
1007
1173
|
* map to the server's `error_code` field (see the server-side `ErrorCode`
|
|
1008
|
-
* enum at `
|
|
1174
|
+
* enum at `engine/src/serving/deployments/errors.py`) so callers can
|
|
1009
1175
|
* `instanceof AuthenticationError` without matching on message text.
|
|
1010
1176
|
*/
|
|
1011
1177
|
declare const ErrorCodes: {
|
|
@@ -1073,6 +1239,17 @@ declare class ValidationError extends KugelAudioError {
|
|
|
1073
1239
|
declare class ConnectionError extends KugelAudioError {
|
|
1074
1240
|
constructor(message: string, options?: KugelAudioErrorOptions);
|
|
1075
1241
|
}
|
|
1242
|
+
/**
|
|
1243
|
+
* A referenced resource doesn't exist or isn't visible to the caller.
|
|
1244
|
+
*
|
|
1245
|
+
* Surfaced when the server returns HTTP 404 with `error_code = NOT_FOUND` —
|
|
1246
|
+
* e.g. an unknown `voiceId`, a voice that belongs to another org, or a
|
|
1247
|
+
* deleted resource. Distinct from {@link ValidationError} (malformed
|
|
1248
|
+
* request) so callers can show "not found" UX without parsing messages.
|
|
1249
|
+
*/
|
|
1250
|
+
declare class NotFoundError extends KugelAudioError {
|
|
1251
|
+
constructor(message?: string, options?: KugelAudioErrorOptions);
|
|
1252
|
+
}
|
|
1076
1253
|
interface HttpResponseLike {
|
|
1077
1254
|
status: number;
|
|
1078
1255
|
headers: {
|
|
@@ -1133,4 +1310,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
|
|
|
1133
1310
|
*/
|
|
1134
1311
|
declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
|
|
1135
1312
|
|
|
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 };
|
|
1313
|
+
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 };
|