Module: RubyLLM::Protocols::Deepgram::Transcription

Defined in:
lib/ruby_llm/protocols/deepgram/transcription.rb

Overview

Transcription dialect for the Deepgram speech-to-text API. Every option is a query parameter on v1/listen, and the body is either the audio bytes or a JSON pointer to a remote url. Giving speaker names turns on diarization, which labels each word and utterance with a numeric speaker index.

Constant Summary collapse

DEFAULT_PARAMS =

Turned on by default so the transcript reads like the transcripts every other provider returns. Smart formatting punctuates and formats numbers, dates, and currency; utterances split the transcript into timed segments.

{ smart_format: true, utterances: true }.freeze
DIARIZE_MODEL =

The batch diarizer to run. 'latest' tracks Deepgram's current generally available diarizer, which the boolean diarize parameter it deprecates does not.

'latest'

Instance Method Summary collapse

Instance Method Details

#parse_transcription_response(response, model:) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 71

def parse_transcription_response(response, model:)
  data = response.body || {}
  channel = data.dig('results', 'channels', 0) || {}
  alternative = channel.dig('alternatives', 0) || {}

  RubyLLM::Transcription.new(
    text: alternative['transcript'],
    model: model,
    language: channel['detected_language'],
    duration: data.dig('metadata', 'duration'),
    segments: data.dig('results', 'utterances'),
    words: alternative['words']
  )
end

#render_transcription_options(timestamps:) ⇒ Object

Raises:

  • (ArgumentError)


14
15
16
17
18
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 14

def render_transcription_options(timestamps:, **)
  return {} if timestamps.nil? || timestamps == :word

  raise ArgumentError, 'Deepgram transcription timestamps must be word'
end

#render_transcription_payload(attachment) ⇒ Object

Deepgram fetches remote audio itself, so a url attachment is sent as a JSON pointer and everything else is uploaded as raw bytes.



65
66
67
68
69
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 65

def render_transcription_payload(attachment)
  return { url: attachment.source.to_s } if attachment.url?

  attachment.content
end

#transcribe(audio_file, model:, language:, format: nil, speaker_names: nil, speaker_references: nil, provider_options: {}, prompt: nil, temperature: nil, &block) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 31

def transcribe(audio_file, model:, language:, format: nil, speaker_names: nil,
               speaker_references: nil, provider_options: {}, prompt: nil, temperature: nil, &block)
  if block
    if format || speaker_references || temperature
      raise ArgumentError,
            'Deepgram streaming transcription does not accept format, speaker_references or temperature'
    end

    return stream_live_transcription(audio_file, model:, language:, speaker_names:, provider_options:, prompt:,
                                     &block)
  end

  track_usage(:transcription) do
    attachment = Attachment.new(audio_file, config: @config)
    url = transcription_url(model:, language:, speaker_names:, provider_options:)
    payload = render_transcription_payload(attachment)
    response = post_transcription(url, payload, attachment)
    parse_transcription_response(response, model:)
  end
end

#transcription_params(model:, language: nil, speaker_names: nil, provider_options: {}) ⇒ Object



57
58
59
60
61
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 57

def transcription_params(model:, language: nil, speaker_names: nil, provider_options: {})
  params = { model: model, language: language }.merge(DEFAULT_PARAMS)
  params[:diarize_model] = DIARIZE_MODEL if speaker_names
  params.merge(provider_options).compact
end

#transcription_url(model:, language: nil, speaker_names: nil, provider_options: {}) ⇒ Object



52
53
54
55
# File 'lib/ruby_llm/protocols/deepgram/transcription.rb', line 52

def transcription_url(model:, language: nil, speaker_names: nil, provider_options: {})
  "v1/listen?#{URI.encode_www_form(transcription_params(model:, language:, speaker_names:,
                                                        provider_options:))}"
end