Skip to content

fix(agent): enable prompt caching for the Anthropic CUA system prompt#2304

Open
aditya-silna wants to merge 2 commits into
browserbase:mainfrom
aditya-silna:fix/anthropic-cua-system-prompt-caching
Open

fix(agent): enable prompt caching for the Anthropic CUA system prompt#2304
aditya-silna wants to merge 2 commits into
browserbase:mainfrom
aditya-silna:fix/anthropic-cua-system-prompt-caching

Conversation

@aditya-silna

@aditya-silna aditya-silna commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Why

In AnthropicCUAClient.getAction(), the system prompt was sent as a plain string:

requestParams.system = this.userProvidedInstructions;

A CUA agent loop re-sends the identical tools + system prefix on every step, so without a cache breakpoint the full prefix is re-processed at full input price each step.

What changed

The system prompt is now sent as a content block array with cache_control:

requestParams.system = [
  {
    type: "text",
    text: this.userProvidedInstructions,
    cache_control: { type: "ephemeral" },
  },
];

Since the Anthropic API renders the prompt as toolssystemmessages, this single breakpoint caches the computer-use tool definition and the system prompt together across steps. Cache reads bill at ~0.1× input price (writes at 1.25×), so this pays for itself from the second step of any run. If the prefix is below the model's minimum cacheable size, the marker is silently ignored — no error, no premium.

Caching is transparent to model behavior; outputs are unchanged.

Testing

  • tsc --noEmit on packages/core passes.

🤖 Generated with Claude Code


Summary by cubic

Enable prompt caching for Anthropic CUA by sending the system prompt as a content block array with cache_control: { type: "ephemeral" } in getAction(). This caches the tools + system prefix across agent steps to cut input cost and latency, and adds a unit test to verify the system payload shape (cached array when instructions exist, omitted otherwise).

Written for commit b6feabf. Summary will update on new commits.

Review in cubic

Send the system prompt as a content block array with
cache_control: ephemeral instead of a plain string, so the
tools + system prefix is cached across agent steps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

This PR is from an external contributor and must be approved by a stagehand team member with write access before CI can run.
Approving the latest commit mirrors it into an internal PR owned by the approver.
If new commits are pushed later, the internal PR stays open but is marked stale until someone approves the latest external commit and refreshes it.

@github-actions github-actions Bot added external-contributor Tracks PRs mirrored from external contributor forks. external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. labels Jul 2, 2026
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b6feabf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file

Confidence score: 4/5

  • In packages/core/lib/v3/agent/AnthropicCUAClient.ts, the new system content-block payload (including cache_control) is currently untested, so a malformed request shape could slip through and cause Anthropic API call failures at runtime. Add a unit test around the mocked getAction SDK request assertions to verify this exact payload before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/lib/v3/agent/AnthropicCUAClient.ts">

<violation number="1" location="packages/core/lib/v3/agent/AnthropicCUAClient.ts:560">
P2: The new `system` content-block array with `cache_control` is not verified by any unit test, even though the codebase already mocks `getAction`'s Anthropic SDK call and asserts on request parameters. Because the API call is typed as `Record<string, unknown>` and uses `@ts-expect-error`, a regression in this shape would compile cleanly but fail at Anthropic at runtime. Adding a focused test that instantiates `AnthropicCUAClient` with non-empty `userProvidedInstructions` and asserts on the `system` field passed to `mockCreate` would be straightforward given the existing test infrastructure.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

// tools + system prefix is cached across agent steps
if (this.userProvidedInstructions) {
requestParams.system = this.userProvidedInstructions;
requestParams.system = [

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.

P2: The new system content-block array with cache_control is not verified by any unit test, even though the codebase already mocks getAction's Anthropic SDK call and asserts on request parameters. Because the API call is typed as Record<string, unknown> and uses @ts-expect-error, a regression in this shape would compile cleanly but fail at Anthropic at runtime. Adding a focused test that instantiates AnthropicCUAClient with non-empty userProvidedInstructions and asserts on the system field passed to mockCreate would be straightforward given the existing test infrastructure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/lib/v3/agent/AnthropicCUAClient.ts, line 560:

<comment>The new `system` content-block array with `cache_control` is not verified by any unit test, even though the codebase already mocks `getAction`'s Anthropic SDK call and asserts on request parameters. Because the API call is typed as `Record<string, unknown>` and uses `@ts-expect-error`, a regression in this shape would compile cleanly but fail at Anthropic at runtime. Adding a focused test that instantiates `AnthropicCUAClient` with non-empty `userProvidedInstructions` and asserts on the `system` field passed to `mockCreate` would be straightforward given the existing test infrastructure.</comment>

<file context>
@@ -554,9 +554,16 @@ export class AnthropicCUAClient extends AgentClient {
+      // tools + system prefix is cached across agent steps
       if (this.userProvidedInstructions) {
-        requestParams.system = this.userProvidedInstructions;
+        requestParams.system = [
+          {
+            type: "text",
</file context>

…lient

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. external-contributor Tracks PRs mirrored from external contributor forks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant