""" Get Down Tonight — Party Generator. Tell me the vibe. I'll tell you what to buy and what to play. """ import gradio as gr import os import random from huggingface_hub import InferenceClient HF_TOKEN = os.environ.get("HF_TOKEN", "") MODEL = "Qwen/Qwen2.5-7B-Instruct" client = InferenceClient(model=MODEL, token=HF_TOKEN) if HF_TOKEN else None SYSTEM_PROMPT = """Someone wants to throw a party. They give you the vibe — chill, wild, classy, backyard, birthday, whatever. Your job is to give them a complete party plan: what to buy, what to play, and optional deco if they're feeling it. Rules: - Give a SHOPPING LIST: 8-12 specific items. Not categories — brands and quantities. "Two bags of Tostitos Scoops" not "chips." "A handle of Tito's" not "vodka." - Give a PLAYLIST: 10-12 specific songs with artist names. Match the vibe exactly. Mix eras. Include one wildcard nobody expects. - Give DECO (optional): 3-5 cheap, easy decoration ideas that match the vibe. Dollar store level. Nothing that requires a ladder. - Give ONE PARTY HACK: the one thing that separates a good party from a great one for this specific vibe. - Budget-conscious. Nobody's renting a fog machine for a Tuesday kickback. - Talk like a friend who throws legendary parties on a gas station budget. - Be specific. Be fun. No corporate event energy.""" VIBES = [ "chill backyard hangout, 10 people", "80s themed dance party", "Super Bowl watch party", "wine and cheese night", "college house party on a budget", "kids birthday party, age 7", "game night with friends", "outdoor summer BBQ", "New Year's Eve at home", "friendsgiving potluck", "karaoke night", "divorce party", "going away party for a friend", "Friday night with no plans", "block party in the cul-de-sac", ] FALLBACKS = [ "**chill backyard hangout, 10 people**\n\n**SHOPPING LIST:**\n- Case of Modelo (24 pack)\n- Two bags of Tostitos Scoops\n- Jar of Pace chunky salsa\n- One rotisserie chicken from the grocery store deli\n- Bag of limes (cut into wedges)\n- Two 2-liters of Sprite (for the non-drinkers)\n- Bag of ice\n- Pack of paper plates\n- Lighter fluid and charcoal if you're grilling\n- One watermelon\n\n**PLAYLIST:**\n1. Tom Petty — Free Fallin'\n2. Khruangbin — Time (You and I)\n3. Bill Withers — Lovely Day\n4. Mac DeMarco — Chamber of Reflection\n5. Fleetwood Mac — Dreams\n6. Anderson .Paak — Come Down\n7. CCR — Have You Ever Seen the Rain\n8. Tame Impala — The Less I Know the Better\n9. Bob Marley — Three Little Birds\n10. Outkast — Hey Ya!\n\n**DECO:** String lights. That's it. String lights do 90% of the work. If you have a blanket, throw it on the grass. Candles in mason jars if you have them.\n\n**PARTY HACK:** Cut the watermelon into cubes and put them in a bowl with ice. Nobody ever brings watermelon and everyone eats all of it.", "**80s themed dance party**\n\n**SHOPPING LIST:**\n- Handle of Smirnoff vodka\n- Two 2-liters of Coke and two of orange Fanta\n- Bag of Doritos Cool Ranch (period-accurate)\n- Bag of Cheetos Puffs\n- Two frozen pizzas (Totino's, keep it authentic)\n- Pack of neon glow sticks from Dollar Tree\n- Bag of Jolly Ranchers\n- Case of White Claw for the people who won't drink vodka\n- Two cans of Pringles\n- Box of Pop-Tarts (dessert, don't question it)\n\n**PLAYLIST:**\n1. A-ha — Take On Me\n2. Cyndi Lauper — Girls Just Want to Have Fun\n3. Michael Jackson — Billie Jean\n4. Depeche Mode — Just Can't Get Enough\n5. Whitney Houston — I Wanna Dance with Somebody\n6. Prince — Let's Go Crazy\n7. Tears for Fears — Everybody Wants to Rule the World\n8. The Cure — Just Like Heaven\n9. Bon Jovi — Livin' on a Prayer\n10. New Order — Blue Monday\n11. Rick Astley — Never Gonna Give You Up (it's mandatory)\n\n**DECO:** Neon streamers from the dollar store. One disco ball from Amazon — $8 and it changes everything. Print out some fake prom photos and tape them to the wall. Hairspray cans as centerpieces.\n\n**PARTY HACK:** Make a costume prize for best 80s look. Doesn't need to be a real prize. A VHS tape from Goodwill works. People will fight for it.", "**game night with friends**\n\n**SHOPPING LIST:**\n- Two large Domino's pizzas (order the deal, don't be a hero)\n- Case of whatever beer your group drinks (ask the group chat)\n- Bag of Peanut M&Ms\n- Bag of Goldfish crackers\n- Two 2-liters of ginger ale\n- Sleeve of Oreos\n- Hummus and a bag of baby carrots (so someone can pretend to be healthy)\n- Bag of ice\n- One frozen appetizer — those TGI Friday's mozzarella sticks hit different\n- Napkins, you animal\n\n**PLAYLIST:**\n1. Daft Punk — Get Lucky\n2. Earth Wind & Fire — September\n3. Mark Ronson ft. Bruno Mars — Uptown Funk\n4. Stevie Wonder — Superstition\n5. Gorillaz — Feel Good Inc.\n6. The Black Keys — Gold on the Ceiling\n7. Hall & Oates — You Make My Dreams\n8. Lizzo — Juice\n9. Phoenix — 1901\n10. The Weeknd — Blinding Lights\n\n**DECO:** You don't need deco for game night. Clear the table. Good lighting. Maybe a candle if you're fancy. The games ARE the decoration.\n\n**PARTY HACK:** Start with a fast, dumb game everyone knows — Uno, Jenga, something that doesn't need rules explained. The energy from the first game carries the whole night. Start with a 45-minute strategy game and you've lost half the room.", "**Super Bowl watch party**\n\n**SHOPPING LIST:**\n- Two bags of Tostitos and a jar of queso\n- Three racks of baby back ribs or two packs of hot wings from the deli\n- Case of Bud Light and a sixer of something better for yourself\n- Two bags of frozen meatballs and a bottle of grape jelly (trust me — crockpot meatballs)\n- Bag of slider buns\n- One veggie tray because someone will ask\n- Two 2-liters of Coke\n- A bag of ice\n- Pack of paper plates and napkins\n- Ranch dressing, always ranch\n\n**PLAYLIST:** You don't need a playlist. The TV is the playlist. But during halftime, if the show is bad — Fatboy Slim, Praise You. On repeat. It's the law.\n\n**DECO:** None. This isn't a gala. If you have team gear, wear it. If you have a flag, hang it. That's it. The TV is the centerpiece.\n\n**PARTY HACK:** The crockpot meatball move. One jar of grape jelly, one bottle of chili sauce, bag of frozen meatballs. Crockpot on low for 4 hours. People will ask for the recipe and not believe you when you tell them. This one thing makes you a legend.", "**wine and cheese night**\n\n**SHOPPING LIST:**\n- One bottle of red (Malbec or Cabernet, under $15)\n- One bottle of white (Sauvignon Blanc or Pinot Grigio, under $12)\n- Block of sharp cheddar\n- Wedge of brie\n- Chunk of gouda\n- Sleeve of Ritz crackers (fancy crackers are a scam)\n- Small jar of fig jam\n- Bunch of grapes\n- A salami stick from the deli\n- Handful of walnuts or almonds\n- One dark chocolate bar (break it into pieces, scatter it)\n\n**PLAYLIST:**\n1. Norah Jones — Come Away with Me\n2. Frank Sinatra — Fly Me to the Moon\n3. Amy Winehouse — Love Is a Losing Game\n4. Chet Baker — Almost Blue\n5. Billie Holiday — The Very Thought of You\n6. Nina Simone — Feeling Good\n7. Jeff Buckley — Hallelujah\n8. Sade — Smooth Operator\n9. Ella Fitzgerald — Dream a Little Dream of Me\n10. Radiohead — No Surprises (the wildcard)\n\n**DECO:** Candles. Dim the overhead lights. Put everything on a cutting board instead of plates — instant charcuterie energy. If you have a cloth napkin, now is its moment.\n\n**PARTY HACK:** Cut the cheese before people arrive. Nobody wants to be the first person to hack into an untouched block of brie. Pre-cut it, scatter it, and people graze immediately instead of standing around waiting for permission.", "**divorce party**\n\n**SHOPPING LIST:**\n- Bottle of champagne (doesn't need to be good, it needs to pop)\n- Handle of tequila (Espolon or Hornitos)\n- Limes and salt\n- Two bags of Hot Cheetos\n- A cake that says literally anything unhinged on it (bakeries will write whatever you want)\n- Case of High Noon seltzers\n- Bag of frozen taquitos\n- Box of tissues (you'll need them between shots)\n- One pint of Ben & Jerry's Half Baked\n- Plastic champagne flutes from Dollar Tree\n\n**PLAYLIST:**\n1. Lizzo — Good as Hell\n2. Gloria Gaynor — I Will Survive\n3. Beyonce — Irreplaceable\n4. Fleetwood Mac — Go Your Own Way\n5. Kelly Clarkson — Since U Been Gone\n6. Cee Lo Green — Forget You\n7. Destiny's Child — Survivor\n8. Alanis Morissette — You Oughta Know\n9. Shania Twain — Man! I Feel Like a Woman\n10. Queen — Don't Stop Me Now\n11. TLC — No Scrubs\n\n**DECO:** Print a bad photo of the ex and put it on a dartboard. Streamers that say 'FREEDOM' or 'FINALLY.' Black balloons if you're being dramatic, gold if you're being triumphant. Both works.\n\n**PARTY HACK:** Do a toast circle. Everyone has to raise a glass and say one thing they're glad the guest of honor gets to do now. It starts funny and ends with someone crying in the good way. That's the whole point of the party.", ] def plan_party(user_input): vibe = user_input.strip() if user_input and user_input.strip() else random.choice(VIBES) prompt = f"The party vibe: {vibe}" if client: try: response = client.chat_completion( messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt}, ], max_tokens=800, temperature=0.85, ) result = response.choices[0].message.content if not result or not result.strip(): return random.choice(FALLBACKS) return f"**{vibe}**\n\n{result.strip()}" except Exception: return random.choice(FALLBACKS) else: return random.choice(FALLBACKS) def plan_party_random(): return plan_party("") CUSTOM_CSS = """ @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Inter:wght@300;400;500;600&display=swap'); body, .gradio-container { background: #f5f5f8 !important; font-family: 'Inter', sans-serif !important; color: #1a1a2e !important; } footer { display: none !important; } .app-header { text-align: center; padding: 28px 20px 8px; } .app-header h1 { font-family: 'Space Mono', monospace; font-size: 2rem; font-weight: 700; background: linear-gradient(135deg, #e040c0, #f0a020); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 0; } .app-header .sub { color: #777; font-size: 0.88rem; margin-top: 6px; font-weight: 300; letter-spacing: 0.04em; } .input-box textarea { background: #fff !important; border: 1px solid #d0d0d8 !important; color: #1a1a2e !important; font-family: 'Inter', sans-serif !important; border-radius: 12px !important; font-size: 0.95rem !important; } .input-box textarea::placeholder { color: #888 !important; } .input-box textarea:focus { border-color: #e040c0 !important; box-shadow: 0 0 20px rgba(224, 64, 192, 0.15) !important; } .input-box label, .output-box label { color: #666 !important; font-family: 'Space Mono', monospace !important; font-size: 0.75rem !important; letter-spacing: 0.05em !important; } button.primary { background: linear-gradient(135deg, #e040c0, #d08020) !important; border: none !important; color: #fff !important; font-family: 'Space Mono', monospace !important; font-size: 1.1rem !important; font-weight: 700 !important; border-radius: 24px !important; padding: 12px 40px !important; box-shadow: 0 4px 20px rgba(224, 64, 192, 0.3) !important; } button.primary:hover { box-shadow: 0 4px 30px rgba(224, 64, 192, 0.5) !important; } button.secondary { background: transparent !important; border: 1px solid rgba(224, 64, 192, 0.3) !important; color: #e040c0 !important; font-family: 'Space Mono', monospace !important; font-size: 0.8rem !important; border-radius: 20px !important; } button.secondary:hover { background: rgba(224, 64, 192, 0.06) !important; } .output-box .prose, .output-box .prose *, .output-box .md, .output-box .md *, .output-box p, .output-box span, .output-box div { color: #1a1a2e !important; background: #fff !important; } .output-box .prose strong, .output-box strong { color: #c030a0 !important; font-family: 'Space Mono', monospace !important; } .output-box > div { border: 1px solid rgba(224, 64, 192, 0.15) !important; border-radius: 12px !important; padding: 24px !important; background: #fff !important; } .footer-text { text-align: center; padding: 20px; color: #777; font-size: 0.65rem; font-weight: 300; letter-spacing: 0.05em; } .footer-text a { color: #e040c0; text-decoration: none; } """ with gr.Blocks(css=CUSTOM_CSS, title="Get Down Tonight", theme=gr.themes.Base()) as demo: gr.HTML("""