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
|
@@ -1,226 +1,419 @@
|
|
|
1
1
|
# Configuration
|
|
2
2
|
|
|
3
|
-
RobotLab
|
|
3
|
+
RobotLab uses a layered configuration system powered by [MywayConfig](https://github.com/MadBomber/myway_config). Configuration is loaded automatically from multiple sources with no block-style `configure` method required.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## How Configuration Works
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Configuration values are loaded in priority order (lowest to highest):
|
|
8
|
+
|
|
9
|
+
1. **Bundled defaults** -- `lib/robot_lab/config/defaults.yml` (shipped with the gem)
|
|
10
|
+
2. **Environment-specific overrides** -- `development`, `test`, or `production` sections in defaults.yml
|
|
11
|
+
3. **User config file** -- `~/.config/robot_lab/config.yml`
|
|
12
|
+
4. **Project config file** -- `./config/robot_lab.yml`
|
|
13
|
+
5. **Environment variables** -- `ROBOT_LAB_*` prefix
|
|
14
|
+
6. **Runtime attributes** -- e.g., `RobotLab.config.logger = ...`
|
|
15
|
+
|
|
16
|
+
Higher-priority sources override lower-priority ones. You only need to set the values you want to change.
|
|
17
|
+
|
|
18
|
+
## Accessing Configuration
|
|
19
|
+
|
|
20
|
+
Use `RobotLab.config` to access the configuration object:
|
|
8
21
|
|
|
9
22
|
```ruby
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
# Access nested values with dot notation
|
|
24
|
+
RobotLab.config.ruby_llm.model #=> "claude-sonnet-4"
|
|
25
|
+
RobotLab.config.ruby_llm.anthropic_api_key #=> "sk-ant-..."
|
|
26
|
+
RobotLab.config.ruby_llm.request_timeout #=> 120
|
|
27
|
+
RobotLab.config.max_iterations #=> 10
|
|
28
|
+
RobotLab.config.streaming_enabled #=> true
|
|
29
|
+
|
|
30
|
+
# Check the environment
|
|
31
|
+
RobotLab.config.development? #=> true/false
|
|
32
|
+
```
|
|
15
33
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
config.default_model = "claude-sonnet-4"
|
|
34
|
+
!!! warning "No configure block"
|
|
35
|
+
RobotLab does **not** use a `RobotLab.configure do |config| ... end` pattern. All configuration comes from config files, environment variables, or direct assignment on `RobotLab.config`.
|
|
19
36
|
|
|
20
|
-
|
|
21
|
-
config.max_iterations = 10 # Max robots per network run
|
|
22
|
-
config.max_tool_iterations = 10 # Max tool calls per robot run
|
|
37
|
+
## Environment Variables
|
|
23
38
|
|
|
24
|
-
|
|
25
|
-
config.streaming_enabled = true
|
|
39
|
+
Environment variables use the `ROBOT_LAB_` prefix. Use double underscores (`__`) for nested values:
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
```bash
|
|
42
|
+
# Top-level settings
|
|
43
|
+
export ROBOT_LAB_MAX_ITERATIONS=20
|
|
44
|
+
export ROBOT_LAB_STREAMING_ENABLED=false
|
|
45
|
+
|
|
46
|
+
# Nested ruby_llm settings (note the double underscore)
|
|
47
|
+
export ROBOT_LAB_RUBY_LLM__MODEL=claude-sonnet-4
|
|
48
|
+
export ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...
|
|
49
|
+
export ROBOT_LAB_RUBY_LLM__OPENAI_API_KEY=sk-...
|
|
50
|
+
export ROBOT_LAB_RUBY_LLM__GEMINI_API_KEY=...
|
|
51
|
+
export ROBOT_LAB_RUBY_LLM__REQUEST_TIMEOUT=180
|
|
52
|
+
export ROBOT_LAB_RUBY_LLM__MAX_RETRIES=5
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The double underscore convention maps to nested YAML structure:
|
|
29
56
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
57
|
+
```
|
|
58
|
+
ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY --> ruby_llm.anthropic_api_key
|
|
59
|
+
ROBOT_LAB_RUBY_LLM__MODEL --> ruby_llm.model
|
|
60
|
+
ROBOT_LAB_MAX_ITERATIONS --> max_iterations
|
|
33
61
|
```
|
|
34
62
|
|
|
35
|
-
##
|
|
63
|
+
## Config Files
|
|
36
64
|
|
|
37
|
-
###
|
|
65
|
+
### Project Config
|
|
38
66
|
|
|
39
|
-
|
|
40
|
-
|--------|-------------|
|
|
41
|
-
| `anthropic_api_key` | Anthropic Claude API key |
|
|
42
|
-
| `openai_api_key` | OpenAI API key |
|
|
43
|
-
| `gemini_api_key` | Google Gemini API key |
|
|
44
|
-
| `bedrock_api_key` | AWS Bedrock API key |
|
|
45
|
-
| `openrouter_api_key` | OpenRouter API key |
|
|
67
|
+
Create `./config/robot_lab.yml` in your project root:
|
|
46
68
|
|
|
47
|
-
|
|
69
|
+
```yaml title="config/robot_lab.yml"
|
|
70
|
+
defaults:
|
|
71
|
+
ruby_llm:
|
|
72
|
+
anthropic_api_key: <%= ENV['ANTHROPIC_API_KEY'] %>
|
|
73
|
+
model: claude-sonnet-4
|
|
74
|
+
request_timeout: 120
|
|
48
75
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
max_iterations: 15
|
|
77
|
+
template_path: prompts
|
|
78
|
+
|
|
79
|
+
development:
|
|
80
|
+
ruby_llm:
|
|
81
|
+
log_level: :debug
|
|
82
|
+
|
|
83
|
+
test:
|
|
84
|
+
max_iterations: 3
|
|
85
|
+
streaming_enabled: false
|
|
86
|
+
ruby_llm:
|
|
87
|
+
model: claude-haiku-3-5
|
|
88
|
+
request_timeout: 30
|
|
89
|
+
max_retries: 1
|
|
90
|
+
|
|
91
|
+
production:
|
|
92
|
+
max_iterations: 20
|
|
93
|
+
ruby_llm:
|
|
94
|
+
request_timeout: 180
|
|
95
|
+
max_retries: 5
|
|
96
|
+
log_level: :warn
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
!!! tip "ERB support"
|
|
100
|
+
Config files support ERB templating, so you can reference environment variables with `<%= ENV['...'] %>`. This is useful for keeping secrets out of config files while still using YAML structure.
|
|
101
|
+
|
|
102
|
+
### User Config
|
|
103
|
+
|
|
104
|
+
Create `~/.config/robot_lab/config.yml` for personal defaults that apply across all your projects:
|
|
56
105
|
|
|
57
|
-
|
|
106
|
+
```yaml title="~/.config/robot_lab/config.yml"
|
|
107
|
+
defaults:
|
|
108
|
+
ruby_llm:
|
|
109
|
+
anthropic_api_key: <%= ENV['ANTHROPIC_API_KEY'] %>
|
|
110
|
+
model: claude-sonnet-4
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Configuration Reference
|
|
58
114
|
|
|
59
|
-
|
|
60
|
-
|--------|---------|-------------|
|
|
61
|
-
| `template_path` | `"prompts"` (or `"app/prompts"` in Rails) | Directory for prompt templates |
|
|
115
|
+
### Core Settings
|
|
62
116
|
|
|
63
|
-
|
|
117
|
+
| Key | Default | Description |
|
|
118
|
+
|-----|---------|-------------|
|
|
119
|
+
| `max_iterations` | `10` | Maximum robots per network run |
|
|
120
|
+
| `max_tool_iterations` | `10` | Maximum tool calls per robot run |
|
|
121
|
+
| `streaming_enabled` | `true` | Enable streaming by default |
|
|
122
|
+
| `template_path` | `null` (auto-detected) | Directory for prompt templates |
|
|
123
|
+
| `mcp` | `:none` | Global MCP server configuration |
|
|
124
|
+
| `tools` | `:none` | Global tool whitelist |
|
|
125
|
+
|
|
126
|
+
### RubyLLM Settings (`ruby_llm:` section)
|
|
127
|
+
|
|
128
|
+
All settings under the `ruby_llm:` key are applied to `RubyLLM.configure` automatically on startup.
|
|
129
|
+
|
|
130
|
+
#### Provider API Keys
|
|
131
|
+
|
|
132
|
+
| Key | Description |
|
|
133
|
+
|-----|-------------|
|
|
134
|
+
| `ruby_llm.anthropic_api_key` | Anthropic Claude API key |
|
|
135
|
+
| `ruby_llm.openai_api_key` | OpenAI API key |
|
|
136
|
+
| `ruby_llm.gemini_api_key` | Google Gemini API key |
|
|
137
|
+
| `ruby_llm.deepseek_api_key` | DeepSeek API key |
|
|
138
|
+
| `ruby_llm.mistral_api_key` | Mistral API key |
|
|
139
|
+
| `ruby_llm.openrouter_api_key` | OpenRouter API key |
|
|
140
|
+
| `ruby_llm.bedrock_api_key` | AWS Bedrock access key |
|
|
141
|
+
| `ruby_llm.bedrock_secret_key` | AWS Bedrock secret key |
|
|
142
|
+
| `ruby_llm.bedrock_region` | AWS Bedrock region |
|
|
143
|
+
| `ruby_llm.xai_api_key` | xAI (Grok) API key |
|
|
144
|
+
|
|
145
|
+
#### Model Defaults
|
|
146
|
+
|
|
147
|
+
| Key | Default | Description |
|
|
148
|
+
|-----|---------|-------------|
|
|
149
|
+
| `ruby_llm.provider` | `:anthropic` | Default LLM provider |
|
|
150
|
+
| `ruby_llm.model` | `claude-sonnet-4` | Default model for robots |
|
|
151
|
+
| `ruby_llm.default_model` | `null` | RubyLLM default model override |
|
|
152
|
+
| `ruby_llm.default_embedding_model` | `null` | Default embedding model |
|
|
153
|
+
| `ruby_llm.default_image_model` | `null` | Default image model |
|
|
154
|
+
|
|
155
|
+
#### Connection Settings
|
|
156
|
+
|
|
157
|
+
| Key | Default | Description |
|
|
158
|
+
|-----|---------|-------------|
|
|
159
|
+
| `ruby_llm.request_timeout` | `120` | Request timeout in seconds |
|
|
160
|
+
| `ruby_llm.max_retries` | `3` | Maximum retry attempts |
|
|
161
|
+
| `ruby_llm.retry_interval` | `1` | Seconds between retries |
|
|
162
|
+
| `ruby_llm.retry_backoff_factor` | `2` | Exponential backoff factor |
|
|
163
|
+
| `ruby_llm.http_proxy` | `null` | HTTP proxy URL |
|
|
164
|
+
|
|
165
|
+
#### Provider Endpoints (self-hosted models)
|
|
166
|
+
|
|
167
|
+
| Key | Description |
|
|
168
|
+
|-----|-------------|
|
|
169
|
+
| `ruby_llm.openai_api_base` | Custom OpenAI-compatible endpoint |
|
|
170
|
+
| `ruby_llm.gemini_api_base` | Custom Gemini endpoint |
|
|
171
|
+
| `ruby_llm.ollama_api_base` | Ollama endpoint (e.g., `http://localhost:11434`) |
|
|
172
|
+
| `ruby_llm.gpustack_api_base` | GPUStack endpoint |
|
|
173
|
+
|
|
174
|
+
#### Logging
|
|
175
|
+
|
|
176
|
+
| Key | Default | Description |
|
|
177
|
+
|-----|---------|-------------|
|
|
178
|
+
| `ruby_llm.log_file` | `null` | Path to log file |
|
|
179
|
+
| `ruby_llm.log_level` | `:info` | Log level (`:debug`, `:info`, `:warn`, `:error`) |
|
|
180
|
+
| `ruby_llm.log_stream_debug` | `false` | Log streaming debug output |
|
|
181
|
+
|
|
182
|
+
### Chat Configuration (`chat:` section)
|
|
183
|
+
|
|
184
|
+
Default chat parameters applied to all robots unless overridden:
|
|
185
|
+
|
|
186
|
+
| Key | Default | Description |
|
|
187
|
+
|-----|---------|-------------|
|
|
188
|
+
| `chat.with_temperature` | `0.7` | Controls randomness (0.0-2.0) |
|
|
189
|
+
| `chat.with_params.top_p` | `null` | Nucleus sampling threshold |
|
|
190
|
+
| `chat.with_params.top_k` | `null` | Top-k sampling |
|
|
191
|
+
| `chat.with_params.max_tokens` | `null` | Maximum tokens in response |
|
|
192
|
+
| `chat.with_params.presence_penalty` | `null` | Presence penalty (-2.0 to 2.0) |
|
|
193
|
+
| `chat.with_params.frequency_penalty` | `null` | Frequency penalty (-2.0 to 2.0) |
|
|
194
|
+
| `chat.with_params.stop` | `null` | Stop sequences |
|
|
195
|
+
|
|
196
|
+
## Runtime-Only Attributes
|
|
197
|
+
|
|
198
|
+
Some attributes can only be set at runtime, not through config files:
|
|
64
199
|
|
|
65
200
|
```ruby
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{ name: "github", transport: { type: "stdio", command: "github-mcp" } }
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
# Global tool whitelist
|
|
73
|
-
config.tools = %w[search_code create_issue]
|
|
74
|
-
end
|
|
201
|
+
# Logger (defaults to Rails.logger in Rails, or Logger.new($stdout) otherwise)
|
|
202
|
+
RobotLab.config.logger = Logger.new(nil) # silence logging
|
|
203
|
+
RobotLab.config.logger = Logger.new("robot.log") # log to file
|
|
75
204
|
```
|
|
76
205
|
|
|
77
|
-
##
|
|
206
|
+
## Reloading Configuration
|
|
78
207
|
|
|
79
|
-
|
|
208
|
+
To reload configuration from all sources:
|
|
80
209
|
|
|
81
210
|
```ruby
|
|
82
|
-
|
|
83
|
-
|
|
211
|
+
RobotLab.reload_config!
|
|
212
|
+
```
|
|
84
213
|
|
|
85
|
-
|
|
86
|
-
default_model "claude-sonnet-4"
|
|
214
|
+
This clears the cached config and reloads from all sources on next access.
|
|
87
215
|
|
|
88
|
-
|
|
89
|
-
mcp [
|
|
90
|
-
{ name: "filesystem", transport: { type: "stdio", command: "mcp-fs" } }
|
|
91
|
-
]
|
|
216
|
+
## Environment-Specific Configuration
|
|
92
217
|
|
|
93
|
-
|
|
94
|
-
tools %w[read_file write_file]
|
|
218
|
+
The `defaults.yml` shipped with RobotLab includes environment-specific overrides:
|
|
95
219
|
|
|
96
|
-
|
|
97
|
-
mcp :inherit
|
|
98
|
-
tools :inherit
|
|
99
|
-
end
|
|
100
|
-
```
|
|
220
|
+
=== "Development"
|
|
101
221
|
|
|
102
|
-
|
|
222
|
+
```yaml
|
|
223
|
+
development:
|
|
224
|
+
ruby_llm:
|
|
225
|
+
log_level: :debug
|
|
226
|
+
```
|
|
103
227
|
|
|
104
|
-
|
|
228
|
+
=== "Test"
|
|
105
229
|
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
|
|
230
|
+
```yaml
|
|
231
|
+
test:
|
|
232
|
+
max_iterations: 3
|
|
233
|
+
streaming_enabled: false
|
|
234
|
+
ruby_llm:
|
|
235
|
+
model: claude-haiku-3-5
|
|
236
|
+
request_timeout: 30
|
|
237
|
+
max_retries: 1
|
|
238
|
+
log_level: :warn
|
|
239
|
+
```
|
|
109
240
|
|
|
110
|
-
|
|
111
|
-
model "claude-sonnet-4"
|
|
241
|
+
=== "Production"
|
|
112
242
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
243
|
+
```yaml
|
|
244
|
+
production:
|
|
245
|
+
streaming_enabled: false
|
|
246
|
+
max_iterations: 20
|
|
247
|
+
ruby_llm:
|
|
248
|
+
request_timeout: 180
|
|
249
|
+
max_retries: 5
|
|
250
|
+
log_level: :warn
|
|
251
|
+
```
|
|
119
252
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
253
|
+
The current environment is determined automatically (via `RAILS_ENV`, `RACK_ENV`, or defaults to `development`).
|
|
254
|
+
|
|
255
|
+
## Rails Integration
|
|
256
|
+
|
|
257
|
+
In Rails, RobotLab is configured automatically via its Railtie. The logger defaults to `Rails.logger`, and templates default to `app/prompts/`.
|
|
258
|
+
|
|
259
|
+
Create a project config file for Rails-specific settings:
|
|
124
260
|
|
|
125
|
-
|
|
261
|
+
```yaml title="config/robot_lab.yml"
|
|
262
|
+
defaults:
|
|
263
|
+
ruby_llm:
|
|
264
|
+
anthropic_api_key: <%= Rails.application.credentials.anthropic_api_key %>
|
|
265
|
+
model: claude-sonnet-4
|
|
126
266
|
|
|
127
|
-
|
|
267
|
+
template_path: null # auto-detects app/prompts in Rails
|
|
128
268
|
|
|
269
|
+
production:
|
|
270
|
+
ruby_llm:
|
|
271
|
+
request_timeout: 180
|
|
272
|
+
max_retries: 5
|
|
129
273
|
```
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
274
|
+
|
|
275
|
+
You can also use Rails credentials:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
rails credentials:edit
|
|
134
279
|
```
|
|
135
280
|
|
|
136
|
-
|
|
281
|
+
```yaml
|
|
282
|
+
# config/credentials.yml.enc
|
|
283
|
+
anthropic_api_key: sk-ant-...
|
|
284
|
+
openai_api_key: sk-...
|
|
285
|
+
```
|
|
137
286
|
|
|
138
|
-
|
|
139
|
-
- `:none` or `nil` or `[]` - No items allowed
|
|
140
|
-
- `[items]` - Specific items only
|
|
287
|
+
Then reference them in your config file with ERB:
|
|
141
288
|
|
|
142
|
-
|
|
289
|
+
```yaml title="config/robot_lab.yml"
|
|
290
|
+
defaults:
|
|
291
|
+
ruby_llm:
|
|
292
|
+
anthropic_api_key: <%= Rails.application.credentials.anthropic_api_key %>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## RunConfig: Shared Operational Defaults
|
|
143
296
|
|
|
144
|
-
|
|
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:
|
|
145
298
|
|
|
146
|
-
```
|
|
147
|
-
RobotLab.
|
|
148
|
-
|
|
149
|
-
config.anthropic_api_key = Rails.application.credentials.anthropic_api_key
|
|
299
|
+
```
|
|
300
|
+
RobotLab.config (global) -> Network RunConfig -> Robot RunConfig -> Template front matter -> Task RunConfig -> Runtime
|
|
301
|
+
```
|
|
150
302
|
|
|
151
|
-
|
|
152
|
-
config.logger = Rails.logger
|
|
303
|
+
### Creating a RunConfig
|
|
153
304
|
|
|
154
|
-
|
|
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
|
|
155
314
|
end
|
|
315
|
+
|
|
316
|
+
# Chaining
|
|
317
|
+
config = RobotLab::RunConfig.new
|
|
318
|
+
.model("claude-sonnet-4")
|
|
319
|
+
.temperature(0.7)
|
|
156
320
|
```
|
|
157
321
|
|
|
158
|
-
|
|
322
|
+
### Applying RunConfig
|
|
323
|
+
|
|
324
|
+
Pass `config:` to robots and networks. Explicit constructor kwargs always override the RunConfig:
|
|
159
325
|
|
|
160
|
-
```ruby
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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]
|
|
166
342
|
end
|
|
167
343
|
```
|
|
168
344
|
|
|
169
|
-
|
|
345
|
+
### Merging Configs
|
|
170
346
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
when "test"
|
|
180
|
-
config.streaming_enabled = false
|
|
181
|
-
when "production"
|
|
182
|
-
config.logger = Rails.logger
|
|
183
|
-
config.default_model = "claude-sonnet-4"
|
|
184
|
-
end
|
|
185
|
-
end
|
|
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)
|
|
186
355
|
```
|
|
187
356
|
|
|
188
|
-
|
|
357
|
+
### Available Fields
|
|
189
358
|
|
|
190
|
-
|
|
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` |
|
|
191
365
|
|
|
192
|
-
|
|
193
|
-
# Required - at least one provider
|
|
194
|
-
ANTHROPIC_API_KEY=sk-ant-...
|
|
195
|
-
OPENAI_API_KEY=sk-...
|
|
196
|
-
GEMINI_API_KEY=...
|
|
366
|
+
### RunConfig vs RobotLab.config
|
|
197
367
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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 |
|
|
203
374
|
|
|
204
|
-
|
|
375
|
+
## Robot-Level Configuration
|
|
376
|
+
|
|
377
|
+
Individual robots can override the global model and other settings:
|
|
205
378
|
|
|
206
379
|
```ruby
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
380
|
+
# Override model for a specific robot
|
|
381
|
+
robot = RobotLab.build(
|
|
382
|
+
name: "fast_bot",
|
|
383
|
+
system_prompt: "You are a quick responder.",
|
|
384
|
+
model: "claude-haiku-3-5",
|
|
385
|
+
temperature: 0.3,
|
|
386
|
+
max_tokens: 500
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
# Or use chaining at runtime
|
|
390
|
+
robot.with_temperature(0.9).with_max_tokens(2000).run("Tell me a story.")
|
|
212
391
|
```
|
|
213
392
|
|
|
214
|
-
##
|
|
393
|
+
## Hierarchical MCP and Tools
|
|
215
394
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
395
|
+
MCP servers and tools use a hierarchical configuration: `runtime > robot > network > global`. Each level can specify:
|
|
396
|
+
|
|
397
|
+
- `:inherit` -- Use the parent level's configuration
|
|
398
|
+
- `:none` -- No MCP servers or tools at this level
|
|
399
|
+
- An explicit array -- Specific servers or tools
|
|
219
400
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
401
|
+
```ruby
|
|
402
|
+
# Robot inheriting network MCP config
|
|
403
|
+
robot = RobotLab.build(
|
|
404
|
+
name: "agent",
|
|
405
|
+
system_prompt: "You are helpful.",
|
|
406
|
+
mcp: :inherit,
|
|
407
|
+
tools: :inherit
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
# Robot with no MCP, specific tools
|
|
411
|
+
robot = RobotLab.build(
|
|
412
|
+
name: "calculator",
|
|
413
|
+
system_prompt: "You solve math problems.",
|
|
414
|
+
mcp: :none,
|
|
415
|
+
local_tools: [Calculator]
|
|
416
|
+
)
|
|
224
417
|
```
|
|
225
418
|
|
|
226
419
|
## Next Steps
|
|
@@ -15,7 +15,7 @@ In this section, you'll learn how to:
|
|
|
15
15
|
|
|
16
16
|
Before you begin, make sure you have:
|
|
17
17
|
|
|
18
|
-
- **Ruby 3.
|
|
18
|
+
- **Ruby 3.2+** installed
|
|
19
19
|
- An **API key** from at least one LLM provider:
|
|
20
20
|
- [Anthropic](https://console.anthropic.com/) (recommended)
|
|
21
21
|
- [OpenAI](https://platform.openai.com/)
|
|
@@ -4,7 +4,7 @@ This guide covers installing RobotLab in your Ruby project.
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
- **Ruby**: 3.
|
|
7
|
+
- **Ruby**: 3.2 or higher
|
|
8
8
|
- **Bundler**: 2.0 or higher (recommended)
|
|
9
9
|
|
|
10
10
|
## Install via Bundler
|
|
@@ -31,13 +31,19 @@ gem install robot_lab
|
|
|
31
31
|
|
|
32
32
|
## Dependencies
|
|
33
33
|
|
|
34
|
-
RobotLab automatically installs these dependencies:
|
|
34
|
+
RobotLab automatically installs these core dependencies:
|
|
35
35
|
|
|
36
36
|
| Gem | Purpose |
|
|
37
37
|
|-----|---------|
|
|
38
|
-
| `ruby_llm` | LLM provider integrations |
|
|
39
|
-
| `
|
|
40
|
-
| `simple_flow` |
|
|
38
|
+
| `ruby_llm` (~> 1.12) | LLM provider integrations (Anthropic, OpenAI, Gemini, etc.) |
|
|
39
|
+
| `prompt_manager` (~> 1.0) | Template-based prompt management with YAML front matter |
|
|
40
|
+
| `simple_flow` (~> 0.3) | Pipeline workflow execution for networks |
|
|
41
|
+
| `myway_config` (~> 0.1) | Layered configuration (defaults, env vars, config files) |
|
|
42
|
+
| `ruby_llm-mcp` | Model Context Protocol client for external tool servers |
|
|
43
|
+
| `ruby_llm-schema` | Schema validation for structured outputs |
|
|
44
|
+
| `ruby_llm-semantic_cache` | Semantic caching for LLM responses |
|
|
45
|
+
| `zeitwerk` (~> 2.6) | Autoloading and eager loading |
|
|
46
|
+
| `async` (~> 2.0) | Fiber-based concurrency |
|
|
41
47
|
|
|
42
48
|
### Optional Dependencies
|
|
43
49
|
|
|
@@ -78,7 +84,7 @@ Run it:
|
|
|
78
84
|
|
|
79
85
|
```bash
|
|
80
86
|
ruby test_robot_lab.rb
|
|
81
|
-
# => RobotLab version: 0.0
|
|
87
|
+
# => RobotLab version: 0.1.0
|
|
82
88
|
# => Installation successful!
|
|
83
89
|
```
|
|
84
90
|
|
|
@@ -107,24 +113,24 @@ rails db:migrate
|
|
|
107
113
|
|
|
108
114
|
## Environment Setup
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
RobotLab uses a layered configuration system (see [Configuration](configuration.md) for full details). The simplest way to get started is with environment variables:
|
|
111
117
|
|
|
112
118
|
=== "Anthropic (Recommended)"
|
|
113
119
|
|
|
114
120
|
```bash
|
|
115
|
-
export
|
|
121
|
+
export ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY="sk-ant-..."
|
|
116
122
|
```
|
|
117
123
|
|
|
118
124
|
=== "OpenAI"
|
|
119
125
|
|
|
120
126
|
```bash
|
|
121
|
-
export
|
|
127
|
+
export ROBOT_LAB_RUBY_LLM__OPENAI_API_KEY="sk-..."
|
|
122
128
|
```
|
|
123
129
|
|
|
124
130
|
=== "Google Gemini"
|
|
125
131
|
|
|
126
132
|
```bash
|
|
127
|
-
export
|
|
133
|
+
export ROBOT_LAB_RUBY_LLM__GEMINI_API_KEY="..."
|
|
128
134
|
```
|
|
129
135
|
|
|
130
136
|
!!! tip "Using dotenv"
|
|
@@ -132,14 +138,17 @@ Before using RobotLab, set up your API keys as environment variables:
|
|
|
132
138
|
|
|
133
139
|
```ruby
|
|
134
140
|
# Gemfile
|
|
135
|
-
gem "dotenv
|
|
141
|
+
gem "dotenv", groups: [:development, :test]
|
|
136
142
|
```
|
|
137
143
|
|
|
138
144
|
```bash
|
|
139
145
|
# .env
|
|
140
|
-
|
|
146
|
+
ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...
|
|
141
147
|
```
|
|
142
148
|
|
|
149
|
+
!!! info "Direct provider env vars"
|
|
150
|
+
RubyLLM also reads provider-specific environment variables directly (e.g., `ANTHROPIC_API_KEY`). If you already have those set, they will be picked up automatically. The `ROBOT_LAB_RUBY_LLM__*` prefix gives you explicit control through RobotLab's config layer.
|
|
151
|
+
|
|
143
152
|
## Troubleshooting
|
|
144
153
|
|
|
145
154
|
### Gem Installation Fails
|
|
@@ -167,7 +176,7 @@ bundle add async-websocket
|
|
|
167
176
|
|
|
168
177
|
If you see authentication errors:
|
|
169
178
|
|
|
170
|
-
1. Verify your API key is set: `echo $
|
|
179
|
+
1. Verify your API key is set: `echo $ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY`
|
|
171
180
|
2. Check the key is valid in your provider's console
|
|
172
181
|
3. Ensure you're using the correct environment variable name
|
|
173
182
|
|