{"version":3,"sources":["../../src/vertexai/gemini.ts"],"sourcesContent":["/**\n * Copyright 2025 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  ActionMetadata,\n  GENKIT_UI_METADATA,\n  GENKIT_UI_WIDGETS,\n  GenkitError,\n  annotateSchema,\n  modelActionMetadata,\n  z,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport {\n  CandidateData,\n  GenerateRequest,\n  GenerateResponseChunkData,\n  GenerateResponseData,\n  GenerationCommonConfigDescriptions,\n  GenerationCommonConfigSchema,\n  MessageData,\n  ModelAction,\n  ModelInfo,\n  ModelMiddleware,\n  ModelReference,\n  getBasicUsageStats,\n  modelRef,\n} from 'genkit/model';\nimport { downloadRequestMedia } from 'genkit/model/middleware';\nimport { model as pluginModel } from 'genkit/plugin';\nimport {\n  fromGeminiCandidate,\n  toGeminiFunctionModeEnum,\n  toGeminiMessage,\n  toGeminiSystemInstruction,\n  toGeminiTool,\n} from '../common/converters.mjs';\nimport {\n  applyLatLngToGoogleMapsTools,\n  fromInteractionDelta,\n  fromInteractionSync,\n  mergeStreamedAudio,\n  selectInteractionInput,\n  toInteractionConfigTool,\n  toInteractionGenerationConfig,\n  toInteractionGoogleSearch,\n  toInteractionResponseModalities,\n  toInteractionSafetySettings,\n  toInteractionSteps,\n  toInteractionTool,\n  toInteractionToolChoice,\n  toInteractionVideoResponseFormat,\n} from '../common/interaction-converters.mjs';\nimport {\n  CreateInteractionRequest,\n  InteractionTool,\n} from '../common/interaction-types.mjs';\nimport { isObject } from '../common/types.mjs';\nimport {\n  isKnownKey,\n  isStringArray,\n  warnDroppedConfigField,\n} from '../common/utils.mjs';\nimport {\n  createInteraction,\n  createInteractionStream,\n  generateContent,\n  generateContentStream,\n} from './client.mjs';\nimport { toGeminiLabels, toGeminiSafetySettings } from './converters.mjs';\nimport {\n  ClientOptions,\n  Content,\n  GenerateContentRequest,\n  GenerateContentResponse,\n  GoogleSearchRetrieval,\n  Model,\n  Tool,\n  ToolConfig,\n  VertexPluginOptions,\n} from './types.mjs';\nimport {\n  calculateRequestOptions,\n  checkModelName,\n  cleanSchema,\n  extractVersion,\n  modelName,\n  toInteractionsClientOptions,\n} from './utils.mjs';\n\nexport const SafetySettingsSchema = z\n  .object({\n    category: z.enum([\n      /** The harm category is unspecified. */\n      'HARM_CATEGORY_UNSPECIFIED',\n      /** The harm category is hate speech. */\n      'HARM_CATEGORY_HATE_SPEECH',\n      /** The harm category is dangerous content. */\n      'HARM_CATEGORY_DANGEROUS_CONTENT',\n      /** The harm category is harassment. */\n      'HARM_CATEGORY_HARASSMENT',\n      /** The harm category is sexually explicit content. */\n      'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n    ]),\n    threshold: z.enum([\n      'BLOCK_LOW_AND_ABOVE',\n      'BLOCK_MEDIUM_AND_ABOVE',\n      'BLOCK_ONLY_HIGH',\n      'BLOCK_NONE',\n    ]),\n  })\n  .passthrough();\n\nconst VertexRetrievalSchema = z\n  .object({\n    datastore: z\n      .object({\n        projectId: z.string().describe('Google Cloud Project ID.').optional(),\n        location: z\n          .string()\n          .describe('Google Cloud region e.g. us-central1.')\n          .optional(),\n        dataStoreId: z\n          .string()\n          .describe(\n            'The data store id, when project id and location are provided as ' +\n              'separate options. Alternatively, the full path to the data ' +\n              'store should be provided in the form: \"projects/{project}/' +\n              'locations/{location}/collections/default_collection/dataStores/{data_store}\".'\n          ),\n      })\n      .describe('Vertex AI Search data store details')\n      .passthrough(),\n    disableAttribution: z\n      .boolean()\n      .describe(\n        'Disable using the search data in detecting grounding attribution. This ' +\n          'does not affect how the result is given to the model for generation.'\n      )\n      .optional(),\n  })\n  .passthrough();\n\nconst GoogleSearchRetrievalSchema = z\n  .object({\n    disableAttribution: z\n      .boolean()\n      .describe(\n        'Disable using the search data in detecting grounding attribution. This ' +\n          'does not affect how the result is given to the model for generation.'\n      )\n      .optional(),\n  })\n  .passthrough();\n\n/**\n * Zod schema of Gemini model options.\n * Please refer to: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#generationconfig, for further information.\n */\nexport const GeminiConfigSchema = GenerationCommonConfigSchema.extend({\n  apiKey: z\n    .string()\n    .describe('Overrides the plugin-configured API key, if specified.')\n    .optional(),\n  apiVersion: z\n    .enum(['v1', 'v1beta1'])\n    .describe(\n      'Overrides the plugin-configured API version to use, if specified.'\n    )\n    .optional(),\n  labels: z\n    .record(z.string())\n    .optional()\n    .describe('Key-value labels to attach to the request for cost tracking.'),\n  temperature: z\n    .number()\n    .min(0.0)\n    .max(2.0)\n    .describe(\n      GenerationCommonConfigDescriptions.temperature +\n        ' The default value is 1.0.'\n    )\n    .optional(),\n  topP: z\n    .number()\n    .min(0)\n    .max(1.0)\n    .describe(\n      GenerationCommonConfigDescriptions.topP + ' The default value is 0.95.'\n    )\n    .optional(),\n  location: z\n    .string()\n    .describe('Google Cloud region e.g. us-central1.')\n    .optional(),\n  store: z\n    .boolean()\n    .describe(\n      'Whether to store the interaction for later retrieval. Defaults to ' +\n        'false. Only used by models on the Interactions API.'\n    )\n    .optional(),\n  previousInteractionId: z\n    .string()\n    .describe(\n      'The ID of the previous interaction to continue. Requires store. ' +\n        'Only used by models on the Interactions API.'\n    )\n    .optional(),\n\n  /**\n   * Safety filter settings. See: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/configure-safety-filters#configurable-filters\n   *\n   * E.g.\n   *\n   * ```js\n   * config: {\n   *   safetySettings: [\n   *     {\n   *       category: 'HARM_CATEGORY_HATE_SPEECH',\n   *       threshold: 'BLOCK_LOW_AND_ABOVE',\n   *     },\n   *     {\n   *       category: 'HARM_CATEGORY_DANGEROUS_CONTENT',\n   *       threshold: 'BLOCK_MEDIUM_AND_ABOVE',\n   *     },\n   *     {\n   *       category: 'HARM_CATEGORY_HARASSMENT',\n   *       threshold: 'BLOCK_ONLY_HIGH',\n   *     },\n   *     {\n   *       category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n   *       threshold: 'BLOCK_NONE',\n   *     },\n   *   ],\n   * }\n   * ```\n   */\n  safetySettings: annotateSchema(\n    z\n      .array(SafetySettingsSchema)\n      .describe(\n        'Adjust how likely you are to see responses that could be harmful. ' +\n          'Content is blocked based on the probability that it is harmful.'\n      )\n      .optional(),\n    { [GENKIT_UI_METADATA.WIDGET]: GENKIT_UI_WIDGETS.SAFETY_SETTINGS }\n  ),\n\n  /**\n   * Vertex retrieval options.\n   *\n   * E.g.\n   *\n   * ```js\n   *   config: {\n   *     vertexRetrieval: {\n   *       datastore: {\n   *         projectId: 'your-cloud-project',\n   *         location: 'us-central1',\n   *         collection: 'your-collection',\n   *       },\n   *       disableAttribution: true,\n   *     }\n   *   }\n   * ```\n   */\n  vertexRetrieval: VertexRetrievalSchema.describe(\n    'Retrieve from Vertex AI Search data store for grounding ' +\n      'generative responses.'\n  ).optional(),\n\n  /**\n   * Google Search retrieval options.\n   *\n   * ```js\n   *   config: {\n   *     googleSearchRetrieval: {\n   *       disableAttribution: true,\n   *     }\n   *   }\n   * ```\n   */\n  googleSearchRetrieval: GoogleSearchRetrievalSchema.describe(\n    'Retrieve public web data for grounding, powered by Google Search.'\n  ).optional(),\n\n  /**\n   * Function calling options.\n   *\n   * E.g. forced tool call:\n   *\n   * ```js\n   *   config: {\n   *     functionCallingConfig: {\n   *       mode: 'ANY',\n   *     }\n   *   }\n   * ```\n   */\n  functionCallingConfig: z\n    .object({\n      mode: z.enum(['MODE_UNSPECIFIED', 'AUTO', 'ANY', 'NONE']).optional(),\n      allowedFunctionNames: z.array(z.string()).optional(),\n      /**\n       * When set to true, arguments of a single function call will be streamed out in\n       * multiple parts/contents/responses. Partial parameter results will be returned in the\n       * [FunctionCall.partial_args] field. This field is not supported in Gemini API.\n       */\n      streamFunctionCallArguments: z.boolean().optional(),\n    })\n    .describe(\n      'Controls how the model uses the provided tools (function declarations). ' +\n        'With AUTO (Default) mode, the model decides whether to generate a ' +\n        'natural language response or suggest a function call based on the ' +\n        'prompt and context. With ANY, the model is constrained to always ' +\n        'predict a function call and guarantee function schema adherence. ' +\n        'With NONE, the model is prohibited from making function calls.'\n    )\n    .passthrough()\n    .optional(),\n  /**\n   * Retrieval config for search grounding and maps grounding\n   */\n  retrievalConfig: z\n    .object({\n      /**\n       * User location for search grounding or\n       * place location for maps grounding.\n       */\n      latLng: z\n        .object({\n          latitude: z.number().optional(),\n          longitude: z.number().optional(),\n        })\n        .describe('User location for Google search or Google maps grounding.')\n        .optional(),\n      /**\n       * Language code for the request. e.g. 'en-us'\n       */\n      languageCode: z.string().optional(),\n    })\n    .passthrough()\n    .optional(),\n  payGo: z\n    .enum(['priority', 'priority-only', 'flex', 'flex-only'])\n    .describe(\n      'PayGo consumption options. Priority provides more consistent performance than Standard PayGo. ' +\n        'Flex is a cost-effective option for non-critical workloads. ' +\n        'The \"-only\" options use only PayGo and no Provisioned Throughput.'\n    )\n    .optional(),\n  thinkingConfig: z\n    .object({\n      includeThoughts: z\n        .boolean()\n        .describe(\n          'Indicates whether to include thoughts in the response.' +\n            'If true, thoughts are returned only if the model supports ' +\n            'thought and thoughts are available.'\n        )\n        .optional(),\n      thinkingBudget: z\n        .number()\n        .min(0)\n        .max(24576)\n        .describe(\n          'For Gemini 2.5 - Indicates the thinking budget in tokens. 0 is DISABLED. ' +\n            '-1 is AUTOMATIC. The default values and allowed ranges are model ' +\n            'dependent. The thinking budget parameter gives the model guidance ' +\n            'on the number of thinking tokens it can use when generating a ' +\n            'response. A greater number of tokens is typically associated with ' +\n            'more detailed thinking, which is needed for solving more complex ' +\n            'tasks. '\n        )\n        .optional(),\n      thinkingLevel: z\n        .enum(['MINIMAL', 'LOW', 'MEDIUM', 'HIGH'])\n        .describe(\n          'For Gemini 3.0 - Indicates the thinking level. A higher level ' +\n            'is associated with more detailed thinking, which is needed for solving ' +\n            'more complex tasks.'\n        )\n        .optional(),\n    })\n    .passthrough()\n    .optional(),\n}).passthrough();\nexport type GeminiConfigSchemaType = typeof GeminiConfigSchema;\n/**\n * Gemini model configuration options.\n *\n * E.g.\n * ```js\n *   config: {\n *     temperature: 0.9,\n *     maxOutputTokens: 300,\n *     safetySettings: [\n *       {\n *         category: 'HARM_CATEGORY_HATE_SPEECH',\n *         threshold: 'BLOCK_LOW_AND_ABOVE',\n *       },\n *       {\n *         category: 'HARM_CATEGORY_DANGEROUS_CONTENT',\n *         threshold: 'BLOCK_MEDIUM_AND_ABOVE',\n *       },\n *       {\n *         category: 'HARM_CATEGORY_HARASSMENT',\n *         threshold: 'BLOCK_ONLY_HIGH',\n *       },\n *       {\n *         category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n *         threshold: 'BLOCK_NONE',\n *       },\n *     ],\n *     functionCallingConfig: {\n *       mode: 'ANY',\n *     }\n *   }\n * ```\n */\nexport type GeminiConfig = z.infer<GeminiConfigSchemaType>;\n\nexport const GeminiImageConfigSchema = GeminiConfigSchema.extend({\n  imageConfig: z\n    .object({\n      aspectRatio: z\n        .enum([\n          '1:1',\n          '2:3',\n          '3:2',\n          '3:4',\n          '4:3',\n          '4:5',\n          '5:4',\n          '9:16',\n          '16:9',\n          '21:9',\n        ])\n        .optional(),\n      imageSize: z.enum(['512', '1K', '2K', '4K']).optional(),\n    })\n    .passthrough()\n    .optional(),\n}).passthrough();\nexport type GeminiImageConfigSchemaType = typeof GeminiImageConfigSchema;\nexport type GeminiImageConfig = z.infer<GeminiImageConfigSchemaType>;\n\nconst VoiceConfigSchema = z\n  .object({\n    voice: z\n      .union([\n        z.enum([\n          'Zephyr',\n          'Puck',\n          'Charon',\n          'Kore',\n          'Fenrir',\n          'Leda',\n          'Orus',\n          'Aoede',\n          'Callirrhoe',\n          'Autonoe',\n          'Enceladus',\n          'Iapetus',\n          'Umbriel',\n          'Algieba',\n          'Despina',\n          'Erinome',\n          'Algenib',\n          'Rasalgethi',\n          'Laomedeia',\n          'Achernar',\n          'Alnilam',\n          'Schedar',\n          'Gacrux',\n          'Pulcherrima',\n          'Achird',\n          'Zubenelgenubi',\n          'Vindemiatrix',\n          'Sadachbia',\n          'Sadaltager',\n          'Sulafat',\n        ]),\n        // Voice Library and custom voice IDs (e.g. `voice_...`). `string & {}`\n        // keeps the prebuilt names in TypeScript autocomplete.\n        z.custom<string & {}>((val) => typeof val === 'string'),\n      ])\n      .describe(\n        'A prebuilt voice name, an Extended Voice Library voice ID, or a ' +\n          'custom voice ID.'\n      )\n      .optional(),\n    // The googleAI shape, also accepted by the platform, so TTS code can move\n    // between the two plugins.\n    prebuiltVoiceConfig: z\n      .object({\n        voiceName: z.string().describe('Name of the preset voice to use'),\n      })\n      .passthrough()\n      .optional(),\n  })\n  .describe(\n    'Configuration for the voice to use: `voice`, or `prebuiltVoiceConfig` ' +\n      '(the googleAI shape)'\n  )\n  .passthrough();\n\nexport const GeminiTtsConfigSchema = GeminiConfigSchema.extend({\n  speechConfig: z\n    .object({\n      voiceConfig: VoiceConfigSchema.optional(),\n      multiSpeakerVoiceConfig: z\n        .object({\n          speakerVoiceConfigs: z\n            .array(\n              z\n                .object({\n                  speaker: z.string().describe('Name of the speaker to use'),\n                  voiceConfig: VoiceConfigSchema,\n                })\n                .describe(\n                  'Configuration for a single speaker in a multi speaker setup'\n                )\n                .passthrough()\n            )\n            .describe(\n              'Configuration for the two speaker voices. Each text part must ' +\n                'name its speaker in `metadata.speechMetadata.speaker`.'\n            ),\n        })\n        .describe('Configuration for multi-speaker setup')\n        .passthrough()\n        .optional(),\n    })\n    .describe('Speech generation config')\n    .passthrough()\n    .optional(),\n  audioFormat: z\n    .object({\n      mimeType: z\n        .union([\n          z.enum(['audio/wav', 'audio/l16', 'audio/mulaw', 'audio/alaw']),\n          z.custom<string & {}>((val) => typeof val === 'string'),\n        ])\n        .describe(\n          'Audio encoding. Defaults to audio/wav (with a header) for ' +\n            'non-streamed requests and audio/l16 (raw PCM, no header) for ' +\n            'streamed requests.'\n        )\n        .optional(),\n    })\n    .describe('Format of the generated audio.')\n    .passthrough()\n    .optional(),\n}).passthrough();\nexport type GeminiTtsConfigSchemaType = typeof GeminiTtsConfigSchema;\nexport type GeminiTtsConfig = z.infer<GeminiTtsConfigSchemaType>;\n\n// Gemini Omni (video generation). The fields follow the platform's\n// Interactions `VideoResponseFormat` and the Omni guide's `video_config`.\nexport const GeminiVideoConfigSchema = GeminiConfigSchema.extend({\n  videoFormat: z\n    .object({\n      aspectRatio: z\n        .union([\n          z.enum(['16:9', '9:16']),\n          // Allows other values. `string & {}` (rather than z.string()) keeps\n          // the listed ones in TypeScript autocomplete.\n          z.custom<string & {}>((val) => typeof val === 'string'),\n        ])\n        .describe(\n          'Aspect ratio of the generated video. Defaults to 16:9 (landscape).'\n        )\n        .optional(),\n      resolution: z\n        .union([\n          z.enum(['360p', '720p', '1080p', '4k']),\n          z.custom<string & {}>((val) => typeof val === 'string'),\n        ])\n        .describe('Resolution of the generated video. Defaults to 720p.')\n        .optional(),\n      delivery: z\n        .union([\n          z.enum(['inline', 'uri']),\n          z.custom<string & {}>((val) => typeof val === 'string'),\n        ])\n        .describe(\n          'How the video is returned. By default it is returned inline. ' +\n            '\"uri\" stores it in Cloud Storage instead (set gcsUri).'\n        )\n        .optional(),\n      gcsUri: z\n        .string()\n        .describe(\n          'The Cloud Storage URI to store the video in. Required when ' +\n            'delivery is \"uri\".'\n        )\n        .optional(),\n    })\n    .describe('Format of the generated video.')\n    .passthrough()\n    .optional(),\n  videoConfig: z\n    .object({\n      task: z\n        .union([\n          z.enum([\n            'text_to_video',\n            'image_to_video',\n            'reference_to_video',\n            'edit',\n            'extend',\n          ]),\n          z.custom<string & {}>((val) => typeof val === 'string'),\n        ])\n        .describe(\n          'The kind of generation to perform. If not set, the model infers ' +\n            'it from the prompt and inputs.'\n        )\n        .optional(),\n    })\n    .describe('Video generation settings.')\n    .passthrough()\n    .optional(),\n}).passthrough();\nexport type GeminiVideoConfigSchemaType = typeof GeminiVideoConfigSchema;\nexport type GeminiVideoConfig = z.infer<GeminiVideoConfigSchemaType>;\n\n// This contains all the Gemini config schema types\ntype ConfigSchemaType =\n  | GeminiConfigSchemaType\n  | GeminiImageConfigSchemaType\n  | GeminiTtsConfigSchemaType\n  | GeminiVideoConfigSchemaType;\ntype ConfigSchema = z.infer<ConfigSchemaType>;\n\n/** Whether each known model uses the Interactions API (see `usesInteractions`). */\nconst modelInteractionsMap = new Map<string, boolean>();\n\nfunction commonRef(\n  name: string,\n  info?: ModelInfo,\n  configSchema: ConfigSchemaType = GeminiConfigSchema,\n  useInteractions: boolean = true\n): ModelReference<ConfigSchemaType> {\n  modelInteractionsMap.set(name, useInteractions);\n\n  return modelRef({\n    name: `vertexai/${name}`,\n    configSchema,\n    info: info ?? {\n      supports: {\n        multiturn: true,\n        media: true,\n        tools: true,\n        toolChoice: true,\n        systemRole: true,\n        constrained: 'all',\n      },\n    },\n  });\n}\n\nconst GENERIC_MODEL = commonRef('gemini');\nconst GENERIC_IMAGE_MODEL = commonRef(\n  'gemini-image',\n  undefined,\n  GeminiImageConfigSchema\n);\nconst GENERIC_TTS_MODEL = commonRef(\n  'gemini-tts',\n  {\n    supports: {\n      multiturn: false,\n      media: false,\n      tools: false,\n      toolChoice: false,\n      systemRole: false,\n      constrained: 'none',\n      output: ['media'],\n    },\n  },\n  GeminiTtsConfigSchema,\n  false\n);\n// Per the Omni guide: text, image and video in, video (with audio) out; edits\n// continue a stored interaction. Tools and structured output aren't\n// documented for video generation.\nconst GENERIC_VIDEO_MODEL = commonRef(\n  'gemini-video',\n  {\n    supports: {\n      multiturn: true,\n      media: true,\n      tools: false,\n      toolChoice: false,\n      systemRole: true,\n      constrained: 'none',\n      output: ['media'],\n    },\n  },\n  GeminiVideoConfigSchema\n);\n\n// Models with `false` stay on generateContent: older models (like in the\n// googleAI plugin) and models whose docs page says the Interactions API isn't\n// supported.\nexport const KNOWN_GEMINI_MODELS = {\n  'gemini-4-argon': commonRef('gemini-4-argon'),\n  // Allowlist only.\n  'gemini-4-argon-cyber-permissive': commonRef(\n    'gemini-4-argon-cyber-permissive'\n  ),\n  'gemini-3.8-flash': commonRef('gemini-3.8-flash'),\n  // Allowlist only.\n  'gemini-3.8-flash-cyber': commonRef(\n    'gemini-3.8-flash-cyber',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-3.7-flash': commonRef('gemini-3.7-flash'),\n  'gemini-3.5-flash-lite': commonRef('gemini-3.5-flash-lite'),\n  'gemini-3.5-flash': commonRef(\n    'gemini-3.5-flash',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-3.1-flash-lite': commonRef(\n    'gemini-3.1-flash-lite',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-3.1-pro-preview': commonRef(\n    'gemini-3.1-pro-preview',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n  // Optimized for custom tools (an extra endpoint of 3.1 Pro).\n  'gemini-3.1-pro-preview-customtools': commonRef(\n    'gemini-3.1-pro-preview-customtools',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-3-flash-preview': commonRef(\n    'gemini-3-flash-preview',\n    undefined,\n    GeminiConfigSchema,\n    false\n  ),\n} as const;\nexport type KnownGeminiModels = keyof typeof KNOWN_GEMINI_MODELS;\nexport type GeminiModelName = `gemini-${string}`;\nexport function isGeminiModelName(value?: string): value is GeminiModelName {\n  return !!(\n    value?.startsWith('gemini-') &&\n    !value.includes('embedding') &&\n    !isImageModelName(value) &&\n    !isTTSModelName(value) &&\n    !isVideoModelName(value)\n  );\n}\n\nexport const KNOWN_IMAGE_MODELS = {\n  // seed, topK, logprobs, temperature and topP aren't supported (the server\n  // returns an error).\n  'gemini-nano-banana-2.1': commonRef(\n    'gemini-nano-banana-2.1',\n    { ...GENERIC_IMAGE_MODEL.info },\n    GeminiImageConfigSchema,\n    false\n  ),\n  'gemini-3.1-flash-lite-image': commonRef(\n    'gemini-3.1-flash-lite-image',\n    { ...GENERIC_IMAGE_MODEL.info },\n    GeminiImageConfigSchema,\n    false\n  ),\n  'gemini-3.1-flash-image': commonRef(\n    'gemini-3.1-flash-image',\n    { ...GENERIC_IMAGE_MODEL.info },\n    GeminiImageConfigSchema,\n    false\n  ),\n  'gemini-3-pro-image': commonRef(\n    'gemini-3-pro-image',\n    { ...GENERIC_IMAGE_MODEL.info },\n    GeminiImageConfigSchema,\n    false\n  ),\n  'gemini-2.5-flash-image': commonRef(\n    'gemini-2.5-flash-image',\n    undefined,\n    GeminiImageConfigSchema,\n    false\n  ),\n} as const;\nexport type KnownImageModels = keyof typeof KNOWN_IMAGE_MODELS;\nexport type ImageModelName =\n  | `gemini-${string}-image${string}`\n  | `gemini-nano-banana-${string}`;\nexport function isImageModelName(value?: string): value is ImageModelName {\n  return !!(\n    value?.startsWith('gemini-') &&\n    (value.includes('-image') || value.startsWith('gemini-nano-banana-'))\n  );\n}\n\n// TTS models only work on generateContent (the Interactions API rejects them,\n// checked live Oct 2026).\nexport const KNOWN_TTS_MODELS = {\n  'gemini-3.8-flash-tts': commonRef(\n    'gemini-3.8-flash-tts',\n    { ...GENERIC_TTS_MODEL.info },\n    GeminiTtsConfigSchema,\n    false\n  ),\n  'gemini-3.8-flash-lite-tts': commonRef(\n    'gemini-3.8-flash-lite-tts',\n    { ...GENERIC_TTS_MODEL.info },\n    GeminiTtsConfigSchema,\n    false\n  ),\n} as const;\nexport type KnownTtsModels = keyof typeof KNOWN_TTS_MODELS;\nexport type TTSModelName = `gemini-${string}-tts${string}`;\nexport function isTTSModelName(value?: string): value is TTSModelName {\n  return !!(value?.startsWith('gemini-') && value.includes('-tts'));\n}\n\n// Omni video models use the Interactions API.\nexport const KNOWN_VIDEO_MODELS = {\n  'gemini-omni-1.1-flash-preview': commonRef(\n    'gemini-omni-1.1-flash-preview',\n    { ...GENERIC_VIDEO_MODEL.info },\n    GeminiVideoConfigSchema\n  ),\n  'gemini-omni-flash-preview': commonRef(\n    'gemini-omni-flash-preview',\n    { ...GENERIC_VIDEO_MODEL.info },\n    GeminiVideoConfigSchema\n  ),\n} as const;\nexport type KnownVideoModels = keyof typeof KNOWN_VIDEO_MODELS;\nexport type VideoModelName = `gemini-omni-${string}`;\nexport function isVideoModelName(value?: string): value is VideoModelName {\n  return !!value?.startsWith('gemini-omni-');\n}\n\nconst KNOWN_MODELS = {\n  ...KNOWN_GEMINI_MODELS,\n  ...KNOWN_IMAGE_MODELS,\n  ...KNOWN_TTS_MODELS,\n  ...KNOWN_VIDEO_MODELS,\n};\nexport type KnownModels = keyof typeof KNOWN_MODELS;\n\n// Models we no longer suggest, but that still work: they still resolve and\n// are still registered as actions, but aren't in the Known*Models types, so\n// they don't show up in autocomplete. Set `stage` on each one (keeping the\n// default `supports`):\n// - 'deprecated': deprecated by Google, or < 1 month from shutdown.\n// - 'legacy': not deprecated, but no longer offered to new projects.\n// Remove a model once the server returns 404 for it.\nconst HIDDEN_MODELS = {\n  // Retirement date Oct 20 2026; kept until the server stops serving them.\n  // They aren't on the Interactions API, so they must stay listed (`false`):\n  // unlisted names would be sent to the Interactions API.\n  'gemini-2.5-pro': commonRef(\n    'gemini-2.5-pro',\n    { ...GENERIC_MODEL.info, stage: 'deprecated' },\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-2.5-flash': commonRef(\n    'gemini-2.5-flash',\n    { ...GENERIC_MODEL.info, stage: 'deprecated' },\n    GeminiConfigSchema,\n    false\n  ),\n  'gemini-2.5-flash-lite': commonRef(\n    'gemini-2.5-flash-lite',\n    { ...GENERIC_MODEL.info, stage: 'deprecated' },\n    GeminiConfigSchema,\n    false\n  ),\n} as const;\n\nconst ALL_MODELS = {\n  ...HIDDEN_MODELS,\n  ...KNOWN_MODELS,\n};\n\n/**\n * Whether a model is called through the Interactions API. Known older models\n * stay on generateContent (`false` in their `commonRef`); newer and unlisted\n * models use the Interactions API. Tuned model endpoints stay on\n * generateContent.\n */\nfunction usesInteractions(modelVersion: string): boolean {\n  if (modelVersion.includes('endpoints/')) {\n    return false;\n  }\n  // The platform's Interactions API doesn't support image or TTS models (it\n  // returns 400 \"Model 'gemini-nano-banana-2.1' is not supported by the\n  // Interactions API\"; the 3.8 TTS models fail too; Oct 2026), so they stay\n  // on generateContent.\n  return (\n    modelInteractionsMap.get(modelVersion) ??\n    !(isImageModelName(modelVersion) || isTTSModelName(modelVersion))\n  );\n}\n\nexport function model(\n  version: string,\n  config: ConfigSchema = {}\n): ModelReference<ConfigSchemaType> {\n  const name = checkModelName(version);\n\n  if (isKnownKey(name, ALL_MODELS)) {\n    return ALL_MODELS[name].withConfig(config);\n  }\n\n  if (isImageModelName(name)) {\n    return modelRef({\n      name: `vertexai/${name}`,\n      config,\n      configSchema: GeminiImageConfigSchema,\n      info: { ...GENERIC_IMAGE_MODEL.info },\n    });\n  }\n\n  if (isVideoModelName(name)) {\n    return modelRef({\n      name: `vertexai/${name}`,\n      config,\n      configSchema: GeminiVideoConfigSchema,\n      info: { ...GENERIC_VIDEO_MODEL.info },\n    });\n  }\n\n  if (isTTSModelName(name)) {\n    return modelRef({\n      name: `vertexai/${name}`,\n      config,\n      configSchema: GeminiTtsConfigSchema,\n      info: { ...GENERIC_TTS_MODEL.info },\n    });\n  }\n\n  return modelRef({\n    name: `vertexai/${name}`,\n    config,\n    configSchema: GeminiConfigSchema,\n    info: {\n      ...GENERIC_MODEL.info,\n    },\n  });\n}\n\nexport function listActions(models: Model[]): ActionMetadata[] {\n  const KNOWN_DECOMISSIONED_MODELS = [\n    'gemini-pro-vision',\n    'gemini-pro',\n    'gemini-ultra',\n    'gemini-ultra-vision',\n  ];\n\n  return models\n    .filter(\n      (m) =>\n        (isGeminiModelName(modelName(m.name)) ||\n          isImageModelName(modelName(m.name)) ||\n          isTTSModelName(modelName(m.name)) ||\n          isVideoModelName(modelName(m.name))) &&\n        !KNOWN_DECOMISSIONED_MODELS.includes(modelName(m.name) || '')\n    )\n    .map((m) => {\n      const ref = model(m.name);\n      return modelActionMetadata({\n        name: ref.name,\n        info: ref.info,\n        configSchema: ref.configSchema,\n      });\n    });\n}\n\nexport function listKnownModels(\n  clientOptions: ClientOptions,\n  pluginOptions?: VertexPluginOptions\n) {\n  return Object.keys(ALL_MODELS).map((name) =>\n    defineModel(name, clientOptions, pluginOptions)\n  );\n}\n\n/**\n * Converts the TTS `audioFormat` config (`{ mimeType: 'audio/mulaw' }`) to\n * the generateContent `responseFormat` (`[{ audio: { mimeType:\n * 'AUDIO_MULAW' } }]`). Returns `undefined` if it isn't set, so the server\n * defaults apply (audio/wav, or audio/l16 when streaming).\n */\nfunction toGeminiAudioResponseFormat(\n  audioFormat: unknown\n): Record<string, unknown>[] | undefined {\n  if (!isObject(audioFormat) || typeof audioFormat.mimeType !== 'string') {\n    return undefined;\n  }\n  const { mimeType, ...rest } = audioFormat;\n  return [\n    {\n      audio: {\n        ...rest,\n        // 'audio/mulaw' -> 'AUDIO_MULAW'; enum values pass through.\n        mimeType: mimeType.toUpperCase().replace('/', '_'),\n      },\n    },\n  ];\n}\n\n/**\n * Builds the Agent Search data store path for `vertexRetrieval`, filling in\n * the project and location from the plugin options when not set.\n */\nfunction toVertexAISearchDatastore(\n  vertexRetrieval: NonNullable<ConfigSchema['vertexRetrieval']>,\n  clientOptions: ClientOptions\n): string {\n  const projectId =\n    vertexRetrieval.datastore.projectId ||\n    (clientOptions.kind != 'express' ? clientOptions.projectId : undefined);\n  // Data stores are in `global`, `us` or `eu`, so global and multi-regional\n  // client locations are valid fallbacks.\n  // TODO: Regional locations (e.g. us-central1) aren't data store locations;\n  // falling back to one probably fails on the server. Kept as before until\n  // checked live.\n  const location =\n    vertexRetrieval.datastore.location ||\n    (clientOptions.kind != 'express' ? clientOptions.location : undefined);\n  const dataStoreId = vertexRetrieval.datastore.dataStoreId;\n  if (!projectId || !location || !dataStoreId) {\n    throw new GenkitError({\n      status: 'INVALID_ARGUMENT',\n      message:\n        'projectId, location and datastoreId are required for vertexRetrieval and could not be determined from configuration',\n    });\n  }\n  return `projects/${projectId}/locations/${location}/collections/default_collection/dataStores/${dataStoreId}`;\n}\n\n/**\n * Converts the request's tools and tool config fields to Interactions tools.\n */\nfunction toVertexInteractionTools(\n  request: GenerateRequest,\n  config: ConfigSchema,\n  clientOptions: ClientOptions,\n  warnDropped: (field: string) => void\n): InteractionTool[] {\n  const tools: InteractionTool[] = [];\n  if (request.tools?.length) {\n    tools.push(...request.tools.map(toInteractionTool));\n  }\n  if (Array.isArray(config.tools)) {\n    tools.push(...config.tools.map(toInteractionConfigTool));\n  }\n  if (config.googleSearchRetrieval) {\n    const { disableAttribution, ...searchConfig } =\n      config.googleSearchRetrieval;\n    if (disableAttribution !== undefined) {\n      warnDropped('googleSearchRetrieval.disableAttribution');\n    }\n    tools.push(toInteractionGoogleSearch(searchConfig));\n  }\n  const vertexRetrieval = config.vertexRetrieval;\n  if (vertexRetrieval) {\n    if (vertexRetrieval.disableAttribution !== undefined) {\n      warnDropped('vertexRetrieval.disableAttribution');\n    }\n    tools.push({\n      type: 'retrieval',\n      retrieval_types: ['vertex_ai_search'],\n      vertex_ai_search_config: {\n        datastores: [toVertexAISearchDatastore(vertexRetrieval, clientOptions)],\n      },\n    });\n  }\n  if (config.retrievalConfig) {\n    // There is no retrieval config on the Interactions path; the user\n    // location is set on the google_maps tool instead.\n    const { latLng, ...unsupportedRetrievalConfig } = config.retrievalConfig;\n    if (latLng && !applyLatLngToGoogleMapsTools(tools, latLng)) {\n      logger.warn(\n        'retrievalConfig.latLng is only used with the googleMaps tool for this model and will be ignored.'\n      );\n    }\n    for (const key of Object.keys(unsupportedRetrievalConfig)) {\n      warnDropped(`retrievalConfig.${key}`);\n    }\n  }\n  return tools;\n}\n\n/**\n * Generates a response with the Interactions API (see `usesInteractions`).\n */\nasync function generateWithInteractions(params: {\n  request: GenerateRequest;\n  /** The request messages, without the system message. */\n  messages: MessageData[];\n  systemMessage?: MessageData;\n  modelVersion: string;\n  config: ConfigSchema;\n  /** The plugin's client options (used for the vertexRetrieval fallback). */\n  pluginClientOptions: ClientOptions;\n  /** The client options for this request (location, API key, headers). */\n  requestClientOptions: ClientOptions;\n  pluginOptions?: VertexPluginOptions;\n  streamingRequested: boolean;\n  sendChunk: (chunk: GenerateResponseChunkData) => void;\n}): Promise<GenerateResponseData> {\n  const { request, modelVersion, pluginOptions, config } = params;\n  const {\n    // Applied to the client options and headers by the caller.\n    apiKey: _apiKey,\n    apiVersion: _apiVersion,\n    location: _location,\n    payGo: _payGo,\n    version: _version,\n    // Converted to tools (toVertexInteractionTools).\n    tools: _tools,\n    googleSearchRetrieval: _googleSearchRetrieval,\n    vertexRetrieval: _vertexRetrieval,\n    retrievalConfig: _retrievalConfig,\n    functionCallingConfig,\n    safetySettings,\n    labels,\n    store: storeFromConfig,\n    previousInteractionId: previousInteractionIdFromConfig,\n    responseModalities,\n    // Sent as `response_format` below.\n    videoFormat,\n    // TTS models don't use the Interactions API.\n    audioFormat,\n    ...generationFields\n  } = config;\n  const warnDropped = (field: string) =>\n    warnDroppedConfigField(modelVersion, field);\n  if (audioFormat !== undefined) {\n    warnDropped('audioFormat');\n  }\n\n  const systemMessage = params.systemMessage;\n  if (systemMessage?.content.some((c) => c.text === undefined)) {\n    throw new GenkitError({\n      status: 'INVALID_ARGUMENT',\n      message:\n        'System message contains non-text content which is not supported for this model.',\n    });\n  }\n\n  if (request.candidates && request.candidates > 1) {\n    logger.warn(\n      'Multiple candidates are not supported for this model with the Interactions API; only one candidate will be returned.'\n    );\n  }\n\n  // The vertexRetrieval data store fallback uses the plugin's project and\n  // location, not `config.location` (same as on generateContent).\n  const tools = toVertexInteractionTools(\n    request,\n    config,\n    params.pluginClientOptions,\n    warnDropped\n  );\n\n  if (functionCallingConfig?.streamFunctionCallArguments !== undefined) {\n    warnDropped('functionCallingConfig.streamFunctionCallArguments');\n  }\n  const generationConfig = toInteractionGenerationConfig(\n    generationFields,\n    warnDropped\n  );\n  const toolChoice = toInteractionToolChoice(\n    functionCallingConfig,\n    request.toolChoice\n  );\n  if (toolChoice) {\n    generationConfig.tool_choice = toolChoice;\n  }\n\n  const store = storeFromConfig === true || pluginOptions?.store === true;\n  const { messages, previousInteractionId } = selectInteractionInput(\n    params.messages,\n    store,\n    previousInteractionIdFromConfig\n  );\n\n  const req: CreateInteractionRequest = {\n    system_instruction: systemMessage?.content.map((c) => c.text).join('\\n'),\n    model: modelVersion,\n    tools: tools.length ? tools : undefined,\n    generation_config: generationConfig,\n    stream: params.streamingRequested,\n    input: toInteractionSteps(messages),\n    store,\n    safety_settings: toInteractionSafetySettings(safetySettings),\n    labels: toGeminiLabels(labels),\n  };\n  if (previousInteractionId) {\n    req.previous_interaction_id = previousInteractionId;\n  }\n\n  const jsonMode =\n    request.output?.format === 'json' || !!request.output?.schema;\n  if (jsonMode) {\n    req.response_format = { type: 'text', mime_type: 'application/json' };\n    if (request.output?.constrained) {\n      req.response_format.schema = pluginOptions?.legacyResponseSchema\n        ? cleanSchema(request.output.schema)\n        : request.output.schema;\n    }\n  }\n\n  const videoResponseFormat = toInteractionVideoResponseFormat(videoFormat);\n  if (videoResponseFormat) {\n    req.response_format = videoResponseFormat;\n  }\n\n  if (Array.isArray(responseModalities) && isStringArray(responseModalities)) {\n    req.response_modalities =\n      toInteractionResponseModalities(responseModalities);\n  } else if (isImageModelName(modelVersion)) {\n    req.response_modalities = ['text', 'image'];\n  }\n\n  if (!params.streamingRequested) {\n    return fromInteractionSync(\n      await createInteraction(req, params.requestClientOptions)\n    );\n  }\n  const result = await createInteractionStream(\n    req,\n    params.requestClientOptions\n  );\n  for await (const event of result.stream) {\n    if (event.event_type === 'step.delta') {\n      const content = fromInteractionDelta(event.delta);\n      if (content.length > 0) {\n        params.sendChunk({ index: 0, content });\n      }\n    }\n  }\n  return fromInteractionSync(await result.response);\n}\n\n/**\n * Define a Vertex AI Gemini model.\n */\nexport function defineModel(\n  name: string,\n  clientOptions: ClientOptions,\n  pluginOptions?: VertexPluginOptions\n): ModelAction {\n  const ref = model(name);\n  const middlewares: ModelMiddleware[] = [];\n  if (ref.info?.supports?.media) {\n    // the gemini api doesn't support downloading media from http(s)\n    middlewares.push(\n      downloadRequestMedia({\n        maxBytes: 1024 * 1024 * 20,\n        filter: (part) => {\n          try {\n            const url = new URL(part.media.url);\n            if (\n              // Gemini can handle these URLs\n              ['www.youtube.com', 'youtube.com', 'youtu.be'].includes(\n                url.hostname\n              )\n            )\n              return false;\n          } catch {}\n          return true;\n        },\n      })\n    );\n  }\n\n  return pluginModel(\n    {\n      name: ref.name,\n      ...ref.info,\n      configSchema: ref.configSchema,\n      use: middlewares,\n    },\n    async (request, { streamingRequested, sendChunk, abortSignal }) => {\n      let clientOpt = { ...clientOptions, signal: abortSignal };\n\n      // Make a copy of messages to avoid side-effects\n      const messages = structuredClone(request.messages);\n      if (messages.length === 0) throw new Error('No messages provided.');\n\n      // Handle system instructions separately\n      let systemInstruction: Content | undefined = undefined;\n      const systemMessage = messages.find((m) => m.role === 'system');\n      if (systemMessage) {\n        messages.splice(messages.indexOf(systemMessage), 1);\n        systemInstruction = toGeminiSystemInstruction(systemMessage);\n      }\n\n      const requestConfig: ConfigSchema = { ...request.config };\n\n      const {\n        apiKey: apiKeyFromConfig,\n        apiVersion: apiVersionFromConfig,\n        functionCallingConfig,\n        retrievalConfig,\n        version: versionFromConfig,\n        googleSearchRetrieval,\n        tools: toolsFromConfig,\n        vertexRetrieval,\n        location,\n        safetySettings,\n        labels: labelsFromConfig,\n        payGo,\n        store: storeFromConfig,\n        previousInteractionId: previousInteractionIdFromConfig,\n        // TTS models: sent as `responseFormat` below.\n        audioFormat: audioFormatFromConfig,\n        // Video (Omni) models use the Interactions API.\n        videoFormat: videoFormatFromConfig,\n        ...restOfConfig\n      } = requestConfig;\n\n      clientOpt = calculateRequestOptions(clientOpt, {\n        location,\n        apiKey: apiKeyFromConfig,\n        apiVersion: apiVersionFromConfig,\n      });\n\n      if (payGo) {\n        const payGoHeaders: Record<string, string> = {};\n        if (payGo === 'priority') {\n          payGoHeaders['X-Vertex-AI-LLM-Shared-Request-Type'] = 'priority';\n        } else if (payGo === 'priority-only') {\n          payGoHeaders['X-Vertex-AI-LLM-Request-Type'] = 'shared';\n          payGoHeaders['X-Vertex-AI-LLM-Shared-Request-Type'] = 'priority';\n        } else if (payGo === 'flex') {\n          payGoHeaders['X-Vertex-AI-LLM-Shared-Request-Type'] = 'flex';\n        } else if (payGo === 'flex-only') {\n          payGoHeaders['X-Vertex-AI-LLM-Request-Type'] = 'shared';\n          payGoHeaders['X-Vertex-AI-LLM-Shared-Request-Type'] = 'flex';\n        }\n        clientOpt.customHeaders = {\n          ...clientOpt.customHeaders,\n          ...payGoHeaders,\n        };\n      }\n\n      const modelVersion = versionFromConfig || extractVersion(ref);\n      if (usesInteractions(modelVersion)) {\n        return generateWithInteractions({\n          request,\n          messages,\n          systemMessage,\n          modelVersion,\n          config: requestConfig,\n          pluginClientOptions: clientOptions,\n          // A defaulted location (us-central1) becomes global here.\n          requestClientOptions: toInteractionsClientOptions(clientOpt),\n          pluginOptions,\n          streamingRequested,\n          sendChunk,\n        });\n      }\n\n      // `store: false` is already how this model behaves, so only warn when\n      // something would actually be ignored.\n      if (storeFromConfig === true || previousInteractionIdFromConfig) {\n        logger.warn(\n          'store and previousInteractionId are not supported for this model and will be ignored.'\n        );\n      }\n      if (videoFormatFromConfig !== undefined) {\n        warnDroppedConfigField(modelVersion, 'videoFormat');\n      }\n\n      const labels = toGeminiLabels(labelsFromConfig);\n\n      const tools: Tool[] = [];\n      if (request.tools?.length) {\n        tools.push({\n          functionDeclarations: request.tools.map(toGeminiTool),\n        });\n      }\n\n      let toolConfig: ToolConfig | undefined;\n      if (functionCallingConfig) {\n        toolConfig = {\n          functionCallingConfig: {\n            ...functionCallingConfig,\n            allowedFunctionNames: functionCallingConfig.allowedFunctionNames,\n            mode: toGeminiFunctionModeEnum(functionCallingConfig.mode),\n          },\n        };\n      } else if (request.toolChoice) {\n        toolConfig = {\n          functionCallingConfig: {\n            mode: toGeminiFunctionModeEnum(request.toolChoice),\n          },\n        };\n      }\n\n      if (retrievalConfig) {\n        if (!toolConfig) {\n          toolConfig = {};\n        }\n        toolConfig.retrievalConfig = structuredClone(retrievalConfig);\n      }\n\n      const jsonMode =\n        request.output?.format === 'json' || !!request.output?.schema;\n\n      if (toolsFromConfig) {\n        tools.push(...(toolsFromConfig as any[]));\n      }\n\n      if (googleSearchRetrieval) {\n        tools.push({\n          googleSearch: googleSearchRetrieval as GoogleSearchRetrieval,\n        });\n      }\n\n      if (vertexRetrieval) {\n        tools.push({\n          retrieval: {\n            vertexAiSearch: {\n              datastore: toVertexAISearchDatastore(\n                vertexRetrieval,\n                clientOptions\n              ),\n            },\n            disableAttribution: vertexRetrieval.disableAttribution,\n          },\n        });\n      }\n\n      const generateContentRequest: GenerateContentRequest = {\n        systemInstruction,\n        generationConfig: {\n          ...restOfConfig,\n          candidateCount: request.candidates || undefined,\n          responseMimeType: jsonMode ? 'application/json' : undefined,\n        },\n        tools,\n        toolConfig,\n        safetySettings: toGeminiSafetySettings(safetySettings),\n        contents: messages.map((message) => toGeminiMessage(message, ref)),\n        labels,\n      };\n\n      if (isImageModelName(modelVersion)) {\n        if (!generateContentRequest.generationConfig!.responseModalities) {\n          generateContentRequest.generationConfig!.responseModalities = [\n            'TEXT',\n            'IMAGE',\n          ];\n        }\n      } else if (isTTSModelName(modelVersion)) {\n        if (!generateContentRequest.generationConfig!.responseModalities) {\n          generateContentRequest.generationConfig!.responseModalities = [\n            'AUDIO',\n          ];\n        }\n      }\n\n      const responseFormat = toGeminiAudioResponseFormat(audioFormatFromConfig);\n      if (responseFormat) {\n        generateContentRequest.generationConfig!.responseFormat =\n          responseFormat;\n      }\n\n      if (jsonMode && request.output?.constrained) {\n        if (pluginOptions?.legacyResponseSchema) {\n          generateContentRequest.generationConfig!.responseSchema = cleanSchema(\n            request.output.schema\n          );\n        } else {\n          generateContentRequest.generationConfig!.responseJsonSchema =\n            request.output.schema;\n        }\n      }\n\n      let response: GenerateContentResponse;\n\n      // Handle streaming and non-streaming responses\n      if (streamingRequested) {\n        const result = await generateContentStream(\n          modelVersion,\n          generateContentRequest,\n          clientOpt\n        );\n\n        const chunks: CandidateData[] = [];\n        for await (const item of result.stream) {\n          (item as GenerateContentResponse).candidates?.forEach((candidate) => {\n            const c = fromGeminiCandidate(candidate, chunks);\n            chunks.push(c);\n            sendChunk({\n              index: c.index,\n              content: c.message.content,\n            });\n          });\n        }\n        response = await result.response;\n      } else {\n        response = await generateContent(\n          modelVersion,\n          generateContentRequest,\n          clientOpt\n        );\n      }\n\n      if (!response.candidates?.length) {\n        throw new GenkitError({\n          status: 'FAILED_PRECONDITION',\n          message: 'No valid candidates returned.',\n        });\n      }\n\n      const candidateData = response.candidates.map((c) =>\n        fromGeminiCandidate(c)\n      );\n      if (streamingRequested && isTTSModelName(modelVersion)) {\n        // Streamed audio arrives as many headerless chunks (audio/l16 by\n        // default); join them into one part, like a non-streamed response.\n        for (const candidate of candidateData) {\n          candidate.message.content = mergeStreamedAudio(\n            candidate.message.content\n          );\n        }\n      }\n\n      return {\n        candidates: candidateData,\n        custom: response,\n        usage: {\n          ...getBasicUsageStats(request.messages, candidateData),\n          inputTokens: response.usageMetadata?.promptTokenCount,\n          outputTokens: response.usageMetadata?.candidatesTokenCount,\n          thoughtsTokens: response.usageMetadata?.thoughtsTokenCount,\n          totalTokens: response.usageMetadata?.totalTokenCount,\n          cachedContentTokens: response.usageMetadata?.cachedContentTokenCount,\n        },\n      };\n    }\n  );\n}\n\nexport const TEST_ONLY = {\n  KNOWN_GEMINI_MODELS,\n  KNOWN_IMAGE_MODELS,\n  KNOWN_TTS_MODELS,\n  KNOWN_VIDEO_MODELS,\n  HIDDEN_MODELS,\n  ALL_MODELS,\n  KNOWN_MODELS,\n};\n"],"mappings":"AAgBA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB;AAAA,EAKE;AAAA,EACA;AAAA,EAMA;AAAA,EACA;AAAA,OACK;AACP,SAAS,4BAA4B;AACrC,SAAS,SAAS,mBAAmB;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB,8BAA8B;AAYvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,uBAAuB,EACjC,OAAO;AAAA,EACN,UAAU,EAAE,KAAK;AAAA;AAAA,IAEf;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF,CAAC;AAAA,EACD,WAAW,EAAE,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH,CAAC,EACA,YAAY;AAEf,MAAM,wBAAwB,EAC3B,OAAO;AAAA,EACN,WAAW,EACR,OAAO;AAAA,IACN,WAAW,EAAE,OAAO,EAAE,SAAS,0BAA0B,EAAE,SAAS;AAAA,IACpE,UAAU,EACP,OAAO,EACP,SAAS,uCAAuC,EAChD,SAAS;AAAA,IACZ,aAAa,EACV,OAAO,EACP;AAAA,MACC;AAAA,IAIF;AAAA,EACJ,CAAC,EACA,SAAS,qCAAqC,EAC9C,YAAY;AAAA,EACf,oBAAoB,EACjB,QAAQ,EACR;AAAA,IACC;AAAA,EAEF,EACC,SAAS;AACd,CAAC,EACA,YAAY;AAEf,MAAM,8BAA8B,EACjC,OAAO;AAAA,EACN,oBAAoB,EACjB,QAAQ,EACR;AAAA,IACC;AAAA,EAEF,EACC,SAAS;AACd,CAAC,EACA,YAAY;AAMR,MAAM,qBAAqB,6BAA6B,OAAO;AAAA,EACpE,QAAQ,EACL,OAAO,EACP,SAAS,wDAAwD,EACjE,SAAS;AAAA,EACZ,YAAY,EACT,KAAK,CAAC,MAAM,SAAS,CAAC,EACtB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,QAAQ,EACL,OAAO,EAAE,OAAO,CAAC,EACjB,SAAS,EACT,SAAS,8DAA8D;AAAA,EAC1E,aAAa,EACV,OAAO,EACP,IAAI,CAAG,EACP,IAAI,CAAG,EACP;AAAA,IACC,mCAAmC,cACjC;AAAA,EACJ,EACC,SAAS;AAAA,EACZ,MAAM,EACH,OAAO,EACP,IAAI,CAAC,EACL,IAAI,CAAG,EACP;AAAA,IACC,mCAAmC,OAAO;AAAA,EAC5C,EACC,SAAS;AAAA,EACZ,UAAU,EACP,OAAO,EACP,SAAS,uCAAuC,EAChD,SAAS;AAAA,EACZ,OAAO,EACJ,QAAQ,EACR;AAAA,IACC;AAAA,EAEF,EACC,SAAS;AAAA,EACZ,uBAAuB,EACpB,OAAO,EACP;AAAA,IACC;AAAA,EAEF,EACC,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BZ,gBAAgB;AAAA,IACd,EACG,MAAM,oBAAoB,EAC1B;AAAA,MACC;AAAA,IAEF,EACC,SAAS;AAAA,IACZ,EAAE,CAAC,mBAAmB,MAAM,GAAG,kBAAkB,gBAAgB;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,iBAAiB,sBAAsB;AAAA,IACrC;AAAA,EAEF,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaX,uBAAuB,4BAA4B;AAAA,IACjD;AAAA,EACF,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeX,uBAAuB,EACpB,OAAO;AAAA,IACN,MAAM,EAAE,KAAK,CAAC,oBAAoB,QAAQ,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,IACnE,sBAAsB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMnD,6BAA6B,EAAE,QAAQ,EAAE,SAAS;AAAA,EACpD,CAAC,EACA;AAAA,IACC;AAAA,EAMF,EACC,YAAY,EACZ,SAAS;AAAA;AAAA;AAAA;AAAA,EAIZ,iBAAiB,EACd,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,QAAQ,EACL,OAAO;AAAA,MACN,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,MAC9B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IACjC,CAAC,EACA,SAAS,2DAA2D,EACpE,SAAS;AAAA;AAAA;AAAA;AAAA,IAIZ,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,CAAC,EACA,YAAY,EACZ,SAAS;AAAA,EACZ,OAAO,EACJ,KAAK,CAAC,YAAY,iBAAiB,QAAQ,WAAW,CAAC,EACvD;AAAA,IACC;AAAA,EAGF,EACC,SAAS;AAAA,EACZ,gBAAgB,EACb,OAAO;AAAA,IACN,iBAAiB,EACd,QAAQ,EACR;AAAA,MACC;AAAA,IAGF,EACC,SAAS;AAAA,IACZ,gBAAgB,EACb,OAAO,EACP,IAAI,CAAC,EACL,IAAI,KAAK,EACT;AAAA,MACC;AAAA,IAOF,EACC,SAAS;AAAA,IACZ,eAAe,EACZ,KAAK,CAAC,WAAW,OAAO,UAAU,MAAM,CAAC,EACzC;AAAA,MACC;AAAA,IAGF,EACC,SAAS;AAAA,EACd,CAAC,EACA,YAAY,EACZ,SAAS;AACd,CAAC,EAAE,YAAY;AAoCR,MAAM,0BAA0B,mBAAmB,OAAO;AAAA,EAC/D,aAAa,EACV,OAAO;AAAA,IACN,aAAa,EACV,KAAK;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC,EACA,SAAS;AAAA,IACZ,WAAW,EAAE,KAAK,CAAC,OAAO,MAAM,MAAM,IAAI,CAAC,EAAE,SAAS;AAAA,EACxD,CAAC,EACA,YAAY,EACZ,SAAS;AACd,CAAC,EAAE,YAAY;AAIf,MAAM,oBAAoB,EACvB,OAAO;AAAA,EACN,OAAO,EACJ,MAAM;AAAA,IACL,EAAE,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA;AAAA,IAGD,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,EACxD,CAAC,EACA;AAAA,IACC;AAAA,EAEF,EACC,SAAS;AAAA;AAAA;AAAA,EAGZ,qBAAqB,EAClB,OAAO;AAAA,IACN,WAAW,EAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,EAClE,CAAC,EACA,YAAY,EACZ,SAAS;AACd,CAAC,EACA;AAAA,EACC;AAEF,EACC,YAAY;AAER,MAAM,wBAAwB,mBAAmB,OAAO;AAAA,EAC7D,cAAc,EACX,OAAO;AAAA,IACN,aAAa,kBAAkB,SAAS;AAAA,IACxC,yBAAyB,EACtB,OAAO;AAAA,MACN,qBAAqB,EAClB;AAAA,QACC,EACG,OAAO;AAAA,UACN,SAAS,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,UACzD,aAAa;AAAA,QACf,CAAC,EACA;AAAA,UACC;AAAA,QACF,EACC,YAAY;AAAA,MACjB,EACC;AAAA,QACC;AAAA,MAEF;AAAA,IACJ,CAAC,EACA,SAAS,uCAAuC,EAChD,YAAY,EACZ,SAAS;AAAA,EACd,CAAC,EACA,SAAS,0BAA0B,EACnC,YAAY,EACZ,SAAS;AAAA,EACZ,aAAa,EACV,OAAO;AAAA,IACN,UAAU,EACP,MAAM;AAAA,MACL,EAAE,KAAK,CAAC,aAAa,aAAa,eAAe,YAAY,CAAC;AAAA,MAC9D,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,IACxD,CAAC,EACA;AAAA,MACC;AAAA,IAGF,EACC,SAAS;AAAA,EACd,CAAC,EACA,SAAS,gCAAgC,EACzC,YAAY,EACZ,SAAS;AACd,CAAC,EAAE,YAAY;AAMR,MAAM,0BAA0B,mBAAmB,OAAO;AAAA,EAC/D,aAAa,EACV,OAAO;AAAA,IACN,aAAa,EACV,MAAM;AAAA,MACL,EAAE,KAAK,CAAC,QAAQ,MAAM,CAAC;AAAA;AAAA;AAAA,MAGvB,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,IACxD,CAAC,EACA;AAAA,MACC;AAAA,IACF,EACC,SAAS;AAAA,IACZ,YAAY,EACT,MAAM;AAAA,MACL,EAAE,KAAK,CAAC,QAAQ,QAAQ,SAAS,IAAI,CAAC;AAAA,MACtC,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,IACxD,CAAC,EACA,SAAS,sDAAsD,EAC/D,SAAS;AAAA,IACZ,UAAU,EACP,MAAM;AAAA,MACL,EAAE,KAAK,CAAC,UAAU,KAAK,CAAC;AAAA,MACxB,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,IACxD,CAAC,EACA;AAAA,MACC;AAAA,IAEF,EACC,SAAS;AAAA,IACZ,QAAQ,EACL,OAAO,EACP;AAAA,MACC;AAAA,IAEF,EACC,SAAS;AAAA,EACd,CAAC,EACA,SAAS,gCAAgC,EACzC,YAAY,EACZ,SAAS;AAAA,EACZ,aAAa,EACV,OAAO;AAAA,IACN,MAAM,EACH,MAAM;AAAA,MACL,EAAE,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,EAAE,OAAoB,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,IACxD,CAAC,EACA;AAAA,MACC;AAAA,IAEF,EACC,SAAS;AAAA,EACd,CAAC,EACA,SAAS,4BAA4B,EACrC,YAAY,EACZ,SAAS;AACd,CAAC,EAAE,YAAY;AAaf,MAAM,uBAAuB,oBAAI,IAAqB;AAEtD,SAAS,UACP,MACA,MACA,eAAiC,oBACjC,kBAA2B,MACO;AAClC,uBAAqB,IAAI,MAAM,eAAe;AAE9C,SAAO,SAAS;AAAA,IACd,MAAM,YAAY,IAAI;AAAA,IACtB;AAAA,IACA,MAAM,QAAQ;AAAA,MACZ,UAAU;AAAA,QACR,WAAW;AAAA,QACX,OAAO;AAAA,QACP,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,MAAM,gBAAgB,UAAU,QAAQ;AACxC,MAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ,CAAC,OAAO;AAAA,IAClB;AAAA,EACF;AAAA,EACA;AAAA,EACA;AACF;AAIA,MAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ,CAAC,OAAO;AAAA,IAClB;AAAA,EACF;AAAA,EACA;AACF;AAKO,MAAM,sBAAsB;AAAA,EACjC,kBAAkB,UAAU,gBAAgB;AAAA;AAAA,EAE5C,mCAAmC;AAAA,IACjC;AAAA,EACF;AAAA,EACA,oBAAoB,UAAU,kBAAkB;AAAA;AAAA,EAEhD,0BAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,oBAAoB,UAAU,kBAAkB;AAAA,EAChD,yBAAyB,UAAU,uBAAuB;AAAA,EAC1D,oBAAoB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,yBAAyB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,0BAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA,sCAAsC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,0BAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,kBAAkB,OAA0C;AAC1E,SAAO,CAAC,EACN,OAAO,WAAW,SAAS,KAC3B,CAAC,MAAM,SAAS,WAAW,KAC3B,CAAC,iBAAiB,KAAK,KACvB,CAAC,eAAe,KAAK,KACrB,CAAC,iBAAiB,KAAK;AAE3B;AAEO,MAAM,qBAAqB;AAAA;AAAA;AAAA,EAGhC,0BAA0B;AAAA,IACxB;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAAA,EACA,+BAA+B;AAAA,IAC7B;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAAA,EACA,0BAA0B;AAAA,IACxB;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAAA,EACA,sBAAsB;AAAA,IACpB;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAAA,EACA,0BAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,iBAAiB,OAAyC;AACxE,SAAO,CAAC,EACN,OAAO,WAAW,SAAS,MAC1B,MAAM,SAAS,QAAQ,KAAK,MAAM,WAAW,qBAAqB;AAEvE;AAIO,MAAM,mBAAmB;AAAA,EAC9B,wBAAwB;AAAA,IACtB;AAAA,IACA,EAAE,GAAG,kBAAkB,KAAK;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AAAA,EACA,6BAA6B;AAAA,IAC3B;AAAA,IACA,EAAE,GAAG,kBAAkB,KAAK;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,eAAe,OAAuC;AACpE,SAAO,CAAC,EAAE,OAAO,WAAW,SAAS,KAAK,MAAM,SAAS,MAAM;AACjE;AAGO,MAAM,qBAAqB;AAAA,EAChC,iCAAiC;AAAA,IAC/B;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,6BAA6B;AAAA,IAC3B;AAAA,IACA,EAAE,GAAG,oBAAoB,KAAK;AAAA,IAC9B;AAAA,EACF;AACF;AAGO,SAAS,iBAAiB,OAAyC;AACxE,SAAO,CAAC,CAAC,OAAO,WAAW,cAAc;AAC3C;AAEA,MAAM,eAAe;AAAA,EACnB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAUA,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIpB,kBAAkB;AAAA,IAChB;AAAA,IACA,EAAE,GAAG,cAAc,MAAM,OAAO,aAAa;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AAAA,EACA,oBAAoB;AAAA,IAClB;AAAA,IACA,EAAE,GAAG,cAAc,MAAM,OAAO,aAAa;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AAAA,EACA,yBAAyB;AAAA,IACvB;AAAA,IACA,EAAE,GAAG,cAAc,MAAM,OAAO,aAAa;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AACF;AAEA,MAAM,aAAa;AAAA,EACjB,GAAG;AAAA,EACH,GAAG;AACL;AAQA,SAAS,iBAAiB,cAA+B;AACvD,MAAI,aAAa,SAAS,YAAY,GAAG;AACvC,WAAO;AAAA,EACT;AAKA,SACE,qBAAqB,IAAI,YAAY,KACrC,EAAE,iBAAiB,YAAY,KAAK,eAAe,YAAY;AAEnE;AAEO,SAAS,MACd,SACA,SAAuB,CAAC,GACU;AAClC,QAAM,OAAO,eAAe,OAAO;AAEnC,MAAI,WAAW,MAAM,UAAU,GAAG;AAChC,WAAO,WAAW,IAAI,EAAE,WAAW,MAAM;AAAA,EAC3C;AAEA,MAAI,iBAAiB,IAAI,GAAG;AAC1B,WAAO,SAAS;AAAA,MACd,MAAM,YAAY,IAAI;AAAA,MACtB;AAAA,MACA,cAAc;AAAA,MACd,MAAM,EAAE,GAAG,oBAAoB,KAAK;AAAA,IACtC,CAAC;AAAA,EACH;AAEA,MAAI,iBAAiB,IAAI,GAAG;AAC1B,WAAO,SAAS;AAAA,MACd,MAAM,YAAY,IAAI;AAAA,MACtB;AAAA,MACA,cAAc;AAAA,MACd,MAAM,EAAE,GAAG,oBAAoB,KAAK;AAAA,IACtC,CAAC;AAAA,EACH;AAEA,MAAI,eAAe,IAAI,GAAG;AACxB,WAAO,SAAS;AAAA,MACd,MAAM,YAAY,IAAI;AAAA,MACtB;AAAA,MACA,cAAc;AAAA,MACd,MAAM,EAAE,GAAG,kBAAkB,KAAK;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,SAAO,SAAS;AAAA,IACd,MAAM,YAAY,IAAI;AAAA,IACtB;AAAA,IACA,cAAc;AAAA,IACd,MAAM;AAAA,MACJ,GAAG,cAAc;AAAA,IACnB;AAAA,EACF,CAAC;AACH;AAEO,SAAS,YAAY,QAAmC;AAC7D,QAAM,6BAA6B;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,OACJ;AAAA,IACC,CAAC,OACE,kBAAkB,UAAU,EAAE,IAAI,CAAC,KAClC,iBAAiB,UAAU,EAAE,IAAI,CAAC,KAClC,eAAe,UAAU,EAAE,IAAI,CAAC,KAChC,iBAAiB,UAAU,EAAE,IAAI,CAAC,MACpC,CAAC,2BAA2B,SAAS,UAAU,EAAE,IAAI,KAAK,EAAE;AAAA,EAChE,EACC,IAAI,CAAC,MAAM;AACV,UAAM,MAAM,MAAM,EAAE,IAAI;AACxB,WAAO,oBAAoB;AAAA,MACzB,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,cAAc,IAAI;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACL;AAEO,SAAS,gBACd,eACA,eACA;AACA,SAAO,OAAO,KAAK,UAAU,EAAE;AAAA,IAAI,CAAC,SAClC,YAAY,MAAM,eAAe,aAAa;AAAA,EAChD;AACF;AAQA,SAAS,4BACP,aACuC;AACvC,MAAI,CAAC,SAAS,WAAW,KAAK,OAAO,YAAY,aAAa,UAAU;AACtE,WAAO;AAAA,EACT;AACA,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,SAAO;AAAA,IACL;AAAA,MACE,OAAO;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,UAAU,SAAS,YAAY,EAAE,QAAQ,KAAK,GAAG;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,0BACP,iBACA,eACQ;AACR,QAAM,YACJ,gBAAgB,UAAU,cACzB,cAAc,QAAQ,YAAY,cAAc,YAAY;AAM/D,QAAM,WACJ,gBAAgB,UAAU,aACzB,cAAc,QAAQ,YAAY,cAAc,WAAW;AAC9D,QAAM,cAAc,gBAAgB,UAAU;AAC9C,MAAI,CAAC,aAAa,CAAC,YAAY,CAAC,aAAa;AAC3C,UAAM,IAAI,YAAY;AAAA,MACpB,QAAQ;AAAA,MACR,SACE;AAAA,IACJ,CAAC;AAAA,EACH;AACA,SAAO,YAAY,SAAS,cAAc,QAAQ,8CAA8C,WAAW;AAC7G;AAKA,SAAS,yBACP,SACA,QACA,eACA,aACmB;AACnB,QAAM,QAA2B,CAAC;AAClC,MAAI,QAAQ,OAAO,QAAQ;AACzB,UAAM,KAAK,GAAG,QAAQ,MAAM,IAAI,iBAAiB,CAAC;AAAA,EACpD;AACA,MAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/B,UAAM,KAAK,GAAG,OAAO,MAAM,IAAI,uBAAuB,CAAC;AAAA,EACzD;AACA,MAAI,OAAO,uBAAuB;AAChC,UAAM,EAAE,oBAAoB,GAAG,aAAa,IAC1C,OAAO;AACT,QAAI,uBAAuB,QAAW;AACpC,kBAAY,0CAA0C;AAAA,IACxD;AACA,UAAM,KAAK,0BAA0B,YAAY,CAAC;AAAA,EACpD;AACA,QAAM,kBAAkB,OAAO;AAC/B,MAAI,iBAAiB;AACnB,QAAI,gBAAgB,uBAAuB,QAAW;AACpD,kBAAY,oCAAoC;AAAA,IAClD;AACA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,iBAAiB,CAAC,kBAAkB;AAAA,MACpC,yBAAyB;AAAA,QACvB,YAAY,CAAC,0BAA0B,iBAAiB,aAAa,CAAC;AAAA,MACxE;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,OAAO,iBAAiB;AAG1B,UAAM,EAAE,QAAQ,GAAG,2BAA2B,IAAI,OAAO;AACzD,QAAI,UAAU,CAAC,6BAA6B,OAAO,MAAM,GAAG;AAC1D,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AACA,eAAW,OAAO,OAAO,KAAK,0BAA0B,GAAG;AACzD,kBAAY,mBAAmB,GAAG,EAAE;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAKA,eAAe,yBAAyB,QAcN;AAChC,QAAM,EAAE,SAAS,cAAc,eAAe,OAAO,IAAI;AACzD,QAAM;AAAA;AAAA,IAEJ,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA;AAAA,IAET,OAAO;AAAA,IACP,uBAAuB;AAAA,IACvB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,uBAAuB;AAAA,IACvB;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,cAAc,CAAC,UACnB,uBAAuB,cAAc,KAAK;AAC5C,MAAI,gBAAgB,QAAW;AAC7B,gBAAY,aAAa;AAAA,EAC3B;AAEA,QAAM,gBAAgB,OAAO;AAC7B,MAAI,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAS,GAAG;AAC5D,UAAM,IAAI,YAAY;AAAA,MACpB,QAAQ;AAAA,MACR,SACE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,cAAc,QAAQ,aAAa,GAAG;AAChD,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAIA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,EACF;AAEA,MAAI,uBAAuB,gCAAgC,QAAW;AACpE,gBAAY,mDAAmD;AAAA,EACjE;AACA,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,EACV;AACA,MAAI,YAAY;AACd,qBAAiB,cAAc;AAAA,EACjC;AAEA,QAAM,QAAQ,oBAAoB,QAAQ,eAAe,UAAU;AACnE,QAAM,EAAE,UAAU,sBAAsB,IAAI;AAAA,IAC1C,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAgC;AAAA,IACpC,oBAAoB,eAAe,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI;AAAA,IACvE,OAAO;AAAA,IACP,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9B,mBAAmB;AAAA,IACnB,QAAQ,OAAO;AAAA,IACf,OAAO,mBAAmB,QAAQ;AAAA,IAClC;AAAA,IACA,iBAAiB,4BAA4B,cAAc;AAAA,IAC3D,QAAQ,eAAe,MAAM;AAAA,EAC/B;AACA,MAAI,uBAAuB;AACzB,QAAI,0BAA0B;AAAA,EAChC;AAEA,QAAM,WACJ,QAAQ,QAAQ,WAAW,UAAU,CAAC,CAAC,QAAQ,QAAQ;AACzD,MAAI,UAAU;AACZ,QAAI,kBAAkB,EAAE,MAAM,QAAQ,WAAW,mBAAmB;AACpE,QAAI,QAAQ,QAAQ,aAAa;AAC/B,UAAI,gBAAgB,SAAS,eAAe,uBACxC,YAAY,QAAQ,OAAO,MAAM,IACjC,QAAQ,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,sBAAsB,iCAAiC,WAAW;AACxE,MAAI,qBAAqB;AACvB,QAAI,kBAAkB;AAAA,EACxB;AAEA,MAAI,MAAM,QAAQ,kBAAkB,KAAK,cAAc,kBAAkB,GAAG;AAC1E,QAAI,sBACF,gCAAgC,kBAAkB;AAAA,EACtD,WAAW,iBAAiB,YAAY,GAAG;AACzC,QAAI,sBAAsB,CAAC,QAAQ,OAAO;AAAA,EAC5C;AAEA,MAAI,CAAC,OAAO,oBAAoB;AAC9B,WAAO;AAAA,MACL,MAAM,kBAAkB,KAAK,OAAO,oBAAoB;AAAA,IAC1D;AAAA,EACF;AACA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,OAAO;AAAA,EACT;AACA,mBAAiB,SAAS,OAAO,QAAQ;AACvC,QAAI,MAAM,eAAe,cAAc;AACrC,YAAM,UAAU,qBAAqB,MAAM,KAAK;AAChD,UAAI,QAAQ,SAAS,GAAG;AACtB,eAAO,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACA,SAAO,oBAAoB,MAAM,OAAO,QAAQ;AAClD;AAKO,SAAS,YACd,MACA,eACA,eACa;AACb,QAAM,MAAM,MAAM,IAAI;AACtB,QAAM,cAAiC,CAAC;AACxC,MAAI,IAAI,MAAM,UAAU,OAAO;AAE7B,gBAAY;AAAA,MACV,qBAAqB;AAAA,QACnB,UAAU,OAAO,OAAO;AAAA,QACxB,QAAQ,CAAC,SAAS;AAChB,cAAI;AACF,kBAAM,MAAM,IAAI,IAAI,KAAK,MAAM,GAAG;AAClC;AAAA;AAAA,cAEE,CAAC,mBAAmB,eAAe,UAAU,EAAE;AAAA,gBAC7C,IAAI;AAAA,cACN;AAAA;AAEA,qBAAO;AAAA,UACX,QAAQ;AAAA,UAAC;AACT,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,MACE,MAAM,IAAI;AAAA,MACV,GAAG,IAAI;AAAA,MACP,cAAc,IAAI;AAAA,MAClB,KAAK;AAAA,IACP;AAAA,IACA,OAAO,SAAS,EAAE,oBAAoB,WAAW,YAAY,MAAM;AACjE,UAAI,YAAY,EAAE,GAAG,eAAe,QAAQ,YAAY;AAGxD,YAAM,WAAW,gBAAgB,QAAQ,QAAQ;AACjD,UAAI,SAAS,WAAW,EAAG,OAAM,IAAI,MAAM,uBAAuB;AAGlE,UAAI,oBAAyC;AAC7C,YAAM,gBAAgB,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC9D,UAAI,eAAe;AACjB,iBAAS,OAAO,SAAS,QAAQ,aAAa,GAAG,CAAC;AAClD,4BAAoB,0BAA0B,aAAa;AAAA,MAC7D;AAEA,YAAM,gBAA8B,EAAE,GAAG,QAAQ,OAAO;AAExD,YAAM;AAAA,QACJ,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,QACP,uBAAuB;AAAA;AAAA,QAEvB,aAAa;AAAA;AAAA,QAEb,aAAa;AAAA,QACb,GAAG;AAAA,MACL,IAAI;AAEJ,kBAAY,wBAAwB,WAAW;AAAA,QAC7C;AAAA,QACA,QAAQ;AAAA,QACR,YAAY;AAAA,MACd,CAAC;AAED,UAAI,OAAO;AACT,cAAM,eAAuC,CAAC;AAC9C,YAAI,UAAU,YAAY;AACxB,uBAAa,qCAAqC,IAAI;AAAA,QACxD,WAAW,UAAU,iBAAiB;AACpC,uBAAa,8BAA8B,IAAI;AAC/C,uBAAa,qCAAqC,IAAI;AAAA,QACxD,WAAW,UAAU,QAAQ;AAC3B,uBAAa,qCAAqC,IAAI;AAAA,QACxD,WAAW,UAAU,aAAa;AAChC,uBAAa,8BAA8B,IAAI;AAC/C,uBAAa,qCAAqC,IAAI;AAAA,QACxD;AACA,kBAAU,gBAAgB;AAAA,UACxB,GAAG,UAAU;AAAA,UACb,GAAG;AAAA,QACL;AAAA,MACF;AAEA,YAAM,eAAe,qBAAqB,eAAe,GAAG;AAC5D,UAAI,iBAAiB,YAAY,GAAG;AAClC,eAAO,yBAAyB;AAAA,UAC9B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,qBAAqB;AAAA;AAAA,UAErB,sBAAsB,4BAA4B,SAAS;AAAA,UAC3D;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAIA,UAAI,oBAAoB,QAAQ,iCAAiC;AAC/D,eAAO;AAAA,UACL;AAAA,QACF;AAAA,MACF;AACA,UAAI,0BAA0B,QAAW;AACvC,+BAAuB,cAAc,aAAa;AAAA,MACpD;AAEA,YAAM,SAAS,eAAe,gBAAgB;AAE9C,YAAM,QAAgB,CAAC;AACvB,UAAI,QAAQ,OAAO,QAAQ;AACzB,cAAM,KAAK;AAAA,UACT,sBAAsB,QAAQ,MAAM,IAAI,YAAY;AAAA,QACtD,CAAC;AAAA,MACH;AAEA,UAAI;AACJ,UAAI,uBAAuB;AACzB,qBAAa;AAAA,UACX,uBAAuB;AAAA,YACrB,GAAG;AAAA,YACH,sBAAsB,sBAAsB;AAAA,YAC5C,MAAM,yBAAyB,sBAAsB,IAAI;AAAA,UAC3D;AAAA,QACF;AAAA,MACF,WAAW,QAAQ,YAAY;AAC7B,qBAAa;AAAA,UACX,uBAAuB;AAAA,YACrB,MAAM,yBAAyB,QAAQ,UAAU;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,iBAAiB;AACnB,YAAI,CAAC,YAAY;AACf,uBAAa,CAAC;AAAA,QAChB;AACA,mBAAW,kBAAkB,gBAAgB,eAAe;AAAA,MAC9D;AAEA,YAAM,WACJ,QAAQ,QAAQ,WAAW,UAAU,CAAC,CAAC,QAAQ,QAAQ;AAEzD,UAAI,iBAAiB;AACnB,cAAM,KAAK,GAAI,eAAyB;AAAA,MAC1C;AAEA,UAAI,uBAAuB;AACzB,cAAM,KAAK;AAAA,UACT,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAEA,UAAI,iBAAiB;AACnB,cAAM,KAAK;AAAA,UACT,WAAW;AAAA,YACT,gBAAgB;AAAA,cACd,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,YACA,oBAAoB,gBAAgB;AAAA,UACtC;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,yBAAiD;AAAA,QACrD;AAAA,QACA,kBAAkB;AAAA,UAChB,GAAG;AAAA,UACH,gBAAgB,QAAQ,cAAc;AAAA,UACtC,kBAAkB,WAAW,qBAAqB;AAAA,QACpD;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,uBAAuB,cAAc;AAAA,QACrD,UAAU,SAAS,IAAI,CAAC,YAAY,gBAAgB,SAAS,GAAG,CAAC;AAAA,QACjE;AAAA,MACF;AAEA,UAAI,iBAAiB,YAAY,GAAG;AAClC,YAAI,CAAC,uBAAuB,iBAAkB,oBAAoB;AAChE,iCAAuB,iBAAkB,qBAAqB;AAAA,YAC5D;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAW,eAAe,YAAY,GAAG;AACvC,YAAI,CAAC,uBAAuB,iBAAkB,oBAAoB;AAChE,iCAAuB,iBAAkB,qBAAqB;AAAA,YAC5D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,iBAAiB,4BAA4B,qBAAqB;AACxE,UAAI,gBAAgB;AAClB,+BAAuB,iBAAkB,iBACvC;AAAA,MACJ;AAEA,UAAI,YAAY,QAAQ,QAAQ,aAAa;AAC3C,YAAI,eAAe,sBAAsB;AACvC,iCAAuB,iBAAkB,iBAAiB;AAAA,YACxD,QAAQ,OAAO;AAAA,UACjB;AAAA,QACF,OAAO;AACL,iCAAuB,iBAAkB,qBACvC,QAAQ,OAAO;AAAA,QACnB;AAAA,MACF;AAEA,UAAI;AAGJ,UAAI,oBAAoB;AACtB,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,cAAM,SAA0B,CAAC;AACjC,yBAAiB,QAAQ,OAAO,QAAQ;AACtC,UAAC,KAAiC,YAAY,QAAQ,CAAC,cAAc;AACnE,kBAAM,IAAI,oBAAoB,WAAW,MAAM;AAC/C,mBAAO,KAAK,CAAC;AACb,sBAAU;AAAA,cACR,OAAO,EAAE;AAAA,cACT,SAAS,EAAE,QAAQ;AAAA,YACrB,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,mBAAW,MAAM,OAAO;AAAA,MAC1B,OAAO;AACL,mBAAW,MAAM;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,YAAY,QAAQ;AAChC,cAAM,IAAI,YAAY;AAAA,UACpB,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAEA,YAAM,gBAAgB,SAAS,WAAW;AAAA,QAAI,CAAC,MAC7C,oBAAoB,CAAC;AAAA,MACvB;AACA,UAAI,sBAAsB,eAAe,YAAY,GAAG;AAGtD,mBAAW,aAAa,eAAe;AACrC,oBAAU,QAAQ,UAAU;AAAA,YAC1B,UAAU,QAAQ;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,GAAG,mBAAmB,QAAQ,UAAU,aAAa;AAAA,UACrD,aAAa,SAAS,eAAe;AAAA,UACrC,cAAc,SAAS,eAAe;AAAA,UACtC,gBAAgB,SAAS,eAAe;AAAA,UACxC,aAAa,SAAS,eAAe;AAAA,UACrC,qBAAqB,SAAS,eAAe;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}