fix(fallback): turnul nu se mai pierde cand Claude e la limita

Detectia de rate limit functiona, dar `_local_fallback_reply` putea
intoarce None din patru locuri fara nicio linie de log — userul primea
`Claude CLI error (exit 1): You've hit your session limit` pe Discord in
loc de raspuns, si nu se putea afla ulterior din log care branch a picat.

- daca runda de unelte iese goala, turnul se reface fara unelte in loc
  sa fie abandonat
- fiecare return None ramas e logat
- daca nici modelul local nu raspunde, mesajul e „Claude e la limita…"
  plus ora de reset, nu eroarea bruta a CLI-ului
- cron: job-urile heartbeat* tac la limita (last_status: rate_limited);
  celelalte trimit o singura linie scurta, ca sa se vada rularea sarita
- is_rate_limit_error / rate_limit_detail mutate in claude_session.py,
  folosite si de scheduler (care nu poate importa router-ul)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzZAMzbyQbzFdsrVoXijBg
This commit is contained in:
2026-08-23 14:52:44 +00:00
parent a1d39637c8
commit b97edd5184
7 changed files with 147 additions and 17 deletions

View File

@@ -242,7 +242,7 @@ class TestRegularMessage:
@patch("src.router._get_channel_config")
@patch("src.router._get_config")
@patch("src.router.send_message")
def test_rate_limit_fallback_unavailable_surfaces_original_error(
def test_rate_limit_fallback_unavailable_surfaces_limit_notice(
self, mock_send, mock_get_config, mock_chan_cfg, mock_fallback,
):
mock_send.side_effect = RuntimeError(
@@ -255,8 +255,11 @@ class TestRegularMessage:
mock_fallback.return_value = None # local fallback itself unreachable
response, is_cmd = route_message("ch-1", "user-1", "hello")
assert "Error:" in response
assert "hit your session limit" in response
# The reset time still has to reach the user; the `Claude CLI error
# (exit 1):` wrapper is noise and must not.
assert "resets 10:50am (UTC)" in response
assert "Claude e la limită" in response
assert "Claude CLI error" not in response
assert is_cmd is False
@patch("src.router._get_channel_config")