diff --git a/homepage/index.html b/homepage/index.html
index 1b696b0..0d3f2c0 100644
--- a/homepage/index.html
+++ b/homepage/index.html
@@ -493,9 +493,16 @@ function logout(){
}
})();
-// 重写 sendCardMsg 和 sendMsg 带上用户信息
-async function sendCardMsg(){const i=document.getElementById('card-chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-card-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='
'+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML=''+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
-async function sendMsg(){const i=document.getElementById('chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML=''+m.replace(//g,'>')+'
';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML=''+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
'}catch(e){ld.className='c-msg bot';ld.innerHTML='连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
+// 对话记忆(每用户独立,保留30轮)
+let chatHistory={};
+function getChatHistory(){const u=localStorage.getItem('current_user')||'default';if(!chatHistory[u])chatHistory[u]=[];return chatHistory[u]}
+function addToHistory(role,content){const h=getChatHistory();h.push({role,content});if(h.length>60)h.splice(0,h.length-60)}
+
+// 页面中央对话
+async function sendCardMsg(){const i=document.getElementById('card-chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-card-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML=''+m.replace(//g,'>')+'
';ms.appendChild(ud);ms.scrollTop=ms.scrollHeight;const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;addToHistory('user',m);try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u,history:getChatHistory()})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML=''+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
';addToHistory('assistant',d.reply)}catch(e){ld.className='c-msg bot';ld.innerHTML='连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
+
+// 浮窗对话(共享记忆)
+async function sendMsg(){const i=document.getElementById('chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML=''+m.replace(//g,'>')+'
';ms.appendChild(ud);ms.scrollTop=ms.scrollHeight;const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='✦ 思考中...
';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;addToHistory('user',m);try{const u=localStorage.getItem('current_user')||'';const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m,user:u,history:getChatHistory()})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML=''+d.reply.replace(//g,'>').replace(/\n/g,'
')+'
';addToHistory('assistant',d.reply)}catch(e){ld.className='c-msg bot';ld.innerHTML='连接暂不可用
'}ms.scrollTop=ms.scrollHeight}
async function upTr(){try{const r=await fetch('/training-status.json');if(!r.ok)return;const d=await r.json();if(d.step===undefined)return;const s=d.step||0,t=d.total||12243,p=Math.min(s/t*100,100);document.getElementById('train-step').textContent=s.toLocaleString()+' / '+t.toLocaleString();document.getElementById('train-pct').textContent=p.toFixed(1)+'%';document.getElementById('train-bar').style.width=p+'%';if(d.loss!==undefined)document.getElementById('train-loss').textContent=d.loss;const e=document.getElementById('train-eta');if(e)e.textContent='预计今日完成 · Step '+s.toLocaleString();const z=document.getElementById('persona-zhu-status');if(z)z.textContent='训练中 · '+p.toFixed(0)+'%';const tag=document.getElementById('status-tag');if(tag)tag.textContent='● 训练中 · Step '+s.toLocaleString()}catch(e){}}
setInterval(upTr,30000);upTr();
diff --git a/homepage/training-status.json b/homepage/training-status.json
index cc39833..1a879e4 100644
--- a/homepage/training-status.json
+++ b/homepage/training-status.json
@@ -1 +1 @@
-{"step": 2860, "total": 12243, "loss": "1.662", "updated": "2026-05-19T11:10:01.962711+00:00Z"}
\ No newline at end of file
+{"step": 3060, "total": 12243, "loss": "1.658", "updated": "2026-05-19T11:16:02.422577+00:00Z"}
\ No newline at end of file