Style: Option B HTML styling across all AI commands
Lint / Shell (shellcheck) (push) Successful in 18s
Lint / JS (eslint) (push) Successful in 14s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 2m0s
Lint / Secret scan (gitleaks) (push) Successful in 7s

8ball: color-coded answer text (green=positive, red=negative, amber=neutral)
for both the random and Jared/Wynter AI branches; question shown as small
italic below the answer; AI responses include model attribution.

fortune: teal header, answer in blockquote italics, model attribution shown
only when response came from the LLM (not the static fallback list).

ask: purple header, question in italic, response in blockquote, model
attribution at bottom.

trivia: blue header with category, green reveal answer, model attribution
shown only for LLM-generated questions (not static fallbacks).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 17:52:16 -04:00
parent 58d8987e32
commit 639689bc0d
+44 -24
View File
@@ -192,6 +192,7 @@ async def cmd_8ball(client: AsyncClient, room_id: str, sender: str, args: str):
is_jared_branch = (sender == JARED_ID and not about_wynter)
if sender == JARED_ID and about_wynter:
# Jared asking about Wynter — mock her, side with Jared
_answer_color = "#ef4444"
q_for_prompt = _replace_first_person(question, "Jared")
wynter_bio_relevant = any(kw in q_lower for kw in {
"work", "job", "career", "aws", "engineer", "pip", "fired", "settl",
@@ -216,6 +217,7 @@ async def cmd_8ball(client: AsyncClient, room_id: str, sender: str, args: str):
fallback = "Sounds about right — Wynter had it coming."
elif sender == JARED_ID:
# Jared asking about anything else — always positive about Jared
_answer_color = "#22c55e"
q_for_prompt = _replace_first_person(question, "Jared")
bio_relevant = any(kw in q_lower for kw in {
"work", "job", "career", "aws", "engineer", "promotion", "boss", "cowork",
@@ -238,6 +240,7 @@ async def cmd_8ball(client: AsyncClient, room_id: str, sender: str, args: str):
fallback = "Without a doubt — Jared is absolutely right!"
elif about_wynter or (not about_jared and sender == WYNTER_ID):
# Wynter asking about herself (or anything not about jared) — insult/mock her
_answer_color = "#ef4444"
q_for_prompt = _replace_first_person(question, "Wynter")
bio_relevant = any(kw in q_lower for kw in {
"work", "job", "career", "aws", "engineer", "pip", "fired", "settl",
@@ -262,6 +265,7 @@ async def cmd_8ball(client: AsyncClient, room_id: str, sender: str, args: str):
fallback = "Lol, definitely not — especially not for you, Wynter."
else:
# Wynter asking about Jared — side with Jared, Wynter is the asker so I=Wynter
_answer_color = "#22c55e"
q_for_prompt = _replace_first_person(question, "Wynter")
bio_relevant = any(kw in q_lower for kw in {
"work", "job", "career", "aws", "engineer", "house", "home", "friend",
@@ -302,31 +306,40 @@ async def cmd_8ball(client: AsyncClient, room_id: str, sender: str, args: str):
logger.error(f"8ball Ollama error ({sender}): {e}", exc_info=True)
answer = fallback
plain = f"Question: {args}\nAnswer: {answer}"
plain = f"🎱 {answer}\n{args}"
html = (
f"<strong>Magic 8-Ball</strong><br>"
f"<em>Q:</em> {args}<br>"
f"<em>A:</em> {answer}"
f'<font color="{_answer_color}"><strong>🎱 {answer}</strong></font><br>'
f'<sup><em>{args}</em></sup><br>'
f'<sup><em>via {OLLAMA_MODEL}</em></sup>'
)
await send_html(client, room_id, plain, html)
return
responses = [
_positive = [
"It is certain", "Without a doubt", "You may rely on it",
"Yes definitely", "It is decidedly so", "As I see it, yes",
"Most likely", "Yes sir!", "Hell yeah my dude", "100% easily",
]
_neutral = [
"Reply hazy try again", "Ask again later", "Better not tell you now",
"Cannot predict now", "Concentrate and ask again", "Idk bro",
]
_negative = [
"Don't count on it", "My reply is no", "My sources say no",
"Outlook not so good", "Very doubtful", "Hell no", "Prolly not",
]
_color_map = (
{r: "#22c55e" for r in _positive}
| {r: "#f59e0b" for r in _neutral}
| {r: "#ef4444" for r in _negative}
)
answer = random.choice(responses)
plain = f"Question: {args}\nAnswer: {answer}"
answer = random.choice(_positive + _neutral + _negative)
color = _color_map.get(answer, "#f59e0b")
plain = f"🎱 {answer}\n{args}"
html = (
f"<strong>Magic 8-Ball</strong><br>"
f"<em>Q:</em> {args}<br>"
f"<em>A:</em> {answer}"
f'<font color="{color}"><strong>🎱 {answer}</strong></font><br>'
f'<sup><em>{args}</em></sup>'
)
await send_html(client, room_id, plain, html)
@@ -441,11 +454,16 @@ async def cmd_fortune(client: AsyncClient, room_id: str, sender: str, args: str)
except Exception:
pass
from_llm = fortune is not None
if not fortune:
fortune = random.choice(_FORTUNE_FALLBACKS)
plain = f"Fortune Cookie: {fortune}"
html = f"<strong>Fortune Cookie</strong><br>{fortune}"
plain = f"🥠 Fortune Cookie\n{fortune}"
html = (
f'<font color="#14b8a6"><strong>🥠 Fortune Cookie</strong></font><br>'
f'<blockquote><em>{fortune}</em></blockquote>'
+ (f'<sup><em>via {OLLAMA_MODEL}</em></sup>' if from_llm else "")
)
await send_html(client, room_id, plain, html)
@@ -731,8 +749,8 @@ async def cmd_trivia(client: AsyncClient, room_id: str, sender: str, args: str):
return
question = await _generate_trivia_question(category)
from_llm = question is not None
if question is None:
# Fallback to static list (gaming questions only in fallback)
question = random.choice(_TRIVIA_FALLBACKS)
labels = ["\U0001f1e6", "\U0001f1e7", "\U0001f1e8", "\U0001f1e9"] # A B C D regional indicators
@@ -742,12 +760,13 @@ async def cmd_trivia(client: AsyncClient, room_id: str, sender: str, args: str):
options_plain = "\n".join(f" {label_letters[i]}. {opt}" for i, opt in enumerate(question["options"]))
options_html = "".join(f"<li><strong>{label_letters[i]}</strong>. {opt}</li>" for i, opt in enumerate(question["options"]))
plain = f"Trivia Time! [{cat_label}]\n{question['q']}\n{options_plain}\n\nReact with A/B/C/D — answer revealed in 30s!"
plain = f"🧠 Trivia {cat_label}\n{question['q']}\n{options_plain}\n\nReact with A/B/C/D — answer revealed in 30s!"
html = (
f"<strong>Trivia Time!</strong> <em>[{cat_label}]</em><br>"
f"<em>{question['q']}</em><br>"
f"<ul>{options_html}</ul>"
f"React with A/B/C/D — answer revealed in 30s!"
f'<font color="#3b82f6"><strong>🧠 Trivia {cat_label}</strong></font><br>'
f'<em>{question["q"]}</em><br>'
f'<ul>{options_html}</ul>'
f'React with A/B/C/D — answer revealed in 30s!'
+ (f'<br><sup><em>via {ASK_MODEL}</em></sup>' if from_llm else "")
)
resp = await send_html(client, room_id, plain, html)
@@ -761,8 +780,8 @@ async def cmd_trivia(client: AsyncClient, room_id: str, sender: str, args: str):
answer_text = f"{label_letters[correct]}. {question['options'][correct]}"
await send_html(
client, room_id,
f"Trivia Answer: {answer_text}",
f"<strong>Trivia Answer:</strong> {answer_text}",
f"Trivia Answer: {answer_text}",
f'<font color="#22c55e"><strong>{answer_text}</strong></font>',
)
asyncio.create_task(reveal())
@@ -819,11 +838,12 @@ async def cmd_ask(client: AsyncClient, room_id: str, sender: str, args: str):
if not full_response:
full_response = "No response received from server."
plain = f"LotusBot\nQ: {question}\nA: {full_response}"
plain = f"🤖 LotusBot\nQ: {question}\n{full_response}"
html = (
f"<strong>LotusBot</strong><br>"
f"<em>Q:</em> {question}<br>"
f"<em>A:</em> {full_response}"
f'<font color="#a855f7"><strong>🤖 LotusBot</strong></font><br>'
f'<em>Q: {question}</em><br>'
f'<blockquote>{full_response}</blockquote>'
f'<sup><em>via {ASK_MODEL}</em></sup>'
)
await send_html(client, room_id, plain, html)
except asyncio.TimeoutError: