gemini_cache 0.0.6 → 0.0.9

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: 276c3ca26a6767aad15542bae697d58b6f6c546827c668bc922632d391ea0598
4
- data.tar.gz: 672b16527768229e7d84819b7d2b2844c41fe57c57e1bf1171414c182e8cc101
3
+ metadata.gz: ae4847ce3abf808c2779601462af28a47989301593355a8a39977a5df495f322
4
+ data.tar.gz: 71e72d0e2750d6b530d407f97a7490c65b6acbf342ad10803916b4b24d418b71
5
5
  SHA512:
6
- metadata.gz: 69700db12b8f6c8e78e3a3577843bc01f6fda112aec173653419c0674dd91baa59aee0a03be37eda62d9f1cf07e8a3892c47f28ec29d7a539d29b0d984988e3e
7
- data.tar.gz: 6992ec6e1537b00dc69de4afe0f13457a75758d6327f8c2bafecd9fb868e833d26a499363649e78e08ba9ac680641453fd572aaa52e4075ebac16885897e57a8
6
+ metadata.gz: 8ab29a93e9555626f6d1eecb189351b5d62b28805e0e90e0ba9c29cb9e5bcf8698f72dadb0621ffbf196503d186a2c341b45c387bc25f940d055bb110455ff78
7
+ data.tar.gz: 50a917b60662ecd5bc1cef90c0a633febfcfbe294c297525d397f60863dfaa29977e43c0743c9f717452fa7d45ce5fe2da8f11f3816d0f65fa5e06f6632675ff
@@ -0,0 +1,46 @@
1
+ module ItemExtender
2
+ def delete = GeminiCache.delete(name: self['name'])
3
+
4
+ def ttl=(new_ttl)
5
+ GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" })
6
+ GeminiCache.get_by_name(name: self['name'])
7
+ end
8
+
9
+ def generate_content(contents:, generation_config: nil)
10
+ conn = Faraday.new(
11
+ url: 'https://generativelanguage.googleapis.com',
12
+ headers: { 'Content-Type' => 'application/json' }
13
+ ) do |f|
14
+ f.options.timeout = 300 # timeout em segundos para a requisição completa
15
+ f.options.open_timeout = 300 # timeout em segundos para abrir a conexão
16
+ end
17
+
18
+ body = {
19
+ cached_content: self['name'],
20
+ contents:
21
+ }
22
+
23
+ body[:generation_config] = generation_config if !generation_config.nil?
24
+
25
+ response = conn.post("/v1beta/models/#{self['model'].split('/').last}:generateContent") do |req|
26
+ req.params['key'] = ENV.fetch('GEMINI_API_KEY')
27
+ req.body = body.to_json
28
+ end
29
+
30
+ if response.status == 200
31
+ resp = JSON.parse(response.body)
32
+ def resp.content = dig('candidates', 0, 'content', 'parts', 0, 'text')
33
+ return resp
34
+ end
35
+
36
+ raise "Erro ao gerar conteúdo: #{response.body}"
37
+ rescue Faraday::Error => e
38
+ raise "Erro na requisição: #{e.message}"
39
+ end
40
+
41
+ def single_prompt(prompt:, generation_config: :accurate_mode)
42
+ # accurate_mode: less creative, more accurate
43
+ generation_config = { temperature: 0, topP: 0, topK: 1 } if generation_config.eql?(:accurate_mode)
44
+ generate_content(contents: [{ parts: [{ text: prompt }], role: 'user' }], generation_config:).content
45
+ end
46
+ end
data/lib/gemini_cache.rb CHANGED
@@ -2,10 +2,22 @@ require 'faraday'
2
2
  require 'open-uri'
3
3
  require 'nokogiri'
4
4
  require 'json'
5
+ require 'base64'
6
+
7
+ require 'gemini_cache/item_extender'
5
8
 
6
9
  module GeminiCache
7
- def self.create(parts:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 600)
8
- raise "Cache name already exist: '#{display_name}'" if GeminiCache.get(display_name:)
10
+ def self.read_local_file(path:, mime_type:) = { inline_data: { mime_type:, data: Base64.strict_encode64(File.read(path)) } }
11
+ def self.read_remote_file(url:, mime_type:) = { inline_data: { mime_type:, data: Base64.strict_encode64(URI.open(url).read) } }
12
+ def self.read_html(url:, default_remover: true)
13
+ doc = Nokogiri::HTML(URI.open(url))
14
+ %w[script style].each { |element| doc.css(element).each(&:remove) } if default_remover
15
+
16
+ doc
17
+ end
18
+
19
+ def self.create(parts:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 300)
20
+ raise "Cache name already exist: '#{display_name}'" if GeminiCache.get_by_display_name(display_name:)
9
21
 
10
22
  content = {
11
23
  model: "models/#{model}",
@@ -24,21 +36,32 @@ module GeminiCache
24
36
  req.body = content
25
37
  end
26
38
 
27
- return JSON.parse(response.body) if response.status == 200
39
+ return get_by_name(name: JSON.parse(response.body)['name']) if response.status == 200
28
40
 
29
41
  raise "Erro ao criar cache: #{response.status} - #{response.body}"
30
42
  rescue Faraday::Error => e
31
43
  raise "Erro na requisição: #{e.message}"
32
44
  end
33
45
 
34
- def self.get(name: nil, display_name: nil)
35
- raise 'Nome do cache ou display name é obrigatório' if name.nil? && display_name.nil?
36
- raise 'Nome do cache e display name não podem ser informados juntos' if !name.nil? && !display_name.nil?
37
-
38
- return GeminiCache.list.find { |item| item['name'].eql? name } if !name.nil?
39
- return GeminiCache.list.find { |item| item['displayName'].eql? display_name } if !display_name.nil?
46
+ def self.create_from_text(text:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 300)
47
+ GeminiCache.create(parts: [{ text: }], display_name:, model:, ttl:)
40
48
  end
41
49
 
50
+ def self.create_from_webpage(url:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 300)
51
+ create_from_text(text: GeminiCache.read_html(url:).inner_text, display_name:, model:, ttl:)
52
+ end
53
+
54
+ def self.create_from_local_file(path:, mime_type:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 300)
55
+ GeminiCache.create(parts: GeminiCache.read_local_file(path:, mime_type:), display_name:, model:, ttl:)
56
+ end
57
+
58
+ def self.create_from_remote_file(url:, mime_type:, display_name:, model: 'gemini-1.5-flash-8b', ttl: 300)
59
+ GeminiCache.create(parts: GeminiCache.read_remote_file(url:, mime_type:), display_name:, model:, ttl:)
60
+ end
61
+
62
+ def self.get_by_name(name: nil) = GeminiCache.list.find { |item| item['name'].eql? name }
63
+ def self.get_by_display_name(display_name: nil) = GeminiCache.list.find { |item| item['displayName'].eql? display_name }
64
+
42
65
  def self.list
43
66
  conn = Faraday.new(
44
67
  url: 'https://generativelanguage.googleapis.com',
@@ -51,51 +74,7 @@ module GeminiCache
51
74
 
52
75
  return [] if JSON.parse(response.body).empty?
53
76
 
54
- JSON.parse(response.body)['cachedContents'].map do |item|
55
- def item.delete = GeminiCache.delete(name: self['name'])
56
- def item.set_ttl(ttl = 120) = GeminiCache.update(name: self['name'], content: { ttl: "#{ttl}s" })
57
-
58
- def item.generate_content(contents:, generation_config: nil)
59
- conn = Faraday.new(
60
- url: 'https://generativelanguage.googleapis.com',
61
- headers: { 'Content-Type' => 'application/json' }
62
- ) do |f|
63
- f.options.timeout = 300 # timeout em segundos para a requisição completa
64
- f.options.open_timeout = 300 # timeout em segundos para abrir a conexão
65
- end
66
-
67
- body = {
68
- cached_content: self['name'],
69
- contents:
70
- }
71
-
72
- body[:generation_config] = generation_config if !generation_config.nil?
73
-
74
- response = conn.post("/v1beta/models/#{self['model'].split('/').last}:generateContent") do |req|
75
- req.params['key'] = ENV.fetch('GEMINI_API_KEY')
76
- req.body = body.to_json
77
- end
78
-
79
- if response.status == 200
80
- resp = JSON.parse(response.body)
81
- def resp.content = dig('candidates', 0, 'content', 'parts', 0, 'text')
82
- return resp
83
- end
84
-
85
- raise "Erro ao gerar conteúdo: #{response.body}"
86
- rescue Faraday::Error => e
87
- raise "Erro na requisição: #{e.message}"
88
- end
89
-
90
- def item.single_prompt(prompt:, generation_config: :accurate_mode)
91
- # accurate_mode: less creative, more accurate
92
- generation_config = { temperature: 0, topP: 0, topK: 1 } if generation_config.eql?(:accurate_mode)
93
-
94
- generate_content(contents: [{ parts: [{ text: prompt }], role: 'user' }], generation_config:).content
95
- end
96
-
97
- item
98
- end
77
+ JSON.parse(response.body)['cachedContents'].map { |item| item.extend(ItemExtender) }
99
78
 
100
79
  rescue Faraday::Error => e
101
80
  raise "Erro na requisição: #{e.message}"
@@ -143,13 +122,4 @@ module GeminiCache
143
122
  class << self
144
123
  alias clear delete_all
145
124
  end
146
-
147
- def self.read_local_file(file_path) = Base64.strict_encode64(File.read(file_path))
148
- def self.read_remote_file(file_url) = Base64.strict_encode64(URI.open(file_url).read)
149
-
150
- def self.read_nokogiri_html(url, default_remover: true)
151
- doc = Nokogiri::HTML(URI.open(url))
152
- %w[script style].each { |element| doc.css(element).each(&:remove) } if default_remover
153
- doc
154
- end
155
125
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemini_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gedean Dias
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1'
27
55
  description: Ruby's Gemini Context Caching wrapper
28
56
  email: gedean.dias@gmail.com
29
57
  executables: []
@@ -31,6 +59,7 @@ extensions: []
31
59
  extra_rdoc_files: []
32
60
  files:
33
61
  - lib/gemini_cache.rb
62
+ - lib/gemini_cache/item_extender.rb
34
63
  homepage: https://github.com/gedean/gemini_cache
35
64
  licenses:
36
65
  - MIT