Files
wiki/tasks/image-gen/DEV_TASK.md
2026-05-24 21:10:02 +03:00

330 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-агент*