OmniAI::OpenAI
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 isENV['OPENAI_API_KEY'])api_prefix(optional) - used with a host when necessaryorganization(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')
Usage with OpenAI-compatible gateways
Private gateways and governed AI control planes can also be configured with a
custom host while keeping application code on OmniAI's OpenAI provider:
client = OmniAI::OpenAI::Client.new(
host: ENV.fetch('OPENAI_HOST', 'https://api.openai.com'),
api_key: ENV.fetch('OPENAI_API_KEY')
)
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-5.2):
completion = client.chat('How fast is a cheetah?', model: OmniAI::OpenAI::Chat::Model::GPT_5_5)
completion.content # 'A cheetah can reach speeds over 100 km/h.'
Note that temperature is not supported by every model (e.g. gpt-5, gpt-5.5 and the o-series). It is
omitted from the request for those models rather than sent and rejected — see TEMPERATURE_UNSUPPORTED_MODELS.
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:)
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.
Reasoning
OpenAI o1 and o3 models support reasoning, which provides a summary of the model's thought process.
# Enable reasoning with unified thinking API
response = client.chat("What is 25 * 25?", model: "o3-mini", thinking: true)
# Or use OpenAI-specific reasoning options
response = client.chat("What is 25 * 25?", model: "o3-mini", reasoning: { effort: "high", summary: "auto" })
Reasoning Effort Levels:
low- Minimal reasoningmedium- Balanced reasoninghigh- Maximum reasoning effort
Accessing Reasoning Content
response.choices.first..contents.each do |content|
case content
when OmniAI::Chat::Thinking
puts "Reasoning: #{content.thinking}"
when OmniAI::Chat::Text
puts "Response: #{content.text}"
end
end
Streaming with Reasoning
client.chat("What are the prime factors of 1234567?", model: "o3-mini", thinking: true, stream: $stdout)
OpenAI API Reference reasoning
Other Responses API Options
Any option that is not modelled explicitly is forwarded to the Responses API verbatim, so parameters the gem does not wrap are still reachable:
completion = client.chat('Summarize this.', model: 'gpt-5.5', max_output_tokens: 512, store: false)
# continue a stored conversation
completion = client.chat('And the next one?', previous_response_id: 'resp_123')
This covers max_output_tokens, previous_response_id, store, parallel_tool_calls, metadata,
truncation, top_p, service_tier, and prompt_cache_key, among others.
OpenAI API Reference responses
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 # '...'
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
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)
Model
model is optional and is one of tts-1, tts-1-hd, or gpt-4o-mini-tts (default):
client.speak('I saw a kitten eating chicken in the kitchen.', format: OmniAI::OpenAI::Speak::Model::TTS_1)
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)
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)
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_...')
Embed
Text can be converted into a vector embedding for similarity comparison usage via:
response = client.('The quick brown fox jumps over a lazy dog.')
response. # [0.0, ...]