Skip to content

feat: enable chat events on coordinator WebSocket#237

Open
aliev wants to merge 5 commits intomainfrom
feat/chat-events-on-coordinator-ws
Open

feat: enable chat events on coordinator WebSocket#237
aliev wants to merge 5 commits intomainfrom
feat/chat-events-on-coordinator-ws

Conversation

@aliev
Copy link
Copy Markdown
Member

@aliev aliev commented Apr 13, 2026

Why

The coordinator WebSocket is connected and receiving events, but there's no public way to register listeners on it from outside ConnectionManager. This blocks use cases like forwarding call events (turn detection, custom events) to external systems.

Changes

  • Expose coordinator_ws property on ConnectionManager for event listener registration

Usage

Receiving events:

ws = connection_manager.coordinator_ws

@ws.on("custom")
def on_custom(event):
    print(event["custom"])

ws.on_wildcard("call.**", lambda event_type, event: print(event_type))

Sending custom events:

await call.send_call_event(
    user_id="agent",
    custom={"type": "status_update", "status": "processing"},
)

Verified event types:

  • custom -- user-defined events (turn detection, agent heartbeat, etc.)
  • call.session_participant_count_updated -- participant count changes
  • health.check -- keep-alive pings

Future work

  • The Python SDK docs currently don't cover event subscription (only JS/Flutter/Kotlin/Swift do). Adding a proper event subscription API (lazy channel watching, similar to JS SDK's channel.watch() + channel.on()) is a future task once we determine the best approach for the Python SDK.

Summary by CodeRabbit

  • New Features
    • Access to coordinator events is now available after connecting, enabling real-time interaction with the coordinator.

The coordinator WS now subscribes to both video and chat products,
allowing chat events (message.new, reactions, typing, etc.) to arrive
on the same connection as video call events. No second WS needed.

- Add "chat" to products in StreamAPIWS auth payload
- Add watch_channels() in connection_utils (same pattern as watch_call)
- ConnectionManager subscribes to messaging channel after watch_call
- Expose coordinator_ws property for event listener registration
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Warning

Rate limit exceeded

@aliev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 36 minutes and 0 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 36 minutes and 0 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fb3fa856-dc0b-48a8-bd75-0fe8e1913f11

📥 Commits

Reviewing files that changed from the base of the PR and between 810998f and 2b3ba0b.

📒 Files selected for processing (1)
  • getstream/video/rtc/connection_manager.py
📝 Walkthrough

Walkthrough

A new public read-only property coordinator_ws is added to ConnectionManager that exposes the internal _coordinator_ws_client attribute, enabling direct access to the coordinator WebSocket client after connection establishment.

Changes

Cohort / File(s) Summary
ConnectionManager Property Addition
getstream/video/rtc/connection_manager.py
Added public coordinator_ws property to expose _coordinator_ws_client for accessing coordinator WebSocket events via ws.on() / ws.on_wildcard() methods; returns None when not connected.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A gateway opens, fair and bright,
Where coordinator talks take flight,
WebSocket whispers now laid bare,
For all who venture there to share!
The rabbit hops with joy so true,
New paths exposed for me and you! 🌟

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: exposing the coordinator WebSocket property to enable external event listener registration for coordinator events, which supports the stated motivation of enabling chat and call event forwarding.
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/chat-events-on-coordinator-ws

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.

Chat event subscription needs discussion with the team -- JS SDK uses
two separate WS connections for chat and video, and mixing them on one
connection may affect MAU billing. Keep coordinator_ws property for
custom events which already work via watch_call.
Copy link
Copy Markdown

@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 `@getstream/video/rtc/connection_manager.py`:
- Around line 623-632: The property coordinator_ws should honor "Returns None if
not connected" by returning the websocket client only when it is actually
connected; update coordinator_ws to check _coordinator_ws_client's connection
state (e.g., _coordinator_ws_client.connected or
_coordinator_ws_client.is_connected) and/or ensure the coordinator helper/task
(e.g., _coordinator_task) is still running, and return None otherwise; use
getattr checks to avoid attribute errors so callers never receive a
non-connected client from coordinator_ws.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 66b96399-2289-4c8e-be81-8a56b62ec916

📥 Commits

Reviewing files that changed from the base of the PR and between 7c4c123 and 810998f.

📒 Files selected for processing (1)
  • getstream/video/rtc/connection_manager.py

Return Optional[StreamAPIWS] and check _connected before returning,
so callers get None instead of a disconnected client.
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.

2 participants