ruby_llm-mcp 0.7.0 → 0.7.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.
- checksums.yaml +4 -4
- data/lib/ruby_llm/mcp/transports/stdio.rb +78 -76
- data/lib/ruby_llm/mcp/version.rb +1 -1
- metadata +1 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b40509c28a60e1ae01ed83d47503d76f30d5f3bf9852ef4c30ca033d6ea149bc
|
|
4
|
+
data.tar.gz: f3393dc6423c6bcda143cb6b22e7042434ca1d7d385cc2adf97ba925efff6912
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 86e6dd3009df055ad4fa6d088b6b1d9fb87cc8c6244b1436e4ef96ef1cbd822c321c779bd518557544a6c457d19270bf1a57c874cb6d80543141ecac7c370754
|
|
7
|
+
data.tar.gz: 5a76f9b2aaf2d3db38d97c9d66341458e25f3cdd89fdaf1768095a1bba20257154e128c9b60245f1f09f3e6f09b967daacd70748008c4edf90c3e836546bd6d6
|
|
@@ -78,51 +78,23 @@ module RubyLLM
|
|
|
78
78
|
@running = true
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
def close
|
|
81
|
+
def close
|
|
82
82
|
@running = false
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
rescue
|
|
87
|
-
nil
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
begin
|
|
91
|
-
@wait_thread&.join(1)
|
|
92
|
-
rescue StandardError
|
|
84
|
+
[@stdin, @stdout, @stderr].each do |stream|
|
|
85
|
+
stream&.close
|
|
86
|
+
rescue IOError, Errno::EBADF
|
|
93
87
|
nil
|
|
94
88
|
end
|
|
95
89
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
rescue StandardError
|
|
99
|
-
nil
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
begin
|
|
103
|
-
@stderr&.close
|
|
90
|
+
[@wait_thread, @reader_thread, @stderr_thread].each do |thread|
|
|
91
|
+
thread&.join(1)
|
|
104
92
|
rescue StandardError
|
|
105
93
|
nil
|
|
106
94
|
end
|
|
107
95
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
rescue StandardError
|
|
111
|
-
nil
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
begin
|
|
115
|
-
@stderr_thread&.join(1)
|
|
116
|
-
rescue StandardError
|
|
117
|
-
nil
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
@stdin = nil
|
|
121
|
-
@stdout = nil
|
|
122
|
-
@stderr = nil
|
|
123
|
-
@wait_thread = nil
|
|
124
|
-
@reader_thread = nil
|
|
125
|
-
@stderr_thread = nil
|
|
96
|
+
@stdin = @stdout = @stderr = nil
|
|
97
|
+
@wait_thread = @reader_thread = @stderr_thread = nil
|
|
126
98
|
end
|
|
127
99
|
|
|
128
100
|
def set_protocol_version(version)
|
|
@@ -151,58 +123,88 @@ module RubyLLM
|
|
|
151
123
|
|
|
152
124
|
def start_reader_thread
|
|
153
125
|
@reader_thread = Thread.new do
|
|
154
|
-
|
|
155
|
-
begin
|
|
156
|
-
if @stdout.closed? || @wait_thread.nil? || !@wait_thread.alive?
|
|
157
|
-
sleep 1
|
|
158
|
-
restart_process if @running
|
|
159
|
-
next
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
line = @stdout.gets
|
|
163
|
-
next unless line && !line.strip.empty?
|
|
164
|
-
|
|
165
|
-
process_response(line.strip)
|
|
166
|
-
rescue IOError, Errno::EPIPE => e
|
|
167
|
-
RubyLLM::MCP.logger.error "Reader error: #{e.message}. Restarting in 1 second..."
|
|
168
|
-
sleep 1
|
|
169
|
-
restart_process if @running
|
|
170
|
-
rescue StandardError => e
|
|
171
|
-
RubyLLM::MCP.logger.error "Error in reader thread: #{e.message}, #{e.backtrace.join("\n")}"
|
|
172
|
-
sleep 1
|
|
173
|
-
end
|
|
174
|
-
end
|
|
126
|
+
read_stdout_loop
|
|
175
127
|
end
|
|
176
128
|
|
|
177
129
|
@reader_thread.abort_on_exception = true
|
|
178
130
|
end
|
|
179
131
|
|
|
132
|
+
def read_stdout_loop
|
|
133
|
+
while @running
|
|
134
|
+
begin
|
|
135
|
+
handle_stdout_read
|
|
136
|
+
rescue IOError, Errno::EPIPE => e
|
|
137
|
+
handle_stream_error(e, "Reader")
|
|
138
|
+
break unless @running
|
|
139
|
+
rescue StandardError => e
|
|
140
|
+
RubyLLM::MCP.logger.error "Error in reader thread: #{e.message}, #{e.backtrace.join("\n")}"
|
|
141
|
+
sleep 1
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def handle_stdout_read
|
|
147
|
+
if @stdout.closed? || @wait_thread.nil? || !@wait_thread.alive?
|
|
148
|
+
if @running
|
|
149
|
+
sleep 1
|
|
150
|
+
restart_process
|
|
151
|
+
end
|
|
152
|
+
return
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
line = @stdout.gets
|
|
156
|
+
return unless line && !line.strip.empty?
|
|
157
|
+
|
|
158
|
+
process_response(line.strip)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def handle_stream_error(error, stream_name)
|
|
162
|
+
# Check @running to distinguish graceful shutdown from unexpected errors.
|
|
163
|
+
# During shutdown, streams are closed intentionally and shouldn't trigger restarts.
|
|
164
|
+
if @running
|
|
165
|
+
RubyLLM::MCP.logger.error "#{stream_name} error: #{error.message}. Restarting in 1 second..."
|
|
166
|
+
sleep 1
|
|
167
|
+
restart_process
|
|
168
|
+
else
|
|
169
|
+
# Graceful shutdown in progress
|
|
170
|
+
RubyLLM::MCP.logger.debug "#{stream_name} thread exiting during shutdown"
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
180
174
|
def start_stderr_thread
|
|
181
175
|
@stderr_thread = Thread.new do
|
|
182
|
-
|
|
183
|
-
begin
|
|
184
|
-
if @stderr.closed? || @wait_thread.nil? || !@wait_thread.alive?
|
|
185
|
-
sleep 1
|
|
186
|
-
next
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
line = @stderr.gets
|
|
190
|
-
next unless line && !line.strip.empty?
|
|
191
|
-
|
|
192
|
-
RubyLLM::MCP.logger.info(line.strip)
|
|
193
|
-
rescue IOError, Errno::EPIPE => e
|
|
194
|
-
RubyLLM::MCP.logger.error "Stderr reader error: #{e.message}"
|
|
195
|
-
sleep 1
|
|
196
|
-
rescue StandardError => e
|
|
197
|
-
RubyLLM::MCP.logger.error "Error in stderr thread: #{e.message}"
|
|
198
|
-
sleep 1
|
|
199
|
-
end
|
|
200
|
-
end
|
|
176
|
+
read_stderr_loop
|
|
201
177
|
end
|
|
202
178
|
|
|
203
179
|
@stderr_thread.abort_on_exception = true
|
|
204
180
|
end
|
|
205
181
|
|
|
182
|
+
def read_stderr_loop
|
|
183
|
+
while @running
|
|
184
|
+
begin
|
|
185
|
+
handle_stderr_read
|
|
186
|
+
rescue IOError, Errno::EPIPE => e
|
|
187
|
+
handle_stream_error(e, "Stderr reader")
|
|
188
|
+
break unless @running
|
|
189
|
+
rescue StandardError => e
|
|
190
|
+
RubyLLM::MCP.logger.error "Error in stderr thread: #{e.message}"
|
|
191
|
+
sleep 1
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def handle_stderr_read
|
|
197
|
+
if @stderr.closed? || @wait_thread.nil? || !@wait_thread.alive?
|
|
198
|
+
sleep 1
|
|
199
|
+
return
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
line = @stderr.gets
|
|
203
|
+
return unless line && !line.strip.empty?
|
|
204
|
+
|
|
205
|
+
RubyLLM::MCP.logger.info(line.strip)
|
|
206
|
+
end
|
|
207
|
+
|
|
206
208
|
def process_response(line)
|
|
207
209
|
response = JSON.parse(line)
|
|
208
210
|
request_id = response["id"]&.to_s
|
data/lib/ruby_llm/mcp/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_llm-mcp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrick Vice
|
|
@@ -145,7 +145,6 @@ metadata:
|
|
|
145
145
|
homepage_uri: https://www.rubyllm-mcp.com
|
|
146
146
|
source_code_uri: https://github.com/patvice/ruby_llm-mcp
|
|
147
147
|
changelog_uri: https://github.com/patvice/ruby_llm-mcp/commits/main
|
|
148
|
-
documentation_uri: https://www.rubyllm-mcp.com
|
|
149
148
|
bug_tracker_uri: https://github.com/patvice/ruby_llm-mcp/issues
|
|
150
149
|
rubygems_mfa_required: 'true'
|
|
151
150
|
allowed_push_host: https://rubygems.org
|