Skip to content

Commit b3c6f53

Browse files
committed
add provider_details field to parts
1 parent 24e47bf commit b3c6f53

File tree

6 files changed

+207
-179
lines changed

6 files changed

+207
-179
lines changed

pydantic_ai_slim/pydantic_ai/messages.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,9 @@ class TextPart:
10031003
part_kind: Literal['text'] = 'text'
10041004
"""Part type identifier, this is available on all parts as a discriminator."""
10051005

1006+
provider_details: dict[str, Any] | None = None
1007+
"""Additional provider-specific details in a serializable format."""
1008+
10061009
def has_content(self) -> bool:
10071010
"""Return `True` if the text content is non-empty."""
10081011
return bool(self.content)
@@ -1042,6 +1045,9 @@ class ThinkingPart:
10421045
part_kind: Literal['thinking'] = 'thinking'
10431046
"""Part type identifier, this is available on all parts as a discriminator."""
10441047

1048+
provider_details: dict[str, Any] | None = None
1049+
"""Additional provider-specific details in a serializable format."""
1050+
10451051
def has_content(self) -> bool:
10461052
"""Return `True` if the thinking content is non-empty."""
10471053
return bool(self.content)
@@ -1068,6 +1074,9 @@ class FilePart:
10681074
part_kind: Literal['file'] = 'file'
10691075
"""Part type identifier, this is available on all parts as a discriminator."""
10701076

1077+
provider_details: dict[str, Any] | None = None
1078+
"""Additional provider-specific details in a serializable format."""
1079+
10711080
def has_content(self) -> bool:
10721081
"""Return `True` if the file content is non-empty."""
10731082
return bool(self.content.data)
@@ -1101,6 +1110,9 @@ class BaseToolCallPart:
11011110
11021111
This is used by some APIs like OpenAI Responses."""
11031112

1113+
provider_details: dict[str, Any] | None = None
1114+
"""Additional provider-specific details in a serializable format."""
1115+
11041116
def args_as_dict(self) -> dict[str, Any]:
11051117
"""Return the arguments as a Python dictionary.
11061118
@@ -1436,6 +1448,9 @@ class TextPartDelta:
14361448
part_delta_kind: Literal['text'] = 'text'
14371449
"""Part delta type identifier, used as a discriminator."""
14381450

1451+
provider_details: dict[str, Any] | None = None
1452+
"""Additional provider-specific details in a serializable format."""
1453+
14391454
def apply(self, part: ModelResponsePart) -> TextPart:
14401455
"""Apply this text delta to an existing `TextPart`.
14411456
@@ -1477,6 +1492,9 @@ class ThinkingPartDelta:
14771492
part_delta_kind: Literal['thinking'] = 'thinking'
14781493
"""Part delta type identifier, used as a discriminator."""
14791494

1495+
provider_details: dict[str, Any] | None = None
1496+
"""Additional provider-specific details in a serializable format."""
1497+
14801498
@overload
14811499
def apply(self, part: ModelResponsePart) -> ThinkingPart: ...
14821500

@@ -1540,6 +1558,9 @@ class ToolCallPartDelta:
15401558
part_delta_kind: Literal['tool_call'] = 'tool_call'
15411559
"""Part delta type identifier, used as a discriminator."""
15421560

1561+
provider_details: dict[str, Any] | None = None
1562+
"""Additional provider-specific details in a serializable format."""
1563+
15431564
def as_part(self) -> ToolCallPart | None:
15441565
"""Convert this delta to a fully formed `ToolCallPart` if possible, otherwise return `None`.
15451566

tests/test_agent.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,7 +3733,9 @@ def test_binary_content_serializable():
37333733
'metadata': None,
37343734
},
37353735
{
3736-
'parts': [{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text'}],
3736+
'parts': [
3737+
{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text', 'provider_details': None}
3738+
],
37373739
'usage': {
37383740
'input_tokens': 56,
37393741
'cache_write_tokens': 0,
@@ -3793,7 +3795,9 @@ def test_image_url_serializable_missing_media_type():
37933795
'metadata': None,
37943796
},
37953797
{
3796-
'parts': [{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text'}],
3798+
'parts': [
3799+
{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text', 'provider_details': None}
3800+
],
37973801
'usage': {
37983802
'input_tokens': 51,
37993803
'cache_write_tokens': 0,
@@ -3860,7 +3864,9 @@ def test_image_url_serializable():
38603864
'metadata': None,
38613865
},
38623866
{
3863-
'parts': [{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text'}],
3867+
'parts': [
3868+
{'content': 'success (no tool calls)', 'id': None, 'part_kind': 'text', 'provider_details': None}
3869+
],
38643870
'usage': {
38653871
'input_tokens': 51,
38663872
'cache_write_tokens': 0,

0 commit comments

Comments
 (0)