feat(release): inspect_release orchestrator + InspectedResult VO
New application-layer entry point that composes the four inspection
layers in one call:
1. parse_release(name, kb) -> (ParsedRelease, ParseReport)
2. detect_media_type(parsed, path, kb) -> patch parsed.media_type
3. find_main_video(path, kb) -> Path | None (top-level scan)
4. prober.probe(video) + enrich -> when video exists and
media_type not in
{unknown, other}
Returns a frozen InspectedResult(parsed, report, source_path,
main_video, media_info, probe_used). kb and prober are injected — no
module-level singletons in inspect.py.
analyze_release tool now delegates to inspect_release; its output
gains two fields, confidence (0-100) and road (easy/shitty/path_of_pain),
surfaced from ParseReport so the LLM can route by confidence. Spec
updated to document them.
12 new tests covering happy paths, probe gating (no video, media_type
'other', probe failure), mutation contract (detect refining
parsed.media_type, enrich filling None fields), resilience
(nonexistent path), and frozen contract. Suite: 1058 passing.
This commit is contained in:
@@ -13,8 +13,6 @@ from alfred.application.filesystem import (
|
||||
MoveMediaUseCase,
|
||||
SetFolderPathUseCase,
|
||||
)
|
||||
from alfred.application.filesystem.detect_media_type import detect_media_type
|
||||
from alfred.application.filesystem.enrich_from_probe import enrich_from_probe
|
||||
from alfred.application.filesystem.resolve_destination import (
|
||||
resolve_episode_destination as _resolve_episode_destination,
|
||||
)
|
||||
@@ -28,7 +26,6 @@ from alfred.application.filesystem.resolve_destination import (
|
||||
resolve_series_destination as _resolve_series_destination,
|
||||
)
|
||||
from alfred.infrastructure.filesystem import FileManager, create_folder, move
|
||||
from alfred.infrastructure.filesystem.find_video import find_video_file
|
||||
from alfred.infrastructure.metadata import MetadataStore
|
||||
from alfred.infrastructure.persistence import get_memory
|
||||
from alfred.infrastructure.probe import FfprobeMediaProber
|
||||
@@ -193,21 +190,10 @@ def set_path_for_folder(folder_name: str, path_value: str) -> dict[str, Any]:
|
||||
def analyze_release(release_name: str, source_path: str) -> dict[str, Any]:
|
||||
"""Thin tool wrapper — semantics live in alfred/agent/tools/specs/analyze_release.yaml."""
|
||||
from alfred.application.filesystem.resolve_destination import _KB # noqa: PLC0415
|
||||
from alfred.domain.release.services import parse_release # noqa: PLC0415
|
||||
|
||||
path = Path(source_path)
|
||||
parsed, _ = parse_release(release_name, _KB)
|
||||
parsed.media_type = detect_media_type(parsed, path, _KB)
|
||||
|
||||
probe_used = False
|
||||
if parsed.media_type not in ("unknown", "other"):
|
||||
video_file = find_video_file(path, _KB)
|
||||
if video_file:
|
||||
media_info = _PROBER.probe(video_file)
|
||||
if media_info:
|
||||
enrich_from_probe(parsed, media_info)
|
||||
probe_used = True
|
||||
from alfred.application.release import inspect_release # noqa: PLC0415
|
||||
|
||||
result = inspect_release(release_name, Path(source_path), _KB, _PROBER)
|
||||
parsed = result.parsed
|
||||
return {
|
||||
"status": "ok",
|
||||
"media_type": parsed.media_type,
|
||||
@@ -229,7 +215,9 @@ def analyze_release(release_name: str, source_path: str) -> dict[str, Any]:
|
||||
"edition": parsed.edition,
|
||||
"site_tag": parsed.site_tag,
|
||||
"is_season_pack": parsed.is_season_pack,
|
||||
"probe_used": probe_used,
|
||||
"probe_used": result.probe_used,
|
||||
"confidence": result.report.confidence,
|
||||
"road": result.report.road,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -80,3 +80,5 @@ returns:
|
||||
site_tag: Source-site tag if present.
|
||||
is_season_pack: True when the folder contains a full season.
|
||||
probe_used: True when ffprobe successfully enriched the result.
|
||||
confidence: Parser confidence score, 0–100 (higher = more reliable).
|
||||
road: "Parser road: 'easy' (group schema matched), 'shitty' (heuristic but acceptable), or 'path_of_pain' (low confidence — ask the user before auto-routing)."
|
||||
|
||||
Reference in New Issue
Block a user