pydantic-ai-slim 0.8.0__py3-none-any.whl → 1.0.0__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/_a2a.py +1 -1
- pydantic_ai/_agent_graph.py +323 -156
- 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 +7 -5
- pydantic_ai/_run_context.py +3 -1
- pydantic_ai/_system_prompt.py +2 -2
- pydantic_ai/_tool_manager.py +32 -28
- pydantic_ai/_utils.py +14 -26
- pydantic_ai/ag_ui.py +82 -51
- 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 +93 -11
- 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 +15 -27
- pydantic_ai/messages.py +156 -44
- pydantic_ai/models/__init__.py +20 -7
- pydantic_ai/models/anthropic.py +10 -17
- pydantic_ai/models/bedrock.py +55 -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 +13 -14
- pydantic_ai/models/google.py +19 -5
- pydantic_ai/models/groq.py +127 -39
- pydantic_ai/models/huggingface.py +5 -5
- pydantic_ai/models/instrumented.py +49 -21
- pydantic_ai/models/mcp_sampling.py +3 -1
- pydantic_ai/models/mistral.py +8 -8
- pydantic_ai/models/openai.py +37 -42
- 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/__init__.py +4 -0
- pydantic_ai/providers/anthropic.py +2 -3
- pydantic_ai/providers/bedrock.py +3 -2
- pydantic_ai/providers/google_vertex.py +2 -1
- pydantic_ai/providers/groq.py +21 -2
- pydantic_ai/providers/litellm.py +134 -0
- pydantic_ai/result.py +173 -52
- pydantic_ai/retries.py +52 -31
- pydantic_ai/run.py +12 -5
- pydantic_ai/tools.py +127 -23
- 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 +58 -21
- pydantic_ai/toolsets/wrapper.py +2 -1
- pydantic_ai/usage.py +44 -8
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/METADATA +8 -9
- pydantic_ai_slim-1.0.0.dist-info/RECORD +121 -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.0.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/licenses/LICENSE +0 -0
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,15 +1,24 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
-
from collections.abc import Sequence
|
|
4
|
+
from collections.abc import AsyncIterator, Callable, Sequence
|
|
5
|
+
from contextlib import AbstractAsyncContextManager
|
|
5
6
|
from dataclasses import replace
|
|
6
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
from pydantic.errors import PydanticUserError
|
|
9
|
-
from temporalio.client import ClientConfig, Plugin as ClientPlugin
|
|
10
|
+
from temporalio.client import ClientConfig, Plugin as ClientPlugin, WorkflowHistory
|
|
10
11
|
from temporalio.contrib.pydantic import PydanticPayloadConverter, pydantic_data_converter
|
|
11
|
-
from temporalio.converter import DefaultPayloadConverter
|
|
12
|
-
from temporalio.
|
|
12
|
+
from temporalio.converter import DataConverter, DefaultPayloadConverter
|
|
13
|
+
from temporalio.service import ConnectConfig, ServiceClient
|
|
14
|
+
from temporalio.worker import (
|
|
15
|
+
Plugin as WorkerPlugin,
|
|
16
|
+
Replayer,
|
|
17
|
+
ReplayerConfig,
|
|
18
|
+
Worker,
|
|
19
|
+
WorkerConfig,
|
|
20
|
+
WorkflowReplayResult,
|
|
21
|
+
)
|
|
13
22
|
from temporalio.worker.workflow_sandbox import SandboxedWorkflowRunner
|
|
14
23
|
|
|
15
24
|
from ...exceptions import UserError
|
|
@@ -31,17 +40,15 @@ __all__ = [
|
|
|
31
40
|
class PydanticAIPlugin(ClientPlugin, WorkerPlugin):
|
|
32
41
|
"""Temporal client and worker plugin for Pydantic AI."""
|
|
33
42
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
DefaultPayloadConverter,
|
|
37
|
-
PydanticPayloadConverter,
|
|
38
|
-
):
|
|
39
|
-
warnings.warn( # pragma: no cover
|
|
40
|
-
'A non-default Temporal data converter was used which has been replaced with the Pydantic data converter.'
|
|
41
|
-
)
|
|
43
|
+
def init_client_plugin(self, next: ClientPlugin) -> None:
|
|
44
|
+
self.next_client_plugin = next
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
def init_worker_plugin(self, next: WorkerPlugin) -> None:
|
|
47
|
+
self.next_worker_plugin = next
|
|
48
|
+
|
|
49
|
+
def configure_client(self, config: ClientConfig) -> ClientConfig:
|
|
50
|
+
config['data_converter'] = self._get_new_data_converter(config.get('data_converter'))
|
|
51
|
+
return self.next_client_plugin.configure_client(config)
|
|
45
52
|
|
|
46
53
|
def configure_worker(self, config: WorkerConfig) -> WorkerConfig:
|
|
47
54
|
runner = config.get('workflow_runner') # pyright: ignore[reportUnknownMemberType]
|
|
@@ -50,6 +57,8 @@ class PydanticAIPlugin(ClientPlugin, WorkerPlugin):
|
|
|
50
57
|
runner,
|
|
51
58
|
restrictions=runner.restrictions.with_passthrough_modules(
|
|
52
59
|
'pydantic_ai',
|
|
60
|
+
'pydantic',
|
|
61
|
+
'pydantic_core',
|
|
53
62
|
'logfire',
|
|
54
63
|
'rich',
|
|
55
64
|
'httpx',
|
|
@@ -67,7 +76,35 @@ class PydanticAIPlugin(ClientPlugin, WorkerPlugin):
|
|
|
67
76
|
PydanticUserError,
|
|
68
77
|
]
|
|
69
78
|
|
|
70
|
-
return
|
|
79
|
+
return self.next_worker_plugin.configure_worker(config)
|
|
80
|
+
|
|
81
|
+
async def connect_service_client(self, config: ConnectConfig) -> ServiceClient:
|
|
82
|
+
return await self.next_client_plugin.connect_service_client(config)
|
|
83
|
+
|
|
84
|
+
async def run_worker(self, worker: Worker) -> None:
|
|
85
|
+
await self.next_worker_plugin.run_worker(worker)
|
|
86
|
+
|
|
87
|
+
def configure_replayer(self, config: ReplayerConfig) -> ReplayerConfig: # pragma: no cover
|
|
88
|
+
config['data_converter'] = self._get_new_data_converter(config.get('data_converter')) # pyright: ignore[reportUnknownMemberType]
|
|
89
|
+
return self.next_worker_plugin.configure_replayer(config)
|
|
90
|
+
|
|
91
|
+
def run_replayer(
|
|
92
|
+
self,
|
|
93
|
+
replayer: Replayer,
|
|
94
|
+
histories: AsyncIterator[WorkflowHistory],
|
|
95
|
+
) -> AbstractAsyncContextManager[AsyncIterator[WorkflowReplayResult]]: # pragma: no cover
|
|
96
|
+
return self.next_worker_plugin.run_replayer(replayer, histories)
|
|
97
|
+
|
|
98
|
+
def _get_new_data_converter(self, converter: DataConverter | None) -> DataConverter:
|
|
99
|
+
if converter and converter.payload_converter_class not in (
|
|
100
|
+
DefaultPayloadConverter,
|
|
101
|
+
PydanticPayloadConverter,
|
|
102
|
+
):
|
|
103
|
+
warnings.warn( # pragma: no cover
|
|
104
|
+
'A non-default Temporal data converter was used which has been replaced with the Pydantic data converter.'
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return pydantic_data_converter
|
|
71
108
|
|
|
72
109
|
|
|
73
110
|
class AgentPlugin(WorkerPlugin):
|
|
@@ -76,8 +113,24 @@ class AgentPlugin(WorkerPlugin):
|
|
|
76
113
|
def __init__(self, agent: TemporalAgent[Any, Any]):
|
|
77
114
|
self.agent = agent
|
|
78
115
|
|
|
116
|
+
def init_worker_plugin(self, next: WorkerPlugin) -> None:
|
|
117
|
+
self.next_worker_plugin = next
|
|
118
|
+
|
|
79
119
|
def configure_worker(self, config: WorkerConfig) -> WorkerConfig:
|
|
80
120
|
activities: Sequence[Callable[..., Any]] = config.get('activities', []) # pyright: ignore[reportUnknownMemberType]
|
|
81
121
|
# Activities are checked for name conflicts by Temporal.
|
|
82
122
|
config['activities'] = [*activities, *self.agent.temporal_activities]
|
|
83
|
-
return
|
|
123
|
+
return self.next_worker_plugin.configure_worker(config)
|
|
124
|
+
|
|
125
|
+
async def run_worker(self, worker: Worker) -> None:
|
|
126
|
+
await self.next_worker_plugin.run_worker(worker)
|
|
127
|
+
|
|
128
|
+
def configure_replayer(self, config: ReplayerConfig) -> ReplayerConfig: # pragma: no cover
|
|
129
|
+
return self.next_worker_plugin.configure_replayer(config)
|
|
130
|
+
|
|
131
|
+
def run_replayer(
|
|
132
|
+
self,
|
|
133
|
+
replayer: Replayer,
|
|
134
|
+
histories: AsyncIterator[WorkflowHistory],
|
|
135
|
+
) -> AbstractAsyncContextManager[AsyncIterator[WorkflowReplayResult]]: # pragma: no cover
|
|
136
|
+
return self.next_worker_plugin.run_replayer(replayer, histories)
|