Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion agent/title_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,19 @@ def auto_title_session(
return

try:
session_db.set_session_title(session_id, title)
set_if_empty = getattr(session_db, "set_session_title_if_empty", None)
if callable(set_if_empty):
title_set = bool(set_if_empty(session_id, title))
else:
# Backward-compatible path for older/custom session stores. Re-check
# immediately before writing so user-set titles that landed during
# generation are less likely to be overwritten.
if session_db.get_session_title(session_id):
return
title_set = bool(session_db.set_session_title(session_id, title))
if not title_set:
logger.debug("Skipped auto-generated title because session title is no longer empty")
return
logger.debug("Auto-generated session title: %s", title)
if title_callback is not None:
try:
Expand Down
13 changes: 13 additions & 0 deletions gateway/platforms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2326,6 +2326,7 @@ def __init__(self, config: PlatformConfig, platform: Platform):
self.config = config
self.platform = platform
self._message_handler: Optional[MessageHandler] = None
self._thread_title_handler: Optional[Callable[[Platform, str, str], Awaitable[None]]] = None
# Optional hook (e.g. Telegram DM topic recovery) that rewrites
# ``event.source.thread_id`` before session keying. Returns the
# corrected thread_id or None to leave the source untouched.
Expand Down Expand Up @@ -2666,6 +2667,16 @@ def _should_auto_tts_for_chat(self, chat_id: str) -> bool:
def set_fatal_error_handler(self, handler: Callable[["BasePlatformAdapter"], Awaitable[None] | None]) -> None:
self._fatal_error_handler = handler

def set_thread_title_handler(self, handler: Optional[Callable[[Platform, str, str], Awaitable[None]]]) -> None:
"""Set an optional handler for platform thread-title changes."""
self._thread_title_handler = handler

async def _notify_thread_title_change(self, thread_id: str, title: str) -> None:
handler = self._thread_title_handler
if not handler or not thread_id or not title:
return
await handler(self.platform, str(thread_id), str(title))

def _mark_connected(self) -> None:
self._running = True
self._fatal_error_code = None
Expand Down Expand Up @@ -5445,6 +5456,7 @@ def build_source(
parent_chat_id: Optional[str] = None,
message_id: Optional[str] = None,
role_authorized: bool = False,
thread_initial_name: Optional[str] = None,
) -> SessionSource:
"""Helper to build a SessionSource for this platform."""
# Normalize empty topic to None
Expand All @@ -5466,6 +5478,7 @@ def build_source(
parent_chat_id=str(parent_chat_id) if parent_chat_id else None,
message_id=str(message_id) if message_id else None,
role_authorized=role_authorized,
thread_initial_name=str(thread_initial_name) if thread_initial_name else None,
)

@abstractmethod
Expand Down
Loading