# NousResearch/hermes-agent · Codex no-byte TTFB watchdog for large requests

## Open now

- 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.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #64594. Verify it addresses your case.
- **Recommended:** read PR #64594 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-64594`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member 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.

## Closed / duplicate issues

- #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

## Prior & competing PRs

- **#64594: fix(codex): scale, don't disable, the no-byte TTFB watchdog for large requests (#61778)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `agent/chat_completion_helpers.py`, `tests/agent/test_codex_ttfb_watchdog.py`
  - fix hunks:
  - `agent/chat_completion_helpers.py`

    ```diff
    @@ -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`

    ```diff
    @@ -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)
    ```

    ```diff
    @@ -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."""
    ```
- **#62997: fix(codex): keep large-request ttfb watchdog active**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#64594`, `#61778`

## Fix status

- Merged to main in PR #64594 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-07-15`.
