Skip to content

Conversation

Kaian
Copy link

@Kaian Kaian commented Aug 27, 2025

We've been exploring the idea of enabling real attended call transfers from LiveKit rooms, with the first step being support for call holding. When connecting LiveKit Trunks from a PBX, this allows music-on-hold configured in the PBX to be played to the participant.

This PR introduces the initial implementation of call hold and unhold functionality in the LiveKit SIP component. It allows the LiveKit Server to put SIP calls on hold and resume them (unhold), by adding the necessary handling of re-INVITE messages for hold/unhold.

Further PRs will be required in other LiveKit projects to fully implement this functionality across the platform (including livekit, livekit-sdks, livekit-protocol and so on).

We’d love to hear if the team is interested in this functionality and any feedback on the approach to summit additional Pull Requests.

@Kaian Kaian requested a review from a team as a code owner August 27, 2025 09:33
@CLAassistant
Copy link

CLAassistant commented Aug 27, 2025

CLA assistant check
All committers have signed the CLA.

@Kaian Kaian force-pushed the hold-resume-initial-implementation branch 2 times, most recently from 8a4cd77 to 04d94e4 Compare August 27, 2025 10:21
Copy link

codecov bot commented Aug 27, 2025

Codecov Report

❌ Patch coverage is 10.10101% with 356 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.97%. Comparing base (0460b40) to head (04d94e4).
⚠️ Report is 131 commits behind head on main.

Files with missing lines Patch % Lines
pkg/sip/inbound.go 2.56% 150 Missing and 2 partials ⚠️
pkg/sip/outbound.go 2.56% 152 Missing ⚠️
pkg/sip/service.go 0.00% 50 Missing ⚠️
pkg/service/service.go 88.88% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #443      +/-   ##
==========================================
- Coverage   65.25%   59.97%   -5.29%     
==========================================
  Files          51       32      -19     
  Lines        6588     7105     +517     
==========================================
- Hits         4299     4261      -38     
- Misses       1915     2462     +547     
- Partials      374      382       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@dennwc dennwc left a comment

Choose a reason for hiding this comment

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

Thank you a lot for contributing the hold/resume functionality! The idea and implementation makes perfect sense. New internal API is the most straightforward way to achieve this.

What I'm wondering about is, would it make sense to hold/unhold automatically when SIP participant looses all audio track subscriptions? In this case, if a person/agent that is in the room suddenly drops, we could indicate a hold for the SIP participant instead of just relaying silence.

This way, there will be no extra API required - existing participant admin API can be used to unsubscribe SIP from existing tracks, move it to another empty room or disconnecting the other peer from the room.

What do you think about this approach?

@Kaian
Copy link
Author

Kaian commented Aug 27, 2025

Hi!

Thanks for the feedback!

We're currently testing this feature in the following scenario: An incoming call is dispatched to a room where an agent can be requested to perform a transfer, first checking whether the destination is available. The agent places the first participant on hold and creates a second participant in the same room by making an outbound call. When this second participant answers, their availability is verified, and based on the response, we remove the second participant from the room and perform a cold transfer from the first participant (or not). This approach has some advantages, such as providing a full transcription or recording of the entire process while only using a single room.

I have little to no experience with LiveKit, so I cannot say what the best approach would be. However, I’m concerned that some providers may not accept in-dialog re-INVITEs the way PBXs do, so making this behavior implicit could cause future issues in other scenarios.

Of course, your opinion is what matters the most, and if you decide to implement it differently, we’ll be more than happy to adapt how our agent works!

Best regards,

@Kaian Kaian force-pushed the hold-resume-initial-implementation branch from 04d94e4 to 8c5ab03 Compare October 2, 2025 14:32
@Kaian
Copy link
Author

Kaian commented Oct 2, 2025

Hi!

Sorry for the long silence, I've been quite busy.

I've been thinking about your proposal, and I understand the point of not changing the API to avoid impacting other modules (SDK, protocol, etc.).

I think at least a Trunk flag will be necessary to mark which providers support receiving an in-dialog re-INVITE, something like holdSupport, disabled by default for inbound/outbound trunks. Media direction would only change for those capable of playing music on hold.

I've rebased and updated the patch by removing some unnecessary code, fixing a problem with SDPVersion not being updated in new messages, and removing all internal API-related code. As a result, the hold/unhold functions are not actually used in this current proposed code. I'm not sure where track subscriptions should be handled to trigger the hold/unhold process (maybe in the LiveKit core project?) so I’ll need some guidance.

Also, regarding the failing tests, I don’t know what the root cause of the problem is and I’m not sure how our changes might have affected them.

Feel free to request any additional information; we’re entirely at your disposal.

Thanks for your time!

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.

3 participants