diff --git a/src/strands/models/bedrock.py b/src/strands/models/bedrock.py index 596936e6f..095216fd6 100644 --- a/src/strands/models/bedrock.py +++ b/src/strands/models/bedrock.py @@ -492,7 +492,11 @@ def _format_request_message_content(self, content: ContentBlock) -> dict[str, An """ # https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_CachePointBlock.html if "cachePoint" in content: - return {"cachePoint": {"type": content["cachePoint"]["type"]}} + cache_point = content["cachePoint"] + result = {"type": cache_point["type"]} + if "ttl" in cache_point: + result["ttl"] = cache_point["ttl"] + return {"cachePoint": result} # https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_DocumentBlock.html if "document" in content: diff --git a/src/strands/types/content.py b/src/strands/types/content.py index d75dbb87f..164f199bb 100644 --- a/src/strands/types/content.py +++ b/src/strands/types/content.py @@ -8,7 +8,7 @@ from typing import Literal -from typing_extensions import TypedDict +from typing_extensions import NotRequired, TypedDict from .citations import CitationsContentBlock from .media import DocumentContent, ImageContent, VideoContent @@ -66,9 +66,11 @@ class CachePoint(TypedDict): Attributes: type: The type of cache point, typically "default". + ttl: Optional TTL duration for cache entries. Valid values are "5m" (5 minutes) or "1h" (1 hour). """ type: str + ttl: NotRequired[Literal["5m", "1h"]] class ContentBlock(TypedDict, total=False): diff --git a/tests/strands/models/test_bedrock.py b/tests/strands/models/test_bedrock.py index 1410e129b..a013f8e68 100644 --- a/tests/strands/models/test_bedrock.py +++ b/tests/strands/models/test_bedrock.py @@ -2050,6 +2050,53 @@ def test_format_request_filters_cache_point_content_blocks(model, model_id): assert "extraField" not in cache_point_block +def test_format_request_preserves_cache_point_ttl(model, model_id): + """Test that format_request preserves the ttl field in cachePoint content blocks.""" + messages = [ + { + "role": "user", + "content": [ + { + "cachePoint": { + "type": "default", + "ttl": "1h", + } + }, + ], + } + ] + + formatted_request = model._format_request(messages) + + cache_point_block = formatted_request["messages"][0]["content"][0]["cachePoint"] + expected = {"type": "default", "ttl": "1h"} + assert cache_point_block == expected + assert cache_point_block["ttl"] == "1h" + + +def test_format_request_cache_point_without_ttl(model, model_id): + """Test that cache points work without ttl field (backward compatibility).""" + messages = [ + { + "role": "user", + "content": [ + { + "cachePoint": { + "type": "default", + } + }, + ], + } + ] + + formatted_request = model._format_request(messages) + + cache_point_block = formatted_request["messages"][0]["content"][0]["cachePoint"] + expected = {"type": "default"} + assert cache_point_block == expected + assert "ttl" not in cache_point_block + + def test_config_validation_warns_on_unknown_keys(bedrock_client, captured_warnings): """Test that unknown config keys emit a warning.""" BedrockModel(model_id="test-model", invalid_param="test")