Pipeline stages
The marketing worker's pipeline is seven discrete stages, each in its own file under src/carousel/. This page walks every stage with its inputs, outputs, and failure mode. Stages run sequentially; the orchestrator short-circuits to a structured error on the first failure.
Overview
- Orchestrator
cf-workers/marketing-swarm/src/carousel/index.ts- Stage files
- retrieve, plan, validate, render-v2, qa, promote (one .ts each)
- Typical p50
- 28 seconds end to end
- Hard timeout
- Cloudflare Worker max execution time
- Idempotency
- Each run has a unique id; stages do not depend on global state
Stage 1: Retrieve
Embed the brief, query Vectorize, hydrate exemplars.
The retrieval step gives the planner concrete prior art to reason from. Without it the planner falls back on generic visual ideas; with it the planner picks up the style and the slide rhythm from previous carousels that scored well. The filter on status: "active" excludes runs that were retired without being promoted.
Stage 2: Plan
Gemma emits a CarouselSpec given the brief, the exemplars, and the registered component index.
Stage 3: Validate
Structural and budget rules. Reject early.
Stage 4: Render
Satori plus Resvg WASM, all in the worker.
Compile turns the DSL into JSX. Satori turns JSX into SVG. Resvg WASM rasterises SVG into PNG. The entire chain runs inside the worker process; no separate cloud-runtime renderer is involved. Fonts are loaded from R2 at worker boot and kept warm in the module-level cache.
Stage 5: QA
LLaVA scores every slide on the same rubric.
Stage 6: Promote
If the average score crosses the threshold, the run becomes an exemplar for next time.
Stage 7: Respond
The HTTP response carries the run id, the score, and signed URLs for every slide.
Error handling
Every stage can fail. The orchestrator catches structured errors and surfaces them.
| Stage | Failure | Behaviour |
|---|---|---|
| Retrieve | Vectorize empty or rate-limited | Continue with no exemplars; planner gets a degraded prompt |
| Plan | Model returns unparseable JSON | Retry once; if still bad, fail with 502 |
| Validate | Spec violates the DSL | Fail with 422 and the validation issues array |
| Render | Satori or Resvg throws on a slide | Fail the whole run with 500 and the slide index |
| QA | LLaVA times out on a slide | Use 0.5 as the fallback score for that slide |
| Promote | D1 or R2 write fails | Log but do not fail the response; the user still gets the deck |