robot_lab 0.0.1 → 0.0.4
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 +90 -0
- data/README.md +203 -46
- data/Rakefile +70 -1
- data/docs/api/core/index.md +12 -0
- data/docs/api/core/robot.md +478 -130
- data/docs/api/core/tool.md +205 -209
- data/docs/api/history/active-record-adapter.md +174 -94
- data/docs/api/history/config.md +186 -93
- data/docs/api/history/index.md +57 -61
- data/docs/api/history/thread-manager.md +123 -73
- 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/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 +361 -112
- 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 +312 -48
- 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 +275 -162
- 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 +417 -212
- data/docs/guides/creating-networks.md +94 -24
- data/docs/guides/mcp-integration.md +152 -113
- data/docs/guides/memory.md +220 -164
- data/docs/guides/streaming.md +80 -110
- data/docs/guides/using-tools.md +259 -212
- data/docs/index.md +50 -37
- data/examples/01_simple_robot.rb +6 -9
- data/examples/02_tools.rb +6 -9
- data/examples/03_network.rb +13 -14
- 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 +140 -0
- data/examples/09_chaining.rb +223 -0
- data/examples/10_memory.rb +331 -0
- data/examples/11_network_introspection.rb +230 -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 +57 -0
- data/examples/14_rusty_circuit/open_mic.rb +121 -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 +173 -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/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 +1 -1
- data/lib/robot_lab/adapters/openai.rb +2 -1
- 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 +2 -2
- data/lib/robot_lab/robot.rb +523 -249
- data/lib/robot_lab/robot_message.rb +44 -0
- data/lib/robot_lab/robot_result.rb +1 -0
- data/lib/robot_lab/robotic_model.rb +1 -1
- data/lib/robot_lab/streaming/context.rb +1 -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/version.rb +1 -1
- data/lib/robot_lab.rb +66 -55
- metadata +107 -116
- 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/configuration.rb +0 -143
|
@@ -1,139 +1,189 @@
|
|
|
1
|
-
# ThreadManager
|
|
1
|
+
# History::ThreadManager
|
|
2
2
|
|
|
3
|
-
Manages conversation thread lifecycle.
|
|
3
|
+
Manages conversation thread lifecycle using a `History::Config` for persistence.
|
|
4
4
|
|
|
5
5
|
## Class: `RobotLab::History::ThreadManager`
|
|
6
6
|
|
|
7
7
|
```ruby
|
|
8
|
-
|
|
8
|
+
config = RobotLab::History::Config.new(...)
|
|
9
|
+
manager = RobotLab::History::ThreadManager.new(config)
|
|
10
|
+
|
|
11
|
+
session_id = manager.create_thread(state: memory, input: "Hello")
|
|
12
|
+
history = manager.get_history(session_id)
|
|
9
13
|
```
|
|
10
14
|
|
|
11
15
|
## Constructor
|
|
12
16
|
|
|
13
17
|
```ruby
|
|
14
|
-
ThreadManager.new(config
|
|
18
|
+
ThreadManager.new(config)
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
**Parameters:**
|
|
18
22
|
|
|
19
23
|
| Name | Type | Description |
|
|
20
24
|
|------|------|-------------|
|
|
21
|
-
| `config` | `Config` | History configuration |
|
|
25
|
+
| `config` | `Config` | History configuration with persistence callbacks |
|
|
26
|
+
|
|
27
|
+
## Attributes
|
|
28
|
+
|
|
29
|
+
### config
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
manager.config # => RobotLab::History::Config
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The history configuration object.
|
|
22
36
|
|
|
23
37
|
## Methods
|
|
24
38
|
|
|
25
39
|
### create_thread
|
|
26
40
|
|
|
27
41
|
```ruby
|
|
28
|
-
|
|
42
|
+
session_id = manager.create_thread(state:, input:)
|
|
29
43
|
```
|
|
30
44
|
|
|
31
|
-
Create a new conversation thread.
|
|
45
|
+
Create a new conversation thread. Delegates to `config.create_thread!` and returns the `session_id` from the result hash.
|
|
32
46
|
|
|
33
|
-
**
|
|
47
|
+
**Parameters:**
|
|
48
|
+
|
|
49
|
+
| Name | Type | Description |
|
|
50
|
+
|------|------|-------------|
|
|
51
|
+
| `state` | `Object` | Current robot memory or state |
|
|
52
|
+
| `input` | `String`, `UserMessage` | Initial user input |
|
|
53
|
+
|
|
54
|
+
**Returns:** `String` -- the session ID for the new thread.
|
|
34
55
|
|
|
35
56
|
### get_history
|
|
36
57
|
|
|
37
58
|
```ruby
|
|
38
|
-
results = manager.get_history(
|
|
59
|
+
results = manager.get_history(session_id)
|
|
39
60
|
```
|
|
40
61
|
|
|
41
|
-
Retrieve conversation history.
|
|
62
|
+
Retrieve conversation history for a thread. Delegates to `config.get!`.
|
|
63
|
+
|
|
64
|
+
**Parameters:**
|
|
42
65
|
|
|
43
|
-
|
|
66
|
+
| Name | Type | Description |
|
|
67
|
+
|------|------|-------------|
|
|
68
|
+
| `session_id` | `String` | Thread identifier |
|
|
69
|
+
|
|
70
|
+
**Returns:** `Array<RobotResult>` -- history of results for the thread.
|
|
71
|
+
|
|
72
|
+
### append_user_message
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
manager.append_user_message(session_id:, message:)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Append a user message to the thread. Delegates to `config.append_user_message!`.
|
|
79
|
+
|
|
80
|
+
**Parameters:**
|
|
81
|
+
|
|
82
|
+
| Name | Type | Description |
|
|
83
|
+
|------|------|-------------|
|
|
84
|
+
| `session_id` | `String` | Thread identifier |
|
|
85
|
+
| `message` | `UserMessage` | User message to append |
|
|
44
86
|
|
|
45
87
|
### append_results
|
|
46
88
|
|
|
47
89
|
```ruby
|
|
48
|
-
manager.append_results(
|
|
90
|
+
manager.append_results(session_id:, results:)
|
|
49
91
|
```
|
|
50
92
|
|
|
51
|
-
|
|
93
|
+
Append robot results to the thread. Delegates to `config.append_results!`.
|
|
52
94
|
|
|
53
|
-
|
|
95
|
+
**Parameters:**
|
|
96
|
+
|
|
97
|
+
| Name | Type | Description |
|
|
98
|
+
|------|------|-------------|
|
|
99
|
+
| `session_id` | `String` | Thread identifier |
|
|
100
|
+
| `results` | `Array<RobotResult>` | Results to append |
|
|
101
|
+
|
|
102
|
+
### load_state
|
|
54
103
|
|
|
55
104
|
```ruby
|
|
56
|
-
|
|
105
|
+
state = manager.load_state(session_id:, state:)
|
|
57
106
|
```
|
|
58
107
|
|
|
59
|
-
|
|
108
|
+
Load history from a thread into a state/memory object. Retrieves the history, sets the `session_id` on the state, and calls `append_result` for each historical result.
|
|
60
109
|
|
|
61
|
-
|
|
110
|
+
**Parameters:**
|
|
111
|
+
|
|
112
|
+
| Name | Type | Description |
|
|
113
|
+
|------|------|-------------|
|
|
114
|
+
| `session_id` | `String` | Thread identifier |
|
|
115
|
+
| `state` | `Object` | State or Memory object to populate |
|
|
116
|
+
|
|
117
|
+
**Returns:** The state object with loaded history.
|
|
118
|
+
|
|
119
|
+
### save_state
|
|
62
120
|
|
|
63
121
|
```ruby
|
|
64
|
-
|
|
122
|
+
manager.save_state(session_id:, state:, since_index: 0)
|
|
65
123
|
```
|
|
66
124
|
|
|
67
|
-
|
|
125
|
+
Save new results from a state object to the thread. Extracts results from `state.results` starting at `since_index` and appends them.
|
|
126
|
+
|
|
127
|
+
**Parameters:**
|
|
128
|
+
|
|
129
|
+
| Name | Type | Description |
|
|
130
|
+
|------|------|-------------|
|
|
131
|
+
| `session_id` | `String` | Thread identifier |
|
|
132
|
+
| `state` | `Object` | State object with results |
|
|
133
|
+
| `since_index` | `Integer` | Save results from this index (default: 0) |
|
|
68
134
|
|
|
69
135
|
## Examples
|
|
70
136
|
|
|
71
137
|
### Basic Usage
|
|
72
138
|
|
|
73
139
|
```ruby
|
|
74
|
-
config = History::Config.new(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
140
|
+
config = RobotLab::History::Config.new(
|
|
141
|
+
create_thread: ->(state:, input:, **) { { session_id: SecureRandom.uuid } },
|
|
142
|
+
get: ->(session_id:, **) { STORE[session_id] || [] },
|
|
143
|
+
append_results: ->(session_id:, new_results:, **) {
|
|
144
|
+
STORE[session_id] ||= []
|
|
145
|
+
STORE[session_id].concat(new_results)
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
manager = RobotLab::History::ThreadManager.new(config)
|
|
150
|
+
|
|
151
|
+
# Start a new conversation
|
|
152
|
+
session_id = manager.create_thread(state: memory, input: "Hello")
|
|
153
|
+
|
|
154
|
+
# Run a robot and save results
|
|
155
|
+
result = robot.run("Hello")
|
|
156
|
+
manager.append_results(session_id: session_id, results: [result])
|
|
157
|
+
|
|
158
|
+
# Later, retrieve history
|
|
159
|
+
history = manager.get_history(session_id)
|
|
91
160
|
```
|
|
92
161
|
|
|
93
|
-
###
|
|
162
|
+
### Loading History into Memory
|
|
94
163
|
|
|
95
164
|
```ruby
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
#
|
|
103
|
-
result1 = network.run(state: state1)
|
|
104
|
-
thread_id = result1.state.thread_id
|
|
105
|
-
|
|
106
|
-
# Continue - history loaded automatically
|
|
107
|
-
state2 = RobotLab.create_state(
|
|
108
|
-
message: UserMessage.new("Continue", thread_id: thread_id)
|
|
109
|
-
)
|
|
110
|
-
result2 = network.run(state: state2)
|
|
165
|
+
manager = RobotLab::History::ThreadManager.new(config)
|
|
166
|
+
|
|
167
|
+
# Create a memory object and load previous conversation
|
|
168
|
+
memory = RobotLab::Memory.new
|
|
169
|
+
manager.load_state(session_id: existing_session_id, state: memory)
|
|
170
|
+
|
|
171
|
+
# Memory now contains previous results and session_id
|
|
111
172
|
```
|
|
112
173
|
|
|
113
|
-
###
|
|
174
|
+
### Saving Incremental Results
|
|
114
175
|
|
|
115
176
|
```ruby
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
metadata: metadata,
|
|
122
|
-
created_at: Time.current
|
|
123
|
-
)
|
|
124
|
-
},
|
|
125
|
-
get: ->(thread_id:, **) { Thread.find(thread_id).results },
|
|
126
|
-
append_results: ->(thread_id:, new_results:, **) {
|
|
127
|
-
Thread.find(thread_id).results.concat(new_results)
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
)
|
|
177
|
+
# Save only new results (since the last save point)
|
|
178
|
+
initial_count = memory.results.length
|
|
179
|
+
|
|
180
|
+
result = robot.run("Follow-up question")
|
|
181
|
+
memory.append_result(result)
|
|
131
182
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
state:
|
|
135
|
-
|
|
136
|
-
metadata: { source: "web", priority: "high" }
|
|
183
|
+
manager.save_state(
|
|
184
|
+
session_id: session_id,
|
|
185
|
+
state: memory,
|
|
186
|
+
since_index: initial_count
|
|
137
187
|
)
|
|
138
188
|
```
|
|
139
189
|
|
data/docs/api/mcp/client.md
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
1
|
# MCP Client
|
|
2
2
|
|
|
3
|
-
Connects to MCP servers and
|
|
3
|
+
Connects to MCP servers, discovers tools, and invokes them via the Model Context Protocol.
|
|
4
4
|
|
|
5
5
|
## Class: `RobotLab::MCP::Client`
|
|
6
6
|
|
|
7
7
|
```ruby
|
|
8
8
|
client = RobotLab::MCP::Client.new(
|
|
9
9
|
name: "filesystem",
|
|
10
|
-
transport: { type: "stdio", command: "mcp-server-filesystem" }
|
|
10
|
+
transport: { type: "stdio", command: "mcp-server-filesystem", args: ["--root", "/data"] }
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
client.connect
|
|
14
14
|
tools = client.list_tools
|
|
15
|
+
result = client.call_tool("readFile", { path: "/data/readme.txt" })
|
|
16
|
+
client.disconnect
|
|
15
17
|
```
|
|
16
18
|
|
|
17
19
|
## Constructor
|
|
18
20
|
|
|
19
21
|
```ruby
|
|
20
|
-
Client.new(
|
|
22
|
+
Client.new(server_or_config)
|
|
21
23
|
```
|
|
22
24
|
|
|
25
|
+
Accepts either a `Server` instance or a Hash configuration. When a Hash is provided, it is used to construct a `Server` internally.
|
|
26
|
+
|
|
23
27
|
**Parameters:**
|
|
24
28
|
|
|
25
29
|
| Name | Type | Description |
|
|
26
30
|
|------|------|-------------|
|
|
27
|
-
| `
|
|
28
|
-
| `transport` | `Hash` | Transport configuration |
|
|
31
|
+
| `server_or_config` | `Server`, `Hash` | Server instance or configuration hash |
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
**Hash Configuration Keys:**
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
| Key | Type | Required | Description |
|
|
36
|
+
|-----|------|----------|-------------|
|
|
37
|
+
| `name` | `String` | Yes | Server identifier |
|
|
38
|
+
| `transport` | `Hash` | Yes | Transport configuration (must include `type`) |
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
client.name # => String
|
|
36
|
-
```
|
|
40
|
+
**Raises:** `ArgumentError` if the config is neither a `Server` nor a `Hash`.
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
## Attributes
|
|
39
43
|
|
|
40
|
-
###
|
|
44
|
+
### server
|
|
41
45
|
|
|
42
46
|
```ruby
|
|
43
|
-
client.
|
|
47
|
+
client.server # => RobotLab::MCP::Server
|
|
44
48
|
```
|
|
45
49
|
|
|
46
|
-
The
|
|
50
|
+
The MCP server configuration object.
|
|
47
51
|
|
|
48
52
|
### connected?
|
|
49
53
|
|
|
@@ -51,38 +55,42 @@ The underlying transport connection.
|
|
|
51
55
|
client.connected? # => Boolean
|
|
52
56
|
```
|
|
53
57
|
|
|
54
|
-
Whether the client is connected.
|
|
58
|
+
Whether the client is currently connected to the server.
|
|
55
59
|
|
|
56
60
|
## Methods
|
|
57
61
|
|
|
58
62
|
### connect
|
|
59
63
|
|
|
60
64
|
```ruby
|
|
61
|
-
client.connect
|
|
65
|
+
client.connect # => self
|
|
62
66
|
```
|
|
63
67
|
|
|
64
|
-
Establish connection to the MCP server.
|
|
68
|
+
Establish a connection to the MCP server. Creates the appropriate transport based on the server's transport type, then connects. If already connected, returns immediately.
|
|
69
|
+
|
|
70
|
+
Connection failures are logged as warnings and the client remains in a disconnected state (does not raise).
|
|
65
71
|
|
|
66
72
|
### disconnect
|
|
67
73
|
|
|
68
74
|
```ruby
|
|
69
|
-
client.disconnect
|
|
75
|
+
client.disconnect # => self
|
|
70
76
|
```
|
|
71
77
|
|
|
72
|
-
Close the connection.
|
|
78
|
+
Close the connection to the MCP server. Closes the underlying transport and resets connection state. If not connected, returns immediately.
|
|
73
79
|
|
|
74
80
|
### list_tools
|
|
75
81
|
|
|
76
82
|
```ruby
|
|
77
|
-
client.list_tools # => Array<
|
|
83
|
+
client.list_tools # => Array<Hash>
|
|
78
84
|
```
|
|
79
85
|
|
|
80
|
-
Discover available tools from the server.
|
|
86
|
+
Discover available tools from the server. Returns an array of tool definition hashes.
|
|
87
|
+
|
|
88
|
+
**Raises:** `MCPError` if not connected.
|
|
81
89
|
|
|
82
90
|
### call_tool
|
|
83
91
|
|
|
84
92
|
```ruby
|
|
85
|
-
result = client.call_tool(name,
|
|
93
|
+
result = client.call_tool(name, arguments = {})
|
|
86
94
|
```
|
|
87
95
|
|
|
88
96
|
Execute a tool on the server.
|
|
@@ -92,30 +100,81 @@ Execute a tool on the server.
|
|
|
92
100
|
| Name | Type | Description |
|
|
93
101
|
|------|------|-------------|
|
|
94
102
|
| `name` | `String` | Tool name |
|
|
95
|
-
| `
|
|
103
|
+
| `arguments` | `Hash` | Tool arguments (default: `{}`) |
|
|
104
|
+
|
|
105
|
+
**Returns:** Tool result content (from the `content` field of the response).
|
|
106
|
+
|
|
107
|
+
**Raises:** `MCPError` if not connected.
|
|
96
108
|
|
|
97
109
|
### list_resources
|
|
98
110
|
|
|
99
111
|
```ruby
|
|
100
|
-
client.list_resources # => Array<
|
|
112
|
+
client.list_resources # => Array<Hash>
|
|
101
113
|
```
|
|
102
114
|
|
|
103
|
-
List available resources
|
|
115
|
+
List available resources from the server.
|
|
116
|
+
|
|
117
|
+
**Raises:** `MCPError` if not connected.
|
|
104
118
|
|
|
105
119
|
### read_resource
|
|
106
120
|
|
|
107
121
|
```ruby
|
|
108
|
-
client.read_resource(uri) # =>
|
|
122
|
+
client.read_resource(uri) # => Object
|
|
109
123
|
```
|
|
110
124
|
|
|
111
125
|
Read a resource by URI.
|
|
112
126
|
|
|
127
|
+
**Parameters:**
|
|
128
|
+
|
|
129
|
+
| Name | Type | Description |
|
|
130
|
+
|------|------|-------------|
|
|
131
|
+
| `uri` | `String` | Resource URI |
|
|
132
|
+
|
|
133
|
+
**Raises:** `MCPError` if not connected.
|
|
134
|
+
|
|
135
|
+
### list_prompts
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
client.list_prompts # => Array<Hash>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
List available prompts from the server.
|
|
142
|
+
|
|
143
|
+
**Raises:** `MCPError` if not connected.
|
|
144
|
+
|
|
145
|
+
### get_prompt
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
client.get_prompt(name, arguments = {}) # => Hash
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Get a prompt by name with optional arguments.
|
|
152
|
+
|
|
153
|
+
**Parameters:**
|
|
154
|
+
|
|
155
|
+
| Name | Type | Description |
|
|
156
|
+
|------|------|-------------|
|
|
157
|
+
| `name` | `String` | Prompt name |
|
|
158
|
+
| `arguments` | `Hash` | Prompt arguments (default: `{}`) |
|
|
159
|
+
|
|
160
|
+
**Raises:** `MCPError` if not connected.
|
|
161
|
+
|
|
162
|
+
### to_h
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
client.to_h # => Hash
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Converts the client to a hash representation containing server config and connection status.
|
|
169
|
+
|
|
113
170
|
## Transport Configuration
|
|
114
171
|
|
|
172
|
+
The transport type is determined by the `type` key in the transport hash of the `Server` configuration.
|
|
173
|
+
|
|
115
174
|
### Stdio
|
|
116
175
|
|
|
117
176
|
```ruby
|
|
118
|
-
client = Client.new(
|
|
177
|
+
client = RobotLab::MCP::Client.new(
|
|
119
178
|
name: "local",
|
|
120
179
|
transport: {
|
|
121
180
|
type: "stdio",
|
|
@@ -128,10 +187,10 @@ client = Client.new(
|
|
|
128
187
|
### WebSocket
|
|
129
188
|
|
|
130
189
|
```ruby
|
|
131
|
-
client = Client.new(
|
|
190
|
+
client = RobotLab::MCP::Client.new(
|
|
132
191
|
name: "remote",
|
|
133
192
|
transport: {
|
|
134
|
-
type: "
|
|
193
|
+
type: "ws",
|
|
135
194
|
url: "wss://mcp.example.com/ws"
|
|
136
195
|
}
|
|
137
196
|
)
|
|
@@ -140,7 +199,7 @@ client = Client.new(
|
|
|
140
199
|
### SSE
|
|
141
200
|
|
|
142
201
|
```ruby
|
|
143
|
-
client = Client.new(
|
|
202
|
+
client = RobotLab::MCP::Client.new(
|
|
144
203
|
name: "streaming",
|
|
145
204
|
transport: {
|
|
146
205
|
type: "sse",
|
|
@@ -149,14 +208,15 @@ client = Client.new(
|
|
|
149
208
|
)
|
|
150
209
|
```
|
|
151
210
|
|
|
152
|
-
### HTTP
|
|
211
|
+
### Streamable HTTP
|
|
153
212
|
|
|
154
213
|
```ruby
|
|
155
|
-
client = Client.new(
|
|
214
|
+
client = RobotLab::MCP::Client.new(
|
|
156
215
|
name: "http",
|
|
157
216
|
transport: {
|
|
158
|
-
type: "http",
|
|
159
|
-
url: "https://mcp.example.com/mcp"
|
|
217
|
+
type: "streamable-http",
|
|
218
|
+
url: "https://mcp.example.com/mcp",
|
|
219
|
+
session_id: "optional-session-id"
|
|
160
220
|
}
|
|
161
221
|
)
|
|
162
222
|
```
|
|
@@ -166,7 +226,7 @@ client = Client.new(
|
|
|
166
226
|
### Basic Usage
|
|
167
227
|
|
|
168
228
|
```ruby
|
|
169
|
-
client = Client.new(
|
|
229
|
+
client = RobotLab::MCP::Client.new(
|
|
170
230
|
name: "github",
|
|
171
231
|
transport: { type: "stdio", command: "mcp-server-github" }
|
|
172
232
|
)
|
|
@@ -175,7 +235,7 @@ client.connect
|
|
|
175
235
|
|
|
176
236
|
# List available tools
|
|
177
237
|
tools = client.list_tools
|
|
178
|
-
tools.each { |t| puts "#{t
|
|
238
|
+
tools.each { |t| puts "#{t[:name]}: #{t[:description]}" }
|
|
179
239
|
|
|
180
240
|
# Call a tool
|
|
181
241
|
result = client.call_tool("search_repositories", { query: "ruby mcp" })
|
|
@@ -184,19 +244,32 @@ puts result
|
|
|
184
244
|
client.disconnect
|
|
185
245
|
```
|
|
186
246
|
|
|
187
|
-
###
|
|
247
|
+
### From a Server Object
|
|
188
248
|
|
|
189
249
|
```ruby
|
|
190
|
-
|
|
191
|
-
name "
|
|
250
|
+
server = RobotLab::MCP::Server.new(
|
|
251
|
+
name: "neon",
|
|
252
|
+
transport: { type: "ws", url: "ws://localhost:8080" }
|
|
253
|
+
)
|
|
192
254
|
|
|
193
|
-
|
|
255
|
+
client = RobotLab::MCP::Client.new(server)
|
|
256
|
+
client.connect
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### In a Robot
|
|
260
|
+
|
|
261
|
+
```ruby
|
|
262
|
+
robot = Robot.new(
|
|
263
|
+
name: "assistant",
|
|
264
|
+
system_prompt: "You help with file operations.",
|
|
265
|
+
mcp: [
|
|
194
266
|
{ name: "fs", transport: { type: "stdio", command: "mcp-fs" } }
|
|
195
267
|
]
|
|
196
|
-
|
|
268
|
+
)
|
|
197
269
|
|
|
198
|
-
# MCP tools are automatically available
|
|
199
|
-
robot.
|
|
270
|
+
# MCP tools are automatically discovered and available to the LLM
|
|
271
|
+
result = robot.run("Read the contents of /data/config.yml")
|
|
272
|
+
puts result.last_text_content
|
|
200
273
|
```
|
|
201
274
|
|
|
202
275
|
### Error Handling
|
|
@@ -205,10 +278,8 @@ robot.tools.each { |t| puts t.name }
|
|
|
205
278
|
begin
|
|
206
279
|
client.connect
|
|
207
280
|
result = client.call_tool("unknown_tool", {})
|
|
208
|
-
rescue RobotLab::
|
|
209
|
-
puts "
|
|
210
|
-
rescue RobotLab::MCP::ToolError => e
|
|
211
|
-
puts "Tool error: #{e.message}"
|
|
281
|
+
rescue RobotLab::MCPError => e
|
|
282
|
+
puts "MCP error: #{e.message}"
|
|
212
283
|
ensure
|
|
213
284
|
client.disconnect
|
|
214
285
|
end
|
|
@@ -217,5 +288,5 @@ end
|
|
|
217
288
|
## See Also
|
|
218
289
|
|
|
219
290
|
- [MCP Overview](index.md)
|
|
291
|
+
- [Server Configuration](server.md)
|
|
220
292
|
- [Transports](transports.md)
|
|
221
|
-
- [MCP Server](server.md)
|