Skip to content

feat(agent): add bounded auto and cold fast modes - #64786

Closed
100yenadmin wants to merge 10 commits into
NousResearch:mainfrom
100yenadmin:feat/auto-fast-mode
Closed

feat(agent): add bounded auto and cold fast modes#64786
100yenadmin wants to merge 10 commits into
NousResearch:mainfrom
100yenadmin:feat/auto-fast-mode

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds bounded auto and cold policies to Hermes's existing fast mode.

Mode Request behavior
normal Normal provider tier for every request.
cold Fast during the opening window of the first logical-session turn only.
auto Fast during the opening window of every user turn.
fast Fast for every request.

The opening window defaults to 60 seconds and is configurable with
agent.fast_auto_on_seconds. Later tool-loop calls, retries, continuations,
and fallback calls start in normal mode after the window expires.

cold is based on prior logical-session transcript activity, not process
uptime. A fresh process resuming a persisted session therefore does not receive
another cold window. System-only setup history still counts as a first turn;
prior user, assistant, or tool activity does not.

The policy is resolved at the model-request boundary using an ephemeral copy of
request_overrides. It does not mutate conversation messages, system prompts,
tool schemas, or persisted overrides, preserving prompt-cache inputs.

Existing normal and fast behavior is unchanged.

How it works

flowchart LR
  A["User turn enters"] --> B{"Configured /fast mode"}

  B -->|normal| N["No fast metadata"]
  B -->|fast| F["Fast on every request"]
  B -->|auto| W["Open a turn-local window"]
  B -->|cold| C{"Prior logical-session activity?"}

  C -->|Yes| N
  C -->|No| W

  W --> I["Resolve request policy at ingress"]
  I --> H["Build request, middleware, and hooks"]
  H --> R{"Still inside cutoff at dispatch?"}

  R -->|Yes| P["Apply provider fast metadata"]
  R -->|No| S["Strip fast-only metadata"]
  F --> P

  N --> D["Dispatch model request"]
  P --> D
  S --> D

  D --> T{"Tool call, retry, or summary?"}
  T -->|Yes| I
  T -->|No| O["Return response"]

  classDef decision fill:#fff4cc,stroke:#a16207,color:#422006,stroke-width:2px;
  classDef fast fill:#dcfce7,stroke:#15803d,color:#052e16,stroke-width:2px;
  classDef normal fill:#f1f5f9,stroke:#64748b,color:#0f172a;
  classDef lifecycle fill:#e0f2fe,stroke:#0369a1,color:#082f49;
  classDef output fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px;

  class B,C,R,T decision;
  class F,W,P fast;
  class N,S normal;
  class A,I,H,D lifecycle;
  class O output;
Loading
  1. cold derives eligibility from the persisted logical-session transcript.
    Explicitly empty or system-only history is eligible; prior user, assistant,
    or tool activity is not.

TLDR- auto but only if cold so fast warmup.

  1. auto opens the same bounded window for every user turn. This concentrates
    fast-tier spend on the user-visible opening, where latency is felt most,
    without applying it indefinitely to long tool loops.

TLDR - User sends message > agent processing initial response is in fast mode and by the time it is finished and sent to user before tool callings, fast mode is turned back off for that turn and until all tool calls and final response is sent from agent (ie rapid initial response but not expensive "fast" mode turn).

  1. The request is checked twice: once at ingress and again immediately before
    provider dispatch. Slow middleware or hooks cannot accidentally carry an
    expired fast decision into the network call.
  2. Only provider request metadata changes. Conversation messages, system
    prompts, tool schemas, and persisted overrides remain stable for prompt
    caching.

Related Issue

Fixes #64785

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Added a small provider-neutral fast-mode policy with:
    • a monotonic turn-start clock;
    • inclusive cutoff behavior;
    • validated 60-second default;
    • request-local override resolution; and
    • transcript-derived cold-session eligibility.
  • Started policy resolution at conversation ingress so prompt assembly, hooks,
    and preflight work consume the same window as provider requests.
  • Re-evaluated the policy at every model-request boundary, including retries
    and later tool-loop calls.
  • Revalidated both direct Codex iteration-limit summary dispatches after request
    construction so an expired window cannot retain service_tier=priority.
  • Routed auto, cold, and fast_auto_on_seconds through AIAgent, CLI,
    messaging gateway, TUI/desktop construction, reuse, resume, and config paths.
  • Added /fast auto and /fast cold selection, persistence, status, command
    metadata, and English fallback messaging.
  • Updated the configuration schema, example config, and slash-command reference.
  • Added behavior tests for live first/second turns, restart/resume history,
    system-only and partial transcripts, cutoff timing, OpenAI/Anthropic request
    overrides, unsupported models, override preservation, and CLI/gateway/TUI
    persistence/readback.
  • Corrected the touched TUI suite's stale browser-launch mock and added a hard
    subprocess.Popen guard so a failing test cannot open a real Chrome window.

How to Test

scripts/run_tests.sh \
  tests/agent/test_fast_mode_auto.py \
  tests/cli/test_fast_command.py \
  tests/gateway/test_fast_command.py \
  tests/run_agent/test_provider_parity.py \
  tests/run_agent/test_run_agent.py \
  tests/run_agent/test_strict_api_validation.py \
  tests/test_tui_gateway_server.py

Expected: 953 tests pass.

ruff check .
python3 scripts/check-windows-footguns.py --all
git diff --check

Expected: all checks pass.

Manual examples:

agent:
  service_tier: cold  # or auto
  fast_auto_on_seconds: 60

/fast status should report the selected policy. For cold, starting a new
logical session opens one bounded fast window; resuming an existing session
does not.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched existing issues and open/closed PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this feature
  • I've run the entire test suite locally (focused 953-test suite passed; full matrix left to CI)
  • I've added tests for my changes
  • I've tested on macOS 26.4 with Python 3.14.6

Documentation & Housekeeping

  • I've updated relevant documentation and docstrings
  • I've updated cli-config.yaml.example and the dashboard config schema
  • CONTRIBUTING.md / AGENTS.md changes are N/A
  • I've considered cross-platform impact; the policy uses stdlib
    time.monotonic() and introduces no OS-specific I/O or process behavior
  • Tool descriptions/schemas are N/A

Validation

953 focused tests passed, 0 failed
344 TUI gateway tests passed without launching a debug Chrome process
Repository-wide Ruff: passed
Windows footgun scan: passed (767 Python files)
Python compile check: passed
git diff --check: passed
Adversarial P0-P2 sweep: 0 qualifying findings remain

@100yenadmin

Copy link
Copy Markdown
Contributor Author

@copilot review

Please review the latest head, with particular attention to turn-boundary timing, provider-specific request overrides, prompt-cache stability, and CLI/gateway/TUI state propagation.

@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have labels Jul 15, 2026
@100yenadmin 100yenadmin changed the title feat(agent): add turn-local auto fast mode feat(agent): add bounded auto and cold fast modes Jul 15, 2026
@100yenadmin

Copy link
Copy Markdown
Contributor Author

@copilot review

Please review the current integrated head (48f707d), especially logical-session cold eligibility, dispatch-time expiry after middleware, Anthropic fast beta preservation, and CLI/gateway/TUI state transitions.

@100yenadmin

Copy link
Copy Markdown
Contributor Author

@copilot review

Please review current head f6e4c1d. In addition to the bounded auto/cold policy, this head corrects the touched TUI test mock so browser-connect retry coverage cannot launch a real Chrome process. Please focus on session eligibility, dispatch-time expiry, provider metadata preservation, and test isolation.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the careful cross-surface implementation and the explicit prompt-cache constraints.

Problems

  • agent/chat_completion_helpers.py:1800-1803 and :1899-1905 send Codex iteration-limit summaries directly after _build_api_kwargs(). The new dispatch-time guard is only installed in agent/conversation_loop.py:1343-1359, so these direct Codex calls do not revalidate after request construction. If the cutoff expires between construction and _run_codex_stream(), the request can retain service_tier=priority, contrary to the bounded-policy guarantee.

Suggested changes

  • Revalidate the Codex summary kwargs immediately before both _run_codex_stream() calls, and add a timing regression test for that direct path.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 16, 2026
@100yenadmin

Copy link
Copy Markdown
Contributor Author

Addressed the Hermes Sweeper finding in 50b261230 on top of current main (659d1123c).

  • Both direct Codex iteration-limit summary paths now call revalidate_fast_mode_request() immediately before _run_codex_stream().
  • The primary-path regression proves kwargs built inside the window with service_tier=priority lose that tier when dispatch occurs at 160.001s.
  • The retry-path regression proves the first dispatch remains fast inside the window while a retry built inside the window loses the stale tier after expiry.
  • The complete documented validation set now passes: 953 tests, plus repository-wide Ruff, the 767-file Windows-footgun scan, compile validation, and git diff --check.

@copilot review

Please review current head 50b261230, especially both direct Codex summary dispatches and the primary/retry cutoff timing coverage.

Resolve the /fast handler conflict by integrating the bounded auto/cold
service tiers (this PR) with main's new interactive fast/normal choice
picker. Typed `/fast auto` and `/fast cold` now route through the
extended _apply_fast_selection helper and are reflected in the 4-way
status line; the interactive picker keeps the fast/normal quick-toggle
(auto/cold stay typed-only, so no new choice_* i18n keys are required).
Config writes go through main's _save_gateway_config_key (the local
_save_config_key closure is dropped).

Also mirror the auto/cold fast-mode i18n keys (label_auto, label_cold,
status_auto, status_cold) across all non-en locales so the catalog
parity test (tests/agent/test_i18n.py::test_catalog_keys_match_english)
passes — they were previously only added to en.yaml.
@100yenadmin

Copy link
Copy Markdown
Contributor Author

Superseded by #74730, which ports the bounded auto/cold policy onto current main and covers the current Relay, summary, gateway, TUI, and Desktop paths. The replacement is at exact head 5579f28e17f95fc2db4130b15c7843f55bb4bc95; its affected tests, lint, and diff checks pass, and its independent runtime/cost review passed after final-Relay-boundary and native-endpoint gating fixes. It is still awaiting maintainer approval for external-fork CI. Closing this stale conflicted branch as superseded, not as integrated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add bounded auto and cold modes to /fast

3 participants