robot_lab 0.2.8 → 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 (262) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -0
  3. data/README.md +16 -18
  4. data/lib/robot_lab/ask_user.rb +3 -3
  5. data/lib/robot_lab/config/defaults.yml +5 -5
  6. data/lib/robot_lab/config.rb +2 -2
  7. data/lib/robot_lab/mcp/transports/streamable_http.rb +2 -4
  8. data/lib/robot_lab/memory.rb +16 -7
  9. data/lib/robot_lab/robot/hooking.rb +26 -0
  10. data/lib/robot_lab/robot/result_building.rb +119 -0
  11. data/lib/robot_lab/robot.rb +37 -120
  12. data/lib/robot_lab/run_config.rb +52 -20
  13. data/lib/robot_lab/tool.rb +7 -12
  14. data/lib/robot_lab/version.rb +1 -1
  15. data/lib/robot_lab.rb +3 -3
  16. metadata +15 -274
  17. data/.architecture/AGENTS.md +0 -32
  18. data/.architecture/config.yml +0 -8
  19. data/.architecture/members.yml +0 -60
  20. data/.architecture/reviews/feature-free-will.md +0 -490
  21. data/.architecture/reviews/overall-codebase.md +0 -427
  22. data/.claude/settings.local.json +0 -57
  23. data/.codex/config.toml +0 -2
  24. data/.envrc +0 -6
  25. data/.github/workflows/deploy-github-pages.yml +0 -52
  26. data/.irbrc +0 -6
  27. data/.loki +0 -65
  28. data/.quality/reek_baseline.txt +0 -43
  29. data/.rubocop.yml +0 -10
  30. data/Archspec.rb +0 -44
  31. data/CLAUDE.md +0 -139
  32. data/COMMITS.md +0 -196
  33. data/Rakefile +0 -193
  34. data/_typos.toml +0 -21
  35. data/agent2agent_review.md +0 -192
  36. data/agentf_improvements.md +0 -253
  37. data/agents.md +0 -14
  38. data/docs/api/core/index.md +0 -147
  39. data/docs/api/core/memory.md +0 -578
  40. data/docs/api/core/network.md +0 -553
  41. data/docs/api/core/result.md +0 -211
  42. data/docs/api/core/robot.md +0 -1667
  43. data/docs/api/core/state.md +0 -145
  44. data/docs/api/core/tool.md +0 -520
  45. data/docs/api/errors.md +0 -323
  46. data/docs/api/hooks.md +0 -469
  47. data/docs/api/index.md +0 -137
  48. data/docs/api/mcp/client.md +0 -387
  49. data/docs/api/mcp/index.md +0 -267
  50. data/docs/api/mcp/server.md +0 -252
  51. data/docs/api/mcp/transports.md +0 -339
  52. data/docs/api/messages/index.md +0 -126
  53. data/docs/api/messages/text-message.md +0 -170
  54. data/docs/api/messages/tool-call-message.md +0 -206
  55. data/docs/api/messages/tool-result-message.md +0 -242
  56. data/docs/api/messages/user-message.md +0 -232
  57. data/docs/api/skills.md +0 -423
  58. data/docs/api/streaming/context.md +0 -280
  59. data/docs/api/streaming/events.md +0 -185
  60. data/docs/api/streaming/index.md +0 -156
  61. data/docs/api/support.md +0 -846
  62. data/docs/architecture/core-concepts.md +0 -575
  63. data/docs/architecture/index.md +0 -252
  64. data/docs/architecture/message-flow.md +0 -366
  65. data/docs/architecture/network-orchestration.md +0 -478
  66. data/docs/architecture/robot-execution.md +0 -396
  67. data/docs/architecture/state-management.md +0 -410
  68. data/docs/assets/css/custom.css +0 -56
  69. data/docs/assets/images/robot_lab.jpg +0 -0
  70. data/docs/concepts.md +0 -641
  71. data/docs/examples/basic-chat.md +0 -258
  72. data/docs/examples/index.md +0 -425
  73. data/docs/examples/mcp-server.md +0 -403
  74. data/docs/examples/multi-robot-network.md +0 -476
  75. data/docs/examples/tool-usage.md +0 -468
  76. data/docs/getting-started/configuration.md +0 -645
  77. data/docs/getting-started/index.md +0 -56
  78. data/docs/getting-started/installation.md +0 -200
  79. data/docs/getting-started/quick-start.md +0 -293
  80. data/docs/guides/building-robots.md +0 -1187
  81. data/docs/guides/creating-networks.md +0 -736
  82. data/docs/guides/hooks.md +0 -1206
  83. data/docs/guides/index.md +0 -78
  84. data/docs/guides/knowledge.md +0 -219
  85. data/docs/guides/mcp-integration.md +0 -740
  86. data/docs/guides/memory.md +0 -458
  87. data/docs/guides/observability.md +0 -733
  88. data/docs/guides/streaming.md +0 -323
  89. data/docs/guides/using-tools.md +0 -780
  90. data/docs/index.md +0 -280
  91. data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
  92. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
  93. data/examples/.envrc +0 -1
  94. data/examples/01_simple_robot.rb +0 -31
  95. data/examples/02_tools.rb +0 -109
  96. data/examples/03_network.rb +0 -118
  97. data/examples/04_mcp.rb +0 -215
  98. data/examples/05_streaming.rb +0 -137
  99. data/examples/06_prompt_templates.rb +0 -325
  100. data/examples/07_network_memory.rb +0 -313
  101. data/examples/08_llm_config.rb +0 -162
  102. data/examples/09_chaining.rb +0 -251
  103. data/examples/10_memory.rb +0 -315
  104. data/examples/11_network_introspection.rb +0 -239
  105. data/examples/12_message_bus.rb +0 -67
  106. data/examples/13_spawn.rb +0 -85
  107. data/examples/14_rusty_circuit/.envrc +0 -1
  108. data/examples/14_rusty_circuit/.gitignore +0 -1
  109. data/examples/14_rusty_circuit/README.md +0 -1
  110. data/examples/14_rusty_circuit/comic.rb +0 -149
  111. data/examples/14_rusty_circuit/display.rb +0 -217
  112. data/examples/14_rusty_circuit/heckler.rb +0 -65
  113. data/examples/14_rusty_circuit/open_mic.rb +0 -132
  114. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
  115. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
  116. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
  117. data/examples/14_rusty_circuit/scout.rb +0 -165
  118. data/examples/14_rusty_circuit/show.log +0 -234
  119. data/examples/15_memory_network_and_bus/.envrc +0 -1
  120. data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
  121. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
  122. data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
  123. data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
  124. data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
  125. data/examples/15_memory_network_and_bus/output/combined_article.md +0 -13
  126. data/examples/15_memory_network_and_bus/output/final_article.md +0 -13
  127. data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
  128. data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
  129. data/examples/15_memory_network_and_bus/output/memory.json +0 -13
  130. data/examples/15_memory_network_and_bus/output/revision_1.md +0 -18
  131. data/examples/15_memory_network_and_bus/output/revision_2.md +0 -13
  132. data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
  133. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
  134. data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
  135. data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
  136. data/examples/16_writers_room/.envrc +0 -1
  137. data/examples/16_writers_room/display.rb +0 -158
  138. data/examples/16_writers_room/output/.gitignore +0 -4
  139. data/examples/16_writers_room/output/README.md +0 -69
  140. data/examples/16_writers_room/output/opus_001.md +0 -263
  141. data/examples/16_writers_room/output/opus_001_notes.log +0 -470
  142. data/examples/16_writers_room/output/opus_002.md +0 -245
  143. data/examples/16_writers_room/output/opus_002_notes.log +0 -546
  144. data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
  145. data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
  146. data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
  147. data/examples/16_writers_room/prompts/writer.md +0 -37
  148. data/examples/16_writers_room/room.rb +0 -186
  149. data/examples/16_writers_room/tools.rb +0 -173
  150. data/examples/16_writers_room/writer.rb +0 -121
  151. data/examples/16_writers_room/writers_room.rb +0 -256
  152. data/examples/17_skills.rb +0 -234
  153. data/examples/18_rails/.envrc +0 -3
  154. data/examples/18_rails/.gitignore +0 -5
  155. data/examples/18_rails/Gemfile +0 -11
  156. data/examples/18_rails/README.md +0 -67
  157. data/examples/18_rails/Rakefile +0 -4
  158. data/examples/18_rails/app/controllers/application_controller.rb +0 -4
  159. data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
  160. data/examples/18_rails/app/jobs/application_job.rb +0 -4
  161. data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
  162. data/examples/18_rails/app/models/application_record.rb +0 -5
  163. data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
  164. data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
  165. data/examples/18_rails/app/robots/chat_robot.rb +0 -25
  166. data/examples/18_rails/app/tools/time_tool.rb +0 -9
  167. data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
  168. data/examples/18_rails/app/views/chat/index.html.erb +0 -67
  169. data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
  170. data/examples/18_rails/bin/dev +0 -7
  171. data/examples/18_rails/bin/rails +0 -6
  172. data/examples/18_rails/bin/setup +0 -15
  173. data/examples/18_rails/config/application.rb +0 -33
  174. data/examples/18_rails/config/cable.yml +0 -2
  175. data/examples/18_rails/config/database.yml +0 -5
  176. data/examples/18_rails/config/environment.rb +0 -4
  177. data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
  178. data/examples/18_rails/config/routes.rb +0 -6
  179. data/examples/18_rails/config.ru +0 -4
  180. data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
  181. data/examples/19_token_tracking.rb +0 -138
  182. data/examples/20_circuit_breaker.rb +0 -147
  183. data/examples/21_learning_loop.rb +0 -181
  184. data/examples/22_context_compression.rb +0 -172
  185. data/examples/23_convergence.rb +0 -133
  186. data/examples/24_structured_delegation.rb +0 -151
  187. data/examples/25_history_search/conversation.jsonl +0 -30
  188. data/examples/25_history_search.rb +0 -133
  189. data/examples/26_document_store/api_versioning_adr.md +0 -52
  190. data/examples/26_document_store/incident_postmortem.md +0 -46
  191. data/examples/26_document_store/postgres_runbook.md +0 -49
  192. data/examples/26_document_store/redis_caching_guide.md +0 -48
  193. data/examples/26_document_store/sidekiq_guide.md +0 -51
  194. data/examples/26_document_store.rb +0 -140
  195. data/examples/27_incident_response/incident_response.rb +0 -261
  196. data/examples/28_mcp_discovery.rb +0 -113
  197. data/examples/29_ractor_tools.rb +0 -240
  198. data/examples/30_ractor_network.rb +0 -252
  199. data/examples/31_launch_assessment.rb +0 -246
  200. data/examples/32_newsletter_reader.rb +0 -193
  201. data/examples/33_stock_generator.rb +0 -80
  202. data/examples/33_stock_predictor.rb +0 -327
  203. data/examples/34_agentskills.rb +0 -76
  204. data/examples/35_hooks.rb +0 -266
  205. data/examples/README.md +0 -533
  206. data/examples/common.rb +0 -148
  207. data/examples/prompts/assistant.md +0 -5
  208. data/examples/prompts/audit_trail.md +0 -8
  209. data/examples/prompts/billing.md +0 -10
  210. data/examples/prompts/classifier.md +0 -7
  211. data/examples/prompts/comedian.md +0 -6
  212. data/examples/prompts/comedy_critic.md +0 -10
  213. data/examples/prompts/configurable.md +0 -9
  214. data/examples/prompts/dispatcher.md +0 -12
  215. data/examples/prompts/entity_extractor.md +0 -14
  216. data/examples/prompts/escalation.md +0 -42
  217. data/examples/prompts/frontmatter_mcp_test.md +0 -9
  218. data/examples/prompts/frontmatter_named_test.md +0 -5
  219. data/examples/prompts/frontmatter_tools_test.md +0 -6
  220. data/examples/prompts/general.md +0 -7
  221. data/examples/prompts/github_assistant.md +0 -14
  222. data/examples/prompts/helper.md +0 -4
  223. data/examples/prompts/incident_responder.md +0 -18
  224. data/examples/prompts/keyword_extractor.md +0 -11
  225. data/examples/prompts/llm_config_demo.md +0 -20
  226. data/examples/prompts/order_support.md +0 -35
  227. data/examples/prompts/os_advocate.md +0 -13
  228. data/examples/prompts/os_chief.md +0 -13
  229. data/examples/prompts/os_editor.md +0 -13
  230. data/examples/prompts/parameterized_main_test.md +0 -6
  231. data/examples/prompts/pii_redactor.md +0 -7
  232. data/examples/prompts/product_support.md +0 -37
  233. data/examples/prompts/runbook_protocol.md +0 -12
  234. data/examples/prompts/sentiment_analyzer.md +0 -12
  235. data/examples/prompts/skill_a_test.md +0 -4
  236. data/examples/prompts/skill_b_test.md +0 -4
  237. data/examples/prompts/skill_config_test.md +0 -5
  238. data/examples/prompts/skill_cycle_a_test.md +0 -6
  239. data/examples/prompts/skill_cycle_b_test.md +0 -6
  240. data/examples/prompts/skill_description_test.md +0 -4
  241. data/examples/prompts/skill_leaf_test.md +0 -4
  242. data/examples/prompts/skill_nested_test.md +0 -6
  243. data/examples/prompts/skill_refs_main_test.md +0 -6
  244. data/examples/prompts/skill_self_ref_test.md +0 -6
  245. data/examples/prompts/skill_with_mcp_test.md +0 -9
  246. data/examples/prompts/skill_with_params_test.md +0 -6
  247. data/examples/prompts/skill_with_robot_name_test.md +0 -5
  248. data/examples/prompts/skill_with_tools_test.md +0 -6
  249. data/examples/prompts/sre_compliance.md +0 -10
  250. data/examples/prompts/structured_output.md +0 -7
  251. data/examples/prompts/synthesizer.md +0 -17
  252. data/examples/prompts/technical.md +0 -10
  253. data/examples/prompts/template_with_skills_test.md +0 -6
  254. data/examples/prompts/triage.md +0 -22
  255. data/examples/ruboruby.md +0 -423
  256. data/examples/xyzzy.rb +0 -97
  257. data/logfile +0 -8
  258. data/mkdocs.yml +0 -209
  259. data/robot_concurrency.md +0 -38
  260. data/simple_acp_review.md +0 -298
  261. data/temp.md +0 -6
  262. data/tool_manifest_plan.md +0 -155
@@ -1,185 +0,0 @@
1
- # Streaming::Events
2
-
3
- Event type constants and classification helpers for the streaming system.
4
-
5
- ## Module: `RobotLab::Streaming::Events`
6
-
7
- Defines all recognized event types as string constants and provides helper methods for classifying events.
8
-
9
- ```ruby
10
- RobotLab::Streaming::Events::TEXT_DELTA # => "text.delta"
11
- RobotLab::Streaming::Events::RUN_COMPLETED # => "run.completed"
12
- RobotLab::Streaming::Events.delta?("text.delta") # => true
13
- ```
14
-
15
- ## Event Type Constants
16
-
17
- ### Run Lifecycle Events
18
-
19
- | Constant | Value | Description |
20
- |----------|-------|-------------|
21
- | `RUN_STARTED` | `"run.started"` | A run has begun |
22
- | `RUN_COMPLETED` | `"run.completed"` | A run completed successfully |
23
- | `RUN_FAILED` | `"run.failed"` | A run failed with an error |
24
- | `RUN_INTERRUPTED` | `"run.interrupted"` | A run was interrupted |
25
-
26
- ### Step Events
27
-
28
- For durable execution tracking:
29
-
30
- | Constant | Value | Description |
31
- |----------|-------|-------------|
32
- | `STEP_STARTED` | `"step.started"` | A processing step has begun |
33
- | `STEP_COMPLETED` | `"step.completed"` | A processing step completed |
34
- | `STEP_FAILED` | `"step.failed"` | A processing step failed |
35
-
36
- ### Part Events
37
-
38
- For message composition tracking:
39
-
40
- | Constant | Value | Description |
41
- |----------|-------|-------------|
42
- | `PART_CREATED` | `"part.created"` | A message part was created |
43
- | `PART_COMPLETED` | `"part.completed"` | A message part completed |
44
- | `PART_FAILED` | `"part.failed"` | A message part failed |
45
-
46
- ### Content Delta Events
47
-
48
- Token-level streaming events:
49
-
50
- | Constant | Value | Description |
51
- |----------|-------|-------------|
52
- | `TEXT_DELTA` | `"text.delta"` | A chunk of text content was generated |
53
- | `TOOL_CALL_ARGUMENTS_DELTA` | `"tool_call.arguments.delta"` | A chunk of tool call arguments |
54
- | `TOOL_CALL_OUTPUT_DELTA` | `"tool_call.output.delta"` | A chunk of tool call output |
55
- | `REASONING_DELTA` | `"reasoning.delta"` | A chunk of reasoning/thinking content |
56
- | `DATA_DELTA` | `"data.delta"` | A chunk of structured data |
57
-
58
- ### Human-in-the-Loop Events
59
-
60
- | Constant | Value | Description |
61
- |----------|-------|-------------|
62
- | `HITL_REQUESTED` | `"hitl.requested"` | Human input has been requested |
63
- | `HITL_RESOLVED` | `"hitl.resolved"` | Human input has been provided |
64
-
65
- ### Metadata Events
66
-
67
- | Constant | Value | Description |
68
- |----------|-------|-------------|
69
- | `USAGE_UPDATED` | `"usage.updated"` | Token usage statistics updated |
70
- | `METADATA_UPDATED` | `"metadata.updated"` | Run metadata updated |
71
-
72
- ### Terminal Event
73
-
74
- | Constant | Value | Description |
75
- |----------|-------|-------------|
76
- | `STREAM_ENDED` | `"stream.ended"` | The stream has ended; no more events |
77
-
78
- ## Event Collections
79
-
80
- ### ALL_EVENTS
81
-
82
- ```ruby
83
- RobotLab::Streaming::Events::ALL_EVENTS
84
- # => Array of all event type strings (frozen)
85
- ```
86
-
87
- ### LIFECYCLE_EVENTS
88
-
89
- ```ruby
90
- RobotLab::Streaming::Events::LIFECYCLE_EVENTS
91
- # => ["run.started", "run.completed", "run.failed", "run.interrupted"]
92
- ```
93
-
94
- ### DELTA_EVENTS
95
-
96
- ```ruby
97
- RobotLab::Streaming::Events::DELTA_EVENTS
98
- # => ["text.delta", "tool_call.arguments.delta", "tool_call.output.delta",
99
- # "reasoning.delta", "data.delta"]
100
- ```
101
-
102
- ## Classification Methods
103
-
104
- ### Events.lifecycle?
105
-
106
- ```ruby
107
- RobotLab::Streaming::Events.lifecycle?("run.started") # => true
108
- RobotLab::Streaming::Events.lifecycle?("text.delta") # => false
109
- ```
110
-
111
- Returns `true` if the event is a run lifecycle event.
112
-
113
- ### Events.delta?
114
-
115
- ```ruby
116
- RobotLab::Streaming::Events.delta?("text.delta") # => true
117
- RobotLab::Streaming::Events.delta?("run.completed") # => false
118
- ```
119
-
120
- Returns `true` if the event is a content delta (token streaming) event.
121
-
122
- ### Events.valid?
123
-
124
- ```ruby
125
- RobotLab::Streaming::Events.valid?("text.delta") # => true
126
- RobotLab::Streaming::Events.valid?("unknown.event") # => false
127
- ```
128
-
129
- Returns `true` if the event is a recognized event type.
130
-
131
- ## Examples
132
-
133
- ### Filtering Events by Category
134
-
135
- ```ruby
136
- publish = ->(event) {
137
- event_type = event[:event]
138
-
139
- if RobotLab::Streaming::Events.delta?(event_type)
140
- # Handle streaming content
141
- print event[:data][:delta]
142
- elsif RobotLab::Streaming::Events.lifecycle?(event_type)
143
- # Handle lifecycle transitions
144
- puts "\n[#{event_type}] run_id=#{event[:data][:run_id]}"
145
- end
146
- }
147
- ```
148
-
149
- ### Using Constants for Event Matching
150
-
151
- ```ruby
152
- include RobotLab::Streaming::Events
153
-
154
- publish = ->(event) {
155
- case event[:event]
156
- when TEXT_DELTA
157
- print event[:data][:delta]
158
- when TOOL_CALL_ARGUMENTS_DELTA
159
- buffer_tool_args(event[:data])
160
- when RUN_COMPLETED
161
- puts "\nRun complete"
162
- when RUN_FAILED
163
- puts "\nRun failed: #{event[:data][:error]}"
164
- when STREAM_ENDED
165
- cleanup
166
- end
167
- }
168
- ```
169
-
170
- ### Validating Custom Events
171
-
172
- ```ruby
173
- def emit(event_type, data)
174
- unless RobotLab::Streaming::Events.valid?(event_type)
175
- raise ArgumentError, "Unknown event type: #{event_type}"
176
- end
177
-
178
- context.publish_event(event: event_type, data: data)
179
- end
180
- ```
181
-
182
- ## See Also
183
-
184
- - [Streaming Overview](index.md)
185
- - [Context](context.md)
@@ -1,156 +0,0 @@
1
- # Streaming
2
-
3
- A standalone event-publishing toolkit. **Not** the live streaming path.
4
-
5
- ## Status: not wired in
6
-
7
- `RobotLab::Streaming::Context`, `Streaming::Events`, and
8
- `Streaming::SequenceCounter` exist and work, but **nothing in the framework uses
9
- them**. `grep -rn "Streaming::" lib/` returns zero hits outside
10
- `lib/robot_lab/streaming/` itself: no robot, network, task, or hook ever
11
- constructs a `Streaming::Context`, and no framework code publishes any of the
12
- events listed below. Enabling this module does not make a robot stream.
13
-
14
- Treat this as a set of building blocks you may drive yourself — a vocabulary of
15
- event names plus a sequencing/ID helper — if you are writing your own
16
- event-broadcast layer (a websocket relay, a SSE endpoint, an audit feed).
17
-
18
- ### The real streaming API
19
-
20
- To actually receive tokens as a robot generates them, use `on_content:` and/or a
21
- block on `run`:
22
-
23
- ```ruby
24
- # Constructor / RunConfig callback — fires on every run
25
- robot = RobotLab.build(
26
- name: "assistant",
27
- system_prompt: "You are helpful.",
28
- on_content: ->(chunk) { print chunk.content }
29
- )
30
-
31
- # Or a block passed to run
32
- robot.run("Tell me a story") { |chunk| print chunk.content }
33
- ```
34
-
35
- Each callback receives a `RubyLLM::Chunk`. Use `chunk.content` — there is no
36
- `chunk.text`. If both are supplied, both fire, with the stored `on_content`
37
- first. `on_content` is read from the robot's own config at construction time; a
38
- network-level `config:` does not supply it.
39
-
40
- The config key `streaming_enabled` has zero consumers in `lib/` and does nothing.
41
-
42
- ## Overview
43
-
44
- The module provides structured event publishing with automatic sequencing,
45
- timestamping, and ID generation. Event names cover run lifecycle, content deltas
46
- (token streaming), tool calls, and metadata updates, and contexts can be nested
47
- so a network-level run and its child robot runs share one monotonic sequence.
48
-
49
- ```ruby
50
- publish = ->(event) {
51
- case event[:event]
52
- when "text.delta"
53
- print event[:data][:delta]
54
- when "run.completed"
55
- puts "\nDone!"
56
- end
57
- }
58
-
59
- context = RobotLab::Streaming::Context.new(
60
- run_id: SecureRandom.uuid,
61
- message_id: SecureRandom.uuid,
62
- scope: "robot",
63
- publish: publish
64
- )
65
-
66
- context.publish_event(event: "text.delta", data: { delta: "Hello" })
67
- ```
68
-
69
- ## Components
70
-
71
- | Component | Description |
72
- |-----------|-------------|
73
- | [Context](context.md) | Manages streaming state, sequencing, and event publishing |
74
- | [Events](events.md) | Event type constants and classification helpers |
75
- | `SequenceCounter` | Thread-safe monotonic counter for event ordering. Its only consumer is `Streaming::Context`, which is itself unused by the framework |
76
-
77
- ## Event Categories
78
-
79
- These are the names defined in `Streaming::Events`. They are constants and
80
- classification helpers only — no framework code emits any of them.
81
-
82
- | Category | Events | Description |
83
- |----------|--------|-------------|
84
- | Lifecycle | `run.started`, `run.completed`, `run.failed`, `run.interrupted` | Run-level state changes |
85
- | Steps | `step.started`, `step.completed`, `step.failed` | Durable execution steps |
86
- | Parts | `part.created`, `part.completed`, `part.failed` | Message composition parts |
87
- | Deltas | `text.delta`, `tool_call.arguments.delta`, `tool_call.output.delta`, `reasoning.delta`, `data.delta` | Token-level content streaming |
88
- | HITL | `hitl.requested`, `hitl.resolved` | Human-in-the-loop events |
89
- | Metadata | `usage.updated`, `metadata.updated` | Token usage and metadata |
90
- | Terminal | `stream.ended` | End of stream signal |
91
-
92
- `DELTA_EVENTS` has five members — `tool_call.output.delta` is easy to miss.
93
- `ALL_EVENTS` has twenty.
94
-
95
- ## Event Structure
96
-
97
- Each published event is a hash with the following shape:
98
-
99
- ```ruby
100
- {
101
- event: "text.delta", # Event type string
102
- data: { # Event payload (merged with context info)
103
- delta: "Hello", # Custom data
104
- run_id: "run_123", # Injected by context
105
- message_id: "msg_456", # Injected by context
106
- scope: "robot" # Injected by context
107
- },
108
- timestamp: 1707900000000, # Millisecond Unix timestamp
109
- sequence_number: 1, # Monotonically increasing
110
- id: "publish-1:text.delta" # Unique event ID
111
- }
112
- ```
113
-
114
- ## Quick Start
115
-
116
- ### Publishing Events
117
-
118
- ```ruby
119
- context = RobotLab::Streaming::Context.new(
120
- run_id: "run_123",
121
- message_id: "msg_456",
122
- scope: "network",
123
- publish: ->(event) { broadcast(event) }
124
- )
125
-
126
- context.publish_event(event: "run.started", data: { robot_name: "assistant" })
127
- context.publish_event(event: "text.delta", data: { delta: "Hello " })
128
- context.publish_event(event: "text.delta", data: { delta: "world!" })
129
- context.publish_event(event: "run.completed", data: {})
130
- ```
131
-
132
- ### Nested Contexts
133
-
134
- Contexts can be nested to model a parent run with child runs sharing one
135
- sequence. Note that no `Network` creates these — you would build the hierarchy
136
- yourself.
137
-
138
- ```ruby
139
- # Parent context for a run you are orchestrating
140
- network_context = RobotLab::Streaming::Context.new(
141
- run_id: "network_run_1",
142
- message_id: "msg_1",
143
- scope: "network",
144
- publish: ->(event) { stream_to_client(event) }
145
- )
146
-
147
- # Child context for each robot (shares the sequence counter)
148
- robot_context = network_context.create_child_context("robot_run_1")
149
- robot_context.publish_event(event: "text.delta", data: { delta: "Response" })
150
- ```
151
-
152
- ## See Also
153
-
154
- - [Context](context.md)
155
- - [Events](events.md)
156
- - [Robot](../core/robot.md) -- `on_content:`, and the block form of `run`, which is how streaming actually works