This commit is contained in:
2026-03-30 09:53:10 -03:00
parent 4220b0418e
commit aac27b8504
32 changed files with 1068 additions and 329 deletions

View File

@@ -137,12 +137,15 @@ class CheckpointData(BaseModel):
@router.get("/checkpoints/{timeline_id}/{stage}", response_model=CheckpointData)
def get_checkpoint_data(timeline_id: str, stage: str):
"""Load checkpoint frames + metadata for the editor UI."""
"""Load checkpoint frames + metadata for the editor UI.
Reads from the timeline's frame cache (local filesystem).
"""
from uuid import UUID
from core.db.models import Timeline, Checkpoint
from core.db.connection import get_session
from core.db.checkpoint import list_checkpoints
from core.detect.checkpoint.frames import load_frames_b64
from core.detect.checkpoint.frames import load_cached_frames_b64
with get_session() as session:
timeline = session.get(Timeline, UUID(timeline_id))
@@ -152,16 +155,14 @@ def get_checkpoint_data(timeline_id: str, stage: str):
checkpoints = list_checkpoints(session, UUID(timeline_id))
if not checkpoints:
raise HTTPException(status_code=404, detail=f"No checkpoints for timeline {timeline_id}")
# Prefer a checkpoint that has this stage's output; fall back to latest
# Prefer a checkpoint for this stage; fall back to latest
checkpoint = next(
(c for c in reversed(checkpoints) if stage in (c.stage_outputs or {})),
(c for c in reversed(checkpoints) if c.stage_name == stage),
checkpoints[-1],
)
raw_manifest = timeline.frames_manifest or {}
manifest = {int(k): v for k, v in raw_manifest.items()}
frames_b64 = load_frames_b64(manifest, timeline.frames_meta or [])
# Read from timeline's frame cache
frames_b64 = load_cached_frames_b64(timeline_id)
frame_list = [
CheckpointFrameInfo(seq=f["seq"], timestamp=f["timestamp"], jpeg_b64=f["jpeg_b64"])
for f in frames_b64
@@ -171,7 +172,7 @@ def get_checkpoint_data(timeline_id: str, stage: str):
timeline_id=timeline_id,
stage=stage,
profile_name=timeline.profile_name,
video_path=timeline.source_video,
video_path=timeline.chunk_paths[0] if timeline.chunk_paths else "",
is_scenario=checkpoint.is_scenario,
scenario_label=checkpoint.scenario_label,
frames=frame_list,
@@ -195,14 +196,12 @@ def list_scenarios_endpoint():
timeline = session.get(Timeline, s.timeline_id)
if not timeline:
continue
last_stage = next(reversed(s.stage_outputs), "") if s.stage_outputs else ""
info = ScenarioInfo(
timeline_id=str(s.timeline_id),
stage=last_stage,
stage=s.stage_name,
scenario_label=s.scenario_label,
profile_name=timeline.profile_name,
video_path=timeline.source_video,
frame_count=len(timeline.frames_manifest or {}),
video_path=timeline.chunk_paths[0] if timeline.chunk_paths else "",
created_at=str(s.created_at) if s.created_at else "",
)
result.append(info)