mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
feat(voice): ship noise suppression treatment to everyone (#3029)
This commit is contained in:
@@ -34,7 +34,6 @@ Missing settings use the defaults documented below. Invalid stored configuration
|
||||
| --- | --- | --- |
|
||||
| sso | [SSO configuration](#sso-configuration-object) object | Single sign-on settings |
|
||||
| gateway_rollout | [Gateway rollout configuration](#gateway-rollout-configuration-object) object | Gateway admission and dispatch tuning |
|
||||
| voice_noise_suppression | [voice noise suppression configuration](#voice-noise-suppression-configuration-object) object | Client-side noise suppression rollout |
|
||||
| push_relay | [push relay configuration](#push-relay-configuration-object) object | Operator consent to the Fluxer-run push relay |
|
||||
| domain_migration | [domain migration configuration](#domain-migration-configuration-object) object | Web domain migration rollout |
|
||||
| altcha_captcha | [ALTCHA captcha configuration](#altcha-captcha-configuration-object) object | ALTCHA proof-of-work captcha rollout |
|
||||
@@ -99,34 +98,6 @@ Every field is present on read. An absent document or missing field uses the def
|
||||
|
||||
Admin reads and writes name this field `rpc_request_timeout_ms`. The legacy stored name is covered in the [operator configuration reference](/operator/configuration/#stored-instance-policy).
|
||||
|
||||
## Voice noise suppression configuration object
|
||||
|
||||
The instance rollout of client-side noise suppression. [Experiments](/http-api/experiments/) defines what a client resolves from it and the closed [backend registry](/http-api/experiments/#noise-suppression-backends) every backend field draws on.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| enabled | boolean | Whether the rollout runs at all (default false) |
|
||||
| config_version | integer | Revision counter, raised by Fluxer and never accepted from a request |
|
||||
| default_backend | string | Backend given to an account the rollout selects (default `standard`) |
|
||||
| enabled_backends | array[string] | Backends a client MAY run, up to 7 entries (default every backend) |
|
||||
| allow_user_override | boolean | Whether an account's own choice replaces the assigned backend (default true) |
|
||||
| rollout_basis_points | integer | Share of accounts the rollout selects, in basis points (0-10000, default 0) |
|
||||
| rollout_salt | string | Salt of the sampling hash (1-64 characters, default `voice-ns-v1`) |
|
||||
| included_user_ids | array[snowflake] | Accounts the rollout always selects, up to 1000 entries (default empty) |
|
||||
| included_guild_ids | array[snowflake] | Guilds whose members the rollout always selects, up to 1000 entries (default empty) |
|
||||
| include_premium_users | boolean | Whether the rollout always selects accounts with active premium (default false) |
|
||||
| excluded_user_ids | array[snowflake] | Accounts the rollout never selects, up to 1000 entries (default empty) |
|
||||
| guild_overrides | array[[guild override](/http-api/experiments/#noise-suppression-guild-override-object) object] | Per-guild replacements, up to 200 entries (default empty) |
|
||||
| suppression_strength | integer | Suppression strength (0-100, default 80) |
|
||||
|
||||
Every field is present on read. An absent document or missing field uses the defaults above.
|
||||
|
||||
`excluded_user_ids` wins over every other rule. Otherwise the rollout selects an account in `included_user_ids`, a member of a guild in `included_guild_ids`, or a premium account while `include_premium_users` is true, whatever `rollout_basis_points` says. A `default_backend` or `guild_overrides` entry naming a backend outside `enabled_backends` is dropped from what a client is served, and the stored value is kept as written.
|
||||
|
||||
How often a client revalidates this rollout is not set here. It is set once for every experiment in the [experiment delivery configuration](#experiment-delivery-configuration-object) below.
|
||||
|
||||
## Push relay configuration object
|
||||
|
||||
The operator's consent to the push relay supplemental privacy notice.
|
||||
@@ -686,7 +657,6 @@ The body has one optional object for each section. Fluxer leaves an absent secti
|
||||
| --- | --- | --- |
|
||||
| sso?<sup>1</sup> | object | Every [SSO configuration](#sso-configuration-object) field except `client_secret_set` and `redirect_uri`, plus `client_secret` |
|
||||
| gateway_rollout? | object | Any subset of the [Gateway rollout configuration](#gateway-rollout-configuration-object) fields, each bound as documented there |
|
||||
| voice_noise_suppression? | object | Any subset of the [noise suppression](#voice-noise-suppression-configuration-object) fields |
|
||||
| push_relay? | object | `relay_consent_accepted` from the [push relay configuration](#push-relay-configuration-object) |
|
||||
| domain_migration? | object | Any subset of the [domain migration](#domain-migration-configuration-object) fields |
|
||||
| altcha_captcha? | object | Any subset of the [ALTCHA captcha](#altcha-captcha-configuration-object) fields |
|
||||
@@ -703,11 +673,9 @@ The body has one optional object for each section. Fluxer leaves an absent secti
|
||||
|
||||
<sup>2</sup> `branding.product_name` is 1 to 80 characters, every branding and legal URL is at most 2048 characters and nullable, `branding.theme_color` is at most 64 characters and nullable, and `setup.configured` and `registration.collect_date_of_birth` are booleans. `branding.premium_product_name` is 1 to 40 characters, and null restores the default. `branding.premium_info_url` is an absolute `http` or `https` URL. Every string is trimmed before it is stored
|
||||
|
||||
`voice_noise_suppression` takes every [voice noise suppression configuration](#voice-noise-suppression-configuration-object) field except `config_version`, each bound as documented there. Fluxer raises `config_version` by one on each request that supplies at least one of them. A section that is absent, or present with no field set, writes nothing and leaves `config_version` alone.
|
||||
|
||||
`push_relay` takes only `relay_consent_accepted`. Fluxer sets `relay_consent_accepted_at` and `relay_consent_accepted_by` itself on the request that changes that flag, and accepts neither from a request. Turning the flag on stamps the current time and the acting account, and turning it off clears both to null. A request that repeats the flag it already holds leaves the stamp alone.
|
||||
|
||||
`domain_migration` works the same way as `voice_noise_suppression`, over the [domain migration configuration](#domain-migration-configuration-object) fields and its own `config_version`.
|
||||
`domain_migration` takes every [domain migration configuration](#domain-migration-configuration-object) field except `config_version`, each bound as documented there. Fluxer raises `config_version` by one on each request that supplies at least one of them. A section that is absent, or present with no field set, writes nothing and leaves `config_version` alone.
|
||||
|
||||
`altcha_captcha` works the same way, over the [ALTCHA captcha configuration](#altcha-captcha-configuration-object) fields and its own `config_version`.
|
||||
|
||||
@@ -753,7 +721,7 @@ On a self-hosted deployment, billing and the `everyone` premium mode exclude eac
|
||||
| 400 | [error response](/admin-api/#error-response) | A policy transition is refused, returned as `INSTANCE_POLICY_TRANSITION_NOT_ALLOWED` |
|
||||
|
||||
:::caution[Sections are applied one after another]
|
||||
The order is `gateway_rollout`, `voice_noise_suppression`, `push_relay`, `domain_migration`, `altcha_captcha`, `profile_timezone`, `experiment_delivery`, `sso`, `registration`, `app_public` branding, legal, and registration fields, `integrations`, `media`, `policy`, `billing`, and finally `app_public.setup`. A failure part way through leaves the earlier sections written.
|
||||
The order is `gateway_rollout`, `push_relay`, `domain_migration`, `altcha_captcha`, `profile_timezone`, `experiment_delivery`, `sso`, `registration`, `app_public` branding, legal, and registration fields, `integrations`, `media`, `policy`, `billing`, and finally `app_public.setup`. A failure part way through leaves the earlier sections written.
|
||||
:::
|
||||
|
||||
### Side effects
|
||||
|
||||
@@ -6,7 +6,7 @@ description: The experiment assignments envelope, the revalidation and polling c
|
||||
|
||||
import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
An experiment is an instance-wide rollout that an operator configures. For each account, Fluxer works out from that configuration whether the account is in the rollout and which settings the account receives. The single route on this page resolves every experiment the server defines and returns them in one envelope, together with the polling cadence they share. This server defines `voice_noise_suppression`, whose placement protocol [Voice](/voice/) defines, `domain_migration`, `altcha_captcha` and `profile_timezone`.
|
||||
An experiment is an instance-wide rollout that an operator configures. For each account, Fluxer works out from that configuration whether the account is in the rollout and which settings the account receives. The single route on this page resolves every experiment the server defines and returns them in one envelope, together with the polling cadence they share. This server defines `domain_migration`, `altcha_captcha` and `profile_timezone`.
|
||||
|
||||
Every assignment is advice. A client that ignores one behaves as it does with the rollout off, and no route and no Gateway event reports what a client actually ran.
|
||||
|
||||
@@ -32,78 +32,12 @@ One entry per experiment. The envelope reports this object even when it is empty
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| voice_noise_suppression? | [noise suppression assignment](#noise-suppression-assignment-object) object | The caller's noise suppression assignment |
|
||||
| domain_migration? | [domain migration assignment](#domain-migration-assignment-object) object | The caller's web domain migration assignment |
|
||||
| altcha_captcha? | [ALTCHA captcha assignment](#altcha-captcha-assignment-object) object | The caller's captcha provider assignment |
|
||||
| profile_timezone? | [profile timezone assignment](#profile-timezone-assignment-object) object | The caller's profile timezone assignment |
|
||||
|
||||
Ignore unknown experiments and treat a missing experiment as off.
|
||||
|
||||
This server version writes `voice_noise_suppression` on every response, including while a rollout is disabled. The disabled value is the first [resolution outcome](#resolution-outcomes) below, which reports `enabled` false and the stored `config_version`, so a client that compares `config_version` with the value from its previous response can see that an operator saved the configuration, even while the rollout stays disabled, and needs no second request for it.
|
||||
|
||||
## Noise suppression backends
|
||||
|
||||
Noise suppression runs in the client, on the microphone track, before that track is published. Fluxer processes no audio for it. The registry is closed, and a backend outside it is not a value this API produces or accepts.
|
||||
|
||||
| Value | Description |
|
||||
| --- | --- |
|
||||
| none | No processing |
|
||||
| standard | The browser or platform suppressor the client already has |
|
||||
| gate | A noise gate keyed on input level |
|
||||
| speex | The Speex preprocessor |
|
||||
| rnnoise | The RNNoise recurrent model |
|
||||
| gtcrn | The GTCRN model |
|
||||
| deep_filter | The DeepFilterNet model |
|
||||
|
||||
A client MUST treat a backend absent from `enabled_backends` as unavailable, including one named by `backend` or by a [guild override](#noise-suppression-guild-override-object).
|
||||
|
||||
## Noise suppression assignment object
|
||||
|
||||
One resolution of the instance noise suppression rollout against one account. Every field is present whenever the key is written.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| enabled | boolean | Whether the rollout is running on this instance |
|
||||
| config_version | integer | The revision of the instance configuration this assignment was resolved from |
|
||||
| user_targeted | boolean | Whether the caller is inside the rollout |
|
||||
| backend | ?string | The [backend](#noise-suppression-backends) the caller applies, and null where the caller is not targeted |
|
||||
| source | ?string | Which rule targeted the caller, one of `user_rule` or `canary`, and null where the caller is not targeted |
|
||||
| guild_overrides | array[[guild override](#noise-suppression-guild-override-object) object] | Per-guild backend replacements that apply to the caller |
|
||||
| enabled_backends | array[string] | The [backends](#noise-suppression-backends) the client MAY run |
|
||||
| allow_user_override | boolean | Whether the account's own stored choice replaces `backend` |
|
||||
| suppression_strength | integer | Suppression strength from 0 through 100, which only a backend that reads it applies |
|
||||
|
||||
`config_version` identifies the configuration revision. It can change without changing the caller's assignment.
|
||||
|
||||
### Resolution outcomes
|
||||
|
||||
The outcomes below set `user_targeted` to false, and they differ in what else they report.
|
||||
|
||||
1. The rollout is off. `enabled` is false, `enabled_backends` and `guild_overrides` are empty, and `allow_user_override` is false.
|
||||
2. The operator has excluded the caller. `enabled` is true, and every other field is as in the first outcome.
|
||||
3. The caller was not drawn. `enabled` is true, and `enabled_backends`, `guild_overrides`, and `allow_user_override` all hold their configured values.
|
||||
|
||||
A caller is drawn by the operator's account or guild allowlist, by having premium when the operator includes premium users, or by the sampled share of the account population. The sampled share sets `source` to `canary`, and every other rule sets it to `user_rule`. A caller that is drawn while `backend` is absent from `enabled_backends` is reported as not drawn, with `user_targeted` false and both `backend` and `source` null.
|
||||
|
||||
A client branches on `user_targeted` rather than on `enabled_backends`, because the third outcome keeps the array populated. A `guild_overrides` entry applies in its guild whether or not the caller was drawn.
|
||||
|
||||
`config_version` reports the stored revision in all outcomes, the rollout being off included.
|
||||
|
||||
## Noise suppression guild override object
|
||||
|
||||
One backend replacement scoped to one guild. While the caller is connected to a voice channel of that guild, the override's `backend` replaces the assignment's `backend`.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| guild_id | snowflake | The guild the replacement applies in |
|
||||
| backend | string | The [backend](#noise-suppression-backends) to run in that guild |
|
||||
|
||||
An override naming a backend that is absent from `enabled_backends` is dropped before the response is written, so every entry is runnable.
|
||||
|
||||
## Domain migration assignment object
|
||||
|
||||
One resolution of the instance web domain migration rollout against one account. This server version writes the key on every response.
|
||||
|
||||
Reference in New Issue
Block a user