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
@@ -1,410 +0,0 @@
1
- # Memory Management
2
-
3
- Memory in RobotLab is a reactive key-value store that provides persistent storage for runtime data, conversation history, and arbitrary user-defined values. A single unified `Memory` class serves both standalone robot usage and shared network execution.
4
-
5
- ## Memory Structure
6
-
7
- The `Memory` class holds:
8
-
9
- ```ruby
10
- memory = RobotLab.create_memory(data: { user_id: "123" })
11
-
12
- memory.data # StateProxy - custom key-value data with method-style access
13
- memory.results # Array<RobotResult> - execution history
14
- memory.messages # Array<Message> - conversation history
15
- memory.session_id # String - optional persistence identifier
16
- memory.cache # RubyLLM::SemanticCache when the optional gem is installed, else nil
17
- ```
18
-
19
- ## Standalone Robot Memory
20
-
21
- Every robot has its own inherent memory instance, accessible via `robot.memory`:
22
-
23
- ```ruby
24
- robot = RobotLab.build(
25
- name: "assistant",
26
- system_prompt: "You are helpful."
27
- )
28
-
29
- # Access the robot's memory
30
- robot.memory[:user_name] = "Alice"
31
- robot.memory[:user_name] #=> "Alice"
32
-
33
- # Run the robot
34
- result = robot.run("Hello!")
35
-
36
- # Memory persists between runs on the same robot instance
37
- robot.memory[:preference] = "dark_mode"
38
- result2 = robot.run("What are my preferences?")
39
-
40
- # Reset memory to initial state
41
- robot.reset_memory
42
- ```
43
-
44
- `reset_memory` resets only the key-value store. It does **not** touch the robot's chat history — that is `robot.clear_messages(keep_system: true)`. The two are independent.
45
-
46
- ## Network Shared Memory
47
-
48
- When robots execute within a network, they share the network's memory instead of using their own inherent memory. This enables inter-robot communication.
49
-
50
- ```ruby
51
- classifier = RobotLab.build(name: "classifier", system_prompt: "Classify requests.")
52
- handler = RobotLab.build(name: "handler", system_prompt: "Handle requests.")
53
-
54
- network = RobotLab.create_network(name: "support") do
55
- task :classifier, classifier, depends_on: :none
56
- task :handler, handler, depends_on: [:classifier]
57
- end
58
-
59
- # The network has its own shared memory
60
- network.memory[:customer_tier] = "premium"
61
-
62
- # All robots in the network read/write from network.memory during execution
63
- result = network.run(message: "I need help with billing")
64
-
65
- # Reset network memory between runs if needed
66
- network.reset_memory
67
- ```
68
-
69
- The memory resolution logic is:
70
-
71
- 1. If `network_memory` is provided at runtime, use that
72
- 2. If the robot is in a network, use the network's shared memory
73
- 3. Otherwise, use the robot's own inherent memory (`robot.memory`)
74
-
75
- ## Creating Memory
76
-
77
- ### Basic Creation
78
-
79
- ```ruby
80
- memory = RobotLab.create_memory
81
- ```
82
-
83
- ### With Initial Data
84
-
85
- ```ruby
86
- memory = RobotLab.create_memory(
87
- data: {
88
- user_id: "user_123",
89
- order_id: "ord_456",
90
- priority: "high"
91
- }
92
- )
93
- ```
94
-
95
- ### With Caching Disabled
96
-
97
- ```ruby
98
- memory = RobotLab.create_memory(data: {}, enable_cache: false)
99
- ```
100
-
101
- ## Reserved Keys
102
-
103
- Memory has five reserved keys with special behavior and dedicated accessors:
104
-
105
- | Key | Type | Description |
106
- |-----|------|-------------|
107
- | `:data` | `StateProxy` | Runtime data with method-style access |
108
- | `:results` | `Array<RobotResult>` | Accumulated robot execution results |
109
- | `:messages` | `Array<Message>` | Conversation history |
110
- | `:session_id` | `String` | Conversation session identifier |
111
- | `:cache` | `RubyLLM::SemanticCache` or `nil` | Semantic cache module when the optional ruby_llm-semantic_cache gem is installed (read-only after init) |
112
-
113
- Reserved keys are accessed through dedicated methods and are excluded from `memory.keys`:
114
-
115
- ```ruby
116
- memory.data[:category] = "billing"
117
- memory.data.category #=> "billing" (method-style via StateProxy)
118
-
119
- memory.results #=> []
120
- memory.session_id #=> nil
121
- memory.cache #=> RubyLLM::SemanticCache (the module itself), or nil when enable_cache: false or the optional gem is absent
122
- ```
123
-
124
- ## StateProxy
125
-
126
- The `data` attribute is a `StateProxy` that provides convenient hash-style and method-style access:
127
-
128
- ```ruby
129
- memory.data[:user_id] # Hash-style access
130
- memory.data[:user_id] = "456" # Assignment
131
-
132
- memory.data.user_id # Method-style access
133
- memory.data.user_id = "456" # Method-style assignment
134
-
135
- memory.data.key?(:user_id) # Check existence
136
- memory.data.keys # Get all keys
137
- memory.data.to_h # Convert to plain hash
138
- ```
139
-
140
- ## Reactive Features
141
-
142
- Memory supports pub/sub semantics where robots can subscribe to key changes and optionally block until values become available.
143
-
144
- ### Setting Values
145
-
146
- Use `memory.set(key, value)` to write a value, wake any waiters, and notify subscribers. Subscriber callbacks are dispatched through `Async { }`: inside a running reactor they run as fibers, but **outside** one they run synchronously on the writer's thread.
147
-
148
- ```ruby
149
- memory.set(:sentiment, { score: 0.8, confidence: 0.95 })
150
- ```
151
-
152
- The `[]=` operator also triggers reactive notifications for non-reserved keys:
153
-
154
- ```ruby
155
- memory[:sentiment] = { score: 0.8 } # Equivalent to memory.set(:sentiment, ...)
156
- ```
157
-
158
- ### Blocking Reads
159
-
160
- Use `memory.get(key, wait:)` to block until a value becomes available. This is useful for concurrent pipeline execution where one robot needs to wait for another's output:
161
-
162
- ```ruby
163
- # Immediate read (returns nil if missing)
164
- memory.get(:sentiment)
165
-
166
- # Block indefinitely until value exists
167
- memory.get(:sentiment, wait: true)
168
-
169
- # Block up to 30 seconds, then raise RobotLab::AwaitTimeout
170
- memory.get(:sentiment, wait: 30)
171
-
172
- # Wait for multiple keys at once
173
- results = memory.get(:sentiment, :entities, :keywords, wait: 60)
174
- #=> { sentiment: {...}, entities: [...], keywords: [...] }
175
- ```
176
-
177
- Two things to be careful with:
178
-
179
- - On expiry a blocking read **raises** `RobotLab::AwaitTimeout`; it does not return `nil`. Rescue it if a missing value is acceptable.
180
- - With multiple keys the timeout is applied **per missing key**, not to the call as a whole. `get_multiple` waits on the missing keys one at a time in order, so the call raises as soon as the *first* one expires — it does not spend the full 60 s on each. The 180 s worst case is only reached when the earlier keys arrive just before their own deadlines.
181
-
182
- ### Subscriptions
183
-
184
- Subscribe to key changes with async callbacks. The callback receives a `MemoryChange` object:
185
-
186
- ```ruby
187
- memory.subscribe(:raw_data) do |change|
188
- puts "#{change.key} changed from #{change.previous} to #{change.value}"
189
- puts "Written by: #{change.writer} at #{change.timestamp}"
190
- end
191
-
192
- # Subscribe to multiple keys
193
- memory.subscribe(:sentiment, :entities) do |change|
194
- update_dashboard(change.key, change.value)
195
- end
196
-
197
- # Pattern-based subscriptions (glob-style matching)
198
- memory.subscribe_pattern("analysis:*") do |change|
199
- puts "Analysis key #{change.key} updated"
200
- end
201
-
202
- # Unsubscribe
203
- sub_id = memory.subscribe(:status) { |c| puts c.value }
204
- memory.unsubscribe(sub_id)
205
-
206
- # Check if key has subscribers
207
- memory.subscribed?(:status) #=> true/false
208
- ```
209
-
210
- ### MemoryChange
211
-
212
- The `MemoryChange` object provides context about what changed:
213
-
214
- ```ruby
215
- change.key #=> :sentiment
216
- change.value #=> { score: 0.8 }
217
- change.previous #=> nil (or previous value)
218
- change.writer #=> "classifier" (robot name)
219
- change.network_name #=> "support_pipeline"
220
- change.timestamp #=> Time
221
- change.created? #=> true (new key, no previous value)
222
- change.updated? #=> false
223
- change.deleted? #=> false
224
- ```
225
-
226
- ## Memory Lifecycle
227
-
228
- ### Results
229
-
230
- Results track the history of robot executions:
231
-
232
- ```ruby
233
- # Append a result
234
- memory.append_result(robot_result)
235
-
236
- # Get all results (returns a copy)
237
- memory.results
238
-
239
- # Get results from a specific index (for incremental persistence)
240
- memory.results_from(5)
241
- ```
242
-
243
- Each `RobotResult` contains:
244
-
245
- ```ruby
246
- result.robot_name # Which robot produced this
247
- result.output # [TextMessage] synthesized from the final response text
248
- result.tool_calls # Array<ToolResultMessage> - effectively always empty (see Message Flow)
249
- result.stop_reason # always nil for a robot.run result (see Message Flow)
250
- result.last_text_content # Convenience: last text content string
251
- result.input_tokens # Prompt tokens for the run
252
- result.output_tokens # Completion tokens for the run
253
- result.created_at # When it was created
254
- ```
255
-
256
- ### Format History
257
-
258
- The `format_history` method prepares messages for LLM consumption:
259
-
260
- ```ruby
261
- formatted = memory.format_history
262
- # Returns combined messages + formatted results
263
- ```
264
-
265
- ### Merge
266
-
267
- Merge additional values into memory:
268
-
269
- ```ruby
270
- memory.merge!(user_id: 123, category: "billing")
271
- ```
272
-
273
- ### Key Management
274
-
275
- ```ruby
276
- memory.key?(:user_id) # Check existence
277
- memory.keys # Get all non-reserved keys
278
- memory.all_keys # Get all keys including reserved
279
- memory.delete(:temp_data) # Delete a specific key
280
- memory.clear # Clear all non-reserved keys
281
- memory.reset # Reset to initial state (preserves cache)
282
- ```
283
-
284
- ## Cloning
285
-
286
- Create independent copies of memory for isolated execution. Subscriptions are not cloned:
287
-
288
- ```ruby
289
- original = RobotLab.create_memory(data: { count: 1 })
290
- cloned = original.clone
291
-
292
- cloned[:count] = 2
293
- original[:count] #=> still 1
294
- ```
295
-
296
- ## Serialization
297
-
298
- Convert memory to and from hash for persistence:
299
-
300
- ```ruby
301
- # To hash
302
- hash = memory.to_h
303
- #=> {
304
- # data: { ... },
305
- # results: [...],
306
- # messages: [...],
307
- # session_id: "abc123",
308
- # custom: { my_key: "value" }
309
- # }
310
-
311
- # To JSON
312
- json = memory.to_json
313
-
314
- # From hash
315
- memory = Memory.from_hash(hash)
316
- ```
317
-
318
- `to_h` is compacted, so nil-valued reserved keys (a missing `session_id`, for instance) are omitted entirely rather than serialized as `nil`.
319
-
320
- ## Semantic Cache
321
-
322
- Memory includes a semantic cache via `RubyLLM::SemanticCache` (optional ruby_llm-semantic_cache gem; not yet ruby_llm 2.0-compatible, so `memory.cache` is `nil` without it) that reduces costs and latency by returning cached responses for semantically equivalent queries:
323
-
324
- ```ruby
325
- # Using the cache with fetch
326
- response = memory.cache.fetch("What is Ruby?") do
327
- RubyLLM.chat.ask("What is Ruby?")
328
- end
329
-
330
- # Wrapping a chat instance
331
- chat = memory.cache.wrap(RubyLLM.chat(model: "gpt-4o"))
332
- chat.ask("What is Ruby?") # Cached on semantic similarity
333
- ```
334
-
335
- Caching can be disabled per-memory or per-robot:
336
-
337
- ```ruby
338
- memory = RobotLab.create_memory(enable_cache: false)
339
- robot = RobotLab.build(name: "bot", system_prompt: "...", enable_cache: false)
340
- ```
341
-
342
- ## Backend Options
343
-
344
- Memory defaults to a Hash-based backend but can use Redis for distributed scenarios:
345
-
346
- ```ruby
347
- # Try Redis, fall back to Hash
348
- memory = Memory.new(backend: :auto)
349
-
350
- # Hash backend — the only value that is honoured literally
351
- memory = Memory.new(backend: :hash)
352
-
353
- # Same behaviour as :auto — try Redis, fall back to Hash
354
- memory = Memory.new(backend: :redis)
355
-
356
- # Check what you actually got
357
- memory.redis? #=> true/false
358
- ```
359
-
360
- !!! note "`backend: :redis` does not force Redis"
361
- `select_backend` special-cases only `:hash`; every other value (`:redis`,
362
- `:auto`, anything else) takes the same branch —
363
- `create_redis_backend || create_hash_backend`. `create_redis_backend`
364
- returns `nil` when `redis` is unavailable and rescues `StandardError` to
365
- `nil` on a connection failure, so an unreachable Redis silently downgrades
366
- to a Hash with no exception and no warning. Always check `memory.redis?` if
367
- the distinction matters.
368
-
369
- Redis is configured via `RobotLab.config.redis` or the `REDIS_URL` environment variable.
370
-
371
- ## Best Practices
372
-
373
- ### 1. Use Memory for Cross-Robot Data
374
-
375
- ```ruby
376
- # In a network, robots share memory automatically.
377
- # Robot A writes:
378
- memory.set(:classification, "billing")
379
-
380
- # Robot B reads:
381
- category = memory.get(:classification)
382
- ```
383
-
384
- ### 2. Use Blocking Reads for Concurrent Pipelines
385
-
386
- ```ruby
387
- # When robots run in parallel, use blocking reads
388
- # to synchronize on shared data:
389
- results = memory.get(:sentiment, :entities, wait: 60)
390
- ```
391
-
392
- ### 3. Keep Data Minimal
393
-
394
- ```ruby
395
- # Store references instead of large objects
396
- memory[:response_id] = response.id # Preferred
397
- # memory[:huge_response] = api_response # Avoid
398
- ```
399
-
400
- ### 4. Reset Between Independent Runs
401
-
402
- ```ruby
403
- network.reset_memory
404
- result = network.run(message: "New conversation")
405
- ```
406
-
407
- ## Next Steps
408
-
409
- - [Network Orchestration](network-orchestration.md) - How networks share memory
410
- - [Message Flow](message-flow.md) - How messages are processed
@@ -1,56 +0,0 @@
1
- /* Custom styles for RobotLab documentation */
2
-
3
- /* Robot-themed accent colors */
4
- :root {
5
- --md-primary-fg-color: #673ab7;
6
- --md-primary-fg-color--light: #9575cd;
7
- --md-primary-fg-color--dark: #512da8;
8
- --md-accent-fg-color: #ffc107;
9
- }
10
-
11
- /* Code block styling */
12
- .md-typeset code {
13
- background-color: rgba(103, 58, 183, 0.1);
14
- }
15
-
16
- /* Admonition customization */
17
- .md-typeset .admonition.robot,
18
- .md-typeset details.robot {
19
- border-color: #673ab7;
20
- }
21
-
22
- .md-typeset .robot > .admonition-title,
23
- .md-typeset .robot > summary {
24
- background-color: rgba(103, 58, 183, 0.1);
25
- }
26
-
27
- .md-typeset .robot > .admonition-title::before,
28
- .md-typeset .robot > summary::before {
29
- background-color: #673ab7;
30
- -webkit-mask-image: var(--md-admonition-icon--robot);
31
- mask-image: var(--md-admonition-icon--robot);
32
- }
33
-
34
- /* Grid cards spacing */
35
- .md-typeset .grid.cards > ul > li {
36
- margin-bottom: 1em;
37
- }
38
-
39
- /* API reference table styling */
40
- .md-typeset table:not([class]) th {
41
- background-color: rgba(103, 58, 183, 0.1);
42
- }
43
-
44
- /* Mermaid diagram styling */
45
- .mermaid {
46
- background: transparent !important;
47
- }
48
-
49
- /* Dark mode adjustments */
50
- [data-md-color-scheme="slate"] {
51
- --md-code-bg-color: #1e1e2e;
52
- }
53
-
54
- [data-md-color-scheme="slate"] .md-typeset code {
55
- background-color: rgba(149, 117, 205, 0.2);
56
- }
Binary file