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:
@@ -273,6 +273,8 @@ CREATE TABLE IF NOT EXISTS daily_art (
|
||||
image_file TEXT, -- our cached (web-large) image
|
||||
image_url_full TEXT, -- source full-res URL, for a later richer /art view
|
||||
is_public_domain INTEGER, -- license marker (CC0/public domain), stored for citizenship
|
||||
blurb TEXT, -- LLM "museum guide" note: what you're looking at (cached)
|
||||
palette TEXT, -- JSON array of hex colors extracted from the image
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
@@ -640,6 +642,9 @@ def _migrate(conn: sqlite3.Connection) -> None:
|
||||
conn.execute("ALTER TABLE daily_art ADD COLUMN image_url_full TEXT")
|
||||
if art_cols and "is_public_domain" not in art_cols:
|
||||
conn.execute("ALTER TABLE daily_art ADD COLUMN is_public_domain INTEGER")
|
||||
for column in ("blurb", "palette"): # richer /art page: guide note + extracted colors
|
||||
if art_cols and column not in art_cols:
|
||||
conn.execute(f"ALTER TABLE daily_art ADD COLUMN {column} TEXT")
|
||||
|
||||
# feedback.read_at (admin inbox read/unread) added later.
|
||||
fb_cols = {row["name"] for row in conn.execute("PRAGMA table_info(feedback)")}
|
||||
|
||||
Reference in New Issue
Block a user