pydantic-ai-slim 0.7.2__py3-none-any.whl → 0.7.3__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.
Files changed (36) hide show
  1. pydantic_ai/_agent_graph.py +2 -2
  2. pydantic_ai/_cli.py +18 -3
  3. pydantic_ai/_run_context.py +2 -2
  4. pydantic_ai/ag_ui.py +4 -4
  5. pydantic_ai/agent/__init__.py +7 -9
  6. pydantic_ai/agent/abstract.py +16 -18
  7. pydantic_ai/agent/wrapper.py +4 -6
  8. pydantic_ai/direct.py +4 -4
  9. pydantic_ai/durable_exec/temporal/_agent.py +13 -15
  10. pydantic_ai/durable_exec/temporal/_model.py +2 -2
  11. pydantic_ai/messages.py +16 -6
  12. pydantic_ai/models/__init__.py +5 -5
  13. pydantic_ai/models/anthropic.py +27 -26
  14. pydantic_ai/models/bedrock.py +24 -26
  15. pydantic_ai/models/cohere.py +20 -25
  16. pydantic_ai/models/fallback.py +15 -15
  17. pydantic_ai/models/function.py +7 -9
  18. pydantic_ai/models/gemini.py +43 -39
  19. pydantic_ai/models/google.py +59 -40
  20. pydantic_ai/models/groq.py +22 -19
  21. pydantic_ai/models/huggingface.py +18 -21
  22. pydantic_ai/models/instrumented.py +4 -4
  23. pydantic_ai/models/mcp_sampling.py +1 -2
  24. pydantic_ai/models/mistral.py +24 -22
  25. pydantic_ai/models/openai.py +98 -44
  26. pydantic_ai/models/test.py +4 -5
  27. pydantic_ai/profiles/openai.py +13 -3
  28. pydantic_ai/providers/openai.py +1 -1
  29. pydantic_ai/result.py +5 -5
  30. pydantic_ai/run.py +4 -11
  31. pydantic_ai/usage.py +229 -67
  32. {pydantic_ai_slim-0.7.2.dist-info → pydantic_ai_slim-0.7.3.dist-info}/METADATA +10 -4
  33. {pydantic_ai_slim-0.7.2.dist-info → pydantic_ai_slim-0.7.3.dist-info}/RECORD +36 -36
  34. {pydantic_ai_slim-0.7.2.dist-info → pydantic_ai_slim-0.7.3.dist-info}/WHEEL +0 -0
  35. {pydantic_ai_slim-0.7.2.dist-info → pydantic_ai_slim-0.7.3.dist-info}/entry_points.txt +0 -0
  36. {pydantic_ai_slim-0.7.2.dist-info → pydantic_ai_slim-0.7.3.dist-info}/licenses/LICENSE +0 -0
pydantic_ai/usage.py CHANGED
@@ -1,67 +1,62 @@
1
1
  from __future__ import annotations as _annotations
2
2
 
3
+ import dataclasses
3
4
  from copy import copy
4
- from dataclasses import dataclass
5
+ from dataclasses import dataclass, fields
6
+
7
+ from typing_extensions import deprecated, overload
5
8
 
6
9
  from . import _utils
7
10
  from .exceptions import UsageLimitExceeded
8
11
 
9
- __all__ = 'Usage', 'UsageLimits'
12
+ __all__ = 'RequestUsage', 'RunUsage', 'Usage', 'UsageLimits'
10
13
 
11
14
 
12
15
  @dataclass(repr=False)
13
- class Usage:
14
- """LLM usage associated with a request or run.
15
-
16
- Responsibility for calculating usage is on the model; Pydantic AI simply sums the usage information across requests.
16
+ class UsageBase:
17
+ input_tokens: int = 0
18
+ """Number of input/prompt tokens."""
17
19
 
18
- You'll need to look up the documentation of the model you're using to convert usage to monetary costs.
19
- """
20
+ cache_write_tokens: int = 0
21
+ """Number of tokens written to the cache."""
22
+ cache_read_tokens: int = 0
23
+ """Number of tokens read from the cache."""
20
24
 
21
- requests: int = 0
22
- """Number of requests made to the LLM API."""
23
- request_tokens: int | None = None
24
- """Tokens used in processing requests."""
25
- response_tokens: int | None = None
26
- """Tokens used in generating responses."""
27
- total_tokens: int | None = None
28
- """Total tokens used in the whole run, should generally be equal to `request_tokens + response_tokens`."""
29
- details: dict[str, int] | None = None
30
- """Any extra details returned by the model."""
25
+ output_tokens: int = 0
26
+ """Number of output/completion tokens."""
31
27
 
32
- def incr(self, incr_usage: Usage) -> None:
33
- """Increment the usage in place.
28
+ input_audio_tokens: int = 0
29
+ """Number of audio input tokens."""
30
+ cache_audio_read_tokens: int = 0
31
+ """Number of audio tokens read from the cache."""
32
+ output_audio_tokens: int = 0
33
+ """Number of audio output tokens."""
34
34
 
35
- Args:
36
- incr_usage: The usage to increment by.
37
- """
38
- for f in 'requests', 'request_tokens', 'response_tokens', 'total_tokens':
39
- self_value = getattr(self, f)
40
- other_value = getattr(incr_usage, f)
41
- if self_value is not None or other_value is not None:
42
- setattr(self, f, (self_value or 0) + (other_value or 0))
35
+ details: dict[str, int] = dataclasses.field(default_factory=dict)
36
+ """Any extra details returned by the model."""
43
37
 
44
- if incr_usage.details:
45
- self.details = self.details or {}
46
- for key, value in incr_usage.details.items():
47
- self.details[key] = self.details.get(key, 0) + value
38
+ @property
39
+ @deprecated('`request_tokens` is deprecated, use `input_tokens` instead')
40
+ def request_tokens(self) -> int:
41
+ return self.input_tokens
48
42
 
49
- def __add__(self, other: Usage) -> Usage:
50
- """Add two Usages together.
43
+ @property
44
+ @deprecated('`response_tokens` is deprecated, use `output_tokens` instead')
45
+ def response_tokens(self) -> int:
46
+ return self.output_tokens
51
47
 
52
- This is provided so it's trivial to sum usage information from multiple requests and runs.
53
- """
54
- new_usage = copy(self)
55
- new_usage.incr(other)
56
- return new_usage
48
+ @property
49
+ def total_tokens(self) -> int:
50
+ """Sum of `input_tokens + output_tokens`."""
51
+ return self.input_tokens + self.output_tokens
57
52
 
58
53
  def opentelemetry_attributes(self) -> dict[str, int]:
59
- """Get the token limits as OpenTelemetry attributes."""
54
+ """Get the token usage values as OpenTelemetry attributes."""
60
55
  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
56
+ if self.input_tokens:
57
+ result['gen_ai.usage.input_tokens'] = self.input_tokens
58
+ if self.output_tokens:
59
+ result['gen_ai.usage.output_tokens'] = self.output_tokens
65
60
  details = self.details
66
61
  if details:
67
62
  prefix = 'gen_ai.usage.details.'
@@ -71,11 +66,118 @@ class Usage:
71
66
  result[prefix + key] = value
72
67
  return result
73
68
 
69
+ def __repr__(self):
70
+ kv_pairs = (f'{f.name}={value!r}' for f in fields(self) if (value := getattr(self, f.name)))
71
+ return f'{self.__class__.__qualname__}({", ".join(kv_pairs)})'
72
+
74
73
  def has_values(self) -> bool:
75
74
  """Whether any values are set and non-zero."""
76
- return bool(self.requests or self.request_tokens or self.response_tokens or self.details)
75
+ return any(dataclasses.asdict(self).values())
77
76
 
78
- __repr__ = _utils.dataclasses_no_defaults_repr
77
+
78
+ @dataclass(repr=False)
79
+ class RequestUsage(UsageBase):
80
+ """LLM usage associated with a single request.
81
+
82
+ This is an implementation of `genai_prices.types.AbstractUsage` so it can be used to calculate the price of the
83
+ request using [genai-prices](https://github.com/pydantic/genai-prices).
84
+ """
85
+
86
+ @property
87
+ def requests(self):
88
+ return 1
89
+
90
+ def incr(self, incr_usage: RequestUsage) -> None:
91
+ """Increment the usage in place.
92
+
93
+ Args:
94
+ incr_usage: The usage to increment by.
95
+ """
96
+ return _incr_usage_tokens(self, incr_usage)
97
+
98
+ def __add__(self, other: RequestUsage) -> RequestUsage:
99
+ """Add two RequestUsages together.
100
+
101
+ This is provided so it's trivial to sum usage information from multiple parts of a response.
102
+
103
+ **WARNING:** this CANNOT be used to sum multiple requests without breaking some pricing calculations.
104
+ """
105
+ new_usage = copy(self)
106
+ new_usage.incr(other)
107
+ return new_usage
108
+
109
+
110
+ @dataclass(repr=False)
111
+ class RunUsage(UsageBase):
112
+ """LLM usage associated with an agent run.
113
+
114
+ Responsibility for calculating request usage is on the model; Pydantic AI simply sums the usage information across requests.
115
+ """
116
+
117
+ requests: int = 0
118
+ """Number of requests made to the LLM API."""
119
+
120
+ input_tokens: int = 0
121
+ """Total number of text input/prompt tokens."""
122
+
123
+ cache_write_tokens: int = 0
124
+ """Total number of tokens written to the cache."""
125
+ cache_read_tokens: int = 0
126
+ """Total number of tokens read from the cache."""
127
+
128
+ input_audio_tokens: int = 0
129
+ """Total number of audio input tokens."""
130
+ cache_audio_read_tokens: int = 0
131
+ """Total number of audio tokens read from the cache."""
132
+
133
+ output_tokens: int = 0
134
+ """Total number of text output/completion tokens."""
135
+
136
+ details: dict[str, int] = dataclasses.field(default_factory=dict)
137
+ """Any extra details returned by the model."""
138
+
139
+ def incr(self, incr_usage: RunUsage | RequestUsage) -> None:
140
+ """Increment the usage in place.
141
+
142
+ Args:
143
+ incr_usage: The usage to increment by.
144
+ """
145
+ if isinstance(incr_usage, RunUsage):
146
+ self.requests += incr_usage.requests
147
+ return _incr_usage_tokens(self, incr_usage)
148
+
149
+ def __add__(self, other: RunUsage | RequestUsage) -> RunUsage:
150
+ """Add two RunUsages together.
151
+
152
+ This is provided so it's trivial to sum usage information from multiple runs.
153
+ """
154
+ new_usage = copy(self)
155
+ new_usage.incr(other)
156
+ return new_usage
157
+
158
+
159
+ def _incr_usage_tokens(slf: RunUsage | RequestUsage, incr_usage: RunUsage | RequestUsage) -> None:
160
+ """Increment the usage in place.
161
+
162
+ Args:
163
+ slf: The usage to increment.
164
+ incr_usage: The usage to increment by.
165
+ """
166
+ slf.input_tokens += incr_usage.input_tokens
167
+ slf.cache_write_tokens += incr_usage.cache_write_tokens
168
+ slf.cache_read_tokens += incr_usage.cache_read_tokens
169
+ slf.input_audio_tokens += incr_usage.input_audio_tokens
170
+ slf.cache_audio_read_tokens += incr_usage.cache_audio_read_tokens
171
+ slf.output_tokens += incr_usage.output_tokens
172
+
173
+ for key, value in incr_usage.details.items():
174
+ slf.details[key] = slf.details.get(key, 0) + value
175
+
176
+
177
+ @dataclass
178
+ @deprecated('`Usage` is deprecated, use `RunUsage` instead')
179
+ class Usage(RunUsage):
180
+ """Deprecated alias for `RunUsage`."""
79
181
 
80
182
 
81
183
  @dataclass(repr=False)
@@ -90,10 +192,10 @@ class UsageLimits:
90
192
 
91
193
  request_limit: int | None = 50
92
194
  """The maximum number of requests allowed to the model."""
93
- request_tokens_limit: int | None = None
94
- """The maximum number of tokens allowed in requests to the model."""
95
- response_tokens_limit: int | None = None
96
- """The maximum number of tokens allowed in responses from the model."""
195
+ input_tokens_limit: int | None = None
196
+ """The maximum number of input/prompt tokens allowed."""
197
+ output_tokens_limit: int | None = None
198
+ """The maximum number of output/response tokens allowed."""
97
199
  total_tokens_limit: int | None = None
98
200
  """The maximum number of tokens allowed in requests and responses combined."""
99
201
  count_tokens_before_request: bool = False
@@ -101,6 +203,69 @@ class UsageLimits:
101
203
  to enforce `request_tokens_limit` ahead of time. This may incur additional overhead
102
204
  (from calling the model's `count_tokens` API before making the actual request) and is disabled by default."""
103
205
 
206
+ @property
207
+ @deprecated('`request_tokens_limit` is deprecated, use `input_tokens_limit` instead')
208
+ def request_tokens_limit(self) -> int | None:
209
+ return self.input_tokens_limit
210
+
211
+ @property
212
+ @deprecated('`response_tokens_limit` is deprecated, use `output_tokens_limit` instead')
213
+ def response_tokens_limit(self) -> int | None:
214
+ return self.output_tokens_limit
215
+
216
+ @overload
217
+ def __init__(
218
+ self,
219
+ *,
220
+ request_limit: int | None = 50,
221
+ input_tokens_limit: int | None = None,
222
+ output_tokens_limit: int | None = None,
223
+ total_tokens_limit: int | None = None,
224
+ count_tokens_before_request: bool = False,
225
+ ) -> None:
226
+ self.request_limit = request_limit
227
+ self.input_tokens_limit = input_tokens_limit
228
+ self.output_tokens_limit = output_tokens_limit
229
+ self.total_tokens_limit = total_tokens_limit
230
+ self.count_tokens_before_request = count_tokens_before_request
231
+
232
+ @overload
233
+ @deprecated(
234
+ 'Use `input_tokens_limit` instead of `request_tokens_limit` and `output_tokens_limit` and `total_tokens_limit`'
235
+ )
236
+ def __init__(
237
+ self,
238
+ *,
239
+ request_limit: int | None = 50,
240
+ request_tokens_limit: int | None = None,
241
+ response_tokens_limit: int | None = None,
242
+ total_tokens_limit: int | None = None,
243
+ count_tokens_before_request: bool = False,
244
+ ) -> None:
245
+ self.request_limit = request_limit
246
+ self.input_tokens_limit = request_tokens_limit
247
+ self.output_tokens_limit = response_tokens_limit
248
+ self.total_tokens_limit = total_tokens_limit
249
+ self.count_tokens_before_request = count_tokens_before_request
250
+
251
+ def __init__(
252
+ self,
253
+ *,
254
+ request_limit: int | None = 50,
255
+ input_tokens_limit: int | None = None,
256
+ output_tokens_limit: int | None = None,
257
+ total_tokens_limit: int | None = None,
258
+ count_tokens_before_request: bool = False,
259
+ # deprecated:
260
+ request_tokens_limit: int | None = None,
261
+ response_tokens_limit: int | None = None,
262
+ ):
263
+ self.request_limit = request_limit
264
+ self.input_tokens_limit = input_tokens_limit or request_tokens_limit
265
+ self.output_tokens_limit = output_tokens_limit or response_tokens_limit
266
+ self.total_tokens_limit = total_tokens_limit
267
+ self.count_tokens_before_request = count_tokens_before_request
268
+
104
269
  def has_token_limits(self) -> bool:
105
270
  """Returns `True` if this instance places any limits on token counts.
106
271
 
@@ -110,43 +275,40 @@ class UsageLimits:
110
275
  If there are no limits, we can skip that processing in the streaming response iterator.
111
276
  """
112
277
  return any(
113
- limit is not None
114
- for limit in (self.request_tokens_limit, self.response_tokens_limit, self.total_tokens_limit)
278
+ limit is not None for limit in (self.input_tokens_limit, self.output_tokens_limit, self.total_tokens_limit)
115
279
  )
116
280
 
117
- def check_before_request(self, usage: Usage) -> None:
281
+ def check_before_request(self, usage: RunUsage) -> None:
118
282
  """Raises a `UsageLimitExceeded` exception if the next request would exceed any of the limits."""
119
283
  request_limit = self.request_limit
120
284
  if request_limit is not None and usage.requests >= request_limit:
121
285
  raise UsageLimitExceeded(f'The next request would exceed the request_limit of {request_limit}')
122
286
 
123
- request_tokens = usage.request_tokens or 0
124
- if self.request_tokens_limit is not None and request_tokens > self.request_tokens_limit:
287
+ input_tokens = usage.input_tokens
288
+ if self.input_tokens_limit is not None and input_tokens > self.input_tokens_limit:
125
289
  raise UsageLimitExceeded(
126
- f'The next request would exceed the request_tokens_limit of {self.request_tokens_limit} ({request_tokens=})'
290
+ f'The next request would exceed the input_tokens_limit of {self.input_tokens_limit} ({input_tokens=})'
127
291
  )
128
292
 
129
- total_tokens = usage.total_tokens or 0
293
+ total_tokens = usage.total_tokens
130
294
  if self.total_tokens_limit is not None and total_tokens > self.total_tokens_limit:
131
295
  raise UsageLimitExceeded(
132
296
  f'The next request would exceed the total_tokens_limit of {self.total_tokens_limit} ({total_tokens=})'
133
297
  )
134
298
 
135
- def check_tokens(self, usage: Usage) -> None:
299
+ def check_tokens(self, usage: RunUsage) -> None:
136
300
  """Raises a `UsageLimitExceeded` exception if the usage exceeds any of the token limits."""
137
- request_tokens = usage.request_tokens or 0
138
- if self.request_tokens_limit is not None and request_tokens > self.request_tokens_limit:
139
- raise UsageLimitExceeded(
140
- f'Exceeded the request_tokens_limit of {self.request_tokens_limit} ({request_tokens=})'
141
- )
301
+ input_tokens = usage.input_tokens
302
+ if self.input_tokens_limit is not None and input_tokens > self.input_tokens_limit:
303
+ raise UsageLimitExceeded(f'Exceeded the input_tokens_limit of {self.input_tokens_limit} ({input_tokens=})')
142
304
 
143
- response_tokens = usage.response_tokens or 0
144
- if self.response_tokens_limit is not None and response_tokens > self.response_tokens_limit:
305
+ output_tokens = usage.output_tokens
306
+ if self.output_tokens_limit is not None and output_tokens > self.output_tokens_limit:
145
307
  raise UsageLimitExceeded(
146
- f'Exceeded the response_tokens_limit of {self.response_tokens_limit} ({response_tokens=})'
308
+ f'Exceeded the output_tokens_limit of {self.output_tokens_limit} ({output_tokens=})'
147
309
  )
148
310
 
149
- total_tokens = usage.total_tokens or 0
311
+ total_tokens = usage.total_tokens
150
312
  if self.total_tokens_limit is not None and total_tokens > self.total_tokens_limit:
151
313
  raise UsageLimitExceeded(f'Exceeded the total_tokens_limit of {self.total_tokens_limit} ({total_tokens=})')
152
314
 
@@ -1,7 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
5
+ Project-URL: Homepage, https://github.com/pydantic/pydantic-ai/tree/main/pydantic_ai_slim
6
+ Project-URL: Source, https://github.com/pydantic/pydantic-ai/tree/main/pydantic_ai_slim
7
+ Project-URL: Documentation, https://ai.pydantic.dev/install/#slim-install
8
+ Project-URL: Changelog, https://github.com/pydantic/pydantic-ai/releases
5
9
  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
10
  License-Expression: MIT
7
11
  License-File: LICENSE
@@ -27,10 +31,11 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
31
  Requires-Python: >=3.9
28
32
  Requires-Dist: eval-type-backport>=0.2.0
29
33
  Requires-Dist: exceptiongroup; python_version < '3.11'
34
+ Requires-Dist: genai-prices>=0.0.22
30
35
  Requires-Dist: griffe>=1.3.2
31
36
  Requires-Dist: httpx>=0.27
32
37
  Requires-Dist: opentelemetry-api>=1.28.0
33
- Requires-Dist: pydantic-graph==0.7.2
38
+ Requires-Dist: pydantic-graph==0.7.3
34
39
  Requires-Dist: pydantic>=2.10
35
40
  Requires-Dist: typing-inspection>=0.4.0
36
41
  Provides-Extra: a2a
@@ -45,13 +50,14 @@ Requires-Dist: boto3>=1.39.0; extra == 'bedrock'
45
50
  Provides-Extra: cli
46
51
  Requires-Dist: argcomplete>=3.5.0; extra == 'cli'
47
52
  Requires-Dist: prompt-toolkit>=3; extra == 'cli'
53
+ Requires-Dist: pyperclip>=1.9.0; extra == 'cli'
48
54
  Requires-Dist: rich>=13; extra == 'cli'
49
55
  Provides-Extra: cohere
50
56
  Requires-Dist: cohere>=5.16.0; (platform_system != 'Emscripten') and extra == 'cohere'
51
57
  Provides-Extra: duckduckgo
52
58
  Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
53
59
  Provides-Extra: evals
54
- Requires-Dist: pydantic-evals==0.7.2; extra == 'evals'
60
+ Requires-Dist: pydantic-evals==0.7.3; extra == 'evals'
55
61
  Provides-Extra: google
56
62
  Requires-Dist: google-genai>=1.28.0; extra == 'google'
57
63
  Provides-Extra: groq
@@ -71,7 +77,7 @@ Requires-Dist: tenacity>=8.2.3; extra == 'retries'
71
77
  Provides-Extra: tavily
72
78
  Requires-Dist: tavily-python>=0.5.0; extra == 'tavily'
73
79
  Provides-Extra: temporal
74
- Requires-Dist: temporalio>=1.15.0; extra == 'temporal'
80
+ Requires-Dist: temporalio==1.15.0; extra == 'temporal'
75
81
  Provides-Extra: vertexai
76
82
  Requires-Dist: google-auth>=2.36.0; extra == 'vertexai'
77
83
  Requires-Dist: requests>=2.32.2; extra == 'vertexai'
@@ -1,66 +1,66 @@
1
1
  pydantic_ai/__init__.py,sha256=Uy0J4BgX4CXsa0sUUb5K0FC4uUWGIwBici93QHLkNsk,1478
2
2
  pydantic_ai/__main__.py,sha256=Q_zJU15DUA01YtlJ2mnaLCoId2YmgmreVEERGuQT-Y0,132
3
3
  pydantic_ai/_a2a.py,sha256=wux52DmJQceLJwF71qxb0Uqupk3aS61m005-NmuWZIw,12164
4
- pydantic_ai/_agent_graph.py,sha256=QB6J-UI-gUUXPhk1ud39yCWw3U04Ea28HWfIN74iO6M,38488
5
- pydantic_ai/_cli.py,sha256=nr3hW7Y4vHzk7oXpfOCupwuJ6Z2SmZLz2dYS6ljCpuc,13281
4
+ pydantic_ai/_agent_graph.py,sha256=W6bdFC_LtROBkU7ZpWqWL-sTSKD17tYyeBI9nWzVL5k,38484
5
+ pydantic_ai/_cli.py,sha256=YNqV2Kb3KYpof0lD4wwnULM2sCxzsvBzsh-oPd6lJN8,13959
6
6
  pydantic_ai/_function_schema.py,sha256=YFHxb6bKfhgeY6rNdbuYXgndGCDanveUx2258xkSNlQ,11233
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=6Vxlw8F9nRWCkjy4qvFF8tmDi2xZn7Dq72T6s4C5kAM,37640
10
10
  pydantic_ai/_parts_manager.py,sha256=zrra5yDpAX8cFB_eK0btAp9d6NAR979V1Rmepm83l1w,17980
11
- pydantic_ai/_run_context.py,sha256=pqb_HPXytE1Z9zZRRuBboRYes_tVTC75WGTpZgnb2Ko,1691
11
+ pydantic_ai/_run_context.py,sha256=uSjR0a9QJ7KifqJsu7buGpK4wqexO7ldZMzWsBOboDI,1697
12
12
  pydantic_ai/_system_prompt.py,sha256=lUSq-gDZjlYTGtd6BUm54yEvTIvgdwBmJ8mLsNZZtYU,1142
13
13
  pydantic_ai/_thinking_part.py,sha256=x80-Vkon16GOyq3W6f2qzafTVPC5dCgF7QD3k8ZMmYU,1304
14
14
  pydantic_ai/_tool_manager.py,sha256=WPMXgHBzyn7UgRKIuqU-oV2GpsAOW0nF2RsxPCKOp7U,9655
15
15
  pydantic_ai/_utils.py,sha256=Ge9rtu8NJvsfSFjx1MduITPr0-9b_I0emDFSpwJbYes,16372
16
- pydantic_ai/ag_ui.py,sha256=2cKSSvl1j0pxVNCFQO82l7LVtkJMt0HUaEXGwy3y558,26463
16
+ pydantic_ai/ag_ui.py,sha256=bd-RJYFFmcw2xkAWj-7N0ZLRMa1dam3LEhlgoNo1l9I,26475
17
17
  pydantic_ai/builtin_tools.py,sha256=mwIq-7m0ZSbCZp1zxswjRfQM648QE01IDfifvqDGxUQ,3023
18
- pydantic_ai/direct.py,sha256=mduSzkCapSAuzV90da1aARy9n-Jwj6papgbMWGbWIkQ,14943
18
+ pydantic_ai/direct.py,sha256=ym1Lb7oCPDU2eMmN8LXzN7Dp_IUJIPmlyKgmxxBUxsc,14905
19
19
  pydantic_ai/exceptions.py,sha256=vHRH_b6JpMi5p5EGhz2O4FSeKGJv3WMD291Y1FjHYFc,3528
20
20
  pydantic_ai/format_prompt.py,sha256=Or-Ytq55RQb1UJqy2HKIyPpZ-knWXfdDP3Z6tNc6Orw,4244
21
21
  pydantic_ai/mcp.py,sha256=n9_ECHmFE-eOZmb1bDh94oy81caefdtSGo1oH2KKWMo,31162
22
- pydantic_ai/messages.py,sha256=kLw3yBtUEoRQ43zZ43PpasgC6EeVbSQi4Fl0PB1tQwA,45700
22
+ pydantic_ai/messages.py,sha256=fPIicZ2J149x4cGSBbgeVahaDlnK6ChbMZ8gsZLPPfg,46099
23
23
  pydantic_ai/output.py,sha256=54Cwd1RruXlA5hucZ1h-SxFrzKHJuLvYvLtH9iyg2GI,11988
24
24
  pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- pydantic_ai/result.py,sha256=2Z5-wJXO5Iw_qHFoMcshTjiUHFdcT1aycNWt26kyLuY,19785
25
+ pydantic_ai/result.py,sha256=gUVJIyoM1FewRFLj7ezuXr7M2RSaQL4AytoIpBMmDy8,19800
26
26
  pydantic_ai/retries.py,sha256=Xkj-gZAd3wc12CVsIErVYx2EIdIwD5yJOL4Ou6jDQ2s,10498
27
- pydantic_ai/run.py,sha256=VSZEadgzRc_tytnHt2Gemdv9z05e6aEJTNPQ7DmuUck,15130
27
+ pydantic_ai/run.py,sha256=acyyTDH8qP1W-gbUA8TBBcOqte-7ICyoelJRjO_ojeo,14879
28
28
  pydantic_ai/settings.py,sha256=yuUZ7-GkdPB-Gbx71kSdh8dSr6gwM9gEwk84qNxPO_I,3552
29
29
  pydantic_ai/tools.py,sha256=1_4kt4HGfpHH4XnYy0lQRzm5Io5SzOjk3AJxa-LJLmE,14821
30
- pydantic_ai/usage.py,sha256=UddLBMmytzKBmsLzyGHHbJAnr4VQkMA8-vSjCeifz3w,6801
31
- pydantic_ai/agent/__init__.py,sha256=IB67d_jxZ3LpIdt5X7ng06CUV84dlzyBMse628PQttk,59319
32
- pydantic_ai/agent/abstract.py,sha256=m83vk00sV7q3MqIHucExkMsiEF52dANHptGl8TNEkbw,42035
33
- pydantic_ai/agent/wrapper.py,sha256=cVIpfPWF63oTD1jeWdFY-OS_ty2nwbeSwsI7upd30Kw,9155
30
+ pydantic_ai/usage.py,sha256=znjemyBOSUo5h0kQwQGEzTBlPGu4qUy69T-mciMUndE,12126
31
+ pydantic_ai/agent/__init__.py,sha256=6qe2t2TRr4yjwClHYaVRCSWFnDD8_7_0LhSfqF1L1ac,59255
32
+ pydantic_ai/agent/abstract.py,sha256=2B00V-SmKlFkrkVW2KQ4e0K_glr9cQL6Llq2OYLqlgg,42000
33
+ pydantic_ai/agent/wrapper.py,sha256=sE_9rA1PNF5v0qAMhRYw0W8bIhLT4RP17S3TSLz0k5w,9084
34
34
  pydantic_ai/common_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  pydantic_ai/common_tools/duckduckgo.py,sha256=aQsm7zKuoRNgPM8ltbdyj8dPkREEkQenimsf_laF6kc,2245
36
36
  pydantic_ai/common_tools/tavily.py,sha256=Q1xxSF5HtXAaZ10Pp-OaDOHXwJf2mco9wScGEQXD7E4,2495
37
37
  pydantic_ai/durable_exec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
38
  pydantic_ai/durable_exec/temporal/__init__.py,sha256=kzUnYUOmHNIsn6UzAa3-vEZx0VpIDZiY84iaRm6z-Qs,3356
39
- pydantic_ai/durable_exec/temporal/_agent.py,sha256=hKJW-oCU5W83sofQ-1f40IQe1FS-qrcmq4Dr-KcSy2c,32864
39
+ pydantic_ai/durable_exec/temporal/_agent.py,sha256=H1oHoZC9wOuAN79LG7Qb3DNtK2XFCLXB-6NRLv97dTI,32820
40
40
  pydantic_ai/durable_exec/temporal/_function_toolset.py,sha256=qKTs7T6YcJ2LBOvrlYBRUHd9zn86TuUaY0Qw5TPGSmE,3848
41
41
  pydantic_ai/durable_exec/temporal/_logfire.py,sha256=_dsvVIdpYJEUyoFUIDYQjCO6TjTITqvlJHwNy_Fi2cw,1866
42
42
  pydantic_ai/durable_exec/temporal/_mcp_server.py,sha256=J7CC4gRDhM4uQo3_kNKV7e4uiWC0He0AgS7bdq9Pt4o,6005
43
- pydantic_ai/durable_exec/temporal/_model.py,sha256=3EN9NuTjmWsB57Y9ukvo4hFf3bw-xF90QNSJ18y1iRk,6631
43
+ pydantic_ai/durable_exec/temporal/_model.py,sha256=7_-f-n1JEg4YsJ8NGoB9RXpaAB-mWZZBR0wtGqa3NgE,6645
44
44
  pydantic_ai/durable_exec/temporal/_run_context.py,sha256=5NTomzWBAlFcXeVw-4mqa76Rmrc8b3G1bB5ElVsAyCY,2310
45
45
  pydantic_ai/durable_exec/temporal/_toolset.py,sha256=XlQx7NGSKR9n-mjNWaTn-i3HW9X4z5fZUAM9DwDTBwY,2865
46
46
  pydantic_ai/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
47
  pydantic_ai/ext/aci.py,sha256=sUllKDNO-LOMurbFgxwRHuzNlBkSa3aVBqXfEm-A_vo,2545
48
48
  pydantic_ai/ext/langchain.py,sha256=iLVEZv1kcLkdIHo3us2yfdi0kVqyJ6qTaCt9BoLWm4k,2335
49
- pydantic_ai/models/__init__.py,sha256=PQcyiPaSj72mt9kjPgg69eboqHqRl0JlBHTS3eCO5uY,34611
50
- pydantic_ai/models/anthropic.py,sha256=8wLXYWzGxD2tEf0V9cy0iApZStZHgup6TUlMjd8pQp4,30019
51
- pydantic_ai/models/bedrock.py,sha256=IzVpH0rpj63fWnQSwYf13sZ4VFAVn0wzSWW4HRgRaSw,30840
52
- pydantic_ai/models/cohere.py,sha256=ZbRvCPgPjDLItUj-r08VPmR8D8e6ARbUiRd8rsZ-1sY,13094
53
- pydantic_ai/models/fallback.py,sha256=8d5C2MDbVBQ1NFHIciaIAJd8-DGzpTbMzIPIR1Dj4Xc,5514
54
- pydantic_ai/models/function.py,sha256=CKSy_xA__n92BnOzfI9BXRsRVy3WjvuRyzibU26I8Js,14299
55
- pydantic_ai/models/gemini.py,sha256=SWeahyDS_8STbofWJoIDvayBIGv-d4CYUuIBERPZkpI,38676
56
- pydantic_ai/models/google.py,sha256=xiAbIT0WkfdwwvjGY5WzOgTpkpxXI7-A2cvnyxwmI8s,29636
57
- pydantic_ai/models/groq.py,sha256=iLgei6osGzLSrtxCPlDUR3Qz2sYa6qmeWJfJPrfc-c4,20942
58
- pydantic_ai/models/huggingface.py,sha256=CMGpAzzaJ-xtDlNAM0IAx97fUagyEO84MMAncBYnwa0,20256
59
- pydantic_ai/models/instrumented.py,sha256=vVHO2sHkZnH7kcFr2iozOOuacfwGQYORhSgUtvDYZEU,16315
60
- pydantic_ai/models/mcp_sampling.py,sha256=0pAMCTkzmhQuyhik8KG2ZUYGVh4tofjdZBf6WdR78ik,3490
61
- pydantic_ai/models/mistral.py,sha256=-nB6VoHvNveLZHRCmXQaX9EFUJlFHXXt7nRyFtI2SIE,32251
62
- pydantic_ai/models/openai.py,sha256=Ozry-an08lai0aI-PmTuOA2dwpMwnFs3VG9xgaEu7EU,61246
63
- pydantic_ai/models/test.py,sha256=XKfJOwjnaMAuGpQwMT-H99vIicFymdJDpAtr0PU0Zoo,19151
49
+ pydantic_ai/models/__init__.py,sha256=h29lgKzOx8fHV0wXHMmaaawn8xGpAuFFxQwZJx4ihvU,34637
50
+ pydantic_ai/models/anthropic.py,sha256=WO-PGqtXZaFV9Oz9aHr-ADMc2qSr8TVep4tPmhWL_DI,30122
51
+ pydantic_ai/models/bedrock.py,sha256=z-qs8RikRxClbhDNsbRcuZ1GsPlb-GjoV88QD6vXOtE,30723
52
+ pydantic_ai/models/cohere.py,sha256=jZPMuFvNv9JTVCbC_p7_1Uxuc5WGn6RVFpH_pwG7iO0,13009
53
+ pydantic_ai/models/fallback.py,sha256=ftcYhl0oSOer0vYbLkaf7dfgI_3h0hk7hp07i1Wh9rI,5526
54
+ pydantic_ai/models/function.py,sha256=dY1aCUwcVXot5e2jWApWMAMnKWkSeEH4vqoe6mTBBZ0,14139
55
+ pydantic_ai/models/gemini.py,sha256=2KoN-sf5skHOkVcvbV5Zw4jGYanZX4n_K4jhyJVYK4U,39151
56
+ pydantic_ai/models/google.py,sha256=dMp1zJOWQFPH2unHDsuVEPoAAjER5u-iSHew0t9lD7o,30498
57
+ pydantic_ai/models/groq.py,sha256=kqegrHbeabp__jNwuib3k0vQTVpra7Gy3D_dwbH9vv8,20960
58
+ pydantic_ai/models/huggingface.py,sha256=JcYDfZbkYsQ9KUlDwfraiWq7dbg8Q0FRKkx8Lv9IWjg,20182
59
+ pydantic_ai/models/instrumented.py,sha256=wzdnuIIIgpMJ7zqhMf-S--ffg9YYEgn5WRkJE2cCwao,16307
60
+ pydantic_ai/models/mcp_sampling.py,sha256=iXIjwTP5Jszn0Iz-5MZiCk_BdUYE7IAxCnC5yIrGIu0,3436
61
+ pydantic_ai/models/mistral.py,sha256=jNkzlEgqD1n0Fb3Yy9CFnlQ-Oi7pe7ixhXokqfrQFqg,32208
62
+ pydantic_ai/models/openai.py,sha256=B6a2zDskBJITszwwmjncQLw4g9qAgZc5HgnlVhtGr7A,62939
63
+ pydantic_ai/models/test.py,sha256=7J9bZOBwqQ3X0f5PT0_JakMPSB5UmIZ5ZFlX8hH45NU,19089
64
64
  pydantic_ai/models/wrapper.py,sha256=9MeHW7mXPsEK03IKL0rtjeX6QgXyZROOOzLh72GiX2k,2148
65
65
  pydantic_ai/profiles/__init__.py,sha256=AdwFrK50_20qJBA_eMXXsV1vdGOvPxLVW82hMQvzXU0,3285
66
66
  pydantic_ai/profiles/_json_schema.py,sha256=CthOGmPSjgEZRRglfvg31zyQ9vjHDdacXoFpmba93dE,7206
@@ -74,7 +74,7 @@ pydantic_ai/profiles/groq.py,sha256=5jLNnOuxq3HTrbY-cizJyGa1hIluW7sCPLmDP1C1unc,
74
74
  pydantic_ai/profiles/meta.py,sha256=JdZcpdRWx8PY1pU9Z2i_TYtA0Cpbg23xyFrV7eXnooY,309
75
75
  pydantic_ai/profiles/mistral.py,sha256=ll01PmcK3szwlTfbaJLQmfd0TADN8lqjov9HpPJzCMQ,217
76
76
  pydantic_ai/profiles/moonshotai.py,sha256=e1RJnbEvazE6aJAqfmYLYGNtwNwg52XQDRDkcLrv3fU,272
77
- pydantic_ai/profiles/openai.py,sha256=YIzZAeJWO8dhmeHcOQk-Kyh6DUd5b0I5EQSTcK0-qy4,7564
77
+ pydantic_ai/profiles/openai.py,sha256=lSPM1tDiWVxQH45YzD_GjYsnkBzLankRFu5JRGfx81I,8112
78
78
  pydantic_ai/profiles/qwen.py,sha256=K4_nJ_oN5NS_9W0Fl-dFgC4emVRTHPXFTtiJ_nycKHo,373
79
79
  pydantic_ai/providers/__init__.py,sha256=-jb9Vl4gE7z0katqwLPaKt5UileuPp0Brq0ZueBVJys,4246
80
80
  pydantic_ai/providers/anthropic.py,sha256=D35UXxCPXv8yIbD0fj9Zg2FvNyoMoJMeDUtVM8Sn78I,3046
@@ -94,7 +94,7 @@ pydantic_ai/providers/huggingface.py,sha256=MLAv-Z99Kii5Faolq97_0Ir1LUKH9CwRmJFa
94
94
  pydantic_ai/providers/mistral.py,sha256=EIUSENjFuGzBhvbdrarUTM4VPkesIMnZrzfnEKHOsc4,3120
95
95
  pydantic_ai/providers/moonshotai.py,sha256=3BAE9eC9QaD3kblVwxtQWEln0-PhgK7bRvrYTCEYXbY,3471
96
96
  pydantic_ai/providers/ollama.py,sha256=GNrrjK02fRCv-3l09N2rl6tFTnGVbdDtfbu5j4Wggv8,4629
97
- pydantic_ai/providers/openai.py,sha256=7iGij0EaFylab7dTZAZDgXr78tr-HsZrn9EI9AkWBNQ,3091
97
+ pydantic_ai/providers/openai.py,sha256=xCpR2c7QnYQukiJJKiFTSaGSewPFht7ekTasJDjSimA,3071
98
98
  pydantic_ai/providers/openrouter.py,sha256=rSJwc_efQlOaGSxN5hjuemg-8llVCEGf5uZaeFwoQm8,4182
99
99
  pydantic_ai/providers/together.py,sha256=zFVSMSm5jXbpkNouvBOTjWrPmlPpCp6sQS5LMSyVjrQ,3482
100
100
  pydantic_ai/providers/vercel.py,sha256=wFIfyfD2RCAVRWtveDDMjumOkP8v9AHy94KV1HXF180,4285
@@ -109,8 +109,8 @@ pydantic_ai/toolsets/prefixed.py,sha256=0KwcDkW8OM36ZUsOLVP5h-Nj2tPq78L3_E2c-1Fb
109
109
  pydantic_ai/toolsets/prepared.py,sha256=Zjfz6S8In6PBVxoKFN9sKPN984zO6t0awB7Lnq5KODw,1431
110
110
  pydantic_ai/toolsets/renamed.py,sha256=JuLHpi-hYPiSPlaTpN8WiXLiGsywYK0axi2lW2Qs75k,1637
111
111
  pydantic_ai/toolsets/wrapper.py,sha256=mMuMPdko9PJUdcsexlRXbwViSwKKJfv6JE58d8HK3ds,1646
112
- pydantic_ai_slim-0.7.2.dist-info/METADATA,sha256=ibQxHaOvu0py9dGB6ALtmaIOpK23YHDxXINvJ92bjDE,4252
113
- pydantic_ai_slim-0.7.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
114
- pydantic_ai_slim-0.7.2.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
115
- pydantic_ai_slim-0.7.2.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
116
- pydantic_ai_slim-0.7.2.dist-info/RECORD,,
112
+ pydantic_ai_slim-0.7.3.dist-info/METADATA,sha256=mfpWSZ9tg3qLymgDpn5XJmX25DYIU9id6c0fMSpHeBc,4661
113
+ pydantic_ai_slim-0.7.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
114
+ pydantic_ai_slim-0.7.3.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
115
+ pydantic_ai_slim-0.7.3.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
116
+ pydantic_ai_slim-0.7.3.dist-info/RECORD,,