feat(gateway): include Discord channel topic in session context

Fixes #163

- Add chat_topic field to SessionSource dataclass
- Update to_dict/from_dict for serialization support
- Add chat_topic parameter to build_source helper
- Extract channel.topic in Discord adapter for messages and slash commands
- Display Channel Topic in system prompt when available
- Normalize empty topics to None
This commit is contained in:
Bartok Moltbot
2026-03-01 03:48:24 -05:00
parent 4d6f380bd1
commit 54147474d3
3 changed files with 21 additions and 1 deletions

View File

@@ -736,9 +736,13 @@ class BasePlatformAdapter(ABC):
chat_type: str = "dm",
user_id: Optional[str] = None,
user_name: Optional[str] = None,
thread_id: Optional[str] = None
thread_id: Optional[str] = None,
chat_topic: Optional[str] = None,
) -> SessionSource:
"""Helper to build a SessionSource for this platform."""
# Normalize empty topic to None
if chat_topic is not None and not chat_topic.strip():
chat_topic = None
return SessionSource(
platform=self.platform,
chat_id=str(chat_id),
@@ -747,6 +751,7 @@ class BasePlatformAdapter(ABC):
user_id=str(user_id) if user_id else None,
user_name=user_name,
thread_id=str(thread_id) if thread_id else None,
chat_topic=chat_topic.strip() if chat_topic else None,
)
@abstractmethod

View File

@@ -542,6 +542,9 @@ class DiscordAdapter(BasePlatformAdapter):
chat_name = interaction.channel.name
if hasattr(interaction.channel, "guild") and interaction.channel.guild:
chat_name = f"{interaction.channel.guild.name} / #{chat_name}"
# Get channel topic (if available)
chat_topic = getattr(interaction.channel, "topic", None)
source = self.build_source(
chat_id=str(interaction.channel_id),
@@ -549,6 +552,7 @@ class DiscordAdapter(BasePlatformAdapter):
chat_type=chat_type,
user_id=str(interaction.user.id),
user_name=interaction.user.display_name,
chat_topic=chat_topic,
)
msg_type = MessageType.COMMAND if text.startswith("/") else MessageType.TEXT
@@ -661,6 +665,9 @@ class DiscordAdapter(BasePlatformAdapter):
if isinstance(message.channel, discord.Thread):
thread_id = str(message.channel.id)
# Get channel topic (if available - TextChannels have topics, DMs/threads don't)
chat_topic = getattr(message.channel, "topic", None)
# Build source
source = self.build_source(
chat_id=str(message.channel.id),
@@ -669,6 +676,7 @@ class DiscordAdapter(BasePlatformAdapter):
user_id=str(message.author.id),
user_name=message.author.display_name,
thread_id=thread_id,
chat_topic=chat_topic,
)
# Build media URLs -- download image attachments to local cache so the

View File

@@ -44,6 +44,7 @@ class SessionSource:
user_id: Optional[str] = None
user_name: Optional[str] = None
thread_id: Optional[str] = None # For forum topics, Discord threads, etc.
chat_topic: Optional[str] = None # Channel topic/description (Discord, Slack)
@property
def description(self) -> str:
@@ -75,6 +76,7 @@ class SessionSource:
"user_id": self.user_id,
"user_name": self.user_name,
"thread_id": self.thread_id,
"chat_topic": self.chat_topic,
}
@classmethod
@@ -87,6 +89,7 @@ class SessionSource:
user_id=data.get("user_id"),
user_name=data.get("user_name"),
thread_id=data.get("thread_id"),
chat_topic=data.get("chat_topic"),
)
@classmethod
@@ -154,6 +157,10 @@ def build_session_context_prompt(context: SessionContext) -> str:
lines.append(f"**Source:** {platform_name} (the machine running this agent)")
else:
lines.append(f"**Source:** {platform_name} ({context.source.description})")
# Channel topic (if available - provides context about the channel's purpose)
if context.source.chat_topic:
lines.append(f"**Channel Topic:** {context.source.chat_topic}")
# User identity (especially useful for WhatsApp where multiple people DM)
if context.source.user_name: