Class: ActionAgent::SandboxInstanceTier
- Inherits:
-
Object
- Object
- ActionAgent::SandboxInstanceTier
- Includes:
- ActiveModel::Attributes, ActiveModel::Model
- Defined in:
- app/models/action_agent/sandbox_instance_tier.rb
Overview
SandboxInstanceTier
Defines available instance sizes for sandbox sessions. Similar to Google Colab or Hugging Face Spaces hardware tiers.
Usage:
tier = SandboxInstanceTier.find(:gpu_t4)
tier.cpu_cores # => 4
tier.memory_gb # => 16
tier.gpu # => "nvidia-t4"
tier.hourly_cost # => 0.35
Constant Summary collapse
- TIERS =
Instance tier definitions Pricing modeled after Colab/HuggingFace/Lambda Labs
{ # --- Free Tier --- free: { id: "free", name: "Free", description: "Basic CPU instance for testing", cpu_cores: 2, memory_gb: 4, disk_gb: 10, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.00, monthly_cost: 0.00, category: "free" }, # --- CPU Tiers --- cpu_small: { id: "cpu_small", name: "CPU Small", description: "2 vCPUs, 8GB RAM", cpu_cores: 2, memory_gb: 8, disk_gb: 20, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.05, monthly_cost: 36.00, category: "pro" }, cpu_medium: { id: "cpu_medium", name: "CPU Medium", description: "4 vCPUs, 16GB RAM", cpu_cores: 4, memory_gb: 16, disk_gb: 50, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.10, monthly_cost: 72.00, category: "pro" }, cpu_large: { id: "cpu_large", name: "CPU Large", description: "8 vCPUs, 32GB RAM", cpu_cores: 8, memory_gb: 32, disk_gb: 100, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.20, monthly_cost: 144.00, category: "pro" }, cpu_xlarge: { id: "cpu_xlarge", name: "CPU XLarge", description: "16 vCPUs, 64GB RAM", cpu_cores: 16, memory_gb: 64, disk_gb: 200, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.40, monthly_cost: 288.00, category: "enterprise" }, # --- GPU Tiers --- gpu_t4: { id: "gpu_t4", name: "GPU T4", description: "NVIDIA T4 (16GB VRAM), 4 vCPUs, 16GB RAM", cpu_cores: 4, memory_gb: 16, disk_gb: 50, gpu: "nvidia-tesla-t4", gpu_memory_gb: 16, hourly_cost: 0.35, monthly_cost: 252.00, category: "pro" }, gpu_l4: { id: "gpu_l4", name: "GPU L4", description: "NVIDIA L4 (24GB VRAM), 8 vCPUs, 32GB RAM", cpu_cores: 8, memory_gb: 32, disk_gb: 100, gpu: "nvidia-l4", gpu_memory_gb: 24, hourly_cost: 0.70, monthly_cost: 504.00, category: "pro" }, gpu_a10g: { id: "gpu_a10g", name: "GPU A10G", description: "NVIDIA A10G (24GB VRAM), 8 vCPUs, 32GB RAM", cpu_cores: 8, memory_gb: 32, disk_gb: 100, gpu: "nvidia-a10g", gpu_memory_gb: 24, hourly_cost: 1.00, monthly_cost: 720.00, category: "enterprise" }, gpu_a100_40: { id: "gpu_a100_40", name: "GPU A100 40GB", description: "NVIDIA A100 (40GB VRAM), 12 vCPUs, 85GB RAM", cpu_cores: 12, memory_gb: 85, disk_gb: 200, gpu: "nvidia-a100-40gb", gpu_memory_gb: 40, hourly_cost: 2.50, monthly_cost: 1800.00, category: "enterprise" }, gpu_a100_80: { id: "gpu_a100_80", name: "GPU A100 80GB", description: "NVIDIA A100 (80GB VRAM), 12 vCPUs, 170GB RAM", cpu_cores: 12, memory_gb: 170, disk_gb: 200, gpu: "nvidia-a100-80gb", gpu_memory_gb: 80, hourly_cost: 4.00, monthly_cost: 2880.00, category: "enterprise" }, # --- High Memory Tiers --- highmem_medium: { id: "highmem_medium", name: "High Memory Medium", description: "4 vCPUs, 64GB RAM", cpu_cores: 4, memory_gb: 64, disk_gb: 100, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.25, monthly_cost: 180.00, category: "pro" }, highmem_large: { id: "highmem_large", name: "High Memory Large", description: "8 vCPUs, 128GB RAM", cpu_cores: 8, memory_gb: 128, disk_gb: 200, gpu: nil, gpu_memory_gb: nil, hourly_cost: 0.50, monthly_cost: 360.00, category: "enterprise" } }.freeze
Class Method Summary collapse
- .all ⇒ Object
- .available ⇒ Object
- .by_category(category) ⇒ Object
- .cpu_tiers ⇒ Object
- .default_tier ⇒ Object
- .find(id) ⇒ Object
- .free_tier ⇒ Object
- .gpu_tiers ⇒ Object
Instance Method Summary collapse
- #as_json ⇒ Object
- #display_price ⇒ Object
- #display_specs ⇒ Object
- #free? ⇒ Boolean
-
#gcp_accelerator_config ⇒ Object
GCP accelerator config.
-
#gcp_machine_type ⇒ Object
GCP machine type mapping.
- #gpu_display_name ⇒ Object
- #has_gpu? ⇒ Boolean
-
#to_incus_limits ⇒ Object
Convert to Incus resource limits.
-
#to_kubernetes_resources ⇒ Object
Convert to Kubernetes resource spec.
Class Method Details
.all ⇒ Object
210 211 212 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 210 def all TIERS.values.map { |attrs| new(attrs) } end |
.available ⇒ Object
221 222 223 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 221 def available all.select(&:available) end |
.by_category(category) ⇒ Object
225 226 227 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 225 def by_category(category) all.select { |t| t.category == category.to_s } end |
.cpu_tiers ⇒ Object
229 230 231 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 229 def cpu_tiers all.select { |t| t.gpu.nil? } end |
.default_tier ⇒ Object
241 242 243 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 241 def default_tier find(:cpu_small) end |
.find(id) ⇒ Object
214 215 216 217 218 219 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 214 def find(id) id = id.to_sym raise ArgumentError, "Unknown tier: #{id}" unless TIERS.key?(id) new(TIERS[id]) end |
.free_tier ⇒ Object
237 238 239 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 237 def free_tier find(:free) end |
.gpu_tiers ⇒ Object
233 234 235 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 233 def gpu_tiers all.select { |t| t.gpu.present? } end |
Instance Method Details
#as_json ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 346 def as_json(*) { id: id, name: name, description: description, specs: { cpu_cores: cpu_cores, memory_gb: memory_gb, disk_gb: disk_gb, gpu: gpu, gpu_memory_gb: gpu_memory_gb }, pricing: { hourly_cost: hourly_cost.to_f, monthly_cost: monthly_cost.to_f, display: display_price }, category: category, available: available } end |
#display_price ⇒ Object
254 255 256 257 258 259 260 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 254 def display_price if free? "Free" else "$#{format('%.2f', hourly_cost)}/hr" end end |
#display_specs ⇒ Object
262 263 264 265 266 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 262 def display_specs specs = [ "#{cpu_cores} vCPU", "#{memory_gb}GB RAM", "#{disk_gb}GB disk" ] specs << "#{gpu_memory_gb}GB #{gpu_display_name}" if has_gpu? specs.join(" | ") end |
#free? ⇒ Boolean
246 247 248 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 246 def free? hourly_cost.zero? end |
#gcp_accelerator_config ⇒ Object
GCP accelerator config
337 338 339 340 341 342 343 344 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 337 def gcp_accelerator_config return nil unless has_gpu? { accelerator_type: gpu, accelerator_count: 1 } end |
#gcp_machine_type ⇒ Object
GCP machine type mapping
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 319 def gcp_machine_type if has_gpu? # GPU instances use n1 or a2 series case gpu when "nvidia-a100-40gb", "nvidia-a100-80gb" "a2-highgpu-1g" else "n1-standard-#{cpu_cores}" end elsif memory_gb > cpu_cores * 8 # High memory ratio "n2-highmem-#{cpu_cores}" else "n2-standard-#{cpu_cores}" end end |
#gpu_display_name ⇒ Object
268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 268 def gpu_display_name return nil unless gpu case gpu when "nvidia-tesla-t4" then "T4" when "nvidia-l4" then "L4" when "nvidia-a10g" then "A10G" when "nvidia-a100-40gb" then "A100 40GB" when "nvidia-a100-80gb" then "A100 80GB" else gpu.gsub("nvidia-", "").upcase end end |
#has_gpu? ⇒ Boolean
250 251 252 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 250 def has_gpu? gpu.present? end |
#to_incus_limits ⇒ Object
Convert to Incus resource limits
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 282 def to_incus_limits limits = { "limits.cpu" => cpu_cores.to_s, "limits.memory" => "#{memory_gb}GB", "limits.processes" => (cpu_cores * 250).to_s } # GPU passthrough requires host configuration if has_gpu? limits["nvidia.runtime"] = "true" limits["nvidia.require.cuda"] = "true" end limits end |
#to_kubernetes_resources ⇒ Object
Convert to Kubernetes resource spec
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'app/models/action_agent/sandbox_instance_tier.rb', line 299 def to_kubernetes_resources resources = { requests: { cpu: "#{cpu_cores * 500}m", memory: "#{memory_gb / 2}Gi" }, limits: { cpu: cpu_cores.to_s, memory: "#{memory_gb}Gi" } } if has_gpu? resources[:limits]["nvidia.com/gpu"] = "1" end resources end |