pydantic-ai-slim 1.7.0__py3-none-any.whl → 1.11.0__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/__init__.py +2 -0
- pydantic_ai/_agent_graph.py +3 -0
- pydantic_ai/_cli.py +2 -2
- pydantic_ai/_run_context.py +8 -2
- pydantic_ai/_tool_manager.py +1 -0
- pydantic_ai/_utils.py +18 -0
- pydantic_ai/ag_ui.py +50 -696
- pydantic_ai/agent/__init__.py +13 -3
- pydantic_ai/agent/abstract.py +172 -9
- pydantic_ai/agent/wrapper.py +5 -0
- pydantic_ai/direct.py +16 -4
- pydantic_ai/durable_exec/dbos/_agent.py +31 -0
- pydantic_ai/durable_exec/prefect/_agent.py +28 -0
- pydantic_ai/durable_exec/temporal/_agent.py +28 -0
- pydantic_ai/durable_exec/temporal/_function_toolset.py +23 -73
- pydantic_ai/durable_exec/temporal/_mcp_server.py +30 -30
- pydantic_ai/durable_exec/temporal/_run_context.py +9 -3
- pydantic_ai/durable_exec/temporal/_toolset.py +67 -3
- pydantic_ai/messages.py +49 -8
- pydantic_ai/models/__init__.py +42 -1
- pydantic_ai/models/google.py +5 -12
- pydantic_ai/models/groq.py +9 -1
- pydantic_ai/models/openai.py +6 -3
- pydantic_ai/profiles/openai.py +5 -2
- pydantic_ai/providers/anthropic.py +2 -2
- pydantic_ai/providers/openrouter.py +3 -0
- pydantic_ai/result.py +178 -11
- pydantic_ai/tools.py +10 -6
- pydantic_ai/ui/__init__.py +16 -0
- pydantic_ai/ui/_adapter.py +386 -0
- pydantic_ai/ui/_event_stream.py +591 -0
- pydantic_ai/ui/_messages_builder.py +28 -0
- pydantic_ai/ui/ag_ui/__init__.py +9 -0
- pydantic_ai/ui/ag_ui/_adapter.py +187 -0
- pydantic_ai/ui/ag_ui/_event_stream.py +236 -0
- pydantic_ai/ui/ag_ui/app.py +148 -0
- pydantic_ai/ui/vercel_ai/__init__.py +16 -0
- pydantic_ai/ui/vercel_ai/_adapter.py +199 -0
- pydantic_ai/ui/vercel_ai/_event_stream.py +187 -0
- pydantic_ai/ui/vercel_ai/_utils.py +16 -0
- pydantic_ai/ui/vercel_ai/request_types.py +275 -0
- pydantic_ai/ui/vercel_ai/response_types.py +230 -0
- {pydantic_ai_slim-1.7.0.dist-info → pydantic_ai_slim-1.11.0.dist-info}/METADATA +10 -6
- {pydantic_ai_slim-1.7.0.dist-info → pydantic_ai_slim-1.11.0.dist-info}/RECORD +47 -33
- {pydantic_ai_slim-1.7.0.dist-info → pydantic_ai_slim-1.11.0.dist-info}/WHEEL +0 -0
- {pydantic_ai_slim-1.7.0.dist-info → pydantic_ai_slim-1.11.0.dist-info}/entry_points.txt +0 -0
- {pydantic_ai_slim-1.7.0.dist-info → pydantic_ai_slim-1.11.0.dist-info}/licenses/LICENSE +0 -0
pydantic_ai/__init__.py
CHANGED
|
@@ -65,6 +65,7 @@ from .messages import (
|
|
|
65
65
|
ModelResponseStreamEvent,
|
|
66
66
|
MultiModalContent,
|
|
67
67
|
PartDeltaEvent,
|
|
68
|
+
PartEndEvent,
|
|
68
69
|
PartStartEvent,
|
|
69
70
|
RetryPromptPart,
|
|
70
71
|
SystemPromptPart,
|
|
@@ -164,6 +165,7 @@ __all__ = (
|
|
|
164
165
|
'ModelResponseStreamEvent',
|
|
165
166
|
'MultiModalContent',
|
|
166
167
|
'PartDeltaEvent',
|
|
168
|
+
'PartEndEvent',
|
|
167
169
|
'PartStartEvent',
|
|
168
170
|
'RetryPromptPart',
|
|
169
171
|
'SystemPromptPart',
|
pydantic_ai/_agent_graph.py
CHANGED
|
@@ -267,6 +267,9 @@ class UserPromptNode(AgentNode[DepsT, NodeRunEndT]):
|
|
|
267
267
|
|
|
268
268
|
next_message.instructions = await ctx.deps.get_instructions(run_context)
|
|
269
269
|
|
|
270
|
+
if not messages and not next_message.parts and not next_message.instructions:
|
|
271
|
+
raise exceptions.UserError('No message history, user prompt, or instructions provided')
|
|
272
|
+
|
|
270
273
|
return ModelRequestNode[DepsT, NodeRunEndT](request=next_message)
|
|
271
274
|
|
|
272
275
|
async def _handle_deferred_tool_results( # noqa: C901
|
pydantic_ai/_cli.py
CHANGED
|
@@ -103,7 +103,7 @@ def cli_exit(prog_name: str = 'pai'): # pragma: no cover
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
def cli( # noqa: C901
|
|
106
|
-
args_list: Sequence[str] | None = None, *, prog_name: str = 'pai', default_model: str = 'openai:gpt-
|
|
106
|
+
args_list: Sequence[str] | None = None, *, prog_name: str = 'pai', default_model: str = 'openai:gpt-5'
|
|
107
107
|
) -> int:
|
|
108
108
|
"""Run the CLI and return the exit code for the process."""
|
|
109
109
|
parser = argparse.ArgumentParser(
|
|
@@ -124,7 +124,7 @@ Special prompts:
|
|
|
124
124
|
'-m',
|
|
125
125
|
'--model',
|
|
126
126
|
nargs='?',
|
|
127
|
-
help=f'Model to use, in format "<provider>:<model>" e.g. "openai:gpt-
|
|
127
|
+
help=f'Model to use, in format "<provider>:<model>" e.g. "openai:gpt-5" or "anthropic:claude-sonnet-4-5". Defaults to "{default_model}".',
|
|
128
128
|
)
|
|
129
129
|
# we don't want to autocomplete or list models that don't include the provider,
|
|
130
130
|
# e.g. we want to show `openai:gpt-4o` but not `gpt-4o`
|
pydantic_ai/_run_context.py
CHANGED
|
@@ -16,15 +16,19 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from .models import Model
|
|
17
17
|
from .result import RunUsage
|
|
18
18
|
|
|
19
|
+
# TODO (v2): Change the default for all typevars like this from `None` to `object`
|
|
19
20
|
AgentDepsT = TypeVar('AgentDepsT', default=None, contravariant=True)
|
|
20
21
|
"""Type variable for agent dependencies."""
|
|
21
22
|
|
|
23
|
+
RunContextAgentDepsT = TypeVar('RunContextAgentDepsT', default=None, covariant=True)
|
|
24
|
+
"""Type variable for the agent dependencies in `RunContext`."""
|
|
25
|
+
|
|
22
26
|
|
|
23
27
|
@dataclasses.dataclass(repr=False, kw_only=True)
|
|
24
|
-
class RunContext(Generic[
|
|
28
|
+
class RunContext(Generic[RunContextAgentDepsT]):
|
|
25
29
|
"""Information about the current call."""
|
|
26
30
|
|
|
27
|
-
deps:
|
|
31
|
+
deps: RunContextAgentDepsT
|
|
28
32
|
"""Dependencies for the agent."""
|
|
29
33
|
model: Model
|
|
30
34
|
"""The model used in this run."""
|
|
@@ -54,6 +58,8 @@ class RunContext(Generic[AgentDepsT]):
|
|
|
54
58
|
"""The current step in the run."""
|
|
55
59
|
tool_call_approved: bool = False
|
|
56
60
|
"""Whether a tool call that required approval has now been approved."""
|
|
61
|
+
partial_output: bool = False
|
|
62
|
+
"""Whether the output passed to an output validator is partial."""
|
|
57
63
|
|
|
58
64
|
@property
|
|
59
65
|
def last_attempt(self) -> bool:
|
pydantic_ai/_tool_manager.py
CHANGED
|
@@ -147,6 +147,7 @@ class ToolManager(Generic[AgentDepsT]):
|
|
|
147
147
|
tool_call_id=call.tool_call_id,
|
|
148
148
|
retry=self.ctx.retries.get(name, 0),
|
|
149
149
|
max_retries=tool.max_retries,
|
|
150
|
+
partial_output=allow_partial,
|
|
150
151
|
)
|
|
151
152
|
|
|
152
153
|
pyd_allow_partial = 'trailing-strings' if allow_partial else 'off'
|
pydantic_ai/_utils.py
CHANGED
|
@@ -234,6 +234,15 @@ def sync_anext(iterator: Iterator[T]) -> T:
|
|
|
234
234
|
raise StopAsyncIteration() from e
|
|
235
235
|
|
|
236
236
|
|
|
237
|
+
def sync_async_iterator(async_iter: AsyncIterator[T]) -> Iterator[T]:
|
|
238
|
+
loop = get_event_loop()
|
|
239
|
+
while True:
|
|
240
|
+
try:
|
|
241
|
+
yield loop.run_until_complete(anext(async_iter))
|
|
242
|
+
except StopAsyncIteration:
|
|
243
|
+
break
|
|
244
|
+
|
|
245
|
+
|
|
237
246
|
def now_utc() -> datetime:
|
|
238
247
|
return datetime.now(tz=timezone.utc)
|
|
239
248
|
|
|
@@ -489,3 +498,12 @@ def get_union_args(tp: Any) -> tuple[Any, ...]:
|
|
|
489
498
|
return tuple(_unwrap_annotated(arg) for arg in get_args(tp))
|
|
490
499
|
else:
|
|
491
500
|
return ()
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def get_event_loop():
|
|
504
|
+
try:
|
|
505
|
+
event_loop = asyncio.get_event_loop()
|
|
506
|
+
except RuntimeError: # pragma: lax no cover
|
|
507
|
+
event_loop = asyncio.new_event_loop()
|
|
508
|
+
asyncio.set_event_loop(event_loop)
|
|
509
|
+
return event_loop
|