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
10 changes: 10 additions & 0 deletions src/strands/models/bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,16 @@ def _format_request_message_content(self, content: ContentBlock) -> dict[str, An
result = {"text": {"text": guard_text["text"], "qualifiers": guard_text["qualifiers"]}}
return {"guardContent": result}

# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_AudioBlock.html
if "audio" in content:
audio = content["audio"]
source = audio["source"]
formatted_source = {}
if "bytes" in source:
formatted_source = {"bytes": source["bytes"]}
result = {"format": audio["format"], "source": formatted_source}
return {"audio": result}

# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ImageBlock.html
if "image" in content:
image = content["image"]
Expand Down
4 changes: 3 additions & 1 deletion src/strands/types/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from typing_extensions import TypedDict

from .citations import CitationsContentBlock
from .media import DocumentContent, ImageContent, VideoContent
from .media import AudioContent, DocumentContent, ImageContent, VideoContent
from .tools import ToolResult, ToolUse


Expand Down Expand Up @@ -75,6 +75,7 @@ class ContentBlock(TypedDict, total=False):
"""A block of content for a message that you pass to, or receive from, a model.

Attributes:
audio: Audio to include in the message.
cachePoint: A cache point configuration to optimize conversation history.
document: A document to include in the message.
guardContent: Contains the content to assess with the guardrail.
Expand All @@ -87,6 +88,7 @@ class ContentBlock(TypedDict, total=False):
citationsContent: Contains the citations for a document.
"""

audio: AudioContent
cachePoint: CachePoint
document: DocumentContent
guardContent: GuardContent
Expand Down
26 changes: 26 additions & 0 deletions src/strands/types/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,29 @@ class VideoContent(TypedDict):

format: VideoFormat
source: VideoSource


AudioFormat = Literal["mp3", "wav", "flac", "ogg", "aac", "webm"]
"""Supported audio formats."""


class AudioSource(TypedDict):
"""Contains the content of audio data.

Attributes:
bytes: The binary content of the audio.
"""

bytes: bytes


class AudioContent(TypedDict):
"""Audio to include in a message.

Attributes:
format: The format of the audio (e.g., "mp3", "wav").
source: The source containing the audio's binary content.
"""

format: AudioFormat
source: AudioSource
27 changes: 27 additions & 0 deletions tests/strands/models/test_bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1888,6 +1888,33 @@ def test_format_request_filters_video_content_blocks(model, model_id):
assert "resolution" not in video_block


def test_format_request_filters_audio_content_blocks(model, model_id):
"""Test that format_request filters extra fields from audio content blocks."""
messages = [
{
"role": "user",
"content": [
{
"audio": {
"format": "mp3",
"source": {"bytes": b"audio_data"},
"duration": 120, # Extra field that should be filtered
"bitrate": "320kbps", # Extra field that should be filtered
}
},
],
}
]

formatted_request = model._format_request(messages)

audio_block = formatted_request["messages"][0]["content"][0]["audio"]
expected = {"format": "mp3", "source": {"bytes": b"audio_data"}}
assert audio_block == expected
assert "duration" not in audio_block
assert "bitrate" not in audio_block


def test_format_request_filters_cache_point_content_blocks(model, model_id):
"""Test that format_request filters extra fields from cachePoint content blocks."""
messages = [
Expand Down
4 changes: 2 additions & 2 deletions tests/strands/tools/test_decorator_pep563.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

from __future__ import annotations

from typing import Any
from typing import Any, Literal

import pytest
from typing_extensions import Literal, TypedDict
from typing_extensions import TypedDict

from strands import tool

Expand Down