# UGC ads Human Guide

## What This Is For
Creates UGC-style ad concepts and video prompts from a product URL, including creator framing, hook structure, captions, aspect ratio, and production settings. It gives the agent a clearer input/output frame for paid media: what context to ask for, what decisions to make, and what usable artifact to return.

Use this as a human-readable version of the UGC ads agent skill. It is meant for marketers, operators, founders, and other non-coders who want the workflow without reading agent-specific implementation instructions.

## When To Use This
- Use this when you need a repeatable process for UGC ads.
- Use this when the task needs judgment, examples, constraints, or a clear output format rather than a one-off prompt.
- Use this when you want to hand an AI assistant enough context to produce a usable marketing artifact.

## When Not To Use This
- Do not use this when you only need a quick factual answer.
- Do not use this when the work depends on private data you cannot share with the assistant.
- Do not use this as a replacement for legal, compliance, financial, or medical review.

## What You Need Before Starting
- The goal or business outcome you want.
- The audience, customer segment, or market context.
- Any source material the assistant should respect, such as notes, briefs, examples, URLs, or brand guidance.
- Constraints such as tone, length, channel, deadline, region, or approval requirements.
- A clear definition of what a good final answer should look like.

## Step-By-Step Workflow
1. State the job clearly: "Use the UGC ads guide to help me with..."
2. Add context: audience, goal, offer, channel, source material, and constraints.
3. Ask the assistant to identify missing inputs before producing the final output.
4. Have the assistant follow the skill-specific guidance below.
5. Review the result against the final checklist and ask for revisions where needed.

## Skill-Specific Guidance
- Step 1 (WebFetch) + Step 3 (capture_website screenshot): ~10–30s
- Step 7 (`generate_reference_video`): ~3–5 min for seedance, ~5–7 min for kling
- Step 7b/c (cartoonize + retry): adds ~1–2 min if seedance moderation rejects the avatar
- Step 8 (deterministic brand/spec overlays): 1-2 `edit_text_overlay` calls, ~30s–5 min total
- Step 9 (captions): single `add_captions` call, ~30s–5 min (transcribe + burn in one shot)
- `Stage 1/3 done — product fetched and categorized.`
- `Stage 2/3 done — avatar and screenshot ready, composing dialogue.`
- `Stage 3/3 done — prompt locked, calling Seedance now.`
- Call `task_status({task_id})` in a tight loop until terminal (`completed | failed | cancelled`). No manual sleep and no Bash polling; the worker holds each status call open.
- On `completed`, unwrap the returned result URL and continue.
- On `failed` or `cancelled`, surface failure to the user with `task_id`, status, and the last status message.
- Do not submit a duplicate request while the original task is still `queued`, `running`, or `processing`.

## Decision Points And Nuance
The original skill emphasizes: Parameters, Cost transparency gate, Runtime expectations, Pre-generation wall-clock guard, Long-running task_status polling, Engine choice: Seedance default, Kling fallback, Steps, Resolve input (empty-args menu), Fetch + categorize, Resolve the avatar (fallback to built-in if missing).

Use these questions to steer the work:
- What is the intended audience or buyer?
- What source material must be preserved?
- What should the assistant optimize for: clarity, persuasion, accuracy, speed, creativity, or conversion?
- What examples represent the desired quality bar?
- What should the assistant avoid?

## Common Mistakes
- | `url` | required | product URL — drives category detection and beat substitution |
- Script and prompt iteration is maximum 2 passes. After the max 2 passes, ship what you have to `generate_reference_video`; do not continue polishing the hook, punchline, or screen-close-up wording.
- Do not submit a duplicate request while the original task is still `queued`, `running`, or `processing`.
- > **Which product should the UGC ad promote?** Required:
- **stylized / illustrated** -> proceed with a visible warning that stylized avatars may be accepted by Kling but can be inconsistent under Seedance moderation; continue only if the user supplied or accepted that avatar.
- `brand_overlay_text` is always the exact `brand_name` from WebFetch. If `brand_name` is empty, use `product_name`; do not let the model invent a logo/wordmark.
- `grounded_spec_overlay_text` must be empty or one exact claim from `claims_allowlist`. Never overlay a number that is absent from `claims_allowlist`.
- Do not use this step for captions or per-word subtitles; Step 9 handles captions with one `add_captions` call.

## Copy-And-Paste Prompt
```text
Use the UGC ads human guide.

My goal:
[Describe the business outcome]

Audience:
[Describe who this is for]

Context and source material:
[Paste notes, examples, links, or existing copy]

Constraints:
[Tone, length, channel, timeline, must-include items, must-avoid items]

Before producing the final output, ask me for any missing information that would materially improve the result.
```

## Final Checklist
- [ ] The output matches the original goal.
- [ ] The audience and context are reflected in the answer.
- [ ] Important constraints and source material were preserved.
- [ ] The assistant made the relevant decisions explicit.
- [ ] The final artifact is ready to use, review, or hand to the next person.

## Source
This guide was generated from the pika-labs/pika-plugins skill entry for `ugc-ads`.

## Source Skill Notes
These notes preserve the nuance from the original skill. Use them as supporting reference when the workflow above feels too generic.

# /pika:ugc-ads

## Parameters

| Param | Default | Notes |
|---|---|---|
| `url` | required | product URL — drives category detection and beat substitution |
| `avatar_url` | built-in fallback | persona portrait URL; fed as `@Image1` reference. When omitted, the skill uses a pre-generated Pixar-style female creator portrait |
| `provider` | `seedance` | seedance: strong at UGC selfie / talking-head POV with native lip-sync, multi-segment in single prompt, supports 3:4. kling: explicit `shots[]`, 9:16/16:9 only |
| `aspect_ratio` | `9:16` | `3:4` is seedance-only (kling rejects 3:4) |
| `variants` | unset | Optional comma list for shared-generation exports. Supported: `9:16`, `16:9`, `1:1`. Keeps the expensive UGC render shared, then reframes the final stage. |
| `category` | auto | `HAUL` / `APP` / `FOOD` / `BEAUTY` / `FITNESS` / `TECH`; auto-picked from URL |
| `captions` | `true` | TikTok-style word-chunked captions burned on top of the final video |

## Cost transparency gate

Before any paid MCP call, call `identity_balance({verbose: true})` once. Surface the current balance, recent burn rate, and remaining runway, then gate the run with this exact message:

> Estimated cost: about 4,000 credits (~$40) for a typical Seedance UGC ad with fallback/retry budget. This exceeds $5, so Reply `proceed` to continue or `cancel` to stop.

Do not call any paid MCP tool until the user replies `proceed`. If the user replies `cancel`, stop without generating. The gate runs after the product URL is known and before avatar analysis, screenshot capture, video generation, captions, or paid retries.

## Runtime expectations

Typical end-to-end run: **6–12 minutes**. Breakdown:

- Step 1 (WebFetch) + Step 3 (capture_website screenshot): ~10–30s
- Step 7 (`generate_reference_video`): ~3–5 min for seedance, ~5–7 min for kling
- Step 7b/c (cartoonize + retry): adds ~1–2 min if seedance moderation rejects the avatar
- Step 8 (deterministic brand/spec overlays): 1-2 `edit_text_overlay` calls, ~30s–5 min total
- Step 9 (captions): single `add_captions` call, ~30s–5 min (transcribe + burn in one shot)

If the run exceeds 15 min without progress, something is wrong — inspect the tool-reported generation status and error message.

## Pre-generation wall-clock guard

Start a timer at skill start once the product URL is available and the cost gate has passed. Time spent waiting for the user's `proceed` reply is not prep time and must not trigger this guard. The first paid generation call is `generate_reference_video`, the long-pole paid stage, and it must be invoked within 5 minutes of skill start. If you have not invoked `generate_reference_video` within 5 minutes of skill start, stop before any paid generation call and report `failed_pre_generation_timeout` with what you have so far: fetched product facts, chosen category, avatar source, screenshot status, draft dialogue, and the exact blocker. Do not keep refining script wording, prompt grounding, or shot order.

Print a single-line progress checkpoint after each prep stage and right before the paid generation call:
- `Stage 1/3 done — product fetched and categorized.`
- `Stage 2/3 done — avatar and screenshot ready, composing dialogue.`
- `Stage 3/3 done — prompt locked, calling Seedance now.`

Script and prompt iteration is maximum 2 passes. After the max 2 passes, ship what you have to `generate_reference_video`; do not continue polishing the hook, punchline, or screen-close-up wording.

## Long-running task_status polling

When any long-running generation or edit call returns a `task_id` with or without an initial status, including `{task_id}`, `{task_id, status: "queued"}`, or an initial `queued`, `running`, or `processing` status, record the task id and start time immediately.

- Call `task_status({task_id})` in a tight loop until terminal (`completed | failed | cancelled`). No manual sleep and no Bash polling; the worker holds each status call open.
- Emit ONE visible progress line every 60s while status is `queued`, `running`, or `processing`: `Seedance i2v queued for {N}m {S}s... still processing`. Replace the provider/stage label when polling Kling, GPT-image-2, caption, or edit tasks.
- On `completed`, unwrap the returned result URL and continue.
- On `failed` or `cancelled`, surface failure to the user with `task_id`, status, and the last status message.
- After 15 min total from the original submit, call `task_cancel({task_id})` if the task is still non-terminal, then surface failure to the user. If cancel reports the task is already terminal, call status once more and report that terminal result.
- Do not submit a duplicate request while the original task is still `queued`, `running`, or `processing`.
- Async polling budget: one active task with one 15 min polling window. After the polling cap is exhausted, cancel the task and surface failure instead of submitting another paid render unless a later step explicitly allows a separate capped retry after the original task is terminal.

## Engine choice: Seedance default, Kling fallback

Default to Seedance for UGC selfie/talking-head ads because it handles native lip-sync, single-prompt multi-beat pacing, and optional 3:4 output well. Use Kling when the caller explicitly passes `provider=kling`, or after Seedance exhausts the capped cartoonized retry only if the user chooses Kling from the stop message. Kling's tradeoff is stricter aspect-ratio support but a separate moderation path and explicit shot segmentation.

## Steps

### 0. Resolve input (empty-args menu)

Strip flags and `key=value` parameters from `$ARGUMENTS`. If no product URL remains and there is no usable product URL in prior context, print this menu and stop:

> **Which product should the UGC ad promote?** Required:
>
> - **Product URL** — page to fetch for product name, category, visual references, and language
>
> Optional: `avatar_url=`, `provider=seedance|kling`, `aspect_ratio=9:16|3:4`, `variants=9:16,16:9,1:1`, `category=auto|HAUL|APP|FOOD|BEAUTY|FITNESS|TECH`, `captions=true|false`.

If the product URL is present, skip this step silently.

### 1. Fetch + categorize

`WebFetch` the URL: pull `product_name`, `brand_name`, value prop, brand color, product form, packaging, hero copy, target user, category, **and the primary language of the page**. Use `category=` if passed; else trust the WebFetch signal; fall back to HAUL for physical, APP for digital.

Build two grounded fact lists from the fetched page:
