Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136/** * Severity classification — the cross-surface attention signal. * State-as-severity, never failure-centric: idle + streaming are calm info/success; * only permission and error actually need you. */import type { AgentStatus } from "@/contracts/agent-info";
export type Severity = "success" | "streaming" | "permission" | "error" | "compact";
export function severityForStatus(status: AgentStatus | undefined): Severity { switch (status) { case "waiting_for_permission": case "waiting_for_ui": return "permission"; case "error": return "error"; case "streaming": return "streaming"; case "compacting": return "compact"; case "idle": default: return "success"; }}
/** * Whether the AGENT is mid-turn (actively working), independent of the runtime process * lifecycle. A runtime can be `running` while the agent sits `idle` between turns — that is * a calm, no-attention state, NOT a live/working one. Only streaming, compacting, and the * two waiting states indicate the agent is actively engaged in a turn right now. * * Distinct from `runtimeIsActive` (session-state.ts), which reports whether the runtime * process is alive (running/starting) — a read-only-vs-live affordance signal, not an * attention signal. Use THIS helper for live/active visual emphasis (bold tab names, * streaming markers); use `runtimeIsActive` for gating live operations. */export function agentIsActive(status: AgentStatus | undefined): boolean { return ( status === "streaming" || status === "compacting" || status === "waiting_for_permission" || status === "waiting_for_ui" );}
/** Attention rank — permissions + errors rise to the top of the rail. */export function attentionRank(status: AgentStatus | undefined): number { switch (status) { case "waiting_for_permission": case "waiting_for_ui": return 0; case "error": return 1; case "streaming": return 2; case "compacting": return 3; case "idle": default: return 4; }}
export function severityClass(status: AgentStatus | undefined): string { const s = severityForStatus(status); return s === "success" ? "" : `is-${s}`;}
export function severityDotClass(status: AgentStatus | undefined): string { const s = severityForStatus(status); return s === "success" ? "sev-dot" : `sev-dot is-${s}`;}
// ── Strip Tower bay model (additive) ──────────────────────────────────────────// The list groups agent cards by status. Group order IS the attention order: URGENT (red)// above WAITING (amber) above ACTIVE (streaming/active) above IDLE. The four groups keep// every agent visible at once — the persistent attention surface.export type Bay = "urgent" | "holds" | "departures" | "arrivals";
/** Group placement for an agent status. State follows the agent, not your hand. */export function bayForStatus(status: AgentStatus | undefined): Bay { switch (status) { case "error": return "urgent"; case "waiting_for_permission": case "waiting_for_ui": return "holds"; case "streaming": case "compacting": return "departures"; case "idle": default: return "arrivals"; }}
/** Display order of groups in the list (top → bottom). Urgent first. */export const BAY_ORDER: Bay[] = ["urgent", "holds", "departures", "arrivals"];
/** Edge-tab token for a status (the card's colored left edge). */export function edgeToken(status: AgentStatus | undefined): string { const s = severityForStatus(status); switch (s) { case "error": return "var(--edge-urgent)"; case "permission": return "var(--edge-hold)"; case "streaming": return "var(--edge-stream)"; case "compact": case "success": default: return "var(--edge-clear)"; }}
/** Short state label for a status — the card's one-line state copy. */export function towerLabel(status: AgentStatus | undefined): string { switch (status) { case "waiting_for_permission": return "permission hold"; case "waiting_for_ui": return "awaiting input"; case "streaming": return "running"; case "compacting": return "compacting"; case "error": return "urgent"; case "idle": default: return "idle"; }}