geminize 1.1.0 → 1.2.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/.memory_bank/activeContext.md +25 -1
- data/.memory_bank/progress.md +26 -13
- data/.memory_bank/projectbrief.md +16 -0
- data/.memory_bank/tasks.md +57 -13
- data/CHANGELOG.md +22 -0
- data/README.md +181 -0
- data/examples/function_calling.rb +218 -0
- data/examples/safety_settings.rb +82 -0
- data/lib/geminize/models/content_request_extensions.rb +219 -0
- data/lib/geminize/models/content_request_safety.rb +123 -0
- data/lib/geminize/models/content_response_extensions.rb +120 -0
- data/lib/geminize/models/function_declaration.rb +112 -0
- data/lib/geminize/models/function_response.rb +70 -0
- data/lib/geminize/models/safety_setting.rb +102 -0
- data/lib/geminize/models/tool.rb +47 -0
- data/lib/geminize/models/tool_config.rb +52 -0
- data/lib/geminize/module_extensions.rb +228 -0
- data/lib/geminize/module_safety.rb +135 -0
- data/lib/geminize/version.rb +1 -1
- data/lib/geminize.rb +12 -0
- metadata +13 -1
@@ -0,0 +1,228 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Geminize
|
4
|
+
class << self
|
5
|
+
# Generate text with function calling capabilities
|
6
|
+
# @param prompt [String] The input prompt
|
7
|
+
# @param functions [Array<Hash>] Array of function definitions
|
8
|
+
# @param model_name [String, nil] The model to use, defaults to the configured default model
|
9
|
+
# @param params [Hash] Additional parameters for generation
|
10
|
+
# @option params [Float] :temperature Controls randomness (0.0-1.0)
|
11
|
+
# @option params [Integer] :max_tokens Maximum tokens to generate
|
12
|
+
# @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
|
13
|
+
# @option params [Integer] :top_k Top-k value for sampling
|
14
|
+
# @option params [Array<String>] :stop_sequences Stop sequences to end generation
|
15
|
+
# @option params [String] :system_instruction System instruction to guide model behavior
|
16
|
+
# @option params [String] :tool_execution_mode Tool execution mode ("AUTO", "MANUAL", or "NONE")
|
17
|
+
# @param with_retries [Boolean] Whether to retry the generation if it fails
|
18
|
+
# @param max_retries [Integer] Maximum number of retries
|
19
|
+
# @param retry_delay [Float] Delay between retries in seconds
|
20
|
+
# @param client_options [Hash] Options for the HTTP client
|
21
|
+
# @return [Geminize::Models::ContentResponse] The generated response
|
22
|
+
# @raise [Geminize::Error] If the generation fails
|
23
|
+
# @example Generate text with a function call
|
24
|
+
# Geminize.generate_with_functions(
|
25
|
+
# "What's the weather in New York?",
|
26
|
+
# [
|
27
|
+
# {
|
28
|
+
# name: "get_weather",
|
29
|
+
# description: "Get the current weather in a location",
|
30
|
+
# parameters: {
|
31
|
+
# type: "object",
|
32
|
+
# properties: {
|
33
|
+
# location: {
|
34
|
+
# type: "string",
|
35
|
+
# description: "The city and state, e.g. New York, NY"
|
36
|
+
# },
|
37
|
+
# unit: {
|
38
|
+
# type: "string",
|
39
|
+
# enum: ["celsius", "fahrenheit"],
|
40
|
+
# description: "The unit of temperature"
|
41
|
+
# }
|
42
|
+
# },
|
43
|
+
# required: ["location"]
|
44
|
+
# }
|
45
|
+
# }
|
46
|
+
# ]
|
47
|
+
# )
|
48
|
+
def generate_with_functions(prompt, functions, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
|
49
|
+
validate_configuration!
|
50
|
+
|
51
|
+
# Initialize the generator
|
52
|
+
client = client_options ? Client.new(client_options) : Client.new
|
53
|
+
generator = TextGeneration.new(client)
|
54
|
+
|
55
|
+
# Parse functions
|
56
|
+
if functions.nil? || !functions.is_a?(Array) || functions.empty?
|
57
|
+
raise Geminize::ValidationError.new(
|
58
|
+
"Functions must be a non-empty array",
|
59
|
+
"INVALID_ARGUMENT"
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set up params with defaults
|
64
|
+
generation_params = params.dup
|
65
|
+
tool_execution_mode = generation_params.delete(:tool_execution_mode) || "AUTO"
|
66
|
+
with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
|
67
|
+
|
68
|
+
# Enhance the system instruction to ensure function calling
|
69
|
+
generation_params[:system_instruction] ||= ""
|
70
|
+
generation_params[:system_instruction] = "You are a helpful assistant. When you encounter a question that you can answer by calling a function, you must always use the provided function. Always respond using the function call format, not with your own text. " + generation_params[:system_instruction]
|
71
|
+
|
72
|
+
# Create the request
|
73
|
+
content_request = Models::ContentRequest.new(
|
74
|
+
prompt,
|
75
|
+
model_name || configuration.default_model,
|
76
|
+
generation_params
|
77
|
+
)
|
78
|
+
|
79
|
+
# Add functions to the request
|
80
|
+
functions.each do |function|
|
81
|
+
content_request.add_function(
|
82
|
+
function[:name],
|
83
|
+
function[:description],
|
84
|
+
function[:parameters]
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Set the tool config
|
89
|
+
content_request.set_tool_config(tool_execution_mode)
|
90
|
+
|
91
|
+
# Generate the response
|
92
|
+
if with_retries
|
93
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
94
|
+
else
|
95
|
+
generator.generate(content_request)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Generate JSON output from a prompt using the Gemini API
|
100
|
+
# @param prompt [String] The input prompt
|
101
|
+
# @param model_name [String, nil] The model to use, defaults to the configured default model
|
102
|
+
# @param params [Hash] Additional parameters for generation
|
103
|
+
# @option params [Float] :temperature Controls randomness (0.0-1.0)
|
104
|
+
# @option params [Integer] :max_tokens Maximum tokens to generate
|
105
|
+
# @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
|
106
|
+
# @option params [Integer] :top_k Top-k value for sampling
|
107
|
+
# @option params [Array<String>] :stop_sequences Stop sequences to end generation
|
108
|
+
# @option params [String] :system_instruction System instruction to guide model behavior
|
109
|
+
# @param with_retries [Boolean] Whether to retry the generation if it fails
|
110
|
+
# @param max_retries [Integer] Maximum number of retries
|
111
|
+
# @param retry_delay [Float] Delay between retries in seconds
|
112
|
+
# @param client_options [Hash] Options for the HTTP client
|
113
|
+
# @option params [Hash] :json_schema Schema for the JSON output (optional)
|
114
|
+
# @return [Geminize::Models::ContentResponse] The generated response with JSON content
|
115
|
+
# @raise [Geminize::Error] If the generation fails
|
116
|
+
# @example Generate JSON output
|
117
|
+
# response = Geminize.generate_json(
|
118
|
+
# "List 3 planets with their diameter",
|
119
|
+
# nil,
|
120
|
+
# system_instruction: "Return the information as a JSON array"
|
121
|
+
# )
|
122
|
+
# planets = response.json_response # Returns parsed JSON
|
123
|
+
def generate_json(prompt, model_name = nil, params = {}, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
|
124
|
+
validate_configuration!
|
125
|
+
|
126
|
+
# Initialize the generator
|
127
|
+
client = client_options ? Client.new(client_options) : Client.new
|
128
|
+
generator = TextGeneration.new(client)
|
129
|
+
|
130
|
+
# Set up params with defaults
|
131
|
+
generation_params = params.dup
|
132
|
+
with_retries = generation_params.delete(:with_retries) != false if generation_params.key?(:with_retries)
|
133
|
+
|
134
|
+
# Enhance the system instruction for JSON output
|
135
|
+
generation_params[:system_instruction] ||= ""
|
136
|
+
generation_params[:system_instruction] = "You must respond with valid JSON only, with no explanation or other text. " + generation_params[:system_instruction]
|
137
|
+
|
138
|
+
# Create the request
|
139
|
+
content_request = Models::ContentRequest.new(
|
140
|
+
prompt,
|
141
|
+
model_name || configuration.default_model,
|
142
|
+
generation_params
|
143
|
+
)
|
144
|
+
|
145
|
+
# Enable JSON mode
|
146
|
+
content_request.enable_json_mode
|
147
|
+
|
148
|
+
# Generate the response
|
149
|
+
if with_retries
|
150
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
151
|
+
else
|
152
|
+
generator.generate(content_request)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Process a function call by executing a provided block and returning the result to Gemini
|
157
|
+
# @param response [Geminize::Models::ContentResponse] The response containing a function call
|
158
|
+
# @param model_name [String, nil] The model to use for the followup, defaults to the configured default model
|
159
|
+
# @param with_retries [Boolean] Whether to retry the generation if it fails
|
160
|
+
# @param max_retries [Integer] Maximum number of retries
|
161
|
+
# @param retry_delay [Float] Delay between retries in seconds
|
162
|
+
# @param client_options [Hash] Options for the HTTP client
|
163
|
+
# @yield [function_name, args] Block to execute the function
|
164
|
+
# @yieldparam function_name [String] The name of the function to execute
|
165
|
+
# @yieldparam args [Hash] The arguments to pass to the function
|
166
|
+
# @yieldreturn [Hash, Array, String, Numeric, Boolean, nil] The result of the function
|
167
|
+
# @return [Geminize::Models::ContentResponse] The response after processing the function
|
168
|
+
# @raise [Geminize::Error] If processing fails
|
169
|
+
# @example Process a function call
|
170
|
+
# response = Geminize.generate_with_functions("What's the weather in New York?", [...])
|
171
|
+
# if response.has_function_call?
|
172
|
+
# final_response = Geminize.process_function_call(response) do |function_name, args|
|
173
|
+
# if function_name == "get_weather"
|
174
|
+
# # Call a real weather API here
|
175
|
+
# { temperature: 72, conditions: "sunny" }
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
# puts final_response.text
|
179
|
+
# end
|
180
|
+
def process_function_call(response, model_name = nil, with_retries: true, max_retries: 3, retry_delay: 1.0, client_options: nil)
|
181
|
+
validate_configuration!
|
182
|
+
|
183
|
+
# Ensure a block is provided
|
184
|
+
unless block_given?
|
185
|
+
raise Geminize::ValidationError.new(
|
186
|
+
"A block must be provided to process the function call",
|
187
|
+
"INVALID_ARGUMENT"
|
188
|
+
)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Ensure the response has a function call
|
192
|
+
unless response.has_function_call?
|
193
|
+
raise Geminize::ValidationError.new(
|
194
|
+
"The response does not contain a function call",
|
195
|
+
"INVALID_ARGUMENT"
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Extract function call information
|
200
|
+
function_call = response.function_call
|
201
|
+
function_name = function_call.name
|
202
|
+
function_args = function_call.response
|
203
|
+
|
204
|
+
# Call the provided block with the function information
|
205
|
+
result = yield(function_name, function_args)
|
206
|
+
|
207
|
+
# Create a function response
|
208
|
+
Models::FunctionResponse.new(function_name, result)
|
209
|
+
|
210
|
+
# Initialize the generator
|
211
|
+
client = client_options ? Client.new(client_options) : Client.new
|
212
|
+
generator = TextGeneration.new(client)
|
213
|
+
|
214
|
+
# Create a request with the function result
|
215
|
+
content_request = Models::ContentRequest.new(
|
216
|
+
"Function #{function_name} returned: #{result.inspect}",
|
217
|
+
model_name || configuration.default_model
|
218
|
+
)
|
219
|
+
|
220
|
+
# Generate the response
|
221
|
+
if with_retries
|
222
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
223
|
+
else
|
224
|
+
generator.generate(content_request)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Geminize
|
4
|
+
class << self
|
5
|
+
# Generate text with custom safety settings
|
6
|
+
# @param prompt [String] The input prompt
|
7
|
+
# @param safety_settings [Array<Hash>] Array of safety setting definitions
|
8
|
+
# @param model_name [String, nil] The model to use (optional)
|
9
|
+
# @param params [Hash] Additional generation parameters
|
10
|
+
# @option params [Float] :temperature Controls randomness (0.0-1.0)
|
11
|
+
# @option params [Integer] :max_tokens Maximum tokens to generate
|
12
|
+
# @option params [Float] :top_p Top-p value for nucleus sampling (0.0-1.0)
|
13
|
+
# @option params [Integer] :top_k Top-k value for sampling
|
14
|
+
# @option params [Array<String>] :stop_sequences Stop sequences to end generation
|
15
|
+
# @option params [String] :system_instruction System instruction to guide model behavior
|
16
|
+
# @option params [Boolean] :with_retries Enable retries for transient errors (default: true)
|
17
|
+
# @option params [Integer] :max_retries Maximum retry attempts (default: 3)
|
18
|
+
# @option params [Float] :retry_delay Initial delay between retries in seconds (default: 1.0)
|
19
|
+
# @option params [Hash] :client_options Options to pass to the client
|
20
|
+
# @return [Geminize::Models::ContentResponse] The generation response
|
21
|
+
# @raise [Geminize::GeminizeError] If the request fails
|
22
|
+
# @example Generate text with specific safety settings
|
23
|
+
# Geminize.generate_with_safety_settings(
|
24
|
+
# "Tell me a scary story",
|
25
|
+
# [
|
26
|
+
# {category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_MEDIUM_AND_ABOVE"},
|
27
|
+
# {category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_LOW_AND_ABOVE"}
|
28
|
+
# ]
|
29
|
+
# )
|
30
|
+
def generate_with_safety_settings(prompt, safety_settings, model_name = nil, params = {})
|
31
|
+
validate_configuration!
|
32
|
+
|
33
|
+
# Extract special options
|
34
|
+
with_retries = params.delete(:with_retries) != false # Default to true
|
35
|
+
max_retries = params.delete(:max_retries) || 3
|
36
|
+
retry_delay = params.delete(:retry_delay) || 1.0
|
37
|
+
client_options = params.delete(:client_options) || {}
|
38
|
+
|
39
|
+
# Create the generator and content request
|
40
|
+
generator = TextGeneration.new(nil, client_options)
|
41
|
+
content_request = Models::ContentRequest.new(
|
42
|
+
prompt,
|
43
|
+
model_name || configuration.default_model,
|
44
|
+
params
|
45
|
+
)
|
46
|
+
|
47
|
+
# Add safety settings to the request
|
48
|
+
safety_settings.each do |setting|
|
49
|
+
content_request.add_safety_setting(
|
50
|
+
setting[:category],
|
51
|
+
setting[:threshold]
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate with or without retries
|
56
|
+
if with_retries
|
57
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
58
|
+
else
|
59
|
+
generator.generate(content_request)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Generate text with maximum safety (blocks most potentially harmful content)
|
64
|
+
# @param prompt [String] The input prompt
|
65
|
+
# @param model_name [String, nil] The model to use (optional)
|
66
|
+
# @param params [Hash] Additional generation parameters
|
67
|
+
# @return [Geminize::Models::ContentResponse] The generation response
|
68
|
+
# @raise [Geminize::GeminizeError] If the request fails
|
69
|
+
# @example Generate text with maximum safety
|
70
|
+
# Geminize.generate_text_safe("Tell me about conflicts", nil, temperature: 0.7)
|
71
|
+
def generate_text_safe(prompt, model_name = nil, params = {})
|
72
|
+
validate_configuration!
|
73
|
+
|
74
|
+
# Extract special options
|
75
|
+
with_retries = params.delete(:with_retries) != false # Default to true
|
76
|
+
max_retries = params.delete(:max_retries) || 3
|
77
|
+
retry_delay = params.delete(:retry_delay) || 1.0
|
78
|
+
client_options = params.delete(:client_options) || {}
|
79
|
+
|
80
|
+
# Create the generator and content request
|
81
|
+
generator = TextGeneration.new(nil, client_options)
|
82
|
+
content_request = Models::ContentRequest.new(
|
83
|
+
prompt,
|
84
|
+
model_name || configuration.default_model,
|
85
|
+
params
|
86
|
+
)
|
87
|
+
|
88
|
+
# Set maximum safety (block low and above)
|
89
|
+
content_request.block_all_harmful_content
|
90
|
+
|
91
|
+
# Generate with or without retries
|
92
|
+
if with_retries
|
93
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
94
|
+
else
|
95
|
+
generator.generate(content_request)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Generate text with minimum safety (blocks only high-risk content)
|
100
|
+
# @param prompt [String] The input prompt
|
101
|
+
# @param model_name [String, nil] The model to use (optional)
|
102
|
+
# @param params [Hash] Additional generation parameters
|
103
|
+
# @return [Geminize::Models::ContentResponse] The generation response
|
104
|
+
# @raise [Geminize::GeminizeError] If the request fails
|
105
|
+
# @example Generate text with minimum safety
|
106
|
+
# Geminize.generate_text_permissive("Tell me about conflicts", nil, temperature: 0.7)
|
107
|
+
def generate_text_permissive(prompt, model_name = nil, params = {})
|
108
|
+
validate_configuration!
|
109
|
+
|
110
|
+
# Extract special options
|
111
|
+
with_retries = params.delete(:with_retries) != false # Default to true
|
112
|
+
max_retries = params.delete(:max_retries) || 3
|
113
|
+
retry_delay = params.delete(:retry_delay) || 1.0
|
114
|
+
client_options = params.delete(:client_options) || {}
|
115
|
+
|
116
|
+
# Create the generator and content request
|
117
|
+
generator = TextGeneration.new(nil, client_options)
|
118
|
+
content_request = Models::ContentRequest.new(
|
119
|
+
prompt,
|
120
|
+
model_name || configuration.default_model,
|
121
|
+
params
|
122
|
+
)
|
123
|
+
|
124
|
+
# Set minimum safety (block only high risk)
|
125
|
+
content_request.block_only_high_risk_content
|
126
|
+
|
127
|
+
# Generate with or without retries
|
128
|
+
if with_retries
|
129
|
+
generator.generate_with_retries(content_request, max_retries, retry_delay)
|
130
|
+
else
|
131
|
+
generator.generate(content_request)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/lib/geminize/version.rb
CHANGED
data/lib/geminize.rb
CHANGED
@@ -28,6 +28,11 @@ require_relative "geminize/models/memory"
|
|
28
28
|
require_relative "geminize/models/conversation"
|
29
29
|
require_relative "geminize/models/embedding_request"
|
30
30
|
require_relative "geminize/models/embedding_response"
|
31
|
+
require_relative "geminize/models/function_declaration"
|
32
|
+
require_relative "geminize/models/tool"
|
33
|
+
require_relative "geminize/models/tool_config"
|
34
|
+
require_relative "geminize/models/function_response"
|
35
|
+
require_relative "geminize/models/safety_setting"
|
31
36
|
require_relative "geminize/request_builder"
|
32
37
|
require_relative "geminize/vector_utils"
|
33
38
|
require_relative "geminize/text_generation"
|
@@ -37,6 +42,13 @@ require_relative "geminize/conversation_repository"
|
|
37
42
|
require_relative "geminize/conversation_service"
|
38
43
|
require_relative "geminize/model_info"
|
39
44
|
|
45
|
+
# Load extensions
|
46
|
+
require_relative "geminize/models/content_request_extensions"
|
47
|
+
require_relative "geminize/models/content_response_extensions"
|
48
|
+
require_relative "geminize/models/content_request_safety"
|
49
|
+
require_relative "geminize/module_extensions"
|
50
|
+
require_relative "geminize/module_safety"
|
51
|
+
|
40
52
|
# Main module for the Geminize gem
|
41
53
|
module Geminize
|
42
54
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geminize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nhat Long Nguyen
|
@@ -184,9 +184,11 @@ files:
|
|
184
184
|
- examples/README.md
|
185
185
|
- examples/configuration.rb
|
186
186
|
- examples/embeddings.rb
|
187
|
+
- examples/function_calling.rb
|
187
188
|
- examples/models_api.rb
|
188
189
|
- examples/multimodal.rb
|
189
190
|
- examples/ruby.png
|
191
|
+
- examples/safety_settings.rb
|
190
192
|
- examples/system_instructions.rb
|
191
193
|
- lib/geminize.rb
|
192
194
|
- lib/geminize/chat.rb
|
@@ -203,15 +205,25 @@ files:
|
|
203
205
|
- lib/geminize/models/chat_request.rb
|
204
206
|
- lib/geminize/models/chat_response.rb
|
205
207
|
- lib/geminize/models/content_request.rb
|
208
|
+
- lib/geminize/models/content_request_extensions.rb
|
209
|
+
- lib/geminize/models/content_request_safety.rb
|
206
210
|
- lib/geminize/models/content_response.rb
|
211
|
+
- lib/geminize/models/content_response_extensions.rb
|
207
212
|
- lib/geminize/models/conversation.rb
|
208
213
|
- lib/geminize/models/embedding_request.rb
|
209
214
|
- lib/geminize/models/embedding_response.rb
|
215
|
+
- lib/geminize/models/function_declaration.rb
|
216
|
+
- lib/geminize/models/function_response.rb
|
210
217
|
- lib/geminize/models/memory.rb
|
211
218
|
- lib/geminize/models/message.rb
|
212
219
|
- lib/geminize/models/model.rb
|
213
220
|
- lib/geminize/models/model_list.rb
|
221
|
+
- lib/geminize/models/safety_setting.rb
|
214
222
|
- lib/geminize/models/stream_response.rb
|
223
|
+
- lib/geminize/models/tool.rb
|
224
|
+
- lib/geminize/models/tool_config.rb
|
225
|
+
- lib/geminize/module_extensions.rb
|
226
|
+
- lib/geminize/module_safety.rb
|
215
227
|
- lib/geminize/request_builder.rb
|
216
228
|
- lib/geminize/text_generation.rb
|
217
229
|
- lib/geminize/validators.rb
|