Allow configuring whether a VAD model runs before calling an external ASR API.
Running VAD can save API calls (and costs) when no audible sound is detected,
but comes with the trade-off of additional computational overhead.
After upgrading Python to 3.13, not all development environments were
updated accordingly. This fixes the incorrect volume mount path
introduced by that upgrade.
Fix MinIO client configuration: I was incorrectly passing a full URL instead of
an endpoint, which caused errors in staging. Local development values did not
reflect the staging setup and were also out of sync with the backend.
Fix an unexpected behavior where filtering LiveKit webhook events sometimes
failed because the room name was not reliably extracted from the webhook data,
causing notifications to be ignored.
Configure the same filtering logic locally to avoid missing this kind of issue
in the future.
Pin egress to the production version, which uses a more recent release than the
default chart value (1.9.0).
Using the default could have led to issues; hopefully this change avoids them.
Link the transcription document to its related recording by adding a short
header explaining that users can download the audio file via a dedicated link.
This was a highly requested feature, as many users need to keep their audio
files.
As part of a small refactor, remove the argument length check in the metadata
analytics class. The hardcoded argument count made code evolution harder and was
easy to forget updating. Argument unwrapping remains fragile and should be
redesigned later to be more robust.
The backend is responsible for generating the download link to ensure
consistency and reliability.
I tried adding a divider, but the Markdown-to-Yjs conversion is very lossy and
almost never handles it correctly. Only about one out of ten conversions works
as expected.
Not all self-hosted instances will configure this setting, so a default text is
shown when the destination is unknown.
This is important to let users quickly click the link and understand which
platform is used to handle the transcription documents.
Explicitly explain that transcription is reserved for public servants. Remove
the temporary beta form: the feature is now available to all public servants,
with restrictions based on domain. Make white-labeling rules explicit and
clarify who to contact for access.
The beta form created frustration, with users registering and never hearing
back from the team.
Improve guidance when a user may be the meeting host but is not logged in, and
therefore cannot activate recording. Add a clear hint and a quick action to log
in. This decision is based on frequent support requests where users could not
understand why recording was unavailable while they were simply not logged in.
Introduce pop-in alerting participants of automatic 2-minute idle
disconnect to enable LiveKit node configuration updates during
maintenance windows, preventing forgotten tabs from blocking
overnight production updates following patterns
from proprietary videoconference solutions.
Make WhisperX language detection configurable through FastAPI settings
to handle empty audio start scenarios where automatic detection fails and
incorrectly defaults to English despite 99% French usage.
Quick fix acknowledging long-term solution should allow dynamic
per-recording language selection configured by users through web
interface rather than global server settings.
Remove incorrect whitespace in queue names that prevented Celery
workers from listening to proper queues. Workers were attempting to
connect to non-existent queues, breaking task distribution.
Add Celery summarize and transcribe worker configuration to Helm
charts for summary microservice. Create new deployment resources
and increment chart version to support distributed task processing.
Implement summarization functionality that processes completed meeting
transcripts to generate concise summaries.
First draft base on a simple recursive agentic scenario.
Observability and evaluation will be added in the next PRs.
Rename incorrectly named OpenAI configuration settings since
they're used to instantiate WhisperX client which is not OpenAI
compatible, preventing confusion about actual service dependencies.
Allow any user, anonymous or authenticated, to start subtitling
in a room only if they are an active participant of it.
Subtitling a room consists of starting the multi-user transcriber agent.
This agent forwards all participants' audio to an STT server and returns
transcription segments for any active voice to the room.
User roles in the backend room system cannot be used
to determine subtitle permissions.
The transcriber agent can be triggered multiple times but will only join a
room once. Unicity is managed by the agent itself.
Any user with a valid LiveKit token can initiate subtitles. Feature flag
logic is implemented on the frontend. The frontend ensures the "start
subtitle" action is only available to users who should see it. The backend
does not enforce feature flags in this version.
Authentication in our system does not imply access to a room. The only
valid proof of access is the LiveKit API token issued by the backend.
Security consideration: A LiveKit API token is valid for 6 hours and
cannot be revoked at the end of a meeting. It is important to verify
that the token was issued for the correct room.
Calls to the agent dispatch endpoint must be server-initiated. The backend
proxies these calls, as clients cannot securely contact the agent dispatch
endpoint directly (per LiveKit documentation).
Room ID is passed as a query parameter. There is currently no validation
ensuring that the room exists prior to agent dispatch.
TODO: implement validation or error handling for non-existent rooms.
The backend does not forward LiveKit tokens to the agent. Default API
rate limiting is applied to prevent abuse.
Create basic Helm chart for LiveKit agent framework deployment on
Kubernetes, inspired by meet-summary FastAPI server configuration.
Integrate chart into local tilt development stack and properly handle
certificate issues that typically occur when calling LiveKit server
with nip.io domain names.
Remove call to generate demo data in tilt stack as it was never useful
to developers and only complicated the migration job unnecessarily.
Migration job should be laser focused on applying database migrations
rather than seeding mock data, improving clarity and reducing
complexity.
Replace mock Django secret key with longer version to resolve security
warnings in development stack.
Still not production-suitable as key remains versioned in repository,
but eliminates security warnings during development workflow.
Remove dependencies on bitnami Helm charts since recent changes in
bitnami organization led to charts no longer being maintained or
published.
Enhanced the Tilt dependencies to avoid any bootstrap or refresh
errors while developping using the Tilt stack.
Making components dependant from each others increase slightly
the time required to spin up the stack the first time.
Add default telephony configuration to the tilt stack to enable
development workflow around authentication features.
Note: This is a fake/mock configuration and is not functional for
production use. It's intended solely for development purposes.
The LiveKit API URL is necessary to interact with the API. It uses https
protocol.
Eplicit wss protocol is necessary in Websocket constructor for some
older browsers.
This resolves critical compatibility issues with legacy browsers
(notably Firefox <124, Chrome <125, Edge <125) that lack support
for HTTPS URLs in the WebSocket() constructor. Without explicit WSS
URLs, WebSocket signaling connections may fail, crash, or be blocked
entirely in these environments.
The setting is optional and defaults to the current behavior when
not specified, ensuring zero breaking changes for existing deployments.
Connection warmup wasn't working properly - only works when trying to
establish WebSocket first, then workaround kicks in. Call WebSocket
endpoint without auth info expecting 401 error, but enough to initiate
cache for subsequent WebSocket functionality.
Scope this **dirty** trick to Firefox users only. Haven't figured out
how to detect proxy from JS code simply.
Tested in staging and works on our constrained WiFi.
Add product analytics to understand summary feature usage and behavior.
Track transcript and task metadata for insights without exposing sensitive
content or speaker data.
Hacky but functional PostHog usage - fully optional for self-hosting.
Extensive tracking approach works for current needs despite not being
PostHog's typical use case.
Replace default "visio" with "LaSuite Meet" and allow env variable
customization. Default Docker image uses "LaSuite Meet", but deployments
can override with custom values by setting env vars and rebuilding.
Our Helm chart wasn't suitable for use with Helm alone because jobs
remained after deployment. We chose to configure ttlSecondsAfterFinished
to clean up jobs after a period of time.
Enable users to join rooms via SIP telephony by:
- Dialing the SIP trunk number
- Entering the room's PIN followed by '#'
The PIN code needs to be generated before the LiveKit room is created,
allowing the owner to send invites to participants in advance.
With 10-digit PINs (10^10 combinations) and a large number of rooms
(e.g., 1M), collisions become statistically inevitable. A retry mechanism
helps reduce the chance of repeated collisions but doesn't eliminate
the overall risk.
With 100K generated PINs, the probability of at least one collision exceeds
39%, due to the birthday paradox.
To scale safely, we’ll later propose using multiple trunks. Each trunk
will handle a separate PIN namespace, and the combination of trunk_id and PIN
will ensure uniqueness. Room assignment will be evenly distributed across
trunks to balance load and minimize collisions.
Following XP principles, we’ll ship the simplest working version of this
feature. The goal is to deliver value quickly without over-engineering.
We’re not solving scaling challenges we don’t currently face.
Our production load is around 10,000 rooms — well within safe limits for
the initial implementation.
Discussion points:
- The `while` loop should be reviewed. Should we add rate limiting
for failed attempts?
- A systematic existence check before `INSERT` is more costly for a rare
event and doesn't prevent race conditions, whereas retrying on integrity
errors is more efficient overall.
- Should we add logging or monitoring to track and analyze collisions?
I tried to balance performance and simplicity while ensuring the
robustness of the PIN generation process.
Implement conditional rendering that hides all feedback-related UI components
when feedback is disabled in backend configuration.
Also, feedback URL is now customizable.
Refactor BaseEgress class to leverage latest livekit-api client's custom
session support. Simplifies code by using built-in capability to disable SSL
verification in development environments instead of previous workaround.
Add new application base URL configuration setting. While somewhat redundant
with existing domain setting, these serve different purposes in the
application. Base URL will be used for constructing complete URLs in
notifications and external references.
Implement secure recording file access through authentication instead of
exposing S3 bucket or using temporary signed links with loose permissions.
Inspired by docs and @spaccoud's implementation, with comprehensive
viewset checks to prevent unauthorized recording downloads.
The ingress reserved to media intercept the original request, and thanks to
Nginx annotations, check with the backend if the user is allowed to donwload
this recording file. This might introduce a dependency to Nginx in the project
by the way.
Note: Tests are integration-based rather than unit tests, requiring minio in
the compose stack and CI environment. Implementation includes known botocore
deprecation warnings that per GitHub issues won't be resolved for months.
Implement backend method to send email notifications when screen recordings
are ready for download. Enables users to be alerted when their recordings are
available. Frontend implementation to follow in upcoming commits.
This service is triggered by the storage hook from Minio.
Add minimal unit test coverage for notification service, addressing previous
lack of tests in this area. The notification service was responsible for
calling the unstable summary service feature, which was developped way too
quickly.
The email template has been reviewed by a LLM, to make it user-friendly and
crystal clear.
Override LiveKit Docker image to include nip.io Certificate Authority for
development environment. Addresses issue where LiveKit webhook calls fail in
dev mode due to unknown CA. Custom image places certificate in appropriate
location since LiveKit chart lacks volume mounting options for CA certs or
webhook SSL disabling capabilities.
Discussed with @rouja.
Enable LiveKit webhook feature to notify backend when events occur in rooms.
Configure LiveKit to call our endpoint whenever events are triggered,
providing real-time updates on room activities. Refer to LiveKit
documentation or LiveKitWebhookEventType enum for complete list of available
events.
This commit is not functionnal, LiveKit fails verifying our backend's
certificate. It will be fixed in the upcoming commits.
LiveKit uses aiohttp which relies on the ssl module under the hood.
Set certificate file using an env variable, similar to @rouja's fix
for the request module.
This tweak applies only in the dev environment.
Replace invalid session/end endpoint with correct logout endpoint in Keycloak
configuration. Fixes broken logout functionality that prevented developers
from properly signing out of the application during development.
Avoid disabling SSL verification in development environment,
simply mount in the right folder, an extra volume, that declares
the certificate authority necessary to validate nip.io domains.
Refactored ClusterSecretStore and ExternalSecret deployment to support
VaultWarden custom fields beyond login/password, including multi-line
values via file input. Also made the secret template name configurable
for added flexibility.
ClusterSecretStore are supposed to be cluster-wide objects, it's useless
to precise any namespace.
Offer a standalone dev environment or a dinum specific dev
environment with ProConnect authentication.
Needed to refactor the way secrets are managed in the project,
and also re-organize the Helm chart to make it totally standalone.
Particulary useful for external wanting to run the project.
Work done by @rouja.