feat(agent): read available models from HIVE_AVAILABLE_MODELS env var
web_ui.rs: add available_models() helper that reads HIVE_AVAILABLE_MODELS (comma-separated, injected by services.hyperhive.availableModels nix option). Falls back to ["haiku", "sonnet", "opus"] when absent or empty. Field added to StateSnapshot so the frontend receives the list on cold-load. app.js: replace hardcoded MODEL_ALIASES array with availableModels module var. Seeded from state.available_models before setHeader/populateOverflowMenu on first /api/state load. Well-known aliases (haiku/sonnet/opus) still get their descriptive labels; operator-declared custom model names show the name itself. Implements the frontend + web_ui.rs side of issue #1359 (nix option shipped separately in PR #1360 by atlas).
This commit is contained in:
parent
6c57b2b4e0
commit
1f54a07195
2 changed files with 57 additions and 12 deletions
|
|
@ -436,6 +436,14 @@ struct StateSnapshot {
|
|||
/// Human name of the swarm (e.g. `"constellat1on"`). Sourced from
|
||||
/// `HYPERHIVE_SWARM_NAME`; `None` when unset.
|
||||
swarm_name: Option<String>,
|
||||
/// Ordered list of model short-names the operator has declared as
|
||||
/// available on this hive. Sourced from `HIVE_AVAILABLE_MODELS`
|
||||
/// (comma-separated, set by `services.hyperhive.availableModels`).
|
||||
/// Falls back to `["haiku", "sonnet", "opus"]` when the env var is
|
||||
/// absent or empty. The frontend model quick-picker renders one button
|
||||
/// per entry in this list, so operators can add new models or drop
|
||||
/// ones they don't want without touching the frontend code.
|
||||
available_models: Vec<String>,
|
||||
}
|
||||
|
||||
/// One navigation link in the agent page header row. The same JSON
|
||||
|
|
@ -561,6 +569,7 @@ async fn api_state(State(state): State<AppState>) -> axum::Json<StateSnapshot> {
|
|||
.filter(|s| !s.is_empty()),
|
||||
hive_name: crate::identity::hive_name(),
|
||||
swarm_name: crate::identity::swarm_name(),
|
||||
available_models: available_models(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1076,3 +1085,25 @@ fn error_response(message: &str) -> Response {
|
|||
// be noise.
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, message.to_owned()).into_response()
|
||||
}
|
||||
|
||||
/// Read `HIVE_AVAILABLE_MODELS` (comma-separated short names injected by
|
||||
/// `services.hyperhive.availableModels`) and return the parsed list.
|
||||
/// Falls back to `["haiku", "sonnet", "opus"]` when the env var is absent
|
||||
/// or resolves to an empty list after trimming.
|
||||
fn available_models() -> Vec<String> {
|
||||
const DEFAULT: &[&str] = &["haiku", "sonnet", "opus"];
|
||||
let raw = match std::env::var("HIVE_AVAILABLE_MODELS") {
|
||||
Ok(v) if !v.trim().is_empty() => v,
|
||||
_ => return DEFAULT.iter().map(|s| s.to_string()).collect(),
|
||||
};
|
||||
let models: Vec<String> = raw
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect();
|
||||
if models.is_empty() {
|
||||
DEFAULT.iter().map(|s| s.to_string()).collect()
|
||||
} else {
|
||||
models
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue