""" frame_metadata.py — Pydantic schemas for LLM structured output. Used by Outlines to enforce valid JSON generation. Design note (schema compaction): The LLM never echoes word indices. Each Frame carries a `count` (how many of the remaining words belong to this line). Indices are reconstructed sequentially on our side, which makes contiguity, ordering and full coverage true *by construction* — the model cannot produce an invalid grouping, and the JSON it must emit is a fraction of the old `word_indices` list size. The LLM's job is just two simple per-line decisions: `count` (line split) and `frame_animation` (one mood-matching effect for the whole line). """ from enum import Enum from typing import List from pydantic import BaseModel, Field class FrameAnim(str, Enum): none = "none" zoom_in = "zoom_in" zoom_out = "zoom_out" pan_left = "pan_left" pan_right = "pan_right" flash = "flash" fade_to_black = "fade_to_black" class Frame(BaseModel): count: int = Field(description="How many of the remaining words (in order) belong to this line") frame_animation: FrameAnim = FrameAnim.none class SongFrames(BaseModel): frames: List[Frame]