0.01
The project is in a healthy, maintained state
An implementation of OmniAI for OpenAI
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

OmniAI::OpenAI

LICENSE RubyGems GitHub Yard CircleCI

An OpenAI implementation of the OmniAI interface supporting ChatGPT, Whisper, Text-to-Voice, Voice-to-Text, and more. This library is community maintained.

Installation

gem install omniai-openai

Usage

Client

A client is setup as follows if ENV['OPENAI_API_KEY'] exists:

client = OmniAI::OpenAI::Client.new

A client may also be passed the following options:

  • api_key (required - default is ENV['OPENAI_API_KEY'])
  • api_prefix (optional) - used with a host when necessary
  • organization (optional)
  • project (optional)
  • host (optional) useful for usage with Ollama, LocalAI or other OpenAI API compatible services

Configuration

Global configuration is supported for the following options:

OmniAI::OpenAI.configure do |config|
  config.api_key = 'sk-...' # default: ENV['OPENAI_API_KEY']
  config.organization = '...' # default: ENV['OPENAI_ORGANIZATION']
  config.project = '...' # default: ENV['OPENAI_PROJECT']
  config.host = '...' # default: 'https://api.openai.com' - override for usage with LocalAI / Ollama
end

Usage with LocalAI

LocalAI offers built in compatability with the OpenAI specification. To initialize a client that points to a Ollama change the host accordingly:

client = OmniAI::OpenAI::Client.new(host: 'http://localhost:8080', api_key: nil)

For details on installation or running LocalAI see the getting started tutorial.

Usage with Ollama

Ollama offers built in compatability with the OpenAI specification. To initialize a client that points to a Ollama change the host accordingly:

client = OmniAI::OpenAI::Client.new(host: 'http://localhost:11434', api_key: nil)

For details on installation or running Ollama checkout the project README.

Usage with OpenRouter

Other fee-based systems/services have adopted all or some of the OpenAI API. For example open_router.ai is a web-services that provides access to many models and providers using their own as well as an OpenAI API.

client  = OmniAI::OpenAI::Client.new(
            host:       'https://open_router.ai',
            api_key:    ENV['OPENROUTER_API_KEY'],
            api_prefix: '/api')

Chat

A chat completion is generated by passing in a simple text prompt:

completion = client.chat('Tell me a joke!')
completion.content # 'Why did the chicken cross the road? To get to the other side.'

A chat completion may also be generated by using a prompt builder:

completion = client.chat do |prompt|
  prompt.system('Your are an expert in geography.')
  prompt.user('What is the capital of Canada?')
end
completion.content # 'The capital of Canada is Ottawa.'

Model

model takes an optional string (default is gpt-4o):

completion = client.chat('How fast is a cheetah?', model: OmniAI::OpenAI::Chat::Model::GPT_3_5_TURBO)
completion.content # 'A cheetah can reach speeds over 100 km/h.'

OpenAI API Reference model

Temperature

temperature takes an optional float between 0.0 and 2.0 (defaults is 0.7):

completion = client.chat('Pick a number between 1 and 5', temperature: 2.0)
completion.content # '3'

OpenAI API Reference temperature

Stream

stream takes an optional a proc to stream responses in real-time chunks instead of waiting for a complete response:

stream = proc do |chunk|
  print(chunk.content) # 'Better', 'three', 'hours', ...
end
client.chat('Be poetic.', stream:)

OpenAI API Reference stream

Format

format takes an optional symbol (:json) and that setes the response_format to json_object:

completion = client.chat(format: :json) do |prompt|
  prompt.system(OmniAI::Chat::JSON_PROMPT)
  prompt.user('What is the name of the drummer for the Beatles?')
end
JSON.parse(completion.content) # { "name": "Ringo" }

OpenAI API Reference response_format

When using JSON mode, you must also instruct the model to produce JSON yourself via a system or user message.

Transcribe

A transcription is generated by passing in a path to a file:

transcription = client.transcribe(file.path)
transcription.text # '...'

Prompt

prompt is optional and can provide additional context for transcribing:

transcription = client.transcribe(file.path, prompt: '')
transcription.text # '...'

OpenAI API Reference prompt

Format

format is optional and supports json, text, srt or vtt:

transcription = client.transcribe(file.path, format: OmniAI::Transcribe::Format::TEXT)
transcription.text # '...'

OpenAI API Reference response_format

Language

language is optional and may improve accuracy and latency:

transcription = client.transcribe(file.path, language: OmniAI::Transcribe::Language::SPANISH)
transcription.text

OpenAI API Reference language

Temperature

temperature is optional and must be between 0.0 (more deterministic) and 1.0 (less deterministic):

transcription = client.transcribe(file.path, temperature: 0.2)
transcription.text

OpenAI API Reference temperature

Speak

Speech can be generated by passing text with a block:

File.open('example.ogg', 'wb') do |file|
  client.speak('How can a clam cram in a clean cream can?') do |chunk|
    file << chunk
  end
end

If a block is not provided then a tempfile is returned:

tempfile = client.speak('Can you can a can as a canner can can a can?')
tempfile.close
tempfile.unlink

Voice

voice is optional and must be one of the supported voices:

client.speak('She sells seashells by the seashore.', voice: OmniAI::OpenAI::Speak::Voice::SHIMMER)

OpenAI API Reference voice

Model

model is optional and must be either tts-1 or tts-1-hd (default):

client.speak('I saw a kitten eating chicken in the kitchen.', format: OmniAI::OpenAI::Speak::Model::TTS_1)

OpenAI API Refernce model

Speed

speed is optional and must be between 0.25 and 0.40:

client.speak('How much wood would a woodchuck chuck if a woodchuck could chuck wood?', speed: 4.0)

OmniAI API Reference speed

Format

format is optional and supports MP3 (default), OPUS, AAC, FLAC, WAV or PCM:

client.speak('A pessemistic pest exists amidst us.', format: OmniAI::OpenAI::Speak::Format::FLAC)

OpenAI API Reference format

Files

Finding an File

client.files.find(id: 'file_...')

Listing all Files

client.files.all

Uploading a File

Using a File

file = client.files.build(io: File.open('demo.pdf', 'wb'))
file.save!

Using a Path

file = client.files.build(io: 'demo.pdf'))
file.save!

Downloading a File

file = client.files.find(id: 'file_...')
File.open('...', 'wb') do |file|
  file.content do |chunk|
    file << chunk
  end
end

Destroying a File

client.files.destroy!('file_...')

Assistants

Finding an Assistant

client.assistants.find(id: 'asst_...')

Listing all Assistants

client.assistants.all

Creating an Assistant

assistant = client.assistants.build
assistant.name = 'Ringo'
assistant.model = OmniAI::OpenAI::Chat::Model::GPT_4
assistant.description = 'The drummer for the Beatles.'
assistant.save!

Updating an Assistant

assistant = client.assistants.find(id: 'asst_...')
assistant.name = 'George'
assistant.model = OmniAI::OpenAI::Chat::Model::GPT_4
assistant.description = 'A guitarist for the Beatles.'
assistant.save!

Destroying an Assistant

client.assistants.destroy!('asst_...')

Threads

Finding a Thread

client.threads.find(id: 'thread_...')

Creating a Thread

thread = client.threads.build
thread.metadata = { user: 'Ringo' }
thread.save!

Updating a Thread

thread = client.threads.find(id: 'thread_...')
thread.metadata = { user: 'Ringo' }
thread.save!

Destroying a Threads

client.threads.destroy!('thread_...')

Messages

Finding a Message

thread = client.threads.find(id: 'thread_...')
message = thread.messages.find(id: 'msg_...')
message.save!

Listing all Messages

thread = client.threads.find(id: 'thread_...')
thread.messages.all

Creating a Message

thread = client.threads.find(id: 'thread_...')
message = thread.messages.build(role: 'user', content: 'Hello?')
message.save!

Updating a Message

thread = client.threads.find(id: 'thread_...')
message = thread.messages.build(role: 'user', content: 'Hello?')
message.save!

Runs

Finding a Run

thread = client.threads.find(id: 'thread_...')
run = thread.runs.find(id: 'run_...')
run.save!

Listing all Runs

thread = client.threads.find(id: 'thread_...')
thread.runs.all

Creating a Run

run = client.runs.find(id: 'thread_...')
run = thread.runs.build
run.metadata = { user: 'Ringo' }
run.save!

Updating a Run

thread = client.threads.find(id: 'thread_...')
run = thread.messages.find(id: 'run_...')
run.metadata = { user: 'Ringo' }
run.save!

Polling a Run

run.terminated? # false
run.poll!
run.terminated? # true
run.status # 'cancelled' / 'failed' / 'completed' / 'expired'

Cancelling a Run

thread = client.threads.find(id: 'thread_...')
run = thread.runs.cancel!(id: 'run_...')

Embed

Text can be converted into a vector embedding for similarity comparison usage via:

response = client.embed('The quick brown fox jumps over a lazy dog.')
response.embedding # [0.0, ...]