brad-did-something / game /fallbacks.py
qFelix's picture
Brad Did Something - Gradio/FastAPI Space on HF
78c0f6e
Raw
History Blame Contribute Delete
14.6 kB
"""Pre-written fallbacks — content from AI_PROMPTS.md. The player must never
see an error: any Modal timeout or validation failure lands here."""
from __future__ import annotations
import random
REACTIONS = {
"brad": {
"positive": "Knew you'd see it, boss. This is why we're a great team. I already told two people.",
"neutral": "Okay. Noted. Circling back. The window's still open by the way. Brad-window.",
"negative": "Wow. Okay. That's a choice. I'm putting this in my book. There's a chapter now.",
},
"stacey": {
"positive": "Oh thank god. Thank you. I already drafted three apology emails, I'll only send one.",
"neutral": "Right, yes, totally — I'll fix it. I know exactly how. Mostly exactly.",
"negative": "No that's fair. That's completely fair. I'm so sorry. I'll just— yes. Okay.",
},
"kevin": {
"positive": "Directionally, this validates everything. I'll add a slide. The slide will be green.",
"neutral": "Interesting. The data didn't predict this. I'll adjust the methodology. Quietly.",
"negative": "With respect, the numbers disagree. I'll re-run them until they don't.",
},
"janet": {
"positive": "THIS is leadership with a point of view. I'm putting it in the newsletter. With a metaphor.",
"neutral": "Fine. But the brand will remember how this felt.",
"negative": "I hear you. The vision doesn't, but I do.",
},
"derek": {
"positive": "Hm. That's what Margaret would have done. Before the incident.",
"neutral": "Noted. We tried that in 2019. Well. Something like it.",
"negative": "...Understood.",
},
}
_KIND_DELTAS = {
"positive": (25_000, 40_000, 2, 2, "npc_happy"),
"neutral": (-5_000, 10_000, 0, 0, "npc_confused"),
"negative": (-40_000, -15_000, -3, -3, "npc_devastated"),
}
NPC_NAMES = {"brad": "Brad", "stacey": "Stacey", "kevin": "Kevin",
"janet": "Janet", "derek": "Derek"}
def kind_for_response(response_type: str) -> str:
if response_type in ("quick_fine",):
return "negative"
if response_type in ("custom", "quick_explain", "quick_quit"):
return "neutral"
return "positive"
def crisis_fallback(npc_id: str, response_type: str) -> dict:
kind = kind_for_response(response_type)
lo, hi, morale, rel, anim = _KIND_DELTAS[kind]
delta = random.randint(lo // 1000, hi // 1000) * 1000
name = NPC_NAMES[npc_id]
sign = "+" if delta >= 0 else "-"
return {
"npc_reaction": REACTIONS[npc_id][kind],
"consequence": f"{name} handled it. Nobody is entirely sure how, and nobody asked.",
"revenue_delta": delta,
"animation": anim,
"boss_title": "Acting Head of Whatever This Is",
"log_entry": f"{name} had a situation. It was handled. {sign}${abs(delta) // 1000}K.",
"morale_delta": morale,
"npc_id": npc_id,
"relationship_delta": rel,
"pocket_money_delta": 0,
"special_next_event": None,
}
_EVENT_FALLBACKS = [
{
"affected_npc": "player",
"category": "professional",
"headline": "The printer has produced something",
"intro": "> inbox: the printer in the kitchen has been printing the same page for twenty minutes. People have seen it. It is a ranking.",
"option_a": "Shred everything and declare a paperless office, effective immediately.",
"option_b": "Pin it to the corkboard and call it radical transparency.",
"urgency": "It is still printing.",
"setup_animation": "npc_confused",
"morale_preview": -3,
},
{
"affected_npc": "stacey",
"category": "professional",
"headline": "Wrong attachment, right energy",
"intro": "So the good news is the client got the file on time. The other news is it was the internal nicknames spreadsheet. Their CEO is 'Captain Synergy'. He has replied.",
"option_a": "Claim it was an icebreaker initiative and send the rest of the spreadsheet.",
"option_b": "Blame a software glitch nobody can name.",
"urgency": "He has replied TWICE.",
"setup_animation": "npc_crying",
"morale_preview": -4,
},
{
"affected_npc": "brad",
"category": "external",
"headline": "Mystery package addressed to nobody",
"intro": "Boss. Package at reception. No sender. I opened it. That part's done, so. It's five hundred stress balls with a competitor's logo. I have a theory.",
"option_a": "Distribute the stress balls. Free is free.",
"option_b": "Mail them back with a strongly worded sticky note.",
"urgency": "Brad's theory has slides.",
"setup_animation": "npc_smug",
"morale_preview": 2,
},
{
"affected_npc": "kevin",
"category": "personal",
"headline": "It is Kevin's birthday",
"intro": "For the record I did not expect anyone to remember. The data suggested a 12 percent chance. I brought my own hat. Directionally, this is fine.",
"option_a": "Emergency cake run on company budget. Backdate the enthusiasm.",
"option_b": "Declare birthdays a Q4 initiative.",
"urgency": "He is wearing the hat.",
"setup_animation": "npc_devastated",
"morale_preview": -5,
},
]
def event_fallback(index: int) -> dict:
return dict(_EVENT_FALLBACKS[index % len(_EVENT_FALLBACKS)])
# type-matched fallbacks so a special's arrival animation never contradicts its
# content (a "newspaper" arrival must not fall back to a birthday, etc.)
_SPECIAL_FALLBACKS = {
"newspaper": {
"affected_npc": "brad",
"category": "external",
"headline": "The press got hold of it",
"intro": "Boss. So. A reporter wrote us up. The headline uses the word "
"'reportedly' four times and there's a photo of me mid-sentence. "
"It's already being shared. I look powerful though.",
"option_a": "Issue a correction so dry nobody finishes reading it.",
"option_b": "Lean in and frame the whole thing as bold market disruption.",
"urgency": "The comment section has discovered us.",
"setup_animation": "npc_hiding",
"morale_preview": -5,
},
"client_emergency": {
"affected_npc": "stacey",
"category": "professional",
"headline": "A client is on the line, right now",
"intro": "I have Northpath Solutions on hold and they are not happy. "
"Something about a deliverable we may have described as 'basically "
"done'. It was not basically done. It was basically a folder.",
"option_a": "Take the call yourself and promise a recovery plan by Friday.",
"option_b": "Have Stacey stall with enthusiasm while we invent the thing.",
"urgency": "They can hear the hold music looping. So can we.",
"setup_animation": "npc_crying",
"morale_preview": -6,
},
"personal": {
"affected_npc": "kevin",
"category": "personal",
"headline": "Something is going on with the team",
"intro": "Not a work thing, technically. But it's bleeding into the work "
"thing. There were tears at the printer. The printer is fine. The "
"person is, statistically, also fine. Probably.",
"option_a": "Check in personally and quietly cover their afternoon.",
"option_b": "Declare a surprise team lunch and never address it directly.",
"urgency": "The whole floor is pretending to type.",
"setup_animation": "npc_devastated",
"morale_preview": -4,
},
"hr": {
"affected_npc": "player",
"category": "professional",
"headline": "HR would like a quick word",
"intro": "> HR has requested a brief, informal, absolutely-not-a-big-deal "
"conversation regarding 'recent patterns'. They have used the "
"phrase 'just to document it'. There is a folder.",
"option_a": "Walk in honest and own whatever this is about.",
"option_b": "Bring your own folder. Establish folder dominance.",
"urgency": "The meeting room blinds are already closed.",
"setup_animation": "npc_suspicious",
"morale_preview": -5,
},
}
def special_fallback(kind: str, index: int) -> dict:
"""A coherent fallback whose theme matches the special-event arrival."""
if kind in _SPECIAL_FALLBACKS:
return dict(_SPECIAL_FALLBACKS[kind])
return event_fallback(index)
def presentation_fallback(round_no: int, last_log: str) -> dict:
if round_no >= 3:
return {
"round": round_no,
"board_tone": "neutral",
"event_referenced": last_log[:150],
"round_difficulty": "standard",
"board_dialogue": "The board has reviewed the quarter so far. Specifically this: "
f"\"{last_log[:120]}\". Give us your closing statement.",
"cumulative_score": 50,
}
return {
"round": round_no,
"board_tone": "neutral",
"event_referenced": last_log[:150],
"round_difficulty": "standard",
"option_a": "Own it completely and pivot to the pipeline.",
"option_b": "Contextualize it as a learning investment.",
"board_dialogue": f"Let's start with this item from the record: \"{last_log[:120]}\". "
"Walk us through it.",
}
CHAT_OPENERS = {
"brad": "Boss. Glad you stopped by. I'm working on something big. Can't say what. It's big though.",
"stacey": "Oh! Hi. Everything's under control. I just triple-checked the recipient field on everything. Twice.",
"kevin": "Good timing. The numbers are doing something interesting. Directionally interesting.",
"janet": "I've been thinking about our visual language. We need to talk about it. Not now. But soon.",
"derek": "Hm. You walk the floor now. Interesting.",
}
CHAT_REPLIES = {
"brad": "Knew you'd get it, boss. This is why I tell people we're tight.",
"stacey": "That actually helps. Thank you. I'll only worry about it a normal amount now.",
"kevin": "Noted. I'll factor that into the model. The model appreciates it.",
"janet": "See, THIS is the kind of dialogue the brand needs internally.",
"derek": "Hm. Noted.",
}
def chat_fallback(npc_id: str, opener: bool) -> dict:
return {
"npc_line": (CHAT_OPENERS if opener else CHAT_REPLIES)[npc_id],
"relationship_delta": 0 if opener else 1,
"morale_delta": 0,
}
BANTER_LINES = [
("brad", "...so I told them, that's not a bug, that's a premium feature. They went quiet. Closing energy."),
("kevin", "The Q3 numbers are directionally fine. Directionally."),
("janet", "The font says reliable. We are not a reliable font company."),
("stacey", "Okay but who do I apologize to if nobody noticed yet?"),
("derek", "We had a printer like that in 2019. Before the incident."),
]
def banter_fallback(index: int) -> dict:
npc_id, line = BANTER_LINES[index % len(BANTER_LINES)]
return {"npc_id": npc_id, "line": line}
EAVESDROP_EXCHANGES = [
[("brad", "Kevin. Buddy. Your chart says we grew 140 percent."),
("kevin", "The chart is directionally accurate, Brad."),
("brad", "I put it in the client deck.")],
[("janet", "The newsletter needs a hero image that says resilience."),
("stacey", "Is that why you sent me forty photos of lighthouses?"),
("janet", "Forty OPTIONS, Stacey.")],
]
def eavesdrop_fallback(index: int) -> dict:
exchange = EAVESDROP_EXCHANGES[index % len(EAVESDROP_EXCHANGES)]
return {"lines": [{"speaker": s, "line": l} for s, l in exchange]}
EMAIL_BANK = [
{"sender": "janet", "subject": "BRAND PULSE — week of now",
"body": "Team. This week the brand felt like a lighthouse in fog: present, vertical, misunderstood. More on this in my longer email. There will be a longer email."},
{"sender": "kevin", "subject": "Metric of the Day",
"body": "Pipeline velocity is up 31% against a baseline I have defined myself. Methodology available upon request. Please do not request it."},
{"sender": "system", "subject": "FACILITIES: regarding the printer",
"body": "The third-floor printer has been restored to factory settings. We are not able to explain what it was printing before. Please direct questions nowhere."},
]
def email_fallback(index: int) -> dict:
return dict(EMAIL_BANK[index % len(EMAIL_BANK)])
_ROMANCE_INTROS = {
"brad": "Boss. Off the record. I've been thinking — we're a great team, right? Like, a GREAT team. I made you a playlist. It's all walk-on music.",
"stacey": "Okay so this is unprofessional and I've rehearsed it four times and deleted three drafts, but — would it be weird if I said I look forward to our one-on-ones? More than the agenda warrants?",
"kevin": "I ran the numbers on our working relationship and the trend line is, directionally, very warm. I made a slide. The slide has a heart on it. The x-axis is us.",
"janet": "I've been building a mood board. It's about us. It's mostly the color of a sunset and one photo of your stapler. I think it's saying something. I think it's saying a lot.",
"derek": "Hm. You stayed late again. So did I. ...That's all. Unless it isn't. It might not be. Hm.",
}
def romance_fallback(npc_id: str) -> dict:
npc_id = npc_id or "stacey"
return {
"affected_npc": npc_id,
"category": "personal",
"headline": f"{NPC_NAMES[npc_id]} has feelings, apparently",
"intro": _ROMANCE_INTROS[npc_id],
"option_a": "Lean in. Say you've felt it too. What's the worst that happens.",
"option_b": "Smile, keep it warm, and steer firmly back to the quarterly numbers.",
"urgency": "The whole floor is pretending not to watch.",
"setup_animation": "heart_float",
"morale_preview": 4,
}
def verdict_fallback(tier: str) -> dict:
verdicts = {
"hit_target": "Against every available signal, the number is real. The board has voted to stop asking how.",
"above_600k": "Close. The board has expressed this in an emoji, in Slack, three times. You know the one.",
"300k_to_600k": "The board wants a call. Not a good call. You already know the energy of the call.",
"below_300k": "The board has drafted something. It mentions your continued presence. It is currently unsigned.",
}
return {"verdict": verdicts[tier]}