1
0

2 Commits 0c4724c835 ... f505efad50

Autor SHA1 Nachricht Datum
  “陈博论” f505efad50 投放诊断智能体匹配 vor 6 Monaten
  “陈博论” 6a8a2fbb4f 智能体切换文案说明 vor 7 Monaten
2 geänderte Dateien mit 180 neuen und 115 gelöschten Zeilen
  1. 9 11
      config.py
  2. 171 104
      templates/index.html

+ 9 - 11
config.py

@@ -96,9 +96,6 @@ class AppConfig:
         """
         根据前端传入的智能体标识,从环境变量读取对应的 APP_ID,并返回使用的环境变量键名。
         优先匹配:
-        - 快手: APP_ID
-        - 头条: TOUTIAO_APP_ID
-        - 视频号: SHIPINGHAO_APP_ID
         其次再尝试 APP_ID_{ALIAS} 以及其它别名;最后回退 APP_ID(通用)与 APP_ID_KUAISHOU。
         返回: (app_id, source_env_key)
         若找不到返回 ("", "")
@@ -109,18 +106,19 @@ class AppConfig:
         primary_map = {
             'kuaishou': ["APP_ID"],
             'toutiao': ["TOUTIAO_APP_ID"],
-            'videoaccount': ["SHIPINHAO_APP_ID"],
-            'planning': ["PLANNING_APP_ID"],
-            'diagnosis': ["DIAGNOSIS_APP_ID"],
+            'pathology': ["PATHOLOGY_APP_ID"], #病理分析
+            'planning': ["PLANNING_APP_ID"], #策划大师
+            'diagnosis': ["DIAGNOSIS_APP_ID"], #投放诊断
         }
 
         # 2) 兼容性别名(作为次优先)
         alias_map = {
-            'kuaishou': ["APP_ID_KUAISHOU", "APP_ID_KS", "APP_ID_快手"],
-            'toutiao': ["APP_ID_TOUTIAO", "APP_ID_TT", "APP_ID_头条"],
-            'videoaccount': ["APP_ID_VIDEOACCOUNT", "APP_ID_WECHAT_VIDEO", "APP_ID_SHIPINHAO", "APP_ID_SHIPINGHAO", "APP_ID_视频号", "APP_ID_WXSPH"],
-            'planning': ["APP_ID_PLANNING", "APP_ID_PL", "APP_ID_规划"],
-            'diagnosis': ["DIAGNOSIS_APP_ID",],
+            'kuaishou': ["APP_ID_KUAISHOU", "APP_ID_KS",],
+            'toutiao': ["APP_ID_TOUTIAO", "APP_ID_TT", ],
+
+            'planning': ["APP_ID_PLANNING", "APP_ID_PL",], #病理分析
+            'pathology': ["APP_ID_PATHOLOGY",], #策划大师
+            'diagnosis': ["DIAGNOSIS_APP_ID",], #投放诊断
         }
 
         for key in primary_map.get(normalized, []):

+ 171 - 104
templates/index.html

@@ -444,7 +444,7 @@
                                         <span style="font-weight: 500;">智能策划大师</span>
                                     </div>
                                 </li>
-                                <li class="agent-option" data-agent="videoaccount"
+                                <li class="agent-option" data-agent="pathology"
                                     style="display:flex; align-items:center; gap:8px; padding:12px; border-radius:8px; cursor:pointer; transition: all 0.2s ease; user-select: none;"
                                     onmouseover="this.style.background='rgba(99, 102, 241, 0.1)'"
                                     onmouseout="this.style.background=''">
@@ -517,11 +517,13 @@
             <div class="chat-main-content">
                 <div id="chat-messages" class="chat-messages glass-panel">
                     <div class="message bot">
-                        <div class="message-content">请发送你的投放数据。 如果是视频诊断,目前仅能诊断文案,请去聚德神转转为文案(最好是带时间戳的字幕-聚德智能视频处理工具可导出)。
+                        <div class="message-content">您好,我是聚德策划大师。请输入您需要的内容,例如:
                             <ul>
-                                <!-- <li>请输入想要分析的疾病或者产品名称</li> -->
+                                <li>请输入需要撰写的产品或疾病名称</li>
+                                <li>补充目标人群、投放场景、文案风格</li>
                             </ul>
                         </div>
+                        <div class="message-content">我将为您输出可直接使用的营销文案、脚本方向和优化建议。</div>
                     </div>
                 </div>
                 <div class="chat-input-container glass-panel">
@@ -535,12 +537,12 @@
                 </div>
             </div>
         </div>
-    </div> 
+    </div>
 
     <!-- 页面启动保护:避免脚本异常时出现纯白屏 -->
     <script>
         (function () {
-            function showFatalScreen(msg) {
+            function showFatalScreen (msg) {
                 if (document.getElementById('fatal-boot-error')) return;
                 const box = document.createElement('div');
                 box.id = 'fatal-boot-error';
@@ -587,11 +589,16 @@
     </script>
 
     <!-- 核心JS库 -->
-    <script src="{{ url_for('static', filename='js/highlight.min.js') }}" onerror="window.__onScriptLoadError('highlight.min.js')"></script>
-    <script src="{{ url_for('static', filename='js/marked.min.js') }}" onerror="window.__onScriptLoadError('marked.min.js')"></script>
-    <script src="{{ url_for('static', filename='js/showdown.min.js') }}" onerror="window.__onScriptLoadError('showdown.min.js')"></script>
-    <script src="{{ url_for('static', filename='js/copy-buttons.js') }}" onerror="window.__onScriptLoadError('copy-buttons.js')"></script>
-    <script src="{{ url_for('static', filename='js/chat.js') }}" onerror="window.__onScriptLoadError('chat.js')"></script>
+    <script src="{{ url_for('static', filename='js/highlight.min.js') }}"
+        onerror="window.__onScriptLoadError('highlight.min.js')"></script>
+    <script src="{{ url_for('static', filename='js/marked.min.js') }}"
+        onerror="window.__onScriptLoadError('marked.min.js')"></script>
+    <script src="{{ url_for('static', filename='js/showdown.min.js') }}"
+        onerror="window.__onScriptLoadError('showdown.min.js')"></script>
+    <script src="{{ url_for('static', filename='js/copy-buttons.js') }}"
+        onerror="window.__onScriptLoadError('copy-buttons.js')"></script>
+    <script src="{{ url_for('static', filename='js/chat.js') }}"
+        onerror="window.__onScriptLoadError('chat.js')"></script>
 
     <!-- 认证和用户信息管理 -->
     <!-- 自定义弹框 -->
@@ -674,7 +681,7 @@
 
     <script>
         // 弹框控制函数
-        function showModal(modalId) {
+        function showModal (modalId) {
             const modal = document.getElementById(modalId);
             if (modal) {
                 modal.classList.add('show');
@@ -682,7 +689,7 @@
             }
         }
 
-        function closeModal(modalId) {
+        function closeModal (modalId) {
             const modal = document.getElementById(modalId);
             if (modal) {
                 modal.classList.remove('show');
@@ -690,7 +697,7 @@
             }
         }
 
-        function showMessage(message, type = 'success') {
+        function showMessage (message, type = 'success') {
             const messageText = document.getElementById('message-text');
             const messageIcon = document.querySelector('#message-modal .modal-icon');
 
@@ -742,7 +749,7 @@
         });
 
         // 思考过程折叠/展开函数
-        function toggleThought(button) {
+        function toggleThought (button) {
             const container = button.closest('.thought-container');
             const content = container.querySelector('.thought-content');
             const icon = button.querySelector('svg path');
@@ -762,7 +769,7 @@
             }
         }
 
-        function checkAuthStatus() {
+        function checkAuthStatus () {
             // 检查URL参数中是否有登录成功信息
             const urlParams = new URLSearchParams(window.location.search);
             const loginSuccess = urlParams.get('login_success');
@@ -833,7 +840,7 @@
             }
         }
 
-        function displayUserInfo(user) {
+        function displayUserInfo (user) {
             // 显示用户头像
             const avatarImg = document.getElementById('avatar-img');
             const avatarFallback = document.getElementById('avatar-fallback');
@@ -913,12 +920,12 @@
             }
         }
 
-        function showUserSection() {
+        function showUserSection () {
             const userInfo = document.getElementById('user-info');
             if (userInfo) userInfo.style.display = 'flex';
         }
 
-        function addAuthHeader(token) {
+        function addAuthHeader (token) {
             // 注意:addAuthHeader函数由chat.js提供,这里不需要重复定义
             // 如果需要设置认证头,直接调用chat.js中的函数
             if (typeof window.addAuthHeader === 'function') {
@@ -926,7 +933,7 @@
             }
         }
 
-        function redirectToLogin() {
+        function redirectToLogin () {
             if (isRedirecting) {
                 return;
             }
@@ -955,7 +962,7 @@
         });
 
         // 用户信息下拉菜单(修复:添加鼠标进入/离开事件,防止移向退出登录按钮时菜单消失)
-        function initializeUserDropdown() {
+        function initializeUserDropdown () {
             const userInfo = document.getElementById('user-info');
             const dropdown = document.getElementById('user-dropdown');
 
@@ -972,7 +979,7 @@
             let isHovering = false;
             let hideTimer = null;
 
-            function showDropdown() {
+            function showDropdown () {
                 if (hideTimer) {
                     clearTimeout(hideTimer);
                     hideTimer = null;
@@ -983,7 +990,7 @@
                 dropdown.style.transform = 'translateY(0) scale(1)';
             }
 
-            function scheduleHide() {
+            function scheduleHide () {
                 if (hideTimer) {
                     clearTimeout(hideTimer);
                 }
@@ -1046,10 +1053,86 @@
             }, 100);
         });
 
+        const AGENT_META = {
+            'planning': {
+                name: '智能策划大师',
+                icon: "{{ url_for('static', filename='img/planning.png') }}"
+            },
+            'pathology': {
+                name: '病理分析',
+                icon: "{{ url_for('static', filename='img/videoaccount.svg') }}"
+            },
+            'diagnosis': {
+                name: '投放诊断',
+                icon: "{{ url_for('static', filename='img/diagnosis.svg') }}"
+            },
+        };
+
+        const AGENT_WELCOME_CONTENT = {
+            'planning': [
+                `您好,我是聚德策划大师。请输入您需要的内容,例如:
+                    <ul>
+                        <li>请输入需要撰写的产品或疾病名称</li>
+                        <li>补充目标人群、投放场景、文案风格</li>
+                    </ul>`,
+                '我将为您输出可直接使用的营销文案、脚本方向和优化建议。'
+            ],
+            'pathology': [
+                `您好,我是病理分析助手。为了更准确分析,请尽量提供:
+                    <ul>
+                        <li>疾病或产品名称</li>
+                    </ul>`,
+                '我会给出病理逻辑拆解、用户关注点与内容表达建议。'
+            ],
+            'diagnosis': [
+                `您好,我是投放诊断助手。请发送您的投放数据,例如:
+                    <ul>
+                        <li>消耗、曝光、点击、转化、成本等核心指标</li>
+                    </ul>`,
+                '如果是视频诊断,目前仅支持文案诊断,建议先转为文案(最好附时间戳字幕)。'
+            ]
+        };
+
+        function getCurrentAgentType () {
+            return localStorage.getItem('current_agent') || 'planning';
+        }
+
+        function getAgentWelcomeHtml (agentType) {
+            const welcomeBlocks = AGENT_WELCOME_CONTENT[agentType] || AGENT_WELCOME_CONTENT['planning'];
+            return `
+                <div class="message bot">
+                    ${welcomeBlocks.map(content => `<div class="message-content">${content}</div>`).join('')}
+                </div>
+            `;
+        }
+
+        function renderAgentWelcomeMessage (agentType) {
+            const chatMessages = document.getElementById('chat-messages');
+            if (!chatMessages) return;
+            chatMessages.innerHTML = getAgentWelcomeHtml(agentType || getCurrentAgentType());
+        }
+
+        function syncAgentWelcomeMessageForEmptyConversation () {
+            const chatMessages = document.getElementById('chat-messages');
+            if (!chatMessages) return;
+
+            const hasUserMessages = chatMessages.querySelectorAll('.message.user').length > 0;
+            if (hasUserMessages) return;
+
+            const hasOnlyOneBotMessage = chatMessages.children.length === 1 &&
+                chatMessages.querySelectorAll('.message.bot').length === 1;
+            const hasNoMessages = chatMessages.children.length === 0;
+
+            if (hasOnlyOneBotMessage || hasNoMessages) {
+                renderAgentWelcomeMessage(getCurrentAgentType());
+            }
+        }
+
         // 智能体选择(悬停展开)
         document.addEventListener('DOMContentLoaded', function () {
             setTimeout(() => {
                 initializeAgentHoverDropdown();
+                syncAgentWelcomeMessageForEmptyConversation();
             }, 100);
 
             // 监听窗口大小变化,重新初始化智能体菜单
@@ -1062,27 +1145,14 @@
             });
         });
 
-        function initializeAgentHoverDropdown() {
+        function initializeAgentHoverDropdown () {
             const dropdown = document.getElementById('agent-dropdown');
             const menu = document.getElementById('agent-menu');
             const triggerText = document.getElementById('agent-trigger-text');
             const triggerIcon = document.getElementById('agent-trigger-icon');
             if (!dropdown || !menu) return;
 
-            const agentMeta = {
-                'planning': {
-                    name: '智能策划大师',
-                    icon: "{{ url_for('static', filename='img/planning.png') }}"
-                },
-                'videoaccount': {
-                    name: '病理分析',
-                    icon: "{{ url_for('static', filename='img/videoaccount.svg') }}"
-                },
-                'diagnosis': {
-                    name: '投放诊断',
-                    icon: "{{ url_for('static', filename='img/diagnosis.svg') }}"
-                },
-            };
+            const agentMeta = AGENT_META;
 
             // 兼容历史存储:如果之前存的是已删除的智能体,强制切回智能策划大师
             const storedAgent = localStorage.getItem('current_agent');
@@ -1102,7 +1172,7 @@
             }
 
             // 高亮选中项(仅影响下拉菜单项,不改全局样式)
-            function clearActiveStyles() {
+            function clearActiveStyles () {
                 menu.querySelectorAll('.agent-option').forEach(item => {
                     item.removeAttribute('data-active');
                     item.style.background = '';
@@ -1111,7 +1181,7 @@
                     item.style.pointerEvents = '';
                 });
             }
-            function setActiveStyles(agentType) {
+            function setActiveStyles (agentType) {
                 clearActiveStyles();
                 const activeEl = menu.querySelector(`.agent-option[data-agent="${agentType}"]`);
                 if (activeEl) {
@@ -1132,7 +1202,7 @@
                 // 移动端:点击显示/隐藏菜单
                 let isMenuOpen = false;
 
-                function showMenu() {
+                function showMenu () {
                     menu.style.display = 'block';
                     isMenuOpen = true;
                     // 添加动画类
@@ -1141,7 +1211,7 @@
                     }, 10);
                 }
 
-                function hideMenu() {
+                function hideMenu () {
                     menu.classList.remove('show');
                     setTimeout(() => {
                         menu.style.display = 'none';
@@ -1174,7 +1244,7 @@
                 let isHovering = false;
                 let hideTimer = null;
 
-                function showMenu() {
+                function showMenu () {
                     if (hideTimer) {
                         clearTimeout(hideTimer);
                         hideTimer = null;
@@ -1182,7 +1252,7 @@
                     menu.style.display = 'block';
                 }
 
-                function scheduleHide() {
+                function scheduleHide () {
                     if (hideTimer) {
                         clearTimeout(hideTimer);
                     }
@@ -1295,7 +1365,7 @@
         }
 
         // 检查对话是否有实际的消息内容
-        function checkConversationHasMessages(conversationId) {
+        function checkConversationHasMessages (conversationId) {
             if (!conversationId || conversationId === 'new') {
                 return false;
             }
@@ -1335,7 +1405,7 @@
             return false;
         }
 
-        function switchAgent(agentType) {
+        function switchAgent (agentType) {
             const current = localStorage.getItem('current_agent') || 'planning';
             if (current === agentType) {
                 return;
@@ -1348,12 +1418,15 @@
             // 更新状态提示(如有)
             updateStatusIndicator(agentType);
 
+            // 空对话下切换智能体时,同步更新说明文案
+            syncAgentWelcomeMessageForEmptyConversation();
+
             // 显示切换提示
             showAgentSwitchNotification(agentType);
         }
 
         // 切换智能体并创建新对话
-        function switchAgentWithNewConversation(agentType) {
+        function switchAgentWithNewConversation (agentType) {
             const current = localStorage.getItem('current_agent') || 'planning';
             if (current === agentType) {
                 return;
@@ -1375,7 +1448,7 @@
         }
 
         // 显示智能体切换确认对话框
-        function showAgentSwitchConfirmDialog(newAgentType, currentAgentType, callback) {
+        function showAgentSwitchConfirmDialog (newAgentType, currentAgentType, callback) {
             // 防止重复弹出对话框
             if (document.querySelector('.agent-switch-dialog-overlay')) {
                 return;
@@ -1383,8 +1456,9 @@
 
             const agentNames = {
                 'planning': '智能策划大师',
-                'videoaccount': '病理分析',
+                'pathology': '病理分析',
                 'diagnosis': '投放诊断',
+
                 'kuaishou': '快手',
                 'toutiao': '头条'
             };
@@ -1542,11 +1616,12 @@
             document.addEventListener('keydown', handleEsc);
         }
 
-        function updateStatusIndicator(agentType) {
+        function updateStatusIndicator (agentType) {
             const agentNames = {
                 'planning': '智能策划大师',
-                'videoaccount': '病理分析',
+                'pathology': '病理分析',
                 'diagnosis': '投放诊断',
+
                 'kuaishou': '快手',
                 'toutiao': '头条'
             };
@@ -1557,11 +1632,12 @@
             }
         }
 
-        function showAgentSwitchNotification(agentType) {
+        function showAgentSwitchNotification (agentType) {
             const agentNames = {
                 'planning': '智能策划大师',
-                'videoaccount': '病理分析',
+                'pathology': '病理分析',
                 'diagnosis': '投放诊断',
+
                 'kuaishou': '快手',
                 'toutiao': '头条'
             };
@@ -1599,12 +1675,12 @@
         }
 
         // 获取当前平台类型(供其他功能使用)
-        function getCurrentAgent() {
-            return localStorage.getItem('current_agent') || 'planning';
+        function getCurrentAgent () {
+            return getCurrentAgentType();
         }
 
         // 动态调整聊天消息区域高度
-        function adjustChatMessagesHeight() {
+        function adjustChatMessagesHeight () {
             const userInput = document.getElementById('user-input');
             const chatMessages = document.getElementById('chat-messages');
 
@@ -1629,7 +1705,7 @@
         }
 
         // 滚动到聊天消息区域底部
-        function scrollToBottom() {
+        function scrollToBottom () {
             const chatMessages = document.getElementById('chat-messages');
             if (chatMessages) {
                 chatMessages.scrollTop = chatMessages.scrollHeight;
@@ -1637,7 +1713,7 @@
         }
 
         // 平滑滚动到聊天消息区域底部
-        function smoothScrollToBottom() {
+        function smoothScrollToBottom () {
             const chatMessages = document.getElementById('chat-messages');
             if (chatMessages) {
                 chatMessages.scrollTo({
@@ -1731,7 +1807,7 @@
 
         // 历史记录侧边栏功能 - 移除自动初始化,由认证成功后调用
 
-        function initializeHistorySidebar() {
+        function initializeHistorySidebar () {
             const sidebar = document.getElementById('history-sidebar');
             const sidebarToggle = document.getElementById('sidebar-toggle');
             const sidebarOverlay = document.getElementById('sidebar-overlay');
@@ -1848,7 +1924,7 @@
         }
 
         // 查找现有的空"新对话"
-        function findExistingEmptyConversation() {
+        function findExistingEmptyConversation () {
             const conversationItems = document.querySelectorAll('.conversation-item');
             for (let item of conversationItems) {
                 const messageCountElement = item.querySelector('.message-count');
@@ -1867,7 +1943,7 @@
         }
 
         // 切换到现有的空"新对话"
-        function switchToExistingEmptyConversation(conversation) {
+        function switchToExistingEmptyConversation (conversation) {
             // 更新当前对话ID和session_id
             window.currentConversationId = conversation.conversationId;
             window.currentSessionId = conversation.sessionId;
@@ -1902,7 +1978,7 @@
             }
         }
 
-        function createNewConversation() {
+        function createNewConversation () {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -2009,15 +2085,10 @@
                 });
         }
 
-        function clearCurrentConversation() {
+        function clearCurrentConversation () {
             const chatMessages = document.getElementById('chat-messages');
             if (chatMessages) {
-                chatMessages.innerHTML = `
-                    <div class="message bot">
-                        <div class="message-content">请发送你的投放数据。如果是视频诊断,目前仅能诊断文案,请去聚德神转转为文案(最好是带时间戳的字幕-聚德智能视频处理工具可导出)。
-                        </div>
-                    </div>
-                `;
+                renderAgentWelcomeMessage(getCurrentAgentType());
             }
 
             // 清除全局状态管理中的当前激活对话
@@ -2029,7 +2100,7 @@
             window.forceNewConversation = false;
         }
 
-        function loadConversation(conversationId) {
+        function loadConversation (conversationId) {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -2046,7 +2117,7 @@
             switchToConversationAndLoad(conversationId, token);
         }
 
-        function switchToConversationAndLoad(conversationId, token) {
+        function switchToConversationAndLoad (conversationId, token) {
             // 调用后端API切换到指定对话
             fetch(`/api/conversations/${conversationId}/switch`, {
                 method: 'POST',
@@ -2076,7 +2147,7 @@
             });
         }
 
-        function loadConversationSimple(conversationId, token) {
+        function loadConversationSimple (conversationId, token) {
             // 检查是否有正在进行的流式响应
             const hasActiveStream = window.conversationStates && window.conversationStates.has(conversationId);
             const streamState = hasActiveStream ? window.conversationStates.get(conversationId) : null;
@@ -2115,11 +2186,7 @@
 
                             // 如果没有消息,显示提示语
                             if (!data.messages || data.messages.length === 0) {
-                                chatMessages.innerHTML = `
-                                    <div class="message bot">
-                                        <div class="message-content">请发送你的投放数据。如果是视频诊断,目前仅能诊断文案,请去聚德神转转为文案(最好是带时间戳的字幕-聚德智能视频处理工具可导出)。</div>
-                                    </div>
-                                `;
+                                renderAgentWelcomeMessage(getCurrentAgentType());
                             } else {
                                 renderAllMessages(data.messages, chatMessages);
                             }
@@ -2370,7 +2437,7 @@
                 });
         }
 
-        function updateExistingMessages(messages, streamElement) {
+        function updateExistingMessages (messages, streamElement) {
             const chatMessages = document.getElementById('chat-messages');
             const existingMessages = Array.from(chatMessages.children);
 
@@ -2392,14 +2459,14 @@
             });
         }
 
-        function renderAllMessages(messages, chatMessages) {
+        function renderAllMessages (messages, chatMessages) {
             messages.forEach((msg, index) => {
                 const messageDiv = createMessageElement(msg);
                 chatMessages.appendChild(messageDiv);
             });
         }
 
-        function createMessageElement(msg) {
+        function createMessageElement (msg) {
             const messageDiv = document.createElement('div');
             messageDiv.className = `message ${msg.role}`;
 
@@ -2516,7 +2583,7 @@
 
 
 
-        function updateConversationSelection(conversationId) {
+        function updateConversationSelection (conversationId) {
             const conversationItems = document.querySelectorAll('.conversation-item');
             conversationItems.forEach(item => {
                 const itemId = item.getAttribute('data-conversation-id');
@@ -2539,7 +2606,7 @@
             });
         }
 
-        function updateConversationStatus(conversationId, status) {
+        function updateConversationStatus (conversationId, status) {
             const conversationItem = document.querySelector(`[data-conversation-id="${conversationId}"]`);
             if (conversationItem) {
                 const statusDot = conversationItem.querySelector('.conversation-status-dot');
@@ -2568,7 +2635,7 @@
             }
         }
 
-        function showConversationMenu(conversationId, button) {
+        function showConversationMenu (conversationId, button) {
             // 创建菜单
             const menu = document.createElement('div');
             menu.className = 'conversation-context-menu';
@@ -2628,7 +2695,7 @@
             });
 
             // 点击外部关闭菜单
-            function closeMenu() {
+            function closeMenu () {
                 menu.style.opacity = '0';
                 menu.style.transform = 'scale(0.9)';
                 setTimeout(() => {
@@ -2639,7 +2706,7 @@
             }
 
             // 点击外部关闭
-            document.addEventListener('click', function closeOnOutsideClick(e) {
+            document.addEventListener('click', function closeOnOutsideClick (e) {
                 if (!menu.contains(e.target) && e.target !== button) {
                     closeMenu();
                     document.removeEventListener('click', closeOnOutsideClick);
@@ -2647,7 +2714,7 @@
             });
         }
 
-        function handleConversationAction(action, conversationId) {
+        function handleConversationAction (action, conversationId) {
             switch (action) {
                 case 'rename':
                     renameConversation(conversationId);
@@ -2658,7 +2725,7 @@
             }
         }
 
-        function renameConversation(conversationId) {
+        function renameConversation (conversationId) {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -2708,7 +2775,7 @@
             }
         }
 
-        function performRename(conversationId, newTitle, token) {
+        function performRename (conversationId, newTitle, token) {
             fetch(`/api/conversations/${conversationId}/rename`, {
                 method: 'POST',
                 headers: {
@@ -2746,7 +2813,7 @@
                 });
         }
 
-        function deleteConversation(conversationId) {
+        function deleteConversation (conversationId) {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -2766,7 +2833,7 @@
             }
         }
 
-        function performDelete(conversationId, token) {
+        function performDelete (conversationId, token) {
             fetch(`/api/conversations/${conversationId}`, {
                 method: 'DELETE',
                 headers: {
@@ -2808,7 +2875,7 @@
                 });
         }
 
-        function loadConversationHistory(autoSelectLatest = false) {
+        function loadConversationHistory (autoSelectLatest = false) {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -2861,7 +2928,7 @@
 
 
 
-        function updateHistorySidebar(conversations, autoSelectLatest = false) {
+        function updateHistorySidebar (conversations, autoSelectLatest = false) {
             // 更新侧边栏的历史记录
             const historyContent = document.querySelector('.history-content');
             const historyLoading = document.getElementById('history-loading');
@@ -2978,7 +3045,7 @@
             }
         }
 
-        function bindConversationEvents() {
+        function bindConversationEvents () {
             // 重新绑定对话项点击事件
             const conversationItems = document.querySelectorAll('.conversation-item');
             conversationItems.forEach(item => {
@@ -3028,7 +3095,7 @@
             });
         }
 
-        function syncSidebarUserInfo() {
+        function syncSidebarUserInfo () {
             const userInfo = localStorage.getItem('user_info');
             if (userInfo) {
                 try {
@@ -3143,7 +3210,7 @@
             }
         }
 
-        function cancelEdit() {
+        function cancelEdit () {
             if (currentEditMessageElement) {
                 // 保存当前滚动位置
                 const chatMessages = document.getElementById('chat-messages');
@@ -3181,7 +3248,7 @@
             }
         }
 
-        function confirmEdit() {
+        function confirmEdit () {
             if (!currentEditMessageElement || !currentEditMessageId) {
                 return;
             }
@@ -3209,7 +3276,7 @@
             performEditMessage(currentEditMessageId, newContent);
         }
 
-        function performEditMessage(messageId, newContent) {
+        function performEditMessage (messageId, newContent) {
             // 检查认证状态
             const token = localStorage.getItem('auth_token');
             if (!token) {
@@ -3262,7 +3329,7 @@
             }
 
             // 创建新的用户消息显示(立即显示编辑后的内容)
-            function createNewUserMessageImmediately() {
+            function createNewUserMessageImmediately () {
                 const chatMessages = document.getElementById('chat-messages');
                 if (!chatMessages) return null;
 
@@ -3410,7 +3477,7 @@
                     const RENDER_INTERVAL = 16;
 
                     // 创建AI回复消息容器
-                    function createBotMessageContainer() {
+                    function createBotMessageContainer () {
                         if (messageDiv) return messageDiv;
 
                         messageDiv = document.createElement('div');
@@ -3462,7 +3529,7 @@
                         return messageDiv;
                     }
 
-                    function readStream() {
+                    function readStream () {
                         reader.read().then(({ done, value }) => {
                             if (done) {
                                 // 流式响应完成
@@ -3508,7 +3575,7 @@
                         });
                     }
 
-                    function handleEditEventData(data) {
+                    function handleEditEventData (data) {
                         // 更新最后更新时间
                         state.lastUpdateTime = Date.now();
 
@@ -3611,7 +3678,7 @@
                         }
                     }
 
-                    function updateUIOnComplete() {
+                    function updateUIOnComplete () {
                         // 删除旧的消息元素(被编辑的消息及其后的所有消息)
                         // 使用chat-messages容器来查找并删除所有相关消息
                         const chatMessages = document.getElementById('chat-messages');
@@ -3678,7 +3745,7 @@
                         forceScrollToBottom();
                     }
 
-                    function updateUIOnError() {
+                    function updateUIOnError () {
                         if (currentEditMessageElement) {
                             const sendBtn = currentEditMessageElement.querySelector('.edit-send-btn');
                             if (sendBtn) {
@@ -3703,14 +3770,14 @@
                         window.isEditingMessage = false;
                     }
 
-                    function forceScrollToBottom() {
+                    function forceScrollToBottom () {
                         const chatMessages = document.getElementById('chat-messages');
                         if (chatMessages) {
                             chatMessages.scrollTop = chatMessages.scrollHeight;
                         }
                     }
 
-                    function isUserNearBottom() {
+                    function isUserNearBottom () {
                         const chatMessages = document.getElementById('chat-messages');
                         if (!chatMessages) return true;
                         const scrollThreshold = 50;