gemini_cache 0.0.6 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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