Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4092,9 +4092,39 @@ def _run_quiet_single_query(cli, effective_query):
_exit_code = 0
if isinstance(result, dict) and result.get("failed"):
_exit_code = 1
if os.environ.get("HERMES_KANBAN_TASK") and result.get("failure_reason") in ("rate_limit", "billing"):
_failure_reason = result.get("failure_reason")
if (
os.environ.get("HERMES_KANBAN_TASK")
and _failure_reason not in ("rate_limit", "billing")
):
# Fallback when the failing turn never stamped
# failure_reason (e.g. quota exhaustion surfacing
# through a path that only carries prose): a
# missing key must not turn a quota wall into a
# generic exit 1, which the dispatcher reads as
# "crashed" and redispatches into the same quota
# window until the circuit breaker trips (#101800).
# Keyword-only, kanban-workers-only; an explicit
# failure_reason above always wins.
_err_text = str(result.get("error") or "")
_quota_signals = (
"rate limit", "rate_limit", "rate-limited",
"429", "quota", "usage limit", "usage_limit",
"billing", "credits exhausted", "insufficient",
)
if any(
_sig in _err_text.lower()
for _sig in _quota_signals
):
_failure_reason = "rate_limit"
if os.environ.get("HERMES_KANBAN_TASK") and _failure_reason in (
"rate_limit",
"billing",
):
try:
from hermes_cli.kanban_db import KANBAN_RATE_LIMIT_EXIT_CODE as _RL_CODE
from hermes_cli.kanban_db import (
KANBAN_RATE_LIMIT_EXIT_CODE as _RL_CODE,
)
_exit_code = _RL_CODE
except Exception:
_exit_code = 1
Expand Down