Skip to content

Commit 63f9a62

Browse files
committed
Refactor MetaTool services: separate write operations to MetaToolWriteService
1 parent 09fda8e commit 63f9a62

File tree

7 files changed

+256
-114
lines changed

7 files changed

+256
-114
lines changed

Gemfile.lock

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,82 +10,84 @@ PATH
1010
GEM
1111
remote: https://rubygems.org/
1212
specs:
13-
actioncable (8.0.4)
14-
actionpack (= 8.0.4)
15-
activesupport (= 8.0.4)
13+
action_text-trix (2.1.15)
14+
railties
15+
actioncable (8.1.1)
16+
actionpack (= 8.1.1)
17+
activesupport (= 8.1.1)
1618
nio4r (~> 2.0)
1719
websocket-driver (>= 0.6.1)
1820
zeitwerk (~> 2.6)
19-
actionmailbox (8.0.4)
20-
actionpack (= 8.0.4)
21-
activejob (= 8.0.4)
22-
activerecord (= 8.0.4)
23-
activestorage (= 8.0.4)
24-
activesupport (= 8.0.4)
21+
actionmailbox (8.1.1)
22+
actionpack (= 8.1.1)
23+
activejob (= 8.1.1)
24+
activerecord (= 8.1.1)
25+
activestorage (= 8.1.1)
26+
activesupport (= 8.1.1)
2527
mail (>= 2.8.0)
26-
actionmailer (8.0.4)
27-
actionpack (= 8.0.4)
28-
actionview (= 8.0.4)
29-
activejob (= 8.0.4)
30-
activesupport (= 8.0.4)
28+
actionmailer (8.1.1)
29+
actionpack (= 8.1.1)
30+
actionview (= 8.1.1)
31+
activejob (= 8.1.1)
32+
activesupport (= 8.1.1)
3133
mail (>= 2.8.0)
3234
rails-dom-testing (~> 2.2)
33-
actionpack (8.0.4)
34-
actionview (= 8.0.4)
35-
activesupport (= 8.0.4)
35+
actionpack (8.1.1)
36+
actionview (= 8.1.1)
37+
activesupport (= 8.1.1)
3638
nokogiri (>= 1.8.5)
3739
rack (>= 2.2.4)
3840
rack-session (>= 1.0.1)
3941
rack-test (>= 0.6.3)
4042
rails-dom-testing (~> 2.2)
4143
rails-html-sanitizer (~> 1.6)
4244
useragent (~> 0.16)
43-
actiontext (8.0.4)
44-
actionpack (= 8.0.4)
45-
activerecord (= 8.0.4)
46-
activestorage (= 8.0.4)
47-
activesupport (= 8.0.4)
45+
actiontext (8.1.1)
46+
action_text-trix (~> 2.1.15)
47+
actionpack (= 8.1.1)
48+
activerecord (= 8.1.1)
49+
activestorage (= 8.1.1)
50+
activesupport (= 8.1.1)
4851
globalid (>= 0.6.0)
4952
nokogiri (>= 1.8.5)
50-
actionview (8.0.4)
51-
activesupport (= 8.0.4)
53+
actionview (8.1.1)
54+
activesupport (= 8.1.1)
5255
builder (~> 3.1)
5356
erubi (~> 1.11)
5457
rails-dom-testing (~> 2.2)
5558
rails-html-sanitizer (~> 1.6)
56-
activejob (8.0.4)
57-
activesupport (= 8.0.4)
59+
activejob (8.1.1)
60+
activesupport (= 8.1.1)
5861
globalid (>= 0.3.6)
59-
activemodel (8.0.4)
60-
activesupport (= 8.0.4)
61-
activerecord (8.0.4)
62-
activemodel (= 8.0.4)
63-
activesupport (= 8.0.4)
62+
activemodel (8.1.1)
63+
activesupport (= 8.1.1)
64+
activerecord (8.1.1)
65+
activemodel (= 8.1.1)
66+
activesupport (= 8.1.1)
6467
timeout (>= 0.4.0)
65-
activestorage (8.0.4)
66-
actionpack (= 8.0.4)
67-
activejob (= 8.0.4)
68-
activerecord (= 8.0.4)
69-
activesupport (= 8.0.4)
68+
activestorage (8.1.1)
69+
actionpack (= 8.1.1)
70+
activejob (= 8.1.1)
71+
activerecord (= 8.1.1)
72+
activesupport (= 8.1.1)
7073
marcel (~> 1.0)
71-
activesupport (8.0.4)
74+
activesupport (8.1.1)
7275
base64
73-
benchmark (>= 0.3)
7476
bigdecimal
7577
concurrent-ruby (~> 1.0, >= 1.3.1)
7678
connection_pool (>= 2.2.5)
7779
drb
7880
i18n (>= 1.6, < 2)
81+
json
7982
logger (>= 1.4.2)
8083
minitest (>= 5.1)
8184
securerandom (>= 0.3)
8285
tzinfo (~> 2.0, >= 2.0.5)
8386
uri (>= 0.13.1)
84-
addressable (2.8.8)
85-
public_suffix (>= 2.0.2, < 8.0)
87+
addressable (2.8.7)
88+
public_suffix (>= 2.0.2, < 7.0)
8689
ast (2.4.3)
8790
base64 (0.3.0)
88-
benchmark (0.5.0)
8991
bigdecimal (3.3.1)
9092
builder (3.3.0)
9193
capybara (3.40.0)
@@ -131,7 +133,7 @@ GEM
131133
dry-inflector (~> 1.0)
132134
dry-logic (~> 1.4)
133135
zeitwerk (~> 2.6)
134-
erb (6.0.0)
136+
erb (5.1.3)
135137
erubi (1.13.1)
136138
event_stream_parser (1.0.0)
137139
faraday (2.14.0)
@@ -174,7 +176,7 @@ GEM
174176
net-pop
175177
net-smtp
176178
marcel (1.1.0)
177-
matrix (0.4.3)
179+
matrix (0.4.2)
178180
mime-types (3.7.0)
179181
logger
180182
mime-types-data (~> 3.2025, >= 3.2025.0507)
@@ -193,13 +195,11 @@ GEM
193195
timeout
194196
net-smtp (0.5.1)
195197
net-protocol
196-
nio4r (2.7.5)
198+
nio4r (2.7.4)
197199
nokogiri (1.18.10-arm64-darwin)
198200
racc (~> 1.4)
199-
nokogiri (1.18.10-x86_64-linux-gnu)
200-
racc (~> 1.4)
201201
parallel (1.27.0)
202-
parser (3.3.10.0)
202+
parser (3.3.8.0)
203203
ast (~> 2.4.1)
204204
racc
205205
pp (0.6.3)
@@ -209,7 +209,7 @@ GEM
209209
psych (5.2.6)
210210
date
211211
stringio
212-
public_suffix (7.0.0)
212+
public_suffix (6.0.2)
213213
puma (7.1.0)
214214
nio4r (~> 2.0)
215215
racc (1.8.1)
@@ -221,30 +221,30 @@ GEM
221221
rack (>= 1.3)
222222
rackup (2.2.1)
223223
rack (>= 3)
224-
rails (8.0.4)
225-
actioncable (= 8.0.4)
226-
actionmailbox (= 8.0.4)
227-
actionmailer (= 8.0.4)
228-
actionpack (= 8.0.4)
229-
actiontext (= 8.0.4)
230-
actionview (= 8.0.4)
231-
activejob (= 8.0.4)
232-
activemodel (= 8.0.4)
233-
activerecord (= 8.0.4)
234-
activestorage (= 8.0.4)
235-
activesupport (= 8.0.4)
224+
rails (8.1.1)
225+
actioncable (= 8.1.1)
226+
actionmailbox (= 8.1.1)
227+
actionmailer (= 8.1.1)
228+
actionpack (= 8.1.1)
229+
actiontext (= 8.1.1)
230+
actionview (= 8.1.1)
231+
activejob (= 8.1.1)
232+
activemodel (= 8.1.1)
233+
activerecord (= 8.1.1)
234+
activestorage (= 8.1.1)
235+
activesupport (= 8.1.1)
236236
bundler (>= 1.15.0)
237-
railties (= 8.0.4)
237+
railties (= 8.1.1)
238238
rails-dom-testing (2.3.0)
239239
activesupport (>= 5.0.0)
240240
minitest
241241
nokogiri (>= 1.6)
242242
rails-html-sanitizer (1.6.2)
243243
loofah (~> 2.21)
244244
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
245-
railties (8.0.4)
246-
actionpack (= 8.0.4)
247-
activesupport (= 8.0.4)
245+
railties (8.1.1)
246+
actionpack (= 8.1.1)
247+
activesupport (= 8.1.1)
248248
irb (~> 1.13)
249249
rackup (>= 1.0.0)
250250
rake (>= 12.2)
@@ -253,26 +253,26 @@ GEM
253253
zeitwerk (~> 2.6)
254254
rainbow (3.1.1)
255255
rake (13.3.1)
256-
rdoc (6.16.0)
256+
rdoc (6.15.1)
257257
erb
258258
psych (>= 4.0.0)
259259
tsort
260-
regexp_parser (2.11.3)
261-
reline (0.6.3)
260+
regexp_parser (2.10.0)
261+
reline (0.6.2)
262262
io-console (~> 0.5)
263263
rexml (3.4.4)
264-
rubocop (1.81.7)
264+
rubocop (1.75.7)
265265
json (~> 2.3)
266266
language_server-protocol (~> 3.17.0.2)
267267
lint_roller (~> 1.1.0)
268268
parallel (~> 1.10)
269269
parser (>= 3.3.0.2)
270270
rainbow (>= 2.2.2, < 4.0)
271271
regexp_parser (>= 2.9.3, < 3.0)
272-
rubocop-ast (>= 1.47.1, < 2.0)
272+
rubocop-ast (>= 1.44.0, < 2.0)
273273
ruby-progressbar (~> 1.7)
274274
unicode-display_width (>= 2.4.0, < 4.0)
275-
rubocop-ast (1.48.0)
275+
rubocop-ast (1.44.1)
276276
parser (>= 3.3.7.2)
277277
prism (~> 1.4)
278278
ruby-progressbar (1.13.0)
@@ -286,25 +286,25 @@ GEM
286286
marcel (~> 1.0)
287287
ruby_llm-schema (~> 0.2.1)
288288
zeitwerk (~> 2)
289-
ruby_llm-schema (0.2.5)
290-
rubyzip (3.2.2)
289+
ruby_llm-schema (0.2.1)
290+
rubyzip (3.2.1)
291291
securerandom (0.4.1)
292292
selenium-webdriver (4.38.0)
293293
base64 (~> 0.2)
294294
logger (~> 1.4)
295295
rexml (~> 3.2, >= 3.2.5)
296296
rubyzip (>= 1.2.2, < 4.0)
297297
websocket (~> 1.0)
298-
sorbet-runtime (0.6.12793)
299-
stringio (3.1.8)
298+
sorbet-runtime (0.6.12798)
299+
stringio (3.1.7)
300300
thor (1.4.0)
301301
timeout (0.4.4)
302302
tsort (0.2.0)
303303
tzinfo (2.0.6)
304304
concurrent-ruby (~> 1.0)
305-
unicode-display_width (3.2.0)
306-
unicode-emoji (~> 4.1)
307-
unicode-emoji (4.1.0)
305+
unicode-display_width (3.1.4)
306+
unicode-emoji (~> 4.0, >= 4.0.4)
307+
unicode-emoji (4.0.4)
308308
uri (1.1.1)
309309
useragent (0.16.11)
310310
websocket (1.2.11)
@@ -317,7 +317,7 @@ GEM
317317
zeitwerk (2.7.3)
318318

319319
PLATFORMS
320-
arm64-darwin-24
320+
arm64-darwin
321321
x86_64-linux
322322

323323
DEPENDENCIES

app/controllers/rails_mcp_engine/playground_controller.rb

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def delete_tool
5050
result = if schema.nil?
5151
{ error: "Tool not found: #{tool_name}" }
5252
else
53-
delete_tool_from_registry(schema[:service_class])
53+
delete_tool_from_registry(tool_name)
5454
end
5555

5656
flash[:register_result] = result
@@ -139,8 +139,9 @@ def register_source(source, class_name)
139139
# The engine.rb defines ApplicationTool.
140140

141141
# Re-using the logic from ManualController but adapting for Engine.
142-
::Tools::MetaToolService.new.register_tool(
142+
::Tools::MetaToolWriteService.new.register_tool(
143143
class_name,
144+
source: source,
144145
before_call: ->(args) { Rails.logger.info(" [MCP] Request #{class_name}: #{args.inspect}") },
145146
after_call: ->(result) { Rails.logger.info(" [MCP] Response #{class_name}: #{result.inspect}") }
146147
)
@@ -168,14 +169,8 @@ def invoke_tool(schema, arguments)
168169
{ error: e.message }
169170
end
170171

171-
def delete_tool_from_registry(service_class)
172-
ToolMeta.registry.delete(service_class)
173-
174-
# Also remove the RubyLLM tool class constant
175-
tool_constant = ToolSchema::RubyLlmFactory.tool_class_name(service_class)
176-
::Tools.send(:remove_const, tool_constant) if ::Tools.const_defined?(tool_constant, false)
177-
178-
{ success: 'Tool deleted successfully' }
172+
def delete_tool_from_registry(tool_name)
173+
::Tools::MetaToolWriteService.new.delete_tool(tool_name)
179174
rescue StandardError => e
180175
{ error: e.message }
181176
end

app/services/tools/meta_tool_service.rb

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,7 @@ def call(action:, tool_name: nil, query: nil, arguments: nil)
4444
end
4545
end
4646

47-
sig { params(class_name: T.nilable(String), before_call: T.nilable(Proc), after_call: T.nilable(Proc)).returns(T::Hash[Symbol, T.untyped]) }
48-
def register_tool(class_name, before_call: nil, after_call: nil)
49-
return { error: 'class_name is required for register' } if class_name.nil? || class_name.empty?
5047

51-
service_class = constantize(class_name)
52-
return { error: "Could not find #{class_name}" } if service_class.nil?
53-
return { error: "#{class_name} must extend ToolMeta" } unless service_class.respond_to?(:tool_metadata)
54-
55-
ToolMeta.registry << service_class unless ToolMeta.registry.include?(service_class)
56-
57-
schema = ToolSchema::Builder.build(service_class)
58-
ToolSchema::RubyLlmFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
59-
ToolSchema::FastMcpFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
60-
61-
{ status: 'registered', tool: summary_payload(schema) }
62-
rescue ToolMeta::MissingSignatureError => e
63-
{ error: e.message }
64-
rescue NameError => e
65-
{ error: "Could not find #{class_name}: #{e.message}" }
66-
end
6748

6849
sig { params(tool_names: T::Array[String]).returns(T::Array[T.class_of(Object)]) }
6950
def self.ruby_llm_tools(tool_names)
@@ -76,7 +57,6 @@ def self.ruby_llm_tools(tool_names)
7657
end
7758
end
7859

79-
private
8060

8161
sig { params(query: T.nilable(String)).returns(T::Hash[Symbol, T.untyped]) }
8262
def search_tools(query)

0 commit comments

Comments
 (0)