Skip to content

feat(caching): add provider cache writes toggle - #2407

Merged
steebchen merged 12 commits into
theopenco:mainfrom
RATCHAW:RATCHAW/api-timeout-cache-toggle
May 28, 2026
Merged

steebchen merged 12 commits into
theopenco:mainfrom
RATCHAW:RATCHAW/api-timeout-cache-toggle

Conversation

@RATCHAW

@RATCHAW RATCHAW commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a project-level "Provider Cache Writes" toggle (default on) that suppresses the gateway's automatic injection of cache_control / cachePoint markers into Anthropic and AWS Bedrock Claude requests, and strips caller-supplied markers when off. This lets users on sparse prompt patterns avoid paying the 1.25× (5m) / 2× (1h) cache-write premium when their gap between requests exceeds the cache TTL, which was the reported pain point (see Discord thread on Opus 4.7 sparse usage).

This also covers coding agents like Claude Code, Cursor, and Cline that always emit cache_control markers regardless of the user's usage pattern — without the strip, those markers would flow through unchanged and the toggle would have no effect.

Verified empirically via direct curl to api.anthropic.com that omitting the markers cleanly disables cache writes (usage.cache_creation_input_tokens=0), per Anthropic docs and AWS Bedrock docs.

Anthropic vs Bedrock cache payloads

The two providers use different wire formats for prompt caching, and the strip / auto-inject logic has to handle both:

  • Anthropic (direct + Vertex) — caching is opt-in via an inline cache_control: {"type": "ephemeral", "ttl"?: "5m"|"1h"} field on a text content block. The field sits inside the same block as the text.
  • AWS Bedrock Converse — caching is opt-in via a separate cachePoint: {"type": "default", "ttl"?: "5m"|"1h"} content block inserted after the text block it should cache. The format is unrelated to Anthropic's cache_control; {"type": "ephemeral"} is not a valid Bedrock cachePoint type and is silently ignored.
  • Bedrock InvokeModel path keeps the Anthropic-native cache_control format, but the gateway routes Bedrock Claude through Converse, so that path is not exercised here.

When the toggle is off:

  1. We strip Anthropic-style cache_control from all message content parts in prepareRequestBody so caller markers don't bleed into either provider.
  2. We gate the gateway's heuristic auto-injection (length-based 4096-char threshold) on providerCacheControlEnabled for both the Anthropic cache_control path and the Bedrock cachePoint path.
  3. We gate the turn-boundary placement (which caches the entire prefix before the last user message in multi-turn conversations) for both providers. Missing this gate on the Bedrock path was the root cause of intermittent cache writes during testing: single-turn requests behaved correctly, but Claude Code's multi-turn conversations always leaked one cachePoint per request.
  4. The Anthropic transformer also counts caller-supplied cache_control markers toward Anthropic's 4-block cap, so requests from agents that already include their own 4 markers don't trigger the "Found 5 blocks with cache_control" 400 after our turn-boundary injection.

Test plan

  • Toggle off in Project Settings → Caching → Provider Cache Writes, save, wait ~5 min for SWR cache to refresh
  • Send a long Anthropic request and confirm usage.cache_creation_input_tokens=0 in the response
  • Send a multi-turn Bedrock Claude request and confirm cache_write_tokens=0 in the activity log
  • Toggle on, repeat, confirm cache_creation_input_tokens>0 (write) then cache_read_input_tokens>0 on a follow-up call
  • Repeat for AWS Bedrock Claude (cachePoint blocks)
  • Verify Claude Code multi-turn sessions show cache_write_tokens=0 on every request with the toggle off

Summary by CodeRabbit

  • New Features

    • Project-level "Provider Cache Writes" setting in dashboard and API (defaults to enabled).
  • Behavior Changes

    • Gateway and request preparation honor the setting: strip or auto-inject provider cache markers per project and propagate to provider calls and retries.
  • Documentation

    • Caching docs updated with auto-injection behavior, TTL guidance, and how to disable provider cache writes.
  • Tests & Migrations

    • Added regression test for marker stripping and a DB migration to add the setting.

Review Change Stack

Adds a project-level toggle that suppresses the gateway's automatic
injection of cache_control / cachePoint markers into Anthropic and AWS
Bedrock Claude requests. Caller-supplied markers still pass through;
only the gateway's length-based heuristic auto-injection is gated. Lets
users on sparse prompt patterns avoid paying the 1.25x/2x cache-write
premium when their gap between requests exceeds the cache TTL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds providerCacheControlEnabled flag to project settings, persisted in the DB, exposed via API schemas/handlers, surfaced in the UI toggle, and used by the gateway to gate or strip provider-side cache markers; includes tests and docs.

Changes

Provider cache control feature

Layer / File(s) Summary
Database schema and storage
packages/db/src/schema.ts, packages/db/migrations/1779728096_needy_robbie_robertson.sql, packages/db/migrations/meta/_journal.json, packages/db/src/cache-helpers.ts
project table gains provider_cache_control_enabled boolean defaulting to true; isCachingEnabled() now returns { enabled, duration, providerCacheControlEnabled } and queries the new column.
API project routes and schemas
apps/api/src/routes/projects.ts, apps/api/src/routes/organization.ts, apps/api/src/routes/v1-master.ts
Project response/request schemas and CRUD handlers extended to accept/return providerCacheControlEnabled; PATCH handler conditionally updates the field and records audit changes; create input and DB insert updated.
UI settings form and types
apps/ui/src/types/settings.ts, apps/ui/src/components/settings/caching-settings.tsx, apps/ui/src/app/dashboard/[orgId]/[projectId]/settings/preferences/_components/caching-settings-rsc.tsx
Settings types include providerCacheControlEnabled; form Zod schema, defaults, and PATCH payload updated; new "Provider Cache Writes" toggle added and initialized from project settings.
Gateway integration and resolve-context
apps/gateway/src/chat/chat.ts, apps/gateway/src/chat/tools/resolve-provider-context.ts
Gateway reads providerCacheControlEnabled from isCachingEnabled() and forwards it into prepareRequestBody and resolveProviderContext for retry/fallback behavior.
Request preparation and Anthropic transform
packages/actions/src/prepare-request-body.ts, packages/actions/src/transform-anthropic-messages.ts
prepareRequestBody and transformAnthropicMessages accept providerCacheControlEnabled; when false, caller cache_control markers are stripped across parts and provider-side auto-injection/heuristics for Anthropic/Bedrock are disabled.
Tests and docs
packages/actions/src/prepare-request-body.spec.ts, apps/docs/content/features/caching/provider-cache-control.mdx
Adds test ensuring caller cache_control markers are stripped when provider cache writes are disabled; docs updated to describe opt-in provider cache writes and the effects of disabling the setting.

Sequence Diagram

sequenceDiagram
  participant chat as apps/gateway/src/chat/chat.ts
  participant cacheHelper as packages/db/src/cache-helpers.isCachingEnabled()
  participant prepare as packages/actions/src/prepare-request-body.ts
  participant transform as packages/actions/src/transform-anthropic-messages.ts

  chat->>cacheHelper: isCachingEnabled(project.id)
  cacheHelper-->>chat: { enabled, duration, providerCacheControlEnabled }
  chat->>prepare: prepareRequestBody(..., providerCacheControlEnabled)
  prepare->>prepare: gate or strip cache markers based on providerCacheControlEnabled
  alt provider == "anthropic"
    prepare->>transform: transformAnthropicMessages(messages, ..., providerCacheControlEnabled)
    transform->>transform: auto-inject cache_control only if providerCacheControlEnabled
  else provider == "bedrock"
    prepare->>prepare: insert cachePoint only if providerCacheControlEnabled
  end
  prepare-->>chat: final request body
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • theopenco/llmgateway#2193: Both PRs touch the gateway’s cache-control handling in request-body construction (notably prepare-request-body.ts / Anthropic→Bedrock cache_controlcachePoint behavior): the main PR gates cache writes via providerCacheControlEnabled, while the retrieved PR adds Bedrock cache-write billing/TTL mapping and related parsing.
  • theopenco/llmgateway#2201: Both PRs modify the same request-preparation pipeline (chat.tsresolve-provider-context.tspackages/actions/src/prepare-request-body.ts) by extending prepareRequestBody with additional cache-control parameters (main: providerCacheControlEnabled; retrieved: OpenAI prompt_cache_key/prompt_cache_retention), even though they target different provider-specific mechanisms.

Suggested reviewers

  • steebchen
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding a toggle to control provider cache writes, which aligns with the core objective of the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3921bd7d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 1977 to 1980
const shouldCache =
providerCacheControlEnabled &&
msg.content.length >= bedrockMinCacheableChars &&
bedrockCacheControlCount < bedrockMaxCacheControlBlocks;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Guard Bedrock turn-boundary cachePoint with toggle

The new providerCacheControlEnabled check is applied to heuristic cache-point insertion here, but later in the Bedrock branch the turn-boundary logic still adds a cachePoint whenever bedrockMessages.length >= 3 and the block limit allows it. In multi-turn Bedrock conversations with the toggle turned off, the gateway still auto-injects a cache marker and can incur cache-write charges, so the new setting does not fully disable automatic provider cache writes. The turn-boundary insertion path should be gated by the same flag.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/gateway/src/chat/chat.ts (1)

4298-4326: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Thread providerCacheControlEnabled into the retry/fallback provider context too.

The initial request body passes providerCacheControlEnabled into prepareRequestBody(...), but the retry context rebuilds provider context via resolveProviderContext(...) and prepareRequestBody(...) there doesn’t clearly show forwarding this flag (and ProviderContextOptions/options passed on retry don’t appear to include it). If retries fall back with the default, cache-control markers can be auto-injected when the toggle is off.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/gateway/src/chat/chat.ts` around lines 4298 - 4326, The retry/fallback
path is not receiving the providerCacheControlEnabled flag so rebuilt contexts
default and may inject cache-control markers; update resolveProviderContext and
the options passed into it (e.g., ProviderContextOptions used in the
retry/fallback logic) to accept providerCacheControlEnabled, and then pass that
same flag into prepareRequestBody when building the retry requestBody; ensure
the retry call sites that construct ProviderContextOptions and call
prepareRequestBody include providerCacheControlEnabled so the retry/fallback
provider honors the original cache-control toggle.
packages/actions/src/prepare-request-body.ts (1)

2031-2061: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Gate Bedrock turn-boundary cachePoint injection behind the toggle.

Line 2031 still auto-adds a cachePoint even when providerCacheControlEnabled is false. That keeps automatic cache writes active (and billable) after opting out.

Suggested fix
-			if (bedrockMessages.length >= 3) {
+			if (providerCacheControlEnabled && bedrockMessages.length >= 3) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/actions/src/prepare-request-body.ts` around lines 2031 - 2061, The
turn-boundary cachePoint injection currently runs unconditionally; wrap the
logic that finds lastUserIdx and potentially pushes createBedrockCachePoint()
behind a check of providerCacheControlEnabled so no cachePoint is added when the
toggle is false. Specifically, inside the code handling bedrockMessages
(referencing bedrockMessages, lastUserIdx, boundaryIdx, boundaryMsg, lastBlock,
createBedrockCachePoint, bedrockCacheControlCount,
bedrockMaxCacheControlBlocks), add or combine an if
(providerCacheControlEnabled) guard before computing boundaryIdx and pushing the
cache point (or skip the push when providerCacheControlEnabled is false).
🧹 Nitpick comments (1)
apps/ui/src/app/dashboard/[orgId]/[projectId]/settings/preferences/_components/caching-settings-rsc.tsx (1)

52-52: 💤 Low value

Consider adding a fallback for consistency.

The form component (line 63 of caching-settings.tsx) uses a ?? true fallback when reading this same field from initialData, but this server component passes project.providerCacheControlEnabled directly. For defensive consistency, consider:

-				providerCacheControlEnabled: project.providerCacheControlEnabled,
+				providerCacheControlEnabled: project.providerCacheControlEnabled ?? true,

This ensures the default aligns with both the database schema default and the form's fallback behavior, even if the Project type allows undefined.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/ui/src/app/dashboard/`[orgId]/[projectId]/settings/preferences/_components/caching-settings-rsc.tsx
at line 52, The server component currently passes providerCacheControlEnabled
directly from project; change it to use a defensive fallback
(project.providerCacheControlEnabled ?? true) so it matches the form's `?? true`
behavior and the DB default; update the object where providerCacheControlEnabled
is set in this file (referencing the project object and the exported value used
by the form) to use that nullish-coalescing fallback so undefined values behave
consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/gateway/src/chat/chat.ts`:
- Around line 4298-4326: The retry/fallback path is not receiving the
providerCacheControlEnabled flag so rebuilt contexts default and may inject
cache-control markers; update resolveProviderContext and the options passed into
it (e.g., ProviderContextOptions used in the retry/fallback logic) to accept
providerCacheControlEnabled, and then pass that same flag into
prepareRequestBody when building the retry requestBody; ensure the retry call
sites that construct ProviderContextOptions and call prepareRequestBody include
providerCacheControlEnabled so the retry/fallback provider honors the original
cache-control toggle.

In `@packages/actions/src/prepare-request-body.ts`:
- Around line 2031-2061: The turn-boundary cachePoint injection currently runs
unconditionally; wrap the logic that finds lastUserIdx and potentially pushes
createBedrockCachePoint() behind a check of providerCacheControlEnabled so no
cachePoint is added when the toggle is false. Specifically, inside the code
handling bedrockMessages (referencing bedrockMessages, lastUserIdx, boundaryIdx,
boundaryMsg, lastBlock, createBedrockCachePoint, bedrockCacheControlCount,
bedrockMaxCacheControlBlocks), add or combine an if
(providerCacheControlEnabled) guard before computing boundaryIdx and pushing the
cache point (or skip the push when providerCacheControlEnabled is false).

---

Nitpick comments:
In
`@apps/ui/src/app/dashboard/`[orgId]/[projectId]/settings/preferences/_components/caching-settings-rsc.tsx:
- Line 52: The server component currently passes providerCacheControlEnabled
directly from project; change it to use a defensive fallback
(project.providerCacheControlEnabled ?? true) so it matches the form's `?? true`
behavior and the DB default; update the object where providerCacheControlEnabled
is set in this file (referencing the project object and the exported value used
by the form) to use that nullish-coalescing fallback so undefined values behave
consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2cdd528a-9f12-46d1-b4f4-e48cc75ff01b

📥 Commits

Reviewing files that changed from the base of the PR and between ba9b62a and e3921bd.

⛔ Files ignored due to path filters (4)
  • apps/code/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/playground/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • apps/ui/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
  • ee/admin/src/lib/api/v1.d.ts is excluded by !**/v1.d.ts
📒 Files selected for processing (15)
  • apps/api/src/routes/organization.ts
  • apps/api/src/routes/projects.ts
  • apps/api/src/routes/v1-master.ts
  • apps/docs/content/features/caching/provider-cache-control.mdx
  • apps/gateway/src/chat/chat.ts
  • apps/ui/src/app/dashboard/[orgId]/[projectId]/settings/preferences/_components/caching-settings-rsc.tsx
  • apps/ui/src/components/settings/caching-settings.tsx
  • apps/ui/src/types/settings.ts
  • packages/actions/src/prepare-request-body.ts
  • packages/actions/src/transform-anthropic-messages.ts
  • packages/db/migrations/1779728096_needy_robbie_robertson.sql
  • packages/db/migrations/meta/1779728096_snapshot.json
  • packages/db/migrations/meta/_journal.json
  • packages/db/src/cache-helpers.ts
  • packages/db/src/schema.ts

Extends the provider cache writes toggle to also strip cache_control
markers that callers send themselves, not just suppress the gateway's
auto-injection heuristic. Without this, coding agents (Claude Code,
Cursor, Cline) would still trigger cache writes on every request
because they emit explicit markers regardless of the user's request
cadence — defeating the toggle for the actual reported use case.

Adds a regression test covering both system and user message stripping,
and updates UI/docs copy to reflect the broader semantics.

Verified end-to-end against api.anthropic.com: a 2509-token prompt with
cache_control returns cache_creation_input_tokens=2509 (write premium);
the same prompt with markers stripped returns 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/actions/src/prepare-request-body.spec.ts (1)

232-300: ⚡ Quick win

Add an AWS Bedrock counterpart for this opt-out stripping test.

This validates Anthropic well, but the same toggle contract applies to Bedrock in prepareRequestBody; adding one Bedrock case here will prevent regressions in the second provider path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/actions/src/prepare-request-body.spec.ts` around lines 232 - 300,
Add a parallel test that mirrors the Anthropic "strips caller-supplied
cache_control when providerCacheControlEnabled is false" case but uses the
Bedrock branch of prepareRequestBody: call prepareRequestBody with provider
"bedrock" (or the Bedrock model id used elsewhere in tests), include system/user
content blocks with caller-supplied cache_control entries, pass
providerCacheControlEnabled = false, and assert that the returned request body
(e.g., requestBody.prompts or the Bedrock-specific fields) has no cache_control
on any content blocks; reference prepareRequestBody and the existing Anthropic
test to copy payload shape and assertions so the Bedrock code path is exercised
the same way.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/actions/src/prepare-request-body.spec.ts`:
- Around line 286-297: The tests use force-casts `(block as any).cache_control`
in the cache-control assertions; replace these with a small typed helper to
narrow the shape safely (e.g., create a helper function like
`getCacheControl(value: unknown): unknown` or `assertNoCacheControl(value:
unknown): void`) and use it in the loops over `requestBody.system` and
`requestBody.messages` to access `cache_control` without `as any`; update the
assertions to call that helper (or narrow with a type guard) when inspecting
`block.cache_control` so the code remains type-safe while keeping the same
expectation logic for `requestBody`, `block`, and `msg` checks.

---

Nitpick comments:
In `@packages/actions/src/prepare-request-body.spec.ts`:
- Around line 232-300: Add a parallel test that mirrors the Anthropic "strips
caller-supplied cache_control when providerCacheControlEnabled is false" case
but uses the Bedrock branch of prepareRequestBody: call prepareRequestBody with
provider "bedrock" (or the Bedrock model id used elsewhere in tests), include
system/user content blocks with caller-supplied cache_control entries, pass
providerCacheControlEnabled = false, and assert that the returned request body
(e.g., requestBody.prompts or the Bedrock-specific fields) has no cache_control
on any content blocks; reference prepareRequestBody and the existing Anthropic
test to copy payload shape and assertions so the Bedrock code path is exercised
the same way.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5343ebde-9fb2-4287-a822-812e1abc64dc

📥 Commits

Reviewing files that changed from the base of the PR and between e3921bd and efa836c.

📒 Files selected for processing (4)
  • apps/docs/content/features/caching/provider-cache-control.mdx
  • apps/ui/src/components/settings/caching-settings.tsx
  • packages/actions/src/prepare-request-body.spec.ts
  • packages/actions/src/prepare-request-body.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/docs/content/features/caching/provider-cache-control.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/ui/src/components/settings/caching-settings.tsx

Comment thread packages/actions/src/prepare-request-body.spec.ts
RATCHAW and others added 6 commits May 27, 2026 17:03
Three fixes uncovered while testing the provider cache toggle:

- Bedrock turn-boundary cachePoint injection wasn't gated by
  providerCacheControlEnabled, so multi-turn conversations leaked one
  cache write per request even with the toggle off.
- transformAnthropicMessages now counts caller-supplied cache_control
  markers toward the 4-block cap; otherwise Claude Code's 4 markers plus
  our turn-boundary injection produced "Found 5" 400 errors.
- Retry path now threads providerCacheControlEnabled through
  resolveProviderContext so fallback attempts honor the toggle too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolve conflict in apps/gateway/src/chat/chat.ts: keep
providerCacheControlEnabled from isCachingEnabled (this branch)
while applying upstream's devPlan gate that disables gateway-side
response caching for dev plan organizations.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ache-toggle

# Conflicts:
#	apps/gateway/src/chat/chat.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d85e137d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3795 to +3799
const {
enabled: projectCachingEnabled,
duration: cacheDuration,
providerCacheControlEnabled,
} = await isCachingEnabled(project.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip cache lookup for dev-plan chats

For dev-plan organizations this new unconditional isCachingEnabled(project.id) call adds a second project DB dependency even though cachingEnabled is forced to false on the next line. If Postgres is unavailable and the existing swr:project:<id> mirror used by findProjectById is populated but the newly required swr:project:cachingEnabled:<id> mirror is not, dev-plan chat requests that previously proceeded will now fail before reaching the provider because isCachingEnabled rethrows on a fallback miss. The provider cache flag is already available on the fetched project, so the dev-plan branch can avoid this lookup or default from that row.

Useful? React with 👍 / 👎.

@steebchen
steebchen merged commit 87d3a35 into theopenco:main May 28, 2026
10 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.

2 participants