Compare commits

...

8 Commits

2 changed files with 104 additions and 27 deletions

View File

@@ -118,12 +118,23 @@ async function loadBackendConfig() {
// 加载工具列表 // 加载工具列表
if (backendConfig.allTools) { if (backendConfig.allTools) {
allTools = backendConfig.allTools; // 过滤掉联网搜索(已有单独按钮)
allTools = backendConfig.allTools.filter(t => t.type !== 'search');
} }
// 加载默认启用的工具 // 加载默认启用的工具,所有工具默认未启用
if (backendConfig.tools) {
enabledTools = backendConfig.tools.map(t => t.tool_id); // 将后台系统配置赋值到 CONFIG
if (backendConfig.system) {
CONFIG.system = backendConfig.system;
}
// 将后台 LLM 配置赋值到 CONFIG
if (backendConfig.llm) {
CONFIG.apiUrl = backendConfig.llm.api_url;
CONFIG.apiKey = backendConfig.llm.api_key;
CONFIG.model = backendConfig.llm.model;
CONFIG.maxTokens = backendConfig.llm.max_tokens || 2048;
} }
updateAgentsDisplay(); updateAgentsDisplay();
@@ -791,7 +802,7 @@ function renderAgentsPage() {
<div class="recent-agent-item" data-conv-id="${conv.id}"> <div class="recent-agent-item" data-conv-id="${conv.id}">
<div class="recent-agent-left"> <div class="recent-agent-left">
<span class="recent-agent-avatar">${conv.agent ? conv.agent.avatar : '🤖'}</span> <span class="recent-agent-avatar">${conv.agent ? conv.agent.avatar : '🤖'}</span>
<span class="recent-agent-name">${conv.title}</span> <span class="recent-agent-title">${conv.title}</span>
</div> </div>
<div class="recent-agent-right"> <div class="recent-agent-right">
<span class="recent-agent-agent-name">${conv.agent ? conv.agent.name : '未知智能体'}</span> <span class="recent-agent-agent-name">${conv.agent ? conv.agent.name : '未知智能体'}</span>
@@ -1326,6 +1337,7 @@ function filterDiscoverAgents(keyword) {
if (!keyword) { if (!keyword) {
// 显示所有 // 显示所有
showDiscoverSection('hot', systemAgents.filter(a => a.category === 'hot')); showDiscoverSection('hot', systemAgents.filter(a => a.category === 'hot'));
showDiscoverSection('basic', systemAgents.filter(a => a.category === 'basic'));
showDiscoverSection('work', systemAgents.filter(a => a.category === 'work')); showDiscoverSection('work', systemAgents.filter(a => a.category === 'work'));
showDiscoverSection('study', systemAgents.filter(a => a.category === 'study')); showDiscoverSection('study', systemAgents.filter(a => a.category === 'study'));
showDiscoverSection('life', systemAgents.filter(a => a.category === 'life')); showDiscoverSection('life', systemAgents.filter(a => a.category === 'life'));
@@ -1340,6 +1352,7 @@ function filterDiscoverAgents(keyword) {
// 显示搜索结果 // 显示搜索结果
showDiscoverSection('hot', filtered.filter(a => a.category === 'hot')); showDiscoverSection('hot', filtered.filter(a => a.category === 'hot'));
showDiscoverSection('basic', filtered.filter(a => a.category === 'basic'));
showDiscoverSection('work', filtered.filter(a => a.category === 'work')); showDiscoverSection('work', filtered.filter(a => a.category === 'work'));
showDiscoverSection('study', filtered.filter(a => a.category === 'study')); showDiscoverSection('study', filtered.filter(a => a.category === 'study'));
showDiscoverSection('life', filtered.filter(a => a.category === 'life')); showDiscoverSection('life', filtered.filter(a => a.category === 'life'));
@@ -2613,7 +2626,12 @@ function showAboutPage() {
const privacyPolicyBtn = document.getElementById('privacyPolicyBtn'); const privacyPolicyBtn = document.getElementById('privacyPolicyBtn');
if (privacyPolicyBtn) { if (privacyPolicyBtn) {
privacyPolicyBtn.addEventListener('click', () => { privacyPolicyBtn.addEventListener('click', () => {
showToast('隐私政策页面待完善'); const privacyUrl = CONFIG?.system?.privacyPolicyUrl;
if (privacyUrl) {
window.open(privacyUrl, '_blank');
} else {
showToast('隐私政策链接未配置');
}
}); });
} }
@@ -2621,7 +2639,12 @@ function showAboutPage() {
const userAgreementBtn = document.getElementById('userAgreementBtn'); const userAgreementBtn = document.getElementById('userAgreementBtn');
if (userAgreementBtn) { if (userAgreementBtn) {
userAgreementBtn.addEventListener('click', () => { userAgreementBtn.addEventListener('click', () => {
showToast('用户协议页面待完善'); const agreementUrl = CONFIG?.system?.userAgreementUrl;
if (agreementUrl) {
window.open(agreementUrl, '_blank');
} else {
showToast('用户协议链接未配置');
}
}); });
} }
} }
@@ -3005,10 +3028,10 @@ function showAgentHistoryPage() {
<div class="agent-history-item" data-conv-id="${conv.id}"> <div class="agent-history-item" data-conv-id="${conv.id}">
<div class="agent-history-left"> <div class="agent-history-left">
<span class="agent-history-avatar">${conv.agent ? conv.agent.avatar : '🤖'}</span> <span class="agent-history-avatar">${conv.agent ? conv.agent.avatar : '🤖'}</span>
<span class="agent-history-name">${conv.title}</span> <span class="agent-history-title">${conv.title}</span>
</div> </div>
<div class="agent-history-right"> <div class="agent-history-right">
<span class="agent-history-agent">${conv.agent ? conv.agent.name : '未知智能体'}</span> <span class="agent-history-agent-name">${conv.agent ? conv.agent.name : '未知智能体'}</span>
<span class="agent-history-time">${formatTime(conv.updatedAt)}</span> <span class="agent-history-time">${formatTime(conv.updatedAt)}</span>
</div> </div>
</div> </div>
@@ -3044,6 +3067,9 @@ async function openAgent(agentId) {
currentAgent = systemAgents.find(a => a.id === agentId); currentAgent = systemAgents.find(a => a.id === agentId);
if (!currentAgent) return; if (!currentAgent) return;
// 加载该智能体的工具选择状态
loadToolsState();
// 检查未登录用户的智能体限制 // 检查未登录用户的智能体限制
if (!currentUser) { if (!currentUser) {
const check = canUseAgent(agentId); const check = canUseAgent(agentId);
@@ -3086,7 +3112,7 @@ async function openAgent(agentId) {
// 创建新对话并设置智能体 // 创建新对话并设置智能体
const newConv = { const newConv = {
id: backendId || Date.now().toString(), id: backendId || Date.now().toString(),
title: currentAgent.name, title: '新对话', // 和普通对话一样,初始标题为"新对话",后续自动生成
messages: [], messages: [],
agentId: agentId, agentId: agentId,
createdAt: Date.now(), createdAt: Date.now(),
@@ -3130,22 +3156,10 @@ function showAgentChatPage() {
<div class="messages" id="messages"></div> <div class="messages" id="messages"></div>
</div> </div>
<!-- 功能开关栏 --> <!-- 功能栏(智能体对话不需要工具选择,工具由后台配置) -->
<div class="feature-bar" id="featureBar"> <div class="feature-bar" id="featureBar">
<div class="feature-left"> <div class="feature-left">
<button class="feature-btn thinking-btn" id="thinkingBtn"> <!-- 智能体工具由后台配置,不显示选择按钮 -->
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>
<span>深度思考</span>
</button>
<button class="feature-btn search-btn" id="searchBtn">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 7 9.5 7 14 9.01 14 9.5 11.99 14 9.5 14z"/></svg>
<span>联网搜索</span>
</button>
<button class="feature-btn tools-btn" id="moreToolsBtn">
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"/></svg>
<span>更多工具</span>
${enabledTools.length > 0 ? `<span class="tools-count">${enabledTools.length}</span>` : ''}
</button>
</div> </div>
<div class="feature-right"> <div class="feature-right">
<button class="feature-btn nav-btn" id="scrollTopBtn"> <button class="feature-btn nav-btn" id="scrollTopBtn">
@@ -3599,6 +3613,10 @@ function openConversation(id) {
return; return;
} }
// 普通对话,加载普通对话的工具状态
currentAgent = null;
loadToolsState();
// 渲染对话页面 // 渲染对话页面
const chatHtml = ` const chatHtml = `
<div id="chatPage"> <div id="chatPage">
@@ -4232,6 +4250,9 @@ function confirmToolsSelection() {
enabledTools = selectedTools; enabledTools = selectedTools;
// 保存工具选择状态
saveToolsState();
// 更新按钮显示 // 更新按钮显示
const moreToolsBtn = document.getElementById('moreToolsBtn'); const moreToolsBtn = document.getElementById('moreToolsBtn');
if (moreToolsBtn) { if (moreToolsBtn) {
@@ -4254,6 +4275,38 @@ function confirmToolsSelection() {
showToast(`已启用 ${enabledTools.length} 个工具`); showToast(`已启用 ${enabledTools.length} 个工具`);
} }
// 保存工具选择状态
function saveToolsState() {
if (currentAgent) {
// 智能体对话:保存到 localStorage按智能体ID
localStorage.setItem(`agentEnabledTools_${currentAgent.id}`, JSON.stringify(enabledTools));
} else {
// 普通对话:保存到 localStorage
localStorage.setItem('chatEnabledTools', JSON.stringify(enabledTools));
}
}
// 加载工具选择状态
function loadToolsState() {
if (currentAgent) {
// 智能体对话:加载该智能体的工具状态
const saved = localStorage.getItem(`agentEnabledTools_${currentAgent.id}`);
if (saved) {
enabledTools = JSON.parse(saved);
} else {
enabledTools = [];
}
} else {
// 普通对话:加载普通对话的工具状态
const saved = localStorage.getItem('chatEnabledTools');
if (saved) {
enabledTools = JSON.parse(saved);
} else {
enabledTools = [];
}
}
}
// 渲染头像(支持 emoji 和上传的图片) // 渲染头像(支持 emoji 和上传的图片)
function renderAvatar(avatar) { function renderAvatar(avatar) {
if (!avatar) return '👤'; if (!avatar) return '👤';
@@ -4513,7 +4566,11 @@ function renderMessages() {
messagesDiv.innerHTML = currentConversation.messages.map((msg, index) => { messagesDiv.innerHTML = currentConversation.messages.map((msg, index) => {
const isUser = msg.role === 'user'; const isUser = msg.role === 'user';
const avatar = isUser ? '👤' : '🤖'; // 用户头像使用实际头像AI头像使用智能体头像或默认
const avatar = isUser
? (currentUser?.avatar || '👤')
: (currentAgent?.avatar || '🤖');
const avatarHtml = isUser ? renderAvatar(avatar) : avatar;
// 处理消息内容(支持图片) // 处理消息内容(支持图片)
let contentHtml = ''; let contentHtml = '';
@@ -4588,7 +4645,7 @@ function renderMessages() {
return ` return `
<div class="message ${msg.role}" data-index="${index}"> <div class="message ${msg.role}" data-index="${index}">
<div class="message-avatar">${avatar}</div> <div class="message-avatar">${avatarHtml}</div>
<div class="message-body"> <div class="message-body">
${searchHtml} ${searchHtml}
${thinkingHtml} ${thinkingHtml}

View File

@@ -1730,6 +1730,16 @@ body {
color: var(--primary); color: var(--primary);
} }
.recent-agent-title {
font-size: 14px;
color: #333;
font-weight: 500;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.recent-agent-agent-name { .recent-agent-agent-name {
font-size: 12px; font-size: 12px;
color: var(--primary); color: var(--primary);
@@ -1807,7 +1817,17 @@ body {
color: var(--primary); color: var(--primary);
} }
.agent-history-agent { .agent-history-title {
font-size: 14px;
color: #333;
font-weight: 500;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-history-agent-name {
font-size: 12px; font-size: 12px;
color: var(--primary); color: var(--primary);
background: rgba(102, 126, 234, 0.1); background: rgba(102, 126, 234, 0.1);