feat: AI 控制台升级为顶级 Tab——DeepSeek 风格聊天界面(气泡+流式渲染+思考折叠),实时 MCP 步骤卡片(工具/参数/截图缩略),SSE 流式输出(delta/step/done/error 事件),配置模态(模型/Key/设备前端可配);工具页旧子栏移除
This commit is contained in:
@@ -41,89 +41,6 @@ async function loadToolsDevices(force){
|
||||
status.textContent = '共 '+_clipDevices.length+' 台设备';
|
||||
}
|
||||
|
||||
// ================== AI 控制台(模型配置 + 指令执行 + 进度轮询) ==================
|
||||
let _agentPoll = null;
|
||||
|
||||
function loadAgentConfig(){
|
||||
apiGet('/api/agent/config').then(r=>{
|
||||
if(!r||!r.ok)return;
|
||||
const b=document.getElementById('agent-api-base');
|
||||
if(!b)return; // 面板未渲染
|
||||
b.value=r.api_base||'https://api.deepseek.com';
|
||||
document.getElementById('agent-model').value=r.model||'';
|
||||
document.getElementById('agent-default-serial').value=r.default_serial||'';
|
||||
const hint=document.getElementById('agent-key-hint');
|
||||
hint.textContent=r.api_key_masked?('已配置 '+r.api_key_masked):'未配置 Key';
|
||||
});
|
||||
}
|
||||
function saveAgentConfig(){
|
||||
const body={api_base:document.getElementById('agent-api-base').value.trim(),
|
||||
model:document.getElementById('agent-model').value.trim(),
|
||||
default_serial:document.getElementById('agent-default-serial').value.trim()};
|
||||
const key=document.getElementById('agent-api-key').value.trim();
|
||||
if(key)body.api_key=key;
|
||||
apiPost('/api/agent/config',body).then(r=>{
|
||||
if(r&&r.ok){showToast('配置已保存','success');loadAgentConfig();}
|
||||
else showToast('保存失败: '+((r&&r.error)||''),'error');
|
||||
});
|
||||
}
|
||||
function runAgent(){
|
||||
const prompt=document.getElementById('agent-prompt').value.trim();
|
||||
if(!prompt){showToast('请输入指令','error');return;}
|
||||
apiPost('/api/agent/run',{prompt}).then(r=>{
|
||||
if(r&&r.ok){
|
||||
showToast('Agent 已启动','success');
|
||||
document.getElementById('agent-status').textContent='运行中...';
|
||||
document.getElementById('btn-agent-run').disabled=true;
|
||||
document.getElementById('agent-answer-wrap').style.display='none';
|
||||
startAgentPoll();
|
||||
}else showToast('启动失败: '+((r&&r.error)||''),'error');
|
||||
});
|
||||
}
|
||||
function startAgentPoll(){
|
||||
if(_agentPoll)clearInterval(_agentPoll);
|
||||
_agentPoll=setInterval(pollAgent,2000);
|
||||
pollAgent();
|
||||
}
|
||||
function stopAgentPoll(){
|
||||
if(_agentPoll){clearInterval(_agentPoll);_agentPoll=null;}
|
||||
}
|
||||
function pollAgent(){
|
||||
apiGet('/api/agent/status').then(r=>{
|
||||
if(!r||!r.ok)return;
|
||||
const st=document.getElementById('agent-status');
|
||||
if(r.state==='running'){
|
||||
st.textContent='运行中... ('+(r.steps||[]).length+' 步)';
|
||||
}else{
|
||||
st.textContent=r.state==='done'?'完成':'失败';
|
||||
document.getElementById('btn-agent-run').disabled=false;
|
||||
stopAgentPoll();
|
||||
}
|
||||
// 步骤流(含截图缩略)
|
||||
const steps=document.getElementById('agent-steps');
|
||||
const html=(r.steps||[]).map(s=>{
|
||||
const args=esc(s.args||'');
|
||||
const img=s.image
|
||||
?'<img src="data:image/jpeg;base64,'+s.image+'" style="max-width:120px;border-radius:6px;margin-top:4px;display:block">':'';
|
||||
return '<div style="padding:6px 0;border-bottom:1px solid var(--ink-line)">'
|
||||
+'<code style="color:var(--teal)">'+esc(s.tool||'')+'</code> '
|
||||
+'<span class="text-muted">'+args+'</span>'+img+'</div>';
|
||||
}).join('')||'';
|
||||
steps.innerHTML=html;
|
||||
// 最终回答
|
||||
if(r.answer){
|
||||
const wrap=document.getElementById('agent-answer-wrap');
|
||||
wrap.style.display='block';
|
||||
document.getElementById('agent-answer').textContent=r.answer;
|
||||
}
|
||||
if(r.error){
|
||||
st.textContent='错误: '+r.error;
|
||||
document.getElementById('btn-agent-run').disabled=false;
|
||||
stopAgentPoll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ================== 设备自动发现(扫描 → 待连接池 → 确认) ==================
|
||||
function loadDiscovery(){
|
||||
apiGet('/api/devices/discovery').then(r=>{
|
||||
|
||||
Reference in New Issue
Block a user