feat!: migrate to OpenAI native tool calls and fix circular deps (#fuck-gemini)

- Fix circular dependencies in agent/tools
- Migrate from custom JSON to OpenAI tool calls format
- Add async streaming (step_stream, complete_stream)
- Simplify prompt system and remove token counting
- Add 5 new API endpoints (/health, /v1/models, /api/memory/*)
- Add 3 new tools (get_torrent_by_index, add_torrent_by_index, set_language)
- Fix all 500 tests and add coverage config (80% threshold)
- Add comprehensive docs (README, pytest guide)

BREAKING: LLM interface changed, memory injection via get_memory()
This commit is contained in:
2025-12-06 19:11:05 +01:00
parent 2c8cdd3ab1
commit 9ca31e45e0
92 changed files with 7897 additions and 1786 deletions
+21 -24
View File
@@ -1,4 +1,5 @@
"""Subtitle domain value objects."""
from dataclasses import dataclass
from enum import Enum
@@ -7,29 +8,21 @@ from ..shared.exceptions import ValidationError
class Language(Enum):
"""Supported subtitle languages."""
ENGLISH = "en"
FRENCH = "fr"
SPANISH = "es"
GERMAN = "de"
ITALIAN = "it"
PORTUGUESE = "pt"
RUSSIAN = "ru"
JAPANESE = "ja"
KOREAN = "ko"
CHINESE = "zh"
ARABIC = "ar"
@classmethod
def from_code(cls, code: str) -> "Language":
"""
Get language from ISO 639-1 code.
Args:
code: Two-letter language code
Returns:
Language enum value
Raises:
ValidationError: If code is not supported
"""
@@ -42,27 +35,28 @@ class Language(Enum):
class SubtitleFormat(Enum):
"""Supported subtitle formats."""
SRT = "srt" # SubRip
ASS = "ass" # Advanced SubStation Alpha
SSA = "ssa" # SubStation Alpha
VTT = "vtt" # WebVTT
SUB = "sub" # MicroDVD
@classmethod
def from_extension(cls, extension: str) -> "SubtitleFormat":
"""
Get format from file extension.
Args:
extension: File extension (with or without dot)
Returns:
SubtitleFormat enum value
Raises:
ValidationError: If extension is not supported
"""
ext = extension.lower().lstrip('.')
ext = extension.lower().lstrip(".")
for fmt in cls:
if fmt.value == ext:
return fmt
@@ -73,22 +67,25 @@ class SubtitleFormat(Enum):
class TimingOffset:
"""
Value object representing subtitle timing offset in milliseconds.
Used for synchronizing subtitles with video.
"""
milliseconds: int
def __post_init__(self):
"""Validate timing offset."""
if not isinstance(self.milliseconds, int):
raise ValidationError(f"Timing offset must be an integer, got {type(self.milliseconds)}")
raise ValidationError(
f"Timing offset must be an integer, got {type(self.milliseconds)}"
)
def to_seconds(self) -> float:
"""Convert to seconds."""
return self.milliseconds / 1000.0
def __str__(self) -> str:
return f"{self.milliseconds}ms"
def __repr__(self) -> str:
return f"TimingOffset({self.milliseconds})"