gemini_cache 0.0.9 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +153 -0
- data/lib/gemini_cache/api_client.rb +61 -0
- data/lib/gemini_cache/configuration.rb +21 -0
- data/lib/gemini_cache/item_extender.rb +57 -30
- data/lib/gemini_cache.rb +63 -96
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7e9a54d31ede523084b82ed3d94912bcbbd33ac2f0452bbc0a87d22ddc3d749
|
4
|
+
data.tar.gz: 7ca621fad09fc18f1a87938d2a42b289841ed7c9a6eaadd290869af4cd132613
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7281d91213fa3b6243e6013e352653b89e15c0be1545ad62c11c97f3259f7afcdb673ffd82d9130c3fd61087ef555844ebe35f684c5ebb0ccd1e9fa0a9a65f7f
|
7
|
+
data.tar.gz: 9648a180a9c48e3ddddc52d3006603b9a8b8f418712474311c578660d8c329ceb4ca5ee23f89ab6262eb4058818e2289910dc58979702662852d50aa3ed2a85f
|
data/README.md
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
# GeminiCache Module Usage Documentation
|
2
|
+
|
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.
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
To use the module, ensure the following Ruby libraries are installed:
|
8
|
+
|
9
|
+
- `faraday`
|
10
|
+
- `open-uri`
|
11
|
+
- `nokogiri`
|
12
|
+
- `json`
|
13
|
+
- `base64`
|
14
|
+
|
15
|
+
## Code Structure
|
16
|
+
|
17
|
+
The module includes the following components:
|
18
|
+
|
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.
|
22
|
+
|
23
|
+
2. **Dependencies**:
|
24
|
+
- `gemini_cache/configuration`
|
25
|
+
- `gemini_cache/api_client`
|
26
|
+
- `gemini_cache/item_extender`
|
27
|
+
|
28
|
+
## Features
|
29
|
+
|
30
|
+
### 1. HTML Parsing
|
31
|
+
Allows processing and cleaning the content of a web page.
|
32
|
+
|
33
|
+
#### Syntax
|
34
|
+
```ruby
|
35
|
+
GeminiCache.parse_html(url:, default_remover: true)
|
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.
|
41
|
+
|
42
|
+
### 2. File Reading
|
43
|
+
|
44
|
+
#### a) Local Files
|
45
|
+
Reads a local file and returns its Base64 encoded data.
|
46
|
+
```ruby
|
47
|
+
GeminiCache.read_local_file(path:, mime_type:)
|
48
|
+
```
|
49
|
+
- **Parameters**:
|
50
|
+
- `path`: Path to the file.
|
51
|
+
- `mime_type`: MIME type of the file.
|
52
|
+
- **Returns**: Hash containing the encoded data.
|
53
|
+
|
54
|
+
#### b) Remote Files
|
55
|
+
Reads a remote file and returns its Base64 encoded data.
|
56
|
+
```ruby
|
57
|
+
GeminiCache.read_remote_file(url:, mime_type:)
|
58
|
+
```
|
59
|
+
- **Parameters**:
|
60
|
+
- `url`: URL of the file.
|
61
|
+
- `mime_type`: MIME type of the file.
|
62
|
+
- **Returns**: Hash containing the encoded data.
|
63
|
+
|
64
|
+
### 3. Webpage Text Reading
|
65
|
+
Extracts text content from a web page, removing unnecessary elements.
|
66
|
+
```ruby
|
67
|
+
GeminiCache.read_webpage_text(url:, default_remover: true)
|
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.
|
73
|
+
|
74
|
+
### 4. Cache Creation
|
75
|
+
Creates a new cache from different data sources.
|
76
|
+
|
77
|
+
#### General Syntax
|
78
|
+
```ruby
|
79
|
+
GeminiCache.create(parts:, display_name:, on_conflict: :raise_error, model: nil, ttl: nil)
|
80
|
+
```
|
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.
|
111
|
+
```ruby
|
112
|
+
GeminiCache.list
|
113
|
+
```
|
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.
|
128
|
+
```ruby
|
129
|
+
GeminiCache.update(name:, content:)
|
130
|
+
```
|
131
|
+
- **Parameters**:
|
132
|
+
- `name`: Name of the cache.
|
133
|
+
- `content`: Updated content.
|
134
|
+
|
135
|
+
#### Cache Deletion
|
136
|
+
- By Name:
|
137
|
+
```ruby
|
138
|
+
GeminiCache.delete(name:)
|
139
|
+
```
|
140
|
+
- All Caches:
|
141
|
+
```ruby
|
142
|
+
GeminiCache.delete_all
|
143
|
+
```
|
144
|
+
|
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`.
|
150
|
+
|
151
|
+
## Conclusion
|
152
|
+
This documentation covers the main functionalities of the `GeminiCache` module. For more details on specific configurations, refer to the source code or official documentation.
|
153
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module GeminiCache
|
2
|
+
class ApiClient
|
3
|
+
class ApiError < StandardError; end
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@conn = Faraday.new(
|
7
|
+
url: GeminiCache.configuration.api_base_url,
|
8
|
+
headers: { 'Content-Type' => 'application/json' }
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_cache(content)
|
13
|
+
response = @conn.post('/v1beta/cachedContents') do |req|
|
14
|
+
req.params['key'] = api_key
|
15
|
+
req.body = content
|
16
|
+
end
|
17
|
+
|
18
|
+
handle_response(response)
|
19
|
+
end
|
20
|
+
|
21
|
+
def list_caches
|
22
|
+
response = @conn.get('/v1beta/cachedContents') do |req|
|
23
|
+
req.params['key'] = api_key
|
24
|
+
end
|
25
|
+
|
26
|
+
handle_response(response)
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_cache(name, content)
|
30
|
+
response = @conn.patch("/v1beta/#{name}") do |req|
|
31
|
+
req.params['key'] = api_key
|
32
|
+
req.body = content
|
33
|
+
end
|
34
|
+
|
35
|
+
handle_response(response)
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_cache(name)
|
39
|
+
response = @conn.delete("/v1beta/#{name}") do |req|
|
40
|
+
req.params['key'] = api_key
|
41
|
+
end
|
42
|
+
|
43
|
+
handle_response(response)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def api_key
|
49
|
+
GeminiCache.configuration.api_key || ENV.fetch('GEMINI_API_KEY')
|
50
|
+
end
|
51
|
+
|
52
|
+
def handle_response(response)
|
53
|
+
return JSON.parse(response.body) if response.status == 200
|
54
|
+
|
55
|
+
error_message = JSON.parse(response.body)['error'] rescue response.body
|
56
|
+
raise ApiError, "API request failed (#{response.status}): #{error_message}"
|
57
|
+
rescue Faraday::Error => e
|
58
|
+
raise ApiError, "Network error: #{e.message}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GeminiCache
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :api_key, :api_base_url, :default_model, :default_ttl
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@api_base_url = 'https://generativelanguage.googleapis.com'
|
7
|
+
@default_model = 'gemini-1.5-flash-8b'
|
8
|
+
@default_ttl = 300
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure
|
18
|
+
yield(configuration)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,46 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ItemExtender
|
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
|
7
|
+
|
2
8
|
def delete = GeminiCache.delete(name: self['name'])
|
3
9
|
|
4
10
|
def ttl=(new_ttl)
|
5
|
-
GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" })
|
6
|
-
GeminiCache.get_by_name(name: self['name'])
|
11
|
+
GeminiCache.update(name: self['name'], content: { ttl: "#{new_ttl}s" }.to_json)
|
7
12
|
end
|
8
|
-
|
13
|
+
|
9
14
|
def generate_content(contents:, generation_config: nil)
|
10
|
-
|
11
|
-
|
15
|
+
response = api_client.post(generate_content_endpoint) do |req|
|
16
|
+
req.params['key'] = ENV.fetch('GEMINI_API_KEY')
|
17
|
+
req.body = build_request_body(contents, generation_config)
|
18
|
+
end
|
19
|
+
|
20
|
+
handle_response(response)
|
21
|
+
rescue Faraday::Error => e
|
22
|
+
raise GeminiAPIError, "Request failed: #{e.message}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def single_prompt(prompt:, generation_config: :accurate_mode)
|
26
|
+
config = generation_config.eql?(:accurate_mode) ? ACCURATE_MODE_CONFIG : generation_config
|
27
|
+
|
28
|
+
generate_content(
|
29
|
+
contents: [{ parts: [{ text: prompt }], role: 'user' }],
|
30
|
+
generation_config: config
|
31
|
+
).content
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def api_client
|
37
|
+
@api_client ||= Faraday.new(
|
38
|
+
url: GEMINI_API_BASE_URL,
|
12
39
|
headers: { 'Content-Type' => 'application/json' }
|
13
40
|
) do |f|
|
14
|
-
f.options.timeout =
|
15
|
-
f.options.open_timeout =
|
41
|
+
f.options.timeout = DEFAULT_TIMEOUT
|
42
|
+
f.options.open_timeout = DEFAULT_TIMEOUT
|
16
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_content_endpoint
|
47
|
+
"/v1beta/models/#{self['model'].split('/').last}:generateContent"
|
48
|
+
end
|
17
49
|
|
18
|
-
|
50
|
+
def build_request_body(contents, generation_config)
|
51
|
+
{
|
19
52
|
cached_content: self['name'],
|
20
|
-
contents:
|
21
|
-
|
53
|
+
contents: contents,
|
54
|
+
generation_config: generation_config
|
55
|
+
}.compact.to_json
|
56
|
+
end
|
22
57
|
|
23
|
-
|
58
|
+
def handle_response(response)
|
59
|
+
return parse_successful_response(response) if response.status == 200
|
24
60
|
|
25
|
-
|
26
|
-
|
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
|
61
|
+
raise GeminiAPIError, "Content generation failed: #{response.body}"
|
62
|
+
end
|
35
63
|
|
36
|
-
|
37
|
-
|
38
|
-
|
64
|
+
def parse_successful_response(response)
|
65
|
+
resp = JSON.parse(response.body)
|
66
|
+
def resp.content
|
67
|
+
dig('candidates', 0, 'content', 'parts', 0, 'text')
|
68
|
+
end
|
69
|
+
resp
|
39
70
|
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
71
|
end
|
72
|
+
|
73
|
+
class GeminiAPIError < StandardError; end
|
data/lib/gemini_cache.rb
CHANGED
@@ -4,122 +4,89 @@ 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
|
|
9
11
|
module GeminiCache
|
10
|
-
|
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
|
12
|
+
class Error < StandardError; end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
14
|
+
class << self
|
15
|
+
def parse_html(url:, default_remover: true)
|
16
|
+
doc = Nokogiri::HTML(URI.open(url, "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"))
|
17
|
+
%w[script style].each { |element| doc.css(element).each(&:remove) } if default_remover
|
18
|
+
doc
|
37
19
|
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
|
-
|
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
|
49
20
|
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
21
|
+
def read_local_file(path:, mime_type:)
|
22
|
+
{ inline_data: { mime_type:, data: Base64.strict_encode64(File.read(path)) } }
|
23
|
+
end
|
57
24
|
|
58
|
-
|
59
|
-
|
60
|
-
|
25
|
+
def read_remote_file(url:, mime_type:)
|
26
|
+
{ inline_data: { mime_type:, data: Base64.strict_encode64(URI.open(url).read) } }
|
27
|
+
end
|
61
28
|
|
62
|
-
|
63
|
-
|
29
|
+
def read_webpage_text(url:, default_remover: true) = { text: parse_html(url:, default_remover:).inner_text }
|
30
|
+
|
31
|
+
def create(parts:, display_name:, on_conflict: :raise_error, model: nil, ttl: nil)
|
32
|
+
existing_cache = find_by_display_name(display_name:)
|
33
|
+
|
34
|
+
if existing_cache
|
35
|
+
case on_conflict
|
36
|
+
when :raise_error
|
37
|
+
raise Error, "Cache with display name '#{display_name}' already exists"
|
38
|
+
when :get_existing
|
39
|
+
return existing_cache
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
content = {
|
44
|
+
model: "models/#{model || configuration.default_model}",
|
45
|
+
display_name: display_name,
|
46
|
+
contents: [{ parts:, role: 'user' }],
|
47
|
+
ttl: "#{ttl || configuration.default_ttl}s"
|
48
|
+
}
|
49
|
+
|
50
|
+
response = api_client.create_cache(content.to_json)
|
51
|
+
find_by_name(name: response['name'])
|
52
|
+
end
|
64
53
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
54
|
+
def create_from_text(text:, **options) = create(parts: [{ text: }], **options)
|
55
|
+
def create_from_webpage(url:, **options) = create_from_text(text: read_webpage_text(url:)[:text], **options)
|
56
|
+
def create_from_local_file(path:, mime_type:, **options)
|
57
|
+
file_data = read_local_file(path: path, mime_type: mime_type)
|
58
|
+
create(parts: [file_data], **options)
|
59
|
+
end
|
70
60
|
|
71
|
-
|
72
|
-
|
61
|
+
def create_from_remote_file(url:, mime_type:, **options)
|
62
|
+
file_data = read_remote_file(url: url, mime_type: mime_type)
|
63
|
+
create(parts: [file_data], **options)
|
73
64
|
end
|
74
|
-
|
75
|
-
return [] if JSON.parse(response.body).empty?
|
76
65
|
|
77
|
-
|
66
|
+
def list
|
67
|
+
response = api_client.list_caches
|
68
|
+
return [] if response.empty?
|
78
69
|
|
79
|
-
|
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
|
70
|
+
response['cachedContents'].map { |item| item.extend(ItemExtender) }
|
92
71
|
end
|
93
72
|
|
94
|
-
|
95
|
-
|
96
|
-
raise "Erro ao atualizar cache: #{response.body}"
|
97
|
-
rescue Faraday::Error => e
|
98
|
-
raise "Erro na requisição: #{e.message}"
|
99
|
-
end
|
73
|
+
def find_by_name(name:) = list.find { |item| item['name'].eql?(name) }
|
74
|
+
def find_by_display_name(display_name:) = list.find { |item| item['displayName'].eql?(display_name) }
|
100
75
|
|
101
|
-
|
102
|
-
conn = Faraday.new(
|
103
|
-
url: 'https://generativelanguage.googleapis.com',
|
104
|
-
headers: { 'Content-Type' => 'application/json' }
|
105
|
-
)
|
76
|
+
def update(name:, content:) = api_client.update_cache(name, content)
|
106
77
|
|
107
|
-
|
108
|
-
|
78
|
+
def delete(name:)
|
79
|
+
api_client.delete_cache(name)
|
80
|
+
true
|
109
81
|
end
|
110
82
|
|
111
|
-
|
112
|
-
|
113
|
-
raise "Erro ao deletar cache: #{response.body}"
|
114
|
-
rescue Faraday::Error => e
|
115
|
-
raise "Erro na requisição: #{e.message}"
|
116
|
-
end
|
83
|
+
def delete_all() = list.each { |item| item.delete }
|
84
|
+
alias clear delete_all
|
117
85
|
|
118
|
-
|
119
|
-
GeminiCache.list.each { |item| item.delete }
|
120
|
-
end
|
86
|
+
private
|
121
87
|
|
122
|
-
|
123
|
-
|
88
|
+
def api_client
|
89
|
+
@api_client ||= ApiClient.new
|
90
|
+
end
|
124
91
|
end
|
125
92
|
end
|
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.12
|
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-01-06 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: faraday
|
@@ -58,13 +57,15 @@ executables: []
|
|
58
57
|
extensions: []
|
59
58
|
extra_rdoc_files: []
|
60
59
|
files:
|
60
|
+
- README.md
|
61
61
|
- lib/gemini_cache.rb
|
62
|
+
- lib/gemini_cache/api_client.rb
|
63
|
+
- lib/gemini_cache/configuration.rb
|
62
64
|
- lib/gemini_cache/item_extender.rb
|
63
65
|
homepage: https://github.com/gedean/gemini_cache
|
64
66
|
licenses:
|
65
67
|
- MIT
|
66
68
|
metadata: {}
|
67
|
-
post_install_message:
|
68
69
|
rdoc_options: []
|
69
70
|
require_paths:
|
70
71
|
- lib
|
@@ -79,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
80
|
- !ruby/object:Gem::Version
|
80
81
|
version: '0'
|
81
82
|
requirements: []
|
82
|
-
rubygems_version: 3.
|
83
|
-
signing_key:
|
83
|
+
rubygems_version: 3.6.2
|
84
84
|
specification_version: 4
|
85
85
|
summary: Ruby Gemini Context Caching
|
86
86
|
test_files: []
|