pydantic-ai-slim 0.8.0__py3-none-any.whl → 1.0.0b1__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.
- pydantic_ai/__init__.py +28 -2
- pydantic_ai/_agent_graph.py +310 -140
- pydantic_ai/_function_schema.py +5 -5
- pydantic_ai/_griffe.py +2 -1
- pydantic_ai/_otel_messages.py +2 -2
- pydantic_ai/_output.py +31 -35
- pydantic_ai/_parts_manager.py +4 -4
- pydantic_ai/_run_context.py +3 -1
- pydantic_ai/_system_prompt.py +2 -2
- pydantic_ai/_tool_manager.py +3 -22
- pydantic_ai/_utils.py +14 -26
- pydantic_ai/ag_ui.py +7 -8
- pydantic_ai/agent/__init__.py +84 -17
- pydantic_ai/agent/abstract.py +35 -4
- pydantic_ai/agent/wrapper.py +6 -0
- pydantic_ai/builtin_tools.py +2 -2
- pydantic_ai/common_tools/duckduckgo.py +4 -2
- pydantic_ai/durable_exec/temporal/__init__.py +70 -17
- pydantic_ai/durable_exec/temporal/_agent.py +23 -2
- pydantic_ai/durable_exec/temporal/_function_toolset.py +53 -6
- pydantic_ai/durable_exec/temporal/_logfire.py +6 -3
- pydantic_ai/durable_exec/temporal/_mcp_server.py +2 -1
- pydantic_ai/durable_exec/temporal/_model.py +2 -2
- pydantic_ai/durable_exec/temporal/_run_context.py +2 -1
- pydantic_ai/durable_exec/temporal/_toolset.py +2 -1
- pydantic_ai/exceptions.py +45 -2
- pydantic_ai/format_prompt.py +2 -2
- pydantic_ai/mcp.py +2 -2
- pydantic_ai/messages.py +81 -28
- pydantic_ai/models/__init__.py +19 -7
- pydantic_ai/models/anthropic.py +6 -6
- pydantic_ai/models/bedrock.py +63 -57
- pydantic_ai/models/cohere.py +3 -3
- pydantic_ai/models/fallback.py +2 -2
- pydantic_ai/models/function.py +25 -23
- pydantic_ai/models/gemini.py +10 -13
- pydantic_ai/models/google.py +4 -4
- pydantic_ai/models/groq.py +5 -5
- pydantic_ai/models/huggingface.py +5 -5
- pydantic_ai/models/instrumented.py +44 -21
- pydantic_ai/models/mcp_sampling.py +3 -1
- pydantic_ai/models/mistral.py +8 -8
- pydantic_ai/models/openai.py +20 -29
- pydantic_ai/models/test.py +24 -4
- pydantic_ai/output.py +27 -32
- pydantic_ai/profiles/__init__.py +3 -3
- pydantic_ai/profiles/groq.py +1 -1
- pydantic_ai/profiles/openai.py +25 -4
- pydantic_ai/providers/anthropic.py +2 -3
- pydantic_ai/providers/bedrock.py +3 -2
- pydantic_ai/result.py +173 -52
- pydantic_ai/retries.py +10 -29
- pydantic_ai/run.py +12 -5
- pydantic_ai/tools.py +126 -22
- pydantic_ai/toolsets/__init__.py +4 -1
- pydantic_ai/toolsets/_dynamic.py +4 -4
- pydantic_ai/toolsets/abstract.py +18 -2
- pydantic_ai/toolsets/approval_required.py +32 -0
- pydantic_ai/toolsets/combined.py +7 -12
- pydantic_ai/toolsets/{deferred.py → external.py} +11 -5
- pydantic_ai/toolsets/filtered.py +1 -1
- pydantic_ai/toolsets/function.py +13 -4
- pydantic_ai/toolsets/wrapper.py +2 -1
- pydantic_ai/usage.py +7 -5
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/METADATA +6 -7
- pydantic_ai_slim-1.0.0b1.dist-info/RECORD +120 -0
- pydantic_ai_slim-0.8.0.dist-info/RECORD +0 -119
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/licenses/LICENSE +0 -0
pydantic_ai/agent/__init__.py
CHANGED
|
@@ -4,12 +4,12 @@ import dataclasses
|
|
|
4
4
|
import inspect
|
|
5
5
|
import json
|
|
6
6
|
import warnings
|
|
7
|
-
from
|
|
8
|
-
from collections.abc import AsyncIterator, Awaitable, Iterator, Sequence
|
|
7
|
+
from collections.abc import AsyncIterator, Awaitable, Callable, Iterator, Sequence
|
|
9
8
|
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager, contextmanager
|
|
10
9
|
from contextvars import ContextVar
|
|
11
|
-
from typing import TYPE_CHECKING, Any,
|
|
10
|
+
from typing import TYPE_CHECKING, Any, ClassVar, cast, overload
|
|
12
11
|
|
|
12
|
+
import anyio
|
|
13
13
|
from opentelemetry.trace import NoOpTracer, use_span
|
|
14
14
|
from pydantic.json_schema import GenerateJsonSchema
|
|
15
15
|
from typing_extensions import TypeVar, deprecated
|
|
@@ -45,10 +45,15 @@ from ..run import AgentRun, AgentRunResult
|
|
|
45
45
|
from ..settings import ModelSettings, merge_model_settings
|
|
46
46
|
from ..tools import (
|
|
47
47
|
AgentDepsT,
|
|
48
|
+
DeferredToolCallResult,
|
|
49
|
+
DeferredToolResult,
|
|
50
|
+
DeferredToolResults,
|
|
48
51
|
DocstringFormat,
|
|
49
52
|
GenerateToolJsonSchema,
|
|
50
53
|
RunContext,
|
|
51
54
|
Tool,
|
|
55
|
+
ToolApproved,
|
|
56
|
+
ToolDenied,
|
|
52
57
|
ToolFuncContext,
|
|
53
58
|
ToolFuncEither,
|
|
54
59
|
ToolFuncPlain,
|
|
@@ -152,7 +157,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
152
157
|
|
|
153
158
|
_event_stream_handler: EventStreamHandler[AgentDepsT] | None = dataclasses.field(repr=False)
|
|
154
159
|
|
|
155
|
-
_enter_lock: Lock = dataclasses.field(repr=False)
|
|
160
|
+
_enter_lock: anyio.Lock = dataclasses.field(repr=False)
|
|
156
161
|
_entered_count: int = dataclasses.field(repr=False)
|
|
157
162
|
_exit_stack: AsyncExitStack | None = dataclasses.field(repr=False)
|
|
158
163
|
|
|
@@ -321,7 +326,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
321
326
|
|
|
322
327
|
self._instructions = ''
|
|
323
328
|
self._instructions_functions = []
|
|
324
|
-
if isinstance(instructions,
|
|
329
|
+
if isinstance(instructions, str | Callable):
|
|
325
330
|
instructions = [instructions]
|
|
326
331
|
for instruction in instructions or []:
|
|
327
332
|
if isinstance(instruction, str):
|
|
@@ -346,7 +351,9 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
346
351
|
if self._output_toolset:
|
|
347
352
|
self._output_toolset.max_retries = self._max_result_retries
|
|
348
353
|
|
|
349
|
-
self._function_toolset = _AgentFunctionToolset(
|
|
354
|
+
self._function_toolset = _AgentFunctionToolset(
|
|
355
|
+
tools, max_retries=self._max_tool_retries, output_schema=self._output_schema
|
|
356
|
+
)
|
|
350
357
|
self._dynamic_toolsets = [
|
|
351
358
|
DynamicToolset[AgentDepsT](toolset_func=toolset)
|
|
352
359
|
for toolset in toolsets or []
|
|
@@ -367,7 +374,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
367
374
|
_utils.Option[Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]]]
|
|
368
375
|
] = ContextVar('_override_tools', default=None)
|
|
369
376
|
|
|
370
|
-
self._enter_lock =
|
|
377
|
+
self._enter_lock = anyio.Lock()
|
|
371
378
|
self._entered_count = 0
|
|
372
379
|
self._exit_stack = None
|
|
373
380
|
|
|
@@ -427,6 +434,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
427
434
|
*,
|
|
428
435
|
output_type: None = None,
|
|
429
436
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
437
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
430
438
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
431
439
|
deps: AgentDepsT = None,
|
|
432
440
|
model_settings: ModelSettings | None = None,
|
|
@@ -443,6 +451,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
443
451
|
*,
|
|
444
452
|
output_type: OutputSpec[RunOutputDataT],
|
|
445
453
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
454
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
446
455
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
447
456
|
deps: AgentDepsT = None,
|
|
448
457
|
model_settings: ModelSettings | None = None,
|
|
@@ -453,12 +462,13 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
453
462
|
) -> AbstractAsyncContextManager[AgentRun[AgentDepsT, RunOutputDataT]]: ...
|
|
454
463
|
|
|
455
464
|
@asynccontextmanager
|
|
456
|
-
async def iter(
|
|
465
|
+
async def iter( # noqa: C901
|
|
457
466
|
self,
|
|
458
467
|
user_prompt: str | Sequence[_messages.UserContent] | None = None,
|
|
459
468
|
*,
|
|
460
469
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
461
470
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
471
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
462
472
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
463
473
|
deps: AgentDepsT = None,
|
|
464
474
|
model_settings: ModelSettings | None = None,
|
|
@@ -531,6 +541,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
531
541
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
532
542
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
533
543
|
message_history: History of the conversation so far.
|
|
544
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
534
545
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
535
546
|
deps: Optional dependencies to use for this run.
|
|
536
547
|
model_settings: Optional settings to use for this model's request.
|
|
@@ -609,6 +620,23 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
609
620
|
instrumentation_settings = None
|
|
610
621
|
tracer = NoOpTracer()
|
|
611
622
|
|
|
623
|
+
tool_call_results: dict[str, DeferredToolResult] | None = None
|
|
624
|
+
if deferred_tool_results is not None:
|
|
625
|
+
tool_call_results = {}
|
|
626
|
+
for tool_call_id, approval in deferred_tool_results.approvals.items():
|
|
627
|
+
if approval is True:
|
|
628
|
+
approval = ToolApproved()
|
|
629
|
+
elif approval is False:
|
|
630
|
+
approval = ToolDenied()
|
|
631
|
+
tool_call_results[tool_call_id] = approval
|
|
632
|
+
|
|
633
|
+
if calls := deferred_tool_results.calls:
|
|
634
|
+
call_result_types = _utils.get_union_args(DeferredToolCallResult)
|
|
635
|
+
for tool_call_id, result in calls.items():
|
|
636
|
+
if not isinstance(result, call_result_types):
|
|
637
|
+
result = _messages.ToolReturn(result)
|
|
638
|
+
tool_call_results[tool_call_id] = result
|
|
639
|
+
|
|
612
640
|
graph_deps = _agent_graph.GraphAgentDeps[AgentDepsT, RunOutputDataT](
|
|
613
641
|
user_deps=deps,
|
|
614
642
|
prompt=user_prompt,
|
|
@@ -623,6 +651,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
623
651
|
history_processors=self.history_processors,
|
|
624
652
|
builtin_tools=list(self._builtin_tools),
|
|
625
653
|
tool_manager=tool_manager,
|
|
654
|
+
tool_call_results=tool_call_results,
|
|
626
655
|
tracer=tracer,
|
|
627
656
|
get_instructions=get_instructions,
|
|
628
657
|
instrumentation_settings=instrumentation_settings,
|
|
@@ -678,22 +707,28 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
678
707
|
self, state: _agent_graph.GraphAgentState, usage: _usage.RunUsage, settings: InstrumentationSettings
|
|
679
708
|
):
|
|
680
709
|
if settings.version == 1:
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
710
|
+
attrs = {
|
|
711
|
+
'all_messages_events': json.dumps(
|
|
712
|
+
[
|
|
713
|
+
InstrumentedModel.event_to_dict(e)
|
|
714
|
+
for e in settings.messages_to_otel_events(state.message_history)
|
|
715
|
+
]
|
|
716
|
+
)
|
|
717
|
+
}
|
|
685
718
|
else:
|
|
686
|
-
|
|
687
|
-
|
|
719
|
+
attrs = {
|
|
720
|
+
'pydantic_ai.all_messages': json.dumps(settings.messages_to_otel_messages(state.message_history)),
|
|
721
|
+
**settings.system_instructions_attributes(self._instructions),
|
|
722
|
+
}
|
|
688
723
|
|
|
689
724
|
return {
|
|
690
725
|
**usage.opentelemetry_attributes(),
|
|
691
|
-
|
|
726
|
+
**attrs,
|
|
692
727
|
'logfire.json_schema': json.dumps(
|
|
693
728
|
{
|
|
694
729
|
'type': 'object',
|
|
695
730
|
'properties': {
|
|
696
|
-
|
|
731
|
+
**{attr: {'type': 'array'} for attr in attrs.keys()},
|
|
697
732
|
'final_result': {'type': 'object'},
|
|
698
733
|
},
|
|
699
734
|
}
|
|
@@ -970,6 +1005,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
970
1005
|
require_parameter_descriptions: bool = False,
|
|
971
1006
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
972
1007
|
strict: bool | None = None,
|
|
1008
|
+
requires_approval: bool = False,
|
|
973
1009
|
) -> Callable[[ToolFuncContext[AgentDepsT, ToolParams]], ToolFuncContext[AgentDepsT, ToolParams]]: ...
|
|
974
1010
|
|
|
975
1011
|
def tool(
|
|
@@ -984,6 +1020,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
984
1020
|
require_parameter_descriptions: bool = False,
|
|
985
1021
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
986
1022
|
strict: bool | None = None,
|
|
1023
|
+
requires_approval: bool = False,
|
|
987
1024
|
) -> Any:
|
|
988
1025
|
"""Decorator to register a tool function which takes [`RunContext`][pydantic_ai.tools.RunContext] as its first argument.
|
|
989
1026
|
|
|
@@ -1028,6 +1065,8 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1028
1065
|
schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
|
|
1029
1066
|
strict: Whether to enforce JSON schema compliance (only affects OpenAI).
|
|
1030
1067
|
See [`ToolDefinition`][pydantic_ai.tools.ToolDefinition] for more info.
|
|
1068
|
+
requires_approval: Whether this tool requires human-in-the-loop approval. Defaults to False.
|
|
1069
|
+
See the [tools documentation](../tools.md#human-in-the-loop-tool-approval) for more info.
|
|
1031
1070
|
"""
|
|
1032
1071
|
|
|
1033
1072
|
def tool_decorator(
|
|
@@ -1044,6 +1083,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1044
1083
|
require_parameter_descriptions,
|
|
1045
1084
|
schema_generator,
|
|
1046
1085
|
strict,
|
|
1086
|
+
requires_approval,
|
|
1047
1087
|
)
|
|
1048
1088
|
return func_
|
|
1049
1089
|
|
|
@@ -1064,6 +1104,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1064
1104
|
require_parameter_descriptions: bool = False,
|
|
1065
1105
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
1066
1106
|
strict: bool | None = None,
|
|
1107
|
+
requires_approval: bool = False,
|
|
1067
1108
|
) -> Callable[[ToolFuncPlain[ToolParams]], ToolFuncPlain[ToolParams]]: ...
|
|
1068
1109
|
|
|
1069
1110
|
def tool_plain(
|
|
@@ -1078,6 +1119,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1078
1119
|
require_parameter_descriptions: bool = False,
|
|
1079
1120
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
1080
1121
|
strict: bool | None = None,
|
|
1122
|
+
requires_approval: bool = False,
|
|
1081
1123
|
) -> Any:
|
|
1082
1124
|
"""Decorator to register a tool function which DOES NOT take `RunContext` as an argument.
|
|
1083
1125
|
|
|
@@ -1122,6 +1164,8 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1122
1164
|
schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
|
|
1123
1165
|
strict: Whether to enforce JSON schema compliance (only affects OpenAI).
|
|
1124
1166
|
See [`ToolDefinition`][pydantic_ai.tools.ToolDefinition] for more info.
|
|
1167
|
+
requires_approval: Whether this tool requires human-in-the-loop approval. Defaults to False.
|
|
1168
|
+
See the [tools documentation](../tools.md#human-in-the-loop-tool-approval) for more info.
|
|
1125
1169
|
"""
|
|
1126
1170
|
|
|
1127
1171
|
def tool_decorator(func_: ToolFuncPlain[ToolParams]) -> ToolFuncPlain[ToolParams]:
|
|
@@ -1136,6 +1180,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1136
1180
|
require_parameter_descriptions,
|
|
1137
1181
|
schema_generator,
|
|
1138
1182
|
strict,
|
|
1183
|
+
requires_approval,
|
|
1139
1184
|
)
|
|
1140
1185
|
return func_
|
|
1141
1186
|
|
|
@@ -1279,7 +1324,9 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1279
1324
|
toolsets: list[AbstractToolset[AgentDepsT]] = []
|
|
1280
1325
|
|
|
1281
1326
|
if some_tools := self._override_tools.get():
|
|
1282
|
-
function_toolset = _AgentFunctionToolset(
|
|
1327
|
+
function_toolset = _AgentFunctionToolset(
|
|
1328
|
+
some_tools.value, max_retries=self._max_tool_retries, output_schema=self._output_schema
|
|
1329
|
+
)
|
|
1283
1330
|
else:
|
|
1284
1331
|
function_toolset = self._function_toolset
|
|
1285
1332
|
toolsets.append(function_toolset)
|
|
@@ -1376,6 +1423,19 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1376
1423
|
|
|
1377
1424
|
@dataclasses.dataclass(init=False)
|
|
1378
1425
|
class _AgentFunctionToolset(FunctionToolset[AgentDepsT]):
|
|
1426
|
+
output_schema: _output.BaseOutputSchema[Any]
|
|
1427
|
+
|
|
1428
|
+
def __init__(
|
|
1429
|
+
self,
|
|
1430
|
+
tools: Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]] = [],
|
|
1431
|
+
*,
|
|
1432
|
+
max_retries: int = 1,
|
|
1433
|
+
id: str | None = None,
|
|
1434
|
+
output_schema: _output.BaseOutputSchema[Any],
|
|
1435
|
+
):
|
|
1436
|
+
self.output_schema = output_schema
|
|
1437
|
+
super().__init__(tools, max_retries=max_retries, id=id)
|
|
1438
|
+
|
|
1379
1439
|
@property
|
|
1380
1440
|
def id(self) -> str:
|
|
1381
1441
|
return '<agent>'
|
|
@@ -1383,3 +1443,10 @@ class _AgentFunctionToolset(FunctionToolset[AgentDepsT]):
|
|
|
1383
1443
|
@property
|
|
1384
1444
|
def label(self) -> str:
|
|
1385
1445
|
return 'the agent'
|
|
1446
|
+
|
|
1447
|
+
def add_tool(self, tool: Tool[AgentDepsT]) -> None:
|
|
1448
|
+
if tool.requires_approval and not self.output_schema.allows_deferred_tools:
|
|
1449
|
+
raise exceptions.UserError(
|
|
1450
|
+
'To use tools that require approval, add `DeferredToolRequests` to the list of output types for this agent.'
|
|
1451
|
+
)
|
|
1452
|
+
super().add_tool(tool)
|
pydantic_ai/agent/abstract.py
CHANGED
|
@@ -2,12 +2,12 @@ from __future__ import annotations as _annotations
|
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
|
-
from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterator, Mapping, Sequence
|
|
5
|
+
from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Callable, Iterator, Mapping, Sequence
|
|
6
6
|
from contextlib import AbstractAsyncContextManager, asynccontextmanager, contextmanager
|
|
7
7
|
from types import FrameType
|
|
8
|
-
from typing import TYPE_CHECKING, Any,
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeAlias, cast, overload
|
|
9
9
|
|
|
10
|
-
from typing_extensions import Self,
|
|
10
|
+
from typing_extensions import Self, TypeIs, TypeVar
|
|
11
11
|
|
|
12
12
|
from pydantic_graph import End
|
|
13
13
|
from pydantic_graph._utils import get_event_loop
|
|
@@ -27,6 +27,7 @@ from ..run import AgentRun, AgentRunResult
|
|
|
27
27
|
from ..settings import ModelSettings
|
|
28
28
|
from ..tools import (
|
|
29
29
|
AgentDepsT,
|
|
30
|
+
DeferredToolResults,
|
|
30
31
|
RunContext,
|
|
31
32
|
Tool,
|
|
32
33
|
ToolFuncEither,
|
|
@@ -116,6 +117,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
116
117
|
*,
|
|
117
118
|
output_type: None = None,
|
|
118
119
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
120
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
119
121
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
120
122
|
deps: AgentDepsT = None,
|
|
121
123
|
model_settings: ModelSettings | None = None,
|
|
@@ -133,6 +135,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
133
135
|
*,
|
|
134
136
|
output_type: OutputSpec[RunOutputDataT],
|
|
135
137
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
138
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
136
139
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
137
140
|
deps: AgentDepsT = None,
|
|
138
141
|
model_settings: ModelSettings | None = None,
|
|
@@ -149,6 +152,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
149
152
|
*,
|
|
150
153
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
151
154
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
155
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
152
156
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
153
157
|
deps: AgentDepsT = None,
|
|
154
158
|
model_settings: ModelSettings | None = None,
|
|
@@ -180,6 +184,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
180
184
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
181
185
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
182
186
|
message_history: History of the conversation so far.
|
|
187
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
183
188
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
184
189
|
deps: Optional dependencies to use for this run.
|
|
185
190
|
model_settings: Optional settings to use for this model's request.
|
|
@@ -201,6 +206,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
201
206
|
user_prompt=user_prompt,
|
|
202
207
|
output_type=output_type,
|
|
203
208
|
message_history=message_history,
|
|
209
|
+
deferred_tool_results=deferred_tool_results,
|
|
204
210
|
model=model,
|
|
205
211
|
deps=deps,
|
|
206
212
|
model_settings=model_settings,
|
|
@@ -225,6 +231,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
225
231
|
*,
|
|
226
232
|
output_type: None = None,
|
|
227
233
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
234
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
228
235
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
229
236
|
deps: AgentDepsT = None,
|
|
230
237
|
model_settings: ModelSettings | None = None,
|
|
@@ -242,6 +249,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
242
249
|
*,
|
|
243
250
|
output_type: OutputSpec[RunOutputDataT],
|
|
244
251
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
252
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
245
253
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
246
254
|
deps: AgentDepsT = None,
|
|
247
255
|
model_settings: ModelSettings | None = None,
|
|
@@ -258,6 +266,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
258
266
|
*,
|
|
259
267
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
260
268
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
269
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
261
270
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
262
271
|
deps: AgentDepsT = None,
|
|
263
272
|
model_settings: ModelSettings | None = None,
|
|
@@ -288,6 +297,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
288
297
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
289
298
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
290
299
|
message_history: History of the conversation so far.
|
|
300
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
291
301
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
292
302
|
deps: Optional dependencies to use for this run.
|
|
293
303
|
model_settings: Optional settings to use for this model's request.
|
|
@@ -308,6 +318,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
308
318
|
user_prompt,
|
|
309
319
|
output_type=output_type,
|
|
310
320
|
message_history=message_history,
|
|
321
|
+
deferred_tool_results=deferred_tool_results,
|
|
311
322
|
model=model,
|
|
312
323
|
deps=deps,
|
|
313
324
|
model_settings=model_settings,
|
|
@@ -326,6 +337,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
326
337
|
*,
|
|
327
338
|
output_type: None = None,
|
|
328
339
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
340
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
329
341
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
330
342
|
deps: AgentDepsT = None,
|
|
331
343
|
model_settings: ModelSettings | None = None,
|
|
@@ -343,6 +355,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
343
355
|
*,
|
|
344
356
|
output_type: OutputSpec[RunOutputDataT],
|
|
345
357
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
358
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
346
359
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
347
360
|
deps: AgentDepsT = None,
|
|
348
361
|
model_settings: ModelSettings | None = None,
|
|
@@ -360,6 +373,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
360
373
|
*,
|
|
361
374
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
362
375
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
376
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
363
377
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
364
378
|
deps: AgentDepsT = None,
|
|
365
379
|
model_settings: ModelSettings | None = None,
|
|
@@ -398,6 +412,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
398
412
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
399
413
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
400
414
|
message_history: History of the conversation so far.
|
|
415
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
401
416
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
402
417
|
deps: Optional dependencies to use for this run.
|
|
403
418
|
model_settings: Optional settings to use for this model's request.
|
|
@@ -424,6 +439,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
424
439
|
user_prompt,
|
|
425
440
|
output_type=output_type,
|
|
426
441
|
message_history=message_history,
|
|
442
|
+
deferred_tool_results=deferred_tool_results,
|
|
427
443
|
model=model,
|
|
428
444
|
deps=deps,
|
|
429
445
|
model_settings=model_settings,
|
|
@@ -436,8 +452,8 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
436
452
|
assert isinstance(first_node, _agent_graph.UserPromptNode) # the first node should be a user prompt node
|
|
437
453
|
node = first_node
|
|
438
454
|
while True:
|
|
455
|
+
graph_ctx = agent_run.ctx
|
|
439
456
|
if self.is_model_request_node(node):
|
|
440
|
-
graph_ctx = agent_run.ctx
|
|
441
457
|
async with node.stream(graph_ctx) as stream:
|
|
442
458
|
final_result_event = None
|
|
443
459
|
|
|
@@ -505,6 +521,17 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
505
521
|
await event_stream_handler(_agent_graph.build_run_context(agent_run.ctx), stream)
|
|
506
522
|
|
|
507
523
|
next_node = await agent_run.next(node)
|
|
524
|
+
if isinstance(next_node, End) and agent_run.result is not None:
|
|
525
|
+
# A final output could have been produced by the CallToolsNode rather than the ModelRequestNode,
|
|
526
|
+
# if a tool function raised CallDeferred or ApprovalRequired.
|
|
527
|
+
# In this case there's no response to stream, but we still let the user access the output etc as normal.
|
|
528
|
+
yield StreamedRunResult(
|
|
529
|
+
graph_ctx.state.message_history,
|
|
530
|
+
graph_ctx.deps.new_message_index,
|
|
531
|
+
run_result=agent_run.result,
|
|
532
|
+
)
|
|
533
|
+
yielded = True
|
|
534
|
+
break
|
|
508
535
|
if not isinstance(next_node, _agent_graph.AgentNode):
|
|
509
536
|
raise exceptions.AgentRunError( # pragma: no cover
|
|
510
537
|
'Should have produced a StreamedRunResult before getting here'
|
|
@@ -521,6 +548,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
521
548
|
*,
|
|
522
549
|
output_type: None = None,
|
|
523
550
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
551
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
524
552
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
525
553
|
deps: AgentDepsT = None,
|
|
526
554
|
model_settings: ModelSettings | None = None,
|
|
@@ -537,6 +565,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
537
565
|
*,
|
|
538
566
|
output_type: OutputSpec[RunOutputDataT],
|
|
539
567
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
568
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
540
569
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
541
570
|
deps: AgentDepsT = None,
|
|
542
571
|
model_settings: ModelSettings | None = None,
|
|
@@ -554,6 +583,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
554
583
|
*,
|
|
555
584
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
556
585
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
586
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
557
587
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
558
588
|
deps: AgentDepsT = None,
|
|
559
589
|
model_settings: ModelSettings | None = None,
|
|
@@ -626,6 +656,7 @@ class AbstractAgent(Generic[AgentDepsT, OutputDataT], ABC):
|
|
|
626
656
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
627
657
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
628
658
|
message_history: History of the conversation so far.
|
|
659
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
629
660
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
630
661
|
deps: Optional dependencies to use for this run.
|
|
631
662
|
model_settings: Optional settings to use for this model's request.
|
pydantic_ai/agent/wrapper.py
CHANGED
|
@@ -15,6 +15,7 @@ from ..run import AgentRun
|
|
|
15
15
|
from ..settings import ModelSettings
|
|
16
16
|
from ..tools import (
|
|
17
17
|
AgentDepsT,
|
|
18
|
+
DeferredToolResults,
|
|
18
19
|
Tool,
|
|
19
20
|
ToolFuncEither,
|
|
20
21
|
)
|
|
@@ -72,6 +73,7 @@ class WrapperAgent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
72
73
|
*,
|
|
73
74
|
output_type: None = None,
|
|
74
75
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
76
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
75
77
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
76
78
|
deps: AgentDepsT = None,
|
|
77
79
|
model_settings: ModelSettings | None = None,
|
|
@@ -88,6 +90,7 @@ class WrapperAgent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
88
90
|
*,
|
|
89
91
|
output_type: OutputSpec[RunOutputDataT],
|
|
90
92
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
93
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
91
94
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
92
95
|
deps: AgentDepsT = None,
|
|
93
96
|
model_settings: ModelSettings | None = None,
|
|
@@ -104,6 +107,7 @@ class WrapperAgent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
104
107
|
*,
|
|
105
108
|
output_type: OutputSpec[RunOutputDataT] | None = None,
|
|
106
109
|
message_history: list[_messages.ModelMessage] | None = None,
|
|
110
|
+
deferred_tool_results: DeferredToolResults | None = None,
|
|
107
111
|
model: models.Model | models.KnownModelName | str | None = None,
|
|
108
112
|
deps: AgentDepsT = None,
|
|
109
113
|
model_settings: ModelSettings | None = None,
|
|
@@ -176,6 +180,7 @@ class WrapperAgent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
176
180
|
output_type: Custom output type to use for this run, `output_type` may only be used if the agent has no
|
|
177
181
|
output validators since output validators would expect an argument that matches the agent's output type.
|
|
178
182
|
message_history: History of the conversation so far.
|
|
183
|
+
deferred_tool_results: Optional results for deferred tool calls in the message history.
|
|
179
184
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
180
185
|
deps: Optional dependencies to use for this run.
|
|
181
186
|
model_settings: Optional settings to use for this model's request.
|
|
@@ -191,6 +196,7 @@ class WrapperAgent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
191
196
|
user_prompt=user_prompt,
|
|
192
197
|
output_type=output_type,
|
|
193
198
|
message_history=message_history,
|
|
199
|
+
deferred_tool_results=deferred_tool_results,
|
|
194
200
|
model=model,
|
|
195
201
|
deps=deps,
|
|
196
202
|
model_settings=model_settings,
|
pydantic_ai/builtin_tools.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing_extensions import TypedDict
|
|
|
9
9
|
__all__ = ('AbstractBuiltinTool', 'WebSearchTool', 'WebSearchUserLocation', 'CodeExecutionTool', 'UrlContextTool')
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
@dataclass
|
|
12
|
+
@dataclass(kw_only=True)
|
|
13
13
|
class AbstractBuiltinTool(ABC):
|
|
14
14
|
"""A builtin tool that can be used by an agent.
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ class AbstractBuiltinTool(ABC):
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
@dataclass
|
|
22
|
+
@dataclass(kw_only=True)
|
|
23
23
|
class WebSearchTool(AbstractBuiltinTool):
|
|
24
24
|
"""A builtin tool that allows your agent to search the web for information.
|
|
25
25
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import functools
|
|
2
|
-
from dataclasses import dataclass
|
|
2
|
+
from dataclasses import KW_ONLY, dataclass
|
|
3
3
|
|
|
4
4
|
import anyio
|
|
5
5
|
import anyio.to_thread
|
|
@@ -43,7 +43,9 @@ class DuckDuckGoSearchTool:
|
|
|
43
43
|
client: DDGS
|
|
44
44
|
"""The DuckDuckGo search client."""
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
_: KW_ONLY
|
|
47
|
+
|
|
48
|
+
max_results: int | None
|
|
47
49
|
"""The maximum number of results. If None, returns results only from the first response."""
|
|
48
50
|
|
|
49
51
|
async def __call__(self, query: str) -> list[DuckDuckGoResult]:
|