Skip to content

Commit b78fa7c

Browse files
Merge pull request #159 from openai/release-please--branches--main--changes--next
release: 0.9.0
2 parents 68ee27e + 62542c4 commit b78fa7c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+833
-283
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
- 'integrated/**'
88
- 'stl-preview-head/**'
99
- 'stl-preview-base/**'
10+
pull_request:
11+
branches-ignore:
12+
- 'stl-preview-head/**'
13+
- 'stl-preview-base/**'
1014

1115
jobs:
1216
lint:

.github/workflows/publish-gem.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Workflow for re-publishing to rubygems.org in case it failed for some reason.
2-
# You can run this workflow by navigating to https://www.github.com/openai/openai-python/actions/workflows/publish-gem.yml
2+
# You can run this workflow by navigating to https://www.github.com/openai/openai-ruby/actions/workflows/publish-gem.yml
33
name: Publish Gem
44
on:
55
workflow_dispatch:

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.8.0"
2+
".": "0.9.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 109
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-3ae9c18dd7ccfc3ac5206f24394665f563a19015cfa8847b2801a2694d012abc.yml
3-
openapi_spec_hash: 48175b03b58805cd5c80793c66fd54e5
4-
config_hash: 4caff63b74a41f71006987db702f2918
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-9e41d2d5471d2c28bff0d616f4476f5b0e6c541ef4cb51bdaaef5fdf5e13c8b2.yml
3+
openapi_spec_hash: 86f765e18d00e32cf2ce9db7ab84d946
4+
config_hash: dc5515e257676a27cb1ace1784aa92b3

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## 0.9.0 (2025-06-17)
4+
5+
Full Changelog: [v0.8.0...v0.9.0](https://github.com/openai/openai-ruby/compare/v0.8.0...v0.9.0)
6+
7+
### Features
8+
9+
* **api:** add reusable prompt IDs ([72e35ad](https://github.com/openai/openai-ruby/commit/72e35ad4a677a70a98db291a20aa212e53c367ea))
10+
* **api:** manual updates ([a4bcab7](https://github.com/openai/openai-ruby/commit/a4bcab736d59404c61b148a468d3bf0bc570fa39))
11+
12+
13+
### Chores
14+
15+
* **ci:** enable for pull requests ([e8dfcf9](https://github.com/openai/openai-ruby/commit/e8dfcf97f3af426d3ad83472fa6eaac718acbd4d))
16+
* **ci:** link to correct github repo ([7b34316](https://github.com/openai/openai-ruby/commit/7b3431612ea66d123bc114ec55bdf07f6081439e))
17+
18+
19+
### Documentation
20+
21+
* structured outputs in README ([#723](https://github.com/openai/openai-ruby/issues/723)) ([7212e61](https://github.com/openai/openai-ruby/commit/7212e61ee2fb9ebff0576b0bff4424f43ae54af2))
22+
* use image edit example in readme ([#722](https://github.com/openai/openai-ruby/issues/722)) ([eaa5055](https://github.com/openai/openai-ruby/commit/eaa5055eebca620c261c749ae4945845532c012d))
23+
324
## 0.8.0 (2025-06-10)
425

526
Full Changelog: [v0.7.0...v0.8.0](https://github.com/openai/openai-ruby/compare/v0.7.0...v0.8.0)

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ GIT
1111
PATH
1212
remote: .
1313
specs:
14-
openai (0.8.0)
14+
openai (0.9.0)
1515
connection_pool
1616

1717
GEM

README.md

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
1515
<!-- x-release-please-start-version -->
1616

1717
```ruby
18-
gem "openai", "~> 0.8.0"
18+
gem "openai", "~> 0.9.0"
1919
```
2020

2121
<!-- x-release-please-end -->
@@ -96,15 +96,126 @@ file_object = openai.files.create(file: Pathname("input.jsonl"), purpose: "fine-
9696
# Alternatively, pass file contents or a `StringIO` directly:
9797
file_object = openai.files.create(file: File.read("input.jsonl"), purpose: "fine-tune")
9898

99+
puts(file_object.id)
100+
99101
# Or, to control the filename and/or content type:
100-
file = OpenAI::FilePart.new(File.read("input.jsonl"), filename: "input.jsonl", content_type: "")
101-
file_object = openai.files.create(file: file, purpose: "fine-tune")
102+
image = OpenAI::FilePart.new(Pathname('dog.jpg'), content_type: 'image/jpeg')
103+
edited = openai.images.edit(
104+
prompt: "make this image look like a painting",
105+
model: "gpt-image-1",
106+
size: '1024x1024',
107+
image: image
108+
)
102109

103-
puts(file_object.id)
110+
puts(edited.data.first)
104111
```
105112

106113
Note that you can also pass a raw `IO` descriptor, but this disables retries, as the library can't be sure if the descriptor is a file or pipe (which cannot be rewound).
107114

115+
### [Structured outputs](https://platform.openai.com/docs/guides/structured-outputs) and function calling
116+
117+
This SDK ships with helpers in `OpenAI::BaseModel`, `OpenAI::ArrayOf`, `OpenAI::EnumOf`, and `OpenAI::UnionOf` to help you define the supported JSON schemas used in making structured outputs and function calling requests.
118+
119+
<details>
120+
<summary>Snippet</summary>
121+
122+
```ruby
123+
# Participant model with an optional last_name and an enum for status
124+
class Participant < OpenAI::BaseModel
125+
required :first_name, String
126+
required :last_name, String, nil?: true
127+
required :status, OpenAI::EnumOf[:confirmed, :unconfirmed, :tentative]
128+
end
129+
130+
# CalendarEvent model with a list of participants.
131+
class CalendarEvent < OpenAI::BaseModel
132+
required :name, String
133+
required :date, String
134+
required :participants, OpenAI::ArrayOf[Participant]
135+
end
136+
137+
138+
client = OpenAI::Client.new
139+
140+
response = client.responses.create(
141+
model: "gpt-4o-2024-08-06",
142+
input: [
143+
{role: :system, content: "Extract the event information."},
144+
{
145+
role: :user,
146+
content: <<~CONTENT
147+
Alice Shah and Lena are going to a science fair on Friday at 123 Main St. in San Diego.
148+
They have also invited Jasper Vellani and Talia Groves - Jasper has not responded and Talia said she is thinking about it.
149+
CONTENT
150+
}
151+
],
152+
text: CalendarEvent
153+
)
154+
155+
response
156+
.output
157+
.flat_map { _1.content }
158+
# filter out refusal responses
159+
.grep_v(OpenAI::Models::Responses::ResponseOutputRefusal)
160+
.each do |content|
161+
# parsed is an instance of `CalendarEvent`
162+
pp(content.parsed)
163+
end
164+
```
165+
166+
</details>
167+
168+
See the [examples](https://github.com/openai/openai-ruby/tree/main/examples) directory for more usage examples for helper usage.
169+
170+
To make the equivalent request using raw JSON schema format, you would do the following:
171+
172+
<details>
173+
<summary>Snippet</summary>
174+
175+
```ruby
176+
response = client.responses.create(
177+
model: "gpt-4o-2024-08-06",
178+
input: [
179+
{role: :system, content: "Extract the event information."},
180+
{
181+
role: :user,
182+
content: "..."
183+
}
184+
],
185+
text: {
186+
format: {
187+
type: :json_schema,
188+
name: "CalendarEvent",
189+
strict: true,
190+
schema: {
191+
type: "object",
192+
properties: {
193+
name: {type: "string"},
194+
date: {type: "string"},
195+
participants: {
196+
type: "array",
197+
items: {
198+
type: "object",
199+
properties: {
200+
first_name: {type: "string"},
201+
last_name: {type: %w[string null]},
202+
status: {type: "string", enum: %w[confirmed unconfirmed tentative]}
203+
},
204+
required: %w[first_name last_name status],
205+
additionalProperties: false
206+
}
207+
}
208+
},
209+
required: %w[name date participants],
210+
additionalProperties: false
211+
}
212+
}
213+
}
214+
)
215+
```
216+
217+
</details>
218+
108219
### Handling errors
109220

110221
When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of `OpenAI::Errors::APIError` will be thrown:

examples/structured_outputs_chat_completions.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ class CalendarEvent < OpenAI::BaseModel
5151
.choices
5252
.reject { _1.message.refusal }
5353
.each do |choice|
54+
# parsed is an instance of `CalendarEvent`
5455
pp(choice.message.parsed)
5556
end

examples/structured_outputs_chat_completions_function_calling.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ class GetWeather < OpenAI::BaseModel
2727
.reject { _1.message.refusal }
2828
.flat_map { _1.message.tool_calls.to_a }
2929
.each do |tool_call|
30+
# parsed is an instance of `GetWeather`
3031
pp(tool_call.function.parsed)
3132
end

examples/structured_outputs_responses.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ class CalendarEvent < OpenAI::BaseModel
5151
# filter out refusal responses
5252
.grep_v(OpenAI::Models::Responses::ResponseOutputRefusal)
5353
.each do |content|
54+
# parsed is an instance of `CalendarEvent`
5455
pp(content.parsed)
5556
end

examples/structured_outputs_responses_function_calling.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ class GetWeather < OpenAI::BaseModel
2424
response
2525
.output
2626
.each do |output|
27+
# parsed is an instance of `GetWeather`
2728
pp(output.parsed)
2829
end

lib/openai.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@
416416
require_relative "openai/models/responses/response_output_refusal"
417417
require_relative "openai/models/responses/response_output_text"
418418
require_relative "openai/models/responses/response_output_text_annotation_added_event"
419+
require_relative "openai/models/responses/response_prompt"
419420
require_relative "openai/models/responses/response_queued_event"
420421
require_relative "openai/models/responses/response_reasoning_delta_event"
421422
require_relative "openai/models/responses/response_reasoning_done_event"

lib/openai/models/chat/chat_completion.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ module ServiceTier
213213
AUTO = :auto
214214
DEFAULT = :default
215215
FLEX = :flex
216+
SCALE = :scale
216217

217218
# @!method self.values
218219
# @return [Array<Symbol>]

lib/openai/models/chat/chat_completion_chunk.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ module ServiceTier
396396
AUTO = :auto
397397
DEFAULT = :default
398398
FLEX = :flex
399+
SCALE = :scale
399400

400401
# @!method self.values
401402
# @return [Array<Symbol>]

lib/openai/models/chat/completion_create_params.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ module ServiceTier
569569
AUTO = :auto
570570
DEFAULT = :default
571571
FLEX = :flex
572+
SCALE = :scale
572573

573574
# @!method self.values
574575
# @return [Array<Symbol>]

lib/openai/models/fine_tuning/checkpoints/permission_retrieve_response.rb

Lines changed: 25 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,76 +6,41 @@ module FineTuning
66
module Checkpoints
77
# @see OpenAI::Resources::FineTuning::Checkpoints::Permissions#retrieve
88
class PermissionRetrieveResponse < OpenAI::Internal::Type::BaseModel
9-
# @!attribute data
9+
# @!attribute id
10+
# The permission identifier, which can be referenced in the API endpoints.
1011
#
11-
# @return [Array<OpenAI::Models::FineTuning::Checkpoints::PermissionRetrieveResponse::Data>]
12-
required :data,
13-
-> { OpenAI::Internal::Type::ArrayOf[OpenAI::Models::FineTuning::Checkpoints::PermissionRetrieveResponse::Data] }
12+
# @return [String]
13+
required :id, String
1414

15-
# @!attribute has_more
15+
# @!attribute created_at
16+
# The Unix timestamp (in seconds) for when the permission was created.
1617
#
17-
# @return [Boolean]
18-
required :has_more, OpenAI::Internal::Type::Boolean
18+
# @return [Integer]
19+
required :created_at, Integer
1920

2021
# @!attribute object
22+
# The object type, which is always "checkpoint.permission".
2123
#
22-
# @return [Symbol, :list]
23-
required :object, const: :list
24+
# @return [Symbol, :"checkpoint.permission"]
25+
required :object, const: :"checkpoint.permission"
2426

25-
# @!attribute first_id
27+
# @!attribute project_id
28+
# The project identifier that the permission is for.
2629
#
27-
# @return [String, nil]
28-
optional :first_id, String, nil?: true
30+
# @return [String]
31+
required :project_id, String
2932

30-
# @!attribute last_id
33+
# @!method initialize(id:, created_at:, project_id:, object: :"checkpoint.permission")
34+
# The `checkpoint.permission` object represents a permission for a fine-tuned
35+
# model checkpoint.
3136
#
32-
# @return [String, nil]
33-
optional :last_id, String, nil?: true
34-
35-
# @!method initialize(data:, has_more:, first_id: nil, last_id: nil, object: :list)
36-
# @param data [Array<OpenAI::Models::FineTuning::Checkpoints::PermissionRetrieveResponse::Data>]
37-
# @param has_more [Boolean]
38-
# @param first_id [String, nil]
39-
# @param last_id [String, nil]
40-
# @param object [Symbol, :list]
41-
42-
class Data < OpenAI::Internal::Type::BaseModel
43-
# @!attribute id
44-
# The permission identifier, which can be referenced in the API endpoints.
45-
#
46-
# @return [String]
47-
required :id, String
48-
49-
# @!attribute created_at
50-
# The Unix timestamp (in seconds) for when the permission was created.
51-
#
52-
# @return [Integer]
53-
required :created_at, Integer
54-
55-
# @!attribute object
56-
# The object type, which is always "checkpoint.permission".
57-
#
58-
# @return [Symbol, :"checkpoint.permission"]
59-
required :object, const: :"checkpoint.permission"
60-
61-
# @!attribute project_id
62-
# The project identifier that the permission is for.
63-
#
64-
# @return [String]
65-
required :project_id, String
66-
67-
# @!method initialize(id:, created_at:, project_id:, object: :"checkpoint.permission")
68-
# The `checkpoint.permission` object represents a permission for a fine-tuned
69-
# model checkpoint.
70-
#
71-
# @param id [String] The permission identifier, which can be referenced in the API endpoints.
72-
#
73-
# @param created_at [Integer] The Unix timestamp (in seconds) for when the permission was created.
74-
#
75-
# @param project_id [String] The project identifier that the permission is for.
76-
#
77-
# @param object [Symbol, :"checkpoint.permission"] The object type, which is always "checkpoint.permission".
78-
end
37+
# @param id [String] The permission identifier, which can be referenced in the API endpoints.
38+
#
39+
# @param created_at [Integer] The Unix timestamp (in seconds) for when the permission was created.
40+
#
41+
# @param project_id [String] The project identifier that the permission is for.
42+
#
43+
# @param object [Symbol, :"checkpoint.permission"] The object type, which is always "checkpoint.permission".
7944
end
8045
end
8146
end

lib/openai/models/fine_tuning/job_create_params.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class JobCreateParams < OpenAI::Internal::Type::BaseModel
3131
# [preference](https://platform.openai.com/docs/api-reference/fine-tuning/preference-input)
3232
# format.
3333
#
34-
# See the [fine-tuning guide](https://platform.openai.com/docs/guides/fine-tuning)
34+
# See the
35+
# [fine-tuning guide](https://platform.openai.com/docs/guides/model-optimization)
3536
# for more details.
3637
#
3738
# @return [String]
@@ -100,7 +101,8 @@ class JobCreateParams < OpenAI::Internal::Type::BaseModel
100101
# Your dataset must be formatted as a JSONL file. You must upload your file with
101102
# the purpose `fine-tune`.
102103
#
103-
# See the [fine-tuning guide](https://platform.openai.com/docs/guides/fine-tuning)
104+
# See the
105+
# [fine-tuning guide](https://platform.openai.com/docs/guides/model-optimization)
104106
# for more details.
105107
#
106108
# @return [String, nil]

0 commit comments

Comments
 (0)