pydantic-ai-slim 1.0.15__py3-none-any.whl → 1.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pydantic-ai-slim might be problematic. Click here for more details.

@@ -112,7 +112,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
112
112
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
113
113
  *,
114
114
  output_type: OutputSpec[RunOutputDataT] | None = None,
115
- message_history: list[_messages.ModelMessage] | None = None,
115
+ message_history: Sequence[_messages.ModelMessage] | None = None,
116
116
  deferred_tool_results: DeferredToolResults | None = None,
117
117
  model: models.Model | models.KnownModelName | str | None = None,
118
118
  deps: AgentDepsT,
@@ -149,7 +149,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
149
149
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
150
150
  *,
151
151
  output_type: OutputSpec[RunOutputDataT] | None = None,
152
- message_history: list[_messages.ModelMessage] | None = None,
152
+ message_history: Sequence[_messages.ModelMessage] | None = None,
153
153
  deferred_tool_results: DeferredToolResults | None = None,
154
154
  model: models.Model | models.KnownModelName | str | None = None,
155
155
  deps: AgentDepsT,
@@ -237,7 +237,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
237
237
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
238
238
  *,
239
239
  output_type: None = None,
240
- message_history: list[_messages.ModelMessage] | None = None,
240
+ message_history: Sequence[_messages.ModelMessage] | None = None,
241
241
  deferred_tool_results: DeferredToolResults | None = None,
242
242
  model: models.Model | models.KnownModelName | str | None = None,
243
243
  deps: AgentDepsT = None,
@@ -255,7 +255,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
255
255
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
256
256
  *,
257
257
  output_type: OutputSpec[RunOutputDataT],
258
- message_history: list[_messages.ModelMessage] | None = None,
258
+ message_history: Sequence[_messages.ModelMessage] | None = None,
259
259
  deferred_tool_results: DeferredToolResults | None = None,
260
260
  model: models.Model | models.KnownModelName | str | None = None,
261
261
  deps: AgentDepsT = None,
@@ -272,7 +272,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
272
272
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
273
273
  *,
274
274
  output_type: OutputSpec[RunOutputDataT] | None = None,
275
- message_history: list[_messages.ModelMessage] | None = None,
275
+ message_history: Sequence[_messages.ModelMessage] | None = None,
276
276
  deferred_tool_results: DeferredToolResults | None = None,
277
277
  model: models.Model | models.KnownModelName | str | None = None,
278
278
  deps: AgentDepsT = None,
@@ -341,7 +341,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
341
341
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
342
342
  *,
343
343
  output_type: None = None,
344
- message_history: list[_messages.ModelMessage] | None = None,
344
+ message_history: Sequence[_messages.ModelMessage] | None = None,
345
345
  deferred_tool_results: DeferredToolResults | None = None,
346
346
  model: models.Model | models.KnownModelName | str | None = None,
347
347
  deps: AgentDepsT = None,
@@ -359,7 +359,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
359
359
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
360
360
  *,
361
361
  output_type: OutputSpec[RunOutputDataT],
362
- message_history: list[_messages.ModelMessage] | None = None,
362
+ message_history: Sequence[_messages.ModelMessage] | None = None,
363
363
  deferred_tool_results: DeferredToolResults | None = None,
364
364
  model: models.Model | models.KnownModelName | str | None = None,
365
365
  deps: AgentDepsT = None,
@@ -376,7 +376,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
376
376
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
377
377
  *,
378
378
  output_type: OutputSpec[RunOutputDataT] | None = None,
379
- message_history: list[_messages.ModelMessage] | None = None,
379
+ message_history: Sequence[_messages.ModelMessage] | None = None,
380
380
  deferred_tool_results: DeferredToolResults | None = None,
381
381
  model: models.Model | models.KnownModelName | str | None = None,
382
382
  deps: AgentDepsT = None,
@@ -444,7 +444,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
444
444
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
445
445
  *,
446
446
  output_type: None = None,
447
- message_history: list[_messages.ModelMessage] | None = None,
447
+ message_history: Sequence[_messages.ModelMessage] | None = None,
448
448
  deferred_tool_results: DeferredToolResults | None = None,
449
449
  model: models.Model | models.KnownModelName | str | None = None,
450
450
  deps: AgentDepsT = None,
@@ -462,7 +462,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
462
462
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
463
463
  *,
464
464
  output_type: OutputSpec[RunOutputDataT],
465
- message_history: list[_messages.ModelMessage] | None = None,
465
+ message_history: Sequence[_messages.ModelMessage] | None = None,
466
466
  deferred_tool_results: DeferredToolResults | None = None,
467
467
  model: models.Model | models.KnownModelName | str | None = None,
468
468
  deps: AgentDepsT = None,
@@ -480,7 +480,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
480
480
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
481
481
  *,
482
482
  output_type: OutputSpec[RunOutputDataT] | None = None,
483
- message_history: list[_messages.ModelMessage] | None = None,
483
+ message_history: Sequence[_messages.ModelMessage] | None = None,
484
484
  deferred_tool_results: DeferredToolResults | None = None,
485
485
  model: models.Model | models.KnownModelName | str | None = None,
486
486
  deps: AgentDepsT = None,
@@ -553,7 +553,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
553
553
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
554
554
  *,
555
555
  output_type: None = None,
556
- message_history: list[_messages.ModelMessage] | None = None,
556
+ message_history: Sequence[_messages.ModelMessage] | None = None,
557
557
  deferred_tool_results: DeferredToolResults | None = None,
558
558
  model: models.Model | models.KnownModelName | str | None = None,
559
559
  deps: AgentDepsT = None,
@@ -570,7 +570,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
570
570
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
571
571
  *,
572
572
  output_type: OutputSpec[RunOutputDataT],
573
- message_history: list[_messages.ModelMessage] | None = None,
573
+ message_history: Sequence[_messages.ModelMessage] | None = None,
574
574
  deferred_tool_results: DeferredToolResults | None = None,
575
575
  model: models.Model | models.KnownModelName | str | None = None,
576
576
  deps: AgentDepsT = None,
@@ -586,7 +586,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
586
586
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
587
587
  *,
588
588
  output_type: OutputSpec[RunOutputDataT] | None = None,
589
- message_history: list[_messages.ModelMessage] | None = None,
589
+ message_history: Sequence[_messages.ModelMessage] | None = None,
590
590
  deferred_tool_results: DeferredToolResults | None = None,
591
591
  model: models.Model | models.KnownModelName | str | None = None,
592
592
  deps: AgentDepsT = None,
@@ -656,7 +656,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
656
656
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
657
657
  *,
658
658
  output_type: None = None,
659
- message_history: list[_messages.ModelMessage] | None = None,
659
+ message_history: Sequence[_messages.ModelMessage] | None = None,
660
660
  deferred_tool_results: DeferredToolResults | None = None,
661
661
  model: models.Model | models.KnownModelName | str | None = None,
662
662
  deps: AgentDepsT = None,
@@ -674,7 +674,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
674
674
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
675
675
  *,
676
676
  output_type: OutputSpec[RunOutputDataT],
677
- message_history: list[_messages.ModelMessage] | None = None,
677
+ message_history: Sequence[_messages.ModelMessage] | None = None,
678
678
  deferred_tool_results: DeferredToolResults | None = None,
679
679
  model: models.Model | models.KnownModelName | str | None = None,
680
680
  deps: AgentDepsT = None,
@@ -692,7 +692,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
692
692
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
693
693
  *,
694
694
  output_type: OutputSpec[RunOutputDataT] | None = None,
695
- message_history: list[_messages.ModelMessage] | None = None,
695
+ message_history: Sequence[_messages.ModelMessage] | None = None,
696
696
  deferred_tool_results: DeferredToolResults | None = None,
697
697
  model: models.Model | models.KnownModelName | str | None = None,
698
698
  deps: AgentDepsT = None,
@@ -804,18 +804,20 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
804
804
  def override(
805
805
  self,
806
806
  *,
807
+ name: str | _utils.Unset = _utils.UNSET,
807
808
  deps: AgentDepsT | _utils.Unset = _utils.UNSET,
808
809
  model: models.Model | models.KnownModelName | str | _utils.Unset = _utils.UNSET,
809
810
  toolsets: Sequence[AbstractToolset[AgentDepsT]] | _utils.Unset = _utils.UNSET,
810
811
  tools: Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]] | _utils.Unset = _utils.UNSET,
811
812
  instructions: Instructions[AgentDepsT] | _utils.Unset = _utils.UNSET,
812
813
  ) -> Iterator[None]:
813
- """Context manager to temporarily override agent dependencies, model, toolsets, tools, or instructions.
814
+ """Context manager to temporarily override agent name, dependencies, model, toolsets, tools, or instructions.
814
815
 
815
816
  This is particularly useful when testing.
816
817
  You can find an example of this [here](../testing.md#overriding-model-via-pytest-fixtures).
817
818
 
818
819
  Args:
820
+ name: The name to use instead of the name passed to the agent constructor and agent run.
819
821
  deps: The dependencies to use instead of the dependencies passed to the agent run.
820
822
  model: The model to use instead of the model passed to the agent run.
821
823
  toolsets: The toolsets to use instead of the toolsets passed to the agent constructor and agent run.
@@ -828,6 +830,7 @@ class DBOSAgent(WrapperAgent[AgentDepsT, OutputDataT], DBOSConfiguredInstance):
828
830
  )
829
831
 
830
832
  with super().override(
833
+ name=name,
831
834
  deps=deps,
832
835
  model=model,
833
836
  toolsets=toolsets,
@@ -259,7 +259,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
259
259
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
260
260
  *,
261
261
  output_type: None = None,
262
- message_history: list[_messages.ModelMessage] | None = None,
262
+ message_history: Sequence[_messages.ModelMessage] | None = None,
263
263
  deferred_tool_results: DeferredToolResults | None = None,
264
264
  model: models.Model | models.KnownModelName | str | None = None,
265
265
  deps: AgentDepsT = None,
@@ -277,7 +277,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
277
277
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
278
278
  *,
279
279
  output_type: OutputSpec[RunOutputDataT],
280
- message_history: list[_messages.ModelMessage] | None = None,
280
+ message_history: Sequence[_messages.ModelMessage] | None = None,
281
281
  deferred_tool_results: DeferredToolResults | None = None,
282
282
  model: models.Model | models.KnownModelName | str | None = None,
283
283
  deps: AgentDepsT = None,
@@ -294,7 +294,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
294
294
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
295
295
  *,
296
296
  output_type: OutputSpec[RunOutputDataT] | None = None,
297
- message_history: list[_messages.ModelMessage] | None = None,
297
+ message_history: Sequence[_messages.ModelMessage] | None = None,
298
298
  deferred_tool_results: DeferredToolResults | None = None,
299
299
  model: models.Model | models.KnownModelName | str | None = None,
300
300
  deps: AgentDepsT = None,
@@ -369,7 +369,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
369
369
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
370
370
  *,
371
371
  output_type: None = None,
372
- message_history: list[_messages.ModelMessage] | None = None,
372
+ message_history: Sequence[_messages.ModelMessage] | None = None,
373
373
  deferred_tool_results: DeferredToolResults | None = None,
374
374
  model: models.Model | models.KnownModelName | str | None = None,
375
375
  deps: AgentDepsT = None,
@@ -387,7 +387,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
387
387
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
388
388
  *,
389
389
  output_type: OutputSpec[RunOutputDataT],
390
- message_history: list[_messages.ModelMessage] | None = None,
390
+ message_history: Sequence[_messages.ModelMessage] | None = None,
391
391
  deferred_tool_results: DeferredToolResults | None = None,
392
392
  model: models.Model | models.KnownModelName | str | None = None,
393
393
  deps: AgentDepsT = None,
@@ -404,7 +404,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
404
404
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
405
405
  *,
406
406
  output_type: OutputSpec[RunOutputDataT] | None = None,
407
- message_history: list[_messages.ModelMessage] | None = None,
407
+ message_history: Sequence[_messages.ModelMessage] | None = None,
408
408
  deferred_tool_results: DeferredToolResults | None = None,
409
409
  model: models.Model | models.KnownModelName | str | None = None,
410
410
  deps: AgentDepsT = None,
@@ -477,7 +477,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
477
477
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
478
478
  *,
479
479
  output_type: None = None,
480
- message_history: list[_messages.ModelMessage] | None = None,
480
+ message_history: Sequence[_messages.ModelMessage] | None = None,
481
481
  deferred_tool_results: DeferredToolResults | None = None,
482
482
  model: models.Model | models.KnownModelName | str | None = None,
483
483
  deps: AgentDepsT = None,
@@ -495,7 +495,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
495
495
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
496
496
  *,
497
497
  output_type: OutputSpec[RunOutputDataT],
498
- message_history: list[_messages.ModelMessage] | None = None,
498
+ message_history: Sequence[_messages.ModelMessage] | None = None,
499
499
  deferred_tool_results: DeferredToolResults | None = None,
500
500
  model: models.Model | models.KnownModelName | str | None = None,
501
501
  deps: AgentDepsT = None,
@@ -513,7 +513,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
513
513
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
514
514
  *,
515
515
  output_type: OutputSpec[RunOutputDataT] | None = None,
516
- message_history: list[_messages.ModelMessage] | None = None,
516
+ message_history: Sequence[_messages.ModelMessage] | None = None,
517
517
  deferred_tool_results: DeferredToolResults | None = None,
518
518
  model: models.Model | models.KnownModelName | str | None = None,
519
519
  deps: AgentDepsT = None,
@@ -586,7 +586,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
586
586
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
587
587
  *,
588
588
  output_type: None = None,
589
- message_history: list[_messages.ModelMessage] | None = None,
589
+ message_history: Sequence[_messages.ModelMessage] | None = None,
590
590
  deferred_tool_results: DeferredToolResults | None = None,
591
591
  model: models.Model | models.KnownModelName | str | None = None,
592
592
  deps: AgentDepsT = None,
@@ -603,7 +603,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
603
603
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
604
604
  *,
605
605
  output_type: OutputSpec[RunOutputDataT],
606
- message_history: list[_messages.ModelMessage] | None = None,
606
+ message_history: Sequence[_messages.ModelMessage] | None = None,
607
607
  deferred_tool_results: DeferredToolResults | None = None,
608
608
  model: models.Model | models.KnownModelName | str | None = None,
609
609
  deps: AgentDepsT = None,
@@ -619,7 +619,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
619
619
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
620
620
  *,
621
621
  output_type: OutputSpec[RunOutputDataT] | None = None,
622
- message_history: list[_messages.ModelMessage] | None = None,
622
+ message_history: Sequence[_messages.ModelMessage] | None = None,
623
623
  deferred_tool_results: DeferredToolResults | None = None,
624
624
  model: models.Model | models.KnownModelName | str | None = None,
625
625
  deps: AgentDepsT = None,
@@ -704,7 +704,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
704
704
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
705
705
  *,
706
706
  output_type: None = None,
707
- message_history: list[_messages.ModelMessage] | None = None,
707
+ message_history: Sequence[_messages.ModelMessage] | None = None,
708
708
  deferred_tool_results: DeferredToolResults | None = None,
709
709
  model: models.Model | models.KnownModelName | str | None = None,
710
710
  deps: AgentDepsT = None,
@@ -722,7 +722,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
722
722
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
723
723
  *,
724
724
  output_type: OutputSpec[RunOutputDataT],
725
- message_history: list[_messages.ModelMessage] | None = None,
725
+ message_history: Sequence[_messages.ModelMessage] | None = None,
726
726
  deferred_tool_results: DeferredToolResults | None = None,
727
727
  model: models.Model | models.KnownModelName | str | None = None,
728
728
  deps: AgentDepsT = None,
@@ -740,7 +740,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
740
740
  user_prompt: str | Sequence[_messages.UserContent] | None = None,
741
741
  *,
742
742
  output_type: OutputSpec[RunOutputDataT] | None = None,
743
- message_history: list[_messages.ModelMessage] | None = None,
743
+ message_history: Sequence[_messages.ModelMessage] | None = None,
744
744
  deferred_tool_results: DeferredToolResults | None = None,
745
745
  model: models.Model | models.KnownModelName | str | None = None,
746
746
  deps: AgentDepsT = None,
@@ -862,18 +862,20 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
862
862
  def override(
863
863
  self,
864
864
  *,
865
+ name: str | _utils.Unset = _utils.UNSET,
865
866
  deps: AgentDepsT | _utils.Unset = _utils.UNSET,
866
867
  model: models.Model | models.KnownModelName | str | _utils.Unset = _utils.UNSET,
867
868
  toolsets: Sequence[AbstractToolset[AgentDepsT]] | _utils.Unset = _utils.UNSET,
868
869
  tools: Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]] | _utils.Unset = _utils.UNSET,
869
870
  instructions: Instructions[AgentDepsT] | _utils.Unset = _utils.UNSET,
870
871
  ) -> Iterator[None]:
871
- """Context manager to temporarily override agent dependencies, model, toolsets, tools, or instructions.
872
+ """Context manager to temporarily override agent name, dependencies, model, toolsets, tools, or instructions.
872
873
 
873
874
  This is particularly useful when testing.
874
875
  You can find an example of this [here](../testing.md#overriding-model-via-pytest-fixtures).
875
876
 
876
877
  Args:
878
+ name: The name to use instead of the name passed to the agent constructor and agent run.
877
879
  deps: The dependencies to use instead of the dependencies passed to the agent run.
878
880
  model: The model to use instead of the model passed to the agent run.
879
881
  toolsets: The toolsets to use instead of the toolsets passed to the agent constructor and agent run.
@@ -895,6 +897,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
895
897
  )
896
898
 
897
899
  with super().override(
900
+ name=name,
898
901
  deps=deps,
899
902
  model=model,
900
903
  toolsets=toolsets,
@@ -2,7 +2,7 @@ from __future__ import annotations as _annotations
2
2
 
3
3
  from collections.abc import Iterable, Iterator, Mapping
4
4
  from dataclasses import asdict, dataclass, field, fields, is_dataclass
5
- from datetime import date
5
+ from datetime import date, time, timedelta
6
6
  from enum import Enum
7
7
  from typing import Any, Literal
8
8
  from xml.etree import ElementTree
@@ -27,7 +27,7 @@ def format_as_xml(
27
27
  This is useful since LLMs often find it easier to read semi-structured data (e.g. examples) as XML,
28
28
  rather than JSON etc.
29
29
 
30
- Supports: `str`, `bytes`, `bytearray`, `bool`, `int`, `float`, `date`, `datetime`, `Enum`,
30
+ Supports: `str`, `bytes`, `bytearray`, `bool`, `int`, `float`, `date`, `datetime`, `time`, `timedelta`, `Enum`,
31
31
  `Mapping`, `Iterable`, `dataclass`, and `BaseModel`.
32
32
 
33
33
  Args:
@@ -104,8 +104,10 @@ class _ToXml:
104
104
  element.text = value.decode(errors='ignore')
105
105
  elif isinstance(value, bool | int | float | Enum):
106
106
  element.text = str(value)
107
- elif isinstance(value, date):
107
+ elif isinstance(value, date | time):
108
108
  element.text = value.isoformat()
109
+ elif isinstance(value, timedelta):
110
+ element.text = str(value)
109
111
  elif isinstance(value, Mapping):
110
112
  if tag is None and path in self._element_names:
111
113
  element.tag = self._element_names[path]
@@ -165,7 +167,7 @@ class _ToXml:
165
167
  path: str = '',
166
168
  ):
167
169
  """Parse data structures as dataclasses or Pydantic models to extract element names and attributes."""
168
- if value is None or isinstance(value, (str | int | float | date | bytearray | bytes | bool)):
170
+ if value is None or isinstance(value, (str | int | float | date | time | timedelta | bytearray | bytes | bool)):
169
171
  return
170
172
  elif isinstance(value, Mapping):
171
173
  for k, v in value.items(): # pyright: ignore[reportUnknownVariableType]
pydantic_ai/messages.py CHANGED
@@ -114,22 +114,8 @@ class FileUrl(ABC):
114
114
 
115
115
  _: KW_ONLY
116
116
 
117
- identifier: str
118
- """The identifier of the file, such as a unique ID. generating one from the url if not explicitly set.
119
-
120
- This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
121
- and the tool can look up the file in question by iterating over the message history and finding the matching `FileUrl`.
122
-
123
- This identifier is only automatically passed to the model when the `FileUrl` is returned by a tool.
124
- If you're passing the `FileUrl` as a user message, it's up to you to include a separate text part with the identifier,
125
- e.g. "This is file <identifier>:" preceding the `FileUrl`.
126
-
127
- It's also included in inline-text delimiters for providers that require inlining text documents, so the model can
128
- distinguish multiple files.
129
- """
130
-
131
117
  force_download: bool = False
132
- """If the model supports it:
118
+ """For OpenAI and Google APIs it:
133
119
 
134
120
  * If True, the file is downloaded and the data is sent to the model as bytes.
135
121
  * If False, the URL is sent directly to the model and no download is performed.
@@ -147,20 +133,24 @@ class FileUrl(ABC):
147
133
  compare=False, default=None
148
134
  )
149
135
 
136
+ _identifier: Annotated[str | None, pydantic.Field(alias='identifier', default=None, exclude=True)] = field(
137
+ compare=False, default=None
138
+ )
139
+
150
140
  def __init__(
151
141
  self,
152
142
  url: str,
153
143
  *,
154
- force_download: bool = False,
155
- vendor_metadata: dict[str, Any] | None = None,
156
144
  media_type: str | None = None,
157
145
  identifier: str | None = None,
146
+ force_download: bool = False,
147
+ vendor_metadata: dict[str, Any] | None = None,
158
148
  ) -> None:
159
149
  self.url = url
150
+ self._media_type = media_type
151
+ self._identifier = identifier
160
152
  self.force_download = force_download
161
153
  self.vendor_metadata = vendor_metadata
162
- self._media_type = media_type
163
- self.identifier = identifier or _multi_modal_content_identifier(url)
164
154
 
165
155
  @pydantic.computed_field
166
156
  @property
@@ -168,6 +158,23 @@ class FileUrl(ABC):
168
158
  """Return the media type of the file, based on the URL or the provided `media_type`."""
169
159
  return self._media_type or self._infer_media_type()
170
160
 
161
+ @pydantic.computed_field
162
+ @property
163
+ def identifier(self) -> str:
164
+ """The identifier of the file, such as a unique ID.
165
+
166
+ This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
167
+ and the tool can look up the file in question by iterating over the message history and finding the matching `FileUrl`.
168
+
169
+ This identifier is only automatically passed to the model when the `FileUrl` is returned by a tool.
170
+ If you're passing the `FileUrl` as a user message, it's up to you to include a separate text part with the identifier,
171
+ e.g. "This is file <identifier>:" preceding the `FileUrl`.
172
+
173
+ It's also included in inline-text delimiters for providers that require inlining text documents, so the model can
174
+ distinguish multiple files.
175
+ """
176
+ return self._identifier or _multi_modal_content_identifier(self.url)
177
+
171
178
  @abstractmethod
172
179
  def _infer_media_type(self) -> str:
173
180
  """Infer the media type of the file based on the URL."""
@@ -198,20 +205,21 @@ class VideoUrl(FileUrl):
198
205
  self,
199
206
  url: str,
200
207
  *,
208
+ media_type: str | None = None,
209
+ identifier: str | None = None,
201
210
  force_download: bool = False,
202
211
  vendor_metadata: dict[str, Any] | None = None,
203
- media_type: str | None = None,
204
212
  kind: Literal['video-url'] = 'video-url',
205
- identifier: str | None = None,
206
213
  # Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
207
214
  _media_type: str | None = None,
215
+ _identifier: str | None = None,
208
216
  ) -> None:
209
217
  super().__init__(
210
218
  url=url,
211
219
  force_download=force_download,
212
220
  vendor_metadata=vendor_metadata,
213
221
  media_type=media_type or _media_type,
214
- identifier=identifier,
222
+ identifier=identifier or _identifier,
215
223
  )
216
224
  self.kind = kind
217
225
 
@@ -273,20 +281,21 @@ class AudioUrl(FileUrl):
273
281
  self,
274
282
  url: str,
275
283
  *,
284
+ media_type: str | None = None,
285
+ identifier: str | None = None,
276
286
  force_download: bool = False,
277
287
  vendor_metadata: dict[str, Any] | None = None,
278
- media_type: str | None = None,
279
288
  kind: Literal['audio-url'] = 'audio-url',
280
- identifier: str | None = None,
281
289
  # Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
282
290
  _media_type: str | None = None,
291
+ _identifier: str | None = None,
283
292
  ) -> None:
284
293
  super().__init__(
285
294
  url=url,
286
295
  force_download=force_download,
287
296
  vendor_metadata=vendor_metadata,
288
297
  media_type=media_type or _media_type,
289
- identifier=identifier,
298
+ identifier=identifier or _identifier,
290
299
  )
291
300
  self.kind = kind
292
301
 
@@ -335,20 +344,21 @@ class ImageUrl(FileUrl):
335
344
  self,
336
345
  url: str,
337
346
  *,
347
+ media_type: str | None = None,
348
+ identifier: str | None = None,
338
349
  force_download: bool = False,
339
350
  vendor_metadata: dict[str, Any] | None = None,
340
- media_type: str | None = None,
341
351
  kind: Literal['image-url'] = 'image-url',
342
- identifier: str | None = None,
343
352
  # Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
344
353
  _media_type: str | None = None,
354
+ _identifier: str | None = None,
345
355
  ) -> None:
346
356
  super().__init__(
347
357
  url=url,
348
358
  force_download=force_download,
349
359
  vendor_metadata=vendor_metadata,
350
360
  media_type=media_type or _media_type,
351
- identifier=identifier,
361
+ identifier=identifier or _identifier,
352
362
  )
353
363
  self.kind = kind
354
364
 
@@ -392,20 +402,21 @@ class DocumentUrl(FileUrl):
392
402
  self,
393
403
  url: str,
394
404
  *,
405
+ media_type: str | None = None,
406
+ identifier: str | None = None,
395
407
  force_download: bool = False,
396
408
  vendor_metadata: dict[str, Any] | None = None,
397
- media_type: str | None = None,
398
409
  kind: Literal['document-url'] = 'document-url',
399
- identifier: str | None = None,
400
410
  # Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
401
411
  _media_type: str | None = None,
412
+ _identifier: str | None = None,
402
413
  ) -> None:
403
414
  super().__init__(
404
415
  url=url,
405
416
  force_download=force_download,
406
417
  vendor_metadata=vendor_metadata,
407
418
  media_type=media_type or _media_type,
408
- identifier=identifier,
419
+ identifier=identifier or _identifier,
409
420
  )
410
421
  self.kind = kind
411
422
 
@@ -460,16 +471,6 @@ class BinaryContent:
460
471
  media_type: AudioMediaType | ImageMediaType | DocumentMediaType | str
461
472
  """The media type of the binary data."""
462
473
 
463
- identifier: str
464
- """Identifier for the binary content, such as a unique ID.
465
- This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
466
- and the tool can look up the file in question by iterating over the message history and finding the matching `BinaryContent`.
467
-
468
- This identifier is only automatically passed to the model when the `BinaryContent` is returned by a tool.
469
- If you're passing the `BinaryContent` as a user message, it's up to you to include a separate text part with the identifier,
470
- e.g. "This is file <identifier>:" preceding the `BinaryContent`.
471
- """
472
-
473
474
  vendor_metadata: dict[str, Any] | None = None
474
475
  """Vendor-specific metadata for the file.
475
476
 
@@ -478,6 +479,10 @@ class BinaryContent:
478
479
  - `OpenAIChatModel`, `OpenAIResponsesModel`: `BinaryContent.vendor_metadata['detail']` is used as `detail` setting for images
479
480
  """
480
481
 
482
+ _identifier: Annotated[str | None, pydantic.Field(alias='identifier', default=None, exclude=True)] = field(
483
+ compare=False, default=None
484
+ )
485
+
481
486
  kind: Literal['binary'] = 'binary'
482
487
  """Type identifier, this is available on all parts as a discriminator."""
483
488
 
@@ -489,10 +494,12 @@ class BinaryContent:
489
494
  identifier: str | None = None,
490
495
  vendor_metadata: dict[str, Any] | None = None,
491
496
  kind: Literal['binary'] = 'binary',
497
+ # Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
498
+ _identifier: str | None = None,
492
499
  ) -> None:
493
500
  self.data = data
494
501
  self.media_type = media_type
495
- self.identifier = identifier or _multi_modal_content_identifier(data)
502
+ self._identifier = identifier or _identifier
496
503
  self.vendor_metadata = vendor_metadata
497
504
  self.kind = kind
498
505
 
@@ -518,6 +525,23 @@ class BinaryContent:
518
525
  media_type, data = data_uri[len(prefix) :].split(';base64,', 1)
519
526
  return cls(data=base64.b64decode(data), media_type=media_type)
520
527
 
528
+ @pydantic.computed_field
529
+ @property
530
+ def identifier(self) -> str:
531
+ """Identifier for the binary content, such as a unique ID.
532
+
533
+ This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
534
+ and the tool can look up the file in question by iterating over the message history and finding the matching `BinaryContent`.
535
+
536
+ This identifier is only automatically passed to the model when the `BinaryContent` is returned by a tool.
537
+ If you're passing the `BinaryContent` as a user message, it's up to you to include a separate text part with the identifier,
538
+ e.g. "This is file <identifier>:" preceding the `BinaryContent`.
539
+
540
+ It's also included in inline-text delimiters for providers that require inlining text documents, so the model can
541
+ distinguish multiple files.
542
+ """
543
+ return self._identifier or _multi_modal_content_identifier(self.data)
544
+
521
545
  @property
522
546
  def data_uri(self) -> str:
523
547
  """Convert the `BinaryContent` to a data URI."""