diff --git a/api-relay-server/package-lock.json b/api-relay-server/package-lock.json
index b0b686f..1e6d133 100644
--- a/api-relay-server/package-lock.json
+++ b/api-relay-server/package-lock.json
@@ -9,6 +9,7 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
+        "api-relay-server": "file:",
         "body-parser": "^2.2.0",
         "cors": "^2.8.5",
         "express": "^5.1.0",
@@ -195,6 +196,10 @@
         "node": ">= 8"
       }
     },
+    "node_modules/api-relay-server": {
+      "resolved": "",
+      "link": true
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
diff --git a/api-relay-server/package.json b/api-relay-server/package.json
index af7649c..93d6306 100644
--- a/api-relay-server/package.json
+++ b/api-relay-server/package.json
@@ -14,6 +14,7 @@
   "license": "ISC",
   "description": "",
   "dependencies": {
+    "api-relay-server": "file:",
     "body-parser": "^2.2.0",
     "cors": "^2.8.5",
     "express": "^5.1.0",
diff --git a/api-relay-server/src/admin-ui/admin.html b/api-relay-server/src/admin-ui/admin.html
index 91a440c..23d25f9 100644
--- a/api-relay-server/src/admin-ui/admin.html
+++ b/api-relay-server/src/admin-ui/admin.html
@@ -1,41 +1,102 @@
 <!--
   Chat Relay: Relay for AI Chat Interfaces
   Copyright (C) 2025 Jamison Moore
-
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.
-
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.
-
   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see https://www.gnu.org/licenses/.
 -->
 <!DOCTYPE html>
 <html lang="en">
+
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Chat Relay Admin</title>
     <style>
-        body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f4f4f4; color: #333; }
-        header { background-color: #333; color: #fff; padding: 1em; text-align: center; }
-        nav { background-color: #444; padding: 0.5em; }
-        nav ul { list-style-type: none; padding: 0; margin: 0; text-align: center; }
-        nav ul li { display: inline; margin-right: 20px; }
-        nav ul li a { color: #fff; text-decoration: none; font-weight: bold; }
-        nav ul li a.active { text-decoration: underline; }
-        .container { padding: 1em; }
-        .tab-content { display: none; }
-        .tab-content.active { display: block; }
-        h2 { border-bottom: 2px solid #333; padding-bottom: 0.5em; }
-        table { width: 100%; border-collapse: collapse; margin-top: 1em; }
-        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
-        th { background-color: #555; color: white; }
+        body {
+            font-family: Arial, sans-serif;
+            margin: 0;
+            padding: 0;
+            background-color: #f4f4f4;
+            color: #333;
+        }
+
+        header {
+            background-color: #333;
+            color: #fff;
+            padding: 1em;
+            text-align: center;
+        }
+
+        nav {
+            background-color: #444;
+            padding: 0.5em;
+        }
+
+        nav ul {
+            list-style-type: none;
+            padding: 0;
+            margin: 0;
+            text-align: center;
+        }
+
+        nav ul li {
+            display: inline;
+            margin-right: 20px;
+        }
+
+        nav ul li a {
+            color: #fff;
+            text-decoration: none;
+            font-weight: bold;
+        }
+
+        nav ul li a.active {
+            text-decoration: underline;
+        }
+
+        .container {
+            padding: 1em;
+        }
+
+        .tab-content {
+            display: none;
+        }
+
+        .tab-content.active {
+            display: block;
+        }
+
+        h2 {
+            border-bottom: 2px solid #333;
+            padding-bottom: 0.5em;
+        }
+
+        table {
+            width: 100%;
+            border-collapse: collapse;
+            margin-top: 1em;
+        }
+
+        th,
+        td {
+            border: 1px solid #ddd;
+            padding: 8px;
+            text-align: left;
+        }
+
+        th {
+            background-color: #555;
+            color: white;
+        }
+
         .log-window {
             background-color: #222;
             color: #0f0;
@@ -46,10 +107,21 @@
             border: 1px solid #444;
             margin-top: 1em;
         }
-        .log-entry { white-space: pre-wrap; }
-        .collapsible-header { background-color: #555; color: white; padding: 0.5em; cursor: pointer; text-align: center; }
+
+        .log-entry {
+            white-space: pre-wrap;
+        }
+
+        .collapsible-header {
+            background-color: #555;
+            color: white;
+            padding: 0.5em;
+            cursor: pointer;
+            text-align: center;
+        }
     </style>
 </head>
+
 <body>
     <header>
         <h1>Chat Relay Admin Dashboard</h1>
@@ -63,7 +135,8 @@ <h1>Chat Relay Admin Dashboard</h1>
     </nav>
     <div class="container">
         <div id="messages" class="tab-content active">
-            <h2>Message History <button id="refresh-messages-btn" style="font-size: 0.8em; margin-left: 10px;">Refresh Messages</button></h2>
+            <h2>Message History <button id="refresh-messages-btn" style="font-size: 0.8em; margin-left: 10px;">Refresh
+                    Messages</button></h2>
             <table>
                 <thead>
                     <tr>
@@ -97,7 +170,8 @@ <h2>Configuration Settings</h2>
                 <div style="margin-top: 0.5em;">
                     <label>New Request Behavior (if extension busy):</label>
                     <div>
-                        <input type="radio" id="newRequestBehaviorQueue" name="newRequestBehavior" value="queue" checked>
+                        <input type="radio" id="newRequestBehaviorQueue" name="newRequestBehavior" value="queue"
+                            checked>
                         <label for="newRequestBehaviorQueue">Queue</label>
                     </div>
                     <div>
@@ -105,6 +179,10 @@ <h2>Configuration Settings</h2>
                         <label for="newRequestBehaviorDrop">Drop</label>
                     </div>
                 </div>
+                <div style="margin-top: 0.5em;">
+                    <label for="auto-kill-port-input">Auto-kill conflicting port 3003 process on startup: </label>
+                    <input type="checkbox" id="auto-kill-port-input">
+                </div>
                 <button id="save-settings-btn" style="margin-top: 1em; margin-bottom: 0.5em;">Save Settings</button>
                 <span id="update-status-msg" style="margin-left: 10px; font-style: italic;"></span>
                 <p style="margin-top: 1em;">Ping Interval (ms): <span id="setting-ping-interval"></span></p>
@@ -115,7 +193,9 @@ <h2>Server Status</h2>
             <div id="status-content">
                 <p>Server Uptime: <span id="status-uptime">N/A</span></p>
                 <p>Connected Extensions: <span id="status-connected-extensions">0</span></p>
-                <button id="restart-server-btn" style="margin-top: 1em; padding: 0.5em 1em; background-color: #d9534f; color: white; border: none; cursor: pointer;">Restart Server</button>
+                <button id="restart-server-btn"
+                    style="margin-top: 1em; padding: 0.5em 1em; background-color: #d9534f; color: white; border: none; cursor: pointer;">Restart
+                    Server</button>
             </div>
         </div>
     </div>
@@ -135,7 +215,6 @@ <h2>Server Status</h2>
                 link.classList.add('active');
                 const activeTabContent = document.getElementById(link.dataset.tab);
                 activeTabContent.classList.add('active');
-
                 // If settings or status tab is activated, refresh their content
                 if (link.dataset.tab === 'settings' || link.dataset.tab === 'status') {
                     fetchAndDisplayServerInfo();
@@ -152,7 +231,6 @@ <h2>Server Status</h2>
         }
         const messageHistoryBody = document.getElementById('message-history-body');
         const refreshButton = document.getElementById('refresh-messages-btn');
-
         function createPreCell(data) {
             const cell = document.createElement('td');
             if (data === undefined || data === null) {
@@ -168,7 +246,6 @@ <h2>Server Status</h2>
             }
             return cell;
         }
-
         async function fetchAndDisplayMessageHistory() {
             try {
                 const response = await fetch('/v1/admin/message-history');
@@ -176,9 +253,7 @@ <h2>Server Status</h2>
                     throw new Error(`HTTP error! status: ${response.status}`);
                 }
                 const messages = await response.json();
-
                 messageHistoryBody.innerHTML = ''; // Clear existing rows
-
                 if (messages.length === 0) {
                     const row = messageHistoryBody.insertRow();
                     const cell = row.insertCell();
@@ -187,7 +262,6 @@ <h2>Server Status</h2>
                     cell.style.textAlign = 'center';
                     return;
                 }
-
                 // Group messages by requestId
                 const groupedMessages = messages.reduce((acc, logEntry) => {
                     const id = logEntry.requestId;
@@ -203,7 +277,6 @@ <h2>Server Status</h2>
                             status: "Unknown"
                         };
                     }
-
                     // Update fields based on log type
                     switch (logEntry.type) {
                         case 'CHAT_REQUEST_RECEIVED':
@@ -231,22 +304,19 @@ <h2>Server Status</h2>
                     }
                     return acc;
                 }, {});
-
                 // Convert grouped messages object to an array and sort by timestamp (most recent first)
                 const consolidatedMessages = Object.values(groupedMessages).sort((a, b) => {
                     // Sort by startTimestamp, most recent first
                     return new Date(b.startTimestamp) - new Date(a.startTimestamp);
                 });
-
                 if (consolidatedMessages.length === 0) {
-                     const row = messageHistoryBody.insertRow();
+                    const row = messageHistoryBody.insertRow();
                     const cell = row.insertCell();
                     cell.colSpan = 8; // Adjusted for new column
                     cell.textContent = 'No consolidated message history to display.';
                     cell.style.textAlign = 'center';
                     return;
                 }
-
                 consolidatedMessages.forEach(msg => {
                     const row = messageHistoryBody.insertRow();
                     row.insertCell().textContent = new Date(msg.startTimestamp).toLocaleString();
@@ -269,18 +339,16 @@ <h2>Server Status</h2>
                 cell.style.textAlign = 'center';
             }
         }
-
         if (refreshButton) {
             refreshButton.addEventListener('click', fetchAndDisplayMessageHistory);
         }
-
         fetchAndDisplayMessageHistory(); // Initial load for messages
-
         // Elements for settings and status
         const portInputEl = document.getElementById('port-input'); // Corrected ID
         const requestTimeoutInputEl = document.getElementById('request-timeout-input');
         const newRequestBehaviorQueueEl = document.getElementById('newRequestBehaviorQueue');
         const newRequestBehaviorDropEl = document.getElementById('newRequestBehaviorDrop');
+        const autoKillPortInputEl = document.getElementById('auto-kill-port-input');
         const saveSettingsBtn = document.getElementById('save-settings-btn');
         const updateStatusMsgEl = document.getElementById('update-status-msg');
         const settingPingIntervalEl = document.getElementById('setting-ping-interval');
@@ -288,7 +356,6 @@ <h2>Server Status</h2>
         const statusUptimeEl = document.getElementById('status-uptime');
         const statusConnectedExtensionsEl = document.getElementById('status-connected-extensions');
         const restartServerBtn = document.getElementById('restart-server-btn');
-
         function formatUptime(totalSeconds) {
             if (totalSeconds === null || totalSeconds === undefined) return 'N/A';
             const days = Math.floor(totalSeconds / (3600 * 24));
@@ -297,7 +364,6 @@ <h2>Server Status</h2>
             totalSeconds %= 3600;
             const minutes = Math.floor(totalSeconds / 60);
             const seconds = totalSeconds % 60;
-
             let uptimeString = '';
             if (days > 0) uptimeString += `${days}d `;
             if (hours > 0) uptimeString += `${hours}h `;
@@ -305,7 +371,6 @@ <h2>Server Status</h2>
             uptimeString += `${seconds}s`;
             return uptimeString.trim() || '0s';
         }
-
         async function fetchAndDisplayServerInfo() {
             try {
                 const response = await fetch('/v1/admin/server-info');
@@ -313,44 +378,40 @@ <h2>Server Status</h2>
                     throw new Error(`HTTP error! status: ${response.status}`);
                 }
                 const serverInfo = await response.json();
-
                 // Populate Settings
-                if(portInputEl) portInputEl.value = serverInfo.port || ''; // Use portInputEl
-                if(requestTimeoutInputEl) requestTimeoutInputEl.value = serverInfo.requestTimeoutMs !== null ? serverInfo.requestTimeoutMs : '';
-                if(settingPingIntervalEl) settingPingIntervalEl.textContent = serverInfo.pingIntervalMs !== null ? `${serverInfo.pingIntervalMs} ms` : 'N/A (Not Implemented)';
-                
+                if (portInputEl) portInputEl.value = serverInfo.port || ''; // Use portInputEl
+                if (requestTimeoutInputEl) requestTimeoutInputEl.value = serverInfo.requestTimeoutMs !== null ? serverInfo.requestTimeoutMs : '';
+                if (settingPingIntervalEl) settingPingIntervalEl.textContent = serverInfo.pingIntervalMs !== null ? `${serverInfo.pingIntervalMs} ms` : 'N/A (Not Implemented)';
                 if (serverInfo.newRequestBehavior === 'drop') {
-                    if(newRequestBehaviorDropEl) newRequestBehaviorDropEl.checked = true;
+                    if (newRequestBehaviorDropEl) newRequestBehaviorDropEl.checked = true;
                 } else {
-                    if(newRequestBehaviorQueueEl) newRequestBehaviorQueueEl.checked = true; // Default to queue
+                    if (newRequestBehaviorQueueEl) newRequestBehaviorQueueEl.checked = true; // Default to queue
                 }
-
+                if (autoKillPortInputEl) autoKillPortInputEl.checked = serverInfo.autoKillPort || false;
                 // Populate Status
-                if(statusUptimeEl) statusUptimeEl.textContent = formatUptime(serverInfo.uptimeSeconds);
-                if(statusConnectedExtensionsEl) statusConnectedExtensionsEl.textContent = serverInfo.connectedExtensionsCount !== null ? serverInfo.connectedExtensionsCount : 'N/A';
-
+                if (statusUptimeEl) statusUptimeEl.textContent = formatUptime(serverInfo.uptimeSeconds);
+                if (statusConnectedExtensionsEl) statusConnectedExtensionsEl.textContent = serverInfo.connectedExtensionsCount !== null ? serverInfo.connectedExtensionsCount : 'N/A';
             } catch (error) {
                 console.error('Error fetching server info:', error);
-                if(portInputEl) portInputEl.value = 'Error';
-                if(requestTimeoutInputEl) requestTimeoutInputEl.value = 'Error';
-                if(settingPingIntervalEl) settingPingIntervalEl.textContent = 'Error';
-                if(newRequestBehaviorQueueEl) newRequestBehaviorQueueEl.checked = true; // Default on error
+                if (portInputEl) portInputEl.value = 'Error';
+                if (requestTimeoutInputEl) requestTimeoutInputEl.value = 'Error';
+                if (settingPingIntervalEl) settingPingIntervalEl.textContent = 'Error';
+                if (newRequestBehaviorQueueEl) newRequestBehaviorQueueEl.checked = true; // Default on error
+                if (autoKillPortInputEl) autoKillPortInputEl.checked = false; // Default on error
                 // Ensure error handling for status elements
-                if(statusUptimeEl) statusUptimeEl.textContent = 'Error loading uptime';
-                if(statusConnectedExtensionsEl) statusConnectedExtensionsEl.textContent = 'Error loading connections';
+                if (statusUptimeEl) statusUptimeEl.textContent = 'Error loading uptime';
+                if (statusConnectedExtensionsEl) statusConnectedExtensionsEl.textContent = 'Error loading connections';
             }
         }
-        
         async function handleSaveSettings() {
-            if (!requestTimeoutInputEl || !portInputEl || !updateStatusMsgEl || !newRequestBehaviorQueueEl || !newRequestBehaviorDropEl) return;
-
+            if (!requestTimeoutInputEl || !portInputEl || !updateStatusMsgEl || !newRequestBehaviorQueueEl || !newRequestBehaviorDropEl || !autoKillPortInputEl) return;
             const newTimeout = parseInt(requestTimeoutInputEl.value, 10);
             const newPort = parseInt(portInputEl.value, 10);
             const selectedNewRequestBehavior = newRequestBehaviorQueueEl.checked ? 'queue' : 'drop';
+            const autoKillPort = autoKillPortInputEl.checked;
             let settingsToUpdate = {};
             let validationError = false;
             let messages = [];
-
             if (requestTimeoutInputEl.value.trim() !== '') { // Only process if there's input
                 if (!isNaN(newTimeout) && newTimeout > 0) {
                     settingsToUpdate.requestTimeoutMs = newTimeout;
@@ -359,37 +420,32 @@ <h2>Server Status</h2>
                     validationError = true;
                 }
             }
-
             if (portInputEl.value.trim() !== '') { // Only process if there's input
-                 if (!isNaN(newPort) && newPort > 0 && newPort <= 65535) {
+                if (!isNaN(newPort) && newPort > 0 && newPort <= 65535) {
                     settingsToUpdate.port = newPort;
                 } else {
                     messages.push('Invalid port: Must be between 1 and 65535.');
                     validationError = true;
                 }
             }
-
             // Always include newRequestBehavior as it's controlled by radio buttons
             // No specific validation needed here as it's either 'queue' or 'drop'
             settingsToUpdate.newRequestBehavior = selectedNewRequestBehavior;
-            
+            settingsToUpdate.autoKillPort = autoKillPort; // Add the new setting
             if (validationError) {
                 updateStatusMsgEl.textContent = messages.join(' ');
                 updateStatusMsgEl.style.color = 'red';
                 setTimeout(() => { updateStatusMsgEl.textContent = ''; }, 7000);
                 return;
             }
-
             if (Object.keys(settingsToUpdate).length === 0) {
                 updateStatusMsgEl.textContent = 'No changes to save.';
                 updateStatusMsgEl.style.color = 'blue';
                 setTimeout(() => { updateStatusMsgEl.textContent = ''; }, 5000);
                 return;
             }
-
             updateStatusMsgEl.textContent = 'Saving settings...';
             updateStatusMsgEl.style.color = 'orange';
-
             try {
                 const response = await fetch('/v1/admin/update-settings', {
                     method: 'POST',
@@ -415,11 +471,9 @@ <h2>Server Status</h2>
             const clearTime = updateStatusMsgEl.textContent.toLowerCase().includes('restart') ? 15000 : 7000;
             setTimeout(() => { updateStatusMsgEl.textContent = ''; }, clearTime);
         }
-
         if (saveSettingsBtn) {
             saveSettingsBtn.addEventListener('click', handleSaveSettings);
         }
-        
         async function handleRestartServer() {
             if (confirm('Are you sure you want to restart the server?')) {
                 try {
@@ -432,15 +486,13 @@ <h2>Server Status</h2>
                 }
             }
         }
-
         if (restartServerBtn) {
             restartServerBtn.addEventListener('click', handleRestartServer);
         }
-        
         // Initial load for settings and status
         fetchAndDisplayServerInfo();
-
         console.log("Admin UI initialized. Message history, settings, status, and restart functionality implemented.");
     </script>
 </body>
+
 </html>
\ No newline at end of file
diff --git a/api-relay-server/src/server.ts b/api-relay-server/src/server.ts
index fe5654f..5cebc2c 100644
--- a/api-relay-server/src/server.ts
+++ b/api-relay-server/src/server.ts
@@ -15,13 +15,14 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program.  If not, see https://www.gnu.org/licenses/.
  */
-import express, { Request, Response, NextFunction, Router } from 'express';
 import bodyParser from 'body-parser';
+import { execSync } from 'child_process'; // Import for executing commands
 import cors from 'cors';
-import { WebSocketServer, WebSocket } from 'ws';
+import express, { NextFunction, Request, Response, Router } from 'express';
+import fs from 'fs';
 import http from 'http';
 import path from 'path';
-import fs from 'fs';
+import { WebSocket, WebSocketServer } from 'ws';
 // Interfaces
 interface PendingRequest {
   resolve: (value: any) => void;
@@ -91,16 +92,16 @@ type AdminLogDataType = ChatRequestData | ChatResponseData | ChatErrorData | any
 interface AdminLogEntry {
   timestamp: string;
   type:
-    | 'CHAT_REQUEST_RECEIVED'
-    | 'CHAT_RESPONSE_SENT'
-    | 'CHAT_ERROR_RESPONSE_SENT'
-    | 'CHAT_REQUEST_QUEUED'
-    | 'CHAT_REQUEST_DROPPED'
-    | 'CHAT_REQUEST_DEQUEUED'
-    | 'CHAT_REQUEST_PROCESSING'
-    | 'CHAT_REQUEST_ERROR' // For pre-processing errors like no extension
-    | 'SETTING_UPDATE' // Existing type, ensure it's included
-    | string; // Fallback for other/future types
+  | 'CHAT_REQUEST_RECEIVED'
+  | 'CHAT_RESPONSE_SENT'
+  | 'CHAT_ERROR_RESPONSE_SENT'
+  | 'CHAT_REQUEST_QUEUED'
+  | 'CHAT_REQUEST_DROPPED'
+  | 'CHAT_REQUEST_DEQUEUED'
+  | 'CHAT_REQUEST_PROCESSING'
+  | 'CHAT_REQUEST_ERROR' // For pre-processing errors like no extension
+  | 'SETTING_UPDATE' // Existing type, ensure it's included
+  | string; // Fallback for other/future types
   requestId: string;
   data: AdminLogDataType;
 }
@@ -117,6 +118,7 @@ interface ServerConfig {
   requestTimeoutMs?: number;
   lastRestartRequestTimestamp?: number; // New field
   newRequestBehavior?: 'queue' | 'drop';
+  autoKillPort?: boolean; // New setting for auto-killing port
 }
 
 // Function to read configuration
@@ -147,8 +149,9 @@ const initialConfig = loadServerConfig();
 
 // Initialize newRequestBehavior from config, defaulting to 'queue'
 newRequestBehavior = initialConfig.newRequestBehavior && (initialConfig.newRequestBehavior === 'queue' || initialConfig.newRequestBehavior === 'drop')
-                    ? initialConfig.newRequestBehavior
-                    : 'queue';
+  ? initialConfig.newRequestBehavior
+  : 'queue';
+let autoKillPort = initialConfig.autoKillPort === undefined ? false : initialConfig.autoKillPort; // Initialize autoKillPort
 
 const PORT = initialConfig.port || parseInt(process.env.PORT || '3003', 10);
 let currentRequestTimeoutMs = initialConfig.requestTimeoutMs || parseInt(process.env.REQUEST_TIMEOUT_MS || '120000', 10);
@@ -213,7 +216,7 @@ wss.on('connection', (ws: WebSocket) => {
             console.error(`SERVER: Rejecting request ${requestIdToProcess} with error: ${responseDataToUse}`);
             pendingRequest.reject(new Error(responseDataToUse || "Error from extension"));
           } else {
-            console.log(`SERVER: Resolving request ${requestIdToProcess} with data (first 100 chars): ${(responseDataToUse || "").substring(0,100)}`);
+            console.log(`SERVER: Resolving request ${requestIdToProcess} with data (first 100 chars): ${(responseDataToUse || "").substring(0, 100)}`);
             pendingRequest.resolve(responseDataToUse);
           }
           pendingRequests.delete(requestIdToProcess);
@@ -242,7 +245,7 @@ async function logAdminMessage(
   data: AdminLogDataType      // Use the specific union type for data
 ): Promise<void> {
   const timestamp = new Date().toISOString();
-  
+
   // For debugging, let's log what's being passed to logAdminMessage
   // console.log(`LOGGING [${type}] ReqID [${requestId}]:`, JSON.stringify(data, null, 2));
 
@@ -252,7 +255,7 @@ async function logAdminMessage(
     requestId: String(requestId),
     data,
   };
-  
+
   adminMessageHistory.unshift(logEntry);
 
   if (adminMessageHistory.length > MAX_ADMIN_HISTORY_LENGTH) {
@@ -455,7 +458,7 @@ apiRouter.post('/chat/completions', async (req: Request, res: Response): Promise
       }
       return;
     }
-    
+
     if (newRequestBehavior === 'queue') {
       requestQueue.push(queuedItem);
       logAdminMessage('CHAT_REQUEST_QUEUED', requestId, {
@@ -476,8 +479,8 @@ apiRouter.post('/chat/completions', async (req: Request, res: Response): Promise
     // This catch is a safety net if processRequest itself throws an unhandled error *before* it can send a response.
     console.error(`SERVER: Unhandled error from processRequest for ${requestId} in /chat/completions:`, error);
     logAdminMessage('CHAT_ERROR_RESPONSE_SENT', requestId, {
-        toClientError: { message: (error as Error).message, type: "server_error", code: "unhandled_processing_catch" },
-        status: `Error: ${(error as Error).message}`
+      toClientError: { message: (error as Error).message, type: "server_error", code: "unhandled_processing_catch" },
+      status: `Error: ${(error as Error).message}`
     }).catch(err => console.error("ADMIN_LOG_ERROR (CHAT_ERROR_RESPONSE_SENT):", err));
     if (!res.headersSent) {
       res.status(500).json({
@@ -525,13 +528,13 @@ apiRouter.get('/admin/message-history', (req: Request, res: Response): void => {
   } catch (error) {
     console.error('Error fetching message history from in-memory store:', error);
     if (!res.headersSent) {
-        res.status(500).json({
-            error: {
-                message: (error instanceof Error ? error.message : String(error)) || 'Failed to retrieve message history',
-                type: 'server_error', // Changed from redis_error
-                code: 'history_retrieval_failed'
-            }
-        });
+      res.status(500).json({
+        error: {
+          message: (error instanceof Error ? error.message : String(error)) || 'Failed to retrieve message history',
+          type: 'server_error', // Changed from redis_error
+          code: 'history_retrieval_failed'
+        }
+      });
     }
   }
 });
@@ -544,6 +547,7 @@ apiRouter.get('/admin/server-info', (req: Request, res: Response): void => {
       port: PORT,
       requestTimeoutMs: currentRequestTimeoutMs, // Report the current mutable value
       newRequestBehavior: newRequestBehavior, // Add the current behavior
+      autoKillPort: autoKillPort, // Add the current autoKillPort setting
       pingIntervalMs: null, // Placeholder - No explicit ping interval defined for client pings
       connectedExtensionsCount: activeConnections.length,
       uptimeSeconds: uptimeSeconds,
@@ -552,13 +556,13 @@ apiRouter.get('/admin/server-info', (req: Request, res: Response): void => {
   } catch (error) {
     console.error('Error fetching server info:', error);
     if (!res.headersSent) {
-        res.status(500).json({
-            error: {
-                message: (error instanceof Error ? error.message : String(error)) || 'Failed to retrieve server info',
-                type: 'server_error',
-                code: 'server_info_failed'
-            }
-        });
+      res.status(500).json({
+        error: {
+          message: (error instanceof Error ? error.message : String(error)) || 'Failed to retrieve server info',
+          type: 'server_error',
+          code: 'server_info_failed'
+        }
+      });
     }
   }
 });
@@ -605,10 +609,10 @@ apiRouter.post('/admin/restart-server', (req: Request, res: Response): void => {
 
 // The more comprehensive update-settings endpoint below handles both port and requestTimeoutMs.
 apiRouter.post('/admin/update-settings', (req: Request, res: Response): void => {
-  const { requestTimeoutMs, port, newRequestBehavior: newBehaviorValue } = req.body;
+  const { requestTimeoutMs, port, newRequestBehavior: newBehaviorValue, autoKillPort: newAutoKillPortValue } = req.body;
   let configChanged = false;
   let messages: string[] = [];
-  
+
   const currentConfig = loadServerConfig(); // Load current disk config to preserve other settings
 
   if (requestTimeoutMs !== undefined) {
@@ -632,7 +636,7 @@ apiRouter.post('/admin/update-settings', (req: Request, res: Response): void =>
       currentConfig.port = newPort; // Update config for saving
       configChanged = true;
       messages.push(`Server port configured to ${newPort}. This change will take effect after server restart.`);
-       logAdminMessage('SETTING_UPDATE', 'SERVER_CONFIG', { setting: 'port', value: newPort, requiresRestart: true })
+      logAdminMessage('SETTING_UPDATE', 'SERVER_CONFIG', { setting: 'port', value: newPort, requiresRestart: true })
         .catch(err => console.error("ADMIN_LOG_ERROR (SETTING_UPDATE):", err));
     } else {
       res.status(400).json({ error: 'Invalid port value. Must be a positive number between 1 and 65535.' });
@@ -654,6 +658,20 @@ apiRouter.post('/admin/update-settings', (req: Request, res: Response): void =>
     }
   }
 
+  if (newAutoKillPortValue !== undefined) {
+    if (typeof newAutoKillPortValue === 'boolean') {
+      autoKillPort = newAutoKillPortValue; // Update in-memory value immediately
+      currentConfig.autoKillPort = newAutoKillPortValue; // Update config for saving
+      configChanged = true;
+      messages.push(`Auto-kill port setting updated to '${autoKillPort}'. This change is effective on next server startup if port conflict occurs.`);
+      logAdminMessage('SETTING_UPDATE', 'SERVER_CONFIG', { setting: 'autoKillPort', value: autoKillPort, requiresRestartToSeeEffect: true })
+        .catch(err => console.error("ADMIN_LOG_ERROR (SETTING_UPDATE autoKillPort):", err));
+    } else {
+      res.status(400).json({ error: "Invalid autoKillPort value. Must be a boolean." });
+      return;
+    }
+  }
+
   if (configChanged) {
     saveServerConfig(currentConfig);
     res.json({ message: messages.join(' ') });
@@ -669,8 +687,73 @@ app.get('/health', (req: Request, res: Response) => {
 
 // Mount the API router
 app.use('/v1', apiRouter);
+
+// Function to handle port conflict before starting the server
+function handlePortConflict(portToFree: number, killProcess: boolean): void {
+  if (!killProcess) {
+    console.log(`Auto-kill for port ${portToFree} is disabled. Will not attempt to free port.`);
+    return;
+  }
+
+  console.log(`Checking if port ${portToFree} is in use...`);
+  try {
+    // Command to find process using the port (Windows specific)
+    const command = `netstat -ano -p TCP | findstr ":${portToFree}.*LISTENING"`;
+    const output = execSync(command, { encoding: 'utf-8' });
+
+    if (output) {
+      console.log(`Port ${portToFree} is in use. Output:\n${output}`);
+      // Extract PID - Example: TCP    0.0.0.0:3003           0.0.0.0:0              LISTENING       12345
+      // PID is the last number on the line.
+      const lines = output.trim().split('\n');
+      if (lines.length > 0) {
+        const firstLine = lines[0];
+        const parts = firstLine.trim().split(/\s+/);
+        const pid = parts[parts.length - 1];
+
+        if (pid && !isNaN(parseInt(pid))) {
+          console.log(`Attempting to kill process with PID: ${pid} using port ${portToFree}`);
+          try {
+            execSync(`taskkill /PID ${pid} /F`);
+            console.log(`Successfully killed process ${pid} using port ${portToFree}.`);
+            logAdminMessage('PORT_KILLED', `PORT_${portToFree}`, { port: portToFree, pid: pid, status: 'success' })
+              .catch(err => console.error("ADMIN_LOG_ERROR (PORT_KILLED):", err));
+          } catch (killError) {
+            console.error(`Failed to kill process ${pid} using port ${portToFree}:`, killError);
+            logAdminMessage('PORT_KILL_FAILED', `PORT_${portToFree}`, { port: portToFree, pid: pid, status: 'failure', error: (killError as Error).message })
+              .catch(err => console.error("ADMIN_LOG_ERROR (PORT_KILL_FAILED):", err));
+          }
+        } else {
+          console.warn(`Could not extract a valid PID for port ${portToFree} from netstat output: ${firstLine}`);
+        }
+      } else {
+        console.log(`No process found listening on port ${portToFree} from netstat output.`);
+      }
+    } else {
+      console.log(`Port ${portToFree} is free.`);
+    }
+  } catch (error: any) {
+    // If findstr returns an error, it usually means the port is not found / not in use.
+    if (error.status === 1) { // findstr exits with 1 if string not found
+      console.log(`Port ${portToFree} appears to be free (netstat/findstr did not find it).`);
+    } else {
+      console.error(`Error checking port ${portToFree}:`, error.message);
+    }
+  }
+}
+
 // Start the server
-server.listen(PORT, () => {
-  console.log(`OpenAI-compatible relay server running on port ${PORT}`);
-  console.log(`WebSocket server for browser extensions running on ws://localhost:${PORT}`);
+async function startServer() {
+  // Handle potential port conflict before starting the server
+  handlePortConflict(PORT, autoKillPort);
+
+  server.listen(PORT, () => {
+    console.log(`OpenAI-compatible relay server running on port ${PORT}`);
+    console.log(`WebSocket server for browser extensions running on ws://localhost:${PORT}`);
+  });
+}
+
+startServer().catch(err => {
+  console.error("Failed to start server:", err);
+  process.exit(1);
 });
diff --git a/extension/background.js b/extension/background.js
index f392107..fdc947c 100644
--- a/extension/background.js
+++ b/extension/background.js
@@ -1,27 +1,7 @@
-/*
- * Chat Relay: Relay for AI Chat Interfaces
- * Copyright (C) 2025 Jamison Moore
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see https://www.gnu.org/licenses/.
- */
-// AI Chat Relay - Background Script
-
-// Default settings
 const DEFAULT_SETTINGS = {
-  serverHost: 'localhost',
-  serverPort: 3003,
-  serverProtocol: 'ws'
+    serverHost: 'localhost',
+    serverPort: 3003,
+    serverProtocol: 'ws'
 };
 
 let relaySocket = null;
@@ -29,757 +9,783 @@ let reconnectInterval = 5000;
 let reconnectTimer = null;
 let activeTabId = null;
 let serverUrl = '';
-let lastRequestId = null; // User's global lastRequestId
-let processingRequest = false; // User's global processing flag
-let pendingRequests = []; // User's command queue
-let lastSuccessfullyProcessedMessageText = null; // Text of the last message successfully processed (AI response or duplicate handled)
-const pendingRequestDetails = new Map(); // Stores { text: string } for active requests, keyed by requestId
+let lastRequestId = null;
+let processingRequest = false;
+let pendingRequests = [];
+let lastSuccessfullyProcessedMessageText = null;
+const pendingRequestDetails = new Map();
+let currentRequestTargetTabId = null;
 
-// Supported domains for chat interfaces
 const supportedDomains = ['gemini.google.com', 'aistudio.google.com', 'chatgpt.com', 'claude.ai'];
 
-// ===== DEBUGGER RELATED GLOBALS =====
 const BG_LOG_PREFIX = '[BG DEBUGGER]';
-let debuggerAttachedTabs = new Map(); // tabId -> { providerName, patterns, isFetchEnabled, isAttached, lastKnownRequestId }
+let debuggerAttachedTabs = new Map();
 
 
-// Load settings and connect to the relay server
 function loadSettingsAndConnect() {
-  console.log("BACKGROUND: Loading settings and connecting to relay server");
-  chrome.storage.sync.get(DEFAULT_SETTINGS, (items) => {
-    serverUrl = `${items.serverProtocol}://${items.serverHost}:${items.serverPort}`;
-    console.log("BACKGROUND: Using server URL:", serverUrl);
-    connectToRelayServer();
-  });
+    console.log("BACKGROUND: Loading settings and connecting to relay server");
+    chrome.storage.sync.get(DEFAULT_SETTINGS, (items) => {
+        serverUrl = `${items.serverProtocol}://${items.serverHost}:${items.serverPort}`;
+        console.log("BACKGROUND: Using server URL:", serverUrl);
+        connectToRelayServer();
+    });
 }
 
-// Connect to the relay server
 function connectToRelayServer() {
-  if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-    console.log("BACKGROUND: Relay WS: Already connected.");
-    return;
-  }
-
-  if (!navigator.onLine) {
-    console.warn("BACKGROUND: Network offline. Deferring connection attempt.");
-    if (reconnectTimer) clearTimeout(reconnectTimer);
-    reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
-    return;
-  }
-
-  const healthCheckUrl = serverUrl.replace(/^ws/, 'http') + '/health';
-  console.log("BACKGROUND: Performing HTTP pre-check to", healthCheckUrl);
-
-  fetch(healthCheckUrl)
-    .then(response => {
-      if (!response.ok) {
-        // Server responded, but not with a 2xx status (e.g., 404, 500)
-        console.warn(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} received non-OK status: ${response.status}. Server might be having issues. Deferring WebSocket attempt.`);
-        return Promise.reject(new Error(`Server responded with ${response.status}`));
-      }
-      return response.json(); // Attempt to parse JSON
-    })
-    .then(healthData => {
-      console.log(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} successful. Server status: ${healthData.status}, Active Connections: ${healthData.activeBrowserConnections}. Proceeding with WebSocket connection.`);
-      attemptWebSocketConnection();
-    })
-    .catch(fetchError => {
-      // This catches network errors (server down) or errors from the .then() chain (non-OK response, JSON parse error)
-      console.warn(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} failed: ${fetchError.message}. Server is likely down, unreachable, or health endpoint is misbehaving. Deferring WebSocket attempt.`);
-      relaySocket = null;
-      if (reconnectTimer) clearTimeout(reconnectTimer);
-      reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
-    });
+    if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+        console.log("BACKGROUND: Relay WS: Already connected.");
+        return;
+    }
+
+    if (!navigator.onLine) {
+        console.warn("BACKGROUND: Network offline. Deferring connection attempt.");
+        if (reconnectTimer) clearTimeout(reconnectTimer);
+        reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
+        return;
+    }
+
+    const healthCheckUrl = serverUrl.replace(/^ws/, 'http') + '/health';
+    console.log("BACKGROUND: Performing HTTP pre-check to", healthCheckUrl);
+
+    fetch(healthCheckUrl)
+        .then(response => {
+            if (!response.ok) {
+                console.warn(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} received non-OK status: ${response.status}. Server might be having issues. Deferring WebSocket attempt.`);
+                return Promise.reject(new Error(`Server responded with ${response.status}`));
+            }
+            return response.json();
+        })
+        .then(healthData => {
+            console.log(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} successful. Server status: ${healthData.status}, Active Connections: ${healthData.activeBrowserConnections}. Proceeding with WebSocket connection.`);
+            attemptWebSocketConnection();
+        })
+        .catch(fetchError => {
+            console.warn(`BACKGROUND: HTTP pre-check to ${healthCheckUrl} failed: ${fetchError.message}. Server is likely down, unreachable, or health endpoint is misbehaving. Deferring WebSocket attempt.`);
+            relaySocket = null;
+            if (reconnectTimer) clearTimeout(reconnectTimer);
+            reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
+        });
 }
 
 function attemptWebSocketConnection() {
-  console.log("BACKGROUND: Relay WS: Attempting to connect to", serverUrl);
-  try {
-    relaySocket = new WebSocket(serverUrl);
-
-    relaySocket.onopen = () => {
-      console.log("BACKGROUND: Relay WS: Connection established with relay server.");
-      reconnectInterval = 5000; // Reset reconnect interval on successful connection
-      if (reconnectTimer) clearTimeout(reconnectTimer);
-      reconnectTimer = null;
-    };
-
-    relaySocket.onmessage = (event) => {
-      console.log("BACKGROUND: Relay WS: Message received from relay server:", event.data);
-      try {
-        const command = JSON.parse(event.data);
-        if (command.type === 'SEND_CHAT_MESSAGE') {
-          console.log("BACKGROUND: Received SEND_CHAT_MESSAGE command with requestId:", command.requestId);
-          
-          // Store details for this new request
-          pendingRequestDetails.set(command.requestId, { messageContent: command.message }); // Changed key 'text' to 'messageContent'
-          let messagePreview = "";
-          const messageValue = command.message;
-          if (typeof messageValue === 'string') {
-            messagePreview = `String: "${messageValue.substring(0, 50)}..."`;
-          } else if (messageValue instanceof ArrayBuffer) {
-            messagePreview = `ArrayBuffer data (size: ${messageValue.byteLength} bytes)`;
-          } else if (messageValue instanceof Blob) {
-            messagePreview = `Blob data (size: ${messageValue.size} bytes, type: ${messageValue.type})`;
-          } else if (messageValue && typeof messageValue === 'object' && messageValue !== null) {
-            messagePreview = `Object data (type: ${Object.prototype.toString.call(messageValue)})`;
-          } else {
-            messagePreview = `Data type: ${typeof messageValue}, Value: ${String(messageValue).substring(0,50)}`;
-          }
-          console.log(`BACKGROUND: Stored details for requestId: ${command.requestId}, message: ${messagePreview}`);
-
-          // Add to the queue
-          pendingRequests.push(command);
-          console.log(`BACKGROUND: Added command with requestId: ${command.requestId} to queue. Queue length: ${pendingRequests.length}`);
-          
-          // Attempt to process the next request in the queue
-          processNextRequest();
-        }
-      } catch (error) {
-        console.error("BACKGROUND: Relay WS: Error processing message from relay server:", error);
-      }
-    };
-
-    relaySocket.onerror = (errorEvent) => {
-      console.warn("BACKGROUND: Relay WS: WebSocket connection error (event):", errorEvent);
-      // onclose will typically follow and handle reconnection logic
-    };
-
-    relaySocket.onclose = (closeEvent) => {
-      console.log(`BACKGROUND: Relay WS: Connection closed (event). Code: ${closeEvent.code}, Reason: '${closeEvent.reason || 'N/A'}', Cleanly: ${closeEvent.wasClean}. Will attempt reconnect (via connectToRelayServer) in ${reconnectInterval / 1000}s.`);
-      relaySocket = null;
-      if (reconnectTimer) clearTimeout(reconnectTimer);
-      // Retry the entire connectToRelayServer process, which includes the HTTP pre-check
-      reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
-    };
-  } catch (instantiationError) {
-    console.error("BACKGROUND: Relay WS: Error instantiating WebSocket:", instantiationError);
-    relaySocket = null;
-    if (reconnectTimer) clearTimeout(reconnectTimer);
-    console.log(`BACKGROUND: Relay WS: Instantiation failed. Will attempt reconnect (via connectToRelayServer) in ${reconnectInterval / 1000}s.`);
-    // Retry the entire connectToRelayServer process
-    reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
-  }
+    console.log("BACKGROUND: Relay WS: Attempting to connect to", serverUrl);
+    try {
+        relaySocket = new WebSocket(serverUrl);
+
+        relaySocket.onopen = () => {
+            console.log("BACKGROUND: Relay WS: Connection established with relay server.");
+            reconnectInterval = 5000;
+            if (reconnectTimer) clearTimeout(reconnectTimer);
+            reconnectTimer = null;
+        };
+
+        relaySocket.onmessage = (event) => {
+            console.log("BACKGROUND: Relay WS: Message received from relay server:", event.data);
+            try {
+                const command = JSON.parse(event.data);
+                if (command.type === 'SEND_CHAT_MESSAGE') {
+                    console.log("BACKGROUND: Received SEND_CHAT_MESSAGE command with requestId:", command.requestId);
+
+                    pendingRequestDetails.set(command.requestId, {
+                        messageContent: command.message,
+                        settings: command.settings
+                    });
+                    let messagePreview = "";
+                    const messageValue = command.message;
+                    if (typeof messageValue === 'string') {
+                        messagePreview = `String: "${messageValue.substring(0, 50)}..."`;
+                    } else if (messageValue instanceof ArrayBuffer) {
+                        messagePreview = `ArrayBuffer data (size: ${messageValue.byteLength} bytes)`;
+                    } else if (messageValue instanceof Blob) {
+                        messagePreview = `Blob data (size: ${messageValue.size} bytes, type: ${messageValue.type})`;
+                    } else if (messageValue && typeof messageValue === 'object' && messageValue !== null) {
+                        messagePreview = `Object data (type: ${Object.prototype.toString.call(messageValue)})`;
+                    } else {
+                        messagePreview = `Data type: ${typeof messageValue}, Value: ${String(messageValue).substring(0, 50)}`;
+                    }
+                    console.log(`BACKGROUND: Stored details for requestId: ${command.requestId}, message: ${messagePreview}`);
+
+                    pendingRequests.push(command);
+                    console.log(`BACKGROUND: Added command with requestId: ${command.requestId} to queue. Queue length: ${pendingRequests.length}`);
+
+                    processNextRequest();
+                }
+            } catch (error) {
+                console.error("BACKGROUND: Relay WS: Error processing message from relay server:", error);
+            }
+        };
+
+        relaySocket.onerror = (errorEvent) => {
+            console.warn("BACKGROUND: Relay WS: WebSocket connection error (event):", errorEvent);
+        };
+
+        relaySocket.onclose = (closeEvent) => {
+            console.log(`BACKGROUND: Relay WS: Connection closed (event). Code: ${closeEvent.code}, Reason: '${closeEvent.reason || 'N/A'}', Cleanly: ${closeEvent.wasClean}. Will attempt reconnect (via connectToRelayServer) in ${reconnectInterval / 1000}s.`);
+            relaySocket = null;
+            if (reconnectTimer) clearTimeout(reconnectTimer);
+            reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
+        };
+    } catch (instantiationError) {
+        console.error("BACKGROUND: Relay WS: Error instantiating WebSocket:", instantiationError);
+        relaySocket = null;
+        if (reconnectTimer) clearTimeout(reconnectTimer);
+        console.log(`BACKGROUND: Relay WS: Instantiation failed. Will attempt reconnect (via connectToRelayServer) in ${reconnectInterval / 1000}s.`);
+        reconnectTimer = setTimeout(connectToRelayServer, reconnectInterval);
+    }
 }
 
-// Forward commands to content script
-async function forwardCommandToContentScript(command) { // command will include original requestId
-  try {
-    console.log("BACKGROUND: Forwarding command to content script:", command);
-    let targetTabIdForCommand = null;
-    
-    if (activeTabId) {
-      try {
-        console.log(`BACKGROUND: Attempting to use stored activeTabId: ${activeTabId}`);
-        // Test send to ensure tab is still valid for this command before associating requestId
-        await new Promise((resolve, reject) => {
-            chrome.tabs.sendMessage(activeTabId, { type: "PING_TAB" }, response => { // Ping before associating
-                if (chrome.runtime.lastError || !response || !response.success) {
-                    console.warn(`BACKGROUND: Ping to stored tab ${activeTabId} failed or no ack:`, chrome.runtime.lastError ? chrome.runtime.lastError.message : "No response/success false");
-                    activeTabId = null; // Invalidate activeTabId
-                    reject(new Error("Ping failed"));
+async function forwardCommandToContentScript(command) {
+    try {
+        console.log("BACKGROUND: Forwarding command to content script:", command);
+        let targetTabIdForCommand = null;
+
+        if (activeTabId) {
+            try {
+                console.log(`BACKGROUND: Attempting to use stored activeTabId: ${activeTabId}`);
+                await new Promise((resolve, reject) => {
+                    chrome.tabs.sendMessage(activeTabId, { type: "PING_TAB" }, response => {
+                        if (chrome.runtime.lastError || !response || !response.success) {
+                            console.warn(`BACKGROUND: Ping to stored tab ${activeTabId} failed or no ack:`, chrome.runtime.lastError ? chrome.runtime.lastError.message : "No response/success false");
+                            activeTabId = null;
+                            reject(new Error("Ping failed"));
+                        } else {
+                            console.log(`BACKGROUND: Ping to stored tab ${activeTabId} successful.`);
+                            targetTabIdForCommand = activeTabId;
+                            resolve();
+                        }
+                    });
+                });
+            } catch (error) {
+                console.warn(`BACKGROUND: Error using stored activeTabId ${activeTabId}, will find new tab:`, error);
+            }
+        }
+
+        if (!targetTabIdForCommand) {
+            targetTabIdForCommand = await findAndSendToSuitableTab(command, true);
+        }
+
+        if (targetTabIdForCommand) {
+            if (processingRequest && command.requestId === lastRequestId) {
+                currentRequestTargetTabId = targetTabIdForCommand;
+                console.log(`BACKGROUND: Set currentRequestTargetTabId to ${targetTabIdForCommand} for active requestId ${lastRequestId}`);
+            }
+            const tabInfo = debuggerAttachedTabs.get(targetTabIdForCommand);
+            if (tabInfo) {
+                tabInfo.lastKnownRequestId = command.requestId;
+                console.log(BG_LOG_PREFIX, `Associated requestId ${command.requestId} with tab ${targetTabIdForCommand} for debugger.`);
+            } else {
+                console.warn(BG_LOG_PREFIX, `Tab ${targetTabIdForCommand} is not being debugged. Cannot associate requestId for debugger.`);
+            }
+
+            chrome.tabs.sendMessage(targetTabIdForCommand, command, (response) => {
+                if (chrome.runtime.lastError) {
+                    console.error(`BACKGROUND: Error sending message to tab ${targetTabIdForCommand}:`, chrome.runtime.lastError.message);
+                    if (lastRequestId === command.requestId) {
+                        processingRequest = false;
+                    }
                 } else {
-                    console.log(`BACKGROUND: Ping to stored tab ${activeTabId} successful.`);
-                    targetTabIdForCommand = activeTabId;
-                    resolve();
+                    console.log(`BACKGROUND: Content script in tab ${targetTabIdForCommand} acknowledged command:`, response);
                 }
             });
-        });
-      } catch (error) {
-        // Fall through to findAndSendToSuitableTab if ping fails
-        console.warn(`BACKGROUND: Error using stored activeTabId ${activeTabId}, will find new tab:`, error);
-      }
-    }
-    
-    if (!targetTabIdForCommand) {
-        targetTabIdForCommand = await findAndSendToSuitableTab(command, true); // Pass true to only find, not send yet
-    }
 
-    if (targetTabIdForCommand) {
-        const tabInfo = debuggerAttachedTabs.get(targetTabIdForCommand);
-        if (tabInfo) {
-            tabInfo.lastKnownRequestId = command.requestId; // Store command's requestId for this specific tab
-            console.log(BG_LOG_PREFIX, `Associated requestId ${command.requestId} with tab ${targetTabIdForCommand} for debugger.`);
         } else {
-            console.warn(BG_LOG_PREFIX, `Tab ${targetTabIdForCommand} is not being debugged. Cannot associate requestId for debugger.`);
-        }
+            const errorMsg = "Could not find any suitable tab for command.";
+            console.error(`BACKGROUND: ${errorMsg} for requestId: ${command.requestId}.`);
+
+            if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                relaySocket.send(JSON.stringify({
+                    type: "CHAT_RESPONSE_ERROR",
+                    requestId: command.requestId,
+                    error: errorMsg
+                }));
+                console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR to server for requestId: ${command.requestId} (no suitable tab).`);
+            } else {
+                console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE_ERROR for requestId: ${command.requestId} (no suitable tab).`);
+            }
 
-        // Now actually send the command
-        chrome.tabs.sendMessage(targetTabIdForCommand, command, (response) => {
-          if (chrome.runtime.lastError) {
-            console.error(`BACKGROUND: Error sending message to tab ${targetTabIdForCommand}:`, chrome.runtime.lastError.message);
-            if (lastRequestId === command.requestId) { 
+            if (lastRequestId === command.requestId) {
                 processingRequest = false;
+                currentRequestTargetTabId = null;
+                console.log(`BACKGROUND: Reset processingRequest and currentRequestTargetTabId for requestId: ${command.requestId} (no suitable tab).`);
             }
-          } else {
-            console.log(`BACKGROUND: Content script in tab ${targetTabIdForCommand} acknowledged command:`, response);
-          }
-        });
+            processNextRequest();
+        }
 
-    } else {
-        const errorMsg = "Could not find any suitable tab for command.";
-        console.error(`BACKGROUND: ${errorMsg} for requestId: ${command.requestId}.`);
-        
+    } catch (error) {
+        console.error("BACKGROUND: Error in forwardCommandToContentScript for requestId:", command.requestId, error);
         if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
             relaySocket.send(JSON.stringify({
                 type: "CHAT_RESPONSE_ERROR",
                 requestId: command.requestId,
-                error: errorMsg
+                error: `Internal error in background script while forwarding command: ${error.message}`
             }));
-            console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR to server for requestId: ${command.requestId} (no suitable tab).`);
+            console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR to server for requestId: ${command.requestId} (exception).`);
         } else {
-            console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE_ERROR for requestId: ${command.requestId} (no suitable tab).`);
+            console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE_ERROR for requestId: ${command.requestId} (exception).`);
         }
 
         if (lastRequestId === command.requestId) {
             processingRequest = false;
-            console.log(`BACKGROUND: Reset processingRequest for requestId: ${command.requestId} (no suitable tab).`);
+            currentRequestTargetTabId = null;
+            console.log(`BACKGROUND: Reset processingRequest and currentRequestTargetTabId for requestId: ${command.requestId} (exception).`);
         }
-        // Ensure processNextRequest is called to handle any queued items,
-        // even if this one failed.
-        processNextRequest();
     }
-
-  } catch (error) {
-    console.error("BACKGROUND: Error in forwardCommandToContentScript for requestId:", command.requestId, error);
-    // Send an error back to the server if an unexpected error occurs during forwarding
-    if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-        relaySocket.send(JSON.stringify({
-            type: "CHAT_RESPONSE_ERROR",
-            requestId: command.requestId,
-            error: `Internal error in background script while forwarding command: ${error.message}`
-        }));
-        console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR to server for requestId: ${command.requestId} (exception).`);
-    } else {
-        console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE_ERROR for requestId: ${command.requestId} (exception).`);
-    }
-
-    if (lastRequestId === command.requestId) {
-        processingRequest = false;
-        console.log(`BACKGROUND: Reset processingRequest for requestId: ${command.requestId} (exception).`);
-    }
-  }
 }
 
-// Helper function to find a suitable tab and send the command
 async function findAndSendToSuitableTab(command, justFinding = false) {
-  try {
-    console.log("BACKGROUND: Finding suitable tab for command:", command);
-    const allTabs = await chrome.tabs.query({});
-    const matchingTabs = allTabs.filter(tab => {
-      if (!tab.url) return false;
-      return supportedDomains.some(domain => tab.url.includes(domain));
-    });
-    
-    console.log(`BACKGROUND: Found ${matchingTabs.length} tabs matching supported domains`);
-    
-    if (matchingTabs.length > 0) {
-      const activeMatchingTabs = matchingTabs.filter(tab => tab.active);
-      const targetTab = activeMatchingTabs.length > 0 ? activeMatchingTabs[0] : matchingTabs[0];
-      console.log(`BACKGROUND: Selected tab ${targetTab.id} (${targetTab.url})`);
-      activeTabId = targetTab.id; // Update global activeTabId
-
-      if (justFinding) {
-          return targetTab.id;
-      }
-      
-      console.warn("BACKGROUND: findAndSendToSuitableTab called with justFinding=false. Sending is now handled by caller.");
-      return targetTab.id; 
+    try {
+        console.log("BACKGROUND: Finding suitable tab for command:", command);
+        const allTabs = await chrome.tabs.query({});
+        const matchingTabs = allTabs.filter(tab => {
+            if (!tab.url) return false;
+            return supportedDomains.some(domain => tab.url.includes(domain));
+        });
 
-    } else {
-      console.error("BACKGROUND: Could not find any tabs matching supported domains.");
-      return null;
+        console.log(`BACKGROUND: Found ${matchingTabs.length} tabs matching supported domains`);
+
+        if (matchingTabs.length > 0) {
+            const activeMatchingTabs = matchingTabs.filter(tab => tab.active);
+            const targetTab = activeMatchingTabs.length > 0 ? activeMatchingTabs[0] : matchingTabs[0];
+            console.log(`BACKGROUND: Selected tab ${targetTab.id} (${targetTab.url})`);
+            activeTabId = targetTab.id;
+
+            if (justFinding) {
+                return targetTab.id;
+            }
+
+            console.warn("BACKGROUND: findAndSendToSuitableTab called with justFinding=false. Sending is now handled by caller.");
+            return targetTab.id;
+
+        } else {
+            console.error("BACKGROUND: Could not find any tabs matching supported domains.");
+            return null;
+        }
+    } catch (error) {
+        console.error("BACKGROUND: Error finding suitable tab:", error);
+        return null;
     }
-  } catch (error) {
-    console.error("BACKGROUND: Error finding suitable tab:", error);
-    return null;
-  }
 }
 
-// Process the next request in the queue
 function processNextRequest() {
-  console.log("BACKGROUND: Processing next request, queue length:", pendingRequests.length);
-  if (processingRequest && pendingRequests.length > 0) {
-      console.log("BACKGROUND: Still processing a request, deferring processNextRequest call.");
-      return; 
-  }
-  
-  if (pendingRequests.length > 0) {
-    const nextCommand = pendingRequests.shift();
-    console.log("BACKGROUND: Processing next command from queue:", nextCommand);
-    
-    // Ensure details are stored if this came from the pendingRequests queue
-    // (though ideally they are stored when initially received from server)
-    if (!pendingRequestDetails.has(nextCommand.requestId) && nextCommand.message !== undefined) {
-        pendingRequestDetails.set(nextCommand.requestId, { messageContent: nextCommand.message }); // Use messageContent
-        let preview = typeof nextCommand.message === 'string' ? `"${nextCommand.message.substring(0,30)}..."` : `Type: ${typeof nextCommand.message}`;
-        console.log(`BACKGROUND: Stored details (messageContent) for queued requestId: ${nextCommand.requestId} (Message: ${preview}) while processing queue.`);
+    console.log("BACKGROUND: Processing next request, queue length:", pendingRequests.length);
+    if (processingRequest && pendingRequests.length > 0) {
+        console.log("BACKGROUND: Still processing a request, deferring processNextRequest call.");
+        return;
     }
 
-    processingRequest = true;
-    lastRequestId = nextCommand.requestId;
-    
-    // Add a delay before forwarding the command
-    setTimeout(() => {
-        forwardCommandToContentScript({
-          action: "SEND_CHAT_MESSAGE",
-          requestId: nextCommand.requestId,
-          messageContent: nextCommand.message,
-          settings: nextCommand.settings,
-          lastProcessedText: lastSuccessfullyProcessedMessageText // Pass the text of the last successfully processed message
-        });
-    }, 500); // 500ms delay
-  } else {
-    console.log("BACKGROUND: No pending requests to process.");
-  }
+    if (pendingRequests.length > 0) {
+        const nextCommand = pendingRequests.shift();
+        console.log("BACKGROUND: Processing next command from queue:", nextCommand);
+
+        if (!pendingRequestDetails.has(nextCommand.requestId) && nextCommand.message !== undefined) {
+            pendingRequestDetails.set(nextCommand.requestId, { messageContent: nextCommand.message });
+            let preview = typeof nextCommand.message === 'string' ? `"${nextCommand.message.substring(0, 30)}..."` : `Type: ${typeof nextCommand.message}`;
+            console.log(`BACKGROUND: Stored details (messageContent) for queued requestId: ${nextCommand.requestId} (Message: ${preview}) while processing queue.`);
+        }
+
+        processingRequest = true;
+        lastRequestId = nextCommand.requestId;
+
+        setTimeout(() => {
+            forwardCommandToContentScript({
+                action: "SEND_CHAT_MESSAGE",
+                requestId: nextCommand.requestId,
+                messageContent: nextCommand.message,
+                settings: nextCommand.settings,
+                lastProcessedText: lastSuccessfullyProcessedMessageText
+            });
+        }, 500);
+    } else {
+        console.log("BACKGROUND: No pending requests to process.");
+    }
 }
 
-// Helper function to check if a URL is supported by a given provider
-// This might need to be more sophisticated if provider domains are complex
 function isUrlSupportedByProvider(url, providerName) {
-    // This function would need access to the provider definitions or a shared config
-    // For AIStudioProvider:
     if (providerName === "AIStudioProvider") {
         return url.includes("aistudio.google.com");
     }
-    // For GeminiProvider:
     if (providerName === "GeminiProvider") {
         return url.includes("gemini.google.com");
     }
-    // For ChatGPTProvider:
-    if (providerName === "ChatGptProvider") { // Match the casing used by the provider's .name property
+    if (providerName === "ChatGptProvider") {
         return url.includes("chatgpt.com");
     }
-    // For ClaudeProvider:
-    if (providerName === "ClaudeProvider") { // Match the casing used by the provider's .name property
+    if (providerName === "ClaudeProvider") {
         return url.includes("claude.ai");
     }
-    // Add other providers if necessary
     console.warn(BG_LOG_PREFIX, `isUrlSupportedByProvider: Unknown providerName '${providerName}'`);
     return false;
 }
 
-// Listen for tab updates
 chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
-  if (changeInfo.status === 'complete' && tab.url) {
-    const isSupportedDomain = supportedDomains.some(domain => tab.url.includes(domain));
-    if (isSupportedDomain) {
-      console.log(`BACKGROUND: A supported tab ${tabId} (${tab.url}) was updated. Checking if it should be the active tab.`);
-      // Potentially update activeTabId, but be careful if multiple supported tabs are open.
-      // The existing logic for activeTabId update via messages from content script might be more reliable.
-      // For now, let's ensure it's set if it's the *only* active one or becomes active.
-      if (tab.active || !activeTabId) {
-           // Check if this tab is actually one of the supported types before making it active
-           // This is a bit redundant with supportedDomains check but good for clarity
-           const currentProvider = providerUtils.getProviderForUrl(tab.url); // Assuming providerUtils is accessible or we have a similar utility
-           if (currentProvider) {
-                activeTabId = tabId;
-                console.log(`BACKGROUND: Set ${tabId} (${tab.url}) as the active tab.`);
-           }
-      }
-    }
-  }
-
-  // Handle debugger re-attachment on URL changes for already debugged tabs
-  const attachmentDetails = debuggerAttachedTabs.get(tabId);
-  if (attachmentDetails && attachmentDetails.isAttached && changeInfo.url && tab && tab.url) {
-    // changeInfo.url is the old URL, tab.url is the new one
-    console.log(BG_LOG_PREFIX, `Tab ${tabId} updated. Old URL: ${changeInfo.url}, New URL: ${tab.url}. Checking debugger status.`);
-
-    const providerStillValidForNewUrl = isUrlSupportedByProvider(tab.url, attachmentDetails.providerName);
-
-    if (providerStillValidForNewUrl) {
-      console.log(BG_LOG_PREFIX, `Tab ${tabId} URL changed to ${tab.url}. Provider ${attachmentDetails.providerName} still valid. Re-initiating debugger attachment.`);
-      const oldProviderName = attachmentDetails.providerName;
-      const oldPatterns = attachmentDetails.patterns; // These patterns were from the content script for the *domain*
-      
-      // Detach first to ensure a clean state, then re-attach.
-      // The 'isAttached' flag in attachmentDetails will be set to false by detachDebugger.
-      await detachDebugger(tabId);
-      
-      // Check if tab still exists (it should, as we are in its onUpdated event)
-      try {
-        const updatedTabInfo = await chrome.tabs.get(tabId);
-        if (updatedTabInfo) {
-            console.log(BG_LOG_PREFIX, `Proactively re-attaching debugger to ${tabId} (${updatedTabInfo.url}) with provider ${oldProviderName}.`);
-            // Content script should send SET_DEBUGGER_TARGETS on its re-initialization.
-            // However, a proactive re-attachment can be beneficial.
-            // The patterns might need to be re-fetched if they are URL-specific beyond the domain.
-            // For now, using oldPatterns, assuming they are domain-level.
-            await attachDebuggerAndEnableFetch(tabId, oldProviderName, oldPatterns);
+    if (changeInfo.status === 'complete' && tab.url) {
+        const isSupportedDomain = supportedDomains.some(domain => tab.url.includes(domain));
+        if (isSupportedDomain) {
+            console.log(`BACKGROUND: A supported tab ${tabId} (${tab.url}) was updated. Checking if it should be the active tab.`);
+            if (tab.active || !activeTabId) {
+                const currentProvider = providerUtils.getProviderForUrl(tab.url);
+                if (currentProvider) {
+                    activeTabId = tabId;
+                    console.log(`BACKGROUND: Set ${tabId} (${tab.url}) as the active tab.`);
+                }
+            }
         }
-      } catch (error) {
-        console.warn(BG_LOG_PREFIX, `Error getting tab info for ${tabId} during re-attachment attempt:`, error.message);
-      }
-
-    } else {
-      console.log(BG_LOG_PREFIX, `Tab ${tabId} URL changed to ${tab.url}. Provider ${attachmentDetails.providerName} no longer valid or URL not supported by provider. Detaching debugger.`);
-      await detachDebugger(tabId);
     }
-  } else if (attachmentDetails && attachmentDetails.isAttached && changeInfo.status === 'loading' && tab && tab.url && !changeInfo.url) {
-    // Sometimes URL change is only visible when status is 'loading' and tab.url is the new one.
-    // This is a more aggressive check.
-    const newUrl = tab.url;
-    console.log(BG_LOG_PREFIX, `Tab ${tabId} is loading new URL: ${newUrl}. Checking debugger status.`);
-    const providerStillValidForNewUrl = isUrlSupportedByProvider(newUrl, attachmentDetails.providerName);
-    if (!providerStillValidForNewUrl) {
-        console.log(BG_LOG_PREFIX, `Tab ${tabId} loading new URL ${newUrl}. Provider ${attachmentDetails.providerName} may no longer be valid. Detaching.`);
-        await detachDebugger(tabId);
+
+    const attachmentDetails = debuggerAttachedTabs.get(tabId);
+    if (attachmentDetails && attachmentDetails.isAttached && changeInfo.url && tab && tab.url) {
+        console.log(BG_LOG_PREFIX, `Tab ${tabId} updated. Old URL: ${changeInfo.url}, New URL: ${tab.url}. Checking debugger status.`);
+
+        const providerStillValidForNewUrl = isUrlSupportedByProvider(tab.url, attachmentDetails.providerName);
+
+        if (providerStillValidForNewUrl) {
+            console.log(BG_LOG_PREFIX, `Tab ${tabId} URL changed to ${tab.url}. Provider ${attachmentDetails.providerName} still valid. Re-initiating debugger attachment.`);
+            const oldProviderName = attachmentDetails.providerName;
+            const oldPatterns = attachmentDetails.patterns;
+
+            await detachDebugger(tabId);
+
+            try {
+                const updatedTabInfo = await chrome.tabs.get(tabId);
+                if (updatedTabInfo) {
+                    console.log(BG_LOG_PREFIX, `Proactively re-attaching debugger to ${tabId} (${updatedTabInfo.url}) with provider ${oldProviderName}.`);
+                    await attachDebuggerAndEnableFetch(tabId, oldProviderName, oldPatterns);
+
+                    if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId) {
+                        const interruptedRequestDetails = pendingRequestDetails.get(lastRequestId);
+                        if (interruptedRequestDetails) {
+                            console.warn(BG_LOG_PREFIX, `Tab ${tabId} update (URL: ${tab.url}) may have interrupted processing for requestId: ${lastRequestId}. Attempting to resend after a delay.`);
+
+                            setTimeout(() => {
+                                if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId && pendingRequestDetails.has(lastRequestId)) {
+                                    console.log(BG_LOG_PREFIX, `Re-forwarding command for interrupted requestId: ${lastRequestId} to tab ${tabId}`);
+                                    forwardCommandToContentScript({
+                                        action: "SEND_CHAT_MESSAGE",
+                                        requestId: lastRequestId,
+                                        messageContent: interruptedRequestDetails.messageContent,
+                                        settings: interruptedRequestDetails.settings,
+                                        lastProcessedText: lastSuccessfullyProcessedMessageText
+                                    });
+                                } else {
+                                    console.log(BG_LOG_PREFIX, `Resend for ${lastRequestId} aborted; state changed before resend timeout. Current processing: ${processingRequest}, current lastReqId: ${lastRequestId}, current targetTab: ${currentRequestTargetTabId}, details still pending: ${pendingRequestDetails.has(lastRequestId)}`);
+                                }
+                            }, 2000);
+                        } else {
+                            console.warn(BG_LOG_PREFIX, `Tab ${tabId} update occurred while processing requestId: ${lastRequestId}, but no details found in pendingRequestDetails to resend. The request might have been cleared by another process.`);
+
+                            if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId) {
+                                console.error(BG_LOG_PREFIX, `Critical state: Tab update for ${tabId} (target of ${lastRequestId}), but details missing. Forcing reset of processing state for ${lastRequestId}.`);
+                                if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                                    relaySocket.send(JSON.stringify({
+                                        type: "CHAT_RESPONSE_ERROR",
+                                        requestId: lastRequestId,
+                                        error: `Request ${lastRequestId} processing was interrupted by tab update and its details were lost. Cannot resend.`
+                                    }));
+                                }
+                                processingRequest = false;
+                                currentRequestTargetTabId = null;
+                                pendingRequestDetails.delete(lastRequestId);
+                                const tabInfoForReset = debuggerAttachedTabs.get(tabId);
+                                if (tabInfoForReset && tabInfoForReset.lastKnownRequestId === lastRequestId) {
+                                    tabInfoForReset.lastKnownRequestId = null;
+                                }
+                                processNextRequest();
+                            }
+                        }
+                    }
+
+                    if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId) {
+                        const interruptedRequestDetails = pendingRequestDetails.get(lastRequestId);
+                        if (interruptedRequestDetails) {
+                            console.warn(BG_LOG_PREFIX, `Tab ${tabId} update (URL: ${tab.url}) may have interrupted processing for requestId: ${lastRequestId}. Attempting to resend after a delay.`);
+
+                            setTimeout(() => {
+                                if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId && pendingRequestDetails.has(lastRequestId)) {
+                                    console.log(BG_LOG_PREFIX, `Re-forwarding command for interrupted requestId: ${lastRequestId} to tab ${tabId}`);
+                                    forwardCommandToContentScript({
+                                        action: "SEND_CHAT_MESSAGE",
+                                        requestId: lastRequestId,
+                                        messageContent: interruptedRequestDetails.messageContent,
+                                        settings: interruptedRequestDetails.settings,
+                                        lastProcessedText: lastSuccessfullyProcessedMessageText
+                                    });
+                                } else {
+                                    console.log(BG_LOG_PREFIX, `Resend for ${lastRequestId} aborted; state changed before resend timeout. Current processing: ${processingRequest}, current lastReqId: ${lastRequestId}, current targetTab: ${currentRequestTargetTabId}, details still pending: ${pendingRequestDetails.has(lastRequestId)}`);
+                                }
+                            }, 2000);
+                        } else {
+                            console.warn(BG_LOG_PREFIX, `Tab ${tabId} update occurred while processing requestId: ${lastRequestId}, but no details found in pendingRequestDetails to resend. The request might have been cleared by another process.`);
+                            if (processingRequest && lastRequestId !== null && tabId === currentRequestTargetTabId) {
+                                console.error(BG_LOG_PREFIX, `Critical state: Tab update for ${tabId} (target of ${lastRequestId}), but details missing. Forcing reset of processing state for ${lastRequestId}.`);
+                                if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                                    relaySocket.send(JSON.stringify({
+                                        type: "CHAT_RESPONSE_ERROR",
+                                        requestId: lastRequestId,
+                                        error: `Request ${lastRequestId} processing was interrupted by tab update and its details were lost. Cannot resend.`
+                                    }));
+                                }
+                                processingRequest = false;
+                                currentRequestTargetTabId = null;
+                                pendingRequestDetails.delete(lastRequestId);
+                                const tabInfoForReset = debuggerAttachedTabs.get(tabId);
+                                if (tabInfoForReset && tabInfoForReset.lastKnownRequestId === lastRequestId) {
+                                    tabInfoForReset.lastKnownRequestId = null;
+                                }
+                                processNextRequest();
+                            }
+                        }
+                    }
+                }
+            } catch (error) {
+                console.warn(BG_LOG_PREFIX, `Error getting tab info for ${tabId} during re-attachment attempt:`, error.message);
+            }
+
+        } else {
+            console.log(BG_LOG_PREFIX, `Tab ${tabId} URL changed to ${tab.url}. Provider ${attachmentDetails.providerName} no longer valid or URL not supported by provider. Detaching debugger.`);
+            await detachDebugger(tabId);
+        }
+    } else if (attachmentDetails && attachmentDetails.isAttached && changeInfo.status === 'loading' && tab && tab.url && !changeInfo.url) {
+        const newUrl = tab.url;
+        console.log(BG_LOG_PREFIX, `Tab ${tabId} is loading new URL: ${newUrl}. Checking debugger status.`);
+        const providerStillValidForNewUrl = isUrlSupportedByProvider(newUrl, attachmentDetails.providerName);
+        if (!providerStillValidForNewUrl) {
+            console.log(BG_LOG_PREFIX, `Tab ${tabId} loading new URL ${newUrl}. Provider ${attachmentDetails.providerName} may no longer be valid. Detaching.`);
+            await detachDebugger(tabId);
+        }
     }
-    // If provider is still valid, we'll let the 'complete' status handler above deal with re-attachment if needed,
-    // or rely on content script sending SET_DEBUGGER_TARGETS.
-  }
 });
 
-// Listen for messages from Content Scripts and Popup
 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
-  console.log("BACKGROUND: Received message:", message.type || message.action, "from tabId:", sender.tab ? sender.tab.id : 'popup/unknown');
-  
-  if (sender.tab && sender.tab.id) {
-    activeTabId = sender.tab.id; // User's original logic for activeTabId
-    console.log(`BACKGROUND: Updated activeTabId to ${activeTabId} from sender`);
-  }
-
-  if (message.type === "SET_DEBUGGER_TARGETS") {
-      if (sender.tab && sender.tab.id) {
-          const tabId = sender.tab.id;
-          console.log(BG_LOG_PREFIX, `SET_DEBUGGER_TARGETS for tab ${tabId}, provider: ${message.providerName}, patterns:`, message.patterns);
-          attachDebuggerAndEnableFetch(tabId, message.providerName, message.patterns);
-          sendResponse({ status: "Debugger attachment initiated" });
-      } else {
-          console.error(BG_LOG_PREFIX, "SET_DEBUGGER_TARGETS message received without valid sender.tab.id");
-          sendResponse({ status: "Error: Missing tabId" });
-      }
-      return true; 
-  } 
-  else if (message.type === "CHAT_RELAY_READY") {
-    console.log(`BACKGROUND: Content script ready in ${message.chatInterface} on tab ${sender.tab ? sender.tab.id : 'unknown'}`);
-    if (sender.tab && sender.tab.id) activeTabId = sender.tab.id;
-    sendResponse({ success: true });
-    return true; // Indicate that sendResponse might be used (even if synchronously here)
-  } else if (message.action === "RESPONSE_CAPTURED") {
-    console.log(`BACKGROUND: Received captured response (OLD DOM METHOD) from content script on tab ${sender.tab ? sender.tab.id : 'unknown'} Request ID: ${message.requestId}`);
-    
-    if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-      console.log("BACKGROUND: Forwarding (OLD DOM) response to relay server:", message.response);
-      relaySocket.send(JSON.stringify({
-        type: "CHAT_RESPONSE", 
-        requestId: message.requestId, 
-        response: message.response,
-        isFinal: true 
-      }));
-      sendResponse({ success: true });
-      
-      if (lastRequestId === message.requestId) {
-          processingRequest = false;
-          console.log("BACKGROUND: Reset processingRequest after (OLD DOM) RESPONSE_CAPTURED.");
-          processNextRequest();
-      }
+    console.log("BACKGROUND: Received message:", message.type || message.action, "from tabId:", sender.tab ? sender.tab.id : 'popup/unknown');
 
-    } else {
-      console.error("BACKGROUND: Relay WS not connected, cannot forward (OLD DOM) response");
-      sendResponse({ success: false, error: "Relay WebSocket not connected" });
-      if (lastRequestId === message.requestId) {
-          processingRequest = false;
-      }
+    if (sender.tab && sender.tab.id) {
+        activeTabId = sender.tab.id;
+        console.log(`BACKGROUND: Updated activeTabId to ${activeTabId} from sender`);
     }
-    return true; 
-  } else if (message.action === "GET_CONNECTION_STATUS") {
-    const isConnected = relaySocket && relaySocket.readyState === WebSocket.OPEN;
-    sendResponse({ connected: isConnected });
-    return true; // Indicate that sendResponse might be used
-  } else if (message.type === "CHAT_RESPONSE_FROM_DOM") {
-    console.log(`BACKGROUND: Received CHAT_RESPONSE_FROM_DOM from tab ${sender.tab ? sender.tab.id : 'unknown'} for requestId ${message.requestId}`);
-    const tabId = sender.tab ? sender.tab.id : null;
-    const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
-
-    if (tabInfo && tabInfo.lastKnownRequestId === message.requestId && processingRequest) {
-        if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-            relaySocket.send(JSON.stringify({
-                type: "CHAT_RESPONSE_CHUNK",
-                requestId: message.requestId,
-                chunk: message.text,
-                isFinal: message.isFinal !== undefined ? message.isFinal : true
-            }));
-            relaySocket.send(JSON.stringify({
-                type: "CHAT_RESPONSE_STREAM_ENDED",
-                requestId: message.requestId
-            }));
-            console.log(`BACKGROUND: Sent CHAT_RESPONSE_CHUNK (from DOM) and _STREAM_ENDED for app requestId: ${message.requestId}`);
-            sendResponse({ success: true, message: "DOM Response forwarded to relay." });
+
+    if (message.type === "SET_DEBUGGER_TARGETS") {
+        if (sender.tab && sender.tab.id) {
+            const tabId = sender.tab.id;
+            console.log(BG_LOG_PREFIX, `SET_DEBUGGER_TARGETS for tab ${tabId}, provider: ${message.providerName}, patterns:`, message.patterns);
+            attachDebuggerAndEnableFetch(tabId, message.providerName, message.patterns);
+            sendResponse({ status: "Debugger attachment initiated" });
         } else {
-            console.error(`BACKGROUND: Relay WS not connected, cannot send DOM-captured response for requestId: ${message.requestId}`);
-            sendResponse({ success: false, error: "Relay WebSocket not connected." });
+            console.error(BG_LOG_PREFIX, "SET_DEBUGGER_TARGETS message received without valid sender.tab.id");
+            sendResponse({ status: "Error: Missing tabId" });
         }
-        // Finalize this request processing
-        processingRequest = false;
-        if (tabInfo) tabInfo.lastKnownRequestId = null; // Clear for this specific tab op
-        console.log(`BACKGROUND: Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId} after DOM response.`);
-        processNextRequest();
-    } else {
-        console.warn(`BACKGROUND: Mismatched requestId or not processing for CHAT_RESPONSE_FROM_DOM. Current lastKnownRequestId: ${tabInfo ? tabInfo.lastKnownRequestId : 'N/A'}, processingRequest: ${processingRequest}, msg RequestId: ${message.requestId}`);
-        sendResponse({ success: false, error: "Mismatched requestId or not processing." });
+        return true;
     }
-    return true;
-  } else if (message.type === "CHAT_RESPONSE_FROM_DOM_FAILED") {
-    console.error(`BACKGROUND: Received CHAT_RESPONSE_FROM_DOM_FAILED from tab ${sender.tab ? sender.tab.id : 'unknown'} for requestId ${message.requestId}: ${message.error}`);
-    const tabId = sender.tab ? sender.tab.id : null;
-    const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
+    else if (message.type === "CHAT_RELAY_READY") {
+        console.log(`BACKGROUND: Content script ready in ${message.chatInterface} on tab ${sender.tab ? sender.tab.id : 'unknown'}`);
+        if (sender.tab && sender.tab.id) activeTabId = sender.tab.id;
+        sendResponse({ success: true });
+        return true;
+    } else if (message.action === "RESPONSE_CAPTURED") {
+        console.log(`BACKGROUND: Received captured response (OLD DOM METHOD) from content script on tab ${sender.tab ? sender.tab.id : 'unknown'} Request ID: ${message.requestId}`);
 
-    if (tabInfo && tabInfo.lastKnownRequestId === message.requestId && processingRequest) {
-        if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-            relaySocket.send(JSON.stringify({
-                type: "CHAT_RESPONSE_ERROR",
-                requestId: message.requestId,
-                error: `Failed to capture response from DOM on tab ${tabId}: ${message.error}`
-            }));
-        }
-        sendResponse({ success: true, message: "DOM failure noted and error sent to relay." });
-        // Finalize this request processing
-        processingRequest = false;
-        if (tabInfo) tabInfo.lastKnownRequestId = null;
-        console.log(`BACKGROUND: Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId} after DOM failure.`);
-        processNextRequest();
-    } else {
-        console.warn(`BACKGROUND: Mismatched requestId or not processing for CHAT_RESPONSE_FROM_DOM_FAILED. Current lastKnownRequestId: ${tabInfo ? tabInfo.lastKnownRequestId : 'N/A'}, processingRequest: ${processingRequest}, msg RequestId: ${message.requestId}`);
-        sendResponse({ success: false, error: "Mismatched requestId or not processing for DOM failure." });
-    }
-    return true;
-  } else if (message.type === "FINAL_RESPONSE_TO_RELAY") {
-      console.log(BG_LOG_PREFIX, `[REQ-${message.requestId}] RECEIVED FINAL_RESPONSE_TO_RELAY. FromTab: ${sender.tab ? sender.tab.id : 'N/A'}. HasError: ${!!message.error}. TextLength: ${message.text ? String(message.text).length : 'N/A'}. IsFinal: ${message.isFinal}. FullMsg:`, JSON.stringify(message).substring(0,500));
-      const tabId = sender.tab ? sender.tab.id : null;
-      const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
-
-      // Update lastSuccessfullyProcessedMessageText regardless of current processing state,
-      // as this confirms a message text was fully processed by the AI.
-      const details = pendingRequestDetails.get(message.requestId);
-      if (details) {
-          if (typeof details.messageContent === 'string') {
-              lastSuccessfullyProcessedMessageText = details.messageContent;
-              console.log(`BACKGROUND: Updated lastSuccessfullyProcessedMessageText to: "${lastSuccessfullyProcessedMessageText.substring(0,50)}..." for completed requestId ${message.requestId}`);
-          } else {
-              console.log(`BACKGROUND: RequestId ${message.requestId} (messageContent type: ${typeof details.messageContent}) completed. lastSuccessfullyProcessedMessageText not updated with non-string content.`);
-          }
-          pendingRequestDetails.delete(message.requestId);
-      } else {
-          console.warn(`BACKGROUND: Received FINAL_RESPONSE_TO_RELAY for unknown requestId ${message.requestId} (not in pendingRequestDetails). Cannot update lastSuccessfullyProcessedMessageText accurately.`);
-      }
-
-      // Check if this is the request we are currently processing for state reset
-      if (processingRequest && lastRequestId === message.requestId) {
-          if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-              if (message.error) { // Check if content.js sent an error (e.g., response too large)
-                  console.error(BG_LOG_PREFIX, `Content script reported an error for requestId ${message.requestId}: ${message.error}`);
-                  try {
-                      relaySocket.send(JSON.stringify({
-                          type: "CHAT_RESPONSE_ERROR",
-                          requestId: message.requestId,
-                          error: message.error
-                      }));
-                      console.log(BG_LOG_PREFIX, `Sent CHAT_RESPONSE_ERROR to server for requestId ${message.requestId} due to content script error.`);
-                      sendResponse({ success: true, message: "Error reported by content script sent to relay." });
-                  } catch (e) {
-                      console.error(BG_LOG_PREFIX, `Error sending CHAT_RESPONSE_ERROR to relay for requestId ${message.requestId}:`, e);
-                      sendResponse({ success: false, error: `Error sending CHAT_RESPONSE_ERROR to relay: ${e.message}` });
-                  }
-              } else { // No error from content.js, proceed to send data
-                  try {
-                      const responseText = message.text || "";
-                      console.log(BG_LOG_PREFIX, `Attempting to send FINAL CHAT_RESPONSE_CHUNK for requestId ${message.requestId}. Data length: ${responseText.length}`);
-                      relaySocket.send(JSON.stringify({
-                          type: "CHAT_RESPONSE_CHUNK",
-                          requestId: message.requestId,
-                          chunk: responseText,
-                          isFinal: true
-                      }));
-                      console.log(BG_LOG_PREFIX, `Attempting to send CHAT_RESPONSE_STREAM_ENDED for requestId ${message.requestId}`);
-                      relaySocket.send(JSON.stringify({
-                          type: "CHAT_RESPONSE_STREAM_ENDED",
-                          requestId: message.requestId
-                      }));
-                      console.log(BG_LOG_PREFIX, `Successfully sent FINAL CHAT_RESPONSE_CHUNK and _STREAM_ENDED for app requestId: ${message.requestId} to relaySocket.`);
-                      sendResponse({ success: true, message: "Final response sent to relay." });
-                  } catch (e) {
-                      console.error(BG_LOG_PREFIX, `Error during relaySocket.send() for FINAL response (requestId ${message.requestId}):`, e);
-                      sendResponse({ success: false, error: `Error sending final response to relay: ${e.message}` });
-                  }
-              }
-          } else {
-              console.error(BG_LOG_PREFIX, `Relay WS not OPEN (state: ${relaySocket ? relaySocket.readyState : 'null'}), cannot send final response/error for app requestId: ${message.requestId}`);
-              sendResponse({ success: false, error: "Relay WebSocket not connected." });
-          }
-
-          // Finalize this request processing
-          console.log(BG_LOG_PREFIX, `Processing complete for command with app requestId: ${message.requestId} on tab ${tabId}`);
-          processingRequest = false;
-          if (tabInfo) tabInfo.lastKnownRequestId = null;
-          console.log(BG_LOG_PREFIX, `Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId}.`);
-          processNextRequest();
-      } else {
-          console.warn(`BACKGROUND: Received FINAL_RESPONSE_TO_RELAY for requestId ${message.requestId}, but not currently processing it (current: ${lastRequestId}, processing: ${processingRequest}). Ignoring.`);
-          sendResponse({ success: false, error: "Request ID mismatch or not processing." });
-      }
-      return true; // Indicate async response potentially
-  } else if (message.type === "DUPLICATE_MESSAGE_HANDLED") {
-    console.log(`BACKGROUND: Content script handled requestId ${message.requestId} as a duplicate of text: "${message.originalText ? message.originalText.substring(0,50) : 'N/A'}..."`);
-    
-    // Update last successfully processed text because this text was confirmed as a duplicate of it.
-    lastSuccessfullyProcessedMessageText = message.originalText;
-    pendingRequestDetails.delete(message.requestId); // Clean up details map
-    console.log(`BACKGROUND: Updated lastSuccessfullyProcessedMessageText (due to duplicate) to: "${lastSuccessfullyProcessedMessageText ? lastSuccessfullyProcessedMessageText.substring(0,50) : 'N/A'}..."`);
-
-    if (processingRequest && lastRequestId === message.requestId) {
         if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+            console.log("BACKGROUND: Forwarding (OLD DOM) response to relay server:", message.response);
             relaySocket.send(JSON.stringify({
                 type: "CHAT_RESPONSE",
                 requestId: message.requestId,
-                response: `[ChatRelay Extension] Request to send duplicate message ("${message.originalText ? message.originalText.substring(0,100) : 'N/A'}") was detected and cleared from input. No message sent to AI.`,
+                response: message.response,
                 isFinal: true
             }));
-            console.log(`BACKGROUND: Sent CHAT_RESPONSE (for duplicate) to server for requestId: ${message.requestId}.`);
+            sendResponse({ success: true });
+
+            if (lastRequestId === message.requestId) {
+                processingRequest = false;
+                console.log("BACKGROUND: Reset processingRequest after (OLD DOM) RESPONSE_CAPTURED.");
+                processNextRequest();
+            }
+
         } else {
-            console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE (for duplicate) for requestId: ${message.requestId}.`);
+            console.error("BACKGROUND: Relay WS not connected, cannot forward (OLD DOM) response");
+            sendResponse({ success: false, error: "Relay WebSocket not connected" });
+            if (lastRequestId === message.requestId) {
+                processingRequest = false;
+            }
         }
-
-        processingRequest = false;
-        // lastRequestId remains, it's the ID of the last command *received*
-        // currentRequestText (if used) would be nulled here.
-        const tabInfo = sender.tab ? debuggerAttachedTabs.get(sender.tab.id) : null;
-        if (tabInfo && tabInfo.lastKnownRequestId === message.requestId) {
-             tabInfo.lastKnownRequestId = null;
+        return true;
+    } else if (message.action === "GET_CONNECTION_STATUS") {
+        const isConnected = relaySocket && relaySocket.readyState === WebSocket.OPEN;
+        sendResponse({ connected: isConnected });
+        return true;
+    } else if (message.type === "CHAT_RESPONSE_FROM_DOM") {
+        console.log(`BACKGROUND: Received CHAT_RESPONSE_FROM_DOM from tab ${sender.tab ? sender.tab.id : 'unknown'} for requestId ${message.requestId}`);
+        const tabId = sender.tab ? sender.tab.id : null;
+        const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
+
+        if (tabInfo && tabInfo.lastKnownRequestId === message.requestId && processingRequest) {
+            if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                relaySocket.send(JSON.stringify({
+                    type: "CHAT_RESPONSE_CHUNK",
+                    requestId: message.requestId,
+                    chunk: message.text,
+                    isFinal: message.isFinal !== undefined ? message.isFinal : true
+                }));
+                relaySocket.send(JSON.stringify({
+                    type: "CHAT_RESPONSE_STREAM_ENDED",
+                    requestId: message.requestId
+                }));
+                console.log(`BACKGROUND: Sent CHAT_RESPONSE_CHUNK (from DOM) and _STREAM_ENDED for app requestId: ${message.requestId}`);
+                sendResponse({ success: true, message: "DOM Response forwarded to relay." });
+            } else {
+                console.error(`BACKGROUND: Relay WS not connected, cannot send DOM-captured response for requestId: ${message.requestId}`);
+                sendResponse({ success: false, error: "Relay WebSocket not connected." });
+            }
+            processingRequest = false;
+            if (tabInfo) tabInfo.lastKnownRequestId = null;
+            console.log(`BACKGROUND: Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId} after DOM response.`);
+            processNextRequest();
+        } else {
+            console.warn(`BACKGROUND: Mismatched requestId or not processing for CHAT_RESPONSE_FROM_DOM. Current lastKnownRequestId: ${tabInfo ? tabInfo.lastKnownRequestId : 'N/A'}, processingRequest: ${processingRequest}, msg RequestId: ${message.requestId}`);
+            sendResponse({ success: false, error: "Mismatched requestId or not processing." });
         }
+        return true;
+    } else if (message.type === "CHAT_RESPONSE_FROM_DOM_FAILED") {
+        console.error(`BACKGROUND: Received CHAT_RESPONSE_FROM_DOM_FAILED from tab ${sender.tab ? sender.tab.id : 'unknown'} for requestId ${message.requestId}: ${message.error}`);
+        const tabId = sender.tab ? sender.tab.id : null;
+        const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
 
-        console.log(`BACKGROUND: Reset processingRequest after DUPLICATE_MESSAGE_HANDLED for requestId: ${message.requestId}.`);
-        processNextRequest();
-    } else {
-        console.warn(`BACKGROUND: Received DUPLICATE_MESSAGE_HANDLED for requestId ${message.requestId}, but not currently processing it or ID mismatch. Current lastRequestId: ${lastRequestId}, processing: ${processingRequest}. Still updated LSPMT.`);
-        // If it was an older request, its details are cleaned, LSPMT updated. Server informed if possible.
-         if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-            relaySocket.send(JSON.stringify({
-                type: "CHAT_RESPONSE",
-                requestId: message.requestId,
-                response: `[ChatRelay Extension] An older/superseded request (ID: ${message.requestId}, Text: "${message.originalText ? message.originalText.substring(0,100) : 'N/A'}") was handled as a duplicate.`,
-                isFinal: true
-            }));
+        if (tabInfo && tabInfo.lastKnownRequestId === message.requestId && processingRequest) {
+            if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                relaySocket.send(JSON.stringify({
+                    type: "CHAT_RESPONSE_ERROR",
+                    requestId: message.requestId,
+                    error: `Failed to capture response from DOM on tab ${tabId}: ${message.error}`
+                }));
+            }
+            sendResponse({ success: true, message: "DOM failure noted and error sent to relay." });
+            processingRequest = false;
+            if (tabInfo) tabInfo.lastKnownRequestId = null;
+            console.log(`BACKGROUND: Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId} after DOM failure.`);
+            processNextRequest();
+        } else {
+            console.warn(`BACKGROUND: Mismatched requestId or not processing for CHAT_RESPONSE_FROM_DOM_FAILED. Current lastKnownRequestId: ${tabInfo ? tabInfo.lastKnownRequestId : 'N/A'}, processingRequest: ${processingRequest}, msg RequestId: ${message.requestId}`);
+            sendResponse({ success: false, error: "Mismatched requestId or not processing for DOM failure." });
         }
-    }
-    sendResponse({ success: true, message: "Duplicate handling acknowledged by background." });
-    return true;
-  } else if (message.type === "USER_STOP_REQUEST") {
-    const requestIdToStop = message.requestId;
-    console.log(`BACKGROUND: Received USER_STOP_REQUEST for requestId: ${requestIdToStop}`);
-    let responseSent = false; // To ensure sendResponse is called once
-
-    // Case 1: The request to stop is the currently processing one.
-    if (processingRequest && lastRequestId === requestIdToStop) {
-        console.log(`BACKGROUND: Initiating stop for currently processing request: ${lastRequestId}. Content script will send FINAL_RESPONSE_TO_RELAY.`);
-        if (activeTabId) {
-            chrome.tabs.sendMessage(activeTabId, {
-                action: "STOP_STREAMING",
-                requestId: lastRequestId
-            }, response => {
-                if (chrome.runtime.lastError) {
-                    console.error(`BACKGROUND: Error sending STOP_STREAMING to tab ${activeTabId} for requestId ${lastRequestId}:`, chrome.runtime.lastError.message);
+        return true;
+    } else if (message.type === "FINAL_RESPONSE_TO_RELAY") {
+        console.log(BG_LOG_PREFIX, `[REQ-${message.requestId}] RECEIVED FINAL_RESPONSE_TO_RELAY. FromTab: ${sender.tab ? sender.tab.id : 'N/A'}. HasError: ${!!message.error}. TextLength: ${message.text ? String(message.text).length : 'N/A'}. IsFinal: ${message.isFinal}. FullMsg:`, JSON.stringify(message).substring(0, 500));
+        const tabId = sender.tab ? sender.tab.id : null;
+        const tabInfo = tabId ? debuggerAttachedTabs.get(tabId) : null;
+
+        const details = pendingRequestDetails.get(message.requestId);
+        if (details) {
+            if (typeof details.messageContent === 'string') {
+                lastSuccessfullyProcessedMessageText = details.messageContent;
+                console.log(`BACKGROUND: Updated lastSuccessfullyProcessedMessageText to: "${lastSuccessfullyProcessedMessageText.substring(0, 50)}..." for completed requestId ${message.requestId}`);
+            } else {
+                console.log(`BACKGROUND: RequestId ${message.requestId} (messageContent type: ${typeof details.messageContent}) completed. lastSuccessfullyProcessedMessageText not updated with non-string content.`);
+            }
+            pendingRequestDetails.delete(message.requestId);
+        } else {
+            console.warn(`BACKGROUND: Received FINAL_RESPONSE_TO_RELAY for unknown requestId ${message.requestId} (not in pendingRequestDetails). Cannot update lastSuccessfullyProcessedMessageText accurately.`);
+        }
+
+        if (processingRequest && lastRequestId === message.requestId) {
+            if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                if (message.error) {
+                    console.error(BG_LOG_PREFIX, `Content script reported an error for requestId ${message.requestId}: ${message.error}`);
+                    try {
+                        relaySocket.send(JSON.stringify({
+                            type: "CHAT_RESPONSE_ERROR",
+                            requestId: message.requestId,
+                            error: message.error
+                        }));
+                        console.log(BG_LOG_PREFIX, `Sent CHAT_RESPONSE_ERROR to server for requestId ${message.requestId} due to content script error.`);
+                        sendResponse({ success: true, message: "Error reported by content script sent to relay." });
+                    } catch (e) {
+                        console.error(BG_LOG_PREFIX, `Error sending CHAT_RESPONSE_ERROR to relay for requestId ${message.requestId}:`, e);
+                        sendResponse({ success: false, error: `Error sending CHAT_RESPONSE_ERROR to relay: ${e.message}` });
+                    }
                 } else {
-                    console.log(`BACKGROUND: Sent STOP_STREAMING to tab ${activeTabId} for requestId ${lastRequestId}. Content script ack:`, response);
+                    try {
+                        let responseText = message.text || "";
+                        
+                        // Decode text if it was encoded by content script
+                        if (message.encoded) {
+                            responseText = decodeURIComponent(responseText);
+                        }
+                        
+                        console.log(BG_LOG_PREFIX, `Attempting to send FINAL CHAT_RESPONSE_CHUNK for requestId ${message.requestId}. Data length: ${responseText.length}`);
+                        relaySocket.send(JSON.stringify({
+                            type: "CHAT_RESPONSE_CHUNK",
+                            requestId: message.requestId,
+                            chunk: responseText,
+                            isFinal: true
+                        }));
+                        console.log(BG_LOG_PREFIX, `Attempting to send CHAT_RESPONSE_STREAM_ENDED for requestId ${message.requestId}`);
+                        relaySocket.send(JSON.stringify({
+                            type: "CHAT_RESPONSE_STREAM_ENDED",
+                            requestId: message.requestId
+                        }));
+                        console.log(BG_LOG_PREFIX, `Successfully sent FINAL CHAT_RESPONSE_CHUNK and _STREAM_ENDED for app requestId: ${message.requestId} to relaySocket.`);
+                        sendResponse({ success: true, message: "Final response sent to relay." });
+                    } catch (e) {
+                        console.error(BG_LOG_PREFIX, `Error during relaySocket.send() for FINAL response (requestId ${message.requestId}):`, e);
+                        sendResponse({ success: false, error: `Error sending final response to relay: ${e.message}` });
+                    }
                 }
-            });
+            } else {
+                console.error(BG_LOG_PREFIX, `Relay WS not OPEN (state: ${relaySocket ? relaySocket.readyState : 'null'}), cannot send final response/error for app requestId: ${message.requestId}`);
+                sendResponse({ success: false, error: "Relay WebSocket not connected." });
+            }
+
+            console.log(BG_LOG_PREFIX, `Processing complete for command with app requestId: ${message.requestId} on tab ${tabId}`);
+            processingRequest = false;
+            currentRequestTargetTabId = null;
+            if (tabInfo) tabInfo.lastKnownRequestId = null;
+            console.log(BG_LOG_PREFIX, `Reset processingRequest. Cleared lastKnownRequestId for tab ${tabId}.`);
+            processNextRequest();
         } else {
-            console.warn(`BACKGROUND: Cannot send STOP_STREAMING for currently processing requestId ${lastRequestId}, activeTabId is null. This request might not be properly finalized by the provider.`);
-            // If no active tab, we can't tell content.js to stop.
-            // We should still inform the relay and clean up what we can,
-            // though the provider state might remain for this request.
+            console.warn(`BACKGROUND: Received FINAL_RESPONSE_TO_RELAY for requestId ${message.requestId}, but not currently processing it (current: ${lastRequestId}, processing: ${processingRequest}). Ignoring.`);
+            sendResponse({ success: false, error: "Request ID mismatch or not processing." });
+        }
+        return true;
+    } else if (message.type === "DUPLICATE_MESSAGE_HANDLED") {
+        console.log(`BACKGROUND: Content script handled requestId ${message.requestId} as a duplicate of text: "${message.originalText ? message.originalText.substring(0, 50) : 'N/A'}..."`);
+
+        lastSuccessfullyProcessedMessageText = message.originalText;
+        pendingRequestDetails.delete(message.requestId);
+        console.log(`BACKGROUND: Updated lastSuccessfullyProcessedMessageText (due to duplicate) to: "${lastSuccessfullyProcessedMessageText ? lastSuccessfullyProcessedMessageText.substring(0, 50) : 'N/A'}..."`);
+
+        if (processingRequest && lastRequestId === message.requestId) {
             if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
                 relaySocket.send(JSON.stringify({
-                    type: "CHAT_RESPONSE_ERROR",
-                    requestId: lastRequestId,
-                    error: "Request cancelled by user (no active tab to signal provider)."
+                    type: "CHAT_RESPONSE",
+                    requestId: message.requestId,
+                    response: `[ChatRelay Extension] Request to send duplicate message ("${message.originalText ? message.originalText.substring(0, 100) : 'N/A'}") was detected and cleared from input. No message sent to AI.`,
+                    isFinal: true
                 }));
+                console.log(`BACKGROUND: Sent CHAT_RESPONSE (for duplicate) to server for requestId: ${message.requestId}.`);
+            } else {
+                console.error(`BACKGROUND: Relay WS not OPEN, cannot send CHAT_RESPONSE (for duplicate) for requestId: ${message.requestId}.`);
             }
-            // Since we can't rely on FINAL_RESPONSE_TO_RELAY, we have to clean up here.
+
             processingRequest = false;
-            pendingRequestDetails.delete(lastRequestId);
-            // lastSuccessfullyProcessedMessageText = null; // Consider if this should be reset
-            console.log(`BACKGROUND: Forcefully reset processingRequest for ${lastRequestId} due to USER_STOP_REQUEST with no active tab.`);
-            processNextRequest(); // Attempt to process next
-        }
+            currentRequestTargetTabId = null;
+            const tabInfo = sender.tab ? debuggerAttachedTabs.get(sender.tab.id) : null;
+            if (tabInfo && tabInfo.lastKnownRequestId === message.requestId) {
+                tabInfo.lastKnownRequestId = null;
+            }
 
-        // Inform relay server about cancellation (can be done early)
-        if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-            relaySocket.send(JSON.stringify({
-                type: "CHAT_RESPONSE_ERROR", // Or a new type like "USER_CANCELLED_REQUEST"
-                requestId: lastRequestId, // Use lastRequestId as it's the one being processed
-                error: "Request cancelled by user."
-            }));
-            console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR (user cancelled) to server for currently processing requestId: ${lastRequestId}.`);
+            console.log(`BACKGROUND: Reset processingRequest after DUPLICATE_MESSAGE_HANDLED for requestId: ${message.requestId}.`);
+            processNextRequest();
+        } else {
+            console.warn(`BACKGROUND: Received DUPLICATE_MESSAGE_HANDLED for requestId ${message.requestId}, but not currently processing it or ID mismatch. Current lastRequestId: ${lastRequestId}, processing: ${processingRequest}. Still updated LSPMT.`);
+            if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                relaySocket.send(JSON.stringify({
+                    type: "CHAT_RESPONSE",
+                    requestId: message.requestId,
+                    response: `[ChatRelay Extension] An older/superseded request (ID: ${message.requestId}, Text: "${message.originalText ? message.originalText.substring(0, 100) : 'N/A'}") was handled as a duplicate.`,
+                    isFinal: true
+                }));
+            }
         }
-        
-        // IMPORTANT: Do NOT set processingRequest = false or clear lastRequestId details here.
-        // Let the FINAL_RESPONSE_TO_RELAY (triggered by provider.stopStreaming) handle the final state cleanup.
-        sendResponse({ success: true, message: `Stop initiated for currently processing request ${lastRequestId}. Waiting for finalization from content script.` });
-        responseSent = true;
-
-    // Case 2: The request to stop is in the pending queue (not actively processing).
-    } else {
-        const initialQueueLength = pendingRequests.length;
-        pendingRequests = pendingRequests.filter(req => req.requestId !== requestIdToStop);
-        if (pendingRequests.length < initialQueueLength) {
-            console.log(`BACKGROUND: Removed requestId ${requestIdToStop} from pendingRequests queue.`);
-            pendingRequestDetails.delete(requestIdToStop); // Clean up details for the queued item
+        sendResponse({ success: true, message: "Duplicate handling acknowledged by background." });
+        return true;
+    } else if (message.type === "USER_STOP_REQUEST") {
+        const requestIdToStop = message.requestId;
+        console.log(`BACKGROUND: Received USER_STOP_REQUEST for requestId: ${requestIdToStop}`);
+        let responseSent = false;
+
+        if (processingRequest && lastRequestId === requestIdToStop) {
+            console.log(`BACKGROUND: Initiating stop for currently processing request: ${lastRequestId}. Content script will send FINAL_RESPONSE_TO_RELAY.`);
+            if (activeTabId) {
+                chrome.tabs.sendMessage(activeTabId, {
+                    action: "STOP_STREAMING",
+                    requestId: lastRequestId
+                }, response => {
+                    if (chrome.runtime.lastError) {
+                        console.error(`BACKGROUND: Error sending STOP_STREAMING to tab ${activeTabId} for requestId ${lastRequestId}:`, chrome.runtime.lastError.message);
+                    } else {
+                        console.log(`BACKGROUND: Sent STOP_STREAMING to tab ${activeTabId} for requestId ${lastRequestId}. Content script ack:`, response);
+                    }
+                });
+            } else {
+                console.warn(`BACKGROUND: Cannot send STOP_STREAMING for currently processing requestId ${lastRequestId}, activeTabId is null. This request might not be properly finalized by the provider.`);
+                if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                    relaySocket.send(JSON.stringify({
+                        type: "CHAT_RESPONSE_ERROR",
+                        requestId: lastRequestId,
+                        error: "Request cancelled by user (no active tab to signal provider)."
+                    }));
+                }
+                processingRequest = false;
+                currentRequestTargetTabId = null;
+                pendingRequestDetails.delete(lastRequestId);
+                console.log(`BACKGROUND: Forcefully reset processingRequest for ${lastRequestId} due to USER_STOP_REQUEST with no active tab.`);
+                processNextRequest();
+            }
 
             if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
-                 relaySocket.send(JSON.stringify({
+                relaySocket.send(JSON.stringify({
                     type: "CHAT_RESPONSE_ERROR",
-                    requestId: requestIdToStop,
-                    error: `Request ${requestIdToStop} cancelled by user while in queue.`
+                    requestId: lastRequestId,
+                    error: "Request cancelled by user."
                 }));
-                console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR (user cancelled in queue) to server for requestId: ${requestIdToStop}.`);
+                console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR (user cancelled) to server for currently processing requestId: ${lastRequestId}.`);
             }
-            if (!responseSent) sendResponse({ success: true, message: `Request ${requestIdToStop} removed from queue.` });
+
+            sendResponse({ success: true, message: `Stop initiated for currently processing request ${lastRequestId}. Waiting for finalization from content script.` });
             responseSent = true;
+
+        } else {
+            const initialQueueLength = pendingRequests.length;
+            pendingRequests = pendingRequests.filter(req => req.requestId !== requestIdToStop);
+            if (pendingRequests.length < initialQueueLength) {
+                console.log(`BACKGROUND: Removed requestId ${requestIdToStop} from pendingRequests queue.`);
+                pendingRequestDetails.delete(requestIdToStop);
+
+                if (relaySocket && relaySocket.readyState === WebSocket.OPEN) {
+                    relaySocket.send(JSON.stringify({
+                        type: "CHAT_RESPONSE_ERROR",
+                        requestId: requestIdToStop,
+                        error: `Request ${requestIdToStop} cancelled by user while in queue.`
+                    }));
+                    console.log(`BACKGROUND: Sent CHAT_RESPONSE_ERROR (user cancelled in queue) to server for requestId: ${requestIdToStop}.`);
+                }
+                if (!responseSent) sendResponse({ success: true, message: `Request ${requestIdToStop} removed from queue.` });
+                responseSent = true;
+            }
         }
-    }
 
-    if (!responseSent) {
-        console.warn(`BACKGROUND: USER_STOP_REQUEST for ${requestIdToStop}, but it was not actively processing nor found in the pending queue. Current active: ${lastRequestId}, processing: ${processingRequest}`);
-        sendResponse({ success: false, error: "Request not found processing or in queue." });
+        if (!responseSent) {
+            console.warn(`BACKGROUND: USER_STOP_REQUEST for ${requestIdToStop}, but it was not actively processing nor found in the pending queue. Current active: ${lastRequestId}, processing: ${processingRequest}`);
+            sendResponse({ success: false, error: "Request not found processing or in queue." });
+        }
+        return true;
     }
-    return true;
-  }
-  // IMPORTANT: Add other top-level else if (message.action === "SAVE_SETTINGS") etc. here if they exist outside this snippet
 });
 
-// Listen for storage changes to update the server URL
 chrome.storage.onChanged.addListener((changes, namespace) => {
-  if (namespace === 'sync') {
-    let needsReconnect = false;
-    if (changes.serverHost || changes.serverPort || changes.serverProtocol) {
-        needsReconnect = true;
-    }
-    
-    if (needsReconnect) {
-      console.log("BACKGROUND: Server settings changed, reconnecting...");
-      if (relaySocket) {
-        relaySocket.close(); 
-      } else {
-        loadSettingsAndConnect(); 
-      }
+    if (namespace === 'sync') {
+        let needsReconnect = false;
+        if (changes.serverHost || changes.serverPort || changes.serverProtocol) {
+            needsReconnect = true;
+        }
+
+        if (needsReconnect) {
+            console.log("BACKGROUND: Server settings changed, reconnecting...");
+            if (relaySocket) {
+                relaySocket.close();
+            } else {
+                loadSettingsAndConnect();
+            }
+        }
     }
-  }
 });
 
-// Initial setup
 loadSettingsAndConnect();
 
-// Placeholder for providerUtils if it's not globally available from another script.
-// In a real extension, this would likely be imported or part of a shared module.
 const providerUtils = {
-    _providers: {}, // providerName -> { instance, domains }
-    registerProvider: function(name, domains, instance) {
+    _providers: {},
+    registerProvider: function (name, domains, instance) {
         this._providers[name] = { instance, domains };
-        // console.log(BG_LOG_PREFIX, `Provider registered in background (simulated): ${name}`);
     },
-    getProviderForUrl: function(url) {
+    getProviderForUrl: function (url) {
         for (const name in this._providers) {
             if (this._providers[name].domains.some(domain => url.includes(domain))) {
                 return this._providers[name].instance;
@@ -787,10 +793,7 @@ const providerUtils = {
         }
         return null;
     },
-    // Simulate AIStudioProvider registration for isUrlSupportedByProvider
-    // This would normally happen if provider-utils.js was also loaded in background context
-    // or if this info was passed/stored differently.
-    _initializeSimulatedProviders: function() {
+    _initializeSimulatedProviders: function () {
         this.registerProvider("AIStudioProvider", ["aistudio.google.com"], { name: "AIStudioProvider" });
         this.registerProvider("GeminiProvider", ["gemini.google.com"], { name: "GeminiProvider" });
         this.registerProvider("GeminiProvider", ["chatgpt.com"], { name: "ChatGPTProvider" });
@@ -798,12 +801,11 @@ const providerUtils = {
 
     }
 };
-providerUtils._initializeSimulatedProviders(); // Call to populate for the helper
+providerUtils._initializeSimulatedProviders();
 
 console.log("BACKGROUND: AI Chat Relay: Background Service Worker started.");
 
 
-// ===== DEBUGGER LOGIC =====
 async function attachDebuggerAndEnableFetch(tabId, providerName, patterns) {
     if (!tabId || !patterns || patterns.length === 0) {
         console.error(BG_LOG_PREFIX, `attachDebuggerAndEnableFetch: Invalid parameters for tab ${tabId}. Patterns:`, patterns);
@@ -831,17 +833,17 @@ async function attachDebuggerAndEnableFetch(tabId, providerName, patterns) {
                         patterns: patterns,
                         isFetchEnabled: false,
                         isAttached: true,
-                        lastKnownRequestId: null 
+                        lastKnownRequestId: null
                     });
                     resolve();
                 });
             });
         }
-        
+
         const currentTabDataForPatterns = debuggerAttachedTabs.get(tabId);
         if (currentTabDataForPatterns) {
-            currentTabDataForPatterns.patterns = patterns; 
-            currentTabDataForPatterns.providerName = providerName; 
+            currentTabDataForPatterns.patterns = patterns;
+            currentTabDataForPatterns.providerName = providerName;
         }
 
         console.log(BG_LOG_PREFIX, `Enabling Fetch domain for tab ${tabId} with patterns:`, patterns);
@@ -882,15 +884,14 @@ async function detachDebugger(tabId) {
                         console.log(BG_LOG_PREFIX, `Successfully detached debugger from tab ${tabId}`);
                     }
                     debuggerAttachedTabs.delete(tabId);
-                    resolve(); // Resolve even if detach had an error, as we've cleaned up map
+                    resolve();
                 });
             });
-        } catch (error) { // Catch errors from the Promise constructor itself or unhandled rejections
+        } catch (error) {
             console.error(BG_LOG_PREFIX, `Exception during detach for tab ${tabId}:`, error);
-            debuggerAttachedTabs.delete(tabId); // Ensure cleanup
+            debuggerAttachedTabs.delete(tabId);
         }
     } else {
-        // If not attached or no details, still ensure it's not in the map
         debuggerAttachedTabs.delete(tabId);
     }
 }
@@ -919,8 +920,6 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
     const tabId = debuggeeId.tabId;
     const tabInfo = debuggerAttachedTabs.get(tabId);
 
-    // DEVELOPER ACTION: This parsing function needs to be robustly implemented
-    // based on consistent observation of the AI Studio response structure.
     function parseAiStudioResponse(jsonString) {
         try {
             const parsed = JSON.parse(jsonString);
@@ -933,18 +932,16 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
                                 for (const innerMostArray of candidateBlock[0][0][0][0]) {
                                     if (Array.isArray(innerMostArray) && innerMostArray.length > 1 && typeof innerMostArray[1] === 'string') {
                                         const textSegment = innerMostArray[1];
-                                        // Basic heuristic to filter out "thought process" or similar meta-commentary.
-                                        // This will need refinement based on actual response variations.
                                         if (!textSegment.toLowerCase().includes("thinking process") &&
                                             !textSegment.toLowerCase().includes("thought process") &&
-                                            !textSegment.startsWith("1.") && // Avoid numbered list from thoughts
+                                            !textSegment.startsWith("1.") &&
                                             !textSegment.startsWith("2.") &&
                                             !textSegment.startsWith("3.") &&
                                             !textSegment.startsWith("4.") &&
                                             !textSegment.startsWith("5.") &&
                                             !textSegment.startsWith("6.") &&
                                             textSegment.trim() !== "**") {
-                                            combinedText += textSegment; // Concatenate, newlines are part of the text
+                                            combinedText += textSegment;
                                         }
                                     }
                                 }
@@ -953,14 +950,13 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
                     }
                 }
             }
-            // Cleanup common markdown/formatting that might not be desired for relay
             let cleanedMessage = combinedText.replace(/\*\*/g, "").replace(/\\n/g, "\n").replace(/\n\s*\n/g, '\n').trim();
-            
+
             if (cleanedMessage) {
                 console.log(BG_LOG_PREFIX, "Parsed AI Studio response to (first 100 chars):", cleanedMessage.substring(0, 100));
                 return cleanedMessage;
             } else {
-                console.warn(BG_LOG_PREFIX, "Parsing AI Studio response yielded empty text. Original (first 200 chars):", jsonString.substring(0,200));
+                console.warn(BG_LOG_PREFIX, "Parsing AI Studio response yielded empty text. Original (first 200 chars):", jsonString.substring(0, 200));
             }
         } catch (e) {
             console.error(BG_LOG_PREFIX, "Error parsing AI Studio response JSON:", e, "Original string (first 200 chars):", jsonString.substring(0, 200));
@@ -996,60 +992,51 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
                     }
                     console.log(BG_LOG_PREFIX, `Raw responseBodyData for debugger requestId ${params.requestId} (first 200 chars):`, JSON.stringify(responseBodyData).substring(0, 200) + "...");
 
-                    const rawBodyText = responseBodyData.base64Encoded ? atob(responseBodyData.body) : responseBodyData.body;
-                    
+                    const rawBodyText = responseBodyData.base64Encoded ? new TextDecoder('utf-8').decode(Uint8Array.from(atob(responseBodyData.body), c => c.charCodeAt(0))) : responseBodyData.body;
+
                     if (rawBodyText === undefined || rawBodyText === null) {
                         console.error(BG_LOG_PREFIX, `Extracted rawBodyText is undefined or null for debugger requestId ${params.requestId}.`);
                         return;
                     }
-                    
-                    // Prioritize tabInfo.lastKnownRequestId if available and matches the global lastRequestId
-                    // Otherwise, use the global lastRequestId if we are in a processing state.
+
                     let tempRequestId = tabInfo ? tabInfo.lastKnownRequestId : null;
 
-                    if (processingRequest && lastRequestId !== null) { // lastRequestId is the app's current global request ID
+                    if (processingRequest && lastRequestId !== null) {
                         if (tempRequestId !== null && tempRequestId === lastRequestId) {
                             currentOperationRequestId = tempRequestId;
                             console.log(BG_LOG_PREFIX, `Using tabInfo.lastKnownRequestId: ${currentOperationRequestId} for debugger event on tab ${tabId} (debugger requestId ${params.requestId})`);
                         } else {
-                            currentOperationRequestId = lastRequestId; // Fallback to global if tabInfo's doesn't match or is null
+                            currentOperationRequestId = lastRequestId;
                             console.warn(BG_LOG_PREFIX, `Using global lastRequestId: ${currentOperationRequestId} for debugger event on tab ${tabId} (debugger requestId ${params.requestId}). TabInfo had: ${tempRequestId}.`);
                         }
                     } else if (tempRequestId !== null) {
-                        // Not in a global processingRequest state, but tabInfo has an ID. This might be a stray event.
                         currentOperationRequestId = tempRequestId;
-                         console.warn(BG_LOG_PREFIX, `Not in global processingRequest, but using tabInfo.lastKnownRequestId: ${currentOperationRequestId} for debugger event on tab ${tabId} (debugger requestId ${params.requestId}). This might be unexpected.`);
+                        console.warn(BG_LOG_PREFIX, `Not in global processingRequest, but using tabInfo.lastKnownRequestId: ${currentOperationRequestId} for debugger event on tab ${tabId} (debugger requestId ${params.requestId}). This might be unexpected.`);
                     } else {
                         currentOperationRequestId = null;
                     }
 
-                    // Check specifically for null/undefined, as 0 is a valid ID but falsy in JS
                     if (currentOperationRequestId === null || currentOperationRequestId === undefined) {
                         console.warn(BG_LOG_PREFIX, `Could not determine currentOperationRequestId for debugger event on tab ${tabId} (debugger requestId ${params.requestId}). Global lastRequestId: ${lastRequestId}, processingRequest: ${processingRequest}, tabInfo.lastKnownRequestId: ${tabInfo ? tabInfo.lastKnownRequestId : 'N/A'}. Ignoring body.`);
                         return;
                     }
-                    
+
                     if (rawBodyText === "") {
                         console.warn(BG_LOG_PREFIX, `Received empty rawBodyText for app requestId ${currentOperationRequestId} (debugger requestId ${params.requestId}). Not processing further for this event, waiting for potential subsequent data.`);
                         return;
                     }
                     console.log(BG_LOG_PREFIX, `Raw bodyText for tab ${tabId}, debugger requestId ${params.requestId} (first 100 chars):`, rawBodyText.substring(0, 100));
-                    
-                    // User wants rawBodyText (decoded JSON string) to be sent directly.
-                    // The parseAiStudioResponse function will be bypassed for this debugger flow.
+
                     const dataToSend = rawBodyText;
 
-                    console.log(BG_LOG_PREFIX, `Data to send for app requestId ${currentOperationRequestId} (first 100 chars): '${dataToSend ? dataToSend.substring(0,100) : "[EMPTY_DATA]"}'`);
+                    console.log(BG_LOG_PREFIX, `Data to send for app requestId ${currentOperationRequestId} (first 100 chars): '${dataToSend ? dataToSend.substring(0, 100) : "[EMPTY_DATA]"}'`);
 
-                    // CRITICAL CHECK: Only proceed if this requestId is still considered active/pending by background.js
                     if (currentOperationRequestId !== null && currentOperationRequestId !== undefined && pendingRequestDetails.has(currentOperationRequestId)) {
-                        if (tabId) { // tabId should be valid if we reached here from debuggeeId
+                        if (tabId) {
                             const messageToSend = {
                                 type: "DEBUGGER_RESPONSE",
                                 requestId: currentOperationRequestId,
-                                data: dataToSend, // Send the raw decoded JSON string
-                                // isFinal: true // The provider's parseDebuggerResponse will determine true finality from content.
-                                               // Background sends true to indicate this debugger event (HTTP response) is complete.
+                                data: dataToSend,
                                 isFinal: true
                             };
                             console.log(BG_LOG_PREFIX, `Attempting to send DEBUGGER_RESPONSE to tab ${tabId} for app requestId ${currentOperationRequestId}. Message object:`, JSON.stringify(messageToSend));
@@ -1065,10 +1052,9 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
                                             error: `Failed to send/ack DEBUGGER_RESPONSE to content script for requestId ${currentOperationRequestId}: ${errorMessage}`
                                         }));
                                     }
-                                    // If sending to content script fails, and it's the active request, we must clean up.
                                     if (processingRequest && lastRequestId === currentOperationRequestId) {
                                         processingRequest = false;
-                                        pendingRequestDetails.delete(currentOperationRequestId); // Ensure it's removed
+                                        pendingRequestDetails.delete(currentOperationRequestId);
                                         const tabInfoForReset = debuggerAttachedTabs.get(tabId);
                                         if (tabInfoForReset && tabInfoForReset.lastKnownRequestId === currentOperationRequestId) {
                                             tabInfoForReset.lastKnownRequestId = null;
@@ -1086,7 +1072,6 @@ chrome.debugger.onEvent.addListener((debuggeeId, message, params) => {
                         console.warn(BG_LOG_PREFIX, `Skipping sending DEBUGGER_RESPONSE for app requestId ${currentOperationRequestId} (debugger requestId ${params.requestId}) because it's no longer in pendingRequestDetails or ID is null/undefined. Tab: ${tabId}.`);
                     }
                 } finally {
-                    // We still need to continue the intercepted request in the browser, regardless of whether we processed its body.
                     console.log(BG_LOG_PREFIX, `[FINALLY] Continuing debugger request ${params.requestId}.`);
                     chrome.debugger.sendCommand(debuggeeId, "Fetch.continueRequest", { requestId: params.requestId }, () => {
                         if (chrome.runtime.lastError) {
diff --git a/extension/content.js b/extension/content.js
index 0a30933..f0fdb9e 100644
--- a/extension/content.js
+++ b/extension/content.js
@@ -1,41 +1,19 @@
-/*
- * Chat Relay: Relay for AI Chat Interfaces
- * Copyright (C) 2025 Jamison Moore
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see https://www.gnu.org/licenses/.
- */
-// AI Chat Relay - Content Script
-
-// Prefix for console logs
+
 const CS_LOG_PREFIX = '[CS CONTENT]';
 console.log(CS_LOG_PREFIX, "Content Script Injected & Loaded");
 
-// Global state
-let provider = null; // This will be set by initializeContentRelay
+let provider = null;
 let setupComplete = false;
 let currentRequestId = null;
-let processingMessage = false; // Flag to track if we're currently processing a message
-let responseMonitoringTimers = []; // Keep track of all monitoring timers
-let captureAttempts = 0; // Track how many capture attempts we've made
-const MAX_CAPTURE_ATTEMPTS = 30; // Maximum number of capture attempts
-const CAPTURE_DELAY = 1000; // 1 second between capture attempts
+let processingMessage = false;
+let responseMonitoringTimers = [];
+let captureAttempts = 0;
+const MAX_CAPTURE_ATTEMPTS = 30;
+const CAPTURE_DELAY = 1000;
 
-// Helper function to find potential input fields and buttons
 function findPotentialSelectors() {
   console.log(CS_LOG_PREFIX, "Searching for potential input fields and buttons...");
-  
-  // Find all textareas
+
   const textareas = document.querySelectorAll('textarea');
   console.log(CS_LOG_PREFIX, "Found textareas:", textareas.length);
   textareas.forEach((textarea, index) => {
@@ -47,8 +25,7 @@ function findPotentialSelectors() {
       name: textarea.name
     });
   });
-  
-  // Find all input fields
+
   const inputs = document.querySelectorAll('input[type="text"]');
   console.log(CS_LOG_PREFIX, "Found text inputs:", inputs.length);
   inputs.forEach((input, index) => {
@@ -60,8 +37,7 @@ function findPotentialSelectors() {
       name: input.name
     });
   });
-  
-  // Find all buttons
+
   const buttons = document.querySelectorAll('button');
   console.log(CS_LOG_PREFIX, "Found buttons:", buttons.length);
   buttons.forEach((button, index) => {
@@ -75,109 +51,102 @@ function findPotentialSelectors() {
 }
 
 function initializeContentRelay() {
-    if (setupComplete) {
-        console.log(CS_LOG_PREFIX, "Initialization already attempted or complete.");
-        return;
-    }
-    console.log(CS_LOG_PREFIX, 'Initializing content relay...');
+  if (setupComplete) {
+    console.log(CS_LOG_PREFIX, "Initialization already attempted or complete.");
+    return;
+  }
+  console.log(CS_LOG_PREFIX, 'Initializing content relay...');
 
-    // Provider Detection
-    if (window.providerUtils) {
-        const detectedProvider = window.providerUtils.detectProvider(window.location.hostname); // New detection method
-        provider = detectedProvider; // Update the global provider instance
+  if (window.providerUtils) {
+    const detectedProvider = window.providerUtils.detectProvider(window.location.hostname);
+    provider = detectedProvider;
 
-        console.log(CS_LOG_PREFIX, 'Detected provider:', provider ? provider.name : 'None');
+    console.log(CS_LOG_PREFIX, 'Detected provider:', provider ? provider.name : 'None');
 
-        if (provider && typeof provider.getStreamingApiPatterns === 'function') {
-            const patternsFromProvider = provider.getStreamingApiPatterns();
-            console.log(CS_LOG_PREFIX, 'Retrieved patterns from provider:', patternsFromProvider);
+    if (provider && typeof provider.getStreamingApiPatterns === 'function') {
+      const patternsFromProvider = provider.getStreamingApiPatterns();
+      console.log(CS_LOG_PREFIX, 'Retrieved patterns from provider:', patternsFromProvider);
 
-            if (patternsFromProvider && patternsFromProvider.length > 0) {
-                chrome.runtime.sendMessage({
-                    type: "SET_DEBUGGER_TARGETS",
-                    providerName: provider.name,
-                    patterns: patternsFromProvider
-                }, response => {
-                    if (chrome.runtime.lastError) {
-                        console.error(CS_LOG_PREFIX, 'Error sending SET_DEBUGGER_TARGETS:', chrome.runtime.lastError.message);
-                    } else {
-                        console.log(CS_LOG_PREFIX, 'SET_DEBUGGER_TARGETS message sent, response:', response);
-                    }
-                });
-            } else {
-                console.log(CS_LOG_PREFIX, 'No patterns returned by provider or patterns array is empty.');
-            }
-        } else {
-            if (provider) {
-                console.log(CS_LOG_PREFIX, `Provider '${provider.name}' found, but getStreamingApiPatterns method is missing or not a function.`);
-            } else {
-                console.log(CS_LOG_PREFIX, 'No current provider instance found to get patterns from.');
-            }
-        }
+      if (patternsFromProvider && patternsFromProvider.length > 0) {
+        chrome.runtime.sendMessage({
+          type: "SET_DEBUGGER_TARGETS",
+          providerName: provider.name,
+          patterns: patternsFromProvider
+        }, response => {
+          if (chrome.runtime.lastError) {
+            console.error(CS_LOG_PREFIX, 'Error sending SET_DEBUGGER_TARGETS:', chrome.runtime.lastError.message);
+          } else {
+            console.log(CS_LOG_PREFIX, 'SET_DEBUGGER_TARGETS message sent, response:', response);
+          }
+        });
+      } else {
+        console.log(CS_LOG_PREFIX, 'No patterns returned by provider or patterns array is empty.');
+      }
     } else {
-        console.error(CS_LOG_PREFIX, 'providerUtils not found. Cannot detect provider or send patterns.');
+      if (provider) {
+        console.log(CS_LOG_PREFIX, `Provider '${provider.name}' found, but getStreamingApiPatterns method is missing or not a function.`);
+      } else {
+        console.log(CS_LOG_PREFIX, 'No current provider instance found to get patterns from.');
+      }
     }
+  } else {
+    console.error(CS_LOG_PREFIX, 'providerUtils not found. Cannot detect provider or send patterns.');
+  }
 
-    // Send CHAT_RELAY_READY (always, after attempting provider setup)
-    chrome.runtime.sendMessage({
-      type: "CHAT_RELAY_READY",
-      chatInterface: provider ? provider.name : "unknown" // Add provider name
-    }, response => {
-        if (chrome.runtime.lastError) {
-            console.error(CS_LOG_PREFIX, 'Error sending CHAT_RELAY_READY:', chrome.runtime.lastError.message);
-        } else {
-            console.log(CS_LOG_PREFIX, 'CHAT_RELAY_READY message sent, response:', response);
-        }
-    });
-    
-    // Setup message listeners (will be called later, once, via setupMessageListeners)
-
-    // If a provider is detected, proceed with provider-specific setup after a delay
-    if (provider) {
-        console.log(CS_LOG_PREFIX, `Proceeding with provider-specific setup for: ${provider.name}`);
-        setTimeout(() => {
-            // Double check setupComplete flag in case of async issues or rapid calls, though less likely here.
-            if (!setupComplete) { 
-                findPotentialSelectors(); 
-                setupAutomaticResponseCapture(); 
-                startElementPolling(); 
-                console.log(CS_LOG_PREFIX, "Provider-specific DOM setup (response capture, polling) initiated after delay.");
-            }
-        }, 2000); // Delay to allow page elements to fully render
+  chrome.runtime.sendMessage({
+    type: "CHAT_RELAY_READY",
+    chatInterface: provider ? provider.name : "unknown"
+  }, response => {
+    if (chrome.runtime.lastError) {
+      console.error(CS_LOG_PREFIX, 'Error sending CHAT_RELAY_READY:', chrome.runtime.lastError.message);
     } else {
-        console.warn(CS_LOG_PREFIX, "No provider detected. Some provider-specific features (response capture, element polling) will not be initialized.");
+      console.log(CS_LOG_PREFIX, 'CHAT_RELAY_READY message sent, response:', response);
     }
-    
-    setupComplete = true; 
-    console.log(CS_LOG_PREFIX, "Content relay initialization sequence finished.");
+  });
+
+
+  if (provider) {
+    console.log(CS_LOG_PREFIX, `Proceeding with provider-specific setup for: ${provider.name}`);
+    setTimeout(() => {
+      if (!setupComplete) {
+        findPotentialSelectors();
+        setupAutomaticResponseCapture();
+        startElementPolling();
+        console.log(CS_LOG_PREFIX, "Provider-specific DOM setup (response capture, polling) initiated after delay.");
+      }
+    }, 2000);
+  } else {
+    console.warn(CS_LOG_PREFIX, "No provider detected. Some provider-specific features (response capture, element polling) will not be initialized.");
+  }
+
+  setupComplete = true;
+  console.log(CS_LOG_PREFIX, "Content relay initialization sequence finished.");
 }
 
-// Poll for elements that might be loaded dynamically
 function startElementPolling() {
   if (!provider) {
     console.warn(CS_LOG_PREFIX, "Cannot start element polling: no provider detected.");
     return;
   }
   console.log(CS_LOG_PREFIX, "Starting element polling...");
-  
-  // Check every 2 seconds for the input field and send button
+
   const pollingInterval = setInterval(() => {
-    if (!provider) { // Provider might have been lost or was never there
-        clearInterval(pollingInterval);
-        console.warn(CS_LOG_PREFIX, "Stopping element polling: provider became unavailable.");
-        return;
+    if (!provider) {
+      clearInterval(pollingInterval);
+      console.warn(CS_LOG_PREFIX, "Stopping element polling: provider became unavailable.");
+      return;
     }
     const inputField = document.querySelector(provider.inputSelector);
     const sendButton = document.querySelector(provider.sendButtonSelector);
-    
+
     if (inputField) {
       console.log(CS_LOG_PREFIX, "Found input field:", inputField);
     }
-    
+
     if (sendButton) {
       console.log(CS_LOG_PREFIX, "Found send button:", sendButton);
     }
-    
+
     if (inputField && sendButton) {
       console.log(CS_LOG_PREFIX, "Found all required elements, stopping polling");
       clearInterval(pollingInterval);
@@ -185,18 +154,15 @@ function startElementPolling() {
   }, 2000);
 }
 
-// Function to send a message to the chat interface
 function sendChatMessage(text) {
   if (!provider) {
     console.error(CS_LOG_PREFIX, "Cannot send chat message: No provider configured.");
-    processingMessage = false; // Reset flag
+    processingMessage = false;
     return false;
   }
-  // Try to send the message with retries
-  return sendChatMessageWithRetry(text, 5); // Try up to 5 times
+  return sendChatMessageWithRetry(text, 5);
 }
 
-// Helper function to send a message with retries
 function sendChatMessageWithRetry(text, maxRetries, currentRetry = 0) {
   if (!provider) {
     console.error(CS_LOG_PREFIX, `Cannot send chat message with retry (attempt ${currentRetry + 1}/${maxRetries}): No provider.`);
@@ -212,13 +178,13 @@ function sendChatMessageWithRetry(text, maxRetries, currentRetry = 0) {
         setTimeout(() => {
           sendChatMessageWithRetry(text, maxRetries, currentRetry + 1);
         }, 1000);
-        return true; 
+        return true;
       }
       console.error(CS_LOG_PREFIX, "Could not find input field after all retries");
-      processingMessage = false; 
+      processingMessage = false;
       return false;
     }
-    
+
     const sendButton = document.querySelector(provider.sendButtonSelector);
     if (!sendButton) {
       console.log(CS_LOG_PREFIX, `Could not find send button (attempt ${currentRetry + 1}/${maxRetries})`);
@@ -227,31 +193,31 @@ function sendChatMessageWithRetry(text, maxRetries, currentRetry = 0) {
         setTimeout(() => {
           sendChatMessageWithRetry(text, maxRetries, currentRetry + 1);
         }, 1000);
-        return true; 
+        return true;
       }
       console.error(CS_LOG_PREFIX, "Could not find send button after all retries");
-      processingMessage = false; 
+      processingMessage = false;
       return false;
     }
-    
+
     const result = provider.sendChatMessage(text, inputField, sendButton);
-    
+
     if (result) {
-        console.log(CS_LOG_PREFIX, "Message sent successfully via provider.");
-        if (provider.shouldSkipResponseMonitoring && provider.shouldSkipResponseMonitoring()) {
-            console.log(CS_LOG_PREFIX, `Provider ${provider.name} has requested to skip response monitoring.`);
-            processingMessage = false; // Message sent, no monitoring, so reset.
-        } else {
-            console.log(CS_LOG_PREFIX, `Waiting ${CAPTURE_DELAY/1000} seconds before starting to monitor for responses...`);
-            const timer = setTimeout(() => {
-                console.log(CS_LOG_PREFIX, "Starting to monitor for responses now");
-                startMonitoringForResponse();
-            }, CAPTURE_DELAY);
-            responseMonitoringTimers.push(timer);
-        }
+      console.log(CS_LOG_PREFIX, "Message sent successfully via provider.");
+      if (provider.shouldSkipResponseMonitoring && provider.shouldSkipResponseMonitoring()) {
+        console.log(CS_LOG_PREFIX, `Provider ${provider.name} has requested to skip response monitoring.`);
+        processingMessage = false;
+      } else {
+        console.log(CS_LOG_PREFIX, `Waiting ${CAPTURE_DELAY / 1000} seconds before starting to monitor for responses...`);
+        const timer = setTimeout(() => {
+          console.log(CS_LOG_PREFIX, "Starting to monitor for responses now");
+          startMonitoringForResponse();
+        }, CAPTURE_DELAY);
+        responseMonitoringTimers.push(timer);
+      }
     } else {
-        console.error(CS_LOG_PREFIX, "Provider reported failure sending message.");
-        processingMessage = false; // Reset on failure
+      console.error(CS_LOG_PREFIX, "Provider reported failure sending message.");
+      processingMessage = false;
     }
     return result;
   } catch (error) {
@@ -261,49 +227,47 @@ function sendChatMessageWithRetry(text, maxRetries, currentRetry = 0) {
       setTimeout(() => {
         sendChatMessageWithRetry(text, maxRetries, currentRetry + 1);
       }, 1000);
-      return true; 
+      return true;
     }
-    processingMessage = false; 
+    processingMessage = false;
     return false;
   }
 }
 
-// Function to start monitoring for a response
 function startMonitoringForResponse() {
   if (!provider || !provider.responseSelector || !provider.getResponseText) {
     console.error(CS_LOG_PREFIX, "Cannot monitor for response: Provider or necessary provider methods/selectors are not configured.");
-    processingMessage = false; // Can't monitor, so reset.
+    processingMessage = false;
     return;
   }
 
   console.log(CS_LOG_PREFIX, "Starting response monitoring process...");
-  captureAttempts = 0; // Reset capture attempts for this new monitoring session
+  captureAttempts = 0;
 
   const attemptCapture = () => {
     if (!processingMessage && currentRequestId === null) {
       console.log(CS_LOG_PREFIX, "Response monitoring stopped because processingMessage is false and currentRequestId is null (likely request completed or cancelled).");
-      return; // Stop if no longer processing a message
+      return;
     }
-    
+
     if (captureAttempts >= MAX_CAPTURE_ATTEMPTS) {
       console.error(CS_LOG_PREFIX, "Maximum response capture attempts reached. Stopping monitoring.");
-      // Send a timeout/error message back to the background script
-      if (currentRequestId !== null) { // Ensure there's a request ID to report error for
-          chrome.runtime.sendMessage({
-              type: "FINAL_RESPONSE_TO_RELAY",
-              requestId: currentRequestId,
-              error: "Response capture timed out in content script.",
-              isFinal: true // Treat as final to unblock server
-          }, response => {
-              if (chrome.runtime.lastError) {
-                  console.error(CS_LOG_PREFIX, 'Error sending capture timeout error:', chrome.runtime.lastError.message);
-              } else {
-                  console.log(CS_LOG_PREFIX, 'Capture timeout error sent to background, response:', response);
-              }
-          });
+      if (currentRequestId !== null) {
+        chrome.runtime.sendMessage({
+          type: "FINAL_RESPONSE_TO_RELAY",
+          requestId: currentRequestId,
+          error: "Response capture timed out in content script.",
+          isFinal: true
+        }, response => {
+          if (chrome.runtime.lastError) {
+            console.error(CS_LOG_PREFIX, 'Error sending capture timeout error:', chrome.runtime.lastError.message);
+          } else {
+            console.log(CS_LOG_PREFIX, 'Capture timeout error sent to background, response:', response);
+          }
+        });
       }
       processingMessage = false;
-      currentRequestId = null; // Clear current request ID as it timed out
+      currentRequestId = null;
       return;
     }
 
@@ -313,45 +277,40 @@ function startMonitoringForResponse() {
     const responseElement = document.querySelector(provider.responseSelector);
     if (responseElement) {
       const responseText = provider.getResponseText(responseElement);
-      const isFinal = provider.isResponseComplete ? provider.isResponseComplete(responseElement) : false; // Default to false if not implemented
+      const isFinal = provider.isResponseComplete ? provider.isResponseComplete(responseElement) : false;
 
       console.log(CS_LOG_PREFIX, `Captured response text (length: ${responseText.length}), isFinal: ${isFinal}`);
-      
-      // Send to background
+
       chrome.runtime.sendMessage({
-        type: "FINAL_RESPONSE_TO_RELAY", // Or a new type like "PARTIAL_RESPONSE" if needed
+        type: "FINAL_RESPONSE_TO_RELAY",
         requestId: currentRequestId,
         text: responseText,
         isFinal: isFinal
       }, response => {
-          if (chrome.runtime.lastError) {
-              console.error(CS_LOG_PREFIX, 'Error sending response data to background:', chrome.runtime.lastError.message);
-          } else {
-              console.log(CS_LOG_PREFIX, 'Response data sent to background, response:', response);
-          }
+        if (chrome.runtime.lastError) {
+          console.error(CS_LOG_PREFIX, 'Error sending response data to background:', chrome.runtime.lastError.message);
+        } else {
+          console.log(CS_LOG_PREFIX, 'Response data sent to background, response:', response);
+        }
       });
 
       if (isFinal) {
         console.log(CS_LOG_PREFIX, "Final response detected. Stopping monitoring.");
-        processingMessage = false; // Reset flag as processing is complete
-        // currentRequestId will be cleared by handleProviderResponse or if a new message comes
-        return; 
+        processingMessage = false;
+        return;
       }
     } else {
       console.log(CS_LOG_PREFIX, "Response element not found yet.");
     }
 
-    // Continue polling
     const timer = setTimeout(attemptCapture, CAPTURE_DELAY);
     responseMonitoringTimers.push(timer);
   };
 
-  // Initial call to start the process
   attemptCapture();
 }
 
 
-// Function to set up automatic response capture using MutationObserver
 function setupAutomaticResponseCapture() {
   if (!provider || !provider.responseContainerSelector || typeof provider.handleMutation !== 'function') {
     console.warn(CS_LOG_PREFIX, "Cannot set up automatic response capture: Provider or necessary provider methods/selectors are not configured.");
@@ -364,47 +323,35 @@ function setupAutomaticResponseCapture() {
 
   if (!targetNode) {
     console.warn(CS_LOG_PREFIX, `Response container element ('${provider.responseContainerSelector}') not found. MutationObserver not started. Will rely on polling or debugger.`);
-    // Optionally, retry finding the targetNode after a delay, or fall back to polling exclusively.
-    // For now, we just warn and don't start the observer.
     return;
   }
 
   const config = { childList: true, subtree: true, characterData: true };
 
   const callback = (mutationsList, observer) => {
-    // If not processing a message, or no current request, don't do anything.
-    // This check is crucial to prevent processing mutations when not expected.
     if (!processingMessage || currentRequestId === null) {
-        // console.log(CS_LOG_PREFIX, "MutationObserver: Ignoring mutation, not actively processing a message or no currentRequestId.");
-        return;
+      return;
     }
-    
-    // Let the provider handle the mutation and decide if it's relevant
-    // The provider's handleMutation should call handleProviderResponse with the requestId
+
     try {
-        provider.handleMutation(mutationsList, observer, currentRequestId, handleProviderResponse);
+      provider.handleMutation(mutationsList, observer, currentRequestId, handleProviderResponse);
     } catch (e) {
-        console.error(CS_LOG_PREFIX, "Error in provider.handleMutation:", e);
+      console.error(CS_LOG_PREFIX, "Error in provider.handleMutation:", e);
     }
   };
 
   const observer = new MutationObserver(callback);
-  
+
   try {
-      observer.observe(targetNode, config);
-      console.log(CS_LOG_PREFIX, "MutationObserver started on:", targetNode);
+    observer.observe(targetNode, config);
+    console.log(CS_LOG_PREFIX, "MutationObserver started on:", targetNode);
   } catch (e) {
-      console.error(CS_LOG_PREFIX, "Failed to start MutationObserver:", e, "on target:", targetNode);
-      // Fallback or error handling if observer cannot be started
+    console.error(CS_LOG_PREFIX, "Failed to start MutationObserver:", e, "on target:", targetNode);
   }
 
-  // Store the observer if we need to disconnect it later
-  // e.g., window.chatRelayObserver = observer;
 }
 
 
-// Function to monitor for the completion of a response (e.g., when a "thinking" indicator disappears)
-// This is a more generic version, specific providers might have more tailored logic.
 function monitorResponseCompletion(element) {
   if (!provider || !provider.thinkingIndicatorSelector) {
     console.warn(CS_LOG_PREFIX, "Cannot monitor response completion: No thinkingIndicatorSelector in provider.");
@@ -413,35 +360,20 @@ function monitorResponseCompletion(element) {
 
   const thinkingIndicator = document.querySelector(provider.thinkingIndicatorSelector);
   if (!thinkingIndicator) {
-    // If the indicator is already gone, assume completion or it never appeared.
-    // Provider's getResponseText should ideally capture the full text.
     console.log(CS_LOG_PREFIX, "Thinking indicator not found, assuming response is complete or was never present.");
-    // Potentially call captureResponse one last time if needed by provider logic
-    // captureResponse(null, true); // Example, might need adjustment
     return;
   }
 
   console.log(CS_LOG_PREFIX, "Thinking indicator found. Monitoring for its removal...");
   const observer = new MutationObserver((mutationsList, obs) => {
-    // Check if the thinking indicator (or its parent, if it's removed directly) is no longer in the DOM
-    // or if a specific class/attribute indicating completion appears.
-    // This logic needs to be robust and provider-specific.
-    
-    // A simple check: if the element itself is removed or a known parent.
-    // More complex checks might involve looking for specific classes on the response element.
+
     if (!document.body.contains(thinkingIndicator)) {
       console.log(CS_LOG_PREFIX, "Thinking indicator removed. Assuming response completion.");
       obs.disconnect();
-      // Capture the final response
-      // This assumes captureResponse can get the full text now.
-      // The 'true' flag indicates this is considered the final capture.
-      captureResponse(null, true); 
+      captureResponse(null, true);
     }
-    // Add other provider-specific checks here if needed
   });
 
-  // Observe the parent of the thinking indicator for changes in its children (e.g., removal of the indicator)
-  // Or observe attributes of the indicator itself if it changes state instead of being removed.
   if (thinkingIndicator.parentNode) {
     observer.observe(thinkingIndicator.parentNode, { childList: true, subtree: true });
   } else {
@@ -449,141 +381,116 @@ function monitorResponseCompletion(element) {
   }
 }
 
-// Specific monitoring for Gemini, if needed (example)
 function monitorGeminiResponse(element) {
-    // Gemini specific logic for monitoring response element for completion
-    // This might involve looking for specific attributes or child elements
-    // that indicate the stream has finished.
-    console.log(CS_LOG_PREFIX, "Monitoring Gemini response element:", element);
-    // Example: Observe for a specific class or attribute change
-    const observer = new MutationObserver((mutationsList, obs) => {
-        let isComplete = false;
-        // Check mutations for signs of completion based on Gemini's DOM structure
-        // For instance, a "generating" class is removed, or a "complete" attribute is set.
-        // This is highly dependent on the actual Gemini interface.
-        // Example (conceptual):
-        // if (element.classList.contains('response-complete')) {
-        //    isComplete = true;
-        // }
-
-        if (isComplete) {
-            console.log(CS_LOG_PREFIX, "Gemini response detected as complete by mutation.");
-            obs.disconnect();
-            captureResponse(element, true); // Capture final response
-        }
-    });
-    observer.observe(element, { attributes: true, childList: true, subtree: true });
-    console.log(CS_LOG_PREFIX, "Gemini response observer started.");
+  console.log(CS_LOG_PREFIX, "Monitoring Gemini response element:", element);
+  const observer = new MutationObserver((mutationsList, obs) => {
+    let isComplete = false;
+
+    if (isComplete) {
+      console.log(CS_LOG_PREFIX, "Gemini response detected as complete by mutation.");
+      obs.disconnect();
+      captureResponse(element, true);
+    }
+  });
+  observer.observe(element, { attributes: true, childList: true, subtree: true });
+  console.log(CS_LOG_PREFIX, "Gemini response observer started.");
 }
 
 function monitorGeminiContentStability(element) {
-    let lastContent = "";
-    let stableCount = 0;
-    const STABLE_THRESHOLD = 3; // Number of intervals content must remain unchanged
-    const CHECK_INTERVAL = 300; // Milliseconds
-
-    console.log(CS_LOG_PREFIX, "Starting Gemini content stability monitoring for element:", element);
-
-    const intervalId = setInterval(() => {
-        if (!processingMessage || currentRequestId === null) {
-            console.log(CS_LOG_PREFIX, "Gemini stability: Stopping, no longer processing message.");
-            clearInterval(intervalId);
-            return;
-        }
+  let lastContent = "";
+  let stableCount = 0;
+  const STABLE_THRESHOLD = 3;
+  const CHECK_INTERVAL = 300;
 
-        const currentContent = provider.getResponseText(element);
-        if (currentContent === lastContent) {
-            stableCount++;
-            console.log(CS_LOG_PREFIX, `Gemini stability: Content stable, count: ${stableCount}`);
-        } else {
-            lastContent = currentContent;
-            stableCount = 0; // Reset if content changes
-            console.log(CS_LOG_PREFIX, `Gemini stability: Content changed. New length: ${currentContent.length}`);
-            // Send partial update if provider wants it
-            if (provider.sendPartialUpdates) {
-                 handleProviderResponse(currentRequestId, currentContent, false);
-            }
-        }
+  console.log(CS_LOG_PREFIX, "Starting Gemini content stability monitoring for element:", element);
 
-        if (stableCount >= STABLE_THRESHOLD) {
-            console.log(CS_LOG_PREFIX, "Gemini stability: Content stable for threshold. Assuming final.");
-            clearInterval(intervalId);
-            // Ensure the very latest content is captured and sent as final
-            const finalContent = provider.getResponseText(element);
-            handleProviderResponse(currentRequestId, finalContent, true);
-        }
-    }, CHECK_INTERVAL);
-    responseMonitoringTimers.push(intervalId); // Store to clear if needed
+  const intervalId = setInterval(() => {
+    if (!processingMessage || currentRequestId === null) {
+      console.log(CS_LOG_PREFIX, "Gemini stability: Stopping, no longer processing message.");
+      clearInterval(intervalId);
+      return;
+    }
+
+    const currentContent = provider.getResponseText(element);
+    if (currentContent === lastContent) {
+      stableCount++;
+      console.log(CS_LOG_PREFIX, `Gemini stability: Content stable, count: ${stableCount}`);
+    } else {
+      lastContent = currentContent;
+      stableCount = 0;
+      console.log(CS_LOG_PREFIX, `Gemini stability: Content changed. New length: ${currentContent.length}`);
+      if (provider.sendPartialUpdates) {
+        handleProviderResponse(currentRequestId, currentContent, false);
+      }
+    }
+
+    if (stableCount >= STABLE_THRESHOLD) {
+      console.log(CS_LOG_PREFIX, "Gemini stability: Content stable for threshold. Assuming final.");
+      clearInterval(intervalId);
+      const finalContent = provider.getResponseText(element);
+      handleProviderResponse(currentRequestId, finalContent, true);
+    }
+  }, CHECK_INTERVAL);
+  responseMonitoringTimers.push(intervalId);
 }
 
 
-// Function to capture the response text
-// potentialTurnElement is passed by some providers (like Gemini) if they identify the specific response "turn" element
 function captureResponse(potentialTurnElement = null, isFinal = false) {
   if (!provider || !provider.getResponseText) {
     console.error(CS_LOG_PREFIX, "Cannot capture response: No provider or getResponseText method.");
     if (currentRequestId !== null) {
-        handleProviderResponse(currentRequestId, "Error: Provider misconfiguration for response capture.", true);
+      handleProviderResponse(currentRequestId, "Error: Provider misconfiguration for response capture.", true);
     }
     return;
   }
 
-  // Use the potentialTurnElement if provided and valid, otherwise fall back to provider.responseSelector
   let responseElement = null;
   if (potentialTurnElement && typeof potentialTurnElement === 'object' && potentialTurnElement.nodeType === 1) {
-      responseElement = potentialTurnElement;
-      console.log(CS_LOG_PREFIX, "Using provided potentialTurnElement for capture:", responseElement);
+    responseElement = potentialTurnElement;
+    console.log(CS_LOG_PREFIX, "Using provided potentialTurnElement for capture:", responseElement);
   } else {
-      if (!provider.responseSelector) {
-          console.error(CS_LOG_PREFIX, "Cannot capture response: No responseSelector in provider and no valid potentialTurnElement given.");
-          if (currentRequestId !== null) {
-              handleProviderResponse(currentRequestId, "Error: Provider responseSelector missing.", true);
-          }
-          return;
+    if (!provider.responseSelector) {
+      console.error(CS_LOG_PREFIX, "Cannot capture response: No responseSelector in provider and no valid potentialTurnElement given.");
+      if (currentRequestId !== null) {
+        handleProviderResponse(currentRequestId, "Error: Provider responseSelector missing.", true);
       }
-      responseElement = document.querySelector(provider.responseSelector);
-      console.log(CS_LOG_PREFIX, "Using provider.responseSelector for capture:", provider.responseSelector);
+      return;
+    }
+    responseElement = document.querySelector(provider.responseSelector);
+    console.log(CS_LOG_PREFIX, "Using provider.responseSelector for capture:", provider.responseSelector);
   }
 
   if (!responseElement) {
     console.warn(CS_LOG_PREFIX, "Response element not found during capture.");
-    // If it's supposed to be final and element is not found, it might be an issue.
     if (isFinal && currentRequestId !== null) {
-        handleProviderResponse(currentRequestId, "Error: Response element not found for final capture.", true);
+      handleProviderResponse(currentRequestId, "Error: Response element not found for final capture.", true);
     }
     return;
   }
 
   const responseText = provider.getResponseText(responseElement);
-  // isFinal flag is now passed as an argument, but provider might have its own check
   const trulyFinal = isFinal || (provider.isResponseComplete ? provider.isResponseComplete(responseElement) : false);
 
   console.log(CS_LOG_PREFIX, `Captured response (length: ${responseText.length}), isFinal: ${trulyFinal}. Passed isFinal: ${isFinal}`);
-  
+
   if (currentRequestId === null) {
-      console.warn(CS_LOG_PREFIX, "captureResponse: currentRequestId is null. Cannot send response to background.");
-      return;
+    console.warn(CS_LOG_PREFIX, "captureResponse: currentRequestId is null. Cannot send response to background.");
+    return;
   }
 
-  // Call handleProviderResponse, which will then relay to background
-  // This centralizes the logic for sending FINAL_RESPONSE_TO_RELAY
   handleProviderResponse(currentRequestId, responseText, trulyFinal);
 }
 
-// Function to clear all active response monitoring timers
 function clearResponseMonitoringTimers() {
-    console.log(CS_LOG_PREFIX, `Clearing ${responseMonitoringTimers.length} response monitoring timers.`);
-    responseMonitoringTimers.forEach(timerId => clearTimeout(timerId)); // Works for both setTimeout and setInterval IDs
-    responseMonitoringTimers = []; // Reset the array
+  console.log(CS_LOG_PREFIX, `Clearing ${responseMonitoringTimers.length} response monitoring timers.`);
+  responseMonitoringTimers.forEach(timerId => clearTimeout(timerId));
+  responseMonitoringTimers = [];
 }
 
-// Define message listener function *before* calling it
-// Renamed setupAutomaticMessageSending to setupMessageListeners
-function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
-  // Listen for commands from the background script
+function setupMessageListeners() {
   chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
     if (message.action === "SEND_CHAT_MESSAGE") {
-      const messageContent = message.messageContent; // Use messageContent
+      const messageContent = message.messageContent;
       let messagePreview = "";
       if (typeof messageContent === 'string') {
         messagePreview = `String: "${messageContent.substring(0, 50)}..."`;
@@ -594,9 +501,9 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
       } else if (messageContent && typeof messageContent === 'object' && messageContent !== null) {
         messagePreview = `Object data (type: ${Object.prototype.toString.call(messageContent)})`;
       } else {
-        messagePreview = `Data type: ${typeof messageContent}, Value: ${String(messageContent).substring(0,50)}`;
+        messagePreview = `Data type: ${typeof messageContent}, Value: ${String(messageContent).substring(0, 50)}`;
       }
-      console.log(CS_LOG_PREFIX, "Received command to send message:", messagePreview, "Request ID:", message.requestId, "Last Processed Text:", message.lastProcessedText ? `"${message.lastProcessedText.substring(0,50)}..."` : "null");
+      console.log(CS_LOG_PREFIX, "Received command to send message:", messagePreview, "Request ID:", message.requestId, "Last Processed Text:", message.lastProcessedText ? `"${message.lastProcessedText.substring(0, 50)}..."` : "null");
 
       if (!provider) {
         console.error(CS_LOG_PREFIX, "Cannot send message: No provider detected.");
@@ -604,7 +511,6 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
         return true;
       }
 
-      // Superseding / duplicate requestId logic (unchanged)
       if (processingMessage && currentRequestId !== null && currentRequestId !== message.requestId) {
         console.warn(CS_LOG_PREFIX, `New message (requestId: ${message.requestId}) received while request ${currentRequestId} was processing. The new message will supersede the old one.`);
         clearResponseMonitoringTimers();
@@ -612,11 +518,10 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
         currentRequestId = null;
       } else if (processingMessage && currentRequestId === message.requestId) {
         console.warn(CS_LOG_PREFIX, `Received duplicate SEND_CHAT_MESSAGE for already processing requestId: ${message.requestId}. Ignoring duplicate command.`);
-        sendResponse({ success: false, error: "Duplicate command for already processing requestId."});
+        sendResponse({ success: false, error: "Duplicate command for already processing requestId." });
         return true;
       }
 
-      // Attempt to get the input field
       const inputField = document.querySelector(provider.inputSelector);
       let currentUIInputText = null;
 
@@ -624,24 +529,18 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
         currentUIInputText = inputField.value;
       } else {
         console.error(CS_LOG_PREFIX, "Input field not found via selector:", provider.inputSelector, "Cannot process SEND_CHAT_MESSAGE for requestId:", message.requestId);
-        // Reset state if this was meant to be the current request
-        if (currentRequestId === message.requestId) { // Check if we were about to set this as current
-            processingMessage = false; // Ensure it's reset if it was about to become active
-            // currentRequestId is not yet set to message.requestId here if it's a new command
+        if (currentRequestId === message.requestId) {
+          processingMessage = false;
         }
         sendResponse({ success: false, error: "Input field not found by content script." });
         return true;
       }
 
-      // Duplicate Message Scenario Check:
-      // 1. We have a record of the last processed text from the background script.
-      // 2. The server is trying to send that exact same text again (messageContent === message.lastProcessedText).
-      // 3. The UI input field also currently contains that exact same text (currentUIInputText === messageContent).
       let isDuplicateMessageScenario = false;
       if (typeof messageContent === 'string' && typeof message.lastProcessedText === 'string' && typeof currentUIInputText === 'string') {
         isDuplicateMessageScenario = message.lastProcessedText &&
-                                     messageContent === message.lastProcessedText &&
-                                     currentUIInputText === messageContent;
+          messageContent === message.lastProcessedText &&
+          currentUIInputText === messageContent;
       }
 
       if (isDuplicateMessageScenario) {
@@ -649,16 +548,14 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
         console.log(CS_LOG_PREFIX, `  Server wants to send: "${messageContent.substring(0, 50)}..."`);
         console.log(CS_LOG_PREFIX, `  Last processed text was: "${message.lastProcessedText.substring(0, 50)}..."`);
         console.log(CS_LOG_PREFIX, `  Current UI input is: "${currentUIInputText.substring(0, 50)}..."`);
-        
+
         console.log(CS_LOG_PREFIX, "Clearing input field and notifying background.");
-        inputField.value = ''; // Clear the input field
-        // Optionally, dispatch 'input' or 'change' events if the website needs them for reactivity
-        // inputField.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
+        inputField.value = '';
 
         chrome.runtime.sendMessage({
           type: "DUPLICATE_MESSAGE_HANDLED",
           requestId: message.requestId,
-          originalText: messageContent // The text that was duplicated
+          originalText: messageContent
         }, response => {
           if (chrome.runtime.lastError) {
             console.error(CS_LOG_PREFIX, 'Error sending DUPLICATE_MESSAGE_HANDLED:', chrome.runtime.lastError.message);
@@ -667,29 +564,22 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
           }
         });
 
-        // This request is now considered "handled" by the content script (as a duplicate).
-        // Reset content script's immediate processing state if this was about to become the active request.
-        // Note: currentRequestId might not yet be message.requestId if this is a brand new command.
-        // The background script will manage its own processingRequest flag based on DUPLICATE_MESSAGE_HANDLED.
-        // For content.js, we ensure we don't proceed to send this.
-        // If currentRequestId was already message.requestId (e.g. from a retry/glitch), reset it.
         if (currentRequestId === message.requestId) {
-            processingMessage = false;
-            currentRequestId = null;
+          processingMessage = false;
+          currentRequestId = null;
         }
-        
+
         sendResponse({ success: true, message: "Duplicate message scenario handled by clearing input." });
         return true;
       }
 
-      // If not a duplicate, proceed with normal sending logic:
       console.log(CS_LOG_PREFIX, `Not a duplicate scenario for requestId: ${message.requestId}. Proceeding to send.`);
       processingMessage = true;
       currentRequestId = message.requestId;
       console.log(CS_LOG_PREFIX, `Set currentRequestId to ${currentRequestId} for processing.`);
 
       if (provider && typeof provider.sendChatMessage === 'function') {
-        provider.sendChatMessage(messageContent, currentRequestId) // Pass messageContent and the requestId
+        provider.sendChatMessage(messageContent, currentRequestId)
           .then(success => {
             if (success) {
               console.log(CS_LOG_PREFIX, `Message sending initiated successfully via provider for requestId: ${currentRequestId}.`);
@@ -698,15 +588,13 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
                 provider.initiateResponseCapture(currentRequestId, handleProviderResponse);
               } else {
                 console.error(CS_LOG_PREFIX, `Provider ${provider.name} does not have initiateResponseCapture method. Response will not be processed for requestId ${currentRequestId}.`);
-                // If no response capture, this request might hang on the server side.
-                // Consider sending an error back to background.js or directly to server.
-                 chrome.runtime.sendMessage({
-                    type: "FINAL_RESPONSE_TO_RELAY",
-                    requestId: currentRequestId,
-                    error: `Provider ${provider.name} cannot capture responses. Message sent but no response will be relayed.`,
-                    isFinal: true
+                chrome.runtime.sendMessage({
+                  type: "FINAL_RESPONSE_TO_RELAY",
+                  requestId: currentRequestId,
+                  error: `Provider ${provider.name} cannot capture responses. Message sent but no response will be relayed.`,
+                  isFinal: true
                 });
-                processingMessage = false; // As we can't process response
+                processingMessage = false;
                 currentRequestId = null;
               }
               sendResponse({ success: true, message: "Message sending initiated by provider." });
@@ -725,41 +613,34 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
       } else {
         console.error(CS_LOG_PREFIX, "Provider or provider.sendChatMessage is not available for requestId:", message.requestId);
         processingMessage = false;
-        currentRequestId = null; // Ensure reset if it was about to be set
+        currentRequestId = null;
         sendResponse({ success: false, error: "Provider or sendChatMessage method missing." });
       }
-      return true; // Indicate async response
+      return true;
     } else if (message.type === "DEBUGGER_RESPONSE") {
-      console.log(CS_LOG_PREFIX, "Received DEBUGGER_RESPONSE message object:", JSON.stringify(message)); // Log full received message
+      console.log(CS_LOG_PREFIX, "Received DEBUGGER_RESPONSE message object:", JSON.stringify(message));
       console.log(CS_LOG_PREFIX, `Processing DEBUGGER_RESPONSE for app requestId: ${currentRequestId}. Debugger requestId: ${message.requestId}. Data length: ${message.data ? message.data.length : 'null'}`);
       if (!provider) {
-          console.error(CS_LOG_PREFIX, "Received DEBUGGER_RESPONSE but no provider is active.");
-          sendResponse({ success: false, error: "No provider active." });
-          return true;
+        console.error(CS_LOG_PREFIX, "Received DEBUGGER_RESPONSE but no provider is active.");
+        sendResponse({ success: false, error: "No provider active." });
+        return true;
       }
       if (typeof provider.handleDebuggerData !== 'function') {
-          console.error(CS_LOG_PREFIX, `Provider ${provider.name} does not implement handleDebuggerData.`);
-          sendResponse({ success: false, error: `Provider ${provider.name} does not support debugger method.` });
-          return true;
+        console.error(CS_LOG_PREFIX, `Provider ${provider.name} does not implement handleDebuggerData.`);
+        sendResponse({ success: false, error: `Provider ${provider.name} does not support debugger method.` });
+        return true;
       }
-      // IMPORTANT: The message.requestId IS the application's original requestId,
-      // associated by background.js. We should use this directly.
-      // The content.js currentRequestId might have been cleared if the provider.sendChatMessage failed,
-      // but the debugger stream might still be valid for message.requestId.
-
-      if (!message.requestId && message.requestId !== 0) { // Check if message.requestId is missing or invalid (0 is a valid requestId)
-          console.error(CS_LOG_PREFIX, `Received DEBUGGER_RESPONSE without a valid message.requestId. Ignoring. Message:`, message);
-          sendResponse({ success: false, error: "DEBUGGER_RESPONSE missing requestId." });
-          return true;
+
+      if (!message.requestId && message.requestId !== 0) {
+        console.error(CS_LOG_PREFIX, `Received DEBUGGER_RESPONSE without a valid message.requestId. Ignoring. Message:`, message);
+        sendResponse({ success: false, error: "DEBUGGER_RESPONSE missing requestId." });
+        return true;
       }
 
-      // Pass the raw data, the message's requestId, and isFinal flag to the provider
-      // The provider's handleDebuggerData is responsible for calling handleProviderResponse
-      console.log(CS_LOG_PREFIX, `Calling provider.handleDebuggerData for requestId: ${message.requestId} with isFinal: ${message.isFinal}`); // Log before call
+      console.log(CS_LOG_PREFIX, `Calling provider.handleDebuggerData for requestId: ${message.requestId} with isFinal: ${message.isFinal}`);
       provider.handleDebuggerData(message.requestId, message.data, message.isFinal, handleProviderResponse);
-      // Acknowledge receipt of the debugger data
       sendResponse({ success: true, message: "Debugger data passed to provider." });
-      return true; // Indicate async response (provider will eventually call handleProviderResponse)
+      return true;
 
     } else if (message.type === "PING_TAB") {
       console.log(CS_LOG_PREFIX, "Received PING_TAB from background script.");
@@ -769,13 +650,11 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
       console.log(CS_LOG_PREFIX, `Received STOP_STREAMING command for requestId: ${message.requestId}`);
       if (provider && typeof provider.stopStreaming === 'function') {
         provider.stopStreaming(message.requestId);
-        // The handleProviderResponse might have already cleared currentRequestId if it matched.
-        // We ensure processingMessage is false if this was the active request.
         if (currentRequestId === message.requestId) {
-            processingMessage = false;
-            currentRequestId = null; // Explicitly clear here as well
-            clearResponseMonitoringTimers(); // Ensure any DOM timers are also cleared
-            console.log(CS_LOG_PREFIX, `STOP_STREAMING: Cleared active currentRequestId ${message.requestId} and processingMessage flag.`);
+          processingMessage = false;
+          currentRequestId = null;
+          clearResponseMonitoringTimers();
+          console.log(CS_LOG_PREFIX, `STOP_STREAMING: Cleared active currentRequestId ${message.requestId} and processingMessage flag.`);
         }
         sendResponse({ success: true, message: `Streaming stopped for requestId: ${message.requestId}` });
       } else {
@@ -785,79 +664,69 @@ function setupMessageListeners() { // Renamed from setupAutomaticMessageSending
       return true;
     }
 
-    // Handle other potential message types if needed
-    // else if (message.type === '...') { ... }
 
-    // If the message type isn't handled, return false or undefined
     console.log(CS_LOG_PREFIX, "Unhandled message type received:", message.type || message.action);
-    // sendResponse({ success: false, error: "Unhandled message type" }); // Optional: send error back
-    // return false; // Or let it be undefined
   });
 }
 
-// Generic callback function passed to the provider.
-// The provider calls this when it has determined the final response or a chunk of it.
 function handleProviderResponse(requestId, responseText, isFinal) {
-  console.log(CS_LOG_PREFIX, `handleProviderResponse called for requestId: ${requestId}. Data length: ${responseText ? String(responseText).length : 'null'}. isFinal: ${isFinal}. Data (first 100 chars): '${(responseText || "").substring(0,100)}', Type: ${typeof responseText}`);
-  
-  // The requestId parameter here is the one that the provider determined this response is for.
-  // This should be the definitive requestId for this piece of data.
-  // We log if content.js's currentRequestId is different, but proceed with the passed 'requestId'.
-  if (currentRequestId !== requestId && currentRequestId !== null) { // also check currentRequestId is not null to avoid warning on initial load or after reset
-      console.warn(CS_LOG_PREFIX, `handleProviderResponse: content.js currentRequestId (${currentRequestId}) differs from provider's response requestId (${requestId}). Proceeding with provider's requestId for data relay.`);
+  console.log(CS_LOG_PREFIX, `handleProviderResponse called for requestId: ${requestId}. Data length: ${responseText ? String(responseText).length : 'null'}. isFinal: ${isFinal}. Data (first 100 chars): '${(responseText || "").substring(0, 100)}', Type: ${typeof responseText}`);
+
+  if (currentRequestId !== requestId && currentRequestId !== null) {
+    console.warn(CS_LOG_PREFIX, `handleProviderResponse: content.js currentRequestId (${currentRequestId}) differs from provider's response requestId (${requestId}). Proceeding with provider's requestId for data relay.`);
   }
-  // Continue to process with the 'requestId' passed to this function.
 
   if (chrome.runtime && chrome.runtime.sendMessage) {
-      const MAX_RESPONSE_TEXT_LENGTH = 500 * 1024; // 500KB limit for safety
-      let messageToSendToBackground;
-
-      if (responseText && typeof responseText === 'string' && responseText.length > MAX_RESPONSE_TEXT_LENGTH) {
-          console.warn(CS_LOG_PREFIX, `ResponseText for requestId ${requestId} is too large (${responseText.length} bytes). Sending error and truncated text.`);
-          messageToSendToBackground = {
-              type: "FINAL_RESPONSE_TO_RELAY",
-              requestId: requestId,
-              error: `Response too large to transmit (length: ${responseText.length}). Check content script logs for truncated version.`,
-              // text: responseText.substring(0, MAX_RESPONSE_TEXT_LENGTH) + "... (truncated by content.js)", // Optionally send truncated
-              text: `Error: Response too large (length: ${responseText.length}). See AI Studio for full response.`, // Simpler error text
-              isFinal: true // This is a final error state
-          };
-      } else {
-          messageToSendToBackground = {
-              type: "FINAL_RESPONSE_TO_RELAY",
-              requestId: requestId,
-              text: responseText, // Can be null if AIStudioProvider parsed it as such
-              isFinal: isFinal
-          };
-      }
+    const MAX_RESPONSE_TEXT_LENGTH = 500 * 1024;
+    let messageToSendToBackground;
 
-      console.log(CS_LOG_PREFIX, `[REQ-${requestId}] PRE-SEND to BG: Type: ${messageToSendToBackground.type}, isFinal: ${messageToSendToBackground.isFinal}, HasError: ${!!messageToSendToBackground.error}, TextLength: ${messageToSendToBackground.text ? String(messageToSendToBackground.text).length : (messageToSendToBackground.error ? String(messageToSendToBackground.error).length : 'N/A')}`);
-      try {
-          chrome.runtime.sendMessage(messageToSendToBackground, response => {
-              if (chrome.runtime.lastError) {
-                  console.error(CS_LOG_PREFIX, `[REQ-${requestId}] SEND FAILED to BG: ${chrome.runtime.lastError.message}. Message attempted:`, JSON.stringify(messageToSendToBackground).substring(0, 500));
-              } else {
-                  console.log(CS_LOG_PREFIX, `[REQ-${requestId}] SEND SUCCESS to BG. Ack from BG:`, response);
-              }
-          });
-      } catch (syncError) {
-          console.error(CS_LOG_PREFIX, `[REQ-${requestId}] SYNC ERROR sending to BG: ${syncError.message}. Message attempted:`, JSON.stringify(messageToSendToBackground).substring(0, 500), syncError);
-      }
+    // Encode special Unicode characters before transmission
+    const encodedText = responseText ? encodeURIComponent(responseText) : "";
+    
+    if (responseText && typeof responseText === 'string' && responseText.length > MAX_RESPONSE_TEXT_LENGTH) {
+      console.warn(CS_LOG_PREFIX, `ResponseText for requestId ${requestId} is too large (${responseText.length} bytes). Sending error and truncated text.`);
+      messageToSendToBackground = {
+        type: "FINAL_RESPONSE_TO_RELAY",
+        requestId: requestId,
+        error: `Response too large to transmit (length: ${responseText.length}). Check content script logs for truncated version.`,
+        text: `Error: Response too large (length: ${responseText.length}). See AI Studio for full response.`,
+        isFinal: true,
+        encoded: true
+      };
+    } else {
+      messageToSendToBackground = {
+        type: "FINAL_RESPONSE_TO_RELAY",
+        requestId: requestId,
+        text: encodedText,
+        isFinal: isFinal,
+        encoded: true
+      };
+    }
+
+    console.log(CS_LOG_PREFIX, `[REQ-${requestId}] PRE-SEND to BG: Type: ${messageToSendToBackground.type}, isFinal: ${messageToSendToBackground.isFinal}, HasError: ${!!messageToSendToBackground.error}, TextLength: ${messageToSendToBackground.text ? String(messageToSendToBackground.text).length : (messageToSendToBackground.error ? String(messageToSendToBackground.error).length : 'N/A')}`);
+    try {
+      chrome.runtime.sendMessage(messageToSendToBackground, response => {
+        if (chrome.runtime.lastError) {
+          console.error(CS_LOG_PREFIX, `[REQ-${requestId}] SEND FAILED to BG: ${chrome.runtime.lastError.message}. Message attempted:`, JSON.stringify(messageToSendToBackground).substring(0, 500));
+        } else {
+          console.log(CS_LOG_PREFIX, `[REQ-${requestId}] SEND SUCCESS to BG. Ack from BG:`, response);
+        }
+      });
+    } catch (syncError) {
+      console.error(CS_LOG_PREFIX, `[REQ-${requestId}] SYNC ERROR sending to BG: ${syncError.message}. Message attempted:`, JSON.stringify(messageToSendToBackground).substring(0, 500), syncError);
+    }
   } else {
-      console.error(CS_LOG_PREFIX, "Cannot send FINAL_RESPONSE_TO_RELAY, runtime is invalid.");
+    console.error(CS_LOG_PREFIX, "Cannot send FINAL_RESPONSE_TO_RELAY, runtime is invalid.");
   }
 
   if (isFinal) {
-    // Reset content script state AFTER sending the final response message,
-    // but only if the finalized requestId matches what content.js currently considers its active request.
     if (currentRequestId === requestId) {
       processingMessage = false;
       currentRequestId = null;
-      clearResponseMonitoringTimers(); // Clear any timers associated with this request
+      clearResponseMonitoringTimers();
       console.log(CS_LOG_PREFIX, `Processing finished for active requestId: ${requestId}. State reset in content.js.`);
     } else {
       console.log(CS_LOG_PREFIX, `Processing finished for requestId: ${requestId}. This was not the active content.js requestId (${currentRequestId}), so content.js state not altered by this finalization. However, timers for ${requestId} might need explicit cleanup if any were started by it.`);
-      // If specific timers were associated with 'requestId' (not currentRequestId), they should be cleared by the provider or a more granular timer management.
     }
   } else {
     console.log(CS_LOG_PREFIX, `Partial response processed for requestId: ${requestId}. Awaiting more data or final flag.`);
@@ -865,22 +734,20 @@ function handleProviderResponse(requestId, responseText, isFinal) {
 }
 
 
-// Call initialization functions
-// Ensure DOM is ready for provider detection and DOM manipulations
 if (document.readyState === "loading") {
-    document.addEventListener("DOMContentLoaded", attemptInitialization);
+  document.addEventListener("DOMContentLoaded", attemptInitialization);
 } else {
-    attemptInitialization(); // DOMContentLoaded has already fired
+  attemptInitialization();
 }
 
 function attemptInitialization() {
-    console.log(CS_LOG_PREFIX, "Attempting initialization...");
-    if (window.attemptedInitialization) {
-        console.log(CS_LOG_PREFIX, "Initialization already attempted. Skipping.");
-        return;
-    }
-    window.attemptedInitialization = true;
-    initializeContentRelay(); // Initialize provider detection, DOM setup, etc.
-    setupMessageListeners();  // Setup listeners for messages from background script
-    console.log(CS_LOG_PREFIX, "Initialization attempt complete. Message listeners set up.");
+  console.log(CS_LOG_PREFIX, "Attempting initialization...");
+  if (window.attemptedInitialization) {
+    console.log(CS_LOG_PREFIX, "Initialization already attempted. Skipping.");
+    return;
+  }
+  window.attemptedInitialization = true;
+  initializeContentRelay();
+  setupMessageListeners();
+  console.log(CS_LOG_PREFIX, "Initialization attempt complete. Message listeners set up.");
 }
diff --git a/extension/providers/aistudio.js b/extension/providers/aistudio.js
index 18f7448..d4baabc 100644
--- a/extension/providers/aistudio.js
+++ b/extension/providers/aistudio.js
@@ -1,84 +1,45 @@
-/*
- * Chat Relay: Relay for AI Chat Interfaces
- * Copyright (C) 2025 Jamison Moore
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see https://www.gnu.org/licenses/.
- */
-// AI Chat Relay - AI Studio Provider
 
 class AIStudioProvider {
   constructor() {
-    // --- START OF CONFIGURABLE PROPERTIES ---
-    // Method for response capture: "debugger" or "dom"
     this.captureMethod = "debugger";
-    // URL pattern for debugger to intercept if captureMethod is "debugger". Ensure this is specific.
-    this.debuggerUrlPattern = "*MakerSuiteService/GenerateContent*"; // VERIFY THIS PATTERN
-    // Whether to include "thinking" process in the message or just the final answer.
-    // If true, parseDebuggerResponse returns a JSON string: { "thinking": "...", "answer": "..." }
-    // If false, parseDebuggerResponse returns a string: "answer"
+    this.debuggerUrlPattern = "*MakerSuiteService/GenerateContent*";
     this.includeThinkingInMessage = false;
 
-    // Option to enable AI Studio function calling on load
-    // ENABLE_AISTUDIO_FUNCTION_CALLING: true or false
     this.ENABLE_AISTUDIO_FUNCTION_CALLING = true;
-    // --- END OF CONFIGURABLE PROPERTIES ---
 
-    this.name = "AIStudioProvider"; // Updated name
+    this.name = "AIStudioProvider";
     this.supportedDomains = ["aistudio.google.com"];
-    
-    // Selectors for the AI Studio interface
+
     this.inputSelector = 'textarea.textarea, textarea.gmat-body-medium, textarea[aria-label="Type something or pick one from prompt gallery"]';
-    
-    // The send button selector
+
     this.sendButtonSelector = 'button.run-button, button[aria-label="Run"], button.mat-mdc-tooltip-trigger.run-button';
-    
-    // Updated response selectors based on the actual elements
+
     this.responseSelector = '.response-container, .response-text, .model-response, .model-response-container, ms-chat-turn, ms-prompt-chunk, ms-text-chunk, .very-large-text-container, .cmark-node';
-    
-    // Thinking indicator selector
+
     this.thinkingIndicatorSelector = '.thinking-indicator, .loading-indicator, .typing-indicator, .response-loading, loading-indicator';
 
-    // Fallback selectors
-    this.responseSelectorForDOMFallback = '.response-container, .model-response-text'; // Placeholder, adjust as needed
-    this.thinkingIndicatorSelectorForDOM = '.thinking-indicator, .spinner'; // Placeholder, adjust as needed
-    
-    // Last sent message to avoid capturing it as a response
+    this.responseSelectorForDOMFallback = '.response-container, .model-response-text';
+    this.thinkingIndicatorSelectorForDOM = '.thinking-indicator, .spinner';
+
     this.lastSentMessage = '';
 
-    // Initialize pendingResponseCallbacks
     this.pendingResponseCallbacks = new Map();
 
-    // Call the method to ensure function calling is enabled on initial load
     this.ensureFunctionCallingEnabled();
 
-    // Listen for SPA navigation events to re-trigger the check
     if (window.navigation) {
       window.navigation.addEventListener('navigate', (event) => {
-        // We are interested in same-document navigations, common in SPAs
         if (!event.canIntercept || event.hashChange || event.downloadRequest !== null) {
           return;
         }
-        // Check if the navigation is within the same origin and path structure of AI Studio
         const currentUrl = new URL(window.location.href);
         const destinationUrl = new URL(event.destination.url);
 
         if (currentUrl.origin === destinationUrl.origin && destinationUrl.pathname.startsWith("/prompts/")) {
           console.log(`[${this.name}] Detected SPA navigation to: ${event.destination.url}. Re-checking function calling toggle.`);
-          // Use a timeout to allow the new view's DOM to settle
           setTimeout(() => {
             this.ensureFunctionCallingEnabled();
-          }, 1000); // Delay to allow DOM update
+          }, 1000);
         }
       });
     } else {
@@ -92,18 +53,17 @@ class AIStudioProvider {
       return;
     }
 
-    const checkInterval = 500; // ms
-    const maxDuration = 7000; // ms
+    const checkInterval = 500;
+    const maxDuration = 7000;
     let elapsedTime = 0;
     const providerName = this.name;
 
-    // Clear any existing timer for this specific functionality to avoid multiple polling loops
     if (this.functionCallingPollTimer) {
-        clearTimeout(this.functionCallingPollTimer);
-        this.functionCallingPollTimer = null;
-        console.log(`[${providerName}] Cleared previous function calling poll timer.`);
+      clearTimeout(this.functionCallingPollTimer);
+      this.functionCallingPollTimer = null;
+      console.log(`[${providerName}] Cleared previous function calling poll timer.`);
     }
-    
+
     console.log(`[${providerName}] Ensuring function calling is enabled (polling up to ${maxDuration / 1000}s).`);
 
     const tryEnableFunctionCalling = () => {
@@ -115,7 +75,6 @@ class AIStudioProvider {
         if (!isChecked) {
           console.log(`[${providerName}] Function calling toggle found and is NOT checked. Attempting to enable...`);
           functionCallingToggle.click();
-          // Verify after a short delay if the click was successful
           setTimeout(() => {
             const stillChecked = functionCallingToggle.getAttribute('aria-checked') === 'true';
             if (stillChecked) {
@@ -127,7 +86,7 @@ class AIStudioProvider {
         } else {
           console.log(`[${providerName}] Function calling toggle found and is already enabled.`);
         }
-        this.functionCallingPollTimer = null; // Clear timer once action is taken or element found
+        this.functionCallingPollTimer = null;
       } else {
         elapsedTime += checkInterval;
         if (elapsedTime < maxDuration) {
@@ -135,35 +94,29 @@ class AIStudioProvider {
           this.functionCallingPollTimer = setTimeout(tryEnableFunctionCalling, checkInterval);
         } else {
           console.warn(`[${providerName}] Function calling toggle button (selector: 'button[aria-label="Function calling"]') not found after ${maxDuration}ms. It might not be available on this page/view or selector is incorrect.`);
-          this.functionCallingPollTimer = null; // Clear timer
+          this.functionCallingPollTimer = null;
         }
       }
     };
 
-    // Start the first attempt after a brief initial delay
     this.functionCallingPollTimer = setTimeout(tryEnableFunctionCalling, 500);
   }
 
-  // Send a message to the chat interface
-  async sendChatMessage(messageContent) {
-    console.log(`[${this.name}] sendChatMessage called with content type:`, typeof messageContent, Array.isArray(messageContent) ? `Array length: ${messageContent.length}` : '');
+  async sendChatMessage(messageContent, requestId) {
+    console.log(`[${this.name} REQ-${requestId}] sendChatMessage called with content type:`, typeof messageContent, Array.isArray(messageContent) ? `Array length: ${messageContent.length}` : '');
     const inputField = document.querySelector(this.inputSelector);
-    const sendButton = document.querySelector(this.sendButtonSelector);
 
-    if (!inputField || !sendButton) {
-      console.error(`[${this.name}] Missing input field or send button. Input: ${this.inputSelector}, Button: ${this.sendButtonSelector}`);
+    if (!inputField) {
+      console.error(`[${this.name} REQ-${requestId}] Missing input field. Input selector: ${this.inputSelector}`);
       return false;
     }
 
-    console.log(`[${this.name}] Attempting to send message to AI Studio with:`, {
-      inputField: inputField.className,
-      sendButton: sendButton.getAttribute('aria-label') || sendButton.className
-    });
+    // Deferred sendButton logging moved to after it's defined
 
     try {
       let textToInput = "";
       let blobToPaste = null;
-      let blobMimeType = "image/png"; // Default MIME type
+      let blobMimeType = "image/png";
 
       if (typeof messageContent === 'string') {
         textToInput = messageContent;
@@ -181,7 +134,7 @@ class AIStudioProvider {
             textToInput += (textToInput ? "\n" : "") + part.text;
             console.log(`[${this.name}] Added text part:`, part.text.substring(0, 50) + "...");
           } else if (part.type === "image_url" && part.image_url && typeof part.image_url.url === 'string') {
-            if (!blobToPaste) { // Prioritize the first image found
+            if (!blobToPaste) {
               try {
                 const response = await fetch(part.image_url.url);
                 blobToPaste = await response.blob();
@@ -195,25 +148,20 @@ class AIStudioProvider {
             }
           }
         }
-        this.lastSentMessage = `Array content (Text: "${textToInput.substring(0,50)}...", Image: ${blobToPaste ? 'Yes' : 'No'})`;
+        this.lastSentMessage = `Array content (Text: "${textToInput.substring(0, 50)}...", Image: ${blobToPaste ? 'Yes' : 'No'})`;
       } else {
         console.error(`[${this.name}] Unhandled message content type: ${typeof messageContent}. Cannot send.`);
         this.lastSentMessage = `Unhandled data type: ${typeof messageContent}`;
         return false;
       }
 
-      // Set text input if any
       if (textToInput) {
         inputField.value = textToInput;
         inputField.dispatchEvent(new Event('input', { bubbles: true }));
         console.log(`[${this.name}] Set input field value with accumulated text.`);
       } else {
-        // If there's no text but an image, ensure the input field is clear if AI Studio requires it
-        // inputField.value = ""; 
-        // inputField.dispatchEvent(new Event('input', { bubbles: true }));
       }
 
-      // Paste blob if any
       if (blobToPaste) {
         const dataTransfer = new DataTransfer();
         const file = new File([blobToPaste], "pasted_image." + (blobMimeType.split('/')[1] || 'png'), { type: blobMimeType });
@@ -226,50 +174,65 @@ class AIStudioProvider {
         inputField.dispatchEvent(pasteEvent);
         console.log(`[${this.name}] Dispatched paste event with Blob data.`);
       }
-      
+
       inputField.focus();
       await new Promise(resolve => setTimeout(resolve, 100));
 
       let attempts = 0;
-      const maxAttempts = 60; // Try up to 60 times (5 minutes total)
-      const retryDelay = 5000; // 5 seconds delay between attempts
+      const maxAttempts = 60;
+      const retryDelay = 5000;
 
       while (attempts < maxAttempts) {
+        const sendButton = document.querySelector(this.sendButtonSelector);
+        if (attempts === 0) {
+          console.log(`[${this.name} REQ-${requestId}] Initial attempt to send. Input field class: ${inputField.className}. Send button details:`,
+            sendButton ? {
+              ariaLabel: sendButton.getAttribute('aria-label'),
+              className: sendButton.className,
+              selector: this.sendButtonSelector
+            } : "NOT FOUND");
+        }
+        if (!sendButton) {
+          console.warn(`[${this.name} REQ-${requestId}] Send button not found (attempt ${attempts + 1}). Will retry.`);
+          attempts++;
+          if (attempts >= maxAttempts) {
+            console.error(`[${this.name} REQ-${requestId}] Send button not found after ${maxAttempts} attempts.`);
+            return false;
+          }
+          await new Promise(resolve => setTimeout(resolve, retryDelay));
+          continue;
+        }
+
         const isDisabled = sendButton.disabled ||
-                           sendButton.getAttribute('aria-disabled') === 'true' ||
-                           sendButton.classList.contains('disabled');
+          sendButton.getAttribute('aria-disabled') === 'true' ||
+          sendButton.classList.contains('disabled');
 
         if (!isDisabled) {
-          // Removed check for input field content matching lastSentMessage
-          // as it can cause issues when there are multiple messages waiting to be sent
-          console.log(`[${this.name}] Send button is enabled. Clicking send button (attempt ${attempts + 1}).`);
+          console.log(`[${this.name} REQ-${requestId}] Send button is enabled. Clicking send button (attempt ${attempts + 1}).`);
           sendButton.click();
-          return true; // Successfully clicked
+          return true;
         }
 
         attempts++;
         if (attempts >= maxAttempts) {
           console.error(`[${this.name}] Send button remained disabled after ${maxAttempts} attempts. Failed to send message.`);
-          return false; // Failed to send
+          return false;
         }
 
         console.log(`[${this.name}] Send button is disabled (attempt ${attempts}). Trying to enable and will retry in ${retryDelay}ms.`);
-        // Attempt to trigger UI updates that might enable the button
-        inputField.dispatchEvent(new Event('input', { bubbles: true })); // Re-dispatch input
+        inputField.dispatchEvent(new Event('input', { bubbles: true }));
         inputField.dispatchEvent(new Event('change', { bubbles: true }));
         inputField.dispatchEvent(new Event('blur', { bubbles: true }));
-        // Focusing and bluring input sometimes helps enable send buttons
         inputField.focus();
-        await new Promise(resolve => setTimeout(resolve, 50)); // Short delay for focus
+        await new Promise(resolve => setTimeout(resolve, 50));
         inputField.blur();
-        
+
         await new Promise(resolve => setTimeout(resolve, retryDelay));
       }
-      // Should not be reached if logic is correct, but as a fallback:
       console.error(`[${this.name}] Exited send button check loop unexpectedly.`);
       return false;
     } catch (error) {
-      console.error(`[${this.name}] Error sending message to AI Studio:`, error);
+      console.error(`[${this.name} REQ-${requestId}] Error sending message to AI Studio:`, error);
       return false;
     }
   }
@@ -282,16 +245,16 @@ class AIStudioProvider {
     } else if (this.captureMethod === "dom") {
       console.log(`[${this.name}] Starting DOM monitoring for requestId: ${requestId}`);
       this.pendingResponseCallbacks.set(requestId, responseCallback);
-      this._stopDOMMonitoring(); 
-      this._startDOMMonitoring(requestId); 
+      this._stopDOMMonitoring();
+      this._startDOMMonitoring(requestId);
     } else {
       console.error(`[${this.name}] Unknown capture method: ${this.captureMethod}`);
-      responseCallback(requestId, `[Error: Unknown capture method '${this.captureMethod}' in provider]`, true); 
-      this.pendingResponseCallbacks.delete(requestId); 
+      responseCallback(requestId, `[Error: Unknown capture method '${this.captureMethod}' in provider]`, true);
+      this.pendingResponseCallbacks.delete(requestId);
     }
   }
 
-  handleDebuggerData(requestId, rawData, isFinalFromBackground) { // Renamed isFinal to isFinalFromBackground for clarity
+  handleDebuggerData(requestId, rawData, isFinalFromBackground) {
     console.log(`[${this.name}] handleDebuggerData called for requestId: ${requestId}. Raw data length: ${rawData ? rawData.length : 'null'}. isFinalFromBackground: ${isFinalFromBackground}`);
     const callback = this.pendingResponseCallbacks.get(requestId);
     if (!callback) {
@@ -303,48 +266,41 @@ class AIStudioProvider {
     let contentHasInternalFinalMarker = false;
 
     if (rawData && rawData.trim() !== "") {
-        const parseOutput = this.parseDebuggerResponse(rawData);
-        parsedText = parseOutput.text;
-        contentHasInternalFinalMarker = parseOutput.isFinalResponse; // Use the parser's determination
-        console.log(`[${this.name}] Debugger data parsed for requestId: ${requestId}. Parsed text (first 100 chars): '${(parsedText || "").substring(0,100)}', Type: ${typeof parsedText}, ChunkHasFinalMarkerFromParser: ${contentHasInternalFinalMarker}`);
+      const parseOutput = this.parseDebuggerResponse(rawData);
+      parsedText = parseOutput.text;
+      contentHasInternalFinalMarker = parseOutput.isFinalResponse;
+      console.log(`[${this.name}] Debugger data parsed for requestId: ${requestId}. Parsed text (first 100 chars): '${(parsedText || "").substring(0, 100)}', Type: ${typeof parsedText}, ChunkHasFinalMarkerFromParser: ${contentHasInternalFinalMarker}`);
     } else {
       console.log(`[${this.name}] Received empty rawData from debugger for requestId: ${requestId}. isFinalFromBackground: ${isFinalFromBackground}`);
-      // If rawData is empty, text remains empty.
-      // If background says it's final, but data is empty, it's still final.
     }
-    
-    // The response is considered final for the callback if:
-    // 1. The background script explicitly states this is the final debugger event for the request OR
-    // 2. The provider's own parsing of the current chunk's content indicates it's the end of the AI's message.
+
     const isFinalForCallback = isFinalFromBackground || contentHasInternalFinalMarker;
 
-    console.log(`[${this.name}] Calling callback for requestId ${requestId} with text (first 100): '${(parsedText || "").substring(0,100)}', isFinalForCallback: ${isFinalForCallback} (isFinalFromBackground: ${isFinalFromBackground}, contentHasInternalFinalMarker: ${contentHasInternalFinalMarker})`);
+    console.log(`[${this.name}] Calling callback for requestId ${requestId} with text (first 100): '${(parsedText || "").substring(0, 100)}', isFinalForCallback: ${isFinalForCallback} (isFinalFromBackground: ${isFinalFromBackground}, contentHasInternalFinalMarker: ${contentHasInternalFinalMarker})`);
     callback(requestId, parsedText, isFinalForCallback);
-    
-    // If the callback was told this is the final response, then clean up.
+
     if (isFinalForCallback) {
       console.log(`[${this.name}] Final event processed for requestId: ${requestId} (isFinalForCallback was true). Removing callback.`);
       this.pendingResponseCallbacks.delete(requestId);
     }
   }
 
-  // --- Internal DOM Capture Logic (largely unchanged but kept for completeness) ---
-  _captureResponseDOM(element = null) { 
+  _captureResponseDOM(element = null) {
     console.log(`[${this.name}] _captureResponseDOM (DOM method) called with element:`, element);
-    if (!element && this.captureMethod === "dom") { 
-        const elements = document.querySelectorAll(this.responseSelector);
-        if (elements.length > 0) {
-            element = elements[elements.length - 1];
-            console.log(`[${this.name}] _captureResponseDOM: Found element via querySelector during polling.`);
-        }
+    if (!element && this.captureMethod === "dom") {
+      const elements = document.querySelectorAll(this.responseSelector);
+      if (elements.length > 0) {
+        element = elements[elements.length - 1];
+        console.log(`[${this.name}] _captureResponseDOM: Found element via querySelector during polling.`);
+      }
     }
     if (!element) {
       console.log(`[${this.name}] _captureResponseDOM: No element provided or found.`);
-      return { found: false, text: '' }; 
+      return { found: false, text: '' };
     }
-    if (this._isResponseStillGeneratingDOM()) { 
+    if (this._isResponseStillGeneratingDOM()) {
       console.log(`[${this.name}] Response is still being generated (_isResponseStillGeneratingDOM check), waiting for completion`);
-      return { found: false, text: '' }; 
+      return { found: false, text: '' };
     }
     console.log(`[${this.name}] Attempting to capture DOM response from AI Studio...`);
     let responseText = "";
@@ -355,10 +311,9 @@ class AIStudioProvider {
         console.log("AISTUDIO: Element has text content");
         responseText = element.textContent.trim();
         if (responseText &&
-            // Removed check for responseText !== this.lastSentMessage
-            !responseText.includes("Loading") &&
-            !responseText.includes("Thinking") &&
-            !responseText.includes("Expand to view model thoughts")) {
+          !responseText.includes("Loading") &&
+          !responseText.includes("Thinking") &&
+          !responseText.includes("Expand to view model thoughts")) {
           console.log("AISTUDIO: Found response in element:", responseText.substring(0, 50) + (responseText.length > 50 ? "..." : ""));
           foundResponse = true;
         } else {
@@ -384,9 +339,8 @@ class AIStudioProvider {
             if (responseSpan) {
               console.log("AISTUDIO: Found response span in last ms-text-chunk");
               const text = responseSpan.textContent.trim();
-              if (text && 
-                  // Removed check for text !== this.lastSentMessage
-                  !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+              if (text &&
+                !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
                 responseText = text;
                 console.log("AISTUDIO: Found response in span:", responseText.substring(0, 50) + (responseText.length > 50 ? "..." : ""));
                 foundResponse = true;
@@ -394,9 +348,8 @@ class AIStudioProvider {
             } else {
               console.log("AISTUDIO: No response span found, getting text directly from ms-text-chunk");
               const text = lastTextChunk.textContent.trim();
-              if (text && 
-                  // Removed check for text !== this.lastSentMessage
-                  !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+              if (text &&
+                !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
                 responseText = text;
                 console.log("AISTUDIO: Found response in ms-text-chunk:", responseText.substring(0, 50) + (responseText.length > 50 ? "..." : ""));
                 foundResponse = true;
@@ -412,9 +365,8 @@ class AIStudioProvider {
                 const isInThoughtChunk = p.closest('ms-thought-chunk');
                 if (!isInThoughtChunk) {
                   const text = p.textContent.trim();
-                  if (text && 
-                      // Removed check for text !== this.lastSentMessage
-                      !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+                  if (text &&
+                    !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
                     combinedText += text + "\n";
                   }
                 }
@@ -438,9 +390,8 @@ class AIStudioProvider {
             let combinedTextFallback = "";
             paragraphsFallback.forEach((p) => {
               const text = p.textContent.trim();
-              if (text && 
-                  // Removed check for text !== this.lastSentMessage
-                  !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+              if (text &&
+                !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
                 combinedTextFallback += text + "\n";
               }
             });
@@ -451,9 +402,8 @@ class AIStudioProvider {
           }
           if (!foundResponse) {
             const textFallback = lastChatTurnFallback.textContent.trim();
-            if (textFallback && 
-                // Removed check for textFallback !== this.lastSentMessage
-                !textFallback.includes("Loading") && !textFallback.includes("Thinking") && !textFallback.includes("Expand to view model thoughts")) {
+            if (textFallback &&
+              !textFallback.includes("Loading") && !textFallback.includes("Thinking") && !textFallback.includes("Expand to view model thoughts")) {
               responseText = textFallback;
               foundResponse = true;
             }
@@ -467,9 +417,8 @@ class AIStudioProvider {
           for (let i = textContainers.length - 1; i >= 0; i--) {
             const textContainer = textContainers[i];
             const text = textContainer.textContent.trim();
-            if (text && 
-                // Removed check for text !== this.lastSentMessage
-                !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+            if (text &&
+              !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
               responseText = text;
               foundResponse = true;
               break;
@@ -487,9 +436,8 @@ class AIStudioProvider {
             const isUserChunk = paragraph.closest('.user-chunk');
             if (isUserChunk) continue;
             const text = paragraph.textContent.trim();
-            if (text && 
-                // Removed check for text !== this.lastSentMessage
-                !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
+            if (text &&
+              !text.includes("Loading") && !text.includes("Thinking") && !text.includes("Expand to view model thoughts")) {
               combinedTextDoc = text + "\n" + combinedTextDoc;
               if (text.startsWith("Hello") || text.includes("I'm doing") || text.includes("How can I assist")) break;
             }
@@ -513,126 +461,123 @@ class AIStudioProvider {
         .replace(/\n{3,}/g, '\n\n')
         .trim();
     }
-    return { 
+    return {
       found: foundResponse && !!responseText.trim(),
       text: responseText
     };
   }
 
-  // --- START OF CORRECTED DEBUGGER PARSING LOGIC ---
   parseDebuggerResponse(jsonString) {
-    console.log(`[${this.name}] Parsing debugger response (AI Studio specific)... Input jsonString (first 200):`, jsonString ? jsonString.substring(0,200) : "null", "Type:", typeof jsonString);
-    
+    console.log(`[${this.name}] Parsing debugger response (AI Studio specific)... Input jsonString (first 200):`, jsonString ? jsonString.substring(0, 200) : "null", "Type:", typeof jsonString);
+
     if (!jsonString || jsonString.trim() === "") {
-        console.warn(`[${this.name}] parseDebuggerResponse called with empty or null jsonString.`);
-        return { text: "", isFinalResponse: false }; 
+      console.warn(`[${this.name}] parseDebuggerResponse called with empty or null jsonString.`);
+      return { text: "", isFinalResponse: false };
     }
 
     let thinkingAndProcessText = "";
     let actualResponseText = "";
-    let overallMarkerFound = false; 
+    let overallMarkerFound = false;
 
     function findEndOfUnitMarker(data) {
-        if (Array.isArray(data)) {
-            if (data.length >= 2 && data[data.length - 1] === 1 && data[data.length - 2] === "model") {
-                return true;
-            }
-            for (const item of data) {
-                if (findEndOfUnitMarker(item)) { 
-                    return true;
-                }
-            }
+      if (Array.isArray(data)) {
+        if (data.length >= 2 && data[data.length - 1] === 1 && data[data.length - 2] === "model") {
+          return true;
         }
-        return false;
+        for (const item of data) {
+          if (findEndOfUnitMarker(item)) {
+            return true;
+          }
+        }
+      }
+      return false;
     }
 
     function extractTextSegments(data, segments = []) {
-        if (Array.isArray(data)) {
-            if (data.length > 1 && data[0] === null && typeof data[1] === 'string') {
-                segments.push(data[1]);
-            } else {
-                for (const item of data) {
-                    extractTextSegments(item, segments); 
-                }
-            }
+      if (Array.isArray(data)) {
+        if (data.length > 1 && data[0] === null && typeof data[1] === 'string') {
+          segments.push(data[1]);
+        } else {
+          for (const item of data) {
+            extractTextSegments(item, segments);
+          }
         }
-        return segments;
+      }
+      return segments;
     }
 
     try {
-        const parsedJson = JSON.parse(jsonString);
-        if (Array.isArray(parsedJson)) {
-            for (let i = 0; i < parsedJson.length; i++) {
-                const chunk = parsedJson[i];
-                const textSegmentsInChunk = extractTextSegments(chunk);
-                if (textSegmentsInChunk.length > 0) {
-                    actualResponseText += textSegmentsInChunk.join("");
-                }
-                if (findEndOfUnitMarker(chunk)) {
-                    overallMarkerFound = true;
-                }
-                if (this.includeThinkingInMessage) {
-                    if (Array.isArray(chunk) && chunk[0] && Array.isArray(chunk[0][0]) && chunk[0][0][2]) {
-                        const potentialThinkingBlock = chunk[0][0][2];
-                        const thinkingSegments = extractTextSegments(potentialThinkingBlock);
-                        const thinkingBlockText = thinkingSegments.join("").trim();
-                        if (thinkingBlockText && !actualResponseText.includes(thinkingBlockText)) {
-                            thinkingAndProcessText += thinkingBlockText + "\n";
-                        }
-                    }
-                }
+      const parsedJson = JSON.parse(jsonString);
+      if (Array.isArray(parsedJson)) {
+        for (let i = 0; i < parsedJson.length; i++) {
+          const chunk = parsedJson[i];
+          const textSegmentsInChunk = extractTextSegments(chunk);
+          if (textSegmentsInChunk.length > 0) {
+            actualResponseText += textSegmentsInChunk.join("");
+          }
+          if (findEndOfUnitMarker(chunk)) {
+            overallMarkerFound = true;
+          }
+          if (this.includeThinkingInMessage) {
+            if (Array.isArray(chunk) && chunk[0] && Array.isArray(chunk[0][0]) && chunk[0][0][2]) {
+              const potentialThinkingBlock = chunk[0][0][2];
+              const thinkingSegments = extractTextSegments(potentialThinkingBlock);
+              const thinkingBlockText = thinkingSegments.join("").trim();
+              if (thinkingBlockText && !actualResponseText.includes(thinkingBlockText)) {
+                thinkingAndProcessText += thinkingBlockText + "\n";
+              }
             }
+          }
+        }
+      } else {
+        if (typeof parsedJson === 'string') {
+          actualResponseText = parsedJson;
+          overallMarkerFound = true;
         } else {
-            if (typeof parsedJson === 'string') {
-                actualResponseText = parsedJson;
-                overallMarkerFound = true; 
-            } else {
-                console.warn(`[${this.name}] Parsed JSON is not an array as expected. Type: ${typeof parsedJson}. Content (first 100): ${JSON.stringify(parsedJson).substring(0,100)}`);
-                const genericText = extractTextSegments(parsedJson).join("");
-                if (genericText) {
-                    actualResponseText = genericText;
-                    overallMarkerFound = true; 
-                } else {
-                     actualResponseText = "[Error: Unexpected JSON structure from AI Studio]";
-                     overallMarkerFound = true; 
-                }
-            }
+          console.warn(`[${this.name}] Parsed JSON is not an array as expected. Type: ${typeof parsedJson}. Content (first 100): ${JSON.stringify(parsedJson).substring(0, 100)}`);
+          const genericText = extractTextSegments(parsedJson).join("");
+          if (genericText) {
+            actualResponseText = genericText;
+            overallMarkerFound = true;
+          } else {
+            actualResponseText = "[Error: Unexpected JSON structure from AI Studio]";
+            overallMarkerFound = true;
+          }
         }
-        
-        actualResponseText = actualResponseText.replace(/\\n/g, "\n").replace(/\n\s*\n/g, '\n').trim();
-        thinkingAndProcessText = thinkingAndProcessText.replace(/\\n/g, "\n").replace(/\n\s*\n/g, '\n').trim();
+      }
+
+      actualResponseText = actualResponseText.replace(/\\n/g, "\n").replace(/\n\s*\n/g, '\n').trim();
+      thinkingAndProcessText = thinkingAndProcessText.replace(/\\n/g, "\n").replace(/\n\s*\n/g, '\n').trim();
 
     } catch (e) {
-        console.error(`[${this.name}] Error parsing AI Studio debugger response JSON:`, e, "Original string (first 200 chars):", jsonString.substring(0, 200));
-        const formattedFallback = this.formatOutput("", jsonString); 
-        return { text: formattedFallback, isFinalResponse: true }; 
+      console.error(`[${this.name}] Error parsing AI Studio debugger response JSON:`, e, "Original string (first 200 chars):", jsonString.substring(0, 200));
+      const formattedFallback = this.formatOutput("", jsonString);
+      return { text: formattedFallback, isFinalResponse: true };
     }
-    
+
     const formattedOutput = this.formatOutput(thinkingAndProcessText, actualResponseText);
     if (formattedOutput.trim() === "" && overallMarkerFound) {
-        return { text: "", isFinalResponse: true };
+      return { text: "", isFinalResponse: true };
     }
     return { text: formattedOutput, isFinalResponse: overallMarkerFound };
   }
 
   formatOutput(thinkingText, answerText) {
     if (this.includeThinkingInMessage && thinkingText && thinkingText.trim() !== "") {
-        try {
-            const result = {
-                thinking: thinkingText.trim(),
-                answer: (answerText || "").trim() 
-            };
-            return JSON.stringify(result);
-        } catch (e) {
-            console.error(`[${this.name}] Error stringifying thinking/answer object:`, e);
-            return (answerText || "").trim();
-        }
+      try {
+        const result = {
+          thinking: thinkingText.trim(),
+          answer: (answerText || "").trim()
+        };
+        return JSON.stringify(result);
+      } catch (e) {
+        console.error(`[${this.name}] Error stringifying thinking/answer object:`, e);
+        return (answerText || "").trim();
+      }
     }
-    return (answerText || "").trim(); 
+    return (answerText || "").trim();
   }
-  // --- END OF CORRECTED DEBUGGER PARSING LOGIC ---
-  
-  // --- Other methods (DOM fallback, etc. - largely unchanged but included for completeness) ---
+
   _findResponseElementDOM(container) {
     console.log(`[${this.name}] _findResponseElementDOM called on container:`, container);
     if (!container) return null;
@@ -641,7 +586,6 @@ class AIStudioProvider {
     if (elements.length > 0) {
       const lastElement = elements[elements.length - 1];
       console.log(`[${this.name}] Found last response element via DOM:`, lastElement);
-      // Add checks to ensure it's not the user's input or an old response
       if (lastElement.textContent && lastElement.textContent.trim() !== this.lastSentMessage) {
         return lastElement;
       }
@@ -651,21 +595,14 @@ class AIStudioProvider {
   }
 
   shouldSkipResponseMonitoring() {
-    // Example: if a provider indicates via a specific property or method
-    // For AIStudio, if using debugger, we don't need DOM monitoring.
-    // This method is more for providers that might sometimes use DOM, sometimes not.
-    // console.log(`[${this.name}] shouldSkipResponseMonitoring called. Capture method: ${this.captureMethod}`);
     return this.captureMethod === "debugger";
   }
 
   _isResponseStillGeneratingDOM() {
-    // This is for the DOM fallback method
     const thinkingIndicator = document.querySelector(this.thinkingIndicatorSelectorForDOM);
     if (thinkingIndicator) {
-      // console.log(`[${this.name}] DOM Fallback: Thinking indicator found.`);
       return true;
     }
-    // console.log(`[${this.name}] DOM Fallback: No thinking indicator found.`);
     return false;
   }
 
@@ -681,7 +618,7 @@ class AIStudioProvider {
 
   _startDOMMonitoring(requestId) {
     console.log(`[${this.name}] DOM Fallback: _startDOMMonitoring for requestId: ${requestId}`);
-    this._stopDOMMonitoring(); // Stop any existing observer
+    this._stopDOMMonitoring();
 
     const callback = this.pendingResponseCallbacks.get(requestId);
     if (!callback) {
@@ -690,24 +627,24 @@ class AIStudioProvider {
     }
 
     let attempts = 0;
-    const maxAttempts = 15; // Try for ~15 seconds
+    const maxAttempts = 15;
     const interval = 1000;
 
     this.domMonitorTimer = setInterval(() => {
       console.log(`[${this.name}] DOM Fallback: Polling attempt ${attempts + 1}/${maxAttempts} for requestId: ${requestId}`);
-      const responseData = this._captureResponseDOM(); // Will use this.responseSelectorForDOMFallback
+      const responseData = this._captureResponseDOM();
 
       if (responseData.found && responseData.text.trim() !== "") {
-        console.log(`[${this.name}] DOM Fallback: Response captured for requestId ${requestId}. Text (first 100): ${responseData.text.substring(0,100)}`);
+        console.log(`[${this.name}] DOM Fallback: Response captured for requestId ${requestId}. Text (first 100): ${responseData.text.substring(0, 100)}`);
         this._stopDOMMonitoring();
-        callback(requestId, responseData.text, true); // Assume final for DOM capture
+        callback(requestId, responseData.text, true);
         this.pendingResponseCallbacks.delete(requestId);
       } else {
         attempts++;
         if (attempts >= maxAttempts) {
           console.warn(`[${this.name}] DOM Fallback: Max attempts reached for requestId ${requestId}. No response captured.`);
           this._stopDOMMonitoring();
-          callback(requestId, "[Error: Timed out waiting for DOM response]", true); // Error, final
+          callback(requestId, "[Error: Timed out waiting for DOM response]", true);
           this.pendingResponseCallbacks.delete(requestId);
         }
       }
@@ -724,7 +661,6 @@ class AIStudioProvider {
   }
 }
 
-// Ensure the provider is available on the window for the content script
 if (window.providerUtils) {
   const providerInstance = new AIStudioProvider();
   window.providerUtils.registerProvider(
diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json
index 75cab07..07dd57b 100644
--- a/mcp-server/package-lock.json
+++ b/mcp-server/package-lock.json
@@ -8,6 +8,7 @@
       "name": "chat-relay-mcp",
       "version": "0.0.1",
       "dependencies": {
+        "chat-relay-mcp": "file:",
         "mcp-framework": "^0.2.2",
         "node-fetch": "^3.3.2",
         "ws": "^8.18.2",
@@ -175,6 +176,10 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/chat-relay-mcp": {
+      "resolved": "",
+      "link": true
+    },
     "node_modules/commander": {
       "version": "12.1.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
diff --git a/mcp-server/package.json b/mcp-server/package.json
index 8b1219d..8a9951b 100644
--- a/mcp-server/package.json
+++ b/mcp-server/package.json
@@ -15,6 +15,7 @@
     "start": "node dist/index.js"
   },
   "dependencies": {
+    "chat-relay-mcp": "file:",
     "mcp-framework": "^0.2.2",
     "node-fetch": "^3.3.2",
     "ws": "^8.18.2",