|
13 | 13 | from fai.utils.scribe.devin_client import DevinClient, create_or_get_devin_session, send_devin_message |
14 | 14 | from fai.utils.scribe.session_poller import poll_devin_session |
15 | 15 | from fai.utils.scribe.slack_file_handler import process_slack_attachments |
16 | | -from fai.utils.scribe.slack_thread_unfurler import unfurl_thread_links |
| 16 | +from fai.utils.scribe.slack_thread_unfurler import ( |
| 17 | + fetch_thread_messages, |
| 18 | + fetch_user_info, |
| 19 | + format_thread_as_context, |
| 20 | + unfurl_thread_links, |
| 21 | +) |
17 | 22 |
|
18 | 23 | STARTUP_RESPONSE = "🚀 Starting a new session for `{github_repo}`..." |
19 | 24 | ERROR_RESPONSE = "❌ An unknown error has occurred. Please reach out to [email protected]." |
@@ -119,6 +124,56 @@ async def handle_scribe_message(event: dict[str, Any], team_id: str) -> ScribeMe |
119 | 124 | if thread_context: |
120 | 125 | text = f"{thread_context}\n{text}" |
121 | 126 |
|
| 127 | + async with async_session_maker() as session: |
| 128 | + result = await session.execute( |
| 129 | + select(ScribeSessionDb).where( |
| 130 | + ScribeSessionDb.integration_id == integration.integration_id, |
| 131 | + ScribeSessionDb.slack_thread_ts == thread_ts, |
| 132 | + ) |
| 133 | + ) |
| 134 | + existing_session = result.scalar_one_or_none() |
| 135 | + |
| 136 | + current_msg_ts = event.get("ts") |
| 137 | + is_reply_in_existing_thread = thread_ts != current_msg_ts |
| 138 | + is_new_session = existing_session is None |
| 139 | + |
| 140 | + if is_reply_in_existing_thread and is_new_session: |
| 141 | + LOGGER.info(f"[SCRIBE] Bot tagged in existing thread {thread_ts} (new session), fetching thread history") |
| 142 | + try: |
| 143 | + from slack_sdk.web.async_client import AsyncWebClient |
| 144 | + |
| 145 | + client = AsyncWebClient(token=integration.slack_bot_token) |
| 146 | + thread_messages = await fetch_thread_messages(client, channel, thread_ts) |
| 147 | + |
| 148 | + if thread_messages: |
| 149 | + messages_before_mention = [msg for msg in thread_messages if msg.get("ts", "") < current_msg_ts] |
| 150 | + |
| 151 | + if messages_before_mention: |
| 152 | + LOGGER.info( |
| 153 | + f"[SCRIBE] Found {len(messages_before_mention)} messages before current mention in thread" |
| 154 | + ) |
| 155 | + |
| 156 | + user_cache: dict[str, str] = {} |
| 157 | + for msg in messages_before_mention: |
| 158 | + user_id = msg.get("user") |
| 159 | + if user_id and user_id not in user_cache: |
| 160 | + user_cache[user_id] = await fetch_user_info(client, user_id) |
| 161 | + |
| 162 | + existing_thread_context = format_thread_as_context(messages_before_mention, user_cache) |
| 163 | + |
| 164 | + if existing_thread_context: |
| 165 | + text = f"{existing_thread_context}\n{text}" |
| 166 | + LOGGER.info("[SCRIBE] Added existing thread context to message") |
| 167 | + else: |
| 168 | + LOGGER.info("[SCRIBE] No messages found before current mention") |
| 169 | + else: |
| 170 | + LOGGER.warning(f"[SCRIBE] Failed to fetch thread messages for {thread_ts}") |
| 171 | + |
| 172 | + except Exception as e: |
| 173 | + LOGGER.warning(f"[SCRIBE] Error fetching existing thread context: {e}, proceeding without it") |
| 174 | + elif existing_session: |
| 175 | + LOGGER.info(f"[SCRIBE] Existing session found for thread {thread_ts}, skipping thread context loading") |
| 176 | + |
122 | 177 | github_repo = integration.github_repo |
123 | 178 |
|
124 | 179 | current_settings = integration.settings or {} |
|
0 commit comments