@ai-sdk/cartesia 3.0.2 → 3.0.4
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 +13 -0
- package/README.md +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.js +327 -10
- package/dist/index.js.map +1 -1
- package/docs/95-cartesia.mdx +58 -1
- package/package.json +2 -2
- package/src/cartesia-config.ts +6 -1
- package/src/cartesia-provider.ts +8 -0
- package/src/cartesia-transcription-model-options.ts +10 -0
- package/src/cartesia-transcription-model.ts +387 -2
- package/src/cartesia-transcription-options.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @ai-sdk/cartesia
|
|
2
2
|
|
|
3
|
+
## 3.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 529a5ef: Add Ink 2 streaming transcription through `TranscriptionModelV4.doStream` and the shared WebSocket transport.
|
|
8
|
+
|
|
9
|
+
## 3.0.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [31c7be8]
|
|
14
|
+
- @ai-sdk/provider-utils@5.0.10
|
|
15
|
+
|
|
3
16
|
## 3.0.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AI SDK - Cartesia Provider
|
|
2
2
|
|
|
3
3
|
The **[Cartesia provider](https://ai-sdk.dev/providers/ai-sdk-providers/cartesia)** for the [AI SDK](https://ai-sdk.dev/docs)
|
|
4
|
-
contains Sonic 3.5 speech generation, Ink-Whisper batch transcription, and Ink 2 realtime transcription support.
|
|
4
|
+
contains Sonic 3.5 speech generation, Ink-Whisper batch transcription, and Ink 2 realtime and streaming transcription support.
|
|
5
5
|
|
|
6
6
|
> **Deploying to Vercel?** With Vercel's AI Gateway you can access Cartesia (and hundreds of models from other providers) — no additional packages, API keys, or extra cost. [Get started with AI Gateway](https://vercel.com/ai-gateway).
|
|
7
7
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as _ai_sdk_provider from '@ai-sdk/provider';
|
|
2
|
-
import { SpeechModelV4, ProviderV4, TranscriptionModelV4, Experimental_RealtimeFactoryV4, Experimental_RealtimeModelV4, Experimental_RealtimeModelV4ClientSecretOptions, Experimental_RealtimeModelV4ClientSecretResult, Experimental_RealtimeModelV4ServerEvent, Experimental_RealtimeModelV4ClientEvent, Experimental_RealtimeModelV4SessionConfig } from '@ai-sdk/provider';
|
|
3
|
-
import { FetchFunction, WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { SpeechModelV4, ProviderV4, TranscriptionModelV4, Experimental_RealtimeFactoryV4, Experimental_TranscriptionModelV4StreamOptions, Experimental_RealtimeModelV4, Experimental_RealtimeModelV4ClientSecretOptions, Experimental_RealtimeModelV4ClientSecretResult, Experimental_RealtimeModelV4ServerEvent, Experimental_RealtimeModelV4ClientEvent, Experimental_RealtimeModelV4SessionConfig } from '@ai-sdk/provider';
|
|
3
|
+
import { FetchFunction, WebSocketConstructor, WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@ai-sdk/provider-utils';
|
|
4
4
|
import { z } from 'zod/v4';
|
|
5
5
|
|
|
6
|
-
type CartesiaTranscriptionModelId = 'ink-whisper' | (string & {});
|
|
6
|
+
type CartesiaTranscriptionModelId = 'ink-whisper' | 'ink-2' | (string & {});
|
|
7
7
|
|
|
8
8
|
type CartesiaConfig = {
|
|
9
9
|
provider: string;
|
|
@@ -13,6 +13,8 @@ type CartesiaConfig = {
|
|
|
13
13
|
}) => string;
|
|
14
14
|
headers?: () => Record<string, string | undefined>;
|
|
15
15
|
fetch?: FetchFunction;
|
|
16
|
+
version?: string;
|
|
17
|
+
webSocket?: WebSocketConstructor;
|
|
16
18
|
generateId?: () => string;
|
|
17
19
|
};
|
|
18
20
|
|
|
@@ -81,6 +83,10 @@ interface CartesiaProviderSettings {
|
|
|
81
83
|
* or to provide a custom fetch implementation for e.g. testing.
|
|
82
84
|
*/
|
|
83
85
|
fetch?: FetchFunction;
|
|
86
|
+
/**
|
|
87
|
+
* Custom WebSocket implementation for streaming transcription.
|
|
88
|
+
*/
|
|
89
|
+
webSocket?: WebSocketConstructor;
|
|
84
90
|
}
|
|
85
91
|
/**
|
|
86
92
|
* Create a Cartesia provider instance.
|
|
@@ -112,6 +118,8 @@ declare class CartesiaTranscriptionModel implements TranscriptionModelV4 {
|
|
|
112
118
|
constructor(modelId: CartesiaTranscriptionModelId, config: CartesiaTranscriptionModelConfig);
|
|
113
119
|
private getArgs;
|
|
114
120
|
doGenerate(options: Parameters<TranscriptionModelV4['doGenerate']>[0]): Promise<Awaited<ReturnType<TranscriptionModelV4['doGenerate']>>>;
|
|
121
|
+
doStream(options: Experimental_TranscriptionModelV4StreamOptions): Promise<Awaited<ReturnType<NonNullable<TranscriptionModelV4['doStream']>>>>;
|
|
122
|
+
private createStreamingAccessToken;
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
type CartesiaRealtimeModelId = 'ink-2' | (string & {});
|
|
@@ -160,10 +168,10 @@ declare const cartesiaSpeechModelOptionsSchema: z.ZodObject<{
|
|
|
160
168
|
mp3: "mp3";
|
|
161
169
|
}>>>;
|
|
162
170
|
encoding: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
163
|
-
pcm_f32le: "pcm_f32le";
|
|
164
171
|
pcm_s16le: "pcm_s16le";
|
|
165
172
|
pcm_mulaw: "pcm_mulaw";
|
|
166
173
|
pcm_alaw: "pcm_alaw";
|
|
174
|
+
pcm_f32le: "pcm_f32le";
|
|
167
175
|
}>>>;
|
|
168
176
|
sampleRate: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<8000>, z.ZodLiteral<16000>, z.ZodLiteral<22050>, z.ZodLiteral<24000>, z.ZodLiteral<44100>, z.ZodLiteral<48000>]>>>;
|
|
169
177
|
bitRate: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<32000>, z.ZodLiteral<64000>, z.ZodLiteral<96000>, z.ZodLiteral<128000>, z.ZodLiteral<192000>]>>>;
|
|
@@ -177,6 +185,9 @@ declare const cartesiaTranscriptionModelOptionsSchema: z.ZodObject<{
|
|
|
177
185
|
timestampGranularities: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodEnum<{
|
|
178
186
|
word: "word";
|
|
179
187
|
}>>>>;
|
|
188
|
+
streaming: z.ZodOptional<z.ZodObject<{
|
|
189
|
+
turnDetection: z.ZodOptional<z.ZodBoolean>;
|
|
190
|
+
}, z.core.$strip>>;
|
|
180
191
|
}, z.core.$strip>;
|
|
181
192
|
type CartesiaTranscriptionModelOptions = z.infer<typeof cartesiaTranscriptionModelOptionsSchema>;
|
|
182
193
|
|
package/dist/index.js
CHANGED
|
@@ -8,14 +8,23 @@ import {
|
|
|
8
8
|
} from "@ai-sdk/provider-utils";
|
|
9
9
|
|
|
10
10
|
// src/cartesia-transcription-model.ts
|
|
11
|
+
import {
|
|
12
|
+
InvalidArgumentError,
|
|
13
|
+
UnsupportedFunctionalityError
|
|
14
|
+
} from "@ai-sdk/provider";
|
|
11
15
|
import {
|
|
12
16
|
combineHeaders,
|
|
17
|
+
connectToWebSocket,
|
|
13
18
|
convertBase64ToUint8Array,
|
|
14
19
|
createJsonResponseHandler,
|
|
15
20
|
mediaTypeToExtension,
|
|
16
21
|
parseProviderOptions,
|
|
17
22
|
postFormDataToApi,
|
|
23
|
+
postJsonToApi,
|
|
24
|
+
safeParseJSON,
|
|
18
25
|
serializeModelOptions,
|
|
26
|
+
toWebSocketUrl,
|
|
27
|
+
waitForWebSocketBufferDrain,
|
|
19
28
|
WORKFLOW_SERIALIZE,
|
|
20
29
|
WORKFLOW_DESERIALIZE
|
|
21
30
|
} from "@ai-sdk/provider-utils";
|
|
@@ -42,7 +51,15 @@ var cartesiaTranscriptionModelOptionsSchema = z2.object({
|
|
|
42
51
|
/** The language of the audio (ISO 639-1 code). Defaults to English. */
|
|
43
52
|
language: z2.string().nullish(),
|
|
44
53
|
/** The timestamp granularities to populate. Currently only `word` is supported. */
|
|
45
|
-
timestampGranularities: z2.array(z2.enum(["word"])).nullish()
|
|
54
|
+
timestampGranularities: z2.array(z2.enum(["word"])).nullish(),
|
|
55
|
+
/** Options for realtime Ink 2 transcription over WebSocket. */
|
|
56
|
+
streaming: z2.object({
|
|
57
|
+
/**
|
|
58
|
+
* Use Cartesia's native turn detection endpoint. Defaults to true.
|
|
59
|
+
* Disable this to finalize the transcript only when the audio stream ends.
|
|
60
|
+
*/
|
|
61
|
+
turnDetection: z2.boolean().optional()
|
|
62
|
+
}).optional()
|
|
46
63
|
});
|
|
47
64
|
|
|
48
65
|
// src/cartesia-transcription-model.ts
|
|
@@ -75,6 +92,13 @@ var CartesiaTranscriptionModel = class _CartesiaTranscriptionModel {
|
|
|
75
92
|
providerOptions,
|
|
76
93
|
schema: cartesiaTranscriptionModelOptionsSchema
|
|
77
94
|
});
|
|
95
|
+
if ((cartesiaOptions == null ? void 0 : cartesiaOptions.streaming) != null) {
|
|
96
|
+
warnings.push({
|
|
97
|
+
type: "unsupported",
|
|
98
|
+
feature: "providerOptions.cartesia.streaming",
|
|
99
|
+
details: "Cartesia batch transcription does not support streaming options."
|
|
100
|
+
});
|
|
101
|
+
}
|
|
78
102
|
const formData = new FormData();
|
|
79
103
|
const blob = audio instanceof Uint8Array ? new Blob([audio]) : new Blob([convertBase64ToUint8Array(audio)]);
|
|
80
104
|
const fileExtension = mediaTypeToExtension(mediaType);
|
|
@@ -101,6 +125,11 @@ var CartesiaTranscriptionModel = class _CartesiaTranscriptionModel {
|
|
|
101
125
|
}
|
|
102
126
|
async doGenerate(options) {
|
|
103
127
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
128
|
+
if (isStreamingTranscriptionModelId(this.modelId)) {
|
|
129
|
+
throw new UnsupportedFunctionalityError({
|
|
130
|
+
functionality: `non-streaming transcription with ${this.modelId}`
|
|
131
|
+
});
|
|
132
|
+
}
|
|
104
133
|
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
105
134
|
const { formData, warnings } = await this.getArgs(options);
|
|
106
135
|
const {
|
|
@@ -139,7 +168,287 @@ var CartesiaTranscriptionModel = class _CartesiaTranscriptionModel {
|
|
|
139
168
|
}
|
|
140
169
|
};
|
|
141
170
|
}
|
|
171
|
+
async doStream(options) {
|
|
172
|
+
var _a, _b, _c, _d, _e, _f;
|
|
173
|
+
if (!isStreamingTranscriptionModelId(this.modelId)) {
|
|
174
|
+
throw new UnsupportedFunctionalityError({
|
|
175
|
+
functionality: `streaming transcription with ${this.modelId}`
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
179
|
+
const warnings = [];
|
|
180
|
+
const cartesiaOptions = await parseProviderOptions({
|
|
181
|
+
provider: "cartesia",
|
|
182
|
+
providerOptions: options.providerOptions,
|
|
183
|
+
schema: cartesiaTranscriptionModelOptionsSchema
|
|
184
|
+
});
|
|
185
|
+
if ((cartesiaOptions == null ? void 0 : cartesiaOptions.language) != null && cartesiaOptions.language !== "en") {
|
|
186
|
+
throw new InvalidArgumentError({
|
|
187
|
+
argument: "providerOptions",
|
|
188
|
+
message: "Cartesia Ink 2 currently supports English only."
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
if ((cartesiaOptions == null ? void 0 : cartesiaOptions.timestampGranularities) != null) {
|
|
192
|
+
warnings.push({
|
|
193
|
+
type: "unsupported",
|
|
194
|
+
feature: "providerOptions.cartesia.timestampGranularities",
|
|
195
|
+
details: "Cartesia streaming transcription does not support timestamp granularities."
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const token = await this.createStreamingAccessToken(options);
|
|
199
|
+
const useTurnDetection = ((_d = cartesiaOptions == null ? void 0 : cartesiaOptions.streaming) == null ? void 0 : _d.turnDetection) !== false;
|
|
200
|
+
const url = buildCartesiaStreamingTranscriptionUrl({
|
|
201
|
+
baseURL: this.config.url({ path: "/", modelId: this.modelId }),
|
|
202
|
+
version: (_e = this.config.version) != null ? _e : "2026-03-01",
|
|
203
|
+
modelId: this.modelId,
|
|
204
|
+
inputAudioFormat: options.inputAudioFormat,
|
|
205
|
+
providerOptions: cartesiaOptions,
|
|
206
|
+
token,
|
|
207
|
+
useTurnDetection
|
|
208
|
+
});
|
|
209
|
+
const requestUrl = new URL(url);
|
|
210
|
+
requestUrl.searchParams.delete("access_token");
|
|
211
|
+
return {
|
|
212
|
+
request: { body: requestUrl.toString() },
|
|
213
|
+
response: {
|
|
214
|
+
timestamp: currentDate,
|
|
215
|
+
modelId: this.modelId
|
|
216
|
+
},
|
|
217
|
+
stream: createCartesiaStreamingTranscriptionStream({
|
|
218
|
+
webSocket: this.config.webSocket,
|
|
219
|
+
url,
|
|
220
|
+
warnings,
|
|
221
|
+
language: (_f = cartesiaOptions == null ? void 0 : cartesiaOptions.language) != null ? _f : "en",
|
|
222
|
+
useTurnDetection,
|
|
223
|
+
audio: options.audio,
|
|
224
|
+
abortSignal: options.abortSignal,
|
|
225
|
+
includeRawChunks: options.includeRawChunks
|
|
226
|
+
})
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
async createStreamingAccessToken(options) {
|
|
230
|
+
var _a, _b;
|
|
231
|
+
const { value } = await postJsonToApi({
|
|
232
|
+
url: this.config.url({ path: "/access-token", modelId: this.modelId }),
|
|
233
|
+
headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
|
|
234
|
+
body: { grants: { stt: true } },
|
|
235
|
+
failedResponseHandler: cartesiaFailedResponseHandler,
|
|
236
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
237
|
+
cartesiaAccessTokenResponseSchema
|
|
238
|
+
),
|
|
239
|
+
abortSignal: options.abortSignal,
|
|
240
|
+
fetch: this.config.fetch
|
|
241
|
+
});
|
|
242
|
+
return value.token;
|
|
243
|
+
}
|
|
142
244
|
};
|
|
245
|
+
function createCartesiaStreamingTranscriptionStream({
|
|
246
|
+
webSocket,
|
|
247
|
+
url,
|
|
248
|
+
warnings,
|
|
249
|
+
language,
|
|
250
|
+
useTurnDetection,
|
|
251
|
+
audio,
|
|
252
|
+
abortSignal,
|
|
253
|
+
includeRawChunks
|
|
254
|
+
}) {
|
|
255
|
+
let finished = false;
|
|
256
|
+
let cleanup = () => {
|
|
257
|
+
};
|
|
258
|
+
return new ReadableStream({
|
|
259
|
+
start: (controller) => {
|
|
260
|
+
const finalTexts = [];
|
|
261
|
+
let durationInSeconds = 0;
|
|
262
|
+
let audioReader;
|
|
263
|
+
let connection;
|
|
264
|
+
cleanup = (closeCode) => {
|
|
265
|
+
if (audioReader != null) {
|
|
266
|
+
void audioReader.cancel().catch(() => {
|
|
267
|
+
});
|
|
268
|
+
} else {
|
|
269
|
+
void audio.cancel().catch(() => {
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
connection == null ? void 0 : connection.close(closeCode);
|
|
273
|
+
};
|
|
274
|
+
const finishWithError = (error) => {
|
|
275
|
+
if (finished) return;
|
|
276
|
+
finished = true;
|
|
277
|
+
cleanup();
|
|
278
|
+
controller.error(error);
|
|
279
|
+
};
|
|
280
|
+
const finish = () => {
|
|
281
|
+
if (finished) return;
|
|
282
|
+
finished = true;
|
|
283
|
+
controller.enqueue({
|
|
284
|
+
type: "finish",
|
|
285
|
+
text: finalTexts.join(useTurnDetection ? " " : ""),
|
|
286
|
+
segments: [],
|
|
287
|
+
language,
|
|
288
|
+
...durationInSeconds > 0 ? { durationInSeconds } : {}
|
|
289
|
+
});
|
|
290
|
+
controller.close();
|
|
291
|
+
cleanup(1e3);
|
|
292
|
+
};
|
|
293
|
+
const sendAudio = async (socket) => {
|
|
294
|
+
audioReader = audio.getReader();
|
|
295
|
+
try {
|
|
296
|
+
while (true) {
|
|
297
|
+
const { done, value } = await audioReader.read();
|
|
298
|
+
if (done || finished) break;
|
|
299
|
+
socket.send(
|
|
300
|
+
value instanceof Uint8Array ? value : convertBase64ToUint8Array(value)
|
|
301
|
+
);
|
|
302
|
+
await waitForWebSocketBufferDrain(socket);
|
|
303
|
+
}
|
|
304
|
+
} finally {
|
|
305
|
+
audioReader.releaseLock();
|
|
306
|
+
audioReader = void 0;
|
|
307
|
+
}
|
|
308
|
+
if (!finished) {
|
|
309
|
+
socket.send(
|
|
310
|
+
useTurnDetection ? JSON.stringify({ type: "close" }) : "finalize"
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
connection = connectToWebSocket({
|
|
315
|
+
url,
|
|
316
|
+
webSocket,
|
|
317
|
+
abortSignal,
|
|
318
|
+
onAbort: finishWithError,
|
|
319
|
+
onProcessingError: finishWithError,
|
|
320
|
+
onOpen: (socket) => {
|
|
321
|
+
controller.enqueue({ type: "stream-start", warnings });
|
|
322
|
+
void sendAudio(socket).catch(finishWithError);
|
|
323
|
+
},
|
|
324
|
+
onMessageText: async (text) => {
|
|
325
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
326
|
+
const parsed = await safeParseJSON({ text });
|
|
327
|
+
if (!parsed.success) return;
|
|
328
|
+
const raw = parsed.value;
|
|
329
|
+
if (includeRawChunks) {
|
|
330
|
+
controller.enqueue({ type: "raw", rawValue: raw });
|
|
331
|
+
}
|
|
332
|
+
switch (raw.type) {
|
|
333
|
+
case "turn.update":
|
|
334
|
+
case "turn.eager_end": {
|
|
335
|
+
controller.enqueue({
|
|
336
|
+
type: "transcript-partial",
|
|
337
|
+
id: raw.request_id,
|
|
338
|
+
text: (_a = raw.transcript) != null ? _a : ""
|
|
339
|
+
});
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case "turn.end": {
|
|
343
|
+
const text2 = (_b = raw.transcript) != null ? _b : "";
|
|
344
|
+
finalTexts.push(text2);
|
|
345
|
+
controller.enqueue({
|
|
346
|
+
type: "transcript-final",
|
|
347
|
+
id: raw.request_id,
|
|
348
|
+
text: text2
|
|
349
|
+
});
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
case "transcript": {
|
|
353
|
+
const transcript = (_c = raw.text) != null ? _c : "";
|
|
354
|
+
if (raw.is_final === true) {
|
|
355
|
+
finalTexts.push(transcript);
|
|
356
|
+
durationInSeconds += (_d = raw.duration) != null ? _d : 0;
|
|
357
|
+
controller.enqueue({
|
|
358
|
+
type: "transcript-final",
|
|
359
|
+
id: raw.request_id,
|
|
360
|
+
text: transcript
|
|
361
|
+
});
|
|
362
|
+
} else {
|
|
363
|
+
controller.enqueue({
|
|
364
|
+
type: "transcript-partial",
|
|
365
|
+
id: raw.request_id,
|
|
366
|
+
text: transcript,
|
|
367
|
+
...raw.duration != null ? { durationInSeconds: raw.duration } : {}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
case "flush_done": {
|
|
373
|
+
(_e = connection == null ? void 0 : connection.socket) == null ? void 0 : _e.send("close");
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case "done": {
|
|
377
|
+
finish();
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
case "error": {
|
|
381
|
+
finishWithError(
|
|
382
|
+
new Error(
|
|
383
|
+
(_g = (_f = raw.message) != null ? _f : raw.error_code) != null ? _g : "Cartesia streaming transcription error"
|
|
384
|
+
)
|
|
385
|
+
);
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
onSocketError: () => {
|
|
391
|
+
finishWithError(new Error("Cartesia streaming transcription error"));
|
|
392
|
+
},
|
|
393
|
+
onClose: () => {
|
|
394
|
+
if (!finished) finish();
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
},
|
|
398
|
+
cancel: () => {
|
|
399
|
+
if (finished) return;
|
|
400
|
+
finished = true;
|
|
401
|
+
cleanup();
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
function buildCartesiaStreamingTranscriptionUrl({
|
|
406
|
+
baseURL,
|
|
407
|
+
version,
|
|
408
|
+
modelId,
|
|
409
|
+
inputAudioFormat,
|
|
410
|
+
providerOptions,
|
|
411
|
+
token,
|
|
412
|
+
useTurnDetection
|
|
413
|
+
}) {
|
|
414
|
+
var _a;
|
|
415
|
+
const url = toWebSocketUrl(
|
|
416
|
+
new URL(
|
|
417
|
+
useTurnDetection ? "/stt/turns/websocket" : "/stt/websocket",
|
|
418
|
+
baseURL
|
|
419
|
+
)
|
|
420
|
+
);
|
|
421
|
+
url.searchParams.set("model", modelId);
|
|
422
|
+
url.searchParams.set(
|
|
423
|
+
"encoding",
|
|
424
|
+
cartesiaEncodingFromInputAudioFormat(inputAudioFormat.type)
|
|
425
|
+
);
|
|
426
|
+
url.searchParams.set("sample_rate", String((_a = inputAudioFormat.rate) != null ? _a : 24e3));
|
|
427
|
+
url.searchParams.set("cartesia_version", version);
|
|
428
|
+
url.searchParams.set("access_token", token);
|
|
429
|
+
if (!useTurnDetection && (providerOptions == null ? void 0 : providerOptions.language) != null) {
|
|
430
|
+
url.searchParams.set("language", providerOptions.language);
|
|
431
|
+
}
|
|
432
|
+
return url;
|
|
433
|
+
}
|
|
434
|
+
function cartesiaEncodingFromInputAudioFormat(type) {
|
|
435
|
+
switch (type) {
|
|
436
|
+
case "audio/pcm":
|
|
437
|
+
return "pcm_s16le";
|
|
438
|
+
case "audio/pcmu":
|
|
439
|
+
return "pcm_mulaw";
|
|
440
|
+
case "audio/pcma":
|
|
441
|
+
return "pcm_alaw";
|
|
442
|
+
default:
|
|
443
|
+
throw new InvalidArgumentError({
|
|
444
|
+
argument: "inputAudioFormat",
|
|
445
|
+
message: `Unsupported Cartesia streaming audio format: ${type}`
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
function isStreamingTranscriptionModelId(modelId) {
|
|
450
|
+
return modelId === "ink-2" || modelId.startsWith("ink-2-");
|
|
451
|
+
}
|
|
143
452
|
var cartesiaTranscriptionResponseSchema = z3.object({
|
|
144
453
|
text: z3.string(),
|
|
145
454
|
language: z3.string().nullish(),
|
|
@@ -152,13 +461,16 @@ var cartesiaTranscriptionResponseSchema = z3.object({
|
|
|
152
461
|
})
|
|
153
462
|
).nullish()
|
|
154
463
|
});
|
|
464
|
+
var cartesiaAccessTokenResponseSchema = z3.object({
|
|
465
|
+
token: z3.string().min(1)
|
|
466
|
+
});
|
|
155
467
|
|
|
156
468
|
// src/cartesia-speech-model.ts
|
|
157
469
|
import {
|
|
158
470
|
combineHeaders as combineHeaders2,
|
|
159
471
|
createBinaryResponseHandler,
|
|
160
472
|
parseProviderOptions as parseProviderOptions2,
|
|
161
|
-
postJsonToApi,
|
|
473
|
+
postJsonToApi as postJsonToApi2,
|
|
162
474
|
serializeModelOptions as serializeModelOptions2,
|
|
163
475
|
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE2,
|
|
164
476
|
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE2
|
|
@@ -359,7 +671,7 @@ var CartesiaSpeechModel = class _CartesiaSpeechModel {
|
|
|
359
671
|
value: audio,
|
|
360
672
|
responseHeaders,
|
|
361
673
|
rawValue: rawResponse
|
|
362
|
-
} = await
|
|
674
|
+
} = await postJsonToApi2({
|
|
363
675
|
url: this.config.url({
|
|
364
676
|
path: "/tts/bytes",
|
|
365
677
|
modelId: this.modelId
|
|
@@ -617,7 +929,7 @@ function resolveCartesiaEncoding(type) {
|
|
|
617
929
|
}
|
|
618
930
|
|
|
619
931
|
// src/version.ts
|
|
620
|
-
var VERSION = true ? "3.0.
|
|
932
|
+
var VERSION = true ? "3.0.4" : "0.0.0-test";
|
|
621
933
|
|
|
622
934
|
// src/cartesia-provider.ts
|
|
623
935
|
var CARTESIA_API_VERSION = "2026-03-01";
|
|
@@ -637,12 +949,17 @@ function createCartesia(options = {}) {
|
|
|
637
949
|
`ai-sdk/cartesia/${VERSION}`
|
|
638
950
|
);
|
|
639
951
|
};
|
|
640
|
-
const createTranscriptionModel = (modelId) =>
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
952
|
+
const createTranscriptionModel = (modelId) => {
|
|
953
|
+
var _a;
|
|
954
|
+
return new CartesiaTranscriptionModel(modelId, {
|
|
955
|
+
provider: `cartesia.transcription`,
|
|
956
|
+
url: ({ path }) => `https://api.cartesia.ai${path}`,
|
|
957
|
+
headers: getHeaders,
|
|
958
|
+
fetch: options.fetch,
|
|
959
|
+
version: (_a = options.version) != null ? _a : CARTESIA_API_VERSION,
|
|
960
|
+
webSocket: options.webSocket
|
|
961
|
+
});
|
|
962
|
+
};
|
|
646
963
|
const createSpeechModel = (modelId) => new CartesiaSpeechModel(modelId, {
|
|
647
964
|
provider: `cartesia.speech`,
|
|
648
965
|
url: ({ path }) => `https://api.cartesia.ai${path}`,
|