sn-ppt-standard
This skill is self-contained — no dependency on sn-image-base for LLM/VLM (T2I still goes through sn-image-base). Every call through $SKILL_DIR/scripts/run_stage.py. Every subcommand is deterministic: one input set → one output artifact → one-line JSON status.
Preconditions
<deck_dir>/task_pack.jsonexists andppt_mode == "standard"<deck_dir>/info_pack.jsonexists
Any missing → stop and tell user to enter via /skill sn-ppt-entry.
🚫 Hard rules (the main agent MUST NOT)
- Do NOT write Python scripts that loop over pages or slots in a single exec. Use the batch subcommands, or per-item execs in the agent's own loop of tool_calls.
- Do NOT fake image generation. If
gen-imagefails, don't write a placeholder PNG — the HTML stage will redesign around the missing slot. - Do NOT construct LLM prompts yourself.
run_stage.pyis the only place that builds payloads. - Do NOT add
timing/ logging / retry layers. The skill is intentionally thin. - Do NOT go silent between execs. Echo a one-line Chinese progress message after each exec before issuing the next.
Pipeline
R="python3 $SKILL_DIR/scripts/run_stage.py"
D="<deck_dir>"
$R preflight --deck-dir $D # validate + stage assets
$R style --deck-dir $D # -> style_spec.json
$R outline --deck-dir $D # -> outline.json
$R asset-plan --deck-dir $D # -> asset_plan.json
# Per-item forms — one progress line per item:
$R gen-image --deck-dir $D --page N --slot SLOT_ID
$R page-html --deck-dir $D --page N
# Batch (concurrent) equivalents — default 4 workers. Each prints one summary
# JSON to stdout plus per-item status lines to stderr.
$R batch-gen-image --deck-dir $D [--concurrency 4]
$R batch-page-html --deck-dir $D [--concurrency 4]
$R export --deck-dir $D # -> <deck_id>.pptx
batch-gen-image serializes writes to asset_plan.json under a process-local lock so concurrent workers don't clobber each other.
How page-html works (two LLM calls per page)
- Rewrite —
prompts/page_html_rewrite.mdconverts the structured outline + style_spec + inherited content into a natural-language user prompt (content, layout, palette, inherited material). - Generate —
prompts/page_html.mdis a hard-contract system prompt (document shell, image path format, ECharts rules, single-layer background,<span>wrapping rule, language lock). Receives the rewritten query as the user message and returns the final<!DOCTYPE html>...</html>.
This split keeps converter-facing mechanical contracts (chart container id = chart_N, {renderer:'svg'}, __pptxChartsReady counter, allowed chart types, etc.) in the generator's system prompt — not buried in the natural-language query where they'd get smoothed out.
Output on each exec
One JSON line to stdout:
{"status": "ok", "page_no": 3, "path": "images/page_003_hero.png"}
or on failure (exit code 1):
{"status": "failed", "error": "<reason>", "page_no": 3}
For gen-image failures: don't retry, don't substitute — the HTML stage will redesign around it.
Progress echo — MANDATORY
| Stage | Example |
|---|---|
| After preflight | 已进入 sn-ppt-standard,共 N 页 |
| After style | [1] style_spec.json ✓ 主色 #2D5BFF |
| After outline | [2] outline.json ✓ 10 页 |
| After asset-plan | [3] asset_plan.json ✓ N 槽位 |
| Per gen-image | [图 5/14] page_003/hero ✓ or ... ✗ 服务端 502 |
| After all gen-image | 图片生成阶段完成:成功 12,失败 2 |
| Per page-html | [页 3/10] HTML ✓ |
| After export | PPTX ✓ (10/10 页) or PPTX 失败: ... |
Silence for more than ~30 seconds = a bug.
Resume semantics
The script is stateless — re-run a subcommand and it'll overwrite its output artifact. Quick ls <deck_dir> decides what's left:
style_spec.jsonexists → skipstyleoutline.jsonexists → skipoutlineasset_plan.jsonexists → skipasset-plan(but any slot whoselocal_pathis missing orstatus != "ok"still needsgen-image)pages/page_NNN.htmlexists → skippage-htmlfor that page<deck_id>.pptxexists → skipexport
scripts/resume_scan.py emits a JSON manifest summarizing all this.
Env
Configured via .env at the repo root (or <repo>/skills/.env). model_client.py auto-loads both. Required:
SN_CHAT_API_KEYfor shared text/vision chat auth, or per-kind overridesSN_TEXT_API_KEY/SN_VISION_API_KEYSN_IMAGE_GEN_API_KEY,SN_IMAGE_GEN_BASE_URL,SN_IMAGE_GEN_MODEL
Optional SN_CHAT_BASE_URL / SN_TEXT_BASE_URL / SN_VISION_BASE_URL, SN_CHAT_MODEL / SN_TEXT_MODEL / SN_VISION_MODEL, and SN_CHAT_TIMEOUT / SN_TEXT_TIMEOUT / SN_VISION_TIMEOUT override defaults.
Run python $SKILL_DIR/lib/model_client.py health to verify env before running the pipeline.
Export PPTX gate
scripts/export_pptx/html_to_pptx.mjs is invoked with --force — skips built-in motif / real-photo gates (this skill doesn't use the motif protocol). PPTX still produces even if some slots are missing images.
If the converter crashes, run_stage.py export returns status: "failed". That's the deck's ending state; PPTX is simply absent.
Does NOT
- Does not call
sn-image-basefor LLM/VLM (only for T2I). - Does not retry failed model calls.
- Does not write progress to disk.
- Does not do per-page visual review or rewriting (removed in this iteration).
微信扫一扫