217 lines
8.4 KiB
Markdown
217 lines
8.4 KiB
Markdown
# BRD: Скилл `image-gen`
|
||
|
||
---
|
||
created: 2026-05-24
|
||
updated: 2026-05-25
|
||
status: approved (v1.1 — bugfixes applied)
|
||
---
|
||
|
||
## Назначение
|
||
|
||
Скилл генерации изображений через онлайн-модели (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 \
|
||
--tg-chat-id "126472752"
|
||
↓
|
||
API → сохранить JPG в ~/.openclaw/workspace/temp/image-gen/YYYY-MM-DD/ → отправить в Telegram
|
||
Подпись авто-генерируется: "🎨 Model: <model>\n📐 <ratio> | <size>\n📝 <prompt>..."
|
||
↓
|
||
Агент спрашивает: "Сохранить промпт в избранное?"
|
||
```
|
||
|
||
---
|
||
|
||
## Структура скилла
|
||
|
||
```
|
||
~/.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 "..." # финальный промпт (английский, мин 10 chars)
|
||
--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 "..." # опционально (дефолт: ~/.openclaw/workspace/temp/image-gen/YYYY-MM-DD/)
|
||
--tg-chat-id "126472752" # обязательный, Telegram chat_id для delivery
|
||
--image-size "2K" # 1K, 2K, 4K
|
||
--models-md "..." # опционально, путь к params/models.md
|
||
```
|
||
|
||
Скрипт:
|
||
1. Читает API ключ из `.env` (OPENROUTER_API_KEY / A2E_API_TOKEN)
|
||
2. Парсит `negative_prompt` из `params/models.md` если не передан `--negative`
|
||
3. Валидирует промпт (минимум 10 символов)
|
||
4. Если `--model group:all_v4` — последовательно генерирует для каждой модели группы
|
||
5. Retry 429 с exponential backoff: 5с → 10с → 20с
|
||
6. Сохраняет каждую картинку: `YYYY-MM-DD_HH-MM-SS_<model>.jpg`
|
||
7. Отправляет в Telegram через `openclaw message send --media <path>`
|
||
8. Считает раздельно: `generated_ok` vs `sent_ok`
|
||
|
||
---
|
||
|
||
## `.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/`
|
||
|
||
## Changelog
|
||
|
||
- **2026-05-25 v1.1** — Bugfix release:
|
||
- ✅ Negative prompt auto-parsed from `models.md` (no manual `--negative` required)
|
||
- ✅ 429 retry with exponential backoff (5s → 10s → 20s, max 3 attempts)
|
||
- ✅ Separate `generated_ok` / `sent_ok` counters (TG failure ≠ success)
|
||
- ✅ A2E graceful skip before loop (early exit, clear message)
|
||
- ✅ Prompt validation before API call (min 10 chars)
|
||
- ✅ Correct save-dir path (`workspace/temp/image-gen/` not `~/images/`)
|
||
- ✅ Removed false `--tg-caption` param from CLI spec
|