{"version":3,"sources":["../src/whisper.ts"],"sourcesContent":["/**\n * Copyright 2026 Xavier Portilla Edo\n * Copyright 2026 Google LLC\n * Copyright 2026 Bloom Inc.\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 type { GenerateRequest, GenerateResponseData, Genkit } from \"genkit\";\nimport { GenerationCommonConfigSchema, Message, z } from \"genkit\";\nimport type { ModelAction } from \"genkit/model\";\nimport { modelRef } from \"genkit/model\";\nimport type AzureOpenAI from \"openai\";\nimport {\n  type Transcription,\n  type TranscriptionCreateParamsNonStreaming,\n} from \"openai/resources/audio/index\";\n\nexport const Whisper1ConfigSchema = GenerationCommonConfigSchema.extend({\n  language: z.string().optional(),\n  timestamp_granularities: z.array(z.enum([\"word\", \"segment\"])).optional(),\n  response_format: z\n    .enum([\"json\", \"text\", \"srt\", \"verbose_json\", \"vtt\"])\n    .optional(),\n});\n\nexport const whisper1 = modelRef({\n  name: \"azure-openai/whisper-1\",\n  info: {\n    label: \"OpenAI - Whisper\",\n    supports: {\n      media: true,\n      output: [\"text\", \"json\"],\n      multiturn: false,\n      systemRole: false,\n      tools: false,\n    },\n  },\n  configSchema: Whisper1ConfigSchema,\n});\n\nfunction toWhisper1Request(\n  request: GenerateRequest<typeof Whisper1ConfigSchema>,\n): TranscriptionCreateParamsNonStreaming {\n  const message = new Message(request.messages[0]);\n  const media = message.media;\n  if (!media?.url) {\n    throw new Error(\"No media found in the request\");\n  }\n  const mediaBuffer = Buffer.from(\n    media.url.slice(media.url.indexOf(\",\") + 1),\n    \"base64\",\n  );\n  const mediaFile = new File([mediaBuffer], \"input\", {\n    type:\n      media.contentType ??\n      media.url.slice(\"data:\".length, media.url.indexOf(\";\")),\n  });\n  const options: TranscriptionCreateParamsNonStreaming = {\n    model: \"whisper-1\",\n    file: mediaFile,\n    prompt: message.text,\n    temperature: request.config?.temperature,\n    language: request.config?.language,\n    timestamp_granularities: request.config?.timestamp_granularities,\n  };\n  const outputFormat = request.output?.format as \"json\" | \"text\" | \"media\";\n  const customFormat = request.config?.response_format;\n  if (outputFormat && customFormat) {\n    if (\n      outputFormat === \"json\" &&\n      customFormat !== \"json\" &&\n      customFormat !== \"verbose_json\"\n    ) {\n      throw new Error(\n        `Custom response format ${customFormat} is not compatible with output format ${outputFormat}`,\n      );\n    }\n  }\n  if (outputFormat === \"media\") {\n    throw new Error(`Output format ${outputFormat} is not supported.`);\n  }\n  options.response_format = customFormat || outputFormat || \"text\";\n  for (const k in options) {\n    if (options[k as keyof typeof options] === undefined) {\n      delete options[k as keyof typeof options];\n    }\n  }\n  return options;\n}\n\nfunction toGenerateResponse(\n  result: Transcription | string,\n): GenerateResponseData {\n  return {\n    candidates: [\n      {\n        index: 0,\n        finishReason: \"stop\",\n        message: {\n          role: \"model\",\n          content: [\n            {\n              text: typeof result === \"string\" ? result : result.text,\n            },\n          ],\n        },\n      },\n    ],\n  };\n}\n\nexport function whisper1Model(\n  ai: Genkit,\n  client: AzureOpenAI,\n): ModelAction<typeof Whisper1ConfigSchema> {\n  return ai.defineModel<typeof Whisper1ConfigSchema>(\n    {\n      name: whisper1.name,\n      ...whisper1.info,\n      configSchema: whisper1.configSchema,\n    },\n    async (request) => {\n      const result = await client.audio.transcriptions.create(\n        toWhisper1Request(request),\n      );\n      return toGenerateResponse(result);\n    },\n  );\n}\n"],"mappings":"AAmBA,SAAS,8BAA8B,SAAS,SAAS;AAEzD,SAAS,gBAAgB;AAOlB,MAAM,uBAAuB,6BAA6B,OAAO;AAAA,EACtE,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,yBAAyB,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,CAAC,CAAC,EAAE,SAAS;AAAA,EACvE,iBAAiB,EACd,KAAK,CAAC,QAAQ,QAAQ,OAAO,gBAAgB,KAAK,CAAC,EACnD,SAAS;AACd,CAAC;AAEM,MAAM,WAAW,SAAS;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,OAAO;AAAA,MACP,QAAQ,CAAC,QAAQ,MAAM;AAAA,MACvB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,cAAc;AAChB,CAAC;AAED,SAAS,kBACP,SACuC;AACvC,QAAM,UAAU,IAAI,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAC/C,QAAM,QAAQ,QAAQ;AACtB,MAAI,CAAC,OAAO,KAAK;AACf,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,QAAM,cAAc,OAAO;AAAA,IACzB,MAAM,IAAI,MAAM,MAAM,IAAI,QAAQ,GAAG,IAAI,CAAC;AAAA,IAC1C;AAAA,EACF;AACA,QAAM,YAAY,IAAI,KAAK,CAAC,WAAW,GAAG,SAAS;AAAA,IACjD,MACE,MAAM,eACN,MAAM,IAAI,MAAM,QAAQ,QAAQ,MAAM,IAAI,QAAQ,GAAG,CAAC;AAAA,EAC1D,CAAC;AACD,QAAM,UAAiD;AAAA,IACrD,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,QAAQ;AAAA,IAChB,aAAa,QAAQ,QAAQ;AAAA,IAC7B,UAAU,QAAQ,QAAQ;AAAA,IAC1B,yBAAyB,QAAQ,QAAQ;AAAA,EAC3C;AACA,QAAM,eAAe,QAAQ,QAAQ;AACrC,QAAM,eAAe,QAAQ,QAAQ;AACrC,MAAI,gBAAgB,cAAc;AAChC,QACE,iBAAiB,UACjB,iBAAiB,UACjB,iBAAiB,gBACjB;AACA,YAAM,IAAI;AAAA,QACR,0BAA0B,YAAY,yCAAyC,YAAY;AAAA,MAC7F;AAAA,IACF;AAAA,EACF;AACA,MAAI,iBAAiB,SAAS;AAC5B,UAAM,IAAI,MAAM,iBAAiB,YAAY,oBAAoB;AAAA,EACnE;AACA,UAAQ,kBAAkB,gBAAgB,gBAAgB;AAC1D,aAAW,KAAK,SAAS;AACvB,QAAI,QAAQ,CAAyB,MAAM,QAAW;AACpD,aAAO,QAAQ,CAAyB;AAAA,IAC1C;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBACP,QACsB;AACtB,SAAO;AAAA,IACL,YAAY;AAAA,MACV;AAAA,QACE,OAAO;AAAA,QACP,cAAc;AAAA,QACd,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,YACP;AAAA,cACE,MAAM,OAAO,WAAW,WAAW,SAAS,OAAO;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,cACd,IACA,QAC0C;AAC1C,SAAO,GAAG;AAAA,IACR;AAAA,MACE,MAAM,SAAS;AAAA,MACf,GAAG,SAAS;AAAA,MACZ,cAAc,SAAS;AAAA,IACzB;AAAA,IACA,OAAO,YAAY;AACjB,YAAM,SAAS,MAAM,OAAO,MAAM,eAAe;AAAA,QAC/C,kBAAkB,OAAO;AAAA,MAC3B;AACA,aAAO,mBAAmB,MAAM;AAAA,IAClC;AAAA,EACF;AACF;","names":[]}