robot_lab 0.3.0 → 0.3.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +1 -1
  4. data/lib/robot_lab/mcp/transports/streamable_http.rb +1 -1
  5. data/lib/robot_lab/version.rb +1 -1
  6. metadata +3 -253
  7. data/.architecture/AGENTS.md +0 -32
  8. data/.architecture/config.yml +0 -8
  9. data/.architecture/members.yml +0 -60
  10. data/.architecture/reviews/feature-free-will.md +0 -490
  11. data/.architecture/reviews/overall-codebase.md +0 -427
  12. data/.claude/settings.local.json +0 -57
  13. data/.codex/config.toml +0 -2
  14. data/.envrc +0 -6
  15. data/.github/workflows/deploy-github-pages.yml +0 -52
  16. data/.irbrc +0 -6
  17. data/.loki +0 -65
  18. data/.quality/reek_baseline.txt +0 -43
  19. data/.rubocop.yml +0 -10
  20. data/Archspec.rb +0 -44
  21. data/CLAUDE.md +0 -141
  22. data/COMMITS.md +0 -196
  23. data/Rakefile +0 -193
  24. data/_typos.toml +0 -21
  25. data/agent2agent_review.md +0 -192
  26. data/agentf_improvements.md +0 -253
  27. data/agents.md +0 -14
  28. data/docs/api/core/index.md +0 -147
  29. data/docs/api/core/memory.md +0 -578
  30. data/docs/api/core/network.md +0 -553
  31. data/docs/api/core/result.md +0 -211
  32. data/docs/api/core/robot.md +0 -1667
  33. data/docs/api/core/state.md +0 -145
  34. data/docs/api/core/tool.md +0 -520
  35. data/docs/api/errors.md +0 -323
  36. data/docs/api/hooks.md +0 -469
  37. data/docs/api/index.md +0 -137
  38. data/docs/api/mcp/client.md +0 -387
  39. data/docs/api/mcp/index.md +0 -267
  40. data/docs/api/mcp/server.md +0 -252
  41. data/docs/api/mcp/transports.md +0 -339
  42. data/docs/api/messages/index.md +0 -126
  43. data/docs/api/messages/text-message.md +0 -170
  44. data/docs/api/messages/tool-call-message.md +0 -206
  45. data/docs/api/messages/tool-result-message.md +0 -242
  46. data/docs/api/messages/user-message.md +0 -232
  47. data/docs/api/skills.md +0 -423
  48. data/docs/api/streaming/context.md +0 -280
  49. data/docs/api/streaming/events.md +0 -185
  50. data/docs/api/streaming/index.md +0 -156
  51. data/docs/api/support.md +0 -846
  52. data/docs/architecture/core-concepts.md +0 -575
  53. data/docs/architecture/index.md +0 -252
  54. data/docs/architecture/message-flow.md +0 -366
  55. data/docs/architecture/network-orchestration.md +0 -478
  56. data/docs/architecture/robot-execution.md +0 -396
  57. data/docs/architecture/state-management.md +0 -410
  58. data/docs/assets/css/custom.css +0 -56
  59. data/docs/assets/images/robot_lab.jpg +0 -0
  60. data/docs/concepts.md +0 -641
  61. data/docs/examples/basic-chat.md +0 -258
  62. data/docs/examples/index.md +0 -425
  63. data/docs/examples/mcp-server.md +0 -403
  64. data/docs/examples/multi-robot-network.md +0 -476
  65. data/docs/examples/tool-usage.md +0 -468
  66. data/docs/getting-started/configuration.md +0 -645
  67. data/docs/getting-started/index.md +0 -56
  68. data/docs/getting-started/installation.md +0 -197
  69. data/docs/getting-started/quick-start.md +0 -293
  70. data/docs/guides/building-robots.md +0 -1187
  71. data/docs/guides/creating-networks.md +0 -736
  72. data/docs/guides/hooks.md +0 -1206
  73. data/docs/guides/index.md +0 -78
  74. data/docs/guides/knowledge.md +0 -219
  75. data/docs/guides/mcp-integration.md +0 -740
  76. data/docs/guides/memory.md +0 -458
  77. data/docs/guides/observability.md +0 -733
  78. data/docs/guides/streaming.md +0 -323
  79. data/docs/guides/using-tools.md +0 -780
  80. data/docs/index.md +0 -280
  81. data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
  82. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
  83. data/examples/.envrc +0 -3
  84. data/examples/01_simple_robot.rb +0 -31
  85. data/examples/02_tools.rb +0 -109
  86. data/examples/03_network.rb +0 -118
  87. data/examples/04_mcp.rb +0 -217
  88. data/examples/05_streaming.rb +0 -137
  89. data/examples/06_prompt_templates.rb +0 -325
  90. data/examples/07_network_memory.rb +0 -313
  91. data/examples/08_llm_config.rb +0 -162
  92. data/examples/09_chaining.rb +0 -251
  93. data/examples/10_memory.rb +0 -315
  94. data/examples/11_network_introspection.rb +0 -239
  95. data/examples/12_message_bus.rb +0 -67
  96. data/examples/13_spawn.rb +0 -85
  97. data/examples/14_rusty_circuit/.envrc +0 -1
  98. data/examples/14_rusty_circuit/.gitignore +0 -1
  99. data/examples/14_rusty_circuit/README.md +0 -1
  100. data/examples/14_rusty_circuit/comic.rb +0 -149
  101. data/examples/14_rusty_circuit/display.rb +0 -217
  102. data/examples/14_rusty_circuit/heckler.rb +0 -65
  103. data/examples/14_rusty_circuit/open_mic.rb +0 -132
  104. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
  105. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
  106. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
  107. data/examples/14_rusty_circuit/scout.rb +0 -165
  108. data/examples/14_rusty_circuit/show.log +0 -234
  109. data/examples/15_memory_network_and_bus/.envrc +0 -1
  110. data/examples/15_memory_network_and_bus/README.md +0 -66
  111. data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
  112. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
  113. data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
  114. data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
  115. data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
  116. data/examples/15_memory_network_and_bus/output/combined_article.md +0 -11
  117. data/examples/15_memory_network_and_bus/output/final_article.md +0 -8
  118. data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
  119. data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
  120. data/examples/15_memory_network_and_bus/output/memory.json +0 -13
  121. data/examples/15_memory_network_and_bus/output/revision_1.md +0 -29
  122. data/examples/15_memory_network_and_bus/output/revision_2.md +0 -50
  123. data/examples/15_memory_network_and_bus/output/revision_3.md +0 -8
  124. data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
  125. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
  126. data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
  127. data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
  128. data/examples/16_writers_room/.envrc +0 -1
  129. data/examples/16_writers_room/display.rb +0 -158
  130. data/examples/16_writers_room/output/.gitignore +0 -4
  131. data/examples/16_writers_room/output/README.md +0 -69
  132. data/examples/16_writers_room/output/opus_001.md +0 -263
  133. data/examples/16_writers_room/output/opus_001_notes.log +0 -470
  134. data/examples/16_writers_room/output/opus_002.md +0 -245
  135. data/examples/16_writers_room/output/opus_002_notes.log +0 -546
  136. data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
  137. data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
  138. data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
  139. data/examples/16_writers_room/prompts/writer.md +0 -37
  140. data/examples/16_writers_room/room.rb +0 -186
  141. data/examples/16_writers_room/tools.rb +0 -173
  142. data/examples/16_writers_room/writer.rb +0 -121
  143. data/examples/16_writers_room/writers_room.rb +0 -256
  144. data/examples/17_skills.rb +0 -234
  145. data/examples/18_rails/.envrc +0 -3
  146. data/examples/18_rails/.gitignore +0 -5
  147. data/examples/18_rails/Gemfile +0 -11
  148. data/examples/18_rails/README.md +0 -67
  149. data/examples/18_rails/Rakefile +0 -4
  150. data/examples/18_rails/app/controllers/application_controller.rb +0 -4
  151. data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
  152. data/examples/18_rails/app/jobs/application_job.rb +0 -4
  153. data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
  154. data/examples/18_rails/app/models/application_record.rb +0 -5
  155. data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
  156. data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
  157. data/examples/18_rails/app/robots/chat_robot.rb +0 -25
  158. data/examples/18_rails/app/tools/time_tool.rb +0 -9
  159. data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
  160. data/examples/18_rails/app/views/chat/index.html.erb +0 -67
  161. data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
  162. data/examples/18_rails/bin/dev +0 -7
  163. data/examples/18_rails/bin/rails +0 -6
  164. data/examples/18_rails/bin/setup +0 -15
  165. data/examples/18_rails/config/application.rb +0 -33
  166. data/examples/18_rails/config/cable.yml +0 -2
  167. data/examples/18_rails/config/database.yml +0 -5
  168. data/examples/18_rails/config/environment.rb +0 -4
  169. data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
  170. data/examples/18_rails/config/routes.rb +0 -6
  171. data/examples/18_rails/config.ru +0 -4
  172. data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
  173. data/examples/19_token_tracking.rb +0 -138
  174. data/examples/20_circuit_breaker.rb +0 -147
  175. data/examples/21_learning_loop.rb +0 -181
  176. data/examples/22_context_compression.rb +0 -172
  177. data/examples/23_convergence.rb +0 -133
  178. data/examples/24_structured_delegation.rb +0 -151
  179. data/examples/25_history_search/conversation.jsonl +0 -30
  180. data/examples/25_history_search.rb +0 -133
  181. data/examples/26_document_store/api_versioning_adr.md +0 -52
  182. data/examples/26_document_store/incident_postmortem.md +0 -46
  183. data/examples/26_document_store/postgres_runbook.md +0 -49
  184. data/examples/26_document_store/redis_caching_guide.md +0 -48
  185. data/examples/26_document_store/sidekiq_guide.md +0 -51
  186. data/examples/26_document_store.rb +0 -140
  187. data/examples/27_incident_response/README.md +0 -65
  188. data/examples/27_incident_response/incident_response.rb +0 -261
  189. data/examples/28_mcp_discovery.rb +0 -113
  190. data/examples/29_ractor_tools.rb +0 -240
  191. data/examples/30_ractor_network.rb +0 -252
  192. data/examples/31_launch_assessment.rb +0 -246
  193. data/examples/32_newsletter_reader.rb +0 -193
  194. data/examples/33_stock_generator.rb +0 -80
  195. data/examples/33_stock_predictor.rb +0 -327
  196. data/examples/34_agentskills.rb +0 -76
  197. data/examples/35_hooks.rb +0 -266
  198. data/examples/README.md +0 -550
  199. data/examples/common.rb +0 -180
  200. data/examples/prompts/assistant.md +0 -5
  201. data/examples/prompts/audit_trail.md +0 -8
  202. data/examples/prompts/billing.md +0 -10
  203. data/examples/prompts/classifier.md +0 -7
  204. data/examples/prompts/comedian.md +0 -6
  205. data/examples/prompts/comedy_critic.md +0 -10
  206. data/examples/prompts/configurable.md +0 -9
  207. data/examples/prompts/dispatcher.md +0 -12
  208. data/examples/prompts/entity_extractor.md +0 -14
  209. data/examples/prompts/escalation.md +0 -42
  210. data/examples/prompts/frontmatter_mcp_test.md +0 -9
  211. data/examples/prompts/frontmatter_named_test.md +0 -5
  212. data/examples/prompts/frontmatter_tools_test.md +0 -6
  213. data/examples/prompts/general.md +0 -7
  214. data/examples/prompts/github_assistant.md +0 -14
  215. data/examples/prompts/helper.md +0 -4
  216. data/examples/prompts/incident_responder.md +0 -18
  217. data/examples/prompts/keyword_extractor.md +0 -11
  218. data/examples/prompts/llm_config_demo.md +0 -20
  219. data/examples/prompts/order_support.md +0 -35
  220. data/examples/prompts/os_advocate.md +0 -13
  221. data/examples/prompts/os_chief.md +0 -13
  222. data/examples/prompts/os_editor.md +0 -13
  223. data/examples/prompts/parameterized_main_test.md +0 -6
  224. data/examples/prompts/pii_redactor.md +0 -7
  225. data/examples/prompts/product_support.md +0 -37
  226. data/examples/prompts/runbook_protocol.md +0 -12
  227. data/examples/prompts/sentiment_analyzer.md +0 -12
  228. data/examples/prompts/skill_a_test.md +0 -4
  229. data/examples/prompts/skill_b_test.md +0 -4
  230. data/examples/prompts/skill_config_test.md +0 -5
  231. data/examples/prompts/skill_cycle_a_test.md +0 -6
  232. data/examples/prompts/skill_cycle_b_test.md +0 -6
  233. data/examples/prompts/skill_description_test.md +0 -4
  234. data/examples/prompts/skill_leaf_test.md +0 -4
  235. data/examples/prompts/skill_nested_test.md +0 -6
  236. data/examples/prompts/skill_refs_main_test.md +0 -6
  237. data/examples/prompts/skill_self_ref_test.md +0 -6
  238. data/examples/prompts/skill_with_mcp_test.md +0 -9
  239. data/examples/prompts/skill_with_params_test.md +0 -6
  240. data/examples/prompts/skill_with_robot_name_test.md +0 -5
  241. data/examples/prompts/skill_with_tools_test.md +0 -6
  242. data/examples/prompts/sre_compliance.md +0 -10
  243. data/examples/prompts/structured_output.md +0 -7
  244. data/examples/prompts/synthesizer.md +0 -17
  245. data/examples/prompts/technical.md +0 -10
  246. data/examples/prompts/template_with_skills_test.md +0 -6
  247. data/examples/prompts/triage.md +0 -22
  248. data/examples/ruboruby.md +0 -423
  249. data/examples/run_all.rb +0 -60
  250. data/examples/xyzzy.rb +0 -97
  251. data/logfile +0 -8
  252. data/mkdocs.yml +0 -209
  253. data/robot_concurrency.md +0 -38
  254. data/simple_acp_review.md +0 -298
  255. data/temp.md +0 -6
  256. data/tool_manifest_plan.md +0 -155
data/examples/README.md DELETED
@@ -1,550 +0,0 @@
1
- # RobotLab Examples
2
-
3
- Working demonstrations of RobotLab features, from single-robot basics to multi-robot orchestration and message bus communication.
4
-
5
- > **A note on performance:** how fast (and how well) these demos run depends
6
- > almost entirely on which provider and model you point them at. A large model
7
- > served locally on consumer hardware can take a minute or more per LLM call,
8
- > while a small local model or a hosted API answers in seconds — and smaller
9
- > models may also give noticeably weaker answers on the multi-robot demos.
10
- > Wall-clock times you see will differ from anyone else's; tune the
11
- > provider/model in `common.rb` (or via `LLM_PROFILE`) to trade speed against
12
- > quality.
13
-
14
- ## Prerequisites
15
-
16
- - Ruby >= 3.2
17
- - `bundle install` (from the project root)
18
- - [Ollama](https://ollama.com) running locally with the demo model pulled:
19
-
20
- ```bash
21
- ollama serve
22
- ollama pull qwen3.6
23
- ```
24
-
25
- Every example runs against a **local** model — no API keys, no egress, no
26
- per-token cost. The model, provider and endpoint are set in one place,
27
- `examples/common.rb`:
28
-
29
- ```ruby
30
- LLM = {
31
- default: LlmConfig.new(provider: "ollama", model: "qwen3.6:latest"),
32
- small: LlmConfig.new(provider: "ollama", model: "qwen2.5:7b"),
33
- large: LlmConfig.new(provider: "ollama", model: "llama3.3:latest")
34
- }
35
- ```
36
-
37
- Robots pick it up with the `llm_opts` helper:
38
-
39
- ```ruby
40
- robot = RobotLab.build(name: "helper", **llm_opts) # default model
41
- cheap = RobotLab.build(name: "helper", **llm_opts(:small)) # smaller model
42
- ```
43
-
44
- `provider:` is not optional here. Ollama models are absent from RubyLLM's
45
- model registry, so passing `model:` alone raises `RubyLLM::ModelNotFoundError`
46
- — supplying `provider:` is what makes RubyLLM skip the registry lookup. Note
47
- also that `RunConfig` has no `provider` field, so provider and model travel
48
- together on the robot even when other settings come from a shared `RunConfig`.
49
-
50
- `common.rb` also raises `request_timeout` to 900s. A 20B+ model on consumer
51
- hardware routinely takes longer than robot_lab's 120s default on a long
52
- answer, which otherwise surfaces mid-example as `Net::ReadTimeout`. Override
53
- with `LLM_REQUEST_TIMEOUT`.
54
-
55
- ## Runtime: pick your model with `LLM_PROFILE`
56
-
57
- Every example is a *sequence* of LLM calls, so wall-clock is dominated by
58
- `calls × seconds-per-call`. On `qwen3.6:latest` expect roughly **60-70s per
59
- call**. That is fine for the single-robot examples and painful for the
60
- multi-robot ones:
61
-
62
- | Example | LLM calls | `qwen3.6:latest` | `LLM_PROFILE=small` |
63
- |---------|-----------|------------------|---------------------|
64
- | 01, 02, 19, 20 | 1-6 | seconds to ~5 min | fast |
65
- | 03, 06, 07, 24, 27, 31 | 4-8 | ~5-10 min | ~2 min |
66
- | 13, 14, 15 | ~20-30 | **30-40 min** | ~5-10 min |
67
- | 16 | unbounded (600s cap) | usually hits the cap | often completes |
68
-
69
- `LLM_PROFILE` switches the model for any example without editing it:
70
-
71
- ```bash
72
- LLM_PROFILE=small bundle exec ruby examples/14_rusty_circuit/open_mic.rb
73
- ```
74
-
75
- Valid values are the keys of `LLM` in `common.rb`: `default`, `small`, `large`.
76
-
77
- **Long silences are not hangs.** In example 14 the scout writes its notes to
78
- `output/scout_notes.md` rather than STDOUT, and a scout turn is 1-4 sequential
79
- calls — minutes of blank terminal. The `· Scout …` lines exist so you can tell
80
- progress from a stall. Example 16 is the same idea at larger scale: writers
81
- coordinate through shared memory, and much of the work shows up in
82
- `output/room.log` rather than on screen.
83
-
84
- ## Running Examples
85
-
86
- ```bash
87
- # Run a specific example by number
88
- bundle exec rake examples:run[1]
89
-
90
- # Run all examples
91
- bundle exec rake examples:all
92
-
93
- # Run directly
94
- bundle exec ruby examples/01_simple_robot.rb
95
-
96
- # Run every demo serially with a banner between each (works from any cwd)
97
- examples/run_all.rb
98
- ```
99
-
100
- `run_all.rb` executes every executable `NN_*.rb` demo in order, announcing
101
- each one with a banner so the outputs stay separated. Ctrl-C kills only the
102
- demo that is currently running — the runner notes the interruption and moves
103
- on to the next demo.
104
-
105
- ## Tools require `tools: :inherit` at run time
106
-
107
- This trips up everyone once. `Robot#run` defaults to `tools: :none`, which
108
- means *"send zero tools this turn"* — the robot still holds them in
109
- `local_tools`, but the provider never sees them and the model answers from
110
- memory instead of calling anything:
111
-
112
- ```ruby
113
- robot = RobotLab.build(name: "bot", **llm_opts, local_tools: [Calculator])
114
-
115
- robot.run("What is 15 * 7?") # Calculator is NEVER offered
116
- robot.run("What is 15 * 7?", tools: :inherit) # Calculator is offered
117
- ```
118
-
119
- The same applies to MCP (`mcp: :inherit`), to network tasks
120
- (`task :name, robot, tools: :inherit`), and to anything that forwards keywords
121
- into `run` — including `RobotLab::RailsIntegration::Job`. Examples 02, 04, 06,
122
- 14, 15, 16, 20, 33 and the Rails app all pass it explicitly.
123
-
124
- ## Directory Structure
125
-
126
- ```
127
- examples/
128
- common.rb # Shared LLM config (Ollama), llm_opts, output helpers
129
- xyzzy.rb # Single-file hook extension used by 35
130
- 01_simple_robot.rb # Basic robot with template
131
- 02_tools.rb # Robot with custom tools
132
- 03_network.rb # Multi-robot network with routing
133
- 04_mcp.rb # MCP server integration (GitHub)
134
- 05_streaming.rb # Real-time streaming callbacks
135
- 06_prompt_templates.rb # Template-based e-commerce support
136
- 07_network_memory.rb # Shared memory with concurrent robots
137
- 08_llm_config.rb # Configuration hierarchy demo
138
- 09_chaining.rb # with_* method chaining & reconfiguration
139
- 10_memory.rb # Advanced Memory API operations
140
- 11_network_introspection.rb # Network visualization & inspection
141
- 12_message_bus.rb # Bidirectional robot communication
142
- 13_spawn.rb # Dynamic specialist robot spawning
143
- 14_rusty_circuit/ # Multi-robot open mic with self-modification
144
- open_mic.rb # Main entrypoint — wires up the show
145
- comic.rb # Comedian with self-modification tools
146
- heckler.rb # Audience heckler (can stay silent or counter-joke)
147
- scout.rb # Talent scout with analyst spawning
148
- display.rb # Terminal formatting (color, wrapping, file output)
149
- prompts/ # Templates for comic, heckler, and scout
150
- 15_memory_network_and_bus/ # Network + memory + bus + spawn in one pipeline
151
- editorial_pipeline.rb # Main entrypoint — three writers, editor, chief
152
- 16_writers_room/ # Self-organizing group: no orchestration at all
153
- writers_room.rb # Main entrypoint — book and screenplay modes
154
- 17_skills.rb # Composable skills, flat and recursive
155
- 18_rails/ # Minimal Rails 8 demo app (full integration)
156
- app/robots/chat_robot.rb # Robot factory with system prompt + TimeTool
157
- app/tools/time_tool.rb # Custom RobotLab::Tool subclass
158
- app/jobs/robot_run_job.rb # Background job with Turbo Stream callbacks
159
- app/controllers/ # Chat controller (index + create)
160
- app/views/ # Layout with CDN importmap, chat view with streaming
161
- app/models/ # RobotLabThread, RobotLabResult
162
- config/ # Minimal Rails 8 config (async adapters, no asset pipeline)
163
- db/migrate/ # Migration from generator template
164
- 19_token_tracking.rb # Per-robot token & cost tracking
165
- 20_circuit_breaker.rb # Tool loop circuit breaker with max_tool_rounds
166
- 21_learning_loop.rb # Learning accumulation across runs with robot.learn
167
- 22_context_compression.rb # Context window compression with HistoryCompressor
168
- 23_convergence.rb # Debate convergence detection and reconciler fast-path
169
- 24_structured_delegation.rb # Structured delegation with duration and token tracking
170
- 25_history_search.rb # Semantic search over a robot's conversation history
171
- 26_document_store.rb # Embedding-based document store (RAG) via fastembed
172
- 27_incident_response/ # BusPoller, reactive memory, poller groups
173
- incident_response.rb # Main entrypoint — wires up the war room
174
- 28_mcp_discovery.rb # Semantic MCP server selection before connecting
175
- 29_ractor_tools.rb # Ractor-safe tools: worker pool, freeze_deep, parallel batch
176
- 30_ractor_network.rb # Ractor network scheduler: dependency waves, parallel_mode
177
- 31_launch_assessment.rb # 6 parallel analysts, max_concurrent_robots: 4 semaphore cap
178
- 32_newsletter_reader.rb # Utility script (no RobotLab) — RSS to Markdown
179
- 33_stock_generator.rb # Companion publisher for 33_stock_predictor (Redis)
180
- 33_stock_predictor.rb # Durable cross-session learning via robot_lab-durable
181
- 34_agentskills.rb # AgentSkills.io folder-format skills, matched per run
182
- 35_hooks.rb # Hook architecture demo using xyzzy.rb
183
- prompts/ # Prompt templates (.md with YAML front matter)
184
- ```
185
-
186
- ## Examples
187
-
188
- ### 01 — Simple Robot
189
-
190
- Create and run a basic robot using a prompt template. Sends a single message and displays the response.
191
-
192
- **Requires:** Ollama
193
-
194
- ### 02 — Tools
195
-
196
- Give a robot custom tools (`Calculator`, `FortuneCookie`) defined as `RubyLLM::Tool` subclasses. The LLM decides when to call each tool based on the user's request.
197
-
198
- **Requires:** Ollama
199
-
200
- ### 03 — Multi-Robot Network
201
-
202
- Build a customer support network with a classifier robot that routes requests to billing, technical, or general specialists. Uses SimpleFlow's optional task activation for conditional routing.
203
-
204
- **Requires:** Ollama
205
-
206
- ### 04 — MCP Integration
207
-
208
- Connect to the GitHub MCP server via stdio transport. Part 1 demonstrates direct `MCP::Client` usage (listing tools, calling `search_repositories`). Part 2 wraps the MCP server inside a robot for natural-language queries.
209
-
210
- **Requires:** Ollama, `GITHUB_PERSONAL_ACCESS_TOKEN`, `github-mcp-server` installed
211
-
212
- ### 05 — Streaming
213
-
214
- Real-time streaming of robot responses through four routes: the stored `on_content:` callback wired at build time, a per-call block passed to `run()`, both together (stored fires first, then the block), and `on_content` arriving through a `RunConfig`.
215
-
216
- **Requires:** Ollama (makes four live calls)
217
-
218
- ### 06 — Prompt Templates
219
-
220
- Full e-commerce support system using prompt_manager templates with YAML front matter. A triage robot classifies customer requests and routes to order, product, or escalation specialists. Demonstrates build-time context (company info, policies) and run-time context (customer data, order history).
221
-
222
- **Requires:** Ollama
223
-
224
- ### 07 — Network Memory
225
-
226
- Reactive shared memory with concurrent robots. Multiple analysis robots (sentiment, entity extraction, keywords) run in parallel and write to shared memory. A synthesizer robot waits for all results using blocking reads, then produces a combined analysis. Demonstrates subscriptions, notifications, and network broadcast.
227
-
228
- **Requires:** Ollama
229
-
230
- ### 08 — LLM Configuration
231
-
232
- Walks through the full configuration hierarchy without making LLM calls:
233
-
234
- 1. Bundled defaults
235
- 2. Environment-specific overrides
236
- 3. XDG user config
237
- 4. Project config
238
- 5. Environment variables
239
- 6. Template front matter
240
- 7. Constructor parameters
241
- 8. `with_*` method chaining
242
- 9. Run-time context
243
-
244
- **Requires:** None (no LLM calls)
245
-
246
- ### 09 — Chaining & Reconfiguration
247
-
248
- Demonstrates the Robot API surface for runtime configuration: `with_*` method chaining, `update()` for reconfiguration, `to_h` introspection, config diffs between steps, and how constructor params override template front matter.
249
-
250
- **Requires:** None (no LLM calls)
251
-
252
- ### 10 — Advanced Memory
253
-
254
- Comprehensive Memory API demo: `StateProxy` for method-style access, key and pattern subscriptions, `MemoryChange` objects, key enumeration, serialization round-trips, clone for isolated copies, delete with reserved key protection, and clear vs reset.
255
-
256
- **Requires:** None (no LLM calls)
257
-
258
- ### 11 — Network Introspection
259
-
260
- Network visualization and inspection tools: `to_mermaid()` for diagram export, `to_dot()` for Graphviz, `execution_plan()` for text output, `visualize()` for ASCII pipelines, robot access by name, dynamic `add_robot()`, `to_h()` introspection, task-specific config, and `broadcast()`.
261
-
262
- **Requires:** None (no LLM calls)
263
-
264
- ### 12 — Message Bus
265
-
266
- Bidirectional robot communication via TypedBus. A comedy critic (Alice) tasks a comedian (Bob) to tell robot jokes. Alice evaluates each joke with her LLM; if it's not funny, she sends Bob back for another attempt. Bob's temperature ramps from 0.2 to 1.0 across retries for increasing creativity. The loop continues until Alice approves or `MAX_ATTEMPTS` is reached.
267
-
268
- Demonstrates: Robot subclasses, prompt templates, auto-ack `on_message`, `reply()` convenience, temperature ramping, convergence patterns.
269
-
270
- **Requires:** Ollama
271
-
272
- ### 13 — Spawning Robots
273
-
274
- Dynamic specialist creation at runtime. A dispatcher robot receives questions, asks its LLM what kind of specialist is needed, then uses `spawn` to create one on the fly. The bus is created lazily on the first spawn — no explicit bus setup required. Spawned specialists are reused across questions of the same type.
275
-
276
- Demonstrates: `spawn` for dynamic robot creation, lazy bus creation, `on_message` for reply handling, LLM-driven delegation.
277
-
278
- **Requires:** Ollama
279
-
280
- ### 14 — The Rusty Circuit (Open Mic Night)
281
-
282
- A comedy club where three robots interact through a shared message bus. A comedian performs stand-up armed with self-modification tools (style reinvention, energy adjustment, coaching). A heckler reacts from the audience — heckling weak material, telling counter-jokes with the comic as the punch line, showing grudging respect, or staying silent when a bit doesn't warrant a response. A talent scout observes silently, spawning specialist analysts and refining evaluation criteria before delivering a final verdict.
283
-
284
- Terminal output is color-formatted: comic bits in cyan (left-aligned), heckler reactions in yellow (right-indented), tool annotations dimmed. Scout notes go to `scout_notes.md` instead of STDOUT. The final verdict appears in green on both STDOUT and the scout file.
285
-
286
- Demonstrates: Robot subclasses, self-modification via tool side effects, dynamic spawning (`spawn`), shared `:room` channel + personal channels, `enqueue_delivery` for serializing async deliveries, `[SILENCE]` opt-out pattern, style reinvention via user-prompt injection.
287
-
288
- **Requires:** Ollama. The most expensive example in the suite — ~30 LLM calls, 30+ minutes on `qwen3.6`. Use `LLM_PROFILE=small` to watch it in under ten.
289
-
290
- ### 15 — Memory, Network, Bus & Spawn Together
291
-
292
- An editorial pipeline where three writers advocate for macOS, Windows, and Linux/BSD as a home AI research lab platform. The network runs the writers in parallel and hands their drafts to an editor through shared memory; the Linux writer spawns three distro specialists mid-pipeline; an editor-in-chief outside the pipeline reviews the combined article over the bus and can demand revisions.
293
-
294
- Demonstrates: all four coordination mechanisms in one program, plus the direct `shared_memory` reference pattern that parallel pipeline steps need (`extract_run_context` deletes from a shared hash, so only the first parallel step would otherwise see `network_memory`).
295
-
296
- **Requires:** Ollama
297
-
298
- ### 16 — The Writers' Room (Self-Organizing Group)
299
-
300
- A team of identical writer robots produces a 10-chapter novella with no orchestration, no pipeline, and no assigned roles. Each writer subscribes to a `:room` broadcast channel and a personal channel, and has tools to read/write shared memory, broadcast, DM, spawn more writers, and mark the work complete. The script seeds the room with an assignment and waits.
301
-
302
- `--screenplay-from output/memory.json` re-runs the room in screenplay mode, adapting a finished book into a 4-act TV movie pilot at scene granularity.
303
-
304
- Demonstrates: emergent coordination, `clear_messages(keep_system: true)` as a per-message conversation reset, dynamic team growth, memory as the single source of truth.
305
-
306
- **Requires:** Ollama (long-running — `--timeout` defaults to 600s)
307
-
308
- ### 17 — Composable Skills
309
-
310
- Skills are ordinary templates whose bodies are prepended to the main template. An SRE incident responder is composed from `runbook_protocol` and `structured_output` (flat skills) plus `sre_compliance`, which recursively expands to `pii_redactor` and `audit_trail`. The assembled system prompt is printed line-by-line so the depth-first expansion order is visible, and a skill-less robot is built alongside it for size comparison.
311
-
312
- **Requires:** Ollama
313
-
314
- ### 19 — Token & Cost Tracking
315
-
316
- Track token usage across runs using `result.input_tokens` / `result.output_tokens` for per-run counts and `robot.total_input_tokens` / `robot.total_output_tokens` for running totals. Demonstrates `reset_token_totals` to start a fresh batch. Local inference is free, so cost is reported as `$0.00000 (local)`; set `RATE_INPUT_CPM` / `RATE_OUTPUT_CPM` to price the same traffic against a hosted provider.
317
-
318
- **Requires:** Ollama
319
-
320
- ### 20 — Tool Loop Circuit Breaker
321
-
322
- Guards against runaway tool call loops using `max_tool_rounds:`. A step processor tool is designed to always return "more steps remain", which would loop indefinitely without a guard. The circuit breaker fires after the configured limit and raises `RobotLab::ToolLoopError`. Shows how to rescue the error gracefully and confirms the robot is fully reusable after a breaker trip.
323
-
324
- **Requires:** Ollama
325
-
326
- ### 21 — Learning Accumulation Loop
327
-
328
- Builds up cross-run observations with `robot.learn(text)`. A code reviewer accumulates one key insight after each review. On subsequent runs, learnings are automatically prepended to the user message as a "LEARNINGS FROM PREVIOUS RUNS:" block. Demonstrates bidirectional substring deduplication (broader learnings replace narrower ones), the `robot.learnings` accessor, and how learnings survive a robot rebuild via the shared `Memory` object.
329
-
330
- **Requires:** Ollama
331
-
332
- ### 22 — Context Window Compression
333
-
334
- Demonstrates `robot.compress_history()` for reducing token usage in long conversations. Old turns are scored against the recent context using stemmed term-frequency cosine similarity (via the `classifier` gem). High-relevance turns are kept verbatim; irrelevant turns are dropped; medium-relevance turns can optionally be summarized by a second robot. Shows both drop-mode and summarizer-lambda patterns, plus the LLM summarizer integration recipe.
335
-
336
- **Requires:** `gem 'classifier', '~> 2.3'` in your Gemfile (no LLM calls in the demo itself)
337
-
338
- ### 23 — Debate Convergence Detection
339
-
340
- Demonstrates `RobotLab::Convergence` for detecting when two independent agents have reached the same conclusion. Scores pairs of texts from identical → semantically similar → partially related → unrelated, showing how the similarity metric varies. Includes the fast-path pattern: a gate robot compares two verifiers' replies and only activates the expensive reconciler — via SimpleFlow optional-task activation — when they disagree.
341
-
342
- **Requires:** `gem 'classifier', '~> 2.3'` in your Gemfile (no LLM calls in the demo itself)
343
-
344
- ### 24 — Structured Delegation
345
-
346
- Demonstrates `robot.delegate(to:, task:)` for synchronous and asynchronous inter-robot delegation. The manager robot delegates document analysis to a summarizer and an analyst. Shows synchronous (sequential, blocking) and asynchronous (parallel fan-out, `DelegationFuture`) modes with wall-time comparison. Each result carries `delegated_by`, `duration`, and token counts.
347
-
348
- **Requires:** Ollama
349
-
350
- ### 25 — Chat History Search
351
-
352
- Demonstrates `robot.search_history(query, limit:)` — semantic search over accumulated conversation turns using stemmed TF cosine similarity. No LLM calls: messages are injected directly. Shows relevance ranking, role preservation, short-message filtering, and the `DependencyError` guard.
353
-
354
- **Requires:** `gem 'classifier', '~> 2.3'` in your Gemfile (no LLM calls)
355
-
356
- ### 26 — Embedding-Based Document Store
357
-
358
- Demonstrates `memory.store_document(key, text)` and `memory.search_documents(query, limit:)` — a lightweight RAG store using `fastembed` (BAAI/bge-small-en-v1.5). Documents are embedded once; queries are compared by cosine similarity at search time. Includes the `RobotLab::DocumentStore` standalone API and a RAG pattern sketch showing how to pass retrieved context to a robot.
359
-
360
- **Requires:** `robot_lab-document_store` gem (`gem "robot_lab-document_store"` in your Gemfile); downloads the ~23 MB ONNX model on first run (cached in `~/.cache/fastembed/`)
361
-
362
- ### 27 — Production Incident War Room
363
-
364
- Three SRE scout robots investigate a payment-service outage in parallel — database layer, network layer, and application layer. Each scout stores its findings in shared reactive memory and broadcasts a status update to a war-room coordinator via TypedBus.
365
-
366
- Demonstrates all four Phase 5 infrastructure improvements together:
367
-
368
- | Feature | How it shows up |
369
- |---------|----------------|
370
- | **IO.pipe Waiter** (#13) | Commander blocks on `memory.get(:db_finding, :net_finding, :app_finding, wait: 60)`; wakes the instant the last scout writes its key |
371
- | **BusPoller** (#14) | All three scouts send bus messages to the war room; BusPoller serializes delivery so war_room processes them one at a time, in arrival order, with no dropped messages |
372
- | **Poller Groups** (#15) | Scout tasks labeled `poller_group: :investigation`; commander task labeled `poller_group: :command`; group list printed before the run |
373
- | **Reactive Memory** | `memory.subscribe` callbacks fire in real-time as each scout writes, while the blocking waiter runs independently |
374
-
375
- **Run:**
376
- ```bash
377
- bundle exec ruby examples/27_incident_response/incident_response.rb
378
- # or
379
- bundle exec rake examples:run[27]
380
- ```
381
-
382
- **Requires:** Ollama
383
-
384
- ### 28 — MCP Server Discovery
385
-
386
- When a robot has many MCP servers configured, connecting to all of them upfront is wasteful. `mcp_discovery: true` enables semantic server selection: before the first connection, `MCP::ServerDiscovery` scores each server's `name + description` against the user query using TF cosine similarity and connects only the relevant subset.
387
-
388
- Demonstrates: `MCP::ServerDiscovery.select(query, from:, threshold:)`, the `description:` field on MCP server configs, `mcp_discovery: true` on Robot, and all four fallback cases (no descriptions, blank query, classifier unavailable, no match above threshold).
389
-
390
- **Requires:** None (no LLM calls — exercises the discovery module directly)
391
-
392
- ### 29 — Ractor-Safe CPU Tools
393
-
394
- Demonstrates Track 1 of RobotLab's Ractor parallelism: CPU-bound tool classes that
395
- bypass the GVL by routing through a pool of Ractor workers.
396
-
397
- | Section | What it shows |
398
- |---------|--------------|
399
- | `ractor_safe?` flags | `WordStatsTool`, `ReadabilityTool`, `HeavyDigestTool` inherit `ractor_safe true` from `TextTool`; `RequestCounterTool` (mutable class variable) does not |
400
- | `RactorBoundary.freeze_deep` | Deep-freezes nested hashes/arrays; raises `RactorBoundaryError` on `StringIO` |
401
- | Single pool submit | Direct `RobotLab.ractor_pool.submit(class_name, args)` calls |
402
- | `ToolError` propagation | `nil.scan(...)` inside a Ractor worker → `NoMethodError` → `RobotLab::ToolError` |
403
- | Parallel batch | 6 threads each submitting a `HeavyDigestTool` job (5 000 SHA-256 rounds) simultaneously vs sequentially; speedup visible on multi-core hardware |
404
-
405
- **Requires:** None (no LLM calls)
406
-
407
- ### 30 — Ractor Network Scheduler
408
-
409
- Demonstrates Track 2 of RobotLab's Ractor parallelism: running a multi-robot
410
- pipeline under `parallel_mode: :ractor`, which dispatches independent tasks in
411
- true parallel waves and respects `depends_on` ordering.
412
-
413
- Pipeline topology (4 robots):
414
- ```
415
- headline_finder ──┐
416
- background_brief ──┼──► report_writer
417
- fact_checker ──┘
418
- ```
419
- Wave 1 (headline_finder + background_brief + fact_checker) runs in parallel;
420
- Wave 2 (report_writer) runs after all three complete.
421
-
422
- **Part 1** — `SimulatedScheduler` (overrides `execute_spec` with `sleep`) shows
423
- wave ordering and timing without any API calls. Expected: ~1.3 s parallel vs 2.2 s sequential.
424
-
425
- **Part 2** — Walks through `Network.new(parallel_mode: :ractor)` configuration
426
- and the `pipeline.step_dependencies` dependency graph inspection.
427
-
428
- **Part 3** — Live LLM run (enabled automatically when `ANTHROPIC_API_KEY` is set).
429
-
430
- **Requires:** None for Parts 1 & 2. `RUN_LIVE=1` plus Ollama for Part 3 (expected to fail — ruby_llm is not Ractor-safe yet).
431
-
432
- ### 31 — Product Launch Assessment (Concurrency Cap)
433
-
434
- Six specialist robots evaluate a product launch simultaneously: market, competitive, technical, risk, financial, and legal analysts. `RunConfig.new(max_concurrent_robots: 4)` caps the `Async::Semaphore` at 4 in-flight LLM calls — robots 5 and 6 queue until a slot opens. A `LaunchDirector` reads all six findings from shared reactive memory and issues a GO / NO-GO recommendation. Start timestamps in the output make the semaphore behavior visible.
435
-
436
- Demonstrates: `max_concurrent_robots:` on `RunConfig`, `Async::Semaphore` back-pressure via `simple_flow`, six parallel `depends_on: :none` tasks, shared memory writes and blocking reads.
437
-
438
- **Requires:** Ollama
439
-
440
- ### 32 — Newsletter Reader
441
-
442
- A plain utility script that fetches unprocessed issues from Ruby newsletter RSS feeds and saves them as Markdown. **It uses no part of RobotLab** — it lives here as a content feeder for other experiments, not as a capability demo. Set `CLIPPINGS_DIR` to choose the output folder.
443
-
444
- **Requires:** `html2markdown` on `PATH`
445
-
446
- ### 33 — Durable Cross-Session Learning
447
-
448
- `33_stock_generator.rb` publishes synthetic XYZZY prices to a Redis channel using geometric Brownian motion. `33_stock_predictor.rb` consumes them, predicts each window's high/low with an SMA + EMA ensemble, and after every window asks a tuner robot to adjust the predictor's parameters.
449
-
450
- The tuner uses `robot_lab-durable`. Note the API: `learn:` / `learn_domain:` are **not** constructor parameters (`Robot#initialize` takes a fixed keyword list with no `**rest`, so passing them raises `ArgumentError`). Call `robot.setup_durable_learning(domain:)` after `build`, which seeds `robot.learnings` from `~/.robot_lab/durable/<domain>.yml` and appends the `RecallKnowledge` / `RecordKnowledge` tools. Core `Robot#run` does not invoke the reflector, so the caller drives `robot.run_reflector` to promote learnings back to the store.
451
-
452
- Run the two scripts in separate terminals.
453
-
454
- **Requires:** Ollama, Redis on localhost:6379, `robot_lab-durable`
455
-
456
- ### 34 — AgentSkills.io Integration
457
-
458
- Skills declared as `skills: [:code_reviewer]` are resolved from `~/.prompts/skills/<name>/SKILL.md` and matched per-run by embedding similarity — a code-review question activates the skill, an unrelated question does not. Run the two queries and compare.
459
-
460
- **Requires:** Ollama, `robot_lab-document_store` gem, a `SKILL.md` at `~/.prompts/skills/code_reviewer/`
461
-
462
- ### 35 — Hooks Architecture
463
-
464
- Loads `xyzzy.rb`, a single-file `RobotLab::Hook` subclass that registers for every hook and logs each callback with the context it receives. Demonstrates robot run, LLM generation, tool call, network run, task, and error hooks. Stubs `robot.chat.ask` for the deterministic sections; the LLM-generation section makes four real calls to show `around_llm_generation` serving two of them from a cache.
465
-
466
- `RobotLab::Hook` has no logger accessor — handlers own their output. `xyzzy.rb` freezes its log destination from `XYZZY_LOG_PATH` at load time, so the env var must be set before the `require`.
467
-
468
- **Requires:** Ollama (four calls in the LLM-loop section)
469
-
470
- ### 18 — Rails Integration Demo
471
-
472
- A minimal, hand-built Rails 8 app that exercises every piece of RobotLab's Rails integration end-to-end. No `rails new` — every file is hand-crafted for minimum size.
473
-
474
- **What it demonstrates:**
475
- - **ChatRobot** with a custom `TimeTool` (`app/robots/`, `app/tools/`)
476
- - **RobotRunJob** — background execution via `ActiveJob` async adapter
477
- - **Turbo Stream token streaming** — real-time content chunks broadcast to the browser over ActionCable
478
- - **Persistence** — `RobotLabThread` + `RobotLabResult` with conversation history
479
- - **Auto-scrolling chat** — MutationObserver keeps the view pinned to the latest streaming content
480
-
481
- **No Redis, no Solid Queue, no asset pipeline.** Uses `:async` adapters for both ActiveJob and ActionCable. Turbo JS loaded via importmap from CDN (`@hotwired/turbo-rails`).
482
-
483
- **Two API details worth copying:** the job's superclass is `RobotLab::RailsIntegration::Job` (there is no `RobotLab::Job` alias), and the controller enqueues with `tools: :inherit` so that keyword reaches `robot.run` — otherwise `TimeTool` is never offered and the model guesses the time.
484
-
485
- ```bash
486
- cd examples/18_rails
487
- bin/setup # bundle install + db:create + db:migrate
488
- bin/dev # starts Puma on http://localhost:3000
489
- ```
490
-
491
- **Requires:** Ollama, Ruby 3.2+
492
-
493
- ## Prompt Templates
494
-
495
- Templates live in `examples/prompts/` as `.md` files with YAML front matter. Each template defines a robot's personality and behavior:
496
-
497
- ```markdown
498
- ---
499
- description: Simple helpful assistant
500
- temperature: 0.7
501
- parameters:
502
- company_name: null
503
- ---
504
- You are a helpful assistant for <%= company_name %>.
505
- ```
506
-
507
- Front matter keys like `model`, `temperature`, `top_p`, `max_tokens` are applied to the robot's chat automatically. Parameters with `null` values are required and must be provided via `context:` at build time.
508
-
509
- ### Template Inventory
510
-
511
- | Template | Used By | Description |
512
- |----------|---------|-------------|
513
- | `helper.md` | 01 | Simple helpful assistant |
514
- | `assistant.md` | 02 | Assistant with tool access |
515
- | `classifier.md` | 03 | Request classifier (billing/technical/general) |
516
- | `billing.md` | 03 | Billing specialist |
517
- | `technical.md` | 03 | Technical support specialist |
518
- | `general.md` | 03 | General support |
519
- | `github_assistant.md` | 04 | GitHub-aware assistant |
520
- | `triage.md` | 06 | E-commerce request triage |
521
- | `order_support.md` | 06 | Order inquiry specialist |
522
- | `product_support.md` | 06 | Product questions specialist |
523
- | `escalation.md` | 06 | Complex issue handler |
524
- | `sentiment_analyzer.md` | 07 | Sentiment analysis |
525
- | `entity_extractor.md` | 07 | Entity extraction |
526
- | `keyword_extractor.md` | 07 | Keyword extraction |
527
- | `synthesizer.md` | 07 | Multi-source synthesis |
528
- | `llm_config_demo.md` | 08 | Configuration demo |
529
- | `configurable.md` | 09 | Configurable template with front matter |
530
- | `comedian.md` | 12 | Robot joke teller |
531
- | `comedy_critic.md` | 12 | Joke evaluator (FUNNY/NOT_FUNNY) |
532
- | `dispatcher.md` | 13 | Specialist role dispatcher |
533
- | `open_mic_comic.md` | 14 | Observational comedian with self-modification |
534
- | `open_mic_heckler.md` | 14 | Tough audience heckler (can stay silent or counter-joke) |
535
- | `open_mic_scout.md` | 14 | Talent scout with analyst recruitment |
536
- | `os_advocate.md` | 15 | Operating-system advocacy writer |
537
- | `os_editor.md` | 15 | Synthesizes the three advocacy drafts |
538
- | `os_chief.md` | 15 | Editor-in-chief (APPROVED / REVISE) |
539
- | `writer.md` | 16 | Self-organizing novella writer |
540
- | `screenplay_writer.md` | 16 | Self-organizing screenplay writer |
541
- | `incident_responder.md` | 17 | SRE on-call analyst (main template) |
542
- | `runbook_protocol.md` | 17 | Flat skill: 5-step incident protocol |
543
- | `structured_output.md` | 17 | Flat skill: JSON response format |
544
- | `sre_compliance.md` | 17 | Recursive skill: bundles the two leaves below |
545
- | `pii_redactor.md` | 17 | Leaf skill: redact PII |
546
- | `audit_trail.md` | 17 | Leaf skill: audit metadata |
547
-
548
- Templates matching `*_test.md` are fixtures for the test suite, not examples.
549
-
550
- Templates for 14, 15 and 16 live in those examples' own `prompts/` directories; each entrypoint sets `ROBOT_LAB_TEMPLATE_PATH` before requiring `common.rb`.