ActiveAgent

ActiveAgent is a Rails-like framework and engine designed to integrate LLMs, AI agents, and custom tools into Ruby on Rails applications with ease.

It supports multiple provider adapters (Gemini, OpenAI, Anthropic), handles multi-turn tool-execution loops automatically, offers plug-and-play conversation memory (in-memory or ActiveRecord), and includes a gorgeous streaming chat widget ready for your Rails views.


Installation

Add this line to your application's Gemfile:

gem 'active_agent_rails', path: 'path/to/active_agent_rails'

And then execute:

$ bundle install

Setup Configuration & Memory

Run the installation generator to create the initializer and the migration for database-backed conversation history:

$ rails generate active_agent:install

Run the migration to create the active_agent_messages table:

$ rails db:migrate

Configuration

You can configure providers and API keys in config/initializers/active_agent.rb:

ActiveAgent.configure do |config|
  # Default provider: :gemini, :openai, or :anthropic
  config.default_provider = :gemini

  # API Keys
  config.gemini_api_key = ENV["GEMINI_API_KEY"]
  config.openai_api_key = ENV["OPENAI_API_KEY"]
  config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]

  # Memory store: :in_memory or :active_record
  config.memory_store = :active_record
end

Defining an Agent

Generate a new agent using the generator:

$ rails generate active_agent:agent customer_service

This scaffolds app/agents/customer_service_agent.rb. You can configure the system instructions, providers, and declare custom tools:

# app/agents/customer_service_agent.rb
class CustomerServiceAgent < ActiveAgent::Base
  provider :gemini # Or :openai, :anthropic
  model "gemini-2.5-flash"
  system_prompt "You are a customer service assistant. You help users check their order details."

  # Expose a Ruby method as a tool for the agent
  tool :get_order_status, description: "Check shipping status of an order" do
    parameter :order_id, type: :string, description: "Order ID (e.g., ORD-123)", required: true
  end

  # Define the tool implementation
  def get_order_status(order_id:)
    order = Order.find_by(order_number: order_id)
    return "Order #{order_id} not found." unless order

    "Order #{order_id} is currently #{order.status}. Expected delivery: #{order.delivery_date}."
  end
end

Usage

1. In Ruby Code (Rails Controller, Job, or Console)

# Initialize agent for a specific user/session ID
agent = CustomerServiceAgent.new(conversation_id: "user_session_99")

# Run agent chat
response = agent.chat("Hi! Can you check the status of my order ORD-5541?")
puts response
# => "Order ORD-5541 is currently Shipped. Expected delivery: 2026-07-02."

2. View Integration: Streaming Chat Widget

Mount the ActiveAgent engine routes in your application's config/routes.rb:

# config/routes.rb
Rails.application.routes.draw do
  # ... other routes
  mount ActiveAgent::Engine => "/active_agent"
end

Now, you can drop the chat assistant widget into any of your Rails views:

<!-- app/views/home/index.html.erb -->
<%= active_agent_chat_widget(agent: :customer_service, conversation_id: current_user.id) %>

This will inject a floating AI chat assistant at the bottom right. When the user types a message:

  • The UI communicates with /active_agent/chats.
  • The controller leverages Server-Sent Events (SSE) to stream the response back in real-time.
  • The assistant displays typing animations and updates the response character-by-character.
  • Message history is preserved automatically in the database using the ActiveRecord memory store.

Customizing Tools

ActiveAgent tools support several parameter types (:string, :integer, :number, :boolean, :array, :object):

tool :update_profile, description: "Update user profile data" do
  parameter :user_id, type: :integer, description: "Target user ID"
  parameter :updates, type: :object, description: "Hash of update key-values"
end

The engine maps these types to the appropriate API schema formatting expected by the LLM providers (Google Gemini, OpenAI, Anthropic).


License

The gem is available as open source under the terms of the MIT License.