Module: ActionAgent

Defined in:
lib/action_agent.rb,
lib/action_agent.rb,
lib/action_agent/engine.rb,
lib/action_agent/version.rb,
app/models/action_agent/agent.rb,
lib/action_agent/compatibility.rb,
app/models/action_agent/api_key.rb,
app/models/action_agent/agent_run.rb,
app/models/action_agent/evaluation.rb,
app/models/action_agent/sandbox_run.rb,
app/models/action_agent/agent_memory.rb,
app/models/action_agent/provider_key.rb,
app/jobs/action_agent/application_job.rb,
app/jobs/action_agent/sandbox_run_job.rb,
app/models/action_agent/agent_context.rb,
app/models/action_agent/agent_message.rb,
app/models/action_agent/agent_version.rb,
app/models/action_agent/model_pricing.rb,
app/services/action_agent/mcp_catalog.rb,
app/models/action_agent/agent_template.rb,
app/models/action_agent/evaluation_run.rb,
app/models/action_agent/sandbox_session.rb,
app/models/action_agent/telemetry_trace.rb,
app/services/action_agent/agent_toolbox.rb,
app/models/action_agent/agent_generation.rb,
app/models/action_agent/recording_action.rb,
app/models/concerns/action_agent/ownable.rb,
app/services/action_agent/tool_discovery.rb,
app/jobs/action_agent/agent_execution_job.rb,
app/jobs/action_agent/sandbox_cleanup_job.rb,
app/jobs/action_agent/trace_retention_job.rb,
app/models/action_agent/session_recording.rb,
app/queries/action_agent/agent_executions.rb,
app/services/action_agent/agent_registrar.rb,
app/services/action_agent/agent_scorecard.rb,
app/models/action_agent/agent_memory_entry.rb,
app/models/action_agent/application_record.rb,
app/models/action_agent/recording_snapshot.rb,
app/jobs/action_agent/sandbox_provision_job.rb,
app/models/action_agent/sandbox_instance_tier.rb,
lib/generators/action_agent/install_generator.rb,
app/controllers/action_agent/traces_controller.rb,
app/models/concerns/action_agent/adapter_aware.rb,
app/services/action_agent/mock_sandbox_backend.rb,
app/services/action_agent/sandbox_orchestrator.rb,
app/controllers/action_agent/api/mcp_controller.rb,
app/services/action_agent/playwright_mcp_client.rb,
app/controllers/action_agent/api/base_controller.rb,
app/serializers/action_agent/interaction_preview.rb,
app/controllers/action_agent/api/tools_controller.rb,
app/controllers/action_agent/dashboard_controller.rb,
app/services/action_agent/agent_execution_service.rb,
app/controllers/action_agent/api/agents_controller.rb,
app/controllers/action_agent/api/traces_controller.rb,
app/jobs/action_agent/process_telemetry_traces_job.rb,
app/services/action_agent/mcp_recording_middleware.rb,
app/controllers/action_agent/api/metrics_controller.rb,
app/controllers/action_agent/application_controller.rb,
app/models/concerns/action_agent/session_recordable.rb,
app/services/action_agent/evaluation_runner_service.rb,
app/services/action_agent/session_recording_service.rb,
app/controllers/action_agent/api/api_keys_controller.rb,
app/controllers/action_agent/api/analytics_controller.rb,
app/controllers/action_agent/api/sandboxes_controller.rb,
app/controllers/action_agent/api/templates_controller.rb,
app/serializers/action_agent/agent_message_serializer.rb,
app/controllers/action_agent/api/agent_runs_controller.rb,
app/controllers/action_agent/api/evaluations_controller.rb,
app/controllers/action_agent/api/mcp_servers_controller.rb,
app/serializers/action_agent/telemetry_trace_serializer.rb,
app/controllers/action_agent/api/interactions_controller.rb,
app/controllers/action_agent/api/provider_keys_controller.rb,
app/controllers/action_agent/api/trace_reports_controller.rb,
app/serializers/action_agent/trace_interaction_serializer.rb,
app/controllers/action_agent/api/instance_tiers_controller.rb,
app/controllers/action_agent/api/provider_models_controller.rb,
app/controllers/action_agent/api/session_recordings_controller.rb

Overview

Transitional aliases for the names this engine shipped under when it lived inside the activeagent gem (<= 1.1.0).

Three of these matter for more than tidiness:

* ActiveAgent::ProcessTelemetryTracesJob — Active Job serializes the class
name into the queue payload, so a job enqueued before the upgrade is
dequeued after it and must still resolve to something.
* ActiveAgent::TelemetryTrace — apps subclass it (the activeagents.ai
platform does) and it is referenced from initializers.
* ActiveAgent::Dashboard — every existing initializer calls
ActiveAgent::Dashboard.configure.

Each warns once through the deprecator and forwards to the new constant. Remove in the next major.

Defined Under Namespace

Modules: AdapterAware, Api, Compatibility, InteractionPreview, Ownable, SessionRecordable Classes: Agent, AgentContext, AgentExecutionJob, AgentExecutionService, AgentExecutions, AgentGeneration, AgentMemory, AgentMemoryEntry, AgentMessage, AgentMessageSerializer, AgentRegistrar, AgentRun, AgentScorecard, AgentTemplate, AgentToolbox, AgentVersion, ApiKey, ApplicationController, ApplicationJob, ApplicationRecord, DashboardController, Engine, Evaluation, EvaluationRun, EvaluationRunnerService, InstallGenerator, McpCatalog, McpRecordingMiddleware, MockSandboxBackend, ModelPricing, PlaywrightMcpClient, ProcessTelemetryTracesJob, ProviderKey, RecordingAction, RecordingSnapshot, SandboxCleanupJob, SandboxInstanceTier, SandboxOrchestrator, SandboxProvisionJob, SandboxRun, SandboxRunJob, SandboxSession, SessionRecording, SessionRecordingService, TelemetryTrace, TelemetryTraceSerializer, ToolDiscovery, TraceInteractionSerializer, TraceRetentionJob, TracesController

Constant Summary collapse

VERSION =
"1.2.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.account_classString?

Class name for the Account model (multi-tenant mode)

Returns:

  • (String, nil)


102
103
104
# File 'lib/action_agent.rb', line 102

def 
  @account_class
end

.agent_polymorphic_nameString?

Value stored in polymorphic *_type columns for dashboard agents (agent_memories.memorable_type, agent_contexts.contextable_type). Unset means the class name. A host app whose existing rows were written under its own constant sets its name here.

Returns:

  • (String, nil)


251
252
253
# File 'lib/action_agent.rb', line 251

def agent_polymorphic_name
  @agent_polymorphic_name
end

.agent_scope_resolverProc?

The agents an owner can reach. Defaults to the ones that owner owns. A host app where those differ — the platform's agents belong to users while its API keys belong to accounts — supplies its own scope.

Returns:

  • (Proc, nil)


141
142
143
# File 'lib/action_agent.rb', line 141

def agent_scope_resolver
  @agent_scope_resolver
end

.authentication_methodProc?

Authentication method to call on controllers

Returns:

  • (Proc, nil)

    A proc that receives the controller instance



94
95
96
# File 'lib/action_agent.rb', line 94

def authentication_method
  @authentication_method
end

.base_controller_classString

Deprecated.

Never consumed — dashboard controllers inherit ActionController::Base. Retained as a no-op so existing initializers that set it keep booting; remove in the next major.

Returns:

  • (String)


178
179
180
# File 'lib/action_agent.rb', line 178

def base_controller_class
  @base_controller_class
end

.current_account_methodSymbol?

Method to call on controller to get current account (multi-tenant mode). Only usable when the host app has mixed that method into the engine's controllers; otherwise use current_account_resolver.

Returns:

  • (Symbol, nil)


112
113
114
# File 'lib/action_agent.rb', line 112

def 
  @current_account_method
end

.current_account_resolverProc?

Resolves the current tenant from the controller. See current_user_resolver.

Returns:

  • (Proc, nil)


129
130
131
# File 'lib/action_agent.rb', line 129

def 
  @current_account_resolver
end

.current_user_methodSymbol?

Method to call on controller to get current user. Same caveat as current_account_method — see current_user_resolver.

Returns:

  • (Symbol, nil)


117
118
119
# File 'lib/action_agent.rb', line 117

def current_user_method
  @current_user_method
end

.current_user_resolverProc?

Resolves the signed-in user from the controller. Preferred over current_user_method: the engine's controllers are their own base class, so a host app's current_user helper is not on them unless the app deliberately put it there.

Returns:

  • (Proc, nil)


124
125
126
# File 'lib/action_agent.rb', line 124

def current_user_resolver
  @current_user_resolver
end

.encrypt_credentialsBoolean

Whether API keys and provider credentials are encrypted at rest with Active Record Encryption. On by default, which requires the host app to have run rails db:encryption:init. Turning it off stores those secrets in plain text — a deliberate downgrade, never a default.

Returns:

  • (Boolean)


244
245
246
# File 'lib/action_agent.rb', line 244

def encrypt_credentials
  @encrypt_credentials
end

.execution_enabledBoolean

Whether the dashboard may execute agents against real providers. Disable to run the dashboard as a read-only observability surface.

Returns:

  • (Boolean)


210
211
212
# File 'lib/action_agent.rb', line 210

def execution_enabled
  @execution_enabled
end

.ingest_api_keyString?

Bearer token required by the ingest API in single-tenant mode. When unset the local ingest endpoint accepts unauthenticated posts, so set it whenever the mount is reachable beyond your own machine. (Multi-tenant mode authenticates per-account keys instead.)

Returns:

  • (String, nil)


172
173
174
# File 'lib/action_agent.rb', line 172

def ingest_api_key
  @ingest_api_key
end

.layoutString?

Custom layout for the dashboard

Returns:

  • (String, nil)


153
154
155
# File 'lib/action_agent.rb', line 153

def layout
  @layout
end

.multi_tenantBoolean

Enable multi-tenant mode (requires account association)

Returns:

  • (Boolean)


98
99
100
# File 'lib/action_agent.rb', line 98

def multi_tenant
  @multi_tenant
end

.provider_credentials_resolverProc?

Resolves LLM provider credentials for a run. Receives (owner, provider_name) and returns a Hash merged into the agent's generation options (e.g. { access_token: "sk-..." } or { host: "http://localhost:11434&quot; }), or nil to fall back to the host app's config/active_agent.yml.

Unset means config/active_agent.yml is the only source, which is what a self-hosted install wants.

Returns:

  • (Proc, nil)


199
200
201
# File 'lib/action_agent.rb', line 199

def provider_credentials_resolver
  @provider_credentials_resolver
end

.quota_checkerProc?

Called before each run/trace-ingest to enforce host-app limits. Receives (owner, kind) where kind is :execution or :trace_ingest, and returns nil to allow, or to deny: a message String, or a Hash merged into the response so the app can surface its own usage numbers. Denials surface as HTTP 402 (execution) / 429 (ingest).

Unset means unlimited, which is what a self-hosted install wants.

Returns:

  • (Proc, nil)


188
189
190
# File 'lib/action_agent.rb', line 188

def quota_checker
  @quota_checker
end

.sandbox_backendsHash{String => String}

Extra sandbox backends contributed by the host app, as { "cloud_run" => "CloudRunService" }. The engine ships :mock and :local (Docker); cloud backends live in the app that operates them.

Returns:

  • (Hash{String => String})


205
206
207
# File 'lib/action_agent.rb', line 205

def sandbox_backends
  @sandbox_backends
end

.sandbox_limitsHash?

Custom sandbox limits (overrides defaults)

Returns:

  • (Hash, nil)


161
162
163
# File 'lib/action_agent.rb', line 161

def sandbox_limits
  @sandbox_limits
end

.sandbox_serviceSymbol

Sandbox service type (:local, :cloud_run, :kubernetes)

Returns:

  • (Symbol)


157
158
159
# File 'lib/action_agent.rb', line 157

def sandbox_service
  @sandbox_service
end

.storage_serviceObject?

Storage service for screenshots/snapshots

Returns:

  • (Object, nil)

    Object responding to #signed_url_for and #fetch_snapshot



165
166
167
# File 'lib/action_agent.rb', line 165

def storage_service
  @storage_service
end

.table_name_prefixObject



19
20
21
22
# File 'lib/action_agent.rb', line 19

def table_name_prefix
  global = defined?(::ActiveRecord::Base) ? ::ActiveRecord::Base.table_name_prefix : ""
  "#{global}#{@table_name_prefix ||= "active_agent_"}"
end

.tenant_resolverProc?

The tenant whose telemetry relates to owner. Traces belong to accounts while agents may belong to users, so the two are not always the same record and a host app says how to get from one to the other.

Returns:

  • (Proc, nil)


135
136
137
# File 'lib/action_agent.rb', line 135

def tenant_resolver
  @tenant_resolver
end

.trace_model_classString?

Custom trace model class (for host app overrides)

Returns:

  • (String, nil)


145
146
147
# File 'lib/action_agent.rb', line 145

def trace_model_class
  @trace_model_class
end

.trace_owner_resolverProc?

Maps an ingested trace to the owner that its newly observed agents belong to. Defaults to the trace's account in multi-tenant mode and to nobody in single-tenant mode. A host app whose agents hang off a different record (the platform's hang off the account's owning user) supplies its own mapping.

Returns:

  • (Proc, nil)


230
231
232
# File 'lib/action_agent.rb', line 230

def trace_owner_resolver
  @trace_owner_resolver
end

.trace_retentionActiveSupport::Duration, ...

How long telemetry traces are kept before TraceRetentionJob prunes them. A Duration applies to every trace; a callable receives each owner and returns that owner's window (nil keeps everything). Unset means nothing is ever deleted.

Returns:

  • (ActiveSupport::Duration, Proc, nil)


237
238
239
# File 'lib/action_agent.rb', line 237

def trace_retention
  @trace_retention
end

.upgrade_urlString?

Where the dashboard's upgrade CTAs should send people. Unset in a self-hosted install, where there is nothing to upgrade, and the CTAs say so instead of linking nowhere.

Returns:

  • (String, nil)


216
217
218
# File 'lib/action_agent.rb', line 216

def upgrade_url
  @upgrade_url
end

.usage_recorderProc?

Called after the dashboard performs a metered action, as (owner, kind) — the counterpart to quota_checker, for host apps that track usage against a plan. Unset means nothing is counted.

Returns:

  • (Proc, nil)


222
223
224
# File 'lib/action_agent.rb', line 222

def usage_recorder
  @usage_recorder
end

.use_inertiaBoolean

Enable React/Inertia frontend instead of ERB

Returns:

  • (Boolean)


149
150
151
# File 'lib/action_agent.rb', line 149

def use_inertia
  @use_inertia
end

.user_classString?

Class name for the User model

Returns:

  • (String, nil)


106
107
108
# File 'lib/action_agent.rb', line 106

def user_class
  @user_class
end

Class Method Details

.agent_modelClass

Returns the agent model class to use.

Returns:

  • (Class)

    The agent model class



329
330
331
# File 'lib/action_agent.rb', line 329

def agent_model
  ActionAgent::Agent
end

.agents_for(owner) ⇒ ActiveRecord::Relation

The agents owner can reach.

Returns:

  • (ActiveRecord::Relation)


320
321
322
323
324
# File 'lib/action_agent.rb', line 320

def agents_for(owner)
  return agent_model.for_owner(owner) if agent_scope_resolver.nil?

  agent_scope_resolver.call(owner) || agent_model.none
end

.configure {|config| ... } ⇒ Object

Configures the dashboard.

Yields:

  • (config)

    Configuration block



346
347
348
# File 'lib/action_agent.rb', line 346

def configure
  yield self
end

.deprecatorObject

Deprecation warnings for this gem, routed through Rails' machinery so a host app can silence or escalate them like any other.



88
89
90
# File 'lib/action_agent.rb', line 88

def deprecator
  @deprecator ||= ActiveSupport::Deprecation.new("2.0", "ActionAgent")
end

.execution_enabled?Boolean

Returns whether agent execution is permitted.

Returns:

  • (Boolean)


263
264
265
# File 'lib/action_agent.rb', line 263

def execution_enabled?
  @execution_enabled != false
end

.multi_tenant?Boolean

Returns whether multi-tenant mode is enabled.

Returns:

  • (Boolean)


256
257
258
# File 'lib/action_agent.rb', line 256

def multi_tenant?
  @multi_tenant == true
end

.owner_classClass?

Returns the configured owner class: the Account in multi-tenant mode, the User otherwise. Nil when the host app configured neither, which is the single-user self-hosted case.

Returns:

  • (Class, nil)


338
339
340
341
# File 'lib/action_agent.rb', line 338

def owner_class
  name = multi_tenant? ?  : user_class
  name&.safe_constantize
end

.provider_credentials(owner, provider) ⇒ Hash

Provider options for owner, or {} when the host app has none and config/active_agent.yml should be used as-is.

Returns:

  • (Hash)


289
290
291
292
293
294
295
296
# File 'lib/action_agent.rb', line 289

def provider_credentials(owner, provider)
  return {} if provider_credentials_resolver.nil?

  provider_credentials_resolver.call(owner, provider) || {}
rescue StandardError => e
  Rails.logger.warn("[ActionAgent] provider credential lookup failed: #{e.message}")
  {}
end

.quota_denial(owner, kind) ⇒ String, ...

Asks the host app whether owner may perform kind.

Returns:

  • (String, Hash, nil)

    denial message or payload, nil when allowed



279
280
281
282
283
# File 'lib/action_agent.rb', line 279

def quota_denial(owner, kind)
  return nil if quota_checker.nil?

  quota_checker.call(owner, kind)
end

.record_usage(owner, kind) ⇒ Object

Tells the host app that owner performed kind. Never raises: a bookkeeping failure must not fail the action that was already taken.



269
270
271
272
273
274
# File 'lib/action_agent.rb', line 269

def record_usage(owner, kind)
  usage_recorder&.call(owner, kind)
rescue StandardError => e
  Rails.logger.warn("[ActionAgent] usage recording failed: #{e.message}")
  nil
end

.reset!Object

Reset configuration to defaults



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/action_agent.rb', line 351

def reset!
  @authentication_method = nil
  @multi_tenant = false
  @account_class = nil
  @user_class = nil
  @current_account_method = nil
  @current_user_method = nil
  @current_user_resolver = nil
  @current_account_resolver = nil
  @agent_scope_resolver = nil
  @tenant_resolver = nil
  @trace_model_class = nil
  @use_inertia = false
  @layout = nil
  @sandbox_service = :local
  @sandbox_limits = nil
  @storage_service = nil
  @ingest_api_key = nil
  @base_controller_class = "ActionController::Base" # deprecated no-op
  @quota_checker = nil
  @provider_credentials_resolver = nil
  @sandbox_backends = {}
  @execution_enabled = true
  @table_name_prefix = "active_agent_"
  @agent_polymorphic_name = nil
  @encrypt_credentials = true
  @trace_retention = nil
  @trace_owner_resolver = nil
  @usage_recorder = nil
  @upgrade_url = nil
end

.tenant_for(owner) ⇒ Object

The tenant owner belongs to. Identity unless the host app says otherwise, which is right for every single-tenant install.



311
312
313
314
315
# File 'lib/action_agent.rb', line 311

def tenant_for(owner)
  return owner if tenant_resolver.nil?

  tenant_resolver.call(owner)
end

.trace_modelClass

Returns the trace model class to use.

Returns:

  • (Class)

    The trace model class



301
302
303
304
305
306
307
# File 'lib/action_agent.rb', line 301

def trace_model
  if trace_model_class
    trace_model_class.constantize
  else
    ActionAgent::TelemetryTrace
  end
end