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
+28 -20
View File
@@ -1,4 +1,5 @@
"""TV Show domain value objects."""
from dataclasses import dataclass
from enum import Enum
@@ -7,18 +8,19 @@ from ..shared.exceptions import ValidationError
class ShowStatus(Enum):
"""Status of a TV show - whether it's still airing or has ended."""
ONGOING = "ongoing"
ENDED = "ended"
UNKNOWN = "unknown"
@classmethod
def from_string(cls, status_str: str) -> "ShowStatus":
"""
Parse status from string.
Args:
status_str: Status string (e.g., "ongoing", "ended")
Returns:
ShowStatus enum value
"""
@@ -33,34 +35,37 @@ class ShowStatus(Enum):
class SeasonNumber:
"""
Value object representing a season number.
Validates that the season number is valid (>= 0).
Season 0 is used for specials.
"""
value: int
def __post_init__(self):
"""Validate season number."""
if not isinstance(self.value, int):
raise ValidationError(f"Season number must be an integer, got {type(self.value)}")
raise ValidationError(
f"Season number must be an integer, got {type(self.value)}"
)
if self.value < 0:
raise ValidationError(f"Season number cannot be negative: {self.value}")
# Reasonable upper limit
if self.value > 100:
raise ValidationError(f"Season number too high: {self.value}")
def is_special(self) -> bool:
"""Check if this is the specials season (season 0)."""
return self.value == 0
def __str__(self) -> str:
return str(self.value)
def __repr__(self) -> str:
return f"SeasonNumber({self.value})"
def __int__(self) -> int:
return self.value
@@ -69,28 +74,31 @@ class SeasonNumber:
class EpisodeNumber:
"""
Value object representing an episode number.
Validates that the episode number is valid (>= 1).
"""
value: int
def __post_init__(self):
"""Validate episode number."""
if not isinstance(self.value, int):
raise ValidationError(f"Episode number must be an integer, got {type(self.value)}")
raise ValidationError(
f"Episode number must be an integer, got {type(self.value)}"
)
if self.value < 1:
raise ValidationError(f"Episode number must be >= 1, got {self.value}")
# Reasonable upper limit
if self.value > 1000:
raise ValidationError(f"Episode number too high: {self.value}")
def __str__(self) -> str:
return str(self.value)
def __repr__(self) -> str:
return f"EpisodeNumber({self.value})"
def __int__(self) -> int:
return self.value