Skip to content

Conversation

timelfrink
Copy link
Contributor

@timelfrink timelfrink commented Sep 15, 2025

Title

feat: Support requestMetadata in Bedrock Converse API

Relevant issues

Fixes #14562

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • I have added a screenshot of my new test passing locally
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem

Type

🆕 New Feature

Changes

What this PR does

Adds support for AWS Bedrock Converse API requestMetadata parameter in LiteLLM SDK, enabling users to attach arbitrary metadata to requests for logging, traceability, and cost attribution in multi-cloud environments.

Problem being solved

Currently, the requestMetadata field is ignored when sending Bedrock API requests through LiteLLM, preventing users from adding metadata for observability and operational use cases. This feature request (#14562) aims to provide the same functionality as labels in Vertex AI, allowing metadata that is not influenced by prompt content to be attached to requests for accurate traceability.

Core Implementation

  • Type definitions (litellm/types/llms/bedrock.py:223): Added requestMetadata: Optional[Dict[str, str]] field to CommonRequestObject
  • Parameter support (litellm/llms/bedrock/chat/converse_transformation.py:207): Added requestMetadata to get_supported_openai_params()
  • Validation logic (litellm/llms/bedrock/chat/converse_transformation.py:123-195): Implemented comprehensive validation following AWS Bedrock constraints:
    • Maximum 16 key-value pairs
    • Key length: 1-256 characters
    • Value length: 0-256 characters
    • Character set validation: [a-zA-Z0-9\s:_@$#=/+,.-]
  • Request transformation (litellm/llms/bedrock/chat/converse_transformation.py:517-520, 843-845): Maps requestMetadata parameter to top-level requestMetadata field in Bedrock API request

Testing

  • Parameter support test (test_converse_transformation.py:1595-1601): Verifies requestMetadata appears in supported parameters
  • Transformation test (test_converse_transformation.py:1604-1641): Ensures proper mapping to top-level requestMetadata field
  • Validation tests (test_converse_transformation.py:1644-1734): Comprehensive validation of AWS constraints including:
    • Maximum item count (16)
    • Key/value length limits
    • Character set validation
    • Type validation (strings only)
    • Edge cases with empty values and special characters

How to verify it

Automated Verification

  • Tests pass: All 9 request_metadata tests pass - poetry run pytest tests/test_litellm/llms/bedrock/chat/test_converse_transformation.py -k "requestMetadata" -v
  • Core functionality tests: test_request_metadata_parameter_support, test_request_metadata_transformation, test_request_metadata_validation
  • Edge case tests: Empty metadata, character validation, key/value constraints, integration with other params ✅
  • Linting passes: poetry run ruff check litellm/llms/bedrock/chat/converse_transformation.py
  • Code refactored: Extracted helper methods to improve maintainability and resolve statement count issues
  • Type checking: External dependency issue (botocore stubs) - not related to our changes, existing codebase issue
  • Integration tests pass: Full bedrock integration test suite

Manual Verification

  • Original issue scenario works correctly: Pass requestMetadata parameter and verify it appears in Bedrock API request
  • Edge cases handle properly: Test validation with invalid metadata formats
  • No regression in existing functionality: Ensure existing Bedrock Converse functionality works unchanged
  • Performance acceptable under load: Validation overhead is minimal

Breaking changes

None - this is a purely additive feature that maintains full backward compatibility.

Migration required

None - existing code continues to work unchanged. Users can optionally start using the new requestMetadata parameter.

Usage Example

import litellm

response = litellm.completion(
    model="bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0",
    messages=[{"role": "user", "content": "Hello!"}],
    requestMetadata={
        "cost_center": "engineering",
        "user_id": "user123",
        "session_id": "sess_abc123"
    }
)

The requestMetadata will be included in the Bedrock API request as a top-level requestMetadata field, enabling proper logging and traceability.

Related issues/PRs

Next Steps

  1. Complete manual testing checklist
  2. Address any failing automated checks
  3. Request review from maintainers
  4. Provide screenshot of local test execution

Copy link

vercel bot commented Sep 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
litellm Error Error Sep 22, 2025 4:27am

Copy link
Contributor

Choose a reason for hiding this comment

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

document this param @timelfrink

also ideally - shouldn't we have a consistent param for such values across gemini / bedrock?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added to docs.
Not sure if you want to have one param for this. I think we should follow the provider's native API parameter names (like AWS's requestMetadata and Google's labels) rather than forcing artificial uniformity. What you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

i trust your instinct

- Test requestMetadata parameter support in get_supported_openai_params
- Test transformation to top-level field in Bedrock API request
- Test validation of AWS constraints: max 16 items, key/value length limits
- Test character set validation for keys and values
- Cover edge cases including empty values and special characters
- Ensure compatibility with existing test patterns
- Add requestMetadata field to CommonRequestObject type definition
- Support request_metadata parameter in get_supported_openai_params
- Add comprehensive validation for AWS Bedrock constraints:
  * Maximum 16 key-value pairs
  * Key length 1-256 characters
  * Value length 0-256 characters
  * Character set validation [a-zA-Z0-9\s:_@0=/+,.-]
- Transform request_metadata to top-level requestMetadata field in API request
- Maintain backward compatibility with existing functionality
- Enable metadata logging and traceability for multi-cloud environments
- Split _transform_request_helper into smaller focused methods
- Extract _prepare_request_params for parameter preparation logic
- Extract _process_tools_and_beta for tool processing logic
- Resolve PLR0915 (too many statements) linting issue
- Maintain all existing functionality and test compatibility
… params

- Change parameter from request_metadata to requestMetadata to match camelCase convention
- Consistent with guardrailConfig and performanceConfig naming pattern
- Update all references in transformation code and error messages
- Update tests and documentation to use correct parameter name
- Fix type checking for parameter validation
@timelfrink timelfrink force-pushed the feat/issue-14562-bedrock-converse-request-metadata branch from 04ed11a to 27a37ce Compare September 18, 2025 07:22
@krrishdholakia krrishdholakia merged commit 52a56bd into BerriAI:main Sep 22, 2025
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature]: Support logging requestMetadata in LiteLLM SDK for Bedrock Converse
2 participants