Skip to content

fix(media): webp mime, guardContent image gating, 3gp video mapping - #19

Closed
chaynabors wants to merge 1 commit into
mainfrom
agent-tasks/2204
Closed

chaynabors wants to merge 1 commit into
mainfrom
agent-tasks/2204

Conversation

@chaynabors

@chaynabors chaynabors commented Jun 24, 2026 •

Copy link
Copy Markdown
Owner

Fixes strands-agents#2204.

The Python SDK has three related media-handling gaps where the TypeScript SDK is correct:

  • Anthropic image MIME lookup. mimetypes.types_map returns application/octet-stream for .webp on common Python installs, so WebP images are rejected by Anthropic. Same lookup is used by the OpenAI, Gemini, Writer, LlamaAPI, LlamaCpp, and OpenAI Responses providers, all with the same defect for WebP. They now share an explicit format -> media_type map for the image formats Strands already accepts (png, jpeg, jpg, gif, webp). Document MIME lookups, where this defect does not apply, still go through mimetypes.
  • Bedrock guardContent wrapping. Bedrock's GuardrailConverseContentBlock only accepts png and jpeg. We wrap all image formats today, which makes a guardrail_latest_message=True request fail at validation when a user sends a webp or gif. The wrap is now gated to png/jpeg, matching the TypeScript SDK. GuardContent also gains the image field it was missing.
  • Bedrock 3GP video format. Bedrock expects the enum three_gp, but the natural user-facing alias is 3gp. 3gp is now accepted on VideoFormat and normalized at request format time, again matching the TypeScript SDK.

Tests extend the existing test_format_request_with_image (Anthropic) to cover all five supported formats, add a parametrized 3gp/three_gp/mp4 video format test, and add a guardrail test that asserts unsupported image formats pass through unwrapped.

Related upstream PRs each fix a strict subset of this issue: strands-agents#2304 covers Anthropic WebP only, strands-agents#2306 covers Bedrock 3GP only, strands-agents#2552 covers WebP + guardContent gating but only on Anthropic + Bedrock and without tests or the GuardContent.image type, and strands-agents#2399 covers WebP + 3GP. None of them fix all three bugs in one place, propagate the WebP MIME fix to the other six providers that share the same mimetypes.types_map call, or add the missing GuardContent.image field. This PR is the smallest change that closes strands-agents#2204 fully.

Verify

cd strands-py
hatch test tests/strands/models/test_anthropic.py tests/strands/models/test_bedrock.py
hatch fmt --check src/strands/models src/strands/types tests/strands/models/test_anthropic.py tests/strands/models/test_bedrock.py

@chaynabors chaynabors left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each subitem is a real bug with the right fix. The webp MIME issue at strands-py/src/strands/models/anthropic.py:145 is real on older CPython where mimetypes.types_map lacks .webp, and the explicit map also handles the jpg alias cleanly. The Bedrock guardContent gating at strands-py/src/strands/models/bedrock.py:506 to png and jpeg only matches the AWS guardrail support and the TypeScript SDK. The 3gp to three_gp mapping at strands-py/src/strands/models/bedrock.py:714 plus the VideoFormat literal at strands-py/src/strands/types/media.py:110 hits the right Bedrock enum spelling, though accepting both 3gp and three_gp is mildly redundant. The GuardContent total=False with image at strands-py/src/strands/types/content.py:31 is safe for current consumers since both inbound destructure sites at strands-py/src/strands/models/bedrock.py:620 and strands-py/src/strands/models/model.py:78 still operate on the text branch. Worth noting the same mimetypes.types_map pattern exists for image format in strands-py/src/strands/models/openai.py:186, gemini.py:173, writer.py:104, llamaapi.py:108, llamacpp.py:222, and openai_responses.py:98, so webp can still misroute through those providers on the same Python builds. Commit and PR style look clean: single lowercase conventional commit, no co-author trailer, no em-dashes, prose-only body that calls out scope and skipped items implicitly via the explicit list of what is fixed.

@chaynabors

Copy link
Copy Markdown
Owner Author

Extended the explicit image mime map to openai, gemini, writer, llamaapi, llamacpp, and openai_responses so webp does not misroute through those providers either. Document paths still go through mimetypes.types_map.

@chaynabors

Copy link
Copy Markdown
Owner Author

WebP images were getting the wrong mime type, Bedrock was wrapping unsupported image formats in guard content, and the 3gp video format was being passed through unmapped. The fix introduces explicit image format mime maps across the providers, gates guard content wrapping to png and jpeg only, declares the image field on guard content, and maps 3gp to the Bedrock enum value while accepting both spellings.

Obviously mergable: yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Media type handling bugs and missing format support

1 participant