myagent-ai 1.19.8 → 1.19.9

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.
@@ -1500,6 +1500,32 @@ class MainAgent(BaseAgent):
1500
1500
 
1501
1501
  # 循环正常结束(max_iter 耗尽)时兜底保存
1502
1502
  else:
1503
+ logger.warning(f"[{task_id}] 达到最大迭代次数 ({max_iter}),任务未完成")
1504
+ # 通知前端:达到迭代上限
1505
+ await self._emit_v2_event("v2_iter_limit", {
1506
+ "message": f"任务已达到最大迭代次数 ({max_iter}),已自动保存为未完成任务",
1507
+ "iterations": self._iteration_count,
1508
+ "max_iterations": max_iter,
1509
+ "task_id": task_id,
1510
+ }, stream_callback)
1511
+ # 将未完成任务保存到任务持久化队列
1512
+ try:
1513
+ from core.task_persistence import TaskPersistence
1514
+ _tp = TaskPersistence()
1515
+ _tp.initialize()
1516
+ _tp.save_task(
1517
+ task_id=task_id,
1518
+ description=context.user_input or "未完成任务",
1519
+ session_id=context.session_id or "",
1520
+ agent_path=context.agent_path or "",
1521
+ status="pending",
1522
+ metadata={"iterations": self._iteration_count, "reason": "达到最大迭代次数"},
1523
+ last_message=f"达到最大迭代次数 {max_iter},共执行 {self._iteration_count} 次",
1524
+ )
1525
+ logger.info(f"[{task_id}] 已将未完成任务保存到任务队列")
1526
+ except Exception as _tp_err:
1527
+ logger.warning(f"[{task_id}] 保存未完成任务失败: {_tp_err}")
1528
+
1503
1529
  if self.memory and _v2_reasoning_collected:
1504
1530
  _fallback_text = "\n".join(_v2_reasoning_collected)
1505
1531
  if _fallback_text.strip():
package/config.py CHANGED
@@ -71,7 +71,7 @@ class ExecutorConfig:
71
71
  @dataclass
72
72
  class AgentConfig:
73
73
  """Agent 配置"""
74
- max_iterations: int = 30 # 单任务最大迭代次数
74
+ max_iterations: int = 10000 # 单任务最大迭代次数
75
75
  max_parallel: int = 3 # 最大并行任务数
76
76
  verbose: bool = True # 详细日志
77
77
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.19.8",
3
+ "version": "1.19.9",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
@@ -975,6 +975,7 @@ input,textarea,select{font:inherit}
975
975
  .toast-error{background:#fef2f2;color:#991b1b;border:1px solid #fecaca}
976
976
  .toast-success{background:#ecfdf5;color:#065f46;border:1px solid #a7f3d0}
977
977
  .toast-info{background:#eff6ff;color:#1e3a5f;border:1px solid #bfdbfe}
978
+ .toast-warning{background:#fffbeb;color:#92400e;border:1px solid #fde68a}
978
979
 
979
980
  /* ── Confirm Dialog ── */
980
981
  .modal-overlay{
@@ -2045,6 +2046,7 @@ input,textarea,select{font:inherit}
2045
2046
  [data-theme="dark"] .toast-error{background:rgba(127,29,29,.8);color:#fca5a5;border-color:rgba(239,68,68,.4)}
2046
2047
  [data-theme="dark"] .toast-success{background:rgba(6,78,59,.8);color:#6ee7b7;border-color:rgba(16,185,129,.4)}
2047
2048
  [data-theme="dark"] .toast-info{background:rgba(30,64,175,.8);color:#93c5fd;border-color:rgba(59,130,246,.4)}
2049
+ [data-theme="dark"] .toast-warning{background:rgba(113,63,18,.8);color:#fcd34d;border-color:rgba(245,158,11,.4)}
2048
2050
  [data-theme="dark"] .modal-overlay{background:rgba(0,0,0,.5)}
2049
2051
  [data-theme="dark"] .exec-badge.local{background:rgba(16,185,129,.15);color:#6ee7b7}
2050
2052
  [data-theme="dark"] .exec-badge.sandbox{background:rgba(245,158,11,.15);color:#fcd34d}
@@ -1871,6 +1871,20 @@ async function sendMessage(opts) {
1871
1871
  }
1872
1872
  ttsManager.streamDelta(evt.content);
1873
1873
  }
1874
+ } else if (evt.type === 'v2_iter_limit') {
1875
+ // 达到最大迭代次数限制
1876
+ flushV2Reasoning();
1877
+ flushCurrentText();
1878
+ // 弹窗通知用户
1879
+ if (typeof toast === 'function') {
1880
+ toast(evt.message || '任务已达到最大迭代次数,已保存为未完成任务', 'warning', 8000);
1881
+ }
1882
+ // 在消息中追加提示
1883
+ var _limitNotice = '\n\n> ⚠️ **达到迭代上限** (' + (evt.iterations || 0) + '/' + (evt.max_iterations || 0) + '),任务已自动保存为未完成任务。';
1884
+ if (state.messages[msgIdx]) {
1885
+ state.messages[msgIdx].content = (state.messages[msgIdx].content || '') + _limitNotice;
1886
+ }
1887
+ throttledStreamUpdate(msgIdx);
1874
1888
  } else if (evt.type === 'done') {
1875
1889
  // Flush remaining V2 reasoning as final text part
1876
1890
  flushV2Reasoning();