gemini-ai 3.2.0 → 4.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c726dcc65ecf4cfca2819e6f18da5fd1a3eb96e45888971881c7255631a2f074
4
- data.tar.gz: 2d1617c38f987a40386b48b8465871e44f60bc2bd00dc4883704f91aa12aaab9
3
+ metadata.gz: b66c146b7230d838c888d5f90107f07bcc2827c7710b77c1284c52315b3c9515
4
+ data.tar.gz: c125664051e260270bb08b81ecc932a3e4b730ea1c69601ba93af4749af54fcf
5
5
  SHA512:
6
- metadata.gz: c3356afb013f69f51c1dfd6f379da7ae615dbbc4750dff25b977bc70a4ccda428a4466cbf4ea60dd7341bbc634882b56d1d76a24c3993a449c97ae566c44daf1
7
- data.tar.gz: 9412ff5d682105db69caf9cc98688d499f794f76231e741450ee6eebd2c0f49efaeca6376f3b45a424e070e717e702a347ce5cf5cf0eb27229dc8e10727cdb32
6
+ metadata.gz: dd67f092295620ff45cb75f07b67dc0753d54c92ff598284a0f10ce4a45e7f395aad0235320fb95ab86bb12f9033c21e4b3fe776bb99bd6d98f8228054bc6bca
7
+ data.tar.gz: c03ab797796745870124159762e11f0ea5a56ee9cb033f97c7b62088dd0a2d2dae85f1fa874245ddc3fa3482ae7739f1a311546807ee78e1dbd17e7f5807cc52
data/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
1
  *.gem
2
2
  .devcontainer
3
3
  .env
4
+ *.tmp
5
+ *.temp
6
+ temp.rb
7
+ tmp.rb
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  group :test, :development do
8
- gem 'dotenv', '~> 2.8', '>= 2.8.1'
8
+ gem 'dotenv', '~> 3.1', '>= 3.1.2'
9
9
  gem 'pry-byebug', '~> 3.10', '>= 3.10.1'
10
- gem 'rubocop', '~> 1.60', '>= 1.60.1'
10
+ gem 'rubocop', '~> 1.63', '>= 1.63.5'
11
11
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gemini-ai (3.2.0)
4
+ gemini-ai (4.0.0)
5
5
  event_stream_parser (~> 1.0)
6
6
  faraday (~> 2.9)
7
7
  faraday-typhoeus (~> 1.1)
@@ -14,9 +14,10 @@ GEM
14
14
  addressable (2.8.6)
15
15
  public_suffix (>= 2.0.2, < 6.0)
16
16
  ast (2.4.2)
17
+ base64 (0.2.0)
17
18
  byebug (11.1.3)
18
19
  coderay (1.1.3)
19
- dotenv (2.8.1)
20
+ dotenv (3.1.2)
20
21
  ethon (0.16.0)
21
22
  ffi (>= 1.15.0)
22
23
  event_stream_parser (1.0.0)
@@ -28,25 +29,26 @@ GEM
28
29
  faraday (~> 2.0)
29
30
  typhoeus (~> 1.4)
30
31
  ffi (1.16.3)
31
- google-cloud-env (2.1.0)
32
+ google-cloud-env (2.1.1)
32
33
  faraday (>= 1.0, < 3.a)
33
- googleauth (1.9.1)
34
+ googleauth (1.11.0)
34
35
  faraday (>= 1.0, < 3.a)
35
36
  google-cloud-env (~> 2.1)
36
37
  jwt (>= 1.4, < 3.0)
37
38
  multi_json (~> 1.11)
38
39
  os (>= 0.9, < 2.0)
39
40
  signet (>= 0.16, < 2.a)
40
- json (2.7.1)
41
- jwt (2.7.1)
41
+ json (2.7.2)
42
+ jwt (2.8.1)
43
+ base64
42
44
  language_server-protocol (3.17.0.3)
43
- method_source (1.0.0)
45
+ method_source (1.1.0)
44
46
  multi_json (1.15.0)
45
47
  net-http (0.4.1)
46
48
  uri
47
49
  os (1.1.4)
48
50
  parallel (1.24.0)
49
- parser (3.3.0.5)
51
+ parser (3.3.1.0)
50
52
  ast (~> 2.4.1)
51
53
  racc
52
54
  pry (0.14.2)
@@ -55,12 +57,13 @@ GEM
55
57
  pry-byebug (3.10.1)
56
58
  byebug (~> 11.0)
57
59
  pry (>= 0.13, < 0.15)
58
- public_suffix (5.0.4)
60
+ public_suffix (5.0.5)
59
61
  racc (1.7.3)
60
62
  rainbow (3.1.1)
61
- regexp_parser (2.9.0)
62
- rexml (3.2.6)
63
- rubocop (1.60.1)
63
+ regexp_parser (2.9.2)
64
+ rexml (3.2.8)
65
+ strscan (>= 3.0.9)
66
+ rubocop (1.63.5)
64
67
  json (~> 2.3)
65
68
  language_server-protocol (>= 3.17.0)
66
69
  parallel (~> 1.10)
@@ -68,17 +71,18 @@ GEM
68
71
  rainbow (>= 2.2.2, < 4.0)
69
72
  regexp_parser (>= 1.8, < 3.0)
70
73
  rexml (>= 3.2.5, < 4.0)
71
- rubocop-ast (>= 1.30.0, < 2.0)
74
+ rubocop-ast (>= 1.31.1, < 2.0)
72
75
  ruby-progressbar (~> 1.7)
73
76
  unicode-display_width (>= 2.4.0, < 3.0)
74
- rubocop-ast (1.30.0)
75
- parser (>= 3.2.1.0)
77
+ rubocop-ast (1.31.3)
78
+ parser (>= 3.3.1.0)
76
79
  ruby-progressbar (1.13.0)
77
- signet (0.18.0)
80
+ signet (0.19.0)
78
81
  addressable (~> 2.8)
79
82
  faraday (>= 0.17.5, < 3.a)
80
83
  jwt (>= 1.5, < 3.0)
81
84
  multi_json (~> 1.10)
85
+ strscan (3.1.0)
82
86
  typhoeus (1.4.1)
83
87
  ethon (>= 0.9.0)
84
88
  unicode-display_width (2.5.0)
@@ -88,10 +92,10 @@ PLATFORMS
88
92
  x86_64-linux
89
93
 
90
94
  DEPENDENCIES
91
- dotenv (~> 2.8, >= 2.8.1)
95
+ dotenv (~> 3.1, >= 3.1.2)
92
96
  gemini-ai!
93
97
  pry-byebug (~> 3.10, >= 3.10.1)
94
- rubocop (~> 1.60, >= 1.60.1)
98
+ rubocop (~> 1.63, >= 1.63.5)
95
99
 
96
100
  BUNDLED WITH
97
101
  2.4.22
data/README.md CHANGED
@@ -9,7 +9,7 @@ A Ruby Gem for interacting with [Gemini](https://deepmind.google/technologies/ge
9
9
  ## TL;DR and Quick Start
10
10
 
11
11
  ```ruby
12
- gem 'gemini-ai', '~> 3.2.0'
12
+ gem 'gemini-ai', '~> 4.0.0'
13
13
  ```
14
14
 
15
15
  ```ruby
@@ -73,41 +73,46 @@ Result:
73
73
  - [TL;DR and Quick Start](#tldr-and-quick-start)
74
74
  - [Index](#index)
75
75
  - [Setup](#setup)
76
- - [Installing](#installing)
77
- - [Credentials](#credentials)
78
- - [Option 1: API Key (Generative Language API)](#option-1-api-key-generative-language-api)
79
- - [Option 2: Service Account Credentials File (Vertex AI API)](#option-2-service-account-credentials-file-vertex-ai-api)
80
- - [Option 3: Application Default Credentials (Vertex AI API)](#option-3-application-default-credentials-vertex-ai-api)
81
- - [Required Data](#required-data)
82
- - [Custom Version](#custom-version)
76
+ - [Installing](#installing)
77
+ - [Credentials](#credentials)
78
+ - [Option 1: API Key (Generative Language API)](#option-1-api-key-generative-language-api)
79
+ - [Option 2: Service Account Credentials File (Vertex AI API)](#option-2-service-account-credentials-file-vertex-ai-api)
80
+ - [Option 3: Application Default Credentials (Vertex AI API)](#option-3-application-default-credentials-vertex-ai-api)
81
+ - [Required Data](#required-data)
82
+ - [Custom Version](#custom-version)
83
+ - [Available Models](#available-models)
83
84
  - [Usage](#usage)
84
- - [Client](#client)
85
- - [Methods](#methods)
86
- - [stream_generate_content](#stream_generate_content)
87
- - [Receiving Stream Events](#receiving-stream-events)
88
- - [Without Events](#without-events)
89
- - [generate_content](#generate_content)
90
- - [Modes](#modes)
91
- - [Text](#text)
92
- - [Image](#image)
93
- - [Video](#video)
94
- - [Streaming vs. Server-Sent Events (SSE)](#streaming-vs-server-sent-events-sse)
95
- - [Server-Sent Events (SSE) Hang](#server-sent-events-sse-hang)
96
- - [Non-Streaming](#non-streaming)
97
- - [Back-and-Forth Conversations](#back-and-forth-conversations)
98
- - [Tools (Functions) Calling](#tools-functions-calling)
99
- - [New Functionalities and APIs](#new-functionalities-and-apis)
100
- - [Request Options](#request-options)
101
- - [Adapter](#adapter)
102
- - [Timeout](#timeout)
103
- - [Error Handling](#error-handling)
104
- - [Rescuing](#rescuing)
105
- - [For Short](#for-short)
106
- - [Errors](#errors)
85
+ - [Client](#client)
86
+ - [Methods](#methods)
87
+ - [Chat](#chat)
88
+ - [stream_generate_content](#stream_generate_content)
89
+ - [Receiving Stream Events](#receiving-stream-events)
90
+ - [Without Events](#without-events)
91
+ - [generate_content](#generate_content)
92
+ - [Embeddings](#embeddings)
93
+ - [predict](#predict)
94
+ - [embed_content](#embed_content)
95
+ - [Modes](#modes)
96
+ - [Text](#text)
97
+ - [Image](#image)
98
+ - [Video](#video)
99
+ - [Streaming vs. Server-Sent Events (SSE)](#streaming-vs-server-sent-events-sse)
100
+ - [Server-Sent Events (SSE) Hang](#server-sent-events-sse-hang)
101
+ - [Non-Streaming](#non-streaming)
102
+ - [Back-and-Forth Conversations](#back-and-forth-conversations)
103
+ - [Tools (Functions) Calling](#tools-functions-calling)
104
+ - [New Functionalities and APIs](#new-functionalities-and-apis)
105
+ - [Request Options](#request-options)
106
+ - [Adapter](#adapter)
107
+ - [Timeout](#timeout)
108
+ - [Error Handling](#error-handling)
109
+ - [Rescuing](#rescuing)
110
+ - [For Short](#for-short)
111
+ - [Errors](#errors)
107
112
  - [Development](#development)
108
- - [Purpose](#purpose)
109
- - [Publish to RubyGems](#publish-to-rubygems)
110
- - [Updating the README](#updating-the-readme)
113
+ - [Purpose](#purpose)
114
+ - [Publish to RubyGems](#publish-to-rubygems)
115
+ - [Updating the README](#updating-the-readme)
111
116
  - [Resources and References](#resources-and-references)
112
117
  - [Disclaimer](#disclaimer)
113
118
 
@@ -116,11 +121,11 @@ Result:
116
121
  ### Installing
117
122
 
118
123
  ```sh
119
- gem install gemini-ai -v 3.2.0
124
+ gem install gemini-ai -v 4.0.0
120
125
  ```
121
126
 
122
127
  ```sh
123
- gem 'gemini-ai', '~> 3.2.0'
128
+ gem 'gemini-ai', '~> 4.0.0'
124
129
  ```
125
130
 
126
131
  ### Credentials
@@ -309,6 +314,43 @@ client = Gemini.new(
309
314
  )
310
315
  ```
311
316
 
317
+ ## Available Models
318
+
319
+ These models are accessible to the repository **author** as of May 2025 in the `us-east4` region. Access to models may vary by region, user, and account. All models here are expected to work, if you can access them. This is just a reference of what a "typical" user may expect to have access to right away:
320
+
321
+ | Model | Vertex AI | Generative Language |
322
+ |------------------------------------------|:---------:|:-------------------:|
323
+ | gemini-pro-vision | ✅ | 🔒 |
324
+ | gemini-pro | ✅ | ✅ |
325
+ | gemini-1.5-pro-preview-0514 | ✅ | 🔒 |
326
+ | gemini-1.5-pro-preview-0409 | ✅ | 🔒 |
327
+ | gemini-1.5-pro | 🔒 | 🔒 |
328
+ | gemini-1.5-flash-preview-0514 | ✅ | 🔒 |
329
+ | gemini-1.5-flash | 🔒 | 🔒 |
330
+ | gemini-1.0-pro-vision-latest | 🔒 | 🔒 |
331
+ | gemini-1.0-pro-vision-001 | ✅ | 🔒 |
332
+ | gemini-1.0-pro-vision | ✅ | 🔒 |
333
+ | gemini-1.0-pro-latest | 🔒 | ✅ |
334
+ | gemini-1.0-pro-002 | ✅ | 🔒 |
335
+ | gemini-1.0-pro-001 | ✅ | ✅ |
336
+ | gemini-1.0-pro | ✅ | ✅ |
337
+ | text-embedding-004 | ✅ | ✅ |
338
+ | embedding-001 | 🔒 | ✅ |
339
+ | text-multilingual-embedding-002 | ✅ | 🔒 |
340
+ | textembedding-gecko-multilingual@001 | ✅ | 🔒 |
341
+ | textembedding-gecko-multilingual@latest | ✅ | 🔒 |
342
+ | textembedding-gecko@001 | ✅ | 🔒 |
343
+ | textembedding-gecko@002 | ✅ | 🔒 |
344
+ | textembedding-gecko@003 | ✅ | 🔒 |
345
+ | textembedding-gecko@latest | ✅ | 🔒 |
346
+
347
+ You can follow new models at:
348
+
349
+ - [Google models](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models)
350
+ - [Model versions and lifecycle](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning)
351
+
352
+ This is [the code](https://gist.github.com/gbaptista/d7390901293bce81ee12ff4ec5fed62c) used for generating this table that you can use to explore your own access.
353
+
312
354
  ## Usage
313
355
 
314
356
  ### Client
@@ -349,9 +391,11 @@ client = Gemini.new(
349
391
 
350
392
  ### Methods
351
393
 
352
- #### stream_generate_content
394
+ #### Chat
395
+
396
+ ##### stream_generate_content
353
397
 
354
- ##### Receiving Stream Events
398
+ ###### Receiving Stream Events
355
399
 
356
400
  Ensure that you have enabled [Server-Sent Events](#streaming-vs-server-sent-events-sse) before using blocks for streaming:
357
401
 
@@ -383,7 +427,7 @@ Event:
383
427
  } }
384
428
  ```
385
429
 
386
- ##### Without Events
430
+ ###### Without Events
387
431
 
388
432
  You can use `stream_generate_content` without events:
389
433
 
@@ -423,7 +467,7 @@ result = client.stream_generate_content(
423
467
  end
424
468
  ```
425
469
 
426
- #### generate_content
470
+ ##### generate_content
427
471
 
428
472
  ```ruby
429
473
  result = client.generate_content(
@@ -452,6 +496,58 @@ Result:
452
496
 
453
497
  As of the writing of this README, only the `generative-language-api` service supports the `generate_content` method; `vertex-ai-api` does not.
454
498
 
499
+ #### Embeddings
500
+
501
+ ##### predict
502
+
503
+ Vertex AI API generates embeddings through the `predict` method ([documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings)), and you need a client set up to use an embedding model (e.g. `text-embedding-004`):
504
+
505
+ ```ruby
506
+ result = client.predict(
507
+ { instances: [{ content: 'What is life?' }],
508
+ parameters: { autoTruncate: true } }
509
+ )
510
+ ```
511
+
512
+ Result:
513
+ ```ruby
514
+ { 'predictions' =>
515
+ [{ 'embeddings' =>
516
+ { 'statistics' => { 'truncated' => false, 'token_count' => 4 },
517
+ 'values' =>
518
+ [-0.006861076690256596,
519
+ 0.00020840796059928834,
520
+ -0.028549950569868088,
521
+ # ...
522
+ 0.0020092015620321035,
523
+ 0.03279878571629524,
524
+ -0.014905261807143688] } }],
525
+ 'metadata' => { 'billableCharacterCount' => 11 } }
526
+ ```
527
+
528
+ ##### embed_content
529
+
530
+ Generative Language API generates embeddings through the `embed_content` method ([documentation](https://ai.google.dev/api/rest/v1/models/embedContent)), and you need a client set up to use an embedding model (e.g. `text-embedding-004`):
531
+
532
+ ```ruby
533
+ result = client.embed_content(
534
+ { content: { parts: [{ text: 'What is life?' }] } }
535
+ )
536
+ ```
537
+
538
+ Result:
539
+ ```ruby
540
+ { 'embedding' =>
541
+ { 'values' =>
542
+ [-0.0065307906,
543
+ -0.0001632607,
544
+ -0.028370803,
545
+
546
+ 0.0019950708,
547
+ 0.032798845,
548
+ -0.014878989] } }
549
+ ```
550
+
455
551
  ### Modes
456
552
 
457
553
  #### Text
@@ -904,12 +1000,25 @@ Which will result in:
904
1000
 
905
1001
  ### New Functionalities and APIs
906
1002
 
907
- Google may launch a new endpoint that we haven't covered in the Gem yet. If that's the case, you may still be able to use it through the `request` method. For example, `stream_generate_content` is just a wrapper for `google/models/gemini-pro:streamGenerateContent`, which you can call directly like this:
1003
+ Google may launch a new endpoint that we haven't covered in the Gem yet. If that's the case, you may still be able to use it through the `request` method. For example, `stream_generate_content` is just a wrapper for `models/gemini-pro:streamGenerateContent` (Generative Language API) or `publishers/google/models/gemini-pro:streamGenerateContent` (Vertex AI API), which you can call directly like this:
908
1004
 
909
1005
  ```ruby
1006
+ # Generative Language API
910
1007
  result = client.request(
911
- 'streamGenerateContent',
912
- { contents: { role: 'user', parts: { text: 'hi!' } } }
1008
+ 'models/gemini-pro:streamGenerateContent',
1009
+ { contents: { role: 'user', parts: { text: 'hi!' } } },
1010
+ request_method: 'POST',
1011
+ server_sent_events: true
1012
+ )
1013
+ ```
1014
+
1015
+ ```ruby
1016
+ # Vertex AI API
1017
+ result = client.request(
1018
+ 'publishers/google/models/gemini-pro:streamGenerateContent',
1019
+ { contents: { role: 'user', parts: { text: 'hi!' } } },
1020
+ request_method: 'POST',
1021
+ server_sent_events: true
913
1022
  )
914
1023
  ```
915
1024
 
@@ -1039,7 +1148,7 @@ gem build gemini-ai.gemspec
1039
1148
 
1040
1149
  gem signin
1041
1150
 
1042
- gem push gemini-ai-3.2.0.gem
1151
+ gem push gemini-ai-4.0.0.gem
1043
1152
  ```
1044
1153
 
1045
1154
  ### Updating the README
@@ -1083,6 +1192,9 @@ These resources and references may be useful throughout your learning process.
1083
1192
  - [Gemini API Documentation](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini)
1084
1193
  - [Vertex AI API Documentation](https://cloud.google.com/vertex-ai/docs/reference)
1085
1194
  - [REST Documentation](https://cloud.google.com/vertex-ai/docs/reference/rest)
1195
+ - [Get text embeddings](https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings)
1196
+ - [Google models](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models)
1197
+ - [Model versions and lifecycle](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning)
1086
1198
  - [Google DeepMind Gemini](https://deepmind.google/technologies/gemini/)
1087
1199
  - [Stream responses from Generative AI models](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/streaming)
1088
1200
  - [Function calling](https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/function-calling)
@@ -46,12 +46,19 @@ module Gemini
46
46
 
47
47
  @service_version = config.dig(:credentials, :version) || DEFAULT_SERVICE_VERSION
48
48
 
49
- @address = case @service
50
- when 'vertex-ai-api'
51
- "https://#{config[:credentials][:region]}-aiplatform.googleapis.com/#{@service_version}/projects/#{@project_id}/locations/#{config[:credentials][:region]}/publishers/google/models/#{config[:options][:model]}"
52
- when 'generative-language-api'
53
- "https://generativelanguage.googleapis.com/#{@service_version}/models/#{config[:options][:model]}"
54
- end
49
+ @base_address = case @service
50
+ when 'vertex-ai-api'
51
+ "https://#{config[:credentials][:region]}-aiplatform.googleapis.com/#{@service_version}/projects/#{@project_id}/locations/#{config[:credentials][:region]}"
52
+ when 'generative-language-api'
53
+ "https://generativelanguage.googleapis.com/#{@service_version}"
54
+ end
55
+
56
+ @model_address = case @service
57
+ when 'vertex-ai-api'
58
+ "publishers/google/models/#{config[:options][:model]}"
59
+ when 'generative-language-api'
60
+ "models/#{config[:options][:model]}"
61
+ end
55
62
 
56
63
  @server_sent_events = config.dig(:options, :server_sent_events)
57
64
 
@@ -68,21 +75,59 @@ module Gemini
68
75
  end
69
76
  end
70
77
 
78
+ def predict(payload, server_sent_events: nil, &callback)
79
+ result = request(
80
+ "#{@model_address}:predict", payload,
81
+ server_sent_events:, &callback
82
+ )
83
+
84
+ return result.first if result.is_a?(Array) && result.size == 1
85
+
86
+ result
87
+ end
88
+
89
+ def embed_content(payload, server_sent_events: nil, &callback)
90
+ result = request(
91
+ "#{@model_address}:embedContent", payload,
92
+ server_sent_events:, &callback
93
+ )
94
+
95
+ return result.first if result.is_a?(Array) && result.size == 1
96
+
97
+ result
98
+ end
99
+
71
100
  def stream_generate_content(payload, server_sent_events: nil, &callback)
72
- request('streamGenerateContent', payload, server_sent_events:, &callback)
101
+ request("#{@model_address}:streamGenerateContent", payload, server_sent_events:, &callback)
102
+ end
103
+
104
+ def models(_server_sent_events: nil, &callback)
105
+ result = request(
106
+ 'models',
107
+ nil, server_sent_events: false, request_method: 'GET', &callback
108
+ )
109
+
110
+ return result.first if result.is_a?(Array) && result.size == 1
111
+
112
+ result
73
113
  end
74
114
 
75
115
  def generate_content(payload, server_sent_events: nil, &callback)
76
- result = request('generateContent', payload, server_sent_events:, &callback)
116
+ result = request(
117
+ "#{@model_address}:generateContent", payload,
118
+ server_sent_events:, &callback
119
+ )
77
120
 
78
121
  return result.first if result.is_a?(Array) && result.size == 1
79
122
 
80
123
  result
81
124
  end
82
125
 
83
- def request(path, payload, server_sent_events: nil, &callback)
126
+ def request(path, payload, server_sent_events: nil, request_method: 'POST', &callback)
84
127
  server_sent_events_enabled = server_sent_events.nil? ? @server_sent_events : server_sent_events
85
- url = "#{@address}:#{path}"
128
+
129
+ url = "#{@base_address}/#{path}"
130
+
86
131
  params = []
87
132
 
88
133
  params << 'alt=sse' if server_sent_events_enabled
@@ -97,20 +142,21 @@ module Gemini
97
142
 
98
143
  results = []
99
144
 
145
+ method_to_call = request_method.to_s.strip.downcase.to_sym
146
+
100
147
  response = Faraday.new(request: @request_options) do |faraday|
101
148
  faraday.adapter @faraday_adapter
102
149
  faraday.response :raise_error
103
- end.post do |request|
150
+ end.send(method_to_call) do |request|
104
151
  request.url url
105
152
  request.headers['Content-Type'] = 'application/json'
106
153
  if @authentication == :service_account || @authentication == :default_credentials
107
154
  request.headers['Authorization'] = "Bearer #{@authorizer.fetch_access_token!['access_token']}"
108
155
  end
109
156
 
110
- request.body = payload.to_json
157
+ request.body = payload.to_json unless payload.nil?
111
158
 
112
159
  if server_sent_events_enabled
113
-
114
160
  partial_json = ''
115
161
 
116
162
  parser = EventStreamParser::Parser.new
data/gemini-ai.gemspec CHANGED
@@ -32,7 +32,11 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency 'event_stream_parser', '~> 1.0'
33
33
  spec.add_dependency 'faraday', '~> 2.9'
34
34
  spec.add_dependency 'faraday-typhoeus', '~> 1.1'
35
+
36
+ # Before upgrading, check this:
37
+ # https://github.com/gbaptista/gemini-ai/pull/10
35
38
  spec.add_dependency 'googleauth', '~> 1.8'
39
+
36
40
  spec.add_dependency 'typhoeus', '~> 1.4', '>= 1.4.1'
37
41
 
38
42
  spec.metadata['rubygems_mfa_required'] = 'true'
data/static/gem.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Gemini
4
4
  GEM = {
5
5
  name: 'gemini-ai',
6
- version: '3.2.0',
6
+ version: '4.0.0',
7
7
  author: 'gbaptista',
8
8
  summary: "Interact with Google's Gemini AI.",
9
9
  description: "A Ruby Gem for interacting with Gemini through Vertex AI, Generative Language API, or AI Studio, Google's generative AI services.",
@@ -23,7 +23,7 @@
23
23
  (remove nil?))]
24
24
  (->> processed-lines
25
25
  (map (fn [{:keys [level title link]}]
26
- (str (apply str (repeat (* 4 (- level 2)) " "))
26
+ (str (apply str (repeat (* 2 (- level 2)) " "))
27
27
  "- ["
28
28
  title
29
29
  "](#"
data/template.md CHANGED
@@ -9,7 +9,7 @@ A Ruby Gem for interacting with [Gemini](https://deepmind.google/technologies/ge
9
9
  ## TL;DR and Quick Start
10
10
 
11
11
  ```ruby
12
- gem 'gemini-ai', '~> 3.2.0'
12
+ gem 'gemini-ai', '~> 4.0.0'
13
13
  ```
14
14
 
15
15
  ```ruby
@@ -77,11 +77,11 @@ Result:
77
77
  ### Installing
78
78
 
79
79
  ```sh
80
- gem install gemini-ai -v 3.2.0
80
+ gem install gemini-ai -v 4.0.0
81
81
  ```
82
82
 
83
83
  ```sh
84
- gem 'gemini-ai', '~> 3.2.0'
84
+ gem 'gemini-ai', '~> 4.0.0'
85
85
  ```
86
86
 
87
87
  ### Credentials
@@ -270,6 +270,43 @@ client = Gemini.new(
270
270
  )
271
271
  ```
272
272
 
273
+ ## Available Models
274
+
275
+ These models are accessible to the repository **author** as of May 2025 in the `us-east4` region. Access to models may vary by region, user, and account. All models here are expected to work, if you can access them. This is just a reference of what a "typical" user may expect to have access to right away:
276
+
277
+ | Model | Vertex AI | Generative Language |
278
+ |------------------------------------------|:---------:|:-------------------:|
279
+ | gemini-pro-vision | ✅ | 🔒 |
280
+ | gemini-pro | ✅ | ✅ |
281
+ | gemini-1.5-pro-preview-0514 | ✅ | 🔒 |
282
+ | gemini-1.5-pro-preview-0409 | ✅ | 🔒 |
283
+ | gemini-1.5-pro | 🔒 | 🔒 |
284
+ | gemini-1.5-flash-preview-0514 | ✅ | 🔒 |
285
+ | gemini-1.5-flash | 🔒 | 🔒 |
286
+ | gemini-1.0-pro-vision-latest | 🔒 | 🔒 |
287
+ | gemini-1.0-pro-vision-001 | ✅ | 🔒 |
288
+ | gemini-1.0-pro-vision | ✅ | 🔒 |
289
+ | gemini-1.0-pro-latest | 🔒 | ✅ |
290
+ | gemini-1.0-pro-002 | ✅ | 🔒 |
291
+ | gemini-1.0-pro-001 | ✅ | ✅ |
292
+ | gemini-1.0-pro | ✅ | ✅ |
293
+ | text-embedding-004 | ✅ | ✅ |
294
+ | embedding-001 | 🔒 | ✅ |
295
+ | text-multilingual-embedding-002 | ✅ | 🔒 |
296
+ | textembedding-gecko-multilingual@001 | ✅ | 🔒 |
297
+ | textembedding-gecko-multilingual@latest | ✅ | 🔒 |
298
+ | textembedding-gecko@001 | ✅ | 🔒 |
299
+ | textembedding-gecko@002 | ✅ | 🔒 |
300
+ | textembedding-gecko@003 | ✅ | 🔒 |
301
+ | textembedding-gecko@latest | ✅ | 🔒 |
302
+
303
+ You can follow new models at:
304
+
305
+ - [Google models](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models)
306
+ - [Model versions and lifecycle](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning)
307
+
308
+ This is [the code](https://gist.github.com/gbaptista/d7390901293bce81ee12ff4ec5fed62c) used for generating this table that you can use to explore your own access.
309
+
273
310
  ## Usage
274
311
 
275
312
  ### Client
@@ -310,9 +347,11 @@ client = Gemini.new(
310
347
 
311
348
  ### Methods
312
349
 
313
- #### stream_generate_content
350
+ #### Chat
351
+
352
+ ##### stream_generate_content
314
353
 
315
- ##### Receiving Stream Events
354
+ ###### Receiving Stream Events
316
355
 
317
356
  Ensure that you have enabled [Server-Sent Events](#streaming-vs-server-sent-events-sse) before using blocks for streaming:
318
357
 
@@ -344,7 +383,7 @@ Event:
344
383
  } }
345
384
  ```
346
385
 
347
- ##### Without Events
386
+ ###### Without Events
348
387
 
349
388
  You can use `stream_generate_content` without events:
350
389
 
@@ -384,7 +423,7 @@ result = client.stream_generate_content(
384
423
  end
385
424
  ```
386
425
 
387
- #### generate_content
426
+ ##### generate_content
388
427
 
389
428
  ```ruby
390
429
  result = client.generate_content(
@@ -413,6 +452,58 @@ Result:
413
452
 
414
453
  As of the writing of this README, only the `generative-language-api` service supports the `generate_content` method; `vertex-ai-api` does not.
415
454
 
455
+ #### Embeddings
456
+
457
+ ##### predict
458
+
459
+ Vertex AI API generates embeddings through the `predict` method ([documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings)), and you need a client set up to use an embedding model (e.g. `text-embedding-004`):
460
+
461
+ ```ruby
462
+ result = client.predict(
463
+ { instances: [{ content: 'What is life?' }],
464
+ parameters: { autoTruncate: true } }
465
+ )
466
+ ```
467
+
468
+ Result:
469
+ ```ruby
470
+ { 'predictions' =>
471
+ [{ 'embeddings' =>
472
+ { 'statistics' => { 'truncated' => false, 'token_count' => 4 },
473
+ 'values' =>
474
+ [-0.006861076690256596,
475
+ 0.00020840796059928834,
476
+ -0.028549950569868088,
477
+ # ...
478
+ 0.0020092015620321035,
479
+ 0.03279878571629524,
480
+ -0.014905261807143688] } }],
481
+ 'metadata' => { 'billableCharacterCount' => 11 } }
482
+ ```
483
+
484
+ ##### embed_content
485
+
486
+ Generative Language API generates embeddings through the `embed_content` method ([documentation](https://ai.google.dev/api/rest/v1/models/embedContent)), and you need a client set up to use an embedding model (e.g. `text-embedding-004`):
487
+
488
+ ```ruby
489
+ result = client.embed_content(
490
+ { content: { parts: [{ text: 'What is life?' }] } }
491
+ )
492
+ ```
493
+
494
+ Result:
495
+ ```ruby
496
+ { 'embedding' =>
497
+ { 'values' =>
498
+ [-0.0065307906,
499
+ -0.0001632607,
500
+ -0.028370803,
501
+
502
+ 0.0019950708,
503
+ 0.032798845,
504
+ -0.014878989] } }
505
+ ```
506
+
416
507
  ### Modes
417
508
 
418
509
  #### Text
@@ -865,12 +956,25 @@ Which will result in:
865
956
 
866
957
  ### New Functionalities and APIs
867
958
 
868
- Google may launch a new endpoint that we haven't covered in the Gem yet. If that's the case, you may still be able to use it through the `request` method. For example, `stream_generate_content` is just a wrapper for `google/models/gemini-pro:streamGenerateContent`, which you can call directly like this:
959
+ Google may launch a new endpoint that we haven't covered in the Gem yet. If that's the case, you may still be able to use it through the `request` method. For example, `stream_generate_content` is just a wrapper for `models/gemini-pro:streamGenerateContent` (Generative Language API) or `publishers/google/models/gemini-pro:streamGenerateContent` (Vertex AI API), which you can call directly like this:
869
960
 
870
961
  ```ruby
962
+ # Generative Language API
871
963
  result = client.request(
872
- 'streamGenerateContent',
873
- { contents: { role: 'user', parts: { text: 'hi!' } } }
964
+ 'models/gemini-pro:streamGenerateContent',
965
+ { contents: { role: 'user', parts: { text: 'hi!' } } },
966
+ request_method: 'POST',
967
+ server_sent_events: true
968
+ )
969
+ ```
970
+
971
+ ```ruby
972
+ # Vertex AI API
973
+ result = client.request(
974
+ 'publishers/google/models/gemini-pro:streamGenerateContent',
975
+ { contents: { role: 'user', parts: { text: 'hi!' } } },
976
+ request_method: 'POST',
977
+ server_sent_events: true
874
978
  )
875
979
  ```
876
980
 
@@ -1000,7 +1104,7 @@ gem build gemini-ai.gemspec
1000
1104
 
1001
1105
  gem signin
1002
1106
 
1003
- gem push gemini-ai-3.2.0.gem
1107
+ gem push gemini-ai-4.0.0.gem
1004
1108
  ```
1005
1109
 
1006
1110
  ### Updating the README
@@ -1044,6 +1148,9 @@ These resources and references may be useful throughout your learning process.
1044
1148
  - [Gemini API Documentation](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini)
1045
1149
  - [Vertex AI API Documentation](https://cloud.google.com/vertex-ai/docs/reference)
1046
1150
  - [REST Documentation](https://cloud.google.com/vertex-ai/docs/reference/rest)
1151
+ - [Get text embeddings](https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings)
1152
+ - [Google models](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models)
1153
+ - [Model versions and lifecycle](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning)
1047
1154
  - [Google DeepMind Gemini](https://deepmind.google/technologies/gemini/)
1048
1155
  - [Stream responses from Generative AI models](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/streaming)
1049
1156
  - [Function calling](https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/function-calling)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemini-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gbaptista
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-24 00:00:00.000000000 Z
11
+ date: 2024-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: event_stream_parser