Skip to content

fix(anthropic): prompt-cache breakpoints + accounting parity for the direct-Anthropic path - #1141

Merged
murdore merged 1 commit into
releasefrom
fix/anthropic-prompt-cache-parity
Jul 10, 2026
Merged

murdore merged 1 commit into
releasefrom
fix/anthropic-prompt-cache-parity

Conversation

@murdore

@murdore murdore commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The native Vertex+Claude path has had full prompt caching since 9.79.1 (applyVertexAnthropicCacheBreakpoints: system + tools + rolling history markers, cache-token capture, discounted pricing). The direct anthropic provider was left behind in three ways:

  1. No rolling history breakpoints. Only the system prompt (via MessageBuilder) and the last tool definition (via GenerationHandler) carry cache_control — the growing, tool-result-heavy conversation history falls after the last marker and is re-billed at full input price on every turn.
  2. generate()-path cache accounting silently dropped. The native V3 delegating model reports cache reads/writes only through ai@6's normalized usage shape — flat cachedInputTokens and nested inputTokenDetails.{cacheReadTokens,cacheWriteTokens} (asLanguageModelUsage()) — none of which extractCacheReadTokens/extractCacheCreationTokens recognized. Caching happened and Anthropic billed the discount, but NeuroLink reported the cache tokens as undefined. (Bedrock hits the same GenerationHandler path.)
  3. stream()-path cache accounting never attempted. executeStream() accumulated only input_tokens/output_tokens off message_start; cache_read_input_tokens/cache_creation_input_tokens on the same event were never read.

Fix

  • utils/anthropicCacheBreakpoints.ts — new applyAnthropicHistoryCacheBreakpoints() (rolling tail markers for paths whose stable-prefix markers are managed upstream) + countAnthropicCacheMarkers(). The count feeds the budget so a request can never exceed Anthropic's four-marker cap — critical on the direct path, where the AI-SDK pipeline has already placed system/tool markers before the provider sees the request. Already-marked tail blocks are skipped without consuming budget, so per-step re-application stays idempotent. applyVertexAnthropicCacheBreakpoints is untouched (all 34 existing tests pass unchanged).
  • providers/anthropic.ts — doGenerate and the executeStream step loop apply the history breakpoints (re-applied per step, mirroring the Vertex loops); executeStream now accumulates cache reads/writes and threads them through resolveUsage into the OTel span (gen_ai.usage.cached_input_tokens) and calculateCost (which already prices cacheReadTokens/cacheCreationTokens).
  • utils/tokenUtils.ts + types/common.ts — extractors recognize the ai@6 shapes; legacy field names keep precedence, so no behavior change for any existing provider.

Tests

Extended test/continuous-test-suite-cache-breakpoints.ts (pnpm run test:cache): 47/47 pass — 13 new assertions covering marker counting, budget clamping (incl. zero/negative), newest-first placement, purity, idempotent re-application, and the ai@6 extraction shapes.

Origin

Found while investigating cached-token accounting for curator (Claude-on-Vertex works today; this brings the currently-dormant direct-Anthropic path to parity before anyone switches to it, e.g. for OAuth/Claude-subscription access).

Summary by CodeRabbit

  • New Features

    • Added Anthropic prompt caching across standard and multi-step streaming requests.
    • Improved cache breakpoint handling for ongoing conversations while respecting existing cache markers.
    • Added support for reporting cache read and cache creation token usage.
  • Bug Fixes

    • Updated token accounting and cost calculations to include cached input tokens.
    • Improved compatibility with normalized provider usage formats for cache metrics.

…direct-Anthropic path

The native Vertex+Claude path has had full prompt caching since 9.79.1;
the direct anthropic provider was left behind in three ways:

1. No rolling history breakpoints: only the system prompt (MessageBuilder)
   and last tool (GenerationHandler) carried cache_control, so the growing
   conversation history fell after the last marker and was re-billed at
   full input price every turn. doGenerate and executeStream now apply
   applyAnthropicHistoryCacheBreakpoints, counting pre-existing markers
   via countAnthropicCacheMarkers so a request can never exceed
   Anthropic's four-marker cap.

2. generate()-path cache accounting silently dropped: the native V3 model
   reports cache tokens only through ai@6's normalized usage shape
   (cachedInputTokens / inputTokenDetails.{cacheReadTokens,cacheWriteTokens}),
   which extractCacheReadTokens/extractCacheCreationTokens did not
   recognize. Both extractors (and RawUsageObject) now do; legacy field
   names keep precedence. Also unblocks Bedrock on the same path.

3. stream()-path cache accounting never attempted: executeStream now
   accumulates cache_read_input_tokens/cache_creation_input_tokens off
   message_start events and threads them through resolveUsage into the
   OTel span and cost calculation.
Copilot AI review requested due to automatic review settings July 10, 2026 04:05
@vercel

vercel Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
neurolink Ready Ready Preview, Comment Jul 10, 2026 4:05am

@github-actions

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: 5c053229dcd2c65e1e5970c7a1476e6fa76ca25c
  • Message: fix(anthropic): prompt-cache breakpoints + accounting parity for the direct-Anthropic path
  • Author: Sachin Sharma

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Anthropic requests now apply rolling history cache breakpoints in non-streaming and multi-step streaming flows. Cache read/write tokens are extracted, included in cost and usage totals, and represented in shared usage types with expanded test coverage.

Changes

Anthropic cache integration

Layer / File(s) Summary
Cache breakpoint and usage contracts
src/lib/utils/anthropicCacheBreakpoints.ts, src/lib/types/common.ts, src/lib/utils/tokenUtils.ts
Adds the four-marker budget, marker counting and history breakpoint helpers, normalized cache-token fields, deferred usage typing, and additional cache read/write extraction paths.
Anthropic request and stream accounting
src/lib/providers/anthropic.ts, src/lib/providers/openaiChatCompletionsClient.ts
Applies cached messages to direct and streaming Anthropic requests, accumulates cache usage, includes it in cost and deferred usage totals, and reuses DeferredUsage.
Cache behavior validation
test/continuous-test-suite-cache-breakpoints.ts
Tests marker budgeting, newest-message placement, input purity, idempotency, and normalized cache-token extraction.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: Tara-ag

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR changes prompt-caching and token accounting, but linked issue #39 requires logging consolidation and debug-flag control. Align the PR with issue #39 by implementing the logging consolidation, debug flag support, and console.log migration, or relink the correct issue.
Out of Scope Changes check ⚠️ Warning The entire changeset is unrelated to the directly linked logging issue and introduces prompt-caching work instead. Remove the unrelated Anthropic caching changes or update the linked issue to match the intended prompt-caching work.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: Anthropic prompt-cache breakpoint and accounting parity.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/anthropic-prompt-cache-parity

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.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

Copilot AI 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.

Pull request overview

This PR brings the direct Anthropic provider path up to parity with the existing Vertex+Claude prompt-caching behavior by adding rolling history cache breakpoints (under Anthropic’s 4-marker cap) and ensuring cache read/write tokens are correctly extracted and propagated through both generate and stream usage/cost accounting.

Changes:

  • Added direct-Anthropic rolling history cache breakpoints and marker counting/budgeting utilities.
  • Extended cache token extraction to recognize AI SDK v6 normalized usage shapes (cachedInputTokens + inputTokenDetails cacheRead/cacheWrite).
  • Updated Anthropic streaming usage aggregation to include cache read/write tokens; added regression tests covering direct path behavior and extraction shapes.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/continuous-test-suite-cache-breakpoints.ts Adds coverage for direct-Anthropic marker budgeting/idempotence and ai@6 cache token extraction.
src/lib/utils/tokenUtils.ts Extends cache read/write extractors to recognize ai@6 normalized usage shapes.
src/lib/utils/anthropicCacheBreakpoints.ts Introduces marker counting and history-only breakpoint application for direct Anthropic requests, respecting the 4-marker cap.
src/lib/types/common.ts Adds ai@6 cache fields to RawUsageObject and introduces a DeferredUsage type supporting optional cache fields.
src/lib/providers/openaiChatCompletionsClient.ts Updates deferred analytics typing to use DeferredUsage.
src/lib/providers/anthropic.ts Applies direct-path history breakpoints in generate/stream paths and accumulates cache reads/writes for streaming usage/cost/OTel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1451 to +1455
const thinking = options.providerOptions?.anthropic?.thinking as
| { type: "enabled"; budget_tokens: number }
| undefined;

// Prompt-cache parity with the native Vertex+Claude path: upstream
Comment on lines +1463 to +1471
const cacheMarkersUsed = countAnthropicCacheMarkers({
system,
tools,
messages: messages as unknown as VertexAnthropicMessage[],
});
const cachedMessages = applyAnthropicHistoryCacheBreakpoints(
messages as unknown as VertexAnthropicMessage[],
ANTHROPIC_MAX_CACHE_BREAKPOINTS - cacheMarkersUsed,
) as unknown as Anthropic.Messages.MessageParam[];
Comment on lines +1824 to +1832
const cacheMarkersUsed = countAnthropicCacheMarkers({
system: payload.system,
tools: anthropicTools,
messages: conversation as unknown as VertexAnthropicMessage[],
});
const cachedConversation = applyAnthropicHistoryCacheBreakpoints(
conversation as unknown as VertexAnthropicMessage[],
ANTHROPIC_MAX_CACHE_BREAKPOINTS - cacheMarkersUsed,
) as unknown as Anthropic.Messages.MessageParam[];

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/continuous-test-suite-cache-breakpoints.ts (1)

495-534: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tests only validate extraction in isolation — doesn't cover the extractTokenUsage() cost-calculation flow.

These assertions correctly validate extractCacheReadTokens/extractCacheCreationTokens in isolation, but none of them combine an inclusive inputTokens value with cachedInputTokens/inputTokenDetails in a single usage object run through extractTokenUsage() — the path where the double-counting concern flagged in tokenUtils.ts (extractCacheCreationTokens/extractCacheReadTokens, lines 100-156) would actually surface. Once that concern is resolved, consider adding an end-to-end extractTokenUsage() case with both fields present to lock in the fix.

🤖 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 `@test/continuous-test-suite-cache-breakpoints.ts` around lines 495 - 534, The
cache extraction tests do not cover the full cost-calculation path through
extractTokenUsage(). Extend testAi6CacheUsageExtraction with an end-to-end usage
object containing inclusive inputTokens plus cachedInputTokens or
inputTokenDetails cache fields, and assert the resulting token usage prevents
double-counting while preserving cache read/creation values. Use
extractTokenUsage() rather than testing only extractCacheReadTokens() and
extractCacheCreationTokens().
🤖 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 `@src/lib/utils/tokenUtils.ts`:
- Around line 94-98: The token extraction and pricing logic must treat ai@6
cache token fields as subsets of total input, not additive tokens. Update the
relevant functions in tokenUtils.ts, including the cache extraction and
calculateCost paths, to subtract cachedInputTokens,
inputTokenDetails.cacheReadTokens, and inputTokenDetails.cacheWriteTokens from
inputTokens before pricing, while preserving existing provider-specific
handling.

---

Nitpick comments:
In `@test/continuous-test-suite-cache-breakpoints.ts`:
- Around line 495-534: The cache extraction tests do not cover the full
cost-calculation path through extractTokenUsage(). Extend
testAi6CacheUsageExtraction with an end-to-end usage object containing inclusive
inputTokens plus cachedInputTokens or inputTokenDetails cache fields, and assert
the resulting token usage prevents double-counting while preserving cache
read/creation values. Use extractTokenUsage() rather than testing only
extractCacheReadTokens() and extractCacheCreationTokens().
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 44e24e76-a94b-4b2b-ae8f-f6c66d93df63

📥 Commits

Reviewing files that changed from the base of the PR and between 466f543 and 5c05322.

📒 Files selected for processing (6)
  • src/lib/providers/anthropic.ts
  • src/lib/providers/openaiChatCompletionsClient.ts
  • src/lib/types/common.ts
  • src/lib/utils/anthropicCacheBreakpoints.ts
  • src/lib/utils/tokenUtils.ts
  • test/continuous-test-suite-cache-breakpoints.ts

Comment on lines 94 to +98
/**
* Extract cache creation token count from various provider formats
* Supports: cacheCreationInputTokens, cacheCreationTokens
* Supports: cacheCreationInputTokens, cacheCreationTokens, and the ai@6
* normalized `inputTokenDetails.cacheWriteTokens` (the only shape the native
* direct-Anthropic path reports through generateText).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== tokenUtils.ts ==\n'
sed -n '1,240p' src/lib/utils/tokenUtils.ts

printf '\n== search extractInputTokens / calculateCost usages ==\n'
rg -n "extractInputTokens|calculateCost|extractCacheReadTokens|extractCacheCreationTokens|cachedInputTokens|inputTokenDetails|cacheReadTokens|cacheWriteTokens" src/lib -S

Repository: juspay/neurolink

Length of output: 26702


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== ai sdk anthopic source/docs search terms ==\n'
rg -n "cacheReadTokens|cacheWriteTokens|cachedInputTokens|inputTokens.*cache|inputTokenDetails|LanguageModelUsage" . -S

Repository: juspay/neurolink

Length of output: 21836


🌐 Web query:

AI SDK 6 Anthropic inputTokens inputTokenDetails cacheReadTokens cacheWriteTokens inclusive exclusive semantics

💡 Result:

In the Vercel AI SDK (version 6 and later), token usage reporting for Anthropic has been standardized to use the provider-agnostic usage object, moving away from provider-specific metadata fields [1]. Key components of the usage object related to Anthropic prompt caching are found within result.usage.inputTokenDetails [2][1][3][4]: - cacheReadTokens: Represents the number of input tokens served from the cache (cache hit) [1][5][3]. - cacheWriteTokens: Represents the number of input tokens written to the cache (cache creation/miss) [1][5][3]. - noCacheTokens: Represents the number of input tokens that were not cached [3]. These values are accessible directly from the usage object returned by generateText and streamText [1][4]. The AI SDK previously exposed cache creation tokens via providerMetadata.anthropic (as cacheCreationInputTokens), but this field was removed to unify the interface across all providers [1]. Regarding semantics: - The inputTokens total in the usage object generally reflects the total number of tokens processed [6]. - Cache read and cache write tokens are distinct; the first turn often involves cacheWriteTokens > 0 (and cacheReadTokens = 0), while subsequent turns with a byte-stable prefix will show cacheReadTokens > 0 [5]. - "Inclusive" or "exclusive" phrasing is not standard terminology for these fields in the SDK; rather, these fields are additive components that categorize the total inputTokens (i.e., inputTokens ≈ noCacheTokens + cacheReadTokens + cacheWriteTokens) [6][3]. For implementation, you set cache breakpoints using providerOptions in your message content [4]: { providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' } } } } [4]

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '730,770p' src/lib/utils/pricing.ts
printf '\n== relevant tokenUtils block ==\n'
sed -n '236,320p' src/lib/utils/tokenUtils.ts
printf '\n== tests around cache breakpoints ==\n'
sed -n '470,525p' test/continuous-test-suite-cache-breakpoints.ts

Repository: juspay/neurolink

Length of output: 6499


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== src/lib/types/common.ts slice ==\n'
sed -n '330,390p' src/lib/types/common.ts

printf '\n== test/continuous-test-suite-cache-breakpoints.ts slice ==\n'
sed -n '490,535p' test/continuous-test-suite-cache-breakpoints.ts

printf '\n== GenerationHandler usage/cost slice ==\n'
sed -n '650,950p' src/lib/core/modules/GenerationHandler.ts

Repository: juspay/neurolink

Length of output: 14236


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('test/continuous-test-suite-cache-breakpoints.ts')
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
    if 525 <= i <= 575:
        print(f"{i}: {line}")
PY

Repository: juspay/neurolink

Length of output: 715


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('test/continuous-test-suite-cache-breakpoints.ts')
for i, line in enumerate(p.read_text().splitlines(), 1):
    if 525 <= i <= 575:
        print(f"{i}: {line}")
PY

Repository: juspay/neurolink

Length of output: 715


Treat ai@6 cache tokens as overlapping with inputTokens
inputTokens is the inclusive total for the direct-Anthropic generateText shape, so cachedInputTokens, inputTokenDetails.cacheReadTokens, and inputTokenDetails.cacheWriteTokens need to be removed from input before pricing. As written, they’re handled like additive buckets and calculateCost will bill the cached/write portion twice.

🤖 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 `@src/lib/utils/tokenUtils.ts` around lines 94 - 98, The token extraction and
pricing logic must treat ai@6 cache token fields as subsets of total input, not
additive tokens. Update the relevant functions in tokenUtils.ts, including the
cache extraction and calculateCost paths, to subtract cachedInputTokens,
inputTokenDetails.cacheReadTokens, and inputTokenDetails.cacheWriteTokens from
inputTokens before pricing, while preserving existing provider-specific
handling.

@Tara-ag Tara-ag 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.

Review Summary

Files reviewed: 6 changed files, processed one at a time.
New issues raised: 2 (both MINOR/SUGGESTION, non-blocking).

Findings

  1. src/lib/providers/anthropic.ts (line ~1812) — 💡 The inline comment claims conversation itself is never mutated, but the loop later pushes assistant/tool turns into it. The breakpoint helper is indeed pure (it clones), so re-counting stays stable; the wording just needs to credit the helper rather than the mutable array.

  2. src/lib/providers/openaiChatCompletionsClient.ts (line ~643) — 💡 Consolidating the deferred-usage shape into the new DeferredUsage type is good. Since openaiChatCompletionsBase.ts consumes createDeferredAnalytics and currently resolves only the three required fields, cache reads/writes can still be dropped for OpenAI-compatible providers. Suggest a follow-up to plumb cache fields through runStreamLoop when providers populate them.

Blocking assessment

  • No hardcoded secrets or credentials.
  • No security vulnerabilities (injection, SSRF, unsafe eval, etc.).
  • No breaking changes to the public SDK API (DeferredUsage and the new optional RawUsageObject fields are additive).
  • No violations of non-negotiable CLAUDE.md Critical Rules enforced outside CI (dynamic imports, Gemini/tools+schema mutual exclusion, CLI/SDK separation, formatProviderError return contract, backward compatibility).
  • The Anthropic cache-marker budget logic correctly respects Anthropic’s four-marker cap and is idempotent across multi-step loops.
  • Cache token accounting in both doGenerate and executeStream matches Anthropic’s separate cache-read/cache-write reporting and feeds calculateCost correctly.

Decision: Approve. The two comments are minor clarity/follow-up notes and do not block merge.

const conversation = payload.messages.slice();
let totalInput = 0;
let totalOutput = 0;
let totalCacheRead = 0;

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.

💡 The comment claims conversation itself is never mutated, but the loop later calls conversation.push(...) twice per tool step. The breakpoint helper is pure (it clones the array), but the statement about conversation is misleading. Consider rephrasing to clarify that the helper’s purity is what keeps re-counting stable, e.g.:

// Pure: applyAnthropicHistoryCacheBreakpoints clones `conversation`,
// so re-counting the original array at the top of each step stays stable.

completionTokens: number;
totalTokens: number;
}>((r) => {
let resolveUsage: (u: DeferredUsage) => void = () => {};

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.

💡 The new DeferredUsage type is a good consolidation. Just confirming: createDeferredAnalytics is also consumed by openaiChatCompletionsBase.ts (via this module). The base class currently resolves usage with only promptTokens/completionTokens/totalTokens. Since DeferredUsage now carries optional cache fields, consider whether openaiChatCompletionsBase.runStreamLoop should forward cache values when providers populate them. Not blocking for this PR, but worth a follow-up so OpenAI-compatible cache reads aren't dropped at the resolve boundary.

@murdore
murdore merged commit 66df1ae into release Jul 10, 2026
18 checks passed
@murdore
murdore deleted the fix/anthropic-prompt-cache-parity branch July 10, 2026 13:27
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.86.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

This branch was successfully deployed

1 active deployment
Preview — 5c053229 Deployed Jul 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants