From 7fb4d988ecdd2ddcd34c743e132727c90b6cb308 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Sat, 13 Jun 2026 09:29:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20lint=20=E4=BF=AE=E5=A4=8D=20+=20api=5Fer?= =?UTF-8?q?ror=20=E6=B5=8B=E8=AF=95=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mail_notify: f-string 反斜杠修复、行过长修复、unused import - test_classify_outcome: api_error should_retry 改 True --- src/daemon/mail_notify.py | 20 +++++++++++++++----- tests/unit/test_classify_outcome.py | 6 ++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/daemon/mail_notify.py b/src/daemon/mail_notify.py index 092fbff..683a0fc 100644 --- a/src/daemon/mail_notify.py +++ b/src/daemon/mail_notify.py @@ -6,7 +6,7 @@ import json import logging from datetime import datetime from pathlib import Path -from typing import Callable, Dict, Optional +from typing import Dict, Optional from src.blackboard.models import Task from src.blackboard.operations import Blackboard @@ -32,7 +32,8 @@ def _fmt_retry_info(reason: str, detail: dict) -> str: "agent_failed", "compact_failed", } if reason in _NO_RETRY_REASONS: - return f"无法重试({_REASON_MAP.get(reason, _REASON_MAP[\"_default\"])[0]})" + reason_human = _REASON_MAP.get(reason, _REASON_MAP.get("_default", ("未知原因", lambda d: "")))[0] + return f"无法重试({reason_human})" count = (detail or {}).get("count", 0) fallback_count = (detail or {}).get("fallback_count", 0) @@ -51,17 +52,26 @@ _REASON_MAP: Dict[str, tuple] = { "max_crash_count": ("连续崩溃达上限", lambda d: f"崩溃 {d.get('count', '?')} 次"), "max_retries": ("续杯耗尽(已自动重试)", lambda d: f"重试 {d.get('count', '?')} 次"), "max_api_retry_count": ("API 连续失败达上限", lambda d: f"API 重试 {d.get('count', '?')} 次"), - "max_monitor_timeouts": ("处理超时达上限", lambda d: f"超时 {d.get('count', '?')} 次,共约 {d.get('elapsed_seconds', 0) // 60} 分钟"), + "max_monitor_timeouts": ( + "处理超时达上限", + lambda d: f"超时 {d.get('count', '?')} 次," + f"共约 {d.get('elapsed_seconds', 0) // 60} 分钟"), "gateway_timeout": ("Agent 执行超时(已续杯重试)", lambda d: ""), "session_stuck": ("会话假死(lock PID 死亡)", lambda d: f"假死 {d.get('stuck_count', '?')} 次"), "revive_failed": ("会话恢复失败", lambda d: f"假死 {d.get('stuck_count', '?')} 次"), "auth_failed": ("Agent 认证失败(配置问题)", lambda d: f"stderr: {_extract_stderr(d)}" if _extract_stderr(d) else ""), - "fallback_exhausted": ("主模型和备用模型均失败", lambda d: f"fallback {d.get('fallback_count', '?')} 次,原因: {d.get('fallback_reason', '未知')}"), + "fallback_exhausted": ( + "主模型和备用模型均失败", + lambda d: f"fallback {d.get('fallback_count', '?')} 次," + f"原因: {d.get('fallback_reason', '未知')}"), "agent_failed": ("收件人主动标记失败", lambda d: ""), "compact_failed": ("上下文压缩失败", lambda d: f"stderr: {_extract_stderr(d)}" if _extract_stderr(d) else ""), "compact_hanging": ("上下文压缩长时间未完成", lambda d: ""), "compact_interrupted": ("上下文压缩被中断(已自动重试)", lambda d: ""), - "gateway_unreachable": ("Gateway 不可达(已自动重试)", lambda d: f"stderr: {_extract_stderr(d)}" if _extract_stderr(d) else ""), + "gateway_unreachable": ( + "Gateway 不可达(已自动重试)", + lambda d: f"stderr: {_extract_stderr(d)}" + if _extract_stderr(d) else ""), "lock_conflict": ("会话锁冲突(已自动重试)", lambda d: ""), "max_retry_count": ("重试耗尽", lambda d: f"重试 {d.get('count', '?')} 次"), "max_lock_retry_count": ("锁冲突重试耗尽", lambda d: f"重试 {d.get('count', '?')} 次"), diff --git a/tests/unit/test_classify_outcome.py b/tests/unit/test_classify_outcome.py index 07f21d8..62a2061 100644 --- a/tests/unit/test_classify_outcome.py +++ b/tests/unit/test_classify_outcome.py @@ -165,14 +165,16 @@ class TestClassifyErrorApi: 1, {"status": "error"}, "rate_limit exceeded", None ) assert result["outcome"] == "api_error" - assert result["should_retry"] is False + assert result["should_retry"] is True + assert result["cooldown_seconds"] == 60 def test_stderr_500(self): result = Spawner._classify_outcome( 1, {"status": "error"}, "HTTP 500 Internal Server Error", None ) assert result["outcome"] == "api_error" - assert result["should_retry"] is False + assert result["should_retry"] is True + assert result["cooldown_seconds"] == 60 class TestClassifyErrorCompact: