CtrlK
BlogDocsLog inGet started
Tessl Logo

media-proxy

Shared helper that routes ALL paid media generation (FAL image/video, ElevenLabs music) through the GooseWorks proxies so every call bills the Ads agent — never a provider SDK's default host. Host-swaps the FAL queue URLs, loads the agent token from ~/.gooseworks/credentials.json, and returns the result CDN URL. Every video-ad media capability imports this; templates never call a provider directly.

64

Quality

76%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Medium

Suggest reviewing before use

Fix and improve this skill with Tessl

tessl review fix ./skills/ads/capabilities/media-proxy/SKILL.md
SKILL.md
Quality
Evals
Security

media-proxy

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 bills the Ads agent.

Crash-resume (never lose / double-bill a paid render)

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):

  • Poll-through-outage_fal_run's poll loop re-attaches to the same status/result URL through connection refused / timeout blips instead of crashing.

  • Persist + resume — each submit's request_id + poll URLs are written to ~/.gooseworks/pending-fal-jobs/. 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.

Use it

from media_proxy import fal_generate, fal_generate_video, eleven_music, download

# image (nano-banana / gpt-image / etc.) — inputs must be PUBLIC urls
img = fal_generate("fal-ai/nano-banana/edit",
                   {"prompt": p, "image_urls": [product_url], "aspect_ratio": "9:16"})
# video i2v (kling / seedance / veo)
vid = fal_generate_video("fal-ai/kling-video/v2.1/standard/image-to-video",
                         {"prompt": p, "image_url": keyframe_url, "duration": "10"})
# music bed
eleven_music(prompt, 10500, "music.mp3", force_instrumental=True)

Contracts (load-bearing)

  • Bills the Ads agent?token=&agent_id= from ~/.gooseworks/credentials.json (the CLI writes it; run gooseworks login if missing).
  • Host-swap the FAL queue URLs — submit returns status_url/response_url on queue.fal.run; the helper rewrites them to the proxy base (keeps the path). Never poll queue.fal.run directly (401 + burns credits).
  • FAL inputs that are local files must be PUBLIC urls. The orchestrator hosts a local image/audio via the MCP get_upload_urlget_download_url presigned URL and passes THAT url in. This module does not do MCP uploads (prefer the presigned url; fal-storage-proxy may 404).
  • Only the final *.fal.media url is a real public URL — everything else is behind the proxy.

Related

  • Used by create-image-fal, create-video-fal, create-music-elevenlabs.
  • The goose-video orchestrator hosts local inputs (MCP upload → presign) before calling these.
Repository
gooseworks-ai/goose-skills
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.