diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index dcd97f309..b2fd79df8 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -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 diff --git a/gateway/platforms/discord.py b/gateway/platforms/discord.py index b3f128116..e8f5f69c1 100644 --- a/gateway/platforms/discord.py +++ b/gateway/platforms/discord.py @@ -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 diff --git a/gateway/session.py b/gateway/session.py index c93aba24a..b59196b81 100644 --- a/gateway/session.py +++ b/gateway/session.py @@ -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: