feat(startup): first-frame detection + startup_timeline API
Adds per-AppController startup timing instrumentation to answer 'did the warmup block the first frame?' AppController.__init__ records _init_start_ts at entry (cold-start anchor). WarmupManager.on_complete callback stamps _warmup_done_ts. App.render_main_interface (gui_2.py) calls mark_first_frame_rendered() on its first call, which stamps _first_frame_ts and logs the timeline. New public API on AppController: - init_start_ts (property): float - warmup_done_ts (property): Optional[float] - first_frame_ts (property): Optional[float] - mark_first_frame_rendered(ts=None): idempotent; logs to stderr - startup_timeline() -> dict with all timestamps + precomputed deltas: warmup_ms, first_frame_after_init_ms, first_frame_after_warmup_ms Stderr log on warmup done: [startup] warmup done in 1186.2ms (first frame rendered Nms BEFORE/AFTER) Stderr log on first frame: [startup] first frame at Xms after init (warmup took Yms) (rendered Zms BEFORE/AFTER warmup done) Hook API: - GET /api/startup_timeline - ApiHookClient.get_startup_timeline() -> dict 5 new tests in test_warmup_canaries.py covering all the new methods. All 18 canary tests + 10 api_hooks tests + 6 gui_indicator tests pass. Script scripts/apply_startup_timeline.py is included as a reference for the multi-edit pattern (the proper MCP-equivalent tools will be added later per the edit_workflow doc).
This commit is contained in:
@@ -329,6 +329,16 @@ class ApiHookClient:
|
||||
result = self._make_request('GET', '/api/warmup_canaries') or {}
|
||||
return result.get("canaries", []) if isinstance(result, dict) else []
|
||||
|
||||
def get_startup_timeline(self) -> dict[str, Any]:
|
||||
"""
|
||||
Returns the startup timeline: dict with init_start_ts, warmup_done_ts,
|
||||
first_frame_ts, warmup_ms, first_frame_after_init_ms,
|
||||
first_frame_after_warmup_ms. Lets external clients answer
|
||||
'did the warmup block the first frame?'.
|
||||
[C: tests/test_api_hooks_warmup.py:test_live_startup_timeline_endpoint]
|
||||
"""
|
||||
return self._make_request('GET', '/api/startup_timeline') or {}
|
||||
|
||||
#endregion: Diagnostics
|
||||
|
||||
#region: Project
|
||||
|
||||
Reference in New Issue
Block a user