Skip to content

fix(agents): honor explicit long Anthropic cache TTL on custom hosts#67800

Merged
hxy91819 merged 4 commits intoopenclaw:mainfrom
MonkeyLeeT:codex/anthropic-cache-long-ttl-custom-hosts
Apr 21, 2026
Merged

fix(agents): honor explicit long Anthropic cache TTL on custom hosts#67800
hxy91819 merged 4 commits intoopenclaw:mainfrom
MonkeyLeeT:codex/anthropic-cache-long-ttl-custom-hosts

Conversation

@MonkeyLeeT
Copy link
Copy Markdown
Contributor

Summary

  • honor explicit cacheRetention: "long" for custom anthropic-messages providers when building Anthropic cache-control payloads
  • keep the existing hostname allowlist behavior for implicit or env-driven long retention so defaults remain conservative
  • add regression coverage for explicit long, explicit short, and env-driven long retention on custom hosts

Why

Custom Anthropic-compatible proxies can support 1-hour prompt-cache TTLs even when they do not use Anthropic or Vertex hostnames. OpenClaw was silently downgrading explicit cacheRetention: "long" to the default 5-minute ephemeral cache for those providers.

Closes #67164.

Root Cause

src/agents/anthropic-payload-policy.ts only emitted ttl: "1h" when cacheRetention was long and the baseUrl hostname matched a hardcoded Anthropic/Vertex allowlist. That made explicit long-retention opt-ins ineffective for custom anthropic-messages endpoints.

Behavior Change

  • explicit cacheRetention: "long" now emits cache_control: { type: "ephemeral", ttl: "1h" } even for custom hosts
  • implicit/env-driven long retention still requires an allowlisted host
  • explicit short and none behavior are unchanged

Validation

  • pnpm test src/agents/anthropic-payload-policy.test.ts

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 16, 2026
@MonkeyLeeT MonkeyLeeT changed the title [codex] Honor explicit long Anthropic cache TTL on custom hosts fix(agents): honor explicit long Anthropic cache TTL on custom hosts Apr 16, 2026
@MonkeyLeeT MonkeyLeeT marked this pull request as ready for review April 16, 2026 19:58
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Greptile Summary

This PR fixes a bug where explicit cacheRetention: "long" on custom anthropic-messages providers was silently downgraded to 5-minute ephemeral cache because the TTL gate required an allowlisted hostname. The fix adds a short-circuit: if cacheRetention is explicitly "long", the 1h TTL is applied regardless of hostname, while implicit/env-driven long retention still requires an allowlisted endpoint. The implementation is minimal and correct, with three new test cases covering explicit long, env-driven long, and explicit short retention on custom hosts.

Confidence Score: 5/5

Safe to merge — minimal, targeted fix with correct logic and comprehensive regression tests.

The logic change is provably correct across all four input cases (explicit long, env-driven long, explicit short, none). Tests cover the new behavioral paths. No P0/P1 findings.

No files require special attention.

Reviews (1): Last reviewed commit: "Merge branch 'main' into codex/anthropic..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@suboss87 suboss87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix. The distinction between explicit user opt-in vs env-driven defaults is the right call for custom proxy hosts.

One thing to watch: retention is derived from cacheRetention (possibly after env defaults), so the condition retention === "long" && (cacheRetention === "long" || isLongTtlEligibleEndpoint(baseUrl)) works correctly but the relationship between the two variables is implicit. If someone later changes how retention is resolved without updating this site, the behavior could drift. Might be worth a comment noting that cacheRetention === "long" is the "was this explicitly set by the user" check vs the env/hostname path.

The env save/restore in the test is clean. Tests look solid.

@MonkeyLeeT
Copy link
Copy Markdown
Contributor Author

@hxy91819 PTAL

@MonkeyLeeT MonkeyLeeT force-pushed the codex/anthropic-cache-long-ttl-custom-hosts branch 7 times, most recently from 5a61244 to ad9f567 Compare April 20, 2026 01:36
@mujiannan
Copy link
Copy Markdown

The security bot's concern seems overstated for this use case. When a user explicitly sets cacheRetention: "long", they've already made a deliberate configuration choice — they know they're routing traffic through a custom/proxy host and have accepted that relationship. The previous silent downgrade to 5-minute TTL is the surprising behavior here, not the fix.

The allowLongTtlOnCustomHosts flag suggestion just adds friction without meaningful security benefit: anyone who configures cacheRetention: "long" on a custom host is presumably already aware of and trusting that host. Requiring a second opt-in flag doesn't change the trust model, it just makes the feature harder to use.

Option 3 from the original issue is the right call — honor explicit user intent. The allowlist can remain as the default guard when cacheRetention is unset or "auto".

mene-crab added a commit to mene-crab/openclaw that referenced this pull request Apr 20, 2026
Cherry-pick of openclaw#67800 (ad9f567)

- Explicit cacheRetention: 'long' now emits ttl: '1h' for any host
- Implicit/env-driven long retention still requires allowlisted host
- Tests added for explicit long, implicit long, explicit short
@hxy91819 hxy91819 self-assigned this Apr 20, 2026
@hxy91819
Copy link
Copy Markdown
Member

Review: Honor explicit long Anthropic cache TTL on custom hosts

APPROVED — this is completing an already-open capability path, not introducing new behavior.

Custom anthropic-messages providers with explicit cacheRetention: "long" already emit cache_control: { type: "ephemeral" } (5-min TTL) via #59049. This PR just adds the ttl: "1h" variant that was incorrectly blocked by the hostname allowlist. The explicit-vs-implicit distinction is clean: cacheRetention === "long" bypasses the allowlist (explicit opt-in), while PI_CACHE_RETENTION=long still requires allowlist membership (conservative default preserved).


Why the gap exists — historical investigation

The allowlist and custom-provider support evolved independently:

  1. fix(agents): honor cacheRetention for custom anthropic providers #59049resolveCacheRetention() extended to admit custom-anthropic-api providers with explicit config. Door opened.
  2. 067496b129 — Policy logic refactored into anthropic-payload-policy.ts with baseUrl.includes("api.anthropic.com"). Wall built — only Anthropic official endpoints get 1h TTL.
  3. fix(cache): enable prompt cache retention for Anthropic Vertex AI #60888 — Wall upgraded to proper isLongTtlEligibleEndpoint() allowlist + Vertex AI hostnames. Window added, but the custom-anthropic-api family from step 1 was not accounted for.
  4. This PR — Adds explicit-config escape hatch. Door and wall aligned.

The gap was not an intentional security boundary — it was an alignment miss between two layers implemented at different times.


No blocking issues. Optional nice-to-have: warn-level log when ttl: "1h" is applied to a non-allowlisted endpoint, to help operators validate the configuration is intentional.

Note: Do not merge until after the next release.

hxy91819 added a commit to MonkeyLeeT/openclaw that referenced this pull request Apr 21, 2026
@hxy91819 hxy91819 force-pushed the codex/anthropic-cache-long-ttl-custom-hosts branch from bca4213 to 3852331 Compare April 21, 2026 09:43
@hxy91819 hxy91819 merged commit 4bacdc8 into openclaw:main Apr 21, 2026
9 checks passed
@hxy91819
Copy link
Copy Markdown
Member

Merged via squash.

Thanks @MonkeyLeeT!

hxy91819 added a commit that referenced this pull request Apr 21, 2026
hxy91819 added a commit that referenced this pull request Apr 21, 2026
* fix(changelog): remove duplicate entry for PR #67800

* docs(changelog): move #67800 note from Unreleased into 2026.4.20
zhongmairen pushed a commit to agencyos-cn/openclaw-bad that referenced this pull request Apr 21, 2026
* 'main' of https://github.com/openclaw/openclaw: (653 commits)
  docs(changelog): deduplicate openclaw#67800 entries in Unreleased (openclaw#69670)
  fix(agents): honor explicit long Anthropic cache TTL on custom hosts (openclaw#67800)
  fix: fix Telegram media file delivery (openclaw#69641)
  fix(media): preserve outbound attachment filenames
  fix(media): parse lowercase media directives
  fix(bluebubbles): add opt-in coalesceSameSenderDms for split-send DMs (openclaw#69258)
  fix: centralize provider thinking profiles
  docs: prepare 2026.4.20 changelog
  fix: stage ACP and Codex runtime deps
  fix(gateway): drop stale service env on reinstall
  test: add bundled channel dependency Docker smoke
  test: relax detached task recovery timing assertion
  fix: ignore placeholder shells in runtime detection (openclaw#69308)
  shell: fall back to sh when SHELL is /usr/bin/false or nologin
  fix(browser): clarify DevToolsActivePort attach failures
  fix: sanitize mcp transport warning fields
  fix: launch Windows startup gateway directly
  fix(openai-codex): normalize legacy copilot transport
  fix: narrow MCP stdio env safety filter (openclaw#69540)
  fix(mcp): block dangerous stdio env overrides
  ...
gdibble pushed a commit to gdibble/openclaw that referenced this pull request Apr 21, 2026
…penclaw#67800)

Merged via squash.

Prepared head SHA: 0ffde15
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819
gdibble pushed a commit to gdibble/openclaw that referenced this pull request Apr 21, 2026
…enclaw#69670)

* fix(changelog): remove duplicate entry for PR openclaw#67800

* docs(changelog): move openclaw#67800 note from Unreleased into 2026.4.20
medikoo pushed a commit to medikoo/openclaw that referenced this pull request Apr 24, 2026
…penclaw#67800)

Merged via squash.

Prepared head SHA: 0ffde15
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819
medikoo pushed a commit to medikoo/openclaw that referenced this pull request Apr 24, 2026
…enclaw#69670)

* fix(changelog): remove duplicate entry for PR openclaw#67800

* docs(changelog): move openclaw#67800 note from Unreleased into 2026.4.20
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…penclaw#67800)

Merged via squash.

Prepared head SHA: 0ffde15
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…enclaw#69670)

* fix(changelog): remove duplicate entry for PR openclaw#67800

* docs(changelog): move openclaw#67800 note from Unreleased into 2026.4.20
zhonghe0615 pushed a commit to zhonghe0615/openclaw that referenced this pull request May 7, 2026
…penclaw#67800)

Merged via squash.

Prepared head SHA: 0ffde15
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819
zhonghe0615 pushed a commit to zhonghe0615/openclaw that referenced this pull request May 7, 2026
…enclaw#69670)

* fix(changelog): remove duplicate entry for PR openclaw#67800

* docs(changelog): move openclaw#67800 note from Unreleased into 2026.4.20
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…penclaw#67800)

Merged via squash.

Prepared head SHA: 0ffde15
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…enclaw#69670)

* fix(changelog): remove duplicate entry for PR openclaw#67800

* docs(changelog): move openclaw#67800 note from Unreleased into 2026.4.20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow 1-hour cache TTL (cacheRetention: "long") for custom Anthropic-compatible providers

4 participants