auto-sync: 2026-05-24 21:10:01

This commit is contained in:
Stream
2026-05-24 21:10:02 +03:00
parent dd14299b46
commit 9a5c0fe544
3 changed files with 772 additions and 0 deletions

197
tasks/image-gen/BRD.md Normal file
View File

@@ -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_<model>.jpg`
4. Отправляет в Telegram через `openclaw message send --media <path>`
---
## `.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/`

329
tasks/image-gen/DEV_TASK.md Normal file
View File

@@ -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_<model_short>.jpg`
4. Каждую картинку отправить в TG:
```bash
openclaw message send --channel telegram --target <tg-chat-id> \
--media <path> \
--message "🎨 Model: <model>\n📝 <caption>"
```
- [ ] **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-агент*

View File

@@ -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 | Запрос на английском | ⬜ |