Skip to content

Commit 9eaf023

Browse files
authored
Update gemini caching for open router and cline provider (RooCodeInc#3260)
* gemini caching * changeset
1 parent cf9ce1d commit 9eaf023

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

.changeset/quiet-cups-tie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": minor
3+
---
4+
5+
updated gemini caching for OR and cline provider

src/api/transform/openrouter-stream.ts

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export async function createOpenRouterStream(
2121

2222
// prompt caching: https://openrouter.ai/docs/prompt-caching
2323
// this was initially specifically for claude models (some models may 'support prompt caching' automatically without this)
24-
// gemini models only use the last breakpoint for caching, so the others will be ignored
24+
// includes custom support for gemini which does not have iterative caching
2525
switch (model.id) {
2626
case "anthropic/claude-3.7-sonnet":
2727
case "anthropic/claude-3.7-sonnet:beta":
@@ -40,10 +40,6 @@ export async function createOpenRouterStream(
4040
case "anthropic/claude-3-haiku:beta":
4141
case "anthropic/claude-3-opus":
4242
case "anthropic/claude-3-opus:beta":
43-
case "google/gemini-2.5-pro-preview-03-25":
44-
case "google/gemini-2.0-flash-001":
45-
case "google/gemini-flash-1.5":
46-
case "google/gemini-pro-1.5":
4743
openAiMessages[0] = {
4844
role: "system",
4945
content: [
@@ -75,6 +71,52 @@ export async function createOpenRouterStream(
7571
}
7672
})
7773
break
74+
case "google/gemini-2.5-pro-preview-03-25":
75+
case "google/gemini-2.0-flash-001":
76+
case "google/gemini-flash-1.5":
77+
case "google/gemini-pro-1.5":
78+
// gemini only uses the last breakpoint for caching, so the others will be ignored
79+
openAiMessages[0] = {
80+
role: "system",
81+
content: [
82+
{
83+
type: "text",
84+
text: systemPrompt,
85+
// @ts-ignore-next-line
86+
cache_control: { type: "ephemeral" },
87+
},
88+
],
89+
}
90+
91+
const GEMINI_CACHE_USER_MESSAGE_INTERVAL = 4 // add new breakpoint every 4 turns
92+
const userMessages = openAiMessages.filter((msg) => msg.role === "user")
93+
94+
const userMessageCount = userMessages.length
95+
const targetUserMessageNumber =
96+
Math.floor(userMessageCount / GEMINI_CACHE_USER_MESSAGE_INTERVAL) * GEMINI_CACHE_USER_MESSAGE_INTERVAL
97+
98+
if (targetUserMessageNumber > 0) {
99+
// otherwise dont need to add a breakpoint
100+
const msg = userMessages[targetUserMessageNumber - 1]
101+
102+
if (msg) {
103+
if (typeof msg.content === "string") {
104+
msg.content = [{ type: "text", text: msg.content }]
105+
}
106+
if (Array.isArray(msg.content)) {
107+
// NOTE: this is fine since env details will always be added at the end. but if it weren't there, and the user added a image_url type message, it would pop a text part before it and then move it after to the end.
108+
let lastTextPart = msg.content.filter((part) => part.type === "text").pop()
109+
110+
if (!lastTextPart) {
111+
lastTextPart = { type: "text", text: "..." }
112+
msg.content.push(lastTextPart)
113+
}
114+
// @ts-ignore-next-line
115+
lastTextPart["cache_control"] = { type: "ephemeral" }
116+
}
117+
}
118+
}
119+
break
78120
default:
79121
break
80122
}

0 commit comments

Comments
 (0)