robot_lab-ractor
Ractor-based CPU parallelism for the RobotLab LLM agent framework.
[!CAUTION] This gem is under active development. APIs may change without notice.
What it provides
RactorWorkerPool— shared pool of Ractor workers for CPU-bound tools; tools markedractor_safe trueare routed through it automaticallyRactorNetworkScheduler— DAG-aware parallel execution of robot pipelines using RactorsRactorBoundary— deep-freeze utilities for safely sharing objects across Ractor boundariesRactorMemoryProxy— thread-safe proxy exposingRobotLab::Memoryto Ractor workers viaRactor::WrapperRobotLab.ractor_pool/.shutdown_ractor_pool— process-level pool management added to theRobotLabmodule
Installation
Add to your Gemfile:
gem "robot_lab"
gem "robot_lab-ractor"
CPU-Bound Tools
Mark a tool ractor_safe true and RobotLab automatically routes its calls through the global RactorWorkerPool instead of running inline:
class TranscribeAudio < RubyLLM::Tool
ractor_safe true
description "Transcribe an audio file"
param :path, type: :string, desc: "Path to audio file"
def execute(path:)
AudioTranscriber.run(path) # pure computation, no shared mutable state
end
end
robot = RobotLab.build(
name: "transcriber",
system_prompt: "You transcribe audio files.",
local_tools: [TranscribeAudio]
)
result = robot.run("Transcribe /recordings/meeting.mp3")
puts result.last_text_content
Parallel Robot Networks
Pass parallel_mode: :ractor when creating a network to dispatch independent robots across hardware threads simultaneously:
network = RobotLab.create_network(name: "analysis", parallel_mode: :ractor) do
task :fetch, fetcher_robot, depends_on: :none
task :sentiment, sentiment_robot, depends_on: [:fetch]
task :entities, entity_robot, depends_on: [:fetch] # runs in parallel with :sentiment
task :summarize, summary_robot, depends_on: [:sentiment, :entities]
end
results = network.run(message: "Analyze customer feedback")
# => { "fetch" => "...", "sentiment" => "positive", "entities" => "...", "summarize" => "..." }
The scheduler builds a DAG from the depends_on: declarations and fires each stage as soon as its dependencies resolve.
Pool Management
# Pool is lazily created on first use
pool = RobotLab.ractor_pool
# Drain and shut down explicitly (e.g. at process exit)
RobotLab.shutdown_ractor_pool
Constraints
Because Ractors are isolated execution contexts that bypass Ruby's GVL, objects passed into them must be deeply frozen (no shared mutable state). The RactorBoundary utility handles this automatically for tool arguments. Your tool's execute method must not reference any unfrozen constants or class-level mutable state.
Links
License
MIT License - Copyright (c) 2025 Dewayne VanHoozer
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/MadBomber/robot_lab-ractor.