AQIT 0.1.0
Loading...
Searching...
No Matches
status_display.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2"""`aquin status` — one bullet per fact, nothing else."""
3
4from __future__ import annotations
5
6import json
7from dataclasses import dataclass, field
8from typing import Any
9
10
11@dataclass
12class StatusSnapshot:
13 logged_in: bool = False
14 account: str | None = None
15 active_id: str | None = None
16 token_masked: str | None = None
17 other_accounts: list[str] = field(default_factory=list)
18 model_id: str | None = None
19 mode_label: str | None = None
20 device: str | None = None
21 location_label: str | None = None
22 gpu_line: str | None = None
23 engine_line: str = ""
24 license_line: str = ""
25 live_note: str | None = None
29 *,
30 account: str | None = None,
31 active_id: str | None = None,
32 token_masked: str | None = None,
33 other_accounts: list[str] | None = None,
34 live_note: str | None = None,
35 logged_in: bool = True,
36) -> StatusSnapshot:
37 """Gather local state only (no network). Auth is not required."""
38 _ = account, active_id, token_masked, other_accounts, live_note, logged_in
39
40 from aquin.compute.model_loader import get_active_model_id
41 from aquin.engine.main import _load_state
42 from aquin.license_acceptance import is_license_accepted
43
44 state = _load_state()
45 model_id = get_active_model_id(allow_daemon=False)
46 mode_label_str = None
47 if model_id:
48 try:
49 from aquin.session_mode import mode_for_model_id, mode_label as mode_label_fn
50
51 mode_label_str = mode_label_fn(mode_for_model_id(model_id))
52 except Exception:
53 pass
54
55 loc = state.get("location") or {}
56 location_label = (
57 loc.get("location_label") if isinstance(loc, dict) else None
58 )
59
60 return StatusSnapshot(
61 logged_in=True,
62 account=None,
63 active_id=None,
64 token_masked=None,
65 other_accounts=[],
66 model_id=model_id,
67 mode_label=mode_label_str,
68 device=state.get("device"),
69 location_label=location_label,
70 gpu_line=_gpu_line_from_state(state),
71 engine_line=_engine_line_fast(),
72 license_line="accepted" if is_license_accepted() else "not accepted",
73 live_note=None,
74 )
75
76
77def _status_rows(snapshot: StatusSnapshot) -> list[tuple[str, str]]:
78 """Small set of rows for the default human status output."""
79 rows: list[tuple[str, str]] = []
80
81 if snapshot.model_id:
82 model = snapshot.model_id
83 if snapshot.mode_label:
84 model = f"{model} ({snapshot.mode_label})"
85 rows.append(("model", model))
86 else:
87 rows.append(("model", "none - aquin load model <id>"))
88
89 rows.append(("engine", snapshot.engine_line or "off"))
90 rows.append(("gpu", snapshot.gpu_line or "unknown"))
91 if snapshot.live_note:
92 rows.append(("note", snapshot.live_note))
93 rows.append(("license", snapshot.license_line or "?"))
94 return rows
95
96
97def status_payload(snapshot: StatusSnapshot) -> dict[str, Any]:
98 """Machine-readable status for Ink / scripts (`aquin status --json`)."""
99 return {
100 "loggedIn": bool(snapshot.logged_in),
101 "rows": [{"label": label, "value": value} for label, value in _status_rows(snapshot)],
102 }
103
104def render_status(snapshot: StatusSnapshot, *, plain: bool = False) -> None:
105 """Print a small static status summary."""
106 _ = plain
107 rows = _status_rows(snapshot)
108 label_w = max((len(label) for label, _ in rows), default=8)
109 for label, value in rows:
110 print(f"{label.ljust(label_w)} {value}")
111
112
113# Back-compat name
114def render_status_ascii(snapshot: StatusSnapshot) -> None:
115 render_status(snapshot, plain=True)
116
117
119 *,
120 account: str | None,
121 active_id: str | None,
122 token_masked: str | None,
123 other_accounts: list[str],
124 live_note: str | None = None,
125) -> None:
127 account=account,
128 active_id=active_id,
129 token_masked=token_masked,
130 other_accounts=other_accounts,
131 live_note=live_note,
132 logged_in=True,
133 )
134 render_status(snap)
135
136
137def _gpu_line_from_state(state: dict[str, Any]) -> str | None:
138 gpu_info = state.get("gpu_info")
139 parsed: dict[str, Any] | None = None
140 if gpu_info:
141 try:
142 parsed = json.loads(gpu_info) if isinstance(gpu_info, str) else gpu_info
143 except Exception:
144 parsed = None
145
146 if parsed:
147 gpus = parsed.get("gpus") or []
148 backend = parsed.get("backend") or parsed.get("selected_device")
149 if gpus:
150 g = gpus[0]
151 name = g.get("name", "?")
152 vram = g.get("vram_gb", "?")
153 line = f"{name} ({vram} GB)"
154 if backend and backend not in ("cuda",):
155 line += f" - {backend}"
156 return line
157 if parsed.get("mps_available") or parsed.get("selected_device") == "mps":
158 return "Apple Metal (MPS)"
159 if parsed.get("accelerator_available") is False:
160 return "no GPU accelerator"
161
162 try:
163 from aquin.compute.device import probe_backend
164
165 probe = probe_backend()
166 if probe.get("gpus"):
167 g = probe["gpus"][0]
168 return f"{g.get('name', '?')} ({g.get('vram_gb', '?')} GB) - {probe.get('backend')}"
169 if probe.get("selected") == "mps":
170 return "Apple Metal (MPS)"
171 if not probe.get("accelerator_available"):
172 return "no GPU accelerator"
173 return probe.get("summary")
174 except Exception:
175 return None
176
177
178def _engine_line_fast() -> str:
179 try:
180 from aquin.engine import model_daemon
181
182 h = model_daemon.health_fast()
183 if h:
184 resident = h.get("model_id") or "none"
185 status = h.get("model_status") or "idle"
186 if status == "loading":
187 target = h.get("loading_model_id") or resident
188 elapsed = h.get("elapsed_s")
189 bit = f"loading: {target}"
190 if elapsed is not None:
191 bit = f"{bit} ({elapsed}s)"
192 return bit
193 vram = h.get("vram")
194 if resident == "none":
195 return "on, no model"
196 line = f"ready: {resident}"
197 if vram and resident != "none":
198 line = f"{line} ({vram})"
199 return line
200 except Exception:
201 pass
202 return "off"
None render_status(StatusSnapshot snapshot, *, bool plain=False)
None render_status_ascii(StatusSnapshot snapshot)
dict[str, Any] status_payload(StatusSnapshot snapshot)
list[tuple[str, str]] _status_rows(StatusSnapshot snapshot)
None collect_and_render_status(*, str|None account, str|None active_id, str|None token_masked, list[str] other_accounts, str|None live_note=None)
str|None _gpu_line_from_state(dict[str, Any] state)
StatusSnapshot collect_status_snapshot(*, str|None account=None, str|None active_id=None, str|None token_masked=None, list[str]|None other_accounts=None, str|None live_note=None, bool logged_in=True)