Skip to content

fix(bedrock): handle toolResult attachment co-location per-model via bedrock_tool_result_colocatable_content - #6098

Merged
DouweM merged 16 commits into
pydantic:mainfrom
Hasnaathussain:fix/6081-bedrock-tool-result-attachments-conflict
Jul 4, 2026
Merged

DouweM merged 16 commits into
pydantic:mainfrom
Hasnaathussain:fix/6081-bedrock-tool-result-attachments-conflict

Conversation

@Hasnaathussain

@Hasnaathussain Hasnaathussain commented Jun 27, 2026 •

Copy link
Copy Markdown
Contributor

Closes #6081

Problem

On Bedrock, pydantic-ai merges consecutive user turns into one Converse message. When a tool-result turn is followed by a user turn carrying an attachment, they merge into one user message co-locating a toolResult block with the attachment — which some models reject with a misleading ValidationException about a missing tool_result.

The original fix split every such turn with a synthetic assistant message for all models. Live testing against Bedrock (us-east-1) shows the constraint is per-model, so a blanket split is both incomplete (misses models with a stricter rule) and over-broad (needlessly pollutes models with no rule).

Evidence (live Converse, what may share a user message with a toolResult)

Family text image document (pdf) document (csv/txt/docx) video
Anthropic ✅ ✅ ✅ ❌ ❌ (video unsupported)
Amazon Nova ✅ ✅ ✅ ✅ ✅
Meta Llama 4 ❌ ❌ ❌ ❌ ❌
Mistral (pixtral) ❌ ❌ ❌ ❌ ❌
Qwen ✅ ✅ — (no doc support) — —
  • Anthropic rejects documents and video beside a toolResult, but accepts text and images. (PDF happens to pass, but the pdf-vs-other-document split is undocumented and brittle, so we conservatively treat all documents as non-co-locatable.)
  • Nova has no constraint at all — the old blanket fix inserted a pointless dummy turn here.
  • Llama and Mistral reject any content sharing a toolResult turn, even plain text — a broader form of the same bug that the attachment-only guard missed.

Mechanism notes, also verified: a bare split into two consecutive user turns does not work (Bedrock re-merges same-role turns), so an alternating assistant turn is required; the separator must be non-whitespace (. works everywhere); block order within the message is irrelevant. AWS does not document the toolResult+document constraint — it's model behavior — which is why this is driven by empirical per-family testing.

Fix

Add a bedrock_tool_result_colocatable_content model-profile flag listing the content-block kinds a model accepts alongside a toolResult. The merge pass splits the turns (separating them with a synthetic . assistant message) only when the combined content isn't co-locatable for that model; otherwise it merges as before.

Family flag value effect
Anthropic {'text', 'image'} splits out documents + video
Meta, Mistral frozenset() toolResult isolated from all other content
everyone else (default) all kinds merges freely, no dummy turn

The default is permissive, so no behavior change for uncovered families.

Tests

  • Per-family mapping unit tests pinning the exact reshaped sequence (Anthropic split, Nova merged, Llama isolated).
  • VCR cassettes recorded against live Bedrock proving each family accepts its reshaped history: Anthropic with a text/plain document (the original PDF recording is accepted even without the fix, so it proved nothing — a text document actually reproduces the rejection), Nova co-located with no dummy turn, and Llama with text isolated.
  • Provider-profile assertions for the new flag values.

Follow-ups (separate PRs)

Live testing surfaced two adjacent, distinct defects that are handled in their own PRs rather than widening this one:

  • bedrock_supported_media_kinds_in_tool_returns has wrong per-family values (Mistral/Writer accept document but reject image inside tool results; Qwen accepts neither; Nova rejects binary documents).
  • The "conversation must start with a user message" workaround is provider-specific (Anthropic and Qwen accept a leading assistant turn) and currently applied as a blanket rule.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 27, 2026 19:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added size: S Small PR (≤100 weighted lines) bug Report that something isn't working, or PR implementing a fix labels Jun 27, 2026
@DouweM

DouweM commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

There's some related logic here:

# https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Message.html
# "If you include a ContentBlock with a document field, you must also include a ContentBlock with a text field."
has_document = any('document' in block for block in content)
has_text = any('text' in block for block in content)
if has_document and not has_text:
content.insert(0, {'text': 'See attached document(s).'})
return [{'role': 'user', 'content': content}]

Worth checking to see if we can make it more consistent / fix it in one place.

@Hasnaathussain

Hasnaathussain commented Jul 1, 2026 •

Copy link
Copy Markdown
Contributor Author

I have addressed this! I've updated the logic at the end of _map_messages to perform a clean pass over all final processed user messages. Any message that contains a document block but lacks a text block will now have a "See attached document(s)." prefix automatically inserted. This makes the text-field injection completely consistent and robust across user prompts, tool returns, and split/merged user turns. All 138 Bedrock tests pass locally.

@Hasnaathussain
Hasnaathussain force-pushed the fix/6081-bedrock-tool-result-attachments-conflict branch 2 times, most recently from 573a32e to 79b7ab4 Compare July 1, 2026 20:06
@coderabbitai

coderabbitai Bot commented Jul 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a97d87fb-02d2-4ee3-8446-0ccc165301b0

📥 Commits

Reviewing files that changed from the base of the PR and between 3e2204b and 0e7ffd3.

📒 Files selected for processing (5)
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py
  • pydantic_ai_slim/pydantic_ai/providers/bedrock.py
  • tests/models/test_bedrock.py
  • tests/profiles/test_resolution_matrix.py
  • tests/providers/test_bedrock.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • pydantic/logfire (manual)
  • pydantic/pydantic-ai (manual)
  • pydantic/pydantic (auto-detected)
✅ Files skipped from review due to trivial changes (1)
  • tests/profiles/test_resolution_matrix.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/providers/test_bedrock.py
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py

📝 Walkthrough

Walkthrough

This PR updates Bedrock message mapping so toolResult content is not merged with disallowed attachments in the same user message. A new Bedrock model-profile field defines which content kinds may colocate with toolResult; Anthropic allows text and image, Meta and Mistral allow none, and Nova stays unset. _map_messages now inserts a synthetic assistant . turn when needed. Tests and cassettes cover Anthropic, Nova, and Llama behavior.

Changes

Related issues: #6081
Suggested labels: bug, bedrock

Sequence Diagram(s)

sequenceDiagram
  participant _map_messages
  participant BedrockModelProfile
  participant BedrockMessages
  _map_messages->>BedrockModelProfile: read bedrock_tool_result_colocatable_content
  _map_messages->>_map_messages: inspect following user turn content kinds
  alt toolResult + disallowed content kind
    _map_messages->>BedrockMessages: insert synthetic assistant "."
  else allowed content kind
    _map_messages->>BedrockMessages: merge into prior user message
  end
Loading

Poem:
A toolResult met a document,
and Bedrock said, “Not consequent.”
So . stepped in between the two,
and all the turns now made it through.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: per-model handling of Bedrock toolResult co-location via a new profile flag.
Description check ✅ Passed The description covers the problem, fix, tests, and closing issue, matching the repository template well enough.
Linked Issues check ✅ Passed The PR implements the issue's core requirement by preventing tool_result from being merged with attachment-bearing user turns.
Out of Scope Changes check ✅ Passed The added tests, provider profile field, and cassettes all support the Bedrock co-location fix and stay within scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pydantic_ai_slim/pydantic_ai/models/bedrock.py (2)

1192-1207: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Confirm this block is truly needed given it's marked unreachable.

This normalization pass is marked # pragma: no cover (per the commit, intentionally, since _map_user_prompt and the merge logic already guarantee the document+text invariant per-message before this runs). Keeping unreachable defensive code is a reasonable safety net, but worth a second look: if it's truly dead given current invariants, consider removing it to avoid maintaining unreachable logic; if it's meant as future-proofing against new merge paths, a short comment explaining why would help future readers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pydantic_ai_slim/pydantic_ai/models/bedrock.py` around lines 1192 - 1207, The
normalization in bedrock.py that injects a fallback text block for user messages
with documents appears unreachable given the existing _map_user_prompt and merge
logic, so either remove the dead defensive branch from the processed_messages
loop or keep it only if needed for future-proofing and add a short explanatory
comment near the role/content check to justify why the invariant is not
guaranteed elsewhere.

1128-1148: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate detection logic could be extracted into a helper.

The any(... for k in ('image', 'document', 'video')) / any('toolResult' in block ...) checks are repeated four times here (and similar logic reappears at Line 1196 and Line 1330-1331). Extracting a small helper (e.g. _has_block_kind(content, *keys)) would reduce duplication and improve readability.

♻️ Proposed refactor
+    `@staticmethod`
+    def _has_block_kind(content: list[Any], *keys: str) -> bool:
+        return any(any(k in block for k in keys) for block in content)
+
     for current_message in bedrock_messages:
         if (
             last_message is not None
             and current_message['role'] == last_message['role']
             and current_message['role'] == 'user'
         ):
-            last_has_tool_result = any('toolResult' in block for block in last_message['content'])
-            current_has_attachment = any(
-                any(k in block for k in ('image', 'document', 'video')) for block in current_message['content']
-            )
-            last_has_attachment = any(
-                any(k in block for k in ('image', 'document', 'video')) for block in last_message['content']
-            )
-            current_has_tool_result = any('toolResult' in block for block in current_message['content'])
+            last_has_tool_result = self._has_block_kind(last_message['content'], 'toolResult')
+            current_has_attachment = self._has_block_kind(current_message['content'], 'image', 'document', 'video')
+            last_has_attachment = self._has_block_kind(last_message['content'], 'image', 'document', 'video')
+            current_has_tool_result = self._has_block_kind(current_message['content'], 'toolResult')
As per coding guidelines, "Consolidate methods with duplicated logic using helpers, delegation, or type overloads."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pydantic_ai_slim/pydantic_ai/models/bedrock.py` around lines 1128 - 1148, The
duplicate block-type detection in bedrock message processing should be
consolidated into a helper to reduce repetition. Extract the repeated `any(...)`
content checks used for `toolResult` and attachment kinds into a small method or
local helper, such as one used by the message-merging logic in `bedrock.py`, and
reuse it wherever the same pattern appears in the message processing flow. Keep
the merge decision in the existing code path, but delegate the repeated
detection work to the helper so the `processed_messages` assembly stays readable
and easier to maintain.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pydantic_ai_slim/pydantic_ai/models/bedrock.py`:
- Around line 1192-1207: The normalization in bedrock.py that injects a fallback
text block for user messages with documents appears unreachable given the
existing _map_user_prompt and merge logic, so either remove the dead defensive
branch from the processed_messages loop or keep it only if needed for
future-proofing and add a short explanatory comment near the role/content check
to justify why the invariant is not guaranteed elsewhere.
- Around line 1128-1148: The duplicate block-type detection in bedrock message
processing should be consolidated into a helper to reduce repetition. Extract
the repeated `any(...)` content checks used for `toolResult` and attachment
kinds into a small method or local helper, such as one used by the
message-merging logic in `bedrock.py`, and reuse it wherever the same pattern
appears in the message processing flow. Keep the merge decision in the existing
code path, but delegate the repeated detection work to the helper so the
`processed_messages` assembly stays readable and easier to maintain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b3ba337-4fc2-4c00-9b40-1c03c92432fc

📥 Commits

Reviewing files that changed from the base of the PR and between c3cf7b3 and 1b6d02e.

📒 Files selected for processing (1)
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • pydantic/logfire (manual)
  • pydantic/pydantic-ai (manual)
  • pydantic/pydantic (auto-detected)

Hasnaathussain and others added 9 commits July 3, 2026 18:15
…ssistant message

Bedrock rejects a user message that co-locates a `toolResult` block with an
attachment block, and it also requires alternating roles, so a plain split
into two `user` turns is not enough. Insert a minimal assistant turn between
them, using `.` because Anthropic on Bedrock rejects whitespace-only text.

- drop the redundant post-merge document-text guard; `_map_user_prompt`
  already guarantees a text block alongside any document
- add a VCR regression test proving Converse accepts the reshaped history
- keep a unit test pinning the exact mapped message sequence

Refs pydantic#6081
@adtyavrdhn
adtyavrdhn force-pushed the fix/6081-bedrock-tool-result-attachments-conflict branch from a376ac7 to 2f1f287 Compare July 3, 2026 12:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pydantic_ai_slim/pydantic_ai/models/bedrock.py (1)

1003-1035: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Split unsupported tool-return attachments into a separate user turn The else branch still appends sibling_content to the same user message as toolResult, so a tool return with a video (or any other unsupported media kind) can still produce the forbidden toolResult + attachment shape and hit the same Bedrock validation failure. Emit a second user message here instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pydantic_ai_slim/pydantic_ai/models/bedrock.py` around lines 1003 - 1035, The
Bedrock tool-return assembly in the branch handling is_multi_modal_content still
combines the toolResult payload and unsupported attachment sibling_content into
one user message, which can trigger the same invalid shape. Update this path in
bedrock.py so the toolResult message is appended first, then emit the attachment
content as a separate user turn instead of extending the same user_content list;
keep the logic around _map_file_to_content_block, tool_result_content, and
sibling_content intact.
🧹 Nitpick comments (1)
tests/models/test_bedrock.py (1)

5182-5211: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Solid regression coverage; only document attachment type exercised.

The fix's merge-guard checks image/document/video uniformly, but only document is covered by these new tests. Given the logic is generic and already unit-pinned, this is a minor coverage gap rather than a real risk.

As per coding guidelines, "Provide comprehensive tests covering 100% of code paths, favoring integration tests and real requests."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/models/test_bedrock.py` around lines 5182 - 5211, Add regression
coverage for the merge-guard in the Bedrock history reshaping logic by
exercising the other attachment types handled alongside `document`, especially
`image` and `video`. Update the Bedrock test suite around
`test_bedrock_tool_result_followed_by_attachment_accepted` and the related
history-mapping helpers so the same tool-result-followed-by-attachment scenario
is verified for all supported attachment variants, not just `document`.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pydantic_ai_slim/pydantic_ai/models/bedrock.py`:
- Around line 1003-1035: The Bedrock tool-return assembly in the branch handling
is_multi_modal_content still combines the toolResult payload and unsupported
attachment sibling_content into one user message, which can trigger the same
invalid shape. Update this path in bedrock.py so the toolResult message is
appended first, then emit the attachment content as a separate user turn instead
of extending the same user_content list; keep the logic around
_map_file_to_content_block, tool_result_content, and sibling_content intact.

---

Nitpick comments:
In `@tests/models/test_bedrock.py`:
- Around line 5182-5211: Add regression coverage for the merge-guard in the
Bedrock history reshaping logic by exercising the other attachment types handled
alongside `document`, especially `image` and `video`. Update the Bedrock test
suite around `test_bedrock_tool_result_followed_by_attachment_accepted` and the
related history-mapping helpers so the same tool-result-followed-by-attachment
scenario is verified for all supported attachment variants, not just `document`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d5230da7-77d0-433f-8320-74ae9fddfbac

📥 Commits

Reviewing files that changed from the base of the PR and between 1b6d02e and 2f1f287.

📒 Files selected for processing (3)
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py
  • tests/models/cassettes/test_bedrock/test_bedrock_tool_result_followed_by_attachment_accepted.yaml
  • tests/models/test_bedrock.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • pydantic/logfire (manual)
  • pydantic/pydantic-ai (manual)
  • pydantic/pydantic (auto-detected)

@DouweM DouweM self-assigned this Jul 3, 2026
DouweM added 2 commits July 3, 2026 22:11
The previous fix split every `toolResult`-then-attachment turn with a synthetic
assistant message for all models, but live Converse testing shows the constraint
is per-model: Anthropic rejects only documents/video beside a `toolResult` (text
and images are fine), Llama and Mistral reject any content sharing the turn, and
Nova has no constraint at all — so the blanket split needlessly polluted Nova
(and every permissive model) with a dummy turn.

Introduce a `bedrock_tool_result_colocatable_content` profile flag listing the
content-block kinds a model accepts alongside a `toolResult`. The merge pass
splits (separating the turns with a synthetic assistant message, since Bedrock
re-merges consecutive same-role turns) only when the combined content isn't
co-locatable for that model. Default is permissive, preserving behavior for
uncovered families. Set to `{text, image}` for Anthropic and `frozenset()` for
Meta and Mistral (the latter reproduce the same defect for plain text, a broader
form of pydantic#6081).

Replace the PDF VCR recording (which Anthropic accepts even without the fix, so
it proved nothing) with `text/plain` recordings that actually reproduce the
rejection, plus Nova (co-located, no split) and Llama (text isolated) cassettes.

Refs pydantic#6081
@github-actions github-actions Bot added size: M Medium PR (101-500 weighted lines) and removed size: S Small PR (≤100 weighted lines) labels Jul 3, 2026
@DouweM DouweM added the douwebot reviews the PR that gets labeled and removes the label at the end label Jul 3, 2026
@github-actions github-actions Bot removed the douwebot reviews the PR that gets labeled and removes the label at the end label Jul 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/models/test_bedrock.py (1)

5169-5227: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add VCR-exemption rationale to the Nova/Llama unit tests.

test_bedrock_anthropic_tool_result_and_document_alternate explains why it's a unit test rather than a VCR test (cassette matcher isn't sensitive to request body). test_bedrock_nova_tool_result_and_document_merge and test_bedrock_llama_tool_result_isolated_from_text pin the same kind of internal request-payload shape but their docstrings omit this rationale.

As per path instructions, "Each unit test should explain why it is not (or cannot be) a VCR test, especially when it pins internal behavior, pre-request guards, or request payload shape that cassettes would not reliably catch."

Source: Path instructions


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d65779c-6227-41f3-a628-f0ae36d23f96

📥 Commits

Reviewing files that changed from the base of the PR and between 2f1f287 and d76fddd.

📒 Files selected for processing (7)
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py
  • pydantic_ai_slim/pydantic_ai/providers/bedrock.py
  • tests/models/cassettes/test_bedrock/test_bedrock_anthropic_tool_result_followed_by_document_accepted.yaml
  • tests/models/cassettes/test_bedrock/test_bedrock_llama_tool_result_followed_by_text_accepted.yaml
  • tests/models/cassettes/test_bedrock/test_bedrock_nova_tool_result_followed_by_document_accepted.yaml
  • tests/models/test_bedrock.py
  • tests/providers/test_bedrock.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • pydantic/logfire (manual)
  • pydantic/pydantic-ai (manual)
  • pydantic/pydantic (auto-detected)
✅ Files skipped from review due to trivial changes (2)
  • tests/models/cassettes/test_bedrock/test_bedrock_anthropic_tool_result_followed_by_document_accepted.yaml
  • tests/models/cassettes/test_bedrock/test_bedrock_llama_tool_result_followed_by_text_accepted.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • pydantic_ai_slim/pydantic_ai/models/bedrock.py

…result_colocatable_content`

The new profile flag appears in the normalized profile snapshots for Anthropic
(`{text, image}`), Meta, and Mistral (`frozenset()`) on Bedrock.
@DouweM DouweM changed the title fix(bedrock): prevent Converse ValidationException on consecutive tool_result and media attachment turns fix(bedrock): handle toolResult attachment co-location per-model via bedrock_tool_result_colocatable_content Jul 3, 2026
@DouweM DouweM added the douwebot reviews the PR that gets labeled and removes the label at the end label Jul 3, 2026
@github-actions github-actions Bot removed the douwebot reviews the PR that gets labeled and removes the label at the end label Jul 3, 2026
"""Default: `False`."""
bedrock_supported_media_kinds_in_tool_returns: frozenset[str]
"""Default: `frozenset({'image'})`."""
bedrock_tool_result_colocatable_content: frozenset[str]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's use a Literal union with the actual supported values, instead of str. That also goes for supported_media_kinds....

DouweM added 3 commits July 4, 2026 00:12
…eral` unions

Address review: use `frozenset[Literal[...]]` instead of `frozenset[str]` for
`bedrock_tool_result_colocatable_content` and `bedrock_supported_media_kinds_in_tool_returns`.
…flict

Resolve additive conflicts from pydantic#6255 (leading-assistant-message flag): keep both
that flag and this PR's `bedrock_tool_result_colocatable_content` in `BedrockModelProfile`,
the Anthropic profile, and the resolution-matrix / test-bedrock snapshots.
…flict

Resolve conflicts from pydantic#6254 (media-kinds fix): union the two `bedrock_meta_model_profile`
definitions (both `bedrock_tool_result_colocatable_content` and
`bedrock_supported_media_kinds_in_tool_returns`), and keep both flags' values in the
Mistral profile and in the resolution-matrix / provider-test assertions.
@DouweM
DouweM enabled auto-merge (squash) July 4, 2026 00:35
@DouweM
DouweM merged commit e3d7980 into pydantic:main Jul 4, 2026
61 checks passed
DouweM added a commit that referenced this pull request Jul 4, 2026
Reconcile with #6098 (now in main): keep the tool-return media-deferral logic and its
hoisted `colocatable_content`, and drop the duplicated co-location tests that landed via
#6098 (they're a subset of this branch's superset).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Report that something isn't working, or PR implementing a fix size: M Medium PR (101-500 weighted lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bedrock: an attachment (DocumentUrl/ImageUrl) merged into the same user message as a tool_result → Converse ValidationException

4 participants