Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 78 additions & 78 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,82 +10,84 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actioncable (8.0.4)
actionpack (= 8.0.4)
activesupport (= 8.0.4)
action_text-trix (2.1.15)
railties
actioncable (8.1.1)
actionpack (= 8.1.1)
activesupport (= 8.1.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (8.0.4)
actionpack (= 8.0.4)
activejob (= 8.0.4)
activerecord (= 8.0.4)
activestorage (= 8.0.4)
activesupport (= 8.0.4)
actionmailbox (8.1.1)
actionpack (= 8.1.1)
activejob (= 8.1.1)
activerecord (= 8.1.1)
activestorage (= 8.1.1)
activesupport (= 8.1.1)
mail (>= 2.8.0)
actionmailer (8.0.4)
actionpack (= 8.0.4)
actionview (= 8.0.4)
activejob (= 8.0.4)
activesupport (= 8.0.4)
actionmailer (8.1.1)
actionpack (= 8.1.1)
actionview (= 8.1.1)
activejob (= 8.1.1)
activesupport (= 8.1.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (8.0.4)
actionview (= 8.0.4)
activesupport (= 8.0.4)
actionpack (8.1.1)
actionview (= 8.1.1)
activesupport (= 8.1.1)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (8.0.4)
actionpack (= 8.0.4)
activerecord (= 8.0.4)
activestorage (= 8.0.4)
activesupport (= 8.0.4)
actiontext (8.1.1)
action_text-trix (~> 2.1.15)
actionpack (= 8.1.1)
activerecord (= 8.1.1)
activestorage (= 8.1.1)
activesupport (= 8.1.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (8.0.4)
activesupport (= 8.0.4)
actionview (8.1.1)
activesupport (= 8.1.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (8.0.4)
activesupport (= 8.0.4)
activejob (8.1.1)
activesupport (= 8.1.1)
globalid (>= 0.3.6)
activemodel (8.0.4)
activesupport (= 8.0.4)
activerecord (8.0.4)
activemodel (= 8.0.4)
activesupport (= 8.0.4)
activemodel (8.1.1)
activesupport (= 8.1.1)
activerecord (8.1.1)
activemodel (= 8.1.1)
activesupport (= 8.1.1)
timeout (>= 0.4.0)
activestorage (8.0.4)
actionpack (= 8.0.4)
activejob (= 8.0.4)
activerecord (= 8.0.4)
activesupport (= 8.0.4)
activestorage (8.1.1)
actionpack (= 8.1.1)
activejob (= 8.1.1)
activerecord (= 8.1.1)
activesupport (= 8.1.1)
marcel (~> 1.0)
activesupport (8.0.4)
activesupport (8.1.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.8)
public_suffix (>= 2.0.2, < 8.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.3)
base64 (0.3.0)
benchmark (0.5.0)
bigdecimal (3.3.1)
builder (3.3.0)
capybara (3.40.0)
Expand Down Expand Up @@ -131,7 +133,7 @@ GEM
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
erb (6.0.0)
erb (5.1.3)
erubi (1.13.1)
event_stream_parser (1.0.0)
faraday (2.14.0)
Expand Down Expand Up @@ -174,7 +176,7 @@ GEM
net-pop
net-smtp
marcel (1.1.0)
matrix (0.4.3)
matrix (0.4.2)
mime-types (3.7.0)
logger
mime-types-data (~> 3.2025, >= 3.2025.0507)
Expand All @@ -193,13 +195,11 @@ GEM
timeout
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nio4r (2.7.4)
nokogiri (1.18.10-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.10-x86_64-linux-gnu)
racc (~> 1.4)
parallel (1.27.0)
parser (3.3.10.0)
parser (3.3.8.0)
ast (~> 2.4.1)
racc
pp (0.6.3)
Expand All @@ -209,7 +209,7 @@ GEM
psych (5.2.6)
date
stringio
public_suffix (7.0.0)
public_suffix (6.0.2)
puma (7.1.0)
nio4r (~> 2.0)
racc (1.8.1)
Expand All @@ -221,30 +221,30 @@ GEM
rack (>= 1.3)
rackup (2.2.1)
rack (>= 3)
rails (8.0.4)
actioncable (= 8.0.4)
actionmailbox (= 8.0.4)
actionmailer (= 8.0.4)
actionpack (= 8.0.4)
actiontext (= 8.0.4)
actionview (= 8.0.4)
activejob (= 8.0.4)
activemodel (= 8.0.4)
activerecord (= 8.0.4)
activestorage (= 8.0.4)
activesupport (= 8.0.4)
rails (8.1.1)
actioncable (= 8.1.1)
actionmailbox (= 8.1.1)
actionmailer (= 8.1.1)
actionpack (= 8.1.1)
actiontext (= 8.1.1)
actionview (= 8.1.1)
activejob (= 8.1.1)
activemodel (= 8.1.1)
activerecord (= 8.1.1)
activestorage (= 8.1.1)
activesupport (= 8.1.1)
bundler (>= 1.15.0)
railties (= 8.0.4)
railties (= 8.1.1)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
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)
railties (8.0.4)
actionpack (= 8.0.4)
activesupport (= 8.0.4)
railties (8.1.1)
actionpack (= 8.1.1)
activesupport (= 8.1.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
Expand All @@ -253,26 +253,26 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.1)
rdoc (6.16.0)
rdoc (6.15.1)
erb
psych (>= 4.0.0)
tsort
regexp_parser (2.11.3)
reline (0.6.3)
regexp_parser (2.10.0)
reline (0.6.2)
io-console (~> 0.5)
rexml (3.4.4)
rubocop (1.81.7)
rubocop (1.75.7)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.47.1, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.48.0)
rubocop-ast (1.44.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
ruby-progressbar (1.13.0)
Expand All @@ -286,25 +286,25 @@ GEM
marcel (~> 1.0)
ruby_llm-schema (~> 0.2.1)
zeitwerk (~> 2)
ruby_llm-schema (0.2.5)
rubyzip (3.2.2)
ruby_llm-schema (0.2.1)
rubyzip (3.2.1)
securerandom (0.4.1)
selenium-webdriver (4.38.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 4.0)
websocket (~> 1.0)
sorbet-runtime (0.6.12793)
stringio (3.1.8)
sorbet-runtime (0.6.12798)
stringio (3.1.7)
thor (1.4.0)
timeout (0.4.4)
tsort (0.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
unicode-display_width (3.1.4)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uri (1.1.1)
useragent (0.16.11)
websocket (1.2.11)
Expand All @@ -317,7 +317,7 @@ GEM
zeitwerk (2.7.3)

PLATFORMS
arm64-darwin-24
arm64-darwin
x86_64-linux

DEPENDENCIES
Expand Down
15 changes: 5 additions & 10 deletions app/controllers/rails_mcp_engine/playground_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def delete_tool
result = if schema.nil?
{ error: "Tool not found: #{tool_name}" }
else
delete_tool_from_registry(schema[:service_class])
delete_tool_from_registry(tool_name)
end

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

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

def delete_tool_from_registry(service_class)
ToolMeta.registry.delete(service_class)

# Also remove the RubyLLM tool class constant
tool_constant = ToolSchema::RubyLlmFactory.tool_class_name(service_class)
::Tools.send(:remove_const, tool_constant) if ::Tools.const_defined?(tool_constant, false)

{ success: 'Tool deleted successfully' }
def delete_tool_from_registry(tool_name)
::Tools::MetaToolWriteService.new.delete_tool(tool_name)
rescue StandardError => e
{ error: e.message }
end
Expand Down
20 changes: 0 additions & 20 deletions app/services/tools/meta_tool_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,7 @@ def call(action:, tool_name: nil, query: nil, arguments: nil)
end
end

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

service_class = constantize(class_name)
return { error: "Could not find #{class_name}" } if service_class.nil?
return { error: "#{class_name} must extend ToolMeta" } unless service_class.respond_to?(:tool_metadata)

ToolMeta.registry << service_class unless ToolMeta.registry.include?(service_class)

schema = ToolSchema::Builder.build(service_class)
ToolSchema::RubyLlmFactory.build(service_class, schema, before_call: before_call, after_call: after_call)
ToolSchema::FastMcpFactory.build(service_class, schema, before_call: before_call, after_call: after_call)

{ status: 'registered', tool: summary_payload(schema) }
rescue ToolMeta::MissingSignatureError => e
{ error: e.message }
rescue NameError => e
{ error: "Could not find #{class_name}: #{e.message}" }
end

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

private

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