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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c46802e2152430f164990a91499be669e928201e7793b162f8f62152349078af
4
- data.tar.gz: 58269b584d08e9d236a3d85ac5728f4e4453a845ace9ebbf8c1ac22890609a1f
3
+ metadata.gz: 01f2984f551757482fbf590485875bef064060d27eb84d3d4325e307db1029c5
4
+ data.tar.gz: a492d121a5dc1916412296269cf0055ce14512855fecb94e2b018dcefb9b404d
5
5
  SHA512:
6
- metadata.gz: 9003c9cac451081ce0589f54acb2d72813e53a8708426e320e30732aa5842d99187af14f1c54bab69cfcc3bcc401529375377547a090f530aa1da140fd0a4b3f
7
- data.tar.gz: 691e4ebfd80fcfa7af22f1ca26393256a69ddf6957be8960590eebddc5e20a1a30db3ba8cfc1ae65dba10491df6f2844fd72d3ca2444420cb23db357a0225e25
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
- @completed[index.to_i] || to_a[index.to_i]
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.0-flash-exp-image-generation", **params)
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.0-flash-exp-image-generation", **params)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLM
4
- VERSION = "0.16.1"
4
+ VERSION = "0.16.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antar Azri