omniai-google 3.10.0 → 3.13.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 +1 -1
- data/lib/omniai/google/chat/usage_serializer.rb +33 -5
- data/lib/omniai/google/chat.rb +4 -2
- data/lib/omniai/google/client.rb +15 -2
- data/lib/omniai/google/embed.rb +7 -0
- data/lib/omniai/google/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8dab5e45bcb29a2506c505023b188ff9bfab5e000529a84bf691d5fbd576f66d
|
|
4
|
+
data.tar.gz: 2f77225d19897c818297fdd225721d5aa412b95edcf4f4445c2d309662b3360e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8c5582f5d5a94cdac496da59f9840799ba3786a26047afe269e06deabf120886e704474b976cebb9b35ee947e31031f8b00479cd8d0f2d6ff0a551878799219c
|
|
7
|
+
data.tar.gz: 6c9bd1633e7deba0331cdf3134381b25b195e869c3607139797decc04b43d57b424ffbfc83234035b955cac22a37a635f34981adab55dddfc67949b586f27cb0
|
data/README.md
CHANGED
|
@@ -87,7 +87,7 @@ completion.text # 'The capital of Canada is Ottawa.'
|
|
|
87
87
|
|
|
88
88
|
#### Model
|
|
89
89
|
|
|
90
|
-
`model` takes an optional string (default is `gemini-3.
|
|
90
|
+
`model` takes an optional string (default is `gemini-3.7-flash`):
|
|
91
91
|
|
|
92
92
|
```ruby
|
|
93
93
|
completion = client.chat('How fast is a cheetah?', model: OmniAI::Google::Chat::Model::GEMINI_FLASH)
|
|
@@ -5,23 +5,51 @@ module OmniAI
|
|
|
5
5
|
class Chat
|
|
6
6
|
# Overrides usage serialize / deserialize.
|
|
7
7
|
module UsageSerializer
|
|
8
|
+
# Gemini reports thinking separately from the answer: `candidatesTokenCount` covers the answer only, while
|
|
9
|
+
# `thoughtsTokenCount` covers internal reasoning. Google bills both as output and `totalTokenCount` includes
|
|
10
|
+
# both, so `output_tokens` is the sum — matching Anthropic and OpenAI, where reasoning is already folded into
|
|
11
|
+
# the output count and reported back only as a breakdown.
|
|
12
|
+
#
|
|
8
13
|
# @param usage [OmniAI::Chat::Usage]
|
|
9
14
|
# @return [Hash]
|
|
10
15
|
def self.serialize(usage, *)
|
|
11
|
-
|
|
16
|
+
thinking_tokens = usage.thinking_tokens
|
|
17
|
+
candidates_tokens = usage.output_tokens
|
|
18
|
+
# `thinking_tokens` is a subset of `output_tokens`, so this cannot go negative for any Usage this gem
|
|
19
|
+
# builds. Clamp anyway: a hand-constructed Usage that violates the subset invariant should not produce a
|
|
20
|
+
# negative token count on the wire.
|
|
21
|
+
candidates_tokens = [candidates_tokens - thinking_tokens, 0].max if candidates_tokens && thinking_tokens
|
|
22
|
+
|
|
23
|
+
data = {
|
|
12
24
|
promptTokenCount: usage.input_tokens,
|
|
13
|
-
candidatesTokenCount:
|
|
25
|
+
candidatesTokenCount: candidates_tokens,
|
|
14
26
|
totalTokenCount: usage.total_tokens,
|
|
15
27
|
}
|
|
28
|
+
# Gemini omits the key entirely when nothing was thought; only emit it when there is a value to report.
|
|
29
|
+
data[:thoughtsTokenCount] = thinking_tokens unless thinking_tokens.nil?
|
|
30
|
+
data
|
|
16
31
|
end
|
|
17
32
|
|
|
33
|
+
# Returns `nil` when the payload carries no token counts at all. A truncated stream still assembles a
|
|
34
|
+
# `usageMetadata` — Gemini sends one on every chunk, carrying only `trafficType` until the terminal chunk —
|
|
35
|
+
# so the presence of the key is not the presence of usage. Building a Usage from it would report every
|
|
36
|
+
# count as `nil`, which arithmetic downstream silently turns into zero.
|
|
37
|
+
#
|
|
38
|
+
# The test is strictly "no count is present", never "the counts are falsy": a reported `0` is a count.
|
|
39
|
+
#
|
|
18
40
|
# @param data [Hash]
|
|
19
|
-
# @return [OmniAI::Chat::Usage]
|
|
41
|
+
# @return [OmniAI::Chat::Usage, nil]
|
|
20
42
|
def self.deserialize(data, *)
|
|
21
43
|
input_tokens = data["promptTokenCount"]
|
|
22
|
-
|
|
44
|
+
candidates_tokens = data["candidatesTokenCount"]
|
|
45
|
+
thinking_tokens = data["thoughtsTokenCount"]
|
|
23
46
|
total_tokens = data["totalTokenCount"]
|
|
24
|
-
|
|
47
|
+
|
|
48
|
+
return if [input_tokens, candidates_tokens, thinking_tokens, total_tokens].all?(&:nil?)
|
|
49
|
+
|
|
50
|
+
output_tokens = (candidates_tokens || 0) + (thinking_tokens || 0) if candidates_tokens || thinking_tokens
|
|
51
|
+
|
|
52
|
+
OmniAI::Chat::Usage.new(input_tokens:, output_tokens:, total_tokens:, thinking_tokens:)
|
|
25
53
|
end
|
|
26
54
|
end
|
|
27
55
|
end
|
data/lib/omniai/google/chat.rb
CHANGED
|
@@ -23,11 +23,13 @@ module OmniAI
|
|
|
23
23
|
GEMINI_2_5_FLASH = "gemini-2.5-flash"
|
|
24
24
|
GEMINI_3_FLASH = "gemini-3-flash-preview"
|
|
25
25
|
GEMINI_3_5_FLASH = "gemini-3.5-flash"
|
|
26
|
+
GEMINI_3_6_FLASH = "gemini-3.6-flash"
|
|
27
|
+
GEMINI_3_7_FLASH = "gemini-3.7-flash"
|
|
26
28
|
GEMINI_PRO = GEMINI_3_1_PRO
|
|
27
|
-
GEMINI_FLASH =
|
|
29
|
+
GEMINI_FLASH = GEMINI_3_7_FLASH
|
|
28
30
|
end
|
|
29
31
|
|
|
30
|
-
DEFAULT_MODEL = Model::
|
|
32
|
+
DEFAULT_MODEL = Model::GEMINI_FLASH
|
|
31
33
|
|
|
32
34
|
module ResponseMimeType
|
|
33
35
|
JSON = "application/json"
|
data/lib/omniai/google/client.rb
CHANGED
|
@@ -39,7 +39,7 @@ module OmniAI
|
|
|
39
39
|
credentials: OmniAI::Google.config.credentials,
|
|
40
40
|
logger: OmniAI::Google.config.logger,
|
|
41
41
|
host: OmniAI::Google.config.host,
|
|
42
|
-
version:
|
|
42
|
+
version: nil,
|
|
43
43
|
timeout: OmniAI::Google.config.timeout
|
|
44
44
|
)
|
|
45
45
|
if api_key.nil? && credentials.nil?
|
|
@@ -51,7 +51,7 @@ module OmniAI
|
|
|
51
51
|
@project_id = project_id
|
|
52
52
|
@location_id = location_id
|
|
53
53
|
@credentials = Credentials.parse(credentials)
|
|
54
|
-
@version = version
|
|
54
|
+
@version = version || default_version
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# @raise [OmniAI::Error]
|
|
@@ -128,6 +128,19 @@ module OmniAI
|
|
|
128
128
|
|
|
129
129
|
private
|
|
130
130
|
|
|
131
|
+
# Vertex AI serves `v1`; the Gemini API serves `v1beta`. `OmniAI::Google.config.version` derives from the
|
|
132
|
+
# *config's* host, not this client's, so a client constructed with a Vertex host but an otherwise default
|
|
133
|
+
# config inherited `v1beta` and produced `/v1beta/projects/.../locations/...`, which 404s against every
|
|
134
|
+
# regional endpoint.
|
|
135
|
+
#
|
|
136
|
+
# Only the Vertex case is derived from this client's host. Any other custom host — a proxy or gateway in
|
|
137
|
+
# front of the Gemini API — keeps deferring to the config, so those callers are unaffected.
|
|
138
|
+
#
|
|
139
|
+
# @return [String]
|
|
140
|
+
def default_version
|
|
141
|
+
vertex? ? Config::Version::STABLE : OmniAI::Google.config.version
|
|
142
|
+
end
|
|
143
|
+
|
|
131
144
|
# @return [String] e.g. "Bearer ..."
|
|
132
145
|
def auth
|
|
133
146
|
@credentials.fetch_access_token!
|
data/lib/omniai/google/embed.rb
CHANGED
|
@@ -40,6 +40,13 @@ module OmniAI
|
|
|
40
40
|
[data["embedding"]["values"]]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
# Always returns a Usage, never nil — callers rely on `response.usage` being present here without a nil check.
|
|
44
|
+
#
|
|
45
|
+
# This deliberately differs from the chat-side `UsageSerializer`, which returns nil when the payload carries
|
|
46
|
+
# no token counts at all (a truncated Gemini stream still sends a `usageMetadata` containing only
|
|
47
|
+
# `trafficType`). Embeddings have no streaming path and so no equivalent partial payload, so there is nothing
|
|
48
|
+
# to distinguish. Do not make this nil-safe "for consistency" with chat: it would turn an unguarded
|
|
49
|
+
# `response.usage.total_tokens` in a consumer into a NoMethodError.
|
|
43
50
|
USAGE_METADATA_DESERIALIZER = proc do |data, *|
|
|
44
51
|
prompt_tokens = data.dig("usageMetadata", "promptTokenCount")
|
|
45
52
|
total_tokens = data.dig("usageMetadata", "totalTokenCount")
|
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.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Sylvestre
|
|
@@ -57,14 +57,14 @@ dependencies:
|
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '3.
|
|
60
|
+
version: '3.8'
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '3.
|
|
67
|
+
version: '3.8'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: openssl
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|