omniai-openai 0.2.0 → 1.0.1

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: 046a2d4be43b4a9537a18b90fc69a9a7bfb191d76471d5a9374cc731c5e8b8a3
4
- data.tar.gz: e1f2914a05ae5a527c09126d015df285e6efaa86d37fca2ac16ec694799f186f
3
+ metadata.gz: 17b76524bf985fda37fec8e7cea18aece3380a1831be7de6abe2652767aafc92
4
+ data.tar.gz: e32a791f07f2697f56f2dfa15f11e8b05abf4416610925880d12cc7b5d0dda90
5
5
  SHA512:
6
- metadata.gz: cace4852fc0a5ce7b59cb0a74728324396384a3c7793611bc48c61081bb910ec2cfc3dd09e0b3d4bb14fe16767913663cc2621b964ac0e87f93dcb1fab10873c
7
- data.tar.gz: 16fbad4c8b63260e069f07314811ad8cbbbb4bdbbcd2b412b63902372abf7271d9ccc87bbdc06cf529530f633408d80ab3d9f05d0032d1fc7a85d82ecd7f8d2c
6
+ metadata.gz: 9aa657f83ece505e056597a36c73a77f24abc45af4094c5e982b949bc9631ba6a401ff410220855c43073232578bda7fe37ed7003e006259caaf8d1333825dab
7
+ data.tar.gz: a96fe7cb53c737220b21c43013af12fab828476336827c446bfb12e64b02340ef55cac0a762facd0d5103db8afad078bf72b94fe760bbda2d36437eeee68468b
data/Gemfile CHANGED
@@ -11,5 +11,4 @@ gem 'rspec_junit_formatter'
11
11
  gem 'rubocop'
12
12
  gem 'rubocop-rake'
13
13
  gem 'rubocop-rspec'
14
- gem 'vcr'
15
14
  gem 'webmock'
data/README.md CHANGED
@@ -75,6 +75,8 @@ completion = client.chat.completion('How fast is a cheetah?', model: OmniAI::Ope
75
75
  completion.choice.message.content # 'A cheetah can reach speeds over 100 km/h.'
76
76
  ```
77
77
 
78
+ [OpenAI API Reference `model`](https://platform.openai.com/docs/api-reference/chat/create#chat-create-model)
79
+
78
80
  #### Temperature
79
81
 
80
82
  `temperature` takes an optional float between `0.0` and `2.0` (defaults is `0.7`):
@@ -84,6 +86,8 @@ completion = client.chat.completion('Pick a number between 1 and 5', temperature
84
86
  completion.choice.message.content # '3'
85
87
  ```
86
88
 
89
+ [OpenAI API Reference `temperature`](https://platform.openai.com/docs/api-reference/chat/create#chat-create-temperature)
90
+
87
91
  #### Stream
88
92
 
89
93
  `stream` takes an optional a proc to stream responses in real-time chunks instead of waiting for a complete response:
@@ -95,11 +99,20 @@ end
95
99
  client.chat.completion('Be poetic.', stream:)
96
100
  ```
97
101
 
102
+ [OpenAI API Reference `stream`](https://platform.openai.com/docs/api-reference/chat/create#chat-create-stream)
103
+
98
104
  #### Format
99
105
 
100
- `format` takes an optional symbol (i.e. `:json`) and switches the client to parsing message content as `json`:
106
+ `format` takes an optional symbol (`:json`) and that setes the `response_format` to `json_object`:
101
107
 
102
108
  ```ruby
103
- completion = client.chat.completion('Please provide a color name / hex / hsl as JSON.', format: :json)
104
- completion.choice.message.content # { "name": "Black", "hex": "#000", "hsl": { "h": 0, "s": 0, "l": 0 } }
109
+ completion = client.chat.completion([
110
+ { role: OmniAI::Chat::Role::SYSTEM, content: OmniAI::Chat::JSON_PROMPT },
111
+ { role: OmniAI::Chat::Role::USER, content: 'What is the name of the drummer for the Beatles?' }
112
+ ], format: :json)
113
+ JSON.parse(completion.choice.message.content) # { "name": "Ringo" }
105
114
  ```
115
+
116
+ [OpenAI API Reference `response_format`](https://platform.openai.com/docs/api-reference/chat/create#chat-create-stream)
117
+
118
+ > When using JSON mode, you must also instruct the model to produce JSON yourself via a system or user message.
@@ -3,15 +3,9 @@
3
3
  module OmniAI
4
4
  module OpenAI
5
5
  # An OpenAI chat implementation.
6
- #
7
- # Usage:
8
- #
9
- # chat = OmniAI::OpenAI::Chat.new(client: client)
10
- # chat.completion('Tell me a joke.')
11
- # chat.completion(['Tell me a joke.'])
12
- # chat.completion({ role: 'user', content: 'Tell me a joke.' })
13
- # chat.completion([{ role: 'system', content: 'Tell me a joke.' }])
14
6
  class Chat < OmniAI::Chat
7
+ JSON_RESPONSE_FORMAT = { type: 'json_object' }.freeze
8
+
15
9
  module Model
16
10
  GPT_4O = 'gpt-4o'
17
11
  GPT_4 = 'gpt-4'
@@ -19,24 +13,22 @@ module OmniAI
19
13
  GPT_3_5_TURBO = 'gpt-3.5-turbo'
20
14
  end
21
15
 
22
- module Role
23
- ASSISTANT = 'assistant'
24
- USER = 'user'
25
- SYSTEM = 'system'
16
+ protected
17
+
18
+ # @return [Hash]
19
+ def payload
20
+ OmniAI::OpenAI.config.chat_options.merge({
21
+ messages:,
22
+ model: @model,
23
+ stream: @stream.nil? ? nil : !@stream.nil?,
24
+ temperature: @temperature,
25
+ response_format: (JSON_RESPONSE_FORMAT if @format.eql?(:json)),
26
+ }).compact
26
27
  end
27
28
 
28
- # @raise [OmniAI::Error]
29
- #
30
- # @param prompt [String]
31
- # @param model [String] optional
32
- # @param format [Symbol] optional :text or :json
33
- # @param temperature [Float, nil] optional
34
- # @param stream [Proc, nil] optional
35
- #
36
- # @return [OmniAI::OpenAi::Chat::Response]
37
- def completion(messages, model: Model::GPT_4O, temperature: nil, format: nil, stream: nil)
38
- request = Request.new(client: @client, messages:, model:, temperature:, format:, stream:)
39
- request.process!
29
+ # @return [String]
30
+ def path
31
+ "/#{OmniAI::OpenAI::Client::VERSION}/chat/completions"
40
32
  end
41
33
  end
42
34
  end
@@ -52,9 +52,17 @@ module OmniAI
52
52
  end
53
53
  end
54
54
 
55
- # @return [OmniAI::OpenAI::Chat]
56
- def chat
57
- Chat.new(client: self)
55
+ # @raise [OmniAI::Error]
56
+ #
57
+ # @param messages [String, Array, Hash]
58
+ # @param model [String] optional
59
+ # @param format [Symbol] optional :text or :json
60
+ # @param temperature [Float, nil] optional
61
+ # @param stream [Proc, nil] optional
62
+ #
63
+ # @return [OmniAI::Chat::Completion]
64
+ def chat(messages, model: Chat::Model::GPT_4O, temperature: nil, format: nil, stream: nil)
65
+ Chat.process!(messages, model:, temperature:, format:, stream:, client: self)
58
66
  end
59
67
  end
60
68
  end
@@ -4,7 +4,7 @@ module OmniAI
4
4
  module OpenAI
5
5
  # Configuration for managing the OpenAI `api_key` / `organization` / `project` / `logger`.
6
6
  class Config < OmniAI::Config
7
- attr_accessor :organization, :project
7
+ attr_accessor :organization, :project, :chat_options
8
8
 
9
9
  def initialize
10
10
  super
@@ -12,6 +12,7 @@ module OmniAI
12
12
  @organization = ENV.fetch('OPENAI_ORGANIZATION', nil)
13
13
  @project = ENV.fetch('OPENAI_PROJECT', nil)
14
14
  @host = ENV.fetch('OPENAI_HOST', 'https://api.openai.com')
15
+ @chat_options = {}
15
16
  end
16
17
  end
17
18
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAI
4
4
  module OpenAI
5
- VERSION = '0.2.0'
5
+ VERSION = '1.0.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniai-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
@@ -63,7 +63,6 @@ files:
63
63
  - README.md
64
64
  - lib/omniai/openai.rb
65
65
  - lib/omniai/openai/chat.rb
66
- - lib/omniai/openai/chat/request.rb
67
66
  - lib/omniai/openai/client.rb
68
67
  - lib/omniai/openai/config.rb
69
68
  - lib/omniai/openai/version.rb
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OmniAI
4
- module OpenAI
5
- class Chat
6
- # An implementation of OmniAI::Chat::Request for OpenAI.
7
- class Request < OmniAI::Chat::Request
8
- protected
9
-
10
- # @return [Hash]
11
- def payload
12
- { messages: }.tap do |payload|
13
- payload[:model] = @model
14
- payload[:stream] = !@stream.nil? unless @stream.nil?
15
- payload[:temperature] = @temperature if @temperature
16
- payload[:response_format] = { type: 'json_object' } if @format.eql?(:json)
17
- end
18
- end
19
-
20
- # @return [Array<Hash>]
21
- def messages
22
- arrayify(@messages).map do |content|
23
- case content
24
- when String then { role: OmniAI::OpenAI::Chat::Role::USER, content: }
25
- when Hash then content
26
- else raise Error, "Unsupported content=#{content.inspect}"
27
- end
28
- end
29
- end
30
-
31
- # @return [String]
32
- def path
33
- "/#{OmniAI::OpenAI::Client::VERSION}/chat/completions"
34
- end
35
-
36
- private
37
-
38
- # @param value [Object, Array<Object>]
39
- # @return [Array<Object>]
40
- def arrayify(value)
41
- value.is_a?(Array) ? value : [value]
42
- end
43
- end
44
- end
45
- end
46
- end