pydantic-ai-slim 0.0.6a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pydantic-ai-slim might be problematic. Click here for more details.
- pydantic_ai/__init__.py +8 -0
- pydantic_ai/_griffe.py +128 -0
- pydantic_ai/_pydantic.py +216 -0
- pydantic_ai/_result.py +258 -0
- pydantic_ai/_retriever.py +114 -0
- pydantic_ai/_system_prompt.py +33 -0
- pydantic_ai/_utils.py +247 -0
- pydantic_ai/agent.py +795 -0
- pydantic_ai/dependencies.py +83 -0
- pydantic_ai/exceptions.py +56 -0
- pydantic_ai/messages.py +205 -0
- pydantic_ai/models/__init__.py +300 -0
- pydantic_ai/models/function.py +268 -0
- pydantic_ai/models/gemini.py +720 -0
- pydantic_ai/models/groq.py +400 -0
- pydantic_ai/models/openai.py +379 -0
- pydantic_ai/models/test.py +389 -0
- pydantic_ai/models/vertexai.py +306 -0
- pydantic_ai/py.typed +0 -0
- pydantic_ai/result.py +314 -0
- pydantic_ai_slim-0.0.6a1.dist-info/METADATA +49 -0
- pydantic_ai_slim-0.0.6a1.dist-info/RECORD +23 -0
- pydantic_ai_slim-0.0.6a1.dist-info/WHEEL +4 -0
pydantic_ai/result.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
from __future__ import annotations as _annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import AsyncIterator
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Generic, TypeVar, cast
|
|
8
|
+
|
|
9
|
+
import logfire_api
|
|
10
|
+
|
|
11
|
+
from . import _result, _utils, exceptions, messages, models
|
|
12
|
+
from .dependencies import AgentDeps
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
'ResultData',
|
|
16
|
+
'Cost',
|
|
17
|
+
'RunResult',
|
|
18
|
+
'StreamedRunResult',
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
ResultData = TypeVar('ResultData')
|
|
23
|
+
"""Type variable for the result data of a run."""
|
|
24
|
+
|
|
25
|
+
_logfire = logfire_api.Logfire(otel_scope='pydantic-ai')
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class Cost:
|
|
30
|
+
"""Cost of a request or run.
|
|
31
|
+
|
|
32
|
+
Responsibility for calculating costs is on the model used, PydanticAI simply sums the cost of requests.
|
|
33
|
+
|
|
34
|
+
You'll need to look up the documentation of the model you're using to convent "token count" costs to monetary costs.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
request_tokens: int | None = None
|
|
38
|
+
"""Tokens used in processing the request."""
|
|
39
|
+
response_tokens: int | None = None
|
|
40
|
+
"""Tokens used in generating the response."""
|
|
41
|
+
total_tokens: int | None = None
|
|
42
|
+
"""Total tokens used in the whole run, should generally be equal to `request_tokens + response_tokens`."""
|
|
43
|
+
details: dict[str, int] | None = None
|
|
44
|
+
"""Any extra details returned by the model."""
|
|
45
|
+
|
|
46
|
+
def __add__(self, other: Cost) -> Cost:
|
|
47
|
+
"""Add two costs together.
|
|
48
|
+
|
|
49
|
+
This is provided so it's trivial to sum costs from multiple requests and runs.
|
|
50
|
+
"""
|
|
51
|
+
counts: dict[str, int] = {}
|
|
52
|
+
for field in 'request_tokens', 'response_tokens', 'total_tokens':
|
|
53
|
+
self_value = getattr(self, field)
|
|
54
|
+
other_value = getattr(other, field)
|
|
55
|
+
if self_value is not None or other_value is not None:
|
|
56
|
+
counts[field] = (self_value or 0) + (other_value or 0)
|
|
57
|
+
|
|
58
|
+
details = self.details.copy() if self.details is not None else None
|
|
59
|
+
if other.details is not None:
|
|
60
|
+
details = details or {}
|
|
61
|
+
for key, value in other.details.items():
|
|
62
|
+
details[key] = details.get(key, 0) + value
|
|
63
|
+
|
|
64
|
+
return Cost(**counts, details=details or None)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class _BaseRunResult(ABC, Generic[ResultData]):
|
|
69
|
+
"""Base type for results.
|
|
70
|
+
|
|
71
|
+
You should not import or use this type directly, instead use its subclasses `RunResult` and `StreamedRunResult`.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
_all_messages: list[messages.Message]
|
|
75
|
+
_new_message_index: int
|
|
76
|
+
|
|
77
|
+
def all_messages(self) -> list[messages.Message]:
|
|
78
|
+
"""Return the history of messages."""
|
|
79
|
+
# this is a method to be consistent with the other methods
|
|
80
|
+
return self._all_messages
|
|
81
|
+
|
|
82
|
+
def all_messages_json(self) -> bytes:
|
|
83
|
+
"""Return all messages from [`all_messages`][..all_messages] as JSON bytes."""
|
|
84
|
+
return messages.MessagesTypeAdapter.dump_json(self.all_messages())
|
|
85
|
+
|
|
86
|
+
def new_messages(self) -> list[messages.Message]:
|
|
87
|
+
"""Return new messages associated with this run.
|
|
88
|
+
|
|
89
|
+
System prompts and any messages from older runs are excluded.
|
|
90
|
+
"""
|
|
91
|
+
return self.all_messages()[self._new_message_index :]
|
|
92
|
+
|
|
93
|
+
def new_messages_json(self) -> bytes:
|
|
94
|
+
"""Return new messages from [`new_messages`][..new_messages] as JSON bytes."""
|
|
95
|
+
return messages.MessagesTypeAdapter.dump_json(self.new_messages())
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def cost(self) -> Cost:
|
|
99
|
+
raise NotImplementedError()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class RunResult(_BaseRunResult[ResultData]):
|
|
104
|
+
"""Result of a non-streamed run."""
|
|
105
|
+
|
|
106
|
+
data: ResultData
|
|
107
|
+
"""Data from the final response in the run."""
|
|
108
|
+
_cost: Cost
|
|
109
|
+
|
|
110
|
+
def cost(self) -> Cost:
|
|
111
|
+
"""Return the cost of the whole run."""
|
|
112
|
+
return self._cost
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass
|
|
116
|
+
class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultData]):
|
|
117
|
+
"""Result of a streamed run that returns structured data via a tool call."""
|
|
118
|
+
|
|
119
|
+
cost_so_far: Cost
|
|
120
|
+
"""Cost of the run up until the last request."""
|
|
121
|
+
_stream_response: models.EitherStreamedResponse
|
|
122
|
+
_result_schema: _result.ResultSchema[ResultData] | None
|
|
123
|
+
_deps: AgentDeps
|
|
124
|
+
_result_validators: list[_result.ResultValidator[AgentDeps, ResultData]]
|
|
125
|
+
is_complete: bool = False
|
|
126
|
+
"""Whether the stream has all been received.
|
|
127
|
+
|
|
128
|
+
This is set to `True` when one of
|
|
129
|
+
[`stream`][pydantic_ai.result.StreamedRunResult.stream],
|
|
130
|
+
[`stream_text`][pydantic_ai.result.StreamedRunResult.stream_text],
|
|
131
|
+
[`stream_structured`][pydantic_ai.result.StreamedRunResult.stream_structured] or
|
|
132
|
+
[`get_data`][pydantic_ai.result.StreamedRunResult.get_data] completes.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
async def stream(self, *, debounce_by: float | None = 0.1) -> AsyncIterator[ResultData]:
|
|
136
|
+
"""Stream the response as an async iterable.
|
|
137
|
+
|
|
138
|
+
The pydantic validator for structured data will be called in
|
|
139
|
+
[partial mode](https://docs.pydantic.dev/dev/concepts/experimental/#partial-validation)
|
|
140
|
+
on each iteration.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
debounce_by: by how much (if at all) to debounce/group the response chunks by. `None` means no debouncing.
|
|
144
|
+
Debouncing is particularly important for long structured responses to reduce the overhead of
|
|
145
|
+
performing validation as each token is received.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
An async iterable of the response data.
|
|
149
|
+
"""
|
|
150
|
+
if isinstance(self._stream_response, models.StreamTextResponse):
|
|
151
|
+
async for text in self.stream_text(debounce_by=debounce_by):
|
|
152
|
+
yield cast(ResultData, text)
|
|
153
|
+
else:
|
|
154
|
+
async for structured_message, is_last in self.stream_structured(debounce_by=debounce_by):
|
|
155
|
+
yield await self.validate_structured_result(structured_message, allow_partial=not is_last)
|
|
156
|
+
|
|
157
|
+
async def stream_text(self, *, delta: bool = False, debounce_by: float | None = 0.1) -> AsyncIterator[str]:
|
|
158
|
+
"""Stream the text result as an async iterable.
|
|
159
|
+
|
|
160
|
+
!!! note
|
|
161
|
+
This method will fail if the response is structured,
|
|
162
|
+
e.g. if [`is_structured`][pydantic_ai.result.StreamedRunResult.is_structured] returns `True`.
|
|
163
|
+
|
|
164
|
+
!!! note
|
|
165
|
+
Result validators will NOT be called on the text result if `delta=True`.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
delta: if `True`, yield each chunk of text as it is received, if `False` (default), yield the full text
|
|
169
|
+
up to the current point.
|
|
170
|
+
debounce_by: by how much (if at all) to debounce/group the response chunks by. `None` means no debouncing.
|
|
171
|
+
Debouncing is particularly important for long structured responses to reduce the overhead of
|
|
172
|
+
performing validation as each token is received.
|
|
173
|
+
"""
|
|
174
|
+
with _logfire.span('response stream text') as lf_span:
|
|
175
|
+
if isinstance(self._stream_response, models.StreamStructuredResponse):
|
|
176
|
+
raise exceptions.UserError('stream_text() can only be used with text responses')
|
|
177
|
+
if delta:
|
|
178
|
+
async with _utils.group_by_temporal(self._stream_response, debounce_by) as group_iter:
|
|
179
|
+
async for _ in group_iter:
|
|
180
|
+
yield ''.join(self._stream_response.get())
|
|
181
|
+
final_delta = ''.join(self._stream_response.get(final=True))
|
|
182
|
+
if final_delta:
|
|
183
|
+
yield final_delta
|
|
184
|
+
else:
|
|
185
|
+
# a quick benchmark shows it's faster to build up a string with concat when we're
|
|
186
|
+
# yielding at each step
|
|
187
|
+
chunks: list[str] = []
|
|
188
|
+
combined = ''
|
|
189
|
+
async with _utils.group_by_temporal(self._stream_response, debounce_by) as group_iter:
|
|
190
|
+
async for _ in group_iter:
|
|
191
|
+
new = False
|
|
192
|
+
for chunk in self._stream_response.get():
|
|
193
|
+
chunks.append(chunk)
|
|
194
|
+
new = True
|
|
195
|
+
if new:
|
|
196
|
+
combined = await self._validate_text_result(''.join(chunks))
|
|
197
|
+
yield combined
|
|
198
|
+
|
|
199
|
+
new = False
|
|
200
|
+
for chunk in self._stream_response.get(final=True):
|
|
201
|
+
chunks.append(chunk)
|
|
202
|
+
new = True
|
|
203
|
+
if new:
|
|
204
|
+
combined = await self._validate_text_result(''.join(chunks))
|
|
205
|
+
yield combined
|
|
206
|
+
lf_span.set_attribute('combined_text', combined)
|
|
207
|
+
self._marked_completed(text=combined)
|
|
208
|
+
|
|
209
|
+
async def stream_structured(
|
|
210
|
+
self, *, debounce_by: float | None = 0.1
|
|
211
|
+
) -> AsyncIterator[tuple[messages.ModelStructuredResponse, bool]]:
|
|
212
|
+
"""Stream the response as an async iterable of Structured LLM Messages.
|
|
213
|
+
|
|
214
|
+
!!! note
|
|
215
|
+
This method will fail if the response is text,
|
|
216
|
+
e.g. if [`is_structured`][pydantic_ai.result.StreamedRunResult.is_structured] returns `False`.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
debounce_by: by how much (if at all) to debounce/group the response chunks by. `None` means no debouncing.
|
|
220
|
+
Debouncing is particularly important for long structured responses to reduce the overhead of
|
|
221
|
+
performing validation as each token is received.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
An async iterable of the structured response message and whether that is the last message.
|
|
225
|
+
"""
|
|
226
|
+
with _logfire.span('response stream structured') as lf_span:
|
|
227
|
+
if isinstance(self._stream_response, models.StreamTextResponse):
|
|
228
|
+
raise exceptions.UserError('stream_structured() can only be used with structured responses')
|
|
229
|
+
else:
|
|
230
|
+
# we should already have a message at this point, yield that first if it has any content
|
|
231
|
+
msg = self._stream_response.get()
|
|
232
|
+
if any(call.has_content() for call in msg.calls):
|
|
233
|
+
yield msg, False
|
|
234
|
+
async with _utils.group_by_temporal(self._stream_response, debounce_by) as group_iter:
|
|
235
|
+
async for _ in group_iter:
|
|
236
|
+
msg = self._stream_response.get()
|
|
237
|
+
if any(call.has_content() for call in msg.calls):
|
|
238
|
+
yield msg, False
|
|
239
|
+
msg = self._stream_response.get(final=True)
|
|
240
|
+
yield msg, True
|
|
241
|
+
lf_span.set_attribute('structured_response', msg)
|
|
242
|
+
self._marked_completed(structured_message=msg)
|
|
243
|
+
|
|
244
|
+
async def get_data(self) -> ResultData:
|
|
245
|
+
"""Stream the whole response, validate and return it."""
|
|
246
|
+
async for _ in self._stream_response:
|
|
247
|
+
pass
|
|
248
|
+
if isinstance(self._stream_response, models.StreamTextResponse):
|
|
249
|
+
text = ''.join(self._stream_response.get(final=True))
|
|
250
|
+
text = await self._validate_text_result(text)
|
|
251
|
+
self._marked_completed(text=text)
|
|
252
|
+
return cast(ResultData, text)
|
|
253
|
+
else:
|
|
254
|
+
structured_message = self._stream_response.get(final=True)
|
|
255
|
+
self._marked_completed(structured_message=structured_message)
|
|
256
|
+
return await self.validate_structured_result(structured_message)
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def is_structured(self) -> bool:
|
|
260
|
+
"""Return whether the stream response contains structured data (as opposed to text)."""
|
|
261
|
+
return isinstance(self._stream_response, models.StreamStructuredResponse)
|
|
262
|
+
|
|
263
|
+
def cost(self) -> Cost:
|
|
264
|
+
"""Return the cost of the whole run.
|
|
265
|
+
|
|
266
|
+
!!! note
|
|
267
|
+
This won't return the full cost until the stream is finished.
|
|
268
|
+
"""
|
|
269
|
+
return self.cost_so_far + self._stream_response.cost()
|
|
270
|
+
|
|
271
|
+
def timestamp(self) -> datetime:
|
|
272
|
+
"""Get the timestamp of the response."""
|
|
273
|
+
return self._stream_response.timestamp()
|
|
274
|
+
|
|
275
|
+
async def validate_structured_result(
|
|
276
|
+
self, message: messages.ModelStructuredResponse, *, allow_partial: bool = False
|
|
277
|
+
) -> ResultData:
|
|
278
|
+
"""Validate a structured result message."""
|
|
279
|
+
assert self._result_schema is not None, 'Expected _result_schema to not be None'
|
|
280
|
+
match = self._result_schema.find_tool(message)
|
|
281
|
+
if match is None:
|
|
282
|
+
raise exceptions.UnexpectedModelBehavior(
|
|
283
|
+
f'Invalid message, unable to find tool: {self._result_schema.tool_names()}'
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
call, result_tool = match
|
|
287
|
+
result_data = result_tool.validate(call, allow_partial=allow_partial, wrap_validation_errors=False)
|
|
288
|
+
|
|
289
|
+
for validator in self._result_validators:
|
|
290
|
+
result_data = await validator.validate(result_data, self._deps, 0, call)
|
|
291
|
+
return result_data
|
|
292
|
+
|
|
293
|
+
async def _validate_text_result(self, text: str) -> str:
|
|
294
|
+
for validator in self._result_validators:
|
|
295
|
+
text = await validator.validate( # pyright: ignore[reportAssignmentType]
|
|
296
|
+
text, # pyright: ignore[reportArgumentType]
|
|
297
|
+
self._deps,
|
|
298
|
+
0,
|
|
299
|
+
None,
|
|
300
|
+
)
|
|
301
|
+
return text
|
|
302
|
+
|
|
303
|
+
def _marked_completed(
|
|
304
|
+
self, *, text: str | None = None, structured_message: messages.ModelStructuredResponse | None = None
|
|
305
|
+
) -> None:
|
|
306
|
+
self.is_complete = True
|
|
307
|
+
if text is not None:
|
|
308
|
+
assert structured_message is None, 'Either text or structured_message should provided, not both'
|
|
309
|
+
self._all_messages.append(
|
|
310
|
+
messages.ModelTextResponse(content=text, timestamp=self._stream_response.timestamp())
|
|
311
|
+
)
|
|
312
|
+
else:
|
|
313
|
+
assert structured_message is not None, 'Either text or structured_message should provided, not both'
|
|
314
|
+
self._all_messages.append(structured_message)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: pydantic-ai-slim
|
|
3
|
+
Version: 0.0.6a1
|
|
4
|
+
Summary: Agent Framework / shim to use Pydantic with LLMs
|
|
5
|
+
Author-email: Samuel Colvin <samuel@pydantic.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Environment :: MacOS X
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Operating System :: Unix
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Internet
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Requires-Dist: eval-type-backport>=0.2.0
|
|
28
|
+
Requires-Dist: griffe>=1.3.2
|
|
29
|
+
Requires-Dist: httpx>=0.27.2
|
|
30
|
+
Requires-Dist: logfire-api>=1.2.0
|
|
31
|
+
Requires-Dist: pydantic>=2.10
|
|
32
|
+
Provides-Extra: groq
|
|
33
|
+
Requires-Dist: groq>=0.12.0; extra == 'groq'
|
|
34
|
+
Provides-Extra: logfire
|
|
35
|
+
Requires-Dist: logfire>=2.3; extra == 'logfire'
|
|
36
|
+
Provides-Extra: openai
|
|
37
|
+
Requires-Dist: openai>=1.54.3; extra == 'openai'
|
|
38
|
+
Provides-Extra: vertexai
|
|
39
|
+
Requires-Dist: google-auth>=2.36.0; extra == 'vertexai'
|
|
40
|
+
Requires-Dist: requests>=2.32.3; extra == 'vertexai'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# Coming soon
|
|
44
|
+
|
|
45
|
+
[](https://github.com/pydantic/pydantic-ai/actions/workflows/ci.yml?query=branch%3Amain)
|
|
46
|
+
[](https://coverage-badge.samuelcolvin.workers.dev/redirect/pydantic/pydantic-ai)
|
|
47
|
+
[](https://pypi.python.org/pypi/pydantic-ai)
|
|
48
|
+
[](https://github.com/pydantic/pydantic-ai)
|
|
49
|
+
[](https://github.com/pydantic/pydantic-ai/blob/main/LICENSE)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
pydantic_ai/__init__.py,sha256=CpfmVxuykeDRkujNMVwGkpa1FJRw3W8MgQ8ccLX9D-E,314
|
|
2
|
+
pydantic_ai/_griffe.py,sha256=pRjCJ6B1hhx6k46XJgl9zF6aRYxRmqEZKFok8unp4Iw,3449
|
|
3
|
+
pydantic_ai/_pydantic.py,sha256=JslSZjj8Ni98oGfrmbS3RGM0B0_PdNZynvgAW2CnXeU,8056
|
|
4
|
+
pydantic_ai/_result.py,sha256=_qVaq_gmQyPWlyFn_9unafPqOiwSgoa23qxvUwMypo8,9683
|
|
5
|
+
pydantic_ai/_retriever.py,sha256=HxYDfpvcOrhv9gq_1CKRIRAFyLs0qquJGDO9LAWy8ok,4638
|
|
6
|
+
pydantic_ai/_system_prompt.py,sha256=PfNCuG45mM65HtoTiYKz6pWv_CQ9dtxPjl-u8BEn2z4,1094
|
|
7
|
+
pydantic_ai/_utils.py,sha256=7tPzgiiDUWAZGH6zmBZ91CUN3aFSv0szEkw0RDbPLJg,8128
|
|
8
|
+
pydantic_ai/agent.py,sha256=nFwHI3w8JpCqze5UX5TAxiZsSSyavsyKo2W5ITNke1g,34454
|
|
9
|
+
pydantic_ai/dependencies.py,sha256=6IawVRoLSefOtO6oCsxB3kndJRVEP1-DHSE9-2T3ZW8,2509
|
|
10
|
+
pydantic_ai/exceptions.py,sha256=bcde_Xg2yCnSYduhTbbtH3_9kQR6UuKqWJNEzfxiKyw,1566
|
|
11
|
+
pydantic_ai/messages.py,sha256=tmZOFCGVIEmSk8YYQ9qiyb6Q-6DTiqOzfWiryCHVQpY,7536
|
|
12
|
+
pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
pydantic_ai/result.py,sha256=Gs2ZjuFJgONGJm8M5R2mGph5-lUFLBg7FxVrs2CVDPs,13525
|
|
14
|
+
pydantic_ai/models/__init__.py,sha256=gAH9jbSk6ezqwJpCoVHbdMwULz9mu5VuguARUqKfN8w,10140
|
|
15
|
+
pydantic_ai/models/function.py,sha256=dv1a1RhfdXqwXMFI_y8QzPWJj_YW6Q7twvKvO98JVUE,10124
|
|
16
|
+
pydantic_ai/models/gemini.py,sha256=vHg91s9UzqU3teNnvOJLXkYI8Gu9Wt1vhEu6zB3Ttd8,27677
|
|
17
|
+
pydantic_ai/models/groq.py,sha256=7zKpFg3Fvc-S2n_EroQg5AAD5cOj4y7SKQ7VjMiNSUs,14939
|
|
18
|
+
pydantic_ai/models/openai.py,sha256=_XZ0eDbk3Q3_V2MlMMaZArzYGSm2VuBR47lv4TmFgjY,14923
|
|
19
|
+
pydantic_ai/models/test.py,sha256=T53NKS7pQbCgzo7QIFGdObt3zbDs5t-tjSlkDNsKCuo,14523
|
|
20
|
+
pydantic_ai/models/vertexai.py,sha256=YiYB82WOB5Kp4NjYhweN0ZNjE39-dnpDseMyoyf6Evk,11294
|
|
21
|
+
pydantic_ai_slim-0.0.6a1.dist-info/METADATA,sha256=_-oC_F0n1UQiREqVF5kfjKXuK9eYQapX5U2hv03q4J4,2372
|
|
22
|
+
pydantic_ai_slim-0.0.6a1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
23
|
+
pydantic_ai_slim-0.0.6a1.dist-info/RECORD,,
|