UNPKG

sarvam-ai-sdk

Version:

Sarvam AI Provider support for AI-SDK

1,540 lines (1,513 loc) 51.1 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { createSarvam: () => createSarvam, sarvam: () => sarvam }); module.exports = __toCommonJS(index_exports); // src/sarvam-provider.ts var import_provider_utils11 = require("@ai-sdk/provider-utils"); // src/sarvam-chat-language-model.ts var import_provider3 = require("@ai-sdk/provider"); var import_provider_utils4 = require("@ai-sdk/provider-utils"); var import_zod2 = require("zod"); // src/convert-to-sarvam-chat-messages.ts var import_provider = require("@ai-sdk/provider"); var import_provider_utils = require("@ai-sdk/provider-utils"); function convertToSarvamChatMessages(prompt, fakeToolSystemPrompt) { const messages = []; for (const { role, content } of prompt) { switch (role) { case "system": { const contentData = fakeToolSystemPrompt ? `${content} ${fakeToolSystemPrompt}` : content; messages.push({ role: "system", content: contentData }); break; } case "user": { if (content.length === 1 && content[0].type === "text") { messages.push({ role: "user", content: content[0].text }); break; } messages.push({ role: "user", content: content.map((part) => { var _a; switch (part.type) { case "text": { return { type: "text", text: part.text }; } case "image": { return { type: "image_url", image_url: { url: part.image instanceof URL ? part.image.toString() : `data:${(_a = part.mimeType) != null ? _a : "image/jpeg"};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(part.image)}` } }; } case "file": { throw new import_provider.UnsupportedFunctionalityError({ functionality: "File content parts in user messages" }); } } }) }); break; } case "assistant": { let text = ""; const toolCalls = []; for (const part of content) { switch (part.type) { case "text": { text += part.text; break; } case "tool-call": { toolCalls.push({ id: part.toolCallId, type: "function", function: { name: part.toolName, arguments: JSON.stringify(part.args) } }); break; } } } messages.push({ role: "assistant", content: text, tool_calls: toolCalls.length > 0 ? toolCalls : void 0 }); break; } case "tool": { for (const toolResponse of content) { messages.push({ role: "tool", tool_call_id: toolResponse.toolCallId, content: JSON.stringify(toolResponse.result) }); } break; } default: { const _exhaustiveCheck = role; throw new Error(`Unsupported role: ${_exhaustiveCheck}`); } } } return messages; } // src/get-response-metadata.ts function getResponseMetadata({ id, model, created }) { return { id: id != null ? id : void 0, modelId: model != null ? model : void 0, timestamp: created != null ? new Date(created * 1e3) : void 0 }; } // src/map-sarvam-finish-reason.ts function mapSarvamFinishReason(finishReason) { switch (finishReason) { case "stop": return "stop"; case "length": return "length"; case "content_filter": return "content-filter"; case "function_call": case "tool_calls": return "tool-calls"; default: return "unknown"; } } // src/sarvam-error.ts var import_zod = require("zod"); var import_provider_utils2 = require("@ai-sdk/provider-utils"); var sarvamErrorDataSchema = import_zod.z.object({ error: import_zod.z.object({ message: import_zod.z.string(), type: import_zod.z.string() }) }); var sarvamFailedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)({ errorSchema: sarvamErrorDataSchema, errorToMessage: (data) => data.error.message }); // src/sarvam-prepare-tools.ts var import_provider2 = require("@ai-sdk/provider"); var import_provider_utils3 = require("@ai-sdk/provider-utils"); var import_json_schema_to_typescript = require("json-schema-to-typescript"); function prepareTools({ mode }) { var _a; const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0; const toolWarnings = []; if (tools == null) { return { tools: void 0, tool_choice: void 0, toolWarnings }; } const toolChoice = mode.toolChoice; const sarvamTools = []; for (const tool of tools) { if (tool.type === "provider-defined") { toolWarnings.push({ type: "unsupported-tool", tool }); } else { sarvamTools.push({ type: "function", function: { name: tool.name, description: tool.description, parameters: tool.parameters } }); } } if (toolChoice == null) { return { tools: sarvamTools, tool_choice: void 0, toolWarnings }; } const type = toolChoice.type; switch (type) { case "auto": case "none": case "required": return { tools: sarvamTools, tool_choice: type, toolWarnings }; case "tool": return { tools: sarvamTools, tool_choice: { type: "function", function: { name: toolChoice.toolName } }, toolWarnings }; default: { const _exhaustiveCheck = type; throw new import_provider2.UnsupportedFunctionalityError({ functionality: `Unsupported tool choice type: ${_exhaustiveCheck}` }); } } } var simulateToolCalling = async (tools) => { const context = []; const names = []; for (const tool of tools) { names.push(tool.function.name); const tsType = await (0, import_json_schema_to_typescript.compile)( tool.function.parameters, tool.function.name, { bannerComment: "", format: false, declareExternallyReferenced: true, enableConstEnums: true, unreachableDefinitions: false, strictIndexSignatures: false } ); const toolContext = tsType.replace( /export interface (\w+) \{/, (_, name) => `type ${tool.function.name} = {` ).replace(/\/\*\*\s*\n\s*\*\s*(.*?)\s*\n\s*\*\//, "// $1"); context.push(`// ${tool.function.description} ${toolContext}`); } const text = `These are the available tool you can execute. ${context.join("\n")} type YourToolChoices = { 'toolName': '${names.join("' | '")}', 'toolData': ${names.join(" | ")} } Respond normally. If user request to execute any tool, respond with pure JSON format Make sure to translate toolData to English. eg: const myChoice: YourToolChoices = { "toolName": <name>, "toolData": <data> }`; return text; }; var extractToolCallData = (jsonObject) => { const toolFunction = jsonObject; if (!("toolName" in toolFunction)) return; if (!("toolData" in toolFunction)) return; return { args: JSON.stringify(toolFunction.toolData), toolCallId: (0, import_provider_utils3.generateId)(), toolCallType: "function", toolName: toolFunction.toolName }; }; var parseJSON = (text) => { const jsonRegex = /\{(?:[^{}]*|\{[^{}]*\})*\}/g; const jsonMatches = text.match(jsonRegex); if (jsonMatches && jsonMatches[0]) { try { const jsonObject = JSON.parse(jsonMatches[0]); return jsonObject; } catch (error) { } } }; var simulateJsonSchema = () => "If user doen't specify, make sure to translate json data content into pure English."; // src/sarvam-chat-language-model.ts var SarvamChatLanguageModel = class { constructor(modelId, settings, config) { this.specificationVersion = "v1"; this.supportsStructuredOutputs = false; this.defaultObjectGenerationMode = "json"; this.modelId = modelId; this.settings = settings; this.config = config; } get provider() { return this.config.provider; } get supportsImageUrls() { return !this.settings.downloadImages; } async getArgs({ mode, prompt, maxTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, stopSequences, responseFormat, seed, stream, providerMetadata }) { const type = mode.type; const simulate = this.settings.simulate; if (type === "object-json" && simulate === "tool-calling") throw new Error('Use { simulate: "json-object" } with generateObject()'); if (type === "regular" && simulate === "json-object") throw new Error('Use { simulate: "tool-calling" } with generateText()'); const warnings = []; if (stream) { warnings.push({ type: "other", message: "Streaming is still experimental for Sarvam" }); } if (topK != null) { warnings.push({ type: "unsupported-setting", setting: "topK" }); } if (responseFormat != null && responseFormat.type === "json" && responseFormat.schema != null) { warnings.push({ type: "unsupported-setting", setting: "responseFormat", details: "JSON response format schema is not supported" }); } const sarvamOptions = (0, import_provider_utils4.parseProviderOptions)({ provider: "sarvam", providerOptions: providerMetadata, schema: import_zod2.z.object({ reasoningFormat: import_zod2.z.enum(["parsed", "raw", "hidden"]).nullish() }) }); const baseArgs = (prompt2, extraSystemPrompt) => ({ // model id: model: this.modelId, // model specific settings: user: this.settings.user, parallel_tool_calls: this.settings.parallelToolCalls, // standardized settings: max_tokens: maxTokens, temperature, top_p: topP, frequency_penalty: frequencyPenalty, presence_penalty: presencePenalty, stop: stopSequences, seed, // response format: response_format: ( // json object response format is not supported for streaming: stream === false && (responseFormat == null ? void 0 : responseFormat.type) === "json" ? { type: "json_object" } : void 0 ), // provider options: reasoning_format: sarvamOptions == null ? void 0 : sarvamOptions.reasoningFormat, // messages: messages: convertToSarvamChatMessages(prompt2, extraSystemPrompt) }); switch (type) { case "regular": { const { tools, tool_choice, toolWarnings } = prepareTools({ mode }); const extraSystemPrompt = tools && simulate === "tool-calling" ? await simulateToolCalling(tools) : void 0; return { args: { ...baseArgs(prompt, extraSystemPrompt), tools, tool_choice }, warnings: [...warnings, ...toolWarnings] }; } case "object-json": { const extraSystemPrompt = simulate === "json-object" ? simulateJsonSchema() : void 0; return { args: { ...baseArgs(prompt, extraSystemPrompt), response_format: ( // json object response format is not supported for streaming: stream === false ? { type: "json_object" } : void 0 ) }, warnings }; } case "object-tool": { return { args: { ...baseArgs(prompt), tool_choice: { type: "function", function: { name: mode.tool.name } }, tools: [ { type: "function", function: { name: mode.tool.name, description: mode.tool.description, parameters: mode.tool.parameters } } ] }, warnings }; } default: { const _exhaustiveCheck = type; throw new Error(`Unsupported type: ${_exhaustiveCheck}`); } } } async doGenerate(options) { var _a, _b, _c, _d, _e, _f, _g; const { args, warnings } = await this.getArgs({ ...options, stream: false }); const body = JSON.stringify(args); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils4.postJsonToApi)({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: (0, import_provider_utils4.combineHeaders)(this.config.headers(), options.headers), body: args, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)( sarvamChatResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const { messages: rawPrompt, ...rawSettings } = args; const choice = response.choices[0]; let text = (_a = choice.message.content) != null ? _a : void 0; let toolCalls = (_b = choice.message.tool_calls) == null ? void 0 : _b.map((toolCall) => { var _a2; return { toolCallType: "function", toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils4.generateId)(), toolName: toolCall.function.name, args: toolCall.function.arguments }; }); if (this.settings.simulate === "tool-calling") { if (text && text.length !== 0) { const jsonObject = parseJSON(text); if (jsonObject) { const newTools = extractToolCallData(jsonObject); if (newTools) { toolCalls = [newTools]; text = void 0; } } } } if (this.settings.simulate === "json-object") { if (text && text.length !== 0) { const jsonObject = parseJSON(text); if (jsonObject) { const newTools = extractToolCallData(jsonObject); text = JSON.stringify(jsonObject); } } } return { text, toolCalls, reasoning: (_c = choice.message.reasoning) != null ? _c : void 0, finishReason: mapSarvamFinishReason(choice.finish_reason), usage: { promptTokens: (_e = (_d = response.usage) == null ? void 0 : _d.prompt_tokens) != null ? _e : NaN, completionTokens: (_g = (_f = response.usage) == null ? void 0 : _f.completion_tokens) != null ? _g : NaN }, rawCall: { rawPrompt, rawSettings }, rawResponse: { headers: responseHeaders, body: rawResponse }, response: getResponseMetadata(response), warnings, request: { body } }; } async doStream(options) { const { args, warnings } = await this.getArgs({ ...options, stream: true }); const body = JSON.stringify({ ...args, stream: true }); const { responseHeaders, value: response } = await (0, import_provider_utils4.postJsonToApi)({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: (0, import_provider_utils4.combineHeaders)(this.config.headers(), options.headers), body: { ...args, stream: true }, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils4.createEventSourceResponseHandler)( sarvamChatChunkSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const { messages: rawPrompt, ...rawSettings } = args; const toolCalls = []; let finishReason = "unknown"; let usage = { promptTokens: void 0, completionTokens: void 0 }; let isFirstChunk = true; let providerMetadata; return { stream: response.pipeThrough( new TransformStream({ transform(chunk, controller) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o; if (!chunk.success) { finishReason = "error"; controller.enqueue({ type: "error", error: chunk.error }); return; } const value = chunk.value; if ("error" in value) { finishReason = "error"; controller.enqueue({ type: "error", error: value.error }); return; } if (isFirstChunk) { isFirstChunk = false; controller.enqueue({ type: "response-metadata", ...getResponseMetadata(value) }); } if (((_a = value.x_sarvam) == null ? void 0 : _a.usage) != null) { usage = { promptTokens: (_b = value.x_sarvam.usage.prompt_tokens) != null ? _b : void 0, completionTokens: (_c = value.x_sarvam.usage.completion_tokens) != null ? _c : void 0 }; } const choice = value.choices[0]; if ((choice == null ? void 0 : choice.finish_reason) != null) { finishReason = mapSarvamFinishReason(choice.finish_reason); } if ((choice == null ? void 0 : choice.delta) == null) { return; } const delta = choice.delta; if (delta.reasoning != null && delta.reasoning.length > 0) { controller.enqueue({ type: "reasoning", textDelta: delta.reasoning }); } if (delta.content != null && delta.content.length > 0) { controller.enqueue({ type: "text-delta", textDelta: delta.content }); } if (delta.tool_calls != null) { for (const toolCallDelta of delta.tool_calls) { const index = toolCallDelta.index; if (toolCalls[index] == null) { if (toolCallDelta.type !== "function") { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function' type.` }); } if (toolCallDelta.id == null) { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'id' to be a string.` }); } if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function.name' to be a string.` }); } toolCalls[index] = { id: toolCallDelta.id, type: "function", function: { name: toolCallDelta.function.name, arguments: (_e = toolCallDelta.function.arguments) != null ? _e : "" }, hasFinished: false }; const toolCall2 = toolCalls[index]; if (((_f = toolCall2.function) == null ? void 0 : _f.name) != null && ((_g = toolCall2.function) == null ? void 0 : _g.arguments) != null) { if (toolCall2.function.arguments.length > 0) { controller.enqueue({ type: "tool-call-delta", toolCallType: "function", toolCallId: toolCall2.id, toolName: toolCall2.function.name, argsTextDelta: toolCall2.function.arguments }); } if ((0, import_provider_utils4.isParsableJson)(toolCall2.function.arguments)) { controller.enqueue({ type: "tool-call", toolCallType: "function", toolCallId: (_h = toolCall2.id) != null ? _h : (0, import_provider_utils4.generateId)(), toolName: toolCall2.function.name, args: toolCall2.function.arguments }); toolCall2.hasFinished = true; } } continue; } const toolCall = toolCalls[index]; if (toolCall.hasFinished) { continue; } if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) { toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : ""; } controller.enqueue({ type: "tool-call-delta", toolCallType: "function", toolCallId: toolCall.id, toolName: toolCall.function.name, argsTextDelta: (_l = toolCallDelta.function.arguments) != null ? _l : "" }); if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && (0, import_provider_utils4.isParsableJson)(toolCall.function.arguments)) { controller.enqueue({ type: "tool-call", toolCallType: "function", toolCallId: (_o = toolCall.id) != null ? _o : (0, import_provider_utils4.generateId)(), toolName: toolCall.function.name, args: toolCall.function.arguments }); toolCall.hasFinished = true; } } } }, flush(controller) { var _a, _b; controller.enqueue({ type: "finish", finishReason, usage: { promptTokens: (_a = usage.promptTokens) != null ? _a : NaN, completionTokens: (_b = usage.completionTokens) != null ? _b : NaN }, ...providerMetadata != null ? { providerMetadata } : {} }); } }) ), rawCall: { rawPrompt, rawSettings }, rawResponse: { headers: responseHeaders }, warnings, request: { body } }; } }; var sarvamChatResponseSchema = import_zod2.z.object({ id: import_zod2.z.string().nullish(), created: import_zod2.z.number().nullish(), model: import_zod2.z.string().nullish(), choices: import_zod2.z.array( import_zod2.z.object({ message: import_zod2.z.object({ content: import_zod2.z.string().nullish(), reasoning: import_zod2.z.string().nullish(), tool_calls: import_zod2.z.array( import_zod2.z.object({ id: import_zod2.z.string().nullish(), type: import_zod2.z.literal("function"), function: import_zod2.z.object({ name: import_zod2.z.string(), arguments: import_zod2.z.string() }) }) ).nullish() }), index: import_zod2.z.number(), finish_reason: import_zod2.z.string().nullish() }) ), usage: import_zod2.z.object({ prompt_tokens: import_zod2.z.number().nullish(), completion_tokens: import_zod2.z.number().nullish() }).nullish() }); var sarvamChatChunkSchema = import_zod2.z.union([ import_zod2.z.object({ id: import_zod2.z.string().nullish(), created: import_zod2.z.number().nullish(), model: import_zod2.z.string().nullish(), choices: import_zod2.z.array( import_zod2.z.object({ delta: import_zod2.z.object({ content: import_zod2.z.string().nullish(), reasoning: import_zod2.z.string().nullish(), tool_calls: import_zod2.z.array( import_zod2.z.object({ index: import_zod2.z.number(), id: import_zod2.z.string().nullish(), type: import_zod2.z.literal("function").optional(), function: import_zod2.z.object({ name: import_zod2.z.string().nullish(), arguments: import_zod2.z.string().nullish() }) }) ).nullish() }).nullish(), finish_reason: import_zod2.z.string().nullable().optional(), index: import_zod2.z.number() }) ), x_sarvam: import_zod2.z.object({ usage: import_zod2.z.object({ prompt_tokens: import_zod2.z.number().nullish(), completion_tokens: import_zod2.z.number().nullish() }).nullish() }).nullish() }), sarvamErrorDataSchema ]); // src/sarvam-speech-model.ts var import_provider_utils5 = require("@ai-sdk/provider-utils"); // src/sarvam-speech-settings.ts var import_zod3 = require("zod"); var SpeakerSchema = import_zod3.z.enum([ "meera", "pavithra", "maitreyi", "arvind", "amol", "amartya", "diya", "neel", "misha", "vian", "arjun", "maya", "anushka", "abhilash", "manisha", "vidya", "arya", "karun", "hitesh" ]).default("meera"); var SarvamProviderOptionsSchema = import_zod3.z.object({ speaker: SpeakerSchema, pitch: import_zod3.z.number().min(-0.75).max(0.75).default(0), pace: import_zod3.z.number().min(0.5).max(2).default(1), loudness: import_zod3.z.number().min(0.3).max(3).default(1), speech_sample_rate: import_zod3.z.union([ import_zod3.z.literal(8e3), import_zod3.z.literal(16e3), import_zod3.z.literal(22050), import_zod3.z.literal(24e3) ]).default(22050), enable_preprocessing: import_zod3.z.boolean().default(false) }).partial(); // src/sarvam-speech-model.ts var import_zod4 = require("zod"); var SarvamSpeechModel = class { constructor(modelId, languageCode, config) { this.modelId = modelId; this.languageCode = languageCode; this.config = config; this.specificationVersion = "v1"; } get provider() { return this.config.provider; } getArgs({ text, voice, outputFormat = "wav", // speed, // instructions, providerOptions }) { const warnings = []; const sarvamOptions = (0, import_provider_utils5.parseProviderOptions)({ provider: "sarvam", providerOptions: { sarvam: { ...providerOptions == null ? void 0 : providerOptions.sarvam, ...this.config.speech } }, schema: SarvamProviderOptionsSchema }); const getSpeaker = () => { if (sarvamOptions == null ? void 0 : sarvamOptions.speaker) return sarvamOptions.speaker; if (voice) { return SpeakerSchema.parse(voice); } switch (this.modelId) { case "bulbul:v1": return "meera"; case "bulbul:v2": return "manisha"; } return "meera"; }; const requestBody = { model: this.modelId, text, target_language_code: this.languageCode, speaker: getSpeaker() // response_format: "wav", // speed, // instructions, }; if (outputFormat) { if (["mp3", "opus", "aac", "flac", "wav", "pcm"].includes( outputFormat )) { requestBody.response_format = outputFormat; } else { warnings.push({ type: "unsupported-setting", setting: "outputFormat", details: `Unsupported output format: ${outputFormat}. Using mp3 instead.` }); } } if (sarvamOptions) { const speechModelOptions = {}; for (const key in speechModelOptions) { const value = speechModelOptions[key]; if (value !== void 0) { requestBody[key] = value; } } } return { requestBody, warnings }; } async doGenerate(options) { var _a, _b, _c; 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, warnings } = this.getArgs(options); const { value, responseHeaders, rawValue: rawResponse } = await (0, import_provider_utils5.postJsonToApi)({ url: this.config.url({ path: "/text-to-speech", modelId: this.modelId }), headers: (0, import_provider_utils5.combineHeaders)(this.config.headers(), options.headers), body: requestBody, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils5.createJsonResponseHandler)( import_zod4.z.object({ request_id: import_zod4.z.string(), audios: import_zod4.z.array(import_zod4.z.string()) }) ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const audio = value.audios[0]; return { audio, warnings, request: { body: JSON.stringify(requestBody) }, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders, body: rawResponse } }; } }; // src/sarvam-transcription-model.ts var import_provider_utils6 = require("@ai-sdk/provider-utils"); var import_zod6 = require("zod"); // src/sarvam-transcription-settings.ts var import_zod5 = require("zod"); var SarvamProviderOptionsSchema2 = import_zod5.z.object({ with_timestamps: import_zod5.z.boolean().nullish().default(false), with_diarization: import_zod5.z.boolean().nullish().default(false), num_speakers: import_zod5.z.number().int().nullish() }); // src/sarvam-transcription-model.ts var SarvamTranscriptionModel = class { constructor(modelId, languageCode, config) { this.modelId = modelId; this.languageCode = languageCode; this.config = config; this.specificationVersion = "v1"; } get provider() { return this.config.provider; } getArgs({ audio, mediaType, providerOptions }) { const warnings = []; if (this.modelId === "saarika:v1" && this.languageCode === "unknown") throw new Error( "Language code unknown is not supported for model saarika:v1" ); const sarvamOptions = (0, import_provider_utils6.parseProviderOptions)({ provider: "sarvam", providerOptions: { sarvam: { ...providerOptions == null ? void 0 : providerOptions.sarvam, ...this.config.transcription } }, schema: SarvamProviderOptionsSchema2 }); const formData = new FormData(); const blob = audio instanceof Blob ? audio : new Blob([audio], { type: mediaType }); formData.append("file", blob); formData.append("model", this.modelId); if (sarvamOptions) { formData.append("language_code", this.languageCode); formData.append( "with_timestamps", sarvamOptions.with_timestamps ? "true" : "false" ); formData.append( "with_diarization", sarvamOptions.with_diarization ? "true" : "false" ); if (sarvamOptions.num_speakers !== null && sarvamOptions.num_speakers !== void 0) { formData.append( "num_speakers", sarvamOptions.num_speakers.toString() ); } } return { formData, 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 { formData, warnings } = this.getArgs(options); const { value: response, responseHeaders, rawValue: rawResponse } = await (0, import_provider_utils6.postFormDataToApi)({ url: this.config.url({ path: "/speech-to-text", modelId: this.modelId }), headers: (0, import_provider_utils6.combineHeaders)(this.config.headers(), options.headers), formData, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils6.createJsonResponseHandler)( sarvamTranscriptionResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); return { text: response.transcript, segments: response.timestamps ? response.timestamps.words.map((word, index) => ({ text: word, startSecond: response.timestamps.start_time_seconds[index], endSecond: response.timestamps.end_time_seconds[index] })) : [], language: response.language_code ? response.language_code : void 0, durationInSeconds: (_e = (_d = response.timestamps) == null ? void 0 : _d.end_time_seconds[response.timestamps.end_time_seconds.length - 1]) != null ? _e : void 0, warnings, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders, body: rawResponse } }; } }; var sarvamTranscriptionResponseSchema = import_zod6.z.object({ request_id: import_zod6.z.string().nullable(), transcript: import_zod6.z.string(), language_code: import_zod6.z.string().nullable(), timestamps: import_zod6.z.object({ end_time_seconds: import_zod6.z.array(import_zod6.z.number()), start_time_seconds: import_zod6.z.array(import_zod6.z.number()), words: import_zod6.z.array(import_zod6.z.string()) }).optional(), diarized_transcript: import_zod6.z.object({ entries: import_zod6.z.array( import_zod6.z.object({ end_time_seconds: import_zod6.z.array(import_zod6.z.number()), start_time_seconds: import_zod6.z.array(import_zod6.z.number()), transcript: import_zod6.z.string(), speaker_id: import_zod6.z.string() }) ) }).optional() }); // src/sarvam-translation-model.ts var import_provider_utils7 = require("@ai-sdk/provider-utils"); var import_zod8 = require("zod"); // src/sarvam-config.ts var import_zod7 = require("zod"); var SarvamLanguageCodeSchema = import_zod7.z.enum([ "hi-IN", "bn-IN", "kn-IN", "ml-IN", "mr-IN", "od-IN", "pa-IN", "ta-IN", "te-IN", "en-IN", "gu-IN" ]); var SarvamScriptCodeSchema = import_zod7.z.enum([ "Latn", "Deva", "Beng", "Gujr", "Knda", "Mlym", "Orya", "Guru", "Taml", "Telu" ]); // src/sarvam-translation-model.ts var SarvamTranslationModel = class { constructor(settings, config) { this.specificationVersion = "v1"; this.supportsStructuredOutputs = false; this.defaultObjectGenerationMode = "json"; var _a; this.modelId = (_a = settings.model) != null ? _a : "mayura:v1"; this.settings = settings; this.config = config; } get provider() { return this.config.provider; } get supportsImageUrls() { return false; } getArgs({ mode, prompt }) { var _a, _b, _c, _d, _e, _f, _g, _h; const type = mode.type; const warnings = []; if (this.settings.from === this.settings.to) { throw new Error( "Source and target languages code must be different." ); } if (this.modelId === "sarvam-translate:v1") { if (((_a = this.settings.mode) != null ? _a : "formal") !== "formal") throw new Error( "Sarvam 'sarvam-translate:v1' only support mode formal." ); if (((_b = this.settings.from) != null ? _b : "auto") === "auto") throw new Error( "Sarvam 'sarvam-translate:v1' requires source language code." ); } if (type !== "regular") { const _exhaustiveCheck = type; throw new Error(`Unsupported type: ${_exhaustiveCheck}`); } const messages = convertToSarvamChatMessages(prompt); return { messages, args: { input: messages.filter((m) => m.role === "user").map((m) => m.content).join("\n"), source_language_code: (_c = this.settings.from) != null ? _c : "auto", target_language_code: this.settings.to, numerals_format: (_d = this.settings.numerals_format) != null ? _d : "international", enable_preprocessing: (_e = this.settings.enable_preprocessing) != null ? _e : false, output_script: (_f = this.settings.output_script) != null ? _f : null, speaker_gender: (_g = this.settings.speaker_gender) != null ? _g : "Male", mode: (_h = this.settings.mode) != null ? _h : "formal", model: this.modelId }, warnings }; } async doGenerate(options) { var _a; const { args, warnings, messages } = this.getArgs({ ...options, stream: false }); const body = JSON.stringify(args); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils7.postJsonToApi)({ url: this.config.url({ path: "/translate" }), headers: (0, import_provider_utils7.combineHeaders)(this.config.headers(), options.headers), body: args, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils7.createJsonResponseHandler)( sarvamTranslationResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const { input: rawPrompt, ...rawSettings } = args; const text = (_a = response.translated_text) != null ? _a : void 0; return { text, toolCalls: void 0, reasoning: void 0, finishReason: "unknown", usage: { promptTokens: NaN, completionTokens: NaN }, rawCall: { rawPrompt, rawSettings }, rawResponse: { headers: responseHeaders, body: rawResponse }, response: void 0, warnings, request: { body } }; } async doStream(options) { throw new Error("Translation feature doesn't support streaming yet"); } }; var sarvamTranslationResponseSchema = import_zod8.z.object({ translated_text: import_zod8.z.string().nullish(), source_language_code: SarvamLanguageCodeSchema.nullable(), request_id: import_zod8.z.string().nullish() }); // src/sarvam-transliterate-model.ts var import_provider_utils8 = require("@ai-sdk/provider-utils"); var import_zod9 = require("zod"); var SarvamTransliterateModel = class { constructor(settings, config) { this.specificationVersion = "v1"; this.supportsStructuredOutputs = false; this.defaultObjectGenerationMode = "json"; this.modelId = "unknown"; this.settings = settings; this.config = config; } get provider() { return this.config.provider; } get supportsImageUrls() { return false; } getArgs({ mode, prompt }) { var _a, _b, _c; const type = mode.type; const warnings = []; if (this.settings.from !== "auto") { if (this.settings.to !== "en-IN" && this.settings.from !== "en-IN") throw new Error( "Sarvam doesn't support Indic-Indic Transliteration yet" ); } if (type !== "regular") { const _exhaustiveCheck = type; throw new Error(`Unsupported type: ${_exhaustiveCheck}`); } const messages = convertToSarvamChatMessages(prompt); return { messages, args: { input: messages.filter((m) => m.role === "user").map((m) => m.content).join("\n"), source_language_code: (_a = this.settings.from) != null ? _a : "auto", target_language_code: this.settings.to, numerals_format: (_b = this.settings.numerals_format) != null ? _b : "international", ...this.settings.spoken_form ? { spoken_form: this.settings.spoken_form, spoken_form_numerals_language: (_c = this.settings.spoken_form_numerals_language) != null ? _c : "english" } : {} }, warnings }; } async doGenerate(options) { var _a; const { args, warnings, messages } = this.getArgs({ ...options, stream: false }); const body = JSON.stringify(args); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils8.postJsonToApi)({ url: this.config.url({ path: "/transliterate" }), headers: (0, import_provider_utils8.combineHeaders)(this.config.headers(), options.headers), body: args, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils8.createJsonResponseHandler)( sarvamTransliterateResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const { input: rawPrompt, ...rawSettings } = args; let text = (_a = response.transliterated_text) != null ? _a : void 0; return { text, toolCalls: void 0, reasoning: void 0, finishReason: "unknown", usage: { promptTokens: NaN, completionTokens: NaN }, rawCall: { rawPrompt, rawSettings }, rawResponse: { headers: responseHeaders, body: rawResponse }, response: void 0, warnings, request: { body } }; } async doStream(options) { throw new Error("Transliterate feature doesn't streaming yet"); } }; var sarvamTransliterateResponseSchema = import_zod9.z.object({ transliterated_text: import_zod9.z.string().nullish(), source_language_code: SarvamLanguageCodeSchema.nullable(), request_id: import_zod9.z.string().nullish() }); // src/sarvam-lid-model.ts var import_provider_utils9 = require("@ai-sdk/provider-utils"); var import_zod10 = require("zod"); var SarvamLidModel = class { constructor(config) { this.specificationVersion = "v1"; this.supportsStructuredOutputs = false; this.defaultObjectGenerationMode = "json"; this.modelId = "unknown"; this.config = config; } get provider() { return this.config.provider; } get supportsImageUrls() { return false; } getArgs({ mode, prompt }) { const type = mode.type; const warnings = []; if (type !== "regular") { const _exhaustiveCheck = type; throw new Error(`Unsupported type: ${_exhaustiveCheck}`); } const messages = convertToSarvamChatMessages(prompt); return { messages, args: { input: messages.filter((m) => m.role === "user").map((m) => m.content).join("\n") }, warnings }; } async doGenerate(options) { var _a; const { args, warnings, messages } = this.getArgs({ ...options, stream: false }); const body = JSON.stringify(args); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils9.postJsonToApi)({ url: this.config.url({ path: "/text-lid" }), headers: (0, import_provider_utils9.combineHeaders)(this.config.headers(), options.headers), body: args, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils9.createJsonResponseHandler)( sarvamLidResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const { input: rawPrompt, ...rawSettings } = args; const text = (_a = response.language_code) != null ? _a : void 0; return { text, toolCalls: void 0, reasoning: void 0, finishReason: "unknown", usage: { promptTokens: NaN, completionTokens: NaN }, rawCall: { rawPrompt, rawSettings }, rawResponse: { headers: responseHeaders, body: rawResponse }, response: void 0, warnings, request: { body } }; } async doStream(options) { throw new Error("Language Identification feature doesn't streaming yet"); } }; var sarvamLidResponseSchema = import_zod10.z.object({ script_code: SarvamScriptCodeSchema.nullish(), language_code: SarvamLanguageCodeSchema.nullable(), request_id: import_zod10.z.string().nullish() }); // src/sarvam-speech-translation-model.ts var import_provider_utils10 = require("@ai-sdk/provider-utils"); var import_zod11 = require("zod"); var SarvamSpeechTranslationModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v1"; } get provider() { return this.config.provider; } getArgs({ audio, mediaType, providerOptions }) { const warnings = []; const formData = new FormData(); const blob = audio instanceof Blob ? audio : new Blob([audio], { type: mediaType }); formData.append("file", blob); formData.append("model", this.modelId); return { formData, warnings }; } async doGenerate(options) { var _a, _b, _c; 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 { formData, warnings } = this.getArgs(options); const { value: response, responseHeaders, rawValue: rawResponse } = await (0, import_provider_utils10.postFormDataToApi)({ url: this.config.url({ path: "/speech-to-text-translate", modelId: this.modelId }), headers: (0, import_provider_utils10.combineHeaders)(this.config.headers(), options.headers), formData, failedResponseHandler: sarvamFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils10.createJsonResponseHandler)( sarvamTranscriptionResponseSchema2 ), abortSignal: options.abortSignal, fetch: this.config.fetch }); return { text: response.transcript, segments: [], language: response.language_code ? response.language_code : void 0, durationInSeconds: void 0, warnings, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders, body: rawResponse } }; } }; var sarvamTranscriptionResponseSchema2 = import_zod11.z.object({ request_id: import_zod11.z.string().nullable(), transcript: import_zod11.z.string(), language_code: import_zod11.z.string().nullable(), // timestamps: z // .object({ // end_time_seconds: z.array(z.number()), // start_time_seconds: z.array(z.number()), // words: z.array(z.string()), // }) // .optional(), diarized_transcript: import_zod11.z.object({ entries: import_zod11.z.array( import_zod11.z.object({ end_time_seconds: import_zod11.z.array(import_zod11.z.number()), start_time_seconds: import_zod11.z.array(import_zod11.z.number()), transcript: import_zod11.z.string(), speaker_id: import_zod11.z.string() }) ) }).nullable().optional() }); // src/sarvam-provider.ts function createSarvam(options = {}) { var _a; const baseURL = (_a = (0, import_provider_utils11.withoutTrailingSlash)(options.baseURL)) != null ? _a : "https://api.sarvam.ai"; const getApiKey = () => (0, import_provider_utils11.loadApiKey)({ apiKey: options.apiKey, environmentVariableName: "SARVAM_API_KEY", description: "Sarvam" }); const getHeaders = () => ({ Authorization: `Bearer ${getApiKey()}`, "api-subscription-key": getApiKey(), ...options.headers }); const createChatModel = (modelId, settings = {}) => new SarvamChatLanguageModel(modelId, settings, { provider: "sarvam.chat", url: ({ path }) => `${baseURL}/v1${path}`, headers: getHeaders, fetch: options.fetch }); const createLanguageModel = (modelId, settings) => { if (new.target) { throw new Error( "The Sarvam model function cannot be called with the new keyword." ); } return createChatModel(modelId, settings); }; const createTranscriptionModel = (modelId, languageCode = "unknown", settings) => new SarvamTranscriptionModel(modelId, languageCode, { provider: "sarvam.transcription", url: ({ path }) => `${baseURL}${path}`, headers: getHeaders, fetch: options.fetch, transcription: settings }); const createSpeechTranslation = (modelId) => new SarvamSpeechTranslationModel(modelId, { provider: "sarvam.transcription", url: ({ path }) => `${baseURL}${path}`, headers: getHeaders, fetch: options.fetch }); const createSpeechModel = (modelId, languageCode, settings) => new SarvamSpeechModel(modelId, languageCode, { provider: "sarvam.speech", url: ({ path }) => `${baseURL}${path}`, headers: getHeaders, fetch: options.fetch, speech: settings }); const createTransliterateModel = (settings) => new SarvamTransliterateModel( settings, { provider: "sarvam.transliterate", url: ({ path }) => `${baseURL}${path}`, headers: getHeaders, fetch: options.fetch } ); const createTranslationMode