ruby_llm-mcp 0.6.4 → 0.7.0
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/generators/ruby_llm/mcp/templates/initializer.rb +1 -4
- data/lib/ruby_llm/mcp/configuration.rb +1 -0
- data/lib/ruby_llm/mcp/content.rb +10 -2
- data/lib/ruby_llm/mcp/resource.rb +1 -1
- data/lib/ruby_llm/mcp/tool.rb +89 -85
- data/lib/ruby_llm/mcp/version.rb +1 -1
- data/lib/ruby_llm/mcp.rb +3 -3
- metadata +3 -7
- data/lib/ruby_llm/mcp/parameter.rb +0 -49
- data/lib/ruby_llm/mcp/providers/anthropic/complex_parameter_support.rb +0 -87
- data/lib/ruby_llm/mcp/providers/gemini/complex_parameter_support.rb +0 -86
- data/lib/ruby_llm/mcp/providers/openai/complex_parameter_support.rb +0 -72
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c8d0ab416033fcafeed6caa5146ab4c5599d0576eb3a17b2e0c04bb4bbb2234
|
|
4
|
+
data.tar.gz: 207026831043126a1e0dfac10fbbe9e8a396edbe8ab874c8af04d1230d57de5c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fbae5a8e05f3df2ee2ef81469a7ca8159b03cde998c5881e6e32ab0353cdb22a3b03a3cf63e3464f95e05f71ed87f861d793e944683c72c90660162fb6263e5
|
|
7
|
+
data.tar.gz: 9888713bcb543421c389954a36d235f024e271163096a82473c4bf1b1c2b16737602c0b608ff28d653cf1ab636909f0b9c6120e228b74ecdc794f2b0ebfc3dc4
|
|
@@ -11,9 +11,6 @@ RubyLLM::MCP.configure do |config|
|
|
|
11
11
|
# Pool timeout in seconds
|
|
12
12
|
config.pool_timeout = 5
|
|
13
13
|
|
|
14
|
-
# Enable complex parameter support for various providers
|
|
15
|
-
config.support_complex_parameters!
|
|
16
|
-
|
|
17
14
|
# Path to MCPs configuration file
|
|
18
15
|
config.config_path = Rails.root.join("config", "mcps.yml")
|
|
19
16
|
|
|
@@ -31,7 +28,7 @@ RubyLLM::MCP.configure do |config|
|
|
|
31
28
|
# Set preferred model for sampling
|
|
32
29
|
# config.sampling.preferred_model do
|
|
33
30
|
# # Return the preferred model name
|
|
34
|
-
# "claude-
|
|
31
|
+
# "claude-sonnet-4"
|
|
35
32
|
# end
|
|
36
33
|
|
|
37
34
|
# Set a guard for sampling
|
|
@@ -111,6 +111,7 @@ module RubyLLM
|
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def support_complex_parameters!
|
|
114
|
+
warn "[DEPRECATION] config.support_complex_parameters! is no longer needed and will be removed in version 0.8.0"
|
|
114
115
|
return if @has_support_complex_parameters
|
|
115
116
|
|
|
116
117
|
@has_support_complex_parameters = true
|
data/lib/ruby_llm/mcp/content.rb
CHANGED
|
@@ -7,13 +7,21 @@ module RubyLLM
|
|
|
7
7
|
|
|
8
8
|
def initialize(text: nil, attachments: nil) # rubocop:disable Lint/MissingSuper
|
|
9
9
|
@text = text
|
|
10
|
-
@attachments =
|
|
10
|
+
@attachments = []
|
|
11
|
+
|
|
12
|
+
# Handle MCP::Attachment objects directly without processing
|
|
13
|
+
if attachments.is_a?(Array) && attachments.all? { |a| a.is_a?(MCP::Attachment) }
|
|
14
|
+
@attachments = attachments
|
|
15
|
+
elsif attachments
|
|
16
|
+
# Let parent class process other types of attachments
|
|
17
|
+
process_attachments(attachments)
|
|
18
|
+
end
|
|
11
19
|
end
|
|
12
20
|
|
|
13
21
|
# This is a workaround to allow the content object to be passed as the tool call
|
|
14
22
|
# to return audio or image attachments.
|
|
15
23
|
def to_s
|
|
16
|
-
|
|
24
|
+
text.to_s
|
|
17
25
|
end
|
|
18
26
|
end
|
|
19
27
|
end
|
data/lib/ruby_llm/mcp/tool.rb
CHANGED
|
@@ -25,7 +25,7 @@ module RubyLLM
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
class Tool < RubyLLM::Tool
|
|
28
|
-
attr_reader :name, :title, :description, :
|
|
28
|
+
attr_reader :name, :title, :description, :coordinator, :tool_response, :with_prefix
|
|
29
29
|
|
|
30
30
|
def initialize(coordinator, tool_response, with_prefix: false)
|
|
31
31
|
super()
|
|
@@ -35,18 +35,23 @@ module RubyLLM
|
|
|
35
35
|
@name = format_name(tool_response["name"])
|
|
36
36
|
@mcp_name = tool_response["name"]
|
|
37
37
|
@description = tool_response["description"].to_s
|
|
38
|
-
@parameters = create_parameters(tool_response["inputSchema"])
|
|
39
38
|
|
|
40
39
|
@input_schema = tool_response["inputSchema"]
|
|
41
40
|
@output_schema = tool_response["outputSchema"]
|
|
42
41
|
|
|
43
42
|
@annotations = tool_response["annotations"] ? Annotation.new(tool_response["annotations"]) : nil
|
|
43
|
+
|
|
44
|
+
@normalized_input_schema = normalize_if_invalid(@input_schema)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def display_name
|
|
47
48
|
"#{@coordinator.name}: #{@name}"
|
|
48
49
|
end
|
|
49
50
|
|
|
51
|
+
def params_schema
|
|
52
|
+
@normalized_input_schema
|
|
53
|
+
end
|
|
54
|
+
|
|
50
55
|
def execute(**params)
|
|
51
56
|
result = @coordinator.execute_tool(
|
|
52
57
|
name: @mcp_name,
|
|
@@ -83,7 +88,7 @@ module RubyLLM
|
|
|
83
88
|
{
|
|
84
89
|
name: @name,
|
|
85
90
|
description: @description,
|
|
86
|
-
|
|
91
|
+
params_schema: @@normalized_input_schema,
|
|
87
92
|
annotations: @annotations&.to_h
|
|
88
93
|
}
|
|
89
94
|
end
|
|
@@ -92,76 +97,6 @@ module RubyLLM
|
|
|
92
97
|
|
|
93
98
|
private
|
|
94
99
|
|
|
95
|
-
def create_parameters(schema)
|
|
96
|
-
params = {}
|
|
97
|
-
return params if schema["properties"].nil?
|
|
98
|
-
|
|
99
|
-
schema["properties"].each_key do |key|
|
|
100
|
-
param_data = schema.dig("properties", key)
|
|
101
|
-
param_data = expand_shorthand_type_to_anyof(param_data)
|
|
102
|
-
|
|
103
|
-
param = if param_data.key?("oneOf") || param_data.key?("anyOf") || param_data.key?("allOf")
|
|
104
|
-
process_union_parameter(key, param_data)
|
|
105
|
-
else
|
|
106
|
-
process_parameter(key, param_data)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
params[key] = param
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
params
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def process_union_parameter(key, param_data)
|
|
116
|
-
union_type = param_data.keys.first
|
|
117
|
-
param = RubyLLM::MCP::Parameter.new(
|
|
118
|
-
key,
|
|
119
|
-
type: :union,
|
|
120
|
-
title: param_data["title"],
|
|
121
|
-
desc: param_data["description"],
|
|
122
|
-
union_type: union_type
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
param.properties = param_data[union_type].map do |value|
|
|
126
|
-
expanded_value = expand_shorthand_type_to_anyof(value)
|
|
127
|
-
if expanded_value.key?("anyOf")
|
|
128
|
-
process_union_parameter(key, expanded_value)
|
|
129
|
-
else
|
|
130
|
-
process_parameter(key, value, lifted_type: param_data["type"])
|
|
131
|
-
end
|
|
132
|
-
end.compact
|
|
133
|
-
|
|
134
|
-
param
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def process_parameter(key, param_data, lifted_type: nil)
|
|
138
|
-
param = RubyLLM::MCP::Parameter.new(
|
|
139
|
-
key,
|
|
140
|
-
type: param_data["type"] || lifted_type || "string",
|
|
141
|
-
title: param_data["title"],
|
|
142
|
-
desc: param_data["description"],
|
|
143
|
-
required: param_data["required"],
|
|
144
|
-
default: param_data["default"]
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
if param.type == :array
|
|
148
|
-
items = param_data["items"]
|
|
149
|
-
param.items = items
|
|
150
|
-
if items.key?("properties")
|
|
151
|
-
param.properties = create_parameters(items)
|
|
152
|
-
end
|
|
153
|
-
if items.key?("enum")
|
|
154
|
-
param.enum = items["enum"]
|
|
155
|
-
end
|
|
156
|
-
elsif param.type == :object
|
|
157
|
-
if param_data.key?("properties")
|
|
158
|
-
param.properties = create_parameters(param_data)
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
param
|
|
163
|
-
end
|
|
164
|
-
|
|
165
100
|
def create_content_for_message(content)
|
|
166
101
|
case content["type"]
|
|
167
102
|
when "text"
|
|
@@ -205,19 +140,88 @@ module RubyLLM
|
|
|
205
140
|
end
|
|
206
141
|
end
|
|
207
142
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
# This keeps $ref references clean and provides a consistent structure for union types
|
|
211
|
-
#
|
|
212
|
-
# @param param_data [Hash] The parameter data that may contain a shorthand type array
|
|
213
|
-
# @return [Hash] The expanded parameter data with anyOf, or the original if not a shorthand
|
|
214
|
-
def expand_shorthand_type_to_anyof(param_data)
|
|
215
|
-
type = param_data["type"]
|
|
216
|
-
return param_data unless type.is_a?(Array)
|
|
143
|
+
def normalize_schema(schema)
|
|
144
|
+
return schema if schema.nil?
|
|
217
145
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
146
|
+
case schema
|
|
147
|
+
when Hash
|
|
148
|
+
normalize_hash_schema(schema)
|
|
149
|
+
when Array
|
|
150
|
+
normalize_array_schema(schema)
|
|
151
|
+
else
|
|
152
|
+
schema
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def normalize_hash_schema(schema)
|
|
157
|
+
normalized = schema.transform_values { |value| normalize_schema_value(value) }
|
|
158
|
+
ensure_object_properties(normalized)
|
|
159
|
+
normalized
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def normalize_array_schema(schema)
|
|
163
|
+
schema.map { |item| normalize_schema_value(item) }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def normalize_schema_value(value)
|
|
167
|
+
case value
|
|
168
|
+
when Hash
|
|
169
|
+
normalize_schema(value)
|
|
170
|
+
when Array
|
|
171
|
+
normalize_array_schema(value)
|
|
172
|
+
else
|
|
173
|
+
value
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def ensure_object_properties(schema)
|
|
178
|
+
if schema["type"] == "object" && !schema.key?("properties")
|
|
179
|
+
schema["properties"] = {}
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def normalize_if_invalid(schema)
|
|
184
|
+
return schema if schema.nil?
|
|
185
|
+
|
|
186
|
+
if valid_schema?(schema)
|
|
187
|
+
schema
|
|
188
|
+
else
|
|
189
|
+
normalize_schema(schema)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def valid_schema?(schema)
|
|
194
|
+
return true if schema.nil?
|
|
195
|
+
|
|
196
|
+
case schema
|
|
197
|
+
when Hash
|
|
198
|
+
valid_hash_schema?(schema)
|
|
199
|
+
when Array
|
|
200
|
+
schema.all? { |item| valid_schema?(item) }
|
|
201
|
+
else
|
|
202
|
+
true
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def valid_hash_schema?(schema)
|
|
207
|
+
# Check if this level has missing properties for object type
|
|
208
|
+
if schema["type"] == "object" && !schema.key?("properties")
|
|
209
|
+
return false
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Recursively check nested schemas
|
|
213
|
+
schema.each_value do |value|
|
|
214
|
+
return false unless valid_schema?(value)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
begin
|
|
218
|
+
JSON::Validator.validate!(schema, {})
|
|
219
|
+
true
|
|
220
|
+
rescue JSON::Schema::SchemaError
|
|
221
|
+
false
|
|
222
|
+
rescue JSON::Schema::ValidationError
|
|
223
|
+
true
|
|
224
|
+
end
|
|
221
225
|
end
|
|
222
226
|
end
|
|
223
227
|
end
|
data/lib/ruby_llm/mcp/version.rb
CHANGED
data/lib/ruby_llm/mcp.rb
CHANGED
|
@@ -62,9 +62,9 @@ module RubyLLM
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def support_complex_parameters!
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
warn "[DEPRECATION] RubyLLM::MCP.support_complex_parameters! is no longer needed " \
|
|
66
|
+
"and will be removed in version 0.8.0"
|
|
67
|
+
# No-op: Complex parameters are now supported by default
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def configure
|
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.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrick Vice
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '1.
|
|
46
|
+
version: '1.9'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '1.
|
|
53
|
+
version: '1.9'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: zeitwerk
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -97,13 +97,9 @@ files:
|
|
|
97
97
|
- lib/ruby_llm/mcp/notifications/cancelled.rb
|
|
98
98
|
- lib/ruby_llm/mcp/notifications/initialize.rb
|
|
99
99
|
- lib/ruby_llm/mcp/notifications/roots_list_change.rb
|
|
100
|
-
- lib/ruby_llm/mcp/parameter.rb
|
|
101
100
|
- lib/ruby_llm/mcp/progress.rb
|
|
102
101
|
- lib/ruby_llm/mcp/prompt.rb
|
|
103
102
|
- lib/ruby_llm/mcp/protocol.rb
|
|
104
|
-
- lib/ruby_llm/mcp/providers/anthropic/complex_parameter_support.rb
|
|
105
|
-
- lib/ruby_llm/mcp/providers/gemini/complex_parameter_support.rb
|
|
106
|
-
- lib/ruby_llm/mcp/providers/openai/complex_parameter_support.rb
|
|
107
103
|
- lib/ruby_llm/mcp/railtie.rb
|
|
108
104
|
- lib/ruby_llm/mcp/requests/completion_prompt.rb
|
|
109
105
|
- lib/ruby_llm/mcp/requests/completion_resource.rb
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "ruby_llm/tool"
|
|
4
|
-
|
|
5
|
-
module RubyLLM
|
|
6
|
-
module MCP
|
|
7
|
-
class Parameter < RubyLLM::Parameter
|
|
8
|
-
attr_accessor :items, :properties, :enum, :union_type, :default, :title
|
|
9
|
-
|
|
10
|
-
class << self
|
|
11
|
-
def all_mcp_parameters?(parameters)
|
|
12
|
-
parameters.is_a?(Hash) &&
|
|
13
|
-
parameters.any? &&
|
|
14
|
-
parameters.values.all? { |p| p.is_a?(RubyLLM::MCP::Parameter) }
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def initialize(name, type: "string", title: nil, desc: nil, required: true, default: nil, union_type: nil) # rubocop:disable Metrics/ParameterLists
|
|
19
|
-
super(name, type: type.to_sym, desc: desc, required: required)
|
|
20
|
-
@title = title
|
|
21
|
-
@properties = {}
|
|
22
|
-
@union_type = union_type
|
|
23
|
-
@default = default
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def item_type
|
|
27
|
-
@items&.dig("type")&.to_sym
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def as_json(*_args)
|
|
31
|
-
to_h
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def to_h
|
|
35
|
-
{
|
|
36
|
-
name: @name,
|
|
37
|
-
type: @type,
|
|
38
|
-
description: @desc,
|
|
39
|
-
required: @required,
|
|
40
|
-
default: @default,
|
|
41
|
-
union_type: @union_type,
|
|
42
|
-
items: @items&.to_h,
|
|
43
|
-
properties: @properties&.values,
|
|
44
|
-
enum: @enum
|
|
45
|
-
}
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyLLM
|
|
4
|
-
module MCP
|
|
5
|
-
module Providers
|
|
6
|
-
module Anthropic
|
|
7
|
-
module ComplexParameterSupport
|
|
8
|
-
module_function
|
|
9
|
-
|
|
10
|
-
def clean_parameters(parameters)
|
|
11
|
-
parameters.transform_values do |param|
|
|
12
|
-
mcp_build_properties(param).compact
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def required_parameters(parameters)
|
|
17
|
-
parameters.select { |_, param| param.required }.keys
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def mcp_build_properties(param) # rubocop:disable Metrics/MethodLength
|
|
21
|
-
case param.type
|
|
22
|
-
when :array
|
|
23
|
-
if param.item_type == :object
|
|
24
|
-
{
|
|
25
|
-
type: param.type,
|
|
26
|
-
title: param.title,
|
|
27
|
-
description: param.description,
|
|
28
|
-
items: { type: param.item_type, properties: clean_parameters(param.properties) }
|
|
29
|
-
}.compact
|
|
30
|
-
else
|
|
31
|
-
{
|
|
32
|
-
type: param.type,
|
|
33
|
-
title: param.title,
|
|
34
|
-
description: param.description,
|
|
35
|
-
default: param.default,
|
|
36
|
-
items: { type: param.item_type, enum: param.enum }.compact
|
|
37
|
-
}.compact
|
|
38
|
-
end
|
|
39
|
-
when :object
|
|
40
|
-
{
|
|
41
|
-
type: param.type,
|
|
42
|
-
title: param.title,
|
|
43
|
-
description: param.description,
|
|
44
|
-
properties: clean_parameters(param.properties),
|
|
45
|
-
required: required_parameters(param.properties)
|
|
46
|
-
}.compact
|
|
47
|
-
when :union
|
|
48
|
-
{
|
|
49
|
-
param.union_type => param.properties.map { |property| mcp_build_properties(property) }
|
|
50
|
-
}
|
|
51
|
-
else
|
|
52
|
-
{
|
|
53
|
-
type: param.type,
|
|
54
|
-
title: param.title,
|
|
55
|
-
description: param.description
|
|
56
|
-
}.compact
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
module RubyLLM::Providers::Anthropic::Tools
|
|
66
|
-
alias original_clean_parameters clean_parameters
|
|
67
|
-
alias original_required_parameters required_parameters
|
|
68
|
-
module_function :original_clean_parameters, :original_required_parameters
|
|
69
|
-
|
|
70
|
-
def clean_parameters(parameters)
|
|
71
|
-
if RubyLLM::MCP::Parameter.all_mcp_parameters?(parameters)
|
|
72
|
-
return RubyLLM::MCP::Providers::Anthropic::ComplexParameterSupport.clean_parameters(parameters)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
original_clean_parameters(parameters)
|
|
76
|
-
end
|
|
77
|
-
module_function :clean_parameters
|
|
78
|
-
|
|
79
|
-
def required_parameters(parameters)
|
|
80
|
-
if RubyLLM::MCP::Parameter.all_mcp_parameters?(parameters)
|
|
81
|
-
return RubyLLM::MCP::Providers::Anthropic::ComplexParameterSupport.required_parameters(parameters)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
original_required_parameters(parameters)
|
|
85
|
-
end
|
|
86
|
-
module_function :required_parameters
|
|
87
|
-
end
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyLLM
|
|
4
|
-
module MCP
|
|
5
|
-
module Providers
|
|
6
|
-
module Gemini
|
|
7
|
-
module ComplexParameterSupport
|
|
8
|
-
module_function
|
|
9
|
-
|
|
10
|
-
# Format tool parameters for Gemini API
|
|
11
|
-
def format_parameters(parameters)
|
|
12
|
-
{
|
|
13
|
-
type: "OBJECT",
|
|
14
|
-
properties: parameters.transform_values { |param| mcp_build_properties(param) },
|
|
15
|
-
required: parameters.select { |_, p| p.required }.keys.map(&:to_s)
|
|
16
|
-
}
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def mcp_build_properties(param) # rubocop:disable Metrics/MethodLength
|
|
20
|
-
properties = case param.type
|
|
21
|
-
when :array
|
|
22
|
-
if param.item_type == :object
|
|
23
|
-
{
|
|
24
|
-
type: param_type_for_gemini(param.type),
|
|
25
|
-
title: param.title,
|
|
26
|
-
description: param.description,
|
|
27
|
-
items: {
|
|
28
|
-
type: param_type_for_gemini(param.item_type),
|
|
29
|
-
properties: param.properties.transform_values { |value| mcp_build_properties(value) }
|
|
30
|
-
}
|
|
31
|
-
}.compact
|
|
32
|
-
else
|
|
33
|
-
{
|
|
34
|
-
type: param_type_for_gemini(param.type),
|
|
35
|
-
title: param.title,
|
|
36
|
-
description: param.description,
|
|
37
|
-
default: param.default,
|
|
38
|
-
items: { type: param_type_for_gemini(param.item_type), enum: param.enum }.compact
|
|
39
|
-
}.compact
|
|
40
|
-
end
|
|
41
|
-
when :object
|
|
42
|
-
{
|
|
43
|
-
type: param_type_for_gemini(param.type),
|
|
44
|
-
title: param.title,
|
|
45
|
-
description: param.description,
|
|
46
|
-
properties: param.properties.transform_values { |value| mcp_build_properties(value) },
|
|
47
|
-
required: param.properties.select { |_, p| p.required }.keys
|
|
48
|
-
}.compact
|
|
49
|
-
when :union
|
|
50
|
-
{
|
|
51
|
-
param.union_type => param.properties.map { |properties| mcp_build_properties(properties) }
|
|
52
|
-
}
|
|
53
|
-
else
|
|
54
|
-
{
|
|
55
|
-
type: param_type_for_gemini(param.type),
|
|
56
|
-
title: param.title,
|
|
57
|
-
description: param.description
|
|
58
|
-
}
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
properties.compact
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def param_type_for_gemini(type)
|
|
65
|
-
RubyLLM::Providers::Gemini::Tools.param_type_for_gemini(type)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
module RubyLLM::Providers::Gemini::Tools
|
|
74
|
-
alias original_format_parameters format_parameters
|
|
75
|
-
module_function :original_format_parameters
|
|
76
|
-
module_function :param_type_for_gemini
|
|
77
|
-
|
|
78
|
-
def format_parameters(parameters)
|
|
79
|
-
if RubyLLM::MCP::Parameter.all_mcp_parameters?(parameters)
|
|
80
|
-
return RubyLLM::MCP::Providers::Gemini::ComplexParameterSupport.format_parameters(parameters)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
original_format_parameters(parameters)
|
|
84
|
-
end
|
|
85
|
-
module_function :format_parameters
|
|
86
|
-
end
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyLLM
|
|
4
|
-
module MCP
|
|
5
|
-
module Providers
|
|
6
|
-
module OpenAI
|
|
7
|
-
module ComplexParameterSupport
|
|
8
|
-
module_function
|
|
9
|
-
|
|
10
|
-
def param_schema(param) # rubocop:disable Metrics/MethodLength
|
|
11
|
-
properties = case param.type
|
|
12
|
-
when :array
|
|
13
|
-
if param.item_type == :object
|
|
14
|
-
{
|
|
15
|
-
type: param.type,
|
|
16
|
-
title: param.title,
|
|
17
|
-
description: param.description,
|
|
18
|
-
items: {
|
|
19
|
-
type: param.item_type,
|
|
20
|
-
properties: param.properties.transform_values { |value| param_schema(value) }
|
|
21
|
-
}
|
|
22
|
-
}.compact
|
|
23
|
-
else
|
|
24
|
-
{
|
|
25
|
-
type: param.type,
|
|
26
|
-
title: param.title,
|
|
27
|
-
description: param.description,
|
|
28
|
-
default: param.default,
|
|
29
|
-
items: { type: param.item_type, enum: param.enum }.compact
|
|
30
|
-
}.compact
|
|
31
|
-
end
|
|
32
|
-
when :object
|
|
33
|
-
{
|
|
34
|
-
type: param.type,
|
|
35
|
-
title: param.title,
|
|
36
|
-
description: param.description,
|
|
37
|
-
properties: param.properties.transform_values { |value| param_schema(value) },
|
|
38
|
-
required: param.properties.select { |_, p| p.required }.keys
|
|
39
|
-
}.compact
|
|
40
|
-
when :union
|
|
41
|
-
{
|
|
42
|
-
param.union_type => param.properties.map { |property| param_schema(property) }
|
|
43
|
-
}
|
|
44
|
-
else
|
|
45
|
-
{
|
|
46
|
-
type: param.type,
|
|
47
|
-
title: param.title,
|
|
48
|
-
description: param.description
|
|
49
|
-
}.compact
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
properties.compact
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
module RubyLLM::Providers::OpenAI::Tools
|
|
61
|
-
alias original_param_schema param_schema
|
|
62
|
-
module_function :original_param_schema
|
|
63
|
-
|
|
64
|
-
def param_schema(param)
|
|
65
|
-
if param.is_a?(RubyLLM::MCP::Parameter)
|
|
66
|
-
return RubyLLM::MCP::Providers::OpenAI::ComplexParameterSupport.param_schema(param)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
original_param_schema(param)
|
|
70
|
-
end
|
|
71
|
-
module_function :param_schema
|
|
72
|
-
end
|