🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@ai-sdk/mistral

Package Overview
Dependencies
Maintainers
3
Versions
372
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ai-sdk/mistral - npm Package Compare versions

Comparing version
4.0.11
to
4.0.12
+16
src/mistral-speech-model-options.ts
import { z } from 'zod/v4';
export type MistralSpeechModelId = 'voxtral-mini-tts-2603' | (string & {});
export const mistralSpeechModelOptions = z.object({
/**
* Base64-encoded reference audio for one-off voice cloning.
*
* When provided, this takes precedence over the standard `voice` option.
*/
refAudio: z.string().min(1).optional(),
});
export type MistralSpeechModelOptions = z.infer<
typeof mistralSpeechModelOptions
>;
import type { SharedV4Warning, SpeechModelV4 } from '@ai-sdk/provider';
import {
combineHeaders,
createJsonResponseHandler,
parseProviderOptions,
postToApi,
serializeModelOptions,
WORKFLOW_DESERIALIZE,
WORKFLOW_SERIALIZE,
type FetchFunction,
} from '@ai-sdk/provider-utils';
import { z } from 'zod/v4';
import { mistralFailedResponseHandler } from './mistral-error';
import {
mistralSpeechModelOptions,
type MistralSpeechModelId,
} from './mistral-speech-model-options';
interface MistralSpeechModelConfig {
provider: string;
baseURL: string;
headers?: () => Record<string, string | undefined>;
fetch?: FetchFunction;
_internal?: {
currentDate?: () => Date;
};
}
type MistralSpeechOutputFormat = 'pcm' | 'wav' | 'mp3' | 'flac' | 'opus';
export class MistralSpeechModel implements SpeechModelV4 {
readonly specificationVersion = 'v4';
static [WORKFLOW_SERIALIZE](model: MistralSpeechModel) {
return serializeModelOptions({
modelId: model.modelId,
config: model.config,
});
}
static [WORKFLOW_DESERIALIZE](options: {
modelId: MistralSpeechModelId;
config: MistralSpeechModelConfig;
}) {
return new MistralSpeechModel(options.modelId, options.config);
}
get provider(): string {
return this.config.provider;
}
constructor(
readonly modelId: MistralSpeechModelId,
private readonly config: MistralSpeechModelConfig,
) {}
private async getArgs({
text,
voice,
outputFormat = 'mp3',
instructions,
speed,
language,
providerOptions,
}: Parameters<SpeechModelV4['doGenerate']>[0]) {
const warnings: SharedV4Warning[] = [];
const mistralOptions = await parseProviderOptions({
provider: 'mistral',
providerOptions,
schema: mistralSpeechModelOptions,
});
let responseFormat: MistralSpeechOutputFormat = 'mp3';
if (['pcm', 'wav', 'mp3', 'flac', 'opus'].includes(outputFormat)) {
responseFormat = outputFormat as MistralSpeechOutputFormat;
} else {
warnings.push({
type: 'unsupported',
feature: 'outputFormat',
details: `Unsupported output format: ${outputFormat}. Using mp3 instead.`,
});
}
if (instructions != null) {
warnings.push({
type: 'unsupported',
feature: 'instructions',
details:
'Mistral speech models do not support the `instructions` option. ' +
'Use a reference audio clip to guide delivery.',
});
}
if (speed != null) {
warnings.push({
type: 'unsupported',
feature: 'speed',
details:
'Mistral speech models do not support the `speed` option. It was ignored.',
});
}
if (language != null) {
warnings.push({
type: 'unsupported',
feature: 'language',
details:
'Mistral speech models do not support the `language` option. ' +
'Language is inferred from the input text and voice.',
});
}
const refAudio = mistralOptions?.refAudio;
const requestBody = {
model: this.modelId,
input: text,
voice_id: refAudio == null ? voice : undefined,
ref_audio: refAudio,
response_format: responseFormat,
stream: false,
};
const requestBodyValues = {
...requestBody,
ref_audio: refAudio == null ? undefined : '[redacted]',
};
return { requestBody, requestBodyValues, warnings };
}
async doGenerate(
options: Parameters<SpeechModelV4['doGenerate']>[0],
): Promise<Awaited<ReturnType<SpeechModelV4['doGenerate']>>> {
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
const { requestBody, requestBodyValues, warnings } =
await this.getArgs(options);
const {
value: response,
responseHeaders,
rawValue: rawResponse,
} = await postToApi({
url: `${this.config.baseURL}/audio/speech`,
headers: combineHeaders(
{ 'Content-Type': 'application/json' },
this.config.headers?.(),
options.headers,
),
body: {
content: JSON.stringify(requestBody),
values: requestBodyValues,
},
failedResponseHandler: mistralFailedResponseHandler,
successfulResponseHandler: createJsonResponseHandler(
mistralSpeechResponseSchema,
),
abortSignal: options.abortSignal,
fetch: this.config.fetch,
});
return {
audio: response.audio_data,
warnings,
request: {
body: JSON.stringify(requestBodyValues),
},
response: {
timestamp: currentDate,
modelId: this.modelId,
headers: responseHeaders,
body: rawResponse,
},
};
}
}
const mistralSpeechResponseSchema = z.object({
audio_data: z.string(),
});
+6
-0
# @ai-sdk/mistral
## 4.0.12
### Patch Changes
- ba433f7: Add non-streaming Voxtral text-to-speech generation with saved voice IDs and one-off reference audio.
## 4.0.11

@@ -4,0 +10,0 @@

+16
-2

@@ -1,2 +0,2 @@

import { ProviderV4, LanguageModelV4, EmbeddingModelV4 } from '@ai-sdk/provider';
import { ProviderV4, LanguageModelV4, EmbeddingModelV4, SpeechModelV4 } from '@ai-sdk/provider';
import { FetchFunction } from '@ai-sdk/provider-utils';

@@ -34,2 +34,8 @@ import { z } from 'zod/v4';

type MistralSpeechModelId = 'voxtral-mini-tts-2603' | (string & {});
declare const mistralSpeechModelOptions: z.ZodObject<{
refAudio: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
type MistralSpeechModelOptions = z.infer<typeof mistralSpeechModelOptions>;
interface MistralProvider extends ProviderV4 {

@@ -54,2 +60,10 @@ (modelId: MistralChatModelId): LanguageModelV4;

/**
* Creates a model for speech generation (text-to-speech).
*/
speech(modelId: MistralSpeechModelId): SpeechModelV4;
/**
* Creates a model for speech generation (text-to-speech).
*/
speechModel(modelId: MistralSpeechModelId): SpeechModelV4;
/**
* @deprecated Use `embedding` instead.

@@ -96,2 +110,2 @@ */

export { type MistralEmbeddingModelOptions, type MistralLanguageModelChatOptions, type MistralLanguageModelChatOptions as MistralLanguageModelOptions, type MistralProvider, type MistralProviderSettings, VERSION, createMistral, mistral };
export { type MistralEmbeddingModelOptions, type MistralLanguageModelChatOptions, type MistralLanguageModelChatOptions as MistralLanguageModelOptions, type MistralProvider, type MistralProviderSettings, type MistralSpeechModelId, type MistralSpeechModelOptions, VERSION, createMistral, mistral };

@@ -941,4 +941,152 @@ // src/mistral-provider.ts

// src/mistral-speech-model.ts
import {
combineHeaders as combineHeaders3,
createJsonResponseHandler as createJsonResponseHandler3,
parseProviderOptions as parseProviderOptions3,
postToApi,
serializeModelOptions as serializeModelOptions3,
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE3,
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE3
} from "@ai-sdk/provider-utils";
import { z as z7 } from "zod/v4";
// src/mistral-speech-model-options.ts
import { z as z6 } from "zod/v4";
var mistralSpeechModelOptions = z6.object({
/**
* Base64-encoded reference audio for one-off voice cloning.
*
* When provided, this takes precedence over the standard `voice` option.
*/
refAudio: z6.string().min(1).optional()
});
// src/mistral-speech-model.ts
var MistralSpeechModel = class _MistralSpeechModel {
constructor(modelId, config) {
this.modelId = modelId;
this.config = config;
this.specificationVersion = "v4";
}
static [WORKFLOW_SERIALIZE3](model) {
return serializeModelOptions3({
modelId: model.modelId,
config: model.config
});
}
static [WORKFLOW_DESERIALIZE3](options) {
return new _MistralSpeechModel(options.modelId, options.config);
}
get provider() {
return this.config.provider;
}
async getArgs({
text,
voice,
outputFormat = "mp3",
instructions,
speed,
language,
providerOptions
}) {
const warnings = [];
const mistralOptions = await parseProviderOptions3({
provider: "mistral",
providerOptions,
schema: mistralSpeechModelOptions
});
let responseFormat = "mp3";
if (["pcm", "wav", "mp3", "flac", "opus"].includes(outputFormat)) {
responseFormat = outputFormat;
} else {
warnings.push({
type: "unsupported",
feature: "outputFormat",
details: `Unsupported output format: ${outputFormat}. Using mp3 instead.`
});
}
if (instructions != null) {
warnings.push({
type: "unsupported",
feature: "instructions",
details: "Mistral speech models do not support the `instructions` option. Use a reference audio clip to guide delivery."
});
}
if (speed != null) {
warnings.push({
type: "unsupported",
feature: "speed",
details: "Mistral speech models do not support the `speed` option. It was ignored."
});
}
if (language != null) {
warnings.push({
type: "unsupported",
feature: "language",
details: "Mistral speech models do not support the `language` option. Language is inferred from the input text and voice."
});
}
const refAudio = mistralOptions == null ? void 0 : mistralOptions.refAudio;
const requestBody = {
model: this.modelId,
input: text,
voice_id: refAudio == null ? voice : void 0,
ref_audio: refAudio,
response_format: responseFormat,
stream: false
};
const requestBodyValues = {
...requestBody,
ref_audio: refAudio == null ? void 0 : "[redacted]"
};
return { requestBody, requestBodyValues, warnings };
}
async doGenerate(options) {
var _a, _b, _c, _d, _e;
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
const { requestBody, requestBodyValues, warnings } = await this.getArgs(options);
const {
value: response,
responseHeaders,
rawValue: rawResponse
} = await postToApi({
url: `${this.config.baseURL}/audio/speech`,
headers: combineHeaders3(
{ "Content-Type": "application/json" },
(_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d),
options.headers
),
body: {
content: JSON.stringify(requestBody),
values: requestBodyValues
},
failedResponseHandler: mistralFailedResponseHandler,
successfulResponseHandler: createJsonResponseHandler3(
mistralSpeechResponseSchema
),
abortSignal: options.abortSignal,
fetch: this.config.fetch
});
return {
audio: response.audio_data,
warnings,
request: {
body: JSON.stringify(requestBodyValues)
},
response: {
timestamp: currentDate,
modelId: this.modelId,
headers: responseHeaders,
body: rawResponse
}
};
}
};
var mistralSpeechResponseSchema = z7.object({
audio_data: z7.string()
});
// src/version.ts
var VERSION = true ? "4.0.11" : "0.0.0-test";
var VERSION = true ? "4.0.12" : "0.0.0-test";

@@ -973,2 +1121,8 @@ // src/mistral-provider.ts

});
const createSpeechModel = (modelId) => new MistralSpeechModel(modelId, {
provider: "mistral.speech",
baseURL,
headers: getHeaders,
fetch: options.fetch
});
const provider = function(modelId) {

@@ -989,2 +1143,4 @@ if (new.target) {

provider.textEmbeddingModel = createEmbeddingModel;
provider.speech = createSpeechModel;
provider.speechModel = createSpeechModel;
provider.imageModel = (modelId) => {

@@ -991,0 +1147,0 @@ throw new NoSuchModelError({ modelId, modelType: "imageModel" });

+1
-1
{
"name": "@ai-sdk/mistral",
"version": "4.0.11",
"version": "4.0.12",
"type": "module",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

# AI SDK - Mistral Provider
The **[Mistral provider](https://ai-sdk.dev/providers/ai-sdk-providers/mistral)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for the Mistral chat API.
The **[Mistral provider](https://ai-sdk.dev/providers/ai-sdk-providers/mistral)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model, embedding model, and speech model support for Mistral APIs.

@@ -5,0 +5,0 @@ > **Deploying to Vercel?** With Vercel's AI Gateway you can access Mistral (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).

@@ -12,2 +12,6 @@ export { createMistral, mistral } from './mistral-provider';

export type { MistralEmbeddingModelOptions } from './mistral-embedding-model-options';
export type {
MistralSpeechModelId,
MistralSpeechModelOptions,
} from './mistral-speech-model-options';
export { VERSION } from './version';

@@ -6,2 +6,3 @@ import {

type ProviderV4,
type SpeechModelV4,
} from '@ai-sdk/provider';

@@ -18,2 +19,4 @@ import {

import type { MistralEmbeddingModelId } from './mistral-embedding-model-options';
import { MistralSpeechModel } from './mistral-speech-model';
import type { MistralSpeechModelId } from './mistral-speech-model-options';
import { VERSION } from './version';

@@ -45,2 +48,12 @@

/**
* Creates a model for speech generation (text-to-speech).
*/
speech(modelId: MistralSpeechModelId): SpeechModelV4;
/**
* Creates a model for speech generation (text-to-speech).
*/
speechModel(modelId: MistralSpeechModelId): SpeechModelV4;
/**
* @deprecated Use `embedding` instead.

@@ -122,2 +135,10 @@ */

const createSpeechModel = (modelId: MistralSpeechModelId) =>
new MistralSpeechModel(modelId, {
provider: 'mistral.speech',
baseURL,
headers: getHeaders,
fetch: options.fetch,
});
const provider = function (modelId: MistralChatModelId) {

@@ -140,2 +161,4 @@ if (new.target) {

provider.textEmbeddingModel = createEmbeddingModel;
provider.speech = createSpeechModel;
provider.speechModel = createSpeechModel;

@@ -142,0 +165,0 @@ provider.imageModel = (modelId: string) => {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet