{"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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","names":[]}