llm.rb 0.16.1 → 0.16.2
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/lib/llm/buffer.rb +10 -2
- data/lib/llm/error.rb +4 -0
- data/lib/llm/providers/gemini/images.rb +11 -4
- data/lib/llm/providers/gemini/response/image.rb +5 -0
- data/lib/llm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01f2984f551757482fbf590485875bef064060d27eb84d3d4325e307db1029c5
|
4
|
+
data.tar.gz: a492d121a5dc1916412296269cf0055ce14512855fecb94e2b018dcefb9b404d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 341d074d9d732056599d6f27865f8fcf3fecd0f6062de73ec5dffcd056031e727c43f8058c472d69b598ae3fa4232bb47b960b331b20b8f7cc9323a86e9beeb7
|
7
|
+
data.tar.gz: aa9c19a4b51b8c379f6d8a8f486172e332d6ca1fb4a3f65fa2b32ff7685a3f48fd6d5db0092bcc3a97fca7f36b4f4214df1dfd675ad1215a172e5ae9ce76cc00
|
data/lib/llm/buffer.rb
CHANGED
@@ -65,12 +65,20 @@ module LLM
|
|
65
65
|
alias_method :push, :<<
|
66
66
|
|
67
67
|
##
|
68
|
-
# @param [Integer, #to_i] index
|
68
|
+
# @param [Integer, Range, #to_i] index
|
69
69
|
# The message index
|
70
70
|
# @return [LLM::Message, nil]
|
71
71
|
# Returns a message, or nil
|
72
72
|
def [](index)
|
73
|
-
|
73
|
+
if index.respond_to?(:to_i)
|
74
|
+
@completed[index.to_i] || to_a[index.to_i]
|
75
|
+
elsif Range === index
|
76
|
+
slice = @completed[index]
|
77
|
+
invalidate = slice.nil? || slice.size < index.size
|
78
|
+
invalidate ? to_a[index] : slice
|
79
|
+
else
|
80
|
+
raise TypeError, "index must be an Integer or Range"
|
81
|
+
end
|
74
82
|
end
|
75
83
|
|
76
84
|
##
|
data/lib/llm/error.rb
CHANGED
@@ -35,6 +35,10 @@ module LLM
|
|
35
35
|
# HTTPServerError
|
36
36
|
ServerError = Class.new(ResponseError)
|
37
37
|
|
38
|
+
##
|
39
|
+
# When no images are found in a response
|
40
|
+
NoImageError = Class.new(ResponseError)
|
41
|
+
|
38
42
|
##
|
39
43
|
# When an given an input object that is not understood
|
40
44
|
FormatError = Class.new(Error)
|
@@ -36,12 +36,13 @@ class LLM::Gemini
|
|
36
36
|
# @param [String] prompt The prompt
|
37
37
|
# @param [Hash] params Other parameters (see Gemini docs)
|
38
38
|
# @raise (see LLM::Provider#request)
|
39
|
+
# @raise [LLM::NoImageError] when no images are returned
|
39
40
|
# @note
|
40
41
|
# The prompt should make it clear you want to generate an image, or you
|
41
42
|
# might unexpectedly receive a purely textual response. This is due to how
|
42
43
|
# Gemini implements image generation under the hood.
|
43
44
|
# @return [LLM::Response]
|
44
|
-
def create(prompt:, model: "gemini-2.
|
45
|
+
def create(prompt:, model: "gemini-2.5-flash-image-preview", **params)
|
45
46
|
req = Net::HTTP::Post.new("/v1beta/models/#{model}:generateContent?key=#{key}", headers)
|
46
47
|
body = JSON.dump({
|
47
48
|
contents: [{parts: [{text: create_prompt}, {text: prompt}]}],
|
@@ -49,7 +50,7 @@ class LLM::Gemini
|
|
49
50
|
}.merge!(params))
|
50
51
|
req.body = body
|
51
52
|
res = execute(request: req)
|
52
|
-
LLM::Response.new(res).extend(LLM::Gemini::Response::Image)
|
53
|
+
validate LLM::Response.new(res).extend(LLM::Gemini::Response::Image)
|
53
54
|
end
|
54
55
|
|
55
56
|
##
|
@@ -63,9 +64,10 @@ class LLM::Gemini
|
|
63
64
|
# @param [String] prompt The prompt
|
64
65
|
# @param [Hash] params Other parameters (see Gemini docs)
|
65
66
|
# @raise (see LLM::Provider#request)
|
67
|
+
# @raise [LLM::NoImageError] when no images are returned
|
66
68
|
# @note (see LLM::Gemini::Images#create)
|
67
69
|
# @return [LLM::Response]
|
68
|
-
def edit(image:, prompt:, model: "gemini-2.
|
70
|
+
def edit(image:, prompt:, model: "gemini-2.5-flash-image-preview", **params)
|
69
71
|
req = Net::HTTP::Post.new("/v1beta/models/#{model}:generateContent?key=#{key}", headers)
|
70
72
|
image = LLM.File(image)
|
71
73
|
body = JSON.dump({
|
@@ -74,7 +76,7 @@ class LLM::Gemini
|
|
74
76
|
}.merge!(params)).b
|
75
77
|
set_body_stream(req, StringIO.new(body))
|
76
78
|
res = execute(request: req)
|
77
|
-
LLM::Response.new(res).extend(LLM::Gemini::Response::Image)
|
79
|
+
validate LLM::Response.new(res).extend(LLM::Gemini::Response::Image)
|
78
80
|
end
|
79
81
|
|
80
82
|
##
|
@@ -119,6 +121,11 @@ class LLM::Gemini
|
|
119
121
|
PROMPT
|
120
122
|
end
|
121
123
|
|
124
|
+
def validate(res)
|
125
|
+
return res unless res.images.empty?
|
126
|
+
raise LLM::NoImageError.new { _1.response = res.res }, "no images found in response"
|
127
|
+
end
|
128
|
+
|
122
129
|
[:headers, :execute, :set_body_stream].each do |m|
|
123
130
|
define_method(m) { |*args, **kwargs, &b| @provider.send(m, *args, **kwargs, &b) }
|
124
131
|
end
|
@@ -22,5 +22,10 @@ module LLM::Gemini::Response
|
|
22
22
|
# will always return an empty array.
|
23
23
|
# @return [Array<String>]
|
24
24
|
def urls = []
|
25
|
+
|
26
|
+
##
|
27
|
+
# Returns one or more candidates, or an empty array
|
28
|
+
# @return [Array<Hash>]
|
29
|
+
def candidates = body.candidates || []
|
25
30
|
end
|
26
31
|
end
|
data/lib/llm/version.rb
CHANGED