Skip to content

Commit ad4782b

Browse files
authored
Add an option to enable prompt caching (#2924)
1 parent 31600ed commit ad4782b

File tree

21 files changed

+127
-12
lines changed

21 files changed

+127
-12
lines changed

src/exports/roo-code.d.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type ProviderSettings = {
3636
supportsImages?: boolean | undefined
3737
supportsComputerUse?: boolean | undefined
3838
supportsPromptCache: boolean
39+
isPromptCacheOptional?: boolean | undefined
3940
inputPrice?: number | undefined
4041
outputPrice?: number | undefined
4142
cacheWritesPrice?: number | undefined
@@ -68,6 +69,7 @@ type ProviderSettings = {
6869
supportsImages?: boolean | undefined
6970
supportsComputerUse?: boolean | undefined
7071
supportsPromptCache: boolean
72+
isPromptCacheOptional?: boolean | undefined
7173
inputPrice?: number | undefined
7274
outputPrice?: number | undefined
7375
cacheWritesPrice?: number | undefined
@@ -120,6 +122,7 @@ type ProviderSettings = {
120122
supportsImages?: boolean | undefined
121123
supportsComputerUse?: boolean | undefined
122124
supportsPromptCache: boolean
125+
isPromptCacheOptional?: boolean | undefined
123126
inputPrice?: number | undefined
124127
outputPrice?: number | undefined
125128
cacheWritesPrice?: number | undefined
@@ -175,6 +178,7 @@ type ProviderSettings = {
175178
supportsImages?: boolean | undefined
176179
supportsComputerUse?: boolean | undefined
177180
supportsPromptCache: boolean
181+
isPromptCacheOptional?: boolean | undefined
178182
inputPrice?: number | undefined
179183
outputPrice?: number | undefined
180184
cacheWritesPrice?: number | undefined
@@ -206,6 +210,7 @@ type ProviderSettings = {
206210
supportsImages?: boolean | undefined
207211
supportsComputerUse?: boolean | undefined
208212
supportsPromptCache: boolean
213+
isPromptCacheOptional?: boolean | undefined
209214
inputPrice?: number | undefined
210215
outputPrice?: number | undefined
211216
cacheWritesPrice?: number | undefined
@@ -231,11 +236,12 @@ type ProviderSettings = {
231236
modelMaxTokens?: number | undefined
232237
modelMaxThinkingTokens?: number | undefined
233238
includeMaxTokens?: boolean | undefined
234-
modelTemperature?: (number | null) | undefined
235239
reasoningEffort?: ("low" | "medium" | "high") | undefined
236-
rateLimitSeconds?: number | undefined
240+
promptCachingEnabled?: boolean | undefined
237241
diffEnabled?: boolean | undefined
238242
fuzzyMatchThreshold?: number | undefined
243+
modelTemperature?: (number | null) | undefined
244+
rateLimitSeconds?: number | undefined
239245
fakeAi?: unknown | undefined
240246
}
241247

src/exports/types.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type ProviderSettings = {
3737
supportsImages?: boolean | undefined
3838
supportsComputerUse?: boolean | undefined
3939
supportsPromptCache: boolean
40+
isPromptCacheOptional?: boolean | undefined
4041
inputPrice?: number | undefined
4142
outputPrice?: number | undefined
4243
cacheWritesPrice?: number | undefined
@@ -69,6 +70,7 @@ type ProviderSettings = {
6970
supportsImages?: boolean | undefined
7071
supportsComputerUse?: boolean | undefined
7172
supportsPromptCache: boolean
73+
isPromptCacheOptional?: boolean | undefined
7274
inputPrice?: number | undefined
7375
outputPrice?: number | undefined
7476
cacheWritesPrice?: number | undefined
@@ -121,6 +123,7 @@ type ProviderSettings = {
121123
supportsImages?: boolean | undefined
122124
supportsComputerUse?: boolean | undefined
123125
supportsPromptCache: boolean
126+
isPromptCacheOptional?: boolean | undefined
124127
inputPrice?: number | undefined
125128
outputPrice?: number | undefined
126129
cacheWritesPrice?: number | undefined
@@ -176,6 +179,7 @@ type ProviderSettings = {
176179
supportsImages?: boolean | undefined
177180
supportsComputerUse?: boolean | undefined
178181
supportsPromptCache: boolean
182+
isPromptCacheOptional?: boolean | undefined
179183
inputPrice?: number | undefined
180184
outputPrice?: number | undefined
181185
cacheWritesPrice?: number | undefined
@@ -207,6 +211,7 @@ type ProviderSettings = {
207211
supportsImages?: boolean | undefined
208212
supportsComputerUse?: boolean | undefined
209213
supportsPromptCache: boolean
214+
isPromptCacheOptional?: boolean | undefined
210215
inputPrice?: number | undefined
211216
outputPrice?: number | undefined
212217
cacheWritesPrice?: number | undefined
@@ -232,11 +237,12 @@ type ProviderSettings = {
232237
modelMaxTokens?: number | undefined
233238
modelMaxThinkingTokens?: number | undefined
234239
includeMaxTokens?: boolean | undefined
235-
modelTemperature?: (number | null) | undefined
236240
reasoningEffort?: ("low" | "medium" | "high") | undefined
237-
rateLimitSeconds?: number | undefined
241+
promptCachingEnabled?: boolean | undefined
238242
diffEnabled?: boolean | undefined
239243
fuzzyMatchThreshold?: number | undefined
244+
modelTemperature?: (number | null) | undefined
245+
rateLimitSeconds?: number | undefined
240246
fakeAi?: unknown | undefined
241247
}
242248

src/schemas/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export const modelInfoSchema = z.object({
104104
supportsImages: z.boolean().optional(),
105105
supportsComputerUse: z.boolean().optional(),
106106
supportsPromptCache: z.boolean(),
107+
isPromptCacheOptional: z.boolean().optional(),
107108
inputPrice: z.number().optional(),
108109
outputPrice: z.number().optional(),
109110
cacheWritesPrice: z.number().optional(),
@@ -398,11 +399,12 @@ export const providerSettingsSchema = z.object({
398399
modelMaxThinkingTokens: z.number().optional(),
399400
// Generic
400401
includeMaxTokens: z.boolean().optional(),
401-
modelTemperature: z.number().nullish(),
402402
reasoningEffort: reasoningEffortsSchema.optional(),
403-
rateLimitSeconds: z.number().optional(),
403+
promptCachingEnabled: z.boolean().optional(),
404404
diffEnabled: z.boolean().optional(),
405405
fuzzyMatchThreshold: z.number().optional(),
406+
modelTemperature: z.number().nullish(),
407+
rateLimitSeconds: z.number().optional(),
406408
// Fake AI
407409
fakeAi: z.unknown().optional(),
408410
})
@@ -489,11 +491,12 @@ const providerSettingsRecord: ProviderSettingsRecord = {
489491
modelMaxThinkingTokens: undefined,
490492
// Generic
491493
includeMaxTokens: undefined,
492-
modelTemperature: undefined,
493494
reasoningEffort: undefined,
494-
rateLimitSeconds: undefined,
495+
promptCachingEnabled: undefined,
495496
diffEnabled: undefined,
496497
fuzzyMatchThreshold: undefined,
498+
modelTemperature: undefined,
499+
rateLimitSeconds: undefined,
497500
// Fake AI
498501
fakeAi: undefined,
499502
// X.AI (Grok)

src/shared/api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ export const geminiModels = {
683683
contextWindow: 1_048_576,
684684
supportsImages: true,
685685
supportsPromptCache: false,
686+
isPromptCacheOptional: true,
686687
inputPrice: 2.5, // This is the pricing for prompts above 200k tokens.
687688
outputPrice: 15,
688689
cacheReadsPrice: 0.625,
@@ -707,6 +708,7 @@ export const geminiModels = {
707708
contextWindow: 1_048_576,
708709
supportsImages: true,
709710
supportsPromptCache: false,
711+
isPromptCacheOptional: true,
710712
inputPrice: 0.1,
711713
outputPrice: 0.4,
712714
cacheReadsPrice: 0.025,
@@ -757,6 +759,7 @@ export const geminiModels = {
757759
contextWindow: 1_048_576,
758760
supportsImages: true,
759761
supportsPromptCache: false,
762+
isPromptCacheOptional: true,
760763
inputPrice: 0.15, // This is the pricing for prompts above 128k tokens.
761764
outputPrice: 0.6,
762765
cacheReadsPrice: 0.0375,

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,16 @@ import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
4141
import { MODELS_BY_PROVIDER, PROVIDERS, VERTEX_REGIONS, REASONING_MODELS } from "./constants"
4242
import { ModelInfoView } from "./ModelInfoView"
4343
import { ModelPicker } from "./ModelPicker"
44-
import { TemperatureControl } from "./TemperatureControl"
45-
import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
46-
import { DiffSettingsControl } from "./DiffSettingsControl"
4744
import { ApiErrorMessage } from "./ApiErrorMessage"
4845
import { ThinkingBudget } from "./ThinkingBudget"
4946
import { R1FormatSetting } from "./R1FormatSetting"
5047
import { OpenRouterBalanceDisplay } from "./OpenRouterBalanceDisplay"
5148
import { RequestyBalanceDisplay } from "./RequestyBalanceDisplay"
5249
import { ReasoningEffort } from "./ReasoningEffort"
50+
import { PromptCachingControl } from "./PromptCachingControl"
51+
import { DiffSettingsControl } from "./DiffSettingsControl"
52+
import { TemperatureControl } from "./TemperatureControl"
53+
import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
5354

5455
interface ApiOptionsProps {
5556
uriScheme: string | undefined
@@ -1742,6 +1743,13 @@ const ApiOptions = ({
17421743
/>
17431744
)}
17441745

1746+
{selectedModelInfo.supportsPromptCache && selectedModelInfo.isPromptCacheOptional && (
1747+
<PromptCachingControl
1748+
apiConfiguration={apiConfiguration}
1749+
setApiConfigurationField={setApiConfigurationField}
1750+
/>
1751+
)}
1752+
17451753
{!fromWelcomeView && (
17461754
<>
17471755
<DiffSettingsControl
@@ -1750,7 +1758,7 @@ const ApiOptions = ({
17501758
onChange={(field, value) => setApiConfigurationField(field, value)}
17511759
/>
17521760
<TemperatureControl
1753-
value={apiConfiguration?.modelTemperature}
1761+
value={apiConfiguration.modelTemperature}
17541762
onChange={handleInputChange("modelTemperature", noTransform)}
17551763
maxValue={2}
17561764
/>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
2+
3+
import { ApiConfiguration } from "@roo/shared/api"
4+
5+
import { useAppTranslation } from "@src/i18n/TranslationContext"
6+
7+
interface PromptCachingControlProps {
8+
apiConfiguration: ApiConfiguration
9+
setApiConfigurationField: <K extends keyof ApiConfiguration>(field: K, value: ApiConfiguration[K]) => void
10+
}
11+
12+
export const PromptCachingControl = ({ apiConfiguration, setApiConfigurationField }: PromptCachingControlProps) => {
13+
const { t } = useAppTranslation()
14+
15+
return (
16+
<>
17+
<div>
18+
<VSCodeCheckbox
19+
checked={apiConfiguration.promptCachingEnabled}
20+
onChange={(e: any) => setApiConfigurationField("promptCachingEnabled", e.target.checked)}>
21+
<label className="block font-medium mb-1">{t("settings:promptCaching.label")}</label>
22+
</VSCodeCheckbox>
23+
<div className="text-sm text-vscode-descriptionForeground mt-1">
24+
{t("settings:promptCaching.description")}
25+
</div>
26+
</div>
27+
</>
28+
)
29+
}

webview-ui/src/i18n/locales/ca/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@
386386
"description": "Quan està activat, Roo utilitzarà l'eina diff de blocs múltiples. Això intentarà actualitzar múltiples blocs de codi a l'arxiu en una sola petició."
387387
}
388388
},
389+
"promptCaching": {
390+
"label": "Habilitar emmagatzematge en caché de prompts",
391+
"description": "Quan està habilitat, Roo utilitzarà aquest model amb la memòria cau de prompts activada per reduir costos."
392+
},
389393
"temperature": {
390394
"useCustom": "Utilitzar temperatura personalitzada",
391395
"description": "Controla l'aleatorietat en les respostes del model.",

webview-ui/src/i18n/locales/de/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@
386386
"description": "Wenn aktiviert, verwendet Roo das Multi-Block-Diff-Werkzeug. Dies versucht, mehrere Codeblöcke in der Datei in einer Anfrage zu aktualisieren."
387387
}
388388
},
389+
"promptCaching": {
390+
"label": "Prompt-Caching aktivieren",
391+
"description": "Wenn aktiviert, wird Roo dieses Modell mit aktiviertem Prompt-Caching verwenden, um Kosten zu reduzieren."
392+
},
389393
"temperature": {
390394
"useCustom": "Benutzerdefinierte Temperatur verwenden",
391395
"description": "Steuert die Zufälligkeit in den Antworten des Modells.",

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@
386386
"description": "When enabled, Roo will use multi block diff tool. This will try to update multiple code blocks in the file in one request."
387387
}
388388
},
389+
"promptCaching": {
390+
"label": "Enable prompt caching",
391+
"description": "When enabled, Roo will use this model with prompt caching turned on in order to reduce costs."
392+
},
389393
"temperature": {
390394
"useCustom": "Use custom temperature",
391395
"description": "Controls randomness in the model's responses.",

webview-ui/src/i18n/locales/es/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@
386386
"description": "Cuando está habilitado, Roo usará la herramienta de diff de bloques múltiples. Esto intentará actualizar múltiples bloques de código en el archivo en una sola solicitud."
387387
}
388388
},
389+
"promptCaching": {
390+
"label": "Habilitar caché de prompts",
391+
"description": "Cuando está habilitado, Roo usará este modelo con el caché de prompts activado para reducir costos."
392+
},
389393
"temperature": {
390394
"useCustom": "Usar temperatura personalizada",
391395
"description": "Controla la aleatoriedad en las respuestas del modelo.",

0 commit comments

Comments
 (0)