robot_lab 0.0.1 → 0.0.6
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.
- checksums.yaml +4 -4
- data/.github/workflows/deploy-github-pages.yml +9 -9
- data/.irbrc +6 -0
- data/CHANGELOG.md +140 -0
- data/README.md +263 -48
- data/Rakefile +71 -1
- data/docs/api/core/index.md +53 -46
- data/docs/api/core/memory.md +200 -154
- data/docs/api/core/network.md +13 -3
- data/docs/api/core/robot.md +490 -130
- data/docs/api/core/state.md +55 -73
- data/docs/api/core/tool.md +205 -209
- data/docs/api/index.md +7 -28
- data/docs/api/mcp/client.md +119 -48
- data/docs/api/mcp/index.md +75 -60
- data/docs/api/mcp/server.md +120 -136
- data/docs/api/mcp/transports.md +172 -184
- data/docs/api/messages/index.md +35 -20
- data/docs/api/messages/text-message.md +67 -21
- data/docs/api/messages/tool-call-message.md +80 -41
- data/docs/api/messages/tool-result-message.md +119 -50
- data/docs/api/messages/user-message.md +48 -24
- data/docs/api/streaming/context.md +157 -74
- data/docs/api/streaming/events.md +114 -166
- data/docs/api/streaming/index.md +74 -72
- data/docs/architecture/core-concepts.md +360 -116
- data/docs/architecture/index.md +97 -59
- data/docs/architecture/message-flow.md +138 -129
- data/docs/architecture/network-orchestration.md +197 -50
- data/docs/architecture/robot-execution.md +199 -146
- data/docs/architecture/state-management.md +255 -187
- data/docs/concepts.md +311 -49
- data/docs/examples/basic-chat.md +89 -77
- data/docs/examples/index.md +222 -47
- data/docs/examples/mcp-server.md +207 -203
- data/docs/examples/multi-robot-network.md +129 -35
- data/docs/examples/rails-application.md +159 -160
- data/docs/examples/tool-usage.md +295 -204
- data/docs/getting-started/configuration.md +347 -154
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/installation.md +22 -13
- data/docs/getting-started/quick-start.md +166 -121
- data/docs/guides/building-robots.md +418 -212
- data/docs/guides/creating-networks.md +143 -24
- data/docs/guides/index.md +0 -5
- data/docs/guides/mcp-integration.md +152 -113
- data/docs/guides/memory.md +220 -164
- data/docs/guides/rails-integration.md +244 -162
- data/docs/guides/streaming.md +137 -187
- data/docs/guides/using-tools.md +259 -212
- data/docs/index.md +46 -41
- data/examples/01_simple_robot.rb +6 -9
- data/examples/02_tools.rb +6 -9
- data/examples/03_network.rb +19 -17
- data/examples/04_mcp.rb +5 -8
- data/examples/05_streaming.rb +5 -8
- data/examples/06_prompt_templates.rb +42 -37
- data/examples/07_network_memory.rb +13 -14
- data/examples/08_llm_config.rb +169 -0
- data/examples/09_chaining.rb +262 -0
- data/examples/10_memory.rb +331 -0
- data/examples/11_network_introspection.rb +253 -0
- data/examples/12_message_bus.rb +74 -0
- data/examples/13_spawn.rb +90 -0
- data/examples/14_rusty_circuit/comic.rb +143 -0
- data/examples/14_rusty_circuit/display.rb +203 -0
- data/examples/14_rusty_circuit/heckler.rb +63 -0
- data/examples/14_rusty_circuit/open_mic.rb +123 -0
- data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
- data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
- data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
- data/examples/14_rusty_circuit/scout.rb +156 -0
- data/examples/14_rusty_circuit/scout_notes.md +89 -0
- data/examples/14_rusty_circuit/show.log +234 -0
- data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
- data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
- data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
- data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
- data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
- data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
- data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
- data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
- data/examples/15_memory_network_and_bus/output/memory.json +13 -0
- data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
- data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
- data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
- data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
- data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
- data/examples/16_writers_room/display.rb +158 -0
- data/examples/16_writers_room/output/.gitignore +2 -0
- data/examples/16_writers_room/output/opus_001.md +263 -0
- data/examples/16_writers_room/output/opus_001_notes.log +470 -0
- data/examples/16_writers_room/prompts/writer.md +37 -0
- data/examples/16_writers_room/room.rb +150 -0
- data/examples/16_writers_room/tools.rb +162 -0
- data/examples/16_writers_room/writer.rb +121 -0
- data/examples/16_writers_room/writers_room.rb +162 -0
- data/examples/README.md +197 -0
- data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
- data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
- data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
- data/examples/prompts/comedian.md +6 -0
- data/examples/prompts/comedy_critic.md +10 -0
- data/examples/prompts/configurable.md +9 -0
- data/examples/prompts/dispatcher.md +12 -0
- data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
- data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
- data/examples/prompts/frontmatter_mcp_test.md +9 -0
- data/examples/prompts/frontmatter_named_test.md +5 -0
- data/examples/prompts/frontmatter_tools_test.md +6 -0
- data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
- data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
- data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
- data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
- data/examples/prompts/llm_config_demo.md +20 -0
- data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
- data/examples/prompts/os_advocate.md +13 -0
- data/examples/prompts/os_chief.md +13 -0
- data/examples/prompts/os_editor.md +13 -0
- data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
- data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
- data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
- data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
- data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
- data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
- data/lib/robot_lab/ask_user.rb +75 -0
- data/lib/robot_lab/config/defaults.yml +121 -0
- data/lib/robot_lab/config.rb +183 -0
- data/lib/robot_lab/error.rb +6 -0
- data/lib/robot_lab/mcp/client.rb +1 -1
- data/lib/robot_lab/memory.rb +10 -34
- data/lib/robot_lab/network.rb +13 -20
- data/lib/robot_lab/robot/bus_messaging.rb +239 -0
- data/lib/robot_lab/robot/mcp_management.rb +88 -0
- data/lib/robot_lab/robot/template_rendering.rb +130 -0
- data/lib/robot_lab/robot.rb +240 -330
- data/lib/robot_lab/robot_message.rb +44 -0
- data/lib/robot_lab/robot_result.rb +1 -0
- data/lib/robot_lab/run_config.rb +184 -0
- data/lib/robot_lab/state_proxy.rb +2 -12
- data/lib/robot_lab/streaming/context.rb +1 -1
- data/lib/robot_lab/task.rb +8 -1
- data/lib/robot_lab/tool.rb +108 -172
- data/lib/robot_lab/tool_config.rb +1 -1
- data/lib/robot_lab/tool_manifest.rb +2 -18
- data/lib/robot_lab/utils.rb +39 -0
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +89 -57
- data/mkdocs.yml +0 -11
- metadata +121 -135
- data/docs/api/adapters/anthropic.md +0 -121
- data/docs/api/adapters/gemini.md +0 -133
- data/docs/api/adapters/index.md +0 -104
- data/docs/api/adapters/openai.md +0 -134
- data/docs/api/history/active-record-adapter.md +0 -195
- data/docs/api/history/config.md +0 -191
- data/docs/api/history/index.md +0 -132
- data/docs/api/history/thread-manager.md +0 -144
- data/docs/guides/history.md +0 -359
- data/examples/prompts/assistant/user.txt.erb +0 -1
- data/examples/prompts/billing/user.txt.erb +0 -1
- data/examples/prompts/classifier/user.txt.erb +0 -1
- data/examples/prompts/entity_extractor/user.txt.erb +0 -3
- data/examples/prompts/escalation/user.txt.erb +0 -34
- data/examples/prompts/general/user.txt.erb +0 -1
- data/examples/prompts/github_assistant/user.txt.erb +0 -1
- data/examples/prompts/helper/user.txt.erb +0 -1
- data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
- data/examples/prompts/order_support/user.txt.erb +0 -22
- data/examples/prompts/product_support/user.txt.erb +0 -32
- data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
- data/examples/prompts/synthesizer/user.txt.erb +0 -15
- data/examples/prompts/technical/user.txt.erb +0 -1
- data/examples/prompts/triage/user.txt.erb +0 -17
- data/lib/robot_lab/adapters/anthropic.rb +0 -163
- data/lib/robot_lab/adapters/base.rb +0 -85
- data/lib/robot_lab/adapters/gemini.rb +0 -193
- data/lib/robot_lab/adapters/openai.rb +0 -159
- data/lib/robot_lab/adapters/registry.rb +0 -81
- data/lib/robot_lab/configuration.rb +0 -143
- data/lib/robot_lab/errors.rb +0 -70
- data/lib/robot_lab/history/active_record_adapter.rb +0 -146
- data/lib/robot_lab/history/config.rb +0 -115
- data/lib/robot_lab/history/thread_manager.rb +0 -93
- data/lib/robot_lab/robotic_model.rb +0 -324
|
@@ -6,20 +6,35 @@ Tool invocation request from the LLM.
|
|
|
6
6
|
|
|
7
7
|
```ruby
|
|
8
8
|
message = ToolCallMessage.new(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
role: "assistant",
|
|
10
|
+
tools: [
|
|
11
|
+
ToolMessage.new(id: "call_abc123", name: "get_weather", input: { city: "New York" })
|
|
12
|
+
]
|
|
12
13
|
)
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
## Constructor
|
|
16
17
|
|
|
17
18
|
```ruby
|
|
18
|
-
ToolCallMessage.new(
|
|
19
|
+
ToolCallMessage.new(role:, tools:, stop_reason: nil)
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
**Parameters:**
|
|
22
23
|
|
|
24
|
+
| Name | Type | Description |
|
|
25
|
+
|------|------|-------------|
|
|
26
|
+
| `role` | `String` | Message role (typically "assistant") |
|
|
27
|
+
| `tools` | `Array<ToolMessage>` | Array of tool call objects |
|
|
28
|
+
| `stop_reason` | `String`, `nil` | Stop reason (defaults to "tool") |
|
|
29
|
+
|
|
30
|
+
## ToolMessage
|
|
31
|
+
|
|
32
|
+
Each tool call is represented by a standalone `ToolMessage` object:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
ToolMessage.new(id:, name:, input:)
|
|
36
|
+
```
|
|
37
|
+
|
|
23
38
|
| Name | Type | Description |
|
|
24
39
|
|------|------|-------------|
|
|
25
40
|
| `id` | `String` | Unique call identifier |
|
|
@@ -28,37 +43,45 @@ ToolCallMessage.new(id:, name:, input:)
|
|
|
28
43
|
|
|
29
44
|
## Attributes
|
|
30
45
|
|
|
31
|
-
###
|
|
46
|
+
### tools
|
|
32
47
|
|
|
33
48
|
```ruby
|
|
34
|
-
message.
|
|
49
|
+
message.tools # => Array<ToolMessage>
|
|
35
50
|
```
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
Array of `ToolMessage` objects representing the tool calls.
|
|
38
53
|
|
|
39
|
-
###
|
|
54
|
+
### role
|
|
40
55
|
|
|
41
56
|
```ruby
|
|
42
|
-
message.
|
|
57
|
+
message.role # => "assistant"
|
|
43
58
|
```
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
Returns a String. The LLM initiates tool calls, so this is typically `"assistant"`.
|
|
46
61
|
|
|
47
|
-
###
|
|
62
|
+
### type
|
|
48
63
|
|
|
49
64
|
```ruby
|
|
50
|
-
message.
|
|
65
|
+
message.type # => "tool_call"
|
|
51
66
|
```
|
|
52
67
|
|
|
53
|
-
|
|
68
|
+
Always returns `"tool_call"`.
|
|
54
69
|
|
|
55
|
-
###
|
|
70
|
+
### content
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
message.content # => nil
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Always `nil` for tool call messages (the tool data is in `tools`).
|
|
77
|
+
|
|
78
|
+
### stop_reason
|
|
56
79
|
|
|
57
80
|
```ruby
|
|
58
|
-
message.
|
|
81
|
+
message.stop_reason # => "tool"
|
|
59
82
|
```
|
|
60
83
|
|
|
61
|
-
|
|
84
|
+
Defaults to `"tool"` indicating the conversation stopped for tool execution.
|
|
62
85
|
|
|
63
86
|
## Methods
|
|
64
87
|
|
|
@@ -74,12 +97,12 @@ Hash representation.
|
|
|
74
97
|
|
|
75
98
|
```ruby
|
|
76
99
|
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
name: "get_weather",
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
type: "tool_call",
|
|
101
|
+
role: "assistant",
|
|
102
|
+
tools: [
|
|
103
|
+
{ type: "tool", id: "call_abc123", name: "get_weather", input: { city: "New York" } }
|
|
104
|
+
],
|
|
105
|
+
stop_reason: "tool"
|
|
83
106
|
}
|
|
84
107
|
```
|
|
85
108
|
|
|
@@ -91,28 +114,48 @@ message.to_json # => String
|
|
|
91
114
|
|
|
92
115
|
JSON representation.
|
|
93
116
|
|
|
117
|
+
### Predicates
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
message.tool_call? # => true
|
|
121
|
+
message.text? # => false
|
|
122
|
+
message.assistant? # => true
|
|
123
|
+
message.tool_stop? # => true
|
|
124
|
+
```
|
|
125
|
+
|
|
94
126
|
## Examples
|
|
95
127
|
|
|
96
|
-
###
|
|
128
|
+
### Single Tool Call
|
|
97
129
|
|
|
98
130
|
```ruby
|
|
99
|
-
|
|
131
|
+
tool = ToolMessage.new(
|
|
100
132
|
id: "call_1",
|
|
101
133
|
name: "search_orders",
|
|
102
134
|
input: { user_id: "123", status: "pending" }
|
|
103
135
|
)
|
|
136
|
+
|
|
137
|
+
call = ToolCallMessage.new(role: "assistant", tools: [tool])
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Multiple Tool Calls
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
tools = [
|
|
144
|
+
ToolMessage.new(id: "call_1", name: "get_weather", input: { city: "NYC" }),
|
|
145
|
+
ToolMessage.new(id: "call_2", name: "get_time", input: { timezone: "EST" })
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
call = ToolCallMessage.new(role: "assistant", tools: tools)
|
|
149
|
+
call.tools.length # => 2
|
|
104
150
|
```
|
|
105
151
|
|
|
106
152
|
### Processing Tool Calls
|
|
107
153
|
|
|
108
154
|
```ruby
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
puts "
|
|
113
|
-
puts "Parameters: #{msg.input.inspect}"
|
|
114
|
-
when ToolResultMessage
|
|
115
|
-
puts "Result for #{msg.id}: #{msg.result}"
|
|
155
|
+
if message.tool_call?
|
|
156
|
+
message.tools.each do |tool|
|
|
157
|
+
puts "Tool called: #{tool.name}"
|
|
158
|
+
puts "Parameters: #{tool.input.inspect}"
|
|
116
159
|
end
|
|
117
160
|
end
|
|
118
161
|
```
|
|
@@ -121,19 +164,15 @@ end
|
|
|
121
164
|
|
|
122
165
|
```ruby
|
|
123
166
|
# LLM returns a tool call
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
name: "get_weather",
|
|
127
|
-
input: { city: "Seattle" }
|
|
128
|
-
)
|
|
167
|
+
tool = ToolMessage.new(id: "call_weather_1", name: "get_weather", input: { city: "Seattle" })
|
|
168
|
+
tool_call = ToolCallMessage.new(role: "assistant", tools: [tool])
|
|
129
169
|
|
|
130
|
-
#
|
|
131
|
-
|
|
170
|
+
# Execute the tool and record the result
|
|
171
|
+
result_data = execute_tool(tool.name, tool.input)
|
|
132
172
|
|
|
133
|
-
# Result is recorded
|
|
134
173
|
tool_result = ToolResultMessage.new(
|
|
135
|
-
|
|
136
|
-
|
|
174
|
+
tool: tool,
|
|
175
|
+
content: { data: result_data }
|
|
137
176
|
)
|
|
138
177
|
```
|
|
139
178
|
|
|
@@ -5,53 +5,104 @@ Result from tool execution.
|
|
|
5
5
|
## Class: `RobotLab::ToolResultMessage`
|
|
6
6
|
|
|
7
7
|
```ruby
|
|
8
|
+
tool = ToolMessage.new(id: "call_abc123", name: "get_weather", input: { city: "NYC" })
|
|
9
|
+
|
|
8
10
|
message = ToolResultMessage.new(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
tool: tool,
|
|
12
|
+
content: { data: { temperature: 72, conditions: "sunny" } }
|
|
11
13
|
)
|
|
12
14
|
```
|
|
13
15
|
|
|
14
16
|
## Constructor
|
|
15
17
|
|
|
16
18
|
```ruby
|
|
17
|
-
ToolResultMessage.new(
|
|
19
|
+
ToolResultMessage.new(tool:, content:, stop_reason: nil)
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
**Parameters:**
|
|
21
23
|
|
|
22
24
|
| Name | Type | Description |
|
|
23
25
|
|------|------|-------------|
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
+
| `tool` | `ToolMessage` | The tool call that was executed |
|
|
27
|
+
| `content` | `Hash` | Result with `:data` key (success) or `:error` key (failure) |
|
|
28
|
+
| `stop_reason` | `String`, `nil` | Stop reason (defaults to "tool") |
|
|
26
29
|
|
|
27
30
|
## Attributes
|
|
28
31
|
|
|
29
|
-
###
|
|
32
|
+
### tool
|
|
30
33
|
|
|
31
34
|
```ruby
|
|
32
|
-
message.
|
|
35
|
+
message.tool # => ToolMessage
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
The `ToolMessage` representing the tool call that produced this result. Provides access to `tool.id`, `tool.name`, and `tool.input`.
|
|
36
39
|
|
|
37
|
-
###
|
|
40
|
+
### content
|
|
38
41
|
|
|
39
42
|
```ruby
|
|
40
|
-
message.
|
|
43
|
+
message.content # => Hash
|
|
41
44
|
```
|
|
42
45
|
|
|
43
|
-
The result
|
|
46
|
+
The result content. Contains either a `:data` key (success) or an `:error` key (failure).
|
|
44
47
|
|
|
45
48
|
### role
|
|
46
49
|
|
|
47
50
|
```ruby
|
|
48
|
-
message.role # =>
|
|
51
|
+
message.role # => "tool_result"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Always returns `"tool_result"`.
|
|
55
|
+
|
|
56
|
+
### type
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
message.type # => "tool_result"
|
|
49
60
|
```
|
|
50
61
|
|
|
51
|
-
Always returns
|
|
62
|
+
Always returns `"tool_result"`.
|
|
63
|
+
|
|
64
|
+
### stop_reason
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
message.stop_reason # => "tool"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Defaults to `"tool"`.
|
|
52
71
|
|
|
53
72
|
## Methods
|
|
54
73
|
|
|
74
|
+
### success?
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
message.success? # => Boolean
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Returns `true` if the content contains a `:data` key.
|
|
81
|
+
|
|
82
|
+
### error?
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
message.error? # => Boolean
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Returns `true` if the content contains an `:error` key.
|
|
89
|
+
|
|
90
|
+
### data
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
message.data # => Object | nil
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Returns the result data if successful, `nil` otherwise.
|
|
97
|
+
|
|
98
|
+
### error
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
message.error # => String | nil
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Returns the error message if there was an error, `nil` otherwise.
|
|
105
|
+
|
|
55
106
|
### to_h
|
|
56
107
|
|
|
57
108
|
```ruby
|
|
@@ -64,11 +115,11 @@ Hash representation.
|
|
|
64
115
|
|
|
65
116
|
```ruby
|
|
66
117
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
118
|
+
type: "tool_result",
|
|
119
|
+
role: "tool_result",
|
|
120
|
+
tool: { type: "tool", id: "call_abc123", name: "get_weather", input: { city: "NYC" } },
|
|
121
|
+
content: { data: { temperature: 72, conditions: "sunny" } },
|
|
122
|
+
stop_reason: "tool"
|
|
72
123
|
}
|
|
73
124
|
```
|
|
74
125
|
|
|
@@ -80,70 +131,88 @@ message.to_json # => String
|
|
|
80
131
|
|
|
81
132
|
JSON representation.
|
|
82
133
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
### Basic Result
|
|
134
|
+
### Predicates
|
|
86
135
|
|
|
87
136
|
```ruby
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
137
|
+
message.tool_result? # => true
|
|
138
|
+
message.tool_call? # => false
|
|
139
|
+
message.text? # => false
|
|
140
|
+
message.tool_stop? # => true
|
|
92
141
|
```
|
|
93
142
|
|
|
94
|
-
|
|
143
|
+
## Examples
|
|
144
|
+
|
|
145
|
+
### Successful Result
|
|
95
146
|
|
|
96
147
|
```ruby
|
|
148
|
+
tool = ToolMessage.new(id: "call_1", name: "search_orders", input: { user_id: "123" })
|
|
149
|
+
|
|
97
150
|
result = ToolResultMessage.new(
|
|
98
|
-
|
|
99
|
-
|
|
151
|
+
tool: tool,
|
|
152
|
+
content: { data: { order_id: "ord_123", status: "shipped" } }
|
|
100
153
|
)
|
|
154
|
+
|
|
155
|
+
result.success? # => true
|
|
156
|
+
result.data # => { order_id: "ord_123", status: "shipped" }
|
|
101
157
|
```
|
|
102
158
|
|
|
103
|
-
###
|
|
159
|
+
### Error Result
|
|
104
160
|
|
|
105
161
|
```ruby
|
|
162
|
+
tool = ToolMessage.new(id: "call_order", name: "get_order", input: { id: "bad" })
|
|
163
|
+
|
|
106
164
|
result = ToolResultMessage.new(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{ id: 1, name: "Product A" },
|
|
110
|
-
{ id: 2, name: "Product B" }
|
|
111
|
-
]
|
|
165
|
+
tool: tool,
|
|
166
|
+
content: { error: "Order not found" }
|
|
112
167
|
)
|
|
168
|
+
|
|
169
|
+
result.error? # => true
|
|
170
|
+
result.error # => "Order not found"
|
|
171
|
+
result.data # => nil
|
|
113
172
|
```
|
|
114
173
|
|
|
115
|
-
###
|
|
174
|
+
### Accessing Tool Information
|
|
116
175
|
|
|
117
176
|
```ruby
|
|
118
177
|
result = ToolResultMessage.new(
|
|
119
|
-
id: "
|
|
120
|
-
|
|
178
|
+
tool: ToolMessage.new(id: "call_1", name: "get_weather", input: { city: "Berlin" }),
|
|
179
|
+
content: { data: { temperature: 15, unit: "celsius" } }
|
|
121
180
|
)
|
|
181
|
+
|
|
182
|
+
result.tool.name # => "get_weather"
|
|
183
|
+
result.tool.id # => "call_1"
|
|
184
|
+
result.tool.input # => { city: "Berlin" }
|
|
185
|
+
result.data # => { temperature: 15, unit: "celsius" }
|
|
122
186
|
```
|
|
123
187
|
|
|
124
|
-
### Matching
|
|
188
|
+
### Matching Tool Calls with Results
|
|
125
189
|
|
|
126
190
|
```ruby
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
191
|
+
# Given a ToolCallMessage and its results
|
|
192
|
+
tool_call_msg.tools.each do |tool|
|
|
193
|
+
# Find the matching result
|
|
194
|
+
matching_result = results.find { |r| r.tool.id == tool.id }
|
|
195
|
+
|
|
196
|
+
if matching_result&.success?
|
|
197
|
+
puts "#{tool.name}(#{tool.input}) => #{matching_result.data}"
|
|
198
|
+
elsif matching_result&.error?
|
|
199
|
+
puts "#{tool.name} failed: #{matching_result.error}"
|
|
133
200
|
end
|
|
134
201
|
end
|
|
135
202
|
```
|
|
136
203
|
|
|
137
|
-
### In
|
|
204
|
+
### In Memory History
|
|
138
205
|
|
|
139
206
|
```ruby
|
|
140
|
-
# Find all tool results from
|
|
141
|
-
tool_results =
|
|
142
|
-
.flat_map(&:output)
|
|
143
|
-
.select { |m| m.is_a?(ToolResultMessage) }
|
|
207
|
+
# Find all tool results from memory
|
|
208
|
+
tool_results = memory.messages.select(&:tool_result?)
|
|
144
209
|
|
|
145
210
|
tool_results.each do |tr|
|
|
146
|
-
|
|
211
|
+
if tr.success?
|
|
212
|
+
puts "#{tr.tool.name}: #{tr.data}"
|
|
213
|
+
else
|
|
214
|
+
puts "#{tr.tool.name} error: #{tr.error}"
|
|
215
|
+
end
|
|
147
216
|
end
|
|
148
217
|
```
|
|
149
218
|
|
|
@@ -7,16 +7,18 @@ User input with conversation metadata.
|
|
|
7
7
|
```ruby
|
|
8
8
|
message = UserMessage.new(
|
|
9
9
|
"What's my order status?",
|
|
10
|
-
|
|
10
|
+
session_id: "session_123",
|
|
11
11
|
system_prompt: "Be concise",
|
|
12
12
|
metadata: { source: "web" }
|
|
13
13
|
)
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
**Note:** `UserMessage` is a standalone class, not a subclass of `Message`.
|
|
17
|
+
|
|
16
18
|
## Constructor
|
|
17
19
|
|
|
18
20
|
```ruby
|
|
19
|
-
UserMessage.new(content,
|
|
21
|
+
UserMessage.new(content, session_id: nil, system_prompt: nil, metadata: nil, id: nil)
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
**Parameters:**
|
|
@@ -24,9 +26,10 @@ UserMessage.new(content, thread_id: nil, system_prompt: nil, metadata: {})
|
|
|
24
26
|
| Name | Type | Description |
|
|
25
27
|
|------|------|-------------|
|
|
26
28
|
| `content` | `String` | Message text |
|
|
27
|
-
| `
|
|
29
|
+
| `session_id` | `String`, `nil` | Conversation session ID |
|
|
28
30
|
| `system_prompt` | `String`, `nil` | Override system prompt |
|
|
29
|
-
| `metadata` | `Hash` | Additional metadata |
|
|
31
|
+
| `metadata` | `Hash`, `nil` | Additional metadata |
|
|
32
|
+
| `id` | `String`, `nil` | Unique message ID (defaults to UUID) |
|
|
30
33
|
|
|
31
34
|
## Attributes
|
|
32
35
|
|
|
@@ -38,13 +41,13 @@ message.content # => String
|
|
|
38
41
|
|
|
39
42
|
The message text.
|
|
40
43
|
|
|
41
|
-
###
|
|
44
|
+
### session_id
|
|
42
45
|
|
|
43
46
|
```ruby
|
|
44
|
-
message.
|
|
47
|
+
message.session_id # => String | nil
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
Conversation
|
|
50
|
+
Conversation session identifier for history persistence.
|
|
48
51
|
|
|
49
52
|
### system_prompt
|
|
50
53
|
|
|
@@ -78,14 +81,6 @@ message.created_at # => Time
|
|
|
78
81
|
|
|
79
82
|
Message creation timestamp.
|
|
80
83
|
|
|
81
|
-
### role
|
|
82
|
-
|
|
83
|
-
```ruby
|
|
84
|
-
message.role # => :user
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Always returns `:user`.
|
|
88
|
-
|
|
89
84
|
## Methods
|
|
90
85
|
|
|
91
86
|
### to_h
|
|
@@ -100,10 +95,11 @@ Hash representation.
|
|
|
100
95
|
|
|
101
96
|
```ruby
|
|
102
97
|
{
|
|
103
|
-
role: :user,
|
|
104
98
|
content: "What's my order status?",
|
|
99
|
+
session_id: "session_123",
|
|
100
|
+
system_prompt: "Be concise",
|
|
101
|
+
metadata: { source: "web" },
|
|
105
102
|
id: "uuid-here",
|
|
106
|
-
thread_id: "thread_123",
|
|
107
103
|
created_at: "2024-01-15T10:30:00Z"
|
|
108
104
|
}
|
|
109
105
|
```
|
|
@@ -116,6 +112,30 @@ message.to_json # => String
|
|
|
116
112
|
|
|
117
113
|
JSON representation.
|
|
118
114
|
|
|
115
|
+
### to_message
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
message.to_message # => TextMessage
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Converts to a `TextMessage` with role `"user"` for use in conversation history.
|
|
122
|
+
|
|
123
|
+
### to_s
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
message.to_s # => String
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Returns the content string.
|
|
130
|
+
|
|
131
|
+
### self.from
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
UserMessage.from(input) # => UserMessage
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Creates a `UserMessage` from a String, Hash, or existing `UserMessage`.
|
|
138
|
+
|
|
119
139
|
## Examples
|
|
120
140
|
|
|
121
141
|
### Basic Message
|
|
@@ -124,12 +144,12 @@ JSON representation.
|
|
|
124
144
|
message = UserMessage.new("Hello!")
|
|
125
145
|
```
|
|
126
146
|
|
|
127
|
-
### With
|
|
147
|
+
### With Session ID
|
|
128
148
|
|
|
129
149
|
```ruby
|
|
130
150
|
message = UserMessage.new(
|
|
131
151
|
"Continue our conversation",
|
|
132
|
-
|
|
152
|
+
session_id: "session_abc123"
|
|
133
153
|
)
|
|
134
154
|
```
|
|
135
155
|
|
|
@@ -156,16 +176,20 @@ message = UserMessage.new(
|
|
|
156
176
|
)
|
|
157
177
|
```
|
|
158
178
|
|
|
159
|
-
### Creating
|
|
179
|
+
### Creating from Various Inputs
|
|
160
180
|
|
|
161
181
|
```ruby
|
|
162
|
-
|
|
163
|
-
|
|
182
|
+
# From a string
|
|
183
|
+
msg = UserMessage.from("Hello!")
|
|
184
|
+
|
|
185
|
+
# From a hash
|
|
186
|
+
msg = UserMessage.from(content: "Hello!", session_id: "123")
|
|
164
187
|
|
|
165
|
-
|
|
188
|
+
# From an existing UserMessage (returns as-is)
|
|
189
|
+
msg = UserMessage.from(existing_message)
|
|
166
190
|
```
|
|
167
191
|
|
|
168
192
|
## See Also
|
|
169
193
|
|
|
170
|
-
- [
|
|
194
|
+
- [Memory](../core/memory.md)
|
|
171
195
|
- [TextMessage](text-message.md)
|