SuperAPI AI Directory

gpt-image2-ppt

Office & productivity

View repository

Updated 10-16 12:38

About this skill

gpt-image2-ppt -- Generate PPT with gpt-image-2

Feed a markdown outline (or slides_plan.json) + a visual style directly to OpenAI's official Images API (gpt-image-2), generate images page by page, and finally package them into a 16:9 .pptx.

Available Styles

Style ID One-line positioning Use cases
gradient-glass Apple Vision OS / Spatial Glass AI product launches, tech sharing, creative proposals
clean-tech-blue Stripe / Linear-grade blue and white Funding pitches, business plans, corporate strategy
vector-illustration Retro vector illustration + black outlines Education and training, brand stories, community sharing
editorial-mono Kinfolk / Monocle editorial design Brand launches, cultural interviews, book sharing
dark-aurora Linear / Vercel dark neon AI products, developer tools, tech sharing
risograph Riso dual-color printing + halftone texture Creative studios, cultural and creative brands, independent zines
japanese-wabi MUJI / Kenya Hara-style wabi-sabi Tea ceremony, lifestyle, luxury goods, cultural lectures
swiss-grid Bauhaus / Vignelli International Style grid Academic reports, museum exhibitions, serious presentations
hand-sketch Sketchnote / whiteboard hand-drawn Workshops, product brainstorming, training
y2k-chrome Y2K millennium liquid metal + butterfly stickers Streetwear, entertainment, brand collaborations, Gen Z marketing
abstract-art-showcase Black-and-white minimalism, art exhibition feel, oversized typography juxtaposed with abstract imagery Art curation, portfolios, brand tone display
coal-industry-business-company-profile Industrial brown and black, heavy headlines, structural lines, and hard-edged icons Energy, manufacturing, heavy-asset company introductions
college-candy-aesthetics-infographics Candy colors, campus feel, rounded infographics, and light decorations Education, campus events, lightweight data popularization
creative-agency Creative agency temperament, strong visual collage, distinctive layout rhythm Agency proposals, brand plans, creative presentations
culinary-innovation Culinary innovation feel, food photography, warm color blocks, and magazine-style typography Food and beverage brands, food innovation, menu/new product launches
data-science-consulting Data consulting blue-gray, modular layout, charts, and tech-flavored information hierarchy Data analysis, AI consulting, enterprise digitalization
mindfulness-in-the-classroom-breathing-techniques Soft mental health color palette, negative space, rounded blocks, and a quiet illustration feel Mental health, classroom activities, breathing training courses
mind-maps-workshop-professional Professional workshop style, mind map nodes, clear process structure Training workshops, methodologies, team co-creation
meeting-agenda Meeting agenda feel, clean grid, strong information grouping, and business headlines Regular meetings, project syncs, management reports
investment-company-business-plan Investment institution quality, dark-light contrast, steady business layout Investment plans, fund introductions, business plans
indigenous-cultures Cultural patterns, natural colors, handmade texture, and narrative composition Cultural courses, historical themes, public welfare education
health-disparities-and-social-determinants-of-health-doctor-of-philosophy-phd-in-health-behavior-and-health-education Public health academic style, rational grid, soft medical colors and paper-like hierarchy Medical thesis defense, public health reports, education research
geometric-duotone-thesis Two-color geometry, thesis defense feel, angled shapes and strong titles Academic defense, research reports, chapter-based content
geometric-clinical-case Geometric medical style, calm color palette, case cards and clear columns Clinical cases, medical training, diagnosis and treatment reports
geometric-business Business geometric blocks, steady blue-green tones, concise chart language Business plans, team reports, product strategy
formal-lavender-portfolio Light purple formality, portfolio whitespace, elegant thin lines and soft layouts Personal portfolios, design resumes, professional showcases
flowery Floral decorations, soft color blocks, romantic yet orderly typography Lifestyle, women's brands, event introductions
first-impressions First-impression theme, strong cover visuals, dramatic relationship between person/title Interview training, personal branding, communication courses
final-year-project-thesis-defense Graduation project defense, academic grid, clear chapters and data pages Graduation defense, project completion, research showcases
fashion-business-consulting-toolkit-aesthetic Fashion consulting feel, high-end collage, magazine typography and neutral colors Fashion business, brand consulting, trend reports
economic-impact-of-coronavirus Economic impact report style, serious infographics, calm colors and data storytelling Macroeconomics, policy analysis, risk reports
eco-green-business-plan Sage green, natural material photography, eco-friendly business and minimalist split screens Sustainable business, eco-friendly brands, healthy lifestyle

All available styles are uniformly placed under styles/ and grouped by source, used in exactly the same way:initial/ contains the initial 10 sets,featured/ contains 22 curated sets,xiamulingzi/ contains 233 sets provided by designer @夏目玲子. For the directory index see styles/README.md; for curated style cover showcases see docs/distilled-styles.md.

Style selection principle: first choose the closest set in styles/ based on the content scenario. For technical topics, prioritize dark-aurora / gradient-glass / data-science-consulting; for business topics, prioritize clean-tech-blue / editorial-mono / eco-green-business-plan / investment-company-business-plan; for culture and lifestyle topics, prioritize japanese-wabi / vector-illustration / culinary-innovation / flowery; for academic topics, prioritize swiss-grid / geometric-duotone-thesis / final-year-project-thesis-defense; for workshops and training, prioritize hand-sketch / mind-maps-workshop-professional / mindfulness-in-the-classroom-breathing-techniques.

Scenario recipes (optional starter templates)

examples/ is not a new skill, nor is it a required runtime input; it is the scenario starter template library for the current skill, used to help the agent write the first version of slides_plan.mdfaster when the user only gives a vague request.

Trigger rules:

  • When the user has already provided a complete outline / complete slides_plan.md / complete slides_plan.json , do not apply a recipe; directly follow the user's content through the generation process.
  • When the user only says something like "make a product launch PPT / fundraising pitch / weekly report / courseware / thesis defense / book sharing" and other common scenarios, and has not given a clear page structure, first check examples/ Is there a matching recipe.
  • The recipe serves only as a structural reference: read examples/<id>/recipe.md to understand the scenario, recommended styles, and considerations, then refer to examples/<id>/slides_plan.md 's page-order structure and rewrite it with the user's own topic and content.
  • Do not treat the fictional products, companies, projects, or data in the examples as the user's finished work; they must be replaced with information provided by the user, or clearly marked as placeholder content and await user confirmation.
  • If the user provides real images, logos, screenshots, paper figures, or product UI, still handle them according to the "external real image insertion" rules; the recipe is only responsible for content structure and does not replace the material fidelity process.

Currently built-in recipes:

User scenario recipe directory Recommended style
Product launch, new feature launch, AI product introduction examples/product-launch/ gradient-glass
Financing roadshow, business plan, investor report examples/investor-pitch/ clean-tech-blue
Project weekly report, monthly report, regular meeting sync examples/weekly-report/ meeting-agenda
Courseware, training, knowledge popularization examples/courseware/ vector-illustration
Thesis defense, graduation project defense, final project presentation examples/thesis-defense/ final-year-project-thesis-defense
Book sharing, cultural interview, viewpoint sharing examples/book-sharing/ editorial-mono

How to use:

  1. Determine whether the user's need matches a recipe.
  2. Read the corresponding recipe.md and slides_plan.md.
  3. Based on the user's topic, rewrite a new slides_plan.md, do not directly modify the recipe source file.
  4. Confirm with the user the page count, title of each page, and key content.
  5. After the user confirms, execute md_to_plan.py to convert to json, and continue with the specified style or template cloning process below.

Layout bank sidecar for built-in styles (the only runtime format)

Built-in styles use a dual-file structure of "MD for humans, JSON for machines":

styles/<collection>/<style-id>.md            # 风格说明、设计令牌、基础提示词
styles/<collection>/<style-id>.layouts.json  # 必需;每页 layout bank,供自动分配页面形态

generate_ppt.py will use the .layouts.json of the same name as the RuntimeProfile without a reference image: assign different layouts via assign_layouts() , write visual_signature / content_capacity / best_for / avoid_for / variation_tags into the prompt, and write the condensed information of the matched layout into metadata.json.

Currently all styles/**/*.md must be paired with a .layouts.jsonof the same directory and name. Old styles that only have Markdown and lack a sidecar will directly report an error before image generation, and will no longer silently use the old Prompt; first migrate them to the paired format. In the future, when distilling public templates or adding built-in styles, a JSON sidecar must also be produced; do not compress multi-page layouts into only a "layout system" text paragraph in a single MD.

Unified RuntimeProfile execution core

Strict template cloning and structured style sidecars are both first compiled into the same RuntimeProfile, then uniformly processed through assign_layouts(), page Profile attachment, prompt compilation, and metadata recording. The entry adapter only retains the necessary differences:

  • template-clone: comes from --template-profile or template vision analysis; layout can carry reference_image, only --template-strict is actually passed into image generation.
  • distilled-style: comes from <style>.md + <style>.layouts.json; uses content routing and multiple layouts, and does not depend on the original template images.

RuntimeProfile uniformly records source_kind, fixed prompt_strategy=layout-fields、layouts and capabilities(routing / evidence / reference / portability). The priority is fixed as: valid template Profile > style RuntimeProfile; when the template analysis has no layouts, it must truly fall back to the structured style, rather than only printing a hint. The runtime no longer includes legacy-freeform or the synthetic layout branch.

Template clone mode

Give the skill a .pptx template directly, and all subsequent pages will imitate this template.

# 一行:自动渲染 + 模板分析 + 出图。需本机有可用 PPTX 渲染后端
python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --template-pptx ./company-template.pptx \
  --template-strict

--template-strict means that for each page, the corresponding template page is fed to gpt-image-2 as an image reference, giving the highest fidelity.

Template rendering: no need to operate PowerPoint on this machine

The skill includes render_template.py, which automatically renders the .pptx into one PNG per page, saved to <cwd>/template_renders/<stem>/page-NN.png.

Agent pre-check (mandatory when cloning a template)

Before running any --template-pptx command, you must first check whether this machine has an available PPTX rendering backend.

How to check:

  • Preferred: run python3 scripts/render_template.py --checkin the skill directory. It verifies whether the backend is actually executable, rather than only checking whether the path exists.
  • macOS: first check /Applications/Keynote.app and whether AppleScript is executable; otherwise check libreoffice --version || soffice --version
  • Windows: first check whether the local PowerPoint COM can start; otherwise check libreoffice --version / soffice --version
  • Linux / compatibility layers: check libreoffice --version || soffice --version, do not rely only on which

Note: HarmonyOS / Termux / container / special architecture environments may look like Linux, but you cannot assume that the Linux aarch64 LibreOffice binary is runnable; you must rely on the actual execution results of render_template.py --check or soffice --version . Do not treat aspose-slides as the default fallback; it has no installable wheel in many mobile/special Python environments.

If no available backend exists, first tell the user that template rendering requires installing an executable LibreOffice, or have the user manually export each template page as page-01.png、page-02.png on desktop and pass it in via --template-images . Optional installation commands:

Platform Installation command
Windows winget install LibreOffice.LibreOffice
macOS brew install --cask libreoffice
Linux (Debian/Ubuntu) sudo apt-get install -y libreoffice
Linux (Fedora/RHEL) sudo dnf install -y libreoffice
Linux (Arch) sudo pacman -S --noconfirm libreoffice-fresh

After installation, check again and confirm that an available rendering backend exists before continuing the subsequent process.

Note: On Windows, winget is built into Win10/11 and will pop up a UAC confirmation dialog, which requires the user to click confirm; on macOS, brew requires installing Homebrew first.

render_template.py 's rendering backend is automatically selected by priority:

  1. Windows: PowerPoint COM (preferred when Office is installed locally, directly outputs PNG and skips the PDF step) > LibreOffice
  2. macOS: Keynote AppleScript (preferred when Keynote is installed locally, directly outputs PNG) > LibreOffice
  3. Linux / compatibility layers: a LibreOffice / soffice command confirmed to be runnable via --version detection
  4. PDF -> PNG goes through pymupdf(already in requirements); if not installed, use pdf2image + poppler

Run generate_ppt.py --template-pptx ... when omitting --template-images will automatically trigger one render; you can also manually run it once first:

python3 scripts/render_template.py company-template.pptx
# -> <cwd>/template_renders/company_template/page-01.png ... page-NN.png

Two-layer cache for template mimicking

Material Path Purpose
PNG for each template page <cwd>/template_renders/<stem>/page-NN.png Long-term reuse of one render from the local rendering backend
Template style analysis <cwd>/template_cache/<sha256>.json or hand-written template_profile.json Generated by the multimodal agent itself by looking at the images; only text-only agents need an external vision setup
Generated output <cwd>/outputs/<timestamp>/ A new directory for every new run

All three live under the caller's cwd and naturally rise and fall together with the project; it is recommended to add template_renders/、template_cache/、outputs/ to the project's .gitignore.

Template image analysis (let the agent decide for itself whether VISION_*is needed):

  • The current code agent is itself a multimodal model (for example Claude Code's multimodal Claude, Codex's multimodal GPT): no additional VISION_*configuration is needed. The agent directly reads template_renders/<stem>/page-*.png, generates template_analyzer.py , then passes it to TemplateProfile structure of template_profile.jsonaccording to the --template-profile template_profile.json . If it needs to work with generate_ppt.pyusing --template-strict, each layout must include reference_image(the absolute path or accessible path of the template PNG).
  • The current code agent is a text-only model (for example, connected only to a DeepSeek text model): it cannot view template screenshots and needs additional VISION_BASE_URL / VISION_API_KEY / VISION_MODEL_NAMEconfiguration so that template_analyzer.py calls a separate OpenAI-compatible multimodal endpoint to do template analysis.

vision analysis and image generation are always decoupled via gpt-image-2 —switching the vision provider does not affect the image output path.

Installation

git clone git@github.com:JuneYaooo/gpt-image2-ppt-skills.git
cd gpt-image2-ppt-skills
bash install_as_skill.sh --target claude   # Claude Code
# 或
bash install_as_skill.sh --target codex    # Codex
# API 直连所需密钥优先通过 agent 配置 / 系统环境变量注入

Environment variable injection (for direct API connection)

Do not write this skill's keys into .envin the caller's business project root directory, and do not read the generic .envin the user's project just to generate images. Environment variables should be injected in the standard way for the agent framework:

  • Generic / CI / server: inject via system environment variables, Docker Compose environment / env_file, Kubernetes Secret, CI Secret, etc.
  • Claude Code: inject environment variables via the user-level ~/.claude/settings.json or project-level .claude/settings.local.json ; command-line environment variables have the highest priority.
  • OpenClaw / custom Agent: use apiKey / env reference in the framework configuration to reference system environment variables, avoiding writing keys in plaintext into the project configuration.
  • Local standalone CLI fallback: you can set GPT_IMAGE2_PPT_ENV=/path/to/private.env, or use .envunder the skill installation directory; this is only a fallback method, not the business project .env.

A direct API connection requires these variables:

OPENAI_BASE_URL=https://api.openai.com    # 或任意 OpenAI 兼容中转站
OPENAI_API_KEY=sk-...
GPT_IMAGE_MODEL_NAME=gpt-image-2
GPT_IMAGE_QUALITY=high                     # low / medium / high / auto

# 可选:模板克隆模式的 vision 分析 backend。
# 多模态 agent / 原生 Codex 可自己看图生成 --template-profile,不需要下面这组。
# 只有纯文本 agent(如 DeepSeek 文本模型)才需要外挂下面这组。
# 不内置默认 endpoint,请填你自己信任的服务,否则就别填。
# VISION_BASE_URL=https://your-openai-compatible-relay.example.com/v1
# VISION_API_KEY=sk-...
# VISION_MODEL_NAME=gemini-3.1-pro-preview   # 或 gpt-4o / claude-3.5-sonnet 等任意多模态 SKU

The configuration priority is fixed as: current process environment variables > platform-injected gpt-image2-ppt_* variables > GPT_IMAGE2_PPT_ENV / under the skill directory .env;JULING_GPT_IMAGE2_* Only used as a compatible fallback when there is no corresponding OPENAI_* configuration; it will not override explicit configuration.

Security note: the script only reads the current process environment, platform-injected gpt-image2-ppt_* variables, explicit GPT_IMAGE2_PPT_ENV, and the .env fallback under the skill installation directory. The script does not recursively read .envfrom the caller's project directory, to avoid accidentally consuming business project secrets.python3 scripts/render_template.py --check will perform a minimal real conversion to verify the re-rendering backend.

If you are the Codex agent (native image_generation for image output -- recommended)

If you yourself are Codex (the agent running this skill is Codex CLI / Codex TUI), and the current environment provides the image_generation tool and a ChatGPT login state, then do not use generate_ppt.py or --backend codex to handle image output; directly use the native tool to generate images, and at the end just reuse this repository's md conversion / PPTX packaging logic.

Key boundary: the Python script runs in a subprocess and cannot access the native tool in the current agent session.generate_ppt.py --backend codex can only start another codex exec subprocess to have another Codex generate images; it is not "reusing the current Codex's image_generation tool". Therefore, when the current agent can already generate images natively, the image generation action must be performed by the agent itself, not delegated to generate_ppt.py.

How to determine

You can access the image_generation tool, and you can generate images without manually configuring OPENAI_API_KEY -- if these two conditions are met, take the native path. If the current Codex session does not have this tool, handle it as an ordinary agent: go through the API direct connection, the--backend codex fallback backend, or have the user fill in the environment.

Image generation flow (Codex native path)

1. Prepare slides data

If there is no slides_plan.jsonyet, first write slides_plan.md → python3 scripts/md_to_plan.py ... to json according to steps 2-3 of "Generation flow" below.

2. Prepare prompts with the unified runtime

Do not manually replicate generate_prompt(). Run --prepare-onlyso that the API direct connection and the Codex native path share the same RuntimeProfile, layout routing, and prompt compiler:

python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --style styles/<collection>/<id>.md \
  --prepare-only \
  --output outputs/<timestamp>

This command does not call the image API or package a PPTX; it generates prompts.json, per-page prompt text, and metadata.json. For a single-page smoke test, also pass --slides 1.

3. Read the compilation result for each page

From outputs/<timestamp>/prompts.json , read each page's prompt、reference_image、asset_reference_image and layout_id. Do not reassemble a Prompt based on the Markdown, otherwise it will bypass the structured layout bank.

4. Call the image_generation tool to generate images

For each page, call your image_generation tool:

  • prompt: prompts.json the complete prompt already compiled for that page
  • output_format: png
  • If reference_image / asset_reference_imagewas recorded, pass it in the original order as the image reference
  • Save the returned image to outputs/<timestamp>/images/slide-NN.png(NN is the two-digit page number)

Concurrency is allowed (≤4 concurrent recommended, to avoid rate limiting).

5. Package the PPTX

If this deck has no external real image objects, you can use the simple full-page PNG packaging below. If any page has external_image / image_overlay / external_image_placeholder and it points to a real image, you cannot use this simple packaging snippet, otherwise the real image will be merged into the full-page background PNG and the user will not be able to select and drag it separately in PowerPoint. In that case you must use generate_ppt.py 's standard packaging logic, or call generate_pptx(..., metadata=metadata)in an existing session, so that the real image is overlaid on the background as an independent picture object.

python3 -c "
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
import os, glob
for p in sorted(glob.glob('outputs/<timestamp>/images/slide-*.png')):
    slide = prs.slides.add_slide(blank)
    slide.shapes.add_picture(p, 0, 0, width=prs.slide_width, height=prs.slide_height)
prs.save('outputs/<timestamp>/<title>.pptx')
print('done')
"

The correct PPTX structure for a page with an external real image should be:

  • Layer 1:images/slide-XX.png as the full-page background image (including the model-generated background and text).
  • Layer 2:source as an independent PPT picture object, placed according to slide_spec coordinates on the background, selectable, draggable, and resizable in PowerPoint.

Template cloning mode (Codex native path)

You are yourself a multimodal agent -- directly Read extract the visual style from each page PNG of the template, write it into template_profile.json(for the schema see template_analyzer.py in TemplateProfile, write reference_imagefor each layout), then use --template-profile template_profile.json --template-strict --prepare-only to compile each page's Prompt and reference; do not manually choose another Prompt assembly logic.

No need to configure VISION_* -- you are the vision.

Difference from the "--backend codex" below

Native path (this section) --backend codex
Applicable scenario You are the Codex agent You are Claude Code / another agent, borrowing the local codex CLI
Invocation method Directly call the image_generation tool spawn codex exec --full-auto subprocess
Image generation layers 1 layer 2 layers (agent → python → codex exec)
Speed A few seconds per image 30-60s per image
Reliability Precise tool parameters Natural language relay, occasional failures
Requires API Key No No

Optional: generate images via codex CLI (--backend codex, for non-Codex callers)

If you are a Codex agent, do not take this path -- use the "native path" in the previous section instead.

When you run this skill with Claude Code / OpenClaw / another agent, but the local machine has codex CLI installed and logged in (codex login), you can borrow its credentials to generate images, saving the need to configure OPENAI_API_KEY:

python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/initial/editorial-mono.md --backend codex

The default backend is still openai(direct API calls, fast, stable concurrency, 3-10s per page).--backend codex is an escape hatch, suitable for scenarios where "you only want to run 1-2 images to test the waters and don't want to configure a key".

Tradeoffs:

  • ✅ No need to configure in this skill OPENAI_API_KEY
  • ⚠️ Slow: each page has an extra agent loop layer, 30-60s+ per page, 10 pages may take 5-10 minutes
  • ⚠️ Billing unchanged: gpt-image-2 is billed per image, not included in the ChatGPT subscription; codex is just spending your quota on your behalf
  • ⚠️ Poor controllability: aspect_ratio / quality / reference_image rely on natural language instructions for codex to forward, occasional failures

Related envs (all optional):

CODEX_CMD="codex exec --full-auto"   # 覆盖 codex 调用方式(默认这串)
CODEX_IMAGE_MODEL=gpt-image-2        # 传给 codex 的目标模型
CODEX_TIMEOUT_SECS=900               # 单页超时
GPT_IMAGE_BACKEND=codex              # 不想每次敲 --backend 就设这个

The same applies to vision analysis for template cloning -- when the caller agent itself is multimodal (Claude Code / multimodal codex), it can directly Read Extract the style from the template PNG, without configuring VISION_*; only when the caller agent is a pure text model is an external vision provider needed.

Generation flow (specified style)

md first, then json: md is for humans to read, easy to diff / review / edit copy; json is derived from md, fed to generate_ppt.py, marked as generated, not hand-edited.

  1. The user provides an outline / existing slides_plan.json; if the user only gives a common scenario and theme, first choose one according to the "scenario recipes" above examples/<id>/ as the structural reference
  2. The Agent writes a new one according to the md spec below slides_plan.md, confirms the copy with the user:
    ---
    title: MediWise Health Suite 商业计划书
    ---
    
    ## 1. [cover] MediWise Health Suite
    副标题:家庭健康管理智能平台
    年份:2026
    
    ## 2. [content] 市场痛点:健康管理的两类割裂
    痛点一:高频无深度
    ...
    
    ## 6. [data] 效率对比:使用 MediWise 前后
    ...
    
    • h2 format:## N. [page_type, layout=layout-05] 本页标题行
    • N. optional (auto-numbered by order of appearance);[page_type] optional (default content);layout= only needed in template cloning mode
    • page_type: cover / agenda / section / content / data / quote / closing / other
    • h2 title line → in json content first line; the body below → body
  3. After the user OKs it, convert to json:
    python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json
    
  4. Choose a style: from styles/initial/、styles/featured/ or styles/xiamulingzi/ , pick one, corresponding to styles/<collection>/<id>.md; if a recipe was used, prefer the recipe.md / in the frontmatter's recommended_style, when a visual preview is needed first look at docs/distilled-styles.md
  5. Construct slide_spec (Agent step): read styles/<collection>/<id>.md visual spec, for slides_plan.json construct each page's slide_spec(each element's type, content, position, style), write into each page's slide_spec field. Format see the "point and edit" section below
  6. Call the script:
    python3 scripts/generate_ppt.py --plan slides_plan.json --style styles/initial/editorial-mono.md
    
  7. Artifacts are in <cwd>/outputs/<timestamp>/:
    • images/slide-XX.png -- each page's PNG (16:9, 1536x864)
    • prompts.json -- the full prompt used for each page (for review / secondary fine-tuning)
    • metadata.json -- slide_spec version history (supports precise editing and rollback)
    • <title>.pptx -- 16:9 PPTX; by default the background and text are full-page images, via external_image Real images placed in will be overlaid as independent PPT image objects

Editable Mode (disabled by default)

Normal mode still prioritizes the full-page aesthetics of gpt-image-2, outputting backgrounds and text as full-page images. Only enable editable mode when the user explicitly requests "editable PPTX / text can be changed / elements can be split / images can be moved / native shapes"; do not enable it by default on your own based on content type.

Core Principle

Do not prohibit gpt-image-2 from generating titles, body text, numbers, tables, logos, or key charts in the initial visual draft. The model still first generates a complete finished page, to preserve the overall composition, materials, lighting effects, and the relationship between text and visuals; editable mode is a post-generation reconstruction step.

Effect Priority and Round Control

Editable mode takes final visual effect and object-level editable quality as its primary goals, and does not force completion in a single round; but it must distinguish low-cost inspection rounds from high-cost generation rounds:

  • Inspection rounds can be multiple: scene schema, font availability, text overflow, object out-of-bounds, image aspect ratio, black-and-white background edges, object movement, PPTX re-rendering, and manual visual inspection can all be repeated, and must not be skipped in pursuit of fewer rounds.
  • Generation rounds escalate level by level: first adjust deterministic parameters such as fonts, coordinates, cropping, rounded corners, and z-order; next use A1 original-pixel extraction and A2 occlusion completion; then only perform B AI separation/regeneration for failed complex assets; only when the overall composition, visual hierarchy, or style is clearly unacceptable may the entire page be regenerated.
  • Local problems only fix local areas: when one layer, one text box, or one slot fails, do not by default regenerate other content that has already passed inspection.
  • Keep the current best version each round: in quality-report.json record the problems of this round, the repair scope, the route used, and the result; stop when the new version brings no visible improvement, and do not let the layout drift randomly just to "try one more time."
  • Real assets still prioritize fidelity: logos, product UI, medical imaging, paper charts, financial data, and evidence screenshots must not be switched to AI redrawing just to reduce rounds.

Recommended order:

完整视觉稿 / 用户参考图
  -> 一次性 scene 规划与对象分层
  -> 原生对象重建 + A1/A2 素材处理
  -> 多轮低成本预检与回渲染
  -> 仅对失败范围做局部修复或 B 路由
  -> 只有结构性失败才重生整页
  -> 选择历史最佳版本交付

Pre-check for Re-rendering in Editable Mode (required)

An editable PPTX must be able to be re-rendered into images, for a multimodal agent to read page by page and for manual acceptance; the requirements are the same as template cloning mode. Before running any --editable command, you must first check whether this machine has an executable PPTX rendering backend:

python3 scripts/render_template.py --check
  • Windows: PowerPoint COM > LibreOffice
  • macOS: Keynote AppleScript > LibreOffice
  • Linux / compatibility layer: actually executable LibreOffice / soffice

You cannot check only whether file paths or installation packages exist; the actual results of --check, PowerPoint COM startup, Keynote AppleScript detection, or libreoffice --version must be used as the standard. HarmonyOS, Termux, containers, and special architectures likewise must not assume that LibreOffice can run.

If no backend is available, stop editable mode and inform the user to install PowerPoint, Keynote, or LibreOffice; you must not generate a -editable.pptx that has not undergone re-render inspection and claim success. The installation method is the same as the rendering backend description in "Template Cloning Mode" above.

generate_ppt.py --editable will run an equivalent precheck before starting generation; after the build completes, it automatically sends -editable.pptx back-rendered to <session>/editable_renders/page-XX.png. The agent must read these PNGs page by page and check for font substitution, line breaks, object misalignment, edges and visual differences. When a text-only agent cannot complete this step, it must explicitly require the user or another multimodal agent to inspect the images for acceptance; it must not treat the automated report as manual acceptance.

When the user explicitly requests editability, the agent must:

  1. First run python3 scripts/render_template.py --checkto confirm that the back-rendering backend is actually available;
  2. Normally complete slides_plan.md → slides_plan.json and the single-page visual smoke test;
  3. Save the full visual draft of each page as visual-master;
  4. Establish for each page slide-XX.scene.json, clean plate, independent assets and QC evidence;
  5. Invoke the explicit --editable mode;
  6. Read <session>/editable_renders/page-XX.png and manually inspect page by page; do not just look at the automated report.
python3 scripts/generate_ppt.py \
  --plan slides_plan.json \
  --style styles/initial/dark-aurora.md \
  --editable \
  --editable-scenes editable_scenes/
  • --editable is off by default; when not passed, the existing generation, editing, rollback and normal PPTX packaging behavior is unchanged.
  • --editable-scenes points to a directory containing slide-01.scene.json、slide-02.scene.json and other files.
  • When --editable-scenes is omitted, it will attempt <session>/editable_scenes/.
  • The CLI will reject an unavailable back-rendering environment before generation, and will automatically generate <session>/editable_renders/page-XX.pngafter the build.
  • When a scene is missing pages, assets are lost or the format is wrong, it must not silently degrade into full-page images and claim editability; it should preserve the normal PPTX and intermediate evidence, then fail explicitly.
  • On success, retain both <title>.pptx and <title>-editable.pptx.

Scene Elements

Each scene uses real pixel canvas coordinates, and at minimum declares slide_number、canvas、clean_plate and z_index -sorted elements. Supports:

type Purpose
native_text Titles, body text, dates, numbers, labels, badge text; outputs native PowerPoint text boxes
image_layer Photos, key visuals, illustrations, complex textures and objects that cannot reasonably be converted into shapes; outputs independent image layers
native_shape Rectangles, rounded rectangles, circles, five-pointed stars and lines; outputs native PowerPoint shapes
connector Straight connector lines and arrows for architecture diagrams and flowcharts

For paths in a scene, prefer writing relative paths relative to the scene JSON, to make it easy to move examples and sessions as a whole. For a complete example, see examples/editable-pptx/case05-summer-poster/slide-01.scene.json.

A1 → A2 → B routing for overlapping assets

  1. A1 direct original-pixel extraction (default): extract directly from the complete visual comp when the contour is complete, occlusion is minimal, and edges are clean. Multiple mutually overlapping assets are by default extracted as one connected combined layer, without forcibly splitting them into incomplete objects.
  2. A2 original pixels + occlusion completion: keep the visible original pixels, and complete the back of the object or the clean plate exposed after the object is moved away.
  3. B AI separation or regeneration: enabled only when A1/A2 results are unsatisfactory for fur, plush, semi-transparent, glass, white subjects, complex watercolor edges, or occlusion completion, or when the user explicitly requests design mode.

Do not skip A1 just because B is more convenient. Every escalation must be recorded in quality-report.json . In Case 05, the plush character, white ice cream, and watercolor clouds are mixed, and A1/A2 edges are unstable, so B is used to generate a combined asset on a monochrome key background, then background removal is done locally.

Clean plate and page types

  • Save visual-master.png, do not overwrite the original finished page.
  • Text and standalone image objects must be removed from clean-plate.png ; after moving an object, a second copy of the same object must not be exposed.
  • API edit may only composite within an explicit repair mask, and pixels outside the mask must be locked.
  • Simple gradients, neon light bands, and solid-color cards may use deterministic interpolation; ghost text, color blocks, dark circles, or obvious patches must be rejected.
  • For data pages, build titles, labels, and numbers separately as native_text, do not treat the entire data card as a non-editable screenshot.
  • Architecture diagrams, flowcharts, and rule infographics should preferably be rebuilt as native_shape + native_text + connector, do not merely overlay text on a screenshot.

Delivery threshold

Each page must retain at least:

editable/slide-XX/
├── visual-master.png
├── clean-plate.png
├── repair-mask.png          # 使用局部修复时
├── layers/*.png
├── edge-check-white.png     # 有透明图片层时
├── edge-check-black.png
└── quality-report.json

Before delivery, must check: scene schema, PPTX object names and counts, pixel changes outside masks, black/white background edges, text modifications, image moves,editable_renders/page-XX.png , and the human visual effect. The initial report status is rendered_pending_manual_review; it can be judged as passing only after a multimodal agent or the user visually inspects it page by page.

Report to the user the plain PPTX,-editable.pptx, the output directory, and the editable_renders/ path, and explain which visuals still exist as standalone image layers.

Inserting real external images (recommended precise workflow)

Default rule: when the user provides a real image, prioritize pasting it faithfully as the original image; do not let gpt-image-2 redraw this image. Use slide_spec to declare external image slots:

This workflow is enabled only when an element declares type: "external_image" / image_overlay / external_image_placeholder and source can resolve to a real local image file. Ordinary generation without a real image source, template cloning, pure placeholder layouts, and old free-style generation are unaffected.

If the user explicitly says "I care more about the visual blending effect, it doesn't have to paste the original image / redrawing is fine / image-to-image is fine", you may use reference image mode: input the image to the model as a generation reference, rather than as a final standalone pasted image. In this case the layout is usually more blended, but pixel-level fidelity is not guaranteed, and there will be no individually selectable original image object in the PPT.

Reference image mode may use type: "image_reference", or in external_image explicitly write on render_mode: "reference" / preserve_original: false:

{
  "elements": {
    "mood_reference": {
      "type": "image_reference",
      "source": "/absolute/path/to/photo.png",
      "purpose": "只作为视觉参考,允许模型融合重绘,不作为独立 PPT 图片对象后贴"
    }
  }
}

Do not use reference-image redrawing for high-precision assets: medical imaging, pathology images, diagnostic evidence, experimental/engineering readings, financial tables, paper charts, legal evidence screenshots, exact product UI screenshots, etc. should all by default go through external_image to paste with fidelity, and prompt the user to verify before delivery.

{
  "elements": {
    "hero_photo": {
      "type": "external_image",
      "source": "/absolute/path/to/photo.png",
      "layout_intent": "auto",
      "tailor_to_asset": true,
      "slot_strategy": "fit-within",
      "fit": "contain",
      "slot": {
        "padding": 0.012,
        "bleed": 0,
        "fill": "#F7F7F5",
        "mask_placeholder": false,
        "sanitize_background": false,
        "draw_frame": false,
        "outline_width": 0,
        "skeleton_canvas_fill": "transparent",
        "skeleton_fill": "transparent",
        "skeleton_shape": "corners",
        "skeleton_outline": "#000000",
        "skeleton_outline_width": 2,
        "skeleton_ticks": false
      }
    }
  }
}

During generation, the script automatically does four things:

  1. Plan slots first, then generate the skeleton. The script will preferentially read the external_image_slotsin the template profile, or infer candidate regions such as "image left, text right / image right, text left / chart at bottom / central main visual" from the template summary; then combine the page's text volume, title length, number of real images, real image aspect ratios, and asset categories (photo / chart / document / architecture diagram, etc.) to score and select positions, and first produce position / computed_bbox / auto_layout_reason / layout_planning_profile. The skeleton only draws this planning result for the model to see; it is not responsible for improvising positions on the fly.
  2. Read the source real image dimensions. If tailor_to_asset: true or slot_strategy: "fit-within"is declared, the script will treat position as an "available area" and calculate computed_bboxwithin it according to the real image aspect ratio; this bbox will be used simultaneously in the prompt, the skeleton reference image, and the final PPTX image placement. This is not resizing after generation, but tailoring before gpt-image-2 image generation.
  3. In outputs/<timestamp>/references/slide-XX-asset-skeleton.png , generate a transparent-canvas corner-marker skeleton reference image, mark out the final_image_rect_px that the final real image will cover, and pass it as a reference image to gpt-image-2. This is only used to guide the model not to place key information in that area; only call gpt-image-2once per page, not generate one first and then regenerate using the skeleton.
  4. When packaging the PPTX, use python-pptx with the same bbox to paste the real image pointed to by source as an independent image object. By default, do not draw extra frames or lay down masks; also do not by default clean up gpt-image-2 generated images. Real images should not be composited into images/slide-XX.png, otherwise the user cannot drag them separately in the PPT.

If after generation you find that the real image slot presses into a large area of text or graphics, prioritize the following two methods:

  1. Fine-tune the slot before pre-generation: change slide_spec.elements.<id>.position(or anchor / padding), let the real asset move to a cleaner area, then regenerate that page. As long as the slot position changes, the background must be regenerated; do not just move the final image in the PPTX, otherwise the background content may still press on the new position.
  2. Secondary layout repair: when the overall style of the first page is already satisfactory and only local content presses into the slot, use --edit SLIDE --external-slot-repair. This mode will pass both the current page and the new asset-skeleton as reference images, requiring the model to keep the original style but rearrange text/graphics so that the slot is left empty.

Example: move the real image area to the right and rearrange the current page:

python3 scripts/generate_ppt.py \
  --session outputs/20260529_120000 \
  --edit 3 \
  --external-slot-repair \
  --element-updates '{"hero_photo":{"position":[0.60,0.16,0.32,0.60],"anchor":"center"}}'

At the same time, every page containing an external real image will be included in outputs/<timestamp>/external_image_trace/slide-XX/ Record the full intermediate pipeline:

  • step1-real-on-blank.png: paste the real images onto a blank page at their final coordinates and sizes first, to confirm "the real image should ultimately appear here".
  • step2-reference-outline-blank.png: remove the real images and keep only the corner-marker positioning reference image for gpt-image-2 ; by default a transparent canvas, with no white background laid down. The positioning area uses final_image_rect_px, i.e. the pixel rectangle that the final real image will actually cover, not the outer slot. This image is also copied to references/slide-XX-asset-skeleton.png and used as an image reference input.
  • step3-generated-background.png:gpt-image-2 the background image generated from the step2 reference, with the real images not yet pasted in.
  • step3-image2-raw.png / step3-sanitized-background.png: appears only when sanitize_background: true is explicitly set, used as a fallback to clean up placeholder blocks the model has already drawn; disabled by default.
  • step4-final-overlay-preview.png: a preview image with the real images pasted back onto step3 at the same coordinates as step1, used to compare against the final PPTX result.
  • manifest.json: record each external image's source、slot_bbox_norm、inner_rect_norm、reference_rect_px、final_image_rect_px, padding, bleed, asset dimensions and aspect ratio.

Key principles:

  • The reference skeleton is responsible for "telling the model where not to put key information", not for asking the model to draw white empty boxes.
  • When template cloning / --template-strict and external real-image slots exist at the same time, the generation stage passes in two references at once: the template page for learning the style, andasset-skeleton for marking the area to be covered by the pasted image; do not choose only one, otherwise the model looking only at the template page will not know the final image position.
  • External real-image pages cannot simply stack a "template photo/image area prompt" and a "leave blank prompt". Before constructing the prompt, conflicts must be resolved: the template only provides color scheme, fonts, grid, rhythm and decorative language; the template's photo areas, image frames, full-bleed images, cropped images, etc. are all regarded as already replaced by the real-image slots.
  • When constructing slide_spec ,position cannot be chosen arbitrarily, and must not default to a fixed right side. In template cloning mode, preferably let the template profile provide external_image_slots, or infer candidate image areas from the template layout summary, then score them based on this page's text volume, number of real images, real image aspect ratios and page type: when there is a lot of text, prioritize securing the title/body reading area; when there are many images or extreme aspect ratios, prioritize using the template's original column/split or top-bottom layout; when they cannot coexist, reduce decoration and fake visual subjects rather than letting the real images squeeze the content.
  • It is recommended to write layout_intent: "auto"first rather than hand-writing position. The script will read the template candidate slots, real image dimensions, text volume, image count and aspect ratios to choose the position and write it to position / computed_bbox / auto_layout_reason; only when automatic planning is unsatisfactory should a manual position override be used.
  • When using layout_intent: "auto" ,slide_spec.layout Try to clearly describe the image area direction and structure, for example "text on left, image on right / right image / right landscape photo / bottom image / portrait rail". Automatic planning will prioritize inferring the real image area from these directional descriptions and template candidate slots; when the description is too vague, text-heavy pages may degrade to conservative small image slots.
  • position By default can serve as an "allowed area";computed_bbox is the final real image slot calculated by the script.
  • If you want to fully fix the coordinates, do not tailor them; directly write bbox, or set slot_strategy: "exact" / tailor_to_asset: false.
  • Final precision is guaranteed by the python-pptx coordinates, not by the model drawing boxes.
  • skeleton_outline_width only controls the skeleton reference image shown to the model;outline_width / draw_frame controls whether a visible box appears in the final PPT.
  • Do not write normalized coordinates in the prompt; position is controlled by the transparent corner-marker reference image, avoiding the model misinterpreting numeric coordinates and also avoiding closed boxes being understood as real image frames.
  • skeleton_canvas_fill / skeleton_fill / skeleton_outline / skeleton_outline_width / skeleton_shape only affects the reference skeleton image. By default skeleton_canvas_fill: "transparent" and skeleton_shape: "corners", only at the final_image_rect_px four corners draw short corner markers, do not draw a closed rectangle, do not lay down a white background, to avoid the model interpreting the reference as a real image frame or white placeholder block. When the old behavior is needed, explicitly set skeleton_shape: "outline"。
  • sanitize_background / mask_placeholder is not the recommended path; they are only suitable for clearing extremely slight placeholder traces, not for solving the problem of text or graphics covering the slot over a large area. When content is covered, handle it as "fine-tune the slot and regenerate" or "secondary layout repair".
  • By default, do not draw an outer frame in the final output, do not insert any background-color rectangle, only paste the real image;mask_placeholder will be ignored, to avoid producing a draggable white background under the real image. Only when explicitly setting draw_frame: true and outline_width > 0 will an unfilled border be additionally drawn.
  • Recommended default:tailor_to_asset: true + slot_strategy: "fit-within" + fit: "contain" + a small amount of padding. This fully preserves the original image and makes the skeleton image reserved according to the asset aspect ratio from the start.
  • fit: "contain" preserves the full image;fit: "cover" center-crops the image to fill the slot.
  • If you want a "perfect fit" with no white edges, use fit: "cover"、padding: 0、outline_width: 0, and set a very small bleed(for example 0.0015-0.003) to make the image extend about 1-3px beyond the slot, offsetting rounding and anti-aliasing seams in PowerPoint / Quick Look rendering.
  • If you want to "reserve a little but not have strange gaps", do not rely on later contain to force it into a large frame with a mismatched aspect ratio; instead use fit-within to first calculate a slot with matching aspect ratio, then use a very small padding for design whitespace.
  • Before delivery, you must spot-check external_image_trace/slide-XX/manifest.json: focus on whether final_image_rect_px matches visual expectations, and whetherauto_layout_reason selected the correct left/right or top/bottom area. If a landscape image is calculated as a small thumbnail, a portrait image is too narrow, or the position covers content, first clarify the directional intent of slide_spec.layout , or explicitly set position, then regenerate that page's background and repackage the PPTX.

The overall schematic is saved at docs/external_image_overlay_logic.txt; when modifying the external real-image pipeline, first check against this diagram to confirm the order is still "template/page/asset profiling -> candidate slot scoring -> transparent skeleton -> background generation -> paste real images afterward -> quality check/limited repair".

Generation flow (template cloning)

  1. Obtain the template .pptx (user-provided / internal template library / downloaded from the web)

  2. (Optional) Render separately and manually select first----for large templates (>15 pages), it is recommended to first python3 scripts/render_template.py xxx.pptx, then from template_renders/<stem>/ pick 8-12 representative pages and copy them to template_renders/<stem>_curated/, for vision analysis. The more precise the page count, the more accurate the layout match.

  3. Generate slides_plan.md → convert to slides_plan.json (see steps 2-3 of the specified style flow). Each page slide_number / page_type (cover / agenda / section / content / data / quote / closing / other) / content; for precise alignment, add in the h2 layout=layout-NN(NN = template page N / the template page number you expect it to correspond to)

  4. Image generation smoke test. For API direct connection / non-Codex native path, run generate_ppt.py:

    python3 scripts/generate_ppt.py \
      --plan slides_plan.json \
      --template-pptx xxx.pptx \
      --template-images template_renders/xxx_curated \
      --template-strict --slides 1
    

    If the current agent is itself a multimodal model, you can also first look at the template PNGs and write out template_profile.json, then run it this way, without needing VISION_*:

    python3 scripts/generate_ppt.py \
      --plan slides_plan.json \
      --template-profile template_profile.json \
      --template-strict --slides 1
    

    First --slides 1 to smoke-test the cover; if the result is OK, then run the full batch.

    If the current agent is Codex with native image generation capability, do not use the above generate_ppt.py command to handle image generation; first generate / read template_profile.json, then follow the "Codex native path" to directly call the current session's image generation tool to output page 1 PNG, and after the user confirms, generate all pages and package them.

  5. Tell the user the artifact paths

Template page selection / reuse principles

Core principle: strive for 1 page : 1 layout----in the same deck, use a different template page as reference for each slide, and the audience will feel that every page is new content; if the same unique layout appears 2-3 times, the audience will subconsciously think "why is this page here again".

During vision analysis, each layout is tagged reuse_friendly:

For each layout, TemplateProfile, in addition to id / page_type / summary / json_schema / reference_image, also tries to save:

  • visual_signature: the most obvious visual differentiator of this page, e.g. "image on the right, text on the left", "numbered timeline", "three-card grid".
  • content_capacity: the information density it is suitable for carrying, to avoid cramming long text into a strongly visual page.
  • best_for / avoid_for: content structures it is suitable or unsuitable for.
  • variation_tags: short English labels, used to help compare and stagger layout forms.

During generation, assign_layouts() is used to prioritize unused layouts; even if the plan does not hand-write slide_spec, the matched template layout will also be written into template_layout_profile as a simplified version, metadata.json, for subsequent editing, image slot planning, and review.

reuse_friendly typical layout cost of multiple uses
false(not reusable, (!) strong warning) Cover, 3 named character illustration pages, unique scene images (snow mountain / broadcast tower / retro radio), 5-step zigzag with a unique icon per step, novelty data central device Visual repetition is very obvious, the audience will be confused
true(reusable, but still recommend staggering, (i) weak hint) Plain text, card grid, generic list, section subheadings Not fatal, but it plainly wastes the other good layouts in the template

When building the plan, the Agent's execution strategy:

  1. Prioritize assigning the template's N different layouts to N slides (if N is not enough, look in the SKILL at the reuse_friendly=true parts and pick the ones that can be reused)
  2. If some page in the plan has a very similar content structure (for example multiple "5-step processes"), first try rewriting the content to express it with a different layout (use different process pages for 4 steps + 5 steps), instead of using the same zigzag twice
  3. After the smoke run, look at the Layout 复用检测 output: (!) must be changed, (i) change depending on the situation; just change the corresponding slide's layout_id in the plan
  4. After reading the profile JSON, choose the layout:cat <cwd>/template_cache/<sha256>.json | jq '.layouts[] | {id, page_type, reuse_friendly, visual_signature, content_capacity, summary}'; if it is a template_profile.jsongenerated by a multimodal agent itself, then read that file.

generate_ppt.py will automatically run a reuse check once before dispatching the task, print the warnings to the terminal, and not block execution.

Skill invocation conventions

When the user says "make a PPT" / "generate slides":

  1. First ask three things (do not start directly):
    • Content / number of pages / who is the audience?
    • Style preference? Based on styles/ and docs/distilled-styles.md scenario category mappings, recommend 1-2; or the user uploads their own .pptx template (go through --template-pptx, automatically rendered)
    • Whether a single-page test image is needed first to see the effect (for direct API use --slides 1; for the Codex native path, directly generate page 1 PNG)
  2. First write slides_plan.md to let the user confirm the copy (md is the source of truth, human-review friendly)
  3. Convert to slides_plan.json:python3 scripts/md_to_plan.py slides_plan.md -o slides_plan.json(json is marked as generated, do not hand-edit; to change the copy, go back to the md, change it, then convert)
  4. Build slide_spec (Agent step): read styles/<collection>/<id>.md to understand the visual conventions, then for slides_plan.json build slide_specfor each page, and write it into each page's slide_spec field (format see the "change exactly where you point" section). This step makes later modifications precise down to each element
  5. Image-generation smoke test:
    • Direct API / non-Codex native path: run generate_ppt.py --slides 1 to produce a cover smoke test, and if the effect is OK then run the full batch
    • If the current agent is Codex with native image-generation capability: follow the "Codex native path" above and directly call the current session's image_generation tool to generate outputs/<timestamp>/images/slide-01.png; do not use generate_ppt.py --backend codex
  6. Tell the user the artifact paths, the artifacts are in outputs/<timestamp>/,<title>.pptx and can be opened directly

User-facing expression conventions

When reporting to ordinary users, by default do not explain slide_spec、metadata.json、element-updates, JSON Schema, pytest commands, and other internal implementation, unless the user explicitly asks about technical details.

What users care about most is:

  1. Whether the resulting PPT looks good and can be used directly.
  2. Which scenarios are stable and which scenarios require manual acceptance.
  3. Whether only the specified pages / specified content were changed.
  4. Where the final output directory and PPTX file are.
  5. What the current shortcomings are, for example the background/text is still a full-page image, and small numbers/text need to be reviewed; real logos/product images require provided assets before they can be placed as independent image objects.

If you need to introduce the editing capabilities, prioritize citing docs/edit_guide.md scenario tiers, before / after cases, and current shortcomings; do not put the implementation chain in front of the user.

When the user says "change XX on page X":

  1. Find the session: first use --list-sessions to list existing sessions, and determine which one is to be edited
  2. Read metadata.json: check the slide_spec of the corresponding slide, and find the target element
  3. Confirm the modification content: tell the user the current content and ask for the new content
  4. Construct the edit instruction: use --element-updates to specify the element to change and the new content
  5. Run --edit:python3 scripts/generate_ppt.py --edit X --session <ts> --element-updates '{"elem_id": {"content": "new"}}'
  6. Report the result: a new version has been generated, and the PPTX has been updated

Generate only some pages

python3 scripts/generate_ppt.py --plan my_plan.json --style styles/initial/dark-aurora.md --slides 1,3,5

When pages that have already been run have a PNG with the same name, they are automatically skipped, making page-by-page iteration convenient.

"Edit exactly what you point to" PPT editing workflow

This section only keeps the information needed for the agent to execute; for the complete structure, version chain, and data security details, see docs/workflow.md. When explaining the capabilities to ordinary users, see docs/edit_guide.md.

Structural requirements during generation

When generating a new PPT, the agent should write a concise slide_specfor each page, to facilitate subsequent precise modifications by title, subtitle, card, metric, and other elements. Minimum requirements:

  • layout: a one-sentence description of the layout
  • elements: a semantic element dictionary
  • Common element IDs:title、subtitle、card_1、card_2、metric_1、date_line、footer
  • For element fields, prefer writing type、content or heading/body、position、style、color

Do not write a very long spec just for the sake of completeness; as long as it enables subsequent locating and editing, that is enough.

Modify an existing slide

  1. Use --list-sessions to find the target session.
  2. Read the target session's metadata.json, and locate the page number and element ID.
  3. If the user has not given the new content, first ask, "The current content is X; what should it be changed to?"
  4. Use --element-updates to describe the modification; when stronger constraints are needed, add --edit-instruction, clearly stating "do not change other content, layout, or color scheme."
  5. After running --edit , check the target page image; the rebuilt PPTX will be updated in sync.

Common commands:

python3 scripts/generate_ppt.py \
  --edit 3 \
  --session 20240523_143052 \
  --element-updates '{"subtitle": {"content": "医疗数据碎片化"}}' \
  --edit-instruction "将副标题从'健康管理的两类割裂'改为'医疗数据碎片化'"

python3 scripts/generate_ppt.py \
  --edit 3 \
  --session 20240523_143052 \
  --edit-prompt "在参考图基础上,只修改标题下方副标题的文字,从'健康管理的两类割裂'改为'医疗数据碎片化',保持位置、字体、颜色、大小完全不变。" \
  --element-updates '{"subtitle": {"content": "医疗数据碎片化"}}'

Modify after ingesting an external PPTX

An external PPTX can first be ingested as an image session, and then a multimodal agent can look at the images to fill in each page's slide_spec. Before the specs are filled in, do not promise to "precisely modify a certain object."

python3 scripts/generate_ppt.py --ingest-pptx path/to/deck.pptx
python3 scripts/generate_ppt.py --ingest-pptx path/to/deck.pptx --session my_deck_2024

Rollback and session list

python3 scripts/generate_ppt.py \
  --rollback 3 \
  --to-version 1 \
  --session 20240523_143052

python3 scripts/generate_ppt.py --list-sessions

File structure

gpt-image2-ppt-skills/
|---- SKILL.md                # 本文件(Claude Code skill 入口)
|---- AGENTS.md               # codex / aider / cursor 等 agent 的薄索引,指向本文件
|---- README.md               # 项目说明
|---- scripts/                # 所有 Python 脚本
|   |---- generate_ppt.py         # 主入口(CLI)
|   |---- runtime_profile.py      # 模板克隆 / 结构化 style sidecar 的统一运行时适配器
|   |---- md_to_plan.py           # slides_plan.md -> slides_plan.json 转换器(CLI)
|   |---- render_template.py      # PPTX -> 每页 PNG 的辅助脚本(CLI + library)
|   |---- image_generator.py      # gpt-image-2 wrapper(支持 reference image,openai backend)
|   |---- codex_backend.py        # 可选:走 codex CLI 出图(--backend codex)
|   \---- template_analyzer.py    # PPT 模板剖析器(vision + 缓存)
|---- styles/                 # 所有可用风格,每个 .md 配同名 .layouts.json
|   |---- initial/            # 初始 10 套
|   |---- featured/           # 精选 22 套
|   |---- xiamulingzi/        # 设计师 @夏目玲子 提供的 233 套
|   \---- README.md           # 目录说明与调用示例
|---- examples/               # 场景 recipes:常见 PPT 的 slides_plan.md 起步模板
|   |---- product-launch/             investor-pitch/
|   |---- weekly-report/              courseware/
|   |---- thesis-defense/             book-sharing/
|---- docs/README.en.md       # 英文 README
|---- install_as_skill.sh     # 一键安装到 agent skills 目录
|---- requirements.txt        # requests + python-dotenv + python-pptx + jsonschema + pymupdf
\---- .env.example

The runtime directories generated when invoked are all under <cwd> :

<your-project>/
|---- template_renders/<stem>/page-NN.png   # PPTX 渲染(render_template.py)
|---- template_cache/<sha256>.json          # 外挂 vision 风格分析缓存(纯文本 agent 路径)
|---- template_profile.json                 # 多模态 agent 可手写/生成的模板 profile(可选)
\---- outputs/<timestamp>/                  # 每次生成产物

License

Apache License 2.0.