Skip to content

Commit 2709555

Browse files
roomote[bot]roomote
andauthored
fix(bedrock): enable prompt caching for custom ARN and default to ON (RooCodeInc#11373)
* fix(bedrock): enable prompt caching for custom ARN and default to ON - Set supportsPromptCache to true for custom-arn model info in useSelectedModel.ts - Change awsUsePromptCache default from false to true using nullish coalescing - Add tests for custom-arn prompt caching support Closes RooCodeInc#10846 * fix(bedrock): align backend awsUsePromptCache default with UI (?? true) The backend treated undefined awsUsePromptCache as falsy (OFF) while the UI checkbox defaulted to true via nullish coalescing. This caused the UI to show prompt caching as ON but the backend to keep it OFF for new users. Apply the same ?? true default in the backend so both sides agree. --------- Co-authored-by: Roo Code <roomote@roocode.com>
1 parent 3a7a01f commit 2709555

5 files changed

Lines changed: 103 additions & 3 deletions

File tree

src/api/providers/__tests__/bedrock.spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,4 +1275,56 @@ describe("AwsBedrockHandler", () => {
12751275
expect(mockCaptureException).toHaveBeenCalled()
12761276
})
12771277
})
1278+
1279+
describe("prompt cache default behavior", () => {
1280+
beforeEach(() => {
1281+
mockConverseStreamCommand.mockReset()
1282+
})
1283+
1284+
// System prompt must exceed minTokensPerCachePoint (1024) for cache points to be placed
1285+
const longSystemPrompt = "You are a helpful assistant. ".repeat(200)
1286+
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
1287+
1288+
it("should enable prompt caching by default when awsUsePromptCache is undefined", async () => {
1289+
const defaultHandler = new AwsBedrockHandler({
1290+
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
1291+
awsAccessKey: "test-access-key",
1292+
awsSecretKey: "test-secret-key",
1293+
awsRegion: "us-east-1",
1294+
// awsUsePromptCache is intentionally omitted (undefined)
1295+
})
1296+
1297+
const generator = defaultHandler.createMessage(longSystemPrompt, messages)
1298+
await generator.next() // Start the generator
1299+
1300+
expect(mockConverseStreamCommand).toHaveBeenCalled()
1301+
const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
1302+
1303+
// System content should include a cachePoint entry since prompt caching defaults to ON
1304+
const systemBlocks = commandArg.system
1305+
const hasCachePoint = systemBlocks?.some((block: any) => block.cachePoint !== undefined)
1306+
expect(hasCachePoint).toBe(true)
1307+
})
1308+
1309+
it("should disable prompt caching when awsUsePromptCache is explicitly false", async () => {
1310+
const disabledHandler = new AwsBedrockHandler({
1311+
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
1312+
awsAccessKey: "test-access-key",
1313+
awsSecretKey: "test-secret-key",
1314+
awsRegion: "us-east-1",
1315+
awsUsePromptCache: false,
1316+
})
1317+
1318+
const generator = disabledHandler.createMessage(longSystemPrompt, messages)
1319+
await generator.next() // Start the generator
1320+
1321+
expect(mockConverseStreamCommand).toHaveBeenCalled()
1322+
const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
1323+
1324+
// System content should NOT include cachePoint since caching is explicitly disabled
1325+
const systemBlocks = commandArg.system
1326+
const hasCachePoint = systemBlocks?.some((block: any) => block.cachePoint !== undefined)
1327+
expect(hasCachePoint).toBe(false)
1328+
})
1329+
})
12781330
})

src/api/providers/bedrock.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
357357
},
358358
): ApiStream {
359359
const modelConfig = this.getModel()
360-
const usePromptCache = Boolean(this.options.awsUsePromptCache && this.supportsAwsPromptCache(modelConfig))
360+
const usePromptCache = Boolean(
361+
(this.options.awsUsePromptCache ?? true) && this.supportsAwsPromptCache(modelConfig),
362+
)
361363

362364
const conversationId =
363365
messages.length > 0

webview-ui/src/components/settings/providers/Bedrock.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo
198198
{selectedModelInfo?.supportsPromptCache && (
199199
<>
200200
<Checkbox
201-
checked={apiConfiguration?.awsUsePromptCache || false}
201+
checked={apiConfiguration?.awsUsePromptCache ?? true}
202202
onChange={handleInputChange("awsUsePromptCache", noTransform)}>
203203
<div className="flex items-center gap-1">
204204
<span>{t("settings:providers.enablePromptCaching")}</span>

webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,52 @@ describe("useSelectedModel", () => {
496496
})
497497
})
498498

499+
describe("bedrock provider with custom ARN", () => {
500+
beforeEach(() => {
501+
mockUseRouterModels.mockReturnValue({
502+
data: {
503+
openrouter: {},
504+
requesty: {},
505+
litellm: {},
506+
},
507+
isLoading: false,
508+
isError: false,
509+
} as any)
510+
511+
mockUseOpenRouterModelProviders.mockReturnValue({
512+
data: {},
513+
isLoading: false,
514+
isError: false,
515+
} as any)
516+
})
517+
518+
it("should enable supportsPromptCache for custom-arn model", () => {
519+
const apiConfiguration: ProviderSettings = {
520+
apiProvider: "bedrock",
521+
apiModelId: "custom-arn",
522+
}
523+
524+
const wrapper = createWrapper()
525+
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
526+
527+
expect(result.current.id).toBe("custom-arn")
528+
expect(result.current.info?.supportsPromptCache).toBe(true)
529+
})
530+
531+
it("should enable supportsImages for custom-arn model", () => {
532+
const apiConfiguration: ProviderSettings = {
533+
apiProvider: "bedrock",
534+
apiModelId: "custom-arn",
535+
}
536+
537+
const wrapper = createWrapper()
538+
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
539+
540+
expect(result.current.id).toBe("custom-arn")
541+
expect(result.current.info?.supportsImages).toBe(true)
542+
})
543+
})
544+
499545
describe("litellm provider", () => {
500546
beforeEach(() => {
501547
mockUseOpenRouterModelProviders.mockReturnValue({

webview-ui/src/components/ui/hooks/useSelectedModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ function getSelectedModel({
182182
if (id === "custom-arn") {
183183
return {
184184
id,
185-
info: { maxTokens: 5000, contextWindow: 128_000, supportsPromptCache: false, supportsImages: true },
185+
info: { maxTokens: 5000, contextWindow: 128_000, supportsPromptCache: true, supportsImages: true },
186186
}
187187
}
188188

0 commit comments

Comments
 (0)