Skip to content

Conversation

@IM594
Copy link
Contributor

@IM594 IM594 commented Oct 25, 2025

This pull request resolves #613

To resolve this issue, I added an onconnectionstatechange listener to the RTCPeerConnection instance — this is the minimum fix. If the underlying connection state transitions to 'disconnected', 'failed', or 'closed', the close() method is now invoked.

@changeset-bot
Copy link

changeset-bot bot commented Oct 25, 2025

🦋 Changeset detected

Latest commit: 83c6f5f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@openai/agents-realtime Patch
@openai/agents Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@IM594 IM594 marked this pull request as draft October 27, 2025 03:26
@IM594 IM594 marked this pull request as ready for review October 27, 2025 05:33
@IM594
Copy link
Contributor Author

IM594 commented Oct 27, 2025

sdk.v0.1.11.webrtc.bug.mov
webrtc.bug.fixed.mov

@seratch seratch added bug Something isn't working package:agents-realtime labels Oct 27, 2025
@seratch
Copy link
Member

seratch commented Oct 27, 2025

Thanks for sending this patch! I actually also did something similar, so I think this should be fine. I will look into details and do testing on my end too.

@seratch seratch self-requested a review October 27, 2025 12:41
@seratch
Copy link
Member

seratch commented Oct 28, 2025

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seratch
Copy link
Member

seratch commented Oct 28, 2025

@IM594 I asked my local codex to review the changes again, and it says:

• Review comment:

  - [P1] Rebind connectionstate handler after changePeerConnection — packages/agents-realtime/src/openaiRealtimeWebRtc.ts:263-266
    When changePeerConnection returns a new RTCPeerConnection, the onconnectionstatechange handler added just above never gets reattached to that replacement. That means the new
  peer connection will never trigger close() on failed/disconnected states, so status stays connected and no connection_change event fires—the exact regression this patch is trying
  to solve. Anyone overriding the connection (a documented capability) will still miss disconnects after this change. Please reapply the handler to the returned peer connection (and
  ideally remove it from the original one) so the auto-disconnect logic works in that scenario.

And this makes sense to me. The suggested changes are:

diff --git a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts
index 2c5c661..19d5279 100644
--- a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts
+++ b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts
@@ -181,17 +181,22 @@ export class OpenAIRealtimeWebRTC
         const dataChannel = peerConnection.createDataChannel('oai-events');
         let callId: string | undefined = undefined;
 
-        peerConnection.onconnectionstatechange = () => {
-          switch (peerConnection.connectionState) {
-            case 'disconnected':
-            case 'failed':
-            case 'closed':
-              this.close();
-              break;
-            // 'connected' state is handled by dataChannel.onopen. So we don't need to handle it here.
-            // 'new' and 'connecting' are intermediate states and don't require action here
-          }
+        const attachConnectionStateHandler = (
+          connection: RTCPeerConnection,
+        ) => {
+          connection.onconnectionstatechange = () => {
+            switch (connection.connectionState) {
+              case 'disconnected':
+              case 'failed':
+              case 'closed':
+                this.close();
+                break;
+              // 'connected' state is handled by dataChannel.onopen. So we don't need to handle it here.
+              // 'new' and 'connecting' are intermediate states and do not require action here.
+            }
+          };
         };
+        attachConnectionStateHandler(peerConnection);
 
         this.#state = {
           status: 'connecting',
@@ -261,8 +266,13 @@ export class OpenAIRealtimeWebRTC
         peerConnection.addTrack(stream.getAudioTracks()[0]);
 
         if (this.options.changePeerConnection) {
+          const originalPeerConnection = peerConnection;
           peerConnection =
             await this.options.changePeerConnection(peerConnection);
+          if (originalPeerConnection !== peerConnection) {
+            originalPeerConnection.onconnectionstatechange = null;
+          }
+          attachConnectionStateHandler(peerConnection);
           this.#state = { ...this.#state, peerConnection };
         }

What do you think?

@IM594
Copy link
Contributor Author

IM594 commented Oct 28, 2025

@seratch Great catch, and thanks for pointing this out! You're right, the handler needed to be moved. I've added a test for this.

My apologies for the oversight and any extra work it caused. I really appreciate the thorough review—it's what makes the SDK more robust

@seratch seratch enabled auto-merge (squash) October 28, 2025 21:31
@seratch seratch merged commit 8c93873 into openai:main Oct 28, 2025
4 checks passed
@IM594 IM594 deleted the fix/handle-webrtc-disconnect branch October 29, 2025 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working package:agents-realtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAIRealtimeWebRTC connection_change Fails to Detect Disconnection After Connection is Established

2 participants