Add a separate llm_chat client so chat responses use a smarter model
(gpt-4o-mini) while analysis stays on the cheap local Qwen3-8B.
Falls back to llm_heavy if LLM_CHAT_MODEL is not set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The model dumps paraphrased context and style labels in [brackets]
before its actual roast. Instead of just removing bracket lines
(which leaves the preamble text), split on them and keep only the
last non-empty segment — the real answer is always last.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The model paraphrases injected metadata in unpredictable ways, so
targeted regexes can't keep up. Replace them with a single rule: any
[bracketed block] on its own line gets removed, since real roasts
never use standalone brackets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add frequency_penalty (0.8) and presence_penalty (0.6) to LLM chat
calls to discourage repeated tokens. Inject the bot's last 5 responses
into the system prompt so the model knows what to avoid. Strengthen
the roast prompt with explicit anti-repetition rules and remove example
lines the model was copying verbatim ("Real ___ energy", etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the bot replies (proactive or mentioned), it now fetches the
user's drama tracker notes and their last ~10 messages in the channel.
Gives the LLM real context for personalized replies instead of
generic roasts on bare pings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Proactive replies used channel.send() which posted standalone messages
with no visual link to what triggered them. Now all replies use
message.reply() so the response is always attached to the source message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Send as a channel message instead of message.reply() so it doesn't
look like the bot is talking to itself.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reply to any message + @bot to have the bot read and respond to it.
Also picks up image attachments from referenced messages so users
can reply to a photo with "@bot roast this".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The prompt was scoreboard-only, so selfies got nonsensical stat-based
roasts. Now the LLM identifies what's in the image and roasts accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Broader regex to strip leaked metadata even when the LLM drops
the "Server context:" prefix but keeps the content.
2. Skip sentiment analysis for messages that mention or reply to
the bot. Users interacting with the bot in roast/chat modes
shouldn't have those messages inflate their drama score.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When someone reacts to the bot's message, there's a 50% chance it
fires back with a reply commenting on their emoji choice, in
character for the current mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The local LLM was echoing back [Server context: ...] metadata lines
in its responses despite prompt instructions not to. Now stripped
via regex before sending to Discord.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a user replies to the bot's message, the original bot message
text is now included in the context sent to the LLM. This prevents
the LLM from misinterpreting follow-up questions like "what does
this even mean?" since it can see what message is being referenced.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a server-wide mode system with /bcs-mode command.
- Default: current hall-monitor behavior unchanged
- Chatty: friendly chat participant with proactive replies (~10% chance)
- Roast: savage roast mode with proactive replies
- Chatty/roast use relaxed moderation thresholds
- 5-message cooldown between proactive replies per channel
- Bot status updates to reflect active mode
- /bcs-status shows current mode and effective thresholds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only inject drama score/offense context when values are noteworthy
(score >= 0.2 or offenses > 0). Update personality prompt to avoid
harping on zero scores and vary responses more.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the LLM is offline, post to #bcs-log instead of sending
the "brain offline" message in chat.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- spike_mute: 0.8→0.7, mute: 0.75→0.65 so escalating users get
timed out after a warning instead of endlessly warned
- Skip debounce on @mentions so sentiment analysis fires immediately
- Chat cog awaits pending sentiment analysis before replying,
ensuring warnings/mutes appear before the personality response
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Triage model (LLM_MODEL) handles every message cheaply. If toxicity
>= 0.25, off_topic, or coherence < 0.6, the message is re-analyzed
with the heavy model (LLM_ESCALATION_MODEL). Chat, image analysis,
/bcs-test, and /bcs-scan always use the heavy model.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When @mentioned with an image attachment, the bot now roasts players
based on scoreboard screenshots using the vision model. Text-only
mentions continue to work as before.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Serialize all LLM requests through an asyncio semaphore to prevent
overloading athena with concurrent requests
- Switch chat() to streaming so the typing indicator only appears once
the model starts generating (not during thinking/loading)
- Increase LLM timeout from 5 to 10 minutes for slow first loads
- Rename ollama_client.py to llm_client.py and self.ollama to self.llm
since the bot uses a generic OpenAI-compatible API
- Update embed labels from "Ollama" to "LLM"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the analysis and chat personality system prompts from inline Python
strings to prompts/analysis.txt and prompts/chat_personality.txt for
easier editing. Also add a rule so users quoting/reporting what someone
else said are not penalized for the quoted words.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Discord bot for monitoring chat sentiment and tracking drama using
Ollama LLM on athena.lan. Includes sentiment analysis, slash commands,
drama tracking, and SQL Server persistence via Docker Compose.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>