ruby-gemini-api 0.1.3 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42b86546e154705767e40dad92410df0e1be21e335ae95630d8c2213f42a8a04
4
- data.tar.gz: ea10d1a8c13bf0c49ccd720c9e1c25494b9c9a4955879b15e20c2722d5f8f712
3
+ metadata.gz: e140bb695362a7924c1b633fbe0a5ac0a2dda14880a755157592024f3f4e719e
4
+ data.tar.gz: 5b6e2ec5d5be300ba558199c8ff2160e598615cbdb4e744209416fa7322bf0f6
5
5
  SHA512:
6
- metadata.gz: 778b3de54c33818cb7d8fc6f2adc6e3876b5db4ef6dae3c9c1e1ad0db429c4b9c3225ae0518545feaba441cea212fbff0843ee72fe095c73f5fbc3b0c3a37862
7
- data.tar.gz: 07cfd038ac791757e11ea1784ba48760fd3b292b6cb5edf8434930dcd4815da89431259ca9359718dc665117630d82d70852f934ef1644130d92666d0c504e12
6
+ metadata.gz: a2f3b01548fc4da69d1d1e77943444a164dc781940eeb1e7b8ee1d34eeca34db7f46e532f5b504175000145e11e0d343319da59111b87f2f403a99c08e6517e1
7
+ data.tar.gz: a84dcc5431abb1a4aa9753cec5a8e36106aa365cacf88b3d29998622382069f01650f11396a6867ce0b940e5faa4788fcb2eb7c744a27203a034f2918e353416
data/CHANGELOG.md CHANGED
@@ -10,4 +10,11 @@
10
10
  - Add function calling
11
11
 
12
12
  ## [0.1.3] - 2025-10-09
13
- - Add support for multi-image input
13
+ - Add support for multi-image input
14
+
15
+ ## [0.1.4] - 2025-11-08
16
+ - Add support for grounding search
17
+
18
+ ## [0.1.5] - 2025-11-13
19
+ - Add support for URL Context tool
20
+ - Add simplified method for accessing grounding search sources
data/README.md CHANGED
@@ -272,6 +272,159 @@ client.files.delete(name: file_name)
272
272
 
273
273
  For more examples, check out the `demo/vision_demo.rb` and `demo/file_vision_demo.rb` files included with the gem.
274
274
 
275
+ ### Grounding with Google Search
276
+
277
+ You can use Gemini API's Google Search grounding feature to retrieve real-time information.
278
+
279
+ #### Basic Usage
280
+
281
+ ```ruby
282
+ require 'gemini'
283
+
284
+ client = Gemini::Client.new(ENV['GEMINI_API_KEY'])
285
+
286
+ # Use Google Search to get real-time information
287
+ response = client.generate_content(
288
+ "Who won the euro 2024?",
289
+ model: "gemini-2.0-flash-lite",
290
+ tools: [{ google_search: {} }]
291
+ )
292
+
293
+ if response.success?
294
+ puts response.text
295
+
296
+ # Check grounding information
297
+ if response.grounded?
298
+ puts "\nSource references:"
299
+ response.grounding_sources.each do |source|
300
+ puts "- #{source[:title]}"
301
+ puts " #{source[:url]}"
302
+ end
303
+ end
304
+ end
305
+ ```
306
+
307
+ #### Checking Grounding Metadata
308
+
309
+ ```ruby
310
+ # Check if response is grounded
311
+ if response.grounded?
312
+ # Get formatted source information (recommended)
313
+ response.grounding_sources.each do |source|
314
+ puts "Title: #{source[:title]}"
315
+ puts "URL: #{source[:url]}"
316
+ end
317
+
318
+ # You can also access raw metadata
319
+ metadata = response.grounding_metadata
320
+ chunks = response.grounding_chunks
321
+ entry_point = response.search_entry_point
322
+ end
323
+ ```
324
+
325
+ #### Example with Different Topics
326
+
327
+ ```ruby
328
+ response = client.generate_content(
329
+ "What are the latest AI developments in 2024?",
330
+ model: "gemini-2.0-flash-lite",
331
+ tools: [{ google_search: {} }]
332
+ )
333
+
334
+ if response.success? && response.grounded?
335
+ puts response.text
336
+ puts "\nSources: #{response.grounding_chunks.length} references"
337
+ end
338
+ ```
339
+
340
+ #### Demo Application
341
+
342
+ You can find a grounding search demo in:
343
+
344
+ ```bash
345
+ ruby demo/grounding_search_demo_ja.rb
346
+ ```
347
+
348
+ ### URL Context
349
+
350
+ You can use Gemini API's URL Context feature to retrieve and analyze content from web pages.
351
+
352
+ #### Basic Usage
353
+
354
+ ```ruby
355
+ require 'gemini'
356
+
357
+ client = Gemini::Client.new(ENV['GEMINI_API_KEY'])
358
+
359
+ # Use URL Context to analyze web pages (shortcut)
360
+ response = client.generate_content(
361
+ "Summarize the content of this page: https://www.ruby-lang.org",
362
+ model: "gemini-2.5-flash",
363
+ url_context: true
364
+ )
365
+
366
+ if response.success?
367
+ puts response.text
368
+ end
369
+ ```
370
+
371
+ #### Using Explicit Tools Parameter
372
+
373
+ ```ruby
374
+ # Explicit tools parameter
375
+ response = client.generate_content(
376
+ "Compare these two pages: https://www.ruby-lang.org and https://www.python.org",
377
+ model: "gemini-2.5-flash",
378
+ tools: [{ url_context: {} }]
379
+ )
380
+ ```
381
+
382
+ #### Combining URL Context with Google Search
383
+
384
+ ```ruby
385
+ # Use both URL Context and Google Search
386
+ response = client.generate_content(
387
+ "What is the latest information about Ruby from https://www.ruby-lang.org and recent news?",
388
+ model: "gemini-2.5-flash",
389
+ url_context: true,
390
+ google_search: true
391
+ )
392
+ ```
393
+
394
+ #### Checking URL Context Metadata
395
+
396
+ ```ruby
397
+ # Check if URL Context was used
398
+ if response.url_context?
399
+ # Get full metadata
400
+ metadata = response.url_context_metadata
401
+
402
+ # Get retrieved URL information
403
+ urls = response.retrieved_urls
404
+
405
+ # Check retrieval status for each URL
406
+ response.url_retrieval_statuses.each do |url_info|
407
+ puts "URL: #{url_info[:url]}"
408
+ puts "Status: #{url_info[:status]}"
409
+ puts "Title: #{url_info[:title]}" if url_info[:title]
410
+ end
411
+ end
412
+ ```
413
+
414
+ #### Limitations
415
+
416
+ - Maximum 20 URLs per request
417
+ - Maximum 34MB content size per URL
418
+ - YouTube videos and paywalled content are not supported
419
+
420
+ #### Demo Application
421
+
422
+ You can find a URL context demo in:
423
+
424
+ ```bash
425
+ ruby demo/url_context_demo.rb https://www.ruby-lang.org
426
+ ```
427
+
275
428
  ### Image Generation
276
429
 
277
430
  ```ruby
data/lib/gemini/client.rb CHANGED
@@ -117,8 +117,9 @@ module Gemini
117
117
  # Helper methods for convenience
118
118
 
119
119
  # Method with usage similar to OpenAI's chat
120
- def generate_content(prompt, model: "gemini-2.0-flash-lite", system_instruction: nil,
121
- response_mime_type: nil, response_schema: nil, temperature: 0.5, tools: nil, **parameters, &stream_callback)
120
+ def generate_content(prompt, model: "gemini-2.0-flash-lite", system_instruction: nil,
121
+ response_mime_type: nil, response_schema: nil, temperature: 0.5, tools: nil,
122
+ url_context: false, google_search: false, **parameters, &stream_callback)
122
123
  content = format_content(prompt)
123
124
  params = {
124
125
  contents: [content],
@@ -137,7 +138,11 @@ module Gemini
137
138
  if response_schema
138
139
  params[:generation_config]["response_schema"] = response_schema
139
140
  end
140
- params[:tools] = tools if tools
141
+
142
+ # Handle tool shortcuts
143
+ tools = build_tools_array(tools, url_context: url_context, google_search: google_search)
144
+ params[:tools] = tools if tools && !tools.empty?
145
+
141
146
  params.merge!(parameters)
142
147
 
143
148
  if block_given?
@@ -149,32 +154,38 @@ module Gemini
149
154
 
150
155
  # Streaming text generation
151
156
  def generate_content_stream(prompt, model: "gemini-2.0-flash-lite", system_instruction: nil,
152
- response_mime_type: nil, response_schema: nil, temperature: 0.5, **parameters, &block)
157
+ response_mime_type: nil, response_schema: nil, temperature: 0.5,
158
+ url_context: false, google_search: false, **parameters, &block)
153
159
  raise ArgumentError, "Block is required for streaming" unless block_given?
154
-
160
+
155
161
  content = format_content(prompt)
156
162
  params = {
157
163
  contents: [content],
158
164
  model: model
159
165
  }
160
-
166
+
161
167
  if system_instruction
162
168
  params[:system_instruction] = format_content(system_instruction)
163
169
  end
164
-
170
+
165
171
  params[:generation_config] ||= {}
166
-
172
+
167
173
  if response_mime_type
168
174
  params[:generation_config][:response_mime_type] = response_mime_type
169
175
  end
170
-
176
+
171
177
  if response_schema
172
178
  params[:generation_config][:response_schema] = response_schema
173
179
  end
174
180
  params[:generation_config]["temperature"] = temperature
181
+
182
+ # Handle tool shortcuts
183
+ tools = build_tools_array(nil, url_context: url_context, google_search: google_search)
184
+ params[:tools] = tools if tools && !tools.empty?
185
+
175
186
  # Merge other parameters
176
187
  params.merge!(parameters)
177
-
188
+
178
189
  chat(parameters: params, &block)
179
190
  end
180
191
 
@@ -399,7 +410,29 @@ module Gemini
399
410
  end
400
411
 
401
412
  private
402
-
413
+
414
+ # Build tools array from explicit tools parameter and shortcuts
415
+ def build_tools_array(tools, url_context: false, google_search: false)
416
+ result_tools = []
417
+
418
+ # Add existing tools if provided
419
+ if tools.is_a?(Array)
420
+ result_tools.concat(tools)
421
+ elsif tools
422
+ result_tools << tools
423
+ end
424
+
425
+ # Add url_context tool if requested
426
+ result_tools << { url_context: {} } if url_context
427
+
428
+ # Add google_search tool if requested
429
+ result_tools << { google_search: {} } if google_search
430
+
431
+ # Remove duplicates based on tool keys and return
432
+ return nil if result_tools.empty?
433
+ result_tools.uniq { |tool| tool.keys.first }
434
+ end
435
+
403
436
  # Process stream chunk and pass to callback
404
437
  def process_stream_chunk(chunk, &callback)
405
438
  if chunk.respond_to?(:dig) && chunk.dig("candidates", 0, "content", "parts", 0, "text")
@@ -99,6 +99,78 @@ module Gemini
99
99
  def safety_blocked?
100
100
  finish_reason == "SAFETY"
101
101
  end
102
+
103
+ # Get grounding metadata (for Google Search grounding)
104
+ def grounding_metadata
105
+ first_candidate&.dig("groundingMetadata")
106
+ end
107
+
108
+ # Check if response has grounding metadata
109
+ def grounded?
110
+ !grounding_metadata.nil? && !grounding_metadata.empty?
111
+ end
112
+
113
+ # Get grounding chunks (source references)
114
+ def grounding_chunks
115
+ grounding_metadata&.dig("groundingChunks") || []
116
+ end
117
+
118
+ # Get search entry point URL (if available)
119
+ def search_entry_point
120
+ grounding_metadata&.dig("searchEntryPoint", "renderedContent")
121
+ end
122
+
123
+ # Get formatted grounding sources (simplified access)
124
+ def grounding_sources
125
+ return [] unless grounded?
126
+
127
+ grounding_chunks.map do |chunk|
128
+ if chunk["web"]
129
+ {
130
+ url: chunk["web"]["uri"],
131
+ title: chunk["web"]["title"],
132
+ type: "web"
133
+ }
134
+ else
135
+ # Handle other potential chunk types
136
+ {
137
+ type: "unknown",
138
+ data: chunk
139
+ }
140
+ end
141
+ end
142
+ end
143
+
144
+ # Get URL context metadata (for URL Context tool)
145
+ def url_context_metadata
146
+ first_candidate&.dig("urlContextMetadata")
147
+ end
148
+
149
+ # Check if response has URL context metadata
150
+ def url_context?
151
+ !url_context_metadata.nil? && !url_context_metadata.empty?
152
+ end
153
+
154
+ # Get retrieved URLs from URL context
155
+ def retrieved_urls
156
+ return [] unless url_context?
157
+
158
+ url_context_metadata&.dig("urlMetadata") || []
159
+ end
160
+
161
+ # Get URL retrieval statuses
162
+ def url_retrieval_statuses
163
+ return [] unless url_context?
164
+
165
+ retrieved_urls.map do |url_info|
166
+ {
167
+ url: url_info["retrievedUrl"],
168
+ status: url_info["urlRetrievalStatus"],
169
+ title: url_info["title"]
170
+ }
171
+ end
172
+ end
173
+
102
174
 
103
175
  # Get token usage information
104
176
  def usage
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gemini
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-gemini-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - rira100000000
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-10-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -172,7 +171,6 @@ metadata:
172
171
  source_code_uri: https://github.com/rira100000000/ruby-gemini-api
173
172
  changelog_uri: https://github.com/rira100000000/ruby-gemini-api/blob/main/CHANGELOG.md
174
173
  rubygems_mfa_required: 'true'
175
- post_install_message:
176
174
  rdoc_options: []
177
175
  require_paths:
178
176
  - lib
@@ -187,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
185
  - !ruby/object:Gem::Version
188
186
  version: '0'
189
187
  requirements: []
190
- rubygems_version: 3.5.11
191
- signing_key:
188
+ rubygems_version: 3.7.2
192
189
  specification_version: 4
193
190
  summary: Ruby client for Google's Gemini API
194
191
  test_files: []