lex-gemini 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3fc603fd61048eacb62856e1d69d9f3a91bea5bc0af2fd6fa302021a6f54b2f1
4
+ data.tar.gz: 2019858b1f1587e40b4d71aaa13d0cdf8b06a3202e3d0313690da4add0bf24c3
5
+ SHA512:
6
+ metadata.gz: f72c04be03d39391f3afeb17fee0440840c75852b9fb6bb6ca17625ba86aa5f1a2a87e2dfe72fe94342621af70d6dfa168f64e78e935f5885ef4bb34c9dbc887
7
+ data.tar.gz: c68e1688f7d9f07a34e17fa1d8fb553769d8bb98bf441e21069bf32cea38bc7b49d1baaea5318eaeac9d0bbd1a060d37c676daf1c39a1c61405a0ccb6461b85a
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,54 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
6
+ Layout/LineLength:
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
16
+ Metrics/MethodLength:
17
+ Max: 50
18
+
19
+ Metrics/ClassLength:
20
+ Max: 1500
21
+
22
+ Metrics/ModuleLength:
23
+ Max: 1500
24
+
25
+ Metrics/BlockLength:
26
+ Max: 40
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
30
+ Metrics/AbcSize:
31
+ Max: 60
32
+
33
+ Metrics/CyclomaticComplexity:
34
+ Max: 15
35
+
36
+ Metrics/PerceivedComplexity:
37
+ Max: 17
38
+
39
+ Style/Documentation:
40
+ Enabled: false
41
+
42
+ Style/SymbolArray:
43
+ Enabled: true
44
+
45
+ Style/FrozenStringLiteralComment:
46
+ Enabled: true
47
+ EnforcedStyle: always
48
+
49
+ Metrics/ParameterLists:
50
+ Max: 10
51
+ CountKeywordArgs: false
52
+
53
+ Naming/FileName:
54
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## [0.1.1] - 2026-03-18
4
+
5
+ ### Changed
6
+ - deleted gemfile.lock
7
+
8
+ ## [0.1.0] - 2026-03-13
9
+
10
+ ### Added
11
+ - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,65 @@
1
+ # lex-gemini: Google Gemini API Integration for LegionIO
2
+
3
+ **Repository Level 3 Documentation**
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-ai/CLAUDE.md`
5
+ - **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Legion Extension that connects LegionIO to Google Gemini API. Generate content, create embeddings, manage files, count tokens, and cache content.
10
+
11
+ **GitHub**: https://github.com/LegionIO/lex-gemini
12
+ **License**: MIT
13
+ **Version**: 0.1.0
14
+ **Specs**: 36 examples
15
+
16
+ ## Architecture
17
+
18
+ ```
19
+ Legion::Extensions::Gemini
20
+ ├── Runners/
21
+ │ ├── Content # generate(api_key:, contents:, model:, ...), stream_generate(...)
22
+ │ ├── Embeddings # embed(api_key:, content:, model:, ...), batch_embed(...)
23
+ │ ├── Models # list(api_key:, ...), get(api_key:, name:, ...)
24
+ │ ├── Tokens # count(api_key:, contents:, model:, ...)
25
+ │ ├── Files # upload(api_key:, file_path:, mime_type:, ...), list, get, delete
26
+ │ └── CachedContents # create(api_key:, model:, contents:, ...), list, get, update, delete
27
+ └── Helpers/
28
+ └── Client # Faraday-based HTTP client (class, instantiated per-request)
29
+ ```
30
+
31
+ Unlike lex-claude and lex-openai, `Helpers::Client` is a **class** instantiated per-request. Each runner creates `Helpers::Client.new(api_key:, model:)` inline. This means no module-level `extend` is used in runners; instead, runners call `Helpers::Client.new(...)` directly.
32
+
33
+ `include Legion::Extensions::Helpers::Lex` guard: uses `if defined?(Legion::Extensions::Helpers::Lex)` (note: slightly different guard pattern from lex-claude/lex-openai which use `const_defined?`).
34
+
35
+ ## Key Design Decisions
36
+
37
+ - `Helpers::Client` is a class to allow per-request model selection without global state.
38
+ - Authentication uses query parameter `?key=<api_key>` set on the Faraday connection params, so all requests automatically include it.
39
+ - File upload falls back to raw binary upload (`X-Goog-Upload-Protocol: raw`) when `faraday-multipart` is not loaded.
40
+ - `Helpers::Client#handle_response` returns the raw body on success and `{ error:, status: }` on failure (unlike lex-claude/lex-openai which always return `{ result:, status: }`).
41
+ - `gemini-2.0-flash` is the default model for Content, Tokens, and `Helpers::Client` initialization.
42
+ - `gemini-embedding-exp` is the default model for Embeddings runners.
43
+
44
+ ## API Base URL
45
+
46
+ `https://generativelanguage.googleapis.com` — path prefix `v1beta` is prepended per-request in `Helpers::Client`.
47
+
48
+ ## Dependencies
49
+
50
+ | Gem | Purpose |
51
+ |-----|---------|
52
+ | `faraday` >= 2.0 | HTTP client for Gemini REST API |
53
+ | `faraday-multipart` | File uploads (optional — falls back to raw binary upload if not available) |
54
+
55
+ ## Testing
56
+
57
+ ```bash
58
+ bundle install
59
+ bundle exec rspec # 36 examples
60
+ bundle exec rubocop
61
+ ```
62
+
63
+ ---
64
+
65
+ **Maintained By**: Matthew Iverson (@Esity)
data/Dockerfile ADDED
@@ -0,0 +1,6 @@
1
+ FROM legionio/legion
2
+
3
+ COPY . /usr/src/app/lex-gemini
4
+
5
+ WORKDIR /usr/src/app/lex-gemini
6
+ RUN bundle install
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'rspec_junit_formatter'
10
+ gem 'rubocop'
11
+ gem 'simplecov'
12
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Esity
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # lex-gemini
2
+
3
+ Google Gemini API integration for [LegionIO](https://github.com/LegionIO/LegionIO). Generate content, create embeddings, manage files, count tokens, and cache content using Google's Gemini models.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install lex-gemini
9
+ ```
10
+
11
+ Or add to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'lex-gemini'
15
+ ```
16
+
17
+ ## Functions
18
+
19
+ ### Content
20
+ - `generate` - Generate text content using Gemini models
21
+ - `stream_generate` - Stream generated content
22
+
23
+ ### Embeddings
24
+ - `embed` - Generate embedding vectors from text
25
+ - `batch_embed` - Generate multiple embeddings in one request
26
+
27
+ ### Models
28
+ - `list` - List available Gemini models
29
+ - `get` - Get details about a specific model
30
+
31
+ ### Tokens
32
+ - `count` - Count tokens in content
33
+
34
+ ### Files
35
+ - `upload` - Upload a file for use with Gemini
36
+ - `list` - List uploaded files
37
+ - `get` - Get file metadata
38
+ - `delete` - Delete an uploaded file
39
+
40
+ ### Cached Contents
41
+ - `create` - Create cached content for repeated use
42
+ - `list` - List cached contents
43
+ - `get` - Get cached content details
44
+ - `update` - Update cached content expiration
45
+ - `delete` - Delete cached content
46
+
47
+ ## Configuration
48
+
49
+ Set your API key in your LegionIO settings:
50
+
51
+ ```json
52
+ {
53
+ "gemini": {
54
+ "api_key": "AIza..."
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Standalone Usage
60
+
61
+ ```ruby
62
+ require 'legion/extensions/gemini/helpers/client'
63
+
64
+ client = Legion::Extensions::Gemini::Helpers::Client.new(
65
+ api_key: ENV['GEMINI_API_KEY'],
66
+ model: 'gemini-2.0-flash'
67
+ )
68
+
69
+ # Generate content
70
+ result = client.generate_content(
71
+ contents: [{ parts: [{ text: 'Explain quantum entanglement in one sentence.' }] }]
72
+ )
73
+ puts result.dig('candidates', 0, 'content', 'parts', 0, 'text')
74
+
75
+ # Generate embeddings
76
+ embedding_client = Legion::Extensions::Gemini::Helpers::Client.new(
77
+ api_key: ENV['GEMINI_API_KEY'],
78
+ model: 'gemini-embedding-exp'
79
+ )
80
+ embedding = embedding_client.embed_content(
81
+ content: { parts: [{ text: 'Hello world' }] }
82
+ )
83
+ puts embedding['embedding']['values'].length
84
+
85
+ # Count tokens
86
+ tokens = client.count_tokens(
87
+ contents: [{ parts: [{ text: 'How many tokens?' }] }]
88
+ )
89
+ puts tokens['totalTokens']
90
+ ```
91
+
92
+ ## Dependencies
93
+
94
+ - `faraday` >= 2.0 - HTTP client
95
+ - `faraday-multipart` (optional) - required only for multipart file uploads; raw binary upload used as fallback
96
+
97
+ ## Requirements
98
+
99
+ - Ruby >= 3.4
100
+ - [LegionIO](https://github.com/LegionIO/LegionIO) framework (optional for standalone usage)
101
+ - Google Gemini API key ([Get one here](https://ai.google.dev/))
102
+
103
+ ## License
104
+
105
+ MIT
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/gemini/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-gemini'
7
+ spec.version = Legion::Extensions::Gemini::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Gemini'
12
+ spec.description = 'Connects LegionIO to Google Gemini API'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-gemini'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-gemini'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-gemini'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-gemini'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-gemini/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'faraday', '>= 2.0'
30
+ end
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+
6
+ module Legion
7
+ module Extensions
8
+ module Gemini
9
+ module Helpers
10
+ class Client
11
+ BASE_URL = 'https://generativelanguage.googleapis.com'
12
+ API_VERSION = 'v1beta'
13
+
14
+ attr_reader :api_key, :model, :connection
15
+
16
+ def initialize(api_key:, model: 'gemini-2.0-flash', base_url: BASE_URL)
17
+ @api_key = api_key
18
+ @model = model
19
+ @connection = Faraday.new(url: base_url) do |conn|
20
+ conn.request :json
21
+ conn.response :json
22
+ conn.params['key'] = api_key
23
+ end
24
+ end
25
+
26
+ def generate_content(contents:, generation_config: nil, safety_settings: nil, system_instruction: nil, model: @model)
27
+ body = { contents: contents }
28
+ body[:generationConfig] = generation_config if generation_config
29
+ body[:safetySettings] = safety_settings if safety_settings
30
+ body[:systemInstruction] = system_instruction if system_instruction
31
+ post("#{API_VERSION}/models/#{model}:generateContent", body)
32
+ end
33
+
34
+ def stream_generate_content(contents:, generation_config: nil, safety_settings: nil, system_instruction: nil, model: @model)
35
+ body = { contents: contents }
36
+ body[:generationConfig] = generation_config if generation_config
37
+ body[:safetySettings] = safety_settings if safety_settings
38
+ body[:systemInstruction] = system_instruction if system_instruction
39
+ post("#{API_VERSION}/models/#{model}:streamGenerateContent", body)
40
+ end
41
+
42
+ def embed_content(content:, task_type: nil, title: nil, model: @model)
43
+ body = { content: content }
44
+ body[:taskType] = task_type if task_type
45
+ body[:title] = title if title
46
+ post("#{API_VERSION}/models/#{model}:embedContent", body)
47
+ end
48
+
49
+ def batch_embed_contents(requests:, model: @model)
50
+ post("#{API_VERSION}/models/#{model}:batchEmbedContents", { requests: requests })
51
+ end
52
+
53
+ def list_models
54
+ get("#{API_VERSION}/models")
55
+ end
56
+
57
+ def get_model(name:)
58
+ get("#{API_VERSION}/models/#{name}")
59
+ end
60
+
61
+ def count_tokens(contents:, model: @model)
62
+ post("#{API_VERSION}/models/#{model}:countTokens", { contents: contents })
63
+ end
64
+
65
+ def upload_file(file_path:, mime_type:, display_name: nil)
66
+ metadata = { file: { mimeType: mime_type } }
67
+ metadata[:file][:displayName] = display_name if display_name
68
+
69
+ upload_conn = Faraday.new(url: BASE_URL) do |conn|
70
+ conn.params['key'] = api_key
71
+ end
72
+
73
+ payload = Faraday::Multipart::FilePart.new(file_path, mime_type) if defined?(Faraday::Multipart)
74
+
75
+ if payload
76
+ upload_conn.request :multipart
77
+ upload_conn.post("/upload/#{API_VERSION}/files") do |req|
78
+ req.body = { metadata: metadata.to_json, file: payload }
79
+ end
80
+ else
81
+ upload_conn.post("/upload/#{API_VERSION}/files") do |req|
82
+ req.headers['Content-Type'] = mime_type
83
+ req.headers['X-Goog-Upload-Protocol'] = 'raw'
84
+ req.body = File.binread(file_path)
85
+ end
86
+ end
87
+ end
88
+
89
+ def list_files(page_size: nil, page_token: nil)
90
+ params = {}
91
+ params[:pageSize] = page_size if page_size
92
+ params[:pageToken] = page_token if page_token
93
+ get("#{API_VERSION}/files", params)
94
+ end
95
+
96
+ def get_file(name:)
97
+ get("#{API_VERSION}/#{name}")
98
+ end
99
+
100
+ def delete_file(name:)
101
+ delete("#{API_VERSION}/#{name}")
102
+ end
103
+
104
+ def create_cached_content(model:, contents:, ttl: nil, expire_time: nil, display_name: nil, system_instruction: nil)
105
+ body = { model: "models/#{model}", contents: contents }
106
+ body[:ttl] = ttl if ttl
107
+ body[:expireTime] = expire_time if expire_time
108
+ body[:displayName] = display_name if display_name
109
+ body[:systemInstruction] = system_instruction if system_instruction
110
+ post("#{API_VERSION}/cachedContents", body)
111
+ end
112
+
113
+ def list_cached_contents(page_size: nil, page_token: nil)
114
+ params = {}
115
+ params[:pageSize] = page_size if page_size
116
+ params[:pageToken] = page_token if page_token
117
+ get("#{API_VERSION}/cachedContents", params)
118
+ end
119
+
120
+ def get_cached_content(name:)
121
+ get("#{API_VERSION}/#{name}")
122
+ end
123
+
124
+ def update_cached_content(name:, ttl: nil, expire_time: nil)
125
+ body = {}
126
+ update_masks = []
127
+ if ttl
128
+ body[:ttl] = ttl
129
+ update_masks << 'ttl'
130
+ end
131
+ if expire_time
132
+ body[:expireTime] = expire_time
133
+ update_masks << 'expireTime'
134
+ end
135
+ patch("#{API_VERSION}/#{name}", body, updateMask: update_masks.join(','))
136
+ end
137
+
138
+ def delete_cached_content(name:)
139
+ delete("#{API_VERSION}/#{name}")
140
+ end
141
+
142
+ private
143
+
144
+ def get(path, params = {})
145
+ response = connection.get(path, params)
146
+ handle_response(response)
147
+ end
148
+
149
+ def post(path, body)
150
+ response = connection.post(path, body)
151
+ handle_response(response)
152
+ end
153
+
154
+ def patch(path, body, params = {})
155
+ response = connection.patch(path) do |req|
156
+ req.params = connection.params.merge(params)
157
+ req.body = body
158
+ end
159
+ handle_response(response)
160
+ end
161
+
162
+ def delete(path)
163
+ response = connection.delete(path)
164
+ handle_response(response)
165
+ end
166
+
167
+ def handle_response(response)
168
+ return response.body if response.success?
169
+
170
+ { error: response.body, status: response.status }
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module CachedContents
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def create(api_key:, model:, contents:, ttl: nil, expire_time: nil, display_name: nil, system_instruction: nil, **)
11
+ client = Helpers::Client.new(api_key: api_key)
12
+ { result: client.create_cached_content(model: model, contents: contents, ttl: ttl, expire_time: expire_time,
13
+ display_name: display_name, system_instruction: system_instruction) }
14
+ end
15
+
16
+ def list(api_key:, page_size: nil, page_token: nil, **)
17
+ client = Helpers::Client.new(api_key: api_key)
18
+ { result: client.list_cached_contents(page_size: page_size, page_token: page_token) }
19
+ end
20
+
21
+ def get(api_key:, name:, **)
22
+ client = Helpers::Client.new(api_key: api_key)
23
+ { result: client.get_cached_content(name: name) }
24
+ end
25
+
26
+ def update(api_key:, name:, ttl: nil, expire_time: nil, **)
27
+ client = Helpers::Client.new(api_key: api_key)
28
+ { result: client.update_cached_content(name: name, ttl: ttl, expire_time: expire_time) }
29
+ end
30
+
31
+ def delete(api_key:, name:, **)
32
+ client = Helpers::Client.new(api_key: api_key)
33
+ { result: client.delete_cached_content(name: name) }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module Content
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def generate(api_key:, contents:, model: 'gemini-2.0-flash', generation_config: nil, safety_settings: nil,
11
+ system_instruction: nil, **)
12
+ client = Helpers::Client.new(api_key: api_key, model: model)
13
+ { result: client.generate_content(contents: contents, generation_config: generation_config,
14
+ safety_settings: safety_settings, system_instruction: system_instruction) }
15
+ end
16
+
17
+ def stream_generate(api_key:, contents:, model: 'gemini-2.0-flash', generation_config: nil, safety_settings: nil,
18
+ system_instruction: nil, **)
19
+ client = Helpers::Client.new(api_key: api_key, model: model)
20
+ { result: client.stream_generate_content(contents: contents, generation_config: generation_config,
21
+ safety_settings: safety_settings,
22
+ system_instruction: system_instruction) }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module Embeddings
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def embed(api_key:, content:, model: 'gemini-embedding-exp', task_type: nil, title: nil, **)
11
+ client = Helpers::Client.new(api_key: api_key, model: model)
12
+ { result: client.embed_content(content: content, task_type: task_type, title: title) }
13
+ end
14
+
15
+ def batch_embed(api_key:, requests:, model: 'gemini-embedding-exp', **)
16
+ client = Helpers::Client.new(api_key: api_key, model: model)
17
+ { result: client.batch_embed_contents(requests: requests) }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module Files
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def upload(api_key:, file_path:, mime_type:, display_name: nil, **)
11
+ client = Helpers::Client.new(api_key: api_key)
12
+ { result: client.upload_file(file_path: file_path, mime_type: mime_type, display_name: display_name) }
13
+ end
14
+
15
+ def list(api_key:, page_size: nil, page_token: nil, **)
16
+ client = Helpers::Client.new(api_key: api_key)
17
+ { result: client.list_files(page_size: page_size, page_token: page_token) }
18
+ end
19
+
20
+ def get(api_key:, name:, **)
21
+ client = Helpers::Client.new(api_key: api_key)
22
+ { result: client.get_file(name: name) }
23
+ end
24
+
25
+ def delete(api_key:, name:, **)
26
+ client = Helpers::Client.new(api_key: api_key)
27
+ { result: client.delete_file(name: name) }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module Models
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def list(api_key:, **)
11
+ client = Helpers::Client.new(api_key: api_key)
12
+ { result: client.list_models }
13
+ end
14
+
15
+ def get(api_key:, name:, **)
16
+ client = Helpers::Client.new(api_key: api_key)
17
+ { result: client.get_model(name: name) }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ module Runners
7
+ module Tokens
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def count(api_key:, contents:, model: 'gemini-2.0-flash', **)
11
+ client = Helpers::Client.new(api_key: api_key, model: model)
12
+ { result: client.count_tokens(contents: contents) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Gemini
6
+ VERSION = '0.1.1'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/gemini/version'
4
+ require 'legion/extensions/gemini/helpers/client'
5
+ require 'legion/extensions/gemini/runners/content'
6
+ require 'legion/extensions/gemini/runners/embeddings'
7
+ require 'legion/extensions/gemini/runners/models'
8
+ require 'legion/extensions/gemini/runners/tokens'
9
+ require 'legion/extensions/gemini/runners/files'
10
+ require 'legion/extensions/gemini/runners/cached_contents'
11
+
12
+ module Legion
13
+ module Extensions
14
+ module Gemini
15
+ extend Legion::Extensions::Core if defined?(Legion::Extensions::Core)
16
+ end
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-gemini
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ description: Connects LegionIO to Google Gemini API
27
+ email:
28
+ - matthewdiverson@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ".github/workflows/ci.yml"
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - ".rubocop.yml"
37
+ - CHANGELOG.md
38
+ - CLAUDE.md
39
+ - Dockerfile
40
+ - Gemfile
41
+ - LICENSE
42
+ - README.md
43
+ - lex-gemini.gemspec
44
+ - lib/legion/extensions/gemini.rb
45
+ - lib/legion/extensions/gemini/helpers/client.rb
46
+ - lib/legion/extensions/gemini/runners/cached_contents.rb
47
+ - lib/legion/extensions/gemini/runners/content.rb
48
+ - lib/legion/extensions/gemini/runners/embeddings.rb
49
+ - lib/legion/extensions/gemini/runners/files.rb
50
+ - lib/legion/extensions/gemini/runners/models.rb
51
+ - lib/legion/extensions/gemini/runners/tokens.rb
52
+ - lib/legion/extensions/gemini/version.rb
53
+ homepage: https://github.com/LegionIO/lex-gemini
54
+ licenses:
55
+ - MIT
56
+ metadata:
57
+ homepage_uri: https://github.com/LegionIO/lex-gemini
58
+ source_code_uri: https://github.com/LegionIO/lex-gemini
59
+ documentation_uri: https://github.com/LegionIO/lex-gemini
60
+ changelog_uri: https://github.com/LegionIO/lex-gemini
61
+ bug_tracker_uri: https://github.com/LegionIO/lex-gemini/issues
62
+ rubygems_mfa_required: 'true'
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '3.4'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.6.9
78
+ specification_version: 4
79
+ summary: LEX Gemini
80
+ test_files: []