omniai-google 3.14.0 → 3.15.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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc72ad3bc8cfe3181908f748f705708827ea8f10a3c533b9d1d4352d6f5d9df0
|
|
4
|
+
data.tar.gz: c29f890a61470dc3ddce22d5753ca4410a04ba91b93faab6381411805e41fdbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bdee9a2925e8ea39873fb8e34b94378aa0549d0b1443a3c20b55bef586dda1208514e042ee63c6780ed6ec8f457b24a7af85f9def73d82c1c77e4a6ca84a6db2
|
|
7
|
+
data.tar.gz: 3402943f6994d0489fc2382731e41e116667e3e93b09908dc6549c1f890f7ba2bdb397e27af9d4999fb925a7be19489c2f1566dae6e56dcf9cdb61bf731e20c2
|
|
@@ -18,11 +18,69 @@ module OmniAI
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
validate!
|
|
21
22
|
@data
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
protected
|
|
25
26
|
|
|
27
|
+
# Google reports a post-200 failure as an `error` object in the stream, which
|
|
28
|
+
# `process_data!` otherwise copies into @data and returns as an empty success.
|
|
29
|
+
def validate!
|
|
30
|
+
error = @data["error"]
|
|
31
|
+
if error
|
|
32
|
+
raise StreamError.new("the stream carried an error: #{error_summary(error)}",
|
|
33
|
+
provider_message: error["message"])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# No candidates at all (a usageMetadata-only stream) is incomplete too.
|
|
37
|
+
candidates = @data["candidates"] || []
|
|
38
|
+
incomplete = candidates.select { |candidate| incomplete?(candidate) }
|
|
39
|
+
return unless candidates.empty? || incomplete.any?
|
|
40
|
+
|
|
41
|
+
raise IncompleteStreamError,
|
|
42
|
+
"the stream ended without a finish reason: #{candidates_summary(incomplete)}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Only thought-only-and-empty counts. A missing finishReason alone would also condemn
|
|
46
|
+
# an unterminated stream that did deliver an answer, and discarding a usable answer to
|
|
47
|
+
# retry is the more expensive mistake.
|
|
48
|
+
def incomplete?(candidate)
|
|
49
|
+
return false if candidate["finishReason"]
|
|
50
|
+
|
|
51
|
+
parts = candidate.dig("content", "parts") || []
|
|
52
|
+
parts.none? { |part| part["functionCall"] || answer_part?(part) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# "" is truthy in Ruby, so an empty text part must not count as an answer.
|
|
56
|
+
def answer_part?(part)
|
|
57
|
+
!thought_part?(part) && !part["text"].to_s.strip.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Code and status only. Google's `message` can echo request content back, and consumers
|
|
61
|
+
# log these, so it is omitted for the same reason candidates_summary omits part text.
|
|
62
|
+
#
|
|
63
|
+
# @param error [Hash]
|
|
64
|
+
# @return [String]
|
|
65
|
+
def error_summary(error)
|
|
66
|
+
"code=#{error['code'].inspect} status=#{error['status'].inspect}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Structure only: consumers log these messages and part text may be sensitive.
|
|
70
|
+
#
|
|
71
|
+
# @param candidates [Array<Hash>]
|
|
72
|
+
# @return [String]
|
|
73
|
+
def candidates_summary(candidates)
|
|
74
|
+
return "candidates=0" if candidates.empty?
|
|
75
|
+
|
|
76
|
+
candidates.map.with_index do |candidate, index|
|
|
77
|
+
parts = candidate.dig("content", "parts") || []
|
|
78
|
+
"candidate=#{index} parts=#{parts.size} " \
|
|
79
|
+
"thought_parts=#{parts.count { |part| part['thought'] }} " \
|
|
80
|
+
"finish_reason=#{candidate['finishReason'].inspect}"
|
|
81
|
+
end.join("; ")
|
|
82
|
+
end
|
|
83
|
+
|
|
26
84
|
# @yield [delta]
|
|
27
85
|
# @yieldparam delta [OmniAI::Chat::Delta]
|
|
28
86
|
#
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniAI
|
|
4
|
+
module Google
|
|
5
|
+
# Raised when a stream ends with no `finishReason` and produced nothing but thinking.
|
|
6
|
+
# Rescue StreamError to catch this and stream errors together. `#provider_message` is
|
|
7
|
+
# always nil here -- there is no provider error to carry.
|
|
8
|
+
class IncompleteStreamError < StreamError; end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OmniAI
|
|
4
|
+
module Google
|
|
5
|
+
# Raised when a streamed generation does not complete.
|
|
6
|
+
#
|
|
7
|
+
# Deliberately has no `#response`: the request returned 200 and the failure arrived inside
|
|
8
|
+
# the stream. Consumers branch on that to decide whether to retry.
|
|
9
|
+
class StreamError < OmniAI::Error
|
|
10
|
+
# Google's own explanation of the failure, verbatim.
|
|
11
|
+
#
|
|
12
|
+
# Named for what it holds rather than borrowing `value` from FinishReason, which is a
|
|
13
|
+
# provider enum rather than prose. Kept off `#message` because consumers log that and
|
|
14
|
+
# this text can echo request content -- a deliberate departure from HTTPError, which puts
|
|
15
|
+
# the whole response body into its message.
|
|
16
|
+
#
|
|
17
|
+
# @return [String, nil]
|
|
18
|
+
attr_reader :provider_message
|
|
19
|
+
|
|
20
|
+
# @param message [String, nil]
|
|
21
|
+
# @param provider_message [String, nil]
|
|
22
|
+
def initialize(message = nil, provider_message: nil)
|
|
23
|
+
@provider_message = provider_message
|
|
24
|
+
super(message)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
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.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Sylvestre
|
|
@@ -122,6 +122,8 @@ files:
|
|
|
122
122
|
- lib/omniai/google/config.rb
|
|
123
123
|
- lib/omniai/google/credentials.rb
|
|
124
124
|
- lib/omniai/google/embed.rb
|
|
125
|
+
- lib/omniai/google/incomplete_stream_error.rb
|
|
126
|
+
- lib/omniai/google/stream_error.rb
|
|
125
127
|
- lib/omniai/google/transcribe.rb
|
|
126
128
|
- lib/omniai/google/transcribe_helpers.rb
|
|
127
129
|
- lib/omniai/google/upload.rb
|