studio-lumiere-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/annotate-image/SKILL.md +99 -0
- package/.agents/skills/config-troubleshooting/SKILL.md +97 -0
- package/.agents/skills/generate-images/SKILL.md +667 -0
- package/.agents/skills/generate-video/SKILL.md +328 -0
- package/.agents/skills/image-grid/SKILL.md +96 -0
- package/.agents/skills/image-overlay/SKILL.md +66 -0
- package/.agents/skills/image-overlay/agents/openai.yaml +4 -0
- package/.agents/skills/image-overlay/scripts/overlay-image.js +218 -0
- package/.agents/skills/muse-management/SKILL.md +232 -0
- package/.agents/skills/refine-images/SKILL.md +192 -0
- package/.agents/skills/tired-girl/SKILL.md +131 -0
- package/.env.example +2 -0
- package/AGENTS.md +66 -0
- package/README.md +96 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +214 -0
- package/dist/cli.js.map +1 -0
- package/dist/clients/geminiClient.d.ts +37 -0
- package/dist/clients/geminiClient.js +129 -0
- package/dist/clients/geminiClient.js.map +1 -0
- package/dist/config/constants.d.ts +63 -0
- package/dist/config/constants.js +1005 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/options.d.ts +1 -0
- package/dist/config/options.js +2 -0
- package/dist/config/options.js.map +1 -0
- package/dist/config/templates.d.ts +3 -0
- package/dist/config/templates.js +4 -0
- package/dist/config/templates.js.map +1 -0
- package/dist/config/tiredGirl.d.ts +3 -0
- package/dist/config/tiredGirl.js +9 -0
- package/dist/config/tiredGirl.js.map +1 -0
- package/dist/image/annotate.d.ts +2 -0
- package/dist/image/annotate.js +119 -0
- package/dist/image/annotate.js.map +1 -0
- package/dist/image/grid.d.ts +2 -0
- package/dist/image/grid.js +44 -0
- package/dist/image/grid.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/pipelines/createMuse.d.ts +3 -0
- package/dist/pipelines/createMuse.js +49 -0
- package/dist/pipelines/createMuse.js.map +1 -0
- package/dist/pipelines/generateImages.d.ts +2 -0
- package/dist/pipelines/generateImages.js +140 -0
- package/dist/pipelines/generateImages.js.map +1 -0
- package/dist/pipelines/generateTiredGirl.d.ts +2 -0
- package/dist/pipelines/generateTiredGirl.js +73 -0
- package/dist/pipelines/generateTiredGirl.js.map +1 -0
- package/dist/pipelines/generateVideo.d.ts +2 -0
- package/dist/pipelines/generateVideo.js +27 -0
- package/dist/pipelines/generateVideo.js.map +1 -0
- package/dist/pipelines/refineImage.d.ts +2 -0
- package/dist/pipelines/refineImage.js +28 -0
- package/dist/pipelines/refineImage.js.map +1 -0
- package/dist/pipelines/resolve.d.ts +11 -0
- package/dist/pipelines/resolve.js +74 -0
- package/dist/pipelines/resolve.js.map +1 -0
- package/dist/pipelines/upscaleImage.d.ts +2 -0
- package/dist/pipelines/upscaleImage.js +23 -0
- package/dist/pipelines/upscaleImage.js.map +1 -0
- package/dist/prompt/buildPrompt.d.ts +4 -0
- package/dist/prompt/buildPrompt.js +322 -0
- package/dist/prompt/buildPrompt.js.map +1 -0
- package/dist/prompt/tiredGirlPrompt.d.ts +3 -0
- package/dist/prompt/tiredGirlPrompt.js +33 -0
- package/dist/prompt/tiredGirlPrompt.js.map +1 -0
- package/dist/storage/files.d.ts +15 -0
- package/dist/storage/files.js +34 -0
- package/dist/storage/files.js.map +1 -0
- package/dist/storage/museStore.d.ts +5 -0
- package/dist/storage/museStore.js +26 -0
- package/dist/storage/museStore.js.map +1 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/generate.d.ts +1 -0
- package/examples/generate.js +28 -0
- package/examples/generate.js.map +1 -0
- package/examples/generate.ts +30 -0
- package/examples/muse.d.ts +1 -0
- package/examples/muse.js +18 -0
- package/examples/muse.js.map +1 -0
- package/examples/muse.ts +20 -0
- package/examples/video.d.ts +1 -0
- package/examples/video.js +18 -0
- package/examples/video.js.map +1 -0
- package/examples/video.ts +20 -0
- package/logo-round.png +0 -0
- package/logo.jpeg +0 -0
- package/package.json +27 -0
- package/src/cli.ts +259 -0
- package/src/clients/geminiClient.ts +168 -0
- package/src/config/constants.ts +1105 -0
- package/src/config/options.ts +15 -0
- package/src/config/templates.ts +4 -0
- package/src/config/tiredGirl.ts +11 -0
- package/src/image/annotate.ts +139 -0
- package/src/image/grid.ts +58 -0
- package/src/index.ts +27 -0
- package/src/pipelines/createMuse.ts +76 -0
- package/src/pipelines/generateImages.ts +203 -0
- package/src/pipelines/generateTiredGirl.ts +86 -0
- package/src/pipelines/generateVideo.ts +36 -0
- package/src/pipelines/refineImage.ts +36 -0
- package/src/pipelines/resolve.ts +88 -0
- package/src/pipelines/upscaleImage.ts +30 -0
- package/src/prompt/buildPrompt.ts +380 -0
- package/src/prompt/tiredGirlPrompt.ts +35 -0
- package/src/storage/files.ts +41 -0
- package/src/storage/museStore.ts +31 -0
- package/src/types.ts +198 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,667 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-images
|
|
3
|
+
description: End-to-end guide to generate images with local-lumiere SDK/CLI; use for image generation workflows and parameter reference.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Generate Images (local-lumiere)
|
|
7
|
+
|
|
8
|
+
This document is a complete, end-to-end guide for an AI agent to generate images using the **local-lumiere** SDK/CLI. It is designed to be consumed as a standalone skill: read this file, then follow the steps exactly. It covers **every function**, **every parameter**, and **all configuration points** involved in image generation.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Quick Start (60 seconds)
|
|
13
|
+
|
|
14
|
+
1) Ensure `GEMINI_API_KEY` is set in your environment.
|
|
15
|
+
2) Build the project:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
npm install
|
|
19
|
+
npm run build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3) Generate an image via CLI:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
node dist/cli.js generate \
|
|
26
|
+
--images ./inputs/ring.jpg \
|
|
27
|
+
--template hand_model \
|
|
28
|
+
--detail nail_nude \
|
|
29
|
+
--ethnicity mena \
|
|
30
|
+
--skin-tone medium \
|
|
31
|
+
--hair-color brunette \
|
|
32
|
+
--background cream_silk \
|
|
33
|
+
--background-type studio \
|
|
34
|
+
--vibe clean \
|
|
35
|
+
--resolution portrait \
|
|
36
|
+
--quantity 1
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
4) Find output files under `outputs/generations/<timestamp>/`.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 0) Purpose
|
|
44
|
+
|
|
45
|
+
The goal is to programmatically generate high-end jewelry imagery locally, mirroring the Studio Lumiere app flow:
|
|
46
|
+
|
|
47
|
+
- Provide input jewelry images
|
|
48
|
+
- Choose a template + template options
|
|
49
|
+
- Pick model/style settings (ethnicity, skin tone, hair, background, vibe, resolution, occasion)
|
|
50
|
+
- Optionally use a Muse (consistent model reference)
|
|
51
|
+
- Optionally generate multiple outputs in one run
|
|
52
|
+
- Save outputs locally + log full metadata
|
|
53
|
+
|
|
54
|
+
This skill focuses specifically on **image generation** (not refine/upscale/video/muse creation except where Muse references are used in generation).
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 1) Where the Image Generation API Lives
|
|
59
|
+
|
|
60
|
+
**SDK entrypoint**: `src/index.ts`
|
|
61
|
+
|
|
62
|
+
- `generateImages` (primary API)
|
|
63
|
+
- `TEMPLATES`, `ETHNICITIES`, `SKIN_TONES`, `HAIR_COLORS`, `BACKGROUNDS`, `BACKGROUND_TYPES`, `VIBES`, `RESOLUTIONS`, `OCCASIONS` (config lists)
|
|
64
|
+
|
|
65
|
+
**Pipeline implementation**: `src/pipelines/generateImages.ts`
|
|
66
|
+
|
|
67
|
+
**Prompt building**: `src/prompt/buildPrompt.ts`
|
|
68
|
+
|
|
69
|
+
**Gemini client wrapper**: `src/clients/geminiClient.ts`
|
|
70
|
+
|
|
71
|
+
**Option resolution**: `src/pipelines/resolve.ts`
|
|
72
|
+
|
|
73
|
+
**File I/O**: `src/storage/files.ts`
|
|
74
|
+
|
|
75
|
+
**Muse lookup**: `src/storage/museStore.ts`
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 2) Required Environment and Configuration
|
|
80
|
+
|
|
81
|
+
### 2.1 Environment Variables
|
|
82
|
+
|
|
83
|
+
- `GEMINI_API_KEY` (required)
|
|
84
|
+
- Used by `GeminiClient` to authenticate to Gemini APIs.
|
|
85
|
+
|
|
86
|
+
- `LUMIERE_OUTPUT_DIR` (optional)
|
|
87
|
+
- Default output directory for all generated assets.
|
|
88
|
+
- Defaults to `outputs` if not set.
|
|
89
|
+
|
|
90
|
+
### 2.2 Runtime Config Object
|
|
91
|
+
|
|
92
|
+
All SDK functions expect a `LumiereConfig` object:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
export interface LumiereConfig {
|
|
96
|
+
apiKey: string; // required
|
|
97
|
+
outputDir: string; // required (can be read from env)
|
|
98
|
+
models?: {
|
|
99
|
+
prompt?: string; // Gemini text model
|
|
100
|
+
image?: string; // Gemini image model
|
|
101
|
+
video?: string; // Gemini video model
|
|
102
|
+
};
|
|
103
|
+
retry?: {
|
|
104
|
+
maxRetries?: number; // default: 3
|
|
105
|
+
baseDelayMs?: number;// default: 1500
|
|
106
|
+
maxDelayMs?: number; // default: 12000
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Defaults if omitted:
|
|
112
|
+
|
|
113
|
+
- `models.prompt`: `gemini-3-flash-preview`
|
|
114
|
+
- `models.image`: `gemini-3-pro-image-preview`
|
|
115
|
+
- `models.video`: `veo-3.1-generate-preview` (not used for images)
|
|
116
|
+
- `retry.maxRetries`: 3
|
|
117
|
+
- `retry.baseDelayMs`: 1500
|
|
118
|
+
- `retry.maxDelayMs`: 12000
|
|
119
|
+
|
|
120
|
+
### 2.3 Output Directory Structure
|
|
121
|
+
|
|
122
|
+
`generateImages()` creates a timestamped folder under `outputDir`:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
outputs/
|
|
126
|
+
generations/
|
|
127
|
+
2026-02-11T19-40-12-123Z/
|
|
128
|
+
image_1.png
|
|
129
|
+
image_2.png
|
|
130
|
+
generation.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The timestamp is generated in `resolveOutputDir()` in `src/storage/files.ts`.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 3) Primary Function: generateImages
|
|
138
|
+
|
|
139
|
+
### 3.1 Function Signature
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
export const generateImages = async (
|
|
143
|
+
config: LumiereConfig,
|
|
144
|
+
request: GenerationRequest
|
|
145
|
+
): Promise<GenerationResult>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 3.2 Request Object: GenerationRequest
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
export interface GenerationRequest {
|
|
152
|
+
inputImages: string[]; // Required. File paths to local jewelry images.
|
|
153
|
+
quantity?: number; // Optional. Number of images to generate. Default: 1.
|
|
154
|
+
selections: GenerationSelections; // Required. All template/style choices.
|
|
155
|
+
styleHint?: string; // Optional. Extra pose/angle guidance.
|
|
156
|
+
museId?: string; // Optional. ID of a stored Muse.
|
|
157
|
+
museImagePaths?: string[]; // Optional. Direct Muse image paths.
|
|
158
|
+
outputDir?: string; // Optional. Override config.outputDir.
|
|
159
|
+
enhancePrompt?: boolean; // Optional. Default true. Uses LLM prompt enhancement.
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3.3 Response Object: GenerationResult
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
export interface GenerationResult {
|
|
167
|
+
prompt: string; // Base prompt (pre-enhancement)
|
|
168
|
+
enhancedPrompt?: string; // Final prompt after enhancement
|
|
169
|
+
outputImages: string[]; // Paths of saved output images
|
|
170
|
+
logPath: string; // Path to generation.json
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 4) GenerationSelections (All Parameters)
|
|
177
|
+
|
|
178
|
+
The **selections** object controls all creative settings. All IDs must match configured options.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
export interface GenerationSelections {
|
|
182
|
+
templateId: string; // Required: template key
|
|
183
|
+
detailId?: string; // Primary template option
|
|
184
|
+
secondaryDetailId?: string;// Secondary template option
|
|
185
|
+
tertiaryDetailId?: string; // Tertiary template option
|
|
186
|
+
ethnicityId?: string; // Model ethnicity
|
|
187
|
+
skinToneId?: string; // Model skin tone
|
|
188
|
+
hairColorId?: string; // Model hair color
|
|
189
|
+
backgroundId?: string; // Background palette
|
|
190
|
+
backgroundTypeId?: string; // Background environment
|
|
191
|
+
vibeId?: string; // Lighting & mood
|
|
192
|
+
resolutionId?: string; // Aspect ratio preset
|
|
193
|
+
occasionId?: string; // Optional theme
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Every field is optional except `templateId`.**
|
|
198
|
+
|
|
199
|
+
If a field is not provided, the pipeline may:
|
|
200
|
+
- Omit that parameter from the prompt
|
|
201
|
+
- Fall back to a safe default (e.g., `resolutionId` defaults to `portrait`)
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 5) Templates (All Available IDs)
|
|
206
|
+
|
|
207
|
+
Templates are defined in `src/config/templates.ts` and resolved by `TEMPLATE_MAP`.
|
|
208
|
+
|
|
209
|
+
### 5.1 Template IDs
|
|
210
|
+
|
|
211
|
+
- `hand_model`
|
|
212
|
+
- `neck_model`
|
|
213
|
+
- `ear_model`
|
|
214
|
+
- `flatlay_creative`
|
|
215
|
+
- `floating_minimal`
|
|
216
|
+
- `half_body_muse`
|
|
217
|
+
- `museum_exhibit`
|
|
218
|
+
- `romantic_mood`
|
|
219
|
+
- `romance_proposal`
|
|
220
|
+
|
|
221
|
+
Each template includes:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
interface Template {
|
|
225
|
+
id: string;
|
|
226
|
+
name: string;
|
|
227
|
+
description: string;
|
|
228
|
+
basePrompt: string;
|
|
229
|
+
customizationLabel?: string;
|
|
230
|
+
customizationOptions?: Option[];
|
|
231
|
+
secondaryCustomizationLabel?: string;
|
|
232
|
+
secondaryCustomizationOptions?: Option[];
|
|
233
|
+
tertiaryCustomizationLabel?: string;
|
|
234
|
+
tertiaryCustomizationOptions?: Option[];
|
|
235
|
+
museEnabled?: boolean;
|
|
236
|
+
videoEnabled?: boolean;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 5.2 Template Options (Primary/Secondary/Tertiary)
|
|
241
|
+
|
|
242
|
+
Each template can define up to 3 customization groups:
|
|
243
|
+
|
|
244
|
+
- **Primary** => `detailId`
|
|
245
|
+
- **Secondary** => `secondaryDetailId`
|
|
246
|
+
- **Tertiary** => `tertiaryDetailId`
|
|
247
|
+
|
|
248
|
+
The option lists are defined per template in `src/config/templates.ts`.
|
|
249
|
+
|
|
250
|
+
If an ID is passed but not found in the template’s option list, the resolver will still accept it by mapping it to a placeholder `{ id, name, value }`.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 6) Global Style Options (All Config Lists)
|
|
255
|
+
|
|
256
|
+
Defined in `src/config/options.ts`.
|
|
257
|
+
|
|
258
|
+
### 6.1 Ethnicities (`ETHNICITIES`)
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
id: "none" | "mena" | "south_asian" | "east_asian" | "black" | "white" | "latina"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Used for prompt substitution and may expand to specific regions via `ETHNICITY_REGIONS`.
|
|
265
|
+
|
|
266
|
+
### 6.2 Skin Tones (`SKIN_TONES`)
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
id: "porcelain" | "fair" | "medium" | "tan" | "deep"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 6.3 Hair Colors (`HAIR_COLORS`)
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
id: "black" | "brunette" | "blonde" | "red" | "salt_pepper"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### 6.4 Background Palettes (`BACKGROUNDS`)
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
id: "cream_silk" | "midnight_velvet" | "white_marble" | "warm_sand" | "charcoal"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 6.5 Background Types (`BACKGROUND_TYPES`)
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
id: "studio" | "interior" | "outdoor" | "macro"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### 6.6 Vibes (`VIBES`)
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
id: "golden" | "moody" | "clean" | "romantic"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 6.7 Resolutions (`RESOLUTIONS`)
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
id: "square" | "portrait" | "story" | "landscape"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Maps to aspect ratio values:
|
|
303
|
+
|
|
304
|
+
- square => `1:1`
|
|
305
|
+
- portrait => `3:4`
|
|
306
|
+
- story => `9:16`
|
|
307
|
+
- landscape => `16:9`
|
|
308
|
+
|
|
309
|
+
### 6.8 Occasions (`OCCASIONS`)
|
|
310
|
+
|
|
311
|
+
Example IDs:
|
|
312
|
+
|
|
313
|
+
- `wedding`
|
|
314
|
+
- `eid`
|
|
315
|
+
- `valentines`
|
|
316
|
+
|
|
317
|
+
Each occasion injects a rich scene description into the prompt if selected.
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 7) Prompt Construction (All Inputs and Behavior)
|
|
322
|
+
|
|
323
|
+
Prompt construction happens in `buildLumierePrompt()` in `src/prompt/buildPrompt.ts`.
|
|
324
|
+
|
|
325
|
+
### 7.1 Inputs
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
interface PromptInputs {
|
|
329
|
+
template: Template;
|
|
330
|
+
detail?: Option;
|
|
331
|
+
secondaryDetail?: Option;
|
|
332
|
+
tertiaryDetail?: Option;
|
|
333
|
+
ethnicity?: Option;
|
|
334
|
+
skinTone?: Option;
|
|
335
|
+
hairColor?: Option;
|
|
336
|
+
background?: Option;
|
|
337
|
+
backgroundType?: Option;
|
|
338
|
+
vibe?: Option;
|
|
339
|
+
resolution: Resolution;
|
|
340
|
+
occasion?: OccasionTheme;
|
|
341
|
+
imageCount: number;
|
|
342
|
+
isVariation?: boolean;
|
|
343
|
+
styleHint?: string;
|
|
344
|
+
hasMuse?: boolean;
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### 7.2 Core Prompt Rules
|
|
349
|
+
|
|
350
|
+
- Replaces `[ETHNICITY]` and `[HAIR_COLOR]` placeholders in template base prompts.
|
|
351
|
+
- Enforces jewelry fidelity (no extra jewelry, no fake sparkles).
|
|
352
|
+
- Optionally adds occasion scene blocks.
|
|
353
|
+
- Adds model specifications from detail/secondary/tertiary selections.
|
|
354
|
+
- Applies environment settings if no occasion is chosen.
|
|
355
|
+
- Adds technical requirements, aspect ratio, and strict prohibitions.
|
|
356
|
+
- If `styleHint` is provided, it appends “STYLE & POSE DIRECTION.”
|
|
357
|
+
- If `isVariation` true, it appends an explicit “variation instruction.”
|
|
358
|
+
|
|
359
|
+
### 7.3 Skip Logic for Ethnicity
|
|
360
|
+
|
|
361
|
+
Ethnicity is **not** included when:
|
|
362
|
+
|
|
363
|
+
- A Muse is being used (`hasMuse` true), OR
|
|
364
|
+
- Template is one of: `hand_model`, `flatlay_creative`, `floating_minimal`, `museum_exhibit`, `romantic_mood`
|
|
365
|
+
|
|
366
|
+
### 7.4 System Instruction
|
|
367
|
+
|
|
368
|
+
`buildSystemInstruction(template, ethnicity)` generates an additional system-style block to guide the LLM for each template.
|
|
369
|
+
|
|
370
|
+
This is combined with the base prompt if `enhancePrompt` is enabled:
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
final = systemInstruction + "\n\n" + basePrompt
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 8) Prompt Enhancement (Gemini Text Model)
|
|
379
|
+
|
|
380
|
+
If `enhancePrompt` is `true` (default), the pipeline calls:
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
GeminiClient.generateText(promptInput)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
- `promptInput` = system instruction + base prompt
|
|
387
|
+
- The result becomes `enhancedPrompt`
|
|
388
|
+
|
|
389
|
+
If disabled, `enhancedPrompt` is the same as `basePrompt`.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## 9) Muse Handling in Generation
|
|
394
|
+
|
|
395
|
+
There are **two ways** to supply Muse references:
|
|
396
|
+
|
|
397
|
+
1) **Direct image paths**: `museImagePaths` (preferred for ad-hoc runs)
|
|
398
|
+
2) **Stored Muse**: `museId`, loaded from `muses.json`
|
|
399
|
+
|
|
400
|
+
### 9.1 Muse Image Parts
|
|
401
|
+
|
|
402
|
+
If Muse images are provided, they are appended to the image parts array and the final prompt is extended with strict Muse consistency language.
|
|
403
|
+
|
|
404
|
+
Muse logic happens in `generateImages.ts`:
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
if (museImageParts) {
|
|
408
|
+
finalPrompt += "Muse consistency requirement...";
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Muse images are passed **after** jewelry images in the `parts` array:
|
|
413
|
+
|
|
414
|
+
```
|
|
415
|
+
parts = [ { text: finalPrompt }, ...jewelryImages, ...museImages ]
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 10) Gemini Image Generation Call
|
|
421
|
+
|
|
422
|
+
Image generation is performed by:
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
GeminiClient.generateImage({
|
|
426
|
+
parts,
|
|
427
|
+
aspectRatio,
|
|
428
|
+
imageSize: "2K"
|
|
429
|
+
})
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 10.1 parts
|
|
433
|
+
|
|
434
|
+
`parts` is an array of:
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
{ text?: string; inlineData?: { mimeType: string; data: string } }
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
The first part is always the prompt (text). Subsequent parts are inline base64 images.
|
|
441
|
+
|
|
442
|
+
### 10.2 Aspect Ratio
|
|
443
|
+
|
|
444
|
+
Passed from `Resolution.aspectRatio`, resolved via `resolveResolution()`.
|
|
445
|
+
|
|
446
|
+
### 10.3 Image Size
|
|
447
|
+
|
|
448
|
+
Hard-coded to `2K` in the image generation pipeline.
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## 11) Upscaling an Image
|
|
453
|
+
|
|
454
|
+
While this skill focuses on generation, upscaling is a common follow-up step and is supported locally via `upscaleImage`.
|
|
455
|
+
|
|
456
|
+
### 11.1 Function Signature
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
export const upscaleImage = async (
|
|
460
|
+
config: LumiereConfig,
|
|
461
|
+
request: UpscaleRequest
|
|
462
|
+
): Promise<string>
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 11.2 Request Object: UpscaleRequest
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
export interface UpscaleRequest {
|
|
469
|
+
inputImage: string; // Required. Path to a local image file.
|
|
470
|
+
scale?: number; // Optional. Scale factor (default: 2).
|
|
471
|
+
outputDir?: string; // Optional. Override config.outputDir.
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### 11.3 Behavior
|
|
476
|
+
|
|
477
|
+
- Builds an upscaling prompt: "Upscale this image to Nx resolution..."
|
|
478
|
+
- Uses Gemini image model via `GeminiClient.generateImage()`
|
|
479
|
+
- Saves output as `upscaled.png` in `outputs/upscales/<timestamp>/`
|
|
480
|
+
- Writes `upscale.json` log with input path, scale, output path
|
|
481
|
+
|
|
482
|
+
### 11.4 SDK Example
|
|
483
|
+
|
|
484
|
+
```ts
|
|
485
|
+
import { upscaleImage } from "./dist/index.js";
|
|
486
|
+
|
|
487
|
+
const outputPath = await upscaleImage(
|
|
488
|
+
{ apiKey, outputDir: "outputs" },
|
|
489
|
+
{ inputImage: "./outputs/generations/.../image_1.png", scale: 2 }
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
console.log(outputPath);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 11.5 CLI Example
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
node dist/cli.js upscale --image ./outputs/image.png --scale 2
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## 12) CLI Usage (Full Parameters)
|
|
504
|
+
|
|
505
|
+
The CLI is implemented in `src/cli.ts` and compiled to `dist/cli.js`.
|
|
506
|
+
|
|
507
|
+
### 12.1 Generate Command
|
|
508
|
+
|
|
509
|
+
```
|
|
510
|
+
node dist/cli.js generate \
|
|
511
|
+
--images ./inputs/ring.jpg,./inputs/bracelet.jpg \
|
|
512
|
+
--template hand_model \
|
|
513
|
+
--detail nail_nude \
|
|
514
|
+
--secondary-detail nail_red \
|
|
515
|
+
--tertiary-detail makeup_soft \
|
|
516
|
+
--ethnicity mena \
|
|
517
|
+
--skin-tone medium \
|
|
518
|
+
--hair-color brunette \
|
|
519
|
+
--background cream_silk \
|
|
520
|
+
--background-type studio \
|
|
521
|
+
--vibe clean \
|
|
522
|
+
--resolution portrait \
|
|
523
|
+
--occasion wedding \
|
|
524
|
+
--quantity 2 \
|
|
525
|
+
--muse-id muse_1700000000000 \
|
|
526
|
+
--muse-images ./muses/m1.png,./muses/m2.png,./muses/m3.png
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### 12.2 Important CLI Flags
|
|
530
|
+
|
|
531
|
+
- `--images`: **required**. Comma-separated list.
|
|
532
|
+
- `--template`: **required**. Must match one of `TEMPLATES`.
|
|
533
|
+
- `--detail`: optional
|
|
534
|
+
- `--secondary-detail`: optional
|
|
535
|
+
- `--tertiary-detail`: optional
|
|
536
|
+
- `--ethnicity`: optional
|
|
537
|
+
- `--skin-tone`: optional
|
|
538
|
+
- `--hair-color`: optional
|
|
539
|
+
- `--background`: optional
|
|
540
|
+
- `--background-type`: optional
|
|
541
|
+
- `--vibe`: optional
|
|
542
|
+
- `--resolution`: optional
|
|
543
|
+
- `--occasion`: optional
|
|
544
|
+
- `--quantity`: optional (default 1)
|
|
545
|
+
- `--muse-id`: optional
|
|
546
|
+
- `--muse-images`: optional (comma list)
|
|
547
|
+
- `--no-enhance`: disable prompt enhancement
|
|
548
|
+
|
|
549
|
+
`--no-enhance` flips `enhancePrompt=false`.
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## 13) Function Call Example (SDK)
|
|
554
|
+
|
|
555
|
+
```ts
|
|
556
|
+
import { generateImages } from "./dist/index.js";
|
|
557
|
+
|
|
558
|
+
const result = await generateImages(
|
|
559
|
+
{
|
|
560
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
561
|
+
outputDir: "outputs",
|
|
562
|
+
models: {
|
|
563
|
+
prompt: "gemini-3-flash-preview",
|
|
564
|
+
image: "gemini-3-pro-image-preview"
|
|
565
|
+
},
|
|
566
|
+
retry: {
|
|
567
|
+
maxRetries: 3,
|
|
568
|
+
baseDelayMs: 1500,
|
|
569
|
+
maxDelayMs: 12000
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
inputImages: ["./inputs/ring.jpg"],
|
|
574
|
+
quantity: 2,
|
|
575
|
+
selections: {
|
|
576
|
+
templateId: "hand_model",
|
|
577
|
+
detailId: "nail_nude",
|
|
578
|
+
ethnicityId: "mena",
|
|
579
|
+
skinToneId: "medium",
|
|
580
|
+
hairColorId: "brunette",
|
|
581
|
+
backgroundId: "cream_silk",
|
|
582
|
+
backgroundTypeId: "studio",
|
|
583
|
+
vibeId: "clean",
|
|
584
|
+
resolutionId: "portrait",
|
|
585
|
+
occasionId: "wedding"
|
|
586
|
+
},
|
|
587
|
+
enhancePrompt: true
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
console.log(result.outputImages);
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## 14) Error Handling and Retries
|
|
597
|
+
|
|
598
|
+
All Gemini calls use a retry wrapper:
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
retry: {
|
|
602
|
+
maxRetries: 3,
|
|
603
|
+
baseDelayMs: 1500,
|
|
604
|
+
maxDelayMs: 12000
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
Retryable error detection looks for:
|
|
609
|
+
- HTTP 429 / 503
|
|
610
|
+
- “overloaded”, “unavailable”, “timeout” text
|
|
611
|
+
|
|
612
|
+
If all retries fail, the error is thrown as-is.
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
## 15) Extending or Modifying the Skill
|
|
617
|
+
|
|
618
|
+
If you need more templates/options:
|
|
619
|
+
|
|
620
|
+
- Add them to `src/config/templates.ts` or `src/config/options.ts`.
|
|
621
|
+
- Ensure your new IDs are used in `GenerationSelections`.
|
|
622
|
+
- The resolver will accept unknown IDs but won’t provide canonical names/values.
|
|
623
|
+
|
|
624
|
+
If you want a different image model or output size:
|
|
625
|
+
|
|
626
|
+
- Change defaults in `GeminiClient` or override `config.models.image`.
|
|
627
|
+
- Modify `generateImages.ts` to change `imageSize` from `2K` to `4K`.
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## 16) Quick Checklist for an AI Agent
|
|
632
|
+
|
|
633
|
+
1) Ensure `GEMINI_API_KEY` is set.
|
|
634
|
+
2) Choose template ID from `TEMPLATES`.
|
|
635
|
+
3) Pick detail IDs based on that template’s options.
|
|
636
|
+
4) Decide optional style params (ethnicity, skin tone, hair, background, vibe, resolution, occasion).
|
|
637
|
+
5) Collect local input image paths.
|
|
638
|
+
6) Optionally provide Muse images or a stored `museId`.
|
|
639
|
+
7) Call `generateImages(config, request)`.
|
|
640
|
+
8) Read output paths and logs from the result.
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
## 17) Related Files (For Reference)
|
|
645
|
+
|
|
646
|
+
- `src/pipelines/generateImages.ts`
|
|
647
|
+
- `src/prompt/buildPrompt.ts`
|
|
648
|
+
- `src/clients/geminiClient.ts`
|
|
649
|
+
- `src/pipelines/resolve.ts`
|
|
650
|
+
- `src/config/templates.ts`
|
|
651
|
+
- `src/config/options.ts`
|
|
652
|
+
- `src/storage/files.ts`
|
|
653
|
+
- `src/storage/museStore.ts`
|
|
654
|
+
- `src/cli.ts`
|
|
655
|
+
|
|
656
|
+
End of skill.
|
|
657
|
+
|
|
658
|
+
## Related Skills
|
|
659
|
+
|
|
660
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\generate-images.md`
|
|
661
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\generate-video.md`
|
|
662
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\refine-images.md`
|
|
663
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\muse-management.md`
|
|
664
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\tired-girl.md`
|
|
665
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\image-grid.md`
|
|
666
|
+
- `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\config-troubleshooting.md`
|
|
667
|
+
|