import {z} from 'zod' export type FIMCompletionRequest = {model: string, temperature?: (number | null) | undefined, top_p?: (number | null) | undefined, max_tokens?: (number | null) | undefined, stream?: boolean | undefined, stop?: (string | Array | null) | undefined, random_seed?: (number | null) | undefined, metadata?: ({[key: string]: unknown} | null) | undefined, prompt: string, suffix?: (string | null) | undefined, min_tokens?: (number | null) | undefined, prompt_cache_key?: (string | null) | undefined}; export type CreateApiV1FimCompletionsArgs = {body: FIMCompletionRequest}; export type CreateApiV1FimCompletionsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const usageInfo = z.object({prompt_tokens: z.number().int(), completion_tokens: z.number().int(), total_tokens: z.number().int(), prompt_audio_seconds: z.number().int().nullable().optional(), service_tier: z.string().nullable().optional()}); export const textChunk = z.object({type: z.literal("text").optional(), text: z.string()}); export const imageDetail = z.enum(["low", "auto", "high"]); export const imageURL = z.object({url: z.string(), detail: imageDetail.nullable().optional()}); export const imageURLChunk = z.object({type: z.literal("image_url").optional(), image_url: z.union([imageURL, z.string()])}); export const documentURLChunk = z.object({type: z.literal("document_url").optional(), document_url: z.string(), document_name: z.string().nullable().optional()}); export const referenceChunk = z.object({type: z.literal("reference").optional(), reference_ids: z.array(z.union([z.number().int(), z.string()]))}); export const fileChunk = z.object({type: z.literal("file").optional(), file_id: z.string()}); export const builtInConnectors = z.enum(["web_search", "web_search_premium", "code_interpreter", "image_generation", "document_library", "mistral_mcp"]); export const toolReferenceChunk = z.object({type: z.literal("tool_reference").optional(), tool: z.union([builtInConnectors, z.string()]), title: z.string(), url: z.string().nullable().optional(), favicon: z.string().nullable().optional(), description: z.string().nullable().optional()}); export const thinkChunk = z.object({type: z.literal("thinking").optional(), thinking: z.array(z.union([textChunk, toolReferenceChunk, referenceChunk])), signature: z.string().nullable().optional(), closed: z.boolean().optional()}); export const audioChunk = z.object({type: z.literal("input_audio").optional(), input_audio: z.union([z.string(), z.string()])}); export const resourceChunk = z.object({type: z.literal("resource").optional(), uri: z.string(), content: z.discriminatedUnion("type", [textChunk, imageURLChunk])}); export const resourceLinkChunk = z.object({type: z.literal("resource_link").optional(), uri: z.string(), metadata: z.record(z.string(), z.union([z.string(), z.number().int(), z.number(), z.boolean()])).nullable().optional()}); export const contentChunk = z.discriminatedUnion("type", [textChunk, imageURLChunk, documentURLChunk, referenceChunk, fileChunk, thinkChunk, audioChunk, resourceChunk, resourceLinkChunk]); export const toolTypes = z.literal("function"); export const functionCall = z.object({name: z.string(), arguments: z.union([z.record(z.string(), z.unknown()), z.string()])}); export const toolCall = z.object({id: z.string().optional(), type: toolTypes.optional(), function: functionCall, index: z.number().int().optional()}); export const assistantMessage = z.object({role: z.literal("assistant").optional(), content: z.union([z.string(), z.array(contentChunk)]).nullable().optional(), tool_calls: z.array(toolCall).nullable().optional(), prefix: z.boolean().optional()}); export const deltaMessage = z.object({role: z.string().nullable().optional(), content: z.union([z.string(), z.array(contentChunk)]).nullable().optional(), tool_calls: z.array(toolCall).nullable().optional(), tool_call_id: z.string().nullable().optional(), index: z.number().int().gte(0).nullable().optional(), metadata: z.record(z.string(), z.unknown()).nullable().optional()}); export const chatCompletionResponseTokenLogprobs = z.object({token: z.string(), logprob: z.number(), bytes: z.array(z.number().int()), token_id: z.number().int()}); export const chatCompletionResponseTokenLogprobsTopK = z.object({token: z.string(), logprob: z.number(), bytes: z.array(z.number().int()), token_id: z.number().int(), top_logprobs: z.array(chatCompletionResponseTokenLogprobs).nullable().optional()}); export const chatCompletionResponseChoiceLogprobs = z.object({content: z.array(chatCompletionResponseTokenLogprobsTopK)}); export const chatCompletionChoice = z.object({index: z.number().int(), message: assistantMessage.optional(), messages: z.array(deltaMessage).optional(), finish_reason: z.enum(["stop", "length", "model_length", "error", "tool_calls"]), logprobs: chatCompletionResponseChoiceLogprobs.nullable().optional(), prompt_logprobs: chatCompletionResponseChoiceLogprobs.nullable().optional()}); export const fIMCompletionResponse = z.object({id: z.string(), object: z.string(), model: z.string(), usage: usageInfo, created: z.number().int(), choices: z.array(chatCompletionChoice)}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Fim Completion * * POST /v1/fim/completions */ export const createApiV1FimCompletions = async (args: CreateApiV1FimCompletionsArgs, options?: CreateApiV1FimCompletionsOptions) => { const {baseUrl = "https://api.mistral.ai", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKey !== undefined) headers.set('authorization', `Bearer ${ApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/fim/completions${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(fIMCompletionResponse, await res.json()) };