summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorMajor Hayden <[email protected]>2026-03-31 15:16:14 -0500
committerGitHub <[email protected]>2026-03-31 15:16:14 -0500
commit26cc924ea223cb27449b432beddb8abcfc36e65b (patch)
tree1586adcbccb191ae3ff3aa08404d68abf23fc3e8 /packages
parent4dd866d5c47f8e4db08796cfbb83bc6d5c0a8ce5 (diff)
downloadopencode-26cc924ea223cb27449b432beddb8abcfc36e65b.tar.gz
opencode-26cc924ea223cb27449b432beddb8abcfc36e65b.zip
feat: enable prompt caching and cache token tracking for google-vertex-anthropic (#20266)
Signed-off-by: Major Hayden <[email protected]>
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/provider/transform.ts1
-rw-r--r--packages/opencode/src/session/index.ts3
-rw-r--r--packages/opencode/test/provider/transform.test.ts52
-rw-r--r--packages/opencode/test/session/compaction.test.ts22
4 files changed, 78 insertions, 0 deletions
diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts
index 219200b76..c40223868 100644
--- a/packages/opencode/src/provider/transform.ts
+++ b/packages/opencode/src/provider/transform.ts
@@ -280,6 +280,7 @@ export namespace ProviderTransform {
msgs = normalizeMessages(msgs, model, options)
if (
(model.providerID === "anthropic" ||
+ model.providerID === "google-vertex-anthropic" ||
model.api.id.includes("anthropic") ||
model.api.id.includes("claude") ||
model.id.includes("anthropic") ||
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index 74506c31d..94aee14c0 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -257,6 +257,9 @@ export namespace Session {
const cacheReadInputTokens = safe(input.usage.cachedInputTokens ?? 0)
const cacheWriteInputTokens = safe(
(input.metadata?.["anthropic"]?.["cacheCreationInputTokens"] ??
+ // google-vertex-anthropic returns metadata under "vertex" key
+ // (AnthropicMessagesLanguageModel custom provider key from 'vertex.anthropic.messages')
+ input.metadata?.["vertex"]?.["cacheCreationInputTokens"] ??
// @ts-expect-error
input.metadata?.["bedrock"]?.["usage"]?.["cacheWriteInputTokens"] ??
// @ts-expect-error
diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts
index 5a1016bb7..0aee396f4 100644
--- a/packages/opencode/test/provider/transform.test.ts
+++ b/packages/opencode/test/provider/transform.test.ts
@@ -1792,6 +1792,58 @@ describe("ProviderTransform.message - cache control on gateway", () => {
},
})
})
+
+ test("google-vertex-anthropic applies cache control", () => {
+ const model = createModel({
+ providerID: "google-vertex-anthropic",
+ api: {
+ id: "google-vertex-anthropic",
+ url: "https://us-central1-aiplatform.googleapis.com",
+ npm: "@ai-sdk/google-vertex/anthropic",
+ },
+ id: "claude-sonnet-4@20250514",
+ })
+ const msgs = [
+ {
+ role: "system",
+ content: "You are a helpful assistant",
+ },
+ {
+ role: "user",
+ content: "Hello",
+ },
+ ] as any[]
+
+ const result = ProviderTransform.message(msgs, model, {}) as any[]
+
+ expect(result[0].providerOptions).toEqual({
+ anthropic: {
+ cacheControl: {
+ type: "ephemeral",
+ },
+ },
+ openrouter: {
+ cacheControl: {
+ type: "ephemeral",
+ },
+ },
+ bedrock: {
+ cachePoint: {
+ type: "default",
+ },
+ },
+ openaiCompatible: {
+ cache_control: {
+ type: "ephemeral",
+ },
+ },
+ copilot: {
+ copilot_cache_control: {
+ type: "ephemeral",
+ },
+ },
+ })
+ })
})
describe("ProviderTransform.variants", () => {
diff --git a/packages/opencode/test/session/compaction.test.ts b/packages/opencode/test/session/compaction.test.ts
index a686d7ccf..e6d715728 100644
--- a/packages/opencode/test/session/compaction.test.ts
+++ b/packages/opencode/test/session/compaction.test.ts
@@ -1199,4 +1199,26 @@ describe("session.getUsage", () => {
expect(result.tokens.total).toBe(1500)
},
)
+
+ test("extracts cache write tokens from vertex metadata key", () => {
+ const model = createModel({ context: 100_000, output: 32_000, npm: "@ai-sdk/google-vertex/anthropic" })
+ const result = Session.getUsage({
+ model,
+ usage: {
+ inputTokens: 1000,
+ outputTokens: 500,
+ totalTokens: 1500,
+ cachedInputTokens: 200,
+ },
+ metadata: {
+ vertex: {
+ cacheCreationInputTokens: 300,
+ },
+ },
+ })
+
+ expect(result.tokens.input).toBe(500)
+ expect(result.tokens.cache.read).toBe(200)
+ expect(result.tokens.cache.write).toBe(300)
+ })
})