Module: RobotLab

Defined in:
lib/robot_lab.rb,
lib/robot_lab.rb,
lib/robot_lab/hook.rb,
lib/robot_lab/task.rb,
lib/robot_lab/tool.rb,
lib/robot_lab/error.rb,
lib/robot_lab/hooks.rb,
lib/robot_lab/names.rb,
lib/robot_lab/robot.rb,
lib/robot_lab/utils.rb,
lib/robot_lab/config.rb,
lib/robot_lab/errors.rb,
lib/robot_lab/memory.rb,
lib/robot_lab/waiter.rb,
lib/robot_lab/message.rb,
lib/robot_lab/network.rb,
lib/robot_lab/sandbox.rb,
lib/robot_lab/version.rb,
lib/robot_lab/ask_user.rb,
lib/robot_lab/narrator.rb,
lib/robot_lab/runnable.rb,
lib/robot_lab/bus_poller.rb,
lib/robot_lab/mcp/client.rb,
lib/robot_lab/mcp/server.rb,
lib/robot_lab/run_config.rb,
lib/robot_lab/agent_skill.rb,
lib/robot_lab/convergence.rb,
lib/robot_lab/script_tool.rb,
lib/robot_lab/state_proxy.rb,
lib/robot_lab/tool_config.rb,
lib/robot_lab/capabilities.rb,
lib/robot_lab/hook_context.rb,
lib/robot_lab/robot/budget.rb,
lib/robot_lab/robot_result.rb,
lib/robot_lab/sandbox/null.rb,
lib/robot_lab/user_message.rb,
lib/robot_lab/budget/ledger.rb,
lib/robot_lab/hook_registry.rb,
lib/robot_lab/memory_change.rb,
lib/robot_lab/robot/hooking.rb,
lib/robot_lab/robot_message.rb,
lib/robot_lab/text_analysis.rb,
lib/robot_lab/tool_manifest.rb,
lib/robot_lab/sandbox/seatbelt.rb,
lib/robot_lab/streaming/events.rb,
lib/robot_lab/delegation_future.rb,
lib/robot_lab/streaming/context.rb,
lib/robot_lab/doom_loop_detector.rb,
lib/robot_lab/history_compressor.rb,
lib/robot_lab/mcp/transports/sse.rb,
lib/robot_lab/agent_skill_catalog.rb,
lib/robot_lab/mcp/transports/base.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/robot/template_rendering.rb,
lib/robot_lab/robot/agent_skill_matching.rb,
lib/robot_lab/streaming/sequence_counter.rb,
lib/robot_lab/mcp/transports/streamable_http.rb,
sig/robot_lab.rbs

Overview

A large curated word list, not application logic — kept as one inline module for lookup speed, so the size/length cops below are false positives. rubocop:disable Metrics/ModuleLength

Defined Under Namespace

Modules: Budget, Convergence, Errors, Hooks, MCP, Runnable, Sandbox, ScriptTool, Streaming, TextAnalysis, ToolConfig, Utils Classes: AgentSkill, AgentSkillCatalog, AskUser, AwaitTimeout, BudgetExceeded, BusError, BusPoller, Capabilities, CompactionHookContext, Config, ConfigurationError, DelegationFuture, DependencyError, DoomLoopDetector, DotState, Error, ExtensionState, HistoryCompressor, Hook, HookContext, HookRegistry, InferenceError, LearnHookContext, LlmGenerationHookContext, MCPError, Memory, MemoryChange, Message, Narrator, Network, NetworkRunHookContext, RactorBoundaryError, RedisBackend, Robot, RobotMessage, RobotResult, RunConfig, RunHookContext, StateProxy, Task, TaskHookContext, TextMessage, Tool, ToolCallHookContext, ToolCallMessage, ToolError, ToolLoopError, ToolManifest, ToolMessage, ToolNotFoundError, ToolResultMessage, UserMessage, Waiter

Constant Summary collapse

NAMES =

Fictional robot names rubocop:disable Metrics/CollectionLiteralLength

%w[
  R_7723
  R_790
  AXL
  Adam
  Adam_Link
  Alfie
  Alojzy_Kukuryk
  Alpha_5
  Alpha_6
  Alsatia_Zevo
  AMEE
  Ancient_Ore_Crusher
  Andrew
  Andrew_Martin
  Andromon
  Aniel
  Aqua
  Arbeitsmaschine
  Arthur
  Artificial_Friend
  Ash
  Astor
  Astro_Boy
  Athena
  Atmophytes
  AUTO
  Ava
  B_4
  BATs
  BEN
  BOB
  B166ER
  Baymax
  BB
  BB_8
  Becker
  Bender
  Bénédict_Masson
  Bennie
  Beta
  Beta_Machine
  Billybot
  Bishop
  Black_Beauty
  Blue_Senturion
  Boilerplate
  Boppers
  Bors
  Box
  Brackenridge
  Brainbots
  BRL_A
  Bruno
  Bubo
  Buffybot
  BURN_E
  Byron
  C_3PO
  CHOMPS
  Calculon
  Caliban
  Call
  Cambot
  Candy_Droober
  Carl
  Casandra_Kresnov
  CASE
  Cassandra_One
  Chani
  CHAPPiE
  Charlie
  Cherry_2000
  Chip
  CHIP
  Chitti
  Chuck_the_Robot
  Chucky
  Chumblies
  Claire
  Clamps
  Clunk
  Coconuts
  Coldfire
  Coldstone
  Colossus
  Conky_2000
  Coppélia
  Coyote
  Crimson
  Crow_T_Robot
  Cutie
  Cybots
  Cylons
  D_FIB
  DARYL
  Damon
  Data
  David
  David_8
  Dee_Model
  Dewey
  DOR_15
  Dorfl
  Dot_Matrix
  DV_8
  ED_209
  EDI
  Elio
  Elle
  Emma_2
  Enforcer_Drone
  Engimals
  EVAs
  Eve
  EVE
  Evolver
  Ez_27
  false_Maria
  Fembots
  Flexo
  Frank_Saunders
  Franklin_Droober
  Freya
  Freysa
  Frost
  G2
  Galaxina
  GERTY_3000
  Giant_Robot
  Giddy
  Gigantor
  Gnut
  GO_4
  Goddard
  Gog
  Gort
  Gort
  Gris
  Grounder
  Guardromon
  Gypsy
  Hadaly
  HAN_S
  Haro
  HCR_328
  Hector
  Helen_OLoy
  Helena
  Hermes
  Huey
  Hymie
  Ilia
  Intergalactic_Advocate_Bob
  Jaegers
  Janice_Em
  Jay_Score
  Jay_Dub
  Jenkins
  Jenny_Wakeman
  Jessica
  Jet
  Jet_Jaguar
  Jinx
  Johnny_5
  Johnny_Cab
  Juliana_Tainer
  K
  K_2SO
  K9
  Kampfmaschin
  KARR
  Kay_Em_14
  Kei
  Kikaider
  Killbots
  Kirby
  Kit
  KITT
  Klapaucius
  Kronos
  Kryten
  Kwanzaa_Bot
  Kyoko
  L_76
  L3_37
  Lal
  Lenny
  Leon_Kowalski
  Lomax
  Lore
  Louie
  Luv
  M_O
  M3GAN
  Mac
  Magog
  Mami
  Manders
  Mandroid
  Marcus_Wright
  Maria
  Mariette
  Marius
  Mark_1
  MARK13
  Marvin
  Mary_25
  Maschinenmensch
  Mata_Nui
  Maureen_Droober
  MAX
  Max_404
  Maximillian
  May
  MD_63
  Mech_Eagles
  Mecha_King_Ghidorah
  Mechagodzilla
  Mechagodzilla
  Mechani_Kong
  Mechano
  Mechonoids
  Mec_Willy
  Melfina
  Merlin_Athrawes
  Micro_Managers
  MM7
  Moguera
  MOOSE
  Moravecs
  Mordel
  Morgan
  Mr_Split
  Mr_Static
  Muranian
  Necron_99
  Neotnia
  Newman
  Nimani
  Nimue_Alban
  Norby
  NS4
  Okra
  Olimpia
  Oliver
  Olympia
  Omega
  Omnidroid
  Otis
  POPS
  Paws
  Peace
  Phatasaur
  Phil
  Pino_Petto
  PR_T
  Primus
  Pris
  Project_2501
  Proteus_IV
  Quinn
  R_Daneel_Olivaw
  R_Giskard_Reventlov
  RALF
  ROTOR
  R2_D2
  R4_P17
  Rabbot
  Rachael
  Radius
  Rena
  Replicators
  Rex
  RIA
  Richard_Daniel
  Rick_Deckard
  Ro_Man_Extension_XJ_2
  Rob_Monkey
  Robbie
  Robby
  Robo
  Robo_Clowns
  RoboDoc
  RoboGadget
  Robot_7
  Robot_B_9
  Robot_Devil
  Robot_Santa
  Robot_ZX29B
  Robotoid
  Roderick
  Rosie
  Roy_Batty
  Roz
  ROZZUM_unit_7134
  SAR_003
  S1MONE
  Samantha
  Sapper_Morton
  Sara
  Scratch
  Sentinels
  Setaur
  Sheen
  Sheriff_Not_a_Robot
  SHROUD
  SI_9
  Sico
  SID_67
  SIMON
  Skutters
  Solo
  Sonny
  Sox
  Sparks
  Speedy
  Spofforth
  Spot
  Stitchpunks
  Sulla
  T_1000
  T_600
  T_800
  T_850
  T_Bob
  T_X
  Talkie_Toaster
  TARS
  Terminus
  Tet
  The_Automaton
  The_Cast_Iron_Man
  The_Electric_Grandmother
  The_Fury
  The_Golden_Army
  The_Gunslinger
  The_Hangman
  The_Iron_Giant
  The_Iron_Man
  The_Juggernaut
  The_Mechanical_Cow
  The_Mechanical_Dummy
  The_Mechanical_Horse
  The_Mechanical_Hound
  The_One_Who_Waits
  Tin_Man
  Tik_Tok
  Tilk
  Tilly
  Tima
  Toaster
  Tobor
  Tom
  Tom_Servo
  Tony
  Torg
  Trace_Mayter
  Trurl
  Twonky
  Ultron
  Ulyssses
  UniBlab
  US_47
  VINCENT
  Vahki
  Val
  Valerie_23
  Vanessa_Kensington
  VAQ_M
  Victor
  Vision
  VN_GO
  Voltron
  WALL_E
  Walter_One
  Weebo
  Wilmer
  XJ_9
  Yod
  Z_1
  Z_2
  Z_3
  Zane_Gort
  Zat
  Zhora
  Zoromes
].freeze
VERSION =

Returns:

  • (String)
"0.2.7"

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) ⇒ 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



236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/robot_lab.rb', line 236

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

.clear_hooks!Object



130
131
132
# File 'lib/robot_lab.rb', line 130

def clear_hooks!
  @hooks = HookRegistry.new
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 file (~/.config/robot_lab/robot_lab.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



164
165
166
# File 'lib/robot_lab.rb', line 164

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



177
178
179
# File 'lib/robot_lab.rb', line 177

def configure
  yield config
end

.create_memory(data: {}, enable_cache: true) ⇒ 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



298
299
300
# File 'lib/robot_lab.rb', line 298

def create_memory(data: {}, enable_cache: true, **)
  Memory.new(data: data, enable_cache: enable_cache, **)
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
  task :first, robot1, depends_on: :none
  task :second, robot2, depends_on: [:first]
end

With optional routing

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

Parallel execution

network = RobotLab.create_network(name: "analysis") do
  task :fetch, fetcher, depends_on: :none
  task :sentiment, sentiment_bot, depends_on: [:fetch]
  task :entities, entity_bot, depends_on: [:fetch]
  task :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 tasks (the DSL method is task)

Returns:

  • (Network)

    a new Network instance



278
279
280
# File 'lib/robot_lab.rb', line 278

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

.current_hook_scopeObject



145
146
147
# File 'lib/robot_lab.rb', line 145

def current_hook_scope
  Thread.current[:robot_lab_hook_scope]
end

.extension(name) ⇒ Object

Returns the module registered for the named extension, or nil.

Parameters:

  • name (Symbol)

    extension identifier



111
112
113
# File 'lib/robot_lab.rb', line 111

def extension(name)
  @extensions[name]
end

.extension_loaded?(name) ⇒ Boolean

Returns true if the named extension gem has been loaded.

Parameters:

  • name (Symbol)

    extension identifier

Returns:

  • (Boolean)


104
105
106
# File 'lib/robot_lab.rb', line 104

def extension_loaded?(name)
  @extensions.key?(name)
end

.hooksObject



122
123
124
# File 'lib/robot_lab.rb', line 122

def hooks
  @hooks ||= HookRegistry.new
end

.loaded_extensionsArray<Symbol>

Returns the list of registered extension names.

Returns:

  • (Array<Symbol>)


118
119
120
# File 'lib/robot_lab.rb', line 118

def loaded_extensions
  @extensions.keys
end

.nameObject

rubocop:enable Metrics/CollectionLiteralLength



399
# File 'lib/robot_lab/names.rb', line 399

def self.name = names.first

.names(how_many = 1) ⇒ Object



400
# File 'lib/robot_lab/names.rb', line 400

def self.names(how_many = 1) = NAMES.sample(how_many).sort

.on(handler_class, context: nil) ⇒ Object



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

def on(handler_class, context: nil)
  hooks.on(handler_class, context: context)
end

.register_extension(name, mod) ⇒ Object

Registers an extension gem so core can detect it without depending on it.

Extension gems call this at load time to announce themselves. Core uses extension_loaded? to guard optional behavior instead of defined?/respond_to?.

Parameters:

  • name (Symbol)

    identifier for the extension (e.g. :durable, :ractor)

  • mod (Module, Object)

    the extension's primary module or a sentinel value



97
98
99
# File 'lib/robot_lab.rb', line 97

def register_extension(name, mod)
  @extensions[name] = mod
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



187
188
189
190
# File 'lib/robot_lab.rb', line 187

def reload_config!
  @config = nil
  config
end

.render_template(name, **context) ⇒ String

Render a named prompt template to a String using the configured template library (the prompts_dir from config / ROBOT_LAB_TEMPLATE_PATH). Front matter parameters are supplied as keyword arguments.

Unlike #build (which renders a template as a robot's system prompt), this returns the plain text, so callers can use it as a task, a message, or a grading rubric.

Examples:

RobotLab.render_template(:objective, topic: "commit messages")

Parameters:

  • name (Symbol, String)

    template id (filename without extension)

  • context (Hash)

    values for the template's parameters

Returns:

  • (String)

    the rendered prompt text



206
207
208
# File 'lib/robot_lab.rb', line 206

def render_template(name, **context)
  PM.parse(name.to_sym).to_s(**context)
end

.with_hook_scope(registries, per_run_hooks) ⇒ Object



134
135
136
137
138
139
140
141
142
143
# File 'lib/robot_lab.rb', line 134

def with_hook_scope(registries, per_run_hooks)
  previous = Thread.current[:robot_lab_hook_scope]
  Thread.current[:robot_lab_hook_scope] = {
    registries: registries,
    per_run_hooks: per_run_hooks
  }
  yield
ensure
  Thread.current[:robot_lab_hook_scope] = previous
end