Skip to content

Active Agent

Agents are Controllers that act as the core of the Active Agent framework. Active Agent manages AI-driven interactions, prompts, actions, and generative responses using Action Prompt. Action Prompt is a structured way to manage prompts, render formatted message content through action views, and handle responses.

Active Agent implements base actions that can be used by any agent that inherits from ActiveAgent::Base.

The primary action is the prompt_context which provides a common interface to render prompts with context messages.

ruby
class TranslationAgent < ApplicationAgent
  generate_with :openai, instructions: "Translate the given text from one language to another."

  def translate
    prompt
  end
end
ruby
json.type :function
json.function do
  json.name action_name
  json.description "This action takes params locale and message and returns a translated message."
  json.parameters do
    json.type :object
    json.properties do
      json.locale do
        json.type :string
        json.description "The target language for translation."
      end
      json.message do
        json.type :string
        json.description "The text to be translated."
      end
    end
  end
end
erb
translate: <%= params[:message] %>; to <%= params[:locale] %>

Key Features

  • Prompt management: Handle prompt-generation request-response cycles with actions that render templated prompts with messages, context, and params.
  • Action methods: Define public methods that become callable tools or functions for the Agent to perform actions that can render prompts to the agent or generative views to the user.
  • Queued Generation: Manage asynchronous prompt generation and response cycles with Active Job, allowing for efficient processing of requests.
  • Callbacks: Use before_action, after_action, before_generation, after_generation callbacks to manage prompt context and handle generated responses.
  • Streaming: Support real-time updates with the on_stream callback to the user interface based on agent interactions.

Example

ruby
class TravelAgent < ApplicationAgent
  before_action :set_user

  def search
    @departure = params[:departure]
    @destination = params[:destination]
    @results = params[:results] || []
    prompt(content_type: :html)
  end

  def book
    @flight_id = params[:flight_id]
    @passenger_name = params[:passenger_name]
    @confirmation_number = params[:confirmation_number]
    prompt(content_type: :text)
  end

  def confirm
    @confirmation_number = params[:confirmation_number]
    @passenger_name = params[:passenger_name]
    @flight_details = params[:flight_details]
    prompt(content_type: :text)
  end

  private

  def set_user
    @user = params[:user] || OpenStruct.new(name: "Guest")
  end
end
erb
<h2>Travel Search Results</h2>

<p>Searching for flights from <%= @departure %> to <%= @destination %></p>

<ul>
<% @results.each do |flight| %>
  <li>
    <%= flight[:airline] %> - $<%= flight[:price] %>
    <br>Departure: <%= flight[:departure] %>
  </li>
<% end %>
</ul>

<p>Would you like to book any of these flights?</p>
erb
Booking flight <%= @flight_id %>
Passenger: <%= @passenger_name %>
Confirmation: <%= @confirmation_number %>
Status: Booking confirmed
erb
Your booking has been confirmed!

Confirmation Number: <%= @confirmation_number || "TRV123456" %>
Passenger: <%= @passenger_name || "Guest" %>
Flight: <%= @flight_details || "Flight details will be sent via email" %>

Thank you for choosing our travel service.

Using the Travel Agent

ruby
# Different actions use different formats based on their purpose
search_response = TravelAgent.with(
  message: "Search flights",
  departure: "NYC",
  destination: "LAX",
  results: []
).search
assert search_response.message.content.include?("Travel Search Results")  # Rich UI format

book_response = TravelAgent.with(
  message: "Book flight",
  flight_id: "AA123",
  passenger_name: "Test User",
  confirmation_number: "CNF789"
).book
assert book_response.message.content.include?("Booking flight AA123")   # Text format
assert book_response.message.content.include?("Test User")

confirm_response = TravelAgent.with(
  message: "Confirm",
  confirmation_number: "CNF789",
  passenger_name: "Test User"
).confirm
assert confirm_response.message.content.include?("Your booking has been confirmed!") # Simple text format
Search Response Example

activeagent/test/agents/travel_agent_test.rb:132

ruby
<h2>Travel Search Results</h2>

<p>Searching for flights from NYC to LAX</p>

<ul>
  <li>
    American Airlines - $299
    <br>Departure: 10:00 AM
  </li>
  <li>
    Delta - $350
    <br>Departure: 2:00 PM
  </li>
</ul>

<p>Would you like to book any of these flights?</p>
Book Response Example

activeagent/test/agents/travel_agent_test.rb:151

ruby
Booking flight AA123
Passenger: John Doe
Confirmation: CNF123456
Status: Booking confirmed
Confirm Response Example

activeagent/test/agents/travel_agent_test.rb:169

ruby
Your booking has been confirmed!

Confirmation Number: TRV789012
Passenger: Jane Smith
Flight: AA123 - NYC to LAX, departing 10:00 AM

Thank you for choosing our travel service.

Concepts

User-Agent interactions

We're not talking about HTTP User Agents here, but rather the interactions between the user and the AI agent. The user interacts with the agent through a series of prompt context messages and actions that are defined in the agent class. These actions can be used to retrieve data, create custom views, handle user input, and manage the flow of data between different components of your application.

Agents are conceptually similar to a user in the sense that they have a persona, behavior, and state. They can perform actions and have objectives, just like a user. The following table illustrates the similarities between the user and the AI agent:

UserAgent
WhoPersonaArchetype
BehaviorStoriesInstructions
StateScenarioContext
WhatObjectiveGoal
HowActionsTools

Agent Oriented Programming (AOP)

Agent Oriented Programming (AOP) is a programming paradigm that focuses on the use of agents as a primary building block of applications. It allows developers to create modular, reusable components that can be easily integrated into existing systems. AOP promotes code reusability, maintainability, and scalability, making it easier to build complex AI-driven applications.

OOPAOP
unitObjectAgent
paramsmessage, args, blockprompt, context, tools
computationmethod, send, returnperform, generate, response
stateinstance variablesprompt context
flowmethod callsprompt and response cycles
constraintscoded logicwritten instructions