Skip to content

feat(client): echo negotiationId in subscriber offer answer#2166

Open
oliverlaz wants to merge 2 commits intomainfrom
feat/echo-negotiation-id
Open

feat(client): echo negotiationId in subscriber offer answer#2166
oliverlaz wants to merge 2 commits intomainfrom
feat/echo-negotiation-id

Conversation

@oliverlaz
Copy link
Member

@oliverlaz oliverlaz commented Mar 18, 2026

💡 Overview

Echo the negotiationId from the SubscriberOffer back in the SendAnswerRequest so the SFU can correlate offers with their corresponding answers.

📝 Implementation notes

  • Updated Subscriber.negotiate() to pass subscriberOffer.negotiationId through to sfuClient.sendAnswer()
  • Updated Subscriber test to verify negotiationId is echoed
  • Includes codegen updates from protocol changes (new SFU models/RPCs, webrtcVersion in ClientDetails)
  • Populates the new webrtcVersion field in client-details.ts

🎫 Ticket: https://linear.app/stream/issue/REACT-898/echo-negotiationid-param-in-subscriber-offer
🔗 Protocol PR: GetStream/protocol#1717

Summary by CodeRabbit

  • New Features

    • Enhanced client details with WebRTC version information now exposed
    • Improved WebRTC connection negotiation with enhanced tracking
  • Tests

    • Updated tests to reflect WebRTC negotiation enhancements

Echo the negotiationId from the SubscriberOffer back in the SendAnswerRequest
so the SFU can correlate offers with their corresponding answers. Also includes
codegen updates from protocol PR #1717 and populates the new webrtcVersion
field in ClientDetails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

⚠️ No Changeset found

Latest commit: 3b14f18

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • packages/client/src/gen/video/sfu/signal_rpc/signal.ts is excluded by !**/gen/**

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3b53eb92-84d4-4f75-9318-0d74c097e27d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updates client-side WebRTC handling to expose WebRTC version information in client details for browser and React Native environments, and propagates a negotiation identifier through the subscriber offer/answer exchange to the SFU.

Changes

Cohort / File(s) Summary
Client Details Enhancement
packages/client/src/helpers/client-details.ts
Adds webrtcVersion field to ClientDetails return object. Introduces browserVersion variable derived from user agent or fallback to browser version, used for both browser.version and webrtcVersion population in both RN and non-RN code paths.
Subscriber Offer/Answer Flow
packages/client/src/rtc/Subscriber.ts
Includes negotiationId in the answer payload sent to the SFU when processing a subscriber offer, enabling negotiation tracking at the SFU level.
Subscriber Tests
packages/client/src/rtc/__tests__/Subscriber.test.ts
Updates test to create SubscriberOffer with negotiationId field and validates propagation through the offer/answer flow to the SFU interaction payload.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A version whispered through the wire,
Negotiation IDs climb ever higher,
WebRTC signals now more clear,
Details tracked throughout the sphere! 📡✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: echoing negotiationId in the subscriber offer answer to allow SFU correlation.
Description check ✅ Passed The description covers all required template sections with clear overview, implementation notes, and relevant ticket/protocol PR references.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/echo-negotiation-id
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/client/src/rtc/Subscriber.ts`:
- Around line 168-172: The call to sfuClient.sendAnswer (sending
PeerType.SUBSCRIBER with negotiationId from subscriberOffer) is awaited but its
returned RPC payload/error is not checked; update the code around sendAnswer to
capture the response, check response.error (or equivalent error field) and
handle non-null errors by throwing or returning a failure before marking the
negotiation successful, ensuring you don't proceed when the SFU reports an error
for this negotiationId and sdp.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c43f4bbc-d046-42b9-8abb-3a3d61d78149

📥 Commits

Reviewing files that changed from the base of the PR and between 4a95b9c and 18489c1.

⛔ Files ignored due to path filters (4)
  • packages/client/src/gen/video/sfu/event/events.ts is excluded by !**/gen/**
  • packages/client/src/gen/video/sfu/models/models.ts is excluded by !**/gen/**
  • packages/client/src/gen/video/sfu/signal_rpc/signal.client.ts is excluded by !**/gen/**
  • packages/client/src/gen/video/sfu/signal_rpc/signal.ts is excluded by !**/gen/**
📒 Files selected for processing (3)
  • packages/client/src/helpers/client-details.ts
  • packages/client/src/rtc/Subscriber.ts
  • packages/client/src/rtc/__tests__/Subscriber.test.ts

Comment on lines 168 to 172
await this.sfuClient.sendAnswer({
peerType: PeerType.SUBSCRIBER,
sdp: answer.sdp || '',
negotiationId: subscriberOffer.negotiationId,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle sendAnswer RPC errors before treating negotiation as successful.

sendAnswer is awaited but its SFU error payload is not checked, which can mask negotiation failures.

💡 Proposed fix
-    await this.sfuClient.sendAnswer({
+    const { response } = await this.sfuClient.sendAnswer({
       peerType: PeerType.SUBSCRIBER,
       sdp: answer.sdp || '',
       negotiationId: subscriberOffer.negotiationId,
     });
+    if (response.error) throw new NegotiationError(response.error);
As per coding guidelines "Always check response.error from SFU RPC calls before proceeding".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/client/src/rtc/Subscriber.ts` around lines 168 - 172, The call to
sfuClient.sendAnswer (sending PeerType.SUBSCRIBER with negotiationId from
subscriberOffer) is awaited but its returned RPC payload/error is not checked;
update the code around sendAnswer to capture the response, check response.error
(or equivalent error field) and handle non-null errors by throwing or returning
a failure before marking the negotiation successful, ensuring you don't proceed
when the SFU reports an error for this negotiationId and sdp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant