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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Geminize
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
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.1.0
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