goose-ads
Edit, resize, animate and study image ads with GooseWorks in this chat. New static or image ads go to the make-static-ads skill…
Shared helper that routes ALL paid media generation (FAL image/video, ElevenLabs music) through the GooseWorks proxies so every call is charged to your GooseWorks credits — never a provider SDK's default host. Host-swaps the FAL queue URLs, loads the agent token from the sandbox
Claude Code
$ npx -y skills add gooseworks-ai/goose-skills --skill media-proxy --agent claude-code
Codex
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a codex -y
Cursor
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a cursor -y
Gemini CLI
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a gemini-cli -y
GitHub Copilot
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a github-copilot -y
OpenCode
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a opencode -y
Windsurf
$ npx skills add gooseworks-ai/goose-skills --skill media-proxy -a windsurf -y
name: media-proxy description: Shared helper that routes ALL paid media generation (FAL image/video, ElevenLabs music) through the GooseWorks proxies so every call is charged to your GooseWorks credits — never a provider SDK's default host. Host-swaps the FAL queue URLs, loads the agent token from the sandbox env (GW_MEDIA_PROXY_TOKEN) or ~/.gooseworks/credentials.json, and returns the result CDN URL. Every video-ad media capability imports this; templates never call a provider directly. status: active version: "2.0.6"
The foundation capability for paid media in the video-ad pipeline. It fixes the auth-path conflict where engine scripts called FAL/ElevenLabs **directly** (billing the wrong account): all paid calls now go through `<api_base>/api/internal/{fal-proxy,elevenlabs-proxy}` with `?token=&agent_id=`, which **is charged to your GooseWorks credits**.
A FAL submit BILLS immediately, but the local backend can blip during a multi-minute render. Two built-in protections (automatic for every capability that imports this):
URL through `connection refused` / timeout blips instead of crashing.
`~/.gooseworks/pending-fal-jobs/` (`GW_FAL_PENDING_DIR` overrides, for tests). A caller that keeps its own manifest passes `on_submit=` to `fal_generate*`: it is called with the `request_id` right after the submit is saved. If the poller still dies, **re-attach instead of re-firing** (re-firing double-bills): `resume_fal(request_id)` in Python, or the CLI:
resume.py --list # resumable (submitted, unfinished) jobs resume.py --request-id <id> --out final.mp4 # poll to completion + download
`resume_fal` NEVER re-submits, so it can't double-charge.
`default_poll_timeout(model)`: **1800s for video / lipsync / audio-driven models**, 600s for images (`GW_FAL_POLL_TIMEOUT_S` overrides; `timeout_s=` per call). A timeout raises `FalPollTimeout` carrying `.request_id` + `.model_path` — the job is still running and already paid for. **Re-attach with `resume_fal(e.request_id)`; never call `fal_generate*` again for it** (a veed/fabric lipsync once finished 26s after a 600s poller quit, and the retry paid for a second identical job).
identical submit (same agent + model + body) within 30 min, so an accidental resubmit re-attaches instead of paying twice (response header `x-gw-deduped: 1`). For a **deliberate re-roll** of the same input (want a new take), pass `new_take=True` (`fal_generate(..., new_take=True)` / `fal_generate_video(...)`), which sends `x-gw-no-dedupe: 1` (raw HTTP callers: that header or `?dedupe=0`).
never pays twice.** The body-match dedupe above breaks after a sandbox restart: the resumed run re-uploads its inputs (voiceover, stills) and gets NEW urls, so the body differs. `fal_generate*(..., input_digest=d)` sends `x-gw-input-digest: d`; the proxy then dedupes on (agent + model + digest) for **24 h** and returns the job you already paid for. Use the same stable digest you save with `media_upload` (see below). If that job's result has since expired at fal, the poll fails: retry once with `new_take=True`.
When fal refuses a request on policy grounds, `_fal_run` (and so `fal_generate*`) raises **`FalPolicyRejection`**, a `RuntimeError` subclass, so old `except RuntimeError` handlers still work. Policy grounds means a likeness of a real person ("likenesses of real people", "real person", "public figure"), `content_policy_violation`, `partner_validation_failed`, or NSFW / safety checker.
or a string; a top-level `type`/`code`/`error`; the GooseWorks MCP wrapper `{"error": {"code": "provider_validation_failed", "status": 422, "detail": <fal body>}}`; and a failed `job_get` reply `{"status": "failed", "error": "fal returned HTTP 422 for the result.", "result": {"detail": <fal body>}}` (fal reports most failed generations as COMPLETED plus a 422 on the result). Before this, a body with both `msg` and `type` kept the message and lost the type, so the rejection looked like a generic error.
`partner_validation_failed`, `content_blocked`) at any status, or a policy phrase (likeness, public figure, usage guidelines, risk control, moderation, blocked for safety, NSFW, flagged by the safety checker) on an explicit 4xx that is not 408 or 429. Input errors such as "Could not detect a real person's face" or "enable_safety_checker cannot be disabled" are not policy. A rejection on a 5xx, 408 or 429 is surfaced but **never recorded**.
`partner_validation` | `content_policy` | `nsfw`), `error_type`, `request_id`, `http_status`, `stage`, `charged` and `charge_note`. `charged` is `False` for an explicit provider 4xx: the GooseWorks proxy debits only a successful response and releases the hold on a 4xx (read from the proxy code, not yet confirmed on a real rejection). It is `None` (unknown) for a job that failed after it was accepted.
next to `pending-fal-jobs/` (`GW_FAL_REJECTIONS_DIR` overrides). The key is a digest of the model plus the canonical JSON payload (sorted keys), and also of `input_digest` when one is pass
Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.
Edit, resize, animate and study image ads with GooseWorks in this chat. New static or image ads go to the make-static-ads skill…
Make product photos (studio, lifestyle or on a model) of a brand's real products with GooseWorks in this chat. Start brand work…
Make an approved GooseWorks video when an answer's next_step gives its command.
Make a video ad in this chat from a real reference ad, found or theirs; styles are the fallback. Follow every answer's next_step.
GooseWorks growth coworker and router for markets, competitors, audiences, creators, campaigns, ads, photos, graphics, video,…
Create a custom video with sourced product accuracy, explicit sound routing and exact-final audiovisual review.
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use…
Comprehensive SEO analysis for any website or business type. Full site audits, single-page analysis, technical SEO (crawlability,…
Turn the current project website into a short, polished, shareable launch video using Hyperframes. Use when someone says "/brag",…
Full website GEO+SEO audit with parallel subagent delegation. Orchestrates a comprehensive Generative Engine Optimization audit…