@breeze.blue/sdk 0.18.0 → 0.20.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.0
4
+
5
+ - Manage Studio projects, chapters, clips, auxiliary tracks, audio instances and files through `client.studio`.
6
+ - Import multi-chapter scripts with existing voices, preserve edit tokens and error metadata, and upload materials without forwarding API credentials.
7
+ - Convert seconds and 48 kHz timeline frames with SDK helpers.
8
+
9
+ ## 0.19.0
10
+
11
+ - Create Voice Remix candidates from custom descriptions or curated presets, with automatic input preparation and Expressive (4) as the default strength.
12
+ - List Remix presets, reuse a prepared performance across candidates, and read source metadata and original-audio comparisons.
13
+ - Retry Remix submissions with an idempotency key and save candidates using their source voice's name and description by default.
14
+
3
15
  ## 0.18.0
4
16
 
5
17
  - Create asynchronous speech jobs with word timestamps and read timing from completed job results.
package/README.md CHANGED
@@ -488,6 +488,45 @@ while (localized.status !== "ready") {
488
488
  generatedVoiceId = localized.generatedVoiceId!;
489
489
  ```
490
490
 
491
+ Voice Remix creates a same-language candidate from an owned or official voice
492
+ and a custom description or preset. Each successful candidate uses the Voice Design candidate
493
+ price. The source remains unchanged.
494
+
495
+ ```ts
496
+ const remixJob = await client.voices.createRemixPreview({
497
+ voiceId: firstVoiceId,
498
+ prompt: "Make the voice warmer and more expressive.",
499
+ guidanceScale: 4,
500
+ });
501
+ let remix = await client.voices.getRemixPreview(remixJob.generationJobId);
502
+ while (remix.status !== "ready") {
503
+ if (remix.status === "failed" || remix.status === "cancelled") {
504
+ throw new Error(remix.error?.detail ?? remix.status);
505
+ }
506
+ await new Promise((resolve) => setTimeout(resolve, 2000));
507
+ remix = await client.voices.getRemixPreview(remixJob.generationJobId);
508
+ }
509
+ generatedVoiceId = remix.generatedVoiceId!;
510
+ ```
511
+
512
+ Use `streamPreview` and `savePreview` with the generated ID to audition and save
513
+ a private, independent voice. A client timeout leaves the server job running.
514
+
515
+ Custom input is enhanced into an instruction and matching script in the source
516
+ language. List templates with `client.voices.listRemixPresets()` and pass
517
+ `presetId` instead of `prompt` to use one. Edited templates are enhanced;
518
+ unchanged templates are translated only when the source language differs.
519
+
520
+ To compare strengths, call `client.voices.prepareRemixPreview(...)` first and
521
+ pass its `preparationToken` to each create call with the same input. The token
522
+ lasts 24 hours. Values 2 / 4 / 6 / 8 mean Stable / Expressive / Creative / Intense;
523
+ 4 is the default. Web Auto compares separate candidates at 4, 6, and 8.
524
+ Use `options.headers["Idempotency-Key"]` to retry uncertain submissions safely,
525
+ with a distinct key per candidate. Status includes `comparisonAudioUrl`,
526
+ `comparisonText`, and `sourceVoice`. Saving without `voiceName` or
527
+ `voiceDescription` uses the source values.
528
+ See the [Voice Remix guide](https://docs.breezeblue.ai/guides/voice-remix).
529
+
491
530
  For the fastest first audio, generate one design preview as a live 24 kHz mono
492
531
  PCM response. The Node `stream()` helper consumes the response body directly;
493
532
  a clean end means `generatedVoiceId` is ready to save:
@@ -612,3 +651,11 @@ Stream audio and word/token timestamps with `client.textToSpeech.streamWithTimes
612
651
  For a complete response, use `client.textToSpeech.convertWithTimestamps(...)`. It returns base64 audio, its content type, and the full word/token timestamp list. Decode the audio before saving or playback. See [Speech timing](https://docs.breezeblue.ai/guides/speech-timing) and [Convert with timestamps](https://docs.breezeblue.ai/api-reference/text-to-speech/convert-with-timestamps).
613
652
 
614
653
  For background generation with timing, use `client.textToSpeech.createJobWithTimestamps(...)`. Poll with `client.generationJobs.get(jobId)`; a ready job includes `wordTimestamps` and the audio download URL.
654
+
655
+ Clone preview creation accepts an omitted name. The server uses the filename stem or `Cloned Voice`; saving a Clone preview without a name keeps its preview name. Other preview types still require a save name. Explicit names longer than 80 Unicode characters are rejected.
656
+
657
+ ## Studio management
658
+
659
+ `client.studio` exposes `projects`, `chapters`, `clips`, `tracks`, `instances`, and `files`. Import scripts with existing voice IDs, edit inherited instructions and silence, upload MP3/WAV materials, and arrange background audio. Project writes require the latest edit token and a UUID operation ID. Conflicts preserve error metadata and are not retried automatically.
660
+
661
+ See the [Studio initialization guide](https://docs.breezeblue.ai/guides/studio-projects) for a complete workflow. Signed uploads use a separate request without the API key. Management operations do not generate speech or export projects.
@@ -19,7 +19,7 @@ function transform(value, keyFn) {
19
19
  if (isPlainObject(value)) {
20
20
  const out = {};
21
21
  for (const [k, v] of Object.entries(value)) {
22
- out[keyFn(k)] = transform(v, keyFn);
22
+ out[keyFn(k)] = ["client_refs", "clientRefs", "headers"].includes(k) ? v : transform(v, keyFn);
23
23
  }
24
24
  return out;
25
25
  }
package/dist/client.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import { StudioResource } from "./studio.js";
1
2
  import { SpeechTimingStream, type SpeechWithTimestamps } from "./timestamps.js";
2
3
  import { AudioResponse } from "./audio.js";
3
- import type { AudioRequestOptions, BreezeBlueWebSocket, AsyncTextToSpeechJob, Balance, BreezeBlueClientOptions, CurrentApiKeyResponse, GenericStatus, GenerationJob, HistoryItem, HistoryList, HistoryListParams, Model, RequestOptions, RealtimeTextToSpeechConnectOptions, RealtimeTextToSpeechEvent, RealtimeTextToSpeechManagedConnectOptions, RealtimeTextToSpeechMessage, RealtimeTextToSpeechSession, RealtimeTextToSpeechSessionRequest, SavedVoice, SaveVoiceRequest, StreamTextToSpeechOptions, TextToSpeechRequest, TtsEnhanceRequest, TtsEnhanceResponse, Usage, UsageParams, Voice, VoiceClonePreview, VoiceClonePreviewRequest, VoiceDesignRequest, VoiceDesignResponse, VoiceDesignStreamRequest, VoiceEditRequest, VoiceList, VoiceLocalizeJob, VoiceLocalizePreviewRequest, VoiceLocalizePreviewStatus, VoiceMetadataOptions, VoiceRandomParams, VoiceSearchParams, VoiceSettings } from "./types.js";
4
+ import type { AudioRequestOptions, BreezeBlueWebSocket, AsyncTextToSpeechJob, Balance, BreezeBlueClientOptions, CurrentApiKeyResponse, GenericStatus, GenerationJob, HistoryItem, HistoryList, HistoryListParams, Model, RequestOptions, RealtimeTextToSpeechConnectOptions, RealtimeTextToSpeechEvent, RealtimeTextToSpeechManagedConnectOptions, RealtimeTextToSpeechMessage, RealtimeTextToSpeechSession, RealtimeTextToSpeechSessionRequest, SavedVoice, SaveVoiceRequest, StreamTextToSpeechOptions, TextToSpeechRequest, TtsEnhanceRequest, TtsEnhanceResponse, Usage, UsageParams, Voice, VoiceClonePreview, VoiceClonePreviewRequest, VoiceDesignRequest, VoiceDesignResponse, VoiceDesignStreamRequest, VoiceEditRequest, VoiceList, VoiceLocalizeJob, VoiceLocalizePreviewRequest, VoiceLocalizePreviewStatus, VoiceRemixPreviewRequest, VoiceRemixPrepareRequest, VoiceRemixPresets, VoiceRemixPreparation, VoiceRemixJob, VoiceRemixPreviewStatus, VoiceMetadataOptions, VoiceRandomParams, VoiceSearchParams, VoiceSettings } from "./types.js";
4
5
  export declare class BreezeBlueClient {
5
6
  readonly apiKey: string | undefined;
6
7
  readonly baseUrl: string;
@@ -14,6 +15,7 @@ export declare class BreezeBlueClient {
14
15
  readonly history: HistoryResource;
15
16
  readonly models: ModelsResource;
16
17
  readonly account: AccountResource;
18
+ readonly studio: StudioResource;
17
19
  constructor(options?: BreezeBlueClientOptions);
18
20
  requestJson<T>(method: string, path: string, params?: object, body?: unknown, options?: RequestOptions): Promise<T>;
19
21
  requestAudio(method: string, path: string, params?: object, body?: unknown, options?: RequestOptions): Promise<AudioResponse>;
@@ -252,6 +254,14 @@ declare class VoicesResource {
252
254
  * A clean end means `generatedVoiceId` is ready for {@link savePreview}.
253
255
  */
254
256
  streamDesignPreview(request: VoiceDesignStreamRequest, options?: RequestOptions): Promise<AudioResponse>;
257
+ /** List curated voice changes and their sample recordings. */
258
+ listRemixPresets(options?: RequestOptions): Promise<VoiceRemixPresets>;
259
+ /** Prepare once without generating audio; reuse the token for 24 hours with the same input. */
260
+ prepareRemixPreview(request: VoiceRemixPrepareRequest, options?: RequestOptions): Promise<VoiceRemixPreparation>;
261
+ /** Create one candidate. Custom input is enhanced automatically; guidance defaults to 4. */
262
+ createRemixPreview(request: VoiceRemixPreviewRequest, options?: RequestOptions): Promise<VoiceRemixJob>;
263
+ /** A polling timeout does not cancel the server task. Keep the job ID to resume polling. */
264
+ getRemixPreview(generationJobId: string, options?: RequestOptions): Promise<VoiceRemixPreviewStatus>;
255
265
  /**
256
266
  * Start a preview that speaks an existing voice in another language.
257
267
  * Localization runs as a background job: poll the returned
@@ -266,9 +276,9 @@ declare class VoicesResource {
266
276
  * is set only when the job ends in `failed`.
267
277
  */
268
278
  getLocalizePreview(generationJobId: string, options?: RequestOptions): Promise<VoiceLocalizePreviewStatus>;
269
- /** Download the completed audio of a clone or design preview. */
279
+ /** Download a ready Design, Clone, Remix or Localize preview. */
270
280
  streamPreview(generatedVoiceId: string, options?: AudioRequestOptions): Promise<AudioResponse>;
271
- /** Persist a clone or design preview as a real voice asset. */
281
+ /** Save a ready preview; Remix defaults name and description to its source. */
272
282
  savePreview(request: SaveVoiceRequest, options?: RequestOptions): Promise<SavedVoice>;
273
283
  }
274
284
  declare class HistoryResource {
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { StudioResource } from "./studio.js";
1
2
  import { SpeechTimingStream } from "./timestamps.js";
2
3
  import { AudioResponse } from "./audio.js";
3
4
  import { BreezeBlueAPIError, BreezeBlueConfigurationError, BreezeBlueRealtimeError, errorFromResponse, } from "./errors.js";
@@ -33,6 +34,7 @@ export class BreezeBlueClient {
33
34
  history;
34
35
  models;
35
36
  account;
37
+ studio;
36
38
  constructor(options = {}) {
37
39
  const envApiKey = typeof process !== "undefined" ? process.env.BREEZE_API_KEY : undefined;
38
40
  const envBaseUrl = typeof process !== "undefined" ? process.env.BREEZE_BASE_URL : undefined;
@@ -50,6 +52,7 @@ export class BreezeBlueClient {
50
52
  this.history = new HistoryResource(this);
51
53
  this.models = new ModelsResource(this);
52
54
  this.account = new AccountResource(this);
55
+ this.studio = new StudioResource(this);
53
56
  }
54
57
  async requestJson(method, path, params, body, options) {
55
58
  const response = await this.request(method, path, params, body, options);
@@ -1580,6 +1583,22 @@ class VoicesResource {
1580
1583
  streamDesignPreview(request, options) {
1581
1584
  return this.client.requestAudio("POST", "/v1/voice-previews/design/stream", undefined, request, options);
1582
1585
  }
1586
+ /** List curated voice changes and their sample recordings. */
1587
+ listRemixPresets(options) {
1588
+ return this.client.requestJson("GET", "/v1/voice-previews/remix/presets", undefined, undefined, options);
1589
+ }
1590
+ /** Prepare once without generating audio; reuse the token for 24 hours with the same input. */
1591
+ prepareRemixPreview(request, options) {
1592
+ return this.client.requestJson("POST", "/v1/voice-previews/remix/prepare", undefined, request, options);
1593
+ }
1594
+ /** Create one candidate. Custom input is enhanced automatically; guidance defaults to 4. */
1595
+ createRemixPreview(request, options) {
1596
+ return this.client.requestJson("POST", "/v1/voice-previews/remix", undefined, request, options);
1597
+ }
1598
+ /** A polling timeout does not cancel the server task. Keep the job ID to resume polling. */
1599
+ getRemixPreview(generationJobId, options) {
1600
+ return this.client.requestJson("GET", `/v1/voice-previews/remix/${encodeURIComponent(generationJobId)}`, undefined, undefined, options);
1601
+ }
1583
1602
  /**
1584
1603
  * Start a preview that speaks an existing voice in another language.
1585
1604
  * Localization runs as a background job: poll the returned
@@ -1598,11 +1617,11 @@ class VoicesResource {
1598
1617
  getLocalizePreview(generationJobId, options) {
1599
1618
  return this.client.requestJson("GET", `/v1/voice-previews/localize/${encodeURIComponent(generationJobId)}`, undefined, undefined, options);
1600
1619
  }
1601
- /** Download the completed audio of a clone or design preview. */
1620
+ /** Download a ready Design, Clone, Remix or Localize preview. */
1602
1621
  streamPreview(generatedVoiceId, options = {}) {
1603
1622
  return this.client.requestAudio("GET", `/v1/voice-previews/${encodeURIComponent(generatedVoiceId)}/stream`, { outputFormat: options.outputFormat }, undefined, options);
1604
1623
  }
1605
- /** Persist a clone or design preview as a real voice asset. */
1624
+ /** Save a ready preview; Remix defaults name and description to its source. */
1606
1625
  async savePreview(request, options) {
1607
1626
  const result = await this.client.requestJson("POST", `/v1/voice-previews/${encodeURIComponent(request.generatedVoiceId)}/save`, undefined, {
1608
1627
  voiceName: request.voiceName,
@@ -1754,6 +1773,9 @@ function mergeHeaders(headers, input) {
1754
1773
  new Headers(input).forEach((value, key) => headers.set(key, value));
1755
1774
  }
1756
1775
  function clonePreviewForm(request) {
1776
+ if (request.name != null && typeof request.name !== "string") {
1777
+ throw new BreezeBlueConfigurationError("Clone name must be a string or null.");
1778
+ }
1757
1779
  if (request.removeBackgroundNoise) {
1758
1780
  throw new BreezeBlueConfigurationError("removeBackgroundNoise is not supported by the Breeze Developer API.");
1759
1781
  }
@@ -1763,7 +1785,7 @@ function clonePreviewForm(request) {
1763
1785
  }
1764
1786
  }
1765
1787
  const form = new FormData();
1766
- form.set("name", request.name);
1788
+ appendOptional(form, "name", request.name ?? undefined);
1767
1789
  appendOptional(form, "description", request.description);
1768
1790
  for (const file of normalizeFiles(request.file, request.files, { required: true })) {
1769
1791
  appendFile(form, "files", file);
package/dist/index.d.ts CHANGED
@@ -6,3 +6,5 @@ export type * from "./types.js";
6
6
  export * from "./voice-metadata.js";
7
7
  export { SpeechTimingStream } from "./timestamps.js";
8
8
  export type { SpeechTimingChunk, SpeechWithTimestamps, WordTimestamp } from "./timestamps.js";
9
+ export * from "./studio.js";
10
+ export type * from "./studio-types.js";
package/dist/index.js CHANGED
@@ -4,3 +4,4 @@ export { BreezeBlueClient, ManagedRealtimeTextToSpeechConnection, RealtimeTextTo
4
4
  export { SDK_NAME, SDK_VERSION } from "./version.js";
5
5
  export * from "./voice-metadata.js";
6
6
  export { SpeechTimingStream } from "./timestamps.js";
7
+ export * from "./studio.js";
@@ -0,0 +1,337 @@
1
+ export interface StudioChapterCreate {
2
+ expectedEditToken: string;
3
+ operationId: string;
4
+ title: string;
5
+ }
6
+ export interface StudioChapterDelete {
7
+ expectedEditToken: string;
8
+ operationId: string;
9
+ moveToChapterId?: string | null;
10
+ }
11
+ export interface StudioChapterList {
12
+ items: Array<StudioChapterView>;
13
+ editToken: string;
14
+ }
15
+ export interface StudioChapterPatch {
16
+ expectedEditToken: string;
17
+ operationId: string;
18
+ title: string;
19
+ }
20
+ export interface StudioChapterResult {
21
+ chapter: StudioChapterView;
22
+ editToken: string;
23
+ }
24
+ export interface StudioChapterView {
25
+ id: string;
26
+ title: string;
27
+ deleted: boolean;
28
+ clipIds: Array<string>;
29
+ }
30
+ export interface StudioClipBatchCreate {
31
+ expectedEditToken: string;
32
+ operationId: string;
33
+ chapterId?: string | null;
34
+ afterClipId?: string | null;
35
+ clips: Array<StudioClipFields>;
36
+ }
37
+ export interface StudioClipBatchPatch {
38
+ expectedEditToken: string;
39
+ operationId: string;
40
+ updates: Array<StudioClipUpdateItem>;
41
+ }
42
+ export interface StudioClipBulkDelete {
43
+ expectedEditToken: string;
44
+ operationId: string;
45
+ clipIds: Array<string>;
46
+ }
47
+ export interface StudioClipCreate {
48
+ expectedEditToken: string;
49
+ operationId: string;
50
+ clientRef?: string | null;
51
+ name?: string;
52
+ script?: string;
53
+ instructions?: string;
54
+ voiceId?: string | null;
55
+ playback?: StudioPlayback;
56
+ trailingSilenceMs?: number | null;
57
+ chapterId?: string | null;
58
+ afterClipId?: string | null;
59
+ }
60
+ export interface StudioClipFields {
61
+ clientRef?: string | null;
62
+ name?: string;
63
+ script?: string;
64
+ instructions?: string;
65
+ voiceId?: string | null;
66
+ playback?: StudioPlayback;
67
+ trailingSilenceMs?: number | null;
68
+ }
69
+ export interface StudioClipList {
70
+ items: Array<StudioClipView>;
71
+ editToken: string;
72
+ total: number;
73
+ page: number;
74
+ pageSize: number;
75
+ }
76
+ export interface StudioClipMove {
77
+ expectedEditToken: string;
78
+ operationId: string;
79
+ clipIds: Array<string>;
80
+ chapterId: string;
81
+ afterClipId?: string | null;
82
+ }
83
+ export interface StudioClipPatch {
84
+ expectedEditToken: string;
85
+ operationId: string;
86
+ name?: string | null;
87
+ script?: string | null;
88
+ instructions?: string | null;
89
+ voiceId?: string | null;
90
+ playback?: StudioPlayback | null;
91
+ trailingSilenceMs?: number | null;
92
+ }
93
+ export interface StudioClipReorder {
94
+ expectedEditToken: string;
95
+ operationId: string;
96
+ ids: Array<string>;
97
+ chapterId: string;
98
+ }
99
+ export interface StudioClipResult {
100
+ clip: StudioClipView;
101
+ editToken: string;
102
+ }
103
+ export interface StudioClipUpdateItem {
104
+ name?: string | null;
105
+ script?: string | null;
106
+ instructions?: string | null;
107
+ voiceId?: string | null;
108
+ playback?: StudioPlayback | null;
109
+ trailingSilenceMs?: number | null;
110
+ clipId: string;
111
+ }
112
+ export interface StudioClipView {
113
+ id: string;
114
+ chapterId: string | null;
115
+ name: string;
116
+ script: string;
117
+ instructions: string;
118
+ voiceId: string | null;
119
+ voice: StudioVoiceSummary | null;
120
+ playback: StudioPlayback;
121
+ trailingSilenceMs: number | null;
122
+ effectiveInstructions: string;
123
+ effectiveTrailingSilenceMs: number;
124
+ version: number;
125
+ }
126
+ export interface StudioDeleted {
127
+ deleted?: boolean;
128
+ editToken?: string | null;
129
+ }
130
+ export interface StudioEdit {
131
+ expectedEditToken: string;
132
+ operationId: string;
133
+ }
134
+ export interface StudioEffects {
135
+ speed?: number;
136
+ volume?: number;
137
+ fadeInSeconds?: number;
138
+ fadeOutSeconds?: number;
139
+ }
140
+ export interface StudioFileCreate {
141
+ operationId: string;
142
+ projectId?: string | null;
143
+ name: string;
144
+ sizeBytes: number;
145
+ mimeType: "audio/mpeg" | "audio/wav";
146
+ }
147
+ export interface StudioFileDelete {
148
+ expectedRevision: number;
149
+ }
150
+ export interface StudioFileList {
151
+ items: Array<StudioFileView>;
152
+ nextOffset: number | null;
153
+ }
154
+ export interface StudioFilePatch {
155
+ expectedRevision: number;
156
+ name: string;
157
+ }
158
+ export interface StudioFileView {
159
+ id: string;
160
+ projectId: string | null;
161
+ name: string;
162
+ revision: number;
163
+ status: string;
164
+ frames: number | null;
165
+ sampleRate: number;
166
+ sizeBytes: number | null;
167
+ errorCode: string | null;
168
+ errorReason: string | null;
169
+ errorMessage: string | null;
170
+ references: number;
171
+ }
172
+ export interface StudioImportChapter {
173
+ clientRef?: string | null;
174
+ title: string;
175
+ clips: Array<StudioClipFields>;
176
+ }
177
+ export interface StudioInstanceCreate {
178
+ expectedEditToken: string;
179
+ operationId: string;
180
+ fileId: string;
181
+ position?: StudioPosition;
182
+ trimStart?: number;
183
+ trimEnd: number;
184
+ effects?: StudioEffects;
185
+ length?: number | null;
186
+ }
187
+ export interface StudioInstanceList {
188
+ items: Array<StudioInstanceView>;
189
+ editToken: string;
190
+ }
191
+ export interface StudioInstancePatch {
192
+ expectedEditToken: string;
193
+ operationId: string;
194
+ fileId?: string | null;
195
+ position?: StudioPosition | null;
196
+ trimStart?: number | null;
197
+ trimEnd?: number | null;
198
+ effects?: StudioEffects | null;
199
+ length?: number | null;
200
+ trackId?: string | null;
201
+ }
202
+ export interface StudioInstanceResult {
203
+ instance: StudioInstanceView;
204
+ editToken: string;
205
+ }
206
+ export interface StudioInstanceView {
207
+ id: string;
208
+ fileId: string;
209
+ position: StudioPosition;
210
+ trimStart: number;
211
+ trimEnd: number;
212
+ effects: StudioEffects;
213
+ length?: number | null;
214
+ phase?: number;
215
+ envelopeOffset?: number;
216
+ envelopeLength?: number | null;
217
+ issues?: Array<string>;
218
+ }
219
+ export interface StudioPlayback {
220
+ speed?: number;
221
+ volume?: number;
222
+ }
223
+ export interface StudioPosition {
224
+ mode?: "fixed" | "follow";
225
+ frame?: number;
226
+ clipId?: string | null;
227
+ edge?: "start" | "end";
228
+ offset?: number;
229
+ }
230
+ export interface StudioProjectCreate {
231
+ title?: string;
232
+ description?: string;
233
+ ttsSettings?: StudioTtsSettings | null;
234
+ defaultVoiceId?: string | null;
235
+ defaultInstructions?: string;
236
+ defaultSilenceMs?: number;
237
+ operationId: string;
238
+ }
239
+ export interface StudioProjectImport {
240
+ title?: string;
241
+ description?: string;
242
+ ttsSettings?: StudioTtsSettings | null;
243
+ defaultVoiceId?: string | null;
244
+ defaultInstructions?: string;
245
+ defaultSilenceMs?: number;
246
+ operationId: string;
247
+ chapters: Array<StudioImportChapter>;
248
+ }
249
+ export interface StudioProjectList {
250
+ items: Array<StudioProjectView>;
251
+ total: number;
252
+ page: number;
253
+ pageSize: number;
254
+ }
255
+ export interface StudioProjectPatch {
256
+ expectedEditToken: string;
257
+ operationId: string;
258
+ title?: string | null;
259
+ description?: string | null;
260
+ ttsSettings?: StudioTtsSettings | null;
261
+ defaultVoiceId?: string | null;
262
+ defaultInstructions?: string | null;
263
+ defaultSilenceMs?: number | null;
264
+ }
265
+ export interface StudioProjectResult {
266
+ project: StudioProjectView;
267
+ editToken: string;
268
+ clientRefs?: Record<string, string>;
269
+ createdIds?: Array<string>;
270
+ }
271
+ export interface StudioProjectView {
272
+ title?: string;
273
+ description?: string;
274
+ ttsSettings?: StudioTtsSettings | null;
275
+ defaultVoiceId?: string | null;
276
+ defaultInstructions?: string;
277
+ defaultSilenceMs?: number;
278
+ id: string;
279
+ editToken: string;
280
+ createdAt: string;
281
+ updatedAt: string;
282
+ chapterCount: number;
283
+ clipCount: number;
284
+ }
285
+ export interface StudioReorder {
286
+ expectedEditToken: string;
287
+ operationId: string;
288
+ ids: Array<string>;
289
+ }
290
+ export interface StudioTrackCreate {
291
+ expectedEditToken: string;
292
+ operationId: string;
293
+ name: string;
294
+ chapterId?: string | null;
295
+ volume?: number;
296
+ muted?: boolean;
297
+ }
298
+ export interface StudioTrackList {
299
+ items: Array<StudioTrackView>;
300
+ editToken: string;
301
+ }
302
+ export interface StudioTrackPatch {
303
+ expectedEditToken: string;
304
+ operationId: string;
305
+ name?: string | null;
306
+ chapterId?: string | null;
307
+ volume?: number | null;
308
+ muted?: boolean | null;
309
+ }
310
+ export interface StudioTrackResult {
311
+ track: StudioTrackView;
312
+ editToken: string;
313
+ }
314
+ export interface StudioTrackView {
315
+ id: string;
316
+ name: string;
317
+ chapterId?: string | null;
318
+ volume?: number;
319
+ muted?: boolean;
320
+ readonly?: boolean;
321
+ instances?: Array<StudioInstanceView>;
322
+ }
323
+ export interface StudioTtsSettings {
324
+ model?: string | null;
325
+ language?: string | null;
326
+ generationLanguage?: string | null;
327
+ guidanceScale?: number | null;
328
+ }
329
+ export interface StudioUploadResult {
330
+ uploadUrl: string;
331
+ headers?: Record<string, string>;
332
+ }
333
+ export interface StudioVoiceSummary {
334
+ id: string;
335
+ name: string;
336
+ available: boolean;
337
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,91 @@
1
+ import type { BreezeBlueClient } from "./client.js";
2
+ import type { RequestOptions } from "./types.js";
3
+ import type * as Types from "./studio-types.js";
4
+ export declare function secondsToFrames(seconds: number): number;
5
+ export declare function framesToSeconds(frames: number): number;
6
+ export declare class StudioProjectsResource {
7
+ private client;
8
+ constructor(client: BreezeBlueClient);
9
+ list(params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectList>;
10
+ create(body: Types.StudioProjectCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
11
+ importProject(body: Types.StudioProjectImport, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
12
+ get(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
13
+ update(projectId: string, body: Types.StudioProjectPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
14
+ delete(projectId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioDeleted>;
15
+ }
16
+ export declare class StudioChaptersResource {
17
+ private client;
18
+ constructor(client: BreezeBlueClient);
19
+ list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioChapterList>;
20
+ create(projectId: string, body: Types.StudioChapterCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
21
+ reorder(projectId: string, body: Types.StudioReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
22
+ get(projectId: string, chapterId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioChapterResult>;
23
+ update(projectId: string, chapterId: string, body: Types.StudioChapterPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
24
+ delete(projectId: string, chapterId: string, body: Types.StudioChapterDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
25
+ restore(projectId: string, chapterId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
26
+ }
27
+ export declare class StudioClipsResource {
28
+ private client;
29
+ constructor(client: BreezeBlueClient);
30
+ list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioClipList>;
31
+ create(projectId: string, body: Types.StudioClipCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
32
+ batchCreate(projectId: string, body: Types.StudioClipBatchCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
33
+ batchUpdate(projectId: string, body: Types.StudioClipBatchPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
34
+ bulkDelete(projectId: string, body: Types.StudioClipBulkDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
35
+ reorder(projectId: string, body: Types.StudioClipReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
36
+ move(projectId: string, body: Types.StudioClipMove, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
37
+ get(projectId: string, clipId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioClipResult>;
38
+ update(projectId: string, clipId: string, body: Types.StudioClipPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
39
+ delete(projectId: string, clipId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
40
+ }
41
+ export declare class StudioTracksResource {
42
+ private client;
43
+ constructor(client: BreezeBlueClient);
44
+ list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioTrackList>;
45
+ create(projectId: string, body: Types.StudioTrackCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
46
+ reorder(projectId: string, body: Types.StudioReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
47
+ get(projectId: string, trackId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioTrackResult>;
48
+ update(projectId: string, trackId: string, body: Types.StudioTrackPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
49
+ delete(projectId: string, trackId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
50
+ }
51
+ export declare class StudioInstancesResource {
52
+ private client;
53
+ constructor(client: BreezeBlueClient);
54
+ list(projectId: string, trackId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioInstanceList>;
55
+ create(projectId: string, trackId: string, body: Types.StudioInstanceCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
56
+ get(projectId: string, trackId: string, instanceId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioInstanceResult>;
57
+ update(projectId: string, trackId: string, instanceId: string, body: Types.StudioInstancePatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
58
+ delete(projectId: string, trackId: string, instanceId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
59
+ }
60
+ export declare class StudioFilesResource {
61
+ private client;
62
+ constructor(client: BreezeBlueClient);
63
+ list(params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileList>;
64
+ create(body: Types.StudioFileCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
65
+ get(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
66
+ update(fileId: string, body: Types.StudioFilePatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
67
+ delete(fileId: string, body: Types.StudioFileDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioDeleted>;
68
+ uploadUrl(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioUploadResult>;
69
+ complete(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
70
+ retry(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
71
+ waitReady(fileId: string, options?: {
72
+ timeout?: number;
73
+ pollInterval?: number;
74
+ signal?: AbortSignal;
75
+ }): Promise<Types.StudioFileView>;
76
+ upload(file: Blob, input: {
77
+ operationId: string;
78
+ name: string;
79
+ projectId?: string;
80
+ wait?: boolean;
81
+ }, options?: RequestOptions): Promise<Types.StudioFileView>;
82
+ }
83
+ export declare class StudioResource {
84
+ readonly projects: StudioProjectsResource;
85
+ readonly chapters: StudioChaptersResource;
86
+ readonly clips: StudioClipsResource;
87
+ readonly tracks: StudioTracksResource;
88
+ readonly instances: StudioInstancesResource;
89
+ readonly files: StudioFilesResource;
90
+ constructor(client: BreezeBlueClient);
91
+ }
package/dist/studio.js ADDED
@@ -0,0 +1,213 @@
1
+ export function secondsToFrames(seconds) {
2
+ if (!Number.isFinite(seconds))
3
+ throw new Error("seconds must be finite");
4
+ return Math.sign(seconds) * Math.round(Math.abs(seconds) * 48000);
5
+ }
6
+ export function framesToSeconds(frames) { return frames / 48000; }
7
+ export class StudioProjectsResource {
8
+ client;
9
+ constructor(client) {
10
+ this.client = client;
11
+ }
12
+ list(params, options) {
13
+ return this.client.requestJson("GET", `/v1/studio/projects`, params, undefined, options);
14
+ }
15
+ create(body, params, options) {
16
+ return this.client.requestJson("POST", `/v1/studio/projects`, params, body, options);
17
+ }
18
+ importProject(body, params, options) {
19
+ return this.client.requestJson("POST", `/v1/studio/projects/import`, params, body, options);
20
+ }
21
+ get(projectId, params, options) {
22
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, undefined, options);
23
+ }
24
+ update(projectId, body, params, options) {
25
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, body, options);
26
+ }
27
+ delete(projectId, body, params, options) {
28
+ return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, body, options);
29
+ }
30
+ }
31
+ export class StudioChaptersResource {
32
+ client;
33
+ constructor(client) {
34
+ this.client = client;
35
+ }
36
+ list(projectId, params, options) {
37
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters`, params, undefined, options);
38
+ }
39
+ create(projectId, body, params, options) {
40
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters`, params, body, options);
41
+ }
42
+ reorder(projectId, body, params, options) {
43
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/reorder`, params, body, options);
44
+ }
45
+ get(projectId, chapterId, params, options) {
46
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, undefined, options);
47
+ }
48
+ update(projectId, chapterId, body, params, options) {
49
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, body, options);
50
+ }
51
+ delete(projectId, chapterId, body, params, options) {
52
+ return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, body, options);
53
+ }
54
+ restore(projectId, chapterId, body, params, options) {
55
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}/restore`, params, body, options);
56
+ }
57
+ }
58
+ export class StudioClipsResource {
59
+ client;
60
+ constructor(client) {
61
+ this.client = client;
62
+ }
63
+ list(projectId, params, options) {
64
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips`, params, undefined, options);
65
+ }
66
+ create(projectId, body, params, options) {
67
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips`, params, body, options);
68
+ }
69
+ batchCreate(projectId, body, params, options) {
70
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/batch`, params, body, options);
71
+ }
72
+ batchUpdate(projectId, body, params, options) {
73
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/batch`, params, body, options);
74
+ }
75
+ bulkDelete(projectId, body, params, options) {
76
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/bulk-delete`, params, body, options);
77
+ }
78
+ reorder(projectId, body, params, options) {
79
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/reorder`, params, body, options);
80
+ }
81
+ move(projectId, body, params, options) {
82
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/move`, params, body, options);
83
+ }
84
+ get(projectId, clipId, params, options) {
85
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, undefined, options);
86
+ }
87
+ update(projectId, clipId, body, params, options) {
88
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, body, options);
89
+ }
90
+ delete(projectId, clipId, body, params, options) {
91
+ return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, body, options);
92
+ }
93
+ }
94
+ export class StudioTracksResource {
95
+ client;
96
+ constructor(client) {
97
+ this.client = client;
98
+ }
99
+ list(projectId, params, options) {
100
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks`, params, undefined, options);
101
+ }
102
+ create(projectId, body, params, options) {
103
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks`, params, body, options);
104
+ }
105
+ reorder(projectId, body, params, options) {
106
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/reorder`, params, body, options);
107
+ }
108
+ get(projectId, trackId, params, options) {
109
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, undefined, options);
110
+ }
111
+ update(projectId, trackId, body, params, options) {
112
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, body, options);
113
+ }
114
+ delete(projectId, trackId, body, params, options) {
115
+ return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, body, options);
116
+ }
117
+ }
118
+ export class StudioInstancesResource {
119
+ client;
120
+ constructor(client) {
121
+ this.client = client;
122
+ }
123
+ list(projectId, trackId, params, options) {
124
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances`, params, undefined, options);
125
+ }
126
+ create(projectId, trackId, body, params, options) {
127
+ return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances`, params, body, options);
128
+ }
129
+ get(projectId, trackId, instanceId, params, options) {
130
+ return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, undefined, options);
131
+ }
132
+ update(projectId, trackId, instanceId, body, params, options) {
133
+ return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, body, options);
134
+ }
135
+ delete(projectId, trackId, instanceId, body, params, options) {
136
+ return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, body, options);
137
+ }
138
+ }
139
+ export class StudioFilesResource {
140
+ client;
141
+ constructor(client) {
142
+ this.client = client;
143
+ }
144
+ list(params, options) {
145
+ return this.client.requestJson("GET", `/v1/studio/files`, params, undefined, options);
146
+ }
147
+ create(body, params, options) {
148
+ return this.client.requestJson("POST", `/v1/studio/files`, params, body, options);
149
+ }
150
+ get(fileId, params, options) {
151
+ return this.client.requestJson("GET", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, undefined, options);
152
+ }
153
+ update(fileId, body, params, options) {
154
+ return this.client.requestJson("PATCH", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, body, options);
155
+ }
156
+ delete(fileId, body, params, options) {
157
+ return this.client.requestJson("DELETE", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, body, options);
158
+ }
159
+ uploadUrl(fileId, params, options) {
160
+ return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/upload`, params, undefined, options);
161
+ }
162
+ complete(fileId, params, options) {
163
+ return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/complete`, params, undefined, options);
164
+ }
165
+ retry(fileId, params, options) {
166
+ return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/retry`, params, undefined, options);
167
+ }
168
+ async waitReady(fileId, options = {}) {
169
+ const deadline = Date.now() + (options.timeout ?? 300000);
170
+ while (true) {
171
+ options.signal?.throwIfAborted();
172
+ const value = await this.get(fileId, undefined, { signal: options.signal });
173
+ if (value.status === "ready")
174
+ return value;
175
+ if (value.status === "failed")
176
+ throw new Error(value.errorMessage ?? "Studio file processing failed");
177
+ if (Date.now() >= deadline)
178
+ throw new Error("Studio file is still processing; query the same file ID to resume");
179
+ await new Promise(resolve => setTimeout(resolve, Math.max(100, Math.min(options.pollInterval ?? 1000, deadline - Date.now()))));
180
+ }
181
+ }
182
+ async upload(file, input, options = {}) {
183
+ const mimeType = input.name.toLowerCase().endsWith(".mp3") ? "audio/mpeg" : input.name.toLowerCase().endsWith(".wav") ? "audio/wav" : null;
184
+ if (!mimeType)
185
+ throw new Error("Studio accepts MP3 or WAV files");
186
+ let value = await this.create({ operationId: input.operationId, name: input.name, projectId: input.projectId, sizeBytes: file.size, mimeType }, undefined, options);
187
+ if (value.status === "uploading") {
188
+ const signed = await this.uploadUrl(value.id, undefined, options);
189
+ // Never use the API request helper for a signed storage URL.
190
+ const response = await this.client.fetch(signed.uploadUrl, { method: "PUT", headers: signed.headers, body: file, credentials: "omit", redirect: "error", signal: options.signal });
191
+ if (!response.ok)
192
+ throw new Error(`Studio upload failed: ${response.status}`);
193
+ value = await this.complete(value.id, undefined, options);
194
+ }
195
+ return input.wait === false ? value : this.waitReady(value.id, { signal: options.signal });
196
+ }
197
+ }
198
+ export class StudioResource {
199
+ projects;
200
+ chapters;
201
+ clips;
202
+ tracks;
203
+ instances;
204
+ files;
205
+ constructor(client) {
206
+ this.projects = new StudioProjectsResource(client);
207
+ this.chapters = new StudioChaptersResource(client);
208
+ this.clips = new StudioClipsResource(client);
209
+ this.tracks = new StudioTracksResource(client);
210
+ this.instances = new StudioInstancesResource(client);
211
+ this.files = new StudioFilesResource(client);
212
+ }
213
+ }
package/dist/types.d.ts CHANGED
@@ -401,7 +401,7 @@ export interface UploadFile {
401
401
  contentType?: string;
402
402
  }
403
403
  export interface VoiceClonePreviewRequest {
404
- name: string;
404
+ name?: string | null;
405
405
  file?: UploadData | UploadFile;
406
406
  files?: Array<UploadData | UploadFile>;
407
407
  description?: string;
@@ -454,6 +454,56 @@ export interface VoiceDesignResponse {
454
454
  previews: VoiceDesignPreview[];
455
455
  text: string;
456
456
  }
457
+ export interface VoiceRemixPrepareRequest {
458
+ voiceId: string;
459
+ prompt?: string;
460
+ presetId?: string;
461
+ }
462
+ export interface VoiceRemixPreviewRequest extends VoiceRemixPrepareRequest {
463
+ guidanceScale?: number;
464
+ preparationToken?: string;
465
+ }
466
+ export interface VoiceRemixSource {
467
+ voiceId: string | null;
468
+ name: string | null;
469
+ description: string | null;
470
+ }
471
+ export interface VoiceRemixPreset {
472
+ id: string;
473
+ category: string;
474
+ name: string;
475
+ prompt: string;
476
+ script: string;
477
+ language: string;
478
+ guidanceScale: number;
479
+ previewAudioUrl: string;
480
+ }
481
+ export interface VoiceRemixPresets {
482
+ presets: VoiceRemixPreset[];
483
+ exampleVoiceId: string;
484
+ }
485
+ export interface VoiceRemixPreparation {
486
+ preparationToken: string;
487
+ languageCode: VoiceLanguageCode;
488
+ instruction: string;
489
+ text: string;
490
+ sourceVoice: VoiceRemixSource;
491
+ }
492
+ export interface VoiceRemixJob {
493
+ generationJobId: string;
494
+ status: string;
495
+ }
496
+ export interface VoiceRemixPreviewStatus extends VoiceRemixJob {
497
+ languageCode?: VoiceLanguageCode | null;
498
+ generatedVoiceId?: string | null;
499
+ text?: string | null;
500
+ error?: GenerationJobError | null;
501
+ instruction?: string | null;
502
+ guidanceScale?: number | null;
503
+ sourceVoice?: VoiceRemixSource | null;
504
+ comparisonAudioUrl?: string | null;
505
+ comparisonText?: string | null;
506
+ }
457
507
  export interface VoiceLocalizePreviewRequest {
458
508
  voiceId: string;
459
509
  languageCode: VoiceLanguageCode;
@@ -473,7 +523,7 @@ export interface VoiceLocalizePreviewStatus {
473
523
  }
474
524
  export interface SaveVoiceRequest {
475
525
  generatedVoiceId: string;
476
- voiceName: string;
526
+ voiceName?: string | null;
477
527
  voiceDescription?: string | null;
478
528
  tags?: string[];
479
529
  primaryCategoryCode?: string;
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const SDK_VERSION = "0.18.0";
1
+ export declare const SDK_VERSION = "0.20.0";
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.18.0";
1
+ export const SDK_VERSION = "0.20.0";
2
2
  export const SDK_NAME = "@breeze.blue/sdk";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breeze.blue/sdk",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "ESM-first TypeScript SDK for the Breeze Blue Developer API.",
5
5
  "license": "MIT",
6
6
  "author": "Breeze Blue <support@breezeblue.ai>",