2525import time
2626from typing import Literal , TypedDict
2727
28+ from trueentropy .config import get_config
2829from trueentropy .pool import EntropyPool
2930
3031# -----------------------------------------------------------------------------
3132# Type Definitions
3233# -----------------------------------------------------------------------------
3334
3435
36+ class SourceStatus (TypedDict ):
37+ """
38+ Status of an individual entropy source.
39+
40+ Attributes:
41+ enabled: Whether this source is enabled in config
42+ requires_network: Whether this source needs network access
43+ """
44+
45+ enabled : bool
46+ requires_network : bool
47+
48+
3549class HealthStatus (TypedDict ):
3650 """
3751 TypedDict representing the health status of an entropy pool.
@@ -43,6 +57,8 @@ class HealthStatus(TypedDict):
4357 pool_utilization: Percentage of pool capacity used (0-100)
4458 time_since_feed: Seconds since last entropy feed
4559 recommendation: Suggested action for the user
60+ sources: Status of each entropy source
61+ offline_mode: Whether running in offline mode (no network sources)
4662 """
4763
4864 score : int
@@ -51,6 +67,8 @@ class HealthStatus(TypedDict):
5167 pool_utilization : float
5268 time_since_feed : float
5369 recommendation : str
70+ sources : dict [str , SourceStatus ]
71+ offline_mode : bool
5472
5573
5674# -----------------------------------------------------------------------------
@@ -172,6 +190,20 @@ def entropy_health(pool: EntropyPool) -> HealthStatus:
172190 "background collector to ensure entropy diversity."
173191 )
174192
193+ # -------------------------------------------------------------------------
194+ # Build Sources Status
195+ # -------------------------------------------------------------------------
196+
197+ config = get_config ()
198+ sources : dict [str , SourceStatus ] = {}
199+
200+ for source_name in ["timing" , "system" , "network" , "external" , "weather" , "radioactive" ]:
201+ info = config .get_source_info (source_name )
202+ sources [source_name ] = SourceStatus (
203+ enabled = info ["enabled" ],
204+ requires_network = info ["requires_network" ],
205+ )
206+
175207 # -------------------------------------------------------------------------
176208 # Build and Return Result
177209 # -------------------------------------------------------------------------
@@ -183,6 +215,8 @@ def entropy_health(pool: EntropyPool) -> HealthStatus:
183215 pool_utilization = round (pool_utilization , 2 ),
184216 time_since_feed = round (time_since_feed , 2 ),
185217 recommendation = recommendation ,
218+ sources = sources ,
219+ offline_mode = config .offline_mode ,
186220 )
187221
188222
@@ -236,7 +270,31 @@ def print_health_report(pool: EntropyPool) -> None:
236270 f"({ health ['pool_utilization' ]:.1f} %) ║"
237271 )
238272 print (f"║ Last Feed: { health ['time_since_feed' ]:.1f} seconds ago ║" )
273+
274+ # Show offline mode status
275+ if health ["offline_mode" ]:
276+ print ("║ Mode: OFFLINE (local sources) ║" )
277+ else :
278+ print ("║ Mode: ONLINE (all sources) ║" )
279+
280+ print ("╠══════════════════════════════════════════╣" )
281+ print ("║ Entropy Sources Status ║" )
282+ print ("╠══════════════════════════════════════════╣" )
283+
284+ # Display each source status
285+ for source_name , source_info in health ["sources" ].items ():
286+ if source_info ["enabled" ]:
287+ status_icon = "✓"
288+ status_text = "enabled "
289+ else :
290+ status_icon = "○"
291+ status_text = "disabled"
292+
293+ network_tag = " (net)" if source_info ["requires_network" ] else " "
294+ print (f"║ { status_icon } { source_name :12} { status_text } { network_tag } ║" )
295+
239296 print ("╠══════════════════════════════════════════╣" )
240297 print (f"║ { emoji } { health ['recommendation' ][:40 ]:40} ║" )
241298 print ("╚══════════════════════════════════════════╝" )
242299 print ()
300+
0 commit comments