RubyLLM 1.14: Tailwind Chat UI + Rails AI Generators + Config DSL 🎨🤖🛠️
This release overhauls the Rails experience.
RubyLLM 1.14 ships a complete Tailwind-powered chat UI, new Rails generators for agents/tools/schemas, a simplified configuration DSL where providers self-register their options, and a batch of bug fixes across logging, agents, associations, and dependency constraints.
🎨 Tailwind Chat UI
demo.mp4
The Rails chat UI generator now produces a polished Tailwind-based interface out of the box. Run the generator and get a working chat app with message streaming, model selection, tool call display, and proper empty states — all styled with Tailwind CSS.
bin/rails generate ruby_llm:chat_uiThe generated views use role-aware partials (_user, _assistant, _system, _tool, _error) for clean message rendering, Turbo Stream templates for real-time updates, and broadcasts_to for simplified broadcasting.
🏗️ Rails AI Generators
New generators scaffold agents, tools, and schemas with a single command:
bin/rails generate ruby_llm:agent SupportAgent
bin/rails generate ruby_llm:tool WeatherToolThe install generator now creates conventional directories (app/agents, app/tools, app/schemas, app/prompts) with .gitkeep files. Tool partials follow a new naming convention for tool-specific rendering, and the generator produces matching specs.
⚙️ Simplified Configuration DSL
Provider configuration options are now self-registered by each provider using a declarative configuration_options method, replacing the monolithic attr_accessor list in Configuration. When a provider is registered, its options become attr_accessors on RubyLLM::Configuration automatically.
Each provider declares its own option keys following the <provider_slug>_<option> convention:
# In the provider class:
class DeepSeek < RubyLLM::Provider
class << self
def configuration_options
%i[deepseek_api_key deepseek_api_base]
end
end
end
# These become available in configuration automatically:
RubyLLM.configure do |config|
config.deepseek_api_key = ENV["DEEPSEEK_API_KEY"]
config.deepseek_api_base = ENV["DEEPSEEK_API_BASE"]
endThis means third-party provider gems can register their own config keys without patching Configuration.
🐛 Fixes
Faraday Logging Memory Bloat
Faraday body logging no longer serializes large payloads (e.g. base64-encoded PDFs) when the log level is above DEBUG. This eliminates unnecessary memory allocations on every request. Fixes #562.
Gemspec Faraday Constraint Regression
Fixed an overly strict Faraday version constraint in the gemspec that broke compatibility for some users. Fixes #682.
Agent assume_model_exists Propagation
Agent class-level assume_model_exists configuration now correctly propagates to chat instances. Previously, setting it on the agent class had no effect.
Renamed Model Associations
Fixed incorrect foreign key references when using renamed model associations with acts_as helpers.
Eager Logger Interpolation
Fixed eager string interpolation in log statements that caused unnecessary object allocations even when logging was disabled.
Error Raised with String Argument
RubyLLM::Error.new("message") no longer raises a NoMethodError. Fixes #653.
MySQL/MariaDB Compatibility
Fixed JSON column default handling for MySQL/MariaDB users. Fixes #521.
File Attachments Across Ruby Versions
Stabilized file attachment handling to work consistently across different Ruby versions.
Model Type Classification
Fixed model type classification for models that support multiple output modalities (e.g. text + image).
VertexAI Registry Filtering
Slash-based model IDs are now filtered out of the Vertex AI registry, preventing invalid model entries.
📦 Updated Model Registry
Default models and the model registry have been refreshed with the latest available models.
Installation
gem "ruby_llm", "1.14"Upgrading from 1.13.x
bundle update ruby_llmMerged PRs
- Fix NoMethodError when Error is raised with a string argument by @cgmoore120 in #653
- Fix/562 faraday logging memory bloat by @sergiobayona in #661
- Fix/eager logger interpolation and dead options by @sergiobayona in #662
- Fix incorrect reference for renamed model associations by @jayelkaake in #668
- Fix agent not propagating assume_model_exists from class config by @jeffmcfadden in #680
New Contributors
- @cgmoore120 made their first contribution in #653
- @sergiobayona made their first contribution in #661
- @jayelkaake made their first contribution in #668
- @jeffmcfadden made their first contribution in #680
Full Changelog: 1.13.2...1.14.0