robot_lab 0.0.1
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 +7 -0
- data/.envrc +1 -0
- data/.github/workflows/deploy-github-pages.yml +52 -0
- data/.github/workflows/deploy-yard-docs.yml +52 -0
- data/CHANGELOG.md +55 -0
- data/COMMITS.md +196 -0
- data/LICENSE.txt +21 -0
- data/README.md +332 -0
- data/Rakefile +67 -0
- data/docs/api/adapters/anthropic.md +121 -0
- data/docs/api/adapters/gemini.md +133 -0
- data/docs/api/adapters/index.md +104 -0
- data/docs/api/adapters/openai.md +134 -0
- data/docs/api/core/index.md +113 -0
- data/docs/api/core/memory.md +314 -0
- data/docs/api/core/network.md +291 -0
- data/docs/api/core/robot.md +273 -0
- data/docs/api/core/state.md +273 -0
- data/docs/api/core/tool.md +353 -0
- data/docs/api/history/active-record-adapter.md +195 -0
- data/docs/api/history/config.md +191 -0
- data/docs/api/history/index.md +132 -0
- data/docs/api/history/thread-manager.md +144 -0
- data/docs/api/index.md +82 -0
- data/docs/api/mcp/client.md +221 -0
- data/docs/api/mcp/index.md +111 -0
- data/docs/api/mcp/server.md +225 -0
- data/docs/api/mcp/transports.md +264 -0
- data/docs/api/messages/index.md +67 -0
- data/docs/api/messages/text-message.md +102 -0
- data/docs/api/messages/tool-call-message.md +144 -0
- data/docs/api/messages/tool-result-message.md +154 -0
- data/docs/api/messages/user-message.md +171 -0
- data/docs/api/streaming/context.md +174 -0
- data/docs/api/streaming/events.md +237 -0
- data/docs/api/streaming/index.md +108 -0
- data/docs/architecture/core-concepts.md +243 -0
- data/docs/architecture/index.md +138 -0
- data/docs/architecture/message-flow.md +320 -0
- data/docs/architecture/network-orchestration.md +216 -0
- data/docs/architecture/robot-execution.md +243 -0
- data/docs/architecture/state-management.md +323 -0
- data/docs/assets/css/custom.css +56 -0
- data/docs/assets/images/robot_lab.jpg +0 -0
- data/docs/concepts.md +216 -0
- data/docs/examples/basic-chat.md +193 -0
- data/docs/examples/index.md +129 -0
- data/docs/examples/mcp-server.md +290 -0
- data/docs/examples/multi-robot-network.md +312 -0
- data/docs/examples/rails-application.md +420 -0
- data/docs/examples/tool-usage.md +310 -0
- data/docs/getting-started/configuration.md +230 -0
- data/docs/getting-started/index.md +56 -0
- data/docs/getting-started/installation.md +179 -0
- data/docs/getting-started/quick-start.md +203 -0
- data/docs/guides/building-robots.md +376 -0
- data/docs/guides/creating-networks.md +366 -0
- data/docs/guides/history.md +359 -0
- data/docs/guides/index.md +68 -0
- data/docs/guides/mcp-integration.md +356 -0
- data/docs/guides/memory.md +309 -0
- data/docs/guides/rails-integration.md +432 -0
- data/docs/guides/streaming.md +314 -0
- data/docs/guides/using-tools.md +394 -0
- data/docs/index.md +160 -0
- data/examples/01_simple_robot.rb +38 -0
- data/examples/02_tools.rb +106 -0
- data/examples/03_network.rb +103 -0
- data/examples/04_mcp.rb +219 -0
- data/examples/05_streaming.rb +124 -0
- data/examples/06_prompt_templates.rb +324 -0
- data/examples/07_network_memory.rb +329 -0
- data/examples/prompts/assistant/system.txt.erb +2 -0
- data/examples/prompts/assistant/user.txt.erb +1 -0
- data/examples/prompts/billing/system.txt.erb +7 -0
- data/examples/prompts/billing/user.txt.erb +1 -0
- data/examples/prompts/classifier/system.txt.erb +4 -0
- data/examples/prompts/classifier/user.txt.erb +1 -0
- data/examples/prompts/entity_extractor/system.txt.erb +11 -0
- data/examples/prompts/entity_extractor/user.txt.erb +3 -0
- data/examples/prompts/escalation/system.txt.erb +35 -0
- data/examples/prompts/escalation/user.txt.erb +34 -0
- data/examples/prompts/general/system.txt.erb +4 -0
- data/examples/prompts/general/user.txt.erb +1 -0
- data/examples/prompts/github_assistant/system.txt.erb +6 -0
- data/examples/prompts/github_assistant/user.txt.erb +1 -0
- data/examples/prompts/helper/system.txt.erb +1 -0
- data/examples/prompts/helper/user.txt.erb +1 -0
- data/examples/prompts/keyword_extractor/system.txt.erb +8 -0
- data/examples/prompts/keyword_extractor/user.txt.erb +3 -0
- data/examples/prompts/order_support/system.txt.erb +27 -0
- data/examples/prompts/order_support/user.txt.erb +22 -0
- data/examples/prompts/product_support/system.txt.erb +30 -0
- data/examples/prompts/product_support/user.txt.erb +32 -0
- data/examples/prompts/sentiment_analyzer/system.txt.erb +9 -0
- data/examples/prompts/sentiment_analyzer/user.txt.erb +3 -0
- data/examples/prompts/synthesizer/system.txt.erb +14 -0
- data/examples/prompts/synthesizer/user.txt.erb +15 -0
- data/examples/prompts/technical/system.txt.erb +7 -0
- data/examples/prompts/technical/user.txt.erb +1 -0
- data/examples/prompts/triage/system.txt.erb +16 -0
- data/examples/prompts/triage/user.txt.erb +17 -0
- data/lib/generators/robot_lab/install_generator.rb +78 -0
- data/lib/generators/robot_lab/robot_generator.rb +55 -0
- data/lib/generators/robot_lab/templates/initializer.rb.tt +41 -0
- data/lib/generators/robot_lab/templates/migration.rb.tt +32 -0
- data/lib/generators/robot_lab/templates/result_model.rb.tt +52 -0
- data/lib/generators/robot_lab/templates/robot.rb.tt +46 -0
- data/lib/generators/robot_lab/templates/robot_test.rb.tt +32 -0
- data/lib/generators/robot_lab/templates/routing_robot.rb.tt +53 -0
- data/lib/generators/robot_lab/templates/thread_model.rb.tt +40 -0
- data/lib/robot_lab/adapters/anthropic.rb +163 -0
- data/lib/robot_lab/adapters/base.rb +85 -0
- data/lib/robot_lab/adapters/gemini.rb +193 -0
- data/lib/robot_lab/adapters/openai.rb +159 -0
- data/lib/robot_lab/adapters/registry.rb +81 -0
- data/lib/robot_lab/configuration.rb +143 -0
- data/lib/robot_lab/error.rb +32 -0
- data/lib/robot_lab/errors.rb +70 -0
- data/lib/robot_lab/history/active_record_adapter.rb +146 -0
- data/lib/robot_lab/history/config.rb +115 -0
- data/lib/robot_lab/history/thread_manager.rb +93 -0
- data/lib/robot_lab/mcp/client.rb +210 -0
- data/lib/robot_lab/mcp/server.rb +84 -0
- data/lib/robot_lab/mcp/transports/base.rb +56 -0
- data/lib/robot_lab/mcp/transports/sse.rb +117 -0
- data/lib/robot_lab/mcp/transports/stdio.rb +133 -0
- data/lib/robot_lab/mcp/transports/streamable_http.rb +139 -0
- data/lib/robot_lab/mcp/transports/websocket.rb +108 -0
- data/lib/robot_lab/memory.rb +882 -0
- data/lib/robot_lab/memory_change.rb +123 -0
- data/lib/robot_lab/message.rb +357 -0
- data/lib/robot_lab/network.rb +350 -0
- data/lib/robot_lab/rails/engine.rb +29 -0
- data/lib/robot_lab/rails/railtie.rb +42 -0
- data/lib/robot_lab/robot.rb +560 -0
- data/lib/robot_lab/robot_result.rb +205 -0
- data/lib/robot_lab/robotic_model.rb +324 -0
- data/lib/robot_lab/state_proxy.rb +188 -0
- data/lib/robot_lab/streaming/context.rb +144 -0
- data/lib/robot_lab/streaming/events.rb +95 -0
- data/lib/robot_lab/streaming/sequence_counter.rb +48 -0
- data/lib/robot_lab/task.rb +117 -0
- data/lib/robot_lab/tool.rb +223 -0
- data/lib/robot_lab/tool_config.rb +112 -0
- data/lib/robot_lab/tool_manifest.rb +234 -0
- data/lib/robot_lab/user_message.rb +118 -0
- data/lib/robot_lab/version.rb +5 -0
- data/lib/robot_lab/waiter.rb +73 -0
- data/lib/robot_lab.rb +195 -0
- data/mkdocs.yml +214 -0
- data/sig/robot_lab.rbs +4 -0
- metadata +442 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Network
|
|
2
|
+
|
|
3
|
+
Orchestrates multiple robots using SimpleFlow pipelines with DAG-based execution.
|
|
4
|
+
|
|
5
|
+
## Class: `RobotLab::Network`
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
network = RobotLab.create_network(name: "support") do
|
|
9
|
+
task :classifier, classifier_robot, depends_on: :none
|
|
10
|
+
task :billing, billing_robot, depends_on: :optional
|
|
11
|
+
end
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Attributes
|
|
15
|
+
|
|
16
|
+
### name
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
network.name # => String
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Network identifier for logging and debugging.
|
|
23
|
+
|
|
24
|
+
### robots
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
network.robots # => Hash<String, Robot>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Hash of robots keyed by name.
|
|
31
|
+
|
|
32
|
+
### pipeline
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
network.pipeline # => SimpleFlow::Pipeline
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The underlying SimpleFlow pipeline.
|
|
39
|
+
|
|
40
|
+
## Methods
|
|
41
|
+
|
|
42
|
+
### run
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
result = network.run(
|
|
46
|
+
message: "Help me",
|
|
47
|
+
customer_id: 123,
|
|
48
|
+
**context
|
|
49
|
+
)
|
|
50
|
+
# => SimpleFlow::Result
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Execute the network pipeline.
|
|
54
|
+
|
|
55
|
+
**Parameters:**
|
|
56
|
+
|
|
57
|
+
| Name | Type | Description |
|
|
58
|
+
|------|------|-------------|
|
|
59
|
+
| `message` | `String` | The input message |
|
|
60
|
+
| `**context` | `Hash` | Additional context passed to all robots |
|
|
61
|
+
|
|
62
|
+
**Returns:** `SimpleFlow::Result`
|
|
63
|
+
|
|
64
|
+
### task
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
network.task(name, robot, context: {}, mcp: :none, tools: :none, memory: nil, depends_on: :none)
|
|
68
|
+
# => self
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Add a task to the pipeline with optional per-task configuration.
|
|
72
|
+
|
|
73
|
+
**Parameters:**
|
|
74
|
+
|
|
75
|
+
| Name | Type | Description |
|
|
76
|
+
|------|------|-------------|
|
|
77
|
+
| `name` | `Symbol` | Task identifier |
|
|
78
|
+
| `robot` | `Robot` | Robot instance to execute |
|
|
79
|
+
| `context` | `Hash` | Task-specific context (deep-merged with run params) |
|
|
80
|
+
| `mcp` | `:none`, Array | MCP server config (`:none` or array of servers) |
|
|
81
|
+
| `tools` | `:none`, Array | Tools config (`:none` or array of tools) |
|
|
82
|
+
| `memory` | `Memory`, `nil` | Task-specific memory |
|
|
83
|
+
| `depends_on` | `:none`, `Array<Symbol>`, `:optional` | Task dependencies |
|
|
84
|
+
|
|
85
|
+
**Dependency Types:**
|
|
86
|
+
|
|
87
|
+
| Value | Description |
|
|
88
|
+
|-------|-------------|
|
|
89
|
+
| `:none` | No dependencies, runs first |
|
|
90
|
+
| `[:task1, :task2]` | Waits for listed tasks to complete |
|
|
91
|
+
| `:optional` | Only runs when explicitly activated |
|
|
92
|
+
|
|
93
|
+
### add_robot
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
network.add_robot(robot)
|
|
97
|
+
# => self
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Add a robot without creating a pipeline task. Useful for robots referenced by other tasks.
|
|
101
|
+
|
|
102
|
+
### robot / []
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
network.robot("billing") # => Robot
|
|
106
|
+
network["billing"] # => Robot (alias)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Get robot by name.
|
|
110
|
+
|
|
111
|
+
### available_robots
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
network.available_robots # => Array<Robot>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Returns all robot instances.
|
|
118
|
+
|
|
119
|
+
### visualize
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
network.visualize # => String
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
ASCII visualization of the pipeline.
|
|
126
|
+
|
|
127
|
+
### to_mermaid
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
network.to_mermaid # => String
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Mermaid diagram definition.
|
|
134
|
+
|
|
135
|
+
### execution_plan
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
network.execution_plan # => String
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Human-readable execution plan.
|
|
142
|
+
|
|
143
|
+
### to_h
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
network.to_h # => Hash
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Hash representation of network configuration.
|
|
150
|
+
|
|
151
|
+
```ruby
|
|
152
|
+
{
|
|
153
|
+
name: "support",
|
|
154
|
+
robots: ["classifier", "billing", "technical"],
|
|
155
|
+
tasks: ["classifier", "billing", "technical"],
|
|
156
|
+
optional_tasks: [:billing, :technical]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## SimpleFlow::Result
|
|
161
|
+
|
|
162
|
+
When `run` is called, a `SimpleFlow::Result` is returned:
|
|
163
|
+
|
|
164
|
+
### Attributes
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
result.value # Final task's output (RobotResult)
|
|
168
|
+
result.context # Hash of all task results
|
|
169
|
+
result.halted? # Whether execution stopped early
|
|
170
|
+
result.continued? # Whether execution continues
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Context Structure
|
|
174
|
+
|
|
175
|
+
```ruby
|
|
176
|
+
result.context[:run_params] # Original run parameters
|
|
177
|
+
result.context[:classifier] # Classifier robot's RobotResult
|
|
178
|
+
result.context[:billing] # Billing robot's RobotResult (if activated)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Builder DSL
|
|
182
|
+
|
|
183
|
+
### task
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
network = RobotLab.create_network(name: "pipeline") do
|
|
187
|
+
task :first, robot1, depends_on: :none
|
|
188
|
+
task :second, robot2, depends_on: [:first]
|
|
189
|
+
task :optional, robot3, depends_on: :optional
|
|
190
|
+
end
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### task with context
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
network = RobotLab.create_network(name: "support") do
|
|
197
|
+
task :classifier, classifier_robot, depends_on: :none
|
|
198
|
+
task :billing, billing_robot,
|
|
199
|
+
context: { department: "billing", escalation_level: 2 },
|
|
200
|
+
depends_on: :optional
|
|
201
|
+
task :technical, technical_robot,
|
|
202
|
+
context: { department: "technical" },
|
|
203
|
+
tools: [DebugTool, LogTool],
|
|
204
|
+
depends_on: :optional
|
|
205
|
+
end
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Examples
|
|
209
|
+
|
|
210
|
+
### Sequential Pipeline
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
network = RobotLab.create_network(name: "pipeline") do
|
|
214
|
+
task :extract, extractor, depends_on: :none
|
|
215
|
+
task :transform, transformer, depends_on: [:extract]
|
|
216
|
+
task :load, loader, depends_on: [:transform]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
result = network.run(message: "Process this document")
|
|
220
|
+
puts result.value.last_text_content
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Parallel Execution
|
|
224
|
+
|
|
225
|
+
```ruby
|
|
226
|
+
network = RobotLab.create_network(name: "analysis", concurrency: :threads) do
|
|
227
|
+
task :fetch, fetcher, depends_on: :none
|
|
228
|
+
|
|
229
|
+
# Run in parallel
|
|
230
|
+
task :sentiment, sentiment_bot, depends_on: [:fetch]
|
|
231
|
+
task :entities, entity_bot, depends_on: [:fetch]
|
|
232
|
+
|
|
233
|
+
# Wait for both
|
|
234
|
+
task :merge, merger, depends_on: [:sentiment, :entities]
|
|
235
|
+
end
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Conditional Routing
|
|
239
|
+
|
|
240
|
+
```ruby
|
|
241
|
+
class ClassifierRobot < RobotLab::Robot
|
|
242
|
+
def call(result)
|
|
243
|
+
robot_result = run(**extract_run_context(result))
|
|
244
|
+
|
|
245
|
+
new_result = result
|
|
246
|
+
.with_context(@name.to_sym, robot_result)
|
|
247
|
+
.continue(robot_result)
|
|
248
|
+
|
|
249
|
+
category = robot_result.last_text_content.to_s.downcase
|
|
250
|
+
case category
|
|
251
|
+
when /billing/ then new_result.activate(:billing)
|
|
252
|
+
when /technical/ then new_result.activate(:technical)
|
|
253
|
+
else new_result.activate(:general)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
network = RobotLab.create_network(name: "support") do
|
|
259
|
+
task :classifier, ClassifierRobot.new(name: "classifier", template: :classifier),
|
|
260
|
+
depends_on: :none
|
|
261
|
+
task :billing, billing_robot, depends_on: :optional
|
|
262
|
+
task :technical, technical_robot, depends_on: :optional
|
|
263
|
+
task :general, general_robot, depends_on: :optional
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
result = network.run(message: "I have a billing question")
|
|
267
|
+
puts result.value.last_text_content
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Accessing Task Results
|
|
271
|
+
|
|
272
|
+
```ruby
|
|
273
|
+
result = network.run(message: "Hello")
|
|
274
|
+
|
|
275
|
+
# Access individual task results
|
|
276
|
+
classifier_result = result.context[:classifier]
|
|
277
|
+
puts "Classification: #{classifier_result.last_text_content}"
|
|
278
|
+
|
|
279
|
+
# Check which optional task ran
|
|
280
|
+
if result.context[:billing]
|
|
281
|
+
puts "Billing handled the request"
|
|
282
|
+
elsif result.context[:technical]
|
|
283
|
+
puts "Technical handled the request"
|
|
284
|
+
end
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## See Also
|
|
288
|
+
|
|
289
|
+
- [Creating Networks Guide](../../guides/creating-networks.md)
|
|
290
|
+
- [Network Orchestration](../../architecture/network-orchestration.md)
|
|
291
|
+
- [Robot](robot.md)
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Robot
|
|
2
|
+
|
|
3
|
+
LLM-powered agent with personality, tools, and model configuration.
|
|
4
|
+
|
|
5
|
+
## Class: `RobotLab::Robot`
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
robot = RobotLab.build do
|
|
9
|
+
name "assistant"
|
|
10
|
+
description "A helpful assistant"
|
|
11
|
+
model "claude-sonnet-4"
|
|
12
|
+
template "You are helpful."
|
|
13
|
+
end
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Attributes
|
|
17
|
+
|
|
18
|
+
### name
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
robot.name # => String
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Unique identifier for the robot within a network.
|
|
25
|
+
|
|
26
|
+
### description
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
robot.description # => String
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Human-readable description of what the robot does.
|
|
33
|
+
|
|
34
|
+
### model
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
robot.model # => String
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
LLM model identifier (e.g., "claude-sonnet-4", "gpt-4o").
|
|
41
|
+
|
|
42
|
+
### template
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
robot.template # => String
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
System prompt that defines the robot's personality.
|
|
49
|
+
|
|
50
|
+
### local_tools
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
robot.local_tools # => Array<Tool>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Tools defined directly on the robot.
|
|
57
|
+
|
|
58
|
+
### mcp_clients
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
robot.mcp_clients # => Array<MCP::Client>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Connected MCP server clients.
|
|
65
|
+
|
|
66
|
+
### mcp_tools
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
robot.mcp_tools # => Array<Tool>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Tools discovered from MCP servers.
|
|
73
|
+
|
|
74
|
+
### mcp_config
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
robot.mcp_config # => Symbol | Array
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
MCP configuration (`:inherit`, `:none`, or server array).
|
|
81
|
+
|
|
82
|
+
### tools_config
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
robot.tools_config # => Symbol | Array
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Tools whitelist configuration (`:inherit`, `:none`, or tool names).
|
|
89
|
+
|
|
90
|
+
## Methods
|
|
91
|
+
|
|
92
|
+
### tools
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
robot.tools # => Array<Tool>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Returns all available tools (local + MCP, filtered by whitelist).
|
|
99
|
+
|
|
100
|
+
### run
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
result = robot.run(
|
|
104
|
+
state: state,
|
|
105
|
+
network: network,
|
|
106
|
+
streaming: nil,
|
|
107
|
+
**context
|
|
108
|
+
)
|
|
109
|
+
# => RobotResult
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Execute the robot with the given state.
|
|
113
|
+
|
|
114
|
+
**Parameters:**
|
|
115
|
+
|
|
116
|
+
| Name | Type | Description |
|
|
117
|
+
|------|------|-------------|
|
|
118
|
+
| `state` | `State` | Conversation state |
|
|
119
|
+
| `network` | `Network`, `NetworkRun`, `nil` | Network context |
|
|
120
|
+
| `streaming` | `Proc`, `nil` | Streaming callback |
|
|
121
|
+
| `**context` | `Hash` | Additional context |
|
|
122
|
+
|
|
123
|
+
**Returns:** `RobotResult`
|
|
124
|
+
|
|
125
|
+
### disconnect
|
|
126
|
+
|
|
127
|
+
```ruby
|
|
128
|
+
robot.disconnect
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Disconnect from all MCP servers.
|
|
132
|
+
|
|
133
|
+
### to_h
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
robot.to_h # => Hash
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Returns hash representation of the robot.
|
|
140
|
+
|
|
141
|
+
## Builder DSL
|
|
142
|
+
|
|
143
|
+
### name
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
name "my_robot"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Set the robot's name.
|
|
150
|
+
|
|
151
|
+
### description
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
description "Handles customer inquiries"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Set the robot's description.
|
|
158
|
+
|
|
159
|
+
### model
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
model "claude-sonnet-4"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Set the LLM model.
|
|
166
|
+
|
|
167
|
+
### template
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
# Inline template
|
|
171
|
+
template "You are a helpful assistant."
|
|
172
|
+
|
|
173
|
+
# Template file (loads from template_path)
|
|
174
|
+
template "support/system_prompt"
|
|
175
|
+
|
|
176
|
+
# Template file with variables
|
|
177
|
+
template "support/system_prompt", company: "Acme"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Set the system prompt.
|
|
181
|
+
|
|
182
|
+
### tool
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
tool :tool_name do
|
|
186
|
+
description "What the tool does"
|
|
187
|
+
parameter :param, type: :string, required: true
|
|
188
|
+
handler { |param:, **_| do_something(param) }
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Define a tool for the robot.
|
|
193
|
+
|
|
194
|
+
### mcp
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
mcp :inherit # Use network's MCP servers
|
|
198
|
+
mcp :none # No MCP servers
|
|
199
|
+
mcp [ # Specific servers
|
|
200
|
+
{ name: "fs", transport: { type: "stdio", command: "mcp-fs" } }
|
|
201
|
+
]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Configure MCP servers.
|
|
205
|
+
|
|
206
|
+
### tools (whitelist)
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
tools :inherit # Use network's tools
|
|
210
|
+
tools :none # No inherited tools
|
|
211
|
+
tools %w[read_file write_file] # Only these tools
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Configure tool whitelist.
|
|
215
|
+
|
|
216
|
+
## Examples
|
|
217
|
+
|
|
218
|
+
### Basic Robot
|
|
219
|
+
|
|
220
|
+
```ruby
|
|
221
|
+
robot = RobotLab.build do
|
|
222
|
+
name "greeter"
|
|
223
|
+
template "You greet users warmly."
|
|
224
|
+
end
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Robot with Tools
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
robot = RobotLab.build do
|
|
231
|
+
name "calculator"
|
|
232
|
+
model "claude-sonnet-4"
|
|
233
|
+
template "You help with math problems."
|
|
234
|
+
|
|
235
|
+
tool :add do
|
|
236
|
+
description "Add two numbers"
|
|
237
|
+
parameter :a, type: :number, required: true
|
|
238
|
+
parameter :b, type: :number, required: true
|
|
239
|
+
handler { |a:, b:, **_| a + b }
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
tool :multiply do
|
|
243
|
+
description "Multiply two numbers"
|
|
244
|
+
parameter :a, type: :number, required: true
|
|
245
|
+
parameter :b, type: :number, required: true
|
|
246
|
+
handler { |a:, b:, **_| a * b }
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Robot with MCP
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
robot = RobotLab.build do
|
|
255
|
+
name "developer"
|
|
256
|
+
template "You help with coding tasks."
|
|
257
|
+
|
|
258
|
+
mcp [
|
|
259
|
+
{
|
|
260
|
+
name: "github",
|
|
261
|
+
transport: { type: "stdio", command: "mcp-server-github" }
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
|
|
265
|
+
tools %w[search_repositories create_issue]
|
|
266
|
+
end
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## See Also
|
|
270
|
+
|
|
271
|
+
- [Building Robots Guide](../../guides/building-robots.md)
|
|
272
|
+
- [Tool](tool.md)
|
|
273
|
+
- [Network](network.md)
|