Class: ActiveAgent::Dashboard::SandboxSession

Inherits:
ApplicationRecord show all
Defined in:
lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb

Overview

Manages sandbox execution sessions for agent runs.

Sandbox sessions provide isolated execution environments for running agents with tools like browser automation, file system access, etc.

Supports both local (Docker/Incus) and cloud (Cloud Run) sandbox providers.

Examples:

Creating a sandbox session

session = ActiveAgent::Dashboard::SandboxSession.create!(
  sandbox_type: "playwright_mcp"
)
session.provision!

Constant Summary collapse

SANDBOX_TYPES =

Sandbox types

%w[playwright_mcp terminal research].freeze
DEFAULT_LIMITS =

Default limits (can be overridden by platform tier limits)

{
  max_runs: 10,
  timeout_seconds: 300,
  max_tokens: 50_000,
  session_duration_minutes: 15
}.freeze

Instance Method Summary collapse

Methods inherited from ApplicationRecord

for_owner, owner_association, table_name

Instance Method Details

#active?Boolean

Check if session is still valid

Returns:

  • (Boolean)


65
66
67
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 65

def active?
  !expired? && !failed? && !completed? && expires_at > Time.current
end

#can_run?Boolean

Check if can run more tasks

Returns:

  • (Boolean)


70
71
72
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 70

def can_run?
  active? && runs_count < max_runs
end

#detailsObject

Detailed info including runs



147
148
149
150
151
152
153
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 147

def details
  summary.merge(
    runs: runs,
    total_duration_ms: total_duration_ms,
    last_activity_at: last_activity_at&.iso8601
  )
end

#expire!Object

Expire the session



125
126
127
128
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 125

def expire!
  update!(status: :expired)
  ActiveAgent::Dashboard::SandboxCleanupJob.perform_later(id) if cloud_run_job_id.present?
end

#mark_ready!(sandbox_url:, sandbox_job_id: nil) ⇒ Object

Mark as ready with sandbox URL



116
117
118
119
120
121
122
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 116

def mark_ready!(sandbox_url:, sandbox_job_id: nil)
  update!(
    status: :ready,
    cloud_run_url: sandbox_url,
    cloud_run_job_id: sandbox_job_id
  )
end

#provision!Object

Provision the sandbox



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 102

def provision!
  return if provisioning? || ready?

  update!(status: :provisioning)

  # Use configured sandbox service
  if Rails.env.development? || Rails.env.test?
    ActiveAgent::Dashboard::SandboxProvisionJob.perform_now(id)
  else
    ActiveAgent::Dashboard::SandboxProvisionJob.perform_later(id)
  end
end

#record_run!(task:, result:, duration_ms:, tokens:, screenshots: [], provider: nil) ⇒ Object

Record a new run (thread-safe for parallel execution)



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 75

def record_run!(task:, result:, duration_ms:, tokens:, screenshots: [], provider: nil)
  run = {
    id: SecureRandom.uuid,
    task: task,
    result: result,
    duration_ms: duration_ms,
    tokens: tokens,
    screenshots: screenshots,
    provider: provider,
    status: "completed",
    created_at: Time.current.iso8601
  }

  with_lock do
    reload
    self.runs = runs + [ run ]
    self.runs_count = runs.size
    self.total_tokens += tokens
    self.total_duration_ms += duration_ms
    self.last_activity_at = Time.current
    save!
  end

  run
end

#summaryObject

Summary for API responses



131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb', line 131

def summary
  {
    id: id,
    session_id: session_id,
    sandbox_type: sandbox_type,
    status: status,
    runs_count: runs_count,
    max_runs: max_runs,
    total_tokens: total_tokens,
    expires_at: expires_at&.iso8601,
    created_at: created_at.iso8601,
    cloud_run_url: cloud_run_url
  }
end