Module: RobotLab

Defined in:
lib/robot_lab.rb,
lib/robot_lab.rb,
lib/robot_lab/task.rb,
lib/robot_lab/tool.rb,
lib/robot_lab/error.rb,
lib/robot_lab/robot.rb,
lib/robot_lab/utils.rb,
lib/robot_lab/config.rb,
lib/robot_lab/memory.rb,
lib/robot_lab/waiter.rb,
lib/robot_lab/message.rb,
lib/robot_lab/network.rb,
lib/robot_lab/version.rb,
lib/robot_lab/ask_user.rb,
lib/robot_lab/bus_poller.rb,
lib/robot_lab/mcp/client.rb,
lib/robot_lab/mcp/server.rb,
lib/robot_lab/ractor_job.rb,
lib/robot_lab/run_config.rb,
lib/robot_lab/convergence.rb,
lib/robot_lab/state_proxy.rb,
lib/robot_lab/tool_config.rb,
lib/robot_lab/robot_result.rb,
lib/robot_lab/user_message.rb,
lib/robot_lab/memory_change.rb,
lib/robot_lab/robot_message.rb,
lib/robot_lab/text_analysis.rb,
lib/robot_lab/tool_manifest.rb,
lib/robot_lab/document_store.rb,
lib/robot_lab/ractor_boundary.rb,
lib/robot_lab/streaming/events.rb,
lib/robot_lab/delegation_future.rb,
lib/robot_lab/streaming/context.rb,
lib/robot_lab/history_compressor.rb,
lib/robot_lab/mcp/transports/sse.rb,
lib/robot_lab/ractor_worker_pool.rb,
lib/robot_lab/mcp/transports/base.rb,
lib/robot_lab/ractor_memory_proxy.rb,
lib/robot_lab/robot/bus_messaging.rb,
lib/robot_lab/mcp/server_discovery.rb,
lib/robot_lab/mcp/transports/stdio.rb,
lib/robot_lab/robot/history_search.rb,
lib/robot_lab/robot/mcp_management.rb,
lib/robot_lab/mcp/connection_poller.rb,
lib/robot_lab/mcp/transports/websocket.rb,
lib/robot_lab/ractor_network_scheduler.rb,
lib/robot_lab/rails_integration/engine.rb,
lib/robot_lab/robot/template_rendering.rb,
lib/robot_lab/rails_integration/railtie.rb,
lib/generators/robot_lab/robot_generator.rb,
lib/robot_lab/streaming/sequence_counter.rb,
lib/generators/robot_lab/install_generator.rb,
lib/robot_lab/mcp/transports/streamable_http.rb,
lib/robot_lab/rails_integration/turbo_stream_callbacks.rb

Overview

Define the module first so Zeitwerk can populate it

RobotLab is a Ruby framework for building and orchestrating multi-robot LLM workflows. It provides a modular architecture with adapters for multiple LLM providers (Anthropic, OpenAI, Gemini), MCP (Model Context Protocol) integration, streaming support, and history management.

Examples:

Basic usage with a single robot

robot = RobotLab.build(name: "assistant", template: "chat.erb")
result = robot.run("Hello, world!")

Creating a network of robots

network = RobotLab.create_network(name: "pipeline") do
  step :analyzer, analyzer, depends_on: :none
  step :writer, writer, depends_on: [:analyzer]
  step :reviewer, reviewer, depends_on: [:writer]
end
result = network.run(message: "Process this document")

Configuration

# Via environment variables (ROBOT_LAB_* prefix)
# ROBOT_LAB_DEFAULT_MODEL=gpt-4
# ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...

# Or via config files (~/.config/robot_lab/config.yml or ./config/robot_lab.yml)
# See lib/robot_lab/config/defaults.yml for all options

# Access configuration values:
RobotLab.config.ruby_llm.model            #=> "claude-sonnet-4"
RobotLab.config.ruby_llm.request_timeout  #=> 120

Defined Under Namespace

Modules: Convergence, Generators, MCP, RactorBoundary, RailsIntegration, Streaming, TextAnalysis, ToolConfig, Utils Classes: AskUser, AwaitTimeout, BusError, BusPoller, Config, ConfigurationError, DelegationFuture, DependencyError, DocumentStore, Error, HistoryCompressor, InferenceError, MCPError, Memory, MemoryChange, Message, Network, RactorBoundaryError, RactorJob, RactorJobError, RactorMemoryProxy, RactorNetworkScheduler, RactorWorkerPool, RedisBackend, Robot, RobotMessage, RobotResult, RobotSpec, RunConfig, StateProxy, Task, TextMessage, Tool, ToolCallMessage, ToolError, ToolLoopError, ToolManifest, ToolMessage, ToolNotFoundError, ToolResultMessage, UserMessage, Waiter

Constant Summary collapse

VERSION =
"0.0.11"

Class Method Summary collapse

Class Method Details

.build(name: "robot", template: nil, system_prompt: nil, context: {}, enable_cache: true, bus: nil, skills: nil, config: nil, **options) ⇒ Robot

Factory method to create a new Robot instance.

Examples:

Bare robot (no template or prompt)

robot = RobotLab.build
robot.with_instructions("You are helpful.").run("Hello!")

Robot with template

robot = RobotLab.build(
  name: "assistant",
  template: :assistant,
  context: { tone: "friendly" }
)

Robot with inline system prompt

robot = RobotLab.build(
  name: "helper",
  system_prompt: "You are a helpful assistant."
)

Parameters:

  • name (String, nil) (defaults to: "robot")

    the unique identifier for the robot (auto-generated if nil)

  • template (Symbol, nil) (defaults to: nil)

    the prompt_manager template for the robot’s prompt

  • system_prompt (String, nil) (defaults to: nil)

    inline system prompt (can be used alone or with template)

  • context (Hash) (defaults to: {})

    variables to pass to the template

  • enable_cache (Boolean) (defaults to: true)

    whether to enable semantic caching (default: true)

  • options (Hash)

    additional options passed to Robot.new

Returns:

  • (Robot)

    a new Robot instance



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/robot_lab.rb', line 156

def build(name: "robot", template: nil, system_prompt: nil, context: {}, enable_cache: true, bus: nil, skills: nil, config: nil, **options)
  Robot.new(
    name: name,
    template: template,
    system_prompt: system_prompt,
    context: context,
    enable_cache: enable_cache,
    bus: bus,
    skills: skills,
    config: config,
    **options
  )
end

.configConfig

Returns the Config object (MywayConfig-based).

Configuration is automatically loaded from:

  • Bundled defaults (lib/robot_lab/config/defaults.yml)

  • Environment-specific overrides (development, test, production)

  • XDG config files (~/.config/robot_lab/config.yml)

  • Project config (./config/robot_lab.yml)

  • Environment variables (ROBOT_LAB_*)

Examples:

RobotLab.config.ruby_llm.model            #=> "claude-sonnet-4"
RobotLab.config.ruby_llm.request_timeout  #=> 120
RobotLab.config.development?              #=> true

Returns:

  • (Config)

    the config instance



99
100
101
# File 'lib/robot_lab.rb', line 99

def config
  @config ||= Config.new.tap(&:after_load)
end

.configure {|Config| ... } ⇒ Config

Yields the Config object for block-style configuration.

Examples:

RobotLab.configure do |c|
  c.default_model = "claude-sonnet-4"
end

Yields:

  • (Config)

    the config instance

Returns:

  • (Config)

    the config instance



113
114
115
# File 'lib/robot_lab.rb', line 113

def configure
  yield config
end

.create_memory(data: {}, enable_cache: true, **options) ⇒ Memory

Factory method to create a new Memory object.

Examples:

Basic memory

memory = RobotLab.create_memory(data: { user_id: 123 })

Memory with custom values

memory = RobotLab.create_memory(data: { category: nil })
memory[:session_id] = "abc123"

Memory with caching disabled

memory = RobotLab.create_memory(data: {}, enable_cache: false)

Parameters:

  • data (Hash) (defaults to: {})

    initial runtime data

  • enable_cache (Boolean) (defaults to: true)

    whether to enable semantic caching (default: true)

  • options (Hash)

    additional options passed to Memory.new

Returns:

  • (Memory)

    a new Memory instance



219
220
221
# File 'lib/robot_lab.rb', line 219

def create_memory(data: {}, enable_cache: true, **options)
  Memory.new(data: data, enable_cache: enable_cache, **options)
end

.create_network(name:, concurrency: :auto, config: nil) { ... } ⇒ Network

Factory method to create a new Network of robots.

Examples:

Sequential pipeline

network = RobotLab.create_network(name: "pipeline") do
  step :first, robot1, depends_on: :none
  step :second, robot2, depends_on: [:first]
end

With optional routing

network = RobotLab.create_network(name: "support") do
  step :classifier, classifier, depends_on: :none
  step :billing, billing_robot, depends_on: :optional
  step :technical, technical_robot, depends_on: :optional
end

Parallel execution

network = RobotLab.create_network(name: "analysis") do
  step :fetch, fetcher, depends_on: :none
  step :sentiment, sentiment_bot, depends_on: [:fetch]
  step :entities, entity_bot, depends_on: [:fetch]
  step :merge, merger, depends_on: [:sentiment, :entities]
end

Parameters:

  • name (String)

    the unique identifier for the network

  • concurrency (Symbol) (defaults to: :auto)

    concurrency model (:auto, :threads, :async)

Yields:

  • Block for defining pipeline steps

Returns:

  • (Network)

    a new Network instance



198
199
200
# File 'lib/robot_lab.rb', line 198

def create_network(name:, concurrency: :auto, config: nil, &block)
  Network.new(name: name, concurrency: concurrency, config: config, &block)
end

.ractor_poolRactorWorkerPool

Returns the shared RactorWorkerPool, lazily initialized.

Pool size is determined by RobotLab.config.ractor_pool_size or defaults to Etc.nprocessors (:auto). The pool lives for the lifetime of the process. Call RobotLab.shutdown_ractor_pool to drain and close it explicitly.

Returns:



232
233
234
235
236
237
# File 'lib/robot_lab.rb', line 232

def ractor_pool
  @ractor_pool ||= begin
    size = config.respond_to?(:ractor_pool_size) ? (config.ractor_pool_size || :auto) : :auto
    RactorWorkerPool.new(size: size)
  end
end

.reload_config!Config

Reload configuration from all sources.

Clears the cached Config instance, forcing it to be reloaded on next access.

Returns:

  • (Config)

    the new config instance



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

def reload_config!
  @config = nil
  config
end

.shutdown_ractor_poolvoid

This method returns an undefined value.

Shut down the shared Ractor worker pool, draining in-flight jobs.



242
243
244
245
# File 'lib/robot_lab.rb', line 242

def shutdown_ractor_pool
  @ractor_pool&.shutdown
  @ractor_pool = nil
end