Skip to content

fix(caching): prompt_caching.enabled toggle for strict Anthropic proxies (salvage #35862, closes #13477) - #184

Merged
hashbender merged 1 commit into
mainfrom
mirror/pr-56105
Jul 1, 2026
Merged

fix(caching): prompt_caching.enabled toggle for strict Anthropic proxies (salvage #35862, closes #13477)#184
hashbender merged 1 commit into
mainfrom
mirror/pr-56105

Conversation

@hashbender

Copy link
Copy Markdown
Owner

Summary

Adds a prompt_caching.enabled config toggle so a user on a strict Anthropic-compatible proxy (LiteLLM-style, e.g. llm.echo.tech) that injects its own cache_control markers can turn off client-side markers entirely — fixing the HTTP 400 "A maximum of 4 blocks with cache_control may be provided. Found 5" reported in NousResearch#13477 without regressing caching for every well-behaved third-party gateway.

Salvages @janrenz's PR NousResearch#35862 (the config toggle), then closes the gap it left: the disable must survive /model switches and fallback re-derivation.

Why the toggle, not a third-party strip

The original report (NousResearch#13477) proposed stripping ALL markers whenever base_url isn't anthropic.com. That matches every non-Anthropic endpoint, so it would kill caching for MiniMax, Zhipu GLM, Bedrock, Foundry, Kimi, DeepSeek — all of which anthropic_prompt_cache_policy deliberately caches on and none of which double-inject. Wrong lever. The real problem is one misbehaving proxy adding a 5th marker on top of our 4; the correct fix is a per-setup opt-out.

Changes

  • hermes_cli/config.py: add prompt_caching.enabled: true default + escape-hatch comment.
  • agent/agent_runtime_helpers.py: gate anthropic_prompt_cache_policy on enabled=false → returns (False, False) before any branch, so init, /model switch, and fallback all honor it.
  • agent/agent_init.py: keep @janrenz's isinstance hardening on the cache_ttl read; drop the now-redundant init-only override (the policy gate covers it).
  • tests/: policy-level kill-switch tests (native / OpenRouter / third-party / model-switch survival / enabled-true-keeps-caching) + @janrenz's init test.
  • website/docs/: document the enabled toggle.
  • scripts/release.py: AUTHOR_MAP entry for @janrenz.

Root cause

Client never exceeds 4 markers on native Anthropic (traced E2E: apply_anthropic_cache_control marks system + last-3, tool-merge collapses them 1:1). The proxy adds a 5th server-side. The only client-side lever that helps is not sending markers to that proxy — a config toggle.

Validation

path enabled=false enabled=true (default)
native Anthropic (False, False) (True, True)
OpenRouter Claude (False, False) (True, False)
third-party proxy (False, False) (True, True)
after /model switch (False, False) policy-derived
after fallback swap (False, False) policy-derived

E2E confirmed the disable survives all three re-derivation paths and re-enabling restores caching. test_anthropic_prompt_cache_policy.py 29/29 green; test_run_agent.py caching subset 9/9 green.

Closes NousResearch#13477 (via the toggle, not the proposed strip). Salvages NousResearch#35862 with authorship preserved.

Infographic

prompt caching kill switch


Mirror-of: NousResearch#56105
NousResearch#56105

@tenki-reviewer

tenki-reviewer Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Complete
No issues found!

Risk: 🟢 Low (15/100) — no findings · 199 LOC across 8 files


This PR adds a prompt_caching kill-switch config key and cleans up moa trace config entries from DEFAULT_CONFIG. No defects found — all 4 flagged candidates were correctly rejected by the verifier as false positives (redundant type guards that are actually load-bearing, pre-existing doc-code drift, and .get() fallback patterns).

Files Reviewed (8 files)
agent/agent_init.py
agent/agent_runtime_helpers.py
hermes_cli/config.py
scripts/release.py
tests/run_agent/test_anthropic_prompt_cache_policy.py
tests/run_agent/test_run_agent.py
website/docs/developer-guide/context-compression-and-caching.md
website/docs/user-guide/configuration.md

@hashbender
hashbender merged commit e756f52 into main Jul 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant