openai 0.78.0 → 0.80.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 +4 -4
- data/CHANGELOG.md +99 -0
- data/README.md +241 -8
- data/SECURITY.md +6 -22
- data/azure.md +110 -0
- data/bedrock.md +197 -0
- data/examples/mtls_custom_http_client.rb +61 -0
- data/lib/openai/auth/workload_identity.rb +13 -2
- data/lib/openai/auth/workload_identity_auth.rb +2 -1
- data/lib/openai/client.rb +29 -6
- data/lib/openai/errors.rb +11 -1
- data/lib/openai/helpers/streaming/chat_completion_stream.rb +3 -3
- data/lib/openai/helpers/streaming/response_stream.rb +5 -6
- data/lib/openai/helpers/structured_output/base_model.rb +20 -19
- data/lib/openai/helpers/structured_output/json_schema_converter.rb +12 -5
- data/lib/openai/http_client.rb +99 -7
- data/lib/openai/internal/conversation_cursor_page.rb +5 -6
- data/lib/openai/internal/cursor_page.rb +3 -3
- data/lib/openai/internal/logging.rb +419 -0
- data/lib/openai/internal/next_cursor_page.rb +5 -6
- data/lib/openai/internal/page.rb +2 -2
- data/lib/openai/internal/provider.rb +7 -1
- data/lib/openai/internal/read_io_adapter.rb +42 -18
- data/lib/openai/internal/stream.rb +2 -2
- data/lib/openai/internal/transport/base_client.rb +137 -37
- data/lib/openai/internal/type/array_of.rb +6 -4
- data/lib/openai/internal/type/base_model.rb +39 -1
- data/lib/openai/internal/type/base_page.rb +19 -2
- data/lib/openai/internal/type/base_stream.rb +39 -7
- data/lib/openai/internal/type/hash_of.rb +3 -3
- data/lib/openai/internal/util.rb +52 -27
- data/lib/openai/models/admin/organization/audit_log_list_params.rb +3 -1
- data/lib/openai/models/admin/organization/audit_log_list_response.rb +33 -11
- data/lib/openai/models/admin/organization/groups/role_list_response.rb +5 -1
- data/lib/openai/models/admin/organization/groups/role_retrieve_response.rb +5 -1
- data/lib/openai/models/admin/organization/projects/groups/role_list_response.rb +6 -1
- data/lib/openai/models/admin/organization/projects/groups/role_retrieve_response.rb +6 -1
- data/lib/openai/models/admin/organization/projects/service_account_create_response.rb +3 -1
- data/lib/openai/models/admin/organization/projects/users/role_list_response.rb +6 -1
- data/lib/openai/models/admin/organization/projects/users/role_retrieve_response.rb +6 -1
- data/lib/openai/models/admin/organization/users/role_list_response.rb +5 -1
- data/lib/openai/models/admin/organization/users/role_retrieve_response.rb +5 -1
- data/lib/openai/models/all_models.rb +5 -0
- data/lib/openai/models/audio/transcription_create_params.rb +7 -1
- data/lib/openai/models/audio/translation_create_params.rb +7 -1
- data/lib/openai/models/beta/beta_mcp_tool_call_error.rb +84 -0
- data/lib/openai/models/beta/beta_response.rb +27 -0
- data/lib/openai/models/beta/beta_response_input_item.rb +3 -3
- data/lib/openai/models/beta/beta_response_item.rb +3 -3
- data/lib/openai/models/beta/beta_response_output_item.rb +3 -3
- data/lib/openai/models/beta/beta_response_output_item_added_event.rb +5 -2
- data/lib/openai/models/beta/beta_response_output_text_annotation_added_event.rb +201 -4
- data/lib/openai/models/beta/beta_response_reasoning_item.rb +5 -0
- data/lib/openai/models/beta/beta_response_stream_event.rb +1 -1
- data/lib/openai/models/beta/beta_responses_client_event.rb +46 -3
- data/lib/openai/models/beta/beta_responses_server_event.rb +1143 -63
- data/lib/openai/models/beta/beta_web_search_tool.rb +11 -1
- data/lib/openai/models/beta/response_compact_params.rb +18 -0
- data/lib/openai/models/beta/response_create_params.rb +27 -0
- data/lib/openai/models/chat_model.rb +1 -0
- data/lib/openai/models/completion_usage.rb +26 -2
- data/lib/openai/models/containers/file_create_params.rb +4 -0
- data/lib/openai/models/content_provenance_check_create_params.rb +4 -0
- data/lib/openai/models/conversations/conversation_item.rb +3 -3
- data/lib/openai/models/file_create_params.rb +4 -0
- data/lib/openai/models/image_create_variation_params.rb +4 -0
- data/lib/openai/models/image_edit_params.rb +8 -0
- data/lib/openai/models/model.rb +9 -1
- data/lib/openai/models/responses/mcp_tool_call_error.rb +82 -0
- data/lib/openai/models/responses/response.rb +9 -0
- data/lib/openai/models/responses/response_compact_params.rb +18 -0
- data/lib/openai/models/responses/response_create_params.rb +9 -0
- data/lib/openai/models/responses/response_input_item.rb +3 -3
- data/lib/openai/models/responses/response_item.rb +3 -3
- data/lib/openai/models/responses/response_output_item.rb +3 -3
- data/lib/openai/models/responses/response_output_item_added_event.rb +5 -2
- data/lib/openai/models/responses/response_output_text_annotation_added_event.rb +201 -4
- data/lib/openai/models/responses/response_reasoning_item.rb +5 -0
- data/lib/openai/models/responses/response_stream_event.rb +1 -1
- data/lib/openai/models/responses/responses_client_event.rb +22 -1
- data/lib/openai/models/responses/responses_server_event.rb +1107 -56
- data/lib/openai/models/responses/web_search_tool.rb +11 -1
- data/lib/openai/models/responses_model.rb +5 -0
- data/lib/openai/models/skill_create_params.rb +4 -0
- data/lib/openai/models/skills/version_create_params.rb +4 -0
- data/lib/openai/models/uploads/part_create_params.rb +4 -0
- data/lib/openai/models/vector_store_search_response.rb +3 -1
- data/lib/openai/models/video_create_character_params.rb +4 -0
- data/lib/openai/models/video_create_params.rb +4 -0
- data/lib/openai/models/video_edit_params.rb +4 -0
- data/lib/openai/models/video_extend_params.rb +4 -0
- data/lib/openai/models.rb +9 -1
- data/lib/openai/net_http_client.rb +20 -6
- data/lib/openai/providers/azure.rb +216 -0
- data/lib/openai/providers/bedrock.rb +130 -17
- data/lib/openai/resources/admin/organization/projects/groups/roles.rb +1 -1
- data/lib/openai/resources/admin/organization/projects/groups.rb +1 -1
- data/lib/openai/resources/admin/organization/projects/users/roles.rb +1 -1
- data/lib/openai/resources/admin/organization/projects.rb +4 -2
- data/lib/openai/resources/audio/transcriptions.rb +8 -0
- data/lib/openai/resources/audio/translations.rb +4 -0
- data/lib/openai/resources/beta/responses.rb +1 -1
- data/lib/openai/resources/beta/threads/runs/steps.rb +2 -2
- data/lib/openai/resources/containers/files.rb +4 -0
- data/lib/openai/resources/content_provenance_checks.rb +4 -0
- data/lib/openai/resources/conversations/items.rb +1 -1
- data/lib/openai/resources/evals/runs/output_items.rb +1 -1
- data/lib/openai/resources/files.rb +5 -1
- data/lib/openai/resources/images.rb +12 -0
- data/lib/openai/resources/responses.rb +3 -2
- data/lib/openai/resources/skills/versions.rb +4 -0
- data/lib/openai/resources/skills.rb +4 -0
- data/lib/openai/resources/uploads/parts.rb +4 -0
- data/lib/openai/resources/vector_stores/file_batches.rb +1 -1
- data/lib/openai/resources/videos.rb +38 -0
- data/lib/openai/resources/webhooks.rb +18 -6
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +111 -105
- data/rbi/openai/auth.rbi +4 -4
- data/rbi/openai/client.rbi +13 -3
- data/rbi/openai/errors.rbi +7 -0
- data/rbi/openai/helpers/streaming/events.rbi +12 -0
- data/rbi/openai/http_client.rbi +62 -2
- data/rbi/openai/internal/logging.rbi +192 -0
- data/rbi/openai/internal/provider.rbi +3 -0
- data/rbi/openai/internal/read_io_adapter.rbi +6 -1
- data/rbi/openai/internal/transport/base_client.rbi +61 -7
- data/rbi/openai/internal/type/base_model.rbi +24 -1
- data/rbi/openai/internal/type/base_page.rbi +13 -2
- data/rbi/openai/internal/type/base_stream.rbi +15 -4
- data/rbi/openai/internal/util.rbi +26 -2
- data/rbi/openai/models/admin/organization/audit_log_list_params.rbi +5 -0
- data/rbi/openai/models/admin/organization/audit_log_list_response.rbi +5 -0
- data/rbi/openai/models/all_models.rbi +25 -0
- data/rbi/openai/models/audio/transcription_create_params.rbi +14 -2
- data/rbi/openai/models/audio/translation_create_params.rbi +14 -2
- data/rbi/openai/models/beta/beta_mcp_tool_call_error.rbi +122 -0
- data/rbi/openai/models/beta/beta_response.rbi +47 -0
- data/rbi/openai/models/beta/beta_response_input_item.rbi +27 -3
- data/rbi/openai/models/beta/beta_response_item.rbi +27 -3
- data/rbi/openai/models/beta/beta_response_output_item.rbi +27 -3
- data/rbi/openai/models/beta/beta_response_output_item_added_event.rbi +8 -2
- data/rbi/openai/models/beta/beta_response_output_text_annotation_added_event.rbi +297 -5
- data/rbi/openai/models/beta/beta_response_reasoning_item.rbi +10 -0
- data/rbi/openai/models/beta/beta_response_stream_event.rbi +1 -1
- data/rbi/openai/models/beta/beta_responses_client_event.rbi +69 -1
- data/rbi/openai/models/beta/beta_responses_server_event.rbi +3945 -54
- data/rbi/openai/models/beta/beta_web_search_tool.rbi +15 -0
- data/rbi/openai/models/beta/response_compact_params.rbi +30 -0
- data/rbi/openai/models/beta/response_create_params.rbi +47 -0
- data/rbi/openai/models/chat_model.rbi +2 -0
- data/rbi/openai/models/completion_usage.rbi +39 -6
- data/rbi/openai/models/containers/file_create_params.rbi +8 -0
- data/rbi/openai/models/content_provenance_check_create_params.rbi +8 -0
- data/rbi/openai/models/conversations/conversation_item.rbi +12 -3
- data/rbi/openai/models/file_create_params.rbi +8 -0
- data/rbi/openai/models/image_create_variation_params.rbi +8 -0
- data/rbi/openai/models/image_edit_params.rbi +16 -0
- data/rbi/openai/models/model.rbi +14 -1
- data/rbi/openai/models/responses/mcp_tool_call_error.rbi +120 -0
- data/rbi/openai/models/responses/response.rbi +17 -0
- data/rbi/openai/models/responses/response_compact_params.rbi +30 -0
- data/rbi/openai/models/responses/response_create_params.rbi +17 -0
- data/rbi/openai/models/responses/response_input_item.rbi +27 -3
- data/rbi/openai/models/responses/response_item.rbi +27 -3
- data/rbi/openai/models/responses/response_output_item.rbi +27 -3
- data/rbi/openai/models/responses/response_output_item_added_event.rbi +8 -2
- data/rbi/openai/models/responses/response_output_text_annotation_added_event.rbi +297 -5
- data/rbi/openai/models/responses/response_reasoning_item.rbi +10 -0
- data/rbi/openai/models/responses/response_stream_event.rbi +1 -1
- data/rbi/openai/models/responses/responses_client_event.rbi +36 -0
- data/rbi/openai/models/responses/responses_server_event.rbi +3385 -53
- data/rbi/openai/models/responses/web_search_tool.rbi +15 -0
- data/rbi/openai/models/responses_model.rbi +25 -0
- data/rbi/openai/models/skill_create_params.rbi +8 -0
- data/rbi/openai/models/skills/version_create_params.rbi +8 -0
- data/rbi/openai/models/uploads/part_create_params.rbi +8 -0
- data/rbi/openai/models/video_create_character_params.rbi +8 -0
- data/rbi/openai/models/video_create_params.rbi +8 -0
- data/rbi/openai/models/video_edit_params.rbi +8 -0
- data/rbi/openai/models/video_extend_params.rbi +8 -0
- data/rbi/openai/net_http_client.rbi +2 -2
- data/rbi/openai/providers.rbi +11 -0
- data/rbi/openai/resources/audio/transcriptions.rbi +14 -2
- data/rbi/openai/resources/audio/translations.rbi +7 -1
- data/rbi/openai/resources/beta/responses.rbi +8 -0
- data/rbi/openai/resources/containers/files.rbi +4 -0
- data/rbi/openai/resources/content_provenance_checks.rbi +4 -0
- data/rbi/openai/resources/files.rbi +5 -1
- data/rbi/openai/resources/images.rbi +20 -0
- data/rbi/openai/resources/responses.rbi +8 -0
- data/rbi/openai/resources/skills/versions.rbi +4 -0
- data/rbi/openai/resources/skills.rbi +4 -0
- data/rbi/openai/resources/uploads/parts.rbi +4 -0
- data/rbi/openai/resources/videos.rbi +16 -0
- data/sig/openai/client.rbs +6 -2
- data/sig/openai/errors.rbs +5 -0
- data/sig/openai/http_client.rbs +37 -2
- data/sig/openai/internal/logging.rbs +88 -0
- data/sig/openai/internal/provider.rbs +3 -1
- data/sig/openai/internal/read_io_adapter.rbs +3 -1
- data/sig/openai/internal/transport/base_client.rbs +33 -5
- data/sig/openai/internal/type/base_model.rbs +13 -0
- data/sig/openai/internal/type/base_page.rbs +8 -1
- data/sig/openai/internal/type/base_stream.rbs +8 -2
- data/sig/openai/internal/util.rbs +12 -0
- data/sig/openai/models/admin/organization/audit_log_list_params.rbs +2 -0
- data/sig/openai/models/admin/organization/audit_log_list_response.rbs +2 -0
- data/sig/openai/models/all_models.rbs +10 -0
- data/sig/openai/models/beta/beta_mcp_tool_call_error.rbs +75 -0
- data/sig/openai/models/beta/beta_response.rbs +14 -1
- data/sig/openai/models/beta/beta_response_input_item.rbs +4 -4
- data/sig/openai/models/beta/beta_response_item.rbs +4 -4
- data/sig/openai/models/beta/beta_response_output_item.rbs +4 -4
- data/sig/openai/models/beta/beta_response_output_text_annotation_added_event.rbs +149 -4
- data/sig/openai/models/beta/beta_responses_client_event.rbs +21 -1
- data/sig/openai/models/beta/beta_responses_server_event.rbs +2005 -53
- data/sig/openai/models/beta/beta_web_search_tool.rbs +7 -0
- data/sig/openai/models/beta/response_compact_params.rbs +12 -0
- data/sig/openai/models/beta/response_create_params.rbs +14 -1
- data/sig/openai/models/chat_model.rbs +2 -0
- data/sig/openai/models/completion_usage.rbs +27 -6
- data/sig/openai/models/conversations/conversation_item.rbs +4 -4
- data/sig/openai/models/model.rbs +12 -2
- data/sig/openai/models/responses/mcp_tool_call_error.rbs +73 -0
- data/sig/openai/models/responses/response.rbs +2 -1
- data/sig/openai/models/responses/response_compact_params.rbs +12 -0
- data/sig/openai/models/responses/response_create_params.rbs +2 -1
- data/sig/openai/models/responses/response_input_item.rbs +4 -4
- data/sig/openai/models/responses/response_item.rbs +4 -4
- data/sig/openai/models/responses/response_output_item.rbs +4 -4
- data/sig/openai/models/responses/response_output_text_annotation_added_event.rbs +149 -4
- data/sig/openai/models/responses/responses_client_event.rbs +9 -1
- data/sig/openai/models/responses/responses_server_event.rbs +1834 -53
- data/sig/openai/models/responses/web_search_tool.rbs +7 -0
- data/sig/openai/models/responses_model.rbs +10 -0
- data/sig/openai/net_http_client.rbs +2 -2
- data/sig/openai/providers.rbs +7 -0
- metadata +30 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 04e35fa6de9362524ec8eb2967901334c36bc49af09ac5e3b1a5ca2b7cac0a79
|
|
4
|
+
data.tar.gz: bc0d81dc930ca951a59c5470444728d9152abad4bc7ed86e22738819718d8115
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 72ee61370ccfd94c541c06726fc17fcf3a1626234a6fd10259f1a2a1fda4b56ccaf6bc02c3dfea7f5142cd568abf073c6382fd6878c0a6185c1f27e71eaee5df
|
|
7
|
+
data.tar.gz: 9258b2d20da4c2a5bd4c509bd5f55505921a96fc1db97a421f2679f5ae2316fd33729d3f6fcf1130f0964aec1e5a8334c07db38afd2a8443ce7cd2037e45b065
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.80.0](https://github.com/openai/openai-ruby/compare/v0.79.0...v0.80.0) (2026-08-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add Amazon Bedrock Runtime support ([#424](https://github.com/openai/openai-ruby/issues/424)) ([cf48c01](https://github.com/openai/openai-ruby/commit/cf48c0157183797b5c4c66635ad4bfcb14fe2b3a))
|
|
9
|
+
* **api:** Ultrafast tier, structured MCP and websocket errors, separate websocket events ([#414](https://github.com/openai/openai-ruby/issues/414)) ([c1f3525](https://github.com/openai/openai-ruby/commit/c1f35252bc042445ba419e413b744a2f55c514ce))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* validate RuboCop directives without a Git checkout ([#425](https://github.com/openai/openai-ruby/issues/425)) ([a3cae51](https://github.com/openai/openai-ruby/commit/a3cae518dc18d1cc222558ed86332cc97f1316cc))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Chores
|
|
18
|
+
|
|
19
|
+
* enforce heredoc method call position ([#431](https://github.com/openai/openai-ruby/issues/431)) ([70cebe3](https://github.com/openai/openai-ruby/commit/70cebe3c460a659c5d181b66f92d620d2f6654f5))
|
|
20
|
+
* remove SDK namespace line-length exemption ([#419](https://github.com/openai/openai-ruby/issues/419)) ([a089ee1](https://github.com/openai/openai-ruby/commit/a089ee1788b9399fa0570896dc422ae375b6baf3))
|
|
21
|
+
|
|
22
|
+
## [0.79.0](https://github.com/openai/openai-ruby/compare/v0.78.0...v0.79.0) (2026-08-14)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add HTTP response observability ([#365](https://github.com/openai/openai-ruby/issues/365)) ([48d36b7](https://github.com/openai/openai-ruby/commit/48d36b70883a446a8062dca50fbc2d419fbe1fb9))
|
|
28
|
+
* add Tapioca typing for structured outputs ([#364](https://github.com/openai/openai-ruby/issues/364)) ([738e2b4](https://github.com/openai/openai-ruby/commit/738e2b4de4f991e594f9d319c4d17f0955cd8edd))
|
|
29
|
+
* **api:** Add new model identifiers and remove audit log source ([e0a4bc5](https://github.com/openai/openai-ruby/commit/e0a4bc56d5280c45a12e44adc49b6c34e182b33f))
|
|
30
|
+
* **api:** add WebSocket stream IDs ([#387](https://github.com/openai/openai-ruby/issues/387)) ([5880287](https://github.com/openai/openai-ruby/commit/588028770b493f2ad55b1b9acfe6ad3164c1cddc))
|
|
31
|
+
* **api:** add workload identity access token issued event ([#372](https://github.com/openai/openai-ruby/issues/372)) ([9199779](https://github.com/openai/openai-ruby/commit/919977919667da8b0764a7134d646e9cac24e709))
|
|
32
|
+
* **api:** deprecate Sora video APIs ([#386](https://github.com/openai/openai-ruby/issues/386)) ([0664456](https://github.com/openai/openai-ruby/commit/0664456735e3eccc8dd15041a45528f59df3787d))
|
|
33
|
+
* **client:** add default headers ([#369](https://github.com/openai/openai-ruby/issues/369)) ([d516874](https://github.com/openai/openai-ruby/commit/d516874ebca3ac142ecbc9d829367ab97ae685f2))
|
|
34
|
+
* expose request IDs ([#352](https://github.com/openai/openai-ruby/issues/352)) ([c15fb7b](https://github.com/openai/openai-ruby/commit/c15fb7b5d3f15de8ffc1404dba870752175415af))
|
|
35
|
+
* support Azure OpenAI v1 ([#355](https://github.com/openai/openai-ruby/issues/355)) ([c1d223e](https://github.com/openai/openai-ruby/commit/c1d223e2253450cee2631f875b968baa7cbcdc2e))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Bug Fixes
|
|
39
|
+
|
|
40
|
+
* **api:** Add new model identifiers and remove audit log source ([#360](https://github.com/openai/openai-ruby/issues/360)) ([e0a4bc5](https://github.com/openai/openai-ruby/commit/e0a4bc56d5280c45a12e44adc49b6c34e182b33f))
|
|
41
|
+
* **api:** allow nil timeout in client signatures ([#363](https://github.com/openai/openai-ruby/issues/363)) ([e52ca61](https://github.com/openai/openai-ruby/commit/e52ca61a116f7a49e98f903c28337232608264d7))
|
|
42
|
+
* **api:** document file upload metadata defaults ([#361](https://github.com/openai/openai-ruby/issues/361)) ([b4bc1ea](https://github.com/openai/openai-ruby/commit/b4bc1eaf8dd8edcc10700b3d29669816176839a3))
|
|
43
|
+
* coerce nested BaseModel fields ([#295](https://github.com/openai/openai-ruby/issues/295)) ([e5152a9](https://github.com/openai/openai-ruby/commit/e5152a92962251ce76ceb3d89ec0b6b37fa4efdb))
|
|
44
|
+
* enable streaming when retrieving responses ([#413](https://github.com/openai/openai-ruby/issues/413)) ([fd85182](https://github.com/openai/openai-ruby/commit/fd8518235b16089b03733040f22e51f3fb043ed4))
|
|
45
|
+
* encode multipart array and nested fields ([#348](https://github.com/openai/openai-ruby/issues/348)) ([1c71a1e](https://github.com/openai/openai-ruby/commit/1c71a1eccdee36a1e8dc8ab974ad1437396bd6e6))
|
|
46
|
+
* honor workload identity environment defaults ([#398](https://github.com/openai/openai-ruby/issues/398)) ([f4afea1](https://github.com/openai/openai-ruby/commit/f4afea1057ebfa5447fbbef0d89f62943473efdc))
|
|
47
|
+
* keep required path parameters out of resource query strings ([#402](https://github.com/openai/openai-ruby/issues/402)) ([6768a7c](https://github.com/openai/openai-ruby/commit/6768a7c29664fc9edce4f4da261920da8bb1959d))
|
|
48
|
+
* loading after ActiveSupport 6 subclass extensions ([#346](https://github.com/openai/openai-ruby/issues/346)) ([20fbb09](https://github.com/openai/openai-ruby/commit/20fbb0942991888e618e5b5a86531e58fff65626))
|
|
49
|
+
* make SDK debug body logging fail closed ([#411](https://github.com/openai/openai-ruby/issues/411)) ([c4f7284](https://github.com/openai/openai-ruby/commit/c4f72846e6f2bddc280f0723f880130ad27d2b71))
|
|
50
|
+
* package every README-linked guide and example ([#382](https://github.com/openai/openai-ruby/issues/382)) ([ddecd0f](https://github.com/openai/openai-ruby/commit/ddecd0f75fc2a9e33e5fb6caf3f7531f7868fb90))
|
|
51
|
+
* preserve binary multipart stream reads ([#354](https://github.com/openai/openai-ruby/issues/354)) ([b3a1ba7](https://github.com/openai/openai-ruby/commit/b3a1ba7f3dc561ac28d2768e619e46da75177c3c))
|
|
52
|
+
* preserve existing BaseModel instances during coercion ([#400](https://github.com/openai/openai-ruby/issues/400)) ([fbd8560](https://github.com/openai/openai-ruby/commit/fbd8560ff986774acb4c3af849eba048232a8da3))
|
|
53
|
+
* preserve prefixed idempotency headers on redirects ([#404](https://github.com/openai/openai-ruby/issues/404)) ([c380e13](https://github.com/openai/openai-ruby/commit/c380e13d1f866d591add5b32cc7e414de0ac85f2))
|
|
54
|
+
* preserve stream identity with HTTP logging ([#384](https://github.com/openai/openai-ruby/issues/384)) ([640a1fe](https://github.com/openai/openai-ruby/commit/640a1fed33e57194cf4241001d171b75bc3b7638))
|
|
55
|
+
* prevent symbol-keyed headers from bypassing security filters ([#383](https://github.com/openai/openai-ruby/issues/383)) ([b8165af](https://github.com/openai/openai-ruby/commit/b8165afa3065ee01e1440bc7e5339a9c5a7d7123))
|
|
56
|
+
* redact sensitive query and form logging ([#389](https://github.com/openai/openai-ruby/issues/389)) ([7aa54e4](https://github.com/openai/openai-ruby/commit/7aa54e43aba381c33639a8f697348d0620ced5d0))
|
|
57
|
+
* reject invalid webhook signing secrets ([#403](https://github.com/openai/openai-ruby/issues/403)) ([ad12458](https://github.com/openai/openai-ruby/commit/ad1245832fd18c7830becc2375c9fa7deadca88f))
|
|
58
|
+
* remove unsound structured-output Tapioca compiler ([#405](https://github.com/openai/openai-ruby/issues/405)) ([826769a](https://github.com/openai/openai-ruby/commit/826769a5169eb659042fbfcb9259ad61f04d20a5))
|
|
59
|
+
* restore RuboCop coverage for RBI files ([#388](https://github.com/openai/openai-ruby/issues/388)) ([d2d4b5d](https://github.com/openai/openai-ruby/commit/d2d4b5d1308e21703724b2f2561da2d328be5c46))
|
|
60
|
+
* return values from interruptible enumerator ([#350](https://github.com/openai/openai-ruby/issues/350)) ([327dad7](https://github.com/openai/openai-ruby/commit/327dad76d434b8ea56401efb1312e9b499cc8e71))
|
|
61
|
+
* strip credential headers on cross-origin redirects ([#391](https://github.com/openai/openai-ruby/issues/391)) ([f50f08c](https://github.com/openai/openai-ruby/commit/f50f08c15f373e956c0013d519c6d69c2484e562))
|
|
62
|
+
* tighten JSON, JSONL, and SSE content type matching ([#277](https://github.com/openai/openai-ruby/issues/277)) ([66359a0](https://github.com/openai/openai-ruby/commit/66359a09076711315bed0c8aceea8db89bc4bd42))
|
|
63
|
+
* use API field names in structured output schemas ([#390](https://github.com/openai/openai-ruby/issues/390)) ([d1e3cf3](https://github.com/openai/openai-ruby/commit/d1e3cf3cd2793d18e98394cd5e66da766c686557))
|
|
64
|
+
* validate and bound retry delays ([#392](https://github.com/openai/openai-ruby/issues/392)) ([fff94e7](https://github.com/openai/openai-ruby/commit/fff94e789a9d750913306fe3c52973bd3e730916))
|
|
65
|
+
* **webhooks:** support Rack and case-insensitive HTTP headers ([#401](https://github.com/openai/openai-ruby/issues/401)) ([37de980](https://github.com/openai/openai-ruby/commit/37de98099af70d8e97f50f8dc02ce5166c081d38))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Reverts
|
|
69
|
+
|
|
70
|
+
* nested BaseModel coercion ([#295](https://github.com/openai/openai-ruby/issues/295)) ([#375](https://github.com/openai/openai-ruby/issues/375)) ([65fa76e](https://github.com/openai/openai-ruby/commit/65fa76e57881804908bc4d1753ee7d60cff1f875))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Chores
|
|
74
|
+
|
|
75
|
+
* Cover Ruby files at the SDK root ([#362](https://github.com/openai/openai-ruby/issues/362)) ([d11f25b](https://github.com/openai/openai-ruby/commit/d11f25b28044e618849cd430c63946a306ede32c))
|
|
76
|
+
* enforce boolean symbol lint ([#395](https://github.com/openai/openai-ruby/issues/395)) ([fafdf2e](https://github.com/openai/openai-ruby/commit/fafdf2e86e2736b79212189dee07aa83ba912945))
|
|
77
|
+
* enforce deprecated constant lint ([#379](https://github.com/openai/openai-ruby/issues/379)) ([0def912](https://github.com/openai/openai-ruby/commit/0def9124cadee946879f2f66a5018ee986972509))
|
|
78
|
+
* enforce duplicate match pattern lint ([#380](https://github.com/openai/openai-ruby/issues/380)) ([7a8f2fb](https://github.com/openai/openai-ruby/commit/7a8f2fb4ac9d1176bb5e8eac88cccc9766e3fd6c))
|
|
79
|
+
* enforce empty else lint ([#396](https://github.com/openai/openai-ruby/issues/396)) ([1e073c1](https://github.com/openai/openai-ruby/commit/1e073c14a657e93ea0394fba29f9a059b3bf9b09))
|
|
80
|
+
* enforce line length lint ([#406](https://github.com/openai/openai-ruby/issues/406)) ([4592061](https://github.com/openai/openai-ruby/commit/459206126267209930640d25eae0fada7177bff0))
|
|
81
|
+
* enforce line length on base models ([#416](https://github.com/openai/openai-ruby/issues/416)) ([aef1e33](https://github.com/openai/openai-ruby/commit/aef1e333cae9c72379b3230a35d0274917999f82))
|
|
82
|
+
* enforce line length on requires ([#415](https://github.com/openai/openai-ruby/issues/415)) ([c24e045](https://github.com/openai/openai-ruby/commit/c24e045bc1a194a0935a36ed48a17841f5309718))
|
|
83
|
+
* enforce missing RuboCop enable directives ([#368](https://github.com/openai/openai-ruby/issues/368)) ([50046bf](https://github.com/openai/openai-ruby/commit/50046bf02497984d46377b9e9f1f6cc1370ee776))
|
|
84
|
+
* enforce missing super lint ([#393](https://github.com/openai/openai-ruby/issues/393)) ([2a42bd0](https://github.com/openai/openai-ruby/commit/2a42bd0531f0c16e2d61d55b2dee80e541111812))
|
|
85
|
+
* enforce nonempty pattern branches ([#409](https://github.com/openai/openai-ruby/issues/409)) ([9d22d5c](https://github.com/openai/openai-ruby/commit/9d22d5c63a9f68f1839de6f6b20f92d767eec80b))
|
|
86
|
+
* enforce redundant directive lint ([#366](https://github.com/openai/openai-ruby/issues/366)) ([8448a4c](https://github.com/openai/openai-ruby/commit/8448a4cb1551fb47a28205556e0bce320eb82c99))
|
|
87
|
+
* enforce redundant exception lint ([#397](https://github.com/openai/openai-ruby/issues/397)) ([cbda8bc](https://github.com/openai/openai-ruby/commit/cbda8bc0e6e3b2b8d0b96dfe3021d4557b713400))
|
|
88
|
+
* enforce symbol conversion lint ([#381](https://github.com/openai/openai-ruby/issues/381)) ([0531498](https://github.com/openai/openai-ruby/commit/0531498c5498804408381dcef3ddec1228196ecd))
|
|
89
|
+
* enforce useless assignment lint ([#394](https://github.com/openai/openai-ruby/issues/394)) ([9688836](https://github.com/openai/openai-ruby/commit/96888367ae757d119c90f2d9a81f4000d21745c2))
|
|
90
|
+
* guard RuboCop suppression directives ([#408](https://github.com/openai/openai-ruby/issues/408)) ([5b6e0dc](https://github.com/openai/openai-ruby/commit/5b6e0dcc325f0f5a6a0fc6df8d9aea4999c90cf5))
|
|
91
|
+
* lint Ruby files repository-wide ([#377](https://github.com/openai/openai-ruby/issues/377)) ([8ca8426](https://github.com/openai/openai-ruby/commit/8ca842693f441f19b18fda7190de4d68b2f7f9d9))
|
|
92
|
+
* remove Stainless attribution and infrastructure ([#371](https://github.com/openai/openai-ruby/issues/371)) ([33d2c86](https://github.com/openai/openai-ruby/commit/33d2c864e1f3c2a683f1b826838b2bfd2e380a26))
|
|
93
|
+
* require MFA for gem releases ([#378](https://github.com/openai/openai-ruby/issues/378)) ([71798ec](https://github.com/openai/openai-ruby/commit/71798ecb840a3feb8574efae3dd94af577717d64))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### Documentation
|
|
97
|
+
|
|
98
|
+
* **api:** describe response stream event unions ([#412](https://github.com/openai/openai-ruby/issues/412)) ([87d18ef](https://github.com/openai/openai-ruby/commit/87d18efc19445d0080344f6ebd5bc95dc8aed5cb))
|
|
99
|
+
* clarify file upload metadata ([#358](https://github.com/openai/openai-ruby/issues/358)) ([698ac65](https://github.com/openai/openai-ruby/commit/698ac65d948f07edf30255c621abaac6437f0bcf)), closes [#243](https://github.com/openai/openai-ruby/issues/243)
|
|
100
|
+
* document fiber scheduler concurrency ([#357](https://github.com/openai/openai-ruby/issues/357)) ([25a7bbc](https://github.com/openai/openai-ruby/commit/25a7bbcdc93c3331dc199e4cfe1da6037ef43bb2))
|
|
101
|
+
|
|
3
102
|
## [0.78.0](https://github.com/openai/openai-ruby/compare/v0.77.1...v0.78.0) (2026-08-07)
|
|
4
103
|
|
|
5
104
|
|
data/README.md
CHANGED
|
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
|
|
|
15
15
|
<!-- x-release-please-start-version -->
|
|
16
16
|
|
|
17
17
|
```ruby
|
|
18
|
-
gem "openai", "~> 0.
|
|
18
|
+
gem "openai", "~> 0.80.0"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
<!-- x-release-please-end -->
|
|
@@ -82,6 +82,8 @@ end
|
|
|
82
82
|
|
|
83
83
|
Request parameters that correspond to file uploads can be passed as raw contents, a [`Pathname`](https://rubyapi.org/3.3/o/pathname) instance, [`StringIO`](https://rubyapi.org/3.3/o/stringio), or more.
|
|
84
84
|
|
|
85
|
+
Raw `String` and `StringIO` values, and `IO` objects without a path, do not carry format-identifying metadata. The SDK sends them using the fallback filename `upload`; raw `String` values default to `text/plain`, while `StringIO` and pathless `IO` values default to `application/octet-stream`. For format-sensitive endpoints, such as audio transcriptions, wrap each value in `OpenAI::FilePart` and provide an extension-bearing filename and content type.
|
|
86
|
+
|
|
85
87
|
```ruby
|
|
86
88
|
require "pathname"
|
|
87
89
|
|
|
@@ -93,12 +95,25 @@ file_object = openai.files.create(file: File.read("input.jsonl"), purpose: "fine
|
|
|
93
95
|
|
|
94
96
|
puts(file_object.id)
|
|
95
97
|
|
|
96
|
-
#
|
|
97
|
-
|
|
98
|
+
# For format-sensitive uploads, provide the filename and content type:
|
|
99
|
+
audio_data = StringIO.new(File.binread("audio.wav"))
|
|
100
|
+
audio = OpenAI::FilePart.new(
|
|
101
|
+
audio_data,
|
|
102
|
+
filename: "audio.wav",
|
|
103
|
+
content_type: "audio/wav"
|
|
104
|
+
)
|
|
105
|
+
transcription = openai.audio.transcriptions.create(
|
|
106
|
+
model: "gpt-4o-transcribe",
|
|
107
|
+
file: audio
|
|
108
|
+
)
|
|
109
|
+
puts(transcription.text)
|
|
110
|
+
|
|
111
|
+
# FilePart also accepts a Pathname:
|
|
112
|
+
image = OpenAI::FilePart.new(Pathname("dog.jpg"), content_type: "image/jpeg")
|
|
98
113
|
edited = openai.images.edit(
|
|
99
114
|
prompt: "make this image look like a painting",
|
|
100
115
|
model: "gpt-image-1",
|
|
101
|
-
size:
|
|
116
|
+
size: "1024x1024",
|
|
102
117
|
image: image
|
|
103
118
|
)
|
|
104
119
|
|
|
@@ -205,6 +220,49 @@ rotation, build and atomically swap in new `OpenAI::NetHTTPClient` and
|
|
|
205
220
|
in-flight work finishes. See the complete [custom HTTP client mTLS
|
|
206
221
|
example](examples/mtls_custom_http_client.rb).
|
|
207
222
|
|
|
223
|
+
## Microsoft Azure OpenAI
|
|
224
|
+
|
|
225
|
+
Use the standard client with the Azure provider to call model deployments through
|
|
226
|
+
the Azure OpenAI v1 API. The provider accepts an Azure resource endpoint and
|
|
227
|
+
adds `/openai/v1` when needed:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
require "openai"
|
|
231
|
+
|
|
232
|
+
client = OpenAI::Client.new(
|
|
233
|
+
provider: OpenAI::Providers.azure(
|
|
234
|
+
endpoint: ENV.fetch("AZURE_OPENAI_ENDPOINT"),
|
|
235
|
+
api_key: ENV.fetch("AZURE_OPENAI_API_KEY")
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
response = client.responses.create(
|
|
240
|
+
model: ENV.fetch("AZURE_OPENAI_DEPLOYMENT"),
|
|
241
|
+
input: "Say hello!"
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
puts(response.output_text)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Omit `endpoint` and `api_key` to use `AZURE_OPENAI_ENDPOINT` and
|
|
248
|
+
`AZURE_OPENAI_API_KEY`. For Microsoft Entra authentication, pass a callable
|
|
249
|
+
that returns a current bearer token. The provider invokes it before every
|
|
250
|
+
request attempt, including retries:
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
client = OpenAI::Client.new(
|
|
254
|
+
provider: OpenAI::Providers.azure(
|
|
255
|
+
endpoint: ENV.fetch("AZURE_OPENAI_ENDPOINT"),
|
|
256
|
+
token_provider: -> { fetch_azure_openai_token }
|
|
257
|
+
)
|
|
258
|
+
)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
This integration targets the Azure OpenAI v1 API. It does not add dated
|
|
262
|
+
`api-version` query parameters or rewrite requests to legacy
|
|
263
|
+
`/deployments/{deployment}` paths. See [azure.md](azure.md) for configuration,
|
|
264
|
+
authentication precedence, and endpoint security details.
|
|
265
|
+
|
|
208
266
|
## Amazon Bedrock
|
|
209
267
|
|
|
210
268
|
Use the standard client with the Bedrock provider to call OpenAI models through Amazon Bedrock's OpenAI-compatible API. Add `aws-sdk-core` to your application for AWS credential discovery and SigV4 signing:
|
|
@@ -365,8 +423,11 @@ Note that the `body` parameter must be the raw JSON string sent from the server
|
|
|
365
423
|
require 'sinatra'
|
|
366
424
|
require 'openai'
|
|
367
425
|
|
|
368
|
-
# Set up the client with
|
|
369
|
-
client = OpenAI::Client.new(
|
|
426
|
+
# Set up the client with API credentials and the webhook secret
|
|
427
|
+
client = OpenAI::Client.new(
|
|
428
|
+
api_key: ENV.fetch('OPENAI_API_KEY'),
|
|
429
|
+
webhook_secret: ENV.fetch('OPENAI_WEBHOOK_SECRET')
|
|
430
|
+
)
|
|
370
431
|
|
|
371
432
|
post '/webhook' do
|
|
372
433
|
request_body = request.body.read
|
|
@@ -404,8 +465,11 @@ require 'sinatra'
|
|
|
404
465
|
require 'json'
|
|
405
466
|
require 'openai'
|
|
406
467
|
|
|
407
|
-
# Set up the client with
|
|
408
|
-
client = OpenAI::Client.new(
|
|
468
|
+
# Set up the client with API credentials and the webhook secret
|
|
469
|
+
client = OpenAI::Client.new(
|
|
470
|
+
api_key: ENV.fetch('OPENAI_API_KEY'),
|
|
471
|
+
webhook_secret: ENV.fetch('OPENAI_WEBHOOK_SECRET')
|
|
472
|
+
)
|
|
409
473
|
|
|
410
474
|
post '/webhook' do
|
|
411
475
|
request_body = request.body.read
|
|
@@ -565,6 +629,108 @@ Error codes are as follows:
|
|
|
565
629
|
| Timeout | `APITimeoutError` |
|
|
566
630
|
| Network error | `APIConnectionError` |
|
|
567
631
|
|
|
632
|
+
### Request logging
|
|
633
|
+
|
|
634
|
+
Request logging is disabled by default. Enable it with a standard Ruby logger
|
|
635
|
+
when creating the client:
|
|
636
|
+
|
|
637
|
+
```ruby
|
|
638
|
+
client = OpenAI::Client.new(
|
|
639
|
+
api_key: ENV.fetch("OPENAI_API_KEY"),
|
|
640
|
+
logger: Rails.logger,
|
|
641
|
+
log_level: :info
|
|
642
|
+
)
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
The logger can be any object that responds to `debug`, `info`, `warn`, and
|
|
646
|
+
`error`; the SDK does not depend on Rails. Supplying a logger enables `:info`
|
|
647
|
+
logging by default. When logging is enabled without a custom logger, the SDK
|
|
648
|
+
uses a standard-library `Logger` that writes to stderr. Use `log_level: :off`
|
|
649
|
+
when you only need retry notifications.
|
|
650
|
+
|
|
651
|
+
You can instead set `OPENAI_LOG=info` or `OPENAI_LOG=debug`. An explicit
|
|
652
|
+
`log_level:` takes precedence over the environment variable.
|
|
653
|
+
|
|
654
|
+
For example, to use the stderr logger for one process:
|
|
655
|
+
|
|
656
|
+
```sh
|
|
657
|
+
OPENAI_LOG=info bundle exec ruby app.rb
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
A completion message includes the logical request and retry context:
|
|
661
|
+
|
|
662
|
+
```text
|
|
663
|
+
[openai] request complete log_id=log_a1b2c3d4e5f6 method=POST path=/v1/responses status=200 request_id=req_123 attempts=1 duration_ms=42.7
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
| Level | Behavior |
|
|
667
|
+
| --- | --- |
|
|
668
|
+
| `:off` | No SDK request logs (default) |
|
|
669
|
+
| `:error` | Terminal request failures after retries are exhausted |
|
|
670
|
+
| `:warn` | Error events plus retry reason and delay |
|
|
671
|
+
| `:info` | Safe request completion summaries |
|
|
672
|
+
| `:debug` | Per-attempt headers and bounded structural body diagnostics |
|
|
673
|
+
|
|
674
|
+
Info, warning, and error logs include operational fields such as the HTTP
|
|
675
|
+
method, sanitized path, status, request ID, duration, and attempt count. They
|
|
676
|
+
never include headers or bodies. Debug logs redact credential-bearing headers
|
|
677
|
+
and query parameters, including authorization, API-key, cookie, token,
|
|
678
|
+
credential, and signature values.
|
|
679
|
+
|
|
680
|
+
Debug body diagnostics never include customer-controlled object keys, string
|
|
681
|
+
values, prompts, model responses, tool arguments, form fields, or signed URLs.
|
|
682
|
+
JSON bodies report only their byte size, top-level type, and object-field or
|
|
683
|
+
array-item count; form bodies report only their byte size and field count. The
|
|
684
|
+
built-in logger omits uploaded file contents, multipart bodies, binary bodies,
|
|
685
|
+
server-sent event contents, unsupported text bodies, oversized bodies, and
|
|
686
|
+
incomplete bodies. Response bodies are observed only as the application consumes
|
|
687
|
+
them and are never read eagerly for logging.
|
|
688
|
+
|
|
689
|
+
SDK log messages are intended for human diagnostics. Their text format is not
|
|
690
|
+
a stable structured-event API and may change between releases. Exceptions from
|
|
691
|
+
a supplied logger are isolated and never replace an API result or API error.
|
|
692
|
+
|
|
693
|
+
### Response metadata and request IDs
|
|
694
|
+
|
|
695
|
+
OpenAI recommends logging request IDs in production so requests can be traced
|
|
696
|
+
during troubleshooting. Top-level models and pages returned by the client expose
|
|
697
|
+
immutable HTTP response metadata through `last_response`:
|
|
698
|
+
|
|
699
|
+
```ruby
|
|
700
|
+
response = openai.responses.create(model: "gpt-5.2", input: "Say 'this is a test'.")
|
|
701
|
+
puts(response.last_response.status) # 200
|
|
702
|
+
puts(response.last_response.headers["x-request-id"]) # req_123
|
|
703
|
+
puts(response.last_response.request_id) # req_123
|
|
704
|
+
puts(response._request_id) # req_123
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Header names and values are normalized to strings, header names are lowercase,
|
|
708
|
+
and the metadata and header map are frozen. Streams expose the metadata for the
|
|
709
|
+
HTTP response that opened the stream. Higher-level streaming helpers expose the
|
|
710
|
+
same metadata as their underlying stream; models assembled from stream events
|
|
711
|
+
do not.
|
|
712
|
+
|
|
713
|
+
`last_response` and `_request_id` are only populated on top-level typed models
|
|
714
|
+
and pages returned by the client. They are `nil` on constructed or nested models
|
|
715
|
+
and are not included in `to_h`, JSON, or YAML output. Endpoints returning raw
|
|
716
|
+
primitives, binary data, or `nil` do not expose this metadata. Unlike other
|
|
717
|
+
properties that begin with an underscore, `_request_id` is public.
|
|
718
|
+
|
|
719
|
+
For failed HTTP requests, catch `OpenAI::Errors::APIStatusError` and use
|
|
720
|
+
`request_id`:
|
|
721
|
+
|
|
722
|
+
```ruby
|
|
723
|
+
begin
|
|
724
|
+
openai.responses.create(model: "gpt-5.2", input: "Say 'this is a test'.")
|
|
725
|
+
rescue OpenAI::Errors::APIStatusError => e
|
|
726
|
+
puts(e.request_id) # req_123
|
|
727
|
+
raise
|
|
728
|
+
end
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
See the [official OpenAI request debugging documentation](https://developers.openai.com/api/reference/overview#debugging-requests)
|
|
732
|
+
for more information.
|
|
733
|
+
|
|
568
734
|
### Retries
|
|
569
735
|
|
|
570
736
|
Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
|
|
@@ -587,6 +753,27 @@ openai.chat.completions.create(
|
|
|
587
753
|
)
|
|
588
754
|
```
|
|
589
755
|
|
|
756
|
+
To observe retries as they happen, supply an `on_retry` callback when creating
|
|
757
|
+
the client. The callback runs immediately before the retry delay and receives
|
|
758
|
+
an immutable `OpenAI::RetryEvent`:
|
|
759
|
+
|
|
760
|
+
```ruby
|
|
761
|
+
openai = OpenAI::Client.new(
|
|
762
|
+
log_level: :off,
|
|
763
|
+
on_retry: lambda do |event|
|
|
764
|
+
Rails.logger.warn(
|
|
765
|
+
"OpenAI retry #{event.attempt}/#{event.max_attempts} " \
|
|
766
|
+
"status=#{event.status.inspect} request_id=#{event.request_id.inspect}"
|
|
767
|
+
)
|
|
768
|
+
end
|
|
769
|
+
)
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
For response-triggered retries, `event.response` contains the same immutable
|
|
773
|
+
status, headers, and request ID shape as `last_response`. For connection errors,
|
|
774
|
+
`event.error` is populated instead. Exceptions raised by the callback are
|
|
775
|
+
isolated and do not replace the API result or error.
|
|
776
|
+
|
|
590
777
|
### Timeouts
|
|
591
778
|
|
|
592
779
|
By default, requests will time out after 600 seconds. You can use the timeout option to configure or disable this:
|
|
@@ -611,6 +798,20 @@ Note that requests that time out are retried by default.
|
|
|
611
798
|
|
|
612
799
|
## Advanced concepts
|
|
613
800
|
|
|
801
|
+
### Default request headers
|
|
802
|
+
|
|
803
|
+
Use `default_headers` to send the same custom headers with every request made by a client:
|
|
804
|
+
|
|
805
|
+
```ruby
|
|
806
|
+
finance = OpenAI::Client.new(
|
|
807
|
+
default_headers: {"x-cost-center" => "finance"}
|
|
808
|
+
)
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
Explicit `default_headers` override values from `OPENAI_CUSTOM_HEADERS`. For a single request,
|
|
812
|
+
`request_options[:extra_headers]` can override a client default or remove it by assigning `nil`.
|
|
813
|
+
Authentication and endpoint-specific headers also take precedence over client defaults.
|
|
814
|
+
|
|
614
815
|
### BaseModel
|
|
615
816
|
|
|
616
817
|
All parameter and response objects inherit from `OpenAI::Internal::Type::BaseModel`, which provides several conveniences, including:
|
|
@@ -668,6 +869,38 @@ response = client.request(
|
|
|
668
869
|
|
|
669
870
|
`OpenAI::Client` instances using the default `OpenAI::NetHTTPClient` are threadsafe, but are only fork-safe when there are no in-flight HTTP requests. Injected HTTP clients are responsible for documenting and enforcing their own concurrency guarantees.
|
|
670
871
|
|
|
872
|
+
#### Asynchronous requests with a fiber scheduler
|
|
873
|
+
|
|
874
|
+
The default HTTP client also cooperates with Ruby's fiber scheduler interface
|
|
875
|
+
(`Fiber.scheduler`). When a request runs inside a non-blocking fiber managed by
|
|
876
|
+
an active scheduler, network operations, streaming reads, retry delays, and
|
|
877
|
+
waits for a pooled connection yield to other fibers instead of blocking the
|
|
878
|
+
thread. Resource methods keep their normal return types; schedule each complete
|
|
879
|
+
request or stream operation as a task using the scheduler implementation your
|
|
880
|
+
application already uses.
|
|
881
|
+
|
|
882
|
+
For example, with the [`async`](https://github.com/socketry/async) gem:
|
|
883
|
+
|
|
884
|
+
```ruby
|
|
885
|
+
require "async"
|
|
886
|
+
|
|
887
|
+
prompts = ["Summarize the incident report.", "Draft the follow-up actions."]
|
|
888
|
+
|
|
889
|
+
responses = Async do |task|
|
|
890
|
+
prompts.map do |prompt|
|
|
891
|
+
task.async do
|
|
892
|
+
openai.responses.create(model: "gpt-5.2", input: prompt)
|
|
893
|
+
end
|
|
894
|
+
end.map(&:wait)
|
|
895
|
+
end.wait
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
Outside a non-blocking fiber managed by an active scheduler, calls block the
|
|
899
|
+
current thread as usual. The SDK does not install a scheduler or depend on a
|
|
900
|
+
particular scheduler gem.
|
|
901
|
+
|
|
902
|
+
#### Connection pooling
|
|
903
|
+
|
|
671
904
|
By default, each `OpenAI::Client` creates its own HTTP connection pool with a size of at least 99 connections. As such, we recommend instantiating the client once per application in most settings. An injected HTTP client may instead share its pool across multiple SDK clients; the caller owns that HTTP client's lifecycle.
|
|
672
905
|
|
|
673
906
|
When all available connections from the pool are checked out, requests wait for a new connection to become available, with queue time counting towards the request timeout.
|
data/SECURITY.md
CHANGED
|
@@ -2,28 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Reporting Security Issues
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Please report potential security vulnerabilities through OpenAI's
|
|
6
|
+
[coordinated vulnerability disclosure process](https://openai.com/policies/coordinated-vulnerability-disclosure-policy).
|
|
7
|
+
For questions about that process, contact disclosure@openai.com.
|
|
8
8
|
|
|
9
9
|
## Responsible Disclosure
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
before making any information public.
|
|
15
|
-
|
|
16
|
-
## Reporting Non-SDK Related Security Issues
|
|
17
|
-
|
|
18
|
-
If you encounter security issues that are not directly related to SDKs but pertain to the services
|
|
19
|
-
or products provided by OpenAI, please follow the respective company's security reporting guidelines.
|
|
20
|
-
|
|
21
|
-
### OpenAI Terms and Policies
|
|
22
|
-
|
|
23
|
-
Our Security Policy can be found at [Security Policy URL](https://openai.com/policies/coordinated-vulnerability-disclosure-policy).
|
|
24
|
-
|
|
25
|
-
Please contact disclosure@openai.com for any questions or concerns regarding the security of our services.
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
Thank you for helping us keep the SDKs and systems they interact with secure.
|
|
11
|
+
Please allow OpenAI a reasonable amount of time to investigate and address the
|
|
12
|
+
issue before making information public. Thank you for helping us keep this SDK
|
|
13
|
+
and the systems it interacts with secure.
|
data/azure.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Microsoft Azure OpenAI
|
|
2
|
+
|
|
3
|
+
Configure the standard `OpenAI::Client` with the Azure provider to use the
|
|
4
|
+
[Azure OpenAI v1 API](https://learn.microsoft.com/azure/foundry/openai/api-version-lifecycle):
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
require "openai"
|
|
8
|
+
|
|
9
|
+
client = OpenAI::Client.new(
|
|
10
|
+
provider: OpenAI::Providers.azure(
|
|
11
|
+
endpoint: ENV.fetch("AZURE_OPENAI_ENDPOINT"),
|
|
12
|
+
api_key: ENV.fetch("AZURE_OPENAI_API_KEY")
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
response = client.responses.create(
|
|
17
|
+
model: ENV.fetch("AZURE_OPENAI_DEPLOYMENT"),
|
|
18
|
+
input: "Say hello!"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
puts(response.output_text)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The `model` parameter is the Azure model deployment name. The provider exposes
|
|
25
|
+
the normal Ruby SDK resources, request and response models, retries, pagination,
|
|
26
|
+
streaming helpers, and custom HTTP transport. Azure controls which resources and
|
|
27
|
+
features are available for a deployment; unsupported calls surface as normal API
|
|
28
|
+
errors.
|
|
29
|
+
|
|
30
|
+
## Endpoint configuration
|
|
31
|
+
|
|
32
|
+
Pass the Azure resource endpoint or set `AZURE_OPENAI_ENDPOINT`:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
provider = OpenAI::Providers.azure(
|
|
36
|
+
endpoint: "https://my-resource.openai.azure.com",
|
|
37
|
+
api_key: ENV.fetch("AZURE_OPENAI_API_KEY")
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The provider appends `/openai/v1` when it is absent. These values therefore
|
|
42
|
+
configure the same base URL:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
https://my-resource.openai.azure.com
|
|
46
|
+
https://my-resource.openai.azure.com/openai
|
|
47
|
+
https://my-resource.openai.azure.com/openai/v1/
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The endpoint must be an absolute HTTP or HTTPS URL without user information, a
|
|
51
|
+
query string, or a fragment. Use HTTPS outside local testing. A path prefix is
|
|
52
|
+
preserved for gateways and private routing, for example
|
|
53
|
+
`https://gateway.example.com/azure` becomes
|
|
54
|
+
`https://gateway.example.com/azure/openai/v1`.
|
|
55
|
+
|
|
56
|
+
## Authentication
|
|
57
|
+
|
|
58
|
+
Configure exactly one authentication mode explicitly. If neither is explicit,
|
|
59
|
+
the provider uses `AZURE_OPENAI_API_KEY`.
|
|
60
|
+
|
|
61
|
+
### Azure API key
|
|
62
|
+
|
|
63
|
+
Pass `api_key` or set `AZURE_OPENAI_API_KEY`. The provider sends it in Azure's
|
|
64
|
+
`api-key` header:
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
provider = OpenAI::Providers.azure(
|
|
68
|
+
endpoint: ENV.fetch("AZURE_OPENAI_ENDPOINT"),
|
|
69
|
+
api_key: ENV.fetch("AZURE_OPENAI_API_KEY")
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Passing `api_key: nil` explicitly skips the environment fallback.
|
|
74
|
+
|
|
75
|
+
### Microsoft Entra bearer token
|
|
76
|
+
|
|
77
|
+
Pass a callable that returns a current access token for Azure OpenAI. Credential
|
|
78
|
+
acquisition stays with the application, so the SDK does not require an Azure
|
|
79
|
+
identity package:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
provider = OpenAI::Providers.azure(
|
|
83
|
+
endpoint: ENV.fetch("AZURE_OPENAI_ENDPOINT"),
|
|
84
|
+
token_provider: -> {
|
|
85
|
+
credential.get_token("https://cognitiveservices.azure.com/.default").token
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
An explicit `token_provider` takes precedence over an ambient
|
|
91
|
+
`AZURE_OPENAI_API_KEY`. It is invoked immediately before every request attempt,
|
|
92
|
+
including API retries, so applications can refresh short-lived tokens without
|
|
93
|
+
rebuilding the client.
|
|
94
|
+
|
|
95
|
+
## Security
|
|
96
|
+
|
|
97
|
+
The provider validates the request origin before attaching an API key or bearer
|
|
98
|
+
token. It refuses to authenticate redirects or custom requests whose origin
|
|
99
|
+
differs from the configured Azure endpoint. Custom `Authorization` and `api-key`
|
|
100
|
+
headers cannot be combined with provider-owned authentication.
|
|
101
|
+
|
|
102
|
+
Keep credentials out of source control and logs. Prefer short-lived Microsoft
|
|
103
|
+
Entra tokens to long-lived API keys for production workloads.
|
|
104
|
+
|
|
105
|
+
## Dated Azure APIs
|
|
106
|
+
|
|
107
|
+
This provider targets the GA Azure OpenAI v1 API. It does not support dated API
|
|
108
|
+
versions such as `2025-04-01-preview`, inject `api-version` query parameters, or
|
|
109
|
+
rewrite generated resource paths to `/deployments/{deployment}`. Use the v1 API
|
|
110
|
+
for new integrations.
|