robot_lab 0.0.1 → 0.0.6
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/.github/workflows/deploy-github-pages.yml +9 -9
- data/.irbrc +6 -0
- data/CHANGELOG.md +140 -0
- data/README.md +263 -48
- data/Rakefile +71 -1
- data/docs/api/core/index.md +53 -46
- data/docs/api/core/memory.md +200 -154
- data/docs/api/core/network.md +13 -3
- data/docs/api/core/robot.md +490 -130
- data/docs/api/core/state.md +55 -73
- data/docs/api/core/tool.md +205 -209
- data/docs/api/index.md +7 -28
- data/docs/api/mcp/client.md +119 -48
- data/docs/api/mcp/index.md +75 -60
- data/docs/api/mcp/server.md +120 -136
- data/docs/api/mcp/transports.md +172 -184
- 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/api/streaming/context.md +157 -74
- data/docs/api/streaming/events.md +114 -166
- data/docs/api/streaming/index.md +74 -72
- data/docs/architecture/core-concepts.md +360 -116
- data/docs/architecture/index.md +97 -59
- data/docs/architecture/message-flow.md +138 -129
- data/docs/architecture/network-orchestration.md +197 -50
- data/docs/architecture/robot-execution.md +199 -146
- data/docs/architecture/state-management.md +255 -187
- data/docs/concepts.md +311 -49
- data/docs/examples/basic-chat.md +89 -77
- data/docs/examples/index.md +222 -47
- data/docs/examples/mcp-server.md +207 -203
- data/docs/examples/multi-robot-network.md +129 -35
- data/docs/examples/rails-application.md +159 -160
- data/docs/examples/tool-usage.md +295 -204
- data/docs/getting-started/configuration.md +347 -154
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/installation.md +22 -13
- data/docs/getting-started/quick-start.md +166 -121
- data/docs/guides/building-robots.md +418 -212
- data/docs/guides/creating-networks.md +143 -24
- data/docs/guides/index.md +0 -5
- data/docs/guides/mcp-integration.md +152 -113
- data/docs/guides/memory.md +220 -164
- data/docs/guides/rails-integration.md +244 -162
- data/docs/guides/streaming.md +137 -187
- data/docs/guides/using-tools.md +259 -212
- data/docs/index.md +46 -41
- data/examples/01_simple_robot.rb +6 -9
- data/examples/02_tools.rb +6 -9
- data/examples/03_network.rb +19 -17
- data/examples/04_mcp.rb +5 -8
- data/examples/05_streaming.rb +5 -8
- data/examples/06_prompt_templates.rb +42 -37
- data/examples/07_network_memory.rb +13 -14
- data/examples/08_llm_config.rb +169 -0
- data/examples/09_chaining.rb +262 -0
- data/examples/10_memory.rb +331 -0
- data/examples/11_network_introspection.rb +253 -0
- data/examples/12_message_bus.rb +74 -0
- data/examples/13_spawn.rb +90 -0
- data/examples/14_rusty_circuit/comic.rb +143 -0
- data/examples/14_rusty_circuit/display.rb +203 -0
- data/examples/14_rusty_circuit/heckler.rb +63 -0
- data/examples/14_rusty_circuit/open_mic.rb +123 -0
- data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
- data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
- data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
- data/examples/14_rusty_circuit/scout.rb +156 -0
- data/examples/14_rusty_circuit/scout_notes.md +89 -0
- data/examples/14_rusty_circuit/show.log +234 -0
- data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
- data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
- data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
- data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
- data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
- data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
- data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
- data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
- data/examples/15_memory_network_and_bus/output/memory.json +13 -0
- data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
- data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
- data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
- data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
- data/examples/16_writers_room/display.rb +158 -0
- data/examples/16_writers_room/output/.gitignore +2 -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/prompts/writer.md +37 -0
- data/examples/16_writers_room/room.rb +150 -0
- data/examples/16_writers_room/tools.rb +162 -0
- data/examples/16_writers_room/writer.rb +121 -0
- data/examples/16_writers_room/writers_room.rb +162 -0
- data/examples/README.md +197 -0
- data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
- data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
- data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
- data/examples/prompts/comedian.md +6 -0
- data/examples/prompts/comedy_critic.md +10 -0
- data/examples/prompts/configurable.md +9 -0
- data/examples/prompts/dispatcher.md +12 -0
- data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
- data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
- data/examples/prompts/frontmatter_mcp_test.md +9 -0
- data/examples/prompts/frontmatter_named_test.md +5 -0
- data/examples/prompts/frontmatter_tools_test.md +6 -0
- data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
- data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
- data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
- data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
- data/examples/prompts/llm_config_demo.md +20 -0
- data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
- data/examples/prompts/os_advocate.md +13 -0
- data/examples/prompts/os_chief.md +13 -0
- data/examples/prompts/os_editor.md +13 -0
- data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
- data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
- data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
- data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
- data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
- data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
- data/lib/robot_lab/ask_user.rb +75 -0
- data/lib/robot_lab/config/defaults.yml +121 -0
- data/lib/robot_lab/config.rb +183 -0
- data/lib/robot_lab/error.rb +6 -0
- data/lib/robot_lab/mcp/client.rb +1 -1
- data/lib/robot_lab/memory.rb +10 -34
- 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 +240 -330
- data/lib/robot_lab/robot_message.rb +44 -0
- data/lib/robot_lab/robot_result.rb +1 -0
- data/lib/robot_lab/run_config.rb +184 -0
- data/lib/robot_lab/state_proxy.rb +2 -12
- data/lib/robot_lab/streaming/context.rb +1 -1
- data/lib/robot_lab/task.rb +8 -1
- data/lib/robot_lab/tool.rb +108 -172
- data/lib/robot_lab/tool_config.rb +1 -1
- data/lib/robot_lab/tool_manifest.rb +2 -18
- data/lib/robot_lab/utils.rb +39 -0
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +89 -57
- data/mkdocs.yml +0 -11
- metadata +121 -135
- 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 -195
- data/docs/api/history/config.md +0 -191
- data/docs/api/history/index.md +0 -132
- data/docs/api/history/thread-manager.md +0 -144
- data/docs/guides/history.md +0 -359
- data/examples/prompts/assistant/user.txt.erb +0 -1
- data/examples/prompts/billing/user.txt.erb +0 -1
- data/examples/prompts/classifier/user.txt.erb +0 -1
- data/examples/prompts/entity_extractor/user.txt.erb +0 -3
- data/examples/prompts/escalation/user.txt.erb +0 -34
- data/examples/prompts/general/user.txt.erb +0 -1
- data/examples/prompts/github_assistant/user.txt.erb +0 -1
- data/examples/prompts/helper/user.txt.erb +0 -1
- data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
- data/examples/prompts/order_support/user.txt.erb +0 -22
- data/examples/prompts/product_support/user.txt.erb +0 -32
- data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
- data/examples/prompts/synthesizer/user.txt.erb +0 -15
- data/examples/prompts/technical/user.txt.erb +0 -1
- data/examples/prompts/triage/user.txt.erb +0 -17
- 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 -159
- data/lib/robot_lab/adapters/registry.rb +0 -81
- data/lib/robot_lab/configuration.rb +0 -143
- 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
data/docs/api/core/tool.md
CHANGED
|
@@ -2,27 +2,67 @@
|
|
|
2
2
|
|
|
3
3
|
Callable function that robots can use to interact with external systems.
|
|
4
4
|
|
|
5
|
-
## Class: `RobotLab::Tool`
|
|
5
|
+
## Class: `RobotLab::Tool < RubyLLM::Tool`
|
|
6
|
+
|
|
7
|
+
RobotLab::Tool inherits from RubyLLM::Tool, adding a `robot:` constructor parameter and a `Tool.create` factory for dynamic tools.
|
|
8
|
+
|
|
9
|
+
### Subclass Pattern
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
class GetWeather < RobotLab::Tool
|
|
13
|
+
description "Get weather for a location"
|
|
14
|
+
|
|
15
|
+
param :location, type: "string", desc: "City name or zip code"
|
|
16
|
+
param :unit, type: "string", desc: "Temperature unit", required: false
|
|
17
|
+
|
|
18
|
+
def execute(location:, unit: "celsius")
|
|
19
|
+
WeatherService.current(location, unit: unit)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Factory Pattern
|
|
6
25
|
|
|
7
26
|
```ruby
|
|
8
|
-
tool = RobotLab::Tool.
|
|
27
|
+
tool = RobotLab::Tool.create(
|
|
9
28
|
name: "get_weather",
|
|
10
|
-
description: "Get weather for a location",
|
|
11
|
-
parameters: {
|
|
12
|
-
|
|
13
|
-
|
|
29
|
+
description: "Get current weather for a location",
|
|
30
|
+
parameters: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
location: { type: "string", description: "City name" }
|
|
34
|
+
},
|
|
35
|
+
required: ["location"]
|
|
36
|
+
}
|
|
37
|
+
) { |args| WeatherService.current(args[:location]) }
|
|
14
38
|
```
|
|
15
39
|
|
|
16
40
|
## Constructor
|
|
17
41
|
|
|
18
42
|
```ruby
|
|
19
|
-
Tool.new(
|
|
43
|
+
Tool.new(robot: nil)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Parameters:**
|
|
47
|
+
|
|
48
|
+
| Name | Type | Description |
|
|
49
|
+
|------|------|-------------|
|
|
50
|
+
| `robot` | `Robot, nil` | The owning robot instance |
|
|
51
|
+
|
|
52
|
+
## Class Methods
|
|
53
|
+
|
|
54
|
+
### Tool.create
|
|
55
|
+
|
|
56
|
+
Factory for dynamic tools (MCP wrappers, inline tools).
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
Tool.create(
|
|
20
60
|
name:,
|
|
21
61
|
description: nil,
|
|
22
|
-
parameters:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
62
|
+
parameters: nil,
|
|
63
|
+
mcp: nil,
|
|
64
|
+
robot: nil,
|
|
65
|
+
&handler
|
|
26
66
|
)
|
|
27
67
|
```
|
|
28
68
|
|
|
@@ -30,321 +70,277 @@ Tool.new(
|
|
|
30
70
|
|
|
31
71
|
| Name | Type | Description |
|
|
32
72
|
|------|------|-------------|
|
|
33
|
-
| `name` | `String` | Tool identifier |
|
|
73
|
+
| `name` | `String, Symbol` | Tool identifier |
|
|
34
74
|
| `description` | `String` | What the tool does |
|
|
35
|
-
| `parameters` | `Hash` |
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
75
|
+
| `parameters` | `Hash` | JSON Schema parameter definition |
|
|
76
|
+
| `mcp` | `String` | MCP server name |
|
|
77
|
+
| `robot` | `Robot` | Owning robot instance |
|
|
78
|
+
| `&handler` | `Block` | Receives `args` hash, returns result |
|
|
39
79
|
|
|
40
|
-
##
|
|
80
|
+
## Inherited DSL (from RubyLLM::Tool)
|
|
41
81
|
|
|
42
|
-
###
|
|
82
|
+
### description
|
|
43
83
|
|
|
44
84
|
```ruby
|
|
45
|
-
|
|
85
|
+
class MyTool < RobotLab::Tool
|
|
86
|
+
description "What this tool does"
|
|
87
|
+
end
|
|
46
88
|
```
|
|
47
89
|
|
|
48
|
-
|
|
90
|
+
### param
|
|
49
91
|
|
|
50
|
-
|
|
92
|
+
```ruby
|
|
93
|
+
class MyTool < RobotLab::Tool
|
|
94
|
+
param :name, type: "string", desc: "User's name"
|
|
95
|
+
param :age, type: "integer", desc: "User's age", required: false
|
|
96
|
+
end
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### execute
|
|
51
100
|
|
|
52
101
|
```ruby
|
|
53
|
-
|
|
102
|
+
class MyTool < RobotLab::Tool
|
|
103
|
+
def execute(name:, age: nil)
|
|
104
|
+
# Implementation
|
|
105
|
+
end
|
|
106
|
+
end
|
|
54
107
|
```
|
|
55
108
|
|
|
56
|
-
|
|
109
|
+
### halt
|
|
57
110
|
|
|
58
|
-
|
|
111
|
+
Stop the tool use loop from within execute:
|
|
59
112
|
|
|
60
113
|
```ruby
|
|
61
|
-
|
|
114
|
+
def execute(**)
|
|
115
|
+
halt("Done processing")
|
|
116
|
+
end
|
|
62
117
|
```
|
|
63
118
|
|
|
64
|
-
|
|
119
|
+
### with_params
|
|
65
120
|
|
|
66
|
-
|
|
121
|
+
Set provider-specific parameters:
|
|
67
122
|
|
|
68
123
|
```ruby
|
|
69
|
-
|
|
124
|
+
class MyTool < RobotLab::Tool
|
|
125
|
+
with_params(strict: true)
|
|
126
|
+
end
|
|
70
127
|
```
|
|
71
128
|
|
|
72
|
-
|
|
129
|
+
## Attributes
|
|
73
130
|
|
|
74
|
-
###
|
|
131
|
+
### robot
|
|
75
132
|
|
|
76
133
|
```ruby
|
|
77
|
-
tool.
|
|
134
|
+
tool.robot # => Robot or nil
|
|
135
|
+
tool.robot = some_robot
|
|
78
136
|
```
|
|
79
137
|
|
|
80
|
-
|
|
138
|
+
Read/write accessor for the owning robot. Set via constructor or assigned later.
|
|
81
139
|
|
|
82
|
-
###
|
|
140
|
+
### mcp
|
|
83
141
|
|
|
84
142
|
```ruby
|
|
85
|
-
tool.
|
|
143
|
+
tool.mcp # => String or nil
|
|
86
144
|
```
|
|
87
145
|
|
|
88
|
-
|
|
146
|
+
The MCP server name, set via `Tool.create(mcp: "server_name")`.
|
|
89
147
|
|
|
90
148
|
## Methods
|
|
91
149
|
|
|
92
|
-
###
|
|
150
|
+
### name
|
|
93
151
|
|
|
94
152
|
```ruby
|
|
95
|
-
|
|
96
|
-
params,
|
|
97
|
-
robot: robot,
|
|
98
|
-
network: network,
|
|
99
|
-
state: state
|
|
100
|
-
)
|
|
153
|
+
tool.name # => String
|
|
101
154
|
```
|
|
102
155
|
|
|
103
|
-
|
|
156
|
+
Returns the tool name. For subclasses, derived from the class name (CamelCase to snake_case). For `create`d tools, returns the explicit name.
|
|
104
157
|
|
|
105
|
-
###
|
|
158
|
+
### mcp?
|
|
106
159
|
|
|
107
160
|
```ruby
|
|
108
|
-
tool.
|
|
161
|
+
tool.mcp? # => Boolean
|
|
109
162
|
```
|
|
110
163
|
|
|
111
|
-
|
|
164
|
+
Whether this is an MCP-provided tool.
|
|
112
165
|
|
|
113
|
-
###
|
|
166
|
+
### call
|
|
114
167
|
|
|
115
168
|
```ruby
|
|
116
|
-
tool.
|
|
169
|
+
result = tool.call(args_hash)
|
|
117
170
|
```
|
|
118
171
|
|
|
119
|
-
|
|
172
|
+
Inherited from RubyLLM::Tool. Converts string keys to symbols and calls `execute(**args)`.
|
|
120
173
|
|
|
121
|
-
###
|
|
174
|
+
### params_schema
|
|
122
175
|
|
|
123
176
|
```ruby
|
|
124
|
-
tool.
|
|
177
|
+
tool.params_schema # => Hash or nil
|
|
125
178
|
```
|
|
126
179
|
|
|
127
|
-
JSON Schema
|
|
128
|
-
|
|
129
|
-
## Parameter Schema
|
|
180
|
+
Inherited. Returns the JSON Schema for tool parameters.
|
|
130
181
|
|
|
131
|
-
###
|
|
182
|
+
### provider_params
|
|
132
183
|
|
|
133
184
|
```ruby
|
|
134
|
-
|
|
135
|
-
name: { type: "string" },
|
|
136
|
-
count: { type: "integer" },
|
|
137
|
-
price: { type: "number" },
|
|
138
|
-
active: { type: "boolean" },
|
|
139
|
-
tags: { type: "array" }
|
|
140
|
-
}
|
|
185
|
+
tool.provider_params # => Hash
|
|
141
186
|
```
|
|
142
187
|
|
|
143
|
-
|
|
188
|
+
Inherited. Returns provider-specific parameters (e.g., `{ strict: true }`).
|
|
189
|
+
|
|
190
|
+
### to_h
|
|
144
191
|
|
|
145
192
|
```ruby
|
|
146
|
-
|
|
147
|
-
id: { type: "string", required: true }
|
|
148
|
-
}
|
|
193
|
+
tool.to_h # => Hash
|
|
149
194
|
```
|
|
150
195
|
|
|
151
|
-
|
|
196
|
+
Hash representation with `:name`, `:description`, `:mcp`.
|
|
197
|
+
|
|
198
|
+
### to_json
|
|
152
199
|
|
|
153
200
|
```ruby
|
|
154
|
-
|
|
155
|
-
query: {
|
|
156
|
-
type: "string",
|
|
157
|
-
description: "Search query (supports wildcards)"
|
|
158
|
-
}
|
|
159
|
-
}
|
|
201
|
+
tool.to_json # => String
|
|
160
202
|
```
|
|
161
203
|
|
|
162
|
-
|
|
204
|
+
JSON representation.
|
|
205
|
+
|
|
206
|
+
### to_json_schema
|
|
163
207
|
|
|
164
208
|
```ruby
|
|
165
|
-
|
|
166
|
-
status: {
|
|
167
|
-
type: "string",
|
|
168
|
-
enum: ["pending", "active", "completed"]
|
|
169
|
-
}
|
|
170
|
-
}
|
|
209
|
+
tool.to_json_schema # => Hash
|
|
171
210
|
```
|
|
172
211
|
|
|
173
|
-
|
|
212
|
+
JSON Schema representation for LLM function calling. Returns `{ name:, description:, parameters: }`.
|
|
213
|
+
|
|
214
|
+
## Robot-Aware Tools
|
|
215
|
+
|
|
216
|
+
Tools that modify their owning robot use the `robot` accessor:
|
|
174
217
|
|
|
175
218
|
```ruby
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
219
|
+
class AdjustTemperature < RobotLab::Tool
|
|
220
|
+
description "Adjust the robot's creativity level"
|
|
221
|
+
|
|
222
|
+
param :level, type: "number", desc: "Temperature from 0.0 to 1.0"
|
|
223
|
+
|
|
224
|
+
def execute(level:)
|
|
225
|
+
robot.with_temperature(level)
|
|
226
|
+
"Temperature adjusted to #{level}"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Pass robot: self when constructing
|
|
231
|
+
robot = RobotLab.build(
|
|
232
|
+
name: "creative_bot",
|
|
233
|
+
system_prompt: "You are creative.",
|
|
234
|
+
local_tools: [AdjustTemperature.new(robot: self)]
|
|
235
|
+
)
|
|
182
236
|
```
|
|
183
237
|
|
|
184
|
-
##
|
|
238
|
+
## Parameter Types
|
|
185
239
|
|
|
186
|
-
###
|
|
240
|
+
### String
|
|
187
241
|
|
|
188
242
|
```ruby
|
|
189
|
-
|
|
190
|
-
do_something(param)
|
|
191
|
-
}
|
|
243
|
+
param :name, type: "string", desc: "User's full name"
|
|
192
244
|
```
|
|
193
245
|
|
|
194
|
-
###
|
|
246
|
+
### Integer
|
|
195
247
|
|
|
196
248
|
```ruby
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
# network - The NetworkRun
|
|
200
|
-
# state - Current State
|
|
249
|
+
param :count, type: "integer", desc: "Number of results"
|
|
250
|
+
```
|
|
201
251
|
|
|
202
|
-
|
|
203
|
-
state.memory.remember("last_action", param)
|
|
252
|
+
### Number (Float)
|
|
204
253
|
|
|
205
|
-
|
|
206
|
-
|
|
254
|
+
```ruby
|
|
255
|
+
param :price, type: "number", desc: "Price in dollars"
|
|
207
256
|
```
|
|
208
257
|
|
|
209
|
-
###
|
|
258
|
+
### Boolean
|
|
210
259
|
|
|
211
260
|
```ruby
|
|
212
|
-
|
|
213
|
-
record = Record.find_by(id: id)
|
|
214
|
-
|
|
215
|
-
if record
|
|
216
|
-
{ success: true, data: record.to_h }
|
|
217
|
-
else
|
|
218
|
-
{ success: false, error: "Not found" }
|
|
219
|
-
end
|
|
220
|
-
rescue StandardError => e
|
|
221
|
-
{ success: false, error: e.message }
|
|
222
|
-
}
|
|
261
|
+
param :active, type: "boolean", desc: "Whether the user is active"
|
|
223
262
|
```
|
|
224
263
|
|
|
225
|
-
|
|
264
|
+
### Required vs Optional
|
|
226
265
|
|
|
227
|
-
|
|
266
|
+
Parameters are required by default. Mark optional with `required: false`:
|
|
228
267
|
|
|
229
268
|
```ruby
|
|
230
|
-
|
|
231
|
-
|
|
269
|
+
param :query, type: "string", desc: "Search query" # required
|
|
270
|
+
param :limit, type: "integer", desc: "Max results", required: false # optional
|
|
271
|
+
```
|
|
232
272
|
|
|
233
|
-
|
|
234
|
-
parameter :param2, type: :integer, default: 10
|
|
273
|
+
## Built-in: AskUser
|
|
235
274
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
275
|
+
`RobotLab::AskUser` is a built-in tool that lets a robot ask the user a question via the terminal. The LLM decides when human input is needed and calls this tool.
|
|
276
|
+
|
|
277
|
+
### Class: `RobotLab::AskUser < RobotLab::Tool`
|
|
278
|
+
|
|
279
|
+
```ruby
|
|
280
|
+
class RobotLab::AskUser < RobotLab::Tool
|
|
281
|
+
description "Ask the user a question and wait for their typed response"
|
|
282
|
+
param :question, type: "string", desc: "The question to ask the user"
|
|
283
|
+
param :choices, type: "array", desc: "Optional list of choices to present", required: false
|
|
284
|
+
param :default, type: "string", desc: "Default value if user presses Enter", required: false
|
|
239
285
|
end
|
|
240
286
|
```
|
|
241
287
|
|
|
242
|
-
|
|
288
|
+
### Parameters
|
|
243
289
|
|
|
244
|
-
|
|
290
|
+
| Name | Type | Required | Description |
|
|
291
|
+
|------|------|----------|-------------|
|
|
292
|
+
| `question` | `String` | Yes | The question to display |
|
|
293
|
+
| `choices` | `Array` | No | Numbered choices to present |
|
|
294
|
+
| `default` | `String` | No | Value returned when user presses Enter without typing |
|
|
245
295
|
|
|
246
|
-
|
|
247
|
-
manifest = RobotLab::ToolManifest.new(
|
|
248
|
-
tool: original_tool,
|
|
249
|
-
name: "custom_name",
|
|
250
|
-
description: "Custom description"
|
|
251
|
-
)
|
|
296
|
+
### IO Resolution
|
|
252
297
|
|
|
253
|
-
|
|
254
|
-
```
|
|
298
|
+
The tool reads input and writes output using the owning robot's `input`/`output` accessors:
|
|
255
299
|
|
|
256
|
-
|
|
300
|
+
1. `robot.input` / `robot.output` if set
|
|
301
|
+
2. Falls back to `$stdin` / `$stdout`
|
|
257
302
|
|
|
258
|
-
|
|
259
|
-
- `name` - Override name (or original)
|
|
260
|
-
- `description` - Override description (or original)
|
|
261
|
-
- `aliases` - Alternative names
|
|
303
|
+
### Terminal Output
|
|
262
304
|
|
|
263
|
-
|
|
305
|
+
```
|
|
306
|
+
[robot_name] What programming language do you want to learn?
|
|
307
|
+
1. Ruby
|
|
308
|
+
2. Python
|
|
309
|
+
3. Go
|
|
310
|
+
> [Ruby]
|
|
311
|
+
```
|
|
264
312
|
|
|
265
|
-
###
|
|
313
|
+
### Usage
|
|
266
314
|
|
|
267
315
|
```ruby
|
|
268
|
-
|
|
269
|
-
name: "
|
|
270
|
-
|
|
271
|
-
|
|
316
|
+
robot = RobotLab.build(
|
|
317
|
+
name: "interviewer",
|
|
318
|
+
system_prompt: "Interview the user about their project needs. Use ask_user to gather information.",
|
|
319
|
+
local_tools: [RobotLab::AskUser]
|
|
272
320
|
)
|
|
321
|
+
robot.run("Find out what the user wants to build")
|
|
273
322
|
```
|
|
274
323
|
|
|
275
|
-
###
|
|
324
|
+
### Testing with StringIO
|
|
276
325
|
|
|
277
326
|
```ruby
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
required: true
|
|
286
|
-
},
|
|
287
|
-
limit: {
|
|
288
|
-
type: "integer",
|
|
289
|
-
description: "Max results",
|
|
290
|
-
default: 10
|
|
291
|
-
},
|
|
292
|
-
status: {
|
|
293
|
-
type: "string",
|
|
294
|
-
enum: ["active", "inactive", "all"],
|
|
295
|
-
default: "active"
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
handler: ->(query:, limit:, status:, **_) {
|
|
299
|
-
User.search(query, limit: limit, status: status)
|
|
300
|
-
}
|
|
301
|
-
)
|
|
327
|
+
robot = RobotLab::Robot.new(name: "bot", template: :assistant)
|
|
328
|
+
robot.input = StringIO.new("Ruby\n")
|
|
329
|
+
robot.output = StringIO.new
|
|
330
|
+
|
|
331
|
+
tool = RobotLab::AskUser.new(robot: robot)
|
|
332
|
+
result = tool.call("question" => "Pick a language:", "choices" => ["Ruby", "Python"])
|
|
333
|
+
# => "Ruby"
|
|
302
334
|
```
|
|
303
335
|
|
|
304
|
-
###
|
|
336
|
+
### Choice Mapping
|
|
305
337
|
|
|
306
|
-
|
|
307
|
-
tool = Tool.new(
|
|
308
|
-
name: "fetch_stock_price",
|
|
309
|
-
description: "Get current stock price",
|
|
310
|
-
parameters: {
|
|
311
|
-
symbol: { type: "string", required: true }
|
|
312
|
-
},
|
|
313
|
-
handler: ->(symbol:, **_) {
|
|
314
|
-
response = HTTP.get("https://api.stocks.example/#{symbol}")
|
|
315
|
-
|
|
316
|
-
if response.status.success?
|
|
317
|
-
JSON.parse(response.body)
|
|
318
|
-
else
|
|
319
|
-
{ error: "Failed to fetch", status: response.status.code }
|
|
320
|
-
end
|
|
321
|
-
rescue HTTP::Error => e
|
|
322
|
-
{ error: "Network error: #{e.message}" }
|
|
323
|
-
}
|
|
324
|
-
)
|
|
325
|
-
```
|
|
338
|
+
When `choices` are provided, the user can type either:
|
|
326
339
|
|
|
327
|
-
|
|
340
|
+
- A **number** (e.g., `2`) — mapped to the corresponding choice text
|
|
341
|
+
- **Text** (e.g., `Python`) — returned as-is
|
|
328
342
|
|
|
329
|
-
|
|
330
|
-
tool = Tool.new(
|
|
331
|
-
name: "get_order",
|
|
332
|
-
description: "Get order details",
|
|
333
|
-
parameters: {
|
|
334
|
-
order_id: { type: "string", required: true }
|
|
335
|
-
},
|
|
336
|
-
handler: ->(order_id:, state:, **_) {
|
|
337
|
-
user_id = state.data[:user_id]
|
|
338
|
-
order = Order.find_by(id: order_id, user_id: user_id)
|
|
339
|
-
|
|
340
|
-
if order
|
|
341
|
-
order.as_json(include: [:items, :shipping])
|
|
342
|
-
else
|
|
343
|
-
{ error: "Order not found or unauthorized" }
|
|
344
|
-
end
|
|
345
|
-
}
|
|
346
|
-
)
|
|
347
|
-
```
|
|
343
|
+
Out-of-range numbers are returned as-is (the LLM can re-ask if needed).
|
|
348
344
|
|
|
349
345
|
## See Also
|
|
350
346
|
|
data/docs/api/index.md
CHANGED
|
@@ -10,9 +10,8 @@ The fundamental building blocks of RobotLab:
|
|
|
10
10
|
|-------|-------------|
|
|
11
11
|
| [Robot](core/robot.md) | LLM-powered agent with personality and tools |
|
|
12
12
|
| [Network](core/network.md) | Orchestrates multiple robots |
|
|
13
|
-
| [
|
|
13
|
+
| [Memory](core/memory.md) | Reactive key-value store for sharing data |
|
|
14
14
|
| [Tool](core/tool.md) | Custom function robots can call |
|
|
15
|
-
| [Memory](core/memory.md) | Shared key-value store |
|
|
16
15
|
|
|
17
16
|
## Messages
|
|
18
17
|
|
|
@@ -21,20 +20,10 @@ Message types for LLM communication:
|
|
|
21
20
|
| Class | Description |
|
|
22
21
|
|-------|-------------|
|
|
23
22
|
| [UserMessage](messages/user-message.md) | User input with metadata |
|
|
24
|
-
| [TextMessage](messages/text-message.md) |
|
|
23
|
+
| [TextMessage](messages/text-message.md) | Text message with role |
|
|
25
24
|
| [ToolCallMessage](messages/tool-call-message.md) | Tool execution request |
|
|
26
25
|
| [ToolResultMessage](messages/tool-result-message.md) | Tool execution result |
|
|
27
26
|
|
|
28
|
-
## Adapters
|
|
29
|
-
|
|
30
|
-
Provider-specific message conversion:
|
|
31
|
-
|
|
32
|
-
| Class | Description |
|
|
33
|
-
|-------|-------------|
|
|
34
|
-
| [Anthropic](adapters/anthropic.md) | Claude models adapter |
|
|
35
|
-
| [OpenAI](adapters/openai.md) | GPT models adapter |
|
|
36
|
-
| [Gemini](adapters/gemini.md) | Google Gemini adapter |
|
|
37
|
-
|
|
38
27
|
## MCP (Model Context Protocol)
|
|
39
28
|
|
|
40
29
|
Connect to external tool servers:
|
|
@@ -54,29 +43,19 @@ Real-time response streaming:
|
|
|
54
43
|
| [Context](streaming/context.md) | Streaming context |
|
|
55
44
|
| [Events](streaming/events.md) | Event utilities |
|
|
56
45
|
|
|
57
|
-
## History
|
|
58
|
-
|
|
59
|
-
Conversation persistence:
|
|
60
|
-
|
|
61
|
-
| Class | Description |
|
|
62
|
-
|-------|-------------|
|
|
63
|
-
| [Config](history/config.md) | History configuration |
|
|
64
|
-
| [ThreadManager](history/thread-manager.md) | Thread lifecycle |
|
|
65
|
-
| [ActiveRecordAdapter](history/active-record-adapter.md) | Rails adapter |
|
|
66
|
-
|
|
67
46
|
## Module Methods
|
|
68
47
|
|
|
69
48
|
### RobotLab
|
|
70
49
|
|
|
71
50
|
```ruby
|
|
72
51
|
# Configuration
|
|
73
|
-
RobotLab.
|
|
74
|
-
RobotLab.
|
|
52
|
+
RobotLab.config # => Config instance
|
|
53
|
+
RobotLab.reload_config! # => reload from all sources
|
|
75
54
|
|
|
76
55
|
# Building
|
|
77
|
-
RobotLab.build
|
|
78
|
-
RobotLab.create_network { ... }
|
|
79
|
-
RobotLab.
|
|
56
|
+
RobotLab.build(name:, template:, system_prompt:, context:, **options)
|
|
57
|
+
RobotLab.create_network(name:, concurrency:) { ... }
|
|
58
|
+
RobotLab.create_memory(data:, enable_cache:, **options)
|
|
80
59
|
```
|
|
81
60
|
|
|
82
61
|
See individual class documentation for detailed method references.
|