feat: move user aliases from config to DB with /bcs-alias command

Aliases now stored in UserState table instead of config.yaml. Adds
Aliases column (NVARCHAR 500), loads on startup, persists via flush.
New /bcs-alias slash command (view/set/clear) for managing nicknames.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 10:35:19 -05:00
parent ad1234ec99
commit 33d56f8737
6 changed files with 124 additions and 28 deletions
+9 -12
View File
@@ -253,18 +253,18 @@ class SentimentCog(commands.Cog):
"""Replace display name keys with anonymous keys in user notes map."""
return {anon_map.get(name, name): notes for name, notes in user_notes_map.items()}
@staticmethod
def _build_alias_context(
self,
messages: list[discord.Message],
anon_map: dict[str, str],
alias_config: dict,
) -> str:
"""Build anonymized alias context string for the LLM.
Maps user IDs from messages to their known nicknames using the
config, then replaces display names with anonymous keys.
Maps user IDs from messages to their known nicknames from
DramaTracker, then replaces display names with anonymous keys.
"""
if not alias_config:
all_aliases = self.bot.drama_tracker.get_all_aliases()
if not all_aliases:
return ""
lines = []
seen_ids: set[int] = set()
@@ -273,14 +273,13 @@ class SentimentCog(commands.Cog):
if uid in seen_ids:
continue
seen_ids.add(uid)
aliases = alias_config.get(uid)
aliases = all_aliases.get(uid)
if aliases:
anon_key = anon_map.get(msg.author.display_name, msg.author.display_name)
lines.append(f" {anon_key} is also known as: {', '.join(aliases)}")
# Also include aliases for members NOT in the conversation (so the LLM
# can recognize name-drops of absent members)
for uid, aliases in alias_config.items():
uid = int(uid) if isinstance(uid, str) else uid
for uid, aliases in all_aliases.items():
if uid not in seen_ids:
lines.append(f" (not in chat) also known as: {', '.join(aliases)}")
return "\n".join(lines) if lines else ""
@@ -498,8 +497,7 @@ class SentimentCog(commands.Cog):
anon_conversation = self._anonymize_conversation(conversation, anon_map)
anon_notes = self._anonymize_notes(user_notes_map, anon_map) if user_notes_map else user_notes_map
alias_config = config.get("user_aliases", {})
alias_context = self._build_alias_context(all_messages, anon_map, alias_config)
alias_context = self._build_alias_context(all_messages, anon_map)
channel_context = build_channel_context(ref_message, game_channels)
@@ -675,8 +673,7 @@ class SentimentCog(commands.Cog):
anon_conversation = self._anonymize_conversation(conversation, anon_map)
anon_notes = self._anonymize_notes(user_notes_map, anon_map) if user_notes_map else user_notes_map
alias_config = config.get("user_aliases", {})
alias_context = self._build_alias_context(raw_messages, anon_map, alias_config)
alias_context = self._build_alias_context(raw_messages, anon_map)
channel_context = build_channel_context(raw_messages[0], game_channels)
mention_context = (