myagent-ai 1.10.1 → 1.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.10.1",
3
+ "version": "1.10.3",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
package/web/api_server.py CHANGED
@@ -2459,15 +2459,24 @@ class ApiServer:
2459
2459
  async def handle_memory_search(self, request):
2460
2460
  q = request.query.get("q", ""); cat = request.query.get("category", "")
2461
2461
  if not self.core.memory: return web.json_response([])
2462
- results = self.core.memory.search(q, category=cat, limit=20)
2463
- return web.json_response([{"id": e.id, "key": e.key, "content": e.content,
2464
- "category": e.category, "importance": e.importance} for e in results])
2462
+ results = self.core.memory.search(q, category=cat, limit=30)
2463
+ return web.json_response([{
2464
+ "id": e.id, "key": e.key, "content": e.content[:500],
2465
+ "category": e.category, "importance": e.importance,
2466
+ "role": e.role, "session_id": e.session_id, "created_at": e.created_at,
2467
+ } for e in results])
2465
2468
 
2466
2469
  async def handle_list_long_term(self, request):
2467
2470
  if not self.core.memory: return web.json_response([])
2468
- entries = self.core.memory.get_long_term(limit=50)
2469
- return web.json_response([{"id": e.id, "key": e.key, "content": e.content[:300],
2470
- "summary": e.summary, "importance": e.importance} for e in entries])
2471
+ cat = request.query.get("category", "long_term")
2472
+ limit = int(request.query.get("limit", "50"))
2473
+ entries = self.core.memory._query(category=cat, limit=limit, order_by="created_at DESC")
2474
+ return web.json_response([{
2475
+ "id": e.id, "key": e.key, "content": e.content[:500],
2476
+ "summary": e.summary, "importance": e.importance,
2477
+ "category": e.category, "role": e.role,
2478
+ "session_id": e.session_id, "created_at": e.created_at,
2479
+ } for e in entries])
2471
2480
 
2472
2481
  async def handle_delete_long_term(self, request):
2473
2482
  if self.core.memory:
@@ -2486,6 +2486,8 @@ function renderDeptDetail(path, detail) {
2486
2486
  function openDeptGroupChat(groupId) {
2487
2487
  closeGroupModal();
2488
2488
  selectGroup(groupId);
2489
+ // 移动端:确保右侧面板关闭
2490
+ if (typeof isMobile === 'function' && isMobile()) closeMobileAgentPanel();
2489
2491
  }
2490
2492
 
2491
2493
  // ── Dept Info Editor ──
@@ -131,7 +131,11 @@ function toggleGroupsSection() {
131
131
  // ══════════════════════════════════════════════════════
132
132
 
133
133
  async function selectGroup(gid) {
134
- if (gid === currentGroupId) return;
134
+ if (gid === currentGroupId) {
135
+ // 即使已在当前群聊,移动端也要关闭右侧面板
136
+ if (typeof isMobile === 'function' && isMobile()) closeMobileAgentPanel();
137
+ return;
138
+ }
135
139
  currentView = 'group';
136
140
  currentGroupId = gid;
137
141
 
package/web/ui/index.html CHANGED
@@ -913,28 +913,71 @@ function enterSession(sid,agentName){
913
913
  }
914
914
 
915
915
  // ========== Memory ==========
916
+ let _memCategory='long_term';
916
917
  async function renderMemory(){
917
918
  let stats={},lt=[];
918
919
  try{stats=await api('/api/memory/stats')}catch(e){stats={error:e.message}}
919
- try{lt=await api('/api/memory/long-term')}catch(e){lt=[]}
920
+ try{lt=await api('/api/memory/long-term?category='+encodeURIComponent(_memCategory))}catch(e){lt=[]}
920
921
  if(stats.error){$('content').innerHTML='<div class="empty" style="color:var(--danger)">记忆系统异常: '+escHtml(stats.error)+'</div>';return}
922
+ const cats=[{k:'short_term',l:'短期记忆'},{k:'working',l:'工作记忆'},{k:'long_term',l:'长期记忆'}];
923
+ let tabHtml='<div class="flex gap-8 mb-8">';
924
+ for(const c of cats){
925
+ const active=c.k===_memCategory?'btn-primary':'btn-ghost';
926
+ const count=stats[c.k+'_count']||0;
927
+ tabHtml+=`<button class="btn ${active}" onclick="_memCategory='${c.k}';renderMemory()">${c.l} (${count})</button>`;
928
+ }
929
+ tabHtml+='</div>';
921
930
  let html=`<div class="grid" style="grid-template-columns:repeat(4,1fr);margin-bottom:16px">
922
931
  <div class="stat"><div class="label">总计</div><div class="value">${stats.total_count||0}</div></div>
923
932
  <div class="stat"><div class="label">短期</div><div class="value">${stats.short_term_count||0}</div></div>
924
933
  <div class="stat"><div class="label">工作</div><div class="value">${stats.working_count||0}</div></div>
925
934
  <div class="stat"><div class="label">长期</div><div class="value">${stats.long_term_count||0}</div></div></div>`;
935
+ html+=tabHtml;
926
936
  html+='<div class="flex gap-8 mb-16"><input id="memSearch" placeholder="搜索记忆..." onkeydown="if(event.key===\'Enter\')searchMemory()" style="max-width:400px"><button class="btn btn-primary" onclick="searchMemory()">搜索</button><button class="btn btn-ghost" onclick="cleanupMemory()">清理过期</button></div>';
927
- html+='<h3 style="margin-bottom:8px">长期记忆</h3><table><tr><th>Key</th><th>内容</th><th>重要性</th><th></th></tr>';
928
- for(const e of (lt||[])){html+=`<tr><td>${escHtml(e.key||'')}</td><td>${escHtml((e.content||e.summary||'').slice(0,150))}</td><td>${e.importance||''}</td><td><button class="btn btn-sm btn-danger" onclick="deleteMemory('${e.id}')">删除</button></td></tr>`;}
929
- html+='</table>';if(!lt||!lt.length)html+='<div class="empty">暂无长期记忆</div>';
937
+ if(lt&&lt.length){
938
+ const isShortTerm=_memCategory==='short_term';
939
+ const showSession=isShortTerm;
940
+ const showRole=isShortTerm;
941
+ let thHtml='<tr>';
942
+ thHtml+='<th>Key</th><th>内容</th>';
943
+ if(showRole)thHtml+='<th>角色</th>';
944
+ if(showSession)thHtml+='<th>会话</th>';
945
+ if(!isShortTerm)thHtml+='<th>重要性</th>';
946
+ thHtml+='<th></th></tr>';
947
+ html+='<table>'+thHtml;
948
+ for(const e of lt){
949
+ const content=(e.content||e.summary||'')||(e.role==='user'?'[用户消息]':e.role==='assistant'?'[助手回复]':'[系统]');
950
+
951
+ let contentPreview=escHtml(content.slice(0,300));
952
+ if(content.length>300)contentPreview+=`<span style="color:var(--text3)">... (${content.length}字)</span>`;
953
+ html+='<tr><td style="white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis">'+escHtml(e.key||e.role||'-')+'</td>';
954
+ html+='<td style="max-width:600px;word-break:break-word;font-size:13px">'+contentPreview+'</td>';
955
+ if(showRole)html+='<td style="white-space:nowrap">'+escHtml(e.role||'')+'</td>';
956
+ if(showSession)html+='<td style="white-space:nowrap;max-width:140px;overflow:hidden;text-overflow:ellipsis;font-size:12px;color:var(--text3)" title="'+escHtml(e.session_id||'')+'">'+escHtml((e.session_id||'').split('_web_')[0])+'</td>';
957
+ if(!isShortTerm)html+='<td>'+(e.importance!=null?e.importance.toFixed(2):'')+'</td>';
958
+ html+='<td><button class="btn btn-sm btn-danger" onclick="deleteMemory(\''+e.id+'\')">删除</button></td></tr>';
959
+ }
960
+ html+='</table>';
961
+ }else{
962
+ html+='<div class="empty">暂无'+(_memCategory==='short_term'?'短期':_memCategory==='working'?'工作':'长期')+'记忆</div>';
963
+ }
930
964
  $('content').innerHTML=html;
931
965
  }
932
966
  async function searchMemory(){
933
967
  const q=$('memSearch').value;if(!q)return;
934
968
  const r=await api('/api/memory/search?q='+encodeURIComponent(q));
935
- let html='<h3>搜索结果: '+(r.length||0)+' 条</h3><table><tr><th>Key</th><th>内容</th><th>分类</th></tr>';
936
- for(const e of (r||[])){html+=`<tr><td>${escHtml(e.key||'')}</td><td>${escHtml((e.content||'').slice(0,200))}</td><td>${e.category||''}</td></tr>`;}
937
- html+='</table><button class="btn btn-ghost mt-8" onclick="renderMemory()">返回</button>';$('content').innerHTML=html;
969
+ let html='<h3>搜索结果: '+(r.length||0)+' 条</h3>';
970
+ if(r&&r.length){
971
+ html+='<table><tr><th>Key</th><th>内容</th><th>分类</th><th>角色</th><th>会话</th></tr>';
972
+ for(const e of r){
973
+ const content=(e.content||'').slice(0,300);
974
+ html+=`<tr><td style="white-space:nowrap">${escHtml(e.key||'')}</td><td style="max-width:600px;word-break:break-word;font-size:13px">${escHtml(content)}</td><td>${e.category||''}</td><td>${escHtml(e.role||'')}</td><td style="font-size:12px;color:var(--text3)">${escHtml((e.session_id||'').split('_web_')[0])}</td></tr>`;
975
+ }
976
+ html+='</table>';
977
+ }else{
978
+ html+='<div class="empty">未找到匹配的记忆</div>';
979
+ }
980
+ html+='<button class="btn btn-ghost mt-8" onclick="renderMemory()">返回</button>';$('content').innerHTML=html;
938
981
  }
939
982
  async function deleteMemory(id){await api(`/api/memory/long-term/${id}`,{method:'DELETE'});renderMemory()}
940
983
  async function cleanupMemory(){const r=await api('/api/memory/cleanup',{method:'POST'});showToast('清理了 '+(r.cleaned||0)+' 条','success');renderMemory()}