ai-chat 0.0.6 → 0.0.7

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: f4875edb9f6b70da87fbdabfc11fa25be2e76d51496a0ba369e2cf360511abd5
4
- data.tar.gz: a062324e299eea25b68696d1d292f2f0b9fe217b3adaa7068020b6db7d198e53
3
+ metadata.gz: 80aebb03e5962c921d6f5e47ee1521b760ffabe223869141eaa0b1d6b53514c0
4
+ data.tar.gz: 53fb9565b1e41a7bf5b93bd85cabe09af0be5028a163612bc440298aef4a01df
5
5
  SHA512:
6
- metadata.gz: fd196bf575fdb10389c93d52e29596bfe68c5a48c49e81b2f5efe377ab91c55b4a2533bb0d09912d06c2400bee688f98f76605161dca9fcf4cab34ebad3067e5
7
- data.tar.gz: d973e4d78ef6fe30333f494d60cd590d523727bf1a175c6fb6ce1832c26dd03dd52bbff8681ad15aec4a19afda2b5616ac9fdda21499ec86e635a106381af9d1
6
+ metadata.gz: 1216d345bb460a00a9baf6555fc60d1337ee2ac73590fb6ec8d5a0af839a7eca664dfc83f94f5b7f1898217ad67d8ecd314c911874d4affbbcc3d5f1d8ab3f75
7
+ data.tar.gz: a8bcf3c0f3edadfc6ba9398220214fd9c90c0bfa2ec9a4ad5c3f54c957b0a30a5c5d6df4beb36cfd8df86e2defd4117acd827c52387710e9246e6e8649e1ccfa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.7] - 2025-04-25
4
+
5
+ - Added support for reasoning effort parameter (`reasoning_effort`) with the OpenAI Responses API
6
+ - Support for reasoning models like o3, o4-mini
7
+ - Updated documentation with examples
8
+
9
+ ## [0.0.6] - 2025-04-25
10
+
11
+ - Fixed minor bugs
12
+ - Improved error handling
13
+
3
14
  ## [0.0.5] - 2025-04-25
4
15
 
5
16
  - Updated to use OpenAI's Responses API instead of Chat Completions API
data/README.md CHANGED
@@ -154,12 +154,45 @@ Useful if you are reconstructing a chat that has already happened.
154
154
  - You can call `.messages` to get an array containing the conversation so far.
155
155
  - TODO: Setting `.messages` will replace the conversation with the provided array.
156
156
 
157
+ ## Testing with Real API Calls
158
+
159
+ While this gem includes specs, they use mocked API responses. To test with real API calls:
160
+
161
+ 1. Navigate to the test program directory: `cd test_program`
162
+ 2. Create a `.env` file in the test_program directory with your API credentials:
163
+ ```
164
+ # Your OpenAI API key
165
+ OPENAI_API_KEY=your_openai_api_key_here
166
+ ```
167
+ 3. Install dependencies: `bundle install`
168
+ 4. Run the test program: `ruby test_ai_chat.rb`
169
+
170
+ This test program runs through all the major features of the gem, making real API calls to OpenAI.
171
+
172
+ ## Reasoning Effort
173
+
174
+ When using reasoning models like `o3` or `o4-mini`, you can specify a reasoning effort level to control how much reasoning the model does before producing its final response:
175
+
176
+ ```ruby
177
+ x = AI::Chat.new
178
+ x.model = "o4-mini"
179
+ x.reasoning_effort = "medium" # Can be "low", "medium", or "high"
180
+
181
+ x.user("Write a bash script that transposes a matrix represented as '[1,2],[3,4],[5,6]'")
182
+ x.assistant!
183
+ ```
184
+
185
+ The `reasoning_effort` parameter guides the model on how many reasoning tokens to generate before creating a response to the prompt. Options are:
186
+ - `"low"`: Favors speed and economical token usage
187
+ - `"medium"`: (Default) Balances speed and reasoning accuracy
188
+ - `"high"`: Favors more complete reasoning
189
+
190
+ Setting to `nil` disables the reasoning parameter.
191
+
157
192
  ## TODOs
158
193
 
159
- - Add a `reasoning_effort` parameter.
160
194
  - Add the ability to set all messages at once, ideally with an ActiveRecord Relation.
161
195
  - Add a way to access the whole API response body (rather than just the message content).
162
- - Add specs.
163
196
 
164
197
  ## Contributing
165
198
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AI
4
4
  class Chat
5
- VERSION = "0.0.6"
5
+ VERSION = "0.0.7"
6
6
  end
7
7
  end
data/lib/ai/chat.rb CHANGED
@@ -5,11 +5,31 @@
5
5
  module AI
6
6
  class Chat
7
7
  attr_accessor :messages, :schema, :model
8
+ attr_reader :reasoning_effort
9
+
10
+ VALID_REASONING_EFFORTS = [:low, :medium, :high].freeze
8
11
 
9
12
  def initialize(api_key: nil)
10
13
  @api_key = api_key || ENV.fetch("OPENAI_API_KEY")
11
14
  @messages = []
12
15
  @model = "gpt-4.1-mini"
16
+ @reasoning_effort = nil
17
+ end
18
+
19
+ def reasoning_effort=(value)
20
+ if value.nil?
21
+ @reasoning_effort = nil
22
+ else
23
+ # Convert string to symbol if needed
24
+ symbol_value = value.is_a?(String) ? value.to_sym : value
25
+
26
+ if VALID_REASONING_EFFORTS.include?(symbol_value)
27
+ @reasoning_effort = symbol_value
28
+ else
29
+ valid_values = VALID_REASONING_EFFORTS.map { |v| ":#{v} or \"#{v}\"" }.join(", ")
30
+ raise ArgumentError, "Invalid reasoning_effort value: '#{value}'. Must be one of: #{valid_values}"
31
+ end
32
+ end
13
33
  end
14
34
 
15
35
  def system(content)
@@ -99,6 +119,14 @@ module AI
99
119
  "input" => messages
100
120
  }
101
121
 
122
+ # Add reasoning parameter if specified
123
+ if !@reasoning_effort.nil?
124
+ # Convert symbol back to string for the API request
125
+ request_body_hash["reasoning"] = {
126
+ "effort" => @reasoning_effort.to_s
127
+ }
128
+ end
129
+
102
130
  # Handle structured output (JSON schema)
103
131
  if !schema.nil?
104
132
  # Parse the schema and use it with Structured Output (json_schema)
@@ -172,7 +200,7 @@ module AI
172
200
  end
173
201
 
174
202
  def inspect
175
- "#<#{self.class.name} @messages=#{messages.inspect} @model=#{@model.inspect} @schema=#{@schema.inspect}>"
203
+ "#<#{self.class.name} @messages=#{messages.inspect} @model=#{@model.inspect} @schema=#{@schema.inspect} @reasoning_effort=#{@reasoning_effort.inspect}>"
176
204
  end
177
205
 
178
206
  private
@@ -112,4 +112,46 @@ a.user("Tell me a joke.")
112
112
  response = a.assistant!
113
113
  puts "Assistant response after manual message: #{response}"
114
114
 
115
+ # Reasoning Effort Test
116
+ puts "\nReasoning Effort Test:"
117
+ puts "---------------------"
118
+ begin
119
+ r = AI::Chat.new
120
+ r.model = "o4-mini" # Use a reasoning model
121
+ r.reasoning_effort = "medium"
122
+ r.user("Write a short bash script that counts the number of unique words in a text file.")
123
+ response = r.assistant!
124
+ puts "Response with reasoning effort 'medium': #{response}"
125
+ rescue => e
126
+ puts "Reasoning effort test error: #{e.message}"
127
+ end
128
+
129
+ # Reasoning Effort Validation Test
130
+ puts "\nReasoning Effort Validation Test:"
131
+ puts "-------------------------------"
132
+ begin
133
+ r = AI::Chat.new
134
+ puts "Setting valid reasoning effort string 'low'..."
135
+ r.reasoning_effort = "low"
136
+ puts "Success: reasoning_effort = #{r.reasoning_effort}"
137
+
138
+ puts "Setting valid reasoning effort symbol :medium..."
139
+ r.reasoning_effort = :medium
140
+ puts "Success: reasoning_effort = #{r.reasoning_effort}"
141
+
142
+ puts "Setting valid reasoning effort string 'high'..."
143
+ r.reasoning_effort = "high"
144
+ puts "Success: reasoning_effort = #{r.reasoning_effort}"
145
+
146
+ puts "Setting nil reasoning effort..."
147
+ r.reasoning_effort = nil
148
+ puts "Success: reasoning_effort = #{r.reasoning_effort}"
149
+
150
+ puts "Setting invalid reasoning effort 'extreme'..."
151
+ r.reasoning_effort = "extreme"
152
+ puts "This line should not be reached"
153
+ rescue ArgumentError => e
154
+ puts "Expected error caught: #{e.message}"
155
+ end
156
+
115
157
  puts "\nTests completed!"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ai-chat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raghu Betina
@@ -141,7 +141,6 @@ files:
141
141
  - LICENSE.txt
142
142
  - README.md
143
143
  - Rakefile
144
- - ai_chat.gemspec
145
144
  - lib/ai-chat.rb
146
145
  - lib/ai/chat.rb
147
146
  - lib/ai/chat/version.rb
data/ai_chat.gemspec DELETED
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/ai/chat/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "ai-chat"
7
- spec.version = AI::Chat::VERSION
8
- spec.authors = ["Raghu Betina", "Jelani Woods"]
9
- spec.email = ["raghu@firstdraft.com", "jelani@firstdraft.com"]
10
-
11
- spec.summary = "This gem provides a class called `AI::Chat` that is intended to make it as easy as possible to use OpenAI's Responses API."
12
- spec.description = "This gem provides a class called `AI::Chat` that is intended to make it as easy as possible to use OpenAI's Responses API. Supports Structured Output and Image Processing."
13
- spec.homepage = "https://github.com/firstdraft/ai-chat"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.0.0"
16
-
17
- # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
-
19
- spec.metadata["homepage_uri"] = spec.homepage
20
- spec.metadata["source_code_uri"] = "https://github.com/firstdraft/ai-chat"
21
- spec.metadata["changelog_uri"] = "https://github.com/firstdraft/ai-chat/blob/main/CHANGELOG.md"
22
-
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
- `git ls-files -z`.split("\x0").reject do |f|
27
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(git|travis|circleci)|appveyor)})
28
- end
29
- end
30
- spec.bindir = "exe"
31
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
- spec.require_paths = ["lib"]
33
-
34
- # Register dependencies of the gem
35
- spec.add_runtime_dependency "mime-types", "~> 3.0"
36
- spec.add_runtime_dependency "base64" # Works for all Ruby versions
37
-
38
- # Development dependencies
39
- spec.add_development_dependency "rake", "~> 13.0"
40
- spec.add_development_dependency "rspec", "~> 3.12"
41
- spec.add_development_dependency "factory_bot", "~> 6.2"
42
- spec.add_development_dependency "webmock", "~> 3.18"
43
- spec.add_development_dependency "vcr", "~> 6.1"
44
- spec.add_development_dependency "standard", "~> 1.32"
45
-
46
- # For more information and examples about making a new gem, check out our
47
- # guide at: https://bundler.io/guides/creating_gem.html
48
- end