ruby-gemini-api 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5a02e1edca475bc3a7ab45e9e595186a99e2546fb46c1f1f1232a8215d45469
4
- data.tar.gz: a688b8e1a0bb724ab24d8cb1113ad689a784bc41915b180e17e9b4552dad4628
3
+ metadata.gz: 36071e1dcc5fb406f9f49318cc2cffdb0e4159a0811c74da0aebd48293d9ef02
4
+ data.tar.gz: cdccba0ec67eb7fa2cd69ffcb8ddcd79c7056d6a636dcb3ccd0d05af14f5acbd
5
5
  SHA512:
6
- metadata.gz: a5d4af0804fb7ded6bbf069b492b31b56979ab6421dafcf671704a8aae62405946ca4efa6cdb1ef13ab69ec16a19fb0b1d19df5045d6840ae843c7500250094d
7
- data.tar.gz: e9c83f07e0cfb54827d7c0a4180ab8731a7b8580669073d7d9acfe0a8b45b015d18c42acf6fbd1ffd2da3b9acb89ea7723da7e1abba756761666944a985f63dc
6
+ metadata.gz: e50e268d2c015f45bf6db61d07e5b124aa07b967a278999aa00c29f760e1c41d1465af8582055764fc64454156f15130f498318cdc264cd78d342dc28cec4030
7
+ data.tar.gz: 21a68ce8106b7b2d0e5e9468d0464f91a18b62cbfad7c6c6924280d58bf525f9b4ac7e87ffe0e06076bd03b9f2b77fe0b6e35b9ba93bdfaedfbcc65afc6abc40
data/CHANGELOG.md CHANGED
@@ -5,3 +5,6 @@
5
5
 
6
6
  ## [0.1.1] - 2025-05-04
7
7
  - Changed generate_contents to accept temperature parameter
8
+
9
+ ## [0.1.2] - 2025-07-10
10
+ - Add function calling
data/README.md CHANGED
@@ -18,6 +18,55 @@ This project is inspired by and pays homage to [ruby-openai](https://github.com/
18
18
  - Document processing (PDFs and other formats)
19
19
  - Context caching for efficient processing
20
20
 
21
+ ### How to use Function Calling
22
+
23
+ ```ruby
24
+ require 'gemini'
25
+
26
+ # Initialize Gemini client
27
+ client = Gemini::Client.new(ENV['GEMINI_API_KEY'])
28
+
29
+ # Define function declarations for Function Calling
30
+ # Note: Use camelCase (functionDeclarations) for Gemini API compatibility
31
+ tools = [
32
+ {
33
+ functionDeclarations: [
34
+ {
35
+ name: "get_current_weather",
36
+ description: "Get the current weather information",
37
+ parameters: {
38
+ type: "object",
39
+ properties: {
40
+ location: {
41
+ type: "string",
42
+ description: "City name, e.g., Tokyo"
43
+ }
44
+ },
45
+ required: ["location"]
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+
52
+ # User prompt
53
+ user_prompt = "Tell me the current weather in Tokyo."
54
+
55
+ # Send request with Function Calling tools
56
+ response = client.generate_content(
57
+ user_prompt,
58
+ model: "gemini-2.0-flash",
59
+ tools: tools
60
+ )
61
+
62
+ # Parse function call from the response
63
+ unless response.function_calls.empty?
64
+ function_call = response.function_calls.first
65
+ puts "Function name to call: #{function_call["name"]}"
66
+ puts "Function arguments: #{function_call["args"]}"
67
+ end
68
+ ```
69
+
21
70
  ## Installation
22
71
 
23
72
  Add this line to your application's Gemfile:
data/lib/gemini/client.rb CHANGED
@@ -116,34 +116,30 @@ module Gemini
116
116
 
117
117
  # Helper methods for convenience
118
118
 
119
- # Method with usage similar to OpenAI's chat
119
+ # Method with usage similar to OpenAI's chat
120
120
  def generate_content(prompt, model: "gemini-2.0-flash-lite", system_instruction: nil,
121
- response_mime_type: nil, response_schema: nil, temperature: 0.5, **parameters, &stream_callback)
122
- # For image/text combinations, the prompt is passed as an array
123
- # example: [{type: "text", text: "What is this?"}, {type: "image_url", image_url: {url: "https://example.com/image.jpg"}}]
121
+ response_mime_type: nil, response_schema: nil, temperature: 0.5, tools: nil, **parameters, &stream_callback)
124
122
  content = format_content(prompt)
125
123
  params = {
126
124
  contents: [content],
127
125
  model: model
128
126
  }
129
-
127
+
130
128
  if system_instruction
131
129
  params[:system_instruction] = format_content(system_instruction)
132
130
  end
133
-
134
- params[:generation_config] ||= {}
135
-
131
+ params[:generation_config] ||= {}
132
+ params[:generation_config]["temperature"] = temperature
136
133
  if response_mime_type
137
134
  params[:generation_config]["response_mime_type"] = response_mime_type
138
135
  end
139
-
136
+
140
137
  if response_schema
141
138
  params[:generation_config]["response_schema"] = response_schema
142
139
  end
143
- params[:generation_config]["temperature"] = temperature
144
- # Merge other parameters
140
+ params[:tools] = tools if tools
145
141
  params.merge!(parameters)
146
-
142
+
147
143
  if block_given?
148
144
  chat(parameters: params, &stream_callback)
149
145
  else
@@ -138,11 +138,8 @@ module Gemini
138
138
 
139
139
  # Get function call information
140
140
  def function_calls
141
- return [] unless valid?
142
-
143
- first_candidate&.dig("content", "parts")
144
- &.select { |part| part.key?("functionCall") }
145
- &.map { |part| part["functionCall"] } || []
141
+ parts = first_candidate.dig("content", "parts") || []
142
+ parts.map { |part| part["functionCall"] }.compact
146
143
  end
147
144
 
148
145
  # Get response role (usually "model")
@@ -0,0 +1,68 @@
1
+ module Gemini
2
+ class ToolDefinition
3
+ def initialize(&block)
4
+ @functions = {}
5
+ instance_eval(&block) if block_given?
6
+ end
7
+
8
+ def function(name, description:, &block)
9
+ @functions[name] = {
10
+ name: name,
11
+ description: description,
12
+ parameters: {
13
+ type: 'object',
14
+ properties: {},
15
+ required: []
16
+ }
17
+ }
18
+ @current_function = name
19
+ instance_eval(&block) if block_given?
20
+ @current_function = nil
21
+ end
22
+ alias add_function function
23
+
24
+ def property(name, type:, description:, required: false)
25
+ raise 'property must be defined within a function block' unless @current_function
26
+
27
+ @functions[@current_function][:parameters][:properties][name] = {
28
+ type: type.to_s,
29
+ description: description
30
+ }
31
+ @functions[@current_function][:parameters][:required] << name if required
32
+ end
33
+
34
+ def +(other)
35
+ raise ArgumentError, 'can only merge with another ToolDefinition' unless other.is_a?(ToolDefinition)
36
+
37
+ new_definition = dup
38
+ other.instance_variable_get(:@functions).each do |name, definition|
39
+ new_definition.instance_variable_get(:@functions)[name] = definition
40
+ end
41
+ new_definition
42
+ end
43
+
44
+ def delete_function(name)
45
+ @functions.delete(name)
46
+ end
47
+
48
+ def list_functions
49
+ @functions.keys
50
+ end
51
+
52
+ def to_h
53
+ {
54
+ function_declarations: @functions.values
55
+ }
56
+ end
57
+
58
+ def to_json(*args)
59
+ to_h.to_json(*args)
60
+ end
61
+
62
+ def dup
63
+ new_instance = self.class.new
64
+ new_instance.instance_variable_set(:@functions, @functions.dup)
65
+ new_instance
66
+ end
67
+ end
68
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gemini
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/gemini.rb CHANGED
@@ -3,7 +3,8 @@ require "faraday/multipart"
3
3
  require "json"
4
4
  require 'dotenv/load'
5
5
 
6
- require_relative "gemini/version"
6
+ require_relative 'gemini/version'
7
+ require_relative 'gemini/tool_definition'
7
8
  require_relative "gemini/http_headers"
8
9
  require_relative "gemini/http"
9
10
  require_relative "gemini/client"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-gemini-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - rira100000000
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-04 00:00:00.000000000 Z
11
+ date: 2025-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -161,6 +161,7 @@ files:
161
161
  - lib/gemini/response.rb
162
162
  - lib/gemini/runs.rb
163
163
  - lib/gemini/threads.rb
164
+ - lib/gemini/tool_definition.rb
164
165
  - lib/gemini/version.rb
165
166
  - lib/ruby/gemini.rb
166
167
  homepage: https://github.com/rira100000000/ruby-gemini-api