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.
Files changed (239) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +99 -0
  3. data/README.md +241 -8
  4. data/SECURITY.md +6 -22
  5. data/azure.md +110 -0
  6. data/bedrock.md +197 -0
  7. data/examples/mtls_custom_http_client.rb +61 -0
  8. data/lib/openai/auth/workload_identity.rb +13 -2
  9. data/lib/openai/auth/workload_identity_auth.rb +2 -1
  10. data/lib/openai/client.rb +29 -6
  11. data/lib/openai/errors.rb +11 -1
  12. data/lib/openai/helpers/streaming/chat_completion_stream.rb +3 -3
  13. data/lib/openai/helpers/streaming/response_stream.rb +5 -6
  14. data/lib/openai/helpers/structured_output/base_model.rb +20 -19
  15. data/lib/openai/helpers/structured_output/json_schema_converter.rb +12 -5
  16. data/lib/openai/http_client.rb +99 -7
  17. data/lib/openai/internal/conversation_cursor_page.rb +5 -6
  18. data/lib/openai/internal/cursor_page.rb +3 -3
  19. data/lib/openai/internal/logging.rb +419 -0
  20. data/lib/openai/internal/next_cursor_page.rb +5 -6
  21. data/lib/openai/internal/page.rb +2 -2
  22. data/lib/openai/internal/provider.rb +7 -1
  23. data/lib/openai/internal/read_io_adapter.rb +42 -18
  24. data/lib/openai/internal/stream.rb +2 -2
  25. data/lib/openai/internal/transport/base_client.rb +137 -37
  26. data/lib/openai/internal/type/array_of.rb +6 -4
  27. data/lib/openai/internal/type/base_model.rb +39 -1
  28. data/lib/openai/internal/type/base_page.rb +19 -2
  29. data/lib/openai/internal/type/base_stream.rb +39 -7
  30. data/lib/openai/internal/type/hash_of.rb +3 -3
  31. data/lib/openai/internal/util.rb +52 -27
  32. data/lib/openai/models/admin/organization/audit_log_list_params.rb +3 -1
  33. data/lib/openai/models/admin/organization/audit_log_list_response.rb +33 -11
  34. data/lib/openai/models/admin/organization/groups/role_list_response.rb +5 -1
  35. data/lib/openai/models/admin/organization/groups/role_retrieve_response.rb +5 -1
  36. data/lib/openai/models/admin/organization/projects/groups/role_list_response.rb +6 -1
  37. data/lib/openai/models/admin/organization/projects/groups/role_retrieve_response.rb +6 -1
  38. data/lib/openai/models/admin/organization/projects/service_account_create_response.rb +3 -1
  39. data/lib/openai/models/admin/organization/projects/users/role_list_response.rb +6 -1
  40. data/lib/openai/models/admin/organization/projects/users/role_retrieve_response.rb +6 -1
  41. data/lib/openai/models/admin/organization/users/role_list_response.rb +5 -1
  42. data/lib/openai/models/admin/organization/users/role_retrieve_response.rb +5 -1
  43. data/lib/openai/models/all_models.rb +5 -0
  44. data/lib/openai/models/audio/transcription_create_params.rb +7 -1
  45. data/lib/openai/models/audio/translation_create_params.rb +7 -1
  46. data/lib/openai/models/beta/beta_mcp_tool_call_error.rb +84 -0
  47. data/lib/openai/models/beta/beta_response.rb +27 -0
  48. data/lib/openai/models/beta/beta_response_input_item.rb +3 -3
  49. data/lib/openai/models/beta/beta_response_item.rb +3 -3
  50. data/lib/openai/models/beta/beta_response_output_item.rb +3 -3
  51. data/lib/openai/models/beta/beta_response_output_item_added_event.rb +5 -2
  52. data/lib/openai/models/beta/beta_response_output_text_annotation_added_event.rb +201 -4
  53. data/lib/openai/models/beta/beta_response_reasoning_item.rb +5 -0
  54. data/lib/openai/models/beta/beta_response_stream_event.rb +1 -1
  55. data/lib/openai/models/beta/beta_responses_client_event.rb +46 -3
  56. data/lib/openai/models/beta/beta_responses_server_event.rb +1143 -63
  57. data/lib/openai/models/beta/beta_web_search_tool.rb +11 -1
  58. data/lib/openai/models/beta/response_compact_params.rb +18 -0
  59. data/lib/openai/models/beta/response_create_params.rb +27 -0
  60. data/lib/openai/models/chat_model.rb +1 -0
  61. data/lib/openai/models/completion_usage.rb +26 -2
  62. data/lib/openai/models/containers/file_create_params.rb +4 -0
  63. data/lib/openai/models/content_provenance_check_create_params.rb +4 -0
  64. data/lib/openai/models/conversations/conversation_item.rb +3 -3
  65. data/lib/openai/models/file_create_params.rb +4 -0
  66. data/lib/openai/models/image_create_variation_params.rb +4 -0
  67. data/lib/openai/models/image_edit_params.rb +8 -0
  68. data/lib/openai/models/model.rb +9 -1
  69. data/lib/openai/models/responses/mcp_tool_call_error.rb +82 -0
  70. data/lib/openai/models/responses/response.rb +9 -0
  71. data/lib/openai/models/responses/response_compact_params.rb +18 -0
  72. data/lib/openai/models/responses/response_create_params.rb +9 -0
  73. data/lib/openai/models/responses/response_input_item.rb +3 -3
  74. data/lib/openai/models/responses/response_item.rb +3 -3
  75. data/lib/openai/models/responses/response_output_item.rb +3 -3
  76. data/lib/openai/models/responses/response_output_item_added_event.rb +5 -2
  77. data/lib/openai/models/responses/response_output_text_annotation_added_event.rb +201 -4
  78. data/lib/openai/models/responses/response_reasoning_item.rb +5 -0
  79. data/lib/openai/models/responses/response_stream_event.rb +1 -1
  80. data/lib/openai/models/responses/responses_client_event.rb +22 -1
  81. data/lib/openai/models/responses/responses_server_event.rb +1107 -56
  82. data/lib/openai/models/responses/web_search_tool.rb +11 -1
  83. data/lib/openai/models/responses_model.rb +5 -0
  84. data/lib/openai/models/skill_create_params.rb +4 -0
  85. data/lib/openai/models/skills/version_create_params.rb +4 -0
  86. data/lib/openai/models/uploads/part_create_params.rb +4 -0
  87. data/lib/openai/models/vector_store_search_response.rb +3 -1
  88. data/lib/openai/models/video_create_character_params.rb +4 -0
  89. data/lib/openai/models/video_create_params.rb +4 -0
  90. data/lib/openai/models/video_edit_params.rb +4 -0
  91. data/lib/openai/models/video_extend_params.rb +4 -0
  92. data/lib/openai/models.rb +9 -1
  93. data/lib/openai/net_http_client.rb +20 -6
  94. data/lib/openai/providers/azure.rb +216 -0
  95. data/lib/openai/providers/bedrock.rb +130 -17
  96. data/lib/openai/resources/admin/organization/projects/groups/roles.rb +1 -1
  97. data/lib/openai/resources/admin/organization/projects/groups.rb +1 -1
  98. data/lib/openai/resources/admin/organization/projects/users/roles.rb +1 -1
  99. data/lib/openai/resources/admin/organization/projects.rb +4 -2
  100. data/lib/openai/resources/audio/transcriptions.rb +8 -0
  101. data/lib/openai/resources/audio/translations.rb +4 -0
  102. data/lib/openai/resources/beta/responses.rb +1 -1
  103. data/lib/openai/resources/beta/threads/runs/steps.rb +2 -2
  104. data/lib/openai/resources/containers/files.rb +4 -0
  105. data/lib/openai/resources/content_provenance_checks.rb +4 -0
  106. data/lib/openai/resources/conversations/items.rb +1 -1
  107. data/lib/openai/resources/evals/runs/output_items.rb +1 -1
  108. data/lib/openai/resources/files.rb +5 -1
  109. data/lib/openai/resources/images.rb +12 -0
  110. data/lib/openai/resources/responses.rb +3 -2
  111. data/lib/openai/resources/skills/versions.rb +4 -0
  112. data/lib/openai/resources/skills.rb +4 -0
  113. data/lib/openai/resources/uploads/parts.rb +4 -0
  114. data/lib/openai/resources/vector_stores/file_batches.rb +1 -1
  115. data/lib/openai/resources/videos.rb +38 -0
  116. data/lib/openai/resources/webhooks.rb +18 -6
  117. data/lib/openai/version.rb +1 -1
  118. data/lib/openai.rb +111 -105
  119. data/rbi/openai/auth.rbi +4 -4
  120. data/rbi/openai/client.rbi +13 -3
  121. data/rbi/openai/errors.rbi +7 -0
  122. data/rbi/openai/helpers/streaming/events.rbi +12 -0
  123. data/rbi/openai/http_client.rbi +62 -2
  124. data/rbi/openai/internal/logging.rbi +192 -0
  125. data/rbi/openai/internal/provider.rbi +3 -0
  126. data/rbi/openai/internal/read_io_adapter.rbi +6 -1
  127. data/rbi/openai/internal/transport/base_client.rbi +61 -7
  128. data/rbi/openai/internal/type/base_model.rbi +24 -1
  129. data/rbi/openai/internal/type/base_page.rbi +13 -2
  130. data/rbi/openai/internal/type/base_stream.rbi +15 -4
  131. data/rbi/openai/internal/util.rbi +26 -2
  132. data/rbi/openai/models/admin/organization/audit_log_list_params.rbi +5 -0
  133. data/rbi/openai/models/admin/organization/audit_log_list_response.rbi +5 -0
  134. data/rbi/openai/models/all_models.rbi +25 -0
  135. data/rbi/openai/models/audio/transcription_create_params.rbi +14 -2
  136. data/rbi/openai/models/audio/translation_create_params.rbi +14 -2
  137. data/rbi/openai/models/beta/beta_mcp_tool_call_error.rbi +122 -0
  138. data/rbi/openai/models/beta/beta_response.rbi +47 -0
  139. data/rbi/openai/models/beta/beta_response_input_item.rbi +27 -3
  140. data/rbi/openai/models/beta/beta_response_item.rbi +27 -3
  141. data/rbi/openai/models/beta/beta_response_output_item.rbi +27 -3
  142. data/rbi/openai/models/beta/beta_response_output_item_added_event.rbi +8 -2
  143. data/rbi/openai/models/beta/beta_response_output_text_annotation_added_event.rbi +297 -5
  144. data/rbi/openai/models/beta/beta_response_reasoning_item.rbi +10 -0
  145. data/rbi/openai/models/beta/beta_response_stream_event.rbi +1 -1
  146. data/rbi/openai/models/beta/beta_responses_client_event.rbi +69 -1
  147. data/rbi/openai/models/beta/beta_responses_server_event.rbi +3945 -54
  148. data/rbi/openai/models/beta/beta_web_search_tool.rbi +15 -0
  149. data/rbi/openai/models/beta/response_compact_params.rbi +30 -0
  150. data/rbi/openai/models/beta/response_create_params.rbi +47 -0
  151. data/rbi/openai/models/chat_model.rbi +2 -0
  152. data/rbi/openai/models/completion_usage.rbi +39 -6
  153. data/rbi/openai/models/containers/file_create_params.rbi +8 -0
  154. data/rbi/openai/models/content_provenance_check_create_params.rbi +8 -0
  155. data/rbi/openai/models/conversations/conversation_item.rbi +12 -3
  156. data/rbi/openai/models/file_create_params.rbi +8 -0
  157. data/rbi/openai/models/image_create_variation_params.rbi +8 -0
  158. data/rbi/openai/models/image_edit_params.rbi +16 -0
  159. data/rbi/openai/models/model.rbi +14 -1
  160. data/rbi/openai/models/responses/mcp_tool_call_error.rbi +120 -0
  161. data/rbi/openai/models/responses/response.rbi +17 -0
  162. data/rbi/openai/models/responses/response_compact_params.rbi +30 -0
  163. data/rbi/openai/models/responses/response_create_params.rbi +17 -0
  164. data/rbi/openai/models/responses/response_input_item.rbi +27 -3
  165. data/rbi/openai/models/responses/response_item.rbi +27 -3
  166. data/rbi/openai/models/responses/response_output_item.rbi +27 -3
  167. data/rbi/openai/models/responses/response_output_item_added_event.rbi +8 -2
  168. data/rbi/openai/models/responses/response_output_text_annotation_added_event.rbi +297 -5
  169. data/rbi/openai/models/responses/response_reasoning_item.rbi +10 -0
  170. data/rbi/openai/models/responses/response_stream_event.rbi +1 -1
  171. data/rbi/openai/models/responses/responses_client_event.rbi +36 -0
  172. data/rbi/openai/models/responses/responses_server_event.rbi +3385 -53
  173. data/rbi/openai/models/responses/web_search_tool.rbi +15 -0
  174. data/rbi/openai/models/responses_model.rbi +25 -0
  175. data/rbi/openai/models/skill_create_params.rbi +8 -0
  176. data/rbi/openai/models/skills/version_create_params.rbi +8 -0
  177. data/rbi/openai/models/uploads/part_create_params.rbi +8 -0
  178. data/rbi/openai/models/video_create_character_params.rbi +8 -0
  179. data/rbi/openai/models/video_create_params.rbi +8 -0
  180. data/rbi/openai/models/video_edit_params.rbi +8 -0
  181. data/rbi/openai/models/video_extend_params.rbi +8 -0
  182. data/rbi/openai/net_http_client.rbi +2 -2
  183. data/rbi/openai/providers.rbi +11 -0
  184. data/rbi/openai/resources/audio/transcriptions.rbi +14 -2
  185. data/rbi/openai/resources/audio/translations.rbi +7 -1
  186. data/rbi/openai/resources/beta/responses.rbi +8 -0
  187. data/rbi/openai/resources/containers/files.rbi +4 -0
  188. data/rbi/openai/resources/content_provenance_checks.rbi +4 -0
  189. data/rbi/openai/resources/files.rbi +5 -1
  190. data/rbi/openai/resources/images.rbi +20 -0
  191. data/rbi/openai/resources/responses.rbi +8 -0
  192. data/rbi/openai/resources/skills/versions.rbi +4 -0
  193. data/rbi/openai/resources/skills.rbi +4 -0
  194. data/rbi/openai/resources/uploads/parts.rbi +4 -0
  195. data/rbi/openai/resources/videos.rbi +16 -0
  196. data/sig/openai/client.rbs +6 -2
  197. data/sig/openai/errors.rbs +5 -0
  198. data/sig/openai/http_client.rbs +37 -2
  199. data/sig/openai/internal/logging.rbs +88 -0
  200. data/sig/openai/internal/provider.rbs +3 -1
  201. data/sig/openai/internal/read_io_adapter.rbs +3 -1
  202. data/sig/openai/internal/transport/base_client.rbs +33 -5
  203. data/sig/openai/internal/type/base_model.rbs +13 -0
  204. data/sig/openai/internal/type/base_page.rbs +8 -1
  205. data/sig/openai/internal/type/base_stream.rbs +8 -2
  206. data/sig/openai/internal/util.rbs +12 -0
  207. data/sig/openai/models/admin/organization/audit_log_list_params.rbs +2 -0
  208. data/sig/openai/models/admin/organization/audit_log_list_response.rbs +2 -0
  209. data/sig/openai/models/all_models.rbs +10 -0
  210. data/sig/openai/models/beta/beta_mcp_tool_call_error.rbs +75 -0
  211. data/sig/openai/models/beta/beta_response.rbs +14 -1
  212. data/sig/openai/models/beta/beta_response_input_item.rbs +4 -4
  213. data/sig/openai/models/beta/beta_response_item.rbs +4 -4
  214. data/sig/openai/models/beta/beta_response_output_item.rbs +4 -4
  215. data/sig/openai/models/beta/beta_response_output_text_annotation_added_event.rbs +149 -4
  216. data/sig/openai/models/beta/beta_responses_client_event.rbs +21 -1
  217. data/sig/openai/models/beta/beta_responses_server_event.rbs +2005 -53
  218. data/sig/openai/models/beta/beta_web_search_tool.rbs +7 -0
  219. data/sig/openai/models/beta/response_compact_params.rbs +12 -0
  220. data/sig/openai/models/beta/response_create_params.rbs +14 -1
  221. data/sig/openai/models/chat_model.rbs +2 -0
  222. data/sig/openai/models/completion_usage.rbs +27 -6
  223. data/sig/openai/models/conversations/conversation_item.rbs +4 -4
  224. data/sig/openai/models/model.rbs +12 -2
  225. data/sig/openai/models/responses/mcp_tool_call_error.rbs +73 -0
  226. data/sig/openai/models/responses/response.rbs +2 -1
  227. data/sig/openai/models/responses/response_compact_params.rbs +12 -0
  228. data/sig/openai/models/responses/response_create_params.rbs +2 -1
  229. data/sig/openai/models/responses/response_input_item.rbs +4 -4
  230. data/sig/openai/models/responses/response_item.rbs +4 -4
  231. data/sig/openai/models/responses/response_output_item.rbs +4 -4
  232. data/sig/openai/models/responses/response_output_text_annotation_added_event.rbs +149 -4
  233. data/sig/openai/models/responses/responses_client_event.rbs +9 -1
  234. data/sig/openai/models/responses/responses_server_event.rbs +1834 -53
  235. data/sig/openai/models/responses/web_search_tool.rbs +7 -0
  236. data/sig/openai/models/responses_model.rbs +10 -0
  237. data/sig/openai/net_http_client.rbs +2 -2
  238. data/sig/openai/providers.rbs +7 -0
  239. metadata +30 -1
@@ -4,8 +4,9 @@ module OpenAI
4
4
  module Providers
5
5
  # @api private
6
6
  module Bedrock
7
- SERVICE = "bedrock-mantle"
8
- CANONICAL_HOST = /\Abedrock-mantle\.([a-z0-9-]+)\.api\.aws\z/i
7
+ SERVICES = {mantle: "bedrock-mantle", runtime: "bedrock"}.freeze
8
+ AWS_REGION_PATTERN = /\A[a-z]{2,8}(?:-[a-z0-9]+)+-\d+\z/
9
+ AUTH_HEADERS = %w[authorization].freeze
9
10
  SIGNING_HEADERS = %w[authorization x-amz-content-sha256 x-amz-date x-amz-security-token].freeze
10
11
  BEARER_AUTH_MARKER = :openai_bedrock_bearer
11
12
  SIGV4_AUTH_MARKER = :openai_bedrock_sigv4
@@ -38,6 +39,7 @@ module OpenAI
38
39
  attr_reader :name
39
40
 
40
41
  def initialize(
42
+ endpoint:,
41
43
  region:,
42
44
  base_url:,
43
45
  bearer_provider:,
@@ -49,6 +51,7 @@ module OpenAI
49
51
  default_chain:
50
52
  )
51
53
  @name = "bedrock"
54
+ @endpoint = endpoint
52
55
  @region = region&.freeze
53
56
  @base_url = base_url&.freeze
54
57
  @bearer_provider = bearer_provider
@@ -62,14 +65,17 @@ module OpenAI
62
65
 
63
66
  def configure
64
67
  if @bearer_provider
65
- base_url = Bedrock.resolve_base_url(@base_url, @region)
68
+ base_url = Bedrock.resolve_base_url(@base_url, @region, endpoint: @endpoint)
69
+ Bedrock.validate_canonical_endpoint!(base_url, @endpoint, @region)
66
70
  auth = BearerAuth.new(token_provider: @bearer_provider, base_url: base_url)
67
71
  else
68
72
  Bedrock.load_aws!
69
73
  region = @region || Bedrock.profile_region(@profile)
70
74
  raise ArgumentError, MISSING_REGION_MESSAGE if region.nil?
75
+ Bedrock.validate_region!(region)
71
76
 
72
- base_url = Bedrock.resolve_base_url(@base_url, region)
77
+ base_url = Bedrock.resolve_base_url(@base_url, region, endpoint: @endpoint)
78
+ Bedrock.validate_canonical_endpoint!(base_url, @endpoint, region)
73
79
  credentials =
74
80
  if @access_key_id
75
81
  Aws::Credentials.new(@access_key_id, @secret_access_key, @session_token)
@@ -81,6 +87,7 @@ module OpenAI
81
87
  DefaultCredentialsProvider.new
82
88
  end
83
89
  auth = SigV4Auth.new(
90
+ endpoint: @endpoint,
84
91
  region: region,
85
92
  base_url: base_url,
86
93
  credentials_provider: credentials,
@@ -91,7 +98,8 @@ module OpenAI
91
98
  OpenAI::Internal::Provider::Runtime.new(
92
99
  name: name,
93
100
  base_url: base_url,
94
- prepare_request: auth.method(:prepare_request)
101
+ prepare_request: auth.method(:prepare_request),
102
+ authentication_headers: AUTH_HEADERS
95
103
  )
96
104
  end
97
105
  end
@@ -128,12 +136,13 @@ module OpenAI
128
136
  end
129
137
 
130
138
  class SigV4Auth
131
- def initialize(region:, base_url:, credentials_provider:, default_chain:)
139
+ def initialize(endpoint:, region:, base_url:, credentials_provider:, default_chain:)
140
+ @endpoint = endpoint
132
141
  @region = region
133
142
  @base_url = URI(base_url)
134
143
  @default_chain = default_chain
135
144
  @signer = Aws::Sigv4::Signer.new(
136
- service: SERVICE,
145
+ service: SERVICES.fetch(endpoint),
137
146
  region: region,
138
147
  credentials_provider: credentials_provider
139
148
  )
@@ -142,7 +151,7 @@ module OpenAI
142
151
  def prepare_request(request)
143
152
  url = request.fetch(:url)
144
153
  Bedrock.validate_origin!(url, @base_url, action: "sign")
145
- Bedrock.validate_endpoint_region!(url, @region)
154
+ Bedrock.validate_endpoint_region!(url, @region, endpoint: @endpoint)
146
155
  body = request[:body]
147
156
  unless body.nil? || body.is_a?(String)
148
157
  raise OpenAI::Errors::Error, NON_REPLAYABLE_BODY_MESSAGE
@@ -261,10 +270,86 @@ module OpenAI
261
270
  raise OpenAI::Errors::Error.new(MISSING_DEPENDENCY_MESSAGE), cause: e
262
271
  end
263
272
 
264
- def resolve_base_url(base_url, region)
273
+ def resolve_base_url(base_url, region, endpoint:)
265
274
  return base_url if base_url
266
275
  raise ArgumentError, MISSING_REGION_MESSAGE if region.nil?
267
- "https://bedrock-mantle.#{region}.api.aws/v1"
276
+
277
+ if endpoint == :runtime
278
+ suffix, = runtime_dns_suffixes(region)
279
+ "https://bedrock-runtime.#{region}.#{suffix}/openai/v1"
280
+ else
281
+ "https://bedrock-mantle.#{region}.api.aws/v1"
282
+ end
283
+ end
284
+
285
+ def runtime_dns_suffixes(region)
286
+ case region
287
+ when /\Acn-/
288
+ ["amazonaws.com.cn", "api.amazonwebservices.com.cn"]
289
+ when /\Aeusc-/
290
+ ["amazonaws.eu", "api.amazonwebservices.eu"]
291
+ when /\Aus-iso-/
292
+ ["c2s.ic.gov", "api.aws.ic.gov"]
293
+ when /\Aus-isob-/
294
+ ["sc2s.sgov.gov", "api.aws.scloud"]
295
+ when /\Aeu-isoe-/
296
+ ["cloud.adc-e.uk", "api.cloud-aws.adc-e.uk"]
297
+ when /\Aus-isof-/
298
+ ["csp.hci.ic.gov", "api.aws.hci.ic.gov"]
299
+ else
300
+ ["amazonaws.com", "api.aws"]
301
+ end
302
+ end
303
+
304
+ def parse_endpoint_hostname(hostname)
305
+ service, region, *suffix_parts = hostname.delete_suffix(".").downcase.split(".")
306
+ suffix = suffix_parts.join(".")
307
+
308
+ if service == "bedrock-mantle" && region&.match?(/\A[a-z0-9-]+\z/) && suffix == "api.aws"
309
+ return {endpoint: :mantle, region: region}
310
+ end
311
+
312
+ if %w[bedrock-runtime bedrock-runtime-fips].include?(service) && region &&
313
+ runtime_dns_suffixes(region).include?(suffix)
314
+ return {endpoint: :runtime, region: region}
315
+ end
316
+
317
+ nil
318
+ end
319
+
320
+ def validate_canonical_endpoint!(base_url, endpoint, region)
321
+ uri = URI(base_url)
322
+ canonical = parse_endpoint_hostname(uri.host)
323
+ return unless canonical
324
+
325
+ unless uri.is_a?(URI::HTTPS)
326
+ raise ArgumentError, "Canonical Amazon Bedrock endpoints require HTTPS."
327
+ end
328
+ if canonical.fetch(:endpoint) != endpoint
329
+ raise ArgumentError,
330
+ "The Bedrock #{canonical.fetch(:endpoint)} hostname does not match the " \
331
+ "selected `#{endpoint}` endpoint."
332
+ end
333
+ return if region.nil? || canonical.fetch(:region) == region
334
+
335
+ raise ArgumentError,
336
+ "The Bedrock endpoint region `#{canonical.fetch(:region)}` does not match the " \
337
+ "configured AWS region `#{region}`."
338
+ end
339
+
340
+ def validate_region!(region)
341
+ return if AWS_REGION_PATTERN.match?(region)
342
+
343
+ raise ArgumentError,
344
+ "The Bedrock AWS `region` is invalid. Use a standard AWS region such as `us-east-1`."
345
+ end
346
+
347
+ def normalize_endpoint(endpoint)
348
+ return nil if endpoint.nil?
349
+ return endpoint.to_sym if endpoint == "mantle" || endpoint == "runtime"
350
+ return endpoint if endpoint == :mantle || endpoint == :runtime
351
+
352
+ raise ArgumentError, "The Bedrock `endpoint` must be either `mantle` or `runtime`."
268
353
  end
269
354
 
270
355
  def normalize_base_url(base_url)
@@ -308,9 +393,18 @@ module OpenAI
308
393
  message
309
394
  end
310
395
 
311
- def validate_endpoint_region!(url, region)
312
- endpoint_region = CANONICAL_HOST.match(url.host)&.[](1)
313
- return if endpoint_region.nil? || endpoint_region == region
396
+ def validate_endpoint_region!(url, region, endpoint:)
397
+ canonical = parse_endpoint_hostname(url.host)
398
+ return unless canonical
399
+
400
+ if canonical.fetch(:endpoint) != endpoint
401
+ raise OpenAI::Errors::Error,
402
+ "The Bedrock #{canonical.fetch(:endpoint)} hostname does not match the " \
403
+ "selected `#{endpoint}` endpoint."
404
+ end
405
+
406
+ endpoint_region = canonical.fetch(:region)
407
+ return if endpoint_region == region
314
408
  message =
315
409
  "The Bedrock endpoint region `#{endpoint_region}` does not match the SigV4 " \
316
410
  "region `#{region}`."
@@ -340,16 +434,19 @@ module OpenAI
340
434
  end
341
435
 
342
436
  class << self
343
- # Configure the standard OpenAI client for Amazon Bedrock Mantle.
437
+ # Configure the standard OpenAI client for Amazon Bedrock Mantle or Runtime.
344
438
  #
345
439
  # Authentication precedence is an explicit bearer or AWS mode, then
346
440
  # AWS_BEARER_TOKEN_BEDROCK, then the standard AWS credential chain.
347
441
  #
442
+ # @param endpoint [String, Symbol, nil] Bedrock endpoint family. Defaults to
443
+ # Mantle unless a canonical Runtime `base_url` is supplied.
444
+ #
348
445
  # @param region [String, nil] AWS signing region. Defaults to `AWS_REGION`,
349
446
  # `AWS_DEFAULT_REGION`, or the selected profile's configured region.
350
447
  #
351
448
  # @param base_url [String, nil] Bedrock API root. Defaults to
352
- # `AWS_BEDROCK_BASE_URL` or the regional Bedrock Mantle endpoint.
449
+ # `AWS_BEDROCK_BASE_URL` or the selected regional Bedrock endpoint.
353
450
  #
354
451
  # @param api_key [String, nil] Explicit Bedrock bearer credential. Passing
355
452
  # `nil` explicitly skips the `AWS_BEARER_TOKEN_BEDROCK` fallback.
@@ -372,6 +469,7 @@ module OpenAI
372
469
  #
373
470
  # @return [OpenAI::Provider]
374
471
  def bedrock(
472
+ endpoint: nil,
375
473
  region: nil,
376
474
  base_url: OpenAI::Internal::OMIT,
377
475
  api_key: OpenAI::Internal::OMIT,
@@ -382,12 +480,12 @@ module OpenAI
382
480
  profile: nil,
383
481
  credentials_provider: nil
384
482
  )
483
+ normalized_endpoint = Bedrock.normalize_endpoint(endpoint)
385
484
  normalized_region = Bedrock.normalize_optional_string(region)
386
485
  if !region.nil? && normalized_region.nil?
387
486
  raise ArgumentError, "The Bedrock AWS `region` must not be empty."
388
487
  end
389
- normalized_region ||= Bedrock.normalize_optional_string(ENV["AWS_REGION"]) ||
390
- Bedrock.normalize_optional_string(ENV["AWS_DEFAULT_REGION"])
488
+ Bedrock.validate_region!(normalized_region) if normalized_region
391
489
 
392
490
  normalized_profile = Bedrock.normalize_optional_string(profile)
393
491
  if !profile.nil? && normalized_profile.nil?
@@ -405,6 +503,10 @@ module OpenAI
405
503
  normalized
406
504
  end
407
505
  configured_base_url = Bedrock.normalize_base_url(configured_base_url) if configured_base_url
506
+ canonical_endpoint = if configured_base_url
507
+ Bedrock.parse_endpoint_hostname(URI(configured_base_url).host)
508
+ end
509
+ resolved_endpoint = normalized_endpoint || canonical_endpoint&.fetch(:endpoint) || :mantle
408
510
 
409
511
  has_access_key = !access_key_id.nil?
410
512
  has_secret_key = !secret_access_key.nil?
@@ -467,11 +569,22 @@ module OpenAI
467
569
  end
468
570
  end
469
571
 
572
+ if normalized_region.nil? && (bearer_provider.nil? || configured_base_url.nil?)
573
+ normalized_region = Bedrock.normalize_optional_string(ENV["AWS_REGION"]) ||
574
+ Bedrock.normalize_optional_string(ENV["AWS_DEFAULT_REGION"])
575
+ Bedrock.validate_region!(normalized_region) if normalized_region
576
+ end
577
+
578
+ if configured_base_url
579
+ Bedrock.validate_canonical_endpoint!(configured_base_url, resolved_endpoint, normalized_region)
580
+ end
581
+
470
582
  if bearer_provider && configured_base_url.nil? && normalized_region.nil?
471
583
  raise ArgumentError, Bedrock::MISSING_REGION_MESSAGE
472
584
  end
473
585
 
474
586
  definition = Bedrock::Definition.new(
587
+ endpoint: resolved_endpoint,
475
588
  region: normalized_region,
476
589
  base_url: configured_base_url,
477
590
  bearer_provider: bearer_provider,
@@ -97,11 +97,11 @@ module OpenAI
97
97
  # @see OpenAI::Models::Admin::Organization::Projects::Groups::RoleListParams
98
98
  def list(group_id, params)
99
99
  parsed, options = OpenAI::Admin::Organization::Projects::Groups::RoleListParams.dump_request(params)
100
- query = OpenAI::Internal::Util.encode_query_params(parsed)
101
100
  project_id =
102
101
  parsed.delete(:project_id) do
103
102
  raise ArgumentError.new("missing required path argument #{_1}")
104
103
  end
104
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
105
105
  @client.request(
106
106
  method: :get,
107
107
  path: ["projects/%1$s/groups/%2$s/roles", project_id, group_id],
@@ -53,11 +53,11 @@ module OpenAI
53
53
  # @see OpenAI::Models::Admin::Organization::Projects::GroupRetrieveParams
54
54
  def retrieve(group_id, params)
55
55
  parsed, options = OpenAI::Admin::Organization::Projects::GroupRetrieveParams.dump_request(params)
56
- query = OpenAI::Internal::Util.encode_query_params(parsed)
57
56
  project_id =
58
57
  parsed.delete(:project_id) do
59
58
  raise ArgumentError.new("missing required path argument #{_1}")
60
59
  end
60
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
61
61
  @client.request(
62
62
  method: :get,
63
63
  path: ["organization/projects/%1$s/groups/%2$s", project_id, group_id],
@@ -97,11 +97,11 @@ module OpenAI
97
97
  # @see OpenAI::Models::Admin::Organization::Projects::Users::RoleListParams
98
98
  def list(user_id, params)
99
99
  parsed, options = OpenAI::Admin::Organization::Projects::Users::RoleListParams.dump_request(params)
100
- query = OpenAI::Internal::Util.encode_query_params(parsed)
101
100
  project_id =
102
101
  parsed.delete(:project_id) do
103
102
  raise ArgumentError.new("missing required path argument #{_1}")
104
103
  end
104
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
105
105
  @client.request(
106
106
  method: :get,
107
107
  path: ["projects/%1$s/users/%2$s/roles", project_id, user_id],
@@ -182,7 +182,8 @@ module OpenAI
182
182
  def initialize(client:)
183
183
  @client = client
184
184
  @users = OpenAI::Resources::Admin::Organization::Projects::Users.new(client: client)
185
- @service_accounts = OpenAI::Resources::Admin::Organization::Projects::ServiceAccounts.new(client: client)
185
+ @service_accounts =
186
+ OpenAI::Resources::Admin::Organization::Projects::ServiceAccounts.new(client: client)
186
187
  @api_keys = OpenAI::Resources::Admin::Organization::Projects::APIKeys.new(client: client)
187
188
  @rate_limits = OpenAI::Resources::Admin::Organization::Projects::RateLimits.new(client: client)
188
189
  @model_permissions =
@@ -191,7 +192,8 @@ module OpenAI
191
192
  OpenAI::Resources::Admin::Organization::Projects::HostedToolPermissions.new(client: client)
192
193
  @groups = OpenAI::Resources::Admin::Organization::Projects::Groups.new(client: client)
193
194
  @roles = OpenAI::Resources::Admin::Organization::Projects::Roles.new(client: client)
194
- @data_retention = OpenAI::Resources::Admin::Organization::Projects::DataRetention.new(client: client)
195
+ @data_retention =
196
+ OpenAI::Resources::Admin::Organization::Projects::DataRetention.new(client: client)
195
197
  @spend_limit = OpenAI::Resources::Admin::Organization::Projects::SpendLimit.new(client: client)
196
198
  @spend_alerts = OpenAI::Resources::Admin::Organization::Projects::SpendAlerts.new(client: client)
197
199
  @certificates = OpenAI::Resources::Admin::Organization::Projects::Certificates.new(client: client)
@@ -16,6 +16,10 @@ module OpenAI
16
16
  # Returns a transcription object in `json`, `diarized_json`, or `verbose_json`
17
17
  # format, or a stream of transcript events.
18
18
  #
19
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
20
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
21
+ # content type.
22
+ #
19
23
  # @overload create(file:, model:, chunking_strategy: nil, include: nil, keywords: nil, known_speaker_names: nil, known_speaker_references: nil, language: nil, languages: nil, prompt: nil, response_format: nil, temperature: nil, timestamp_granularities: nil, request_options: {})
20
24
  #
21
25
  # @param file [Pathname, StringIO, IO, String, OpenAI::FilePart] The audio file object (not file name) to transcribe, in one of these formats: fl
@@ -77,6 +81,10 @@ module OpenAI
77
81
  # Returns a transcription object in `json`, `diarized_json`, or `verbose_json`
78
82
  # format, or a stream of transcript events.
79
83
  #
84
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
85
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
86
+ # content type.
87
+ #
80
88
  # @overload create_streaming(file:, model:, chunking_strategy: nil, include: nil, keywords: nil, known_speaker_names: nil, known_speaker_references: nil, language: nil, languages: nil, prompt: nil, response_format: nil, temperature: nil, timestamp_granularities: nil, request_options: {})
81
89
  #
82
90
  # @param file [Pathname, StringIO, IO, String, OpenAI::FilePart] The audio file object (not file name) to transcribe, in one of these formats: fl
@@ -10,6 +10,10 @@ module OpenAI
10
10
  #
11
11
  # Translates audio into English.
12
12
  #
13
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
14
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
15
+ # content type.
16
+ #
13
17
  # @overload create(file:, model:, prompt: nil, response_format: nil, temperature: nil, request_options: {})
14
18
  #
15
19
  # @param file [Pathname, StringIO, IO, String, OpenAI::FilePart] The audio file object (not file name) translate, in one of these formats: flac,
@@ -301,12 +301,12 @@ module OpenAI
301
301
  def retrieve_streaming(response_id, params = {})
302
302
  query_params = [:include, :include_obfuscation, :starting_after, :stream]
303
303
  parsed, options = OpenAI::Beta::ResponseRetrieveParams.dump_request(params)
304
- query = OpenAI::Internal::Util.encode_query_params(parsed.slice(*query_params))
305
304
  unless parsed.fetch(:stream, true)
306
305
  message = "Please use `#retrieve` for the non-streaming use case."
307
306
  raise ArgumentError.new(message)
308
307
  end
309
308
  parsed.store(:stream, true)
309
+ query = OpenAI::Internal::Util.encode_query_params(parsed.slice(*query_params))
310
310
  @client.request(
311
311
  method: :get,
312
312
  path: ["responses/%1$s?beta=true", response_id],
@@ -33,7 +33,6 @@ module OpenAI
33
33
  # @see OpenAI::Models::Beta::Threads::Runs::StepRetrieveParams
34
34
  def retrieve(step_id, params)
35
35
  parsed, options = OpenAI::Beta::Threads::Runs::StepRetrieveParams.dump_request(params)
36
- query = OpenAI::Internal::Util.encode_query_params(parsed)
37
36
  thread_id =
38
37
  parsed.delete(:thread_id) do
39
38
  raise ArgumentError.new("missing required path argument #{_1}")
@@ -42,6 +41,7 @@ module OpenAI
42
41
  parsed.delete(:run_id) do
43
42
  raise ArgumentError.new("missing required path argument #{_1}")
44
43
  end
44
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
45
45
  @client.request(
46
46
  method: :get,
47
47
  path: ["threads/%1$s/runs/%2$s/steps/%3$s", thread_id, run_id, step_id],
@@ -82,11 +82,11 @@ module OpenAI
82
82
  # @see OpenAI::Models::Beta::Threads::Runs::StepListParams
83
83
  def list(run_id, params)
84
84
  parsed, options = OpenAI::Beta::Threads::Runs::StepListParams.dump_request(params)
85
- query = OpenAI::Internal::Util.encode_query_params(parsed)
86
85
  thread_id =
87
86
  parsed.delete(:thread_id) do
88
87
  raise ArgumentError.new("missing required path argument #{_1}")
89
88
  end
89
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
90
90
  @client.request(
91
91
  method: :get,
92
92
  path: ["threads/%1$s/runs/%2$s/steps", thread_id, run_id],
@@ -15,6 +15,10 @@ module OpenAI
15
15
  # You can send either a multipart/form-data request with the raw file content, or
16
16
  # a JSON request with a file ID.
17
17
  #
18
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
19
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
20
+ # content type.
21
+ #
18
22
  # @overload create(container_id, file: nil, file_id: nil, request_options: {})
19
23
  #
20
24
  # @param container_id [String]
@@ -13,6 +13,10 @@ module OpenAI
13
13
  # signals were available. Content could also still be AI-generated by another
14
14
  # company's model, which the tool currently does not detect.
15
15
  #
16
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
17
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
18
+ # content type.
19
+ #
16
20
  # @overload create(file:, request_options: {})
17
21
  #
18
22
  # @param file [Pathname, StringIO, IO, String, OpenAI::FilePart] The image or audio file to check for supported OpenAI provenance signals.
@@ -58,11 +58,11 @@ module OpenAI
58
58
  # @see OpenAI::Models::Conversations::ItemRetrieveParams
59
59
  def retrieve(item_id, params)
60
60
  parsed, options = OpenAI::Conversations::ItemRetrieveParams.dump_request(params)
61
- query = OpenAI::Internal::Util.encode_query_params(parsed)
62
61
  conversation_id =
63
62
  parsed.delete(:conversation_id) do
64
63
  raise ArgumentError.new("missing required path argument #{_1}")
65
64
  end
65
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
66
66
  @client.request(
67
67
  method: :get,
68
68
  path: ["conversations/%1$s/items/%2$s", conversation_id, item_id],
@@ -66,11 +66,11 @@ module OpenAI
66
66
  # @see OpenAI::Models::Evals::Runs::OutputItemListParams
67
67
  def list(run_id, params)
68
68
  parsed, options = OpenAI::Evals::Runs::OutputItemListParams.dump_request(params)
69
- query = OpenAI::Internal::Util.encode_query_params(parsed)
70
69
  eval_id =
71
70
  parsed.delete(:eval_id) do
72
71
  raise ArgumentError.new("missing required path argument #{_1}")
73
72
  end
73
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
74
74
  @client.request(
75
75
  method: :get,
76
76
  path: ["evals/%1$s/runs/%2$s/output_items", eval_id, run_id],
@@ -36,6 +36,10 @@ module OpenAI
36
36
  # Please [contact us](https://help.openai.com/) if you need to increase these
37
37
  # storage limits.
38
38
  #
39
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
40
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
41
+ # content type.
42
+ #
39
43
  # @overload create(file:, purpose:, expires_after: nil, request_options: {})
40
44
  #
41
45
  # @param file [Pathname, StringIO, IO, String, OpenAI::FilePart] The File object (not file name) to be uploaded.
@@ -138,7 +142,7 @@ module OpenAI
138
142
  )
139
143
  end
140
144
 
141
- # Returns the contents of the specified file.
145
+ # Returns a response containing the contents of the specified file.
142
146
  #
143
147
  # @overload content(file_id, request_options: {})
144
148
  #
@@ -9,6 +9,10 @@ module OpenAI
9
9
  #
10
10
  # Creates a variation of a given image. This endpoint only supports `dall-e-2`.
11
11
  #
12
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
13
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
14
+ # content type.
15
+ #
12
16
  # @overload create_variation(image:, model: nil, n: nil, response_format: nil, size: nil, user: nil, request_options: {})
13
17
  #
14
18
  # @param image [Pathname, StringIO, IO, String, OpenAI::FilePart] The image to use as the basis for the variation(s). Must be a valid PNG file, le
@@ -50,6 +54,10 @@ module OpenAI
50
54
  # prompt. This endpoint supports GPT Image models (`gpt-image-1.5`, `gpt-image-1`,
51
55
  # `gpt-image-1-mini`, and `chatgpt-image-latest`) and `dall-e-2`.
52
56
  #
57
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
58
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
59
+ # content type.
60
+ #
53
61
  # @overload edit(image:, prompt:, background: nil, input_fidelity: nil, mask: nil, model: nil, n: nil, output_compression: nil, output_format: nil, partial_images: nil, quality: nil, response_format: nil, size: nil, user: nil, request_options: {})
54
62
  #
55
63
  # @param image [Pathname, StringIO, IO, String, OpenAI::FilePart, Array<Pathname, StringIO, IO, String, OpenAI::FilePart>] The image(s) to edit. Must be a supported image file or an array of images.
@@ -111,6 +119,10 @@ module OpenAI
111
119
  # prompt. This endpoint supports GPT Image models (`gpt-image-1.5`, `gpt-image-1`,
112
120
  # `gpt-image-1-mini`, and `chatgpt-image-latest`) and `dall-e-2`.
113
121
  #
122
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
123
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
124
+ # content type.
125
+ #
114
126
  # @overload edit_stream_raw(image:, prompt:, background: nil, input_fidelity: nil, mask: nil, model: nil, n: nil, output_compression: nil, output_format: nil, partial_images: nil, quality: nil, response_format: nil, size: nil, user: nil, request_options: {})
115
127
  #
116
128
  # @param image [Pathname, StringIO, IO, String, OpenAI::FilePart, Array<Pathname, StringIO, IO, String, OpenAI::FilePart>] The image(s) to edit. Must be a supported image file or an array of images.
@@ -407,12 +407,12 @@ module OpenAI
407
407
  # @see OpenAI::Models::Responses::ResponseRetrieveParams
408
408
  def retrieve_streaming(response_id, params = {})
409
409
  parsed, options = OpenAI::Responses::ResponseRetrieveParams.dump_request(params)
410
- query = OpenAI::Internal::Util.encode_query_params(parsed)
411
410
  unless parsed.fetch(:stream, true)
412
411
  message = "Please use `#retrieve` for the non-streaming use case."
413
412
  raise ArgumentError.new(message)
414
413
  end
415
414
  parsed.store(:stream, true)
415
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
416
416
  @client.request(
417
417
  method: :get,
418
418
  path: ["responses/%1$s", response_id],
@@ -662,7 +662,8 @@ module OpenAI
662
662
  tool_models.store(name, params)
663
663
  tool[:function][:parameters] = params.to_json_schema
664
664
  tool
665
- in {type: _, function: Hash => func} if func[:parameters].is_a?(Class) && func[:parameters] < OpenAI::Internal::Type::BaseModel
665
+ in {type: _, function: Hash => func} if func[:parameters].is_a?(Class) &&
666
+ func[:parameters] < OpenAI::Internal::Type::BaseModel
666
667
  params = func[:parameters]
667
668
  name = func[:name] || params.name.split("::").last
668
669
  tool_models.store(name, params)
@@ -9,6 +9,10 @@ module OpenAI
9
9
 
10
10
  # Create a new immutable skill version.
11
11
  #
12
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
13
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
14
+ # content type.
15
+ #
12
16
  # @overload create(skill_id, default: nil, files: nil, request_options: {})
13
17
  #
14
18
  # @param skill_id [String] The identifier of the skill to version.
@@ -11,6 +11,10 @@ module OpenAI
11
11
 
12
12
  # Create a new skill.
13
13
  #
14
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
15
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
16
+ # content type.
17
+ #
14
18
  # @overload create(files: nil, request_options: {})
15
19
  #
16
20
  # @param files [Array<Pathname, StringIO, IO, String, OpenAI::FilePart>, Pathname, StringIO, IO, String, OpenAI::FilePart] Skill files to upload (directory upload) or a single zip file.
@@ -20,6 +20,10 @@ module OpenAI
20
20
  # order of the Parts when you
21
21
  # [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete).
22
22
  #
23
+ # `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
24
+ # metadata. Use `OpenAI::FilePart` when you need to override the filename or
25
+ # content type.
26
+ #
23
27
  # @overload create(upload_id, data:, request_options: {})
24
28
  #
25
29
  # @param upload_id [String] The ID of the Upload.
@@ -123,11 +123,11 @@ module OpenAI
123
123
  # @see OpenAI::Models::VectorStores::FileBatchListFilesParams
124
124
  def list_files(batch_id, params)
125
125
  parsed, options = OpenAI::VectorStores::FileBatchListFilesParams.dump_request(params)
126
- query = OpenAI::Internal::Util.encode_query_params(parsed)
127
126
  vector_store_id =
128
127
  parsed.delete(:vector_store_id) do
129
128
  raise ArgumentError.new("missing required path argument #{_1}")
130
129
  end
130
+ query = OpenAI::Internal::Util.encode_query_params(parsed)
131
131
  @client.request(
132
132
  method: :get,
133
133
  path: ["vector_stores/%1$s/file_batches/%2$s/files", vector_store_id, batch_id],