OpenAI Provider
The OpenAI provider connects to OpenAI’s API for GPT models.
Installation
Add the OpenAI gem to your Gemfile:
gem 'openai'
Configuration
Set your API key globally:
Riffer.configure do |config| config.openai.api_key = ENV['OPENAI_API_KEY'] end
Or per-agent:
class MyAgent < Riffer::Agent model 'openai/gpt-4o' provider_options api_key: ENV['CUSTOM_API_KEY'] end
Supported Models
Use any OpenAI model in the openai/model format:
model 'openai/gpt-4o' model 'openai/gpt-4o-mini' model 'openai/gpt-4-turbo' model 'openai/gpt-3.5-turbo'
Model Options
temperature
Controls randomness (0.0-2.0):
model_options temperature: 0.7
max_tokens
Maximum tokens in response:
model_options max_tokens: 4096
reasoning
Enables extended thinking (for supported models):
model_options reasoning: 'medium' # 'low', 'medium', or 'high'
When reasoning is enabled, you’ll receive ReasoningDelta and ReasoningDone events during streaming.
web_search
Enable server-side web search using OpenAI’s web_search_preview tool. Pass true to use defaults or a hash to merge with the tool definition:
# Enable with defaults model_options web_search: true # With custom configuration model_options web_search: {search_context_size: "medium"}
Example
Riffer.configure do |config| config.openai.api_key = ENV['OPENAI_API_KEY'] end class CodeReviewAgent < Riffer::Agent model 'openai/gpt-4o' instructions 'You are a code reviewer. Provide constructive feedback.' model_options temperature: 0.3, reasoning: 'medium' end agent = CodeReviewAgent.new puts agent.generate("Review this code: def add(a,b); a+b; end")
Streaming
agent.stream("Explain Ruby blocks").each do |event| case event when Riffer::StreamEvents::TextDelta print event.content when Riffer::StreamEvents::ReasoningDelta # Extended thinking content print "[thinking] #{event.content}" when Riffer::StreamEvents::ReasoningDone puts "\n[reasoning complete]" end end
Tool Calling
OpenAI provider converts tools to function calling format with strict mode:
class CalculatorTool < Riffer::Tool description "Performs basic math operations" params do required :operation, String, enum: ["add", "subtract", "multiply", "divide"] required :a, Float, description: "First number" required :b, Float, description: "Second number" end def call(context:, operation:, a:, b:) case operation when "add" then a + b when "subtract" then a - b when "multiply" then a * b when "divide" then a / b end.to_s end end class MathAgent < Riffer::Agent model 'openai/gpt-4o' uses_tools [CalculatorTool] end
Web Search
Web search allows the model to search the web for up-to-date information. When enabled, the provider injects the web_search_preview tool into the request.
class SearchAgent < Riffer::Agent model 'openai/gpt-4o' model_options web_search: true end agent = SearchAgent.new agent.stream("What's the latest Ruby release?").each do |event| case event when Riffer::StreamEvents::WebSearchStatus # OpenAI emits a full status sequence: # "in_progress" → "searching" → "open_page" → "completed" puts "[search: #{event.status}]" puts " query: #{event.query}" if event.query puts " url: #{event.url}" if event.url when Riffer::StreamEvents::WebSearchDone puts "[search complete: #{event.query}]" when Riffer::StreamEvents::TextDelta print event.content end end
Note: OpenAI sources include
urlbut nottitle. Each source in thesourcesarray will havetitle: nil.
Message Format
The provider converts Riffer messages to OpenAI format:
Riffer Message |
OpenAI Role |
|---|---|
System |
developer |
User |
user |
Assistant |
assistant |
Tool |
function_call_output |
Direct Provider Usage
provider = Riffer::Providers::OpenAI.new(api_key: ENV['OPENAI_API_KEY']) response = provider.generate_text( prompt: "Hello!", model: "gpt-4o", temperature: 0.7 ) puts response.content