pydantic-ai-slim 1.2.1__tar.gz → 1.4.0__tar.gz
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_slim-1.2.1 → pydantic_ai_slim-1.4.0}/PKG-INFO +5 -5
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/__init__.py +4 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_agent_graph.py +41 -8
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/agent/__init__.py +11 -19
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/builtin_tools.py +106 -4
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/exceptions.py +5 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/mcp.py +1 -22
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/__init__.py +45 -37
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/anthropic.py +132 -11
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/bedrock.py +4 -4
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/cohere.py +0 -7
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/gemini.py +9 -2
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/google.py +31 -21
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/groq.py +4 -4
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/huggingface.py +2 -2
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/openai.py +243 -49
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/__init__.py +21 -12
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/bedrock.py +60 -16
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/gateway.py +60 -72
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/google.py +61 -23
- pydantic_ai_slim-1.4.0/pydantic_ai/providers/ovhcloud.py +95 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/usage.py +13 -2
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pyproject.toml +2 -2
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/.gitignore +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/LICENSE +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/README.md +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/__main__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_a2a.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_cli.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_function_schema.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_griffe.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_instrumentation.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_json_schema.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_mcp.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_otel_messages.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_output.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_parts_manager.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_run_context.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_system_prompt.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_thinking_part.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_tool_manager.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/_utils.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/ag_ui.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/agent/abstract.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/agent/wrapper.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/common_tools/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/common_tools/duckduckgo.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/common_tools/tavily.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/direct.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/dbos/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/dbos/_agent.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/dbos/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/dbos/_model.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/dbos/_utils.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_agent.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_cache_policies.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_function_toolset.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_model.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_toolset.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/prefect/_types.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_agent.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_function_toolset.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_logfire.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_model.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_run_context.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/durable_exec/temporal/_toolset.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/ext/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/ext/aci.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/ext/langchain.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/format_prompt.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/messages.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/fallback.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/function.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/instrumented.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/mcp_sampling.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/mistral.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/test.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/models/wrapper.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/output.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/amazon.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/anthropic.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/cohere.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/deepseek.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/google.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/grok.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/groq.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/harmony.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/meta.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/mistral.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/moonshotai.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/openai.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/profiles/qwen.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/anthropic.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/azure.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/cerebras.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/cohere.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/deepseek.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/fireworks.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/github.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/google_gla.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/google_vertex.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/grok.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/groq.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/heroku.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/huggingface.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/litellm.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/mistral.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/moonshotai.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/nebius.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/ollama.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/openai.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/openrouter.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/together.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/providers/vercel.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/py.typed +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/result.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/retries.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/run.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/settings.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/tools.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/__init__.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/_dynamic.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/abstract.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/approval_required.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/combined.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/external.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/filtered.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/function.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/prefixed.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/prepared.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/renamed.py +0 -0
- {pydantic_ai_slim-1.2.1 → pydantic_ai_slim-1.4.0}/pydantic_ai/toolsets/wrapper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydantic-ai-slim
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
|
|
5
5
|
Project-URL: Homepage, https://github.com/pydantic/pydantic-ai/tree/main/pydantic_ai_slim
|
|
6
6
|
Project-URL: Source, https://github.com/pydantic/pydantic-ai/tree/main/pydantic_ai_slim
|
|
@@ -29,11 +29,11 @@ Classifier: Topic :: Internet
|
|
|
29
29
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
30
30
|
Requires-Python: >=3.10
|
|
31
31
|
Requires-Dist: exceptiongroup; python_version < '3.11'
|
|
32
|
-
Requires-Dist: genai-prices>=0.0.
|
|
32
|
+
Requires-Dist: genai-prices>=0.0.35
|
|
33
33
|
Requires-Dist: griffe>=1.3.2
|
|
34
34
|
Requires-Dist: httpx>=0.27
|
|
35
35
|
Requires-Dist: opentelemetry-api>=1.28.0
|
|
36
|
-
Requires-Dist: pydantic-graph==1.
|
|
36
|
+
Requires-Dist: pydantic-graph==1.4.0
|
|
37
37
|
Requires-Dist: pydantic>=2.10
|
|
38
38
|
Requires-Dist: typing-inspection>=0.4.0
|
|
39
39
|
Provides-Extra: a2a
|
|
@@ -57,9 +57,9 @@ Requires-Dist: dbos>=1.14.0; extra == 'dbos'
|
|
|
57
57
|
Provides-Extra: duckduckgo
|
|
58
58
|
Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
|
|
59
59
|
Provides-Extra: evals
|
|
60
|
-
Requires-Dist: pydantic-evals==1.
|
|
60
|
+
Requires-Dist: pydantic-evals==1.4.0; extra == 'evals'
|
|
61
61
|
Provides-Extra: google
|
|
62
|
-
Requires-Dist: google-genai>=1.
|
|
62
|
+
Requires-Dist: google-genai>=1.46.0; extra == 'google'
|
|
63
63
|
Provides-Extra: groq
|
|
64
64
|
Requires-Dist: groq>=0.25.0; extra == 'groq'
|
|
65
65
|
Provides-Extra: huggingface
|
|
@@ -12,6 +12,7 @@ from .agent import (
|
|
|
12
12
|
from .builtin_tools import (
|
|
13
13
|
CodeExecutionTool,
|
|
14
14
|
ImageGenerationTool,
|
|
15
|
+
MCPServerTool,
|
|
15
16
|
MemoryTool,
|
|
16
17
|
UrlContextTool,
|
|
17
18
|
WebSearchTool,
|
|
@@ -22,6 +23,7 @@ from .exceptions import (
|
|
|
22
23
|
ApprovalRequired,
|
|
23
24
|
CallDeferred,
|
|
24
25
|
FallbackExceptionGroup,
|
|
26
|
+
IncompleteToolCall,
|
|
25
27
|
ModelHTTPError,
|
|
26
28
|
ModelRetry,
|
|
27
29
|
UnexpectedModelBehavior,
|
|
@@ -124,6 +126,7 @@ __all__ = (
|
|
|
124
126
|
'ModelRetry',
|
|
125
127
|
'ModelHTTPError',
|
|
126
128
|
'FallbackExceptionGroup',
|
|
129
|
+
'IncompleteToolCall',
|
|
127
130
|
'UnexpectedModelBehavior',
|
|
128
131
|
'UsageLimitExceeded',
|
|
129
132
|
'UserError',
|
|
@@ -211,6 +214,7 @@ __all__ = (
|
|
|
211
214
|
'CodeExecutionTool',
|
|
212
215
|
'ImageGenerationTool',
|
|
213
216
|
'MemoryTool',
|
|
217
|
+
'MCPServerTool',
|
|
214
218
|
# output
|
|
215
219
|
'ToolOutput',
|
|
216
220
|
'NativeOutput',
|
|
@@ -92,9 +92,28 @@ class GraphAgentState:
|
|
|
92
92
|
retries: int = 0
|
|
93
93
|
run_step: int = 0
|
|
94
94
|
|
|
95
|
-
def increment_retries(
|
|
95
|
+
def increment_retries(
|
|
96
|
+
self,
|
|
97
|
+
max_result_retries: int,
|
|
98
|
+
error: BaseException | None = None,
|
|
99
|
+
model_settings: ModelSettings | None = None,
|
|
100
|
+
) -> None:
|
|
96
101
|
self.retries += 1
|
|
97
102
|
if self.retries > max_result_retries:
|
|
103
|
+
if (
|
|
104
|
+
self.message_history
|
|
105
|
+
and isinstance(model_response := self.message_history[-1], _messages.ModelResponse)
|
|
106
|
+
and model_response.finish_reason == 'length'
|
|
107
|
+
and model_response.parts
|
|
108
|
+
and isinstance(tool_call := model_response.parts[-1], _messages.ToolCallPart)
|
|
109
|
+
):
|
|
110
|
+
try:
|
|
111
|
+
tool_call.args_as_dict()
|
|
112
|
+
except Exception:
|
|
113
|
+
max_tokens = (model_settings or {}).get('max_tokens') if model_settings else None
|
|
114
|
+
raise exceptions.IncompleteToolCall(
|
|
115
|
+
f'Model token limit ({max_tokens if max_tokens is not None else "provider default"}) exceeded while emitting a tool call, resulting in incomplete arguments. Increase max tokens or simplify tool call arguments to fit within limit.'
|
|
116
|
+
)
|
|
98
117
|
message = f'Exceeded maximum retries ({max_result_retries}) for output validation'
|
|
99
118
|
if error:
|
|
100
119
|
if isinstance(error, exceptions.UnexpectedModelBehavior) and error.__cause__ is not None:
|
|
@@ -568,8 +587,12 @@ class CallToolsNode(AgentNode[DepsT, NodeRunEndT]):
|
|
|
568
587
|
# resubmit the most recent request that resulted in an empty response,
|
|
569
588
|
# as the empty response and request will not create any items in the API payload,
|
|
570
589
|
# in the hope the model will return a non-empty response this time.
|
|
571
|
-
ctx.state.increment_retries(ctx.deps.max_result_retries)
|
|
572
|
-
|
|
590
|
+
ctx.state.increment_retries(ctx.deps.max_result_retries, model_settings=ctx.deps.model_settings)
|
|
591
|
+
run_context = build_run_context(ctx)
|
|
592
|
+
instructions = await ctx.deps.get_instructions(run_context)
|
|
593
|
+
self._next_node = ModelRequestNode[DepsT, NodeRunEndT](
|
|
594
|
+
_messages.ModelRequest(parts=[], instructions=instructions)
|
|
595
|
+
)
|
|
573
596
|
return
|
|
574
597
|
|
|
575
598
|
text = ''
|
|
@@ -630,8 +653,14 @@ class CallToolsNode(AgentNode[DepsT, NodeRunEndT]):
|
|
|
630
653
|
)
|
|
631
654
|
raise ToolRetryError(m)
|
|
632
655
|
except ToolRetryError as e:
|
|
633
|
-
ctx.state.increment_retries(
|
|
634
|
-
|
|
656
|
+
ctx.state.increment_retries(
|
|
657
|
+
ctx.deps.max_result_retries, error=e, model_settings=ctx.deps.model_settings
|
|
658
|
+
)
|
|
659
|
+
run_context = build_run_context(ctx)
|
|
660
|
+
instructions = await ctx.deps.get_instructions(run_context)
|
|
661
|
+
self._next_node = ModelRequestNode[DepsT, NodeRunEndT](
|
|
662
|
+
_messages.ModelRequest(parts=[e.tool_retry], instructions=instructions)
|
|
663
|
+
)
|
|
635
664
|
|
|
636
665
|
self._events_iterator = _run_stream()
|
|
637
666
|
|
|
@@ -788,10 +817,14 @@ async def process_tool_calls( # noqa: C901
|
|
|
788
817
|
try:
|
|
789
818
|
result_data = await tool_manager.handle_call(call)
|
|
790
819
|
except exceptions.UnexpectedModelBehavior as e:
|
|
791
|
-
ctx.state.increment_retries(
|
|
820
|
+
ctx.state.increment_retries(
|
|
821
|
+
ctx.deps.max_result_retries, error=e, model_settings=ctx.deps.model_settings
|
|
822
|
+
)
|
|
792
823
|
raise e # pragma: lax no cover
|
|
793
824
|
except ToolRetryError as e:
|
|
794
|
-
ctx.state.increment_retries(
|
|
825
|
+
ctx.state.increment_retries(
|
|
826
|
+
ctx.deps.max_result_retries, error=e, model_settings=ctx.deps.model_settings
|
|
827
|
+
)
|
|
795
828
|
yield _messages.FunctionToolCallEvent(call)
|
|
796
829
|
output_parts.append(e.tool_retry)
|
|
797
830
|
yield _messages.FunctionToolResultEvent(e.tool_retry)
|
|
@@ -820,7 +853,7 @@ async def process_tool_calls( # noqa: C901
|
|
|
820
853
|
|
|
821
854
|
# Then, we handle unknown tool calls
|
|
822
855
|
if tool_calls_by_kind['unknown']:
|
|
823
|
-
ctx.state.increment_retries(ctx.deps.max_result_retries)
|
|
856
|
+
ctx.state.increment_retries(ctx.deps.max_result_retries, model_settings=ctx.deps.model_settings)
|
|
824
857
|
calls_to_run.extend(tool_calls_by_kind['unknown'])
|
|
825
858
|
|
|
826
859
|
calls_to_run_results: dict[str, DeferredToolResult] = {}
|
|
@@ -542,6 +542,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
542
542
|
"""
|
|
543
543
|
if infer_name and self.name is None:
|
|
544
544
|
self._infer_name(inspect.currentframe())
|
|
545
|
+
|
|
545
546
|
model_used = self._get_model(model)
|
|
546
547
|
del model
|
|
547
548
|
|
|
@@ -607,16 +608,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
607
608
|
else:
|
|
608
609
|
instrumentation_settings = None
|
|
609
610
|
tracer = NoOpTracer()
|
|
610
|
-
|
|
611
|
-
# Deduplicate builtin tools passed to the agent and the run based on type
|
|
612
|
-
builtin_tools = list(
|
|
613
|
-
{
|
|
614
|
-
**({type(tool): tool for tool in self._builtin_tools or []}),
|
|
615
|
-
**({type(tool): tool for tool in builtin_tools}),
|
|
616
|
-
}.values()
|
|
617
|
-
)
|
|
618
|
-
else:
|
|
619
|
-
builtin_tools = list(self._builtin_tools)
|
|
611
|
+
|
|
620
612
|
graph_deps = _agent_graph.GraphAgentDeps[AgentDepsT, RunOutputDataT](
|
|
621
613
|
user_deps=deps,
|
|
622
614
|
prompt=user_prompt,
|
|
@@ -629,7 +621,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
629
621
|
output_schema=output_schema,
|
|
630
622
|
output_validators=output_validators,
|
|
631
623
|
history_processors=self.history_processors,
|
|
632
|
-
builtin_tools=builtin_tools,
|
|
624
|
+
builtin_tools=[*self._builtin_tools, *(builtin_tools or [])],
|
|
633
625
|
tool_manager=tool_manager,
|
|
634
626
|
tracer=tracer,
|
|
635
627
|
get_instructions=get_instructions,
|
|
@@ -662,14 +654,14 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
662
654
|
)
|
|
663
655
|
|
|
664
656
|
try:
|
|
665
|
-
async with
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
657
|
+
async with graph.iter(
|
|
658
|
+
start_node,
|
|
659
|
+
state=state,
|
|
660
|
+
deps=graph_deps,
|
|
661
|
+
span=use_span(run_span) if run_span.is_recording() else None,
|
|
662
|
+
infer_name=False,
|
|
663
|
+
) as graph_run:
|
|
664
|
+
async with toolset:
|
|
673
665
|
agent_run = AgentRun(graph_run)
|
|
674
666
|
yield agent_run
|
|
675
667
|
if (final_result := agent_run.result) is not None and run_span.is_recording():
|
|
@@ -2,13 +2,12 @@ from __future__ import annotations as _annotations
|
|
|
2
2
|
|
|
3
3
|
from abc import ABC
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Annotated, Any, Literal, Union
|
|
6
6
|
|
|
7
|
+
import pydantic
|
|
8
|
+
from pydantic_core import core_schema
|
|
7
9
|
from typing_extensions import TypedDict
|
|
8
10
|
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from .builtin_tools import AbstractBuiltinTool
|
|
11
|
-
|
|
12
11
|
__all__ = (
|
|
13
12
|
'AbstractBuiltinTool',
|
|
14
13
|
'WebSearchTool',
|
|
@@ -17,8 +16,11 @@ __all__ = (
|
|
|
17
16
|
'UrlContextTool',
|
|
18
17
|
'ImageGenerationTool',
|
|
19
18
|
'MemoryTool',
|
|
19
|
+
'MCPServerTool',
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
+
_BUILTIN_TOOL_TYPES: dict[str, type[AbstractBuiltinTool]] = {}
|
|
23
|
+
|
|
22
24
|
|
|
23
25
|
@dataclass(kw_only=True)
|
|
24
26
|
class AbstractBuiltinTool(ABC):
|
|
@@ -32,6 +34,34 @@ class AbstractBuiltinTool(ABC):
|
|
|
32
34
|
kind: str = 'unknown_builtin_tool'
|
|
33
35
|
"""Built-in tool identifier, this should be available on all built-in tools as a discriminator."""
|
|
34
36
|
|
|
37
|
+
@property
|
|
38
|
+
def unique_id(self) -> str:
|
|
39
|
+
"""A unique identifier for the builtin tool.
|
|
40
|
+
|
|
41
|
+
If multiple instances of the same builtin tool can be passed to the model, subclasses should override this property to allow them to be distinguished.
|
|
42
|
+
"""
|
|
43
|
+
return self.kind
|
|
44
|
+
|
|
45
|
+
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
46
|
+
super().__init_subclass__(**kwargs)
|
|
47
|
+
_BUILTIN_TOOL_TYPES[cls.kind] = cls
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def __get_pydantic_core_schema__(
|
|
51
|
+
cls, _source_type: Any, handler: pydantic.GetCoreSchemaHandler
|
|
52
|
+
) -> core_schema.CoreSchema:
|
|
53
|
+
if cls is not AbstractBuiltinTool:
|
|
54
|
+
return handler(cls)
|
|
55
|
+
|
|
56
|
+
tools = _BUILTIN_TOOL_TYPES.values()
|
|
57
|
+
if len(tools) == 1: # pragma: no cover
|
|
58
|
+
tools_type = next(iter(tools))
|
|
59
|
+
else:
|
|
60
|
+
tools_annotated = [Annotated[tool, pydantic.Tag(tool.kind)] for tool in tools]
|
|
61
|
+
tools_type = Annotated[Union[tuple(tools_annotated)], pydantic.Discriminator(_tool_discriminator)] # noqa: UP007
|
|
62
|
+
|
|
63
|
+
return handler(tools_type)
|
|
64
|
+
|
|
35
65
|
|
|
36
66
|
@dataclass(kw_only=True)
|
|
37
67
|
class WebSearchTool(AbstractBuiltinTool):
|
|
@@ -120,6 +150,7 @@ class WebSearchUserLocation(TypedDict, total=False):
|
|
|
120
150
|
"""The timezone of the user's location."""
|
|
121
151
|
|
|
122
152
|
|
|
153
|
+
@dataclass(kw_only=True)
|
|
123
154
|
class CodeExecutionTool(AbstractBuiltinTool):
|
|
124
155
|
"""A builtin tool that allows your agent to execute code.
|
|
125
156
|
|
|
@@ -134,6 +165,7 @@ class CodeExecutionTool(AbstractBuiltinTool):
|
|
|
134
165
|
"""The kind of tool."""
|
|
135
166
|
|
|
136
167
|
|
|
168
|
+
@dataclass(kw_only=True)
|
|
137
169
|
class UrlContextTool(AbstractBuiltinTool):
|
|
138
170
|
"""Allows your agent to access contents from URLs.
|
|
139
171
|
|
|
@@ -227,6 +259,7 @@ class ImageGenerationTool(AbstractBuiltinTool):
|
|
|
227
259
|
"""The kind of tool."""
|
|
228
260
|
|
|
229
261
|
|
|
262
|
+
@dataclass(kw_only=True)
|
|
230
263
|
class MemoryTool(AbstractBuiltinTool):
|
|
231
264
|
"""A builtin tool that allows your agent to use memory.
|
|
232
265
|
|
|
@@ -237,3 +270,72 @@ class MemoryTool(AbstractBuiltinTool):
|
|
|
237
270
|
|
|
238
271
|
kind: str = 'memory'
|
|
239
272
|
"""The kind of tool."""
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
@dataclass(kw_only=True)
|
|
276
|
+
class MCPServerTool(AbstractBuiltinTool):
|
|
277
|
+
"""A builtin tool that allows your agent to use MCP servers.
|
|
278
|
+
|
|
279
|
+
Supported by:
|
|
280
|
+
|
|
281
|
+
* OpenAI Responses
|
|
282
|
+
* Anthropic
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
id: str
|
|
286
|
+
"""A unique identifier for the MCP server."""
|
|
287
|
+
|
|
288
|
+
url: str
|
|
289
|
+
"""The URL of the MCP server to use.
|
|
290
|
+
|
|
291
|
+
For OpenAI Responses, it is possible to use `connector_id` by providing it as `x-openai-connector:<connector_id>`.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
authorization_token: str | None = None
|
|
295
|
+
"""Authorization header to use when making requests to the MCP server.
|
|
296
|
+
|
|
297
|
+
Supported by:
|
|
298
|
+
|
|
299
|
+
* OpenAI Responses
|
|
300
|
+
* Anthropic
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
description: str | None = None
|
|
304
|
+
"""A description of the MCP server.
|
|
305
|
+
|
|
306
|
+
Supported by:
|
|
307
|
+
|
|
308
|
+
* OpenAI Responses
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
allowed_tools: list[str] | None = None
|
|
312
|
+
"""A list of tools that the MCP server can use.
|
|
313
|
+
|
|
314
|
+
Supported by:
|
|
315
|
+
|
|
316
|
+
* OpenAI Responses
|
|
317
|
+
* Anthropic
|
|
318
|
+
"""
|
|
319
|
+
|
|
320
|
+
headers: dict[str, str] | None = None
|
|
321
|
+
"""Optional HTTP headers to send to the MCP server.
|
|
322
|
+
|
|
323
|
+
Use for authentication or other purposes.
|
|
324
|
+
|
|
325
|
+
Supported by:
|
|
326
|
+
|
|
327
|
+
* OpenAI Responses
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
kind: str = 'mcp_server'
|
|
331
|
+
|
|
332
|
+
@property
|
|
333
|
+
def unique_id(self) -> str:
|
|
334
|
+
return ':'.join([self.kind, self.id])
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def _tool_discriminator(tool_data: dict[str, Any] | AbstractBuiltinTool) -> str:
|
|
338
|
+
if isinstance(tool_data, dict):
|
|
339
|
+
return tool_data.get('kind', AbstractBuiltinTool.kind)
|
|
340
|
+
else:
|
|
341
|
+
return tool_data.kind
|
|
@@ -23,6 +23,7 @@ __all__ = (
|
|
|
23
23
|
'UnexpectedModelBehavior',
|
|
24
24
|
'UsageLimitExceeded',
|
|
25
25
|
'ModelHTTPError',
|
|
26
|
+
'IncompleteToolCall',
|
|
26
27
|
'FallbackExceptionGroup',
|
|
27
28
|
)
|
|
28
29
|
|
|
@@ -168,3 +169,7 @@ class ToolRetryError(Exception):
|
|
|
168
169
|
def __init__(self, tool_retry: RetryPromptPart):
|
|
169
170
|
self.tool_retry = tool_retry
|
|
170
171
|
super().__init__()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class IncompleteToolCall(UnexpectedModelBehavior):
|
|
175
|
+
"""Error raised when a model stops due to token limit while emitting a tool call."""
|
|
@@ -441,14 +441,9 @@ class MCPServerStdio(MCPServer):
|
|
|
441
441
|
'uv', args=['run', 'mcp-run-python', 'stdio'], timeout=10
|
|
442
442
|
)
|
|
443
443
|
agent = Agent('openai:gpt-4o', toolsets=[server])
|
|
444
|
-
|
|
445
|
-
async def main():
|
|
446
|
-
async with agent: # (2)!
|
|
447
|
-
...
|
|
448
444
|
```
|
|
449
445
|
|
|
450
446
|
1. See [MCP Run Python](https://github.com/pydantic/mcp-run-python) for more information.
|
|
451
|
-
2. This will start the server as a subprocess and connect to it.
|
|
452
447
|
"""
|
|
453
448
|
|
|
454
449
|
command: str
|
|
@@ -788,13 +783,7 @@ class MCPServerSSE(_MCPServerHTTP):
|
|
|
788
783
|
|
|
789
784
|
server = MCPServerSSE('http://localhost:3001/sse')
|
|
790
785
|
agent = Agent('openai:gpt-4o', toolsets=[server])
|
|
791
|
-
|
|
792
|
-
async def main():
|
|
793
|
-
async with agent: # (1)!
|
|
794
|
-
...
|
|
795
786
|
```
|
|
796
|
-
|
|
797
|
-
1. This will connect to a server running on `localhost:3001`.
|
|
798
787
|
"""
|
|
799
788
|
|
|
800
789
|
@classmethod
|
|
@@ -837,13 +826,7 @@ class MCPServerHTTP(MCPServerSSE):
|
|
|
837
826
|
|
|
838
827
|
server = MCPServerHTTP('http://localhost:3001/sse')
|
|
839
828
|
agent = Agent('openai:gpt-4o', toolsets=[server])
|
|
840
|
-
|
|
841
|
-
async def main():
|
|
842
|
-
async with agent: # (2)!
|
|
843
|
-
...
|
|
844
829
|
```
|
|
845
|
-
|
|
846
|
-
1. This will connect to a server running on `localhost:3001`.
|
|
847
830
|
"""
|
|
848
831
|
|
|
849
832
|
|
|
@@ -862,12 +845,8 @@ class MCPServerStreamableHTTP(_MCPServerHTTP):
|
|
|
862
845
|
from pydantic_ai import Agent
|
|
863
846
|
from pydantic_ai.mcp import MCPServerStreamableHTTP
|
|
864
847
|
|
|
865
|
-
server = MCPServerStreamableHTTP('http://localhost:8000/mcp')
|
|
848
|
+
server = MCPServerStreamableHTTP('http://localhost:8000/mcp')
|
|
866
849
|
agent = Agent('openai:gpt-4o', toolsets=[server])
|
|
867
|
-
|
|
868
|
-
async def main():
|
|
869
|
-
async with agent: # (2)!
|
|
870
|
-
...
|
|
871
850
|
```
|
|
872
851
|
"""
|
|
873
852
|
|
|
@@ -43,6 +43,7 @@ from ..messages import (
|
|
|
43
43
|
)
|
|
44
44
|
from ..output import OutputMode
|
|
45
45
|
from ..profiles import DEFAULT_PROFILE, ModelProfile, ModelProfileSpec
|
|
46
|
+
from ..providers import infer_provider
|
|
46
47
|
from ..settings import ModelSettings, merge_model_settings
|
|
47
48
|
from ..tools import ToolDefinition
|
|
48
49
|
from ..usage import RequestUsage
|
|
@@ -129,15 +130,8 @@ KnownModelName = TypeAliasType(
|
|
|
129
130
|
'cerebras:qwen-3-235b-a22b-thinking-2507',
|
|
130
131
|
'cohere:c4ai-aya-expanse-32b',
|
|
131
132
|
'cohere:c4ai-aya-expanse-8b',
|
|
132
|
-
'cohere:command',
|
|
133
|
-
'cohere:command-light',
|
|
134
|
-
'cohere:command-light-nightly',
|
|
135
133
|
'cohere:command-nightly',
|
|
136
|
-
'cohere:command-r',
|
|
137
|
-
'cohere:command-r-03-2024',
|
|
138
134
|
'cohere:command-r-08-2024',
|
|
139
|
-
'cohere:command-r-plus',
|
|
140
|
-
'cohere:command-r-plus-04-2024',
|
|
141
135
|
'cohere:command-r-plus-08-2024',
|
|
142
136
|
'cohere:command-r7b-12-2024',
|
|
143
137
|
'deepseek:deepseek-chat',
|
|
@@ -416,9 +410,17 @@ class Model(ABC):
|
|
|
416
410
|
they need to customize the preparation flow further, but most implementations should simply call
|
|
417
411
|
``self.prepare_request(...)`` at the start of their ``request`` (and related) methods.
|
|
418
412
|
"""
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
413
|
+
model_settings = merge_model_settings(self.settings, model_settings)
|
|
414
|
+
|
|
415
|
+
if builtin_tools := model_request_parameters.builtin_tools:
|
|
416
|
+
# Deduplicate builtin tools
|
|
417
|
+
model_request_parameters = replace(
|
|
418
|
+
model_request_parameters,
|
|
419
|
+
builtin_tools=list({tool.unique_id: tool for tool in builtin_tools}.values()),
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
model_request_parameters = self.customize_request_parameters(model_request_parameters)
|
|
423
|
+
return model_settings, model_request_parameters
|
|
422
424
|
|
|
423
425
|
@property
|
|
424
426
|
@abstractmethod
|
|
@@ -644,41 +646,39 @@ def infer_model(model: Model | KnownModelName | str) -> Model: # noqa: C901
|
|
|
644
646
|
return TestModel()
|
|
645
647
|
|
|
646
648
|
try:
|
|
647
|
-
|
|
649
|
+
provider_name, model_name = model.split(':', maxsplit=1)
|
|
648
650
|
except ValueError:
|
|
649
|
-
|
|
651
|
+
provider_name = None
|
|
650
652
|
model_name = model
|
|
651
653
|
if model_name.startswith(('gpt', 'o1', 'o3')):
|
|
652
|
-
|
|
654
|
+
provider_name = 'openai'
|
|
653
655
|
elif model_name.startswith('claude'):
|
|
654
|
-
|
|
656
|
+
provider_name = 'anthropic'
|
|
655
657
|
elif model_name.startswith('gemini'):
|
|
656
|
-
|
|
658
|
+
provider_name = 'google-gla'
|
|
657
659
|
|
|
658
|
-
if
|
|
660
|
+
if provider_name is not None:
|
|
659
661
|
warnings.warn(
|
|
660
|
-
f"Specifying a model name without a provider prefix is deprecated. Instead of {model_name!r}, use '{
|
|
662
|
+
f"Specifying a model name without a provider prefix is deprecated. Instead of {model_name!r}, use '{provider_name}:{model_name}'.",
|
|
661
663
|
DeprecationWarning,
|
|
662
664
|
)
|
|
663
665
|
else:
|
|
664
666
|
raise UserError(f'Unknown model: {model}')
|
|
665
667
|
|
|
666
|
-
if
|
|
668
|
+
if provider_name == 'vertexai': # pragma: no cover
|
|
667
669
|
warnings.warn(
|
|
668
670
|
"The 'vertexai' provider name is deprecated. Use 'google-vertex' instead.",
|
|
669
671
|
DeprecationWarning,
|
|
670
672
|
)
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
if provider == 'gateway':
|
|
674
|
-
from ..providers.gateway import infer_model as infer_model_from_gateway
|
|
673
|
+
provider_name = 'google-vertex'
|
|
675
674
|
|
|
676
|
-
|
|
677
|
-
elif provider == 'cohere':
|
|
678
|
-
from .cohere import CohereModel
|
|
675
|
+
provider = infer_provider(provider_name)
|
|
679
676
|
|
|
680
|
-
|
|
681
|
-
|
|
677
|
+
model_kind = provider_name
|
|
678
|
+
if model_kind.startswith('gateway/'):
|
|
679
|
+
model_kind = provider_name.removeprefix('gateway/')
|
|
680
|
+
if model_kind in (
|
|
681
|
+
'openai',
|
|
682
682
|
'azure',
|
|
683
683
|
'deepseek',
|
|
684
684
|
'cerebras',
|
|
@@ -688,42 +688,50 @@ def infer_model(model: Model | KnownModelName | str) -> Model: # noqa: C901
|
|
|
688
688
|
'heroku',
|
|
689
689
|
'moonshotai',
|
|
690
690
|
'ollama',
|
|
691
|
-
'openai',
|
|
692
|
-
'openai-chat',
|
|
693
691
|
'openrouter',
|
|
694
692
|
'together',
|
|
695
693
|
'vercel',
|
|
696
694
|
'litellm',
|
|
697
695
|
'nebius',
|
|
696
|
+
'ovhcloud',
|
|
698
697
|
):
|
|
698
|
+
model_kind = 'openai-chat'
|
|
699
|
+
elif model_kind in ('google-gla', 'google-vertex'):
|
|
700
|
+
model_kind = 'google'
|
|
701
|
+
|
|
702
|
+
if model_kind == 'openai-chat':
|
|
699
703
|
from .openai import OpenAIChatModel
|
|
700
704
|
|
|
701
705
|
return OpenAIChatModel(model_name, provider=provider)
|
|
702
|
-
elif
|
|
706
|
+
elif model_kind == 'openai-responses':
|
|
703
707
|
from .openai import OpenAIResponsesModel
|
|
704
708
|
|
|
705
|
-
return OpenAIResponsesModel(model_name, provider=
|
|
706
|
-
elif
|
|
709
|
+
return OpenAIResponsesModel(model_name, provider=provider)
|
|
710
|
+
elif model_kind == 'google':
|
|
707
711
|
from .google import GoogleModel
|
|
708
712
|
|
|
709
713
|
return GoogleModel(model_name, provider=provider)
|
|
710
|
-
elif
|
|
714
|
+
elif model_kind == 'groq':
|
|
711
715
|
from .groq import GroqModel
|
|
712
716
|
|
|
713
717
|
return GroqModel(model_name, provider=provider)
|
|
714
|
-
elif
|
|
718
|
+
elif model_kind == 'cohere':
|
|
719
|
+
from .cohere import CohereModel
|
|
720
|
+
|
|
721
|
+
return CohereModel(model_name, provider=provider)
|
|
722
|
+
elif model_kind == 'mistral':
|
|
715
723
|
from .mistral import MistralModel
|
|
716
724
|
|
|
717
725
|
return MistralModel(model_name, provider=provider)
|
|
718
|
-
elif
|
|
726
|
+
elif model_kind == 'anthropic':
|
|
719
727
|
from .anthropic import AnthropicModel
|
|
720
728
|
|
|
721
729
|
return AnthropicModel(model_name, provider=provider)
|
|
722
|
-
elif
|
|
730
|
+
elif model_kind == 'bedrock':
|
|
723
731
|
from .bedrock import BedrockConverseModel
|
|
724
732
|
|
|
725
733
|
return BedrockConverseModel(model_name, provider=provider)
|
|
726
|
-
elif
|
|
734
|
+
elif model_kind == 'huggingface':
|
|
727
735
|
from .huggingface import HuggingFaceModel
|
|
728
736
|
|
|
729
737
|
return HuggingFaceModel(model_name, provider=provider)
|