diff --git a/static/app.js b/static/js/app.js
similarity index 97%
rename from static/app.js
rename to static/js/app.js
index bbe12b9..b5ffbf4 100644
--- a/static/app.js
+++ b/static/js/app.js
@@ -1,599 +1,599 @@
-// static/js/app.js
-
-import * as api from './api.js'; // 导入API模块
-import * as ui from './ui_manager.js'; // 导入UI管理模块
-
-let currentSession = {}; // 全局变量,存储当前会话信息
-let currentRoles = []; // 全局变量,存储当前角色列表
-let currentMemories = []; // 全局变量,存储当前记忆集列表
-
-// 初始化应用程序。
-// 加载所有初始数据并设置事件监听器。
-async function initializeApp() {
-    console.log("应用程序初始化开始...");
-
-    ui.initializeUIElements();
-
-    // 恢复窗口宽度设置
-    const savedWidth = localStorage.getItem('chatWindowWidth');
-    if (savedWidth === 'full') {
-        const mainContent = document.querySelector('.main-content');
-        const container = document.querySelector('.container');
-        mainContent.classList.add('full-width');
-        container.classList.add('full-width');
-        // 更新按钮图标
-        const icon = ui.Elements.toggleWidthBtn.querySelector('i');
-        icon.classList.remove('fa-expand-alt');
-        icon.classList.add('fa-compress-alt');
-    }
-
-    // 设置导航菜单点击事件
-    ui.Elements.navItems.forEach(item => {
-        item.addEventListener('click', (e) => {
-            e.preventDefault();
-            ui.showSection(item.dataset.target);
-            // 切换section时刷新数据
-            if (item.dataset.target === 'config-section') loadConfigAndModels();
-            if (item.dataset.target === 'features-section') loadFeaturesAndRoles();
-            if (item.dataset.target === 'memory-section') loadMemoryAndMemories();
-            if (item.dataset.target === 'log-section') loadLogs();
-        });
-    });
-
-    // 加载初始会话信息、角色和记忆列表
-    await loadInitialData();
-
-    // 设置聊天区域事件监听
-    ui.Elements.sendBtn.addEventListener('click', sendMessageHandler);
-    ui.Elements.userInput.addEventListener('keydown', (e) => {
-        if (e.key === 'Enter' && !e.shiftKey) {
-            e.preventDefault(); // 阻止默认换行
-            sendMessageHandler();
-        }
-    });
-    ui.Elements.clearChatHistoryBtn.addEventListener('click', clearChatLogHandler);
-    ui.Elements.toggleWidthBtn.addEventListener('click', toggleChatWindowWidthHandler);
-
-    // 设置配置区域事件监听
-    ui.Elements.saveConfigBtn.addEventListener('click', saveConfigHandler);
-    ui.Elements.showApiKeyCheckbox.addEventListener('change', (e) => {
-        ui.Elements.geminiApiKeyInput.type = e.target.checked ? 'text' : 'password';
-    });
-
-    // 设置特征区域事件监听
-    ui.Elements.refreshFeaturesBtn.addEventListener('click', loadFeaturesAndRoles);
-    ui.Elements.saveFeaturesBtn.addEventListener('click', saveFeaturesContentHandler);
-    ui.Elements.createRoleBtn.addEventListener('click', createRoleHandler);
-
-    // 设置记忆区域事件监听
-    ui.Elements.refreshMemoryBtn.addEventListener('click', loadMemoryAndMemories);
-    ui.Elements.saveMemoryBtn.addEventListener('click', saveMemoryContentHandler);
-    ui.Elements.triggerMemoryUpdateBtn.addEventListener('click', triggerMemoryUpdateHandler);
-    ui.Elements.createMemoryBtn.addEventListener('click', createMemoryHandler);
-
-    // 设置日志区域事件监听
-    ui.Elements.refreshLogBtn.addEventListener('click', loadLogs);
-
-    // 默认显示聊天界面并加载历史
-    ui.showSection('chat-section');
-    await loadChatLog();
-    console.log("应用程序初始化完毕。");
-}
-
-// 加载初始数据:会话信息、角色列表、记忆集列表。
-async function loadInitialData() {
-    try {
-        currentSession = await api.fetchActiveSession();
-        currentRoles = await api.fetchRoles(); // 赋值给全局变量
-        currentMemories = await api.fetchMemories(); // 赋值给全局变量
-        ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
-        ui.setMemoryUpdateStatus(currentSession.memory_status);
-        console.log("初始数据加载完成。", currentSession);
-    } catch (error) {
-        ui.showToast(`加载初始数据失败: ${error.message}`, 'error');
-        console.error("加载初始数据失败:", error);
-    }
-}
-
-// 加载并渲染配置和模型列表。
-async function loadConfigAndModels() {
-    try {
-        const config = await api.fetchConfig();
-        ui.renderConfigForm(config);
-
-        // fetchModels 现在直接通过后端代理获取模型列表,不再需要 baseUrl 参数
-        const models = await api.fetchModels();
-        ui.populateModelSelects(models, config.API.DEFAULT_GEMINI_MODEL, config.API.MEMORY_UPDATE_MODEL);
-        console.log("配置和模型列表加载完成。");
-    } catch (error) {
-        ui.showToast(`加载配置失败: ${error.message}`, 'error');
-        console.error("加载配置失败:", error);
-    }
-}
-
-// 保存配置处理函数。
-async function saveConfigHandler() {
-    const configData = {
-        API: {
-            GEMINI_API_BASE_URL: document.getElementById('gemini-api-base-url').value,
-            GEMINI_API_KEY: ui.Elements.geminiApiKeyInput.value,
-            DEFAULT_GEMINI_MODEL: ui.Elements.defaultGeminiModelSelect.options[ui.Elements.defaultGeminiModelSelect.selectedIndex].value,
-            MEMORY_UPDATE_MODEL: ui.Elements.memoryUpdateModelSelect.options[ui.Elements.memoryUpdateModelSelect.selectedIndex].value,
-        },
-        Application: {
-            CONTEXT_WINDOW_SIZE: parseInt(document.getElementById('context-window-size').value),
-            MEMORY_RETENTION_TURNS: parseInt(document.getElementById('memory-retention-turns').value),
-            MAX_SHORT_TERM_EVENTS: parseInt(document.getElementById('max-short-term-events').value),
-        }
-    };
-
-    ui.toggleLoadingState(ui.Elements.saveConfigBtn, true);
-    try {
-        const response = await api.saveConfig(configData);
-        ui.showToast(response.message, 'success');
-        await loadConfigAndModels(); // 重新加载以确保UI同步
-    } catch (error) {
-        ui.showToast(`保存配置失败: ${error.message}`, 'error');
-    } finally {
-        ui.toggleLoadingState(ui.Elements.saveConfigBtn, false);
-    }
-}
-
-// 加载并渲染聊天记录。
-async function loadChatLog() {
-    try {
-        const chatLog = await api.fetchChatLog();
-        // 确保聊天消息的 role 字段从后端返回的 'ai' 转换为 'bot'
-        // 并且 content 字段在渲染前经过 DOMPurify 清理和 marked 解析
-        ui.renderChatHistory(chatLog.map(msg => ({
-            id: msg.id, // 传递消息ID
-            role: msg.role === 'user' ? 'user' : 'bot',
-            content: msg.content,
-            timestamp: msg.timestamp
-        })));
-        console.log("聊天记录加载完成。");
-    } catch (error) {
-        ui.showToast(`加载聊天记录失败: ${error.message}`, 'error');
-        console.error("加载聊天记录失败:", error);
-    }
-}
-
-// 清空聊天记录处理函数。
-async function clearChatLogHandler() {
-    ui.showModal(
-        "清空聊天记录",
-        "确定要清空当前聊天记录吗?此操作不可逆。",
-        async () => {
-            ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, true);
-            try {
-                const response = await api.clearChatLog();
-                ui.showToast(response.message, 'success');
-                ui.renderChatHistory([]); // 清空UI
-                currentSession.turn_counter = 0; // 重置轮次计数器
-                ui.updateSessionInfo(currentSession);
-                triggerMemoryUpdateHandler(); // 触发记忆更新
-                console.log("聊天记录清空成功。");
-            } catch (error) {
-                ui.showToast(`清空聊天记录失败: ${error.message}`, 'error');
-                console.error("清空聊天记录失败:", error);
-            } finally {
-                ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, false);
-            }
-        });
-}
-
-
-// 发送消息处理函数。
-async function sendMessageHandler() {
-    const message = ui.Elements.userInput.value.trim();
-    if (!message) {
-        return;
-    }
-
-    // 为用户消息生成一个唯一的ID
-    const userMessageId = `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-    ui.addChatMessage('user', message, new Date().toISOString(), userMessageId);
-    ui.Elements.userInput.value = ''; // 清空输入框
-
-    // 禁用发送按钮和输入框
-    ui.toggleLoadingState(ui.Elements.sendBtn, true);
-    ui.toggleLoadingState(ui.Elements.userInput, true);
-
-    // 添加一个临时的"AI 正在思考..."消息,并生成一个唯一的ID
-    const thinkingMessageId = `bot-thinking-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-    ui.addChatMessage('bot', 'AI 正在思考...', new Date().toISOString(), thinkingMessageId);
-
-    // 设置重试参数
-    const maxRetries = 3; // 最大重试次数
-    const retryDelay = 1000; // 重试间隔(毫秒)
-    let retryCount = 0;
-    let success = false;
-
-    while (retryCount < maxRetries && !success) {
-        try {
-            if (retryCount > 0) {
-                // 如果是重试,更新思考消息
-                ui.updateChatMessageContent(thinkingMessageId, `AI 正在思考...(第${retryCount}次重试)`);
-                await new Promise(resolve => setTimeout(resolve, retryDelay)); // 等待一段时间再重试
-            }
-            console.log("正在发送消息...", retryCount > 0 ? `(第${retryCount}次重试)` : "");
-
-            // 检查是否支持流式响应
-            // 使用流式响应方式发送消息
-            try {
-                const response = await api.sendMessage(message, true); // 添加第二个参数表示使用流式响应
-
-                // 标记请求已成功
-                success = true;
-
-                // 初始化流式响应处理
-                let fullResponse = "";
-                let isFirstChunk = true;
-
-                // 为响应创建一个永久的消息ID,替换思考消息
-                const permanentBotMessageId = `bot-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-
-                // 处理流式响应的每个块
-                for await (const textChunk of response) {
-                    if (textChunk) {
-                        console.log('接收到文本块:', textChunk.substring(0, 50) + '...');
-                        if (isFirstChunk) {
-                            // 第一次收到数据时,替换思考消息为新的消息
-                            ui.removeChatMessage(thinkingMessageId);
-                            fullResponse = textChunk; // 初始化 fullResponse
-                            ui.addChatMessage('bot', fullResponse, new Date().toISOString(), permanentBotMessageId);
-                            isFirstChunk = false;
-                        } else {
-                            // 后续数据,累加并更新现有消息
-                            fullResponse += textChunk;
-                            ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
-                        }
-                    }
-                }
-
-                // 流结束后,确保界面更新
-                if (fullResponse && !isFirstChunk) {
-                    ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
-                } else if (isFirstChunk) {
-                    // 如果没有收到任何内容
-                    ui.removeChatMessage(thinkingMessageId);
-                    ui.addChatMessage('bot', '抱歉,未收到AI助手的响应,请重试。', new Date().toISOString(), permanentBotMessageId);
-                }
-
-                // 流式响应结束后,重新获取会话信息以更新 turn_counter 和 memory_status
-                currentSession = await api.fetchActiveSession();
-                ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
-                triggerMemoryUpdateHandler(); // 触发记忆更新
-
-
-            } catch (streamError) {
-                console.warn("流式请求失败,回退到标准请求:", streamError);
-
-                // 回退到标准请求
-                const response = await api.sendMessage(message, false);
-
-                if (response && response.success) {
-                    console.log("消息发送成功,收到响应:", response);
-                    // 成功时,更新临时消息为 AI 的实际回复
-                    ui.updateChatMessageContent(thinkingMessageId, response.response);
-                    // 更新会话信息
-                    currentSession.turn_counter = response.turn_counter;
-                    currentSession.memory_status = response.memory_status; // 更新记忆状态
-                    ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
-                    success = true;
-                    triggerMemoryUpdateHandler(); // 触发记忆更新
-                } else if (response) {
-                    console.warn("API返回成功但内容表示失败:", response);
-                    throw new Error(response.message || '发送消息失败');
-                } else {
-                    throw new Error('服务器未返回有效响应');
-                }
-            }
-        } catch (error) {
-            console.error(`发送消息时发生错误 (尝试 ${retryCount + 1}/${maxRetries}):`, error);
-            retryCount++;
-
-            // 如果是最后一次尝试仍然失败
-            if (retryCount >= maxRetries && !success) {
-                // 移除思考消息并显示错误提示
-                ui.removeChatMessage(thinkingMessageId);
-                ui.showToast(`发送消息失败,已尝试 ${maxRetries} 次。请稍后再试。`, 'error');
-            }
-        }
-    }
-
-    // 重新启用发送按钮和输入框
-    ui.toggleLoadingState(ui.Elements.sendBtn, false);
-    ui.toggleLoadingState(ui.Elements.userInput, false);
-}
-
-// 加载并渲染特征内容和角色列表。
-async function loadFeaturesAndRoles() {
-    try {
-        const roles = await api.fetchRoles();
-        const featuresContent = await api.fetchFeaturesContent();
-
-        ui.renderFeaturesContent(featuresContent);
-        ui.renderRoleList(roles, currentSession.role_id, switchRoleHandler, deleteRoleHandler);
-        console.log("特征和角色列表加载完成。");
-    } catch (error) {
-        ui.showToast(`加载特征或角色失败: ${error.message}`, 'error');
-        console.error("加载特征或角色失败:", error);
-    }
-}
-
-// 保存特征内容处理函数。
-async function saveFeaturesContentHandler() {
-    let content;
-    try {
-        content = JSON.parse(ui.Elements.featuresContentTextarea.value);
-    } catch (error) {
-        ui.showToast(`特征内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
-        console.error("解析特征内容失败:", error);
-        return;
-    }
-
-    ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, true);
-    try {
-        const response = await api.saveFeaturesContent(content);
-        ui.showToast(response.message, 'success');
-    } catch (error) {
-        ui.showToast(`保存特征内容失败: ${error.message}`, 'error');
-        console.error("保存特征内容失败:", error);
-    } finally {
-        ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, false);
-    }
-}
-
-// 创建新角色处理函数。
-async function createRoleHandler() {
-    const roleId = ui.Elements.newRoleIdInput.value.trim();
-    const roleName = ui.Elements.newRoleNameInput.value.trim();
-    if (!roleId || !roleName) {
-        ui.showToast("角色ID和名称不能为空。", 'warning');
-        return;
-    }
-
-    ui.toggleLoadingState(ui.Elements.createRoleBtn, true);
-    try {
-        const response = await api.createRole(roleId, roleName);
-        ui.showToast(response.message, 'success');
-        ui.Elements.newRoleIdInput.value = '';
-        ui.Elements.newRoleNameInput.value = '';
-        await loadFeaturesAndRoles(); // 刷新列表
-    } catch (error) {
-        ui.showToast(`创建角色失败: ${error.message}`, 'error');
-    } finally {
-        ui.toggleLoadingState(ui.Elements.createRoleBtn, false);
-    }
-}
-
-// 切换角色处理函数。
-// @param { string } roleId 要切换到的角色ID。
-async function switchRoleHandler(roleId) {
-    if (roleId === currentSession.role_id) {
-        ui.showToast("当前角色已是此角色。", 'info');
-        return;
-    }
-    ui.showModal(
-        "切换角色",
-        `确定要切换到角色 "${roleId}" 吗?这会重置当前对话。`,
-        async (confirmBtn) => { // 传入确认按钮元素
-            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
-            try {
-                const response = await api.setActiveSession(roleId, currentSession.memory_id);
-                currentSession = response;
-                await loadInitialData();
-                await loadFeaturesAndRoles();
-                await loadChatLog();
-                triggerMemoryUpdateHandler(); // 触发记忆更新
-                ui.showToast(`已切换到角色 "${roleId}"`, 'success');
-            } catch (error) {
-                ui.showToast(`切换角色失败: ${error.message}`, 'error');
-                console.error("切换角色失败:", error);
-            } finally {
-                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
-            }
-        }
-    );
-}
-
-// 删除角色处理函数。
-// @param { string } roleId 要删除的角色ID。
-async function deleteRoleHandler(roleId) {
-    if (roleId === currentSession.role_id) {
-        ui.showToast("不能删除当前活跃的角色!", 'error');
-        return;
-    }
-    ui.showModal(
-        "删除角色",
-        `确定要删除角色 "${roleId}" 吗?此操作可逆。`,
-        async (confirmBtn) => { // 传入确认按钮元素
-            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
-            try {
-                const response = await api.deleteRole(roleId);
-                ui.showToast(response.message, 'success');
-                await loadFeaturesAndRoles(); // 刷新列表
-            } catch (error) {
-                ui.showToast(`删除角色失败: ${error.message}`, 'error');
-            } finally {
-                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
-            }
-        }
-    );
-}
-
-// 加载并渲染记忆内容和记忆集列表。
-async function loadMemoryAndMemories() {
-    try {
-        const memories = await api.fetchMemories();
-        const memoryContent = await api.fetchMemoryContent();
-
-        ui.renderMemoryContent(memoryContent);
-        ui.renderMemoryList(memories, currentSession.memory_id, switchMemoryHandler, deleteMemoryHandler);
-        console.log("记忆内容和记忆集列表加载完成。");
-    } catch (error) {
-        ui.showToast(`加载记忆或记忆集失败: ${error.message}`, 'error');
-        console.error("加载记忆或记忆集失败:", error);
-    }
-}
-
-// 保存记忆内容处理函数。
-async function saveMemoryContentHandler() {
-    let content;
-    try {
-        content = JSON.parse(ui.Elements.memoryContentTextarea.value);
-    } catch (error) {
-        ui.showToast(`记忆内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
-        console.error("解析记忆内容失败:", error);
-        return;
-    }
-
-    ui.toggleLoadingState(ui.Elements.saveMemoryBtn, true);
-    try {
-        const response = await api.saveMemoryContent(content);
-        ui.showToast(response.message, 'success');
-    } catch (error) {
-        ui.showToast(`保存记忆内容失败: ${error.message}`, 'error');
-        console.error("保存记忆内容失败:", error);
-    } finally {
-        ui.toggleLoadingState(ui.Elements.saveMemoryBtn, false);
-    }
-}
-
-// 创建新记忆集处理函数。
-async function createMemoryHandler() {
-    const memoryId = ui.Elements.newMemoryIdInput.value.trim();
-    const memoryName = ui.Elements.newMemoryNameInput.value.trim();
-    if (!memoryId || !memoryName) {
-        ui.showToast("记忆集ID和名称不能为空。", 'warning');
-        return;
-    }
-
-    ui.toggleLoadingState(ui.Elements.createMemoryBtn, true);
-    try {
-        const response = await api.createMemory(memoryId, memoryName);
-        ui.showToast(response.message, 'success');
-        ui.Elements.newMemoryIdInput.value = '';
-        ui.Elements.newMemoryNameInput.value = '';
-        await loadMemoryAndMemories(); // 刷新列表
-    } catch (error) {
-        ui.showToast(`创建记忆集失败: ${error.message}`, 'error');
-    } finally {
-        ui.toggleLoadingState(ui.Elements.createMemoryBtn, false);
-    }
-}
-
-// 切换记忆集处理函数。
-// @param { string } memoryId 要切换到的记忆集ID。
-async function switchMemoryHandler(memoryId) {
-    if (memoryId === currentSession.memory_id) {
-        ui.showToast("当前记忆集是此记忆集。", 'info');
-        return;
-    }
-    ui.showModal(
-        "切换记忆集",
-        `确定要切换到记忆集 "${memoryId}" 吗?这会重置当前对话。`,
-        async (confirmBtn) => { // 传入确认按钮元素
-            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
-            try {
-                const response = await api.setActiveSession(currentSession.role_id, memoryId);
-                currentSession = response;
-                await loadInitialData();
-                await loadMemoryAndMemories();
-                await loadChatLog();
-                triggerMemoryUpdateHandler(); // 触发记忆更新
-                ui.showToast(`已切换到记忆集 "${memoryId}"`, 'success');
-            } catch (error) {
-                ui.showToast(`切换记忆集失败: ${error.message}`, 'error');
-                console.error("切换记忆集失败:", error);
-            } finally {
-                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
-            }
-        }
-    );
-}
-
-// 删除记忆集处理函数。
-// @param { string } memoryId 要删除的记忆集ID。
-async function deleteMemoryHandler(memoryId) {
-    if (memoryId === currentSession.memory_id) {
-        ui.showToast("不能删除当前活跃的记忆集!", 'error');
-        return;
-    }
-    ui.showModal(
-        "删除记忆集",
-        `确定要删除记忆集 "${memoryId}" 吗?此操作不可逆。`,
-        async (confirmBtn) => { // 传入确认按钮元素
-            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
-            try {
-                const response = await api.deleteMemory(memoryId);
-                ui.showToast(response.message, 'success');
-                await loadMemoryAndMemories(); // 刷新列表
-            } catch (error) {
-                ui.showToast(`删除记忆集失败: ${error.message}`, 'error');
-            } finally {
-                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
-            }
-        }
-    );
-}
-
-// 触发记忆更新处理函数。
-async function triggerMemoryUpdateHandler() {
-    ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, true);
-    ui.setMemoryUpdateStatus('updating'); // 设置为updating状态
-    ui.Elements.memoryUpdateStatusText.textContent = '记忆整理中 (手动)...';
-    try {
-        const response = await api.triggerMemoryUpdate();
-        ui.showToast(response.message, 'info');
-        // 记忆更新是异步的,触发后需要重新获取会话信息来更新状态
-        currentSession = await api.fetchActiveSession();
-        ui.setMemoryUpdateStatus(currentSession.memory_status);
-    } catch (error) {
-        ui.showToast(`触发记忆更新失败: ${error.message}`, 'error');
-        console.error("触发记忆更新失败:", error);
-        ui.setMemoryUpdateStatus('error'); // 触发失败则显示错误状态
-    } finally {
-        ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, false);
-    }
-}
-
-
-// 加载并渲染日志内容。
-async function loadLogs() {
-    try {
-        const logContent = await api.fetchLogs(); // 通过API获取日志
-        ui.renderLogContent(logContent);
-        console.log("日志加载完成。");
-    } catch (error) {
-        ui.showToast(`加载日志失败: ${error.message}`, 'error');
-        console.error("加载日志失败:", error);
-        ui.renderLogContent(`加载日志失败: ${error.message}`);
-    }
-}
-
-// 切换聊天窗口宽度处理函数
-function toggleChatWindowWidthHandler() {
-    const mainContent = document.querySelector('.main-content');
-    const container = document.querySelector('.container');
-
-    // 同时切换主内容区和容器的全宽类
-    mainContent.classList.toggle('full-width');
-    container.classList.toggle('full-width');
-
-    // 切换按钮图标
-    const icon = ui.Elements.toggleWidthBtn.querySelector('i');
-    if (mainContent.classList.contains('full-width')) {
-        icon.classList.remove('fa-expand-alt');
-        icon.classList.add('fa-compress-alt');
-        localStorage.setItem('chatWindowWidth', 'full');
-    } else {
-        icon.classList.remove('fa-compress-alt');
-        icon.classList.add('fa-expand-alt');
-        localStorage.setItem('chatWindowWidth', 'default');
-    }
-}
-
-// 应用程序启动
-document.addEventListener('DOMContentLoaded', initializeApp);
+// static/js/app.js
+
+import * as api from './api.js'; // 导入API模块
+import * as ui from './ui_manager.js'; // 导入UI管理模块
+
+let currentSession = {}; // 全局变量,存储当前会话信息
+let currentRoles = []; // 全局变量,存储当前角色列表
+let currentMemories = []; // 全局变量,存储当前记忆集列表
+
+// 初始化应用程序。
+// 加载所有初始数据并设置事件监听器。
+async function initializeApp() {
+    console.log("应用程序初始化开始...");
+
+    ui.initializeUIElements();
+
+    // 恢复窗口宽度设置
+    const savedWidth = localStorage.getItem('chatWindowWidth');
+    if (savedWidth === 'full') {
+        const mainContent = document.querySelector('.main-content');
+        const container = document.querySelector('.container');
+        mainContent.classList.add('full-width');
+        container.classList.add('full-width');
+        // 更新按钮图标
+        const icon = ui.Elements.toggleWidthBtn.querySelector('i');
+        icon.classList.remove('fa-expand-alt');
+        icon.classList.add('fa-compress-alt');
+    }
+
+    // 设置导航菜单点击事件
+    ui.Elements.navItems.forEach(item => {
+        item.addEventListener('click', (e) => {
+            e.preventDefault();
+            ui.showSection(item.dataset.target);
+            // 切换section时刷新数据
+            if (item.dataset.target === 'config-section') loadConfigAndModels();
+            if (item.dataset.target === 'features-section') loadFeaturesAndRoles();
+            if (item.dataset.target === 'memory-section') loadMemoryAndMemories();
+            if (item.dataset.target === 'log-section') loadLogs();
+        });
+    });
+
+    // 加载初始会话信息、角色和记忆列表
+    await loadInitialData();
+
+    // 设置聊天区域事件监听
+    ui.Elements.sendBtn.addEventListener('click', sendMessageHandler);
+    ui.Elements.userInput.addEventListener('keydown', (e) => {
+        if (e.key === 'Enter' && !e.shiftKey) {
+            e.preventDefault(); // 阻止默认换行
+            sendMessageHandler();
+        }
+    });
+    ui.Elements.clearChatHistoryBtn.addEventListener('click', clearChatLogHandler);
+    ui.Elements.toggleWidthBtn.addEventListener('click', toggleChatWindowWidthHandler);
+
+    // 设置配置区域事件监听
+    ui.Elements.saveConfigBtn.addEventListener('click', saveConfigHandler);
+    ui.Elements.showApiKeyCheckbox.addEventListener('change', (e) => {
+        ui.Elements.geminiApiKeyInput.type = e.target.checked ? 'text' : 'password';
+    });
+
+    // 设置特征区域事件监听
+    ui.Elements.refreshFeaturesBtn.addEventListener('click', loadFeaturesAndRoles);
+    ui.Elements.saveFeaturesBtn.addEventListener('click', saveFeaturesContentHandler);
+    ui.Elements.createRoleBtn.addEventListener('click', createRoleHandler);
+
+    // 设置记忆区域事件监听
+    ui.Elements.refreshMemoryBtn.addEventListener('click', loadMemoryAndMemories);
+    ui.Elements.saveMemoryBtn.addEventListener('click', saveMemoryContentHandler);
+    ui.Elements.triggerMemoryUpdateBtn.addEventListener('click', triggerMemoryUpdateHandler);
+    ui.Elements.createMemoryBtn.addEventListener('click', createMemoryHandler);
+
+    // 设置日志区域事件监听
+    ui.Elements.refreshLogBtn.addEventListener('click', loadLogs);
+
+    // 默认显示聊天界面并加载历史
+    ui.showSection('chat-section');
+    await loadChatLog();
+    console.log("应用程序初始化完毕。");
+}
+
+// 加载初始数据:会话信息、角色列表、记忆集列表。
+async function loadInitialData() {
+    try {
+        currentSession = await api.fetchActiveSession();
+        currentRoles = await api.fetchRoles(); // 赋值给全局变量
+        currentMemories = await api.fetchMemories(); // 赋值给全局变量
+        ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
+        ui.setMemoryUpdateStatus(currentSession.memory_status);
+        console.log("初始数据加载完成。", currentSession);
+    } catch (error) {
+        ui.showToast(`加载初始数据失败: ${error.message}`, 'error');
+        console.error("加载初始数据失败:", error);
+    }
+}
+
+// 加载并渲染配置和模型列表。
+async function loadConfigAndModels() {
+    try {
+        const config = await api.fetchConfig();
+        ui.renderConfigForm(config);
+
+        // fetchModels 现在直接通过后端代理获取模型列表,不再需要 baseUrl 参数
+        const models = await api.fetchModels();
+        ui.populateModelSelects(models, config.API.DEFAULT_GEMINI_MODEL, config.API.MEMORY_UPDATE_MODEL);
+        console.log("配置和模型列表加载完成。");
+    } catch (error) {
+        ui.showToast(`加载配置失败: ${error.message}`, 'error');
+        console.error("加载配置失败:", error);
+    }
+}
+
+// 保存配置处理函数。
+async function saveConfigHandler() {
+    const configData = {
+        API: {
+            GEMINI_API_BASE_URL: document.getElementById('gemini-api-base-url').value,
+            GEMINI_API_KEY: ui.Elements.geminiApiKeyInput.value,
+            DEFAULT_GEMINI_MODEL: ui.Elements.defaultGeminiModelSelect.options[ui.Elements.defaultGeminiModelSelect.selectedIndex].value,
+            MEMORY_UPDATE_MODEL: ui.Elements.memoryUpdateModelSelect.options[ui.Elements.memoryUpdateModelSelect.selectedIndex].value,
+        },
+        Application: {
+            CONTEXT_WINDOW_SIZE: parseInt(document.getElementById('context-window-size').value),
+            MEMORY_RETENTION_TURNS: parseInt(document.getElementById('memory-retention-turns').value),
+            MAX_SHORT_TERM_EVENTS: parseInt(document.getElementById('max-short-term-events').value),
+        }
+    };
+
+    ui.toggleLoadingState(ui.Elements.saveConfigBtn, true);
+    try {
+        const response = await api.saveConfig(configData);
+        ui.showToast(response.message, 'success');
+        await loadConfigAndModels(); // 重新加载以确保UI同步
+    } catch (error) {
+        ui.showToast(`保存配置失败: ${error.message}`, 'error');
+    } finally {
+        ui.toggleLoadingState(ui.Elements.saveConfigBtn, false);
+    }
+}
+
+// 加载并渲染聊天记录。
+async function loadChatLog() {
+    try {
+        const chatLog = await api.fetchChatLog();
+        // 确保聊天消息的 role 字段从后端返回的 'ai' 转换为 'bot'
+        // 并且 content 字段在渲染前经过 DOMPurify 清理和 marked 解析
+        ui.renderChatHistory(chatLog.map(msg => ({
+            id: msg.id, // 传递消息ID
+            role: msg.role === 'user' ? 'user' : 'bot',
+            content: msg.content,
+            timestamp: msg.timestamp
+        })));
+        console.log("聊天记录加载完成。");
+    } catch (error) {
+        ui.showToast(`加载聊天记录失败: ${error.message}`, 'error');
+        console.error("加载聊天记录失败:", error);
+    }
+}
+
+// 清空聊天记录处理函数。
+async function clearChatLogHandler() {
+    ui.showModal(
+        "清空聊天记录",
+        "确定要清空当前聊天记录吗?此操作不可逆。",
+        async () => {
+            ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, true);
+            try {
+                const response = await api.clearChatLog();
+                ui.showToast(response.message, 'success');
+                ui.renderChatHistory([]); // 清空UI
+                currentSession.turn_counter = 0; // 重置轮次计数器
+                ui.updateSessionInfo(currentSession);
+                triggerMemoryUpdateHandler(); // 触发记忆更新
+                console.log("聊天记录清空成功。");
+            } catch (error) {
+                ui.showToast(`清空聊天记录失败: ${error.message}`, 'error');
+                console.error("清空聊天记录失败:", error);
+            } finally {
+                ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, false);
+            }
+        });
+}
+
+
+// 发送消息处理函数。
+async function sendMessageHandler() {
+    const message = ui.Elements.userInput.value.trim();
+    if (!message) {
+        return;
+    }
+
+    // 为用户消息生成一个唯一的ID
+    const userMessageId = `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+    ui.addChatMessage('user', message, new Date().toISOString(), userMessageId);
+    ui.Elements.userInput.value = ''; // 清空输入框
+
+    // 禁用发送按钮和输入框
+    ui.toggleLoadingState(ui.Elements.sendBtn, true);
+    ui.toggleLoadingState(ui.Elements.userInput, true);
+
+    // 添加一个临时的"AI 正在思考..."消息,并生成一个唯一的ID
+    const thinkingMessageId = `bot-thinking-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+    ui.addChatMessage('bot', 'AI 正在思考...', new Date().toISOString(), thinkingMessageId);
+
+    // 设置重试参数
+    const maxRetries = 3; // 最大重试次数
+    const retryDelay = 1000; // 重试间隔(毫秒)
+    let retryCount = 0;
+    let success = false;
+
+    while (retryCount < maxRetries && !success) {
+        try {
+            if (retryCount > 0) {
+                // 如果是重试,更新思考消息
+                ui.updateChatMessageContent(thinkingMessageId, `AI 正在思考...(第${retryCount}次重试)`);
+                await new Promise(resolve => setTimeout(resolve, retryDelay)); // 等待一段时间再重试
+            }
+            console.log("正在发送消息...", retryCount > 0 ? `(第${retryCount}次重试)` : "");
+
+            // 检查是否支持流式响应
+            // 使用流式响应方式发送消息
+            try {
+                const response = await api.sendMessage(message, true); // 添加第二个参数表示使用流式响应
+
+                // 标记请求已成功
+                success = true;
+
+                // 初始化流式响应处理
+                let fullResponse = "";
+                let isFirstChunk = true;
+
+                // 为响应创建一个永久的消息ID,替换思考消息
+                const permanentBotMessageId = `bot-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+
+                // 处理流式响应的每个块
+                for await (const textChunk of response) {
+                    if (textChunk) {
+                        console.log('接收到文本块:', textChunk.substring(0, 50) + '...');
+                        if (isFirstChunk) {
+                            // 第一次收到数据时,替换思考消息为新的消息
+                            ui.removeChatMessage(thinkingMessageId);
+                            fullResponse = textChunk; // 初始化 fullResponse
+                            ui.addChatMessage('bot', fullResponse, new Date().toISOString(), permanentBotMessageId);
+                            isFirstChunk = false;
+                        } else {
+                            // 后续数据,累加并更新现有消息
+                            fullResponse += textChunk;
+                            ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
+                        }
+                    }
+                }
+
+                // 流结束后,确保界面更新
+                if (fullResponse && !isFirstChunk) {
+                    ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
+                } else if (isFirstChunk) {
+                    // 如果没有收到任何内容
+                    ui.removeChatMessage(thinkingMessageId);
+                    ui.addChatMessage('bot', '抱歉,未收到AI助手的响应,请重试。', new Date().toISOString(), permanentBotMessageId);
+                }
+
+                // 流式响应结束后,重新获取会话信息以更新 turn_counter 和 memory_status
+                currentSession = await api.fetchActiveSession();
+                ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
+                triggerMemoryUpdateHandler(); // 触发记忆更新
+
+
+            } catch (streamError) {
+                console.warn("流式请求失败,回退到标准请求:", streamError);
+
+                // 回退到标准请求
+                const response = await api.sendMessage(message, false);
+
+                if (response && response.success) {
+                    console.log("消息发送成功,收到响应:", response);
+                    // 成功时,更新临时消息为 AI 的实际回复
+                    ui.updateChatMessageContent(thinkingMessageId, response.response);
+                    // 更新会话信息
+                    currentSession.turn_counter = response.turn_counter;
+                    currentSession.memory_status = response.memory_status; // 更新记忆状态
+                    ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
+                    success = true;
+                    triggerMemoryUpdateHandler(); // 触发记忆更新
+                } else if (response) {
+                    console.warn("API返回成功但内容表示失败:", response);
+                    throw new Error(response.message || '发送消息失败');
+                } else {
+                    throw new Error('服务器未返回有效响应');
+                }
+            }
+        } catch (error) {
+            console.error(`发送消息时发生错误 (尝试 ${retryCount + 1}/${maxRetries}):`, error);
+            retryCount++;
+
+            // 如果是最后一次尝试仍然失败
+            if (retryCount >= maxRetries && !success) {
+                // 移除思考消息并显示错误提示
+                ui.removeChatMessage(thinkingMessageId);
+                ui.showToast(`发送消息失败,已尝试 ${maxRetries} 次。请稍后再试。`, 'error');
+            }
+        }
+    }
+
+    // 重新启用发送按钮和输入框
+    ui.toggleLoadingState(ui.Elements.sendBtn, false);
+    ui.toggleLoadingState(ui.Elements.userInput, false);
+}
+
+// 加载并渲染特征内容和角色列表。
+async function loadFeaturesAndRoles() {
+    try {
+        const roles = await api.fetchRoles();
+        const featuresContent = await api.fetchFeaturesContent();
+
+        ui.renderFeaturesContent(featuresContent);
+        ui.renderRoleList(roles, currentSession.role_id, switchRoleHandler, deleteRoleHandler);
+        console.log("特征和角色列表加载完成。");
+    } catch (error) {
+        ui.showToast(`加载特征或角色失败: ${error.message}`, 'error');
+        console.error("加载特征或角色失败:", error);
+    }
+}
+
+// 保存特征内容处理函数。
+async function saveFeaturesContentHandler() {
+    let content;
+    try {
+        content = JSON.parse(ui.Elements.featuresContentTextarea.value);
+    } catch (error) {
+        ui.showToast(`特征内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
+        console.error("解析特征内容失败:", error);
+        return;
+    }
+
+    ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, true);
+    try {
+        const response = await api.saveFeaturesContent(content);
+        ui.showToast(response.message, 'success');
+    } catch (error) {
+        ui.showToast(`保存特征内容失败: ${error.message}`, 'error');
+        console.error("保存特征内容失败:", error);
+    } finally {
+        ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, false);
+    }
+}
+
+// 创建新角色处理函数。
+async function createRoleHandler() {
+    const roleId = ui.Elements.newRoleIdInput.value.trim();
+    const roleName = ui.Elements.newRoleNameInput.value.trim();
+    if (!roleId || !roleName) {
+        ui.showToast("角色ID和名称不能为空。", 'warning');
+        return;
+    }
+
+    ui.toggleLoadingState(ui.Elements.createRoleBtn, true);
+    try {
+        const response = await api.createRole(roleId, roleName);
+        ui.showToast(response.message, 'success');
+        ui.Elements.newRoleIdInput.value = '';
+        ui.Elements.newRoleNameInput.value = '';
+        await loadFeaturesAndRoles(); // 刷新列表
+    } catch (error) {
+        ui.showToast(`创建角色失败: ${error.message}`, 'error');
+    } finally {
+        ui.toggleLoadingState(ui.Elements.createRoleBtn, false);
+    }
+}
+
+// 切换角色处理函数。
+// @param { string } roleId 要切换到的角色ID。
+async function switchRoleHandler(roleId) {
+    if (roleId === currentSession.role_id) {
+        ui.showToast("当前角色已是此角色。", 'info');
+        return;
+    }
+    ui.showModal(
+        "切换角色",
+        `确定要切换到角色 "${roleId}" 吗?这会重置当前对话。`,
+        async (confirmBtn) => { // 传入确认按钮元素
+            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
+            try {
+                const response = await api.setActiveSession(roleId, currentSession.memory_id);
+                currentSession = response;
+                await loadInitialData();
+                await loadFeaturesAndRoles();
+                await loadChatLog();
+                triggerMemoryUpdateHandler(); // 触发记忆更新
+                ui.showToast(`已切换到角色 "${roleId}"`, 'success');
+            } catch (error) {
+                ui.showToast(`切换角色失败: ${error.message}`, 'error');
+                console.error("切换角色失败:", error);
+            } finally {
+                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
+            }
+        }
+    );
+}
+
+// 删除角色处理函数。
+// @param { string } roleId 要删除的角色ID。
+async function deleteRoleHandler(roleId) {
+    if (roleId === currentSession.role_id) {
+        ui.showToast("不能删除当前活跃的角色!", 'error');
+        return;
+    }
+    ui.showModal(
+        "删除角色",
+        `确定要删除角色 "${roleId}" 吗?此操作可逆。`,
+        async (confirmBtn) => { // 传入确认按钮元素
+            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
+            try {
+                const response = await api.deleteRole(roleId);
+                ui.showToast(response.message, 'success');
+                await loadFeaturesAndRoles(); // 刷新列表
+            } catch (error) {
+                ui.showToast(`删除角色失败: ${error.message}`, 'error');
+            } finally {
+                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
+            }
+        }
+    );
+}
+
+// 加载并渲染记忆内容和记忆集列表。
+async function loadMemoryAndMemories() {
+    try {
+        const memories = await api.fetchMemories();
+        const memoryContent = await api.fetchMemoryContent();
+
+        ui.renderMemoryContent(memoryContent);
+        ui.renderMemoryList(memories, currentSession.memory_id, switchMemoryHandler, deleteMemoryHandler);
+        console.log("记忆内容和记忆集列表加载完成。");
+    } catch (error) {
+        ui.showToast(`加载记忆或记忆集失败: ${error.message}`, 'error');
+        console.error("加载记忆或记忆集失败:", error);
+    }
+}
+
+// 保存记忆内容处理函数。
+async function saveMemoryContentHandler() {
+    let content;
+    try {
+        content = JSON.parse(ui.Elements.memoryContentTextarea.value);
+    } catch (error) {
+        ui.showToast(`记忆内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
+        console.error("解析记忆内容失败:", error);
+        return;
+    }
+
+    ui.toggleLoadingState(ui.Elements.saveMemoryBtn, true);
+    try {
+        const response = await api.saveMemoryContent(content);
+        ui.showToast(response.message, 'success');
+    } catch (error) {
+        ui.showToast(`保存记忆内容失败: ${error.message}`, 'error');
+        console.error("保存记忆内容失败:", error);
+    } finally {
+        ui.toggleLoadingState(ui.Elements.saveMemoryBtn, false);
+    }
+}
+
+// 创建新记忆集处理函数。
+async function createMemoryHandler() {
+    const memoryId = ui.Elements.newMemoryIdInput.value.trim();
+    const memoryName = ui.Elements.newMemoryNameInput.value.trim();
+    if (!memoryId || !memoryName) {
+        ui.showToast("记忆集ID和名称不能为空。", 'warning');
+        return;
+    }
+
+    ui.toggleLoadingState(ui.Elements.createMemoryBtn, true);
+    try {
+        const response = await api.createMemory(memoryId, memoryName);
+        ui.showToast(response.message, 'success');
+        ui.Elements.newMemoryIdInput.value = '';
+        ui.Elements.newMemoryNameInput.value = '';
+        await loadMemoryAndMemories(); // 刷新列表
+    } catch (error) {
+        ui.showToast(`创建记忆集失败: ${error.message}`, 'error');
+    } finally {
+        ui.toggleLoadingState(ui.Elements.createMemoryBtn, false);
+    }
+}
+
+// 切换记忆集处理函数。
+// @param { string } memoryId 要切换到的记忆集ID。
+async function switchMemoryHandler(memoryId) {
+    if (memoryId === currentSession.memory_id) {
+        ui.showToast("当前记忆集是此记忆集。", 'info');
+        return;
+    }
+    ui.showModal(
+        "切换记忆集",
+        `确定要切换到记忆集 "${memoryId}" 吗?这会重置当前对话。`,
+        async (confirmBtn) => { // 传入确认按钮元素
+            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
+            try {
+                const response = await api.setActiveSession(currentSession.role_id, memoryId);
+                currentSession = response;
+                await loadInitialData();
+                await loadMemoryAndMemories();
+                await loadChatLog();
+                triggerMemoryUpdateHandler(); // 触发记忆更新
+                ui.showToast(`已切换到记忆集 "${memoryId}"`, 'success');
+            } catch (error) {
+                ui.showToast(`切换记忆集失败: ${error.message}`, 'error');
+                console.error("切换记忆集失败:", error);
+            } finally {
+                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
+            }
+        }
+    );
+}
+
+// 删除记忆集处理函数。
+// @param { string } memoryId 要删除的记忆集ID。
+async function deleteMemoryHandler(memoryId) {
+    if (memoryId === currentSession.memory_id) {
+        ui.showToast("不能删除当前活跃的记忆集!", 'error');
+        return;
+    }
+    ui.showModal(
+        "删除记忆集",
+        `确定要删除记忆集 "${memoryId}" 吗?此操作不可逆。`,
+        async (confirmBtn) => { // 传入确认按钮元素
+            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
+            try {
+                const response = await api.deleteMemory(memoryId);
+                ui.showToast(response.message, 'success');
+                await loadMemoryAndMemories(); // 刷新列表
+            } catch (error) {
+                ui.showToast(`删除记忆集失败: ${error.message}`, 'error');
+            } finally {
+                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
+            }
+        }
+    );
+}
+
+// 触发记忆更新处理函数。
+async function triggerMemoryUpdateHandler() {
+    ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, true);
+    ui.setMemoryUpdateStatus('updating'); // 设置为updating状态
+    ui.Elements.memoryUpdateStatusText.textContent = '记忆整理中 (手动)...';
+    try {
+        const response = await api.triggerMemoryUpdate();
+        ui.showToast(response.message, 'info');
+        // 记忆更新是异步的,触发后需要重新获取会话信息来更新状态
+        currentSession = await api.fetchActiveSession();
+        ui.setMemoryUpdateStatus(currentSession.memory_status);
+    } catch (error) {
+        ui.showToast(`触发记忆更新失败: ${error.message}`, 'error');
+        console.error("触发记忆更新失败:", error);
+        ui.setMemoryUpdateStatus('error'); // 触发失败则显示错误状态
+    } finally {
+        ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, false);
+    }
+}
+
+
+// 加载并渲染日志内容。
+async function loadLogs() {
+    try {
+        const logContent = await api.fetchLogs(); // 通过API获取日志
+        ui.renderLogContent(logContent);
+        console.log("日志加载完成。");
+    } catch (error) {
+        ui.showToast(`加载日志失败: ${error.message}`, 'error');
+        console.error("加载日志失败:", error);
+        ui.renderLogContent(`加载日志失败: ${error.message}`);
+    }
+}
+
+// 切换聊天窗口宽度处理函数
+function toggleChatWindowWidthHandler() {
+    const mainContent = document.querySelector('.main-content');
+    const container = document.querySelector('.container');
+
+    // 同时切换主内容区和容器的全宽类
+    mainContent.classList.toggle('full-width');
+    container.classList.toggle('full-width');
+
+    // 切换按钮图标
+    const icon = ui.Elements.toggleWidthBtn.querySelector('i');
+    if (mainContent.classList.contains('full-width')) {
+        icon.classList.remove('fa-expand-alt');
+        icon.classList.add('fa-compress-alt');
+        localStorage.setItem('chatWindowWidth', 'full');
+    } else {
+        icon.classList.remove('fa-compress-alt');
+        icon.classList.add('fa-expand-alt');
+        localStorage.setItem('chatWindowWidth', 'default');
+    }
+}
+
+// 应用程序启动
+document.addEventListener('DOMContentLoaded', initializeApp);