From 2c89d20072ed1611227bcdb0cb3771407e5c0a21 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:13:17 +0000 Subject: [PATCH 1/2] feat(api): add support for realtime calls --- .stats.yml | 8 +- lib/openai.rb | 7 +- .../models/realtime/call_accept_params.rb | 16 ++ .../models/realtime/call_hangup_params.rb | 16 ++ .../models/realtime/call_refer_params.rb | 28 +++ .../models/realtime/call_reject_params.rb | 28 +++ lib/openai/resources/realtime.rb | 4 + lib/openai/resources/realtime/calls.rb | 143 ++++++++++++++ .../models/realtime/call_accept_params.rbi | 29 +++ .../models/realtime/call_hangup_params.rbi | 29 +++ .../models/realtime/call_refer_params.rbi | 44 +++++ .../models/realtime/call_reject_params.rbi | 47 +++++ rbi/openai/resources/realtime.rbi | 3 + rbi/openai/resources/realtime/calls.rbi | 182 ++++++++++++++++++ scripts/detect-breaking-changes | 1 + .../models/realtime/call_accept_params.rbs | 17 ++ .../models/realtime/call_hangup_params.rbs | 17 ++ .../models/realtime/call_refer_params.rbs | 25 +++ .../models/realtime/call_reject_params.rbs | 27 +++ sig/openai/resources/realtime.rbs | 2 + sig/openai/resources/realtime/calls.rbs | 43 +++++ test/openai/resources/realtime/calls_test.rb | 37 ++++ 22 files changed, 748 insertions(+), 5 deletions(-) create mode 100644 lib/openai/models/realtime/call_accept_params.rb create mode 100644 lib/openai/models/realtime/call_hangup_params.rb create mode 100644 lib/openai/models/realtime/call_refer_params.rb create mode 100644 lib/openai/models/realtime/call_reject_params.rb create mode 100644 lib/openai/resources/realtime/calls.rb create mode 100644 rbi/openai/models/realtime/call_accept_params.rbi create mode 100644 rbi/openai/models/realtime/call_hangup_params.rbi create mode 100644 rbi/openai/models/realtime/call_refer_params.rbi create mode 100644 rbi/openai/models/realtime/call_reject_params.rbi create mode 100644 rbi/openai/resources/realtime/calls.rbi create mode 100644 sig/openai/models/realtime/call_accept_params.rbs create mode 100644 sig/openai/models/realtime/call_hangup_params.rbs create mode 100644 sig/openai/models/realtime/call_refer_params.rbs create mode 100644 sig/openai/models/realtime/call_reject_params.rbs create mode 100644 sig/openai/resources/realtime/calls.rbs create mode 100644 test/openai/resources/realtime/calls_test.rb diff --git a/.stats.yml b/.stats.yml index 27f2ffc6..4e40d470 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 118 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-e205b1f2da6a1f2caa229efa9ede63f2d3d2fedeeb2dd6ed3d880bafdcb0ab88.yml -openapi_spec_hash: c8aee2469a749f6a838b40c57e4b7b06 -config_hash: 45dcba51451ba532959c020a0ddbf23c +configured_endpoints: 122 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-fadefdc7c7e30df47c09df323669b242ff90ee08e51f304175ace5274e0aab49.yml +openapi_spec_hash: 6d20f639d9ff8a097a34962da6218231 +config_hash: 902654e60f5d659f2bfcfd903e17c46d diff --git a/lib/openai.rb b/lib/openai.rb index 6af4b6d8..d2f7fa8c 100644 --- a/lib/openai.rb +++ b/lib/openai.rb @@ -71,6 +71,7 @@ require_relative "openai/models/graders/python_grader" require_relative "openai/models/graders/text_similarity_grader" require_relative "openai/models/fine_tuning/fine_tuning_job_wandb_integration_object" +require_relative "openai/models/realtime/realtime_session_create_request" require_relative "openai/models/responses/response_function_tool_call" require_relative "openai/models/all_models" require_relative "openai/models/audio/speech_create_params" @@ -383,6 +384,10 @@ require_relative "openai/models/moderation_text_input" require_relative "openai/models/other_file_chunking_strategy_object" require_relative "openai/models/realtime/audio_transcription" +require_relative "openai/models/realtime/call_accept_params" +require_relative "openai/models/realtime/call_hangup_params" +require_relative "openai/models/realtime/call_refer_params" +require_relative "openai/models/realtime/call_reject_params" require_relative "openai/models/realtime/client_secret_create_params" require_relative "openai/models/realtime/client_secret_create_response" require_relative "openai/models/realtime/conversation_created_event" @@ -448,7 +453,6 @@ require_relative "openai/models/realtime/realtime_server_event" require_relative "openai/models/realtime/realtime_session" require_relative "openai/models/realtime/realtime_session_client_secret" -require_relative "openai/models/realtime/realtime_session_create_request" require_relative "openai/models/realtime/realtime_session_create_response" require_relative "openai/models/realtime/realtime_tool_choice_config" require_relative "openai/models/realtime/realtime_tools_config" @@ -695,6 +699,7 @@ require_relative "openai/resources/models" require_relative "openai/resources/moderations" require_relative "openai/resources/realtime" +require_relative "openai/resources/realtime/calls" require_relative "openai/resources/realtime/client_secrets" require_relative "openai/resources/responses" require_relative "openai/resources/responses/input_items" diff --git a/lib/openai/models/realtime/call_accept_params.rb b/lib/openai/models/realtime/call_accept_params.rb new file mode 100644 index 00000000..b4ced4e5 --- /dev/null +++ b/lib/openai/models/realtime/call_accept_params.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module OpenAI + module Models + module Realtime + # @see OpenAI::Resources::Realtime::Calls#accept + class CallAcceptParams < OpenAI::Models::Realtime::RealtimeSessionCreateRequest + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + # @!method initialize(request_options: {}) + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}] + end + end + end +end diff --git a/lib/openai/models/realtime/call_hangup_params.rb b/lib/openai/models/realtime/call_hangup_params.rb new file mode 100644 index 00000000..4cec8d5b --- /dev/null +++ b/lib/openai/models/realtime/call_hangup_params.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module OpenAI + module Models + module Realtime + # @see OpenAI::Resources::Realtime::Calls#hangup + class CallHangupParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + # @!method initialize(request_options: {}) + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}] + end + end + end +end diff --git a/lib/openai/models/realtime/call_refer_params.rb b/lib/openai/models/realtime/call_refer_params.rb new file mode 100644 index 00000000..fe15fb38 --- /dev/null +++ b/lib/openai/models/realtime/call_refer_params.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module OpenAI + module Models + module Realtime + # @see OpenAI::Resources::Realtime::Calls#refer + class CallReferParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + # @!attribute target_uri + # URI that should appear in the SIP Refer-To header. Supports values like + # `tel:+14155550123` or `sip:agent@example.com`. + # + # @return [String] + required :target_uri, String + + # @!method initialize(target_uri:, request_options: {}) + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallReferParams} for more details. + # + # @param target_uri [String] URI that should appear in the SIP Refer-To header. Supports values like + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}] + end + end + end +end diff --git a/lib/openai/models/realtime/call_reject_params.rb b/lib/openai/models/realtime/call_reject_params.rb new file mode 100644 index 00000000..5efc854b --- /dev/null +++ b/lib/openai/models/realtime/call_reject_params.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module OpenAI + module Models + module Realtime + # @see OpenAI::Resources::Realtime::Calls#reject + class CallRejectParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + # @!attribute status_code + # SIP response code to send back to the caller. Defaults to `603` (Decline) when + # omitted. + # + # @return [Integer, nil] + optional :status_code, Integer + + # @!method initialize(status_code: nil, request_options: {}) + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallRejectParams} for more details. + # + # @param status_code [Integer] SIP response code to send back to the caller. Defaults to `603` (Decline) + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}] + end + end + end +end diff --git a/lib/openai/resources/realtime.rb b/lib/openai/resources/realtime.rb index 62577575..f361d152 100644 --- a/lib/openai/resources/realtime.rb +++ b/lib/openai/resources/realtime.rb @@ -6,12 +6,16 @@ class Realtime # @return [OpenAI::Resources::Realtime::ClientSecrets] attr_reader :client_secrets + # @return [OpenAI::Resources::Realtime::Calls] + attr_reader :calls + # @api private # # @param client [OpenAI::Client] def initialize(client:) @client = client @client_secrets = OpenAI::Resources::Realtime::ClientSecrets.new(client: client) + @calls = OpenAI::Resources::Realtime::Calls.new(client: client) end end end diff --git a/lib/openai/resources/realtime/calls.rb b/lib/openai/resources/realtime/calls.rb new file mode 100644 index 00000000..b25dc4d7 --- /dev/null +++ b/lib/openai/resources/realtime/calls.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +module OpenAI + module Resources + class Realtime + class Calls + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallAcceptParams} for more details. + # + # Accept an incoming SIP call and configure the realtime session that will handle + # it. + # + # @overload accept(call_id, audio: nil, include: nil, instructions: nil, max_output_tokens: nil, model: nil, output_modalities: nil, prompt: nil, tool_choice: nil, tools: nil, tracing: nil, truncation: nil, type: :realtime, request_options: {}) + # + # @param call_id [String] The identifier for the call provided in the + # + # @param audio [OpenAI::Models::Realtime::RealtimeAudioConfig] Configuration for input and output audio. + # + # @param include [Array] Additional fields to include in server outputs. + # + # @param instructions [String] The default system instructions (i.e. system message) prepended to model calls. + # + # @param max_output_tokens [Integer, Symbol, :inf] Maximum number of output tokens for a single assistant response, + # + # @param model [String, Symbol, OpenAI::Models::Realtime::RealtimeSessionCreateRequest::Model] The Realtime model used for this session. + # + # @param output_modalities [Array] The set of modalities the model can respond with. It defaults to `["audio"]`, in + # + # @param prompt [OpenAI::Models::Responses::ResponsePrompt, nil] Reference to a prompt template and its variables. + # + # @param tool_choice [Symbol, OpenAI::Models::Responses::ToolChoiceOptions, OpenAI::Models::Responses::ToolChoiceFunction, OpenAI::Models::Responses::ToolChoiceMcp] How the model chooses tools. Provide one of the string modes or force a specific + # + # @param tools [Array] Tools available to the model. + # + # @param tracing [Symbol, :auto, OpenAI::Models::Realtime::RealtimeTracingConfig::TracingConfiguration, nil] Realtime API can write session traces to the [Traces Dashboard](/logs?api=traces + # + # @param truncation [Symbol, OpenAI::Models::Realtime::RealtimeTruncation::RealtimeTruncationStrategy, OpenAI::Models::Realtime::RealtimeTruncationRetentionRatio] Controls how the realtime conversation is truncated prior to model inference. + # + # @param type [Symbol, :realtime] The type of session to create. Always `realtime` for the Realtime API. + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see OpenAI::Models::Realtime::CallAcceptParams + def accept(call_id, params) + parsed, options = OpenAI::Realtime::CallAcceptParams.dump_request(params) + @client.request( + method: :post, + path: ["realtime/calls/%1$s/accept", call_id], + body: parsed, + model: NilClass, + options: options + ) + end + + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallHangupParams} for more details. + # + # End an active Realtime API call, whether it was initiated over SIP or WebRTC. + # + # @overload hangup(call_id, request_options: {}) + # + # @param call_id [String] The identifier for the call. For SIP calls, use the value provided in the + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see OpenAI::Models::Realtime::CallHangupParams + def hangup(call_id, params = {}) + @client.request( + method: :post, + path: ["realtime/calls/%1$s/hangup", call_id], + model: NilClass, + options: params[:request_options] + ) + end + + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallReferParams} for more details. + # + # Transfer an active SIP call to a new destination using the SIP REFER verb. + # + # @overload refer(call_id, target_uri:, request_options: {}) + # + # @param call_id [String] The identifier for the call provided in the + # + # @param target_uri [String] URI that should appear in the SIP Refer-To header. Supports values like + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see OpenAI::Models::Realtime::CallReferParams + def refer(call_id, params) + parsed, options = OpenAI::Realtime::CallReferParams.dump_request(params) + @client.request( + method: :post, + path: ["realtime/calls/%1$s/refer", call_id], + body: parsed, + model: NilClass, + options: options + ) + end + + # Some parameter documentations has been truncated, see + # {OpenAI::Models::Realtime::CallRejectParams} for more details. + # + # Decline an incoming SIP call by returning a SIP status code to the caller. + # + # @overload reject(call_id, status_code: nil, request_options: {}) + # + # @param call_id [String] The identifier for the call provided in the + # + # @param status_code [Integer] SIP response code to send back to the caller. Defaults to `603` (Decline) + # + # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see OpenAI::Models::Realtime::CallRejectParams + def reject(call_id, params = {}) + parsed, options = OpenAI::Realtime::CallRejectParams.dump_request(params) + @client.request( + method: :post, + path: ["realtime/calls/%1$s/reject", call_id], + body: parsed, + model: NilClass, + options: options + ) + end + + # @api private + # + # @param client [OpenAI::Client] + def initialize(client:) + @client = client + end + end + end + end +end diff --git a/rbi/openai/models/realtime/call_accept_params.rbi b/rbi/openai/models/realtime/call_accept_params.rbi new file mode 100644 index 00000000..0ab94073 --- /dev/null +++ b/rbi/openai/models/realtime/call_accept_params.rbi @@ -0,0 +1,29 @@ +# typed: strong + +module OpenAI + module Models + module Realtime + class CallAcceptParams < OpenAI::Models::Realtime::RealtimeSessionCreateRequest + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any(OpenAI::Realtime::CallAcceptParams, OpenAI::Internal::AnyHash) + end + + sig do + params(request_options: OpenAI::RequestOptions::OrHash).returns( + T.attached_class + ) + end + def self.new(request_options: {}) + end + + sig { override.returns({ request_options: OpenAI::RequestOptions }) } + def to_hash + end + end + end + end +end diff --git a/rbi/openai/models/realtime/call_hangup_params.rbi b/rbi/openai/models/realtime/call_hangup_params.rbi new file mode 100644 index 00000000..de5920b8 --- /dev/null +++ b/rbi/openai/models/realtime/call_hangup_params.rbi @@ -0,0 +1,29 @@ +# typed: strong + +module OpenAI + module Models + module Realtime + class CallHangupParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any(OpenAI::Realtime::CallHangupParams, OpenAI::Internal::AnyHash) + end + + sig do + params(request_options: OpenAI::RequestOptions::OrHash).returns( + T.attached_class + ) + end + def self.new(request_options: {}) + end + + sig { override.returns({ request_options: OpenAI::RequestOptions }) } + def to_hash + end + end + end + end +end diff --git a/rbi/openai/models/realtime/call_refer_params.rbi b/rbi/openai/models/realtime/call_refer_params.rbi new file mode 100644 index 00000000..07fb54a2 --- /dev/null +++ b/rbi/openai/models/realtime/call_refer_params.rbi @@ -0,0 +1,44 @@ +# typed: strong + +module OpenAI + module Models + module Realtime + class CallReferParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any(OpenAI::Realtime::CallReferParams, OpenAI::Internal::AnyHash) + end + + # URI that should appear in the SIP Refer-To header. Supports values like + # `tel:+14155550123` or `sip:agent@example.com`. + sig { returns(String) } + attr_accessor :target_uri + + sig do + params( + target_uri: String, + request_options: OpenAI::RequestOptions::OrHash + ).returns(T.attached_class) + end + def self.new( + # URI that should appear in the SIP Refer-To header. Supports values like + # `tel:+14155550123` or `sip:agent@example.com`. + target_uri:, + request_options: {} + ) + end + + sig do + override.returns( + { target_uri: String, request_options: OpenAI::RequestOptions } + ) + end + def to_hash + end + end + end + end +end diff --git a/rbi/openai/models/realtime/call_reject_params.rbi b/rbi/openai/models/realtime/call_reject_params.rbi new file mode 100644 index 00000000..b7ab158e --- /dev/null +++ b/rbi/openai/models/realtime/call_reject_params.rbi @@ -0,0 +1,47 @@ +# typed: strong + +module OpenAI + module Models + module Realtime + class CallRejectParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any(OpenAI::Realtime::CallRejectParams, OpenAI::Internal::AnyHash) + end + + # SIP response code to send back to the caller. Defaults to `603` (Decline) when + # omitted. + sig { returns(T.nilable(Integer)) } + attr_reader :status_code + + sig { params(status_code: Integer).void } + attr_writer :status_code + + sig do + params( + status_code: Integer, + request_options: OpenAI::RequestOptions::OrHash + ).returns(T.attached_class) + end + def self.new( + # SIP response code to send back to the caller. Defaults to `603` (Decline) when + # omitted. + status_code: nil, + request_options: {} + ) + end + + sig do + override.returns( + { status_code: Integer, request_options: OpenAI::RequestOptions } + ) + end + def to_hash + end + end + end + end +end diff --git a/rbi/openai/resources/realtime.rbi b/rbi/openai/resources/realtime.rbi index 5d6c55b9..93c14444 100644 --- a/rbi/openai/resources/realtime.rbi +++ b/rbi/openai/resources/realtime.rbi @@ -6,6 +6,9 @@ module OpenAI sig { returns(OpenAI::Resources::Realtime::ClientSecrets) } attr_reader :client_secrets + sig { returns(OpenAI::Resources::Realtime::Calls) } + attr_reader :calls + # @api private sig { params(client: OpenAI::Client).returns(T.attached_class) } def self.new(client:) diff --git a/rbi/openai/resources/realtime/calls.rbi b/rbi/openai/resources/realtime/calls.rbi new file mode 100644 index 00000000..f1df77f2 --- /dev/null +++ b/rbi/openai/resources/realtime/calls.rbi @@ -0,0 +1,182 @@ +# typed: strong + +module OpenAI + module Resources + class Realtime + class Calls + # Accept an incoming SIP call and configure the realtime session that will handle + # it. + sig do + params( + call_id: String, + audio: OpenAI::Realtime::RealtimeAudioConfig::OrHash, + include: + T::Array[ + OpenAI::Realtime::RealtimeSessionCreateRequest::Include::OrSymbol + ], + instructions: String, + max_output_tokens: T.any(Integer, Symbol), + model: + T.any( + String, + OpenAI::Realtime::RealtimeSessionCreateRequest::Model::OrSymbol + ), + output_modalities: + T::Array[ + OpenAI::Realtime::RealtimeSessionCreateRequest::OutputModality::OrSymbol + ], + prompt: T.nilable(OpenAI::Responses::ResponsePrompt::OrHash), + tool_choice: + T.any( + OpenAI::Responses::ToolChoiceOptions::OrSymbol, + OpenAI::Responses::ToolChoiceFunction::OrHash, + OpenAI::Responses::ToolChoiceMcp::OrHash + ), + tools: + T::Array[ + T.any( + OpenAI::Realtime::RealtimeFunctionTool::OrHash, + OpenAI::Realtime::RealtimeToolsConfigUnion::Mcp::OrHash + ) + ], + tracing: + T.nilable( + T.any( + Symbol, + OpenAI::Realtime::RealtimeTracingConfig::TracingConfiguration::OrHash + ) + ), + truncation: + T.any( + OpenAI::Realtime::RealtimeTruncation::RealtimeTruncationStrategy::OrSymbol, + OpenAI::Realtime::RealtimeTruncationRetentionRatio::OrHash + ), + type: Symbol, + request_options: OpenAI::RequestOptions::OrHash + ).void + end + def accept( + # The identifier for the call provided in the + # [`realtime.call.incoming`](https://platform.openai.com/docs/api-reference/webhook_events/realtime/call/incoming) + # webhook. + call_id, + # Configuration for input and output audio. + audio: nil, + # Additional fields to include in server outputs. + # + # `item.input_audio_transcription.logprobs`: Include logprobs for input audio + # transcription. + include: nil, + # The default system instructions (i.e. system message) prepended to model calls. + # This field allows the client to guide the model on desired responses. The model + # can be instructed on response content and format, (e.g. "be extremely succinct", + # "act friendly", "here are examples of good responses") and on audio behavior + # (e.g. "talk quickly", "inject emotion into your voice", "laugh frequently"). The + # instructions are not guaranteed to be followed by the model, but they provide + # guidance to the model on the desired behavior. + # + # Note that the server sets default instructions which will be used if this field + # is not set and are visible in the `session.created` event at the start of the + # session. + instructions: nil, + # Maximum number of output tokens for a single assistant response, inclusive of + # tool calls. Provide an integer between 1 and 4096 to limit output tokens, or + # `inf` for the maximum available tokens for a given model. Defaults to `inf`. + max_output_tokens: nil, + # The Realtime model used for this session. + model: nil, + # The set of modalities the model can respond with. It defaults to `["audio"]`, + # indicating that the model will respond with audio plus a transcript. `["text"]` + # can be used to make the model respond with text only. It is not possible to + # request both `text` and `audio` at the same time. + output_modalities: nil, + # Reference to a prompt template and its variables. + # [Learn more](https://platform.openai.com/docs/guides/text?api-mode=responses#reusable-prompts). + prompt: nil, + # How the model chooses tools. Provide one of the string modes or force a specific + # function/MCP tool. + tool_choice: nil, + # Tools available to the model. + tools: nil, + # Realtime API can write session traces to the + # [Traces Dashboard](/logs?api=traces). Set to null to disable tracing. Once + # tracing is enabled for a session, the configuration cannot be modified. + # + # `auto` will create a trace for the session with default values for the workflow + # name, group id, and metadata. + tracing: nil, + # Controls how the realtime conversation is truncated prior to model inference. + # The default is `auto`. + truncation: nil, + # The type of session to create. Always `realtime` for the Realtime API. + type: :realtime, + request_options: {} + ) + end + + # End an active Realtime API call, whether it was initiated over SIP or WebRTC. + sig do + params( + call_id: String, + request_options: OpenAI::RequestOptions::OrHash + ).void + end + def hangup( + # The identifier for the call. For SIP calls, use the value provided in the + # [`realtime.call.incoming`](https://platform.openai.com/docs/api-reference/webhook_events/realtime/call/incoming) + # webhook. For WebRTC sessions, reuse the call ID returned in the `Location` + # header when creating the call with + # [`POST /v1/realtime/calls`](https://platform.openai.com/docs/api-reference/realtime/create-call). + call_id, + request_options: {} + ) + end + + # Transfer an active SIP call to a new destination using the SIP REFER verb. + sig do + params( + call_id: String, + target_uri: String, + request_options: OpenAI::RequestOptions::OrHash + ).void + end + def refer( + # The identifier for the call provided in the + # [`realtime.call.incoming`](https://platform.openai.com/docs/api-reference/webhook_events/realtime/call/incoming) + # webhook. + call_id, + # URI that should appear in the SIP Refer-To header. Supports values like + # `tel:+14155550123` or `sip:agent@example.com`. + target_uri:, + request_options: {} + ) + end + + # Decline an incoming SIP call by returning a SIP status code to the caller. + sig do + params( + call_id: String, + status_code: Integer, + request_options: OpenAI::RequestOptions::OrHash + ).void + end + def reject( + # The identifier for the call provided in the + # [`realtime.call.incoming`](https://platform.openai.com/docs/api-reference/webhook_events/realtime/call/incoming) + # webhook. + call_id, + # SIP response code to send back to the caller. Defaults to `603` (Decline) when + # omitted. + status_code: nil, + request_options: {} + ) + end + + # @api private + sig { params(client: OpenAI::Client).returns(T.attached_class) } + def self.new(client:) + end + end + end + end +end diff --git a/scripts/detect-breaking-changes b/scripts/detect-breaking-changes index 9187ba05..112f4354 100755 --- a/scripts/detect-breaking-changes +++ b/scripts/detect-breaking-changes @@ -48,6 +48,7 @@ TEST_PATHS=( test/openai/resources/responses/input_items_test.rb test/openai/resources/realtime_test.rb test/openai/resources/realtime/client_secrets_test.rb + test/openai/resources/realtime/calls_test.rb test/openai/resources/conversations_test.rb test/openai/resources/conversations/items_test.rb test/openai/resources/evals_test.rb diff --git a/sig/openai/models/realtime/call_accept_params.rbs b/sig/openai/models/realtime/call_accept_params.rbs new file mode 100644 index 00000000..7967ee45 --- /dev/null +++ b/sig/openai/models/realtime/call_accept_params.rbs @@ -0,0 +1,17 @@ +module OpenAI + module Models + module Realtime + type call_accept_params = + { } & OpenAI::Internal::Type::request_parameters + + class CallAcceptParams < OpenAI::Models::Realtime::RealtimeSessionCreateRequest + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + def initialize: (?request_options: OpenAI::request_opts) -> void + + def to_hash: -> { request_options: OpenAI::RequestOptions } + end + end + end +end diff --git a/sig/openai/models/realtime/call_hangup_params.rbs b/sig/openai/models/realtime/call_hangup_params.rbs new file mode 100644 index 00000000..49bb3b28 --- /dev/null +++ b/sig/openai/models/realtime/call_hangup_params.rbs @@ -0,0 +1,17 @@ +module OpenAI + module Models + module Realtime + type call_hangup_params = + { } & OpenAI::Internal::Type::request_parameters + + class CallHangupParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + def initialize: (?request_options: OpenAI::request_opts) -> void + + def to_hash: -> { request_options: OpenAI::RequestOptions } + end + end + end +end diff --git a/sig/openai/models/realtime/call_refer_params.rbs b/sig/openai/models/realtime/call_refer_params.rbs new file mode 100644 index 00000000..cc14d2a1 --- /dev/null +++ b/sig/openai/models/realtime/call_refer_params.rbs @@ -0,0 +1,25 @@ +module OpenAI + module Models + module Realtime + type call_refer_params = + { target_uri: String } & OpenAI::Internal::Type::request_parameters + + class CallReferParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + attr_accessor target_uri: String + + def initialize: ( + target_uri: String, + ?request_options: OpenAI::request_opts + ) -> void + + def to_hash: -> { + target_uri: String, + request_options: OpenAI::RequestOptions + } + end + end + end +end diff --git a/sig/openai/models/realtime/call_reject_params.rbs b/sig/openai/models/realtime/call_reject_params.rbs new file mode 100644 index 00000000..4b630172 --- /dev/null +++ b/sig/openai/models/realtime/call_reject_params.rbs @@ -0,0 +1,27 @@ +module OpenAI + module Models + module Realtime + type call_reject_params = + { status_code: Integer } & OpenAI::Internal::Type::request_parameters + + class CallRejectParams < OpenAI::Internal::Type::BaseModel + extend OpenAI::Internal::Type::RequestParameters::Converter + include OpenAI::Internal::Type::RequestParameters + + attr_reader status_code: Integer? + + def status_code=: (Integer) -> Integer + + def initialize: ( + ?status_code: Integer, + ?request_options: OpenAI::request_opts + ) -> void + + def to_hash: -> { + status_code: Integer, + request_options: OpenAI::RequestOptions + } + end + end + end +end diff --git a/sig/openai/resources/realtime.rbs b/sig/openai/resources/realtime.rbs index 682a7fa1..999debec 100644 --- a/sig/openai/resources/realtime.rbs +++ b/sig/openai/resources/realtime.rbs @@ -3,6 +3,8 @@ module OpenAI class Realtime attr_reader client_secrets: OpenAI::Resources::Realtime::ClientSecrets + attr_reader calls: OpenAI::Resources::Realtime::Calls + def initialize: (client: OpenAI::Client) -> void end end diff --git a/sig/openai/resources/realtime/calls.rbs b/sig/openai/resources/realtime/calls.rbs new file mode 100644 index 00000000..b3855ab9 --- /dev/null +++ b/sig/openai/resources/realtime/calls.rbs @@ -0,0 +1,43 @@ +module OpenAI + module Resources + class Realtime + class Calls + def accept: ( + String call_id, + ?audio: OpenAI::Realtime::RealtimeAudioConfig, + ?include: ::Array[OpenAI::Models::Realtime::RealtimeSessionCreateRequest::include_], + ?instructions: String, + ?max_output_tokens: OpenAI::Models::Realtime::RealtimeSessionCreateRequest::max_output_tokens, + ?model: OpenAI::Models::Realtime::RealtimeSessionCreateRequest::model, + ?output_modalities: ::Array[OpenAI::Models::Realtime::RealtimeSessionCreateRequest::output_modality], + ?prompt: OpenAI::Responses::ResponsePrompt?, + ?tool_choice: OpenAI::Models::Realtime::realtime_tool_choice_config, + ?tools: OpenAI::Models::Realtime::realtime_tools_config, + ?tracing: OpenAI::Models::Realtime::realtime_tracing_config?, + ?truncation: OpenAI::Models::Realtime::realtime_truncation, + ?type: :realtime, + ?request_options: OpenAI::request_opts + ) -> nil + + def hangup: ( + String call_id, + ?request_options: OpenAI::request_opts + ) -> nil + + def refer: ( + String call_id, + target_uri: String, + ?request_options: OpenAI::request_opts + ) -> nil + + def reject: ( + String call_id, + ?status_code: Integer, + ?request_options: OpenAI::request_opts + ) -> nil + + def initialize: (client: OpenAI::Client) -> void + end + end + end +end diff --git a/test/openai/resources/realtime/calls_test.rb b/test/openai/resources/realtime/calls_test.rb new file mode 100644 index 00000000..938be40e --- /dev/null +++ b/test/openai/resources/realtime/calls_test.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require_relative "../../test_helper" + +class OpenAI::Test::Resources::Realtime::CallsTest < OpenAI::Test::ResourceTest + def test_accept_required_params + response = @openai.realtime.calls.accept("call_id", type: :realtime) + + assert_pattern do + response => nil + end + end + + def test_hangup + response = @openai.realtime.calls.hangup("call_id") + + assert_pattern do + response => nil + end + end + + def test_refer_required_params + response = @openai.realtime.calls.refer("call_id", target_uri: "tel:+14155550123") + + assert_pattern do + response => nil + end + end + + def test_reject + response = @openai.realtime.calls.reject("call_id") + + assert_pattern do + response => nil + end + end +end From 013c5a30264559f57195fa37d82dbe7532244095 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:13:36 +0000 Subject: [PATCH 2/2] release: 0.29.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ Gemfile.lock | 2 +- README.md | 2 +- lib/openai/version.rb | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a6fc929e..b8dda9bf 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.28.1" + ".": "0.29.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d8174a97..3c9f596e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.29.0 (2025-10-02) + +Full Changelog: [v0.28.1...v0.29.0](https://github.com/openai/openai-ruby/compare/v0.28.1...v0.29.0) + +### Features + +* **api:** add support for realtime calls ([2c89d20](https://github.com/openai/openai-ruby/commit/2c89d20072ed1611227bcdb0cb3771407e5c0a21)) + ## 0.28.1 (2025-10-01) Full Changelog: [v0.28.0...v0.28.1](https://github.com/openai/openai-ruby/compare/v0.28.0...v0.28.1) diff --git a/Gemfile.lock b/Gemfile.lock index a95bebcb..cb62acc6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - openai (0.28.1) + openai (0.29.0) connection_pool GEM diff --git a/README.md b/README.md index 070e52ad..dd7a2a72 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application ```ruby -gem "openai", "~> 0.28.1" +gem "openai", "~> 0.29.0" ``` diff --git a/lib/openai/version.rb b/lib/openai/version.rb index ac17d046..ad6e4b51 100644 --- a/lib/openai/version.rb +++ b/lib/openai/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module OpenAI - VERSION = "0.28.1" + VERSION = "0.29.0" end