Coverage Report

Created: 2026-11-04 02:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
super-tts-daemon/src/daemon/http/v1/registry/list.rs
Line
Count
Source
1
// SPDX-License-Identifier: GPL-3.0-only
2
use crate::daemon::http::state::AppState;
3
use crate::daemon::http::wire::{ErrorEnvelope, ReasonEnvelope, RegistryError};
4
use axum::extract::{Query, State};
5
use axum::response::Response;
6
use super_engine_daemon::registry::endpoints::{self, ListQuery};
7
use super_tts_shared::registry::RegistryListResponse;
8
9
/// `GET /registry/backend/list` — list installable backends from the registry.
10
#[utoipa::path(
11
    get,
12
    path = "/registry/backend/list",
13
    tag = "registry",
14
    summary = "Browse the published backend catalog",
15
    description = "\
16
Every backend published to the registry, with the models each serves and whether this \
17
machine can run it. `compatibility.compatible` is decided against the host's actual \
18
accelerators and this Super TTS's version, so the list reflects what is installable here \
19
rather than what exists in general; pass `include_incompatible=true` to see the rest, each \
20
with a `compatibility.reason` worth showing the user.
21
22
`needs_client_update` separates the two ways a backend can be blocked: a host that lacks \
23
the right GPU will never run it, but a Super TTS one version behind is something the user \
24
can fix in a minute. Those are listed even without `include_incompatible`; surface them \
25
differently.
26
27
`update_available` is the daemon's answer rather than the client's arithmetic: it \
28
compares the installed `backend.toml` on disk against what the index offers, by \
29
`source`, and refuses a downgrade. An entry with no `installed_version` is an install, \
30
not an update.
31
32
This is what is *available*; `GET /backend/list` is what is installed. The index is \
33
cached and re-fetched on a schedule — `POST /registry/backend/refresh` forces that \
34
now.",
35
    params(ListQuery),
36
    security(("session_token" = ["settings"])),
37
    responses(
38
        (status = 200, description = "The catalog.", body = RegistryListResponse),
39
        (status = 401, description = "Token unknown, expired, or its binary changed.", body = ReasonEnvelope),
40
        (status = 403, description = "The token lacks the `settings` scope.", body = ErrorEnvelope),
41
        (status = 429, description = "Per-client rate limit hit; back off and retry.", body = ErrorEnvelope),
42
        (status = 503, description = "The catalog could not be fetched and nothing is cached (`registry_unavailable`). Retry, or force a fetch with `POST /registry/backend/refresh`.", body = RegistryError),
43
    ),
44
)]
45
0
pub(crate) async fn list_registry_backends(
46
0
    State(s): State<AppState>,
47
0
    Query(q): Query<ListQuery>,
48
0
) -> Response {
49
0
    endpoints::list(&s.registry, &q).await
50
0
}