diff --git a/tasks/image-gen/BRD.md b/tasks/image-gen/BRD.md new file mode 100644 index 0000000..77153a3 --- /dev/null +++ b/tasks/image-gen/BRD.md @@ -0,0 +1,197 @@ +# BRD: Скилл `image-gen` + +--- +created: 2026-05-24 +status: approved +--- + +## Назначение + +Скилл генерации изображений через онлайн-модели (Recraft через OpenRouter, A2E.ai). +Доступен **всем агентам OpenClaw** (`~/.openclaw/skills/image-gen/`). + +--- + +## Триггер + +Пользователь пишет: «сгенерируй фото», «нарисуй изображение», «generate image», «сгенерируй картинку» и т.п. + +--- + +## Поток работы + +``` +Запрос пользователя (рус) + ↓ +Агент читает params/templates.md + params/styles.md + ↓ +Агент матчит объекты/стили → собирает промпт (рус→англ) +Промпт = base_template(s) + style + уникальные детали из запроса + quality enhancers + ↓ +scripts/generate.py --prompt "..." --negative "..." --model "..." --ratio "9:16" --count 1 + ↓ +API → сохранить JPG в ~/images/image-gen/YYYY-MM-DD/ → отправить в Telegram +Подпись: "Model: recraft-v4.1-pro | <саммари промпта на русском>" + ↓ +Агент спрашивает: "Сохранить промпт в избранное?" +``` + +--- + +## Структура скилла + +``` +~/.openclaw/skills/image-gen/ +├── SKILL.md +├── params/ +│ ├── templates.md # шаблоны объектов (редактируются через Стрим или вручную) +│ ├── models.md # список моделей, дефолты, negative prompt +│ ├── styles.md # фотографические стили +│ └── favorites.md # избранные промпты + модель + дата +├── scripts/ +│ └── generate.py # вся работа с API, сохранение, отправка в TG +└── references/ + ├── recraft_api.md # OpenRouter image generation API + recraft-специфика + ├── recraft_prompting.md # как писать промпты для recraft моделей + ├── a2e_api.md # A2E.ai API (text-to-image endpoint) + └── a2e_prompting.md # как писать промпты для A2E моделей +``` + +--- + +## Параметры моделей (`params/models.md`) + +```md +## Recraft (через OpenRouter) + +default_model: recraft/recraft-v4.1-pro +default_aspect_ratio: 9:16 +default_count: 1 +default_image_size: 2K +negative_prompt: deformed limbs, distorted hands, extra fingers, bad anatomy, + blurry, low quality, watermark, signature, text + +### Модели Recraft +- recraft/recraft-v4.1-pro ← дефолт +- recraft/recraft-v4.1-utility-pro +- recraft/recraft-v4.1-utility +- recraft/recraft-v4.1 +- recraft/recraft-v4-pro +- recraft/recraft-v4 +- recraft/recraft-v3 + +### Группы моделей (для мульти-генерации) +- group:all_v4.1 = [v4.1-pro, v4.1-utility-pro, v4.1-utility, v4.1] +- group:all_v4 = [v4.1-pro, v4.1-utility-pro, v4.1-utility, v4.1, v4-pro, v4] +- group:all = [все выше + v3] + +## A2E.ai +api_url: https://video.a2e.ai/api/ +default_model: (определяется из API доки — см. a2e_api.md) +``` + +--- + +## Шаблоны объектов (`params/templates.md`) + +Формат: каждый шаблон содержит `triggers` (слова для матчинга из запроса) и `base` (базовое описание на английском). Качественные усилители (`photorealistic`, `8K`, `masterpiece`) прямо в `base`. + +```md +## blonde_woman +Triggers: блондинка, blonde, blondinka +Base: A beautiful blonde woman, 25 years old, long wavy golden hair, + blue eyes, natural makeup, slim athletic figure, photorealistic, + sharp focus, 8K, masterpiece + +## park +Triggers: парк, park +Base: lush green urban park, sunny afternoon, tall trees, + soft bokeh background, natural daylight +``` + +--- + +## Стили (`params/styles.md`) + +```md +## portrait +Triggers: портрет, portrait +Style: 85mm lens portrait photography, shallow depth of field, + studio lighting, sharp focus on face, professional headshot + +## cinematic +Triggers: кинематограф, cinematic, кино +Style: cinematic shot, movie still, dramatic lighting, + widescreen composition, film grain + +## street +Triggers: стрит, уличное, street +Style: street photography, candid, natural light, urban setting +``` + +--- + +## Избранное (`params/favorites.md`) + +```md +## 2026-05-24 — blonde in park +Model: recraft/recraft-v4.1-pro +Prompt: A beautiful blonde woman in a lush green park, 85mm portrait, + shallow depth of field, golden hour lighting... +Negative: deformed limbs, distorted hands... +``` + +--- + +## `scripts/generate.py` — интерфейс + +``` +generate.py + --prompt "..." # финальный промпт (английский) + --negative "..." # negative prompt (из params/models.md) + --model "recraft/..." # или "group:all_v4" + --ratio "9:16" # aspect ratio (дефолт: 9:16) + --count 1 # вариантов на модель (дефолт: 1) + --provider "openrouter" # openrouter | a2e (дефолт: openrouter) + --save-dir "~/images/image-gen/YYYY-MM-DD/" + --tg-caption "..." # подпись: "Model: X | <саммари>" +``` + +Скрипт: +1. Читает API ключ из `.env` (OPENROUTER_API_KEY / A2E_API_TOKEN) +2. Если `--model group:all_v4` — запускает параллельно для всех моделей группы +3. Сохраняет каждую картинку: `YYYY-MM-DD_HH-MM-SS_.jpg` +4. Отправляет в Telegram через `openclaw message send --media ` + +--- + +## `.env` переменные (только там, нигде больше) + +``` +OPENROUTER_API_KEY=... # нужно добавить (если ещё нет) +A2E_API_TOKEN=... # ✅ уже есть +TELEGRAM_BOT_TOKEN=... # ✅ уже есть +TELEGRAM_CHAT_ID=... # ✅ уже есть +``` + +--- + +## Что НЕ входит в MVP + +- Генерация видео через A2E +- Image-to-image (вариации от существующей картинки) +- Inpainting / outpainting +- Negative prompt через UI (только через шаблон) +- История с превью-галереей + +--- + +## Задача Dev-агента + +1. Изучить A2E API (`https://video.a2e.ai/dev`) и написать `references/a2e_api.md` + `references/a2e_prompting.md` +2. Изучить OpenRouter image generation и написать `references/recraft_api.md` + `references/recraft_prompting.md` +3. Создать `scripts/generate.py` с интерфейсом выше +4. Создать стартовые `params/templates.md`, `params/models.md`, `params/styles.md`, `params/favorites.md` +5. Написать `SKILL.md` +6. Протестировать: запустить `generate.py` с тестовым промптом, убедиться что картинка сохранена и отправлена в TG +7. Упаковать скилл: `package_skill.py ~/.openclaw/skills/image-gen/` diff --git a/tasks/image-gen/DEV_TASK.md b/tasks/image-gen/DEV_TASK.md new file mode 100644 index 0000000..765b2e0 --- /dev/null +++ b/tasks/image-gen/DEV_TASK.md @@ -0,0 +1,329 @@ +# DEV TASK: Скилл `image-gen` — генерация изображений + +**Статус:** Ready for dev +**Проект:** image-gen +**BRD:** `tasks/image-gen/BRD.md` + +--- + +## Цель + +Создать AgentSkill `image-gen` в `~/.openclaw/skills/image-gen/` — скилл генерации изображений через Recraft (OpenRouter) и A2E.ai, доступный всем агентам OpenClaw. + +## Архитектура + +Агент читает шаблоны из `params/`, составляет английский промпт, вызывает `scripts/generate.py`. Скрипт делает API-запрос, сохраняет картинку на диск, отправляет в Telegram через OpenClaw CLI. Агент тратит токены только на трансформацию запроса → промпт. + +## Стек / Зависимости + +- Python 3.x (доступен в контейнере) +- `requests` (pip install requests) +- `python-dotenv` (pip install python-dotenv) +- OpenRouter API (image generation endpoint) +- A2E.ai API (text-to-image endpoint) +- OpenClaw CLI (`openclaw message send`) + +--- + +## Инфраструктура + +| Параметр | Значение | +|----------|----------| +| Расположение скилла | `~/.openclaw/skills/image-gen/` | +| Env-файл | `~/.openclaw/.env` | +| Папка для картинок | `~/images/image-gen/YYYY-MM-DD/` | +| Упаковка скилла | `/app/skills/skill-creator/scripts/package_skill.py` | + +--- + +## Файловая карта + +| Действие | Файл | Ответственность | +|----------|------|-----------------| +| Создать | `~/.openclaw/skills/image-gen/SKILL.md` | Метаданные + инструкции для агента | +| Создать | `~/.openclaw/skills/image-gen/params/models.md` | Модели, дефолты, negative prompt | +| Создать | `~/.openclaw/skills/image-gen/params/templates.md` | Шаблоны объектов | +| Создать | `~/.openclaw/skills/image-gen/params/styles.md` | Фотостили | +| Создать | `~/.openclaw/skills/image-gen/params/favorites.md` | Избранные промпты (пустой) | +| Создать | `~/.openclaw/skills/image-gen/scripts/generate.py` | Скрипт генерации | +| Создать | `~/.openclaw/skills/image-gen/references/recraft_api.md` | OpenRouter image gen API | +| Создать | `~/.openclaw/skills/image-gen/references/recraft_prompting.md` | Промптинг для Recraft | +| Создать | `~/.openclaw/skills/image-gen/references/a2e_api.md` | A2E.ai API (text-to-image) | +| Создать | `~/.openclaw/skills/image-gen/references/a2e_prompting.md` | Промптинг для A2E | + +--- + +## Задачи + +### Task 1: Изучить API и написать references + +**Шаги:** + +- [ ] **1.1** Изучить OpenRouter image generation API: + - Доку: `https://openrouter.ai/docs/guides/overview/multimodal/image-generation.md` + - Модели Recraft: `https://openrouter.ai/recraft/recraft-v4.1-pro` и соседние + - Написать `references/recraft_api.md` — endpoint, параметры запроса, формат ответа (base64), `image_config` (aspect_ratio, image_size), negative prompt + +- [ ] **1.2** Изучить A2E.ai text-to-image API: + - Сайт: `https://video.a2e.ai/dev` (может требовать браузер — попробовать `curl -L`) + - Поискать OpenAPI spec или Swagger: `https://video.a2e.ai/api/schema/` или `/openapi.json` + - Ключ: `A2E_API_TOKEN` в `~/.openclaw/.env` + - Написать `references/a2e_api.md` — endpoint, параметры, формат ответа + +- [ ] **1.3** Написать `references/recraft_prompting.md`: + - Структура промпта для recraft (subject, style, lighting, camera, quality) + - Примеры хороших промптов + - Что работает хорошо / плохо + - Источник: `https://www.recraft.ai/docs/api-reference/getting-started` + практические примеры + +- [ ] **1.4** Написать `references/a2e_prompting.md`: + - Аналогично для A2E моделей + +**Критерий готовности:** 4 reference файла созданы, содержат рабочие примеры запросов. + +--- + +### Task 2: Создать `params/` файлы + +**Шаги:** + +- [ ] **2.1** Создать `params/models.md`: + +```md +## Recraft (OpenRouter) + +default_model: recraft/recraft-v4.1-pro +default_aspect_ratio: 9:16 +default_count: 1 +default_image_size: 2K +negative_prompt: deformed limbs, distorted hands, extra fingers, bad anatomy, blurry, low quality, watermark, signature, text overlay + +### Доступные модели +- recraft/recraft-v4.1-pro ← дефолт +- recraft/recraft-v4.1-utility-pro +- recraft/recraft-v4.1-utility +- recraft/recraft-v4.1 +- recraft/recraft-v4-pro +- recraft/recraft-v4 +- recraft/recraft-v3 + +### Группы (для мульти-генерации) +- group:all_v4.1 = recraft/recraft-v4.1-pro, recraft/recraft-v4.1-utility-pro, recraft/recraft-v4.1-utility, recraft/recraft-v4.1 +- group:all_v4 = recraft/recraft-v4.1-pro, recraft/recraft-v4.1-utility-pro, recraft/recraft-v4.1-utility, recraft/recraft-v4.1, recraft/recraft-v4-pro, recraft/recraft-v4 +- group:all = все выше + recraft/recraft-v3 + +## A2E.ai +default_model: (заполнить из API доки) +api_url: https://video.a2e.ai/api/ +``` + +- [ ] **2.2** Создать `params/templates.md` со стартовыми шаблонами: + +```md +# Шаблоны объектов для image-gen +# Формат: triggers (слова для матчинга, через запятую) + base (описание на английском) +# Quality enhancers включены прямо в base каждого шаблона + +## blonde_woman +Triggers: блондинка, blonde, блондинки +Base: A beautiful blonde woman, 25 years old, long wavy golden hair, blue eyes, natural makeup, slim athletic figure, photorealistic, sharp focus, 8K resolution, masterpiece quality, professional photography + +## brunette_woman +Triggers: брюнетка, brunette, брюнетки +Base: A beautiful brunette woman, 25 years old, long dark wavy hair, green eyes, natural makeup, slim figure, photorealistic, sharp focus, 8K resolution, masterpiece quality, professional photography + +## park +Triggers: парк, park, садик +Base: lush green urban park, sunny afternoon, tall trees, soft bokeh background, natural daylight, fresh grass + +## forest +Triggers: лес, forest, лесу +Base: dense green forest, dappled sunlight through trees, misty atmosphere, natural lighting, photorealistic environment + +## beach +Triggers: пляж, beach, море, sea +Base: sunny tropical beach, clear turquoise water, white sand, palm trees, golden hour lighting + +## city +Triggers: город, city, улица, street +Base: modern city street, urban environment, evening golden hour, bokeh city lights background + +## cafe +Triggers: кафе, cafe, кофейня, coffee shop +Base: cozy modern cafe interior, warm lighting, wooden tables, coffee cups, soft bokeh background +``` + +- [ ] **2.3** Создать `params/styles.md`: + +```md +# Фотографические стили для image-gen + +## portrait +Triggers: портрет, portrait +Style: 85mm lens portrait photography, shallow depth of field f/1.8, studio lighting, sharp focus on face, professional headshot quality + +## cinematic +Triggers: кинематограф, cinematic, кино, film +Style: cinematic shot, movie still, dramatic lighting, widescreen 2.35:1 composition, film grain, color grading + +## street +Triggers: стрит, уличное, street photography, репортаж +Style: candid street photography, natural available light, urban setting, Leica style, documentary feel + +## fashion +Triggers: фэшн, fashion, модный, editorial +Style: high fashion editorial photography, Vogue style, dramatic studio lighting, fashion magazine composition + +## artistic +Triggers: арт, художественное, artistic, art photo +Style: fine art photography, creative composition, dramatic shadows, high contrast, artistic vision +``` + +- [ ] **2.4** Создать пустой `params/favorites.md`: + +```md +# Избранные промпты image-gen +# Формат: дата — описание | Model | Prompt | Negative + +``` + +**Критерий готовности:** 4 params файла созданы, templates содержат минимум 5 объектов. + +--- + +### Task 3: Написать `scripts/generate.py` + +**Шаги:** + +- [ ] **3.1** Реализовать скрипт со следующим CLI-интерфейсом: + +``` +python generate.py \ + --prompt "A beautiful blonde woman in a park..." \ + --negative "deformed limbs, bad anatomy..." \ + --model "recraft/recraft-v4.1-pro" \ + --ratio "9:16" \ + --count 1 \ + --provider "openrouter" \ + --save-dir "/root/images/image-gen/2026-05-24/" \ + --tg-chat-id "126472752" +``` + +- [ ] **3.2** Логика скрипта: + 1. Загрузить `.env` из `~/.openclaw/.env` + 2. Если `--model` начинается с `group:` — развернуть в список моделей из `params/models.md` (парсить файл) + 3. Для каждой модели × count итераций: + - Сделать API запрос (OpenRouter или A2E в зависимости от `--provider`) + - Сохранить как `YYYY-MM-DD_HH-MM-SS_.jpg` + 4. Каждую картинку отправить в TG: + ```bash + openclaw message send --channel telegram --target \ + --media \ + --message "🎨 Model: \n📝 " + ``` + +- [ ] **3.3** OpenRouter API вызов: + ```python + POST https://openrouter.ai/api/v1/chat/completions + Authorization: Bearer $OPENROUTER_API_KEY + { + "model": "recraft/recraft-v4.1-pro", + "messages": [{"role": "user", "content": prompt}], + "modalities": ["image"], + "image_config": { + "aspect_ratio": ratio, + "image_size": "2K" + } + } + # Ответ: choices[0].message.images[0].image_url.url → base64 + # Декодировать base64 и сохранить как .jpg + ``` + +- [ ] **3.4** A2E API вызов — реализовать согласно `references/a2e_api.md` (изучить в Task 1) + +- [ ] **3.5** Протестировать: + ```bash + cd ~/.openclaw/skills/image-gen/ + python scripts/generate.py \ + --prompt "A beautiful blonde woman in a sunny park, portrait, 8K, photorealistic" \ + --negative "deformed limbs, distorted hands" \ + --model "recraft/recraft-v4.1-pro" \ + --ratio "9:16" \ + --count 1 \ + --provider "openrouter" \ + --save-dir "/tmp/test-images/" \ + --tg-chat-id "126472752" + ``` + Ожидаемый результат: картинка сохранена в `/tmp/test-images/`, пришла в Telegram с подписью. + +**Критерий готовности:** тест успешен, картинка в Telegram. + +--- + +### Task 4: Написать `SKILL.md` + +- [ ] **4.1** Создать `SKILL.md` с фронтматтером и инструкциями: + +```yaml +--- +name: image-gen +description: Generate images via Recraft (OpenRouter) and A2E.ai models. + Use when user asks to generate, draw, or create an image/photo. + Triggers: "сгенерируй фото", "нарисуй изображение", "generate image", + "сгенерируй картинку", "create a photo", "draw me". +--- +``` + +Тело SKILL.md должно содержать: +- Как читать `params/templates.md` и матчить объекты из запроса +- Как читать `params/styles.md` и применять стиль +- Формула промпта: `base_template + location/context + style + user_unique_details` +- Как вызывать `scripts/generate.py` +- Как обрабатывать мульти-модель запросы (`group:all_v4`) +- После генерации: спросить "Сохранить в избранное?" → если да, добавить в `params/favorites.md` +- Ссылки на references: читать перед работой с новой моделью или если нужны детали API + +- [ ] **4.2** Убедиться что SKILL.md ≤ 500 строк (детали → в references) + +**Критерий готовности:** SKILL.md проходит валидацию `package_skill.py`. + +--- + +### Task 5: Упаковать скилл + +- [ ] **5.1** Запустить упаковку: + ```bash + python /app/skills/skill-creator/scripts/package_skill.py \ + ~/.openclaw/skills/image-gen/ \ + ~/.openclaw/skills/ + ``` + Ожидаемый результат: `~/.openclaw/skills/image-gen.skill` создан без ошибок. + +**Критерий готовности:** файл `image-gen.skill` создан, валидация прошла без ошибок. + +--- + +## Проверка (Acceptance) + +| # | Проверка | Команда | Ожидаемый результат | +|---|----------|---------|---------------------| +| 1 | Структура скилла | `ls ~/.openclaw/skills/image-gen/` | Все папки и файлы созданы | +| 2 | Тест генерации Recraft | `python generate.py --prompt "test girl in park" --model recraft/recraft-v4.1-pro ...` | Картинка в TG | +| 3 | Тест группы моделей | `--model group:all_v4.1 --count 1` | 4 картинки в TG | +| 4 | Упаковка | `package_skill.py ~/.openclaw/skills/image-gen/` | Нет ошибок валидации | + +--- + +## Ограничения и контекст + +- ⚠️ API ключи **только из `~/.openclaw/.env`** — не хардкодить в скрипт +- ⚠️ A2E API может требовать браузерного рендеринга для доки — попробовать `curl -H "Authorization: Bearer $A2E_API_TOKEN" https://video.a2e.ai/api/` для autodiscovery +- ⚠️ OpenRouter возвращает изображение как base64 data URL в `choices[0].message.images[0].image_url.url` — нужно декодировать и сохранить +- ⚠️ `openclaw message send --media` — таймаут 30+ секунд +- ⚠️ `params/models.md` — парсить нужно только секцию `groups:` для разворачивания групп; простой text parsing достаточен +- 🚫 Не использовать `MEDIA:` директиву в ответах агента — только `openclaw message send` +- ℹ️ Скилл устанавливается в `~/.openclaw/skills/` — общая папка для всех агентов + +--- + +*Создано: 2026-05-24 | Автор ТЗ: Стрим | Исполнитель: Dev-агент* diff --git a/tasks/image-gen/TEST_CASES.md b/tasks/image-gen/TEST_CASES.md new file mode 100644 index 0000000..8c382a2 --- /dev/null +++ b/tasks/image-gen/TEST_CASES.md @@ -0,0 +1,246 @@ +# Тест-кейсы: Скилл `image-gen` + +--- +created: 2026-05-24 +--- + +## TC-01: Базовая генерация — один объект, дефолтная модель + +**Запрос пользователя:** «сгенерируй фото блондинки» + +**Ожидаемое поведение:** +1. Агент матчит шаблон `blonde_woman` +2. Промпт = `base(blonde_woman)` + качественные усилители из шаблона +3. Модель: `recraft/recraft-v4.1-pro` (дефолт) +4. Aspect ratio: 9:16 (дефолт) +5. Negative prompt из `params/models.md` +6. Картинка отправлена в TG с подписью: `🎨 Model: recraft/recraft-v4.1-pro | 📝 Блондинка` +7. Агент спрашивает: «Сохранить в избранное?» + +**Проверка:** картинка в Telegram, вертикальная ✅ + +--- + +## TC-02: Объект + локация + +**Запрос:** «сгенерируй фото блондинки в парке» + +**Ожидаемое поведение:** +1. Матчит: `blonde_woman` + `park` +2. Промпт = `base(blonde_woman)` + `base(park)` + merged контекст +3. Дефолтная модель, 9:16 + +**Проверка:** на фото — блондинка на фоне парка ✅ + +--- + +## TC-03: Объект + локация + стиль + +**Запрос:** «сгенерируй портрет блондинки в парке» + +**Ожидаемое поведение:** +1. Матчит: `blonde_woman` + `park` + стиль `portrait` +2. Промпт = `base(blonde_woman)` + `base(park)` + `style(portrait)` +3. Aspect ratio: остаётся 9:16 (портрет вертикальный — ок) + +**Проверка:** мягкий боке, 85mm-look, блондинка в парке ✅ + +--- + +## TC-04: Явное указание модели + +**Запрос:** «сгенерируй фото блондинки через recraft-v4» + +**Ожидаемое поведение:** +1. Модель: `recraft/recraft-v4` (явно указана) +2. Остальное — дефолты + +**Проверка:** подпись содержит `recraft-v4`, не `recraft-v4.1-pro` ✅ + +--- + +## TC-05: Мульти-модель — группа v4.1 + +**Запрос:** «сгенерируй блондинку через все модели v4.1» + +**Ожидаемое поведение:** +1. `--model group:all_v4.1` → разворачивается в 4 модели +2. Один и тот же промпт отправляется в каждую модель +3. В TG приходят 4 картинки, каждая с подписью своей модели + +**Проверка:** 4 фото в TG с разными моделями в подписи ✅ + +--- + +## TC-06: Мульти-модель — все recraft + +**Запрос:** «сгенерируй через все модели recraft» + +**Ожидаемое поведение:** +1. `--model group:all` → 7 моделей +2. 7 картинок в TG + +**Проверка:** 7 фото, все с разными моделями ✅ + +--- + +## TC-07: Несколько вариантов от одной модели + +**Запрос:** «сгенерируй 3 варианта фото блондинки» + +**Ожидаемое поведение:** +1. `--count 3`, дефолтная модель +2. 3 картинки с одного промпта (разный seed) +3. Каждая отправлена отдельно в TG + +**Проверка:** 3 фото в TG, одна и та же модель в подписи ✅ + +--- + +## TC-08: Нестандартные детали без шаблона + +**Запрос:** «сгенерируй фото гор на закате» + +**Ожидаемое поведение:** +1. Нет шаблона для "горы" — агент использует детали из запроса напрямую +2. Промпт = перевод запроса на английский + quality enhancers +3. Не падает с ошибкой + +**Проверка:** горы на закате, нет артефактов ✅ + +--- + +## TC-09: Горизонтальный формат + +**Запрос:** «сгенерируй горизонтальное фото пляжа» + +**Ожидаемое поведение:** +1. Слово "горизонтальное" → aspect ratio `16:9` +2. Промпт матчит шаблон `beach` + +**Проверка:** фото горизонтальное (landscape) ✅ + +--- + +## TC-10: Квадратный формат + +**Запрос:** «сгенерируй квадратное фото кафе» + +**Ожидаемое поведение:** +1. "квадратное" → aspect ratio `1:1` +2. Шаблон `cafe` + +**Проверка:** квадратное фото ✅ + +--- + +## TC-11: Сохранение в избранное + +**Запрос:** «сгенерируй блондинку в лесу» +→ Картинка отправлена +→ Агент: «Сохранить в избранное?» +**Ответ:** «да» + +**Ожидаемое поведение:** +1. В `params/favorites.md` добавлена запись: + - дата, краткое описание, модель, полный промпт, negative prompt + +**Проверка:** запись появилась в `params/favorites.md` ✅ + +--- + +## TC-12: Negative prompt работает + +**Запрос:** «сгенерируй фото девушки в полный рост» + +**Ожидаемое поведение:** +1. Negative prompt включён: `deformed limbs, distorted hands, extra fingers...` +2. Руки и ноги выглядят нормально + +**Проверка:** нет деформаций рук/ног ✅ (субъективная оценка) + +--- + +## TC-13: A2E.ai провайдер + +**Запрос:** «сгенерируй фото блондинки через a2e» + +**Ожидаемое поведение:** +1. `--provider a2e` +2. Вызывается A2E API (не OpenRouter) +3. Картинка сохранена и отправлена в TG + +**Проверка:** картинка пришла, в подписи видно что это A2E ✅ + +--- + +## TC-14: Кинематографический стиль + +**Запрос:** «сгенерируй кинематографическое фото города ночью» + +**Ожидаемое поведение:** +1. Стиль `cinematic` + шаблон `city` + детали "ночью" (night) +2. Промпт: `cinematic shot, dramatic lighting, city at night...` + +**Проверка:** ночной город, кинематографический вид ✅ + +--- + +## TC-15: Несуществующий шаблон + несуществующий стиль + +**Запрос:** «сгенерируй фото дракона в стиле акварели» + +**Ожидаемое поведение:** +1. Нет шаблона "дракон", нет стиля "акварель" +2. Агент переводит запрос на английский напрямую: `dragon, watercolor style...` +3. Не падает, генерирует + +**Проверка:** фото дракона в акварельном стиле ✅ + +--- + +## TC-16: Граничный случай — очень короткий запрос + +**Запрос:** «сгенерируй» + +**Ожидаемое поведение:** +1. Агент уточняет: «Что именно сгенерировать?» +2. Не вызывает скрипт с пустым промптом + +**Проверка:** агент задал уточняющий вопрос ✅ + +--- + +## TC-17: Граничный случай — запрос на английском + +**Запрос:** «generate photo of blonde in a park» + +**Ожидаемое поведение:** +1. Скилл триггерится на английский запрос тоже +2. Матчит `blonde_woman` + `park` + +**Проверка:** сгенерировано нормально ✅ + +--- + +## Чеклист для финальной приёмки + +| TC | Описание | Статус | +|----|----------|--------| +| TC-01 | Базовая генерация | ⬜ | +| TC-02 | Объект + локация | ⬜ | +| TC-03 | Объект + локация + стиль | ⬜ | +| TC-04 | Явная модель | ⬜ | +| TC-05 | Группа all_v4.1 | ⬜ | +| TC-06 | Все модели | ⬜ | +| TC-07 | 3 варианта | ⬜ | +| TC-08 | Без шаблона | ⬜ | +| TC-09 | Горизонтальный | ⬜ | +| TC-10 | Квадратный | ⬜ | +| TC-11 | Избранное | ⬜ | +| TC-12 | Negative prompt | ⬜ | +| TC-13 | A2E провайдер | ⬜ | +| TC-14 | Кино стиль | ⬜ | +| TC-15 | Нет шаблона/стиля | ⬜ | +| TC-16 | Пустой запрос | ⬜ | +| TC-17 | Запрос на английском | ⬜ |