Skip to content

Python: [Bug]: BedrockChatClient silently drops guardrailConfig and other Bedrock options, so GPT-6 Sol/Luna reasoning effort can't be set #8678

Description

@kimnamu

Description

Thanks for the Bedrock connector and for already declaring the Bedrock-specific keys on BedrockChatOptions. As far as I can tell, guardrailConfig, performanceConfig, requestMetadata and promptVariables never reach the Converse request, and there is no way to pass additionalModelRequestFields, which is where Converse takes the reasoning effort for the new OpenAI GPT-6 Sol/Luna models.

BedrockChatClient.get_response(options=...), us-east-1, main @ f42ff01 BedrockChatClient Raw boto3 converse, same input
guardrailConfig with a guardrail ID that doesn't exist ❌ key not sent, call succeeds ValidationException: The provided guardrail identifier is invalid.
additionalModelRequestFields={"reasoning": {"effort": "none"}}, us.openai.gpt-6-sol ❌ key not sent, reasoning block still returned, 47 output tokens text only, 5 output tokens
same, us.openai.gpt-6-luna ❌ key not sent, 57 output tokens text only, 5 output tokens
performanceConfig, requestMetadata, promptVariables ❌ keys not sent sent

The keys do reach _prepare_options, but the returned request only contains modelId, messages, inferenceConfig and the optional system/toolConfig/outputConfig.

Where: _prepare_options in python/packages/bedrock/agent_framework_bedrock/_chat_client.py (L400-464). The keys are declared at L149-160 but nothing reads them, and the metadata docstring (L139) points to an additional_properties path that no longer exists. Before #3140 the request builder ran payload.update(chat_options.additional_properties); that line went away in the TypedDict refactor. Gemini's _prepare_config and Anthropic's _prepare_options still copy provider-specific option keys into their requests.

Impact: a guardrail passed through options is silently not applied, and nothing fails, so it is easy to miss in production. It affects every Bedrock model, not only GPT-6.

Suggested fix: copy these keys into the request when they are set and declare additionalModelRequestFields on BedrockChatOptions. Requests that don't set them stay the same. I have a small PR with a regression test and will link it here.

Code Sample

import asyncio
from agent_framework.amazon import BedrockChatClient

async def main():
    client = BedrockChatClient(model="us.openai.gpt-6-sol", region="us-east-1")
    # raw Converse rejects this guardrail ID; BedrockChatClient never sends it
    await client.get_response("pong", options={"guardrailConfig": {"guardrailIdentifier": "does-not-exist", "guardrailVersion": "1"}})
    # reasoning effort never reaches the request
    r = await client.get_response("How many primes are below 50? Number only.",
                                  options={"additionalModelRequestFields": {"reasoning": {"effort": "none"}}})
    print(r.usage_details["output_token_count"])

asyncio.run(main())

Error Messages / Stack Traces

# BedrockChatClient, main @ f42ff01
us.openai.gpt-6-sol effort=none -> '15' blocks ['reasoningContent', 'text'] output_tokens 47
us.openai.gpt-6-sol guardrailConfig(does-not-exist) -> OK (guardrail not applied)
us.openai.gpt-6-luna effort=none -> '15' blocks ['reasoningContent', 'text'] output_tokens 57
us.openai.gpt-6-luna guardrailConfig(does-not-exist) -> OK (guardrail not applied)

# raw boto3 converse, same inputs
us.openai.gpt-6-sol raw effort=none -> blocks ['text'] outputTokens 5
us.openai.gpt-6-sol raw guardrailConfig(nonexistent) -> ValidationException The provided guardrail identifier is invalid.
us.openai.gpt-6-luna raw effort=none -> blocks ['text'] outputTokens 5
us.openai.gpt-6-luna raw guardrailConfig(nonexistent) -> ValidationException The provided guardrail identifier is invalid.

Package Versions

agent-framework-core: 1.19.0, agent-framework-bedrock: 1.0.0b260918 (main @ f42ff01), boto3: 1.43.100

Python Version

Python 3.12

Additional Context

GPT-6 reasoning effort on Converse

On GPT-6 Sol/Luna, Converse accepts reasoning.effort values none, low, medium, high, xhigh and max inside additionalModelRequestFields. The gpt-oss style reasoning_effort key is rejected with Unknown parameter: 'reasoning_effort'.

Activity

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

Metadata

Metadata

Labels

agentsUsage: [Issues, PRs], Target: Single agentpythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions