omniai-google 3.21.0 → 3.22.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/README.md +24 -0
- data/lib/omniai/google/chat.rb +5 -0
- data/lib/omniai/google/client.rb +45 -3
- data/lib/omniai/google/config.rb +6 -0
- data/lib/omniai/google/embed.rb +5 -0
- data/lib/omniai/google/live.rb +1 -1
- data/lib/omniai/google/transcribe/gemini.rb +7 -4
- data/lib/omniai/google/transcribe.rb +5 -0
- data/lib/omniai/google/transcribe_helpers.rb +4 -0
- data/lib/omniai/google/unknown_location_error.rb +17 -0
- data/lib/omniai/google/version.rb +1 -1
- data/lib/omniai/google/vertex.rb +25 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bdc1ade66e25bb33aca449a360b70e9e0df885996022ce6ed6bc8350137cf69c
|
|
4
|
+
data.tar.gz: f54782298b7bd730164e437564ac3184b23eeebb5df7779c429d9cc978d68983
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d7b57da0258da82684ac694c35d056b77b60ac2edbf6b3146c674f84b2906d42457915672276a5c19a8ea24ec6aa7108359e224ce33660e2c5eb6bbb110b692
|
|
7
|
+
data.tar.gz: b577e9ce548f3cae58d0fbffea9a933c648855f48a5455c277f04d77fd842b839de095e767da1f235f648994fe265fc7814d9b7acfb1412d91d91c4b5667349d
|
data/README.md
CHANGED
|
@@ -58,6 +58,30 @@ OmniAI::Google.configure do |config|
|
|
|
58
58
|
end
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
#### Vertex Locations per Model
|
|
62
|
+
|
|
63
|
+
No single Vertex location serves every model. To route each model to its own location, set `locations`; the host is
|
|
64
|
+
derived from the location the way Google's SDKs do it (`global`, the `us` / `eu` multi-regions, or a single region):
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
OmniAI::Google.configure do |config|
|
|
68
|
+
config.credentials = File.open("./credentials.json")
|
|
69
|
+
config.project_id = '...'
|
|
70
|
+
config.locations = {
|
|
71
|
+
'gemini-3.8-flash' => 'us', # https://aiplatform.us.rep.googleapis.com
|
|
72
|
+
'gemini-2.5-flash' => 'us-central1', # https://us-central1-aiplatform.googleapis.com
|
|
73
|
+
'gemini-embedding-001' => 'us-central1',
|
|
74
|
+
'chirp_3' => 'us',
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Applies to chat (including streaming), embed, transcribe and live. A mapped location is used as given.
|
|
80
|
+
- A model missing from the map raises `OmniAI::Google::UnknownLocationError` (with `#model`) before any request.
|
|
81
|
+
List every model you call, including any default you rely on (`Chat::DEFAULT_MODEL`, `Embed::DEFAULT_MODEL`,
|
|
82
|
+
`Transcribe::DEFAULT_MODEL`).
|
|
83
|
+
- A client built with an explicit `host:` or `location_id:` ignores the map.
|
|
84
|
+
|
|
61
85
|
**Note for Transcription**: When using transcription features, ensure your service account has the necessary permissions for Google Cloud Speech-to-Text API and Google Cloud Storage (for automatic file uploads). See the [GCS Setup](#gcs-setup-for-transcription) section below for detailed configuration.
|
|
62
86
|
|
|
63
87
|
Credentials may be configured using:
|
data/lib/omniai/google/chat.rb
CHANGED
|
@@ -76,6 +76,11 @@ module OmniAI
|
|
|
76
76
|
context.deserializers[:thinking] = ThinkingSerializer.method(:deserialize)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
# `client` is swapped for `client.for_model(model)`, so `locations` routes the request.
|
|
80
|
+
def initialize(prompt = nil, client:, model:, **, &)
|
|
81
|
+
super(prompt, client: client.for_model(model), model:, **, &)
|
|
82
|
+
end
|
|
83
|
+
|
|
79
84
|
protected
|
|
80
85
|
|
|
81
86
|
# @return [Context]
|
data/lib/omniai/google/client.rb
CHANGED
|
@@ -20,6 +20,10 @@ module OmniAI
|
|
|
20
20
|
#
|
|
21
21
|
# client = OmniAI::Google::Client.new
|
|
22
22
|
class Client < OmniAI::Client
|
|
23
|
+
# Marks `host` / `location_id` as not passed, so an explicit value can take precedence over `locations`.
|
|
24
|
+
UNSET = Object.new.freeze
|
|
25
|
+
private_constant :UNSET
|
|
26
|
+
|
|
23
27
|
# @!attribute [rw] version
|
|
24
28
|
# @return [String, nil]
|
|
25
29
|
attr_accessor :version
|
|
@@ -32,28 +36,56 @@ module OmniAI
|
|
|
32
36
|
# @param version [String] default is `OmniAI::Google.config.version`
|
|
33
37
|
# @param logger [Logger] default is `OmniAI::Google.config.logger`
|
|
34
38
|
# @param timeout [Integer] default is `OmniAI::Google.config.timeout`
|
|
39
|
+
# @param locations [Hash{String => String}, nil] default is `OmniAI::Google.config.locations`; ignored when
|
|
40
|
+
# `host` or `location_id` is passed
|
|
35
41
|
def initialize(
|
|
36
42
|
api_key: OmniAI::Google.config.api_key,
|
|
37
43
|
project_id: OmniAI::Google.config.project_id,
|
|
38
|
-
location_id:
|
|
44
|
+
location_id: UNSET,
|
|
39
45
|
credentials: OmniAI::Google.config.credentials,
|
|
40
46
|
logger: OmniAI::Google.config.logger,
|
|
41
|
-
host:
|
|
47
|
+
host: UNSET,
|
|
42
48
|
version: nil,
|
|
43
|
-
timeout: OmniAI::Google.config.timeout
|
|
49
|
+
timeout: OmniAI::Google.config.timeout,
|
|
50
|
+
locations: OmniAI::Google.config.locations
|
|
44
51
|
)
|
|
45
52
|
if api_key.nil? && credentials.nil?
|
|
46
53
|
raise(ArgumentError, "either an `api_key` or `credentials` must be provided")
|
|
47
54
|
end
|
|
48
55
|
|
|
56
|
+
pinned = !(UNSET.equal?(host) && UNSET.equal?(location_id))
|
|
57
|
+
@locations = locations unless pinned
|
|
58
|
+
host = OmniAI::Google.config.host if UNSET.equal?(host)
|
|
59
|
+
location_id = OmniAI::Google.config.location_id if UNSET.equal?(location_id)
|
|
60
|
+
|
|
49
61
|
super(api_key:, host:, logger:, timeout:)
|
|
50
62
|
|
|
51
63
|
@project_id = project_id
|
|
52
64
|
@location_id = location_id
|
|
53
65
|
@credentials = Credentials.parse(credentials)
|
|
66
|
+
@version_override = version
|
|
54
67
|
@version = version || default_version
|
|
55
68
|
end
|
|
56
69
|
|
|
70
|
+
# A copy of this client pointed at the model's location in `locations`, or this client when no map applies.
|
|
71
|
+
#
|
|
72
|
+
# @param model [String]
|
|
73
|
+
#
|
|
74
|
+
# @raise [UnknownLocationError] when the map has no entry for the model
|
|
75
|
+
#
|
|
76
|
+
# @return [Client]
|
|
77
|
+
def for_model(model)
|
|
78
|
+
return self if @locations.nil?
|
|
79
|
+
|
|
80
|
+
location_id = @locations.fetch(model) { raise UnknownLocationError, model }
|
|
81
|
+
dup.tap { |client| client.locate!(location_id) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [Boolean] true for a client returned by `#for_model`
|
|
85
|
+
def located?
|
|
86
|
+
@located || false
|
|
87
|
+
end
|
|
88
|
+
|
|
57
89
|
# @raise [OmniAI::Error]
|
|
58
90
|
#
|
|
59
91
|
# @param messages [String] optional
|
|
@@ -155,6 +187,16 @@ module OmniAI
|
|
|
155
187
|
false
|
|
156
188
|
end
|
|
157
189
|
|
|
190
|
+
protected
|
|
191
|
+
|
|
192
|
+
# @param location_id [String]
|
|
193
|
+
def locate!(location_id)
|
|
194
|
+
@location_id = location_id
|
|
195
|
+
@host = Vertex.host(location_id)
|
|
196
|
+
@version = @version_override || Config::Version::STABLE
|
|
197
|
+
@located = true
|
|
198
|
+
end
|
|
199
|
+
|
|
158
200
|
private
|
|
159
201
|
|
|
160
202
|
# Vertex AI serves `v1`; the Gemini API serves `v1beta`. `OmniAI::Google.config.version` derives from the
|
data/lib/omniai/google/config.rb
CHANGED
|
@@ -19,6 +19,12 @@ module OmniAI
|
|
|
19
19
|
# @return [String, nil]
|
|
20
20
|
attr_accessor :location_id
|
|
21
21
|
|
|
22
|
+
# @!attribute [rw] locations
|
|
23
|
+
# Vertex location per model, e.g. `{ "gemini-3.8-flash" => "us" }`. When set, each request derives its host
|
|
24
|
+
# from the model's location, and a model missing from the map raises `UnknownLocationError`.
|
|
25
|
+
# @return [Hash{String => String}, nil]
|
|
26
|
+
attr_accessor :locations
|
|
27
|
+
|
|
22
28
|
# @param api_key [String, nil] optional - defaults to `ENV['GOOGLE_API_KEY']`
|
|
23
29
|
# @param project_id [String, nil] optional - defaults to `ENV['GOOGLE_PROJECT_ID']`
|
|
24
30
|
# @param location_id [String, nil] optional - defaults to `ENV['GOOGLE_LOCATION_ID']`
|
data/lib/omniai/google/embed.rb
CHANGED
|
@@ -72,6 +72,11 @@ module OmniAI
|
|
|
72
72
|
context.deserializers[:usage] = USAGE_METADATA_DESERIALIZER
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
# `client` is swapped for `client.for_model(model)`, so `locations` routes the request.
|
|
76
|
+
def initialize(input, client:, model:, **)
|
|
77
|
+
super(input, client: client.for_model(model), model:, **)
|
|
78
|
+
end
|
|
79
|
+
|
|
75
80
|
protected
|
|
76
81
|
|
|
77
82
|
# Determines which endpoint to use based on client and model configuration.
|
data/lib/omniai/google/live.rb
CHANGED
|
@@ -76,7 +76,7 @@ module OmniAI
|
|
|
76
76
|
# @yieldparam event [Live::Event::*]
|
|
77
77
|
def initialize(client:, model: DEFAULT_MODEL, system: nil, tools: nil, tool_behavior: :blocking, voice: nil,
|
|
78
78
|
transcription: true, vad: nil, compression: false, resumption: nil, write_timeout: WRITE_TIMEOUT, &handler)
|
|
79
|
-
@client = client
|
|
79
|
+
@client = client.for_model(model)
|
|
80
80
|
@model = model
|
|
81
81
|
@system = system
|
|
82
82
|
@tools = tools || []
|
|
@@ -54,7 +54,7 @@ module OmniAI
|
|
|
54
54
|
def initialize(io, client:, model:, language: nil, format: nil, diarization: false, word_timestamps: false,
|
|
55
55
|
vocabulary: nil)
|
|
56
56
|
@io = io
|
|
57
|
-
@client = client
|
|
57
|
+
@client = client.for_model(model)
|
|
58
58
|
@model = model
|
|
59
59
|
@language = language
|
|
60
60
|
@format = format || OmniAI::Transcribe::Format::JSON
|
|
@@ -92,8 +92,12 @@ module OmniAI
|
|
|
92
92
|
# Served from the global endpoint and the us/eu multi-regions, never a single region, so a zonal Vertex
|
|
93
93
|
# location_id maps to its multi-region (same rule as Chirp 3); `us` is the default.
|
|
94
94
|
#
|
|
95
|
-
#
|
|
95
|
+
# A location from `locations` is used as given.
|
|
96
|
+
#
|
|
97
|
+
# @return [String] "global", "us" or "eu", unless mapped
|
|
96
98
|
def gemini_location_id
|
|
99
|
+
return @client.instance_variable_get(:@location_id) if @client.located?
|
|
100
|
+
|
|
97
101
|
case @client.instance_variable_get(:@location_id)
|
|
98
102
|
when "global" then "global"
|
|
99
103
|
when /\A(eu|europe)/i then "eu"
|
|
@@ -103,8 +107,7 @@ module OmniAI
|
|
|
103
107
|
|
|
104
108
|
# @return [String]
|
|
105
109
|
def host
|
|
106
|
-
|
|
107
|
-
location == "global" ? "https://aiplatform.googleapis.com" : "https://aiplatform.#{location}.rep.googleapis.com"
|
|
110
|
+
Vertex.host(gemini_location_id)
|
|
108
111
|
end
|
|
109
112
|
|
|
110
113
|
# @return [String]
|
|
@@ -49,6 +49,11 @@ module OmniAI
|
|
|
49
49
|
super
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
# `client` is swapped for `client.for_model(model)`, so `locations` routes the request.
|
|
53
|
+
def initialize(io, client:, model:, **)
|
|
54
|
+
super(io, client: client.for_model(model), model:, **)
|
|
55
|
+
end
|
|
56
|
+
|
|
52
57
|
# @raise [HTTPError]
|
|
53
58
|
#
|
|
54
59
|
# @return [OmniAI::Transcribe::Transcription]
|
|
@@ -12,8 +12,12 @@ module OmniAI
|
|
|
12
12
|
raise(ArgumentError, "project_id is required for transcription")
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# A location from `locations` is used as given; otherwise it is derived per model.
|
|
16
|
+
#
|
|
15
17
|
# @return [String]
|
|
16
18
|
def location_id
|
|
19
|
+
return @client.instance_variable_get(:@location_id) if @client.located?
|
|
20
|
+
|
|
17
21
|
case @model
|
|
18
22
|
when "chirp_2"
|
|
19
23
|
"us-central1"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniAI
|
|
4
|
+
module Google
|
|
5
|
+
# Raised before any request when `locations` is configured but has no entry for the model.
|
|
6
|
+
class UnknownLocationError < OmniAI::Error
|
|
7
|
+
# @return [String]
|
|
8
|
+
attr_reader :model
|
|
9
|
+
|
|
10
|
+
# @param model [String]
|
|
11
|
+
def initialize(model)
|
|
12
|
+
@model = model
|
|
13
|
+
super("no location configured for model #{model.inspect}")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniAI
|
|
4
|
+
module Google
|
|
5
|
+
# Vertex AI endpoints.
|
|
6
|
+
module Vertex
|
|
7
|
+
MULTI_REGIONS = %w[us eu].freeze
|
|
8
|
+
|
|
9
|
+
# The host serving a location, derived the way Google's own SDKs do (google-genai, vertexai).
|
|
10
|
+
#
|
|
11
|
+
# @param location_id [String] e.g. "global", "us" or "us-central1"
|
|
12
|
+
#
|
|
13
|
+
# @return [String]
|
|
14
|
+
def self.host(location_id)
|
|
15
|
+
if location_id.eql?("global")
|
|
16
|
+
"https://aiplatform.googleapis.com"
|
|
17
|
+
elsif MULTI_REGIONS.include?(location_id)
|
|
18
|
+
"https://aiplatform.#{location_id}.rep.googleapis.com"
|
|
19
|
+
else
|
|
20
|
+
"https://#{location_id}-aiplatform.googleapis.com"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omniai-google
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.22.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Sylvestre
|
|
@@ -144,9 +144,11 @@ files:
|
|
|
144
144
|
- lib/omniai/google/transcribe.rb
|
|
145
145
|
- lib/omniai/google/transcribe/gemini.rb
|
|
146
146
|
- lib/omniai/google/transcribe_helpers.rb
|
|
147
|
+
- lib/omniai/google/unknown_location_error.rb
|
|
147
148
|
- lib/omniai/google/upload.rb
|
|
148
149
|
- lib/omniai/google/upload/file.rb
|
|
149
150
|
- lib/omniai/google/version.rb
|
|
151
|
+
- lib/omniai/google/vertex.rb
|
|
150
152
|
homepage: https://github.com/ksylvest/omniai-google
|
|
151
153
|
licenses:
|
|
152
154
|
- MIT
|