kugelaudio 0.8.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/CHANGELOG.md +8 -0
- package/README.md +30 -1
- package/dist/chunk-CB3B6T7F.mjs +391 -0
- package/dist/chunk-D57AKD2S.mjs +391 -0
- package/dist/index.d.mts +84 -11
- package/dist/index.d.ts +84 -11
- package/dist/index.js +193 -7
- package/dist/index.mjs +186 -334
- package/dist/livekit/index.d.mts +222 -0
- package/dist/livekit/index.d.ts +222 -0
- package/dist/livekit/index.js +994 -0
- package/dist/livekit/index.mjs +746 -0
- package/package.json +23 -3
- package/src/cfg-scale.test.ts +33 -0
- package/src/client.test.ts +110 -0
- package/src/client.ts +213 -5
- package/src/index.ts +2 -0
- package/src/livekit/index.ts +32 -0
- package/src/livekit/models.test.ts +30 -0
- package/src/livekit/models.ts +84 -0
- package/src/livekit/tts.functional.test.ts +348 -0
- package/src/livekit/tts.ts +833 -0
- package/src/livekit/wire.test.ts +112 -0
- package/src/livekit/wire.ts +126 -0
- package/src/types.ts +47 -7
- package/src/utils.ts +16 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
+
}) : x)(function(x) {
|
|
7
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
+
});
|
|
10
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
11
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
12
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
14
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
15
|
+
|
|
16
|
+
// src/errors.ts
|
|
17
|
+
var ErrorCodes = {
|
|
18
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
19
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
20
|
+
INSUFFICIENT_CREDITS: "INSUFFICIENT_CREDITS",
|
|
21
|
+
MODEL_UNAVAILABLE: "MODEL_UNAVAILABLE",
|
|
22
|
+
EMPTY_AUDIO: "EMPTY_AUDIO",
|
|
23
|
+
VALIDATION: "VALIDATION_ERROR",
|
|
24
|
+
INTERNAL: "INTERNAL_ERROR",
|
|
25
|
+
NOT_FOUND: "NOT_FOUND",
|
|
26
|
+
MISSING_VOICE_ID: "MISSING_VOICE_ID",
|
|
27
|
+
TOO_MANY_CONTEXTS: "TOO_MANY_CONTEXTS"
|
|
28
|
+
};
|
|
29
|
+
var WsCloseCodes = {
|
|
30
|
+
UNAUTHORIZED: 4001,
|
|
31
|
+
INSUFFICIENT_CREDITS: 4003,
|
|
32
|
+
RATE_LIMITED: 4029,
|
|
33
|
+
MODEL_UNAVAILABLE: 4500
|
|
34
|
+
};
|
|
35
|
+
var API_KEYS_URL = "https://app.kugelaudio.com/settings/api-keys";
|
|
36
|
+
var BILLING_URL = "https://app.kugelaudio.com/billing";
|
|
37
|
+
var KugelAudioError = class _KugelAudioError extends Error {
|
|
38
|
+
constructor(message, options = {}) {
|
|
39
|
+
super(options.requestId ? `${message} (request_id: ${options.requestId})` : message);
|
|
40
|
+
this.name = "KugelAudioError";
|
|
41
|
+
this.statusCode = options.statusCode;
|
|
42
|
+
this.errorCode = options.errorCode;
|
|
43
|
+
this.requestId = options.requestId;
|
|
44
|
+
this.retryAfter = options.retryAfter;
|
|
45
|
+
Object.setPrototypeOf(this, _KugelAudioError.prototype);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var AuthenticationError = class _AuthenticationError extends KugelAudioError {
|
|
49
|
+
constructor(message, options = {}) {
|
|
50
|
+
super(
|
|
51
|
+
message ?? `KugelAudio rejected the API key. Check it is current at ${API_KEYS_URL}.`,
|
|
52
|
+
{ statusCode: 401, errorCode: ErrorCodes.UNAUTHORIZED, ...options }
|
|
53
|
+
);
|
|
54
|
+
this.name = "AuthenticationError";
|
|
55
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var RateLimitError = class _RateLimitError extends KugelAudioError {
|
|
59
|
+
constructor(message, options = {}) {
|
|
60
|
+
const msg = message ?? (options.retryAfter ? `KugelAudio rate limit hit; retry after ${options.retryAfter}s.` : "KugelAudio rate limit hit; retry shortly.");
|
|
61
|
+
super(msg, { statusCode: 429, errorCode: ErrorCodes.RATE_LIMITED, ...options });
|
|
62
|
+
this.name = "RateLimitError";
|
|
63
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var InsufficientCreditsError = class _InsufficientCreditsError extends KugelAudioError {
|
|
67
|
+
constructor(message, options = {}) {
|
|
68
|
+
super(
|
|
69
|
+
message ?? `Your KugelAudio account is out of credits. Top up at ${BILLING_URL}.`,
|
|
70
|
+
{ statusCode: 402, errorCode: ErrorCodes.INSUFFICIENT_CREDITS, ...options }
|
|
71
|
+
);
|
|
72
|
+
this.name = "InsufficientCreditsError";
|
|
73
|
+
Object.setPrototypeOf(this, _InsufficientCreditsError.prototype);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var ValidationError = class _ValidationError extends KugelAudioError {
|
|
77
|
+
constructor(message, options = {}) {
|
|
78
|
+
super(message, { statusCode: 400, errorCode: ErrorCodes.VALIDATION, ...options });
|
|
79
|
+
this.name = "ValidationError";
|
|
80
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var ConnectionError = class _ConnectionError extends KugelAudioError {
|
|
84
|
+
constructor(message, options = {}) {
|
|
85
|
+
super(message, { statusCode: 503, ...options });
|
|
86
|
+
this.name = "ConnectionError";
|
|
87
|
+
Object.setPrototypeOf(this, _ConnectionError.prototype);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var NotFoundError = class _NotFoundError extends KugelAudioError {
|
|
91
|
+
constructor(message, options = {}) {
|
|
92
|
+
super(message ?? "Not found.", {
|
|
93
|
+
statusCode: 404,
|
|
94
|
+
errorCode: ErrorCodes.NOT_FOUND,
|
|
95
|
+
...options
|
|
96
|
+
});
|
|
97
|
+
this.name = "NotFoundError";
|
|
98
|
+
Object.setPrototypeOf(this, _NotFoundError.prototype);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
function build(status, errorCode, message, opts = {}) {
|
|
102
|
+
const common = { ...opts };
|
|
103
|
+
if (status !== void 0) common.statusCode = status;
|
|
104
|
+
if (errorCode !== void 0) common.errorCode = errorCode;
|
|
105
|
+
if (errorCode === ErrorCodes.UNAUTHORIZED || status === 401) {
|
|
106
|
+
return new AuthenticationError(message || void 0, common);
|
|
107
|
+
}
|
|
108
|
+
if (errorCode === ErrorCodes.INSUFFICIENT_CREDITS || status === 402) {
|
|
109
|
+
return new InsufficientCreditsError(message || void 0, common);
|
|
110
|
+
}
|
|
111
|
+
if (errorCode === ErrorCodes.RATE_LIMITED || errorCode === ErrorCodes.TOO_MANY_CONTEXTS || status === 429) {
|
|
112
|
+
return new RateLimitError(message || void 0, common);
|
|
113
|
+
}
|
|
114
|
+
if (errorCode === ErrorCodes.VALIDATION || errorCode === ErrorCodes.MISSING_VOICE_ID || status === 400) {
|
|
115
|
+
return new ValidationError(message || "Request validation failed.", common);
|
|
116
|
+
}
|
|
117
|
+
if (errorCode === ErrorCodes.MODEL_UNAVAILABLE || status === 503) {
|
|
118
|
+
const detail = message || "service temporarily unavailable";
|
|
119
|
+
return new ConnectionError(
|
|
120
|
+
`KugelAudio is temporarily unavailable: ${detail}. Retry shortly.`,
|
|
121
|
+
common
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (errorCode === ErrorCodes.NOT_FOUND || status === 404) {
|
|
125
|
+
return new NotFoundError(message || void 0, common);
|
|
126
|
+
}
|
|
127
|
+
return new KugelAudioError(message || `HTTP ${status}`, common);
|
|
128
|
+
}
|
|
129
|
+
function readHeader(headers, name) {
|
|
130
|
+
if (headers && typeof headers.get === "function") {
|
|
131
|
+
return headers.get(name) ?? void 0;
|
|
132
|
+
}
|
|
133
|
+
const rec = headers;
|
|
134
|
+
return rec[name] ?? rec[name.toLowerCase()] ?? void 0;
|
|
135
|
+
}
|
|
136
|
+
function classifyHttpError(status, bodyText, headers) {
|
|
137
|
+
let errorCode;
|
|
138
|
+
let message = "";
|
|
139
|
+
let retryAfter;
|
|
140
|
+
if (bodyText) {
|
|
141
|
+
try {
|
|
142
|
+
const body = JSON.parse(bodyText);
|
|
143
|
+
if (body && typeof body === "object") {
|
|
144
|
+
errorCode = typeof body.error_code === "string" ? body.error_code : void 0;
|
|
145
|
+
const msg = body.error ?? body.detail;
|
|
146
|
+
if (Array.isArray(msg)) {
|
|
147
|
+
message = msg.map((m) => String(m)).join("; ");
|
|
148
|
+
} else if (typeof msg === "string") {
|
|
149
|
+
message = msg;
|
|
150
|
+
}
|
|
151
|
+
if (typeof body.retry_after === "number") {
|
|
152
|
+
retryAfter = body.retry_after;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (retryAfter === void 0) {
|
|
159
|
+
const header = readHeader(headers, "Retry-After") ?? readHeader(headers, "retry-after");
|
|
160
|
+
if (header) {
|
|
161
|
+
const n = Number(header);
|
|
162
|
+
if (Number.isFinite(n)) retryAfter = n;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const requestId = readHeader(headers, "x-request-id") ?? readHeader(headers, "X-Request-Id");
|
|
166
|
+
if (!message) {
|
|
167
|
+
message = (bodyText || "").trim();
|
|
168
|
+
}
|
|
169
|
+
return build(status, errorCode, message, { requestId, retryAfter });
|
|
170
|
+
}
|
|
171
|
+
function classifyWsFrame(data) {
|
|
172
|
+
const errorCode = data.error_code;
|
|
173
|
+
const message = data.error ?? "Server reported an error.";
|
|
174
|
+
const status = typeof data.code === "number" ? data.code : void 0;
|
|
175
|
+
const retryAfter = typeof data.retry_after === "number" ? data.retry_after : void 0;
|
|
176
|
+
return build(status, errorCode, message, { retryAfter });
|
|
177
|
+
}
|
|
178
|
+
function classifyWsClose(code, reason) {
|
|
179
|
+
const reasonTxt = (reason ?? "").trim();
|
|
180
|
+
if (code === WsCloseCodes.UNAUTHORIZED) {
|
|
181
|
+
let msg = `KugelAudio rejected the API key. Check it is current at ${API_KEYS_URL}.`;
|
|
182
|
+
if (reasonTxt) msg = `${msg} (${reasonTxt})`;
|
|
183
|
+
return new AuthenticationError(msg);
|
|
184
|
+
}
|
|
185
|
+
if (code === WsCloseCodes.INSUFFICIENT_CREDITS) {
|
|
186
|
+
return new InsufficientCreditsError();
|
|
187
|
+
}
|
|
188
|
+
if (code === WsCloseCodes.RATE_LIMITED) {
|
|
189
|
+
return new RateLimitError();
|
|
190
|
+
}
|
|
191
|
+
if (code === WsCloseCodes.MODEL_UNAVAILABLE) {
|
|
192
|
+
const suffix = reasonTxt ? ` (${reasonTxt})` : "";
|
|
193
|
+
return new ConnectionError(
|
|
194
|
+
`KugelAudio model is temporarily unavailable. Retry shortly.${suffix}`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
const detail = reasonTxt || "no reason given";
|
|
198
|
+
const codeStr = code !== void 0 ? ` (code ${code})` : "";
|
|
199
|
+
return new ConnectionError(
|
|
200
|
+
`KugelAudio WebSocket closed by server: ${detail}${codeStr}.`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
function classifyWsHandshakeError(err) {
|
|
204
|
+
if (!err || typeof err !== "object") return null;
|
|
205
|
+
const e = err;
|
|
206
|
+
let status;
|
|
207
|
+
if (typeof e.statusCode === "number") {
|
|
208
|
+
status = e.statusCode;
|
|
209
|
+
}
|
|
210
|
+
if (status === void 0 && typeof e.message === "string") {
|
|
211
|
+
const m = e.message.match(/Unexpected server response:\s*(\d{3})/i);
|
|
212
|
+
if (m) status = Number(m[1]);
|
|
213
|
+
}
|
|
214
|
+
if (status === void 0) return null;
|
|
215
|
+
if (status === 403) {
|
|
216
|
+
return new AuthenticationError();
|
|
217
|
+
}
|
|
218
|
+
return build(status, void 0, typeof e.message === "string" ? e.message : "");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/utils.ts
|
|
222
|
+
var MIN_CFG_SCALE = 1.2;
|
|
223
|
+
var MAX_CFG_SCALE = 2.5;
|
|
224
|
+
function clampCfgScale(cfgScale) {
|
|
225
|
+
if (cfgScale === void 0) return void 0;
|
|
226
|
+
return Math.min(MAX_CFG_SCALE, Math.max(MIN_CFG_SCALE, cfgScale));
|
|
227
|
+
}
|
|
228
|
+
function base64ToArrayBuffer(base64) {
|
|
229
|
+
if (typeof atob === "function") {
|
|
230
|
+
const binary = atob(base64);
|
|
231
|
+
const bytes = new Uint8Array(binary.length);
|
|
232
|
+
for (let i = 0; i < binary.length; i++) {
|
|
233
|
+
bytes[i] = binary.charCodeAt(i);
|
|
234
|
+
}
|
|
235
|
+
return bytes.buffer;
|
|
236
|
+
} else {
|
|
237
|
+
const buffer = Buffer.from(base64, "base64");
|
|
238
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function decodePCM16(base64) {
|
|
242
|
+
const buffer = base64ToArrayBuffer(base64);
|
|
243
|
+
const int16 = new Int16Array(buffer);
|
|
244
|
+
const float32 = new Float32Array(int16.length);
|
|
245
|
+
for (let i = 0; i < int16.length; i++) {
|
|
246
|
+
float32[i] = int16[i] / 32768;
|
|
247
|
+
}
|
|
248
|
+
return float32;
|
|
249
|
+
}
|
|
250
|
+
function createWavFile(audio, sampleRate) {
|
|
251
|
+
const dataSize = audio.byteLength;
|
|
252
|
+
const fileSize = 44 + dataSize;
|
|
253
|
+
const buffer = new ArrayBuffer(fileSize);
|
|
254
|
+
const view = new DataView(buffer);
|
|
255
|
+
writeString(view, 0, "RIFF");
|
|
256
|
+
view.setUint32(4, fileSize - 8, true);
|
|
257
|
+
writeString(view, 8, "WAVE");
|
|
258
|
+
writeString(view, 12, "fmt ");
|
|
259
|
+
view.setUint32(16, 16, true);
|
|
260
|
+
view.setUint16(20, 1, true);
|
|
261
|
+
view.setUint16(22, 1, true);
|
|
262
|
+
view.setUint32(24, sampleRate, true);
|
|
263
|
+
view.setUint32(28, sampleRate * 2, true);
|
|
264
|
+
view.setUint16(32, 2, true);
|
|
265
|
+
view.setUint16(34, 16, true);
|
|
266
|
+
writeString(view, 36, "data");
|
|
267
|
+
view.setUint32(40, dataSize, true);
|
|
268
|
+
const audioBytes = new Uint8Array(audio);
|
|
269
|
+
const wavBytes = new Uint8Array(buffer);
|
|
270
|
+
wavBytes.set(audioBytes, 44);
|
|
271
|
+
return buffer;
|
|
272
|
+
}
|
|
273
|
+
function writeString(view, offset, str) {
|
|
274
|
+
for (let i = 0; i < str.length; i++) {
|
|
275
|
+
view.setUint8(offset + i, str.charCodeAt(i));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function createWavBlob(audio, sampleRate) {
|
|
279
|
+
const wavBuffer = createWavFile(audio, sampleRate);
|
|
280
|
+
return new Blob([wavBuffer], { type: "audio/wav" });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// package.json
|
|
284
|
+
var package_default = {
|
|
285
|
+
name: "kugelaudio",
|
|
286
|
+
version: "0.8.0",
|
|
287
|
+
description: "Official JavaScript/TypeScript SDK for KugelAudio TTS API",
|
|
288
|
+
main: "dist/index.js",
|
|
289
|
+
module: "dist/index.mjs",
|
|
290
|
+
types: "dist/index.d.ts",
|
|
291
|
+
exports: {
|
|
292
|
+
".": {
|
|
293
|
+
types: "./dist/index.d.ts",
|
|
294
|
+
import: "./dist/index.mjs",
|
|
295
|
+
require: "./dist/index.js"
|
|
296
|
+
},
|
|
297
|
+
"./livekit": {
|
|
298
|
+
types: "./dist/livekit/index.d.ts",
|
|
299
|
+
import: "./dist/livekit/index.mjs",
|
|
300
|
+
require: "./dist/livekit/index.js"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
files: [
|
|
304
|
+
"dist",
|
|
305
|
+
"src",
|
|
306
|
+
"LICENSE",
|
|
307
|
+
"CHANGELOG.md"
|
|
308
|
+
],
|
|
309
|
+
scripts: {
|
|
310
|
+
build: "tsup src/index.ts src/livekit/index.ts --format cjs,esm --dts",
|
|
311
|
+
dev: "tsup src/index.ts src/livekit/index.ts --format cjs,esm --dts --watch",
|
|
312
|
+
lint: "eslint src/",
|
|
313
|
+
test: "vitest run",
|
|
314
|
+
"test:watch": "vitest",
|
|
315
|
+
prepublishOnly: "npm run build"
|
|
316
|
+
},
|
|
317
|
+
keywords: [
|
|
318
|
+
"tts",
|
|
319
|
+
"text-to-speech",
|
|
320
|
+
"audio",
|
|
321
|
+
"streaming",
|
|
322
|
+
"websocket",
|
|
323
|
+
"kugelaudio"
|
|
324
|
+
],
|
|
325
|
+
author: "KugelAudio <hello@kugelaudio.com>",
|
|
326
|
+
license: "MIT",
|
|
327
|
+
repository: {
|
|
328
|
+
type: "git",
|
|
329
|
+
url: "https://github.com/Kugelaudio/KugelAudio",
|
|
330
|
+
directory: "sdks/js"
|
|
331
|
+
},
|
|
332
|
+
homepage: "https://kugelaudio.com",
|
|
333
|
+
bugs: {
|
|
334
|
+
url: "https://github.com/Kugelaudio/KugelAudio/issues"
|
|
335
|
+
},
|
|
336
|
+
devDependencies: {
|
|
337
|
+
"@livekit/agents": "^1.4.11",
|
|
338
|
+
"@livekit/rtc-node": "^0.13.30",
|
|
339
|
+
"@types/node": "^25.3.2",
|
|
340
|
+
"@types/ws": "^8.18.1",
|
|
341
|
+
tsup: "^8.0.0",
|
|
342
|
+
typescript: "^6.0.2",
|
|
343
|
+
vitest: "^4.0.18"
|
|
344
|
+
},
|
|
345
|
+
peerDependencies: {
|
|
346
|
+
"@livekit/agents": ">=1.0.0",
|
|
347
|
+
"@livekit/rtc-node": ">=0.13.0"
|
|
348
|
+
},
|
|
349
|
+
peerDependenciesMeta: {
|
|
350
|
+
"@livekit/agents": {
|
|
351
|
+
optional: true
|
|
352
|
+
},
|
|
353
|
+
"@livekit/rtc-node": {
|
|
354
|
+
optional: true
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
engines: {
|
|
358
|
+
node: ">=18.0.0"
|
|
359
|
+
},
|
|
360
|
+
dependencies: {
|
|
361
|
+
tsx: "^4.21.0",
|
|
362
|
+
ws: "^8.18.0"
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
export {
|
|
367
|
+
__require,
|
|
368
|
+
__privateGet,
|
|
369
|
+
__privateAdd,
|
|
370
|
+
__privateSet,
|
|
371
|
+
__privateMethod,
|
|
372
|
+
ErrorCodes,
|
|
373
|
+
WsCloseCodes,
|
|
374
|
+
KugelAudioError,
|
|
375
|
+
AuthenticationError,
|
|
376
|
+
RateLimitError,
|
|
377
|
+
InsufficientCreditsError,
|
|
378
|
+
ValidationError,
|
|
379
|
+
ConnectionError,
|
|
380
|
+
NotFoundError,
|
|
381
|
+
classifyHttpError,
|
|
382
|
+
classifyWsFrame,
|
|
383
|
+
classifyWsClose,
|
|
384
|
+
classifyWsHandshakeError,
|
|
385
|
+
clampCfgScale,
|
|
386
|
+
base64ToArrayBuffer,
|
|
387
|
+
decodePCM16,
|
|
388
|
+
createWavFile,
|
|
389
|
+
createWavBlob,
|
|
390
|
+
package_default
|
|
391
|
+
};
|
package/dist/index.d.mts
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
|
-
/**
|
|
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),
|
|
@@ -269,8 +270,9 @@ interface GenerateOptions {
|
|
|
269
270
|
/**
|
|
270
271
|
* Playback speed multiplier (0.8 = slower, 1.0 = normal, 1.2 = faster).
|
|
271
272
|
*
|
|
272
|
-
* Uses pitch-preserving time-stretching (WSOLA); applies
|
|
273
|
-
*
|
|
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).
|
|
274
276
|
* Range: [0.8, 1.2]. Default: 1.0.
|
|
275
277
|
*/
|
|
276
278
|
speed?: number;
|
|
@@ -312,7 +314,7 @@ interface StreamConfig {
|
|
|
312
314
|
voiceId?: number;
|
|
313
315
|
/** Model ID. Default: 'kugel-3'. Legacy ids still accepted; they alias to kugel-3 server-side. */
|
|
314
316
|
modelId?: string;
|
|
315
|
-
/**
|
|
317
|
+
/** Classifier-free guidance scale. Clamped to [1.2, 2.5] (default: 2.0). */
|
|
316
318
|
cfgScale?: number;
|
|
317
319
|
/**
|
|
318
320
|
* Sampling variance. Range [0.0, 1.0]. 0 = most stable, 1 = most variance.
|
|
@@ -369,8 +371,9 @@ interface StreamConfig {
|
|
|
369
371
|
/**
|
|
370
372
|
* Playback speed multiplier (0.8 = slower, 1.0 = normal, 1.2 = faster).
|
|
371
373
|
*
|
|
372
|
-
* Uses pitch-preserving time-stretching (WSOLA); applies
|
|
373
|
-
*
|
|
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).
|
|
374
377
|
* Range: [0.8, 1.2]. Default: 1.0.
|
|
375
378
|
*/
|
|
376
379
|
speed?: number;
|
|
@@ -383,6 +386,41 @@ interface StreamConfig {
|
|
|
383
386
|
*/
|
|
384
387
|
dictionaryIds?: number[];
|
|
385
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;
|
|
423
|
+
}
|
|
386
424
|
/**
|
|
387
425
|
* Event callbacks for a streaming session (`/ws/tts/stream`).
|
|
388
426
|
*
|
|
@@ -577,7 +615,7 @@ interface MultiContextConfig {
|
|
|
577
615
|
sampleRate?: number;
|
|
578
616
|
/** Combined codec+rate token (e.g. 'ulaw_8000'); opt-in, set-once per context. */
|
|
579
617
|
outputFormat?: string;
|
|
580
|
-
/**
|
|
618
|
+
/** Classifier-free guidance scale. Clamped to [1.2, 2.5] (default: 2.0). */
|
|
581
619
|
cfgScale?: number;
|
|
582
620
|
/**
|
|
583
621
|
* Sampling variance. Range [0.0, 1.0]. 0 = most stable, 1 = most variance.
|
|
@@ -1061,6 +1099,22 @@ declare class MultiContextSession {
|
|
|
1061
1099
|
* Send keep-alive to reset a context's inactivity timeout.
|
|
1062
1100
|
*/
|
|
1063
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>;
|
|
1064
1118
|
/**
|
|
1065
1119
|
* Close the session and all contexts.
|
|
1066
1120
|
*/
|
|
@@ -1190,6 +1244,28 @@ declare class StreamingSession {
|
|
|
1190
1244
|
* to change voice, model, language, or other settings.
|
|
1191
1245
|
*/
|
|
1192
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>;
|
|
1193
1269
|
/**
|
|
1194
1270
|
* Close the session and the WebSocket connection.
|
|
1195
1271
|
*
|
|
@@ -1445,9 +1521,6 @@ declare function classifyWsClose(code: number | undefined, reason?: string): Kug
|
|
|
1445
1521
|
*/
|
|
1446
1522
|
declare function classifyWsHandshakeError(err: unknown): KugelAudioError | null;
|
|
1447
1523
|
|
|
1448
|
-
/**
|
|
1449
|
-
* Utility functions for KugelAudio SDK.
|
|
1450
|
-
*/
|
|
1451
1524
|
/**
|
|
1452
1525
|
* Decode base64 string to ArrayBuffer.
|
|
1453
1526
|
*/
|
|
@@ -1465,4 +1538,4 @@ declare function createWavFile(audio: ArrayBuffer, sampleRate: number): ArrayBuf
|
|
|
1465
1538
|
*/
|
|
1466
1539
|
declare function createWavBlob(audio: ArrayBuffer, sampleRate: number): Blob;
|
|
1467
1540
|
|
|
1468
|
-
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 SessionUsage, 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 };
|
|
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 };
|