{"id":67512,"plugin_id":"plugin_asdk_app_6ac64f4127ac8191a614f4860d640c20","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-28T13:09:02.326Z","digest":"b110a90cbc3d6feb3df0bd7741f802b7b21055b9b681c91a591a073aa1903cd2","against":null,"payload":{"description":"Turn an end-to-end video creative brief into a sectioned shot list, search the user's Recharm clip library for footage that fits each section using label-based filters, and produce a final creative brief with picks. Use whenever a user provides a brief/script/storyboard and asks for matching footage from Recharm.","included_files":[],"name":"brief-creator","skill_md_contents":"---\nname: \"brief-creator\"\ndescription: Turn an end-to-end video creative brief into a sectioned shot list, search the user's Recharm clip library for footage that fits each section using label-based filters, and produce a final creative brief with picks. Use whenever a user provides a brief/script/storyboard and asks for matching footage from Recharm.\n---\n\n# Find Video Footage for a Brief\n\nYou orchestrate a multi-step search loop against the user's Recharm clip library to turn a creative brief into a shot-by-shot brief with concrete clip picks. You use label-based filters to constrain searches — no visual review of clips is performed.\n\nThe Recharm MCP server (`recharm`) is available in this plugin. Key behavioral notes:\n\n- Call `list_labels` once at the start — keep the result for the entire workflow; do not call it again per scene.\n- You do NOT build HTML. You pick clips and hand `save_brief` a slim structured package; the server derives every clip's URLs, name, duration, and aspect ratio from its `clipSymbol` and renders the HTML.\n- Call `save_brief` exactly once, after the clip picks are final. Each call mints a new URL.\n- Do not paginate `search_clips_visually` — use the first page only.\n- Only use label values returned by `list_labels` — do not invent or guess label strings.\n\nPlease check the actual MCP server data for up-to-date API info.\n\n**Always refer to a clip in user-facing output as its `clipName` — `<clipSymbol> - <sceneType>`** (e.g. \"AB - Product Reveal\"). If `sceneType` is null, fall back to just the `clipSymbol`.\n\nThis skill processes one video at a time. If you detect that the provided brief calls for creating multiple videos, prompt the user up front whether to run the skill once per video (sequentially) or pick a single video to process — then follow the steps below for each chosen video.\n\nFollow the steps below in order.\n\n## Before you begin — capture the prompt\n\nNote the user's verbatim opening message now — before any processing. By Step 7, `prompt` will include this plus any further input they gave during the workflow (see below).\n\n**File attachments (PDF, Word doc, etc.):** if the user attached a file, read its full content and treat it as the brief. For `prompt`, start with the filename, then a newline, then the full extracted text of the file — not a summary. If the user also typed an accompanying message (e.g. \"make this into a brief\"), prepend that message followed by a newline before the filename and content.\n\n**Subsequent user input:** as the workflow progresses, append any further instructions, corrections, clarifications, or interruptions the user provides — verbatim. This includes answers to questions you asked, changes of direction, feedback on scene breakdowns, or anything else they typed. The goal is that a viewer of the brief can reconstruct the full intent from `prompt` alone.\n\n## Step 1 — Confirm the brand\n\n- If the user already named a brand slug (e.g. `lululemon`, `hike_footwear`), use it.\n- Otherwise call `list_brands` and ask the user to pick.\n- Do not guess the brand if there is any ambiguity.\n\n## Step 2 — Fetch available labels\n\nCall `list_labels(brandName)` and keep the result for the rest of the workflow. You will use these categories and labels to build search filters. Do not invent or use label values that were not returned by this call.\n\nNote the following special-case categories if present:\n\n- **SceneType**: each clip belongs to exactly one SceneType. Useful values include `Hook`, `CTA`, `Product Benefit`, `Demo`, and `Product Shot`.\n- **ActorType**: indicates whether a person appears and whether they are speaking.\n\n## Step 3 — Section the brief\n\nRead the brief and break it into ordered scenes. Each scene should be approximately 2–5 seconds and correspond to a single Recharm clip. Cap the total at **18 scenes**.\n\nFor each scene capture:\n\n- A short heading (e.g. \"Hook — runner laces up at dawn\")\n- 1–2 sentences describing what should appear on screen\n- The narrative role (hook / problem / product reveal / benefit / proof / CTA / etc.) when the brief implies one\n\nIf the user supplied an explicit scene breakdown, use it and skip to Step 4. Otherwise, **show the proposed scene breakdown to the user and wait for confirmation before proceeding.**\n\nIf a transcript (also called voiceover or VO) is provided, use it to inform what each scene should show — but section the brief independently of transcript timing.\n\n## Step 4 — Build search queries\n\nFor each scene, generate **2-4 search queries**. Each query has:\n\n- A short visual phrase (under ~8 words) describing what is literally on screen — not abstract concepts. \"woman tying running shoes on porch\" beats \"morning motivation\". Vary phrases across queries to cover different subjects, framings, and environments.\n- An optional `filters` object with 0–3 categories and 1-2 labels from the `list_labels` response.\n\n### Filter rules\n\n**SceneType filter:** use the SceneType that best matches the scene's narrative role when a relevant SceneType exists in the label list.\n\n**ActorType filter (transcript constraint):** if a transcript (or voiceover/VO) was provided AND `ActorType` is present in the `list_labels` response, add `ActorType: [\"Actor B-roll\", \"No Actor\"]` as a hard filter on every query. If `ActorType` is absent from the label list, omit this filter entirely.\n\n**Product filter:** if a specific product was named in the input:\n\n1. Look for a product-related label category in the `list_labels` response.\n2. If found, match the product name to the closest available label. If you are unsure which label is the right match, ask the user to pick before searching.\n3. If no product label category exists, include the product name in the text query phrase for scenes where it is relevant (product shots, demos, CTAs) — not mechanically on every scene.\n\n**General filter guidance:** supply multiple labels within a category to broaden results (OR logic within a category). Only combine multiple categories when both constraints are genuinely required (AND logic across categories) — over-filtering will return too few results.\n\n## Step 5 — Search, section by section\n\nEach `search_clips_visually` hit is slim: `clipSymbol`, `clipName`, `rawVideoPublicId`, `sceneType`, `cosineDistance` (lower is closer), `durationMs`, and `categoriesAndLabels` (top hits). No media URLs are returned — pick clips by `clipSymbol` and the server derives the rest at render time.\n\nFor each scene:\n\n1. Call `search_clips_visually` once per query phrase, passing `brandName`, `query`, and any `filters`. Do not paginate — use only the first page of results.\n2. Select the **1–2 top results per query** by lowest `cosineDistance`. Do not fetch or examine poster images or sprite images.\n3. Aim for **3–6 clips per scene** total (across all queries). Deduplicate by `clipSymbol` — if the same clip appears in multiple query results, count it once and attribute it to the query with the best cosineDistance.\n4. Use **at most one clip per `rawVideoPublicId`** within a scene — clips sharing a `rawVideoPublicId` are different moments of the same source video and look near-identical. Keep the best (lowest cosineDistance) and drop the rest, so each scene's picks are visually varied.\n5. Track, per picked clip, the **query phrase** and the **filters** used in the search that surfaced it — both go into the brief package in Step 6.\n6. If all results for a scene have weak cosineDistance scores, leave that scene's clip list empty (Step 6) so it renders as a \"custom shoot needed\" gap, and note it in the overall summary to the user.\n\n## Step 6 — Assemble the brief package\n\nDo **not** write HTML. Build a slim structured package the server will render:\n\n- `title`: a short brief title, e.g. `\"5 Outdated Rules\" · UGC Testimonial · Women 50+`.\n- `prompt`: the user's original message, verbatim — the exact text captured before Step 1. Along with further input. Do not paraphrase.\n- `scenes`: the ordered scenes from Step 3. Each scene is:\n  - `name`: the scene heading.\n  - `description`: the 1–2 sentence on-screen description from Step 3.\n  - `clips`: the picked clips for the scene, in order. Each clip is:\n    - `clipSymbol`: the `clipSymbol` from the `search_clips_visually` hit.\n    - `searchString`: the query phrase that surfaced this clip (Step 4/5).\n    - `filters`: the label filters used in that search, if any (the same `filters` object you passed to `search_clips_visually`).\n  - For a scene that needs a custom shoot (no strong matches), use an **empty `clips` array** — it renders as a \"custom shoot needed\" gap.\n\nYou do not provide URLs, durations, dimensions, aspect ratios, or display names — the server derives all of those from each `clipSymbol`.\n\n## Step 7 — Save and share the brief\n\nOnce the package is assembled, call `save_brief` exactly once with the **v2** payload:\n\n```\nsave_brief(brandName, {\n  version: \"v2\",\n  title: \"<brief title>\",\n  prompt: \"<user prompt message(s) as mentioned in Step 1>\",\n  scenes: [\n    {\n      name: \"<scene heading>\",\n      description: \"<on-screen description>\",\n      clips: [\n        { clipSymbol: \"<symbol>\", searchString: \"<query phrase>\", filters: { <category>: [\"<label>\"] } }\n      ]\n    }\n    // ...a scene needing a custom shoot uses: { name, description, clips: [] }\n  ]\n})\n```\n\nThe tool derives, renders, and uploads the HTML, returning `{ url, briefId, s3Key }` — surface the `url` to the user as the shareable link. After saving, give the user a short **overall summary**: scenes that need custom footage, cross-cutting observations, and obvious gaps in the brand's library. If the call fails, report the failure and show the structured package you assembled.\n\n## What not to do\n\n- Don't fetch or examine poster images or sprite images — clip selection is based on cosineDistance and text metadata only.\n- Don't use label values that were not returned by `list_labels` — the API will reject them.\n- Don't over-filter: combining many categories will produce too few results.\n- Don't pad picks with weak matches without a warning note.\n- Don't invent `clipSymbol`s — only use ones returned by `search_clips_visually`.\n- Don't refer to a clip by `clipSymbol` alone in user-facing output — always use `clipName`.\n- Don't ask the user to run searches themselves — you do it via the MCP.\n- Don't build HTML or construct clip URLs yourself — hand `save_brief` the v2 structured package and let the server render.\n- Don't call `save_brief` more than once per brief, and don't call it before the clip picks are final.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}