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,211 +0,0 @@
1
- # RobotResult
2
-
3
- `RobotResult` is returned by every `robot.run()` call. It carries the LLM output, tool call results, token usage, timing, and delegation metadata for that execution.
4
-
5
- ## Accessing the Response
6
-
7
- ```ruby
8
- result = robot.run("What is the capital of France?")
9
-
10
- result.reply # => "The capital of France is Paris."
11
- result.last_text_content # => reply is an alias for this
12
- result.output # => [TextMessage] — see below
13
- result.tool_calls # => [] in practice — see below
14
- ```
15
-
16
- `last_text_content` returns the content of the last text message in `output`;
17
- `reply` is an alias for it. This is the string you want for the vast majority of
18
- use cases.
19
-
20
- !!! note "`output` is not the full turn"
21
- `output` is built as `[TextMessage.new(role: "assistant", content: text)]`
22
- from the **final response text only** — a one-element array, or an empty
23
- array when there is no text. It never contains the user message, the tool
24
- calls, or the intermediate assistant turns. Read `robot.messages` for the
25
- real conversation.
26
-
27
- The text is resolved in this order: `response.content`; then
28
- `response.thinking.text` (for models that route all output through reasoning
29
- content, e.g. `qwen3` on Ollama); then the most recent assistant text from
30
- *the current turn only* in the chat history.
31
-
32
- !!! note "`tool_calls` is effectively always empty"
33
- It is populated from the **final** assistant message, which no longer carries
34
- tool calls once ruby_llm's tool loop has completed. Consequently
35
- `has_tool_calls?` is also normally `false`. To observe tool activity, use the
36
- `on_tool_call:` / `on_tool_result:` callbacks or the `:tool_call` hook family.
37
-
38
- There is **no** `text?` predicate and **no** `content` accessor on `RobotResult`.
39
-
40
- ## Token & Cost Tracking
41
-
42
- ```ruby
43
- result.input_tokens # => Integer — tokens sent to the LLM this run
44
- result.output_tokens # => Integer — tokens generated this run
45
- ```
46
-
47
- Token counts are zero for providers that do not return usage data.
48
-
49
- ## Timing
50
-
51
- `duration` is set when the result travels through a network pipeline or a `delegate` call. It is `nil` when calling `robot.run()` directly.
52
-
53
- ```ruby
54
- result.duration # => Float (elapsed seconds) or nil
55
- ```
56
-
57
- ## Delegation Metadata
58
-
59
- When a result comes back through `robot.delegate(to:, task:)`, two additional fields are populated:
60
-
61
- ```ruby
62
- result.delegated_by # => "manager" (the robot that issued the delegation)
63
- result.duration # => 2.34 (always set by delegate)
64
- ```
65
-
66
- ## Identity & Status
67
-
68
- ```ruby
69
- result.robot_name # => "analyst"
70
- result.id # => "550e8400-e29b-..." (UUID, unique per run)
71
- result.created_at # => Time instance
72
- result.stop_reason # => nil — always, for results built by Robot#run
73
- ```
74
-
75
- !!! warning "`stop_reason` is always `nil` here"
76
- `build_result` sets it with
77
- `response.respond_to?(:stop_reason) ? response.stop_reason : nil`, and
78
- `RubyLLM::Message` does **not** define `stop_reason`. So every
79
- `robot.run` result carries `nil`, and `export` drops the key entirely.
80
- (`RobotLab::Message::VALID_STOP_REASONS` is `["tool", "stop"]`, but that
81
- constant governs the message classes you construct yourself — it is not
82
- what a `RobotResult` reports.)
83
-
84
- ## Inspecting the Output
85
-
86
- ```ruby
87
- result.output.each do |message|
88
- puts message.role # "assistant"
89
- puts message.content # String
90
- end
91
-
92
- result.has_tool_calls? # => output.any?(&:tool_call?) || tool_calls.any?
93
- result.stopped? # => true if execution ended naturally (not mid-tool-call)
94
- ```
95
-
96
- Because `stop_reason` is always `nil` on a `Robot#run` result, `stopped?`
97
- collapses to `!has_tool_calls?` in practice — and since `tool_calls` is
98
- effectively always empty, it is normally `true`.
99
-
100
- ## Persistence
101
-
102
- Export for serialization (excludes the debug fields):
103
-
104
- ```ruby
105
- hash = result.export
106
- # {
107
- # robot_name: "analyst",
108
- # delegated_by: "manager",
109
- # output: [...],
110
- # tool_calls: [...],
111
- # created_at: "2026-04-18T12:00:00Z",
112
- # id: "550e8400-...",
113
- # checksum: "a1b2c3...",
114
- # # stop_reason is absent — it is nil, and export is .compact-ed
115
- # duration: 2.34,
116
- # input_tokens: 512,
117
- # output_tokens: 128
118
- # }
119
-
120
- json = result.to_json # uses export
121
-
122
- hash_with_debug = result.to_h # export + prompt/history/raw, also compacted
123
-
124
- # Reconstruct from hash
125
- restored = RobotLab::RobotResult.from_hash(hash)
126
- ```
127
-
128
- !!! warning "`export` is `.compact`ed"
129
- Keys whose value is `nil` are dropped entirely. `delegated_by` and
130
- `duration` disappear when unset, and `stop_reason` is dropped from
131
- **every** `Robot#run` result because it is always `nil`. `input_tokens` and
132
- `output_tokens` are additionally converted to `nil` (and therefore dropped)
133
- when they are **zero**, so a provider that reports no usage yields a hash
134
- with no token keys at all:
135
-
136
- ```ruby
137
- RobotLab::RobotResult.new(robot_name: "a", output: []).export
138
- # => { robot_name: "a", output: [], tool_calls: [],
139
- # created_at: "...", id: "...", checksum: "..." }
140
- ```
141
-
142
- Only `robot_name`, `output`, `tool_calls`, `created_at`, `id`, and `checksum`
143
- are always present. Code reading an exported hash must tolerate missing keys.
144
-
145
- `checksum` is a SHA-256 hex digest of `{ output:, tool_calls:, created_at: }`
146
- (with `created_at` reduced to an integer epoch). Use it for deduplication when
147
- persisting results.
148
-
149
- ## Debug Fields
150
-
151
- All three are read/write and excluded from `export`/`to_json` (but included in `to_h`):
152
-
153
- ```ruby
154
- result.prompt # Array<Message>, nil — nil unless you assign it
155
- result.history # Array<Message>, nil — nil unless you assign it
156
- result.raw # the raw ruby_llm response; Robot#run always sets this
157
- ```
158
-
159
- `raw` is populated by `Robot#build_result` on every run, so it is the escape
160
- hatch for anything RobotLab does not surface (cost, provider metadata, the
161
- untouched message object). `prompt` and `history` are never populated by the
162
- framework.
163
-
164
- ## Attribute Reference
165
-
166
- | Attribute | Access | Type | Description |
167
- |-----------|--------|------|-------------|
168
- | `robot_name` | r | String | Name of the robot that produced this result |
169
- | `last_text_content` | r | String, nil | Content of the last text message in `output` (alias: `reply`) |
170
- | `output` | r | Array\<TextMessage\> | The final response text, as a one-element array (or empty) |
171
- | `tool_calls` | r | Array\<ToolResultMessage\> | Tool call results — effectively always empty |
172
- | `input_tokens` | r | Integer | Tokens sent to LLM (0 when the provider reports no usage) |
173
- | `output_tokens` | r | Integer | Tokens generated (0 when not reported) |
174
- | `id` | r | String | UUID, generated per result |
175
- | `created_at` | r | Time | Creation timestamp |
176
- | `stop_reason` | r | String, nil | Always `nil` for `Robot#run` results (the ruby_llm response has no `stop_reason`); settable only when you build a `RobotResult` yourself |
177
- | `duration` | rw | Float, nil | Elapsed seconds — set by `delegate` and by `Robot#call` in a pipeline; `nil` for a direct `robot.run` |
178
- | `delegated_by` | rw | String, nil | Delegating robot's name — set by `delegate` |
179
- | `prompt` | rw | Array\<Message\>, nil | Debug field, `nil` unless assigned |
180
- | `history` | rw | Array\<Message\>, nil | Debug field, `nil` unless assigned |
181
- | `raw` | rw | Object, nil | The raw ruby_llm response; set by `Robot#build_result` |
182
-
183
- Methods: `checksum`, `export`, `to_h`, `to_json`, `has_tool_calls?`, `stopped?`,
184
- and the class method `RobotResult.from_hash`.
185
-
186
- ## Constructor
187
-
188
- ```ruby
189
- RobotLab::RobotResult.new(
190
- robot_name:, # required
191
- output:, # required — Array<Message, Hash>
192
- tool_calls: [],
193
- created_at: nil, # defaults to Time.now
194
- id: nil, # defaults to SecureRandom.uuid
195
- prompt: nil,
196
- history: nil,
197
- raw: nil,
198
- stop_reason: nil,
199
- input_tokens: 0,
200
- output_tokens: 0
201
- )
202
- ```
203
-
204
- `output` entries must be `Message` instances or Hashes (`Message.from_hash`);
205
- anything else raises `ArgumentError`.
206
-
207
- ## Related
208
-
209
- - [Robot API](robot.md) — [`run`](robot.md#run), [`delegate`](robot.md#delegate), [`compress_history`](robot.md#compress_history)
210
- - [Building Robots](../../guides/building-robots.md) — Robot construction patterns
211
- - [Structured Delegation](../../guides/building-robots.md#structured-delegation) — `DelegationFuture` and async fan-out