Configuration
Riffer uses a centralized configuration system for provider credentials and settings.
Global Configuration
Use Riffer.configure to set up provider credentials:
Riffer.configure do |config| config.openai.api_key = ENV['OPENAI_API_KEY'] config.amazon_bedrock.region = 'us-east-1' config.amazon_bedrock.api_token = ENV['BEDROCK_API_TOKEN'] config.anthropic.api_key = ENV['ANTHROPIC_API_KEY'] end
Accessing Configuration
Access the current configuration via Riffer.config:
Riffer.config.openai.api_key # => "sk-..." Riffer.config.amazon_bedrock.region # => "us-east-1" Riffer.config.anthropic.api_key # => "sk-ant-..."
Provider-Specific Configuration
For provider credentials and setup, see the individual Provider guides.
MCP (Model Context Protocol)
Optional settings for MCP server integrations:
| Option | Description |
|---|---|
credentials |
Optional Proc for per-run tools/call HTTP headers: ->(manifest:, matched_tags:, context:) { Hash or nil } |
discovery_runner |
Riffer::Runner instance for tool discovery (default Runner::Sequential.new) |
Riffer.configure do |config| config.mcp.credentials = lambda do |manifest:, matched_tags:, context:| {"Authorization" => "Bearer #{token_for(context)}"} end end
See MCP for registration, tags, and agent use_mcp.
Tool Runtime (Experimental)
Warning: This feature is experimental and may be removed or changed without warning in a future release.
Configure the default tool runtime for all agents:
Riffer.configure do |config| config.tool_runtime = Riffer::Tools::Runtime::Threaded end
| Value | Description |
|---|---|
Riffer::Tools::Runtime subclass |
Instantiated automatically (e.g., Riffer::Tools::Runtime::Inline, Riffer::Tools::Runtime::Threaded) |
Riffer::Tools::Runtime instance |
Custom runtime with specific options |
Proc |
Dynamic resolution |
Per-agent configuration overrides this global default. See Advanced Tool Configuration β Tool Runtime for details.
Skills
Skills-related global configuration lives under config.skills.
Default activation tool
Override the tool the LLM calls to activate a skill. Defaults to Riffer::Skills::ActivateTool:
Riffer.configure do |config| config.skills.default_activate_tool = MyCustomActivateTool end
Per-agent override is available inside the skills block via activate_tool MyCustomActivateTool. See Skills β Custom Activation Tool.
Default backend
Set an app-wide default skills backend. Used by any agent that declares a skills block without specifying its own backend:
Riffer.configure do |config| config.skills.default_backend = Riffer::Skills::FilesystemBackend.new(".skills") end
Accepts a Riffer::Skills::Backend instance or a Proc that receives context and returns a backend. Defaults to nil β agents that donβt set their own backend get no skills, matching pre-existing behavior. Per-agent backends override this default.
Message ID Strategy
Opt in to stable identifiers on every message for logging, persistence, or replay:
Riffer.configure do |config| config.message_id_strategy = :uuidv7 end
| Value | Description |
|---|---|
:none (default) |
No id is generated; message.id returns nil and :id is omitted from to_h. |
:uuid |
UUIDv4 via SecureRandom.uuid. |
:uuidv7 |
Time-ordered UUIDv7 via SecureRandom.uuid_v7 (Ruby 3.3+). |
When the strategy is not :none, every Riffer::Messages::Base instance β user prompts, system instructions, assistant responses, and tool results β gets an auto-generated id at construction time. IDs are included in message.to_h when present and omitted when nil. Provider API payloads are unaffected; the id stays on the Ruby side.
When constructing a Riffer::Agent::Session from persisted history with the strategy enabled, supply ids on every seeded message yourself β Riffer never fabricates identifiers for pre-existing history. Messages built via the Riffer::Messages::* constructors auto-generate ids per the strategy, so as long as those constructors are used at message-creation time, ids flow through.
See Messages β IDs for more details.
Experimental: History Healing
Warning: This feature is experimental and may change without notice.
Opts the agent into keeping the tool_use β tool_result invariant intact on its own:
Riffer.configure do |config| config.experimental_history_healing = true end
When enabled, two repairs run automatically:
-
Seeded session. Passing a pre-populated
Riffer::Agent::SessiontoAgent.new(session: ...)silently drops orphanedtool_useexchanges (assistanttool_callwith no matchingToolresult) and parentlessToolmessages before the next inference call. Pending tool calls on the resume boundary β the last assistant whose tail is purelyToolresults (or none) β are preserved;execute_pending_tool_callsruns them on the next LLM call. -
Interrupts. Any orphan
tool_useleft when the loop is interrupted (caller-issuedinterrupt!or the built-inINTERRUPT_MAX_STEPSceiling) is filled with a placeholderRiffer::Messages::Toolcarryingerror_type: :interruptedand the content"Tool call interrupted before completion.". Filledcall_ids are exposed onRiffer::Agent::Response#healed_tool_call_ids(andRiffer::StreamEvents::Interrupt#healed_tool_call_idswhen streaming).
Defaults to false β pre-healing behavior. Seeded sessions pass through untouched, and orphan tool_use left by an interrupt remain in history for execute_pending_tool_calls to re-run on the next call.
There is no per-call override and no customizable placeholder. Callers needing finer control can call agent.session.update(tool_call_id:, ...) after the interrupt returns to upgrade a placeholder in place. See Agent Lifecycle β Healing pending tool results on interrupt.
Agent-Level Configuration
Override global configuration at the agent level:
provider_options
Pass options directly to the provider client:
class MyAgent < Riffer::Agent model 'openai/gpt-5-mini' # Override API key for this agent only provider_options api_key: ENV['CUSTOM_OPENAI_KEY'] end
model_options
Pass options to each LLM request:
class MyAgent < Riffer::Agent model 'openai/gpt-5-mini' # These options are sent with every generate/stream call model_options temperature: 0.7, reasoning: 'medium' end
Common Model Options
OpenAI
| Option | Description |
|---|---|
temperature |
Sampling temperature (0.0-2.0) |
max_tokens |
Maximum tokens in response |
top_p |
Nucleus sampling parameter |
reasoning |
Reasoning effort level (low, medium, high) |
web_search |
Enable web search (true or config hash) |
class MyAgent < Riffer::Agent model 'openai/gpt-5-mini' model_options temperature: 0.7, reasoning: 'medium' end
Amazon Bedrock
Options are passed through to the Bedrock Converse API.
| Option | Description |
|---|---|
inference_config |
Hash with max_tokens, temperature, top_p, stop_sequences |
additional_model_request_fields |
Hash for model-specific params (e.g., top_k for Claude) |
class MyAgent < Riffer::Agent model 'amazon_bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0' model_options inference_config: {temperature: 0.7, max_tokens: 4096} end
Anthropic
| Option | Description |
|---|---|
temperature |
Sampling temperature |
max_tokens |
Maximum tokens in response |
top_p |
Nucleus sampling parameter |
top_k |
Top-k sampling parameter |
thinking |
Extended thinking config hash (Claude 3.7+) |
web_search |
Enable web search (true or config hash) |
class MyAgent < Riffer::Agent model 'anthropic/claude-haiku-4-5-20251001' model_options temperature: 0.7, max_tokens: 4096 end # With extended thinking (Claude 3.7+) class ReasoningAgent < Riffer::Agent model 'anthropic/claude-haiku-4-5-20251001' model_options thinking: {type: "enabled", budget_tokens: 10000} end
Environment Variables
Recommended pattern for managing credentials:
# config/initializers/riffer.rb (Rails) # or at application startup Riffer.configure do |config| config.openai.api_key = ENV.fetch('OPENAI_API_KEY') { raise 'OPENAI_API_KEY not set' } if ENV['BEDROCK_REGION'] config.amazon_bedrock.region = ENV['BEDROCK_REGION'] config.amazon_bedrock.api_token = ENV['BEDROCK_API_TOKEN'] end end
Multiple Configurations
For different environments or use cases, use agent-level overrides:
class ProductionAgent < Riffer::Agent model 'openai/gpt-5-mini' provider_options api_key: ENV['PRODUCTION_OPENAI_KEY'] end class DevelopmentAgent < Riffer::Agent model 'openai/gpt-5-mini' provider_options api_key: ENV['DEV_OPENAI_KEY'] model_options temperature: 0.0 # Deterministic for testing end