Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions strands-py/src/strands/models/bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ class BedrockConfig(BaseModelConfig, total=False):
See https://docs.aws.amazon.com/bedrock/latest/userguide/structured-output.html
temperature: Controls randomness in generation (higher = more random)
top_p: Controls diversity via nucleus sampling (alternative to temperature)
request_metadata: Key-value metadata to attach to the request for cost tracking and attribution.
Appears in model invocation logs for per-request finops. Max 16 entries, keys/values max 256 chars.
See https://docs.aws.amazon.com/bedrock/latest/userguide/cost-mgmt-request-metadata.html
use_native_token_count: Whether to use the native Bedrock CountTokens API.
When True, count_tokens() calls the Bedrock API for accurate counts.
When False (default), skips the API call and uses the local estimator.
Expand All @@ -141,6 +144,7 @@ class BedrockConfig(BaseModelConfig, total=False):
max_tokens: int | None
model_id: str
include_tool_result_status: Literal["auto"] | bool | None
request_metadata: dict[str, str] | None
service_tier: str | None
stop_sequences: list[str] | None
streaming: bool | None
Expand Down Expand Up @@ -333,6 +337,11 @@ def _format_request(
]
if value is not None
},
**(
{"requestMetadata": self.config["request_metadata"]}
if self.config.get("request_metadata")
else {}
),
**(
self.config["additional_args"]
if "additional_args" in self.config and self.config["additional_args"] is not None
Expand Down
19 changes: 19 additions & 0 deletions strands-py/tests/strands/models/test_bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,25 @@ def test_format_request_with_service_tier(model, messages, model_id):
assert tru_request == exp_request


def test_format_request_with_request_metadata(model, messages, model_id):
model.update_config(request_metadata={"team": "orchestrator", "environment": "prod"})
tru_request = model._format_request(messages)
exp_request = {
"inferenceConfig": {},
"modelId": model_id,
"messages": messages,
"requestMetadata": {"team": "orchestrator", "environment": "prod"},
"system": [],
}

assert tru_request == exp_request


def test_format_request_without_request_metadata(model, messages, model_id):
tru_request = model._format_request(messages)
assert "requestMetadata" not in tru_request


def test_format_request_inference_config(model, messages, model_id, inference_config):
model.update_config(**inference_config)
tru_request = model._format_request(messages)
Expand Down