robot_lab 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.architecture/AGENTS.md +32 -0
  3. data/.architecture/config.yml +8 -0
  4. data/.architecture/members.yml +60 -0
  5. data/.architecture/reviews/feature-free-will.md +490 -0
  6. data/.architecture/reviews/overall-codebase.md +427 -0
  7. data/.claude/settings.local.json +57 -0
  8. data/.codex/config.toml +2 -0
  9. data/.irbrc +2 -2
  10. data/.rubocop.yml +172 -0
  11. data/CHANGELOG.md +72 -0
  12. data/CLAUDE.md +139 -0
  13. data/README.md +91 -95
  14. data/Rakefile +109 -3
  15. data/agent2agent_review.md +192 -0
  16. data/agentf_improvements.md +253 -0
  17. data/agents.md +14 -0
  18. data/docs/examples/index.md +37 -2
  19. data/docs/getting-started/configuration.md +20 -7
  20. data/docs/guides/index.md +16 -16
  21. data/docs/guides/knowledge.md +7 -1
  22. data/docs/guides/observability.md +132 -0
  23. data/docs/index.md +30 -3
  24. data/docs/superpowers/plans/2026-05-06-agentskills.md +1303 -0
  25. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +247 -0
  26. data/examples/.envrc +1 -0
  27. data/examples/01_simple_robot.rb +5 -9
  28. data/examples/02_tools.rb +5 -9
  29. data/examples/03_network.rb +8 -9
  30. data/examples/04_mcp.rb +21 -29
  31. data/examples/05_streaming.rb +12 -18
  32. data/examples/06_prompt_templates.rb +11 -19
  33. data/examples/07_network_memory.rb +16 -31
  34. data/examples/08_llm_config.rb +10 -22
  35. data/examples/09_chaining.rb +16 -27
  36. data/examples/10_memory.rb +12 -28
  37. data/examples/11_network_introspection.rb +15 -29
  38. data/examples/12_message_bus.rb +5 -12
  39. data/examples/13_spawn.rb +5 -10
  40. data/examples/14_rusty_circuit/.envrc +1 -0
  41. data/examples/14_rusty_circuit/comic.rb +2 -0
  42. data/examples/14_rusty_circuit/heckler.rb +1 -1
  43. data/examples/14_rusty_circuit/open_mic.rb +1 -3
  44. data/examples/14_rusty_circuit/scout.rb +2 -0
  45. data/examples/15_memory_network_and_bus/.envrc +1 -0
  46. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +6 -3
  47. data/examples/15_memory_network_and_bus/linux_writer.rb +1 -1
  48. data/examples/15_memory_network_and_bus/output/combined_article.md +6 -6
  49. data/examples/15_memory_network_and_bus/output/final_article.md +6 -8
  50. data/examples/15_memory_network_and_bus/output/linux_draft.md +4 -2
  51. data/examples/15_memory_network_and_bus/output/mac_draft.md +3 -3
  52. data/examples/15_memory_network_and_bus/output/memory.json +6 -6
  53. data/examples/15_memory_network_and_bus/output/revision_1.md +10 -11
  54. data/examples/15_memory_network_and_bus/output/revision_2.md +6 -8
  55. data/examples/15_memory_network_and_bus/output/windows_draft.md +3 -3
  56. data/examples/16_writers_room/.envrc +1 -0
  57. data/examples/16_writers_room/writers_room.rb +2 -4
  58. data/examples/17_skills.rb +8 -17
  59. data/examples/18_rails/Gemfile +1 -0
  60. data/examples/19_token_tracking.rb +9 -15
  61. data/examples/20_circuit_breaker.rb +10 -19
  62. data/examples/21_learning_loop.rb +11 -20
  63. data/examples/22_context_compression.rb +6 -13
  64. data/examples/23_convergence.rb +6 -17
  65. data/examples/24_structured_delegation.rb +11 -15
  66. data/examples/25_history_search.rb +5 -12
  67. data/examples/26_document_store.rb +6 -13
  68. data/examples/27_incident_response/incident_response.rb +4 -5
  69. data/examples/28_mcp_discovery.rb +8 -11
  70. data/examples/29_ractor_tools.rb +4 -9
  71. data/examples/30_ractor_network.rb +10 -19
  72. data/examples/31_launch_assessment.rb +10 -23
  73. data/examples/32_newsletter_reader.rb +188 -0
  74. data/examples/33_stock_generator.rb +80 -0
  75. data/examples/33_stock_predictor.rb +306 -0
  76. data/examples/34_agentskills.rb +72 -0
  77. data/examples/README.md +1 -1
  78. data/examples/common.rb +76 -0
  79. data/examples/ruboruby.md +423 -0
  80. data/examples/temp.md +51 -0
  81. data/lib/robot_lab/agent_skill.rb +63 -0
  82. data/lib/robot_lab/agent_skill_catalog.rb +74 -0
  83. data/lib/robot_lab/ask_user.rb +2 -2
  84. data/lib/robot_lab/bus_poller.rb +12 -5
  85. data/lib/robot_lab/config.rb +1 -12
  86. data/lib/robot_lab/delegation_future.rb +1 -1
  87. data/lib/robot_lab/doom_loop_detector.rb +98 -0
  88. data/lib/robot_lab/history_compressor.rb +4 -10
  89. data/lib/robot_lab/mcp/client.rb +1 -2
  90. data/lib/robot_lab/mcp/connection_poller.rb +3 -3
  91. data/lib/robot_lab/mcp/server.rb +1 -1
  92. data/lib/robot_lab/mcp/server_discovery.rb +0 -2
  93. data/lib/robot_lab/memory.rb +32 -27
  94. data/lib/robot_lab/memory_change.rb +2 -2
  95. data/lib/robot_lab/message.rb +4 -4
  96. data/lib/robot_lab/network.rb +11 -6
  97. data/lib/robot_lab/robot/agent_skill_matching.rb +99 -0
  98. data/lib/robot_lab/robot/bus_messaging.rb +9 -27
  99. data/lib/robot_lab/robot/history_search.rb +4 -1
  100. data/lib/robot_lab/robot/mcp_management.rb +5 -11
  101. data/lib/robot_lab/robot/template_rendering.rb +60 -40
  102. data/lib/robot_lab/robot.rb +323 -206
  103. data/lib/robot_lab/robot_result.rb +6 -5
  104. data/lib/robot_lab/run_config.rb +5 -11
  105. data/lib/robot_lab/script_tool.rb +76 -0
  106. data/lib/robot_lab/state_proxy.rb +7 -5
  107. data/lib/robot_lab/tool.rb +3 -3
  108. data/lib/robot_lab/tool_config.rb +1 -1
  109. data/lib/robot_lab/tool_manifest.rb +5 -7
  110. data/lib/robot_lab/user_message.rb +2 -2
  111. data/lib/robot_lab/version.rb +1 -1
  112. data/lib/robot_lab/waiter.rb +1 -1
  113. data/lib/robot_lab.rb +41 -52
  114. data/logfile +8 -0
  115. data/mkdocs.yml +2 -3
  116. data/robot_concurrency.md +38 -0
  117. data/simple_acp_review.md +298 -0
  118. data/site/404.html +2300 -0
  119. data/site/api/core/index.html +2706 -0
  120. data/site/api/core/memory/index.html +3793 -0
  121. data/site/api/core/network/index.html +3500 -0
  122. data/site/api/core/robot/index.html +4566 -0
  123. data/site/api/core/state/index.html +3390 -0
  124. data/site/api/core/tool/index.html +3843 -0
  125. data/site/api/index.html +2635 -0
  126. data/site/api/mcp/client/index.html +3435 -0
  127. data/site/api/mcp/index.html +2783 -0
  128. data/site/api/mcp/server/index.html +3252 -0
  129. data/site/api/mcp/transports/index.html +3352 -0
  130. data/site/api/messages/index.html +2641 -0
  131. data/site/api/messages/text-message/index.html +3087 -0
  132. data/site/api/messages/tool-call-message/index.html +3159 -0
  133. data/site/api/messages/tool-result-message/index.html +3252 -0
  134. data/site/api/messages/user-message/index.html +3212 -0
  135. data/site/api/streaming/context/index.html +3282 -0
  136. data/site/api/streaming/events/index.html +3347 -0
  137. data/site/api/streaming/index.html +2738 -0
  138. data/site/architecture/core-concepts/index.html +3757 -0
  139. data/site/architecture/index.html +2797 -0
  140. data/site/architecture/message-flow/index.html +3238 -0
  141. data/site/architecture/network-orchestration/index.html +3433 -0
  142. data/site/architecture/robot-execution/index.html +3140 -0
  143. data/site/architecture/state-management/index.html +3498 -0
  144. data/site/assets/css/custom.css +56 -0
  145. data/site/assets/images/favicon.png +0 -0
  146. data/site/assets/images/robot_lab.jpg +0 -0
  147. data/site/assets/javascripts/bundle.79ae519e.min.js +16 -0
  148. data/site/assets/javascripts/bundle.79ae519e.min.js.map +7 -0
  149. data/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
  150. data/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
  151. data/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
  152. data/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
  153. data/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
  154. data/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
  155. data/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
  156. data/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
  157. data/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
  158. data/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
  159. data/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
  160. data/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
  161. data/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
  162. data/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
  163. data/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
  164. data/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
  165. data/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
  166. data/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
  167. data/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
  168. data/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
  169. data/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
  170. data/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
  171. data/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
  172. data/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
  173. data/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
  174. data/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
  175. data/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
  176. data/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
  177. data/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
  178. data/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
  179. data/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
  180. data/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
  181. data/site/assets/javascripts/lunr/tinyseg.js +206 -0
  182. data/site/assets/javascripts/lunr/wordcut.js +6708 -0
  183. data/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
  184. data/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
  185. data/site/assets/stylesheets/main.484c7ddc.min.css +1 -0
  186. data/site/assets/stylesheets/main.484c7ddc.min.css.map +1 -0
  187. data/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
  188. data/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
  189. data/site/concepts/index.html +3455 -0
  190. data/site/examples/basic-chat/index.html +2880 -0
  191. data/site/examples/index.html +2907 -0
  192. data/site/examples/mcp-server/index.html +3018 -0
  193. data/site/examples/multi-robot-network/index.html +3131 -0
  194. data/site/examples/rails-application/index.html +3329 -0
  195. data/site/examples/tool-usage/index.html +3085 -0
  196. data/site/getting-started/configuration/index.html +3745 -0
  197. data/site/getting-started/index.html +2572 -0
  198. data/site/getting-started/installation/index.html +2981 -0
  199. data/site/getting-started/quick-start/index.html +2942 -0
  200. data/site/guides/building-robots/index.html +4290 -0
  201. data/site/guides/creating-networks/index.html +3858 -0
  202. data/site/guides/index.html +2586 -0
  203. data/site/guides/mcp-integration/index.html +3581 -0
  204. data/site/guides/memory/index.html +3586 -0
  205. data/site/guides/rails-integration/index.html +4019 -0
  206. data/site/guides/streaming/index.html +3157 -0
  207. data/site/guides/using-tools/index.html +3802 -0
  208. data/site/index.html +2671 -0
  209. data/site/search/search_index.json +1 -0
  210. data/site/sitemap.xml +183 -0
  211. data/site/sitemap.xml.gz +0 -0
  212. data/site/tags.json +1 -0
  213. data/temp.md +6 -0
  214. data/tool_manifest_plan.md +155 -0
  215. metadata +154 -92
  216. data/docs/examples/rails-application.md +0 -419
  217. data/docs/guides/ractor-parallelism.md +0 -364
  218. data/docs/guides/rails-integration.md +0 -681
  219. data/docs/superpowers/plans/2026-04-14-ractor-integration.md +0 -1538
  220. data/docs/superpowers/specs/2026-04-14-ractor-integration-design.md +0 -258
  221. data/lib/generators/robot_lab/install_generator.rb +0 -90
  222. data/lib/generators/robot_lab/job_generator.rb +0 -40
  223. data/lib/generators/robot_lab/robot_generator.rb +0 -55
  224. data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -42
  225. data/lib/generators/robot_lab/templates/job.rb.tt +0 -21
  226. data/lib/generators/robot_lab/templates/migration.rb.tt +0 -32
  227. data/lib/generators/robot_lab/templates/result_model.rb.tt +0 -52
  228. data/lib/generators/robot_lab/templates/robot.rb.tt +0 -31
  229. data/lib/generators/robot_lab/templates/robot_job.rb.tt +0 -18
  230. data/lib/generators/robot_lab/templates/robot_test.rb.tt +0 -34
  231. data/lib/generators/robot_lab/templates/routing_robot.rb.tt +0 -59
  232. data/lib/generators/robot_lab/templates/thread_model.rb.tt +0 -40
  233. data/lib/robot_lab/document_store.rb +0 -155
  234. data/lib/robot_lab/ractor_boundary.rb +0 -42
  235. data/lib/robot_lab/ractor_job.rb +0 -37
  236. data/lib/robot_lab/ractor_memory_proxy.rb +0 -85
  237. data/lib/robot_lab/ractor_network_scheduler.rb +0 -154
  238. data/lib/robot_lab/ractor_worker_pool.rb +0 -117
  239. data/lib/robot_lab/rails_integration/engine.rb +0 -29
  240. data/lib/robot_lab/rails_integration/job.rb +0 -158
  241. data/lib/robot_lab/rails_integration/railtie.rb +0 -51
  242. data/lib/robot_lab/rails_integration/turbo_stream_callbacks.rb +0 -72
@@ -4,6 +4,8 @@ Facilities that help you monitor, control, improve, and scale robot behaviour:
4
4
 
5
5
  - **Token & Cost Tracking** — measure LLM usage per run and cumulatively
6
6
  - **Tool Loop Circuit Breaker** — guard against runaway tool call loops
7
+ - **Doom Loop Detection** — catch cyclic or repetitive tool-call patterns before they spiral
8
+ - **Automatic Context Compaction** — prevent context overflow with configurable auto-compression
7
9
  - **Learning Accumulation** — build up cross-run observations that guide future runs
8
10
  - **Context Window Compression** — prune irrelevant history to stay within token budgets
9
11
  - **Convergence Detection** — detect when independent agents reach the same conclusion
@@ -162,6 +164,120 @@ puts result.reply # "The result is 42."
162
164
 
163
165
  ---
164
166
 
167
+ ## Doom Loop Detection
168
+
169
+ ### The Problem
170
+
171
+ `max_tool_rounds` stops a robot that loops forever, but it fires on quantity alone. A subtler failure is when a robot cycles through the same tool call sequence repeatedly — calling tool A, then B, then C, then A again — without hitting the round limit. This is a doom loop: the robot is working but not making progress.
172
+
173
+ ### doom_loop_threshold
174
+
175
+ ```ruby
176
+ robot = RobotLab.build(
177
+ name: "runner",
178
+ system_prompt: "Execute all steps.",
179
+ local_tools: [StepTool],
180
+ doom_loop_threshold: 3
181
+ )
182
+ ```
183
+
184
+ Set `doom_loop_threshold:` to the number of repetitions after which the detector fires. It catches two patterns:
185
+
186
+ - **Consecutive repetition** — `[A, A, A]` (same tool called N times in a row)
187
+ - **Cyclic repetition** — `[A, B, C, A, B, C, A, B, C]` (same sequence repeated N times)
188
+
189
+ When a doom loop is detected, a warning message is embedded directly in the tool result, prompting the LLM to try a fundamentally different approach. This avoids corrupting the Anthropic message format (no injected user messages between `tool_use`/`tool_result` pairs).
190
+
191
+ `doom_loop_threshold` can also be supplied via `RunConfig`:
192
+
193
+ ```ruby
194
+ config = RobotLab::RunConfig.new(doom_loop_threshold: 3)
195
+ robot = RobotLab.build(name: "runner", system_prompt: "...", config: config)
196
+ ```
197
+
198
+ ### Complementary to max_tool_rounds
199
+
200
+ Use both together for comprehensive loop protection:
201
+
202
+ ```ruby
203
+ robot = RobotLab.build(
204
+ name: "executor",
205
+ system_prompt: "Execute every step.",
206
+ local_tools: [StepTool],
207
+ max_tool_rounds: 20, # hard ceiling on total tool calls
208
+ doom_loop_threshold: 3 # catches repetitive patterns early
209
+ )
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Automatic Context Compaction
215
+
216
+ ### The Problem
217
+
218
+ Long-running robots accumulate conversation history. Eventually, the cumulative token count approaches the model's context window limit, causing API errors or degraded performance. Manually calling `compress_history` at the right moment requires application-level bookkeeping.
219
+
220
+ ### auto_compact
221
+
222
+ Set `auto_compact:` to have the robot compress its history automatically before each `run()`:
223
+
224
+ ```ruby
225
+ # Compact when estimated token usage exceeds 80% of the model's context window
226
+ robot = RobotLab.build(
227
+ name: "analyst",
228
+ system_prompt: "You are a research analyst.",
229
+ auto_compact: :context_window
230
+ )
231
+ ```
232
+
233
+ ### Tuning the Threshold
234
+
235
+ `compact_threshold:` sets the fraction of the model's context window that triggers compaction. Defaults to `0.80` (80%):
236
+
237
+ ```ruby
238
+ robot = RobotLab.build(
239
+ name: "analyst",
240
+ system_prompt: "You are a research analyst.",
241
+ auto_compact: :context_window,
242
+ compact_threshold: 0.70 # compact earlier, at 70%
243
+ )
244
+ ```
245
+
246
+ ### Application-Owned Compaction
247
+
248
+ Pass a `Proc` to take full control — the proc decides both when and how to compact:
249
+
250
+ ```ruby
251
+ robot = RobotLab.build(
252
+ name: "analyst",
253
+ system_prompt: "You are a research analyst.",
254
+ auto_compact: ->(r) {
255
+ r.compress_history(recent_turns: 5) if r.chat.messages.size > 40
256
+ }
257
+ )
258
+ ```
259
+
260
+ The proc receives the robot instance and is called before every `run()` when messages are non-empty.
261
+
262
+ ### Options
263
+
264
+ | Value | Behaviour |
265
+ |-------|-----------|
266
+ | `nil` / `:none` | No automatic compaction (default) |
267
+ | `:context_window` | Compact when estimated token usage exceeds `compact_threshold` fraction of model's context window |
268
+ | `Proc` | Called with the robot; application decides when and how to compact |
269
+
270
+ Via `RunConfig`:
271
+
272
+ ```ruby
273
+ config = RobotLab::RunConfig.new(auto_compact: :context_window, compact_threshold: 0.75)
274
+ robot = RobotLab.build(name: "analyst", system_prompt: "...", config: config)
275
+ ```
276
+
277
+ Requires the `classifier` gem (`~> 2.3`) when using `:context_window`. Without it, a `RobotLab::DependencyError` is caught and logged rather than raised, so the robot continues running uncompressed.
278
+
279
+ ---
280
+
165
281
  ## Learning Accumulation
166
282
 
167
283
  ### The Problem
@@ -238,6 +354,21 @@ end
238
354
 
239
355
  After all three runs, `reviewer.learnings` contains up to three insights (fewer if any are subsets of others).
240
356
 
357
+ ### Durable Learning (learn: Constructor Shorthand)
358
+
359
+ The `robot_lab-durable` gem adds automatic end-of-session learning promotion. Enable it with `learn: true` in the constructor:
360
+
361
+ ```ruby
362
+ reviewer = RobotLab.build(
363
+ name: "reviewer",
364
+ system_prompt: "You are a Ruby code reviewer.",
365
+ learn: true,
366
+ learn_domain: "ruby_review" # optional namespace for the durable store
367
+ )
368
+ ```
369
+
370
+ At the end of each session, the robot reflects on its observations and promotes durable insights to a YAML-backed store that persists across process restarts. On the next run, those stored insights are automatically reloaded as learnings.
371
+
241
372
  ### Memory Persistence
242
373
 
243
374
  Learnings are stored in `memory[:learnings]`. They survive a robot rebuild when the same `Memory` object is passed to the new robot:
@@ -484,3 +615,4 @@ puts "#{analysis.robot_name} (#{analysis.duration.round(2)}s): #{analysis.reply}
484
615
  - [Example 22 — Context Window Compression](../../examples/22_context_compression.rb)
485
616
  - [Example 23 — Convergence Detection](../../examples/23_convergence.rb)
486
617
  - [Example 24 — Structured Delegation](../../examples/24_structured_delegation.rb)
618
+ - [RunConfig reference](../getting-started/configuration.md#runconfig-shared-operational-defaults)
data/docs/index.md CHANGED
@@ -116,16 +116,43 @@ Each robot is backed by a persistent LLM chat, configured with keyword arguments
116
116
 
117
117
  [:octicons-arrow-right-24: Configuration](getting-started/configuration.md)
118
118
 
119
- - :material-train-car-container:{ .lg .middle } **Rails Integration**
119
+ - :material-shield-check:{ .lg .middle } **Observability & Safety**
120
120
 
121
121
  ---
122
122
 
123
- Generators, background jobs, and Turbo Stream token broadcasting for real-time streaming to the browser.
123
+ Token tracking, `max_tool_rounds` circuit breaker, `doom_loop_threshold` pattern detection, and `auto_compact` context window management keep robots reliable in production.
124
124
 
125
- [:octicons-arrow-right-24: Rails Guide](guides/rails-integration.md)
125
+ [:octicons-arrow-right-24: Observability Guide](guides/observability.md)
126
+
127
+ - :material-brain:{ .lg .middle } **Runtime Skill Matching**
128
+
129
+ ---
130
+
131
+ `AgentSkillMatching` selects the most relevant `AgentSkill` files from a catalog directory via semantic similarity before each `run()`, injecting only what the robot needs.
132
+
133
+ [:octicons-arrow-right-24: Using Tools](guides/using-tools.md)
134
+
135
+ - :material-book-open-outline:{ .lg .middle } **Knowledge & Retrieval**
136
+
137
+ ---
138
+
139
+ `robot.search_history` for semantic search over conversation turns, and `memory.store_document` / `memory.search_documents` for embedding-based RAG.
140
+
141
+ [:octicons-arrow-right-24: Knowledge Guide](guides/knowledge.md)
126
142
 
127
143
  </div>
128
144
 
145
+ ## Extension Gems
146
+
147
+ These optional gems extend RobotLab with additional capabilities:
148
+
149
+ | Gem | What it adds |
150
+ |-----|-------------|
151
+ | [robot_lab-rails](https://github.com/MadBomber/robot_lab-rails) | Rails Engine, generators, `RobotLab::Job` base class, Turbo Stream broadcasting |
152
+ | [robot_lab-ractor](https://github.com/MadBomber/robot_lab-ractor) | CPU parallelism for `ractor_safe` tools and robot networks via Ruby Ractors |
153
+ | [robot_lab-durable](https://github.com/MadBomber/robot_lab-durable) | Cross-session knowledge persistence — robots accumulate and recall learned facts |
154
+ | [robot_lab-document_store](https://github.com/MadBomber/robot_lab-document_store) | Embedding-based semantic document search powered by fastembed |
155
+
129
156
  ## Quick Example
130
157
 
131
158
  ```ruby