Skip to content

Configuration ​

ActiveAgent provides flexible configuration options for both framework-level settings and provider-specific configurations. Configure global behavior like retry strategies and logging, or define multiple AI providers with environment-specific settings.

Global Settings ​

Configure framework-level behavior using ActiveAgent.configure:

ruby
ActiveAgent.configure do |config|
  # Retry configuration (see Retries documentation for details)
  config.retries = true
  config.retries_count = 3

  # Logging (non-Rails only)
  config.logger = Logger.new(STDOUT)
  config.logger.level = Logger::INFO
end

Reference ​

SettingTypeDefaultDescription
retriesBoolean, ProctrueRetry strategy for failed requests
retries_countInteger3Maximum retry attempts
retries_onArray<Class>Network errorsException classes that trigger retries
loggerLoggerRails.loggerLogger instance (Rails auto-configured)

Flow and Precedence ​

ActiveAgent applies configuration settings in a hierarchical order, where each level can override the previous one. Understanding this flow helps you control exactly how your agents behave at different stages.

Configuration Hierarchy ​

Settings are applied in the following order, from lowest to highest precedence:

  1. Global Root Settings - Base configuration defined in your YAML file or set on the configuration object
  2. Environment-Specific Settings - Override root settings based on the current environment (development, test, production)
  3. Agent-Level Settings - Configuration provided to generate_with or embed_with in your agent class
  4. Request-Level Settings - Settings passed when calling prompt, embed, or generate_with on an instance
  5. Generation Call - Final settings applied at the moment prompt_now or embed_now is triggered

Each level overrides only the specific settings it defines, leaving others unchanged from previous levels.

Configuration Flow Example ​

yaml
# config/active_agent.yml
# 1. Global root settings
openai: &openai
  service: "OpenAI"
  access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
  model: "gpt-4o"
  temperature: 0.5

# 2. Environment-specific overrides
development:
  openai:
    <<: *openai
    model: "gpt-4o-mini"      # Overrides model for development
    temperature: 0.7           # Overrides temperature for development
ruby
# 3. Agent-level configuration
class MyAgent < ApplicationAgent
  generate_with :openai, temperature: 0.8  # Overrides temperature from YAML
end

# 4. Request-level configuration
agent = MyAgent.with(message: "Hello")
  .prompt_context
  .generate_with(:openai, model: "gpt-4o", max_tokens: 1000)  # Overrides model, adds max_tokens

# 5. Generation triggered
result = agent.prompt_now  # Uses: openai service, gpt-4o model, 0.8 temperature, 1000 max_tokens

Precedence in Action ​

Given the example above, here's how settings are resolved:

SettingRootEnvironmentAgent ClassRequestFinal Value
service"OpenAI"--"OpenAI""OpenAI"
model"gpt-4o""gpt-4o-mini"-"gpt-4o""gpt-4o"
temperature0.50.70.8-0.8
max_tokens---10001000
access_token"sk-..."---"sk-..."

Practical Applications ​

Development vs Production Models:

yaml
openai: &openai
  service: "OpenAI"
  access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
  model: "gpt-4o"

development:
  openai:
    <<: *openai
    model: "gpt-4o-mini"  # Cheaper for development

production:
  openai:
    <<: *openai
    model: "gpt-4o"  # Full capability for production

Agent-Specific Defaults:

ruby
class CreativeAgent < ApplicationAgent
  generate_with :openai, temperature: 0.9  # High creativity by default
end

class PreciseAgent < ApplicationAgent
  generate_with :openai, temperature: 0.2  # Low temperature for consistency
end

Request-Level Overrides:

ruby
class CreativeAgent < ApplicationAgent
  generate_with :openai, temperature: 0.9  # High creativity by default

  # Low temperature takes effect
  def imagine
    prompt(temperature: 0.3)
  end
end

Key Principles ​

  • Explicit overrides implicit - Specifically set values always win over inherited ones
  • Closer to execution wins - Settings applied closer to prompt_now take precedence
  • Partial overrides - You only need to specify the settings you want to change
  • Environment awareness - Environment-specific settings automatically apply without code changes

Providers ​

YAML Configuration File ​

The recommended way to configure providers is using a YAML file with environment-specific sections. This approach keeps API keys secure, supports multiple providers, and allows different settings per environment.

Create config/active_agent.yml:

yaml
anthropic: &anthropic
  service: "Anthropic"
  access_token: <%= Rails.application.credentials.dig(:anthropic, :access_token) %>
openai: &openai
  service: "OpenAI"
  access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
open_router: &open_router
  service: "OpenRouter"
  access_token: <%= Rails.application.credentials.dig(:open_router, :access_token) || Rails.application.credentials.dig(:open_router, :api_key) %>
ollama: &ollama
  service: "Ollama"
  model: "gpt-oss:20b"
bedrock: &bedrock
  service: "Bedrock"
  aws_region: <%= ENV.fetch("AWS_REGION", "us-east-1") %>
mock: &mock
  service: "Mock"
  model: "mock-model"
ruby_llm: &ruby_llm
  service: "RubyLLM"
gemini: &gemini
  service: "Gemini"
  model: "gemini-2.0-flash"
  api_key: <%= Rails.application.credentials.dig(:gemini, :api_key) %>
yaml
development:
  openai:
    <<: *openai
    model: "gpt-4o-mini"
  open_router:
    <<: *open_router
    model: "qwen/qwen3-30b-a3b:free"
  ollama:
    <<: *ollama
  anthropic:
    <<: *anthropic
  bedrock:
    <<: *bedrock
  mock:
    <<: *mock
  ruby_llm:
    <<: *ruby_llm
  gemini:
    <<: *gemini

Key features:

  • YAML anchors (&openai, *openai) - Reuse common configuration blocks
  • ERB templates - Access Rails credentials and environment variables
  • Environment sections - Different settings for development, test, production
  • Provider-specific settings - Configure API keys, models, temperatures, etc.

Loading Configuration ​

Load the YAML configuration in your Rails initializer:

ruby
# config/initializers/activeagent.rb
ActiveAgent.configuration_load(Rails.root.join("config/active_agent.yml"))

The Railtie automatically loads config/active_agent.yml if it exists, so you typically don't need to do this manually in Rails applications.

Storing API Keys ​

Best practice: Store API keys in Rails credentials, not directly in YAML files.

bash
# Edit credentials
rails credentials:edit

# Add provider keys
openai:
  access_token: sk-...

anthropic:
  access_token: sk-ant-...

open_router:
  access_token: sk-or-...

Reference in active_agent.yml:

yaml
openai: &openai
  service: "OpenAI"
  access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>

Reference ​

Common settings available across all providers:

SettingTypeRequiredDescription
serviceStringYesProvider class name (OpenAI, Anthropic, OpenRouter, Ollama, RubyLLM, Mock)
access_token / api_keyStringYes*API authentication key
modelStringYes*Model identifier for the LLM to use
temperatureFloatNoRandomness control (0.0-2.0, default varies by provider)
max_tokensIntegerNoMaximum tokens in response

* Required by most providers. Some providers like Ollama may not require authentication for local instances, and may have default models configured.

Provider-specific settings: Each provider supports additional configuration options beyond these common settings. For complete details on available settings, environment variables, and provider-specific features, see:

Using Configured Providers ​

Once configured, reference providers by name in your agents:

ruby
class MyAgent < ApplicationAgent
  generate_with :openai  # Uses settings from config/active_agent.yml
end

Multiple Provider Instances ​

Configure multiple instances of the same provider with different settings:

yaml
development:
  openai_fast:
    service: "OpenAI"
    access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
    model: "gpt-4o-mini"
    temperature: 0.7

  openai_precise:
    service: "OpenAI"
    access_token: <%= Rails.application.credentials.dig(:openai, :access_token) %>
    model: "gpt-4o"
    temperature: 0.3

Use in agents:

ruby
class FastAgent < ApplicationAgent
  generate_with :openai_fast
end

class PreciseAgent < ApplicationAgent
  generate_with :openai_precise
end

Retrys ​

ActiveAgent automatically retries failed requests due to network errors. Configure retry behavior globally or provide custom retry strategies.

Quick configuration:

ruby
# Enable/disable retries
config.retries = true           # Enable automatic retries (default)
config.retries = false          # Disable all retries

# Adjust retry count
config.retries_count = 5        # Maximum retry attempts (default: 3)

# Add custom exception classes
config.retries_on << CustomNetworkError

For advanced retry configuration including exponential backoff, custom strategies, rate limiting, and per-provider settings, see Retries.

Logging ​

Rails Applications ​

In Rails, ActiveAgent automatically inherits logging settings from your Rails application:

  • Logger: Uses Rails.logger by default
  • Log level: Inherits from Rails.logger.level

Configure in your environment files:

ruby
# config/environments/development.rb
config.log_level = :debug

# config/environments/production.rb
config.log_level = :info

Non-Rails Applications ​

For standalone Ruby applications, configure logging manually:

ruby
ActiveAgent.configure do |config|
  # Set up logger
  config.logger = Logger.new(STDOUT)
  config.logger.level = Logger::INFO
end

Log levels:

  • DEBUG - All instrumentation events with full detail
  • INFO - Important operations (API calls, completions)
  • WARN - Errors and retries only
  • ERROR - Only failures
  • FATAL - Disable instrumentation logging

See Instrumentation for detailed logging and monitoring options.

Dashboard configuration ​

ActiveAgent.configure and config/active_agent.yml configure the framework only. The dashboard is a separate gem — actionagent — with its own configuration object and its own initializer, so none of its settings hang off ActiveAgent:

ruby
# config/initializers/action_agent.rb
# `rails generate action_agent:install` writes this file with the options
# commented out; fill in the ones you need.
ActionAgent.configure do |config|
  config.authentication_method = ->(controller) { controller.authenticate_admin! }
  config.ingest_api_key = Rails.application.credentials.dig(:active_agent, :ingest_api_key)

  # Run the mount as a read-only observability surface:
  # config.execution_enabled = false

  # The Ask ActiveAgents assistant is a development and CI tool, on in
  # development and test only. Turn it on elsewhere deliberately:
  # config.assistant_enabled = true

  # The Run Agent workbench is recorded for its conversation's replay, with
  # field values masked. Record nothing:
  # config.capture_dashboard_sessions = false

  # Boot GitHub checkouts as local processes (development and test only
  # unless local_sandboxes_enabled is set):
  # config.sandbox_service = :local
end

The two stay separate on purpose. config/active_agent.yml is read by every app that runs agents; config/initializers/action_agent.rb only exists in the app that mounts ActionAgent::Engine. Provider credentials still come from config/active_agent.yml even for agents executed from the dashboard — the dashboard's own per-owner keys layer on top of it rather than replacing it.

Dev Console covers authentication_method, multi_tenant, account_class and trace_model_class. Its Local checkout sandboxes section covers the sandbox and Claude Code options:

OptionDefault
sandbox_service:mock (SANDBOX_BACKEND overrides it)
local_sandboxes_enabledunset: on in development and test, off elsewhere
local_sandbox_rootRails.root.join("tmp/action_agent/sandboxes")
local_sandbox_boot_timeout600 seconds
claude_code_command"claude"
claude_code_permission_mode"acceptEdits"
claude_code_max_turnsnil (Claude Code's own default)
claude_code_timeout1800 seconds
claude_code_auth:api_key (or :local_login for the local machine; :sandbox_login for per-user sandbox sign-in)
claude_code_login_timeout300 seconds (bounded to 1–600)
claude_code_hosted_login_enabledfalse; remote adapters must also implement the login lifecycle

Self-Hosted Dashboard adds ingest_api_key, current_account_resolver, trace_retention, execution_enabled, assistant_enabled, capture_dashboard_sessions, sandbox_backends, layout, and model_concerns and controller_concerns, which put your app's own concerns on the engine's models and controllers. The host-app integration seams — quota_checker, usage_recorder, agent_scope_resolver, tenant_resolver, trace_owner_resolver, provider_credentials_resolver and the rest — are documented on ActionAgent itself, in the gem's lib/action_agent.rb.

  • Dev Console - Installing and mounting the actionagent dashboard engine
  • Retries - Retry strategies, custom retry logic, and error handling
  • Instrumentation - Logging, monitoring, and event tracking
  • Rails Integration - Rails-specific configuration and setup
  • Testing - Test configuration and mock providers
  • Agents - How agents use configuration in generate_with
  • Providers - Provider-specific features and behavior