feat: 前端根据LLM能力显示/隐藏功能按钮

- llmCapabilities 存储思考模式和视觉能力状态
- loadBackendConfig 从后台API加载LLM能力配置
- 智能体对话界面根据能力条件渲染深度思考按钮
- 普通对话界面根据能力条件渲染深度思考按钮
- 上传图片选项根据视觉能力条件显示/隐藏
- 输入框placeholder根据视觉能力动态变化
- handleImageUpload 检查视觉能力,不支持时提示用户等待升级
This commit is contained in:
2026-04-29 11:52:00 +08:00
parent 00d074efca
commit d38cbea01a

View File

@@ -116,6 +116,13 @@ async function loadBackendConfig() {
}; };
} }
// 加载LLM能力配置思考模式、视觉能力
if (backendConfig.llm) {
llmCapabilities.thinking = backendConfig.llm.enable_thinking === 1;
llmCapabilities.vision = backendConfig.llm.enable_vision === 1;
console.log('LLM能力: 思考模式=', llmCapabilities.thinking, '视觉=', llmCapabilities.vision);
}
updateAgentsDisplay(); updateAgentsDisplay();
console.log('后台配置已加载', backendConfig); console.log('后台配置已加载', backendConfig);
} catch (e) { } catch (e) {
@@ -283,6 +290,12 @@ let enableThinking = false; // 深度思考
let enableSearch = false; // 联网搜索 let enableSearch = false; // 联网搜索
let autoScrollEnabled = true; // 自动滚动(用户滚动后可关闭) let autoScrollEnabled = true; // 自动滚动(用户滚动后可关闭)
// LLM 能力标志(从后台配置加载)
let llmCapabilities = {
thinking: false, // 是否支持思考模式
vision: false // 是否支持视觉能力
};
// DOM 元素(初始为 null在 openConversation 时重新获取) // DOM 元素(初始为 null在 openConversation 时重新获取)
let appContainer = null; let appContainer = null;
let messagesContainer = null; let messagesContainer = null;
@@ -2917,10 +2930,12 @@ function showAgentChatPage() {
<!-- 功能开关栏 --> <!-- 功能开关栏 -->
<div class="feature-bar" id="featureBar"> <div class="feature-bar" id="featureBar">
<div class="feature-left"> <div class="feature-left">
${llmCapabilities.thinking ? `
<button class="feature-btn thinking-btn" id="thinkingBtn"> <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> <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> <span>深度思考</span>
</button> </button>
` : ''}
<button class="feature-btn search-btn" id="searchBtn"> <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> <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> <span>联网搜索</span>
@@ -2940,7 +2955,7 @@ function showAgentChatPage() {
<button class="attach-btn" id="attachBtn" title="上传文件"> <button class="attach-btn" id="attachBtn" title="上传文件">
<svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg> <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
</button> </button>
<textarea id="userInput" placeholder="输入消息..." rows="1"></textarea> <textarea id="userInput" placeholder="${llmCapabilities.vision ? '输入消息或上传图片...' : '输入消息...'}" rows="1"></textarea>
<button class="send-btn" id="sendBtn"> <button class="send-btn" id="sendBtn">
<svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg> <svg viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
</button> </button>
@@ -2949,10 +2964,12 @@ function showAgentChatPage() {
<!-- 上传选项弹窗 --> <!-- 上传选项弹窗 -->
<div class="attach-panel" id="attachPanel"> <div class="attach-panel" id="attachPanel">
<div class="attach-panel-content"> <div class="attach-panel-content">
${llmCapabilities.vision ? `
<div class="attach-item" data-type="image"> <div class="attach-item" data-type="image">
<div class="attach-icon">📷</div> <div class="attach-icon">📷</div>
<div class="attach-label">上传图片</div> <div class="attach-label">上传图片</div>
</div> </div>
` : ''}
<div class="attach-item" data-type="file"> <div class="attach-item" data-type="file">
<div class="attach-icon">📄</div> <div class="attach-icon">📄</div>
<div class="attach-label">上传文件</div> <div class="attach-label">上传文件</div>
@@ -3385,10 +3402,12 @@ function openConversation(id) {
<!-- 功能开关栏 --> <!-- 功能开关栏 -->
<div class="feature-bar"> <div class="feature-bar">
<div class="feature-left"> <div class="feature-left">
${llmCapabilities.thinking ? `
<button class="feature-btn thinking-btn ${enableThinking ? 'active' : ''}" id="thinkingBtn"> <button class="feature-btn thinking-btn ${enableThinking ? 'active' : ''}" 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> <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> <span>深度思考</span>
</button> </button>
` : ''}
<button class="feature-btn search-btn ${enableSearch ? 'active' : ''}" id="searchBtn"> <button class="feature-btn search-btn ${enableSearch ? 'active' : ''}" 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> <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> <span>联网搜索</span>
@@ -3410,7 +3429,7 @@ function openConversation(id) {
</button> </button>
<textarea <textarea
id="userInput" id="userInput"
placeholder="输入消息..." placeholder="${llmCapabilities.vision ? '输入消息或上传图片...' : '输入消息...'}"
rows="1" rows="1"
></textarea> ></textarea>
<button class="send-btn" id="sendBtn"> <button class="send-btn" id="sendBtn">
@@ -3421,10 +3440,12 @@ function openConversation(id) {
<!-- 上传选项弹窗 --> <!-- 上传选项弹窗 -->
<div class="attach-panel" id="attachPanel"> <div class="attach-panel" id="attachPanel">
<div class="attach-panel-content"> <div class="attach-panel-content">
${llmCapabilities.vision ? `
<div class="attach-item" data-type="image"> <div class="attach-item" data-type="image">
<div class="attach-icon">📷</div> <div class="attach-icon">📷</div>
<div class="attach-label">上传图片</div> <div class="attach-label">上传图片</div>
</div> </div>
` : ''}
<div class="attach-item" data-type="file"> <div class="attach-item" data-type="file">
<div class="attach-icon">📄</div> <div class="attach-icon">📄</div>
<div class="attach-label">上传文件</div> <div class="attach-label">上传文件</div>
@@ -4286,6 +4307,13 @@ async function handleImageUpload(e) {
const file = e.target.files[0]; const file = e.target.files[0];
if (!file) return; if (!file) return;
// 检查是否支持视觉能力
if (!llmCapabilities.vision) {
showToast('当前大模型不支持图片分析功能,请等待后期升级');
e.target.value = '';
return;
}
// 读取图片为base64 // 读取图片为base64
const reader = new FileReader(); const reader = new FileReader();
reader.onload = async (event) => { reader.onload = async (event) => {