pydantic-ai-slim 0.4.2__py3-none-any.whl → 0.4.4__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/_agent_graph.py +219 -315
- pydantic_ai/_cli.py +9 -7
- pydantic_ai/_output.py +296 -226
- pydantic_ai/_parts_manager.py +2 -2
- pydantic_ai/_run_context.py +8 -14
- pydantic_ai/_tool_manager.py +190 -0
- pydantic_ai/_utils.py +18 -1
- pydantic_ai/ag_ui.py +675 -0
- pydantic_ai/agent.py +369 -155
- pydantic_ai/common_tools/duckduckgo.py +5 -2
- pydantic_ai/exceptions.py +14 -2
- pydantic_ai/ext/aci.py +12 -3
- pydantic_ai/ext/langchain.py +9 -1
- pydantic_ai/mcp.py +147 -84
- pydantic_ai/messages.py +19 -9
- pydantic_ai/models/__init__.py +43 -19
- pydantic_ai/models/anthropic.py +2 -2
- pydantic_ai/models/bedrock.py +1 -1
- pydantic_ai/models/cohere.py +1 -1
- pydantic_ai/models/function.py +50 -24
- pydantic_ai/models/gemini.py +3 -11
- pydantic_ai/models/google.py +3 -12
- pydantic_ai/models/groq.py +2 -1
- pydantic_ai/models/huggingface.py +463 -0
- pydantic_ai/models/instrumented.py +1 -1
- pydantic_ai/models/mistral.py +3 -3
- pydantic_ai/models/openai.py +5 -5
- pydantic_ai/output.py +21 -7
- pydantic_ai/profiles/google.py +1 -1
- pydantic_ai/profiles/moonshotai.py +8 -0
- pydantic_ai/providers/__init__.py +4 -0
- pydantic_ai/providers/google.py +2 -2
- pydantic_ai/providers/google_vertex.py +10 -5
- pydantic_ai/providers/grok.py +13 -1
- pydantic_ai/providers/groq.py +2 -0
- pydantic_ai/providers/huggingface.py +88 -0
- pydantic_ai/result.py +57 -33
- pydantic_ai/tools.py +26 -119
- pydantic_ai/toolsets/__init__.py +22 -0
- pydantic_ai/toolsets/abstract.py +155 -0
- pydantic_ai/toolsets/combined.py +88 -0
- pydantic_ai/toolsets/deferred.py +38 -0
- pydantic_ai/toolsets/filtered.py +24 -0
- pydantic_ai/toolsets/function.py +238 -0
- pydantic_ai/toolsets/prefixed.py +37 -0
- pydantic_ai/toolsets/prepared.py +36 -0
- pydantic_ai/toolsets/renamed.py +42 -0
- pydantic_ai/toolsets/wrapper.py +37 -0
- pydantic_ai/usage.py +14 -8
- {pydantic_ai_slim-0.4.2.dist-info → pydantic_ai_slim-0.4.4.dist-info}/METADATA +13 -8
- pydantic_ai_slim-0.4.4.dist-info/RECORD +98 -0
- pydantic_ai_slim-0.4.2.dist-info/RECORD +0 -83
- {pydantic_ai_slim-0.4.2.dist-info → pydantic_ai_slim-0.4.4.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-0.4.2.dist-info → pydantic_ai_slim-0.4.4.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-0.4.2.dist-info → pydantic_ai_slim-0.4.4.dist-info}/licenses/LICENSE +0 -0
pydantic_ai/models/__init__.py
CHANGED
|
@@ -134,31 +134,15 @@ KnownModelName = TypeAliasType(
|
|
|
134
134
|
'cohere:command-r7b-12-2024',
|
|
135
135
|
'deepseek:deepseek-chat',
|
|
136
136
|
'deepseek:deepseek-reasoner',
|
|
137
|
-
'google-gla:gemini-1.5-flash',
|
|
138
|
-
'google-gla:gemini-1.5-flash-8b',
|
|
139
|
-
'google-gla:gemini-1.5-pro',
|
|
140
|
-
'google-gla:gemini-1.0-pro',
|
|
141
137
|
'google-gla:gemini-2.0-flash',
|
|
142
|
-
'google-gla:gemini-2.0-flash-lite
|
|
143
|
-
'google-gla:gemini-2.0-pro-exp-02-05',
|
|
144
|
-
'google-gla:gemini-2.5-flash-preview-05-20',
|
|
138
|
+
'google-gla:gemini-2.0-flash-lite',
|
|
145
139
|
'google-gla:gemini-2.5-flash',
|
|
146
140
|
'google-gla:gemini-2.5-flash-lite-preview-06-17',
|
|
147
|
-
'google-gla:gemini-2.5-pro-exp-03-25',
|
|
148
|
-
'google-gla:gemini-2.5-pro-preview-05-06',
|
|
149
141
|
'google-gla:gemini-2.5-pro',
|
|
150
|
-
'google-vertex:gemini-1.5-flash',
|
|
151
|
-
'google-vertex:gemini-1.5-flash-8b',
|
|
152
|
-
'google-vertex:gemini-1.5-pro',
|
|
153
|
-
'google-vertex:gemini-1.0-pro',
|
|
154
142
|
'google-vertex:gemini-2.0-flash',
|
|
155
|
-
'google-vertex:gemini-2.0-flash-lite
|
|
156
|
-
'google-vertex:gemini-2.0-pro-exp-02-05',
|
|
157
|
-
'google-vertex:gemini-2.5-flash-preview-05-20',
|
|
143
|
+
'google-vertex:gemini-2.0-flash-lite',
|
|
158
144
|
'google-vertex:gemini-2.5-flash',
|
|
159
145
|
'google-vertex:gemini-2.5-flash-lite-preview-06-17',
|
|
160
|
-
'google-vertex:gemini-2.5-pro-exp-03-25',
|
|
161
|
-
'google-vertex:gemini-2.5-pro-preview-05-06',
|
|
162
146
|
'google-vertex:gemini-2.5-pro',
|
|
163
147
|
'gpt-3.5-turbo',
|
|
164
148
|
'gpt-3.5-turbo-0125',
|
|
@@ -192,6 +176,7 @@ KnownModelName = TypeAliasType(
|
|
|
192
176
|
'gpt-4o-audio-preview',
|
|
193
177
|
'gpt-4o-audio-preview-2024-10-01',
|
|
194
178
|
'gpt-4o-audio-preview-2024-12-17',
|
|
179
|
+
'gpt-4o-audio-preview-2025-06-03',
|
|
195
180
|
'gpt-4o-mini',
|
|
196
181
|
'gpt-4o-mini-2024-07-18',
|
|
197
182
|
'gpt-4o-mini-audio-preview',
|
|
@@ -200,6 +185,14 @@ KnownModelName = TypeAliasType(
|
|
|
200
185
|
'gpt-4o-mini-search-preview-2025-03-11',
|
|
201
186
|
'gpt-4o-search-preview',
|
|
202
187
|
'gpt-4o-search-preview-2025-03-11',
|
|
188
|
+
'grok:grok-4',
|
|
189
|
+
'grok:grok-4-0709',
|
|
190
|
+
'grok:grok-3',
|
|
191
|
+
'grok:grok-3-mini',
|
|
192
|
+
'grok:grok-3-fast',
|
|
193
|
+
'grok:grok-3-mini-fast',
|
|
194
|
+
'grok:grok-2-vision-1212',
|
|
195
|
+
'grok:grok-2-image-1212',
|
|
203
196
|
'groq:distil-whisper-large-v3-en',
|
|
204
197
|
'groq:gemma2-9b-it',
|
|
205
198
|
'groq:llama-3.3-70b-versatile',
|
|
@@ -207,6 +200,7 @@ KnownModelName = TypeAliasType(
|
|
|
207
200
|
'groq:llama-guard-3-8b',
|
|
208
201
|
'groq:llama3-70b-8192',
|
|
209
202
|
'groq:llama3-8b-8192',
|
|
203
|
+
'groq:moonshotai/kimi-k2-instruct',
|
|
210
204
|
'groq:whisper-large-v3',
|
|
211
205
|
'groq:whisper-large-v3-turbo',
|
|
212
206
|
'groq:playai-tts',
|
|
@@ -227,6 +221,14 @@ KnownModelName = TypeAliasType(
|
|
|
227
221
|
'heroku:claude-3-7-sonnet',
|
|
228
222
|
'heroku:claude-4-sonnet',
|
|
229
223
|
'heroku:claude-3-haiku',
|
|
224
|
+
'huggingface:Qwen/QwQ-32B',
|
|
225
|
+
'huggingface:Qwen/Qwen2.5-72B-Instruct',
|
|
226
|
+
'huggingface:Qwen/Qwen3-235B-A22B',
|
|
227
|
+
'huggingface:Qwen/Qwen3-32B',
|
|
228
|
+
'huggingface:deepseek-ai/DeepSeek-R1',
|
|
229
|
+
'huggingface:meta-llama/Llama-3.3-70B-Instruct',
|
|
230
|
+
'huggingface:meta-llama/Llama-4-Maverick-17B-128E-Instruct',
|
|
231
|
+
'huggingface:meta-llama/Llama-4-Scout-17B-16E-Instruct',
|
|
230
232
|
'mistral:codestral-latest',
|
|
231
233
|
'mistral:mistral-large-latest',
|
|
232
234
|
'mistral:mistral-moderation-latest',
|
|
@@ -237,11 +239,18 @@ KnownModelName = TypeAliasType(
|
|
|
237
239
|
'o1-mini-2024-09-12',
|
|
238
240
|
'o1-preview',
|
|
239
241
|
'o1-preview-2024-09-12',
|
|
242
|
+
'o1-pro',
|
|
243
|
+
'o1-pro-2025-03-19',
|
|
240
244
|
'o3',
|
|
241
245
|
'o3-2025-04-16',
|
|
246
|
+
'o3-deep-research',
|
|
247
|
+
'o3-deep-research-2025-06-26',
|
|
242
248
|
'o3-mini',
|
|
243
249
|
'o3-mini-2025-01-31',
|
|
250
|
+
'o3-pro',
|
|
251
|
+
'o3-pro-2025-06-10',
|
|
244
252
|
'openai:chatgpt-4o-latest',
|
|
253
|
+
'openai:codex-mini-latest',
|
|
245
254
|
'openai:gpt-3.5-turbo',
|
|
246
255
|
'openai:gpt-3.5-turbo-0125',
|
|
247
256
|
'openai:gpt-3.5-turbo-0301',
|
|
@@ -274,6 +283,7 @@ KnownModelName = TypeAliasType(
|
|
|
274
283
|
'openai:gpt-4o-audio-preview',
|
|
275
284
|
'openai:gpt-4o-audio-preview-2024-10-01',
|
|
276
285
|
'openai:gpt-4o-audio-preview-2024-12-17',
|
|
286
|
+
'openai:gpt-4o-audio-preview-2025-06-03',
|
|
277
287
|
'openai:gpt-4o-mini',
|
|
278
288
|
'openai:gpt-4o-mini-2024-07-18',
|
|
279
289
|
'openai:gpt-4o-mini-audio-preview',
|
|
@@ -288,12 +298,22 @@ KnownModelName = TypeAliasType(
|
|
|
288
298
|
'openai:o1-mini-2024-09-12',
|
|
289
299
|
'openai:o1-preview',
|
|
290
300
|
'openai:o1-preview-2024-09-12',
|
|
301
|
+
'openai:o1-pro',
|
|
302
|
+
'openai:o1-pro-2025-03-19',
|
|
291
303
|
'openai:o3',
|
|
292
304
|
'openai:o3-2025-04-16',
|
|
305
|
+
'openai:o3-deep-research',
|
|
306
|
+
'openai:o3-deep-research-2025-06-26',
|
|
293
307
|
'openai:o3-mini',
|
|
294
308
|
'openai:o3-mini-2025-01-31',
|
|
295
309
|
'openai:o4-mini',
|
|
296
310
|
'openai:o4-mini-2025-04-16',
|
|
311
|
+
'openai:o4-mini-deep-research',
|
|
312
|
+
'openai:o4-mini-deep-research-2025-06-26',
|
|
313
|
+
'openai:o3-pro',
|
|
314
|
+
'openai:o3-pro-2025-06-10',
|
|
315
|
+
'openai:computer-use-preview',
|
|
316
|
+
'openai:computer-use-preview-2025-03-11',
|
|
297
317
|
'test',
|
|
298
318
|
],
|
|
299
319
|
)
|
|
@@ -560,7 +580,7 @@ def override_allow_model_requests(allow_model_requests: bool) -> Iterator[None]:
|
|
|
560
580
|
ALLOW_MODEL_REQUESTS = old_value # pyright: ignore[reportConstantRedefinition]
|
|
561
581
|
|
|
562
582
|
|
|
563
|
-
def infer_model(model: Model | KnownModelName | str) -> Model:
|
|
583
|
+
def infer_model(model: Model | KnownModelName | str) -> Model: # noqa: C901
|
|
564
584
|
"""Infer the model from the name."""
|
|
565
585
|
if isinstance(model, Model):
|
|
566
586
|
return model
|
|
@@ -624,6 +644,10 @@ def infer_model(model: Model | KnownModelName | str) -> Model:
|
|
|
624
644
|
from .bedrock import BedrockConverseModel
|
|
625
645
|
|
|
626
646
|
return BedrockConverseModel(model_name, provider=provider)
|
|
647
|
+
elif provider == 'huggingface':
|
|
648
|
+
from .huggingface import HuggingFaceModel
|
|
649
|
+
|
|
650
|
+
return HuggingFaceModel(model_name, provider=provider)
|
|
627
651
|
else:
|
|
628
652
|
raise UserError(f'Unknown model: {model}') # pragma: no cover
|
|
629
653
|
|
pydantic_ai/models/anthropic.py
CHANGED
|
@@ -256,7 +256,7 @@ class AnthropicModel(Model):
|
|
|
256
256
|
except APIStatusError as e:
|
|
257
257
|
if (status_code := e.status_code) >= 400:
|
|
258
258
|
raise ModelHTTPError(status_code=status_code, model_name=self.model_name, body=e.body) from e
|
|
259
|
-
raise # pragma:
|
|
259
|
+
raise # pragma: no cover
|
|
260
260
|
|
|
261
261
|
def _process_response(self, response: BetaMessage) -> ModelResponse:
|
|
262
262
|
"""Process a non-streamed response, and prepare a message to return."""
|
|
@@ -266,7 +266,7 @@ class AnthropicModel(Model):
|
|
|
266
266
|
items.append(TextPart(content=item.text))
|
|
267
267
|
elif isinstance(item, BetaRedactedThinkingBlock): # pragma: no cover
|
|
268
268
|
warnings.warn(
|
|
269
|
-
'
|
|
269
|
+
'Pydantic AI currently does not handle redacted thinking blocks. '
|
|
270
270
|
'If you have a suggestion on how we should handle them, please open an issue.',
|
|
271
271
|
UserWarning,
|
|
272
272
|
)
|
pydantic_ai/models/bedrock.py
CHANGED
pydantic_ai/models/cohere.py
CHANGED
|
@@ -183,7 +183,7 @@ class CohereModel(Model):
|
|
|
183
183
|
except ApiError as e:
|
|
184
184
|
if (status_code := e.status_code) and status_code >= 400:
|
|
185
185
|
raise ModelHTTPError(status_code=status_code, model_name=self.model_name, body=e.body) from e
|
|
186
|
-
raise # pragma:
|
|
186
|
+
raise # pragma: no cover
|
|
187
187
|
|
|
188
188
|
def _process_response(self, response: ChatResponse) -> ModelResponse:
|
|
189
189
|
"""Process a non-streamed response, and prepare a message to return."""
|
pydantic_ai/models/function.py
CHANGED
|
@@ -214,21 +214,39 @@ class DeltaToolCall:
|
|
|
214
214
|
"""Incremental change to the tool call ID."""
|
|
215
215
|
|
|
216
216
|
|
|
217
|
+
@dataclass
|
|
218
|
+
class DeltaThinkingPart:
|
|
219
|
+
"""Incremental change to a thinking part.
|
|
220
|
+
|
|
221
|
+
Used to describe a chunk when streaming thinking responses.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
content: str | None = None
|
|
225
|
+
"""Incremental change to the thinking content."""
|
|
226
|
+
signature: str | None = None
|
|
227
|
+
"""Incremental change to the thinking signature."""
|
|
228
|
+
|
|
229
|
+
|
|
217
230
|
DeltaToolCalls: TypeAlias = dict[int, DeltaToolCall]
|
|
218
231
|
"""A mapping of tool call IDs to incremental changes."""
|
|
219
232
|
|
|
233
|
+
DeltaThinkingCalls: TypeAlias = dict[int, DeltaThinkingPart]
|
|
234
|
+
"""A mapping of thinking call IDs to incremental changes."""
|
|
235
|
+
|
|
220
236
|
# TODO: Change the signature to Callable[[list[ModelMessage], ModelSettings, ModelRequestParameters], ...]
|
|
221
237
|
FunctionDef: TypeAlias = Callable[[list[ModelMessage], AgentInfo], Union[ModelResponse, Awaitable[ModelResponse]]]
|
|
222
238
|
"""A function used to generate a non-streamed response."""
|
|
223
239
|
|
|
224
240
|
# TODO: Change signature as indicated above
|
|
225
|
-
StreamFunctionDef: TypeAlias = Callable[
|
|
241
|
+
StreamFunctionDef: TypeAlias = Callable[
|
|
242
|
+
[list[ModelMessage], AgentInfo], AsyncIterator[Union[str, DeltaToolCalls, DeltaThinkingCalls]]
|
|
243
|
+
]
|
|
226
244
|
"""A function used to generate a streamed response.
|
|
227
245
|
|
|
228
|
-
While this is defined as having return type of `AsyncIterator[Union[str, DeltaToolCalls]]`, it should
|
|
229
|
-
really be considered as `Union[AsyncIterator[str], AsyncIterator[DeltaToolCalls]`,
|
|
246
|
+
While this is defined as having return type of `AsyncIterator[Union[str, DeltaToolCalls, DeltaThinkingCalls]]`, it should
|
|
247
|
+
really be considered as `Union[AsyncIterator[str], AsyncIterator[DeltaToolCalls], AsyncIterator[DeltaThinkingCalls]]`,
|
|
230
248
|
|
|
231
|
-
E.g. you need to yield all text or all `
|
|
249
|
+
E.g. you need to yield all text, all `DeltaToolCalls`, or all `DeltaThinkingCalls`, not mix them.
|
|
232
250
|
"""
|
|
233
251
|
|
|
234
252
|
|
|
@@ -237,7 +255,7 @@ class FunctionStreamedResponse(StreamedResponse):
|
|
|
237
255
|
"""Implementation of `StreamedResponse` for [FunctionModel][pydantic_ai.models.function.FunctionModel]."""
|
|
238
256
|
|
|
239
257
|
_model_name: str
|
|
240
|
-
_iter: AsyncIterator[str | DeltaToolCalls]
|
|
258
|
+
_iter: AsyncIterator[str | DeltaToolCalls | DeltaThinkingCalls]
|
|
241
259
|
_timestamp: datetime = field(default_factory=_utils.now_utc)
|
|
242
260
|
|
|
243
261
|
def __post_init__(self):
|
|
@@ -249,20 +267,31 @@ class FunctionStreamedResponse(StreamedResponse):
|
|
|
249
267
|
response_tokens = _estimate_string_tokens(item)
|
|
250
268
|
self._usage += usage.Usage(response_tokens=response_tokens, total_tokens=response_tokens)
|
|
251
269
|
yield self._parts_manager.handle_text_delta(vendor_part_id='content', content=item)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
|
|
270
|
+
elif isinstance(item, dict) and item:
|
|
271
|
+
for dtc_index, delta in item.items():
|
|
272
|
+
if isinstance(delta, DeltaThinkingPart):
|
|
273
|
+
if delta.content: # pragma: no branch
|
|
274
|
+
response_tokens = _estimate_string_tokens(delta.content)
|
|
275
|
+
self._usage += usage.Usage(response_tokens=response_tokens, total_tokens=response_tokens)
|
|
276
|
+
yield self._parts_manager.handle_thinking_delta(
|
|
277
|
+
vendor_part_id=dtc_index,
|
|
278
|
+
content=delta.content,
|
|
279
|
+
signature=delta.signature,
|
|
280
|
+
)
|
|
281
|
+
elif isinstance(delta, DeltaToolCall):
|
|
282
|
+
if delta.json_args:
|
|
283
|
+
response_tokens = _estimate_string_tokens(delta.json_args)
|
|
284
|
+
self._usage += usage.Usage(response_tokens=response_tokens, total_tokens=response_tokens)
|
|
285
|
+
maybe_event = self._parts_manager.handle_tool_call_delta(
|
|
286
|
+
vendor_part_id=dtc_index,
|
|
287
|
+
tool_name=delta.name,
|
|
288
|
+
args=delta.json_args,
|
|
289
|
+
tool_call_id=delta.tool_call_id,
|
|
290
|
+
)
|
|
291
|
+
if maybe_event is not None:
|
|
292
|
+
yield maybe_event
|
|
293
|
+
else:
|
|
294
|
+
assert_never(delta)
|
|
266
295
|
|
|
267
296
|
@property
|
|
268
297
|
def model_name(self) -> str:
|
|
@@ -299,12 +328,9 @@ def _estimate_usage(messages: Iterable[ModelMessage]) -> usage.Usage:
|
|
|
299
328
|
if isinstance(part, TextPart):
|
|
300
329
|
response_tokens += _estimate_string_tokens(part.content)
|
|
301
330
|
elif isinstance(part, ThinkingPart):
|
|
302
|
-
|
|
303
|
-
# If you are unsatisfied with this, please open an issue.
|
|
304
|
-
pass
|
|
331
|
+
response_tokens += _estimate_string_tokens(part.content)
|
|
305
332
|
elif isinstance(part, ToolCallPart):
|
|
306
|
-
|
|
307
|
-
response_tokens += 1 + _estimate_string_tokens(call.args_as_json_str())
|
|
333
|
+
response_tokens += 1 + _estimate_string_tokens(part.args_as_json_str())
|
|
308
334
|
else:
|
|
309
335
|
assert_never(part)
|
|
310
336
|
else:
|
pydantic_ai/models/gemini.py
CHANGED
|
@@ -48,18 +48,10 @@ from . import (
|
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
LatestGeminiModelNames = Literal[
|
|
51
|
-
'gemini-1.5-flash',
|
|
52
|
-
'gemini-1.5-flash-8b',
|
|
53
|
-
'gemini-1.5-pro',
|
|
54
|
-
'gemini-1.0-pro',
|
|
55
51
|
'gemini-2.0-flash',
|
|
56
|
-
'gemini-2.0-flash-lite
|
|
57
|
-
'gemini-2.0-pro-exp-02-05',
|
|
58
|
-
'gemini-2.5-flash-preview-05-20',
|
|
52
|
+
'gemini-2.0-flash-lite',
|
|
59
53
|
'gemini-2.5-flash',
|
|
60
54
|
'gemini-2.5-flash-lite-preview-06-17',
|
|
61
|
-
'gemini-2.5-pro-exp-03-25',
|
|
62
|
-
'gemini-2.5-pro-preview-05-06',
|
|
63
55
|
'gemini-2.5-pro',
|
|
64
56
|
]
|
|
65
57
|
"""Latest Gemini models."""
|
|
@@ -253,7 +245,7 @@ class GeminiModel(Model):
|
|
|
253
245
|
|
|
254
246
|
if gemini_labels := model_settings.get('gemini_labels'):
|
|
255
247
|
if self._system == 'google-vertex':
|
|
256
|
-
request_data['labels'] = gemini_labels
|
|
248
|
+
request_data['labels'] = gemini_labels
|
|
257
249
|
|
|
258
250
|
headers = {'Content-Type': 'application/json', 'User-Agent': get_user_agent()}
|
|
259
251
|
url = f'/{self._model_name}:{"streamGenerateContent" if streamed else "generateContent"}'
|
|
@@ -415,7 +407,7 @@ def _settings_to_generation_config(model_settings: GeminiModelSettings) -> _Gemi
|
|
|
415
407
|
if (frequency_penalty := model_settings.get('frequency_penalty')) is not None:
|
|
416
408
|
config['frequency_penalty'] = frequency_penalty
|
|
417
409
|
if (thinkingConfig := model_settings.get('gemini_thinking_config')) is not None:
|
|
418
|
-
config['thinking_config'] = thinkingConfig
|
|
410
|
+
config['thinking_config'] = thinkingConfig
|
|
419
411
|
return config
|
|
420
412
|
|
|
421
413
|
|
pydantic_ai/models/google.py
CHANGED
|
@@ -73,18 +73,10 @@ except ImportError as _import_error:
|
|
|
73
73
|
) from _import_error
|
|
74
74
|
|
|
75
75
|
LatestGoogleModelNames = Literal[
|
|
76
|
-
'gemini-1.5-flash',
|
|
77
|
-
'gemini-1.5-flash-8b',
|
|
78
|
-
'gemini-1.5-pro',
|
|
79
|
-
'gemini-1.0-pro',
|
|
80
76
|
'gemini-2.0-flash',
|
|
81
|
-
'gemini-2.0-flash-lite
|
|
82
|
-
'gemini-2.0-pro-exp-02-05',
|
|
83
|
-
'gemini-2.5-flash-preview-05-20',
|
|
77
|
+
'gemini-2.0-flash-lite',
|
|
84
78
|
'gemini-2.5-flash',
|
|
85
79
|
'gemini-2.5-flash-lite-preview-06-17',
|
|
86
|
-
'gemini-2.5-pro-exp-03-25',
|
|
87
|
-
'gemini-2.5-pro-preview-05-06',
|
|
88
80
|
'gemini-2.5-pro',
|
|
89
81
|
]
|
|
90
82
|
"""Latest Gemini models."""
|
|
@@ -166,7 +158,7 @@ class GoogleModel(Model):
|
|
|
166
158
|
self._model_name = model_name
|
|
167
159
|
|
|
168
160
|
if isinstance(provider, str):
|
|
169
|
-
provider = GoogleProvider(vertexai=provider == 'google-vertex')
|
|
161
|
+
provider = GoogleProvider(vertexai=provider == 'google-vertex')
|
|
170
162
|
|
|
171
163
|
self._provider = provider
|
|
172
164
|
self._system = provider.name
|
|
@@ -492,8 +484,7 @@ def _content_model_response(m: ModelResponse) -> ContentDict:
|
|
|
492
484
|
function_call = FunctionCallDict(name=item.tool_name, args=item.args_as_dict(), id=item.tool_call_id)
|
|
493
485
|
parts.append({'function_call': function_call})
|
|
494
486
|
elif isinstance(item, TextPart):
|
|
495
|
-
|
|
496
|
-
parts.append({'text': item.content})
|
|
487
|
+
parts.append({'text': item.content})
|
|
497
488
|
elif isinstance(item, ThinkingPart): # pragma: no cover
|
|
498
489
|
# NOTE: We don't send ThinkingPart to the providers yet. If you are unsatisfied with this,
|
|
499
490
|
# please open an issue. The below code is the code to send thinking to the provider.
|
pydantic_ai/models/groq.py
CHANGED
|
@@ -79,6 +79,7 @@ PreviewGroqModelNames = Literal[
|
|
|
79
79
|
'llama-3.2-3b-preview',
|
|
80
80
|
'llama-3.2-11b-vision-preview',
|
|
81
81
|
'llama-3.2-90b-vision-preview',
|
|
82
|
+
'moonshotai/kimi-k2-instruct',
|
|
82
83
|
]
|
|
83
84
|
"""Preview Groq models from <https://console.groq.com/docs/models#preview-models>."""
|
|
84
85
|
|
|
@@ -248,7 +249,7 @@ class GroqModel(Model):
|
|
|
248
249
|
except APIStatusError as e:
|
|
249
250
|
if (status_code := e.status_code) >= 400:
|
|
250
251
|
raise ModelHTTPError(status_code=status_code, model_name=self.model_name, body=e.body) from e
|
|
251
|
-
raise # pragma:
|
|
252
|
+
raise # pragma: no cover
|
|
252
253
|
|
|
253
254
|
def _process_response(self, response: chat.ChatCompletion) -> ModelResponse:
|
|
254
255
|
"""Process a non-streamed response, and prepare a message to return."""
|