pydantic-ai-slim 1.3.0__tar.gz → 1.5.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.3.0 → pydantic_ai_slim-1.5.0}/PKG-INFO +3 -3
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/__init__.py +2 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_agent_graph.py +33 -14
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_utils.py +8 -8
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/agent/__init__.py +6 -18
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/builtin_tools.py +71 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/__init__.py +11 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_function_toolset.py +2 -1
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/exceptions.py +1 -1
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/messages.py +1 -1
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/__init__.py +11 -3
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/anthropic.py +130 -9
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/google.py +26 -14
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/openai.py +190 -13
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/google.py +31 -2
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/run.py +40 -24
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/.gitignore +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/LICENSE +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/README.md +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/__main__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_a2a.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_cli.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_function_schema.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_griffe.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_instrumentation.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_json_schema.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_mcp.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_otel_messages.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_output.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_parts_manager.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_run_context.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_system_prompt.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_thinking_part.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/_tool_manager.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/ag_ui.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/agent/abstract.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/agent/wrapper.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/common_tools/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/common_tools/duckduckgo.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/common_tools/tavily.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/direct.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/dbos/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/dbos/_agent.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/dbos/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/dbos/_model.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/dbos/_utils.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_agent.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_cache_policies.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_function_toolset.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_model.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_toolset.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/prefect/_types.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_agent.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_logfire.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_mcp_server.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_model.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_run_context.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/_toolset.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/ext/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/ext/aci.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/ext/langchain.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/format_prompt.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/mcp.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/bedrock.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/cohere.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/fallback.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/function.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/gemini.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/groq.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/huggingface.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/instrumented.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/mcp_sampling.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/mistral.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/test.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/models/wrapper.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/output.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/amazon.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/anthropic.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/cohere.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/deepseek.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/google.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/grok.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/groq.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/harmony.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/meta.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/mistral.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/moonshotai.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/openai.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/profiles/qwen.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/anthropic.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/azure.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/bedrock.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/cerebras.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/cohere.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/deepseek.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/fireworks.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/gateway.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/github.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/google_gla.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/google_vertex.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/grok.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/groq.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/heroku.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/huggingface.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/litellm.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/mistral.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/moonshotai.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/nebius.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/ollama.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/openai.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/openrouter.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/ovhcloud.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/together.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/providers/vercel.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/py.typed +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/result.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/retries.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/settings.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/tools.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/__init__.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/_dynamic.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/abstract.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/approval_required.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/combined.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/external.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/filtered.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/function.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/prefixed.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/prepared.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/renamed.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/toolsets/wrapper.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/usage.py +0 -0
- {pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydantic-ai-slim
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.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
|
|
@@ -33,7 +33,7 @@ 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.5.0
|
|
37
37
|
Requires-Dist: pydantic>=2.10
|
|
38
38
|
Requires-Dist: typing-inspection>=0.4.0
|
|
39
39
|
Provides-Extra: a2a
|
|
@@ -57,7 +57,7 @@ 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.5.0; extra == 'evals'
|
|
61
61
|
Provides-Extra: google
|
|
62
62
|
Requires-Dist: google-genai>=1.46.0; extra == 'google'
|
|
63
63
|
Provides-Extra: groq
|
|
@@ -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,
|
|
@@ -213,6 +214,7 @@ __all__ = (
|
|
|
213
214
|
'CodeExecutionTool',
|
|
214
215
|
'ImageGenerationTool',
|
|
215
216
|
'MemoryTool',
|
|
217
|
+
'MCPServerTool',
|
|
216
218
|
# output
|
|
217
219
|
'ToolOutput',
|
|
218
220
|
'NativeOutput',
|
|
@@ -20,7 +20,8 @@ from pydantic_ai._instrumentation import DEFAULT_INSTRUMENTATION_VERSION
|
|
|
20
20
|
from pydantic_ai._tool_manager import ToolManager
|
|
21
21
|
from pydantic_ai._utils import dataclasses_no_defaults_repr, get_union_args, is_async_callable, run_in_executor
|
|
22
22
|
from pydantic_ai.builtin_tools import AbstractBuiltinTool
|
|
23
|
-
from pydantic_graph import BaseNode,
|
|
23
|
+
from pydantic_graph import BaseNode, GraphRunContext
|
|
24
|
+
from pydantic_graph.beta import Graph, GraphBuilder
|
|
24
25
|
from pydantic_graph.nodes import End, NodeRunEndT
|
|
25
26
|
|
|
26
27
|
from . import _output, _system_prompt, exceptions, messages as _messages, models, result, usage as _usage
|
|
@@ -588,7 +589,11 @@ class CallToolsNode(AgentNode[DepsT, NodeRunEndT]):
|
|
|
588
589
|
# as the empty response and request will not create any items in the API payload,
|
|
589
590
|
# in the hope the model will return a non-empty response this time.
|
|
590
591
|
ctx.state.increment_retries(ctx.deps.max_result_retries, model_settings=ctx.deps.model_settings)
|
|
591
|
-
|
|
592
|
+
run_context = build_run_context(ctx)
|
|
593
|
+
instructions = await ctx.deps.get_instructions(run_context)
|
|
594
|
+
self._next_node = ModelRequestNode[DepsT, NodeRunEndT](
|
|
595
|
+
_messages.ModelRequest(parts=[], instructions=instructions)
|
|
596
|
+
)
|
|
592
597
|
return
|
|
593
598
|
|
|
594
599
|
text = ''
|
|
@@ -652,7 +657,11 @@ class CallToolsNode(AgentNode[DepsT, NodeRunEndT]):
|
|
|
652
657
|
ctx.state.increment_retries(
|
|
653
658
|
ctx.deps.max_result_retries, error=e, model_settings=ctx.deps.model_settings
|
|
654
659
|
)
|
|
655
|
-
|
|
660
|
+
run_context = build_run_context(ctx)
|
|
661
|
+
instructions = await ctx.deps.get_instructions(run_context)
|
|
662
|
+
self._next_node = ModelRequestNode[DepsT, NodeRunEndT](
|
|
663
|
+
_messages.ModelRequest(parts=[e.tool_retry], instructions=instructions)
|
|
664
|
+
)
|
|
656
665
|
|
|
657
666
|
self._events_iterator = _run_stream()
|
|
658
667
|
|
|
@@ -1154,22 +1163,32 @@ def build_agent_graph(
|
|
|
1154
1163
|
name: str | None,
|
|
1155
1164
|
deps_type: type[DepsT],
|
|
1156
1165
|
output_type: OutputSpec[OutputT],
|
|
1157
|
-
) -> Graph[
|
|
1166
|
+
) -> Graph[
|
|
1167
|
+
GraphAgentState,
|
|
1168
|
+
GraphAgentDeps[DepsT, OutputT],
|
|
1169
|
+
UserPromptNode[DepsT, OutputT],
|
|
1170
|
+
result.FinalResult[OutputT],
|
|
1171
|
+
]:
|
|
1158
1172
|
"""Build the execution [Graph][pydantic_graph.Graph] for a given agent."""
|
|
1159
|
-
|
|
1160
|
-
UserPromptNode[DepsT],
|
|
1161
|
-
ModelRequestNode[DepsT],
|
|
1162
|
-
CallToolsNode[DepsT],
|
|
1163
|
-
SetFinalResult[DepsT],
|
|
1164
|
-
)
|
|
1165
|
-
graph = Graph[GraphAgentState, GraphAgentDeps[DepsT, Any], result.FinalResult[OutputT]](
|
|
1166
|
-
nodes=nodes,
|
|
1173
|
+
g = GraphBuilder(
|
|
1167
1174
|
name=name or 'Agent',
|
|
1168
1175
|
state_type=GraphAgentState,
|
|
1169
|
-
|
|
1176
|
+
deps_type=GraphAgentDeps[DepsT, OutputT],
|
|
1177
|
+
input_type=UserPromptNode[DepsT, OutputT],
|
|
1178
|
+
output_type=result.FinalResult[OutputT],
|
|
1170
1179
|
auto_instrument=False,
|
|
1171
1180
|
)
|
|
1172
|
-
|
|
1181
|
+
|
|
1182
|
+
g.add(
|
|
1183
|
+
g.edge_from(g.start_node).to(UserPromptNode[DepsT, OutputT]),
|
|
1184
|
+
g.node(UserPromptNode[DepsT, OutputT]),
|
|
1185
|
+
g.node(ModelRequestNode[DepsT, OutputT]),
|
|
1186
|
+
g.node(CallToolsNode[DepsT, OutputT]),
|
|
1187
|
+
g.node(
|
|
1188
|
+
SetFinalResult[DepsT, OutputT],
|
|
1189
|
+
),
|
|
1190
|
+
)
|
|
1191
|
+
return g.build(validate_graph_structure=False)
|
|
1173
1192
|
|
|
1174
1193
|
|
|
1175
1194
|
async def _process_message_history(
|
|
@@ -147,7 +147,7 @@ async def group_by_temporal(
|
|
|
147
147
|
aiterable: The async iterable to group.
|
|
148
148
|
soft_max_interval: Maximum interval over which to group items, this should avoid a trickle of items causing
|
|
149
149
|
a group to never be yielded. It's a soft max in the sense that once we're over this time, we yield items
|
|
150
|
-
as soon as `aiter
|
|
150
|
+
as soon as `anext(aiter)` returns. If `None`, no grouping/debouncing is performed
|
|
151
151
|
|
|
152
152
|
Returns:
|
|
153
153
|
A context manager usable as an async iterable of lists of items produced by the input async iterable.
|
|
@@ -171,7 +171,7 @@ async def group_by_temporal(
|
|
|
171
171
|
buffer: list[T] = []
|
|
172
172
|
group_start_time = time.monotonic()
|
|
173
173
|
|
|
174
|
-
aiterator = aiterable
|
|
174
|
+
aiterator = aiter(aiterable)
|
|
175
175
|
while True:
|
|
176
176
|
if group_start_time is None:
|
|
177
177
|
# group hasn't started, we just wait for the maximum interval
|
|
@@ -182,9 +182,9 @@ async def group_by_temporal(
|
|
|
182
182
|
|
|
183
183
|
# if there's no current task, we get the next one
|
|
184
184
|
if task is None:
|
|
185
|
-
# aiter
|
|
185
|
+
# anext(aiter) returns an Awaitable[T], not a Coroutine which asyncio.create_task expects
|
|
186
186
|
# so far, this doesn't seem to be a problem
|
|
187
|
-
task = asyncio.create_task(aiterator
|
|
187
|
+
task = asyncio.create_task(anext(aiterator)) # pyright: ignore[reportArgumentType]
|
|
188
188
|
|
|
189
189
|
# we use asyncio.wait to avoid cancelling the coroutine if it's not done
|
|
190
190
|
done, _ = await asyncio.wait((task,), timeout=wait_time)
|
|
@@ -284,10 +284,10 @@ class PeekableAsyncStream(Generic[T]):
|
|
|
284
284
|
|
|
285
285
|
# Otherwise, we need to fetch the next item from the underlying iterator.
|
|
286
286
|
if self._source_iter is None:
|
|
287
|
-
self._source_iter = self._source
|
|
287
|
+
self._source_iter = aiter(self._source)
|
|
288
288
|
|
|
289
289
|
try:
|
|
290
|
-
self._buffer = await self._source_iter
|
|
290
|
+
self._buffer = await anext(self._source_iter)
|
|
291
291
|
except StopAsyncIteration:
|
|
292
292
|
self._exhausted = True
|
|
293
293
|
return UNSET
|
|
@@ -318,10 +318,10 @@ class PeekableAsyncStream(Generic[T]):
|
|
|
318
318
|
|
|
319
319
|
# Otherwise, fetch the next item from the source.
|
|
320
320
|
if self._source_iter is None:
|
|
321
|
-
self._source_iter = self._source
|
|
321
|
+
self._source_iter = aiter(self._source)
|
|
322
322
|
|
|
323
323
|
try:
|
|
324
|
-
return await self._source_iter
|
|
324
|
+
return await anext(self._source_iter)
|
|
325
325
|
except StopAsyncIteration:
|
|
326
326
|
self._exhausted = True
|
|
327
327
|
raise
|
|
@@ -15,7 +15,6 @@ from pydantic.json_schema import GenerateJsonSchema
|
|
|
15
15
|
from typing_extensions import Self, TypeVar, deprecated
|
|
16
16
|
|
|
17
17
|
from pydantic_ai._instrumentation import DEFAULT_INSTRUMENTATION_VERSION, InstrumentationNames
|
|
18
|
-
from pydantic_graph import Graph
|
|
19
18
|
|
|
20
19
|
from .. import (
|
|
21
20
|
_agent_graph,
|
|
@@ -41,7 +40,6 @@ from ..builtin_tools import AbstractBuiltinTool
|
|
|
41
40
|
from ..models.instrumented import InstrumentationSettings, InstrumentedModel, instrument_model
|
|
42
41
|
from ..output import OutputDataT, OutputSpec
|
|
43
42
|
from ..profiles import ModelProfile
|
|
44
|
-
from ..result import FinalResult
|
|
45
43
|
from ..run import AgentRun, AgentRunResult
|
|
46
44
|
from ..settings import ModelSettings, merge_model_settings
|
|
47
45
|
from ..tools import (
|
|
@@ -542,6 +540,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
542
540
|
"""
|
|
543
541
|
if infer_name and self.name is None:
|
|
544
542
|
self._infer_name(inspect.currentframe())
|
|
543
|
+
|
|
545
544
|
model_used = self._get_model(model)
|
|
546
545
|
del model
|
|
547
546
|
|
|
@@ -565,9 +564,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
565
564
|
tool_manager = ToolManager[AgentDepsT](toolset)
|
|
566
565
|
|
|
567
566
|
# Build the graph
|
|
568
|
-
graph
|
|
569
|
-
_agent_graph.build_agent_graph(self.name, self._deps_type, output_type_)
|
|
570
|
-
)
|
|
567
|
+
graph = _agent_graph.build_agent_graph(self.name, self._deps_type, output_type_)
|
|
571
568
|
|
|
572
569
|
# Build the initial state
|
|
573
570
|
usage = usage or _usage.RunUsage()
|
|
@@ -607,16 +604,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
607
604
|
else:
|
|
608
605
|
instrumentation_settings = None
|
|
609
606
|
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)
|
|
607
|
+
|
|
620
608
|
graph_deps = _agent_graph.GraphAgentDeps[AgentDepsT, RunOutputDataT](
|
|
621
609
|
user_deps=deps,
|
|
622
610
|
prompt=user_prompt,
|
|
@@ -629,14 +617,14 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
629
617
|
output_schema=output_schema,
|
|
630
618
|
output_validators=output_validators,
|
|
631
619
|
history_processors=self.history_processors,
|
|
632
|
-
builtin_tools=builtin_tools,
|
|
620
|
+
builtin_tools=[*self._builtin_tools, *(builtin_tools or [])],
|
|
633
621
|
tool_manager=tool_manager,
|
|
634
622
|
tracer=tracer,
|
|
635
623
|
get_instructions=get_instructions,
|
|
636
624
|
instrumentation_settings=instrumentation_settings,
|
|
637
625
|
)
|
|
638
626
|
|
|
639
|
-
|
|
627
|
+
user_prompt_node = _agent_graph.UserPromptNode[AgentDepsT](
|
|
640
628
|
user_prompt=user_prompt,
|
|
641
629
|
deferred_tool_results=deferred_tool_results,
|
|
642
630
|
instructions=instructions_literal,
|
|
@@ -663,7 +651,7 @@ class Agent(AbstractAgent[AgentDepsT, OutputDataT]):
|
|
|
663
651
|
|
|
664
652
|
try:
|
|
665
653
|
async with graph.iter(
|
|
666
|
-
|
|
654
|
+
inputs=user_prompt_node,
|
|
667
655
|
state=state,
|
|
668
656
|
deps=graph_deps,
|
|
669
657
|
span=use_span(run_span) if run_span.is_recording() else None,
|
|
@@ -16,6 +16,7 @@ __all__ = (
|
|
|
16
16
|
'UrlContextTool',
|
|
17
17
|
'ImageGenerationTool',
|
|
18
18
|
'MemoryTool',
|
|
19
|
+
'MCPServerTool',
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
_BUILTIN_TOOL_TYPES: dict[str, type[AbstractBuiltinTool]] = {}
|
|
@@ -33,6 +34,14 @@ class AbstractBuiltinTool(ABC):
|
|
|
33
34
|
kind: str = 'unknown_builtin_tool'
|
|
34
35
|
"""Built-in tool identifier, this should be available on all built-in tools as a discriminator."""
|
|
35
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
|
+
|
|
36
45
|
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
37
46
|
super().__init_subclass__(**kwargs)
|
|
38
47
|
_BUILTIN_TOOL_TYPES[cls.kind] = cls
|
|
@@ -263,6 +272,68 @@ class MemoryTool(AbstractBuiltinTool):
|
|
|
263
272
|
"""The kind of tool."""
|
|
264
273
|
|
|
265
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
|
+
|
|
266
337
|
def _tool_discriminator(tool_data: dict[str, Any] | AbstractBuiltinTool) -> str:
|
|
267
338
|
if isinstance(tool_data, dict):
|
|
268
339
|
return tool_data.get('kind', AbstractBuiltinTool.kind)
|
{pydantic_ai_slim-1.3.0 → pydantic_ai_slim-1.5.0}/pydantic_ai/durable_exec/temporal/__init__.py
RENAMED
|
@@ -36,6 +36,17 @@ __all__ = [
|
|
|
36
36
|
'TemporalWrapperToolset',
|
|
37
37
|
]
|
|
38
38
|
|
|
39
|
+
# We need eagerly import the anyio backends or it will happens inside workflow code and temporal has issues
|
|
40
|
+
# Note: It's difficult to add a test that covers this because pytest presumably does these imports itself
|
|
41
|
+
# when you have a @pytest.mark.anyio somewhere.
|
|
42
|
+
# I suppose we could add a test that runs a python script in a separate process, but I have not done that...
|
|
43
|
+
import anyio._backends._asyncio # pyright: ignore[reportUnusedImport]
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
import anyio._backends._trio # noqa F401 # pyright: ignore[reportUnusedImport]
|
|
47
|
+
except ImportError:
|
|
48
|
+
pass
|
|
49
|
+
|
|
39
50
|
|
|
40
51
|
class PydanticAIPlugin(ClientPlugin, WorkerPlugin):
|
|
41
52
|
"""Temporal client and worker plugin for Pydantic AI."""
|
|
@@ -2,11 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Annotated, Any, Literal
|
|
5
|
+
from typing import Annotated, Any, Literal
|
|
6
6
|
|
|
7
7
|
from pydantic import ConfigDict, Discriminator, with_config
|
|
8
8
|
from temporalio import activity, workflow
|
|
9
9
|
from temporalio.workflow import ActivityConfig
|
|
10
|
+
from typing_extensions import assert_never
|
|
10
11
|
|
|
11
12
|
from pydantic_ai import FunctionToolset, ToolsetTool
|
|
12
13
|
from pydantic_ai.exceptions import ApprovalRequired, CallDeferred, ModelRetry, UserError
|
|
@@ -159,7 +159,7 @@ class ModelHTTPError(AgentRunError):
|
|
|
159
159
|
super().__init__(message)
|
|
160
160
|
|
|
161
161
|
|
|
162
|
-
class FallbackExceptionGroup(ExceptionGroup):
|
|
162
|
+
class FallbackExceptionGroup(ExceptionGroup[Any]):
|
|
163
163
|
"""A group of exceptions that can be raised when all fallback models fail."""
|
|
164
164
|
|
|
165
165
|
|
|
@@ -480,7 +480,7 @@ class BinaryContent:
|
|
|
480
480
|
"""
|
|
481
481
|
|
|
482
482
|
_identifier: Annotated[str | None, pydantic.Field(alias='identifier', default=None, exclude=True)] = field(
|
|
483
|
-
compare=False, default=None
|
|
483
|
+
compare=False, default=None, repr=False
|
|
484
484
|
)
|
|
485
485
|
|
|
486
486
|
kind: Literal['binary'] = 'binary'
|
|
@@ -410,9 +410,17 @@ class Model(ABC):
|
|
|
410
410
|
they need to customize the preparation flow further, but most implementations should simply call
|
|
411
411
|
``self.prepare_request(...)`` at the start of their ``request`` (and related) methods.
|
|
412
412
|
"""
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
|
416
424
|
|
|
417
425
|
@property
|
|
418
426
|
@abstractmethod
|