gemini_cache 0.0.9 → 0.0.11

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: ae4847ce3abf808c2779601462af28a47989301593355a8a39977a5df495f322
4
- data.tar.gz: 71e72d0e2750d6b530d407f97a7490c65b6acbf342ad10803916b4b24d418b71
3
+ metadata.gz: 5f3682e46bf67ce3fae20c5e27210eafdadc25338a54eecfec4c9f48a726ce7a
4
+ data.tar.gz: '0393aa11b0f296e72cbd7604be9061ad0186df90cfaeb6d5665b4d77d893d700'
5
5
  SHA512:
6
- metadata.gz: 8ab29a93e9555626f6d1eecb189351b5d62b28805e0e90e0ba9c29cb9e5bcf8698f72dadb0621ffbf196503d186a2c341b45c387bc25f940d055bb110455ff78
7
- data.tar.gz: 50a917b60662ecd5bc1cef90c0a633febfcfbe294c297525d397f60863dfaa29977e43c0743c9f717452fa7d45ce5fe2da8f11f3816d0f65fa5e06f6632675ff
6
+ metadata.gz: 5caf764b56efeb6234a03248b9dca22d7f84d2a885e7dca10651b80c49c2c390f473db4cd92037965af2f2ee3718cc78565db2bb257963b8137a9504056590ea
7
+ data.tar.gz: fba129ed606d3c62a5f39149cd2359fd5d6c18d01a978ffee0bff4a3968fc2c9f2f49723ffe6421192399b021e0023d9766fc7601ebf321e9619ea2b54a77834
data/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # GeminiCache
2
+
3
+ GeminiCache é uma biblioteca Ruby para interagir com a API de Cache do Google Gemini. Ela fornece uma interface simples para criar, gerenciar e manipular caches de conteúdo para uso com os modelos de IA do Gemini.
4
+
5
+ ## Instalação
6
+
7
+ Adicione esta linha ao Gemfile da sua aplicação:
8
+
9
+ ```ruby
10
+ gem 'gemini_cache'
11
+ ```
12
+
13
+ E então execute:
14
+
15
+ ```bash
16
+ $ bundle install
17
+ ```
18
+
19
+ Ou instale manualmente:
20
+
21
+ ```bash
22
+ $ gem install gemini_cache
23
+ ```
24
+
25
+ ## Configuração
26
+
27
+ Antes de usar a biblioteca, você precisa configurar sua chave de API do Google Gemini. Você pode fazer isso de duas maneiras:
28
+
29
+ ### 1. Usando variáveis de ambiente
30
+
31
+ ```bash
32
+ export GEMINI_API_KEY='sua_chave_api_aqui'
33
+ ```
34
+
35
+ ### 2. Usando o bloco de configuração
36
+
37
+ ```ruby
38
+ GeminiCache.configure do |config|
39
+ config.api_key = 'sua_chave_api_aqui'
40
+ config.timeout = 30 # opcional, tempo limite em segundos
41
+ config.cache_dir = '/path/to/cache' # opcional, diretório para cache local
42
+ end
43
+ ```
44
+
45
+ ## Uso Básico
46
+
47
+ ### Inicializando o Cliente
48
+
49
+ ```ruby
50
+ cache = GeminiCache::Client.new
51
+ ```
52
+
53
+ ### Operações Básicas
54
+
55
+ #### Armazenando dados no cache
56
+
57
+ ```ruby
58
+ # Armazena um valor com uma chave
59
+ cache.set('minha_chave', 'meu_valor')
60
+
61
+ # Armazena com tempo de expiração (em segundos)
62
+ cache.set('minha_chave', 'meu_valor', expires_in: 3600)
63
+ ```
64
+
65
+ #### Recuperando dados do cache
66
+
67
+ ```ruby
68
+ # Recupera um valor
69
+ valor = cache.get('minha_chave')
70
+
71
+ # Recupera com valor padrão se a chave não existir
72
+ valor = cache.get('minha_chave', default: 'valor_padrao')
73
+ ```
74
+
75
+ #### Removendo dados do cache
76
+
77
+ ```ruby
78
+ # Remove uma chave específica
79
+ cache.delete('minha_chave')
80
+
81
+ # Limpa todo o cache
82
+ cache.clear
83
+ ```
84
+
85
+ ### Uso Avançado
86
+
87
+ #### Cache em Lote
88
+
89
+ ```ruby
90
+ # Armazena múltiplos valores
91
+ cache.set_multi({
92
+ 'chave1' => 'valor1',
93
+ 'chave2' => 'valor2'
94
+ })
95
+
96
+ # Recupera múltiplos valores
97
+ valores = cache.get_multi(['chave1', 'chave2'])
98
+ ```
99
+
100
+ #### Cache com Blocos
101
+
102
+ ```ruby
103
+ # Executa o bloco apenas se o valor não estiver em cache
104
+ resultado = cache.fetch('minha_chave') do
105
+ # código computacionalmente intensivo aqui
106
+ resultado_computado
107
+ end
108
+ ```
109
+
110
+ ## Exemplos de Uso com Gemini AI
111
+
112
+ ```ruby
113
+ # Cacheia resultados de chamadas à API do Gemini
114
+ resposta = cache.fetch('consulta_gemini') do
115
+ gemini_client.generate_content('Qual é o sentido da vida?')
116
+ end
117
+
118
+ # Cache com namespace para diferentes modelos
119
+ cache_pro = GeminiCache::Client.new(namespace: 'gemini-pro')
120
+ cache_vision = GeminiCache::Client.new(namespace: 'gemini-vision')
121
+ ```
122
+
123
+ ## Tratamento de Erros
124
+
125
+ ```ruby
126
+ begin
127
+ cache.get('minha_chave')
128
+ rescue GeminiCache::ConnectionError => e
129
+ puts "Erro de conexão: #{e.message}"
130
+ rescue GeminiCache::TimeoutError => e
131
+ puts "Tempo limite excedido: #{e.message}"
132
+ end
133
+ ```
134
+
135
+ ## Contribuindo
136
+
137
+ 1. Faça um fork do projeto
138
+ 2. Crie sua feature branch (`git checkout -b feature/nova-feature`)
139
+ 3. Faça commit das suas alterações (`git commit -am 'Adiciona nova feature'`)
140
+ 4. Faça push para a branch (`git push origin feature/nova-feature`)
141
+ 5. Crie um novo Pull Request
142
+
143
+ ## Licença
144
+
145
+ Esta gem está disponível como código aberto sob os termos da [Licença MIT](https://opensource.org/licenses/MIT).
@@ -0,0 +1,86 @@
1
+ module GeminiCache
2
+ # Client for making HTTP requests to the Gemini API
3
+ class ApiClient
4
+ # Error class for API-related errors
5
+ class ApiError < StandardError; end
6
+
7
+ # Initializes a new API client
8
+ def initialize
9
+ @conn = Faraday.new(
10
+ url: GeminiCache.configuration.api_base_url,
11
+ headers: { 'Content-Type' => 'application/json' }
12
+ )
13
+ end
14
+
15
+ # Creates a new cache
16
+ # @param content [String] JSON string of cache content
17
+ # @return [Hash] API response
18
+ # @raise [ApiError] if the request fails
19
+ def create_cache(content)
20
+ response = @conn.post('/v1beta/cachedContents') do |req|
21
+ req.params['key'] = api_key
22
+ req.body = content
23
+ end
24
+
25
+ handle_response(response)
26
+ end
27
+
28
+ # Lists all caches
29
+ # @return [Hash] API response
30
+ # @raise [ApiError] if the request fails
31
+ def list_caches
32
+ response = @conn.get('/v1beta/cachedContents') do |req|
33
+ req.params['key'] = api_key
34
+ end
35
+
36
+ handle_response(response)
37
+ end
38
+
39
+ # Updates an existing cache
40
+ # @param name [String] cache name
41
+ # @param content [String] JSON string of new content
42
+ # @return [Hash] API response
43
+ # @raise [ApiError] if the request fails
44
+ def update_cache(name, content)
45
+ response = @conn.patch("/v1beta/#{name}") do |req|
46
+ req.params['key'] = api_key
47
+ req.body = content
48
+ end
49
+
50
+ handle_response(response)
51
+ end
52
+
53
+ # Deletes a cache
54
+ # @param name [String] cache name
55
+ # @return [Hash] API response
56
+ # @raise [ApiError] if the request fails
57
+ def delete_cache(name)
58
+ response = @conn.delete("/v1beta/#{name}") do |req|
59
+ req.params['key'] = api_key
60
+ end
61
+
62
+ handle_response(response)
63
+ end
64
+
65
+ private
66
+
67
+ # Gets the API key from configuration or environment
68
+ # @return [String] API key
69
+ def api_key
70
+ GeminiCache.configuration.api_key || ENV.fetch('GEMINI_API_KEY')
71
+ end
72
+
73
+ # Handles API responses
74
+ # @param response [Faraday::Response] HTTP response
75
+ # @return [Hash] parsed response body
76
+ # @raise [ApiError] if response status is not 200
77
+ def handle_response(response)
78
+ return JSON.parse(response.body) if response.status == 200
79
+
80
+ error_message = JSON.parse(response.body)['error'] rescue response.body
81
+ raise ApiError, "API request failed (#{response.status}): #{error_message}"
82
+ rescue Faraday::Error => e
83
+ raise ApiError, "Network error: #{e.message}"
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,35 @@
1
+ module GeminiCache
2
+ # Configuration class for GeminiCache settings
3
+ # @attr [String] api_key The API key for Gemini API
4
+ # @attr [String] api_base_url The base URL for the Gemini API
5
+ # @attr [String] default_model The default model to use
6
+ # @attr [Integer] default_ttl The default time-to-live in seconds
7
+ class Configuration
8
+ attr_accessor :api_key, :api_base_url, :default_model, :default_ttl
9
+
10
+ # Initializes a new Configuration with default values
11
+ def initialize
12
+ @api_base_url = 'https://generativelanguage.googleapis.com'
13
+ @default_model = 'gemini-1.5-flash-8b'
14
+ @default_ttl = 300
15
+ end
16
+ end
17
+
18
+ class << self
19
+ # @return [Configuration] current configuration
20
+ def configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ # Configures GeminiCache
25
+ # @yield [Configuration] configuration object
26
+ # @example
27
+ # GeminiCache.configure do |config|
28
+ # config.api_key = 'your-api-key'
29
+ # config.default_ttl = 600
30
+ # end
31
+ def configure
32
+ yield(configuration)
33
+ end
34
+ end
35
+ end
@@ -1,46 +1,89 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ItemExtender
2
- def delete = GeminiCache.delete(name: self['name'])
4
+ GEMINI_API_BASE_URL = 'https://generativelanguage.googleapis.com'
5
+ DEFAULT_TIMEOUT = 300 # seconds
6
+ ACCURATE_MODE_CONFIG = { temperature: 0, topP: 0, topK: 1 }.freeze
3
7
 
4
- def ttl=(new_ttl)
5
- GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" })
6
- GeminiCache.get_by_name(name: self['name'])
8
+ # Deletes the cached item
9
+ # @return [void]
10
+ def delete
11
+ GeminiCache.delete(name: self['name'])
7
12
  end
8
13
 
14
+ # Updates the TTL of the cached item
15
+ # @param new_ttl [Integer] new TTL value in seconds
16
+ # @return [void]
17
+ def ttl=(new_ttl)
18
+ GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" }.to_json)
19
+ end
20
+
21
+ # Generates content using the Gemini API
22
+ # @param contents [Array<Hash>] array of content parts
23
+ # @param generation_config [Hash, nil] optional generation configuration
24
+ # @return [Hash] response with added #content method
25
+ # @raise [GeminiAPIError] when the API request fails
9
26
  def generate_content(contents:, generation_config: nil)
10
- conn = Faraday.new(
11
- url: 'https://generativelanguage.googleapis.com',
27
+ response = api_client.post(generate_content_endpoint) do |req|
28
+ req.params['key'] = ENV.fetch('GEMINI_API_KEY')
29
+ req.body = build_request_body(contents, generation_config)
30
+ end
31
+
32
+ handle_response(response)
33
+ rescue Faraday::Error => e
34
+ raise GeminiAPIError, "Request failed: #{e.message}"
35
+ end
36
+
37
+ # Generates content from a single prompt
38
+ # @param prompt [String] the input prompt
39
+ # @param generation_config [Hash, Symbol] generation configuration or :accurate_mode
40
+ # @return [String] generated content
41
+ def single_prompt(prompt:, generation_config: :accurate_mode)
42
+ config = generation_config.eql?(:accurate_mode) ? ACCURATE_MODE_CONFIG : generation_config
43
+
44
+ generate_content(
45
+ contents: [{ parts: [{ text: prompt }], role: 'user' }],
46
+ generation_config: config
47
+ ).content
48
+ end
49
+
50
+ private
51
+
52
+ def api_client
53
+ @api_client ||= Faraday.new(
54
+ url: GEMINI_API_BASE_URL,
12
55
  headers: { 'Content-Type' => 'application/json' }
13
56
  ) 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
57
+ f.options.timeout = DEFAULT_TIMEOUT
58
+ f.options.open_timeout = DEFAULT_TIMEOUT
16
59
  end
60
+ end
61
+
62
+ def generate_content_endpoint
63
+ "/v1beta/models/#{self['model'].split('/').last}:generateContent"
64
+ end
17
65
 
18
- body = {
66
+ def build_request_body(contents, generation_config)
67
+ {
19
68
  cached_content: self['name'],
20
- contents:
21
- }
69
+ contents: contents,
70
+ generation_config: generation_config
71
+ }.compact.to_json
72
+ end
22
73
 
23
- body[:generation_config] = generation_config if !generation_config.nil?
74
+ def handle_response(response)
75
+ return parse_successful_response(response) if response.status == 200
24
76
 
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
77
+ raise GeminiAPIError, "Content generation failed: #{response.body}"
78
+ end
35
79
 
36
- raise "Erro ao gerar conteúdo: #{response.body}"
37
- rescue Faraday::Error => e
38
- raise "Erro na requisição: #{e.message}"
80
+ def parse_successful_response(response)
81
+ resp = JSON.parse(response.body)
82
+ def resp.content
83
+ dig('candidates', 0, 'content', 'parts', 0, 'text')
84
+ end
85
+ resp
39
86
  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
87
  end
88
+
89
+ class GeminiAPIError < StandardError; end
data/lib/gemini_cache.rb CHANGED
@@ -4,122 +4,169 @@ require 'nokogiri'
4
4
  require 'json'
5
5
  require 'base64'
6
6
 
7
+ require 'gemini_cache/configuration'
8
+ require 'gemini_cache/api_client'
7
9
  require 'gemini_cache/item_extender'
8
10
 
11
+ # Module for interacting with Google's Gemini API cached contents
12
+ # @example Basic usage
13
+ # GeminiCache.configure do |config|
14
+ # config.api_key = 'your-api-key'
15
+ # end
16
+ #
17
+ # # Create a cache from text
18
+ # cache = GeminiCache.create_from_text(
19
+ # text: "Hello, world!",
20
+ # display_name: "my-cache"
21
+ # )
9
22
  module GeminiCache
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
23
+ # Custom error class for GeminiCache-specific errors
24
+ class Error < StandardError; end
15
25
 
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:)
21
-
22
- content = {
23
- model: "models/#{model}",
24
- display_name:,
25
- contents: [parts:, role: 'user'],
26
- ttl: "#{ttl}s"
27
- }.to_json
28
-
29
- conn = Faraday.new(
30
- url: 'https://generativelanguage.googleapis.com',
31
- headers: { 'Content-Type' => 'application/json' }
32
- )
33
-
34
- response = conn.post('/v1beta/cachedContents') do |req|
35
- req.params['key'] = ENV.fetch('GEMINI_API_KEY')
36
- req.body = content
26
+ class << self
27
+ # Reads a local file and prepares it for the Gemini API
28
+ # @param path [String] path to the local file
29
+ # @param mime_type [String] MIME type of the file
30
+ # @return [Hash] formatted data for the API
31
+ def read_local_file(path:, mime_type:)
32
+ { inline_data: { mime_type:, data: Base64.strict_encode64(File.read(path)) } }
37
33
  end
38
-
39
- return get_by_name(name: JSON.parse(response.body)['name']) if response.status == 200
40
-
41
- raise "Erro ao criar cache: #{response.status} - #{response.body}"
42
- rescue Faraday::Error => e
43
- raise "Erro na requisição: #{e.message}"
44
- end
45
34
 
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:)
48
- end
35
+ # Reads a remote file and prepares it for the Gemini API
36
+ # @param url [String] URL of the remote file
37
+ # @param mime_type [String] MIME type of the file
38
+ # @return [Hash] formatted data for the API
39
+ def read_remote_file(url:, mime_type:)
40
+ { inline_data: { mime_type:, data: Base64.strict_encode64(URI.open(url).read) } }
41
+ end
49
42
 
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
43
+ # Reads and parses HTML content from a URL
44
+ # @param url [String] URL of the webpage
45
+ # @param default_remover [Boolean] whether to remove script and style tags
46
+ # @return [Nokogiri::HTML::Document] parsed HTML document
47
+ def read_html(url:, default_remover: true)
48
+ doc = Nokogiri::HTML(URI.open(url))
49
+ %w[script style].each { |element| doc.css(element).each(&:remove) } if default_remover
50
+ doc
51
+ end
53
52
 
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
53
+ # Creates a new cache in the Gemini API
54
+ # @param parts [Array<Hash>] content parts to cache
55
+ # @param display_name [String] unique display name for the cache
56
+ # @param on_conflict [:raise_error, :get_existing] action to take if cache exists
57
+ # @param model [String, nil] Gemini model to use
58
+ # @param ttl [Integer, nil] time-to-live in seconds
59
+ # @return [Hash] created cache data
60
+ # @raise [Error] if cache already exists and on_conflict is :raise_error
61
+ def create(parts:, display_name:, on_conflict: :raise_error, model: nil, ttl: nil)
62
+ existing_cache = find_by_display_name(display_name:)
63
+
64
+ if existing_cache
65
+ case on_conflict
66
+ when :raise_error
67
+ raise Error, "Cache with display name '#{display_name}' already exists"
68
+ when :get_existing
69
+ return existing_cache
70
+ end
71
+ end
72
+
73
+ content = {
74
+ model: "models/#{model || configuration.default_model}",
75
+ display_name: display_name,
76
+ contents: [{ parts:, role: 'user' }],
77
+ ttl: "#{ttl || configuration.default_ttl}s"
78
+ }
79
+
80
+ response = api_client.create_cache(content.to_json)
81
+ find_by_name(name: response['name'])
82
+ end
57
83
 
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
84
+ # Creates a cache from plain text
85
+ # @param text [String] text content to cache
86
+ # @param options [Hash] additional options passed to #create
87
+ # @return [Hash] created cache data
88
+ def create_from_text(text:, **options)
89
+ create(parts: [{ text: }], **options)
90
+ end
61
91
 
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 }
92
+ # Creates a cache from a webpage's content
93
+ # @param url [String] URL of the webpage
94
+ # @param options [Hash] additional options passed to #create
95
+ # @return [Hash] created cache data
96
+ def create_from_webpage(url:, **options)
97
+ create_from_text(text: read_html(url:).inner_text, **options)
98
+ end
64
99
 
65
- def self.list
66
- conn = Faraday.new(
67
- url: 'https://generativelanguage.googleapis.com',
68
- headers: { 'Content-Type' => 'application/json' }
69
- )
100
+ # Creates a cache from a local file
101
+ # @param path [String] path to the local file
102
+ # @param mime_type [String] MIME type of the file
103
+ # @param options [Hash] additional options passed to #create
104
+ # @return [Hash] created cache data
105
+ def create_from_local_file(path:, mime_type:, **options)
106
+ file_data = read_local_file(path: path, mime_type: mime_type)
107
+ create(parts: [file_data], **options)
108
+ end
70
109
 
71
- response = conn.get("/v1beta/cachedContents") do |req|
72
- req.params['key'] = ENV.fetch('GEMINI_API_KEY')
110
+ # Creates a cache from a remote file
111
+ # @param url [String] URL of the remote file
112
+ # @param mime_type [String] MIME type of the file
113
+ # @param options [Hash] additional options passed to #create
114
+ # @return [Hash] created cache data
115
+ def create_from_remote_file(url:, mime_type:, **options)
116
+ file_data = read_remote_file(url: url, mime_type: mime_type)
117
+ create(parts: [file_data], **options)
73
118
  end
74
-
75
- return [] if JSON.parse(response.body).empty?
76
119
 
77
- JSON.parse(response.body)['cachedContents'].map { |item| item.extend(ItemExtender) }
120
+ # Lists all available caches
121
+ # @return [Array<Hash>] list of caches with ItemExtender mixed in
122
+ def list
123
+ response = api_client.list_caches
124
+ return [] if response.empty?
78
125
 
79
- rescue Faraday::Error => e
80
- raise "Erro na requisição: #{e.message}"
81
- end
82
-
83
- def self.update(name:, content:)
84
- conn = Faraday.new(
85
- url: 'https://generativelanguage.googleapis.com',
86
- headers: { 'Content-Type' => 'application/json' }
87
- )
88
-
89
- response = conn.patch("/v1beta/#{name}") do |req|
90
- req.params['key'] = ENV.fetch('GEMINI_API_KEY')
91
- req.body = content.to_json
126
+ response['cachedContents'].map { |item| item.extend(ItemExtender) }
92
127
  end
93
128
 
94
- return JSON.parse(response.body) if response.status == 200
95
-
96
- raise "Erro ao atualizar cache: #{response.body}"
97
- rescue Faraday::Error => e
98
- raise "Erro na requisição: #{e.message}"
99
- end
100
-
101
- def self.delete(name:)
102
- conn = Faraday.new(
103
- url: 'https://generativelanguage.googleapis.com',
104
- headers: { 'Content-Type' => 'application/json' }
105
- )
129
+ # Finds a cache by its internal name
130
+ # @param name [String] internal name of the cache
131
+ # @return [Hash, nil] cache data if found, nil otherwise
132
+ def find_by_name(name:)
133
+ list.find { |item| item['name'].eql?(name) }
134
+ end
106
135
 
107
- response = conn.delete("/v1beta/#{name}") do |req|
108
- req.params['key'] = ENV.fetch('GEMINI_API_KEY')
136
+ # Finds a cache by its display name
137
+ # @param display_name [String] display name of the cache
138
+ # @return [Hash, nil] cache data if found, nil otherwise
139
+ def find_by_display_name(display_name:)
140
+ list.find { |item| item['displayName'].eql?(display_name) }
109
141
  end
110
142
 
111
- return true if response.status == 200
112
-
113
- raise "Erro ao deletar cache: #{response.body}"
114
- rescue Faraday::Error => e
115
- raise "Erro na requisição: #{e.message}"
116
- end
143
+ # Updates an existing cache
144
+ # @param name [String] internal name of the cache
145
+ # @param content [Hash] new content for the cache
146
+ # @return [Hash] updated cache data
147
+ def update(name:, content:)
148
+ api_client.update_cache(name, content)
149
+ end
117
150
 
118
- def self.delete_all
119
- GeminiCache.list.each { |item| item.delete }
120
- end
151
+ # Deletes a specific cache
152
+ # @param name [String] internal name of the cache to delete
153
+ # @return [Boolean] true if successful
154
+ def delete(name:)
155
+ api_client.delete_cache(name)
156
+ true
157
+ end
121
158
 
122
- class << self
159
+ # Deletes all caches
160
+ # @return [void]
161
+ def delete_all
162
+ list.each { |item| item.delete }
163
+ end
123
164
  alias clear delete_all
165
+
166
+ private
167
+
168
+ def api_client
169
+ @api_client ||= ApiClient.new
170
+ end
124
171
  end
125
172
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemini_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gedean Dias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-23 00:00:00.000000000 Z
11
+ date: 2024-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -58,7 +58,10 @@ executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
+ - README.md
61
62
  - lib/gemini_cache.rb
63
+ - lib/gemini_cache/api_client.rb
64
+ - lib/gemini_cache/configuration.rb
62
65
  - lib/gemini_cache/item_extender.rb
63
66
  homepage: https://github.com/gedean/gemini_cache
64
67
  licenses: