{"version":3,"file":"transcribe.mjs","names":[],"sources":["../../../../../../../ai/src/transcribe/transcribe.ts"],"sourcesContent":["import type { BaseReport } from \"../contracts/result/base-report.type\";\nimport { REPORT_SCHEMA_VERSION } from \"../contracts/result/base-report.type\";\nimport type { ExecuteResult } from \"../contracts/result/execute-result.type\";\nimport type { ModelPricing } from \"../contracts/result/model-pricing.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport type {\n  AudioInput,\n  TranscriptionModelContract,\n  TranscriptionModelPricing,\n  TranscriptionSegment,\n} from \"../contracts/transcription-model.contract\";\nimport { AIError } from \"../errors/ai-error\";\nimport { ProviderError } from \"../errors/provider-error\";\nimport type { FlowObserveOption } from \"../observe/resolve-observers\";\nimport { notifyObservers } from \"../observe/resolve-observers\";\nimport { computeCost } from \"../utils/compute-cost\";\nimport { generateRunId } from \"../utils/generate-run-id\";\nimport { stampReportLineage } from \"../utils/stamp-report-lineage\";\n\n/** Parameters for {@link transcribe}. `model` comes from `sdk.transcribe({ name })`. */\nexport type TranscribeParams = {\n  /** The STT model to transcribe with. */\n  model: TranscriptionModelContract;\n  /** The audio to transcribe (inlined base64 bytes + media type). */\n  audio: AudioInput;\n  /** BCP-47 language hint. */\n  language?: string;\n  /** Optional priming prompt (spelling/style hints). */\n  prompt?: string;\n  /** Provider response-format override (e.g. `\"verbose_json\"`). */\n  format?: string;\n  /** Cancellation handle. */\n  signal?: AbortSignal;\n  /** Observability routing — same `observe` seam as agents. */\n  observe?: FlowObserveOption;\n  /** Groups this call into a session for flat cost/trace queries. */\n  sessionId?: string;\n  /** Report node name (defaults to `\"transcription\"`). */\n  name?: string;\n  /** Provider-specific options forwarded verbatim to the adapter. */\n  options?: Record<string, unknown>;\n};\n\n/** Success payload of a {@link transcribe} run. */\nexport type TranscriptionData = {\n  /** The full transcript text. */\n  text: string;\n  /** Timestamped segments when the provider returned them. */\n  segments?: TranscriptionSegment[];\n};\n\n/** The report node a {@link transcribe} run produces (`type: \"transcription\"`). */\nexport type TranscriptionReport = BaseReport & {\n  type: \"transcription\";\n  /** Identity of the STT model this run used. */\n  model: { name: string; provider: string };\n  /** Input audio duration in seconds, when the provider reported it. */\n  durationSeconds?: number;\n};\n\n/** Result envelope of {@link transcribe} — the uniform `{ data, error, usage, report }`. */\nexport type TranscriptionResult = ExecuteResult<TranscriptionData> & {\n  type: \"transcription\";\n  report: TranscriptionReport;\n};\n\n/**\n * Transcribe audio to text — the speech-to-text verb of the\n * output-modality track (Theme I), inverse of `ai.speech()`. Wraps a\n * {@link TranscriptionModelContract} (from `openai.transcribe(...)`) in\n * the uniform result contract:\n *\n * - **Never throws.** Provider failures surface as a typed `AIError` on\n *   `result.error`.\n * - **Cost-truth.** `result.usage.cost` is filled per-minute\n *   (`whisper-1`) or per-token (`gpt-4o-transcribe`).\n * - **Observable.** The completed {@link TranscriptionReport} routes to\n *   any registered `Observer` via the `observe` seam.\n *\n * @example\n * const openai = new OpenAISDK({ apiKey });\n * const { data, error } = await ai.transcribe({\n *   model: openai.transcribe({ name: \"whisper-1\" }),\n *   audio: { base64, mediaType: \"audio/mpeg\", filename: \"voicemail.mp3\" },\n *   language: \"en\",\n * });\n * if (!error) console.log(data.text);\n */\nexport async function transcribe(params: TranscribeParams): Promise<TranscriptionResult> {\n  const { model, audio } = params;\n\n  const runId = generateRunId(\"transcription\");\n  const startedAt = new Date().toISOString();\n  const startPerf = performance.now();\n\n  const usage: Usage = { input: 0, output: 0, total: 0 };\n  let data: TranscriptionData | undefined;\n  let error: AIError | undefined;\n  let status: TranscriptionReport[\"status\"] = \"completed\";\n  let durationSeconds: number | undefined;\n\n  try {\n    const response = await model.transcribe(audio, {\n      language: params.language,\n      prompt: params.prompt,\n      format: params.format,\n      signal: params.signal,\n      ...params.options,\n    });\n\n    Object.assign(usage, response.usage);\n    durationSeconds = response.durationSeconds;\n\n    if (usage.cost === undefined) {\n      const cost = computeTranscriptionCost(usage, durationSeconds, model.pricing);\n      if (cost !== undefined) {\n        usage.cost = cost;\n      }\n    }\n\n    data = { text: response.text, ...(response.segments ? { segments: response.segments } : {}) };\n  } catch (thrown) {\n    error =\n      thrown instanceof AIError ? thrown : new ProviderError(toMessage(thrown), { cause: thrown });\n    status = params.signal?.aborted ? \"cancelled\" : \"failed\";\n  }\n\n  const report: TranscriptionReport = {\n    runId,\n    rootRunId: runId,\n    name: params.name ?? \"transcription\",\n    type: \"transcription\",\n    status,\n    error,\n    startedAt,\n    endedAt: new Date().toISOString(),\n    duration: performance.now() - startPerf,\n    usage,\n    children: [],\n    model: { name: model.name, provider: model.provider },\n    ...(durationSeconds !== undefined ? { durationSeconds } : {}),\n    reportSchemaVersion: REPORT_SCHEMA_VERSION,\n  };\n\n  stampReportLineage(report, { rootRunId: runId, sessionId: params.sessionId });\n\n  await notifyObservers(params.observe, report);\n\n  return { type: \"transcription\", data, error, usage, report };\n}\n\n/**\n * Price an STT run: `perMinute × (durationSeconds / 60)` (per-minute\n * metering, attributed to `cost.input`) wins when configured, otherwise\n * the standard token math. Returns `undefined` when no usable pricing\n * is present (e.g. per-minute pricing but the provider didn't report a\n * duration).\n */\nfunction computeTranscriptionCost(\n  usage: Usage,\n  durationSeconds: number | undefined,\n  pricing: TranscriptionModelPricing | undefined,\n): ModelPricing | undefined {\n  if (!pricing) {\n    return undefined;\n  }\n\n  if (pricing.perMinute !== undefined) {\n    if (durationSeconds === undefined) {\n      return undefined;\n    }\n    return { input: (durationSeconds / 60) * pricing.perMinute, output: 0 };\n  }\n\n  if (pricing.input !== undefined && pricing.output !== undefined) {\n    return computeCost(usage, { input: pricing.input, output: pricing.output });\n  }\n\n  return undefined;\n}\n\n/** Best-effort message for a non-`AIError` thrown value. */\nfunction toMessage(thrown: unknown): string {\n  return thrown instanceof Error ? thrown.message : String(thrown);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwFA,eAAsB,WAAW,QAAwD;CACvF,MAAM,EAAE,OAAO,UAAU;CAEzB,MAAM,QAAQ,cAAc,eAAe;CAC3C,MAAM,6BAAY,IAAI,KAAK,EAAC,CAAC,YAAY;CACzC,MAAM,YAAY,YAAY,IAAI;CAElC,MAAM,QAAe;EAAE,OAAO;EAAG,QAAQ;EAAG,OAAO;CAAE;CACrD,IAAI;CACJ,IAAI;CACJ,IAAI,SAAwC;CAC5C,IAAI;CAEJ,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,WAAW,OAAO;GAC7C,UAAU,OAAO;GACjB,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,GAAG,OAAO;EACZ,CAAC;EAED,OAAO,OAAO,OAAO,SAAS,KAAK;EACnC,kBAAkB,SAAS;EAE3B,IAAI,MAAM,SAAS,QAAW;GAC5B,MAAM,OAAO,yBAAyB,OAAO,iBAAiB,MAAM,OAAO;GAC3E,IAAI,SAAS,QACX,MAAM,OAAO;EAEjB;EAEA,OAAO;GAAE,MAAM,SAAS;GAAM,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;EAAG;CAC9F,SAAS,QAAQ;EACf,QACE,kBAAkB,UAAU,SAAS,IAAI,cAAc,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO,CAAC;EAC7F,SAAS,OAAO,QAAQ,UAAU,cAAc;CAClD;CAEA,MAAM,SAA8B;EAClC;EACA,WAAW;EACX,MAAM,OAAO,QAAQ;EACrB,MAAM;EACN;EACA;EACA;EACA,0BAAS,IAAI,KAAK,EAAC,CAAC,YAAY;EAChC,UAAU,YAAY,IAAI,IAAI;EAC9B;EACA,UAAU,CAAC;EACX,OAAO;GAAE,MAAM,MAAM;GAAM,UAAU,MAAM;EAAS;EACpD,GAAI,oBAAoB,SAAY,EAAE,gBAAgB,IAAI,CAAC;EAC3D;CACF;CAEA,mBAAmB,QAAQ;EAAE,WAAW;EAAO,WAAW,OAAO;CAAU,CAAC;CAE5E,MAAM,gBAAgB,OAAO,SAAS,MAAM;CAE5C,OAAO;EAAE,MAAM;EAAiB;EAAM;EAAO;EAAO;CAAO;AAC7D;;;;;;;;AASA,SAAS,yBACP,OACA,iBACA,SAC0B;CAC1B,IAAI,CAAC,SACH;CAGF,IAAI,QAAQ,cAAc,QAAW;EACnC,IAAI,oBAAoB,QACtB;EAEF,OAAO;GAAE,OAAQ,kBAAkB,KAAM,QAAQ;GAAW,QAAQ;EAAE;CACxE;CAEA,IAAI,QAAQ,UAAU,UAAa,QAAQ,WAAW,QACpD,OAAO,YAAY,OAAO;EAAE,OAAO,QAAQ;EAAO,QAAQ,QAAQ;CAAO,CAAC;AAI9E;;AAGA,SAAS,UAAU,QAAyB;CAC1C,OAAO,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACjE"}