Class: RobotLab::Robot

Inherits:
RubyLLM::Agent
  • Object
show all
Includes:
Robot::AgentSkillMatching, Robot::Budget, Robot::BusMessaging, Robot::HistorySearch, Robot::Hooking, Robot::MCPManagement, Robot::TemplateRendering, Runnable
Defined in:
lib/robot_lab/robot.rb,
lib/robot_lab/robot/budget.rb,
lib/robot_lab/robot/hooking.rb,
lib/robot_lab/robot/bus_messaging.rb,
lib/robot_lab/robot/history_search.rb,
lib/robot_lab/robot/mcp_management.rb,
lib/robot_lab/robot/template_rendering.rb,
lib/robot_lab/robot/agent_skill_matching.rb

Overview

LLM-powered robot built on RubyLLM::Agent

Robot is a subclass of RubyLLM::Agent that adds:

  • Template-based prompts via prompt_manager
  • Shared memory (standalone or network)
  • Tool integration with hierarchical MCP configuration
  • SimpleFlow pipeline integration

Memory Behavior

Standalone: Robot uses its own inherent memory (robot.memory). In a Network: Robot uses the network's shared memory.

Examples:

Simple robot with template

robot = Robot.new(name: "helper", template: :helper)
result = robot.run("Hello!")

Robot with inline system prompt

robot = Robot.new(name: "bot", system_prompt: "You are helpful.")
result = robot.run("What is 2+2?")

Bare robot configured via chaining

robot = Robot.new(name: "bot")
robot.with_instructions("Be concise.").run("Hello")

Robot with tools

robot = Robot.new(
  name: "support",
  template: :support,
  local_tools: [OrderLookup, RefundProcessor]
)

Defined Under Namespace

Modules: AgentSkillMatching, Budget, BusMessaging, HistorySearch, Hooking, MCPManagement, TemplateRendering

Constant Summary collapse

DEFAULT_MAX_TOOLS =

Default ceiling on tools handed to the provider per turn. OpenAI and Anthropic both reject tool arrays longer than 128. Override per robot via RunConfig#max_tools.

128

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Runnable

#chief, #network?, #robot_count, #single?

Constructor Details

#initialize(name:, template: nil, system_prompt: nil, context: {}, description: nil, local_tools: [], model: nil, provider: nil, mcp_servers: [], mcp: :none, tools: :none, on_tool_call: nil, on_tool_result: nil, on_content: nil, enable_cache: true, bus: nil, skills: nil, temperature: nil, top_p: nil, top_k: nil, max_tokens: nil, presence_penalty: nil, frequency_penalty: nil, stop: nil, max_tool_rounds: nil, token_budget: nil, cost_budget: nil, doom_loop_threshold: nil, mcp_discovery: false, config: nil) ⇒ Robot

Creates a new Robot instance.

Parameters:

  • name (String)

    the unique identifier for the robot

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

    the prompt_manager template

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

    inline system prompt

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

    variables to pass to the template

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

    optional description

  • local_tools (Array) (defaults to: [])

    tools defined locally

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

    the LLM model to use

  • mcp_servers (Array) (defaults to: [])

    legacy parameter for MCP server configurations

  • mcp (Symbol, Array) (defaults to: :none)

    hierarchical MCP config

  • tools (Symbol, Array) (defaults to: :none)

    hierarchical tools config

  • on_tool_call (Proc, nil) (defaults to: nil)

    callback invoked when a tool is called

  • on_tool_result (Proc, nil) (defaults to: nil)

    callback invoked when a tool returns a result

  • on_content (Proc, nil) (defaults to: nil)

    callback invoked with each streaming content chunk

  • enable_cache (Boolean) (defaults to: true)

    whether to enable semantic caching

  • bus (TypedBus::MessageBus, nil) (defaults to: nil)

    optional message bus for inter-robot communication

  • temperature (Float, nil) (defaults to: nil)

    controls randomness

  • top_p (Float, nil) (defaults to: nil)

    nucleus sampling threshold

  • top_k (Integer, nil) (defaults to: nil)

    top-k sampling

  • max_tokens (Integer, nil) (defaults to: nil)

    maximum tokens in response

  • presence_penalty (Float, nil) (defaults to: nil)

    penalize based on presence

  • frequency_penalty (Float, nil) (defaults to: nil)

    penalize based on frequency

  • stop (String, Array, nil) (defaults to: nil)

    stop sequences

  • skills (Symbol, Array<Symbol>, nil) (defaults to: nil)

    skill templates to prepend

  • config (RunConfig, nil) (defaults to: nil)

    shared configuration (merged with explicit kwargs)



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/robot_lab/robot.rb', line 158

def initialize(
  name:,
  template: nil,
  system_prompt: nil,
  context: {},
  description: nil,
  local_tools: [],
  model: nil,
  provider: nil,
  mcp_servers: [],
  mcp: :none,
  tools: :none,
  on_tool_call: nil,
  on_tool_result: nil,
  on_content: nil,
  enable_cache: true,
  bus: nil,
  skills: nil,
  temperature: nil,
  top_p: nil,
  top_k: nil,
  max_tokens: nil,
  presence_penalty: nil,
  frequency_penalty: nil,
  stop: nil,
  max_tool_rounds: nil,
  token_budget: nil,
  cost_budget: nil,
  doom_loop_threshold: nil,
  mcp_discovery: false,
  config: nil
)
  validate_tools_filter!(tools)

  assign_identity_ivars(name: name, template: template, system_prompt: system_prompt,
                        context: context, description: description, local_tools: local_tools,
                        skills: skills, mcp_discovery: mcp_discovery)

  build_effective_config(
    model: model, temperature: temperature, top_p: top_p, top_k: top_k,
    max_tokens: max_tokens, presence_penalty: presence_penalty,
    frequency_penalty: frequency_penalty, stop: stop,
    on_tool_call: on_tool_call, on_tool_result: on_tool_result,
    on_content: on_content, bus: bus, enable_cache: enable_cache,
    max_tool_rounds: max_tool_rounds, token_budget: token_budget, cost_budget: cost_budget,
    doom_loop_threshold: doom_loop_threshold, mcp_servers: mcp_servers,
    mcp: mcp, tools: tools, config: config
  )

  extract_config_ivars
  initialize_runtime_state
  initialize_memory

  lab_config = RobotLab.config
  resolved_model = @config.model || lab_config.ruby_llm.model
  chat_kwargs   = { model: resolved_model }

  # RubyLLM auto-sets assume_model_exists for local providers when provider is specified.
  @provider = provider
  if @provider
    chat_kwargs[:provider] = @provider
    chat_kwargs[:assume_model_exists] = true
  end

  super(chat: nil, **chat_kwargs)

  apply_template
  apply_system_prompt
  apply_chat_params
  register_chat_callbacks
end

Instance Attribute Details

#budget_ledgerObject (readonly)

Returns the value of attribute budget_ledger.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def budget_ledger
  @budget_ledger
end

#busObject (readonly)

Returns the value of attribute bus.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def bus
  @bus
end

#configObject (readonly)

Returns the value of attribute config.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def config
  @config
end

#descriptionString? (readonly)

Returns an optional description of the robot's purpose.

Returns:

  • (String, nil)

    an optional description of the robot's purpose



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#hooksObject (readonly)

Returns the value of attribute hooks.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def hooks
  @hooks
end

#inputIO

Returns input stream for user interaction (default: $stdin).

Returns:

  • (IO)

    input stream for user interaction (default: $stdin)



79
80
81
# File 'lib/robot_lab/robot.rb', line 79

def input
  @input
end

#learningsObject (readonly)

Returns the value of attribute learnings.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def learnings
  @learnings
end

#local_toolsArray (readonly)

Returns the locally defined tools for this robot.

Returns:

  • (Array)

    the locally defined tools for this robot



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#mcp_clientsHash<String, MCP::Client> (readonly)

Returns connected MCP clients by server name.

Returns:

  • (Hash<String, MCP::Client>)

    connected MCP clients by server name



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#mcp_configSymbol, Array (readonly)

Returns build-time MCP configuration (raw, unresolved).

Returns:

  • (Symbol, Array)

    build-time MCP configuration (raw, unresolved)



91
92
93
# File 'lib/robot_lab/robot.rb', line 91

def mcp_config
  @mcp_config
end

#mcp_toolsArray<Tool> (readonly)

Returns tools discovered from MCP servers.

Returns:

  • (Array<Tool>)

    tools discovered from MCP servers



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#memoryMemory (readonly)

Returns the robot's inherent memory (used when standalone, not in network).

Returns:

  • (Memory)

    the robot's inherent memory (used when standalone, not in network)



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#nameString (readonly)

Returns the unique identifier for the robot.

Returns:

  • (String)

    the unique identifier for the robot



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#outboxObject (readonly)

Returns the value of attribute outbox.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def outbox
  @outbox
end

#outputIO

Returns output stream for user interaction (default: $stdout).

Returns:

  • (IO)

    output stream for user interaction (default: $stdout)



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#providerObject (readonly)

Returns the value of attribute provider.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def provider
  @provider
end

#skillsObject (readonly)

Returns the value of attribute skills.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def skills
  @skills
end

#system_promptString? (readonly)

Returns inline system prompt (used alone or appended to template).

Returns:

  • (String, nil)

    inline system prompt (used alone or appended to template)



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#templateSymbol? (readonly)

Returns the prompt_manager template for the robot's prompt.

Returns:

  • (Symbol, nil)

    the prompt_manager template for the robot's prompt



79
# File 'lib/robot_lab/robot.rb', line 79

attr_accessor :input, :output

#tools_configObject (readonly)

Returns the value of attribute tools_config.



91
# File 'lib/robot_lab/robot.rb', line 91

attr_reader :mcp_config, :tools_config

#total_input_tokensObject (readonly)

Returns the value of attribute total_input_tokens.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def total_input_tokens
  @total_input_tokens
end

#total_output_tokensObject (readonly)

Returns the value of attribute total_output_tokens.



81
82
83
# File 'lib/robot_lab/robot.rb', line 81

def total_output_tokens
  @total_output_tokens
end

Instance Method Details

#call(result) ⇒ SimpleFlow::Result

SimpleFlow step interface

Parameters:

  • result (SimpleFlow::Result)

    incoming result from previous step

Returns:

  • (SimpleFlow::Result)

    result with robot output



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/robot_lab/robot.rb', line 271

def call(result)
  run_context = extract_run_context(result)

  # Extract the message from run context
  message = run_context.delete(:message)

  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  robot_result = run(message, **run_context)
  robot_result.duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time

  result
    .with_context(@name.to_sym, robot_result)
    .continue(robot_result)
rescue Exception => e # rubocop:disable Lint/RescueException
  # Catch all errors (including SecurityError, Timeout::Error, etc.)
  # so one failing robot doesn't crash the entire network pipeline.
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
  error_result = RobotResult.new(
    robot_name: @name,
    output: [TextMessage.new(role: 'assistant', content: "Error: #{e.class}: #{e.message}")]
  )
  error_result.duration = elapsed

  result
    .with_context(@name.to_sym, error_result)
    .continue(error_result)
end

#chatRubyLLM::Chat

Access the underlying RubyLLM::Chat instance. Useful for checkpoint/restore operations that need direct access to conversation state.

Returns:

  • (RubyLLM::Chat)


357
358
359
# File 'lib/robot_lab/robot.rb', line 357

def chat
  @chat
end

#chat_providerString?

Return the provider for this robot's chat. Useful for displaying model/provider info without reaching into chat internals.

Returns:

  • (String, nil)


481
482
483
484
485
486
# File 'lib/robot_lab/robot.rb', line 481

def chat_provider
  m = @chat.model
  m.respond_to?(:provider) ? m.provider : nil
rescue StandardError
  nil
end

#clear_messages(keep_system: true) ⇒ self

Clear conversation messages, optionally keeping the system prompt.

Parameters:

  • keep_system (Boolean) (defaults to: true)

    whether to preserve the system message

Returns:

  • (self)


372
373
374
375
376
377
378
379
380
381
# File 'lib/robot_lab/robot.rb', line 372

def clear_messages(keep_system: true)
  if keep_system
    system_msg = @chat.messages.find { |m| m.role == :system }
    @chat.reset_messages!
    @chat.add_message(system_msg) if system_msg
  else
    @chat.reset_messages!
  end
  self
end

#compress_history(recent_turns: 3, keep_threshold: 0.6, drop_threshold: 0.2, summarizer: nil) ⇒ self

Compress conversation history using TF-IDF relevance scoring.

Old turns are tiered against the most recent context:

  • High relevance (score >= keep_threshold) → kept verbatim
  • Medium relevance (drop_threshold..keep_threshold) → summarized or dropped
  • Low relevance (score < drop_threshold) → dropped

System messages and tool call/result messages are always preserved. The most recent recent_turns pairs are also always kept verbatim.

Requires the optional 'classifier' gem (~> 2.3). Raises DependencyError if not installed.

Parameters:

  • recent_turns (Integer) (defaults to: 3)

    turn pairs to protect at the end (default 3)

  • keep_threshold (Float) (defaults to: 0.6)

    cosine score >= this → keep verbatim (default 0.6)

  • drop_threshold (Float) (defaults to: 0.2)

    cosine score < this → drop (default 0.2)

  • summarizer (#call, nil) (defaults to: nil)

    callable(text) -> String for medium-tier; nil drops medium-tier instead of summarizing

Returns:

  • (self)


412
413
414
415
416
417
418
419
420
421
# File 'lib/robot_lab/robot.rb', line 412

def compress_history(recent_turns: 3, keep_threshold: 0.6, drop_threshold: 0.2, summarizer: nil)
  compressed = HistoryCompressor.new(
    messages:       @chat.messages,
    recent_turns:   recent_turns,
    keep_threshold: keep_threshold,
    drop_threshold: drop_threshold,
    summarizer:     summarizer
  ).call
  replace_messages(compressed)
end

#connect_mcp!self

Eagerly connect to configured MCP servers and discover tools. Normally MCP connections are lazy (established on first run). Call this to connect early, e.g. to display connection status at startup.

Returns:

  • (self)


312
313
314
315
316
# File 'lib/robot_lab/robot.rb', line 312

def connect_mcp!
  resolved_mcp = resolve_mcp_hierarchy(@mcp_config)
  ensure_mcp_clients(resolved_mcp) if resolved_mcp.is_a?(Array) && resolved_mcp.any?
  self
end

#crewArray<Robot>

Runnable protocol: a single robot is a crew of one. (network? defaults to false from RobotLab::Runnable.)

Returns:



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

def crew
  [self]
end

#delegate(to:, task:, async: false) ⇒ RobotResult, DelegationFuture

Delegate a task to another robot, synchronously or asynchronously.

Synchronous (default, async: false): blocks until the delegatee finishes and returns a RobotResult annotated with delegated_by, duration, and token counts.

Asynchronous (+async: true+): starts the delegatee in a background thread and returns a DelegationFuture immediately. Call future.value to block for the result, or future.resolved? to poll.

Examples:

Synchronous

result = manager.delegate(to: analyst, task: "What are the risks?")
puts result.reply          # analyst's answer
puts result.delegated_by   # => "manager"
puts result.duration       # => 1.43 (seconds)

Async fan-out

f1 = manager.delegate(to: summarizer, task: "summarize ...", async: true)
f2 = manager.delegate(to: analyst,    task: "analyze ...",   async: true)
summary  = f1.value          # blocks if not yet done
analysis = f2.value(timeout: 30)

Parameters:

  • to (Robot)

    the robot to delegate to

  • task (String)

    the message to send

  • async (Boolean) (defaults to: false)

    when true, returns a DelegationFuture immediately

  • kwargs (Hash)

    additional keyword args forwarded to Robot#run

Returns:



451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/robot_lab/robot.rb', line 451

def delegate(to:, task:, async: false, **)
  if async
    future = DelegationFuture.new(robot_name: to.name, delegated_by: @name)
    delegator_name = @name

    Thread.new do
      started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      result = to.run(task, **)
      result.duration     = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at
      result.delegated_by = delegator_name
      future.resolve!(result)
    rescue => e
      future.reject!(e)
    end

    future
  else
    started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    result = to.run(task, **)
    result.duration     = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at
    result.delegated_by = @name
    result
  end
end

#disconnectself

Disconnect all MCP clients and bus channel.

Returns:

  • (self)


330
331
332
333
334
# File 'lib/robot_lab/robot.rb', line 330

def disconnect
  @mcp_clients.each_value(&:disconnect)
  teardown_bus_channel if @bus
  self
end

#effective_configHash

Returns the fully-merged configuration for this robot at runtime.

Reflects the result of merging the RunConfig hierarchy (global → network → constructor kwargs → template front matter). Nil fields are omitted.

Examples:

robot.effective_config
#=> { model: "claude-sonnet-4-6", temperature: 0.7, max_tokens: 4096 }

Returns:

  • (Hash)

    merged config keyed by field name



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/robot_lab/robot.rb', line 111

def effective_config
  {
    model:               @config.model,
    temperature:         @config.temperature,
    top_p:               @config.top_p,
    top_k:               @config.top_k,
    max_tokens:          @config.max_tokens,
    presence_penalty:    @config.presence_penalty,
    frequency_penalty:   @config.frequency_penalty,
    stop:                @config.stop,
    tools:               @config.tools,
    mcp:                 @config.mcp,
    max_tool_rounds:     @config.max_tool_rounds,
    doom_loop_threshold: @config.doom_loop_threshold,
    auto_compact:        @config.auto_compact,
    compact_threshold:   @config.compact_threshold,
    token_budget:        @config.token_budget,
    cost_budget:         @config.cost_budget
  }.compact
end

#failed_mcp_server_namesArray<String>

Returns server names that failed to connect.

Returns:

  • (Array<String>)


321
322
323
324
325
# File 'lib/robot_lab/robot.rb', line 321

def failed_mcp_server_names
  return [] unless @failed_mcp_configs

  @failed_mcp_configs.keys
end

#inject_mcp!(clients:, tools:) ⇒ self

Inject pre-connected MCP clients and their tools into this robot. Used by host applications (e.g. AIA) that manage MCP connections externally and need to pass them to robots without re-connecting.

Parameters:

  • clients (Hash<String, MCP::Client>)

    connected MCP clients by server name

  • tools (Array<Tool>)

    tools discovered from the MCP servers

Returns:

  • (self)


345
346
347
348
349
350
# File 'lib/robot_lab/robot.rb', line 345

def inject_mcp!(clients:, tools:)
  @mcp_clients = clients
  @mcp_tools = tools
  @mcp_initialized = true
  self
end

#learn(text) ⇒ self

Add a learning to this robot's accumulation store.

Deduplicates by bidirectional substring matching: a new learning is skipped if it is already contained within an existing learning, or an existing learning is contained within the new one (the new one wins and replaces the weaker entry).

Learnings are persisted to the robot's inherent memory under :learnings.

Parameters:

  • text (String)

    the insight to record

Returns:

  • (self)


507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'lib/robot_lab/robot.rb', line 507

def learn(text)
  text = text.to_s.strip
  return self if text.empty?

  ctx        = LearnHookContext.new(robot: self, text: text, learnings_before: @learnings.dup)
  registries = [RobotLab.hooks, @hooks]

  RobotLab::Hooks.run(:learn, ctx, registries: registries) do
    @learnings.reject! { |existing| text.include?(existing) }

    unless @learnings.any? { |existing| existing.include?(text) }
      @learnings << text
      @memory.set(:learnings, @learnings.dup)
      ctx.stored = true
    end

    RobotLab::Hooks.call(:on_learn, ctx, registries: registries)
  end

  self
end

#mcp_client(server_name) ⇒ MCP::Client?

Find an MCP client by server name.

Parameters:

  • server_name (String)

    the MCP server name

Returns:



492
493
494
# File 'lib/robot_lab/robot.rb', line 492

def mcp_client(server_name)
  @mcp_clients[server_name]
end

#messagesArray<RubyLLM::Message>

Return the conversation messages from the underlying chat.

Returns:

  • (Array<RubyLLM::Message>)


364
365
366
# File 'lib/robot_lab/robot.rb', line 364

def messages
  @chat.messages
end

#modelString?

Returns the model identifier

Returns:

  • (String, nil)

    the LLM model ID string



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

def model
  return nil unless @chat.respond_to?(:model)

  m = @chat.model
  m.respond_to?(:id) ? m.id : m.to_s
end

#replace_messages(messages) ⇒ self

Replace conversation messages with a saved set (for checkpoint restore).

Parameters:

  • messages (Array<RubyLLM::Message>)

    the messages to restore

Returns:

  • (self)


387
388
389
390
391
# File 'lib/robot_lab/robot.rb', line 387

def replace_messages(messages)
  @chat.reset_messages!
  messages.each { |m| @chat.add_message(m) }
  self
end

#reset_memoryself

Reset the robot's inherent memory

Returns:

  • (self)


302
303
304
305
# File 'lib/robot_lab/robot.rb', line 302

def reset_memory
  @memory.reset
  self
end

#reset_token_totalsself

Reset cumulative token counters to zero.

Returns:

  • (self)


532
533
534
535
536
# File 'lib/robot_lab/robot.rb', line 532

def reset_token_totals
  @total_input_tokens = 0
  @total_output_tokens = 0
  self
end

#to_hHash

Converts the robot to a hash representation

Returns:

  • (Hash)


541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'lib/robot_lab/robot.rb', line 541

def to_h
  {
    name: name,
    description: description,
    template: template,
    skills: @skills,
    system_prompt: system_prompt,
    local_tools: local_tools.map { |t| t.respond_to?(:name) ? t.name : t.to_s },
    mcp_tools: mcp_tools.map(&:name),
    mcp_config: @mcp_config,
    tools_config: @tools_config,
    mcp_servers: @mcp_clients.keys,
    model: model,
    config: (@config.empty? ? nil : @config.to_json_hash),
    bus: @bus ? true : nil
  }.compact
end

#update(template: nil, context: nil, system_prompt: nil, model: nil, temperature: nil, **kwargs) ⇒ self

Reconfigure the robot for a new context

Parameters:

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

    new template to apply

  • context (Hash, nil) (defaults to: nil)

    new context for the template

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

    new system prompt

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

    new model

  • temperature (Float, nil) (defaults to: nil)

    new temperature

Returns:

  • (self)


248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/robot_lab/robot.rb', line 248

def update(template: nil, context: nil, system_prompt: nil, model: nil, temperature: nil, **kwargs)
  if template
    @template = template
    ctx = context || @build_context
    apply_template_to_chat(ctx)
  end

  @chat.with_instructions(system_prompt) if system_prompt
  @chat.with_model(model) if model
  @chat.with_temperature(temperature) if temperature

  kwargs.each do |key, value|
    method = :"with_#{key}"
    @chat.public_send(method, value) if value && @chat.respond_to?(method)
  end

  self
end