Class: RubyLLM::Agents::SpeechResult

Inherits:
Object
  • Object
show all
Includes:
Trackable
Defined in:
lib/ruby_llm/agents/results/speech_result.rb

Overview

Result object for text-to-speech operations

Wraps audio output with metadata about the operation including duration, format, cost, and utility methods for saving audio.

Examples:

Basic usage

result = ArticleNarrator.call(text: "Hello world")
result.audio       # => Binary audio data
result.duration    # => 1.5 (seconds)
result.total_cost  # => 0.0003

Saving audio

result.save_to("/path/to/output.mp3")

Base64 encoding

result.to_base64   # => "//uQx..."

Audio Content collapse

Audio Metadata collapse

Input Metadata collapse

Voice Info collapse

Timing collapse

Cost & Usage collapse

Status collapse

Multi-tenancy collapse

Error collapse

Execution Record collapse

Instance Method Summary collapse

Methods included from Trackable

included

Constructor Details

#initialize(attributes = {}) ⇒ SpeechResult

Creates a new SpeechResult instance

Parameters:

  • attributes (Hash) (defaults to: {})

    Result attributes

Options Hash (attributes):

  • :audio (String)

    Binary audio data

  • :audio_url (String)

    URL if stored remotely

  • :audio_key (String)

    Storage key

  • :audio_path (String)

    Local file path

  • :duration (Float)

    Duration in seconds

  • :format (Symbol)

    Audio format

  • :sample_rate (Integer)

    Sample rate in Hz

  • :bitrate (Integer)

    Bitrate in kbps

  • :file_size (Integer)

    Size in bytes

  • :characters (Integer)

    Character count

  • :text_length (Integer)

    Original text length

  • :provider (Symbol)

    Provider name

  • :model_id (String)

    Model identifier

  • :voice_id (String)

    Voice identifier

  • :voice_name (String)

    Voice display name

  • :duration_ms (Integer)

    Execution duration

  • :started_at (Time)

    Start time

  • :completed_at (Time)

    Completion time

  • :total_cost (Float)

    Cost in USD

  • :status (Symbol)

    Status

  • :tenant_id (String)

    Tenant identifier

  • :error_class (String)

    Error class

  • :error_message (String)

    Error message



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 190

def initialize(attributes = {})
  # Audio content
  @audio = attributes[:audio]
  @audio_url = attributes[:audio_url]
  @audio_key = attributes[:audio_key]
  @audio_path = attributes[:audio_path]

  # Audio metadata
  @duration = attributes[:duration]
  @format = attributes[:format]
  @sample_rate = attributes[:sample_rate]
  @bitrate = attributes[:bitrate]
  @file_size = attributes[:file_size] || @audio&.bytesize

  # Input metadata
  @characters = attributes[:characters]
  @text_length = attributes[:text_length]

  # Voice info
  @provider = attributes[:provider]
  @model_id = attributes[:model_id]
  @voice_id = attributes[:voice_id]
  @voice_name = attributes[:voice_name]

  # Timing
  @duration_ms = attributes[:duration_ms]
  @started_at = attributes[:started_at]
  @completed_at = attributes[:completed_at]

  # Cost & usage
  @total_cost = attributes[:total_cost]

  # Status
  @status = attributes[:status] || :success

  # Multi-tenancy
  @tenant_id = attributes[:tenant_id]

  # Error
  @error_class = attributes[:error_class]
  @error_message = attributes[:error_message]

  # Execution record
  @execution_id = attributes[:execution_id]

  # Tracking
  @agent_class_name = attributes[:agent_class_name]
  register_with_tracker
end

Instance Attribute Details

#audioObject (readonly)



32
33
34
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 32

def audio
  @audio
end

#audio_keyString?

Returns Storage key if stored.

Returns:

  • (String, nil)

    Storage key if stored



40
41
42
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 40

def audio_key
  @audio_key
end

#audio_pathString?

Returns Local file path if saved.

Returns:

  • (String, nil)

    Local file path if saved



44
45
46
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 44

def audio_path
  @audio_path
end

#audio_urlString?

Returns URL if audio was stored remotely.

Returns:

  • (String, nil)

    URL if audio was stored remotely



36
37
38
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 36

def audio_url
  @audio_url
end

#bitrateObject (readonly)



64
65
66
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 64

def bitrate
  @bitrate
end

#charactersObject (readonly)



76
77
78
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 76

def characters
  @characters
end

#completed_atObject (readonly)



116
117
118
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 116

def completed_at
  @completed_at
end

#durationObject (readonly)



52
53
54
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 52

def duration
  @duration
end

#duration_msObject (readonly)



108
109
110
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 108

def duration_ms
  @duration_ms
end

#error_classObject (readonly)



148
149
150
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 148

def error_class
  @error_class
end

#error_messageObject (readonly)



152
153
154
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 152

def error_message
  @error_message
end

#execution_idObject (readonly)



160
161
162
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 160

def execution_id
  @execution_id
end

#file_sizeObject (readonly)



68
69
70
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 68

def file_size
  @file_size
end

#formatObject (readonly)



56
57
58
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 56

def format
  @format
end

#model_idObject (readonly)



92
93
94
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 92

def model_id
  @model_id
end

#providerObject (readonly)



88
89
90
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 88

def provider
  @provider
end

#sample_rateObject (readonly)



60
61
62
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 60

def sample_rate
  @sample_rate
end

#started_atObject (readonly)



112
113
114
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 112

def started_at
  @started_at
end

#statusObject (readonly)



132
133
134
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 132

def status
  @status
end

#tenant_idObject (readonly)



140
141
142
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 140

def tenant_id
  @tenant_id
end

#text_lengthObject (readonly)



80
81
82
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 80

def text_length
  @text_length
end

#total_costObject (readonly)



124
125
126
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 124

def total_cost
  @total_cost
end

#voice_idObject (readonly)



96
97
98
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 96

def voice_id
  @voice_id
end

#voice_nameObject (readonly)



100
101
102
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 100

def voice_name
  @voice_name
end

Instance Method Details

#content_typeString

Returns MIME type for the audio format

Returns:

  • (String)

    MIME type



339
340
341
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 339

def content_type
  mime_type_for_format
end

#error?Boolean

Returns whether the speech generation failed

Returns:

  • (Boolean)

    true if an error occurred



257
258
259
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 257

def error?
  !success?
end

#executionRubyLLM::Agents::Execution?

Loads the associated Execution record from the database

Returns:



243
244
245
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 243

def execution
  @execution ||= RubyLLM::Agents::Execution.find_by(id: execution_id) if execution_id
end

#mime_type_for_formatString

Returns MIME type for the audio format

Returns:

  • (String)

    MIME type



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 346

def mime_type_for_format
  fmt = format.to_s

  # Handle ElevenLabs native format strings (e.g., "mp3_44100_128")
  return "audio/mpeg" if fmt.start_with?("mp3")
  return "audio/wav" if fmt.start_with?("wav")
  return "audio/opus" if fmt.start_with?("opus")
  return "audio/pcm" if fmt.start_with?("pcm")
  return "audio/alaw" if fmt.start_with?("alaw")
  return "audio/basic" if fmt.start_with?("ulaw")

  # Handle simple symbols (backward compatible)
  case format
  when :mp3 then "audio/mpeg"
  when :wav then "audio/wav"
  when :ogg then "audio/ogg"
  when :flac then "audio/flac"
  when :aac then "audio/aac"
  when :opus then "audio/opus"
  when :pcm then "audio/pcm"
  else "audio/mpeg"
  end
end

#save_to(path) ⇒ String

Saves the audio to a file

Parameters:

  • path (String)

    File path to save to

Returns:

  • (String)

    The path where audio was saved

Raises:

  • (StandardError)

    If audio data is not available



266
267
268
269
270
271
272
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 266

def save_to(path)
  raise StandardError, "No audio data available" unless audio

  File.binwrite(path, audio)
  @audio_path = path
  path
end

#success?Boolean

Returns whether the speech generation succeeded

Returns:

  • (Boolean)

    true if no error occurred



250
251
252
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 250

def success?
  error_class.nil? && status == :success
end

#to_base64String?

Returns the audio as a Base64-encoded string

Returns:

  • (String, nil)

    Base64-encoded audio or nil if no audio



277
278
279
280
281
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 277

def to_base64
  return nil unless audio

  Base64.strict_encode64(audio)
end

#to_data_uriString?

Returns the audio as a data URI

Returns:

  • (String, nil)

    Data URI or nil if no audio



286
287
288
289
290
291
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 286

def to_data_uri
  return nil unless audio

  mime_type = mime_type_for_format
  "data:#{mime_type};base64,#{to_base64}"
end

#to_hHash

Converts the result to a hash

Returns:

  • (Hash)

    All result data as a hash



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 307

def to_h
  {
    audio_url: audio_url,
    audio_key: audio_key,
    audio_path: audio_path,
    duration: duration,
    format: format,
    sample_rate: sample_rate,
    bitrate: bitrate,
    file_size: file_size,
    characters: characters,
    text_length: text_length,
    provider: provider,
    model_id: model_id,
    voice_id: voice_id,
    voice_name: voice_name,
    duration_ms: duration_ms,
    started_at: started_at,
    completed_at: completed_at,
    total_cost: total_cost,
    status: status,
    tenant_id: tenant_id,
    error_class: error_class,
    error_message: error_message,
    execution_id: execution_id
    # Note: audio binary data excluded for serialization safety
  }
end

#words_per_secondFloat?

Returns words per second of generated audio

Returns:

  • (Float, nil)

    Words per second or nil if not calculable



296
297
298
299
300
301
302
# File 'lib/ruby_llm/agents/results/speech_result.rb', line 296

def words_per_second
  return nil unless text_length && duration && duration > 0

  # Rough estimate: average word length is 5 characters
  word_count = text_length / 5.0
  word_count / duration
end