INTRO
A multi-agent AI system that runs an Etsy print-on-demand storefront — from trend discovery to artwork generation to listing publication to margin tracking — with the human only stepping in to approve or reject finished listings.
It's the kind of project that looks like 'just orchestration' until you start building it. Real money moves through real APIs that don't forgive double-charges. Image generation costs real money per call. LLM outputs drift in non-obvious ways. The interesting work was the boring work: idempotency, dedup, rate limits, and margin math that survives currency conversion and fee changes. ~36k lines of Python and TypeScript, 45+ schema migrations, CI-gated.
SECTION
Four agents, one schema, no orchestrator
The agents don't call each other. They write to and read from a shared Supabase schema, and each owns one stage of the pipeline. Scout writes `trend_briefs`. Design picks up briefs in `pending` status and writes `design_packages`. Listing picks up packages and publishes to Etsy. Ledger watches Etsy receipts and writes `orders` with derived margins. Status transitions on shared rows are the API.
That decision avoided a central orchestrator entirely. Each agent has its own runtime, deployment cadence, and retry semantics. Scout runs on nightly cron (trends don't change minute-to-minute). Design and Listing poll every 15 minutes (image generation is slow and expensive). Ledger polls every 30 minutes (Etsy receipts settle slowly). They scale and fail independently — when fal.ai had an outage, Design stalled and the others kept working off the existing pipeline backlog.
Diagram showing status flow across the four agents
/work/presswork/pipeline-flow.png1400 × 800 PX
SECTION
Polyglot on purpose
Scout and Design are Python — `httpx`, `pydantic`, `structlog`. Listing and Ledger are TypeScript — `Zod` for schemas, `Bottleneck` for rate-limited Etsy calls. The shared schema is the contract; the polyglot is the optimization. Each language has its own client library in the monorepo (`packages/shared_py` for Python agents, `packages/shared` for TypeScript) that wraps Supabase access, Etsy auth refresh, and Slack/email notifications.
That's heresy in some shops, but the right tool actually wins: Python's data and AI tooling for the LLM-heavy upstream stages, TypeScript's runtime safety and async-API ergonomics for the money-touching downstream stages. CI typechecks both stacks and runs an end-to-end test that drives a single trend brief through all four agents against fixture data.
Side-by-side: Python pydantic model vs TypeScript Zod schema for the same shared shape
/work/presswork/polyglot.png1400 × 800 PX
SECTION
Idempotency, dedup, and not getting fleeced
Every step that costs money or sends money is protected. The Design agent SHA-256 hashes the final image prompt before calling fal.ai — identical prompts reuse the prior image instead of paying for a duplicate generation. Scout does exact-match dedup *and* Claude-powered semantic dedup before writing a brief, so near-duplicate trends don't flood the pipeline. Ledger has a unique constraint on `etsy_order_id`, so polling can run as often as it likes without double-counting a sale.
When something fails, `structlog` emits a structured log line. A Slack webhook fires per low-margin order so I see them within minutes. A separate daily cron emits a revenue/margin digest by Slack and email. The whole loop is observable from a phone — which matters, because the agents don't sleep.
Slack daily revenue digest with margin breakdown
/work/presswork/slack-digest.png1200 × 900 PX
Dedup pipeline: exact match, then SHA-256 prompt hash, then semantic dedup
/work/presswork/dedup-flow.png1200 × 900 PX
SECTION
The boring math that wasn't boring
Etsy returns receipts in buyer currency. Printify charges in USD. Etsy's fees depend on listing price, payment method, and shipping origin. True margin is `(USD sale − Etsy fees − print cost)` — and getting that calculation right, then keeping it right as Etsy revises their fee structure, is where most projects in this space quietly leak money.
Ledger normalizes currencies via a daily rate snapshot, computes fees with Etsy's official rules implemented per their published documentation, looks up print costs by SKU, and writes the final margin onto the row. The same row drives both the daily digest and the low-margin Slack alert. One source of truth for every dollar.
OUTCOME
Live and shipping listings on Etsy. Optional `HUMAN_REVIEW_ENABLED` gate keeps a human in the loop without putting them on the critical path. Observable from Slack, deployable from a single railway up. The system runs unattended — the agents don't sleep, and the database is the only thing they share.
EXHIBITS
Captures
CAPTURE / 01 OF 03
AI-generated print artwork sample 01
/work/presswork/sample-design-01.png1000 × 1000 PX
CAPTURE / 02 OF 03
AI-generated print artwork sample 02
/work/presswork/sample-design-02.png1000 × 1000 PX
CAPTURE / 03 OF 03
Operator dashboard showing pipeline state and review queue
/work/presswork/dashboard.png1000 × 1000 PX