pydantic-ai-slim 0.8.1__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 +70 -9
- 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 +4 -2
- 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 +1 -1
- 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 +73 -25
- pydantic_ai/models/__init__.py +5 -4
- pydantic_ai/models/anthropic.py +5 -5
- pydantic_ai/models/bedrock.py +58 -56
- 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 +9 -12
- pydantic_ai/models/google.py +3 -3
- pydantic_ai/models/groq.py +4 -4
- pydantic_ai/models/huggingface.py +4 -4
- pydantic_ai/models/instrumented.py +30 -16
- pydantic_ai/models/mcp_sampling.py +3 -1
- pydantic_ai/models/mistral.py +6 -6
- pydantic_ai/models/openai.py +18 -27
- 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 +144 -41
- 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.1.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/METADATA +5 -6
- pydantic_ai_slim-1.0.0b1.dist-info/RECORD +120 -0
- pydantic_ai_slim-0.8.1.dist-info/RECORD +0 -119
- {pydantic_ai_slim-0.8.1.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.8.1.dist-info → pydantic_ai_slim-1.0.0b1.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.8.1.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,
|
|
@@ -976,6 +1005,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
976
1005
|
require_parameter_descriptions: bool = False,
|
|
977
1006
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
978
1007
|
strict: bool | None = None,
|
|
1008
|
+
requires_approval: bool = False,
|
|
979
1009
|
) -> Callable[[ToolFuncContext[AgentDepsT, ToolParams]], ToolFuncContext[AgentDepsT, ToolParams]]: ...
|
|
980
1010
|
|
|
981
1011
|
def tool(
|
|
@@ -990,6 +1020,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
990
1020
|
require_parameter_descriptions: bool = False,
|
|
991
1021
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
992
1022
|
strict: bool | None = None,
|
|
1023
|
+
requires_approval: bool = False,
|
|
993
1024
|
) -> Any:
|
|
994
1025
|
"""Decorator to register a tool function which takes [`RunContext`][pydantic_ai.tools.RunContext] as its first argument.
|
|
995
1026
|
|
|
@@ -1034,6 +1065,8 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1034
1065
|
schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
|
|
1035
1066
|
strict: Whether to enforce JSON schema compliance (only affects OpenAI).
|
|
1036
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.
|
|
1037
1070
|
"""
|
|
1038
1071
|
|
|
1039
1072
|
def tool_decorator(
|
|
@@ -1050,6 +1083,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1050
1083
|
require_parameter_descriptions,
|
|
1051
1084
|
schema_generator,
|
|
1052
1085
|
strict,
|
|
1086
|
+
requires_approval,
|
|
1053
1087
|
)
|
|
1054
1088
|
return func_
|
|
1055
1089
|
|
|
@@ -1070,6 +1104,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1070
1104
|
require_parameter_descriptions: bool = False,
|
|
1071
1105
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
1072
1106
|
strict: bool | None = None,
|
|
1107
|
+
requires_approval: bool = False,
|
|
1073
1108
|
) -> Callable[[ToolFuncPlain[ToolParams]], ToolFuncPlain[ToolParams]]: ...
|
|
1074
1109
|
|
|
1075
1110
|
def tool_plain(
|
|
@@ -1084,6 +1119,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1084
1119
|
require_parameter_descriptions: bool = False,
|
|
1085
1120
|
schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
|
|
1086
1121
|
strict: bool | None = None,
|
|
1122
|
+
requires_approval: bool = False,
|
|
1087
1123
|
) -> Any:
|
|
1088
1124
|
"""Decorator to register a tool function which DOES NOT take `RunContext` as an argument.
|
|
1089
1125
|
|
|
@@ -1128,6 +1164,8 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1128
1164
|
schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
|
|
1129
1165
|
strict: Whether to enforce JSON schema compliance (only affects OpenAI).
|
|
1130
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.
|
|
1131
1169
|
"""
|
|
1132
1170
|
|
|
1133
1171
|
def tool_decorator(func_: ToolFuncPlain[ToolParams]) -> ToolFuncPlain[ToolParams]:
|
|
@@ -1142,6 +1180,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1142
1180
|
require_parameter_descriptions,
|
|
1143
1181
|
schema_generator,
|
|
1144
1182
|
strict,
|
|
1183
|
+
requires_approval,
|
|
1145
1184
|
)
|
|
1146
1185
|
return func_
|
|
1147
1186
|
|
|
@@ -1285,7 +1324,9 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1285
1324
|
toolsets: list[AbstractToolset[AgentDepsT]] = []
|
|
1286
1325
|
|
|
1287
1326
|
if some_tools := self._override_tools.get():
|
|
1288
|
-
function_toolset = _AgentFunctionToolset(
|
|
1327
|
+
function_toolset = _AgentFunctionToolset(
|
|
1328
|
+
some_tools.value, max_retries=self._max_tool_retries, output_schema=self._output_schema
|
|
1329
|
+
)
|
|
1289
1330
|
else:
|
|
1290
1331
|
function_toolset = self._function_toolset
|
|
1291
1332
|
toolsets.append(function_toolset)
|
|
@@ -1382,6 +1423,19 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
1382
1423
|
|
|
1383
1424
|
@dataclasses.dataclass(init=False)
|
|
1384
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
|
+
|
|
1385
1439
|
@property
|
|
1386
1440
|
def id(self) -> str:
|
|
1387
1441
|
return '<agent>'
|
|
@@ -1389,3 +1443,10 @@ class _AgentFunctionToolset(FunctionToolset[AgentDepsT]):
|
|
|
1389
1443
|
@property
|
|
1390
1444
|
def label(self) -> str:
|
|
1391
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]:
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
-
from collections.abc import AsyncIterator, Sequence
|
|
4
|
+
from collections.abc import AsyncIterator, Callable, Sequence
|
|
5
5
|
from contextlib import AbstractAsyncContextManager
|
|
6
6
|
from dataclasses import replace
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
from pydantic.errors import PydanticUserError
|
|
10
10
|
from temporalio.client import ClientConfig, Plugin as ClientPlugin, WorkflowHistory
|
|
@@ -57,6 +57,8 @@ class PydanticAIPlugin(ClientPlugin, WorkerPlugin):
|
|
|
57
57
|
runner,
|
|
58
58
|
restrictions=runner.restrictions.with_passthrough_modules(
|
|
59
59
|
'pydantic_ai',
|
|
60
|
+
'pydantic',
|
|
61
|
+
'pydantic_core',
|
|
60
62
|
'logfire',
|
|
61
63
|
'rich',
|
|
62
64
|
'httpx',
|