pydantic-ai-slim 0.4.6__py3-none-any.whl → 0.4.8__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.
@@ -0,0 +1,97 @@
1
+ from __future__ import annotations as _annotations
2
+
3
+ import os
4
+ from typing import Literal, overload
5
+
6
+ from httpx import AsyncClient as AsyncHTTPClient
7
+ from openai import AsyncOpenAI
8
+
9
+ from pydantic_ai.exceptions import UserError
10
+ from pydantic_ai.models import cached_async_http_client
11
+ from pydantic_ai.profiles import ModelProfile
12
+ from pydantic_ai.profiles.moonshotai import moonshotai_model_profile
13
+ from pydantic_ai.profiles.openai import (
14
+ OpenAIJsonSchemaTransformer,
15
+ OpenAIModelProfile,
16
+ )
17
+ from pydantic_ai.providers import Provider
18
+
19
+ MoonshotAIModelName = Literal[
20
+ 'moonshot-v1-8k',
21
+ 'moonshot-v1-32k',
22
+ 'moonshot-v1-128k',
23
+ 'moonshot-v1-8k-vision-preview',
24
+ 'moonshot-v1-32k-vision-preview',
25
+ 'moonshot-v1-128k-vision-preview',
26
+ 'kimi-latest',
27
+ 'kimi-thinking-preview',
28
+ 'kimi-k2-0711-preview',
29
+ ]
30
+
31
+
32
+ class MoonshotAIProvider(Provider[AsyncOpenAI]):
33
+ """Provider for MoonshotAI platform (Kimi models)."""
34
+
35
+ @property
36
+ def name(self) -> str:
37
+ return 'moonshotai'
38
+
39
+ @property
40
+ def base_url(self) -> str:
41
+ # OpenAI-compatible endpoint, see MoonshotAI docs
42
+ return 'https://api.moonshot.ai/v1'
43
+
44
+ @property
45
+ def client(self) -> AsyncOpenAI:
46
+ return self._client
47
+
48
+ def model_profile(self, model_name: str) -> ModelProfile | None:
49
+ profile = moonshotai_model_profile(model_name)
50
+
51
+ # As the MoonshotAI API is OpenAI-compatible, let's assume we also need OpenAIJsonSchemaTransformer,
52
+ # unless json_schema_transformer is set explicitly.
53
+ # Also, MoonshotAI does not support strict tool definitions
54
+ # https://platform.moonshot.ai/docs/guide/migrating-from-openai-to-kimi#about-tool_choice
55
+ # "Please note that the current version of Kimi API does not support the tool_choice=required parameter."
56
+ return OpenAIModelProfile(
57
+ json_schema_transformer=OpenAIJsonSchemaTransformer,
58
+ openai_supports_tool_choice_required=False,
59
+ supports_json_object_output=True,
60
+ ).update(profile)
61
+
62
+ # ---------------------------------------------------------------------
63
+ # Construction helpers
64
+ # ---------------------------------------------------------------------
65
+ @overload
66
+ def __init__(self) -> None: ...
67
+
68
+ @overload
69
+ def __init__(self, *, api_key: str) -> None: ...
70
+
71
+ @overload
72
+ def __init__(self, *, api_key: str, http_client: AsyncHTTPClient) -> None: ...
73
+
74
+ @overload
75
+ def __init__(self, *, openai_client: AsyncOpenAI | None = None) -> None: ...
76
+
77
+ def __init__(
78
+ self,
79
+ *,
80
+ api_key: str | None = None,
81
+ openai_client: AsyncOpenAI | None = None,
82
+ http_client: AsyncHTTPClient | None = None,
83
+ ) -> None:
84
+ api_key = api_key or os.getenv('MOONSHOTAI_API_KEY')
85
+ if not api_key and openai_client is None:
86
+ raise UserError(
87
+ 'Set the `MOONSHOTAI_API_KEY` environment variable or pass it via '
88
+ '`MoonshotAIProvider(api_key=...)` to use the MoonshotAI provider.'
89
+ )
90
+
91
+ if openai_client is not None:
92
+ self._client = openai_client
93
+ elif http_client is not None:
94
+ self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
95
+ else:
96
+ http_client = cached_async_http_client(provider='moonshotai')
97
+ self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations as _annotations
2
+
3
+ import os
4
+ from typing import overload
5
+
6
+ from httpx import AsyncClient as AsyncHTTPClient
7
+
8
+ from pydantic_ai.exceptions import UserError
9
+ from pydantic_ai.models import cached_async_http_client
10
+ from pydantic_ai.profiles import ModelProfile
11
+ from pydantic_ai.profiles.amazon import amazon_model_profile
12
+ from pydantic_ai.profiles.anthropic import anthropic_model_profile
13
+ from pydantic_ai.profiles.cohere import cohere_model_profile
14
+ from pydantic_ai.profiles.deepseek import deepseek_model_profile
15
+ from pydantic_ai.profiles.google import google_model_profile
16
+ from pydantic_ai.profiles.grok import grok_model_profile
17
+ from pydantic_ai.profiles.mistral import mistral_model_profile
18
+ from pydantic_ai.profiles.openai import OpenAIJsonSchemaTransformer, OpenAIModelProfile, openai_model_profile
19
+ from pydantic_ai.providers import Provider
20
+
21
+ try:
22
+ from openai import AsyncOpenAI
23
+ except ImportError as _import_error: # pragma: no cover
24
+ raise ImportError(
25
+ 'Please install the `openai` package to use the Vercel provider, '
26
+ 'you can use the `openai` optional group — `pip install "pydantic-ai-slim[openai]"`'
27
+ ) from _import_error
28
+
29
+
30
+ class VercelProvider(Provider[AsyncOpenAI]):
31
+ """Provider for Vercel AI Gateway API."""
32
+
33
+ @property
34
+ def name(self) -> str:
35
+ return 'vercel'
36
+
37
+ @property
38
+ def base_url(self) -> str:
39
+ return 'https://ai-gateway.vercel.sh/v1'
40
+
41
+ @property
42
+ def client(self) -> AsyncOpenAI:
43
+ return self._client
44
+
45
+ def model_profile(self, model_name: str) -> ModelProfile | None:
46
+ provider_to_profile = {
47
+ 'anthropic': anthropic_model_profile,
48
+ 'bedrock': amazon_model_profile,
49
+ 'cohere': cohere_model_profile,
50
+ 'deepseek': deepseek_model_profile,
51
+ 'mistral': mistral_model_profile,
52
+ 'openai': openai_model_profile,
53
+ 'vertex': google_model_profile,
54
+ 'xai': grok_model_profile,
55
+ }
56
+
57
+ profile = None
58
+
59
+ try:
60
+ provider, model_name = model_name.split('/', 1)
61
+ except ValueError:
62
+ raise UserError(f"Model name must be in 'provider/model' format, got: {model_name!r}")
63
+
64
+ if provider in provider_to_profile:
65
+ profile = provider_to_profile[provider](model_name)
66
+
67
+ # As VercelProvider is always used with OpenAIModel, which used to unconditionally use OpenAIJsonSchemaTransformer,
68
+ # we need to maintain that behavior unless json_schema_transformer is set explicitly
69
+ return OpenAIModelProfile(
70
+ json_schema_transformer=OpenAIJsonSchemaTransformer,
71
+ ).update(profile)
72
+
73
+ @overload
74
+ def __init__(self) -> None: ...
75
+
76
+ @overload
77
+ def __init__(self, *, api_key: str) -> None: ...
78
+
79
+ @overload
80
+ def __init__(self, *, api_key: str, http_client: AsyncHTTPClient) -> None: ...
81
+
82
+ @overload
83
+ def __init__(self, *, openai_client: AsyncOpenAI | None = None) -> None: ...
84
+
85
+ def __init__(
86
+ self,
87
+ *,
88
+ api_key: str | None = None,
89
+ openai_client: AsyncOpenAI | None = None,
90
+ http_client: AsyncHTTPClient | None = None,
91
+ ) -> None:
92
+ # Support Vercel AI Gateway's standard environment variables
93
+ api_key = api_key or os.getenv('VERCEL_AI_GATEWAY_API_KEY') or os.getenv('VERCEL_OIDC_TOKEN')
94
+
95
+ if not api_key and openai_client is None:
96
+ raise UserError(
97
+ 'Set the `VERCEL_AI_GATEWAY_API_KEY` or `VERCEL_OIDC_TOKEN` environment variable '
98
+ 'or pass the API key via `VercelProvider(api_key=...)` to use the Vercel provider.'
99
+ )
100
+
101
+ if openai_client is not None:
102
+ self._client = openai_client
103
+ elif http_client is not None:
104
+ self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
105
+ else:
106
+ http_client = cached_async_http_client(provider='vercel')
107
+ self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
pydantic_ai/retries.py ADDED
@@ -0,0 +1,249 @@
1
+ """Retries utilities based on tenacity, especially for HTTP requests.
2
+
3
+ This module provides HTTP transport wrappers and wait strategies that integrate with
4
+ the tenacity library to add retry capabilities to HTTP requests. The transports can be
5
+ used with HTTP clients that support custom transports (such as httpx), while the wait
6
+ strategies can be used with any tenacity retry decorator.
7
+
8
+ The module includes:
9
+ - TenacityTransport: Synchronous HTTP transport with retry capabilities
10
+ - AsyncTenacityTransport: Asynchronous HTTP transport with retry capabilities
11
+ - wait_retry_after: Wait strategy that respects HTTP Retry-After headers
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from httpx import AsyncBaseTransport, AsyncHTTPTransport, BaseTransport, HTTPTransport, Request, Response
17
+
18
+ try:
19
+ from tenacity import AsyncRetrying, Retrying
20
+ except ImportError as _import_error:
21
+ raise ImportError(
22
+ 'Please install `tenacity` to use the retries utilities, '
23
+ 'you can use the `retries` optional group — `pip install "pydantic-ai-slim[retries]"`'
24
+ ) from _import_error
25
+
26
+
27
+ __all__ = ['TenacityTransport', 'AsyncTenacityTransport', 'wait_retry_after']
28
+
29
+ from datetime import datetime, timezone
30
+ from email.utils import parsedate_to_datetime
31
+ from typing import Callable, cast
32
+
33
+ from httpx import HTTPStatusError
34
+ from tenacity import RetryCallState, wait_exponential
35
+
36
+
37
+ class TenacityTransport(BaseTransport):
38
+ """Synchronous HTTP transport with tenacity-based retry functionality.
39
+
40
+ This transport wraps another BaseTransport and adds retry capabilities using the tenacity library.
41
+ It can be configured to retry requests based on various conditions such as specific exception types,
42
+ response status codes, or custom validation logic.
43
+
44
+ The transport works by intercepting HTTP requests and responses, allowing the tenacity controller
45
+ to determine when and how to retry failed requests. The validate_response function can be used
46
+ to convert HTTP responses into exceptions that trigger retries.
47
+
48
+ Args:
49
+ wrapped: The underlying transport to wrap and add retry functionality to.
50
+ controller: The tenacity Retrying instance that defines the retry behavior
51
+ (retry conditions, wait strategy, stop conditions, etc.).
52
+ validate_response: Optional callable that takes a Response and can raise an exception
53
+ to be handled by the controller if the response should trigger a retry.
54
+ Common use case is to raise exceptions for certain HTTP status codes.
55
+ If None, no response validation is performed.
56
+
57
+ Example:
58
+ ```python
59
+ from httpx import Client, HTTPTransport, HTTPStatusError
60
+ from tenacity import Retrying, stop_after_attempt, retry_if_exception_type
61
+ from pydantic_ai.retries import TenacityTransport, wait_retry_after
62
+
63
+ transport = TenacityTransport(
64
+ HTTPTransport(),
65
+ Retrying(
66
+ retry=retry_if_exception_type(HTTPStatusError),
67
+ wait=wait_retry_after(max_wait=300),
68
+ stop=stop_after_attempt(5),
69
+ reraise=True
70
+ ),
71
+ validate_response=lambda r: r.raise_for_status()
72
+ )
73
+ client = Client(transport=transport)
74
+ ```
75
+ """
76
+
77
+ def __init__(
78
+ self,
79
+ controller: Retrying,
80
+ wrapped: BaseTransport | None = None,
81
+ validate_response: Callable[[Response], None] | None = None,
82
+ ):
83
+ self.controller = controller
84
+ self.wrapped = wrapped or HTTPTransport()
85
+ self.validate_response = validate_response
86
+
87
+ def handle_request(self, request: Request) -> Response:
88
+ """Handle an HTTP request with retry logic.
89
+
90
+ Args:
91
+ request: The HTTP request to handle.
92
+
93
+ Returns:
94
+ The HTTP response.
95
+
96
+ Raises:
97
+ RuntimeError: If the retry controller did not make any attempts.
98
+ Exception: Any exception raised by the wrapped transport or validation function.
99
+ """
100
+ for attempt in self.controller:
101
+ with attempt:
102
+ response = self.wrapped.handle_request(request)
103
+ if self.validate_response:
104
+ self.validate_response(response)
105
+ return response
106
+ raise RuntimeError('The retry controller did not make any attempts') # pragma: no cover
107
+
108
+
109
+ class AsyncTenacityTransport(AsyncBaseTransport):
110
+ """Asynchronous HTTP transport with tenacity-based retry functionality.
111
+
112
+ This transport wraps another AsyncBaseTransport and adds retry capabilities using the tenacity library.
113
+ It can be configured to retry requests based on various conditions such as specific exception types,
114
+ response status codes, or custom validation logic.
115
+
116
+ The transport works by intercepting HTTP requests and responses, allowing the tenacity controller
117
+ to determine when and how to retry failed requests. The validate_response function can be used
118
+ to convert HTTP responses into exceptions that trigger retries.
119
+
120
+ Args:
121
+ wrapped: The underlying async transport to wrap and add retry functionality to.
122
+ controller: The tenacity AsyncRetrying instance that defines the retry behavior
123
+ (retry conditions, wait strategy, stop conditions, etc.).
124
+ validate_response: Optional callable that takes a Response and can raise an exception
125
+ to be handled by the controller if the response should trigger a retry.
126
+ Common use case is to raise exceptions for certain HTTP status codes.
127
+ If None, no response validation is performed.
128
+
129
+ Example:
130
+ ```python
131
+ from httpx import AsyncClient, HTTPStatusError
132
+ from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
133
+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
134
+
135
+ transport = AsyncTenacityTransport(
136
+ AsyncRetrying(
137
+ retry=retry_if_exception_type(HTTPStatusError),
138
+ wait=wait_retry_after(max_wait=300),
139
+ stop=stop_after_attempt(5),
140
+ reraise=True
141
+ ),
142
+ validate_response=lambda r: r.raise_for_status()
143
+ )
144
+ client = AsyncClient(transport=transport)
145
+ ```
146
+ """
147
+
148
+ def __init__(
149
+ self,
150
+ controller: AsyncRetrying,
151
+ wrapped: AsyncBaseTransport | None = None,
152
+ validate_response: Callable[[Response], None] | None = None,
153
+ ):
154
+ self.controller = controller
155
+ self.wrapped = wrapped or AsyncHTTPTransport()
156
+ self.validate_response = validate_response
157
+
158
+ async def handle_async_request(self, request: Request) -> Response:
159
+ """Handle an async HTTP request with retry logic.
160
+
161
+ Args:
162
+ request: The HTTP request to handle.
163
+
164
+ Returns:
165
+ The HTTP response.
166
+
167
+ Raises:
168
+ RuntimeError: If the retry controller did not make any attempts.
169
+ Exception: Any exception raised by the wrapped transport or validation function.
170
+ """
171
+ async for attempt in self.controller:
172
+ with attempt:
173
+ response = await self.wrapped.handle_async_request(request)
174
+ if self.validate_response:
175
+ self.validate_response(response)
176
+ return response
177
+ raise RuntimeError('The retry controller did not make any attempts') # pragma: no cover
178
+
179
+
180
+ def wait_retry_after(
181
+ fallback_strategy: Callable[[RetryCallState], float] | None = None, max_wait: float = 300
182
+ ) -> Callable[[RetryCallState], float]:
183
+ """Create a tenacity-compatible wait strategy that respects HTTP Retry-After headers.
184
+
185
+ This wait strategy checks if the exception contains an HTTPStatusError with a
186
+ Retry-After header, and if so, waits for the time specified in the header.
187
+ If no header is present or parsing fails, it falls back to the provided strategy.
188
+
189
+ The Retry-After header can be in two formats:
190
+ - An integer representing seconds to wait
191
+ - An HTTP date string representing when to retry
192
+
193
+ Args:
194
+ fallback_strategy: Wait strategy to use when no Retry-After header is present
195
+ or parsing fails. Defaults to exponential backoff with max 60s.
196
+ max_wait: Maximum time to wait in seconds, regardless of header value.
197
+ Defaults to 300 (5 minutes).
198
+
199
+ Returns:
200
+ A wait function that can be used with tenacity retry decorators.
201
+
202
+ Example:
203
+ ```python
204
+ from httpx import AsyncClient, HTTPStatusError
205
+ from tenacity import AsyncRetrying, stop_after_attempt, retry_if_exception_type
206
+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
207
+
208
+ transport = AsyncTenacityTransport(
209
+ AsyncRetrying(
210
+ retry=retry_if_exception_type(HTTPStatusError),
211
+ wait=wait_retry_after(max_wait=120),
212
+ stop=stop_after_attempt(5),
213
+ reraise=True
214
+ ),
215
+ validate_response=lambda r: r.raise_for_status()
216
+ )
217
+ client = AsyncClient(transport=transport)
218
+ ```
219
+ """
220
+ if fallback_strategy is None:
221
+ fallback_strategy = wait_exponential(multiplier=1, max=60)
222
+
223
+ def wait_func(state: RetryCallState) -> float:
224
+ exc = state.outcome.exception() if state.outcome else None
225
+ if isinstance(exc, HTTPStatusError):
226
+ retry_after = exc.response.headers.get('retry-after')
227
+ if retry_after:
228
+ try:
229
+ # Try parsing as seconds first
230
+ wait_seconds = int(retry_after)
231
+ return min(float(wait_seconds), max_wait)
232
+ except ValueError:
233
+ # Try parsing as HTTP date
234
+ try:
235
+ retry_time = cast(datetime, parsedate_to_datetime(retry_after))
236
+ assert isinstance(retry_time, datetime)
237
+ now = datetime.now(timezone.utc)
238
+ wait_seconds = (retry_time - now).total_seconds()
239
+
240
+ if wait_seconds > 0:
241
+ return min(wait_seconds, max_wait)
242
+ except (ValueError, TypeError, AssertionError):
243
+ # If date parsing fails, fall back to fallback strategy
244
+ pass
245
+
246
+ # Use fallback strategy
247
+ return fallback_strategy(state)
248
+
249
+ return wait_func
@@ -43,9 +43,10 @@ class CombinedToolset(AbstractToolset[AgentDepsT]):
43
43
  async def __aenter__(self) -> Self:
44
44
  async with self._enter_lock:
45
45
  if self._entered_count == 0:
46
- self._exit_stack = AsyncExitStack()
47
- for toolset in self.toolsets:
48
- await self._exit_stack.enter_async_context(toolset)
46
+ async with AsyncExitStack() as exit_stack:
47
+ for toolset in self.toolsets:
48
+ await exit_stack.enter_async_context(toolset)
49
+ self._exit_stack = exit_stack.pop_all()
49
50
  self._entered_count += 1
50
51
  return self
51
52
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.4.6
3
+ Version: 0.4.8
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.6
33
+ Requires-Dist: pydantic-graph==0.4.8
34
34
  Requires-Dist: pydantic>=2.10
35
35
  Requires-Dist: typing-inspection>=0.4.0
36
36
  Provides-Extra: a2a
@@ -47,25 +47,28 @@ 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.13.11; (platform_system != 'Emscripten') and extra == 'cohere'
50
+ Requires-Dist: cohere>=5.16.0; (platform_system != 'Emscripten') and extra == 'cohere'
51
+ Requires-Dist: tokenizers<=0.21.2; extra == 'cohere'
51
52
  Provides-Extra: duckduckgo
52
53
  Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
53
54
  Provides-Extra: evals
54
- Requires-Dist: pydantic-evals==0.4.6; extra == 'evals'
55
+ Requires-Dist: pydantic-evals==0.4.8; extra == 'evals'
55
56
  Provides-Extra: google
56
57
  Requires-Dist: google-genai>=1.24.0; extra == 'google'
57
58
  Provides-Extra: groq
58
59
  Requires-Dist: groq>=0.19.0; extra == 'groq'
59
60
  Provides-Extra: huggingface
60
- Requires-Dist: huggingface-hub[inference]>=0.33.2; extra == 'huggingface'
61
+ Requires-Dist: huggingface-hub[inference]>=0.33.5; extra == 'huggingface'
61
62
  Provides-Extra: logfire
62
63
  Requires-Dist: logfire>=3.11.0; extra == 'logfire'
63
64
  Provides-Extra: mcp
64
- Requires-Dist: mcp>=1.9.4; (python_version >= '3.10') and extra == 'mcp'
65
+ Requires-Dist: mcp>=1.10.0; (python_version >= '3.10') and extra == 'mcp'
65
66
  Provides-Extra: mistral
66
67
  Requires-Dist: mistralai>=1.9.2; extra == 'mistral'
67
68
  Provides-Extra: openai
68
69
  Requires-Dist: openai>=1.92.0; extra == 'openai'
70
+ Provides-Extra: retries
71
+ Requires-Dist: tenacity>=8.2.3; extra == 'retries'
69
72
  Provides-Extra: tavily
70
73
  Requires-Dist: tavily-python>=0.5.0; extra == 'tavily'
71
74
  Provides-Extra: vertexai
@@ -7,23 +7,24 @@ pydantic_ai/_function_schema.py,sha256=6Xuash0DVpfPF0rWQce0bhtgti8YRyk3B1-OK_n6d
7
7
  pydantic_ai/_griffe.py,sha256=Ugft16ZHw9CN_6-lW0Svn6jESK9zHXO_x4utkGBkbBI,5253
8
8
  pydantic_ai/_mcp.py,sha256=PuvwnlLjv7YYOa9AZJCrklevBug99zGMhwJCBGG7BHQ,5626
9
9
  pydantic_ai/_output.py,sha256=2k-nxfPNLJEb-wjnPhQo63lh-yQH1XsIhNG1hjsrim0,37462
10
- pydantic_ai/_parts_manager.py,sha256=CGm_fovTrFNQ3H8s9-edSBuG8Jzqrgw5TqRnPlzPyr4,16184
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=b1Uqc0bGcFCn71hl04gcX_W80lQugueEm-0m--fde2s,25758
17
- pydantic_ai/agent.py,sha256=z_-UizrEOPyPGyWn28NzgR_74bvn0W0qxeyMT9rlPok,106458
16
+ pydantic_ai/ag_ui.py,sha256=KW9B8ZrG2IgOGdsTcDbprSOGV3jIC-nWxf-gYBRHJzg,25411
17
+ pydantic_ai/agent.py,sha256=IaO8MQapAKwDTyMCdufLZM5dDsPnNBBiQ5JA-CCFHW8,106528
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=3YvQmTGpWC4stG9CthYCWnEE7XXIGuc2Xtfw4Yiya8c,23817
23
- pydantic_ai/messages.py,sha256=ZLV6Evc0-HWiR7nt0C_6Oe9kFhmE0o4Hg19TZPUPTaU,40089
22
+ pydantic_ai/mcp.py,sha256=v_f4CRzJ399uPC96aqTiEzpaYvuo6vIQyLIpXQBudsY,26271
23
+ pydantic_ai/messages.py,sha256=QutKuCXC6aglsbpyI5b3FTzCh7n7uVhJ47KwpEfCtpU,42548
24
24
  pydantic_ai/output.py,sha256=54Cwd1RruXlA5hucZ1h-SxFrzKHJuLvYvLtH9iyg2GI,11988
25
25
  pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  pydantic_ai/result.py,sha256=6RYFUGMC_YXJ_v57DFc0swVFkYEmJxByBw5J3aWtXfw,25310
27
+ pydantic_ai/retries.py,sha256=Xkj-gZAd3wc12CVsIErVYx2EIdIwD5yJOL4Ou6jDQ2s,10498
27
28
  pydantic_ai/settings.py,sha256=yuUZ7-GkdPB-Gbx71kSdh8dSr6gwM9gEwk84qNxPO_I,3552
28
29
  pydantic_ai/tools.py,sha256=PQm1yWbocdrhyLdMf_J8dJMTRJTWzyS2BEF24t4jgqw,14205
29
30
  pydantic_ai/usage.py,sha256=ceC9HHflyM_rkLBJqtaWPc-M8bEoq5rZF4XwGblPQoU,5830
@@ -33,21 +34,21 @@ pydantic_ai/common_tools/tavily.py,sha256=Q1xxSF5HtXAaZ10Pp-OaDOHXwJf2mco9wScGEQ
33
34
  pydantic_ai/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  pydantic_ai/ext/aci.py,sha256=vUaNIj6pRM52x6RkPW_DohSYxJPm75pPUfOMw2i5Xx0,2515
35
36
  pydantic_ai/ext/langchain.py,sha256=GemxfhpyG1JPxj69PbRiSJANnY8Q5s4hSB7wqt-uTbo,2266
36
- pydantic_ai/models/__init__.py,sha256=Bth7A-ULAqc9gQ0o6Jp6B8QhpDnBuh6lRNW6iMJqryA,30478
37
- pydantic_ai/models/anthropic.py,sha256=R_vOfxYiZbijFDLHYz8cMaruGOWL4To1c2iMzVuD-l0,23823
38
- pydantic_ai/models/bedrock.py,sha256=WnYykDnkyBd340tpt4l35T8SjT3z50RO83EZ8n77FVA,29399
39
- pydantic_ai/models/cohere.py,sha256=PTqwMRsgaLGVUrzb80sh9jS6CNuvDokvPHKT5KTYR_g,12788
37
+ pydantic_ai/models/__init__.py,sha256=GZ2YE5qcqI8tNpovlO0_6Ryx92bo8sQTsLmRKiYnSU4,30912
38
+ pydantic_ai/models/anthropic.py,sha256=dMPFqIeYCIhoeU_4uk9PmZYQWL1NbkSVmVrBKXplTiI,24167
39
+ pydantic_ai/models/bedrock.py,sha256=O6wKZDu4L18L1L2Nsa-XMW4ch073FjcLKRA5t_NXcHU,29511
40
+ pydantic_ai/models/cohere.py,sha256=lKUXEPqTMqxIJfouDj-Fr1bnfkrPu-JK3Xth7CL03kU,12800
40
41
  pydantic_ai/models/fallback.py,sha256=URaV-dTQWkg99xrlkmknue5lXZWDcEt7cJ1Vsky4oB4,5130
41
- pydantic_ai/models/function.py,sha256=4C9Bu8Hm2z-wB5f8oOzEO1gkquHtMux4iLU0FwfgtVs,13431
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
45
- pydantic_ai/models/huggingface.py,sha256=DTkbfySeBfRqIrbMzgUunGnIo-3mLuaDyQjBYTT42bI,18857
42
+ pydantic_ai/models/function.py,sha256=iHhG6GYN14XDo3_qbdliv_umY10B7-k11aoDoVF4xP8,13563
43
+ pydantic_ai/models/gemini.py,sha256=BMFEiDJXbB0DPj5DKK4kCwXuQHifT2WU-WuthJOqPsI,38138
44
+ pydantic_ai/models/google.py,sha256=NNcr2jJlK3eFlSRyaTgDPuSjG2GxOOj0vYDrAfD6rbo,24394
45
+ pydantic_ai/models/groq.py,sha256=8-sh8h2sJNZE6TiNUoiTKjmWghtCncxa3BX_xN979XQ,18854
46
+ pydantic_ai/models/huggingface.py,sha256=06Rh0Q-p_2LPuny5RIooMx-NWD1rbbhLWP2wL4E6aq0,19019
46
47
  pydantic_ai/models/instrumented.py,sha256=aqvzspcGexn1Molbu6Mn4EEPRBSoQCCCS_yknJvJJ-8,16205
47
48
  pydantic_ai/models/mcp_sampling.py,sha256=q9nnjNEAAbhrfRc_Qw5z9TtCHMG_SwlCWW9FvKWjh8k,3395
48
- pydantic_ai/models/mistral.py,sha256=t9ecKi3NiWP70pF_YJFf7pMwO_iQQNfus1-suq50s_k,31308
49
- pydantic_ai/models/openai.py,sha256=_35Cp0-m-6ZECNRVcHpi4O4a37lJOc4OipEHHzZCkY4,55092
50
- pydantic_ai/models/test.py,sha256=S8hp3fJZJVSwWl01bBi-q7YpijdbstXhGg3aCPon98o,18227
49
+ pydantic_ai/models/mistral.py,sha256=u3LcPVqvdI2WHckffbj7zRT5oQn9yYdTRbtEN20Gqpw,31427
50
+ pydantic_ai/models/openai.py,sha256=CJC5nU-b8HeKSa_4EbvTG_cmRjEnBjpoVbdfg_4ttyA,55834
51
+ pydantic_ai/models/test.py,sha256=tkm6K0-G5Mc_iSqVzVIpU9VLil9dfkE1-5az8GGWwTI,18457
51
52
  pydantic_ai/models/wrapper.py,sha256=A5-ncYhPF8c9S_czGoXkd55s2KOQb65p3jbVpwZiFPA,2043
52
53
  pydantic_ai/profiles/__init__.py,sha256=BXMqUpgRfosmYgcxjKAI9ESCj47JTSa30DhKXEgVLzM,2419
53
54
  pydantic_ai/profiles/_json_schema.py,sha256=sTNHkaK0kbwmbldZp9JRGQNax0f5Qvwy0HkWuu_nGxU,7179
@@ -60,9 +61,9 @@ pydantic_ai/profiles/grok.py,sha256=nBOxOCYCK9aiLmz2Q-esqYhotNbbBC1boAoOYIk1tVw,
60
61
  pydantic_ai/profiles/meta.py,sha256=IAGPoUrLWd-g9ajAgpWp9fIeOrP-7dBlZ2HEFjIhUbY,334
61
62
  pydantic_ai/profiles/mistral.py,sha256=ll01PmcK3szwlTfbaJLQmfd0TADN8lqjov9HpPJzCMQ,217
62
63
  pydantic_ai/profiles/moonshotai.py,sha256=LL5RacKHKn6rdvhoKjpGgZ8aVriv5NMeL6HCWEANAiU,223
63
- pydantic_ai/profiles/openai.py,sha256=wFFtzbM22HbxxRNDXYEs6tr6_RSbv8xN_xBPz6RsP9s,6698
64
+ pydantic_ai/profiles/openai.py,sha256=2s1DILf4fetSA5e0vUpB-KbNp-nCfSFqlJslbxXLCA8,7157
64
65
  pydantic_ai/profiles/qwen.py,sha256=u7pL8uomoQTVl45g5wDrHx0P_oFDLaN6ALswuwmkWc0,334
65
- pydantic_ai/providers/__init__.py,sha256=8D685KEGzwtgeg1Z5tC9ugr_O16E1VWWmeqSgAnx69k,3779
66
+ pydantic_ai/providers/__init__.py,sha256=6Jm4ioGiI5jcwKUC2Yxv-GHdrK3ZTJmb-9_eHBZgfdw,4005
66
67
  pydantic_ai/providers/anthropic.py,sha256=D35UXxCPXv8yIbD0fj9Zg2FvNyoMoJMeDUtVM8Sn78I,3046
67
68
  pydantic_ai/providers/azure.py,sha256=y77IHGiSQ9Ttx9f4SGMgdpin2Daq6eYyzUdM9ET22RQ,5819
68
69
  pydantic_ai/providers/bedrock.py,sha256=ycdTXnkj_WNqPMA7DNDPeYia0C37FP0_l0CygSQmWYI,5694
@@ -78,12 +79,14 @@ pydantic_ai/providers/groq.py,sha256=hqcR-RFHHHeemYP3K16IFeQTJKywNEU2wNZOSGTz6fE
78
79
  pydantic_ai/providers/heroku.py,sha256=NmDIkAdxtWsvCjlX-bKI5FgI4HW1zO9-e0mrNQNGMCk,2990
79
80
  pydantic_ai/providers/huggingface.py,sha256=LRmJcJpQRRYvam3IAPkYs2fMUJf70GgE3aDgQltGRCU,3821
80
81
  pydantic_ai/providers/mistral.py,sha256=EIUSENjFuGzBhvbdrarUTM4VPkesIMnZrzfnEKHOsc4,3120
82
+ pydantic_ai/providers/moonshotai.py,sha256=3BAE9eC9QaD3kblVwxtQWEln0-PhgK7bRvrYTCEYXbY,3471
81
83
  pydantic_ai/providers/openai.py,sha256=7iGij0EaFylab7dTZAZDgXr78tr-HsZrn9EI9AkWBNQ,3091
82
84
  pydantic_ai/providers/openrouter.py,sha256=NXjNdnlXIBrBMMqbzcWQnowXOuZh4NHikXenBn5h3mc,4061
83
85
  pydantic_ai/providers/together.py,sha256=zFVSMSm5jXbpkNouvBOTjWrPmlPpCp6sQS5LMSyVjrQ,3482
86
+ pydantic_ai/providers/vercel.py,sha256=JM1NmqLR64RvEmVWI8t2zGQdxOHJ-CguibOI0uSv-_Q,4061
84
87
  pydantic_ai/toolsets/__init__.py,sha256=JCnqqAFeuHhmVW4XK0LM6Op_9B1cvsQUJ3vTmQ9Z5cQ,590
85
88
  pydantic_ai/toolsets/abstract.py,sha256=LqunlpwUsoHVn4VMtdjEoLY5kiMUF74PZ4KW539K8tQ,6027
86
- pydantic_ai/toolsets/combined.py,sha256=bmhQqxq4WQz_55a_cMsUfcCK6ggF74QEPoa12w34MOU,3371
89
+ pydantic_ai/toolsets/combined.py,sha256=UBSZ5quJAm4aITkI4enOTJ6sEDndkJ2sKvT1sTeX5LU,3440
87
90
  pydantic_ai/toolsets/deferred.py,sha256=j_CO2KesBXFPyVYiIk3sO2bimJ1bssnShdaGx4UNuPQ,1444
88
91
  pydantic_ai/toolsets/filtered.py,sha256=qmPeQDTZoWa_yyk6VXKHcpV9NFgdnLN48sBf7WItjBs,855
89
92
  pydantic_ai/toolsets/function.py,sha256=Pgc8q6vh3qkBzI3xL0k-CQaETGG63zfy1PyWtqqzXwc,10186
@@ -91,8 +94,8 @@ pydantic_ai/toolsets/prefixed.py,sha256=MIStkzUdiU0rk2Y6P19IrTBxspH5pTstGxsqCBt-
91
94
  pydantic_ai/toolsets/prepared.py,sha256=Zjfz6S8In6PBVxoKFN9sKPN984zO6t0awB7Lnq5KODw,1431
92
95
  pydantic_ai/toolsets/renamed.py,sha256=JuLHpi-hYPiSPlaTpN8WiXLiGsywYK0axi2lW2Qs75k,1637
93
96
  pydantic_ai/toolsets/wrapper.py,sha256=WjLoiM1WDuffSJ4mDS6pZrEZGHgZ421fjrqFcB66W94,1205
94
- pydantic_ai_slim-0.4.6.dist-info/METADATA,sha256=kBkX5UxEKP5fhR-teYZXhAp7MTzFYAspuNTuqZDDkvg,4098
95
- pydantic_ai_slim-0.4.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
- pydantic_ai_slim-0.4.6.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
97
- pydantic_ai_slim-0.4.6.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
98
- pydantic_ai_slim-0.4.6.dist-info/RECORD,,
97
+ pydantic_ai_slim-0.4.8.dist-info/METADATA,sha256=nliQXFsj6CUu4vC4pLcAWNSvekw8aZMJEkSo5tNOLfw,4226
98
+ pydantic_ai_slim-0.4.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ pydantic_ai_slim-0.4.8.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
100
+ pydantic_ai_slim-0.4.8.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
101
+ pydantic_ai_slim-0.4.8.dist-info/RECORD,,