pydantic-ai-slim 0.0.9__py3-none-any.whl → 0.0.11__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.py
CHANGED
|
@@ -2,9 +2,11 @@ from __future__ import annotations as _annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import dataclasses
|
|
5
|
+
import inspect
|
|
5
6
|
from collections.abc import AsyncIterator, Awaitable, Iterator, Sequence
|
|
6
7
|
from contextlib import asynccontextmanager, contextmanager
|
|
7
8
|
from dataclasses import dataclass, field
|
|
9
|
+
from types import FrameType
|
|
8
10
|
from typing import Any, Callable, Generic, cast, final, overload
|
|
9
11
|
|
|
10
12
|
import logfire_api
|
|
@@ -54,6 +56,11 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
54
56
|
# dataclass fields mostly for my sanity — knowing what attributes are available
|
|
55
57
|
model: models.Model | models.KnownModelName | None
|
|
56
58
|
"""The default model configured for this agent."""
|
|
59
|
+
name: str | None
|
|
60
|
+
"""The name of the agent, used for logging.
|
|
61
|
+
|
|
62
|
+
If `None`, we try to infer the agent name from the call frame when the agent is first run.
|
|
63
|
+
"""
|
|
57
64
|
_result_schema: _result.ResultSchema[ResultData] | None = field(repr=False)
|
|
58
65
|
_result_validators: list[_result.ResultValidator[AgentDeps, ResultData]] = field(repr=False)
|
|
59
66
|
_allow_text_result: bool = field(repr=False)
|
|
@@ -79,6 +86,7 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
79
86
|
result_type: type[ResultData] = str,
|
|
80
87
|
system_prompt: str | Sequence[str] = (),
|
|
81
88
|
deps_type: type[AgentDeps] = NoneType,
|
|
89
|
+
name: str | None = None,
|
|
82
90
|
retries: int = 1,
|
|
83
91
|
result_tool_name: str = 'final_result',
|
|
84
92
|
result_tool_description: str | None = None,
|
|
@@ -98,6 +106,8 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
98
106
|
parameterize the agent, and therefore get the best out of static type checking.
|
|
99
107
|
If you're not using deps, but want type checking to pass, you can set `deps=None` to satisfy Pyright
|
|
100
108
|
or add a type hint `: Agent[None, <return type>]`.
|
|
109
|
+
name: The name of the agent, used for logging. If `None`, we try to infer the agent name from the call frame
|
|
110
|
+
when the agent is first run.
|
|
101
111
|
retries: The default number of retries to allow before raising an error.
|
|
102
112
|
result_tool_name: The name of the tool to use for the final result.
|
|
103
113
|
result_tool_description: The description of the final result tool.
|
|
@@ -115,6 +125,7 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
115
125
|
else:
|
|
116
126
|
self.model = models.infer_model(model)
|
|
117
127
|
|
|
128
|
+
self.name = name
|
|
118
129
|
self._result_schema = _result.ResultSchema[result_type].build(
|
|
119
130
|
result_type, result_tool_name, result_tool_description
|
|
120
131
|
)
|
|
@@ -139,6 +150,7 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
139
150
|
message_history: list[_messages.Message] | None = None,
|
|
140
151
|
model: models.Model | models.KnownModelName | None = None,
|
|
141
152
|
deps: AgentDeps = None,
|
|
153
|
+
infer_name: bool = True,
|
|
142
154
|
) -> result.RunResult[ResultData]:
|
|
143
155
|
"""Run the agent with a user prompt in async mode.
|
|
144
156
|
|
|
@@ -147,20 +159,24 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
147
159
|
message_history: History of the conversation so far.
|
|
148
160
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
149
161
|
deps: Optional dependencies to use for this run.
|
|
162
|
+
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
150
163
|
|
|
151
164
|
Returns:
|
|
152
165
|
The result of the run.
|
|
153
166
|
"""
|
|
167
|
+
if infer_name and self.name is None:
|
|
168
|
+
self._infer_name(inspect.currentframe())
|
|
154
169
|
model_used, custom_model, agent_model = await self._get_agent_model(model)
|
|
155
170
|
|
|
156
171
|
deps = self._get_deps(deps)
|
|
157
172
|
|
|
158
173
|
with _logfire.span(
|
|
159
|
-
'
|
|
174
|
+
'{agent_name} run {prompt=}',
|
|
160
175
|
prompt=user_prompt,
|
|
161
176
|
agent=self,
|
|
162
177
|
custom_model=custom_model,
|
|
163
178
|
model_name=model_used.name(),
|
|
179
|
+
agent_name=self.name or 'agent',
|
|
164
180
|
) as run_span:
|
|
165
181
|
new_message_index, messages = await self._prepare_messages(deps, user_prompt, message_history)
|
|
166
182
|
self.last_run_messages = messages
|
|
@@ -208,6 +224,7 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
208
224
|
message_history: list[_messages.Message] | None = None,
|
|
209
225
|
model: models.Model | models.KnownModelName | None = None,
|
|
210
226
|
deps: AgentDeps = None,
|
|
227
|
+
infer_name: bool = True,
|
|
211
228
|
) -> result.RunResult[ResultData]:
|
|
212
229
|
"""Run the agent with a user prompt synchronously.
|
|
213
230
|
|
|
@@ -218,12 +235,17 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
218
235
|
message_history: History of the conversation so far.
|
|
219
236
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
220
237
|
deps: Optional dependencies to use for this run.
|
|
238
|
+
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
221
239
|
|
|
222
240
|
Returns:
|
|
223
241
|
The result of the run.
|
|
224
242
|
"""
|
|
243
|
+
if infer_name and self.name is None:
|
|
244
|
+
self._infer_name(inspect.currentframe())
|
|
225
245
|
loop = asyncio.get_event_loop()
|
|
226
|
-
return loop.run_until_complete(
|
|
246
|
+
return loop.run_until_complete(
|
|
247
|
+
self.run(user_prompt, message_history=message_history, model=model, deps=deps, infer_name=False)
|
|
248
|
+
)
|
|
227
249
|
|
|
228
250
|
@asynccontextmanager
|
|
229
251
|
async def run_stream(
|
|
@@ -233,6 +255,7 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
233
255
|
message_history: list[_messages.Message] | None = None,
|
|
234
256
|
model: models.Model | models.KnownModelName | None = None,
|
|
235
257
|
deps: AgentDeps = None,
|
|
258
|
+
infer_name: bool = True,
|
|
236
259
|
) -> AsyncIterator[result.StreamedRunResult[AgentDeps, ResultData]]:
|
|
237
260
|
"""Run the agent with a user prompt in async mode, returning a streamed response.
|
|
238
261
|
|
|
@@ -241,20 +264,26 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
241
264
|
message_history: History of the conversation so far.
|
|
242
265
|
model: Optional model to use for this run, required if `model` was not set when creating the agent.
|
|
243
266
|
deps: Optional dependencies to use for this run.
|
|
267
|
+
infer_name: Whether to try to infer the agent name from the call frame if it's not set.
|
|
244
268
|
|
|
245
269
|
Returns:
|
|
246
270
|
The result of the run.
|
|
247
271
|
"""
|
|
272
|
+
if infer_name and self.name is None:
|
|
273
|
+
# f_back because `asynccontextmanager` adds one frame
|
|
274
|
+
if frame := inspect.currentframe(): # pragma: no branch
|
|
275
|
+
self._infer_name(frame.f_back)
|
|
248
276
|
model_used, custom_model, agent_model = await self._get_agent_model(model)
|
|
249
277
|
|
|
250
278
|
deps = self._get_deps(deps)
|
|
251
279
|
|
|
252
280
|
with _logfire.span(
|
|
253
|
-
'
|
|
281
|
+
'{agent_name} run stream {prompt=}',
|
|
254
282
|
prompt=user_prompt,
|
|
255
283
|
agent=self,
|
|
256
284
|
custom_model=custom_model,
|
|
257
285
|
model_name=model_used.name(),
|
|
286
|
+
agent_name=self.name or 'agent',
|
|
258
287
|
) as run_span:
|
|
259
288
|
new_message_index, messages = await self._prepare_messages(deps, user_prompt, message_history)
|
|
260
289
|
self.last_run_messages = messages
|
|
@@ -798,6 +827,25 @@ class Agent(Generic[AgentDeps, ResultData]):
|
|
|
798
827
|
else:
|
|
799
828
|
return deps
|
|
800
829
|
|
|
830
|
+
def _infer_name(self, function_frame: FrameType | None) -> None:
|
|
831
|
+
"""Infer the agent name from the call frame.
|
|
832
|
+
|
|
833
|
+
Usage should be `self._infer_name(inspect.currentframe())`.
|
|
834
|
+
"""
|
|
835
|
+
assert self.name is None, 'Name already set'
|
|
836
|
+
if function_frame is not None: # pragma: no branch
|
|
837
|
+
if parent_frame := function_frame.f_back: # pragma: no branch
|
|
838
|
+
for name, item in parent_frame.f_locals.items():
|
|
839
|
+
if item is self:
|
|
840
|
+
self.name = name
|
|
841
|
+
return
|
|
842
|
+
if parent_frame.f_locals != parent_frame.f_globals:
|
|
843
|
+
# if we couldn't find the agent in locals and globals are a different dict, try globals
|
|
844
|
+
for name, item in parent_frame.f_globals.items():
|
|
845
|
+
if item is self:
|
|
846
|
+
self.name = name
|
|
847
|
+
return
|
|
848
|
+
|
|
801
849
|
|
|
802
850
|
@dataclass
|
|
803
851
|
class _MarkFinalResult(Generic[ResultData]):
|
|
@@ -4,7 +4,7 @@ pydantic_ai/_pydantic.py,sha256=oFfcHDv_wuL1NQ7mCzVHvP1HBaVzyvb7xS-_Iiri_tA,8491
|
|
|
4
4
|
pydantic_ai/_result.py,sha256=wzcfwDpr_sro1Vkn3DkyIhCXMHTReDxL_ZYm50JzdRI,9667
|
|
5
5
|
pydantic_ai/_system_prompt.py,sha256=vFT0y9Wykl5veGMgLLkGRYiHQrgdW2BZ1rwMn4izjjo,1085
|
|
6
6
|
pydantic_ai/_utils.py,sha256=eNb7f3-ZQC8WDEa87iUcXGQ-lyuutFQG-5yBCMD4Vvs,8227
|
|
7
|
-
pydantic_ai/agent.py,sha256=
|
|
7
|
+
pydantic_ai/agent.py,sha256=5QOiDVByatRqKlxyRLba0fBUZcuaEkew3eqovFiOB5M,37311
|
|
8
8
|
pydantic_ai/exceptions.py,sha256=ko_47M0k6Rhg9mUC9P1cj7N4LCH6cC0pEsF65A2vL-U,1561
|
|
9
9
|
pydantic_ai/messages.py,sha256=I0_CPXDIGGSy-PXHuKq540oAXYOO9uyylpsfSsE4vLs,7032
|
|
10
10
|
pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -17,6 +17,6 @@ pydantic_ai/models/groq.py,sha256=Tx2yU3ysmPLBmWGsjzES-XcumzrsoBtB7spCnJBlLiM,14
|
|
|
17
17
|
pydantic_ai/models/openai.py,sha256=5ihH25CrS0tnZNW-BZw4GyPe8V-IxIHWw3B9ulPVjQE,14931
|
|
18
18
|
pydantic_ai/models/test.py,sha256=q1wch_E7TSb4qx9PCcP1YyBGZx567MGlAQhlAlON0S8,14463
|
|
19
19
|
pydantic_ai/models/vertexai.py,sha256=5wI8y2YjeRgSE51uKy5OtevQkks65uEbxIUAs5EGBaI,9161
|
|
20
|
-
pydantic_ai_slim-0.0.
|
|
21
|
-
pydantic_ai_slim-0.0.
|
|
22
|
-
pydantic_ai_slim-0.0.
|
|
20
|
+
pydantic_ai_slim-0.0.11.dist-info/METADATA,sha256=JPixjiAAN-dFKXFk6njU5-cf3_JqkwEBnXh2fUn2Ok4,2562
|
|
21
|
+
pydantic_ai_slim-0.0.11.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
22
|
+
pydantic_ai_slim-0.0.11.dist-info/RECORD,,
|
|
File without changes
|