openai 0.83.0 → 0.85.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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/README.md +1 -1
  4. data/SECURITY.md +10 -0
  5. data/docs/architecture/security-model.md +267 -0
  6. data/lib/openai/auth/workload_identity_auth.rb +17 -2
  7. data/lib/openai/client.rb +24 -6
  8. data/lib/openai/errors.rb +1 -1
  9. data/lib/openai/helpers/streaming/chat_completion_stream.rb +18 -10
  10. data/lib/openai/helpers/streaming/response_events.rb +2 -2
  11. data/lib/openai/helpers/streaming/response_stream.rb +80 -44
  12. data/lib/openai/helpers/structured_output/array_of.rb +2 -2
  13. data/lib/openai/helpers/structured_output/base_model.rb +19 -5
  14. data/lib/openai/helpers/structured_output/chat_completion_parser.rb +12 -3
  15. data/lib/openai/helpers/structured_output/json_schema_converter.rb +34 -11
  16. data/lib/openai/helpers/structured_output/response_parser.rb +1 -1
  17. data/lib/openai/internal/type/base_model.rb +2 -2
  18. data/lib/openai/internal/type/converter.rb +1 -1
  19. data/lib/openai/internal/util.rb +2 -2
  20. data/lib/openai/internal/vector_store_file_uploader.rb +1 -1
  21. data/lib/openai/models/admin/organization/usage_costs_params.rb +10 -1
  22. data/lib/openai/models/batch.rb +4 -4
  23. data/lib/openai/models/beta/beta_custom_tool.rb +13 -1
  24. data/lib/openai/models/beta/beta_function_tool.rb +8 -1
  25. data/lib/openai/models/beta/beta_namespace_tool.rb +10 -1
  26. data/lib/openai/models/beta/beta_response.rb +26 -18
  27. data/lib/openai/models/beta/beta_response_configuration_update_item.rb +103 -0
  28. data/lib/openai/models/beta/beta_response_configuration_update_item_param.rb +104 -0
  29. data/lib/openai/models/beta/beta_response_custom_tool_call.rb +9 -1
  30. data/lib/openai/models/beta/beta_response_custom_tool_call_item.rb +3 -1
  31. data/lib/openai/models/beta/beta_response_error.rb +96 -1
  32. data/lib/openai/models/beta/beta_response_function_tool_call.rb +9 -1
  33. data/lib/openai/models/beta/beta_response_function_tool_call_item.rb +3 -1
  34. data/lib/openai/models/beta/beta_response_incomplete_event.rb +4 -0
  35. data/lib/openai/models/beta/beta_response_inject_event.rb +2 -2
  36. data/lib/openai/models/beta/beta_response_inject_failed_event.rb +2 -2
  37. data/lib/openai/models/beta/beta_response_input_item.rb +6 -1
  38. data/lib/openai/models/beta/beta_response_item.rb +5 -1
  39. data/lib/openai/models/beta/beta_response_steer_accepted_event.rb +81 -0
  40. data/lib/openai/models/beta/beta_response_steer_error_code.rb +61 -0
  41. data/lib/openai/models/beta/beta_response_steer_event.rb +75 -0
  42. data/lib/openai/models/beta/beta_response_steer_failed_event.rb +151 -0
  43. data/lib/openai/models/beta/beta_response_steer_input.rb +360 -0
  44. data/lib/openai/models/beta/beta_response_steer_input_content.rb +28 -0
  45. data/lib/openai/models/beta/beta_response_steer_pending_event.rb +113 -0
  46. data/lib/openai/models/beta/beta_response_steer_pending_reason.rb +26 -0
  47. data/lib/openai/models/beta/beta_response_steer_required_input.rb +215 -0
  48. data/lib/openai/models/beta/beta_response_stream_event.rb +4 -0
  49. data/lib/openai/models/beta/beta_response_usage.rb +1 -12
  50. data/lib/openai/models/beta/beta_responses_client_event.rb +45 -16
  51. data/lib/openai/models/beta/beta_responses_server_event.rb +164 -2
  52. data/lib/openai/models/beta/response_compact_params.rb +13 -10
  53. data/lib/openai/models/beta/response_create_params.rb +14 -15
  54. data/lib/openai/models/beta/responses/beta_response_item_list.rb +2 -2
  55. data/lib/openai/models/beta/responses/input_token_count_params.rb +3 -3
  56. data/lib/openai/models/chat/completion_create_params.rb +8 -8
  57. data/lib/openai/models/chat_model.rb +1 -0
  58. data/lib/openai/models/completion_usage.rb +1 -12
  59. data/lib/openai/models/conversations/conversation_create_params.rb +2 -2
  60. data/lib/openai/models/conversations/conversation_item.rb +5 -1
  61. data/lib/openai/models/conversations/conversation_item_list.rb +2 -2
  62. data/lib/openai/models/conversations/item_create_params.rb +2 -2
  63. data/lib/openai/models/error_object.rb +90 -1
  64. data/lib/openai/models/eval_create_response.rb +1 -1
  65. data/lib/openai/models/eval_list_response.rb +1 -1
  66. data/lib/openai/models/eval_retrieve_response.rb +1 -1
  67. data/lib/openai/models/eval_update_response.rb +1 -1
  68. data/lib/openai/models/evals/create_eval_completions_run_data_source.rb +2 -2
  69. data/lib/openai/models/reasoning.rb +0 -2
  70. data/lib/openai/models/responses/custom_tool.rb +13 -1
  71. data/lib/openai/models/responses/function_tool.rb +8 -1
  72. data/lib/openai/models/responses/input_token_count_params.rb +3 -3
  73. data/lib/openai/models/responses/namespace_tool.rb +10 -1
  74. data/lib/openai/models/responses/response.rb +20 -13
  75. data/lib/openai/models/responses/response_compact_params.rb +13 -10
  76. data/lib/openai/models/responses/response_configuration_update_item.rb +56 -0
  77. data/lib/openai/models/responses/response_configuration_update_item_param.rb +57 -0
  78. data/lib/openai/models/responses/response_create_params.rb +8 -10
  79. data/lib/openai/models/responses/response_custom_tool_call.rb +9 -1
  80. data/lib/openai/models/responses/response_custom_tool_call_item.rb +3 -1
  81. data/lib/openai/models/responses/response_error.rb +96 -1
  82. data/lib/openai/models/responses/response_function_tool_call.rb +9 -1
  83. data/lib/openai/models/responses/response_function_tool_call_item.rb +3 -1
  84. data/lib/openai/models/responses/response_incomplete_event.rb +4 -0
  85. data/lib/openai/models/responses/response_input_item.rb +6 -1
  86. data/lib/openai/models/responses/response_item.rb +5 -1
  87. data/lib/openai/models/responses/response_item_list.rb +2 -2
  88. data/lib/openai/models/responses/response_steer_accepted_event.rb +79 -0
  89. data/lib/openai/models/responses/response_steer_error_code.rb +59 -0
  90. data/lib/openai/models/responses/response_steer_event.rb +73 -0
  91. data/lib/openai/models/responses/response_steer_failed_event.rb +149 -0
  92. data/lib/openai/models/responses/response_steer_input.rb +304 -0
  93. data/lib/openai/models/responses/response_steer_input_content.rb +26 -0
  94. data/lib/openai/models/responses/response_steer_pending_event.rb +111 -0
  95. data/lib/openai/models/responses/response_steer_pending_reason.rb +24 -0
  96. data/lib/openai/models/responses/response_steer_required_input.rb +213 -0
  97. data/lib/openai/models/responses/response_stream_event.rb +4 -0
  98. data/lib/openai/models/responses/response_usage.rb +1 -12
  99. data/lib/openai/models/responses/responses_client_event.rb +872 -771
  100. data/lib/openai/models/responses/responses_server_event.rb +162 -2
  101. data/lib/openai/models/safety/alert_retrieve_params.rb +24 -0
  102. data/lib/openai/models/safety/safety_alert.rb +96 -0
  103. data/lib/openai/models/video_create_error.rb +93 -1
  104. data/lib/openai/models/webhooks/safety_alert_created_webhook_event.rb +63 -0
  105. data/lib/openai/models/webhooks/safety_org_alert_created_webhook_event.rb +63 -0
  106. data/lib/openai/models/webhooks/unwrap_webhook_event.rb +7 -1
  107. data/lib/openai/models.rb +2 -0
  108. data/lib/openai/net_http_client.rb +1 -1
  109. data/lib/openai/providers/bedrock.rb +20 -12
  110. data/lib/openai/resources/admin/organization/usage.rb +3 -1
  111. data/lib/openai/resources/beta/responses/input_items.rb +1 -1
  112. data/lib/openai/resources/beta/responses/input_tokens.rb +1 -1
  113. data/lib/openai/resources/beta/responses.rb +8 -8
  114. data/lib/openai/resources/chat/completions.rb +2 -2
  115. data/lib/openai/resources/conversations/items.rb +3 -3
  116. data/lib/openai/resources/conversations.rb +1 -1
  117. data/lib/openai/resources/responses/input_items.rb +1 -1
  118. data/lib/openai/resources/responses/input_tokens.rb +1 -1
  119. data/lib/openai/resources/responses.rb +10 -9
  120. data/lib/openai/resources/safety/alerts.rb +37 -0
  121. data/lib/openai/resources/safety.rb +18 -0
  122. data/lib/openai/resources/webhooks.rb +1 -1
  123. data/lib/openai/version.rb +1 -1
  124. data/lib/openai.rb +29 -0
  125. data/rbi/openai/client.rbi +3 -0
  126. data/rbi/openai/errors.rbi +1 -1
  127. data/rbi/openai/helpers/streaming/events.rbi +2 -2
  128. data/rbi/openai/helpers/streaming/response_stream.rbi +3 -3
  129. data/rbi/openai/models/admin/organization/usage_costs_params.rbi +15 -0
  130. data/rbi/openai/models/batch.rbi +6 -6
  131. data/rbi/openai/models/beta/beta_custom_tool.rbi +15 -0
  132. data/rbi/openai/models/beta/beta_function_tool.rbi +11 -0
  133. data/rbi/openai/models/beta/beta_namespace_tool.rbi +15 -0
  134. data/rbi/openai/models/beta/beta_response.rbi +21 -18
  135. data/rbi/openai/models/beta/beta_response_configuration_update_item.rbi +200 -0
  136. data/rbi/openai/models/beta/beta_response_configuration_update_item_param.rbi +207 -0
  137. data/rbi/openai/models/beta/beta_response_custom_tool_call.rbi +13 -0
  138. data/rbi/openai/models/beta/beta_response_custom_tool_call_item.rbi +6 -0
  139. data/rbi/openai/models/beta/beta_response_error.rbi +161 -3
  140. data/rbi/openai/models/beta/beta_response_function_tool_call.rbi +13 -0
  141. data/rbi/openai/models/beta/beta_response_function_tool_call_item.rbi +6 -0
  142. data/rbi/openai/models/beta/beta_response_incomplete_event.rbi +4 -0
  143. data/rbi/openai/models/beta/beta_response_inject_event.rbi +3 -0
  144. data/rbi/openai/models/beta/beta_response_inject_failed_event.rbi +3 -0
  145. data/rbi/openai/models/beta/beta_response_input_item.rbi +1 -0
  146. data/rbi/openai/models/beta/beta_response_item.rbi +1 -0
  147. data/rbi/openai/models/beta/beta_response_steer_accepted_event.rbi +148 -0
  148. data/rbi/openai/models/beta/beta_response_steer_error_code.rbi +65 -0
  149. data/rbi/openai/models/beta/beta_response_steer_event.rbi +118 -0
  150. data/rbi/openai/models/beta/beta_response_steer_failed_event.rbi +267 -0
  151. data/rbi/openai/models/beta/beta_response_steer_input.rbi +602 -0
  152. data/rbi/openai/models/beta/beta_response_steer_input_content.rbi +31 -0
  153. data/rbi/openai/models/beta/beta_response_steer_pending_event.rbi +222 -0
  154. data/rbi/openai/models/beta/beta_response_steer_pending_reason.rbi +35 -0
  155. data/rbi/openai/models/beta/beta_response_steer_required_input.rbi +379 -0
  156. data/rbi/openai/models/beta/beta_response_usage.rbi +3 -13
  157. data/rbi/openai/models/beta/beta_responses_client_event.rbi +14 -15
  158. data/rbi/openai/models/beta/beta_responses_server_event.rbi +206 -3
  159. data/rbi/openai/models/beta/response_compact_params.rbi +10 -9
  160. data/rbi/openai/models/beta/response_create_params.rbi +10 -15
  161. data/rbi/openai/models/beta/responses/beta_response_item_list.rbi +1 -0
  162. data/rbi/openai/models/chat/completion_create_params.rbi +9 -9
  163. data/rbi/openai/models/chat_model.rbi +1 -0
  164. data/rbi/openai/models/completion_usage.rbi +0 -10
  165. data/rbi/openai/models/conversations/conversation_create_params.rbi +3 -0
  166. data/rbi/openai/models/conversations/conversation_item.rbi +1 -0
  167. data/rbi/openai/models/conversations/conversation_item_list.rbi +1 -0
  168. data/rbi/openai/models/conversations/item_create_params.rbi +3 -0
  169. data/rbi/openai/models/error_object.rbi +156 -3
  170. data/rbi/openai/models/eval_create_response.rbi +1 -1
  171. data/rbi/openai/models/eval_list_response.rbi +1 -1
  172. data/rbi/openai/models/eval_retrieve_response.rbi +1 -1
  173. data/rbi/openai/models/eval_update_response.rbi +1 -1
  174. data/rbi/openai/models/evals/create_eval_completions_run_data_source.rbi +2 -2
  175. data/rbi/openai/models/reasoning.rbi +0 -2
  176. data/rbi/openai/models/responses/custom_tool.rbi +15 -0
  177. data/rbi/openai/models/responses/function_tool.rbi +11 -0
  178. data/rbi/openai/models/responses/namespace_tool.rbi +15 -0
  179. data/rbi/openai/models/responses/response.rbi +17 -13
  180. data/rbi/openai/models/responses/response_compact_params.rbi +10 -9
  181. data/rbi/openai/models/responses/response_configuration_update_item.rbi +112 -0
  182. data/rbi/openai/models/responses/response_configuration_update_item_param.rbi +117 -0
  183. data/rbi/openai/models/responses/response_create_params.rbi +6 -10
  184. data/rbi/openai/models/responses/response_custom_tool_call.rbi +13 -0
  185. data/rbi/openai/models/responses/response_custom_tool_call_item.rbi +6 -0
  186. data/rbi/openai/models/responses/response_error.rbi +161 -3
  187. data/rbi/openai/models/responses/response_function_tool_call.rbi +13 -0
  188. data/rbi/openai/models/responses/response_function_tool_call_item.rbi +6 -0
  189. data/rbi/openai/models/responses/response_incomplete_event.rbi +4 -0
  190. data/rbi/openai/models/responses/response_input_item.rbi +1 -0
  191. data/rbi/openai/models/responses/response_item.rbi +1 -0
  192. data/rbi/openai/models/responses/response_item_list.rbi +1 -0
  193. data/rbi/openai/models/responses/response_steer_accepted_event.rbi +146 -0
  194. data/rbi/openai/models/responses/response_steer_error_code.rbi +63 -0
  195. data/rbi/openai/models/responses/response_steer_event.rbi +119 -0
  196. data/rbi/openai/models/responses/response_steer_failed_event.rbi +268 -0
  197. data/rbi/openai/models/responses/response_steer_input.rbi +474 -0
  198. data/rbi/openai/models/responses/response_steer_input_content.rbi +29 -0
  199. data/rbi/openai/models/responses/response_steer_pending_event.rbi +220 -0
  200. data/rbi/openai/models/responses/response_steer_pending_reason.rbi +33 -0
  201. data/rbi/openai/models/responses/response_steer_required_input.rbi +377 -0
  202. data/rbi/openai/models/responses/response_usage.rbi +3 -13
  203. data/rbi/openai/models/responses/responses_client_event.rbi +1205 -1041
  204. data/rbi/openai/models/responses/responses_server_event.rbi +202 -3
  205. data/rbi/openai/models/safety/alert_retrieve_params.rbi +55 -0
  206. data/rbi/openai/models/safety/safety_alert.rbi +147 -0
  207. data/rbi/openai/models/video_create_error.rbi +149 -3
  208. data/rbi/openai/models/webhooks/safety_alert_created_webhook_event.rbi +130 -0
  209. data/rbi/openai/models/webhooks/safety_org_alert_created_webhook_event.rbi +130 -0
  210. data/rbi/openai/models/webhooks/unwrap_webhook_event.rbi +3 -1
  211. data/rbi/openai/models.rbi +2 -0
  212. data/rbi/openai/resources/admin/organization/usage.rbi +4 -0
  213. data/rbi/openai/resources/beta/responses.rbi +7 -11
  214. data/rbi/openai/resources/chat/completions.rbi +6 -6
  215. data/rbi/openai/resources/conversations/items.rbi +1 -0
  216. data/rbi/openai/resources/conversations.rbi +1 -0
  217. data/rbi/openai/resources/responses.rbi +9 -13
  218. data/rbi/openai/resources/safety/alerts.rbi +30 -0
  219. data/rbi/openai/resources/safety.rbi +18 -0
  220. data/rbi/openai/resources/webhooks.rbi +3 -1
  221. data/sig/openai/client.rbs +2 -0
  222. data/sig/openai/errors.rbs +1 -1
  223. data/sig/openai/internal/transport/base_client.rbs +4 -19
  224. data/sig/openai/models/admin/organization/usage_costs_params.rbs +7 -0
  225. data/sig/openai/models/beta/beta_custom_tool.rbs +7 -0
  226. data/sig/openai/models/beta/beta_function_tool.rbs +7 -0
  227. data/sig/openai/models/beta/beta_namespace_tool.rbs +7 -0
  228. data/sig/openai/models/beta/beta_response.rbs +7 -2
  229. data/sig/openai/models/beta/beta_response_configuration_update_item.rbs +91 -0
  230. data/sig/openai/models/beta/beta_response_configuration_update_item_param.rbs +87 -0
  231. data/sig/openai/models/beta/beta_response_custom_tool_call.rbs +7 -0
  232. data/sig/openai/models/beta/beta_response_custom_tool_call_item.rbs +3 -0
  233. data/sig/openai/models/beta/beta_response_error.rbs +82 -3
  234. data/sig/openai/models/beta/beta_response_function_tool_call.rbs +7 -0
  235. data/sig/openai/models/beta/beta_response_function_tool_call_item.rbs +3 -0
  236. data/sig/openai/models/beta/beta_response_input_item.rbs +1 -0
  237. data/sig/openai/models/beta/beta_response_item.rbs +1 -0
  238. data/sig/openai/models/beta/beta_response_steer_accepted_event.rbs +53 -0
  239. data/sig/openai/models/beta/beta_response_steer_error_code.rbs +31 -0
  240. data/sig/openai/models/beta/beta_response_steer_event.rbs +34 -0
  241. data/sig/openai/models/beta/beta_response_steer_failed_event.rbs +102 -0
  242. data/sig/openai/models/beta/beta_response_steer_input.rbs +214 -0
  243. data/sig/openai/models/beta/beta_response_steer_input_content.rbs +18 -0
  244. data/sig/openai/models/beta/beta_response_steer_pending_event.rbs +63 -0
  245. data/sig/openai/models/beta/beta_response_steer_pending_reason.rbs +16 -0
  246. data/sig/openai/models/beta/beta_response_steer_required_input.rbs +161 -0
  247. data/sig/openai/models/beta/beta_response_usage.rbs +3 -8
  248. data/sig/openai/models/beta/beta_responses_client_event.rbs +4 -1
  249. data/sig/openai/models/beta/beta_responses_server_event.rbs +80 -3
  250. data/sig/openai/models/beta/response_compact_params.rbs +3 -1
  251. data/sig/openai/models/beta/response_create_params.rbs +3 -1
  252. data/sig/openai/models/chat_model.rbs +3 -1
  253. data/sig/openai/models/completion_usage.rbs +0 -5
  254. data/sig/openai/models/conversations/conversation_item.rbs +1 -0
  255. data/sig/openai/models/error_object.rbs +82 -3
  256. data/sig/openai/models/responses/custom_tool.rbs +7 -0
  257. data/sig/openai/models/responses/function_tool.rbs +7 -0
  258. data/sig/openai/models/responses/namespace_tool.rbs +7 -0
  259. data/sig/openai/models/responses/response.rbs +4 -1
  260. data/sig/openai/models/responses/response_compact_params.rbs +3 -1
  261. data/sig/openai/models/responses/response_configuration_update_item.rbs +46 -0
  262. data/sig/openai/models/responses/response_configuration_update_item_param.rbs +46 -0
  263. data/sig/openai/models/responses/response_custom_tool_call.rbs +7 -0
  264. data/sig/openai/models/responses/response_custom_tool_call_item.rbs +3 -0
  265. data/sig/openai/models/responses/response_error.rbs +79 -3
  266. data/sig/openai/models/responses/response_function_tool_call.rbs +7 -0
  267. data/sig/openai/models/responses/response_function_tool_call_item.rbs +3 -0
  268. data/sig/openai/models/responses/response_input_item.rbs +1 -0
  269. data/sig/openai/models/responses/response_item.rbs +1 -0
  270. data/sig/openai/models/responses/response_steer_accepted_event.rbs +51 -0
  271. data/sig/openai/models/responses/response_steer_error_code.rbs +29 -0
  272. data/sig/openai/models/responses/response_steer_event.rbs +32 -0
  273. data/sig/openai/models/responses/response_steer_failed_event.rbs +100 -0
  274. data/sig/openai/models/responses/response_steer_input.rbs +182 -0
  275. data/sig/openai/models/responses/response_steer_input_content.rbs +16 -0
  276. data/sig/openai/models/responses/response_steer_pending_event.rbs +61 -0
  277. data/sig/openai/models/responses/response_steer_pending_reason.rbs +13 -0
  278. data/sig/openai/models/responses/response_steer_required_input.rbs +159 -0
  279. data/sig/openai/models/responses/response_usage.rbs +3 -8
  280. data/sig/openai/models/responses/responses_client_event.rbs +355 -344
  281. data/sig/openai/models/responses/responses_server_event.rbs +80 -3
  282. data/sig/openai/models/safety/alert_retrieve_params.rbs +22 -0
  283. data/sig/openai/models/safety/safety_alert.rbs +81 -0
  284. data/sig/openai/models/video_create_error.rbs +87 -3
  285. data/sig/openai/models/webhooks/safety_alert_created_webhook_event.rbs +52 -0
  286. data/sig/openai/models/webhooks/safety_org_alert_created_webhook_event.rbs +52 -0
  287. data/sig/openai/models/webhooks/unwrap_webhook_event.rbs +2 -0
  288. data/sig/openai/models.rbs +2 -0
  289. data/sig/openai/resources/admin/organization/usage.rbs +1 -0
  290. data/sig/openai/resources/safety/alerts.rbs +14 -0
  291. data/sig/openai/resources/safety.rbs +9 -0
  292. data/sig/openai/resources/webhooks.rbs +3 -1
  293. metadata +86 -1
@@ -13,7 +13,8 @@ module OpenAI
13
13
  @last_response = raw_stream.last_response
14
14
  @iterator = iterator
15
15
  @state = ResponseStreamState.new(
16
- text_format: text_format
16
+ text_format: text_format,
17
+ starting_after: starting_after
17
18
  )
18
19
  end
19
20
 
@@ -26,7 +27,7 @@ module OpenAI
26
27
  OpenAI::Internal::Util.chain_fused(@iterator) do |yielder|
27
28
  @iterator.each do |event|
28
29
  case event
29
- when OpenAI::Streaming::ResponseTextDeltaEvent
30
+ when OpenAI::Models::Responses::ResponseTextDeltaEvent
30
31
  yielder << event.delta
31
32
  end
32
33
  end
@@ -80,10 +81,11 @@ module OpenAI
80
81
  class ResponseStreamState
81
82
  attr_reader :completed_response
82
83
 
83
- def initialize(text_format:)
84
+ def initialize(text_format:, starting_after: nil)
84
85
  @current_snapshot = nil
85
86
  @completed_response = nil
86
87
  @text_format = text_format
88
+ @resumed = !starting_after.nil?
87
89
  end
88
90
 
89
91
  def handle_event(event)
@@ -98,31 +100,43 @@ module OpenAI
98
100
 
99
101
  case event
100
102
  when OpenAI::Models::Responses::ResponseTextDeltaEvent
101
- output = @current_snapshot.output[event.output_index]
102
- assert_type(output, :message)
103
+ if @current_snapshot
104
+ output = @current_snapshot.output[event.output_index]
105
+ assert_type(output, :message)
103
106
 
104
- content = output.content[event.content_index]
105
- assert_type(content, :output_text)
106
-
107
- events_to_yield <<
108
- OpenAI::Streaming::ResponseTextDeltaEvent.new(
109
- content_index: event.content_index,
110
- delta: event.delta,
111
- item_id: event.item_id,
112
- output_index: event.output_index,
113
- sequence_number: event.sequence_number,
114
- type: event.type,
115
- snapshot: content.text
116
- )
107
+ content = output.content[event.content_index]
108
+ assert_type(content, :output_text)
109
+ events_to_yield <<
110
+ OpenAI::Streaming::ResponseTextDeltaEvent.new(
111
+ content_index: event.content_index,
112
+ delta: event.delta,
113
+ item_id: event.item_id,
114
+ output_index: event.output_index,
115
+ sequence_number: event.sequence_number,
116
+ type: event.type,
117
+ snapshot: content.text
118
+ )
119
+ else
120
+ # A server-directed resumed stream may begin after response.created.
121
+ # Without the omitted prefix, a snapshot would be incomplete and
122
+ # materializing every partial prefix would make streaming quadratic.
123
+ events_to_yield <<
124
+ OpenAI::Streaming::ResponseTextDeltaEvent.new(event.to_h.merge(snapshot: nil))
125
+ end
117
126
 
118
127
  when OpenAI::Models::Responses::ResponseTextDoneEvent
119
- output = @current_snapshot.output[event.output_index]
120
- assert_type(output, :message)
128
+ text = if @current_snapshot
129
+ output = @current_snapshot.output[event.output_index]
130
+ assert_type(output, :message)
121
131
 
122
- content = output.content[event.content_index]
123
- assert_type(content, :output_text)
132
+ content = output.content[event.content_index]
133
+ assert_type(content, :output_text)
134
+ content.text
135
+ else
136
+ event.text
137
+ end
124
138
 
125
- parsed = parse_structured_text(content.text)
139
+ parsed = parse_structured_text(text)
126
140
 
127
141
  events_to_yield <<
128
142
  OpenAI::Streaming::ResponseTextDoneEvent.new(
@@ -136,18 +150,26 @@ module OpenAI
136
150
  )
137
151
 
138
152
  when OpenAI::Models::Responses::ResponseFunctionCallArgumentsDeltaEvent
139
- output = @current_snapshot.output[event.output_index]
140
- assert_type(output, :function_call)
141
-
142
- events_to_yield <<
143
- OpenAI::Streaming::ResponseFunctionCallArgumentsDeltaEvent.new(
144
- delta: event.delta,
145
- item_id: event.item_id,
146
- output_index: event.output_index,
147
- sequence_number: event.sequence_number,
148
- type: event.type,
149
- snapshot: output.arguments
150
- )
153
+ if @current_snapshot
154
+ output = @current_snapshot.output[event.output_index]
155
+ assert_type(output, :function_call)
156
+ events_to_yield <<
157
+ OpenAI::Streaming::ResponseFunctionCallArgumentsDeltaEvent.new(
158
+ delta: event.delta,
159
+ item_id: event.item_id,
160
+ output_index: event.output_index,
161
+ sequence_number: event.sequence_number,
162
+ type: event.type,
163
+ snapshot: output.arguments
164
+ )
165
+ else
166
+ # See the text-delta branch above: a partial server resume has no
167
+ # complete argument prefix from which to build a truthful snapshot.
168
+ events_to_yield <<
169
+ OpenAI::Streaming::ResponseFunctionCallArgumentsDeltaEvent.new(
170
+ event.to_h.merge(snapshot: nil)
171
+ )
172
+ end
151
173
 
152
174
  when OpenAI::Models::Responses::ResponseCompletedEvent
153
175
  events_to_yield <<
@@ -167,26 +189,30 @@ module OpenAI
167
189
 
168
190
  def accumulate_event(event:, current_snapshot:)
169
191
  if current_snapshot.nil?
170
- unless event.is_a?(OpenAI::Models::Responses::ResponseCreatedEvent)
192
+ if event.is_a?(OpenAI::Models::Responses::ResponseCreatedEvent)
193
+ return isolated_value(event.response)
194
+ end
195
+
196
+ unless @resumed
171
197
  raise "Expected first event to be response.created"
172
198
  end
173
199
 
174
- # Use the converter to create a new, isolated copy of the response object.
175
- # This ensures proper type validation and prevents shared object references.
176
- return OpenAI::Internal::Type::Converter.coerce(
177
- OpenAI::Models::Responses::Response,
178
- event.response
179
- )
200
+ if event.is_a?(OpenAI::Models::Responses::ResponseCompletedEvent)
201
+ @completed_response = event.response
202
+ return event.response
203
+ end
204
+
205
+ return nil
180
206
  end
181
207
 
182
208
  case event
183
209
  when OpenAI::Models::Responses::ResponseOutputItemAddedEvent
184
- current_snapshot.output.push(event.item)
210
+ current_snapshot.output.push(isolated_value(event.item))
185
211
 
186
212
  when OpenAI::Models::Responses::ResponseContentPartAddedEvent
187
213
  output = current_snapshot.output[event.output_index]
188
214
  if output && output.type == :message
189
- output.content.push(event.part)
215
+ output.content.push(isolated_value(event.part))
190
216
  current_snapshot.output[event.output_index] = output
191
217
  end
192
218
 
@@ -217,6 +243,16 @@ module OpenAI
217
243
 
218
244
  private
219
245
 
246
+ # Materialize fresh containers before snapshot accumulation mutates them.
247
+ # Coercing an already-typed model returns it unchanged, so first use the
248
+ # model's recursive raw representation. Unknown union fallbacks stay raw.
249
+ def isolated_value(value)
250
+ raw = OpenAI::Internal::Type::BaseModel.recursively_to_h(value, convert: false)
251
+ return raw unless value.is_a?(OpenAI::Internal::Type::BaseModel)
252
+
253
+ OpenAI::Internal::Type::Converter.coerce(value.class, raw)
254
+ end
255
+
220
256
  def assert_type(object, expected_type)
221
257
  return if object && object.type == expected_type
222
258
  actual_type = object ? object.type : "nil"
@@ -24,10 +24,10 @@ module OpenAI
24
24
  # @return [Hash{Symbol=>Object}]
25
25
  def to_json_schema_inner(state:)
26
26
  OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.cache_def!(state, type: self) do
27
- state.fetch(:path) << "[]"
27
+ new_state = {**state, path: [*state.fetch(:path), "[]"]}
28
28
  items = OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.to_json_schema_inner(
29
29
  item_type,
30
- state: state
30
+ state: new_state
31
31
  )
32
32
  items = OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.to_nilable(items) if nilable?
33
33
  OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.assoc_meta!(items, meta: @meta)
@@ -32,13 +32,27 @@ module OpenAI
32
32
  OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.cache_def!(state, type: self) do
33
33
  path = state.fetch(:path)
34
34
  properties = field_values.to_h do |field|
35
- api_name, type, nilable, meta = field.fetch_values(:api_name, :type, :nilable, :meta)
35
+ api_name, type, nilable, const, meta = field.fetch_values(:api_name, :type, :nilable, :const, :meta)
36
36
  new_state = {**state, path: [*path, ".#{api_name}"]}
37
37
 
38
- schema = OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.to_json_schema_inner(
39
- type,
40
- state: new_state
41
- )
38
+ literal_const = case const
39
+ when Integer, TrueClass, FalseClass
40
+ true
41
+ when Float
42
+ const.finite?
43
+ else
44
+ false
45
+ end
46
+
47
+ schema = if literal_const
48
+ {const: const}
49
+ else
50
+ OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.to_json_schema_inner(
51
+ type,
52
+ state: new_state
53
+ )
54
+ end
55
+
42
56
  schema = OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.to_nilable(schema) if nilable
43
57
  OpenAI::Helpers::StructuredOutput::JsonSchemaConverter.assoc_meta!(
44
58
  schema,
@@ -28,6 +28,8 @@ module OpenAI
28
28
 
29
29
  raw[:choices]&.each do |choice|
30
30
  choice.dig(:message, :tool_calls)&.each do |tool_call|
31
+ next if tool_call[:type] == "custom"
32
+
31
33
  func = tool_call.fetch(:function)
32
34
  next if (model = tool_models[func.fetch(:name)]).nil?
33
35
 
@@ -65,7 +67,10 @@ module OpenAI
65
67
  }
66
68
  )
67
69
  in {
68
- response_format: {type: :json_schema, json_schema: OpenAI::StructuredOutput::JsonSchemaConverter => model}
70
+ response_format: {
71
+ type: :json_schema | "json_schema",
72
+ json_schema: OpenAI::StructuredOutput::JsonSchemaConverter => model
73
+ }
69
74
  }
70
75
  parsed.fetch(:response_format).update(
71
76
  json_schema: {
@@ -76,11 +81,15 @@ module OpenAI
76
81
  )
77
82
  in {
78
83
  response_format: {
79
- type: :json_schema,
84
+ type: :json_schema | "json_schema",
80
85
  json_schema: {schema: OpenAI::StructuredOutput::JsonSchemaConverter => model}
81
86
  }
82
87
  }
83
88
  parsed.dig(:response_format, :json_schema).store(:schema, model.to_json_schema)
89
+ else
90
+ end
91
+
92
+ case parsed
84
93
  in {tools: Array => tools}
85
94
  mapped = tools.map do |tool|
86
95
  case tool
@@ -118,7 +127,7 @@ module OpenAI
118
127
  return [] if tools.nil?
119
128
 
120
129
  tools.map do |tool|
121
- next tool unless tool[:type] == :function
130
+ next tool unless [:function, "function"].include?(tool[:type])
122
131
 
123
132
  function_name = tool.dig(:function, :name)
124
133
  model = tool_models[function_name]
@@ -23,6 +23,15 @@ module OpenAI
23
23
  end
24
24
  end
25
25
  .freeze
26
+ # @api private
27
+ RECURSIVE = Object
28
+ .new
29
+ .tap do
30
+ _1.define_singleton_method(:inspect) do
31
+ "#<#{OpenAI::Helpers::StructuredOutput::JsonSchemaConverter}::RECURSIVE>"
32
+ end
33
+ end
34
+ .freeze
26
35
 
27
36
  # rubocop:disable Lint/UnusedMethodArgument
28
37
 
@@ -56,6 +65,8 @@ module OpenAI
56
65
  {type: null}
57
66
  ]
58
67
  }
68
+ in {const: _}
69
+ {anyOf: [schema, {type: null}]}
59
70
  in {anyOf: schemas}
60
71
  null = {type: null}
61
72
  schemas.any? { _1 == null || _1 == {type: ["null"]} } ? schema : {anyOf: [*schemas, null]}
@@ -94,6 +105,10 @@ module OpenAI
94
105
  defs, path = state.fetch_values(:defs, :path)
95
106
  if (stored = defs[type])
96
107
  pointers = stored.fetch(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::POINTERS)
108
+ if pointers.first.fetch(:$ref).empty?
109
+ stored[OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::RECURSIVE] = true
110
+ end
111
+
97
112
  pointers.first.except(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::NO_REF).tap do
98
113
  pointers << _1
99
114
  end
@@ -128,27 +143,35 @@ module OpenAI
128
143
  )
129
144
  reused_defs = {}
130
145
  defs.each_value do |acc|
131
- sch = acc.except(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::POINTERS)
146
+ recursive = acc.key?(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::RECURSIVE)
147
+ sch = acc.except(
148
+ OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::POINTERS,
149
+ OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::RECURSIVE
150
+ )
132
151
  pointers = acc.fetch(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::POINTERS)
133
152
 
134
153
  no_refs, refs = pointers.partition do
135
154
  _1.delete(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::NO_REF)
136
155
  end
137
156
 
138
- case refs
139
- in [ref]
140
- ref.replace(ref.except(:$ref).merge(sch))
141
- in [_, ref, *]
142
- reused_defs.store(ref.fetch(:$ref), sch)
143
- refs.each do
144
- unless (meta = _1.except(:$ref)).empty?
145
- _1.replace(allOf: [_1.slice(:$ref), meta])
157
+ if recursive
158
+ reused_defs.store(pointers.first.fetch(:$ref), sch)
159
+ else
160
+ case refs
161
+ in [ref]
162
+ ref.replace(ref.except(:$ref).merge(sch))
163
+ in [_, ref, *]
164
+ reused_defs.store(ref.fetch(:$ref), sch)
165
+ refs.each do
166
+ unless (meta = _1.except(:$ref)).empty?
167
+ _1.replace(allOf: [_1.slice(:$ref), meta])
168
+ end
146
169
  end
170
+ else
147
171
  end
148
- else
149
172
  end
150
173
 
151
- no_refs.each { _1.replace(_1.except(:$ref).merge(sch)) }
174
+ no_refs.each { _1.replace(_1.except(:$ref).merge(sch)) } unless recursive
152
175
  end
153
176
 
154
177
  xformed = reused_defs.transform_keys do
@@ -109,7 +109,7 @@ module OpenAI
109
109
  parameters: tool.to_json_schema
110
110
  }
111
111
  in {type: :function, parameters: OpenAI::StructuredOutput::JsonSchemaConverter => params}
112
- func = tool.fetch(:function)
112
+ func = tool.fetch(:function, tool)
113
113
  name = func[:name] ||= params.name.split("::").last
114
114
  tool_models.store(name, params)
115
115
  func.update(parameters: params.to_json_schema)
@@ -119,7 +119,7 @@ module OpenAI
119
119
  Kernel.then do
120
120
  value = @data.fetch(name_sym) { const == OpenAI::Internal::OMIT ? nil : const }
121
121
  state = OpenAI::Internal::Type::Converter.new_coerce_state(translate_names: false)
122
- if (nilable || !required) && value.nil?
122
+ if (nilable || !required) && nil.equal?(value)
123
123
  nil
124
124
  else
125
125
  OpenAI::Internal::Type::Converter.coerce(
@@ -321,7 +321,7 @@ module OpenAI
321
321
  keys.delete(src_name)
322
322
 
323
323
  state[:error] = nil
324
- converted = if item.nil? && (nilable || !required)
324
+ converted = if nil.equal?(item) && (nilable || !required)
325
325
  exactness[nilable ? :yes : :maybe] += 1
326
326
  nil
327
327
  else
@@ -199,7 +199,7 @@ module OpenAI
199
199
 
200
200
  case target
201
201
  in -> { _1 <= NilClass }
202
- exactness[value.nil? ? :yes : :maybe] += 1
202
+ exactness[nil.equal?(value) ? :yes : :maybe] += 1
203
203
  return nil
204
204
  in -> { _1 <= Integer }
205
205
  case value
@@ -510,7 +510,7 @@ module OpenAI
510
510
  IO.copy_stream(val, y)
511
511
  in StringIO
512
512
  y << format(content_line, content_type || "application/octet-stream")
513
- y << val.string
513
+ y << (val.string.byteslice(val.pos..) || "")
514
514
  in -> { primitive?(_1) }
515
515
  y << format(content_line, content_type || "text/plain")
516
516
  y << val.to_s
@@ -630,7 +630,7 @@ module OpenAI
630
630
  in [OpenAI::Internal::Util::JSON_CONTENT, Hash | Array | -> { primitive?(_1) }]
631
631
  [headers, JSON.generate(body)]
632
632
  in [OpenAI::Internal::Util::JSONL_CONTENT, Enumerable] unless OpenAI::Internal::Type::FileInput === body
633
- [headers, body.lazy.map { JSON.generate(_1) }]
633
+ [headers, body.lazy.map { "#{JSON.generate(_1)}\n" }]
634
634
  in [%r{^multipart/form-data}, Hash | OpenAI::Internal::Type::FileInput]
635
635
  boundary, strio = encode_multipart_streaming(body)
636
636
  headers = {**headers, "content-type" => "#{content_type}; boundary=#{boundary}"}
@@ -132,7 +132,7 @@ module OpenAI
132
132
  complete = false
133
133
  case content
134
134
  in StringIO
135
- temporary_file.write(content.string)
135
+ temporary_file.write(content.string.byteslice(content.pos..) || "")
136
136
  in String
137
137
  temporary_file.write(content)
138
138
  in IO
@@ -51,6 +51,13 @@ module OpenAI
51
51
  # @return [Integer, nil]
52
52
  optional :limit, Integer
53
53
 
54
+ # @!attribute line_items
55
+ # Return only costs for these exact line item names. Each value must match the
56
+ # complete `line_item` value, for example `gpt-6-astra, input_tokens`.
57
+ #
58
+ # @return [Array<String>, nil]
59
+ optional :line_items, OpenAI::Internal::Type::ArrayOf[String]
60
+
54
61
  # @!attribute page
55
62
  # A cursor for use in pagination. Corresponding to the `next_page` field from the
56
63
  # previous response.
@@ -64,7 +71,7 @@ module OpenAI
64
71
  # @return [Array<String>, nil]
65
72
  optional :project_ids, OpenAI::Internal::Type::ArrayOf[String]
66
73
 
67
- # @!method initialize(start_time:, api_key_ids: nil, bucket_width: nil, end_time: nil, group_by: nil, limit: nil, page: nil, project_ids: nil, request_options: {})
74
+ # @!method initialize(start_time:, api_key_ids: nil, bucket_width: nil, end_time: nil, group_by: nil, limit: nil, line_items: nil, page: nil, project_ids: nil, request_options: {})
68
75
  # Some parameter documentations has been truncated, see
69
76
  # {OpenAI::Models::Admin::Organization::UsageCostsParams} for more details.
70
77
  #
@@ -80,6 +87,8 @@ module OpenAI
80
87
  #
81
88
  # @param limit [Integer] A limit on the number of buckets to be returned. Limit can range between 1 and 1
82
89
  #
90
+ # @param line_items [Array<String>] Return only costs for these exact line item names. Each value must match the com
91
+ #
83
92
  # @param page [String] A cursor for use in pagination. Corresponding to the `next_page` field from the
84
93
  #
85
94
  # @param project_ids [Array<String>] Return only costs for these projects.
@@ -116,9 +116,9 @@ module OpenAI
116
116
  optional :metadata, OpenAI::Internal::Type::HashOf[String], nil?: true
117
117
 
118
118
  # @!attribute model
119
- # Model ID used to process the batch, like `gpt-5-2025-08-07`. OpenAI offers a
120
- # wide range of models with different capabilities, performance characteristics,
121
- # and price points. Refer to the
119
+ # Model ID used to process the batch, like `gpt-6-astra`. OpenAI offers a wide
120
+ # range of models with different capabilities, performance characteristics, and
121
+ # price points. Refer to the
122
122
  # [model guide](https://platform.openai.com/docs/models) to browse and compare
123
123
  # available models.
124
124
  #
@@ -183,7 +183,7 @@ module OpenAI
183
183
  #
184
184
  # @param metadata [Hash{Symbol=>String}, nil] Set of 16 key-value pairs that can be attached to an object. This can be
185
185
  #
186
- # @param model [String] Model ID used to process the batch, like `gpt-5-2025-08-07`. OpenAI
186
+ # @param model [String] Model ID used to process the batch, like `gpt-6-astra`. OpenAI
187
187
  #
188
188
  # @param output_file_id [String] The ID of the file containing the outputs of successfully executed requests.
189
189
  #
@@ -26,6 +26,13 @@ module OpenAI
26
26
  nil?: true
27
27
  )
28
28
 
29
+ # @!attribute async
30
+ # Whether the tool response can be returned asynchronously versus immediately
31
+ # returned on next response creation.
32
+ #
33
+ # @return [Boolean, nil]
34
+ optional :async, OpenAI::Internal::Type::Boolean
35
+
29
36
  # @!attribute defer_loading
30
37
  # Whether this tool should be deferred and discovered via tool search.
31
38
  #
@@ -44,7 +51,10 @@ module OpenAI
44
51
  # @return [OpenAI::Models::Beta::BetaCustomTool::Format::Text, OpenAI::Models::Beta::BetaCustomTool::Format::Grammar, nil]
45
52
  optional :format_, union: -> { OpenAI::Beta::BetaCustomTool::Format }, api_name: :format
46
53
 
47
- # @!method initialize(name:, allowed_callers: nil, defer_loading: nil, description: nil, format_: nil, type: :custom)
54
+ # @!method initialize(name:, allowed_callers: nil, async: nil, defer_loading: nil, description: nil, format_: nil, type: :custom)
55
+ # Some parameter documentations has been truncated, see
56
+ # {OpenAI::Models::Beta::BetaCustomTool} for more details.
57
+ #
48
58
  # A custom tool that processes input using a specified format. Learn more about
49
59
  # [custom tools](https://platform.openai.com/docs/guides/function-calling#custom-tools)
50
60
  #
@@ -52,6 +62,8 @@ module OpenAI
52
62
  #
53
63
  # @param allowed_callers [Array<Symbol, OpenAI::Models::Beta::BetaCustomTool::AllowedCaller>, nil] The tool invocation context(s).
54
64
  #
65
+ # @param async [Boolean] Whether the tool response can be returned asynchronously versus immediately retu
66
+ #
55
67
  # @param defer_loading [Boolean] Whether this tool should be deferred and discovered via tool search.
56
68
  #
57
69
  # @param description [String] Optional description of the custom tool, used to provide more context.
@@ -38,6 +38,11 @@ module OpenAI
38
38
  nil?: true
39
39
  )
40
40
 
41
+ # @!attribute async
42
+ #
43
+ # @return [Boolean, nil]
44
+ optional :async, OpenAI::Internal::Type::Boolean
45
+
41
46
  # @!attribute defer_loading
42
47
  # Whether this function is deferred and loaded via tool search.
43
48
  #
@@ -58,7 +63,7 @@ module OpenAI
58
63
  # @return [Hash{Symbol=>Object}, nil]
59
64
  optional :output_schema, OpenAI::Internal::Type::HashOf[OpenAI::Internal::Type::Unknown], nil?: true
60
65
 
61
- # @!method initialize(name:, parameters:, strict:, allowed_callers: nil, defer_loading: nil, description: nil, output_schema: nil, type: :function)
66
+ # @!method initialize(name:, parameters:, strict:, allowed_callers: nil, async: nil, defer_loading: nil, description: nil, output_schema: nil, type: :function)
62
67
  # Some parameter documentations has been truncated, see
63
68
  # {OpenAI::Models::Beta::BetaFunctionTool} for more details.
64
69
  #
@@ -74,6 +79,8 @@ module OpenAI
74
79
  #
75
80
  # @param allowed_callers [Array<Symbol, OpenAI::Models::Beta::BetaFunctionTool::AllowedCaller>, nil] The tool invocation context(s).
76
81
  #
82
+ # @param async [Boolean]
83
+ #
77
84
  # @param defer_loading [Boolean] Whether this function is deferred and loaded via tool search.
78
85
  #
79
86
  # @param description [String, nil] A description of the function. Used by the model to determine whether or not to
@@ -73,6 +73,13 @@ module OpenAI
73
73
  nil?: true
74
74
  )
75
75
 
76
+ # @!attribute async
77
+ # Whether the tool response can be returned asynchronously versus immediately
78
+ # returned on next response creation.
79
+ #
80
+ # @return [Boolean, nil]
81
+ optional :async, OpenAI::Internal::Type::Boolean
82
+
76
83
  # @!attribute defer_loading
77
84
  # Whether this function should be deferred and discovered via tool search.
78
85
  #
@@ -108,7 +115,7 @@ module OpenAI
108
115
  # @return [Boolean, nil]
109
116
  optional :strict, OpenAI::Internal::Type::Boolean, nil?: true
110
117
 
111
- # @!method initialize(name:, allowed_callers: nil, defer_loading: nil, description: nil, output_schema: nil, parameters: nil, strict: nil, type: :function)
118
+ # @!method initialize(name:, allowed_callers: nil, async: nil, defer_loading: nil, description: nil, output_schema: nil, parameters: nil, strict: nil, type: :function)
112
119
  # Some parameter documentations has been truncated, see
113
120
  # {OpenAI::Models::Beta::BetaNamespaceTool::Tool::Function} for more details.
114
121
  #
@@ -116,6 +123,8 @@ module OpenAI
116
123
  #
117
124
  # @param allowed_callers [Array<Symbol, OpenAI::Models::Beta::BetaNamespaceTool::Tool::Function::AllowedCaller>, nil] The tool invocation context(s).
118
125
  #
126
+ # @param async [Boolean] Whether the tool response can be returned asynchronously versus immediately retu
127
+ #
119
128
  # @param defer_loading [Boolean] Whether this function should be deferred and discovered via tool search.
120
129
  #
121
130
  # @param description [String, nil]