Module: RubyLLM::Protocols::Interactions::Transcription
- Includes:
- Gemini::FileTranscription
- Defined in:
- lib/ruby_llm/protocols/interactions/transcription.rb
Overview
:nodoc: all
Instance Method Summary collapse
- #parse_transcription_response(response, model:) ⇒ Object
- #parse_transcription_word(word) ⇒ Object
- #render_transcription_options(timestamps:) ⇒ Object
- #render_transcription_payload(attachment, model:, language:, speaker_names:, provider_options:, prompt:) ⇒ Object
- #transcription_url(_model) ⇒ Object
- #validate_transcription_config(config) ⇒ Object
Methods included from Gemini::FileTranscription
#transcribe, #validate_transcription_request
Instance Method Details
#parse_transcription_response(response, model:) ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 40 def parse_transcription_response(response, model:) data = response.body = parse_completion_body(data, raw: response) annotations = Array(data['steps']).flat_map { |step| Array(step['content']) } .flat_map { |part| Array(part['annotations']) } words = annotations.filter_map { |item| parse_transcription_word(item) if item['type'] == 'word_info' } RubyLLM::Transcription.new(text: .content, model:, words: words.empty? ? nil : words, **parse_interaction_usage(data['usage'] || {})) end |
#parse_transcription_word(word) ⇒ Object
50 51 52 53 54 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 50 def parse_transcription_word(word) { 'word' => word['text'], 'speaker' => word['speaker'], 'start' => word['start_offset'] && Float(word['start_offset'].delete_suffix('s')), 'end' => word['end_offset'] && Float(word['end_offset'].delete_suffix('s')) }.compact end |
#render_transcription_options(timestamps:) ⇒ Object
7 8 9 10 11 12 13 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 7 def (timestamps:, **) return {} if .nil? raise ArgumentError, 'Gemini transcription timestamps must be word' unless == :word { generation_config: { transcription_config: { mode: { type: 'verbatim', timestamp_granularities: ['word'] } } } } end |
#render_transcription_payload(attachment, model:, language:, speaker_names:, provider_options:, prompt:) ⇒ Object
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 21 def render_transcription_payload(, model:, language:, speaker_names:, provider_options:, prompt:) config = { language_codes: language && Array(language), custom_vocabulary: prompt && Array(prompt) }.compact config[:mode] = { type: 'verbatim', diarization_mode: 'speaker' } if speaker_names payload = { model:, store: false, input: [{ type: 'audio', mime_type: .mime_type, data: .encoded }], generation_config: { transcription_config: config } } payload = Support::Utils.deep_merge(payload, ) validate_transcription_config(payload.dig(:generation_config, :transcription_config)) payload end |
#transcription_url(_model) ⇒ Object
17 18 19 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 17 def transcription_url(_model) 'interactions' end |
#validate_transcription_config(config) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/ruby_llm/protocols/interactions/transcription.rb', line 32 def validate_transcription_config(config) mode = config[:mode] return unless config[:custom_vocabulary] && mode.is_a?(Hash) return unless mode[:diarization_mode] || mode[:timestamp_granularities] raise ArgumentError, 'Gemini custom vocabulary cannot be combined with diarization or word timestamps' end |