Class: ActionAgent::Api::SandboxesController
- Inherits:
-
BaseController
- Object
- ActionController::Base
- ActionAgent::ApplicationController
- BaseController
- ActionAgent::Api::SandboxesController
- Defined in:
- app/controllers/action_agent/api/sandboxes_controller.rb
Instance Method Summary collapse
-
#compare ⇒ Object
POST /api/sandboxes/compare Run multiple providers in a single sandbox using parallel generation jobs.
-
#create ⇒ Object
POST /api/sandboxes Create a new sandbox session, owned by whoever opened it.
-
#destroy ⇒ Object
DELETE /api/sandboxes/:session_id End sandbox session.
-
#index ⇒ Object
GET /api/sandboxes List available sandbox types and sample tasks.
-
#run ⇒ Object
POST /api/sandboxes/:session_id/run Execute a task in the sandbox.
-
#show ⇒ Object
GET /api/sandboxes/:session_id Get sandbox status and run history.
Methods inherited from ActionAgent::ApplicationController
Instance Method Details
#compare ⇒ Object
POST /api/sandboxes/compare Run multiple providers in a single sandbox using parallel generation jobs
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 20 def compare providers = params[:providers] || %w[anthropic openai ollama] task = params[:task] sandbox_id = params[:sandbox_id] return render json: { error: "Task required" }, status: :bad_request unless task.present? return render json: { error: "At least 2 providers required" }, status: :bad_request if providers.size < 2 # Validate providers invalid = providers - %w[anthropic openai ollama] return render json: { error: "Invalid providers: #{invalid.join(', ')}" }, status: :bad_request if invalid.any? # Use existing sandbox or create a new one (single container per user) sandbox = if sandbox_id.present? owned(SandboxSession).find_by!(session_id: sandbox_id) else s = SandboxSession.new(sandbox_type: params[:sandbox_type] || "playwright_mcp") s.user = current_user if s.respond_to?(:user=) s.save! s.provision! s.reload s end unless sandbox.can_run? return render json: { error: sandbox.expired? ? "Session expired" : "Maximum runs exceeded", sandbox: sandbox.summary }, status: :unprocessable_entity end sandbox.update!(status: :running) comparison_id = SecureRandom.uuid # Spawn a separate generation job for each provider (all in same sandbox) runs = providers.map do |provider| run_id = SecureRandom.uuid SandboxRunJob.perform_later(sandbox.id, run_id, task, provider) { provider: provider, run_id: run_id, status: "running" } end render json: { comparison_id: comparison_id, task: task, sandbox: sandbox.summary, runs: runs }, status: :accepted end |
#create ⇒ Object
POST /api/sandboxes Create a new sandbox session, owned by whoever opened it.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 87 def create @sandbox = SandboxSession.new(sandbox_params) # Guarded: the association only exists when the host app configured a # user model, and a single-user install configures none. @sandbox.user = current_user if @sandbox.respond_to?(:user=) @sandbox.agent_template = AgentTemplate.find_by(slug: params[:template_slug]) if params[:template_slug] if @sandbox.save @sandbox.provision! @sandbox.reload # Reload to get updated status after provisioning render json: { sandbox: @sandbox.summary }, status: :created else render json: { errors: @sandbox.errors. }, status: :unprocessable_entity end end |
#destroy ⇒ Object
DELETE /api/sandboxes/:session_id End sandbox session
155 156 157 158 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 155 def destroy @sandbox.expire! render json: { deleted: true } end |
#index ⇒ Object
GET /api/sandboxes List available sandbox types and sample tasks
76 77 78 79 80 81 82 83 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 76 def index render json: { sandbox_types: SandboxSession::SANDBOX_TYPES, free_tier_limits: SandboxSession::FREE_TIER_LIMITS, templates: free_tier_templates, sample_tasks: sample_tasks } end |
#run ⇒ Object
POST /api/sandboxes/:session_id/run Execute a task in the sandbox
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 111 def run unless @sandbox.can_run? return render json: { error: @sandbox.expired? ? "Session expired" : "Maximum runs exceeded", sandbox: @sandbox.summary }, status: :unprocessable_entity end # Whatever limits the host app imposes on running an agent. if (denial = ActionAgent.quota_denial(current_owner, :execution)) return render json: { error: "Plan limit reached", upgrade_required: true, message: denial }, status: :payment_required end task = params[:task] return render json: { error: "Task required" }, status: :bad_request unless task.present? # Provider selection (default to anthropic) provider = params[:provider] || "anthropic" unless %w[anthropic openai ollama].include?(provider) return render json: { error: "Invalid provider" }, status: :bad_request end record_execution_usage @sandbox.update!(status: :running) # Execute via job for async processing run_id = SecureRandom.uuid SandboxRunJob.perform_later(@sandbox.id, run_id, task, provider) render json: { run_id: run_id, status: "running", provider: provider, sandbox: @sandbox.summary }, status: :accepted end |
#show ⇒ Object
GET /api/sandboxes/:session_id Get sandbox status and run history
105 106 107 |
# File 'app/controllers/action_agent/api/sandboxes_controller.rb', line 105 def show render json: { sandbox: @sandbox.details } end |