@genkit-ai/vertexai
Version:
Genkit AI framework plugin for Google Cloud Vertex AI APIs including Gemini APIs, Imagen, and more.
1 lines • 50.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/gemini.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 {\n Content,\n FunctionCallingMode,\n FunctionDeclaration,\n FunctionDeclarationSchemaType,\n Part as GeminiPart,\n GenerateContentCandidate,\n GenerateContentResponse,\n GenerativeModelPreview,\n HarmBlockThreshold,\n HarmCategory,\n Schema,\n StartChatParams,\n ToolConfig,\n VertexAI,\n type GoogleSearchRetrieval,\n} from '@google-cloud/vertexai';\nimport { ApiClient } from '@google-cloud/vertexai/build/src/resources/index.js';\nimport {\n GENKIT_CLIENT_HEADER,\n Genkit,\n GenkitError,\n JSONSchema,\n z,\n} from 'genkit';\nimport {\n CandidateData,\n GenerateRequest,\n GenerationCommonConfigSchema,\n MediaPart,\n MessageData,\n ModelAction,\n ModelInfo,\n ModelMiddleware,\n ModelReference,\n Part,\n ToolDefinitionSchema,\n getBasicUsageStats,\n modelRef,\n} from 'genkit/model';\nimport {\n downloadRequestMedia,\n simulateSystemPrompt,\n} from 'genkit/model/middleware';\nimport { runInNewSpan } from 'genkit/tracing';\nimport { GoogleAuth } from 'google-auth-library';\nimport { PluginOptions } from './common/types.js';\nimport { handleCacheIfNeeded } from './context-caching/index.js';\nimport { extractCacheConfig } from './context-caching/utils.js';\n\nconst SafetySettingsSchema = z.object({\n category: z.nativeEnum(HarmCategory),\n threshold: z.nativeEnum(HarmBlockThreshold),\n});\n\nconst VertexRetrievalSchema = z.object({\n datastore: z\n .object({\n projectId: z.string().describe('Google Cloud Project ID.').optional(),\n location: z\n .string()\n .describe('Google Cloud region e.g. us-central1.')\n .optional(),\n dataStoreId: z\n .string()\n .describe(\n 'The data store id, when project id and location are provided as ' +\n 'separate options. Alternatively, the full path to the data ' +\n 'store should be provided in the form: \"projects/{project}/' +\n 'locations/{location}/collections/default_collection/dataStores/{data_store}\".'\n ),\n })\n .describe('Vertex AI Search data store details'),\n disableAttribution: z\n .boolean()\n .describe(\n 'Disable using the search data in detecting grounding attribution. This ' +\n 'does not affect how the result is given to the model for generation.'\n )\n .optional(),\n});\n\nconst GoogleSearchRetrievalSchema = z.object({\n disableAttribution: z\n .boolean()\n .describe(\n 'Disable using the search data in detecting grounding attribution. This ' +\n 'does not affect how the result is given to the model for generation.'\n )\n .optional(),\n});\n\n/**\n * Zod schema of Gemini model options.\n */\nexport const GeminiConfigSchema = GenerationCommonConfigSchema.extend({\n location: z\n .string()\n .describe('Google Cloud region e.g. us-central1.')\n .optional(),\n\n /**\n * Safety filter settings. See: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/configure-safety-filters#configurable-filters\n *\n * E.g.\n *\n * ```js\n * config: {\n * safetySettings: [\n * {\n * category: 'HARM_CATEGORY_HATE_SPEECH',\n * threshold: 'BLOCK_LOW_AND_ABOVE',\n * },\n * {\n * category: 'HARM_CATEGORY_DANGEROUS_CONTENT',\n * threshold: 'BLOCK_MEDIUM_AND_ABOVE',\n * },\n * {\n * category: 'HARM_CATEGORY_HARASSMENT',\n * threshold: 'BLOCK_ONLY_HIGH',\n * },\n * {\n * category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n * threshold: 'BLOCK_NONE',\n * },\n * ],\n * }\n * ```\n */\n safetySettings: z\n .array(SafetySettingsSchema)\n .describe(\n 'Adjust how likely you are to see responses that could be harmful. ' +\n 'Content is blocked based on the probability that it is harmful.'\n )\n .optional(),\n\n /**\n * Vertex retrieval options.\n *\n * E.g.\n *\n * ```js\n * config: {\n * vertexRetrieval: {\n * datastore: {\n * projectId: 'your-cloud-project',\n * location: 'us-central1',\n * collection: 'your-collection',\n * },\n * disableAttribution: true,\n * }\n * }\n * ```\n */\n vertexRetrieval: VertexRetrievalSchema.describe(\n 'Retrieve from Vertex AI Search data store for grounding ' +\n 'generative responses.'\n ).optional(),\n\n /**\n * Google Search retrieval options.\n *\n * ```js\n * config: {\n * googleSearchRetrieval: {\n * disableAttribution: true,\n * }\n * }\n * ```\n */\n googleSearchRetrieval: GoogleSearchRetrievalSchema.describe(\n 'Retrieve public web data for grounding, powered by Google Search.'\n ).optional(),\n\n /**\n * Function calling options.\n *\n * E.g. forced tool call:\n *\n * ```js\n * config: {\n * functionCallingConfig: {\n * mode: 'ANY',\n * }\n * }\n * ```\n */\n functionCallingConfig: z\n .object({\n mode: z.enum(['MODE_UNSPECIFIED', 'AUTO', 'ANY', 'NONE']).optional(),\n allowedFunctionNames: z.array(z.string()).optional(),\n })\n .describe(\n 'Controls how the model uses the provided tools (function declarations). ' +\n 'With AUTO (Default) mode, the model decides whether to generate a ' +\n 'natural language response or suggest a function call based on the ' +\n 'prompt and context. With ANY, the model is constrained to always ' +\n 'predict a function call and guarantee function schema adherence. ' +\n 'With NONE, the model is prohibited from making function calls.'\n )\n .optional(),\n});\n\n/**\n * Known model names, to allow code completion for convenience. Allows other model names.\n */\nexport type GeminiVersionString =\n | keyof typeof SUPPORTED_GEMINI_MODELS\n | (string & {});\n\n/**\n * Returns a reference to a model that can be used in generate calls.\n *\n * ```js\n * await ai.generate({\n * prompt: 'hi',\n * model: gemini('gemini-1.5-flash')\n * });\n * ```\n */\nexport function gemini(\n version: GeminiVersionString,\n options: GeminiConfig = {}\n): ModelReference<typeof GeminiConfigSchema> {\n const nearestModel = nearestGeminiModelRef(version);\n return modelRef({\n name: `vertexai/${version}`,\n config: options,\n configSchema: GeminiConfigSchema,\n info: {\n ...nearestModel.info,\n // If exact suffix match for a known model, use its label, otherwise create a new label\n label: nearestModel.name.endsWith(version)\n ? nearestModel.info?.label\n : `Vertex AI - ${version}`,\n },\n });\n}\n\nfunction nearestGeminiModelRef(\n version: GeminiVersionString,\n options: GeminiConfig = {}\n): ModelReference<typeof GeminiConfigSchema> {\n const matchingKey = longestMatchingPrefix(\n version,\n Object.keys(SUPPORTED_GEMINI_MODELS)\n );\n if (matchingKey) {\n return SUPPORTED_GEMINI_MODELS[matchingKey].withConfig({\n ...options,\n version,\n });\n }\n return GENERIC_GEMINI_MODEL.withConfig({ ...options, version });\n}\n\nfunction longestMatchingPrefix(version: string, potentialMatches: string[]) {\n return potentialMatches\n .filter((p) => version.startsWith(p))\n .reduce(\n (longest, current) =>\n current.length > longest.length ? current : longest,\n ''\n );\n}\n\n/**\n * Gemini model configuration options.\n *\n * E.g.\n * ```js\n * config: {\n * temperature: 0.9,\n * maxOutputTokens: 300,\n * safetySettings: [\n * {\n * category: 'HARM_CATEGORY_HATE_SPEECH',\n * threshold: 'BLOCK_LOW_AND_ABOVE',\n * },\n * {\n * category: 'HARM_CATEGORY_DANGEROUS_CONTENT',\n * threshold: 'BLOCK_MEDIUM_AND_ABOVE',\n * },\n * {\n * category: 'HARM_CATEGORY_HARASSMENT',\n * threshold: 'BLOCK_ONLY_HIGH',\n * },\n * {\n * category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n * threshold: 'BLOCK_NONE',\n * },\n * ],\n * functionCallingConfig: {\n * mode: 'ANY',\n * }\n * }\n * ```\n */\nexport type GeminiConfig = z.infer<typeof GeminiConfigSchema>;\n\nexport const gemini10Pro = modelRef({\n name: 'vertexai/gemini-1.0-pro',\n info: {\n label: 'Vertex AI - Gemini Pro',\n versions: ['gemini-1.0-pro-001', 'gemini-1.0-pro-002'],\n supports: {\n multiturn: true,\n media: false,\n tools: true,\n systemRole: true,\n constrained: 'no-tools',\n toolChoice: true,\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini15Pro = modelRef({\n name: 'vertexai/gemini-1.5-pro',\n info: {\n label: 'Vertex AI - Gemini 1.5 Pro',\n versions: ['gemini-1.5-pro-001', 'gemini-1.5-pro-002'],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini15Flash = modelRef({\n name: 'vertexai/gemini-1.5-flash',\n info: {\n label: 'Vertex AI - Gemini 1.5 Flash',\n versions: ['gemini-1.5-flash-001', 'gemini-1.5-flash-002'],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini20Flash001 = modelRef({\n name: 'vertexai/gemini-2.0-flash-001',\n info: {\n label: 'Vertex AI - Gemini 2.0 Flash 001',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini20Flash = modelRef({\n name: 'vertexai/gemini-2.0-flash',\n info: {\n label: 'Vertex AI - Gemini 2.0 Flash',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini20FlashLite = modelRef({\n name: 'vertexai/gemini-2.0-flash-lite',\n info: {\n label: 'Vertex AI - Gemini 2.0 Flash Lite',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini20FlashLitePreview0205 = modelRef({\n name: 'vertexai/gemini-2.0-flash-lite-preview-02-05',\n info: {\n label: 'Vertex AI - Gemini 2.0 Flash Lite Preview 02-05',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini20ProExp0205 = modelRef({\n name: 'vertexai/gemini-2.0-pro-exp-02-05',\n info: {\n label: 'Vertex AI - Gemini 2.0 Flash Pro Experimental 02-05',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini25ProExp0325 = modelRef({\n name: 'vertexai/gemini-2.5-pro-exp-03-25',\n info: {\n label: 'Vertex AI - Gemini 2.5 Pro Experimental 03-25',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const gemini25ProPreview0325 = modelRef({\n name: 'vertexai/gemini-2.5-pro-preview-03-25',\n info: {\n label: 'Vertex AI - Gemini 2.5 Pro Preview 03-25',\n versions: [],\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n constrained: 'no-tools',\n },\n },\n configSchema: GeminiConfigSchema,\n});\n\nexport const GENERIC_GEMINI_MODEL = modelRef({\n name: 'vertexai/gemini',\n configSchema: GeminiConfigSchema,\n info: {\n label: 'Google Gemini',\n supports: {\n multiturn: true,\n media: true,\n tools: true,\n toolChoice: true,\n systemRole: true,\n },\n },\n});\n\nexport const SUPPORTED_V1_MODELS = {\n 'gemini-1.0-pro': gemini10Pro,\n};\n\nexport const SUPPORTED_V15_MODELS = {\n 'gemini-1.5-pro': gemini15Pro,\n 'gemini-1.5-flash': gemini15Flash,\n 'gemini-2.0-flash': gemini20Flash,\n 'gemini-2.0-flash-001': gemini20Flash001,\n 'gemini-2.0-flash-lite': gemini20FlashLite,\n 'gemini-2.0-flash-lite-preview-02-05': gemini20FlashLitePreview0205,\n 'gemini-2.0-pro-exp-02-05': gemini20ProExp0205,\n 'gemini-2.5-pro-exp-03-25': gemini25ProExp0325,\n 'gemini-2.5-pro-preview-03-25': gemini25ProPreview0325,\n};\n\nexport const SUPPORTED_GEMINI_MODELS = {\n ...SUPPORTED_V1_MODELS,\n ...SUPPORTED_V15_MODELS,\n} as const;\n\nfunction toGeminiRole(\n role: MessageData['role'],\n modelInfo?: ModelInfo\n): string {\n switch (role) {\n case 'user':\n return 'user';\n case 'model':\n return 'model';\n case 'system':\n if (modelInfo && modelInfo.supports?.systemRole) {\n // We should have already pulled out the supported system messages,\n // anything remaining is unsupported; throw an error.\n throw new Error(\n 'system role is only supported for a single message in the first position'\n );\n } else {\n throw new Error('system role is not supported');\n }\n case 'tool':\n return 'function';\n default:\n return 'user';\n }\n}\n\n/** @hidden */\nexport const toGeminiTool = (\n tool: z.infer<typeof ToolDefinitionSchema>\n): FunctionDeclaration => {\n const declaration: FunctionDeclaration = {\n name: tool.name.replace(/\\//g, '__'), // Gemini throws on '/' in tool name\n description: tool.description,\n parameters: convertSchemaProperty(tool.inputSchema),\n };\n return declaration;\n};\n\nconst toGeminiFileDataPart = (part: MediaPart): GeminiPart => {\n const media = part.media;\n if (media.url.startsWith('gs://') || media.url.startsWith('http')) {\n if (!media.contentType)\n throw new Error(\n 'Must supply contentType when using media from http(s):// or gs:// URLs.'\n );\n return {\n fileData: {\n mimeType: media.contentType,\n fileUri: media.url,\n },\n };\n } else if (media.url.startsWith('data:')) {\n const dataUrl = media.url;\n const b64Data = dataUrl.substring(dataUrl.indexOf(',')! + 1);\n const contentType =\n media.contentType ||\n dataUrl.substring(dataUrl.indexOf(':')! + 1, dataUrl.indexOf(';'));\n return { inlineData: { mimeType: contentType, data: b64Data } };\n }\n\n throw Error(\n 'Could not convert genkit part to gemini tool response part: missing file data'\n );\n};\n\nconst toGeminiToolRequestPart = (part: Part): GeminiPart => {\n if (!part?.toolRequest?.input) {\n throw Error(\n 'Could not convert genkit part to gemini tool response part: missing tool request data'\n );\n }\n return {\n functionCall: {\n name: part.toolRequest.name,\n args: part.toolRequest.input,\n },\n };\n};\n\nconst toGeminiToolResponsePart = (part: Part): GeminiPart => {\n if (!part?.toolResponse?.output) {\n throw Error(\n 'Could not convert genkit part to gemini tool response part: missing tool response data'\n );\n }\n return {\n functionResponse: {\n name: part.toolResponse.name,\n response: {\n name: part.toolResponse.name,\n content: part.toolResponse.output,\n },\n },\n };\n};\n\nexport function toGeminiSystemInstruction(message: MessageData): Content {\n return {\n role: 'user',\n parts: message.content.map(toGeminiPart),\n };\n}\n\nexport function toGeminiMessage(\n message: MessageData,\n modelInfo?: ModelInfo\n): Content {\n let sortedParts = message.content;\n if (message.role === 'tool') {\n sortedParts = [...message.content].sort((a, b) => {\n const aRef = a.toolResponse?.ref;\n const bRef = b.toolResponse?.ref;\n if (!aRef && !bRef) return 0;\n if (!aRef) return 1;\n if (!bRef) return -1;\n return parseInt(aRef, 10) - parseInt(bRef, 10);\n });\n }\n return {\n role: toGeminiRole(message.role, modelInfo),\n parts: sortedParts.map(toGeminiPart),\n };\n}\n\nfunction fromGeminiFinishReason(\n reason: GenerateContentCandidate['finishReason']\n): CandidateData['finishReason'] {\n if (!reason) return 'unknown';\n switch (reason) {\n case 'STOP':\n return 'stop';\n case 'MAX_TOKENS':\n return 'length';\n case 'SAFETY': // blocked for safety\n case 'RECITATION': // blocked for reciting training data\n return 'blocked';\n default:\n return 'unknown';\n }\n}\n\nfunction toGeminiPart(part: Part): GeminiPart {\n if (part.text) {\n return { text: part.text };\n } else if (part.media) {\n return toGeminiFileDataPart(part);\n } else if (part.toolRequest) {\n return toGeminiToolRequestPart(part);\n } else if (part.toolResponse) {\n return toGeminiToolResponsePart(part);\n } else {\n throw new Error('unsupported type');\n }\n}\n\nfunction fromGeminiInlineDataPart(part: GeminiPart): MediaPart {\n // Check if the required properties exist\n if (\n !part.inlineData ||\n !part.inlineData.hasOwnProperty('mimeType') ||\n !part.inlineData.hasOwnProperty('data')\n ) {\n throw new Error('Invalid GeminiPart: missing required properties');\n }\n const { mimeType, data } = part.inlineData;\n // Combine data and mimeType into a data URL\n const dataUrl = `data:${mimeType};base64,${data}`;\n return {\n media: {\n url: dataUrl,\n contentType: mimeType,\n },\n };\n}\n\nfunction fromGeminiFileDataPart(part: GeminiPart): MediaPart {\n if (\n !part.fileData ||\n !part.fileData.hasOwnProperty('mimeType') ||\n !part.fileData.hasOwnProperty('url')\n ) {\n throw new Error(\n 'Invalid Gemini File Data Part: missing required properties'\n );\n }\n\n return {\n media: {\n url: part.fileData?.fileUri,\n contentType: part.fileData?.mimeType,\n },\n };\n}\n\nfunction fromGeminiFunctionCallPart(part: GeminiPart, ref?: string): Part {\n if (!part.functionCall) {\n throw new Error(\n 'Invalid Gemini Function Call Part: missing function call data'\n );\n }\n return {\n toolRequest: {\n name: part.functionCall.name,\n input: part.functionCall.args,\n ref,\n },\n };\n}\n\nfunction fromGeminiFunctionResponsePart(part: GeminiPart, ref?: string): Part {\n if (!part.functionResponse) {\n throw new Error(\n 'Invalid Gemini Function Call Part: missing function call data'\n );\n }\n return {\n toolResponse: {\n name: part.functionResponse.name.replace(/__/g, '/'), // restore slashes\n output: part.functionResponse.response,\n ref,\n },\n };\n}\n\n// Converts vertex part to genkit part\nfunction fromGeminiPart(\n part: GeminiPart,\n jsonMode: boolean,\n ref?: string\n): Part {\n if (part.text !== undefined) return { text: part.text };\n if (part.inlineData) return fromGeminiInlineDataPart(part);\n if (part.fileData) return fromGeminiFileDataPart(part);\n if (part.functionCall) return fromGeminiFunctionCallPart(part, ref);\n if (part.functionResponse) return fromGeminiFunctionResponsePart(part, ref);\n\n throw new Error(\n 'Part type is unsupported/corrupted. Either data is missing or type cannot be inferred from type.'\n );\n}\nexport function fromGeminiCandidate(\n candidate: GenerateContentCandidate,\n jsonMode: boolean\n): CandidateData {\n const parts = candidate.content.parts || [];\n\n const genkitCandidate: CandidateData = {\n index: candidate.index || 0,\n message: {\n role: 'model',\n content: parts.map((part, index) => {\n return fromGeminiPart(part, jsonMode, index.toString());\n }),\n },\n finishReason: fromGeminiFinishReason(candidate.finishReason),\n finishMessage: candidate.finishMessage,\n custom: {\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n },\n };\n return genkitCandidate;\n}\n// Translate JSON schema to Vertex AI's format. Specifically, the type field needs be mapped.\n// Since JSON schemas can include nested arrays/objects, we have to recursively map the type field\n// in all nested fields.\nfunction convertSchemaProperty(property) {\n if (!property || !property.type) {\n return undefined;\n }\n const baseSchema = {} as Schema;\n if (property.description) {\n baseSchema.description = property.description;\n }\n if (property.enum) {\n baseSchema.enum = property.enum;\n }\n if (property.nullable) {\n baseSchema.nullable = property.nullable;\n }\n let propertyType;\n // nullable schema can ALSO be defined as, for example, type=['string','null']\n if (Array.isArray(property.type)) {\n const types = property.type as string[];\n if (types.includes('null')) {\n baseSchema.nullable = true;\n }\n // grab the type that's not `null`\n propertyType = types.find((t) => t !== 'null');\n } else {\n propertyType = property.type;\n }\n if (propertyType === 'object') {\n const nestedProperties = {};\n Object.keys(property.properties).forEach((key) => {\n nestedProperties[key] = convertSchemaProperty(property.properties[key]);\n });\n return {\n ...baseSchema,\n type: FunctionDeclarationSchemaType.OBJECT,\n properties: nestedProperties,\n required: property.required,\n };\n } else if (propertyType === 'array') {\n return {\n ...baseSchema,\n type: FunctionDeclarationSchemaType.ARRAY,\n items: convertSchemaProperty(property.items),\n };\n } else {\n const schemaType = FunctionDeclarationSchemaType[\n propertyType.toUpperCase()\n ] as FunctionDeclarationSchemaType;\n if (!schemaType) {\n throw new GenkitError({\n status: 'INVALID_ARGUMENT',\n message: `Unsupported property type ${propertyType.toUpperCase()}`,\n });\n }\n return {\n ...baseSchema,\n type: schemaType,\n };\n }\n}\n\nexport function cleanSchema(schema: JSONSchema): JSONSchema {\n const out = structuredClone(schema);\n for (const key in out) {\n if (key === '$schema' || key === 'additionalProperties') {\n delete out[key];\n continue;\n }\n if (typeof out[key] === 'object') {\n out[key] = cleanSchema(out[key]);\n }\n // Zod nullish() and picoschema optional fields will produce type `[\"string\", \"null\"]`\n // which is not supported by the model API. Convert them to just `\"string\"`.\n if (key === 'type' && Array.isArray(out[key])) {\n // find the first that's not `null`.\n out[key] = out[key].find((t) => t !== 'null');\n }\n }\n return out;\n}\n\n/**\n * Define a Vertex AI Gemini model.\n */\nexport function defineGeminiKnownModel(\n ai: Genkit,\n name: string,\n vertexClientFactory: (\n request: GenerateRequest<typeof GeminiConfigSchema>\n ) => VertexAI,\n options: PluginOptions,\n debugTraces?: boolean\n): ModelAction {\n const modelName = `vertexai/${name}`;\n\n const model: ModelReference<z.ZodTypeAny> = SUPPORTED_GEMINI_MODELS[name];\n if (!model) throw new Error(`Unsupported model: ${name}`);\n\n return defineGeminiModel({\n ai,\n modelName,\n version: name,\n modelInfo: model?.info,\n vertexClientFactory,\n options,\n debugTraces,\n });\n}\n\n/**\n * Define a Vertex AI Gemini model.\n */\nexport function defineGeminiModel({\n ai,\n modelName,\n version,\n modelInfo,\n vertexClientFactory,\n options,\n debugTraces,\n}: {\n ai: Genkit;\n modelName: string;\n version: string;\n modelInfo: ModelInfo | undefined;\n vertexClientFactory: (\n request: GenerateRequest<typeof GeminiConfigSchema>\n ) => VertexAI;\n options: PluginOptions;\n debugTraces?: boolean;\n}): ModelAction {\n const middlewares: ModelMiddleware[] = [];\n if (SUPPORTED_V1_MODELS[version]) {\n middlewares.push(simulateSystemPrompt());\n }\n if (modelInfo?.supports?.media) {\n // the gemini api doesn't support downloading media from http(s)\n middlewares.push(\n downloadRequestMedia({\n maxBytes: 1024 * 1024 * 20,\n filter: (part) => {\n try {\n const url = new URL(part.media.url);\n if (\n // Gemini can handle these URLs\n ['www.youtube.com', 'youtube.com', 'youtu.be'].includes(\n url.hostname\n )\n )\n return false;\n } catch {}\n return true;\n },\n })\n );\n }\n\n return ai.defineModel(\n {\n name: modelName,\n ...modelInfo,\n configSchema: GeminiConfigSchema,\n use: middlewares,\n },\n async (request, sendChunk) => {\n const vertex = vertexClientFactory(request);\n\n // Make a copy of messages to avoid side-effects\n const messages = [...request.messages];\n if (messages.length === 0) throw new Error('No messages provided.');\n\n // Handle system instructions separately\n let systemInstruction: Content | undefined = undefined;\n if (!SUPPORTED_V1_MODELS[version]) {\n const systemMessage = messages.find((m) => m.role === 'system');\n if (systemMessage) {\n messages.splice(messages.indexOf(systemMessage), 1);\n systemInstruction = toGeminiSystemInstruction(systemMessage);\n }\n }\n\n const tools = request.tools?.length\n ? [{ functionDeclarations: request.tools.map(toGeminiTool) }]\n : [];\n\n let toolConfig: ToolConfig | undefined;\n if (request?.config?.functionCallingConfig) {\n toolConfig = {\n functionCallingConfig: {\n allowedFunctionNames:\n request.config.functionCallingConfig.allowedFunctionNames,\n mode: toFunctionModeEnum(request.config.functionCallingConfig.mode),\n },\n };\n } else if (request.toolChoice) {\n toolConfig = {\n functionCallingConfig: {\n mode: toGeminiFunctionModeEnum(request.toolChoice),\n },\n };\n }\n\n // Cannot use tools and function calling at the same time\n const jsonMode =\n (request.output?.format === 'json' || !!request.output?.schema) &&\n tools.length === 0;\n\n let chatRequest: StartChatParams = {\n systemInstruction,\n tools,\n toolConfig,\n history: messages\n .slice(0, -1)\n .map((message) => toGeminiMessage(message, modelInfo)),\n generationConfig: {\n candidateCount: request.candidates || undefined,\n temperature: request.config?.temperature,\n maxOutputTokens: request.config?.maxOutputTokens,\n topK: request.config?.topK,\n topP: request.config?.topP,\n responseMimeType: jsonMode ? 'application/json' : undefined,\n stopSequences: request.config?.stopSequences,\n },\n safetySettings: request.config?.safetySettings,\n };\n\n // Handle cache\n const modelVersion = (request.config?.version || version) as string;\n const cacheConfigDetails = extractCacheConfig(request);\n\n const apiClient = new ApiClient(\n options.projectId!,\n options.location,\n 'v1beta1',\n new GoogleAuth(options.googleAuth!)\n );\n\n const { chatRequest: updatedChatRequest, cache } =\n await handleCacheIfNeeded(\n apiClient,\n request,\n chatRequest,\n modelVersion,\n cacheConfigDetails\n );\n\n let genModel: GenerativeModelPreview;\n\n if (jsonMode && request.output?.constrained) {\n updatedChatRequest.generationConfig!.responseSchema = cleanSchema(\n request.output.schema\n );\n }\n\n if (request.config?.googleSearchRetrieval) {\n updatedChatRequest.tools?.push({\n googleSearchRetrieval: request.config\n .googleSearchRetrieval as GoogleSearchRetrieval,\n });\n }\n\n if (request.config?.vertexRetrieval) {\n const vertexRetrieval = request.config.vertexRetrieval;\n const _projectId =\n vertexRetrieval.datastore.projectId || options.projectId;\n const _location =\n vertexRetrieval.datastore.location || options.location;\n const _dataStoreId = vertexRetrieval.datastore.dataStoreId;\n const datastore = `projects/${_projectId}/locations/${_location}/collections/default_collection/dataStores/${_dataStoreId}`;\n updatedChatRequest.tools?.push({\n retrieval: {\n vertexAiSearch: {\n datastore,\n },\n disableAttribution: vertexRetrieval.disableAttribution,\n },\n });\n }\n\n const msg = toGeminiMessage(messages[messages.length - 1], modelInfo);\n\n if (cache) {\n genModel = vertex.preview.getGenerativeModelFromCachedContent(\n cache,\n {\n model: modelVersion,\n },\n {\n apiClient: GENKIT_CLIENT_HEADER,\n }\n );\n } else {\n genModel = vertex.preview.getGenerativeModel(\n {\n model: modelVersion,\n },\n {\n apiClient: GENKIT_CLIENT_HEADER,\n }\n );\n }\n\n const callGemini = async () => {\n let response: GenerateContentResponse;\n\n // Handle streaming and non-streaming responses\n if (sendChunk) {\n const result = await genModel\n .startChat(updatedChatRequest)\n .sendMessageStream(msg.parts);\n\n for await (const item of result.stream) {\n (item as GenerateContentResponse).candidates?.forEach(\n (candidate) => {\n const c = fromGeminiCandidate(candidate, jsonMode);\n sendChunk({\n index: c.index,\n content: c.message.content,\n });\n }\n );\n }\n\n response = await result.response;\n } else {\n const result = await genModel\n .startChat(updatedChatRequest)\n .sendMessage(msg.parts);\n\n response = result.response;\n }\n\n if (!response.candidates?.length) {\n throw new GenkitError({\n status: 'FAILED_PRECONDITION',\n message: 'No valid candidates returned.',\n });\n }\n\n const candidateData = response.candidates.map((c) =>\n fromGeminiCandidate(c, jsonMode)\n );\n\n return {\n candidates: candidateData,\n custom: response,\n usage: {\n ...getBasicUsageStats(request.messages, candidateData),\n inputTokens: response.usageMetadata?.promptTokenCount,\n outputTokens: response.usageMetadata?.candidatesTokenCount,\n totalTokens: response.usageMetadata?.totalTokenCount,\n },\n };\n };\n\n // If debugTraces is enable, we wrap the actual model call with a span, add raw\n // API params as for input.\n return debugTraces\n ? await runInNewSpan(\n ai.registry,\n {\n metadata: {\n name: sendChunk ? 'sendMessageStream' : 'sendMessage',\n },\n },\n async (metadata) => {\n metadata.input = {\n sdk: '@google-cloud/vertexai',\n cache: cache,\n model: genModel.getModelName(),\n chatOptions: updatedChatRequest,\n parts: msg.parts,\n options,\n };\n const response = await callGemini();\n metadata.output = response.custom;\n return response;\n }\n )\n : await callGemini();\n }\n );\n}\n\n/** Converts mode from the config, which follows Gemini naming convention. */\nfunction toFunctionModeEnum(\n enumMode: string | undefined\n): FunctionCallingMode | undefined {\n if (enumMode === undefined) {\n return undefined;\n }\n switch (enumMode) {\n case 'MODE_UNSPECIFIED': {\n return FunctionCallingMode.MODE_UNSPECIFIED;\n }\n case 'ANY': {\n return FunctionCallingMode.ANY;\n }\n case 'AUTO': {\n return FunctionCallingMode.AUTO;\n }\n case 'NONE': {\n return FunctionCallingMode.NONE;\n }\n default:\n throw new Error(`unsupported function calling mode: ${enumMode}`);\n }\n}\n\n/** Converts mode from genkit tool choice. */\nfunction toGeminiFunctionModeEnum(\n genkitMode: 'auto' | 'required' | 'none'\n): FunctionCallingMode | undefined {\n if (genkitMode === undefined) {\n return undefined;\n }\n switch (genkitMode) {\n case 'required': {\n return FunctionCallingMode.ANY;\n }\n case 'auto': {\n return FunctionCallingMode.AUTO;\n }\n case 'none': {\n return FunctionCallingMode.NONE;\n }\n default:\n throw new Error(`unsupported function calling mode: ${genkitMode}`);\n }\n}\n"],"mappings":"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