myagent-ai 1.27.8 → 1.28.0

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.
@@ -728,6 +728,10 @@ class MainAgent(BaseAgent):
728
728
  # XML 解析失败时的 LLM 修正重试计数
729
729
  _xml_correction_retries: int = 0
730
730
 
731
+ # [v1.28] 优先使用调用方传入的 agent_db_id(来自 _stream_process_message)
732
+ # 确保 V2 路径保存会话记忆时使用正确的 agent_id(与 session 列表查询一致)
733
+ _effective_agent_id = context.metadata.get("agent_db_id", self.agent_id)
734
+
731
735
  # [v1.26.9] 统一历史对话处理算法 - 确保流式和非流式输出使用相同的逻辑
732
736
  conversation_history = self._build_conversation_history(context, task_id)
733
737
 
@@ -745,7 +749,7 @@ class MainAgent(BaseAgent):
745
749
  _attachment_meta["images"] = context.metadata["user_image_files"]
746
750
  if context.metadata.get("user_file_files"):
747
751
  _attachment_meta["files"] = context.metadata["user_file_files"]
748
- self.memory.add_session(agent_id=self.agent_id,
752
+ self.memory.add_session(agent_id=_effective_agent_id,
749
753
  session_id=context.session_id,
750
754
  role="user",
751
755
  content=context.user_message,
@@ -869,7 +873,7 @@ class MainAgent(BaseAgent):
869
873
  for _msg in messages:
870
874
  _input_parts.append(f"=== {_msg.role.upper()} ===\n{_msg.get_text_content()}")
871
875
  _llm_input_text = "\n\n".join(_input_parts)
872
- self.memory.add_session(agent_id=self.agent_id,
876
+ self.memory.add_session(agent_id=_effective_agent_id,
873
877
  session_id=context.session_id,
874
878
  role="system",
875
879
  content=_llm_input_text,
@@ -896,7 +900,7 @@ class MainAgent(BaseAgent):
896
900
  context.working_memory["final_response"] = _censor_msg
897
901
  await self._emit_v2_event("v2_reasoning", {"content": _censor_msg}, stream_callback)
898
902
  if self.memory:
899
- self.memory.add_session(agent_id=self.agent_id,
903
+ self.memory.add_session(agent_id=_effective_agent_id,
900
904
  session_id=context.session_id,
901
905
  role="assistant",
902
906
  content=_censor_msg,
@@ -926,7 +930,7 @@ class MainAgent(BaseAgent):
926
930
  context.working_memory["final_response"] = _vision_skip_msg
927
931
  await self._emit_v2_event("v2_reasoning", {"content": _vision_skip_msg}, stream_callback)
928
932
  if self.memory:
929
- self.memory.add_session(agent_id=self.agent_id,
933
+ self.memory.add_session(agent_id=_effective_agent_id,
930
934
  session_id=context.session_id,
931
935
  role="assistant",
932
936
  content=_vision_skip_msg,
@@ -938,7 +942,7 @@ class MainAgent(BaseAgent):
938
942
  context.working_memory["final_response"] = error_msg
939
943
  await self._emit_v2_event("v2_reasoning", {"content": error_msg}, stream_callback)
940
944
  if self.memory:
941
- self.memory.add_session(agent_id=self.agent_id,
945
+ self.memory.add_session(agent_id=_effective_agent_id,
942
946
  session_id=context.session_id,
943
947
  role="assistant",
944
948
  content=error_msg,
@@ -950,7 +954,7 @@ class MainAgent(BaseAgent):
950
954
 
951
955
  # 保存 LLM 原始输出到会话记忆(用于回溯和审计,key=llm_output 不出现在对话历史中)
952
956
  if self.memory:
953
- self.memory.add_session(agent_id=self.agent_id,
957
+ self.memory.add_session(agent_id=_effective_agent_id,
954
958
  session_id=context.session_id,
955
959
  role="assistant",
956
960
  content=llm_raw,
@@ -959,7 +963,7 @@ class MainAgent(BaseAgent):
959
963
  )
960
964
  # 保存推理模型的思考过程(key=reasoning 供前端刷新后展示)
961
965
  if response.reasoning and response.reasoning.strip():
962
- self.memory.add_session(agent_id=self.agent_id,
966
+ self.memory.add_session(agent_id=_effective_agent_id,
963
967
  session_id=context.session_id,
964
968
  role="assistant",
965
969
  content=response.reasoning.strip(),
@@ -1049,7 +1053,7 @@ class MainAgent(BaseAgent):
1049
1053
  stream_callback,
1050
1054
  )
1051
1055
  if self.memory:
1052
- self.memory.add_session(agent_id=self.agent_id,
1056
+ self.memory.add_session(agent_id=_effective_agent_id,
1053
1057
  session_id=context.session_id,
1054
1058
  role="assistant",
1055
1059
  content=_msg,
@@ -1115,7 +1119,7 @@ class MainAgent(BaseAgent):
1115
1119
  "v2_reasoning", {"content": final_text}, stream_callback
1116
1120
  )
1117
1121
  if self.memory:
1118
- self.memory.add_session(agent_id=self.agent_id,
1122
+ self.memory.add_session(agent_id=_effective_agent_id,
1119
1123
  session_id=context.session_id,
1120
1124
  role="assistant",
1121
1125
  content=final_text,
@@ -1223,7 +1227,7 @@ class MainAgent(BaseAgent):
1223
1227
  f"(相似度>=0.80, 旧记忆ID={_session_dup.id})"
1224
1228
  )
1225
1229
  else:
1226
- self.memory.add_session(agent_id=self.agent_id,
1230
+ self.memory.add_session(agent_id=_effective_agent_id,
1227
1231
  session_id=context.session_id,
1228
1232
  key="conversation_insight",
1229
1233
  content=parsed.remember,
@@ -1303,7 +1307,7 @@ class MainAgent(BaseAgent):
1303
1307
  stream_callback,
1304
1308
  )
1305
1309
  if self.memory:
1306
- self.memory.add_session(agent_id=self.agent_id,
1310
+ self.memory.add_session(agent_id=_effective_agent_id,
1307
1311
  session_id=context.session_id,
1308
1312
  role="assistant",
1309
1313
  content=parsed.ask_user,
@@ -1314,29 +1318,32 @@ class MainAgent(BaseAgent):
1314
1318
  if not parsed.tools_to_call:
1315
1319
  logger.info(f"[{task_id}] 无工具调用,任务完成")
1316
1320
  if _v2_reasoning_collected:
1317
- # [v1.24] 拆开每条消息独立发送,不再合并
1318
- for _msg in _v2_reasoning_collected:
1321
+ # [v1.28] Step 5.5 已将所有 reasoning 文本 emit 给前端
1322
+ # 此处仅保存尚未持久化到 memory 的内容,不再重复 emit
1323
+ _new_items = _v2_reasoning_collected[_last_saved_len:]
1324
+ for _msg in _new_items:
1319
1325
  if _msg.strip():
1320
- await self._emit_v2_event("v2_reasoning", {"content": _msg}, stream_callback)
1321
1326
  if self.memory:
1322
- self.memory.add_session(agent_id=self.agent_id,
1327
+ self.memory.add_session(agent_id=_effective_agent_id,
1323
1328
  session_id=context.session_id,
1324
1329
  role="assistant",
1325
1330
  content=_msg,
1326
1331
  )
1327
- final_text = _v2_reasoning_collected[-1] if _v2_reasoning_collected else "已完成所有操作。"
1332
+ _last_saved_len = len(_v2_reasoning_collected)
1333
+ # reasoning 的最后一条作为最终文本(已在 Step 5.5 发送给前端)
1334
+ final_text = _v2_reasoning_collected[-1]
1328
1335
  else:
1329
1336
  before, after = extract_surrounding_text(llm_raw)
1330
1337
  final_text = (before + "\n" + after).strip() if (before.strip() or after.strip()) else "已完成所有操作。"
1331
1338
  context.working_memory["final_response"] = final_text
1332
1339
  if not _emitted_reasoning_this_iter:
1333
1340
  await self._emit_v2_event("v2_reasoning", {"content": truncate_str(final_text, 3000)}, stream_callback)
1334
- if self.memory:
1335
- self.memory.add_session(agent_id=self.agent_id,
1336
- session_id=context.session_id,
1337
- role="assistant",
1338
- content=final_text,
1339
- )
1341
+ if self.memory:
1342
+ self.memory.add_session(agent_id=_effective_agent_id,
1343
+ session_id=context.session_id,
1344
+ role="assistant",
1345
+ content=final_text,
1346
+ )
1340
1347
  break
1341
1348
 
1342
1349
  # Step 11: 有工具调用 — 顺序执行所有工具
@@ -1561,7 +1568,7 @@ class MainAgent(BaseAgent):
1561
1568
  if self.memory:
1562
1569
  # 构建工具调用记录,包含 beforecalltext 作为标题
1563
1570
  tool_call_title = before_call if before_call else f"调用工具: {tool_name}"
1564
- self.memory.add_session(agent_id=self.agent_id,
1571
+ self.memory.add_session(agent_id=_effective_agent_id,
1565
1572
  session_id=context.session_id,
1566
1573
  role="assistant",
1567
1574
  content=f"{tool_call_title}\n调用工具: {tool_name}\n参数: {truncate_str(parms, 1000)}",
@@ -1570,7 +1577,7 @@ class MainAgent(BaseAgent):
1570
1577
  )
1571
1578
  # [v1.15.52] 保存完整的工具执行原始结果(不截断,原汁原味)
1572
1579
  _raw_result_str = json.dumps(tool_result, ensure_ascii=False, indent=2) if tool_result else str(tool_result)
1573
- self.memory.add_session(agent_id=self.agent_id,
1580
+ self.memory.add_session(agent_id=_effective_agent_id,
1574
1581
  session_id=context.session_id,
1575
1582
  role="tool",
1576
1583
  content=f"[{tool_name}] {_status}\n{truncate_str(output_str, 10000)}",
@@ -1578,7 +1585,7 @@ class MainAgent(BaseAgent):
1578
1585
  importance=0.4,
1579
1586
  )
1580
1587
  # 额外保存原始完整 JSON(用于 Raw 查看器完整回溯)
1581
- self.memory.add_session(agent_id=self.agent_id,
1588
+ self.memory.add_session(agent_id=_effective_agent_id,
1582
1589
  session_id=context.session_id,
1583
1590
  role="tool",
1584
1591
  content=f"[{tool_name}] 原始结果 ({_status})\n{truncate_str(_raw_result_str, 45000)}",
@@ -1624,7 +1631,7 @@ class MainAgent(BaseAgent):
1624
1631
  _new_items = _v2_reasoning_collected[_last_saved_len:]
1625
1632
  for _msg in _new_items:
1626
1633
  if _msg.strip():
1627
- self.memory.add_session(agent_id=self.agent_id,
1634
+ self.memory.add_session(agent_id=_effective_agent_id,
1628
1635
  session_id=context.session_id,
1629
1636
  role="assistant",
1630
1637
  content=_msg,
@@ -1664,7 +1671,7 @@ class MainAgent(BaseAgent):
1664
1671
  # [v1.24] 拆开每条消息独立保存,不再合并
1665
1672
  for _msg in _v2_reasoning_collected:
1666
1673
  if _msg.strip():
1667
- self.memory.add_session(agent_id=self.agent_id,
1674
+ self.memory.add_session(agent_id=_effective_agent_id,
1668
1675
  session_id=context.session_id,
1669
1676
  role="assistant",
1670
1677
  content=_msg,
@@ -1674,7 +1681,7 @@ class MainAgent(BaseAgent):
1674
1681
  if _sent_files and self.memory:
1675
1682
  import json as _json_files
1676
1683
  try:
1677
- self.memory.add_session(agent_id=self.agent_id,
1684
+ self.memory.add_session(agent_id=_effective_agent_id,
1678
1685
  session_id=context.session_id,
1679
1686
  role="assistant",
1680
1687
  content="", # 空内容,仅用于承载文件元数据
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.27.8",
3
+ "version": "1.28.0",
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
@@ -5810,6 +5810,10 @@ window.addEventListener('beforeunload', function() {{
5810
5810
  context.metadata["chat_mode"] = chat_mode
5811
5811
  context.metadata["user_voice_text"] = voice_text # 语音输入原始文本(用于 usersays_correct)
5812
5812
 
5813
+ # [v1.28] 传入正确的 agent_db_id,确保 V2 路径保存会话时使用正确的 agent_id
5814
+ if agent_path and self.core.memory:
5815
+ context.metadata["agent_db_id"] = self.core.memory.get_agent_id(agent_path)
5816
+
5813
5817
  # [v1.16.12→17] 处理用户图片附件 — 保存到磁盘 + data URI 传给 LLM Vision API
5814
5818
  if user_images:
5815
5819
  _processed_images = []
@@ -6055,7 +6059,8 @@ window.addEventListener('beforeunload', function() {{
6055
6059
  recent = agent.memory.get_conversation(session_id, limit=3)
6056
6060
  _has_assistant = any(e.role == "assistant" for e in recent)
6057
6061
  if not _has_assistant and final_response and final_response.strip():
6058
- agent.memory.add_session(agent_id=agent_id,
6062
+ _fallback_agent_id = context.metadata.get("agent_db_id", 0)
6063
+ agent.memory.add_session(agent_id=_fallback_agent_id,
6059
6064
  session_id=session_id, role="assistant", content=final_response,
6060
6065
  )
6061
6066
 
@@ -4986,7 +4986,7 @@ const SETUP_PROVIDERS = {
4986
4986
  desc: '免费,步跃/MiniMax/智谱等模型',
4987
4987
  base_url: 'https://api-inference.modelscope.cn/v1',
4988
4988
  model: 'stepfun-ai/Step-3.5-Flash',
4989
- key_required: false, key_label: 'API Key(可选,不填使用免费额度)'
4989
+ key_required: false, key_label: 'API Key'
4990
4990
  },
4991
4991
  openai: {
4992
4992
  icon: '🌐', name: 'OpenAI / ChatGPT',
@@ -5161,7 +5161,7 @@ function renderSetupStep() {
5161
5161
  </div>`
5162
5162
  : `<div class="form-group">
5163
5163
  <label>${p.key_label}</label>
5164
- <input type="password" id="setupApiKey" placeholder="留空即可" autocomplete="off">
5164
+ <input type="password" id="setupApiKey" placeholder="" autocomplete="off">
5165
5165
  <div class="form-hint">选填,某些模型需要</div>
5166
5166
  </div>`;
5167
5167