pydantic-ai-slim 0.0.19__py3-none-any.whl → 0.0.21__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/result.py CHANGED
@@ -11,35 +11,49 @@ import logfire_api
11
11
  from typing_extensions import TypeVar
12
12
 
13
13
  from . import _result, _utils, exceptions, messages as _messages, models
14
- from .tools import AgentDeps, RunContext
14
+ from .tools import AgentDepsT, RunContext
15
15
  from .usage import Usage, UsageLimits
16
16
 
17
- __all__ = 'ResultData', 'ResultValidatorFunc', 'RunResult', 'StreamedRunResult'
17
+ __all__ = 'ResultDataT', 'ResultDataT_inv', 'ResultValidatorFunc', 'RunResult', 'StreamedRunResult'
18
18
 
19
19
 
20
- ResultData = TypeVar('ResultData', default=str)
21
- """Type variable for the result data of a run."""
20
+ T = TypeVar('T')
21
+ """An invariant TypeVar."""
22
+ ResultDataT_inv = TypeVar('ResultDataT_inv', default=str)
23
+ """
24
+ An invariant type variable for the result data of a model.
25
+
26
+ We need to use an invariant typevar for `ResultValidator` and `ResultValidatorFunc` because the result data type is used
27
+ in both the input and output of a `ResultValidatorFunc`. This can theoretically lead to some issues assuming that types
28
+ possessing ResultValidator's are covariant in the result data type, but in practice this is rarely an issue, and
29
+ changing it would have negative consequences for the ergonomics of the library.
30
+
31
+ At some point, it may make sense to change the input to ResultValidatorFunc to be `Any` or `object` as doing that would
32
+ resolve these potential variance issues.
33
+ """
34
+ ResultDataT = TypeVar('ResultDataT', default=str, covariant=True)
35
+ """Covariant type variable for the result data type of a run."""
22
36
 
23
37
  ResultValidatorFunc = Union[
24
- Callable[[RunContext[AgentDeps], ResultData], ResultData],
25
- Callable[[RunContext[AgentDeps], ResultData], Awaitable[ResultData]],
26
- Callable[[ResultData], ResultData],
27
- Callable[[ResultData], Awaitable[ResultData]],
38
+ Callable[[RunContext[AgentDepsT], ResultDataT_inv], ResultDataT_inv],
39
+ Callable[[RunContext[AgentDepsT], ResultDataT_inv], Awaitable[ResultDataT_inv]],
40
+ Callable[[ResultDataT_inv], ResultDataT_inv],
41
+ Callable[[ResultDataT_inv], Awaitable[ResultDataT_inv]],
28
42
  ]
29
43
  """
30
- A function that always takes `ResultData` and returns `ResultData` and:
44
+ A function that always takes and returns the same type of data (which is the result type of an agent run), and:
31
45
 
32
46
  * may or may not take [`RunContext`][pydantic_ai.tools.RunContext] as a first argument
33
47
  * may or may not be async
34
48
 
35
- Usage `ResultValidatorFunc[AgentDeps, ResultData]`.
49
+ Usage `ResultValidatorFunc[AgentDepsT, T]`.
36
50
  """
37
51
 
38
52
  _logfire = logfire_api.Logfire(otel_scope='pydantic-ai')
39
53
 
40
54
 
41
55
  @dataclass
42
- class _BaseRunResult(ABC, Generic[ResultData]):
56
+ class _BaseRunResult(ABC, Generic[ResultDataT]):
43
57
  """Base type for results.
44
58
 
45
59
  You should not import or use this type directly, instead use its subclasses `RunResult` and `StreamedRunResult`.
@@ -119,10 +133,10 @@ class _BaseRunResult(ABC, Generic[ResultData]):
119
133
 
120
134
 
121
135
  @dataclass
122
- class RunResult(_BaseRunResult[ResultData]):
136
+ class RunResult(_BaseRunResult[ResultDataT]):
123
137
  """Result of a non-streamed run."""
124
138
 
125
- data: ResultData
139
+ data: ResultDataT
126
140
  """Data from the final response in the run."""
127
141
  _result_tool_name: str | None
128
142
  _usage: Usage
@@ -165,14 +179,14 @@ class RunResult(_BaseRunResult[ResultData]):
165
179
 
166
180
 
167
181
  @dataclass
168
- class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultData]):
182
+ class StreamedRunResult(_BaseRunResult[ResultDataT], Generic[AgentDepsT, ResultDataT]):
169
183
  """Result of a streamed run that returns structured data via a tool call."""
170
184
 
171
185
  _usage_limits: UsageLimits | None
172
186
  _stream_response: models.StreamedResponse
173
- _result_schema: _result.ResultSchema[ResultData] | None
174
- _run_ctx: RunContext[AgentDeps]
175
- _result_validators: list[_result.ResultValidator[AgentDeps, ResultData]]
187
+ _result_schema: _result.ResultSchema[ResultDataT] | None
188
+ _run_ctx: RunContext[AgentDepsT]
189
+ _result_validators: list[_result.ResultValidator[AgentDepsT, ResultDataT]]
176
190
  _result_tool_name: str | None
177
191
  _on_complete: Callable[[], Awaitable[None]]
178
192
  is_complete: bool = field(default=False, init=False)
@@ -185,7 +199,7 @@ class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultDat
185
199
  [`get_data`][pydantic_ai.result.StreamedRunResult.get_data] completes.
186
200
  """
187
201
 
188
- async def stream(self, *, debounce_by: float | None = 0.1) -> AsyncIterator[ResultData]:
202
+ async def stream(self, *, debounce_by: float | None = 0.1) -> AsyncIterator[ResultDataT]:
189
203
  """Stream the response as an async iterable.
190
204
 
191
205
  The pydantic validator for structured data will be called in
@@ -269,7 +283,12 @@ class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultDat
269
283
  yield combined_validated_text
270
284
 
271
285
  lf_span.set_attribute('combined_text', combined_validated_text)
272
- await self._marked_completed(_messages.ModelResponse.from_text(combined_validated_text))
286
+ await self._marked_completed(
287
+ _messages.ModelResponse(
288
+ parts=[_messages.TextPart(combined_validated_text)],
289
+ model_name=self._stream_response.model_name(),
290
+ )
291
+ )
273
292
 
274
293
  async def stream_structured(
275
294
  self, *, debounce_by: float | None = 0.1
@@ -306,7 +325,7 @@ class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultDat
306
325
  lf_span.set_attribute('structured_response', msg)
307
326
  await self._marked_completed(msg)
308
327
 
309
- async def get_data(self) -> ResultData:
328
+ async def get_data(self) -> ResultDataT:
310
329
  """Stream the whole response, validate and return it."""
311
330
  usage_checking_stream = _get_usage_checking_stream_response(
312
331
  self._stream_response, self._usage_limits, self.usage
@@ -332,7 +351,7 @@ class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultDat
332
351
 
333
352
  async def validate_structured_result(
334
353
  self, message: _messages.ModelResponse, *, allow_partial: bool = False
335
- ) -> ResultData:
354
+ ) -> ResultDataT:
336
355
  """Validate a structured result message."""
337
356
  if self._result_schema is not None and self._result_tool_name is not None:
338
357
  match = self._result_schema.find_named_tool(message.parts, self._result_tool_name)
@@ -351,17 +370,17 @@ class StreamedRunResult(_BaseRunResult[ResultData], Generic[AgentDeps, ResultDat
351
370
  text = '\n\n'.join(x.content for x in message.parts if isinstance(x, _messages.TextPart))
352
371
  for validator in self._result_validators:
353
372
  text = await validator.validate(
354
- text, # pyright: ignore[reportArgumentType]
373
+ text,
355
374
  None,
356
375
  self._run_ctx,
357
376
  )
358
- # Since there is no result tool, we can assume that str is compatible with ResultData
359
- return cast(ResultData, text)
377
+ # Since there is no result tool, we can assume that str is compatible with ResultDataT
378
+ return cast(ResultDataT, text)
360
379
 
361
380
  async def _validate_text_result(self, text: str) -> str:
362
381
  for validator in self._result_validators:
363
- text = await validator.validate( # pyright: ignore[reportAssignmentType]
364
- text, # pyright: ignore[reportArgumentType]
382
+ text = await validator.validate(
383
+ text,
365
384
  None,
366
385
  self._run_ctx,
367
386
  )
pydantic_ai/settings.py CHANGED
@@ -12,7 +12,8 @@ if TYPE_CHECKING:
12
12
  class ModelSettings(TypedDict, total=False):
13
13
  """Settings to configure an LLM.
14
14
 
15
- Here we include only settings which apply to multiple models / model providers.
15
+ Here we include only settings which apply to multiple models / model providers,
16
+ though not all of these settings are supported by all models.
16
17
  """
17
18
 
18
19
  max_tokens: int
@@ -24,6 +25,8 @@ class ModelSettings(TypedDict, total=False):
24
25
  * Anthropic
25
26
  * OpenAI
26
27
  * Groq
28
+ * Cohere
29
+ * Mistral
27
30
  """
28
31
 
29
32
  temperature: float
@@ -40,6 +43,8 @@ class ModelSettings(TypedDict, total=False):
40
43
  * Anthropic
41
44
  * OpenAI
42
45
  * Groq
46
+ * Cohere
47
+ * Mistral
43
48
  """
44
49
 
45
50
  top_p: float
@@ -55,6 +60,8 @@ class ModelSettings(TypedDict, total=False):
55
60
  * Anthropic
56
61
  * OpenAI
57
62
  * Groq
63
+ * Cohere
64
+ * Mistral
58
65
  """
59
66
 
60
67
  timeout: float | Timeout
@@ -66,6 +73,56 @@ class ModelSettings(TypedDict, total=False):
66
73
  * Anthropic
67
74
  * OpenAI
68
75
  * Groq
76
+ * Mistral
77
+ """
78
+
79
+ parallel_tool_calls: bool
80
+ """Whether to allow parallel tool calls.
81
+
82
+ Supported by:
83
+ * OpenAI (some models, not o1)
84
+ * Groq
85
+ * Anthropic
86
+ """
87
+
88
+ seed: int
89
+ """The random seed to use for the model, theoretically allowing for deterministic results.
90
+
91
+ Supported by:
92
+ * OpenAI
93
+ * Groq
94
+ * Cohere
95
+ * Mistral
96
+ """
97
+
98
+ presence_penalty: float
99
+ """Penalize new tokens based on whether they have appeared in the text so far.
100
+
101
+ Supported by:
102
+ * OpenAI
103
+ * Groq
104
+ * Cohere
105
+ * Gemini
106
+ * Mistral
107
+ """
108
+
109
+ frequency_penalty: float
110
+ """Penalize new tokens based on their existing frequency in the text so far.
111
+
112
+ Supported by:
113
+ * OpenAI
114
+ * Groq
115
+ * Cohere
116
+ * Gemini
117
+ * Mistral
118
+ """
119
+
120
+ logit_bias: dict[str, int]
121
+ """Modify the likelihood of specified tokens appearing in the completion.
122
+
123
+ Supported by:
124
+ * OpenAI
125
+ * Groq
69
126
  """
70
127
 
71
128
 
pydantic_ai/tools.py CHANGED
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
17
17
  from .result import Usage
18
18
 
19
19
  __all__ = (
20
- 'AgentDeps',
20
+ 'AgentDepsT',
21
21
  'DocstringFormat',
22
22
  'RunContext',
23
23
  'SystemPromptFunc',
@@ -31,15 +31,15 @@ __all__ = (
31
31
  'ToolDefinition',
32
32
  )
33
33
 
34
- AgentDeps = TypeVar('AgentDeps', default=None)
34
+ AgentDepsT = TypeVar('AgentDepsT', default=None, contravariant=True)
35
35
  """Type variable for agent dependencies."""
36
36
 
37
37
 
38
38
  @dataclasses.dataclass
39
- class RunContext(Generic[AgentDeps]):
39
+ class RunContext(Generic[AgentDepsT]):
40
40
  """Information about the current call."""
41
41
 
42
- deps: AgentDeps
42
+ deps: AgentDepsT
43
43
  """Dependencies for the agent."""
44
44
  model: models.Model
45
45
  """The model used in this run."""
@@ -58,7 +58,7 @@ class RunContext(Generic[AgentDeps]):
58
58
 
59
59
  def replace_with(
60
60
  self, retry: int | None = None, tool_name: str | None | _utils.Unset = _utils.UNSET
61
- ) -> RunContext[AgentDeps]:
61
+ ) -> RunContext[AgentDepsT]:
62
62
  # Create a new `RunContext` a new `retry` value and `tool_name`.
63
63
  kwargs = {}
64
64
  if retry is not None:
@@ -72,35 +72,35 @@ ToolParams = ParamSpec('ToolParams', default=...)
72
72
  """Retrieval function param spec."""
73
73
 
74
74
  SystemPromptFunc = Union[
75
- Callable[[RunContext[AgentDeps]], str],
76
- Callable[[RunContext[AgentDeps]], Awaitable[str]],
75
+ Callable[[RunContext[AgentDepsT]], str],
76
+ Callable[[RunContext[AgentDepsT]], Awaitable[str]],
77
77
  Callable[[], str],
78
78
  Callable[[], Awaitable[str]],
79
79
  ]
80
80
  """A function that may or maybe not take `RunContext` as an argument, and may or may not be async.
81
81
 
82
- Usage `SystemPromptFunc[AgentDeps]`.
82
+ Usage `SystemPromptFunc[AgentDepsT]`.
83
83
  """
84
84
 
85
- ToolFuncContext = Callable[Concatenate[RunContext[AgentDeps], ToolParams], Any]
85
+ ToolFuncContext = Callable[Concatenate[RunContext[AgentDepsT], ToolParams], Any]
86
86
  """A tool function that takes `RunContext` as the first argument.
87
87
 
88
- Usage `ToolContextFunc[AgentDeps, ToolParams]`.
88
+ Usage `ToolContextFunc[AgentDepsT, ToolParams]`.
89
89
  """
90
90
  ToolFuncPlain = Callable[ToolParams, Any]
91
91
  """A tool function that does not take `RunContext` as the first argument.
92
92
 
93
93
  Usage `ToolPlainFunc[ToolParams]`.
94
94
  """
95
- ToolFuncEither = Union[ToolFuncContext[AgentDeps, ToolParams], ToolFuncPlain[ToolParams]]
95
+ ToolFuncEither = Union[ToolFuncContext[AgentDepsT, ToolParams], ToolFuncPlain[ToolParams]]
96
96
  """Either kind of tool function.
97
97
 
98
98
  This is just a union of [`ToolFuncContext`][pydantic_ai.tools.ToolFuncContext] and
99
99
  [`ToolFuncPlain`][pydantic_ai.tools.ToolFuncPlain].
100
100
 
101
- Usage `ToolFuncEither[AgentDeps, ToolParams]`.
101
+ Usage `ToolFuncEither[AgentDepsT, ToolParams]`.
102
102
  """
103
- ToolPrepareFunc: TypeAlias = 'Callable[[RunContext[AgentDeps], ToolDefinition], Awaitable[ToolDefinition | None]]'
103
+ ToolPrepareFunc: TypeAlias = 'Callable[[RunContext[AgentDepsT], ToolDefinition], Awaitable[ToolDefinition | None]]'
104
104
  """Definition of a function that can prepare a tool definition at call time.
105
105
 
106
106
  See [tool docs](../tools.md#tool-prepare) for more information.
@@ -125,7 +125,7 @@ def hitchhiker(ctx: RunContext[int], answer: str) -> str:
125
125
  hitchhiker = Tool(hitchhiker, prepare=only_if_42)
126
126
  ```
127
127
 
128
- Usage `ToolPrepareFunc[AgentDeps]`.
128
+ Usage `ToolPrepareFunc[AgentDepsT]`.
129
129
  """
130
130
 
131
131
  DocstringFormat = Literal['google', 'numpy', 'sphinx', 'auto']
@@ -141,15 +141,15 @@ A = TypeVar('A')
141
141
 
142
142
 
143
143
  @dataclass(init=False)
144
- class Tool(Generic[AgentDeps]):
144
+ class Tool(Generic[AgentDepsT]):
145
145
  """A tool function for an agent."""
146
146
 
147
- function: ToolFuncEither[AgentDeps]
147
+ function: ToolFuncEither[AgentDepsT]
148
148
  takes_ctx: bool
149
149
  max_retries: int | None
150
150
  name: str
151
151
  description: str
152
- prepare: ToolPrepareFunc[AgentDeps] | None
152
+ prepare: ToolPrepareFunc[AgentDepsT] | None
153
153
  docstring_format: DocstringFormat
154
154
  require_parameter_descriptions: bool
155
155
  _is_async: bool = field(init=False)
@@ -158,17 +158,20 @@ class Tool(Generic[AgentDeps]):
158
158
  _var_positional_field: str | None = field(init=False)
159
159
  _validator: SchemaValidator = field(init=False, repr=False)
160
160
  _parameters_json_schema: ObjectJsonSchema = field(init=False)
161
+
162
+ # TODO: Move this state off the Tool class, which is otherwise stateless.
163
+ # This should be tracked inside a specific agent run, not the tool.
161
164
  current_retry: int = field(default=0, init=False)
162
165
 
163
166
  def __init__(
164
167
  self,
165
- function: ToolFuncEither[AgentDeps],
168
+ function: ToolFuncEither[AgentDepsT],
166
169
  *,
167
170
  takes_ctx: bool | None = None,
168
171
  max_retries: int | None = None,
169
172
  name: str | None = None,
170
173
  description: str | None = None,
171
- prepare: ToolPrepareFunc[AgentDeps] | None = None,
174
+ prepare: ToolPrepareFunc[AgentDepsT] | None = None,
172
175
  docstring_format: DocstringFormat = 'auto',
173
176
  require_parameter_descriptions: bool = False,
174
177
  ):
@@ -240,7 +243,7 @@ class Tool(Generic[AgentDeps]):
240
243
  self._validator = f['validator']
241
244
  self._parameters_json_schema = f['json_schema']
242
245
 
243
- async def prepare_tool_def(self, ctx: RunContext[AgentDeps]) -> ToolDefinition | None:
246
+ async def prepare_tool_def(self, ctx: RunContext[AgentDepsT]) -> ToolDefinition | None:
244
247
  """Get the tool definition.
245
248
 
246
249
  By default, this method creates a tool definition, then either returns it, or calls `self.prepare`
@@ -260,14 +263,14 @@ class Tool(Generic[AgentDeps]):
260
263
  return tool_def
261
264
 
262
265
  async def run(
263
- self, message: _messages.ToolCallPart, run_context: RunContext[AgentDeps]
264
- ) -> _messages.ModelRequestPart:
266
+ self, message: _messages.ToolCallPart, run_context: RunContext[AgentDepsT]
267
+ ) -> _messages.ToolReturnPart | _messages.RetryPromptPart:
265
268
  """Run the tool function asynchronously."""
266
269
  try:
267
- if isinstance(message.args, _messages.ArgsJson):
268
- args_dict = self._validator.validate_json(message.args.args_json)
270
+ if isinstance(message.args, str):
271
+ args_dict = self._validator.validate_json(message.args)
269
272
  else:
270
- args_dict = self._validator.validate_python(message.args.args_dict)
273
+ args_dict = self._validator.validate_python(message.args)
271
274
  except ValidationError as e:
272
275
  return self._on_error(e, message)
273
276
 
@@ -293,7 +296,7 @@ class Tool(Generic[AgentDeps]):
293
296
  self,
294
297
  args_dict: dict[str, Any],
295
298
  message: _messages.ToolCallPart,
296
- run_context: RunContext[AgentDeps],
299
+ run_context: RunContext[AgentDepsT],
297
300
  ) -> tuple[list[Any], dict[str, Any]]:
298
301
  if self._single_arg_name:
299
302
  args_dict = {self._single_arg_name: args_dict}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.0.19
3
+ Version: 0.0.21
4
4
  Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
5
5
  Author-email: Samuel Colvin <samuel@pydantic.dev>
6
6
  License-Expression: MIT
@@ -26,13 +26,15 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Requires-Python: >=3.9
27
27
  Requires-Dist: eval-type-backport>=0.2.0
28
28
  Requires-Dist: griffe>=1.3.2
29
- Requires-Dist: httpx>=0.27.2
29
+ Requires-Dist: httpx>=0.27
30
30
  Requires-Dist: logfire-api>=1.2.0
31
31
  Requires-Dist: pydantic>=2.10
32
32
  Provides-Extra: anthropic
33
33
  Requires-Dist: anthropic>=0.40.0; extra == 'anthropic'
34
+ Provides-Extra: cohere
35
+ Requires-Dist: cohere>=5.13.11; extra == 'cohere'
34
36
  Provides-Extra: graph
35
- Requires-Dist: pydantic-graph==0.0.19; extra == 'graph'
37
+ Requires-Dist: pydantic-graph==0.0.21; extra == 'graph'
36
38
  Provides-Extra: groq
37
39
  Requires-Dist: groq>=0.12.0; extra == 'groq'
38
40
  Provides-Extra: logfire
@@ -40,7 +42,7 @@ Requires-Dist: logfire>=2.3; extra == 'logfire'
40
42
  Provides-Extra: mistral
41
43
  Requires-Dist: mistralai>=1.2.5; extra == 'mistral'
42
44
  Provides-Extra: openai
43
- Requires-Dist: openai>=1.54.3; extra == 'openai'
45
+ Requires-Dist: openai>=1.59.0; extra == 'openai'
44
46
  Provides-Extra: vertexai
45
47
  Requires-Dist: google-auth>=2.36.0; extra == 'vertexai'
46
48
  Requires-Dist: requests>=2.32.3; extra == 'vertexai'
@@ -0,0 +1,29 @@
1
+ pydantic_ai/__init__.py,sha256=FbYetEgT6OO25u2KF5ZnFxKpz5DtnSpfckRXP4mjl8E,489
2
+ pydantic_ai/_griffe.py,sha256=RYRKiLbgG97QxnazbAwlnc74XxevGHLQet-FGfq9qls,3960
3
+ pydantic_ai/_parts_manager.py,sha256=ARfDQY1_5AIY5rNl_M2fAYHEFCe03ZxdhgjHf9qeIKw,11872
4
+ pydantic_ai/_pydantic.py,sha256=dROz3Hmfdi0C2exq88FhefDRVo_8S3rtkXnoUHzsz0c,8753
5
+ pydantic_ai/_result.py,sha256=tN1pVulf_EM4bkBvpNUWPnUXezLY-sBrJEVCFdy2nLU,10264
6
+ pydantic_ai/_system_prompt.py,sha256=602c2jyle2R_SesOrITBDETZqsLk4BZ8Cbo8yEhmx04,1120
7
+ pydantic_ai/_utils.py,sha256=zfuY3NiPPsSM5J1q2JElfbfIa8S1ONGOlC7M-iyBVso,9430
8
+ pydantic_ai/agent.py,sha256=7o7yfatFPBDkrpSi2t0A4xivX7lzlNbOhtIMEJQpLKc,63620
9
+ pydantic_ai/exceptions.py,sha256=eGDKX6bGhgVxXBzu81Sk3iiAkXr0GUtgT7bD5Rxlqpg,2028
10
+ pydantic_ai/format_as_xml.py,sha256=QE7eMlg5-YUMw1_2kcI3h0uKYPZZyGkgXFDtfZTMeeI,4480
11
+ pydantic_ai/messages.py,sha256=kzXn4ZjlX9Sy2KXgFHWYbbwPk7TzTPdztzOJLWEONwU,17101
12
+ pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ pydantic_ai/result.py,sha256=0beXiUfiSb2kVc68iqLeg2qFQW6-mnTC8TFtiQayPDQ,18394
14
+ pydantic_ai/settings.py,sha256=QSqs4_l_Gs2v4oixYNwKQhPiec_m9pn6XEAeUMFxt24,3054
15
+ pydantic_ai/tools.py,sha256=lhupwm815lPlFFS79B0P61AyhUYtepA62LbZOCJrPEY,13205
16
+ pydantic_ai/usage.py,sha256=60d9f6M7YEYuKMbqDGDogX4KsA73fhDtWyDXYXoIPaI,4948
17
+ pydantic_ai/models/__init__.py,sha256=XgZAhiSVVX0TbePHXSxVnDIbG38jQG9g3WRMlA_EHDY,13063
18
+ pydantic_ai/models/anthropic.py,sha256=v2m6zjaezLjtkHO2Rx67rmoN1iOqDeAp9fswJcqRMBA,16967
19
+ pydantic_ai/models/cohere.py,sha256=wyjtD2uwkYYbsXLKwr-flmXSng_Atd-0jqtVDxDie14,10611
20
+ pydantic_ai/models/function.py,sha256=jv2aw5K4KrMIRPFSTiGbBHcv16UZtGEe_1irjTudLg0,9826
21
+ pydantic_ai/models/gemini.py,sha256=espBJbEMZjdzT5fC_rKOHoo_5o5xH-Y1Ea-RZR4JaPs,28222
22
+ pydantic_ai/models/groq.py,sha256=W-uosi9PtvgXp8yoF6w8QZxPtrVjX1fmRQDjQQ10meE,13603
23
+ pydantic_ai/models/mistral.py,sha256=RuRlxTBPGXIpcwTdjX2596uN2tgHBvCDQCWieWa1A_Q,24793
24
+ pydantic_ai/models/openai.py,sha256=6ymsBzyu9WJVewbn3345jt_JoXpUpCLYOQERYJJlyRY,15228
25
+ pydantic_ai/models/test.py,sha256=D_wBpRtrPcikopd5LBYjdAp3q-1gvuB9WnuopBQiRME,16659
26
+ pydantic_ai/models/vertexai.py,sha256=bQZ5W8n4521AH3jTiyP1fOYxtNgCgkhjCbBeASv5Ap8,9388
27
+ pydantic_ai_slim-0.0.21.dist-info/METADATA,sha256=EeGz0ZJG_g_o7xKu-2XiXN2zZsBhGZLwL39QaQGZQdc,2879
28
+ pydantic_ai_slim-0.0.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
+ pydantic_ai_slim-0.0.21.dist-info/RECORD,,
@@ -1,120 +0,0 @@
1
- from __future__ import annotations as _annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import Literal, Union
5
-
6
- from httpx import AsyncClient as AsyncHTTPClient
7
-
8
- from ..tools import ToolDefinition
9
- from . import (
10
- AgentModel,
11
- Model,
12
- cached_async_http_client,
13
- )
14
-
15
- try:
16
- from openai import AsyncOpenAI
17
- except ImportError as e:
18
- raise ImportError(
19
- 'Please install `openai` to use the OpenAI model, '
20
- "you can use the `openai` optional group — `pip install 'pydantic-ai-slim[openai]'`"
21
- ) from e
22
-
23
-
24
- from .openai import OpenAIModel
25
-
26
- CommonOllamaModelNames = Literal[
27
- 'codellama',
28
- 'gemma',
29
- 'gemma2',
30
- 'llama3',
31
- 'llama3.1',
32
- 'llama3.2',
33
- 'llama3.2-vision',
34
- 'llama3.3',
35
- 'mistral',
36
- 'mistral-nemo',
37
- 'mixtral',
38
- 'phi3',
39
- 'phi4',
40
- 'qwq',
41
- 'qwen',
42
- 'qwen2',
43
- 'qwen2.5',
44
- 'starcoder2',
45
- ]
46
- """This contains just the most common ollama models.
47
-
48
- For a full list see [ollama.com/library](https://ollama.com/library).
49
- """
50
- OllamaModelName = Union[CommonOllamaModelNames, str]
51
- """Possible ollama models.
52
-
53
- Since Ollama supports hundreds of models, we explicitly list the most models but
54
- allow any name in the type hints.
55
- """
56
-
57
-
58
- @dataclass(init=False)
59
- class OllamaModel(Model):
60
- """A model that implements Ollama using the OpenAI API.
61
-
62
- Internally, this uses the [OpenAI Python client](https://github.com/openai/openai-python) to interact with the Ollama server.
63
-
64
- Apart from `__init__`, all methods are private or match those of the base class.
65
- """
66
-
67
- model_name: OllamaModelName
68
- openai_model: OpenAIModel
69
-
70
- def __init__(
71
- self,
72
- model_name: OllamaModelName,
73
- *,
74
- base_url: str | None = 'http://localhost:11434/v1/',
75
- api_key: str = 'ollama',
76
- openai_client: AsyncOpenAI | None = None,
77
- http_client: AsyncHTTPClient | None = None,
78
- ):
79
- """Initialize an Ollama model.
80
-
81
- Ollama has built-in compatability for the OpenAI chat completions API ([source](https://ollama.com/blog/openai-compatibility)), so we reuse the
82
- [`OpenAIModel`][pydantic_ai.models.openai.OpenAIModel] here.
83
-
84
- Args:
85
- model_name: The name of the Ollama model to use. List of models available [here](https://ollama.com/library)
86
- You must first download the model (`ollama pull <MODEL-NAME>`) in order to use the model
87
- base_url: The base url for the ollama requests. The default value is the ollama default
88
- api_key: The API key to use for authentication. Defaults to 'ollama' for local instances,
89
- but can be customized for proxy setups that require authentication
90
- openai_client: An existing
91
- [`AsyncOpenAI`](https://github.com/openai/openai-python?tab=readme-ov-file#async-usage)
92
- client to use, if provided, `base_url` and `http_client` must be `None`.
93
- http_client: An existing `httpx.AsyncClient` to use for making HTTP requests.
94
- """
95
- self.model_name = model_name
96
- if openai_client is not None:
97
- assert base_url is None, 'Cannot provide both `openai_client` and `base_url`'
98
- assert http_client is None, 'Cannot provide both `openai_client` and `http_client`'
99
- self.openai_model = OpenAIModel(model_name=model_name, openai_client=openai_client)
100
- else:
101
- # API key is not required for ollama but a value is required to create the client
102
- http_client_ = http_client or cached_async_http_client()
103
- oai_client = AsyncOpenAI(base_url=base_url, api_key=api_key, http_client=http_client_)
104
- self.openai_model = OpenAIModel(model_name=model_name, openai_client=oai_client)
105
-
106
- async def agent_model(
107
- self,
108
- *,
109
- function_tools: list[ToolDefinition],
110
- allow_text_result: bool,
111
- result_tools: list[ToolDefinition],
112
- ) -> AgentModel:
113
- return await self.openai_model.agent_model(
114
- function_tools=function_tools,
115
- allow_text_result=allow_text_result,
116
- result_tools=result_tools,
117
- )
118
-
119
- def name(self) -> str:
120
- return f'ollama:{self.model_name}'
@@ -1,29 +0,0 @@
1
- pydantic_ai/__init__.py,sha256=FbYetEgT6OO25u2KF5ZnFxKpz5DtnSpfckRXP4mjl8E,489
2
- pydantic_ai/_griffe.py,sha256=RYRKiLbgG97QxnazbAwlnc74XxevGHLQet-FGfq9qls,3960
3
- pydantic_ai/_parts_manager.py,sha256=pMDZs6BGC8EmaNa-73QvuptmxdG2MhBrBLIydCOl-gM,11886
4
- pydantic_ai/_pydantic.py,sha256=Zvjd2te6EzPrFnz--oDSdqwZuPw3vCiflTHriRhpNsY,8698
5
- pydantic_ai/_result.py,sha256=cUSugZQV0n5Z4fFHiMqua-2xs_0S6m-rr-yd6QS3nFE,10317
6
- pydantic_ai/_system_prompt.py,sha256=Fsl1K6GdQP0WhWBzvJxCc5uTqCD06lHjJlTADah-PI0,1116
7
- pydantic_ai/_utils.py,sha256=EHW866W6ZpGJLCWtoEAcwIPeWo9OQFhnD5el2DwVcwc,10949
8
- pydantic_ai/agent.py,sha256=Z_79gw4BIJooBIqJwPbnDHvmBcCXp2dbNd_832tc_do,62500
9
- pydantic_ai/exceptions.py,sha256=eGDKX6bGhgVxXBzu81Sk3iiAkXr0GUtgT7bD5Rxlqpg,2028
10
- pydantic_ai/format_as_xml.py,sha256=QE7eMlg5-YUMw1_2kcI3h0uKYPZZyGkgXFDtfZTMeeI,4480
11
- pydantic_ai/messages.py,sha256=b4RpaXogREquE8WHlGPMm0UGTNx2QtePV5GYk-9EscY,18185
12
- pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- pydantic_ai/result.py,sha256=93ZLxr2jPx0cZeslHgphJ6XJnQMEybktzQ_LUT47h3Q,17429
14
- pydantic_ai/settings.py,sha256=oTk8ZfYuUsNxpJMWLvSrO1OH_0ur7VKgDNTMQG0tPyM,1974
15
- pydantic_ai/tools.py,sha256=iwa2PyhnKmvh_njy4aMfRIh7AP5igDIZ1ZPvgvvn6bM,13018
16
- pydantic_ai/usage.py,sha256=60d9f6M7YEYuKMbqDGDogX4KsA73fhDtWyDXYXoIPaI,4948
17
- pydantic_ai/models/__init__.py,sha256=Q4_fHy48szaA_TrIW3LZhRXiDUlhPAYf8LkhinSP3s8,10883
18
- pydantic_ai/models/anthropic.py,sha256=MkFqy2F7SPb_qAbgzc04iZWmVuoEBgn30v1HY1Wjadc,13543
19
- pydantic_ai/models/function.py,sha256=iT4XT8VEaJbNwYJAWtrI_jbRAb2tZO6UL93ErR4RYhM,9629
20
- pydantic_ai/models/gemini.py,sha256=3RTVQBAI1jWL3Xx_hi7qdy_6H-kTeuAOTPELnlVtPp4,27498
21
- pydantic_ai/models/groq.py,sha256=kzQSFT-04WmQmdRaB6Wj0mxHeAXIgyrryZkptNiA4Ng,13211
22
- pydantic_ai/models/mistral.py,sha256=qyYOLBpOdI5iPBmQxf5jp1d17sxqa1r8GJ7tb4yE45U,24549
23
- pydantic_ai/models/ollama.py,sha256=aHI8pNw7fqOOgvlEWcTnTYTmhf0cGg41x-p5sUQr2_k,4200
24
- pydantic_ai/models/openai.py,sha256=FzV6OCuK4Sr_J2GTuM-6Vu9NbDyZPxllwQPmssdOtbQ,13774
25
- pydantic_ai/models/test.py,sha256=0m2Pdn0xJMjvAVekVIoADQL0aSkOnGZJct9k4WvImrQ,15880
26
- pydantic_ai/models/vertexai.py,sha256=dHGrmLMgekWAEOZkLsO5rwDtQ6mjPixvn0umlvWAZok,9323
27
- pydantic_ai_slim-0.0.19.dist-info/METADATA,sha256=lnGlda0-tCapsWI72DyzGV9Sppm5I7koWbb7-xEpWcU,2808
28
- pydantic_ai_slim-0.0.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
- pydantic_ai_slim-0.0.19.dist-info/RECORD,,