robot_lab 0.0.4 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -0
- data/README.md +64 -6
- data/Rakefile +2 -1
- data/docs/api/core/index.md +41 -46
- data/docs/api/core/memory.md +200 -154
- data/docs/api/core/network.md +13 -3
- data/docs/api/core/robot.md +38 -26
- data/docs/api/core/state.md +55 -73
- data/docs/api/index.md +7 -28
- data/docs/api/messages/index.md +35 -20
- data/docs/api/messages/text-message.md +67 -21
- data/docs/api/messages/tool-call-message.md +80 -41
- data/docs/api/messages/tool-result-message.md +119 -50
- data/docs/api/messages/user-message.md +48 -24
- data/docs/architecture/core-concepts.md +10 -15
- data/docs/concepts.md +5 -7
- data/docs/examples/index.md +2 -2
- data/docs/getting-started/configuration.md +80 -0
- data/docs/guides/building-robots.md +10 -9
- data/docs/guides/creating-networks.md +49 -0
- data/docs/guides/index.md +0 -5
- data/docs/guides/rails-integration.md +244 -162
- data/docs/guides/streaming.md +118 -138
- data/docs/index.md +0 -8
- data/examples/03_network.rb +10 -7
- data/examples/08_llm_config.rb +40 -11
- data/examples/09_chaining.rb +45 -6
- data/examples/11_network_introspection.rb +30 -7
- data/examples/12_message_bus.rb +1 -1
- data/examples/14_rusty_circuit/heckler.rb +14 -8
- data/examples/14_rusty_circuit/open_mic.rb +5 -3
- data/examples/14_rusty_circuit/scout.rb +14 -31
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +1 -1
- data/examples/16_writers_room/display.rb +158 -0
- data/examples/16_writers_room/output/.gitignore +4 -0
- data/examples/16_writers_room/output/README.md +69 -0
- data/examples/16_writers_room/output/opus_001.md +263 -0
- data/examples/16_writers_room/output/opus_001_notes.log +470 -0
- data/examples/16_writers_room/output/opus_002.md +245 -0
- data/examples/16_writers_room/output/opus_002_notes.log +546 -0
- data/examples/16_writers_room/output/opus_002_screenplay.md +7989 -0
- data/examples/16_writers_room/output/opus_002_screenplay_notes.md +993 -0
- data/examples/16_writers_room/prompts/screenplay_writer.md +66 -0
- data/examples/16_writers_room/prompts/writer.md +37 -0
- data/examples/16_writers_room/room.rb +186 -0
- data/examples/16_writers_room/tools.rb +173 -0
- data/examples/16_writers_room/writer.rb +121 -0
- data/examples/16_writers_room/writers_room.rb +256 -0
- data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
- data/lib/robot_lab/memory.rb +8 -32
- data/lib/robot_lab/network.rb +13 -20
- data/lib/robot_lab/robot/bus_messaging.rb +239 -0
- data/lib/robot_lab/robot/mcp_management.rb +88 -0
- data/lib/robot_lab/robot/template_rendering.rb +130 -0
- data/lib/robot_lab/robot.rb +56 -420
- data/lib/robot_lab/run_config.rb +184 -0
- data/lib/robot_lab/state_proxy.rb +2 -12
- data/lib/robot_lab/task.rb +8 -1
- data/lib/robot_lab/utils.rb +39 -0
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +29 -8
- data/mkdocs.yml +0 -11
- metadata +21 -20
- data/docs/api/adapters/anthropic.md +0 -121
- data/docs/api/adapters/gemini.md +0 -133
- data/docs/api/adapters/index.md +0 -104
- data/docs/api/adapters/openai.md +0 -134
- data/docs/api/history/active-record-adapter.md +0 -275
- data/docs/api/history/config.md +0 -284
- data/docs/api/history/index.md +0 -128
- data/docs/api/history/thread-manager.md +0 -194
- data/docs/guides/history.md +0 -359
- data/lib/robot_lab/adapters/anthropic.rb +0 -163
- data/lib/robot_lab/adapters/base.rb +0 -85
- data/lib/robot_lab/adapters/gemini.rb +0 -193
- data/lib/robot_lab/adapters/openai.rb +0 -160
- data/lib/robot_lab/adapters/registry.rb +0 -81
- data/lib/robot_lab/errors.rb +0 -70
- data/lib/robot_lab/history/active_record_adapter.rb +0 -146
- data/lib/robot_lab/history/config.rb +0 -115
- data/lib/robot_lab/history/thread_manager.rb +0 -93
- data/lib/robot_lab/robotic_model.rb +0 -324
|
@@ -7,16 +7,18 @@ User input with conversation metadata.
|
|
|
7
7
|
```ruby
|
|
8
8
|
message = UserMessage.new(
|
|
9
9
|
"What's my order status?",
|
|
10
|
-
|
|
10
|
+
session_id: "session_123",
|
|
11
11
|
system_prompt: "Be concise",
|
|
12
12
|
metadata: { source: "web" }
|
|
13
13
|
)
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
**Note:** `UserMessage` is a standalone class, not a subclass of `Message`.
|
|
17
|
+
|
|
16
18
|
## Constructor
|
|
17
19
|
|
|
18
20
|
```ruby
|
|
19
|
-
UserMessage.new(content,
|
|
21
|
+
UserMessage.new(content, session_id: nil, system_prompt: nil, metadata: nil, id: nil)
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
**Parameters:**
|
|
@@ -24,9 +26,10 @@ UserMessage.new(content, thread_id: nil, system_prompt: nil, metadata: {})
|
|
|
24
26
|
| Name | Type | Description |
|
|
25
27
|
|------|------|-------------|
|
|
26
28
|
| `content` | `String` | Message text |
|
|
27
|
-
| `
|
|
29
|
+
| `session_id` | `String`, `nil` | Conversation session ID |
|
|
28
30
|
| `system_prompt` | `String`, `nil` | Override system prompt |
|
|
29
|
-
| `metadata` | `Hash` | Additional metadata |
|
|
31
|
+
| `metadata` | `Hash`, `nil` | Additional metadata |
|
|
32
|
+
| `id` | `String`, `nil` | Unique message ID (defaults to UUID) |
|
|
30
33
|
|
|
31
34
|
## Attributes
|
|
32
35
|
|
|
@@ -38,13 +41,13 @@ message.content # => String
|
|
|
38
41
|
|
|
39
42
|
The message text.
|
|
40
43
|
|
|
41
|
-
###
|
|
44
|
+
### session_id
|
|
42
45
|
|
|
43
46
|
```ruby
|
|
44
|
-
message.
|
|
47
|
+
message.session_id # => String | nil
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
Conversation
|
|
50
|
+
Conversation session identifier for history persistence.
|
|
48
51
|
|
|
49
52
|
### system_prompt
|
|
50
53
|
|
|
@@ -78,14 +81,6 @@ message.created_at # => Time
|
|
|
78
81
|
|
|
79
82
|
Message creation timestamp.
|
|
80
83
|
|
|
81
|
-
### role
|
|
82
|
-
|
|
83
|
-
```ruby
|
|
84
|
-
message.role # => :user
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Always returns `:user`.
|
|
88
|
-
|
|
89
84
|
## Methods
|
|
90
85
|
|
|
91
86
|
### to_h
|
|
@@ -100,10 +95,11 @@ Hash representation.
|
|
|
100
95
|
|
|
101
96
|
```ruby
|
|
102
97
|
{
|
|
103
|
-
role: :user,
|
|
104
98
|
content: "What's my order status?",
|
|
99
|
+
session_id: "session_123",
|
|
100
|
+
system_prompt: "Be concise",
|
|
101
|
+
metadata: { source: "web" },
|
|
105
102
|
id: "uuid-here",
|
|
106
|
-
thread_id: "thread_123",
|
|
107
103
|
created_at: "2024-01-15T10:30:00Z"
|
|
108
104
|
}
|
|
109
105
|
```
|
|
@@ -116,6 +112,30 @@ message.to_json # => String
|
|
|
116
112
|
|
|
117
113
|
JSON representation.
|
|
118
114
|
|
|
115
|
+
### to_message
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
message.to_message # => TextMessage
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Converts to a `TextMessage` with role `"user"` for use in conversation history.
|
|
122
|
+
|
|
123
|
+
### to_s
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
message.to_s # => String
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Returns the content string.
|
|
130
|
+
|
|
131
|
+
### self.from
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
UserMessage.from(input) # => UserMessage
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Creates a `UserMessage` from a String, Hash, or existing `UserMessage`.
|
|
138
|
+
|
|
119
139
|
## Examples
|
|
120
140
|
|
|
121
141
|
### Basic Message
|
|
@@ -124,12 +144,12 @@ JSON representation.
|
|
|
124
144
|
message = UserMessage.new("Hello!")
|
|
125
145
|
```
|
|
126
146
|
|
|
127
|
-
### With
|
|
147
|
+
### With Session ID
|
|
128
148
|
|
|
129
149
|
```ruby
|
|
130
150
|
message = UserMessage.new(
|
|
131
151
|
"Continue our conversation",
|
|
132
|
-
|
|
152
|
+
session_id: "session_abc123"
|
|
133
153
|
)
|
|
134
154
|
```
|
|
135
155
|
|
|
@@ -156,16 +176,20 @@ message = UserMessage.new(
|
|
|
156
176
|
)
|
|
157
177
|
```
|
|
158
178
|
|
|
159
|
-
### Creating
|
|
179
|
+
### Creating from Various Inputs
|
|
160
180
|
|
|
161
181
|
```ruby
|
|
162
|
-
|
|
163
|
-
|
|
182
|
+
# From a string
|
|
183
|
+
msg = UserMessage.from("Hello!")
|
|
184
|
+
|
|
185
|
+
# From a hash
|
|
186
|
+
msg = UserMessage.from(content: "Hello!", session_id: "123")
|
|
164
187
|
|
|
165
|
-
|
|
188
|
+
# From an existing UserMessage (returns as-is)
|
|
189
|
+
msg = UserMessage.from(existing_message)
|
|
166
190
|
```
|
|
167
191
|
|
|
168
192
|
## See Also
|
|
169
193
|
|
|
170
|
-
- [
|
|
194
|
+
- [Memory](../core/memory.md)
|
|
171
195
|
- [TextMessage](text-message.md)
|
|
@@ -130,22 +130,21 @@ robot = RobotLab.build(
|
|
|
130
130
|
)
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
### RobotLab::Tool
|
|
133
|
+
### RobotLab::Tool.create Factory
|
|
134
134
|
|
|
135
135
|
For simpler tools that do not need a class:
|
|
136
136
|
|
|
137
137
|
```ruby
|
|
138
|
-
tool = RobotLab::Tool.
|
|
138
|
+
tool = RobotLab::Tool.create(
|
|
139
139
|
name: "get_time",
|
|
140
|
-
description: "Get the current time"
|
|
141
|
-
|
|
142
|
-
)
|
|
140
|
+
description: "Get the current time"
|
|
141
|
+
) { |_args| Time.now.to_s }
|
|
143
142
|
```
|
|
144
143
|
|
|
145
144
|
With parameter schema:
|
|
146
145
|
|
|
147
146
|
```ruby
|
|
148
|
-
tool = RobotLab::Tool.
|
|
147
|
+
tool = RobotLab::Tool.create(
|
|
149
148
|
name: "get_weather",
|
|
150
149
|
description: "Get weather for a location",
|
|
151
150
|
parameters: {
|
|
@@ -154,11 +153,8 @@ tool = RobotLab::Tool.new(
|
|
|
154
153
|
location: { type: "string", description: "City name" }
|
|
155
154
|
},
|
|
156
155
|
required: ["location"]
|
|
157
|
-
},
|
|
158
|
-
handler: ->(input, **_opts) {
|
|
159
|
-
WeatherAPI.current(input[:location])
|
|
160
156
|
}
|
|
161
|
-
)
|
|
157
|
+
) { |args| WeatherAPI.current(args[:location]) }
|
|
162
158
|
```
|
|
163
159
|
|
|
164
160
|
### Tool Execution
|
|
@@ -167,10 +163,9 @@ When an LLM decides to use a tool:
|
|
|
167
163
|
|
|
168
164
|
1. LLM generates a tool call with tool name and arguments
|
|
169
165
|
2. `@chat` (RubyLLM) identifies the tool from its registered tools
|
|
170
|
-
3.
|
|
171
|
-
4.
|
|
172
|
-
5.
|
|
173
|
-
6. Loop repeats until the LLM produces a final text response
|
|
166
|
+
3. Calls the `execute` method with keyword arguments
|
|
167
|
+
4. Result is sent back to the LLM for continued processing
|
|
168
|
+
5. Loop repeats until the LLM produces a final text response
|
|
174
169
|
|
|
175
170
|
### Error Handling
|
|
176
171
|
|
|
@@ -414,7 +409,7 @@ alice.send_message(to: :bob, content: "Tell me a joke.")
|
|
|
414
409
|
# Handle incoming messages with auto-ack (1 arg)
|
|
415
410
|
bob.on_message do |message|
|
|
416
411
|
joke = bob.run(message.content.to_s).last_text_content
|
|
417
|
-
bob.
|
|
412
|
+
bob.send_reply(to: message.from.to_sym, content: joke, in_reply_to: message.key)
|
|
418
413
|
end
|
|
419
414
|
```
|
|
420
415
|
|
data/docs/concepts.md
CHANGED
|
@@ -167,10 +167,10 @@ robot = RobotLab.build(
|
|
|
167
167
|
)
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
-
### RobotLab::Tool
|
|
170
|
+
### RobotLab::Tool.create Factory
|
|
171
171
|
|
|
172
172
|
```ruby
|
|
173
|
-
tool = RobotLab::Tool.
|
|
173
|
+
tool = RobotLab::Tool.create(
|
|
174
174
|
name: "get_weather",
|
|
175
175
|
description: "Get current weather for a location",
|
|
176
176
|
parameters: {
|
|
@@ -180,9 +180,7 @@ tool = RobotLab::Tool.new(
|
|
|
180
180
|
},
|
|
181
181
|
required: ["location"]
|
|
182
182
|
}
|
|
183
|
-
)
|
|
184
|
-
WeatherService.current(input[:location])
|
|
185
|
-
end
|
|
183
|
+
) { |args| WeatherService.current(args[:location]) }
|
|
186
184
|
```
|
|
187
185
|
|
|
188
186
|
## RobotResult
|
|
@@ -374,7 +372,7 @@ alice = RobotLab.build(name: "alice", system_prompt: "You evaluate jokes.", bus:
|
|
|
374
372
|
# Register handlers
|
|
375
373
|
bob.on_message do |message|
|
|
376
374
|
joke = bob.run(message.content.to_s).last_text_content
|
|
377
|
-
bob.
|
|
375
|
+
bob.send_reply(to: message.from.to_sym, content: joke, in_reply_to: message.key)
|
|
378
376
|
end
|
|
379
377
|
|
|
380
378
|
alice.on_message do |message|
|
|
@@ -391,7 +389,7 @@ Key features:
|
|
|
391
389
|
|
|
392
390
|
- **Typed channels** — only `RobotMessage` objects accepted per channel
|
|
393
391
|
- **Auto-ACK** — 1-arg `on_message` blocks auto-acknowledge; 2-arg blocks give manual control
|
|
394
|
-
- **Reply correlation** — `
|
|
392
|
+
- **Reply correlation** — `send_reply(to:, content:, in_reply_to:)` tracks threads via `in_reply_to`
|
|
395
393
|
- **Independent of Network** — bus works without a Network pipeline
|
|
396
394
|
|
|
397
395
|
### Dynamic Spawning
|
data/docs/examples/index.md
CHANGED
|
@@ -190,7 +190,7 @@ class Comedian < RobotLab::Robot
|
|
|
190
190
|
temp = [TEMP_START + TEMP_STEP * (@attempts - 1), 1.0].min
|
|
191
191
|
with_temperature(temp)
|
|
192
192
|
joke = run(message.content.to_s).last_text_content.strip
|
|
193
|
-
|
|
193
|
+
send_reply(to: message.from.to_sym, content: joke, in_reply_to: message.key)
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
|
|
@@ -224,7 +224,7 @@ Key patterns demonstrated:
|
|
|
224
224
|
|
|
225
225
|
- **Robot subclasses** with templates for prompt management
|
|
226
226
|
- **Auto-ack** via 1-arg `on_message` blocks
|
|
227
|
-
- **`
|
|
227
|
+
- **`send_reply(to:, content:, in_reply_to:)`** for correlated responses
|
|
228
228
|
- **Temperature ramping** (0.2 → 1.0) for increasing creativity
|
|
229
229
|
- **Convergence loop** that terminates when the critic approves
|
|
230
230
|
|
|
@@ -292,6 +292,86 @@ defaults:
|
|
|
292
292
|
anthropic_api_key: <%= Rails.application.credentials.anthropic_api_key %>
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
+
## RunConfig: Shared Operational Defaults
|
|
296
|
+
|
|
297
|
+
`RunConfig` is a configuration object that lets you express operational defaults for LLM settings, tools, callbacks, and infrastructure. Unlike `RobotLab.config` (which is global and static), RunConfig flows through the hierarchy and can be customized at each level:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
RobotLab.config (global) -> Network RunConfig -> Robot RunConfig -> Template front matter -> Task RunConfig -> Runtime
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Creating a RunConfig
|
|
304
|
+
|
|
305
|
+
```ruby
|
|
306
|
+
# Keyword construction
|
|
307
|
+
config = RobotLab::RunConfig.new(model: "claude-sonnet-4", temperature: 0.7)
|
|
308
|
+
|
|
309
|
+
# Block DSL
|
|
310
|
+
config = RobotLab::RunConfig.new do |c|
|
|
311
|
+
c.model "claude-sonnet-4"
|
|
312
|
+
c.temperature 0.7
|
|
313
|
+
c.max_tokens 2000
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Chaining
|
|
317
|
+
config = RobotLab::RunConfig.new
|
|
318
|
+
.model("claude-sonnet-4")
|
|
319
|
+
.temperature(0.7)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Applying RunConfig
|
|
323
|
+
|
|
324
|
+
Pass `config:` to robots and networks. Explicit constructor kwargs always override the RunConfig:
|
|
325
|
+
|
|
326
|
+
```ruby
|
|
327
|
+
# Shared config for a team of robots
|
|
328
|
+
shared = RobotLab::RunConfig.new(model: "claude-sonnet-4", temperature: 0.5)
|
|
329
|
+
|
|
330
|
+
# Robot uses shared config
|
|
331
|
+
robot = RobotLab.build(
|
|
332
|
+
name: "writer",
|
|
333
|
+
system_prompt: "You are a creative writer.",
|
|
334
|
+
config: shared,
|
|
335
|
+
temperature: 0.9 # overrides shared config's 0.5
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
# Network applies config to all member robots
|
|
339
|
+
network = RobotLab.create_network(name: "pipeline", config: shared) do
|
|
340
|
+
task :analyzer, analyzer_robot, depends_on: :none
|
|
341
|
+
task :writer, writer_robot, depends_on: [:analyzer]
|
|
342
|
+
end
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Merging Configs
|
|
346
|
+
|
|
347
|
+
RunConfig supports merge semantics where the more-specific config's values win:
|
|
348
|
+
|
|
349
|
+
```ruby
|
|
350
|
+
network_config = RobotLab::RunConfig.new(model: "claude-sonnet-4", temperature: 0.5)
|
|
351
|
+
robot_config = RobotLab::RunConfig.new(temperature: 0.9)
|
|
352
|
+
effective = network_config.merge(robot_config)
|
|
353
|
+
effective.model #=> "claude-sonnet-4" (inherited)
|
|
354
|
+
effective.temperature #=> 0.9 (overridden)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Available Fields
|
|
358
|
+
|
|
359
|
+
| Category | Fields |
|
|
360
|
+
|----------|--------|
|
|
361
|
+
| **LLM** | `model`, `temperature`, `top_p`, `top_k`, `max_tokens`, `presence_penalty`, `frequency_penalty`, `stop` |
|
|
362
|
+
| **Tools** | `mcp`, `tools` |
|
|
363
|
+
| **Callbacks** | `on_tool_call`, `on_tool_result` |
|
|
364
|
+
| **Infrastructure** | `bus`, `enable_cache` |
|
|
365
|
+
|
|
366
|
+
### RunConfig vs RobotLab.config
|
|
367
|
+
|
|
368
|
+
| | `RobotLab.config` | `RunConfig` |
|
|
369
|
+
|---|---|---|
|
|
370
|
+
| **Scope** | Global (all robots) | Per-network, per-robot, or per-task |
|
|
371
|
+
| **Source** | YAML files, env vars | Code (constructor, block DSL) |
|
|
372
|
+
| **Mutability** | Loaded once, rarely changed | Created per use case, merged |
|
|
373
|
+
| **Purpose** | API keys, timeouts, defaults | Model, temperature, tools per workflow |
|
|
374
|
+
|
|
295
375
|
## Robot-Level Configuration
|
|
296
376
|
|
|
297
377
|
Individual robots can override the global model and other settings:
|
|
@@ -340,17 +340,18 @@ puts result.value.last_text_content
|
|
|
340
340
|
|
|
341
341
|
### With Streaming
|
|
342
342
|
|
|
343
|
-
Stream responses in real-time by
|
|
343
|
+
Stream responses in real-time by registering callbacks before calling `run`:
|
|
344
344
|
|
|
345
345
|
```ruby
|
|
346
|
-
robot.
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
end
|
|
346
|
+
robot.on_new_message do |message|
|
|
347
|
+
print message.content if message.content
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
robot.on_tool_call do |tool_call|
|
|
351
|
+
puts "\nCalling tool: #{tool_call.name}"
|
|
353
352
|
end
|
|
353
|
+
|
|
354
|
+
result = robot.run("Tell me a story")
|
|
354
355
|
```
|
|
355
356
|
|
|
356
357
|
## Robot Patterns
|
|
@@ -434,7 +435,7 @@ class Comedian < RobotLab::Robot
|
|
|
434
435
|
super(name: "bob", template: :comedian, bus: bus)
|
|
435
436
|
on_message do |message|
|
|
436
437
|
joke = run(message.content.to_s).last_text_content.strip
|
|
437
|
-
|
|
438
|
+
send_reply(to: message.from.to_sym, content: joke, in_reply_to: message.key)
|
|
438
439
|
end
|
|
439
440
|
end
|
|
440
441
|
end
|
|
@@ -122,6 +122,7 @@ end
|
|
|
122
122
|
| `mcp` | MCP servers for this task (`:none`, `:inherit`, or array) |
|
|
123
123
|
| `tools` | Tools available to this task (`:none`, `:inherit`, or array) |
|
|
124
124
|
| `memory` | Task-specific memory |
|
|
125
|
+
| `config` | Per-task `RunConfig` (merged on top of network's config) |
|
|
125
126
|
| `depends_on` | `:none`, `[:task1]`, or `:optional` |
|
|
126
127
|
|
|
127
128
|
## Conditional Routing
|
|
@@ -380,6 +381,54 @@ network.memory # => Memory instance (shared)
|
|
|
380
381
|
network.to_h # => Hash representation
|
|
381
382
|
```
|
|
382
383
|
|
|
384
|
+
## Configuration Inheritance
|
|
385
|
+
|
|
386
|
+
Networks accept a `config:` parameter that establishes default LLM settings for all member robots. This is useful when you want consistent behavior across a pipeline without configuring each robot individually.
|
|
387
|
+
|
|
388
|
+
### Network-Wide Defaults
|
|
389
|
+
|
|
390
|
+
```ruby
|
|
391
|
+
# All robots in this network use the same model and temperature
|
|
392
|
+
shared = RobotLab::RunConfig.new(model: "claude-sonnet-4", temperature: 0.5)
|
|
393
|
+
|
|
394
|
+
network = RobotLab.create_network(name: "pipeline", config: shared) do
|
|
395
|
+
task :analyzer, analyzer_robot, depends_on: :none
|
|
396
|
+
task :writer, writer_robot, depends_on: [:analyzer]
|
|
397
|
+
task :reviewer, reviewer_robot, depends_on: [:writer]
|
|
398
|
+
end
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Per-Task Overrides
|
|
402
|
+
|
|
403
|
+
Individual tasks can override the network's config with their own `config:`:
|
|
404
|
+
|
|
405
|
+
```ruby
|
|
406
|
+
creative_config = RobotLab::RunConfig.new(temperature: 0.9)
|
|
407
|
+
|
|
408
|
+
network = RobotLab.create_network(name: "pipeline", config: shared) do
|
|
409
|
+
task :analyzer, analyzer_robot, depends_on: :none
|
|
410
|
+
task :writer, writer_robot,
|
|
411
|
+
config: creative_config, # writer gets higher temperature
|
|
412
|
+
depends_on: [:analyzer]
|
|
413
|
+
task :reviewer, reviewer_robot, depends_on: [:writer]
|
|
414
|
+
end
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Inheritance Chain
|
|
418
|
+
|
|
419
|
+
The full configuration hierarchy (most-specific wins):
|
|
420
|
+
|
|
421
|
+
```
|
|
422
|
+
RobotLab.config (global)
|
|
423
|
+
-> Network config
|
|
424
|
+
-> Task config
|
|
425
|
+
-> Robot config (from constructor)
|
|
426
|
+
-> Template front matter
|
|
427
|
+
-> Constructor kwargs (model:, temperature:, etc.)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Each layer only overrides values it explicitly sets. Unset values pass through from the parent.
|
|
431
|
+
|
|
383
432
|
## Best Practices
|
|
384
433
|
|
|
385
434
|
### 1. Keep Robots Focused
|
data/docs/guides/index.md
CHANGED
|
@@ -34,10 +34,6 @@ If you're new to RobotLab, start here:
|
|
|
34
34
|
|
|
35
35
|
Real-time streaming of LLM responses
|
|
36
36
|
|
|
37
|
-
- [:octicons-database-24: **Conversation History**](history.md)
|
|
38
|
-
|
|
39
|
-
Persist and restore conversation threads
|
|
40
|
-
|
|
41
37
|
- [:octicons-cpu-24: **Memory System**](memory.md)
|
|
42
38
|
|
|
43
39
|
Share data between robots with the memory system
|
|
@@ -63,6 +59,5 @@ If you're new to RobotLab, start here:
|
|
|
63
59
|
| [Using Tools](using-tools.md) | Add custom capabilities | 10 min |
|
|
64
60
|
| [MCP Integration](mcp-integration.md) | External tool servers | 10 min |
|
|
65
61
|
| [Streaming](streaming.md) | Real-time responses | 5 min |
|
|
66
|
-
| [History](history.md) | Conversation persistence | 10 min |
|
|
67
62
|
| [Memory](memory.md) | Shared data store | 5 min |
|
|
68
63
|
| [Rails Integration](rails-integration.md) | Rails application setup | 15 min |
|