robot_lab 0.0.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 (153) hide show
  1. checksums.yaml +7 -0
  2. data/.envrc +1 -0
  3. data/.github/workflows/deploy-github-pages.yml +52 -0
  4. data/.github/workflows/deploy-yard-docs.yml +52 -0
  5. data/CHANGELOG.md +55 -0
  6. data/COMMITS.md +196 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +332 -0
  9. data/Rakefile +67 -0
  10. data/docs/api/adapters/anthropic.md +121 -0
  11. data/docs/api/adapters/gemini.md +133 -0
  12. data/docs/api/adapters/index.md +104 -0
  13. data/docs/api/adapters/openai.md +134 -0
  14. data/docs/api/core/index.md +113 -0
  15. data/docs/api/core/memory.md +314 -0
  16. data/docs/api/core/network.md +291 -0
  17. data/docs/api/core/robot.md +273 -0
  18. data/docs/api/core/state.md +273 -0
  19. data/docs/api/core/tool.md +353 -0
  20. data/docs/api/history/active-record-adapter.md +195 -0
  21. data/docs/api/history/config.md +191 -0
  22. data/docs/api/history/index.md +132 -0
  23. data/docs/api/history/thread-manager.md +144 -0
  24. data/docs/api/index.md +82 -0
  25. data/docs/api/mcp/client.md +221 -0
  26. data/docs/api/mcp/index.md +111 -0
  27. data/docs/api/mcp/server.md +225 -0
  28. data/docs/api/mcp/transports.md +264 -0
  29. data/docs/api/messages/index.md +67 -0
  30. data/docs/api/messages/text-message.md +102 -0
  31. data/docs/api/messages/tool-call-message.md +144 -0
  32. data/docs/api/messages/tool-result-message.md +154 -0
  33. data/docs/api/messages/user-message.md +171 -0
  34. data/docs/api/streaming/context.md +174 -0
  35. data/docs/api/streaming/events.md +237 -0
  36. data/docs/api/streaming/index.md +108 -0
  37. data/docs/architecture/core-concepts.md +243 -0
  38. data/docs/architecture/index.md +138 -0
  39. data/docs/architecture/message-flow.md +320 -0
  40. data/docs/architecture/network-orchestration.md +216 -0
  41. data/docs/architecture/robot-execution.md +243 -0
  42. data/docs/architecture/state-management.md +323 -0
  43. data/docs/assets/css/custom.css +56 -0
  44. data/docs/assets/images/robot_lab.jpg +0 -0
  45. data/docs/concepts.md +216 -0
  46. data/docs/examples/basic-chat.md +193 -0
  47. data/docs/examples/index.md +129 -0
  48. data/docs/examples/mcp-server.md +290 -0
  49. data/docs/examples/multi-robot-network.md +312 -0
  50. data/docs/examples/rails-application.md +420 -0
  51. data/docs/examples/tool-usage.md +310 -0
  52. data/docs/getting-started/configuration.md +230 -0
  53. data/docs/getting-started/index.md +56 -0
  54. data/docs/getting-started/installation.md +179 -0
  55. data/docs/getting-started/quick-start.md +203 -0
  56. data/docs/guides/building-robots.md +376 -0
  57. data/docs/guides/creating-networks.md +366 -0
  58. data/docs/guides/history.md +359 -0
  59. data/docs/guides/index.md +68 -0
  60. data/docs/guides/mcp-integration.md +356 -0
  61. data/docs/guides/memory.md +309 -0
  62. data/docs/guides/rails-integration.md +432 -0
  63. data/docs/guides/streaming.md +314 -0
  64. data/docs/guides/using-tools.md +394 -0
  65. data/docs/index.md +160 -0
  66. data/examples/01_simple_robot.rb +38 -0
  67. data/examples/02_tools.rb +106 -0
  68. data/examples/03_network.rb +103 -0
  69. data/examples/04_mcp.rb +219 -0
  70. data/examples/05_streaming.rb +124 -0
  71. data/examples/06_prompt_templates.rb +324 -0
  72. data/examples/07_network_memory.rb +329 -0
  73. data/examples/prompts/assistant/system.txt.erb +2 -0
  74. data/examples/prompts/assistant/user.txt.erb +1 -0
  75. data/examples/prompts/billing/system.txt.erb +7 -0
  76. data/examples/prompts/billing/user.txt.erb +1 -0
  77. data/examples/prompts/classifier/system.txt.erb +4 -0
  78. data/examples/prompts/classifier/user.txt.erb +1 -0
  79. data/examples/prompts/entity_extractor/system.txt.erb +11 -0
  80. data/examples/prompts/entity_extractor/user.txt.erb +3 -0
  81. data/examples/prompts/escalation/system.txt.erb +35 -0
  82. data/examples/prompts/escalation/user.txt.erb +34 -0
  83. data/examples/prompts/general/system.txt.erb +4 -0
  84. data/examples/prompts/general/user.txt.erb +1 -0
  85. data/examples/prompts/github_assistant/system.txt.erb +6 -0
  86. data/examples/prompts/github_assistant/user.txt.erb +1 -0
  87. data/examples/prompts/helper/system.txt.erb +1 -0
  88. data/examples/prompts/helper/user.txt.erb +1 -0
  89. data/examples/prompts/keyword_extractor/system.txt.erb +8 -0
  90. data/examples/prompts/keyword_extractor/user.txt.erb +3 -0
  91. data/examples/prompts/order_support/system.txt.erb +27 -0
  92. data/examples/prompts/order_support/user.txt.erb +22 -0
  93. data/examples/prompts/product_support/system.txt.erb +30 -0
  94. data/examples/prompts/product_support/user.txt.erb +32 -0
  95. data/examples/prompts/sentiment_analyzer/system.txt.erb +9 -0
  96. data/examples/prompts/sentiment_analyzer/user.txt.erb +3 -0
  97. data/examples/prompts/synthesizer/system.txt.erb +14 -0
  98. data/examples/prompts/synthesizer/user.txt.erb +15 -0
  99. data/examples/prompts/technical/system.txt.erb +7 -0
  100. data/examples/prompts/technical/user.txt.erb +1 -0
  101. data/examples/prompts/triage/system.txt.erb +16 -0
  102. data/examples/prompts/triage/user.txt.erb +17 -0
  103. data/lib/generators/robot_lab/install_generator.rb +78 -0
  104. data/lib/generators/robot_lab/robot_generator.rb +55 -0
  105. data/lib/generators/robot_lab/templates/initializer.rb.tt +41 -0
  106. data/lib/generators/robot_lab/templates/migration.rb.tt +32 -0
  107. data/lib/generators/robot_lab/templates/result_model.rb.tt +52 -0
  108. data/lib/generators/robot_lab/templates/robot.rb.tt +46 -0
  109. data/lib/generators/robot_lab/templates/robot_test.rb.tt +32 -0
  110. data/lib/generators/robot_lab/templates/routing_robot.rb.tt +53 -0
  111. data/lib/generators/robot_lab/templates/thread_model.rb.tt +40 -0
  112. data/lib/robot_lab/adapters/anthropic.rb +163 -0
  113. data/lib/robot_lab/adapters/base.rb +85 -0
  114. data/lib/robot_lab/adapters/gemini.rb +193 -0
  115. data/lib/robot_lab/adapters/openai.rb +159 -0
  116. data/lib/robot_lab/adapters/registry.rb +81 -0
  117. data/lib/robot_lab/configuration.rb +143 -0
  118. data/lib/robot_lab/error.rb +32 -0
  119. data/lib/robot_lab/errors.rb +70 -0
  120. data/lib/robot_lab/history/active_record_adapter.rb +146 -0
  121. data/lib/robot_lab/history/config.rb +115 -0
  122. data/lib/robot_lab/history/thread_manager.rb +93 -0
  123. data/lib/robot_lab/mcp/client.rb +210 -0
  124. data/lib/robot_lab/mcp/server.rb +84 -0
  125. data/lib/robot_lab/mcp/transports/base.rb +56 -0
  126. data/lib/robot_lab/mcp/transports/sse.rb +117 -0
  127. data/lib/robot_lab/mcp/transports/stdio.rb +133 -0
  128. data/lib/robot_lab/mcp/transports/streamable_http.rb +139 -0
  129. data/lib/robot_lab/mcp/transports/websocket.rb +108 -0
  130. data/lib/robot_lab/memory.rb +882 -0
  131. data/lib/robot_lab/memory_change.rb +123 -0
  132. data/lib/robot_lab/message.rb +357 -0
  133. data/lib/robot_lab/network.rb +350 -0
  134. data/lib/robot_lab/rails/engine.rb +29 -0
  135. data/lib/robot_lab/rails/railtie.rb +42 -0
  136. data/lib/robot_lab/robot.rb +560 -0
  137. data/lib/robot_lab/robot_result.rb +205 -0
  138. data/lib/robot_lab/robotic_model.rb +324 -0
  139. data/lib/robot_lab/state_proxy.rb +188 -0
  140. data/lib/robot_lab/streaming/context.rb +144 -0
  141. data/lib/robot_lab/streaming/events.rb +95 -0
  142. data/lib/robot_lab/streaming/sequence_counter.rb +48 -0
  143. data/lib/robot_lab/task.rb +117 -0
  144. data/lib/robot_lab/tool.rb +223 -0
  145. data/lib/robot_lab/tool_config.rb +112 -0
  146. data/lib/robot_lab/tool_manifest.rb +234 -0
  147. data/lib/robot_lab/user_message.rb +118 -0
  148. data/lib/robot_lab/version.rb +5 -0
  149. data/lib/robot_lab/waiter.rb +73 -0
  150. data/lib/robot_lab.rb +195 -0
  151. data/mkdocs.yml +214 -0
  152. data/sig/robot_lab.rbs +4 -0
  153. metadata +442 -0
@@ -0,0 +1,323 @@
1
+ # State Management
2
+
3
+ State in RobotLab tracks all data and history for a conversation or workflow.
4
+
5
+ ## State Structure
6
+
7
+ The `State` class holds:
8
+
9
+ ```ruby
10
+ state = RobotLab.create_state(
11
+ message: "Hello!", # Current user message
12
+ data: { user_id: "123" } # Custom workflow data
13
+ )
14
+
15
+ state.data # StateProxy - custom key-value data
16
+ state.results # Array<RobotResult> - execution history
17
+ state.messages # Array<Message> - formatted conversation
18
+ state.thread_id # String - optional persistence ID
19
+ state.memory # Memory - shared key-value store
20
+ ```
21
+
22
+ ## Creating State
23
+
24
+ ### Basic Creation
25
+
26
+ ```ruby
27
+ state = RobotLab.create_state(message: "What's the weather?")
28
+ ```
29
+
30
+ ### With Custom Data
31
+
32
+ ```ruby
33
+ state = RobotLab.create_state(
34
+ message: "Process my order",
35
+ data: {
36
+ user_id: "user_123",
37
+ order_id: "ord_456",
38
+ priority: "high"
39
+ }
40
+ )
41
+ ```
42
+
43
+ ### From Existing Results
44
+
45
+ ```ruby
46
+ state = RobotLab.create_state(
47
+ message: "Continue our conversation",
48
+ results: previous_results,
49
+ thread_id: "thread_abc"
50
+ )
51
+ ```
52
+
53
+ ## StateProxy
54
+
55
+ The `data` attribute is a `StateProxy` that provides convenient access:
56
+
57
+ ```ruby
58
+ state.data[:user_id] # Hash-style access
59
+ state.data[:user_id] = "456" # Assignment
60
+
61
+ state.data.user_id # Method-style access
62
+ state.data.user_id = "456" # Method-style assignment
63
+
64
+ state.data.key?(:user_id) # Check existence
65
+ state.data.keys # Get all keys
66
+ state.data.to_h # Convert to plain hash
67
+ ```
68
+
69
+ ### Change Tracking
70
+
71
+ StateProxy can track changes:
72
+
73
+ ```ruby
74
+ state = State.new(
75
+ data: { count: 0 },
76
+ on_change: ->(key, old_val, new_val) {
77
+ puts "#{key}: #{old_val} -> #{new_val}"
78
+ }
79
+ )
80
+
81
+ state.data[:count] = 1 # Prints: "count: 0 -> 1"
82
+ ```
83
+
84
+ ## Memory
85
+
86
+ Memory provides a shared key-value store across robots:
87
+
88
+ ```ruby
89
+ # Store values
90
+ state.memory.remember("user_name", "Alice")
91
+ state.memory.remember("preferences", { theme: "dark" })
92
+
93
+ # Retrieve values
94
+ name = state.memory.recall("user_name") # => "Alice"
95
+
96
+ # Check existence
97
+ state.memory.exists?("user_name") # => true
98
+
99
+ # Remove values
100
+ state.memory.forget("user_name")
101
+
102
+ # List all
103
+ state.memory.all # => { "user_name" => "Alice", ... }
104
+ ```
105
+
106
+ ### Scoped Memory
107
+
108
+ Organize memory with namespaces:
109
+
110
+ ```ruby
111
+ # Create scoped view
112
+ user_memory = state.memory.scoped("user:123")
113
+ user_memory.remember("last_login", Time.now)
114
+
115
+ # Access scoped data
116
+ user_memory.recall("last_login")
117
+
118
+ # Full key is "user:123:last_login"
119
+ state.memory.recall("user:123:last_login")
120
+ ```
121
+
122
+ ### Shared Memory
123
+
124
+ Use the `SHARED` namespace for cross-robot data:
125
+
126
+ ```ruby
127
+ # In first robot
128
+ state.memory.remember("SHARED:context", important_data)
129
+
130
+ # In second robot (same or different network run)
131
+ data = state.memory.recall("SHARED:context")
132
+ ```
133
+
134
+ ### Memory Operations
135
+
136
+ ```ruby
137
+ # Search by pattern
138
+ matches = state.memory.search("user:*")
139
+
140
+ # Get statistics
141
+ state.memory.stats
142
+ # => { total_keys: 15, namespaces: ["user", "session"] }
143
+
144
+ # Clear namespace
145
+ state.memory.scoped("temp").clear
146
+
147
+ # Clear everything
148
+ state.memory.clear_all
149
+ ```
150
+
151
+ ## Results
152
+
153
+ Results track the history of robot executions:
154
+
155
+ ```ruby
156
+ # Append a result
157
+ state.append_result(robot_result)
158
+
159
+ # Get all results
160
+ state.results
161
+
162
+ # Get results from index
163
+ state.results_from(5) # Results starting at index 5
164
+
165
+ # Format for LLM conversation
166
+ state.format_history
167
+ ```
168
+
169
+ ### Result History
170
+
171
+ Each `RobotResult` contains:
172
+
173
+ ```ruby
174
+ result.robot_name # Which robot produced this
175
+ result.output # Array<Message> - response content
176
+ result.tool_calls # Array<ToolMessage> - tools called
177
+ result.stop_reason # "stop", "tool", etc.
178
+ result.created_at # When it was created
179
+ ```
180
+
181
+ ## Messages
182
+
183
+ The `messages` method formats state for LLM consumption:
184
+
185
+ ```ruby
186
+ messages = state.messages
187
+
188
+ # Returns Array<Message> with:
189
+ # - System message (if present)
190
+ # - Alternating user/assistant messages
191
+ # - Tool calls and results
192
+ ```
193
+
194
+ ## Thread ID
195
+
196
+ For persistent conversations:
197
+
198
+ ```ruby
199
+ # Set thread ID
200
+ state.thread_id = "thread_123"
201
+
202
+ # Or via UserMessage
203
+ message = UserMessage.new(
204
+ "Continue",
205
+ thread_id: "thread_123"
206
+ )
207
+ state = RobotLab.create_state(message: message)
208
+ ```
209
+
210
+ ## State Cloning
211
+
212
+ Create independent copies:
213
+
214
+ ```ruby
215
+ original = RobotLab.create_state(data: { count: 1 })
216
+ clone = original.clone
217
+
218
+ clone.data[:count] = 2
219
+ original.data[:count] # Still 1
220
+ ```
221
+
222
+ ## Serialization
223
+
224
+ Convert state to/from hash:
225
+
226
+ ```ruby
227
+ # To hash
228
+ hash = state.to_h
229
+ json = state.to_json
230
+
231
+ # From hash
232
+ state = State.from_hash(hash)
233
+ ```
234
+
235
+ ### Hash Structure
236
+
237
+ ```ruby
238
+ {
239
+ data: { ... },
240
+ results: [
241
+ {
242
+ robot_name: "assistant",
243
+ output: [...],
244
+ tool_calls: [...],
245
+ stop_reason: "stop"
246
+ }
247
+ ],
248
+ thread_id: "thread_123"
249
+ }
250
+ ```
251
+
252
+ ## UserMessage
253
+
254
+ Enhanced message with metadata:
255
+
256
+ ```ruby
257
+ message = UserMessage.new(
258
+ "What's the status of my order?",
259
+ thread_id: "thread_123",
260
+ system_prompt: "Respond in Spanish", # Augment system prompt
261
+ metadata: {
262
+ user_id: "user_456",
263
+ source: "web_chat"
264
+ }
265
+ )
266
+
267
+ state = RobotLab.create_state(message: message)
268
+ ```
269
+
270
+ ### UserMessage Properties
271
+
272
+ | Property | Description |
273
+ |----------|-------------|
274
+ | `content` | The message text |
275
+ | `thread_id` | Conversation thread ID |
276
+ | `system_prompt` | Additional system instructions |
277
+ | `metadata` | Custom key-value data |
278
+ | `id` | Unique message identifier |
279
+ | `created_at` | Timestamp |
280
+
281
+ ## Best Practices
282
+
283
+ ### 1. Use Memory for Cross-Robot Data
284
+
285
+ ```ruby
286
+ # Don't pass data through routing
287
+ router = ->(args) {
288
+ # Bad: parsing previous output for data
289
+ }
290
+
291
+ # Do: use memory
292
+ state.memory.remember("classification", "billing")
293
+ # Later robot reads it directly
294
+ ```
295
+
296
+ ### 2. Scope Memory Appropriately
297
+
298
+ ```ruby
299
+ # Session data
300
+ session = state.memory.scoped("session:#{session_id}")
301
+
302
+ # User preferences
303
+ user = state.memory.scoped("user:#{user_id}")
304
+
305
+ # Temporary working data
306
+ temp = state.memory.scoped("temp")
307
+ ```
308
+
309
+ ### 3. Keep Data Minimal
310
+
311
+ ```ruby
312
+ # Don't store large objects
313
+ state.data[:huge_response] = api_response # Bad
314
+
315
+ # Store references instead
316
+ state.data[:response_id] = response.id # Good
317
+ ```
318
+
319
+ ## Next Steps
320
+
321
+ - [Memory System](../guides/memory.md) - Advanced memory patterns
322
+ - [History Guide](../guides/history.md) - Persisting state
323
+ - [Message Flow](message-flow.md) - How messages are processed
@@ -0,0 +1,56 @@
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
data/docs/concepts.md ADDED
@@ -0,0 +1,216 @@
1
+ # Core Concepts
2
+
3
+ Understanding the fundamental concepts in RobotLab will help you build effective AI applications.
4
+
5
+ ## Robot
6
+
7
+ A **Robot** is an LLM-powered agent with a specific personality, capabilities, and tools. Each robot has:
8
+
9
+ - **Name**: A unique identifier within a network
10
+ - **Description**: What the robot does (used for routing decisions)
11
+ - **Template/System Prompt**: Instructions that define the robot's behavior
12
+ - **Model**: The LLM model to use (e.g., `claude-sonnet-4`)
13
+ - **Tools**: Custom functions the robot can call
14
+
15
+ ```ruby
16
+ robot = RobotLab.build do
17
+ name "support_agent"
18
+ description "Handles customer support inquiries"
19
+ model "claude-sonnet-4"
20
+ template "You are a friendly customer support agent..."
21
+
22
+ tool :lookup_order do
23
+ description "Look up order details by order ID"
24
+ parameter :order_id, type: :string, required: true
25
+ handler { |order_id:| Order.find(order_id).to_h }
26
+ end
27
+ end
28
+ ```
29
+
30
+ ## Network
31
+
32
+ A **Network** is a collection of robots orchestrated using [SimpleFlow](https://github.com/MadBomber/simple_flow) pipelines. Networks provide:
33
+
34
+ - **Task-Based Orchestration**: Define tasks with dependencies and routing
35
+ - **Parallel Execution**: Tasks with the same dependencies run concurrently
36
+ - **Optional Task Activation**: Dynamic routing based on robot output
37
+ - **Per-Task Configuration**: Each task can have its own context, tools, and MCP servers
38
+
39
+ ```ruby
40
+ network = RobotLab.create_network(name: "customer_service") do
41
+ task :classifier, classifier_robot, depends_on: :none
42
+ task :billing, billing_robot,
43
+ context: { department: "billing" },
44
+ depends_on: :optional
45
+ task :technical, technical_robot,
46
+ context: { department: "technical" },
47
+ depends_on: :optional
48
+ end
49
+ ```
50
+
51
+ ## Task
52
+
53
+ A **Task** wraps a robot for use in a network pipeline with per-task configuration:
54
+
55
+ - **Context**: Task-specific context deep-merged with network run params
56
+ - **MCP**: MCP servers available to this task
57
+ - **Tools**: Tools available to this task
58
+ - **Memory**: Task-specific memory
59
+ - **Dependencies**: `:none`, `[:task1, :task2]`, or `:optional`
60
+
61
+ ```ruby
62
+ task :billing, billing_robot,
63
+ context: { department: "billing", escalation_level: 2 },
64
+ tools: [RefundTool, InvoiceTool],
65
+ depends_on: :optional
66
+ ```
67
+
68
+ ## SimpleFlow::Result
69
+
70
+ Networks use `SimpleFlow::Result` for data flow between tasks:
71
+
72
+ ```ruby
73
+ result.value # Current task's output (RobotResult)
74
+ result.context # Accumulated context from all tasks
75
+ result.halted? # Whether execution stopped early
76
+ result.continued? # Whether execution continues
77
+ ```
78
+
79
+ ### Result Methods
80
+
81
+ | Method | Purpose |
82
+ |--------|---------|
83
+ | `continue(value)` | Continue to next tasks |
84
+ | `halt(value)` | Stop pipeline execution |
85
+ | `with_context(key, val)` | Add data to context |
86
+ | `activate(task_name)` | Enable optional task |
87
+
88
+ ## Tool
89
+
90
+ **Tools** are functions that robots can call to interact with external systems:
91
+
92
+ ```ruby
93
+ tool = RobotLab::Tool.new(
94
+ name: "get_weather",
95
+ description: "Get current weather for a location",
96
+ parameters: {
97
+ location: { type: "string", description: "City name" }
98
+ },
99
+ handler: ->(location:, **_context) {
100
+ WeatherService.current(location)
101
+ }
102
+ )
103
+ ```
104
+
105
+ ## Message Types
106
+
107
+ RobotLab uses several message types to represent conversation content:
108
+
109
+ | Type | Purpose |
110
+ |------|---------|
111
+ | `TextMessage` | User or assistant text content |
112
+ | `ToolMessage` | Tool definition with name and parameters |
113
+ | `ToolCallMessage` | Request from LLM to execute a tool |
114
+ | `ToolResultMessage` | Result returned from tool execution |
115
+
116
+ ## Memory
117
+
118
+ **Memory** provides persistent storage across robot executions:
119
+
120
+ ```ruby
121
+ # Robot with inherent memory
122
+ robot = RobotLab.build(name: "assistant", system_prompt: "You are helpful.")
123
+ robot.run(message: "My name is Alice")
124
+ robot.run(message: "What's my name?") # Memory persists
125
+
126
+ # Access robot's memory
127
+ robot.memory[:user_id] = 123
128
+ robot.memory.data[:category] = "billing"
129
+
130
+ # Runtime memory injection
131
+ robot.run(message: "Help me", memory: { session_id: "abc123" })
132
+
133
+ # Reset memory
134
+ robot.reset_memory
135
+ ```
136
+
137
+ ## MCP (Model Context Protocol)
138
+
139
+ **MCP** allows robots to connect to external tool servers:
140
+
141
+ ```ruby
142
+ robot = RobotLab.build(
143
+ name: "developer",
144
+ mcp: [
145
+ { name: "filesystem", transport: { type: "stdio", command: "mcp-server-filesystem" } },
146
+ { name: "github", transport: { type: "stdio", command: "mcp-server-github" } }
147
+ ]
148
+ )
149
+ ```
150
+
151
+ ## Execution Flow
152
+
153
+ ```mermaid
154
+ sequenceDiagram
155
+ participant User
156
+ participant Network
157
+ participant Pipeline
158
+ participant Task
159
+ participant Robot
160
+ participant LLM
161
+ participant Tool
162
+
163
+ User->>Network: run(message, context)
164
+ Network->>Pipeline: call(initial_result)
165
+ Pipeline->>Task: call(result)
166
+ Task->>Robot: call(enhanced_result)
167
+ Robot->>LLM: inference(messages, tools)
168
+
169
+ alt Tool Call
170
+ LLM-->>Robot: tool_call
171
+ Robot->>Tool: execute(params)
172
+ Tool-->>Robot: result
173
+ Robot->>LLM: continue with result
174
+ end
175
+
176
+ LLM-->>Robot: response
177
+ Robot-->>Task: RobotResult
178
+ Task-->>Pipeline: result.continue(value)
179
+
180
+ alt Optional Task Activated
181
+ Pipeline->>Task: call activated task
182
+ end
183
+
184
+ Pipeline-->>Network: final result
185
+ Network-->>User: SimpleFlow::Result
186
+ ```
187
+
188
+ ## Conditional Routing
189
+
190
+ Use custom Robot subclasses to implement intelligent routing:
191
+
192
+ ```ruby
193
+ class ClassifierRobot < RobotLab::Robot
194
+ def call(result)
195
+ robot_result = run(**extract_run_context(result))
196
+
197
+ new_result = result
198
+ .with_context(@name.to_sym, robot_result)
199
+ .continue(robot_result)
200
+
201
+ # Activate appropriate specialist
202
+ category = robot_result.last_text_content.to_s.downcase
203
+ case category
204
+ when /billing/ then new_result.activate(:billing)
205
+ when /technical/ then new_result.activate(:technical)
206
+ else new_result.activate(:general)
207
+ end
208
+ end
209
+ end
210
+ ```
211
+
212
+ ## Next Steps
213
+
214
+ - [Quick Start Guide](getting-started/quick-start.md) - Build your first robot
215
+ - [Building Robots](guides/building-robots.md) - Detailed robot creation guide
216
+ - [Creating Networks](guides/creating-networks.md) - Network orchestration patterns