feat: 智能体管理增加上线开关、标签、可使用工具
智能体新增功能: - 上线开关(is_online):点击快速切换,未上线则APP不可见 - 标签(tags):支持多标签,逗号分隔(hot/popular/new等) - 可使用工具(enable_tools):配置智能体可用的工具列表 类别调整: - 热门改为标签,不再是类别 - 类别改为: basic/work/study/life - hot=热门标签, popular=推荐标签, new=新品标签 数据库变更: - agents表新增 is_online 字段 - agents表新增 enable_tools 字段 - 移除 enable_search 字段(改为工具) API新增: - /api/admin/agents/<id>/online 切换上线状态 - 前端配置只返回上线且活跃的智能体
This commit is contained in:
120
www/admin.js
120
www/admin.js
@@ -361,14 +361,22 @@ async function deleteLLM(id) {
|
||||
async function loadAgentsPage(content) {
|
||||
agents = await fetchAPI('/api/admin/agents');
|
||||
llmConfigs = await fetchAPI('/api/admin/llm');
|
||||
toolConfigs = await fetchAPI('/api/admin/tools');
|
||||
|
||||
const categories = {
|
||||
hot: '热门',
|
||||
basic: '基础',
|
||||
work: '工作',
|
||||
study: '学习',
|
||||
life: '生活'
|
||||
};
|
||||
|
||||
const tagLabels = {
|
||||
'hot': '🔥 热门',
|
||||
'popular': '👍 推荐',
|
||||
'new': '🆕 新品',
|
||||
'': ''
|
||||
};
|
||||
|
||||
content.innerHTML = `
|
||||
<div class="content-header">
|
||||
<h1 class="content-title">智能体管理</h1>
|
||||
@@ -382,9 +390,9 @@ async function loadAgentsPage(content) {
|
||||
<th>头像</th>
|
||||
<th>名称</th>
|
||||
<th>类别</th>
|
||||
<th>描述</th>
|
||||
<th>标签</th>
|
||||
<th>热度</th>
|
||||
<th>状态</th>
|
||||
<th>上线状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -394,9 +402,13 @@ async function loadAgentsPage(content) {
|
||||
<td style="font-size: 24px;">${a.avatar}</td>
|
||||
<td>${a.name}</td>
|
||||
<td>${categories[a.category] || a.category}</td>
|
||||
<td style="max-width: 200px; overflow: hidden; text-overflow: ellipsis;">${a.description || '-'}</td>
|
||||
<td>${a.tags ? a.tags.split(',').map(t => tagLabels[t] || t).filter(t => t).join(' ') : '-'}</td>
|
||||
<td>${a.heat || 0}</td>
|
||||
<td>${a.is_active ? '✅ 启用' : '❌ 禁用'}</td>
|
||||
<td>
|
||||
<span style="cursor: pointer; color: ${a.is_online ? '#22c55e' : '#e53e3e'};" onclick="toggleAgentOnline('${a.agent_id}', ${a.is_online})">
|
||||
${a.is_online ? '✅ 已上线' : '❌ 未上线'}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="action-btns">
|
||||
<button class="action-btn edit" onclick="showEditAgentModal('${a.agent_id}')">编辑</button>
|
||||
@@ -408,9 +420,34 @@ async function loadAgentsPage(content) {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 24px; padding: 16px; background: white; border-radius: 12px;">
|
||||
<h3 style="margin-bottom: 16px;">说明</h3>
|
||||
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;">
|
||||
<div style="padding: 12px; background: #f5f7fa; border-radius: 8px;">
|
||||
<strong>上线状态</strong>
|
||||
<p style="color: #718096; font-size: 12px; margin-top: 4px;">点击可快速切换,未上线则APP不可见</p>
|
||||
</div>
|
||||
<div style="padding: 12px; background: #f5f7fa; border-radius: 8px;">
|
||||
<strong>标签</strong>
|
||||
<p style="color: #718096; font-size: 12px; margin-top: 4px;">hot=热门, popular=推荐, new=新品</p>
|
||||
</div>
|
||||
<div style="padding: 12px; background: #f5f7fa; border-radius: 8px;">
|
||||
<strong>类别</strong>
|
||||
<p style="color: #718096; font-size: 12px; margin-top: 4px;">basic/work/study/life</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
async function toggleAgentOnline(agentId, currentStatus) {
|
||||
const newStatus = currentStatus ? 0 : 1;
|
||||
await fetchAPI(`/api/admin/agents/${agentId}/online`, 'POST', { is_online: newStatus });
|
||||
showToast(newStatus ? '已上线' : '已下线');
|
||||
loadPage('agents');
|
||||
}
|
||||
|
||||
function showAddAgentModal() {
|
||||
showModal('添加智能体', `
|
||||
<div class="form-group">
|
||||
@@ -432,12 +469,51 @@ function showAddAgentModal() {
|
||||
<div class="form-group">
|
||||
<label class="form-label">类别</label>
|
||||
<select class="form-select" id="agentCategory">
|
||||
<option value="hot">热门</option>
|
||||
<option value="basic">基础</option>
|
||||
<option value="work">工作</option>
|
||||
<option value="study">学习</option>
|
||||
<option value="life">生活</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">标签(逗号分隔)</label>
|
||||
<input type="text" class="form-input" id="agentTags" placeholder="如:hot,popular">
|
||||
<span style="color: #999; font-size: 12px;">可选: hot(热门), popular(推荐), new(新品)</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">描述</label>
|
||||
<input type="text" class="form-input" id="agentDescription" placeholder="智能体描述">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">System Prompt</label>
|
||||
<textarea class="form-textarea" id="agentPrompt" placeholder="系统提示词"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">LLM配置(可选)</label>
|
||||
<select class="form-select" id="agentLLM">
|
||||
<option value="">使用默认</option>
|
||||
${llmConfigs.map(c => `<option value="${c.id}">${c.name}</option>`).join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">可使用工具(逗号分隔)</label>
|
||||
<input type="text" class="form-input" id="agentEnableTools" placeholder="如:search,calculator">
|
||||
<span style="color: #999; font-size: 12px;">已配置工具: ${toolConfigs.map(t => t.tool_id).join(', ')}</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">热度</label>
|
||||
<input type="number" class="form-input" id="agentHeat" value="0">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label style="display: flex; align-items: center; gap: 8px;">
|
||||
<input type="checkbox" id="agentIsOnline" checked> 立即上线
|
||||
</label>
|
||||
</div>
|
||||
<button class="form-submit" onclick="saveAgent()">保存</button>
|
||||
`);
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">描述</label>
|
||||
<input type="text" class="form-input" id="agentDescription" placeholder="智能体描述">
|
||||
@@ -494,12 +570,17 @@ function showEditAgentModal(agentId) {
|
||||
<div class="form-group">
|
||||
<label class="form-label">类别</label>
|
||||
<select class="form-select" id="agentCategory">
|
||||
<option value="hot" ${agent.category === 'hot' ? 'selected' : ''}>热门</option>
|
||||
<option value="basic" ${agent.category === 'basic' ? 'selected' : ''}>基础</option>
|
||||
<option value="work" ${agent.category === 'work' ? 'selected' : ''}>工作</option>
|
||||
<option value="study" ${agent.category === 'study' ? 'selected' : ''}>学习</option>
|
||||
<option value="life" ${agent.category === 'life' ? 'selected' : ''}>生活</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">标签(逗号分隔)</label>
|
||||
<input type="text" class="form-input" id="agentTags" value="${agent.tags || ''}">
|
||||
<span style="color: #999; font-size: 12px;">可选: hot(热门), popular(推荐), new(新品)</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">描述</label>
|
||||
<input type="text" class="form-input" id="agentDescription" value="${agent.description || ''}">
|
||||
@@ -509,23 +590,24 @@ function showEditAgentModal(agentId) {
|
||||
<textarea class="form-textarea" id="agentPrompt">${agent.system_prompt || ''}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">LLM配置</label>
|
||||
<label class="form-label">LLM配置(可选)</label>
|
||||
<select class="form-select" id="agentLLM">
|
||||
<option value="">使用默认</option>
|
||||
<option value="" ${!agent.llm_config_id ? 'selected' : ''}>使用默认</option>
|
||||
${llmConfigs.map(c => `<option value="${c.id}" ${c.id === agent.llm_config_id ? 'selected' : ''}>${c.name}</option>`).join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">可使用工具(逗号分隔)</label>
|
||||
<input type="text" class="form-input" id="agentEnableTools" value="${agent.enable_tools || ''}">
|
||||
<span style="color: #999; font-size: 12px;">已配置工具: ${toolConfigs.map(t => t.tool_id).join(', ')}</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">热度</label>
|
||||
<input type="number" class="form-input" id="agentHeat" value="${agent.heat || 0}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">标签</label>
|
||||
<input type="text" class="form-input" id="agentTags" value="${agent.tags || ''}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label style="display: flex; align-items: center; gap: 8px;">
|
||||
<input type="checkbox" id="agentEnableSearch" ${agent.enable_search ? 'checked' : ''}> 启用联网搜索
|
||||
<input type="checkbox" id="agentIsOnline" ${agent.is_online ? 'checked' : ''}> 已上线
|
||||
</label>
|
||||
</div>
|
||||
<button class="form-submit" onclick="updateAgent('${agentId}')">保存</button>
|
||||
@@ -538,12 +620,13 @@ async function saveAgent() {
|
||||
name: document.getElementById('agentName').value,
|
||||
avatar: document.getElementById('agentAvatar').value,
|
||||
category: document.getElementById('agentCategory').value,
|
||||
tags: document.getElementById('agentTags').value,
|
||||
description: document.getElementById('agentDescription').value,
|
||||
system_prompt: document.getElementById('agentPrompt').value,
|
||||
llm_config_id: document.getElementById('agentLLM').value || null,
|
||||
enable_tools: document.getElementById('agentEnableTools').value,
|
||||
heat: parseInt(document.getElementById('agentHeat').value),
|
||||
tags: document.getElementById('agentTags').value,
|
||||
enable_search: document.getElementById('agentEnableSearch').checked ? 1 : 0
|
||||
is_online: document.getElementById('agentIsOnline').checked ? 1 : 0
|
||||
};
|
||||
|
||||
if (!data.agent_id || !data.name || !data.system_prompt) {
|
||||
@@ -562,12 +645,13 @@ async function updateAgent(agentId) {
|
||||
name: document.getElementById('agentName').value,
|
||||
avatar: document.getElementById('agentAvatar').value,
|
||||
category: document.getElementById('agentCategory').value,
|
||||
tags: document.getElementById('agentTags').value,
|
||||
description: document.getElementById('agentDescription').value,
|
||||
system_prompt: document.getElementById('agentPrompt').value,
|
||||
llm_config_id: document.getElementById('agentLLM').value || null,
|
||||
enable_tools: document.getElementById('agentEnableTools').value,
|
||||
heat: parseInt(document.getElementById('agentHeat').value),
|
||||
tags: document.getElementById('agentTags').value,
|
||||
enable_search: document.getElementById('agentEnableSearch').checked ? 1 : 0
|
||||
is_online: document.getElementById('agentIsOnline').checked ? 1 : 0
|
||||
};
|
||||
|
||||
await fetchAPI(`/api/admin/agents/${agentId}`, 'PUT', data);
|
||||
|
||||
Reference in New Issue
Block a user