class Ollama::Handlers::Say

ollama.generate(model: ‘llama3.1’, prompt: ‘Hello World’, &Say.new(interactive: true))
@example Using the Say handler in interactive mode
ollama.generate(model: ‘llama3.1’, prompt: ‘Hello World’, &Say.new(voice: ‘Alex’))
@example Using the Say handler with a custom voice
is preferred over visual display.
interactive modes, making it suitable for applications where audio feedback
text-to-speech capabilities. It supports customization of voice and
commands into audible speech using the operating system’s native
The Say handler is designed to convert text responses from Ollama API
A handler that uses the system’s say command to speak response content.

def call(response)

Returns:
  • (self) - returns the handler instance itself after processing the response

Parameters:
  • response (Ollama::Response) -- the response object containing content to be printed
def call(response)
  if @output.closed?
    wait_output_pid
    @output     = open_output
    @output_pid = @output.pid
  end
  if content = response.response || response.message&.content
    @output.print content
  end
  response.done and @output.close
  self
end

def command(voice:, interactive:)

Returns:
  • (Array) - an array containing the command and its arguments

Parameters:
  • interactive (TrueClass, FalseClass, String, nil) -- the interactive
  • voice (String) -- the voice to be used for speech synthesis
def command(voice:, interactive:)
  command = [ 'say' ]
  voice and command.concat([ '-v', voice ])
  case interactive
  when true
    command << '-i'
  when String
    command << '--interactive=%s' % interactive
  end
  command
end

def initialize(output: nil, voice: 'Samantha', interactive: nil)

Parameters:
  • interactive (TrueClass, FalseClass, String, nil) -- the interactive
  • voice (String) -- the voice to be used for speech synthesis, defaults to 'Samantha'
  • output (IO, nil) -- the output stream to be used for handling responses, defaults to nil
def initialize(output: nil, voice: 'Samantha', interactive: nil)
  @voice       = voice
  @interactive = interactive
  super(output:)
  unless output
    @output = open_output
    @output_pid = @output.pid
  end
end

def open_output

Returns:
  • (IO) - an IO object connected to the say command for text-to-speech conversion
def open_output
  io = IO.popen(Shellwords.join(command(voice:, interactive:)), 'w')
  io.sync = true
  io
end

def wait_output_pid

exception gracefully without raising an error.
If the process has already terminated, it handles the Errno::ECHILD
thread.
to finish execution. It uses non-blocking wait to avoid hanging the main
This method checks if there is an active output process ID and waits for it

The wait_output_pid method waits for the output process to complete.
def wait_output_pid
  @output_pid or return
  Process.wait(@output_pid, Process::WNOHANG | Process::WUNTRACED)
rescue Errno::ECHILD
end