Daily Art engine: museum-guide blurb (grounded LLM) + extracted palette

- daily_art gains blurb + palette columns (idempotent migration).
- art._palette: Pillow median-cut to ~5 hex colors from the cached image (best-
  effort → [] on any failure). art._blurb: a warm 2-3 sentence "what you're
  looking at" note grounded in the Met catalogue (title/artist/bio/date/medium/
  classification/culture/tags). Prompt leans on context/significance and the
  title+tags for subject — explicitly NOT asserting literal composition (figure
  counts/poses) it can't see, since the model can't view the image. Markdown
  stripped from the output.
- pick_daily generates both (client optional → blurb skipped when absent); cycle
  + art CLI pass an LLM client. /api/art/today exposes blurb + palette.
- Backfilled the last 3 days on host (Veteran / Magnolia Vase / Bierstadt).
- scripts/art_blurb_palette_backfill.py for in-place backfill (no re-pick).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-23 20:12:54 -04:00
parent 79ecb800af
commit ed814c97b9
7 changed files with 172 additions and 10 deletions
+2
View File
@@ -2294,6 +2294,8 @@ def create_app() -> FastAPI:
"source": a["source"], "museum": museums.get(a["source"], a["source"]),
"is_public_domain": bool(a["is_public_domain"]),
"license": "Public Domain (CC0)" if a["is_public_domain"] else None,
"blurb": a.get("blurb"),
"palette": json.loads(a["palette"]) if a.get("palette") else [],
"image_url": f"/api/art/image/{a['object_id']}",
"image_url_large": f"/api/art/image/{a['object_id']}?size=full",
}