Releases: OlympiaAI/raix
Releases · OlympiaAI/raix
Release list
Release 2.0.5
Fixed
Raix::Configurationno longer defaultstemperatureto0.0. The default was being injected into every request payload, which OpenRouter rejects with404 No endpoints found that can handle the requested parameterswhen routed to providers whosesupported_parameterslist omitstemperature(notably Anthropic's Claude 4.7 family) andprovider.require_parameters: trueis set — which Raix sets automatically wheneverjson: trueis passed tochat_completion. Callers that want a specific temperature should set one explicitly (self.temperature = 0.0on the including class, orRaix.configure { |c| c.temperature = 0.0 }globally); when unset, Raix now omits the parameter and the provider's own server-side default applies.max_tokens,max_completion_tokens, andmodeldefaults are unchanged.Raix::FunctionToolAdapternow forwards the full JSON-Schema dict for each function parameter to RubyLLM instead of rebuilding it fromtype+descriptiononly. Rich schema fields likeadditionalProperties,items,enum, and nestedpropertieswere silently dropped, leaving providers (notably Gemini's structured output via OpenRouter) to invent degenerate shapes fortype: objectarguments — e.g. emitting{"prefix" => false}instead of{"prefix:title" => "..."}. Function declarations with rich object schemas now reach the provider intact.- The outer tool-args schema continues to inject
additionalProperties: falseandstrict: trueby default for OpenAI strict-mode compatibility, but consumers can override either by setting them explicitly in the function declaration. - Multimodal
transcriptcontent is no longer silently dropped on the RubyLLM backend. OpenAI-style content arrays (atextpart plus one or more{ type: "image_url", image_url: { url: ... } }parts) were passed to RubyLLM verbatim, which treats the array as plain text — so a vision model received text only and confabulated an answer. Raix now translatesimage_urlparts into RubyLLM attachments viaRaix::MultimodalContentAdapter, decoding base64data:URIs into binary IO (RubyLLM'sAttachmentdoes not natively recognizedata:URIs) and passing http(s) URLs through. Text-only completions are unaffected (#51).
Release 2.0.4
Fixed
ruby_llm_requestnow preserves the upstream provider'sid,model, andproviderfields, plus the fullusagepayload (includingprompt_tokens_details.cached_tokensandcompletion_tokens_details.reasoning_tokens) on the OpenAI-compatible response hash. Previously the conversion dropped everything exceptchoicesand basic token counts, which broke callers that needed the generation id for authoritative cost lookups (e.g. OpenRouter's/api/v1/generationendpoint) or that wanted to verify prompt-cache hits viacached_tokens.- Added
require "active_support/core_ext/module/delegation"soRaix::ChatCompletionloads cleanly without an external preload of ActiveSupport. The class usesdelegate :configuration, to: :classbut did not pull in the required core ext, so a barerequire "raix"would raiseNoMethodErrorfordelegate.
Release 2.0.2
Fixed
- Ensure gem files are world-readable (644) for Docker deployments where gems are installed as root but the app runs as a non-root user.
- Added gemspec-level safety net that normalizes file permissions at build time.
Release 2.0.3
Fixed
NoMethodError: undefined method 'strip' for nilinRaix::ChatCompletionwhen an LLM (notably Gemini under certain stop conditions) returns a final assistant message with"content": null. Three call sites inlib/raix/chat_completion.rbnow usecontent.to_s.stripso a nil response coerces to""instead of raising.
Release 2.0.1
Release 2.0.0
Breaking Changes
- Migrated from OpenRouter/OpenAI gems to RubyLLM - Raix now uses RubyLLM as its unified backend for all LLM providers. This provides better multi-provider support and a more consistent API.
- Configuration changes - API keys are now configured through RubyLLM's configuration system instead of separate client instances.
- Removed direct client dependencies -
openrouterandruby-openaigems are no longer direct dependencies; RubyLLM handles provider connections.
Added
before_completionhook - New hook system for intercepting and modifying chat completion requests before they're sent to the AI provider.- Configure at global, class, or instance levels
- Hooks receive a
CompletionContextwith access to messages, params, and the chat completion instance - Messages are mutable for content filtering, PII redaction, adding system prompts, etc.
- Params can be modified for dynamic model selection, A/B testing, and more
- Supports any callable object (Proc, Lambda, or object responding to
#call)
FunctionToolAdapter- New adapter for converting Raix function declarations to RubyLLM tool formatTranscriptAdapter- New adapter for bridging Raix's abbreviated message format with standard OpenAI format
Changed
- Chat completions now use RubyLLM's unified API for all providers (OpenAI, Anthropic, Google, etc.)
- Improved provider detection based on model name patterns
- Streamlined internal architecture with dedicated adapters
Migration Guide
Update your configuration from:
Raix.configure do |config|
config.openrouter_client = OpenRouter::Client.new(access_token: "...")
config.openai_client = OpenAI::Client.new(access_token: "...")
endTo:
RubyLLM.configure do |config|
config.openrouter_api_key = ENV["OPENROUTER_API_KEY"]
config.openai_api_key = ENV["OPENAI_API_KEY"]
# Also supports: anthropic_api_key, gemini_api_key
endRelease 1.0.3
v1.0.2
What's Changed
Added
- Added method to check for API client availability in Configuration
Changed
- Updated ruby-openai dependency to ~> 8.1
Fixed
- Fixed gemspec file reference
Full Changelog: v1.0.1...v1.0.2
v1.0.1
What's Changed
Fixed
- Fixed PromptDeclarations module namespace - now properly namespaced under Raix (#8)
- Removed Rails.logger dependencies from PromptDeclarations for non-Rails environments
- Fixed documentation example showing incorrect
openai: trueusage (should be model string) (#9) - Added comprehensive tests for PromptDeclarations module
Changed
- Improved error handling in PromptDeclarations to catch StandardError instead of generic rescue
Issues Resolved
- Closes #8 - Prompt declarations in README.md to not match the code
- Closes #9 - Chat Completion Fails Due to Invalid JSON Payload (Status 400)
Full Changelog: v1.0.0...v1.0.1
v1.0.0
Major Release: Automatic Tool Call Continuation
This major release introduces automatic continuation after tool calls, eliminating the need for the loop parameter entirely. The system now automatically handles tool execution and continues the conversation until the AI provides a final text response.
Breaking Changes
- Deprecated
loopparameter - The system now automatically continues conversations after tool calls. Theloopparameter shows a deprecation warning but still works for backwards compatibility. - Tool-based completions now return strings instead of arrays - When functions are called, the final response is a string containing the AI's text response, not an array of function results.
stop_looping\!renamed tostop_tool_calls_and_respond\!- Better reflects the new automatic continuation behavior.
New Features
- Automatic conversation continuation - Chat completions automatically continue after tool execution without needing the
loopparameter. max_tool_callsparameter - Controls the maximum number of tool invocations to prevent infinite loops (default: 25).- Configuration for
max_tool_calls- Addedmax_tool_callsto the Configuration class with sensible defaults.
Migration Guide
# Before
response = ai.chat_completion(loop: true)
# After (automatic)
response = ai.chat_completion
# To limit tool calls
response = ai.chat_completion(max_tool_calls: 5)Other Changes
- Improved CI/CD workflow to use
bundle exec rake cifor consistent testing - Fixed conflict between
loopattribute and Ruby'sKernel.loopmethod (fixes #11) - Fixed various RuboCop warnings using keyword argument forwarding
- Improved error handling with proper warning messages
See the CHANGELOG for full details.