gemini_cache 0.0.11 → 0.0.13
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/README.md +128 -106
- data/lib/gemini_cache/api_client.rb +7 -27
- data/lib/gemini_cache/configuration.rb +9 -24
- data/lib/gemini_cache/item_extender.rb +14 -29
- data/lib/gemini_cache.rb +67 -135
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebf54e6bff38c64454e4914eb2523b8e7f31afdc8679047a7f6d98cde885fea1
|
4
|
+
data.tar.gz: 2018cfa7beac9143381785b9bbabec1eb4df0f4d9faafd0dfc4b7c7900376511
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79d93c0baad884c33cfef53b53e6e486c0942ce8e68cddd045dfdfcbbfe6ff9e7bec404e37a56778d756af0a86a1c4cb450eaffd04d9892bcdf449a4f0b9c7b2
|
7
|
+
data.tar.gz: b330e9737286d3997eda16126b6bc2c20e906b4825686e1e7f3d1e4530c621db534bc52d25b3899e6ac8ba96c341d6db2a7f7f964bb9b1060e118218a5f08967
|
data/README.md
CHANGED
@@ -1,145 +1,167 @@
|
|
1
|
-
# GeminiCache
|
1
|
+
# GeminiCache Module Usage Documentation
|
2
2
|
|
3
|
-
|
3
|
+
## Introduction
|
4
|
+
The `GeminiCache` module is a library designed for managing API caches, with features to process web pages, local and remote files, as well as interact with an API to create, update, list, and delete caches. This document describes its functionalities and usage.
|
4
5
|
|
5
|
-
##
|
6
|
+
## Requirements
|
7
|
+
To use the module, ensure the following Ruby libraries are installed:
|
6
8
|
|
7
|
-
|
9
|
+
- `faraday`
|
10
|
+
- `open-uri`
|
11
|
+
- `nokogiri`
|
12
|
+
- `json`
|
13
|
+
- `base64`
|
8
14
|
|
9
|
-
|
10
|
-
gem 'gemini_cache'
|
11
|
-
```
|
15
|
+
## Code Structure
|
12
16
|
|
13
|
-
|
17
|
+
The module includes the following components:
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
1. **Classes and Modules**:
|
20
|
+
- `GeminiCache::Error`: Class for handling custom errors.
|
21
|
+
- `GeminiCache`: Contains the main methods for cache management and file processing.
|
18
22
|
|
19
|
-
|
23
|
+
2. **Dependencies**:
|
24
|
+
- `gemini_cache/configuration`
|
25
|
+
- `gemini_cache/api_client`
|
26
|
+
- `gemini_cache/item_extender`
|
20
27
|
|
21
|
-
|
22
|
-
$ gem install gemini_cache
|
23
|
-
```
|
28
|
+
## Features
|
24
29
|
|
25
|
-
|
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
|
30
|
+
### 1. HTML Parsing
|
31
|
+
Allows processing and cleaning the content of a web page.
|
36
32
|
|
33
|
+
#### Syntax
|
37
34
|
```ruby
|
38
|
-
GeminiCache.
|
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
|
35
|
+
GeminiCache.parse_html(url:, default_remover: true)
|
43
36
|
```
|
37
|
+
- **Parameters**:
|
38
|
+
- `url`: The URL of the page to process.
|
39
|
+
- `default_remover`: Automatically removes `<script>` and `<style>` elements (default: `true`).
|
40
|
+
- **Returns**: A `Nokogiri::HTML` object containing the processed HTML.
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
### Inicializando o Cliente
|
42
|
+
### 2. File Reading
|
48
43
|
|
44
|
+
#### a) Local Files
|
45
|
+
Reads a local file and returns its Base64 encoded data.
|
49
46
|
```ruby
|
50
|
-
|
47
|
+
GeminiCache.read_local_file(path:, mime_type:)
|
51
48
|
```
|
49
|
+
- **Parameters**:
|
50
|
+
- `path`: Path to the file.
|
51
|
+
- `mime_type`: MIME type of the file.
|
52
|
+
- **Returns**: Hash containing the encoded data.
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
#### Armazenando dados no cache
|
56
|
-
|
54
|
+
#### b) Remote Files
|
55
|
+
Reads a remote file and returns its Base64 encoded data.
|
57
56
|
```ruby
|
58
|
-
|
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)
|
57
|
+
GeminiCache.read_remote_file(url:, mime_type:)
|
63
58
|
```
|
59
|
+
- **Parameters**:
|
60
|
+
- `url`: URL of the file.
|
61
|
+
- `mime_type`: MIME type of the file.
|
62
|
+
- **Returns**: Hash containing the encoded data.
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
### 3. Webpage Text Reading
|
65
|
+
Extracts text content from a web page, removing unnecessary elements.
|
67
66
|
```ruby
|
68
|
-
|
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')
|
67
|
+
GeminiCache.read_webpage_text(url:, default_remover: true)
|
73
68
|
```
|
69
|
+
- **Parameters**:
|
70
|
+
- `url`: URL of the page.
|
71
|
+
- `default_remover`: Automatically removes `<script>` and `<style>` elements (default: `true`).
|
72
|
+
- **Returns**: Hash containing the page text.
|
74
73
|
|
75
|
-
|
74
|
+
### 4. Cache Creation
|
75
|
+
Creates a new cache from different data sources.
|
76
76
|
|
77
|
+
#### General Syntax
|
77
78
|
```ruby
|
78
|
-
|
79
|
-
cache.delete('minha_chave')
|
80
|
-
|
81
|
-
# Limpa todo o cache
|
82
|
-
cache.clear
|
79
|
+
GeminiCache.create(parts:, display_name:, on_conflict: :raise_error, model: nil, ttl: nil)
|
83
80
|
```
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
81
|
+
- **Parameters**:
|
82
|
+
- `parts`: Cache data.
|
83
|
+
- `display_name`: Display name of the cache.
|
84
|
+
- `on_conflict`: Action on conflict (`:raise_error` or `:get_existing`).
|
85
|
+
- `model`: Model used (default: system configuration).
|
86
|
+
- `ttl`: Time-to-live for the cache (default: system configuration).
|
87
|
+
- **Returns**: The created cache object.
|
88
|
+
|
89
|
+
#### Creation Methods
|
90
|
+
- Text:
|
91
|
+
```ruby
|
92
|
+
GeminiCache.create_from_text(text:, **options)
|
93
|
+
```
|
94
|
+
- Web Page:
|
95
|
+
```ruby
|
96
|
+
GeminiCache.create_from_webpage(url:, **options)
|
97
|
+
```
|
98
|
+
- Local File:
|
99
|
+
```ruby
|
100
|
+
GeminiCache.create_from_local_file(path:, mime_type:, **options)
|
101
|
+
```
|
102
|
+
- Remote File:
|
103
|
+
```ruby
|
104
|
+
GeminiCache.create_from_remote_file(url:, mime_type:, **options)
|
105
|
+
```
|
106
|
+
|
107
|
+
### 5. Cache Management
|
108
|
+
|
109
|
+
#### Cache Listing
|
110
|
+
Lists all available caches.
|
89
111
|
```ruby
|
90
|
-
|
91
|
-
cache.set_multi({
|
92
|
-
'chave1' => 'valor1',
|
93
|
-
'chave2' => 'valor2'
|
94
|
-
})
|
95
|
-
|
96
|
-
# Recupera múltiplos valores
|
97
|
-
valores = cache.get_multi(['chave1', 'chave2'])
|
112
|
+
GeminiCache.list
|
98
113
|
```
|
99
|
-
|
100
|
-
|
101
|
-
|
114
|
+
- **Returns**: Array of cache objects.
|
115
|
+
|
116
|
+
#### Cache Retrieval
|
117
|
+
- By Name:
|
118
|
+
```ruby
|
119
|
+
GeminiCache.find_by_name(name:)
|
120
|
+
```
|
121
|
+
- By Display Name:
|
122
|
+
```ruby
|
123
|
+
GeminiCache.find_by_display_name(display_name:)
|
124
|
+
```
|
125
|
+
|
126
|
+
#### Cache Updating
|
127
|
+
Updates an existing cache.
|
102
128
|
```ruby
|
103
|
-
|
104
|
-
resultado = cache.fetch('minha_chave') do
|
105
|
-
# código computacionalmente intensivo aqui
|
106
|
-
resultado_computado
|
107
|
-
end
|
129
|
+
GeminiCache.update(name:, content:)
|
108
130
|
```
|
131
|
+
- **Parameters**:
|
132
|
+
- `name`: Name of the cache.
|
133
|
+
- `content`: Updated content.
|
109
134
|
|
110
|
-
|
135
|
+
#### Cache Deletion
|
136
|
+
- By Name:
|
137
|
+
```ruby
|
138
|
+
GeminiCache.delete(name:)
|
139
|
+
```
|
140
|
+
- All Caches:
|
141
|
+
```ruby
|
142
|
+
GeminiCache.delete_all
|
143
|
+
```
|
111
144
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
```
|
145
|
+
## Configuration
|
146
|
+
The methods use configurations defined in the `gemini_cache/configuration` module, and communication is handled via `gemini_cache/api_client`.
|
147
|
+
|
148
|
+
## Errors
|
149
|
+
In case of conflicts or API errors, the module raises a custom exception `GeminiCache::Error`.
|
122
150
|
|
123
|
-
##
|
151
|
+
## Examples
|
124
152
|
|
125
153
|
```ruby
|
126
|
-
|
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
|
-
```
|
154
|
+
require 'gemini_cache'
|
134
155
|
|
135
|
-
|
156
|
+
parts = [
|
157
|
+
{ text: 'Some text' },
|
158
|
+
GeminiCache.read_remote_file(url: '<remote_file_url>', mime_type: 'application/pdf'),
|
159
|
+
GeminiCache.read_webpage_text(url: '<webpage url>')
|
160
|
+
]
|
136
161
|
|
137
|
-
|
138
|
-
|
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
|
162
|
+
cache = GeminiCache.create parts: parts, display_name: 'mycache'
|
163
|
+
```
|
142
164
|
|
143
|
-
##
|
165
|
+
## Conclusion
|
166
|
+
This documentation covers the main functionalities of the `GeminiCache` module. For more details on specific configurations, refer to the source code or official documentation.
|
144
167
|
|
145
|
-
Esta gem está disponível como código aberto sob os termos da [Licença MIT](https://opensource.org/licenses/MIT).
|
@@ -1,10 +1,7 @@
|
|
1
1
|
module GeminiCache
|
2
|
-
# Client for making HTTP requests to the Gemini API
|
3
2
|
class ApiClient
|
4
|
-
# Error class for API-related errors
|
5
3
|
class ApiError < StandardError; end
|
6
4
|
|
7
|
-
# Initializes a new API client
|
8
5
|
def initialize
|
9
6
|
@conn = Faraday.new(
|
10
7
|
url: GeminiCache.configuration.api_base_url,
|
@@ -12,10 +9,6 @@ module GeminiCache
|
|
12
9
|
)
|
13
10
|
end
|
14
11
|
|
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
12
|
def create_cache(content)
|
20
13
|
response = @conn.post('/v1beta/cachedContents') do |req|
|
21
14
|
req.params['key'] = api_key
|
@@ -25,9 +18,6 @@ module GeminiCache
|
|
25
18
|
handle_response(response)
|
26
19
|
end
|
27
20
|
|
28
|
-
# Lists all caches
|
29
|
-
# @return [Hash] API response
|
30
|
-
# @raise [ApiError] if the request fails
|
31
21
|
def list_caches
|
32
22
|
response = @conn.get('/v1beta/cachedContents') do |req|
|
33
23
|
req.params['key'] = api_key
|
@@ -36,11 +26,6 @@ module GeminiCache
|
|
36
26
|
handle_response(response)
|
37
27
|
end
|
38
28
|
|
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
29
|
def update_cache(name, content)
|
45
30
|
response = @conn.patch("/v1beta/#{name}") do |req|
|
46
31
|
req.params['key'] = api_key
|
@@ -50,10 +35,6 @@ module GeminiCache
|
|
50
35
|
handle_response(response)
|
51
36
|
end
|
52
37
|
|
53
|
-
# Deletes a cache
|
54
|
-
# @param name [String] cache name
|
55
|
-
# @return [Hash] API response
|
56
|
-
# @raise [ApiError] if the request fails
|
57
38
|
def delete_cache(name)
|
58
39
|
response = @conn.delete("/v1beta/#{name}") do |req|
|
59
40
|
req.params['key'] = api_key
|
@@ -64,23 +45,22 @@ module GeminiCache
|
|
64
45
|
|
65
46
|
private
|
66
47
|
|
67
|
-
# Gets the API key from configuration or environment
|
68
|
-
# @return [String] API key
|
69
48
|
def api_key
|
70
49
|
GeminiCache.configuration.api_key || ENV.fetch('GEMINI_API_KEY')
|
71
50
|
end
|
72
51
|
|
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
52
|
def handle_response(response)
|
78
53
|
return JSON.parse(response.body) if response.status == 200
|
79
54
|
|
80
|
-
error_message =
|
55
|
+
error_message = begin
|
56
|
+
JSON.parse(response.body)['error']
|
57
|
+
rescue
|
58
|
+
response.body
|
59
|
+
end
|
60
|
+
|
81
61
|
raise ApiError, "API request failed (#{response.status}): #{error_message}"
|
82
62
|
rescue Faraday::Error => e
|
83
63
|
raise ApiError, "Network error: #{e.message}"
|
84
64
|
end
|
85
65
|
end
|
86
|
-
end
|
66
|
+
end
|
@@ -1,35 +1,20 @@
|
|
1
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
2
|
class Configuration
|
8
|
-
attr_accessor :api_key, :api_base_url, :default_model, :default_ttl
|
3
|
+
attr_accessor :api_key, :api_base_url, :default_model, :default_ttl, :default_timeout
|
9
4
|
|
10
|
-
# Initializes a new Configuration with default values
|
11
5
|
def initialize
|
12
6
|
@api_base_url = 'https://generativelanguage.googleapis.com'
|
13
|
-
@default_model = 'gemini-
|
7
|
+
@default_model = 'gemini-flash-lite-latest'
|
14
8
|
@default_ttl = 300
|
9
|
+
@default_timeout = 300
|
15
10
|
end
|
16
11
|
end
|
17
12
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@configuration ||= Configuration.new
|
22
|
-
end
|
13
|
+
def self.configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
23
16
|
|
24
|
-
|
25
|
-
|
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
|
17
|
+
def self.configure
|
18
|
+
yield configuration
|
34
19
|
end
|
35
|
-
end
|
20
|
+
end
|
@@ -1,28 +1,14 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module ItemExtender
|
4
|
-
GEMINI_API_BASE_URL = 'https://generativelanguage.googleapis.com'
|
5
|
-
DEFAULT_TIMEOUT = 300 # seconds
|
6
2
|
ACCURATE_MODE_CONFIG = { temperature: 0, topP: 0, topK: 1 }.freeze
|
7
3
|
|
8
|
-
# Deletes the cached item
|
9
|
-
# @return [void]
|
10
4
|
def delete
|
11
5
|
GeminiCache.delete(name: self['name'])
|
12
6
|
end
|
13
7
|
|
14
|
-
# Updates the TTL of the cached item
|
15
|
-
# @param new_ttl [Integer] new TTL value in seconds
|
16
|
-
# @return [void]
|
17
8
|
def ttl=(new_ttl)
|
18
9
|
GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" }.to_json)
|
19
10
|
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
|
11
|
+
|
26
12
|
def generate_content(contents:, generation_config: nil)
|
27
13
|
response = api_client.post(generate_content_endpoint) do |req|
|
28
14
|
req.params['key'] = ENV.fetch('GEMINI_API_KEY')
|
@@ -33,13 +19,9 @@ module ItemExtender
|
|
33
19
|
rescue Faraday::Error => e
|
34
20
|
raise GeminiAPIError, "Request failed: #{e.message}"
|
35
21
|
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
|
22
|
+
|
41
23
|
def single_prompt(prompt:, generation_config: :accurate_mode)
|
42
|
-
config = generation_config
|
24
|
+
config = generation_config == :accurate_mode ? ACCURATE_MODE_CONFIG : generation_config
|
43
25
|
|
44
26
|
generate_content(
|
45
27
|
contents: [{ parts: [{ text: prompt }], role: 'user' }],
|
@@ -50,12 +32,15 @@ module ItemExtender
|
|
50
32
|
private
|
51
33
|
|
52
34
|
def api_client
|
53
|
-
@api_client ||=
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
35
|
+
@api_client ||= begin
|
36
|
+
timeout = GeminiCache.configuration.default_timeout
|
37
|
+
Faraday.new(
|
38
|
+
url: GeminiCache.configuration.api_base_url,
|
39
|
+
headers: { 'Content-Type' => 'application/json' }
|
40
|
+
) do |f|
|
41
|
+
f.options.timeout = timeout
|
42
|
+
f.options.open_timeout = timeout
|
43
|
+
end
|
59
44
|
end
|
60
45
|
end
|
61
46
|
|
@@ -66,8 +51,8 @@ module ItemExtender
|
|
66
51
|
def build_request_body(contents, generation_config)
|
67
52
|
{
|
68
53
|
cached_content: self['name'],
|
69
|
-
contents
|
70
|
-
generation_config:
|
54
|
+
contents:,
|
55
|
+
generation_config:
|
71
56
|
}.compact.to_json
|
72
57
|
end
|
73
58
|
|
data/lib/gemini_cache.rb
CHANGED
@@ -8,159 +8,91 @@ require 'gemini_cache/configuration'
|
|
8
8
|
require 'gemini_cache/api_client'
|
9
9
|
require 'gemini_cache/item_extender'
|
10
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
|
-
# )
|
22
11
|
module GeminiCache
|
23
|
-
# Custom error class for GeminiCache-specific errors
|
24
12
|
class Error < StandardError; end
|
25
13
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def read_local_file(path:, mime_type:)
|
32
|
-
{ inline_data: { mime_type:, data: Base64.strict_encode64(File.read(path)) } }
|
33
|
-
end
|
14
|
+
def self.parse_html(url:, default_remover: true)
|
15
|
+
doc = Nokogiri::HTML(URI.open(url, 'User-Agent' => 'Mozilla/5.0'))
|
16
|
+
%w[script style].each { doc.css(it).remove } if default_remover
|
17
|
+
doc
|
18
|
+
end
|
34
19
|
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
20
|
+
def self.read_local_file(path:, mime_type:)
|
21
|
+
{ inline_data: { mime_type:, data: Base64.strict_encode64(File.read(path)) } }
|
22
|
+
end
|
42
23
|
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
24
|
+
def self.read_remote_file(url:, mime_type:)
|
25
|
+
{ inline_data: { mime_type:, data: Base64.strict_encode64(URI.open(url).read) } }
|
26
|
+
end
|
52
27
|
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
28
|
+
def self.read_webpage_text(url:, default_remover: true)
|
29
|
+
{ text: parse_html(url:, default_remover:).inner_text }
|
30
|
+
end
|
83
31
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
32
|
+
def self.create(parts:, display_name:, on_conflict: :raise_error, model: nil, ttl: nil)
|
33
|
+
existing_cache = find_by_display_name(display_name:)
|
34
|
+
|
35
|
+
if existing_cache
|
36
|
+
return existing_cache if on_conflict == :get_existing
|
37
|
+
raise Error, "Cache with display name '#{display_name}' already exists" if on_conflict == :raise_error
|
90
38
|
end
|
91
39
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
40
|
+
content = {
|
41
|
+
model: "models/#{model || configuration.default_model}",
|
42
|
+
display_name:,
|
43
|
+
contents: [{ parts:, role: 'user' }],
|
44
|
+
ttl: "#{ttl || configuration.default_ttl}s"
|
45
|
+
}
|
99
46
|
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
47
|
+
response = api_client.create_cache(content.to_json)
|
48
|
+
find_by_name(name: response['name'])
|
49
|
+
end
|
109
50
|
|
110
|
-
|
111
|
-
|
112
|
-
|
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)
|
118
|
-
end
|
51
|
+
def self.create_from_text(text:, **options)
|
52
|
+
create(parts: [{ text: }], **options)
|
53
|
+
end
|
119
54
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
response = api_client.list_caches
|
124
|
-
return [] if response.empty?
|
55
|
+
def self.create_from_webpage(url:, **options)
|
56
|
+
create_from_text(text: read_webpage_text(url:)[:text], **options)
|
57
|
+
end
|
125
58
|
|
126
|
-
|
127
|
-
|
59
|
+
def self.create_from_local_file(path:, mime_type:, **options)
|
60
|
+
create(parts: [read_local_file(path:, mime_type:)], **options)
|
61
|
+
end
|
128
62
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
def find_by_name(name:)
|
133
|
-
list.find { |item| item['name'].eql?(name) }
|
134
|
-
end
|
63
|
+
def self.create_from_remote_file(url:, mime_type:, **options)
|
64
|
+
create(parts: [read_remote_file(url:, mime_type:)], **options)
|
65
|
+
end
|
135
66
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
def find_by_display_name(display_name:)
|
140
|
-
list.find { |item| item['displayName'].eql?(display_name) }
|
141
|
-
end
|
67
|
+
def self.list
|
68
|
+
response = api_client.list_caches
|
69
|
+
return [] if response.empty?
|
142
70
|
|
143
|
-
|
144
|
-
|
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
|
71
|
+
response['cachedContents'].map { it.extend(ItemExtender) }
|
72
|
+
end
|
150
73
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
def delete(name:)
|
155
|
-
api_client.delete_cache(name)
|
156
|
-
true
|
157
|
-
end
|
74
|
+
def self.find_by_name(name:)
|
75
|
+
list.find { it['name'] == name }
|
76
|
+
end
|
158
77
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
78
|
+
def self.find_by_display_name(display_name:)
|
79
|
+
list.find { it['displayName'] == display_name }
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.update(name:, content:)
|
83
|
+
api_client.update_cache(name, content)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.delete(name:)
|
87
|
+
api_client.delete_cache(name)
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.delete_all
|
92
|
+
list.each(&:delete)
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
164
96
|
alias clear delete_all
|
165
97
|
|
166
98
|
private
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemini_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gedean Dias
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-09-29 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: faraday
|
@@ -67,7 +66,6 @@ homepage: https://github.com/gedean/gemini_cache
|
|
67
66
|
licenses:
|
68
67
|
- MIT
|
69
68
|
metadata: {}
|
70
|
-
post_install_message:
|
71
69
|
rdoc_options: []
|
72
70
|
require_paths:
|
73
71
|
- lib
|
@@ -82,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
80
|
- !ruby/object:Gem::Version
|
83
81
|
version: '0'
|
84
82
|
requirements: []
|
85
|
-
rubygems_version: 3.
|
86
|
-
signing_key:
|
83
|
+
rubygems_version: 3.7.2
|
87
84
|
specification_version: 4
|
88
85
|
summary: Ruby Gemini Context Caching
|
89
86
|
test_files: []
|