From cb1ccc57e66636c411e52c38fc8c59953149d7f5 Mon Sep 17 00:00:00 2001 From: HexLab98 Date: Thu, 2 Jul 2026 17:30:04 +0700 Subject: [PATCH] fix(codex): extend stale timeout for gateway-scale tool payloads Lower the openai-codex stale-timeout floor from 25k to 10k estimated tokens so Telegram/gateway sessions (~20k tools+instructions) are not aborted at the generic 90s cutoff while Codex is still prefilling. --- agent/chat_completion_helpers.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/agent/chat_completion_helpers.py b/agent/chat_completion_helpers.py index 7a7064d72fe..4e52b914aac 100644 --- a/agent/chat_completion_helpers.py +++ b/agent/chat_completion_helpers.py @@ -128,6 +128,23 @@ def _is_openai_codex_backend(agent) -> bool: ) +def openai_codex_stale_timeout_floor(est_tokens: int) -> float: + """Minimum wall-clock stale timeout for openai-codex by estimated context. + + Gateway/Telegram sessions routinely ship ~15–25k tokens of tools + + instructions before the first user message. Subscription-backed Codex can + legitimately spend several minutes in backend admission/prefill at that + size; the generic 90s non-stream stale default aborts healthy calls. + """ + if est_tokens > 100_000: + return 1200.0 + if est_tokens > 50_000: + return 900.0 + if est_tokens > 10_000: + return 600.0 + return 0.0 + + def _validated_openrouter_provider_sort(raw_sort: Any) -> Optional[str]: """Return a normalized OpenRouter provider.sort value or None.""" if not isinstance(raw_sort, str): @@ -316,12 +333,9 @@ def interruptible_api_call(agent, api_kwargs: dict): _openai_codex_backend = _is_openai_codex_backend(agent) _est_tokens_for_codex_watchdog = estimate_request_context_tokens(api_kwargs) if _codex_watchdog_enabled and _openai_codex_backend: - if _est_tokens_for_codex_watchdog > 100_000: - _stale_timeout = max(_stale_timeout, 1200.0) - elif _est_tokens_for_codex_watchdog > 50_000: - _stale_timeout = max(_stale_timeout, 900.0) - elif _est_tokens_for_codex_watchdog > 25_000: - _stale_timeout = max(_stale_timeout, 600.0) + _codex_floor = openai_codex_stale_timeout_floor(_est_tokens_for_codex_watchdog) + if _codex_floor: + _stale_timeout = max(_stale_timeout, _codex_floor) if _est_tokens_for_codex_watchdog > 100_000: _codex_idle_timeout_default = 180.0 @@ -344,7 +358,7 @@ def interruptible_api_call(agent, api_kwargs: dict): if _ttfb_timeout <= 0: _ttfb_enabled = False elif _openai_codex_backend: - _ttfb_disable_above = _env_float("HERMES_CODEX_TTFB_DISABLE_ABOVE_TOKENS", 25_000.0) + _ttfb_disable_above = _env_float("HERMES_CODEX_TTFB_DISABLE_ABOVE_TOKENS", 10_000.0) _ttfb_strict = os.environ.get("HERMES_CODEX_TTFB_STRICT", "").strip().lower() in { "1", "true", "yes", "on" }