robot_lab 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/README.md +29 -19
  4. data/lib/robot_lab/errors.rb +4 -0
  5. data/lib/robot_lab/hook_context.rb +9 -2
  6. data/lib/robot_lab/mcp/registry.rb +99 -0
  7. data/lib/robot_lab/mcp/server.rb +47 -83
  8. data/lib/robot_lab/mcp/server_discovery.rb +22 -9
  9. data/lib/robot_lab/mcp.rb +259 -0
  10. data/lib/robot_lab/robot/mcp_management.rb +159 -105
  11. data/lib/robot_lab/robot/tool_call_gating.rb +144 -0
  12. data/lib/robot_lab/robot.rb +72 -99
  13. data/lib/robot_lab/run_config.rb +3 -2
  14. data/lib/robot_lab/tool.rb +8 -23
  15. data/lib/robot_lab/version.rb +1 -1
  16. data/lib/robot_lab.rb +1 -4
  17. metadata +16 -292
  18. data/.architecture/AGENTS.md +0 -32
  19. data/.architecture/config.yml +0 -8
  20. data/.architecture/members.yml +0 -60
  21. data/.architecture/reviews/feature-free-will.md +0 -490
  22. data/.architecture/reviews/overall-codebase.md +0 -427
  23. data/.claude/settings.local.json +0 -57
  24. data/.codex/config.toml +0 -2
  25. data/.envrc +0 -6
  26. data/.github/workflows/deploy-github-pages.yml +0 -52
  27. data/.irbrc +0 -6
  28. data/.loki +0 -65
  29. data/.quality/reek_baseline.txt +0 -43
  30. data/.rubocop.yml +0 -10
  31. data/Archspec.rb +0 -44
  32. data/CLAUDE.md +0 -141
  33. data/COMMITS.md +0 -196
  34. data/Rakefile +0 -193
  35. data/_typos.toml +0 -21
  36. data/agent2agent_review.md +0 -192
  37. data/agentf_improvements.md +0 -253
  38. data/agents.md +0 -14
  39. data/docs/api/core/index.md +0 -147
  40. data/docs/api/core/memory.md +0 -578
  41. data/docs/api/core/network.md +0 -553
  42. data/docs/api/core/result.md +0 -211
  43. data/docs/api/core/robot.md +0 -1667
  44. data/docs/api/core/state.md +0 -145
  45. data/docs/api/core/tool.md +0 -520
  46. data/docs/api/errors.md +0 -323
  47. data/docs/api/hooks.md +0 -469
  48. data/docs/api/index.md +0 -137
  49. data/docs/api/mcp/client.md +0 -387
  50. data/docs/api/mcp/index.md +0 -267
  51. data/docs/api/mcp/server.md +0 -252
  52. data/docs/api/mcp/transports.md +0 -339
  53. data/docs/api/messages/index.md +0 -126
  54. data/docs/api/messages/text-message.md +0 -170
  55. data/docs/api/messages/tool-call-message.md +0 -206
  56. data/docs/api/messages/tool-result-message.md +0 -242
  57. data/docs/api/messages/user-message.md +0 -232
  58. data/docs/api/skills.md +0 -423
  59. data/docs/api/streaming/context.md +0 -280
  60. data/docs/api/streaming/events.md +0 -185
  61. data/docs/api/streaming/index.md +0 -156
  62. data/docs/api/support.md +0 -846
  63. data/docs/architecture/core-concepts.md +0 -575
  64. data/docs/architecture/index.md +0 -252
  65. data/docs/architecture/message-flow.md +0 -366
  66. data/docs/architecture/network-orchestration.md +0 -478
  67. data/docs/architecture/robot-execution.md +0 -396
  68. data/docs/architecture/state-management.md +0 -410
  69. data/docs/assets/css/custom.css +0 -56
  70. data/docs/assets/images/robot_lab.jpg +0 -0
  71. data/docs/concepts.md +0 -641
  72. data/docs/examples/basic-chat.md +0 -258
  73. data/docs/examples/index.md +0 -425
  74. data/docs/examples/mcp-server.md +0 -403
  75. data/docs/examples/multi-robot-network.md +0 -476
  76. data/docs/examples/tool-usage.md +0 -468
  77. data/docs/getting-started/configuration.md +0 -645
  78. data/docs/getting-started/index.md +0 -56
  79. data/docs/getting-started/installation.md +0 -197
  80. data/docs/getting-started/quick-start.md +0 -293
  81. data/docs/guides/building-robots.md +0 -1187
  82. data/docs/guides/creating-networks.md +0 -736
  83. data/docs/guides/hooks.md +0 -1206
  84. data/docs/guides/index.md +0 -78
  85. data/docs/guides/knowledge.md +0 -219
  86. data/docs/guides/mcp-integration.md +0 -740
  87. data/docs/guides/memory.md +0 -458
  88. data/docs/guides/observability.md +0 -733
  89. data/docs/guides/streaming.md +0 -323
  90. data/docs/guides/using-tools.md +0 -780
  91. data/docs/index.md +0 -280
  92. data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
  93. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
  94. data/examples/.envrc +0 -3
  95. data/examples/01_simple_robot.rb +0 -31
  96. data/examples/02_tools.rb +0 -109
  97. data/examples/03_network.rb +0 -118
  98. data/examples/04_mcp.rb +0 -217
  99. data/examples/05_streaming.rb +0 -137
  100. data/examples/06_prompt_templates.rb +0 -325
  101. data/examples/07_network_memory.rb +0 -313
  102. data/examples/08_llm_config.rb +0 -162
  103. data/examples/09_chaining.rb +0 -251
  104. data/examples/10_memory.rb +0 -315
  105. data/examples/11_network_introspection.rb +0 -239
  106. data/examples/12_message_bus.rb +0 -67
  107. data/examples/13_spawn.rb +0 -85
  108. data/examples/14_rusty_circuit/.envrc +0 -1
  109. data/examples/14_rusty_circuit/.gitignore +0 -1
  110. data/examples/14_rusty_circuit/README.md +0 -1
  111. data/examples/14_rusty_circuit/comic.rb +0 -149
  112. data/examples/14_rusty_circuit/display.rb +0 -217
  113. data/examples/14_rusty_circuit/heckler.rb +0 -65
  114. data/examples/14_rusty_circuit/open_mic.rb +0 -132
  115. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
  116. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
  117. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
  118. data/examples/14_rusty_circuit/scout.rb +0 -165
  119. data/examples/14_rusty_circuit/show.log +0 -234
  120. data/examples/15_memory_network_and_bus/.envrc +0 -1
  121. data/examples/15_memory_network_and_bus/README.md +0 -66
  122. data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
  123. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
  124. data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
  125. data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
  126. data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
  127. data/examples/15_memory_network_and_bus/output/combined_article.md +0 -11
  128. data/examples/15_memory_network_and_bus/output/final_article.md +0 -8
  129. data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
  130. data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
  131. data/examples/15_memory_network_and_bus/output/memory.json +0 -13
  132. data/examples/15_memory_network_and_bus/output/revision_1.md +0 -29
  133. data/examples/15_memory_network_and_bus/output/revision_2.md +0 -50
  134. data/examples/15_memory_network_and_bus/output/revision_3.md +0 -8
  135. data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
  136. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
  137. data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
  138. data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
  139. data/examples/16_writers_room/.envrc +0 -1
  140. data/examples/16_writers_room/display.rb +0 -158
  141. data/examples/16_writers_room/output/.gitignore +0 -4
  142. data/examples/16_writers_room/output/README.md +0 -69
  143. data/examples/16_writers_room/output/opus_001.md +0 -263
  144. data/examples/16_writers_room/output/opus_001_notes.log +0 -470
  145. data/examples/16_writers_room/output/opus_002.md +0 -245
  146. data/examples/16_writers_room/output/opus_002_notes.log +0 -546
  147. data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
  148. data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
  149. data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
  150. data/examples/16_writers_room/prompts/writer.md +0 -37
  151. data/examples/16_writers_room/room.rb +0 -186
  152. data/examples/16_writers_room/tools.rb +0 -173
  153. data/examples/16_writers_room/writer.rb +0 -121
  154. data/examples/16_writers_room/writers_room.rb +0 -256
  155. data/examples/17_skills.rb +0 -234
  156. data/examples/18_rails/.envrc +0 -3
  157. data/examples/18_rails/.gitignore +0 -5
  158. data/examples/18_rails/Gemfile +0 -11
  159. data/examples/18_rails/README.md +0 -67
  160. data/examples/18_rails/Rakefile +0 -4
  161. data/examples/18_rails/app/controllers/application_controller.rb +0 -4
  162. data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
  163. data/examples/18_rails/app/jobs/application_job.rb +0 -4
  164. data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
  165. data/examples/18_rails/app/models/application_record.rb +0 -5
  166. data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
  167. data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
  168. data/examples/18_rails/app/robots/chat_robot.rb +0 -25
  169. data/examples/18_rails/app/tools/time_tool.rb +0 -9
  170. data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
  171. data/examples/18_rails/app/views/chat/index.html.erb +0 -67
  172. data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
  173. data/examples/18_rails/bin/dev +0 -7
  174. data/examples/18_rails/bin/rails +0 -6
  175. data/examples/18_rails/bin/setup +0 -15
  176. data/examples/18_rails/config/application.rb +0 -33
  177. data/examples/18_rails/config/cable.yml +0 -2
  178. data/examples/18_rails/config/database.yml +0 -5
  179. data/examples/18_rails/config/environment.rb +0 -4
  180. data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
  181. data/examples/18_rails/config/routes.rb +0 -6
  182. data/examples/18_rails/config.ru +0 -4
  183. data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
  184. data/examples/19_token_tracking.rb +0 -138
  185. data/examples/20_circuit_breaker.rb +0 -147
  186. data/examples/21_learning_loop.rb +0 -181
  187. data/examples/22_context_compression.rb +0 -172
  188. data/examples/23_convergence.rb +0 -133
  189. data/examples/24_structured_delegation.rb +0 -151
  190. data/examples/25_history_search/conversation.jsonl +0 -30
  191. data/examples/25_history_search.rb +0 -133
  192. data/examples/26_document_store/api_versioning_adr.md +0 -52
  193. data/examples/26_document_store/incident_postmortem.md +0 -46
  194. data/examples/26_document_store/postgres_runbook.md +0 -49
  195. data/examples/26_document_store/redis_caching_guide.md +0 -48
  196. data/examples/26_document_store/sidekiq_guide.md +0 -51
  197. data/examples/26_document_store.rb +0 -140
  198. data/examples/27_incident_response/README.md +0 -65
  199. data/examples/27_incident_response/incident_response.rb +0 -261
  200. data/examples/28_mcp_discovery.rb +0 -113
  201. data/examples/29_ractor_tools.rb +0 -240
  202. data/examples/30_ractor_network.rb +0 -252
  203. data/examples/31_launch_assessment.rb +0 -246
  204. data/examples/32_newsletter_reader.rb +0 -193
  205. data/examples/33_stock_generator.rb +0 -80
  206. data/examples/33_stock_predictor.rb +0 -327
  207. data/examples/34_agentskills.rb +0 -76
  208. data/examples/35_hooks.rb +0 -266
  209. data/examples/README.md +0 -550
  210. data/examples/common.rb +0 -180
  211. data/examples/prompts/assistant.md +0 -5
  212. data/examples/prompts/audit_trail.md +0 -8
  213. data/examples/prompts/billing.md +0 -10
  214. data/examples/prompts/classifier.md +0 -7
  215. data/examples/prompts/comedian.md +0 -6
  216. data/examples/prompts/comedy_critic.md +0 -10
  217. data/examples/prompts/configurable.md +0 -9
  218. data/examples/prompts/dispatcher.md +0 -12
  219. data/examples/prompts/entity_extractor.md +0 -14
  220. data/examples/prompts/escalation.md +0 -42
  221. data/examples/prompts/frontmatter_mcp_test.md +0 -9
  222. data/examples/prompts/frontmatter_named_test.md +0 -5
  223. data/examples/prompts/frontmatter_tools_test.md +0 -6
  224. data/examples/prompts/general.md +0 -7
  225. data/examples/prompts/github_assistant.md +0 -14
  226. data/examples/prompts/helper.md +0 -4
  227. data/examples/prompts/incident_responder.md +0 -18
  228. data/examples/prompts/keyword_extractor.md +0 -11
  229. data/examples/prompts/llm_config_demo.md +0 -20
  230. data/examples/prompts/order_support.md +0 -35
  231. data/examples/prompts/os_advocate.md +0 -13
  232. data/examples/prompts/os_chief.md +0 -13
  233. data/examples/prompts/os_editor.md +0 -13
  234. data/examples/prompts/parameterized_main_test.md +0 -6
  235. data/examples/prompts/pii_redactor.md +0 -7
  236. data/examples/prompts/product_support.md +0 -37
  237. data/examples/prompts/runbook_protocol.md +0 -12
  238. data/examples/prompts/sentiment_analyzer.md +0 -12
  239. data/examples/prompts/skill_a_test.md +0 -4
  240. data/examples/prompts/skill_b_test.md +0 -4
  241. data/examples/prompts/skill_config_test.md +0 -5
  242. data/examples/prompts/skill_cycle_a_test.md +0 -6
  243. data/examples/prompts/skill_cycle_b_test.md +0 -6
  244. data/examples/prompts/skill_description_test.md +0 -4
  245. data/examples/prompts/skill_leaf_test.md +0 -4
  246. data/examples/prompts/skill_nested_test.md +0 -6
  247. data/examples/prompts/skill_refs_main_test.md +0 -6
  248. data/examples/prompts/skill_self_ref_test.md +0 -6
  249. data/examples/prompts/skill_with_mcp_test.md +0 -9
  250. data/examples/prompts/skill_with_params_test.md +0 -6
  251. data/examples/prompts/skill_with_robot_name_test.md +0 -5
  252. data/examples/prompts/skill_with_tools_test.md +0 -6
  253. data/examples/prompts/sre_compliance.md +0 -10
  254. data/examples/prompts/structured_output.md +0 -7
  255. data/examples/prompts/synthesizer.md +0 -17
  256. data/examples/prompts/technical.md +0 -10
  257. data/examples/prompts/template_with_skills_test.md +0 -6
  258. data/examples/prompts/triage.md +0 -22
  259. data/examples/ruboruby.md +0 -423
  260. data/examples/run_all.rb +0 -60
  261. data/examples/xyzzy.rb +0 -97
  262. data/lib/robot_lab/mcp/client.rb +0 -223
  263. data/lib/robot_lab/mcp/connection_poller.rb +0 -195
  264. data/lib/robot_lab/mcp/transports/base.rb +0 -64
  265. data/lib/robot_lab/mcp/transports/sse.rb +0 -120
  266. data/lib/robot_lab/mcp/transports/stdio.rb +0 -170
  267. data/lib/robot_lab/mcp/transports/streamable_http.rb +0 -141
  268. data/lib/robot_lab/mcp/transports/websocket.rb +0 -111
  269. data/logfile +0 -8
  270. data/mkdocs.yml +0 -209
  271. data/robot_concurrency.md +0 -38
  272. data/simple_acp_review.md +0 -298
  273. data/temp.md +0 -6
  274. data/tool_manifest_plan.md +0 -155
@@ -1,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