refactor(web_ui): Bus::effective_context_window, sigint_claude + per-connection hello, relocate fetch_reminder_stats, drop redundant guard

This commit is contained in:
müde 2026-07-05 22:47:14 +02:00
commit 9cebc128e2
7 changed files with 63 additions and 49 deletions

View file

@ -36,10 +36,7 @@ pub(super) async fn api_state(State(state): State<AppState>) -> axum::Json<State
let inbox = recent_inbox(&state.socket).await;
let (turn_state, turn_state_since) = state.bus.state_snapshot();
let model = state.bus.model();
let context_window_tokens = state
.bus
.api_context_window()
.unwrap_or_else(|| crate::events::context_window_tokens(&model));
let context_window_tokens = state.bus.effective_context_window(&model);
let ctx_usage = state.bus.last_ctx_usage();
let cost_usage = state.bus.last_cost_usage();
let effort = state.bus.effort();
@ -87,10 +84,7 @@ pub(super) async fn api_dashboard_state(
let (status_text, status_set_at) = read_own_status();
let rate_limited = state.bus.is_rate_limited();
let model = state.bus.model();
let context_window_tokens = state
.bus
.api_context_window()
.unwrap_or_else(|| crate::events::context_window_tokens(&model));
let context_window_tokens = state.bus.effective_context_window(&model);
// Full context-window size = input + cache-read + cache-creation. Using
// raw `input_tokens` here reported only the *uncached* sliver, which is
// ~0 once prompt caching kicks in — so every card showed `ctx·0k`. Match
@ -378,38 +372,16 @@ async fn recent_inbox(socket: &std::path::Path) -> Vec<hive_sh4re::InboxRow> {
}
}
/// Fetch reminder activity stats from the broker via the per-agent /
/// manager socket. Returns None on any transport / decode failure — the
/// stats are decorative, not authoritative.
pub(super) async fn fetch_reminder_stats(
socket: &std::path::Path,
window_secs: u64,
) -> Option<hive_sh4re::ReminderStats> {
match super::broker_request(
socket,
&hive_sh4re::Request::ReminderRollup {
since_secs: window_secs,
agent: None,
},
)
.await
{
Ok(hive_sh4re::Response::ReminderRollup(stats)) => Some(stats),
_ => None,
}
}
/// 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(ToString::to_string).collect(),
};
let models: Vec<String> = raw
// Absent / empty / all-whitespace env all funnel to the single
// emptiness check below — no separate up-front guard needed.
let models: Vec<String> = std::env::var("HIVE_AVAILABLE_MODELS")
.unwrap_or_default()
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())