pydantic-ai-slim 1.0.15__py3-none-any.whl → 1.0.17__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.
- pydantic_ai/_agent_graph.py +13 -12
- pydantic_ai/_cli.py +3 -3
- pydantic_ai/agent/__init__.py +33 -9
- pydantic_ai/agent/abstract.py +54 -26
- pydantic_ai/agent/wrapper.py +13 -4
- pydantic_ai/builtin_tools.py +4 -1
- pydantic_ai/direct.py +9 -9
- pydantic_ai/durable_exec/dbos/_agent.py +52 -20
- pydantic_ai/durable_exec/temporal/_agent.py +45 -16
- pydantic_ai/format_prompt.py +6 -4
- pydantic_ai/messages.py +71 -43
- pydantic_ai/models/anthropic.py +20 -19
- pydantic_ai/models/openai.py +9 -1
- pydantic_ai/result.py +5 -5
- pydantic_ai/usage.py +35 -1
- {pydantic_ai_slim-1.0.15.dist-info → pydantic_ai_slim-1.0.17.dist-info}/METADATA +4 -4
- {pydantic_ai_slim-1.0.15.dist-info → pydantic_ai_slim-1.0.17.dist-info}/RECORD +20 -20
- {pydantic_ai_slim-1.0.15.dist-info → pydantic_ai_slim-1.0.17.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-1.0.15.dist-info → pydantic_ai_slim-1.0.17.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-1.0.15.dist-info → pydantic_ai_slim-1.0.17.dist-info}/licenses/LICENSE +0 -0
|
@@ -25,6 +25,7 @@ from pydantic_ai import (
|
|
|
25
25
|
)
|
|
26
26
|
from pydantic_ai.agent import AbstractAgent, AgentRun, AgentRunResult, EventStreamHandler, WrapperAgent
|
|
27
27
|
from pydantic_ai.agent.abstract import Instructions, RunOutputDataT
|
|
28
|
+
from pydantic_ai.builtin_tools import AbstractBuiltinTool
|
|
28
29
|
from pydantic_ai.exceptions import UserError
|
|
29
30
|
from pydantic_ai.models import Model
|
|
30
31
|
from pydantic_ai.output import OutputDataT, OutputSpec
|
|
@@ -259,7 +260,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
259
260
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
260
261
|
*,
|
|
261
262
|
output_type: None = None,
|
|
262
|
-
message_history:
|
|
263
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
263
264
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
264
265
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
265
266
|
deps: AgentDepsT = None,
|
|
@@ -268,6 +269,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
268
269
|
usage: _usage.RunUsage | None = None,
|
|
269
270
|
infer_name: bool = True,
|
|
270
271
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
272
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
271
273
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
272
274
|
) -> AgentRunResult[OutputDataT]: ...
|
|
273
275
|
|
|
@@ -277,7 +279,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
277
279
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
278
280
|
*,
|
|
279
281
|
output_type: OutputSpec[RunOutputDataT],
|
|
280
|
-
message_history:
|
|
282
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
281
283
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
282
284
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
283
285
|
deps: AgentDepsT = None,
|
|
@@ -286,6 +288,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
286
288
|
usage: _usage.RunUsage | None = None,
|
|
287
289
|
infer_name: bool = True,
|
|
288
290
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
291
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
289
292
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
290
293
|
) -> AgentRunResult[RunOutputDataT]: ...
|
|
291
294
|
|
|
@@ -294,7 +297,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
294
297
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
295
298
|
*,
|
|
296
299
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
297
|
-
message_history:
|
|
300
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
298
301
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
299
302
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
300
303
|
deps: AgentDepsT = None,
|
|
@@ -303,6 +306,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
303
306
|
usage: _usage.RunUsage | None = None,
|
|
304
307
|
infer_name: bool = True,
|
|
305
308
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
309
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
306
310
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
307
311
|
**_deprecated_kwargs: Never,
|
|
308
312
|
) -> AgentRunResult[Any]:
|
|
@@ -337,6 +341,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
337
341
|
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
338
342
|
toolsets: Optional additional toolsets for this run.
|
|
339
343
|
event_stream_handler: Optional event stream handler to use for this run.
|
|
344
|
+
builtin_tools: Optional additional builtin tools for this run.
|
|
340
345
|
|
|
341
346
|
Returns:
|
|
342
347
|
The result of the run.
|
|
@@ -359,6 +364,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
359
364
|
usage=usage,
|
|
360
365
|
infer_name=infer_name,
|
|
361
366
|
toolsets=toolsets,
|
|
367
|
+
builtin_tools=builtin_tools,
|
|
362
368
|
event_stream_handler=event_stream_handler or self.event_stream_handler,
|
|
363
369
|
**_deprecated_kwargs,
|
|
364
370
|
)
|
|
@@ -369,7 +375,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
369
375
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
370
376
|
*,
|
|
371
377
|
output_type: None = None,
|
|
372
|
-
message_history:
|
|
378
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
373
379
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
374
380
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
375
381
|
deps: AgentDepsT = None,
|
|
@@ -378,6 +384,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
378
384
|
usage: _usage.RunUsage | None = None,
|
|
379
385
|
infer_name: bool = True,
|
|
380
386
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
387
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
381
388
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
382
389
|
) -> AgentRunResult[OutputDataT]: ...
|
|
383
390
|
|
|
@@ -387,7 +394,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
387
394
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
388
395
|
*,
|
|
389
396
|
output_type: OutputSpec[RunOutputDataT],
|
|
390
|
-
message_history:
|
|
397
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
391
398
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
392
399
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
393
400
|
deps: AgentDepsT = None,
|
|
@@ -396,6 +403,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
396
403
|
usage: _usage.RunUsage | None = None,
|
|
397
404
|
infer_name: bool = True,
|
|
398
405
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
406
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
399
407
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
400
408
|
) -> AgentRunResult[RunOutputDataT]: ...
|
|
401
409
|
|
|
@@ -404,7 +412,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
404
412
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
405
413
|
*,
|
|
406
414
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
407
|
-
message_history:
|
|
415
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
408
416
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
409
417
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
410
418
|
deps: AgentDepsT = None,
|
|
@@ -413,6 +421,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
413
421
|
usage: _usage.RunUsage | None = None,
|
|
414
422
|
infer_name: bool = True,
|
|
415
423
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
424
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
416
425
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
417
426
|
**_deprecated_kwargs: Never,
|
|
418
427
|
) -> AgentRunResult[Any]:
|
|
@@ -446,6 +455,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
446
455
|
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
447
456
|
toolsets: Optional additional toolsets for this run.
|
|
448
457
|
event_stream_handler: Optional event stream handler to use for this run.
|
|
458
|
+
builtin_tools: Optional additional builtin tools for this run.
|
|
449
459
|
|
|
450
460
|
Returns:
|
|
451
461
|
The result of the run.
|
|
@@ -467,6 +477,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
467
477
|
usage=usage,
|
|
468
478
|
infer_name=infer_name,
|
|
469
479
|
toolsets=toolsets,
|
|
480
|
+
builtin_tools=builtin_tools,
|
|
470
481
|
event_stream_handler=event_stream_handler,
|
|
471
482
|
**_deprecated_kwargs,
|
|
472
483
|
)
|
|
@@ -477,7 +488,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
477
488
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
478
489
|
*,
|
|
479
490
|
output_type: None = None,
|
|
480
|
-
message_history:
|
|
491
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
481
492
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
482
493
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
483
494
|
deps: AgentDepsT = None,
|
|
@@ -486,6 +497,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
486
497
|
usage: _usage.RunUsage | None = None,
|
|
487
498
|
infer_name: bool = True,
|
|
488
499
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
500
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
489
501
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
490
502
|
) -> AbstractAsyncContextManager[StreamedRunResult[AgentDepsT, OutputDataT]]: ...
|
|
491
503
|
|
|
@@ -495,7 +507,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
495
507
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
496
508
|
*,
|
|
497
509
|
output_type: OutputSpec[RunOutputDataT],
|
|
498
|
-
message_history:
|
|
510
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
499
511
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
500
512
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
501
513
|
deps: AgentDepsT = None,
|
|
@@ -504,6 +516,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
504
516
|
usage: _usage.RunUsage | None = None,
|
|
505
517
|
infer_name: bool = True,
|
|
506
518
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
519
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
507
520
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
508
521
|
) -> AbstractAsyncContextManager[StreamedRunResult[AgentDepsT, RunOutputDataT]]: ...
|
|
509
522
|
|
|
@@ -513,7 +526,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
513
526
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
514
527
|
*,
|
|
515
528
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
516
|
-
message_history:
|
|
529
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
517
530
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
518
531
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
519
532
|
deps: AgentDepsT = None,
|
|
@@ -522,6 +535,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
522
535
|
usage: _usage.RunUsage | None = None,
|
|
523
536
|
infer_name: bool = True,
|
|
524
537
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
538
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
525
539
|
event_stream_handler: EventStreamHandler[AgentDepsT] | None = None,
|
|
526
540
|
**_deprecated_kwargs: Never,
|
|
527
541
|
) -> AsyncIterator[StreamedRunResult[AgentDepsT, Any]]:
|
|
@@ -552,6 +566,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
552
566
|
usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
|
|
553
567
|
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
554
568
|
toolsets: Optional additional toolsets for this run.
|
|
569
|
+
builtin_tools: Optional additional builtin tools for this run.
|
|
555
570
|
event_stream_handler: Optional event stream handler to use for this run. It will receive all the events up until the final result is found, which you can then read or stream from inside the context manager.
|
|
556
571
|
|
|
557
572
|
Returns:
|
|
@@ -576,6 +591,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
576
591
|
infer_name=infer_name,
|
|
577
592
|
toolsets=toolsets,
|
|
578
593
|
event_stream_handler=event_stream_handler,
|
|
594
|
+
builtin_tools=builtin_tools,
|
|
579
595
|
**_deprecated_kwargs,
|
|
580
596
|
) as result:
|
|
581
597
|
yield result
|
|
@@ -586,7 +602,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
586
602
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
587
603
|
*,
|
|
588
604
|
output_type: None = None,
|
|
589
|
-
message_history:
|
|
605
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
590
606
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
591
607
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
592
608
|
deps: AgentDepsT = None,
|
|
@@ -595,6 +611,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
595
611
|
usage: _usage.RunUsage | None = None,
|
|
596
612
|
infer_name: bool = True,
|
|
597
613
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
614
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
598
615
|
) -> AsyncIterator[_messages.AgentStreamEvent | AgentRunResultEvent[OutputDataT]]: ...
|
|
599
616
|
|
|
600
617
|
@overload
|
|
@@ -603,7 +620,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
603
620
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
604
621
|
*,
|
|
605
622
|
output_type: OutputSpec[RunOutputDataT],
|
|
606
|
-
message_history:
|
|
623
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
607
624
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
608
625
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
609
626
|
deps: AgentDepsT = None,
|
|
@@ -612,6 +629,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
612
629
|
usage: _usage.RunUsage | None = None,
|
|
613
630
|
infer_name: bool = True,
|
|
614
631
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
632
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
615
633
|
) -> AsyncIterator[_messages.AgentStreamEvent | AgentRunResultEvent[RunOutputDataT]]: ...
|
|
616
634
|
|
|
617
635
|
def run_stream_events(
|
|
@@ -619,7 +637,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
619
637
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
620
638
|
*,
|
|
621
639
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
622
|
-
message_history:
|
|
640
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
623
641
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
624
642
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
625
643
|
deps: AgentDepsT = None,
|
|
@@ -628,6 +646,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
628
646
|
usage: _usage.RunUsage | None = None,
|
|
629
647
|
infer_name: bool = True,
|
|
630
648
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
649
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
631
650
|
) -> AsyncIterator[_messages.AgentStreamEvent | AgentRunResultEvent[Any]]:
|
|
632
651
|
"""Run the agent with a user prompt in async mode and stream events from the run.
|
|
633
652
|
|
|
@@ -673,6 +692,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
673
692
|
usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
|
|
674
693
|
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
675
694
|
toolsets: Optional additional toolsets for this run.
|
|
695
|
+
builtin_tools: Optional additional builtin tools for this run.
|
|
676
696
|
|
|
677
697
|
Returns:
|
|
678
698
|
An async iterable of stream events `AgentStreamEvent` and finally a `AgentRunResultEvent` with the final
|
|
@@ -696,6 +716,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
696
716
|
usage=usage,
|
|
697
717
|
infer_name=infer_name,
|
|
698
718
|
toolsets=toolsets,
|
|
719
|
+
builtin_tools=builtin_tools,
|
|
699
720
|
)
|
|
700
721
|
|
|
701
722
|
@overload
|
|
@@ -704,7 +725,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
704
725
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
705
726
|
*,
|
|
706
727
|
output_type: None = None,
|
|
707
|
-
message_history:
|
|
728
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
708
729
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
709
730
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
710
731
|
deps: AgentDepsT = None,
|
|
@@ -712,6 +733,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
712
733
|
usage_limits: _usage.UsageLimits | None = None,
|
|
713
734
|
usage: _usage.RunUsage | None = None,
|
|
714
735
|
infer_name: bool = True,
|
|
736
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
715
737
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
716
738
|
**_deprecated_kwargs: Never,
|
|
717
739
|
) -> AbstractAsyncContextManager[AgentRun[AgentDepsT, OutputDataT]]: ...
|
|
@@ -722,7 +744,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
722
744
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
723
745
|
*,
|
|
724
746
|
output_type: OutputSpec[RunOutputDataT],
|
|
725
|
-
message_history:
|
|
747
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
726
748
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
727
749
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
728
750
|
deps: AgentDepsT = None,
|
|
@@ -731,6 +753,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
731
753
|
usage: _usage.RunUsage | None = None,
|
|
732
754
|
infer_name: bool = True,
|
|
733
755
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
756
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
734
757
|
**_deprecated_kwargs: Never,
|
|
735
758
|
) -> AbstractAsyncContextManager[AgentRun[AgentDepsT, RunOutputDataT]]: ...
|
|
736
759
|
|
|
@@ -740,7 +763,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
740
763
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
741
764
|
*,
|
|
742
765
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
743
|
-
message_history:
|
|
766
|
+
message_history: Sequence[_messages.ModelMessage] | None = None,
|
|
744
767
|
deferred_tool_results: DeferredToolResults | None = None,
|
|
745
768
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
746
769
|
deps: AgentDepsT = None,
|
|
@@ -749,6 +772,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
749
772
|
usage: _usage.RunUsage | None = None,
|
|
750
773
|
infer_name: bool = True,
|
|
751
774
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
|
|
775
|
+
builtin_tools: Sequence[AbstractBuiltinTool] | None = None,
|
|
752
776
|
**_deprecated_kwargs: Never,
|
|
753
777
|
) -> AsyncIterator[AgentRun[AgentDepsT, Any]]:
|
|
754
778
|
"""A contextmanager which can be used to iterate over the agent graph's nodes as they are executed.
|
|
@@ -822,6 +846,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
822
846
|
usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
|
|
823
847
|
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
824
848
|
toolsets: Optional additional toolsets for this run.
|
|
849
|
+
builtin_tools: Optional additional builtin tools for this run.
|
|
825
850
|
|
|
826
851
|
Returns:
|
|
827
852
|
The result of the run.
|
|
@@ -854,6 +879,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
854
879
|
usage=usage,
|
|
855
880
|
infer_name=infer_name,
|
|
856
881
|
toolsets=toolsets,
|
|
882
|
+
builtin_tools=builtin_tools,
|
|
857
883
|
**_deprecated_kwargs,
|
|
858
884
|
) as run:
|
|
859
885
|
yield run
|
|
@@ -862,18 +888,20 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
862
888
|
def override(
|
|
863
889
|
self,
|
|
864
890
|
*,
|
|
891
|
+
name: str | _utils.Unset = _utils.UNSET,
|
|
865
892
|
deps: AgentDepsT | _utils.Unset = _utils.UNSET,
|
|
866
893
|
model: models.Model | models.KnownModelName | str | _utils.Unset = _utils.UNSET,
|
|
867
894
|
toolsets: Sequence[AbstractToolset[AgentDepsT]] | _utils.Unset = _utils.UNSET,
|
|
868
895
|
tools: Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]] | _utils.Unset = _utils.UNSET,
|
|
869
896
|
instructions: Instructions[AgentDepsT] | _utils.Unset = _utils.UNSET,
|
|
870
897
|
) -> Iterator[None]:
|
|
871
|
-
"""Context manager to temporarily override agent dependencies, model, toolsets, tools, or instructions.
|
|
898
|
+
"""Context manager to temporarily override agent name, dependencies, model, toolsets, tools, or instructions.
|
|
872
899
|
|
|
873
900
|
This is particularly useful when testing.
|
|
874
901
|
You can find an example of this [here](../testing.md#overriding-model-via-pytest-fixtures).
|
|
875
902
|
|
|
876
903
|
Args:
|
|
904
|
+
name: The name to use instead of the name passed to the agent constructor and agent run.
|
|
877
905
|
deps: The dependencies to use instead of the dependencies passed to the agent run.
|
|
878
906
|
model: The model to use instead of the model passed to the agent run.
|
|
879
907
|
toolsets: The toolsets to use instead of the toolsets passed to the agent constructor and agent run.
|
|
@@ -895,6 +923,7 @@ class TemporalAgent(WrapperAgent[AgentDepsT, OutputDataT]):
|
|
|
895
923
|
)
|
|
896
924
|
|
|
897
925
|
with super().override(
|
|
926
|
+
name=name,
|
|
898
927
|
deps=deps,
|
|
899
928
|
model=model,
|
|
900
929
|
toolsets=toolsets,
|
pydantic_ai/format_prompt.py
CHANGED
|
@@ -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
|
-
"""
|
|
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.
|
|
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."""
|
|
@@ -571,9 +595,13 @@ class BinaryImage(BinaryContent):
|
|
|
571
595
|
media_type: str,
|
|
572
596
|
identifier: str | None = None,
|
|
573
597
|
vendor_metadata: dict[str, Any] | None = None,
|
|
598
|
+
# Required for inline-snapshot which expects all dataclass `__init__` methods to take all field names as kwargs.
|
|
574
599
|
kind: Literal['binary'] = 'binary',
|
|
600
|
+
_identifier: str | None = None,
|
|
575
601
|
):
|
|
576
|
-
super().__init__(
|
|
602
|
+
super().__init__(
|
|
603
|
+
data=data, media_type=media_type, identifier=identifier or _identifier, vendor_metadata=vendor_metadata
|
|
604
|
+
)
|
|
577
605
|
|
|
578
606
|
if not self.is_image:
|
|
579
607
|
raise ValueError('`BinaryImage` must be have a media type that starts with "image/"') # pragma: no cover
|