Class: ActiveHarness::Providers::Audio::OpenAI

Inherits:
Base
  • Object
show all
Defined in:
lib/active_harness/providers/audio/openai.rb

Constant Summary collapse

ENDPOINT =
"https://api.openai.com/v1/audio/transcriptions"
CONTENT_TYPES =

OpenAI's transcription endpoint only accepts these formats — notably no flac/ogg/aac, unlike OpenRouter's version of this endpoint.

{
  "mp3"  => "audio/mpeg",
  "mp4"  => "audio/mp4",
  "mpeg" => "audio/mpeg",
  "mpga" => "audio/mpeg",
  "m4a"  => "audio/mp4",
  "wav"  => "audio/wav",
  "webm" => "audio/webm"
}.freeze

Constants inherited from Base

Base::HTTP, Base::STREAMING_HTTP

Instance Method Summary collapse

Instance Method Details

#call(model:, audio_data:, audio_format:, language: nil, **_) ⇒ Object

Synchronous — this endpoint has no job/polling API. Unlike OpenRouter's transcription endpoint, OpenAI's is multipart/form-data only (no base64/JSON request mode).

Parameters:

  • model (String)

    e.g. "whisper-1", "gpt-4o-transcribe", "gpt-4o-mini-transcribe"

  • audio_data (String)

    raw binary audio bytes

  • audio_format (String)

    one of CONTENT_TYPES.keys

  • language (String) (defaults to: nil)

    ISO-639-1 code, e.g. "en" (optional — auto-detected if omitted)

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/active_harness/providers/audio/openai.rb', line 30

def call(model:, audio_data:, audio_format:, language: nil, **_)
  content_type = CONTENT_TYPES[audio_format]
  unless content_type
    raise Errors::InvalidRequestError,
      "openai transcription does not support .#{audio_format} — use one of: #{CONTENT_TYPES.keys.join(', ')}"
  end

  boundary = SecureRandom.hex(16)
  fields   = { "model" => model }
  fields["language"] = language if language

  body = build_multipart_body(boundary, fields, audio_data, "audio.#{audio_format}", content_type)
  headers = {
    "Content-Type"  => "multipart/form-data; boundary=#{boundary}",
    "Authorization" => "Bearer #{api_key}"
  }

  raw  = HTTP.post(URI(ENDPOINT), headers: headers, body: body, timeout: 90)
  data = parse!(raw)
  handle_error!(data)

  text = data["text"]
  raise Errors::ProviderError, "No transcription text in response: #{data.keys}" if text.nil?

  { content: text, provider: :openai, model: model, usage: extract_transcription_usage(data) }
end