{"version":3,"sources":["../../src/common/interaction-converters.ts"],"sourcesContent":["/**\n * Copyright 2026 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  GenerateResponseData,\n  GenerationUsage,\n  GenkitError,\n  MessageData,\n  Operation,\n  Part,\n  z,\n} from 'genkit';\nimport { ToolDefinition } from 'genkit/model';\nimport {\n  AudioContent,\n  CodeExecutionCallStep,\n  CodeExecutionResultStep,\n  Content,\n  DocumentContent,\n  FunctionCallContent,\n  FunctionCallStep,\n  FunctionResultContent,\n  FunctionResultStep,\n  GeminiInteraction,\n  GoogleSearchCallStep,\n  GoogleSearchResultStep,\n  ImageContent,\n  InteractionFileSearchTool,\n  InteractionFunctionTool,\n  InteractionGoogleSearchTool,\n  InteractionSafetySetting,\n  InteractionTool,\n  InteractionToolChoiceConfig,\n  ModelGenerationConfig,\n  ResponseModality,\n  SpeechAnnotation,\n  SpeechConfig,\n  Step,\n  StepDeltaData,\n  TextAnnotationSchema,\n  TextContent,\n  ThoughtContent,\n  ThoughtStep,\n  Usage,\n  VideoContent,\n} from './interaction-types.mjs';\nimport { isObject } from './types.mjs';\nimport {\n  appendToWavData,\n  camelToSnakeCase,\n  cleanSchema,\n  convertObjectKeysToSnakeCase,\n  extractMimeType,\n  interactionErrorCodeToGenkitStatus,\n  isInteractionContentBlockCode,\n  stripLeadingId3Tags,\n  toSnakeCaseObj,\n} from './utils.mjs';\n\n/**\n * Ensures that all tool requests and responses in a list of messages have unique reference IDs.\n *\n * This function performs two passes:\n * 1. Assigns generated IDs to tool requests that lack a `ref`.\n * 2. Assigns matching IDs to tool responses that lack a `ref`, assuming they correspond\n *    sequentially to the requests. If a response has no matching request, it gets an orphaned ID.\n *\n * @param messages - The list of messages to process.\n * @returns A deep copy of the messages with tool IDs ensured.\n */\nexport function ensureToolIds(messages: MessageData[]): MessageData[] {\n  const generatedIds: string[] = [];\n  let nextIdCounter = 0;\n\n  // Deep copy to avoid mutating original request messages\n  const newMessages = structuredClone(messages) as MessageData[];\n\n  // First pass: find ToolRequests without ref\n  for (const message of newMessages) {\n    for (const part of message.content) {\n      if (part.toolRequest && !part.toolRequest.ref) {\n        const newId = `genkit-auto-id-${nextIdCounter++}`;\n        part.toolRequest.ref = newId;\n        generatedIds.push(newId);\n      }\n    }\n  }\n\n  // Second pass: find ToolResponses without ref and assign from queue\n  // Note: This assumes responses are in the same order as requests.\n  for (const message of newMessages) {\n    for (const part of message.content) {\n      if (part.toolResponse && !part.toolResponse.ref) {\n        const id = generatedIds.shift();\n        if (id) {\n          part.toolResponse.ref = id;\n        } else {\n          // No matching request found (or queue empty).\n          // Generate unique one to avoid empty string rejection.\n          part.toolResponse.ref = `genkit-orphan-id-${nextIdCounter++}`;\n        }\n      }\n    }\n  }\n\n  return newMessages;\n}\n\n/**\n * Converts a Genkit ToolDefinition to an InteractionTool format.\n *\n * Maps the name, description, and input schema (cleaned) to the interaction tool structure.\n *\n * @param tool - The Genkit tool definition.\n * @returns The converted InteractionTool.\n */\nexport function toInteractionTool(tool: ToolDefinition): InteractionTool {\n  const func: InteractionFunctionTool = {\n    type: 'function',\n    name: tool.name,\n    description: tool.description,\n  };\n  if (tool.inputSchema) {\n    func.parameters = cleanSchema(tool.inputSchema);\n  }\n  return func;\n}\n\nexport function toInteractionConfigTool(toolRaw: unknown): InteractionTool {\n  if (!isObject(toolRaw)) {\n    throw new Error(\n      `Invalid tool configuration: Expected an object, got ${typeof toolRaw}`\n    );\n  }\n  const tool = toolRaw;\n\n  if ('googleSearch' in tool || 'google_search' in tool) {\n    return toInteractionGoogleSearch(tool.googleSearch || tool.google_search);\n  }\n  if ('codeExecution' in tool || 'code_execution' in tool) {\n    const config = tool.codeExecution || tool.code_execution;\n    if (config === true || config === undefined) {\n      return { type: 'code_execution' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for codeExecution tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    return {\n      type: 'code_execution',\n      ...toSnakeCaseObj(config),\n    };\n  }\n  if ('fileSearch' in tool || 'file_search' in tool) {\n    const config = tool.fileSearch || tool.file_search;\n    if (config === true || config === undefined) {\n      return { type: 'file_search' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for fileSearch tool: Expected object, got ${typeof config}`\n      );\n    }\n    const result: InteractionFileSearchTool = { type: 'file_search' };\n\n    const fileSearchStoreNames =\n      config.fileSearchStoreNames || config.file_search_store_names;\n    const restFileSearch = { ...config };\n    delete restFileSearch.fileSearchStoreNames;\n    delete restFileSearch.file_search_store_names;\n\n    if (fileSearchStoreNames !== undefined) {\n      if (\n        !Array.isArray(fileSearchStoreNames) ||\n        !fileSearchStoreNames.every((n) => typeof n === 'string')\n      ) {\n        throw new Error('fileSearchStoreNames must be an array of strings.');\n      }\n      result.file_search_store_names = fileSearchStoreNames;\n    }\n    return {\n      ...result,\n      ...toSnakeCaseObj(restFileSearch),\n    };\n  }\n  if ('urlContext' in tool) {\n    const config = tool.urlContext;\n    if (config === true || config === undefined) {\n      return { type: 'url_context' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for urlContext tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    return {\n      type: 'url_context',\n      ...toSnakeCaseObj(config),\n    };\n  }\n  if ('googleMaps' in tool) {\n    const config = tool.googleMaps;\n    if (config === true || config === undefined) {\n      return { type: 'google_maps' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for googleMaps tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    return {\n      type: 'google_maps',\n      ...toSnakeCaseObj(config),\n    };\n  }\n  if ('computerUse' in tool) {\n    const config = tool.computerUse;\n    if (config === true || config === undefined) {\n      return { type: 'computer_use' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for computerUse tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    return {\n      type: 'computer_use',\n      ...toSnakeCaseObj(config),\n    };\n  }\n  if ('retrieval' in tool) {\n    const config = tool.retrieval;\n    if (config === true || config === undefined) {\n      return { type: 'retrieval' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for retrieval tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    return {\n      type: 'retrieval',\n      ...toSnakeCaseObj(config),\n    };\n  }\n  if ('mcpServer' in tool) {\n    const config = tool.mcpServer;\n    if (config === true || config === undefined) {\n      return { type: 'mcp_server' };\n    }\n    if (!isObject(config)) {\n      throw new Error(\n        `Invalid configuration for mcpServer tool: Expected object or true, got ${typeof config}`\n      );\n    }\n    const snakeConfig = toSnakeCaseObj(config);\n    if (\n      Array.isArray(snakeConfig.allowed_tools) &&\n      snakeConfig.allowed_tools.length > 0 &&\n      typeof snakeConfig.allowed_tools[0] === 'string'\n    ) {\n      snakeConfig.allowed_tools = [{ tools: snakeConfig.allowed_tools }];\n    }\n    return {\n      type: 'mcp_server',\n      ...snakeConfig,\n    };\n  }\n\n  // Pass through any other tool that names its own `type`, in snake_case.\n  const { type, ...rest } = toSnakeCaseObj(tool);\n  if (typeof type !== 'string') {\n    throw new Error(\n      `Unsupported tool configuration: ${JSON.stringify(tool)}. ` +\n        'Use a built-in tool key (e.g. googleSearch, codeExecution) or set `type`.'\n    );\n  }\n  return { type, ...rest };\n}\n\n/**\n * Copies a `retrievalConfig.latLng` user location onto the Interactions\n * `google_maps` tools, which take `latitude`/`longitude` directly (there is no\n * retrieval config on the Interactions path). A location already set on a tool\n * is kept.\n *\n * @returns Whether there was a `google_maps` tool to apply the location to.\n */\nexport function applyLatLngToGoogleMapsTools(\n  tools: InteractionTool[],\n  latLng: { latitude?: number; longitude?: number }\n): boolean {\n  let found = false;\n  tools.forEach((tool, i) => {\n    if (tool.type !== 'google_maps') return;\n    found = true;\n    if ('latitude' in tool || 'longitude' in tool) return;\n    tools[i] = {\n      ...tool,\n      ...(latLng.latitude !== undefined ? { latitude: latLng.latitude } : {}),\n      ...(latLng.longitude !== undefined\n        ? { longitude: latLng.longitude }\n        : {}),\n    };\n  });\n  return found;\n}\n\n/**\n * Picks the messages to send to the Interactions API and the interaction to\n * continue, if any.\n *\n * Without `store`, the server keeps no history, so every message is sent.\n * With `store`, the last model message's `metadata.interactionId` is\n * continued and only the newer messages are sent. An explicit\n * `previousInteractionId` (which requires `store`) overrides the metadata;\n * messages up to the last model message are still left out.\n *\n * @throws GenkitError (INVALID_ARGUMENT) if `previousInteractionId` is set\n *  without `store`.\n */\nexport function selectInteractionInput(\n  messages: MessageData[],\n  store: boolean,\n  previousInteractionIdFromConfig?: string\n): { messages: MessageData[]; previousInteractionId?: string } {\n  if (previousInteractionIdFromConfig && !store) {\n    throw new GenkitError({\n      status: 'INVALID_ARGUMENT',\n      message: 'store must be true when previousInteractionId is set.',\n    });\n  }\n\n  if (previousInteractionIdFromConfig) {\n    for (let i = messages.length - 1; i >= 0; i--) {\n      if (messages[i].role === 'model') {\n        return {\n          messages: messages.slice(i + 1),\n          previousInteractionId: previousInteractionIdFromConfig,\n        };\n      }\n    }\n    return { messages, previousInteractionId: previousInteractionIdFromConfig };\n  }\n\n  if (store) {\n    for (let i = messages.length - 1; i >= 0; i--) {\n      const prevId = messages[i]?.metadata?.interactionId;\n      if (\n        messages[i].role === 'model' &&\n        prevId &&\n        typeof prevId === 'string'\n      ) {\n        return {\n          messages: messages.slice(i + 1),\n          previousInteractionId: prevId,\n        };\n      }\n    }\n  }\n  return { messages };\n}\n\n/**\n * Converts `functionCallingConfig` (or, without it, the request's\n * `toolChoice`) to the Interactions `generation_config.tool_choice`.\n * Returns `undefined` when neither sets anything.\n */\nexport function toInteractionToolChoice(\n  functionCallingConfig?: { mode?: string; allowedFunctionNames?: string[] },\n  toolChoice?: string\n): InteractionToolChoiceConfig | undefined {\n  if (functionCallingConfig) {\n    const mode = functionCallingConfig.mode?.toLowerCase();\n    const validMode = mode && mode !== 'mode_unspecified' ? mode : undefined;\n    if (!validMode && !functionCallingConfig.allowedFunctionNames?.length) {\n      return undefined;\n    }\n    return {\n      allowed_tools: {\n        ...(validMode ? { mode: validMode } : {}),\n        ...(functionCallingConfig.allowedFunctionNames\n          ? { tools: functionCallingConfig.allowedFunctionNames }\n          : {}),\n      },\n    };\n  }\n  if (toolChoice) {\n    return {\n      allowed_tools: { mode: toolChoice === 'required' ? 'any' : toolChoice },\n    };\n  }\n  return undefined;\n}\n\nexport function toInteractionGoogleSearch(\n  gs: boolean | unknown\n): InteractionGoogleSearchTool {\n  const result: InteractionGoogleSearchTool = { type: 'google_search' };\n\n  if (gs === true || gs === undefined) {\n    return result;\n  }\n\n  if (!isObject(gs)) {\n    throw new Error(\n      `Invalid configuration for googleSearch tool: Expected object or true, got ${typeof gs}`\n    );\n  }\n\n  const searchTypesObj = gs.searchTypes || gs.search_types;\n  if (searchTypesObj !== undefined) {\n    const searchTypes = new Set<string>();\n\n    if (Array.isArray(searchTypesObj)) {\n      for (const type of searchTypesObj) {\n        if (typeof type === 'string') {\n          if (type === 'webSearch' || type === 'web_search') {\n            searchTypes.add('web_search');\n          } else if (type === 'imageSearch' || type === 'image_search') {\n            searchTypes.add('image_search');\n          } else if (\n            type === 'enterpriseWebSearch' ||\n            type === 'enterprise_web_search'\n          ) {\n            searchTypes.add('enterprise_web_search');\n          } else {\n            // Passthrough for any unknown string elements\n            searchTypes.add(camelToSnakeCase(type));\n          }\n        } else {\n          throw new Error(\n            `Invalid search type: Expected string, got ${typeof type}`\n          );\n        }\n      }\n    } else if (isObject(searchTypesObj)) {\n      for (const [key, value] of Object.entries(searchTypesObj)) {\n        if (value) {\n          if (key === 'webSearch' || key === 'web_search') {\n            searchTypes.add('web_search');\n          } else if (key === 'imageSearch' || key === 'image_search') {\n            searchTypes.add('image_search');\n          } else if (\n            key === 'enterpriseWebSearch' ||\n            key === 'enterprise_web_search'\n          ) {\n            searchTypes.add('enterprise_web_search');\n          } else {\n            // Passthrough for any unknown properties\n            searchTypes.add(camelToSnakeCase(key));\n          }\n        }\n      }\n    } else {\n      throw new Error(\n        `Invalid searchTypes configuration: Expected array or object, got ${typeof searchTypesObj}`\n      );\n    }\n\n    if (searchTypes.size > 0) {\n      result.search_types = Array.from(searchTypes);\n    }\n  }\n\n  // Handle any other properties on gs (passthrough)\n  const restConfig = { ...gs };\n  delete restConfig.searchTypes;\n  delete restConfig.search_types;\n\n  Object.assign(result, toSnakeCaseObj(restConfig));\n\n  return result;\n}\n\n/**\n * Converts generateContent-style safety settings to the Interactions API\n * shape: `type` without the `HARM_CATEGORY_` prefix, and lower-case values\n * (`HARM_CATEGORY_HATE_SPEECH` / `BLOCK_LOW_AND_ABOVE` -> `hate_speech` /\n * `block_low_and_above`). The server rejects the upper-case values with a\n * 400. `method` (`SEVERITY` / `PROBABILITY`) is lower-cased too.\n * `HARM_CATEGORY_UNSPECIFIED` has no equivalent and is left out. Other\n * fields are passed through.\n */\nexport function toInteractionSafetySettings(\n  settings?: { category: string; threshold: string; method?: unknown }[]\n): InteractionSafetySetting[] | undefined {\n  if (!settings) return undefined;\n  const result = settings\n    .filter((s) => s.category !== 'HARM_CATEGORY_UNSPECIFIED')\n    .map(({ category, threshold, method, ...rest }) => ({\n      ...toSnakeCaseObj(rest),\n      type: category.replace(/^HARM_CATEGORY_/, '').toLowerCase(),\n      threshold: threshold.toLowerCase(),\n      ...(typeof method === 'string' ? { method: method.toLowerCase() } : {}),\n    }));\n  return result.length ? result : undefined;\n}\n\nexport function toInteractionResponseModalities(\n  modalities: string[]\n): ResponseModality[] {\n  return modalities.map((m) => m.toLowerCase());\n}\n\n/**\n * Converts a Genkit/generateContent-style `speechConfig` to the Interactions\n * API `speech_config`.\n *\n * - `voiceConfig.prebuiltVoiceConfig.voiceName` becomes `[{ voice }]`.\n * - `multiSpeakerVoiceConfig.speakerVoiceConfigs[]` becomes\n *   `{ speakers: [{ speaker, voice }, ...] }`. Each text part must then name\n *   its speaker via `metadata.speechMetadata.speaker`.\n * - A top-level `languageCode` is applied to every entry as `language`.\n *\n * Returns `undefined` if no voice or language is set.\n */\nexport function toInteractionSpeechConfig(\n  speechConfig: unknown\n): ModelGenerationConfig['speech_config'] {\n  if (!isObject(speechConfig)) {\n    return undefined;\n  }\n\n  const language =\n    typeof speechConfig.languageCode === 'string'\n      ? speechConfig.languageCode\n      : undefined;\n  const voiceNameOf = (voiceConfig: unknown): string | undefined => {\n    if (!isObject(voiceConfig) || !isObject(voiceConfig.prebuiltVoiceConfig)) {\n      return undefined;\n    }\n    const voiceName = voiceConfig.prebuiltVoiceConfig.voiceName;\n    return typeof voiceName === 'string' ? voiceName : undefined;\n  };\n  const entry = (voice?: string, speaker?: string): SpeechConfig => ({\n    ...(voice ? { voice } : {}),\n    ...(language ? { language } : {}),\n    ...(speaker ? { speaker } : {}),\n  });\n\n  const multi = speechConfig.multiSpeakerVoiceConfig;\n  if (isObject(multi) && Array.isArray(multi.speakerVoiceConfigs)) {\n    return {\n      speakers: multi.speakerVoiceConfigs\n        .filter(isObject)\n        .map((s) =>\n          entry(\n            voiceNameOf(s.voiceConfig),\n            typeof s.speaker === 'string' ? s.speaker : undefined\n          )\n        ),\n    };\n  }\n\n  const voice = voiceNameOf(speechConfig.voiceConfig);\n  if (voice || language) {\n    return [entry(voice)];\n  }\n  return undefined;\n}\n\n/**\n * Converts the remaining request config into the Interactions\n * `generation_config`.\n *\n * The API rejects unknown `generation_config` fields with a 400, so config\n * fields this plugin defines are mapped explicitly:\n *  - `speechConfig` is converted to `speech_config`;\n *  - `thinkingConfig.thinkingLevel` / `includeThoughts` become\n *    `thinking_level` / `thinking_summaries`. There is no `thinking_config`,\n *    so other thinking fields (e.g. `thinkingBudget`) are dropped;\n *  - `contextCache` (not implemented by this plugin) is dropped.\n * Everything else, including keys the user passes through that aren't in the\n * schema, is forwarded in snake_case.\n *\n * @param config The request config, without fields handled elsewhere.\n * @param onDropped Called with the name of each config field that was dropped.\n */\nexport function toInteractionGenerationConfig(\n  config: Record<string, unknown>,\n  onDropped?: (field: string) => void\n): ModelGenerationConfig {\n  const {\n    speechConfig,\n    thinkingConfig,\n    thinking_config,\n    contextCache,\n    context_cache,\n    // Sent as `response_format` (see toInteractionAudioResponseFormat and\n    // toInteractionVideoResponseFormat).\n    audioFormat: _audioFormat,\n    videoFormat: _videoFormat,\n    ...rest\n  } = config;\n  const result = convertObjectKeysToSnakeCase(rest);\n\n  const interactionSpeechConfig = toInteractionSpeechConfig(speechConfig);\n  if (interactionSpeechConfig) {\n    result.speech_config = interactionSpeechConfig;\n  }\n\n  const thinking = thinkingConfig ?? thinking_config;\n  if (isObject(thinking)) {\n    for (const [key, value] of Object.entries(thinking)) {\n      if (key === 'thinkingLevel' || key === 'thinking_level') {\n        result.thinking_level =\n          typeof value === 'string' ? value.toLowerCase() : value;\n      } else if (key === 'includeThoughts' || key === 'include_thoughts') {\n        result.thinking_summaries =\n          typeof value === 'boolean' ? (value ? 'auto' : 'none') : value;\n      } else {\n        onDropped?.(`thinkingConfig.${key}`);\n      }\n    }\n  }\n\n  if (contextCache !== undefined || context_cache !== undefined) {\n    onDropped?.('contextCache');\n  }\n\n  return result;\n}\n\n/**\n * Converts the `audioFormat` config (`{ mimeType, sampleRate }`) into an\n * Interactions audio `response_format`. Returns `undefined` if it isn't set,\n * so the server defaults apply.\n */\nexport function toInteractionAudioResponseFormat(\n  audioFormat: unknown\n): Record<string, unknown> | undefined {\n  if (!isObject(audioFormat)) {\n    return undefined;\n  }\n  const { mimeType, sampleRate, ...rest } = audioFormat;\n  return {\n    type: 'audio',\n    ...toSnakeCaseObj(rest),\n    ...(typeof mimeType === 'string' ? { mime_type: mimeType } : {}),\n    ...(typeof sampleRate === 'number' ? { sample_rate: sampleRate } : {}),\n  };\n}\n\n/**\n * Converts the `videoFormat` config (`{ aspectRatio, resolution }`) into an\n * Interactions video `response_format`. Returns `undefined` if it isn't set,\n * so the server defaults apply (16:9, 720p).\n */\nexport function toInteractionVideoResponseFormat(\n  videoFormat: unknown\n): Record<string, unknown> | undefined {\n  if (!isObject(videoFormat)) {\n    return undefined;\n  }\n  return { type: 'video', ...toSnakeCaseObj(videoFormat) };\n}\n\n/**\n * Converts a Genkit Part to an Interaction Content object.\n *\n * Handles various part types including text, media, tool requests (mapped to function calls),\n * and tool responses (mapped to function results).\n *\n * @param part - The Genkit message part.\n * @returns The corresponding Interaction Content object.\n * @throws Error if the part type is unsupported.\n */\nexport function toInteractionContent(part: Part): Content | undefined {\n  if (part.text !== undefined) {\n    const speechMetadata = toSpeechMetadataAnnotation(\n      part.metadata?.speechMetadata\n    );\n    return {\n      type: 'text',\n      text: part.text,\n      ...(speechMetadata ? { annotations: [speechMetadata] } : {}),\n    };\n  }\n  if (part.media) {\n    return toInteractionMedia(part);\n  }\n  console.warn(\n    `Unsupported part type for Interaction input: ${JSON.stringify(part)}`\n  );\n  return undefined;\n}\n\n/**\n * Converts a text part's `metadata.speechMetadata` (`{ speaker?, style? }`)\n * into an Interactions `speech_metadata` annotation, used by TTS models to\n * assign each turn to a speaker and set its delivery style.\n */\nfunction toSpeechMetadataAnnotation(\n  speechMetadata: unknown\n): SpeechAnnotation | undefined {\n  if (!isObject(speechMetadata)) {\n    return undefined;\n  }\n  const speaker =\n    typeof speechMetadata.speaker === 'string'\n      ? speechMetadata.speaker\n      : undefined;\n  const style =\n    typeof speechMetadata.style === 'string' ? speechMetadata.style : undefined;\n  if (!speaker && !style) {\n    return undefined;\n  }\n  return {\n    type: 'speech_metadata',\n    ...(speaker ? { speaker } : {}),\n    ...(style ? { style } : {}),\n  };\n}\n\n/** Reports whether a URL points at a YouTube video. */\nfunction isYouTubeUrl(url: string): boolean {\n  try {\n    const host = new URL(url).hostname.replace(/^(www\\.|m\\.)/, '');\n    return host === 'youtube.com' || host === 'youtu.be';\n  } catch {\n    return false;\n  }\n}\n\n/**\n * The `processing` mode (`static` or `agentic`) for a video part, from the\n * part's `metadata.processing`.\n */\nfunction videoProcessingOf(part: Part): Pick<VideoContent, 'processing'> {\n  const processing = part.metadata?.processing;\n  return typeof processing === 'string' ? { processing } : {};\n}\n\nfunction toInteractionMedia(part: Part): Content {\n  if (!part.media) throw new Error('Media part missing media');\n  const { url } = part.media;\n  const contentType = part.media.contentType || extractMimeType(url);\n\n  if (!contentType) {\n    if (url.startsWith('data:')) {\n      throw new Error('Media part missing contentType');\n    }\n    // A URI whose type can't be determined (e.g. a YouTube link or a Files\n    // API URI). The server works out the type itself, so send it without a\n    // mime_type, as the generateContent path does. YouTube links are video;\n    // anything else is sent as a document (verified live: the server still\n    // treats a YouTube link sent as a document as video).\n    if (isYouTubeUrl(url)) {\n      return { type: 'video', uri: url, ...videoProcessingOf(part) };\n    }\n    return { type: 'document', uri: url };\n  }\n\n  // Inline data URLs are sent as `data`, everything else as a `uri`.\n  const source = url.startsWith('data:')\n    ? { data: url.substring(url.indexOf(',') + 1) }\n    : { uri: url };\n  const fields = { mime_type: contentType, ...source };\n\n  if (contentType.startsWith('image/')) {\n    return { type: 'image', ...fields };\n  }\n  if (contentType.startsWith('audio/')) {\n    return { type: 'audio', ...fields };\n  }\n  if (contentType.startsWith('video/')) {\n    return { type: 'video', ...fields, ...videoProcessingOf(part) };\n  }\n  // The Interactions API accepts PDF and CSV documents.\n  if (contentType === 'application/pdf' || contentType === 'text/csv') {\n    return { type: 'document', ...fields };\n  }\n\n  throw new Error(`Unsupported media type: ${contentType}`);\n}\n\n/**\n * Maps a Genkit message role to the corresponding Interaction API role.\n *\n * - 'user' -> 'user'\n * - 'model' -> 'model'\n * - 'tool' -> 'user' (Tool outputs are treated as user turns in this context)\n *\n * @param role - The Genkit message role.\n * @returns The mapped Interaction role string.\n * @throws Error if the role is 'system', as system instructions are handled separately.\n */\nexport function toInteractionRole(role: MessageData['role']): string {\n  switch (role) {\n    case 'user':\n      return 'user';\n    case 'model':\n      return 'model';\n    case 'tool':\n      return 'user';\n    case 'system':\n      throw new Error(\n        `System role should be handled as system_instruction, not part of turns.`\n      );\n    default:\n      return 'user';\n  }\n}\n\nconst GoogleSearchArgsSchema = z.object({ queries: z.array(z.string()) });\nconst RecordUnknownSchema = z.record(z.unknown());\n\nconst MediaResolutionSchema = z.enum(['low', 'medium', 'high', 'ultra_high']);\n\nconst TextContentSchema = z.object({\n  type: z.literal('text'),\n  text: z.string().optional(),\n  annotations: z.array(TextAnnotationSchema).optional(),\n});\n\nconst ImageContentSchema = z.object({\n  type: z.literal('image'),\n  data: z.string().optional(),\n  uri: z.string().optional(),\n  mime_type: z.string().optional(),\n  resolution: MediaResolutionSchema.optional(),\n});\n\nconst FunctionResultArraySchema = z.array(\n  z.union([ImageContentSchema, TextContentSchema])\n);\n\nconst RecordUnknownOrStringOrArraySchema = z.union([\n  RecordUnknownSchema,\n  z.string(),\n  FunctionResultArraySchema,\n]);\n\nconst OptionalStringSchema = z.string().optional();\n\nconst GoogleSearchCallSchema = z.object({\n  id: z.string(),\n  arguments: GoogleSearchArgsSchema,\n});\n\n// The API returns `result` as an array of items (e.g.\n// `[{ search_suggestions }]`), and it must be sent back the same way when the\n// history is resent (e.g. on the second turn of a tool loop). An object is\n// still accepted for parts saved before this was fixed.\nconst GoogleSearchResultSchema = z.object({\n  callId: z.string(),\n  result: z.union([z.array(RecordUnknownSchema), RecordUnknownSchema]),\n});\n\nconst ExecutableCodeSchema = z.object({\n  code: z.string(),\n  language: z.string().default('PYTHON'),\n});\n\nconst CodeExecutionResultSchema = z.object({\n  output: z.string(),\n  outcome: z.string().optional(),\n});\n\nconst ProcessingCallSchema = z.object({ id: z.string() });\n\nconst ProcessingResultSchema = z.object({ callId: z.string() });\n\n/**\n * Converts an array of Genkit MessageData objects into an array of Interaction Steps.\n */\nexport function toInteractionSteps(messages: MessageData[]): Step[] {\n  const steps: Step[] = [];\n\n  for (const message of messages) {\n    const normalContent: Content[] = [];\n\n    for (const part of message.content) {\n      if (part.toolRequest) {\n        const signature = OptionalStringSchema.parse(\n          part.metadata?.thoughtSignature\n        );\n        steps.push({\n          type: 'function_call',\n          name: part.toolRequest.name,\n          arguments: RecordUnknownSchema.optional().parse(\n            part.toolRequest.input\n          ),\n          id: part.toolRequest.ref || '',\n          ...(signature ? { signature } : {}),\n        });\n      } else if (part.toolResponse) {\n        let result: unknown = part.toolResponse.output;\n\n        if (part.toolResponse.content && part.toolResponse.content.length > 0) {\n          const contentParts: Content[] = [];\n          if (result !== undefined) {\n            const outputText =\n              typeof result === 'string' ? result : JSON.stringify(result);\n            contentParts.push({ type: 'text', text: outputText });\n          }\n          for (const p of part.toolResponse.content) {\n            const mapped = toInteractionContent(p);\n            if (mapped) {\n              contentParts.push(mapped);\n            }\n          }\n          result = contentParts;\n        } else if (\n          (typeof result !== 'object' && typeof result !== 'string') ||\n          Array.isArray(result)\n        ) {\n          result = { result: result };\n        }\n\n        let parsedResult:\n          | Record<string, unknown>\n          | string\n          | (ImageContent | TextContent)[];\n        try {\n          parsedResult = RecordUnknownOrStringOrArraySchema.parse(result ?? {});\n        } catch {\n          throw new GenkitError({\n            status: 'INVALID_ARGUMENT',\n            message: `Tool output for ${part.toolResponse.name} may only contain text or image content.`,\n          });\n        }\n        steps.push({\n          type: 'function_result',\n          name: part.toolResponse.name,\n          result: parsedResult,\n          call_id: part.toolResponse.ref || '',\n        });\n      } else if (part.custom?.googleSearchCall) {\n        const gsCall = GoogleSearchCallSchema.parse(\n          part.custom.googleSearchCall\n        );\n        steps.push({\n          type: 'google_search_call',\n          id: gsCall.id,\n          arguments: gsCall.arguments,\n          signature: OptionalStringSchema.parse(\n            part.metadata?.thoughtSignature\n          ),\n        });\n      } else if (part.custom?.googleSearchResult) {\n        const gsResult = GoogleSearchResultSchema.parse(\n          part.custom.googleSearchResult\n        );\n        steps.push({\n          type: 'google_search_result',\n          call_id: gsResult.callId,\n          result: gsResult.result,\n          signature: OptionalStringSchema.parse(\n            part.metadata?.thoughtSignature\n          ),\n        });\n      } else if (part.custom?.executableCode) {\n        const execCode = ExecutableCodeSchema.parse(part.custom.executableCode);\n        steps.push({\n          type: 'code_execution_call',\n          id: z.string().parse(part.metadata?.callId),\n          arguments: {\n            code: execCode.code,\n            language: execCode.language,\n          },\n          signature: OptionalStringSchema.parse(\n            part.metadata?.thoughtSignature\n          ),\n        });\n      } else if (part.custom?.codeExecutionResult) {\n        const execResult = CodeExecutionResultSchema.parse(\n          part.custom.codeExecutionResult\n        );\n        steps.push({\n          type: 'code_execution_result',\n          call_id: z.string().parse(part.metadata?.callId),\n          result: execResult.output,\n          signature: OptionalStringSchema.parse(\n            part.metadata?.thoughtSignature\n          ),\n        });\n      } else if (part.custom?.processingCall) {\n        // Agentic video steps are resent as they came back, with their\n        // signatures, when the history is sent again.\n        const call = ProcessingCallSchema.parse(part.custom.processingCall);\n        const signature = OptionalStringSchema.parse(\n          part.metadata?.thoughtSignature\n        );\n        steps.push({\n          type: 'processing_call',\n          id: call.id,\n          ...(signature ? { signature } : {}),\n        });\n      } else if (part.custom?.processingResult) {\n        const result = ProcessingResultSchema.parse(\n          part.custom.processingResult\n        );\n        const signature = OptionalStringSchema.parse(\n          part.metadata?.thoughtSignature\n        );\n        steps.push({\n          type: 'processing_result',\n          call_id: result.callId,\n          ...(signature ? { signature } : {}),\n        });\n      } else if (\n        part.reasoning !== undefined ||\n        Boolean(part.custom?.thought)\n      ) {\n        const signature =\n          part.metadata?.thoughtSignature ?? part.custom?.thought?.signature;\n        const parsedSignature = OptionalStringSchema.parse(signature);\n\n        let summary: (TextContent | ImageContent)[] | undefined = undefined;\n        if (\n          Array.isArray(part.custom?.thought?.summary) &&\n          part.custom.thought.summary.length > 0\n        ) {\n          summary = part.custom.thought.summary;\n        } else if (part.reasoning) {\n          summary = [{ type: 'text', text: part.reasoning }];\n        }\n\n        const thoughtStep: ThoughtStep = {\n          type: 'thought',\n          ...(summary ? { summary } : {}),\n          ...(parsedSignature ? { signature: parsedSignature } : {}),\n        };\n        steps.push(thoughtStep);\n      } else {\n        const content = toInteractionContent(part);\n        if (content) {\n          normalContent.push(content);\n        }\n      }\n    }\n\n    if (normalContent.length > 0) {\n      if (message.role === 'model') {\n        steps.push({\n          type: 'model_output',\n          content: normalContent,\n        });\n      } else {\n        steps.push({\n          type: 'user_input',\n          content: normalContent,\n        });\n      }\n    }\n  }\n\n  return steps;\n}\n\n/**\n * Converts a streamed step delta into Genkit Parts for a stream chunk.\n *\n * @param delta - The `delta` of a `step.delta` SSE event.\n * @returns The corresponding Genkit Parts (empty for deltas with nothing to\n *   emit, such as partial function call arguments).\n */\nexport function fromInteractionDelta(delta: StepDeltaData): Part[] {\n  switch (delta.type) {\n    case 'text':\n      return [{ text: delta.text }];\n    case 'image':\n    case 'audio':\n    case 'document':\n    case 'video': {\n      let url = delta.uri;\n      if (delta.data && delta.mime_type) {\n        url = `data:${delta.mime_type};base64,${delta.data}`;\n      }\n      const part: Part = {\n        media: {\n          url: url || '',\n          contentType: delta.mime_type,\n        },\n      };\n      if (\n        (delta.type === 'image' || delta.type === 'video') &&\n        delta.resolution !== undefined\n      ) {\n        part.metadata = { resolution: delta.resolution };\n      }\n      return [part];\n    }\n    case 'thought_summary':\n      if (!delta.content) return [];\n      if (delta.content.type === 'text') {\n        return [\n          {\n            reasoning: delta.content.text || '',\n            ...(delta.content.annotations\n              ? { metadata: { annotations: delta.content.annotations } }\n              : {}),\n          },\n        ];\n      }\n      // Non-text thought content (e.g. a draft image) is part of the\n      // reasoning, not the answer. Use the same placeholder as the final\n      // response so streaming clients don't receive it as a regular part.\n      return [{ reasoning: thoughtContentPlaceholder(delta.content) }];\n    case 'thought_signature':\n      return [{ metadata: { thoughtSignature: delta.signature } }];\n    case 'function_call':\n      return [\n        {\n          toolRequest: {\n            name: delta.name,\n            ref: delta.id,\n            input: delta.arguments || {},\n            partial: true,\n          },\n        },\n      ];\n    case 'arguments_delta':\n      return [];\n    case 'code_execution_call': {\n      const part: Part = {\n        custom: {\n          executableCode: {\n            code: delta.arguments.code || '',\n            language: delta.arguments.language || 'PYTHON',\n          },\n        },\n      };\n      if (delta.signature) {\n        part.metadata = { thoughtSignature: delta.signature };\n      }\n      return [part];\n    }\n    case 'code_execution_result': {\n      const part: Part = {\n        custom: {\n          codeExecutionResult: {\n            output: delta.result,\n            outcome: delta.is_error ? 'OUTCOME_FAILED' : 'OUTCOME_OK',\n          },\n        },\n      };\n      if (delta.signature) {\n        part.metadata = { thoughtSignature: delta.signature };\n      }\n      return [part];\n    }\n    case 'google_search_call': {\n      const part: Part = {\n        custom: {\n          googleSearchCall: {\n            id: '',\n            arguments: delta.arguments,\n          },\n        },\n      };\n      if (delta.signature) {\n        part.metadata = { thoughtSignature: delta.signature };\n      }\n      return [part];\n    }\n    case 'google_search_result': {\n      const part: Part = {\n        custom: {\n          googleSearchResult: {\n            callId: '',\n            result: delta.result || [],\n          },\n        },\n      };\n      if (delta.signature) {\n        part.metadata = { thoughtSignature: delta.signature };\n      }\n      return [part];\n    }\n    case 'function_result':\n      return [\n        {\n          custom: {\n            serverFunctionResult: {\n              callId: delta.call_id,\n              name: delta.name || '',\n              result: delta.result,\n              isError: delta.is_error,\n            },\n          },\n        },\n      ];\n    default:\n      return [];\n  }\n}\n\n/**\n * Converts an Interaction Content object back into a Genkit Part.\n *\n * Supports text, image, audio, document, video, thought, function calls, and\n * function results. Unknown content types are returned as a custom part.\n *\n * @param content - The Interaction Content object.\n * @returns The corresponding Genkit Part.\n */\nexport function fromInteractionContent(content: Content): Part {\n  switch (content.type) {\n    case 'text':\n      return fromTextContent(content);\n    case 'image':\n      return fromImageContent(content);\n    case 'audio':\n    case 'document':\n      return fromMediaContent(content);\n    case 'video':\n      return fromVideoContent(content);\n    case 'thought':\n      return fromThoughtContent(content);\n    case 'function_call':\n      return fromFunctionCallContent(content);\n    case 'function_result':\n      return fromFunctionResultContent(content);\n    default:\n      return {\n        custom: {\n          unknownContent: content,\n        },\n      };\n  }\n}\n\nfunction maybeAddGeminiThoughtSignature(step: Step, part: Part): Part {\n  let updatedPart = part;\n\n  if ('signature' in step && step.signature) {\n    updatedPart.metadata = {\n      ...(part.metadata ?? {}),\n      thoughtSignature: step.signature,\n    };\n  }\n  return updatedPart;\n}\n\nexport function fromGoogleSearchCall(step: GoogleSearchCallStep): Part {\n  const part: Part = {\n    custom: {\n      googleSearchCall: {\n        id: step.id,\n        arguments: step.arguments,\n      },\n    },\n  };\n  return maybeAddGeminiThoughtSignature(step, part);\n}\n\nexport function fromGoogleSearchResult(step: GoogleSearchResultStep): Part {\n  const part: Part = {\n    custom: {\n      googleSearchResult: {\n        callId: step.call_id,\n        result: step.result,\n      },\n    },\n  };\n  return maybeAddGeminiThoughtSignature(step, part);\n}\n\nexport function fromCodeExecutionCall(step: CodeExecutionCallStep): Part {\n  const part: Part = {\n    custom: {\n      executableCode: {\n        code: step.arguments.code,\n        language: step.arguments.language || 'PYTHON',\n      },\n    },\n  };\n  part.metadata = { callId: step.id };\n  return maybeAddGeminiThoughtSignature(step, part);\n}\n\nexport function fromCodeExecutionResult(step: CodeExecutionResultStep): Part {\n  const part: Part = {\n    custom: {\n      codeExecutionResult: {\n        output:\n          typeof step.result === 'string'\n            ? step.result\n            : JSON.stringify(step.result),\n        outcome: 'OUTCOME_OK',\n      },\n    },\n  };\n  part.metadata = { callId: step.call_id };\n  return maybeAddGeminiThoughtSignature(step, part);\n}\n\nexport function fromPendingFunctionCall(\n  step: FunctionCallContent | FunctionCallStep\n): Part {\n  // Keep the signature so it can be sent back with the function call when the\n  // history is resent (stateless, the default).\n  return maybeAddGeminiThoughtSignature(step, {\n    toolRequest: {\n      name: step.name,\n      ref: step.id,\n      input: step.arguments,\n    },\n  });\n}\n\nexport function fromServerFunctionCall(\n  step: FunctionCallContent | FunctionCallStep\n): Part {\n  return maybeAddGeminiThoughtSignature(step, {\n    custom: {\n      serverFunctionCall: {\n        id: step.id,\n        name: step.name,\n        arguments: step.arguments,\n      },\n    },\n  });\n}\n\nexport function fromServerFunctionResult(\n  step: FunctionResultContent | FunctionResultStep\n): Part {\n  return {\n    custom: {\n      serverFunctionResult: {\n        callId: step.call_id,\n        name: step.name || '',\n        result: step.result,\n        isError: step.is_error,\n      },\n    },\n  };\n}\n\nexport function fromInteractionStep(step: Step, isPending?: boolean): Part[] {\n  switch (step.type) {\n    case 'model_output':\n      return step.content.map(fromInteractionContent);\n    case 'user_input':\n      return [];\n    case 'google_search_call':\n      return [fromGoogleSearchCall(step)];\n    case 'google_search_result':\n      return [fromGoogleSearchResult(step)];\n    case 'code_execution_call':\n      return [fromCodeExecutionCall(step)];\n    case 'code_execution_result':\n      return [fromCodeExecutionResult(step)];\n    case 'thought':\n      return [fromThoughtContent(step)];\n    case 'function_call':\n      return isPending\n        ? [fromPendingFunctionCall(step)]\n        : [fromServerFunctionCall(step)];\n    case 'function_result':\n      return [fromServerFunctionResult(step)];\n    case 'processing_call':\n      return [\n        maybeAddGeminiThoughtSignature(step, {\n          custom: { processingCall: { id: step.id } },\n        }),\n      ];\n    case 'processing_result':\n      return [\n        maybeAddGeminiThoughtSignature(step, {\n          custom: { processingResult: { callId: step.call_id } },\n        }),\n      ];\n  }\n\n  return [{ custom: { unknownStep: step } }];\n}\n\nfunction getPendingFunctionCallIds(\n  steps: Step[],\n  status?: string\n): Set<string> {\n  const pendingIds = new Set<string>();\n  if (status !== 'requires_action') {\n    return pendingIds;\n  }\n\n  const resultSet = new Set<string>();\n  for (const step of steps) {\n    if (step.type === 'function_result' && step.call_id) {\n      resultSet.add(step.call_id);\n    }\n  }\n\n  for (const step of steps) {\n    if (step.type === 'function_call' && step.id) {\n      if (!resultSet.has(step.id)) {\n        pendingIds.add(step.id);\n      }\n    }\n  }\n\n  return pendingIds;\n}\n\nfunction fromMediaContent(\n  content: ImageContent | AudioContent | VideoContent | DocumentContent\n): Part {\n  let url = content.uri;\n  if (content.data && content.mime_type) {\n    url = `data:${content.mime_type};base64,${content.data}`;\n  }\n  return {\n    media: {\n      url: url || '',\n      contentType: content.mime_type,\n    },\n  };\n}\n\nfunction fromTextContent(content: TextContent): Part {\n  return {\n    text: content.text || '',\n    metadata: {\n      annotations: content.annotations,\n    },\n  };\n}\n\nfunction fromImageContent(content: ImageContent): Part {\n  const part = fromMediaContent(content);\n  if (content.resolution !== undefined) {\n    part.metadata = { resolution: content.resolution };\n  }\n  return part;\n}\n\nfunction fromVideoContent(content: VideoContent): Part {\n  const part = fromMediaContent(content);\n  if (content.resolution !== undefined) {\n    part.metadata = { resolution: content.resolution };\n  }\n  return part;\n}\n\n/**\n * Placeholder text for non-text content inside a thought summary, e.g.\n * `[Image]`, `[Audio]` or `[Function call]`.\n *\n * Thoughts are returned as reasoning text, so non-text items (such as a draft\n * image the model reviews before its final output) are shown as a label\n * instead of being dropped or returned as regular media parts. The label is\n * derived from the content type, so any type the server adds in the future\n * still shows up in the reasoning.\n */\nfunction thoughtContentPlaceholder(content: Content): string {\n  const label = content.type.replace(/_/g, ' ');\n  return `[${label.charAt(0).toUpperCase()}${label.slice(1)}]`;\n}\n\nfunction fromThoughtContent(content: ThoughtContent): Part {\n  let reasoning = '';\n  if (content.summary) {\n    // Separate summary blocks with a newline so distinct thought sections\n    // don't run together. Each summary block is a whole section, both in\n    // non-streamed responses and in streamed `thought_summary` deltas (one\n    // delta per section, confirmed live), so this doesn't split sentences.\n    reasoning = content.summary\n      .map((c) => {\n        if (c.type === 'text') return c.text;\n        return thoughtContentPlaceholder(c);\n      })\n      .join('\\n');\n  }\n\n  return {\n    reasoning,\n    metadata: {\n      thoughtSignature: content.signature,\n    },\n    custom: {\n      thought: content,\n    },\n  };\n}\n\nfunction fromFunctionCallContent(content: FunctionCallContent): Part {\n  return {\n    toolRequest: {\n      name: content.name,\n      input: content.arguments,\n      ref: content.id,\n    },\n  };\n}\n\nfunction isContentArray(val: unknown): val is Content[] {\n  return (\n    Array.isArray(val) &&\n    val.length > 0 &&\n    val.every((item) => isObject(item) && typeof item.type === 'string')\n  );\n}\n\nfunction fromFunctionResultContent(content: FunctionResultContent): Part {\n  if (isContentArray(content.result)) {\n    return {\n      toolResponse: {\n        name: content.name,\n        content: content.result.map((c) => fromInteractionContent(c)),\n        ref: content.call_id,\n      },\n    };\n  }\n  return {\n    toolResponse: {\n      name: content.name,\n      output: content.result,\n      ref: content.call_id,\n    },\n  };\n}\n\n/** Converts Interactions API token usage to Genkit usage. */\nfunction fromInteractionUsage(usage: Usage): GenerationUsage {\n  const result: GenerationUsage = {\n    inputTokens: usage.total_input_tokens,\n    outputTokens: usage.total_output_tokens,\n    totalTokens: usage.total_tokens,\n    cachedContentTokens: usage.total_cached_tokens,\n    thoughtsTokens: usage.total_thought_tokens,\n  };\n  for (const modalityToken of usage.input_tokens_by_modality ?? []) {\n    switch (modalityToken.modality) {\n      case 'text':\n        result.inputCharacters = modalityToken.tokens;\n        break;\n      case 'image':\n        result.inputImages = modalityToken.tokens;\n        break;\n      case 'audio':\n        result.inputAudioFiles = modalityToken.tokens;\n        break;\n      case 'video':\n        result.inputVideos = modalityToken.tokens;\n        break;\n    }\n  }\n  for (const modalityToken of usage.output_tokens_by_modality ?? []) {\n    switch (modalityToken.modality) {\n      case 'text':\n        result.outputCharacters = modalityToken.tokens;\n        break;\n      case 'image':\n        result.outputImages = modalityToken.tokens;\n        break;\n      case 'audio':\n        result.outputAudioFiles = modalityToken.tokens;\n        break;\n      case 'video':\n        result.outputVideos = modalityToken.tokens;\n        break;\n    }\n  }\n  // Tokens loaded by tools, e.g. video frames read during agentic video\n  // understanding. Genkit has no standard field for these.\n  if (usage.total_tool_use_tokens) {\n    result.custom = { toolUseTokens: usage.total_tool_use_tokens };\n  }\n  return result;\n}\n\nconst INTERACTION_FAILED_MESSAGE = 'Interaction failed';\nconst INTERACTION_INCOMPLETE_MESSAGE =\n  'Interaction incomplete (truncated output)';\n\n/** Builds a human-readable message from a failed interaction's errors. */\nfunction interactionFailureMessage(interaction: GeminiInteraction): string {\n  const details = (interaction.errors ?? [])\n    .map((e) => [e.code ? `[${e.code}]` : '', e.message ?? ''].join(' ').trim())\n    .filter(Boolean)\n    .join('; ');\n  return details\n    ? `${INTERACTION_FAILED_MESSAGE}: ${details}`\n    : INTERACTION_FAILED_MESSAGE;\n}\n\n/**\n * Converts a `status: 'failed'` interaction into a Genkit outcome:\n *  - content-policy blocks (safety, recitation, ...) return a response with\n *    `finishReason: 'blocked'`, matching the generateContent path;\n *  - everything else throws a `GenkitError` with the status mapped from the\n *    error code (`UNKNOWN` if unrecognized, which is not retried).\n */\nfunction fromFailedInteraction(\n  interaction: GeminiInteraction\n): GenerateResponseData {\n  const firstError = interaction.errors?.[0];\n  if (isInteractionContentBlockCode(firstError?.code)) {\n    return {\n      finishReason: 'blocked',\n      finishMessage:\n        firstError?.message || interactionFailureMessage(interaction),\n      message: {\n        role: 'model',\n        content: [],\n        ...interactionMessageMetadata(interaction),\n      },\n      custom: interaction,\n      raw: interaction,\n      ...(interaction.usage\n        ? { usage: fromInteractionUsage(interaction.usage) }\n        : {}),\n    };\n  }\n  throw new GenkitError({\n    status: interactionErrorCodeToGenkitStatus(firstError?.code) ?? 'UNKNOWN',\n    message: interactionFailureMessage(interaction),\n    detail: interaction,\n  });\n}\n\n/** Message metadata carrying the interaction and environment IDs, if any. */\nfunction interactionMessageMetadata(\n  interaction: GeminiInteraction\n): Pick<MessageData, 'metadata'> {\n  return interaction.id || interaction.environment_id\n    ? {\n        metadata: {\n          ...(interaction.id ? { interactionId: interaction.id } : {}),\n          ...(interaction.environment_id\n            ? { environmentId: interaction.environment_id }\n            : {}),\n        },\n      }\n    : {};\n}\n\nexport function fromInteractionSync(\n  interaction: GeminiInteraction\n): GenerateResponseData {\n  if (interaction.status === 'failed') {\n    return fromFailedInteraction(interaction);\n  }\n\n  const response: GenerateResponseData = {\n    finishReason: 'stop',\n    message: {\n      role: 'model',\n      content: [],\n      ...(interaction.id || interaction.environment_id\n        ? {\n            metadata: {\n              ...(interaction.id ? { interactionId: interaction.id } : {}),\n              ...(interaction.environment_id\n                ? { environmentId: interaction.environment_id }\n                : {}),\n            },\n          }\n        : {}),\n    },\n    custom: interaction,\n    raw: interaction,\n    ...(interaction.usage\n      ? { usage: fromInteractionUsage(interaction.usage) }\n      : {}),\n  };\n\n  if (interaction.status === 'cancelled') {\n    response.finishReason = 'aborted';\n    response.finishMessage = 'Operation cancelled';\n    response.message!.content = [{ text: 'Operation cancelled.' }];\n    return response;\n  }\n\n  if (interaction.status === 'incomplete') {\n    // Token/step limit reached (MAX_TOKENS); partial content may be present.\n    response.finishReason = 'length';\n    response.finishMessage = INTERACTION_INCOMPLETE_MESSAGE;\n  }\n\n  const steps = interaction.steps;\n  if (steps?.length) {\n    const pendingIds = getPendingFunctionCallIds(steps, interaction.status);\n\n    response.message!.content = steps\n      .flatMap((step) => {\n        const isPending =\n          step.type === 'function_call' && step.id\n            ? pendingIds.has(step.id)\n            : false;\n        return fromInteractionStep(step, isPending);\n      })\n      .filter((p) => p && Object.keys(p).length > 0);\n  }\n  return response;\n}\n\n/** Audio types without a container header, so chunks can be joined end to end. */\nconst HEADERLESS_AUDIO_TYPES = ['audio/l16', 'audio/mulaw', 'audio/alaw'];\n\nfunction isHeaderlessAudio(part: Part): boolean {\n  const contentType = part.media?.contentType?.toLowerCase();\n  return (\n    !!part.media?.url.startsWith('data:') &&\n    !!contentType &&\n    HEADERLESS_AUDIO_TYPES.some((type) => contentType.startsWith(type))\n  );\n}\n\nfunction isWavAudio(part: Part): boolean {\n  return (\n    !!part.media?.url.startsWith('data:') &&\n    !!part.media.contentType?.toLowerCase().startsWith('audio/wav')\n  );\n}\n\nfunction mediaBytes(part: Part): Buffer {\n  const url = part.media?.url ?? '';\n  return Buffer.from(url.substring(url.indexOf(',') + 1), 'base64');\n}\n\nfunction mediaPart(contentType: string, bytes: Buffer): Part {\n  return {\n    media: {\n      url: `data:${contentType};base64,${bytes.toString('base64')}`,\n      contentType,\n    },\n  };\n}\n\n/**\n * Removes ID3 tags from the start of a headerless audio part.\n *\n * The server sometimes sends a C2PA manifest, in an ID3 tag, at the start of a\n * streamed `audio/l16` chunk (seen with gemini-3.8-flash-lite-tts and two\n * speakers). The tag isn't audio: played or joined as raw audio it is noise,\n * and its odd size shifts every sample after it by one byte. This has been\n * reported to the Gemini API team; until it's fixed, the tag is removed so\n * the audio plays correctly. That manifest is dropped. The tag has only been\n * seen whole at the start of a chunk; a tag that doesn't fit in the chunk is\n * left in, since bytes that can't be checked as a tag might be audio.\n */\nexport function removeId3FromAudio(part: Part): Part {\n  if (!part.media || !isHeaderlessAudio(part)) {\n    return part;\n  }\n  const bytes = mediaBytes(part);\n  const audio = stripLeadingId3Tags(bytes);\n  if (audio === bytes) {\n    return part;\n  }\n  const contentType = part.media.contentType ?? 'audio/l16';\n  return {\n    ...part,\n    media: {\n      ...part.media,\n      url: `data:${contentType};base64,${audio.toString('base64')}`,\n    },\n  };\n}\n\n/**\n * Joins streamed audio chunks in the final response into one part, in the\n * format the server returned:\n *  - consecutive headerless chunks (`audio/l16`, `audio/mulaw`, `audio/alaw`)\n *    of the same type are joined end to end;\n *  - a streamed `audio/wav` request starts with a small complete WAV file and\n *    continues with `audio/l16` chunks (seen live). Those chunks go into the\n *    WAV's `data` chunk, giving one WAV like a non-streamed response.\n * Other parts are kept as they are.\n */\nexport function mergeStreamedAudio(parts: Part[]): Part[] {\n  const merged: Part[] = [];\n  let i = 0;\n  while (i < parts.length) {\n    const part = parts[i];\n    if (isWavAudio(part)) {\n      let j = i + 1;\n      while (j < parts.length && isHeaderlessAudio(parts[j])) j++;\n      const audio = Buffer.concat(parts.slice(i + 1, j).map(mediaBytes));\n      const wav =\n        audio.length > 0 ? appendToWavData(mediaBytes(part), audio) : undefined;\n      if (wav && part.media) {\n        merged.push(mediaPart(part.media.contentType ?? 'audio/wav', wav));\n        i = j;\n        continue;\n      }\n      merged.push(part);\n      i++;\n      continue;\n    }\n    if (isHeaderlessAudio(part)) {\n      const contentType = part.media?.contentType;\n      let j = i + 1;\n      while (\n        j < parts.length &&\n        isHeaderlessAudio(parts[j]) &&\n        parts[j].media?.contentType === contentType\n      ) {\n        j++;\n      }\n      if (j - i > 1 && contentType) {\n        merged.push(\n          mediaPart(\n            contentType,\n            Buffer.concat(parts.slice(i, j).map(mediaBytes))\n          )\n        );\n      } else {\n        merged.push(...parts.slice(i, j));\n      }\n      i = j;\n      continue;\n    }\n    merged.push(part);\n    i++;\n  }\n  return merged;\n}\n\nexport function fromInteraction(\n  interaction: GeminiInteraction\n): Operation<GenerateResponseData> {\n  const op = { id: interaction.id } as Operation<GenerateResponseData>;\n  if (interaction.status === 'in_progress' || interaction.status === 'queued') {\n    // Still running, or waiting for capacity (e.g. flex/deferred tiers).\n    op.done = false;\n  } else if (interaction.status === 'failed') {\n    // Always finish the operation on failure; leaving `done` unset would make\n    // callers poll forever.\n    op.done = true;\n    if (isInteractionContentBlockCode(interaction.errors?.[0]?.code)) {\n      op.output = fromFailedInteraction(interaction);\n    } else {\n      op.error = {\n        message: interactionFailureMessage(interaction),\n        ...(interaction.errors?.[0]?.code\n          ? { code: interaction.errors[0].code }\n          : {}),\n      };\n    }\n  } else if (interaction.status === 'cancelled') {\n    op.done = true;\n    op.output = {\n      ...(interaction.usage\n        ? { usage: fromInteractionUsage(interaction.usage) }\n        : {}),\n      finishReason: 'aborted',\n      finishMessage: 'Operation cancelled',\n      message: {\n        role: 'model',\n        content: [{ text: 'Operation cancelled.' }],\n        ...(interaction.id || interaction.environment_id\n          ? {\n              metadata: {\n                ...(interaction.id ? { interactionId: interaction.id } : {}),\n                ...(interaction.environment_id\n                  ? { environmentId: interaction.environment_id }\n                  : {}),\n              },\n            }\n          : {}),\n      },\n    };\n  } else if (\n    interaction.status === 'completed' ||\n    interaction.status === 'incomplete' ||\n    interaction.status === 'requires_action'\n  ) {\n    // `requires_action` is a deliberate pause, not a failure: e.g. a\n    // collaborative-planning plan awaiting approval, a client-side function\n    // call, or an elicitation. The turn is over, so finish the operation and\n    // surface what was produced; the caller continues with\n    // `previousInteractionId`. Pending client function calls become\n    // `toolRequest` parts.\n    op.done = true;\n    const steps = interaction.steps;\n    if (steps?.length) {\n      const pendingIds = getPendingFunctionCallIds(steps, interaction.status);\n      const content = steps\n        .flatMap((step) =>\n          fromInteractionStep(\n            step,\n            step.type === 'function_call' && step.id\n              ? pendingIds.has(step.id)\n              : false\n          )\n        )\n        .filter((p) => p && Object.keys(p).length > 0);\n      op.output = {\n        ...(interaction.status === 'incomplete'\n          ? {\n              finishReason: 'length' as const,\n              finishMessage: INTERACTION_INCOMPLETE_MESSAGE,\n            }\n          : { finishReason: 'stop' as const }),\n        message: {\n          role: 'model',\n          content,\n          ...(interaction.id || interaction.environment_id\n            ? {\n                metadata: {\n                  ...(interaction.id ? { interactionId: interaction.id } : {}),\n                  ...(interaction.environment_id\n                    ? { environmentId: interaction.environment_id }\n                    : {}),\n                  ...(interaction.status === 'requires_action'\n                    ? { interactionStatus: interaction.status }\n                    : {}),\n                },\n              }\n            : {}),\n        },\n        custom: interaction,\n        raw: interaction,\n        ...(interaction.usage\n          ? { usage: fromInteractionUsage(interaction.usage) }\n          : {}),\n      };\n    }\n  } else if (interaction.status) {\n    // A status this plugin doesn't know. Finish the operation rather than\n    // leaving `done` unset, which would make callers poll forever.\n    op.done = true;\n    op.error = {\n      message: `Unknown interaction status: ${interaction.status}`,\n    };\n  }\n  return op;\n}\n"],"mappings":"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","names":["voice"]}