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:
@@ -1,27 +1,28 @@
|
||||
"""Movie domain value objects."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from ..shared.exceptions import ValidationError
|
||||
|
||||
|
||||
class Quality(Enum):
|
||||
"""Video quality levels."""
|
||||
|
||||
SD = "480p"
|
||||
HD = "720p"
|
||||
FULL_HD = "1080p"
|
||||
UHD_4K = "2160p"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, quality_str: str) -> "Quality":
|
||||
"""
|
||||
Parse quality from string.
|
||||
|
||||
|
||||
Args:
|
||||
quality_str: Quality string (e.g., "1080p", "720p")
|
||||
|
||||
|
||||
Returns:
|
||||
Quality enum value
|
||||
"""
|
||||
@@ -38,38 +39,44 @@ class Quality(Enum):
|
||||
class MovieTitle:
|
||||
"""
|
||||
Value object representing a movie title.
|
||||
|
||||
|
||||
Ensures the title is valid and normalized.
|
||||
"""
|
||||
|
||||
value: str
|
||||
|
||||
|
||||
def __post_init__(self):
|
||||
"""Validate movie title."""
|
||||
if not self.value:
|
||||
raise ValidationError("Movie title cannot be empty")
|
||||
|
||||
|
||||
if not isinstance(self.value, str):
|
||||
raise ValidationError(f"Movie title must be a string, got {type(self.value)}")
|
||||
|
||||
raise ValidationError(
|
||||
f"Movie title must be a string, got {type(self.value)}"
|
||||
)
|
||||
|
||||
if len(self.value) > 500:
|
||||
raise ValidationError(f"Movie title too long: {len(self.value)} characters (max 500)")
|
||||
|
||||
raise ValidationError(
|
||||
f"Movie title too long: {len(self.value)} characters (max 500)"
|
||||
)
|
||||
|
||||
def normalized(self) -> str:
|
||||
"""
|
||||
Return normalized title for file system usage.
|
||||
|
||||
|
||||
Removes special characters and replaces spaces with dots.
|
||||
"""
|
||||
import re
|
||||
|
||||
# Remove special characters except spaces, dots, and hyphens
|
||||
cleaned = re.sub(r'[^\w\s\.\-]', '', self.value)
|
||||
cleaned = re.sub(r"[^\w\s\.\-]", "", self.value)
|
||||
# Replace spaces with dots
|
||||
normalized = cleaned.replace(' ', '.')
|
||||
normalized = cleaned.replace(" ", ".")
|
||||
return normalized
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"MovieTitle('{self.value}')"
|
||||
|
||||
@@ -78,22 +85,25 @@ class MovieTitle:
|
||||
class ReleaseYear:
|
||||
"""
|
||||
Value object representing a movie release year.
|
||||
|
||||
|
||||
Validates that the year is reasonable.
|
||||
"""
|
||||
|
||||
value: int
|
||||
|
||||
|
||||
def __post_init__(self):
|
||||
"""Validate release year."""
|
||||
if not isinstance(self.value, int):
|
||||
raise ValidationError(f"Release year must be an integer, got {type(self.value)}")
|
||||
|
||||
raise ValidationError(
|
||||
f"Release year must be an integer, got {type(self.value)}"
|
||||
)
|
||||
|
||||
# Movies started around 1888, and we shouldn't have movies from the future
|
||||
if self.value < 1888 or self.value > 2100:
|
||||
raise ValidationError(f"Invalid release year: {self.value}")
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.value)
|
||||
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ReleaseYear({self.value})"
|
||||
|
||||
Reference in New Issue
Block a user