diff --git a/src/daemon/dispatcher.py b/src/daemon/dispatcher.py index fd6064d..4f9fa2b 100644 --- a/src/daemon/dispatcher.py +++ b/src/daemon/dispatcher.py @@ -712,6 +712,14 @@ class Dispatcher: logger.error("Mail %s: all 3 failed attempts failed, leaving for ticker", task_id) return + # inform 类型:只对成功 outcome 标 done,失败 outcome 留 working 等 ticker 重投 + # Task 路径不受此 bug 影响(走 _task_auto_complete 独立逻辑) + if performative == "inform": + INFORM_DONE_OUTCOMES = {"completed", "claimed", "no_reply"} + if outcome not in INFORM_DONE_OUTCOMES: + logger.info("Mail %s: inform outcome=%s, skip auto-done", task_id, outcome) + return + # 标 done(重试 3 次) for attempt in range(3): try: diff --git a/src/daemon/spawner.py b/src/daemon/spawner.py index 1d45bf2..7876435 100644 --- a/src/daemon/spawner.py +++ b/src/daemon/spawner.py @@ -848,10 +848,13 @@ curl -X POST http://{api_host}:{api_port}/api/projects/{project_id}/tasks/{task_ # A8(gateway_unreachable), A11(lock_conflict), # A10(compact_failed), A12(agent_error) # v2.8.1 Fix-3a: crash 类 outcome 设 cooldown,给 agent session 恢复时间 - if outcome in ("crashed", "compact_failed", "process_crash", "session_stuck", + if outcome == "crashed" and self.counter: + self.counter.set_cooldown(agent_id, seconds=60) + logger.info("Crash cooldown set for %s: 60s (outcome=%s)", agent_id, outcome) + elif outcome in ("compact_failed", "process_crash", "session_stuck", "compact_hanging", "agent_error", "compact_interrupted") and self.counter: self.counter.set_cooldown(agent_id, seconds=300) # 5 分钟 - logger.info("Crash/error cooldown set for %s: 300s (outcome=%s)", agent_id, outcome) + logger.info("Error cooldown set for %s: 300s (outcome=%s)", agent_id, outcome) # F1: 不可恢复 outcome → 立刻标 failed + 写黑板 if outcome in ("auth_failed", "agent_error") and db_path and task_id: logger.error("Task %s: unrecoverable outcome=%s, marking failed immediately", task_id, outcome)