{"version":3,"file":"gemini.cjs","names":["GoogleAISafetyError","AIMessage","SystemMessage","HumanMessage","ToolMessage","ChatGenerationChunk","AIMessageChunk","schemaToGeminiParameters","GeminiSearchToolAttributes"],"sources":["../../src/utils/gemini.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"@langchain/core/utils/uuid\";\nimport {\n  ContentBlock,\n  AIMessage,\n  AIMessageChunk,\n  AIMessageChunkFields,\n  BaseMessage,\n  BaseMessageChunk,\n  BaseMessageFields,\n  MessageContent,\n  MessageContentComplex,\n  MessageContentImageUrl,\n  MessageContentText,\n  type StandardContentBlockConverter,\n  SystemMessage,\n  ToolMessage,\n  UsageMetadata,\n  isAIMessage,\n  parseBase64DataUrl,\n  isDataContentBlock,\n  convertToProviderContentBlock,\n  InputTokenDetails,\n  OutputTokenDetails,\n  ModalitiesTokenDetails,\n  HumanMessage,\n} from \"@langchain/core/messages\";\nimport {\n  ChatGeneration,\n  ChatGenerationChunk,\n  ChatResult,\n} from \"@langchain/core/outputs\";\nimport { StructuredToolParams } from \"@langchain/core/tools\";\nimport { isLangChainTool } from \"@langchain/core/utils/function_calling\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport {\n  GoogleLLMResponse,\n  GoogleAIModelParams,\n  GeminiPartText,\n  GeminiPartInlineData,\n  GeminiPartFileData,\n  GeminiPart,\n  GeminiRole,\n  GeminiContent,\n  GenerateContentResponseData,\n  GoogleAISafetyHandler,\n  GeminiPartFunctionCall,\n  GoogleAIAPI,\n  GeminiAPIConfig,\n  GeminiGroundingSupport,\n  GeminiResponseCandidate,\n  GeminiLogprobsResult,\n  GeminiLogprobsResultCandidate,\n  GeminiLogprobsTopCandidate,\n  ModalityTokenCount,\n  GeminiUrlContextMetadata,\n  GoogleSpeechConfig,\n  GoogleSpeechConfigSimplified,\n  GoogleSpeechSimplifiedLanguage,\n  GoogleSpeechVoiceLanguage,\n  GoogleSpeechVoice,\n  GoogleSpeechSpeakerName,\n  GoogleSpeakerVoiceConfig,\n  GeminiFunctionDeclaration,\n  GeminiGenerationConfig,\n  GeminiRequest,\n  GeminiSafetySetting,\n  GeminiTool,\n  GoogleAIModelRequestParams,\n  GoogleAIToolType,\n  GeminiSearchToolAttributes,\n} from \"../types.js\";\nimport { GoogleAISafetyError } from \"./safety.js\";\nimport { MediaBlob } from \"../experimental/utils/media_core.js\";\nimport { schemaToGeminiParameters } from \"./zod_to_gemini_parameters.js\";\n\nexport interface FunctionCall {\n  name: string;\n  arguments: string;\n}\n\nexport interface ToolCall {\n  id: string;\n  type: \"function\";\n  function: FunctionCall;\n}\n\nexport interface FunctionCallRaw {\n  name: string;\n  arguments: object;\n}\n\nexport interface ToolCallRaw {\n  id: string;\n  type: \"function\";\n  function: FunctionCallRaw;\n}\n\nexport interface DefaultGeminiSafetySettings {\n  errorFinish?: string[];\n}\n\nexport class DefaultGeminiSafetyHandler implements GoogleAISafetyHandler {\n  errorFinish = [\"SAFETY\", \"RECITATION\", \"OTHER\"];\n\n  constructor(settings?: DefaultGeminiSafetySettings) {\n    this.errorFinish = settings?.errorFinish ?? this.errorFinish;\n  }\n\n  handleDataPromptFeedback(\n    response: GoogleLLMResponse,\n    data: GenerateContentResponseData\n  ): GenerateContentResponseData {\n    // Check to see if our prompt was blocked in the first place\n    const promptFeedback = data?.promptFeedback;\n    const blockReason = promptFeedback?.blockReason;\n    if (blockReason) {\n      throw new GoogleAISafetyError(response, `Prompt blocked: ${blockReason}`);\n    }\n    return data;\n  }\n\n  handleDataFinishReason(\n    response: GoogleLLMResponse,\n    data: GenerateContentResponseData\n  ): GenerateContentResponseData {\n    const firstCandidate = data?.candidates?.[0];\n    const finishReason = firstCandidate?.finishReason;\n    if (this.errorFinish.includes(finishReason)) {\n      throw new GoogleAISafetyError(response, `Finish reason: ${finishReason}`);\n    }\n    return data;\n  }\n\n  handleData(\n    response: GoogleLLMResponse,\n    data: GenerateContentResponseData\n  ): GenerateContentResponseData {\n    let ret = data;\n    ret = this.handleDataPromptFeedback(response, ret);\n    ret = this.handleDataFinishReason(response, ret);\n    return ret;\n  }\n\n  handle(response: GoogleLLMResponse): GoogleLLMResponse {\n    let newdata;\n\n    if (\"nextChunk\" in response.data) {\n      // TODO: This is a stream. How to handle?\n      newdata = response.data;\n    } else if (Array.isArray(response.data)) {\n      // If it is an array, try to handle every item in the array\n      try {\n        newdata = response.data.map((item) => this.handleData(response, item));\n      } catch (xx) {\n        // oxlint-disable-next-line no-instanceof/no-instanceof\n        if (xx instanceof GoogleAISafetyError) {\n          throw new GoogleAISafetyError(response, xx.message);\n        } else {\n          throw xx;\n        }\n      }\n    } else {\n      const data = response.data as GenerateContentResponseData;\n      newdata = this.handleData(response, data);\n    }\n\n    return {\n      ...response,\n      data: newdata,\n    };\n  }\n}\n\nexport interface MessageGeminiSafetySettings extends DefaultGeminiSafetySettings {\n  msg?: string;\n  forceNewMessage?: boolean;\n}\n\nexport class MessageGeminiSafetyHandler extends DefaultGeminiSafetyHandler {\n  msg: string = \"\";\n\n  forceNewMessage = false;\n\n  constructor(settings?: MessageGeminiSafetySettings) {\n    super(settings);\n    this.msg = settings?.msg ?? this.msg;\n    this.forceNewMessage = settings?.forceNewMessage ?? this.forceNewMessage;\n  }\n\n  setMessage(data: GenerateContentResponseData): GenerateContentResponseData {\n    const ret = data;\n    if (\n      this.forceNewMessage ||\n      !data?.candidates?.[0]?.content?.parts?.length\n    ) {\n      ret.candidates = data.candidates ?? [];\n      ret.candidates[0] = data.candidates[0] ?? {};\n      ret.candidates[0].content = data.candidates[0].content ?? {};\n      ret.candidates[0].content = {\n        role: \"model\",\n        parts: [{ text: this.msg }],\n      };\n    }\n    return ret;\n  }\n\n  handleData(\n    response: GoogleLLMResponse,\n    data: GenerateContentResponseData\n  ): GenerateContentResponseData {\n    try {\n      return super.handleData(response, data);\n    } catch {\n      return this.setMessage(data);\n    }\n  }\n}\n\nconst extractMimeType = (\n  str: string\n): { mimeType: string; data: string } | null => {\n  if (str.startsWith(\"data:\")) {\n    return {\n      mimeType: str.split(\":\")[1].split(\";\")[0],\n      data: str.split(\",\")[1],\n    };\n  }\n  return null;\n};\n\n/**\n * Infers the MIME type from a URL based on its file extension.\n * This is used as a fallback when the MIME type is not provided.\n *\n * @param url - The URL to infer the MIME type from\n * @returns The inferred MIME type or undefined if it cannot be determined\n */\nfunction inferMimeTypeFromUrl(url: string): string | undefined {\n  const mimeTypeMap: Record<string, string> = {\n    jpg: \"image/jpeg\",\n    jpeg: \"image/jpeg\",\n    png: \"image/png\",\n    gif: \"image/gif\",\n    webp: \"image/webp\",\n    bmp: \"image/bmp\",\n    svg: \"image/svg+xml\",\n    ico: \"image/x-icon\",\n    tiff: \"image/tiff\",\n    tif: \"image/tiff\",\n  };\n\n  try {\n    // Extract the pathname from the URL\n    const pathname = new URL(url).pathname;\n    // Get the file extension (handle query params and fragments)\n    const extension = pathname.split(\".\").pop()?.toLowerCase().split(/[?#]/)[0];\n    return extension ? mimeTypeMap[extension] : undefined;\n  } catch {\n    // If URL parsing fails, try a simple extension extraction\n    const match = url.match(/\\.([a-zA-Z0-9]+)(?:[?#]|$)/);\n    if (match) {\n      const extension = match[1].toLowerCase();\n      return mimeTypeMap[extension];\n    }\n    return undefined;\n  }\n}\n\nexport function normalizeSpeechConfig(\n  config: GoogleSpeechConfig | GoogleSpeechConfigSimplified | undefined\n): GoogleSpeechConfig | undefined {\n  function isSpeechConfig(\n    config: GoogleSpeechConfig | GoogleSpeechConfigSimplified\n  ): config is GoogleSpeechConfig {\n    return (\n      typeof config === \"object\" &&\n      (Object.hasOwn(config, \"voiceConfig\") ||\n        Object.hasOwn(config, \"multiSpeakerVoiceConfig\"))\n    );\n  }\n\n  function hasLanguage(\n    config: GoogleSpeechConfigSimplified\n  ): config is GoogleSpeechSimplifiedLanguage {\n    return typeof config === \"object\" && Object.hasOwn(config, \"languageCode\");\n  }\n\n  function hasVoice(\n    config: GoogleSpeechSimplifiedLanguage\n  ): config is GoogleSpeechVoiceLanguage {\n    return Object.hasOwn(config, \"voice\");\n  }\n\n  if (typeof config === \"undefined\") {\n    return undefined;\n  }\n\n  // If this is already a GoogleSpeechConfig, just return it\n  if (isSpeechConfig(config)) {\n    return config;\n  }\n\n  let languageCode: string | undefined;\n  let voice: GoogleSpeechVoice;\n  if (hasLanguage(config)) {\n    languageCode = config.languageCode;\n    voice = hasVoice(config) ? config.voice : config.voices;\n  } else {\n    languageCode = undefined;\n    voice = config;\n  }\n\n  let ret: GoogleSpeechConfig;\n\n  if (typeof voice === \"string\") {\n    // They just provided the prebuilt voice configuration name. Use it.\n    ret = {\n      voiceConfig: {\n        prebuiltVoiceConfig: {\n          voiceName: voice,\n        },\n      },\n    };\n  } else {\n    // This is multi-speaker, so we have speaker/name pairs\n    // If we have just one (why?), turn it into an array for the moment\n    const voices: GoogleSpeechSpeakerName[] = Array.isArray(voice)\n      ? voice\n      : [voice];\n    // Go through all the speaker/name pairs and turn this into the voice config array\n    const speakerVoiceConfigs: GoogleSpeakerVoiceConfig[] = voices.map(\n      (v: GoogleSpeechSpeakerName): GoogleSpeakerVoiceConfig => ({\n        speaker: v.speaker,\n        voiceConfig: {\n          prebuiltVoiceConfig: {\n            voiceName: v.name,\n          },\n        },\n      })\n    );\n    // Create the multi-speaker voice configuration\n    ret = {\n      multiSpeakerVoiceConfig: {\n        speakerVoiceConfigs,\n      },\n    };\n  }\n\n  if (languageCode) {\n    ret.languageCode = languageCode;\n  }\n\n  return ret;\n}\n\nexport function getGeminiAPI(config?: GeminiAPIConfig): GoogleAIAPI {\n  function messageContentText(\n    content: MessageContentText\n  ): GeminiPartText | null {\n    if (content?.text && content?.text.length > 0) {\n      return {\n        text: content.text,\n      };\n    } else {\n      return null;\n    }\n  }\n\n  function messageContentImageUrlData(\n    content: MessageContentImageUrl\n  ): GeminiPartInlineData | GeminiPartFileData {\n    const url: string =\n      typeof content.image_url === \"string\"\n        ? content.image_url\n        : content.image_url.url;\n    if (!url) {\n      throw new Error(\"Missing Image URL\");\n    }\n\n    const mimeTypeAndData = extractMimeType(url);\n    if (mimeTypeAndData) {\n      return {\n        inlineData: mimeTypeAndData,\n      };\n    } else {\n      // Infer MIME type from URL extension\n      const mimeType = inferMimeTypeFromUrl(url) || \"image/png\";\n      return {\n        fileData: {\n          mimeType,\n          fileUri: url,\n        },\n      };\n    }\n  }\n\n  function messageContentImageUrl(\n    content: MessageContentImageUrl\n  ): GeminiPartInlineData | GeminiPartFileData {\n    const ret = messageContentImageUrlData(content);\n    supplementVideoMetadata(content, ret);\n    return ret;\n  }\n\n  async function blobToFileData(blob: MediaBlob): Promise<GeminiPartFileData> {\n    return {\n      fileData: {\n        fileUri: blob.path!,\n        mimeType: blob.mimetype,\n      },\n    };\n  }\n\n  async function fileUriContentToBlob(\n    uri: string\n  ): Promise<MediaBlob | undefined> {\n    return config?.mediaManager?.getMediaBlob(uri);\n  }\n\n  async function messageContentMediaData(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    content: Record<string, any>\n  ): Promise<GeminiPartInlineData | GeminiPartFileData> {\n    if (\"mimeType\" in content && \"data\" in content) {\n      return {\n        inlineData: {\n          mimeType: content.mimeType,\n          data: content.data,\n        },\n      };\n    } else if (\"mimeType\" in content && \"fileUri\" in content) {\n      return {\n        fileData: {\n          mimeType: content.mimeType,\n          fileUri: content.fileUri,\n        },\n      };\n    } else {\n      const uri = content.fileUri;\n      const blob = await fileUriContentToBlob(uri);\n      if (blob) {\n        return await blobToFileData(blob);\n      }\n    }\n\n    throw new Error(\n      `Invalid media content: ${JSON.stringify(content, null, 1)}`\n    );\n  }\n\n  function supplementVideoMetadata(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    content: MessageContentImageUrl | Record<string, any>,\n    ret: GeminiPartInlineData | GeminiPartFileData\n  ): GeminiPartInlineData | GeminiPartFileData {\n    // Add videoMetadata if defined\n    if (\"videoMetadata\" in content && typeof ret === \"object\") {\n      ret.videoMetadata = content.videoMetadata;\n    }\n    return ret;\n  }\n\n  async function messageContentMedia(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    content: Record<string, any>\n  ): Promise<GeminiPartInlineData | GeminiPartFileData> {\n    const ret = await messageContentMediaData(content);\n    supplementVideoMetadata(content, ret);\n    return ret;\n  }\n\n  function messageContentReasoning(\n    content: MessageContentReasoning\n  ): GeminiPartText | null {\n    if (content?.reasoning && content?.reasoning.length > 0) {\n      return {\n        text: content.reasoning,\n        thought: true,\n      };\n    } else {\n      return null;\n    }\n  }\n\n  const standardContentBlockConverter: StandardContentBlockConverter<{\n    text: GeminiPartText;\n    image: GeminiPartFileData | GeminiPartInlineData;\n    audio: GeminiPartFileData | GeminiPartInlineData;\n    file: GeminiPartFileData | GeminiPartInlineData | GeminiPartText;\n  }> = {\n    providerName: \"Google Gemini\",\n\n    fromStandardTextBlock(block) {\n      return {\n        text: block.text,\n      };\n    },\n\n    fromStandardImageBlock(block): GeminiPartFileData | GeminiPartInlineData {\n      if (block.source_type === \"url\") {\n        const data = parseBase64DataUrl({ dataUrl: block.url });\n        if (data) {\n          return {\n            inlineData: {\n              mimeType: data.mime_type,\n              data: data.data,\n            },\n          };\n        } else {\n          // Infer MIME type from URL if not provided\n          let mimeType = block.mime_type;\n          if (!mimeType || mimeType === \"\") {\n            mimeType = inferMimeTypeFromUrl(block.url) || \"image/png\";\n          }\n          return {\n            fileData: {\n              mimeType,\n              fileUri: block.url,\n            },\n          };\n        }\n      }\n\n      if (block.source_type === \"base64\") {\n        return {\n          inlineData: {\n            mimeType: block.mime_type || \"image/png\",\n            data: block.data,\n          },\n        };\n      }\n\n      throw new Error(`Unsupported source type: ${block.source_type}`);\n    },\n\n    fromStandardAudioBlock(block): GeminiPartFileData | GeminiPartInlineData {\n      if (block.source_type === \"url\") {\n        const data = parseBase64DataUrl({ dataUrl: block.url });\n        if (data) {\n          return {\n            inlineData: {\n              mimeType: data.mime_type,\n              data: data.data,\n            },\n          };\n        } else {\n          return {\n            fileData: {\n              mimeType: block.mime_type || \"audio/mpeg\",\n              fileUri: block.url,\n            },\n          };\n        }\n      }\n\n      if (block.source_type === \"base64\") {\n        return {\n          inlineData: {\n            mimeType: block.mime_type || \"audio/mpeg\",\n            data: block.data,\n          },\n        };\n      }\n\n      throw new Error(`Unsupported source type: ${block.source_type}`);\n    },\n\n    fromStandardFileBlock(\n      block\n    ): GeminiPartFileData | GeminiPartInlineData | GeminiPartText {\n      if (block.source_type === \"text\") {\n        return {\n          text: block.text,\n        };\n      }\n      if (block.source_type === \"url\") {\n        const data = parseBase64DataUrl({ dataUrl: block.url });\n        if (data) {\n          return {\n            inlineData: {\n              mimeType: data.mime_type,\n              data: data.data,\n            },\n          };\n        } else {\n          return {\n            fileData: {\n              mimeType: block.mime_type || \"application/octet-stream\",\n              fileUri: block.url,\n            },\n          };\n        }\n      }\n\n      if (block.source_type === \"base64\") {\n        return {\n          inlineData: {\n            mimeType: block.mime_type || \"application/octet-stream\",\n            data: block.data,\n          },\n        };\n      }\n      throw new Error(`Unsupported source type: ${block.source_type}`);\n    },\n  };\n\n  /**\n   * Converts a ContentBlock.Multimodal block (image, video, audio, file)\n   * to the appropriate GeminiPart format.\n   *\n   * Handles three data record variants:\n   *  - DataRecordBase64: has `data` property → GeminiPartInlineData\n   *  - DataRecordUrl: has `url` property → GeminiPartFileData (or GeminiPartInlineData for data: URLs)\n   *  - DataRecordFileId: has `fileId` property → not directly supported, throws\n   */\n  function multimodalContentBlockToPart(\n    block: ContentBlock.Multimodal.Data,\n    defaultMimeType: string\n  ): GeminiPartInlineData | GeminiPartFileData {\n    if (\"data\" in block && block.data !== undefined) {\n      // DataRecordBase64: inline base64 data\n      const data =\n        // oxlint-disable-next-line no-instanceof/no-instanceof\n        block.data instanceof Uint8Array\n          ? btoa(String.fromCharCode(...block.data))\n          : block.data;\n      return {\n        inlineData: {\n          mimeType: block.mimeType || defaultMimeType,\n          data,\n        },\n      };\n    }\n\n    if (\"url\" in block && block.url !== undefined) {\n      // DataRecordUrl: check if it's a data: URL first\n      const parsed = extractMimeType(block.url);\n      if (parsed) {\n        return {\n          inlineData: {\n            mimeType: parsed.mimeType,\n            data: parsed.data,\n          },\n        };\n      }\n      // Regular URL → fileData\n      const mimeType =\n        block.mimeType || inferMimeTypeFromUrl(block.url) || defaultMimeType;\n      return {\n        fileData: {\n          mimeType,\n          fileUri: block.url,\n        },\n      };\n    }\n\n    if (\"fileId\" in block && block.fileId !== undefined) {\n      throw new Error(\n        `ContentBlock.Multimodal fileId is not supported by Google Gemini. ` +\n          `Use a URL (e.g. gs:// URI) or base64 data instead.`\n      );\n    }\n\n    throw new Error(\n      `Invalid multimodal content block: must have \"data\", \"url\", or \"fileId\" property. ` +\n        `Received: ${JSON.stringify(block)}`\n    );\n  }\n\n  async function messageContentComplexToPart(\n    content: MessageContentComplex\n  ): Promise<GeminiPart | null> {\n    switch (content.type) {\n      case \"text\":\n        if (\"text\" in content) {\n          return messageContentText(content as MessageContentText);\n        }\n        break;\n      case \"image_url\":\n        if (\"image_url\" in content) {\n          // Type guard for MessageContentImageUrl\n          return messageContentImageUrl(content as MessageContentImageUrl);\n        }\n        break;\n      case \"media\":\n        return await messageContentMedia(content);\n      case \"reasoning\":\n        return messageContentReasoning(content as MessageContentReasoning);\n      case \"input_audio\":\n        if (\"input_audio\" in content) {\n          return {\n            inlineData: {\n              mimeType: `audio/${content.input_audio.format}`,\n              data: content.input_audio.data,\n            },\n          };\n        }\n        break;\n      case \"image\":\n        return multimodalContentBlockToPart(\n          content as ContentBlock.Multimodal.Image,\n          \"image/png\"\n        );\n      case \"video\":\n        return multimodalContentBlockToPart(\n          content as ContentBlock.Multimodal.Video,\n          \"video/mp4\"\n        );\n      case \"audio\":\n        return multimodalContentBlockToPart(\n          content as ContentBlock.Multimodal.Audio,\n          \"audio/mpeg\"\n        );\n      case \"file\":\n        return multimodalContentBlockToPart(\n          content as ContentBlock.Multimodal.File,\n          \"application/octet-stream\"\n        );\n      case \"text-plain\":\n        // text-plain blocks can have an inline text property\n        if (\n          \"text\" in content &&\n          typeof (content as ContentBlock.Multimodal.PlainText).text ===\n            \"string\"\n        ) {\n          return { text: (content as ContentBlock.Multimodal.PlainText).text! };\n        }\n        return multimodalContentBlockToPart(\n          content as ContentBlock.Multimodal.PlainText,\n          \"text/plain\"\n        );\n      default:\n        throw new Error(\n          `Unsupported type \"${\n            content.type\n          }\" received while converting message to message parts: ${JSON.stringify(\n            content\n          )}`\n        );\n    }\n    throw new Error(\n      `Cannot coerce \"${content.type}\" message part into a string.`\n    );\n  }\n\n  async function messageContentComplexToParts(\n    content: MessageContentComplex[]\n  ): Promise<(GeminiPart | null)[]> {\n    const contents = content.map((m) =>\n      isDataContentBlock(m)\n        ? convertToProviderContentBlock(m, standardContentBlockConverter)\n        : messageContentComplexToPart(m)\n    );\n    return Promise.all(contents);\n  }\n\n  async function messageContentToParts(\n    content: MessageContent\n  ): Promise<GeminiPart[]> {\n    // Convert a string to a text type MessageContent if needed\n    const messageContent: MessageContentComplex[] =\n      typeof content === \"string\"\n        ? [\n            {\n              type: \"text\",\n              text: content,\n            },\n          ]\n        : content;\n\n    // Get all of the parts, even those that don't correctly resolve\n    const allParts = await messageContentComplexToParts(messageContent);\n\n    // Remove any invalid parts\n    const parts: GeminiPart[] = allParts.reduce(\n      (acc: GeminiPart[], val: GeminiPart | null | undefined) => {\n        if (val) {\n          return [...acc, val];\n        } else {\n          return acc;\n        }\n      },\n      []\n    );\n\n    return parts;\n  }\n\n  function messageToolCallsToParts(toolCalls: ToolCall[]): GeminiPart[] {\n    if (!toolCalls || toolCalls.length === 0) {\n      return [];\n    }\n\n    return toolCalls.map((tool: ToolCall) => {\n      let args = {};\n      if (tool?.function?.arguments) {\n        const argStr = tool.function.arguments;\n        args = JSON.parse(argStr);\n      }\n      return {\n        functionCall: {\n          name: tool.function.name,\n          args,\n        },\n      };\n    });\n  }\n\n  function messageKwargsToParts(kwargs: Record<string, unknown>): GeminiPart[] {\n    const ret: GeminiPart[] = [];\n\n    if (kwargs?.tool_calls) {\n      ret.push(...messageToolCallsToParts(kwargs.tool_calls as ToolCall[]));\n    }\n\n    return ret;\n  }\n\n  async function roleMessageToContent(\n    role: GeminiRole,\n    message: BaseMessage\n  ): Promise<GeminiContent[]> {\n    const contentParts: GeminiPart[] = await messageContentToParts(\n      message.content\n    );\n    let toolParts: GeminiPart[];\n    if (isAIMessage(message) && !!message.tool_calls?.length) {\n      toolParts = message.tool_calls.map(\n        (toolCall): GeminiPart => ({\n          functionCall: {\n            name: toolCall.name,\n            args: toolCall.args,\n          },\n        })\n      );\n    } else {\n      toolParts = messageKwargsToParts(message.additional_kwargs);\n    }\n    const parts: GeminiPart[] = [...contentParts, ...toolParts];\n\n    // Ensure at least one part exists to prevent Gemini API 400 errors\n    // when a message has empty text content and no tool calls.\n    // This commonly happens when an AI message with empty content\n    // (e.g. during a tool call) is passed back as conversation history.\n    if (parts.length === 0) {\n      parts.push({ text: \"\" });\n    }\n\n    const signatures: string[] =\n      (message?.additional_kwargs?.signatures as string[]) ?? [];\n    if (signatures.length === parts.length) {\n      for (let co = 0; co < signatures.length; co += 1) {\n        const signature = signatures[co];\n        if (signature && signature.length > 0) {\n          parts[co].thoughtSignature = signature;\n        }\n      }\n    }\n\n    return [\n      {\n        role,\n        parts,\n      },\n    ];\n  }\n\n  async function systemMessageToContent(\n    message: SystemMessage\n  ): Promise<GeminiContent[]> {\n    return config?.useSystemInstruction\n      ? roleMessageToContent(\"system\", message)\n      : [\n          ...(await roleMessageToContent(\"user\", message)),\n          ...(await roleMessageToContent(\"model\", new AIMessage(\"Ok\"))),\n        ];\n  }\n\n  function toolMessageToContent(\n    message: ToolMessage,\n    prevMessage: BaseMessage\n  ): GeminiContent[] {\n    const contentStr =\n      typeof message.content === \"string\"\n        ? message.content\n        : Array.isArray(message.content)\n          ? (message.content as ContentBlock[]).reduce(\n              (acc: string, content: ContentBlock) => {\n                if (content.type === \"text\") {\n                  return acc + content.text;\n                } else {\n                  return acc;\n                }\n              },\n              \"\"\n            )\n          : JSON.stringify(message.content);\n    // Hacky :(\n    const responseName =\n      (isAIMessage(prevMessage) && !!prevMessage.tool_calls?.length\n        ? prevMessage.tool_calls[0].name\n        : prevMessage.name) ?? message.tool_call_id;\n    try {\n      const content = JSON.parse(contentStr);\n      return [\n        {\n          role: \"function\",\n          parts: [\n            {\n              functionResponse: {\n                name: responseName,\n                response: { content },\n              },\n            },\n          ],\n        },\n      ];\n    } catch (_) {\n      return [\n        {\n          role: \"function\",\n          parts: [\n            {\n              functionResponse: {\n                name: responseName,\n                response: { content: contentStr },\n              },\n            },\n          ],\n        },\n      ];\n    }\n  }\n\n  async function baseMessageToContent(\n    message: BaseMessage,\n    prevMessage: BaseMessage | undefined\n  ): Promise<GeminiContent[]> {\n    if (SystemMessage.isInstance(message)) {\n      return systemMessageToContent(message);\n    } else if (HumanMessage.isInstance(message)) {\n      return roleMessageToContent(\"user\", message);\n    } else if (AIMessage.isInstance(message)) {\n      return roleMessageToContent(\"model\", message);\n    } else if (ToolMessage.isInstance(message)) {\n      if (!prevMessage) {\n        throw new Error(\n          \"Tool messages cannot be the first message passed to the model.\"\n        );\n      }\n      return toolMessageToContent(message, prevMessage);\n    } else {\n      console.log(`Unsupported message type: ${message.type}`);\n      return [];\n    }\n  }\n\n  type MessageContentReasoning = {\n    type: \"reasoning\";\n    reasoning: string;\n  };\n\n  function thoughtPartToMessageContent(\n    part: GeminiPartText\n  ): MessageContentReasoning {\n    return {\n      type: \"reasoning\",\n      reasoning: part.text,\n    };\n  }\n\n  function textPartToMessageContent(part: GeminiPartText): MessageContentText {\n    return {\n      type: \"text\",\n      text: part.text,\n    };\n  }\n\n  function inlineDataPartToMessageContentImage(\n    part: GeminiPartInlineData\n  ): MessageContentImageUrl {\n    return {\n      type: \"image_url\",\n      image_url: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`,\n    };\n  }\n\n  function inlineDataPartToMessageContentMedia(\n    part: GeminiPartInlineData\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  ): Record<string, any> {\n    return {\n      type: \"media\",\n      mimeType: part.inlineData.mimeType,\n      data: part.inlineData.data,\n    };\n  }\n\n  function inlineDataPartToMessageContent(\n    part: GeminiPartInlineData\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  ): MessageContentImageUrl | Record<string, any> {\n    const mimeType = part?.inlineData?.mimeType ?? \"\";\n    if (mimeType.startsWith(\"image\")) {\n      return inlineDataPartToMessageContentImage(part);\n    } else {\n      return inlineDataPartToMessageContentMedia(part);\n    }\n  }\n\n  function fileDataPartToMessageContent(\n    part: GeminiPartFileData\n  ): MessageContentImageUrl {\n    return {\n      type: \"image_url\",\n      image_url: part.fileData.fileUri,\n    };\n  }\n\n  function partsToMessageContent(parts: GeminiPart[]): MessageContent {\n    return parts\n      .map((part: GeminiPart): ContentBlock | null => {\n        if (part === undefined || part === null) {\n          return null;\n        } else if (part.thought) {\n          return thoughtPartToMessageContent(part as GeminiPartText);\n        } else if (\"text\" in part) {\n          return textPartToMessageContent(part);\n        } else if (\"inlineData\" in part) {\n          return inlineDataPartToMessageContent(part) as ContentBlock;\n        } else if (\"fileData\" in part) {\n          return fileDataPartToMessageContent(part);\n        } else {\n          return null;\n        }\n      })\n      .reduce((acc, content) => {\n        if (content) {\n          acc.push(content);\n        }\n        return acc;\n      }, [] as ContentBlock[]);\n  }\n\n  function toolRawToTool(raw: ToolCallRaw): ToolCall {\n    return {\n      id: raw.id,\n      type: raw.type,\n      function: {\n        name: raw.function.name,\n        arguments: JSON.stringify(raw.function.arguments),\n      },\n    };\n  }\n\n  function functionCallPartToToolRaw(\n    part: GeminiPartFunctionCall\n  ): ToolCallRaw {\n    return {\n      id: uuidv4().replace(/-/g, \"\"),\n      type: \"function\",\n      function: {\n        name: part.functionCall.name,\n        arguments: part.functionCall.args ?? {},\n      },\n    };\n  }\n\n  function partsToToolsRaw(parts: GeminiPart[]): ToolCallRaw[] {\n    return parts\n      .map((part: GeminiPart) => {\n        if (part === undefined || part === null) {\n          return null;\n        } else if (\"functionCall\" in part) {\n          return functionCallPartToToolRaw(part);\n        } else {\n          return null;\n        }\n      })\n      .reduce((acc, content) => {\n        if (content) {\n          acc.push(content);\n        }\n        return acc;\n      }, [] as ToolCallRaw[]);\n  }\n\n  function toolsRawToTools(raws: ToolCallRaw[]): ToolCall[] {\n    return raws.map((raw) => toolRawToTool(raw));\n  }\n\n  function responseToGenerateContentResponseData(\n    response: GoogleLLMResponse\n  ): GenerateContentResponseData {\n    if (\"nextChunk\" in response.data) {\n      throw new Error(\"Cannot convert Stream to GenerateContentResponseData\");\n    } else if (Array.isArray(response.data)) {\n      // Collapse the array of response data as if it was a single one\n      return response.data.reduce(\n        (\n          acc: GenerateContentResponseData,\n          val: GenerateContentResponseData\n        ): GenerateContentResponseData => {\n          // Add all the parts\n          // FIXME: Handle other candidates?\n          const valParts = val?.candidates?.[0]?.content?.parts ?? [];\n          acc.candidates[0].content.parts.push(...valParts);\n\n          // FIXME: Merge promptFeedback and safety settings\n          acc.promptFeedback = val.promptFeedback;\n          return acc;\n        }\n      );\n    } else {\n      return response.data as GenerateContentResponseData;\n    }\n  }\n\n  function responseToParts(response: GoogleLLMResponse): GeminiPart[] {\n    const responseData = responseToGenerateContentResponseData(response);\n    const parts = responseData?.candidates?.[0]?.content?.parts ?? [];\n    return parts;\n  }\n\n  function partToText(part: GeminiPart): string {\n    return \"text\" in part ? part.text : \"\";\n  }\n\n  function responseToString(response: GoogleLLMResponse): string {\n    const parts = responseToParts(response);\n    const ret: string = parts.reduce((acc, part) => {\n      const val = partToText(part);\n      return acc + val;\n    }, \"\");\n    return ret;\n  }\n\n  function safeResponseTo<RetType>(\n    response: GoogleLLMResponse,\n    responseTo: (response: GoogleLLMResponse) => RetType\n  ): RetType {\n    const safetyHandler =\n      config?.safetyHandler ?? new DefaultGeminiSafetyHandler();\n    try {\n      const safeResponse = safetyHandler.handle(response);\n      return responseTo(safeResponse);\n    } catch (xx) {\n      // oxlint-disable-next-line no-instanceof/no-instanceof\n      if (xx instanceof GoogleAISafetyError) {\n        const ret = responseTo(xx.response);\n        xx.reply = ret;\n      }\n      throw xx;\n    }\n  }\n\n  function safeResponseToString(response: GoogleLLMResponse): string {\n    return safeResponseTo(response, responseToString);\n  }\n\n  type Logprob = {\n    token: string;\n    logprob: number;\n    bytes: number[];\n    top_logprobs?: Omit<Logprob, \"top_logprobs\">[];\n  };\n\n  type LogprobContent = {\n    content: Logprob[];\n  };\n\n  function logprobResultToLogprob(\n    result: GeminiLogprobsResultCandidate\n  ): Omit<Logprob, \"top_logprobs\"> {\n    const token = result?.token;\n    const logprob = result?.logProbability;\n    const encoder = new TextEncoder();\n    const bytes = Array.from(encoder.encode(token));\n    return {\n      token,\n      logprob,\n      bytes,\n    };\n  }\n\n  function candidateToLogprobs(\n    candidate: GeminiResponseCandidate\n  ): LogprobContent | undefined {\n    const logprobs: GeminiLogprobsResult = candidate?.logprobsResult;\n    const chosenTokens: GeminiLogprobsResultCandidate[] =\n      logprobs?.chosenCandidates ?? [];\n    const topTokens: GeminiLogprobsTopCandidate[] =\n      logprobs?.topCandidates ?? [];\n    const content: Logprob[] = [];\n    for (let co = 0; co < chosenTokens.length; co += 1) {\n      const chosen = chosenTokens[co];\n      const top = topTokens[co]?.candidates ?? [];\n      const logprob: Logprob = logprobResultToLogprob(chosen);\n      logprob.top_logprobs = top.map((l) => logprobResultToLogprob(l));\n      content.push(logprob);\n    }\n    return {\n      content,\n    };\n  }\n\n  function candidateToUrlContextMetadata(\n    candidate: GeminiResponseCandidate\n  ): GeminiUrlContextMetadata | undefined {\n    const retrieval =\n      candidate?.urlRetrievalMetadata?.urlRetrievalContexts ?? [];\n    const context = candidate?.urlContextMetadata?.urlMetadata ?? [];\n    const all = [...retrieval, ...context];\n    if (all.length === 0) {\n      return undefined;\n    } else {\n      return {\n        urlMetadata: all,\n      };\n    }\n  }\n\n  function addModalityCounts(\n    modalityTokenCounts: ModalityTokenCount[],\n    details: InputTokenDetails | OutputTokenDetails\n  ): void {\n    modalityTokenCounts?.forEach((modalityTokenCount) => {\n      const { modality, tokenCount } = modalityTokenCount;\n      const modalityLc: keyof ModalitiesTokenDetails =\n        modality.toLowerCase() as keyof ModalitiesTokenDetails;\n      const currentCount = details[modalityLc] ?? 0;\n      details[modalityLc] = currentCount + tokenCount;\n    });\n  }\n\n  function responseToUsageMetadata(\n    response: GoogleLLMResponse\n  ): UsageMetadata | undefined {\n    if (\"usageMetadata\" in response.data) {\n      const data: GenerateContentResponseData = response?.data;\n      const usageMetadata = data?.usageMetadata;\n\n      const input_tokens = usageMetadata.promptTokenCount ?? 0;\n      const candidatesTokenCount = usageMetadata.candidatesTokenCount ?? 0;\n      const thoughtsTokenCount = usageMetadata.thoughtsTokenCount ?? 0;\n      const output_tokens = candidatesTokenCount + thoughtsTokenCount;\n      const total_tokens =\n        usageMetadata.totalTokenCount ?? input_tokens + output_tokens;\n\n      const input_token_details: InputTokenDetails = {};\n      addModalityCounts(usageMetadata.promptTokensDetails, input_token_details);\n      if (typeof usageMetadata?.cachedContentTokenCount === \"number\") {\n        input_token_details.cache_read = usageMetadata.cachedContentTokenCount;\n      }\n\n      const output_token_details: OutputTokenDetails = {};\n      addModalityCounts(\n        usageMetadata?.candidatesTokensDetails,\n        output_token_details\n      );\n      if (typeof usageMetadata?.thoughtsTokenCount === \"number\") {\n        output_token_details.reasoning = usageMetadata.thoughtsTokenCount;\n      }\n\n      const ret: UsageMetadata = {\n        input_tokens,\n        output_tokens,\n        total_tokens,\n        input_token_details,\n        output_token_details,\n      };\n      return ret;\n    }\n    return undefined;\n  }\n\n  function responseToGenerationInfo(response: GoogleLLMResponse) {\n    const data =\n      Array.isArray(response.data) && response.data[0]\n        ? response.data[0]\n        : response.data &&\n            (response.data as GenerateContentResponseData).candidates\n          ? (response.data as GenerateContentResponseData)\n          : undefined;\n    if (!data) {\n      return {};\n    }\n\n    const finish_reason = data.candidates[0]?.finishReason;\n\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    const ret: Record<string, any> = {\n      safety_ratings: data.candidates[0]?.safetyRatings?.map((rating) => ({\n        category: rating.category,\n        probability: rating.probability,\n        probability_score: rating.probabilityScore,\n        severity: rating.severity,\n        severity_score: rating.severityScore,\n      })),\n      citation_metadata: data.candidates[0]?.citationMetadata,\n      grounding_metadata: data.candidates[0]?.groundingMetadata,\n      finish_reason,\n      finish_message: data.candidates[0]?.finishMessage,\n      url_context_metadata: candidateToUrlContextMetadata(data.candidates[0]),\n      avgLogprobs: data.candidates[0]?.avgLogprobs,\n      logprobs: candidateToLogprobs(data.candidates[0]),\n    };\n\n    // Only add the usage_metadata on the last chunk\n    // sent while streaming (see issue 8102).\n    if (typeof finish_reason === \"string\") {\n      ret.usage_metadata = responseToUsageMetadata(response);\n    }\n\n    return ret;\n  }\n\n  function responseToChatGeneration(\n    response: GoogleLLMResponse\n  ): ChatGenerationChunk {\n    return new ChatGenerationChunk({\n      text: responseToString(response),\n      message: partToMessageChunk(responseToParts(response)[0]),\n      generationInfo: responseToGenerationInfo(response),\n    });\n  }\n\n  function safeResponseToChatGeneration(\n    response: GoogleLLMResponse\n  ): ChatGenerationChunk {\n    return safeResponseTo(response, responseToChatGeneration);\n  }\n\n  function chunkToString(chunk: BaseMessageChunk): string {\n    if (chunk === null) {\n      return \"\";\n    } else if (typeof chunk.content === \"string\") {\n      return chunk.content;\n    } else if (chunk.content.length === 0) {\n      return \"\";\n    } else if (chunk.content[0].type === \"text\") {\n      return chunk.content[0].text as string;\n    } else {\n      throw new Error(`Unexpected chunk: ${chunk}`);\n    }\n  }\n\n  function partToMessageChunk(part: GeminiPart): BaseMessageChunk {\n    const fields = partsToBaseMessageChunkFields([part]);\n    if (typeof fields.content === \"string\") {\n      return new AIMessageChunk(fields);\n    } else if (fields.content?.every((item) => item.type === \"text\")) {\n      const newContent = fields.content\n        .map((item) => (\"text\" in item ? item.text : \"\"))\n        .join(\"\");\n      return new AIMessageChunk({\n        ...fields,\n        content: newContent,\n        response_metadata: {\n          ...fields.response_metadata,\n          model_provider: \"google-vertexai\",\n        },\n      });\n    }\n    return new AIMessageChunk(fields);\n  }\n\n  function partToChatGeneration(part: GeminiPart): ChatGeneration {\n    const message = partToMessageChunk(part);\n    const text = partToText(part);\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    const generationInfo: Record<string, any> = {};\n\n    return new ChatGenerationChunk({\n      text,\n      message,\n      generationInfo,\n    });\n  }\n\n  function groundingSupportByPart(\n    groundingSupports?: GeminiGroundingSupport[]\n  ): GeminiGroundingSupport[][] {\n    const ret: GeminiGroundingSupport[][] = [];\n\n    if (!groundingSupports || groundingSupports.length === 0) {\n      return [];\n    }\n\n    groundingSupports?.forEach((groundingSupport) => {\n      const segment = groundingSupport?.segment;\n      const partIndex = segment?.partIndex ?? 0;\n      if (ret[partIndex]) {\n        ret[partIndex].push(groundingSupport);\n      } else {\n        ret[partIndex] = [groundingSupport];\n      }\n    });\n\n    return ret;\n  }\n\n  function responseToGroundedChatGenerations(\n    response: GoogleLLMResponse\n  ): ChatGeneration[] {\n    const parts = responseToParts(response);\n\n    if (parts.length === 0) {\n      return [];\n    }\n\n    // Citation and grounding information connected to each part / ChatGeneration\n    // to make sure they are available in downstream filters.\n    const candidate = (response?.data as GenerateContentResponseData)\n      ?.candidates?.[0];\n    const groundingMetadata = candidate?.groundingMetadata;\n    const citationMetadata = candidate?.citationMetadata;\n    const groundingParts = groundingSupportByPart(\n      groundingMetadata?.groundingSupports\n    );\n\n    const ret = parts.map((part, index) => {\n      const gen = partToChatGeneration(part);\n      if (!gen.generationInfo) {\n        gen.generationInfo = {};\n      }\n      if (groundingMetadata) {\n        gen.generationInfo.groundingMetadata = groundingMetadata;\n        const groundingPart = groundingParts[index];\n        if (groundingPart) {\n          gen.generationInfo.groundingSupport = groundingPart;\n        }\n      }\n      if (citationMetadata) {\n        gen.generationInfo.citationMetadata = citationMetadata;\n      }\n      return gen;\n    });\n\n    return ret;\n  }\n\n  type GenerationTypes = {\n    content: ChatGeneration[];\n    reasoning: ChatGeneration[];\n  };\n\n  function combineContent(\n    gen: ChatGeneration[],\n    forceComplex: boolean = false\n  ): MessageContent {\n    const allString = gen.every(\n      (item) => typeof item.message.content === \"string\"\n    );\n    if (allString && !forceComplex) {\n      // Everything is a string, and we don't want to force it to return\n      // MessageContentComplex[], so concatenate the content into one string\n      return gen.map((item) => item.message.content).join(\"\");\n    } else {\n      // We either have complex types, or we want to force them, so turn\n      // it into an array of complex types.\n      const ret: ContentBlock[] = [];\n      gen.forEach((item) => {\n        if (typeof item.message.content === \"string\") {\n          // If this is a string, turn it into a text type\n          ret.push({\n            type: \"text\",\n            text: item.message.content,\n          });\n        } else {\n          // Otherwise, add all the complex types to what we're returning\n          item.message.content.forEach((c) => {\n            ret.push(c);\n          });\n        }\n      });\n      return ret;\n    }\n  }\n\n  function combineText(gen: ChatGeneration[]): string {\n    return gen.map((item) => item.text ?? \"\").join(\"\");\n  }\n\n  /*\n   * We don't really need the entire AIMessageChunk here, but it is\n   * a conventient way to combine all the Tool Calling information.\n   */\n  function combineToolCalls(gen: ChatGeneration[]): AIMessageChunk {\n    let ret = new AIMessageChunk(\"\");\n\n    gen.forEach((item: ChatGeneration) => {\n      const message: AIMessageChunk = item?.message as AIMessageChunk;\n      ret = concat(ret, message);\n    });\n\n    return ret;\n  }\n\n  function combineAdditionalKwargs(\n    gen: ChatGeneration[]\n  ): Record<string, unknown> {\n    const ret: Record<string, unknown> = {};\n\n    gen.forEach((item: ChatGeneration) => {\n      const message: AIMessageChunk = item?.message as AIMessageChunk;\n      const kwargs = message?.additional_kwargs ?? {};\n      const keys = Object.keys(kwargs);\n      keys.forEach((key) => {\n        const value = kwargs[key];\n        if (\n          Object.hasOwn(ret, key) &&\n          Array.isArray(ret[key]) &&\n          Array.isArray(value)\n        ) {\n          (ret[key] as Array<unknown>).push(...value);\n        } else {\n          ret[key] = value;\n        }\n      });\n    });\n\n    return ret;\n  }\n\n  function combineGenerations(\n    generations: ChatGeneration[],\n    response: GoogleLLMResponse\n  ): ChatGeneration[] {\n    const gen: GenerationTypes = splitGenerationTypes(generations, response);\n    const combinedContent: MessageContent = combineContent(gen.content);\n    const combinedText = combineText(gen.content);\n    const combinedToolCalls = combineToolCalls(gen.content);\n    const kwargs = combineAdditionalKwargs(gen.content);\n    const lastContent = gen.content[gen.content.length - 1];\n\n    // Add usage metadata\n    const usage_metadata = responseToUsageMetadata(response);\n\n    // Add thinking / reasoning\n    // if (gen.reasoning && gen.reasoning.length > 0) {\n    //   kwargs.reasoning_content = combineContent(gen.reasoning, true);\n    // }\n\n    // Build the message and the generation chunk to return\n    const message = new AIMessageChunk({\n      content: combinedContent,\n      additional_kwargs: kwargs,\n      response_metadata: {\n        model_provider: \"google-vertexai\",\n      },\n      usage_metadata,\n      tool_calls: combinedToolCalls.tool_calls,\n      invalid_tool_calls: combinedToolCalls.invalid_tool_calls,\n    });\n    return [\n      new ChatGenerationChunk({\n        message,\n        text: combinedText,\n        generationInfo: lastContent.generationInfo,\n      }),\n    ];\n  }\n\n  function splitGenerationTypes(\n    generations: ChatGeneration[],\n    _response: GoogleLLMResponse\n  ): GenerationTypes {\n    const content: ChatGeneration[] = [];\n    const reasoning: ChatGeneration[] = [];\n\n    generations.forEach((gen) => {\n      if (gen?.generationInfo?.thought) {\n        reasoning.push(gen);\n      } else {\n        content.push(gen);\n      }\n    });\n\n    return {\n      content,\n      reasoning,\n    };\n  }\n\n  /**\n   * Although this returns an array, only the first (or maybe last)\n   * element in the array is used. So we need to combine them into\n   * just one element that contains everything we need.\n   * @param response\n   */\n  function responseToChatGenerations(\n    response: GoogleLLMResponse\n  ): ChatGeneration[] {\n    const generations = responseToGroundedChatGenerations(response);\n\n    if (generations.length === 0) {\n      return [];\n    }\n\n    const ret = combineGenerations(generations, response);\n\n    // Add logprobs information to the message\n    const candidate = (response?.data as GenerateContentResponseData)\n      ?.candidates?.[0];\n    const avgLogprobs = candidate?.avgLogprobs;\n    const logprobs = candidateToLogprobs(candidate);\n    if (logprobs) {\n      ret[0].message.response_metadata = {\n        model_provider: \"google-vertexai\",\n        ...ret[0].message.response_metadata,\n        logprobs,\n        avgLogprobs,\n      };\n    }\n\n    return ret;\n  }\n\n  function responseToBaseMessageFields(\n    response: GoogleLLMResponse\n  ): BaseMessageFields {\n    const parts = responseToParts(response);\n    return partsToBaseMessageChunkFields(parts);\n  }\n\n  function partsToSignatures(parts: GeminiPart[]): string[] {\n    return parts.map((part: GeminiPart) => part?.thoughtSignature ?? \"\");\n  }\n\n  function partsToBaseMessageChunkFields(\n    parts: GeminiPart[]\n  ): AIMessageChunkFields {\n    const fields: AIMessageChunkFields = {\n      content: partsToMessageContent(parts),\n      tool_call_chunks: [],\n      tool_calls: [],\n      invalid_tool_calls: [],\n      response_metadata: {\n        model_provider: \"google-vertexai\",\n      },\n    };\n    fields.additional_kwargs = {};\n\n    const rawTools = partsToToolsRaw(parts);\n    if (rawTools.length > 0) {\n      const tools = toolsRawToTools(rawTools);\n      for (const tool of tools) {\n        fields.tool_call_chunks?.push({\n          name: tool.function.name,\n          args: tool.function.arguments,\n          id: tool.id,\n          type: \"tool_call_chunk\",\n        });\n\n        try {\n          fields.tool_calls?.push({\n            name: tool.function.name,\n            args: JSON.parse(tool.function.arguments),\n            id: tool.id,\n          });\n          // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        } catch (e: any) {\n          fields.invalid_tool_calls?.push({\n            name: tool.function.name,\n            args: tool.function.arguments,\n            id: tool.id,\n            error: e.message,\n            type: \"invalid_tool_call\",\n          });\n        }\n      }\n      fields.additional_kwargs.tool_calls = tools;\n    }\n\n    fields.additional_kwargs.signatures = partsToSignatures(parts);\n\n    return fields;\n  }\n\n  function responseToBaseMessage(response: GoogleLLMResponse): BaseMessage {\n    const fields = responseToBaseMessageFields(response);\n    return new AIMessage(fields);\n  }\n\n  function safeResponseToBaseMessage(response: GoogleLLMResponse): BaseMessage {\n    return safeResponseTo(response, responseToBaseMessage);\n  }\n\n  function responseToChatResult(response: GoogleLLMResponse): ChatResult {\n    const generations = responseToChatGenerations(response);\n    return {\n      generations,\n      llmOutput: responseToGenerationInfo(response),\n    };\n  }\n\n  function safeResponseToChatResult(response: GoogleLLMResponse): ChatResult {\n    return safeResponseTo(response, responseToChatResult);\n  }\n\n  function inputType(\n    input: MessageContent | BaseMessage[]\n  ): \"MessageContent\" | \"BaseMessageArray\" {\n    if (typeof input === \"string\") {\n      return \"MessageContent\";\n    } else {\n      const firstItem: BaseMessage | MessageContentComplex = input[0];\n      if (Object.hasOwn(firstItem, \"content\")) {\n        return \"BaseMessageArray\";\n      } else {\n        return \"MessageContent\";\n      }\n    }\n  }\n\n  async function formatMessageContents(\n    input: MessageContent,\n    _parameters: GoogleAIModelParams\n  ): Promise<GeminiContent[]> {\n    const parts = await messageContentToParts!(input);\n    const contents: GeminiContent[] = [\n      {\n        role: \"user\", // Required by Vertex AI\n        parts,\n      },\n    ];\n    return contents;\n  }\n\n  async function formatBaseMessageContents(\n    input: BaseMessage[],\n    _parameters: GoogleAIModelParams\n  ): Promise<GeminiContent[]> {\n    const inputPromises: Promise<GeminiContent[]>[] = input.map((msg, i) =>\n      baseMessageToContent!(msg, input[i - 1])\n    );\n    const inputs = await Promise.all(inputPromises);\n\n    return inputs.reduce((acc, cur) => {\n      // Filter out the system content\n      if (cur.every((content) => content.role === \"system\")) {\n        return acc;\n      }\n\n      // Combine adjacent function messages\n      if (\n        cur[0]?.role === \"function\" &&\n        acc.length > 0 &&\n        acc[acc.length - 1].role === \"function\"\n      ) {\n        acc[acc.length - 1].parts = [\n          ...acc[acc.length - 1].parts,\n          ...cur[0].parts,\n        ];\n      } else {\n        acc.push(...cur);\n      }\n\n      return acc;\n    }, [] as GeminiContent[]);\n  }\n\n  async function formatContents(\n    input: MessageContent | BaseMessage[],\n    parameters: GoogleAIModelRequestParams\n  ): Promise<GeminiContent[]> {\n    const it = inputType(input);\n    switch (it) {\n      case \"MessageContent\":\n        return formatMessageContents(input as MessageContent, parameters);\n      case \"BaseMessageArray\":\n        return formatBaseMessageContents(input as BaseMessage[], parameters);\n      default:\n        throw new Error(`Unknown input type \"${it}\": ${input}`);\n    }\n  }\n\n  function formatGenerationConfig(\n    parameters: GoogleAIModelRequestParams\n  ): GeminiGenerationConfig {\n    const ret: GeminiGenerationConfig = {\n      temperature: parameters.temperature,\n      topK: parameters.topK,\n      topP: parameters.topP,\n      seed: parameters.seed,\n      presencePenalty: parameters.presencePenalty,\n      frequencyPenalty: parameters.frequencyPenalty,\n      maxOutputTokens: parameters.maxOutputTokens,\n      stopSequences: parameters.stopSequences,\n      responseMimeType: parameters.responseSchema\n        ? \"application/json\"\n        : parameters.responseMimeType,\n      responseSchema: parameters.responseSchema,\n      responseModalities: parameters.responseModalities,\n      speechConfig: normalizeSpeechConfig(parameters.speechConfig),\n    };\n\n    // Add the logprobs if explicitly set\n    if (typeof parameters.logprobs !== \"undefined\") {\n      ret.responseLogprobs = parameters.logprobs;\n      if (\n        parameters.logprobs &&\n        typeof parameters.topLogprobs !== \"undefined\"\n      ) {\n        ret.logprobs = parameters.topLogprobs;\n      }\n    }\n\n    // Add thinking configuration if explicitly set\n    // Note that you cannot have thinkingBudget set to 0 and includeThoughts true\n    if (\n      typeof parameters.maxReasoningTokens !== \"undefined\" ||\n      typeof parameters.thinkingLevel !== \"undefined\" ||\n      typeof parameters.reasoningLevel !== \"undefined\"\n    ) {\n      ret.thinkingConfig = {};\n\n      if (typeof parameters.maxReasoningTokens !== \"undefined\") {\n        const includeThoughts = parameters.maxReasoningTokens !== 0;\n        ret.thinkingConfig.thinkingBudget = parameters.maxReasoningTokens;\n        ret.thinkingConfig.includeThoughts = includeThoughts;\n      }\n\n      // Map reasoningLevel to thinkingLevel if provided\n      if (typeof parameters.reasoningLevel !== \"undefined\") {\n        const levelMap: Record<string, string> = {\n          minimal: \"MINIMAL\",\n          low: \"LOW\",\n          medium: \"MEDIUM\",\n          high: \"HIGH\",\n        };\n        ret.thinkingConfig.thinkingLevel = levelMap[parameters.reasoningLevel];\n      }\n\n      // Direct thinkingLevel takes precedence over reasoningLevel\n      if (typeof parameters.thinkingLevel !== \"undefined\") {\n        ret.thinkingConfig.thinkingLevel = parameters.thinkingLevel;\n      }\n    }\n\n    // Remove any undefined properties, so we don't send them\n    let attribute: keyof GeminiGenerationConfig;\n    for (attribute in ret) {\n      if (ret[attribute] === undefined) {\n        delete ret[attribute];\n      }\n    }\n\n    return ret;\n  }\n\n  function formatSafetySettings(\n    parameters: GoogleAIModelRequestParams\n  ): GeminiSafetySetting[] {\n    return parameters.safetySettings ?? [];\n  }\n\n  async function formatBaseMessageSystemInstruction(\n    input: BaseMessage[]\n  ): Promise<GeminiContent> {\n    let ret = {} as GeminiContent;\n    for (let index = 0; index < input.length; index += 1) {\n      const message = input[index];\n      if (message.getType() === \"system\") {\n        // For system types, we only want it if it is the first message,\n        // if it appears anywhere else, it should be an error.\n        if (index === 0) {\n          ret = (await baseMessageToContent!(message, undefined))[0];\n        } else {\n          throw new Error(\n            \"System messages are only permitted as the first passed message.\"\n          );\n        }\n      }\n    }\n\n    return ret;\n  }\n\n  async function formatSystemInstruction(\n    input: MessageContent | BaseMessage[]\n  ): Promise<GeminiContent> {\n    if (!config?.useSystemInstruction) {\n      return {} as GeminiContent;\n    }\n\n    const it = inputType(input);\n    switch (it) {\n      case \"BaseMessageArray\":\n        return formatBaseMessageSystemInstruction(input as BaseMessage[]);\n      default:\n        return {} as GeminiContent;\n    }\n  }\n\n  function structuredToolToFunctionDeclaration(\n    tool: StructuredToolParams\n  ): GeminiFunctionDeclaration {\n    const jsonSchema = schemaToGeminiParameters(tool.schema);\n    return {\n      name: tool.name,\n      description: tool.description ?? `A function available to call.`,\n      parameters: jsonSchema,\n    };\n  }\n\n  function searchToolName(tool: GeminiTool): string | undefined {\n    for (const name of GeminiSearchToolAttributes) {\n      if (name in tool) {\n        return name;\n      }\n    }\n    return undefined;\n  }\n\n  function cleanGeminiTool(tool: GeminiTool): GeminiTool {\n    const orig = searchToolName(tool);\n    const adj = config?.googleSearchToolAdjustment;\n    if (orig && adj && adj !== orig) {\n      return {\n        [adj as string]: {},\n      };\n    } else {\n      return tool;\n    }\n  }\n\n  function formatTools(parameters: GoogleAIModelRequestParams): GeminiTool[] {\n    const tools: GoogleAIToolType[] | undefined = parameters?.tools;\n    if (!tools || tools.length === 0) {\n      return [];\n    }\n\n    // Group all LangChain tools into a single functionDeclarations array.\n    // Gemini Tools may be normalized to different tool names\n    const langChainTools: StructuredToolParams[] = [];\n    const otherTools: GeminiTool[] = [];\n    tools.forEach((tool) => {\n      if (isLangChainTool(tool)) {\n        langChainTools.push(tool);\n      } else {\n        otherTools.push(cleanGeminiTool(tool as GeminiTool));\n      }\n    });\n\n    const result: GeminiTool[] = [...otherTools];\n\n    if (langChainTools.length > 0) {\n      result.push({\n        functionDeclarations: langChainTools.map(\n          structuredToolToFunctionDeclaration\n        ),\n      });\n    }\n\n    return result;\n  }\n\n  /**\n   * Checks whether the tools array contains a mix of server-side built-in\n   * tools (e.g. googleSearch, codeExecution) and function declarations.\n   * The Gemini API requires `toolConfig.includeServerSideToolInvocations`\n   * in that case, otherwise it returns HTTP 400.\n   * See https://ai.google.dev/gemini-api/docs/tool-combination\n   */\n  function mixesBuiltinAndFunctionTools(tools: GeminiTool[]): boolean {\n    let hasBuiltin = false;\n    let hasFunctionDeclarations = false;\n    for (const tool of tools) {\n      if (tool.functionDeclarations && tool.functionDeclarations.length > 0) {\n        hasFunctionDeclarations = true;\n      } else {\n        hasBuiltin = true;\n      }\n      if (hasBuiltin && hasFunctionDeclarations) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  function formatToolConfig(\n    parameters: GoogleAIModelRequestParams,\n    tools?: GeminiTool[]\n  ): GeminiRequest[\"toolConfig\"] | undefined {\n    const needsServerSideToolInvocations =\n      tools && tools.length > 1 && mixesBuiltinAndFunctionTools(tools);\n\n    let config: GeminiRequest[\"toolConfig\"] | undefined;\n\n    if (parameters.tool_choice && typeof parameters.tool_choice === \"string\") {\n      if ([\"auto\", \"any\", \"none\"].includes(parameters.tool_choice)) {\n        config = {\n          functionCallingConfig: {\n            mode: parameters.tool_choice as \"auto\" | \"any\" | \"none\",\n            allowedFunctionNames: parameters.allowed_function_names,\n          },\n        };\n      } else {\n        // force tool choice to be a single function name in case of structured output\n        config = {\n          functionCallingConfig: {\n            mode: \"any\",\n            allowedFunctionNames: [parameters.tool_choice],\n          },\n        };\n      }\n    }\n\n    if (needsServerSideToolInvocations) {\n      config = config ?? {};\n      config.includeServerSideToolInvocations = true;\n    }\n\n    return config;\n  }\n\n  async function formatData(\n    input: unknown,\n    parameters: GoogleAIModelRequestParams\n  ): Promise<GeminiRequest> {\n    const typedInput = input as MessageContent | BaseMessage[];\n    const contents = await formatContents(typedInput, parameters);\n    const generationConfig = formatGenerationConfig(parameters);\n    const tools = formatTools(parameters);\n    const toolConfig = formatToolConfig(parameters, tools);\n    const safetySettings = formatSafetySettings(parameters);\n    const systemInstruction = await formatSystemInstruction(typedInput);\n\n    const ret: GeminiRequest = {\n      contents,\n      generationConfig,\n    };\n    if (tools && tools.length) {\n      ret.tools = tools;\n    }\n    if (toolConfig) {\n      ret.toolConfig = toolConfig;\n    }\n    if (safetySettings && safetySettings.length) {\n      ret.safetySettings = safetySettings;\n    }\n    if (\n      systemInstruction?.role &&\n      systemInstruction?.parts &&\n      systemInstruction?.parts?.length\n    ) {\n      ret.systemInstruction = systemInstruction;\n    }\n    if (parameters.cachedContent) {\n      ret.cachedContent = parameters.cachedContent;\n    }\n    if (parameters.labels && Object.keys(parameters.labels).length > 0) {\n      ret.labels = parameters.labels;\n    }\n    return ret;\n  }\n\n  return {\n    messageContentToParts,\n    baseMessageToContent,\n    responseToString: safeResponseToString,\n    responseToChatGeneration: safeResponseToChatGeneration,\n    chunkToString,\n    responseToBaseMessage: safeResponseToBaseMessage,\n    responseToChatResult: safeResponseToChatResult,\n    formatData,\n  };\n}\n\nexport function validateGeminiParams(params: GoogleAIModelParams): void {\n  if (params.maxOutputTokens && params.maxOutputTokens < 0) {\n    throw new Error(\"`maxOutputTokens` must be a positive integer\");\n  }\n  if (typeof params.maxReasoningTokens !== \"undefined\") {\n    if (typeof params.maxOutputTokens !== \"undefined\") {\n      if (params.maxReasoningTokens >= params.maxOutputTokens) {\n        throw new Error(\n          \"`maxOutputTokens` must be greater than `maxReasoningTokens`\"\n        );\n      }\n    }\n  }\n\n  if (\n    params.temperature &&\n    (params.temperature < 0 || params.temperature > 2)\n  ) {\n    throw new Error(\"`temperature` must be in the range of [0.0,2.0]\");\n  }\n\n  if (params.topP && (params.topP < 0 || params.topP > 1)) {\n    throw new Error(\"`topP` must be in the range of [0.0,1.0]\");\n  }\n\n  if (params.topK && params.topK < 0) {\n    throw new Error(\"`topK` must be a positive integer\");\n  }\n}\n\nexport function isModelGemini(modelName: string): boolean {\n  return modelName.toLowerCase().startsWith(\"gemini\");\n}\n\nexport function isModelGemma(modelName: string): boolean {\n  return modelName.toLowerCase().startsWith(\"gemma\");\n}\n"],"mappings":"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"}