[FEATURE] Supported per-generation admission: max-turns=1 still permits output-limit recovery requests

Status Open
Reported on v2.1.258
Maintainer reply None cached
Activity 2 comments · opened Sep 8, 2026

Request

Please provide a supported single-generation mode or synchronous before every model request admission callback in the CLI/Agent SDK, covering native output-limit recovery. We need the embedding host (Hermes) to own generation budgets and continuation decisions. This is not a request to extract OAuth tokens, patch binaries, rewrite requests via a proxy or substitute API billing.

Reproduced behavior

Unmodified native 2.1.258 and 2.1.263, macOS arm64, driven by the unchanged DirectSDK client at eafb4186. The maintained localhost recording peer returns synthetic SSE; only stop_reason changes.

| Native | end_turn | one max_tokens then end_turn | max_tokens throughout |
|---|---:|---:|---:|
|2.1.258|1 request|2 requests|4 requests then output-limit error|
|2.1.263|1 request|2 requests|4 requests then output-limit error|

These are directly observed localhost Messages requests, not inferred num_turns. Fourteen localhost requests total and zero real provider calls. Native max-turns=1, CLAUDE_CODE_MAX_RETRIES=0, native tools disabled, no session persistence, DISABLE_AUTO_COMPACT=1 and DISABLE_COMPACT=1. The output-limit path apparently differs from HTTP retry/tool-turn counting; we do not assert those flags promise otherwise.

Portable reproduction and command, script, original sanitized receipt. Receipt SHA-256: 05fd629f64c4ed3980c5516d541cf69fe683aed38703e28866e86ab2f0ba305d. The portable wrapper changes path arguments/output packaging; it is not represented as the original measured script. No model prompts, real credentials, raw sessions or live configs are needed. Native processes use a sterile temporary home, fake fixture credential, dead proxies and an OS localhost-only outbound policy. Do not remove the sandbox.

Native SHA-256:

  • 2.1.258: b63136194160791c27cfa7b0403060d85eb0752991625fde8c09f9acacb17c78
  • 2.1.263: ef5d2909c8af49f31ab6d5487e90316777bc2fac170adfe8160716caa8aaf4f9

Desired supported contract / acceptance

  1. Deny before the first generation: zero transmitted requests.
  2. Admit one, return max_tokens, deny the next: no second request is transmitted.
  3. Preserve the first partial response, usage and finish reason rather than losing them to recovery/error handling.
  4. A later explicitly authorized host step can continue from canonical history.
  5. No alternate recovery, structured-output, auxiliary or fallback path bypasses admission. Callback failure/cancellation must fail closed before sending.

A documented control satisfying that contract is welcome; we will test a specific supported candidate with the same peer. No supported before-request control was identified in the inspected public interface; this is not a universal-impossibility claim. A post-response hook or request counter cannot provide before-send admission.

Related work / deduplication

Related #84756 asks for a message-transform hook (closed duplicate #84751). #58219 asks for trace propagation. This request is specifically synchronous generation admission and forced output-limit recovery, not message rewriting or trace-only observation. Searches for max-turns/max_tokens/output recovery did not find this exact reproduction/contract.

Our own released integration also fails strict ownership; we corrected its claim and track recovery at https://github.com/100yenadmin/hermes-claude-agent-sdk/issues/21 . The upstream DirectSDK author separately reports the native-recovery boundary. We are not presenting either integration as fully qualified.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗