feat(web): make thinking toggle usable

This commit is contained in:
JOJO 2025-11-18 10:27:23 +08:00
parent f7ce0559b7
commit 7ca7bddba4
4 changed files with 82 additions and 18 deletions

View File

@ -252,7 +252,10 @@ class WebTerminal(MainTerminal):
# 构建状态信息 # 构建状态信息
status = { status = {
"project_path": self.project_path, "project_path": self.project_path,
"thinking_mode": self.thinking_mode, "thinking_mode": {
"enabled": self.thinking_mode,
"label": self.get_thinking_mode_status()
},
"thinking_status": self.get_thinking_mode_status(), "thinking_status": self.get_thinking_mode_status(),
"context": { "context": {
"usage_percent": context_status['usage_percent'], "usage_percent": context_status['usage_percent'],

View File

@ -110,8 +110,7 @@ async function bootstrapApp() {
// 系统信息 // 系统信息
projectPath: '', projectPath: '',
agentVersion: '', agentVersion: '',
thinkingMode: '未知', thinkingMode: true, // true=思考模式, false=快速模式
nextThinkingMode: null,
// 消息相关 // 消息相关
messages: [], messages: [],
@ -593,8 +592,11 @@ async function bootstrapApp() {
this.socket.on('system_ready', (data) => { this.socket.on('system_ready', (data) => {
this.projectPath = data.project_path || ''; this.projectPath = data.project_path || '';
this.agentVersion = data.version || this.agentVersion; this.agentVersion = data.version || this.agentVersion;
this.thinkingMode = data.thinking_mode || '未知'; if (typeof data.thinking_mode === 'object') {
this.nextThinkingMode = null; this.thinkingMode = !!data.thinking_mode.enabled;
} else {
this.thinkingMode = data.thinking_mode === '思考模式';
}
console.log('系统就绪:', data); console.log('系统就绪:', data);
// 系统就绪后立即加载对话列表 // 系统就绪后立即加载对话列表
@ -1291,6 +1293,7 @@ async function bootstrapApp() {
this.toolMenuOpen = false; this.toolMenuOpen = false;
this.toolSettingsLoading = false; this.toolSettingsLoading = false;
this.toolSettings = []; this.toolSettings = [];
this.thinkingMode = false;
console.log('前端状态重置完成'); console.log('前端状态重置完成');
}, },
@ -1324,11 +1327,9 @@ async function bootstrapApp() {
this.projectPath = statusData.project_path || ''; this.projectPath = statusData.project_path || '';
this.agentVersion = statusData.version || this.agentVersion; this.agentVersion = statusData.version || this.agentVersion;
if (statusData.thinking_mode) { if (statusData.thinking_mode) {
this.thinkingMode = statusData.thinking_mode.label || '未知'; this.thinkingMode = !!statusData.thinking_mode.enabled;
this.nextThinkingMode = statusData.thinking_mode.next ?? null;
} else { } else {
this.thinkingMode = '未知'; this.thinkingMode = false;
this.nextThinkingMode = null;
} }
// 获取当前对话信息 // 获取当前对话信息
@ -1862,7 +1863,7 @@ async function bootstrapApp() {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({
thinking_mode: this.thinkingMode !== '快速模式' thinking_mode: this.thinkingMode
}) })
}); });
@ -1988,6 +1989,31 @@ async function bootstrapApp() {
this.sidebarCollapsed = !this.sidebarCollapsed; this.sidebarCollapsed = !this.sidebarCollapsed;
}, },
async toggleThinkingMode() {
try {
const resp = await fetch('/api/thinking-mode', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ thinking_mode: !this.thinkingMode })
});
const data = await resp.json();
if (data.success && data.data) {
if (typeof data.data === 'object') {
this.thinkingMode = !!data.data.enabled;
} else {
this.thinkingMode = data.data === '思考模式';
}
} else {
throw new Error(data.message || data.error || '切换失败');
}
} catch (error) {
console.error('切换思考模式失败:', error);
alert(`切换思考模式失败: ${error.message}`);
}
},
formatTime(timeString) { formatTime(timeString) {
if (!timeString) return ''; if (!timeString) return '';

View File

@ -45,7 +45,7 @@
<span class="agent-version" v-if="agentVersion">{{ agentVersion }}</span> <span class="agent-version" v-if="agentVersion">{{ agentVersion }}</span>
</div> </div>
<div class="header-right"> <div class="header-right">
<span class="thinking-mode">{{ thinkingMode }}</span> <span class="thinking-mode">{{ thinkingMode ? '思考模式' : '快速模式' }}</span>
<span class="connection-status" :class="{ connected: isConnected }"> <span class="connection-status" :class="{ connected: isConnected }">
<span class="status-dot" :class="{ active: isConnected }"></span> <span class="status-dot" :class="{ active: isConnected }"></span>
{{ isConnected ? '已连接' : '未连接' }} {{ isConnected ? '已连接' : '未连接' }}
@ -534,18 +534,18 @@
:disabled="streamingMessage || !isConnected"> :disabled="streamingMessage || !isConnected">
{{ rightCollapsed ? '展开聚焦面板' : '折叠聚焦面板' }} {{ rightCollapsed ? '展开聚焦面板' : '折叠聚焦面板' }}
</button> </button>
<button type="button"
class="menu-btn mode-entry"
@click="toggleThinkingMode"
:disabled="streamingMessage || !isConnected">
{{ thinkingMode ? '当前:思考模式(点此切换为快速模式)' : '当前:快速模式(点此切换为思考模式)' }}
</button>
<button type="button" <button type="button"
class="menu-btn compress-entry" class="menu-btn compress-entry"
@click="compressConversation" @click="compressConversation"
:disabled="compressing || streamingMessage || !isConnected"> :disabled="compressing || streamingMessage || !isConnected">
{{ compressing ? '压缩中...' : '压缩' }} {{ compressing ? '压缩中...' : '压缩' }}
</button> </button>
<button type="button"
class="menu-btn mode-entry"
@click="toggleNextThinkingMode"
:disabled="streamingMessage || !isConnected">
{{ nextThinkingMode ? '下一次: 思考模式' : '下一次: 快速模式' }}
</button>
</div> </div>
</transition> </transition>
</div> </div>

View File

@ -69,6 +69,13 @@ stop_flags: Dict[str, Dict[str, Any]] = {}
DEFAULT_PORT = 8091 DEFAULT_PORT = 8091
def serialize_thinking_mode(terminal: WebTerminal) -> Dict[str, Any]:
"""构造思考模式状态payload包含是否启用与显示标签。"""
return {
"enabled": bool(getattr(terminal, "thinking_mode", False)),
"label": terminal.get_thinking_mode_status() if hasattr(terminal, "get_thinking_mode_status") else ("思考模式" if getattr(terminal, "thinking_mode", False) else "快速模式")
}
def format_read_file_result(result_data: Dict) -> str: def format_read_file_result(result_data: Dict) -> str:
"""格式化 read_file 工具的输出便于在Web端展示。""" """格式化 read_file 工具的输出便于在Web端展示。"""
if not isinstance(result_data, dict): if not isinstance(result_data, dict):
@ -497,6 +504,34 @@ def get_status(terminal: WebTerminal, workspace: UserWorkspace, username: str):
status['version'] = AGENT_VERSION status['version'] = AGENT_VERSION
return jsonify(status) return jsonify(status)
@app.route('/api/thinking-mode', methods=['POST'])
@api_login_required
@with_terminal
def update_thinking_mode(terminal: WebTerminal, workspace: UserWorkspace, username: str):
"""切换思考模式"""
try:
data = request.get_json() or {}
desired_mode = bool(data.get('thinking_mode'))
terminal.thinking_mode = desired_mode
terminal.api_client.thinking_mode = desired_mode
terminal.api_client.start_new_task()
session['thinking_mode'] = desired_mode
status = terminal.get_status()
socketio.emit('status_update', status, room=f"user_{username}")
return jsonify({
"success": True,
"data": status.get("thinking_mode")
})
except Exception as exc:
print(f"[API] 切换思考模式失败: {exc}")
return jsonify({
"success": False,
"error": str(exc),
"message": "切换思考模式时发生异常"
}), 500
@app.route('/api/files') @app.route('/api/files')
@api_login_required @api_login_required
@with_terminal @with_terminal
@ -1053,7 +1088,7 @@ def handle_connect():
reset_system_state(terminal) reset_system_state(terminal)
emit('system_ready', { emit('system_ready', {
'project_path': str(workspace.project_path), 'project_path': str(workspace.project_path),
'thinking_mode': terminal.get_thinking_mode_status(), 'thinking_mode': serialize_thinking_mode(terminal),
'version': AGENT_VERSION 'version': AGENT_VERSION
}, room=request.sid) }, room=request.sid)