geminize 1.0.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/.cursor/mcp.json +3 -0
- data/.cursor/rules/isolation_rules/Core/command-execution.mdc +235 -0
- data/.cursor/rules/isolation_rules/Core/complexity-decision-tree.mdc +187 -0
- data/.cursor/rules/isolation_rules/Core/creative-phase-enforcement.mdc +145 -0
- data/.cursor/rules/isolation_rules/Core/creative-phase-metrics.mdc +195 -0
- data/.cursor/rules/isolation_rules/Core/file-verification.mdc +198 -0
- data/.cursor/rules/isolation_rules/Core/platform-awareness.mdc +71 -0
- data/.cursor/rules/isolation_rules/Level3/planning-comprehensive.mdc +159 -0
- data/.cursor/rules/isolation_rules/Level3/task-tracking-intermediate.mdc +135 -0
- data/.cursor/rules/isolation_rules/Phases/CreativePhase/creative-phase-architecture.mdc +187 -0
- data/.cursor/rules/isolation_rules/main.mdc +123 -0
- data/.cursor/rules/isolation_rules/visual-maps/archive-mode-map.mdc +277 -0
- data/.cursor/rules/isolation_rules/visual-maps/creative-mode-map.mdc +224 -0
- data/.cursor/rules/isolation_rules/visual-maps/implement-mode-map.mdc +321 -0
- data/.cursor/rules/isolation_rules/visual-maps/plan-mode-map.mdc +269 -0
- data/.cursor/rules/isolation_rules/visual-maps/qa-mode-map.mdc +495 -0
- data/.cursor/rules/isolation_rules/visual-maps/reflect-mode-map.mdc +234 -0
- data/.cursor/rules/isolation_rules/visual-maps/van-mode-map.mdc +902 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-complexity-determination.mdc +60 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-file-verification.mdc +49 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-mode-map.mdc +49 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-platform-detection.mdc +50 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-checks/build-test.mdc +117 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-checks/config-check.mdc +103 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-checks/dependency-check.mdc +147 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-checks/environment-check.mdc +104 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-checks/file-verification.mdc +1 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-main.mdc +142 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-utils/common-fixes.mdc +92 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-utils/mode-transitions.mdc +101 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-utils/reports.mdc +149 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-utils/rule-calling-guide.mdc +66 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-utils/rule-calling-help.mdc +19 -0
- data/.cursor/rules/isolation_rules/visual-maps/van_mode_split/van-qa-validation.md.old +363 -0
- data/.env.example +7 -0
- data/.memory_bank/activeContext.md +102 -0
- data/.memory_bank/progress.md +93 -0
- data/.memory_bank/projectbrief.md +45 -0
- data/.memory_bank/systemPatterns.md +90 -0
- data/.memory_bank/tasks.md +142 -0
- data/.memory_bank/techContext.md +73 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +42 -0
- data/README.md +223 -5
- data/examples/function_calling.rb +218 -0
- data/examples/models_api.rb +125 -0
- data/examples/safety_settings.rb +82 -0
- data/lib/geminize/configuration.rb +4 -4
- data/lib/geminize/model_info.rb +87 -8
- 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/model.rb +101 -109
- data/lib/geminize/models/model_list.rb +70 -28
- 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/request_builder.rb +29 -0
- data/lib/geminize/version.rb +1 -1
- data/lib/geminize.rb +83 -14
- metadata +57 -2
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "geminize"
|
6
|
+
require "json"
|
7
|
+
|
8
|
+
# Configure the API key
|
9
|
+
Geminize.configure do |config|
|
10
|
+
config.api_key = ENV["GEMINI_API_KEY"] # Make sure to set your API key in the environment
|
11
|
+
config.default_model = "gemini-1.5-pro-latest" # Use the latest model that supports function calling
|
12
|
+
end
|
13
|
+
|
14
|
+
# Define a weather function that can handle a location and unit
|
15
|
+
def get_weather(location, unit = "celsius")
|
16
|
+
puts "Getting weather for #{location} in #{unit}..."
|
17
|
+
|
18
|
+
# In a real implementation, this would call a weather API
|
19
|
+
# For this example, we'll return mock data
|
20
|
+
case location.downcase
|
21
|
+
when /new york/
|
22
|
+
{temperature: (unit == "celsius") ? 22 : 72, conditions: "Sunny", humidity: 45}
|
23
|
+
when /london/
|
24
|
+
{temperature: (unit == "celsius") ? 15 : 59, conditions: "Rainy", humidity: 80}
|
25
|
+
when /tokyo/
|
26
|
+
{temperature: (unit == "celsius") ? 26 : 79, conditions: "Partly Cloudy", humidity: 65}
|
27
|
+
else
|
28
|
+
{temperature: (unit == "celsius") ? 20 : 68, conditions: "Unknown", humidity: 50}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Enhanced weather function that can handle a batch of locations
|
33
|
+
def get_weather_batch(locations, unit = "celsius")
|
34
|
+
if locations.is_a?(Array)
|
35
|
+
results = {}
|
36
|
+
locations.each do |location|
|
37
|
+
results[location] = get_weather(location, unit)
|
38
|
+
end
|
39
|
+
results
|
40
|
+
else
|
41
|
+
{locations => get_weather(locations, unit)}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Define a function schema for get_weather
|
46
|
+
weather_function = {
|
47
|
+
name: "get_weather",
|
48
|
+
description: "Get the current weather in a location",
|
49
|
+
parameters: {
|
50
|
+
type: "object",
|
51
|
+
properties: {
|
52
|
+
location: {
|
53
|
+
type: "string",
|
54
|
+
description: "The city and state or country, e.g., 'New York, NY' or 'London, UK'"
|
55
|
+
},
|
56
|
+
unit: {
|
57
|
+
type: "string",
|
58
|
+
enum: ["celsius", "fahrenheit"],
|
59
|
+
description: "The unit of temperature"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
required: ["location"]
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
# Define a batch weather function schema that can handle multiple locations
|
67
|
+
batch_weather_function = {
|
68
|
+
name: "get_weather_batch",
|
69
|
+
description: "Get the current weather for multiple locations at once",
|
70
|
+
parameters: {
|
71
|
+
type: "object",
|
72
|
+
properties: {
|
73
|
+
locations: {
|
74
|
+
type: "array",
|
75
|
+
items: {
|
76
|
+
type: "string"
|
77
|
+
},
|
78
|
+
description: "List of cities, e.g., ['New York, NY', 'London, UK', 'Tokyo, Japan']"
|
79
|
+
},
|
80
|
+
unit: {
|
81
|
+
type: "string",
|
82
|
+
enum: ["celsius", "fahrenheit"],
|
83
|
+
description: "The unit of temperature"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
required: ["locations"]
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
puts "==========================================="
|
91
|
+
puts "= GEMINIZE FUNCTION CALLING & JSON EXAMPLES ="
|
92
|
+
puts "==========================================="
|
93
|
+
|
94
|
+
puts "\n=== FUNCTION CALLING EXAMPLE ==="
|
95
|
+
puts "Asking Gemini about the weather in New York..."
|
96
|
+
|
97
|
+
begin
|
98
|
+
# Generate a response with the function definition
|
99
|
+
response = Geminize.generate_with_functions(
|
100
|
+
"What's the weather like in New York?",
|
101
|
+
[weather_function],
|
102
|
+
nil,
|
103
|
+
{temperature: 0.2}
|
104
|
+
)
|
105
|
+
|
106
|
+
# Check if the model wants to call a function
|
107
|
+
if response.has_function_call?
|
108
|
+
function_call = response.function_call
|
109
|
+
puts "Model wants to call function: #{function_call.name}"
|
110
|
+
puts "With arguments: #{function_call.response.inspect}"
|
111
|
+
|
112
|
+
function_name = function_call.name
|
113
|
+
args = function_call.response
|
114
|
+
|
115
|
+
if function_name == "get_weather"
|
116
|
+
location = args["location"]
|
117
|
+
unit = args["unit"] || "celsius"
|
118
|
+
|
119
|
+
# Call our weather function
|
120
|
+
weather_data = get_weather(location, unit)
|
121
|
+
puts "Weather data for #{location}: #{weather_data.inspect}"
|
122
|
+
|
123
|
+
# Process the function result
|
124
|
+
final_response = Geminize.process_function_call(response) do |name, arguments|
|
125
|
+
get_weather(arguments["location"], arguments["unit"])
|
126
|
+
end
|
127
|
+
|
128
|
+
puts "\nFinal response from Gemini:"
|
129
|
+
puts final_response.text
|
130
|
+
else
|
131
|
+
puts "Unexpected function call: #{function_name}"
|
132
|
+
end
|
133
|
+
else
|
134
|
+
puts "Model did not request to call a function."
|
135
|
+
puts "Response: #{response.text}"
|
136
|
+
end
|
137
|
+
rescue => e
|
138
|
+
puts "Error during function calling: #{e.message}"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Example of using JSON mode
|
142
|
+
puts "\n\n=== JSON MODE EXAMPLE ==="
|
143
|
+
puts "Using JSON mode to get weather data in structured format..."
|
144
|
+
|
145
|
+
begin
|
146
|
+
json_response = Geminize.generate_json(
|
147
|
+
"Get the current temperature and weather conditions for New York.",
|
148
|
+
nil,
|
149
|
+
{
|
150
|
+
system_instruction: "Return a JSON object with temperature in celsius and conditions."
|
151
|
+
}
|
152
|
+
)
|
153
|
+
|
154
|
+
if json_response.has_json_response?
|
155
|
+
puts "Structured JSON response:"
|
156
|
+
puts JSON.pretty_generate(json_response.json_response)
|
157
|
+
else
|
158
|
+
puts "Raw text response (not valid JSON):"
|
159
|
+
puts json_response.text
|
160
|
+
end
|
161
|
+
rescue => e
|
162
|
+
puts "Error during JSON mode: #{e.message}"
|
163
|
+
end
|
164
|
+
|
165
|
+
puts "\n\n=== BATCH FUNCTION CALL EXAMPLE ==="
|
166
|
+
puts "Using batch function to efficiently get weather for multiple cities at once..."
|
167
|
+
|
168
|
+
begin
|
169
|
+
# Use a batch function to get all cities at once (more efficient)
|
170
|
+
response = Geminize.generate_with_functions(
|
171
|
+
"I need weather information for New York, Tokyo, and London. Please get all this information in a single function call.",
|
172
|
+
[batch_weather_function],
|
173
|
+
nil,
|
174
|
+
{temperature: 0.2}
|
175
|
+
)
|
176
|
+
|
177
|
+
# Check if the model wants to call the batch function
|
178
|
+
if response.has_function_call?
|
179
|
+
function_call = response.function_call
|
180
|
+
puts "Model wants to call function: #{function_call.name}"
|
181
|
+
puts "With arguments: #{function_call.response.inspect}"
|
182
|
+
|
183
|
+
function_name = function_call.name
|
184
|
+
args = function_call.response
|
185
|
+
|
186
|
+
if function_name == "get_weather_batch"
|
187
|
+
locations = args["locations"]
|
188
|
+
unit = args["unit"] || "celsius"
|
189
|
+
|
190
|
+
# Get weather for all locations at once
|
191
|
+
weather_data = get_weather_batch(locations, unit)
|
192
|
+
puts "Weather data for multiple locations: #{weather_data.inspect}"
|
193
|
+
|
194
|
+
# Process the function result with a single API call
|
195
|
+
final_response = Geminize.process_function_call(response) do |name, arguments|
|
196
|
+
get_weather_batch(arguments["locations"], arguments["unit"])
|
197
|
+
end
|
198
|
+
|
199
|
+
puts "\nFinal response from Gemini:"
|
200
|
+
puts final_response.text
|
201
|
+
else
|
202
|
+
puts "Unexpected function call: #{function_name}"
|
203
|
+
end
|
204
|
+
else
|
205
|
+
puts "Model did not request to call a function."
|
206
|
+
puts "Response: #{response.text}"
|
207
|
+
end
|
208
|
+
rescue => e
|
209
|
+
puts "Error during batch function calling: #{e.message}"
|
210
|
+
puts "\nNOTE: If you hit a quota limit, try:"
|
211
|
+
puts "1. Using a paid API key with higher quotas"
|
212
|
+
puts "2. Reducing the number of examples you run"
|
213
|
+
puts "3. Adding delays between API calls"
|
214
|
+
end
|
215
|
+
|
216
|
+
puts "\n==========================================="
|
217
|
+
puts "= END OF EXAMPLES ="
|
218
|
+
puts "==========================================="
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "geminize"
|
6
|
+
require "pp"
|
7
|
+
|
8
|
+
# Configure the library with your API key
|
9
|
+
Geminize.configure do |config|
|
10
|
+
# Load API key from .env file or environment variables
|
11
|
+
config.api_key = ENV["GEMINI_API_KEY"]
|
12
|
+
# Use the latest API version
|
13
|
+
config.api_version = "v1beta"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Helper method to display model information
|
17
|
+
def display_model(model)
|
18
|
+
puts "========================"
|
19
|
+
puts "Model: #{model.display_name} (#{model.name})"
|
20
|
+
puts "Base Model ID: #{model.base_model_id}"
|
21
|
+
puts "Version: #{model.version}"
|
22
|
+
puts "Description: #{model.description}"
|
23
|
+
puts "Input Token Limit: #{model.input_token_limit}"
|
24
|
+
puts "Output Token Limit: #{model.output_token_limit}"
|
25
|
+
puts "Temperature: #{model.temperature}"
|
26
|
+
puts "Max Temperature: #{model.max_temperature}"
|
27
|
+
puts "Top P: #{model.top_p}"
|
28
|
+
puts "Top K: #{model.top_k}"
|
29
|
+
puts "Supported Methods: #{model.supported_generation_methods.join(", ")}"
|
30
|
+
puts "Capabilities:"
|
31
|
+
puts " - Content Generation: #{model.supports_content_generation?}"
|
32
|
+
puts " - Chat: #{model.supports_message_generation?}"
|
33
|
+
puts " - Embedding: #{model.supports_embedding?}"
|
34
|
+
puts " - Streaming: #{model.supports_streaming?}"
|
35
|
+
puts "========================\n\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
puts "=== MODELS API EXAMPLES ==="
|
39
|
+
|
40
|
+
# Example 1: List models (first page)
|
41
|
+
puts "\n=== Example 1: List first page of models ==="
|
42
|
+
begin
|
43
|
+
model_list = Geminize.list_models(page_size: 5)
|
44
|
+
puts "Found #{model_list.size} models on first page"
|
45
|
+
puts "Has more pages: #{model_list.has_more_pages?}"
|
46
|
+
puts "Next page token: #{model_list.next_page_token}"
|
47
|
+
puts "\nFirst model details:"
|
48
|
+
display_model(model_list.first) if model_list.first
|
49
|
+
rescue => e
|
50
|
+
puts "Error listing models: #{e.message}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Example 2: Get detailed info for a specific model
|
54
|
+
puts "\n=== Example 2: Get specific model info ==="
|
55
|
+
begin
|
56
|
+
model = Geminize.get_model("gemini-1.5-flash")
|
57
|
+
puts "Retrieved model details:"
|
58
|
+
display_model(model)
|
59
|
+
rescue => e
|
60
|
+
puts "Error getting model: #{e.message}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Example 3: Get all models (handling pagination)
|
64
|
+
puts "\n=== Example 3: Get all models (handling pagination) ==="
|
65
|
+
begin
|
66
|
+
all_models = Geminize.list_all_models
|
67
|
+
puts "Retrieved #{all_models.size} models in total"
|
68
|
+
rescue => e
|
69
|
+
puts "Error listing all models: #{e.message}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Example 4: Filter models by capability
|
73
|
+
puts "\n=== Example 4: Filter models by capability ==="
|
74
|
+
begin
|
75
|
+
# Get models that support embedding
|
76
|
+
embedding_models = Geminize.get_embedding_models
|
77
|
+
puts "Found #{embedding_models.size} models that support embeddings"
|
78
|
+
|
79
|
+
# Get models that support content generation
|
80
|
+
content_models = Geminize.get_content_generation_models
|
81
|
+
puts "Found #{content_models.size} models that support content generation"
|
82
|
+
|
83
|
+
# Get models that support chat
|
84
|
+
chat_models = Geminize.get_chat_models
|
85
|
+
puts "Found #{chat_models.size} models that support chat"
|
86
|
+
|
87
|
+
# Get models that support streaming
|
88
|
+
streaming_models = Geminize.get_streaming_models
|
89
|
+
puts "Found #{streaming_models.size} models that support streaming"
|
90
|
+
rescue => e
|
91
|
+
puts "Error filtering models: #{e.message}"
|
92
|
+
end
|
93
|
+
|
94
|
+
# Example 5: Filter models by specific method
|
95
|
+
puts "\n=== Example 5: Filter models by specific method ==="
|
96
|
+
begin
|
97
|
+
method_models = Geminize.get_models_by_method("generateContent")
|
98
|
+
puts "Found #{method_models.size} models that support generateContent"
|
99
|
+
|
100
|
+
# Display a specific model from the filtered list
|
101
|
+
if method_models.size > 0
|
102
|
+
puts "\nExample of a model supporting generateContent:"
|
103
|
+
display_model(method_models.first)
|
104
|
+
end
|
105
|
+
rescue => e
|
106
|
+
puts "Error filtering by method: #{e.message}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Example 6: Model comparison
|
110
|
+
puts "\n=== Example 6: Compare token limits ==="
|
111
|
+
begin
|
112
|
+
all_models = Geminize.list_all_models
|
113
|
+
|
114
|
+
# Filter to models with higher token limits
|
115
|
+
high_capacity_models = all_models.filter_by_min_input_tokens(100_000)
|
116
|
+
|
117
|
+
puts "Models with 100k+ input token limits:"
|
118
|
+
high_capacity_models.each do |model|
|
119
|
+
puts " - #{model.display_name}: #{model.input_token_limit} input tokens"
|
120
|
+
end
|
121
|
+
rescue => e
|
122
|
+
puts "Error comparing models: #{e.message}"
|
123
|
+
end
|
124
|
+
|
125
|
+
puts "\n=== Examples Complete ==="
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "geminize"
|
6
|
+
|
7
|
+
# Configure the API key
|
8
|
+
Geminize.configure do |config|
|
9
|
+
config.api_key = ENV["GEMINI_API_KEY"] # Make sure to set your API key in the environment
|
10
|
+
config.default_model = "gemini-1.5-pro-latest" # Use the latest model
|
11
|
+
end
|
12
|
+
|
13
|
+
# A prompt that might trigger safety filters
|
14
|
+
POTENTIALLY_SENSITIVE_PROMPT = "Describe a violent conflict scene from a movie"
|
15
|
+
|
16
|
+
puts "1. Generating with default safety settings:"
|
17
|
+
begin
|
18
|
+
response = Geminize.generate_text(POTENTIALLY_SENSITIVE_PROMPT, nil, temperature: 0.2)
|
19
|
+
puts "Default response:\n#{response.text}\n\n"
|
20
|
+
rescue Geminize::GeminizeError => e
|
21
|
+
puts "Error with default settings: #{e.message}\n\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "2. Generating with maximum safety (blocking most potentially harmful content):"
|
25
|
+
begin
|
26
|
+
response = Geminize.generate_text_safe(POTENTIALLY_SENSITIVE_PROMPT, nil, temperature: 0.2)
|
27
|
+
puts "Maximum safety response:\n#{response.text}\n\n"
|
28
|
+
rescue Geminize::GeminizeError => e
|
29
|
+
puts "Error with maximum safety: #{e.message}\n\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
puts "3. Generating with minimum safety (blocking only high-risk content):"
|
33
|
+
begin
|
34
|
+
response = Geminize.generate_text_permissive(POTENTIALLY_SENSITIVE_PROMPT, nil, temperature: 0.2)
|
35
|
+
puts "Minimum safety response:\n#{response.text}\n\n"
|
36
|
+
rescue Geminize::GeminizeError => e
|
37
|
+
puts "Error with minimum safety: #{e.message}\n\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
puts "4. Generating with custom safety settings:"
|
41
|
+
begin
|
42
|
+
# Custom safety settings:
|
43
|
+
# - Block medium and above for dangerous content
|
44
|
+
# - Block low and above for hate speech
|
45
|
+
# - Block only high for sexually explicit content
|
46
|
+
# - No blocks for harassment
|
47
|
+
custom_safety_settings = [
|
48
|
+
{category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_MEDIUM_AND_ABOVE"},
|
49
|
+
{category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_LOW_AND_ABOVE"},
|
50
|
+
{category: "HARM_CATEGORY_SEXUALLY_EXPLICIT", threshold: "BLOCK_ONLY_HIGH"},
|
51
|
+
{category: "HARM_CATEGORY_HARASSMENT", threshold: "BLOCK_NONE"}
|
52
|
+
]
|
53
|
+
|
54
|
+
response = Geminize.generate_with_safety_settings(
|
55
|
+
POTENTIALLY_SENSITIVE_PROMPT,
|
56
|
+
custom_safety_settings,
|
57
|
+
nil,
|
58
|
+
temperature: 0.2
|
59
|
+
)
|
60
|
+
puts "Custom safety response:\n#{response.text}\n\n"
|
61
|
+
rescue Geminize::GeminizeError => e
|
62
|
+
puts "Error with custom safety: #{e.message}\n\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Demonstrate direct usage of safety settings in a ContentRequest
|
66
|
+
puts "5. Using safety settings directly in a ContentRequest:"
|
67
|
+
begin
|
68
|
+
generator = Geminize::TextGeneration.new
|
69
|
+
content_request = Geminize::Models::ContentRequest.new(
|
70
|
+
POTENTIALLY_SENSITIVE_PROMPT,
|
71
|
+
nil,
|
72
|
+
temperature: 0.2
|
73
|
+
)
|
74
|
+
|
75
|
+
# Add specific safety settings
|
76
|
+
content_request.add_safety_setting("HARM_CATEGORY_DANGEROUS_CONTENT", "BLOCK_MEDIUM_AND_ABOVE")
|
77
|
+
|
78
|
+
response = generator.generate(content_request)
|
79
|
+
puts "ContentRequest safety response:\n#{response.text}\n\n"
|
80
|
+
rescue Geminize::GeminizeError => e
|
81
|
+
puts "Error with ContentRequest safety: #{e.message}\n\n"
|
82
|
+
end
|
@@ -17,7 +17,7 @@ module Geminize
|
|
17
17
|
DEFAULT_MODEL = "gemini-2.0-flash"
|
18
18
|
|
19
19
|
# Default embedding model
|
20
|
-
DEFAULT_EMBEDDING_MODEL = "embedding-
|
20
|
+
DEFAULT_EMBEDDING_MODEL = "gemini-embedding-exp-03-07"
|
21
21
|
|
22
22
|
# Default timeout values (in seconds)
|
23
23
|
DEFAULT_TIMEOUT = 30
|
@@ -69,9 +69,9 @@ module Geminize
|
|
69
69
|
# @return [void]
|
70
70
|
def reset!
|
71
71
|
@api_key = ENV["GEMINI_API_KEY"]
|
72
|
-
@api_version = DEFAULT_API_VERSION
|
73
|
-
@default_model = DEFAULT_MODEL
|
74
|
-
@default_embedding_model = DEFAULT_EMBEDDING_MODEL
|
72
|
+
@api_version = ENV["GEMINI_API_VERSION"] || DEFAULT_API_VERSION
|
73
|
+
@default_model = ENV["GEMINI_MODEL"] || DEFAULT_MODEL
|
74
|
+
@default_embedding_model = ENV["GEMINI_EMBEDDING_MODEL"] || DEFAULT_EMBEDDING_MODEL
|
75
75
|
@timeout = DEFAULT_TIMEOUT
|
76
76
|
@open_timeout = DEFAULT_OPEN_TIMEOUT
|
77
77
|
@streaming_timeout = DEFAULT_STREAMING_TIMEOUT
|
data/lib/geminize/model_info.rb
CHANGED
@@ -9,6 +9,9 @@ module Geminize
|
|
9
9
|
# @return [Geminize::Client] The HTTP client
|
10
10
|
attr_reader :client
|
11
11
|
|
12
|
+
# Default page size for listing models
|
13
|
+
DEFAULT_PAGE_SIZE = 50
|
14
|
+
|
12
15
|
# Initialize a new ModelInfo instance
|
13
16
|
# @param client [Geminize::Client, nil] The HTTP client to use
|
14
17
|
# @param options [Hash] Additional options for the client
|
@@ -20,19 +23,26 @@ module Geminize
|
|
20
23
|
end
|
21
24
|
|
22
25
|
# List available models from the Gemini API
|
26
|
+
# @param page_size [Integer, nil] Number of models to return per page (max 1000)
|
27
|
+
# @param page_token [String, nil] Token for retrieving a specific page
|
23
28
|
# @param force_refresh [Boolean] Force a refresh from the API instead of using cache
|
24
29
|
# @return [Geminize::Models::ModelList] List of available models
|
25
30
|
# @raise [Geminize::GeminizeError] If the request fails
|
26
|
-
def list_models(force_refresh: false)
|
27
|
-
cache_key = "
|
31
|
+
def list_models(page_size: nil, page_token: nil, force_refresh: false)
|
32
|
+
cache_key = "models_list_#{page_size}_#{page_token}"
|
28
33
|
|
29
34
|
# Check if we have a valid cached result
|
30
35
|
if !force_refresh && @cache[cache_key] && @cache_expiry[cache_key] > Time.now
|
31
36
|
return @cache[cache_key]
|
32
37
|
end
|
33
38
|
|
39
|
+
# Prepare query parameters
|
40
|
+
params = {}
|
41
|
+
params[:pageSize] = page_size if page_size
|
42
|
+
params[:pageToken] = page_token
|
43
|
+
|
34
44
|
# Make the API request
|
35
|
-
response = client.get("models")
|
45
|
+
response = client.get("models", params)
|
36
46
|
|
37
47
|
# Create a ModelList from the response
|
38
48
|
model_list = Models::ModelList.from_api_data(response)
|
@@ -44,13 +54,62 @@ module Geminize
|
|
44
54
|
model_list
|
45
55
|
end
|
46
56
|
|
57
|
+
# Get all available models, handling pagination automatically
|
58
|
+
# @param force_refresh [Boolean] Force a refresh from the API instead of using cache
|
59
|
+
# @return [Geminize::Models::ModelList] Complete list of all available models
|
60
|
+
# @raise [Geminize::GeminizeError] If any request fails
|
61
|
+
def list_all_models(force_refresh: false)
|
62
|
+
cache_key = "all_models_list"
|
63
|
+
|
64
|
+
# Check if we have a valid cached result
|
65
|
+
if !force_refresh && @cache[cache_key] && @cache_expiry[cache_key] > Time.now
|
66
|
+
return @cache[cache_key]
|
67
|
+
end
|
68
|
+
|
69
|
+
all_models = []
|
70
|
+
page_token = nil
|
71
|
+
|
72
|
+
# Fetch first page
|
73
|
+
model_list = list_models(
|
74
|
+
page_size: DEFAULT_PAGE_SIZE,
|
75
|
+
page_token: page_token,
|
76
|
+
force_refresh: force_refresh
|
77
|
+
)
|
78
|
+
all_models.concat(model_list.models)
|
79
|
+
|
80
|
+
# Fetch additional pages if available
|
81
|
+
while model_list.has_more_pages?
|
82
|
+
page_token = model_list.next_page_token
|
83
|
+
model_list = list_models(
|
84
|
+
page_size: DEFAULT_PAGE_SIZE,
|
85
|
+
page_token: page_token,
|
86
|
+
force_refresh: force_refresh
|
87
|
+
)
|
88
|
+
all_models.concat(model_list.models)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Create a consolidated model list
|
92
|
+
result = Models::ModelList.new(all_models)
|
93
|
+
|
94
|
+
# Cache the result
|
95
|
+
@cache[cache_key] = result
|
96
|
+
@cache_expiry[cache_key] = Time.now + @cache_ttl
|
97
|
+
|
98
|
+
result
|
99
|
+
end
|
100
|
+
|
47
101
|
# Get information about a specific model
|
48
|
-
# @param
|
102
|
+
# @param model_name [String] The model name to retrieve (models/{model})
|
49
103
|
# @param force_refresh [Boolean] Force a refresh from the API instead of using cache
|
50
104
|
# @return [Geminize::Models::Model] The model information
|
51
105
|
# @raise [Geminize::GeminizeError] If the request fails or model is not found
|
52
|
-
def get_model(
|
53
|
-
|
106
|
+
def get_model(model_name, force_refresh: false)
|
107
|
+
# Handle both formats: "models/gemini-1.5-pro" or just "gemini-1.5-pro"
|
108
|
+
unless model_name.start_with?("models/")
|
109
|
+
model_name = "models/#{model_name}"
|
110
|
+
end
|
111
|
+
|
112
|
+
cache_key = "model_#{model_name}"
|
54
113
|
|
55
114
|
# Check if we have a valid cached result
|
56
115
|
if !force_refresh && @cache[cache_key] && @cache_expiry[cache_key] > Time.now
|
@@ -59,7 +118,7 @@ module Geminize
|
|
59
118
|
|
60
119
|
# Make the API request
|
61
120
|
begin
|
62
|
-
response = client.get(
|
121
|
+
response = client.get(model_name)
|
63
122
|
|
64
123
|
# Create a Model from the response
|
65
124
|
model = Models::Model.from_api_data(response)
|
@@ -71,10 +130,30 @@ module Geminize
|
|
71
130
|
model
|
72
131
|
rescue Geminize::NotFoundError => e
|
73
132
|
# Re-raise with a more descriptive message
|
74
|
-
raise Geminize::NotFoundError.new("Model '#{
|
133
|
+
raise Geminize::NotFoundError.new("Model '#{model_name}' not found", e.code, e.http_status)
|
75
134
|
end
|
76
135
|
end
|
77
136
|
|
137
|
+
# Get models that support a specific generation method
|
138
|
+
# @param method [String] The generation method (e.g., "generateContent", "embedContent")
|
139
|
+
# @param force_refresh [Boolean] Force a refresh from the API instead of using cache
|
140
|
+
# @return [Geminize::Models::ModelList] List of models that support the method
|
141
|
+
# @raise [Geminize::GeminizeError] If the request fails
|
142
|
+
def get_models_by_method(method, force_refresh: false)
|
143
|
+
all_models = list_all_models(force_refresh: force_refresh)
|
144
|
+
all_models.filter_by_method(method)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get models by base model ID
|
148
|
+
# @param base_model_id [String] The base model ID to filter by
|
149
|
+
# @param force_refresh [Boolean] Force a refresh from the API instead of using cache
|
150
|
+
# @return [Geminize::Models::ModelList] List of models with the specified base model ID
|
151
|
+
# @raise [Geminize::GeminizeError] If the request fails
|
152
|
+
def get_models_by_base_id(base_model_id, force_refresh: false)
|
153
|
+
all_models = list_all_models(force_refresh: force_refresh)
|
154
|
+
all_models.filter_by_base_model_id(base_model_id)
|
155
|
+
end
|
156
|
+
|
78
157
|
# Clear all cached model information
|
79
158
|
# @return [void]
|
80
159
|
def clear_cache
|