-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Description
See @DouweM's latest comments on #2040
Context:
We have a custom API that converts between OpenAI's /chat/completions endpoint format and Bedrock Converse API format. So that our users can use OpenAI-compatible syntax with Bedrock models. Our custom API also supports thinking, tool calling, and streaming.
With thinking + tool calling, the assistant response will look like the following:
{
"role": "assistant",
"content": "...",
"tool_calls": [
{
"id": "...",
"type": "function",
"function": {
"name": "...",
"arguments": "..."
}
}
],
"reasoning_content": "...",
"reasoning_signature": "..."
}
where the reasoning_content
and reasoning_signature
is required by Bedrock Converse API for the next conversation turn. These fields are not part of OpenAI syntax but we added them to make Bedrock compatible.
However, intializing the model like this -
model = OpenAIModel(
"us.anthropic.claude-sonnet-4-20250514-v1:0",
provider=OpenAIProvider(
base_url= END_POINT_URL,
api_key= API_KEY,
),
)
Gives the following issue -
[ERROR] Exception in agent run: 400: An error occurred (ValidationException) when calling the ConverseStream operation: The model returned the following errors: messages.3.content.0.type: Expected thinking or redacted_thinking, but found text. When thinking is enabled, a final assistant message must start with a thinking block (preceeding the lastmost set of tool_use and tool_result blocks). We recommend you include thinking blocks from previous turns. To avoid this requirement, disable thinking. Please consult our documentation at https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking
@DouweM 's suggestion -
@aravindh28
OpenAIChatModel
doesn't currently send thinking parts back:pydantic-ai/pydantic_ai_slim/pydantic_ai/models/openai.py
Lines 577 to 581 in 21c87a5
elif isinstance(item, ThinkingPart): # NOTE: We don't send ThinkingPart to the providers yet. If you are unsatisfied with this, # please open an issue. The below code is the code to send thinking to the provider. # texts.append(f'<think>\n{item.content}\n</think>') pass We could add an
OpenAIModelProfile
option to do so (similar toBedrockModelProfile.bedrock_send_back_thinking_parts
), but we'd need to make sure we send them back in the same field where we received them -- i.e.reasoning_content
for DeepSeek and your API, or in<think>
tags for APIs that returned the thoughts embedded in text parts. We can likely track that onThinkingPart.id
.I'm guessing it would not be an option for your Pydantic AI users to use the Bedrock Converse API directly, while users of other frameworks can use the Chat Completions-compatible API?
This is worth creating a new issue for, by the way.
Originally posted by @DouweM in #2040