pydantic-ai-slim 0.4.3__py3-none-any.whl → 0.4.4__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 (45) hide show
  1. pydantic_ai/_agent_graph.py +220 -319
  2. pydantic_ai/_cli.py +9 -7
  3. pydantic_ai/_output.py +295 -331
  4. pydantic_ai/_parts_manager.py +2 -2
  5. pydantic_ai/_run_context.py +8 -14
  6. pydantic_ai/_tool_manager.py +190 -0
  7. pydantic_ai/_utils.py +18 -1
  8. pydantic_ai/ag_ui.py +675 -0
  9. pydantic_ai/agent.py +369 -156
  10. pydantic_ai/exceptions.py +12 -0
  11. pydantic_ai/ext/aci.py +12 -3
  12. pydantic_ai/ext/langchain.py +9 -1
  13. pydantic_ai/mcp.py +147 -84
  14. pydantic_ai/messages.py +13 -5
  15. pydantic_ai/models/__init__.py +30 -18
  16. pydantic_ai/models/anthropic.py +1 -1
  17. pydantic_ai/models/function.py +50 -24
  18. pydantic_ai/models/gemini.py +1 -9
  19. pydantic_ai/models/google.py +2 -11
  20. pydantic_ai/models/groq.py +1 -0
  21. pydantic_ai/models/mistral.py +1 -1
  22. pydantic_ai/models/openai.py +3 -3
  23. pydantic_ai/output.py +21 -7
  24. pydantic_ai/profiles/google.py +1 -1
  25. pydantic_ai/profiles/moonshotai.py +8 -0
  26. pydantic_ai/providers/grok.py +13 -1
  27. pydantic_ai/providers/groq.py +2 -0
  28. pydantic_ai/result.py +58 -45
  29. pydantic_ai/tools.py +26 -119
  30. pydantic_ai/toolsets/__init__.py +22 -0
  31. pydantic_ai/toolsets/abstract.py +155 -0
  32. pydantic_ai/toolsets/combined.py +88 -0
  33. pydantic_ai/toolsets/deferred.py +38 -0
  34. pydantic_ai/toolsets/filtered.py +24 -0
  35. pydantic_ai/toolsets/function.py +238 -0
  36. pydantic_ai/toolsets/prefixed.py +37 -0
  37. pydantic_ai/toolsets/prepared.py +36 -0
  38. pydantic_ai/toolsets/renamed.py +42 -0
  39. pydantic_ai/toolsets/wrapper.py +37 -0
  40. pydantic_ai/usage.py +14 -8
  41. {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.4.dist-info}/METADATA +10 -7
  42. {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.4.dist-info}/RECORD +45 -32
  43. {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.4.dist-info}/WHEEL +0 -0
  44. {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.4.dist-info}/entry_points.txt +0 -0
  45. {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,238 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Awaitable, Sequence
4
+ from dataclasses import dataclass, field, replace
5
+ from typing import Any, Callable, overload
6
+
7
+ from pydantic.json_schema import GenerateJsonSchema
8
+
9
+ from .._run_context import AgentDepsT, RunContext
10
+ from ..exceptions import UserError
11
+ from ..tools import (
12
+ DocstringFormat,
13
+ GenerateToolJsonSchema,
14
+ Tool,
15
+ ToolFuncEither,
16
+ ToolParams,
17
+ ToolPrepareFunc,
18
+ )
19
+ from .abstract import AbstractToolset, ToolsetTool
20
+
21
+
22
+ @dataclass
23
+ class _FunctionToolsetTool(ToolsetTool[AgentDepsT]):
24
+ """A tool definition for a function toolset tool that keeps track of the function to call."""
25
+
26
+ call_func: Callable[[dict[str, Any], RunContext[AgentDepsT]], Awaitable[Any]]
27
+
28
+
29
+ @dataclass(init=False)
30
+ class FunctionToolset(AbstractToolset[AgentDepsT]):
31
+ """A toolset that lets Python functions be used as tools.
32
+
33
+ See [toolset docs](../toolsets.md#function-toolset) for more information.
34
+ """
35
+
36
+ max_retries: int = field(default=1)
37
+ tools: dict[str, Tool[Any]] = field(default_factory=dict)
38
+
39
+ def __init__(self, tools: Sequence[Tool[AgentDepsT] | ToolFuncEither[AgentDepsT, ...]] = [], max_retries: int = 1):
40
+ """Build a new function toolset.
41
+
42
+ Args:
43
+ tools: The tools to add to the toolset.
44
+ max_retries: The maximum number of retries for each tool during a run.
45
+ """
46
+ self.max_retries = max_retries
47
+ self.tools = {}
48
+ for tool in tools:
49
+ if isinstance(tool, Tool):
50
+ self.add_tool(tool)
51
+ else:
52
+ self.add_function(tool)
53
+
54
+ @overload
55
+ def tool(self, func: ToolFuncEither[AgentDepsT, ToolParams], /) -> ToolFuncEither[AgentDepsT, ToolParams]: ...
56
+
57
+ @overload
58
+ def tool(
59
+ self,
60
+ /,
61
+ *,
62
+ name: str | None = None,
63
+ retries: int | None = None,
64
+ prepare: ToolPrepareFunc[AgentDepsT] | None = None,
65
+ docstring_format: DocstringFormat = 'auto',
66
+ require_parameter_descriptions: bool = False,
67
+ schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
68
+ strict: bool | None = None,
69
+ ) -> Callable[[ToolFuncEither[AgentDepsT, ToolParams]], ToolFuncEither[AgentDepsT, ToolParams]]: ...
70
+
71
+ def tool(
72
+ self,
73
+ func: ToolFuncEither[AgentDepsT, ToolParams] | None = None,
74
+ /,
75
+ *,
76
+ name: str | None = None,
77
+ retries: int | None = None,
78
+ prepare: ToolPrepareFunc[AgentDepsT] | None = None,
79
+ docstring_format: DocstringFormat = 'auto',
80
+ require_parameter_descriptions: bool = False,
81
+ schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
82
+ strict: bool | None = None,
83
+ ) -> Any:
84
+ """Decorator to register a tool function which takes [`RunContext`][pydantic_ai.tools.RunContext] as its first argument.
85
+
86
+ Can decorate a sync or async functions.
87
+
88
+ The docstring is inspected to extract both the tool description and description of each parameter,
89
+ [learn more](../tools.md#function-tools-and-schema).
90
+
91
+ We can't add overloads for every possible signature of tool, since the return type is a recursive union
92
+ so the signature of functions decorated with `@toolset.tool` is obscured.
93
+
94
+ Example:
95
+ ```python
96
+ from pydantic_ai import Agent, RunContext
97
+ from pydantic_ai.toolsets.function import FunctionToolset
98
+
99
+ toolset = FunctionToolset()
100
+
101
+ @toolset.tool
102
+ def foobar(ctx: RunContext[int], x: int) -> int:
103
+ return ctx.deps + x
104
+
105
+ @toolset.tool(retries=2)
106
+ async def spam(ctx: RunContext[str], y: float) -> float:
107
+ return ctx.deps + y
108
+
109
+ agent = Agent('test', toolsets=[toolset], deps_type=int)
110
+ result = agent.run_sync('foobar', deps=1)
111
+ print(result.output)
112
+ #> {"foobar":1,"spam":1.0}
113
+ ```
114
+
115
+ Args:
116
+ func: The tool function to register.
117
+ name: The name of the tool, defaults to the function name.
118
+ retries: The number of retries to allow for this tool, defaults to the agent's default retries,
119
+ which defaults to 1.
120
+ prepare: custom method to prepare the tool definition for each step, return `None` to omit this
121
+ tool from a given step. This is useful if you want to customise a tool at call time,
122
+ or omit it completely from a step. See [`ToolPrepareFunc`][pydantic_ai.tools.ToolPrepareFunc].
123
+ docstring_format: The format of the docstring, see [`DocstringFormat`][pydantic_ai.tools.DocstringFormat].
124
+ Defaults to `'auto'`, such that the format is inferred from the structure of the docstring.
125
+ require_parameter_descriptions: If True, raise an error if a parameter description is missing. Defaults to False.
126
+ schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
127
+ strict: Whether to enforce JSON schema compliance (only affects OpenAI).
128
+ See [`ToolDefinition`][pydantic_ai.tools.ToolDefinition] for more info.
129
+ """
130
+
131
+ def tool_decorator(
132
+ func_: ToolFuncEither[AgentDepsT, ToolParams],
133
+ ) -> ToolFuncEither[AgentDepsT, ToolParams]:
134
+ # noinspection PyTypeChecker
135
+ self.add_function(
136
+ func_,
137
+ None,
138
+ name,
139
+ retries,
140
+ prepare,
141
+ docstring_format,
142
+ require_parameter_descriptions,
143
+ schema_generator,
144
+ strict,
145
+ )
146
+ return func_
147
+
148
+ return tool_decorator if func is None else tool_decorator(func)
149
+
150
+ def add_function(
151
+ self,
152
+ func: ToolFuncEither[AgentDepsT, ToolParams],
153
+ takes_ctx: bool | None = None,
154
+ name: str | None = None,
155
+ retries: int | None = None,
156
+ prepare: ToolPrepareFunc[AgentDepsT] | None = None,
157
+ docstring_format: DocstringFormat = 'auto',
158
+ require_parameter_descriptions: bool = False,
159
+ schema_generator: type[GenerateJsonSchema] = GenerateToolJsonSchema,
160
+ strict: bool | None = None,
161
+ ) -> None:
162
+ """Add a function as a tool to the toolset.
163
+
164
+ Can take a sync or async function.
165
+
166
+ The docstring is inspected to extract both the tool description and description of each parameter,
167
+ [learn more](../tools.md#function-tools-and-schema).
168
+
169
+ Args:
170
+ func: The tool function to register.
171
+ takes_ctx: Whether the function takes a [`RunContext`][pydantic_ai.tools.RunContext] as its first argument. If `None`, this is inferred from the function signature.
172
+ name: The name of the tool, defaults to the function name.
173
+ retries: The number of retries to allow for this tool, defaults to the agent's default retries,
174
+ which defaults to 1.
175
+ prepare: custom method to prepare the tool definition for each step, return `None` to omit this
176
+ tool from a given step. This is useful if you want to customise a tool at call time,
177
+ or omit it completely from a step. See [`ToolPrepareFunc`][pydantic_ai.tools.ToolPrepareFunc].
178
+ docstring_format: The format of the docstring, see [`DocstringFormat`][pydantic_ai.tools.DocstringFormat].
179
+ Defaults to `'auto'`, such that the format is inferred from the structure of the docstring.
180
+ require_parameter_descriptions: If True, raise an error if a parameter description is missing. Defaults to False.
181
+ schema_generator: The JSON schema generator class to use for this tool. Defaults to `GenerateToolJsonSchema`.
182
+ strict: Whether to enforce JSON schema compliance (only affects OpenAI).
183
+ See [`ToolDefinition`][pydantic_ai.tools.ToolDefinition] for more info.
184
+ """
185
+ tool = Tool[AgentDepsT](
186
+ func,
187
+ takes_ctx=takes_ctx,
188
+ name=name,
189
+ max_retries=retries,
190
+ prepare=prepare,
191
+ docstring_format=docstring_format,
192
+ require_parameter_descriptions=require_parameter_descriptions,
193
+ schema_generator=schema_generator,
194
+ strict=strict,
195
+ )
196
+ self.add_tool(tool)
197
+
198
+ def add_tool(self, tool: Tool[AgentDepsT]) -> None:
199
+ """Add a tool to the toolset.
200
+
201
+ Args:
202
+ tool: The tool to add.
203
+ """
204
+ if tool.name in self.tools:
205
+ raise UserError(f'Tool name conflicts with existing tool: {tool.name!r}')
206
+ if tool.max_retries is None:
207
+ tool.max_retries = self.max_retries
208
+ self.tools[tool.name] = tool
209
+
210
+ async def get_tools(self, ctx: RunContext[AgentDepsT]) -> dict[str, ToolsetTool[AgentDepsT]]:
211
+ tools: dict[str, ToolsetTool[AgentDepsT]] = {}
212
+ for original_name, tool in self.tools.items():
213
+ run_context = replace(ctx, tool_name=original_name, retry=ctx.retries.get(original_name, 0))
214
+ tool_def = await tool.prepare_tool_def(run_context)
215
+ if not tool_def:
216
+ continue
217
+
218
+ new_name = tool_def.name
219
+ if new_name in tools:
220
+ if new_name != original_name:
221
+ raise UserError(f'Renaming tool {original_name!r} to {new_name!r} conflicts with existing tool.')
222
+ else:
223
+ raise UserError(f'Tool name conflicts with previously renamed tool: {new_name!r}.')
224
+
225
+ tools[new_name] = _FunctionToolsetTool(
226
+ toolset=self,
227
+ tool_def=tool_def,
228
+ max_retries=tool.max_retries if tool.max_retries is not None else self.max_retries,
229
+ args_validator=tool.function_schema.validator,
230
+ call_func=tool.function_schema.call,
231
+ )
232
+ return tools
233
+
234
+ async def call_tool(
235
+ self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
236
+ ) -> Any:
237
+ assert isinstance(tool, _FunctionToolsetTool)
238
+ return await tool.call_func(tool_args, ctx)
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, replace
4
+ from typing import Any
5
+
6
+ from .._run_context import AgentDepsT, RunContext
7
+ from .abstract import ToolsetTool
8
+ from .wrapper import WrapperToolset
9
+
10
+
11
+ @dataclass
12
+ class PrefixedToolset(WrapperToolset[AgentDepsT]):
13
+ """A toolset that prefixes the names of the tools it contains.
14
+
15
+ See [toolset docs](../toolsets.md#prefixing-tool-names) for more information.
16
+ """
17
+
18
+ prefix: str
19
+
20
+ async def get_tools(self, ctx: RunContext[AgentDepsT]) -> dict[str, ToolsetTool[AgentDepsT]]:
21
+ return {
22
+ new_name: replace(
23
+ tool,
24
+ toolset=self,
25
+ tool_def=replace(tool.tool_def, name=new_name),
26
+ )
27
+ for name, tool in (await super().get_tools(ctx)).items()
28
+ if (new_name := f'{self.prefix}_{name}')
29
+ }
30
+
31
+ async def call_tool(
32
+ self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
33
+ ) -> Any:
34
+ original_name = name.removeprefix(self.prefix + '_')
35
+ ctx = replace(ctx, tool_name=original_name)
36
+ tool = replace(tool, tool_def=replace(tool.tool_def, name=original_name))
37
+ return await super().call_tool(original_name, tool_args, ctx, tool)
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, replace
4
+
5
+ from .._run_context import AgentDepsT, RunContext
6
+ from ..exceptions import UserError
7
+ from ..tools import ToolsPrepareFunc
8
+ from .abstract import ToolsetTool
9
+ from .wrapper import WrapperToolset
10
+
11
+
12
+ @dataclass
13
+ class PreparedToolset(WrapperToolset[AgentDepsT]):
14
+ """A toolset that prepares the tools it contains using a prepare function that takes the agent context and the original tool definitions.
15
+
16
+ See [toolset docs](../toolsets.md#preparing-tool-definitions) for more information.
17
+ """
18
+
19
+ prepare_func: ToolsPrepareFunc[AgentDepsT]
20
+
21
+ async def get_tools(self, ctx: RunContext[AgentDepsT]) -> dict[str, ToolsetTool[AgentDepsT]]:
22
+ original_tools = await super().get_tools(ctx)
23
+ original_tool_defs = [tool.tool_def for tool in original_tools.values()]
24
+ prepared_tool_defs_by_name = {
25
+ tool_def.name: tool_def for tool_def in (await self.prepare_func(ctx, original_tool_defs) or [])
26
+ }
27
+
28
+ if len(prepared_tool_defs_by_name.keys() - original_tools.keys()) > 0:
29
+ raise UserError(
30
+ 'Prepare function cannot add or rename tools. Use `FunctionToolset.add_function()` or `RenamedToolset` instead.'
31
+ )
32
+
33
+ return {
34
+ name: replace(original_tools[name], tool_def=tool_def)
35
+ for name, tool_def in prepared_tool_defs_by_name.items()
36
+ }
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, replace
4
+ from typing import Any
5
+
6
+ from .._run_context import AgentDepsT, RunContext
7
+ from .abstract import ToolsetTool
8
+ from .wrapper import WrapperToolset
9
+
10
+
11
+ @dataclass
12
+ class RenamedToolset(WrapperToolset[AgentDepsT]):
13
+ """A toolset that renames the tools it contains using a dictionary mapping new names to original names.
14
+
15
+ See [toolset docs](../toolsets.md#renaming-tools) for more information.
16
+ """
17
+
18
+ name_map: dict[str, str]
19
+
20
+ async def get_tools(self, ctx: RunContext[AgentDepsT]) -> dict[str, ToolsetTool[AgentDepsT]]:
21
+ original_to_new_name_map = {v: k for k, v in self.name_map.items()}
22
+ original_tools = await super().get_tools(ctx)
23
+ tools: dict[str, ToolsetTool[AgentDepsT]] = {}
24
+ for original_name, tool in original_tools.items():
25
+ new_name = original_to_new_name_map.get(original_name, None)
26
+ if new_name:
27
+ tools[new_name] = replace(
28
+ tool,
29
+ toolset=self,
30
+ tool_def=replace(tool.tool_def, name=new_name),
31
+ )
32
+ else:
33
+ tools[original_name] = tool
34
+ return tools
35
+
36
+ async def call_tool(
37
+ self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
38
+ ) -> Any:
39
+ original_name = self.name_map.get(name, name)
40
+ ctx = replace(ctx, tool_name=original_name)
41
+ tool = replace(tool, tool_def=replace(tool.tool_def, name=original_name))
42
+ return await super().call_tool(original_name, tool_args, ctx, tool)
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, Callable
5
+
6
+ from typing_extensions import Self
7
+
8
+ from .._run_context import AgentDepsT, RunContext
9
+ from .abstract import AbstractToolset, ToolsetTool
10
+
11
+
12
+ @dataclass
13
+ class WrapperToolset(AbstractToolset[AgentDepsT]):
14
+ """A toolset that wraps another toolset and delegates to it.
15
+
16
+ See [toolset docs](../toolsets.md#wrapping-a-toolset) for more information.
17
+ """
18
+
19
+ wrapped: AbstractToolset[AgentDepsT]
20
+
21
+ async def __aenter__(self) -> Self:
22
+ await self.wrapped.__aenter__()
23
+ return self
24
+
25
+ async def __aexit__(self, *args: Any) -> bool | None:
26
+ return await self.wrapped.__aexit__(*args)
27
+
28
+ async def get_tools(self, ctx: RunContext[AgentDepsT]) -> dict[str, ToolsetTool[AgentDepsT]]:
29
+ return await self.wrapped.get_tools(ctx)
30
+
31
+ async def call_tool(
32
+ self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
33
+ ) -> Any:
34
+ return await self.wrapped.call_tool(name, tool_args, ctx, tool)
35
+
36
+ def apply(self, visitor: Callable[[AbstractToolset[AgentDepsT]], None]) -> None:
37
+ self.wrapped.apply(visitor)
pydantic_ai/usage.py CHANGED
@@ -13,7 +13,7 @@ __all__ = 'Usage', 'UsageLimits'
13
13
  class Usage:
14
14
  """LLM usage associated with a request or run.
15
15
 
16
- Responsibility for calculating usage is on the model; PydanticAI simply sums the usage information across requests.
16
+ Responsibility for calculating usage is on the model; Pydantic AI simply sums the usage information across requests.
17
17
 
18
18
  You'll need to look up the documentation of the model you're using to convert usage to monetary costs.
19
19
  """
@@ -57,13 +57,19 @@ class Usage:
57
57
 
58
58
  def opentelemetry_attributes(self) -> dict[str, int]:
59
59
  """Get the token limits as OpenTelemetry attributes."""
60
- result = {
61
- 'gen_ai.usage.input_tokens': self.request_tokens,
62
- 'gen_ai.usage.output_tokens': self.response_tokens,
63
- }
64
- for key, value in (self.details or {}).items():
65
- result[f'gen_ai.usage.details.{key}'] = value # pragma: no cover
66
- return {k: v for k, v in result.items() if v}
60
+ result: dict[str, int] = {}
61
+ if self.request_tokens:
62
+ result['gen_ai.usage.input_tokens'] = self.request_tokens
63
+ if self.response_tokens:
64
+ result['gen_ai.usage.output_tokens'] = self.response_tokens
65
+ details = self.details
66
+ if details:
67
+ prefix = 'gen_ai.usage.details.'
68
+ for key, value in details.items():
69
+ # Skipping check for value since spec implies all detail values are relevant
70
+ if value:
71
+ result[prefix + key] = value
72
+ return result
67
73
 
68
74
  def has_values(self) -> bool:
69
75
  """Whether any values are set and non-zero."""
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
5
- Author-email: Samuel Colvin <samuel@pydantic.dev>, Marcelo Trylesinski <marcelotryle@gmail.com>, David Montague <david@pydantic.dev>, Alex Hall <alex@pydantic.dev>
5
+ Author-email: Samuel Colvin <samuel@pydantic.dev>, Marcelo Trylesinski <marcelotryle@gmail.com>, David Montague <david@pydantic.dev>, Alex Hall <alex@pydantic.dev>, Douwe Maan <douwe@pydantic.dev>
6
6
  License-Expression: MIT
7
7
  License-File: LICENSE
8
8
  Classifier: Development Status :: 4 - Beta
@@ -30,11 +30,14 @@ Requires-Dist: exceptiongroup; python_version < '3.11'
30
30
  Requires-Dist: griffe>=1.3.2
31
31
  Requires-Dist: httpx>=0.27
32
32
  Requires-Dist: opentelemetry-api>=1.28.0
33
- Requires-Dist: pydantic-graph==0.4.3
33
+ Requires-Dist: pydantic-graph==0.4.4
34
34
  Requires-Dist: pydantic>=2.10
35
35
  Requires-Dist: typing-inspection>=0.4.0
36
36
  Provides-Extra: a2a
37
37
  Requires-Dist: fasta2a>=0.4.1; extra == 'a2a'
38
+ Provides-Extra: ag-ui
39
+ Requires-Dist: ag-ui-protocol>=0.1.8; extra == 'ag-ui'
40
+ Requires-Dist: starlette>=0.45.3; extra == 'ag-ui'
38
41
  Provides-Extra: anthropic
39
42
  Requires-Dist: anthropic>=0.52.0; extra == 'anthropic'
40
43
  Provides-Extra: bedrock
@@ -48,7 +51,7 @@ Requires-Dist: cohere>=5.13.11; (platform_system != 'Emscripten') and extra == '
48
51
  Provides-Extra: duckduckgo
49
52
  Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
50
53
  Provides-Extra: evals
51
- Requires-Dist: pydantic-evals==0.4.3; extra == 'evals'
54
+ Requires-Dist: pydantic-evals==0.4.4; extra == 'evals'
52
55
  Provides-Extra: google
53
56
  Requires-Dist: google-genai>=1.24.0; extra == 'google'
54
57
  Provides-Extra: groq
@@ -62,7 +65,7 @@ Requires-Dist: mcp>=1.9.4; (python_version >= '3.10') and extra == 'mcp'
62
65
  Provides-Extra: mistral
63
66
  Requires-Dist: mistralai>=1.2.5; extra == 'mistral'
64
67
  Provides-Extra: openai
65
- Requires-Dist: openai>=1.76.0; extra == 'openai'
68
+ Requires-Dist: openai>=1.92.0; extra == 'openai'
66
69
  Provides-Extra: tavily
67
70
  Requires-Dist: tavily-python>=0.5.0; extra == 'tavily'
68
71
  Provides-Extra: vertexai
@@ -70,7 +73,7 @@ Requires-Dist: google-auth>=2.36.0; extra == 'vertexai'
70
73
  Requires-Dist: requests>=2.32.2; extra == 'vertexai'
71
74
  Description-Content-Type: text/markdown
72
75
 
73
- # PydanticAI Slim
76
+ # Pydantic AI Slim
74
77
 
75
78
  [![CI](https://github.com/pydantic/pydantic-ai/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/pydantic/pydantic-ai/actions/workflows/ci.yml?query=branch%3Amain)
76
79
  [![Coverage](https://coverage-badge.samuelcolvin.workers.dev/pydantic/pydantic-ai.svg)](https://coverage-badge.samuelcolvin.workers.dev/redirect/pydantic/pydantic-ai)
@@ -78,6 +81,6 @@ Description-Content-Type: text/markdown
78
81
  [![versions](https://img.shields.io/pypi/pyversions/pydantic-ai-slim.svg)](https://github.com/pydantic/pydantic-ai)
79
82
  [![license](https://img.shields.io/github/license/pydantic/pydantic-ai.svg?v)](https://github.com/pydantic/pydantic-ai/blob/main/LICENSE)
80
83
 
81
- PydanticAI core logic with minimal required dependencies.
84
+ Pydantic AI core logic with minimal required dependencies.
82
85
 
83
86
  For more information on how to use this package see [ai.pydantic.dev/install](https://ai.pydantic.dev/install/).
@@ -1,50 +1,52 @@
1
1
  pydantic_ai/__init__.py,sha256=h6Rll8pEzUUUX6SckosummoAFbq7ctfBlI6WSyaXR4I,1300
2
2
  pydantic_ai/__main__.py,sha256=Q_zJU15DUA01YtlJ2mnaLCoId2YmgmreVEERGuQT-Y0,132
3
3
  pydantic_ai/_a2a.py,sha256=PFgqW6I3qh3deY4WFfubTUroig9-NaAWxbeMxYjdtfI,12067
4
- pydantic_ai/_agent_graph.py,sha256=2XGCD8Or0zIKkXJLX0jY3eLI38km4mp_jHTQ8yxFw2g,42367
5
- pydantic_ai/_cli.py,sha256=R-sE-9gYqPxV5-5utso4g-bzAKMiTCdo33XOVqE0ZEg,13206
4
+ pydantic_ai/_agent_graph.py,sha256=FrNq9kppV8kFVZf6t-MVGVOWUVBCXQfAinQjMh2gVWw,37192
5
+ pydantic_ai/_cli.py,sha256=YkiW2u9HGPd9fsgo9dpK1DZvtUPk4uXGQJcm75XgfhU,13250
6
6
  pydantic_ai/_function_schema.py,sha256=BZus5y51eqiGQKxQIcCiDoSPml3AtAb12-st_aujU2k,10813
7
7
  pydantic_ai/_griffe.py,sha256=Ugft16ZHw9CN_6-lW0Svn6jESK9zHXO_x4utkGBkbBI,5253
8
8
  pydantic_ai/_mcp.py,sha256=PuvwnlLjv7YYOa9AZJCrklevBug99zGMhwJCBGG7BHQ,5626
9
- pydantic_ai/_output.py,sha256=Z30MgZ7M3WMFwud6sJDIJ-N6Yil10Q8BrTHO5z5FBv0,37954
10
- pydantic_ai/_parts_manager.py,sha256=Lioi8b7Nfyax09yQu8jTkMzxd26dYDrdAqhYvjRSKqQ,16182
11
- pydantic_ai/_run_context.py,sha256=zNkSyiQSH-YweO39ii3iB2taouUOodo3sTjz2Lrj4Pc,1792
9
+ pydantic_ai/_output.py,sha256=bi-ef06b-yDMc_1PUvCWDWLr1Oyk1aRWTYHZpRL-zV0,36595
10
+ pydantic_ai/_parts_manager.py,sha256=CGm_fovTrFNQ3H8s9-edSBuG8Jzqrgw5TqRnPlzPyr4,16184
11
+ pydantic_ai/_run_context.py,sha256=pqb_HPXytE1Z9zZRRuBboRYes_tVTC75WGTpZgnb2Ko,1691
12
12
  pydantic_ai/_system_prompt.py,sha256=lUSq-gDZjlYTGtd6BUm54yEvTIvgdwBmJ8mLsNZZtYU,1142
13
13
  pydantic_ai/_thinking_part.py,sha256=mzx2RZSfiQxAKpljEflrcXRXmFKxtp6bKVyorY3UYZk,1554
14
- pydantic_ai/_utils.py,sha256=9QSHZhbrCbUK18ckchC55OkBkP-1o6xhAxUkEMo9DSQ,15741
15
- pydantic_ai/agent.py,sha256=eAWi7onlDdaXOj2DAriVtzf3cTUrAUrt-oGYx--UJiA,96481
14
+ pydantic_ai/_tool_manager.py,sha256=ptVj2oJm7Qm5MlDQHDNj8BPIEPY0HfkrzqeeD_ZuVbQ,8180
15
+ pydantic_ai/_utils.py,sha256=0Pte4mjir4YFZJTa6i-H6Cra9NbVwSKjOKegArzUggk,16283
16
+ pydantic_ai/ag_ui.py,sha256=b1Uqc0bGcFCn71hl04gcX_W80lQugueEm-0m--fde2s,25758
17
+ pydantic_ai/agent.py,sha256=2kKk22M7kDNUls0bRzwXqviAXjwVaDxVMcFwg8z7Wq8,107794
16
18
  pydantic_ai/direct.py,sha256=WRfgke3zm-eeR39LTuh9XI2TrdHXAqO81eDvFwih4Ko,14803
17
- pydantic_ai/exceptions.py,sha256=1ujJeB3jDDQ-pH5ydBYrgStvR35-GlEW0bYGTGEr4ME,3127
19
+ pydantic_ai/exceptions.py,sha256=o0l6fBrWI5UhosICVZ2yaT-JEJF05eqBlKlQCW8i9UM,3462
18
20
  pydantic_ai/format_as_xml.py,sha256=IINfh1evWDphGahqHNLBArB5dQ4NIqS3S-kru35ztGg,372
19
21
  pydantic_ai/format_prompt.py,sha256=qdKep95Sjlr7u1-qag4JwPbjoURbG0GbeU_l5ODTNw4,4466
20
- pydantic_ai/mcp.py,sha256=6RvxXIn6bUlL2XWpX69i8G3atU-HLLZBgKc93dYqeVo,21830
21
- pydantic_ai/messages.py,sha256=1G6cQs1tlBaCUhuv17RXyCkkiXzad6nYrjg-ZevNsjM,39421
22
- pydantic_ai/output.py,sha256=HU1dIiKyCaCvSxg8U6YMRvn1U50l0D9NMvGt_wqp_xI,11512
22
+ pydantic_ai/mcp.py,sha256=3YvQmTGpWC4stG9CthYCWnEE7XXIGuc2Xtfw4Yiya8c,23817
23
+ pydantic_ai/messages.py,sha256=ZLV6Evc0-HWiR7nt0C_6Oe9kFhmE0o4Hg19TZPUPTaU,40089
24
+ pydantic_ai/output.py,sha256=54Cwd1RruXlA5hucZ1h-SxFrzKHJuLvYvLtH9iyg2GI,11988
23
25
  pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- pydantic_ai/result.py,sha256=PQNWopb0Jb-VD7C-DtIECDX-xjqaFWi8Grhn2Tte66g,25873
26
+ pydantic_ai/result.py,sha256=fhAlW90E_qfsC8IZfKVf8eYCz26NCoDLcxOATKwvYqk,27092
25
27
  pydantic_ai/settings.py,sha256=yuUZ7-GkdPB-Gbx71kSdh8dSr6gwM9gEwk84qNxPO_I,3552
26
- pydantic_ai/tools.py,sha256=ZZ5DZMzSLMZkM9y_G3fx5YnVTki6daPYgRkfuNXAQ-M,17774
27
- pydantic_ai/usage.py,sha256=35YPmItlzfNOwP35Rhh0qBUOlg5On5rUE7xqHQWrpaU,5596
28
+ pydantic_ai/tools.py,sha256=PQm1yWbocdrhyLdMf_J8dJMTRJTWzyS2BEF24t4jgqw,14205
29
+ pydantic_ai/usage.py,sha256=ceC9HHflyM_rkLBJqtaWPc-M8bEoq5rZF4XwGblPQoU,5830
28
30
  pydantic_ai/common_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
31
  pydantic_ai/common_tools/duckduckgo.py,sha256=aQsm7zKuoRNgPM8ltbdyj8dPkREEkQenimsf_laF6kc,2245
30
32
  pydantic_ai/common_tools/tavily.py,sha256=Q1xxSF5HtXAaZ10Pp-OaDOHXwJf2mco9wScGEQXD7E4,2495
31
33
  pydantic_ai/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- pydantic_ai/ext/aci.py,sha256=eiuWamUh90kexWyuGw_Fw2kM-EAA6Pv-IfNhf5hQ8fs,2123
33
- pydantic_ai/ext/langchain.py,sha256=iSyACZiJDDvxr0BKYl9dLxe4BPezCBHxgz_2Vk3W-Ak,1973
34
- pydantic_ai/models/__init__.py,sha256=SdGY1rsTsQADjsxFbkK-8BSO_ALjTVFj5XazthwWi8w,30299
35
- pydantic_ai/models/anthropic.py,sha256=DqG1Y9q3rqXYKI2I-AEWTD1jUyoAjlxnuN0FgT5CRXc,23822
34
+ pydantic_ai/ext/aci.py,sha256=vUaNIj6pRM52x6RkPW_DohSYxJPm75pPUfOMw2i5Xx0,2515
35
+ pydantic_ai/ext/langchain.py,sha256=GemxfhpyG1JPxj69PbRiSJANnY8Q5s4hSB7wqt-uTbo,2266
36
+ pydantic_ai/models/__init__.py,sha256=P4tvuf_AS_sl5lfAJd6PxljUHREwSSYmvZdCs8pg4PA,30490
37
+ pydantic_ai/models/anthropic.py,sha256=R_vOfxYiZbijFDLHYz8cMaruGOWL4To1c2iMzVuD-l0,23823
36
38
  pydantic_ai/models/bedrock.py,sha256=WnYykDnkyBd340tpt4l35T8SjT3z50RO83EZ8n77FVA,29399
37
39
  pydantic_ai/models/cohere.py,sha256=PTqwMRsgaLGVUrzb80sh9jS6CNuvDokvPHKT5KTYR_g,12788
38
40
  pydantic_ai/models/fallback.py,sha256=URaV-dTQWkg99xrlkmknue5lXZWDcEt7cJ1Vsky4oB4,5130
39
- pydantic_ai/models/function.py,sha256=Qyvg7n9SMyhNVugd9T525OrbWYW8BQedy7kBRpHu48Q,12457
40
- pydantic_ai/models/gemini.py,sha256=iyuw3FBfLsdeUT10sHz5xWXsesUrhE0yLa7R6hy8HJs,38603
41
- pydantic_ai/models/google.py,sha256=w6G9rXmL0x-PCI7KyBJFlqUdQV5feCpTR2kgCi52hTI,24192
42
- pydantic_ai/models/groq.py,sha256=fMT1WPkhuLH2G0iQ8IMxZ1oc7zQVgTLhzVZYydASt88,18665
41
+ pydantic_ai/models/function.py,sha256=UIed008-9GgPSox_5uAzmjBLx71kcCWvBS2N3j48Ru4,13586
42
+ pydantic_ai/models/gemini.py,sha256=H5se385dnwZUf59LJjCcSkD3wU4gQVo2KUIuqtF4SVw,38356
43
+ pydantic_ai/models/google.py,sha256=p3EPsZ09LIMGdxedHYKYNlRTL7xLJk2TD93BqzHgq0g,23891
44
+ pydantic_ai/models/groq.py,sha256=Ll933U1qfWEA3YfGE4dCJBNNSGwH4DmmiKKfhrjdiSM,18700
43
45
  pydantic_ai/models/huggingface.py,sha256=DTkbfySeBfRqIrbMzgUunGnIo-3mLuaDyQjBYTT42bI,18857
44
46
  pydantic_ai/models/instrumented.py,sha256=dkVCY_SIoPEBLyAr7jODTsJWh6LzslPVzPwOfvqy3iA,16078
45
47
  pydantic_ai/models/mcp_sampling.py,sha256=q9nnjNEAAbhrfRc_Qw5z9TtCHMG_SwlCWW9FvKWjh8k,3395
46
- pydantic_ai/models/mistral.py,sha256=fvR5ijjOGdV3OHBKtQFPBNjNO2qXhB0hxzXZkkSLMmY,30716
47
- pydantic_ai/models/openai.py,sha256=gyN9idM3164ftEW4iW9fFogKP_xQh4--ChwkHQxG-5Q,54264
48
+ pydantic_ai/models/mistral.py,sha256=o7bDP7CF8_MzZ3jYtPpjqm8uVDhKTjw1KePPZCxXRhE,30720
49
+ pydantic_ai/models/openai.py,sha256=NFFMxWox4HmT8j_kko66yXepZVzpzFQ1sHk06dZLmkQ,54255
48
50
  pydantic_ai/models/test.py,sha256=S8hp3fJZJVSwWl01bBi-q7YpijdbstXhGg3aCPon98o,18227
49
51
  pydantic_ai/models/wrapper.py,sha256=A5-ncYhPF8c9S_czGoXkd55s2KOQb65p3jbVpwZiFPA,2043
50
52
  pydantic_ai/profiles/__init__.py,sha256=BXMqUpgRfosmYgcxjKAI9ESCj47JTSa30DhKXEgVLzM,2419
@@ -53,10 +55,11 @@ pydantic_ai/profiles/amazon.py,sha256=O4ijm1Lpz01vaSiHrkSeGQhbCKV5lyQVtHYqh0pCW_
53
55
  pydantic_ai/profiles/anthropic.py,sha256=DtTGh85tbkTrrrn2OrJ4FJKXWUIxUH_1Vw6y5fyMRyM,222
54
56
  pydantic_ai/profiles/cohere.py,sha256=lcL34Ht1jZopwuqoU6OV9l8vN4zwF-jiPjlsEABbSRo,215
55
57
  pydantic_ai/profiles/deepseek.py,sha256=DS_idprnXpMliKziKF0k1neLDJOwUvpatZ3YLaiYnCM,219
56
- pydantic_ai/profiles/google.py,sha256=DJ0otpkCgVIrjwV2lzAUAejw8ivwZT9pNAY_sGRcrVg,4891
58
+ pydantic_ai/profiles/google.py,sha256=UUa1WxF--aryLcp0tKACeiSVkLAC4_mYixohRXPhJQs,4892
57
59
  pydantic_ai/profiles/grok.py,sha256=nBOxOCYCK9aiLmz2Q-esqYhotNbbBC1boAoOYIk1tVw,211
58
60
  pydantic_ai/profiles/meta.py,sha256=IAGPoUrLWd-g9ajAgpWp9fIeOrP-7dBlZ2HEFjIhUbY,334
59
61
  pydantic_ai/profiles/mistral.py,sha256=ll01PmcK3szwlTfbaJLQmfd0TADN8lqjov9HpPJzCMQ,217
62
+ pydantic_ai/profiles/moonshotai.py,sha256=LL5RacKHKn6rdvhoKjpGgZ8aVriv5NMeL6HCWEANAiU,223
60
63
  pydantic_ai/profiles/openai.py,sha256=wFFtzbM22HbxxRNDXYEs6tr6_RSbv8xN_xBPz6RsP9s,6698
61
64
  pydantic_ai/profiles/qwen.py,sha256=u7pL8uomoQTVl45g5wDrHx0P_oFDLaN6ALswuwmkWc0,334
62
65
  pydantic_ai/providers/__init__.py,sha256=8D685KEGzwtgeg1Z5tC9ugr_O16E1VWWmeqSgAnx69k,3779
@@ -70,16 +73,26 @@ pydantic_ai/providers/github.py,sha256=zPu3oVJKjUE4zIqZ0YfgcTFBNdEy5rIBrSOdPCHJE
70
73
  pydantic_ai/providers/google.py,sha256=b8MOCsawPm07HrFEZGip5OGzW3zfq3HcCDzDNwXgPY4,5946
71
74
  pydantic_ai/providers/google_gla.py,sha256=BCF5_6EVtpkCZ6qIDuvgY1Qa9EirS71l51CBqPqk4C4,1825
72
75
  pydantic_ai/providers/google_vertex.py,sha256=MN3hnZg06pp2VFAmr3o_aAeop7LHj8TbgPSaF5D6PZE,9596
73
- pydantic_ai/providers/grok.py,sha256=mtlx7KP6xEDrDnYR1pmuT61wjUlYbCJNASNCDfVGQ5A,2912
74
- pydantic_ai/providers/groq.py,sha256=LcD0vXiZhWOsMatz0yKzt9NCIAw6H7OhJsQ5GPDqL44,3835
76
+ pydantic_ai/providers/grok.py,sha256=dIkpxuuJlZ4pFtTSgeeJgiM_Z3mJU9qvk4f7jvSzi24,3141
77
+ pydantic_ai/providers/groq.py,sha256=hqcR-RFHHHeemYP3K16IFeQTJKywNEU2wNZOSGTz6fE,3957
75
78
  pydantic_ai/providers/heroku.py,sha256=NmDIkAdxtWsvCjlX-bKI5FgI4HW1zO9-e0mrNQNGMCk,2990
76
79
  pydantic_ai/providers/huggingface.py,sha256=LRmJcJpQRRYvam3IAPkYs2fMUJf70GgE3aDgQltGRCU,3821
77
80
  pydantic_ai/providers/mistral.py,sha256=EIUSENjFuGzBhvbdrarUTM4VPkesIMnZrzfnEKHOsc4,3120
78
81
  pydantic_ai/providers/openai.py,sha256=7iGij0EaFylab7dTZAZDgXr78tr-HsZrn9EI9AkWBNQ,3091
79
82
  pydantic_ai/providers/openrouter.py,sha256=NXjNdnlXIBrBMMqbzcWQnowXOuZh4NHikXenBn5h3mc,4061
80
83
  pydantic_ai/providers/together.py,sha256=zFVSMSm5jXbpkNouvBOTjWrPmlPpCp6sQS5LMSyVjrQ,3482
81
- pydantic_ai_slim-0.4.3.dist-info/METADATA,sha256=QVhjCkzpDVNZRgtXCo4VCcuHM0gq6KhCPyPqbgH1EbM,3935
82
- pydantic_ai_slim-0.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
83
- pydantic_ai_slim-0.4.3.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
84
- pydantic_ai_slim-0.4.3.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
85
- pydantic_ai_slim-0.4.3.dist-info/RECORD,,
84
+ pydantic_ai/toolsets/__init__.py,sha256=JCnqqAFeuHhmVW4XK0LM6Op_9B1cvsQUJ3vTmQ9Z5cQ,590
85
+ pydantic_ai/toolsets/abstract.py,sha256=LqunlpwUsoHVn4VMtdjEoLY5kiMUF74PZ4KW539K8tQ,6027
86
+ pydantic_ai/toolsets/combined.py,sha256=bmhQqxq4WQz_55a_cMsUfcCK6ggF74QEPoa12w34MOU,3371
87
+ pydantic_ai/toolsets/deferred.py,sha256=j_CO2KesBXFPyVYiIk3sO2bimJ1bssnShdaGx4UNuPQ,1444
88
+ pydantic_ai/toolsets/filtered.py,sha256=qmPeQDTZoWa_yyk6VXKHcpV9NFgdnLN48sBf7WItjBs,855
89
+ pydantic_ai/toolsets/function.py,sha256=Pgc8q6vh3qkBzI3xL0k-CQaETGG63zfy1PyWtqqzXwc,10186
90
+ pydantic_ai/toolsets/prefixed.py,sha256=MIStkzUdiU0rk2Y6P19IrTBxspH5pTstGxsqCBt-CX0,1293
91
+ pydantic_ai/toolsets/prepared.py,sha256=Zjfz6S8In6PBVxoKFN9sKPN984zO6t0awB7Lnq5KODw,1431
92
+ pydantic_ai/toolsets/renamed.py,sha256=JuLHpi-hYPiSPlaTpN8WiXLiGsywYK0axi2lW2Qs75k,1637
93
+ pydantic_ai/toolsets/wrapper.py,sha256=WjLoiM1WDuffSJ4mDS6pZrEZGHgZ421fjrqFcB66W94,1205
94
+ pydantic_ai_slim-0.4.4.dist-info/METADATA,sha256=pcwhN2TvSyuzRN7foXXXMgW5AuvTYagRqsN7KE3G0lE,4098
95
+ pydantic_ai_slim-0.4.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ pydantic_ai_slim-0.4.4.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
97
+ pydantic_ai_slim-0.4.4.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
98
+ pydantic_ai_slim-0.4.4.dist-info/RECORD,,