| name | ppt_generate |
| description | Generate slide images from a structured outline JSON, build contact sheets, and export numbered slide images into a PPTX file. |
ppt_generate
Skill Purpose
This skill consumes a structured outline.json and produces a complete slide deck as numbered images plus an optional .pptx export. Python scripts handle image generation, contact sheets, and PPT assembly. Visual quality review is performed by the agent (Codex can view images directly) — not by automated VLM API calls inside Python.
This skill does not generate outlines from natural language, select templates, or run template_ingest.
Inputs
- style.md — required deck-wide style and format guide (written first)
- outline.json — structured per-slide definition with template and reference image paths
- output directory — where numbered images, state, and contact sheets are written
- .env — OpenAI-compatible API configuration for
gpt-image-2
style.md
Write style.md before outline.json. Place it in the same directory as the outline:
data/outlines/deck_01/
├── style.md
└── outline.json
Content defines deck-wide visual identity, layout conventions, imagery tone, and constraints. The full text is injected into every slide generation prompt. See references/style_guide.md.
Image Reference Roles
| Input | Per slide | Max | Role |
|---|
style.md | deck-wide | 1 file | Text style guide (not sent as image) |
template_image | yes | 1 | Slide template — page layout and visual style |
reference_images | yes | 3 | Supplementary visuals — 配图, diagrams, logos |
Outline JSON Structure
Top-level fields (fixed):
| Field | Type | Description |
|---|
deck_title | string | Deck name |
aspect_ratio | string | e.g. "16:9" |
image_format | string | "jpg" or "png" |
slides | array | Slide objects |
Each slide object (fixed fields):
| Field | Type | Description |
|---|
index | int | 1-based slide number (matches output filename) |
slide_id | string | Stable slide identifier |
template_image | string | Slide template path (layout/style), or "" |
reference_images | array | 0–3 supplementary image paths |
description | string | Generation instructions |
layout | string | Layout guidance |
image_guidance | string | Visual / hero image guidance |
text_content | object | Text to render (title, subtitle, bullets, etc.) |
See references/outline_schema.md for full details.
Rendering Workflow
Step 1 — Write style.md
Create style.md in the outline directory before writing outline.json. See references/style_guide.md.
Step 2 — Write outline.json
Define per-slide content, template_image, and optional reference_images (max 3).
Step 3 — Configure API
Copy .env.example to .env and set OPENAI_BASE_URL, OPENAI_API_KEY, and OPENAI_IMAGE_MODEL.
Step 4 — Render slide images
python scripts/render_from_outline.py \
--outline data/outlines/deck_01/outline.json \
--output-dir data/generated/deck_01 \
--format jpg \
--max-workers 4 \
--copy-outline
style.md is loaded from data/outlines/deck_01/style.md by default. Use --style PATH to override.
Output:
generated_deck/
├── style.md
├── outline.json
├── generation_state.json
├── 1.jpg
├── 2.jpg
├── contact_sheet_001.jpg
└── ...
Step 5 — Hash-based skip (batch mode)
On re-run, slides are skipped when slide hash unchanged, output image exists, and style_hash matches. Changing style.md re-renders all slides. Use --force to regenerate anyway.
Step 6 — Single-slide regeneration
python scripts/render_from_outline.py \
--outline data/outlines/deck_01.json \
--output-dir data/generated/deck_01 \
--slide 3 \
--force
Single-slide mode always regenerates the target page regardless of hash.
Contact Sheet Generation
After rendering, contact sheets are rebuilt by default:
- 12 slides per sheet, arranged 4 columns × 3 rows
- Named
contact_sheet_001.jpg, contact_sheet_002.jpg, ...
- Not included in the final PPT
Use contact sheets for quick deck-wide visual review before opening individual slides.
VLM Visual Review (Agent-Driven)
Codex and similar agents can inspect images directly. Perform this step after rendering and before PPT export.
- Quick pass — open
contact_sheet_001.jpg, contact_sheet_002.jpg, ... for overview.
- Detail pass — open individual
N.jpg for any slide that looks wrong.
- Cross-check — compare each image against
style.md and outline.json:
- Deck matches
style.md (colors, typography, mood, density)
text_content rendered correctly
layout respected
image_guidance followed
template_image layout/style preserved when provided
reference_images used appropriately (max 3)
- Per-slide verdict — pass / fail / minor issue.
- Fix loop for failed slides:
- Update
style.md and/or slide fields in outline.json
- Re-render:
--slide N --force
- Contact sheets rebuild automatically
- Re-review the fixed slide
- Do not export PPT until review passes or the user accepts remaining issues.
See references/vlm_review_checklist.md for the full checklist.
Review Summary Format
VLM review completed.
Deck: Example Deck
Total slides: 12
Passed: 10
Failed: 2
Failed slides:
- 3.jpg (slide_id s03): subtitle truncated; layout too crowded on right.
- 7.jpg (slide_id s07): chart area empty; image_guidance not followed.
Action taken:
- Updated outline for slides 3 and 7.
- Re-rendered slides 3 and 7 with --force.
- Re-review passed.
PPT Export Workflow
After visual review:
python scripts/images_to_ppt.py \
--image-dir data/generated/deck_01 \
--output data/generated/deck_01/output.pptx
Only numbered page images (1.jpg, 2.jpg, ...) are included. Contact sheets and metadata files are ignored.
Image Generation Backend
Current backend: gpt-image-2 via OpenAI-compatible endpoint.
- Configuration from
.env only — never hardcode API keys
style.md text is injected into every prompt
template_image is the slide template reference; reference_images (max 3) are supplementary
- Uses
images.edit when references exist, images.generate otherwise
Prohibited Actions
- Do not invent outline fields outside the fixed schema.
- Do not hardcode API keys in code or docs.
- Do not overwrite unchanged slides unnecessarily (respect hash skip in batch mode).
- Do not include contact sheets in the final PPT.
- Do not use non-numbered slide images as PPT pages.
- Do not add VLM API calls to Python scripts.
- Do not auto-modify
outline.json inside render scripts.
Final Render Summary Format
Render completed.
Output directory: data/generated/deck_01
Rendered: 8
Skipped: 4
Failed: 0
Contact sheets: 1
Next step:
Review contact sheets and individual slide images (VLM visual review).
Fix failed slides in outline.json or style.md and re-render with --slide N --force.
Then run images_to_ppt.py to combine numbered page images into a .pptx file.