返回 Skill 列表
extension
分类: 开发与工程无需 API Key

sn-ppt-standard

Standard-mode PPT pipeline. All LLM / VLM / T2I calls are wrapped in a single CLI entry (scripts/run_stage.py). The main agent's job is simple: emit ONE shell command per stage, never write loops, never write prompts.

person作者: gaclovehubgithub

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.json exists and ppt_mode == "standard"
  • <deck_dir>/info_pack.json exists

Any missing → stop and tell user to enter via /skill sn-ppt-entry.

🚫 Hard rules (the main agent MUST NOT)

  1. 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.
  2. Do NOT fake image generation. If gen-image fails, don't write a placeholder PNG — the HTML stage will redesign around the missing slot.
  3. Do NOT construct LLM prompts yourself. run_stage.py is the only place that builds payloads.
  4. Do NOT add timing / logging / retry layers. The skill is intentionally thin.
  5. 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)

  1. Rewriteprompts/page_html_rewrite.md converts the structured outline + style_spec + inherited content into a natural-language user prompt (content, layout, palette, inherited material).
  2. Generateprompts/page_html.md is 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.json exists → skip style
  • outline.json exists → skip outline
  • asset_plan.json exists → skip asset-plan (but any slot whose local_path is missing or status != "ok" still needs gen-image)
  • pages/page_NNN.html exists → skip page-html for that page
  • <deck_id>.pptx exists → skip export

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_KEY for shared text/vision chat auth, or per-kind overrides SN_TEXT_API_KEY / SN_VISION_API_KEY
  • SN_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-base for 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).