NousResearch/hermes-agent

Codex no-byte TTFB watchdog for large requests

Cluster 61778. Data as of

Nothing open on GitHub. Fix merged in #64594 on 15 Jul 2026. Check it covers your case.

The short answer

0open issues
0open PRs
3items grouped
Known?
Yes. 3 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #64594. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #64594. That is separate from the fix event.
Still open
Nothing open on GitHub.

The members concern the Codex no-byte (TTFB) watchdog on large requests. One is a bug report about 0-event hangs being hard to detect for requests over ~10k tokens, and two are fixes that keep the watchdog active or scale it rather than disabling it. This describes only what the titles state and does not indicate whether the bug is closed.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #64594 fix(codex): scale, don't disable, the no-byte TTFB watchdog for large requests (#61778)

    merged to main

    files: agent/chat_completion_helpers.py, tests/agent/test_codex_ttfb_watchdog.py

    Show the diff
    • agent/chat_completion_helpers.py
      @@ -533,25 +533,28 @@ def _call():
                   and _ttfb_disable_above > 0
                   and _est_tokens_for_codex_watchdog >= _ttfb_disable_above
               ):
      -            _ttfb_enabled = False
      -            logger.info(
      -                "Disabling openai-codex no-byte TTFB watchdog for large request "
      -                "(context=~%s tokens >= %.0f). Waiting for backend response instead. "
      -                "Set HERMES_CODEX_TTFB_STRICT=1 to force early reconnects.",
      -                f"{_est_tokens_for_codex_watchdog:,}",
      -                _ttfb_disable_above,
      -            )
      -        else:
      -            _ttfb_cap = _env_float("HERMES_CODEX_TTFB_MAX_SECONDS", 120.0)
      -            if _ttfb_cap > 0 and _ttfb_timeout > _ttfb_cap:
      +            _large_request_ttfb_timeout = _codex_idle_timeout_default
      +            if _ttfb_timeout < _large_request_ttfb_timeout:
                       logger.info(
      -                    "Capping openai-codex no-byte TTFB timeout from %.0fs to %.0fs "
      -                    "(context=~%s tokens). Set HERMES_CODEX_TTFB_MAX_SECONDS to tune.",
      +                    "Scaling openai-codex no-byte TTFB watchdog from %.0fs to %.0fs "
      +                    "for large request (context=~%s tokens >= %.0f). "
      +                    "Set HERMES_CODEX_TTFB_STRICT=1 to keep the smaller cutoff.",
                           _ttfb_timeout,
      -                    _ttfb_cap,
      +                    _large_request_ttfb_timeout,
                           f"{_est_tokens_for_codex_watchdog:,}",
      +                    _ttfb_disable_above,
                       )
      -                _ttfb_timeout = _ttfb_cap
      +                _ttfb_timeout = _large_request_ttfb_timeout
      +        _ttfb_cap = _env_float("HERMES_CODEX_TTFB_MAX_SECONDS", 120.0)
      +        if _ttfb_cap > 0 and _ttfb_timeout > _ttfb_cap:
      +            logger.info(
      +                "Capping openai-codex no-byte TTFB timeout from %.0fs to %.0fs "
      +                "(context=~%s tokens). Set HERMES_CODEX_TTFB_MAX_SECONDS to tune.",
      +                _ttfb_timeout,
      +                _ttfb_cap,
      +                f"{_est_tokens_for_codex_watchdog:,}",
      +            )
      +            _ttfb_timeout = _ttfb_cap
       
           _codex_idle_enabled = _codex_watchdog_enabled
           _codex_idle_timeout = _env_float(
    • tests/agent/test_codex_ttfb_watchdog.py
      @@ -353,8 +353,8 @@ def fake_stream(api_kwargs, client=None, on_first_delta=None):
       
       def test_large_codex_request_waits_instead_of_ttfb_reconnect(tmp_path, monkeypatch):
           """Large Codex inputs can legitimately take longer than the small-request
      -    first-byte cutoff before the first SSE frame. Preserve the full input and
      -    wait instead of killing/retrying at TTFB."""
      +    first-byte cutoff before the first SSE frame. Scale the TTFB timeout up
      +    for those requests instead of killing/retrying at the small-request cutoff."""
           from agent import chat_completion_helpers as h
       
           agent = _make_codex_agent(tmp_path, monkeypatch)
      @@ -386,6 +386,45 @@ def fake_stream(api_kwargs, client=None, on_first_delta=None):
           assert "codex_ttfb_kill" not in closes
       
       
      +def test_large_codex_request_can_still_ttfb_reconnect_when_capped(tmp_path, monkeypatch):
      +    """Large Codex requests should keep a finite TTFB watchdog instead of
      +    disabling it entirely. A low max cap should still force an early reconnect."""
      +    from agent import chat_completion_helpers as h
      +
      +    agent = _make_codex_agent(tmp_path, monkeypatch)
      +    monkeypatch.setenv("HERMES_CODEX_TTFB_TIMEOUT_SECONDS", "1")
      +    monkeypatch.setenv("HERMES_CODEX_TTFB_MAX_SECONDS", "1")
      +
      +    closes: list = []
      +    dummy_client = SimpleNamespace()
      +    monkeypatch.setattr(agent, "_create_request_openai_client", lambda **k: dummy_client)
      +    monkeypatch.setattr(
      +        agent, "_abort_request_openai_client", lambda c, reason=None: closes.append(reason)
      +    )
      +    monkeypatch.setattr(
      +        agent, "_close_request_openai_client", lambda c, reason=None: closes.append(reason)
      +    )
      +
      +    stop = {"flag": False}
      +
      +    def fake_hang(api_kwargs, client=None, on_first_delta=None):
      +        deadline = time.time() + 30
      +        while time.time() < deadline and not stop["flag"] and not agent._interrupt_requested:
      +            time.sleep(0.02)
      +        raise RuntimeError("connection closed")
      +
      +    monkeypatch.setattr(agent, "_run_codex_stream", fake_hang)
      +
      +    large_input = "x" * 44_000  # ~11k estimated tokens, above the large-request gate.
      +    try:
      +        with pytest.raises(TimeoutError) as excinfo:
      +            h.interruptible_api_call(agent, {"model": "gpt-5.5", "input": large_input})
      +        assert "TTFB threshold: 1s" in str(excinfo.value)
      +        assert "codex_ttfb_kill" in closes
      +    finally:
      +        stop["flag"] = True
      +
      +
       def test_large_codex_request_strict_ttfb_env_still_reconnects(tmp_path, monkeypatch):
           """Operators can force the old early-reconnect behavior for large inputs
           with HERMES_CODEX_TTFB_STRICT=1."""

1 PR closed without merging

From the close comments: merged via another change 1

  • #62997 fix(codex): keep large-request ttfb watchdog active · merged via another change → #64594, #61778
Closed issues · 1
  • Closed#61778[Bug]: Codex 0-event hang is undetectable for >10k-token requests — TTFB exemption + event-idle precondition leave only the wall-clock stale timeout, which loses the race to delegation child_timeout
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#64594
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
15 Jul 2026

For your agent

The same facts, typed.