UNPKG

@genkit-ai/vertexai

Version:

Genkit AI framework plugin for Google Cloud Vertex AI APIs including Gemini APIs, Imagen, and more.

1 lines 21.2 kB
{"version":3,"sources":["../../src/modelgarden/mistral.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MistralGoogleCloud } from '@mistralai/mistralai-gcp';\nimport {\n AssistantMessage,\n ChatCompletionChoiceFinishReason,\n ChatCompletionRequest,\n ChatCompletionResponse,\n CompletionChunk,\n FunctionCall,\n Tool as MistralTool,\n SystemMessage,\n ToolCall,\n ToolMessage,\n ToolTypes,\n UserMessage,\n} from '@mistralai/mistralai-gcp/models/components';\nimport {\n GENKIT_CLIENT_HEADER,\n GenerateRequest,\n GenerationCommonConfigSchema,\n Genkit,\n MessageData,\n ModelReference,\n ModelResponseData,\n Part,\n Role,\n ToolRequestPart,\n z,\n} from 'genkit';\nimport { ModelAction, modelRef } from 'genkit/model';\n\n/**\n * See https://docs.mistral.ai/api/#tag/chat/operation/chat_completion_v1_chat_completions_post\n */\nexport const MistralConfigSchema = GenerationCommonConfigSchema.extend({\n // TODO: Update this with all the parameters in\n // https://docs.mistral.ai/api/#tag/chat/operation/chat_completion_v1_chat_completions_post.\n location: z.string().optional(),\n maxOutputTokens: z.number().optional(),\n temperature: z.number().optional(),\n // TODO: is this supported?\n // topK: z.number().optional(),\n topP: z.number().optional(),\n stopSequences: z.array(z.string()).optional(),\n});\n\nexport const mistralLarge = modelRef({\n name: 'vertexai/mistral-large',\n info: {\n label: 'Vertex AI Model Garden - Mistral Large',\n versions: ['mistral-large-2411', 'mistral-large-2407'],\n supports: {\n multiturn: true,\n media: false,\n tools: true,\n systemRole: true,\n output: ['text'],\n },\n },\n configSchema: MistralConfigSchema,\n});\n\nexport const mistralNemo = modelRef({\n name: 'vertexai/mistral-nemo',\n info: {\n label: 'Vertex AI Model Garden - Mistral Nemo',\n versions: ['mistral-nemo-2407'],\n supports: {\n multiturn: true,\n media: false,\n tools: false,\n systemRole: true,\n output: ['text'],\n },\n },\n configSchema: MistralConfigSchema,\n});\n\nexport const codestral = modelRef({\n name: 'vertexai/codestral',\n info: {\n label: 'Vertex AI Model Garden - Codestral',\n versions: ['codestral-2405'],\n supports: {\n multiturn: true,\n media: false,\n tools: false,\n systemRole: true,\n output: ['text'],\n },\n },\n configSchema: MistralConfigSchema,\n});\n\nexport const SUPPORTED_MISTRAL_MODELS: Record<\n string,\n ModelReference<typeof MistralConfigSchema>\n> = {\n 'mistral-large': mistralLarge,\n 'mistral-nemo': mistralNemo,\n codestral: codestral,\n};\n\n// TODO: Do they export a type for this?\ntype MistralRole = 'assistant' | 'user' | 'tool' | 'system';\n\nfunction toMistralRole(role: Role): MistralRole {\n switch (role) {\n case 'model':\n return 'assistant';\n case 'user':\n return 'user';\n case 'tool':\n return 'tool';\n case 'system':\n return 'system';\n default:\n throw new Error(`Unknwon role ${role}`);\n }\n}\nfunction toMistralToolRequest(toolRequest: Record<string, any>): FunctionCall {\n if (!toolRequest.name) {\n throw new Error('Tool name is required');\n }\n\n return {\n name: toolRequest.name,\n // Mistral expects arguments as either a string or object\n arguments:\n typeof toolRequest.input === 'string'\n ? toolRequest.input\n : JSON.stringify(toolRequest.input),\n };\n}\n\nexport function toMistralRequest(\n model: string,\n input: GenerateRequest<typeof MistralConfigSchema>\n): ChatCompletionRequest {\n const messages = input.messages.map((msg) => {\n // Handle regular text messages\n if (msg.content.every((part) => part.text)) {\n const content = msg.content.map((part) => part.text || '').join('');\n return {\n role: toMistralRole(msg.role),\n content,\n };\n }\n\n // Handle assistant's tool/function calls\n const toolRequest = msg.content.find((part) => part.toolRequest);\n if (toolRequest?.toolRequest) {\n const functionCall = toMistralToolRequest(toolRequest.toolRequest);\n return {\n role: 'assistant' as const,\n content: null,\n toolCalls: [\n {\n id: toolRequest.toolRequest.ref,\n type: ToolTypes.Function,\n function: {\n name: functionCall.name,\n arguments: functionCall.arguments,\n },\n },\n ],\n };\n }\n\n // Handle tool responses\n const toolResponse = msg.content.find((part) => part.toolResponse);\n if (toolResponse?.toolResponse) {\n return {\n role: 'tool' as const,\n name: toolResponse.toolResponse.name,\n content: JSON.stringify(toolResponse.toolResponse.output),\n toolCallId: toolResponse.toolResponse.ref, // This must match the id from tool_calls\n };\n }\n\n return {\n role: toMistralRole(msg.role),\n content: msg.content.map((part) => part.text || '').join(''),\n };\n });\n\n validateToolSequence(messages); // This line exists but might not be running?\n\n const request: ChatCompletionRequest = {\n model,\n messages,\n maxTokens: input.config?.maxOutputTokens ?? 1024,\n temperature: input.config?.temperature ?? 0.7,\n ...(input.config?.topP && { topP: input.config.topP }),\n ...(input.config?.stopSequences && { stop: input.config.stopSequences }),\n ...(input.tools && {\n tools: input.tools.map((tool) => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.inputSchema || {},\n },\n })) as MistralTool[],\n }),\n };\n\n return request;\n}\n// Helper to convert Mistral AssistantMessage content into Genkit parts\nfunction fromMistralTextPart(content: string): Part {\n return {\n text: content,\n };\n}\n\n// Helper to convert Mistral ToolCall into Genkit parts\nfunction fromMistralToolCall(toolCall: ToolCall): ToolRequestPart {\n if (!toolCall.function) {\n throw new Error('Tool call must include a function definition');\n }\n\n return {\n toolRequest: {\n ref: toolCall.id,\n name: toolCall.function.name,\n input:\n typeof toolCall.function.arguments === 'string'\n ? JSON.parse(toolCall.function.arguments)\n : toolCall.function.arguments,\n },\n };\n}\n\n// Converts Mistral AssistantMessage content into Genkit parts\nfunction fromMistralMessage(message: AssistantMessage): Part[] {\n const parts: Part[] = [];\n\n // Handle textual content\n if (typeof message.content === 'string') {\n parts.push(fromMistralTextPart(message.content));\n } else if (Array.isArray(message.content)) {\n // If content is an array of ContentChunk, handle each chunk\n message.content.forEach((chunk) => {\n if (chunk.type === 'text') {\n parts.push(fromMistralTextPart(chunk.text));\n }\n // Add support for other ContentChunk types here if needed\n });\n }\n\n // Handle tool calls if present\n if (message.toolCalls) {\n message.toolCalls.forEach((toolCall) => {\n parts.push(fromMistralToolCall(toolCall));\n });\n }\n\n return parts;\n}\n\n// Maps Mistral finish reasons to Genkit finish reasons\nexport function fromMistralFinishReason(\n reason: ChatCompletionChoiceFinishReason | undefined\n): 'length' | 'unknown' | 'stop' | 'blocked' | 'other' {\n switch (reason) {\n case ChatCompletionChoiceFinishReason.Stop:\n return 'stop';\n case ChatCompletionChoiceFinishReason.Length:\n case ChatCompletionChoiceFinishReason.ModelLength:\n return 'length';\n case ChatCompletionChoiceFinishReason.Error:\n return 'other'; // Map generic errors to \"other\"\n case ChatCompletionChoiceFinishReason.ToolCalls:\n return 'stop'; // Assuming tool calls signify a \"stop\" in processing\n default:\n return 'other'; // For undefined or unmapped reasons\n }\n}\n\n// Converts a Mistral response to a Genkit response\nexport function fromMistralResponse(\n _input: GenerateRequest<typeof MistralConfigSchema>,\n response: ChatCompletionResponse\n): ModelResponseData {\n const firstChoice = response.choices?.[0];\n // Convert content from Mistral response to Genkit parts\n const contentParts: Part[] = firstChoice?.message\n ? fromMistralMessage(firstChoice.message)\n : [];\n\n const message: MessageData = {\n role: 'model',\n content: contentParts,\n };\n\n return {\n message,\n finishReason: fromMistralFinishReason(firstChoice?.finishReason),\n usage: {\n inputTokens: response.usage.promptTokens,\n outputTokens: response.usage.completionTokens,\n },\n custom: {\n id: response.id,\n model: response.model,\n created: response.created,\n },\n raw: response, // Include the raw response for debugging or additional context\n };\n}\n\nexport function mistralModel(\n ai: Genkit,\n modelName: string,\n projectId: string,\n region: string\n): ModelAction {\n const getClient = createClientFactory(projectId);\n\n const model = SUPPORTED_MISTRAL_MODELS[modelName];\n if (!model) {\n throw new Error(`Unsupported Mistral model name ${modelName}`);\n }\n\n return ai.defineModel(\n {\n name: model.name,\n label: model.info?.label,\n configSchema: MistralConfigSchema,\n supports: model.info?.supports,\n versions: model.info?.versions,\n },\n async (input, sendChunk) => {\n const client = getClient(input.config?.location || region);\n\n const versionedModel =\n input.config?.version ?? model.info?.versions?.[0] ?? model.name;\n\n if (!sendChunk) {\n const mistralRequest = toMistralRequest(versionedModel, input);\n\n const response = await client.chat.complete(mistralRequest, {\n fetchOptions: {\n headers: {\n 'X-Goog-Api-Client': GENKIT_CLIENT_HEADER,\n },\n },\n });\n\n return fromMistralResponse(input, response);\n } else {\n const mistralRequest = toMistralRequest(versionedModel, input);\n const stream = await client.chat.stream(mistralRequest, {\n fetchOptions: {\n headers: {\n 'X-Goog-Api-Client': GENKIT_CLIENT_HEADER,\n },\n },\n });\n\n for await (const event of stream) {\n const parts = fromMistralCompletionChunk(event.data);\n if (parts.length > 0) {\n sendChunk({\n content: parts,\n });\n }\n }\n\n // Get the complete response after streaming\n const completeResponse = await client.chat.complete(mistralRequest, {\n fetchOptions: {\n headers: {\n 'X-Goog-Api-Client': GENKIT_CLIENT_HEADER,\n },\n },\n });\n\n return fromMistralResponse(input, completeResponse);\n }\n }\n );\n}\n\nfunction createClientFactory(projectId: string) {\n const clients: Record<string, MistralGoogleCloud> = {};\n\n return (region: string): MistralGoogleCloud => {\n if (!region) {\n throw new Error('Region is required to create Mistral client');\n }\n\n try {\n if (!clients[region]) {\n clients[region] = new MistralGoogleCloud({\n region,\n projectId,\n });\n }\n return clients[region];\n } catch (error) {\n throw new Error(\n `Failed to create/retrieve Mistral client for region ${region}: ${error}`\n );\n }\n };\n}\n\ntype MistralMessage =\n | AssistantMessage\n | ToolMessage\n | SystemMessage\n | UserMessage;\n\n// Helper function to validate tool calls and responses match\nfunction validateToolSequence(messages: MistralMessage[]) {\n const toolCalls = (\n messages.filter((m) => {\n return m.role === 'assistant' && m.toolCalls;\n }) as AssistantMessage[]\n ).reduce((acc: ToolCall[], m) => {\n if (m.toolCalls) {\n return [...acc, ...m.toolCalls];\n }\n return acc;\n }, []);\n\n const toolResponses = messages.filter(\n (m) => m.role === 'tool'\n ) as ToolMessage[];\n\n if (toolCalls.length !== toolResponses.length) {\n throw new Error(\n `Mismatch between tool calls (${toolCalls.length}) and responses (${toolResponses.length})`\n );\n }\n\n toolResponses.forEach((response) => {\n const matchingCall = toolCalls.find(\n (call) => call.id === response.toolCallId\n );\n if (!matchingCall) {\n throw new Error(\n `Tool response with ID ${response.toolCallId} has no matching call`\n );\n }\n });\n}\n\nexport function fromMistralCompletionChunk(chunk: CompletionChunk): Part[] {\n if (!chunk.choices?.[0]?.delta) return [];\n\n const delta = chunk.choices[0].delta;\n const parts: Part[] = [];\n\n if (typeof delta.content === 'string') {\n parts.push({ text: delta.content });\n }\n\n if (delta.toolCalls) {\n delta.toolCalls.forEach((toolCall) => {\n if (!toolCall.function) return;\n\n parts.push({\n toolRequest: {\n ref: toolCall.id,\n name: toolCall.function.name,\n input:\n typeof toolCall.function.arguments === 'string'\n ? JSON.parse(toolCall.function.arguments)\n : toolCall.function.arguments,\n },\n });\n });\n }\n\n return parts;\n}\n"],"mappings":"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","names":[]}