robot_lab 0.3.0 → 0.5.0

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.
Files changed (274) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/README.md +29 -19
  4. data/lib/robot_lab/errors.rb +4 -0
  5. data/lib/robot_lab/hook_context.rb +9 -2
  6. data/lib/robot_lab/mcp/registry.rb +99 -0
  7. data/lib/robot_lab/mcp/server.rb +47 -83
  8. data/lib/robot_lab/mcp/server_discovery.rb +22 -9
  9. data/lib/robot_lab/mcp.rb +259 -0
  10. data/lib/robot_lab/robot/mcp_management.rb +159 -105
  11. data/lib/robot_lab/robot/tool_call_gating.rb +144 -0
  12. data/lib/robot_lab/robot.rb +72 -99
  13. data/lib/robot_lab/run_config.rb +3 -2
  14. data/lib/robot_lab/tool.rb +8 -23
  15. data/lib/robot_lab/version.rb +1 -1
  16. data/lib/robot_lab.rb +1 -4
  17. metadata +16 -292
  18. data/.architecture/AGENTS.md +0 -32
  19. data/.architecture/config.yml +0 -8
  20. data/.architecture/members.yml +0 -60
  21. data/.architecture/reviews/feature-free-will.md +0 -490
  22. data/.architecture/reviews/overall-codebase.md +0 -427
  23. data/.claude/settings.local.json +0 -57
  24. data/.codex/config.toml +0 -2
  25. data/.envrc +0 -6
  26. data/.github/workflows/deploy-github-pages.yml +0 -52
  27. data/.irbrc +0 -6
  28. data/.loki +0 -65
  29. data/.quality/reek_baseline.txt +0 -43
  30. data/.rubocop.yml +0 -10
  31. data/Archspec.rb +0 -44
  32. data/CLAUDE.md +0 -141
  33. data/COMMITS.md +0 -196
  34. data/Rakefile +0 -193
  35. data/_typos.toml +0 -21
  36. data/agent2agent_review.md +0 -192
  37. data/agentf_improvements.md +0 -253
  38. data/agents.md +0 -14
  39. data/docs/api/core/index.md +0 -147
  40. data/docs/api/core/memory.md +0 -578
  41. data/docs/api/core/network.md +0 -553
  42. data/docs/api/core/result.md +0 -211
  43. data/docs/api/core/robot.md +0 -1667
  44. data/docs/api/core/state.md +0 -145
  45. data/docs/api/core/tool.md +0 -520
  46. data/docs/api/errors.md +0 -323
  47. data/docs/api/hooks.md +0 -469
  48. data/docs/api/index.md +0 -137
  49. data/docs/api/mcp/client.md +0 -387
  50. data/docs/api/mcp/index.md +0 -267
  51. data/docs/api/mcp/server.md +0 -252
  52. data/docs/api/mcp/transports.md +0 -339
  53. data/docs/api/messages/index.md +0 -126
  54. data/docs/api/messages/text-message.md +0 -170
  55. data/docs/api/messages/tool-call-message.md +0 -206
  56. data/docs/api/messages/tool-result-message.md +0 -242
  57. data/docs/api/messages/user-message.md +0 -232
  58. data/docs/api/skills.md +0 -423
  59. data/docs/api/streaming/context.md +0 -280
  60. data/docs/api/streaming/events.md +0 -185
  61. data/docs/api/streaming/index.md +0 -156
  62. data/docs/api/support.md +0 -846
  63. data/docs/architecture/core-concepts.md +0 -575
  64. data/docs/architecture/index.md +0 -252
  65. data/docs/architecture/message-flow.md +0 -366
  66. data/docs/architecture/network-orchestration.md +0 -478
  67. data/docs/architecture/robot-execution.md +0 -396
  68. data/docs/architecture/state-management.md +0 -410
  69. data/docs/assets/css/custom.css +0 -56
  70. data/docs/assets/images/robot_lab.jpg +0 -0
  71. data/docs/concepts.md +0 -641
  72. data/docs/examples/basic-chat.md +0 -258
  73. data/docs/examples/index.md +0 -425
  74. data/docs/examples/mcp-server.md +0 -403
  75. data/docs/examples/multi-robot-network.md +0 -476
  76. data/docs/examples/tool-usage.md +0 -468
  77. data/docs/getting-started/configuration.md +0 -645
  78. data/docs/getting-started/index.md +0 -56
  79. data/docs/getting-started/installation.md +0 -197
  80. data/docs/getting-started/quick-start.md +0 -293
  81. data/docs/guides/building-robots.md +0 -1187
  82. data/docs/guides/creating-networks.md +0 -736
  83. data/docs/guides/hooks.md +0 -1206
  84. data/docs/guides/index.md +0 -78
  85. data/docs/guides/knowledge.md +0 -219
  86. data/docs/guides/mcp-integration.md +0 -740
  87. data/docs/guides/memory.md +0 -458
  88. data/docs/guides/observability.md +0 -733
  89. data/docs/guides/streaming.md +0 -323
  90. data/docs/guides/using-tools.md +0 -780
  91. data/docs/index.md +0 -280
  92. data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
  93. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
  94. data/examples/.envrc +0 -3
  95. data/examples/01_simple_robot.rb +0 -31
  96. data/examples/02_tools.rb +0 -109
  97. data/examples/03_network.rb +0 -118
  98. data/examples/04_mcp.rb +0 -217
  99. data/examples/05_streaming.rb +0 -137
  100. data/examples/06_prompt_templates.rb +0 -325
  101. data/examples/07_network_memory.rb +0 -313
  102. data/examples/08_llm_config.rb +0 -162
  103. data/examples/09_chaining.rb +0 -251
  104. data/examples/10_memory.rb +0 -315
  105. data/examples/11_network_introspection.rb +0 -239
  106. data/examples/12_message_bus.rb +0 -67
  107. data/examples/13_spawn.rb +0 -85
  108. data/examples/14_rusty_circuit/.envrc +0 -1
  109. data/examples/14_rusty_circuit/.gitignore +0 -1
  110. data/examples/14_rusty_circuit/README.md +0 -1
  111. data/examples/14_rusty_circuit/comic.rb +0 -149
  112. data/examples/14_rusty_circuit/display.rb +0 -217
  113. data/examples/14_rusty_circuit/heckler.rb +0 -65
  114. data/examples/14_rusty_circuit/open_mic.rb +0 -132
  115. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
  116. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
  117. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
  118. data/examples/14_rusty_circuit/scout.rb +0 -165
  119. data/examples/14_rusty_circuit/show.log +0 -234
  120. data/examples/15_memory_network_and_bus/.envrc +0 -1
  121. data/examples/15_memory_network_and_bus/README.md +0 -66
  122. data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
  123. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
  124. data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
  125. data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
  126. data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
  127. data/examples/15_memory_network_and_bus/output/combined_article.md +0 -11
  128. data/examples/15_memory_network_and_bus/output/final_article.md +0 -8
  129. data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
  130. data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
  131. data/examples/15_memory_network_and_bus/output/memory.json +0 -13
  132. data/examples/15_memory_network_and_bus/output/revision_1.md +0 -29
  133. data/examples/15_memory_network_and_bus/output/revision_2.md +0 -50
  134. data/examples/15_memory_network_and_bus/output/revision_3.md +0 -8
  135. data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
  136. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
  137. data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
  138. data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
  139. data/examples/16_writers_room/.envrc +0 -1
  140. data/examples/16_writers_room/display.rb +0 -158
  141. data/examples/16_writers_room/output/.gitignore +0 -4
  142. data/examples/16_writers_room/output/README.md +0 -69
  143. data/examples/16_writers_room/output/opus_001.md +0 -263
  144. data/examples/16_writers_room/output/opus_001_notes.log +0 -470
  145. data/examples/16_writers_room/output/opus_002.md +0 -245
  146. data/examples/16_writers_room/output/opus_002_notes.log +0 -546
  147. data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
  148. data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
  149. data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
  150. data/examples/16_writers_room/prompts/writer.md +0 -37
  151. data/examples/16_writers_room/room.rb +0 -186
  152. data/examples/16_writers_room/tools.rb +0 -173
  153. data/examples/16_writers_room/writer.rb +0 -121
  154. data/examples/16_writers_room/writers_room.rb +0 -256
  155. data/examples/17_skills.rb +0 -234
  156. data/examples/18_rails/.envrc +0 -3
  157. data/examples/18_rails/.gitignore +0 -5
  158. data/examples/18_rails/Gemfile +0 -11
  159. data/examples/18_rails/README.md +0 -67
  160. data/examples/18_rails/Rakefile +0 -4
  161. data/examples/18_rails/app/controllers/application_controller.rb +0 -4
  162. data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
  163. data/examples/18_rails/app/jobs/application_job.rb +0 -4
  164. data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
  165. data/examples/18_rails/app/models/application_record.rb +0 -5
  166. data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
  167. data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
  168. data/examples/18_rails/app/robots/chat_robot.rb +0 -25
  169. data/examples/18_rails/app/tools/time_tool.rb +0 -9
  170. data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
  171. data/examples/18_rails/app/views/chat/index.html.erb +0 -67
  172. data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
  173. data/examples/18_rails/bin/dev +0 -7
  174. data/examples/18_rails/bin/rails +0 -6
  175. data/examples/18_rails/bin/setup +0 -15
  176. data/examples/18_rails/config/application.rb +0 -33
  177. data/examples/18_rails/config/cable.yml +0 -2
  178. data/examples/18_rails/config/database.yml +0 -5
  179. data/examples/18_rails/config/environment.rb +0 -4
  180. data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
  181. data/examples/18_rails/config/routes.rb +0 -6
  182. data/examples/18_rails/config.ru +0 -4
  183. data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
  184. data/examples/19_token_tracking.rb +0 -138
  185. data/examples/20_circuit_breaker.rb +0 -147
  186. data/examples/21_learning_loop.rb +0 -181
  187. data/examples/22_context_compression.rb +0 -172
  188. data/examples/23_convergence.rb +0 -133
  189. data/examples/24_structured_delegation.rb +0 -151
  190. data/examples/25_history_search/conversation.jsonl +0 -30
  191. data/examples/25_history_search.rb +0 -133
  192. data/examples/26_document_store/api_versioning_adr.md +0 -52
  193. data/examples/26_document_store/incident_postmortem.md +0 -46
  194. data/examples/26_document_store/postgres_runbook.md +0 -49
  195. data/examples/26_document_store/redis_caching_guide.md +0 -48
  196. data/examples/26_document_store/sidekiq_guide.md +0 -51
  197. data/examples/26_document_store.rb +0 -140
  198. data/examples/27_incident_response/README.md +0 -65
  199. data/examples/27_incident_response/incident_response.rb +0 -261
  200. data/examples/28_mcp_discovery.rb +0 -113
  201. data/examples/29_ractor_tools.rb +0 -240
  202. data/examples/30_ractor_network.rb +0 -252
  203. data/examples/31_launch_assessment.rb +0 -246
  204. data/examples/32_newsletter_reader.rb +0 -193
  205. data/examples/33_stock_generator.rb +0 -80
  206. data/examples/33_stock_predictor.rb +0 -327
  207. data/examples/34_agentskills.rb +0 -76
  208. data/examples/35_hooks.rb +0 -266
  209. data/examples/README.md +0 -550
  210. data/examples/common.rb +0 -180
  211. data/examples/prompts/assistant.md +0 -5
  212. data/examples/prompts/audit_trail.md +0 -8
  213. data/examples/prompts/billing.md +0 -10
  214. data/examples/prompts/classifier.md +0 -7
  215. data/examples/prompts/comedian.md +0 -6
  216. data/examples/prompts/comedy_critic.md +0 -10
  217. data/examples/prompts/configurable.md +0 -9
  218. data/examples/prompts/dispatcher.md +0 -12
  219. data/examples/prompts/entity_extractor.md +0 -14
  220. data/examples/prompts/escalation.md +0 -42
  221. data/examples/prompts/frontmatter_mcp_test.md +0 -9
  222. data/examples/prompts/frontmatter_named_test.md +0 -5
  223. data/examples/prompts/frontmatter_tools_test.md +0 -6
  224. data/examples/prompts/general.md +0 -7
  225. data/examples/prompts/github_assistant.md +0 -14
  226. data/examples/prompts/helper.md +0 -4
  227. data/examples/prompts/incident_responder.md +0 -18
  228. data/examples/prompts/keyword_extractor.md +0 -11
  229. data/examples/prompts/llm_config_demo.md +0 -20
  230. data/examples/prompts/order_support.md +0 -35
  231. data/examples/prompts/os_advocate.md +0 -13
  232. data/examples/prompts/os_chief.md +0 -13
  233. data/examples/prompts/os_editor.md +0 -13
  234. data/examples/prompts/parameterized_main_test.md +0 -6
  235. data/examples/prompts/pii_redactor.md +0 -7
  236. data/examples/prompts/product_support.md +0 -37
  237. data/examples/prompts/runbook_protocol.md +0 -12
  238. data/examples/prompts/sentiment_analyzer.md +0 -12
  239. data/examples/prompts/skill_a_test.md +0 -4
  240. data/examples/prompts/skill_b_test.md +0 -4
  241. data/examples/prompts/skill_config_test.md +0 -5
  242. data/examples/prompts/skill_cycle_a_test.md +0 -6
  243. data/examples/prompts/skill_cycle_b_test.md +0 -6
  244. data/examples/prompts/skill_description_test.md +0 -4
  245. data/examples/prompts/skill_leaf_test.md +0 -4
  246. data/examples/prompts/skill_nested_test.md +0 -6
  247. data/examples/prompts/skill_refs_main_test.md +0 -6
  248. data/examples/prompts/skill_self_ref_test.md +0 -6
  249. data/examples/prompts/skill_with_mcp_test.md +0 -9
  250. data/examples/prompts/skill_with_params_test.md +0 -6
  251. data/examples/prompts/skill_with_robot_name_test.md +0 -5
  252. data/examples/prompts/skill_with_tools_test.md +0 -6
  253. data/examples/prompts/sre_compliance.md +0 -10
  254. data/examples/prompts/structured_output.md +0 -7
  255. data/examples/prompts/synthesizer.md +0 -17
  256. data/examples/prompts/technical.md +0 -10
  257. data/examples/prompts/template_with_skills_test.md +0 -6
  258. data/examples/prompts/triage.md +0 -22
  259. data/examples/ruboruby.md +0 -423
  260. data/examples/run_all.rb +0 -60
  261. data/examples/xyzzy.rb +0 -97
  262. data/lib/robot_lab/mcp/client.rb +0 -223
  263. data/lib/robot_lab/mcp/connection_poller.rb +0 -195
  264. data/lib/robot_lab/mcp/transports/base.rb +0 -64
  265. data/lib/robot_lab/mcp/transports/sse.rb +0 -120
  266. data/lib/robot_lab/mcp/transports/stdio.rb +0 -170
  267. data/lib/robot_lab/mcp/transports/streamable_http.rb +0 -141
  268. data/lib/robot_lab/mcp/transports/websocket.rb +0 -111
  269. data/logfile +0 -8
  270. data/mkdocs.yml +0 -209
  271. data/robot_concurrency.md +0 -38
  272. data/simple_acp_review.md +0 -298
  273. data/temp.md +0 -6
  274. data/tool_manifest_plan.md +0 -155
@@ -1,197 +0,0 @@
1
- # Installation
2
-
3
- This guide covers installing RobotLab in your Ruby project.
4
-
5
- ## Requirements
6
-
7
- - **Ruby**: 3.2 or higher
8
- - **Bundler**: 2.0 or higher (recommended)
9
-
10
- ## Install via Bundler
11
-
12
- Add RobotLab to your `Gemfile`:
13
-
14
- ```ruby
15
- gem "robot_lab"
16
- ```
17
-
18
- Then install:
19
-
20
- ```bash
21
- bundle install
22
- ```
23
-
24
- ## Install via RubyGems
25
-
26
- Or install directly:
27
-
28
- ```bash
29
- gem install robot_lab
30
- ```
31
-
32
- ## Dependencies
33
-
34
- RobotLab automatically installs these core dependencies:
35
-
36
- | Gem | Purpose |
37
- |-----|---------|
38
- | `ruby_llm` (~> 2.0.0.rc3) | LLM provider integrations (Anthropic, OpenAI, Gemini, etc.) |
39
- | `prompt_manager` (~> 1.0) | Template-based prompt management with YAML front matter |
40
- | `simple_flow` (~> 0.4) | Pipeline workflow execution for networks |
41
- | `myway_config` (~> 0.1) | Layered configuration (defaults, env vars, config files) |
42
- | `zeitwerk` (~> 2.6) | Autoloading and eager loading |
43
- | `async` (~> 2.0) | Fiber-based concurrency |
44
- | `async-http` (~> 0.60) | MCP SSE and streamable-HTTP transports |
45
- | `async-websocket` (~> 0.30) | MCP WebSocket transport |
46
- | `typed_bus` (~> 0.0.1) | Typed message bus for robot-to-robot messaging |
47
- | `ractor_queue` (~> 0.2) | Queue used by the Network bus poller |
48
-
49
- > [!NOTE]
50
- > `async-http` and `async-websocket` are hard runtime dependencies, not optional
51
- > extras — they install with the gem whether or not you use MCP.
52
-
53
- ### Optional Dependencies
54
-
55
- Several features are gated behind gems the core gem does **not** install. Add
56
- whichever you need to your own `Gemfile`:
57
-
58
- | Gem | Enables | Without it |
59
- |-----|---------|------------|
60
- | `classifier` (~> 2.3) | `robot.compress_history`, `RobotLab::Convergence` | `RobotLab::DependencyError` |
61
- | `robot_lab-document_store` | `memory.store_document` / `search_documents` / `document_keys` / `delete_document`, and `AgentSkill` catalogs | `RobotLab::DependencyError` (skill catalogs raise `LoadError`) |
62
- | `redis` | Redis-backed `Memory` | `Memory#redis?` is `false` and the store silently stays in-process |
63
- | `robot_lab-ractor` | Ractor-parallel tool execution and `Network` ractor scheduling | tools run inline; a network run with `parallel_mode: :ractor` raises `RobotLab::DependencyError` |
64
-
65
- ```ruby
66
- # Gemfile
67
- gem "classifier", "~> 2.3"
68
- gem "robot_lab-document_store"
69
- gem "redis"
70
- gem "robot_lab-ractor"
71
- ```
72
-
73
- > [!NOTE]
74
- > Several capabilities advertised on the [home page](../index.md) — embedding-based
75
- > document retrieval, runtime skill matching, and CPU parallelism — depend on the
76
- > gems above. They are genuinely optional, but the feature is unavailable until the
77
- > gem is installed.
78
-
79
- ## Verify Installation
80
-
81
- Create a test file to verify everything works:
82
-
83
- ```ruby
84
- # test_robot_lab.rb
85
- require "robot_lab"
86
-
87
- puts "RobotLab version: #{RobotLab::VERSION}"
88
- puts "Installation successful!"
89
- ```
90
-
91
- Run it:
92
-
93
- ```bash
94
- ruby test_robot_lab.rb
95
- # => RobotLab version: 0.2.6
96
- # => Installation successful!
97
- ```
98
-
99
- ## Rails Installation
100
-
101
- > [!IMPORTANT]
102
- > The core `robot_lab` gem ships **no Rails Engine, no Railtie, and no generators**.
103
- > Rails integration lives in the separate
104
- > [robot_lab-rails](https://github.com/MadBomber/robot_lab-rails) gem.
105
-
106
- Core RobotLab only performs two bare `defined?(::Rails)` checks: it uses
107
- `Rails.logger` as the default logger, and it resolves the template path to
108
- `app/prompts` when `Rails.root` is present. Nothing else is Rails-aware.
109
-
110
- For generators, an `ActiveJob` base class, and Turbo Stream broadcasting, add the
111
- extension gem:
112
-
113
- ```ruby
114
- # Gemfile
115
- gem "robot_lab"
116
- gem "robot_lab-rails"
117
- ```
118
-
119
- Then follow that gem's own installation instructions for its generators and
120
- migrations.
121
-
122
- ## Environment Setup
123
-
124
- RobotLab uses a layered configuration system (see [Configuration](configuration.md) for full details). The simplest way to get started is with environment variables:
125
-
126
- === "Anthropic (Recommended)"
127
-
128
- ```bash
129
- export ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY="sk-ant-..."
130
- ```
131
-
132
- === "OpenAI"
133
-
134
- ```bash
135
- export ROBOT_LAB_RUBY_LLM__OPENAI_API_KEY="sk-..."
136
- ```
137
-
138
- === "Google Gemini"
139
-
140
- ```bash
141
- export ROBOT_LAB_RUBY_LLM__GEMINI_API_KEY="..."
142
- ```
143
-
144
- !!! tip "Using dotenv"
145
- For development, consider using the [dotenv](https://github.com/bkeepers/dotenv) gem to manage environment variables:
146
-
147
- ```ruby
148
- # Gemfile
149
- gem "dotenv", groups: [:development, :test]
150
- ```
151
-
152
- ```bash
153
- # .env
154
- ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...
155
- ```
156
-
157
- !!! info "Direct provider env vars"
158
- 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.
159
-
160
- ## Troubleshooting
161
-
162
- ### Gem Installation Fails
163
-
164
- If you encounter SSL or network errors:
165
-
166
- ```bash
167
- # Update RubyGems
168
- gem update --system
169
-
170
- # Try installing with verbose output
171
- gem install robot_lab --verbose
172
- ```
173
-
174
- ### Missing Dependencies
175
-
176
- If you see a `LoadError` (or a `RobotLab::DependencyError`) naming a gem RobotLab
177
- does not depend on, add it yourself:
178
-
179
- ```bash
180
- # e.g. compress_history / Convergence need the classifier gem
181
- bundle add classifier
182
- ```
183
-
184
- ### API Key Issues
185
-
186
- If you see authentication errors:
187
-
188
- 1. Verify your API key is set: `echo $ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY`
189
- 2. Check the key is valid in your provider's console
190
- 3. Ensure you're using the correct environment variable name
191
-
192
- ## Next Steps
193
-
194
- Now that RobotLab is installed:
195
-
196
- - [:octicons-arrow-right-24: Quick Start](quick-start.md) - Build your first robot
197
- - [:octicons-arrow-right-24: Configuration](configuration.md) - Configure defaults
@@ -1,293 +0,0 @@
1
- # Quick Start
2
-
3
- Build your first RobotLab application in 5 minutes.
4
-
5
- ## Step 1: Set Up API Keys
6
-
7
- RobotLab reads configuration from environment variables automatically. Set your API key before running any code:
8
-
9
- ```bash
10
- export ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY="sk-ant-..."
11
- ```
12
-
13
- Or create a config file at `./config/robot_lab.yml`:
14
-
15
- ```yaml
16
- ruby_llm:
17
- anthropic_api_key: <%= ENV['ANTHROPIC_API_KEY'] %>
18
- ```
19
-
20
- > [!IMPORTANT]
21
- > Config files are **flat** — put the keys at the top level. Wrapping them in a
22
- > `defaults:` key (as the gem's own bundled `defaults.yml` does) makes the whole
23
- > file silently ignored.
24
-
25
- See [Configuration](configuration.md) for all configuration options.
26
-
27
- ## Step 2: Create a Robot
28
-
29
- Build a simple assistant robot using keyword arguments:
30
-
31
- ```ruby
32
- require "robot_lab"
33
-
34
- assistant = RobotLab.build(
35
- name: "assistant",
36
- system_prompt: "You are a helpful AI assistant. You provide clear, accurate, and concise answers."
37
- )
38
- ```
39
-
40
- ## Step 3: Run It
41
-
42
- Send a message and get a response:
43
-
44
- ```ruby
45
- result = assistant.run("What is Ruby on Rails?")
46
-
47
- puts result.last_text_content
48
- ```
49
-
50
- The `run` method takes a positional string message and returns a `RobotResult`. Use `last_text_content` to extract the response text.
51
-
52
- ## Complete Example
53
-
54
- Here is everything together in one file:
55
-
56
- ```ruby title="hello_robot.rb"
57
- require "robot_lab"
58
-
59
- # Build a robot with an inline system prompt
60
- assistant = RobotLab.build(
61
- name: "assistant",
62
- system_prompt: "You are a helpful AI assistant. Be concise and friendly."
63
- )
64
-
65
- # Run the robot with a message
66
- result = assistant.run("Hello! What can you help me with?")
67
-
68
- # Print the response
69
- puts result.last_text_content
70
- ```
71
-
72
- Run it:
73
-
74
- ```bash
75
- ruby hello_robot.rb
76
- ```
77
-
78
- ## Using Templates
79
-
80
- Instead of inline prompts, you can use template files managed by `prompt_manager`. Templates are `.md` files with YAML front matter:
81
-
82
- ```markdown title="prompts/helper.md"
83
- ---
84
- description: A helpful assistant
85
- parameters:
86
- company_name: null
87
- ---
88
- You are a helpful assistant for <%= company_name %>.
89
- Be concise and friendly in your responses.
90
- ```
91
-
92
- Create the robot with a template reference and context:
93
-
94
- ```ruby
95
- robot = RobotLab.build(
96
- name: "helper",
97
- template: :helper,
98
- context: { company_name: "Acme Corp" }
99
- )
100
-
101
- result = robot.run("What services do you offer?")
102
- puts result.last_text_content
103
- ```
104
-
105
- Templates are loaded from the `prompts/` directory by default (or `app/prompts/` in Rails). You can change this in your config.
106
-
107
- ## Adding a Tool
108
-
109
- Give your robot custom capabilities by defining a `RubyLLM::Tool` subclass:
110
-
111
- ```ruby title="hello_tools.rb"
112
- require "robot_lab"
113
-
114
- class CurrentTime < RubyLLM::Tool
115
- description "Get the current date and time"
116
-
117
- param :timezone,
118
- type: "string",
119
- desc: "Timezone name (e.g., 'UTC', 'US/Eastern')",
120
- required: false
121
-
122
- def execute(timezone: "UTC")
123
- Time.now.getlocal(timezone_offset(timezone)).strftime("%Y-%m-%d %H:%M:%S %Z")
124
- rescue => e
125
- Time.now.utc.strftime("%Y-%m-%d %H:%M:%S UTC")
126
- end
127
-
128
- private
129
-
130
- def timezone_offset(tz)
131
- case tz
132
- when "UTC" then "+00:00"
133
- when "US/Eastern" then "-05:00"
134
- when "US/Pacific" then "-08:00"
135
- else "+00:00"
136
- end
137
- end
138
- end
139
-
140
- # Pass tools via the local_tools: parameter
141
- assistant = RobotLab.build(
142
- name: "time_bot",
143
- system_prompt: "You are a helpful assistant. Use the current_time tool when users ask about the time.",
144
- local_tools: [CurrentTime]
145
- )
146
-
147
- # tools: :inherit is REQUIRED -- run() sends no tools without it
148
- result = assistant.run("What time is it right now?", tools: :inherit)
149
- puts result.last_text_content
150
- ```
151
-
152
- Tools are passed to the robot via the `local_tools:` keyword argument as an array of `RubyLLM::Tool` subclasses.
153
-
154
- > [!WARNING]
155
- > **Attaching a tool is not the same as sending it.** `Robot#run` defaults to
156
- > `tools: :none`, which means "send zero tools this turn". Without
157
- > `tools: :inherit` on the run, the example above builds fine, calls the LLM
158
- > fine, and the model simply never sees `CurrentTime` — it will guess or say it
159
- > cannot check the time. The same applies to MCP: pass
160
- > `mcp: :inherit, tools: :inherit` to connect MCP servers and expose their tools.
161
- >
162
- > Do **not** try to fix this by passing `tools: :inherit` to `RobotLab.build` for
163
- > a standalone robot like this one — at build time it resolves against the global
164
- > `:none` and yields an allowlist matching nothing, suppressing the tools even
165
- > when the run asks for them. Put it on the `run` call.
166
- >
167
- > (The one place build-time `:inherit` *is* correct is a robot in a network, where
168
- > it opts into the network `config:`'s list — see
169
- > [Creating Networks](../guides/creating-networks.md).)
170
-
171
- ## Method Chaining
172
-
173
- Robots support a chaining API for runtime adjustments:
174
-
175
- ```ruby
176
- robot = RobotLab.build(name: "writer")
177
-
178
- result = robot
179
- .with_instructions("You are a creative fiction writer.")
180
- .with_temperature(0.9)
181
- .with_model("claude-sonnet-4")
182
- .run("Write a haiku about programming.")
183
-
184
- puts result.last_text_content
185
- ```
186
-
187
- The complete set of chaining methods is `with_context`, `with_headers`,
188
- `with_instructions`, `with_model`, `with_params`, `with_schema`,
189
- `with_temperature`, `with_thinking`, `with_tool`, `with_tools`, plus RobotLab's
190
- own `with_template` and `with_bus`.
191
-
192
- > [!NOTE]
193
- > There is no `with_max_tokens`, `with_top_p`, `with_top_k`, `with_stop`,
194
- > `with_presence_penalty`, or `with_frequency_penalty` — those raise
195
- > `NoMethodError`. Set them as constructor keyword arguments
196
- > (`RobotLab.build(..., max_tokens: 2000)`) or through `with_params`:
197
- >
198
- > ```ruby
199
- > robot.with_params(max_tokens: 2000, top_p: 0.3).run("...")
200
- > ```
201
-
202
- ## Multi-Robot Network
203
-
204
- Create a pipeline of robots using `RobotLab.create_network`. Networks use `SimpleFlow::Pipeline` under the hood with `task` definitions and dependency tracking:
205
-
206
- ```ruby title="hello_network.rb"
207
- require "robot_lab"
208
-
209
- # Build specialized robots
210
- analyst = RobotLab.build(
211
- name: "analyst",
212
- system_prompt: <<~PROMPT
213
- You are a text analyst. Analyze the given text and provide a brief
214
- summary of its key themes and sentiment. Be concise -- 2-3 sentences max.
215
- PROMPT
216
- )
217
-
218
- writer = RobotLab.build(
219
- name: "writer",
220
- system_prompt: <<~PROMPT
221
- You are a professional copywriter. Based on the analysis you receive,
222
- write a short, engaging summary suitable for a newsletter. Keep it
223
- to one paragraph.
224
- PROMPT
225
- )
226
-
227
- # Create a sequential pipeline
228
- network = RobotLab.create_network(name: "content_pipeline") do
229
- task :analyst, analyst, depends_on: :none
230
- task :writer, writer, depends_on: [:analyst]
231
- end
232
-
233
- # Run the network
234
- result = network.run(
235
- message: "Ruby 3.4 was released with significant performance improvements..."
236
- )
237
-
238
- # The final result is from the last robot in the pipeline
239
- if result.value.is_a?(RobotLab::RobotResult)
240
- puts result.value.last_text_content
241
- end
242
-
243
- # Access intermediate results by ROBOT name (see note below)
244
- if result.context[:analyst]
245
- puts "\nAnalysis: #{result.context[:analyst].last_text_content}"
246
- end
247
- ```
248
-
249
- > [!IMPORTANT]
250
- > `result.context` is keyed by the **robot's** `name:`, not by the task name.
251
- > Internally each robot writes `result.with_context(@name.to_sym, robot_result)`.
252
- > The lookup above works only because the robot is named `"analyst"` *and* its
253
- > task is named `:analyst`. If you register a robot under a different task name —
254
- > `task :first_pass, analyst` — the result is still at
255
- > `result.context[:analyst]`, not `result.context[:first_pass]`. Keeping the two
256
- > names identical, as in this example, is the simplest way to avoid the
257
- > surprise.
258
-
259
- ### Network Task Dependencies
260
-
261
- Tasks declare their dependencies to control execution order:
262
-
263
- | Dependency | Meaning |
264
- |-----------|---------|
265
- | `depends_on: :none` | Entry point -- runs first with no dependencies |
266
- | `depends_on: [:task_name]` | Runs after the named task(s) complete |
267
- | `depends_on: :optional` | Only runs if explicitly activated by a preceding task |
268
-
269
- Tasks with non-overlapping dependencies can execute in parallel automatically.
270
-
271
- ## What's Next?
272
-
273
- You have built your first RobotLab application. Here is where to go next:
274
-
275
- <div class="grid cards" markdown>
276
-
277
- - [:octicons-gear-24: **Configuration**](configuration.md)
278
-
279
- Learn all configuration options
280
-
281
- - [:octicons-cpu-24: **Building Robots**](../guides/building-robots.md)
282
-
283
- Deep dive into robot creation
284
-
285
- - [:octicons-tools-24: **Using Tools**](../guides/using-tools.md)
286
-
287
- Give robots custom capabilities
288
-
289
- - [:octicons-git-branch-24: **Creating Networks**](../guides/creating-networks.md)
290
-
291
- Advanced network patterns
292
-
293
- </div>