Huge refactoring

This commit is contained in:
2026-09-17 00:46:04 +03:00
parent c65a9a91e2
commit 018be076b9
11 changed files with 534 additions and 344 deletions

109
utils.py
View File

@@ -1,62 +1,79 @@
from dataclasses import dataclass
from typing import Literal
from typing import Literal, Any
import subprocess
@dataclass
class TimelineEvent:
id: str
"""ID of the event in format `asr_18`"""
class Event:
"""Event within the timeline"""
id: int
"""Unique ID of the event (within single timeline)"""
type: Literal["voice", "vis", "ocr"]
"""Type of the event"""
timestamp: float
"""When did the event happen"""
"""When did the event start (or happen, if `duration` is 0)"""
duration: float
"""How long did the event last (zero if it does not make sence)"""
"""How long did the event last (0 if can't apply)"""
payload: str
"""Payload of the event (text for `asr`, description for `vis`, OCR result for `ocr`)"""
text: str
"""Textual representation of the event (or data in `payload`, if it is not None)"""
custom: dict
"""Custom data"""
links: list[str]
"""ID of related timeline events, empty list for None"""
def get_ai_dict(self) -> dict:
"""Returns dict that is sanitized for AI."""
d = {
"id": self.id,
"timestamp": self.timestamp,
"payload": self.payload
}
if self.duration:
d["duration"] = self.duration
if self.links:
d["links"] = self.links
return d
payload: str | None
"""Payload of the event. `None` for `voice`, image path for `vis`, OCR result for `ocr`"""
@dataclass
class AnalysisWindow:
before_readonly: list[TimelineEvent]
"""Timeline events for context (before current window)"""
class Timeline:
"""Timeline of events"""
modifiable: list[TimelineEvent]
"""Timeline events that are to be analyzed"""
events: list[Event]
"""Events of the timeline"""
after_readonly: list[TimelineEvent]
"""Timeline events for context (after current window)"""
def ffmpeg_split_video(input_path: str) -> tuple[str, str]:
"""Extract audio and video into ./audio.mp3 and ./video.mp4"""
audio_path = "audio.mp3"
video_path = "video.mp4"
subprocess.run(
[
"ffmpeg",
"-y",
"-i", input_path,
@dataclass
class AgentMessage:
content: str
"""Content of the message"""
# Audio
"-map", "0:a:0",
"-vn",
"-c:a", "libmp3lame",
"-q:a", "2",
audio_path,
role: Literal["system", "assistant", "user"]
"""Who sent the message"""
# Video
"-map", "0:v:0",
"-an",
"-c:v", "libx264",
"-crf", "18",
"-preset", "fast",
video_path,
],
check=True,
)
return audio_path, video_path
@dataclass
class TimelineProcessingResult:
events: list[TimelineEvent]
"""List of events"""
desired_events: list[TimelineEvent]
"""List of events desired for existance"""
def ffmpeg_to_mp3(input_path: str) -> str:
"""Convert `input_path` path to mp3 and save it at ./audio.mp3"""
output_path = "audio.mp3"
subprocess.run(
[
"ffmpeg",
"-y",
"-i", input_path,
"-vn",
"-c:a", "libmp3lame",
"-q:a", "2",
output_path,
],
check=True,
)
return output_path