pydantic-ai-slim 0.4.3__py3-none-any.whl → 0.4.5__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/_a2a.py +3 -3
- pydantic_ai/_agent_graph.py +220 -319
- pydantic_ai/_cli.py +9 -7
- pydantic_ai/_output.py +295 -331
- pydantic_ai/_parts_manager.py +2 -2
- pydantic_ai/_run_context.py +8 -14
- pydantic_ai/_tool_manager.py +190 -0
- pydantic_ai/_utils.py +18 -1
- pydantic_ai/ag_ui.py +675 -0
- pydantic_ai/agent.py +378 -164
- pydantic_ai/exceptions.py +12 -0
- pydantic_ai/ext/aci.py +12 -3
- pydantic_ai/ext/langchain.py +9 -1
- pydantic_ai/format_prompt.py +3 -6
- pydantic_ai/mcp.py +147 -84
- pydantic_ai/messages.py +13 -5
- pydantic_ai/models/__init__.py +30 -18
- pydantic_ai/models/anthropic.py +1 -1
- pydantic_ai/models/function.py +50 -24
- pydantic_ai/models/gemini.py +1 -18
- pydantic_ai/models/google.py +2 -11
- pydantic_ai/models/groq.py +1 -0
- pydantic_ai/models/instrumented.py +6 -1
- pydantic_ai/models/mistral.py +1 -1
- pydantic_ai/models/openai.py +16 -4
- pydantic_ai/output.py +21 -7
- pydantic_ai/profiles/google.py +1 -1
- pydantic_ai/profiles/moonshotai.py +8 -0
- pydantic_ai/providers/grok.py +13 -1
- pydantic_ai/providers/groq.py +2 -0
- pydantic_ai/result.py +58 -45
- pydantic_ai/tools.py +26 -119
- pydantic_ai/toolsets/__init__.py +22 -0
- pydantic_ai/toolsets/abstract.py +155 -0
- pydantic_ai/toolsets/combined.py +88 -0
- pydantic_ai/toolsets/deferred.py +38 -0
- pydantic_ai/toolsets/filtered.py +24 -0
- pydantic_ai/toolsets/function.py +238 -0
- pydantic_ai/toolsets/prefixed.py +37 -0
- pydantic_ai/toolsets/prepared.py +36 -0
- pydantic_ai/toolsets/renamed.py +42 -0
- pydantic_ai/toolsets/wrapper.py +37 -0
- pydantic_ai/usage.py +14 -8
- {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.5.dist-info}/METADATA +10 -7
- {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.5.dist-info}/RECORD +48 -35
- {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.5.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.5.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.4.3.dist-info → pydantic_ai_slim-0.4.5.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;
|
|
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
|
-
|
|
62
|
-
'gen_ai.usage.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
+
Version: 0.4.5
|
|
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.
|
|
33
|
+
Requires-Dist: pydantic-graph==0.4.5
|
|
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.
|
|
54
|
+
Requires-Dist: pydantic-evals==0.4.5; 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.
|
|
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
|
-
#
|
|
76
|
+
# Pydantic AI Slim
|
|
74
77
|
|
|
75
78
|
[](https://github.com/pydantic/pydantic-ai/actions/workflows/ci.yml?query=branch%3Amain)
|
|
76
79
|
[](https://coverage-badge.samuelcolvin.workers.dev/redirect/pydantic/pydantic-ai)
|
|
@@ -78,6 +81,6 @@ Description-Content-Type: text/markdown
|
|
|
78
81
|
[](https://github.com/pydantic/pydantic-ai)
|
|
79
82
|
[](https://github.com/pydantic/pydantic-ai/blob/main/LICENSE)
|
|
80
83
|
|
|
81
|
-
|
|
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
|
-
pydantic_ai/_a2a.py,sha256=
|
|
4
|
-
pydantic_ai/_agent_graph.py,sha256=
|
|
5
|
-
pydantic_ai/_cli.py,sha256=
|
|
3
|
+
pydantic_ai/_a2a.py,sha256=Tw_j9VRud0rLEk5kRs4GhRyhWYioXnsoZaTTyISq4M4,12126
|
|
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=
|
|
10
|
-
pydantic_ai/_parts_manager.py,sha256=
|
|
11
|
-
pydantic_ai/_run_context.py,sha256=
|
|
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/
|
|
15
|
-
pydantic_ai/
|
|
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=BIO9-5FGtrI7LfNe8BsjuLmLuzJgIYvR3OB7Bf3vctc,107920
|
|
16
18
|
pydantic_ai/direct.py,sha256=WRfgke3zm-eeR39LTuh9XI2TrdHXAqO81eDvFwih4Ko,14803
|
|
17
|
-
pydantic_ai/exceptions.py,sha256=
|
|
19
|
+
pydantic_ai/exceptions.py,sha256=o0l6fBrWI5UhosICVZ2yaT-JEJF05eqBlKlQCW8i9UM,3462
|
|
18
20
|
pydantic_ai/format_as_xml.py,sha256=IINfh1evWDphGahqHNLBArB5dQ4NIqS3S-kru35ztGg,372
|
|
19
|
-
pydantic_ai/format_prompt.py,sha256=
|
|
20
|
-
pydantic_ai/mcp.py,sha256=
|
|
21
|
-
pydantic_ai/messages.py,sha256=
|
|
22
|
-
pydantic_ai/output.py,sha256=
|
|
21
|
+
pydantic_ai/format_prompt.py,sha256=Or-Ytq55RQb1UJqy2HKIyPpZ-knWXfdDP3Z6tNc6Orw,4244
|
|
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=
|
|
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=
|
|
27
|
-
pydantic_ai/usage.py,sha256=
|
|
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=
|
|
33
|
-
pydantic_ai/ext/langchain.py,sha256=
|
|
34
|
-
pydantic_ai/models/__init__.py,sha256=
|
|
35
|
-
pydantic_ai/models/anthropic.py,sha256=
|
|
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=
|
|
40
|
-
pydantic_ai/models/gemini.py,sha256=
|
|
41
|
-
pydantic_ai/models/google.py,sha256=
|
|
42
|
-
pydantic_ai/models/groq.py,sha256=
|
|
41
|
+
pydantic_ai/models/function.py,sha256=UIed008-9GgPSox_5uAzmjBLx71kcCWvBS2N3j48Ru4,13586
|
|
42
|
+
pydantic_ai/models/gemini.py,sha256=Pm8KKzrhRrjM39XyQsd9pCzaXwiE1dQ0wPB4Slt10ZI,37973
|
|
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
|
-
pydantic_ai/models/instrumented.py,sha256=
|
|
46
|
+
pydantic_ai/models/instrumented.py,sha256=aqvzspcGexn1Molbu6Mn4EEPRBSoQCCCS_yknJvJJ-8,16205
|
|
45
47
|
pydantic_ai/models/mcp_sampling.py,sha256=q9nnjNEAAbhrfRc_Qw5z9TtCHMG_SwlCWW9FvKWjh8k,3395
|
|
46
|
-
pydantic_ai/models/mistral.py,sha256=
|
|
47
|
-
pydantic_ai/models/openai.py,sha256=
|
|
48
|
+
pydantic_ai/models/mistral.py,sha256=o7bDP7CF8_MzZ3jYtPpjqm8uVDhKTjw1KePPZCxXRhE,30720
|
|
49
|
+
pydantic_ai/models/openai.py,sha256=_35Cp0-m-6ZECNRVcHpi4O4a37lJOc4OipEHHzZCkY4,55092
|
|
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=
|
|
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=
|
|
74
|
-
pydantic_ai/providers/groq.py,sha256=
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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.5.dist-info/METADATA,sha256=TfoF7Uy7T5NeiztgTEl2yqUnMYbMnaP-vZL_l9iQ6kI,4098
|
|
95
|
+
pydantic_ai_slim-0.4.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
96
|
+
pydantic_ai_slim-0.4.5.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
|
|
97
|
+
pydantic_ai_slim-0.4.5.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
|
|
98
|
+
pydantic_ai_slim-0.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|