raix 0.4.8 → 0.6

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: 205dfe2efa97dd596884ca2063e33e0c76da34ae052f98e18e8c75c423752b3a
4
- data.tar.gz: 24bfe7d9b6d20a701d70a96366937bf96c4999ea26469c8cc645e4ae874ce5c8
3
+ metadata.gz: 4bb905086f308c10375b54337b9cb4effe9387ed7e7a6a0dd84875176984e29c
4
+ data.tar.gz: dbc3b0d67aa91d8dc9b8ba9504b84d52617529c2a8e69fd0d21f3ad4e59df31d
5
5
  SHA512:
6
- metadata.gz: ea57058bb1e8614decd24d295a641b4e2e6d90ac2d5b2d744b3531561f13304e4e8e41a679c9e0f80b16fdcf0477c8c61262ed9b4fbb451d507db24469540037
7
- data.tar.gz: f6c255abef3c7d2e7440075d4114f564050ffcf95e431dc5301ea6a516cd89f1baf3d96346e86614192d85330e4f234673b89eb9d19930043f0882c8ee2451eb
6
+ metadata.gz: cbbaebe7bd8d18d2cd82b41b7a4bcf468eda1483485b2a707ff980d51068dea1e9ef5e20510dc7dd46bf1982fc7db14054399919842a28930cb12e37fa016022
7
+ data.tar.gz: 61037ede25456a15053e96dc1bae11125a9d3e0d5dc08e255087c9b69a2c4d096fc2e95d27f600a955bd93b421d8ed703b7c7b0df8de35812b82dbf9f0818858
data/.rubocop.yml CHANGED
@@ -30,3 +30,6 @@ Metrics/CyclomaticComplexity:
30
30
 
31
31
  Metrics/PerceivedComplexity:
32
32
  Enabled: false
33
+
34
+ Metrics/ParameterLists:
35
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2024-11-12
4
+ - adds `save_response` option to `chat_completion` to control transcript updates
5
+ - fixes potential race conditions in transcript handling
6
+
3
7
  ## [0.1.0] - 2024-04-03
4
8
 
5
9
  - Initial release, placeholder gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- raix (0.4.8)
4
+ raix (0.6)
5
5
  activesupport (>= 6.0)
6
6
  open_router (~> 0.2)
7
7
  ruby-openai (~> 7.0)
data/README.md CHANGED
@@ -101,6 +101,8 @@ RSpec.describe WhatIsTheWeather do
101
101
  end
102
102
  ```
103
103
 
104
+ Note that for security reasons, dispatching functions only works with functions implemented using `Raix::FunctionDispatch#function` or directly on the class.
105
+
104
106
  #### Multiple Tool Calls
105
107
 
106
108
  Some AI models (like GPT-4) can make multiple tool calls in a single response. When this happens, Raix will automatically handle all the function calls sequentially and return an array of their results. Here's an example:
@@ -44,7 +44,7 @@ module Raix
44
44
  # @option params [Boolean] :openai (false) Whether to use OpenAI's API instead of OpenRouter's.
45
45
  # @option params [Boolean] :raw (false) Whether to return the raw response or dig the text content.
46
46
  # @return [String|Hash] The completed chat response.
47
- def chat_completion(params: {}, loop: false, json: false, raw: false, openai: false)
47
+ def chat_completion(params: {}, loop: false, json: false, raw: false, openai: false, save_response: true)
48
48
  # set params to default values if not provided
49
49
  params[:cache_at] ||= cache_at.presence
50
50
  params[:frequency_penalty] ||= frequency_penalty.presence
@@ -84,7 +84,10 @@ module Raix
84
84
  self.model ||= Raix.configuration.model
85
85
 
86
86
  adapter = MessageAdapters::Base.new(self)
87
- messages = transcript.flatten.compact.map { |msg| adapter.transform(msg) }
87
+
88
+ # duplicate the transcript to avoid race conditions in situations where
89
+ # chat_completion is called multiple times in parallel
90
+ messages = transcript.flatten.compact.map { |msg| adapter.transform(msg) }.dup
88
91
  raise "Can't complete an empty transcript" if messages.blank?
89
92
 
90
93
  begin
@@ -110,12 +113,18 @@ module Raix
110
113
  return tool_calls.map do |tool_call|
111
114
  # dispatch the called function
112
115
  arguments = JSON.parse(tool_call["function"]["arguments"].presence || "{}")
113
- send(tool_call["function"]["name"], arguments.with_indifferent_access)
116
+ function_name = tool_call["function"]["name"]
117
+ raise "Unauthorized function call: #{function_name}" unless self.class.functions.map { |f| f[:name].to_sym }.include?(function_name.to_sym)
118
+
119
+ send(function_name, arguments.with_indifferent_access)
114
120
  end
115
121
  end
116
122
 
117
123
  response.tap do |res|
118
124
  content = res.dig("choices", 0, "message", "content")
125
+
126
+ transcript << { assistant: content } if save_response
127
+
119
128
  if json
120
129
  content = content.squish
121
130
  return JSON.parse(content)
@@ -174,7 +183,7 @@ module Raix
174
183
  params[:stream] ||= stream.presence
175
184
  params[:stream_options] = { include_usage: true } if params[:stream]
176
185
 
177
- params.delete(:temperature) if model == "o1-preview"
186
+ params.delete(:temperature) if model.start_with?("o")
178
187
 
179
188
  Raix.configuration.openai_client.chat(parameters: params.compact.merge(model:, messages:))
180
189
  end
data/lib/raix/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raix
4
- VERSION = "0.4.8"
4
+ VERSION = "0.6"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Obie Fernandez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-06 00:00:00.000000000 Z
11
+ date: 2025-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  requirements: []
105
- rubygems_version: 3.4.10
105
+ rubygems_version: 3.5.21
106
106
  signing_key:
107
107
  specification_version: 4
108
108
  summary: Ruby AI eXtensions