girb-gemini 0.1.0

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: e951ec329dbfe7deddbd367e410abb158f1638af5f78a231d6570669bdc8fc5d
4
+ data.tar.gz: 34ec3ad651b0fbe76373c17919a6b00a0959c4a9f1faf3c8fd981228f9e49a3a
5
+ SHA512:
6
+ metadata.gz: b176f9abe0e37080db7989804e7ba1e936e43eefea1ea6bd6fa1d95e0d3e85d67b7c9eb8d5c2158ec1e2aba55dbb6fba10fda68816a103ebc67445e2760aa616
7
+ data.tar.gz: 4f75ced680fadba2c1671362956b017afc256f657361520ccd8f0c574dbf941c5c3ae4dbd1891b7d9bcfa54d19068cd9d01df6ba9394a75c22c6f764ef018c62
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2025-02-02
4
+
5
+ ### Added
6
+
7
+ - Initial release
8
+ - Google Gemini LLM provider for girb
9
+ - Support for gemini-2.5-flash, gemini-2.5-pro, and other Gemini models
10
+ - Auto-configuration via GEMINI_API_KEY environment variable
11
+ - Function calling support
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rira
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # girb-gemini
2
+
3
+ Google Gemini LLM provider for [girb](https://github.com/rira100000000/girb) (AI-powered IRB assistant).
4
+
5
+ [日本語版 README](README_ja.md)
6
+
7
+ ## Installation
8
+
9
+ Add to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'girb'
13
+ gem 'girb-gemini'
14
+ ```
15
+
16
+ Or install directly:
17
+
18
+ ```bash
19
+ gem install girb girb-gemini
20
+ ```
21
+
22
+ ## Setup
23
+
24
+ Set your API key and provider:
25
+
26
+ ```bash
27
+ export GEMINI_API_KEY=your-api-key
28
+ export GIRB_PROVIDER=girb-gemini
29
+ ```
30
+
31
+ Then start girb:
32
+
33
+ ```bash
34
+ girb
35
+ ```
36
+
37
+ ### Using with regular irb
38
+
39
+ Add to your `~/.irbrc`:
40
+
41
+ ```ruby
42
+ require 'girb-gemini'
43
+ ```
44
+
45
+ Then use regular `irb` command.
46
+
47
+ ## Manual Configuration
48
+
49
+ ```ruby
50
+ require 'girb-gemini'
51
+
52
+ Girb.configure do |c|
53
+ c.provider = Girb::Providers::Gemini.new(
54
+ api_key: ENV['GEMINI_API_KEY'],
55
+ model: 'gemini-2.5-flash' # default
56
+ )
57
+ end
58
+ ```
59
+
60
+ ## Available Models
61
+
62
+ - `gemini-2.5-flash` (default) - Fast and efficient
63
+ - `gemini-2.5-pro` - More capable, slower
64
+
65
+ ## License
66
+
67
+ MIT License
data/README_ja.md ADDED
@@ -0,0 +1,65 @@
1
+ # girb-gemini
2
+
3
+ [girb](https://github.com/rira100000000/girb)(AI搭載IRBアシスタント)用のGoogle Gemini LLMプロバイダー。
4
+
5
+ ## インストール
6
+
7
+ Gemfileに追加:
8
+
9
+ ```ruby
10
+ gem 'girb'
11
+ gem 'girb-gemini'
12
+ ```
13
+
14
+ または直接インストール:
15
+
16
+ ```bash
17
+ gem install girb girb-gemini
18
+ ```
19
+
20
+ ## セットアップ
21
+
22
+ APIキーとプロバイダーを設定:
23
+
24
+ ```bash
25
+ export GEMINI_API_KEY=your-api-key
26
+ export GIRB_PROVIDER=girb-gemini
27
+ ```
28
+
29
+ girbを起動:
30
+
31
+ ```bash
32
+ girb
33
+ ```
34
+
35
+ ### 通常のirbで使用する場合
36
+
37
+ `~/.irbrc` に追加:
38
+
39
+ ```ruby
40
+ require 'girb-gemini'
41
+ ```
42
+
43
+ 通常の `irb` コマンドで使用できます。
44
+
45
+ ## 手動設定
46
+
47
+ ```ruby
48
+ require 'girb-gemini'
49
+
50
+ Girb.configure do |c|
51
+ c.provider = Girb::Providers::Gemini.new(
52
+ api_key: ENV['GEMINI_API_KEY'],
53
+ model: 'gemini-2.5-flash' # デフォルト
54
+ )
55
+ end
56
+ ```
57
+
58
+ ## 利用可能なモデル
59
+
60
+ - `gemini-2.5-flash` (デフォルト) - 高速で効率的
61
+ - `gemini-2.5-pro` - より高性能、やや遅い
62
+
63
+ ## ライセンス
64
+
65
+ MIT License
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/girb-gemini/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "girb-gemini"
7
+ spec.version = GirbGemini::VERSION
8
+ spec.authors = ["rira100000000"]
9
+ spec.email = ["101010hayakawa@gmail.com"]
10
+
11
+ spec.summary = "Gemini provider for girb"
12
+ spec.description = "Google Gemini LLM provider for girb (AI-powered IRB assistant). " \
13
+ "Install this gem to use Gemini as your LLM backend."
14
+ spec.homepage = "https://github.com/rira100000000/girb-gemini"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = ">= 3.2.0"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = spec.homepage
20
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
21
+
22
+ spec.files = Dir.chdir(__dir__) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (File.expand_path(f) == __FILE__) ||
25
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
26
+ end
27
+ end
28
+ spec.require_paths = ["lib"]
29
+
30
+ # Runtime dependencies
31
+ spec.add_dependency "girb", "~> 0.1"
32
+ spec.add_dependency "ruby-gemini-api", "~> 1.0"
33
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gemini"
4
+ require "girb/providers/base"
5
+
6
+ module Girb
7
+ module Providers
8
+ class Gemini < Base
9
+ DEFAULT_MODEL = "gemini-2.5-flash"
10
+
11
+ def initialize(api_key:, model: DEFAULT_MODEL)
12
+ @client = ::Gemini::Client.new(api_key)
13
+ @model = model
14
+ end
15
+
16
+ def chat(messages:, system_prompt:, tools:)
17
+ contents = convert_messages(messages)
18
+ tools_param = build_tools_param(tools)
19
+
20
+ response = @client.chat(parameters: {
21
+ model: @model,
22
+ system_instruction: { parts: [{ text: system_prompt }] },
23
+ contents: contents,
24
+ tools: tools_param
25
+ }.compact)
26
+
27
+ parse_response(response)
28
+ rescue Faraday::BadRequestError => e
29
+ Response.new(error: "API Error: #{e.message}")
30
+ rescue StandardError => e
31
+ Response.new(error: "Error: #{e.message}")
32
+ end
33
+
34
+ private
35
+
36
+ def convert_messages(messages)
37
+ messages.map do |msg|
38
+ case msg[:role]
39
+ when :user
40
+ { role: "user", parts: [{ text: msg[:content] }] }
41
+ when :assistant
42
+ { role: "model", parts: [{ text: msg[:content] }] }
43
+ when :tool_call
44
+ {
45
+ role: "model",
46
+ parts: [{
47
+ function_call: {
48
+ name: msg[:name],
49
+ args: msg[:args]
50
+ }
51
+ }]
52
+ }
53
+ when :tool_result
54
+ {
55
+ role: "user",
56
+ parts: [{
57
+ function_response: {
58
+ name: msg[:name],
59
+ response: msg[:result]
60
+ }
61
+ }]
62
+ }
63
+ else
64
+ { role: "user", parts: [{ text: msg[:content].to_s }] }
65
+ end
66
+ end
67
+ end
68
+
69
+ def build_tools_param(tools)
70
+ return nil if tools.empty?
71
+
72
+ gemini_tools = ::Gemini::ToolDefinition.new
73
+
74
+ tools.each do |tool|
75
+ gemini_tools.add_function(
76
+ tool[:name].to_sym,
77
+ description: tool[:description]
78
+ ) do
79
+ properties = tool.dig(:parameters, :properties) || {}
80
+ required = tool.dig(:parameters, :required) || []
81
+
82
+ properties.each do |prop_name, prop_def|
83
+ type = prop_def[:type]&.to_sym || :string
84
+ desc = prop_def[:description] || ""
85
+ is_required = required.include?(prop_name.to_s) || required.include?(prop_name)
86
+
87
+ property prop_name, type: type, description: desc, required: is_required
88
+ end
89
+ end
90
+ end
91
+
92
+ declarations = gemini_tools.to_h[:function_declarations]
93
+ declarations ? [{ function_declarations: declarations }] : nil
94
+ end
95
+
96
+ def parse_response(response)
97
+ return Response.new(error: "No response") unless response
98
+
99
+ text = response.text
100
+ function_calls = parse_function_calls(response)
101
+
102
+ if response.respond_to?(:error) && response.error
103
+ Response.new(error: response.error, raw_response: response)
104
+ else
105
+ Response.new(text: text, function_calls: function_calls, raw_response: response)
106
+ end
107
+ end
108
+
109
+ def parse_function_calls(response)
110
+ return [] unless response.function_calls&.any?
111
+
112
+ response.function_calls.map do |fc|
113
+ {
114
+ name: fc["name"],
115
+ args: fc["args"] || {}
116
+ }
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GirbGemini
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "girb"
4
+ require_relative "girb/providers/gemini"
5
+
6
+ # Auto-configure Gemini provider if API key is available
7
+ if ENV["GEMINI_API_KEY"]
8
+ Girb.configure do |c|
9
+ unless c.provider
10
+ c.provider = Girb::Providers::Gemini.new(
11
+ api_key: ENV["GEMINI_API_KEY"],
12
+ model: c.model || "gemini-2.5-flash"
13
+ )
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: girb-gemini
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - rira100000000
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: girb
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby-gemini-api
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ description: Google Gemini LLM provider for girb (AI-powered IRB assistant). Install
41
+ this gem to use Gemini as your LLM backend.
42
+ email:
43
+ - 101010hayakawa@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - CHANGELOG.md
49
+ - LICENSE
50
+ - README.md
51
+ - README_ja.md
52
+ - Rakefile
53
+ - girb-gemini.gemspec
54
+ - lib/girb-gemini.rb
55
+ - lib/girb-gemini/version.rb
56
+ - lib/girb/providers/gemini.rb
57
+ homepage: https://github.com/rira100000000/girb-gemini
58
+ licenses:
59
+ - MIT
60
+ metadata:
61
+ homepage_uri: https://github.com/rira100000000/girb-gemini
62
+ source_code_uri: https://github.com/rira100000000/girb-gemini
63
+ changelog_uri: https://github.com/rira100000000/girb-gemini/blob/main/CHANGELOG.md
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 3.2.0
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.7.2
79
+ specification_version: 4
80
+ summary: Gemini provider for girb
81
+ test_files: []