ruby-gemini-api 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd1be2a2b81543d21686e9d4ade4de2e6aa42ea8b26abc4bb0929e9aa77fada0
4
- data.tar.gz: 9b96121c0a8a68220e4e368057424211e29e0652f28f1812b56049842d31c5c9
3
+ metadata.gz: 325e8812a1eb58643280cdfba86f4a8a9a8e3659d882d8fb5fc5e4ac2025a35c
4
+ data.tar.gz: 1bcf959e036341fe71a41a693accc9f0d85a0fe790f43811a2af7ae3b455e10b
5
5
  SHA512:
6
- metadata.gz: be505ec75d011d31cd3c741924b2e845024d4bccdc36b3fbdfa63e0468771a45f7dd4abbc31ec6ade82ff4e992b46bd9e3aa65a06bd874a73a799f1cdb246bed
7
- data.tar.gz: edcc02ff33b17e56a004836b2c55c7a133d883bc38c9f67893f3d3a59afb239bf7329454ef8278cf618e2d393867e445dc88bf539350999258c856f02c775b69
6
+ metadata.gz: 243dd3d0f56a645305e1345de08ca7512088e0d7ae2dfd45f2b5747614c469ed35523991da8cb7d4bef08f060b0cbfb666903e0b5c262e18cebece66405753b9
7
+ data.tar.gz: fa2234b64394200ab6039010f88d5b9ac97c70e4e4266943b0ee57848e7f0141bebe3a50929d315bb54b4ddd88c990c07d3a26cf54f904b1e89727a53a4c8a12
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ### Added
4
+ - Code Execution shortcut support via `code_execution: true` on `generate_content` / `generate_content_stream`
5
+ - `Response` helpers for Code Execution results: `#code_execution?`, `#executable_code`, `#executable_codes`, `#code_execution_output`, `#code_execution_outcome`, `#code_execution_success?`, `#code_execution_results`
6
+
3
7
  ## [1.2.0] - 2026-05-14
4
8
 
5
9
  ### Added
data/README.md CHANGED
@@ -34,6 +34,7 @@ This project is inspired by and pays homage to [ruby-openai](https://github.com/
34
34
  - Token counting (`countTokens`) for prompts, chat history, and full requests with system instruction / tools / cached content
35
35
  - Speech generation (TTS) with 30 prebuilt voices, single-speaker and multi-speaker modes, and one-line WAV file output
36
36
  - Live API: real-time bidirectional conversations with text/audio/video and function calling (sync and async)
37
+ - Code Execution: let the model generate and run Python code, then inspect generated code and execution results
37
38
 
38
39
  ### Function Calling
39
40
 
@@ -110,11 +111,65 @@ puts "After deleting a function: #{all_tools.list_functions}"
110
111
  # => After deleting a function: [:get_current_weather, :send_email]
111
112
  ```
112
113
 
114
+ ### Code Execution
115
+
116
+ Pass `code_execution: true` to let Gemini generate and run Python code when it helps answer calculation or data-processing tasks.
117
+
118
+ ```ruby
119
+ require 'gemini'
120
+
121
+ client = Gemini::Client.new(ENV['GEMINI_API_KEY'])
122
+
123
+ response = client.generate_content(
124
+ "Calculate the sum of the first 50 prime numbers and show the code you used",
125
+ model: "gemini-3.5-flash",
126
+ code_execution: true
127
+ )
128
+
129
+ puts response.text
130
+
131
+ if response.code_execution?
132
+ puts response.executable_code
133
+ puts response.code_execution_outcome
134
+ puts response.code_execution_output
135
+ end
136
+ ```
137
+
138
+ You can also inspect all generated code and execution results:
139
+
140
+ ```ruby
141
+ response.executable_codes # => [{"language"=>"PYTHON", "code"=>"..."}]
142
+ response.code_execution_results # => [{"outcome"=>"OUTCOME_OK", "output"=>"..."}]
143
+ response.code_execution_success? # => true
144
+ ```
145
+
146
+ Code Execution also works with image inputs. For Gemini 3 models, combine it with `thinking_level` when you want the model to inspect an image with code.
147
+
148
+ ```ruby
149
+ response = client.generate_content(
150
+ [
151
+ { type: "text", text: "Read the small numbers in this image" },
152
+ { type: "image_file", image_file: { file_path: "meter.jpg" } }
153
+ ],
154
+ model: "gemini-3.5-flash",
155
+ code_execution: true,
156
+ thinking_level: :medium
157
+ )
158
+ ```
159
+
160
+ A complete example is available in `demo/code_execution_demo.rb`.
161
+
113
162
  ### Thinking Feature
114
163
 
115
164
  Gemini 2.5 and later models support the Thinking feature, which enables the model to perform internal reasoning processes for complex problems to generate higher-quality answers.
116
165
 
117
- #### Using with Gemini 2.5: `thinking_budget`
166
+ #### Deprecation notice: thinking and sampling controls
167
+
168
+ For Gemini 3 and later models, prefer `thinking_level` (`:minimal`, `:low`, `:medium`, `:high`) instead of `thinking_budget`. The `thinking_budget` option remains available for Gemini 2.5 compatibility, but it should be treated as a legacy control when targeting newer models.
169
+
170
+ Sampling parameters such as `temperature`, `top_p`, and `top_k` are also considered legacy tuning knobs for newer Gemini models. Existing code can continue to pass them through for backward compatibility, but new integrations should rely on model defaults and Thinking controls first.
171
+
172
+ #### Legacy Gemini 2.5 usage: `thinking_budget`
118
173
 
119
174
  ```ruby
120
175
  require 'gemini'
@@ -145,7 +200,7 @@ response = client.generate_content(
145
200
  )
146
201
  ```
147
202
 
148
- #### Using with Gemini 3: `thinking_level`
203
+ #### Recommended Gemini 3 usage: `thinking_level`
149
204
 
150
205
  ```ruby
151
206
  # Specify thinking level (:minimal, :low, :medium, :high)
@@ -1675,6 +1730,7 @@ The gem includes several demo applications that showcase its functionality:
1675
1730
  - `demo/file_audio_demo.rb` - Audio transcription with large audio files
1676
1731
  - `demo/structured_output_demo.rb` - Structured JSON output with schema
1677
1732
  - `demo/enum_response_demo.rb` - Enum-constrained responses
1733
+ - `demo/code_execution_demo.rb` - Code Execution with generated Python code and execution output
1678
1734
  - `demo/thinking_demo.rb` - Thinking feature (Gemini 2.5)
1679
1735
  - `demo/thinking_gemini3_demo.rb` - Thinking feature (Gemini 3)
1680
1736
  - `demo/document_chat_demo.rb` - Document processing
@@ -1724,6 +1780,12 @@ ruby demo/structured_output_demo.rb
1724
1780
  # Enum-constrained responses
1725
1781
  ruby demo/enum_response_demo.rb
1726
1782
 
1783
+ # Code Execution
1784
+ ruby demo/code_execution_demo.rb
1785
+
1786
+ # Code Execution with a different model
1787
+ GEMINI_MODEL=gemini-3.5-pro ruby demo/code_execution_demo.rb
1788
+
1727
1789
  # Thinking feature (Gemini 2.5)
1728
1790
  ruby demo/thinking_demo.rb
1729
1791
 
@@ -1745,11 +1807,16 @@ ruby demo/embeddings_demo.rb
1745
1807
 
1746
1808
  ## Models
1747
1809
 
1748
- The library supports various Gemini models:
1810
+ Model names can be passed as strings. Common examples:
1749
1811
 
1812
+ - `gemini-3.5-flash`
1813
+ - `gemini-3.5-pro`
1814
+ - `gemini-3-flash-preview`
1750
1815
  - `gemini-2.5-flash`
1751
1816
  - `gemini-2.5-pro`
1752
1817
 
1818
+ Use `client.models.list` to check models available to your API key.
1819
+
1753
1820
  ## Requirements
1754
1821
 
1755
1822
  - Ruby 3.0 or higher
@@ -1766,4 +1833,4 @@ The library supports various Gemini models:
1766
1833
 
1767
1834
  ## License
1768
1835
 
1769
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
1836
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/lib/gemini/client.rb CHANGED
@@ -202,6 +202,7 @@ module Gemini
202
202
  def generate_content(prompt, model: "gemini-2.5-flash", system_instruction: nil,
203
203
  response_mime_type: nil, response_schema: nil, temperature: 0.5, tools: nil,
204
204
  url_context: false, google_search: false,
205
+ code_execution: false,
205
206
  thinking_budget: nil, thinking_level: nil,
206
207
  **parameters, &stream_callback)
207
208
  content = format_content(prompt)
@@ -230,7 +231,12 @@ module Gemini
230
231
  end
231
232
 
232
233
  # Handle tool shortcuts
233
- tools = build_tools_array(tools, url_context: url_context, google_search: google_search)
234
+ tools = build_tools_array(
235
+ tools,
236
+ url_context: url_context,
237
+ google_search: google_search,
238
+ code_execution: code_execution
239
+ )
234
240
  params[:tools] = tools if tools && !tools.empty?
235
241
 
236
242
  params.merge!(parameters)
@@ -245,7 +251,8 @@ module Gemini
245
251
  # Streaming text generation
246
252
  def generate_content_stream(prompt, model: "gemini-2.5-flash", system_instruction: nil,
247
253
  response_mime_type: nil, response_schema: nil, temperature: 0.5,
248
- url_context: false, google_search: false, **parameters, &block)
254
+ url_context: false, google_search: false, code_execution: false,
255
+ **parameters, &block)
249
256
  raise ArgumentError, "Block is required for streaming" unless block_given?
250
257
 
251
258
  content = format_content(prompt)
@@ -270,7 +277,12 @@ module Gemini
270
277
  params[:generation_config]["temperature"] = temperature
271
278
 
272
279
  # Handle tool shortcuts
273
- tools = build_tools_array(nil, url_context: url_context, google_search: google_search)
280
+ tools = build_tools_array(
281
+ nil,
282
+ url_context: url_context,
283
+ google_search: google_search,
284
+ code_execution: code_execution
285
+ )
274
286
  params[:tools] = tools if tools && !tools.empty?
275
287
 
276
288
  # Merge other parameters
@@ -535,7 +547,7 @@ module Gemini
535
547
  end
536
548
 
537
549
  # Build tools array from explicit tools parameter and shortcuts
538
- def build_tools_array(tools, url_context: false, google_search: false)
550
+ def build_tools_array(tools, url_context: false, google_search: false, code_execution: false)
539
551
  result_tools = []
540
552
 
541
553
  # Add existing tools if provided
@@ -551,6 +563,9 @@ module Gemini
551
563
  # Add google_search tool if requested
552
564
  result_tools << { google_search: {} } if google_search
553
565
 
566
+ # Add code_execution tool if requested
567
+ result_tools << { code_execution: {} } if code_execution
568
+
554
569
  # Remove duplicates based on tool keys and return
555
570
  return nil if result_tools.empty?
556
571
  result_tools.uniq { |tool| tool.keys.first }
@@ -685,4 +700,4 @@ module Gemini
685
700
  end
686
701
  end
687
702
  end
688
- end
703
+ end
@@ -37,6 +37,54 @@ module Gemini
37
37
 
38
38
  parts.select { |part| part.key?("text") }.map { |part| part["text"] }
39
39
  end
40
+
41
+ # Get all executableCode parts returned by the Code Execution tool.
42
+ def executable_codes
43
+ return [] unless valid?
44
+
45
+ parts.map { |part| part["executableCode"] || part["executable_code"] }.compact
46
+ end
47
+
48
+ # Get the first generated code string from a Code Execution response.
49
+ def executable_code
50
+ code_part = executable_codes.first
51
+ return nil unless code_part
52
+
53
+ code_part["code"] || code_part[:code]
54
+ end
55
+
56
+ # Get all codeExecutionResult parts returned by the Code Execution tool.
57
+ def code_execution_results
58
+ return [] unless valid?
59
+
60
+ parts.map { |part| part["codeExecutionResult"] || part["code_execution_result"] }.compact
61
+ end
62
+
63
+ # Get the first execution output string from a Code Execution response.
64
+ def code_execution_output
65
+ result_part = code_execution_results.first
66
+ return nil unless result_part
67
+
68
+ result_part["output"] || result_part[:output]
69
+ end
70
+
71
+ # Get the first execution outcome (for example "OUTCOME_OK").
72
+ def code_execution_outcome
73
+ result_part = code_execution_results.first
74
+ return nil unless result_part
75
+
76
+ result_part["outcome"] || result_part[:outcome]
77
+ end
78
+
79
+ # True when the first Code Execution result completed successfully.
80
+ def code_execution_success?
81
+ code_execution_outcome == "OUTCOME_OK"
82
+ end
83
+
84
+ # True if the response contains generated code or execution results.
85
+ def code_execution?
86
+ !executable_codes.empty? || !code_execution_results.empty?
87
+ end
40
88
 
41
89
  # Get image parts (if any)
42
90
  def image_parts
@@ -650,4 +698,4 @@ module Gemini
650
698
  end
651
699
  end
652
700
  end
653
- end
701
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gemini
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-gemini-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rira100000000
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-06-11 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: faraday
@@ -194,6 +195,7 @@ metadata:
194
195
  source_code_uri: https://github.com/rira100000000/ruby-gemini-api
195
196
  changelog_uri: https://github.com/rira100000000/ruby-gemini-api/blob/main/CHANGELOG.md
196
197
  rubygems_mfa_required: 'true'
198
+ post_install_message:
197
199
  rdoc_options: []
198
200
  require_paths:
199
201
  - lib
@@ -208,7 +210,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
210
  - !ruby/object:Gem::Version
209
211
  version: '0'
210
212
  requirements: []
211
- rubygems_version: 3.6.9
213
+ rubygems_version: 3.3.26
214
+ signing_key:
212
215
  specification_version: 4
213
216
  summary: Ruby client for Google's Gemini API
214
217
  test_files: []