{"version":3,"sources":["../../src/googleai/veo.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  GenerateResponseData,\n  Operation,\n  modelActionMetadata,\n  z,\n} from 'genkit';\nimport {\n  BackgroundModelAction,\n  modelRef,\n  type GenerateRequest,\n  type ModelInfo,\n  type ModelReference,\n} from 'genkit/model';\nimport { backgroundModel as pluginBackgroundModel } from 'genkit/plugin';\nimport { isKnownKey } from '../common/utils.mjs';\nimport { veoCheckOperation, veoPredict } from './client.mjs';\nimport {\n  ClientOptions,\n  GoogleAIPluginOptions,\n  Model,\n  VeoOperation,\n  VeoParameters,\n  VeoPredictRequest,\n} from './types.mjs';\nimport {\n  applyContextOverrides,\n  calculateApiKey,\n  checkModelName,\n  extractText,\n  extractVeoImage,\n  extractVeoVideo,\n  extractVersion,\n  modelName,\n} from './utils.mjs';\n\n/**\n * See https://ai.google.dev/gemini-api/docs/video\n */\nexport const VeoConfigSchema = z\n  .object({\n    negativePrompt: z.string().optional(),\n    aspectRatio: z\n      .enum(['9:16', '16:9'])\n      .describe('Desired aspect ratio of the output video.')\n      .optional(),\n    personGeneration: z\n      .enum(['dont_allow', 'allow_adult', 'allow_all'])\n      .describe(\n        'Control if/how images of people will be generated by the model.'\n      )\n      .optional(),\n    durationSeconds: z\n      .number()\n      .step(1)\n      .min(4) // Veo 3.1 supports 4s for some resolutions.\n      .max(8)\n      .describe('Length of each output video in seconds.')\n      .optional(),\n    resolution: z\n      .enum(['720p', '1080p', '4k'])\n      .describe('Resolution of the output video.')\n      .optional(),\n    seed: z\n      .number()\n      .int()\n      .describe('Random seed for the video generation.')\n      .optional(),\n    enhancePrompt: z\n      .boolean()\n      .describe('Enable or disable the prompt rewriter. Enabled by default.')\n      .optional(),\n  })\n  .passthrough();\nexport type VeoConfigSchemaType = typeof VeoConfigSchema;\nexport type VeoConfig = z.infer<VeoConfigSchemaType>;\n\n// This contains all the Veo config schema types\ntype ConfigSchemaType = VeoConfigSchemaType;\n\nfunction commonRef(\n  name: string,\n  info?: ModelInfo,\n  configSchema: ConfigSchemaType = VeoConfigSchema\n): ModelReference<ConfigSchemaType> {\n  return modelRef({\n    name: `googleai/${name}`,\n    configSchema,\n    info:\n      info ??\n      ({\n        supports: {\n          media: true,\n          multiturn: false,\n          tools: false,\n          systemRole: false,\n          output: ['media'],\n          longRunning: true,\n        },\n      } as ModelInfo), // TODO(ifielker): Remove this cast if we fix longRunning\n  });\n}\n\nconst GENERIC_MODEL = commonRef('veo');\n\nconst KNOWN_MODELS = {} as const;\nexport type KnownModels = keyof typeof KNOWN_MODELS; // For autocomplete\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 KnownModels type, so\n// they don't show up in autocomplete. Set `stage` on each one (keeping the\n// default `supports`): 'deprecated' for models that are deprecated or\n// < 1 month from shutdown.\nconst HIDDEN_MODELS = {\n  // Shut down on Oct 22 2026.\n  'veo-3.1-lite-generate-preview': commonRef('veo-3.1-lite-generate-preview', {\n    ...GENERIC_MODEL.info,\n    stage: 'deprecated',\n  }),\n  'veo-3.1-generate-preview': commonRef('veo-3.1-generate-preview', {\n    ...GENERIC_MODEL.info,\n    stage: 'deprecated',\n  }),\n  'veo-3.1-fast-generate-preview': commonRef('veo-3.1-fast-generate-preview', {\n    ...GENERIC_MODEL.info,\n    stage: 'deprecated',\n  }),\n} as const;\n\nconst ALL_MODELS = {\n  ...HIDDEN_MODELS,\n  ...KNOWN_MODELS,\n};\n\nexport type VeoModelName = `veo-${string}`;\nexport function isVeoModelName(value?: string): value is VeoModelName {\n  return !!value?.startsWith('veo-');\n}\n\nexport function model(\n  version: string,\n  config: VeoConfig = {}\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  return modelRef({\n    name: `googleai/${name}`,\n    config,\n    configSchema: VeoConfigSchema,\n    info: { ...GENERIC_MODEL.info },\n  });\n}\n\n// Takes a full list of models, filters for current Veo models only\n// and returns a modelActionMetadata for each.\nexport function listActions(models: Model[]): ActionMetadata[] {\n  return (\n    models\n      .filter(\n        (m) =>\n          m.supportedGenerationMethods.includes('predictLongRunning') &&\n          isVeoModelName(modelName(m.name))\n      )\n      // Filter out deprecated\n      .filter((m) => !m.description || !m.description.includes('deprecated'))\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}\n\nexport function listKnownModels(options?: GoogleAIPluginOptions) {\n  return Object.keys(ALL_MODELS).map((name: string) =>\n    defineModel(name, options)\n  );\n}\n\n/**\n * Defines a new GoogleAI Veo model.\n */\nexport function defineModel(\n  name: string,\n  pluginOptions?: GoogleAIPluginOptions\n): BackgroundModelAction<VeoConfigSchemaType> {\n  const ref = model(name);\n  const clientOptions: ClientOptions = {\n    apiVersion: pluginOptions?.apiVersion,\n    baseUrl: pluginOptions?.baseUrl,\n    customHeaders: pluginOptions?.customHeaders,\n    experimental_debugTraces: pluginOptions?.experimental_debugTraces,\n  };\n\n  return pluginBackgroundModel({\n    name: ref.name,\n    ...ref.info,\n    configSchema: ref.configSchema,\n    async start(request, options) {\n      // apiKey in config is deprecated in favor of options.context.secrets.apiKey\n      const newClientOptions = applyContextOverrides(\n        {\n          ...clientOptions,\n          apiKey: calculateApiKey(\n            pluginOptions?.apiKey,\n            request.config?.apiKey as string | undefined\n          ),\n        },\n        options?.context\n      );\n      const apiKey = newClientOptions.apiKey;\n\n      const veoPredictRequest: VeoPredictRequest = {\n        instances: [\n          {\n            prompt: extractText(request),\n            image: extractVeoImage(request),\n            video: extractVeoVideo(request),\n          },\n        ],\n        parameters: toVeoParameters(request),\n      };\n\n      const response = await veoPredict(\n        apiKey,\n        extractVersion(ref),\n        veoPredictRequest,\n        newClientOptions\n      );\n\n      return fromVeoOperation(response);\n    },\n    async check(operation, options) {\n      const checkOptions = applyContextOverrides(\n        {\n          ...clientOptions,\n          apiKey: calculateApiKey(pluginOptions?.apiKey, undefined),\n        },\n        options?.context\n      );\n\n      const response = await veoCheckOperation(\n        checkOptions.apiKey,\n        operation.id,\n        checkOptions\n      );\n      return fromVeoOperation(response);\n    },\n  });\n}\n\nfunction toVeoParameters(\n  request: GenerateRequest<VeoConfigSchemaType>\n): VeoParameters {\n  const out = {\n    ...request?.config,\n  };\n\n  for (const k in out) {\n    // undefined is handled by JSON.stringify\n    // false is needed so we can set enhancePrompt to false\n    if (out[k] === null) delete out[k];\n  }\n\n  // This is not part of the request parameters sent to the endpoint\n  // It's pulled out and used separately\n  delete out.apiKey;\n\n  // This was used to help us figure out which model. We no longer need\n  // it here.\n  delete out.version;\n\n  return out;\n}\n\nfunction fromVeoOperation(\n  apiOp: VeoOperation\n): Operation<GenerateResponseData> {\n  const res = { id: apiOp.name } as Operation<GenerateResponseData>;\n  if (apiOp.done !== undefined) {\n    res.done = apiOp.done;\n  }\n\n  if (apiOp.error) {\n    res.error = { message: apiOp.error.message };\n  }\n\n  if (\n    apiOp.response &&\n    apiOp.response.generateVideoResponse &&\n    apiOp.response.generateVideoResponse.generatedSamples\n  ) {\n    res.output = {\n      finishReason: 'stop',\n      raw: apiOp.response,\n      message: {\n        role: 'model',\n        content: apiOp.response.generateVideoResponse.generatedSamples.map(\n          (s) => {\n            return {\n              media: {\n                url: s.video.uri,\n              },\n            };\n          }\n        ),\n      },\n    };\n  }\n\n  return res;\n}\n\nexport const TEST_ONLY = {\n  toVeoParameters,\n  fromVeoOperation,\n  GENERIC_MODEL,\n  KNOWN_MODELS,\n  HIDDEN_MODELS,\n  ALL_MODELS,\n};\n"],"mappings":"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","names":[]}