From 6015104dd8c941dba12dee801c9e811263c1bdd9 Mon Sep 17 00:00:00 2001 From: Jinon Seo Date: Tue, 7 Jul 2026 10:39:18 +0900 Subject: [PATCH] feat(bridge): inject recent conversation history when session resets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a Claude Code session expires or the bridge restarts, the next user message previously arrived in a blank new session — losing all context (e.g. user answering '2' to a numbered-option prompt got "what does 2 mean?" back). Fix: before calling process_message(), capture the stale session_id and read the last 6 exchanges via get_recent_messages(). If the effective_sid is None (new session) but a prior session exists, the exchanges are prepended to the user message as a clearly-labelled context block so Claude can interpret short replies in context. Falls back silently on read errors so existing behaviour is unchanged when no history is available. Co-Authored-By: Claude Sonnet 4.6 --- bridge/core/bot.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/bridge/core/bot.py b/bridge/core/bot.py index 517de37..8c07ab5 100644 --- a/bridge/core/bot.py +++ b/bridge/core/bot.py @@ -315,6 +315,10 @@ async def _process_user_message_text( pass try: + # Capture stale session_id before it may be cleared by auto_new_session. + # Used below to inject recent conversation history when a new session starts. + stale_session_id = current_session.get("session_id") + new_session = current_session.pop("new_session", False) auto_new_session = await session_manager.should_start_new_session( conversation_key, now=message_timestamp @@ -328,13 +332,41 @@ async def _process_user_message_text( await session_manager.set_last_user_message_at(conversation_key, message_timestamp) + effective_sid = self._effective_session_id(conversation_key, current_session) + + # History injection: when the effective session_id is None (new session due to + # bridge restart, session expiry, or auto-rotation) but we have a previous + # session, prepend the recent exchanges so context is not lost. + send_text = text + if effective_sid is None and stale_session_id: + try: + recent = project_chat_handler.get_recent_messages(stale_session_id, limit=6) + if recent: + lines = [] + for m in recent: + label = "사용자" if m["role"] == "user" else "어시스턴트" + snippet = m["content"][:400].replace("\n", " ") + lines.append(f"{label}: {snippet}") + history_block = "\n".join(lines) + send_text = ( + f"[이전 대화 맥락 — 세션 전환으로 자동 주입됨]\n" + f"{history_block}\n\n" + f"[현재 메시지]\n{text}" + ) + logger.info( + f"History injection: {len(recent)} msgs from session " + f"{stale_session_id[:8]}... prepended for user {user_id}" + ) + except Exception as _hist_err: + logger.warning(f"History injection failed, sending without context: {_hist_err}") + enable_streaming_text = next_reply_mode != "voice" response = await project_chat_handler.process_message( - user_message=text, + user_message=send_text, user_id=user_id, chat_id=chat.id, message_id=message.message_id, - session_id=self._effective_session_id(conversation_key, current_session), + session_id=effective_sid, model=current_session.get("model"), new_session=new_session, permission_callback=self._permission_callback,