@breeze.blue/sdk 0.21.1 → 0.22.1
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 +14 -0
- package/README.md +12 -5
- package/dist/client.d.ts +2 -0
- package/dist/client.js +10 -10
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/output-formats.d.ts +10 -0
- package/dist/output-formats.js +8 -0
- package/dist/types.d.ts +6 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.22.1 - 2026-10-29
|
|
4
|
+
|
|
5
|
+
- Document supported Voice Clone reference audio formats and the single-file, 5 MB, synchronous API contract.
|
|
6
|
+
- Align the package release with the Python SDK upload content-type fix.
|
|
7
|
+
|
|
8
|
+
## 0.22.0
|
|
9
|
+
|
|
10
|
+
- Select PCM or MP3 for realtime TTS sessions and preserve the format across managed connections.
|
|
11
|
+
- Export output-format choices shared with the public API while retaining historical conversion profiles.
|
|
12
|
+
- Breaking: remove `visibility` and `primaryCategoryCode` from `voices.savePreview(...)` and `voices.edit(...)`, and remove reference-sample upload arguments from `voices.edit(...)`.
|
|
13
|
+
- Keep official catalog assignment, publication and reference-sample replacement available through authorized low-level HTTP requests or the CLI. Category search and Clone uploads remain available.
|
|
14
|
+
- Voice Clone accepts `referenceLanguageCode: "zh"` to use Qwen ASR for a Chinese reference sample. Omitting it keeps automatic language detection.
|
|
15
|
+
- Check complete Voice and History request fields against public OpenAPI with a shared, operation-specific historical compatibility whitelist.
|
|
16
|
+
|
|
3
17
|
## 0.21.1
|
|
4
18
|
|
|
5
19
|
- Document Voice Design guidance: omitted or null samples 1–4 per preview; explicit values still accept 1–10.
|
package/README.md
CHANGED
|
@@ -107,8 +107,10 @@ If the job is still active, `downloadAudio(...)` rejects with
|
|
|
107
107
|
`BreezeBlueGenerationNotReadyError`; read `error.retryAfter` before retrying.
|
|
108
108
|
|
|
109
109
|
Use realtime text-to-speech when one WebSocket connection should handle multiple
|
|
110
|
-
conversation turns. Realtime
|
|
111
|
-
16-bit
|
|
110
|
+
conversation turns. Realtime supports PCM (default) or MP3 at 24 kHz mono.
|
|
111
|
+
PCM uses raw signed 16-bit little-endian samples. Pass `outputFormat: "mp3"` to
|
|
112
|
+
`realtime.createSession`, `realtime.connect`, or `realtime.connectManaged` to select MP3.
|
|
113
|
+
Each turn's final MP3 bytes arrive before `turn.done`.
|
|
112
114
|
|
|
113
115
|
Realtime needs a `WebSocket` implementation. Browsers, edge runtimes, and
|
|
114
116
|
Node 22+ provide a global one; on Node 20, pass a constructor (for example the
|
|
@@ -396,8 +398,7 @@ Streaming text-to-speech defaults to `pcm` to reduce time to first audio. Pass
|
|
|
396
398
|
format explicitly.
|
|
397
399
|
|
|
398
400
|
Sync and async text-to-speech also take a sample rate and, for the lossy encodings, a bitrate, such as
|
|
399
|
-
`{ outputFormat: "
|
|
400
|
-
downstream compatibility; profiles carrying a sample rate are not available for streaming.
|
|
401
|
+
`{ outputFormat: "wav_24000" }`. Profiles carrying a sample rate apply to sync and async conversion; streaming uses bare encoding names.
|
|
401
402
|
|
|
402
403
|
## Voices
|
|
403
404
|
|
|
@@ -445,6 +446,10 @@ Breeze voice creation is always two steps: produce a **preview**, let the
|
|
|
445
446
|
user accept it, then **save the preview** as a real voice. Three ways to
|
|
446
447
|
produce a preview:
|
|
447
448
|
|
|
449
|
+
Clone samples accept MP3, WAV, M4A, FLAC, AAC, OGG, Opus, WebM audio, WMA,
|
|
450
|
+
or AIFF, at least 3 seconds and up to 5 MB. Clone calls are synchronous.
|
|
451
|
+
Supply a matching `filename` or `contentType` with the upload.
|
|
452
|
+
|
|
448
453
|
```ts
|
|
449
454
|
import { readFile } from "node:fs/promises";
|
|
450
455
|
|
|
@@ -564,7 +569,9 @@ const saved = await client.voices.savePreview({
|
|
|
564
569
|
});
|
|
565
570
|
```
|
|
566
571
|
|
|
567
|
-
|
|
572
|
+
Saved previews are private to your account. Editing a voice's metadata preserves its visibility.
|
|
573
|
+
|
|
574
|
+
Edit a saved voice's name, description, tags, or Voice Metadata, or delete it:
|
|
568
575
|
|
|
569
576
|
```ts
|
|
570
577
|
await client.voices.edit(saved.voiceId, {
|
package/dist/client.d.ts
CHANGED
|
@@ -237,6 +237,8 @@ declare class VoicesResource {
|
|
|
237
237
|
* Generate a clone preview from a single audio sample. Returns a
|
|
238
238
|
* `generatedVoiceId`; call {@link savePreview} after the user accepts
|
|
239
239
|
* the preview to persist it as a real voice.
|
|
240
|
+
* Accepts MP3, WAV, M4A, FLAC, AAC, OGG, Opus, WebM audio, WMA, or AIFF,
|
|
241
|
+
* at least 3 seconds and up to 5 MB. Supply a matching filename or contentType.
|
|
240
242
|
*/
|
|
241
243
|
createClonePreview(request: VoiceClonePreviewRequest, options?: RequestOptions): Promise<VoiceClonePreview>;
|
|
242
244
|
/**
|
package/dist/client.js
CHANGED
|
@@ -163,6 +163,7 @@ class RealtimeTextToSpeechResource {
|
|
|
163
163
|
voiceSettings: request.voiceSettings == null ? request.voiceSettings : { guidanceScale: request.voiceSettings.guidanceScale, useSpeakerBoost: request.voiceSettings.useSpeakerBoost },
|
|
164
164
|
inactivityTimeoutSeconds: request.inactivityTimeoutSeconds,
|
|
165
165
|
enableLogging: request.enableLogging,
|
|
166
|
+
outputFormat: request.outputFormat,
|
|
166
167
|
}, options);
|
|
167
168
|
}
|
|
168
169
|
async connect(voiceId, options = {}) {
|
|
@@ -170,7 +171,7 @@ class RealtimeTextToSpeechResource {
|
|
|
170
171
|
options.websocketUrl !== undefined ||
|
|
171
172
|
options.directWebsocketUrl !== undefined) && hasRealtimeSessionParams(options)) {
|
|
172
173
|
console.warn("@breeze.blue/sdk: realtime.connect ignores modelId, languageCode, instructions, voiceSettings, " +
|
|
173
|
-
"inactivityTimeoutSeconds, and enableLogging when session credentials are provided. " +
|
|
174
|
+
"inactivityTimeoutSeconds, outputFormat, and enableLogging when session credentials are provided. " +
|
|
174
175
|
"Configure these initial values when creating the realtime session instead. " +
|
|
175
176
|
"To change instructions between turns, call connection.updateInstructions() and wait for session.updated.");
|
|
176
177
|
}
|
|
@@ -185,6 +186,7 @@ class RealtimeTextToSpeechResource {
|
|
|
185
186
|
voiceSettings: options.voiceSettings,
|
|
186
187
|
inactivityTimeoutSeconds: options.inactivityTimeoutSeconds,
|
|
187
188
|
enableLogging: options.enableLogging,
|
|
189
|
+
outputFormat: options.outputFormat,
|
|
188
190
|
}, {
|
|
189
191
|
signal: options.signal,
|
|
190
192
|
timeout: options.timeout,
|
|
@@ -226,7 +228,7 @@ class RealtimeTextToSpeechResource {
|
|
|
226
228
|
async connectManaged(voiceId, options = {}) {
|
|
227
229
|
if (options.sessionFactory !== undefined && hasRealtimeSessionParams(options)) {
|
|
228
230
|
console.warn("@breeze.blue/sdk: realtime.connectManaged cannot apply modelId, languageCode, instructions, " +
|
|
229
|
-
"voiceSettings, inactivityTimeoutSeconds, or enableLogging when sessionFactory is provided. " +
|
|
231
|
+
"voiceSettings, inactivityTimeoutSeconds, outputFormat, or enableLogging when sessionFactory is provided. " +
|
|
230
232
|
"Configure these when the factory creates each realtime session. After connecting, confirmed " +
|
|
231
233
|
"updateInstructions() values are carried across managed physical sessions.");
|
|
232
234
|
}
|
|
@@ -237,6 +239,7 @@ class RealtimeTextToSpeechResource {
|
|
|
237
239
|
voiceSettings: options.voiceSettings,
|
|
238
240
|
inactivityTimeoutSeconds: options.inactivityTimeoutSeconds,
|
|
239
241
|
enableLogging: options.enableLogging,
|
|
242
|
+
outputFormat: options.outputFormat,
|
|
240
243
|
};
|
|
241
244
|
const connectionTimeout = options.timeout ?? this.client.timeout ?? DEFAULT_REALTIME_HANDSHAKE_TIMEOUT_MS;
|
|
242
245
|
const createConnection = async (signal) => {
|
|
@@ -272,7 +275,8 @@ function hasRealtimeSessionParams(options) {
|
|
|
272
275
|
options.instructions !== undefined ||
|
|
273
276
|
options.voiceSettings !== undefined ||
|
|
274
277
|
options.inactivityTimeoutSeconds !== undefined ||
|
|
275
|
-
options.enableLogging !== undefined
|
|
278
|
+
options.enableLogging !== undefined ||
|
|
279
|
+
options.outputFormat !== undefined);
|
|
276
280
|
}
|
|
277
281
|
function realtimeClientSecretSubprotocols(clientSecret) {
|
|
278
282
|
if (!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{43}$/.test(clientSecret)) {
|
|
@@ -1569,6 +1573,8 @@ class VoicesResource {
|
|
|
1569
1573
|
* Generate a clone preview from a single audio sample. Returns a
|
|
1570
1574
|
* `generatedVoiceId`; call {@link savePreview} after the user accepts
|
|
1571
1575
|
* the preview to persist it as a real voice.
|
|
1576
|
+
* Accepts MP3, WAV, M4A, FLAC, AAC, OGG, Opus, WebM audio, WMA, or AIFF,
|
|
1577
|
+
* at least 3 seconds and up to 5 MB. Supply a matching filename or contentType.
|
|
1572
1578
|
*/
|
|
1573
1579
|
async createClonePreview(request, options) {
|
|
1574
1580
|
return this.client.requestJson("POST", "/v1/voice-previews/clone", undefined, clonePreviewForm(request), options);
|
|
@@ -1634,8 +1640,6 @@ class VoicesResource {
|
|
|
1634
1640
|
voiceName: request.voiceName,
|
|
1635
1641
|
voiceDescription: request.voiceDescription,
|
|
1636
1642
|
tags: request.tags,
|
|
1637
|
-
primaryCategoryCode: request.primaryCategoryCode,
|
|
1638
|
-
visibility: request.visibility,
|
|
1639
1643
|
languageCode: request.languageCode,
|
|
1640
1644
|
gender: request.gender,
|
|
1641
1645
|
age: request.age,
|
|
@@ -1789,6 +1793,7 @@ function clonePreviewForm(request) {
|
|
|
1789
1793
|
const form = new FormData();
|
|
1790
1794
|
appendOptional(form, "name", request.name ?? undefined);
|
|
1791
1795
|
appendOptional(form, "description", request.description);
|
|
1796
|
+
appendOptional(form, "reference_language_code", request.referenceLanguageCode);
|
|
1792
1797
|
appendOptional(form, "remove_background_noise", request.removeBackgroundNoise ?? false);
|
|
1793
1798
|
for (const file of normalizeFiles(request.file, request.files, { required: true })) {
|
|
1794
1799
|
appendFile(form, "files", file);
|
|
@@ -1803,8 +1808,6 @@ function voiceEditForm(request) {
|
|
|
1803
1808
|
for (const tag of request.tags)
|
|
1804
1809
|
form.append("tags", tag);
|
|
1805
1810
|
}
|
|
1806
|
-
appendOptional(form, "primary_category_code", request.primaryCategoryCode);
|
|
1807
|
-
appendOptional(form, "visibility", request.visibility);
|
|
1808
1811
|
appendOptional(form, "language_code", request.languageCode);
|
|
1809
1812
|
appendNullable(form, "gender", request.gender);
|
|
1810
1813
|
appendNullable(form, "age", request.age);
|
|
@@ -1818,9 +1821,6 @@ function voiceEditForm(request) {
|
|
|
1818
1821
|
}
|
|
1819
1822
|
}
|
|
1820
1823
|
appendNullable(form, "accent", request.accent);
|
|
1821
|
-
for (const file of normalizeFiles(request.file, request.files, { required: false })) {
|
|
1822
|
-
appendFile(form, "files", file);
|
|
1823
|
-
}
|
|
1824
1824
|
return form;
|
|
1825
1825
|
}
|
|
1826
1826
|
function stripHiddenVoiceFields(voice) {
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const AUDIO_ENCODINGS: readonly ["mp3", "wav", "flac", "pcm", "aac", "opus"];
|
|
2
|
+
export declare const TTS_OUTPUT_FORMATS: readonly ["mp3", "wav", "flac", "pcm", "aac", "opus", "mp3_24000_64", "mp3_24000_96", "mp3_24000_128", "mp3_24000_160", "wav_24000", "pcm_24000", "flac_24000", "aac_24000_128"];
|
|
3
|
+
export declare const STREAMING_OUTPUT_FORMATS: readonly ["pcm", "mp3", "wav"];
|
|
4
|
+
export declare const REALTIME_OUTPUT_FORMATS: readonly ["pcm", "mp3"];
|
|
5
|
+
export type TtsOutputFormat = typeof TTS_OUTPUT_FORMATS[number] | (string & {});
|
|
6
|
+
export type StreamingOutputFormat = typeof STREAMING_OUTPUT_FORMATS[number];
|
|
7
|
+
export type RealtimeOutputFormat = typeof REALTIME_OUTPUT_FORMATS[number];
|
|
8
|
+
export declare const DEFAULT_TTS_OUTPUT_FORMAT = "mp3";
|
|
9
|
+
export declare const DEFAULT_STREAM_OUTPUT_FORMAT = "pcm";
|
|
10
|
+
export declare const DEFAULT_REALTIME_OUTPUT_FORMAT = "pcm";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Generated from generation_runtime.output_formats; do not edit by hand.
|
|
2
|
+
export const AUDIO_ENCODINGS = ["mp3", "wav", "flac", "pcm", "aac", "opus"];
|
|
3
|
+
export const TTS_OUTPUT_FORMATS = ["mp3", "wav", "flac", "pcm", "aac", "opus", "mp3_24000_64", "mp3_24000_96", "mp3_24000_128", "mp3_24000_160", "wav_24000", "pcm_24000", "flac_24000", "aac_24000_128"];
|
|
4
|
+
export const STREAMING_OUTPUT_FORMATS = ["pcm", "mp3", "wav"];
|
|
5
|
+
export const REALTIME_OUTPUT_FORMATS = ["pcm", "mp3"];
|
|
6
|
+
export const DEFAULT_TTS_OUTPUT_FORMAT = "mp3";
|
|
7
|
+
export const DEFAULT_STREAM_OUTPUT_FORMAT = "pcm";
|
|
8
|
+
export const DEFAULT_REALTIME_OUTPUT_FORMAT = "pcm";
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TtsOutputFormat, RealtimeOutputFormat } from "./output-formats.js";
|
|
1
2
|
import type { WordTimestamp } from "./timestamps.js";
|
|
2
3
|
import type { VoiceAccent, VoiceWritableAccent, VoiceAge, VoiceGender, VoiceLanguageCode, VoiceTone } from "./voice-metadata.js";
|
|
3
4
|
export type JsonObject = Record<string, unknown>;
|
|
@@ -20,7 +21,7 @@ export interface RequestOptions {
|
|
|
20
21
|
timeout?: number;
|
|
21
22
|
}
|
|
22
23
|
export interface AudioRequestOptions extends RequestOptions {
|
|
23
|
-
outputFormat?:
|
|
24
|
+
outputFormat?: TtsOutputFormat;
|
|
24
25
|
}
|
|
25
26
|
export interface StreamTextToSpeechOptions extends AudioRequestOptions {
|
|
26
27
|
enableLogging?: boolean;
|
|
@@ -38,6 +39,7 @@ export interface BreezeBlueWebSocket {
|
|
|
38
39
|
close(code?: number, reason?: string): void;
|
|
39
40
|
}
|
|
40
41
|
export interface RealtimeTextToSpeechSessionRequest {
|
|
42
|
+
outputFormat?: RealtimeOutputFormat;
|
|
41
43
|
modelId?: string;
|
|
42
44
|
languageCode?: string;
|
|
43
45
|
instructions?: string;
|
|
@@ -49,7 +51,8 @@ export interface RealtimeTextToSpeechAudioFormat {
|
|
|
49
51
|
codec: "pcm_s16le" | string;
|
|
50
52
|
sampleRate: number;
|
|
51
53
|
channels: number;
|
|
52
|
-
sampleWidthBits
|
|
54
|
+
sampleWidthBits?: number | null;
|
|
55
|
+
bitrateKbps?: number;
|
|
53
56
|
}
|
|
54
57
|
export interface RealtimeTextToSpeechSession {
|
|
55
58
|
clientSecret: string;
|
|
@@ -386,6 +389,7 @@ export interface UploadFile {
|
|
|
386
389
|
contentType?: string;
|
|
387
390
|
}
|
|
388
391
|
export interface VoiceClonePreviewRequest {
|
|
392
|
+
referenceLanguageCode?: "zh";
|
|
389
393
|
name?: string | null;
|
|
390
394
|
file?: UploadData | UploadFile;
|
|
391
395
|
files?: Array<UploadData | UploadFile>;
|
|
@@ -400,15 +404,11 @@ export interface VoiceEditRequest {
|
|
|
400
404
|
name?: string;
|
|
401
405
|
description?: string;
|
|
402
406
|
tags?: string[];
|
|
403
|
-
primaryCategoryCode?: string;
|
|
404
|
-
visibility?: "private" | "public" | string;
|
|
405
407
|
languageCode?: VoiceLanguageCode;
|
|
406
408
|
gender?: VoiceGender | null;
|
|
407
409
|
age?: VoiceAge | null;
|
|
408
410
|
tone?: VoiceTone[];
|
|
409
411
|
accent?: VoiceWritableAccent | null;
|
|
410
|
-
file?: UploadData | UploadFile;
|
|
411
|
-
files?: Array<UploadData | UploadFile>;
|
|
412
412
|
}
|
|
413
413
|
export interface VoiceDesignRequest {
|
|
414
414
|
voiceDescription: string;
|
|
@@ -509,8 +509,6 @@ export interface SaveVoiceRequest {
|
|
|
509
509
|
voiceName?: string | null;
|
|
510
510
|
voiceDescription?: string | null;
|
|
511
511
|
tags?: string[];
|
|
512
|
-
primaryCategoryCode?: string;
|
|
513
|
-
visibility?: "private" | "public" | string;
|
|
514
512
|
languageCode: VoiceLanguageCode;
|
|
515
513
|
gender?: VoiceGender | null;
|
|
516
514
|
age?: VoiceAge | null;
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.
|
|
1
|
+
export declare const SDK_VERSION = "0.22.1";
|
|
2
2
|
export declare const SDK_NAME = "@breeze.blue/sdk";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.
|
|
1
|
+
export const SDK_VERSION = "0.22.1";
|
|
2
2
|
export const SDK_NAME = "@breeze.blue/sdk";
|