pydantic-ai-slim 0.4.5__py3-none-any.whl → 0.4.7__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/_function_schema.py +13 -4
- pydantic_ai/_output.py +41 -25
- pydantic_ai/_parts_manager.py +31 -5
- pydantic_ai/ag_ui.py +68 -78
- pydantic_ai/agent.py +9 -29
- pydantic_ai/mcp.py +79 -19
- pydantic_ai/messages.py +74 -16
- pydantic_ai/models/__init__.py +12 -1
- pydantic_ai/models/anthropic.py +11 -3
- pydantic_ai/models/bedrock.py +4 -2
- pydantic_ai/models/cohere.py +6 -6
- pydantic_ai/models/function.py +19 -18
- pydantic_ai/models/gemini.py +5 -1
- pydantic_ai/models/google.py +9 -2
- pydantic_ai/models/groq.py +6 -2
- pydantic_ai/models/huggingface.py +6 -2
- pydantic_ai/models/mistral.py +15 -3
- pydantic_ai/models/openai.py +34 -7
- pydantic_ai/models/test.py +6 -2
- pydantic_ai/profiles/openai.py +8 -0
- pydantic_ai/providers/__init__.py +8 -0
- pydantic_ai/providers/moonshotai.py +97 -0
- pydantic_ai/providers/vercel.py +107 -0
- pydantic_ai/result.py +115 -151
- {pydantic_ai_slim-0.4.5.dist-info → pydantic_ai_slim-0.4.7.dist-info}/METADATA +7 -7
- {pydantic_ai_slim-0.4.5.dist-info → pydantic_ai_slim-0.4.7.dist-info}/RECORD +29 -27
- {pydantic_ai_slim-0.4.5.dist-info → pydantic_ai_slim-0.4.7.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.4.5.dist-info → pydantic_ai_slim-0.4.7.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.4.5.dist-info → pydantic_ai_slim-0.4.7.dist-info}/licenses/LICENSE +0 -0
pydantic_ai/result.py
CHANGED
|
@@ -63,22 +63,18 @@ class AgentStream(Generic[AgentDepsT, OutputDataT]):
|
|
|
63
63
|
async for response in self.stream_responses(debounce_by=debounce_by):
|
|
64
64
|
if self._final_result_event is not None:
|
|
65
65
|
try:
|
|
66
|
-
yield await self._validate_response(
|
|
67
|
-
response, self._final_result_event.tool_name, allow_partial=True
|
|
68
|
-
)
|
|
66
|
+
yield await self._validate_response(response, allow_partial=True)
|
|
69
67
|
except ValidationError:
|
|
70
68
|
pass
|
|
71
69
|
if self._final_result_event is not None: # pragma: no branch
|
|
72
|
-
yield await self._validate_response(
|
|
73
|
-
self._raw_stream_response.get(), self._final_result_event.tool_name, allow_partial=False
|
|
74
|
-
)
|
|
70
|
+
yield await self._validate_response(self._raw_stream_response.get(), allow_partial=False)
|
|
75
71
|
|
|
76
72
|
async def stream_responses(self, *, debounce_by: float | None = 0.1) -> AsyncIterator[_messages.ModelResponse]:
|
|
77
73
|
"""Asynchronously stream the (unvalidated) model responses for the agent."""
|
|
78
74
|
# if the message currently has any parts with content, yield before streaming
|
|
79
75
|
msg = self._raw_stream_response.get()
|
|
80
76
|
for part in msg.parts:
|
|
81
|
-
if part.has_content():
|
|
77
|
+
if part.has_content():
|
|
82
78
|
yield msg
|
|
83
79
|
break
|
|
84
80
|
|
|
@@ -86,6 +82,35 @@ class AgentStream(Generic[AgentDepsT, OutputDataT]):
|
|
|
86
82
|
async for _items in group_iter:
|
|
87
83
|
yield self._raw_stream_response.get() # current state of the response
|
|
88
84
|
|
|
85
|
+
async def stream_text(self, *, delta: bool = False, debounce_by: float | None = 0.1) -> AsyncIterator[str]:
|
|
86
|
+
"""Stream the text result as an async iterable.
|
|
87
|
+
|
|
88
|
+
!!! note
|
|
89
|
+
Result validators will NOT be called on the text result if `delta=True`.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
delta: if `True`, yield each chunk of text as it is received, if `False` (default), yield the full text
|
|
93
|
+
up to the current point.
|
|
94
|
+
debounce_by: by how much (if at all) to debounce/group the response chunks by. `None` means no debouncing.
|
|
95
|
+
Debouncing is particularly important for long structured responses to reduce the overhead of
|
|
96
|
+
performing validation as each token is received.
|
|
97
|
+
"""
|
|
98
|
+
if not isinstance(self._output_schema, PlainTextOutputSchema):
|
|
99
|
+
raise exceptions.UserError('stream_text() can only be used with text responses')
|
|
100
|
+
|
|
101
|
+
if delta:
|
|
102
|
+
async for text in self._stream_response_text(delta=True, debounce_by=debounce_by):
|
|
103
|
+
yield text
|
|
104
|
+
else:
|
|
105
|
+
async for text in self._stream_response_text(delta=False, debounce_by=debounce_by):
|
|
106
|
+
for validator in self._output_validators:
|
|
107
|
+
text = await validator.validate(text, self._run_ctx) # pragma: no cover
|
|
108
|
+
yield text
|
|
109
|
+
|
|
110
|
+
def get(self) -> _messages.ModelResponse:
|
|
111
|
+
"""Get the current state of the response."""
|
|
112
|
+
return self._raw_stream_response.get()
|
|
113
|
+
|
|
89
114
|
def usage(self) -> Usage:
|
|
90
115
|
"""Return the usage of the whole run.
|
|
91
116
|
|
|
@@ -94,10 +119,24 @@ class AgentStream(Generic[AgentDepsT, OutputDataT]):
|
|
|
94
119
|
"""
|
|
95
120
|
return self._initial_run_ctx_usage + self._raw_stream_response.usage()
|
|
96
121
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
122
|
+
def timestamp(self) -> datetime:
|
|
123
|
+
"""Get the timestamp of the response."""
|
|
124
|
+
return self._raw_stream_response.timestamp
|
|
125
|
+
|
|
126
|
+
async def get_output(self) -> OutputDataT:
|
|
127
|
+
"""Stream the whole response, validate the output and return it."""
|
|
128
|
+
async for _ in self:
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
return await self._validate_response(self._raw_stream_response.get(), allow_partial=False)
|
|
132
|
+
|
|
133
|
+
async def _validate_response(self, message: _messages.ModelResponse, *, allow_partial: bool = False) -> OutputDataT:
|
|
100
134
|
"""Validate a structured result message."""
|
|
135
|
+
if self._final_result_event is None:
|
|
136
|
+
raise exceptions.UnexpectedModelBehavior('Invalid response, unable to find output') # pragma: no cover
|
|
137
|
+
|
|
138
|
+
output_tool_name = self._final_result_event.tool_name
|
|
139
|
+
|
|
101
140
|
if isinstance(self._output_schema, ToolOutputSchema) and output_tool_name is not None:
|
|
102
141
|
tool_call = next(
|
|
103
142
|
(
|
|
@@ -114,7 +153,7 @@ class AgentStream(Generic[AgentDepsT, OutputDataT]):
|
|
|
114
153
|
return await self._tool_manager.handle_call(tool_call, allow_partial=allow_partial)
|
|
115
154
|
elif deferred_tool_calls := self._tool_manager.get_deferred_tool_calls(message.parts):
|
|
116
155
|
if not self._output_schema.allows_deferred_tool_calls:
|
|
117
|
-
raise exceptions.UserError(
|
|
156
|
+
raise exceptions.UserError(
|
|
118
157
|
'A deferred tool call was present, but `DeferredToolCalls` is not among output types. To resolve this, add `DeferredToolCalls` to the list of output types for this agent.'
|
|
119
158
|
)
|
|
120
159
|
return cast(OutputDataT, deferred_tool_calls)
|
|
@@ -132,6 +171,54 @@ class AgentStream(Generic[AgentDepsT, OutputDataT]):
|
|
|
132
171
|
'Invalid response, unable to process text output'
|
|
133
172
|
)
|
|
134
173
|
|
|
174
|
+
async def _stream_response_text(
|
|
175
|
+
self, *, delta: bool = False, debounce_by: float | None = 0.1
|
|
176
|
+
) -> AsyncIterator[str]:
|
|
177
|
+
"""Stream the response as an async iterable of text."""
|
|
178
|
+
|
|
179
|
+
# Define a "merged" version of the iterator that will yield items that have already been retrieved
|
|
180
|
+
# and items that we receive while streaming. We define a dedicated async iterator for this so we can
|
|
181
|
+
# pass the combined stream to the group_by_temporal function within `_stream_text_deltas` below.
|
|
182
|
+
async def _stream_text_deltas_ungrouped() -> AsyncIterator[tuple[str, int]]:
|
|
183
|
+
# yields tuples of (text_content, part_index)
|
|
184
|
+
# we don't currently make use of the part_index, but in principle this may be useful
|
|
185
|
+
# so we retain it here for now to make possible future refactors simpler
|
|
186
|
+
msg = self._raw_stream_response.get()
|
|
187
|
+
for i, part in enumerate(msg.parts):
|
|
188
|
+
if isinstance(part, _messages.TextPart) and part.content:
|
|
189
|
+
yield part.content, i
|
|
190
|
+
|
|
191
|
+
async for event in self._raw_stream_response:
|
|
192
|
+
if (
|
|
193
|
+
isinstance(event, _messages.PartStartEvent)
|
|
194
|
+
and isinstance(event.part, _messages.TextPart)
|
|
195
|
+
and event.part.content
|
|
196
|
+
):
|
|
197
|
+
yield event.part.content, event.index # pragma: no cover
|
|
198
|
+
elif ( # pragma: no branch
|
|
199
|
+
isinstance(event, _messages.PartDeltaEvent)
|
|
200
|
+
and isinstance(event.delta, _messages.TextPartDelta)
|
|
201
|
+
and event.delta.content_delta
|
|
202
|
+
):
|
|
203
|
+
yield event.delta.content_delta, event.index
|
|
204
|
+
|
|
205
|
+
async def _stream_text_deltas() -> AsyncIterator[str]:
|
|
206
|
+
async with _utils.group_by_temporal(_stream_text_deltas_ungrouped(), debounce_by) as group_iter:
|
|
207
|
+
async for items in group_iter:
|
|
208
|
+
# Note: we are currently just dropping the part index on the group here
|
|
209
|
+
yield ''.join([content for content, _ in items])
|
|
210
|
+
|
|
211
|
+
if delta:
|
|
212
|
+
async for text in _stream_text_deltas():
|
|
213
|
+
yield text
|
|
214
|
+
else:
|
|
215
|
+
# a quick benchmark shows it's faster to build up a string with concat when we're
|
|
216
|
+
# yielding at each step
|
|
217
|
+
deltas: list[str] = []
|
|
218
|
+
async for text in _stream_text_deltas():
|
|
219
|
+
deltas.append(text)
|
|
220
|
+
yield ''.join(deltas)
|
|
221
|
+
|
|
135
222
|
def __aiter__(self) -> AsyncIterator[AgentStreamEvent]:
|
|
136
223
|
"""Stream [`AgentStreamEvent`][pydantic_ai.messages.AgentStreamEvent]s.
|
|
137
224
|
|
|
@@ -189,16 +276,9 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
189
276
|
_all_messages: list[_messages.ModelMessage]
|
|
190
277
|
_new_message_index: int
|
|
191
278
|
|
|
192
|
-
|
|
193
|
-
_stream_response: models.StreamedResponse
|
|
194
|
-
_output_schema: OutputSchema[OutputDataT]
|
|
195
|
-
_run_ctx: RunContext[AgentDepsT]
|
|
196
|
-
_output_validators: list[OutputValidator[AgentDepsT, OutputDataT]]
|
|
197
|
-
_output_tool_name: str | None
|
|
279
|
+
_stream_response: AgentStream[AgentDepsT, OutputDataT]
|
|
198
280
|
_on_complete: Callable[[], Awaitable[None]]
|
|
199
|
-
_tool_manager: ToolManager[AgentDepsT]
|
|
200
281
|
|
|
201
|
-
_initial_run_ctx_usage: Usage = field(init=False)
|
|
202
282
|
is_complete: bool = field(default=False, init=False)
|
|
203
283
|
"""Whether the stream has all been received.
|
|
204
284
|
|
|
@@ -209,9 +289,6 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
209
289
|
[`get_output`][pydantic_ai.result.StreamedRunResult.get_output] completes.
|
|
210
290
|
"""
|
|
211
291
|
|
|
212
|
-
def __post_init__(self):
|
|
213
|
-
self._initial_run_ctx_usage = copy(self._run_ctx.usage)
|
|
214
|
-
|
|
215
292
|
@overload
|
|
216
293
|
def all_messages(self, *, output_tool_return_content: str | None = None) -> list[_messages.ModelMessage]: ...
|
|
217
294
|
|
|
@@ -332,12 +409,9 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
332
409
|
Returns:
|
|
333
410
|
An async iterable of the response data.
|
|
334
411
|
"""
|
|
335
|
-
async for
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
except ValidationError:
|
|
339
|
-
if is_last:
|
|
340
|
-
raise # pragma: no cover
|
|
412
|
+
async for output in self._stream_response.stream_output(debounce_by=debounce_by):
|
|
413
|
+
yield output
|
|
414
|
+
await self._marked_completed(self._stream_response.get())
|
|
341
415
|
|
|
342
416
|
async def stream_text(self, *, delta: bool = False, debounce_by: float | None = 0.1) -> AsyncIterator[str]:
|
|
343
417
|
"""Stream the text result as an async iterable.
|
|
@@ -352,16 +426,8 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
352
426
|
Debouncing is particularly important for long structured responses to reduce the overhead of
|
|
353
427
|
performing validation as each token is received.
|
|
354
428
|
"""
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if delta:
|
|
359
|
-
async for text in self._stream_response_text(delta=delta, debounce_by=debounce_by):
|
|
360
|
-
yield text
|
|
361
|
-
else:
|
|
362
|
-
async for text in self._stream_response_text(delta=delta, debounce_by=debounce_by):
|
|
363
|
-
combined_validated_text = await self._validate_text_output(text)
|
|
364
|
-
yield combined_validated_text
|
|
429
|
+
async for text in self._stream_response.stream_text(delta=delta, debounce_by=debounce_by):
|
|
430
|
+
yield text
|
|
365
431
|
await self._marked_completed(self._stream_response.get())
|
|
366
432
|
|
|
367
433
|
async def stream_structured(
|
|
@@ -378,13 +444,7 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
378
444
|
An async iterable of the structured response message and whether that is the last message.
|
|
379
445
|
"""
|
|
380
446
|
# if the message currently has any parts with content, yield before streaming
|
|
381
|
-
msg
|
|
382
|
-
for part in msg.parts:
|
|
383
|
-
if part.has_content():
|
|
384
|
-
yield msg, False
|
|
385
|
-
break
|
|
386
|
-
|
|
387
|
-
async for msg in self._stream_response_structured(debounce_by=debounce_by):
|
|
447
|
+
async for msg in self._stream_response.stream_responses(debounce_by=debounce_by):
|
|
388
448
|
yield msg, False
|
|
389
449
|
|
|
390
450
|
msg = self._stream_response.get()
|
|
@@ -394,15 +454,9 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
394
454
|
|
|
395
455
|
async def get_output(self) -> OutputDataT:
|
|
396
456
|
"""Stream the whole response, validate and return it."""
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
async for _ in usage_checking_stream:
|
|
402
|
-
pass
|
|
403
|
-
message = self._stream_response.get()
|
|
404
|
-
await self._marked_completed(message)
|
|
405
|
-
return await self.validate_structured_output(message)
|
|
457
|
+
output = await self._stream_response.get_output()
|
|
458
|
+
await self._marked_completed(self._stream_response.get())
|
|
459
|
+
return output
|
|
406
460
|
|
|
407
461
|
@deprecated('`get_data` is deprecated, use `get_output` instead.')
|
|
408
462
|
async def get_data(self) -> OutputDataT:
|
|
@@ -414,11 +468,11 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
414
468
|
!!! note
|
|
415
469
|
This won't return the full usage until the stream is finished.
|
|
416
470
|
"""
|
|
417
|
-
return self.
|
|
471
|
+
return self._stream_response.usage()
|
|
418
472
|
|
|
419
473
|
def timestamp(self) -> datetime:
|
|
420
474
|
"""Get the timestamp of the response."""
|
|
421
|
-
return self._stream_response.timestamp
|
|
475
|
+
return self._stream_response.timestamp()
|
|
422
476
|
|
|
423
477
|
@deprecated('`validate_structured_result` is deprecated, use `validate_structured_output` instead.')
|
|
424
478
|
async def validate_structured_result(
|
|
@@ -430,105 +484,15 @@ class StreamedRunResult(Generic[AgentDepsT, OutputDataT]):
|
|
|
430
484
|
self, message: _messages.ModelResponse, *, allow_partial: bool = False
|
|
431
485
|
) -> OutputDataT:
|
|
432
486
|
"""Validate a structured result message."""
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
part
|
|
437
|
-
for part in message.parts
|
|
438
|
-
if isinstance(part, _messages.ToolCallPart) and part.tool_name == self._output_tool_name
|
|
439
|
-
),
|
|
440
|
-
None,
|
|
441
|
-
)
|
|
442
|
-
if tool_call is None:
|
|
443
|
-
raise exceptions.UnexpectedModelBehavior( # pragma: no cover
|
|
444
|
-
f'Invalid response, unable to find tool call for {self._output_tool_name!r}'
|
|
445
|
-
)
|
|
446
|
-
return await self._tool_manager.handle_call(tool_call, allow_partial=allow_partial)
|
|
447
|
-
elif deferred_tool_calls := self._tool_manager.get_deferred_tool_calls(message.parts):
|
|
448
|
-
if not self._output_schema.allows_deferred_tool_calls:
|
|
449
|
-
raise exceptions.UserError(
|
|
450
|
-
'A deferred tool call was present, but `DeferredToolCalls` is not among output types. To resolve this, add `DeferredToolCalls` to the list of output types for this agent.'
|
|
451
|
-
)
|
|
452
|
-
return cast(OutputDataT, deferred_tool_calls)
|
|
453
|
-
elif isinstance(self._output_schema, TextOutputSchema):
|
|
454
|
-
text = '\n\n'.join(x.content for x in message.parts if isinstance(x, _messages.TextPart))
|
|
455
|
-
|
|
456
|
-
result_data = await self._output_schema.process(
|
|
457
|
-
text, self._run_ctx, allow_partial=allow_partial, wrap_validation_errors=False
|
|
458
|
-
)
|
|
459
|
-
for validator in self._output_validators:
|
|
460
|
-
result_data = await validator.validate(result_data, self._run_ctx) # pragma: no cover
|
|
461
|
-
return result_data
|
|
462
|
-
else:
|
|
463
|
-
raise exceptions.UnexpectedModelBehavior( # pragma: no cover
|
|
464
|
-
'Invalid response, unable to process text output'
|
|
465
|
-
)
|
|
466
|
-
|
|
467
|
-
async def _validate_text_output(self, text: str) -> str:
|
|
468
|
-
for validator in self._output_validators:
|
|
469
|
-
text = await validator.validate(text, self._run_ctx) # pragma: no cover
|
|
470
|
-
return text
|
|
487
|
+
return await self._stream_response._validate_response( # pyright: ignore[reportPrivateUsage]
|
|
488
|
+
message, allow_partial=allow_partial
|
|
489
|
+
)
|
|
471
490
|
|
|
472
491
|
async def _marked_completed(self, message: _messages.ModelResponse) -> None:
|
|
473
492
|
self.is_complete = True
|
|
474
493
|
self._all_messages.append(message)
|
|
475
494
|
await self._on_complete()
|
|
476
495
|
|
|
477
|
-
async def _stream_response_structured(
|
|
478
|
-
self, *, debounce_by: float | None = 0.1
|
|
479
|
-
) -> AsyncIterator[_messages.ModelResponse]:
|
|
480
|
-
async with _utils.group_by_temporal(self._stream_response, debounce_by) as group_iter:
|
|
481
|
-
async for _items in group_iter:
|
|
482
|
-
yield self._stream_response.get()
|
|
483
|
-
|
|
484
|
-
async def _stream_response_text(
|
|
485
|
-
self, *, delta: bool = False, debounce_by: float | None = 0.1
|
|
486
|
-
) -> AsyncIterator[str]:
|
|
487
|
-
"""Stream the response as an async iterable of text."""
|
|
488
|
-
|
|
489
|
-
# Define a "merged" version of the iterator that will yield items that have already been retrieved
|
|
490
|
-
# and items that we receive while streaming. We define a dedicated async iterator for this so we can
|
|
491
|
-
# pass the combined stream to the group_by_temporal function within `_stream_text_deltas` below.
|
|
492
|
-
async def _stream_text_deltas_ungrouped() -> AsyncIterator[tuple[str, int]]:
|
|
493
|
-
# yields tuples of (text_content, part_index)
|
|
494
|
-
# we don't currently make use of the part_index, but in principle this may be useful
|
|
495
|
-
# so we retain it here for now to make possible future refactors simpler
|
|
496
|
-
msg = self._stream_response.get()
|
|
497
|
-
for i, part in enumerate(msg.parts):
|
|
498
|
-
if isinstance(part, _messages.TextPart) and part.content:
|
|
499
|
-
yield part.content, i
|
|
500
|
-
|
|
501
|
-
async for event in self._stream_response:
|
|
502
|
-
if (
|
|
503
|
-
isinstance(event, _messages.PartStartEvent)
|
|
504
|
-
and isinstance(event.part, _messages.TextPart)
|
|
505
|
-
and event.part.content
|
|
506
|
-
):
|
|
507
|
-
yield event.part.content, event.index # pragma: no cover
|
|
508
|
-
elif ( # pragma: no branch
|
|
509
|
-
isinstance(event, _messages.PartDeltaEvent)
|
|
510
|
-
and isinstance(event.delta, _messages.TextPartDelta)
|
|
511
|
-
and event.delta.content_delta
|
|
512
|
-
):
|
|
513
|
-
yield event.delta.content_delta, event.index
|
|
514
|
-
|
|
515
|
-
async def _stream_text_deltas() -> AsyncIterator[str]:
|
|
516
|
-
async with _utils.group_by_temporal(_stream_text_deltas_ungrouped(), debounce_by) as group_iter:
|
|
517
|
-
async for items in group_iter:
|
|
518
|
-
# Note: we are currently just dropping the part index on the group here
|
|
519
|
-
yield ''.join([content for content, _ in items])
|
|
520
|
-
|
|
521
|
-
if delta:
|
|
522
|
-
async for text in _stream_text_deltas():
|
|
523
|
-
yield text
|
|
524
|
-
else:
|
|
525
|
-
# a quick benchmark shows it's faster to build up a string with concat when we're
|
|
526
|
-
# yielding at each step
|
|
527
|
-
deltas: list[str] = []
|
|
528
|
-
async for text in _stream_text_deltas():
|
|
529
|
-
deltas.append(text)
|
|
530
|
-
yield ''.join(deltas)
|
|
531
|
-
|
|
532
496
|
|
|
533
497
|
@dataclass(repr=False)
|
|
534
498
|
class FinalResult(Generic[OutputDataT]):
|
|
@@ -556,12 +520,12 @@ def _get_usage_checking_stream_response(
|
|
|
556
520
|
) -> AsyncIterable[_messages.ModelResponseStreamEvent]:
|
|
557
521
|
if limits is not None and limits.has_token_limits():
|
|
558
522
|
|
|
559
|
-
async def _usage_checking_iterator():
|
|
523
|
+
async def _usage_checking_iterator():
|
|
560
524
|
async for item in stream_response:
|
|
561
525
|
limits.check_tokens(get_usage())
|
|
562
526
|
yield item
|
|
563
527
|
|
|
564
|
-
return _usage_checking_iterator()
|
|
528
|
+
return _usage_checking_iterator()
|
|
565
529
|
else:
|
|
566
530
|
return stream_response
|
|
567
531
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydantic-ai-slim
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
4
4
|
Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
|
|
5
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
|
|
@@ -30,7 +30,7 @@ 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.7
|
|
34
34
|
Requires-Dist: pydantic>=2.10
|
|
35
35
|
Requires-Dist: typing-inspection>=0.4.0
|
|
36
36
|
Provides-Extra: a2a
|
|
@@ -47,23 +47,23 @@ Requires-Dist: argcomplete>=3.5.0; extra == 'cli'
|
|
|
47
47
|
Requires-Dist: prompt-toolkit>=3; extra == 'cli'
|
|
48
48
|
Requires-Dist: rich>=13; extra == 'cli'
|
|
49
49
|
Provides-Extra: cohere
|
|
50
|
-
Requires-Dist: cohere>=5.
|
|
50
|
+
Requires-Dist: cohere>=5.16.0; (platform_system != 'Emscripten') and extra == 'cohere'
|
|
51
51
|
Provides-Extra: duckduckgo
|
|
52
52
|
Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
|
|
53
53
|
Provides-Extra: evals
|
|
54
|
-
Requires-Dist: pydantic-evals==0.4.
|
|
54
|
+
Requires-Dist: pydantic-evals==0.4.7; extra == 'evals'
|
|
55
55
|
Provides-Extra: google
|
|
56
56
|
Requires-Dist: google-genai>=1.24.0; extra == 'google'
|
|
57
57
|
Provides-Extra: groq
|
|
58
58
|
Requires-Dist: groq>=0.19.0; extra == 'groq'
|
|
59
59
|
Provides-Extra: huggingface
|
|
60
|
-
Requires-Dist: huggingface-hub[inference]>=0.33.
|
|
60
|
+
Requires-Dist: huggingface-hub[inference]>=0.33.5; extra == 'huggingface'
|
|
61
61
|
Provides-Extra: logfire
|
|
62
62
|
Requires-Dist: logfire>=3.11.0; extra == 'logfire'
|
|
63
63
|
Provides-Extra: mcp
|
|
64
|
-
Requires-Dist: mcp>=1.
|
|
64
|
+
Requires-Dist: mcp>=1.10.0; (python_version >= '3.10') and extra == 'mcp'
|
|
65
65
|
Provides-Extra: mistral
|
|
66
|
-
Requires-Dist: mistralai>=1.2
|
|
66
|
+
Requires-Dist: mistralai>=1.9.2; extra == 'mistral'
|
|
67
67
|
Provides-Extra: openai
|
|
68
68
|
Requires-Dist: openai>=1.92.0; extra == 'openai'
|
|
69
69
|
Provides-Extra: tavily
|
|
@@ -3,27 +3,27 @@ pydantic_ai/__main__.py,sha256=Q_zJU15DUA01YtlJ2mnaLCoId2YmgmreVEERGuQT-Y0,132
|
|
|
3
3
|
pydantic_ai/_a2a.py,sha256=Tw_j9VRud0rLEk5kRs4GhRyhWYioXnsoZaTTyISq4M4,12126
|
|
4
4
|
pydantic_ai/_agent_graph.py,sha256=FrNq9kppV8kFVZf6t-MVGVOWUVBCXQfAinQjMh2gVWw,37192
|
|
5
5
|
pydantic_ai/_cli.py,sha256=YkiW2u9HGPd9fsgo9dpK1DZvtUPk4uXGQJcm75XgfhU,13250
|
|
6
|
-
pydantic_ai/_function_schema.py,sha256=
|
|
6
|
+
pydantic_ai/_function_schema.py,sha256=6Xuash0DVpfPF0rWQce0bhtgti8YRyk3B1-OK_n6dqs,11099
|
|
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=
|
|
9
|
+
pydantic_ai/_output.py,sha256=2k-nxfPNLJEb-wjnPhQo63lh-yQH1XsIhNG1hjsrim0,37462
|
|
10
|
+
pydantic_ai/_parts_manager.py,sha256=T4nlxaS697KeikJoqc1I9kRoIN5-_t5TEv-ovpMlzZg,17856
|
|
11
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
14
|
pydantic_ai/_tool_manager.py,sha256=ptVj2oJm7Qm5MlDQHDNj8BPIEPY0HfkrzqeeD_ZuVbQ,8180
|
|
15
15
|
pydantic_ai/_utils.py,sha256=0Pte4mjir4YFZJTa6i-H6Cra9NbVwSKjOKegArzUggk,16283
|
|
16
|
-
pydantic_ai/ag_ui.py,sha256=
|
|
17
|
-
pydantic_ai/agent.py,sha256=
|
|
16
|
+
pydantic_ai/ag_ui.py,sha256=CLb20Z6qDHM7XlKIvQ6oTM6gXdk2KX8wp_q3YLrH06U,25411
|
|
17
|
+
pydantic_ai/agent.py,sha256=z_-UizrEOPyPGyWn28NzgR_74bvn0W0qxeyMT9rlPok,106458
|
|
18
18
|
pydantic_ai/direct.py,sha256=WRfgke3zm-eeR39LTuh9XI2TrdHXAqO81eDvFwih4Ko,14803
|
|
19
19
|
pydantic_ai/exceptions.py,sha256=o0l6fBrWI5UhosICVZ2yaT-JEJF05eqBlKlQCW8i9UM,3462
|
|
20
20
|
pydantic_ai/format_as_xml.py,sha256=IINfh1evWDphGahqHNLBArB5dQ4NIqS3S-kru35ztGg,372
|
|
21
21
|
pydantic_ai/format_prompt.py,sha256=Or-Ytq55RQb1UJqy2HKIyPpZ-knWXfdDP3Z6tNc6Orw,4244
|
|
22
|
-
pydantic_ai/mcp.py,sha256=
|
|
23
|
-
pydantic_ai/messages.py,sha256=
|
|
22
|
+
pydantic_ai/mcp.py,sha256=M56YBCapVbSt-CeJAWaYW3PGHmr1DRtCW8r6yBK1CUU,26173
|
|
23
|
+
pydantic_ai/messages.py,sha256=CX-E9_s_Kxqx2eEGrUVZsAqZyGm9rNQ2Cq9LzbvofZ8,42293
|
|
24
24
|
pydantic_ai/output.py,sha256=54Cwd1RruXlA5hucZ1h-SxFrzKHJuLvYvLtH9iyg2GI,11988
|
|
25
25
|
pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
pydantic_ai/result.py,sha256=
|
|
26
|
+
pydantic_ai/result.py,sha256=6RYFUGMC_YXJ_v57DFc0swVFkYEmJxByBw5J3aWtXfw,25310
|
|
27
27
|
pydantic_ai/settings.py,sha256=yuUZ7-GkdPB-Gbx71kSdh8dSr6gwM9gEwk84qNxPO_I,3552
|
|
28
28
|
pydantic_ai/tools.py,sha256=PQm1yWbocdrhyLdMf_J8dJMTRJTWzyS2BEF24t4jgqw,14205
|
|
29
29
|
pydantic_ai/usage.py,sha256=ceC9HHflyM_rkLBJqtaWPc-M8bEoq5rZF4XwGblPQoU,5830
|
|
@@ -33,21 +33,21 @@ pydantic_ai/common_tools/tavily.py,sha256=Q1xxSF5HtXAaZ10Pp-OaDOHXwJf2mco9wScGEQ
|
|
|
33
33
|
pydantic_ai/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
pydantic_ai/ext/aci.py,sha256=vUaNIj6pRM52x6RkPW_DohSYxJPm75pPUfOMw2i5Xx0,2515
|
|
35
35
|
pydantic_ai/ext/langchain.py,sha256=GemxfhpyG1JPxj69PbRiSJANnY8Q5s4hSB7wqt-uTbo,2266
|
|
36
|
-
pydantic_ai/models/__init__.py,sha256=
|
|
37
|
-
pydantic_ai/models/anthropic.py,sha256=
|
|
38
|
-
pydantic_ai/models/bedrock.py,sha256=
|
|
39
|
-
pydantic_ai/models/cohere.py,sha256=
|
|
36
|
+
pydantic_ai/models/__init__.py,sha256=GZ2YE5qcqI8tNpovlO0_6Ryx92bo8sQTsLmRKiYnSU4,30912
|
|
37
|
+
pydantic_ai/models/anthropic.py,sha256=dMPFqIeYCIhoeU_4uk9PmZYQWL1NbkSVmVrBKXplTiI,24167
|
|
38
|
+
pydantic_ai/models/bedrock.py,sha256=O6wKZDu4L18L1L2Nsa-XMW4ch073FjcLKRA5t_NXcHU,29511
|
|
39
|
+
pydantic_ai/models/cohere.py,sha256=lKUXEPqTMqxIJfouDj-Fr1bnfkrPu-JK3Xth7CL03kU,12800
|
|
40
40
|
pydantic_ai/models/fallback.py,sha256=URaV-dTQWkg99xrlkmknue5lXZWDcEt7cJ1Vsky4oB4,5130
|
|
41
|
-
pydantic_ai/models/function.py,sha256=
|
|
42
|
-
pydantic_ai/models/gemini.py,sha256=
|
|
43
|
-
pydantic_ai/models/google.py,sha256=
|
|
44
|
-
pydantic_ai/models/groq.py,sha256=
|
|
45
|
-
pydantic_ai/models/huggingface.py,sha256=
|
|
41
|
+
pydantic_ai/models/function.py,sha256=iHhG6GYN14XDo3_qbdliv_umY10B7-k11aoDoVF4xP8,13563
|
|
42
|
+
pydantic_ai/models/gemini.py,sha256=BMFEiDJXbB0DPj5DKK4kCwXuQHifT2WU-WuthJOqPsI,38138
|
|
43
|
+
pydantic_ai/models/google.py,sha256=NNcr2jJlK3eFlSRyaTgDPuSjG2GxOOj0vYDrAfD6rbo,24394
|
|
44
|
+
pydantic_ai/models/groq.py,sha256=8-sh8h2sJNZE6TiNUoiTKjmWghtCncxa3BX_xN979XQ,18854
|
|
45
|
+
pydantic_ai/models/huggingface.py,sha256=06Rh0Q-p_2LPuny5RIooMx-NWD1rbbhLWP2wL4E6aq0,19019
|
|
46
46
|
pydantic_ai/models/instrumented.py,sha256=aqvzspcGexn1Molbu6Mn4EEPRBSoQCCCS_yknJvJJ-8,16205
|
|
47
47
|
pydantic_ai/models/mcp_sampling.py,sha256=q9nnjNEAAbhrfRc_Qw5z9TtCHMG_SwlCWW9FvKWjh8k,3395
|
|
48
|
-
pydantic_ai/models/mistral.py,sha256=
|
|
49
|
-
pydantic_ai/models/openai.py,sha256=
|
|
50
|
-
pydantic_ai/models/test.py,sha256=
|
|
48
|
+
pydantic_ai/models/mistral.py,sha256=u3LcPVqvdI2WHckffbj7zRT5oQn9yYdTRbtEN20Gqpw,31427
|
|
49
|
+
pydantic_ai/models/openai.py,sha256=CJC5nU-b8HeKSa_4EbvTG_cmRjEnBjpoVbdfg_4ttyA,55834
|
|
50
|
+
pydantic_ai/models/test.py,sha256=tkm6K0-G5Mc_iSqVzVIpU9VLil9dfkE1-5az8GGWwTI,18457
|
|
51
51
|
pydantic_ai/models/wrapper.py,sha256=A5-ncYhPF8c9S_czGoXkd55s2KOQb65p3jbVpwZiFPA,2043
|
|
52
52
|
pydantic_ai/profiles/__init__.py,sha256=BXMqUpgRfosmYgcxjKAI9ESCj47JTSa30DhKXEgVLzM,2419
|
|
53
53
|
pydantic_ai/profiles/_json_schema.py,sha256=sTNHkaK0kbwmbldZp9JRGQNax0f5Qvwy0HkWuu_nGxU,7179
|
|
@@ -60,9 +60,9 @@ pydantic_ai/profiles/grok.py,sha256=nBOxOCYCK9aiLmz2Q-esqYhotNbbBC1boAoOYIk1tVw,
|
|
|
60
60
|
pydantic_ai/profiles/meta.py,sha256=IAGPoUrLWd-g9ajAgpWp9fIeOrP-7dBlZ2HEFjIhUbY,334
|
|
61
61
|
pydantic_ai/profiles/mistral.py,sha256=ll01PmcK3szwlTfbaJLQmfd0TADN8lqjov9HpPJzCMQ,217
|
|
62
62
|
pydantic_ai/profiles/moonshotai.py,sha256=LL5RacKHKn6rdvhoKjpGgZ8aVriv5NMeL6HCWEANAiU,223
|
|
63
|
-
pydantic_ai/profiles/openai.py,sha256=
|
|
63
|
+
pydantic_ai/profiles/openai.py,sha256=2s1DILf4fetSA5e0vUpB-KbNp-nCfSFqlJslbxXLCA8,7157
|
|
64
64
|
pydantic_ai/profiles/qwen.py,sha256=u7pL8uomoQTVl45g5wDrHx0P_oFDLaN6ALswuwmkWc0,334
|
|
65
|
-
pydantic_ai/providers/__init__.py,sha256=
|
|
65
|
+
pydantic_ai/providers/__init__.py,sha256=6Jm4ioGiI5jcwKUC2Yxv-GHdrK3ZTJmb-9_eHBZgfdw,4005
|
|
66
66
|
pydantic_ai/providers/anthropic.py,sha256=D35UXxCPXv8yIbD0fj9Zg2FvNyoMoJMeDUtVM8Sn78I,3046
|
|
67
67
|
pydantic_ai/providers/azure.py,sha256=y77IHGiSQ9Ttx9f4SGMgdpin2Daq6eYyzUdM9ET22RQ,5819
|
|
68
68
|
pydantic_ai/providers/bedrock.py,sha256=ycdTXnkj_WNqPMA7DNDPeYia0C37FP0_l0CygSQmWYI,5694
|
|
@@ -78,9 +78,11 @@ pydantic_ai/providers/groq.py,sha256=hqcR-RFHHHeemYP3K16IFeQTJKywNEU2wNZOSGTz6fE
|
|
|
78
78
|
pydantic_ai/providers/heroku.py,sha256=NmDIkAdxtWsvCjlX-bKI5FgI4HW1zO9-e0mrNQNGMCk,2990
|
|
79
79
|
pydantic_ai/providers/huggingface.py,sha256=LRmJcJpQRRYvam3IAPkYs2fMUJf70GgE3aDgQltGRCU,3821
|
|
80
80
|
pydantic_ai/providers/mistral.py,sha256=EIUSENjFuGzBhvbdrarUTM4VPkesIMnZrzfnEKHOsc4,3120
|
|
81
|
+
pydantic_ai/providers/moonshotai.py,sha256=3BAE9eC9QaD3kblVwxtQWEln0-PhgK7bRvrYTCEYXbY,3471
|
|
81
82
|
pydantic_ai/providers/openai.py,sha256=7iGij0EaFylab7dTZAZDgXr78tr-HsZrn9EI9AkWBNQ,3091
|
|
82
83
|
pydantic_ai/providers/openrouter.py,sha256=NXjNdnlXIBrBMMqbzcWQnowXOuZh4NHikXenBn5h3mc,4061
|
|
83
84
|
pydantic_ai/providers/together.py,sha256=zFVSMSm5jXbpkNouvBOTjWrPmlPpCp6sQS5LMSyVjrQ,3482
|
|
85
|
+
pydantic_ai/providers/vercel.py,sha256=JM1NmqLR64RvEmVWI8t2zGQdxOHJ-CguibOI0uSv-_Q,4061
|
|
84
86
|
pydantic_ai/toolsets/__init__.py,sha256=JCnqqAFeuHhmVW4XK0LM6Op_9B1cvsQUJ3vTmQ9Z5cQ,590
|
|
85
87
|
pydantic_ai/toolsets/abstract.py,sha256=LqunlpwUsoHVn4VMtdjEoLY5kiMUF74PZ4KW539K8tQ,6027
|
|
86
88
|
pydantic_ai/toolsets/combined.py,sha256=bmhQqxq4WQz_55a_cMsUfcCK6ggF74QEPoa12w34MOU,3371
|
|
@@ -91,8 +93,8 @@ pydantic_ai/toolsets/prefixed.py,sha256=MIStkzUdiU0rk2Y6P19IrTBxspH5pTstGxsqCBt-
|
|
|
91
93
|
pydantic_ai/toolsets/prepared.py,sha256=Zjfz6S8In6PBVxoKFN9sKPN984zO6t0awB7Lnq5KODw,1431
|
|
92
94
|
pydantic_ai/toolsets/renamed.py,sha256=JuLHpi-hYPiSPlaTpN8WiXLiGsywYK0axi2lW2Qs75k,1637
|
|
93
95
|
pydantic_ai/toolsets/wrapper.py,sha256=WjLoiM1WDuffSJ4mDS6pZrEZGHgZ421fjrqFcB66W94,1205
|
|
94
|
-
pydantic_ai_slim-0.4.
|
|
95
|
-
pydantic_ai_slim-0.4.
|
|
96
|
-
pydantic_ai_slim-0.4.
|
|
97
|
-
pydantic_ai_slim-0.4.
|
|
98
|
-
pydantic_ai_slim-0.4.
|
|
96
|
+
pydantic_ai_slim-0.4.7.dist-info/METADATA,sha256=oDZht-6JBIAuL2foZZ1lOSe9JGN5hahwYlXqMBoM8DY,4098
|
|
97
|
+
pydantic_ai_slim-0.4.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
98
|
+
pydantic_ai_slim-0.4.7.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
|
|
99
|
+
pydantic_ai_slim-0.4.7.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
|
|
100
|
+
pydantic_ai_slim-0.4.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|