auto-sync: 2026-05-24 21:10:01
This commit is contained in:
197
tasks/image-gen/BRD.md
Normal file
197
tasks/image-gen/BRD.md
Normal 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
329
tasks/image-gen/DEV_TASK.md
Normal 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-агент*
|
||||
246
tasks/image-gen/TEST_CASES.md
Normal file
246
tasks/image-gen/TEST_CASES.md
Normal 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 | Запрос на английском | ⬜ |
|
||||
Reference in New Issue
Block a user