Exposing LiveKit status in site settings serializer

@Falco Is it possible to expose a public check in the site settings/serializer for whether LiveKit is configured, alongside voice_enabled?

Today voice_enabled is client-exposed, but there’s no public signal for whether a site can serve LiveKit. The only LiveKit-related site attribute, voice_livekit_per_room_available, is scoped to the room-form checkbox, so it returns false under the all_rooms policy and can’t be used to answer “does this site do LiveKit at all”.

RoomSerializer#expected_transport covers the per-room case nicely, but that requires fetching rooms first, and it comes back empty when voice_public_access is off, even on a site where LiveKit is fully configured.

Would something like this be acceptable? It’s derived from existing state, exposes no credentials or policy detail, and needs no new endpoint.

It would go in plugins/voice/plugin.rb, after the voice_livekit_per_room_available block and just before the Voice::DefaultRoomSeeder.ensure! line:

# Public, credential-free signal that the site can serve LiveKit at all.
add_to_serializer(:site, :voice_livekit_available) do
Voice::Livekit.configured? && SiteSetting.voice_livekit_room_policy != "disabled"
end

voice_enabled isn’t reachable from the JSON API at all: /site.json carries no site_settings key. So the only public signal that voice is running on a site is the presence of voice_assets_path.

What I’m asking for is two public, credential-free booleans so a client can decide whether to surface voice before fetching any rooms. Both are derived from existing state and need no new endpoint, in plugins/voice/plugin.rb:

At line 141, above voice_public_access:

#Public, credential-free signals for API clients that voice is enabled.

add_to_serializer(:site, :voice_available) { SiteSetting.voice_enabled }

At line 152, above voice_livekit_per_room_available:

# Whether joins can use LiveKit at all. A bare yes/no: no URL, key or
# policy value. The per-room attribute below only gates the room form's
# SFU checkbox, and reads false under the all_rooms policy.

  add_to_serializer(:site, :voice_livekit_available) do

    Voice::Livekit.configured? && SiteSetting.voice_livekit_room_policy != "disabled"

  end

This exposes nothing new: expected_transport is an ungated attribute on RoomSerializer (line 30, defined at 150) and rooms#index skips login (rooms_controller.rb:18), so “livekit” / “mesh” is already anonymously readable per room. This just answers it without a room fetch that may come back empty.

Please don’t mention team members in-bulk like that (I edited the mentions out).

It may help if you describe what your end goal is for this extra information. It’s hard to answer a feature-request without any justification for what you’ll be using the information for.

Apologies I asked a question on an announcement and I was split to support, which left me unaware of who to speak to since this is a feature request than troubleshooting, after reviewing for past 5hrs I tagged the members from the core commit/merge of voice.

However to add some context. I have an application that acts as a multi-client for Discourse communities, each configured differently, so at boot it builds the navigation for whichever site the user is on. Chat appears if chat is enabled, and I’d like voice to appear if voice is enabled and actually joinable from the app.

The app joins over LiveKit and can’t do mesh, so on a mesh site I want to leave voice out of the navigation entirely rather than show rooms that will fail to connect and make it look like the app is broken.

So the flow is: read site info once at boot, decide whether voice belongs in the app for that site, then use expected_transport per room once the user opens it. The two booleans are just the first step, and without them I’m either showing a feature that can’t work or hiding one that can.

Alternatively I can place “Not Available on this Forum” in a global alert within the application regardless of being enabled but this seemed like the better approach so I’ve pinpointed the entry point and gave the code and comments.

Thanks for the explanation! The request makes sense.

The voice plugin is new and in an experimental state. It will likely go through changes in the next few weeks and months. Especially internal changes. We are open to exposing this information in some fashion, but can’t be sure yet what that form will be. It depends on how the LiveKit integration evolves.

If you think 5h is too much to wait, you may be new to the concept of async comms in forums. Welcome!

I will investigate this and come up with something we can use.

I think you misunderstood, I was up from 1am to 5am reviewing what was done and the merges that’s how i found the team members i originally tagged. Not that i’m waiting on a reply for 5hrs. The app already submitted for review and it’s utilizing the default system I already have.

That’s fine by me, take as much time as needed. I’ve done my testing over a period of 6 months, took some fine tuning for scaling.