diff --git a/family/documents/kids-activities.md b/family/documents/kids-activities.md index 2a26e130..51f79d02 100644 --- a/family/documents/kids-activities.md +++ b/family/documents/kids-activities.md @@ -156,4 +156,4 @@ updated: 2026-05-16 ## 📅 Ближайшие даты -- **23 мая** — День рождения Лизы 🎂 (8 лет). Напоминание по крону 22 мая: набрать Happy Birthday на музыкальной шкатулке Lego +- **23 мая** — День рождения Лизы 🎂 (7 лет). Напоминание по крону 22 мая: набрать Happy Birthday на музыкальной шкатулке Lego diff --git a/family/projects/media-toolbox-kraken.md b/family/projects/media-toolbox-kraken.md index 12bd6b13..2b1e21ad 100644 --- a/family/projects/media-toolbox-kraken.md +++ b/family/projects/media-toolbox-kraken.md @@ -460,6 +460,106 @@ docker run --rm \ --- +## Архитектура: Agentic Flow (agent subcommand) + +> Записано 2026-05-16. Это главная спека `media-pipeline agent` subcommand. + +### Входные данные агента (для каждого unresolved item) + +Агент получает **всё что можно извлечь без баз**: + +1. **Файловые метаданные** — имя папки/файла, набор файлов в папке (для TV show), длительность, формат, битрейт, разрешение (через `ffprobe` или `AVFoundation`) +2. **Транскрипция речи** — `ffmpeg` вырезает первые 60–120 сек аудио → **Whisper API** → текст (речь дикторов, диалоги, announcer voice) +3. **OCR титров** — `ffmpeg` захватывает 5–10 кадров из начала → **tesseract** или Vision API → текст с title card, студия, год +4. **Имена файлов** как уже есть (query names из UnresolvedEntry) + +### Инструменты агента (function calling / tool use) + +LLM получает инструменты и итеративно их вызывает до 10 шагов: + +| Tool | Параметры | Описание | +|------|-----------|----------| +| `search_tmdb` | `title, year?, language?` | Поиск в TMDb API | +| `search_kinopoisk` | `title, year?` | Поиск в KP API | +| `search_imdb` | `title, year?` | IMDb full-text search | +| `fetch_page` | `url` | Фетч и возврат текста страницы (IMDb, Wikipedia, BBC, Rutracker, etc.) | +| `search_web` | `query` | Веб-поиск (DuckDuckGo / SerpAPI) | + +### Выходные данные агента — одно из трёх + +**Вариант A — DB-bound resolve** (нашёл в базе): +```json +{ + "tmdb_id": 12345, + "kp_id": 678, + "imdb_id": "tt1234567" +} +``` +→ Pipeline пишет NFO стандартно через TMDb/KP fetch + +**Вариант B — full metadata без DB binding** (BBC/редкие доки): +```json +{ + "title": "The Frozen Kingdom of the Snow Leopard", + "original_title": "...", + "year": 2020, + "description": "...", + "genres": ["Documentary"], + "poster_url": "https://...", + "source_url": "https://bbc.com/programmes/...", + "duration_min": 59 +} +``` +→ Pipeline пишет custom NFO с этими данными (без tmdb/kp ID). Jellyfin подхватит. + +**Вариант C — manual resolve**: +```json +{ + "category": "unrecognized", + "reason": "Не удалось идентифицировать после всех источников" +} +``` +→ Остаётся в unresolved.json с agent_hint для ручного разбора + +### Выход для TV show / папки с несколькими фильмами + +Агент возвращает **список результатов**, по одному на файл/эпизод. Структура аналогична тому что делает media sync — те же поля что и NFO. + +### Приоритет обработки + +1. Сначала `The.Frozen.Kingdom.of.the.Snow.Leopard.(2020)` — самый сложный кейс, нет в TMDb/KP +2. Остальные BBC/Soviet docs из unresolved.json +3. Все остальные unresolved + +### Реализация + +#### Шаг 1: `MediaFileInspector` (новый модуль) +- `ffprobe` / AVFoundation → duration, format, resolution, audio tracks +- `ffmpeg` → extract frames → Vision/tesseract OCR → title card text +- `ffmpeg` → extract 60s audio → Whisper API → speech transcript +- Все результаты упакованы в `MediaFileContext` struct + +#### Шаг 2: `ChatGPTAPI.resolveMedia(context: MediaFileContext)` (новый метод) +- OpenAI function calling loop (max 10 iterations) +- Системный промпт включает все данные из `MediaFileContext` +- LLM итеративно вызывает tools пока не придёт к выводу +- Возвращает `AgentResolutionResult` (A/B/C) + +#### Шаг 3: `Agent.swift` subcommand расширен +- Запускает `MediaFileInspector` для каждого unresolved item +- Передаёт `MediaFileContext` в `resolveMedia` +- По результату: пишет NFO (A/B) или обновляет hint (C) + +#### Шаг 4: Tier 6 в sync pipeline (опционально) +- После Tier 5 (AIAgentStrategy) — запускает VideoAnalysis для застрявших +- Добавляет найденные variants как новые QueryNameFact → передаёт через Tier 0–4 + +### Зависимости (Linux/arm64 на Кракене) +- `ffprobe` / `ffmpeg` — уже установлен на Кракене +- `whisper-cpp` или OpenAI Whisper API (через ChatGPTAPI) +- `tesseract` — нужно установить (`apt install tesseract-ocr tesseract-ocr-rus`) +- Vision API (macOS only) — для Linux использовать tesseract + ## План: CV/Whisper для Tier 6 (для оценки) > Идея: когда все тиры исчерпаны — использовать сам медиафайл как источник сигнала для идентификации.