mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-14 03:33:43 +08:00
Phase 1 of the model-module refactor: combine pool / cooldown / probe-
completion signals into a single Liveness state surfaced through the
provider DTO, so the dropdown stops listing providers that are provably
unreachable. Zero schema change; one PR backend + frontend.
Backend
- Liveness enum with five mutually-exclusive states: LIVE, COOLDOWN,
REMOVED, UNPROBED, UNCONFIGURED. Computed in ModelProviderService
from AvailableProviderPool / ProviderHealthTracker / ProviderInitProbe
snapshots batched once per listProviders() call.
- ProviderInitProbe.hasBeenProbed exposes a monotonic Set so the UI
can distinguish 'still booting' from 'probed and removed' — without
it the startup window flashes false REMOVED states.
- ProviderInfoDTO gains liveness + unavailableReason +
cooldownRemainingMs + lastProbedAtMs. The legacy 'available' boolean
stays but is now derived from liveness == LIVE so the chat fallback
walker and the dropdown agree about what's usable.
- ProviderInitProbe injected into ModelProviderService via
ObjectProvider to break the startup cycle (probe already depends on
the service).
Frontend
- ProviderInfo type extended with liveness + the three detail fields.
- ModelSelector filters UNCONFIGURED + REMOVED out of the dropdown,
shows COOLDOWN / UNPROBED with a status dot and dimmed rows that the
user can still click to override.
- ProviderCard renders a five-state badge driven by liveness instead
of the old configured + pool-entry combo. Reprobe button now keys
off liveness in {REMOVED, COOLDOWN}.
- useProviders drops loadProviderPool / providerPool — pool data ships
inline on each ProviderInfo, saves a round trip per page load and
keeps a single source of truth.
- i18n: 8 new keys across zh-CN and en-US for liveness labels and the
cooldown countdown tooltips.
Bonus fix (discovered during verification): AgentGraphBuilder.buildOpenAiApi
hard-required a usable API key on every OpenAI-compat provider, ignoring
the per-provider requireApiKey flag. That bug stranded keyless local
runtimes (LM Studio / MLX / llama.cpp) the moment a user actually
launched them; Ollama only worked by accident because its seed row
carries a placeholder string in api_key. keyRequired now honors
requireApiKey, and Spring AI's NoopApiKey is used when no key is needed
so the Authorization header is omitted entirely.
Test
- ModelProviderServiceLivenessTest covers all five Liveness states +
the probe-bean-absent fallback branch.
- vip.mate.llm.** suite (118 tests) green; vue-tsc clean.
- End-to-end browser sanity: 27 raw providers reduce to 6 LIVE groups
in the chat dropdown; LM Studio / MLX / llama.cpp render REMOVED red
badges with reprobe buttons; cloud providers without keys show
UNCONFIGURED.
23 lines
970 B
Java
23 lines
970 B
Java
package vip.mate.llm.model;
|
|
|
|
/**
|
|
* RFC-073: runtime liveness state of a provider, surfaced to the UI so the
|
|
* dropdown / settings page can show truth instead of "configured = available".
|
|
*
|
|
* <p>Computed by {@code ModelProviderService.computeLiveness} from three
|
|
* orthogonal signals: configuration completeness, init-probe progress, and
|
|
* pool / cooldown membership. The five values are mutually exclusive.</p>
|
|
*/
|
|
public enum Liveness {
|
|
/** In pool, not in cooldown. The default healthy state. */
|
|
LIVE,
|
|
/** In pool but in transient cooldown (consecutive failures tripped the threshold). */
|
|
COOLDOWN,
|
|
/** Probed and removed from pool with a HARD reason (auth, billing, model-not-found, init-probe failed). */
|
|
REMOVED,
|
|
/** Not yet probed — startup window or no probe strategy registered for this protocol. */
|
|
UNPROBED,
|
|
/** User-side configuration is incomplete (missing api_key / oauth token / base_url). */
|
|
UNCONFIGURED
|
|
}
|