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.

Files changed (75) hide show
  1. pydantic_ai/__init__.py +28 -2
  2. pydantic_ai/_a2a.py +1 -1
  3. pydantic_ai/_agent_graph.py +323 -156
  4. pydantic_ai/_function_schema.py +5 -5
  5. pydantic_ai/_griffe.py +2 -1
  6. pydantic_ai/_otel_messages.py +2 -2
  7. pydantic_ai/_output.py +31 -35
  8. pydantic_ai/_parts_manager.py +7 -5
  9. pydantic_ai/_run_context.py +3 -1
  10. pydantic_ai/_system_prompt.py +2 -2
  11. pydantic_ai/_tool_manager.py +32 -28
  12. pydantic_ai/_utils.py +14 -26
  13. pydantic_ai/ag_ui.py +82 -51
  14. pydantic_ai/agent/__init__.py +84 -17
  15. pydantic_ai/agent/abstract.py +35 -4
  16. pydantic_ai/agent/wrapper.py +6 -0
  17. pydantic_ai/builtin_tools.py +2 -2
  18. pydantic_ai/common_tools/duckduckgo.py +4 -2
  19. pydantic_ai/durable_exec/temporal/__init__.py +70 -17
  20. pydantic_ai/durable_exec/temporal/_agent.py +93 -11
  21. pydantic_ai/durable_exec/temporal/_function_toolset.py +53 -6
  22. pydantic_ai/durable_exec/temporal/_logfire.py +6 -3
  23. pydantic_ai/durable_exec/temporal/_mcp_server.py +2 -1
  24. pydantic_ai/durable_exec/temporal/_model.py +2 -2
  25. pydantic_ai/durable_exec/temporal/_run_context.py +2 -1
  26. pydantic_ai/durable_exec/temporal/_toolset.py +2 -1
  27. pydantic_ai/exceptions.py +45 -2
  28. pydantic_ai/format_prompt.py +2 -2
  29. pydantic_ai/mcp.py +15 -27
  30. pydantic_ai/messages.py +156 -44
  31. pydantic_ai/models/__init__.py +20 -7
  32. pydantic_ai/models/anthropic.py +10 -17
  33. pydantic_ai/models/bedrock.py +55 -57
  34. pydantic_ai/models/cohere.py +3 -3
  35. pydantic_ai/models/fallback.py +2 -2
  36. pydantic_ai/models/function.py +25 -23
  37. pydantic_ai/models/gemini.py +13 -14
  38. pydantic_ai/models/google.py +19 -5
  39. pydantic_ai/models/groq.py +127 -39
  40. pydantic_ai/models/huggingface.py +5 -5
  41. pydantic_ai/models/instrumented.py +49 -21
  42. pydantic_ai/models/mcp_sampling.py +3 -1
  43. pydantic_ai/models/mistral.py +8 -8
  44. pydantic_ai/models/openai.py +37 -42
  45. pydantic_ai/models/test.py +24 -4
  46. pydantic_ai/output.py +27 -32
  47. pydantic_ai/profiles/__init__.py +3 -3
  48. pydantic_ai/profiles/groq.py +1 -1
  49. pydantic_ai/profiles/openai.py +25 -4
  50. pydantic_ai/providers/__init__.py +4 -0
  51. pydantic_ai/providers/anthropic.py +2 -3
  52. pydantic_ai/providers/bedrock.py +3 -2
  53. pydantic_ai/providers/google_vertex.py +2 -1
  54. pydantic_ai/providers/groq.py +21 -2
  55. pydantic_ai/providers/litellm.py +134 -0
  56. pydantic_ai/result.py +173 -52
  57. pydantic_ai/retries.py +52 -31
  58. pydantic_ai/run.py +12 -5
  59. pydantic_ai/tools.py +127 -23
  60. pydantic_ai/toolsets/__init__.py +4 -1
  61. pydantic_ai/toolsets/_dynamic.py +4 -4
  62. pydantic_ai/toolsets/abstract.py +18 -2
  63. pydantic_ai/toolsets/approval_required.py +32 -0
  64. pydantic_ai/toolsets/combined.py +7 -12
  65. pydantic_ai/toolsets/{deferred.py → external.py} +11 -5
  66. pydantic_ai/toolsets/filtered.py +1 -1
  67. pydantic_ai/toolsets/function.py +58 -21
  68. pydantic_ai/toolsets/wrapper.py +2 -1
  69. pydantic_ai/usage.py +44 -8
  70. {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/METADATA +8 -9
  71. pydantic_ai_slim-1.0.0.dist-info/RECORD +121 -0
  72. pydantic_ai_slim-0.8.0.dist-info/RECORD +0 -119
  73. {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/WHEEL +0 -0
  74. {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/entry_points.txt +0 -0
  75. {pydantic_ai_slim-0.8.0.dist-info → pydantic_ai_slim-1.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -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, Callable, Generic, cast, overload
8
+ from typing import TYPE_CHECKING, Any, Generic, TypeAlias, cast, overload
9
9
 
10
- from typing_extensions import Self, TypeAlias, TypeIs, TypeVar
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.
@@ -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,
@@ -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
- max_results: int | None = None
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, Callable
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.worker import Plugin as WorkerPlugin, WorkerConfig
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 configure_client(self, config: ClientConfig) -> ClientConfig:
35
- if (data_converter := config.get('data_converter')) and data_converter.payload_converter_class not in (
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
- config['data_converter'] = pydantic_data_converter
44
- return super().configure_client(config)
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 super().configure_worker(config)
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 super().configure_worker(config)
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)